From fa0c41900d1e8f669f7becd3073159a3663bcef6 Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Fri, 7 Nov 2008 04:04:17 +0000 Subject: [PATCH 001/523] Initialize branch F-10 for coreutils --- branch | 1 + 1 file changed, 1 insertion(+) create mode 100644 branch diff --git a/branch b/branch new file mode 100644 index 0000000..dc32377 --- /dev/null +++ b/branch @@ -0,0 +1 @@ +F-10 From e18e41532f244e4caeab1de0499eb477e0c50796 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 11 Nov 2008 16:03:49 +0000 Subject: [PATCH 002/523] New upstream release (+ amending/droping patches) --- coreutils-463883-chcon-changes.patch | 4 +- coreutils-5.2.1-runuser.patch | 20 +- coreutils-6.10-manpages.patch | 12 +- coreutils-6.11-sparc-shafix.patch | 6 +- ...-6.12-catch-known-testsuite-failures.patch | 90 ----- coreutils-6.12-date_timerelsnumber.patch | 381 ------------------ coreutils-6.12-dd-fullblock.patch | 173 -------- coreutils-6.12-ls-constant_mem.patch | 38 -- coreutils-6.12-ls-libcap.patch | 257 ------------ coreutils-6.12-seqdecimalutf8.patch | 15 - coreutils-6.12-utimenstouchcp.patch | 89 ---- coreutils-7.0-dftotal.patch | 112 +++++ coreutils-authors.patch | 61 --- coreutils-futimensatkoji.patch | 119 ------ coreutils-getfacl-exit-code.patch | 2 +- coreutils-i18n.patch | 33 +- coreutils-pam.patch | 8 +- coreutils-selinux.patch | 40 +- coreutils-who_texinfo.patch | 78 ---- coreutils.spec | 60 ++- 20 files changed, 190 insertions(+), 1408 deletions(-) delete mode 100644 coreutils-6.12-catch-known-testsuite-failures.patch delete mode 100644 coreutils-6.12-date_timerelsnumber.patch delete mode 100644 coreutils-6.12-dd-fullblock.patch delete mode 100644 coreutils-6.12-ls-constant_mem.patch delete mode 100644 coreutils-6.12-ls-libcap.patch delete mode 100644 coreutils-6.12-seqdecimalutf8.patch delete mode 100644 coreutils-6.12-utimenstouchcp.patch create mode 100644 coreutils-7.0-dftotal.patch delete mode 100644 coreutils-authors.patch delete mode 100644 coreutils-futimensatkoji.patch delete mode 100644 coreutils-who_texinfo.patch diff --git a/coreutils-463883-chcon-changes.patch b/coreutils-463883-chcon-changes.patch index 1a60292..b1cf9f5 100644 --- a/coreutils-463883-chcon-changes.patch +++ b/coreutils-463883-chcon-changes.patch @@ -25,8 +25,8 @@ diff -urNp coreutils-6.12-orig/src/chcon.c coreutils-6.12/src/chcon.c - V_off -}; - /* The name the program was run with. */ - char *program_name; + /* If nonzero, and the systems has support for it, change the context + of symbolic links rather than any files they point to. */ @@ -374,7 +355,6 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ Change the SELinux security context of each FILE to CONTEXT.\n\ With --reference, change the security context of each FILE to that of RFILE.\n\ diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index d4350e5..db6b81d 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -3,7 +3,7 @@ diff -urNp coreutils-6.12-orig/AUTHORS coreutils-6.12/AUTHORS +++ coreutils-6.12/AUTHORS 2008-10-21 15:00:05.000000000 +0200 @@ -63,6 +63,7 @@ pwd: Jim Meyering readlink: Dmitry V. Levin - rm: Paul Rubin, David MacKenzie, Richard Stallman, Jim Meyering + rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering rmdir: David MacKenzie +runuser: David MacKenzie, Dan Walsh runcon: Russell Coker @@ -23,17 +23,21 @@ diff -urNp coreutils-6.12-orig/man/Makefile.am coreutils-6.12/man/Makefile.am diff -urNp coreutils-6.12-orig/README coreutils-6.12/README --- coreutils-6.12-orig/README 2008-05-15 20:44:37.000000000 +0200 +++ coreutils-6.12/README 2008-10-21 14:59:29.000000000 +0200 -@@ -12,8 +12,8 @@ The programs that can be built with this +@@ -12,10 +12,10 @@ The programs that can be built with this factor false fmt fold groups head hostid hostname id install join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir - runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf -- sleep sort split stat stty su sum sync tac tail tee test touch tr true +- sleep sort split stat stty su sum sync tac tail tee test timeout touch tr +- true truncate tsort tty uname unexpand uniq unlink uptime users vdir wc who +- whoami yes + runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum shred -+ shuf sleep sort split stat stty su sum sync tac tail tee test touch tr true - tsort tty uname unexpand uniq unlink uptime users vdir wc who whoami yes ++ shuf sleep sort split stat stty su sum sync tac tail tee test timeout touch ++ tr true truncate tsort tty uname unexpand uniq unlink uptime users vdir wc ++ who whoami yes See the file NEWS for a list of major changes in the current release. + diff -urNp coreutils-6.12-orig/src/Makefile.am coreutils-6.12/src/Makefile.am --- coreutils-6.12-orig/src/Makefile.am 2008-10-21 14:58:31.000000000 +0200 +++ coreutils-6.12/src/Makefile.am 2008-10-21 14:59:58.000000000 +0200 @@ -43,7 +47,7 @@ diff -urNp coreutils-6.12-orig/src/Makefile.am coreutils-6.12/src/Makefile.am id kill logname pathchk printenv printf pwd \ - runcon seq sleep tee \ + runcon runuser seq sleep tee \ - test true tty whoami yes \ + test timeout true truncate tty whoami yes \ base64 @@ -142,6 +142,10 @@ cp_LDADD += $(LIB_ACL) @@ -251,7 +255,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c +#endif initialize_main (&argc, &argv); - program_name = argv[0]; + set_program_name (argv[0]); @@ -670,7 +742,11 @@ main (int argc, char **argv) simulate_login = false; change_environment = true; @@ -343,9 +347,9 @@ diff -urNp coreutils-6.12-orig/tests/misc/help-version coreutils-6.12/tests/misc sleep_args=0 su_args=--version +runuser_args=--version + timeout_args=--version # I'd rather not run sync, since it spins up disks that I've - # deliberately caused to spin down (but not unmounted). --- /dev/null 2007-01-09 09:38:07.860075128 +0000 +++ coreutils-6.7/man/runuser.x 2007-01-09 17:27:56.000000000 +0000 @@ -0,0 +1,12 @@ diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index 2c1b5bc..066114e 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -10,20 +10,10 @@ diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c +"), stdout); fputs (_("\ \n\ - The following two options are useful only when verifying checksums:\n\ + The following three options are useful only when verifying checksums:\n\ diff -urNp coreutils-6.12-orig/src/sort.c coreutils-6.12/src/sort.c --- coreutils-6.12-orig/src/sort.c 2008-10-21 16:04:50.000000000 +0200 +++ coreutils-6.12/src/sort.c 2008-10-22 10:52:30.000000000 +0200 -@@ -375,7 +375,8 @@ Other options:\n\ - -C, --check=quiet, --check=silent like -c, but do not report first bad line\n\ - --compress-program=PROG compress temporaries with PROG;\n\ - decompress them with PROG -d\n\ -- -k, --key=POS1[,POS2] start a key at POS1, end it at POS2 (origin 1)\n\ -+ -k, --key=POS1[,POS2] start a key at POS1, end it at POS2 (origin 1) -\n\ -+ when no POS2 specified, end of line is used\n\ - -m, --merge merge already sorted files; do not sort\n\ - "), stdout); - fputs (_("\ @@ -412,7 +413,7 @@ With no FILE, or when FILE is -, read st \n\ *** WARNING ***\n\ diff --git a/coreutils-6.11-sparc-shafix.patch b/coreutils-6.11-sparc-shafix.patch index 8093785..e24b48b 100644 --- a/coreutils-6.11-sparc-shafix.patch +++ b/coreutils-6.11-sparc-shafix.patch @@ -4,7 +4,7 @@ diff -up coreutils-6.11/src/Makefile.am.sparc coreutils-6.11/src/Makefile.am @@ -101,6 +101,7 @@ shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME) tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) - vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) + vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) +tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) ## If necessary, add -lm to resolve use of pow in lib/strtod.c. @@ -13,8 +13,8 @@ diff -up coreutils-6.11/src/Makefile.in.sparc coreutils-6.11/src/Makefile.in --- coreutils-6.11/src/Makefile.in.sparc 2008-04-19 16:50:10.000000000 -0500 +++ coreutils-6.11/src/Makefile.in 2008-05-29 18:40:36.000000000 -0500 @@ -1251,6 +1251,7 @@ shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME) - tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) - vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_ACL) + vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) \ + $(LIB_ACL) sort_LDADD = $(LDADD) $(POW_LIB) $(LIB_GETHRXTIME) +tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) diff --git a/coreutils-6.12-catch-known-testsuite-failures.patch b/coreutils-6.12-catch-known-testsuite-failures.patch deleted file mode 100644 index 05b9e53..0000000 --- a/coreutils-6.12-catch-known-testsuite-failures.patch +++ /dev/null @@ -1,90 +0,0 @@ -diff -Naurp coreutils-6.12.orig/tests/cp/cp-a-selinux coreutils-6.12/tests/cp/cp-a-selinux ---- coreutils-6.12.orig/tests/cp/cp-a-selinux 2008-05-27 07:39:18.000000000 -0400 -+++ coreutils-6.12/tests/cp/cp-a-selinux 2008-10-06 16:16:38.000000000 -0400 -@@ -33,7 +33,8 @@ cleanup_() { cd /; umount "$cwd/mnt"; } - dd if=/dev/zero of=blob bs=8192 count=200 > /dev/null 2>&1 \ - || framework_failure - mkdir mnt || framework_failure --mkfs -t ext2 -F blob || framework_failure -+mkfs -t ext2 -F blob || -+ skip_test_ "failed to create an ext2 file system" - - # This context is special: it works even when mcstransd isn't running. - ctx=root:object_r:tmp_t:s0 -diff -Naurp coreutils-6.12.orig/tests/cp/preserve-gid coreutils-6.12/tests/cp/preserve-gid ---- coreutils-6.12.orig/tests/cp/preserve-gid 2008-05-27 07:39:18.000000000 -0400 -+++ coreutils-6.12/tests/cp/preserve-gid 2008-10-06 16:16:41.000000000 -0400 -@@ -19,6 +19,10 @@ - . $srcdir/test-lib.sh - require_root_ - -+# Record primary group number, usually 0. -+# This is the group ID used when cp (without -p) creates a new file. -+primary_group_num=$(id -g) -+ - create() { - echo "$1" > "$1" || exit 1 - chown "+$2:+$3" "$1" || exit 1 -@@ -34,7 +38,7 @@ t0() { - if test "x$s" != "x$u $g"; then - # Allow the actual group to match that of the parent directory - # (it was set to 0 above). -- if test "x$s" = "x$u 0"; then -+ if test "x$s" = "x$u $primary_group_num"; then - : - else - echo "$0: $* $f b: $u $g != $s" 1>&2 -diff -Naurp coreutils-6.12.orig/tests/misc/runcon-no-reorder coreutils-6.12/tests/misc/runcon-no-reorder ---- coreutils-6.12.orig/tests/misc/runcon-no-reorder 2008-05-27 07:39:18.000000000 -0400 -+++ coreutils-6.12/tests/misc/runcon-no-reorder 2008-10-06 16:16:41.000000000 -0400 -@@ -23,9 +23,8 @@ fi - - . $srcdir/test-lib.sh - --cat <<\EOF > exp || framework_failure --runcon: runcon may be used only on a SELinux kernel --EOF -+diag='runcon: runcon may be used only on a SELinux kernel' -+echo "$diag" > exp || framework_failure - - fail=0 - -@@ -35,6 +34,14 @@ fail=0 - # about -j being an invalid option. - runcon $(id -Z) true -j 2> out && : > exp - -+# When run on a system with no /selinux/context (i.e., in a chroot), -+# it chcon fails with this: "runcon: invalid context: \ -+# root:system_r:unconfined_t:s0-s0:c0.c1023: No such file or directory" -+# That diagnostic is ok, too, so map it to the more common one. -+case `cat out` in -+ 'runcon: invalid context: '*) echo "$diag" > out;; -+esac -+ - compare out exp || fail=1 - - (exit $fail); exit $fail -diff -Naurp coreutils-6.12.orig/tests/rm/fail-2eperm coreutils-6.12/tests/rm/fail-2eperm ---- coreutils-6.12.orig/tests/rm/fail-2eperm 2008-05-27 07:39:18.000000000 -0400 -+++ coreutils-6.12/tests/rm/fail-2eperm 2008-10-06 16:16:38.000000000 -0400 -@@ -39,8 +39,7 @@ fail=0 - rm_version=`setuidgid $NON_ROOT_USERNAME env PATH="$PATH" rm --version|sed -n '1s/.* //p'` - case $rm_version in - $PACKAGE_VERSION) ;; -- *) echo "$0: cannot access just-built rm as user $NON_ROOT_USERNAME" 1>&2 -- fail=1 ;; -+ *) skip_test_ "cannot access just-built rm as user $NON_ROOT_USERNAME";; - esac - setuidgid $NON_ROOT_USERNAME env PATH="$PATH" rm -rf a 2> out-t && fail=1 - -diff -Naurp coreutils-6.12.orig/THANKS coreutils-6.12/THANKS ---- coreutils-6.12.orig/THANKS 2008-05-06 05:28:24.000000000 -0400 -+++ coreutils-6.12/THANKS 2008-10-06 16:16:38.000000000 -0400 -@@ -237,6 +237,7 @@ Jan Moringen jan. - Jan Nieuwenhuizen janneke@gnu.org - Janos Farkas chexum@shadow.banki.hu - Jarkko Hietaniemi jhi@epsilon.hut.fi -+Jarod Wilson jwilson@redhat.com - Jean Charles Delepine delepine@u-picardie.fr - Jeff Moore jbm@mordor.com - Jeff Sheinberg jeff@bsrd.net diff --git a/coreutils-6.12-date_timerelsnumber.patch b/coreutils-6.12-date_timerelsnumber.patch deleted file mode 100644 index 92de5fb..0000000 --- a/coreutils-6.12-date_timerelsnumber.patch +++ /dev/null @@ -1,381 +0,0 @@ -diff -urNp coreutils-6.12-orig/lib/getdate.y coreutils-6.12/lib/getdate.y ---- coreutils-6.12-orig/lib/getdate.y 2008-01-31 19:37:19.000000000 +0100 -+++ coreutils-6.12/lib/getdate.y 2008-10-08 15:49:35.000000000 +0200 -@@ -1,8 +1,8 @@ - %{ - /* Parse a string into an internal time stamp. - -- Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007 Free Software -- Foundation, Inc. -+ Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008 -+ 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 -@@ -60,7 +60,7 @@ - # undef static - #endif - --#include -+#include - #include - #include - #include -@@ -205,7 +205,7 @@ typedef struct - union YYSTYPE; - static int yylex (union YYSTYPE *, parser_control *); - static int yyerror (parser_control const *, char const *); --static long int time_zone_hhmm (textint, long int); -+static long int time_zone_hhmm (parser_control *, textint, long int); - - /* Extract into *PC any date and time info from a string of digits - of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY, -@@ -246,6 +246,31 @@ digits_to_date_time (parser_control *pc, - } - } - -+/* Increment PC->rel by FACTOR * REL (FACTOR is 1 or -1). */ -+static void -+apply_relative_time (parser_control *pc, relative_time rel, int factor) -+{ -+ pc->rel.ns += factor * rel.ns; -+ pc->rel.seconds += factor * rel.seconds; -+ pc->rel.minutes += factor * rel.minutes; -+ pc->rel.hour += factor * rel.hour; -+ pc->rel.day += factor * rel.day; -+ pc->rel.month += factor * rel.month; -+ pc->rel.year += factor * rel.year; -+ pc->rels_seen = true; -+} -+ -+/* Set PC-> hour, minutes, seconds and nanoseconds members from arguments. */ -+static void -+set_hhmmss (parser_control *pc, long int hour, long int minutes, -+ time_t sec, long int nsec) -+{ -+ pc->hour = hour; -+ pc->minutes = minutes; -+ pc->seconds.tv_sec = sec; -+ pc->seconds.tv_nsec = nsec; -+} -+ - %} - - /* We want a reentrant parser, even if the TZ manipulation and the calls to -@@ -268,7 +293,7 @@ digits_to_date_time (parser_control *pc, - %token tAGO tDST - - %token tYEAR_UNIT tMONTH_UNIT tHOUR_UNIT tMINUTE_UNIT tSEC_UNIT --%token tDAY_UNIT -+%token tDAY_UNIT tDAY_SHIFT - - %token tDAY tDAYZONE tLOCAL_ZONE tMERIDIAN - %token tMONTH tORDINAL tZONE -@@ -279,7 +304,7 @@ digits_to_date_time (parser_control *pc, - %type o_colon_minutes o_merid - %type seconds signed_seconds unsigned_seconds - --%type relunit relunit_snumber -+%type relunit relunit_snumber dayshift - - %% - -@@ -313,7 +338,6 @@ item: - | day - { pc->days_seen++; } - | rel -- { pc->rels_seen = true; } - | number - | hybrid - ; -@@ -321,45 +345,32 @@ item: - time: - tUNUMBER tMERIDIAN - { -- pc->hour = $1.value; -- pc->minutes = 0; -- pc->seconds.tv_sec = 0; -- pc->seconds.tv_nsec = 0; -+ set_hhmmss (pc, $1.value, 0, 0, 0); - pc->meridian = $2; - } - | tUNUMBER ':' tUNUMBER o_merid - { -- pc->hour = $1.value; -- pc->minutes = $3.value; -- pc->seconds.tv_sec = 0; -- pc->seconds.tv_nsec = 0; -+ set_hhmmss (pc, $1.value, $3.value, 0, 0); - pc->meridian = $4; - } - | tUNUMBER ':' tUNUMBER tSNUMBER o_colon_minutes - { -- pc->hour = $1.value; -- pc->minutes = $3.value; -- pc->seconds.tv_sec = 0; -- pc->seconds.tv_nsec = 0; -+ set_hhmmss (pc, $1.value, $3.value, 0, 0); - pc->meridian = MER24; - pc->zones_seen++; -- pc->time_zone = time_zone_hhmm ($4, $5); -+ pc->time_zone = time_zone_hhmm (pc, $4, $5); - } - | tUNUMBER ':' tUNUMBER ':' unsigned_seconds o_merid - { -- pc->hour = $1.value; -- pc->minutes = $3.value; -- pc->seconds = $5; -+ set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec); - pc->meridian = $6; - } - | tUNUMBER ':' tUNUMBER ':' unsigned_seconds tSNUMBER o_colon_minutes - { -- pc->hour = $1.value; -- pc->minutes = $3.value; -- pc->seconds = $5; -+ set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec); - pc->meridian = MER24; - pc->zones_seen++; -- pc->time_zone = time_zone_hhmm ($6, $7); -+ pc->time_zone = time_zone_hhmm (pc, $6, $7); - } - ; - -@@ -381,16 +392,9 @@ zone: - { pc->time_zone = $1; } - | tZONE relunit_snumber - { pc->time_zone = $1; -- pc->rel.ns += $2.ns; -- pc->rel.seconds += $2.seconds; -- pc->rel.minutes += $2.minutes; -- pc->rel.hour += $2.hour; -- pc->rel.day += $2.day; -- pc->rel.month += $2.month; -- pc->rel.year += $2.year; -- pc->rels_seen = true; } -+ apply_relative_time (pc, $2, 1); } - | tZONE tSNUMBER o_colon_minutes -- { pc->time_zone = $1 + time_zone_hhmm ($2, $3); } -+ { pc->time_zone = $1 + time_zone_hhmm (pc, $2, $3); } - | tDAYZONE - { pc->time_zone = $1 + 60; } - | tZONE tDST -@@ -495,25 +499,11 @@ date: - - rel: - relunit tAGO -- { -- pc->rel.ns -= $1.ns; -- pc->rel.seconds -= $1.seconds; -- pc->rel.minutes -= $1.minutes; -- pc->rel.hour -= $1.hour; -- pc->rel.day -= $1.day; -- pc->rel.month -= $1.month; -- pc->rel.year -= $1.year; -- } -+ { apply_relative_time (pc, $1, -1); } - | relunit -- { -- pc->rel.ns += $1.ns; -- pc->rel.seconds += $1.seconds; -- pc->rel.minutes += $1.minutes; -- pc->rel.hour += $1.hour; -- pc->rel.day += $1.day; -- pc->rel.month += $1.month; -- pc->rel.year += $1.year; -- } -+ { apply_relative_time (pc, $1, 1); } -+ | dayshift -+ { apply_relative_time (pc, $1, 1); } - ; - - relunit: -@@ -575,6 +565,11 @@ relunit_snumber: - { $$ = RELATIVE_TIME_0; $$.seconds = $1.value; } - ; - -+dayshift: -+ tDAY_SHIFT -+ { $$ = RELATIVE_TIME_0; $$.day = $1; } -+ ; -+ - seconds: signed_seconds | unsigned_seconds; - - signed_seconds: -@@ -600,14 +595,7 @@ hybrid: - /* Hybrid all-digit and relative offset, so that we accept e.g., - "YYYYMMDD +N days" as well as "YYYYMMDD N days". */ - digits_to_date_time (pc, $1); -- pc->rel.ns += $2.ns; -- pc->rel.seconds += $2.seconds; -- pc->rel.minutes += $2.minutes; -- pc->rel.hour += $2.hour; -- pc->rel.day += $2.day; -- pc->rel.month += $2.month; -- pc->rel.year += $2.year; -- pc->rels_seen = true; -+ apply_relative_time (pc, $2, 1); - } - ; - -@@ -688,10 +676,10 @@ static table const time_units_table[] = - /* Assorted relative-time words. */ - static table const relative_time_table[] = - { -- { "TOMORROW", tDAY_UNIT, 1 }, -- { "YESTERDAY",tDAY_UNIT, -1 }, -- { "TODAY", tDAY_UNIT, 0 }, -- { "NOW", tDAY_UNIT, 0 }, -+ { "TOMORROW", tDAY_SHIFT, 1 }, -+ { "YESTERDAY",tDAY_SHIFT, -1 }, -+ { "TODAY", tDAY_SHIFT, 0 }, -+ { "NOW", tDAY_SHIFT, 0 }, - { "LAST", tORDINAL, -1 }, - { "THIS", tORDINAL, 0 }, - { "NEXT", tORDINAL, 1 }, -@@ -814,15 +802,33 @@ static table const military_table[] = - - /* Convert a time zone expressed as HH:MM into an integer count of - minutes. If MM is negative, then S is of the form HHMM and needs -- to be picked apart; otherwise, S is of the form HH. */ -+ to be picked apart; otherwise, S is of the form HH. As specified in -+ http://www.opengroup.org/susv3xbd/xbd_chap08.html#tag_08_03, allow -+ only valid TZ range, and consider first two digits as hours, if no -+ minutes specified. */ - - static long int --time_zone_hhmm (textint s, long int mm) -+time_zone_hhmm (parser_control *pc, textint s, long int mm) - { -+ long int n_minutes; -+ -+ /* If the length of S is 1 or 2 and no minutes are specified, -+ interpret it as a number of hours. */ -+ if (s.digits <= 2 && mm < 0) -+ s.value *= 100; -+ - if (mm < 0) -- return (s.value / 100) * 60 + s.value % 100; -+ n_minutes = (s.value / 100) * 60 + s.value % 100; - else -- return s.value * 60 + (s.negative ? -mm : mm); -+ n_minutes = s.value * 60 + (s.negative ? -mm : mm); -+ -+ /* If the absolute number of minutes is larger than 24 hours, -+ arrange to reject it by incrementing pc->zones_seen. Thus, -+ we allow only values in the range UTC-24:00 to UTC+24:00. */ -+ if (24 * 60 < abs (n_minutes)) -+ pc->zones_seen++; -+ -+ return n_minutes; - } - - static int -@@ -919,7 +925,7 @@ lookup_word (parser_control const *pc, c - for (p = word; *p; p++) - { - unsigned char ch = *p; -- *p = toupper (ch); -+ *p = c_toupper (ch); - } - - for (tp = meridian_table; tp->name; tp++) -@@ -984,7 +990,7 @@ yylex (YYSTYPE *lvalp, parser_control *p - - for (;;) - { -- while (c = *pc->input, isspace (c)) -+ while (c = *pc->input, c_isspace (c)) - pc->input++; - - if (ISDIGIT (c) || c == '-' || c == '+') -@@ -995,7 +1001,7 @@ yylex (YYSTYPE *lvalp, parser_control *p - if (c == '-' || c == '+') - { - sign = c == '-' ? -1 : 1; -- while (c = *++pc->input, isspace (c)) -+ while (c = *++pc->input, c_isspace (c)) - continue; - if (! ISDIGIT (c)) - /* skip the '-' sign */ -@@ -1099,7 +1105,7 @@ yylex (YYSTYPE *lvalp, parser_control *p - } - } - -- if (isalpha (c)) -+ if (c_isalpha (c)) - { - char buff[20]; - char *p = buff; -@@ -1111,7 +1117,7 @@ yylex (YYSTYPE *lvalp, parser_control *p - *p++ = c; - c = *++pc->input; - } -- while (isalpha (c) || c == '.'); -+ while (c_isalpha (c) || c == '.'); - - *p = '\0'; - tp = lookup_word (pc, buff); -@@ -1224,7 +1230,7 @@ get_date (struct timespec *result, char - if (! tmp) - return false; - -- while (c = *p, isspace (c)) -+ while (c = *p, c_isspace (c)) - p++; - - if (strncmp (p, "TZ=\"", 4) == 0) -@@ -1436,25 +1442,6 @@ get_date (struct timespec *result, char - goto fail; - } - -- if (pc.zones_seen) -- { -- long int delta = pc.time_zone * 60; -- time_t t1; --#ifdef HAVE_TM_GMTOFF -- delta -= tm.tm_gmtoff; --#else -- time_t t = Start; -- struct tm const *gmt = gmtime (&t); -- if (! gmt) -- goto fail; -- delta -= tm_diff (&tm, gmt); --#endif -- t1 = Start - delta; -- if ((Start < t1) != (delta < 0)) -- goto fail; /* time_t overflow */ -- Start = t1; -- } -- - /* Add relative date. */ - if (pc.rel.year | pc.rel.month | pc.rel.day) - { -@@ -1477,6 +1464,27 @@ get_date (struct timespec *result, char - goto fail; - } - -+ /* The only "output" of this if-block is an updated Start value, -+ so this block must follow others that clobber Start. */ -+ if (pc.zones_seen) -+ { -+ long int delta = pc.time_zone * 60; -+ time_t t1; -+#ifdef HAVE_TM_GMTOFF -+ delta -= tm.tm_gmtoff; -+#else -+ time_t t = Start; -+ struct tm const *gmt = gmtime (&t); -+ if (! gmt) -+ goto fail; -+ delta -= tm_diff (&tm, gmt); -+#endif -+ t1 = Start - delta; -+ if ((Start < t1) != (delta < 0)) -+ goto fail; /* time_t overflow */ -+ Start = t1; -+ } -+ - /* Add relative hours, minutes, and seconds. On hosts that support - leap seconds, ignore the possibility of leap seconds; e.g., - "+ 10 minutes" adds 600 seconds, even if one of them is a diff --git a/coreutils-6.12-dd-fullblock.patch b/coreutils-6.12-dd-fullblock.patch deleted file mode 100644 index d8fbbf1..0000000 --- a/coreutils-6.12-dd-fullblock.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 9f8be4b0b83d1e0cbf1326f8cb7e077d026d9b0b Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Wed, 23 Jul 2008 11:29:21 +0200 -Subject: [PATCH] dd: iflag=fullblock now read full blocks if possible -* src/dd.c (iread_fullblock): New function for reading full blocks. -(scanargs): Check for new parameter iflag=fullblock. -(skip): Use iread_fnc pointer instead of iread function. -(dd_copy): Use iread_fnc pointer instead of iread function. -* tests/dd/misc: Add test for dd - read full blocks. -* doc/coretuils.texi: Mention new parameter iflag=fullblock. -* NEWS: Mentioned the change. - ---- - NEWS | 4 ++++ - doc/coreutils.texi | 6 ++++++ - src/dd.c | 39 +++++++++++++++++++++++++++++++++++++-- - tests/dd/misc | 9 +++++++++ - 4 files changed, 56 insertions(+), 2 deletions(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 81e3b91..b95f8dc 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -7719,6 +7719,12 @@ platforms that distinguish binary from text I/O. - Use text I/O. Like @samp{binary}, this option has no effect on - standard platforms. - -+@item fullblock -+@opindex fullblock -+Read full blocks from input if possible. read() may return early -+if a full block is not available, so retry until data is available -+or end of file is reached. This flag can be used only for the iflag option. -+ - @end table - - These flags are not supported on all systems, and @samp{dd} rejects -diff --git a/src/dd.c b/src/dd.c -index ead9574..1b620df 100644 ---- a/src/dd.c -+++ b/src/dd.c -@@ -225,6 +225,9 @@ static sig_atomic_t volatile interrupt_signal; - /* A count of the number of pending info signals that have been received. */ - static sig_atomic_t volatile info_signal_count; - -+/* Function used for read (to handle iflag=fullblock parameter) */ -+static ssize_t (*iread_fnc) (int fd, char *buf, size_t size); -+ - /* A longest symbol in the struct symbol_values tables below. */ - #define LONGEST_SYMBOL "fdatasync" - -@@ -257,6 +260,7 @@ static struct symbol_value const conversions[] = - }; - - /* Flags, for iflag="..." and oflag="...". */ -+#define O_FULLBLOCK 010000000 /* Read only full blocks from input */ - static struct symbol_value const flags[] = - { - {"append", O_APPEND}, -@@ -271,6 +275,7 @@ static struct symbol_value const flags[] = - {"nonblock", O_NONBLOCK}, - {"sync", O_SYNC}, - {"text", O_TEXT}, -+ {"fullblock", O_FULLBLOCK}, /* Read only full blocks from input */ - {"", 0} - }; - -@@ -496,6 +496,8 @@ Each FLAG symbol may be:\n\ - fputs (_(" dsync use synchronized I/O for data\n"), stdout); - if (O_SYNC) - fputs (_(" sync likewise, but also for metadata\n"), stdout); -+ fputs (_(" fullblock accumulate full blocks of input (iflag only)\n"), -+ stdout); - if (O_NONBLOCK) - fputs (_(" nonblock use non-blocking I/O\n"), stdout); - if (O_NOATIME) -@@ -762,6 +769,27 @@ iread (int fd, char *buf, size_t size) - } - } - -+/* Wrapper around iread function which reads full blocks if possible */ -+static ssize_t -+iread_fullblock (int fd, char *buf, size_t size) -+{ -+ ssize_t nread = 0; -+ -+ while (0 < size) -+ { -+ ssize_t ncurr = iread(fd, buf, size); -+ if (ncurr < 0) -+ return ncurr; -+ if (ncurr == 0) -+ break; -+ nread += ncurr; -+ buf += ncurr; -+ size -= ncurr; -+ } -+ -+ return nread; -+} -+ - /* Write to FD the buffer BUF of size SIZE, processing any signals - that arrive. Return the number of bytes written, setting errno if - this is less than SIZE. Keep trying if there are partial -@@ -1000,6 +1028,15 @@ scanargs (int argc, char *const *argv) - if (input_flags & (O_DSYNC | O_SYNC)) - input_flags |= O_RSYNC; - -+ if (output_flags & O_FULLBLOCK) -+ { -+ error (0, 0, "%s: %s", _("invalid output flag"), "'fullblock'"); -+ usage (EXIT_FAILURE); -+ } -+ iread_fnc = (input_flags & O_FULLBLOCK)? -+ iread_fullblock: -+ iread; -+ - if (multiple_bits_set (conversions_mask & (C_ASCII | C_EBCDIC | C_IBM))) - error (EXIT_FAILURE, 0, _("cannot combine any two of {ascii,ebcdic,ibm}")); - if (multiple_bits_set (conversions_mask & (C_BLOCK | C_UNBLOCK))) -@@ -1197,7 +1234,7 @@ skip (int fdesc, char const *file, uintmax_t records, size_t blocksize, - - do - { -- ssize_t nread = iread (fdesc, buf, blocksize); -+ ssize_t nread = iread_fnc (fdesc, buf, blocksize); - if (nread < 0) - { - if (fdesc == STDIN_FILENO) -@@ -1508,7 +1545,7 @@ dd_copy (void) - (conversions_mask & (C_BLOCK | C_UNBLOCK)) ? ' ' : '\0', - input_blocksize); - -- nread = iread (STDIN_FILENO, ibuf, input_blocksize); -+ nread = iread_fnc (STDIN_FILENO, ibuf, input_blocksize); - - if (nread == 0) - break; /* EOF. */ -diff --git a/tests/dd/misc b/tests/dd/misc -index d54fbfa..24e5eba 100755 ---- a/tests/dd/misc -+++ b/tests/dd/misc -@@ -88,6 +88,15 @@ fi - outbytes=`echo x | dd bs=3 ibs=10 obs=10 conv=sync 2>/dev/null | wc -c` - test "$outbytes" -eq 3 || fail=1 - -+(echo a; sleep .1; echo b) \ -+ | LC_ALL=C dd bs=4 status=noxfer iflag=fullblock >out 2>err || fail=1 -+echo "a -+b" > out_ok -+echo "1+0 records in -+1+0 records out" > err_ok -+compare out out_ok || fail=1 -+compare err err_ok || fail=1 -+ - test $fail -eq 0 && fail=$warn - - (exit $fail); exit $fail -diff -ruN coreutils-6.12.old/doc/coreutils.info coreutils-6.12/doc/coreutils.info ---- coreutils-6.12.old/doc/coreutils.info 2008-07-24 12:49:57.000000000 +0200 -+++ coreutils-6.12/doc/coreutils.info 2008-07-24 12:52:17.000000000 +0200 -@@ -6112,6 +6112,12 @@ - Use text I/O. Like `binary', this option has no effect on - standard platforms. - -+ 'fullblock' -+ Read full blocks from input if possible. read() may return -+ early if a full block is not available, so retry until data -+ is available or end of file is reached. This flag can be used -+ only for the iflag option. -+ - - These flags are not supported on all systems, and `dd' rejects - attempts to use them when they are not supported. When reading diff --git a/coreutils-6.12-ls-constant_mem.patch b/coreutils-6.12-ls-constant_mem.patch deleted file mode 100644 index 7643ee9..0000000 --- a/coreutils-6.12-ls-constant_mem.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Kamil Dudka -Date: Wed, 30 Jul 2008 12:31:50 +0000 (+0200) -Subject: ls -U1 now uses constant memory -X-Git-Url: http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff_plain;h=8d974b00fbbc2025de63e1e6d54827648fefa1c4 - -ls -U1 now uses constant memory - -When printing one name per line and not sorting, ls now uses -constant memory per directory, no matter how many files are in -the directory. -* ls.c (print_dir): Print each file name immediately, when possible. ---- - -diff --git a/src/ls.c b/src/ls.c -index 4b69f7d..a661c06 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -2402,6 +2402,20 @@ print_dir (char const *name, char const *realname, bool command_line_arg) - #endif - total_blocks += gobble_file (next->d_name, type, D_INO (next), - false, name); -+ -+ /* In this narrow case, print out each name right away, so -+ ls uses constant memory while processing the entries of -+ this directory. Useful when there are many (millions) -+ of entries in a directory. */ -+ if (format == one_per_line && sort_type == sort_none) -+ { -+ /* We must call sort_files in spite of -+ "sort_type == sort_none" for its initialization -+ of the sorted_file vector. */ -+ sort_files (); -+ print_current_files (); -+ clear_files (); -+ } - } - } - else if (errno != 0) diff --git a/coreutils-6.12-ls-libcap.patch b/coreutils-6.12-ls-libcap.patch deleted file mode 100644 index 12e0170..0000000 --- a/coreutils-6.12-ls-libcap.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 7634188624dc7f48c047b29fab3715dc7a468059 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Wed, 23 Jul 2008 09:52:05 +0200 -Subject: [PATCH] ls: --color now highlights files with capabilities, too -* configure.ac: New option: --disable-libcap. Check for libcap usability. -* src/Makefile.am (dir_LDADD, ls_LDADD, ...): Append $(LIB_CAP). -* src/ls.c: [HAVE_CAP] Include . -(has_capability): New function for capability detection. -(print_color_indicator): Colorize file with capability. -* src/dircolors.c: Update color lists. -* src/dircolors.hin: Mention new CAPABILITY color attribute. -* tests/ls/capability: Test for ls - colorize file with capability. -* tests/Makefile.am (TESTS): Add ls/capability. -* NEWS: Mention the change. - ---- - NEWS | 2 ++ - configure.ac | 13 +++++++++++++ - src/Makefile.am | 6 +++--- - src/dircolors.c | 4 ++-- - src/dircolors.hin | 1 + - src/ls.c | 43 +++++++++++++++++++++++++++++++++++++++++-- - tests/Makefile.am | 1 + - tests/ls/capability | 43 +++++++++++++++++++++++++++++++++++++++++++ - 8 files changed, 106 insertions(+), 7 deletions(-) - create mode 100755 tests/ls/capability - -diff -ruN coreutils-6.12.old/configure.ac coreutils-6.12/configure.ac ---- coreutils-6.12.old/configure.ac 2008-07-24 14:16:32.000000000 +0200 -+++ coreutils-6.12/configure.ac 2008-07-24 14:18:51.000000000 +0200 -@@ -58,6 +58,19 @@ - LIB_SELINUX="-lselinux" - AC_SUBST(LIB_SELINUX)]) - -+dnl Check whether libcap is usable -+AC_ARG_ENABLE([libcap], -+ AC_HELP_STRING([--disable-libcap], [disable libcap support]), -+ AC_MSG_WARN([libcap support disabled by user]), -+ [AC_CHECK_LIB([cap], [cap_get_file], -+ [AC_CHECK_HEADER([sys/capability.h], -+ [LIB_CAP="-lcap" AC_DEFINE(HAVE_CAP, 1, [libcap usability])], -+ [AC_MSG_WARN([header sys/capability.h was not found, support for libcap will not be built])] -+ )], -+ [AC_MSG_WARN([libcap library was not found or not usable, support for libcap will not be built])]) -+ ]) -+AC_SUBST([LIB_CAP]) -+ - AC_FUNC_FORK - - optional_bin_progs= -diff -ruN coreutils-6.12.orig/src/Makefile.am coreutils-6.12/src/Makefile.am ---- coreutils-6.12.orig/src/Makefile.am 2008-07-10 12:30:03.000000000 +0200 -+++ coreutils-6.12/src/Makefile.am 2008-07-24 13:18:43.000000000 +0200 -@@ -98,15 +98,15 @@ - - # for clock_gettime and fdatasync - dd_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC) --dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) -+dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) - id_LDADD = $(LDADD) $(LIB_SELINUX) --ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) -+ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) - mktemp_LDADD = $(LDADD) $(LIB_GETHRXTIME) - pr_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) - shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC) - shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME) - tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) --vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) -+vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) - tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) - - ## If necessary, add -lm to resolve use of pow in lib/strtod.c. -diff --git a/src/dircolors.c b/src/dircolors.c -index 56194f7..79109b9 100644 ---- a/src/dircolors.c -+++ b/src/dircolors.c -@@ -63,14 +63,14 @@ static const char *const slack_codes[] = - "SYMLINK", "ORPHAN", "MISSING", "FIFO", "PIPE", "SOCK", "BLK", "BLOCK", - "CHR", "CHAR", "DOOR", "EXEC", "LEFT", "LEFTCODE", "RIGHT", "RIGHTCODE", - "END", "ENDCODE", "SUID", "SETUID", "SGID", "SETGID", "STICKY", -- "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE", "OWT", NULL -+ "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE", "OWT", "CAPABILITY", NULL - }; - - static const char *const ls_codes[] = - { - "no", "no", "fi", "rs", "di", "ln", "ln", "ln", "or", "mi", "pi", "pi", - "so", "bd", "bd", "cd", "cd", "do", "ex", "lc", "lc", "rc", "rc", "ec", "ec", -- "su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", NULL -+ "su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", "ca", NULL - }; - #define array_len(Array) (sizeof (Array) / sizeof *(Array)) - verify (array_len (slack_codes) == array_len (ls_codes)); -diff --git a/src/dircolors.hin b/src/dircolors.hin -index 38914c8..5137cc6 100644 ---- a/src/dircolors.hin -+++ b/src/dircolors.hin -@@ -77,6 +77,7 @@ CHR 40;33;01 # character device driver - ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file - SETUID 37;41 # file that is setuid (u+s) - SETGID 30;43 # file that is setgid (g+s) -+CAPABILITY 30;41 # file with capability - STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) - OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky - STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable -diff --git a/src/ls.c b/src/ls.c -index 4b69f7d..9bc66a1 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -38,6 +38,10 @@ - #include - #include - -+#ifdef HAVE_CAP -+# include -+#endif -+ - #if HAVE_TERMIOS_H - # include - #endif -@@ -513,14 +517,14 @@ enum indicator_no - C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK, - C_FIFO, C_SOCK, - C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID, -- C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE -+ C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP - }; - - static const char *const indicator_name[]= - { - "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so", - "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st", -- "ow", "tw", NULL -+ "ow", "tw", "ca", NULL - }; - - struct color_ext_type -@@ -553,6 +557,7 @@ static struct bin_str color_indicator[] = - { LEN_STR_PAIR ("37;44") }, /* st: sticky: black on blue */ - { LEN_STR_PAIR ("34;42") }, /* ow: other-writable: blue on green */ - { LEN_STR_PAIR ("30;42") }, /* tw: ow w/ sticky: black on green */ -+ { LEN_STR_PAIR ("30;41") }, /* ca: black on red */ - }; - - /* FIXME: comment */ -@@ -3896,6 +3901,38 @@ print_type_indicator (bool stat_ok, mode_t mode, enum filetype type) - DIRED_PUTCHAR (c); - } - -+#ifdef HAVE_CAP -+static bool -+/* Return true if NAME has a capability (see linux/capability.h) */ -+has_capability (const char *name) -+{ -+ cap_t cap_d; -+ char *result; -+ bool has_cap; -+ -+ cap_d = cap_get_file (name); -+ if (cap_d == NULL) -+ return false; -+ -+ result = cap_to_text (cap_d, NULL); -+ cap_free (cap_d); -+ if (!result) -+ return false; -+ -+ /* check if human-readable capability string is empty */ -+ has_cap = !!*result; -+ -+ cap_free (result); -+ return has_cap; -+} -+#else -+static bool -+has_capability (const char *name) -+{ -+ return false; -+} -+#endif -+ - /* Returns whether any color sequence was printed. */ - static bool - print_color_indicator (const char *name, mode_t mode, int linkok, -@@ -3923,6 +3960,8 @@ print_color_indicator (const char *name, mode_t mode, int linkok, - type = C_SETUID; - else if ((mode & S_ISGID) != 0) - type = C_SETGID; -+ else if (is_colored (C_CAP) && has_capability (name)) -+ type = C_CAP; - else if ((mode & S_IXUGO) != 0) - type = C_EXEC; - } -diff --git a/tests/Makefile.am b/tests/Makefile.am -index c2da630..309d174 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -313,6 +313,7 @@ TESTS = \ - ln/misc \ - ln/sf-1 \ - ln/target-1 \ -+ ls/capability \ - ls/color-dtype-dir \ - ls/dangle \ - ls/dired \ -diff --git a/tests/ls/capability b/tests/ls/capability -new file mode 100755 -index 0000000..549e06b ---- /dev/null -+++ b/tests/ls/capability -@@ -0,0 +1,43 @@ -+#!/bin/sh -+# Ensure "ls --color" properly colorizes file with capability. -+ -+# Copyright (C) 2008 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 . -+ -+if test "$VERBOSE" = yes; then -+ set -x -+ ls --version -+fi -+ -+. $srcdir/test-lib.sh -+require_root_ -+ -+(setcap --help) 2>&1 |grep 'usage: setcap' > /dev/null \ -+ || skip_test_ "setcap utility not found" -+fail=0 -+ -+# Don't let a different umask perturb the results. -+umask 22 -+ -+touch test -+setcap cap_net_bind_service=ep test \ -+ || framework_failure -+code='30;41' -+LS_COLORS="ca=$code" \ -+ ls --color=always test > out || fail=1 -+printf "\033[0m\033[${code}mtest\033[0m\n\033[m" > out_ok || fail=1 -+compare out out_ok || fail=1 -+ -+(exit $fail); exit $fail --- -1.5.4.1 - diff --git a/coreutils-6.12-seqdecimalutf8.patch b/coreutils-6.12-seqdecimalutf8.patch deleted file mode 100644 index 1436acf..0000000 --- a/coreutils-6.12-seqdecimalutf8.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -urNp coreutils-6.12-orig/src/seq.c coreutils-6.12/src/seq.c ---- coreutils-6.12-orig/src/seq.c 2008-05-26 08:40:32.000000000 +0200 -+++ coreutils-6.12/src/seq.c 2008-09-29 22:09:21.000000000 +0200 -@@ -304,7 +304,10 @@ print_numbers (char const *fmt, struct l - bool print_extra_number = false; - long double x_val; - char *x_str; -- int x_strlen = asprintf (&x_str, fmt, x); -+ int x_strlen; -+ setlocale (LC_NUMERIC, "C"); -+ x_strlen = asprintf (&x_str, fmt, x); -+ setlocale (LC_NUMERIC, ""); - if (x_strlen < 0) - xalloc_die (); - x_str[x_strlen - layout.suffix_len] = '\0'; diff --git a/coreutils-6.12-utimenstouchcp.patch b/coreutils-6.12-utimenstouchcp.patch deleted file mode 100644 index 4e90583..0000000 --- a/coreutils-6.12-utimenstouchcp.patch +++ /dev/null @@ -1,89 +0,0 @@ -diff -Naurp coreutils-6.12.orig/lib/utimens.c coreutils-6.12/lib/utimens.c ---- coreutils-6.12.orig/lib/utimens.c 2008-10-06 16:21:11.000000000 -0400 -+++ coreutils-6.12/lib/utimens.c 2008-10-06 16:26:33.000000000 -0400 -@@ -103,6 +103,18 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, - if (fd < 0) - { - int result = utimensat (AT_FDCWD, file, timespec, 0); -+# ifdef __linux__ -+ /* Work around xen kernel bug: -+ http://bugzilla.redhat.com/442352 -+ http://bugzilla.redhat.com/449910 -+ When running on a sufficiently old (pre-RHEL5.3) x86_64 xen -+ kernel, utimensat can mistakenly return its syscall number (280 on -+ x86_64) rather than the proper ENOSYS code, due to a xen bug. -+ FIXME: remove in 2010 or whenever the offending kernels -+ are no longer in common use. */ -+ if (0 < result) -+ errno = ENOSYS; -+# endif - if (result == 0 || errno != ENOSYS) - return result; - } -@@ -110,6 +122,18 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, - #if HAVE_FUTIMENS - { - int result = futimens (fd, timespec); -+# ifdef __linux__ -+ /* Work around xen kernel bug: -+ http://bugzilla.redhat.com/442352 -+ http://bugzilla.redhat.com/449910 -+ When running on a sufficiently old (pre-RHEL5.3) x86_64 xen -+ kernel, utimensat can mistakenly return its syscall number (280 on -+ x86_64) rather than the proper ENOSYS code, due to a xen bug. -+ FIXME: remove in 2010 or whenever the offending kernels -+ are no longer in common use. */ -+ if (0 < result) -+ errno = ENOSYS; -+# endif - if (result == 0 || errno != ENOSYS) - return result; - } -diff -Naurp coreutils-6.12.orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am ---- coreutils-6.12.orig/tests/Makefile.am 2008-10-06 16:21:11.000000000 -0400 -+++ coreutils-6.12/tests/Makefile.am 2008-10-06 16:22:04.000000000 -0400 -@@ -215,6 +215,7 @@ TESTS = \ - misc/tty-eof \ - misc/unexpand \ - misc/uniq \ -+ misc/utimensat-touchcp \ - chmod/c-option \ - chmod/equal-x \ - chmod/equals \ -diff -Naurp coreutils-6.12.orig/tests/misc/utimensat-touchcp coreutils-6.12/tests/misc/utimensat-touchcp ---- coreutils-6.12.orig/tests/misc/utimensat-touchcp 1969-12-31 19:00:00.000000000 -0500 -+++ coreutils-6.12/tests/misc/utimensat-touchcp 2008-10-06 16:22:04.000000000 -0400 -@@ -0,0 +1,33 @@ -+#!/bin/sh -+# Make sure touch -r and cp -pr works without hanging. -+ -+if test "$VERBOSE" = yes; then -+ set -x -+ touch --version -+ cp --version -+fi -+ -+. $srcdir/test-lib.sh -+ -+touch a.old || framework_failure -+sleep 1 -+ -+fail=0 -+ -+#check for touch -+touch -r a.old a || fail=1 -+ls -l --full-time a >time1 -+ls -l --full-time a.old >time2 -+sed -i 's/a.old/a/' time2 -+cmp time1 time2 > /dev/null 2>&1 || fail=1 -+test $fail = 1 && diff time1 time2 2> /dev/null -+ -+#check for cp -+cp -pr a.old b || fail=1 -+ls -l --full-time a >time1 -+ls -l --full-time a.old >time2 -+sed -i 's/a.old/a/' time2 -+cmp time1 time2 > /dev/null 2>&1 || fail=1 -+test $fail = 1 && diff time1 time2 2> /dev/null -+ -+(exit $fail); exit $fail diff --git a/coreutils-7.0-dftotal.patch b/coreutils-7.0-dftotal.patch new file mode 100644 index 0000000..a719263 --- /dev/null +++ b/coreutils-7.0-dftotal.patch @@ -0,0 +1,112 @@ +diff -urNp coreutils-7.0-orig/tests/df/total coreutils-7.0/tests/df/total +--- coreutils-7.0-orig/tests/df/total 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/tests/df/total 2008-11-11 16:56:17.000000000 +0100 +@@ -30,11 +30,8 @@ umask 22 + + RE_TOTAL='^total( +(-?[0-9]+|-)){3} +-?[0-9]+%$' + +-df > tmp || fail=1 +-$EGREP "$RE_TOTAL" tmp && fail=1 +- +-df -i > tmp || fail=1 +-$EGREP "$RE_TOTAL" tmp && fail=1 ++df | $EGREP "$RE_TOTAL" tmp && fail=1 ++df -i | $EGREP "$RE_TOTAL" tmp && fail=1 + + df --total | $EGREP "$RE_TOTAL" || fail=1 + df -i --total | $EGREP "$RE_TOTAL" || fail=1 +diff -urNp coreutils-7.0-orig/tests/df/total-awk coreutils-7.0/tests/df/total-awk +--- coreutils-7.0-orig/tests/df/total-awk 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/tests/df/total-awk 2008-11-11 16:54:49.000000000 +0100 +@@ -23,58 +23,42 @@ fi + + . $srcdir/test-lib.sh + +-fail=0 +- +-# Don't let a different umask perturb the results. +-umask 22 +- +-echo ' +-BEGIN { +- total = 0 +- used = 0 +- available = 0 +-} +-{ +- if (NR==1 || $0==$1 || $0~/^total +(-?[0-9]+|-) +(-?[0-9]+|-) +(-?[0-9]+|-) +-?[0-9]+%$/) +- next +- if ($1~/^[0-9]/) +- { +- total += $1 +- used += $2 +- available += $3 +- } +- else +- { +- total += $2 +- used += $3 +- available += $4 +- } +-} +-END { +- print total +- print used +- print available +-} +-' > compute_sum.awk || fail=1 +- +-echo ' +-/^total +(-?[0-9]+|-) +(-?[0-9]+|-) +(-?[0-9]+|-) +-?[0-9]+%$/ { +- print $2; +- print $3; +- print $4 +-} +-' > parse_total.awk || fail=1 ++cat <<\EOF > check-df || framework_failure ++my ($total, $used, $avail) = (0, 0, 0); ++while (<>) ++ { ++ $. == 1 ++ and next; # skip first (header) line ++ # Recognize df output lines like these: ++ # /dev/sdc1 0 0 0 - /c ++ # tmpfs 1536000 12965 1523035 1% /tmp ++ # total 5285932 787409 4498523 15% ++ /^(.*?) +(-?\d+|-) +(-?\d+|-) +(-?\d+|-) +(?:- |[0-9]+%)(.*)$/ ++ or die "$0: invalid input line\n: $_"; ++ if ($1 eq 'total' && $5 eq '') ++ { ++ $total == $2 or die "$total != $2"; ++ $used == $3 or die "$used != $3"; ++ $avail == $4 or die "$avail != $4"; ++ my $line = <>; ++ defined $line ++ and die "$0: extra line(s) after totals\n"; ++ exit 0; ++ } ++ $total += $2 unless $2 eq '-'; ++ $used += $3 unless $3 eq '-'; ++ $avail += $4 unless $4 eq '-'; ++ } ++die "$0: missing line of totals\n"; ++EOF + + # Use --block-size=512 to keep df from printing rounded-to-kilobyte + # numbers which wouldn't necessarily add up to the displayed total. +-df --block-size=512 --total |tee tmp || fail=1 +-$AWK -f compute_sum.awk tmp > out1 || fail=1 +-$AWK -f parse_total.awk tmp > out2 || fail=1 +-compare out1 out2 || fail=1 ++df --total -P --block-size=512 |tee space || framework_failure ++df --total -i -P |tee inode || framework_failure + +-df -i --block-size=512 --total |tee tmp || fail=1 +-$AWK -f compute_sum.awk tmp > out1 || fail=1 +-$AWK -f parse_total.awk tmp > out2 || fail=1 +-compare out1 out2 || fail=1 ++fail=0 ++$PERL -f check-df space || fail=1 ++$PERL -f check-df inode || fail=1 + + Exit $fail diff --git a/coreutils-authors.patch b/coreutils-authors.patch deleted file mode 100644 index ec76fe0..0000000 --- a/coreutils-authors.patch +++ /dev/null @@ -1,61 +0,0 @@ -Signed-off-by: Ondřej Vašík -Signed-off-by: Jim Meyering - -* src/echo.c (AUTHORS) : Use bash builtin echo authors instead of FIXME unknown -* src/basename.c (AUTHORS): List David as the author. -* AUTHORS: Update here, too. ---- - AUTHORS | 4 ++-- - src/basename.c | 2 +- - src/echo.c | 4 +++- - 3 files changed, 6 insertions(+), 4 deletions(-) -diff --git a/src/basename.c b/src/basename.c -index 38e8879..69b708f 100644 ---- a/src/basename.c -+++ b/src/basename.c -@@ -37,7 +37,7 @@ - /* The official name of this program (e.g., no `g' prefix). */ - #define PROGRAM_NAME "basename" - --#define AUTHORS proper_name ("FIXME unknown") -+#define AUTHORS proper_name ("David MacKenzie") - - /* The name this program was run with. */ - char *program_name; -diff --git a/AUTHORS b/AUTHORS -index 404cf70..666edc1 100644 ---- a/AUTHORS -+++ b/AUTHORS -@@ -3,7 +3,7 @@ each followed by the name(s) of its author(s). - - arch: David MacKenzie, Karel Zak - base64: Simon Josefsson --basename: FIXME unknown -+basename: David MacKenzie - cat: Torbjörn Granlund, Richard M. Stallman - chcon: Russell Coker, Jim Meyering - chgrp: David MacKenzie, Jim Meyering -@@ -22,7 +22,7 @@ dir: Richard M. Stallman, David MacKenzie - dircolors: H. Peter Anvin - dirname: David MacKenzie, Jim Meyering - du: Torbjörn Granlund, David MacKenzie, Paul Eggert, Jim Meyering --echo: FIXME unknown -+echo: Brian Fox, Chet Ramey - env: Richard Mlynarik, David MacKenzie - expand: David MacKenzie - expr: Mike Parker -diff --git a/src/echo.c b/src/echo.c -index ebbf5b8..11e648e 100644 ---- a/src/echo.c -+++ b/src/echo.c -@@ -24,7 +24,9 @@ - /* The official name of this program (e.g., no `g' prefix). */ - #define PROGRAM_NAME "echo" - --#define AUTHORS proper_name ("FIXME unknown") -+#define AUTHORS \ -+ proper_name ("Brian Fox"), \ -+ proper_name ("Chet Ramey") - - /* echo [-neE] [arg ...] - Output the ARGs. If -n is specified, the trailing newline is diff --git a/coreutils-futimensatkoji.patch b/coreutils-futimensatkoji.patch deleted file mode 100644 index f00b8f0..0000000 --- a/coreutils-futimensatkoji.patch +++ /dev/null @@ -1,119 +0,0 @@ -From b566edc2489a889d97416d2390be7796aa8cdbeb Mon Sep 17 00:00:00 2001 -From: Eric Blake -Date: Mon, 2 Jun 2008 15:08:14 -0600 -Subject: [PATCH] Provide futimens/utimensat fallbacks for older kernels. - -* lib/utimens.c (gl_futimens) [HAVE_UTIMENSAT, HAVE_FUTIMENS]: -Provide runtime fallback if kernel lacks support. -Reported by Mike Frysinger. - -Signed-off-by: Eric Blake ---- - lib/utimens.c | 43 ++++++++++++++++++++++++++----------------- - 1 file changed, 26 insertions(+), 17 deletions(-) - -diff --git a/lib/utimens.c b/lib/utimens.c -index 25bc965..134310b 100644 ---- a/lib/utimens.c -+++ b/lib/utimens.c -@@ -96,20 +96,30 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, - #endif - - /* POSIX 200x added two interfaces to set file timestamps with -- nanosecond resolution. */ -+ nanosecond resolution. We provide a fallback for ENOSYS (for -+ example, compiling against Linux 2.6.25 kernel headers and glibc -+ 2.7, but running on Linux 2.6.18 kernel). */ - #if HAVE_UTIMENSAT - if (fd < 0) -- return utimensat (AT_FDCWD, file, timespec, 0); -+ { -+ int result = utimensat (AT_FDCWD, file, timespec, 0); -+ if (result == 0 || errno != ENOSYS) -+ return result; -+ } - #endif - #if HAVE_FUTIMENS -- return futimens (fd, timespec); --#else -+ { -+ int result = futimens (fd, timespec); -+ if (result == 0 || errno != ENOSYS) -+ return result; -+ } -+#endif - - /* The platform lacks an interface to set file timestamps with - nanosecond resolution, so do the best we can, discarding any - fractional part of the timestamp. */ - { --# if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES -+#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES - struct timeval timeval[2]; - struct timeval const *t; - if (timespec) -@@ -125,9 +135,9 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, - - if (fd < 0) - { --# if HAVE_FUTIMESAT -+# if HAVE_FUTIMESAT - return futimesat (AT_FDCWD, file, t); --# endif -+# endif - } - else - { -@@ -141,21 +151,21 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, - worth optimizing, and who knows what other messed-up systems - are out there? So play it safe and fall back on the code - below. */ --# if HAVE_FUTIMESAT -+# if HAVE_FUTIMESAT - if (futimesat (fd, NULL, t) == 0) - return 0; --# elif HAVE_FUTIMES -+# elif HAVE_FUTIMES - if (futimes (fd, t) == 0) - return 0; --# endif -+# endif - } --# endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */ -+#endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */ - - if (!file) - { --# if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) -+#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES)) - errno = ENOSYS; --# endif -+#endif - - /* Prefer EBADF to ENOSYS if both error numbers apply. */ - if (errno == ENOSYS) -@@ -170,9 +180,9 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, - return -1; - } - --# if HAVE_WORKING_UTIMES -+#if HAVE_WORKING_UTIMES - return utimes (file, t); --# else -+#else - { - struct utimbuf utimbuf; - struct utimbuf const *ut; -@@ -187,9 +197,8 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, - - return utime (file, ut); - } --# endif /* !HAVE_WORKING_UTIMES */ -+#endif /* !HAVE_WORKING_UTIMES */ - } --#endif /* !HAVE_FUTIMENS */ - } - - /* Set the access and modification time stamps of FILE to be --- -1.5.5.1 diff --git a/coreutils-getfacl-exit-code.patch b/coreutils-getfacl-exit-code.patch index 837c19d..5a04525 100644 --- a/coreutils-getfacl-exit-code.patch +++ b/coreutils-getfacl-exit-code.patch @@ -20,4 +20,4 @@ +acl2=`cd b && getfacl file` test "$acl1" = "$acl2" || fail=1 - (exit $fail); exit $fail + Exit $fail diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 2f48694..832eadc 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -90,14 +90,14 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am --- coreutils-6.12-orig/tests/Makefile.am 2008-05-27 13:47:53.000000000 +0200 +++ coreutils-6.12/tests/Makefile.am 2008-06-02 10:06:03.000000000 +0200 -@@ -191,6 +191,7 @@ - misc/shuf \ +@@ -192,6 +192,7 @@ misc/sort \ misc/sort-compress \ + misc/sort-files0-from \ + misc/sort-mb-tests \ misc/sort-merge \ misc/sort-rand \ - misc/split-a \ + misc/sort-version \ @@ -391,6 +392,10 @@ $(root_tests) @@ -541,8 +541,8 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am +} +#endif + - static struct line * - dup_line (const struct line *old) + static void + freeline (struct line *line) { @@ -377,11 +601,18 @@ @@ -865,13 +865,13 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c return a pointer to the beginning of the line's field to be compared. */ static char * --find_field (const struct linebuffer *line) +-find_field (struct linebuffer const *line) +find_field_uni (struct linebuffer *line) { size_t count; - char *lp = line->buffer; + char const *lp = line->buffer; @@ -219,6 +245,83 @@ - return lp + i; + return line->buffer + i; } +#if HAVE_MBRTOWC @@ -1214,7 +1214,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c #define TAB_WIDTH 8 /* The official name of this program (e.g., no `g' prefix). */ -@@ -35,23 +57,44 @@ +@@ -35,20 +57,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -1238,9 +1238,6 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + character_mode, +}; + - /* The name this program was run with. */ - char *program_name; - +/* The argument shows current mode. (Default: column_mode) */ +static enum operating_mode operating_mode; + @@ -1735,7 +1732,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c if (hard_LC_TIME) { @@ -1031,6 +1100,64 @@ - #endif + xstrtol_fatal (e, oi, c, long_options, s); } +#if HAVE_MBRTOWC @@ -3900,7 +3897,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + size_t delimlen = 0; initialize_main (&argc, &argv); - program_name = argv[0]; + set_program_name (argv[0]); @@ -770,7 +1090,6 @@ switch (optc) { @@ -4025,10 +4022,10 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c diff -urNp coreutils-6.12/src/join.c coreutils-6.12-orig/src/join.c --- coreutils-6.12/src/join.c 2008-07-16 14:08:01.000000000 +0200 +++ coreutils-6.12-orig/src/join.c 2008-07-16 14:07:02.000000000 +0200 -@@ -489,6 +489,11 @@ get_line (FILE *fp, struct line *line, i - line->nfields_allocated = 0; - line->nfields = 0; - line->fields = NULL; +@@ -634,6 +634,11 @@ get_line (FILE *fp, struct line *line, i + return false; + } + +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) + xfields_multibyte (line); diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 7774cf6..7825b25 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -66,8 +66,8 @@ ATTRIBUTE_NORETURN; +#endif - /* The name this program was run with. */ - char *program_name; + /* If true, pass the `-f' option to the subshell. */ + static bool fast_startup; @@ -225,7 +251,26 @@ } #endif @@ -401,8 +401,8 @@ -might find this idea strange at first. - - - @node Process control - @chapter Process control + @node timeout invocation + @section @command{timeout}: Run a command with a time limit --- coreutils-6.7/configure.ac.pam 2006-12-07 21:30:24.000000000 +0000 +++ coreutils-6.7/configure.ac 2007-01-09 17:18:04.000000000 +0000 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 56b17f8..41b396c 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -37,20 +37,6 @@ diff -urNp coreutils-6.12-orig/man/runcon.x coreutils-6.12/man/runcon.x diff -urNp coreutils-6.12-orig/src/chcon.c coreutils-6.12/src/chcon.c --- coreutils-6.12-orig/src/chcon.c 2008-05-26 08:40:32.000000000 +0200 +++ coreutils-6.12/src/chcon.c 2008-06-16 14:43:24.000000000 +0200 -@@ -302,9 +302,11 @@ process_file (FTS *fts, FTSENT *ent) - - if (ok) - { -- if (verbose) -- printf (_("changing security context of %s"), -+ if (verbose) { -+ printf (_("changing security context of %s"), - quote (file_full_name)); -+ putchar ('\n'); -+ } - - if (change_file_context (fts->fts_cwd_fd, file) != 0) - ok = false; @@ -352,7 +352,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), program_name, program_name, program_name); @@ -209,8 +195,8 @@ diff -urp coreutils-6.10-orig/src/cp.c coreutils-6.10/src/cp.c sparse_type_string, sparse_type); break; -- case 'a': /* Like -dpPR. */ -+ case 'a': /* Like -dpPRc. */ +- case 'a': /* Like -dpR. */ ++ case 'a': /* Like -dpRc. */ x.dereference = DEREF_NEVER; x.preserve_links = true; x.preserve_ownership = true; @@ -296,8 +282,8 @@ diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c - {"preserve_context", no_argument, NULL, PRESERVE_CONTEXT_OPTION}, + {"preserve_context", no_argument, NULL, 'P'}, {"strip", no_argument, NULL, 's'}, + {"strip-program", required_argument, NULL, STRIP_PROGRAM_OPTION}, {"suffix", required_argument, NULL, 'S'}, - {"target-directory", required_argument, NULL, 't'}, @@ -178,6 +178,7 @@ cp_option_init (struct cp_options *x) x->preserve_timestamps = false; x->require_preserve = false; @@ -324,7 +310,7 @@ diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c if ( ! selinux_enabled) { @@ -415,6 +417,10 @@ main (int argc, char **argv) - "this kernel is not SELinux-enabled.")); + "this kernel is not SELinux-enabled")); break; } + if ( x.set_security_context ) { @@ -384,8 +370,8 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c void usage (int status); +static void print_scontext_format (const struct fileinfo *f); - /* The name this program was run with. */ - char *program_name; + /* Initial size of hash table. + Most hierarchies are likely to be shallower than this. */ @@ -314,7 +316,7 @@ static struct pending *pending_dirs; static struct timespec current_time; @@ -871,14 +857,18 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c char *format = NULL; bool ok = true; -@@ -1040,9 +1071,13 @@ main (int argc, char *argv[]) +@@ -1040,13 +1071,13 @@ main (int argc, char *argv[]) terse = true; break; -- case 'Z': /* FIXME: remove in 2010, warn in mid 2008 */ -- /* Ignored, for compatibility with distributions -- that implemented this before upstream. */ -+ case 'Z': +- case 'Z': /* FIXME: remove in 2010 */ +- /* Ignore, for compatibility with distributions +- that implemented this before upstream. +- But warn of impending removal. */ +- error (0, 0, +- _("the --context (-Z) option is obsolete and will be removed\n" +- "in a future release")); ++ case 'Z': + if((is_selinux_enabled()>0)) + secure = 1; + else { diff --git a/coreutils-who_texinfo.patch b/coreutils-who_texinfo.patch deleted file mode 100644 index eb376e7..0000000 --- a/coreutils-who_texinfo.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 63467fa18794f02497c7a46e3b7783ba1180f8fc Mon Sep 17 00:00:00 2001 -From: Jim Meyering -Date: Fri, 4 Jul 2008 16:34:39 +0200 -Subject: [PATCH] who -r: don't print "last=" when the corresponding byte is unprintable - -* src/who.c (print_runlevel): Print last=%c only when the "preceding -run-level" byte is printable. Reported by Gian Piero De Lolliis in -. ---- - src/who.c | 3 ++- - 1 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/src/who.c b/src/who.c -index 5529618..0bba912 100644 ---- a/src/who.c -+++ b/src/who.c -@@ -30,6 +30,7 @@ - #include - #include "system.h" - -+#include "c-ctype.h" - #include "canon-host.h" - #include "readutmp.h" - #include "error.h" -@@ -511,7 +512,7 @@ print_runlevel (const STRUCT_UTMP *utmp_ent) - sprintf (comment, "%s%c", _("last="), (last == 'N') ? 'S' : last); - - print_line (-1, "", ' ', -1, runlevline, time_string (utmp_ent), -- "", "", comment, ""); -+ "", "", c_isprint (last) ? comment : "", ""); - - return; - } --- -1.5.6.1.206.g8dcaf96 - -From 10db2e5e05c67eea205b3ec76a2408f46356a7fd Mon Sep 17 00:00:00 2001 -From: =?utf-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= -Date: Wed, 2 Jul 2008 14:11:05 +0200 -Subject: [PATCH] doci: describe who's -p -r and -t options - -* doc/coreutils.texi (who invocation): ---- - doc/coreutils.texi | 18 ++++++++++++++++++ - 1 files changed, 18 insertions(+), 0 deletions(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 155ba8d..c0ea237 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -12710,6 +12710,24 @@ automatic dial-up internet access. - @opindex --heading - Print a line of column headings. - -+@item -p -+@itemx --process -+@opindex -p -+@opindex --process -+List active processes spawned by init. -+ -+@item -r -+@itemx --runlevel -+@opindex -r -+@opindex --runlevel -+Print the current (and maybe previous) run-level of the init process. -+ -+@item -t -+@itemx --time -+@opindex -t -+@opindex --time -+Print last system clock change. -+ - @item -w - @itemx -T - @itemx --mesg --- -1.5.2.2 - diff --git a/coreutils.spec b/coreutils.spec index 1ede2a4..e16d3d7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: The GNU core utilities: a set of tools commonly used in shell scripts Name: coreutils -Version: 6.12 -Release: 17%{?dist} +Version: 7.0 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,21 +18,14 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -Patch1: coreutils-futimensatkoji.patch -Patch2: coreutils-authors.patch -Patch3: coreutils-who_texinfo.patch -Patch4: coreutils-6.12-date_timerelsnumber.patch -Patch5: coreutils-6.12-seqdecimalutf8.patch -Patch6: coreutils-6.12-catch-known-testsuite-failures.patch -Patch7: coreutils-446294-lsexitstatuses.patch +Patch1: coreutils-446294-lsexitstatuses.patch +Patch2: coreutils-7.0-dftotal.patch # Our patches Patch100: coreutils-6.10-configuration.patch Patch101: coreutils-6.10-manpages.patch #Patch102: coreutils-6.10-longoptions.patch Patch103: coreutils-6.11-sparc-shafix.patch -Patch104: coreutils-6.12-utimenstouchcp.patch -Patch105: coreutils-6.12-dd-fullblock.patch # sh-utils Patch703: sh-utils-2.0.11-dateman.patch @@ -60,10 +53,6 @@ Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch Patch952: coreutils-463883-chcon-changes.patch -# ls enhancements (must be applied after SELINUX patches) -Patch954: coreutils-6.12-ls-libcap.patch -Patch955: coreutils-6.12-ls-constant_mem.patch - BuildRequires: libselinux-devel >= 1.25.6-1 BuildRequires: libacl-devel BuildRequires: gettext bison @@ -107,24 +96,21 @@ These are the GNU core utilities. This package is the combination of the old GNU fileutils, sh-utils, and textutils packages. %prep -%setup -q +#%setup -q +%setup -q -c -T +cd .. +lzma -dc %SOURCE0 | tar xf - +cd %name-%version # From upstream -%patch1 -p1 -b .kojifutimensat -%patch2 -p1 -b .authors -%patch3 -p1 -b .whotexinfo -%patch4 -p1 -b .getdate -%patch5 -p1 -b .sequtf8 -%patch6 -p1 -b .tests -%patch7 -p1 -b .lsexit +%patch1 -p1 -b .lsexit +%patch2 -p1 -b .dftotal # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages #%patch102 -p1 -b .longopt %patch103 -p1 -b .sparc -%patch104 -p1 -b .utimensat -%patch105 -p1 -b .dd-fullblock # sh-utils %patch703 -p1 -b .dateman @@ -141,22 +127,21 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow %patch915 -p1 -b .splitl -%patch916 -p1 -b .getfacl-exit-code +#%patch916 -p1 -b .getfacl-exit-code #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman %patch952 -p1 -b .changeonly -# ls enhancements (must be applied after SELINUX patches) -%patch954 -p1 -b .ls-libcap -%patch955 -p1 -b .ls-constant_mem - - chmod a+x tests/misc/sort-mb-tests chmod a+x tests/misc/id-context -chmod a+x tests/misc/utimensat-touchcp -chmod a+x tests/ls/capability + +#Do require automake 1.10.1 instead of 1.10a +for conffile in aclocal.m4 configure.ac configure $(find ./*/Makefile.in) +do + sed -i 's/1.10a/1.10.1/' "$conffile" +done #fix typos/mistakes in localized documentation(#439410, #440056) for pofile in $(find ./po/*.p*) @@ -169,9 +154,9 @@ done %build %ifarch s390 s390x # Build at -O1 for the moment (bug #196369). -export CFLAGS="$RPM_OPT_FLAGS -fPIC -O1" +export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fPIC -O1" %else -export CFLAGS="$RPM_OPT_FLAGS -fpic" +export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" %endif %{expand:%%global optflags %{optflags} -D_GNU_SOURCE=1} touch aclocal.m4 configure config.hin Makefile.in */Makefile.in @@ -339,6 +324,11 @@ fi /sbin/runuser %changelog +* Tue Nov 11 2008 Ondrej Vasik - 7.0-1 +- new upstream release +- modification/removal of related patches +- use automake 1.10.1 instead of 1.10a + * Mon Nov 03 2008 Ondrej Vasik - 6.12-17 - Requires: ncurses (#469277) From c2ee73dbca11dc44432a13ee0187c53f7d6356f4 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 11 Nov 2008 16:10:30 +0000 Subject: [PATCH 003/523] commited updated sources --- .cvsignore | 2 +- coreutils.spec | 6 +----- sources | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.cvsignore b/.cvsignore index f828846..57a1758 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-6.12.tar.lzma +coreutils-7.0.tar.lzma diff --git a/coreutils.spec b/coreutils.spec index e16d3d7..9654f23 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -96,11 +96,7 @@ These are the GNU core utilities. This package is the combination of the old GNU fileutils, sh-utils, and textutils packages. %prep -#%setup -q -%setup -q -c -T -cd .. -lzma -dc %SOURCE0 | tar xf - -cd %name-%version +%setup -q # From upstream %patch1 -p1 -b .lsexit diff --git a/sources b/sources index db69e6c..d845788 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -c10ccd62490cac4de3bff5022468c9b5 coreutils-6.12.tar.lzma +81c7aecc0daa6cada78005108edb6502 coreutils-7.0.tar.lzma From 185a101acbc94a1f7ae44171c053dd1fc4a11074 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 11 Nov 2008 16:26:15 +0000 Subject: [PATCH 004/523] temporarily skip df --total tests (failures) --- coreutils-6.10-configuration.patch | 12 ++++++++++++ coreutils.spec | 1 + 2 files changed, 13 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 0818bd2..48a46d1 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,3 +1,15 @@ +diff -urNp coreutils-7.0-orig/tests/Makefile.am coreutils-7.0/tests/Makefile.am +--- coreutils-7.0-orig/tests/Makefile.am 2008-11-11 16:37:08.000000000 +0100 ++++ coreutils-7.0/tests/Makefile.am 2008-11-11 16:39:55.000000000 +0100 +@@ -285,8 +285,6 @@ TESTS = \ + dd/skip-seek \ + dd/skip-seek2 \ + dd/unblock-sync \ +- df/total \ +- df/total-awk \ + du/2g \ + du/8gb \ + du/basic \ diff -urN coreutils-6.12-orig/tests/misc/cut coreutils-6.12/tests/misc/cut --- coreutils-6.12-orig/tests/misc/cut 2008-05-17 08:41:11.000000000 +0200 +++ coreutils-6.12/tests/misc/cut 2008-06-02 11:13:08.000000000 +0200 diff --git a/coreutils.spec b/coreutils.spec index 9654f23..e02630c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -324,6 +324,7 @@ fi - new upstream release - modification/removal of related patches - use automake 1.10.1 instead of 1.10a +- temporarily skip df --total tests (failures) * Mon Nov 03 2008 Ondrej Vasik - 6.12-17 - Requires: ncurses (#469277) From e8a61f5499c1991f8f6919450dc5ec78495bbdc6 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 12 Nov 2008 09:38:49 +0000 Subject: [PATCH 005/523] temporarily skip timeout-parameters test (ppc64 failure) --- coreutils-6.10-configuration.patch | 10 +++++++++- coreutils.spec | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 48a46d1..0b369ea 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,7 +1,15 @@ diff -urNp coreutils-7.0-orig/tests/Makefile.am coreutils-7.0/tests/Makefile.am --- coreutils-7.0-orig/tests/Makefile.am 2008-11-11 16:37:08.000000000 +0100 +++ coreutils-7.0/tests/Makefile.am 2008-11-11 16:39:55.000000000 +0100 -@@ -285,8 +285,6 @@ TESTS = \ +@@ -217,7 +217,6 @@ TESTS = \ + misc/tee-dash \ + misc/test-diag \ + misc/timeout \ +- misc/timeout-parameters \ + misc/tr \ + misc/truncate-dangling-symlink \ + misc/truncate-dir-fail \ +@@ -285,8 +284,6 @@ TESTS = \ dd/skip-seek \ dd/skip-seek2 \ dd/unblock-sync \ diff --git a/coreutils.spec b/coreutils.spec index e02630c..b998dbb 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -320,11 +320,12 @@ fi /sbin/runuser %changelog -* Tue Nov 11 2008 Ondrej Vasik - 7.0-1 +* Wed Nov 12 2008 Ondrej Vasik - 7.0-1 - new upstream release - modification/removal of related patches - use automake 1.10.1 instead of 1.10a -- temporarily skip df --total tests (failures) +- temporarily skip df --total tests (failures), + timeout-paramaters (failure on ppc64) * Mon Nov 03 2008 Ondrej Vasik - 6.12-17 - Requires: ncurses (#469277) From 8283df33d5478a6672f91cc3a145b0cd502050c6 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 21 Nov 2008 15:08:56 +0000 Subject: [PATCH 006/523] added requirements for util-linux-ng >= 2.14 (#472445), some sed cleanup --- coreutils-7.0-dftotal.patch | 46 ++++++++++++++++++++++++++++--------- coreutils.spec | 28 ++++++++++++---------- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/coreutils-7.0-dftotal.patch b/coreutils-7.0-dftotal.patch index a719263..3d2e35c 100644 --- a/coreutils-7.0-dftotal.patch +++ b/coreutils-7.0-dftotal.patch @@ -1,24 +1,46 @@ diff -urNp coreutils-7.0-orig/tests/df/total coreutils-7.0/tests/df/total --- coreutils-7.0-orig/tests/df/total 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/tests/df/total 2008-11-11 16:56:17.000000000 +0100 -@@ -30,11 +30,8 @@ umask 22 ++++ coreutils-7.0/tests/df/total 2008-11-12 12:29:24.000000000 +0100 +@@ -18,7 +18,7 @@ + + if test "$VERBOSE" = yes; then + set -x +- ls --version ++ df --version + fi + + . $srcdir/test-lib.sh +@@ -30,13 +30,10 @@ umask 22 RE_TOTAL='^total( +(-?[0-9]+|-)){3} +-?[0-9]+%$' -df > tmp || fail=1 -$EGREP "$RE_TOTAL" tmp && fail=1 -- ++df > tmp && $EGREP "$RE_TOTAL" tmp && fail=1 ++df -i > tmp && $EGREP "$RE_TOTAL" tmp && fail=1 + -df -i > tmp || fail=1 -$EGREP "$RE_TOTAL" tmp && fail=1 -+df | $EGREP "$RE_TOTAL" tmp && fail=1 -+df -i | $EGREP "$RE_TOTAL" tmp && fail=1 +- +-df --total | $EGREP "$RE_TOTAL" || fail=1 +-df -i --total | $EGREP "$RE_TOTAL" || fail=1 ++df --total >tmp && $EGREP "$RE_TOTAL" tmp || fail=1 ++df -i --total >tmp && $EGREP "$RE_TOTAL" tmp || fail=1 - df --total | $EGREP "$RE_TOTAL" || fail=1 - df -i --total | $EGREP "$RE_TOTAL" || fail=1 + Exit $fail diff -urNp coreutils-7.0-orig/tests/df/total-awk coreutils-7.0/tests/df/total-awk --- coreutils-7.0-orig/tests/df/total-awk 2008-09-27 19:28:54.000000000 +0200 +++ coreutils-7.0/tests/df/total-awk 2008-11-11 16:54:49.000000000 +0100 -@@ -23,58 +23,42 @@ fi +@@ -18,7 +18,7 @@ + + if test "$VERBOSE" = yes; then + set -x +- ls --version ++ df --version + fi + + . $srcdir/test-lib.sh +@@ -23,58 +23,44 @@ fi . $srcdir/test-lib.sh @@ -98,14 +120,16 @@ diff -urNp coreutils-7.0-orig/tests/df/total-awk coreutils-7.0/tests/df/total-aw -$AWK -f compute_sum.awk tmp > out1 || fail=1 -$AWK -f parse_total.awk tmp > out2 || fail=1 -compare out1 out2 || fail=1 -+df --total -P --block-size=512 |tee space || framework_failure -+df --total -i -P |tee inode || framework_failure ++fail=0 ++df --total -P --block-size=512 >space || fail=1 ++cat space # this helps when debugging any test failure ++df --total -i -P >inode || fail=1 ++cat inode -df -i --block-size=512 --total |tee tmp || fail=1 -$AWK -f compute_sum.awk tmp > out1 || fail=1 -$AWK -f parse_total.awk tmp > out2 || fail=1 -compare out1 out2 || fail=1 -+fail=0 +$PERL -f check-df space || fail=1 +$PERL -f check-df inode || fail=1 diff --git a/coreutils.spec b/coreutils.spec index b998dbb..b12676e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: The GNU core utilities: a set of tools commonly used in shell scripts Name: coreutils Version: 7.0 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -66,6 +66,9 @@ BuildRequires: libcap-devel >= 2.0.6 Requires(post): libselinux >= 1.25.6-1 Requires: libattr +#util-linux-ng requirement is here only to prevent /bin/arch conflict +#(could be removed after F-11/F-12 split, no idea how to solve it better) +Requires: util-linux-ng >= 2.14 Requires(pre): /sbin/install-info Requires(preun): /sbin/install-info Requires(post): /sbin/install-info @@ -133,19 +136,13 @@ the old GNU fileutils, sh-utils, and textutils packages. chmod a+x tests/misc/sort-mb-tests chmod a+x tests/misc/id-context -#Do require automake 1.10.1 instead of 1.10a -for conffile in aclocal.m4 configure.ac configure $(find ./*/Makefile.in) -do - sed -i 's/1.10a/1.10.1/' "$conffile" -done +sed -i 's/1.10a/1.10.1/' configure.ac #fix typos/mistakes in localized documentation(#439410, #440056) -for pofile in $(find ./po/*.p*) -do - sed -i 's/-dpR/-cdpR/' "$pofile" - sed -i 's/commmand/command/' "$pofile" -done - +find ./po/ -name "*.p*" | xargs \ + sed -i \ + -e 's/-dpR/-cdpR/' \ + -e 's/commmand/command/' %build %ifarch s390 s390x @@ -155,6 +152,7 @@ export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fPIC -O1" export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" %endif %{expand:%%global optflags %{optflags} -D_GNU_SOURCE=1} +#autoreconf -i -v touch aclocal.m4 configure config.hin Makefile.in */Makefile.in aclocal -I m4 autoconf --force @@ -320,6 +318,12 @@ fi /sbin/runuser %changelog +* Fri Nov 21 2008 Ondrej Vasik - 7.0.2 +- added requirements for util-linux-ng >= 2.14 + because of file conflict in update from F-8/F-9(#472445) +- some sed cleanup, df totaltests patch changes (not working + correctly yet :( ) + * Wed Nov 12 2008 Ondrej Vasik - 7.0-1 - new upstream release - modification/removal of related patches From 105574f230a049a853539bd30e1514ae17d89ecf Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 21 Nov 2008 15:28:38 +0000 Subject: [PATCH 007/523] added requirements for util-linux-ng >= 2.14 (/bin/arch conflict, #472445), some sed cleanup --- coreutils.spec | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 1ede2a4..da07adf 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: The GNU core utilities: a set of tools commonly used in shell scripts Name: coreutils Version: 6.12 -Release: 17%{?dist} +Release: 18%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -77,6 +77,9 @@ BuildRequires: libcap-devel >= 2.0.6 Requires(post): libselinux >= 1.25.6-1 Requires: libattr +#util-linux-ng requirement is here only to prevent /bin/arch conflict +#(could be removed after F-11/F-12 split, no idea how to solve it better) +Requires: util-linux-ng >= 2.14 Requires(pre): /sbin/install-info Requires(preun): /sbin/install-info Requires(post): /sbin/install-info @@ -159,19 +162,17 @@ chmod a+x tests/misc/utimensat-touchcp chmod a+x tests/ls/capability #fix typos/mistakes in localized documentation(#439410, #440056) -for pofile in $(find ./po/*.p*) -do - sed -i 's/-dpR/-cdpR/' "$pofile" - sed -i 's/commmand/command/' "$pofile" -done - +find ./po/ -name "*.p*" | xargs \ + sed -i \ + -e 's/-dpR/-cdpR/' \ + -e 's/commmand/command/' %build %ifarch s390 s390x # Build at -O1 for the moment (bug #196369). -export CFLAGS="$RPM_OPT_FLAGS -fPIC -O1" +export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fPIC -O1" %else -export CFLAGS="$RPM_OPT_FLAGS -fpic" +export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" %endif %{expand:%%global optflags %{optflags} -D_GNU_SOURCE=1} touch aclocal.m4 configure config.hin Makefile.in */Makefile.in @@ -339,6 +340,11 @@ fi /sbin/runuser %changelog +* Fri Nov 21 2008 Ondrej Vasik - 6.12-18 +- added requirements for util-linux-ng >= 2.14 + because of file conflict in update from F-8/F-9(#472445) +- some sed cleanup + * Mon Nov 03 2008 Ondrej Vasik - 6.12-17 - Requires: ncurses (#469277) From 25edeeda7554683ab81b48c77a9c01725c14f73d Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 25 Nov 2008 09:38:55 +0000 Subject: [PATCH 008/523] Package summary tuning --- coreutils.spec | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index b12676e..3379d1d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ -Summary: The GNU core utilities: a set of tools commonly used in shell scripts +Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.0 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -318,7 +318,10 @@ fi /sbin/runuser %changelog -* Fri Nov 21 2008 Ondrej Vasik - 7.0.2 +* Tue Nov 25 2008 Ondrej Vasik - 7.0-3 +- package summary tuning + +* Fri Nov 21 2008 Ondrej Vasik - 7.0-2 - added requirements for util-linux-ng >= 2.14 because of file conflict in update from F-8/F-9(#472445) - some sed cleanup, df totaltests patch changes (not working From 5a43cb54ace56c0bf643eaa3ce76ecee3877c2b2 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 3 Dec 2008 22:49:50 +0000 Subject: [PATCH 009/523] fixed regression in expr command(#474434), enable total-awk test again (and skip it only when df not working properly at all) --- coreutils-6.10-configuration.patch | 5 +- coreutils-7.0-dftotal.patch | 41 +- coreutils-7.0-expr-removebignumoptions.patch | 989 +++++++++++++++++++ coreutils.spec | 11 +- 4 files changed, 1011 insertions(+), 35 deletions(-) create mode 100644 coreutils-7.0-expr-removebignumoptions.patch diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 0b369ea..97a7438 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -9,15 +9,14 @@ diff -urNp coreutils-7.0-orig/tests/Makefile.am coreutils-7.0/tests/Makefile.am misc/tr \ misc/truncate-dangling-symlink \ misc/truncate-dir-fail \ -@@ -285,8 +284,6 @@ TESTS = \ +@@ -285,7 +284,6 @@ TESTS = \ dd/skip-seek \ dd/skip-seek2 \ dd/unblock-sync \ - df/total \ -- df/total-awk \ + df/total-awk \ du/2g \ du/8gb \ - du/basic \ diff -urN coreutils-6.12-orig/tests/misc/cut coreutils-6.12/tests/misc/cut --- coreutils-6.12-orig/tests/misc/cut 2008-05-17 08:41:11.000000000 +0200 +++ coreutils-6.12/tests/misc/cut 2008-06-02 11:13:08.000000000 +0200 diff --git a/coreutils-7.0-dftotal.patch b/coreutils-7.0-dftotal.patch index 3d2e35c..950dee8 100644 --- a/coreutils-7.0-dftotal.patch +++ b/coreutils-7.0-dftotal.patch @@ -1,33 +1,3 @@ -diff -urNp coreutils-7.0-orig/tests/df/total coreutils-7.0/tests/df/total ---- coreutils-7.0-orig/tests/df/total 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/tests/df/total 2008-11-12 12:29:24.000000000 +0100 -@@ -18,7 +18,7 @@ - - if test "$VERBOSE" = yes; then - set -x -- ls --version -+ df --version - fi - - . $srcdir/test-lib.sh -@@ -30,13 +30,10 @@ umask 22 - - RE_TOTAL='^total( +(-?[0-9]+|-)){3} +-?[0-9]+%$' - --df > tmp || fail=1 --$EGREP "$RE_TOTAL" tmp && fail=1 -+df > tmp && $EGREP "$RE_TOTAL" tmp && fail=1 -+df -i > tmp && $EGREP "$RE_TOTAL" tmp && fail=1 - --df -i > tmp || fail=1 --$EGREP "$RE_TOTAL" tmp && fail=1 -- --df --total | $EGREP "$RE_TOTAL" || fail=1 --df -i --total | $EGREP "$RE_TOTAL" || fail=1 -+df --total >tmp && $EGREP "$RE_TOTAL" tmp || fail=1 -+df -i --total >tmp && $EGREP "$RE_TOTAL" tmp || fail=1 - - Exit $fail diff -urNp coreutils-7.0-orig/tests/df/total-awk coreutils-7.0/tests/df/total-awk --- coreutils-7.0-orig/tests/df/total-awk 2008-09-27 19:28:54.000000000 +0200 +++ coreutils-7.0/tests/df/total-awk 2008-11-11 16:54:49.000000000 +0100 @@ -40,7 +10,16 @@ diff -urNp coreutils-7.0-orig/tests/df/total-awk coreutils-7.0/tests/df/total-aw fi . $srcdir/test-lib.sh -@@ -23,58 +23,44 @@ fi +@@ -24,6 +24,8 @@ + + . $srcdir/test-lib.sh + ++ df || skip_test_ "df fails" ++ + fail=0 + + # Don't let a different umask perturb the results. +@@ -23,58 +25,44 @@ fi . $srcdir/test-lib.sh diff --git a/coreutils-7.0-expr-removebignumoptions.patch b/coreutils-7.0-expr-removebignumoptions.patch new file mode 100644 index 0000000..8d9f241 --- /dev/null +++ b/coreutils-7.0-expr-removebignumoptions.patch @@ -0,0 +1,989 @@ +diff -urNp coreutils-7.0-orig/src/expr.c coreutils-7.0/src/expr.c +--- coreutils-7.0-orig/src/expr.c 2008-08-24 22:58:15.000000000 +0200 ++++ coreutils-7.0/src/expr.c 2008-10-21 15:47:06.000000000 +0200 +@@ -33,20 +33,122 @@ + #include + #include "system.h" + +-#include + #include +-#if HAVE_GMP +-#include +-#endif + #include "error.h" ++#include "long-options.h" + #include "quotearg.h" + #include "strnumcmp.h" + #include "xstrtol.h" + ++/* Various parts of this code assume size_t fits into unsigned long ++ int, the widest unsigned type that GMP supports. */ ++verify (SIZE_MAX <= ULONG_MAX); ++ ++static void integer_overflow (char) ATTRIBUTE_NORETURN; ++ ++#ifndef HAVE_GMP ++# define HAVE_GMP 0 ++#endif ++ ++#if HAVE_GMP ++# include ++#else ++/* Approximate gmp.h well enough for expr.c's purposes. */ ++typedef intmax_t mpz_t[1]; ++static void mpz_clear (mpz_t z) {} ++static void mpz_init_set_ui (mpz_t z, unsigned long int i) { z[0] = i; } ++static int ++mpz_init_set_str (mpz_t z, char *s, int base) ++{ ++ return xstrtoimax (s, NULL, base, z, NULL) == LONGINT_OK ? 0 : -1; ++} ++static void ++mpz_add (mpz_t r, mpz_t a0, mpz_t b0) ++{ ++ intmax_t a = a0[0]; ++ intmax_t b = b0[0]; ++ intmax_t val = a + b; ++ if ((val < a) != (b < 0)) ++ integer_overflow ('+'); ++ r[0] = val; ++} ++static void ++mpz_sub (mpz_t r, mpz_t a0, mpz_t b0) ++{ ++ intmax_t a = a0[0]; ++ intmax_t b = b0[0]; ++ intmax_t val = a - b; ++ if ((a < val) != (b < 0)) ++ integer_overflow ('-'); ++ r[0] = val; ++} ++static void ++mpz_mul (mpz_t r, mpz_t a0, mpz_t b0) ++{ ++ intmax_t a = a0[0]; ++ intmax_t b = b0[0]; ++ intmax_t val = a * b; ++ if (! (a == 0 || b == 0 ++ || ((val < 0) == ((a < 0) ^ (b < 0)) && val / a == b))) ++ integer_overflow ('*'); ++ r[0] = val; ++} ++static void ++mpz_tdiv_q (mpz_t r, mpz_t a0, mpz_t b0) ++{ ++ intmax_t a = a0[0]; ++ intmax_t b = b0[0]; ++ ++ /* Some x86-style hosts raise an exception for INT_MIN / -1. */ ++ if (a < - INTMAX_MAX && b == -1) ++ integer_overflow ('/'); ++ r[0] = a / b; ++} ++static void ++mpz_tdiv_r (mpz_t r, mpz_t a0, mpz_t b0) ++{ ++ intmax_t a = a0[0]; ++ intmax_t b = b0[0]; ++ ++ /* Some x86-style hosts raise an exception for INT_MIN % -1. */ ++ r[0] = a < - INTMAX_MAX && b == -1 ? 0 : a % b; ++} ++static char * ++mpz_get_str (char const *str, int base, mpz_t z) ++{ ++ char buf[INT_BUFSIZE_BOUND (intmax_t)]; ++ return xstrdup (imaxtostr (z[0], buf)); ++} ++static int ++mpz_sgn (mpz_t z) ++{ ++ return z[0] < 0 ? -1 : 0 < z[0]; ++} ++static int ++mpz_fits_ulong_p (mpz_t z) ++{ ++ return 0 <= z[0] && z[0] <= ULONG_MAX; ++} ++static unsigned long int ++mpz_get_ui (mpz_t z) ++{ ++ return z[0]; ++} ++static int ++mpz_out_str (FILE *stream, int base, mpz_t z) ++{ ++ char buf[INT_BUFSIZE_BOUND (intmax_t)]; ++ return fputs (imaxtostr (z[0], buf), stream) != EOF; ++} ++#endif ++ + /* The official name of this program (e.g., no `g' prefix). */ + #define PROGRAM_NAME "expr" + +-#define AUTHORS proper_name ("Mike Parker"), proper_name ("James Youngman") ++#define AUTHORS \ ++ proper_name ("Mike Parker"), \ ++ proper_name ("James Youngman"), \ ++ proper_name ("Paul Eggert") + + /* Exit statuses. */ + enum +@@ -61,14 +163,10 @@ enum + EXPR_FAILURE + }; + +-/* The kinds of value we can have. +- In the comments below, a variable is described as "arithmetic" if +- it is either integer or mp_integer. Variables are of type mp_integer +- only if GNU MP is available, but the type designator is always defined. */ ++/* The kinds of value we can have. */ + enum valtype + { + integer, +- mp_integer, + string + }; + typedef enum valtype TYPE; +@@ -79,12 +177,7 @@ struct valinfo + TYPE type; /* Which kind. */ + union + { /* The value itself. */ +- /* We could use intmax_t but that would integrate less well with GMP, +- since GMP has mpz_set_si but no intmax_t equivalent. */ +- signed long int i; +-#if HAVE_GMP +- mpz_t z; +-#endif ++ mpz_t i; + char *s; + } u; + }; +@@ -98,34 +191,6 @@ static bool nomoreargs (void); + static bool null (VALUE *v); + static void printv (VALUE *v); + +-/* Arithmetic is done in one of three modes. +- +- The --bignum option forces all arithmetic to use bignums other than +- string indexing (mode==MP_ALWAYS). The --no-bignum option forces +- all arithmetic to use native types rather than bignums +- (mode==MP_NEVER). +- +- The default mode is MP_AUTO if GMP is available and MP_NEVER if +- not. Most functions will process a bignum if one is found, but +- will not convert a native integer to a string if the mode is +- MP_NEVER. */ +-enum arithmetic_mode +- { +- MP_NEVER, /* Never use bignums */ +-#if HAVE_GMP +- MP_ALWAYS, /* Always use bignums. */ +- MP_AUTO, /* Switch if result would otherwise overflow */ +-#endif +- }; +-static enum arithmetic_mode mode = +-#if HAVE_GMP +- MP_AUTO +-#else +- MP_NEVER +-#endif +- ; +- +- + void + usage (int status) + { +@@ -140,10 +205,6 @@ Usage: %s EXPRESSION\n\ + "), + program_name, program_name); + putchar ('\n'); +- fputs (_("\ +- --bignum always use arbitrary-precision arithmetic\n\ +- --no-bignum always use single-precision arithmetic\n"), +- stdout); + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); + fputs (_("\ +@@ -220,47 +281,23 @@ syntax_error (void) + static void + integer_overflow (char op) + { +- error (EXPR_FAILURE, 0, +- _("arithmetic operation %c produced an out of range value, " +- "but arbitrary-precision arithmetic is not available"), op); ++ error (EXPR_FAILURE, ERANGE, "%c", op); ++ abort (); /* notreached */ + } + +-static void die (int exit_status, int errno_val, char const *msg) ++static void die (int errno_val, char const *msg) + ATTRIBUTE_NORETURN; + static void +-die (int exit_status, int errno_val, char const *msg) ++die (int errno_val, char const *msg) + { +- assert (exit_status != 0); +- error (exit_status, errno_val, "%s", msg); ++ error (EXPR_FAILURE, errno_val, "%s", msg); + abort (); /* notreached */ + } + +-static void +-string_too_long (void) +-{ +- die (EXPR_FAILURE, ERANGE, _("string too long")); +-} +- +-enum +-{ +- USE_BIGNUM = CHAR_MAX + 1, +- NO_USE_BIGNUM +-}; +- +-static struct option const long_options[] = +-{ +- {"bignum", no_argument, NULL, USE_BIGNUM}, +- {"no-bignum", no_argument, NULL, NO_USE_BIGNUM}, +- {GETOPT_HELP_OPTION_DECL}, +- {GETOPT_VERSION_OPTION_DECL}, +- {NULL, 0, NULL, 0} +-}; +- + int + main (int argc, char **argv) + { + VALUE *v; +- int c; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -271,49 +308,23 @@ main (int argc, char **argv) + initialize_exit_failure (EXPR_FAILURE); + atexit (close_stdout); + +- /* The argument -0 should not result in an error message. */ +- opterr = 0; +- +- while ((c = getopt_long (argc, argv, "+", long_options, NULL)) != -1) ++ parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, VERSION, ++ usage, AUTHORS, (char const *) NULL); ++ /* The above handles --help and --version. ++ Since there is no other invocation of getopt, handle `--' here. */ ++ if (argc > 1 && STREQ (argv[1], "--")) + { +- /* "expr -0" should interpret the -0 as an integer argument. +- arguments like --foo should also be interpreted as a string +- argument to be "evaluated". +- */ +- if ('?' == c) +- { +- --optind; +- break; +- } +- else +- switch (c) +- { +- case USE_BIGNUM: +-#if HAVE_GMP +- mode = MP_ALWAYS; +-#else +- error (EXPR_FAILURE, 0, +- _("arbitrary-precision support is not available")); +-#endif +- break; +- +- case NO_USE_BIGNUM: +- mode = MP_NEVER; +- break; +- +- case_GETOPT_HELP_CHAR; +- +- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); +- } ++ --argc; ++ ++argv; + } + +- if (argc <= optind) ++ if (argc <= 1) + { + error (0, 0, _("missing operand")); + usage (EXPR_INVALID); + } + +- args = argv + optind; ++ args = argv + 1; + + v = eval (true); + if (!nomoreargs ()) +@@ -326,21 +337,11 @@ main (int argc, char **argv) + /* Return a VALUE for I. */ + + static VALUE * +-int_value (long int i) ++int_value (unsigned long int i) + { + VALUE *v = xmalloc (sizeof *v); +-#if HAVE_GMP +- if (mode == MP_ALWAYS) +- { +- /* all integer values are handled as bignums. */ +- mpz_init_set_si (v->u.z, i); +- v->type = mp_integer; +- return v; +- } +-#endif +- + v->type = integer; +- v->u.i = i; ++ mpz_init_set_ui (v->u.i, i); + return v; + } + +@@ -355,42 +356,15 @@ str_value (char const *s) + return v; + } + +- +-static VALUE * +-substr_value (char const *s, size_t len, size_t pos, size_t nchars_wanted) +-{ +- if (pos >= len) +- return str_value (""); +- else +- { +- VALUE *v = xmalloc (sizeof *v); +- size_t vlen = MIN (nchars_wanted, len - pos + 1); +- char *vlim; +- v->type = string; +- v->u.s = xmalloc (vlen + 1); +- vlim = mempcpy (v->u.s, s + pos, vlen); +- *vlim = '\0'; +- return v; +- } +-} +- +- + /* Free VALUE V, including structure components. */ + + static void + freev (VALUE *v) + { + if (v->type == string) +- { +- free (v->u.s); +- } +- else if (v->type == mp_integer) +- { +- assert (mode != MP_NEVER); +-#if HAVE_GMP +- mpz_clear (v->u.z); +-#endif +- } ++ free (v->u.s); ++ else ++ mpz_clear (v->u.i); + free (v); + } + +@@ -402,21 +376,15 @@ printv (VALUE *v) + switch (v->type) + { + case integer: +- printf ("%ld\n", v->u.i); ++ mpz_out_str (stdout, 10, v->u.i); ++ putchar ('\n'); + break; + case string: + puts (v->u.s); + break; +-#if HAVE_GMP +- case mp_integer: +- mpz_out_str (stdout, 10, v->u.z); +- putchar ('\n'); +- break; +-#endif + default: + abort (); + } +- + } + + /* Return true if V is a null-string or zero-number. */ +@@ -427,11 +395,7 @@ null (VALUE *v) + switch (v->type) + { + case integer: +- return v->u.i == 0; +-#if HAVE_GMP +- case mp_integer: +- return mpz_sgn (v->u.z) == 0; +-#endif ++ return mpz_sgn (v->u.i) == 0; + case string: + { + char const *cp = v->u.s; +@@ -474,29 +438,16 @@ looks_like_integer (char const *cp) + static void + tostring (VALUE *v) + { +- char buf[INT_BUFSIZE_BOUND (long int)]; +- + switch (v->type) + { + case integer: +- snprintf (buf, sizeof buf, "%ld", v->u.i); +- v->u.s = xstrdup (buf); +- v->type = string; +- break; +-#if HAVE_GMP +- case mp_integer: + { +- char *s = mpz_get_str (NULL, 10, v->u.z); +- if (!s) +- { +- xalloc_die (); +- } +- mpz_clear (v->u.z); ++ char *s = mpz_get_str (NULL, 10, v->u.i); ++ mpz_clear (v->u.i); + v->u.s = s; + v->type = string; + } + break; +-#endif + case string: + break; + default: +@@ -504,8 +455,7 @@ tostring (VALUE *v) + } + } + +-/* Coerce V to an arithmetic value. +- Return true on success, false on failure. */ ++/* Coerce V to an integer value. Return true on success, false on failure. */ + + static bool + toarith (VALUE *v) +@@ -513,40 +463,17 @@ toarith (VALUE *v) + switch (v->type) + { + case integer: +- case mp_integer: + return true; +- + case string: + { +- long int value; ++ char *s = v->u.s; + +- if (! looks_like_integer (v->u.s)) ++ if (! looks_like_integer (s)) + return false; +- if (xstrtol (v->u.s, NULL, 10, &value, NULL) != LONGINT_OK) +- { +-#if HAVE_GMP +- if (mode != MP_NEVER) +- { +- char *s = v->u.s; +- if (mpz_init_set_str (v->u.z, s, 10)) +- abort (); /* Bug in looks_like_integer, perhaps. */ +- v->type = mp_integer; +- free (s); +- } +- else +- { +- error (EXPR_FAILURE, ERANGE, "%s", v->u.s); +- } +-#else +- error (EXPR_FAILURE, ERANGE, "%s", v->u.s); +-#endif +- } +- else +- { +- free (v->u.s); +- v->u.i = value; +- v->type = integer; +- } ++ if (mpz_init_set_str (v->u.i, s, 10) != 0 && !HAVE_GMP) ++ error (EXPR_FAILURE, ERANGE, "%s", s); ++ free (s); ++ v->type = integer; + return true; + } + default: +@@ -554,58 +481,23 @@ toarith (VALUE *v) + } + } + +-/* Extract a size_t value from a positive arithmetic value, V. +- The extracted value is stored in *VAL. */ +-static bool +-getsize (const VALUE *v, size_t *val, bool *negative) +-{ +- if (v->type == integer) +- { +- if (v->u.i < 0) +- { +- *negative = true; +- return false; +- } +- else +- { +- *negative = false; +- *val = v->u.i; +- return true; +- } +- } +- else if (v->type == mp_integer) +- { +-#if HAVE_GMP +- if (mpz_sgn (v->u.z) < 0) +- { +- *negative = true; +- return false; +- } +- else if (mpz_fits_ulong_p (v->u.z)) +- { +- unsigned long ul; +- ul = mpz_get_ui (v->u.z); +- *val = ul; +- return true; +- } +- else +- { +- *negative = false; +- return false; +- } +-#else +- abort (); +-#endif +- +- } +- else +- { +- abort (); /* should not pass a string. */ ++/* Extract a size_t value from a integer value I. ++ If the value is negative, return SIZE_MAX. ++ If the value is too large, return SIZE_MAX - 1. */ ++static size_t ++getsize (mpz_t i) ++{ ++ if (mpz_sgn (i) < 0) ++ return SIZE_MAX; ++ if (mpz_fits_ulong_p (i)) ++ { ++ unsigned long int ul = mpz_get_ui (i); ++ if (ul < SIZE_MAX) ++ return ul; + } ++ return SIZE_MAX - 1; + } + +- +- + /* Return true and advance if the next token matches STR exactly. + STR must not be NULL. */ + +@@ -784,41 +676,14 @@ eval6 (bool evaluate) + } + else if (nextarg ("index")) + { +- size_t pos, len; ++ size_t pos; + + l = eval6 (evaluate); + r = eval6 (evaluate); + tostring (l); + tostring (r); + pos = strcspn (l->u.s, r->u.s); +- len = strlen (l->u.s); +- if (pos == len) +- { +- v = int_value (0); +- } +- else +- { +- if (pos < LONG_MAX) +- { +- v = int_value (pos + 1); +- } +- else +- { +-#if HAVE_GMP +- if (mode != MP_NEVER +- && pos < ULONG_MAX) +- { +- v = xmalloc (sizeof *v); +- mpz_init_set_ui (v->u.z, pos+1); +- v->type = mp_integer; +- } +- else +-#endif +- { +- string_too_long (); +- } +- } +- } ++ v = int_value (l->u.s[pos] ? pos + 1 : 0); + freev (l); + freev (r); + return v; +@@ -836,25 +701,21 @@ eval6 (bool evaluate) + v = str_value (""); + else + { +- size_t pos, len; +- bool negative = false; ++ size_t pos = getsize (i1->u.i); ++ size_t len = getsize (i2->u.i); + +- if (getsize (i1, &pos, &negative)) +- if (getsize (i2, &len, &negative)) +- if (pos == 0 || len == 0) +- v = str_value (""); +- else +- v = substr_value (l->u.s, llen, pos-1, len); +- else +- if (negative) +- v = str_value (""); +- else +- die (EXPR_FAILURE, ERANGE, _("string offset is too large")); ++ if (llen < pos || pos == 0 || len == 0 || len == SIZE_MAX) ++ v = str_value (""); + else +- if (negative) +- v = str_value (""); +- else +- die (EXPR_FAILURE, ERANGE, _("substring length too large")); ++ { ++ size_t vlen = MIN (len, llen - pos + 1); ++ char *vlim; ++ v = xmalloc (sizeof *v); ++ v->type = string; ++ v->u.s = xmalloc (vlen + 1); ++ vlim = mempcpy (v->u.s, l->u.s + pos - 1, vlen); ++ *vlim = '\0'; ++ } + } + freev (l); + freev (i1); +@@ -897,170 +758,6 @@ eval5 (bool evaluate) + } + } + +- +-#if HAVE_GMP +-static void +-promote (VALUE *x) +-{ +- if (x->type == integer) +- mpz_init_set_si (x->u.z, x->u.i); +-} +-#endif +- +-/* L = L * R. Both L and R are arithmetic. */ +-static void +-domult (VALUE *l, VALUE *r) +-{ +- if (l->type == integer && r->type == integer) +- { +- long int val = 0; +- val = l->u.i * r->u.i; +- if (! (l->u.i == 0 || r->u.i == 0 +- || ((val < 0) == ((l->u.i < 0) ^ (r->u.i < 0)) +- && val / l->u.i == r->u.i))) +- { +- /* Result would (did) overflow. Handle with MP if available. */ +- if (mode != MP_NEVER) +- { +-#if HAVE_GMP +- mpz_init_set_si (l->u.z, l->u.i); +- mpz_mul_si (l->u.z, l->u.z, r->u.i); /* L*=R */ +- l->type = mp_integer; +-#endif +- } +- else +- { +- integer_overflow ('*'); +- } +- } +- else +- { +- l->u.i = val; +- } +- } +- else +- { +- /* At least one operand is already mp_integer, so promote the other. */ +-#if HAVE_GMP +- /* We could use mpz_mul_si here if R is not already mp_integer, +- but for the moment we'll try to minimise code paths. */ +- if (l->type == integer) +- mpz_init_set_si (l->u.z, l->u.i); +- if (r->type == integer) +- mpz_init_set_si (r->u.z, r->u.i); +- l->type = r->type = mp_integer; +- mpz_mul (l->u.z, l->u.z, r->u.z); /* L*=R */ +-#else +- abort (); +-#endif +- } +-} +- +-/* L = L / R or (if WANT_MODULUS) L = L % R */ +-static void +-dodivide (VALUE *l, VALUE *r, bool want_modulus) +-{ +- if (r->type == integer && r->u.i == 0) +- error (EXPR_INVALID, 0, _("division by zero")); +-#if HAVE_GMP +- if (r->type == mp_integer && mpz_sgn (r->u.z) == 0) +- error (EXPR_INVALID, 0, _("division by zero")); +-#endif +- if (l->type == integer && r->type == integer) +- { +- if (l->u.i < - INT_MAX && r->u.i == -1) +- { +- /* Some x86-style hosts raise an exception for +- INT_MIN / -1 and INT_MIN % -1, so handle these +- problematic cases specially. */ +- if (want_modulus) +- { +- /* X mod -1 is zero for all negative X. +- Although strictly this is implementation-defined, +- we don't want to coredump, so we avoid the calculation. */ +- l->u.i = 0; +- return; +- } +- else +- { +- if (mode != MP_NEVER) +- { +-#if HAVE_GMP +- /* Handle the case by promoting. */ +- mpz_init_set_si (l->u.z, l->u.i); +- l->type = mp_integer; +-#endif +- } +- else +- { +- integer_overflow ('/'); +- } +- } +- } +- else +- { +- l->u.i = want_modulus ? l->u.i % r->u.i : l->u.i / r->u.i; +- return; +- } +- } +- /* If we get to here, at least one operand is mp_integer +- and R is not 0. */ +-#if HAVE_GMP +- { +- int sign_l, sign_r; +- promote (l); +- promote (r); +- sign_l = mpz_sgn (l->u.z); +- sign_r = mpz_sgn (r->u.z); +- +- if (!want_modulus) +- { +- if (!sign_l) +- { +- mpz_set_si (l->u.z, 0); +- } +- else if (sign_l < 0 || sign_r < 0) +- { +- /* At least one operand is negative. For integer arithmetic, +- it's platform-dependent if the operation rounds up or down. +- We mirror what the implementation does. */ +- switch ((3*sign_l) / (2*sign_r)) +- { +- case 2: /* round toward +inf. */ +- case -1: /* round toward +inf. */ +- mpz_cdiv_q (l->u.z, l->u.z, r->u.z); +- break; +- case -2: /* round toward -inf. */ +- case 1: /* round toward -inf */ +- mpz_fdiv_q (l->u.z, l->u.z, r->u.z); +- break; +- default: +- abort (); +- } +- } +- else +- { +- /* Both operands positive. Round toward -inf. */ +- mpz_fdiv_q (l->u.z, l->u.z, r->u.z); +- } +- } +- else +- { +- mpz_mod (l->u.z, l->u.z, r->u.z); /* L = L % R */ +- +- /* If either operand is negative, it's platform-dependent if +- the remainer is positive or negative. We mirror what the +- implementation does. */ +- if (sign_l % sign_r < 0) +- mpz_neg (l->u.z, l->u.z); /* L = (-L) */ +- } +- } +-#else +- abort (); +-#endif +-} +- +- + /* Handle *, /, % operators. */ + + static VALUE * +@@ -1089,71 +786,17 @@ eval4 (bool evaluate) + { + if (!toarith (l) || !toarith (r)) + error (EXPR_INVALID, 0, _("non-numeric argument")); +- switch (fxn) +- { +- case multiply: +- domult (l, r); +- break; +- case divide: +- case mod: +- dodivide (l, r, fxn==mod); +- break; +- } ++ if (fxn != multiply && mpz_sgn (r->u.i) == 0) ++ error (EXPR_INVALID, 0, _("division by zero")); ++ ((fxn == multiply ? mpz_mul ++ : fxn == divide ? mpz_tdiv_q ++ : mpz_tdiv_r) ++ (l->u.i, l->u.i, r->u.i)); + } + freev (r); + } + } + +-/* L = L + R, or L = L - R */ +-static void +-doadd (VALUE *l, VALUE *r, bool add) +-{ +- long int val = 0; +- +- if (!toarith (l) || !toarith (r)) +- error (EXPR_INVALID, 0, _("non-numeric argument")); +- if (l->type == integer && r->type == integer) +- { +- if (add) +- { +- val = l->u.i + r->u.i; +- if ((val < l->u.i) == (r->u.i < 0)) +- { +- l->u.i = val; +- return; +- } +- } +- else +- { +- val = l->u.i - r->u.i; +- if ((l->u.i < val) == (r->u.i < 0)) +- { +- l->u.i = val; +- return; +- } +- } +- } +- /* If we get to here, either the operation overflowed or at least +- one operand is an mp_integer. */ +- if (mode != MP_NEVER) +- { +-#if HAVE_GMP +- promote (l); +- promote (r); +- if (add) +- mpz_add (l->u.z, l->u.z, r->u.z); +- else +- mpz_sub (l->u.z, l->u.z, r->u.z); +-#endif +- } +- else +- { +- integer_overflow ('-'); +- } +-} +- +- +- + /* Handle +, - operators. */ + + static VALUE * +@@ -1161,7 +804,7 @@ eval3 (bool evaluate) + { + VALUE *l; + VALUE *r; +- bool add; ++ enum { plus, minus } fxn; + + #ifdef EVAL_TRACE + trace ("eval3"); +@@ -1170,15 +813,17 @@ eval3 (bool evaluate) + while (1) + { + if (nextarg ("+")) +- add = true; ++ fxn = plus; + else if (nextarg ("-")) +- add = false; ++ fxn = minus; + else + return l; + r = eval4 (evaluate); + if (evaluate) + { +- doadd (l, r, add); ++ if (!toarith (l) || !toarith (r)) ++ error (EXPR_INVALID, 0, _("non-numeric argument")); ++ (fxn == plus ? mpz_add : mpz_sub) (l->u.i, l->u.i, r->u.i); + } + freev (r); + } +diff -urNp coreutils-7.0-orig/tests/misc/expr coreutils-7.0/tests/misc/expr +--- coreutils-7.0-orig/tests/misc/expr 2008-08-24 22:58:15.000000000 +0200 ++++ coreutils-7.0/tests/misc/expr 2008-10-21 15:47:06.000000000 +0200 +@@ -39,6 +39,15 @@ my @Tests = + ['f', '3 + -2', {OUT => '1'}], + ['g', '-2 + -2', {OUT => '-4'}], + ++ # Verify option processing. ++ # Added when option processing broke in the 7.0 beta release ++ ['opt1', '-- -11 + 12', {OUT => '1'}], ++ ['opt2', '-11 + 12', {OUT => '1'}], ++ ['opt3', '-- -1 + 2', {OUT => '1'}], ++ ['opt4', '-1 + 2', {OUT => '1'}], ++ # This evoked a syntax error diagnostic before 2.0.12. ++ ['opt5', '-- 2 + 2', {OUT => '4'}], ++ + ['paren1', '\( 100 % 6 \)', {OUT => '4'}], + ['paren2', '\( 100 % 6 \) - 8', {OUT => '-4'}], + ['paren3', '9 / \( 100 % 6 \) - 8', {OUT => '-6'}], +@@ -59,8 +68,6 @@ my @Tests = + # In 5.1.3 and earlier, this would output the empty string. + ['orempty', '"" \| ""', {OUT => '0'}, {EXIT => 1}], + +- # This evoked a syntax error diagnostic before 2.0.12. +- ['minus2', '-- 2 + 2', {OUT => '4'}], + + # This erroneously succeeded and output `3' before 2.0.12. + ['fail-a', '3 + -', {ERR => "$prog: non-numeric argument\n"}, +@@ -163,8 +170,8 @@ my @Tests = + ['bignum-div', "$big_prod / $big", {OUT => $big_p1}], + ); + +-# If using --bignum fails, remove all /^bignum-/ tests +-`expr --bignum 1` ++# If using big numbers fails, remove all /^bignum-/ tests ++`expr $big_prod '*' $big_prod '*' $big_prod` + or @Tests = grep {$_->[0] !~ /^bignum-/} @Tests; + + # Append a newline to end of each expected `OUT' string. diff --git a/coreutils.spec b/coreutils.spec index 3379d1d..f072acc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.0 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -20,6 +20,7 @@ Source203: coreutils-runuser-l.pamd # From upstream Patch1: coreutils-446294-lsexitstatuses.patch Patch2: coreutils-7.0-dftotal.patch +Patch3: coreutils-7.0-expr-removebignumoptions.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -104,6 +105,7 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .lsexit %patch2 -p1 -b .dftotal +%patch3 -p1 -b .bignum # Our patches %patch100 -p1 -b .configure @@ -318,6 +320,13 @@ fi /sbin/runuser %changelog +* Thu Dec 04 2008 Ondrej Vasik - 7.0-4 +- fixed syntax error w/ "expr" command using negative + string/integer as first (i.e expr -125) - due to + complexity of changes used diff against upstream git-head + (#474434) +- enable total-awk test again (and skip it when df not working) + * Tue Nov 25 2008 Ondrej Vasik - 7.0-3 - package summary tuning From f7b5421d466927c83d0824e6c7f0720b7e17b34f Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 3 Dec 2008 23:11:37 +0000 Subject: [PATCH 010/523] fix info documentation for expr command (#474434) --- coreutils-7.0-expr-removebignumoptions.patch | 23 ++++++++++++++++++++ coreutils.spec | 5 ++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/coreutils-7.0-expr-removebignumoptions.patch b/coreutils-7.0-expr-removebignumoptions.patch index 8d9f241..8916b47 100644 --- a/coreutils-7.0-expr-removebignumoptions.patch +++ b/coreutils-7.0-expr-removebignumoptions.patch @@ -1,3 +1,26 @@ +diff -urNp coreutils-7.0-orig/doc/coreutils.texi coreutils-7.0/doc/coreutils.texi +--- coreutils-7.0-orig/doc/coreutils.texi 2008-12-03 23:57:52.000000000 +0100 ++++ coreutils-7.0/doc/coreutils.texi 2008-12-04 00:00:51.000000000 +0100 +@@ -11167,17 +11167,8 @@ types, but if a numeric overflow occurs + with support for the GNU MP library, @command{expr}, it + uses arbitrary-precision arithmetic. + +-Apart from @option{--help} and @option{--version} (@pxref{Common +-options}), the following options are supported: +- +-@table @samp +-@item --bignum +-Perform arithmetic operations using unlimited precision via the GNU MP library. +-@item --no-bignum +-Use only limited-precision native operations. +-In the event of numeric overflow, @command{expr} fails, +-even if GNU MP is available. +-@end table ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. Options must precede operands. + + @cindex exit status of @command{expr} + Exit status: diff -urNp coreutils-7.0-orig/src/expr.c coreutils-7.0/src/expr.c --- coreutils-7.0-orig/src/expr.c 2008-08-24 22:58:15.000000000 +0200 +++ coreutils-7.0/src/expr.c 2008-10-21 15:47:06.000000000 +0200 diff --git a/coreutils.spec b/coreutils.spec index f072acc..33dc730 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.0 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -320,6 +320,9 @@ fi /sbin/runuser %changelog +* Thu Dec 04 2008 Ondrej Vasik - 7.0-5 +- fix info documentation for expr command as well(#474434) + * Thu Dec 04 2008 Ondrej Vasik - 7.0-4 - fixed syntax error w/ "expr" command using negative string/integer as first (i.e expr -125) - due to From b2649127906bb656df7aaddbd2c7676eef750038 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 28 Jan 2009 17:29:41 +0000 Subject: [PATCH 011/523] cp/mv: --no-clobber option, xattr support (#202823) --- coreutils-5.2.1-runuser.patch | 105 ++--- coreutils-7.0-cp-mv-n.patch | 322 ++++++++++++++ coreutils-7.0-xattr.patch | 792 ++++++++++++++++++++++++++++++++++ coreutils-selinux.patch | 237 +++++----- coreutils.spec | 13 +- 5 files changed, 1297 insertions(+), 172 deletions(-) create mode 100644 coreutils-7.0-cp-mv-n.patch create mode 100644 coreutils-7.0-xattr.patch diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index db6b81d..2e74d74 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-6.12-orig/AUTHORS coreutils-6.12/AUTHORS ---- coreutils-6.12-orig/AUTHORS 2008-10-21 14:58:31.000000000 +0200 -+++ coreutils-6.12/AUTHORS 2008-10-21 15:00:05.000000000 +0200 +diff -urNp coreutils-7.0.orig/AUTHORS coreutils-7.0/AUTHORS +--- coreutils-7.0.orig/AUTHORS 2008-08-24 22:58:15.000000000 +0200 ++++ coreutils-7.0/AUTHORS 2009-01-28 18:11:00.316247411 +0100 @@ -63,6 +63,7 @@ pwd: Jim Meyering readlink: Dmitry V. Levin rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering @@ -9,9 +9,9 @@ diff -urNp coreutils-6.12-orig/AUTHORS coreutils-6.12/AUTHORS runcon: Russell Coker seq: Ulrich Drepper sha1sum: Ulrich Drepper, Scott Miller, David Madore -diff -urNp coreutils-6.12-orig/man/Makefile.am coreutils-6.12/man/Makefile.am ---- coreutils-6.12-orig/man/Makefile.am 2008-05-06 11:28:24.000000000 +0200 -+++ coreutils-6.12/man/Makefile.am 2008-10-21 15:00:13.000000000 +0200 +diff -urNp coreutils-7.0.orig/man/Makefile.am coreutils-7.0/man/Makefile.am +--- coreutils-7.0.orig/man/Makefile.am 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/man/Makefile.am 2009-01-28 18:11:00.317247417 +0100 @@ -93,6 +93,7 @@ readlink.1: $(common_dep) $(srcdir)/read rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c @@ -20,9 +20,25 @@ diff -urNp coreutils-6.12-orig/man/Makefile.am coreutils-6.12/man/Makefile.am seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c -diff -urNp coreutils-6.12-orig/README coreutils-6.12/README ---- coreutils-6.12-orig/README 2008-05-15 20:44:37.000000000 +0200 -+++ coreutils-6.12/README 2008-10-21 14:59:29.000000000 +0200 +diff -urNp coreutils-7.0.orig/man/runuser.x coreutils-7.0/man/runuser.x +--- coreutils-7.0.orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-7.0/man/runuser.x 2009-01-28 18:11:00.321247443 +0100 +@@ -0,0 +1,12 @@ ++[NAME] ++runuser \- run a shell with substitute user and group IDs ++[DESCRIPTION] ++.\" Add any additional description here ++[SEE ALSO] ++.TP ++More detailed Texinfo documentation could be found by command ++.TP ++\t\fBinfo su invocation\fR\t ++.TP ++since the command \fBrunuser\fR is trimmed down version of command \fBrunuser\fR. ++.br +diff -urNp coreutils-7.0.orig/README coreutils-7.0/README +--- coreutils-7.0.orig/README 2008-08-24 22:30:10.000000000 +0200 ++++ coreutils-7.0/README 2009-01-28 18:11:00.318247424 +0100 @@ -12,10 +12,10 @@ The programs that can be built with this factor false fmt fold groups head hostid hostname id install join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup @@ -38,9 +54,9 @@ diff -urNp coreutils-6.12-orig/README coreutils-6.12/README See the file NEWS for a list of major changes in the current release. -diff -urNp coreutils-6.12-orig/src/Makefile.am coreutils-6.12/src/Makefile.am ---- coreutils-6.12-orig/src/Makefile.am 2008-10-21 14:58:31.000000000 +0200 -+++ coreutils-6.12/src/Makefile.am 2008-10-21 14:59:58.000000000 +0200 +diff -urNp coreutils-7.0.orig/src/Makefile.am coreutils-7.0/src/Makefile.am +--- coreutils-7.0.orig/src/Makefile.am 2009-01-28 18:10:10.756926000 +0100 ++++ coreutils-7.0/src/Makefile.am 2009-01-28 18:11:59.658631933 +0100 @@ -38,7 +38,7 @@ EXTRA_PROGRAMS = \ shuf sort split sum tac tail tr tsort unexpand uniq wc \ basename date dirname echo env expr factor false \ @@ -50,9 +66,9 @@ diff -urNp coreutils-6.12-orig/src/Makefile.am coreutils-6.12/src/Makefile.am test timeout true truncate tty whoami yes \ base64 -@@ -142,6 +142,10 @@ cp_LDADD += $(LIB_ACL) - mv_LDADD += $(LIB_ACL) - ginstall_LDADD += $(LIB_ACL) +@@ -154,6 +154,10 @@ cp_LDADD += $(LIB_ACL) $(LIB_XATTR) + mv_LDADD += $(LIB_ACL) $(LIB_XATTR) + ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR) +runuser_SOURCES = su.c +runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\"" @@ -61,7 +77,7 @@ diff -urNp coreutils-6.12-orig/src/Makefile.am coreutils-6.12/src/Makefile.am stat_LDADD = $(LDADD) $(LIB_SELINUX) # Append $(LIBICONV) to each program that uses proper_name_utf8. -@@ -159,7 +163,7 @@ RELEASE_YEAR = \ +@@ -173,7 +177,7 @@ RELEASE_YEAR = \ `sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \ $(top_srcdir)/lib/version-etc.c` @@ -70,9 +86,9 @@ diff -urNp coreutils-6.12-orig/src/Makefile.am coreutils-6.12/src/Makefile.am installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'` -diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c ---- coreutils-6.12-orig/src/su.c 2008-10-21 14:58:31.000000000 +0200 -+++ coreutils-6.12/src/su.c 2008-10-21 15:07:05.000000000 +0200 +diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c +--- coreutils-7.0.orig/src/su.c 2009-01-28 18:10:10.801926000 +0100 ++++ coreutils-7.0/src/su.c 2009-01-28 18:11:00.320247437 +0100 @@ -109,9 +109,15 @@ #include "error.h" @@ -113,7 +129,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c #ifdef USE_PAM ; #else -@@ -186,6 +200,10 @@ static struct option const longopts[] = +@@ -183,6 +197,10 @@ static struct option const longopts[] = {"login", no_argument, NULL, 'l'}, {"preserve-environment", no_argument, NULL, 'p'}, {"shell", required_argument, NULL, 's'}, @@ -124,7 +140,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -287,10 +305,12 @@ correct_password (const struct passwd *p +@@ -284,10 +302,12 @@ correct_password (const struct passwd *p retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh); PAM_BAIL_P; @@ -137,7 +153,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c caller = getpwuid(getuid()); if(caller != NULL && caller->pw_name != NULL) { -@@ -307,6 +327,11 @@ correct_password (const struct passwd *p +@@ -304,6 +324,11 @@ correct_password (const struct passwd *p retval = pam_set_item(pamh, PAM_TTY, tty_name); PAM_BAIL_P; } @@ -149,7 +165,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c retval = pam_authenticate(pamh, 0); PAM_BAIL_P; retval = pam_acct_mgmt(pamh, 0); -@@ -316,6 +341,7 @@ correct_password (const struct passwd *p +@@ -313,6 +338,7 @@ correct_password (const struct passwd *p PAM_BAIL_P; } PAM_BAIL_P; @@ -157,7 +173,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c /* must be authenticated if this point was reached */ return 1; #else /* !USE_PAM */ -@@ -397,11 +423,22 @@ modify_environment (const struct passwd +@@ -394,11 +420,22 @@ modify_environment (const struct passwd /* Become the user and group(s) specified by PW. */ static void @@ -182,7 +198,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c #ifdef USE_PAM pam_close_session(pamh, 0); pam_end(pamh, PAM_ABORT); -@@ -448,7 +485,11 @@ pam_copyenv (pam_handle_t *pamh) +@@ -445,7 +482,11 @@ pam_copyenv (pam_handle_t *pamh) static void run_shell (char const *shell, char const *command, char **additional_args, @@ -195,7 +211,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c { size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; char const **args = xnmalloc (n_args, sizeof *args); -@@ -479,7 +520,11 @@ run_shell (char const *shell, char const +@@ -476,7 +517,11 @@ run_shell (char const *shell, char const child = fork(); if (child == 0) { /* child shell */ @@ -208,7 +224,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c pam_end(pamh, 0); if (!same_session) setsid (); -@@ -623,6 +668,26 @@ usage (int status) +@@ -620,6 +665,26 @@ usage (int status) else { printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name); @@ -235,7 +251,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c fputs (_("\ Change the effective user id and group id to that of USER.\n\ \n\ -@@ -635,6 +700,7 @@ Change the effective user id and group i +@@ -632,6 +697,7 @@ Change the effective user id and group i -p same as -m\n\ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ "), stdout); @@ -243,7 +259,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_("\ -@@ -656,6 +722,12 @@ main (int argc, char **argv) +@@ -653,6 +719,12 @@ main (int argc, char **argv) char *shell = NULL; struct passwd *pw; struct passwd pw_copy; @@ -256,7 +272,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -670,7 +742,11 @@ main (int argc, char **argv) +@@ -667,7 +739,11 @@ main (int argc, char **argv) simulate_login = false; change_environment = true; @@ -269,7 +285,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c { switch (optc) { -@@ -700,6 +776,28 @@ main (int argc, char **argv) +@@ -697,6 +773,28 @@ main (int argc, char **argv) shell = optarg; break; @@ -298,7 +314,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -@@ -738,7 +836,20 @@ main (int argc, char **argv) +@@ -735,7 +833,20 @@ main (int argc, char **argv) : DEFAULT_SHELL); endpwent (); @@ -320,7 +336,7 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c { #ifdef SYSLOG_FAILURE log_su (pw, false); -@@ -770,8 +881,16 @@ main (int argc, char **argv) +@@ -767,8 +878,16 @@ main (int argc, char **argv) modify_environment (pw, shell); #ifndef USE_PAM @@ -339,10 +355,10 @@ diff -urNp coreutils-6.12-orig/src/su.c coreutils-6.12/src/su.c +#endif + ); } -diff -urNp coreutils-6.12-orig/tests/misc/help-version coreutils-6.12/tests/misc/help-version ---- coreutils-6.12-orig/tests/misc/help-version 2008-05-27 13:39:18.000000000 +0200 -+++ coreutils-6.12/tests/misc/help-version 2008-10-21 14:59:16.000000000 +0200 -@@ -146,6 +146,7 @@ printf_args=foo +diff -urNp coreutils-7.0.orig/tests/misc/help-version coreutils-7.0/tests/misc/help-version +--- coreutils-7.0.orig/tests/misc/help-version 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/tests/misc/help-version 2009-01-28 18:11:00.321247443 +0100 +@@ -148,6 +148,7 @@ printf_args=foo seq_args=10 sleep_args=0 su_args=--version @@ -350,18 +366,3 @@ diff -urNp coreutils-6.12-orig/tests/misc/help-version coreutils-6.12/tests/misc timeout_args=--version # I'd rather not run sync, since it spins up disks that I've ---- /dev/null 2007-01-09 09:38:07.860075128 +0000 -+++ coreutils-6.7/man/runuser.x 2007-01-09 17:27:56.000000000 +0000 -@@ -0,0 +1,12 @@ -+[NAME] -+runuser \- run a shell with substitute user and group IDs -+[DESCRIPTION] -+.\" Add any additional description here -+[SEE ALSO] -+.TP -+More detailed Texinfo documentation could be found by command -+.TP -+\t\fBinfo su invocation\fR\t -+.TP -+since the command \fBrunuser\fR is trimmed down version of command \fBrunuser\fR. -+.br diff --git a/coreutils-7.0-cp-mv-n.patch b/coreutils-7.0-cp-mv-n.patch new file mode 100644 index 0000000..c245b0f --- /dev/null +++ b/coreutils-7.0-cp-mv-n.patch @@ -0,0 +1,322 @@ +diff -ruNp coreutils-7.0.orig/doc/coreutils.texi coreutils-7.0/doc/coreutils.texi +--- coreutils-7.0.orig/doc/coreutils.texi 2009-01-28 15:28:14.724301000 +0100 ++++ coreutils-7.0/doc/coreutils.texi 2009-01-28 16:42:36.319138655 +0100 +@@ -7295,6 +7295,9 @@ description of @option{--remove-destinat + This option is independent of the @option{--interactive} or + @option{-i} option: neither cancels the effect of the other. + ++This option is redundant if the @option{--no-clobber} or @option{-n} option is ++used. ++ + @item -H + @opindex -H + If a command line argument specifies a symbolic link, then copy the +@@ -7307,7 +7310,8 @@ via recursive traversal. + @opindex -i + @opindex --interactive + When copying a file other than a directory, prompt whether to +-overwrite an existing destination file. ++overwrite an existing destination file. The @option{-i} option overrides ++a previous @option{-n} option. + + @item -l + @itemx --link +@@ -7321,6 +7325,14 @@ Make hard links instead of copies of non + @opindex --dereference + Follow symbolic links when copying from them. + ++@item -n ++@itemx --no-clobber ++@opindex -n ++@opindex --no-clobber ++Do not overwrite an existing file. The @option{-n} option overrides a previous ++@option{-i} option. This option is mutually exclusive with @option{-b} or ++@option{--backup} option. ++ + @item -P + @itemx --no-dereference + @opindex -P +@@ -8076,6 +8088,11 @@ The program accepts the following option + @opindex --force + @cindex prompts, omitting + Do not prompt the user before removing a destination file. ++@macro mvOptsIfn ++If you specify more than one of the @option{-i}, @option{-f}, @option{-n} ++options, only the final one takes effect. ++@end macro ++@mvOptsIfn + + @item -i + @itemx --interactive +@@ -8085,6 +8102,16 @@ Do not prompt the user before removing a + Prompt whether to overwrite each existing destination file, regardless + of its permissions. + If the response is not affirmative, the file is skipped. ++@mvOptsIfn ++ ++@item -n ++@itemx --no-clobber ++@opindex -n ++@opindex --no-clobber ++@cindex prompts, omitting ++Do not overwrite an existing file. ++@mvOptsIfn ++This option is mutually exclusive with @option{-b} or @option{--backup} option. + + @itemx @w{@kbd{--reply}=@var{how}} + @opindex --reply +diff -ruNp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c +--- coreutils-7.0.orig/src/cp.c 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/src/cp.c 2009-01-28 16:43:08.501394935 +0100 +@@ -1,5 +1,5 @@ + /* cp.c -- file copying (main routines) +- Copyright (C) 89, 90, 91, 1995-2008 Free Software Foundation, Inc. ++ Copyright (C) 89, 90, 91, 1995-2009 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 +@@ -129,6 +129,7 @@ static struct option const long_opts[] = + {"force", no_argument, NULL, 'f'}, + {"interactive", no_argument, NULL, 'i'}, + {"link", no_argument, NULL, 'l'}, ++ {"no-clobber", no_argument, NULL, 'n'}, + {"no-dereference", no_argument, NULL, 'P'}, + {"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION}, + {"no-target-directory", no_argument, NULL, 'T'}, +@@ -182,8 +183,10 @@ Mandatory arguments to long options are + "), stdout); + fputs (_("\ + -f, --force if an existing destination file cannot be\n\ +- opened, remove it and try again\n\ +- -i, --interactive prompt before overwrite\n\ ++ opened, remove it and try again (redundant if\n\ ++ the -n option is used)\n\ ++ -i, --interactive prompt before overwrite (overrides a previous -n\n\ ++ option)\n\ + -H follow command-line symbolic links in SOURCE\n\ + "), stdout); + fputs (_("\ +@@ -191,6 +194,8 @@ Mandatory arguments to long options are + -L, --dereference always follow symbolic links in SOURCE\n\ + "), stdout); + fputs (_("\ ++ -n, --no-clobber do not overwrite an existing file (overrides\n\ ++ a previous -i option)\n\ + -P, --no-dereference never follow symbolic links in SOURCE\n\ + "), stdout); + fputs (_("\ +@@ -909,7 +914,7 @@ main (int argc, char **argv) + we'll actually use backup_suffix_string. */ + backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); + +- while ((c = getopt_long (argc, argv, "abdfHilLprst:uvxPRS:T", ++ while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T", + long_opts, NULL)) + != -1) + { +@@ -965,6 +970,10 @@ main (int argc, char **argv) + x.dereference = DEREF_ALWAYS; + break; + ++ case 'n': ++ x.interactive = I_ALWAYS_NO; ++ break; ++ + case 'P': + x.dereference = DEREF_NEVER; + break; +@@ -1072,6 +1081,13 @@ main (int argc, char **argv) + usage (EXIT_FAILURE); + } + ++ if (make_backups && x.interactive == I_ALWAYS_NO) ++ { ++ error (0, 0, ++ _("options --backup and --no-clobber are mutually exclusive")); ++ usage (EXIT_FAILURE); ++ } ++ + if (backup_suffix_string) + simple_backup_suffix = xstrdup (backup_suffix_string); + +diff -ruNp coreutils-7.0.orig/src/mv.c coreutils-7.0/src/mv.c +--- coreutils-7.0.orig/src/mv.c 2008-08-24 22:30:10.000000000 +0200 ++++ coreutils-7.0/src/mv.c 2009-01-28 16:42:36.906143329 +0100 +@@ -1,5 +1,5 @@ + /* mv -- move or rename files +- Copyright (C) 86, 89, 90, 91, 1995-2008 Free Software Foundation, Inc. ++ Copyright (C) 86, 89, 90, 91, 1995-2009 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 +@@ -76,6 +76,7 @@ static struct option const long_options[ + {"backup", optional_argument, NULL, 'b'}, + {"force", no_argument, NULL, 'f'}, + {"interactive", no_argument, NULL, 'i'}, ++ {"no-clobber", no_argument, NULL, 'n'}, + {"no-target-directory", no_argument, NULL, 'T'}, + {"reply", required_argument, NULL, REPLY_OPTION}, /* Deprecated 2005-07-03, + remove in 2008. */ +@@ -312,6 +313,8 @@ Mandatory arguments to long options are + -b like --backup but does not accept an argument\n\ + -f, --force do not prompt before overwriting\n\ + -i, --interactive prompt before overwrite\n\ ++ -n, --no-clobber do not overwrite an existing file\n\ ++If you specify more than one of -i, -f, -n, only the final one takes effect.\n\ + "), stdout); + fputs (_("\ + --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\ +@@ -374,7 +377,7 @@ main (int argc, char **argv) + we'll actually use backup_suffix_string. */ + backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); + +- while ((c = getopt_long (argc, argv, "bfit:uvS:T", long_options, NULL)) ++ while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL)) + != -1) + { + switch (c) +@@ -396,6 +399,9 @@ main (int argc, char **argv) + error (0, 0, + _("the --reply option is deprecated; use -i or -f instead")); + break; ++ case 'n': ++ x.interactive = I_ALWAYS_NO; ++ break; + case STRIP_TRAILING_SLASHES_OPTION: + remove_trailing_slashes = true; + break; +@@ -468,6 +474,13 @@ main (int argc, char **argv) + quote (file[n_files - 1])); + } + ++ if (make_backups && x.interactive == I_ALWAYS_NO) ++ { ++ error (0, 0, ++ _("options --backup and --no-clobber are mutually exclusive")); ++ usage (EXIT_FAILURE); ++ } ++ + if (backup_suffix_string) + simple_backup_suffix = xstrdup (backup_suffix_string); + +diff -ruNp coreutils-7.0.orig/tests/cp/cp-i coreutils-7.0/tests/cp/cp-i +--- coreutils-7.0.orig/tests/cp/cp-i 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/tests/cp/cp-i 2009-01-28 16:42:37.092144811 +0100 +@@ -31,4 +31,40 @@ fail=0 + # coreutils 6.2 cp would neglect to prompt in this case. + echo n | cp -iR a b 2>/dev/null || fail=1 + ++# test miscellaneous combinations of -f -i -n parameters ++touch c d || framework_failure ++echo "\`c' -> \`d'" > out_copy ++> out_empty ++ ++# ask for overwrite, answer no ++echo n | cp -vi c d 2>/dev/null > out1 || fail=1 ++compare out1 out_empty || fail=1 ++ ++# ask for overwrite, answer yes ++echo y | cp -vi c d 2>/dev/null > out2 || fail=1 ++compare out2 out_copy || fail=1 ++ ++# -i wins over -n ++echo y | cp -vni c d 2>/dev/null > out3 || fail=1 ++compare out3 out_copy || fail=1 ++ ++# -n wins over -i ++echo y | cp -vin c d 2>/dev/null > out4 || fail=1 ++compare out4 out_empty || fail=1 ++ ++# ask for overwrite, answer yes ++echo y | cp -vfi c d 2>/dev/null > out5 || fail=1 ++compare out5 out_copy || fail=1 ++ ++# do not ask, prevent from overwrite ++echo n | cp -vfn c d 2>/dev/null > out6 || fail=1 ++compare out6 out_empty || fail=1 ++ ++# do not ask, prevent from overwrite ++echo n | cp -vnf c d 2>/dev/null > out7 || fail=1 ++compare out7 out_empty || fail=1 ++ ++# options --backup and --no-clobber are mutually exclusive ++cp -bn c d 2>/dev/null && fail=1 ++ + Exit $fail +diff -ruNp coreutils-7.0.orig/tests/Makefile.am coreutils-7.0/tests/Makefile.am +--- coreutils-7.0.orig/tests/Makefile.am 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/tests/Makefile.am 2009-01-28 16:42:37.596148824 +0100 +@@ -374,6 +374,7 @@ TESTS = \ + mv/into-self-3 \ + mv/into-self-4 \ + mv/leak-fd \ ++ mv/mv-n \ + mv/mv-special-1 \ + mv/no-target-dir \ + mv/part-fail \ +diff -ruNp coreutils-7.0.orig/tests/mv/mv-n coreutils-7.0/tests/mv/mv-n +--- coreutils-7.0.orig/tests/mv/mv-n 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-7.0/tests/mv/mv-n 2009-01-28 16:42:37.596148824 +0100 +@@ -0,0 +1,62 @@ ++#!/bin/sh ++# Test whether mv -n works as documented (not overwrite target). ++ ++# Copyright (C) 2006-2008 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 . ++ ++if test "$VERBOSE" = yes; then ++ set -x ++ mv --version ++fi ++ ++. $srcdir/test-lib.sh ++ ++fail=0 ++ ++# test miscellaneous combinations of -f -i -n parameters ++touch a b || framework_failure ++echo "\`a' -> \`b'" > out_move ++> out_empty ++ ++# ask for overwrite, answer no ++touch a b || framework_failure ++echo n | mv -vi a b 2>/dev/null > out1 || fail=1 ++compare out1 out_empty || fail=1 ++ ++# ask for overwrite, answer yes ++touch a b || framework_failure ++echo y | mv -vi a b 2>/dev/null > out2 || fail=1 ++compare out2 out_move || fail=1 ++ ++# -n wins (as the last option) ++touch a b || framework_failure ++echo y | mv -vin a b 2>/dev/null > out3 || fail=1 ++compare out3 out_empty || fail=1 ++ ++# -n wins (as the last option) ++touch a b || framework_failure ++echo y | mv -vfn a b 2>/dev/null > out4 || fail=1 ++compare out4 out_empty || fail=1 ++ ++# -n wins (as the last option) ++touch a b || framework_failure ++echo y | mv -vifn a b 2>/dev/null > out5 || fail=1 ++compare out5 out_empty || fail=1 ++ ++# options --backup and --no-clobber are mutually exclusive ++touch a || framework_failure ++mv -bn a b 2>/dev/null && fail=1 ++ ++Exit $fail diff --git a/coreutils-7.0-xattr.patch b/coreutils-7.0-xattr.patch new file mode 100644 index 0000000..a1bd3a8 --- /dev/null +++ b/coreutils-7.0-xattr.patch @@ -0,0 +1,792 @@ +diff -ruNp coreutils-7.0.orig/doc/coreutils.texi coreutils-7.0/doc/coreutils.texi +--- coreutils-7.0.orig/doc/coreutils.texi 2009-01-28 17:10:24.453415000 +0100 ++++ coreutils-7.0/doc/coreutils.texi 2009-01-28 17:12:04.986109287 +0100 +@@ -7346,7 +7346,7 @@ symbolic links in the destination are al + @itemx @w{@kbd{--preserve}[=@var{attribute_list}]} + @opindex -p + @opindex --preserve +-@cindex file information, preserving ++@cindex file information, preserving, extended attributes, xattr + Preserve the specified attributes of the original files. + If specified, the @var{attribute_list} must be a comma-separated list + of one or more of the following strings: +@@ -7373,6 +7373,11 @@ Preserve in the destination files + any links between corresponding source files. + @c Give examples illustrating how hard links are preserved. + @c Also, show how soft links map to hard links with -L and -H. ++@itemx xattr ++Preserve extended attributes if @command{cp} is built with xattr support, ++and xattrs are supported and enabled on your file system. If SELinux context ++and/or ACLs are implemented using xattrs, they are preserved as well by this ++option. + @itemx all + Preserve all file attributes. + Equivalent to specifying all of the above. +@@ -7912,6 +7917,9 @@ attributes of destination files. It is + copy programs into their destination directories. It refuses to copy + files onto themselves. + ++@cindex extended attributes, xattr ++@command{install} never preserves extended attributes (xattr). ++ + The program accepts the following options. Also see @ref{Common options}. + + @table @samp +@@ -8060,6 +8068,9 @@ directory succeeded, but the second didn + the destination partition and the second and third would be left on the + original partition. + ++@cindex extended attributes, xattr ++@command{mv} always tries to copy extended attributes (xattr). ++ + @cindex prompting, and @command{mv} + If a destination file exists but is normally unwritable, standard input + is a terminal, and the @option{-f} or @option{--force} option is not given, +diff -ruNp coreutils-7.0.orig/m4/prereq.m4 coreutils-7.0/m4/prereq.m4 +--- coreutils-7.0.orig/m4/prereq.m4 2008-06-21 19:04:15.000000000 +0200 ++++ coreutils-7.0/m4/prereq.m4 2009-01-28 17:12:04.987109294 +0100 +@@ -38,6 +38,7 @@ AC_DEFUN([gl_PREREQ], + # handles that; see ../bootstrap.conf. + AC_REQUIRE([gl_EUIDACCESS_STAT]) + AC_REQUIRE([gl_FD_REOPEN]) ++ AC_REQUIRE([gl_FUNC_XATTR]) + AC_REQUIRE([gl_FUNC_XFTS]) + AC_REQUIRE([gl_MEMXFRM]) + AC_REQUIRE([gl_STRINTCMP]) +diff -ruNp coreutils-7.0.orig/m4/xattr.m4 coreutils-7.0/m4/xattr.m4 +--- coreutils-7.0.orig/m4/xattr.m4 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-7.0/m4/xattr.m4 2009-01-28 17:12:04.988109301 +0100 +@@ -0,0 +1,36 @@ ++# xattr.m4 - check for Extended Attributes (Linux) ++ ++# Copyright (C) 2003, 2008 Free Software Foundation, Inc. ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# Originally written by Andreas Gruenbacher. ++# http://www.suse.de/~agruen/coreutils/5.91/coreutils-xattr.diff ++ ++AC_DEFUN([gl_FUNC_XATTR], ++[ ++ AC_ARG_ENABLE([xattr], ++ AC_HELP_STRING([--disable-xattr], ++ [do not support extended attributes]), ++ [use_xattr=$enableval], [use_xattr=yes]) ++ ++ if test "$use_xattr" = "yes"; then ++ AC_CHECK_HEADERS([attr/error_context.h attr/libattr.h]) ++ if test $ac_cv_header_attr_libattr_h = yes \ ++ && test $ac_cv_header_attr_error_context_h = yes; then ++ use_xattr=1 ++ else ++ use_xattr=0 ++ fi ++ AC_DEFINE_UNQUOTED([USE_XATTR], [$use_xattr], ++ [Define if you want extended attribute support.]) ++ xattr_saved_LIBS=$LIBS ++ AC_SEARCH_LIBS([attr_copy_file], [attr], ++ [test "$ac_cv_search_attr_copy_file" = "none required" || ++ LIB_XATTR=$ac_cv_search_attr_copy_file]) ++ AC_CHECK_FUNCS([attr_copy_file]) ++ LIBS=$xattr_saved_LIBS ++ AC_SUBST([LIB_XATTR]) ++ fi ++]) +diff -ruNp coreutils-7.0.orig/src/copy.c coreutils-7.0/src/copy.c +--- coreutils-7.0.orig/src/copy.c 2008-08-24 22:30:10.000000000 +0200 ++++ coreutils-7.0/src/copy.c 2009-01-28 17:12:04.990109315 +0100 +@@ -55,6 +55,13 @@ + #include "areadlink.h" + #include "yesno.h" + ++#if USE_XATTR ++# include ++# include ++# include ++# include "verror.h" ++#endif ++ + #ifndef HAVE_FCHOWN + # define HAVE_FCHOWN false + # define fchown(fd, uid, gid) (-1) +@@ -124,6 +131,70 @@ is_ancestor (const struct stat *sb, cons + return false; + } + ++#if USE_XATTR ++static void ++copy_attr_error (struct error_context *ctx, char const *fmt, ...) ++{ ++ int err = errno; ++ va_list ap; ++ ++ /* use verror module to print error message */ ++ va_start (ap, fmt); ++ verror (0, err, fmt, ap); ++ va_end (ap); ++} ++ ++static char const * ++copy_attr_quote (struct error_context *ctx, char const *str) ++{ ++ return quote (str); ++} ++ ++static void ++copy_attr_free (struct error_context *ctx, char const *str) ++{ ++} ++ ++static bool ++copy_attr_by_fd (char const *src_path, int src_fd, ++ char const *dst_path, int dst_fd) ++{ ++ struct error_context ctx = ++ { ++ .error = copy_attr_error, ++ .quote = copy_attr_quote, ++ .quote_free = copy_attr_free ++ }; ++ return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0, &ctx); ++} ++ ++static bool ++copy_attr_by_name (char const *src_path, char const *dst_path) ++{ ++ struct error_context ctx = ++ { ++ .error = copy_attr_error, ++ .quote = copy_attr_quote, ++ .quote_free = copy_attr_free ++ }; ++ return 0 == attr_copy_file (src_path, dst_path, 0, &ctx); ++} ++#else /* USE_XATTR */ ++ ++static bool ++copy_attr_by_fd (char const *src_path, int src_fd, ++ char const *dst_path, int dst_fd) ++{ ++ return true; ++} ++ ++static bool ++copy_attr_by_name (char const *src_path, char const *dst_path) ++{ ++ return true; ++} ++#endif /* USE_XATTR */ ++ + /* Read the contents of the directory SRC_NAME_IN, and recursively + copy the contents to DST_NAME_IN. NEW_DST is true if + DST_NAME_IN is a directory that was created previously in the +@@ -682,6 +753,11 @@ copy_reg (char const *src_name, char con + + set_author (dst_name, dest_desc, src_sb); + ++ if (x->preserve_xattr && ! copy_attr_by_fd (src_name, source_desc, ++ dst_name, dest_desc) ++ && x->require_preserve_xattr) ++ return false; ++ + if (x->preserve_mode || x->move_mode) + { + if (copy_acl (src_name, source_desc, dst_name, dest_desc, src_mode) != 0 +@@ -1980,6 +2056,10 @@ copy_internal (char const *src_name, cha + + set_author (dst_name, -1, &src_sb); + ++ if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name) ++ && x->require_preserve_xattr) ++ return false; ++ + if (x->preserve_mode || x->move_mode) + { + if (copy_acl (src_name, -1, dst_name, -1, src_mode) != 0 +diff -ruNp coreutils-7.0.orig/src/copy.h coreutils-7.0/src/copy.h +--- coreutils-7.0.orig/src/copy.h 2008-06-21 17:20:29.000000000 +0200 ++++ coreutils-7.0/src/copy.h 2009-01-28 17:12:04.991109322 +0100 +@@ -174,6 +174,19 @@ struct cp_options + fail if it is unable to do so. */ + bool require_preserve_context; + ++ /* If true, attempt to preserve extended attributes using libattr. ++ Ignored if coreutils are compiled without xattr support. */ ++ bool preserve_xattr; ++ ++ /* Useful only when preserve_xattr is true. ++ If true, a failed attempt to preserve file's extended attributes ++ propagates failure "out" to the caller. If false, a failure to ++ preserve file's extended attributes does not change the invoking ++ application's exit status. Give diagnostics for failed syscalls ++ regardless of this setting. For example, with "cp --preserve=xattr" ++ this flag is "true", while with "cp --preserve=all", it is false. */ ++ bool require_preserve_xattr; ++ + /* If true, copy directories recursively and copy special files + as themselves rather than copying their contents. */ + bool recursive; +diff -ruNp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c +--- coreutils-7.0.orig/src/cp.c 2009-01-28 17:10:24.455415000 +0100 ++++ coreutils-7.0/src/cp.c 2009-01-28 17:12:04.992109329 +0100 +@@ -202,7 +202,8 @@ Mandatory arguments to long options are + -p same as --preserve=mode,ownership,timestamps\n\ + --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\ + mode,ownership,timestamps), if possible\n\ +- additional attributes: context, links, all\n\ ++ additional attributes: context, links, xattr,\n\ ++ all\n\ + "), stdout); + fputs (_("\ + --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ +@@ -779,6 +780,8 @@ cp_option_init (struct cp_options *x) + x->preserve_timestamps = false; + x->preserve_security_context = false; + x->require_preserve_context = false; ++ x->preserve_xattr = false; ++ x->require_preserve_xattr = false; + + x->require_preserve = false; + x->recursive = false; +@@ -815,18 +818,20 @@ decode_preserve_arg (char const *arg, st + PRESERVE_OWNERSHIP, + PRESERVE_LINK, + PRESERVE_CONTEXT, ++ PRESERVE_XATTR, + PRESERVE_ALL + }; + static enum File_attribute const preserve_vals[] = + { + PRESERVE_MODE, PRESERVE_TIMESTAMPS, +- PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_ALL ++ PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_XATTR, ++ PRESERVE_ALL + }; + /* Valid arguments to the `--preserve' option. */ + static char const* const preserve_args[] = + { + "mode", "timestamps", +- "ownership", "links", "context", "all", NULL ++ "ownership", "links", "context", "xattr", "all", NULL + }; + ARGMATCH_VERIFY (preserve_args, preserve_vals); + +@@ -867,6 +872,11 @@ decode_preserve_arg (char const *arg, st + x->require_preserve_context = on_off; + break; + ++ case PRESERVE_XATTR: ++ x->preserve_xattr = on_off; ++ x->require_preserve_xattr = on_off; ++ break; ++ + case PRESERVE_ALL: + x->preserve_mode = on_off; + x->preserve_timestamps = on_off; +@@ -874,6 +884,7 @@ decode_preserve_arg (char const *arg, st + x->preserve_links = on_off; + if (selinux_enabled) + x->preserve_security_context = on_off; ++ x->preserve_xattr = on_off; + break; + + default: +@@ -1121,6 +1132,12 @@ main (int argc, char **argv) + "without an SELinux-enabled kernel")); + } + ++#if !USE_XATTR ++ if (x.require_preserve_xattr) ++ error (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is " ++ "built without xattr support")); ++#endif ++ + /* Allocate space for remembering copied and created files. */ + + hash_init (); +diff -ruNp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c +--- coreutils-7.0.orig/src/install.c 2008-09-27 19:28:41.000000000 +0200 ++++ coreutils-7.0/src/install.c 2009-01-28 17:12:04.993109336 +0100 +@@ -200,6 +200,7 @@ cp_option_init (struct cp_options *x) + x->open_dangling_dest_symlink = false; + x->update = false; + x->preserve_security_context = false; ++ x->preserve_xattr = false; + x->verbose = false; + x->dest_info = NULL; + x->src_info = NULL; +diff -ruNp coreutils-7.0.orig/src/Makefile.am coreutils-7.0/src/Makefile.am +--- coreutils-7.0.orig/src/Makefile.am 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/src/Makefile.am 2009-01-28 17:15:23.106476067 +0100 +@@ -149,9 +149,9 @@ su_LDADD = $(LDADD) $(LIB_CRYPT) + dir_LDADD += $(LIB_ACL) + ls_LDADD += $(LIB_ACL) + vdir_LDADD += $(LIB_ACL) +-cp_LDADD += $(LIB_ACL) +-mv_LDADD += $(LIB_ACL) +-ginstall_LDADD += $(LIB_ACL) ++cp_LDADD += $(LIB_ACL) $(LIB_XATTR) ++mv_LDADD += $(LIB_ACL) $(LIB_XATTR) ++ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR) + + stat_LDADD = $(LDADD) $(LIB_SELINUX) + +@@ -226,7 +226,7 @@ uninstall-local: + fi; \ + fi + +-copy_sources = copy.c cp-hash.c ++copy_sources = copy.c cp-hash.c verror.c xvasprintf.c + + # Use `ginstall' in the definition of PROGRAMS and in dependencies to avoid + # confusion with the `install' target. The install rule transforms `ginstall' +diff -ruNp coreutils-7.0.orig/src/mv.c coreutils-7.0/src/mv.c +--- coreutils-7.0.orig/src/mv.c 2009-01-28 17:10:24.456415000 +0100 ++++ coreutils-7.0/src/mv.c 2009-01-28 17:12:04.994109343 +0100 +@@ -140,6 +140,7 @@ cp_option_init (struct cp_options *x) + x->preserve_security_context = selinux_enabled; + x->require_preserve = false; /* FIXME: maybe make this an option */ + x->require_preserve_context = false; ++ x->preserve_xattr = true; + x->recursive = true; + x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */ + x->symbolic_link = false; +diff -ruNp coreutils-7.0.orig/tests/Makefile.am coreutils-7.0/tests/Makefile.am +--- coreutils-7.0.orig/tests/Makefile.am 2009-01-28 17:10:24.457415000 +0100 ++++ coreutils-7.0/tests/Makefile.am 2009-01-28 17:12:04.994109343 +0100 +@@ -230,6 +230,7 @@ TESTS = \ + misc/tty-eof \ + misc/unexpand \ + misc/uniq \ ++ misc/xattr \ + chmod/c-option \ + chmod/equal-x \ + chmod/equals \ +diff -ruNp coreutils-7.0.orig/tests/misc/xattr coreutils-7.0/tests/misc/xattr +--- coreutils-7.0.orig/tests/misc/xattr 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-7.0/tests/misc/xattr 2009-01-28 17:12:04.995109350 +0100 +@@ -0,0 +1,111 @@ ++#!/bin/sh ++# Ensure that cp --preserve=xattr and mv preserve extended attributes and ++# install does not preserve extended attributes. ++ ++# Copyright (C) 2009 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 . ++ ++if test "$VERBOSE" = yes; then ++ set -x ++ cp --version ++ mv --version ++ ginstall --version ++fi ++ ++. $srcdir/test-lib.sh ++ ++# Skip this test if cp was built without xattr support: ++touch src dest || framework_failure ++cp --preserve=xattr -n src dest 2>/dev/null \ ++ || skip_test_ "coreutils built without xattr support" ++ ++# this code was taken from test mv/backup-is-src ++cleanup_() { rm -rf "$other_partition_tmpdir"; } ++. "$abs_srcdir/other-fs-tmpdir" ++b_other="$other_partition_tmpdir/b" ++rm -f $b_other || framework_failure ++ ++# testing xattr name-value pair ++xattr_name="user.foo" ++xattr_value="bar" ++xattr_pair="$xattr_name=\"$xattr_value\"" ++ ++# create new file and check its xattrs ++touch a || framework_failure ++getfattr -d a >out_a || skip_test_ "failed to get xattr of file" ++grep -F "$xattr_pair" out_a >/dev/null && framework_failure ++ ++# try to set user xattr on file ++setfattr -n "$xattr_name" -v "$xattr_value" a >out_a \ ++ || skip_test_ "failed to set xattr of file" ++getfattr -d a >out_a || skip_test_ "failed to get xattr of file" ++grep -F "$xattr_pair" out_a >/dev/null \ ++ || skip_test_ "failed to set xattr of file" ++ ++fail=0 ++ ++# cp should not preserve xattr by default ++cp a b || fail=1 ++getfattr -d b >out_b || skip_test_ "failed to get xattr of file" ++grep -F "$xattr_pair" out_b >/dev/null && fail=1 ++ ++# test if --preserve=xattr option works ++cp --preserve=xattr a b || fail=1 ++getfattr -d b >out_b || skip_test_ "failed to get xattr of file" ++grep -F "$xattr_pair" out_b >/dev/null || fail=1 ++ ++rm b || framework_failure ++ ++# install should never preserve xattr ++ginstall a b || fail=1 ++getfattr -d b >out_b || skip_test_ "failed to get xattr of file" ++grep -F "$xattr_pair" out_b >/dev/null && fail=1 ++ ++# mv should preserve xattr when renaming within a filesystem. ++# This is implicitly done by rename () and doesn't need explicit ++# xattr support in mv. ++mv a b || fail=1 ++getfattr -d b >out_b || skip_test_ "failed to get xattr of file" ++grep -F "$xattr_pair" out_b >/dev/null || cat >&2 <out_a 2>/dev/null \ ++ || test_mv=0 ++getfattr -d $b_other >out_b 2>/dev/null || test_mv=0 ++grep -F "$xattr_pair" out_b >/dev/null || test_mv=0 ++rm -f $b_other || framework_failure ++ ++if test $test_mv -eq 1; then ++ # mv should preserve xattr when copying content from one partition to another ++ mv b $b_other || fail=1 ++ getfattr -d $b_other >out_b 2>/dev/null || skip_test_ "failed to get xattr of file" ++ grep -F "$xattr_pair" out_b >/dev/null || fail=1 ++else ++ cat >&2 <. */ ++ ++/* Written by Eric Blake. */ ++ ++#include ++ ++#include "verror.h" ++#include "xvasprintf.h" ++ ++#include ++#include ++#include ++ ++#if ENABLE_NLS ++# include "gettext.h" ++# define _(msgid) gettext (msgid) ++#endif ++ ++#ifndef _ ++# define _(String) String ++#endif ++ ++/* Print a message with `vfprintf (stderr, FORMAT, ARGS)'; ++ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). ++ If STATUS is nonzero, terminate the program with `exit (STATUS)'. ++ Use the globals error_print_progname and error_message_count similarly ++ to error(). */ ++void ++verror (int status, int errnum, const char *format, va_list args) ++{ ++ verror_at_line (status, errnum, NULL, 0, format, args); ++} ++ ++/* Print a message with `vfprintf (stderr, FORMAT, ARGS)'; ++ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). ++ If STATUS is nonzero, terminate the program with `exit (STATUS)'. ++ If FNAME is not NULL, prepend the message with `FNAME:LINENO:'. ++ Use the globals error_print_progname, error_message_count, and ++ error_one_per_line similarly to error_at_line(). */ ++void ++verror_at_line (int status, int errnum, const char *file, ++ unsigned int line_number, const char *format, va_list args) ++{ ++ char *message = xvasprintf (format, args); ++ if (message) ++ { ++ /* Until http://sourceware.org/bugzilla/show_bug.cgi?id=2997 is fixed, ++ glibc violates GNU Coding Standards when the file argument to ++ error_at_line is NULL. */ ++ if (file) ++ error_at_line (status, errnum, file, line_number, "%s", message); ++ else ++ error (status, errnum, "%s", message); ++ } ++ else ++ { ++ /* EOVERFLOW, EINVAL, and EILSEQ from xvasprintf are signs of ++ serious programmer errors. */ ++ error (0, errno, _("unable to display error message")); ++ abort (); ++ } ++ free (message); ++} +diff -ruNp coreutils-7.0.orig/src/verror.h coreutils-7.0/src/verror.h +--- coreutils-7.0.orig/src/verror.h 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-7.0/src/verror.h 2009-01-28 17:14:54.039275540 +0100 +@@ -0,0 +1,53 @@ ++/* Declaration for va_list error-reporting function ++ Copyright (C) 2006-2007 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 . */ ++ ++#ifndef _VERROR_H ++#define _VERROR_H 1 ++ ++#include "error.h" ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* Print a message with `vfprintf (stderr, FORMAT, ARGS)'; ++ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). ++ If STATUS is nonzero, terminate the program with `exit (STATUS)'. ++ Use the globals error_print_progname and error_message_count similarly ++ to error(). */ ++ ++extern void verror (int __status, int __errnum, const char *__format, ++ va_list __args) ++ __attribute__ ((__format__ (__printf__, 3, 0))); ++ ++/* Print a message with `vfprintf (stderr, FORMAT, ARGS)'; ++ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). ++ If STATUS is nonzero, terminate the program with `exit (STATUS)'. ++ If FNAME is not NULL, prepend the message with `FNAME:LINENO:'. ++ Use the globals error_print_progname, error_message_count, and ++ error_one_per_line similarly to error_at_line(). */ ++ ++extern void verror_at_line (int __status, int __errnum, const char *__fname, ++ unsigned int __lineno, const char *__format, ++ va_list __args) ++ __attribute__ ((__format__ (__printf__, 5, 0))); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* verror.h */ +diff -ruNp coreutils-7.0.orig/src/xvasprintf.c coreutils-7.0/src/xvasprintf.c +--- coreutils-7.0.orig/src/xvasprintf.c 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-7.0/src/xvasprintf.c 2009-01-28 17:15:06.809363638 +0100 +@@ -0,0 +1,110 @@ ++/* vasprintf and asprintf with out-of-memory checking. ++ Copyright (C) 1999, 2002-2004, 2006-2008 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 . */ ++ ++#include ++ ++/* Specification. */ ++#include "xvasprintf.h" ++ ++#include ++#include ++#include ++#include ++ ++#include "xalloc.h" ++ ++/* Checked size_t computations. */ ++#include "xsize.h" ++ ++static inline char * ++xstrcat (size_t argcount, va_list args) ++{ ++ char *result; ++ va_list ap; ++ size_t totalsize; ++ size_t i; ++ char *p; ++ ++ /* Determine the total size. */ ++ totalsize = 0; ++ va_copy (ap, args); ++ for (i = argcount; i > 0; i--) ++ { ++ const char *next = va_arg (ap, const char *); ++ totalsize = xsum (totalsize, strlen (next)); ++ } ++ va_end (ap); ++ ++ /* Test for overflow in the summing pass above or in (totalsize + 1) below. ++ Also, don't return a string longer than INT_MAX, for consistency with ++ vasprintf(). */ ++ if (totalsize == SIZE_MAX || totalsize > INT_MAX) ++ { ++ errno = EOVERFLOW; ++ return NULL; ++ } ++ ++ /* Allocate and fill the result string. */ ++ result = XNMALLOC (totalsize + 1, char); ++ p = result; ++ for (i = argcount; i > 0; i--) ++ { ++ const char *next = va_arg (args, const char *); ++ size_t len = strlen (next); ++ memcpy (p, next, len); ++ p += len; ++ } ++ *p = '\0'; ++ ++ return result; ++} ++ ++char * ++xvasprintf (const char *format, va_list args) ++{ ++ char *result; ++ ++ /* Recognize the special case format = "%s...%s". It is a frequently used ++ idiom for string concatenation and needs to be fast. We don't want to ++ have a separate function xstrcat() for this purpose. */ ++ { ++ size_t argcount = 0; ++ const char *f; ++ ++ for (f = format;;) ++ { ++ if (*f == '\0') ++ /* Recognized the special case of string concatenation. */ ++ return xstrcat (argcount, args); ++ if (*f != '%') ++ break; ++ f++; ++ if (*f != 's') ++ break; ++ f++; ++ argcount++; ++ } ++ } ++ ++ if (vasprintf (&result, format, args) < 0) ++ { ++ if (errno == ENOMEM) ++ xalloc_die (); ++ return NULL; ++ } ++ ++ return result; ++} +diff -ruNp coreutils-7.0.orig/src/xvasprintf.h coreutils-7.0/src/xvasprintf.h +--- coreutils-7.0.orig/src/xvasprintf.h 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-7.0/src/xvasprintf.h 2009-01-28 17:15:06.809363638 +0100 +@@ -0,0 +1,56 @@ ++/* vasprintf and asprintf with out-of-memory checking. ++ Copyright (C) 2002-2004, 2006-2008 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 . */ ++ ++#ifndef _XVASPRINTF_H ++#define _XVASPRINTF_H ++ ++/* Get va_list. */ ++#include ++ ++#ifndef __attribute__ ++/* This feature is available in gcc versions 2.5 and later. */ ++# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) ++# define __attribute__(Spec) /* empty */ ++# endif ++/* The __-protected variants of `format' and `printf' attributes ++ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ ++# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ++# define __format__ format ++# define __printf__ printf ++# endif ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/* Write formatted output to a string dynamically allocated with malloc(), ++ and return it. Upon [ENOMEM] memory allocation error, call xalloc_die. ++ On some other error ++ - [EOVERFLOW] resulting string length is > INT_MAX, ++ - [EINVAL] invalid format string, ++ - [EILSEQ] error during conversion between wide and multibyte characters, ++ return NULL. */ ++extern char *xasprintf (const char *format, ...) ++ __attribute__ ((__format__ (__printf__, 1, 2))); ++extern char *xvasprintf (const char *format, va_list args) ++ __attribute__ ((__format__ (__printf__, 1, 0))); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _XVASPRINTF_H */ diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 41b396c..95f0401 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,6 +1,6 @@ -diff -urp coreutils-6.10-orig/configure.ac coreutils-6.10/configure.ac ---- coreutils-6.10-orig/configure.ac 2008-01-25 12:32:33.000000000 +0100 -+++ coreutils-6.10/configure.ac 2008-01-25 14:10:34.000000000 +0100 +diff -urp coreutils-7.0.orig/configure.ac coreutils-7.0/configure.ac +--- coreutils-7.0.orig/configure.ac 2009-01-28 17:18:16.790672000 +0100 ++++ coreutils-7.0/configure.ac 2009-01-28 17:18:52.757913913 +0100 @@ -51,6 +51,13 @@ AC_ARG_ENABLE(pam, dnl LIB_PAM="-ldl -lpam -lpam_misc" AC_SUBST(LIB_PAM)]) @@ -15,18 +15,18 @@ diff -urp coreutils-6.10-orig/configure.ac coreutils-6.10/configure.ac AC_FUNC_FORK optional_bin_progs= -diff -urNp coreutils-6.12-orig/man/chcon.x coreutils-6.12/man/chcon.x ---- coreutils-6.12-orig/man/chcon.x 2008-03-07 17:05:53.000000000 +0100 -+++ coreutils-6.12/man/chcon.x 2008-10-21 15:53:43.000000000 +0200 +diff -urp coreutils-7.0.orig/man/chcon.x coreutils-7.0/man/chcon.x +--- coreutils-7.0.orig/man/chcon.x 2008-03-07 17:05:53.000000000 +0100 ++++ coreutils-7.0/man/chcon.x 2009-01-28 17:18:52.759913926 +0100 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-6.12-orig/man/runcon.x coreutils-6.12/man/runcon.x ---- coreutils-6.12-orig/man/runcon.x 2008-03-07 17:05:53.000000000 +0100 -+++ coreutils-6.12/man/runcon.x 2008-10-21 15:54:01.000000000 +0200 +diff -urp coreutils-7.0.orig/man/runcon.x coreutils-7.0/man/runcon.x +--- coreutils-7.0.orig/man/runcon.x 2008-03-07 17:05:53.000000000 +0100 ++++ coreutils-7.0/man/runcon.x 2009-01-28 17:18:52.760913933 +0100 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,10 +34,10 @@ diff -urNp coreutils-6.12-orig/man/runcon.x coreutils-6.12/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-6.12-orig/src/chcon.c coreutils-6.12/src/chcon.c ---- coreutils-6.12-orig/src/chcon.c 2008-05-26 08:40:32.000000000 +0200 -+++ coreutils-6.12/src/chcon.c 2008-06-16 14:43:24.000000000 +0200 -@@ -352,7 +352,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ +diff -urp coreutils-7.0.orig/src/chcon.c coreutils-7.0/src/chcon.c +--- coreutils-7.0.orig/src/chcon.c 2008-08-24 22:30:10.000000000 +0200 ++++ coreutils-7.0/src/chcon.c 2009-01-28 17:18:52.761913940 +0100 +@@ -366,7 +366,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), program_name, program_name, program_name); fputs (_("\ @@ -46,10 +46,10 @@ diff -urNp coreutils-6.12-orig/src/chcon.c coreutils-6.12/src/chcon.c With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ -c, --changes like verbose but report only when a change is made\n\ -diff -urp coreutils-6.10-orig/src/copy.c coreutils-6.10/src/copy.c ---- coreutils-6.10-orig/src/copy.c 2008-01-05 23:59:11.000000000 +0100 -+++ coreutils-6.10/src/copy.c 2008-01-25 17:23:17.000000000 +0100 -@@ -371,9 +371,10 @@ copy_reg (char const *src_name, char con +diff -urp coreutils-7.0.orig/src/copy.c coreutils-7.0/src/copy.c +--- coreutils-7.0.orig/src/copy.c 2009-01-28 17:18:16.748671000 +0100 ++++ coreutils-7.0/src/copy.c 2009-01-28 17:18:52.762913947 +0100 +@@ -449,9 +449,10 @@ copy_reg (char const *src_name, char con security_context_t con = NULL; if (getfscreatecon (&con) < 0) { @@ -61,7 +61,7 @@ diff -urp coreutils-6.10-orig/src/copy.c coreutils-6.10/src/copy.c return_val = false; goto close_src_and_dst_desc; } -@@ -383,11 +384,12 @@ copy_reg (char const *src_name, char con +@@ -461,11 +462,12 @@ copy_reg (char const *src_name, char con { if (fsetfilecon (dest_desc, con) < 0) { @@ -77,7 +77,7 @@ diff -urp coreutils-6.10-orig/src/copy.c coreutils-6.10/src/copy.c return_val = false; freecon (con); goto close_src_and_dst_desc; -@@ -1630,11 +1632,12 @@ copy_internal (char const *src_name, cha +@@ -1714,11 +1716,12 @@ copy_internal (char const *src_name, cha { if (setfscreatecon (con) < 0) { @@ -93,7 +93,7 @@ diff -urp coreutils-6.10-orig/src/copy.c coreutils-6.10/src/copy.c freecon (con); return false; } -@@ -1644,12 +1647,14 @@ copy_internal (char const *src_name, cha +@@ -1728,12 +1731,14 @@ copy_internal (char const *src_name, cha else { if (errno != ENOTSUP && errno != ENODATA) @@ -114,7 +114,7 @@ diff -urp coreutils-6.10-orig/src/copy.c coreutils-6.10/src/copy.c } } } -@@ -1735,6 +1740,8 @@ copy_internal (char const *src_name, cha +@@ -1819,6 +1824,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -123,9 +123,9 @@ diff -urp coreutils-6.10-orig/src/copy.c coreutils-6.10/src/copy.c } else { -diff -urp coreutils-6.10-orig/src/copy.h coreutils-6.10/src/copy.h ---- coreutils-6.10-orig/src/copy.h 2008-01-05 23:58:25.000000000 +0100 -+++ coreutils-6.10/src/copy.h 2008-01-25 16:29:21.000000000 +0100 +diff -urp coreutils-7.0.orig/src/copy.h coreutils-7.0/src/copy.h +--- coreutils-7.0.orig/src/copy.h 2009-01-28 17:18:16.748671000 +0100 ++++ coreutils-7.0/src/copy.h 2009-01-28 17:18:52.763913953 +0100 @@ -141,6 +141,9 @@ struct cp_options bool preserve_mode; bool preserve_timestamps; @@ -136,10 +136,10 @@ diff -urp coreutils-6.10-orig/src/copy.h coreutils-6.10/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urp coreutils-6.10-orig/src/cp.c coreutils-6.10/src/cp.c ---- coreutils-6.10-orig/src/cp.c 2008-01-11 12:19:53.000000000 +0100 -+++ coreutils-6.10/src/cp.c 2008-01-25 16:26:22.000000000 +0100 -@@ -147,6 +147,7 @@ static struct option const long_opts[] = +diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c +--- coreutils-7.0.orig/src/cp.c 2009-01-28 17:18:16.750671000 +0100 ++++ coreutils-7.0/src/cp.c 2009-01-28 17:20:29.109561384 +0100 +@@ -148,6 +148,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, {"verbose", no_argument, NULL, 'v'}, @@ -147,7 +147,7 @@ diff -urp coreutils-6.10-orig/src/cp.c coreutils-6.10/src/cp.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -175,7 +175,7 @@ Copy SOURCE to DEST, or multiple SOURCE( +@@ -175,7 +176,7 @@ Copy SOURCE to DEST, or multiple SOURCE( Mandatory arguments to long options are mandatory for short options too.\n\ "), stdout); fputs (_("\ @@ -156,8 +156,8 @@ diff -urp coreutils-6.10-orig/src/cp.c coreutils-6.10/src/cp.c --backup[=CONTROL] make a backup of each existing destination file\n\ -b like --backup but does not accept an argument\n\ --copy-contents copy contents of special files when recursive\n\ -@@ -200,6 +201,9 @@ Mandatory arguments to long options are - additional attributes: context, links, all\n\ +@@ -206,6 +207,9 @@ Mandatory arguments to long options are + all\n\ "), stdout); fputs (_("\ + -c same as --preserve=context\n\ @@ -166,7 +166,7 @@ diff -urp coreutils-6.10-orig/src/cp.c coreutils-6.10/src/cp.c --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents use full source file name under DIRECTORY\n\ "), stdout); -@@ -225,6 +229,7 @@ Mandatory arguments to long options are +@@ -231,6 +235,7 @@ Mandatory arguments to long options are destination file is missing\n\ -v, --verbose explain what is being done\n\ -x, --one-file-system stay on this file system\n\ @@ -174,24 +174,24 @@ diff -urp coreutils-6.10-orig/src/cp.c coreutils-6.10/src/cp.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); -@@ -774,6 +779,7 @@ cp_option_init (struct cp_options *x) +@@ -780,6 +785,7 @@ cp_option_init (struct cp_options *x) x->preserve_timestamps = false; x->preserve_security_context = false; x->require_preserve_context = false; + x->set_security_context = false; + x->preserve_xattr = false; + x->require_preserve_xattr = false; - x->require_preserve = false; - x->recursive = false; -@@ -909,7 +917,7 @@ main (int argc, char **argv) +@@ -925,7 +931,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); -- while ((c = getopt_long (argc, argv, "abdfHilLprst:uvxPRS:T", -+ while ((c = getopt_long (argc, argv, "abcdfHilLprst:uvxPRS:TZ:", +- while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T", ++ while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ:", long_opts, NULL)) != -1) { -@@ -920,13 +928,15 @@ main (int argc, char **argv) +@@ -936,13 +942,15 @@ main (int argc, char **argv) sparse_type_string, sparse_type); break; @@ -209,7 +209,7 @@ diff -urp coreutils-6.10-orig/src/cp.c coreutils-6.10/src/cp.c x.recursive = true; break; -@@ -940,6 +950,16 @@ main (int argc, char **argv) +@@ -956,6 +964,16 @@ main (int argc, char **argv) copy_contents = true; break; @@ -226,7 +226,7 @@ diff -urp coreutils-6.10-orig/src/cp.c coreutils-6.10/src/cp.c case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -@@ -1052,6 +1072,27 @@ main (int argc, char **argv) +@@ -1072,6 +1090,27 @@ main (int argc, char **argv) x.one_file_system = true; break; @@ -254,10 +254,10 @@ diff -urp coreutils-6.10-orig/src/cp.c coreutils-6.10/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urp coreutils-6.10-orig/src/id.c coreutils-6.10/src/id.c ---- coreutils-6.10-orig/src/id.c 2008-01-05 23:59:11.000000000 +0100 -+++ coreutils-6.10/src/id.c 2008-01-25 17:13:53.000000000 +0100 -@@ -110,7 +110,7 @@ int +diff -urp coreutils-7.0.orig/src/id.c coreutils-7.0/src/id.c +--- coreutils-7.0.orig/src/id.c 2008-08-24 22:58:15.000000000 +0200 ++++ coreutils-7.0/src/id.c 2009-01-28 17:18:52.766913973 +0100 +@@ -106,7 +106,7 @@ int main (int argc, char **argv) { int optc; @@ -266,11 +266,10 @@ diff -urp coreutils-6.10-orig/src/id.c coreutils-6.10/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c ---- coreutils-6.10-orig/src/install.c 2008-01-05 23:59:11.000000000 +0100 -+++ coreutils-6.10/src/install.c 2008-01-25 17:32:42.000000000 +0100 - -@@ -146,11 +146,11 @@ static struct option const long_options[ +diff -urp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c +--- coreutils-7.0.orig/src/install.c 2009-01-28 17:18:16.751671000 +0100 ++++ coreutils-7.0/src/install.c 2009-01-28 17:18:52.767913980 +0100 +@@ -152,11 +152,11 @@ static struct option const long_options[ {"no-target-directory", no_argument, NULL, 'T'}, {"owner", required_argument, NULL, 'o'}, {"preserve-timestamps", no_argument, NULL, 'p'}, @@ -284,7 +283,7 @@ diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c {"strip", no_argument, NULL, 's'}, {"strip-program", required_argument, NULL, STRIP_PROGRAM_OPTION}, {"suffix", required_argument, NULL, 'S'}, -@@ -178,6 +178,7 @@ cp_option_init (struct cp_options *x) +@@ -185,6 +185,7 @@ cp_option_init (struct cp_options *x) x->preserve_timestamps = false; x->require_preserve = false; x->require_preserve_context = false; @@ -292,7 +291,7 @@ diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c x->recursive = false; x->sparse_mode = SPARSE_AUTO; x->symbolic_link = false; -@@ -346,7 +338,7 @@ main (int argc, char **argv) +@@ -361,7 +362,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -301,7 +300,7 @@ diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c NULL)) != -1) { switch (optc) -@@ -408,6 +409,7 @@ main (int argc, char **argv) +@@ -428,6 +429,7 @@ main (int argc, char **argv) no_target_directory = true; break; @@ -309,7 +308,7 @@ diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c case PRESERVE_CONTEXT_OPTION: if ( ! selinux_enabled) { -@@ -415,6 +417,10 @@ main (int argc, char **argv) +@@ -435,6 +437,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } @@ -320,7 +319,7 @@ diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c x.preserve_security_context = true; use_default_selinux_context = false; break; -@@ -432,6 +432,7 @@ main (int argc, char **argv) +@@ -446,6 +452,7 @@ main (int argc, char **argv) break; } scontext = optarg; @@ -328,7 +327,7 @@ diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c use_default_selinux_context = false; break; case_GETOPT_HELP_CHAR; -@@ -825,8 +831,8 @@ Mandatory arguments to long options are +@@ -850,8 +857,8 @@ Mandatory arguments to long options are -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ @@ -339,10 +338,10 @@ diff -urp coreutils-6.10-orig/src/install.c coreutils-6.10/src/install.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); -diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c ---- coreutils-6.10-orig/src/ls.c 2008-01-11 11:34:22.000000000 +0100 -+++ coreutils-6.10/src/ls.c 2008-01-25 15:34:49.000000000 +0100 -@@ -134,7 +134,8 @@ enum filetype +diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c +--- coreutils-7.0.orig/src/ls.c 2009-01-28 17:18:16.705671000 +0100 ++++ coreutils-7.0/src/ls.c 2009-01-28 17:18:52.770914000 +0100 +@@ -139,7 +139,8 @@ enum filetype symbolic_link, sock, whiteout, @@ -352,7 +351,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c }; /* Display letters and indicators for each filetype. -@@ -177,8 +178,9 @@ struct fileinfo +@@ -182,8 +183,9 @@ struct fileinfo exists, otherwise false. */ bool linkok; @@ -364,7 +363,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c bool have_acl; }; -@@ -241,6 +242,7 @@ static void queue_directory (char const +@@ -246,6 +248,7 @@ static void queue_directory (char const static void sort_files (void); static void parse_ls_color (void); void usage (int status); @@ -372,7 +371,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c /* Initial size of hash table. Most hierarchies are likely to be shallower than this. */ -@@ -314,7 +316,7 @@ static struct pending *pending_dirs; +@@ -315,7 +318,7 @@ static struct pending *pending_dirs; static struct timespec current_time; @@ -381,7 +380,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c static char UNKNOWN_SECURITY_CONTEXT[] = "?"; /* Whether any of the files has an ACL. This affects the width of the -@@ -354,7 +356,9 @@ enum format +@@ -355,7 +358,9 @@ enum format one_per_line, /* -1 */ many_per_line, /* -C */ horizontal, /* -x */ @@ -392,7 +391,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c }; static enum format format; -@@ -731,6 +735,9 @@ enum +@@ -744,6 +749,9 @@ enum SHOW_CONTROL_CHARS_OPTION, SI_OPTION, SORT_OPTION, @@ -402,7 +401,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c TIME_OPTION, TIME_STYLE_OPTION }; -@@ -776,7 +783,9 @@ static struct option const long_options[ +@@ -789,7 +797,9 @@ static struct option const long_options[ {"time-style", required_argument, NULL, TIME_STYLE_OPTION}, {"color", optional_argument, NULL, COLOR_OPTION}, {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION}, @@ -413,7 +412,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c {"author", no_argument, NULL, AUTHOR_OPTION}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -@@ -786,12 +795,12 @@ static struct option const long_options[ +@@ -799,12 +809,12 @@ static struct option const long_options[ static char const *const format_args[] = { "verbose", "long", "commas", "horizontal", "across", @@ -428,7 +427,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c }; ARGMATCH_VERIFY (format_args, format_types); -@@ -1236,7 +1245,7 @@ main (int argc, char **argv) +@@ -1251,7 +1261,7 @@ main (int argc, char **argv) format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format @@ -437,7 +436,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c || print_block_size; format_needs_type = (! format_needs_stat && (recursive -@@ -1267,7 +1276,7 @@ main (int argc, char **argv) +@@ -1282,7 +1292,7 @@ main (int argc, char **argv) } else do @@ -446,7 +445,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c while (i < argc); if (cwd_n_used) -@@ -1429,7 +1438,7 @@ decode_switches (int argc, char **argv) +@@ -1445,7 +1455,7 @@ decode_switches (int argc, char **argv) ignore_mode = IGNORE_DEFAULT; ignore_patterns = NULL; hide_patterns = NULL; @@ -455,7 +454,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c /* FIXME: put this in a function. */ { -@@ -1811,13 +1820,27 @@ decode_switches (int argc, char **argv) +@@ -1827,13 +1837,27 @@ decode_switches (int argc, char **argv) break; case 'Z': @@ -484,7 +483,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c default: usage (LS_FAILURE); } -@@ -2517,8 +2540,10 @@ clear_files (void) +@@ -2547,8 +2571,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); @@ -497,7 +496,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c } cwd_n_used = 0; -@@ -2560,6 +2585,7 @@ gobble_file (char const *name, enum file +@@ -2590,6 +2616,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -505,7 +504,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c if (command_line_arg || format_needs_stat -@@ -2659,7 +2685,7 @@ gobble_file (char const *name, enum file +@@ -2689,7 +2716,7 @@ gobble_file (char const *name, enum file f->stat_ok = true; @@ -514,7 +513,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c { bool have_acl = false; int attr_len = (do_deref -@@ -2667,9 +2694,7 @@ gobble_file (char const *name, enum file +@@ -2708,9 +2735,7 @@ gobble_file (char const *name, enum file f->scontext = xstrdup ("unlabeled"); } @@ -525,7 +524,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c { f->scontext = UNKNOWN_SECURITY_CONTEXT; -@@ -2681,7 +2706,7 @@ gobble_file (char const *name, enum file +@@ -2722,7 +2747,7 @@ gobble_file (char const *name, enum file err = 0; } @@ -534,7 +533,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c { int n = file_has_acl (absolute_name, &f->stat); err = (n < 0); -@@ -3255,6 +3281,13 @@ print_current_files (void) +@@ -3297,6 +3322,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -548,7 +547,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c break; } } -@@ -3481,7 +3514,7 @@ print_long_format (const struct fileinfo +@@ -3482,7 +3514,7 @@ print_long_format (const struct fileinfo The latter is wrong when inode_number_width is zero. */ p += strlen (p); } @@ -557,7 +556,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c if (print_block_size) { char hbuf[LONGEST_HUMAN_READABLE + 1]; -@@ -3510,9 +3543,15 @@ print_long_format (const struct fileinfo +@@ -3511,9 +3543,15 @@ print_long_format (const struct fileinfo The latter is wrong when nlink_width is zero. */ p += strlen (p); @@ -574,7 +573,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c { DIRED_FPUTS (buf, stdout, p - buf); -@@ -3525,9 +3564,6 @@ print_long_format (const struct fileinfo +@@ -3526,9 +3564,6 @@ print_long_format (const struct fileinfo if (print_author) format_user (f->stat.st_author, author_width, f->stat_ok); @@ -584,7 +583,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c p = buf; } -@@ -3864,9 +3900,6 @@ print_file_name_and_frills (const struct +@@ -3867,9 +3902,6 @@ print_file_name_and_frills (const struct human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ST_NBLOCKSIZE, output_block_size)); @@ -594,7 +593,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, f->stat_ok, f->filetype, NULL); -@@ -4030,9 +4063,6 @@ length_of_file_name_and_frills (const st +@@ -4077,9 +4109,6 @@ length_of_file_name_and_frills (const st output_block_size)) : block_size_width); @@ -604,7 +603,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c quote_name (NULL, f->name, filename_quoting_options, &name_width); len += name_width; -@@ -4461,9 +4491,16 @@ Mandatory arguments to long options are +@@ -4510,9 +4539,16 @@ Mandatory arguments to long options are -w, --width=COLS assume screen width instead of current value\n\ -x list entries by lines instead of by columns\n\ -X sort alphabetically by entry extension\n\ @@ -622,7 +621,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_("\n\ -@@ -4487,3 +4524,67 @@ Exit status is 0 if OK, 1 if minor probl +@@ -4541,3 +4577,67 @@ Exit status:\n\ } exit (status); } @@ -690,10 +689,10 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c + print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); + } +} -diff -urp coreutils-6.10-orig/src/mkdir.c coreutils-6.10/src/mkdir.c ---- coreutils-6.10-orig/src/mkdir.c 2008-01-05 23:58:25.000000000 +0100 -+++ coreutils-6.10/src/mkdir.c 2008-01-25 16:35:14.000000000 +0100 -@@ -41,6 +41,7 @@ char *program_name; +diff -urp coreutils-7.0.orig/src/mkdir.c coreutils-7.0/src/mkdir.c +--- coreutils-7.0.orig/src/mkdir.c 2008-08-24 22:58:15.000000000 +0200 ++++ coreutils-7.0/src/mkdir.c 2009-01-28 17:18:52.771914007 +0100 +@@ -39,6 +39,7 @@ static struct option const longopts[] = { {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, @@ -701,10 +700,10 @@ diff -urp coreutils-6.10-orig/src/mkdir.c coreutils-6.10/src/mkdir.c {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, -diff -urp coreutils-6.10-orig/src/mknod.c coreutils-6.10/src/mknod.c ---- coreutils-6.10-orig/src/mknod.c 2008-01-05 23:58:25.000000000 +0100 -+++ coreutils-6.10/src/mknod.c 2008-01-25 17:01:11.000000000 +0100 -@@ -38,7 +38,7 @@ char *program_name; +diff -urp coreutils-7.0.orig/src/mknod.c coreutils-7.0/src/mknod.c +--- coreutils-7.0.orig/src/mknod.c 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/src/mknod.c 2009-01-28 17:18:52.772914014 +0100 +@@ -35,7 +35,7 @@ static struct option const longopts[] = { @@ -713,21 +712,21 @@ diff -urp coreutils-6.10-orig/src/mknod.c coreutils-6.10/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urp coreutils-6.10-orig/src/mv.c coreutils-6.10/src/mv.c ---- coreutils-6.10-orig/src/mv.c 2008-01-05 23:59:11.000000000 +0100 -+++ coreutils-6.10/src/mv.c 2008-01-25 17:11:50.000000000 +0100 -@@ -137,6 +137,7 @@ cp_option_init (struct cp_options *x) +diff -urp coreutils-7.0.orig/src/mv.c coreutils-7.0/src/mv.c +--- coreutils-7.0.orig/src/mv.c 2009-01-28 17:18:16.752671000 +0100 ++++ coreutils-7.0/src/mv.c 2009-01-28 17:18:52.773914020 +0100 +@@ -138,6 +138,7 @@ cp_option_init (struct cp_options *x) x->preserve_mode = true; x->preserve_timestamps = true; x->preserve_security_context = selinux_enabled; + x->set_security_context = false; x->require_preserve = false; /* FIXME: maybe make this an option */ x->require_preserve_context = false; - x->recursive = true; -diff -urNp coreutils-6.12-orig/src/runcon.c coreutils-6.12/src/runcon.c ---- coreutils-6.12-orig/src/runcon.c 2008-05-26 12:10:20.000000000 +0200 -+++ coreutils-6.12/src/runcon.c 2008-10-21 15:57:30.000000000 +0200 -@@ -88,7 +88,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ + x->preserve_xattr = true; +diff -urp coreutils-7.0.orig/src/runcon.c coreutils-7.0/src/runcon.c +--- coreutils-7.0.orig/src/runcon.c 2008-08-24 22:30:10.000000000 +0200 ++++ coreutils-7.0/src/runcon.c 2009-01-28 17:18:52.774914027 +0100 +@@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ "), program_name, program_name); fputs (_("\ @@ -736,10 +735,10 @@ diff -urNp coreutils-6.12-orig/src/runcon.c coreutils-6.12/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c ---- coreutils-6.10-orig/src/stat.c 2008-01-05 23:59:11.000000000 +0100 -+++ coreutils-6.10/src/stat.c 2008-01-25 16:50:24.000000000 +0100 -@@ -831,7 +831,7 @@ print_it (char const *format, char const +diff -urp coreutils-7.0.orig/src/stat.c coreutils-7.0/src/stat.c +--- coreutils-7.0.orig/src/stat.c 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/src/stat.c 2009-01-28 17:18:52.775914034 +0100 +@@ -823,7 +823,7 @@ print_it (char const *format, char const /* Stat the file system and print what we find. */ static bool @@ -748,7 +747,7 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c { STRUCT_STATVFS statfsbuf; -@@ -843,15 +843,31 @@ do_statfs (char const *filename, bool te +@@ -835,15 +835,31 @@ do_statfs (char const *filename, bool te } if (format == NULL) @@ -787,7 +786,7 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c print_it (format, filename, print_statfs, &statfsbuf); return true; -@@ -859,7 +875,7 @@ do_statfs (char const *filename, bool te +@@ -851,7 +867,7 @@ do_statfs (char const *filename, bool te /* stat the file and print what we find */ static bool @@ -796,7 +795,7 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c { struct stat statbuf; -@@ -872,9 +888,12 @@ do_stat (char const *filename, bool ters +@@ -864,9 +880,12 @@ do_stat (char const *filename, bool ters if (format == NULL) { if (terse) @@ -812,7 +811,7 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c else { /* Temporary hack to match original output until conditional -@@ -891,12 +910,22 @@ do_stat (char const *filename, bool ters +@@ -883,12 +902,22 @@ do_stat (char const *filename, bool ters } else { @@ -841,7 +840,7 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c } } } -@@ -917,6 +946,7 @@ usage (int status) +@@ -909,6 +938,7 @@ usage (int status) Display file or file system status.\n\ \n\ -L, --dereference follow links\n\ @@ -849,7 +848,7 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c -f, --file-system display file system status instead of file status\n\ "), stdout); fputs (_("\ -@@ -1001,6 +1031,7 @@ main (int argc, char *argv[]) +@@ -993,6 +1023,7 @@ main (int argc, char *argv[]) int i; bool fs = false; bool terse = false; @@ -857,7 +856,7 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c char *format = NULL; bool ok = true; -@@ -1040,13 +1071,13 @@ main (int argc, char *argv[]) +@@ -1032,13 +1063,13 @@ main (int argc, char *argv[]) terse = true; break; @@ -878,7 +877,7 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c break; case_GETOPT_HELP_CHAR; -@@ -1062,8 +1097,8 @@ main (int argc, char *argv[]) +@@ -1058,8 +1089,8 @@ main (int argc, char *argv[]) for (i = optind; i < argc; i++) ok &= (fs @@ -889,10 +888,10 @@ diff -urp coreutils-6.10-orig/src/stat.c coreutils-6.10/src/stat.c exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } -diff -urp coreutils-6.10-orig/tests/misc/selinux coreutils-6.10/tests/misc/selinux ---- coreutils-6.10-orig/tests/misc/selinux 2008-01-11 11:34:22.000000000 +0100 -+++ coreutils-6.10/tests/misc/selinux 2008-01-25 18:17:59.000000000 +0100 -@@ -32,12 +32,10 @@ chcon $ctx f d p 2>/dev/null || { +diff -urp coreutils-7.0.orig/tests/misc/selinux coreutils-7.0/tests/misc/selinux +--- coreutils-7.0.orig/tests/misc/selinux 2008-09-27 19:28:54.000000000 +0200 ++++ coreutils-7.0/tests/misc/selinux 2009-01-28 17:18:52.776914041 +0100 +@@ -30,12 +30,10 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. for i in d f p; do @@ -900,9 +899,9 @@ diff -urp coreutils-6.10-orig/tests/misc/selinux coreutils-6.10/tests/misc/selin + c=`ls -dogZ $i|cut -d' ' -f5`; test x$c = x$ctx || fail=1 c=`stat --printf %C $i`; test x$c = x$ctx || fail=1 done - + -# ensure that ls -l output includes the "+". -c=`ls -l f|cut -c11`; test "$c" = + || fail=1 - + # Copy each to a new directory and ensure that context is preserved. cp -r --preserve=all d f p s1 || fail=1 diff --git a/coreutils.spec b/coreutils.spec index 33dc730..4e7c89f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.0 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -21,6 +21,8 @@ Source203: coreutils-runuser-l.pamd Patch1: coreutils-446294-lsexitstatuses.patch Patch2: coreutils-7.0-dftotal.patch Patch3: coreutils-7.0-expr-removebignumoptions.patch +Patch4: coreutils-7.0-cp-mv-n.patch +Patch5: coreutils-7.0-xattr.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -64,6 +66,7 @@ BuildRequires: autoconf >= 2.58 BuildRequires: automake >= 1.10.1 %{?!nopam:BuildRequires: pam-devel} BuildRequires: libcap-devel >= 2.0.6 +Requires: libattr-devel Requires(post): libselinux >= 1.25.6-1 Requires: libattr @@ -106,6 +109,8 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch1 -p1 -b .lsexit %patch2 -p1 -b .dftotal %patch3 -p1 -b .bignum +%patch4 -p1 -b .cpmvn +%patch5 -p1 -b .xattr # Our patches %patch100 -p1 -b .configure @@ -137,6 +142,8 @@ the old GNU fileutils, sh-utils, and textutils packages. chmod a+x tests/misc/sort-mb-tests chmod a+x tests/misc/id-context +chmod a+x tests/mv/mv-n +chmod a+x tests/misc/xattr sed -i 's/1.10a/1.10.1/' configure.ac @@ -320,6 +327,10 @@ fi /sbin/runuser %changelog +* Wed Jan 28 2009 Kamil Dudka - 7.0-6 +- cp/mv: add --no-clobber (-n) option to not overwrite target +- cp/mv: add xattr support (#202823) + * Thu Dec 04 2008 Ondrej Vasik - 7.0-5 - fix info documentation for expr command as well(#474434) From f88f91b802d5436df59268da647efaa717dbfe45 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 28 Jan 2009 18:01:37 +0000 Subject: [PATCH 012/523] added BuildRequires for libattr-devel and attr --- coreutils.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 4e7c89f..a83beee 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.0 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -66,7 +66,8 @@ BuildRequires: autoconf >= 2.58 BuildRequires: automake >= 1.10.1 %{?!nopam:BuildRequires: pam-devel} BuildRequires: libcap-devel >= 2.0.6 -Requires: libattr-devel +BuildRequires: libattr-devel +BuildRequires: attr Requires(post): libselinux >= 1.25.6-1 Requires: libattr @@ -327,6 +328,9 @@ fi /sbin/runuser %changelog +* Wed Jan 28 2009 Kamil Dudka - 7.0-7 +- added BuildRequires for libattr-devel and attr + * Wed Jan 28 2009 Kamil Dudka - 7.0-6 - cp/mv: add --no-clobber (-n) option to not overwrite target - cp/mv: add xattr support (#202823) From eded8d92cbae987b3829cfe20ffeee4af1481152 Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Tue, 24 Feb 2009 09:12:38 +0000 Subject: [PATCH 013/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index a83beee..7cb0fa8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.0 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -328,6 +328,9 @@ fi /sbin/runuser %changelog +* Tue Feb 24 2009 Fedora Release Engineering - 7.0-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + * Wed Jan 28 2009 Kamil Dudka - 7.0-7 - added BuildRequires for libattr-devel and attr From c4b1fe4c8a42d9f2b8862f767f84047ec2cb70d5 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 24 Feb 2009 11:53:38 +0000 Subject: [PATCH 014/523] New upstream release 7.1, removed applied patches, amended patches and LS_COLORS files --- .cvsignore | 2 +- coreutils-446294-lsexitstatuses.patch | 83 -- coreutils-463883-chcon-changes.patch | 46 - coreutils-5.2.1-runuser.patch | 8 +- coreutils-6.10-configuration.patch | 19 - coreutils-6.10-longoptions.patch | 13 - coreutils-6.10-manpages.patch | 12 - coreutils-6.11-sparc-shafix.patch | 22 - coreutils-7.0-cp-mv-n.patch | 322 ------ coreutils-7.0-dftotal.patch | 115 -- coreutils-7.0-expr-removebignumoptions.patch | 1012 ------------------ coreutils-7.0-xattr.patch | 792 -------------- coreutils-DIR_COLORS | 61 +- coreutils-DIR_COLORS.256color | 55 +- coreutils-DIR_COLORS.xterm | 35 +- coreutils-i18n.patch | 11 +- coreutils-pam.patch | 8 +- coreutils-selinux.patch | 284 ++--- coreutils-selinuxmanpages.patch | 33 - coreutils.spec | 36 +- sources | 2 +- 21 files changed, 205 insertions(+), 2766 deletions(-) delete mode 100644 coreutils-446294-lsexitstatuses.patch delete mode 100644 coreutils-463883-chcon-changes.patch delete mode 100644 coreutils-6.10-longoptions.patch delete mode 100644 coreutils-6.11-sparc-shafix.patch delete mode 100644 coreutils-7.0-cp-mv-n.patch delete mode 100644 coreutils-7.0-dftotal.patch delete mode 100644 coreutils-7.0-expr-removebignumoptions.patch delete mode 100644 coreutils-7.0-xattr.patch diff --git a/.cvsignore b/.cvsignore index 57a1758..d2049a4 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-7.0.tar.lzma +coreutils-7.1.tar.gz diff --git a/coreutils-446294-lsexitstatuses.patch b/coreutils-446294-lsexitstatuses.patch deleted file mode 100644 index 50b692c..0000000 --- a/coreutils-446294-lsexitstatuses.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 50654566c77d1335870206f657507a2d1c23f628 Mon Sep 17 00:00:00 2001 -From: =?utf-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= redhat.com> -Date: Thu, 9 Oct 2008 10:56:54 +0200 -Subject: [PATCH] doc: ls: clarify exit status description - -* src/ls.c (exit_status): Clarify comments. -(usage): Clarify exit status description in --help output. -* doc/coreutils.texi (ls invocation): Clarify exit status documentation -Reported by Greg Metcalfe in . ---- - THANKS | 1 + - doc/coreutils.texi | 7 +++++-- - src/ls.c | 16 ++++++++++++---- - 3 files changed, 18 insertions(+), 6 deletions(-) - -diff --git a/THANKS b/THANKS -index e6e48b3..d06f755 100644 ---- a/THANKS -+++ b/THANKS -@@ -201,6 +201,7 @@ Guochun Shi gshi@ncsa.uiuc.edu - GOTO Masanori gotom@debian.or.jp - Greg Louis glouis@dynamicro.on.ca - Greg McGary gkm@gnu.org -+Greg Metcalfe metcalfegreg@qwest.net - Greg Schafer gschafer@zip.com.au - Greg Troxel gdt@bbn.com - Greg Wooledge gawooledge@sherwin.com -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index a0d2202..b7e044d 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -6073,8 +6073,11 @@ ls invocation - - @display - 0 success --1 minor problems (e.g., a subdirectory was not found) --2 serious trouble (e.g., memory exhausted) -+1 minor problems (e.g., failure to access a file or directory not -+ specified as a command line argument. This happens when listing a -+ directory in which entries are actively being removed or renamed.) -+2 serious trouble (e.g., memory exhausted, invalid option or failure -+ to access file or directory specified as a command line argument) - @end display - - Also see @ref{Common options}. -diff --git a/src/ls.c b/src/ls.c -index e107162..108d669 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -715,11 +715,14 @@ static int exit_status; - /* Exit statuses. */ - enum - { -- /* "ls" had a minor problem (e.g., it could not stat a directory -- entry). */ -+ /* "ls" had a minor problem. E.g., while processing a directory, -+ ls obtained the name of an entry via readdir, yet was later -+ unable to stat that name. This happens when listing a directory -+ in which entries are actively being removed or renamed. */ - LS_MINOR_PROBLEM = 1, - -- /* "ls" had more serious trouble. */ -+ /* "ls" had more serious trouble (e.g., memory exhausted, invalid -+ option or failure to stat a command line argument. */ - LS_FAILURE = 2 - }; - -@@ -4527,7 +4530,12 @@ colors, and can be set easily by the dircolors command.\n\ - "), stdout); - fputs (_("\ - \n\ --Exit status is 0 if OK, 1 if minor problems, 2 if serious trouble.\n\ -+Exit status:\n\ -+0 if OK,\n\ -+1 if minor problems (e.g., failure to access a file or directory not\n\ -+ specified as a command line argument\n\ -+2 if serious trouble (e.g., memory exhausted, invalid option or failure\n\ -+ to access a file or directory specified as a command line argument).\n\ - "), stdout); - emit_bug_reporting_address (); - } --- -1.6.0.2.514.g23abd3 diff --git a/coreutils-463883-chcon-changes.patch b/coreutils-463883-chcon-changes.patch deleted file mode 100644 index b1cf9f5..0000000 --- a/coreutils-463883-chcon-changes.patch +++ /dev/null @@ -1,46 +0,0 @@ -diff -urNp coreutils-6.12-orig/src/chcon.c coreutils-6.12/src/chcon.c ---- coreutils-6.12-orig/src/chcon.c 2008-10-08 14:45:59.000000000 +0200 -+++ coreutils-6.12/src/chcon.c 2008-10-08 16:28:36.000000000 +0200 -@@ -35,25 +35,6 @@ - proper_name ("Russell Coker"), \ - proper_name ("Jim Meyering") - --enum Change_status --{ -- CH_NOT_APPLIED, -- CH_SUCCEEDED, -- CH_FAILED, -- CH_NO_CHANGE_REQUESTED --}; -- --enum Verbosity --{ -- /* Print a message for each file that is processed. */ -- V_high, -- -- /* Print a message for each file whose attributes we change. */ -- V_changes_only, -- -- /* Do not be verbose. This is the default. */ -- V_off --}; - - /* If nonzero, and the systems has support for it, change the context - of symbolic links rather than any files they point to. */ -@@ -374,7 +355,6 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ - Change the SELinux security context of each FILE to CONTEXT.\n\ - With --reference, change the security context of each FILE to that of RFILE.\n\ - \n\ -- -c, --changes like verbose but report only when a change is made\n\ - -h, --no-dereference affect symbolic links instead of any referenced file\n\ - "), stdout); - fputs (_("\ -@@ -435,7 +415,7 @@ main (int argc, char **argv) - - atexit (close_stdout); - -- while ((optc = getopt_long (argc, argv, "HLPRchvu:r:t:l:", long_options, NULL)) -+ while ((optc = getopt_long (argc, argv, "HLPRhvu:r:t:l:", long_options, NULL)) - != -1) - { - switch (optc) diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index 2e74d74..6ff3085 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -107,15 +107,15 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c # include @@ -149,6 +155,10 @@ #ifndef USE_PAM - char *crypt (); + char *crypt (char const *key, char const *salt); #endif +#ifndef CHECKPASSWD +#define CHECKPASSWD 1 +#endif + - char *getusershell (); - void endusershell (); - void setusershell (); + char *getusershell (void); + void endusershell (void); + void setusershell (void); @@ -156,7 +166,11 @@ void setusershell (); extern char **environ; diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 97a7438..0818bd2 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,22 +1,3 @@ -diff -urNp coreutils-7.0-orig/tests/Makefile.am coreutils-7.0/tests/Makefile.am ---- coreutils-7.0-orig/tests/Makefile.am 2008-11-11 16:37:08.000000000 +0100 -+++ coreutils-7.0/tests/Makefile.am 2008-11-11 16:39:55.000000000 +0100 -@@ -217,7 +217,6 @@ TESTS = \ - misc/tee-dash \ - misc/test-diag \ - misc/timeout \ -- misc/timeout-parameters \ - misc/tr \ - misc/truncate-dangling-symlink \ - misc/truncate-dir-fail \ -@@ -285,7 +284,6 @@ TESTS = \ - dd/skip-seek \ - dd/skip-seek2 \ - dd/unblock-sync \ -- df/total \ - df/total-awk \ - du/2g \ - du/8gb \ diff -urN coreutils-6.12-orig/tests/misc/cut coreutils-6.12/tests/misc/cut --- coreutils-6.12-orig/tests/misc/cut 2008-05-17 08:41:11.000000000 +0200 +++ coreutils-6.12/tests/misc/cut 2008-06-02 11:13:08.000000000 +0200 diff --git a/coreutils-6.10-longoptions.patch b/coreutils-6.10-longoptions.patch deleted file mode 100644 index ed5a2db..0000000 --- a/coreutils-6.10-longoptions.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -urp coreutils-6.10-orig/lib/long-options.c coreutils-6.10/lib/long-options.c ---- coreutils-6.10-orig/lib/long-options.c 2007-10-17 15:47:26.000000000 +0200 -+++ coreutils-6.10/lib/long-options.c 2008-01-31 14:28:01.000000000 +0100 -@@ -57,8 +57,7 @@ parse_long_options (int argc, - /* Don't print an error message for unrecognized options. */ - opterr = 0; - -- if (argc == 2 -- && (c = getopt_long (argc, argv, "+", long_options, NULL)) != -1) -+ while ((c = getopt_long (argc, argv, "+", long_options, NULL)) != -1) - { - switch (c) - { diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index 066114e..792ce42 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -11,15 +11,3 @@ diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c fputs (_("\ \n\ The following three options are useful only when verifying checksums:\n\ -diff -urNp coreutils-6.12-orig/src/sort.c coreutils-6.12/src/sort.c ---- coreutils-6.12-orig/src/sort.c 2008-10-21 16:04:50.000000000 +0200 -+++ coreutils-6.12/src/sort.c 2008-10-22 10:52:30.000000000 +0200 -@@ -412,7 +413,7 @@ With no FILE, or when FILE is -, read st - \n\ - *** WARNING ***\n\ - The locale specified by the environment affects sort order.\n\ --Set LC_ALL=C to get the traditional sort order that uses\n\ -+Set LC_ALL=C (by \"export LC_LL=C\") to get the traditional sort order that uses\n\ - native byte values.\n\ - "), stdout ); - emit_bug_reporting_address (); diff --git a/coreutils-6.11-sparc-shafix.patch b/coreutils-6.11-sparc-shafix.patch deleted file mode 100644 index e24b48b..0000000 --- a/coreutils-6.11-sparc-shafix.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff -up coreutils-6.11/src/Makefile.am.sparc coreutils-6.11/src/Makefile.am ---- coreutils-6.11/src/Makefile.am.sparc 2008-04-19 16:34:23.000000000 -0500 -+++ coreutils-6.11/src/Makefile.am 2008-05-29 18:40:36.000000000 -0500 -@@ -101,6 +101,7 @@ shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) - shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME) - tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) - vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) -+tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) - - ## If necessary, add -lm to resolve use of pow in lib/strtod.c. - sort_LDADD = $(LDADD) $(POW_LIB) $(LIB_GETHRXTIME) -diff -up coreutils-6.11/src/Makefile.in.sparc coreutils-6.11/src/Makefile.in ---- coreutils-6.11/src/Makefile.in.sparc 2008-04-19 16:50:10.000000000 -0500 -+++ coreutils-6.11/src/Makefile.in 2008-05-29 18:40:36.000000000 -0500 -@@ -1251,6 +1251,7 @@ shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME) - vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) \ - $(LIB_ACL) - sort_LDADD = $(LDADD) $(POW_LIB) $(LIB_GETHRXTIME) -+tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) - - # for get_date and gettime - date_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) diff --git a/coreutils-7.0-cp-mv-n.patch b/coreutils-7.0-cp-mv-n.patch deleted file mode 100644 index c245b0f..0000000 --- a/coreutils-7.0-cp-mv-n.patch +++ /dev/null @@ -1,322 +0,0 @@ -diff -ruNp coreutils-7.0.orig/doc/coreutils.texi coreutils-7.0/doc/coreutils.texi ---- coreutils-7.0.orig/doc/coreutils.texi 2009-01-28 15:28:14.724301000 +0100 -+++ coreutils-7.0/doc/coreutils.texi 2009-01-28 16:42:36.319138655 +0100 -@@ -7295,6 +7295,9 @@ description of @option{--remove-destinat - This option is independent of the @option{--interactive} or - @option{-i} option: neither cancels the effect of the other. - -+This option is redundant if the @option{--no-clobber} or @option{-n} option is -+used. -+ - @item -H - @opindex -H - If a command line argument specifies a symbolic link, then copy the -@@ -7307,7 +7310,8 @@ via recursive traversal. - @opindex -i - @opindex --interactive - When copying a file other than a directory, prompt whether to --overwrite an existing destination file. -+overwrite an existing destination file. The @option{-i} option overrides -+a previous @option{-n} option. - - @item -l - @itemx --link -@@ -7321,6 +7325,14 @@ Make hard links instead of copies of non - @opindex --dereference - Follow symbolic links when copying from them. - -+@item -n -+@itemx --no-clobber -+@opindex -n -+@opindex --no-clobber -+Do not overwrite an existing file. The @option{-n} option overrides a previous -+@option{-i} option. This option is mutually exclusive with @option{-b} or -+@option{--backup} option. -+ - @item -P - @itemx --no-dereference - @opindex -P -@@ -8076,6 +8088,11 @@ The program accepts the following option - @opindex --force - @cindex prompts, omitting - Do not prompt the user before removing a destination file. -+@macro mvOptsIfn -+If you specify more than one of the @option{-i}, @option{-f}, @option{-n} -+options, only the final one takes effect. -+@end macro -+@mvOptsIfn - - @item -i - @itemx --interactive -@@ -8085,6 +8102,16 @@ Do not prompt the user before removing a - Prompt whether to overwrite each existing destination file, regardless - of its permissions. - If the response is not affirmative, the file is skipped. -+@mvOptsIfn -+ -+@item -n -+@itemx --no-clobber -+@opindex -n -+@opindex --no-clobber -+@cindex prompts, omitting -+Do not overwrite an existing file. -+@mvOptsIfn -+This option is mutually exclusive with @option{-b} or @option{--backup} option. - - @itemx @w{@kbd{--reply}=@var{how}} - @opindex --reply -diff -ruNp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c ---- coreutils-7.0.orig/src/cp.c 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/src/cp.c 2009-01-28 16:43:08.501394935 +0100 -@@ -1,5 +1,5 @@ - /* cp.c -- file copying (main routines) -- Copyright (C) 89, 90, 91, 1995-2008 Free Software Foundation, Inc. -+ Copyright (C) 89, 90, 91, 1995-2009 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 -@@ -129,6 +129,7 @@ static struct option const long_opts[] = - {"force", no_argument, NULL, 'f'}, - {"interactive", no_argument, NULL, 'i'}, - {"link", no_argument, NULL, 'l'}, -+ {"no-clobber", no_argument, NULL, 'n'}, - {"no-dereference", no_argument, NULL, 'P'}, - {"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION}, - {"no-target-directory", no_argument, NULL, 'T'}, -@@ -182,8 +183,10 @@ Mandatory arguments to long options are - "), stdout); - fputs (_("\ - -f, --force if an existing destination file cannot be\n\ -- opened, remove it and try again\n\ -- -i, --interactive prompt before overwrite\n\ -+ opened, remove it and try again (redundant if\n\ -+ the -n option is used)\n\ -+ -i, --interactive prompt before overwrite (overrides a previous -n\n\ -+ option)\n\ - -H follow command-line symbolic links in SOURCE\n\ - "), stdout); - fputs (_("\ -@@ -191,6 +194,8 @@ Mandatory arguments to long options are - -L, --dereference always follow symbolic links in SOURCE\n\ - "), stdout); - fputs (_("\ -+ -n, --no-clobber do not overwrite an existing file (overrides\n\ -+ a previous -i option)\n\ - -P, --no-dereference never follow symbolic links in SOURCE\n\ - "), stdout); - fputs (_("\ -@@ -909,7 +914,7 @@ main (int argc, char **argv) - we'll actually use backup_suffix_string. */ - backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); - -- while ((c = getopt_long (argc, argv, "abdfHilLprst:uvxPRS:T", -+ while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T", - long_opts, NULL)) - != -1) - { -@@ -965,6 +970,10 @@ main (int argc, char **argv) - x.dereference = DEREF_ALWAYS; - break; - -+ case 'n': -+ x.interactive = I_ALWAYS_NO; -+ break; -+ - case 'P': - x.dereference = DEREF_NEVER; - break; -@@ -1072,6 +1081,13 @@ main (int argc, char **argv) - usage (EXIT_FAILURE); - } - -+ if (make_backups && x.interactive == I_ALWAYS_NO) -+ { -+ error (0, 0, -+ _("options --backup and --no-clobber are mutually exclusive")); -+ usage (EXIT_FAILURE); -+ } -+ - if (backup_suffix_string) - simple_backup_suffix = xstrdup (backup_suffix_string); - -diff -ruNp coreutils-7.0.orig/src/mv.c coreutils-7.0/src/mv.c ---- coreutils-7.0.orig/src/mv.c 2008-08-24 22:30:10.000000000 +0200 -+++ coreutils-7.0/src/mv.c 2009-01-28 16:42:36.906143329 +0100 -@@ -1,5 +1,5 @@ - /* mv -- move or rename files -- Copyright (C) 86, 89, 90, 91, 1995-2008 Free Software Foundation, Inc. -+ Copyright (C) 86, 89, 90, 91, 1995-2009 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 -@@ -76,6 +76,7 @@ static struct option const long_options[ - {"backup", optional_argument, NULL, 'b'}, - {"force", no_argument, NULL, 'f'}, - {"interactive", no_argument, NULL, 'i'}, -+ {"no-clobber", no_argument, NULL, 'n'}, - {"no-target-directory", no_argument, NULL, 'T'}, - {"reply", required_argument, NULL, REPLY_OPTION}, /* Deprecated 2005-07-03, - remove in 2008. */ -@@ -312,6 +313,8 @@ Mandatory arguments to long options are - -b like --backup but does not accept an argument\n\ - -f, --force do not prompt before overwriting\n\ - -i, --interactive prompt before overwrite\n\ -+ -n, --no-clobber do not overwrite an existing file\n\ -+If you specify more than one of -i, -f, -n, only the final one takes effect.\n\ - "), stdout); - fputs (_("\ - --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\ -@@ -374,7 +377,7 @@ main (int argc, char **argv) - we'll actually use backup_suffix_string. */ - backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); - -- while ((c = getopt_long (argc, argv, "bfit:uvS:T", long_options, NULL)) -+ while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL)) - != -1) - { - switch (c) -@@ -396,6 +399,9 @@ main (int argc, char **argv) - error (0, 0, - _("the --reply option is deprecated; use -i or -f instead")); - break; -+ case 'n': -+ x.interactive = I_ALWAYS_NO; -+ break; - case STRIP_TRAILING_SLASHES_OPTION: - remove_trailing_slashes = true; - break; -@@ -468,6 +474,13 @@ main (int argc, char **argv) - quote (file[n_files - 1])); - } - -+ if (make_backups && x.interactive == I_ALWAYS_NO) -+ { -+ error (0, 0, -+ _("options --backup and --no-clobber are mutually exclusive")); -+ usage (EXIT_FAILURE); -+ } -+ - if (backup_suffix_string) - simple_backup_suffix = xstrdup (backup_suffix_string); - -diff -ruNp coreutils-7.0.orig/tests/cp/cp-i coreutils-7.0/tests/cp/cp-i ---- coreutils-7.0.orig/tests/cp/cp-i 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/tests/cp/cp-i 2009-01-28 16:42:37.092144811 +0100 -@@ -31,4 +31,40 @@ fail=0 - # coreutils 6.2 cp would neglect to prompt in this case. - echo n | cp -iR a b 2>/dev/null || fail=1 - -+# test miscellaneous combinations of -f -i -n parameters -+touch c d || framework_failure -+echo "\`c' -> \`d'" > out_copy -+> out_empty -+ -+# ask for overwrite, answer no -+echo n | cp -vi c d 2>/dev/null > out1 || fail=1 -+compare out1 out_empty || fail=1 -+ -+# ask for overwrite, answer yes -+echo y | cp -vi c d 2>/dev/null > out2 || fail=1 -+compare out2 out_copy || fail=1 -+ -+# -i wins over -n -+echo y | cp -vni c d 2>/dev/null > out3 || fail=1 -+compare out3 out_copy || fail=1 -+ -+# -n wins over -i -+echo y | cp -vin c d 2>/dev/null > out4 || fail=1 -+compare out4 out_empty || fail=1 -+ -+# ask for overwrite, answer yes -+echo y | cp -vfi c d 2>/dev/null > out5 || fail=1 -+compare out5 out_copy || fail=1 -+ -+# do not ask, prevent from overwrite -+echo n | cp -vfn c d 2>/dev/null > out6 || fail=1 -+compare out6 out_empty || fail=1 -+ -+# do not ask, prevent from overwrite -+echo n | cp -vnf c d 2>/dev/null > out7 || fail=1 -+compare out7 out_empty || fail=1 -+ -+# options --backup and --no-clobber are mutually exclusive -+cp -bn c d 2>/dev/null && fail=1 -+ - Exit $fail -diff -ruNp coreutils-7.0.orig/tests/Makefile.am coreutils-7.0/tests/Makefile.am ---- coreutils-7.0.orig/tests/Makefile.am 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/tests/Makefile.am 2009-01-28 16:42:37.596148824 +0100 -@@ -374,6 +374,7 @@ TESTS = \ - mv/into-self-3 \ - mv/into-self-4 \ - mv/leak-fd \ -+ mv/mv-n \ - mv/mv-special-1 \ - mv/no-target-dir \ - mv/part-fail \ -diff -ruNp coreutils-7.0.orig/tests/mv/mv-n coreutils-7.0/tests/mv/mv-n ---- coreutils-7.0.orig/tests/mv/mv-n 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-7.0/tests/mv/mv-n 2009-01-28 16:42:37.596148824 +0100 -@@ -0,0 +1,62 @@ -+#!/bin/sh -+# Test whether mv -n works as documented (not overwrite target). -+ -+# Copyright (C) 2006-2008 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 . -+ -+if test "$VERBOSE" = yes; then -+ set -x -+ mv --version -+fi -+ -+. $srcdir/test-lib.sh -+ -+fail=0 -+ -+# test miscellaneous combinations of -f -i -n parameters -+touch a b || framework_failure -+echo "\`a' -> \`b'" > out_move -+> out_empty -+ -+# ask for overwrite, answer no -+touch a b || framework_failure -+echo n | mv -vi a b 2>/dev/null > out1 || fail=1 -+compare out1 out_empty || fail=1 -+ -+# ask for overwrite, answer yes -+touch a b || framework_failure -+echo y | mv -vi a b 2>/dev/null > out2 || fail=1 -+compare out2 out_move || fail=1 -+ -+# -n wins (as the last option) -+touch a b || framework_failure -+echo y | mv -vin a b 2>/dev/null > out3 || fail=1 -+compare out3 out_empty || fail=1 -+ -+# -n wins (as the last option) -+touch a b || framework_failure -+echo y | mv -vfn a b 2>/dev/null > out4 || fail=1 -+compare out4 out_empty || fail=1 -+ -+# -n wins (as the last option) -+touch a b || framework_failure -+echo y | mv -vifn a b 2>/dev/null > out5 || fail=1 -+compare out5 out_empty || fail=1 -+ -+# options --backup and --no-clobber are mutually exclusive -+touch a || framework_failure -+mv -bn a b 2>/dev/null && fail=1 -+ -+Exit $fail diff --git a/coreutils-7.0-dftotal.patch b/coreutils-7.0-dftotal.patch deleted file mode 100644 index 950dee8..0000000 --- a/coreutils-7.0-dftotal.patch +++ /dev/null @@ -1,115 +0,0 @@ -diff -urNp coreutils-7.0-orig/tests/df/total-awk coreutils-7.0/tests/df/total-awk ---- coreutils-7.0-orig/tests/df/total-awk 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/tests/df/total-awk 2008-11-11 16:54:49.000000000 +0100 -@@ -18,7 +18,7 @@ - - if test "$VERBOSE" = yes; then - set -x -- ls --version -+ df --version - fi - - . $srcdir/test-lib.sh -@@ -24,6 +24,8 @@ - - . $srcdir/test-lib.sh - -+ df || skip_test_ "df fails" -+ - fail=0 - - # Don't let a different umask perturb the results. -@@ -23,58 +25,44 @@ fi - - . $srcdir/test-lib.sh - --fail=0 -- --# Don't let a different umask perturb the results. --umask 22 -- --echo ' --BEGIN { -- total = 0 -- used = 0 -- available = 0 --} --{ -- if (NR==1 || $0==$1 || $0~/^total +(-?[0-9]+|-) +(-?[0-9]+|-) +(-?[0-9]+|-) +-?[0-9]+%$/) -- next -- if ($1~/^[0-9]/) -- { -- total += $1 -- used += $2 -- available += $3 -- } -- else -- { -- total += $2 -- used += $3 -- available += $4 -- } --} --END { -- print total -- print used -- print available --} --' > compute_sum.awk || fail=1 -- --echo ' --/^total +(-?[0-9]+|-) +(-?[0-9]+|-) +(-?[0-9]+|-) +-?[0-9]+%$/ { -- print $2; -- print $3; -- print $4 --} --' > parse_total.awk || fail=1 -+cat <<\EOF > check-df || framework_failure -+my ($total, $used, $avail) = (0, 0, 0); -+while (<>) -+ { -+ $. == 1 -+ and next; # skip first (header) line -+ # Recognize df output lines like these: -+ # /dev/sdc1 0 0 0 - /c -+ # tmpfs 1536000 12965 1523035 1% /tmp -+ # total 5285932 787409 4498523 15% -+ /^(.*?) +(-?\d+|-) +(-?\d+|-) +(-?\d+|-) +(?:- |[0-9]+%)(.*)$/ -+ or die "$0: invalid input line\n: $_"; -+ if ($1 eq 'total' && $5 eq '') -+ { -+ $total == $2 or die "$total != $2"; -+ $used == $3 or die "$used != $3"; -+ $avail == $4 or die "$avail != $4"; -+ my $line = <>; -+ defined $line -+ and die "$0: extra line(s) after totals\n"; -+ exit 0; -+ } -+ $total += $2 unless $2 eq '-'; -+ $used += $3 unless $3 eq '-'; -+ $avail += $4 unless $4 eq '-'; -+ } -+die "$0: missing line of totals\n"; -+EOF - - # Use --block-size=512 to keep df from printing rounded-to-kilobyte - # numbers which wouldn't necessarily add up to the displayed total. --df --block-size=512 --total |tee tmp || fail=1 --$AWK -f compute_sum.awk tmp > out1 || fail=1 --$AWK -f parse_total.awk tmp > out2 || fail=1 --compare out1 out2 || fail=1 -+fail=0 -+df --total -P --block-size=512 >space || fail=1 -+cat space # this helps when debugging any test failure -+df --total -i -P >inode || fail=1 -+cat inode - --df -i --block-size=512 --total |tee tmp || fail=1 --$AWK -f compute_sum.awk tmp > out1 || fail=1 --$AWK -f parse_total.awk tmp > out2 || fail=1 --compare out1 out2 || fail=1 -+$PERL -f check-df space || fail=1 -+$PERL -f check-df inode || fail=1 - - Exit $fail diff --git a/coreutils-7.0-expr-removebignumoptions.patch b/coreutils-7.0-expr-removebignumoptions.patch deleted file mode 100644 index 8916b47..0000000 --- a/coreutils-7.0-expr-removebignumoptions.patch +++ /dev/null @@ -1,1012 +0,0 @@ -diff -urNp coreutils-7.0-orig/doc/coreutils.texi coreutils-7.0/doc/coreutils.texi ---- coreutils-7.0-orig/doc/coreutils.texi 2008-12-03 23:57:52.000000000 +0100 -+++ coreutils-7.0/doc/coreutils.texi 2008-12-04 00:00:51.000000000 +0100 -@@ -11167,17 +11167,8 @@ types, but if a numeric overflow occurs - with support for the GNU MP library, @command{expr}, it - uses arbitrary-precision arithmetic. - --Apart from @option{--help} and @option{--version} (@pxref{Common --options}), the following options are supported: -- --@table @samp --@item --bignum --Perform arithmetic operations using unlimited precision via the GNU MP library. --@item --no-bignum --Use only limited-precision native operations. --In the event of numeric overflow, @command{expr} fails, --even if GNU MP is available. --@end table -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. Options must precede operands. - - @cindex exit status of @command{expr} - Exit status: -diff -urNp coreutils-7.0-orig/src/expr.c coreutils-7.0/src/expr.c ---- coreutils-7.0-orig/src/expr.c 2008-08-24 22:58:15.000000000 +0200 -+++ coreutils-7.0/src/expr.c 2008-10-21 15:47:06.000000000 +0200 -@@ -33,20 +33,122 @@ - #include - #include "system.h" - --#include - #include --#if HAVE_GMP --#include --#endif - #include "error.h" -+#include "long-options.h" - #include "quotearg.h" - #include "strnumcmp.h" - #include "xstrtol.h" - -+/* Various parts of this code assume size_t fits into unsigned long -+ int, the widest unsigned type that GMP supports. */ -+verify (SIZE_MAX <= ULONG_MAX); -+ -+static void integer_overflow (char) ATTRIBUTE_NORETURN; -+ -+#ifndef HAVE_GMP -+# define HAVE_GMP 0 -+#endif -+ -+#if HAVE_GMP -+# include -+#else -+/* Approximate gmp.h well enough for expr.c's purposes. */ -+typedef intmax_t mpz_t[1]; -+static void mpz_clear (mpz_t z) {} -+static void mpz_init_set_ui (mpz_t z, unsigned long int i) { z[0] = i; } -+static int -+mpz_init_set_str (mpz_t z, char *s, int base) -+{ -+ return xstrtoimax (s, NULL, base, z, NULL) == LONGINT_OK ? 0 : -1; -+} -+static void -+mpz_add (mpz_t r, mpz_t a0, mpz_t b0) -+{ -+ intmax_t a = a0[0]; -+ intmax_t b = b0[0]; -+ intmax_t val = a + b; -+ if ((val < a) != (b < 0)) -+ integer_overflow ('+'); -+ r[0] = val; -+} -+static void -+mpz_sub (mpz_t r, mpz_t a0, mpz_t b0) -+{ -+ intmax_t a = a0[0]; -+ intmax_t b = b0[0]; -+ intmax_t val = a - b; -+ if ((a < val) != (b < 0)) -+ integer_overflow ('-'); -+ r[0] = val; -+} -+static void -+mpz_mul (mpz_t r, mpz_t a0, mpz_t b0) -+{ -+ intmax_t a = a0[0]; -+ intmax_t b = b0[0]; -+ intmax_t val = a * b; -+ if (! (a == 0 || b == 0 -+ || ((val < 0) == ((a < 0) ^ (b < 0)) && val / a == b))) -+ integer_overflow ('*'); -+ r[0] = val; -+} -+static void -+mpz_tdiv_q (mpz_t r, mpz_t a0, mpz_t b0) -+{ -+ intmax_t a = a0[0]; -+ intmax_t b = b0[0]; -+ -+ /* Some x86-style hosts raise an exception for INT_MIN / -1. */ -+ if (a < - INTMAX_MAX && b == -1) -+ integer_overflow ('/'); -+ r[0] = a / b; -+} -+static void -+mpz_tdiv_r (mpz_t r, mpz_t a0, mpz_t b0) -+{ -+ intmax_t a = a0[0]; -+ intmax_t b = b0[0]; -+ -+ /* Some x86-style hosts raise an exception for INT_MIN % -1. */ -+ r[0] = a < - INTMAX_MAX && b == -1 ? 0 : a % b; -+} -+static char * -+mpz_get_str (char const *str, int base, mpz_t z) -+{ -+ char buf[INT_BUFSIZE_BOUND (intmax_t)]; -+ return xstrdup (imaxtostr (z[0], buf)); -+} -+static int -+mpz_sgn (mpz_t z) -+{ -+ return z[0] < 0 ? -1 : 0 < z[0]; -+} -+static int -+mpz_fits_ulong_p (mpz_t z) -+{ -+ return 0 <= z[0] && z[0] <= ULONG_MAX; -+} -+static unsigned long int -+mpz_get_ui (mpz_t z) -+{ -+ return z[0]; -+} -+static int -+mpz_out_str (FILE *stream, int base, mpz_t z) -+{ -+ char buf[INT_BUFSIZE_BOUND (intmax_t)]; -+ return fputs (imaxtostr (z[0], buf), stream) != EOF; -+} -+#endif -+ - /* The official name of this program (e.g., no `g' prefix). */ - #define PROGRAM_NAME "expr" - --#define AUTHORS proper_name ("Mike Parker"), proper_name ("James Youngman") -+#define AUTHORS \ -+ proper_name ("Mike Parker"), \ -+ proper_name ("James Youngman"), \ -+ proper_name ("Paul Eggert") - - /* Exit statuses. */ - enum -@@ -61,14 +163,10 @@ enum - EXPR_FAILURE - }; - --/* The kinds of value we can have. -- In the comments below, a variable is described as "arithmetic" if -- it is either integer or mp_integer. Variables are of type mp_integer -- only if GNU MP is available, but the type designator is always defined. */ -+/* The kinds of value we can have. */ - enum valtype - { - integer, -- mp_integer, - string - }; - typedef enum valtype TYPE; -@@ -79,12 +177,7 @@ struct valinfo - TYPE type; /* Which kind. */ - union - { /* The value itself. */ -- /* We could use intmax_t but that would integrate less well with GMP, -- since GMP has mpz_set_si but no intmax_t equivalent. */ -- signed long int i; --#if HAVE_GMP -- mpz_t z; --#endif -+ mpz_t i; - char *s; - } u; - }; -@@ -98,34 +191,6 @@ static bool nomoreargs (void); - static bool null (VALUE *v); - static void printv (VALUE *v); - --/* Arithmetic is done in one of three modes. -- -- The --bignum option forces all arithmetic to use bignums other than -- string indexing (mode==MP_ALWAYS). The --no-bignum option forces -- all arithmetic to use native types rather than bignums -- (mode==MP_NEVER). -- -- The default mode is MP_AUTO if GMP is available and MP_NEVER if -- not. Most functions will process a bignum if one is found, but -- will not convert a native integer to a string if the mode is -- MP_NEVER. */ --enum arithmetic_mode -- { -- MP_NEVER, /* Never use bignums */ --#if HAVE_GMP -- MP_ALWAYS, /* Always use bignums. */ -- MP_AUTO, /* Switch if result would otherwise overflow */ --#endif -- }; --static enum arithmetic_mode mode = --#if HAVE_GMP -- MP_AUTO --#else -- MP_NEVER --#endif -- ; -- -- - void - usage (int status) - { -@@ -140,10 +205,6 @@ Usage: %s EXPRESSION\n\ - "), - program_name, program_name); - putchar ('\n'); -- fputs (_("\ -- --bignum always use arbitrary-precision arithmetic\n\ -- --no-bignum always use single-precision arithmetic\n"), -- stdout); - fputs (HELP_OPTION_DESCRIPTION, stdout); - fputs (VERSION_OPTION_DESCRIPTION, stdout); - fputs (_("\ -@@ -220,47 +281,23 @@ syntax_error (void) - static void - integer_overflow (char op) - { -- error (EXPR_FAILURE, 0, -- _("arithmetic operation %c produced an out of range value, " -- "but arbitrary-precision arithmetic is not available"), op); -+ error (EXPR_FAILURE, ERANGE, "%c", op); -+ abort (); /* notreached */ - } - --static void die (int exit_status, int errno_val, char const *msg) -+static void die (int errno_val, char const *msg) - ATTRIBUTE_NORETURN; - static void --die (int exit_status, int errno_val, char const *msg) -+die (int errno_val, char const *msg) - { -- assert (exit_status != 0); -- error (exit_status, errno_val, "%s", msg); -+ error (EXPR_FAILURE, errno_val, "%s", msg); - abort (); /* notreached */ - } - --static void --string_too_long (void) --{ -- die (EXPR_FAILURE, ERANGE, _("string too long")); --} -- --enum --{ -- USE_BIGNUM = CHAR_MAX + 1, -- NO_USE_BIGNUM --}; -- --static struct option const long_options[] = --{ -- {"bignum", no_argument, NULL, USE_BIGNUM}, -- {"no-bignum", no_argument, NULL, NO_USE_BIGNUM}, -- {GETOPT_HELP_OPTION_DECL}, -- {GETOPT_VERSION_OPTION_DECL}, -- {NULL, 0, NULL, 0} --}; -- - int - main (int argc, char **argv) - { - VALUE *v; -- int c; - - initialize_main (&argc, &argv); - set_program_name (argv[0]); -@@ -271,49 +308,23 @@ main (int argc, char **argv) - initialize_exit_failure (EXPR_FAILURE); - atexit (close_stdout); - -- /* The argument -0 should not result in an error message. */ -- opterr = 0; -- -- while ((c = getopt_long (argc, argv, "+", long_options, NULL)) != -1) -+ parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, VERSION, -+ usage, AUTHORS, (char const *) NULL); -+ /* The above handles --help and --version. -+ Since there is no other invocation of getopt, handle `--' here. */ -+ if (argc > 1 && STREQ (argv[1], "--")) - { -- /* "expr -0" should interpret the -0 as an integer argument. -- arguments like --foo should also be interpreted as a string -- argument to be "evaluated". -- */ -- if ('?' == c) -- { -- --optind; -- break; -- } -- else -- switch (c) -- { -- case USE_BIGNUM: --#if HAVE_GMP -- mode = MP_ALWAYS; --#else -- error (EXPR_FAILURE, 0, -- _("arbitrary-precision support is not available")); --#endif -- break; -- -- case NO_USE_BIGNUM: -- mode = MP_NEVER; -- break; -- -- case_GETOPT_HELP_CHAR; -- -- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -- } -+ --argc; -+ ++argv; - } - -- if (argc <= optind) -+ if (argc <= 1) - { - error (0, 0, _("missing operand")); - usage (EXPR_INVALID); - } - -- args = argv + optind; -+ args = argv + 1; - - v = eval (true); - if (!nomoreargs ()) -@@ -326,21 +337,11 @@ main (int argc, char **argv) - /* Return a VALUE for I. */ - - static VALUE * --int_value (long int i) -+int_value (unsigned long int i) - { - VALUE *v = xmalloc (sizeof *v); --#if HAVE_GMP -- if (mode == MP_ALWAYS) -- { -- /* all integer values are handled as bignums. */ -- mpz_init_set_si (v->u.z, i); -- v->type = mp_integer; -- return v; -- } --#endif -- - v->type = integer; -- v->u.i = i; -+ mpz_init_set_ui (v->u.i, i); - return v; - } - -@@ -355,42 +356,15 @@ str_value (char const *s) - return v; - } - -- --static VALUE * --substr_value (char const *s, size_t len, size_t pos, size_t nchars_wanted) --{ -- if (pos >= len) -- return str_value (""); -- else -- { -- VALUE *v = xmalloc (sizeof *v); -- size_t vlen = MIN (nchars_wanted, len - pos + 1); -- char *vlim; -- v->type = string; -- v->u.s = xmalloc (vlen + 1); -- vlim = mempcpy (v->u.s, s + pos, vlen); -- *vlim = '\0'; -- return v; -- } --} -- -- - /* Free VALUE V, including structure components. */ - - static void - freev (VALUE *v) - { - if (v->type == string) -- { -- free (v->u.s); -- } -- else if (v->type == mp_integer) -- { -- assert (mode != MP_NEVER); --#if HAVE_GMP -- mpz_clear (v->u.z); --#endif -- } -+ free (v->u.s); -+ else -+ mpz_clear (v->u.i); - free (v); - } - -@@ -402,21 +376,15 @@ printv (VALUE *v) - switch (v->type) - { - case integer: -- printf ("%ld\n", v->u.i); -+ mpz_out_str (stdout, 10, v->u.i); -+ putchar ('\n'); - break; - case string: - puts (v->u.s); - break; --#if HAVE_GMP -- case mp_integer: -- mpz_out_str (stdout, 10, v->u.z); -- putchar ('\n'); -- break; --#endif - default: - abort (); - } -- - } - - /* Return true if V is a null-string or zero-number. */ -@@ -427,11 +395,7 @@ null (VALUE *v) - switch (v->type) - { - case integer: -- return v->u.i == 0; --#if HAVE_GMP -- case mp_integer: -- return mpz_sgn (v->u.z) == 0; --#endif -+ return mpz_sgn (v->u.i) == 0; - case string: - { - char const *cp = v->u.s; -@@ -474,29 +438,16 @@ looks_like_integer (char const *cp) - static void - tostring (VALUE *v) - { -- char buf[INT_BUFSIZE_BOUND (long int)]; -- - switch (v->type) - { - case integer: -- snprintf (buf, sizeof buf, "%ld", v->u.i); -- v->u.s = xstrdup (buf); -- v->type = string; -- break; --#if HAVE_GMP -- case mp_integer: - { -- char *s = mpz_get_str (NULL, 10, v->u.z); -- if (!s) -- { -- xalloc_die (); -- } -- mpz_clear (v->u.z); -+ char *s = mpz_get_str (NULL, 10, v->u.i); -+ mpz_clear (v->u.i); - v->u.s = s; - v->type = string; - } - break; --#endif - case string: - break; - default: -@@ -504,8 +455,7 @@ tostring (VALUE *v) - } - } - --/* Coerce V to an arithmetic value. -- Return true on success, false on failure. */ -+/* Coerce V to an integer value. Return true on success, false on failure. */ - - static bool - toarith (VALUE *v) -@@ -513,40 +463,17 @@ toarith (VALUE *v) - switch (v->type) - { - case integer: -- case mp_integer: - return true; -- - case string: - { -- long int value; -+ char *s = v->u.s; - -- if (! looks_like_integer (v->u.s)) -+ if (! looks_like_integer (s)) - return false; -- if (xstrtol (v->u.s, NULL, 10, &value, NULL) != LONGINT_OK) -- { --#if HAVE_GMP -- if (mode != MP_NEVER) -- { -- char *s = v->u.s; -- if (mpz_init_set_str (v->u.z, s, 10)) -- abort (); /* Bug in looks_like_integer, perhaps. */ -- v->type = mp_integer; -- free (s); -- } -- else -- { -- error (EXPR_FAILURE, ERANGE, "%s", v->u.s); -- } --#else -- error (EXPR_FAILURE, ERANGE, "%s", v->u.s); --#endif -- } -- else -- { -- free (v->u.s); -- v->u.i = value; -- v->type = integer; -- } -+ if (mpz_init_set_str (v->u.i, s, 10) != 0 && !HAVE_GMP) -+ error (EXPR_FAILURE, ERANGE, "%s", s); -+ free (s); -+ v->type = integer; - return true; - } - default: -@@ -554,58 +481,23 @@ toarith (VALUE *v) - } - } - --/* Extract a size_t value from a positive arithmetic value, V. -- The extracted value is stored in *VAL. */ --static bool --getsize (const VALUE *v, size_t *val, bool *negative) --{ -- if (v->type == integer) -- { -- if (v->u.i < 0) -- { -- *negative = true; -- return false; -- } -- else -- { -- *negative = false; -- *val = v->u.i; -- return true; -- } -- } -- else if (v->type == mp_integer) -- { --#if HAVE_GMP -- if (mpz_sgn (v->u.z) < 0) -- { -- *negative = true; -- return false; -- } -- else if (mpz_fits_ulong_p (v->u.z)) -- { -- unsigned long ul; -- ul = mpz_get_ui (v->u.z); -- *val = ul; -- return true; -- } -- else -- { -- *negative = false; -- return false; -- } --#else -- abort (); --#endif -- -- } -- else -- { -- abort (); /* should not pass a string. */ -+/* Extract a size_t value from a integer value I. -+ If the value is negative, return SIZE_MAX. -+ If the value is too large, return SIZE_MAX - 1. */ -+static size_t -+getsize (mpz_t i) -+{ -+ if (mpz_sgn (i) < 0) -+ return SIZE_MAX; -+ if (mpz_fits_ulong_p (i)) -+ { -+ unsigned long int ul = mpz_get_ui (i); -+ if (ul < SIZE_MAX) -+ return ul; - } -+ return SIZE_MAX - 1; - } - -- -- - /* Return true and advance if the next token matches STR exactly. - STR must not be NULL. */ - -@@ -784,41 +676,14 @@ eval6 (bool evaluate) - } - else if (nextarg ("index")) - { -- size_t pos, len; -+ size_t pos; - - l = eval6 (evaluate); - r = eval6 (evaluate); - tostring (l); - tostring (r); - pos = strcspn (l->u.s, r->u.s); -- len = strlen (l->u.s); -- if (pos == len) -- { -- v = int_value (0); -- } -- else -- { -- if (pos < LONG_MAX) -- { -- v = int_value (pos + 1); -- } -- else -- { --#if HAVE_GMP -- if (mode != MP_NEVER -- && pos < ULONG_MAX) -- { -- v = xmalloc (sizeof *v); -- mpz_init_set_ui (v->u.z, pos+1); -- v->type = mp_integer; -- } -- else --#endif -- { -- string_too_long (); -- } -- } -- } -+ v = int_value (l->u.s[pos] ? pos + 1 : 0); - freev (l); - freev (r); - return v; -@@ -836,25 +701,21 @@ eval6 (bool evaluate) - v = str_value (""); - else - { -- size_t pos, len; -- bool negative = false; -+ size_t pos = getsize (i1->u.i); -+ size_t len = getsize (i2->u.i); - -- if (getsize (i1, &pos, &negative)) -- if (getsize (i2, &len, &negative)) -- if (pos == 0 || len == 0) -- v = str_value (""); -- else -- v = substr_value (l->u.s, llen, pos-1, len); -- else -- if (negative) -- v = str_value (""); -- else -- die (EXPR_FAILURE, ERANGE, _("string offset is too large")); -+ if (llen < pos || pos == 0 || len == 0 || len == SIZE_MAX) -+ v = str_value (""); - else -- if (negative) -- v = str_value (""); -- else -- die (EXPR_FAILURE, ERANGE, _("substring length too large")); -+ { -+ size_t vlen = MIN (len, llen - pos + 1); -+ char *vlim; -+ v = xmalloc (sizeof *v); -+ v->type = string; -+ v->u.s = xmalloc (vlen + 1); -+ vlim = mempcpy (v->u.s, l->u.s + pos - 1, vlen); -+ *vlim = '\0'; -+ } - } - freev (l); - freev (i1); -@@ -897,170 +758,6 @@ eval5 (bool evaluate) - } - } - -- --#if HAVE_GMP --static void --promote (VALUE *x) --{ -- if (x->type == integer) -- mpz_init_set_si (x->u.z, x->u.i); --} --#endif -- --/* L = L * R. Both L and R are arithmetic. */ --static void --domult (VALUE *l, VALUE *r) --{ -- if (l->type == integer && r->type == integer) -- { -- long int val = 0; -- val = l->u.i * r->u.i; -- if (! (l->u.i == 0 || r->u.i == 0 -- || ((val < 0) == ((l->u.i < 0) ^ (r->u.i < 0)) -- && val / l->u.i == r->u.i))) -- { -- /* Result would (did) overflow. Handle with MP if available. */ -- if (mode != MP_NEVER) -- { --#if HAVE_GMP -- mpz_init_set_si (l->u.z, l->u.i); -- mpz_mul_si (l->u.z, l->u.z, r->u.i); /* L*=R */ -- l->type = mp_integer; --#endif -- } -- else -- { -- integer_overflow ('*'); -- } -- } -- else -- { -- l->u.i = val; -- } -- } -- else -- { -- /* At least one operand is already mp_integer, so promote the other. */ --#if HAVE_GMP -- /* We could use mpz_mul_si here if R is not already mp_integer, -- but for the moment we'll try to minimise code paths. */ -- if (l->type == integer) -- mpz_init_set_si (l->u.z, l->u.i); -- if (r->type == integer) -- mpz_init_set_si (r->u.z, r->u.i); -- l->type = r->type = mp_integer; -- mpz_mul (l->u.z, l->u.z, r->u.z); /* L*=R */ --#else -- abort (); --#endif -- } --} -- --/* L = L / R or (if WANT_MODULUS) L = L % R */ --static void --dodivide (VALUE *l, VALUE *r, bool want_modulus) --{ -- if (r->type == integer && r->u.i == 0) -- error (EXPR_INVALID, 0, _("division by zero")); --#if HAVE_GMP -- if (r->type == mp_integer && mpz_sgn (r->u.z) == 0) -- error (EXPR_INVALID, 0, _("division by zero")); --#endif -- if (l->type == integer && r->type == integer) -- { -- if (l->u.i < - INT_MAX && r->u.i == -1) -- { -- /* Some x86-style hosts raise an exception for -- INT_MIN / -1 and INT_MIN % -1, so handle these -- problematic cases specially. */ -- if (want_modulus) -- { -- /* X mod -1 is zero for all negative X. -- Although strictly this is implementation-defined, -- we don't want to coredump, so we avoid the calculation. */ -- l->u.i = 0; -- return; -- } -- else -- { -- if (mode != MP_NEVER) -- { --#if HAVE_GMP -- /* Handle the case by promoting. */ -- mpz_init_set_si (l->u.z, l->u.i); -- l->type = mp_integer; --#endif -- } -- else -- { -- integer_overflow ('/'); -- } -- } -- } -- else -- { -- l->u.i = want_modulus ? l->u.i % r->u.i : l->u.i / r->u.i; -- return; -- } -- } -- /* If we get to here, at least one operand is mp_integer -- and R is not 0. */ --#if HAVE_GMP -- { -- int sign_l, sign_r; -- promote (l); -- promote (r); -- sign_l = mpz_sgn (l->u.z); -- sign_r = mpz_sgn (r->u.z); -- -- if (!want_modulus) -- { -- if (!sign_l) -- { -- mpz_set_si (l->u.z, 0); -- } -- else if (sign_l < 0 || sign_r < 0) -- { -- /* At least one operand is negative. For integer arithmetic, -- it's platform-dependent if the operation rounds up or down. -- We mirror what the implementation does. */ -- switch ((3*sign_l) / (2*sign_r)) -- { -- case 2: /* round toward +inf. */ -- case -1: /* round toward +inf. */ -- mpz_cdiv_q (l->u.z, l->u.z, r->u.z); -- break; -- case -2: /* round toward -inf. */ -- case 1: /* round toward -inf */ -- mpz_fdiv_q (l->u.z, l->u.z, r->u.z); -- break; -- default: -- abort (); -- } -- } -- else -- { -- /* Both operands positive. Round toward -inf. */ -- mpz_fdiv_q (l->u.z, l->u.z, r->u.z); -- } -- } -- else -- { -- mpz_mod (l->u.z, l->u.z, r->u.z); /* L = L % R */ -- -- /* If either operand is negative, it's platform-dependent if -- the remainer is positive or negative. We mirror what the -- implementation does. */ -- if (sign_l % sign_r < 0) -- mpz_neg (l->u.z, l->u.z); /* L = (-L) */ -- } -- } --#else -- abort (); --#endif --} -- -- - /* Handle *, /, % operators. */ - - static VALUE * -@@ -1089,71 +786,17 @@ eval4 (bool evaluate) - { - if (!toarith (l) || !toarith (r)) - error (EXPR_INVALID, 0, _("non-numeric argument")); -- switch (fxn) -- { -- case multiply: -- domult (l, r); -- break; -- case divide: -- case mod: -- dodivide (l, r, fxn==mod); -- break; -- } -+ if (fxn != multiply && mpz_sgn (r->u.i) == 0) -+ error (EXPR_INVALID, 0, _("division by zero")); -+ ((fxn == multiply ? mpz_mul -+ : fxn == divide ? mpz_tdiv_q -+ : mpz_tdiv_r) -+ (l->u.i, l->u.i, r->u.i)); - } - freev (r); - } - } - --/* L = L + R, or L = L - R */ --static void --doadd (VALUE *l, VALUE *r, bool add) --{ -- long int val = 0; -- -- if (!toarith (l) || !toarith (r)) -- error (EXPR_INVALID, 0, _("non-numeric argument")); -- if (l->type == integer && r->type == integer) -- { -- if (add) -- { -- val = l->u.i + r->u.i; -- if ((val < l->u.i) == (r->u.i < 0)) -- { -- l->u.i = val; -- return; -- } -- } -- else -- { -- val = l->u.i - r->u.i; -- if ((l->u.i < val) == (r->u.i < 0)) -- { -- l->u.i = val; -- return; -- } -- } -- } -- /* If we get to here, either the operation overflowed or at least -- one operand is an mp_integer. */ -- if (mode != MP_NEVER) -- { --#if HAVE_GMP -- promote (l); -- promote (r); -- if (add) -- mpz_add (l->u.z, l->u.z, r->u.z); -- else -- mpz_sub (l->u.z, l->u.z, r->u.z); --#endif -- } -- else -- { -- integer_overflow ('-'); -- } --} -- -- -- - /* Handle +, - operators. */ - - static VALUE * -@@ -1161,7 +804,7 @@ eval3 (bool evaluate) - { - VALUE *l; - VALUE *r; -- bool add; -+ enum { plus, minus } fxn; - - #ifdef EVAL_TRACE - trace ("eval3"); -@@ -1170,15 +813,17 @@ eval3 (bool evaluate) - while (1) - { - if (nextarg ("+")) -- add = true; -+ fxn = plus; - else if (nextarg ("-")) -- add = false; -+ fxn = minus; - else - return l; - r = eval4 (evaluate); - if (evaluate) - { -- doadd (l, r, add); -+ if (!toarith (l) || !toarith (r)) -+ error (EXPR_INVALID, 0, _("non-numeric argument")); -+ (fxn == plus ? mpz_add : mpz_sub) (l->u.i, l->u.i, r->u.i); - } - freev (r); - } -diff -urNp coreutils-7.0-orig/tests/misc/expr coreutils-7.0/tests/misc/expr ---- coreutils-7.0-orig/tests/misc/expr 2008-08-24 22:58:15.000000000 +0200 -+++ coreutils-7.0/tests/misc/expr 2008-10-21 15:47:06.000000000 +0200 -@@ -39,6 +39,15 @@ my @Tests = - ['f', '3 + -2', {OUT => '1'}], - ['g', '-2 + -2', {OUT => '-4'}], - -+ # Verify option processing. -+ # Added when option processing broke in the 7.0 beta release -+ ['opt1', '-- -11 + 12', {OUT => '1'}], -+ ['opt2', '-11 + 12', {OUT => '1'}], -+ ['opt3', '-- -1 + 2', {OUT => '1'}], -+ ['opt4', '-1 + 2', {OUT => '1'}], -+ # This evoked a syntax error diagnostic before 2.0.12. -+ ['opt5', '-- 2 + 2', {OUT => '4'}], -+ - ['paren1', '\( 100 % 6 \)', {OUT => '4'}], - ['paren2', '\( 100 % 6 \) - 8', {OUT => '-4'}], - ['paren3', '9 / \( 100 % 6 \) - 8', {OUT => '-6'}], -@@ -59,8 +68,6 @@ my @Tests = - # In 5.1.3 and earlier, this would output the empty string. - ['orempty', '"" \| ""', {OUT => '0'}, {EXIT => 1}], - -- # This evoked a syntax error diagnostic before 2.0.12. -- ['minus2', '-- 2 + 2', {OUT => '4'}], - - # This erroneously succeeded and output `3' before 2.0.12. - ['fail-a', '3 + -', {ERR => "$prog: non-numeric argument\n"}, -@@ -163,8 +170,8 @@ my @Tests = - ['bignum-div', "$big_prod / $big", {OUT => $big_p1}], - ); - --# If using --bignum fails, remove all /^bignum-/ tests --`expr --bignum 1` -+# If using big numbers fails, remove all /^bignum-/ tests -+`expr $big_prod '*' $big_prod '*' $big_prod` - or @Tests = grep {$_->[0] !~ /^bignum-/} @Tests; - - # Append a newline to end of each expected `OUT' string. diff --git a/coreutils-7.0-xattr.patch b/coreutils-7.0-xattr.patch deleted file mode 100644 index a1bd3a8..0000000 --- a/coreutils-7.0-xattr.patch +++ /dev/null @@ -1,792 +0,0 @@ -diff -ruNp coreutils-7.0.orig/doc/coreutils.texi coreutils-7.0/doc/coreutils.texi ---- coreutils-7.0.orig/doc/coreutils.texi 2009-01-28 17:10:24.453415000 +0100 -+++ coreutils-7.0/doc/coreutils.texi 2009-01-28 17:12:04.986109287 +0100 -@@ -7346,7 +7346,7 @@ symbolic links in the destination are al - @itemx @w{@kbd{--preserve}[=@var{attribute_list}]} - @opindex -p - @opindex --preserve --@cindex file information, preserving -+@cindex file information, preserving, extended attributes, xattr - Preserve the specified attributes of the original files. - If specified, the @var{attribute_list} must be a comma-separated list - of one or more of the following strings: -@@ -7373,6 +7373,11 @@ Preserve in the destination files - any links between corresponding source files. - @c Give examples illustrating how hard links are preserved. - @c Also, show how soft links map to hard links with -L and -H. -+@itemx xattr -+Preserve extended attributes if @command{cp} is built with xattr support, -+and xattrs are supported and enabled on your file system. If SELinux context -+and/or ACLs are implemented using xattrs, they are preserved as well by this -+option. - @itemx all - Preserve all file attributes. - Equivalent to specifying all of the above. -@@ -7912,6 +7917,9 @@ attributes of destination files. It is - copy programs into their destination directories. It refuses to copy - files onto themselves. - -+@cindex extended attributes, xattr -+@command{install} never preserves extended attributes (xattr). -+ - The program accepts the following options. Also see @ref{Common options}. - - @table @samp -@@ -8060,6 +8068,9 @@ directory succeeded, but the second didn - the destination partition and the second and third would be left on the - original partition. - -+@cindex extended attributes, xattr -+@command{mv} always tries to copy extended attributes (xattr). -+ - @cindex prompting, and @command{mv} - If a destination file exists but is normally unwritable, standard input - is a terminal, and the @option{-f} or @option{--force} option is not given, -diff -ruNp coreutils-7.0.orig/m4/prereq.m4 coreutils-7.0/m4/prereq.m4 ---- coreutils-7.0.orig/m4/prereq.m4 2008-06-21 19:04:15.000000000 +0200 -+++ coreutils-7.0/m4/prereq.m4 2009-01-28 17:12:04.987109294 +0100 -@@ -38,6 +38,7 @@ AC_DEFUN([gl_PREREQ], - # handles that; see ../bootstrap.conf. - AC_REQUIRE([gl_EUIDACCESS_STAT]) - AC_REQUIRE([gl_FD_REOPEN]) -+ AC_REQUIRE([gl_FUNC_XATTR]) - AC_REQUIRE([gl_FUNC_XFTS]) - AC_REQUIRE([gl_MEMXFRM]) - AC_REQUIRE([gl_STRINTCMP]) -diff -ruNp coreutils-7.0.orig/m4/xattr.m4 coreutils-7.0/m4/xattr.m4 ---- coreutils-7.0.orig/m4/xattr.m4 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-7.0/m4/xattr.m4 2009-01-28 17:12:04.988109301 +0100 -@@ -0,0 +1,36 @@ -+# xattr.m4 - check for Extended Attributes (Linux) -+ -+# Copyright (C) 2003, 2008 Free Software Foundation, Inc. -+# This file is free software; the Free Software Foundation -+# gives unlimited permission to copy and/or distribute it, -+# with or without modifications, as long as this notice is preserved. -+ -+# Originally written by Andreas Gruenbacher. -+# http://www.suse.de/~agruen/coreutils/5.91/coreutils-xattr.diff -+ -+AC_DEFUN([gl_FUNC_XATTR], -+[ -+ AC_ARG_ENABLE([xattr], -+ AC_HELP_STRING([--disable-xattr], -+ [do not support extended attributes]), -+ [use_xattr=$enableval], [use_xattr=yes]) -+ -+ if test "$use_xattr" = "yes"; then -+ AC_CHECK_HEADERS([attr/error_context.h attr/libattr.h]) -+ if test $ac_cv_header_attr_libattr_h = yes \ -+ && test $ac_cv_header_attr_error_context_h = yes; then -+ use_xattr=1 -+ else -+ use_xattr=0 -+ fi -+ AC_DEFINE_UNQUOTED([USE_XATTR], [$use_xattr], -+ [Define if you want extended attribute support.]) -+ xattr_saved_LIBS=$LIBS -+ AC_SEARCH_LIBS([attr_copy_file], [attr], -+ [test "$ac_cv_search_attr_copy_file" = "none required" || -+ LIB_XATTR=$ac_cv_search_attr_copy_file]) -+ AC_CHECK_FUNCS([attr_copy_file]) -+ LIBS=$xattr_saved_LIBS -+ AC_SUBST([LIB_XATTR]) -+ fi -+]) -diff -ruNp coreutils-7.0.orig/src/copy.c coreutils-7.0/src/copy.c ---- coreutils-7.0.orig/src/copy.c 2008-08-24 22:30:10.000000000 +0200 -+++ coreutils-7.0/src/copy.c 2009-01-28 17:12:04.990109315 +0100 -@@ -55,6 +55,13 @@ - #include "areadlink.h" - #include "yesno.h" - -+#if USE_XATTR -+# include -+# include -+# include -+# include "verror.h" -+#endif -+ - #ifndef HAVE_FCHOWN - # define HAVE_FCHOWN false - # define fchown(fd, uid, gid) (-1) -@@ -124,6 +131,70 @@ is_ancestor (const struct stat *sb, cons - return false; - } - -+#if USE_XATTR -+static void -+copy_attr_error (struct error_context *ctx, char const *fmt, ...) -+{ -+ int err = errno; -+ va_list ap; -+ -+ /* use verror module to print error message */ -+ va_start (ap, fmt); -+ verror (0, err, fmt, ap); -+ va_end (ap); -+} -+ -+static char const * -+copy_attr_quote (struct error_context *ctx, char const *str) -+{ -+ return quote (str); -+} -+ -+static void -+copy_attr_free (struct error_context *ctx, char const *str) -+{ -+} -+ -+static bool -+copy_attr_by_fd (char const *src_path, int src_fd, -+ char const *dst_path, int dst_fd) -+{ -+ struct error_context ctx = -+ { -+ .error = copy_attr_error, -+ .quote = copy_attr_quote, -+ .quote_free = copy_attr_free -+ }; -+ return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0, &ctx); -+} -+ -+static bool -+copy_attr_by_name (char const *src_path, char const *dst_path) -+{ -+ struct error_context ctx = -+ { -+ .error = copy_attr_error, -+ .quote = copy_attr_quote, -+ .quote_free = copy_attr_free -+ }; -+ return 0 == attr_copy_file (src_path, dst_path, 0, &ctx); -+} -+#else /* USE_XATTR */ -+ -+static bool -+copy_attr_by_fd (char const *src_path, int src_fd, -+ char const *dst_path, int dst_fd) -+{ -+ return true; -+} -+ -+static bool -+copy_attr_by_name (char const *src_path, char const *dst_path) -+{ -+ return true; -+} -+#endif /* USE_XATTR */ -+ - /* Read the contents of the directory SRC_NAME_IN, and recursively - copy the contents to DST_NAME_IN. NEW_DST is true if - DST_NAME_IN is a directory that was created previously in the -@@ -682,6 +753,11 @@ copy_reg (char const *src_name, char con - - set_author (dst_name, dest_desc, src_sb); - -+ if (x->preserve_xattr && ! copy_attr_by_fd (src_name, source_desc, -+ dst_name, dest_desc) -+ && x->require_preserve_xattr) -+ return false; -+ - if (x->preserve_mode || x->move_mode) - { - if (copy_acl (src_name, source_desc, dst_name, dest_desc, src_mode) != 0 -@@ -1980,6 +2056,10 @@ copy_internal (char const *src_name, cha - - set_author (dst_name, -1, &src_sb); - -+ if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name) -+ && x->require_preserve_xattr) -+ return false; -+ - if (x->preserve_mode || x->move_mode) - { - if (copy_acl (src_name, -1, dst_name, -1, src_mode) != 0 -diff -ruNp coreutils-7.0.orig/src/copy.h coreutils-7.0/src/copy.h ---- coreutils-7.0.orig/src/copy.h 2008-06-21 17:20:29.000000000 +0200 -+++ coreutils-7.0/src/copy.h 2009-01-28 17:12:04.991109322 +0100 -@@ -174,6 +174,19 @@ struct cp_options - fail if it is unable to do so. */ - bool require_preserve_context; - -+ /* If true, attempt to preserve extended attributes using libattr. -+ Ignored if coreutils are compiled without xattr support. */ -+ bool preserve_xattr; -+ -+ /* Useful only when preserve_xattr is true. -+ If true, a failed attempt to preserve file's extended attributes -+ propagates failure "out" to the caller. If false, a failure to -+ preserve file's extended attributes does not change the invoking -+ application's exit status. Give diagnostics for failed syscalls -+ regardless of this setting. For example, with "cp --preserve=xattr" -+ this flag is "true", while with "cp --preserve=all", it is false. */ -+ bool require_preserve_xattr; -+ - /* If true, copy directories recursively and copy special files - as themselves rather than copying their contents. */ - bool recursive; -diff -ruNp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c ---- coreutils-7.0.orig/src/cp.c 2009-01-28 17:10:24.455415000 +0100 -+++ coreutils-7.0/src/cp.c 2009-01-28 17:12:04.992109329 +0100 -@@ -202,7 +202,8 @@ Mandatory arguments to long options are - -p same as --preserve=mode,ownership,timestamps\n\ - --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\ - mode,ownership,timestamps), if possible\n\ -- additional attributes: context, links, all\n\ -+ additional attributes: context, links, xattr,\n\ -+ all\n\ - "), stdout); - fputs (_("\ - --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ -@@ -779,6 +780,8 @@ cp_option_init (struct cp_options *x) - x->preserve_timestamps = false; - x->preserve_security_context = false; - x->require_preserve_context = false; -+ x->preserve_xattr = false; -+ x->require_preserve_xattr = false; - - x->require_preserve = false; - x->recursive = false; -@@ -815,18 +818,20 @@ decode_preserve_arg (char const *arg, st - PRESERVE_OWNERSHIP, - PRESERVE_LINK, - PRESERVE_CONTEXT, -+ PRESERVE_XATTR, - PRESERVE_ALL - }; - static enum File_attribute const preserve_vals[] = - { - PRESERVE_MODE, PRESERVE_TIMESTAMPS, -- PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_ALL -+ PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_XATTR, -+ PRESERVE_ALL - }; - /* Valid arguments to the `--preserve' option. */ - static char const* const preserve_args[] = - { - "mode", "timestamps", -- "ownership", "links", "context", "all", NULL -+ "ownership", "links", "context", "xattr", "all", NULL - }; - ARGMATCH_VERIFY (preserve_args, preserve_vals); - -@@ -867,6 +872,11 @@ decode_preserve_arg (char const *arg, st - x->require_preserve_context = on_off; - break; - -+ case PRESERVE_XATTR: -+ x->preserve_xattr = on_off; -+ x->require_preserve_xattr = on_off; -+ break; -+ - case PRESERVE_ALL: - x->preserve_mode = on_off; - x->preserve_timestamps = on_off; -@@ -874,6 +884,7 @@ decode_preserve_arg (char const *arg, st - x->preserve_links = on_off; - if (selinux_enabled) - x->preserve_security_context = on_off; -+ x->preserve_xattr = on_off; - break; - - default: -@@ -1121,6 +1132,12 @@ main (int argc, char **argv) - "without an SELinux-enabled kernel")); - } - -+#if !USE_XATTR -+ if (x.require_preserve_xattr) -+ error (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is " -+ "built without xattr support")); -+#endif -+ - /* Allocate space for remembering copied and created files. */ - - hash_init (); -diff -ruNp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c ---- coreutils-7.0.orig/src/install.c 2008-09-27 19:28:41.000000000 +0200 -+++ coreutils-7.0/src/install.c 2009-01-28 17:12:04.993109336 +0100 -@@ -200,6 +200,7 @@ cp_option_init (struct cp_options *x) - x->open_dangling_dest_symlink = false; - x->update = false; - x->preserve_security_context = false; -+ x->preserve_xattr = false; - x->verbose = false; - x->dest_info = NULL; - x->src_info = NULL; -diff -ruNp coreutils-7.0.orig/src/Makefile.am coreutils-7.0/src/Makefile.am ---- coreutils-7.0.orig/src/Makefile.am 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/src/Makefile.am 2009-01-28 17:15:23.106476067 +0100 -@@ -149,9 +149,9 @@ su_LDADD = $(LDADD) $(LIB_CRYPT) - dir_LDADD += $(LIB_ACL) - ls_LDADD += $(LIB_ACL) - vdir_LDADD += $(LIB_ACL) --cp_LDADD += $(LIB_ACL) --mv_LDADD += $(LIB_ACL) --ginstall_LDADD += $(LIB_ACL) -+cp_LDADD += $(LIB_ACL) $(LIB_XATTR) -+mv_LDADD += $(LIB_ACL) $(LIB_XATTR) -+ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR) - - stat_LDADD = $(LDADD) $(LIB_SELINUX) - -@@ -226,7 +226,7 @@ uninstall-local: - fi; \ - fi - --copy_sources = copy.c cp-hash.c -+copy_sources = copy.c cp-hash.c verror.c xvasprintf.c - - # Use `ginstall' in the definition of PROGRAMS and in dependencies to avoid - # confusion with the `install' target. The install rule transforms `ginstall' -diff -ruNp coreutils-7.0.orig/src/mv.c coreutils-7.0/src/mv.c ---- coreutils-7.0.orig/src/mv.c 2009-01-28 17:10:24.456415000 +0100 -+++ coreutils-7.0/src/mv.c 2009-01-28 17:12:04.994109343 +0100 -@@ -140,6 +140,7 @@ cp_option_init (struct cp_options *x) - x->preserve_security_context = selinux_enabled; - x->require_preserve = false; /* FIXME: maybe make this an option */ - x->require_preserve_context = false; -+ x->preserve_xattr = true; - x->recursive = true; - x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */ - x->symbolic_link = false; -diff -ruNp coreutils-7.0.orig/tests/Makefile.am coreutils-7.0/tests/Makefile.am ---- coreutils-7.0.orig/tests/Makefile.am 2009-01-28 17:10:24.457415000 +0100 -+++ coreutils-7.0/tests/Makefile.am 2009-01-28 17:12:04.994109343 +0100 -@@ -230,6 +230,7 @@ TESTS = \ - misc/tty-eof \ - misc/unexpand \ - misc/uniq \ -+ misc/xattr \ - chmod/c-option \ - chmod/equal-x \ - chmod/equals \ -diff -ruNp coreutils-7.0.orig/tests/misc/xattr coreutils-7.0/tests/misc/xattr ---- coreutils-7.0.orig/tests/misc/xattr 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-7.0/tests/misc/xattr 2009-01-28 17:12:04.995109350 +0100 -@@ -0,0 +1,111 @@ -+#!/bin/sh -+# Ensure that cp --preserve=xattr and mv preserve extended attributes and -+# install does not preserve extended attributes. -+ -+# Copyright (C) 2009 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 . -+ -+if test "$VERBOSE" = yes; then -+ set -x -+ cp --version -+ mv --version -+ ginstall --version -+fi -+ -+. $srcdir/test-lib.sh -+ -+# Skip this test if cp was built without xattr support: -+touch src dest || framework_failure -+cp --preserve=xattr -n src dest 2>/dev/null \ -+ || skip_test_ "coreutils built without xattr support" -+ -+# this code was taken from test mv/backup-is-src -+cleanup_() { rm -rf "$other_partition_tmpdir"; } -+. "$abs_srcdir/other-fs-tmpdir" -+b_other="$other_partition_tmpdir/b" -+rm -f $b_other || framework_failure -+ -+# testing xattr name-value pair -+xattr_name="user.foo" -+xattr_value="bar" -+xattr_pair="$xattr_name=\"$xattr_value\"" -+ -+# create new file and check its xattrs -+touch a || framework_failure -+getfattr -d a >out_a || skip_test_ "failed to get xattr of file" -+grep -F "$xattr_pair" out_a >/dev/null && framework_failure -+ -+# try to set user xattr on file -+setfattr -n "$xattr_name" -v "$xattr_value" a >out_a \ -+ || skip_test_ "failed to set xattr of file" -+getfattr -d a >out_a || skip_test_ "failed to get xattr of file" -+grep -F "$xattr_pair" out_a >/dev/null \ -+ || skip_test_ "failed to set xattr of file" -+ -+fail=0 -+ -+# cp should not preserve xattr by default -+cp a b || fail=1 -+getfattr -d b >out_b || skip_test_ "failed to get xattr of file" -+grep -F "$xattr_pair" out_b >/dev/null && fail=1 -+ -+# test if --preserve=xattr option works -+cp --preserve=xattr a b || fail=1 -+getfattr -d b >out_b || skip_test_ "failed to get xattr of file" -+grep -F "$xattr_pair" out_b >/dev/null || fail=1 -+ -+rm b || framework_failure -+ -+# install should never preserve xattr -+ginstall a b || fail=1 -+getfattr -d b >out_b || skip_test_ "failed to get xattr of file" -+grep -F "$xattr_pair" out_b >/dev/null && fail=1 -+ -+# mv should preserve xattr when renaming within a filesystem. -+# This is implicitly done by rename () and doesn't need explicit -+# xattr support in mv. -+mv a b || fail=1 -+getfattr -d b >out_b || skip_test_ "failed to get xattr of file" -+grep -F "$xattr_pair" out_b >/dev/null || cat >&2 <out_a 2>/dev/null \ -+ || test_mv=0 -+getfattr -d $b_other >out_b 2>/dev/null || test_mv=0 -+grep -F "$xattr_pair" out_b >/dev/null || test_mv=0 -+rm -f $b_other || framework_failure -+ -+if test $test_mv -eq 1; then -+ # mv should preserve xattr when copying content from one partition to another -+ mv b $b_other || fail=1 -+ getfattr -d $b_other >out_b 2>/dev/null || skip_test_ "failed to get xattr of file" -+ grep -F "$xattr_pair" out_b >/dev/null || fail=1 -+else -+ cat >&2 <. */ -+ -+/* Written by Eric Blake. */ -+ -+#include -+ -+#include "verror.h" -+#include "xvasprintf.h" -+ -+#include -+#include -+#include -+ -+#if ENABLE_NLS -+# include "gettext.h" -+# define _(msgid) gettext (msgid) -+#endif -+ -+#ifndef _ -+# define _(String) String -+#endif -+ -+/* Print a message with `vfprintf (stderr, FORMAT, ARGS)'; -+ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). -+ If STATUS is nonzero, terminate the program with `exit (STATUS)'. -+ Use the globals error_print_progname and error_message_count similarly -+ to error(). */ -+void -+verror (int status, int errnum, const char *format, va_list args) -+{ -+ verror_at_line (status, errnum, NULL, 0, format, args); -+} -+ -+/* Print a message with `vfprintf (stderr, FORMAT, ARGS)'; -+ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). -+ If STATUS is nonzero, terminate the program with `exit (STATUS)'. -+ If FNAME is not NULL, prepend the message with `FNAME:LINENO:'. -+ Use the globals error_print_progname, error_message_count, and -+ error_one_per_line similarly to error_at_line(). */ -+void -+verror_at_line (int status, int errnum, const char *file, -+ unsigned int line_number, const char *format, va_list args) -+{ -+ char *message = xvasprintf (format, args); -+ if (message) -+ { -+ /* Until http://sourceware.org/bugzilla/show_bug.cgi?id=2997 is fixed, -+ glibc violates GNU Coding Standards when the file argument to -+ error_at_line is NULL. */ -+ if (file) -+ error_at_line (status, errnum, file, line_number, "%s", message); -+ else -+ error (status, errnum, "%s", message); -+ } -+ else -+ { -+ /* EOVERFLOW, EINVAL, and EILSEQ from xvasprintf are signs of -+ serious programmer errors. */ -+ error (0, errno, _("unable to display error message")); -+ abort (); -+ } -+ free (message); -+} -diff -ruNp coreutils-7.0.orig/src/verror.h coreutils-7.0/src/verror.h ---- coreutils-7.0.orig/src/verror.h 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-7.0/src/verror.h 2009-01-28 17:14:54.039275540 +0100 -@@ -0,0 +1,53 @@ -+/* Declaration for va_list error-reporting function -+ Copyright (C) 2006-2007 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 . */ -+ -+#ifndef _VERROR_H -+#define _VERROR_H 1 -+ -+#include "error.h" -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* Print a message with `vfprintf (stderr, FORMAT, ARGS)'; -+ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). -+ If STATUS is nonzero, terminate the program with `exit (STATUS)'. -+ Use the globals error_print_progname and error_message_count similarly -+ to error(). */ -+ -+extern void verror (int __status, int __errnum, const char *__format, -+ va_list __args) -+ __attribute__ ((__format__ (__printf__, 3, 0))); -+ -+/* Print a message with `vfprintf (stderr, FORMAT, ARGS)'; -+ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). -+ If STATUS is nonzero, terminate the program with `exit (STATUS)'. -+ If FNAME is not NULL, prepend the message with `FNAME:LINENO:'. -+ Use the globals error_print_progname, error_message_count, and -+ error_one_per_line similarly to error_at_line(). */ -+ -+extern void verror_at_line (int __status, int __errnum, const char *__fname, -+ unsigned int __lineno, const char *__format, -+ va_list __args) -+ __attribute__ ((__format__ (__printf__, 5, 0))); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* verror.h */ -diff -ruNp coreutils-7.0.orig/src/xvasprintf.c coreutils-7.0/src/xvasprintf.c ---- coreutils-7.0.orig/src/xvasprintf.c 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-7.0/src/xvasprintf.c 2009-01-28 17:15:06.809363638 +0100 -@@ -0,0 +1,110 @@ -+/* vasprintf and asprintf with out-of-memory checking. -+ Copyright (C) 1999, 2002-2004, 2006-2008 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 . */ -+ -+#include -+ -+/* Specification. */ -+#include "xvasprintf.h" -+ -+#include -+#include -+#include -+#include -+ -+#include "xalloc.h" -+ -+/* Checked size_t computations. */ -+#include "xsize.h" -+ -+static inline char * -+xstrcat (size_t argcount, va_list args) -+{ -+ char *result; -+ va_list ap; -+ size_t totalsize; -+ size_t i; -+ char *p; -+ -+ /* Determine the total size. */ -+ totalsize = 0; -+ va_copy (ap, args); -+ for (i = argcount; i > 0; i--) -+ { -+ const char *next = va_arg (ap, const char *); -+ totalsize = xsum (totalsize, strlen (next)); -+ } -+ va_end (ap); -+ -+ /* Test for overflow in the summing pass above or in (totalsize + 1) below. -+ Also, don't return a string longer than INT_MAX, for consistency with -+ vasprintf(). */ -+ if (totalsize == SIZE_MAX || totalsize > INT_MAX) -+ { -+ errno = EOVERFLOW; -+ return NULL; -+ } -+ -+ /* Allocate and fill the result string. */ -+ result = XNMALLOC (totalsize + 1, char); -+ p = result; -+ for (i = argcount; i > 0; i--) -+ { -+ const char *next = va_arg (args, const char *); -+ size_t len = strlen (next); -+ memcpy (p, next, len); -+ p += len; -+ } -+ *p = '\0'; -+ -+ return result; -+} -+ -+char * -+xvasprintf (const char *format, va_list args) -+{ -+ char *result; -+ -+ /* Recognize the special case format = "%s...%s". It is a frequently used -+ idiom for string concatenation and needs to be fast. We don't want to -+ have a separate function xstrcat() for this purpose. */ -+ { -+ size_t argcount = 0; -+ const char *f; -+ -+ for (f = format;;) -+ { -+ if (*f == '\0') -+ /* Recognized the special case of string concatenation. */ -+ return xstrcat (argcount, args); -+ if (*f != '%') -+ break; -+ f++; -+ if (*f != 's') -+ break; -+ f++; -+ argcount++; -+ } -+ } -+ -+ if (vasprintf (&result, format, args) < 0) -+ { -+ if (errno == ENOMEM) -+ xalloc_die (); -+ return NULL; -+ } -+ -+ return result; -+} -diff -ruNp coreutils-7.0.orig/src/xvasprintf.h coreutils-7.0/src/xvasprintf.h ---- coreutils-7.0.orig/src/xvasprintf.h 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-7.0/src/xvasprintf.h 2009-01-28 17:15:06.809363638 +0100 -@@ -0,0 +1,56 @@ -+/* vasprintf and asprintf with out-of-memory checking. -+ Copyright (C) 2002-2004, 2006-2008 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 . */ -+ -+#ifndef _XVASPRINTF_H -+#define _XVASPRINTF_H -+ -+/* Get va_list. */ -+#include -+ -+#ifndef __attribute__ -+/* This feature is available in gcc versions 2.5 and later. */ -+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -+# define __attribute__(Spec) /* empty */ -+# endif -+/* The __-protected variants of `format' and `printf' attributes -+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -+# define __format__ format -+# define __printf__ printf -+# endif -+#endif -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* Write formatted output to a string dynamically allocated with malloc(), -+ and return it. Upon [ENOMEM] memory allocation error, call xalloc_die. -+ On some other error -+ - [EOVERFLOW] resulting string length is > INT_MAX, -+ - [EINVAL] invalid format string, -+ - [EILSEQ] error during conversion between wide and multibyte characters, -+ return NULL. */ -+extern char *xasprintf (const char *format, ...) -+ __attribute__ ((__format__ (__printf__, 1, 2))); -+extern char *xvasprintf (const char *format, va_list args) -+ __attribute__ ((__format__ (__printf__, 1, 0))); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* _XVASPRINTF_H */ diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index d24a5a8..93da421 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -1,4 +1,5 @@ # Configuration file for the color ls utility +# Synchronized with coreutils 7.1 dircolors # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. @@ -34,6 +35,8 @@ TERM cygwin TERM dtterm TERM eterm-color TERM gnome +TERM gnome-256color +TERM jfbterm TERM konsole TERM kterm TERM linux @@ -63,22 +66,24 @@ EIGHTBIT 1 # Below are the color init strings for the basic file types. A color init # string consists of one or more of the following numeric codes: -# Attribute codes: +# Attribute codes: # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed # Text color codes: # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white # Background color codes: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -NORMAL 00 # global default, although everything should be something. -FILE 00 # normal file -DIR 01;34 # directory -LINK 01;36 # symbolic link (If you set this to 'target' instead of a +#NORMAL 00 # no color code at all +#FILE 00 # normal file, use no color at all +RESET 0 # reset to "normal" color +DIR 01;34 # directory +LINK 01;36 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) +HARDLINK 44;37 # regular file with more than one link FIFO 40;33 # pipe SOCK 01;35 # socket DOOR 01;35 # door BLK 40;33;01 # block device driver -CHR 40;33;01 # character device driver +CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file MISSING 01;05;37;41 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) @@ -90,13 +95,13 @@ STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: -EXEC 01;32 +EXEC 01;32 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. # (and any comments you want to add after a '#') # executables (bright green) -#.cmd 01;32 +#.cmd 01;32 #.exe 01;32 #.com 01;32 #.btm 01;32 @@ -104,9 +109,8 @@ EXEC 01;32 #.sh 01;32 #.csh 01;32 # archives or compressed (bright red) -.tar 01;31 +.tar 01;31 .tgz 01;31 -.svgz 01;31 .arj 01;31 .taz 01;31 .lzh 01;31 @@ -129,8 +133,9 @@ EXEC 01;32 .cpio 01;31 .7z 01;31 .rz 01;31 +.xz 01;31 # image formats (magenta) -.jpg 01;35 +.jpg 01;35 .jpeg 01;35 .gif 01;35 .bmp 01;35 @@ -164,21 +169,33 @@ EXEC 01;32 .flc 01;35 .avi 01;35 .fli 01;35 +.flv 01;35 .gl 01;35 .dl 01;35 .xcf 01;35 .xwd 01;35 .yuv 01;35 .svg 01;35 +.svgz 01;35 +# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +.axv 01;35 +.anx 01;35 +.ogv 01;35 +.ogx 01;35 # audio formats (cyan) -.aac 00;36 -.au 00;36 -.flac 00;36 -.mid 00;36 -.midi 00;36 -.mka 00;36 -.mp3 00;36 -.mpc 00;36 -.ogg 00;36 -.ra 00;36 -.wav 00;36 +.aac 01;36 +.au 01;36 +.flac 01;36 +.mid 01;36 +.midi 01;36 +.mka 01;36 +.mp3 01;36 +.mpc 01;36 +.ogg 01;36 +.ra 01;36 +.wav 01;36 +# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +.axa 01;36 +.oga 01;36 +.spx 01;36 +.xspf 01;36 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 34fbe33..af16bf6 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -1,5 +1,6 @@ # Configuration file for the 256color ls utility # This file goes in the /etc directory, and must be world readable. +# Synchronized with coreutils 7.1 dircolors # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. # In the case that you are not satisfied with supplied colors, please @@ -31,7 +32,7 @@ EIGHTBIT 1 # Below are the color init strings for the basic file types. A color init # string consists of one or more of the following numeric codes: -# Attribute codes: +# Attribute codes: # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed # Text color(8 colors mode) codes: # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white @@ -48,16 +49,18 @@ EIGHTBIT 1 # You may find following command useful to search the best one for you: # for ((x=0; x<=255; x++));do echo -e "${x}:\033[48;5;${x}mcolor\033[000m";done -NORMAL 00 # global default, although everything should be something. -FILE 00 # normal file -DIR 01;38;5;27 # directory -LINK 01;38;5;51 # symbolic link (If you set this to 'target' instead of a +#NORMAL 00 # global default, no color code at all +#FILE 00 # normal file, use no color at all +RESET 0 # reset to "normal" color +DIR 01;38;5;27 # directory +LINK 01;38;5;51 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) +HARDLINK 44;38;5;15; # regular file with more than one link FIFO 40;38;5;11 # pipe SOCK 01;38;5;13 # socket DOOR 01;38;5;5 # door BLK 01;48;5;232;38;5;11 # block device driver -CHR 01;48;5;232;38;5;3 # character device driver +CHR 01;48;5;232;38;5;3 # character device driver ORPHAN 01;48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file MISSING 01;05;48;5;232;38;5;15 # ... and the files they point to SETUID 48;5;196;38;5;15 # file that is setuid (u+s) @@ -82,9 +85,8 @@ EXEC 01;38;5;34 #.sh 01;38;5;34 #.csh 01;38;5;34 # archives or compressed (bright red) -.tar 01;38;5;9 +.tar 01;38;5;9 .tgz 01;38;5;9 -.svgz 01;38;5;9 .arj 01;38;5;9 .taz 01;38;5;9 .lzh 01;38;5;9 @@ -107,8 +109,9 @@ EXEC 01;38;5;34 .cpio 01;38;5;9 .7z 01;38;5;9 .rz 01;38;5;9 +.xz 01;38;5;9 # image formats (magenta) -.jpg 01;38;5;13 +.jpg 01;38;5;13 .jpeg 01;38;5;13 .gif 01;38;5;13 .bmp 01;38;5;13 @@ -142,21 +145,33 @@ EXEC 01;38;5;34 .flc 01;38;5;13 .avi 01;38;5;13 .fli 01;38;5;13 +.flv 01;38;5;13 .gl 01;38;5;13 .dl 01;38;5;13 .xcf 01;38;5;13 .xwd 01;38;5;13 .yuv 01;38;5;13 .svg 01;38;5;13 +.svgz 01;38;5;13 +# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +.axv 01;38;5;13 +.anx 01;38;5;13 +.ogv 01;38;5;13 +.ogx 01;38;5;13 # audio formats (cyan) -.aac 00;38;5;45 -.au 00;38;5;45 -.flac 00;38;5;45 -.mid 00;38;5;45 -.midi 00;38;5;45 -.mka 00;38;5;45 -.mp3 00;38;5;45 -.mpc 00;38;5;45 -.ogg 00;38;5;45 -.ra 00;38;5;45 -.wav 00;38;5;45 +.aac 01;38;5;45 +.au 01;38;5;45 +.flac 01;38;5;45 +.mid 01;38;5;45 +.midi 01;38;5;45 +.mka 01;38;5;45 +.mp3 01;38;5;45 +.mpc 01;38;5;45 +.ogg 01;38;5;45 +.ra 01;38;5;45 +.wav 01;38;5;45 +# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +.axa 01;38;5;45 +.oga 01;38;5;45 +.spx 01;38;5;45 +.xspf 01;38;5;45 diff --git a/coreutils-DIR_COLORS.xterm b/coreutils-DIR_COLORS.xterm index dec01f9..dd189cf 100644 --- a/coreutils-DIR_COLORS.xterm +++ b/coreutils-DIR_COLORS.xterm @@ -1,4 +1,5 @@ # Configuration file for the color ls utility +# Synchronized with coreutils 7.1 dircolors # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. @@ -45,22 +46,24 @@ EIGHTBIT 1 # Below are the color init strings for the basic file types. A color init # string consists of one or more of the following numeric codes: -# Attribute codes: +# Attribute codes: # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed # Text color codes: # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white # Background color codes: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -NORMAL 00 # global default, although everything should be something. -FILE 00 # normal file -DIR 00;34 # directory -LINK 00;36 # symbolic link (If you set this to 'target' instead of a +#NORMAL 00 # no color code at all +#FILE 00 # normal file, use no color at all +RESET 0 +DIR 00;34 # directory +LINK 00;36 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) +HARDLINK 44;37 # regular file with more than one link FIFO 40;33 # pipe SOCK 00;35 # socket DOOR 00;35 # door BLK 40;33;01 # block device driver -CHR 40;33;01 # character device driver +CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file MISSING 01;05;37;41 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) @@ -72,7 +75,7 @@ STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: -EXEC 00;32 +EXEC 00;32 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. @@ -85,9 +88,8 @@ EXEC 00;32 #.sh 00;32 #.csh 00;32 # archives or compressed (red) -.tar 00;31 +.tar 00;31 .tgz 00;31 -.svgz 00;31 .arj 00;31 .taz 00;31 .lzh 00;31 @@ -110,8 +112,9 @@ EXEC 00;32 .cpio 00;31 .7z 00;31 .rz 00;31 +.xz 00;31 # image formats (magenta) -.jpg 00;35 +.jpg 00;35 .jpeg 00;35 .gif 00;35 .bmp 00;35 @@ -145,12 +148,19 @@ EXEC 00;32 .flc 00;35 .avi 00;35 .fli 00;35 +.flv 00;35 .gl 00;35 .dl 00;35 .xcf 00;35 .xwd 00;35 .yuv 00;35 .svg 00;35 +.svgz 00;35 +# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +.axv 00;35 +.anx 00;35 +.ogv 00;35 +.ogx 00;35 # audio formats (cyan) .aac 00;36 .au 00;36 @@ -163,3 +173,8 @@ EXEC 00;32 .ogg 00;36 .ra 00;36 .wav 00;36 +# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +.axa 00;36 +.oga 00;36 +.spx 00;36 +.xspf 00;36 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 832eadc..4759add 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -331,7 +331,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am error (EXIT_FAILURE, errno, "-"); --- coreutils-6.8+/src/join.c.i18n 2007-01-14 15:41:28.000000000 +0000 +++ coreutils-6.8+/src/join.c 2007-03-01 15:08:24.000000000 +0000 -@@ -23,17 +23,31 @@ +@@ -23,16 +23,30 @@ #include #include @@ -347,7 +347,6 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am + #include "system.h" #include "error.h" - #include "hard-locale.h" #include "linebuffer.h" -#include "memcasecmp.h" #include "quote.h" @@ -2841,11 +2840,11 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c line of 1st page printed). */ @@ -696,6 +756,7 @@ -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ - static char *col_sep_string = ""; + static char *col_sep_string = (char *) ""; static int col_sep_length = 0; +static int col_sep_width = 0; - static char *column_separator = " "; - static char *line_separator = "\t"; + static char *column_separator = (char *) " "; + static char *line_separator = (char *) "\t"; @@ -852,6 +913,13 @@ col_sep_length = (int) strlen (optarg_S); @@ -2927,7 +2926,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c @@ -1031,7 +1122,7 @@ old_s = false; /* Reset an additional input of -s, -S dominates -s */ - col_sep_string = ""; + col_sep_string = bad_cast (""); - col_sep_length = 0; + col_sep_length = col_sep_width = 0; use_col_separator = true; diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 7825b25..5a5ebfb 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -49,11 +49,11 @@ #define DEFAULT_USER "root" +#ifndef USE_PAM - char *crypt (); + char *crypt (char const *key, char const *salt); +#endif - char *getusershell (); - void endusershell (); - void setusershell (); + char *getusershell (void); + void endusershell (void); + void setusershell (void); extern char **environ; diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 95f0401..5b6c2db 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -49,71 +49,6 @@ diff -urp coreutils-7.0.orig/src/chcon.c coreutils-7.0/src/chcon.c diff -urp coreutils-7.0.orig/src/copy.c coreutils-7.0/src/copy.c --- coreutils-7.0.orig/src/copy.c 2009-01-28 17:18:16.748671000 +0100 +++ coreutils-7.0/src/copy.c 2009-01-28 17:18:52.762913947 +0100 -@@ -449,9 +449,10 @@ copy_reg (char const *src_name, char con - security_context_t con = NULL; - if (getfscreatecon (&con) < 0) - { -- error (0, errno, _("failed to get file system create context")); -+ //do not show error when we not require security context (-a option) - if (x->require_preserve_context) - { -+ error (0, errno, _("failed to get file system create context")); - return_val = false; - goto close_src_and_dst_desc; - } -@@ -461,11 +462,12 @@ copy_reg (char const *src_name, char con - { - if (fsetfilecon (dest_desc, con) < 0) - { -- error (0, errno, -- _("failed to set the security context of %s to %s"), -- quote_n (0, dst_name), quote_n (1, con)); -+ //do not show error when we not require security context (-a option) - if (x->require_preserve_context) - { -+ error (0, errno, -+ _("failed to set the security context of %s to %s"), -+ quote_n (0, dst_name), quote_n (1, con)); - return_val = false; - freecon (con); - goto close_src_and_dst_desc; -@@ -1714,11 +1716,12 @@ copy_internal (char const *src_name, cha - { - if (setfscreatecon (con) < 0) - { -- error (0, errno, -- _("failed to set default file creation context to %s"), -- quote (con)); -+ //do not show error when we not require security context (-a option) - if (x->require_preserve_context) - { -+ error (0, errno, -+ _("failed to set default file creation context to %s"), -+ quote (con)); - freecon (con); - return false; - } -@@ -1728,12 +1731,14 @@ copy_internal (char const *src_name, cha - else - { - if (errno != ENOTSUP && errno != ENODATA) -- { -- error (0, errno, -- _("failed to get security context of %s"), -- quote (src_name)); -- if (x->require_preserve_context) -- return false; -+ { -+ //do not show error when we not require security context (-a option) -+ if (x->require_preserve_context) { -+ error (0, errno, -+ _("failed to get security context of %s"), -+ quote (src_name)); -+ return false; -+ } - } - } - } @@ -1819,6 +1824,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option @@ -147,15 +82,6 @@ diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -175,7 +176,7 @@ Copy SOURCE to DEST, or multiple SOURCE( - Mandatory arguments to long options are mandatory for short options too.\n\ - "), stdout); - fputs (_("\ -- -a, --archive same as -dpR\n\ -+ -a, --archive same as -cdpR\n\ - --backup[=CONTROL] make a backup of each existing destination file\n\ - -b like --backup but does not accept an argument\n\ - --copy-contents copy contents of special files when recursive\n\ @@ -206,6 +207,9 @@ Mandatory arguments to long options are all\n\ "), stdout); @@ -191,24 +117,6 @@ diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c long_opts, NULL)) != -1) { -@@ -936,13 +942,15 @@ main (int argc, char **argv) - sparse_type_string, sparse_type); - break; - -- case 'a': /* Like -dpR. */ -+ case 'a': /* Like -dpRc. */ - x.dereference = DEREF_NEVER; - x.preserve_links = true; - x.preserve_ownership = true; - x.preserve_mode = true; - x.preserve_timestamps = true; -- x.require_preserve = true; -+ x.require_preserve = true; -+ if (selinux_enabled) -+ x.preserve_security_context = true; - x.recursive = true; - break; - @@ -956,6 +964,16 @@ main (int argc, char **argv) copy_contents = true; break; @@ -288,15 +196,15 @@ diff -urp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c x->require_preserve = false; x->require_preserve_context = false; + x->set_security_context = false; + x->require_preserve_xattr = false; x->recursive = false; x->sparse_mode = SPARSE_AUTO; - x->symbolic_link = false; @@ -361,7 +362,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); -- while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pt:TvS:Z:", long_options, -+ while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pPt:TvS:Z:", long_options, +- while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options, ++ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z:", long_options, NULL)) != -1) { switch (optc) @@ -351,18 +259,6 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c }; /* Display letters and indicators for each filetype. -@@ -182,8 +183,9 @@ struct fileinfo - exists, otherwise false. */ - bool linkok; - -- /* For long listings, true if the file has an access control list, -- or an SELinux security context. */ -+ /* For long listings, true if the file has an access control list. -+ Unlike with upstream not true for SELinux scontext(#430779) as -+ this removes possibility to detect ACL via ls */ - bool have_acl; - }; - @@ -246,6 +248,7 @@ static void queue_directory (char const static void sort_files (void); static void parse_ls_color (void); @@ -513,26 +409,6 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c { bool have_acl = false; int attr_len = (do_deref -@@ -2708,9 +2735,7 @@ gobble_file (char const *name, enum file - f->scontext = xstrdup ("unlabeled"); - } - -- if (err == 0) -- have_acl = ! STREQ ("unlabeled", f->scontext); -- else -+ if (err != 0) - { - f->scontext = UNKNOWN_SECURITY_CONTEXT; - -@@ -2722,7 +2747,7 @@ gobble_file (char const *name, enum file - err = 0; - } - -- if (err == 0 && ! have_acl && format == long_format) -+ if (err == 0 && format == long_format) - { - int n = file_has_acl (absolute_name, &f->stat); - err = (n < 0); @@ -3297,6 +3322,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); @@ -590,9 +466,9 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c - if (print_scontext) - printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext); - - print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, - f->stat_ok, f->filetype, NULL); - + size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), + f->linkok, f->stat_ok, f->filetype, + NULL, f->stat.st_nlink, start_col); @@ -4077,9 +4109,6 @@ length_of_file_name_and_frills (const st output_block_size)) : block_size_width); @@ -621,74 +497,6 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_("\n\ -@@ -4541,3 +4577,67 @@ Exit status:\n\ - } - exit (status); - } -+ -+static void -+print_scontext_format (const struct fileinfo *f) -+{ -+ char modebuf[12]; -+ -+ /* 7 fields that may require LONGEST_HUMAN_READABLE bytes, -+ 1 10-byte mode string, -+ 9 spaces, one following each of these fields, and -+ 1 trailing NUL byte. */ -+ -+ char init_bigbuf[7 * LONGEST_HUMAN_READABLE + 10 + 9 + 1]; -+ char *buf = init_bigbuf; -+ size_t bufsize = sizeof (init_bigbuf); -+ size_t s; -+ char *p; -+ const char *fmt; -+ char *user_name; -+ char *group_name; -+ int rv; -+ char *scontext; -+ -+ p = buf; -+ -+ if ( print_scontext ) { /* zero means terse listing */ -+ filemodestring (&f->stat, modebuf); -+ modebuf[10] = (f->have_acl ? '+' : ' '); -+ modebuf[11] = '\0'; -+ -+ /* print mode */ -+ -+ (void) sprintf (p, "%s ", modebuf); -+ p += strlen (p); -+ -+ /* print standard user and group */ -+ -+ DIRED_FPUTS (buf, stdout, p - buf); -+ format_user (f->stat.st_uid, owner_width, f->stat_ok); -+ format_group (f->stat.st_gid, group_width, f->stat_ok); -+ p = buf; -+ } -+ -+ (void) sprintf (p, "%-32s ", f->scontext ?: ""); -+ p += strlen (p); -+ -+ DIRED_INDENT (); -+ DIRED_FPUTS (buf, stdout, p - buf); -+ print_name_with_quoting (f->name, f->stat.st_mode, f->linkok, -+ f->stat_ok, f->filetype, &dired_obstack); -+ -+ if (f->filetype == symbolic_link) { -+ if (f->linkname) { -+ DIRED_FPUTS_LITERAL (" -> ", stdout); -+ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, -+ f->stat_ok, f->filetype, NULL); -+ if (indicator_style != none) -+ print_type_indicator (f->stat_ok, f->linkmode, f->filetype); -+ } -+ } -+ else { -+ if (indicator_style != none) -+ print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); -+ } -+} diff -urp coreutils-7.0.orig/src/mkdir.c coreutils-7.0/src/mkdir.c --- coreutils-7.0.orig/src/mkdir.c 2008-08-24 22:58:15.000000000 +0200 +++ coreutils-7.0/src/mkdir.c 2009-01-28 17:18:52.771914007 +0100 @@ -720,9 +528,9 @@ diff -urp coreutils-7.0.orig/src/mv.c coreutils-7.0/src/mv.c x->preserve_timestamps = true; x->preserve_security_context = selinux_enabled; + x->set_security_context = false; + x->reduce_diagnostics = false; x->require_preserve = false; /* FIXME: maybe make this an option */ x->require_preserve_context = false; - x->preserve_xattr = true; diff -urp coreutils-7.0.orig/src/runcon.c coreutils-7.0/src/runcon.c --- coreutils-7.0.orig/src/runcon.c 2008-08-24 22:30:10.000000000 +0200 +++ coreutils-7.0/src/runcon.c 2009-01-28 17:18:52.774914027 +0100 @@ -891,7 +699,7 @@ diff -urp coreutils-7.0.orig/src/stat.c coreutils-7.0/src/stat.c diff -urp coreutils-7.0.orig/tests/misc/selinux coreutils-7.0/tests/misc/selinux --- coreutils-7.0.orig/tests/misc/selinux 2008-09-27 19:28:54.000000000 +0200 +++ coreutils-7.0/tests/misc/selinux 2009-01-28 17:18:52.776914041 +0100 -@@ -30,12 +30,10 @@ chcon $ctx f d p || +@@ -30,7 +30,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. for i in d f p; do @@ -900,8 +708,76 @@ diff -urp coreutils-7.0.orig/tests/misc/selinux coreutils-7.0/tests/misc/selinux c=`stat --printf %C $i`; test x$c = x$ctx || fail=1 done --# ensure that ls -l output includes the "+". --c=`ls -l f|cut -c11`; test "$c" = + || fail=1 +diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c +--- coreutils-7.1-orig/src/ls.c 2009-02-23 17:11:01.000000000 +0100 ++++ coreutils-7.1/src/ls.c 2009-02-23 17:14:27.000000000 +0100 +@@ -3467,6 +3467,69 @@ format_group_width (gid_t g) + } - # Copy each to a new directory and ensure that context is preserved. - cp -r --preserve=all d f p s1 || fail=1 + ++/* Print info about f in scontext format */ ++static void ++print_scontext_format (const struct fileinfo *f) ++{ ++ char modebuf[12]; ++ ++ /* 7 fields that may require LONGEST_HUMAN_READABLE bytes, ++ 1 10-byte mode string, ++ 9 spaces, one following each of these fields, and ++ 1 trailing NUL byte. */ ++ ++ char init_bigbuf[7 * LONGEST_HUMAN_READABLE + 10 + 9 + 1]; ++ char *buf = init_bigbuf; ++ char *p; ++ ++ p = buf; ++ ++ if ( print_scontext ) { /* zero means terse listing */ ++ filemodestring (&f->stat, modebuf); ++ if (! any_has_acl) ++ modebuf[10] = '\0'; ++ else if (f->acl_type == ACL_T_SELINUX_ONLY) ++ modebuf[10] = '.'; ++ else if (f->acl_type == ACL_T_YES) ++ modebuf[10] = '+'; ++ modebuf[11] = '\0'; ++ ++ /* print mode */ ++ ++ (void) sprintf (p, "%s ", modebuf); ++ p += strlen (p); ++ ++ /* print standard user and group */ ++ ++ DIRED_FPUTS (buf, stdout, p - buf); ++ format_user (f->stat.st_uid, owner_width, f->stat_ok); ++ format_group (f->stat.st_gid, group_width, f->stat_ok); ++ p = buf; ++ } ++ ++ (void) sprintf (p, "%-32s ", f->scontext ?: ""); ++ p += strlen (p); ++ ++ DIRED_INDENT (); ++ DIRED_FPUTS (buf, stdout, p - buf); ++ size_t w = print_name_with_quoting (f->name, FILE_OR_LINK_MODE(f), f->linkok, ++ f->stat_ok, f->filetype, &dired_obstack, f->stat.st_nlink, p - buf); ++ ++ if (f->filetype == symbolic_link) { ++ if (f->linkname) { ++ DIRED_FPUTS_LITERAL (" -> ", stdout); ++ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, ++ f->stat_ok, f->filetype, NULL, f->stat.st_nlink, (p-buf) + w + 4 ); ++ if (indicator_style != none) ++ print_type_indicator (f->stat_ok, f->linkmode, f->filetype); ++ } ++ } ++ else { ++ if (indicator_style != none) ++ print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); ++ } ++} ++ + /* Print information about F in long format. */ + + static void diff --git a/coreutils-selinuxmanpages.patch b/coreutils-selinuxmanpages.patch index c83a583..9cbc166 100644 --- a/coreutils-selinuxmanpages.patch +++ b/coreutils-selinuxmanpages.patch @@ -1,39 +1,6 @@ -diff -urNp coreutils-6.10-orig/doc/coreutils.info coreutils-6.10/doc/coreutils.info ---- coreutils-6.10-orig/doc/coreutils.info 2008-04-07 17:52:11.000000000 +0200 -+++ coreutils-6.10/doc/coreutils.info 2008-04-07 18:03:27.000000000 +0200 -@@ -5642,7 +5642,7 @@ options::. - Preserve as much as possible of the structure and attributes of the - original files in the copy (but do not attempt to preserve internal - directory structure; i.e., `ls -U' may list the entries in a copied -- directory in a different order). Equivalent to `-dpR'. -+ directory in a different order). Equivalent to `-cdpR'. - - `-b' - `--backup[=METHOD]' -@@ -5660,6 +5660,11 @@ options::. - cp --backup --force -- "$i" "$i" - done - -+`-c' -+ Preserve SELinux security context of the original files if possible. -+ Note: Some file systems don't support storing of SELinux security -+ context. -+ - `--copy-contents' - If copying recursively, copy the contents of any special files - (e.g., FIFOs and device files) as if they were regular files. diff -urNp coreutils-6.10-orig/doc/coreutils.texi coreutils-6.10/doc/coreutils.texi --- coreutils-6.10-orig/doc/coreutils.texi 2008-04-07 17:52:11.000000000 +0200 +++ coreutils-6.10/doc/coreutils.texi 2008-04-07 18:01:43.000000000 +0200 -@@ -6957,7 +6957,7 @@ Preserve as much as possible of the stru - original files in the copy (but do not attempt to preserve internal - directory structure; i.e., @samp{ls -U} may list the entries in a copied - directory in a different order). --Equivalent to @option{-dpR}. -+Equivalent to @option{-cdpR}. - - @item -b - @itemx @w{@kbd{--backup}[=@var{method}]} @@ -6981,6 +6981,11 @@ for i; do done @end example diff --git a/coreutils.spec b/coreutils.spec index 7cb0fa8..187840d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,12 +1,13 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 7.0 -Release: 8%{?dist} +Version: 7.1 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.lzma +#Using .tar.gz tarball until xz utils will be in Fedora +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.xterm Source103: coreutils-DIR_COLORS.256color @@ -18,17 +19,10 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -Patch1: coreutils-446294-lsexitstatuses.patch -Patch2: coreutils-7.0-dftotal.patch -Patch3: coreutils-7.0-expr-removebignumoptions.patch -Patch4: coreutils-7.0-cp-mv-n.patch -Patch5: coreutils-7.0-xattr.patch # Our patches Patch100: coreutils-6.10-configuration.patch Patch101: coreutils-6.10-manpages.patch -#Patch102: coreutils-6.10-longoptions.patch -Patch103: coreutils-6.11-sparc-shafix.patch # sh-utils Patch703: sh-utils-2.0.11-dateman.patch @@ -54,15 +48,12 @@ Patch916: coreutils-getfacl-exit-code.patch #(upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch -Patch952: coreutils-463883-chcon-changes.patch BuildRequires: libselinux-devel >= 1.25.6-1 BuildRequires: libacl-devel BuildRequires: gettext bison BuildRequires: texinfo >= 4.3 -BuildRequires: lzma BuildRequires: autoconf >= 2.58 -#dist-lzma required BuildRequires: automake >= 1.10.1 %{?!nopam:BuildRequires: pam-devel} BuildRequires: libcap-devel >= 2.0.6 @@ -107,17 +98,10 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream -%patch1 -p1 -b .lsexit -%patch2 -p1 -b .dftotal -%patch3 -p1 -b .bignum -%patch4 -p1 -b .cpmvn -%patch5 -p1 -b .xattr # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages -#%patch102 -p1 -b .longopt -%patch103 -p1 -b .sparc # sh-utils %patch703 -p1 -b .dateman @@ -134,19 +118,16 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow %patch915 -p1 -b .splitl -#%patch916 -p1 -b .getfacl-exit-code +%patch916 -p1 -b .getfacl-exit-code #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -%patch952 -p1 -b .changeonly chmod a+x tests/misc/sort-mb-tests -chmod a+x tests/misc/id-context -chmod a+x tests/mv/mv-n -chmod a+x tests/misc/xattr sed -i 's/1.10a/1.10.1/' configure.ac +sed -i 's/dist-xz/dist-lzma/' configure.ac #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -328,6 +309,11 @@ fi /sbin/runuser %changelog +* Tue Feb 24 2009 Ondrej Vasik - 7.1-1 +- New upstream release 7.1 (temporarily using tar.gz tarball + as there are no xz utils in Fedora), removed applied + patches, amended patches and LS_COLORS files + * Tue Feb 24 2009 Fedora Release Engineering - 7.0-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild diff --git a/sources b/sources index d845788..3e7e413 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -81c7aecc0daa6cada78005108edb6502 coreutils-7.0.tar.lzma +cbb2b3d1718ee1237b808e00b5c11b1e coreutils-7.1.tar.gz From 4de88fbc58e42c2d3e5d549cc8334541e78c1f6d Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 24 Feb 2009 16:34:43 +0000 Subject: [PATCH 015/523] Rediffed selinux patch(fuzzy), fix fuzz in 2 others --- coreutils-i18n.patch | 2 +- coreutils-pam.patch | 8 +- coreutils-selinux.patch | 725 ++++++++++++++++++++-------------------- 3 files changed, 366 insertions(+), 369 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 4759add..0bb5e06 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2735,7 +2735,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + #include "system.h" #include "error.h" - #include "hard-locale.h" + #include "mbswidth.h" @@ -324,6 +350,18 @@ #include "strftime.h" #include "xstrtol.h" diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 5a5ebfb..5de8f58 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -404,11 +404,11 @@ @node timeout invocation @section @command{timeout}: Run a command with a time limit ---- coreutils-6.7/configure.ac.pam 2006-12-07 21:30:24.000000000 +0000 -+++ coreutils-6.7/configure.ac 2007-01-09 17:18:04.000000000 +0000 +--- coreutils-7.1/configure.ac.pam ++++ coreutils-7.1/configure.ac @@ -44,6 +44,13 @@ - gl_INIT - coreutils_MACROS + [enable compile-time and run-time bounds-checking, and some warnings]) + fi +dnl Give the chance to enable PAM +AC_ARG_ENABLE(pam, dnl diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 5b6c2db..e2ad836 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,7 +1,7 @@ -diff -urp coreutils-7.0.orig/configure.ac coreutils-7.0/configure.ac ---- coreutils-7.0.orig/configure.ac 2009-01-28 17:18:16.790672000 +0100 -+++ coreutils-7.0/configure.ac 2009-01-28 17:18:52.757913913 +0100 -@@ -51,6 +51,13 @@ AC_ARG_ENABLE(pam, dnl +diff -urNp coreutils-7.1-orig/configure.ac coreutils-7.1/configure.ac +--- coreutils-7.1-orig/configure.ac 2009-02-24 13:47:15.000000000 +0100 ++++ coreutils-7.1/configure.ac 2009-02-24 13:47:15.000000000 +0100 +@@ -84,6 +84,13 @@ AC_ARG_ENABLE(pam, dnl LIB_PAM="-ldl -lpam -lpam_misc" AC_SUBST(LIB_PAM)]) @@ -15,18 +15,18 @@ diff -urp coreutils-7.0.orig/configure.ac coreutils-7.0/configure.ac AC_FUNC_FORK optional_bin_progs= -diff -urp coreutils-7.0.orig/man/chcon.x coreutils-7.0/man/chcon.x ---- coreutils-7.0.orig/man/chcon.x 2008-03-07 17:05:53.000000000 +0100 -+++ coreutils-7.0/man/chcon.x 2009-01-28 17:18:52.759913926 +0100 +diff -urNp coreutils-7.1-orig/man/chcon.x coreutils-7.1/man/chcon.x +--- coreutils-7.1-orig/man/chcon.x 2008-09-18 09:06:57.000000000 +0200 ++++ coreutils-7.1/man/chcon.x 2009-02-24 13:47:15.000000000 +0100 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urp coreutils-7.0.orig/man/runcon.x coreutils-7.0/man/runcon.x ---- coreutils-7.0.orig/man/runcon.x 2008-03-07 17:05:53.000000000 +0100 -+++ coreutils-7.0/man/runcon.x 2009-01-28 17:18:52.760913933 +0100 +diff -urNp coreutils-7.1-orig/man/runcon.x coreutils-7.1/man/runcon.x +--- coreutils-7.1-orig/man/runcon.x 2008-09-18 09:06:57.000000000 +0200 ++++ coreutils-7.1/man/runcon.x 2009-02-24 13:47:15.000000000 +0100 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,22 +34,10 @@ diff -urp coreutils-7.0.orig/man/runcon.x coreutils-7.0/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urp coreutils-7.0.orig/src/chcon.c coreutils-7.0/src/chcon.c ---- coreutils-7.0.orig/src/chcon.c 2008-08-24 22:30:10.000000000 +0200 -+++ coreutils-7.0/src/chcon.c 2009-01-28 17:18:52.761913940 +0100 -@@ -366,7 +366,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ - "), - program_name, program_name, program_name); - fputs (_("\ --Change the security context of each FILE to CONTEXT.\n\ -+Change the SELinux security context of each FILE to CONTEXT.\n\ - With --reference, change the security context of each FILE to that of RFILE.\n\ - \n\ - -c, --changes like verbose but report only when a change is made\n\ -diff -urp coreutils-7.0.orig/src/copy.c coreutils-7.0/src/copy.c ---- coreutils-7.0.orig/src/copy.c 2009-01-28 17:18:16.748671000 +0100 -+++ coreutils-7.0/src/copy.c 2009-01-28 17:18:52.762913947 +0100 -@@ -1819,6 +1824,8 @@ copy_internal (char const *src_name, cha +diff -urNp coreutils-7.1-orig/src/copy.c coreutils-7.1/src/copy.c +--- coreutils-7.1-orig/src/copy.c 2009-02-18 15:32:52.000000000 +0100 ++++ coreutils-7.1/src/copy.c 2009-02-24 13:47:15.000000000 +0100 +@@ -1830,6 +1830,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -58,10 +46,10 @@ diff -urp coreutils-7.0.orig/src/copy.c coreutils-7.0/src/copy.c } else { -diff -urp coreutils-7.0.orig/src/copy.h coreutils-7.0/src/copy.h ---- coreutils-7.0.orig/src/copy.h 2009-01-28 17:18:16.748671000 +0100 -+++ coreutils-7.0/src/copy.h 2009-01-28 17:18:52.763913953 +0100 -@@ -141,6 +141,9 @@ struct cp_options +diff -urNp coreutils-7.1-orig/src/copy.h coreutils-7.1/src/copy.h +--- coreutils-7.1-orig/src/copy.h 2009-02-18 15:32:52.000000000 +0100 ++++ coreutils-7.1/src/copy.h 2009-02-24 13:47:15.000000000 +0100 +@@ -140,6 +140,9 @@ struct cp_options bool preserve_mode; bool preserve_timestamps; @@ -71,10 +59,10 @@ diff -urp coreutils-7.0.orig/src/copy.h coreutils-7.0/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c ---- coreutils-7.0.orig/src/cp.c 2009-01-28 17:18:16.750671000 +0100 -+++ coreutils-7.0/src/cp.c 2009-01-28 17:20:29.109561384 +0100 -@@ -148,6 +148,7 @@ static struct option const long_opts[] = +diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c +--- coreutils-7.1-orig/src/cp.c 2009-02-18 15:32:52.000000000 +0100 ++++ coreutils-7.1/src/cp.c 2009-02-24 13:47:15.000000000 +0100 +@@ -133,6 +133,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, {"verbose", no_argument, NULL, 'v'}, @@ -82,7 +70,7 @@ diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -206,6 +207,9 @@ Mandatory arguments to long options are +@@ -191,6 +192,9 @@ Mandatory arguments to long options are all\n\ "), stdout); fputs (_("\ @@ -92,7 +80,7 @@ diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents use full source file name under DIRECTORY\n\ "), stdout); -@@ -231,6 +235,7 @@ Mandatory arguments to long options are +@@ -216,6 +220,7 @@ Mandatory arguments to long options are destination file is missing\n\ -v, --verbose explain what is being done\n\ -x, --one-file-system stay on this file system\n\ @@ -100,15 +88,15 @@ diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); -@@ -780,6 +785,7 @@ cp_option_init (struct cp_options *x) +@@ -765,6 +770,7 @@ cp_option_init (struct cp_options *x) x->preserve_timestamps = false; x->preserve_security_context = false; x->require_preserve_context = false; + x->set_security_context = false; x->preserve_xattr = false; + x->reduce_diagnostics = false; x->require_preserve_xattr = false; - -@@ -925,7 +931,7 @@ main (int argc, char **argv) +@@ -911,7 +917,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -117,7 +105,7 @@ diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c long_opts, NULL)) != -1) { -@@ -956,6 +964,16 @@ main (int argc, char **argv) +@@ -945,6 +951,16 @@ main (int argc, char **argv) copy_contents = true; break; @@ -134,7 +122,7 @@ diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -@@ -1072,6 +1090,27 @@ main (int argc, char **argv) +@@ -1054,6 +1070,27 @@ main (int argc, char **argv) x.one_file_system = true; break; @@ -162,10 +150,22 @@ diff -urp coreutils-7.0.orig/src/cp.c coreutils-7.0/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urp coreutils-7.0.orig/src/id.c coreutils-7.0/src/id.c ---- coreutils-7.0.orig/src/id.c 2008-08-24 22:58:15.000000000 +0200 -+++ coreutils-7.0/src/id.c 2009-01-28 17:18:52.766913973 +0100 -@@ -106,7 +106,7 @@ int +diff -urNp coreutils-7.1-orig/src/chcon.c coreutils-7.1/src/chcon.c +--- coreutils-7.1-orig/src/chcon.c 2008-10-12 16:12:56.000000000 +0200 ++++ coreutils-7.1/src/chcon.c 2009-02-24 13:47:15.000000000 +0100 +@@ -346,7 +346,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ + "), + program_name, program_name, program_name); + fputs (_("\ +-Change the security context of each FILE to CONTEXT.\n\ ++Change the SELinux security context of each FILE to CONTEXT.\n\ + With --reference, change the security context of each FILE to that of RFILE.\n\ + \n\ + -h, --no-dereference affect symbolic links instead of any referenced file\n\ +diff -urNp coreutils-7.1-orig/src/id.c coreutils-7.1/src/id.c +--- coreutils-7.1-orig/src/id.c 2009-02-16 15:57:44.000000000 +0100 ++++ coreutils-7.1/src/id.c 2009-02-24 13:47:15.000000000 +0100 +@@ -107,7 +107,7 @@ int main (int argc, char **argv) { int optc; @@ -174,10 +174,10 @@ diff -urp coreutils-7.0.orig/src/id.c coreutils-7.0/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c ---- coreutils-7.0.orig/src/install.c 2009-01-28 17:18:16.751671000 +0100 -+++ coreutils-7.0/src/install.c 2009-01-28 17:18:52.767913980 +0100 -@@ -152,11 +152,11 @@ static struct option const long_options[ +diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c +--- coreutils-7.1-orig/src/install.c 2009-02-18 15:32:52.000000000 +0100 ++++ coreutils-7.1/src/install.c 2009-02-24 13:47:15.000000000 +0100 +@@ -157,11 +157,11 @@ static struct option const long_options[ {"no-target-directory", no_argument, NULL, 'T'}, {"owner", required_argument, NULL, 'o'}, {"preserve-timestamps", no_argument, NULL, 'p'}, @@ -191,15 +191,15 @@ diff -urp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c {"strip", no_argument, NULL, 's'}, {"strip-program", required_argument, NULL, STRIP_PROGRAM_OPTION}, {"suffix", required_argument, NULL, 'S'}, -@@ -185,6 +185,7 @@ cp_option_init (struct cp_options *x) - x->preserve_timestamps = false; +@@ -292,6 +292,7 @@ cp_option_init (struct cp_options *x) + x->reduce_diagnostics=false; x->require_preserve = false; x->require_preserve_context = false; + x->set_security_context = false; x->require_preserve_xattr = false; x->recursive = false; x->sparse_mode = SPARSE_AUTO; -@@ -361,7 +362,7 @@ main (int argc, char **argv) +@@ -469,7 +470,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -208,7 +208,7 @@ diff -urp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c NULL)) != -1) { switch (optc) -@@ -428,6 +429,7 @@ main (int argc, char **argv) +@@ -539,6 +540,7 @@ main (int argc, char **argv) no_target_directory = true; break; @@ -216,7 +216,7 @@ diff -urp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c case PRESERVE_CONTEXT_OPTION: if ( ! selinux_enabled) { -@@ -435,6 +437,10 @@ main (int argc, char **argv) +@@ -546,6 +548,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } @@ -227,7 +227,7 @@ diff -urp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c x.preserve_security_context = true; use_default_selinux_context = false; break; -@@ -446,6 +452,7 @@ main (int argc, char **argv) +@@ -557,6 +563,7 @@ main (int argc, char **argv) break; } scontext = optarg; @@ -235,7 +235,7 @@ diff -urp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c use_default_selinux_context = false; break; case_GETOPT_HELP_CHAR; -@@ -850,8 +857,8 @@ Mandatory arguments to long options are +@@ -990,8 +997,8 @@ Mandatory arguments to long options are -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ @@ -246,10 +246,10 @@ diff -urp coreutils-7.0.orig/src/install.c coreutils-7.0/src/install.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); -diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c ---- coreutils-7.0.orig/src/ls.c 2009-01-28 17:18:16.705671000 +0100 -+++ coreutils-7.0/src/ls.c 2009-01-28 17:18:52.770914000 +0100 -@@ -139,7 +139,8 @@ enum filetype +diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c +--- coreutils-7.1-orig/src/ls.c 2009-02-20 19:34:02.000000000 +0100 ++++ coreutils-7.1/src/ls.c 2009-02-24 13:47:15.000000000 +0100 +@@ -136,7 +136,8 @@ enum filetype symbolic_link, sock, whiteout, @@ -259,7 +259,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c }; /* Display letters and indicators for each filetype. -@@ -246,6 +248,7 @@ static void queue_directory (char const +@@ -253,6 +254,7 @@ static void queue_directory (char const static void sort_files (void); static void parse_ls_color (void); void usage (int status); @@ -267,7 +267,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c /* Initial size of hash table. Most hierarchies are likely to be shallower than this. */ -@@ -315,7 +318,7 @@ static struct pending *pending_dirs; +@@ -322,7 +324,7 @@ static struct pending *pending_dirs; static struct timespec current_time; @@ -276,7 +276,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c static char UNKNOWN_SECURITY_CONTEXT[] = "?"; /* Whether any of the files has an ACL. This affects the width of the -@@ -355,7 +358,9 @@ enum format +@@ -362,7 +364,9 @@ enum format one_per_line, /* -1 */ many_per_line, /* -C */ horizontal, /* -x */ @@ -287,7 +287,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c }; static enum format format; -@@ -744,6 +749,9 @@ enum +@@ -754,6 +758,9 @@ enum SHOW_CONTROL_CHARS_OPTION, SI_OPTION, SORT_OPTION, @@ -297,7 +297,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c TIME_OPTION, TIME_STYLE_OPTION }; -@@ -789,7 +797,9 @@ static struct option const long_options[ +@@ -799,7 +806,9 @@ static struct option const long_options[ {"time-style", required_argument, NULL, TIME_STYLE_OPTION}, {"color", optional_argument, NULL, COLOR_OPTION}, {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION}, @@ -308,7 +308,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c {"author", no_argument, NULL, AUTHOR_OPTION}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -@@ -799,12 +809,12 @@ static struct option const long_options[ +@@ -809,12 +818,12 @@ static struct option const long_options[ static char const *const format_args[] = { "verbose", "long", "commas", "horizontal", "across", @@ -323,7 +323,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c }; ARGMATCH_VERIFY (format_args, format_types); -@@ -1251,7 +1261,7 @@ main (int argc, char **argv) +@@ -1261,7 +1270,7 @@ main (int argc, char **argv) format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format @@ -332,7 +332,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c || print_block_size; format_needs_type = (! format_needs_stat && (recursive -@@ -1282,7 +1292,7 @@ main (int argc, char **argv) +@@ -1292,7 +1301,7 @@ main (int argc, char **argv) } else do @@ -341,7 +341,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c while (i < argc); if (cwd_n_used) -@@ -1445,7 +1455,7 @@ decode_switches (int argc, char **argv) +@@ -1455,7 +1464,7 @@ decode_switches (int argc, char **argv) ignore_mode = IGNORE_DEFAULT; ignore_patterns = NULL; hide_patterns = NULL; @@ -350,7 +350,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c /* FIXME: put this in a function. */ { -@@ -1827,13 +1837,27 @@ decode_switches (int argc, char **argv) +@@ -1837,13 +1846,27 @@ decode_switches (int argc, char **argv) break; case 'Z': @@ -379,7 +379,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c default: usage (LS_FAILURE); } -@@ -2547,8 +2571,10 @@ clear_files (void) +@@ -2557,8 +2580,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); @@ -392,7 +392,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c } cwd_n_used = 0; -@@ -2590,6 +2616,7 @@ gobble_file (char const *name, enum file +@@ -2600,6 +2625,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -400,16 +400,16 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c if (command_line_arg || format_needs_stat -@@ -2689,7 +2716,7 @@ gobble_file (char const *name, enum file +@@ -2699,7 +2725,7 @@ gobble_file (char const *name, enum file f->stat_ok = true; - if (format == long_format || print_scontext) + if (format == long_format || format == security_format || print_scontext) { + bool have_selinux = false; bool have_acl = false; - int attr_len = (do_deref -@@ -3297,6 +3322,13 @@ print_current_files (void) +@@ -3312,6 +3338,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -423,295 +423,7 @@ diff -urp coreutils-7.0.orig/src/ls.c coreutils-7.0/src/ls.c break; } } -@@ -3482,7 +3514,7 @@ print_long_format (const struct fileinfo - The latter is wrong when inode_number_width is zero. */ - p += strlen (p); - } -- -+ - if (print_block_size) - { - char hbuf[LONGEST_HUMAN_READABLE + 1]; -@@ -3511,9 +3543,15 @@ print_long_format (const struct fileinfo - The latter is wrong when nlink_width is zero. */ - p += strlen (p); - -+ if (print_scontext) -+ { -+ sprintf (p, "%-32s ", f->scontext ? f->scontext : ""); -+ p += strlen (p); -+ } -+ - DIRED_INDENT (); - -- if (print_owner | print_group | print_author | print_scontext) -+ if (print_owner | print_group | print_author) - { - DIRED_FPUTS (buf, stdout, p - buf); - -@@ -3526,9 +3564,6 @@ print_long_format (const struct fileinfo - if (print_author) - format_user (f->stat.st_author, author_width, f->stat_ok); - -- if (print_scontext) -- format_user_or_group (f->scontext, 0, scontext_width); -- - p = buf; - } - -@@ -3867,9 +3902,6 @@ print_file_name_and_frills (const struct - human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, - ST_NBLOCKSIZE, output_block_size)); - -- if (print_scontext) -- printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext); -- - size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), - f->linkok, f->stat_ok, f->filetype, - NULL, f->stat.st_nlink, start_col); -@@ -4077,9 +4109,6 @@ length_of_file_name_and_frills (const st - output_block_size)) - : block_size_width); - -- if (print_scontext) -- len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width); -- - quote_name (NULL, f->name, filename_quoting_options, &name_width); - len += name_width; - -@@ -4510,9 +4539,16 @@ Mandatory arguments to long options are - -w, --width=COLS assume screen width instead of current value\n\ - -x list entries by lines instead of by columns\n\ - -X sort alphabetically by entry extension\n\ -- -Z, --context print any SELinux security context of each file\n\ - -1 list one file per line\n\ - "), stdout); -+ fputs(_("\nSELinux options:\n\n\ -+ --lcontext Display security context. Enable -l. Lines\n\ -+ will probably be too wide for most displays.\n\ -+ -Z, --context Display security context so it fits on most\n\ -+ displays. Displays only mode, user, group,\n\ -+ security context and file name.\n\ -+ --scontext Display only security context and file name.\n\ -+"), stdout); - fputs (HELP_OPTION_DESCRIPTION, stdout); - fputs (VERSION_OPTION_DESCRIPTION, stdout); - fputs (_("\n\ -diff -urp coreutils-7.0.orig/src/mkdir.c coreutils-7.0/src/mkdir.c ---- coreutils-7.0.orig/src/mkdir.c 2008-08-24 22:58:15.000000000 +0200 -+++ coreutils-7.0/src/mkdir.c 2009-01-28 17:18:52.771914007 +0100 -@@ -39,6 +39,7 @@ - static struct option const longopts[] = - { - {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, -+ {"context", required_argument, NULL, 'Z'}, - {"mode", required_argument, NULL, 'm'}, - {"parents", no_argument, NULL, 'p'}, - {"verbose", no_argument, NULL, 'v'}, -diff -urp coreutils-7.0.orig/src/mknod.c coreutils-7.0/src/mknod.c ---- coreutils-7.0.orig/src/mknod.c 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/src/mknod.c 2009-01-28 17:18:52.772914014 +0100 -@@ -35,7 +35,7 @@ - - static struct option const longopts[] = - { -- {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, -+ {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, - {"mode", required_argument, NULL, 'm'}, - {GETOPT_HELP_OPTION_DECL}, - {GETOPT_VERSION_OPTION_DECL}, -diff -urp coreutils-7.0.orig/src/mv.c coreutils-7.0/src/mv.c ---- coreutils-7.0.orig/src/mv.c 2009-01-28 17:18:16.752671000 +0100 -+++ coreutils-7.0/src/mv.c 2009-01-28 17:18:52.773914020 +0100 -@@ -138,6 +138,7 @@ cp_option_init (struct cp_options *x) - x->preserve_mode = true; - x->preserve_timestamps = true; - x->preserve_security_context = selinux_enabled; -+ x->set_security_context = false; - x->reduce_diagnostics = false; - x->require_preserve = false; /* FIXME: maybe make this an option */ - x->require_preserve_context = false; -diff -urp coreutils-7.0.orig/src/runcon.c coreutils-7.0/src/runcon.c ---- coreutils-7.0.orig/src/runcon.c 2008-08-24 22:30:10.000000000 +0200 -+++ coreutils-7.0/src/runcon.c 2009-01-28 17:18:52.774914027 +0100 -@@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ - or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ - "), program_name, program_name); - fputs (_("\ --Run a program in a different security context.\n\ -+Run a program in a different SELinux security context.\n\ - With neither CONTEXT nor COMMAND, print the current security context.\n\ - \n\ - CONTEXT Complete security context\n\ -diff -urp coreutils-7.0.orig/src/stat.c coreutils-7.0/src/stat.c ---- coreutils-7.0.orig/src/stat.c 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/src/stat.c 2009-01-28 17:18:52.775914034 +0100 -@@ -823,7 +823,7 @@ print_it (char const *format, char const - - /* Stat the file system and print what we find. */ - static bool --do_statfs (char const *filename, bool terse, char const *format) -+do_statfs (char const *filename, bool terse, bool secure, char const *format) - { - STRUCT_STATVFS statfsbuf; - -@@ -835,15 +835,31 @@ do_statfs (char const *filename, bool te - } - - if (format == NULL) -+ { -+ if (terse) - { -- format = (terse -- ? "%n %i %l %t %s %S %b %f %a %c %d\n" -- : " File: \"%n\"\n" -- " ID: %-8i Namelen: %-7l Type: %T\n" -- "Block size: %-10s Fundamental block size: %S\n" -- "Blocks: Total: %-10b Free: %-10f Available: %a\n" -- "Inodes: Total: %-10c Free: %d\n"); -+ if (secure) -+ format = "%n %i %l %t %s %S %b %f %a %c %d %C\n"; -+ else -+ format = "%n %i %l %t %s %S %b %f %a %c %d\n"; - } -+ else -+ { -+ if (secure) -+ format = " File: \"%n\"\n" -+ " ID: %-8i Namelen: %-7l Type: %T\n" -+ "Block size: %-10s Fundamental block size: %S\n" -+ "Blocks: Total: %-10b Free: %-10f Available: %a\n" -+ "Inodes: Total: %-10c Free: %d\n" -+ " S_Context: %C\n"; -+ else -+ format = " File: \"%n\"\n" -+ " ID: %-8i Namelen: %-7l Type: %T\n" -+ "Block size: %-10s Fundamental block size: %S\n" -+ "Blocks: Total: %-10b Free: %-10f Available: %a\n" -+ "Inodes: Total: %-10c Free: %d\n"; -+ } -+ } - - print_it (format, filename, print_statfs, &statfsbuf); - return true; -@@ -851,7 +867,7 @@ do_statfs (char const *filename, bool te - - /* stat the file and print what we find */ - static bool --do_stat (char const *filename, bool terse, char const *format) -+do_stat (char const *filename, bool terse, bool secure, char const *format) - { - struct stat statbuf; - -@@ -864,9 +880,12 @@ do_stat (char const *filename, bool ters - if (format == NULL) - { - if (terse) -- { -- format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; -- } -+ { -+ if (secure) -+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"; -+ else -+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; -+ } - else - { - /* Temporary hack to match original output until conditional -@@ -883,12 +902,22 @@ do_stat (char const *filename, bool ters - } - else - { -- format = -- " File: %N\n" -- " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -- "Device: %Dh/%dd\tInode: %-10i Links: %h\n" -- "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -- "Access: %x\n" "Modify: %y\n" "Change: %z\n"; -+ if (secure) -+ format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h" -+ " Device type: %t,%T\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ " S_Context: %C\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; -+ else -+ format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %h\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; - } - } - } -@@ -909,6 +938,7 @@ usage (int status) - Display file or file system status.\n\ - \n\ - -L, --dereference follow links\n\ -+ -Z, --context print the SELinux security context \n\ - -f, --file-system display file system status instead of file status\n\ - "), stdout); - fputs (_("\ -@@ -993,6 +1023,7 @@ main (int argc, char *argv[]) - int i; - bool fs = false; - bool terse = false; -+ bool secure = false; - char *format = NULL; - bool ok = true; - -@@ -1032,13 +1063,13 @@ main (int argc, char *argv[]) - terse = true; - break; - -- case 'Z': /* FIXME: remove in 2010 */ -- /* Ignore, for compatibility with distributions -- that implemented this before upstream. -- But warn of impending removal. */ -- error (0, 0, -- _("the --context (-Z) option is obsolete and will be removed\n" -- "in a future release")); -+ case 'Z': -+ if((is_selinux_enabled()>0)) -+ secure = 1; -+ else { -+ error (0, 0, _("Kernel is not SELinux enabled")); -+ usage (EXIT_FAILURE); -+ } - break; - - case_GETOPT_HELP_CHAR; -@@ -1058,8 +1089,8 @@ main (int argc, char *argv[]) - - for (i = optind; i < argc; i++) - ok &= (fs -- ? do_statfs (argv[i], terse, format) -- : do_stat (argv[i], terse, format)); -+ ? do_statfs (argv[i], terse, secure, format) -+ : do_stat (argv[i], terse, secure, format)); - - exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); - } -diff -urp coreutils-7.0.orig/tests/misc/selinux coreutils-7.0/tests/misc/selinux ---- coreutils-7.0.orig/tests/misc/selinux 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/tests/misc/selinux 2009-01-28 17:18:52.776914041 +0100 -@@ -30,7 +30,7 @@ chcon $ctx f d p || - - # inspect that context with both ls -Z and stat. - for i in d f p; do -- c=`ls -dogZ $i|cut -d' ' -f3`; test x$c = x$ctx || fail=1 -+ c=`ls -dogZ $i|cut -d' ' -f5`; test x$c = x$ctx || fail=1 - c=`stat --printf %C $i`; test x$c = x$ctx || fail=1 - done - -diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c ---- coreutils-7.1-orig/src/ls.c 2009-02-23 17:11:01.000000000 +0100 -+++ coreutils-7.1/src/ls.c 2009-02-23 17:14:27.000000000 +0100 -@@ -3467,6 +3467,69 @@ format_group_width (gid_t g) +@@ -3434,6 +3467,69 @@ format_group_width (gid_t g) } @@ -781,3 +493,288 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c /* Print information about F in long format. */ static void +@@ -3499,7 +3595,7 @@ print_long_format (const struct fileinfo + The latter is wrong when inode_number_width is zero. */ + p += strlen (p); + } +- ++ + if (print_block_size) + { + char hbuf[LONGEST_HUMAN_READABLE + 1]; +@@ -3528,9 +3624,15 @@ print_long_format (const struct fileinfo + The latter is wrong when nlink_width is zero. */ + p += strlen (p); + ++ if (print_scontext) ++ { ++ sprintf (p, "%-32s ", f->scontext ? f->scontext : ""); ++ p += strlen (p); ++ } ++ + DIRED_INDENT (); + +- if (print_owner | print_group | print_author | print_scontext) ++ if (print_owner | print_group | print_author) + { + DIRED_FPUTS (buf, stdout, p - buf); + +@@ -3543,9 +3645,6 @@ print_long_format (const struct fileinfo + if (print_author) + format_user (f->stat.st_author, author_width, f->stat_ok); + +- if (print_scontext) +- format_user_or_group (f->scontext, 0, scontext_width); +- + p = buf; + } + +@@ -3888,9 +3987,6 @@ print_file_name_and_frills (const struct + human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, + ST_NBLOCKSIZE, output_block_size)); + +- if (print_scontext) +- printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext); +- + size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), + f->linkok, f->stat_ok, f->filetype, + NULL, f->stat.st_nlink, start_col); +@@ -4105,9 +4201,6 @@ length_of_file_name_and_frills (const st + output_block_size)) + : block_size_width); + +- if (print_scontext) +- len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width); +- + quote_name (NULL, f->name, filename_quoting_options, &name_width); + len += name_width; + +@@ -4538,9 +4631,16 @@ Mandatory arguments to long options are + -w, --width=COLS assume screen width instead of current value\n\ + -x list entries by lines instead of by columns\n\ + -X sort alphabetically by entry extension\n\ +- -Z, --context print any SELinux security context of each file\n\ + -1 list one file per line\n\ + "), stdout); ++ fputs(_("\nSELinux options:\n\n\ ++ --lcontext Display security context. Enable -l. Lines\n\ ++ will probably be too wide for most displays.\n\ ++ -Z, --context Display security context so it fits on most\n\ ++ displays. Displays only mode, user, group,\n\ ++ security context and file name.\n\ ++ --scontext Display only security context and file name.\n\ ++"), stdout); + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); + fputs (_("\n\ +diff -urNp coreutils-7.1-orig/src/mkdir.c coreutils-7.1/src/mkdir.c +--- coreutils-7.1-orig/src/mkdir.c 2008-10-19 21:47:57.000000000 +0200 ++++ coreutils-7.1/src/mkdir.c 2009-02-24 13:47:15.000000000 +0100 +@@ -38,6 +38,7 @@ + static struct option const longopts[] = + { + {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, ++ {"context", required_argument, NULL, 'Z'}, + {"mode", required_argument, NULL, 'm'}, + {"parents", no_argument, NULL, 'p'}, + {"verbose", no_argument, NULL, 'v'}, +diff -urNp coreutils-7.1-orig/src/mknod.c coreutils-7.1/src/mknod.c +--- coreutils-7.1-orig/src/mknod.c 2008-09-22 16:01:21.000000000 +0200 ++++ coreutils-7.1/src/mknod.c 2009-02-24 13:47:15.000000000 +0100 +@@ -35,7 +35,7 @@ + + static struct option const longopts[] = + { +- {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, ++ {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, + {"mode", required_argument, NULL, 'm'}, + {GETOPT_HELP_OPTION_DECL}, + {GETOPT_VERSION_OPTION_DECL}, +diff -urNp coreutils-7.1-orig/src/mv.c coreutils-7.1/src/mv.c +--- coreutils-7.1-orig/src/mv.c 2009-02-18 15:32:52.000000000 +0100 ++++ coreutils-7.1/src/mv.c 2009-02-24 13:47:15.000000000 +0100 +@@ -122,6 +122,7 @@ cp_option_init (struct cp_options *x) + x->preserve_mode = true; + x->preserve_timestamps = true; + x->preserve_security_context = selinux_enabled; ++ x->set_security_context = false; + x->reduce_diagnostics = false; + x->require_preserve = false; /* FIXME: maybe make this an option */ + x->require_preserve_context = false; +diff -urNp coreutils-7.1-orig/src/runcon.c coreutils-7.1/src/runcon.c +--- coreutils-7.1-orig/src/runcon.c 2008-09-18 09:06:57.000000000 +0200 ++++ coreutils-7.1/src/runcon.c 2009-02-24 13:47:15.000000000 +0100 +@@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ + or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ + "), program_name, program_name); + fputs (_("\ +-Run a program in a different security context.\n\ ++Run a program in a different SELinux security context.\n\ + With neither CONTEXT nor COMMAND, print the current security context.\n\ + \n\ + CONTEXT Complete security context\n\ +diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c +--- coreutils-7.1-orig/src/stat.c 2009-01-27 22:11:25.000000000 +0100 ++++ coreutils-7.1/src/stat.c 2009-02-24 13:47:15.000000000 +0100 +@@ -825,7 +825,7 @@ print_it (char const *format, char const + + /* Stat the file system and print what we find. */ + static bool +-do_statfs (char const *filename, bool terse, char const *format) ++do_statfs (char const *filename, bool terse, bool secure, char const *format) + { + STRUCT_STATVFS statfsbuf; + +@@ -837,15 +837,31 @@ do_statfs (char const *filename, bool te + } + + if (format == NULL) ++ { ++ if (terse) + { +- format = (terse +- ? "%n %i %l %t %s %S %b %f %a %c %d\n" +- : " File: \"%n\"\n" +- " ID: %-8i Namelen: %-7l Type: %T\n" +- "Block size: %-10s Fundamental block size: %S\n" +- "Blocks: Total: %-10b Free: %-10f Available: %a\n" +- "Inodes: Total: %-10c Free: %d\n"); ++ if (secure) ++ format = "%n %i %l %t %s %S %b %f %a %c %d %C\n"; ++ else ++ format = "%n %i %l %t %s %S %b %f %a %c %d\n"; + } ++ else ++ { ++ if (secure) ++ format = " File: \"%n\"\n" ++ " ID: %-8i Namelen: %-7l Type: %T\n" ++ "Block size: %-10s Fundamental block size: %S\n" ++ "Blocks: Total: %-10b Free: %-10f Available: %a\n" ++ "Inodes: Total: %-10c Free: %d\n" ++ " S_Context: %C\n"; ++ else ++ format = " File: \"%n\"\n" ++ " ID: %-8i Namelen: %-7l Type: %T\n" ++ "Block size: %-10s Fundamental block size: %S\n" ++ "Blocks: Total: %-10b Free: %-10f Available: %a\n" ++ "Inodes: Total: %-10c Free: %d\n"; ++ } ++ } + + print_it (format, filename, print_statfs, &statfsbuf); + return true; +@@ -853,7 +869,7 @@ do_statfs (char const *filename, bool te + + /* stat the file and print what we find */ + static bool +-do_stat (char const *filename, bool terse, char const *format) ++do_stat (char const *filename, bool terse, bool secure, char const *format) + { + struct stat statbuf; + +@@ -866,9 +882,12 @@ do_stat (char const *filename, bool ters + if (format == NULL) + { + if (terse) +- { +- format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; +- } ++ { ++ if (secure) ++ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"; ++ else ++ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; ++ } + else + { + /* Temporary hack to match original output until conditional +@@ -885,12 +904,22 @@ do_stat (char const *filename, bool ters + } + else + { +- format = +- " File: %N\n" +- " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" +- "Device: %Dh/%dd\tInode: %-10i Links: %h\n" +- "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" +- "Access: %x\n" "Modify: %y\n" "Change: %z\n"; ++ if (secure) ++ format = ++ " File: %N\n" ++ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" ++ "Device: %Dh/%dd\tInode: %-10i Links: %-5h" ++ " Device type: %t,%T\n" ++ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" ++ " S_Context: %C\n" ++ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; ++ else ++ format = ++ " File: %N\n" ++ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" ++ "Device: %Dh/%dd\tInode: %-10i Links: %h\n" ++ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" ++ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + } + } + } +@@ -911,6 +940,7 @@ usage (int status) + Display file or file system status.\n\ + \n\ + -L, --dereference follow links\n\ ++ -Z, --context print the SELinux security context \n\ + -f, --file-system display file system status instead of file status\n\ + "), stdout); + fputs (_("\ +@@ -995,6 +1025,7 @@ main (int argc, char *argv[]) + int i; + bool fs = false; + bool terse = false; ++ bool secure = false; + char *format = NULL; + bool ok = true; + +@@ -1034,13 +1065,13 @@ main (int argc, char *argv[]) + terse = true; + break; + +- case 'Z': /* FIXME: remove in 2010 */ +- /* Ignore, for compatibility with distributions +- that implemented this before upstream. +- But warn of impending removal. */ +- error (0, 0, +- _("the --context (-Z) option is obsolete and will be removed\n" +- "in a future release")); ++ case 'Z': ++ if((is_selinux_enabled()>0)) ++ secure = 1; ++ else { ++ error (0, 0, _("Kernel is not SELinux enabled")); ++ usage (EXIT_FAILURE); ++ } + break; + + case_GETOPT_HELP_CHAR; +@@ -1060,8 +1091,8 @@ main (int argc, char *argv[]) + + for (i = optind; i < argc; i++) + ok &= (fs +- ? do_statfs (argv[i], terse, format) +- : do_stat (argv[i], terse, format)); ++ ? do_statfs (argv[i], terse, secure, format) ++ : do_stat (argv[i], terse, secure, format)); + + exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); + } +diff -urNp coreutils-7.1-orig/tests/misc/selinux coreutils-7.1/tests/misc/selinux +--- coreutils-7.1-orig/tests/misc/selinux 2008-10-25 14:20:26.000000000 +0200 ++++ coreutils-7.1/tests/misc/selinux 2009-02-24 13:47:15.000000000 +0100 +@@ -30,7 +30,7 @@ chcon $ctx f d p || + + # inspect that context with both ls -Z and stat. + for i in d f p; do +- c=`ls -dogZ $i|cut -d' ' -f3`; test x$c = x$ctx || fail=1 ++ c=`ls -dogZ $i|cut -d' ' -f5`; test x$c = x$ctx || fail=1 + c=`stat --printf %C $i`; test x$c = x$ctx || fail=1 + done + From be82102c5b70e23b5469eb22e01acd9dee43bae6 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 25 Feb 2009 13:13:05 +0000 Subject: [PATCH 016/523] workaround libcap issue, move i18n testsuite tuning to i18n, fix gnulib testsuite failure with multiple skip exit codes --- coreutils-6.10-configuration.patch | 93 +++++++++++++++++++----------- coreutils-i18n.patch | 23 ++++++++ coreutils.spec | 7 ++- 3 files changed, 88 insertions(+), 35 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 0818bd2..0571ea6 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,26 +1,3 @@ -diff -urN coreutils-6.12-orig/tests/misc/cut coreutils-6.12/tests/misc/cut ---- coreutils-6.12-orig/tests/misc/cut 2008-05-17 08:41:11.000000000 +0200 -+++ coreutils-6.12/tests/misc/cut 2008-06-02 11:13:08.000000000 +0200 -@@ -26,7 +26,7 @@ - my $prog = 'cut'; - my $try = "Try \`$prog --help' for more information.\n"; - my $from_1 = "$prog: fields and positions are numbered from 1\n$try"; --my $inval = "$prog: invalid byte or field list\n$try"; -+my $inval = "$prog: invalid byte, character or field list\n$try"; - my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; - - my @Tests = -@@ -140,8 +140,8 @@ - ['od-overlap5', '-b1-3,1-4', '--output-d=:', {IN=>"abcde\n"}, {OUT=>"abcd\n"}], - - # None of the following invalid ranges provoked an error up to coreutils-6.9. -- ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, -- {ERR=>"$prog: invalid decreasing range\n$try"}], -+ ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, -+ {ERR=>"$prog: invalid byte, character or field list\n$try"}], - ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], - ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], - ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], diff -urN coreutils-6.11-orig/tests/mkdir/selinux coreutils-6.11/tests/mkdir/selinux --- coreutils-6.11-orig/tests/mkdir/selinux 2008-04-19 23:34:23.000000000 +0200 +++ coreutils-6.11/tests/mkdir/selinux 2008-04-22 13:23:50.000000000 +0200 @@ -46,17 +23,65 @@ diff -urNp coreutils-6.11-orig/tests/test-lib.sh coreutils-6.11/tests/test-lib.s skip_test_ "this system (or maybe just" \ "the current file system) lacks SELinux support" ;; -diff -urp coreutils-6.11-orig/gnulib-tests/test-getaddrinfo.c coreutils-6.11/gnulib-tests/test-getaddrinfo.c ---- coreutils-6.11-orig/gnulib-tests/test-getaddrinfo.c -+++ coreutils-6.11/gnulib-tests/test-getaddrinfo.c -@@ -70,6 +70,10 @@ int simple (char *host, char *service) - if (res == EAI_NODATA) - return 0; +diff -urNp coreutils-7.1-orig/gnulib-tests/test-getaddrinfo.c coreutils-7.1/gnulib-tests/test-getaddrinfo.c +--- coreutils-7.1-orig/gnulib-tests/test-getaddrinfo.c 2009-01-27 21:33:19.000000000 +0100 ++++ coreutils-7.1/gnulib-tests/test-getaddrinfo.c 2009-02-25 13:52:59.000000000 +0100 +@@ -36,6 +36,8 @@ + # define dbgprintf if (0) printf + #endif -+ /* Do not fail this test for temporary name resolution errors. */ -+ if (res == EAI_AGAIN) -+ return 0; ++static int skip = 0; + - return 1; - } + /* BeOS does not have AF_UNSPEC. */ + #ifndef AF_UNSPEC + # define AF_UNSPEC 0 +@@ -52,6 +54,9 @@ int simple (char *host, char *service) + struct addrinfo *ai0, *ai; + int res; ++ if (skip) ++ return 0; ++ + dbgprintf ("Finding %s service %s...\n", host, service); + + /* This initializes "hints" but does not use it. Is there a reason +@@ -72,8 +77,12 @@ int simple (char *host, char *service) + in-law's farm. */ + if (res == EAI_AGAIN) + { +- fprintf (stderr, "skipping getaddrinfo test: no network?\n"); +- return 77; ++ if (!skip) ++ { ++ skip++; ++ fprintf (stderr, "skipping getaddrinfo test: no network?\n"); ++ return 77; ++ } + } + /* IRIX reports EAI_NONAME for "https". Don't fail the test + merely because of this. */ +diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c +--- coreutils-7.1-orig/src/ls.c 2009-02-25 13:23:59.000000000 +0100 ++++ coreutils-7.1/src/ls.c 2009-02-25 13:25:20.000000000 +0100 +@@ -38,10 +38,6 @@ + #include + #include + +-#ifdef HAVE_CAP +-# include +-#endif +- + #if HAVE_TERMIOS_H + # include + #endif +@@ -84,6 +80,10 @@ + #include "system.h" + #include + ++#ifdef HAVE_CAP ++# include ++#endif ++ + #include "acl.h" + #include "argmatch.h" + #include "dev-ino.h" diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 0bb5e06..cd5852a 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,3 +1,26 @@ +diff -urN coreutils-6.12-orig/tests/misc/cut coreutils-6.12/tests/misc/cut +--- coreutils-6.12-orig/tests/misc/cut 2008-05-17 08:41:11.000000000 +0200 ++++ coreutils-6.12/tests/misc/cut 2008-06-02 11:13:08.000000000 +0200 +@@ -26,7 +26,7 @@ + my $prog = 'cut'; + my $try = "Try \`$prog --help' for more information.\n"; + my $from_1 = "$prog: fields and positions are numbered from 1\n$try"; +-my $inval = "$prog: invalid byte or field list\n$try"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; + my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; + + my @Tests = +@@ -140,8 +140,8 @@ + ['od-overlap5', '-b1-3,1-4', '--output-d=:', {IN=>"abcde\n"}, {OUT=>"abcd\n"}], + + # None of the following invalid ranges provoked an error up to coreutils-6.9. +- ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, +- {ERR=>"$prog: invalid decreasing range\n$try"}], ++ ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, ++ {ERR=>"$prog: invalid byte, character or field list\n$try"}], + ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], + ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], + ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], --- /dev/null 2007-03-01 09:16:39.219409909 +0000 +++ coreutils-6.8+/tests/misc/sort-mb-tests 2007-03-01 15:08:24.000000000 +0000 @@ -0,0 +1,58 @@ diff --git a/coreutils.spec b/coreutils.spec index 187840d..cedba46 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.1 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -309,6 +309,11 @@ fi /sbin/runuser %changelog +* Wed Feb 25 2009 Ondrej Vasik 7.1-2 +- workaround libcap issue with broken headers (#483548) +- fix gnulib testsuite failure (4x77 (skip) is not + 77(skip) ;) ) + * Tue Feb 24 2009 Ondrej Vasik - 7.1-1 - New upstream release 7.1 (temporarily using tar.gz tarball as there are no xz utils in Fedora), removed applied From 49c94e6cef07e165fc38d4fc5d2dd189813a461b Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 25 Feb 2009 15:36:19 +0000 Subject: [PATCH 017/523] fix couple of bugs in sort with determining end of fields (upstream) - includes #485715 fix --- coreutils-7.1-sort-endoffields.patch | 86 ++++++++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 coreutils-7.1-sort-endoffields.patch diff --git a/coreutils-7.1-sort-endoffields.patch b/coreutils-7.1-sort-endoffields.patch new file mode 100644 index 0000000..22e336f --- /dev/null +++ b/coreutils-7.1-sort-endoffields.patch @@ -0,0 +1,86 @@ +diff -urNp coreutils-7.1-orig/src/sort.c coreutils-7.1/src/sort.c +--- coreutils-7.1-orig/src/sort.c 2009-02-25 16:15:52.000000000 +0100 ++++ coreutils-7.1/src/sort.c 2009-02-25 16:20:35.000000000 +0100 +@@ -1598,6 +1598,9 @@ limfield_uni (const struct line *line, c + size_t eword = key->eword, echar = key->echar; + size_t remaining_bytes; + ++ if (echar == 0) ++ eword++; /* skip all of end field. */ ++ + /* Move PTR past EWORD fields or to one past the last byte on LINE, + whichever comes first. If there are more than EWORD fields, leave + PTR pointing at the beginning of the field having zero-based index, +@@ -1673,19 +1676,22 @@ limfield_uni (const struct line *line, c + } + #endif + +- /* If we're ignoring leading blanks when computing the End +- of the field, don't start counting bytes until after skipping +- past any leading blanks. */ +- if (key->skipeblanks) +- while (ptr < lim && blanks[to_uchar (*ptr)]) +- ++ptr; + +- /* Advance PTR by ECHAR (if possible), but no further than LIM. */ +- remaining_bytes = lim - ptr; +- if (echar < remaining_bytes) +- ptr += echar; +- else +- ptr = lim; ++ if (echar != 0) /* We need to skip over a portion of the end field. */ ++ { ++ if (key->skipeblanks) /* blanks not counted in echar. */ ++ { ++ while (ptr < lim && blanks[to_uchar (*ptr)]) ++ ++ptr; ++ } ++ ++ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ ++ remaining_bytes = lim - ptr; ++ if (echar < remaining_bytes) ++ ptr += echar; ++ else ++ ptr = lim; ++ } + + return ptr; + } +@@ -3736,12 +3742,9 @@ main (int argc, char **argv) + badfieldspec (optarg, N_("field number is zero")); + } + if (*s == '.') +- s = parse_field_count (s + 1, &key->echar, +- N_("invalid number after `.'")); +- else + { +- /* `-k 2,3' is equivalent to `+1 -3'. */ +- key->eword++; ++ s = parse_field_count (s + 1, &key->echar, ++ N_("invalid number after `.'")); + } + s = set_ordering (s, key, bl_end); + } +diff -urNp coreutils-7.1-orig/tests/misc/sort coreutils-7.1/tests/misc/sort +--- coreutils-7.1-orig/tests/misc/sort 2009-01-27 22:11:25.000000000 +0100 ++++ coreutils-7.1/tests/misc/sort 2009-02-25 16:21:48.000000000 +0100 +@@ -110,6 +110,8 @@ my @Tests = + ["07b", '-k 2,3', {IN=>"a a b\nz a a\n"}, {OUT=>"z a a\na a b\n"}], + ["07c", '-k 2,3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], + ["07d", '+1 -3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], ++["07e", '-k 2,3.0', {IN=>"a a b\nz a a\n"}, {OUT=>"z a a\na a b\n"}], ++ + # + # report an error for `.' without following char spec + ["08a", '-k 2.,3', {EXIT=>2}, +@@ -210,6 +212,10 @@ my @Tests = + # key start and key end. + ["18e", '-nb -k1.1,1.2', {IN=>" 901\n100\n"}, {OUT=>"100\n 901\n"}], + ++# When ignoring leading blanks for end position, ensure blanks from ++# next field are not included in the sort. I.E. order should not change here. ++["18f", '-k1,1b', {IN=>"a y\na z\n"}, {OUT=>"a y\na z\n"}], ++ + # This looks odd, but works properly -- 2nd keyspec is never + # used because all lines are different. + ["19a", '+0 +1nr', {IN=>"b 2\nb 1\nb 3\n"}, {OUT=>"b 1\nb 2\nb 3\n"}], diff --git a/coreutils.spec b/coreutils.spec index cedba46..a9836da 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.1 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -19,6 +19,7 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream +Patch1: coreutils-7.1-sort-endoffields.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -98,6 +99,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream +%patch1 -p1 -b .endfield # Our patches %patch100 -p1 -b .configure @@ -309,6 +311,10 @@ fi /sbin/runuser %changelog +* Wed Feb 25 2009 Ondrej Vasik 7.1-3 +- fix couple of bugs (including #485715) in sort with + determining end of fields(upstream) + * Wed Feb 25 2009 Ondrej Vasik 7.1-2 - workaround libcap issue with broken headers (#483548) - fix gnulib testsuite failure (4x77 (skip) is not From a359684b15f1d90c7c418422a866efbdd7322810 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 26 Feb 2009 13:44:18 +0000 Subject: [PATCH 018/523] fix showing ACL's for ls -Z (#487374), fix automatic column width for names/groups for it as well --- coreutils-selinux.patch | 92 ++++++++++++++++++++++++++++++----------- coreutils.spec | 6 ++- 2 files changed, 74 insertions(+), 24 deletions(-) diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index e2ad836..247a879 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -323,7 +323,26 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c }; ARGMATCH_VERIFY (format_args, format_types); -@@ -1261,7 +1270,7 @@ main (int argc, char **argv) +@@ -1194,7 +1203,8 @@ main (int argc, char **argv) + /* Avoid following symbolic links when possible. */ + if (is_colored (C_ORPHAN) + || (is_colored (C_EXEC) && color_symlink_as_referent) +- || (is_colored (C_MISSING) && format == long_format)) ++ || (is_colored (C_MISSING) && (format == long_format ++ || format == security_format))) + check_symlink_color = true; + + /* If the standard output is a controlling terminal, watch out +@@ -1241,7 +1251,7 @@ main (int argc, char **argv) + if (dereference == DEREF_UNDEFINED) + dereference = ((immediate_dirs + || indicator_style == classify +- || format == long_format) ++ || format == long_format || format == security_format) + ? DEREF_NEVER + : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); + +@@ -1261,7 +1271,7 @@ main (int argc, char **argv) format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format @@ -332,7 +351,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c || print_block_size; format_needs_type = (! format_needs_stat && (recursive -@@ -1292,7 +1301,7 @@ main (int argc, char **argv) +@@ -1292,7 +1302,7 @@ main (int argc, char **argv) } else do @@ -341,7 +360,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c while (i < argc); if (cwd_n_used) -@@ -1455,7 +1464,7 @@ decode_switches (int argc, char **argv) +@@ -1455,7 +1465,7 @@ decode_switches (int argc, char **argv) ignore_mode = IGNORE_DEFAULT; ignore_patterns = NULL; hide_patterns = NULL; @@ -350,7 +369,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c /* FIXME: put this in a function. */ { -@@ -1837,13 +1846,27 @@ decode_switches (int argc, char **argv) +@@ -1837,13 +1847,27 @@ decode_switches (int argc, char **argv) break; case 'Z': @@ -379,7 +398,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c default: usage (LS_FAILURE); } -@@ -2557,8 +2580,10 @@ clear_files (void) +@@ -2557,8 +2581,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); @@ -392,7 +411,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c } cwd_n_used = 0; -@@ -2600,6 +2625,7 @@ gobble_file (char const *name, enum file +@@ -2600,6 +2626,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -400,7 +419,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c if (command_line_arg || format_needs_stat -@@ -2699,7 +2725,7 @@ gobble_file (char const *name, enum file +@@ -2699,7 +2726,7 @@ gobble_file (char const *name, enum file f->stat_ok = true; @@ -409,7 +428,43 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c { bool have_selinux = false; bool have_acl = false; -@@ -3312,6 +3338,13 @@ print_current_files (void) +@@ -2732,7 +2760,7 @@ gobble_file (char const *name, enum file + err = 0; + } + +- if (err == 0 && format == long_format) ++ if (err == 0 && (format == long_format || format == security_format)) + { + int n = file_has_acl (absolute_name, &f->stat); + err = (n < 0); +@@ -2751,7 +2779,8 @@ gobble_file (char const *name, enum file + } + + if (S_ISLNK (f->stat.st_mode) +- && (format == long_format || check_symlink_color)) ++ && (format == long_format || format == security_format ++ || check_symlink_color)) + { + char *linkname; + struct stat linkstats; +@@ -2771,6 +2800,7 @@ gobble_file (char const *name, enum file + command line are automatically traced if not being + listed as files. */ + if (!command_line_arg || format == long_format ++ || format == security_format + || !S_ISDIR (linkstats.st_mode)) + { + /* Get the linked-to file's mode for the filetype indicator +@@ -2810,7 +2840,7 @@ gobble_file (char const *name, enum file + block_size_width = len; + } + +- if (format == long_format) ++ if (format == long_format || format == security_format) + { + if (print_owner) + { +@@ -3312,6 +3341,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -423,7 +478,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c break; } } -@@ -3434,6 +3467,69 @@ format_group_width (gid_t g) +@@ -3434,6 +3470,69 @@ format_group_width (gid_t g) } @@ -493,16 +548,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c /* Print information about F in long format. */ static void -@@ -3499,7 +3595,7 @@ print_long_format (const struct fileinfo - The latter is wrong when inode_number_width is zero. */ - p += strlen (p); - } -- -+ - if (print_block_size) - { - char hbuf[LONGEST_HUMAN_READABLE + 1]; -@@ -3528,9 +3624,15 @@ print_long_format (const struct fileinfo +@@ -3528,9 +3627,15 @@ print_long_format (const struct fileinfo The latter is wrong when nlink_width is zero. */ p += strlen (p); @@ -519,7 +565,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c { DIRED_FPUTS (buf, stdout, p - buf); -@@ -3543,9 +3645,6 @@ print_long_format (const struct fileinfo +@@ -3543,9 +3648,6 @@ print_long_format (const struct fileinfo if (print_author) format_user (f->stat.st_author, author_width, f->stat_ok); @@ -529,7 +575,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c p = buf; } -@@ -3888,9 +3987,6 @@ print_file_name_and_frills (const struct +@@ -3888,9 +3990,6 @@ print_file_name_and_frills (const struct human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ST_NBLOCKSIZE, output_block_size)); @@ -539,7 +585,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, f->stat_ok, f->filetype, NULL, f->stat.st_nlink, start_col); -@@ -4105,9 +4201,6 @@ length_of_file_name_and_frills (const st +@@ -4105,9 +4204,6 @@ length_of_file_name_and_frills (const st output_block_size)) : block_size_width); @@ -549,7 +595,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c quote_name (NULL, f->name, filename_quoting_options, &name_width); len += name_width; -@@ -4538,9 +4631,16 @@ Mandatory arguments to long options are +@@ -4538,9 +4634,16 @@ Mandatory arguments to long options are -w, --width=COLS assume screen width instead of current value\n\ -x list entries by lines instead of by columns\n\ -X sort alphabetically by entry extension\n\ diff --git a/coreutils.spec b/coreutils.spec index a9836da..9025a1b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.1 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -311,6 +311,10 @@ fi /sbin/runuser %changelog +* Thu Feb 26 2009 Ondrej Vasik 7.1-4 +- fix showing ACL's for ls -Z (#487374), fix automatic + column width for it as well + * Wed Feb 25 2009 Ondrej Vasik 7.1-3 - fix couple of bugs (including #485715) in sort with determining end of fields(upstream) From 9a1c0e27276d66a3663b432d019ea3bd7e8bd437 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 26 Feb 2009 16:28:44 +0000 Subject: [PATCH 019/523] fix showing ACL's for ls -Z (#487374), fix automatic column width computation for it as well, fix couple of bugs (including #485715) in sort with determining end of fields (upstream) --- coreutils-6.12-sort-endoffields.patch | 101 ++++++++++++++++++++++++++ coreutils-selinux.patch | 82 ++++++++++++++++----- coreutils.spec | 10 ++- 3 files changed, 174 insertions(+), 19 deletions(-) create mode 100644 coreutils-6.12-sort-endoffields.patch diff --git a/coreutils-6.12-sort-endoffields.patch b/coreutils-6.12-sort-endoffields.patch new file mode 100644 index 0000000..997feef --- /dev/null +++ b/coreutils-6.12-sort-endoffields.patch @@ -0,0 +1,101 @@ +diff -urNp coreutils-6.12-orig/src/sort.c coreutils-6.12/src/sort.c +--- coreutils-6.12-orig/src/sort.c 2009-02-26 16:01:04.000000000 +0100 ++++ coreutils-6.12/src/sort.c 2009-02-26 16:24:27.000000000 +0100 +@@ -1390,7 +1390,6 @@ begfield_uni (const struct line *line, c + char *ptr = line->text, *lim = ptr + line->length - 1; + size_t sword = key->sword; + size_t schar = key->schar; +- size_t remaining_bytes; + + /* The leading field separator itself is included in a field when -t + is absent. */ +@@ -1416,12 +1415,7 @@ begfield_uni (const struct line *line, c + while (ptr < lim && blanks[to_uchar (*ptr)]) + ++ptr; + +- /* Advance PTR by SCHAR (if possible), but no further than LIM. */ +- remaining_bytes = lim - ptr; +- if (schar < remaining_bytes) +- ptr += schar; +- else +- ptr = lim; ++ ptr = MIN (lim, ptr + schar); + + return ptr; + } +@@ -1493,7 +1487,9 @@ limfield_uni (const struct line *line, c + { + char *ptr = line->text, *lim = ptr + line->length - 1; + size_t eword = key->eword, echar = key->echar; +- size_t remaining_bytes; ++ ++ if (echar == 0) ++ eword++; /* Skip all of end field. */ + + /* Move PTR past EWORD fields or to one past the last byte on LINE, + whichever comes first. If there are more than EWORD fields, leave +@@ -1566,19 +1566,13 @@ limfield_uni (const struct line *line, c + } + #endif + +- /* If we're ignoring leading blanks when computing the End +- of the field, don't start counting bytes until after skipping +- past any leading blanks. */ +- if (key->skipeblanks) +- while (ptr < lim && blanks[to_uchar (*ptr)]) +- ++ptr; +- +- /* Advance PTR by ECHAR (if possible), but no further than LIM. */ +- remaining_bytes = lim - ptr; +- if (echar < remaining_bytes) +- ptr += echar; +- else +- ptr = lim; ++ if (echar != 0) /* We need to skip over a portion of the end field. */ ++ { ++ if (key->skipeblanks) /* blanks not counted in echar. */ ++ while (ptr < lim && blanks[to_uchar (*ptr)]) ++ ++ptr; ++ ptr = MIN (lim, ptr + echar); ++ } + + return ptr; + } +@@ -3582,12 +3579,9 @@ main (int argc, char **argv) + badfieldspec (optarg, N_("field number is zero")); + } + if (*s == '.') +- s = parse_field_count (s + 1, &key->echar, +- N_("invalid number after `.'")); +- else + { +- /* `-k 2,3' is equivalent to `+1 -3'. */ +- key->eword++; ++ s = parse_field_count (s + 1, &key->echar, ++ N_("invalid number after `.'")); + } + s = set_ordering (s, key, bl_end); + } +diff -urNp coreutils-6.12-orig/tests/misc/sort coreutils-6.12/tests/misc/sort +--- coreutils-6.12-orig/tests/misc/sort 2008-05-17 08:41:12.000000000 +0200 ++++ coreutils-6.12/tests/misc/sort 2009-02-26 16:25:39.000000000 +0100 +@@ -108,6 +108,8 @@ my @Tests = + ["07b", '-k 2,3', {IN=>"a a b\nz a a\n"}, {OUT=>"z a a\na a b\n"}], + ["07c", '-k 2,3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], + ["07d", '+1 -3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], ++#ensure a character position of 0 includes whole field ++["07e", '-k 2,3.0', {IN=>"a a b\nz a a\n"}, {OUT=>"z a a\na a b\n"}], + # + # report an error for `.' without following char spec + ["08a", '-k 2.,3', {EXIT=>2}, +@@ -208,6 +210,10 @@ my @Tests = + # key start and key end. + ["18e", '-nb -k1.1,1.2', {IN=>" 901\n100\n"}, {OUT=>"100\n 901\n"}], + ++# When ignoring leading blanks for end position, ensure blanks from ++# next field are not included in the sort. I.E. order should not change here. ++["18f", '-k1,1b', {IN=>"a y\na z\n"}, {OUT=>"a y\na z\n"}], ++ + # This looks odd, but works properly -- 2nd keyspec is never + # used because all lines are different. + ["19a", '+0 +1nr', {IN=>"b 2\nb 1\nb 3\n"}, {OUT=>"b 1\nb 2\nb 3\n"}], diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 56b17f8..7dd868b 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -442,7 +442,26 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c }; ARGMATCH_VERIFY (format_args, format_types); -@@ -1236,7 +1245,7 @@ main (int argc, char **argv) +@@ -1169,7 +1175,8 @@ main (int argc, char **argv) + /* Avoid following symbolic links when possible. */ + if (is_colored (C_ORPHAN) + || (is_colored (C_EXEC) && color_symlink_as_referent) +- || (is_colored (C_MISSING) && format == long_format)) ++ || (is_colored (C_MISSING) && (format == long_format ++ || format == security_format))) + check_symlink_color = true; + + /* If the standard output is a controlling terminal, watch out +@@ -1219,7 +1226,7 @@ main (int argc, char **argv) + if (dereference == DEREF_UNDEFINED) + dereference = ((immediate_dirs + || indicator_style == classify +- || format == long_format) ++ || format == long_format || format == security_format) + ? DEREF_NEVER + : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); + +@@ -1236,7 +1246,7 @@ main (int argc, char **argv) format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format @@ -451,7 +470,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c || print_block_size; format_needs_type = (! format_needs_stat && (recursive -@@ -1267,7 +1276,7 @@ main (int argc, char **argv) +@@ -1267,7 +1277,7 @@ main (int argc, char **argv) } else do @@ -460,7 +479,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c while (i < argc); if (cwd_n_used) -@@ -1429,7 +1438,7 @@ decode_switches (int argc, char **argv) +@@ -1429,7 +1439,7 @@ decode_switches (int argc, char **argv) ignore_mode = IGNORE_DEFAULT; ignore_patterns = NULL; hide_patterns = NULL; @@ -469,7 +488,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c /* FIXME: put this in a function. */ { -@@ -1811,13 +1820,27 @@ decode_switches (int argc, char **argv) +@@ -1811,13 +1821,27 @@ decode_switches (int argc, char **argv) break; case 'Z': @@ -498,7 +517,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c default: usage (LS_FAILURE); } -@@ -2517,8 +2540,10 @@ clear_files (void) +@@ -2517,8 +2541,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); @@ -511,7 +530,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c } cwd_n_used = 0; -@@ -2560,6 +2585,7 @@ gobble_file (char const *name, enum file +@@ -2560,6 +2586,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -519,7 +538,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c if (command_line_arg || format_needs_stat -@@ -2659,7 +2685,7 @@ gobble_file (char const *name, enum file +@@ -2659,7 +2686,7 @@ gobble_file (char const *name, enum file f->stat_ok = true; @@ -528,7 +547,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c { bool have_acl = false; int attr_len = (do_deref -@@ -2667,9 +2694,7 @@ gobble_file (char const *name, enum file +@@ -2667,9 +2695,7 @@ gobble_file (char const *name, enum file f->scontext = xstrdup ("unlabeled"); } @@ -539,16 +558,43 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c { f->scontext = UNKNOWN_SECURITY_CONTEXT; -@@ -2681,7 +2706,7 @@ gobble_file (char const *name, enum file +@@ -2681,7 +2707,7 @@ gobble_file (char const *name, enum file err = 0; } - if (err == 0 && ! have_acl && format == long_format) -+ if (err == 0 && format == long_format) ++ if (err == 0 && format == long_format || format == security_format) { int n = file_has_acl (absolute_name, &f->stat); err = (n < 0); -@@ -3255,6 +3281,13 @@ print_current_files (void) +@@ -2741,7 +2767,7 @@ gobble_file (char const *name, enum file + } + + if (S_ISLNK (f->stat.st_mode) +- && (format == long_format || check_symlink_color)) ++ && (format == long_format || format == security_format || check_symlink_color)) + { + char *linkname; + struct stat linkstats; +@@ -2761,7 +2787,7 @@ gobble_file (char const *name, enum file + command line are automatically traced if not being + listed as files. */ + if (!command_line_arg || format == long_format +- || !S_ISDIR (linkstats.st_mode)) ++ || format == security_format || !S_ISDIR (linkstats.st_mode)) + { + /* Get the linked-to file's mode for the filetype indicator + in long listings. */ +@@ -2800,7 +2826,7 @@ gobble_file (char const *name, enum file + block_size_width = len; + } + +- if (format == long_format) ++ if (format == long_format || format == security_format) + { + if (print_owner) + { +@@ -3255,6 +3282,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -562,7 +608,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c break; } } -@@ -3481,7 +3514,7 @@ print_long_format (const struct fileinfo +@@ -3481,7 +3515,7 @@ print_long_format (const struct fileinfo The latter is wrong when inode_number_width is zero. */ p += strlen (p); } @@ -571,7 +617,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c if (print_block_size) { char hbuf[LONGEST_HUMAN_READABLE + 1]; -@@ -3510,9 +3543,15 @@ print_long_format (const struct fileinfo +@@ -3510,9 +3544,15 @@ print_long_format (const struct fileinfo The latter is wrong when nlink_width is zero. */ p += strlen (p); @@ -588,7 +634,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c { DIRED_FPUTS (buf, stdout, p - buf); -@@ -3525,9 +3564,6 @@ print_long_format (const struct fileinfo +@@ -3525,9 +3565,6 @@ print_long_format (const struct fileinfo if (print_author) format_user (f->stat.st_author, author_width, f->stat_ok); @@ -598,7 +644,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c p = buf; } -@@ -3864,9 +3900,6 @@ print_file_name_and_frills (const struct +@@ -3864,9 +3901,6 @@ print_file_name_and_frills (const struct human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ST_NBLOCKSIZE, output_block_size)); @@ -608,7 +654,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, f->stat_ok, f->filetype, NULL); -@@ -4030,9 +4063,6 @@ length_of_file_name_and_frills (const st +@@ -4030,9 +4064,6 @@ length_of_file_name_and_frills (const st output_block_size)) : block_size_width); @@ -618,7 +664,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c quote_name (NULL, f->name, filename_quoting_options, &name_width); len += name_width; -@@ -4461,9 +4491,16 @@ Mandatory arguments to long options are +@@ -4461,9 +4492,16 @@ Mandatory arguments to long options are -w, --width=COLS assume screen width instead of current value\n\ -x list entries by lines instead of by columns\n\ -X sort alphabetically by entry extension\n\ @@ -636,7 +682,7 @@ diff -urp coreutils-6.10-orig/src/ls.c coreutils-6.10/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_("\n\ -@@ -4487,3 +4524,67 @@ Exit status is 0 if OK, 1 if minor probl +@@ -4487,3 +4525,67 @@ Exit status is 0 if OK, 1 if minor probl } exit (status); } diff --git a/coreutils.spec b/coreutils.spec index da07adf..96902f8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: The GNU core utilities: a set of tools commonly used in shell scripts Name: coreutils Version: 6.12 -Release: 18%{?dist} +Release: 19%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -25,6 +25,7 @@ Patch4: coreutils-6.12-date_timerelsnumber.patch Patch5: coreutils-6.12-seqdecimalutf8.patch Patch6: coreutils-6.12-catch-known-testsuite-failures.patch Patch7: coreutils-446294-lsexitstatuses.patch +Patch8: coreutils-6.12-sort-endoffields.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -120,6 +121,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch5 -p1 -b .sequtf8 %patch6 -p1 -b .tests %patch7 -p1 -b .lsexit +%patch8 -p1 -b .endfields # Our patches %patch100 -p1 -b .configure @@ -340,6 +342,12 @@ fi /sbin/runuser %changelog +* Thu Feb 26 2009 Ondrej Vasik - 6.12-19 +- fix showing ACL's for ls -Z (#487374), fix automatic + column width for it as well +- fix couple of bugs (including #485715) in sort with + determining end of fields(upstream) + * Fri Nov 21 2008 Ondrej Vasik - 6.12-18 - added requirements for util-linux-ng >= 2.14 because of file conflict in update from F-8/F-9(#472445) From c39fe6a1cc42565fc51fdef67ee0d0008feade1a Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 27 Feb 2009 12:13:54 +0000 Subject: [PATCH 020/523] fix infinite loop in recursive cp (introduced by 7.1, upstream) --- coreutils-7.1-cp-recursiveinfloop.patch | 154 ++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 coreutils-7.1-cp-recursiveinfloop.patch diff --git a/coreutils-7.1-cp-recursiveinfloop.patch b/coreutils-7.1-cp-recursiveinfloop.patch new file mode 100644 index 0000000..963af0b --- /dev/null +++ b/coreutils-7.1-cp-recursiveinfloop.patch @@ -0,0 +1,154 @@ +diff -urNp coreutils-7.1-orig/src/copy.c coreutils-7.1/src/copy.c +--- coreutils-7.1-orig/src/copy.c 2009-02-27 12:07:29.000000000 +0100 ++++ coreutils-7.1/src/copy.c 2009-02-27 12:14:29.000000000 +0100 +@@ -104,6 +104,7 @@ static bool copy_internal (char const *s + struct dir_list *ancestors, + const struct cp_options *x, + bool command_line_arg, ++ bool *first_dir_created_per_command_line_arg, + bool *copy_into_self, + bool *rename_succeeded); + static bool owner_failure_ok (struct cp_options const *x); +@@ -201,13 +202,16 @@ copy_attr_by_name (char const *src_path, + DST_NAME_IN is a directory that was created previously in the + recursion. SRC_SB and ANCESTORS describe SRC_NAME_IN. + Set *COPY_INTO_SELF if SRC_NAME_IN is a parent of ++ FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG FIXME + (or the same as) DST_NAME_IN; otherwise, clear it. + Return true if successful. */ + + static bool + copy_dir (char const *src_name_in, char const *dst_name_in, bool new_dst, + const struct stat *src_sb, struct dir_list *ancestors, +- const struct cp_options *x, bool *copy_into_self) ++ const struct cp_options *x, ++ bool *first_dir_created_per_command_line_arg, ++ bool *copy_into_self) + { + char *name_space; + char *namep; +@@ -237,12 +241,20 @@ copy_dir (char const *src_name_in, char + + ok &= copy_internal (src_name, dst_name, new_dst, src_sb->st_dev, + ancestors, &non_command_line_options, false, ++ first_dir_created_per_command_line_arg, + &local_copy_into_self, NULL); + *copy_into_self |= local_copy_into_self; + + free (dst_name); + free (src_name); + ++ /* If we're copying into self, there's no point in continuing, ++ and in fact, that would even infloop, now that we record only ++ the first created directory per command line argument. */ ++ if (local_copy_into_self) ++ break; ++ ++ + namep += strlen (namep) + 1; + } + free (name_space); +@@ -1125,6 +1137,7 @@ restore_default_fscreatecon_or_die (void + not known. ANCESTORS points to a linked, null terminated list of + devices and inodes of parent directories of SRC_NAME. COMMAND_LINE_ARG + is true iff SRC_NAME was specified on the command line. ++ FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG is both input and output. + Set *COPY_INTO_SELF if SRC_NAME is a parent of (or the + same as) DST_NAME; otherwise, clear it. + Return true if successful. */ +@@ -1135,6 +1148,7 @@ copy_internal (char const *src_name, cha + struct dir_list *ancestors, + const struct cp_options *x, + bool command_line_arg, ++ bool *first_dir_created_per_command_line_arg, + bool *copy_into_self, + bool *rename_succeeded) + { +@@ -1815,11 +1829,15 @@ copy_internal (char const *src_name, cha + } + } + +- /* Insert the created directory's inode and device +- numbers into the search structure, so that we can +- avoid copying it again. */ +- if (!x->hard_link) +- remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev); ++ /* Record the created directory's inode and device numbers into ++ the search structure, so that we can avoid copying it again. ++ Do this only for the first directory that is created for each ++ source command line argument. */ ++ if (!*first_dir_created_per_command_line_arg) ++ { ++ remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev); ++ *first_dir_created_per_command_line_arg = true; ++ } + + if (x->verbose) + emit_verbose (src_name, dst_name, NULL); +@@ -1840,6 +1858,7 @@ copy_internal (char const *src_name, cha + in a source directory would cause the containing destination + directory not to have owner/perms set properly. */ + delayed_ok = copy_dir (src_name, dst_name, new_dst, &src_sb, dir, x, ++ first_dir_created_per_command_line_arg, + copy_into_self); + } + } +@@ -2187,8 +2206,11 @@ copy (char const *src_name, char const * + top_level_src_name = src_name; + top_level_dst_name = dst_name; + ++ bool first_dir_created_per_command_line_arg = false; + return copy_internal (src_name, dst_name, nonexistent_dst, 0, NULL, +- options, true, copy_into_self, rename_succeeded); ++ options, true, ++ &first_dir_created_per_command_line_arg, ++ copy_into_self, rename_succeeded); + } + + /* Set *X to the default options for a value of type struct cp_options. */ +diff -urNp coreutils-7.1-orig/tests/cp/into-self coreutils-7.1/tests/cp/into-self +--- coreutils-7.1-orig/tests/cp/into-self 2008-09-18 09:06:57.000000000 +0200 ++++ coreutils-7.1/tests/cp/into-self 2009-02-27 12:16:21.000000000 +0100 +@@ -1,7 +1,7 @@ + #!/bin/sh + # Confirm that copying a directory into itself gets a proper diagnostic. + +-# Copyright (C) 2001, 2002, 2004, 2006-2008 Free Software Foundation, Inc. ++# Copyright (C) 2001, 2002, 2004, 2006-2009 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 +@@ -28,15 +28,32 @@ fi + + . $srcdir/test-lib.sh + +-mkdir dir || framework_failure ++mkdir a dir || framework_failure + + fail=0 + + # This command should exit nonzero. + cp -R dir dir 2> out && fail=1 ++echo 1 >> out ++ ++# This should, too. However, with coreutils-7.1 it would infloop. ++cp -rl dir dir 2>> out && fail=1 ++echo 2 >> out ++ ++cp -rl a dir dir 2>> out && fail=1 ++echo 3 >> out ++cp -rl a dir dir 2>> out && fail=1 ++echo 4 >> out + + cat > exp <<\EOF + cp: cannot copy a directory, `dir', into itself, `dir/dir' ++1 ++cp: cannot copy a directory, `dir', into itself, `dir/dir' ++2 ++cp: cannot copy a directory, `dir', into itself, `dir/dir' ++3 ++cp: cannot copy a directory, `dir', into itself, `dir/dir' ++4 + EOF + #' + diff --git a/coreutils.spec b/coreutils.spec index 9025a1b..bfa4a3a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.1 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -20,6 +20,7 @@ Source203: coreutils-runuser-l.pamd # From upstream Patch1: coreutils-7.1-sort-endoffields.patch +Patch2: coreutils-7.1-cp-recursiveinfloop.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -100,6 +101,7 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .endfield +%patch2 -p1 -b .recinfloop # Our patches %patch100 -p1 -b .configure @@ -311,6 +313,10 @@ fi /sbin/runuser %changelog +* Fri Feb 27 2009 Ondrej Vasik 7.1-5 +- fix infinite loop in recursive cp (upstream, introduced + by 7.1) + * Thu Feb 26 2009 Ondrej Vasik 7.1-4 - fix showing ACL's for ls -Z (#487374), fix automatic column width for it as well From bfff2133f5df6a92053347be42d78bdcae69327f Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 2 Mar 2009 12:42:55 +0000 Subject: [PATCH 021/523] fix sort bugs (including #485715) for multibyte locales --- coreutils-7.1-sort-endoffields.patch | 20 +++++++++++++-- coreutils-i18n.patch | 38 ++++++++++++++++------------ coreutils.spec | 5 +++- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/coreutils-7.1-sort-endoffields.patch b/coreutils-7.1-sort-endoffields.patch index 22e336f..190c4a1 100644 --- a/coreutils-7.1-sort-endoffields.patch +++ b/coreutils-7.1-sort-endoffields.patch @@ -64,7 +64,18 @@ diff -urNp coreutils-7.1-orig/src/sort.c coreutils-7.1/src/sort.c diff -urNp coreutils-7.1-orig/tests/misc/sort coreutils-7.1/tests/misc/sort --- coreutils-7.1-orig/tests/misc/sort 2009-01-27 22:11:25.000000000 +0100 +++ coreutils-7.1/tests/misc/sort 2009-02-25 16:21:48.000000000 +0100 -@@ -110,6 +110,8 @@ my @Tests = +@@ -24,6 +24,10 @@ 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}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ + # 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 '-'. +@@ -110,6 +114,8 @@ my @Tests = ["07b", '-k 2,3', {IN=>"a a b\nz a a\n"}, {OUT=>"z a a\na a b\n"}], ["07c", '-k 2,3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], ["07d", '+1 -3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], @@ -73,7 +84,7 @@ diff -urNp coreutils-7.1-orig/tests/misc/sort coreutils-7.1/tests/misc/sort # # report an error for `.' without following char spec ["08a", '-k 2.,3', {EXIT=>2}, -@@ -210,6 +212,10 @@ my @Tests = +@@ -210,6 +216,15 @@ my @Tests = # key start and key end. ["18e", '-nb -k1.1,1.2', {IN=>" 901\n100\n"}, {OUT=>"100\n 901\n"}], @@ -81,6 +92,11 @@ diff -urNp coreutils-7.1-orig/tests/misc/sort coreutils-7.1/tests/misc/sort +# next field are not included in the sort. I.E. order should not change here. +["18f", '-k1,1b', {IN=>"a y\na z\n"}, {OUT=>"a y\na z\n"}], + ++# When ignoring leading blanks for start position, ensure blanks from ++# next field are not included in the sort. I.E. order should not change here. ++# This was noticed as an issue on fedora 8 (only in multibyte locales). ++["18g", '-k1b,1', {IN=>"a y\na z\n"}, {OUT=>"a y\na z\n"}, ++ {ENV => "LC_ALL=$mb_locale"}], # This looks odd, but works properly -- 2nd keyspec is never # used because all lines are different. ["19a", '+0 +1nr', {IN=>"b 2\nb 1\nb 3\n"}, {OUT=>"b 1\nb 2\nb 3\n"}], diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index cd5852a..5e6facd 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1938,7 +1938,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c if (newlim) lim = newlim; } -@@ -1384,6 +1570,107 @@ +@@ -1384,6 +1570,113 @@ return ptr; } @@ -1952,6 +1952,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + size_t mblength; + mbstate_t state; + ++ if (echar == 0) ++ eword++; /* skip all of end field. */ ++ + memset (&state, '\0', sizeof(mbstate_t)); + + if (tab_length) @@ -2020,24 +2023,27 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + } +# endif + -+ /* If we're skipping leading blanks, don't start counting characters -+ * until after skipping past any leading blanks. */ -+ if (key->skipsblanks) -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) -+ ptr += mblength; ++ if (echar != 0) ++ { ++ /* If we're skipping leading blanks, don't start counting characters ++ * until after skipping past any leading blanks. */ ++ if (key->skipsblanks) ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; + -+ memset (&state, '\0', sizeof(mbstate_t)); ++ 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); ++ /* 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; -+ } ++ if (ptr + mblength > lim) ++ break; ++ else ++ ptr += mblength; ++ } ++ } + + return ptr; +} diff --git a/coreutils.spec b/coreutils.spec index bfa4a3a..24f093e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.1 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -313,6 +313,9 @@ fi /sbin/runuser %changelog +* Mon Mar 02 2009 Ondrej Vasik 7.1-6 +- fix sort bugs (including #485715) for multibyte locales + as well * Fri Feb 27 2009 Ondrej Vasik 7.1-5 - fix infinite loop in recursive cp (upstream, introduced by 7.1) From d540fa5ffffe439a6dfadbd9d1a83a1ddbf9809e Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 2 Mar 2009 12:52:33 +0000 Subject: [PATCH 022/523] fix typo --- coreutils-7.1-sort-endoffields.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-7.1-sort-endoffields.patch b/coreutils-7.1-sort-endoffields.patch index 190c4a1..45d1e28 100644 --- a/coreutils-7.1-sort-endoffields.patch +++ b/coreutils-7.1-sort-endoffields.patch @@ -65,7 +65,7 @@ diff -urNp coreutils-7.1-orig/tests/misc/sort coreutils-7.1/tests/misc/sort --- coreutils-7.1-orig/tests/misc/sort 2009-01-27 22:11:25.000000000 +0100 +++ coreutils-7.1/tests/misc/sort 2009-02-25 16:21:48.000000000 +0100 @@ -24,6 +24,10 @@ my $prog = 'sort'; - # Turn off localization of executable's output. + # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; +my $mb_locale = $ENV{LOCALE_FR_UTF8}; From 85ca01a1d93f5918b4daecb52be590599fc00dc7 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 2 Mar 2009 13:51:18 +0000 Subject: [PATCH 023/523] fix sort bugs (including #485715) for multibyte locales --- coreutils-6.12-sort-endoffields.patch | 20 ++++++++++++-- coreutils-i18n.patch | 38 ++++++++++++++++----------- coreutils.spec | 6 ++++- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/coreutils-6.12-sort-endoffields.patch b/coreutils-6.12-sort-endoffields.patch index 997feef..1f841af 100644 --- a/coreutils-6.12-sort-endoffields.patch +++ b/coreutils-6.12-sort-endoffields.patch @@ -79,7 +79,18 @@ diff -urNp coreutils-6.12-orig/src/sort.c coreutils-6.12/src/sort.c diff -urNp coreutils-6.12-orig/tests/misc/sort coreutils-6.12/tests/misc/sort --- coreutils-6.12-orig/tests/misc/sort 2008-05-17 08:41:12.000000000 +0200 +++ coreutils-6.12/tests/misc/sort 2009-02-26 16:25:39.000000000 +0100 -@@ -108,6 +108,8 @@ my @Tests = +@@ -24,6 +24,10 @@ 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}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ + # 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 '-'. +@@ -108,6 +114,8 @@ my @Tests = ["07b", '-k 2,3', {IN=>"a a b\nz a a\n"}, {OUT=>"z a a\na a b\n"}], ["07c", '-k 2,3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], ["07d", '+1 -3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], @@ -88,7 +99,7 @@ diff -urNp coreutils-6.12-orig/tests/misc/sort coreutils-6.12/tests/misc/sort # # report an error for `.' without following char spec ["08a", '-k 2.,3', {EXIT=>2}, -@@ -208,6 +210,10 @@ my @Tests = +@@ -208,6 +216,15 @@ my @Tests = # key start and key end. ["18e", '-nb -k1.1,1.2', {IN=>" 901\n100\n"}, {OUT=>"100\n 901\n"}], @@ -96,6 +107,11 @@ diff -urNp coreutils-6.12-orig/tests/misc/sort coreutils-6.12/tests/misc/sort +# next field are not included in the sort. I.E. order should not change here. +["18f", '-k1,1b', {IN=>"a y\na z\n"}, {OUT=>"a y\na z\n"}], + ++# When ignoring leading blanks for start position, ensure blanks from ++# next field are not included in the sort. I.E. order should not change here. ++# This was noticed as an issue on fedora 8 (only in multibyte locales). ++["18g", '-k1b,1', {IN=>"a y\na z\n"}, {OUT=>"a y\na z\n"}, ++ {ENV => "LC_ALL=$mb_locale"}], # This looks odd, but works properly -- 2nd keyspec is never # used because all lines are different. ["19a", '+0 +1nr', {IN=>"b 2\nb 1\nb 3\n"}, {OUT=>"b 1\nb 2\nb 3\n"}], diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 2f48694..c70aa2a 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1919,7 +1919,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c if (newlim) lim = newlim; } -@@ -1384,6 +1570,107 @@ +@@ -1384,6 +1570,113 @@ return ptr; } @@ -1931,7 +1931,10 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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)); + @@ -2001,24 +2004,27 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + } +# endif + -+ /* If we're skipping leading blanks, don't start counting characters -+ * until after skipping past any leading blanks. */ -+ if (key->skipsblanks) -+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) -+ ptr += mblength; ++ if (echar != 0) ++ { ++ /* If we're skipping leading blanks, don't start counting characters ++ * until after skipping past any leading blanks. */ ++ if (key->skipsblanks) ++ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) ++ ptr += mblength; + -+ memset (&state, '\0', sizeof(mbstate_t)); ++ 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); ++ /* 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; -+ } ++ if (ptr + mblength > lim) ++ break; ++ else ++ ptr += mblength; ++ } ++ } + + return ptr; +} diff --git a/coreutils.spec b/coreutils.spec index 96902f8..5976065 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: The GNU core utilities: a set of tools commonly used in shell scripts Name: coreutils Version: 6.12 -Release: 19%{?dist} +Release: 20%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -342,6 +342,10 @@ fi /sbin/runuser %changelog +* Mon Mar 02 2009 Ondrej Vasik - 6.12-20 +- fix sort bugs (including #485715) for multibyte locales + as well + * Thu Feb 26 2009 Ondrej Vasik - 6.12-19 - fix showing ACL's for ls -Z (#487374), fix automatic column width for it as well From 579172fc3b48efeb6638ca94dce00e667d8728a5 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 19 Mar 2009 14:56:49 +0000 Subject: [PATCH 024/523] do not ship /etc/DIR_COLORS.xterm (ship /etc/DIR_COLORS.lightbgcolor instead of it, try to preserve xattrs in cp -a when possible --- coreutils.spec | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 24f093e..ebb6e2d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.1 -Release: 6%{?dist} +Release: 7{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -9,7 +9,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) #Using .tar.gz tarball until xz utils will be in Fedora Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz Source101: coreutils-DIR_COLORS -Source102: coreutils-DIR_COLORS.xterm +Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh @@ -50,6 +50,7 @@ Patch916: coreutils-getfacl-exit-code.patch #(upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch +Patch952: coreutils-cp-a-xattrs.patch BuildRequires: libselinux-devel >= 1.25.6-1 BuildRequires: libacl-devel @@ -127,6 +128,7 @@ the old GNU fileutils, sh-utils, and textutils packages. #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman +%patch952 -p1 -b .xattrs chmod a+x tests/misc/sort-mb-tests @@ -202,7 +204,7 @@ for i in env cut; do ln -sf ../../bin/$i $RPM_BUILD_ROOT/usr/bin; done mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d install -p -c -m644 %SOURCE101 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS -install -p -c -m644 %SOURCE102 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.xterm +install -p -c -m644 %SOURCE102 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.lightbgcolor install -p -c -m644 %SOURCE103 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.256color install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh @@ -313,9 +315,18 @@ fi /sbin/runuser %changelog +* Thu Mar 19 2009 Ondrej Vasik 7.1-7 +- do not ship /etc/DIR_COLORS.xterm - as many terminals + use TERM xterm and black background as default - making + ls color output unreadable +- shipping /etc/DIR_COLORS.lightbgcolor instead of it for + light(white/gray) backgrounds +- try to preserve xattrs in cp -a when possible + * Mon Mar 02 2009 Ondrej Vasik 7.1-6 - fix sort bugs (including #485715) for multibyte locales as well + * Fri Feb 27 2009 Ondrej Vasik 7.1-5 - fix infinite loop in recursive cp (upstream, introduced by 7.1) From 92dfad507f7770ef27feef2ab59d94ea1dcac6a0 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 19 Mar 2009 14:57:35 +0000 Subject: [PATCH 025/523] do not ship /etc/DIR_COLORS.xterm (ship /etc/DIR_COLORS.lightbgcolor instead of it, try to preserve xattrs in cp -a when possible --- coreutils-7.1-cp-a-xattrs.patch | 160 ++++++++++++++++++ ...xterm => coreutils-DIR_COLORS.lightbgcolor | 2 +- coreutils-colorls.sh | 2 +- coreutils.spec | 2 +- 4 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 coreutils-7.1-cp-a-xattrs.patch rename coreutils-DIR_COLORS.xterm => coreutils-DIR_COLORS.lightbgcolor (98%) diff --git a/coreutils-7.1-cp-a-xattrs.patch b/coreutils-7.1-cp-a-xattrs.patch new file mode 100644 index 0000000..32f9574 --- /dev/null +++ b/coreutils-7.1-cp-a-xattrs.patch @@ -0,0 +1,160 @@ +From 2c0ac0d7fc6bce3abdbad8529e44318f1370a948 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= +Date: Wed, 11 Mar 2009 16:08:20 +0100 +Subject: [PATCH] cp: make -a option preserve xattrs with reduced diagnostics + +* copy.c (copy_attr_by_fd): Reduce xattr diagnostics for 'cp -a'. + (copy_attr_by_name): Likewise. +* cp.c (main): preserve xattrs with -a option, when possible +* doc/coreutils.texi: document that xattrs are preserved with + cp -a, with no added diagnostics +* tests/misc/xattr: Add tests for 'cp --preserve=all' and 'cp -a'. +--- + doc/coreutils.texi | 7 +++---- + src/copy.c | 22 +++++++++++++--------- + src/cp.c | 1 + + tests/misc/xattr | 15 +++++++++++++-- + 4 files changed, 30 insertions(+), 15 deletions(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 2c1fae5..0bf978a 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -7262,10 +7262,9 @@ Preserve as much as possible of the structure and attributes of the + original files in the copy (but do not attempt to preserve internal + directory structure; i.e., @samp{ls -U} may list the entries in a copied + directory in a different order). +-Try to preserve SELinux security context, but ignore any failure to do that +-and print no corresponding diagnostic. +-This option does not preserve extended attributes(xattr) at the moment. +-Equivalent to @option{-dR --preserve=all} with a few exceptions. ++Try to preserve SELinux security context and extended attributes (xattr), ++but ignore any failure to do that and print no corresponding diagnostic. ++Equivalent to @option{-dR --preserve=all} with the reduced diagnostics. + + @item -b + @itemx @w{@kbd{--backup}[=@var{method}]} +diff --git a/src/copy.c b/src/copy.c +index e37fead..7b4dc08 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -153,13 +153,13 @@ copy_attr_quote (struct error_context *ctx ATTRIBUTE_UNUSED, char const *str) + + static void + copy_attr_free (struct error_context *ctx ATTRIBUTE_UNUSED, +- char const *str ATTRIBUTE_UNUSED) ++ char const *str ATTRIBUTE_UNUSED) + { + } + + static bool + copy_attr_by_fd (char const *src_path, int src_fd, +- char const *dst_path, int dst_fd) ++ char const *dst_path, int dst_fd, const struct cp_options *x) + { + struct error_context ctx = + { +@@ -167,11 +167,13 @@ copy_attr_by_fd (char const *src_path, int src_fd, + .quote = copy_attr_quote, + .quote_free = copy_attr_free + }; +- return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0, &ctx); ++ return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0, ++ x->reduce_diagnostics ? NULL : &ctx); + } + + static bool +-copy_attr_by_name (char const *src_path, char const *dst_path) ++copy_attr_by_name (char const *src_path, char const *dst_path, ++ const struct cp_options *x) + { + struct error_context ctx = + { +@@ -179,19 +181,21 @@ copy_attr_by_name (char const *src_path, char const *dst_path) + .quote = copy_attr_quote, + .quote_free = copy_attr_free + }; +- return 0 == attr_copy_file (src_path, dst_path, 0, &ctx); ++ return 0 == attr_copy_file (src_path, dst_path, 0, ++ x-> reduce_diagnostics ? NULL :&ctx); + } + #else /* USE_XATTR */ + + static bool + copy_attr_by_fd (char const *src_path, int src_fd, +- char const *dst_path, int dst_fd) ++ char const *dst_path, int dst_fd, const struct cp_options *x) + { + return true; + } + + static bool +-copy_attr_by_name (char const *src_path, char const *dst_path) ++copy_attr_by_name (char const *src_path, char const *dst_path, ++ const struct cp_options *x) + { + return true; + } +@@ -759,7 +763,7 @@ copy_reg (char const *src_name, char const *dst_name, + set_author (dst_name, dest_desc, src_sb); + + if (x->preserve_xattr && ! copy_attr_by_fd (src_name, source_desc, +- dst_name, dest_desc) ++ dst_name, dest_desc, x) + && x->require_preserve_xattr) + return false; + +@@ -2076,7 +2080,7 @@ copy_internal (char const *src_name, char const *dst_name, + + set_author (dst_name, -1, &src_sb); + +- if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name) ++ if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name, x) + && x->require_preserve_xattr) + return false; + +diff --git a/src/cp.c b/src/cp.c +index af4bd60..8785076 100644 +--- a/src/cp.c ++++ b/src/cp.c +@@ -925,6 +925,7 @@ main (int argc, char **argv) + x.require_preserve = true; + if (selinux_enabled) + x.preserve_security_context = true; ++ x.preserve_xattr = true; + x.reduce_diagnostics = true; + x.recursive = true; + break; +diff --git a/tests/misc/xattr b/tests/misc/xattr +index 4137c53..f067ff5 100755 +--- a/tests/misc/xattr ++++ b/tests/misc/xattr +@@ -1,6 +1,7 @@ + #!/bin/sh +-# Ensure that cp --preserve=xattr and mv preserve extended attributes and +-# install does not preserve extended attributes. ++# Ensure that cp --preserve=xattr, cp --preserve=all and mv preserve extended ++# attributes and install does not preserve extended attributes. ++# cp -a should preserve xattr, error diagnostics should not be displayed + + # Copyright (C) 2009 Free Software Foundation, Inc. + +@@ -66,6 +67,16 @@ cp --preserve=xattr a b || fail=1 + getfattr -d b >out_b || skip_test_ "failed to get xattr of file" + grep -F "$xattr_pair" out_b >/dev/null || fail=1 + ++#test if --preserve=all option works ++cp --preserve=all a c || fail=1 ++getfattr -d c >out_c || skip_test_ "failed to get xattr of file" ++grep -F "$xattr_pair" out_c >/dev/null || fail=1 ++ ++#test if -a option works without any diagnostics ++cp -a a d 2>err && test -s err && fail=1 ++getfattr -d d >out_d || skip_test_ "failed to get xattr of file" ++grep -F "$xattr_pair" out_d >/dev/null || fail=1 ++ + rm b || framework_failure + + # install should never preserve xattr +-- +1.5.6.1.156.ge903b diff --git a/coreutils-DIR_COLORS.xterm b/coreutils-DIR_COLORS.lightbgcolor similarity index 98% rename from coreutils-DIR_COLORS.xterm rename to coreutils-DIR_COLORS.lightbgcolor index dd189cf..6670556 100644 --- a/coreutils-DIR_COLORS.xterm +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -1,4 +1,4 @@ -# Configuration file for the color ls utility +# Configuration file for the color ls utility - modified for gray backgrounds # Synchronized with coreutils 7.1 dircolors # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index 45955f4..e73cc42 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -2,7 +2,7 @@ #when USER_LS_COLORS defined do not override user LS_COLORS, but use them. if [ -z "$USER_LS_COLORS" ]; then - + alias ll='ls -l' 2>/dev/null alias l.='ls -d .*' 2>/dev/null diff --git a/coreutils.spec b/coreutils.spec index ebb6e2d..493466d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.1 -Release: 7{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ From 81a387abc6bb24e0a7a5068a3a538143266ea740 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 19 Mar 2009 15:10:54 +0000 Subject: [PATCH 026/523] fix typo in patch name --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 493466d..f4305e1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -50,7 +50,7 @@ Patch916: coreutils-getfacl-exit-code.patch #(upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch -Patch952: coreutils-cp-a-xattrs.patch +Patch952: coreutils-7.1-cp-a-xattrs.patch BuildRequires: libselinux-devel >= 1.25.6-1 BuildRequires: libacl-devel From ca7ca126aa55ebdc8811f4b997357aa698f413e4 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 31 Mar 2009 15:48:26 +0000 Subject: [PATCH 027/523] New upstream bugfix release 7.2, removed applied patches --- .cvsignore | 2 +- coreutils-6.10-configuration.patch | 37 ------ coreutils-7.1-cp-a-xattrs.patch | 160 ------------------------ coreutils-7.1-cp-recursiveinfloop.patch | 154 ----------------------- coreutils-7.1-sort-endoffields.patch | 102 --------------- coreutils.spec | 14 +-- sources | 2 +- 7 files changed, 8 insertions(+), 463 deletions(-) delete mode 100644 coreutils-7.1-cp-a-xattrs.patch delete mode 100644 coreutils-7.1-cp-recursiveinfloop.patch delete mode 100644 coreutils-7.1-sort-endoffields.patch diff --git a/.cvsignore b/.cvsignore index d2049a4..c47163f 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-7.1.tar.gz +coreutils-7.2.tar.gz diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 0571ea6..2bfc057 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -23,43 +23,6 @@ diff -urNp coreutils-6.11-orig/tests/test-lib.sh coreutils-6.11/tests/test-lib.s skip_test_ "this system (or maybe just" \ "the current file system) lacks SELinux support" ;; -diff -urNp coreutils-7.1-orig/gnulib-tests/test-getaddrinfo.c coreutils-7.1/gnulib-tests/test-getaddrinfo.c ---- coreutils-7.1-orig/gnulib-tests/test-getaddrinfo.c 2009-01-27 21:33:19.000000000 +0100 -+++ coreutils-7.1/gnulib-tests/test-getaddrinfo.c 2009-02-25 13:52:59.000000000 +0100 -@@ -36,6 +36,8 @@ - # define dbgprintf if (0) printf - #endif - -+static int skip = 0; -+ - /* BeOS does not have AF_UNSPEC. */ - #ifndef AF_UNSPEC - # define AF_UNSPEC 0 -@@ -52,6 +54,9 @@ int simple (char *host, char *service) - struct addrinfo *ai0, *ai; - int res; - -+ if (skip) -+ return 0; -+ - dbgprintf ("Finding %s service %s...\n", host, service); - - /* This initializes "hints" but does not use it. Is there a reason -@@ -72,8 +77,12 @@ int simple (char *host, char *service) - in-law's farm. */ - if (res == EAI_AGAIN) - { -- fprintf (stderr, "skipping getaddrinfo test: no network?\n"); -- return 77; -+ if (!skip) -+ { -+ skip++; -+ fprintf (stderr, "skipping getaddrinfo test: no network?\n"); -+ return 77; -+ } - } - /* IRIX reports EAI_NONAME for "https". Don't fail the test - merely because of this. */ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c --- coreutils-7.1-orig/src/ls.c 2009-02-25 13:23:59.000000000 +0100 +++ coreutils-7.1/src/ls.c 2009-02-25 13:25:20.000000000 +0100 diff --git a/coreutils-7.1-cp-a-xattrs.patch b/coreutils-7.1-cp-a-xattrs.patch deleted file mode 100644 index 32f9574..0000000 --- a/coreutils-7.1-cp-a-xattrs.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 2c0ac0d7fc6bce3abdbad8529e44318f1370a948 Mon Sep 17 00:00:00 2001 -From: =?utf-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= -Date: Wed, 11 Mar 2009 16:08:20 +0100 -Subject: [PATCH] cp: make -a option preserve xattrs with reduced diagnostics - -* copy.c (copy_attr_by_fd): Reduce xattr diagnostics for 'cp -a'. - (copy_attr_by_name): Likewise. -* cp.c (main): preserve xattrs with -a option, when possible -* doc/coreutils.texi: document that xattrs are preserved with - cp -a, with no added diagnostics -* tests/misc/xattr: Add tests for 'cp --preserve=all' and 'cp -a'. ---- - doc/coreutils.texi | 7 +++---- - src/copy.c | 22 +++++++++++++--------- - src/cp.c | 1 + - tests/misc/xattr | 15 +++++++++++++-- - 4 files changed, 30 insertions(+), 15 deletions(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 2c1fae5..0bf978a 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -7262,10 +7262,9 @@ Preserve as much as possible of the structure and attributes of the - original files in the copy (but do not attempt to preserve internal - directory structure; i.e., @samp{ls -U} may list the entries in a copied - directory in a different order). --Try to preserve SELinux security context, but ignore any failure to do that --and print no corresponding diagnostic. --This option does not preserve extended attributes(xattr) at the moment. --Equivalent to @option{-dR --preserve=all} with a few exceptions. -+Try to preserve SELinux security context and extended attributes (xattr), -+but ignore any failure to do that and print no corresponding diagnostic. -+Equivalent to @option{-dR --preserve=all} with the reduced diagnostics. - - @item -b - @itemx @w{@kbd{--backup}[=@var{method}]} -diff --git a/src/copy.c b/src/copy.c -index e37fead..7b4dc08 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -153,13 +153,13 @@ copy_attr_quote (struct error_context *ctx ATTRIBUTE_UNUSED, char const *str) - - static void - copy_attr_free (struct error_context *ctx ATTRIBUTE_UNUSED, -- char const *str ATTRIBUTE_UNUSED) -+ char const *str ATTRIBUTE_UNUSED) - { - } - - static bool - copy_attr_by_fd (char const *src_path, int src_fd, -- char const *dst_path, int dst_fd) -+ char const *dst_path, int dst_fd, const struct cp_options *x) - { - struct error_context ctx = - { -@@ -167,11 +167,13 @@ copy_attr_by_fd (char const *src_path, int src_fd, - .quote = copy_attr_quote, - .quote_free = copy_attr_free - }; -- return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0, &ctx); -+ return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0, -+ x->reduce_diagnostics ? NULL : &ctx); - } - - static bool --copy_attr_by_name (char const *src_path, char const *dst_path) -+copy_attr_by_name (char const *src_path, char const *dst_path, -+ const struct cp_options *x) - { - struct error_context ctx = - { -@@ -179,19 +181,21 @@ copy_attr_by_name (char const *src_path, char const *dst_path) - .quote = copy_attr_quote, - .quote_free = copy_attr_free - }; -- return 0 == attr_copy_file (src_path, dst_path, 0, &ctx); -+ return 0 == attr_copy_file (src_path, dst_path, 0, -+ x-> reduce_diagnostics ? NULL :&ctx); - } - #else /* USE_XATTR */ - - static bool - copy_attr_by_fd (char const *src_path, int src_fd, -- char const *dst_path, int dst_fd) -+ char const *dst_path, int dst_fd, const struct cp_options *x) - { - return true; - } - - static bool --copy_attr_by_name (char const *src_path, char const *dst_path) -+copy_attr_by_name (char const *src_path, char const *dst_path, -+ const struct cp_options *x) - { - return true; - } -@@ -759,7 +763,7 @@ copy_reg (char const *src_name, char const *dst_name, - set_author (dst_name, dest_desc, src_sb); - - if (x->preserve_xattr && ! copy_attr_by_fd (src_name, source_desc, -- dst_name, dest_desc) -+ dst_name, dest_desc, x) - && x->require_preserve_xattr) - return false; - -@@ -2076,7 +2080,7 @@ copy_internal (char const *src_name, char const *dst_name, - - set_author (dst_name, -1, &src_sb); - -- if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name) -+ if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name, x) - && x->require_preserve_xattr) - return false; - -diff --git a/src/cp.c b/src/cp.c -index af4bd60..8785076 100644 ---- a/src/cp.c -+++ b/src/cp.c -@@ -925,6 +925,7 @@ main (int argc, char **argv) - x.require_preserve = true; - if (selinux_enabled) - x.preserve_security_context = true; -+ x.preserve_xattr = true; - x.reduce_diagnostics = true; - x.recursive = true; - break; -diff --git a/tests/misc/xattr b/tests/misc/xattr -index 4137c53..f067ff5 100755 ---- a/tests/misc/xattr -+++ b/tests/misc/xattr -@@ -1,6 +1,7 @@ - #!/bin/sh --# Ensure that cp --preserve=xattr and mv preserve extended attributes and --# install does not preserve extended attributes. -+# Ensure that cp --preserve=xattr, cp --preserve=all and mv preserve extended -+# attributes and install does not preserve extended attributes. -+# cp -a should preserve xattr, error diagnostics should not be displayed - - # Copyright (C) 2009 Free Software Foundation, Inc. - -@@ -66,6 +67,16 @@ cp --preserve=xattr a b || fail=1 - getfattr -d b >out_b || skip_test_ "failed to get xattr of file" - grep -F "$xattr_pair" out_b >/dev/null || fail=1 - -+#test if --preserve=all option works -+cp --preserve=all a c || fail=1 -+getfattr -d c >out_c || skip_test_ "failed to get xattr of file" -+grep -F "$xattr_pair" out_c >/dev/null || fail=1 -+ -+#test if -a option works without any diagnostics -+cp -a a d 2>err && test -s err && fail=1 -+getfattr -d d >out_d || skip_test_ "failed to get xattr of file" -+grep -F "$xattr_pair" out_d >/dev/null || fail=1 -+ - rm b || framework_failure - - # install should never preserve xattr --- -1.5.6.1.156.ge903b diff --git a/coreutils-7.1-cp-recursiveinfloop.patch b/coreutils-7.1-cp-recursiveinfloop.patch deleted file mode 100644 index 963af0b..0000000 --- a/coreutils-7.1-cp-recursiveinfloop.patch +++ /dev/null @@ -1,154 +0,0 @@ -diff -urNp coreutils-7.1-orig/src/copy.c coreutils-7.1/src/copy.c ---- coreutils-7.1-orig/src/copy.c 2009-02-27 12:07:29.000000000 +0100 -+++ coreutils-7.1/src/copy.c 2009-02-27 12:14:29.000000000 +0100 -@@ -104,6 +104,7 @@ static bool copy_internal (char const *s - struct dir_list *ancestors, - const struct cp_options *x, - bool command_line_arg, -+ bool *first_dir_created_per_command_line_arg, - bool *copy_into_self, - bool *rename_succeeded); - static bool owner_failure_ok (struct cp_options const *x); -@@ -201,13 +202,16 @@ copy_attr_by_name (char const *src_path, - DST_NAME_IN is a directory that was created previously in the - recursion. SRC_SB and ANCESTORS describe SRC_NAME_IN. - Set *COPY_INTO_SELF if SRC_NAME_IN is a parent of -+ FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG FIXME - (or the same as) DST_NAME_IN; otherwise, clear it. - Return true if successful. */ - - static bool - copy_dir (char const *src_name_in, char const *dst_name_in, bool new_dst, - const struct stat *src_sb, struct dir_list *ancestors, -- const struct cp_options *x, bool *copy_into_self) -+ const struct cp_options *x, -+ bool *first_dir_created_per_command_line_arg, -+ bool *copy_into_self) - { - char *name_space; - char *namep; -@@ -237,12 +241,20 @@ copy_dir (char const *src_name_in, char - - ok &= copy_internal (src_name, dst_name, new_dst, src_sb->st_dev, - ancestors, &non_command_line_options, false, -+ first_dir_created_per_command_line_arg, - &local_copy_into_self, NULL); - *copy_into_self |= local_copy_into_self; - - free (dst_name); - free (src_name); - -+ /* If we're copying into self, there's no point in continuing, -+ and in fact, that would even infloop, now that we record only -+ the first created directory per command line argument. */ -+ if (local_copy_into_self) -+ break; -+ -+ - namep += strlen (namep) + 1; - } - free (name_space); -@@ -1125,6 +1137,7 @@ restore_default_fscreatecon_or_die (void - not known. ANCESTORS points to a linked, null terminated list of - devices and inodes of parent directories of SRC_NAME. COMMAND_LINE_ARG - is true iff SRC_NAME was specified on the command line. -+ FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG is both input and output. - Set *COPY_INTO_SELF if SRC_NAME is a parent of (or the - same as) DST_NAME; otherwise, clear it. - Return true if successful. */ -@@ -1135,6 +1148,7 @@ copy_internal (char const *src_name, cha - struct dir_list *ancestors, - const struct cp_options *x, - bool command_line_arg, -+ bool *first_dir_created_per_command_line_arg, - bool *copy_into_self, - bool *rename_succeeded) - { -@@ -1815,11 +1829,15 @@ copy_internal (char const *src_name, cha - } - } - -- /* Insert the created directory's inode and device -- numbers into the search structure, so that we can -- avoid copying it again. */ -- if (!x->hard_link) -- remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev); -+ /* Record the created directory's inode and device numbers into -+ the search structure, so that we can avoid copying it again. -+ Do this only for the first directory that is created for each -+ source command line argument. */ -+ if (!*first_dir_created_per_command_line_arg) -+ { -+ remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev); -+ *first_dir_created_per_command_line_arg = true; -+ } - - if (x->verbose) - emit_verbose (src_name, dst_name, NULL); -@@ -1840,6 +1858,7 @@ copy_internal (char const *src_name, cha - in a source directory would cause the containing destination - directory not to have owner/perms set properly. */ - delayed_ok = copy_dir (src_name, dst_name, new_dst, &src_sb, dir, x, -+ first_dir_created_per_command_line_arg, - copy_into_self); - } - } -@@ -2187,8 +2206,11 @@ copy (char const *src_name, char const * - top_level_src_name = src_name; - top_level_dst_name = dst_name; - -+ bool first_dir_created_per_command_line_arg = false; - return copy_internal (src_name, dst_name, nonexistent_dst, 0, NULL, -- options, true, copy_into_self, rename_succeeded); -+ options, true, -+ &first_dir_created_per_command_line_arg, -+ copy_into_self, rename_succeeded); - } - - /* Set *X to the default options for a value of type struct cp_options. */ -diff -urNp coreutils-7.1-orig/tests/cp/into-self coreutils-7.1/tests/cp/into-self ---- coreutils-7.1-orig/tests/cp/into-self 2008-09-18 09:06:57.000000000 +0200 -+++ coreutils-7.1/tests/cp/into-self 2009-02-27 12:16:21.000000000 +0100 -@@ -1,7 +1,7 @@ - #!/bin/sh - # Confirm that copying a directory into itself gets a proper diagnostic. - --# Copyright (C) 2001, 2002, 2004, 2006-2008 Free Software Foundation, Inc. -+# Copyright (C) 2001, 2002, 2004, 2006-2009 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 -@@ -28,15 +28,32 @@ fi - - . $srcdir/test-lib.sh - --mkdir dir || framework_failure -+mkdir a dir || framework_failure - - fail=0 - - # This command should exit nonzero. - cp -R dir dir 2> out && fail=1 -+echo 1 >> out -+ -+# This should, too. However, with coreutils-7.1 it would infloop. -+cp -rl dir dir 2>> out && fail=1 -+echo 2 >> out -+ -+cp -rl a dir dir 2>> out && fail=1 -+echo 3 >> out -+cp -rl a dir dir 2>> out && fail=1 -+echo 4 >> out - - cat > exp <<\EOF - cp: cannot copy a directory, `dir', into itself, `dir/dir' -+1 -+cp: cannot copy a directory, `dir', into itself, `dir/dir' -+2 -+cp: cannot copy a directory, `dir', into itself, `dir/dir' -+3 -+cp: cannot copy a directory, `dir', into itself, `dir/dir' -+4 - EOF - #' - diff --git a/coreutils-7.1-sort-endoffields.patch b/coreutils-7.1-sort-endoffields.patch deleted file mode 100644 index 45d1e28..0000000 --- a/coreutils-7.1-sort-endoffields.patch +++ /dev/null @@ -1,102 +0,0 @@ -diff -urNp coreutils-7.1-orig/src/sort.c coreutils-7.1/src/sort.c ---- coreutils-7.1-orig/src/sort.c 2009-02-25 16:15:52.000000000 +0100 -+++ coreutils-7.1/src/sort.c 2009-02-25 16:20:35.000000000 +0100 -@@ -1598,6 +1598,9 @@ limfield_uni (const struct line *line, c - size_t eword = key->eword, echar = key->echar; - size_t remaining_bytes; - -+ if (echar == 0) -+ eword++; /* skip all of end field. */ -+ - /* Move PTR past EWORD fields or to one past the last byte on LINE, - whichever comes first. If there are more than EWORD fields, leave - PTR pointing at the beginning of the field having zero-based index, -@@ -1673,19 +1676,22 @@ limfield_uni (const struct line *line, c - } - #endif - -- /* If we're ignoring leading blanks when computing the End -- of the field, don't start counting bytes until after skipping -- past any leading blanks. */ -- if (key->skipeblanks) -- while (ptr < lim && blanks[to_uchar (*ptr)]) -- ++ptr; - -- /* Advance PTR by ECHAR (if possible), but no further than LIM. */ -- remaining_bytes = lim - ptr; -- if (echar < remaining_bytes) -- ptr += echar; -- else -- ptr = lim; -+ if (echar != 0) /* We need to skip over a portion of the end field. */ -+ { -+ if (key->skipeblanks) /* blanks not counted in echar. */ -+ { -+ while (ptr < lim && blanks[to_uchar (*ptr)]) -+ ++ptr; -+ } -+ -+ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ -+ remaining_bytes = lim - ptr; -+ if (echar < remaining_bytes) -+ ptr += echar; -+ else -+ ptr = lim; -+ } - - return ptr; - } -@@ -3736,12 +3742,9 @@ main (int argc, char **argv) - badfieldspec (optarg, N_("field number is zero")); - } - if (*s == '.') -- s = parse_field_count (s + 1, &key->echar, -- N_("invalid number after `.'")); -- else - { -- /* `-k 2,3' is equivalent to `+1 -3'. */ -- key->eword++; -+ s = parse_field_count (s + 1, &key->echar, -+ N_("invalid number after `.'")); - } - s = set_ordering (s, key, bl_end); - } -diff -urNp coreutils-7.1-orig/tests/misc/sort coreutils-7.1/tests/misc/sort ---- coreutils-7.1-orig/tests/misc/sort 2009-01-27 22:11:25.000000000 +0100 -+++ coreutils-7.1/tests/misc/sort 2009-02-25 16:21:48.000000000 +0100 -@@ -24,6 +24,10 @@ 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}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; -+ - # 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 '-'. -@@ -110,6 +114,8 @@ my @Tests = - ["07b", '-k 2,3', {IN=>"a a b\nz a a\n"}, {OUT=>"z a a\na a b\n"}], - ["07c", '-k 2,3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], - ["07d", '+1 -3', {IN=>"y k b\nz k a\n"}, {OUT=>"z k a\ny k b\n"}], -+["07e", '-k 2,3.0', {IN=>"a a b\nz a a\n"}, {OUT=>"z a a\na a b\n"}], -+ - # - # report an error for `.' without following char spec - ["08a", '-k 2.,3', {EXIT=>2}, -@@ -210,6 +216,15 @@ my @Tests = - # key start and key end. - ["18e", '-nb -k1.1,1.2', {IN=>" 901\n100\n"}, {OUT=>"100\n 901\n"}], - -+# When ignoring leading blanks for end position, ensure blanks from -+# next field are not included in the sort. I.E. order should not change here. -+["18f", '-k1,1b', {IN=>"a y\na z\n"}, {OUT=>"a y\na z\n"}], -+ -+# When ignoring leading blanks for start position, ensure blanks from -+# next field are not included in the sort. I.E. order should not change here. -+# This was noticed as an issue on fedora 8 (only in multibyte locales). -+["18g", '-k1b,1', {IN=>"a y\na z\n"}, {OUT=>"a y\na z\n"}, -+ {ENV => "LC_ALL=$mb_locale"}], - # This looks odd, but works properly -- 2nd keyspec is never - # used because all lines are different. - ["19a", '+0 +1nr', {IN=>"b 2\nb 1\nb 3\n"}, {OUT=>"b 1\nb 2\nb 3\n"}], diff --git a/coreutils.spec b/coreutils.spec index f4305e1..4813efe 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 7.1 -Release: 7%{?dist} +Version: 7.2 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -19,8 +19,6 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -Patch1: coreutils-7.1-sort-endoffields.patch -Patch2: coreutils-7.1-cp-recursiveinfloop.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -50,7 +48,6 @@ Patch916: coreutils-getfacl-exit-code.patch #(upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch -Patch952: coreutils-7.1-cp-a-xattrs.patch BuildRequires: libselinux-devel >= 1.25.6-1 BuildRequires: libacl-devel @@ -101,8 +98,6 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream -%patch1 -p1 -b .endfield -%patch2 -p1 -b .recinfloop # Our patches %patch100 -p1 -b .configure @@ -128,7 +123,6 @@ the old GNU fileutils, sh-utils, and textutils packages. #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -%patch952 -p1 -b .xattrs chmod a+x tests/misc/sort-mb-tests @@ -315,6 +309,10 @@ fi /sbin/runuser %changelog +* Tue Mar 31 2009 Ondrej Vasik 7.2-1 +- New upstream bugfix release 7.2 +- removed applied patches + * Thu Mar 19 2009 Ondrej Vasik 7.1-7 - do not ship /etc/DIR_COLORS.xterm - as many terminals use TERM xterm and black background as default - making diff --git a/sources b/sources index 3e7e413..a167571 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -cbb2b3d1718ee1237b808e00b5c11b1e coreutils-7.1.tar.gz +427c2914d3eab956f317c9ec6a45e62a coreutils-7.2.tar.gz From 1ef0ec681f4c9d97f4189984b2f83ea8c78ac7a9 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 1 Apr 2009 11:14:30 +0000 Subject: [PATCH 028/523] temporarily disable strverscmp failing gnulib test, defuzz patches --- coreutils-6.10-configuration.patch | 16 ++++++++++++++++ coreutils-i18n.patch | 6 +++--- coreutils-pam.patch | 2 +- coreutils.spec | 1 + 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 2bfc057..172754c 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,3 +1,19 @@ +diff -urNp coreutils-7.2-orig/gnulib-tests/gnulib.mk coreutils-7.2/gnulib-tests/gnulib.mk +--- coreutils-7.2-orig/gnulib-tests/gnulib.mk 2009-03-31 14:28:30.000000000 +0200 ++++ coreutils-7.2/gnulib-tests/gnulib.mk 2009-04-01 12:37:00.000000000 +0200 +@@ -910,9 +910,9 @@ EXTRA_DIST += test-strtod.c + + ## begin gnulib module strverscmp-tests + +-TESTS += test-strverscmp +-check_PROGRAMS += test-strverscmp +-EXTRA_DIST += test-strverscmp.c ++#TESTS += test-strverscmp ++#check_PROGRAMS += test-strverscmp ++#EXTRA_DIST += test-strverscmp.c + + ## end gnulib module strverscmp-tests + diff -urN coreutils-6.11-orig/tests/mkdir/selinux coreutils-6.11/tests/mkdir/selinux --- coreutils-6.11-orig/tests/mkdir/selinux 2008-04-19 23:34:23.000000000 +0200 +++ coreutils-6.11/tests/mkdir/selinux 2008-04-22 13:23:50.000000000 +0200 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 5e6facd..f280ede 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -114,13 +114,13 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am --- coreutils-6.12-orig/tests/Makefile.am 2008-05-27 13:47:53.000000000 +0200 +++ coreutils-6.12/tests/Makefile.am 2008-06-02 10:06:03.000000000 +0200 @@ -192,6 +192,7 @@ - misc/sort \ misc/sort-compress \ + misc/sort-continue \ misc/sort-files0-from \ + misc/sort-mb-tests \ misc/sort-merge \ + misc/sort-merge-fdlimit \ misc/sort-rand \ - misc/sort-version \ @@ -391,6 +392,10 @@ $(root_tests) @@ -2786,7 +2786,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c @@ -416,7 +454,20 @@ - #define NULLCOL (COLUMN *)0 + typedef struct COLUMN COLUMN; -static int char_to_clump (char c); +/* Funtion pointers to switch functions for single byte locale or for diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 5de8f58..6e9a0f2 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -407,7 +407,7 @@ --- coreutils-7.1/configure.ac.pam +++ coreutils-7.1/configure.ac @@ -44,6 +44,13 @@ - [enable compile-time and run-time bounds-checking, and some warnings]) + AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) fi +dnl Give the chance to enable PAM diff --git a/coreutils.spec b/coreutils.spec index 4813efe..cbe4076 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -312,6 +312,7 @@ fi * Tue Mar 31 2009 Ondrej Vasik 7.2-1 - New upstream bugfix release 7.2 - removed applied patches +- temporarily disable strverscmp failing gnulib test * Thu Mar 19 2009 Ondrej Vasik 7.1-7 - do not ship /etc/DIR_COLORS.xterm - as many terminals From 187c0782af63346c5e8d549d715c2c3e11624775 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 17 Apr 2009 09:54:04 +0000 Subject: [PATCH 029/523] make mv xattr support failures silent (as is done for cp -a) - #496142 --- coreutils-silentmv.patch | 12 ++++++++++++ coreutils.spec | 11 ++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 coreutils-silentmv.patch diff --git a/coreutils-silentmv.patch b/coreutils-silentmv.patch new file mode 100644 index 0000000..ab1a293 --- /dev/null +++ b/coreutils-silentmv.patch @@ -0,0 +1,12 @@ +diff -urNp coreutils-7.2-orig/src/mv.c coreutils-7.2/src/mv.c +--- coreutils-7.2-orig/src/mv.c 2009-04-17 11:48:39.000000000 +0200 ++++ coreutils-7.2/src/mv.c 2009-04-17 11:49:17.000000000 +0200 +@@ -117,7 +117,7 @@ cp_option_init (struct cp_options *x) + x->preserve_timestamps = true; + x->preserve_security_context = selinux_enabled; + x->set_security_context = false; +- x->reduce_diagnostics = false; ++ x->reduce_diagnostics = true; + x->require_preserve = false; /* FIXME: maybe make this an option */ + x->require_preserve_context = false; + x->preserve_xattr = true; diff --git a/coreutils.spec b/coreutils.spec index cbe4076..ae1d32b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.2 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -49,6 +49,9 @@ Patch916: coreutils-getfacl-exit-code.patch Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch +Patch960: coreutils-silentmv.patch + + BuildRequires: libselinux-devel >= 1.25.6-1 BuildRequires: libacl-devel BuildRequires: gettext bison @@ -124,6 +127,8 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman +%patch960 -p1 -b .silentmv + chmod a+x tests/misc/sort-mb-tests sed -i 's/1.10a/1.10.1/' configure.ac @@ -309,6 +314,10 @@ fi /sbin/runuser %changelog +* Fri Apr 17 2009 Ondrej Vasik 7.2-2 +- make mv xattr support failures silent (as is done for + cp -a) - #496142 + * Tue Mar 31 2009 Ondrej Vasik 7.2-1 - New upstream bugfix release 7.2 - removed applied patches From 64938e3ecca8e5e25a5cd9c5d983f5b75b948853 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 17 Apr 2009 13:27:36 +0000 Subject: [PATCH 030/523] suppress mv diagnostics only for ENOTSUP and ENODATA, do not run test-memchr gnulib test (koji failure) --- coreutils-6.10-configuration.patch | 13 ++++++++++++ coreutils-silentmv.patch | 33 +++++++++++++++++++----------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 172754c..c814575 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,6 +1,19 @@ diff -urNp coreutils-7.2-orig/gnulib-tests/gnulib.mk coreutils-7.2/gnulib-tests/gnulib.mk --- coreutils-7.2-orig/gnulib-tests/gnulib.mk 2009-03-31 14:28:30.000000000 +0200 +++ coreutils-7.2/gnulib-tests/gnulib.mk 2009-04-01 12:37:00.000000000 +0200 +@@ -606,9 +606,9 @@ EXTRA_DIST += test-mbsstr1.c test-mbsstr + + ## begin gnulib module memchr-tests + +-TESTS += test-memchr +-check_PROGRAMS += test-memchr +-EXTRA_DIST += test-memchr.c ++#TESTS += test-memchr ++#check_PROGRAMS += test-memchr ++#EXTRA_DIST += test-memchr.c + + ## end gnulib module memchr-tests + @@ -910,9 +910,9 @@ EXTRA_DIST += test-strtod.c ## begin gnulib module strverscmp-tests diff --git a/coreutils-silentmv.patch b/coreutils-silentmv.patch index ab1a293..2f7f02b 100644 --- a/coreutils-silentmv.patch +++ b/coreutils-silentmv.patch @@ -1,12 +1,21 @@ -diff -urNp coreutils-7.2-orig/src/mv.c coreutils-7.2/src/mv.c ---- coreutils-7.2-orig/src/mv.c 2009-04-17 11:48:39.000000000 +0200 -+++ coreutils-7.2/src/mv.c 2009-04-17 11:49:17.000000000 +0200 -@@ -117,7 +117,7 @@ cp_option_init (struct cp_options *x) - x->preserve_timestamps = true; - x->preserve_security_context = selinux_enabled; - x->set_security_context = false; -- x->reduce_diagnostics = false; -+ x->reduce_diagnostics = true; - x->require_preserve = false; /* FIXME: maybe make this an option */ - x->require_preserve_context = false; - x->preserve_xattr = true; +diff -urNp coreutils-7.2-orig/src/copy.c coreutils-7.2/src/copy.c +--- coreutils-7.2-orig/src/copy.c 2009-04-17 15:21:26.000000000 +0200 ++++ coreutils-7.2/src/copy.c 2009-04-17 15:24:17.000000000 +0200 +@@ -139,10 +139,13 @@ copy_attr_error (struct error_context *c + int err = errno; + va_list ap; + +- /* use verror module to print error message */ +- va_start (ap, fmt); +- verror (0, err, fmt, ap); +- va_end (ap); ++ if (errno != ENOTSUP && errno != ENODATA) ++ { ++ /* use verror module to print error message */ ++ va_start (ap, fmt); ++ verror (0, err, fmt, ap); ++ va_end (ap); ++ } + } + + static char const * From 17e0cac95597d645f0d8a56a5f3f679bc1f75641 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 23 Apr 2009 17:01:01 +0000 Subject: [PATCH 031/523] fix segfaults in join (i18n patch) when using multibyte locales(#497368) --- coreutils-i18n.patch | 12 ++++++------ coreutils.spec | 6 +++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index f280ede..153c340 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -433,7 +433,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am + + memset (&state, 0, sizeof (mbstate_t)); + -+ if (ptr == lim) ++ if (ptr >= lim) + return; + + if (tab != NULL) @@ -464,7 +464,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am + } + } + -+ if (sep == lim) ++ if (sep >= lim) + break; + + extract_field (line, ptr, sep - ptr); @@ -505,7 +505,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am + mblength = (mblength < 1) ? 1 : mblength; + + sep = ptr + mblength; -+ while (sep != lim) ++ while (sep < lim) + { + state_bak = state; + mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); @@ -524,7 +524,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am + } + + extract_field (line, ptr, sep - ptr); -+ if (sep == lim) ++ if (sep >= lim) + return; + + state_bak = state; @@ -538,7 +538,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am + mblength = (mblength < 1) ? 1 : mblength; + + ptr = sep + mblength; -+ while (ptr != lim) ++ while (ptr < lim) + { + state_bak = state; + mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); @@ -556,7 +556,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am + ptr += mblength; + } + } -+ while (ptr != lim); ++ while (ptr < lim); + } + + extract_field (line, ptr, lim - ptr); diff --git a/coreutils.spec b/coreutils.spec index ae1d32b..d3a1908 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.2 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -314,6 +314,10 @@ fi /sbin/runuser %changelog +* Thu Apr 23 2009 Ondrej Vasik 7.2-3 +- fix segfaults in join (i18n patch) when using multibyte + locales(#497368) + * Fri Apr 17 2009 Ondrej Vasik 7.2-2 - make mv xattr support failures silent (as is done for cp -a) - #496142 From 67e264c1422e0aeda3e15bc35b529f1281b2083c Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 25 May 2009 12:11:34 +0000 Subject: [PATCH 032/523] new upstream release 7.4, removed applied patches --- .cvsignore | 2 +- coreutils-5.2.1-runuser.patch | 6 +++--- coreutils-selinux.patch | 20 +++----------------- coreutils.spec | 15 +++++---------- sources | 2 +- 5 files changed, 13 insertions(+), 32 deletions(-) diff --git a/.cvsignore b/.cvsignore index c47163f..7cd2c15 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-7.2.tar.gz +coreutils-7.4.tar.gz diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index 6ff3085..d88def4 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -1,14 +1,14 @@ diff -urNp coreutils-7.0.orig/AUTHORS coreutils-7.0/AUTHORS --- coreutils-7.0.orig/AUTHORS 2008-08-24 22:58:15.000000000 +0200 +++ coreutils-7.0/AUTHORS 2009-01-28 18:11:00.316247411 +0100 -@@ -63,6 +63,7 @@ pwd: Jim Meyering - readlink: Dmitry V. Levin +@@ -64,6 +64,7 @@ pwd: Jim Meyering rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering rmdir: David MacKenzie -+runuser: David MacKenzie, Dan Walsh runcon: Russell Coker ++runuser: David MacKenzie, Dan Walsh seq: Ulrich Drepper sha1sum: Ulrich Drepper, Scott Miller, David Madore + sha224sum: Ulrich Drepper, Scott Miller, David Madore diff -urNp coreutils-7.0.orig/man/Makefile.am coreutils-7.0/man/Makefile.am --- coreutils-7.0.orig/man/Makefile.am 2008-09-27 19:28:54.000000000 +0200 +++ coreutils-7.0/man/Makefile.am 2009-01-28 18:11:00.317247417 +0100 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 247a879..21bd492 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -177,20 +177,6 @@ diff -urNp coreutils-7.1-orig/src/id.c coreutils-7.1/src/id.c diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c --- coreutils-7.1-orig/src/install.c 2009-02-18 15:32:52.000000000 +0100 +++ coreutils-7.1/src/install.c 2009-02-24 13:47:15.000000000 +0100 -@@ -157,11 +157,11 @@ static struct option const long_options[ - {"no-target-directory", no_argument, NULL, 'T'}, - {"owner", required_argument, NULL, 'o'}, - {"preserve-timestamps", no_argument, NULL, 'p'}, -- {"preserve-context", no_argument, NULL, PRESERVE_CONTEXT_OPTION}, -+ {"preserve-context", no_argument, NULL, 'P'}, - /* Continue silent support for --preserve_context until Jan 2008. FIXME-obs - After that, FIXME-obs: warn in, say, late 2008, and disable altogether - a year or two later. */ -- {"preserve_context", no_argument, NULL, PRESERVE_CONTEXT_OPTION}, -+ {"preserve_context", no_argument, NULL, 'P'}, - {"strip", no_argument, NULL, 's'}, - {"strip-program", required_argument, NULL, STRIP_PROGRAM_OPTION}, - {"suffix", required_argument, NULL, 'S'}, @@ -292,6 +292,7 @@ cp_option_init (struct cp_options *x) x->reduce_diagnostics=false; x->require_preserve = false; @@ -209,9 +195,9 @@ diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c { switch (optc) @@ -539,6 +540,7 @@ main (int argc, char **argv) - no_target_directory = true; - break; - + error (0, 0, _("WARNING: --preserve_context is deprecated; " + "use --preserve-context instead")); + /* fall through */ + case 'P': case PRESERVE_CONTEXT_OPTION: if ( ! selinux_enabled) diff --git a/coreutils.spec b/coreutils.spec index d3a1908..88254a5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 7.2 -Release: 3%{?dist} +Version: 7.4 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -49,9 +49,6 @@ Patch916: coreutils-getfacl-exit-code.patch Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch -Patch960: coreutils-silentmv.patch - - BuildRequires: libselinux-devel >= 1.25.6-1 BuildRequires: libacl-devel BuildRequires: gettext bison @@ -127,13 +124,8 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -%patch960 -p1 -b .silentmv - chmod a+x tests/misc/sort-mb-tests -sed -i 's/1.10a/1.10.1/' configure.ac -sed -i 's/dist-xz/dist-lzma/' configure.ac - #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ sed -i \ @@ -314,6 +306,9 @@ fi /sbin/runuser %changelog +* Mon May 25 2009 Ondrej Vasik 7.4-1 +- new upstream release 7.4, removed applied patches + * Thu Apr 23 2009 Ondrej Vasik 7.2-3 - fix segfaults in join (i18n patch) when using multibyte locales(#497368) diff --git a/sources b/sources index a167571..1df53be 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -427c2914d3eab956f317c9ec6a45e62a coreutils-7.2.tar.gz +c52f4f64dda9a245c38e74c09fdd86d2 coreutils-7.4.tar.gz From 7f2b3258d5bbf354c340b898c1f53155091c9199 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 11 Jun 2009 08:26:29 +0000 Subject: [PATCH 033/523] temporarily workaround probable kernel issue with TCSADRAIN(#504798) --- coreutils-7.4-sttytcsadrain.patch | 12 ++++++++++++ coreutils.spec | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 coreutils-7.4-sttytcsadrain.patch diff --git a/coreutils-7.4-sttytcsadrain.patch b/coreutils-7.4-sttytcsadrain.patch new file mode 100644 index 0000000..af25979 --- /dev/null +++ b/coreutils-7.4-sttytcsadrain.patch @@ -0,0 +1,12 @@ +diff -urNp coreutils-7.4-orig/src/stty.c coreutils-7.4/src/stty.c +--- coreutils-7.4-orig/src/stty.c 2009-04-24 14:41:19.000000000 +0200 ++++ coreutils-7.4/src/stty.c 2009-06-11 10:15:41.000000000 +0200 +@@ -1001,7 +1001,7 @@ main (int argc, char **argv) + spurious difference in an uninitialized portion of the structure. */ + DECLARE_ZEROED_AGGREGATE (struct termios, new_mode); + +- if (tcsetattr (STDIN_FILENO, TCSADRAIN, &mode)) ++ if (tcsetattr (STDIN_FILENO, TCSANOW, &mode)) + error (EXIT_FAILURE, errno, "%s", device_name); + + /* POSIX (according to Zlotnick's book) tcsetattr returns zero if diff --git a/coreutils.spec b/coreutils.spec index 88254a5..e61e4d4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.4 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -23,6 +23,7 @@ Source203: coreutils-runuser-l.pamd # Our patches Patch100: coreutils-6.10-configuration.patch Patch101: coreutils-6.10-manpages.patch +Patch102: coreutils-7.4-sttytcsadrain.patch # sh-utils Patch703: sh-utils-2.0.11-dateman.patch @@ -102,6 +103,7 @@ the old GNU fileutils, sh-utils, and textutils packages. # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages +%patch102 -p1 -b .tcsadrain # sh-utils %patch703 -p1 -b .dateman @@ -306,6 +308,10 @@ fi /sbin/runuser %changelog +* Thu Jun 16 2009 Ondrej Vasik 7.4-2 +- temporarily workaround probable kernel issue with + TCSADRAIN(#504798) + * Mon May 25 2009 Ondrej Vasik 7.4-1 - new upstream release 7.4, removed applied patches From 777ce54cea5e3aac13de242e07c6dbc782f7a3ac Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 6 Jul 2009 21:40:43 +0000 Subject: [PATCH 034/523] do not ignore sort's version sort for multibyte locales(#509688) --- coreutils-i18n.patch | 12 +++++++----- coreutils.spec | 6 +++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 153c340..a784665 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2204,7 +2204,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { struct keyfield const *key = keylist; -@@ -1875,6 +2265,179 @@ +@@ -1875,6 +2265,181 @@ return key->reverse ? -diff : diff; } @@ -2254,6 +2254,8 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + (texta, textb)); + *lima = savea, *limb = saveb; + } ++ else if (key->version) ++ diff = compare_version (texta, lena, textb, lenb); + else if (key->month) + diff = getmonth (texta, lena) - getmonth (textb, lenb); + else @@ -2384,7 +2386,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2744,7 +3305,7 @@ +@@ -2744,7 +3307,7 @@ initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2393,7 +2395,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -2765,6 +3326,27 @@ +@@ -2765,6 +3328,27 @@ thousands_sep = -1; } @@ -2421,7 +2423,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c have_read_stdin = false; inittables (); -@@ -3015,13 +3597,35 @@ +@@ -3015,13 +3599,35 @@ case 't': { @@ -2461,7 +2463,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c else { /* Provoke with `sort -txx'. Complain about -@@ -3032,9 +3636,12 @@ +@@ -3032,9 +3638,12 @@ quote (optarg)); } } diff --git a/coreutils.spec b/coreutils.spec index e61e4d4..bc40e9e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.4 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -308,6 +308,10 @@ fi /sbin/runuser %changelog +* Mon Jul 06 2009 Ondrej Vasik 7.4-3 +- do not ignore sort's version sort for multibyte locales + (#509688) + * Thu Jun 16 2009 Ondrej Vasik 7.4-2 - temporarily workaround probable kernel issue with TCSADRAIN(#504798) From 3dc23f351868c2de61b895c73ebd7fa349c27208 Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Fri, 24 Jul 2009 19:30:04 +0000 Subject: [PATCH 035/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index bc40e9e..2d84bf0 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.4 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -308,6 +308,9 @@ fi /sbin/runuser %changelog +* Fri Jul 24 2009 Fedora Release Engineering - 7.4-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + * Mon Jul 06 2009 Ondrej Vasik 7.4-3 - do not ignore sort's version sort for multibyte locales (#509688) From ff18ef69d37b1e40df17ac2bfb1e5ad599ed6f35 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 5 Aug 2009 08:45:05 +0000 Subject: [PATCH 036/523] - ls -1U with two or more arguments (or with -R or -s) works properly again - install runs faster again with SELinux enabled (#479502) --- coreutils-7.4-install-SELinux.patch | 26 ++++++++ coreutils-7.4-ls-1U.patch | 92 +++++++++++++++++++++++++++++ coreutils.spec | 10 +++- 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 coreutils-7.4-install-SELinux.patch create mode 100644 coreutils-7.4-ls-1U.patch diff --git a/coreutils-7.4-install-SELinux.patch b/coreutils-7.4-install-SELinux.patch new file mode 100644 index 0000000..00e7e19 --- /dev/null +++ b/coreutils-7.4-install-SELinux.patch @@ -0,0 +1,26 @@ +diff -ruNp coreutils-7.4.orig/m4/jm-macros.m4 coreutils-7.4/m4/jm-macros.m4 +--- coreutils-7.4.orig/m4/jm-macros.m4 2009-08-05 10:27:30.660795719 +0200 ++++ coreutils-7.4/m4/jm-macros.m4 2009-08-05 10:30:46.912858189 +0200 +@@ -47,7 +47,21 @@ AC_DEFUN([coreutils_MACROS], + AC_CHECK_FUNCS_ONCE([directio]) + + # Used by install.c. +- AC_CHECK_FUNCS_ONCE([matchpathcon_init_prefix]) ++ coreutils_saved_libs=$LIBS ++ LIBS="$LIBS $LIB_SELINUX" ++ AC_CHECK_FUNCS([matchpathcon_init_prefix], [], ++ [ ++ case "$ac_cv_search_setfilecon:$ac_cv_header_selinux_selinux_h" in ++ no:*) # SELinux disabled ++ ;; ++ *:no) # SELinux disabled ++ ;; ++ *) ++ AC_MSG_WARN([SELinux enabled, but matchpathcon_init_prefix not found]) ++ AC_MSG_WARN([The install utility may run slowly]) ++ esac ++ ]) ++ LIBS=$coreutils_saved_libs + + # Used by sort.c. + AC_CHECK_FUNCS_ONCE([nl_langinfo]) diff --git a/coreutils-7.4-ls-1U.patch b/coreutils-7.4-ls-1U.patch new file mode 100644 index 0000000..bcfe779 --- /dev/null +++ b/coreutils-7.4-ls-1U.patch @@ -0,0 +1,92 @@ +diff -ruNp coreutils-7.4.orig/src/ls.c coreutils-7.4/src/ls.c +--- coreutils-7.4.orig/src/ls.c 2009-08-05 10:14:46.397545653 +0200 ++++ coreutils-7.4/src/ls.c 2009-08-05 10:20:47.564858256 +0200 +@@ -2480,6 +2480,19 @@ print_dir (char const *name, char const + DEV_INO_PUSH (dir_stat.st_dev, dir_stat.st_ino); + } + ++ if (recursive | print_dir_name) ++ { ++ if (!first) ++ DIRED_PUTCHAR ('\n'); ++ first = false; ++ DIRED_INDENT (); ++ PUSH_CURRENT_DIRED_POS (&subdired_obstack); ++ dired_pos += quote_name (stdout, realname ? realname : name, ++ dirname_quoting_options, NULL); ++ PUSH_CURRENT_DIRED_POS (&subdired_obstack); ++ DIRED_FPUTS_LITERAL (":\n", stdout); ++ } ++ + /* Read the directory entries, and insert the subfiles into the `cwd_file' + table. */ + +@@ -2519,7 +2532,8 @@ print_dir (char const *name, char const + ls uses constant memory while processing the entries of + this directory. Useful when there are many (millions) + of entries in a directory. */ +- if (format == one_per_line && sort_type == sort_none) ++ if (format == one_per_line && sort_type == sort_none ++ && !print_block_size && !recursive) + { + /* We must call sort_files in spite of + "sort_type == sort_none" for its initialization +@@ -2555,19 +2569,6 @@ print_dir (char const *name, char const + if (recursive) + extract_dirs_from_files (name, command_line_arg); + +- if (recursive | print_dir_name) +- { +- if (!first) +- DIRED_PUTCHAR ('\n'); +- first = false; +- DIRED_INDENT (); +- PUSH_CURRENT_DIRED_POS (&subdired_obstack); +- dired_pos += quote_name (stdout, realname ? realname : name, +- dirname_quoting_options, NULL); +- PUSH_CURRENT_DIRED_POS (&subdired_obstack); +- DIRED_FPUTS_LITERAL (":\n", stdout); +- } +- + if (format == long_format || print_block_size) + { + const char *p; +diff -ruNp coreutils-7.4.orig/tests/misc/ls-misc coreutils-7.4/tests/misc/ls-misc +--- coreutils-7.4.orig/tests/misc/ls-misc 2009-04-24 14:50:28.000000000 +0200 ++++ coreutils-7.4/tests/misc/ls-misc 2009-08-05 10:20:47.564858256 +0200 +@@ -18,6 +18,7 @@ + use strict; + + (my $program_name = $0) =~ s|.*/||; ++my $prog = 'ls'; + + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; +@@ -224,6 +225,18 @@ my @Tests = + {PRE => sub { mk_file @v_files }}, + {POST => sub { unlink @v_files }}, + ], ++ ++ # Test for the ls -1U bug fixed in coreutils-7.5. ++ # It is triggered only with -1U and with two or more arguments, ++ # at least one of which is a nonempty directory. ++ ['multi-arg-U1', '-U1 d no-such', ++ {OUT => "d:\nf\n"}, ++ {ERR_SUBST=>'s/ch:.*/ch:/'}, ++ {ERR => "$prog: cannot access no-such:\n"}, ++ $mkdir_reg, ++ $rmdir_reg, ++ {EXIT => 2}, ++ ], + ); + + # Start with an unset LS_COLORS environment variable. +@@ -232,8 +245,6 @@ delete $ENV{LS_COLORS}; + my $save_temps = $ENV{SAVE_TEMPS}; + my $verbose = $ENV{VERBOSE}; + +-my $prog = 'ls'; +- + setuid_setup; + my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); + $fail diff --git a/coreutils.spec b/coreutils.spec index 2d84bf0..2acc004 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.4 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -19,6 +19,8 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream +Patch1: coreutils-7.4-ls-1U.patch +Patch2: coreutils-7.4-install-SELinux.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -99,6 +101,8 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream +%patch1 -p1 -b .ls-1U +%patch2 -p1 -b .install-SELinux # Our patches %patch100 -p1 -b .configure @@ -308,6 +312,10 @@ fi /sbin/runuser %changelog +* Wed Aug 05 2009 Kamil Dudka - 7.4-5 +- ls -1U with two or more arguments (or with -R or -s) works properly again +- install runs faster again with SELinux enabled (#479502) + * Fri Jul 24 2009 Fedora Release Engineering - 7.4-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild From 7915d210f22a071673c6ff034c002579c6bfdc44 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 6 Aug 2009 13:24:22 +0000 Subject: [PATCH 037/523] do process install-info only with info files present(#515970), BuildRequire for xz-utils, use xz tarball --- .cvsignore | 2 +- coreutils.spec | 18 ++++++++++++++---- sources | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.cvsignore b/.cvsignore index 7cd2c15..a4d027e 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-7.4.tar.gz +coreutils-7.4.tar.xz diff --git a/coreutils.spec b/coreutils.spec index 2acc004..f176ba5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,13 +1,12 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.4 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -#Using .tar.gz tarball until xz utils will be in Fedora -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color @@ -62,6 +61,7 @@ BuildRequires: automake >= 1.10.1 BuildRequires: libcap-devel >= 2.0.6 BuildRequires: libattr-devel BuildRequires: attr +BuildRequires: xz-utils Requires(post): libselinux >= 1.25.6-1 Requires: libattr @@ -247,19 +247,25 @@ rm -rf $RPM_BUILD_ROOT # coreutils.info. else their postun'll be run too late # and install-info will fail badly because of duplicates for file in sh-utils textutils fileutils; do + if [ -f %{_infodir}/$file.info ]; then /sbin/install-info --delete %{_infodir}/$file.info --dir=%{_infodir}/dir &> /dev/null || : + fi done %preun if [ $1 = 0 ]; then + if [ -f %{_infodir}/%{name}.info ]; then /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || : + fi fi %post /bin/grep -v '(sh-utils)\|(fileutils)\|(textutils)' %{_infodir}/dir > \ %{_infodir}/dir.rpmmodify || exit 0 /bin/mv -f %{_infodir}/dir.rpmmodify %{_infodir}/dir -/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || : +if [ -f %{_infodir}/%{name}.info ]; then + /sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || : +fi %files -f %{name}.lang %defattr(-,root,root,-) @@ -312,6 +318,10 @@ fi /sbin/runuser %changelog +* Thu Aug 06 2009 Ondrej Vasik - 7.4-6 +- do process install-info only with info files present(#515970) +- BuildRequire for xz-utils, use xz tarball + * Wed Aug 05 2009 Kamil Dudka - 7.4-5 - ls -1U with two or more arguments (or with -R or -s) works properly again - install runs faster again with SELinux enabled (#479502) diff --git a/sources b/sources index 1df53be..6d7fa70 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -c52f4f64dda9a245c38e74c09fdd86d2 coreutils-7.4.tar.gz +e8d906c153f271430e3efb2b9a35a35f coreutils-7.4.tar.xz From 378338cdefd4e7c130508b0e5bb9cde215365095 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 6 Aug 2009 13:31:14 +0000 Subject: [PATCH 038/523] package is xz, not xz-utils --- coreutils.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index f176ba5..881621f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -61,7 +61,7 @@ BuildRequires: automake >= 1.10.1 BuildRequires: libcap-devel >= 2.0.6 BuildRequires: libattr-devel BuildRequires: attr -BuildRequires: xz-utils +BuildRequires: xz Requires(post): libselinux >= 1.25.6-1 Requires: libattr @@ -320,7 +320,7 @@ fi %changelog * Thu Aug 06 2009 Ondrej Vasik - 7.4-6 - do process install-info only with info files present(#515970) -- BuildRequire for xz-utils, use xz tarball +- BuildRequires for xz, use xz tarball * Wed Aug 05 2009 Kamil Dudka - 7.4-5 - ls -1U with two or more arguments (or with -R or -s) works properly again From e1052e34a1046e4cce06d6fcdd67279e55038b1a Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 21 Aug 2009 07:00:59 +0000 Subject: [PATCH 039/523] New upstream release 7.5, remove already applied patches,defuzz few others --- .cvsignore | 2 +- coreutils-5.2.1-runuser.patch | 22 +++---- coreutils-6.10-configuration.patch | 4 +- coreutils-7.4-install-SELinux.patch | 26 -------- coreutils-7.4-ls-1U.patch | 92 ----------------------------- coreutils-i18n.patch | 4 +- coreutils.spec | 12 ++-- sources | 2 +- 8 files changed, 23 insertions(+), 141 deletions(-) delete mode 100644 coreutils-7.4-install-SELinux.patch delete mode 100644 coreutils-7.4-ls-1U.patch diff --git a/.cvsignore b/.cvsignore index a4d027e..2d04123 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-7.4.tar.xz +coreutils-7.5.tar.xz diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index d88def4..f879cdd 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -44,13 +44,13 @@ diff -urNp coreutils-7.0.orig/README coreutils-7.0/README link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir - runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf -- sleep sort split stat stty su sum sync tac tail tee test timeout touch tr -- true truncate tsort tty uname unexpand uniq unlink uptime users vdir wc who -- whoami yes +- sleep sort split stat stdbuf stty su sum sync tac tail tee test timeout +- touch tr true truncate tsort tty uname unexpand uniq unlink uptime users +- vdir wc who whoami yes + runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum shred -+ shuf sleep sort split stat stty su sum sync tac tail tee test timeout touch -+ tr true truncate tsort tty uname unexpand uniq unlink uptime users vdir wc -+ who whoami yes ++ shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test ++ timeout touch tr true truncate tsort tty uname unexpand uniq unlink uptime ++ users vdir wc who whoami yes See the file NEWS for a list of major changes in the current release. @@ -355,13 +355,13 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c +#endif + ); } -diff -urNp coreutils-7.0.orig/tests/misc/help-version coreutils-7.0/tests/misc/help-version ---- coreutils-7.0.orig/tests/misc/help-version 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/tests/misc/help-version 2009-01-28 18:11:00.321247443 +0100 -@@ -148,6 +148,7 @@ printf_args=foo - seq_args=10 +diff -urNp coreutils-7.5.orig/tests/misc/help-version coreutils-7.5/tests/misc/help-version +--- coreutils-7.5.orig/tests/misc/help-version ++++ coreutils-7.5/tests/misc/help-version +@@ -150,6 +150,7 @@ printf_args=foo sleep_args=0 su_args=--version + stdbuf_args="-oL true" +runuser_args=--version timeout_args=--version diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index c814575..c0813cb 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -7,10 +7,10 @@ diff -urNp coreutils-7.2-orig/gnulib-tests/gnulib.mk coreutils-7.2/gnulib-tests/ -TESTS += test-memchr -check_PROGRAMS += test-memchr --EXTRA_DIST += test-memchr.c +-EXTRA_DIST += test-memchr.c zerosize-ptr.h +#TESTS += test-memchr +#check_PROGRAMS += test-memchr -+#EXTRA_DIST += test-memchr.c ++#EXTRA_DIST += test-memchr.c zerosize-ptr.h ## end gnulib module memchr-tests diff --git a/coreutils-7.4-install-SELinux.patch b/coreutils-7.4-install-SELinux.patch deleted file mode 100644 index 00e7e19..0000000 --- a/coreutils-7.4-install-SELinux.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff -ruNp coreutils-7.4.orig/m4/jm-macros.m4 coreutils-7.4/m4/jm-macros.m4 ---- coreutils-7.4.orig/m4/jm-macros.m4 2009-08-05 10:27:30.660795719 +0200 -+++ coreutils-7.4/m4/jm-macros.m4 2009-08-05 10:30:46.912858189 +0200 -@@ -47,7 +47,21 @@ AC_DEFUN([coreutils_MACROS], - AC_CHECK_FUNCS_ONCE([directio]) - - # Used by install.c. -- AC_CHECK_FUNCS_ONCE([matchpathcon_init_prefix]) -+ coreutils_saved_libs=$LIBS -+ LIBS="$LIBS $LIB_SELINUX" -+ AC_CHECK_FUNCS([matchpathcon_init_prefix], [], -+ [ -+ case "$ac_cv_search_setfilecon:$ac_cv_header_selinux_selinux_h" in -+ no:*) # SELinux disabled -+ ;; -+ *:no) # SELinux disabled -+ ;; -+ *) -+ AC_MSG_WARN([SELinux enabled, but matchpathcon_init_prefix not found]) -+ AC_MSG_WARN([The install utility may run slowly]) -+ esac -+ ]) -+ LIBS=$coreutils_saved_libs - - # Used by sort.c. - AC_CHECK_FUNCS_ONCE([nl_langinfo]) diff --git a/coreutils-7.4-ls-1U.patch b/coreutils-7.4-ls-1U.patch deleted file mode 100644 index bcfe779..0000000 --- a/coreutils-7.4-ls-1U.patch +++ /dev/null @@ -1,92 +0,0 @@ -diff -ruNp coreutils-7.4.orig/src/ls.c coreutils-7.4/src/ls.c ---- coreutils-7.4.orig/src/ls.c 2009-08-05 10:14:46.397545653 +0200 -+++ coreutils-7.4/src/ls.c 2009-08-05 10:20:47.564858256 +0200 -@@ -2480,6 +2480,19 @@ print_dir (char const *name, char const - DEV_INO_PUSH (dir_stat.st_dev, dir_stat.st_ino); - } - -+ if (recursive | print_dir_name) -+ { -+ if (!first) -+ DIRED_PUTCHAR ('\n'); -+ first = false; -+ DIRED_INDENT (); -+ PUSH_CURRENT_DIRED_POS (&subdired_obstack); -+ dired_pos += quote_name (stdout, realname ? realname : name, -+ dirname_quoting_options, NULL); -+ PUSH_CURRENT_DIRED_POS (&subdired_obstack); -+ DIRED_FPUTS_LITERAL (":\n", stdout); -+ } -+ - /* Read the directory entries, and insert the subfiles into the `cwd_file' - table. */ - -@@ -2519,7 +2532,8 @@ print_dir (char const *name, char const - ls uses constant memory while processing the entries of - this directory. Useful when there are many (millions) - of entries in a directory. */ -- if (format == one_per_line && sort_type == sort_none) -+ if (format == one_per_line && sort_type == sort_none -+ && !print_block_size && !recursive) - { - /* We must call sort_files in spite of - "sort_type == sort_none" for its initialization -@@ -2555,19 +2569,6 @@ print_dir (char const *name, char const - if (recursive) - extract_dirs_from_files (name, command_line_arg); - -- if (recursive | print_dir_name) -- { -- if (!first) -- DIRED_PUTCHAR ('\n'); -- first = false; -- DIRED_INDENT (); -- PUSH_CURRENT_DIRED_POS (&subdired_obstack); -- dired_pos += quote_name (stdout, realname ? realname : name, -- dirname_quoting_options, NULL); -- PUSH_CURRENT_DIRED_POS (&subdired_obstack); -- DIRED_FPUTS_LITERAL (":\n", stdout); -- } -- - if (format == long_format || print_block_size) - { - const char *p; -diff -ruNp coreutils-7.4.orig/tests/misc/ls-misc coreutils-7.4/tests/misc/ls-misc ---- coreutils-7.4.orig/tests/misc/ls-misc 2009-04-24 14:50:28.000000000 +0200 -+++ coreutils-7.4/tests/misc/ls-misc 2009-08-05 10:20:47.564858256 +0200 -@@ -18,6 +18,7 @@ - use strict; - - (my $program_name = $0) =~ s|.*/||; -+my $prog = 'ls'; - - # Turn off localization of executable's output. - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; -@@ -224,6 +225,18 @@ my @Tests = - {PRE => sub { mk_file @v_files }}, - {POST => sub { unlink @v_files }}, - ], -+ -+ # Test for the ls -1U bug fixed in coreutils-7.5. -+ # It is triggered only with -1U and with two or more arguments, -+ # at least one of which is a nonempty directory. -+ ['multi-arg-U1', '-U1 d no-such', -+ {OUT => "d:\nf\n"}, -+ {ERR_SUBST=>'s/ch:.*/ch:/'}, -+ {ERR => "$prog: cannot access no-such:\n"}, -+ $mkdir_reg, -+ $rmdir_reg, -+ {EXIT => 2}, -+ ], - ); - - # Start with an unset LS_COLORS environment variable. -@@ -232,8 +245,6 @@ delete $ENV{LS_COLORS}; - my $save_temps = $ENV{SAVE_TEMPS}; - my $verbose = $ENV{VERBOSE}; - --my $prog = 'ls'; -- - setuid_setup; - my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); - $fail diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index a784665..8f39241 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2089,7 +2089,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c while (blanks[to_uchar (*a)]) a++; @@ -1510,6 +1813,25 @@ - return strnumcmp (a, b, decimal_point, thousands_sep); + : strnumcmp (a, b, decimal_point, thousands_sep)); } +#if HAVE_MBRTOWC @@ -2202,7 +2202,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c -keycompare (const struct line *a, const struct line *b) +keycompare_uni (const struct line *a, const struct line *b) { - struct keyfield const *key = keylist; + struct keyfield *key = keylist; @@ -1875,6 +2265,181 @@ return key->reverse ? -diff : diff; diff --git a/coreutils.spec b/coreutils.spec index 881621f..bd4554c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 7.4 -Release: 6%{?dist} +Version: 7.5 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,8 +18,6 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -Patch1: coreutils-7.4-ls-1U.patch -Patch2: coreutils-7.4-install-SELinux.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -101,8 +99,6 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream -%patch1 -p1 -b .ls-1U -%patch2 -p1 -b .install-SELinux # Our patches %patch100 -p1 -b .configure @@ -318,6 +314,10 @@ fi /sbin/runuser %changelog +* Fri Aug 21 2009 Ondrej Vasik - 7.5-1 +- New upstream release 7.5, remove already applied patches, + defuzz few others + * Thu Aug 06 2009 Ondrej Vasik - 7.4-6 - do process install-info only with info files present(#515970) - BuildRequires for xz, use xz tarball diff --git a/sources b/sources index 6d7fa70..577a3ac 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -e8d906c153f271430e3efb2b9a35a35f coreutils-7.4.tar.xz +ca9219c5b7efa533d552f61a3880f458 coreutils-7.5.tar.xz From 1bc86eb295bff3f386fb1d460ee4d89d35de1d05 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 21 Aug 2009 11:49:02 +0000 Subject: [PATCH 040/523] libstdbuf.so in separate coreutils-libs subpackage, update /etc/DIRCOLORS*, skip two new tests on system with insufficient utimensat support(e.g. koji) --- coreutils-7.5-kojiutimensatskip.patch | 26 ++++++++++++++++++++++++++ coreutils-DIR_COLORS | 16 ++++++++++++---- coreutils-DIR_COLORS.256color | 15 +++++++++++---- coreutils-DIR_COLORS.lightbgcolor | 14 ++++++++++---- coreutils.spec | 23 +++++++++++++++++++++-- 5 files changed, 80 insertions(+), 14 deletions(-) create mode 100644 coreutils-7.5-kojiutimensatskip.patch diff --git a/coreutils-7.5-kojiutimensatskip.patch b/coreutils-7.5-kojiutimensatskip.patch new file mode 100644 index 0000000..9ca38f8 --- /dev/null +++ b/coreutils-7.5-kojiutimensatskip.patch @@ -0,0 +1,26 @@ +diff -urNp coreutils-7.5-orig/tests/cp/preserve-slink-time coreutils-7.5/tests/cp/preserve-slink-time +--- coreutils-7.5-orig/tests/cp/preserve-slink-time 2009-08-15 17:25:32.000000000 +0200 ++++ coreutils-7.5/tests/cp/preserve-slink-time 2009-08-21 12:45:41.000000000 +0200 +@@ -28,6 +28,10 @@ grep '^#define HAVE_UTIMENSAT' "$CONFIG_ + + ln -s no-such dangle || framework_failure + ++cp -Pp dangle d3 2>error ++grep 'Function not implemented' error > /dev/null && ++ skip_test_ 'utimensat function not implemented' ++ + # If the current file system lacks sub-second resolution, sleep for 2s to + # ensure that the times on the copy are different from those of the original. + case $(stat --format=%y dangle) in +diff -urNp coreutils-7.5-orig/tests/mv/part-symlink coreutils-7.5/tests/mv/part-symlink +--- coreutils-7.5-orig/tests/mv/part-symlink 2009-08-15 17:25:32.000000000 +0200 ++++ coreutils-7.5/tests/mv/part-symlink 2009-08-21 12:52:13.000000000 +0200 +@@ -201,6 +201,8 @@ cat <<\EOF > $expected + + EOF + ++grep 'Function not implemented' $actual > /dev/null && ++ skip_test_ 'utimensat function not implemented' + # Redirect to stderr, since stdout is already taken. + compare $expected $actual 1>&2 || fail=1 + diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 93da421..a3a14bb 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -50,6 +50,7 @@ TERM rxvt-cygwin-native TERM rxvt-unicode TERM screen TERM screen-256color +TERM screen-256color-bce TERM screen-bce TERM screen-w TERM screen.linux @@ -78,7 +79,7 @@ RESET 0 # reset to "normal" color DIR 01;34 # directory LINK 01;36 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) -HARDLINK 44;37 # regular file with more than one link +MULTIHARDLINK 00 # regular file with more than one link FIFO 40;33 # pipe SOCK 01;35 # socket DOOR 01;35 # door @@ -115,12 +116,16 @@ EXEC 01;32 .taz 01;31 .lzh 01;31 .lzma 01;31 +.tlz 01;31 +.txz 01;31 .zip 01;31 .z 01;31 .Z 01;31 .dz 01;31 .gz 01;31 +.xz 01;31 .bz2 01;31 +.tbz 01;31 .tbz2 01;31 .bz 01;31 .tz 01;31 @@ -133,7 +138,7 @@ EXEC 01;32 .cpio 01;31 .7z 01;31 .rz 01;31 -.xz 01;31 + # image formats (magenta) .jpg 01;35 .jpeg 01;35 @@ -148,6 +153,8 @@ EXEC 01;32 .tif 01;35 .tiff 01;35 .png 01;35 +.svg 01;35 +.svgz 01;35 .mng 01;35 .pcx 01;35 .mov 01;35 @@ -175,13 +182,13 @@ EXEC 01;32 .xcf 01;35 .xwd 01;35 .yuv 01;35 -.svg 01;35 -.svgz 01;35 + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions .axv 01;35 .anx 01;35 .ogv 01;35 .ogx 01;35 + # audio formats (cyan) .aac 01;36 .au 01;36 @@ -194,6 +201,7 @@ EXEC 01;32 .ogg 01;36 .ra 01;36 .wav 01;36 + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions .axa 01;36 .oga 01;36 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index af16bf6..71d8e24 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -55,7 +55,7 @@ RESET 0 # reset to "normal" color DIR 01;38;5;27 # directory LINK 01;38;5;51 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) -HARDLINK 44;38;5;15; # regular file with more than one link +MULTIHARDLINK 44;38;5;15; # regular file with more than one link FIFO 40;38;5;11 # pipe SOCK 01;38;5;13 # socket DOOR 01;38;5;5 # door @@ -91,12 +91,16 @@ EXEC 01;38;5;34 .taz 01;38;5;9 .lzh 01;38;5;9 .lzma 01;38;5;9 +.tlz 01;38;5;9 +.txz 01;38;5;9 .zip 01;38;5;9 .z 01;38;5;9 .Z 01;38;5;9 .dz 01;38;5;9 .gz 01;38;5;9 +.xz 01;38;5;9 .bz2 01;38;5;9 +.tbz 01;38;5;9 .tbz2 01;38;5;9 .bz 01;38;5;9 .tz 01;38;5;9 @@ -109,7 +113,7 @@ EXEC 01;38;5;34 .cpio 01;38;5;9 .7z 01;38;5;9 .rz 01;38;5;9 -.xz 01;38;5;9 + # image formats (magenta) .jpg 01;38;5;13 .jpeg 01;38;5;13 @@ -124,6 +128,8 @@ EXEC 01;38;5;34 .tif 01;38;5;13 .tiff 01;38;5;13 .png 01;38;5;13 +.svg 01;38;5;13 +.svgz 01;38;5;13 .mng 01;38;5;13 .pcx 01;38;5;13 .mov 01;38;5;13 @@ -151,13 +157,13 @@ EXEC 01;38;5;34 .xcf 01;38;5;13 .xwd 01;38;5;13 .yuv 01;38;5;13 -.svg 01;38;5;13 -.svgz 01;38;5;13 + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions .axv 01;38;5;13 .anx 01;38;5;13 .ogv 01;38;5;13 .ogx 01;38;5;13 + # audio formats (cyan) .aac 01;38;5;45 .au 01;38;5;45 @@ -170,6 +176,7 @@ EXEC 01;38;5;34 .ogg 01;38;5;45 .ra 01;38;5;45 .wav 01;38;5;45 + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions .axa 01;38;5;45 .oga 01;38;5;45 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index 6670556..6d8e457 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -58,7 +58,7 @@ RESET 0 DIR 00;34 # directory LINK 00;36 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) -HARDLINK 44;37 # regular file with more than one link +MULTIHARDLINK 00 # regular file with more than one link FIFO 40;33 # pipe SOCK 00;35 # socket DOOR 00;35 # door @@ -94,12 +94,16 @@ EXEC 00;32 .taz 00;31 .lzh 00;31 .lzma 00;31 +.tlz 00;31 +.txz 00;31 .zip 00;31 .z 00;31 .Z 00;31 .dz 00;31 .gz 00;31 +.xz 00;31 .bz2 00;31 +.tbz 00;31 .tbz2 00;31 .bz 00;31 .tz 00;31 @@ -112,7 +116,6 @@ EXEC 00;32 .cpio 00;31 .7z 00;31 .rz 00;31 -.xz 00;31 # image formats (magenta) .jpg 00;35 .jpeg 00;35 @@ -127,6 +130,8 @@ EXEC 00;32 .tif 00;35 .tiff 00;35 .png 00;35 +.svg 00;35 +.svgz 00;35 .mng 00;35 .pcx 00;35 .mov 00;35 @@ -154,13 +159,13 @@ EXEC 00;32 .xcf 00;35 .xwd 00;35 .yuv 00;35 -.svg 00;35 -.svgz 00;35 + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions .axv 00;35 .anx 00;35 .ogv 00;35 .ogx 00;35 + # audio formats (cyan) .aac 00;36 .au 00;36 @@ -173,6 +178,7 @@ EXEC 00;32 .ogg 00;36 .ra 00;36 .wav 00;36 + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions .axa 00;36 .oga 00;36 diff --git a/coreutils.spec b/coreutils.spec index bd4554c..0c83a76 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -23,6 +23,7 @@ Source203: coreutils-runuser-l.pamd Patch100: coreutils-6.10-configuration.patch Patch101: coreutils-6.10-manpages.patch Patch102: coreutils-7.4-sttytcsadrain.patch +Patch103: coreutils-7.5-kojiutimensatskip.patch # sh-utils Patch703: sh-utils-2.0.11-dateman.patch @@ -59,7 +60,6 @@ BuildRequires: automake >= 1.10.1 BuildRequires: libcap-devel >= 2.0.6 BuildRequires: libattr-devel BuildRequires: attr -BuildRequires: xz Requires(post): libselinux >= 1.25.6-1 Requires: libattr @@ -73,6 +73,7 @@ Requires(post): grep %{?!nopam:Requires: pam >= 0.66-12} Requires(post): libcap >= 2.0.6 Requires: ncurses +Requires: %{name}-libs = %{version}-%{release} # Require a C library that doesn't put LC_TIME files in our way. Conflicts: glibc < 2.2 @@ -95,6 +96,14 @@ Conflicts: tetex < 1.0.7-66 These are the GNU core utilities. This package is the combination of the old GNU fileutils, sh-utils, and textutils packages. +%package libs +Summary: Libraries for %{name} +Group: System Environment/Libraries +Requires: %{name} = %{version}-%{release} + +%description libs +Libraries for coreutils package. + %prep %setup -q @@ -104,6 +113,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch100 -p1 -b .configure %patch101 -p1 -b .manpages %patch102 -p1 -b .tcsadrain +%patch103 -p1 -b .kojiutimensat # sh-utils %patch703 -p1 -b .dateman @@ -313,10 +323,19 @@ fi %_sbindir/chroot /sbin/runuser +%files libs +%defattr(-, root, root, -) +%{_libdir}/coreutils + %changelog * Fri Aug 21 2009 Ondrej Vasik - 7.5-1 - New upstream release 7.5, remove already applied patches, - defuzz few others + defuzz few others, xz in default set(by dependencies), + so no explicit br required +- skip two new tests on system with insufficient utimensat + support(e.g. koji) +- libstdbuf.so in separate coreutils-libs subpackage +- update /etc/DIRCOLORS* * Thu Aug 06 2009 Ondrej Vasik - 7.4-6 - do process install-info only with info files present(#515970) From 5fd0b055f56d6b710b7350a22352ce352dc94003 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 24 Aug 2009 08:38:17 +0000 Subject: [PATCH 041/523] Better fix than workaround the koji insufficient utimensat support issue to prevent failures in other packages --- coreutils-7.5-kojiutimensatskip.patch | 44 +++++++++++---------------- coreutils.spec | 10 ++++-- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/coreutils-7.5-kojiutimensatskip.patch b/coreutils-7.5-kojiutimensatskip.patch index 9ca38f8..e8e3af2 100644 --- a/coreutils-7.5-kojiutimensatskip.patch +++ b/coreutils-7.5-kojiutimensatskip.patch @@ -1,26 +1,18 @@ -diff -urNp coreutils-7.5-orig/tests/cp/preserve-slink-time coreutils-7.5/tests/cp/preserve-slink-time ---- coreutils-7.5-orig/tests/cp/preserve-slink-time 2009-08-15 17:25:32.000000000 +0200 -+++ coreutils-7.5/tests/cp/preserve-slink-time 2009-08-21 12:45:41.000000000 +0200 -@@ -28,6 +28,10 @@ grep '^#define HAVE_UTIMENSAT' "$CONFIG_ - - ln -s no-such dangle || framework_failure - -+cp -Pp dangle d3 2>error -+grep 'Function not implemented' error > /dev/null && -+ skip_test_ 'utimensat function not implemented' -+ - # If the current file system lacks sub-second resolution, sleep for 2s to - # ensure that the times on the copy are different from those of the original. - case $(stat --format=%y dangle) in -diff -urNp coreutils-7.5-orig/tests/mv/part-symlink coreutils-7.5/tests/mv/part-symlink ---- coreutils-7.5-orig/tests/mv/part-symlink 2009-08-15 17:25:32.000000000 +0200 -+++ coreutils-7.5/tests/mv/part-symlink 2009-08-21 12:52:13.000000000 +0200 -@@ -201,6 +201,8 @@ cat <<\EOF > $expected - - EOF - -+grep 'Function not implemented' $actual > /dev/null && -+ skip_test_ 'utimensat function not implemented' - # Redirect to stderr, since stdout is already taken. - compare $expected $actual 1>&2 || fail=1 - +diff -urNp coreutils-7.5-orig/src/copy.c coreutils-7.5/src/copy.c +--- coreutils-7.5-orig/src/copy.c ++++ coreutils-7.5/src/copy.c +@@ -124,7 +124,13 @@ static inline int + utimens_symlink (char const *file, struct timespec const *timespec) + { + #if HAVE_UTIMENSAT +- return utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW); ++ int err = utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW); ++ /* When configuring on a system with new headers and libraries, and ++ running on one with a kernel that is old enough to lack the syscall, ++ utimensat fails with ENOTSUP. Ignore that. */ ++ if (err && errno == ENOSYS) ++ err = 0; ++ return err; + #else + /* Don't set errno=ENOTSUP here as we don't want + to output an error message for this case. */ diff --git a/coreutils.spec b/coreutils.spec index 0c83a76..02d8ad6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.5 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,12 +18,12 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream +Patch1: coreutils-7.5-kojiutimensatskip.patch # Our patches Patch100: coreutils-6.10-configuration.patch Patch101: coreutils-6.10-manpages.patch Patch102: coreutils-7.4-sttytcsadrain.patch -Patch103: coreutils-7.5-kojiutimensatskip.patch # sh-utils Patch703: sh-utils-2.0.11-dateman.patch @@ -108,12 +108,12 @@ Libraries for coreutils package. %setup -q # From upstream +%patch1 -p1 -b .kojiutimensat # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages %patch102 -p1 -b .tcsadrain -%patch103 -p1 -b .kojiutimensat # sh-utils %patch703 -p1 -b .dateman @@ -328,6 +328,10 @@ fi %{_libdir}/coreutils %changelog +* Mon Aug 24 2009 Ondrej Vasik - 7.5-2 +- Better fix than workaround the koji insufficient utimensat + support issue to prevent failures in other packages + * Fri Aug 21 2009 Ondrej Vasik - 7.5-1 - New upstream release 7.5, remove already applied patches, defuzz few others, xz in default set(by dependencies), From f494e3c6ec4d567db67f4caef275475277288c40 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 24 Aug 2009 09:45:05 +0000 Subject: [PATCH 042/523] fix typo --- coreutils-7.5-kojiutimensatskip.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-7.5-kojiutimensatskip.patch b/coreutils-7.5-kojiutimensatskip.patch index e8e3af2..98f9907 100644 --- a/coreutils-7.5-kojiutimensatskip.patch +++ b/coreutils-7.5-kojiutimensatskip.patch @@ -9,7 +9,7 @@ diff -urNp coreutils-7.5-orig/src/copy.c coreutils-7.5/src/copy.c + int err = utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW); + /* When configuring on a system with new headers and libraries, and + running on one with a kernel that is old enough to lack the syscall, -+ utimensat fails with ENOTSUP. Ignore that. */ ++ utimensat fails with ENOSYS. Ignore that. */ + if (err && errno == ENOSYS) + err = 0; + return err; From 063897c2f3896430175da41bc6302d5ae485ec7e Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 1 Sep 2009 10:05:36 +0000 Subject: [PATCH 043/523] ls -i: print consistent inode numbers also for mount points (#453709) --- coreutils-7.5-ls-inode.patch | 211 +++++++++++++++++++++++++++++++++++ coreutils.spec | 9 +- 2 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 coreutils-7.5-ls-inode.patch diff --git a/coreutils-7.5-ls-inode.patch b/coreutils-7.5-ls-inode.patch new file mode 100644 index 0000000..002c2fe --- /dev/null +++ b/coreutils-7.5-ls-inode.patch @@ -0,0 +1,211 @@ +From 3af748aa25193e8a5a8fe520cd967cfbc4d71cb8 Mon Sep 17 00:00:00 2001 +From: Jim Meyering +Date: Wed, 2 Jul 2008 18:01:43 +0200 +Subject: [PATCH] ls -i: print consistent inode numbers also for mount points + +On most unix- and linux-based kernels, ls -i DIR_CONTAINING_MOUNT_POINT +would print the wrong inode number for any entry that is a mount point. +It would do that by relying on readdir's dirent.d_ino values, while +most readdir implementations return the inode number of the underlying, +inaccessible directory. Thus, it is not consistent with what you'd +get when applying stat to the same entry. This bug led to surprising +results like "ls -i" and "ls -i --color" printing different numbers (ls +must usually "stat" a file to colorize its name). This change makes it +so that on offending systems, ls must stat non-command-line-arguments +for which otherwise it would be able to use "for free" dirent.d_ino +values. Regardless of this change, ls is already required to stat every +command-line argument. Note: versions of GNU ls prior to coreutils-6.0 +did not perform the invalid optimization, and hence always printed +correct inode numbers. Thus, for the sake of correctness, ls -i is +forgoing the readdir optimization, for any kernel (including linux!) +with POSIX-nonconforming readdir. Note that currently, only Cygwin has +been agile enough to conform. + +* src/ls.c (RELIABLE_D_INO): Define. +(print_dir): Use it. +For plenty of discussion, see this long thread: +http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14020 +This bug was introduced by the 2006-02-26 commit, 33eb3efe: +"In ls, avoid calling stat for --inode (-i), when possible." +* tests/ls/readdir-mountpoint-inode: New test. +* tests/Makefile.am (TESTS): Add it. +* tests/ls/stat-vs-dirent: Don't suppress failure of this test, +now that ls -i is fixed. Though note that it doesn't test well, +since it compares only the always-stat'd command-line arguments. +* NEWS (Bug fixes): Mention it. +--- + NEWS | 5 +++ + src/ls.c | 23 +++++++++++- + tests/Makefile.am | 1 + + tests/ls/readdir-mountpoint-inode | 72 +++++++++++++++++++++++++++++++++++++ + tests/ls/stat-vs-dirent | 7 +--- + 5 files changed, 101 insertions(+), 7 deletions(-) + create mode 100755 tests/ls/readdir-mountpoint-inode + +diff --git a/NEWS b/NEWS +index 39666fa..50c40be 100644 +--- a/NEWS ++++ b/NEWS +@@ -16,6 +16,11 @@ GNU coreutils NEWS -*- outline -*- + printing a summary to stderr. + [bug introduced in coreutils-6.11] + ++ ls -i now prints consistent inode numbers also for mount points. ++ This makes ls -i DIR less efficient on systems with dysfunctional readdir, ++ because ls must stat every file in order to obtain a guaranteed-valid ++ inode number. [bug introduced in coreutils-6.0] ++ + ** New features + + cp --reflink accepts a new "auto" parameter which falls back to +diff --git a/src/ls.c b/src/ls.c +index 6316dfa..553090d 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -126,6 +126,26 @@ + Subtracting doesn't always work, due to overflow. */ + #define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b)) + ++/* Unix-based readdir implementations have historically returned a dirent.d_ino ++ value that is sometimes not equal to the stat-obtained st_ino value for ++ that same entry. This error occurs for a readdir entry that refers ++ to a mount point. readdir's error is to return the inode number of ++ the underlying directory -- one that typically cannot be stat'ed, as ++ long as a file system is mounted on that directory. RELIABLE_D_INO ++ encapsulates whether we can use the more efficient approach of relying ++ on readdir-supplied d_ino values, or whether we must incur the cost of ++ calling stat or lstat to obtain each guaranteed-valid inode number. */ ++ ++#ifndef READDIR_LIES_ABOUT_MOUNTPOINT_D_INO ++# define READDIR_LIES_ABOUT_MOUNTPOINT_D_INO 1 ++#endif ++ ++#if READDIR_LIES_ABOUT_MOUNTPOINT_D_INO ++# define RELIABLE_D_INO(dp) NOT_AN_INODE_NUMBER ++#else ++# define RELIABLE_D_INO(dp) D_INO (dp) ++#endif ++ + #if ! HAVE_STRUCT_STAT_ST_AUTHOR + # define st_author st_uid + #endif +@@ -2501,7 +2521,8 @@ print_dir (char const *name, char const *realname, bool command_line_arg) + # endif + } + #endif +- total_blocks += gobble_file (next->d_name, type, D_INO (next), ++ total_blocks += gobble_file (next->d_name, type, ++ RELIABLE_D_INO (next), + false, name); + + /* In this narrow case, print out each name right away, so +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 3177056..0151cb0 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -358,6 +358,7 @@ TESTS = \ + ls/no-arg \ + ls/no-cap \ + ls/proc-selinux-segfault \ ++ ls/readdir-mountpoint-inode \ + ls/recursive \ + ls/rt-1 \ + ls/stat-dtype \ +diff --git a/tests/ls/readdir-mountpoint-inode b/tests/ls/readdir-mountpoint-inode +new file mode 100755 +index 0000000..763cab1 +--- /dev/null ++++ b/tests/ls/readdir-mountpoint-inode +@@ -0,0 +1,72 @@ ++#!/bin/sh ++# ensure that ls -i works also for mount points ++ ++# Copyright (C) 2009 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 . ++ ++if test "$VERBOSE" = yes; then ++ set -x ++ ls --version ++fi ++ ++. $srcdir/test-lib.sh ++ ++fail=0 ++ ++mount_points=$(df --local -P 2>&1 | sed -n 's,.*[0-9]% \(/.\),\1,p') ++test -z "$mount_points" && skip_test_ "this test requires a non-root mount point" ++ ++# Given e.g., /dev/shm, produce the list of GNU ls options that ++# let us list just that entry using readdir data from its parent: ++# ls -i -I '[^s]*' -I 's[^h]*' -I 'sh[^m]*' -I 'shm?*' -I '.?*' \ ++# -I '?' -I '??' /dev ++ ++ls_ignore_options() ++{ ++ name=$1 ++ opts="-I '.?*' -I '$name?*'" ++ while :; do ++ glob=$(echo "$name"|sed 's/\(.*\)\(.\)$/\1[^\2]*/') ++ opts="$opts -I '$glob'" ++ name=$(echo "$name"|sed 's/.$//') ++ test -z "$name" && break ++ glob=$(echo "$name"|sed 's/./?/g') ++ opts="$opts -I '$glob'" ++ done ++ echo "$opts" ++} ++ ++inode_via_readdir() ++{ ++ mount_point=$1 ++ base=$(basename $mount_point) ++ case $base in ++ .*) skip_test_ 'mount point component starts with "."' ;; ++ *[*?]*) skip_test_ 'mount point component contains "?" or "*"' ;; ++ esac ++ opts=$(ls_ignore_options "$base") ++ parent_dir=$(dirname $mount_point) ++ eval "ls -i $opts $parent_dir" | sed 's/ .*//' ++} ++ ++# FIXME: use a timeout, in case stat'ing mount points takes too long. ++ ++for dir in $mount_points; do ++ readdir_inode=$(inode_via_readdir $dir) ++ stat_inode=$(env stat --format=%i $dir) ++ test "$readdir_inode" = "$stat_inode" || fail=1 ++done ++ ++Exit $fail +diff --git a/tests/ls/stat-vs-dirent b/tests/ls/stat-vs-dirent +index c1d7ff5..064ec12 100755 +--- a/tests/ls/stat-vs-dirent ++++ b/tests/ls/stat-vs-dirent +@@ -49,12 +49,7 @@ while :; do + The flaw isn't serious for coreutils, but it might break other tools, + so you should report it to your operating system vendor." 1>&2 + +- # This test fails too often, and we don't want to be distracted +- # with reports, since the code that could be affected by the losing +- # behavior (pwd and getcwd) works around any mismatch. +- # So do continue to issue the warning, but don't count it as a +- # real failure. +- # fail=1 ++ fail=1 + break + fi + fi +-- +1.6.4.2.363.g2d6e diff --git a/coreutils.spec b/coreutils.spec index 02d8ad6..45e1254 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.5 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -19,6 +19,7 @@ Source203: coreutils-runuser-l.pamd # From upstream Patch1: coreutils-7.5-kojiutimensatskip.patch +Patch2: coreutils-7.5-ls-inode.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -109,6 +110,7 @@ Libraries for coreutils package. # From upstream %patch1 -p1 -b .kojiutimensat +%patch2 -p1 -b .inode # Our patches %patch100 -p1 -b .configure @@ -137,6 +139,7 @@ Libraries for coreutils package. %patch951 -p1 -b .selinuxman chmod a+x tests/misc/sort-mb-tests +chmod a+x tests/ls/readdir-mountpoint-inode #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -328,6 +331,10 @@ fi %{_libdir}/coreutils %changelog +* Fri Aug 28 2009 Ondrej Vasik - 7.5-3 +- ls -i: print consistent inode numbers also for mount points + (#453709) + * Mon Aug 24 2009 Ondrej Vasik - 7.5-2 - Better fix than workaround the koji insufficient utimensat support issue to prevent failures in other packages From 23a4715f2a76500df159e9ea3fb9d8ad889becd2 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 1 Sep 2009 10:19:01 +0000 Subject: [PATCH 044/523] fix the fuzz --- coreutils-7.5-ls-inode.patch | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/coreutils-7.5-ls-inode.patch b/coreutils-7.5-ls-inode.patch index 002c2fe..bf04027 100644 --- a/coreutils-7.5-ls-inode.patch +++ b/coreutils-7.5-ls-inode.patch @@ -32,14 +32,12 @@ This bug was introduced by the 2006-02-26 commit, 33eb3efe: * tests/ls/stat-vs-dirent: Don't suppress failure of this test, now that ls -i is fixed. Though note that it doesn't test well, since it compares only the always-stat'd command-line arguments. -* NEWS (Bug fixes): Mention it. --- - NEWS | 5 +++ src/ls.c | 23 +++++++++++- tests/Makefile.am | 1 + tests/ls/readdir-mountpoint-inode | 72 +++++++++++++++++++++++++++++++++++++ tests/ls/stat-vs-dirent | 7 +--- - 5 files changed, 101 insertions(+), 7 deletions(-) + 4 files changed, 96 insertions(+), 7 deletions(-) create mode 100755 tests/ls/readdir-mountpoint-inode diff --git a/NEWS b/NEWS @@ -194,8 +192,8 @@ index c1d7ff5..064ec12 100755 --- a/tests/ls/stat-vs-dirent +++ b/tests/ls/stat-vs-dirent @@ -49,12 +49,7 @@ while :; do - The flaw isn't serious for coreutils, but it might break other tools, - so you should report it to your operating system vendor." 1>&2 + The flaw isn't serious for coreutils, but it might break other tools, + so you should report it to your operating system vendor." 1>&2 - # This test fails too often, and we don't want to be distracted - # with reports, since the code that could be affected by the losing From 79c2ad7ebe799142d9f97b79789448b43403b507 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 1 Sep 2009 10:30:03 +0000 Subject: [PATCH 045/523] Need coffee ... --- coreutils-7.5-ls-inode.patch | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/coreutils-7.5-ls-inode.patch b/coreutils-7.5-ls-inode.patch index bf04027..2363aff 100644 --- a/coreutils-7.5-ls-inode.patch +++ b/coreutils-7.5-ls-inode.patch @@ -40,22 +40,6 @@ since it compares only the always-stat'd command-line arguments. 4 files changed, 96 insertions(+), 7 deletions(-) create mode 100755 tests/ls/readdir-mountpoint-inode -diff --git a/NEWS b/NEWS -index 39666fa..50c40be 100644 ---- a/NEWS -+++ b/NEWS -@@ -16,6 +16,11 @@ GNU coreutils NEWS -*- outline -*- - printing a summary to stderr. - [bug introduced in coreutils-6.11] - -+ ls -i now prints consistent inode numbers also for mount points. -+ This makes ls -i DIR less efficient on systems with dysfunctional readdir, -+ because ls must stat every file in order to obtain a guaranteed-valid -+ inode number. [bug introduced in coreutils-6.0] -+ - ** New features - - cp --reflink accepts a new "auto" parameter which falls back to diff --git a/src/ls.c b/src/ls.c index 6316dfa..553090d 100644 --- a/src/ls.c From 2c2fd97500b0aa953b5ec6a058208f83ecb9d238 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 3 Sep 2009 15:19:58 +0000 Subject: [PATCH 046/523] fixed regression where df -l as regular user cause Permission denied (#520630, introduced by fix for rhbz #497830) --- coreutils-7.5-df-localdevice.patch | 17 +++++++++++++++++ coreutils.spec | 9 ++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 coreutils-7.5-df-localdevice.patch diff --git a/coreutils-7.5-df-localdevice.patch b/coreutils-7.5-df-localdevice.patch new file mode 100644 index 0000000..fb45306 --- /dev/null +++ b/coreutils-7.5-df-localdevice.patch @@ -0,0 +1,17 @@ +diff -urNp coreutils-7.5-orig/src/df.c coreutils-7.5/src/df.c +--- coreutils-7.5-orig/src/df.c 2009-08-15 17:25:32.000000000 +0200 ++++ coreutils-7.5/src/df.c 2009-09-03 16:37:25.000000000 +0200 +@@ -995,7 +995,12 @@ main (int argc, char **argv) + for (i = optind; i < argc; ++i) + { + int fd = open (argv[i], O_RDONLY | O_NOCTTY); +- if (fd < 0 || fstat (fd, &stats[i - optind])) ++ if (0 <= fd && !fstat (fd, &stats[i - optind]) ++ && !stat (argv[i], &stats[i - optind])) ++ { ++ /* open() may have failed for normal user but stat() works */ ++ } ++ else + { + error (0, errno, "%s", quote (argv[i])); + exit_status = EXIT_FAILURE; diff --git a/coreutils.spec b/coreutils.spec index 45e1254..a6b8b08 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.5 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -25,6 +25,7 @@ Patch2: coreutils-7.5-ls-inode.patch Patch100: coreutils-6.10-configuration.patch Patch101: coreutils-6.10-manpages.patch Patch102: coreutils-7.4-sttytcsadrain.patch +Patch103: coreutils-7.5-df-localdevice.patch # sh-utils Patch703: sh-utils-2.0.11-dateman.patch @@ -116,6 +117,7 @@ Libraries for coreutils package. %patch100 -p1 -b .configure %patch101 -p1 -b .manpages %patch102 -p1 -b .tcsadrain +%patch103 -p1 -b .localdevice # sh-utils %patch703 -p1 -b .dateman @@ -331,6 +333,11 @@ fi %{_libdir}/coreutils %changelog +* Thu Sep 03 2009 Ondrej Vasik - 7.5-4 +- fixed regression where df -l as regular user + cause "Permission denied" (#520630, introduced by fix for + rhbz #497830) + * Fri Aug 28 2009 Ondrej Vasik - 7.5-3 - ls -i: print consistent inode numbers also for mount points (#453709) From 61fe33cb1ca91770c8054396ad45ac748056bdb8 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 8 Sep 2009 14:34:31 +0000 Subject: [PATCH 047/523] fix sort -h for multibyte locales (reported via http://bugs.archlinux.org/task/16022) --- coreutils-i18n.patch | 14 ++++++-------- coreutils.spec | 6 +++++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 8f39241..9f3fc2b 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2204,7 +2204,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { struct keyfield *key = keylist; -@@ -1875,6 +2265,181 @@ +@@ -1875,6 +2265,179 @@ return key->reverse ? -diff : diff; } @@ -2232,7 +2232,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + + for (;;) + { -+ unsigned char *translate = (unsigned char *) key->translate; ++ char const *translate = key->translate; + bool const *ignore = key->ignore; + + /* Find the lengths. */ @@ -2242,16 +2242,14 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + /* Actually compare the fields. */ + if (key->random) + diff = compare_random (texta, lena, textb, lenb); -+ else if (key->numeric | key->general_numeric) ++ else if (key->numeric | key->general_numeric | key->human_numeric) + { + char savea = *lima, saveb = *limb; + + *lima = *limb = '\0'; -+ if (force_general_numcompare) -+ diff = general_numcompare (texta, textb); -+ else -+ diff = ((key->numeric ? numcompare : general_numcompare) -+ (texta, textb)); ++ diff = (key->numeric ? numcompare (texta, textb) ++ : key->general_numeric ? general_numcompare (texta, textb) ++ : human_numcompare (texta, textb, key)); + *lima = savea, *limb = saveb; + } + else if (key->version) diff --git a/coreutils.spec b/coreutils.spec index a6b8b08..36ed0e4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.5 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -333,6 +333,10 @@ fi %{_libdir}/coreutils %changelog +* Tue Sep 08 2009 Ondrej Vasik - 7.5-5 +- fix sort -h for multibyte locales (reported via + http://bugs.archlinux.org/task/16022) + * Thu Sep 03 2009 Ondrej Vasik - 7.5-4 - fixed regression where df -l as regular user cause "Permission denied" (#520630, introduced by fix for From 266a669f620b3444bafd19b59ca9932863e99657 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 10 Sep 2009 10:36:58 +0000 Subject: [PATCH 048/523] fix double free error in fold for singlebyte locales (caused by multibyte patch) --- coreutils-i18n.patch | 15 ++++++--------- coreutils.spec | 6 +++++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 9f3fc2b..e5174f1 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1348,7 +1348,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* Look for the last blank. */ while (logical_end) { -@@ -218,11 +255,225 @@ +@@ -218,11 +255,222 @@ line_out[offset_out++] = c; } @@ -1358,7 +1358,6 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + -+ free(line_out); +} + +#if HAVE_MBRTOWC @@ -1367,16 +1366,16 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +{ + 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; /* Next read position of BUF. */ ++ char *bufpos = NULL; /* 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; /* 1, when conversion is failed. Otherwise 0. */ + -+ char *line_out = NULL; ++ static char *line_out = NULL; + size_t offset_out = 0; /* Index in `line_out' for next char. */ -+ size_t allocated_out = 0; ++ static size_t allocated_out = 0; + + int increment; + size_t column = 0; @@ -1384,7 +1383,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + size_t last_blank_pos; + size_t last_blank_column; + int is_blank_seen; -+ int last_blank_increment; ++ int last_blank_increment = 0; + int is_bs_following_last_blank; + size_t bs_following_last_blank_num; + int is_cr_after_last_blank; @@ -1503,8 +1502,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + + if (allocated_out < offset_out + mblength) + { -+ allocated_out += 1024; -+ line_out = xrealloc (line_out, allocated_out); ++ line_out = X2REALLOC (line_out, &allocated_out); + } + + memcpy (line_out + offset_out, bufpos, mblength); @@ -1536,7 +1534,6 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c if (offset_out) fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); -+ free(line_out); +} +#endif + diff --git a/coreutils.spec b/coreutils.spec index 36ed0e4..2126148 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.5 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -333,6 +333,10 @@ fi %{_libdir}/coreutils %changelog +* Thu Sep 10 2009 Ondrej Vasik - 7.5-6 +- fix double free error in fold for singlebyte locales + (caused by multibyte patch) + * Tue Sep 08 2009 Ondrej Vasik - 7.5-5 - fix sort -h for multibyte locales (reported via http://bugs.archlinux.org/task/16022) From 25051789712d783c23f02b175814359bf50b5b7a Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Sat, 12 Sep 2009 09:28:49 +0000 Subject: [PATCH 049/523] new upstream bugfix release 7.6, removed applied patches,defuzzed the rest --- .cvsignore | 2 +- coreutils-4.5.3-langinfo.patch | 22 +- coreutils-4.5.3-sysinfo.patch | 12 +- coreutils-5.2.1-runuser.patch | 82 +- coreutils-6.10-configuration.patch | 11 - coreutils-6.10-manpages.patch | 2 +- coreutils-7.4-sttytcsadrain.patch | 4 +- coreutils-7.5-df-localdevice.patch | 17 - coreutils-7.5-kojiutimensatskip.patch | 18 - coreutils-7.5-ls-inode.patch | 193 -- coreutils-i18n.patch | 2349 ++++++++++++------------- coreutils-pam.patch | 12 +- coreutils-selinux.patch | 458 ++--- coreutils-setsid.patch | 40 +- coreutils.spec | 14 +- sources | 2 +- 16 files changed, 1487 insertions(+), 1751 deletions(-) delete mode 100644 coreutils-7.5-df-localdevice.patch delete mode 100644 coreutils-7.5-kojiutimensatskip.patch delete mode 100644 coreutils-7.5-ls-inode.patch diff --git a/.cvsignore b/.cvsignore index 2d04123..edb4b98 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-7.5.tar.xz +coreutils-7.6.tar.xz diff --git a/coreutils-4.5.3-langinfo.patch b/coreutils-4.5.3-langinfo.patch index 49a88aa..a45dcb3 100644 --- a/coreutils-4.5.3-langinfo.patch +++ b/coreutils-4.5.3-langinfo.patch @@ -3,16 +3,16 @@ @@ -451,14 +451,7 @@ format = DATE_FMT_LANGINFO (); if (! *format) - { -- /* Do not wrap the following literal format string with _(...). -- For example, suppose LC_ALL is unset, LC_TIME="POSIX", -- and LANG="ko_KR". In that case, POSIX says that LC_TIME -- determines the format and contents of date and time strings -- written by date, which means "date" must generate output -- using the POSIX locale; but adding _() would cause "date" -- to use a Korean translation of the format. */ -- format = "%a %b %e %H:%M:%S %Z %Y"; -+ format = dcgettext(NULL, N_("%a %b %e %H:%M:%S %Z %Y"), LC_TIME); - } + { +- /* Do not wrap the following literal format string with _(...). +- For example, suppose LC_ALL is unset, LC_TIME="POSIX", +- and LANG="ko_KR". In that case, POSIX says that LC_TIME +- determines the format and contents of date and time strings +- written by date, which means "date" must generate output +- using the POSIX locale; but adding _() would cause "date" +- to use a Korean translation of the format. */ +- format = "%a %b %e %H:%M:%S %Z %Y"; ++ format = dcgettext(NULL, N_("%a %b %e %H:%M:%S %Z %Y"), LC_TIME); + } } diff --git a/coreutils-4.5.3-sysinfo.patch b/coreutils-4.5.3-sysinfo.patch index 94c9f91..cb61d81 100644 --- a/coreutils-4.5.3-sysinfo.patch +++ b/coreutils-4.5.3-sysinfo.patch @@ -17,9 +17,9 @@ + char *element = unknown; #if HAVE_SYSINFO && defined SI_ARCHITECTURE { - static char processor[257]; - if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) - element = processor; + static char processor[257]; + if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) + element = processor; } +#else + { @@ -54,10 +54,10 @@ + char *element = unknown; #if HAVE_SYSINFO && defined SI_PLATFORM { - static char hardware_platform[257]; + static char hardware_platform[257]; @@ -356,6 +378,14 @@ - hardware_platform, sizeof hardware_platform)) - element = hardware_platform; + hardware_platform, sizeof hardware_platform)) + element = hardware_platform; } +#else + { diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index f879cdd..f78cbc0 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -121,11 +121,11 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c static void run_shell (char const *, char const *, char **, size_t, - const struct passwd *) -+ const struct passwd * ++ const struct passwd * +#ifdef RUNUSER -+ , gid_t *groups, int num_groups ++ , gid_t *groups, int num_groups +#endif -+ ) ++ ) #ifdef USE_PAM ; #else @@ -180,9 +180,9 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c -change_identity (const struct passwd *pw) +change_identity (const struct passwd *pw +#ifdef RUNUSER -+ , gid_t *groups, int num_groups ++ , gid_t *groups, int num_groups +#endif -+ ) ++ ) { #ifdef HAVE_INITGROUPS + int rc = 0; @@ -202,12 +202,12 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c static void run_shell (char const *shell, char const *command, char **additional_args, -- size_t n_additional_args, const struct passwd *pw) -+ size_t n_additional_args, const struct passwd *pw +- size_t n_additional_args, const struct passwd *pw) ++ size_t n_additional_args, const struct passwd *pw +#ifdef RUNUSER -+ , gid_t *groups, int num_groups ++ , gid_t *groups, int num_groups +#endif -+ ) ++ ) { size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; char const **args = xnmalloc (n_args, sizeof *args); @@ -218,9 +218,9 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c - change_identity (pw); + change_identity (pw +#ifdef RUNUSER -+ , groups, num_groups ++ , groups, num_groups +#endif -+ ); ++ ); pam_end(pamh, 0); if (!same_session) setsid (); @@ -279,43 +279,43 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c - while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, "c:flmps:" +#ifdef RUNUSER -+ "g:G:" ++ "g:G:" +#endif -+ , longopts, NULL)) != -1) ++ , longopts, NULL)) != -1) { switch (optc) - { + { @@ -697,6 +773,28 @@ main (int argc, char **argv) - shell = optarg; - break; + shell = optarg; + break; +#ifdef RUNUSER -+ case 'g': -+ gr = getgrnam(optarg); -+ if (!gr) -+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg); -+ use_gid = 1; -+ groups[0] = gr->gr_gid; -+ break; ++ case 'g': ++ gr = getgrnam(optarg); ++ if (!gr) ++ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg); ++ use_gid = 1; ++ groups[0] = gr->gr_gid; ++ break; + -+ case 'G': -+ num_supp_groups++; -+ if (num_supp_groups >= NGROUPS_MAX) -+ error (EXIT_FAILURE, 0, -+ _("Can't specify more than %d supplemental groups"), -+ NGROUPS_MAX - 1); -+ gr = getgrnam(optarg); -+ if (!gr) -+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg); -+ groups[num_supp_groups] = gr->gr_gid; -+ break; ++ case 'G': ++ num_supp_groups++; ++ if (num_supp_groups >= NGROUPS_MAX) ++ error (EXIT_FAILURE, 0, ++ _("Can't specify more than %d supplemental groups"), ++ NGROUPS_MAX - 1); ++ gr = getgrnam(optarg); ++ if (!gr) ++ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg); ++ groups[num_supp_groups] = gr->gr_gid; ++ break; +#endif + - case_GETOPT_HELP_CHAR; + case_GETOPT_HELP_CHAR; - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); @@ -735,7 +833,20 @@ main (int argc, char **argv) - : DEFAULT_SHELL); + : DEFAULT_SHELL); endpwent (); - if (!correct_password (pw)) @@ -343,17 +343,17 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c - change_identity (pw); + change_identity (pw +#ifdef RUNUSER -+ , groups, num_supp_groups ++ , groups, num_supp_groups +#endif -+ ); ++ ); #endif - run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); + run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw +#ifdef RUNUSER -+ , groups, num_supp_groups ++ , groups, num_supp_groups +#endif -+ ); ++ ); } diff -urNp coreutils-7.5.orig/tests/misc/help-version coreutils-7.5/tests/misc/help-version --- coreutils-7.5.orig/tests/misc/help-version diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index c0813cb..9b1ec54 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -27,17 +27,6 @@ diff -urNp coreutils-7.2-orig/gnulib-tests/gnulib.mk coreutils-7.2/gnulib-tests/ ## end gnulib module strverscmp-tests -diff -urN coreutils-6.11-orig/tests/mkdir/selinux coreutils-6.11/tests/mkdir/selinux ---- coreutils-6.11-orig/tests/mkdir/selinux 2008-04-19 23:34:23.000000000 +0200 -+++ coreutils-6.11/tests/mkdir/selinux 2008-04-22 13:23:50.000000000 +0200 -@@ -38,6 +28,7 @@ - # successfully, in spite of the invalid context string. - - . $srcdir/test-lib.sh -+require_selinux_ - - c=invalid-selinux-context - msg="failed to set default file creation context to \`$c':" diff -urNp coreutils-6.11-orig/tests/test-lib.sh coreutils-6.11/tests/test-lib.sh --- coreutils-6.11-orig/tests/test-lib.sh 2008-04-19 23:34:23.000000000 +0200 +++ coreutils-6.11/tests/test-lib.sh 2008-04-24 14:18:59.000000000 +0200 diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index 792ce42..047c41c 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -2,7 +2,7 @@ diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c --- coreutils-6.12-orig/src/md5sum.c 2008-05-26 08:40:33.000000000 +0200 +++ coreutils-6.12/src/md5sum.c 2008-10-21 16:07:28.000000000 +0200 @@ -175,6 +175,9 @@ With no FILE, or when FILE is -, read st - fputs (_("\ + fputs (_("\ -t, --text read in text mode (default)\n\ "), stdout); + fputs (_("\ diff --git a/coreutils-7.4-sttytcsadrain.patch b/coreutils-7.4-sttytcsadrain.patch index af25979..caf8387 100644 --- a/coreutils-7.4-sttytcsadrain.patch +++ b/coreutils-7.4-sttytcsadrain.patch @@ -2,11 +2,11 @@ diff -urNp coreutils-7.4-orig/src/stty.c coreutils-7.4/src/stty.c --- coreutils-7.4-orig/src/stty.c 2009-04-24 14:41:19.000000000 +0200 +++ coreutils-7.4/src/stty.c 2009-06-11 10:15:41.000000000 +0200 @@ -1001,7 +1001,7 @@ main (int argc, char **argv) - spurious difference in an uninitialized portion of the structure. */ + spurious difference in an uninitialized portion of the structure. */ DECLARE_ZEROED_AGGREGATE (struct termios, new_mode); - if (tcsetattr (STDIN_FILENO, TCSADRAIN, &mode)) + if (tcsetattr (STDIN_FILENO, TCSANOW, &mode)) - error (EXIT_FAILURE, errno, "%s", device_name); + error (EXIT_FAILURE, errno, "%s", device_name); /* POSIX (according to Zlotnick's book) tcsetattr returns zero if diff --git a/coreutils-7.5-df-localdevice.patch b/coreutils-7.5-df-localdevice.patch deleted file mode 100644 index fb45306..0000000 --- a/coreutils-7.5-df-localdevice.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -urNp coreutils-7.5-orig/src/df.c coreutils-7.5/src/df.c ---- coreutils-7.5-orig/src/df.c 2009-08-15 17:25:32.000000000 +0200 -+++ coreutils-7.5/src/df.c 2009-09-03 16:37:25.000000000 +0200 -@@ -995,7 +995,12 @@ main (int argc, char **argv) - for (i = optind; i < argc; ++i) - { - int fd = open (argv[i], O_RDONLY | O_NOCTTY); -- if (fd < 0 || fstat (fd, &stats[i - optind])) -+ if (0 <= fd && !fstat (fd, &stats[i - optind]) -+ && !stat (argv[i], &stats[i - optind])) -+ { -+ /* open() may have failed for normal user but stat() works */ -+ } -+ else - { - error (0, errno, "%s", quote (argv[i])); - exit_status = EXIT_FAILURE; diff --git a/coreutils-7.5-kojiutimensatskip.patch b/coreutils-7.5-kojiutimensatskip.patch deleted file mode 100644 index 98f9907..0000000 --- a/coreutils-7.5-kojiutimensatskip.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -urNp coreutils-7.5-orig/src/copy.c coreutils-7.5/src/copy.c ---- coreutils-7.5-orig/src/copy.c -+++ coreutils-7.5/src/copy.c -@@ -124,7 +124,13 @@ static inline int - utimens_symlink (char const *file, struct timespec const *timespec) - { - #if HAVE_UTIMENSAT -- return utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW); -+ int err = utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW); -+ /* When configuring on a system with new headers and libraries, and -+ running on one with a kernel that is old enough to lack the syscall, -+ utimensat fails with ENOSYS. Ignore that. */ -+ if (err && errno == ENOSYS) -+ err = 0; -+ return err; - #else - /* Don't set errno=ENOTSUP here as we don't want - to output an error message for this case. */ diff --git a/coreutils-7.5-ls-inode.patch b/coreutils-7.5-ls-inode.patch deleted file mode 100644 index 2363aff..0000000 --- a/coreutils-7.5-ls-inode.patch +++ /dev/null @@ -1,193 +0,0 @@ -From 3af748aa25193e8a5a8fe520cd967cfbc4d71cb8 Mon Sep 17 00:00:00 2001 -From: Jim Meyering -Date: Wed, 2 Jul 2008 18:01:43 +0200 -Subject: [PATCH] ls -i: print consistent inode numbers also for mount points - -On most unix- and linux-based kernels, ls -i DIR_CONTAINING_MOUNT_POINT -would print the wrong inode number for any entry that is a mount point. -It would do that by relying on readdir's dirent.d_ino values, while -most readdir implementations return the inode number of the underlying, -inaccessible directory. Thus, it is not consistent with what you'd -get when applying stat to the same entry. This bug led to surprising -results like "ls -i" and "ls -i --color" printing different numbers (ls -must usually "stat" a file to colorize its name). This change makes it -so that on offending systems, ls must stat non-command-line-arguments -for which otherwise it would be able to use "for free" dirent.d_ino -values. Regardless of this change, ls is already required to stat every -command-line argument. Note: versions of GNU ls prior to coreutils-6.0 -did not perform the invalid optimization, and hence always printed -correct inode numbers. Thus, for the sake of correctness, ls -i is -forgoing the readdir optimization, for any kernel (including linux!) -with POSIX-nonconforming readdir. Note that currently, only Cygwin has -been agile enough to conform. - -* src/ls.c (RELIABLE_D_INO): Define. -(print_dir): Use it. -For plenty of discussion, see this long thread: -http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14020 -This bug was introduced by the 2006-02-26 commit, 33eb3efe: -"In ls, avoid calling stat for --inode (-i), when possible." -* tests/ls/readdir-mountpoint-inode: New test. -* tests/Makefile.am (TESTS): Add it. -* tests/ls/stat-vs-dirent: Don't suppress failure of this test, -now that ls -i is fixed. Though note that it doesn't test well, -since it compares only the always-stat'd command-line arguments. ---- - src/ls.c | 23 +++++++++++- - tests/Makefile.am | 1 + - tests/ls/readdir-mountpoint-inode | 72 +++++++++++++++++++++++++++++++++++++ - tests/ls/stat-vs-dirent | 7 +--- - 4 files changed, 96 insertions(+), 7 deletions(-) - create mode 100755 tests/ls/readdir-mountpoint-inode - -diff --git a/src/ls.c b/src/ls.c -index 6316dfa..553090d 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -126,6 +126,26 @@ - Subtracting doesn't always work, due to overflow. */ - #define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b)) - -+/* Unix-based readdir implementations have historically returned a dirent.d_ino -+ value that is sometimes not equal to the stat-obtained st_ino value for -+ that same entry. This error occurs for a readdir entry that refers -+ to a mount point. readdir's error is to return the inode number of -+ the underlying directory -- one that typically cannot be stat'ed, as -+ long as a file system is mounted on that directory. RELIABLE_D_INO -+ encapsulates whether we can use the more efficient approach of relying -+ on readdir-supplied d_ino values, or whether we must incur the cost of -+ calling stat or lstat to obtain each guaranteed-valid inode number. */ -+ -+#ifndef READDIR_LIES_ABOUT_MOUNTPOINT_D_INO -+# define READDIR_LIES_ABOUT_MOUNTPOINT_D_INO 1 -+#endif -+ -+#if READDIR_LIES_ABOUT_MOUNTPOINT_D_INO -+# define RELIABLE_D_INO(dp) NOT_AN_INODE_NUMBER -+#else -+# define RELIABLE_D_INO(dp) D_INO (dp) -+#endif -+ - #if ! HAVE_STRUCT_STAT_ST_AUTHOR - # define st_author st_uid - #endif -@@ -2501,7 +2521,8 @@ print_dir (char const *name, char const *realname, bool command_line_arg) - # endif - } - #endif -- total_blocks += gobble_file (next->d_name, type, D_INO (next), -+ total_blocks += gobble_file (next->d_name, type, -+ RELIABLE_D_INO (next), - false, name); - - /* In this narrow case, print out each name right away, so -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 3177056..0151cb0 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -358,6 +358,7 @@ TESTS = \ - ls/no-arg \ - ls/no-cap \ - ls/proc-selinux-segfault \ -+ ls/readdir-mountpoint-inode \ - ls/recursive \ - ls/rt-1 \ - ls/stat-dtype \ -diff --git a/tests/ls/readdir-mountpoint-inode b/tests/ls/readdir-mountpoint-inode -new file mode 100755 -index 0000000..763cab1 ---- /dev/null -+++ b/tests/ls/readdir-mountpoint-inode -@@ -0,0 +1,72 @@ -+#!/bin/sh -+# ensure that ls -i works also for mount points -+ -+# Copyright (C) 2009 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 . -+ -+if test "$VERBOSE" = yes; then -+ set -x -+ ls --version -+fi -+ -+. $srcdir/test-lib.sh -+ -+fail=0 -+ -+mount_points=$(df --local -P 2>&1 | sed -n 's,.*[0-9]% \(/.\),\1,p') -+test -z "$mount_points" && skip_test_ "this test requires a non-root mount point" -+ -+# Given e.g., /dev/shm, produce the list of GNU ls options that -+# let us list just that entry using readdir data from its parent: -+# ls -i -I '[^s]*' -I 's[^h]*' -I 'sh[^m]*' -I 'shm?*' -I '.?*' \ -+# -I '?' -I '??' /dev -+ -+ls_ignore_options() -+{ -+ name=$1 -+ opts="-I '.?*' -I '$name?*'" -+ while :; do -+ glob=$(echo "$name"|sed 's/\(.*\)\(.\)$/\1[^\2]*/') -+ opts="$opts -I '$glob'" -+ name=$(echo "$name"|sed 's/.$//') -+ test -z "$name" && break -+ glob=$(echo "$name"|sed 's/./?/g') -+ opts="$opts -I '$glob'" -+ done -+ echo "$opts" -+} -+ -+inode_via_readdir() -+{ -+ mount_point=$1 -+ base=$(basename $mount_point) -+ case $base in -+ .*) skip_test_ 'mount point component starts with "."' ;; -+ *[*?]*) skip_test_ 'mount point component contains "?" or "*"' ;; -+ esac -+ opts=$(ls_ignore_options "$base") -+ parent_dir=$(dirname $mount_point) -+ eval "ls -i $opts $parent_dir" | sed 's/ .*//' -+} -+ -+# FIXME: use a timeout, in case stat'ing mount points takes too long. -+ -+for dir in $mount_points; do -+ readdir_inode=$(inode_via_readdir $dir) -+ stat_inode=$(env stat --format=%i $dir) -+ test "$readdir_inode" = "$stat_inode" || fail=1 -+done -+ -+Exit $fail -diff --git a/tests/ls/stat-vs-dirent b/tests/ls/stat-vs-dirent -index c1d7ff5..064ec12 100755 ---- a/tests/ls/stat-vs-dirent -+++ b/tests/ls/stat-vs-dirent -@@ -49,12 +49,7 @@ while :; do - The flaw isn't serious for coreutils, but it might break other tools, - so you should report it to your operating system vendor." 1>&2 - -- # This test fails too often, and we don't want to be distracted -- # with reports, since the code that could be affected by the losing -- # behavior (pwd and getcwd) works around any mismatch. -- # So do continue to issue the warning, but don't count it as a -- # real failure. -- # fail=1 -+ fail=1 - break - fi - fi --- -1.6.4.2.363.g2d6e diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e5174f1..4030eff 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -187,14 +187,6 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "expand" -@@ -183,6 +200,7 @@ - stops = num_start + len - 1; - } - } -+ - else - { - error (0, 0, _("tab size contains invalid character(s): %s"), @@ -365,6 +383,142 @@ } } @@ -414,7 +406,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am 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); + extract_field (line, ptr, sep - ptr); } else @@ -229,6 +248,148 @@ @@ -586,115 +578,100 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am outlist = outlist_head.next; if (outlist) -@@ -397,12 +628,12 @@ - if (o->file == 0) - { - if (line1 == &uni_blank) -- { -+ { - line = line2; - field = join_field_2; - } - else -- { -+ { - line = line1; - field = join_field_1; - } @@ -416,7 +647,7 @@ - o = o->next; - if (o == NULL) - break; -- putchar (output_separator); -+ PUT_TAB_CHAR; - } + o = o->next; + if (o == NULL) + break; +- putchar (output_separator); ++ PUT_TAB_CHAR; + } putchar ('\n'); } @@ -434,23 +665,23 @@ prfield (join_field_1, line1); for (i = 0; i < join_field_1 && i < line1->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line1); - } + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line1); + } for (i = join_field_1 + 1; i < line1->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line1); - } + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line1); + } for (i = 0; i < join_field_2 && i < line2->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line2); - } + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line2); + } for (i = join_field_2 + 1; i < line2->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line2); - } + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line2); + } putchar ('\n'); @@ -859,20 +1090,41 @@ - case 't': - { -- unsigned char newtab = optarg[0]; -- if (! newtab) -+ char *newtab; -+ size_t newtablen; -+ if (! optarg[0]) - error (EXIT_FAILURE, 0, _("empty tab")); -- if (optarg[1]) -+ newtab = xstrdup (optarg); + case 't': + { +- unsigned char newtab = optarg[0]; +- if (! newtab) ++ char *newtab; ++ size_t newtablen; ++ if (! optarg[0]) + error (EXIT_FAILURE, 0, _("empty tab")); +- if (optarg[1]) ++ newtab = xstrdup (optarg); +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ mbstate_t state; ++ 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 ++ 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 (newtablen == 1 && newtab[1]) -+ { -+ if (STREQ (newtab, "\\0")) -+ newtab[0] = '\0'; -+ } -+ if (tab != NULL && strcmp (tab, newtab)) - { -- if (STREQ (optarg, "\\0")) -- newtab = '\0'; -- else -- error (EXIT_FAILURE, 0, _("multi-character tab %s"), -- quote (optarg)); -+ free (newtab); -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); - } -- if (0 <= tab && tab != newtab) -- error (EXIT_FAILURE, 0, _("incompatible tabs")); - tab = newtab; -+ tablen = newtablen; - } - break; - ++ newtablen = 1; ++ ++ if (newtablen == 1 && newtab[1]) ++ { ++ if (STREQ (newtab, "\\0")) ++ newtab[0] = '\0'; ++ } ++ if (tab != NULL && strcmp (tab, newtab)) + { +- if (STREQ (optarg, "\\0")) +- newtab = '\0'; +- else +- error (EXIT_FAILURE, 0, _("multi-character tab %s"), +- quote (optarg)); ++ free (newtab); ++ error (EXIT_FAILURE, 0, _("incompatible tabs")); + } +- if (0 <= tab && tab != newtab) +- error (EXIT_FAILURE, 0, _("incompatible tabs")); + tab = newtab; ++ tablen = newtablen; + } + break; + diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c --- coreutils-6.11-orig/src/join.c 2008-04-21 13:44:32.000000000 +0200 +++ coreutils-6.11/src/join.c 2008-04-21 14:03:22.000000000 +0200 @@ -324,56 +324,115 @@ keycmp (struct line const *line1, struct - size_t jf_1, size_t jf_2) + size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ - char *beg1; @@ -814,7 +791,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c else { - if (hard_LC_COLLATE) -- return xmemcoll (beg1, len1, beg2, len2); +- return xmemcoll (beg1, len1, beg2, len2); - diff = memcmp (beg1, beg2, MIN (len1, len2)); + copy[0] = (unsigned char *) beg[0]; + copy[1] = (unsigned char *) beg[1]; @@ -899,26 +876,26 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +#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; \ -+ } \ -+ } \ ++ 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 * @@ -940,26 +917,26 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + for (count = 0; count < skip_fields && pos < size; count++) + { + while (pos < size) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); ++ { ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); + -+ if (convfail || !iswblank (wc)) -+ { -+ pos += mblength; -+ break; -+ } -+ pos += mblength; -+ } ++ if (convfail || !iswblank (wc)) ++ { ++ pos += mblength; ++ break; ++ } ++ pos += mblength; ++ } + + while (pos < size) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); ++ { ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); + -+ if (!convfail && iswblank (wc)) -+ break; ++ if (!convfail && iswblank (wc)) ++ break; + -+ pos += mblength; -+ } ++ pos += mblength; ++ } + } + + /* skip fields. */ @@ -997,10 +974,10 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + copy_new = alloca (oldlen + 1); + + for (i = 0; i < oldlen; i++) -+ { -+ copy_old[i] = toupper (old[i]); -+ copy_new[i] = toupper (new[i]); -+ } ++ { ++ copy_old[i] = toupper (old[i]); ++ copy_new[i] = toupper (new[i]); ++ } } - else if (hard_LC_COLLATE) - return xmemcoll (old, oldlen, new, newlen) != 0; @@ -1039,40 +1016,40 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + copy[i] = alloca (len[i] + 1); + + for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) -+ { -+ state_bak = state[i]; -+ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); ++ { ++ state_bak = state[i]; ++ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); + -+ switch (mblength) -+ { -+ case (size_t)-1: -+ case (size_t)-2: -+ state[i] = state_bak; -+ /* Fall through */ -+ case 0: -+ mblength = 1; -+ break; ++ switch (mblength) ++ { ++ case (size_t)-1: ++ case (size_t)-2: ++ state[i] = state_bak; ++ /* Fall through */ ++ case 0: ++ mblength = 1; ++ break; + -+ default: -+ if (ignore_case) -+ { -+ uwc = towupper (wc); ++ default: ++ if (ignore_case) ++ { ++ uwc = towupper (wc); + -+ if (uwc != wc) -+ { -+ mbstate_t state_wc; ++ if (uwc != wc) ++ { ++ mbstate_t state_wc; + -+ memset (&state_wc, '\0', sizeof(mbstate_t)); -+ wcrtomb (copy[i] + j, uwc, &state_wc); -+ } -+ else -+ memcpy (copy[i] + j, str[i] + j, mblength); -+ } -+ else -+ memcpy (copy[i] + j, str[i] + j, mblength); -+ } -+ j += mblength; -+ } ++ memset (&state_wc, '\0', sizeof(mbstate_t)); ++ wcrtomb (copy[i] + j, uwc, &state_wc); ++ } ++ else ++ memcpy (copy[i] + j, str[i] + j, mblength); ++ } ++ else ++ memcpy (copy[i] + j, str[i] + j, mblength); ++ } ++ j += mblength; ++ } + copy[i][j] = '\0'; + len[i] = j; + } @@ -1094,19 +1071,19 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +#endif while (!feof (stdin)) - { - char *thisfield; - size_t thislen; + { + char *thisfield; + size_t thislen; +#if HAVE_MBRTOWC -+ mbstate_t thisstate; ++ mbstate_t thisstate; +#endif + - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - break; - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) + break; + thisfield = find_field (thisline); + thislen = thisline->length - 1 - (thisfield - thisline->buffer); +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) ++ if (MB_CUR_MAX > 1) + { + thisstate = thisline->state; + @@ -1122,11 +1099,11 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + prevstate = thisstate; + } + } -+ else ++ else +#endif - if (prevline->length == 0 - || different (thisfield, prevfield, thislen, prevlen)) - { + if (prevline->length == 0 + || different (thisfield, prevfield, thislen, prevlen)) + { @@ -322,17 +533,26 @@ size_t prevlen; uintmax_t match_count = 0; @@ -1136,7 +1113,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +#endif if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) - goto closefiles; + goto closefiles; prevfield = find_field (prevline); prevlen = prevline->length - 1 - (prevfield - prevline->buffer); +#if HAVE_MBRTOWC @@ -1144,42 +1121,42 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +#endif while (!feof (stdin)) - { - bool match; - char *thisfield; - size_t thislen; + { + bool match; + char *thisfield; + size_t thislen; +#if HAVE_MBRTOWC -+ mbstate_t thisstate; ++ mbstate_t thisstate; +#endif - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - { - if (ferror (stdin)) + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) + { + if (ferror (stdin)) @@ -341,6 +561,15 @@ - } - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); + } + thisfield = find_field (thisline); + thislen = thisline->length - 1 - (thisfield - thisline->buffer); +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { ++ if (MB_CUR_MAX > 1) ++ { + thisstate = thisline->state; + match = !different_multi (thisfield, prevfield, + thislen, prevlen, thisstate, prevstate); + } -+ else ++ else +#endif - match = !different (thisfield, prevfield, thislen, prevlen); - match_count += match; + match = !different (thisfield, prevfield, thislen, prevlen); + match_count += match; @@ -373,6 +602,9 @@ - SWAP_LINES (prevline, thisline); - prevfield = thisfield; - prevlen = thislen; + SWAP_LINES (prevline, thisline); + prevfield = thisfield; + prevlen = thislen; +#if HAVE_MBRTOWC -+ prevstate = thisstate; ++ prevstate = thisstate; +#endif - if (!match) - match_count = 0; - } + if (!match) + match_count = 0; + } @@ -417,6 +649,19 @@ atexit (close_stdout); @@ -1298,7 +1275,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + if (operating_mode != byte_mode) { if (c == '\b') - { + { @@ -121,30 +165,14 @@ to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -1333,21 +1310,21 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c while ((c = getc (istream)) != EOF) { @@ -172,6 +200,15 @@ - bool found_blank = false; - size_t logical_end = offset_out; + 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; -+ } ++ /* 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) - { + /* Look for the last blank. */ + while (logical_end) + { @@ -218,11 +255,222 @@ line_out[offset_out++] = c; } @@ -1365,16 +1342,16 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +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. */ ++ size_t buflen = 0; /* The length of the byte sequence in buf. */ + char *bufpos = NULL; /* 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; /* 1, when conversion is failed. Otherwise 0. */ ++ 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; /* 1, when conversion is failed. Otherwise 0. */ + + static char *line_out = NULL; -+ size_t offset_out = 0; /* Index in `line_out' for next char. */ ++ size_t offset_out = 0; /* Index in `line_out' for next char. */ + static size_t allocated_out = 0; + + int increment; @@ -1388,26 +1365,26 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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; \ -+ } \ ++#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; \ -+ } \ ++#define START_NEW_LINE \ ++ do \ ++ { \ ++ putchar ('\n'); \ ++ column = 0; \ ++ offset_out = 0; \ ++ CLEAR_FLAGS; \ ++ } \ + while (0) + + CLEAR_FLAGS; @@ -1416,14 +1393,14 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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; -+ } ++ { ++ memmove (buf, bufpos, buflen); ++ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); ++ bufpos = buf; ++ } + + if (buflen < 1) -+ break; ++ break; + + /* Get a wide character. */ + convfail = 0; @@ -1431,102 +1408,102 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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 (size_t)-1: ++ case (size_t)-2: ++ convfail++; ++ state = state_bak; ++ /* Fall through. */ + -+ case 0: -+ mblength = 1; -+ break; -+ } ++ 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; ++ 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'\r': ++ increment = -1 * column; ++ break; + -+ case L'\t': -+ increment = 8 - column % 8; -+ break; ++ case L'\t': ++ increment = 8 - column % 8; ++ break; + -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; -+ } -+ } -+ } ++ default: ++ increment = wcwidth (wc); ++ increment = (increment < 0) ? 0 : increment; ++ } ++ } ++ } + + if (column + increment > width && break_spaces && last_blank_pos) -+ { -+ fwrite (line_out, sizeof(char), last_blank_pos, stdout); -+ putchar ('\n'); ++ { ++ 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; -+ } ++ 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; -+ } ++ { ++ 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); -+ } ++ { ++ 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; ++ is_cr_after_last_blank = 1; + + if (is_bs_following_last_blank && !convfail && wc == L'\b') -+ ++bs_following_last_blank_num; ++ ++bs_following_last_blank_num; + else -+ is_bs_following_last_blank = 0; ++ 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; -+ } ++ { ++ 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; @@ -1584,21 +1561,21 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { @@ -264,7 +516,15 @@ 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 '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 '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. */ + case 's': /* Break at word boundaries. */ --- coreutils-6.8+/src/sort.c.i18n 2007-02-24 11:23:23.000000000 +0000 +++ coreutils-6.8+/src/sort.c 2007-03-01 15:10:57.000000000 +0000 @@ -23,10 +23,19 @@ @@ -1637,25 +1614,25 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c #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; \ -+ } \ -+ } \ ++#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. */ @@ -1776,35 +1753,35 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + memset (&state_wc, '\0', sizeof (mbstate_t)); + + for (j = 0; j < s_len;) -+ { -+ if (!ismbblank (s + j, s_len - j, &mblength)) -+ break; -+ j += mblength; -+ } ++ { ++ 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; ++ { ++ 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); -+ } ++ 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]; -+ } ++ for (l = 0; l < mblength; l++) ++ name[k++] = mbc[l]; ++ } + name[k] = '\0'; + } + qsort ((void *) monthtab, MONTHS_PER_YEAR, @@ -1832,11 +1809,11 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + if (tab_length) while (ptr < lim && sword--) { -- while (ptr < lim && *ptr != tab) -+ while (ptr < lim && *ptr != tab[0]) - ++ptr; - if (ptr < lim) - ++ptr; +- while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) + ++ptr; + if (ptr < lim) + ++ptr; @@ -1282,11 +1409,70 @@ return ptr; } @@ -1857,29 +1834,29 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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; -+ } ++ 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; ++ 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) @@ -1891,9 +1868,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); + + if (ptr + mblength > lim) -+ break; ++ break; + else -+ ptr += mblength; ++ ptr += mblength; + } + + return ptr; @@ -1917,11 +1894,11 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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; +- while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) + ++ptr; + if (ptr < lim && (eword | echar)) + ++ptr; @@ -1348,10 +1534,10 @@ */ @@ -1933,7 +1910,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c - newlim = memchr (ptr, tab, lim - ptr); + newlim = memchr (ptr, tab[0], lim - ptr); if (newlim) - lim = newlim; + lim = newlim; } @@ -1384,6 +1570,113 @@ return ptr; @@ -1957,29 +1934,29 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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; -+ } ++ 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; ++ 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; + } + + @@ -1991,16 +1968,16 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + + newlim = NULL; + for (p = ptr; p < lim;) -+ { -+ if (memcmp (p, tab, tab_length) == 0) -+ { -+ newlim = p; -+ break; -+ } ++ { ++ if (memcmp (p, tab, tab_length) == 0) ++ { ++ newlim = p; ++ break; ++ } + -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ p += mblength; -+ } ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ p += mblength; ++ } + } + else + { @@ -2008,14 +1985,14 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + newlim = ptr; + + while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) -+ newlim += mblength; ++ newlim += mblength; + if (ptr < lim) -+ { -+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); -+ ptr += mblength; -+ } ++ { ++ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); ++ ptr += mblength; ++ } + while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) -+ newlim += mblength; ++ newlim += mblength; + lim = newlim; + } +# endif @@ -2036,9 +2013,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); + + if (ptr + mblength > lim) -+ break; ++ break; + else -+ ptr += mblength; ++ ptr += mblength; + } + } + @@ -2050,32 +2027,32 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c 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 @@ -1466,8 +1753,24 @@ - else - { - if (key->skipsblanks) -- while (blanks[to_uchar (*line_start)]) -- line_start++; -+ { + else + { + if (key->skipsblanks) +- while (blanks[to_uchar (*line_start)]) +- line_start++; ++ { +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ size_t mblength; -+ mbstate_t state; -+ memset (&state, '\0', sizeof(mbstate_t)); -+ while (line_start < line->keylim && -+ ismbblank (line_start, -+ line->keylim - line_start, -+ &mblength)) -+ line_start += mblength; -+ } -+ else ++ if (MB_CUR_MAX > 1) ++ { ++ size_t mblength; ++ mbstate_t state; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ 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; - } - } ++ while (blanks[to_uchar (*line_start)]) ++ line_start++; ++ } + line->keybeg = line_start; + } + } @@ -1500,7 +1803,7 @@ hideously fast. */ @@ -2086,7 +2063,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c while (blanks[to_uchar (*a)]) a++; @@ -1510,6 +1813,25 @@ - : strnumcmp (a, b, decimal_point, thousands_sep)); + : strnumcmp (a, b, decimal_point, thousands_sep)); } +#if HAVE_MBRTOWC @@ -2163,10 +2140,10 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + { + month_wcs[i] = towupper(month_wcs[i]); + if (iswblank (month_wcs[i])) -+ { -+ month_wcs[i] = L'\0'; -+ break; -+ } ++ { ++ month_wcs[i] = L'\0'; ++ break; ++ } + } + + wpp = (const wchar_t **)&month_wcs; @@ -2179,9 +2156,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + int ix = (lo + hi) / 2; + + if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) -+ hi = ix; ++ hi = ix; + else -+ lo = ix; ++ lo = ix; + } + while (hi - lo > 1); + @@ -2240,133 +2217,133 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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; ++ { ++ 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, key)); -+ *lima = savea, *limb = saveb; -+ } ++ *lima = *limb = '\0'; ++ diff = (key->numeric ? numcompare (texta, textb) ++ : key->general_numeric ? general_numcompare (texta, textb) ++ : human_numcompare (texta, textb, key)); ++ *lima = savea, *limb = saveb; ++ } + else if (key->version) -+ diff = compare_version (texta, lena, textb, lenb); ++ diff = compare_version (texta, lena, textb, lenb); + else if (key->month) -+ diff = getmonth (texta, lena) - getmonth (textb, lenb); ++ diff = getmonth (texta, lena) - getmonth (textb, lenb); + else -+ { -+ if (ignore || translate) -+ { -+ char *copy_a = (char *) alloca (lena + 1 + lenb + 1); -+ char *copy_b = copy_a + lena + 1; -+ size_t new_len_a, new_len_b; -+ size_t i, j; ++ { ++ if (ignore || translate) ++ { ++ char *copy_a = (char *) alloca (lena + 1 + lenb + 1); ++ char *copy_b = copy_a + lena + 1; ++ size_t new_len_a, new_len_b; ++ size_t i, j; + -+ /* 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++]; \ -+ 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'; \ -+ } \ ++ /* 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++]; \ ++ 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) -+ 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); -+ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b); -+ } -+ else if (lena == 0) -+ diff = - NONZERO (lenb); -+ else if (lenb == 0) -+ goto greater; -+ else -+ diff = xmemcoll (texta, lena, textb, lenb); -+ } ++ 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); ++ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b); ++ } ++ else if (lena == 0) ++ diff = - NONZERO (lenb); ++ else if (lenb == 0) ++ goto greater; ++ else ++ diff = xmemcoll (texta, lena, textb, lenb); ++ } + + if (diff) -+ goto not_equal; ++ goto not_equal; + + key = key->next; + if (! key) -+ break; ++ break; + + /* Find the beginning and limit of the next field. */ + if (key->eword != -1) -+ lima = limfield (a, key), limb = limfield (b, key); ++ lima = limfield (a, key), limb = limfield (b, key); + else -+ lima = a->text + a->length - 1, limb = b->text + b->length - 1; ++ lima = a->text + a->length - 1, limb = b->text + b->length - 1; + + if (key->sword != -1) -+ texta = begfield (a, key), textb = begfield (b, key); ++ 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; -+ } -+ } ++ { ++ 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; ++ } ++ } + } + + return 0; @@ -2420,58 +2397,58 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c @@ -3015,13 +3599,35 @@ - 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]) - error (SORT_FAILURE, 0, _("empty tab")); -- if (optarg[1]) + 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]) + error (SORT_FAILURE, 0, _("empty tab")); +- if (optarg[1]) +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ wchar_t wc; -+ mbstate_t state; -+ size_t i; ++ if (MB_CUR_MAX > 1) ++ { ++ wchar_t wc; ++ mbstate_t state; ++ size_t i; + -+ 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; -+ } -+ } ++ 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 ++ if (newtab_length == 1 && optarg[1]) + { + if (STREQ (optarg, "\\0")) +- newtab = '\0'; ++ newtab[0] = '\0'; + else + { + /* Provoke with `sort -txx'. Complain about @@ -3032,9 +3638,12 @@ - quote (optarg)); - } - } -- if (tab != TAB_DEFAULT && tab != newtab) -+ if (tab_length -+ && (tab_length != newtab_length -+ || memcmp (tab, newtab, tab_length) != 0)) - error (SORT_FAILURE, 0, _("incompatible tabs")); -- tab = newtab; -+ memcpy (tab, newtab, newtab_length); -+ tab_length = newtab_length; - } - break; + quote (optarg)); + } + } +- if (tab != TAB_DEFAULT && tab != newtab) ++ if (tab_length ++ && (tab_length != newtab_length ++ || memcmp (tab, newtab, tab_length) != 0)) + error (SORT_FAILURE, 0, _("incompatible tabs")); +- tab = newtab; ++ memcpy (tab, newtab, newtab_length); ++ tab_length = newtab_length; + } + break; --- coreutils-6.8+/src/unexpand.c.i18n 2007-01-14 15:41:28.000000000 +0000 +++ coreutils-6.8+/src/unexpand.c 2007-03-01 15:08:24.000000000 +0000 @@ -2807,8 +2784,8 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c static void pad_across_to (int position); static void add_line_number (COLUMN *p); static void getoptarg (char *arg, char switch_char, char *character, -+ int *character_length, int *character_width, - int *number); ++ int *character_length, int *character_width, + int *number); void usage (int status); static void print_files (int number_of_files, char **av); @@ -440,7 +492,6 @@ @@ -2907,134 +2884,134 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + n_files = 0; file_names = (argc > 1 - ? xmalloc ((argc - 1) * sizeof (char *)) + ? xmalloc ((argc - 1) * sizeof (char *)) @@ -949,8 +1032,12 @@ - break; - case 'e': - if (optarg) -- getoptarg (optarg, 'e', &input_tab_char, -- &chars_per_input_tab); -+ { -+ int dummy_length, dummy_width; + 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; ++ getoptarg (optarg, 'e', input_tab_char, &dummy_length, ++ &dummy_width, &chars_per_input_tab); ++ } + /* Could check tab width > 0. */ + untabify_input = true; + break; @@ -963,8 +1050,12 @@ - break; - case 'i': - if (optarg) -- getoptarg (optarg, 'i', &output_tab_char, -- &chars_per_output_tab); -+ { -+ int dummy_width; + 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; ++ 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; @@ -991,8 +1082,8 @@ - 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; + 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; @@ -1031,7 +1122,7 @@ - old_s = false; - /* Reset an additional input of -s, -S dominates -s */ - col_sep_string = bad_cast (""); -- col_sep_length = 0; -+ col_sep_length = col_sep_width = 0; - use_col_separator = true; - if (optarg) - separator_string (optarg); + old_s = false; + /* Reset an additional input of -s, -S dominates -s */ + col_sep_string = bad_cast (""); +- col_sep_length = 0; ++ col_sep_length = col_sep_width = 0; + use_col_separator = true; + if (optarg) + separator_string (optarg); @@ -1188,10 +1279,45 @@ 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) ++ 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'}; ++ 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); ++ 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; -+ } ++ 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. */ ++ strncpy (character, arg, *character_length); ++ arg += *character_length; ++ } ++ else /* for single byte locale. */ +#endif -+ { -+ *character = *arg++; -+ *character_length = 1; -+ *character_width = 1; -+ } ++ { ++ *character = *arg++; ++ *character_length = 1; ++ *character_width = 1; ++ } + } + if (*arg) { long int tmp_long; @@ -1256,7 +1382,7 @@ - else - col_sep_string = column_separator; + else + col_sep_string = column_separator; -- col_sep_length = 1; -+ col_sep_length = col_sep_width = 1; - use_col_separator = true; - } +- 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 @@ -1288,11 +1414,11 @@ - TAB_WIDTH (chars_per_input_tab, chars_per_number); */ + 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); + 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; +- 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. */ + printing files in parallel. */ @@ -1307,7 +1433,7 @@ } chars_per_column = (chars_per_line - chars_used_by_number - -- (columns - 1) * col_sep_length) / columns; -+ (columns - 1) * col_sep_width) / columns; +- (columns - 1) * col_sep_length) / columns; ++ (columns - 1) * col_sep_width) / columns; if (chars_per_column < 1) error (EXIT_FAILURE, 0, _("page width too narrow")); @@ -3048,13 +3025,13 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* This loop takes care of all but the rightmost column. */ @@ -1466,7 +1592,7 @@ - } + } else - { -- h = h_next + col_sep_length; -+ h = h_next + col_sep_width; - h_next = h + chars_per_column; - } + { +- h = h_next + col_sep_length; ++ h = h_next + col_sep_width; + h_next = h + chars_per_column; + } } @@ -1756,9 +1882,9 @@ align_column (COLUMN *p) @@ -3086,19 +3063,19 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c @@ -2058,22 +2184,24 @@ /* 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. */ + 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) (' '); + (p->char_func) (' '); } else - (p->char_func) (number_separator); -+ for (j = 0; j < number_separator_length; j++) -+ (p->char_func) (number_separator[j]); ++ 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 @@ -3108,14 +3085,14 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c - (p->char_func) (number_separator); - if (number_separator == '\t') + for (j = 0; j < number_separator_length; j++) -+ (p->char_func) (number_separator[j]); ++ (p->char_func) (number_separator[j]); + if (number_separator[0] == '\t') output_position = POS_AFTER_TAB (chars_per_output_tab, - output_position); + output_position); } @@ -2234,7 +2362,7 @@ while (goal - h_old > 1 - && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) + && (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); @@ -3133,28 +3110,28 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c @@ -2267,6 +2396,7 @@ { 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, + { ++ not_space_flag = 0; + while (l-- > 0) + { + /* 3 types of sep_strings: spaces only, spaces and chars, @@ -2280,12 +2410,15 @@ - } - 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; + } + 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 (); + if (spaces_not_printed > 0) + print_white_space (); @@ -2313,7 +2446,7 @@ required number of tabs and spaces. */ @@ -3187,49 +3164,49 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + mblength = mbrtowc (&wc, mbc, mbc_pos, &state); + + while (mbc_pos > 0) -+ { -+ switch (mblength) -+ { -+ case (size_t)-2: -+ state = state_bak; -+ return; ++ { ++ 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 (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; ++ 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 (); ++ 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; ++ /* 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; -+ } -+ } ++ fwrite (mbc, sizeof(char), mblength, stdout); ++ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); ++ mbc_pos -= mblength; ++ } ++ } + return; + } + putchar (c); @@ -3240,19 +3217,19 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c PAGE may be larger than total number of pages. */ @@ -2517,9 +2718,9 @@ - align_empty_cols = false; - } + align_empty_cols = false; + } - if (padding_not_printed - col_sep_length > 0) + if (padding_not_printed - col_sep_width > 0) - { -- pad_across_to (padding_not_printed - col_sep_length); -+ pad_across_to (padding_not_printed - col_sep_width); - padding_not_printed = ANYWHERE; - } + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } @@ -2620,9 +2821,9 @@ - } + } } - if (padding_not_printed - col_sep_length > 0) @@ -3268,9 +3245,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { output_position = p->start_position + end_vector[line]; - if (p->start_position - col_sep_length == chars_per_margin) -- output_position -= col_sep_length; +- output_position -= col_sep_length; + if (p->start_position - col_sep_width == chars_per_margin) -+ output_position -= col_sep_width; ++ output_position -= col_sep_width; } return true; @@ -3327,118 +3304,118 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + while (mbc_pos > 0) + { + switch (mblength) -+ { -+ case (size_t)-2: -+ state = state_bak; -+ return 0; ++ { ++ case (size_t)-2: ++ state = state_bak; ++ return 0; + -+ case (size_t)-1: -+ state = state_bak; -+ mblength = 1; ++ 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", mbc[0]); -+ for (i = 0; i <= 2; ++i) -+ *s++ = (int) esc_buff[i]; -+ } -+ else -+ { -+ width += 1; -+ chars += 1; -+ *s++ = mbc[0]; -+ } -+ break; ++ if (use_esc_sequence || use_cntrl_prefix) ++ { ++ width = +4; ++ chars = +4; ++ *s++ = '\\'; ++ sprintf (esc_buff, "%03o", 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 */ ++ case 0: ++ mblength = 1; ++ /* Fall through */ + -+ default: -+ if (memcmp (mbc, input_tab_char, mblength) == 0) -+ chars_per_c = chars_per_input_tab; ++ 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; ++ 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; ++ 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", c); -+ 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", c); -+ 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]; -+ } -+ } ++ 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", c); ++ 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", c); ++ 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; + } @@ -3470,7 +3447,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c #include "xstrndup.h" +/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC -+ installation; work around this configuration error. */ ++ installation; work around this configuration error. */ +#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 +# undef MB_LEN_MAX +# define MB_LEN_MAX 16 @@ -3489,49 +3466,49 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c 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; \ -+ } \ -+ } \ ++#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 1. Otherwise 0. */ +#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 = 0; \ -+ 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 througn. */ \ -+ \ -+ case 0: \ -+ MBLENGTH = 1; \ -+ break; \ -+ } \ -+ } \ ++ do \ ++ { \ ++ mbstate_t state_bak; \ ++ \ ++ if (BUFLEN < 1) \ ++ { \ ++ WC = WEOF; \ ++ break; \ ++ } \ ++ \ ++ /* Get a wide character. */ \ ++ CONVFAIL = 0; \ ++ 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 througn. */ \ ++ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ break; \ ++ } \ ++ } \ + while (0) + struct range_pair @@ -3608,49 +3585,49 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c fputs (_("\ --complement complement the set of selected bytes, characters\n\ @@ -362,7 +439,7 @@ - in_digits = false; - /* Starting a range. */ - if (dash_found) -- FATAL_ERROR (_("invalid byte or field list")); -+ FATAL_ERROR (_("invalid byte, character or field list")); - dash_found = true; - fieldstr++; + in_digits = false; + /* Starting a range. */ + if (dash_found) +- FATAL_ERROR (_("invalid byte or field list")); ++ FATAL_ERROR (_("invalid byte, character or field list")); + dash_found = true; + fieldstr++; @@ -387,14 +464,16 @@ - if (!rhs_specified) - { - /* `n-'. From `initial' to end of line. */ -- eol_range_start = initial; -+ if (eol_range_start == 0 || -+ (eol_range_start != 0 && eol_range_start > initial)) -+ eol_range_start = initial; - field_found = true; - } - else - { - /* `m-n' or `-n' (1-n). */ - if (value < initial) -- FATAL_ERROR (_("invalid decreasing range")); -+ FATAL_ERROR (_("invalid byte, character or field list")); + if (!rhs_specified) + { + /* `n-'. From `initial' to end of line. */ +- eol_range_start = initial; ++ if (eol_range_start == 0 || ++ (eol_range_start != 0 && eol_range_start > initial)) ++ eol_range_start = initial; + field_found = true; + } + else + { + /* `m-n' or `-n' (1-n). */ + if (value < initial) +- FATAL_ERROR (_("invalid decreasing range")); ++ FATAL_ERROR (_("invalid byte, character or field list")); - /* Is there already a range going to end of line? */ - if (eol_range_start != 0) + /* Is there already a range going to end of line? */ + if (eol_range_start != 0) @@ -467,6 +546,9 @@ - if (operating_mode == byte_mode) - error (0, 0, - _("byte offset %s is too large"), quote (bad_num)); -+ else if (operating_mode == character_mode) -+ error (0, 0, -+ _("character offset %s is too large"), quote (bad_num)); - else - error (0, 0, - _("field number %s is too large"), quote (bad_num)); + if (operating_mode == byte_mode) + error (0, 0, + _("byte offset %s is too large"), quote (bad_num)); ++ else if (operating_mode == character_mode) ++ error (0, 0, ++ _("character offset %s is too large"), quote (bad_num)); + else + error (0, 0, + _("field number %s is too large"), quote (bad_num)); @@ -477,7 +559,7 @@ - fieldstr++; - } + fieldstr++; + } else -- FATAL_ERROR (_("invalid byte or field list")); -+ FATAL_ERROR (_("invalid byte, character or field list")); +- FATAL_ERROR (_("invalid byte or field list")); ++ FATAL_ERROR (_("invalid byte, character or field list")); } max_range_endpoint = 0; @@ -3670,15 +3647,15 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +static void +cut_characters_or_cut_bytes_no_split (FILE *stream) +{ -+ int idx; /* number of bytes or characters in the line so far. */ ++ int 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. */ -+ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ 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. */ ++ int convfail; /* 1, when conversion is failed. Otherwise 0. */ + + idx = 0; + buflen = 0; @@ -3692,29 +3669,29 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); + + if (wc == WEOF) -+ { -+ if (idx > 0) -+ putchar ('\n'); -+ break; -+ } ++ { ++ if (idx > 0) ++ putchar ('\n'); ++ break; ++ } + else if (wc == L'\n') -+ { -+ putchar ('\n'); -+ idx = 0; -+ } ++ { ++ putchar ('\n'); ++ idx = 0; ++ } + else -+ { -+ idx += (operating_mode == byte_mode) ? mblength : 1; -+ if (print_kth (idx, NULL)) -+ fwrite (bufpos, mblength, sizeof(char), stdout); -+ } ++ { ++ idx += (operating_mode == byte_mode) ? mblength : 1; ++ if (print_kth (idx, NULL)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ } + + buflen -= mblength; + bufpos += mblength; + } +} +#endif -+ ++ /* Read from stream STREAM, printing to standard output any selected fields. */ static void @@ -3732,13 +3709,13 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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. */ -+ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ 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. */ ++ int convfail; /* 1, when conversion is failed. Otherwise 0. */ + + found_any_selected_field = 0; + field_idx = 1; @@ -3764,111 +3741,111 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + while (1) + { + if (field_idx == 1 && buffer_first_field) -+ { -+ int len = 0; ++ { ++ int len = 0; + -+ while (1) -+ { -+ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); + -+ GET_NEXT_WC_FROM_BUFFER -+ (wc, bufpos, buflen, mblength, state, convfail); ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); + -+ if (wc == WEOF) -+ break; ++ 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; ++ 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 == L'\n' || wc == wcdelim)) -+ break; -+ } ++ if (!convfail && (wc == L'\n' || wc == wcdelim)) ++ break; ++ } + -+ if (wc == WEOF) -+ break; ++ if (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 != L'\n')) -+ putchar ('\n'); -+ } -+ continue; -+ } ++ /* 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 != L'\n')) ++ putchar ('\n'); ++ } ++ continue; ++ } + -+ if (print_kth (1, NULL)) -+ { -+ /* Print the field, but not the trailing delimiter. */ -+ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); -+ found_any_selected_field = 1; -+ } -+ ++field_idx; -+ } ++ if (print_kth (1, NULL)) ++ { ++ /* Print the field, but not the trailing delimiter. */ ++ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); ++ found_any_selected_field = 1; ++ } ++ ++field_idx; ++ } + + if (wc != WEOF) -+ { -+ if (print_kth (field_idx, NULL)) -+ { -+ if (found_any_selected_field) -+ { -+ fwrite (output_delimiter_string, sizeof (char), -+ output_delimiter_length, stdout); -+ } -+ found_any_selected_field = 1; -+ } ++ { ++ if (print_kth (field_idx, NULL)) ++ { ++ 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); ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); + -+ GET_NEXT_WC_FROM_BUFFER -+ (wc, bufpos, buflen, mblength, state, convfail); ++ GET_NEXT_WC_FROM_BUFFER ++ (wc, bufpos, buflen, mblength, state, convfail); + -+ if (wc == WEOF) -+ break; -+ else if (!convfail && (wc == wcdelim || wc == L'\n')) -+ { -+ buflen -= mblength; -+ bufpos += mblength; -+ break; -+ } ++ if (wc == WEOF) ++ break; ++ else if (!convfail && (wc == wcdelim || wc == L'\n')) ++ { ++ buflen -= mblength; ++ bufpos += mblength; ++ break; ++ } + -+ if (print_kth (field_idx, NULL)) -+ fwrite (bufpos, mblength, sizeof(char), stdout); ++ if (print_kth (field_idx, NULL)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); + -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+ } ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++ } + + if ((!convfail || wc == L'\n') && buflen < 1) -+ wc = WEOF; ++ wc = WEOF; + + if (!convfail && wc == wcdelim) -+ ++field_idx; ++ ++field_idx; + else if (wc == WEOF || (!convfail && wc == L'\n')) -+ { -+ if (found_any_selected_field -+ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) -+ putchar ('\n'); -+ if (wc == WEOF) -+ break; -+ field_idx = 1; -+ found_any_selected_field = 0; -+ } ++ { ++ if (found_any_selected_field ++ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) ++ putchar ('\n'); ++ if (wc == WEOF) ++ break; ++ field_idx = 1; ++ found_any_selected_field = 0; ++ } + } +} +#endif @@ -3882,34 +3859,34 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + 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 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 character_mode: ++ cut_characters_or_cut_bytes_no_split (stream); ++ break; + -+ case field_mode: -+ cut_fields_mb (stream); -+ break; ++ case field_mode: ++ cut_fields_mb (stream); ++ break; + -+ default: -+ abort (); -+ } ++ default: ++ abort (); ++ } + } else - cut_fields (stream); +#endif + { + if (operating_mode == field_mode) -+ cut_fields (stream); ++ cut_fields (stream); + else -+ cut_bytes (stream); ++ cut_bytes (stream); + } } @@ -3925,75 +3902,75 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c set_program_name (argv[0]); @@ -770,7 +1090,6 @@ 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")); + { + case 'b': +- case 'c': + /* Build the byte list. */ + if (operating_mode != undefined_mode) + FATAL_ERROR (_("only one type of list may be specified")); @@ -778,6 +1097,14 @@ - spec_list_string = optarg; - break; + 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 '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) + case 'f': + /* Build the field list. */ + if (operating_mode != undefined_mode) @@ -789,10 +1116,35 @@ - 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; -+ { + 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; ++ if(MB_CUR_MAX > 1) ++ { ++ mbstate_t state; + -+ memset (&state, '\0', sizeof(mbstate_t)); -+ delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &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); -+ } -+ } ++ 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); ++ } ++ } + -+ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) ++ 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; ++ { ++ 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: + case OUTPUT_DELIMITER_OPTION: @@ -805,6 +1157,7 @@ - break; + break; - case 'n': -+ byte_mode_character_aware = 1; - break; + case 'n': ++ byte_mode_character_aware = 1; + break; - case 's': + case 's': @@ -827,7 +1180,7 @@ if (operating_mode == undefined_mode) FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); @@ -4027,20 +4004,20 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c - output_delimiter_length = 1; +#ifdef HAVE_MBRTOWC + if (MB_CUR_MAX > 1 && !force_singlebyte_mode) -+ { -+ output_delimiter_string = xstrdup(mbdelim); -+ output_delimiter_length = delimlen; -+ } ++ { ++ 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; -+ } ++ { ++ static char dummy[2]; ++ dummy[0] = delim; ++ dummy[1] = '\0'; ++ output_delimiter_string = dummy; ++ output_delimiter_length = 1; ++ } } if (optind == argc) diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 6e9a0f2..4881c7c 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -155,15 +155,15 @@ + char const *display = getenv ("DISPLAY"); + char const *xauthority = getenv ("XAUTHORITY"); if (term) - term = xstrdup (term); + term = xstrdup (term); environ = xmalloc ((6 + !!term) * sizeof (char *)); environ[0] = NULL; if (term) - xsetenv ("TERM", term); + xsetenv ("TERM", term); + if (display) -+ xsetenv ("DISPLAY", display); ++ xsetenv ("DISPLAY", display); + if (xauthority) -+ xsetenv ("XAUTHORITY", xauthority); ++ xsetenv ("XAUTHORITY", xauthority); xsetenv ("HOME", pw->pw_dir); xsetenv ("SHELL", shell); xsetenv ("USER", pw->pw_name); @@ -218,8 +218,8 @@ static void run_shell (char const *shell, char const *command, char **additional_args, -- size_t n_additional_args) -+ size_t n_additional_args, const struct passwd *pw) +- size_t n_additional_args) ++ size_t n_additional_args, const struct passwd *pw) { size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; char const **args = xnmalloc (n_args, sizeof *args); diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 21bd492..233af56 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -38,14 +38,14 @@ diff -urNp coreutils-7.1-orig/src/copy.c coreutils-7.1/src/copy.c --- coreutils-7.1-orig/src/copy.c 2009-02-18 15:32:52.000000000 +0100 +++ coreutils-7.1/src/copy.c 2009-02-24 13:47:15.000000000 +0100 @@ -1830,6 +1830,8 @@ copy_internal (char const *src_name, cha - { - /* Here, we are crossing a file system boundary and cp's -x option - is in effect: so don't copy the contents of this directory. */ + { + /* Here, we are crossing a file system boundary and cp's -x option + is in effect: so don't copy the contents of this directory. */ + if (x->preserve_security_context) -+ restore_default_fscreatecon_or_die (); - } ++ restore_default_fscreatecon_or_die (); + } else - { + { diff -urNp coreutils-7.1-orig/src/copy.h coreutils-7.1/src/copy.h --- coreutils-7.1-orig/src/copy.h 2009-02-18 15:32:52.000000000 +0100 +++ coreutils-7.1/src/copy.h 2009-02-24 13:47:15.000000000 +0100 @@ -102,60 +102,60 @@ diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c - while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T", + while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ:", - long_opts, NULL)) - != -1) + long_opts, NULL)) + != -1) { @@ -945,6 +951,16 @@ main (int argc, char **argv) - copy_contents = true; - break; + copy_contents = true; + break; -+ case 'c': -+ if ( x.set_security_context ) { -+ (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]); -+ exit( 1 ); -+ } -+ else if (selinux_enabled) { -+ x.preserve_security_context = true; -+ x.require_preserve_context = true; -+ } -+ break; - case 'd': - x.preserve_links = true; - x.dereference = DEREF_NEVER; ++ case 'c': ++ if ( x.set_security_context ) { ++ (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]); ++ exit( 1 ); ++ } ++ else if (selinux_enabled) { ++ x.preserve_security_context = true; ++ x.require_preserve_context = true; ++ } ++ break; + case 'd': + x.preserve_links = true; + x.dereference = DEREF_NEVER; @@ -1054,6 +1070,27 @@ main (int argc, char **argv) - x.one_file_system = true; - break; + x.one_file_system = true; + break; + -+ case 'Z': -+ /* politely decline if we're not on a selinux-enabled kernel. */ -+ if( !selinux_enabled ) { -+ fprintf( stderr, "Warning: ignoring --context (-Z). " -+ "It requires a SELinux enabled kernel.\n" ); -+ break; -+ } -+ if ( x.preserve_security_context ) { -+ (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], optarg); -+ exit( 1 ); -+ } -+ x.set_security_context = true; -+ /* if there's a security_context given set new path -+ components to that context, too */ -+ if ( setfscreatecon(optarg) < 0 ) { -+ (void) fprintf(stderr, _("cannot set default security context %s\n"), optarg); -+ exit( 1 ); -+ } -+ break; ++ case 'Z': ++ /* politely decline if we're not on a selinux-enabled kernel. */ ++ if( !selinux_enabled ) { ++ fprintf( stderr, "Warning: ignoring --context (-Z). " ++ "It requires a SELinux enabled kernel.\n" ); ++ break; ++ } ++ if ( x.preserve_security_context ) { ++ (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], optarg); ++ exit( 1 ); ++ } ++ x.set_security_context = true; ++ /* if there's a security_context given set new path ++ components to that context, too */ ++ if ( setfscreatecon(optarg) < 0 ) { ++ (void) fprintf(stderr, _("cannot set default security context %s\n"), optarg); ++ exit( 1 ); ++ } ++ break; + - case 'S': - make_backups = true; - backup_suffix_string = optarg; + case 'S': + make_backups = true; + backup_suffix_string = optarg; diff -urNp coreutils-7.1-orig/src/chcon.c coreutils-7.1/src/chcon.c --- coreutils-7.1-orig/src/chcon.c 2008-10-12 16:12:56.000000000 +0200 +++ coreutils-7.1/src/chcon.c 2009-02-24 13:47:15.000000000 +0100 @@ -346,7 +346,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), - program_name, program_name, program_name); + program_name, program_name, program_name); fputs (_("\ -Change the security context of each FILE to CONTEXT.\n\ +Change the SELinux security context of each FILE to CONTEXT.\n\ @@ -191,36 +191,36 @@ diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c - while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options, + while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z:", long_options, - NULL)) != -1) + NULL)) != -1) { switch (optc) @@ -539,6 +540,7 @@ main (int argc, char **argv) - error (0, 0, _("WARNING: --preserve_context is deprecated; " - "use --preserve-context instead")); - /* fall through */ -+ case 'P': - case PRESERVE_CONTEXT_OPTION: - if ( ! selinux_enabled) - { + error (0, 0, _("WARNING: --preserve_context is deprecated; " + "use --preserve-context instead")); + /* fall through */ ++ case 'P': + case PRESERVE_CONTEXT_OPTION: + if ( ! selinux_enabled) + { @@ -546,6 +548,10 @@ main (int argc, char **argv) - "this kernel is not SELinux-enabled")); - break; - } -+ if ( x.set_security_context ) { -+ (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]); -+ exit( 1 ); -+ } - x.preserve_security_context = true; - use_default_selinux_context = false; - break; + "this kernel is not SELinux-enabled")); + break; + } ++ if ( x.set_security_context ) { ++ (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]); ++ exit( 1 ); ++ } + x.preserve_security_context = true; + use_default_selinux_context = false; + break; @@ -557,6 +563,7 @@ main (int argc, char **argv) - break; - } - scontext = optarg; -+ x.set_security_context = true; - use_default_selinux_context = false; - break; - case_GETOPT_HELP_CHAR; + break; + } + scontext = optarg; ++ x.set_security_context = true; + use_default_selinux_context = false; + break; + case_GETOPT_HELP_CHAR; @@ -990,8 +997,8 @@ Mandatory arguments to long options are -v, --verbose print the name of each directory as it is created\n\ "), stdout); @@ -312,21 +312,21 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c @@ -1194,7 +1203,8 @@ main (int argc, char **argv) /* Avoid following symbolic links when possible. */ if (is_colored (C_ORPHAN) - || (is_colored (C_EXEC) && color_symlink_as_referent) -- || (is_colored (C_MISSING) && format == long_format)) -+ || (is_colored (C_MISSING) && (format == long_format -+ || format == security_format))) - check_symlink_color = true; + || (is_colored (C_EXEC) && color_symlink_as_referent) +- || (is_colored (C_MISSING) && format == long_format)) ++ || (is_colored (C_MISSING) && (format == long_format ++ || format == security_format))) + check_symlink_color = true; /* If the standard output is a controlling terminal, watch out @@ -1241,7 +1251,7 @@ main (int argc, char **argv) if (dereference == DEREF_UNDEFINED) dereference = ((immediate_dirs - || indicator_style == classify -- || format == long_format) -+ || format == long_format || format == security_format) - ? DEREF_NEVER - : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); + || indicator_style == classify +- || format == long_format) ++ || format == long_format || format == security_format) + ? DEREF_NEVER + : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); @@ -1261,7 +1271,7 @@ main (int argc, char **argv) @@ -336,7 +336,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c + || format == security_format || print_scontext || print_block_size; format_needs_type = (! format_needs_stat - && (recursive + && (recursive @@ -1292,7 +1302,7 @@ main (int argc, char **argv) } else @@ -356,42 +356,42 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c /* FIXME: put this in a function. */ { @@ -1837,13 +1847,27 @@ decode_switches (int argc, char **argv) - break; + break; - case 'Z': -- print_scontext = true; -+ print_scontext = 1; + case 'Z': +- print_scontext = true; ++ print_scontext = 1; + format = security_format; - break; + break; - case_GETOPT_HELP_CHAR; + case_GETOPT_HELP_CHAR; - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + case CONTEXT_OPTION: /* default security context format */ -+ print_scontext = 1; -+ format = security_format; -+ break; -+ case LCONTEXT_OPTION: /* long format plus security context */ -+ print_scontext = 1; -+ format = long_format; -+ break; -+ case SCONTEXT_OPTION: /* short form of new security format */ -+ print_scontext = 0; -+ format = security_format; -+ break; ++ print_scontext = 1; ++ format = security_format; ++ break; ++ case LCONTEXT_OPTION: /* long format plus security context */ ++ print_scontext = 1; ++ format = long_format; ++ break; ++ case SCONTEXT_OPTION: /* short form of new security format */ ++ print_scontext = 0; ++ format = security_format; ++ break; + - default: - usage (LS_FAILURE); - } + default: + usage (LS_FAILURE); + } @@ -2557,8 +2581,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); - if (f->scontext != UNKNOWN_SECURITY_CONTEXT) -- freecon (f->scontext); +- freecon (f->scontext); + if (f->scontext != UNKNOWN_SECURITY_CONTEXT) { -+ freecon (f->scontext); ++ freecon (f->scontext); + f->scontext = NULL; + } } @@ -411,49 +411,49 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c - if (format == long_format || print_scontext) + if (format == long_format || format == security_format || print_scontext) - { - bool have_selinux = false; - bool have_acl = false; + { + bool have_selinux = false; + bool have_acl = false; @@ -2732,7 +2760,7 @@ gobble_file (char const *name, enum file - err = 0; - } + err = 0; + } -- if (err == 0 && format == long_format) -+ if (err == 0 && (format == long_format || format == security_format)) - { - int n = file_has_acl (absolute_name, &f->stat); - err = (n < 0); +- if (err == 0 && format == long_format) ++ if (err == 0 && (format == long_format || format == security_format)) + { + int n = file_has_acl (absolute_name, &f->stat); + err = (n < 0); @@ -2751,7 +2779,8 @@ gobble_file (char const *name, enum file - } + } if (S_ISLNK (f->stat.st_mode) -- && (format == long_format || check_symlink_color)) -+ && (format == long_format || format == security_format -+ || check_symlink_color)) - { - char *linkname; - struct stat linkstats; +- && (format == long_format || check_symlink_color)) ++ && (format == long_format || format == security_format ++ || check_symlink_color)) + { + char *linkname; + struct stat linkstats; @@ -2771,6 +2800,7 @@ gobble_file (char const *name, enum file - command line are automatically traced if not being - listed as files. */ - if (!command_line_arg || format == long_format -+ || format == security_format - || !S_ISDIR (linkstats.st_mode)) - { - /* Get the linked-to file's mode for the filetype indicator + command line are automatically traced if not being + listed as files. */ + if (!command_line_arg || format == long_format ++ || format == security_format + || !S_ISDIR (linkstats.st_mode)) + { + /* Get the linked-to file's mode for the filetype indicator @@ -2810,7 +2840,7 @@ gobble_file (char const *name, enum file - block_size_width = len; - } + block_size_width = len; + } - if (format == long_format) + if (format == long_format || format == security_format) - { - if (print_owner) - { + { + if (print_owner) + { @@ -3312,6 +3341,13 @@ print_current_files (void) - print_long_format (sorted_file[i]); - DIRED_PUTCHAR ('\n'); - } + print_long_format (sorted_file[i]); + DIRED_PUTCHAR ('\n'); + } + break; + case security_format: + for (i = 0; i < cwd_n_used; i++) @@ -514,15 +514,15 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c + DIRED_INDENT (); + DIRED_FPUTS (buf, stdout, p - buf); + size_t w = print_name_with_quoting (f->name, FILE_OR_LINK_MODE(f), f->linkok, -+ f->stat_ok, f->filetype, &dired_obstack, f->stat.st_nlink, p - buf); ++ f->stat_ok, f->filetype, &dired_obstack, f->stat.st_nlink, p - buf); + + if (f->filetype == symbolic_link) { + if (f->linkname) { -+ DIRED_FPUTS_LITERAL (" -> ", stdout); -+ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, -+ f->stat_ok, f->filetype, NULL, f->stat.st_nlink, (p-buf) + w + 4 ); -+ if (indicator_style != none) -+ print_type_indicator (f->stat_ok, f->linkmode, f->filetype); ++ DIRED_FPUTS_LITERAL (" -> ", stdout); ++ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, ++ f->stat_ok, f->filetype, NULL, f->stat.st_nlink, (p-buf) + w + 4 ); ++ if (indicator_style != none) ++ print_type_indicator (f->stat_ok, f->linkmode, f->filetype); + } + } + else { @@ -553,27 +553,27 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c @@ -3543,9 +3648,6 @@ print_long_format (const struct fileinfo if (print_author) - format_user (f->stat.st_author, author_width, f->stat_ok); + format_user (f->stat.st_author, author_width, f->stat_ok); - if (print_scontext) -- format_user_or_group (f->scontext, 0, scontext_width); +- format_user_or_group (f->scontext, 0, scontext_width); - p = buf; } @@ -3888,9 +3990,6 @@ print_file_name_and_frills (const struct - human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, - ST_NBLOCKSIZE, output_block_size)); + human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, + ST_NBLOCKSIZE, output_block_size)); - if (print_scontext) - printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext); - size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), - f->linkok, f->stat_ok, f->filetype, - NULL, f->stat.st_nlink, start_col); + f->linkok, f->stat_ok, f->filetype, + NULL, f->stat.st_nlink, start_col); @@ -4105,9 +4204,6 @@ length_of_file_name_and_frills (const st - output_block_size)) - : block_size_width); + output_block_size)) + : block_size_width); - if (print_scontext) - len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width); @@ -598,7 +598,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c +"), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); - fputs (_("\n\ + emit_size_note (); diff -urNp coreutils-7.1-orig/src/mkdir.c coreutils-7.1/src/mkdir.c --- coreutils-7.1-orig/src/mkdir.c 2008-10-19 21:47:57.000000000 +0200 +++ coreutils-7.1/src/mkdir.c 2009-02-24 13:47:15.000000000 +0100 @@ -665,32 +665,32 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c + if (terse) { - format = (terse -- ? "%n %i %l %t %s %S %b %f %a %c %d\n" -- : " File: \"%n\"\n" -- " ID: %-8i Namelen: %-7l Type: %T\n" -- "Block size: %-10s Fundamental block size: %S\n" -- "Blocks: Total: %-10b Free: %-10f Available: %a\n" -- "Inodes: Total: %-10c Free: %d\n"); +- ? "%n %i %l %t %s %S %b %f %a %c %d\n" +- : " File: \"%n\"\n" +- " ID: %-8i Namelen: %-7l Type: %T\n" +- "Block size: %-10s Fundamental block size: %S\n" +- "Blocks: Total: %-10b Free: %-10f Available: %a\n" +- "Inodes: Total: %-10c Free: %d\n"); + if (secure) + format = "%n %i %l %t %s %S %b %f %a %c %d %C\n"; -+ else -+ format = "%n %i %l %t %s %S %b %f %a %c %d\n"; ++ else ++ format = "%n %i %l %t %s %S %b %f %a %c %d\n"; } + else -+ { -+ if (secure) -+ format = " File: \"%n\"\n" -+ " ID: %-8i Namelen: %-7l Type: %T\n" -+ "Block size: %-10s Fundamental block size: %S\n" -+ "Blocks: Total: %-10b Free: %-10f Available: %a\n" -+ "Inodes: Total: %-10c Free: %d\n" -+ " S_Context: %C\n"; -+ else -+ format = " File: \"%n\"\n" -+ " ID: %-8i Namelen: %-7l Type: %T\n" -+ "Block size: %-10s Fundamental block size: %S\n" -+ "Blocks: Total: %-10b Free: %-10f Available: %a\n" -+ "Inodes: Total: %-10c Free: %d\n"; ++ { ++ if (secure) ++ format = " File: \"%n\"\n" ++ " ID: %-8i Namelen: %-7l Type: %T\n" ++ "Block size: %-10s Fundamental block size: %S\n" ++ "Blocks: Total: %-10b Free: %-10f Available: %a\n" ++ "Inodes: Total: %-10c Free: %d\n" ++ " S_Context: %C\n"; ++ else ++ format = " File: \"%n\"\n" ++ " ID: %-8i Namelen: %-7l Type: %T\n" ++ "Block size: %-10s Fundamental block size: %S\n" ++ "Blocks: Total: %-10b Free: %-10f Available: %a\n" ++ "Inodes: Total: %-10c Free: %d\n"; + } + } @@ -709,46 +709,46 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c if (format == NULL) { if (terse) -- { -- format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; -- } +- { +- format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; +- } + { + if (secure) -+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"; -+ else -+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; ++ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"; ++ else ++ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; + } else - { - /* Temporary hack to match original output until conditional + { + /* Temporary hack to match original output until conditional @@ -885,12 +904,22 @@ do_stat (char const *filename, bool ters - } - else - { -- format = -- " File: %N\n" -- " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -- "Device: %Dh/%dd\tInode: %-10i Links: %h\n" -- "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -- "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + } + else + { +- format = +- " File: %N\n" +- " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" +- "Device: %Dh/%dd\tInode: %-10i Links: %h\n" +- "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" +- "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + if (secure) + format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h" -+ " Device type: %t,%T\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ " S_Context: %C\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; ++ " File: %N\n" ++ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" ++ "Device: %Dh/%dd\tInode: %-10i Links: %-5h" ++ " Device type: %t,%T\n" ++ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" ++ " S_Context: %C\n" ++ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + else -+ format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %h\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; - } - } ++ format = ++ " File: %N\n" ++ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" ++ "Device: %Dh/%dd\tInode: %-10i Links: %h\n" ++ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" ++ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; + } + } } @@ -911,6 +940,7 @@ usage (int status) Display file or file system status.\n\ @@ -767,34 +767,34 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c bool ok = true; @@ -1034,13 +1065,13 @@ main (int argc, char *argv[]) - terse = true; - break; + terse = true; + break; -- case 'Z': /* FIXME: remove in 2010 */ -- /* Ignore, for compatibility with distributions -- that implemented this before upstream. -- But warn of impending removal. */ -- error (0, 0, -- _("the --context (-Z) option is obsolete and will be removed\n" -- "in a future release")); -+ case 'Z': +- case 'Z': /* FIXME: remove in 2010 */ +- /* Ignore, for compatibility with distributions +- that implemented this before upstream. +- But warn of impending removal. */ +- error (0, 0, +- _("the --context (-Z) option is obsolete and will be removed\n" +- "in a future release")); ++ case 'Z': + if((is_selinux_enabled()>0)) -+ secure = 1; -+ else { -+ error (0, 0, _("Kernel is not SELinux enabled")); -+ usage (EXIT_FAILURE); -+ } - break; ++ secure = 1; ++ else { ++ error (0, 0, _("Kernel is not SELinux enabled")); ++ usage (EXIT_FAILURE); ++ } + break; - case_GETOPT_HELP_CHAR; + case_GETOPT_HELP_CHAR; @@ -1060,8 +1091,8 @@ main (int argc, char *argv[]) for (i = optind; i < argc; i++) ok &= (fs -- ? do_statfs (argv[i], terse, format) -- : do_stat (argv[i], terse, format)); -+ ? do_statfs (argv[i], terse, secure, format) -+ : do_stat (argv[i], terse, secure, format)); +- ? do_statfs (argv[i], terse, format) +- : do_stat (argv[i], terse, format)); ++ ? do_statfs (argv[i], terse, secure, format) ++ : do_stat (argv[i], terse, secure, format)); exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/coreutils-setsid.patch b/coreutils-setsid.patch index e54535f..78ab64d 100644 --- a/coreutils-setsid.patch +++ b/coreutils-setsid.patch @@ -33,24 +33,24 @@ - || sigprocmask(SIG_UNBLOCK, &ourset, NULL)) { + if (!same_session) + { -+ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) -+ { -+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); -+ caught = 1; -+ } ++ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) ++ { ++ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); ++ caught = 1; ++ } + } + if (!caught && (sigaddset(&ourset, SIGTERM) -+ || sigaddset(&ourset, SIGALRM) -+ || sigaction(SIGTERM, &action, NULL) -+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) { ++ || sigaddset(&ourset, SIGALRM) ++ || sigaction(SIGTERM, &action, NULL) ++ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) { fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); caught = 1; } + if (!caught && !same_session && (sigaction(SIGINT, &action, NULL) -+ || sigaction(SIGQUIT, &action, NULL))) ++ || sigaction(SIGQUIT, &action, NULL))) + { -+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); -+ caught = 1; ++ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); ++ caught = 1; + } } if (!caught) { @@ -73,17 +73,17 @@ struct passwd *pw; struct passwd pw_copy; @@ -656,6 +679,11 @@ - command = optarg; - break; + command = optarg; + break; -+ case 'C': -+ command = optarg; -+ request_same_session = 1; -+ break; ++ case 'C': ++ command = optarg; ++ request_same_session = 1; ++ break; + - case 'f': - fast_startup = true; - break; + case 'f': + fast_startup = true; + break; @@ -725,6 +753,9 @@ } #endif diff --git a/coreutils.spec b/coreutils.spec index 2126148..2141d49 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 7.5 -Release: 6%{?dist} +Version: 7.6 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,14 +18,11 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -Patch1: coreutils-7.5-kojiutimensatskip.patch -Patch2: coreutils-7.5-ls-inode.patch # Our patches Patch100: coreutils-6.10-configuration.patch Patch101: coreutils-6.10-manpages.patch Patch102: coreutils-7.4-sttytcsadrain.patch -Patch103: coreutils-7.5-df-localdevice.patch # sh-utils Patch703: sh-utils-2.0.11-dateman.patch @@ -110,14 +107,11 @@ Libraries for coreutils package. %setup -q # From upstream -%patch1 -p1 -b .kojiutimensat -%patch2 -p1 -b .inode # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages %patch102 -p1 -b .tcsadrain -%patch103 -p1 -b .localdevice # sh-utils %patch703 -p1 -b .dateman @@ -333,6 +327,10 @@ fi %{_libdir}/coreutils %changelog +* Sat Sep 12 2009 Ondrej Vasik - 7.6-1 +- new upstream bugfix release 7.6, removed applied patches, + defuzzed the rest + * Thu Sep 10 2009 Ondrej Vasik - 7.5-6 - fix double free error in fold for singlebyte locales (caused by multibyte patch) diff --git a/sources b/sources index 577a3ac..2cffc5b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -ca9219c5b7efa533d552f61a3880f458 coreutils-7.5.tar.xz +a9fb9368e40205d70fc37b9fe441e8ec coreutils-7.6.tar.xz From 6a4350f7d96cc1adf7c032b0edf5de583cb634fe Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 16 Sep 2009 06:03:40 +0000 Subject: [PATCH 050/523] fix copying of extended attributes for read only source files --- coreutils-cpxattrreadonly.patch | 163 ++++++++++++++++++++++++++++++++ coreutils.spec | 12 ++- 2 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 coreutils-cpxattrreadonly.patch diff --git a/coreutils-cpxattrreadonly.patch b/coreutils-cpxattrreadonly.patch new file mode 100644 index 0000000..2b28996 --- /dev/null +++ b/coreutils-cpxattrreadonly.patch @@ -0,0 +1,163 @@ +From cca83fafa69eb26db458714830b77498b88af8a4 Mon Sep 17 00:00:00 2001 +From: Ondřej Vašík +Date: Mon, 14 Sep 2009 13:12:01 +0000 +Subject: cp,mv: preserve extended attributes even for read-only files + +* src/copy.c (copy_reg): Temporarily set u+rw on the destination file +to allow GNU/Linux to set xattrs. +* tests/misc/xattr: Test that change. +Reported by Ernest N. Mamikonyan. +--- +diff --git a/src/copy.c b/src/copy.c +index f3ff5a2..ad2060b 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -834,6 +834,24 @@ copy_reg (char const *src_name, char const *dst_name, + } + } + ++ /* To allow copying xattrs on read-only files, temporarily chmod u+rw. ++ This workaround is required as an inode permission check is done ++ by xattr_permission() in fs/xattr.c of the GNU/Linux kernel tree. */ ++ if (x->preserve_xattr) ++ { ++ bool access_changed = false; ++ ++ if (!(sb.st_mode & S_IWUSR) && geteuid() != 0) ++ access_changed = fchmod_or_lchmod (dest_desc, dst_name, 0600) == 0; ++ ++ if (!copy_attr_by_fd (src_name, source_desc, dst_name, dest_desc, x) ++ && x->require_preserve_xattr) ++ return_val = false; ++ ++ if (access_changed) ++ fchmod_or_lchmod (dest_desc, dst_name, dst_mode & ~omitted_permissions); ++ } ++ + if (x->preserve_ownership && ! SAME_OWNER_AND_GROUP (*src_sb, sb)) + { + switch (set_owner (x, dst_name, dest_desc, src_sb, *new_dst, &sb)) +@@ -850,11 +868,6 @@ copy_reg (char const *src_name, char const *dst_name, + + set_author (dst_name, dest_desc, src_sb); + +- if (x->preserve_xattr && ! copy_attr_by_fd (src_name, source_desc, +- dst_name, dest_desc, x) +- && x->require_preserve_xattr) +- return_val = false; +- + if (x->preserve_mode || x->move_mode) + { + if (copy_acl (src_name, source_desc, dst_name, dest_desc, src_mode) != 0 +diff --git a/tests/misc/xattr b/tests/misc/xattr +index a27e1f6..fcf7ceb 100755 +--- a/tests/misc/xattr ++++ b/tests/misc/xattr +@@ -29,7 +29,7 @@ fi + + # Skip this test if cp was built without xattr support: + touch src dest || framework_failure +-cp --preserve=xattr -n src dest 2>/dev/null \ ++cp --preserve=xattr -n src dest \ + || skip_test_ "coreutils built without xattr support" + + # this code was taken from test mv/backup-is-src +@@ -46,13 +46,13 @@ xattr_pair="$xattr_name=\"$xattr_value\"" + # create new file and check its xattrs + touch a || framework_failure + getfattr -d a >out_a || skip_test_ "failed to get xattr of file" +-grep -F "$xattr_pair" out_a >/dev/null && framework_failure ++grep -F "$xattr_pair" out_a && framework_failure + + # try to set user xattr on file + setfattr -n "$xattr_name" -v "$xattr_value" a >out_a \ + || skip_test_ "failed to set xattr of file" + getfattr -d a >out_a || skip_test_ "failed to get xattr of file" +-grep -F "$xattr_pair" out_a >/dev/null \ ++grep -F "$xattr_pair" out_a \ + || skip_test_ "failed to set xattr of file" + + fail=0 +@@ -60,36 +60,50 @@ fail=0 + # cp should not preserve xattr by default + cp a b || fail=1 + getfattr -d b >out_b || skip_test_ "failed to get xattr of file" +-grep -F "$xattr_pair" out_b >/dev/null && fail=1 ++grep -F "$xattr_pair" out_b && fail=1 + + # test if --preserve=xattr option works + cp --preserve=xattr a b || fail=1 + getfattr -d b >out_b || skip_test_ "failed to get xattr of file" +-grep -F "$xattr_pair" out_b >/dev/null || fail=1 ++grep -F "$xattr_pair" out_b || fail=1 + + #test if --preserve=all option works + cp --preserve=all a c || fail=1 + getfattr -d c >out_c || skip_test_ "failed to get xattr of file" +-grep -F "$xattr_pair" out_c >/dev/null || fail=1 ++grep -F "$xattr_pair" out_c || fail=1 + + #test if -a option works without any diagnostics + cp -a a d 2>err && test -s err && fail=1 + getfattr -d d >out_d || skip_test_ "failed to get xattr of file" +-grep -F "$xattr_pair" out_d >/dev/null || fail=1 ++grep -F "$xattr_pair" out_d || fail=1 ++ ++#test if --preserve=xattr works even for files without write access ++chmod a-w a || framework_failure ++rm -f e ++cp --preserve=xattr a e || fail=1 ++getfattr -d e >out_e || skip_test_ "failed to get xattr of file" ++grep -F "$xattr_pair" out_e || fail=1 ++ ++#Ensure that permission bits are preserved, too. ++src_perm=$(stat --format=%a a) ++dst_perm=$(stat --format=%a e) ++test "$dst_perm" = "$src_perm" || fail=1 ++ ++chmod u+w a || framework_failure + + rm b || framework_failure + + # install should never preserve xattr + ginstall a b || fail=1 + getfattr -d b >out_b || skip_test_ "failed to get xattr of file" +-grep -F "$xattr_pair" out_b >/dev/null && fail=1 ++grep -F "$xattr_pair" out_b && fail=1 + + # mv should preserve xattr when renaming within a file system. + # This is implicitly done by rename () and doesn't need explicit + # xattr support in mv. + mv a b || fail=1 + getfattr -d b >out_b || skip_test_ "failed to get xattr of file" +-grep -F "$xattr_pair" out_b >/dev/null || cat >&2 <&2 <out_a 2>/dev/null \ ++setfattr -n "$xattr_name" -v "$xattr_value" "$b_other" >out_a \ + || test_mv=0 +-getfattr -d "$b_other" >out_b 2>/dev/null || test_mv=0 +-grep -F "$xattr_pair" out_b >/dev/null || test_mv=0 ++getfattr -d "$b_other" >out_b || test_mv=0 ++grep -F "$xattr_pair" out_b || test_mv=0 + rm -f "$b_other" || framework_failure + + if test $test_mv -eq 1; then + # mv should preserve xattr when copying content from one partition to another + mv b "$b_other" || fail=1 +- getfattr -d "$b_other" >out_b 2>/dev/null || ++ getfattr -d "$b_other" >out_b || + skip_test_ "failed to get xattr of file" +- grep -F "$xattr_pair" out_b >/dev/null || fail=1 ++ grep -F "$xattr_pair" out_b || fail=1 + else + cat >&2 < - 7.6-2 +- fix copying of extended attributes for read only source + files + * Sat Sep 12 2009 Ondrej Vasik - 7.6-1 - new upstream bugfix release 7.6, removed applied patches, defuzzed the rest From f0deff4c0d91132faf96013988d824f943b2581f Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 18 Sep 2009 07:19:28 +0000 Subject: [PATCH 051/523] fixed typo in DIR_COLORS.256color causing no color for multihardlink (thanks P.Brady) --- coreutils-DIR_COLORS.256color | 2 +- coreutils.spec | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 71d8e24..b9ba1d0 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -55,7 +55,7 @@ RESET 0 # reset to "normal" color DIR 01;38;5;27 # directory LINK 01;38;5;51 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 44;38;5;15; # regular file with more than one link +MULTIHARDLINK 44;38;5;15 # regular file with more than one link FIFO 40;38;5;11 # pipe SOCK 01;38;5;13 # socket DOOR 01;38;5;5 # door diff --git a/coreutils.spec b/coreutils.spec index 98da451..90eadd4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.6 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -327,6 +327,10 @@ fi %{_libdir}/coreutils %changelog +* Fri Sep 18 2009 Ondrej Vasik - 7.6-3 +- fixed typo in DIR_COLORS.256color causing no color for + multihardlink + * Wed Sep 16 2009 Ondrej Vasik - 7.6-2 - fix copying of extended attributes for read only source files From 4c2f2aae39d2bc9aa651aa320b96a45b6a146598 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 21 Sep 2009 06:04:14 +0000 Subject: [PATCH 052/523] add dircolors color for GNU lzip (#516897) --- coreutils-7.6-lzipcolor.patch | 11 +++++++++++ coreutils-DIR_COLORS | 1 + coreutils-DIR_COLORS.256color | 1 + coreutils-DIR_COLORS.lightbgcolor | 1 + coreutils.spec | 7 ++++++- 5 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 coreutils-7.6-lzipcolor.patch diff --git a/coreutils-7.6-lzipcolor.patch b/coreutils-7.6-lzipcolor.patch new file mode 100644 index 0000000..d27678b --- /dev/null +++ b/coreutils-7.6-lzipcolor.patch @@ -0,0 +1,11 @@ +diff -urNp coreutils-7.6-orig/src/dircolors.hin coreutils-7.6/src/dircolors.hin +--- coreutils-7.6-orig/src/dircolors.hin 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-7.6/src/dircolors.hin 2009-09-21 08:00:38.000000000 +0200 +@@ -131,6 +131,7 @@ EXEC 01;32 + .cpio 01;31 + .7z 01;31 + .rz 01;31 ++.lz 01;31 + + # image formats + .jpg 01;35 diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index a3a14bb..0e07569 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -123,6 +123,7 @@ EXEC 01;32 .Z 01;31 .dz 01;31 .gz 01;31 +.lz 01;31 .xz 01;31 .bz2 01;31 .tbz 01;31 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index b9ba1d0..4628941 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -98,6 +98,7 @@ EXEC 01;38;5;34 .Z 01;38;5;9 .dz 01;38;5;9 .gz 01;38;5;9 +.lz 01;38;5;9 .xz 01;38;5;9 .bz2 01;38;5;9 .tbz 01;38;5;9 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index 6d8e457..d254559 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -101,6 +101,7 @@ EXEC 00;32 .Z 00;31 .dz 00;31 .gz 00;31 +.lz 00;31 .xz 00;31 .bz2 00;31 .tbz 00;31 diff --git a/coreutils.spec b/coreutils.spec index 90eadd4..c6d1046 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.6 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -19,6 +19,7 @@ Source203: coreutils-runuser-l.pamd # From upstream Patch1: coreutils-cpxattrreadonly.patch +Patch2: coreutils-lzipcolor.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -109,6 +110,7 @@ Libraries for coreutils package. # From upstream %patch1 -p1 -b .roxattr +%patch2 -p1 -b .lzip # Our patches %patch100 -p1 -b .configure @@ -327,6 +329,9 @@ fi %{_libdir}/coreutils %changelog +* Mon Sep 21 2009 Ondrej Vasik - 7.6-4 +- add dircolors color for GNU lzip (#516897) + * Fri Sep 18 2009 Ondrej Vasik - 7.6-3 - fixed typo in DIR_COLORS.256color causing no color for multihardlink From 2277f1a25d96ff8c639590af0037bc9a6c1cb4dc Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 21 Sep 2009 06:08:13 +0000 Subject: [PATCH 053/523] fix the patchname --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index c6d1046..4e72eb1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -19,7 +19,7 @@ Source203: coreutils-runuser-l.pamd # From upstream Patch1: coreutils-cpxattrreadonly.patch -Patch2: coreutils-lzipcolor.patch +Patch2: coreutils-7.6-lzipcolor.patch # Our patches Patch100: coreutils-6.10-configuration.patch From 066fd3a5cb990132d97eacc4fff0da46fdd322e4 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 22 Sep 2009 13:24:02 +0000 Subject: [PATCH 054/523] improve and correct runuser documentation (#524805) --- coreutils-5.2.1-runuser.patch | 31 +++++++++++++++++++++++-------- coreutils.spec | 5 ++++- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index f78cbc0..5600d2f 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -32,9 +32,9 @@ diff -urNp coreutils-7.0.orig/man/runuser.x coreutils-7.0/man/runuser.x +.TP +More detailed Texinfo documentation could be found by command +.TP -+\t\fBinfo su invocation\fR\t ++\t\fBinfo coreutils \(aqsu invocation\(aq\fR\t +.TP -+since the command \fBrunuser\fR is trimmed down version of command \fBrunuser\fR. ++since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR. +.br diff -urNp coreutils-7.0.orig/README coreutils-7.0/README --- coreutils-7.0.orig/README 2008-08-24 22:30:10.000000000 +0200 @@ -224,16 +224,18 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c pam_end(pamh, 0); if (!same_session) setsid (); -@@ -620,6 +665,26 @@ usage (int status) +@@ -620,6 +665,28 @@ usage (int status) else { printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name); +#ifdef RUNUSER -+ fputs (_("\ -+Change the effective user id and group id to that of USER. No PAM hooks\n\ -+are run, and there will be no password prompt. This command is useful\n\ ++ printf (_("\ ++Change the effective user id and group id to that of USER. Only session PAM\n\ ++hooks are run, and there is no password prompt. This command is useful only\n\ +when run as the root user. If run as a non-root user without privilege\n\ -+to set user ID, the command will fail.\n\ ++to set user ID, the command will fail as the binary is not setuid.\n\ ++As %s doesn't run auth and account PAM hooks, it runs with lower overhead\n\ ++than su.\n\ +\n\ + -, -l, --login make the shell a login shell, uses runuser-l\n\ + PAM file instead of default one\n\ @@ -246,7 +248,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c + -m, --preserve-environment do not reset environment variables\n\ + -p same as -m\n\ + -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ -+"), stdout); ++"), program_name); +#else fputs (_("\ Change the effective user id and group id to that of USER.\n\ @@ -366,3 +368,16 @@ diff -urNp coreutils-7.5.orig/tests/misc/help-version coreutils-7.5/tests/misc/h timeout_args=--version # I'd rather not run sync, since it spins up disks that I've +diff -urNp coreutils-7.6-orig/man/help2man coreutils-7.6/man/help2man +--- coreutils-7.6-orig/man/help2man 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-7.6/man/help2man 2009-09-22 15:15:01.000000000 +0200 +@@ -550,6 +550,9 @@ while (length) + $include{$sect} .= $content; + } + ++# There is no info documentation for runuser (shared with su). ++$opt_no_info = 1 if $program eq 'runuser'; ++ + # Refer to the real documentation. + unless ($opt_no_info) + { diff --git a/coreutils.spec b/coreutils.spec index 4e72eb1..06648b5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.6 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -329,6 +329,9 @@ fi %{_libdir}/coreutils %changelog +* Tue Sep 22 2009 Ondrej Vasik - 7.6-5 +- improve and correct runuser documentation (#524805) + * Mon Sep 21 2009 Ondrej Vasik - 7.6-4 - add dircolors color for GNU lzip (#516897) From ae3959bffe8aa17f18253e47eb656971b6e64268 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 2 Oct 2009 14:41:18 +0000 Subject: [PATCH 055/523] ls -LR exits with status 2, not 0, when it encounters a cycle(#525402), ls: print ?, not 0 as inode of dereferenced dangling symlink(#525400), call the install-info on .gz info files --- coreutils-ls-inode.patch | 161 +++++++++++++++++++++++++++++++++++++++ coreutils.spec | 23 ++++-- 2 files changed, 177 insertions(+), 7 deletions(-) create mode 100644 coreutils-ls-inode.patch diff --git a/coreutils-ls-inode.patch b/coreutils-ls-inode.patch new file mode 100644 index 0000000..fa52a67 --- /dev/null +++ b/coreutils-ls-inode.patch @@ -0,0 +1,161 @@ +diff -urNp coreutils-7.6-orig/doc/coreutils.texi coreutils-7.6/doc/coreutils.texi +--- coreutils-7.6-orig/doc/coreutils.texi 2009-09-22 15:12:55.000000000 +0200 ++++ coreutils-7.6/doc/coreutils.texi 2009-10-02 16:09:57.000000000 +0200 +@@ -6114,7 +6114,8 @@ Exit status: + specified as a command line argument. This happens when listing a + directory in which entries are actively being removed or renamed.) + 2 serious trouble (e.g., memory exhausted, invalid option or failure +- to access file or directory specified as a command line argument) ++ to access file or directory specified as a command line argument ++ or a directory loop) + @end display + + Also see @ref{Common options}. + +diff -urNp coreutils-7.6-orig/src/ls.c coreutils-7.6/src/ls.c +--- coreutils-7.6-orig/src/ls.c 2009-09-22 15:12:55.000000000 +0200 ++++ coreutils-7.6/src/ls.c 2009-10-02 16:19:54.000000000 +0200 +@@ -2494,6 +2494,7 @@ print_dir (char const *name, char const + error (0, 0, _("%s: not listing already-listed directory"), + quotearg_colon (name)); + closedir (dirp); ++ set_exit_status (true); + return; + } + +@@ -3582,6 +3583,18 @@ format_user_width (uid_t u) + return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u); + } + ++/* Return a pointer to a formatted version of F->stat.st_ino, ++ possibly using buffer, BUF, of length BUFLEN, which must be at least ++ INT_BUFSIZE_BOUND (uintmax_t) bytes. */ ++static char * ++format_inode (char *buf, size_t buflen, const struct fileinfo *f) ++{ ++ assert (INT_BUFSIZE_BOUND (uintmax_t) <= buflen); ++ return (f->stat_ok && f->stat.st_ino != NOT_AN_INODE_NUMBER ++ ? umaxtostr (f->stat.st_ino, buf) ++ : (char *) "?"); ++} ++ + /* Likewise, for groups. */ + + static int +@@ -3712,9 +3725,7 @@ print_long_format (const struct fileinfo + { + char hbuf[INT_BUFSIZE_BOUND (uintmax_t)]; + sprintf (p, "%*s ", inode_number_width, +- (f->stat.st_ino == NOT_AN_INODE_NUMBER +- ? "?" +- : umaxtostr (f->stat.st_ino, hbuf))); ++ format_inode (hbuf, sizeof hbuf, f)); + /* Increment by strlen (p) here, rather than by inode_number_width + 1. + The latter is wrong when inode_number_width is zero. */ + p += strlen (p); +@@ -4104,12 +4115,13 @@ print_file_name_and_frills (const struct + + if (print_inode) + printf ("%*s ", format == with_commas ? 0 : inode_number_width, +- umaxtostr (f->stat.st_ino, buf)); ++ format_inode (buf, sizeof buf, f)); + + if (print_block_size) + printf ("%*s ", format == with_commas ? 0 : block_size_width, +- human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, +- ST_NBLOCKSIZE, output_block_size)); ++ ! f->stat_ok ? "?" ++ : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ++ ST_NBLOCKSIZE, output_block_size)); + + size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), + f->linkok, f->stat_ok, f->filetype, +@@ -4320,9 +4332,10 @@ length_of_file_name_and_frills (const st + + if (print_block_size) + len += 1 + (format == with_commas +- ? strlen (human_readable (ST_NBLOCKS (f->stat), buf, +- human_output_opts, ST_NBLOCKSIZE, +- output_block_size)) ++ ? strlen (! f->stat_ok ? "?" ++ : human_readable (ST_NBLOCKS (f->stat), buf, ++ human_output_opts, ST_NBLOCKSIZE, ++ output_block_size)) + : block_size_width); + + quote_name (NULL, f->name, filename_quoting_options, &name_width); +diff -urNp coreutils-7.6-orig/tests/ls/dangle coreutils-7.6/tests/ls/dangle +--- coreutils-7.6-orig/tests/ls/dangle 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-7.6/tests/ls/dangle 2009-10-02 16:21:06.000000000 +0200 +@@ -26,6 +26,10 @@ fi + ln -s no-such-file dangle || framework_failure + mkdir -p dir/sub || framework_failure + ln -s dir slink-to-dir || framework_failure ++mkdir d || framework_failure ++ln -s no-such d/dangle || framework_failure ++printf '? dangle\n' > subdir_Li_exp || framework_failure ++printf 'total 0\n? dangle\n' > subdir_Ls_exp || framework_failure + + fail=0 + +@@ -50,4 +54,14 @@ EOF + + compare out exp || fail=1 + ++# Ensure that ls -Li prints "?" as the inode of a dangling symlink. ++rm -f out ++ls -Li d > out 2>/dev/null && fail=1 ++compare out subdir_Li_exp || fail=1 ++ ++# Ensure that ls -Ls prints "?" as the allocation of a dangling symlink. ++rm -f out ++ls -Ls d > out 2>/dev/null && fail=1 ++compare out subdir_Ls_exp || fail=1 ++ + Exit $fail +diff -urNp coreutils-7.6-orig/tests/ls/infloop coreutils-7.6/tests/ls/infloop +--- coreutils-7.6-orig/tests/ls/infloop 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-7.6/tests/ls/infloop 2009-10-02 16:12:11.000000000 +0200 +@@ -1,6 +1,7 @@ + #!/bin/sh + # show that the following no longer makes ls infloop + # mkdir loop; cd loop; ln -s ../loop sub; ls -RL ++# Also ensure ls exits with status = 2 in that case. + + # Copyright (C) 2001-2002, 2004, 2006-2009 Free Software Foundation, Inc. + +@@ -27,21 +28,22 @@ fi + mkdir loop || framework_failure + ln -s ../loop loop/sub || framework_failure + +-fail=0 +- +-ls -RL loop 2>err | head -n 7 > out +-# With an inf-looping ls, out will contain these 7 lines: +-cat < bad ++cat <<\EOF > exp-out || framework_failure + loop: + sub ++EOF + +-loop/sub: +-sub +- +-loop/sub/sub: ++cat <<\EOF > exp-err || framework_failure ++ls: loop/sub: not listing already-listed directory + EOF + +-# Make sure we don't get the "bad" output. +-compare out bad > /dev/null 2>&1 && fail=1 ++fail=0 ++ ++timeout 1 ls -RL loop 2>err > out ++# Ensure that ls exits with status 2 upon detecting a cycle ++test $? = 2 || fail=1 ++ ++compare err exp-err || fail=1 ++compare out exp-out || fail=1 + + Exit $fail + diff --git a/coreutils.spec b/coreutils.spec index 06648b5..1f5f464 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.6 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -20,6 +20,7 @@ Source203: coreutils-runuser-l.pamd # From upstream Patch1: coreutils-cpxattrreadonly.patch Patch2: coreutils-7.6-lzipcolor.patch +Patch3: coreutils-ls-inode.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -111,6 +112,7 @@ Libraries for coreutils package. # From upstream %patch1 -p1 -b .roxattr %patch2 -p1 -b .lzip +%patch3 -p1 -b .inode # Our patches %patch100 -p1 -b .configure @@ -254,15 +256,15 @@ rm -rf $RPM_BUILD_ROOT # coreutils.info. else their postun'll be run too late # and install-info will fail badly because of duplicates for file in sh-utils textutils fileutils; do - if [ -f %{_infodir}/$file.info ]; then - /sbin/install-info --delete %{_infodir}/$file.info --dir=%{_infodir}/dir &> /dev/null || : + if [ -f %{_infodir}/$file.info.gz ]; then + /sbin/install-info --delete %{_infodir}/$file.info.gz --dir=%{_infodir}/dir &> /dev/null || : fi done %preun if [ $1 = 0 ]; then - if [ -f %{_infodir}/%{name}.info ]; then - /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || : + if [ -f %{_infodir}/%{name}.info.gz ]; then + /sbin/install-info --delete %{_infodir}/%{name}.info.gz %{_infodir}/dir || : fi fi @@ -270,8 +272,8 @@ fi /bin/grep -v '(sh-utils)\|(fileutils)\|(textutils)' %{_infodir}/dir > \ %{_infodir}/dir.rpmmodify || exit 0 /bin/mv -f %{_infodir}/dir.rpmmodify %{_infodir}/dir -if [ -f %{_infodir}/%{name}.info ]; then - /sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || : +if [ -f %{_infodir}/%{name}.info.gz ]; then + /sbin/install-info %{_infodir}/%{name}.info.gz %{_infodir}/dir || : fi %files -f %{name}.lang @@ -329,6 +331,13 @@ fi %{_libdir}/coreutils %changelog +* Fri Oct 02 2009 Ondrej Vasik - 7.6-6 +- ls -LR exits with status 2, not 0, when it encounters + a cycle(#525402) +- ls: print "?", not "0" as inode of dereferenced dangling + symlink(#525400) +- call the install-info on .gz info files + * Tue Sep 22 2009 Ondrej Vasik - 7.6-5 - improve and correct runuser documentation (#524805) From e87ead322a3e91229d41a20e245d52dbab2ca029 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 2 Oct 2009 15:06:06 +0000 Subject: [PATCH 056/523] apply upstream patch #3 later to prevent fuzz --- coreutils.spec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 1f5f464..4eedeb4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -112,7 +112,6 @@ Libraries for coreutils package. # From upstream %patch1 -p1 -b .roxattr %patch2 -p1 -b .lzip -%patch3 -p1 -b .inode # Our patches %patch100 -p1 -b .configure @@ -140,6 +139,9 @@ Libraries for coreutils package. %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman +#apply upstream patch later to prevent defuzzing +%patch3 -p1 -b .inode + chmod a+x tests/misc/sort-mb-tests #fix typos/mistakes in localized documentation(#439410, #440056) From fa0337b2a5bbd73e618d098c678230adb7e2c16b Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 5 Oct 2009 07:06:38 +0000 Subject: [PATCH 057/523] chcon no longer aborts on a selinux disabled system(#527142) --- coreutils-selinux.patch | 11 +++++++++++ coreutils.spec | 6 +++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 233af56..162a87b 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -162,6 +162,17 @@ diff -urNp coreutils-7.1-orig/src/chcon.c coreutils-7.1/src/chcon.c With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ -h, --no-dereference affect symbolic links instead of any referenced file\n\ +@@ -519,6 +519,10 @@ main (int argc, char **argv) + usage (EXIT_FAILURE); + } + ++ if (is_selinux_enabled () != 1) ++ error (EXIT_FAILURE, 0, ++ _("%s may be used only on a SELinux kernel"), program_name); ++ + if (reference_file) + { + if (getfilecon (reference_file, &ref_context) < 0) diff -urNp coreutils-7.1-orig/src/id.c coreutils-7.1/src/id.c --- coreutils-7.1-orig/src/id.c 2009-02-16 15:57:44.000000000 +0100 +++ coreutils-7.1/src/id.c 2009-02-24 13:47:15.000000000 +0100 diff --git a/coreutils.spec b/coreutils.spec index 4eedeb4..4a5e061 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 7.6 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -333,6 +333,10 @@ fi %{_libdir}/coreutils %changelog +* Mon Oct 05 2009 Ondrej Vasik - 7.6-7 +- chcon no longer aborts on a selinux disabled system + (#527142) + * Fri Oct 02 2009 Ondrej Vasik - 7.6-6 - ls -LR exits with status 2, not 0, when it encounters a cycle(#525402) From 207519174ea785aa8d5977317836ca9f7a46816e Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 6 Oct 2009 13:43:25 +0000 Subject: [PATCH 058/523] New upstream release 8.0 (beta), defuzz patches, remove applied patches --- .cvsignore | 2 +- coreutils-5.2.1-runuser.patch | 8 +- coreutils-7.6-lzipcolor.patch | 11 --- coreutils-cpxattrreadonly.patch | 163 -------------------------------- coreutils-i18n.patch | 3 +- coreutils-ls-inode.patch | 161 ------------------------------- coreutils-pam.patch | 5 +- coreutils-selinux.patch | 4 +- coreutils.spec | 16 ++-- sources | 2 +- 10 files changed, 15 insertions(+), 360 deletions(-) delete mode 100644 coreutils-7.6-lzipcolor.patch delete mode 100644 coreutils-cpxattrreadonly.patch delete mode 100644 coreutils-ls-inode.patch diff --git a/.cvsignore b/.cvsignore index edb4b98..245b011 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-7.6.tar.xz +coreutils-8.0.tar.xz diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index 5600d2f..ce80533 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -105,18 +105,14 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c #if HAVE_PATHS_H # include -@@ -149,6 +155,10 @@ +@@ -149,11 +155,18 @@ #ifndef USE_PAM char *crypt (char const *key, char const *salt); #endif +#ifndef CHECKPASSWD +#define CHECKPASSWD 1 +#endif -+ - char *getusershell (void); - void endusershell (void); - void setusershell (void); -@@ -156,7 +166,11 @@ void setusershell (); + extern char **environ; static void run_shell (char const *, char const *, char **, size_t, diff --git a/coreutils-7.6-lzipcolor.patch b/coreutils-7.6-lzipcolor.patch deleted file mode 100644 index d27678b..0000000 --- a/coreutils-7.6-lzipcolor.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -urNp coreutils-7.6-orig/src/dircolors.hin coreutils-7.6/src/dircolors.hin ---- coreutils-7.6-orig/src/dircolors.hin 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-7.6/src/dircolors.hin 2009-09-21 08:00:38.000000000 +0200 -@@ -131,6 +131,7 @@ EXEC 01;32 - .cpio 01;31 - .7z 01;31 - .rz 01;31 -+.lz 01;31 - - # image formats - .jpg 01;35 diff --git a/coreutils-cpxattrreadonly.patch b/coreutils-cpxattrreadonly.patch deleted file mode 100644 index 2b28996..0000000 --- a/coreutils-cpxattrreadonly.patch +++ /dev/null @@ -1,163 +0,0 @@ -From cca83fafa69eb26db458714830b77498b88af8a4 Mon Sep 17 00:00:00 2001 -From: Ondřej Vašík -Date: Mon, 14 Sep 2009 13:12:01 +0000 -Subject: cp,mv: preserve extended attributes even for read-only files - -* src/copy.c (copy_reg): Temporarily set u+rw on the destination file -to allow GNU/Linux to set xattrs. -* tests/misc/xattr: Test that change. -Reported by Ernest N. Mamikonyan. ---- -diff --git a/src/copy.c b/src/copy.c -index f3ff5a2..ad2060b 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -834,6 +834,24 @@ copy_reg (char const *src_name, char const *dst_name, - } - } - -+ /* To allow copying xattrs on read-only files, temporarily chmod u+rw. -+ This workaround is required as an inode permission check is done -+ by xattr_permission() in fs/xattr.c of the GNU/Linux kernel tree. */ -+ if (x->preserve_xattr) -+ { -+ bool access_changed = false; -+ -+ if (!(sb.st_mode & S_IWUSR) && geteuid() != 0) -+ access_changed = fchmod_or_lchmod (dest_desc, dst_name, 0600) == 0; -+ -+ if (!copy_attr_by_fd (src_name, source_desc, dst_name, dest_desc, x) -+ && x->require_preserve_xattr) -+ return_val = false; -+ -+ if (access_changed) -+ fchmod_or_lchmod (dest_desc, dst_name, dst_mode & ~omitted_permissions); -+ } -+ - if (x->preserve_ownership && ! SAME_OWNER_AND_GROUP (*src_sb, sb)) - { - switch (set_owner (x, dst_name, dest_desc, src_sb, *new_dst, &sb)) -@@ -850,11 +868,6 @@ copy_reg (char const *src_name, char const *dst_name, - - set_author (dst_name, dest_desc, src_sb); - -- if (x->preserve_xattr && ! copy_attr_by_fd (src_name, source_desc, -- dst_name, dest_desc, x) -- && x->require_preserve_xattr) -- return_val = false; -- - if (x->preserve_mode || x->move_mode) - { - if (copy_acl (src_name, source_desc, dst_name, dest_desc, src_mode) != 0 -diff --git a/tests/misc/xattr b/tests/misc/xattr -index a27e1f6..fcf7ceb 100755 ---- a/tests/misc/xattr -+++ b/tests/misc/xattr -@@ -29,7 +29,7 @@ fi - - # Skip this test if cp was built without xattr support: - touch src dest || framework_failure --cp --preserve=xattr -n src dest 2>/dev/null \ -+cp --preserve=xattr -n src dest \ - || skip_test_ "coreutils built without xattr support" - - # this code was taken from test mv/backup-is-src -@@ -46,13 +46,13 @@ xattr_pair="$xattr_name=\"$xattr_value\"" - # create new file and check its xattrs - touch a || framework_failure - getfattr -d a >out_a || skip_test_ "failed to get xattr of file" --grep -F "$xattr_pair" out_a >/dev/null && framework_failure -+grep -F "$xattr_pair" out_a && framework_failure - - # try to set user xattr on file - setfattr -n "$xattr_name" -v "$xattr_value" a >out_a \ - || skip_test_ "failed to set xattr of file" - getfattr -d a >out_a || skip_test_ "failed to get xattr of file" --grep -F "$xattr_pair" out_a >/dev/null \ -+grep -F "$xattr_pair" out_a \ - || skip_test_ "failed to set xattr of file" - - fail=0 -@@ -60,36 +60,50 @@ fail=0 - # cp should not preserve xattr by default - cp a b || fail=1 - getfattr -d b >out_b || skip_test_ "failed to get xattr of file" --grep -F "$xattr_pair" out_b >/dev/null && fail=1 -+grep -F "$xattr_pair" out_b && fail=1 - - # test if --preserve=xattr option works - cp --preserve=xattr a b || fail=1 - getfattr -d b >out_b || skip_test_ "failed to get xattr of file" --grep -F "$xattr_pair" out_b >/dev/null || fail=1 -+grep -F "$xattr_pair" out_b || fail=1 - - #test if --preserve=all option works - cp --preserve=all a c || fail=1 - getfattr -d c >out_c || skip_test_ "failed to get xattr of file" --grep -F "$xattr_pair" out_c >/dev/null || fail=1 -+grep -F "$xattr_pair" out_c || fail=1 - - #test if -a option works without any diagnostics - cp -a a d 2>err && test -s err && fail=1 - getfattr -d d >out_d || skip_test_ "failed to get xattr of file" --grep -F "$xattr_pair" out_d >/dev/null || fail=1 -+grep -F "$xattr_pair" out_d || fail=1 -+ -+#test if --preserve=xattr works even for files without write access -+chmod a-w a || framework_failure -+rm -f e -+cp --preserve=xattr a e || fail=1 -+getfattr -d e >out_e || skip_test_ "failed to get xattr of file" -+grep -F "$xattr_pair" out_e || fail=1 -+ -+#Ensure that permission bits are preserved, too. -+src_perm=$(stat --format=%a a) -+dst_perm=$(stat --format=%a e) -+test "$dst_perm" = "$src_perm" || fail=1 -+ -+chmod u+w a || framework_failure - - rm b || framework_failure - - # install should never preserve xattr - ginstall a b || fail=1 - getfattr -d b >out_b || skip_test_ "failed to get xattr of file" --grep -F "$xattr_pair" out_b >/dev/null && fail=1 -+grep -F "$xattr_pair" out_b && fail=1 - - # mv should preserve xattr when renaming within a file system. - # This is implicitly done by rename () and doesn't need explicit - # xattr support in mv. - mv a b || fail=1 - getfattr -d b >out_b || skip_test_ "failed to get xattr of file" --grep -F "$xattr_pair" out_b >/dev/null || cat >&2 <&2 <out_a 2>/dev/null \ -+setfattr -n "$xattr_name" -v "$xattr_value" "$b_other" >out_a \ - || test_mv=0 --getfattr -d "$b_other" >out_b 2>/dev/null || test_mv=0 --grep -F "$xattr_pair" out_b >/dev/null || test_mv=0 -+getfattr -d "$b_other" >out_b || test_mv=0 -+grep -F "$xattr_pair" out_b || test_mv=0 - rm -f "$b_other" || framework_failure - - if test $test_mv -eq 1; then - # mv should preserve xattr when copying content from one partition to another - mv b "$b_other" || fail=1 -- getfattr -d "$b_other" >out_b 2>/dev/null || -+ getfattr -d "$b_other" >out_b || - skip_test_ "failed to get xattr of file" -- grep -F "$xattr_pair" out_b >/dev/null || fail=1 -+ grep -F "$xattr_pair" out_b || fail=1 - else - cat >&2 < #include @@ -362,6 +362,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am + #include "system.h" #include "error.h" + #include "hard-locale.h" #include "linebuffer.h" -#include "memcasecmp.h" #include "quote.h" diff --git a/coreutils-ls-inode.patch b/coreutils-ls-inode.patch deleted file mode 100644 index fa52a67..0000000 --- a/coreutils-ls-inode.patch +++ /dev/null @@ -1,161 +0,0 @@ -diff -urNp coreutils-7.6-orig/doc/coreutils.texi coreutils-7.6/doc/coreutils.texi ---- coreutils-7.6-orig/doc/coreutils.texi 2009-09-22 15:12:55.000000000 +0200 -+++ coreutils-7.6/doc/coreutils.texi 2009-10-02 16:09:57.000000000 +0200 -@@ -6114,7 +6114,8 @@ Exit status: - specified as a command line argument. This happens when listing a - directory in which entries are actively being removed or renamed.) - 2 serious trouble (e.g., memory exhausted, invalid option or failure -- to access file or directory specified as a command line argument) -+ to access file or directory specified as a command line argument -+ or a directory loop) - @end display - - Also see @ref{Common options}. - -diff -urNp coreutils-7.6-orig/src/ls.c coreutils-7.6/src/ls.c ---- coreutils-7.6-orig/src/ls.c 2009-09-22 15:12:55.000000000 +0200 -+++ coreutils-7.6/src/ls.c 2009-10-02 16:19:54.000000000 +0200 -@@ -2494,6 +2494,7 @@ print_dir (char const *name, char const - error (0, 0, _("%s: not listing already-listed directory"), - quotearg_colon (name)); - closedir (dirp); -+ set_exit_status (true); - return; - } - -@@ -3582,6 +3583,18 @@ format_user_width (uid_t u) - return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u); - } - -+/* Return a pointer to a formatted version of F->stat.st_ino, -+ possibly using buffer, BUF, of length BUFLEN, which must be at least -+ INT_BUFSIZE_BOUND (uintmax_t) bytes. */ -+static char * -+format_inode (char *buf, size_t buflen, const struct fileinfo *f) -+{ -+ assert (INT_BUFSIZE_BOUND (uintmax_t) <= buflen); -+ return (f->stat_ok && f->stat.st_ino != NOT_AN_INODE_NUMBER -+ ? umaxtostr (f->stat.st_ino, buf) -+ : (char *) "?"); -+} -+ - /* Likewise, for groups. */ - - static int -@@ -3712,9 +3725,7 @@ print_long_format (const struct fileinfo - { - char hbuf[INT_BUFSIZE_BOUND (uintmax_t)]; - sprintf (p, "%*s ", inode_number_width, -- (f->stat.st_ino == NOT_AN_INODE_NUMBER -- ? "?" -- : umaxtostr (f->stat.st_ino, hbuf))); -+ format_inode (hbuf, sizeof hbuf, f)); - /* Increment by strlen (p) here, rather than by inode_number_width + 1. - The latter is wrong when inode_number_width is zero. */ - p += strlen (p); -@@ -4104,12 +4115,13 @@ print_file_name_and_frills (const struct - - if (print_inode) - printf ("%*s ", format == with_commas ? 0 : inode_number_width, -- umaxtostr (f->stat.st_ino, buf)); -+ format_inode (buf, sizeof buf, f)); - - if (print_block_size) - printf ("%*s ", format == with_commas ? 0 : block_size_width, -- human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, -- ST_NBLOCKSIZE, output_block_size)); -+ ! f->stat_ok ? "?" -+ : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, -+ ST_NBLOCKSIZE, output_block_size)); - - size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), - f->linkok, f->stat_ok, f->filetype, -@@ -4320,9 +4332,10 @@ length_of_file_name_and_frills (const st - - if (print_block_size) - len += 1 + (format == with_commas -- ? strlen (human_readable (ST_NBLOCKS (f->stat), buf, -- human_output_opts, ST_NBLOCKSIZE, -- output_block_size)) -+ ? strlen (! f->stat_ok ? "?" -+ : human_readable (ST_NBLOCKS (f->stat), buf, -+ human_output_opts, ST_NBLOCKSIZE, -+ output_block_size)) - : block_size_width); - - quote_name (NULL, f->name, filename_quoting_options, &name_width); -diff -urNp coreutils-7.6-orig/tests/ls/dangle coreutils-7.6/tests/ls/dangle ---- coreutils-7.6-orig/tests/ls/dangle 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-7.6/tests/ls/dangle 2009-10-02 16:21:06.000000000 +0200 -@@ -26,6 +26,10 @@ fi - ln -s no-such-file dangle || framework_failure - mkdir -p dir/sub || framework_failure - ln -s dir slink-to-dir || framework_failure -+mkdir d || framework_failure -+ln -s no-such d/dangle || framework_failure -+printf '? dangle\n' > subdir_Li_exp || framework_failure -+printf 'total 0\n? dangle\n' > subdir_Ls_exp || framework_failure - - fail=0 - -@@ -50,4 +54,14 @@ EOF - - compare out exp || fail=1 - -+# Ensure that ls -Li prints "?" as the inode of a dangling symlink. -+rm -f out -+ls -Li d > out 2>/dev/null && fail=1 -+compare out subdir_Li_exp || fail=1 -+ -+# Ensure that ls -Ls prints "?" as the allocation of a dangling symlink. -+rm -f out -+ls -Ls d > out 2>/dev/null && fail=1 -+compare out subdir_Ls_exp || fail=1 -+ - Exit $fail -diff -urNp coreutils-7.6-orig/tests/ls/infloop coreutils-7.6/tests/ls/infloop ---- coreutils-7.6-orig/tests/ls/infloop 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-7.6/tests/ls/infloop 2009-10-02 16:12:11.000000000 +0200 -@@ -1,6 +1,7 @@ - #!/bin/sh - # show that the following no longer makes ls infloop - # mkdir loop; cd loop; ln -s ../loop sub; ls -RL -+# Also ensure ls exits with status = 2 in that case. - - # Copyright (C) 2001-2002, 2004, 2006-2009 Free Software Foundation, Inc. - -@@ -27,21 +28,22 @@ fi - mkdir loop || framework_failure - ln -s ../loop loop/sub || framework_failure - --fail=0 -- --ls -RL loop 2>err | head -n 7 > out --# With an inf-looping ls, out will contain these 7 lines: --cat < bad -+cat <<\EOF > exp-out || framework_failure - loop: - sub -+EOF - --loop/sub: --sub -- --loop/sub/sub: -+cat <<\EOF > exp-err || framework_failure -+ls: loop/sub: not listing already-listed directory - EOF - --# Make sure we don't get the "bad" output. --compare out bad > /dev/null 2>&1 && fail=1 -+fail=0 -+ -+timeout 1 ls -RL loop 2>err > out -+# Ensure that ls exits with status 2 upon detecting a cycle -+test $? = 2 || fail=1 -+ -+compare err exp-err || fail=1 -+compare out exp-out || fail=1 - - Exit $fail - diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 4881c7c..3bfb9d3 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -44,16 +44,13 @@ #include "system.h" #include "getpass.h" -@@ -128,15 +147,22 @@ +@@ -128,12 +147,19 @@ /* The user to become if none is specified. */ #define DEFAULT_USER "root" +#ifndef USE_PAM char *crypt (char const *key, char const *salt); +#endif - char *getusershell (void); - void endusershell (void); - void setusershell (void); extern char **environ; diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 162a87b..c646812 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -557,8 +557,8 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c + DIRED_INDENT (); -- if (print_owner | print_group | print_author | print_scontext) -+ if (print_owner | print_group | print_author) +- if (print_owner || print_group || print_author || print_scontext) ++ if (print_owner || print_group || print_author) { DIRED_FPUTS (buf, stdout, p - buf); diff --git a/coreutils.spec b/coreutils.spec index 4a5e061..9af4d8a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 7.6 -Release: 7%{?dist} +Version: 8.0 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,9 +18,6 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -Patch1: coreutils-cpxattrreadonly.patch -Patch2: coreutils-7.6-lzipcolor.patch -Patch3: coreutils-ls-inode.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -110,8 +107,6 @@ Libraries for coreutils package. %setup -q # From upstream -%patch1 -p1 -b .roxattr -%patch2 -p1 -b .lzip # Our patches %patch100 -p1 -b .configure @@ -139,9 +134,6 @@ Libraries for coreutils package. %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -#apply upstream patch later to prevent defuzzing -%patch3 -p1 -b .inode - chmod a+x tests/misc/sort-mb-tests #fix typos/mistakes in localized documentation(#439410, #440056) @@ -333,6 +325,10 @@ fi %{_libdir}/coreutils %changelog +* Wed Oct 07 2009 Ondrej Vasik - 8.0-1 +- New upstream release 8.0 (beta), defuzz patches, + remove applied patches + * Mon Oct 05 2009 Ondrej Vasik - 7.6-7 - chcon no longer aborts on a selinux disabled system (#527142) diff --git a/sources b/sources index 2cffc5b..e831813 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -a9fb9368e40205d70fc37b9fe441e8ec coreutils-7.6.tar.xz +fe3bb9376150acb5af4a2a280d6fd91a coreutils-8.0.tar.xz From f8d3fd6d8e7125edf479882fc56c988ec4d837c3 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 7 Oct 2009 08:11:44 +0000 Subject: [PATCH 059/523] defuzz patches --- coreutils-i18n.patch | 15782 +++++++++++++++++++++++++++++----- coreutils-pam.patch | 17479 +++++++++++++++++++++++++++++++++++++- coreutils-selinux.patch | 11953 +++++++++++++++++++++++++- coreutils.spec | 2 +- 4 files changed, 42806 insertions(+), 2410 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index f419eaa..2d56736 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,140 +1,7 @@ -diff -urN coreutils-6.12-orig/tests/misc/cut coreutils-6.12/tests/misc/cut ---- coreutils-6.12-orig/tests/misc/cut 2008-05-17 08:41:11.000000000 +0200 -+++ coreutils-6.12/tests/misc/cut 2008-06-02 11:13:08.000000000 +0200 -@@ -26,7 +26,7 @@ - my $prog = 'cut'; - my $try = "Try \`$prog --help' for more information.\n"; - my $from_1 = "$prog: fields and positions are numbered from 1\n$try"; --my $inval = "$prog: invalid byte or field list\n$try"; -+my $inval = "$prog: invalid byte, character or field list\n$try"; - my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; - - my @Tests = -@@ -140,8 +140,8 @@ - ['od-overlap5', '-b1-3,1-4', '--output-d=:', {IN=>"abcde\n"}, {OUT=>"abcd\n"}], - - # None of the following invalid ranges provoked an error up to coreutils-6.9. -- ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, -- {ERR=>"$prog: invalid decreasing range\n$try"}], -+ ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, -+ {ERR=>"$prog: invalid byte, character or field list\n$try"}], - ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], - ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], - ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ---- /dev/null 2007-03-01 09:16:39.219409909 +0000 -+++ coreutils-6.8+/tests/misc/sort-mb-tests 2007-03-01 15:08:24.000000000 +0000 -@@ -0,0 +1,58 @@ -+#! /bin/sh -+case $# in -+ 0) xx='../src/sort';; -+ *) xx="$1";; -+esac -+test "$VERBOSE" && echo=echo || echo=: -+$echo testing program: $xx -+errors=0 -+test "$srcdir" || srcdir=. -+test "$VERBOSE" && $xx --version 2> /dev/null -+ -+export LC_ALL=en_US.UTF-8 -+locale -k LC_CTYPE 2>&1 | grep -q charmap.*UTF-8 || exit 77 -+errors=0 -+ -+$xx -t @ -k2 -n misc/mb1.I > misc/mb1.O -+code=$? -+if test $code != 0; then -+ $echo "Test mb1 failed: $xx return code $code differs from expected value 0" 1>&2 -+ errors=`expr $errors + 1` -+else -+ cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1 -+ case $? in -+ 0) if test "$VERBOSE"; then $echo "passed mb1"; fi;; -+ 1) $echo "Test mb1 failed: files misc/mb1.O and $srcdir/misc/mb1.X differ" 1>&2 -+ (diff -c misc/mb1.O $srcdir/misc/mb1.X) 2> /dev/null -+ errors=`expr $errors + 1`;; -+ 2) $echo "Test mb1 may have failed." 1>&2 -+ $echo The command "cmp misc/mb1.O $srcdir/misc/mb1.X" failed. 1>&2 -+ errors=`expr $errors + 1`;; -+ esac -+fi -+ -+$xx -t @ -k4 -n misc/mb2.I > misc/mb2.O -+code=$? -+if test $code != 0; then -+ $echo "Test mb2 failed: $xx return code $code differs from expected value 0" 1>&2 -+ errors=`expr $errors + 1` -+else -+ cmp misc/mb2.O $srcdir/misc/mb2.X > /dev/null 2>&1 -+ case $? in -+ 0) if test "$VERBOSE"; then $echo "passed mb2"; fi;; -+ 1) $echo "Test mb2 failed: files misc/mb2.O and $srcdir/misc/mb2.X differ" 1>&2 -+ (diff -c misc/mb2.O $srcdir/misc/mb2.X) 2> /dev/null -+ errors=`expr $errors + 1`;; -+ 2) $echo "Test mb2 may have failed." 1>&2 -+ $echo The command "cmp misc/mb2.O $srcdir/misc/mb2.X" failed. 1>&2 -+ errors=`expr $errors + 1`;; -+ esac -+fi -+ -+if test $errors = 0; then -+ $echo Passed all 113 tests. 1>&2 -+else -+ $echo Failed $errors tests. 1>&2 -+fi -+test $errors = 0 || errors=1 -+exit $errors ---- /dev/null 2007-03-01 09:16:39.219409909 +0000 -+++ coreutils-6.8+/tests/misc/mb2.I 2007-03-01 15:08:24.000000000 +0000 -@@ -0,0 +1,4 @@ -+Apple@AA10@@20 -+Banana@AA5@@30 -+Citrus@AA20@@5 -+Cherry@AA30@@10 ---- /dev/null 2007-03-01 09:16:39.219409909 +0000 -+++ coreutils-6.8+/tests/misc/mb2.X 2007-03-01 15:08:24.000000000 +0000 -@@ -0,0 +1,4 @@ -+Citrus@AA20@@5 -+Cherry@AA30@@10 -+Apple@AA10@@20 -+Banana@AA5@@30 ---- /dev/null 2007-03-01 09:16:39.219409909 +0000 -+++ coreutils-6.8+/tests/misc/mb1.I 2007-03-01 15:08:24.000000000 +0000 -@@ -0,0 +1,4 @@ -+Apple@10 -+Banana@5 -+Citrus@20 -+Cherry@30 ---- /dev/null 2007-03-01 09:16:39.219409909 +0000 -+++ coreutils-6.8+/tests/misc/mb1.X 2007-03-01 15:08:24.000000000 +0000 -@@ -0,0 +1,4 @@ -+Banana@5 -+Apple@10 -+Citrus@20 -+Cherry@30 -diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am ---- coreutils-6.12-orig/tests/Makefile.am 2008-05-27 13:47:53.000000000 +0200 -+++ coreutils-6.12/tests/Makefile.am 2008-06-02 10:06:03.000000000 +0200 -@@ -192,6 +192,7 @@ - misc/sort-compress \ - misc/sort-continue \ - misc/sort-files0-from \ -+ misc/sort-mb-tests \ - misc/sort-merge \ - misc/sort-merge-fdlimit \ - misc/sort-rand \ -@@ -391,6 +392,10 @@ - $(root_tests) - - pr_data = \ -+ misc/mb1.X \ -+ misc/mb1.I \ -+ misc/mb2.X \ -+ misc/mb2.I \ - pr/0F \ - pr/0FF \ - pr/0FFnt \ ---- coreutils-6.8+/lib/linebuffer.h.i18n 2005-05-14 07:44:24.000000000 +0100 -+++ coreutils-6.8+/lib/linebuffer.h 2007-03-01 15:08:24.000000000 +0000 -@@ -22,6 +22,11 @@ +diff -urNp coreutils-8.0-orig/lib/linebuffer.h coreutils-8.0/lib/linebuffer.h +--- coreutils-8.0-orig/lib/linebuffer.h 2009-10-06 10:59:48.000000000 +0200 ++++ coreutils-8.0/lib/linebuffer.h 2009-10-07 10:07:16.000000000 +0200 +@@ -21,6 +21,11 @@ # include @@ -146,7 +13,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am /* A `struct linebuffer' holds a line of text. */ struct linebuffer -@@ -29,6 +34,9 @@ +@@ -28,6 +33,9 @@ struct linebuffer size_t size; /* Allocated. */ size_t length; /* Used. */ char *buffer; @@ -156,9 +23,1557 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am }; /* Initialize linebuffer LINEBUFFER for use. */ ---- coreutils-6.8+/src/expand.c.i18n 2007-01-14 15:41:28.000000000 +0000 -+++ coreutils-6.8+/src/expand.c 2007-03-01 15:08:24.000000000 +0000 -@@ -38,11 +38,28 @@ +diff -urNp coreutils-8.0-orig/lib/linebuffer.h.orig coreutils-8.0/lib/linebuffer.h.orig +--- coreutils-8.0-orig/lib/linebuffer.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/lib/linebuffer.h.orig 2009-10-06 10:59:48.000000000 +0200 +@@ -0,0 +1,53 @@ ++/* linebuffer.h -- declarations for reading arbitrarily long lines ++ ++ Copyright (C) 1986, 1991, 1998, 1999, 2002, 2003, 2007 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 . */ ++ ++#if !defined LINEBUFFER_H ++# define LINEBUFFER_H ++ ++# include ++ ++/* A `struct linebuffer' holds a line of text. */ ++ ++struct linebuffer ++{ ++ size_t size; /* Allocated. */ ++ size_t length; /* Used. */ ++ char *buffer; ++}; ++ ++/* Initialize linebuffer LINEBUFFER for use. */ ++void initbuffer (struct linebuffer *linebuffer); ++ ++/* Read an arbitrarily long line of text from STREAM into LINEBUFFER. ++ Consider lines to be terminated by DELIMITER. ++ Keep the delimiter; append DELIMITER if we reach EOF and it wasn't ++ the last character in the file. Do not NUL-terminate. ++ Return LINEBUFFER, except at end of file return NULL. */ ++struct linebuffer *readlinebuffer_delim (struct linebuffer *linebuffer, ++ FILE *stream, char delimiter); ++ ++/* Read an arbitrarily long line of text from STREAM into LINEBUFFER. ++ Keep the newline; append a newline if it's the last line of a file ++ that ends in a non-newline character. Do not NUL-terminate. ++ Return LINEBUFFER, except at end of file return NULL. */ ++struct linebuffer *readlinebuffer (struct linebuffer *linebuffer, FILE *stream); ++ ++/* Free linebuffer LINEBUFFER and its data, all allocated with malloc. */ ++void freebuffer (struct linebuffer *); ++ ++#endif /* LINEBUFFER_H */ +diff -urNp coreutils-8.0-orig/src/cut.c coreutils-8.0/src/cut.c +--- coreutils-8.0-orig/src/cut.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/cut.c 2009-10-07 10:07:16.000000000 +0200 +@@ -28,6 +28,11 @@ + #include + #include + #include ++ ++/* Get mbstate_t, mbrtowc(). */ ++#if HAVE_WCHAR_H ++# include ++#endif + #include "system.h" + + #include "error.h" +@@ -36,6 +41,18 @@ + #include "quote.h" + #include "xstrndup.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" + +@@ -71,6 +88,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 1. Otherwise 0. */ ++#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 = 0; \ ++ 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 througn. */ \ ++ \ ++ case 0: \ ++ MBLENGTH = 1; \ ++ break; \ ++ } \ ++ } \ ++ while (0) ++ + struct range_pair + { + size_t lo; +@@ -89,7 +152,7 @@ static char *field_1_buffer; + /* The number of bytes allocated for FIELD_1_BUFFER. */ + static size_t field_1_bufsize; + +-/* The largest field or byte index used as an endpoint of a closed ++/* The largest byte, character or field index used as an endpoint of a closed + or degenerate range specification; this doesn't include the starting + index of right-open-ended ranges. For example, with either range spec + `2-5,9-', `2-3,5,9-' this variable would be set to 5. */ +@@ -101,10 +164,11 @@ static size_t eol_range_start; + + /* This is a bit vector. + In byte mode, which bytes to output. ++ In character mode, which characters to output. + In field mode, which DELIM-separated fields to output. +- Both bytes and fields are numbered starting with 1, ++ Bytes, characters and fields are numbered starting with 1, + so the zeroth bit of this array is unused. +- A field or byte K has been selected if ++ A byte, character or field K has been selected if + (K <= MAX_RANGE_ENDPOINT and is_printable_field(K)) + || (EOL_RANGE_START > 0 && K >= EOL_RANGE_START). */ + static unsigned char *printable_field; +@@ -113,15 +177,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 delimeter-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 delimeter characters. + Otherwise, all such lines are printed. This option is valid only + with field mode. */ +@@ -133,6 +207,9 @@ static bool complement; + + /* The delimeter character for field mode. */ + static unsigned char delim; ++#if HAVE_WCHAR_H ++static wchar_t wcdelim; ++#endif + + /* True if the --output-delimiter=STRING option was specified. */ + static bool output_delimiter_specified; +@@ -206,7 +283,7 @@ Mandatory arguments to long options are + -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\ +@@ -365,7 +442,7 @@ set_fields (const char *fieldstr) + in_digits = false; + /* Starting a range. */ + if (dash_found) +- FATAL_ERROR (_("invalid byte or field list")); ++ FATAL_ERROR (_("invalid byte, character or field list")); + dash_found = true; + fieldstr++; + +@@ -389,14 +466,16 @@ set_fields (const char *fieldstr) + if (!rhs_specified) + { + /* `n-'. From `initial' to end of line. */ +- eol_range_start = initial; ++ if (eol_range_start == 0 || ++ (eol_range_start != 0 && eol_range_start > initial)) ++ eol_range_start = initial; + field_found = true; + } + else + { + /* `m-n' or `-n' (1-n). */ + if (value < initial) +- FATAL_ERROR (_("invalid decreasing range")); ++ FATAL_ERROR (_("invalid byte, character or field list")); + + /* Is there already a range going to end of line? */ + if (eol_range_start != 0) +@@ -476,6 +555,9 @@ set_fields (const char *fieldstr) + if (operating_mode == byte_mode) + error (0, 0, + _("byte offset %s is too large"), quote (bad_num)); ++ else if (operating_mode == character_mode) ++ error (0, 0, ++ _("character offset %s is too large"), quote (bad_num)); + else + error (0, 0, + _("field number %s is too large"), quote (bad_num)); +@@ -486,7 +568,7 @@ set_fields (const char *fieldstr) + fieldstr++; + } + else +- FATAL_ERROR (_("invalid byte or field list")); ++ FATAL_ERROR (_("invalid byte, character or field list")); + } + + max_range_endpoint = 0; +@@ -579,6 +661,63 @@ 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) ++{ ++ int 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. */ ++ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ ++ idx = 0; ++ buflen = 0; ++ bufpos = buf; ++ memset (&state, '\0', sizeof(mbstate_t)); ++ ++ while (1) ++ { ++ REFILL_BUFFER (buf, bufpos, buflen, stream); ++ ++ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); ++ ++ if (wc == WEOF) ++ { ++ if (idx > 0) ++ putchar ('\n'); ++ break; ++ } ++ else if (wc == L'\n') ++ { ++ putchar ('\n'); ++ idx = 0; ++ } ++ else ++ { ++ idx += (operating_mode == byte_mode) ? mblength : 1; ++ if (print_kth (idx, NULL)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ } ++ ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++} ++#endif ++ + /* Read from stream STREAM, printing to standard output any selected fields. */ + + static void +@@ -701,13 +840,192 @@ cut_fields (FILE *stream) + } + } + ++#if HAVE_MBRTOWC ++static void ++cut_fields_mb (FILE *stream) ++{ ++ int c; ++ unsigned int 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. */ ++ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ ++ 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); ++ 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, NULL)); ++ ++ 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 == L'\n' || wc == wcdelim)) ++ break; ++ } ++ ++ if (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 != L'\n')) ++ putchar ('\n'); ++ } ++ continue; ++ } ++ ++ if (print_kth (1, NULL)) ++ { ++ /* Print the field, but not the trailing delimiter. */ ++ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); ++ found_any_selected_field = 1; ++ } ++ ++field_idx; ++ } ++ ++ if (wc != WEOF) ++ { ++ if (print_kth (field_idx, NULL)) ++ { ++ 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 == L'\n')) ++ { ++ buflen -= mblength; ++ bufpos += mblength; ++ break; ++ } ++ ++ if (print_kth (field_idx, NULL)) ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ ++ buflen -= mblength; ++ bufpos += mblength; ++ } ++ } ++ ++ if ((!convfail || wc == L'\n') && buflen < 1) ++ wc = WEOF; ++ ++ if (!convfail && wc == wcdelim) ++ ++field_idx; ++ else if (wc == WEOF || (!convfail && wc == L'\n')) ++ { ++ if (found_any_selected_field ++ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) ++ putchar ('\n'); ++ if (wc == WEOF) ++ break; ++ field_idx = 1; ++ 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: ++ 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. +@@ -757,6 +1075,8 @@ main (int argc, char **argv) + bool ok; + bool delim_specified = false; + char *spec_list_string IF_LINT(= NULL); ++ char mbdelim[MB_LEN_MAX + 1]; ++ size_t delimlen = 0; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -779,7 +1099,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")); +@@ -787,6 +1106,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) +@@ -798,10 +1125,35 @@ 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); ++ } ++ } ++ ++ 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: +@@ -814,6 +1166,7 @@ main (int argc, char **argv) + break; + + case 'n': ++ byte_mode_character_aware = 1; + break; + + case 's': +@@ -836,7 +1189,7 @@ main (int argc, char **argv) + if (operating_mode == undefined_mode) + FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); + +- if (delim != '\0' && operating_mode != field_mode) ++ if (delim_specified && operating_mode != field_mode) + FATAL_ERROR (_("an input delimiter may be specified only\ + when operating on fields")); + +@@ -863,15 +1216,34 @@ main (int argc, char **argv) + } + + 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) +diff -urNp coreutils-8.0-orig/src/cut.c.orig coreutils-8.0/src/cut.c.orig +--- coreutils-8.0-orig/src/cut.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/cut.c.orig 2009-09-23 10:25:44.000000000 +0200 +@@ -0,0 +1,893 @@ ++/* cut - remove parts of lines of files ++ Copyright (C) 1997-2009 Free Software Foundation, Inc. ++ Copyright (C) 1984 David M. Ihnat ++ ++ 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 David Ihnat. */ ++ ++/* POSIX changes, bug fixes, long-named options, and cleanup ++ by David MacKenzie . ++ ++ Rewrite cut_fields and cut_bytes -- Jim Meyering. */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include "system.h" ++ ++#include "error.h" ++#include "getndelim2.h" ++#include "hash.h" ++#include "quote.h" ++#include "xstrndup.h" ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "cut" ++ ++#define AUTHORS \ ++ proper_name ("David M. Ihnat"), \ ++ proper_name ("David MacKenzie"), \ ++ proper_name ("Jim Meyering") ++ ++#define FATAL_ERROR(Message) \ ++ do \ ++ { \ ++ error (0, 0, (Message)); \ ++ usage (EXIT_FAILURE); \ ++ } \ ++ while (0) ++ ++/* Append LOW, HIGH to the list RP of range pairs, allocating additional ++ space if necessary. Update local variable N_RP. When allocating, ++ update global variable N_RP_ALLOCATED. */ ++ ++#define ADD_RANGE_PAIR(rp, low, high) \ ++ do \ ++ { \ ++ if (low == 0 || high == 0) \ ++ FATAL_ERROR (_("fields and positions are numbered from 1")); \ ++ if (n_rp >= n_rp_allocated) \ ++ { \ ++ (rp) = X2NREALLOC (rp, &n_rp_allocated); \ ++ } \ ++ rp[n_rp].lo = (low); \ ++ rp[n_rp].hi = (high); \ ++ ++n_rp; \ ++ } \ ++ while (0) ++ ++struct range_pair ++ { ++ size_t lo; ++ size_t hi; ++ }; ++ ++/* 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 ++ first field must be read into this buffer to determine whether it ++ is followed by a delimiter or a newline before any of it may be ++ output. Otherwise, cut_fields can do the job without using this ++ buffer. */ ++static char *field_1_buffer; ++ ++/* The number of bytes allocated for FIELD_1_BUFFER. */ ++static size_t field_1_bufsize; ++ ++/* The largest field or byte index used as an endpoint of a closed ++ or degenerate range specification; this doesn't include the starting ++ index of right-open-ended ranges. For example, with either range spec ++ `2-5,9-', `2-3,5,9-' this variable would be set to 5. */ ++static size_t max_range_endpoint; ++ ++/* If nonzero, this is the index of the first field in a range that goes ++ to end of line. */ ++static size_t eol_range_start; ++ ++/* This is a bit vector. ++ In byte mode, which bytes to output. ++ In field mode, which DELIM-separated fields to output. ++ Both bytes and fields are numbered starting with 1, ++ so the zeroth bit of this array is unused. ++ A field or byte K has been selected if ++ (K <= MAX_RANGE_ENDPOINT and is_printable_field(K)) ++ || (EOL_RANGE_START > 0 && K >= EOL_RANGE_START). */ ++static unsigned char *printable_field; ++ ++enum operating_mode ++ { ++ undefined_mode, ++ ++ /* Output characters that are in the given bytes. */ ++ byte_mode, ++ ++ /* Output the given delimeter-separated fields. */ ++ field_mode ++ }; ++ ++static enum operating_mode operating_mode; ++ ++/* If true do not output lines containing no delimeter characters. ++ Otherwise, all such lines are printed. This option is valid only ++ with field mode. */ ++static bool suppress_non_delimited; ++ ++/* If nonzero, print all bytes, characters, or fields _except_ ++ those that were specified. */ ++static bool complement; ++ ++/* The delimeter character for field mode. */ ++static unsigned char delim; ++ ++/* True if the --output-delimiter=STRING option was specified. */ ++static bool output_delimiter_specified; ++ ++/* The length of output_delimiter_string. */ ++static size_t output_delimiter_length; ++ ++/* The output field separator string. Defaults to the 1-character ++ string consisting of the input delimiter. */ ++static char *output_delimiter_string; ++ ++/* True if we have ever read standard input. */ ++static bool have_read_stdin; ++ ++#define HT_RANGE_START_INDEX_INITIAL_CAPACITY 31 ++ ++/* The set of range-start indices. For example, given a range-spec list like ++ `-b1,3-5,4-9,15-', the following indices will be recorded here: 1, 3, 15. ++ Note that although `4' looks like a range-start index, it is in the middle ++ of the `3-5' range, so it doesn't count. ++ This table is created/used IFF output_delimiter_specified is set. */ ++static Hash_table *range_start_ht; ++ ++/* For long options that have no equivalent short option, use a ++ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ ++enum ++{ ++ OUTPUT_DELIMITER_OPTION = CHAR_MAX + 1, ++ COMPLEMENT_OPTION ++}; ++ ++static struct option const longopts[] = ++{ ++ {"bytes", required_argument, NULL, 'b'}, ++ {"characters", required_argument, NULL, 'c'}, ++ {"fields", required_argument, NULL, 'f'}, ++ {"delimiter", required_argument, NULL, 'd'}, ++ {"only-delimited", no_argument, NULL, 's'}, ++ {"output-delimiter", required_argument, NULL, OUTPUT_DELIMITER_OPTION}, ++ {"complement", no_argument, NULL, COMPLEMENT_OPTION}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s OPTION... [FILE]...\n\ ++"), ++ program_name); ++ fputs (_("\ ++Print selected parts of lines from each FILE to standard output.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ -b, --bytes=LIST select only these bytes\n\ ++ -c, --characters=LIST select only these characters\n\ ++ -d, --delimiter=DELIM use DELIM instead of TAB for field delimiter\n\ ++"), stdout); ++ fputs (_("\ ++ -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\ ++"), stdout); ++ fputs (_("\ ++ --complement complement the set of selected bytes, characters\n\ ++ or fields\n\ ++"), stdout); ++ fputs (_("\ ++ -s, --only-delimited do not print lines not containing delimiters\n\ ++ --output-delimiter=STRING use STRING as the output delimiter\n\ ++ the default is to use the input delimiter\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++Use one, and only one of -b, -c or -f. Each LIST is made up of one\n\ ++range, or many ranges separated by commas. Selected input is written\n\ ++in the same order that it is read, and is written exactly once.\n\ ++"), stdout); ++ fputs (_("\ ++Each range is one of:\n\ ++\n\ ++ N N'th byte, character or field, counted from 1\n\ ++ N- from N'th byte, character or field, to end of line\n\ ++ N-M from N'th to M'th (included) byte, character or field\n\ ++ -M from first to M'th (included) byte, character or field\n\ ++\n\ ++With no FILE, or when FILE is -, read standard input.\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++static inline void ++mark_range_start (size_t i) ++{ ++ /* Record the fact that `i' is a range-start index. */ ++ void *ent_from_table = hash_insert (range_start_ht, (void*) i); ++ if (ent_from_table == NULL) ++ { ++ /* Insertion failed due to lack of memory. */ ++ xalloc_die (); ++ } ++ assert ((size_t) ent_from_table == i); ++} ++ ++static inline void ++mark_printable_field (size_t i) ++{ ++ size_t n = i / CHAR_BIT; ++ printable_field[n] |= (1 << (i % CHAR_BIT)); ++} ++ ++static inline bool ++is_printable_field (size_t i) ++{ ++ size_t n = i / CHAR_BIT; ++ return (printable_field[n] >> (i % CHAR_BIT)) & 1; ++} ++ ++static size_t ++hash_int (const void *x, size_t tablesize) ++{ ++#ifdef UINTPTR_MAX ++ uintptr_t y = (uintptr_t) x; ++#else ++ size_t y = (size_t) x; ++#endif ++ return y % tablesize; ++} ++ ++static bool ++hash_compare_ints (void const *x, void const *y) ++{ ++ return (x == y) ? true : false; ++} ++ ++static bool ++is_range_start_index (size_t i) ++{ ++ return hash_lookup (range_start_ht, (void *) i) ? true : false; ++} ++ ++/* Return nonzero if the K'th field or byte is printable. ++ When returning nonzero, if RANGE_START is non-NULL, ++ set *RANGE_START to true if K is the beginning of a range, and to ++ false otherwise. */ ++ ++static bool ++print_kth (size_t k, bool *range_start) ++{ ++ bool k_selected ++ = ((0 < eol_range_start && eol_range_start <= k) ++ || (k <= max_range_endpoint && is_printable_field (k))); ++ ++ bool is_selected = k_selected ^ complement; ++ if (range_start && is_selected) ++ *range_start = is_range_start_index (k); ++ ++ return is_selected; ++} ++ ++/* Comparison function for qsort to order the list of ++ struct range_pairs. */ ++static int ++compare_ranges (const void *a, const void *b) ++{ ++ int a_start = ((const struct range_pair *) a)->lo; ++ int b_start = ((const struct range_pair *) b)->lo; ++ return a_start < b_start ? -1 : a_start > b_start; ++} ++ ++/* Given the list of field or byte range specifications FIELDSTR, set ++ MAX_RANGE_ENDPOINT and allocate and initialize the PRINTABLE_FIELD ++ array. If there is a right-open-ended range, set EOL_RANGE_START ++ to its starting index. FIELDSTR should be composed of one or more ++ numbers or ranges of numbers, separated by blanks or commas. ++ Incomplete ranges may be given: `-m' means `1-m'; `n-' means `n' ++ through end of line. Return true if FIELDSTR contains at least ++ one field specification, false otherwise. */ ++ ++/* FIXME-someday: What if the user wants to cut out the 1,000,000-th ++ field of some huge input file? This function shouldn't have to ++ allocate a table of a million bits just so we can test every ++ field < 10^6 with an array dereference. Instead, consider using ++ an adaptive approach: if the range of selected fields is too large, ++ but only a few fields/byte-offsets are actually selected, use a ++ hash table. If the range of selected fields is too large, and ++ too many are selected, then resort to using the range-pairs (the ++ `rp' array) directly. */ ++ ++static bool ++set_fields (const char *fieldstr) ++{ ++ size_t initial = 1; /* Value of first number in a range. */ ++ size_t value = 0; /* If nonzero, a number being accumulated. */ ++ bool lhs_specified = false; ++ bool rhs_specified = false; ++ bool dash_found = false; /* True if a '-' is found in this field. */ ++ bool field_found = false; /* True if at least one field spec ++ has been processed. */ ++ ++ struct range_pair *rp = NULL; ++ size_t n_rp = 0; ++ size_t n_rp_allocated = 0; ++ size_t i; ++ bool in_digits = false; ++ ++ /* Collect and store in RP the range end points. ++ It also sets EOL_RANGE_START if appropriate. */ ++ ++ for (;;) ++ { ++ if (*fieldstr == '-') ++ { ++ in_digits = false; ++ /* Starting a range. */ ++ if (dash_found) ++ FATAL_ERROR (_("invalid byte or field list")); ++ dash_found = true; ++ fieldstr++; ++ ++ initial = (lhs_specified ? value : 1); ++ value = 0; ++ } ++ else if (*fieldstr == ',' || ++ isblank (to_uchar (*fieldstr)) || *fieldstr == '\0') ++ { ++ in_digits = false; ++ /* Ending the string, or this field/byte sublist. */ ++ if (dash_found) ++ { ++ dash_found = false; ++ ++ if (!lhs_specified && !rhs_specified) ++ FATAL_ERROR (_("invalid range with no endpoint: -")); ++ ++ /* A range. Possibilities: -n, m-n, n-. ++ In any case, `initial' contains the start of the range. */ ++ if (!rhs_specified) ++ { ++ /* `n-'. From `initial' to end of line. */ ++ eol_range_start = initial; ++ field_found = true; ++ } ++ else ++ { ++ /* `m-n' or `-n' (1-n). */ ++ if (value < initial) ++ FATAL_ERROR (_("invalid decreasing range")); ++ ++ /* Is there already a range going to end of line? */ ++ if (eol_range_start != 0) ++ { ++ /* Yes. Is the new sequence already contained ++ in the old one? If so, no processing is ++ necessary. */ ++ if (initial < eol_range_start) ++ { ++ /* No, the new sequence starts before the ++ old. Does the old range going to end of line ++ extend into the new range? */ ++ if (eol_range_start <= value) ++ { ++ /* Yes. Simply move the end of line marker. */ ++ eol_range_start = initial; ++ } ++ else ++ { ++ /* No. A simple range, before and disjoint from ++ the range going to end of line. Fill it. */ ++ ADD_RANGE_PAIR (rp, initial, value); ++ } ++ ++ /* In any case, some fields were selected. */ ++ field_found = true; ++ } ++ } ++ else ++ { ++ /* There is no range going to end of line. */ ++ ADD_RANGE_PAIR (rp, initial, value); ++ field_found = true; ++ } ++ value = 0; ++ } ++ } ++ else ++ { ++ /* A simple field number, not a range. */ ++ ADD_RANGE_PAIR (rp, value, value); ++ value = 0; ++ field_found = true; ++ } ++ ++ if (*fieldstr == '\0') ++ { ++ break; ++ } ++ ++ fieldstr++; ++ lhs_specified = false; ++ rhs_specified = false; ++ } ++ else if (ISDIGIT (*fieldstr)) ++ { ++ /* Record beginning of digit string, in case we have to ++ complain about it. */ ++ static char const *num_start; ++ if (!in_digits || !num_start) ++ num_start = fieldstr; ++ in_digits = true; ++ ++ if (dash_found) ++ rhs_specified = 1; ++ else ++ lhs_specified = 1; ++ ++ /* Detect overflow. */ ++ if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t)) ++ { ++ /* In case the user specified -c$(echo 2^64|bc),22, ++ complain only about the first number. */ ++ /* Determine the length of the offending number. */ ++ size_t len = strspn (num_start, "0123456789"); ++ char *bad_num = xstrndup (num_start, len); ++ if (operating_mode == byte_mode) ++ error (0, 0, ++ _("byte offset %s is too large"), quote (bad_num)); ++ else ++ error (0, 0, ++ _("field number %s is too large"), quote (bad_num)); ++ free (bad_num); ++ exit (EXIT_FAILURE); ++ } ++ ++ fieldstr++; ++ } ++ else ++ FATAL_ERROR (_("invalid byte or field list")); ++ } ++ ++ max_range_endpoint = 0; ++ for (i = 0; i < n_rp; i++) ++ { ++ if (rp[i].hi > max_range_endpoint) ++ max_range_endpoint = rp[i].hi; ++ } ++ ++ /* Allocate an array large enough so that it may be indexed by ++ the field numbers corresponding to all finite ranges ++ (i.e. `2-6' or `-4', but not `5-') in FIELDSTR. */ ++ ++ printable_field = xzalloc (max_range_endpoint / CHAR_BIT + 1); ++ ++ qsort (rp, n_rp, sizeof (rp[0]), compare_ranges); ++ ++ /* Set the array entries corresponding to integers in the ranges of RP. */ ++ for (i = 0; i < n_rp; i++) ++ { ++ size_t j; ++ size_t rsi_candidate; ++ ++ /* Record the range-start indices, i.e., record each start ++ index that is not part of any other (lo..hi] range. */ ++ rsi_candidate = complement ? rp[i].hi + 1 : rp[i].lo; ++ if (output_delimiter_specified ++ && !is_printable_field (rsi_candidate)) ++ mark_range_start (rsi_candidate); ++ ++ for (j = rp[i].lo; j <= rp[i].hi; j++) ++ mark_printable_field (j); ++ } ++ ++ if (output_delimiter_specified ++ && !complement ++ && eol_range_start && !is_printable_field (eol_range_start)) ++ mark_range_start (eol_range_start); ++ ++ free (rp); ++ ++ return field_found; ++} ++ ++/* Read from stream STREAM, printing to standard output any selected bytes. */ ++ ++static void ++cut_bytes (FILE *stream) ++{ ++ size_t byte_idx; /* Number of bytes in the line so far. */ ++ /* 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; ++ ++ byte_idx = 0; ++ print_delimiter = false; ++ while (1) ++ { ++ int c; /* Each character from the file. */ ++ ++ c = getc (stream); ++ ++ if (c == '\n') ++ { ++ putchar ('\n'); ++ byte_idx = 0; ++ print_delimiter = false; ++ } ++ else if (c == EOF) ++ { ++ if (byte_idx > 0) ++ putchar ('\n'); ++ break; ++ } ++ else ++ { ++ bool range_start; ++ bool *rs = output_delimiter_specified ? &range_start : NULL; ++ if (print_kth (++byte_idx, rs)) ++ { ++ if (rs && *rs && print_delimiter) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ print_delimiter = true; ++ putchar (c); ++ } ++ } ++ } ++} ++ ++/* Read from stream STREAM, printing to standard output any selected fields. */ ++ ++static void ++cut_fields (FILE *stream) ++{ ++ int c; ++ size_t field_idx = 1; ++ bool found_any_selected_field = false; ++ bool buffer_first_field; ++ ++ c = getc (stream); ++ if (c == EOF) ++ return; ++ ++ ungetc (c, stream); ++ ++ /* 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, NULL)); ++ ++ while (1) ++ { ++ if (field_idx == 1 && buffer_first_field) ++ { ++ ssize_t len; ++ size_t n_bytes; ++ ++ len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0, ++ GETNLINE_NO_LIMIT, delim, '\n', stream); ++ if (len < 0) ++ { ++ free (field_1_buffer); ++ field_1_buffer = NULL; ++ if (ferror (stream) || feof (stream)) ++ break; ++ xalloc_die (); ++ } ++ ++ n_bytes = len; ++ assert (n_bytes != 0); ++ ++ /* 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 (to_uchar (field_1_buffer[n_bytes - 1]) != delim) ++ { ++ if (suppress_non_delimited) ++ { ++ /* Empty. */ ++ } ++ else ++ { ++ fwrite (field_1_buffer, sizeof (char), n_bytes, stdout); ++ /* Make sure the output line is newline terminated. */ ++ if (field_1_buffer[n_bytes - 1] != '\n') ++ putchar ('\n'); ++ } ++ continue; ++ } ++ if (print_kth (1, NULL)) ++ { ++ /* Print the field, but not the trailing delimiter. */ ++ fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout); ++ found_any_selected_field = true; ++ } ++ ++field_idx; ++ } ++ ++ if (c != EOF) ++ { ++ if (print_kth (field_idx, NULL)) ++ { ++ if (found_any_selected_field) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ found_any_selected_field = true; ++ ++ while ((c = getc (stream)) != delim && c != '\n' && c != EOF) ++ { ++ putchar (c); ++ } ++ } ++ else ++ { ++ while ((c = getc (stream)) != delim && c != '\n' && c != EOF) ++ { ++ /* Empty. */ ++ } ++ } ++ } ++ ++ if (c == '\n') ++ { ++ c = getc (stream); ++ if (c != EOF) ++ { ++ ungetc (c, stream); ++ c = '\n'; ++ } ++ } ++ ++ if (c == delim) ++ ++field_idx; ++ else if (c == '\n' || c == EOF) ++ { ++ if (found_any_selected_field ++ || !(suppress_non_delimited && field_idx == 1)) ++ putchar ('\n'); ++ if (c == EOF) ++ break; ++ field_idx = 1; ++ found_any_selected_field = false; ++ } ++ } ++} ++ ++static void ++cut_stream (FILE *stream) ++{ ++ if (operating_mode == byte_mode) ++ cut_bytes (stream); ++ else ++ cut_fields (stream); ++} ++ ++/* Process file FILE to standard output. ++ Return true if successful. */ ++ ++static bool ++cut_file (char const *file) ++{ ++ FILE *stream; ++ ++ if (STREQ (file, "-")) ++ { ++ have_read_stdin = true; ++ stream = stdin; ++ } ++ else ++ { ++ stream = fopen (file, "r"); ++ if (stream == NULL) ++ { ++ error (0, errno, "%s", file); ++ return false; ++ } ++ } ++ ++ cut_stream (stream); ++ ++ if (ferror (stream)) ++ { ++ error (0, errno, "%s", file); ++ return false; ++ } ++ if (STREQ (file, "-")) ++ clearerr (stream); /* Also clear EOF. */ ++ else if (fclose (stream) == EOF) ++ { ++ error (0, errno, "%s", file); ++ return false; ++ } ++ return true; ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int optc; ++ bool ok; ++ bool delim_specified = false; ++ char *spec_list_string IF_LINT(= NULL); ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ atexit (close_stdout); ++ ++ operating_mode = undefined_mode; ++ ++ /* By default, all non-delimited lines are printed. */ ++ suppress_non_delimited = false; ++ ++ delim = '\0'; ++ have_read_stdin = false; ++ ++ while ((optc = getopt_long (argc, argv, "b:c:d:f:ns", longopts, NULL)) != -1) ++ { ++ 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")); ++ operating_mode = byte_mode; ++ spec_list_string = optarg; ++ break; ++ ++ case 'f': ++ /* Build the field list. */ ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = field_mode; ++ spec_list_string = optarg; ++ break; ++ ++ 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; ++ break; ++ ++ case OUTPUT_DELIMITER_OPTION: ++ output_delimiter_specified = true; ++ /* Interpret --output-delimiter='' to mean ++ `use the NUL byte as the delimiter.' */ ++ output_delimiter_length = (optarg[0] == '\0' ++ ? 1 : strlen (optarg)); ++ output_delimiter_string = xstrdup (optarg); ++ break; ++ ++ case 'n': ++ break; ++ ++ case 's': ++ suppress_non_delimited = true; ++ break; ++ ++ case COMPLEMENT_OPTION: ++ complement = true; ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (EXIT_FAILURE); ++ } ++ } ++ ++ if (operating_mode == undefined_mode) ++ FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); ++ ++ if (delim != '\0' && operating_mode != field_mode) ++ FATAL_ERROR (_("an input delimiter may be specified only\ ++ when operating on fields")); ++ ++ if (suppress_non_delimited && operating_mode != field_mode) ++ FATAL_ERROR (_("suppressing non-delimited lines makes sense\n\ ++\tonly when operating on fields")); ++ ++ if (output_delimiter_specified) ++ { ++ range_start_ht = hash_initialize (HT_RANGE_START_INDEX_INITIAL_CAPACITY, ++ NULL, hash_int, ++ hash_compare_ints, NULL); ++ if (range_start_ht == NULL) ++ xalloc_die (); ++ ++ } ++ ++ if (! set_fields (spec_list_string)) ++ { ++ if (operating_mode == field_mode) ++ FATAL_ERROR (_("missing list of fields")); ++ else ++ FATAL_ERROR (_("missing list of positions")); ++ } ++ ++ if (!delim_specified) ++ delim = '\t'; ++ ++ if (output_delimiter_string == NULL) ++ { ++ static char dummy[2]; ++ dummy[0] = delim; ++ dummy[1] = '\0'; ++ output_delimiter_string = dummy; ++ output_delimiter_length = 1; ++ } ++ ++ if (optind == argc) ++ ok = cut_file ("-"); ++ else ++ for (ok = true; optind < argc; optind++) ++ ok &= cut_file (argv[optind]); ++ ++ if (range_start_ht) ++ hash_free (range_start_ht); ++ ++ if (have_read_stdin && fclose (stdin) == EOF) ++ { ++ error (0, errno, "-"); ++ ok = false; ++ } ++ ++ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); ++} +diff -urNp coreutils-8.0-orig/src/expand.c coreutils-8.0/src/expand.c +--- coreutils-8.0-orig/src/expand.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/expand.c 2009-10-07 10:07:16.000000000 +0200 +@@ -37,11 +37,28 @@ #include #include #include @@ -187,7 +1602,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "expand" -@@ -365,6 +383,142 @@ +@@ -357,6 +374,142 @@ expand (void) } } @@ -330,7 +1745,7 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am int main (int argc, char **argv) { -@@ -429,7 +583,12 @@ +@@ -421,7 +574,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -344,843 +1759,444 @@ diff -urN coreutils-6.12-orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); ---- coreutils-6.8+/src/join.c.i18n 2007-01-14 15:41:28.000000000 +0000 -+++ coreutils-6.8+/src/join.c 2007-03-01 15:08:24.000000000 +0000 -@@ -23,17 +23,31 @@ - #include - #include - -+/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif +diff -urNp coreutils-8.0-orig/src/expand.c.orig coreutils-8.0/src/expand.c.orig +--- coreutils-8.0-orig/src/expand.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/expand.c.orig 2009-09-29 15:27:54.000000000 +0200 +@@ -0,0 +1,430 @@ ++/* expand - convert tabs to spaces ++ Copyright (C) 89, 91, 1995-2006, 2008-2009 Free Software Foundation, Inc. + -+/* Get iswblank(), towupper. */ -+#if HAVE_WCTYPE_H -+# include -+#endif ++ 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. + - #include "system.h" - #include "error.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 ++ 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. + - /* The official name of this program (e.g., no `g' prefix). */ - #define PROGRAM_NAME "join" - -@@ -104,10 +118,12 @@ - /* 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; ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ + -+/* The number of bytes used for tab. */ -+static size_t tablen = 0; - - /* If nonzero, check that the input is correctly ordered. */ - static enum -@@ -199,10 +217,11 @@ - if (ptr == lim) - return; - -- if (0 <= tab) -+ 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 -@@ -229,6 +248,148 @@ - extract_field (line, ptr, lim - ptr); - } - -+#if HAVE_MBRTOWC -+static void -+xfields_multibyte (struct line *line) ++/* By default, convert all tabs to spaces. ++ Preserves backspace characters in the output; they decrement the ++ column count for tab calculations. ++ The default action is equivalent to -8. ++ ++ Options: ++ --tabs=tab1[,tab2[,...]] ++ -t tab1[,tab2[,...]] ++ -tab1[,tab2[,...]] If only one tab stop is given, set the tabs tab1 ++ columns apart instead of the default 8. Otherwise, ++ set the tabs at columns tab1, tab2, etc. (numbered from ++ 0); replace any tabs beyond the tab stops given with ++ single spaces. ++ --initial ++ -i Only convert initial tabs on each line to spaces. ++ ++ David MacKenzie */ ++ ++#include ++ ++#include ++#include ++#include ++#include "system.h" ++#include "error.h" ++#include "quote.h" ++#include "xstrndup.h" ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "expand" ++ ++#define AUTHORS proper_name ("David MacKenzie") ++ ++/* If true, convert blanks even after nonblank characters have been ++ read on the line. */ ++static bool convert_entire_line; ++ ++/* If nonzero, the size of all tab stops. If zero, use `tab_list' instead. */ ++static uintmax_t tab_size; ++ ++/* Array of the explicit column numbers of the tab stops; ++ after `tab_list' is exhausted, each additional tab is replaced ++ by a space. The first column is column 0. */ ++static uintmax_t *tab_list; ++ ++/* The number of allocated entries in `tab_list'. */ ++static size_t n_tabs_allocated; ++ ++/* The index of the first invalid element of `tab_list', ++ where the next element can be added. */ ++static size_t first_free_tab; ++ ++/* Null-terminated array of input filenames. */ ++static char **file_list; ++ ++/* Default for `file_list' if no files are given on the command line. */ ++static char *stdin_argv[] = +{ -+ 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; ++ (char *) "-", NULL ++}; + -+ memset (&state, 0, sizeof (mbstate_t)); ++/* True if we have ever read standard input. */ ++static bool have_read_stdin; + -+ if (ptr >= lim) ++/* The desired exit status. */ ++static int exit_status; ++ ++static char const shortopts[] = "it:0::1::2::3::4::5::6::7::8::9::"; ++ ++static struct option const longopts[] = ++{ ++ {"tabs", required_argument, NULL, 't'}, ++ {"initial", no_argument, NULL, 'i'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... [FILE]...\n\ ++"), ++ program_name); ++ fputs (_("\ ++Convert tabs in each FILE to spaces, writing to standard output.\n\ ++With no FILE, or when FILE is -, read standard input.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ -i, --initial do not convert tabs after non blanks\n\ ++ -t, --tabs=NUMBER have tabs NUMBER characters apart, not 8\n\ ++"), stdout); ++ fputs (_("\ ++ -t, --tabs=LIST use comma separated list of explicit tab positions\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++/* Add tab stop TABVAL to the end of `tab_list'. */ ++ ++static void ++add_tab_stop (uintmax_t tabval) ++{ ++ if (first_free_tab == n_tabs_allocated) ++ tab_list = X2NREALLOC (tab_list, &n_tabs_allocated); ++ tab_list[first_free_tab++] = tabval; ++} ++ ++/* Add the comma or blank separated list of tab stops STOPS ++ to the list of tab stops. */ ++ ++static void ++parse_tab_stops (char const *stops) ++{ ++ bool have_tabval = false; ++ uintmax_t tabval IF_LINT (= 0); ++ char const *num_start IF_LINT (= NULL); ++ bool ok = true; ++ ++ for (; *stops; stops++) ++ { ++ if (*stops == ',' || isblank (to_uchar (*stops))) ++ { ++ if (have_tabval) ++ add_tab_stop (tabval); ++ have_tabval = false; ++ } ++ else if (ISDIGIT (*stops)) ++ { ++ if (!have_tabval) ++ { ++ tabval = 0; ++ have_tabval = true; ++ num_start = stops; ++ } ++ ++ /* Detect overflow. */ ++ if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) ++ { ++ size_t len = strspn (num_start, "0123456789"); ++ char *bad_num = xstrndup (num_start, len); ++ error (0, 0, _("tab stop is too large %s"), quote (bad_num)); ++ free (bad_num); ++ ok = false; ++ stops = num_start + len - 1; ++ } ++ } ++ else ++ { ++ error (0, 0, _("tab size contains invalid character(s): %s"), ++ quote (stops)); ++ ok = false; ++ break; ++ } ++ } ++ ++ if (!ok) ++ exit (EXIT_FAILURE); ++ ++ if (have_tabval) ++ add_tab_stop (tabval); ++} ++ ++/* Check that the list of tab stops TABS, with ENTRIES entries, ++ contains only nonzero, ascending values. */ ++ ++static void ++validate_tab_stops (uintmax_t const *tabs, size_t entries) ++{ ++ uintmax_t prev_tab = 0; ++ size_t i; ++ ++ for (i = 0; i < entries; i++) ++ { ++ if (tabs[i] == 0) ++ error (EXIT_FAILURE, 0, _("tab size cannot be 0")); ++ if (tabs[i] <= prev_tab) ++ error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); ++ prev_tab = tabs[i]; ++ } ++} ++ ++/* Close the old stream pointer FP if it is non-NULL, ++ and return a new one opened to read the next input file. ++ Open a filename of `-' as the standard input. ++ Return NULL if there are no more input files. */ ++ ++static FILE * ++next_file (FILE *fp) ++{ ++ static char *prev_file; ++ char *file; ++ ++ if (fp) ++ { ++ if (ferror (fp)) ++ { ++ error (0, errno, "%s", prev_file); ++ exit_status = EXIT_FAILURE; ++ } ++ if (STREQ (prev_file, "-")) ++ clearerr (fp); /* Also clear EOF. */ ++ else if (fclose (fp) != 0) ++ { ++ error (0, errno, "%s", prev_file); ++ exit_status = EXIT_FAILURE; ++ } ++ } ++ ++ while ((file = *file_list++) != NULL) ++ { ++ if (STREQ (file, "-")) ++ { ++ have_read_stdin = true; ++ prev_file = file; ++ return stdin; ++ } ++ fp = fopen (file, "r"); ++ if (fp) ++ { ++ prev_file = file; ++ return fp; ++ } ++ error (0, errno, "%s", file); ++ exit_status = EXIT_FAILURE; ++ } ++ return NULL; ++} ++ ++/* Change tabs to spaces, writing to stdout. ++ Read each file in `file_list', in order. */ ++ ++static void ++expand (void) ++{ ++ /* Input stream. */ ++ FILE *fp = next_file (NULL); ++ ++ if (!fp) + return; + -+ if (tab != NULL) ++ for (;;) + { -+ unsigned char t = tab[0]; -+ 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); ++ /* Input character, or EOF. */ ++ int c; + -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; ++ /* If true, perform translations. */ ++ bool convert = true; + -+ if (mblength == tablen && !memcmp (sep, tab, mblength)) -+ break; -+ else -+ { -+ sep += mblength; -+ continue; -+ } -+ } + -+ if (sep >= lim) -+ break; ++ /* The following variables have valid values only when CONVERT ++ is true: */ + -+ 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); ++ /* Column of next input character. */ ++ uintmax_t column = 0; + -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; ++ /* Index in TAB_LIST of next tab stop to examine. */ ++ size_t tab_index = 0; + -+ if (!iswblank(wc)) -+ break; -+ ptr += mblength; -+ } ++ ++ /* Convert a line of text. */ + + 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)) -+ 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)) -+ break; -+ -+ ptr += mblength; -+ } -+ } -+ while (ptr < lim); -+ } -+ -+ extract_field (line, ptr, lim - ptr); -+} -+#endif -+ - static void - freeline (struct line *line) - { -@@ -377,11 +601,18 @@ - - /* Print the join of LINE1 and LINE2. */ - -+#define PUT_TAB_CHAR \ -+ do \ -+ { \ -+ (tab != NULL) ? \ -+ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ -+ } \ -+ while (0) -+ - static void - prjoin (struct line const *line1, struct line const *line2) - { - const struct outlist *outlist; -- char output_separator = tab < 0 ? ' ' : tab; - - outlist = outlist_head.next; - if (outlist) -@@ -416,7 +647,7 @@ - o = o->next; - if (o == NULL) - break; -- putchar (output_separator); -+ PUT_TAB_CHAR; - } - putchar ('\n'); - } -@@ -434,23 +665,23 @@ - prfield (join_field_1, line1); - for (i = 0; i < join_field_1 && i < line1->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line1); - } - for (i = join_field_1 + 1; i < line1->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line1); - } - - for (i = 0; i < join_field_2 && i < line2->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line2); - } - for (i = join_field_2 + 1; i < line2->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line2); - } - putchar ('\n'); -@@ -859,20 +1090,41 @@ - - case 't': - { -- unsigned char newtab = optarg[0]; -- if (! newtab) -+ char *newtab; -+ size_t newtablen; -+ if (! optarg[0]) - error (EXIT_FAILURE, 0, _("empty tab")); -- if (optarg[1]) -+ 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 (newtablen == 1 && newtab[1]) -+ { -+ if (STREQ (newtab, "\\0")) -+ newtab[0] = '\0'; -+ } -+ if (tab != NULL && strcmp (tab, newtab)) - { -- if (STREQ (optarg, "\\0")) -- newtab = '\0'; -- else -- error (EXIT_FAILURE, 0, _("multi-character tab %s"), -- quote (optarg)); -+ free (newtab); -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); - } -- if (0 <= tab && tab != newtab) -- error (EXIT_FAILURE, 0, _("incompatible tabs")); - tab = newtab; -+ tablen = newtablen; - } - break; - -diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c ---- coreutils-6.11-orig/src/join.c 2008-04-21 13:44:32.000000000 +0200 -+++ coreutils-6.11/src/join.c 2008-04-21 14:03:22.000000000 +0200 -@@ -324,56 +324,115 @@ 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; - - 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++) -+ { -+ copy[i] = alloca (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; -+ -+ memset (&state_wc, '\0', sizeof (mbstate_t)); -+ wcrtomb (copy[i] + j, uwc, &state_wc); -+ } -+ else -+ memcpy (copy[i] + j, beg[i] + j, mblength); -+ } -+ j += mblength; -+ } -+ copy[i][j] = '\0'; -+ } -+ } -+ else -+#endif -+ { -+ for (i = 0; i < 2; i++) -+ { -+ copy[i] = alloca (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] = (unsigned char *) beg[0]; -+ copy[1] = (unsigned char *) beg[1]; - } - -+ if (hard_LC_COLLATE) -+ return xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); -+ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); -+ -+ - 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 ---- coreutils-6.8+/src/uniq.c.i18n 2007-01-14 15:41:28.000000000 +0000 -+++ coreutils-6.8+/src/uniq.c 2007-03-01 15:08:24.000000000 +0000 -@@ -23,6 +23,16 @@ - #include - #include - -+/* Get mbstate_t, mbrtowc(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get isw* functions. */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+ - #include "system.h" - #include "argmatch.h" - #include "linebuffer.h" -@@ -32,7 +42,19 @@ - #include "quote.h" - #include "xmemcoll.h" - #include "xstrtol.h" --#include "memcasecmp.h" -+#include "xmemcoll.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" -@@ -109,6 +131,10 @@ - /* Select whether/how to delimit groups of duplicate lines. */ - static enum delimit_method delimit_groups; - -+/* Function pointers. */ -+static char * -+(*find_field) (struct linebuffer *line); -+ - static struct option const longopts[] = - { - {"count", no_argument, NULL, 'c'}, -@@ -198,7 +224,7 @@ - return a pointer to the beginning of the line's field to be compared. */ - - static char * --find_field (struct linebuffer const *line) -+find_field_uni (struct linebuffer *line) - { - size_t count; - char const *lp = line->buffer; -@@ -219,6 +245,83 @@ - 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; -+ -+ 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)) ++ while ((c = getc (fp)) < 0 && (fp = next_file (fp))) ++ continue; ++ ++ if (convert) + { -+ pos += mblength; -+ break; -+ } -+ pos += mblength; -+ } -+ -+ while (pos < size) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); -+ -+ if (!convfail && iswblank (wc)) -+ 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. -@@ -227,6 +330,8 @@ - static bool - different (char *old, char *new, size_t oldlen, size_t newlen) - { -+ char *copy_old, *copy_new; -+ - if (check_chars < oldlen) - oldlen = check_chars; - if (check_chars < newlen) -@@ -234,14 +339,92 @@ - - if (ignore_case) - { -- /* FIXME: This should invoke strcoll somehow. */ -- return oldlen != newlen || memcasecmp (old, new, oldlen); -+ size_t i; -+ -+ copy_old = alloca (oldlen + 1); -+ copy_new = alloca (oldlen + 1); -+ -+ for (i = 0; i < oldlen; i++) -+ { -+ copy_old[i] = toupper (old[i]); -+ copy_new[i] = toupper (new[i]); -+ } - } -- else if (hard_LC_COLLATE) -- return xmemcoll (old, oldlen, new, newlen) != 0; - else -- return oldlen != newlen || memcmp (old, new, oldlen); -+ { -+ copy_old = (char *)old; -+ copy_new = (char *)new; -+ } -+ -+ return xmemcoll (copy_old, oldlen, copy_new, newlen); -+} -+ -+#if HAVE_MBRTOWC -+static int -+different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) -+{ -+ size_t i, j, chars; -+ const char *str[2]; -+ char *copy[2]; -+ size_t len[2]; -+ mbstate_t state[2]; -+ size_t mblength; -+ wchar_t wc, uwc; -+ mbstate_t state_bak; -+ -+ str[0] = old; -+ str[1] = new; -+ len[0] = oldlen; -+ len[1] = newlen; -+ state[0] = oldstate; -+ state[1] = newstate; -+ -+ for (i = 0; i < 2; i++) -+ { -+ copy[i] = alloca (len[i] + 1); -+ -+ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) -+ { -+ state_bak = state[i]; -+ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); -+ -+ switch (mblength) -+ { -+ case (size_t)-1: -+ case (size_t)-2: -+ state[i] = state_bak; -+ /* Fall through */ -+ case 0: -+ mblength = 1; -+ break; -+ -+ default: -+ if (ignore_case) ++ if (c == '\t') + { -+ uwc = towupper (wc); ++ /* Column the next input tab stop is on. */ ++ uintmax_t next_tab_column; + -+ if (uwc != wc) -+ { -+ mbstate_t state_wc; -+ -+ memset (&state_wc, '\0', sizeof(mbstate_t)); -+ wcrtomb (copy[i] + j, uwc, &state_wc); -+ } ++ if (tab_size) ++ next_tab_column = column + (tab_size - column % tab_size); + else -+ memcpy (copy[i] + j, str[i] + j, mblength); ++ for (;;) ++ if (tab_index == first_free_tab) ++ { ++ next_tab_column = column + 1; ++ break; ++ } ++ else ++ { ++ uintmax_t tab = tab_list[tab_index++]; ++ if (column < tab) ++ { ++ next_tab_column = tab; ++ break; ++ } ++ } ++ ++ if (next_tab_column < column) ++ error (EXIT_FAILURE, 0, _("input line is too long")); ++ ++ while (++column < next_tab_column) ++ if (putchar (' ') < 0) ++ error (EXIT_FAILURE, errno, _("write error")); ++ ++ c = ' '; ++ } ++ else if (c == '\b') ++ { ++ /* Go back one column, and force recalculation of the ++ next tab stop. */ ++ column -= !!column; ++ tab_index -= !!tab_index; + } + else -+ memcpy (copy[i] + j, str[i] + j, mblength); ++ { ++ column++; ++ if (!column) ++ error (EXIT_FAILURE, 0, _("input line is too long")); ++ } ++ ++ convert &= convert_entire_line || !! isblank (c); + } -+ j += mblength; ++ ++ if (c < 0) ++ return; ++ ++ if (putchar (c) < 0) ++ error (EXIT_FAILURE, errno, _("write error")); + } -+ copy[i][j] = '\0'; -+ len[i] = j; ++ while (c != '\n'); + } ++} + -+ return xmemcoll (copy[0], len[0], copy[1], len[1]); - } -+#endif - - /* Output the line in linebuffer LINE to standard output - provided that the switches say it should be output. -@@ -295,15 +478,43 @@ - { - char *prevfield IF_LINT (= NULL); - size_t prevlen IF_LINT (= 0); -+#if HAVE_MBRTOWC -+ mbstate_t prevstate; ++int ++main (int argc, char **argv) ++{ ++ int c; + -+ memset (&prevstate, '\0', sizeof (mbstate_t)); -+#endif - - while (!feof (stdin)) - { - char *thisfield; - size_t thislen; -+#if HAVE_MBRTOWC -+ mbstate_t thisstate; -+#endif ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); + - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - break; - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ thisstate = thisline->state; ++ atexit (close_stdout); + -+ if (prevline->length == 0 || different_multi -+ (thisfield, prevfield, thislen, prevlen, thisstate, prevstate)) -+ { -+ fwrite (thisline->buffer, sizeof (char), -+ thisline->length, stdout); ++ have_read_stdin = false; ++ exit_status = EXIT_SUCCESS; ++ convert_entire_line = true; ++ tab_list = NULL; ++ first_free_tab = 0; + -+ SWAP_LINES (prevline, thisline); -+ prevfield = thisfield; -+ prevlen = thislen; -+ prevstate = thisstate; -+ } -+ } -+ else -+#endif - if (prevline->length == 0 - || different (thisfield, prevfield, thislen, prevlen)) - { -@@ -322,17 +533,26 @@ - size_t prevlen; - uintmax_t match_count = 0; - bool first_delimiter = true; -+#if HAVE_MBRTOWC -+ mbstate_t prevstate; -+#endif - - if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) - goto closefiles; - prevfield = find_field (prevline); - prevlen = prevline->length - 1 - (prevfield - prevline->buffer); -+#if HAVE_MBRTOWC -+ prevstate = prevline->state; -+#endif - - while (!feof (stdin)) - { - bool match; - char *thisfield; - size_t thislen; -+#if HAVE_MBRTOWC -+ mbstate_t thisstate; -+#endif - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - { - if (ferror (stdin)) -@@ -341,6 +561,15 @@ - } - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ thisstate = thisline->state; -+ match = !different_multi (thisfield, prevfield, -+ thislen, prevlen, thisstate, prevstate); -+ } ++ while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) ++ { ++ switch (c) ++ { ++ case 'i': ++ convert_entire_line = false; ++ break; ++ ++ case 't': ++ parse_tab_stops (optarg); ++ break; ++ ++ case '0': case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': case '8': case '9': ++ if (optarg) ++ parse_tab_stops (optarg - 1); + else -+#endif - match = !different (thisfield, prevfield, thislen, prevlen); - match_count += match; - -@@ -373,6 +602,9 @@ - SWAP_LINES (prevline, thisline); - prevfield = thisfield; - prevlen = thislen; -+#if HAVE_MBRTOWC -+ prevstate = thisstate; -+#endif - if (!match) - match_count = 0; - } -@@ -417,6 +649,19 @@ - - atexit (close_stdout); - -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ find_field = find_field_multi; ++ { ++ char tab_stop[2]; ++ tab_stop[0] = c; ++ tab_stop[1] = '\0'; ++ parse_tab_stops (tab_stop); ++ } ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (EXIT_FAILURE); ++ } + } ++ ++ validate_tab_stops (tab_list, first_free_tab); ++ ++ if (first_free_tab == 0) ++ tab_size = 8; ++ else if (first_free_tab == 1) ++ tab_size = tab_list[0]; + else -+#endif -+ { -+ find_field = find_field_uni; -+ } ++ tab_size = 0; + ++ file_list = (optind < argc ? &argv[optind] : stdin_argv); + ++ expand (); + - skip_chars = 0; - skip_fields = 0; - check_chars = SIZE_MAX; ---- coreutils-6.8+/src/fold.c.i18n 2007-02-23 12:01:47.000000000 +0000 -+++ coreutils-6.8+/src/fold.c 2007-03-01 15:08:24.000000000 +0000 -@@ -23,11 +23,33 @@ ++ if (have_read_stdin && fclose (stdin) != 0) ++ error (EXIT_FAILURE, errno, "-"); ++ ++ exit (exit_status); ++} +diff -urNp coreutils-8.0-orig/src/fold.c coreutils-8.0/src/fold.c +--- coreutils-8.0-orig/src/fold.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/fold.c 2009-10-07 10:07:16.000000000 +0200 +@@ -22,11 +22,33 @@ #include #include @@ -1214,7 +2230,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c #define TAB_WIDTH 8 /* The official name of this program (e.g., no `g' prefix). */ -@@ -35,20 +57,41 @@ +@@ -34,20 +56,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -1260,7 +2276,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c {"spaces", no_argument, NULL, 's'}, {"width", required_argument, NULL, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -81,6 +124,7 @@ +@@ -77,6 +120,7 @@ Mandatory arguments to long options are "), stdout); fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -1268,7 +2284,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -98,7 +142,7 @@ +@@ -94,7 +138,7 @@ Mandatory arguments to long options are static size_t adjust_column (size_t column, char c) { @@ -1277,7 +2293,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { if (c == '\b') { -@@ -121,30 +165,14 @@ +@@ -117,30 +161,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -1310,7 +2326,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c while ((c = getc (istream)) != EOF) { -@@ -172,6 +200,15 @@ +@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t bool found_blank = false; size_t logical_end = offset_out; @@ -1326,16 +2342,16 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* Look for the last blank. */ while (logical_end) { -@@ -218,11 +255,222 @@ +@@ -214,11 +251,222 @@ 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 (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + +} + +#if HAVE_MBRTOWC @@ -1508,10 +2524,10 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + } + + *saved_errno = errno; - - if (offset_out) - fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); - ++ ++ if (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ +} +#endif + @@ -1550,7 +2566,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c if (ferror (istream)) { error (0, saved_errno, "%s", filename); -@@ -255,7 +506,8 @@ +@@ -251,7 +499,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1560,7 +2576,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -264,7 +516,15 @@ +@@ -260,7 +509,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1577,9 +2593,5774 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c break; case 's': /* Break at word boundaries. */ ---- coreutils-6.8+/src/sort.c.i18n 2007-02-24 11:23:23.000000000 +0000 -+++ coreutils-6.8+/src/sort.c 2007-03-01 15:10:57.000000000 +0000 -@@ -23,10 +23,19 @@ +diff -urNp coreutils-8.0-orig/src/fold.c.orig coreutils-8.0/src/fold.c.orig +--- coreutils-8.0-orig/src/fold.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/fold.c.orig 2009-09-23 10:25:44.000000000 +0200 +@@ -0,0 +1,314 @@ ++/* fold -- wrap each input line to fit in specified width. ++ Copyright (C) 91, 1995-2006, 2008-2009 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 David MacKenzie, djm@gnu.ai.mit.edu. */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#include "system.h" ++#include "error.h" ++#include "quote.h" ++#include "xstrtol.h" ++ ++#define TAB_WIDTH 8 ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "fold" ++ ++#define AUTHORS proper_name ("David MacKenzie") ++ ++/* 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 struct option const longopts[] = ++{ ++ {"bytes", no_argument, NULL, 'b'}, ++ {"spaces", no_argument, NULL, 's'}, ++ {"width", required_argument, NULL, 'w'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... [FILE]...\n\ ++"), ++ program_name); ++ fputs (_("\ ++Wrap input lines in each FILE (standard input by default), writing to\n\ ++standard output.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ -b, --bytes count bytes rather than columns\n\ ++ -s, --spaces break at spaces\n\ ++ -w, --width=WIDTH use WIDTH columns instead of 80\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++/* Assuming the current column is COLUMN, return the column that ++ printing C will move the cursor to. ++ The first column is 0. */ ++ ++static size_t ++adjust_column (size_t column, char c) ++{ ++ if (!count_bytes) ++ { ++ if (c == '\b') ++ { ++ if (column > 0) ++ column--; ++ } ++ else if (c == '\r') ++ column = 0; ++ else if (c == '\t') ++ column += TAB_WIDTH - column % TAB_WIDTH; ++ else /* if (isprint (c)) */ ++ column++; ++ } ++ else ++ column++; ++ return column; ++} ++ ++/* Fold file FILENAME, or standard input if FILENAME is "-", ++ to stdout, with maximum line length WIDTH. ++ Return true if successful. */ ++ ++static bool ++fold_file (char const *filename, size_t width) ++{ ++ FILE *istream; ++ int 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", filename); ++ return false; ++ } ++ ++ while ((c = getc (istream)) != EOF) ++ { ++ if (offset_out + 1 >= allocated_out) ++ line_out = X2REALLOC (line_out, &allocated_out); ++ ++ if (c == '\n') ++ { ++ line_out[offset_out++] = c; ++ fwrite (line_out, sizeof (char), offset_out, stdout); ++ column = offset_out = 0; ++ continue; ++ } ++ ++ rescan: ++ column = adjust_column (column, c); ++ ++ if (column > width) ++ { ++ /* This character would make the line too long. ++ Print the line plus a newline, and make this character ++ start the next line. */ ++ if (break_spaces) ++ { ++ bool found_blank = false; ++ size_t logical_end = offset_out; ++ ++ /* Look for the last blank. */ ++ while (logical_end) ++ { ++ --logical_end; ++ if (isblank (to_uchar (line_out[logical_end]))) ++ { ++ found_blank = true; ++ break; ++ } ++ } ++ ++ if (found_blank) ++ { ++ size_t i; ++ ++ /* Found a blank. Don't output the part after it. */ ++ logical_end++; ++ fwrite (line_out, sizeof (char), (size_t) logical_end, ++ stdout); ++ putchar ('\n'); ++ /* Move the remainder to the beginning of the next line. ++ The areas being copied here might overlap. */ ++ memmove (line_out, line_out + logical_end, ++ offset_out - logical_end); ++ offset_out -= logical_end; ++ for (column = i = 0; i < offset_out; i++) ++ column = adjust_column (column, line_out[i]); ++ goto rescan; ++ } ++ } ++ ++ if (offset_out == 0) ++ { ++ line_out[offset_out++] = c; ++ continue; ++ } ++ ++ line_out[offset_out++] = '\n'; ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ column = offset_out = 0; ++ goto rescan; ++ } ++ ++ line_out[offset_out++] = c; ++ } ++ ++ saved_errno = errno; ++ ++ if (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ ++ if (ferror (istream)) ++ { ++ error (0, saved_errno, "%s", filename); ++ if (!STREQ (filename, "-")) ++ fclose (istream); ++ return false; ++ } ++ if (!STREQ (filename, "-") && fclose (istream) == EOF) ++ { ++ error (0, errno, "%s", filename); ++ return false; ++ } ++ ++ return true; ++} ++ ++int ++main (int argc, char **argv) ++{ ++ size_t width = 80; ++ int i; ++ int optc; ++ bool ok; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ atexit (close_stdout); ++ ++ break_spaces = count_bytes = have_read_stdin = false; ++ ++ while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) ++ { ++ char optargbuf[2]; ++ ++ switch (optc) ++ { ++ case 'b': /* Count bytes rather than columns. */ ++ count_bytes = true; ++ break; ++ ++ case 's': /* Break at word boundaries. */ ++ break_spaces = true; ++ break; ++ ++ case '0': case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': case '8': case '9': ++ if (optarg) ++ optarg--; ++ else ++ { ++ optargbuf[0] = optc; ++ optargbuf[1] = '\0'; ++ optarg = optargbuf; ++ } ++ /* Fall through. */ ++ case 'w': /* Line width. */ ++ { ++ unsigned long int tmp_ulong; ++ if (! (xstrtoul (optarg, NULL, 10, &tmp_ulong, "") == LONGINT_OK ++ && 0 < tmp_ulong && tmp_ulong < SIZE_MAX - TAB_WIDTH)) ++ error (EXIT_FAILURE, 0, ++ _("invalid number of columns: %s"), quote (optarg)); ++ width = tmp_ulong; ++ } ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (EXIT_FAILURE); ++ } ++ } ++ ++ if (argc == optind) ++ ok = fold_file ("-", width); ++ else ++ { ++ ok = true; ++ for (i = optind; i < argc; i++) ++ ok &= fold_file (argv[i], width); ++ } ++ ++ if (have_read_stdin && fclose (stdin) == EOF) ++ error (EXIT_FAILURE, errno, "-"); ++ ++ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); ++} +diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c +--- coreutils-8.0-orig/src/join.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/join.c 2009-10-07 10:07:16.000000000 +0200 +@@ -22,17 +22,31 @@ + #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 "error.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" + +@@ -121,10 +135,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 +@@ -239,10 +255,11 @@ xfields (struct line *line) + if (ptr == lim) + return; + +- if (0 <= tab) ++ 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 +@@ -269,6 +286,148 @@ 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) ++ { ++ unsigned char t = tab[0]; ++ 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)) ++ 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)) ++ 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)) ++ break; ++ ++ ptr += mblength; ++ } ++ } ++ while (ptr < lim); ++ } ++ ++ extract_field (line, ptr, lim - ptr); ++} ++#endif ++ + static void + freeline (struct line *line) + { +@@ -287,56 +446,115 @@ 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; + + 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++) ++ { ++ copy[i] = alloca (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; ++ ++ memset (&state_wc, '\0', sizeof (mbstate_t)); ++ wcrtomb (copy[i] + j, uwc, &state_wc); ++ } ++ else ++ memcpy (copy[i] + j, beg[i] + j, mblength); ++ } ++ j += mblength; ++ } ++ copy[i][j] = '\0'; ++ } ++ } ++ else ++#endif ++ { ++ for (i = 0; i < 2; i++) ++ { ++ copy[i] = alloca (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] = (unsigned char *) beg[0]; ++ copy[1] = (unsigned char *) beg[1]; + } + ++ if (hard_LC_COLLATE) ++ return xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); ++ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); ++ ++ + 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 +@@ -417,6 +635,11 @@ get_line (FILE *fp, struct line **linep, + return false; + } + ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ xfields_multibyte (line); ++ else ++#endif + xfields (line); + + if (prevline[which - 1]) +@@ -518,11 +741,18 @@ prfield (size_t n, struct line const *li + + /* Print the join of LINE1 and LINE2. */ + ++#define PUT_TAB_CHAR \ ++ do \ ++ { \ ++ (tab != NULL) ? \ ++ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ ++ } \ ++ while (0) ++ + static void + prjoin (struct line const *line1, struct line const *line2) + { + const struct outlist *outlist; +- char output_separator = tab < 0 ? ' ' : tab; + + outlist = outlist_head.next; + if (outlist) +@@ -557,7 +787,7 @@ prjoin (struct line const *line1, struct + o = o->next; + if (o == NULL) + break; +- putchar (output_separator); ++ PUT_TAB_CHAR; + } + putchar ('\n'); + } +@@ -575,23 +805,23 @@ prjoin (struct line const *line1, struct + prfield (join_field_1, line1); + for (i = 0; i < join_field_1 && i < line1->nfields; ++i) + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line1); + } + for (i = join_field_1 + 1; i < line1->nfields; ++i) + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line1); + } + + for (i = 0; i < join_field_2 && i < line2->nfields; ++i) + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line2); + } + for (i = join_field_2 + 1; i < line2->nfields; ++i) + { +- putchar (output_separator); ++ PUT_TAB_CHAR; + prfield (i, line2); + } + putchar ('\n'); +@@ -1022,20 +1252,41 @@ main (int argc, char **argv) + + case 't': + { +- unsigned char newtab = optarg[0]; +- if (! newtab) ++ char *newtab; ++ size_t newtablen; ++ if (! optarg[0]) + error (EXIT_FAILURE, 0, _("empty tab")); +- if (optarg[1]) ++ 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 (newtablen == 1 && newtab[1]) ++ { ++ if (STREQ (newtab, "\\0")) ++ newtab[0] = '\0'; ++ } ++ if (tab != NULL && strcmp (tab, newtab)) + { +- if (STREQ (optarg, "\\0")) +- newtab = '\0'; +- else +- error (EXIT_FAILURE, 0, _("multi-character tab %s"), +- quote (optarg)); ++ free (newtab); ++ error (EXIT_FAILURE, 0, _("incompatible tabs")); + } +- if (0 <= tab && tab != newtab) +- error (EXIT_FAILURE, 0, _("incompatible tabs")); + tab = newtab; ++ tablen = newtablen; + } + break; + +diff -urNp coreutils-8.0-orig/src/join.c.orig coreutils-8.0/src/join.c.orig +--- coreutils-8.0-orig/src/join.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/join.c.orig 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,1360 @@ ++/* join - join lines of two files on a common field ++ Copyright (C) 91, 1995-2006, 2008-2009 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 Mike Haertel, mike@gnu.ai.mit.edu. */ ++ ++#include ++ ++#include ++#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 "error.h" ++#include "hard-locale.h" ++#include "linebuffer.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" ++ ++#define AUTHORS proper_name ("Mike Haertel") ++ ++#define join system_join ++ ++#define SWAPLINES(a, b) do { \ ++ struct line *tmp = a; \ ++ a = b; \ ++ b = tmp; \ ++} while (0); ++ ++/* An element of the list identifying which fields to print for each ++ output line. */ ++struct outlist ++ { ++ /* File number: 0, 1, or 2. 0 means use the join field. ++ 1 means use the first file argument, 2 the second. */ ++ int file; ++ ++ /* Field index (zero-based), specified only when FILE is 1 or 2. */ ++ size_t field; ++ ++ struct outlist *next; ++ }; ++ ++/* A field of a line. */ ++struct field ++ { ++ char *beg; /* First character in field. */ ++ size_t len; /* The length of the field. */ ++ }; ++ ++/* A line read from an input file. */ ++struct line ++ { ++ struct linebuffer buf; /* The line itself. */ ++ size_t nfields; /* Number of elements in `fields'. */ ++ size_t nfields_allocated; /* Number of elements allocated for `fields'. */ ++ struct field *fields; ++ }; ++ ++/* One or more consecutive lines read from a file that all have the ++ same join field value. */ ++struct seq ++ { ++ size_t count; /* Elements used in `lines'. */ ++ size_t alloc; /* Elements allocated in `lines'. */ ++ struct line **lines; ++ }; ++ ++/* The previous line read from each file. */ ++static struct line *prevline[2] = {NULL, NULL}; ++ ++/* This provides an extra line buffer for each file. We need these if we ++ try to read two consecutive lines into the same buffer, since we don't ++ want to overwrite the previous buffer before we check order. */ ++static struct line *spareline[2] = {NULL, NULL}; ++ ++/* True if the LC_COLLATE locale is hard. */ ++static bool hard_LC_COLLATE; ++ ++/* If nonzero, print unpairable lines in file 1 or 2. */ ++static bool print_unpairables_1, print_unpairables_2; ++ ++/* If nonzero, print pairable lines. */ ++static bool print_pairables; ++ ++/* If nonzero, we have seen at least one unpairable line. */ ++static bool seen_unpairable; ++ ++/* If nonzero, we have warned about disorder in that file. */ ++static bool issued_disorder_warning[2]; ++ ++/* Empty output field filler. */ ++static char const *empty_filler; ++ ++/* Field to join on; SIZE_MAX means they haven't been determined yet. */ ++static size_t join_field_1 = SIZE_MAX; ++static size_t join_field_2 = SIZE_MAX; ++ ++/* List of fields to print. */ ++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 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 ++ { ++ CHECK_ORDER_DEFAULT, ++ CHECK_ORDER_ENABLED, ++ CHECK_ORDER_DISABLED ++ } check_input_order; ++ ++enum ++{ ++ CHECK_ORDER_OPTION = CHAR_MAX + 1, ++ NOCHECK_ORDER_OPTION ++}; ++ ++ ++static struct option const longopts[] = ++{ ++ {"ignore-case", no_argument, NULL, 'i'}, ++ {"check-order", no_argument, NULL, CHECK_ORDER_OPTION}, ++ {"nocheck-order", no_argument, NULL, NOCHECK_ORDER_OPTION}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++/* Used to print non-joining lines */ ++static struct line uni_blank; ++ ++/* If nonzero, ignore case when comparing join fields. */ ++static bool ignore_case; ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... FILE1 FILE2\n\ ++"), ++ program_name); ++ fputs (_("\ ++For each pair of input lines with identical join fields, write a line to\n\ ++standard output. The default join field is the first, delimited\n\ ++by whitespace. When FILE1 or FILE2 (not both) is -, read standard input.\n\ ++\n\ ++ -a FILENUM print unpairable lines coming from file FILENUM, where\n\ ++ FILENUM is 1 or 2, corresponding to FILE1 or FILE2\n\ ++ -e EMPTY replace missing input fields with EMPTY\n\ ++"), stdout); ++ fputs (_("\ ++ -i, --ignore-case ignore differences in case when comparing fields\n\ ++ -j FIELD equivalent to `-1 FIELD -2 FIELD'\n\ ++ -o FORMAT obey FORMAT while constructing output line\n\ ++ -t CHAR use CHAR as input and output field separator\n\ ++"), stdout); ++ fputs (_("\ ++ -v FILENUM like -a FILENUM, but suppress joined output lines\n\ ++ -1 FIELD join on this FIELD of file 1\n\ ++ -2 FIELD join on this FIELD of file 2\n\ ++ --check-order check that the input is correctly sorted, even\n\ ++ if all input lines are pairable\n\ ++ --nocheck-order do not check that the input is correctly sorted\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++Unless -t CHAR is given, leading blanks separate fields and are ignored,\n\ ++else fields are separated by CHAR. Any FIELD is a field number counted\n\ ++from 1. FORMAT is one or more comma or blank separated specifications,\n\ ++each being `FILENUM.FIELD' or `0'. Default FORMAT outputs the join field,\n\ ++the remaining fields from FILE1, the remaining fields from FILE2, all\n\ ++separated by CHAR.\n\ ++\n\ ++Important: FILE1 and FILE2 must be sorted on the join fields.\n\ ++E.g., use `sort -k 1b,1' if `join' has no options.\n\ ++Note, comparisons honor the rules specified by `LC_COLLATE'.\n\ ++If the input is not sorted and some lines cannot be joined, a\n\ ++warning message will be given.\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++/* Record a field in LINE, with location FIELD and size LEN. */ ++ ++static void ++extract_field (struct line *line, char *field, size_t len) ++{ ++ if (line->nfields >= line->nfields_allocated) ++ { ++ line->fields = X2NREALLOC (line->fields, &line->nfields_allocated); ++ } ++ line->fields[line->nfields].beg = field; ++ line->fields[line->nfields].len = len; ++ ++(line->nfields); ++} ++ ++/* Fill in the `fields' structure in LINE. */ ++ ++static void ++xfields (struct line *line) ++{ ++ char *ptr = line->buf.buffer; ++ char const *lim = ptr + line->buf.length - 1; ++ ++ if (ptr == lim) ++ return; ++ ++ if (tab != NULL) ++ { ++ unsigned char t = tab[0]; ++ char *sep; ++ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) ++ extract_field (line, ptr, sep - ptr); ++ } ++ else ++ { ++ /* Skip leading blanks before the first field. */ ++ while (isblank (to_uchar (*ptr))) ++ if (++ptr == lim) ++ return; ++ ++ do ++ { ++ char *sep; ++ for (sep = ptr + 1; sep != lim && ! isblank (to_uchar (*sep)); sep++) ++ continue; ++ extract_field (line, ptr, sep - ptr); ++ if (sep == lim) ++ return; ++ for (ptr = sep + 1; ptr != lim && isblank (to_uchar (*ptr)); ptr++) ++ continue; ++ } ++ while (ptr != lim); ++ } ++ ++ 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) ++ { ++ unsigned char t = tab[0]; ++ 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)) ++ 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)) ++ 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)) ++ break; ++ ++ ptr += mblength; ++ } ++ } ++ while (ptr < lim); ++ } ++ ++ extract_field (line, ptr, lim - ptr); ++} ++#endif ++ ++static void ++freeline (struct line *line) ++{ ++ free (line->fields); ++ free (line->buf.buffer); ++ line->buf.buffer = NULL; ++} ++ ++/* Return <0 if the join field in LINE1 compares less than the one in LINE2; ++ >0 if it compares greater; 0 if it compares equal. ++ Report an error and exit if the comparison fails. ++ Use join fields JF_1 and JF_2 respectively. */ ++ ++static int ++keycmp (struct line const *line1, struct line const *line2, ++ size_t jf_1, size_t jf_2) ++{ ++ /* Start of field to compare in each file. */ ++ char *beg[2]; ++ char *copy[2]; ++ size_t len[2]; /* Length of fields to compare. */ ++ int diff; ++ int i, j; ++ ++ if (jf_1 < line1->nfields) ++ { ++ beg[0] = line1->fields[jf_1].beg; ++ len[0] = line1->fields[jf_1].len; ++ } ++ else ++ { ++ beg[0] = NULL; ++ len[0] = 0; ++ } ++ ++ if (jf_2 < line2->nfields) ++ { ++ beg[1] = line2->fields[jf_2].beg; ++ len[1] = line2->fields[jf_2].len; ++ } ++ else ++ { ++ beg[1] = NULL; ++ len[1] = 0; ++ } ++ ++ if (len[0] == 0) ++ return len[1] == 0 ? 0 : -1; ++ if (len[1] == 0) ++ return 1; ++ ++ if (ignore_case) ++ { ++#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++) ++ { ++ copy[i] = alloca (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; ++ ++ memset (&state_wc, '\0', sizeof (mbstate_t)); ++ wcrtomb (copy[i] + j, uwc, &state_wc); ++ } ++ else ++ memcpy (copy[i] + j, beg[i] + j, mblength); ++ } ++ j += mblength; ++ } ++ copy[i][j] = '\0'; ++ } ++ } ++ else ++#endif ++ { ++ for (i = 0; i < 2; i++) ++ { ++ copy[i] = alloca (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 ++ { ++ copy[0] = (unsigned char *) beg[0]; ++ copy[1] = (unsigned char *) beg[1]; ++ } ++ ++ if (hard_LC_COLLATE) ++ return xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); ++ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); ++ ++ ++ if (diff) ++ return diff; ++ return len[0] - len[1]; ++} ++ ++/* Check that successive input lines PREV and CURRENT from input file ++ WHATFILE are presented in order, unless the user may be relying on ++ the GNU extension that input lines may be out of order if no input ++ lines are unpairable. ++ ++ If the user specified --nocheck-order, the check is not made. ++ If the user specified --check-order, the problem is fatal. ++ Otherwise (the default), the message is simply a warning. ++ ++ A message is printed at most once per input file. */ ++ ++static void ++check_order (const struct line *prev, ++ const struct line *current, ++ int whatfile) ++{ ++ if (check_input_order != CHECK_ORDER_DISABLED ++ && ((check_input_order == CHECK_ORDER_ENABLED) || seen_unpairable)) ++ { ++ if (!issued_disorder_warning[whatfile-1]) ++ { ++ size_t join_field = whatfile == 1 ? join_field_1 : join_field_2; ++ if (keycmp (prev, current, join_field, join_field) > 0) ++ { ++ error ((check_input_order == CHECK_ORDER_ENABLED ++ ? EXIT_FAILURE : 0), ++ 0, _("file %d is not in sorted order"), whatfile); ++ ++ /* If we get to here, the message was just a warning, but we ++ want only to issue it once. */ ++ issued_disorder_warning[whatfile-1] = true; ++ } ++ } ++ } ++} ++ ++static inline void ++reset_line (struct line *line) ++{ ++ line->nfields = 0; ++} ++ ++static struct line * ++init_linep (struct line **linep) ++{ ++ struct line *line = xmalloc (sizeof *line); ++ memset (line, '\0', sizeof *line); ++ *linep = line; ++ return line; ++} ++ ++/* Read a line from FP into LINE and split it into fields. ++ Return true if successful. */ ++ ++static bool ++get_line (FILE *fp, struct line **linep, int which) ++{ ++ struct line *line = *linep; ++ ++ if (line == prevline[which - 1]) ++ { ++ SWAPLINES (line, spareline[which - 1]); ++ *linep = line; ++ } ++ ++ if (line) ++ reset_line (line); ++ else ++ line = init_linep (linep); ++ ++ if (! readlinebuffer (&line->buf, fp)) ++ { ++ if (ferror (fp)) ++ error (EXIT_FAILURE, errno, _("read error")); ++ freeline (line); ++ return false; ++ } ++ ++ xfields (line); ++ ++ if (prevline[which - 1]) ++ check_order (prevline[which - 1], line, which); ++ ++ prevline[which - 1] = line; ++ return true; ++} ++ ++static void ++free_spareline (void) ++{ ++ size_t i; ++ ++ for (i = 0; i < ARRAY_CARDINALITY (spareline); i++) ++ { ++ if (spareline[i]) ++ { ++ freeline (spareline[i]); ++ free (spareline[i]); ++ } ++ } ++} ++ ++static void ++initseq (struct seq *seq) ++{ ++ seq->count = 0; ++ seq->alloc = 0; ++ seq->lines = NULL; ++} ++ ++/* Read a line from FP and add it to SEQ. Return true if successful. */ ++ ++static bool ++getseq (FILE *fp, struct seq *seq, int whichfile) ++{ ++ if (seq->count == seq->alloc) ++ { ++ size_t i; ++ seq->lines = X2NREALLOC (seq->lines, &seq->alloc); ++ for (i = seq->count; i < seq->alloc; i++) ++ seq->lines[i] = NULL; ++ } ++ ++ if (get_line (fp, &seq->lines[seq->count], whichfile)) ++ { ++ ++seq->count; ++ return true; ++ } ++ return false; ++} ++ ++/* Read a line from FP and add it to SEQ, as the first item if FIRST is ++ true, else as the next. */ ++static bool ++advance_seq (FILE *fp, struct seq *seq, bool first, int whichfile) ++{ ++ if (first) ++ seq->count = 0; ++ ++ return getseq (fp, seq, whichfile); ++} ++ ++static void ++delseq (struct seq *seq) ++{ ++ size_t i; ++ for (i = 0; i < seq->alloc; i++) ++ if (seq->lines[i]) ++ { ++ if (seq->lines[i]->buf.buffer) ++ freeline (seq->lines[i]); ++ free (seq->lines[i]); ++ } ++ free (seq->lines); ++} ++ ++ ++/* Print field N of LINE if it exists and is nonempty, otherwise ++ `empty_filler' if it is nonempty. */ ++ ++static void ++prfield (size_t n, struct line const *line) ++{ ++ size_t len; ++ ++ if (n < line->nfields) ++ { ++ len = line->fields[n].len; ++ if (len) ++ fwrite (line->fields[n].beg, 1, len, stdout); ++ else if (empty_filler) ++ fputs (empty_filler, stdout); ++ } ++ else if (empty_filler) ++ fputs (empty_filler, stdout); ++} ++ ++/* Print the join of LINE1 and LINE2. */ ++ ++#define PUT_TAB_CHAR \ ++ do \ ++ { \ ++ (tab != NULL) ? \ ++ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ ++ } \ ++ while (0) ++ ++static void ++prjoin (struct line const *line1, struct line const *line2) ++{ ++ const struct outlist *outlist; ++ ++ outlist = outlist_head.next; ++ if (outlist) ++ { ++ const struct outlist *o; ++ ++ o = outlist; ++ while (1) ++ { ++ size_t field; ++ struct line const *line; ++ ++ if (o->file == 0) ++ { ++ if (line1 == &uni_blank) ++ { ++ line = line2; ++ field = join_field_2; ++ } ++ else ++ { ++ line = line1; ++ field = join_field_1; ++ } ++ } ++ else ++ { ++ line = (o->file == 1 ? line1 : line2); ++ field = o->field; ++ } ++ prfield (field, line); ++ o = o->next; ++ if (o == NULL) ++ break; ++ PUT_TAB_CHAR; ++ } ++ putchar ('\n'); ++ } ++ else ++ { ++ size_t i; ++ ++ if (line1 == &uni_blank) ++ { ++ struct line const *t; ++ t = line1; ++ line1 = line2; ++ line2 = t; ++ } ++ prfield (join_field_1, line1); ++ for (i = 0; i < join_field_1 && i < line1->nfields; ++i) ++ { ++ PUT_TAB_CHAR; ++ prfield (i, line1); ++ } ++ for (i = join_field_1 + 1; i < line1->nfields; ++i) ++ { ++ PUT_TAB_CHAR; ++ prfield (i, line1); ++ } ++ ++ for (i = 0; i < join_field_2 && i < line2->nfields; ++i) ++ { ++ PUT_TAB_CHAR; ++ prfield (i, line2); ++ } ++ for (i = join_field_2 + 1; i < line2->nfields; ++i) ++ { ++ PUT_TAB_CHAR; ++ prfield (i, line2); ++ } ++ putchar ('\n'); ++ } ++} ++ ++/* Print the join of the files in FP1 and FP2. */ ++ ++static void ++join (FILE *fp1, FILE *fp2) ++{ ++ struct seq seq1, seq2; ++ struct line **linep = xmalloc (sizeof *linep); ++ int diff; ++ bool eof1, eof2, checktail; ++ ++ *linep = NULL; ++ ++ /* Read the first line of each file. */ ++ initseq (&seq1); ++ getseq (fp1, &seq1, 1); ++ initseq (&seq2); ++ getseq (fp2, &seq2, 2); ++ ++ while (seq1.count && seq2.count) ++ { ++ size_t i; ++ diff = keycmp (seq1.lines[0], seq2.lines[0], ++ join_field_1, join_field_2); ++ if (diff < 0) ++ { ++ if (print_unpairables_1) ++ prjoin (seq1.lines[0], &uni_blank); ++ advance_seq (fp1, &seq1, true, 1); ++ seen_unpairable = true; ++ continue; ++ } ++ if (diff > 0) ++ { ++ if (print_unpairables_2) ++ prjoin (&uni_blank, seq2.lines[0]); ++ advance_seq (fp2, &seq2, true, 2); ++ seen_unpairable = true; ++ continue; ++ } ++ ++ /* Keep reading lines from file1 as long as they continue to ++ match the current line from file2. */ ++ eof1 = false; ++ do ++ if (!advance_seq (fp1, &seq1, false, 1)) ++ { ++ eof1 = true; ++ ++seq1.count; ++ break; ++ } ++ while (!keycmp (seq1.lines[seq1.count - 1], seq2.lines[0], ++ join_field_1, join_field_2)); ++ ++ /* Keep reading lines from file2 as long as they continue to ++ match the current line from file1. */ ++ eof2 = false; ++ do ++ if (!advance_seq (fp2, &seq2, false, 2)) ++ { ++ eof2 = true; ++ ++seq2.count; ++ break; ++ } ++ while (!keycmp (seq1.lines[0], seq2.lines[seq2.count - 1], ++ join_field_1, join_field_2)); ++ ++ if (print_pairables) ++ { ++ for (i = 0; i < seq1.count - 1; ++i) ++ { ++ size_t j; ++ for (j = 0; j < seq2.count - 1; ++j) ++ prjoin (seq1.lines[i], seq2.lines[j]); ++ } ++ } ++ ++ if (!eof1) ++ { ++ SWAPLINES (seq1.lines[0], seq1.lines[seq1.count - 1]); ++ seq1.count = 1; ++ } ++ else ++ seq1.count = 0; ++ ++ if (!eof2) ++ { ++ SWAPLINES (seq2.lines[0], seq2.lines[seq2.count - 1]); ++ seq2.count = 1; ++ } ++ else ++ seq2.count = 0; ++ } ++ ++ /* If the user did not specify --check-order, and the we read the ++ tail ends of both inputs to verify that they are in order. We ++ skip the rest of the tail once we have issued a warning for that ++ file, unless we actually need to print the unpairable lines. */ ++ if (check_input_order != CHECK_ORDER_DISABLED ++ && !(issued_disorder_warning[0] && issued_disorder_warning[1])) ++ checktail = true; ++ else ++ checktail = false; ++ ++ if ((print_unpairables_1 || checktail) && seq1.count) ++ { ++ if (print_unpairables_1) ++ prjoin (seq1.lines[0], &uni_blank); ++ seen_unpairable = true; ++ while (get_line (fp1, linep, 1)) ++ { ++ if (print_unpairables_1) ++ prjoin (*linep, &uni_blank); ++ if (issued_disorder_warning[0] && !print_unpairables_1) ++ break; ++ } ++ } ++ ++ if ((print_unpairables_2 || checktail) && seq2.count) ++ { ++ if (print_unpairables_2) ++ prjoin (&uni_blank, seq2.lines[0]); ++ seen_unpairable = true; ++ while (get_line (fp2, linep, 2)) ++ { ++ if (print_unpairables_2) ++ prjoin (&uni_blank, *linep); ++ if (issued_disorder_warning[1] && !print_unpairables_2) ++ break; ++ } ++ } ++ ++ free (*linep); ++ ++ free (linep); ++ delseq (&seq1); ++ delseq (&seq2); ++} ++ ++/* Add a field spec for field FIELD of file FILE to `outlist'. */ ++ ++static void ++add_field (int file, size_t field) ++{ ++ struct outlist *o; ++ ++ assert (file == 0 || file == 1 || file == 2); ++ assert (file != 0 || field == 0); ++ ++ o = xmalloc (sizeof *o); ++ o->file = file; ++ o->field = field; ++ o->next = NULL; ++ ++ /* Add to the end of the list so the fields are in the right order. */ ++ outlist_end->next = o; ++ outlist_end = o; ++} ++ ++/* Convert a string of decimal digits, STR (the 1-based join field number), ++ to an integral value. Upon successful conversion, return one less ++ (the zero-based field number). Silently convert too-large values ++ to SIZE_MAX - 1. Otherwise, if a value cannot be converted, give a ++ diagnostic and exit. */ ++ ++static size_t ++string_to_join_field (char const *str) ++{ ++ size_t result; ++ unsigned long int val; ++ verify (SIZE_MAX <= ULONG_MAX); ++ ++ strtol_error s_err = xstrtoul (str, NULL, 10, &val, ""); ++ if (s_err == LONGINT_OVERFLOW || (s_err == LONGINT_OK && SIZE_MAX < val)) ++ val = SIZE_MAX; ++ else if (s_err != LONGINT_OK || val == 0) ++ error (EXIT_FAILURE, 0, _("invalid field number: %s"), quote (str)); ++ ++ result = val - 1; ++ ++ return result; ++} ++ ++/* Convert a single field specifier string, S, to a *FILE_INDEX, *FIELD_INDEX ++ pair. In S, the field index string is 1-based; *FIELD_INDEX is zero-based. ++ If S is valid, return true. Otherwise, give a diagnostic and exit. */ ++ ++static void ++decode_field_spec (const char *s, int *file_index, size_t *field_index) ++{ ++ /* The first character must be 0, 1, or 2. */ ++ switch (s[0]) ++ { ++ case '0': ++ if (s[1]) ++ { ++ /* `0' must be all alone -- no `.FIELD'. */ ++ error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s)); ++ } ++ *file_index = 0; ++ *field_index = 0; ++ break; ++ ++ case '1': ++ case '2': ++ if (s[1] != '.') ++ error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s)); ++ *file_index = s[0] - '0'; ++ *field_index = string_to_join_field (s + 2); ++ break; ++ ++ default: ++ error (EXIT_FAILURE, 0, ++ _("invalid file number in field spec: %s"), quote (s)); ++ ++ /* Tell gcc -W -Wall that we can't get beyond this point. ++ This avoids a warning (otherwise legit) that the caller's copies ++ of *file_index and *field_index might be used uninitialized. */ ++ abort (); ++ ++ break; ++ } ++} ++ ++/* Add the comma or blank separated field spec(s) in STR to `outlist'. */ ++ ++static void ++add_field_list (char *str) ++{ ++ char *p = str; ++ ++ do ++ { ++ int file_index; ++ size_t field_index; ++ char const *spec_item = p; ++ ++ p = strpbrk (p, ", \t"); ++ if (p) ++ *p++ = '\0'; ++ decode_field_spec (spec_item, &file_index, &field_index); ++ add_field (file_index, field_index); ++ } ++ while (p); ++} ++ ++/* Set the join field *VAR to VAL, but report an error if *VAR is set ++ more than once to incompatible values. */ ++ ++static void ++set_join_field (size_t *var, size_t val) ++{ ++ if (*var != SIZE_MAX && *var != val) ++ { ++ unsigned long int var1 = *var + 1; ++ unsigned long int val1 = val + 1; ++ error (EXIT_FAILURE, 0, _("incompatible join fields %lu, %lu"), ++ var1, val1); ++ } ++ *var = val; ++} ++ ++/* Status of command-line arguments. */ ++ ++enum operand_status ++ { ++ /* This argument must be an operand, i.e., one of the files to be ++ joined. */ ++ MUST_BE_OPERAND, ++ ++ /* This might be the argument of the preceding -j1 or -j2 option, ++ or it might be an operand. */ ++ MIGHT_BE_J1_ARG, ++ MIGHT_BE_J2_ARG, ++ ++ /* This might be the argument of the preceding -o option, or it might be ++ an operand. */ ++ MIGHT_BE_O_ARG ++ }; ++ ++/* Add NAME to the array of input file NAMES with operand statuses ++ OPERAND_STATUS; currently there are NFILES names in the list. */ ++ ++static void ++add_file_name (char *name, char *names[2], ++ int operand_status[2], int joption_count[2], int *nfiles, ++ int *prev_optc_status, int *optc_status) ++{ ++ int n = *nfiles; ++ ++ if (n == 2) ++ { ++ bool op0 = (operand_status[0] == MUST_BE_OPERAND); ++ char *arg = names[op0]; ++ switch (operand_status[op0]) ++ { ++ case MUST_BE_OPERAND: ++ error (0, 0, _("extra operand %s"), quote (name)); ++ usage (EXIT_FAILURE); ++ ++ case MIGHT_BE_J1_ARG: ++ joption_count[0]--; ++ set_join_field (&join_field_1, string_to_join_field (arg)); ++ break; ++ ++ case MIGHT_BE_J2_ARG: ++ joption_count[1]--; ++ set_join_field (&join_field_2, string_to_join_field (arg)); ++ break; ++ ++ case MIGHT_BE_O_ARG: ++ add_field_list (arg); ++ break; ++ } ++ if (!op0) ++ { ++ operand_status[0] = operand_status[1]; ++ names[0] = names[1]; ++ } ++ n = 1; ++ } ++ ++ operand_status[n] = *prev_optc_status; ++ names[n] = name; ++ *nfiles = n + 1; ++ if (*prev_optc_status == MIGHT_BE_O_ARG) ++ *optc_status = MIGHT_BE_O_ARG; ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int optc_status; ++ int prev_optc_status = MUST_BE_OPERAND; ++ int operand_status[2]; ++ int joption_count[2] = { 0, 0 }; ++ char *names[2]; ++ FILE *fp1, *fp2; ++ int optc; ++ int nfiles = 0; ++ int i; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ hard_LC_COLLATE = hard_locale (LC_COLLATE); ++ ++ atexit (close_stdout); ++ atexit (free_spareline); ++ ++ print_pairables = true; ++ seen_unpairable = false; ++ issued_disorder_warning[0] = issued_disorder_warning[1] = false; ++ check_input_order = CHECK_ORDER_DEFAULT; ++ ++ while ((optc = getopt_long (argc, argv, "-a:e:i1:2:j:o:t:v:", ++ longopts, NULL)) ++ != -1) ++ { ++ optc_status = MUST_BE_OPERAND; ++ ++ switch (optc) ++ { ++ case 'v': ++ print_pairables = false; ++ /* Fall through. */ ++ ++ case 'a': ++ { ++ unsigned long int val; ++ if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK ++ || (val != 1 && val != 2)) ++ error (EXIT_FAILURE, 0, ++ _("invalid field number: %s"), quote (optarg)); ++ if (val == 1) ++ print_unpairables_1 = true; ++ else ++ print_unpairables_2 = true; ++ } ++ break; ++ ++ case 'e': ++ if (empty_filler && ! STREQ (empty_filler, optarg)) ++ error (EXIT_FAILURE, 0, ++ _("conflicting empty-field replacement strings")); ++ empty_filler = optarg; ++ break; ++ ++ case 'i': ++ ignore_case = true; ++ break; ++ ++ case '1': ++ set_join_field (&join_field_1, string_to_join_field (optarg)); ++ break; ++ ++ case '2': ++ set_join_field (&join_field_2, string_to_join_field (optarg)); ++ break; ++ ++ case 'j': ++ if ((optarg[0] == '1' || optarg[0] == '2') && !optarg[1] ++ && optarg == argv[optind - 1] + 2) ++ { ++ /* The argument was either "-j1" or "-j2". */ ++ bool is_j2 = (optarg[0] == '2'); ++ joption_count[is_j2]++; ++ optc_status = MIGHT_BE_J1_ARG + is_j2; ++ } ++ else ++ { ++ set_join_field (&join_field_1, string_to_join_field (optarg)); ++ set_join_field (&join_field_2, join_field_1); ++ } ++ break; ++ ++ case 'o': ++ add_field_list (optarg); ++ optc_status = MIGHT_BE_O_ARG; ++ break; ++ ++ case 't': ++ { ++ char *newtab; ++ size_t newtablen; ++ if (! optarg[0]) ++ error (EXIT_FAILURE, 0, _("empty tab")); ++ 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 (newtablen == 1 && newtab[1]) ++ { ++ if (STREQ (newtab, "\\0")) ++ newtab[0] = '\0'; ++ } ++ if (tab != NULL && strcmp (tab, newtab)) ++ { ++ free (newtab); ++ error (EXIT_FAILURE, 0, _("incompatible tabs")); ++ } ++ tab = newtab; ++ tablen = newtablen; ++ } ++ break; ++ ++ case NOCHECK_ORDER_OPTION: ++ check_input_order = CHECK_ORDER_DISABLED; ++ break; ++ ++ case CHECK_ORDER_OPTION: ++ check_input_order = CHECK_ORDER_ENABLED; ++ break; ++ ++ case 1: /* Non-option argument. */ ++ add_file_name (optarg, names, operand_status, joption_count, ++ &nfiles, &prev_optc_status, &optc_status); ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (EXIT_FAILURE); ++ } ++ ++ prev_optc_status = optc_status; ++ } ++ ++ /* Process any operands after "--". */ ++ prev_optc_status = MUST_BE_OPERAND; ++ while (optind < argc) ++ add_file_name (argv[optind++], names, operand_status, joption_count, ++ &nfiles, &prev_optc_status, &optc_status); ++ ++ if (nfiles != 2) ++ { ++ if (nfiles == 0) ++ error (0, 0, _("missing operand")); ++ else ++ error (0, 0, _("missing operand after %s"), quote (argv[argc - 1])); ++ usage (EXIT_FAILURE); ++ } ++ ++ /* If "-j1" was specified and it turns out not to have had an argument, ++ treat it as "-j 1". Likewise for -j2. */ ++ for (i = 0; i < 2; i++) ++ if (joption_count[i] != 0) ++ { ++ set_join_field (&join_field_1, i); ++ set_join_field (&join_field_2, i); ++ } ++ ++ if (join_field_1 == SIZE_MAX) ++ join_field_1 = 0; ++ if (join_field_2 == SIZE_MAX) ++ join_field_2 = 0; ++ ++ fp1 = STREQ (names[0], "-") ? stdin : fopen (names[0], "r"); ++ if (!fp1) ++ error (EXIT_FAILURE, errno, "%s", names[0]); ++ fp2 = STREQ (names[1], "-") ? stdin : fopen (names[1], "r"); ++ if (!fp2) ++ error (EXIT_FAILURE, errno, "%s", names[1]); ++ if (fp1 == fp2) ++ error (EXIT_FAILURE, errno, _("both files cannot be standard input")); ++ join (fp1, fp2); ++ ++ if (fclose (fp1) != 0) ++ error (EXIT_FAILURE, errno, "%s", names[0]); ++ if (fclose (fp2) != 0) ++ error (EXIT_FAILURE, errno, "%s", names[1]); ++ ++ if (issued_disorder_warning[0] || issued_disorder_warning[1]) ++ exit (EXIT_FAILURE); ++ else ++ exit (EXIT_SUCCESS); ++} +diff -urNp coreutils-8.0-orig/src/pr.c coreutils-8.0/src/pr.c +--- coreutils-8.0-orig/src/pr.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/pr.c 2009-10-07 10:07:16.000000000 +0200 +@@ -312,6 +312,32 @@ + + #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 ++ ++/* Get iswprint(). -- for wcwidth(). */ ++#if HAVE_WCTYPE_H ++# include ++#endif ++#if !defined iswprint && !HAVE_ISWPRINT ++# define iswprint(wc) 1 ++#endif ++ + #include "system.h" + #include "error.h" + #include "hard-locale.h" +@@ -322,6 +348,18 @@ + #include "strftime.h" + #include "xstrtol.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" + +@@ -414,7 +452,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); +@@ -424,6 +475,7 @@ static void print_header (void); + static void pad_across_to (int position); + static void add_line_number (COLUMN *p); + static void getoptarg (char *arg, char switch_char, char *character, ++ int *character_length, int *character_width, + int *number); + void usage (int status); + static void print_files (int number_of_files, char **av); +@@ -438,7 +490,6 @@ static void store_char (char c); + static void pad_down (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); +@@ -450,7 +501,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. */ +@@ -554,7 +605,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. */ +@@ -564,7 +615,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 +692,13 @@ static int power_10; + 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 +751,7 @@ static bool use_col_separator = false; + -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ + static char *col_sep_string = (char *) ""; + static int col_sep_length = 0; ++static int col_sep_width = 0; + static char *column_separator = (char *) " "; + static char *line_separator = (char *) "\t"; + +@@ -847,6 +908,13 @@ separator_string (const char *optarg_S) + col_sep_length = (int) strlen (optarg_S); + col_sep_string = xmalloc (col_sep_length + 1); + strcpy (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 +@@ -871,6 +939,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 + ? xmalloc ((argc - 1) * sizeof (char *)) +@@ -947,8 +1030,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; +@@ -961,8 +1048,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; +@@ -989,8 +1080,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; +@@ -1029,7 +1120,7 @@ main (int argc, char **argv) + old_s = false; + /* Reset an additional input of -s, -S dominates -s */ + col_sep_string = bad_cast (""); +- col_sep_length = 0; ++ col_sep_length = col_sep_width = 0; + use_col_separator = true; + if (optarg) + separator_string (optarg); +@@ -1186,10 +1277,45 @@ main (int argc, char **argv) + 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; +@@ -1248,7 +1374,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 +@@ -1279,11 +1405,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. */ +@@ -1298,7 +1424,7 @@ init_parameters (int number_of_files) + } + + chars_per_column = (chars_per_line - chars_used_by_number - +- (columns - 1) * col_sep_length) / columns; ++ (columns - 1) * col_sep_width) / columns; + + if (chars_per_column < 1) + error (EXIT_FAILURE, 0, _("page width too narrow")); +@@ -1423,7 +1549,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. */ + +@@ -1457,7 +1583,7 @@ init_funcs (void) + } + else + { +- h = h_next + col_sep_length; ++ h = h_next + col_sep_width; + h_next = h + chars_per_column; + } + } +@@ -1747,9 +1873,9 @@ static void + align_column (COLUMN *p) + { + padding_not_printed = p->start_position; +- if (padding_not_printed - col_sep_length > 0) ++ if (padding_not_printed - col_sep_width > 0) + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } + +@@ -2020,13 +2146,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 left_cut; + +@@ -2049,22 +2175,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); + } +@@ -2225,7 +2353,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) +@@ -2245,6 +2373,7 @@ print_sep_string (void) + { + char *s; + int l = col_sep_length; ++ int not_space_flag; + + s = col_sep_string; + +@@ -2258,6 +2387,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, +@@ -2271,12 +2401,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 (); +@@ -2304,7 +2437,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) + { +@@ -2328,6 +2461,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. */ + +@@ -2507,9 +2708,9 @@ read_line (COLUMN *p) + align_empty_cols = false; + } + +- if (padding_not_printed - col_sep_length > 0) ++ if (padding_not_printed - col_sep_width > 0) + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } + +@@ -2610,9 +2811,9 @@ print_stored (COLUMN *p) + } + } + +- if (padding_not_printed - col_sep_length > 0) ++ if (padding_not_printed - col_sep_width > 0) + { +- pad_across_to (padding_not_printed - col_sep_length); ++ pad_across_to (padding_not_printed - col_sep_width); + padding_not_printed = ANYWHERE; + } + +@@ -2625,8 +2826,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; +@@ -2645,7 +2846,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; +@@ -2655,10 +2856,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); + +@@ -2739,6 +2940,154 @@ 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", 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", c); ++ 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", c); ++ 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; ++ } ++ ++ 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. + +diff -urNp coreutils-8.0-orig/src/pr.c.orig coreutils-8.0/src/pr.c.orig +--- coreutils-8.0-orig/src/pr.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/pr.c.orig 2009-09-29 15:27:54.000000000 +0200 +@@ -0,0 +1,2877 @@ ++/* pr -- convert text files for printing. ++ Copyright (C) 88, 91, 1995-2009 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 . */ ++ ++/* By Pete TerMaat, with considerable refinement by Roland Huebner. */ ++ ++/* Things to watch: Sys V screws up on ... ++ pr -n -3 -s: /usr/dict/words ++ pr -m -o10 -n /usr/dict/words{,,,} ++ pr -6 -a -n -o5 /usr/dict/words ++ ++ Ideas: ++ ++ Keep a things_to_do list of functions to call when we know we have ++ something to print. Cleaner than current series of checks. ++ ++ Improve the printing of control prefixes. ++ ++ Expand the file name in the centered header line to a full file name. ++ ++ ++ Concept: ++ ++ If the input_tab_char differs from the default value TAB ++ (`-e[CHAR[...]]' is used), any input text tab is expanded to the ++ default width of 8 spaces (compare char_to_clump). - Same as SunOS ++ does. ++ ++ The treatment of the number_separator (compare add_line_number): ++ The default value TAB of the number_separator (`-n[SEP[...]]') doesn't ++ be thought to be an input character. An optional `-e'-input has no ++ effect. ++ - With single column output ++ only one POSIX requirement has to be met: ++ The default n-separator should be a TAB. The consequence is a ++ different width between the number and the text if the output position ++ of the separator changes, i.e. it depends upon the left margin used. ++ That's not nice but easy-to-use together with the defaults of other ++ utilities, e.g. sort or cut. - Same as SunOS does. ++ - With multicolumn output ++ two conflicting POSIX requirements exist: ++ First `default n-separator is TAB', second `output text columns shall ++ be of equal width'. Moreover POSIX specifies the number+separator a ++ part of the column, together with `-COLUMN' and `-a -COLUMN'. ++ (With -m output the number shall occupy each line only once. Exactly ++ the same situation as single column output exists.) ++ GNU pr gives priority to the 2nd requirement and observes POSIX ++ column definition. The n-separator TAB is expanded to the same number ++ of spaces in each column using the default value 8. Tabification is ++ only performed if it is compatible with the output position. ++ Consequence: The output text columns are of equal width. The layout ++ of a page does not change if the left margin varies. - Looks better ++ than the SunOS approach. ++ SunOS pr gives priority to the 1st requirement. n-separator TAB ++ width varies with each column. Only the width of text part of the ++ column is fixed. ++ Consequence: The output text columns don't have equal width. The ++ widths and the layout of the whole page varies with the left margin. ++ An overflow of the line length (without margin) over the input value ++ PAGE_WIDTH may occur. ++ ++ The interference of the POSIX-compliant small letter options -w and -s: ++ (`interference' means `setting a _separator_ with -s switches off the ++ column structure and the default - not generally - page_width, ++ acts on -w option') ++ options: text form / separator: equivalent new options: ++ -w l -s[x] ++ -------------------------------------------------------------------- ++ 1. -- -- columns / space -- ++ trunc. to page_width = 72 ++ 2. -- -s[:] full lines / TAB[:] -J --sep-string[=""|:] ++ no truncation ++ 3. -w l -- columns / space -W l ++ trunc. to page_width = l ++ 4. -w l -s[:] columns / no sep.[:] -W l --sep-string[=:] ++ trunc. to page_width = l ++ -------------------------------------------------------------------- ++ ++ ++ Options: ++ ++ Including version 1.22i: ++ Some SMALL LETTER options have been redefined with the object of a ++ better POSIX compliance. The output of some further cases has been ++ adapted to other UNIXes. A violation of downward compatibility has to ++ be accepted. ++ Some NEW CAPITAL LETTER options ( -J, -S, -W) has been introduced to ++ turn off unexpected interferences of small letter options (-s and -w ++ together with the three column options). ++ -N option and the second argument LAST_PAGE of +FIRST_PAGE offer more ++ flexibility; The detailed handling of form feeds set in the input ++ files requires -T option. ++ ++ Capital letter options dominate small letter ones. ++ ++ Some of the option-arguments cannot be specified as separate arguments ++ from the preceding option letter (already stated in POSIX specification). ++ ++ Form feeds in the input cause page breaks in the output. Multiple ++ form feeds produce empty pages. ++ ++ +FIRST_PAGE[:LAST_PAGE], --pages=FIRST_PAGE[:LAST_PAGE] ++ begin [stop] printing with page FIRST_[LAST_]PAGE ++ ++ -COLUMN, --columns=COLUMN ++ Produce output that is COLUMN columns wide and ++ print columns down, unless -a is used. Balance number of ++ lines in the columns on each page. ++ ++ -a, --across Print columns across rather than down, used ++ together with -COLUMN. The input ++ one ++ two ++ three ++ four ++ will be printed with `-a -3' as ++ one two three ++ four ++ ++ -b Balance columns on the last page. ++ -b is no longer an independent option. It's always used ++ together with -COLUMN (unless -a is used) to get a ++ consistent formulation with "FF set by hand" in input ++ files. Each formfeed found terminates the number of lines ++ to be read with the actual page. The situation for ++ printing columns down is equivalent to that on the last ++ page. So we need a balancing. ++ ++ Keeping -b as an underground option guarantees some ++ downward compatibility. Utilities using pr with -b ++ (a most frequently used form) still work as usual. ++ ++ -c, --show-control-chars ++ Print unprintable characters as control prefixes. ++ Control-g is printed as ^G (use hat notation) and ++ octal backslash notation. ++ ++ -d, --double-space Double space the output. ++ ++ -D FORMAT, --date-format=FORMAT Use FORMAT for the header date. ++ ++ -e[CHAR[WIDTH]], --expand-tabs[=CHAR[WIDTH]] ++ Expand tabs to spaces on input. Optional argument CHAR ++ is the input TAB character. (Default is TAB). Optional ++ argument WIDTH is the input TAB character's width. ++ (Default is 8.) ++ ++ -F, -f, --form-feed Use formfeeds instead of newlines to separate ++ pages. A three line HEADER is used, no TRAILER with -F, ++ without -F both HEADER and TRAILER are made of five lines. ++ ++ -h HEADER, --header=HEADER ++ Replace the filename in the header with the string HEADER. ++ A centered header is used. ++ ++ -i[CHAR[WIDTH]], --output-tabs[=CHAR[WIDTH]] ++ Replace spaces with tabs on output. Optional argument ++ CHAR is the output TAB character. (Default is TAB). ++ Optional argument WIDTH is the output TAB character's ++ width. (Default is 8) ++ ++ -J, --join-lines Merge lines of full length, turns off -W/-w ++ line truncation, no column alignment, --sep-string[=STRING] ++ sets separators, works with all column options ++ (-COLUMN | -a -COLUMN | -m). ++ -J has been introduced (together with -W and --sep-string) to ++ disentangle the old (POSIX compliant) options -w, -s ++ along with the 3 column options. ++ ++ -l PAGE_LENGTH, --length=PAGE_LENGTH ++ Set the page length to PAGE_LENGTH lines. Default is 66, ++ including 5 lines of HEADER and 5 lines of TRAILER ++ without -F, but only 3 lines of HEADER and no TRAILER ++ with -F (i.e the number of text lines defaults to 56 or ++ 63 respectively). ++ ++ -m, --merge Print files in parallel; pad_across_to align ++ columns; truncate lines and print separator strings; ++ Do it also with empty columns to get a continuous line ++ numbering and column marking by separators throughout ++ the whole merged file. ++ ++ Empty pages in some input files produce empty columns ++ [marked by separators] in the merged pages. Completely ++ empty merged pages show no column separators at all. ++ ++ The layout of a merged page is ruled by the largest form ++ feed distance of the single pages at that page. Shorter ++ columns will be filled up with empty lines. ++ ++ Together with -J option join lines of full length and ++ set separators when -S option is used. ++ ++ -n[SEP[DIGITS]], --number-lines[=SEP[DIGITS]] ++ Provide DIGITS digit line numbering (default for DIGITS ++ is 5). With multicolumn output the number occupies the ++ first DIGITS column positions of each text column or only ++ each line of -m output. ++ With single column output the number precedes each line ++ just as -m output. ++ Optional argument SEP is the character appended to the ++ line number to separate it from the text followed. ++ The default separator is a TAB. In a strict sense a TAB ++ is always printed with single column output only. The ++ TAB-width varies with the TAB-position, e.g. with the ++ left margin specified by -o option. ++ With multicolumn output priority is given to `equal width ++ of output columns' (a POSIX specification). The TAB-width ++ is fixed to the value of the 1st column and does not ++ change with different values of left margin. That means a ++ fixed number of spaces is always printed in the place of ++ a TAB. The tabification depends upon the output ++ position. ++ ++ Default counting of the line numbers starts with 1st ++ line of the input file (not the 1st line printed, ++ compare the --page option and -N option). ++ ++ -N NUMBER, --first-line-number=NUMBER ++ Start line counting with the number NUMBER at the 1st ++ line of first page printed (mostly not the 1st line of ++ the input file). ++ ++ -o MARGIN, --indent=MARGIN ++ Offset each line with a margin MARGIN spaces wide. ++ Total page width is the size of the margin plus the ++ PAGE_WIDTH set with -W/-w option. ++ ++ -r, --no-file-warnings ++ Omit warning when a file cannot be opened. ++ ++ -s[CHAR], --separator[=CHAR] ++ Separate columns by a single character CHAR, default for ++ CHAR is the TAB character without -w and 'no char' with -w. ++ Without `-s' default separator `space' is set. ++ -s[CHAR] turns off line truncation of all 3 column options ++ (-COLUMN|-a -COLUMN|-m) except -w is set. That is a POSIX ++ compliant formulation. The source code translates -s into ++ the new options -S and -J, also -W if required. ++ ++ -S STRING, --sep-string[=STRING] ++ Separate columns by any string STRING. The -S option ++ doesn't react upon the -W/-w option (unlike -s option ++ does). It defines a separator nothing else. ++ Without -S: Default separator TAB is used with -J and ++ `space' otherwise (same as -S" "). ++ With -S "": No separator is used. ++ Quotes should be used with blanks and some shell active ++ characters. ++ -S is problematic because in its obsolete form you ++ cannot use -S "STRING", but in its standard form you ++ must use -S "STRING" if STRING is empty. Use ++ --sep-string to avoid the ambiguity. ++ ++ -t, --omit-header Do not print headers or footers but retain form ++ feeds set in the input files. ++ ++ -T, --omit-pagination ++ Do not print headers or footers, eliminate any pagination ++ by form feeds set in the input files. ++ ++ -v, --show-nonprinting ++ Print unprintable characters as escape sequences. Use ++ octal backslash notation. Control-G becomes \007. ++ ++ -w PAGE_WIDTH, --width=PAGE_WIDTH ++ Set page width to PAGE_WIDTH characters for multiple ++ text-column output only (default for PAGE_WIDTH is 72). ++ -s[CHAR] turns off the default page width and any line ++ truncation. Lines of full length will be merged, ++ regardless of the column options set. A POSIX compliant ++ formulation. ++ ++ -W PAGE_WIDTH, --page-width=PAGE_WIDTH ++ Set the page width to PAGE_WIDTH characters. That's valid ++ with and without a column option. Text lines will be ++ truncated, unless -J is used. Together with one of the ++ column options (-COLUMN| -a -COLUMN| -m) column alignment ++ is always used. ++ Default is 72 characters. ++ Without -W PAGE_WIDTH ++ - but with one of the column options default truncation of ++ 72 characters is used (to keep downward compatibility ++ and to simplify most frequently met column tasks). ++ Column alignment and column separators are used. ++ - and without any of the column options NO line truncation ++ is used (to keep downward compatibility and to meet most ++ frequent tasks). That's equivalent to -W 72 -J . ++ ++ With/without -W PAGE_WIDTH the header line is always ++ truncated to avoid line overflow. ++ ++ (In pr versions newer than 1.14 -S option does no longer ++ affect -W option.) ++ ++*/ ++ ++ ++#include ++ ++#include ++#include ++#include "system.h" ++#include "error.h" ++#include "hard-locale.h" ++#include "mbswidth.h" ++#include "quote.h" ++#include "stat-time.h" ++#include "stdio--.h" ++#include "strftime.h" ++#include "xstrtol.h" ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "pr" ++ ++#define AUTHORS \ ++ proper_name ("Pete TerMaat"), \ ++ proper_name ("Roland Huebner") ++ ++/* Used with start_position in the struct COLUMN described below. ++ If start_position == ANYWHERE, we aren't truncating columns and ++ can begin printing a column anywhere. Otherwise we must pad to ++ the horizontal position start_position. */ ++#define ANYWHERE 0 ++ ++/* Each column has one of these structures allocated for it. ++ If we're only dealing with one file, fp is the same for all ++ columns. ++ ++ The general strategy is to spend time setting up these column ++ structures (storing columns if necessary), after which printing ++ is a matter of flitting from column to column and calling ++ print_func. ++ ++ Parallel files, single files printing across in multiple ++ columns, and single files printing down in multiple columns all ++ fit the same printing loop. ++ ++ print_func Function used to print lines in this column. ++ If we're storing this column it will be ++ print_stored(), Otherwise it will be read_line(). ++ ++ char_func Function used to process characters in this column. ++ If we're storing this column it will be store_char(), ++ otherwise it will be print_char(). ++ ++ current_line Index of the current entry in line_vector, which ++ contains the index of the first character of the ++ current line in buff[]. ++ ++ lines_stored Number of lines in this column which are stored in ++ buff. ++ ++ lines_to_print If we're storing this column, lines_to_print is ++ the number of stored_lines which remain to be ++ printed. Otherwise it is the number of lines ++ we can print without exceeding lines_per_body. ++ ++ start_position The horizontal position we want to be in before we ++ print the first character in this column. ++ ++ numbered True means precede this column with a line number. */ ++ ++/* FIXME: There are many unchecked integer overflows in this file, ++ that will cause this command to misbehave given large inputs or ++ options. Many of the "int" values below should be "size_t" or ++ something else like that. */ ++ ++struct COLUMN; ++struct COLUMN ++ { ++ FILE *fp; /* Input stream for this column. */ ++ char const *name; /* File name. */ ++ enum ++ { ++ OPEN, ++ FF_FOUND, /* used with -b option, set with \f, changed ++ to ON_HOLD after print_header */ ++ ON_HOLD, /* Hit a form feed. */ ++ CLOSED ++ } ++ status; /* Status of the file pointer. */ ++ ++ /* Func to print lines in this col. */ ++ bool (*print_func) (struct COLUMN *); ++ ++ /* Func to print/store chars in this col. */ ++ void (*char_func) (char); ++ ++ int current_line; /* Index of current place in line_vector. */ ++ int lines_stored; /* Number of lines stored in buff. */ ++ int lines_to_print; /* No. lines stored or space left on page. */ ++ int start_position; /* Horizontal position of first char. */ ++ bool numbered; ++ bool full_page_printed; /* True means printed without a FF found. */ ++ ++ /* p->full_page_printed controls a special case of "FF set by hand": ++ True means a full page has been printed without FF found. To avoid an ++ additional empty page we have to ignore a FF immediately following in ++ the next line. */ ++ }; ++ ++typedef struct COLUMN COLUMN; ++ ++static int char_to_clump (char c); ++static bool read_line (COLUMN *p); ++static bool print_page (void); ++static bool print_stored (COLUMN *p); ++static bool open_file (char *name, COLUMN *p); ++static bool skip_to_page (uintmax_t page); ++static void print_header (void); ++static void pad_across_to (int position); ++static void add_line_number (COLUMN *p); ++static void getoptarg (char *arg, char switch_char, char *character, ++ int *number); ++void usage (int status); ++static void print_files (int number_of_files, char **av); ++static void init_parameters (int number_of_files); ++static void init_header (char const *filename, int desc); ++static bool init_fps (int number_of_files, char **av); ++static void init_funcs (void); ++static void init_store_cols (void); ++static void store_columns (void); ++static void balance (int total_stored); ++static void store_char (char c); ++static void pad_down (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); ++ ++/* All of the columns to print. */ ++static COLUMN *column_vector; ++ ++/* When printing a single file in multiple downward columns, ++ 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; ++ ++/* Index of the position in buff where the next character ++ will be stored. */ ++static unsigned int buff_current; ++ ++/* The number of characters in buff. ++ Used for allocation of buff and to detect overflow of buff. */ ++static size_t buff_allocated; ++ ++/* Array of indices into buff. ++ Each entry is an index of the first character of a line. ++ This is used when storing lines to facilitate shuffling when ++ we do column balancing on the last page. */ ++static int *line_vector; ++ ++/* Array of horizonal positions. ++ For each line in line_vector, end_vector[line] is the horizontal ++ position we are in after printing that line. We keep track of this ++ so that we know how much we need to pad to prepare for the next ++ column. */ ++static int *end_vector; ++ ++/* (-m) True means we're printing multiple files in parallel. */ ++static bool parallel_files = false; ++ ++/* (-m) True means a line starts with some empty columns (some files ++ already CLOSED or ON_HOLD) which we have to align. */ ++static bool align_empty_cols; ++ ++/* (-m) True means we have not yet found any printable column in a line. ++ align_empty_cols = true has to be maintained. */ ++static bool empty_line; ++ ++/* (-m) False means printable column output precedes a form feed found. ++ Column alignment is done only once. No additional action with that form ++ feed. ++ True means we found only a form feed in a column. Maybe we have to do ++ some column alignment with that form feed. */ ++static bool FF_only; ++ ++/* (-[0-9]+) True means we're given an option explicitly specifying ++ number of columns. Used to detect when this option is used with -m ++ and when translating old options to new/long options. */ ++static bool explicit_columns = false; ++ ++/* (-t|-T) False means we aren't printing headers and footers. */ ++static bool extremities = true; ++ ++/* (-t) True means we retain all FF set by hand in input files. ++ False is set with -T option. */ ++static bool keep_FF = false; ++static bool print_a_FF = false; ++ ++/* True means we need to print a header as soon as we know we've got input ++ to print after it. */ ++static bool print_a_header; ++ ++/* (-f) True means use formfeeds instead of newlines to separate pages. */ ++static bool use_form_feed = false; ++ ++/* True means we have read the standard input. */ ++static bool have_read_stdin = false; ++ ++/* True means the -a flag has been given. */ ++static bool print_across_flag = false; ++ ++/* True means we're printing one file in multiple (>1) downward columns. */ ++static bool storing_columns = true; ++ ++/* (-b) True means balance columns on the last page as Sys V does. */ ++/* That's no longer an independent option. With storing_columns = true ++ balance_columns = true is used too (s. function init_parameters). ++ We get a consistent formulation with "FF set by hand" in input files. */ ++static bool balance_columns = false; ++ ++/* (-l) Number of lines on a page, including header and footer lines. */ ++static int lines_per_page = 66; ++ ++/* Number of lines in the header and footer can be reset to 0 using ++ the -t flag. */ ++enum { lines_per_header = 5 }; ++static int lines_per_body; ++enum { lines_per_footer = 5 }; ++ ++/* (-w|-W) Width in characters of the page. Does not include the width of ++ the margin. */ ++static int chars_per_line = 72; ++ ++/* (-w|W) True means we truncate lines longer than chars_per_column. */ ++static bool truncate_lines = false; ++ ++/* (-J) True means we join lines without any line truncation. -J ++ dominates -w option. */ ++static bool join_lines = false; ++ ++/* Number of characters in a column. Based on col_sep_length and ++ page width. */ ++static int chars_per_column; ++ ++/* (-e) True means convert tabs to spaces on input. */ ++static bool untabify_input = false; ++ ++/* (-e) The input tab character. */ ++static char input_tab_char = '\t'; ++ ++/* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... ++ where the leftmost column is 1. */ ++static int chars_per_input_tab = 8; ++ ++/* (-i) True means convert spaces to tabs on output. */ ++static bool tabify_output = false; ++ ++/* (-i) The output tab character. */ ++static char output_tab_char = '\t'; ++ ++/* (-i) The width of the output tab. */ ++static int chars_per_output_tab = 8; ++ ++/* Keeps track of pending white space. When we hit a nonspace ++ character after some whitespace, we print whitespace, tabbing ++ if necessary to get to output_position + spaces_not_printed. */ ++static int spaces_not_printed; ++ ++/* (-o) Number of spaces in the left margin (tabs used when possible). */ ++static int chars_per_margin = 0; ++ ++/* Position where the next character will fall. ++ Leftmost position is 0 + chars_per_margin. ++ Rightmost position is chars_per_margin + chars_per_line - 1. ++ This is important for converting spaces to tabs on output. */ ++static int output_position; ++ ++/* Horizontal position relative to the current file. ++ (output_position depends on where we are on the page; ++ input_position depends on where we are in the file.) ++ Important for converting tabs to spaces on input. */ ++static int input_position; ++ ++/* True if there were any failed opens so we can exit with nonzero ++ status. */ ++static bool failed_opens = false; ++ ++/* The number of spaces taken up if we print a tab character with width ++ c_ from position h_. */ ++#define TAB_WIDTH(c_, h_) ((c_) - ((h_) % (c_))) ++ ++/* The horizontal position we'll be at after printing a tab character ++ of width c_ from the position h_. */ ++#define POS_AFTER_TAB(c_, h_) ((h_) + TAB_WIDTH (c_, h_)) ++ ++/* (-NNN) Number of columns of text to print. */ ++static int columns = 1; ++ ++/* (+NNN:MMM) Page numbers on which to begin and stop printing. ++ first_page_number = 0 will be used to check input only. */ ++static uintmax_t first_page_number = 0; ++static uintmax_t last_page_number = UINTMAX_MAX; ++ ++/* Number of files open (not closed, not on hold). */ ++static int files_ready_to_read = 0; ++ ++/* Current page number. Displayed in header. */ ++static uintmax_t page_number; ++ ++/* Current line number. Displayed when -n flag is specified. ++ ++ When printing files in parallel (-m flag), line numbering is as follows: ++ 1 foo goo moo ++ 2 hoo too zoo ++ ++ When printing files across (-a flag), ... ++ 1 foo 2 moo 3 goo ++ 4 hoo 5 too 6 zoo ++ ++ Otherwise, line numbering is as follows: ++ 1 foo 3 goo 5 too ++ 2 moo 4 hoo 6 zoo */ ++static int line_number; ++ ++/* With line_number overflow, we use power_10 to cut off the higher-order ++ digits of the line_number */ ++static int power_10; ++ ++/* (-n) True means lines should be preceded by numbers. */ ++static bool numbered_lines = false; ++ ++/* (-n) Character which follows each line number. */ ++static char number_separator = '\t'; ++ ++/* (-n) line counting starts with 1st line of input file (not with 1st ++ line of 1st page printed). */ ++static int line_count = 1; ++ ++/* (-n) True means counting of skipped lines starts with 1st line of ++ input file. False means -N option is used in addition, counting of ++ skipped lines not required. */ ++static bool skip_count = true; ++ ++/* (-N) Counting starts with start_line_number = NUMBER at 1st line of ++ first page printed, usually not 1st page of input file. */ ++static int start_line_num = 1; ++ ++/* (-n) Width in characters of a line number. */ ++static int chars_per_number = 5; ++ ++/* Used when widening the first column to accommodate numbers -- only ++ needed when printing files in parallel. Includes width of both the ++ number and the number_separator. */ ++static int number_width; ++ ++/* Buffer sprintf uses to format a line number. */ ++static char *number_buff; ++ ++/* (-v) True means unprintable characters are printed as escape sequences. ++ control-g becomes \007. */ ++static bool use_esc_sequence = false; ++ ++/* (-c) True means unprintable characters are printed as control prefixes. ++ control-g becomes ^G. */ ++static bool use_cntrl_prefix = false; ++ ++/* (-d) True means output is double spaced. */ ++static bool double_space = false; ++ ++/* Number of files opened initially in init_files. Should be 1 ++ unless we're printing multiple files in parallel. */ ++static int total_files = 0; ++ ++/* (-r) True means don't complain if we can't open a file. */ ++static bool ignore_failed_opens = false; ++ ++/* (-S) True means we separate columns with a specified string. ++ -S option does not affect line truncation nor column alignment. */ ++static bool use_col_separator = false; ++ ++/* String used to separate columns if the -S option has been specified. ++ Default without -S but together with one of the column options ++ -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ ++static char *col_sep_string = (char *) ""; ++static int col_sep_length = 0; ++static char *column_separator = (char *) " "; ++static char *line_separator = (char *) "\t"; ++ ++/* Number of separator characters waiting to be printed as soon as we ++ know that we have any input remaining to be printed. */ ++static int separators_not_printed; ++ ++/* Position we need to pad to, as soon as we know that we have input ++ remaining to be printed. */ ++static int padding_not_printed; ++ ++/* True means we should pad the end of the page. Remains false until we ++ know we have a page to print. */ ++static bool pad_vertically; ++ ++/* (-h) String of characters used in place of the filename in the header. */ ++static char *custom_header; ++ ++/* (-D) Date format for the header. */ ++static char const *date_format; ++ ++/* Date and file name for the header. */ ++static char *date_text; ++static char const *file_text; ++ ++/* Output columns available, not counting the date and file name. */ ++static int header_width_available; ++ ++static char *clump_buff; ++ ++/* True means we read the line no. lines_per_body in skip_read ++ called by skip_to_page. That variable controls the coincidence of a ++ "FF set by hand" and "full_page_printed", see above the definition of ++ structure COLUMN. */ ++static bool last_line = false; ++ ++/* For long options that have no equivalent short option, use a ++ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ ++enum ++{ ++ COLUMNS_OPTION = CHAR_MAX + 1, ++ PAGES_OPTION ++}; ++ ++static char const short_options[] = ++ "-0123456789D:FJN:S::TW:abcde::fh:i::l:mn::o:rs::tvw:"; ++ ++static struct option const long_options[] = ++{ ++ {"pages", required_argument, NULL, PAGES_OPTION}, ++ {"columns", required_argument, NULL, COLUMNS_OPTION}, ++ {"across", no_argument, NULL, 'a'}, ++ {"show-control-chars", no_argument, NULL, 'c'}, ++ {"double-space", no_argument, NULL, 'd'}, ++ {"date-format", required_argument, NULL, 'D'}, ++ {"expand-tabs", optional_argument, NULL, 'e'}, ++ {"form-feed", no_argument, NULL, 'f'}, ++ {"header", required_argument, NULL, 'h'}, ++ {"output-tabs", optional_argument, NULL, 'i'}, ++ {"join-lines", no_argument, NULL, 'J'}, ++ {"length", required_argument, NULL, 'l'}, ++ {"merge", no_argument, NULL, 'm'}, ++ {"number-lines", optional_argument, NULL, 'n'}, ++ {"first-line-number", required_argument, NULL, 'N'}, ++ {"indent", required_argument, NULL, 'o'}, ++ {"no-file-warnings", no_argument, NULL, 'r'}, ++ {"separator", optional_argument, NULL, 's'}, ++ {"sep-string", optional_argument, NULL, 'S'}, ++ {"omit-header", no_argument, NULL, 't'}, ++ {"omit-pagination", no_argument, NULL, 'T'}, ++ {"show-nonprinting", no_argument, NULL, 'v'}, ++ {"width", required_argument, NULL, 'w'}, ++ {"page-width", required_argument, NULL, 'W'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++/* Return the number of columns that have either an open file or ++ stored lines. */ ++ ++static int ++cols_ready_to_print (void) ++{ ++ COLUMN *q; ++ int i; ++ int n; ++ ++ n = 0; ++ for (q = column_vector, i = 0; i < columns; ++q, ++i) ++ if (q->status == OPEN || ++ q->status == FF_FOUND || /* With -b: To print a header only */ ++ (storing_columns && q->lines_stored > 0 && q->lines_to_print > 0)) ++ ++n; ++ return n; ++} ++ ++/* Estimate first_ / last_page_number ++ using option +FIRST_PAGE:LAST_PAGE */ ++ ++static bool ++first_last_page (int oi, char c, char const *pages) ++{ ++ char *p; ++ uintmax_t first; ++ uintmax_t last = UINTMAX_MAX; ++ strtol_error err = xstrtoumax (pages, &p, 10, &first, ""); ++ if (err != LONGINT_OK && err != LONGINT_INVALID_SUFFIX_CHAR) ++ xstrtol_fatal (err, oi, c, long_options, pages); ++ ++ if (p == pages || !first) ++ return false; ++ ++ if (*p == ':') ++ { ++ char const *p1 = p + 1; ++ err = xstrtoumax (p1, &p, 10, &last, ""); ++ if (err != LONGINT_OK) ++ xstrtol_fatal (err, oi, c, long_options, pages); ++ if (p1 == p || last < first) ++ return false; ++ } ++ ++ if (*p) ++ return false; ++ ++ first_page_number = first; ++ last_page_number = last; ++ return true; ++} ++ ++/* Parse column count string S, and if it's valid (1 or larger and ++ within range of the type of `columns') set the global variables ++ columns and explicit_columns and return true. ++ Otherwise, exit with a diagnostic. */ ++static void ++parse_column_count (char const *s) ++{ ++ long int tmp_long; ++ if (xstrtol (s, NULL, 10, &tmp_long, "") != LONGINT_OK ++ || !(1 <= tmp_long && tmp_long <= INT_MAX)) ++ error (EXIT_FAILURE, 0, ++ _("invalid number of columns: %s"), quote (s)); ++ ++ columns = tmp_long; ++ explicit_columns = true; ++} ++ ++/* Estimate length of col_sep_string with option -S. */ ++ ++static void ++separator_string (const char *optarg_S) ++{ ++ col_sep_length = (int) strlen (optarg_S); ++ col_sep_string = xmalloc (col_sep_length + 1); ++ strcpy (col_sep_string, optarg_S); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int n_files; ++ bool old_options = false; ++ bool old_w = false; ++ bool old_s = false; ++ char **file_names; ++ ++ /* Accumulate the digits of old-style options like -99. */ ++ char *column_count_string = NULL; ++ size_t n_digits = 0; ++ size_t n_alloc = 0; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ atexit (close_stdout); ++ ++ n_files = 0; ++ file_names = (argc > 1 ++ ? xmalloc ((argc - 1) * sizeof (char *)) ++ : NULL); ++ ++ for (;;) ++ { ++ int oi = -1; ++ int c = getopt_long (argc, argv, short_options, long_options, &oi); ++ if (c == -1) ++ break; ++ ++ if (ISDIGIT (c)) ++ { ++ /* Accumulate column-count digits specified via old-style options. */ ++ if (n_digits + 1 >= n_alloc) ++ column_count_string ++ = X2REALLOC (column_count_string, &n_alloc); ++ column_count_string[n_digits++] = c; ++ column_count_string[n_digits] = '\0'; ++ continue; ++ } ++ ++ n_digits = 0; ++ ++ switch (c) ++ { ++ case 1: /* Non-option argument. */ ++ /* long option --page dominates old `+FIRST_PAGE ...'. */ ++ if (! (first_page_number == 0 ++ && *optarg == '+' && first_last_page (-2, '+', optarg + 1))) ++ file_names[n_files++] = optarg; ++ break; ++ ++ case PAGES_OPTION: /* --pages=FIRST_PAGE[:LAST_PAGE] */ ++ { /* dominates old opt +... */ ++ if (! optarg) ++ error (EXIT_FAILURE, 0, ++ _("`--pages=FIRST_PAGE[:LAST_PAGE]' missing argument")); ++ else if (! first_last_page (oi, 0, optarg)) ++ error (EXIT_FAILURE, 0, _("invalid page range %s"), ++ quote (optarg)); ++ break; ++ } ++ ++ case COLUMNS_OPTION: /* --columns=COLUMN */ ++ { ++ parse_column_count (optarg); ++ ++ /* If there was a prior column count specified via the ++ short-named option syntax, e.g., -9, ensure that this ++ long-name-specified value overrides it. */ ++ free (column_count_string); ++ column_count_string = NULL; ++ n_alloc = 0; ++ break; ++ } ++ ++ case 'a': ++ print_across_flag = true; ++ storing_columns = false; ++ break; ++ case 'b': ++ balance_columns = true; ++ break; ++ case 'c': ++ use_cntrl_prefix = true; ++ break; ++ case 'd': ++ double_space = true; ++ break; ++ case 'D': ++ date_format = optarg; ++ break; ++ case 'e': ++ if (optarg) ++ getoptarg (optarg, 'e', &input_tab_char, ++ &chars_per_input_tab); ++ /* Could check tab width > 0. */ ++ untabify_input = true; ++ break; ++ case 'f': ++ case 'F': ++ use_form_feed = true; ++ break; ++ case 'h': ++ custom_header = optarg; ++ break; ++ case 'i': ++ if (optarg) ++ getoptarg (optarg, 'i', &output_tab_char, ++ &chars_per_output_tab); ++ /* Could check tab width > 0. */ ++ tabify_output = true; ++ break; ++ case 'J': ++ join_lines = true; ++ break; ++ case 'l': ++ { ++ long int tmp_long; ++ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK ++ || tmp_long <= 0 || tmp_long > INT_MAX) ++ { ++ error (EXIT_FAILURE, 0, ++ _("`-l PAGE_LENGTH' invalid number of lines: %s"), ++ quote (optarg)); ++ } ++ lines_per_page = tmp_long; ++ break; ++ } ++ case 'm': ++ parallel_files = true; ++ storing_columns = false; ++ break; ++ case 'n': ++ numbered_lines = true; ++ if (optarg) ++ getoptarg (optarg, 'n', &number_separator, ++ &chars_per_number); ++ break; ++ case 'N': ++ skip_count = false; ++ { ++ long int tmp_long; ++ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK ++ || tmp_long > INT_MAX) ++ { ++ error (EXIT_FAILURE, 0, ++ _("`-N NUMBER' invalid starting line number: %s"), ++ quote (optarg)); ++ } ++ start_line_num = tmp_long; ++ break; ++ } ++ case 'o': ++ { ++ long int tmp_long; ++ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK ++ || tmp_long < 0 || tmp_long > INT_MAX) ++ error (EXIT_FAILURE, 0, ++ _("`-o MARGIN' invalid line offset: %s"), quote (optarg)); ++ chars_per_margin = tmp_long; ++ break; ++ } ++ case 'r': ++ ignore_failed_opens = true; ++ break; ++ case 's': ++ old_options = true; ++ old_s = true; ++ if (!use_col_separator && optarg) ++ separator_string (optarg); ++ break; ++ case 'S': ++ old_s = false; ++ /* Reset an additional input of -s, -S dominates -s */ ++ col_sep_string = bad_cast (""); ++ col_sep_length = 0; ++ use_col_separator = true; ++ if (optarg) ++ separator_string (optarg); ++ break; ++ case 't': ++ extremities = false; ++ keep_FF = true; ++ break; ++ case 'T': ++ extremities = false; ++ keep_FF = false; ++ break; ++ case 'v': ++ use_esc_sequence = true; ++ break; ++ case 'w': ++ old_options = true; ++ old_w = true; ++ { ++ long int tmp_long; ++ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK ++ || tmp_long <= 0 || tmp_long > INT_MAX) ++ error (EXIT_FAILURE, 0, ++ _("`-w PAGE_WIDTH' invalid number of characters: %s"), ++ quote (optarg)); ++ if (!truncate_lines) ++ chars_per_line = tmp_long; ++ break; ++ } ++ case 'W': ++ old_w = false; /* dominates -w */ ++ truncate_lines = true; ++ { ++ long int tmp_long; ++ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK ++ || tmp_long <= 0 || tmp_long > INT_MAX) ++ error (EXIT_FAILURE, 0, ++ _("`-W PAGE_WIDTH' invalid number of characters: %s"), ++ quote (optarg)); ++ chars_per_line = tmp_long; ++ break; ++ } ++ case_GETOPT_HELP_CHAR; ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ default: ++ usage (EXIT_FAILURE); ++ break; ++ } ++ } ++ ++ if (column_count_string) ++ { ++ parse_column_count (column_count_string); ++ free (column_count_string); ++ } ++ ++ if (! date_format) ++ date_format = (getenv ("POSIXLY_CORRECT") && !hard_locale (LC_TIME) ++ ? "%b %e %H:%M %Y" ++ : "%Y-%m-%d %H:%M"); ++ ++ /* Now we can set a reasonable initial value: */ ++ if (first_page_number == 0) ++ first_page_number = 1; ++ ++ if (parallel_files && explicit_columns) ++ error (EXIT_FAILURE, 0, ++ _("cannot specify number of columns when printing in parallel")); ++ ++ if (parallel_files && print_across_flag) ++ error (EXIT_FAILURE, 0, ++ _("cannot specify both printing across and printing in parallel")); ++ ++/* Translate some old short options to new/long options. ++ To meet downward compatibility with other UNIX pr utilities ++ and some POSIX specifications. */ ++ ++ if (old_options) ++ { ++ if (old_w) ++ { ++ if (parallel_files || explicit_columns) ++ { ++ /* activate -W */ ++ truncate_lines = true; ++ if (old_s) ++ /* adapt HP-UX and SunOS: -s = no separator; ++ activate -S */ ++ use_col_separator = true; ++ } ++ else ++ /* old -w sets width with columns only ++ activate -J */ ++ join_lines = true; ++ } ++ else if (!use_col_separator) ++ { ++ /* No -S option read */ ++ if (old_s && (parallel_files || explicit_columns)) ++ { ++ if (!truncate_lines) ++ { ++ /* old -s (without -w and -W) annuls column alignment, ++ uses fields, activate -J */ ++ join_lines = true; ++ if (col_sep_length > 0) ++ /* activate -S */ ++ use_col_separator = true; ++ } ++ else ++ /* with -W */ ++ /* adapt HP-UX and SunOS: -s = no separator; ++ activate -S */ ++ use_col_separator = true; ++ } ++ } ++ } ++ ++ for (; optind < argc; optind++) ++ { ++ file_names[n_files++] = argv[optind]; ++ } ++ ++ if (n_files == 0) ++ { ++ /* No file arguments specified; read from standard input. */ ++ print_files (0, NULL); ++ } ++ else ++ { ++ if (parallel_files) ++ print_files (n_files, file_names); ++ else ++ { ++ int i; ++ for (i = 0; i < n_files; i++) ++ print_files (1, &file_names[i]); ++ } ++ } ++ ++ cleanup (); ++ ++ if (have_read_stdin && fclose (stdin) == EOF) ++ error (EXIT_FAILURE, errno, _("standard input")); ++ if (failed_opens) ++ exit (EXIT_FAILURE); ++ exit (EXIT_SUCCESS); ++} ++ ++/* Parse options of the form -scNNN. ++ ++ Example: -nck, where 'n' is the option, c is the optional number ++ separator, and k is the optional width of the field used when printing ++ a number. */ ++ ++static void ++getoptarg (char *arg, char switch_char, char *character, int *number) ++{ ++ if (!ISDIGIT (*arg)) ++ *character = *arg++; ++ if (*arg) ++ { ++ long int tmp_long; ++ if (xstrtol (arg, NULL, 10, &tmp_long, "") != LONGINT_OK ++ || tmp_long <= 0 || tmp_long > INT_MAX) ++ { ++ error (0, 0, ++ _("`-%c' extra characters or invalid number in the argument: %s"), ++ switch_char, quote (arg)); ++ usage (EXIT_FAILURE); ++ } ++ *number = tmp_long; ++ } ++} ++ ++/* Set parameters related to formatting. */ ++ ++static void ++init_parameters (int number_of_files) ++{ ++ int chars_used_by_number = 0; ++ ++ lines_per_body = lines_per_page - lines_per_header - lines_per_footer; ++ if (lines_per_body <= 0) ++ { ++ extremities = false; ++ keep_FF = true; ++ } ++ if (extremities == false) ++ lines_per_body = lines_per_page; ++ ++ if (double_space) ++ lines_per_body = lines_per_body / 2; ++ ++ /* If input is stdin, cannot print parallel files. BSD dumps core ++ on this. */ ++ if (number_of_files == 0) ++ parallel_files = false; ++ ++ if (parallel_files) ++ columns = number_of_files; ++ ++ /* One file, multi columns down: -b option is set to get a consistent ++ formulation with "FF set by hand" in input files. */ ++ if (storing_columns) ++ balance_columns = true; ++ ++ /* Tabification is assumed for multiple columns. */ ++ if (columns > 1) ++ { ++ if (!use_col_separator) ++ { ++ /* Use default separator */ ++ if (join_lines) ++ col_sep_string = line_separator; ++ else ++ col_sep_string = column_separator; ++ ++ col_sep_length = 1; ++ use_col_separator = true; ++ } ++ /* It's rather pointless to define a TAB separator with column ++ alignment */ ++ else if (!join_lines && *col_sep_string == '\t') ++ col_sep_string = column_separator; ++ ++ truncate_lines = true; ++ tabify_output = true; ++ } ++ else ++ storing_columns = false; ++ ++ /* -J dominates -w in any case */ ++ if (join_lines) ++ truncate_lines = false; ++ ++ if (numbered_lines) ++ { ++ int tmp_i; ++ int chars_per_default_tab = 8; ++ ++ line_count = start_line_num; ++ ++ /* To allow input tab-expansion (-e sensitive) use: ++ if (number_separator == input_tab_char) ++ number_width = chars_per_number + ++ TAB_WIDTH (chars_per_input_tab, chars_per_number); */ ++ ++ /* Estimate chars_per_text without any margin and keep it constant. */ ++ if (number_separator == '\t') ++ number_width = chars_per_number + ++ TAB_WIDTH (chars_per_default_tab, chars_per_number); ++ else ++ number_width = chars_per_number + 1; ++ ++ /* The number is part of the column width unless we are ++ printing files in parallel. */ ++ if (parallel_files) ++ chars_used_by_number = number_width; ++ ++ /* We use power_10 to cut off the higher-order digits of the ++ line_number in function add_line_number */ ++ tmp_i = chars_per_number; ++ for (power_10 = 1; tmp_i > 0; --tmp_i) ++ power_10 = 10 * power_10; ++ } ++ ++ chars_per_column = (chars_per_line - chars_used_by_number - ++ (columns - 1) * col_sep_length) / columns; ++ ++ if (chars_per_column < 1) ++ error (EXIT_FAILURE, 0, _("page width too narrow")); ++ ++ if (numbered_lines) ++ { ++ free (number_buff); ++ number_buff = xmalloc (2 * chars_per_number); ++ } ++ ++ /* Pick the maximum between the tab width and the width of an ++ escape sequence. ++ The width of an escape sequence (4) isn't the lower limit any longer. ++ 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)); ++} ++ ++/* Open the necessary files, ++ maintaining a COLUMN structure for each column. ++ ++ With multiple files, each column p has a different p->fp. ++ With single files, each column p has the same p->fp. ++ Return false if (number_of_files > 0) and no files can be opened, ++ true otherwise. ++ ++ With each column/file p, p->full_page_printed is initialized, ++ see also open_file. */ ++ ++static bool ++init_fps (int number_of_files, char **av) ++{ ++ int i, files_left; ++ COLUMN *p; ++ FILE *firstfp; ++ char const *firstname; ++ ++ total_files = 0; ++ ++ free (column_vector); ++ column_vector = xnmalloc (columns, sizeof (COLUMN)); ++ ++ if (parallel_files) ++ { ++ files_left = number_of_files; ++ for (p = column_vector; files_left--; ++p, ++av) ++ { ++ if (! open_file (*av, p)) ++ { ++ --p; ++ --columns; ++ } ++ } ++ if (columns == 0) ++ return false; ++ init_header ("", -1); ++ } ++ else ++ { ++ p = column_vector; ++ if (number_of_files > 0) ++ { ++ if (! open_file (*av, p)) ++ return false; ++ init_header (*av, fileno (p->fp)); ++ p->lines_stored = 0; ++ } ++ else ++ { ++ p->name = _("standard input"); ++ p->fp = stdin; ++ have_read_stdin = true; ++ p->status = OPEN; ++ p->full_page_printed = false; ++ ++total_files; ++ init_header ("", -1); ++ p->lines_stored = 0; ++ } ++ ++ firstname = p->name; ++ firstfp = p->fp; ++ for (i = columns - 1, ++p; i; --i, ++p) ++ { ++ p->name = firstname; ++ p->fp = firstfp; ++ p->status = OPEN; ++ p->full_page_printed = false; ++ p->lines_stored = 0; ++ } ++ } ++ files_ready_to_read = total_files; ++ return true; ++} ++ ++/* Determine print_func and char_func, the functions ++ used by each column for printing and/or storing. ++ ++ Determine the horizontal position desired when we begin ++ printing a column (p->start_position). */ ++ ++static void ++init_funcs (void) ++{ ++ int i, h, h_next; ++ COLUMN *p; ++ ++ h = chars_per_margin; ++ ++ if (!truncate_lines) ++ h_next = ANYWHERE; ++ else ++ { ++ /* When numbering lines of parallel files, we enlarge the ++ first column to accomodate the number. Looks better than ++ the Sys V approach. */ ++ if (parallel_files && numbered_lines) ++ h_next = h + chars_per_column + number_width; ++ else ++ h_next = h + chars_per_column; ++ } ++ ++ /* Enlarge p->start_position of first column to use the same form of ++ padding_not_printed with all columns. */ ++ h = h + col_sep_length; ++ ++ /* This loop takes care of all but the rightmost column. */ ++ ++ for (p = column_vector, i = 1; i < columns; ++p, ++i) ++ { ++ if (storing_columns) /* One file, multi columns down. */ ++ { ++ p->char_func = store_char; ++ p->print_func = print_stored; ++ } ++ else ++ /* One file, multi columns across; or parallel files. */ ++ { ++ p->char_func = print_char; ++ p->print_func = read_line; ++ } ++ ++ /* Number only the first column when printing files in ++ parallel. */ ++ p->numbered = numbered_lines && (!parallel_files || i == 1); ++ p->start_position = h; ++ ++ /* If we don't truncate lines, all start_positions are ++ ANYWHERE, except the first column's start_position when ++ using a margin. */ ++ ++ if (!truncate_lines) ++ { ++ h = ANYWHERE; ++ h_next = ANYWHERE; ++ } ++ else ++ { ++ h = h_next + col_sep_length; ++ h_next = h + chars_per_column; ++ } ++ } ++ ++ /* The rightmost column. ++ ++ Doesn't need to be stored unless we intend to balance ++ columns on the last page. */ ++ if (storing_columns && balance_columns) ++ { ++ p->char_func = store_char; ++ p->print_func = print_stored; ++ } ++ else ++ { ++ p->char_func = print_char; ++ p->print_func = read_line; ++ } ++ ++ p->numbered = numbered_lines && (!parallel_files || i == 1); ++ p->start_position = h; ++} ++ ++/* Open a file. Return true if successful. ++ ++ With each file p, p->full_page_printed is initialized, ++ see also init_fps. */ ++ ++static bool ++open_file (char *name, COLUMN *p) ++{ ++ if (STREQ (name, "-")) ++ { ++ p->name = _("standard input"); ++ p->fp = stdin; ++ have_read_stdin = true; ++ } ++ else ++ { ++ p->name = name; ++ p->fp = fopen (name, "r"); ++ } ++ if (p->fp == NULL) ++ { ++ failed_opens = true; ++ if (!ignore_failed_opens) ++ error (0, errno, "%s", name); ++ return false; ++ } ++ p->status = OPEN; ++ p->full_page_printed = false; ++ ++total_files; ++ return true; ++} ++ ++/* Close the file in P. ++ ++ If we aren't dealing with multiple files in parallel, we change ++ the status of all columns in the column list to reflect the close. */ ++ ++static void ++close_file (COLUMN *p) ++{ ++ COLUMN *q; ++ int i; ++ ++ if (p->status == CLOSED) ++ return; ++ if (ferror (p->fp)) ++ error (EXIT_FAILURE, errno, "%s", p->name); ++ if (fileno (p->fp) != STDIN_FILENO && fclose (p->fp) != 0) ++ error (EXIT_FAILURE, errno, "%s", p->name); ++ ++ if (!parallel_files) ++ { ++ for (q = column_vector, i = columns; i; ++q, --i) ++ { ++ q->status = CLOSED; ++ if (q->lines_stored == 0) ++ { ++ q->lines_to_print = 0; ++ } ++ } ++ } ++ else ++ { ++ p->status = CLOSED; ++ p->lines_to_print = 0; ++ } ++ ++ --files_ready_to_read; ++} ++ ++/* Put a file on hold until we start a new page, ++ since we've hit a form feed. ++ ++ If we aren't dealing with parallel files, we must change the ++ status of all columns in the column list. */ ++ ++static void ++hold_file (COLUMN *p) ++{ ++ COLUMN *q; ++ int i; ++ ++ if (!parallel_files) ++ for (q = column_vector, i = columns; i; ++q, --i) ++ { ++ if (storing_columns) ++ q->status = FF_FOUND; ++ else ++ q->status = ON_HOLD; ++ } ++ else ++ p->status = ON_HOLD; ++ ++ p->lines_to_print = 0; ++ --files_ready_to_read; ++} ++ ++/* Undo hold_file -- go through the column list and change any ++ ON_HOLD columns to OPEN. Used at the end of each page. */ ++ ++static void ++reset_status (void) ++{ ++ int i = columns; ++ COLUMN *p; ++ ++ for (p = column_vector; i; --i, ++p) ++ if (p->status == ON_HOLD) ++ { ++ p->status = OPEN; ++ files_ready_to_read++; ++ } ++ ++ if (storing_columns) ++ { ++ if (column_vector->status == CLOSED) ++ /* We use the info to output an error message in skip_to_page. */ ++ files_ready_to_read = 0; ++ else ++ files_ready_to_read = 1; ++ } ++} ++ ++/* Print a single file, or multiple files in parallel. ++ ++ Set up the list of columns, opening the necessary files. ++ Allocate space for storing columns, if necessary. ++ Skip to first_page_number, if user has asked to skip leading pages. ++ Determine which functions are appropriate to store/print lines ++ in each column. ++ Print the file(s). */ ++ ++static void ++print_files (int number_of_files, char **av) ++{ ++ init_parameters (number_of_files); ++ if (! init_fps (number_of_files, av)) ++ return; ++ if (storing_columns) ++ init_store_cols (); ++ ++ if (first_page_number > 1) ++ { ++ if (!skip_to_page (first_page_number)) ++ return; ++ else ++ page_number = first_page_number; ++ } ++ else ++ page_number = 1; ++ ++ init_funcs (); ++ ++ line_number = line_count; ++ while (print_page ()) ++ ; ++} ++ ++/* Initialize header information. ++ If DESC is non-negative, it is a file descriptor open to ++ FILENAME for reading. */ ++ ++static void ++init_header (char const *filename, int desc) ++{ ++ char *buf = NULL; ++ struct stat st; ++ struct timespec t; ++ int ns; ++ struct tm *tm; ++ ++ /* If parallel files or standard input, use current date. */ ++ if (STREQ (filename, "-")) ++ desc = -1; ++ if (0 <= desc && fstat (desc, &st) == 0) ++ t = get_stat_mtime (&st); ++ else ++ { ++ static struct timespec timespec; ++ if (! timespec.tv_sec) ++ gettime (×pec); ++ t = timespec; ++ } ++ ++ ns = t.tv_nsec; ++ tm = localtime (&t.tv_sec); ++ if (tm == NULL) ++ { ++ buf = xmalloc (INT_BUFSIZE_BOUND (long int) ++ + MAX (10, INT_BUFSIZE_BOUND (int))); ++ sprintf (buf, "%ld.%09d", (long int) t.tv_sec, ns); ++ } ++ else ++ { ++ size_t bufsize = nstrftime (NULL, SIZE_MAX, date_format, tm, 0, ns) + 1; ++ buf = xmalloc (bufsize); ++ nstrftime (buf, bufsize, date_format, tm, 0, ns); ++ } ++ ++ free (date_text); ++ date_text = buf; ++ file_text = custom_header ? custom_header : desc < 0 ? "" : filename; ++ header_width_available = (chars_per_line ++ - mbswidth (date_text, 0) ++ - mbswidth (file_text, 0)); ++} ++ ++/* Set things up for printing a page ++ ++ Scan through the columns ... ++ Determine which are ready to print ++ (i.e., which have lines stored or open files) ++ Set p->lines_to_print appropriately ++ (to p->lines_stored if we're storing, or lines_per_body ++ if we're reading straight from the file) ++ Keep track of this total so we know when to stop printing */ ++ ++static void ++init_page (void) ++{ ++ int j; ++ COLUMN *p; ++ ++ if (storing_columns) ++ { ++ store_columns (); ++ for (j = columns - 1, p = column_vector; j; --j, ++p) ++ { ++ p->lines_to_print = p->lines_stored; ++ } ++ ++ /* Last column. */ ++ if (balance_columns) ++ { ++ p->lines_to_print = p->lines_stored; ++ } ++ /* Since we're not balancing columns, we don't need to store ++ the rightmost column. Read it straight from the file. */ ++ else ++ { ++ if (p->status == OPEN) ++ { ++ p->lines_to_print = lines_per_body; ++ } ++ else ++ p->lines_to_print = 0; ++ } ++ } ++ else ++ for (j = columns, p = column_vector; j; --j, ++p) ++ if (p->status == OPEN) ++ { ++ p->lines_to_print = lines_per_body; ++ } ++ else ++ p->lines_to_print = 0; ++} ++ ++/* Align empty columns and print separators. ++ Empty columns will be formed by files with status ON_HOLD or CLOSED ++ when printing multiple files in parallel. */ ++ ++static void ++align_column (COLUMN *p) ++{ ++ padding_not_printed = p->start_position; ++ if (padding_not_printed - col_sep_length > 0) ++ { ++ pad_across_to (padding_not_printed - col_sep_length); ++ padding_not_printed = ANYWHERE; ++ } ++ ++ if (use_col_separator) ++ print_sep_string (); ++ ++ if (p->numbered) ++ add_line_number (p); ++} ++ ++/* Print one page. ++ ++ As long as there are lines left on the page and columns ready to print, ++ Scan across the column list ++ if the column has stored lines or the file is open ++ pad to the appropriate spot ++ print the column ++ pad the remainder of the page with \n or \f as requested ++ reset the status of all files -- any files which where on hold because ++ of formfeeds are now put back into the lineup. */ ++ ++static bool ++print_page (void) ++{ ++ int j; ++ int lines_left_on_page; ++ COLUMN *p; ++ ++ /* Used as an accumulator (with | operator) of successive values of ++ pad_vertically. The trick is to set pad_vertically ++ to false before each run through the inner loop, then after that ++ loop, it tells us whether a line was actually printed (whether a ++ newline needs to be output -- or two for double spacing). But those ++ values have to be accumulated (in pv) so we can invoke pad_down ++ properly after the outer loop completes. */ ++ bool pv; ++ ++ init_page (); ++ ++ if (cols_ready_to_print () == 0) ++ return false; ++ ++ if (extremities) ++ print_a_header = true; ++ ++ /* Don't pad unless we know a page was printed. */ ++ pad_vertically = false; ++ pv = false; ++ ++ lines_left_on_page = lines_per_body; ++ if (double_space) ++ lines_left_on_page *= 2; ++ ++ while (lines_left_on_page > 0 && cols_ready_to_print () > 0) ++ { ++ output_position = 0; ++ spaces_not_printed = 0; ++ separators_not_printed = 0; ++ pad_vertically = false; ++ align_empty_cols = false; ++ empty_line = true; ++ ++ for (j = 1, p = column_vector; j <= columns; ++j, ++p) ++ { ++ input_position = 0; ++ if (p->lines_to_print > 0 || p->status == FF_FOUND) ++ { ++ FF_only = false; ++ padding_not_printed = p->start_position; ++ if (!(p->print_func) (p)) ++ read_rest_of_line (p); ++ pv |= pad_vertically; ++ ++ --p->lines_to_print; ++ if (p->lines_to_print <= 0) ++ { ++ if (cols_ready_to_print () <= 0) ++ break; ++ } ++ ++ /* File p changed its status to ON_HOLD or CLOSED */ ++ if (parallel_files && p->status != OPEN) ++ { ++ if (empty_line) ++ align_empty_cols = true; ++ else if (p->status == CLOSED || ++ (p->status == ON_HOLD && FF_only)) ++ align_column (p); ++ } ++ } ++ else if (parallel_files) ++ { ++ /* File status ON_HOLD or CLOSED */ ++ if (empty_line) ++ align_empty_cols = true; ++ else ++ align_column (p); ++ } ++ ++ /* We need it also with an empty column */ ++ if (use_col_separator) ++ ++separators_not_printed; ++ } ++ ++ if (pad_vertically) ++ { ++ putchar ('\n'); ++ --lines_left_on_page; ++ } ++ ++ if (cols_ready_to_print () <= 0 && !extremities) ++ break; ++ ++ if (double_space && pv) ++ { ++ putchar ('\n'); ++ --lines_left_on_page; ++ } ++ } ++ ++ if (lines_left_on_page == 0) ++ for (j = 1, p = column_vector; j <= columns; ++j, ++p) ++ if (p->status == OPEN) ++ p->full_page_printed = true; ++ ++ pad_vertically = pv; ++ ++ if (pad_vertically && extremities) ++ pad_down (lines_left_on_page + lines_per_footer); ++ else if (keep_FF && print_a_FF) ++ { ++ putchar ('\f'); ++ print_a_FF = false; ++ } ++ ++ if (last_page_number < page_number) ++ return false; /* Stop printing with LAST_PAGE */ ++ ++ reset_status (); /* Change ON_HOLD to OPEN. */ ++ ++ return true; /* More pages to go. */ ++} ++ ++/* Allocate space for storing columns. ++ ++ This is necessary when printing multiple columns from a single file. ++ Lines are stored consecutively in buff, separated by '\0'. ++ ++ The following doesn't apply any longer - any tuning possible? ++ (We can't use a fixed offset since with the '-s' flag lines aren't ++ truncated.) ++ ++ We maintain a list (line_vector) of pointers to the beginnings ++ of lines in buff. We allocate one more than the number of lines ++ because the last entry tells us the index of the last character, ++ which we need to know in order to print the last line in buff. */ ++ ++static void ++init_store_cols (void) ++{ ++ int total_lines = lines_per_body * columns; ++ int chars_if_truncate = total_lines * (chars_per_column + 1); ++ ++ free (line_vector); ++ /* FIXME: here's where it was allocated. */ ++ line_vector = xmalloc ((total_lines + 1) * sizeof (int *)); ++ ++ free (end_vector); ++ end_vector = xmalloc (total_lines * sizeof (int *)); ++ ++ free (buff); ++ buff_allocated = (use_col_separator ++ ? 2 * chars_if_truncate ++ : chars_if_truncate); /* Tune this. */ ++ buff = xmalloc (buff_allocated); ++} ++ ++/* Store all but the rightmost column. ++ (Used when printing a single file in multiple downward columns) ++ ++ For each column ++ set p->current_line to be the index in line_vector of the ++ first line in the column ++ For each line in the column ++ store the line in buff ++ add to line_vector the index of the line's first char ++ buff_start is the index in buff of the first character in the ++ current line. */ ++ ++static void ++store_columns (void) ++{ ++ int i, j; ++ unsigned int line = 0; ++ unsigned int buff_start; ++ int last_col; /* The rightmost column which will be saved in buff */ ++ COLUMN *p; ++ ++ buff_current = 0; ++ buff_start = 0; ++ ++ if (balance_columns) ++ last_col = columns; ++ else ++ last_col = columns - 1; ++ ++ for (i = 1, p = column_vector; i <= last_col; ++i, ++p) ++ p->lines_stored = 0; ++ ++ for (i = 1, p = column_vector; i <= last_col && files_ready_to_read; ++ ++i, ++p) ++ { ++ p->current_line = line; ++ for (j = lines_per_body; j && files_ready_to_read; --j) ++ ++ if (p->status == OPEN) /* Redundant. Clean up. */ ++ { ++ input_position = 0; ++ ++ if (!read_line (p)) ++ read_rest_of_line (p); ++ ++ if (p->status == OPEN ++ || buff_start != buff_current) ++ { ++ ++p->lines_stored; ++ line_vector[line] = buff_start; ++ end_vector[line++] = input_position; ++ buff_start = buff_current; ++ } ++ } ++ } ++ ++ /* Keep track of the location of the last char in buff. */ ++ line_vector[line] = buff_start; ++ ++ if (balance_columns) ++ balance (line); ++} ++ ++static void ++balance (int total_stored) ++{ ++ COLUMN *p; ++ int i, lines; ++ int first_line = 0; ++ ++ for (i = 1, p = column_vector; i <= columns; ++i, ++p) ++ { ++ lines = total_stored / columns; ++ if (i <= total_stored % columns) ++ ++lines; ++ ++ p->lines_stored = lines; ++ p->current_line = first_line; ++ ++ first_line += lines; ++ } ++} ++ ++/* Store a character in the buffer. */ ++ ++static void ++store_char (char c) ++{ ++ if (buff_current >= buff_allocated) ++ { ++ /* May be too generous. */ ++ buff = X2REALLOC (buff, &buff_allocated); ++ } ++ buff[buff_current++] = c; ++} ++ ++static void ++add_line_number (COLUMN *p) ++{ ++ int i; ++ char *s; ++ int left_cut; ++ ++ /* Cutting off the higher-order digits is more informative than ++ lower-order cut off*/ ++ if (line_number < power_10) ++ sprintf (number_buff, "%*d", chars_per_number, line_number); ++ else ++ { ++ left_cut = line_number % power_10; ++ sprintf (number_buff, "%0*d", chars_per_number, left_cut); ++ } ++ line_number++; ++ s = number_buff; ++ for (i = chars_per_number; i > 0; i--) ++ (p->char_func) (*s++); ++ ++ if (columns > 1) ++ { ++ /* 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') ++ { ++ i = number_width - chars_per_number; ++ while (i-- > 0) ++ (p->char_func) (' '); ++ } ++ else ++ (p->char_func) (number_separator); ++ } ++ 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') ++ output_position = POS_AFTER_TAB (chars_per_output_tab, ++ output_position); ++ } ++ ++ if (truncate_lines && !parallel_files) ++ input_position += number_width; ++} ++ ++/* Print (or store) padding until the current horizontal position ++ is position. */ ++ ++static void ++pad_across_to (int position) ++{ ++ int h = output_position; ++ ++ if (tabify_output) ++ spaces_not_printed = position - output_position; ++ else ++ { ++ while (++h <= position) ++ putchar (' '); ++ output_position = position; ++ } ++} ++ ++/* Pad to the bottom of the page. ++ ++ If the user has requested a formfeed, use one. ++ Otherwise, use newlines. */ ++ ++static void ++pad_down (int lines) ++{ ++ int i; ++ ++ if (use_form_feed) ++ putchar ('\f'); ++ else ++ for (i = lines; i; --i) ++ putchar ('\n'); ++} ++ ++/* Read the rest of the line. ++ ++ Read from the current column's file until an end of line is ++ hit. Used when we've truncated a line and we no longer need ++ to print or store its characters. */ ++ ++static void ++read_rest_of_line (COLUMN *p) ++{ ++ int c; ++ FILE *f = p->fp; ++ ++ while ((c = getc (f)) != '\n') ++ { ++ if (c == '\f') ++ { ++ if ((c = getc (f)) != '\n') ++ ungetc (c, f); ++ if (keep_FF) ++ print_a_FF = true; ++ hold_file (p); ++ break; ++ } ++ else if (c == EOF) ++ { ++ close_file (p); ++ break; ++ } ++ } ++} ++ ++/* Read a line with skip_to_page. ++ ++ Read from the current column's file until an end of line is ++ hit. Used when we read full lines to skip pages. ++ With skip_to_page we have to check for FF-coincidence which is done ++ in function read_line otherwise. ++ Count lines of skipped pages to find the line number of 1st page ++ printed relative to 1st line of input file (start_line_num). */ ++ ++static void ++skip_read (COLUMN *p, int column_number) ++{ ++ int c; ++ FILE *f = p->fp; ++ int i; ++ bool single_ff = false; ++ COLUMN *q; ++ ++ /* Read 1st character in a line or any character succeeding a FF */ ++ if ((c = getc (f)) == '\f' && p->full_page_printed) ++ /* A FF-coincidence with a previous full_page_printed. ++ To avoid an additional empty page, eliminate the FF */ ++ if ((c = getc (f)) == '\n') ++ c = getc (f); ++ ++ p->full_page_printed = false; ++ ++ /* 1st character a FF means a single FF without any printable ++ characters. Don't count it as a line with -n option. */ ++ if (c == '\f') ++ single_ff = true; ++ ++ /* Preparing for a FF-coincidence: Maybe we finish that page ++ without a FF found */ ++ if (last_line) ++ p->full_page_printed = true; ++ ++ while (c != '\n') ++ { ++ if (c == '\f') ++ { ++ /* No FF-coincidence possible, ++ no catching up of a FF-coincidence with next page */ ++ if (last_line) ++ { ++ if (!parallel_files) ++ for (q = column_vector, i = columns; i; ++q, --i) ++ q->full_page_printed = false; ++ else ++ p->full_page_printed = false; ++ } ++ ++ if ((c = getc (f)) != '\n') ++ ungetc (c, f); ++ hold_file (p); ++ break; ++ } ++ else if (c == EOF) ++ { ++ close_file (p); ++ break; ++ } ++ c = getc (f); ++ } ++ ++ if (skip_count) ++ if ((!parallel_files || column_number == 1) && !single_ff) ++ ++line_count; ++} ++ ++/* If we're tabifying output, ++ ++ When print_char encounters white space it keeps track ++ of our desired horizontal position and delays printing ++ until this function is called. */ ++ ++static void ++print_white_space (void) ++{ ++ int h_new; ++ int h_old = output_position; ++ int goal = h_old + spaces_not_printed; ++ ++ while (goal - h_old > 1 ++ && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) ++ { ++ putchar (output_tab_char); ++ h_old = h_new; ++ } ++ while (++h_old <= goal) ++ putchar (' '); ++ ++ output_position = goal; ++ spaces_not_printed = 0; ++} ++ ++/* Print column separators. ++ ++ We keep a count until we know that we'll be printing a line, ++ then print_sep_string() is called. */ ++ ++static void ++print_sep_string (void) ++{ ++ char *s; ++ int l = col_sep_length; ++ ++ s = col_sep_string; ++ ++ if (separators_not_printed <= 0) ++ { ++ /* We'll be starting a line with chars_per_margin, anything else? */ ++ if (spaces_not_printed > 0) ++ print_white_space (); ++ } ++ else ++ { ++ for (; separators_not_printed > 0; --separators_not_printed) ++ { ++ while (l-- > 0) ++ { ++ /* 3 types of sep_strings: spaces only, spaces and chars, ++ chars only */ ++ if (*s == ' ') ++ { ++ /* We're tabifying output; consecutive spaces in ++ sep_string may have to be converted to tabs */ ++ s++; ++ ++spaces_not_printed; ++ } ++ else ++ { ++ if (spaces_not_printed > 0) ++ print_white_space (); ++ putchar (*s++); ++ ++output_position; ++ } ++ } ++ /* sep_string ends with some spaces */ ++ if (spaces_not_printed > 0) ++ print_white_space (); ++ } ++ } ++} ++ ++/* Print (or store, depending on p->char_func) a clump of N ++ characters. */ ++ ++static void ++print_clump (COLUMN *p, int n, char *clump) ++{ ++ while (n--) ++ (p->char_func) (*clump++); ++} ++ ++/* Print a character. ++ ++ Update the following comment: process-char hasn't been used any ++ longer. ++ If we're tabifying, all tabs have been converted to spaces by ++ process_char(). Keep a count of consecutive spaces, and when ++ a nonspace is encountered, call print_white_space() to print the ++ required number of tabs and spaces. */ ++ ++static void ++print_char (char c) ++{ ++ if (tabify_output) ++ { ++ if (c == ' ') ++ { ++ ++spaces_not_printed; ++ return; ++ } ++ else if (spaces_not_printed > 0) ++ print_white_space (); ++ ++ /* Nonprintables are assumed to have width 0, except '\b'. */ ++ if (! isprint (to_uchar (c))) ++ { ++ if (c == '\b') ++ --output_position; ++ } ++ else ++ ++output_position; ++ } ++ putchar (c); ++} ++ ++/* Skip to page PAGE before printing. ++ PAGE may be larger than total number of pages. */ ++ ++static bool ++skip_to_page (uintmax_t page) ++{ ++ uintmax_t n; ++ int i; ++ int j; ++ COLUMN *p; ++ ++ for (n = 1; n < page; ++n) ++ { ++ for (i = 1; i < lines_per_body; ++i) ++ { ++ for (j = 1, p = column_vector; j <= columns; ++j, ++p) ++ if (p->status == OPEN) ++ skip_read (p, j); ++ } ++ last_line = true; ++ for (j = 1, p = column_vector; j <= columns; ++j, ++p) ++ if (p->status == OPEN) ++ skip_read (p, j); ++ ++ if (storing_columns) /* change FF_FOUND to ON_HOLD */ ++ for (j = 1, p = column_vector; j <= columns; ++j, ++p) ++ if (p->status != CLOSED) ++ p->status = ON_HOLD; ++ ++ reset_status (); ++ last_line = false; ++ ++ if (files_ready_to_read < 1) ++ { ++ /* It's very helpful, normally the total number of pages is ++ not known in advance. */ ++ error (0, 0, ++ _("starting page number %"PRIuMAX ++ " exceeds page count %"PRIuMAX), ++ page, n); ++ break; ++ } ++ } ++ return files_ready_to_read > 0; ++} ++ ++/* Print a header. ++ ++ Formfeeds are assumed to use up two lines at the beginning of ++ the page. */ ++ ++static void ++print_header (void) ++{ ++ char page_text[256 + INT_STRLEN_BOUND (page_number)]; ++ int available_width; ++ int lhs_spaces; ++ int rhs_spaces; ++ ++ output_position = 0; ++ pad_across_to (chars_per_margin); ++ print_white_space (); ++ ++ if (page_number == 0) ++ error (EXIT_FAILURE, 0, _("page number overflow")); ++ ++ /* The translator must ensure that formatting the translation of ++ "Page %"PRIuMAX does not generate more than (sizeof page_text - 1) ++ bytes. */ ++ sprintf (page_text, _("Page %"PRIuMAX), page_number++); ++ available_width = header_width_available - mbswidth (page_text, 0); ++ available_width = MAX (0, available_width); ++ lhs_spaces = available_width >> 1; ++ rhs_spaces = available_width - lhs_spaces; ++ ++ printf ("\n\n%*.*s%s%*.*s%s%*.*s%s\n\n\n", ++ chars_per_margin, chars_per_margin, " ", ++ date_text, lhs_spaces, lhs_spaces, " ", ++ file_text, rhs_spaces, rhs_spaces, " ", page_text); ++ ++ print_a_header = false; ++ output_position = 0; ++} ++ ++/* Print (or store, if p->char_func is store_char()) a line. ++ ++ Read a character to determine whether we have a line or not. ++ (We may hit EOF, \n, or \f) ++ ++ Once we know we have a line, ++ set pad_vertically = true, meaning it's safe ++ to pad down at the end of the page, since we do have a page. ++ print a header if needed. ++ pad across to padding_not_printed if needed. ++ print any separators which need to be printed. ++ print a line number if it needs to be printed. ++ ++ Print the clump which corresponds to the first character. ++ ++ Enter a loop and keep printing until an end of line condition ++ exists, or until we exceed chars_per_column. ++ ++ Return false if we exceed chars_per_column before reading ++ an end of line character, true otherwise. */ ++ ++static bool ++read_line (COLUMN *p) ++{ ++ int c; ++ int chars IF_LINT (= 0); ++ int last_input_position; ++ int j, k; ++ COLUMN *q; ++ ++ /* read 1st character in each line or any character succeeding a FF: */ ++ c = getc (p->fp); ++ ++ last_input_position = input_position; ++ ++ if (c == '\f' && p->full_page_printed) ++ if ((c = getc (p->fp)) == '\n') ++ c = getc (p->fp); ++ p->full_page_printed = false; ++ ++ switch (c) ++ { ++ case '\f': ++ if ((c = getc (p->fp)) != '\n') ++ ungetc (c, p->fp); ++ FF_only = true; ++ if (print_a_header && !storing_columns) ++ { ++ pad_vertically = true; ++ print_header (); ++ } ++ else if (keep_FF) ++ print_a_FF = true; ++ hold_file (p); ++ return true; ++ case EOF: ++ close_file (p); ++ return true; ++ case '\n': ++ break; ++ default: ++ chars = char_to_clump (c); ++ } ++ ++ if (truncate_lines && input_position > chars_per_column) ++ { ++ input_position = last_input_position; ++ return false; ++ } ++ ++ if (p->char_func != store_char) ++ { ++ pad_vertically = true; ++ ++ if (print_a_header && !storing_columns) ++ print_header (); ++ ++ if (parallel_files && align_empty_cols) ++ { ++ /* We have to align empty columns at the beginning of a line. */ ++ k = separators_not_printed; ++ separators_not_printed = 0; ++ for (j = 1, q = column_vector; j <= k; ++j, ++q) ++ { ++ align_column (q); ++ separators_not_printed += 1; ++ } ++ padding_not_printed = p->start_position; ++ if (truncate_lines) ++ spaces_not_printed = chars_per_column; ++ else ++ spaces_not_printed = 0; ++ align_empty_cols = false; ++ } ++ ++ if (padding_not_printed - col_sep_length > 0) ++ { ++ pad_across_to (padding_not_printed - col_sep_length); ++ padding_not_printed = ANYWHERE; ++ } ++ ++ if (use_col_separator) ++ print_sep_string (); ++ } ++ ++ if (p->numbered) ++ add_line_number (p); ++ ++ empty_line = false; ++ if (c == '\n') ++ return true; ++ ++ print_clump (p, chars, clump_buff); ++ ++ for (;;) ++ { ++ c = getc (p->fp); ++ ++ switch (c) ++ { ++ case '\n': ++ return true; ++ case '\f': ++ if ((c = getc (p->fp)) != '\n') ++ ungetc (c, p->fp); ++ if (keep_FF) ++ print_a_FF = true; ++ hold_file (p); ++ return true; ++ case EOF: ++ close_file (p); ++ return true; ++ } ++ ++ last_input_position = input_position; ++ chars = char_to_clump (c); ++ if (truncate_lines && input_position > chars_per_column) ++ { ++ input_position = last_input_position; ++ return false; ++ } ++ ++ print_clump (p, chars, clump_buff); ++ } ++} ++ ++/* Print a line from buff. ++ ++ If this function has been called, we know we have "something to ++ print". But it remains to be seen whether we have a real text page ++ or an empty page (a single form feed) with/without a header only. ++ Therefore first we set pad_vertically to true and print a header ++ if necessary. ++ If FF_FOUND and we are using -t|-T option we omit any newline by ++ setting pad_vertically to false (see print_page). ++ Otherwise we pad across if necessary, print separators if necessary ++ and text of COLUMN *p. ++ ++ Return true, meaning there is no need to call read_rest_of_line. */ ++ ++static bool ++print_stored (COLUMN *p) ++{ ++ COLUMN *q; ++ int i; ++ ++ int line = p->current_line++; ++ char *first = &buff[line_vector[line]]; ++ /* FIXME ++ UMR: Uninitialized memory read: ++ * This is occurring while in: ++ print_stored [pr.c:2239] ++ * Reading 4 bytes from 0x5148c in the heap. ++ * Address 0x5148c is 4 bytes into a malloc'd block at 0x51488 of 676 bytes ++ * This block was allocated from: ++ malloc [rtlib.o] ++ xmalloc [xmalloc.c:94] ++ init_store_cols [pr.c:1648] ++ */ ++ char *last = &buff[line_vector[line + 1]]; ++ ++ pad_vertically = true; ++ ++ if (print_a_header) ++ print_header (); ++ ++ if (p->status == FF_FOUND) ++ { ++ for (i = 1, q = column_vector; i <= columns; ++i, ++q) ++ q->status = ON_HOLD; ++ if (column_vector->lines_to_print <= 0) ++ { ++ if (!extremities) ++ pad_vertically = false; ++ return true; /* print a header only */ ++ } ++ } ++ ++ if (padding_not_printed - col_sep_length > 0) ++ { ++ pad_across_to (padding_not_printed - col_sep_length); ++ padding_not_printed = ANYWHERE; ++ } ++ ++ if (use_col_separator) ++ print_sep_string (); ++ ++ while (first != last) ++ print_char (*first++); ++ ++ 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; ++ } ++ ++ return true; ++} ++ ++/* Convert a character to the proper format and return the number of ++ characters in the resulting clump. Increment input_position by ++ the width of the clump. ++ ++ Tabs are converted to clumps of spaces. ++ Nonprintable characters may be converted to clumps of escape ++ sequences or control prefixes. ++ ++ Note: the width of a clump is not necessarily equal to the number of ++ characters in clump_buff. (e.g, the width of '\b' is -1, while the ++ number of characters is 1.) */ ++ ++static int ++char_to_clump (char c) ++{ ++ unsigned char uc = c; ++ char *s = clump_buff; ++ int i; ++ char esc_buff[4]; ++ int width; ++ int chars; ++ int chars_per_c = 8; ++ ++ if (c == input_tab_char) ++ chars_per_c = chars_per_input_tab; ++ ++ if (c == input_tab_char || c == '\t') ++ { ++ width = TAB_WIDTH (chars_per_c, input_position); ++ ++ if (untabify_input) ++ { ++ for (i = width; i; --i) ++ *s++ = ' '; ++ chars = width; ++ } ++ else ++ { ++ *s = c; ++ chars = 1; ++ } ++ ++ } ++ else if (! isprint (uc)) ++ { ++ if (use_esc_sequence) ++ { ++ width = 4; ++ chars = 4; ++ *s++ = '\\'; ++ sprintf (esc_buff, "%03o", uc); ++ for (i = 0; i <= 2; ++i) ++ *s++ = esc_buff[i]; ++ } ++ else if (use_cntrl_prefix) ++ { ++ if (uc < 0200) ++ { ++ width = 2; ++ chars = 2; ++ *s++ = '^'; ++ *s++ = c ^ 0100; ++ } ++ else ++ { ++ width = 4; ++ chars = 4; ++ *s++ = '\\'; ++ sprintf (esc_buff, "%03o", uc); ++ for (i = 0; i <= 2; ++i) ++ *s++ = esc_buff[i]; ++ } ++ } ++ else if (c == '\b') ++ { ++ width = -1; ++ chars = 1; ++ *s = c; ++ } ++ else ++ { ++ width = 0; ++ chars = 1; ++ *s = c; ++ } ++ } ++ else ++ { ++ width = 1; ++ chars = 1; ++ *s = c; ++ } ++ ++ /* 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; ++} ++ ++/* We've just printed some files and need to clean up things before ++ looking for more options and printing the next batch of files. ++ ++ Free everything we've xmalloc'ed, except `header'. */ ++ ++static void ++cleanup (void) ++{ ++ free (number_buff); ++ free (clump_buff); ++ free (column_vector); ++ free (line_vector); ++ free (end_vector); ++ free (buff); ++} ++ ++/* Complain, print a usage message, and die. */ ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... [FILE]...\n\ ++"), ++ program_name); ++ ++ fputs (_("\ ++Paginate or columnate FILE(s) for printing.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ +FIRST_PAGE[:LAST_PAGE], --pages=FIRST_PAGE[:LAST_PAGE]\n\ ++ begin [stop] printing with page FIRST_[LAST_]PAGE\n\ ++ -COLUMN, --columns=COLUMN\n\ ++ output COLUMN columns and print columns down,\n\ ++ unless -a is used. Balance number of lines in the\n\ ++ columns on each page.\n\ ++"), stdout); ++ fputs (_("\ ++ -a, --across print columns across rather than down, used together\n\ ++ with -COLUMN\n\ ++ -c, --show-control-chars\n\ ++ use hat notation (^G) and octal backslash notation\n\ ++ -d, --double-space\n\ ++ double space the output\n\ ++"), stdout); ++ fputs (_("\ ++ -D, --date-format=FORMAT\n\ ++ use FORMAT for the header date\n\ ++ -e[CHAR[WIDTH]], --expand-tabs[=CHAR[WIDTH]]\n\ ++ expand input CHARs (TABs) to tab WIDTH (8)\n\ ++ -F, -f, --form-feed\n\ ++ use form feeds instead of newlines to separate pages\n\ ++ (by a 3-line page header with -F or a 5-line header\n\ ++ and trailer without -F)\n\ ++"), stdout); ++ fputs (_("\ ++ -h, --header=HEADER\n\ ++ use a centered HEADER instead of filename in page header,\n\ ++ -h \"\" prints a blank line, don't use -h\"\"\n\ ++ -i[CHAR[WIDTH]], --output-tabs[=CHAR[WIDTH]]\n\ ++ replace spaces with CHARs (TABs) to tab WIDTH (8)\n\ ++ -J, --join-lines merge full lines, turns off -W line truncation, no column\n\ ++ alignment, --sep-string[=STRING] sets separators\n\ ++"), stdout); ++ fputs (_("\ ++ -l, --length=PAGE_LENGTH\n\ ++ set the page length to PAGE_LENGTH (66) lines\n\ ++ (default number of lines of text 56, and with -F 63)\n\ ++ -m, --merge print all files in parallel, one in each column,\n\ ++ truncate lines, but join lines of full length with -J\n\ ++"), stdout); ++ fputs (_("\ ++ -n[SEP[DIGITS]], --number-lines[=SEP[DIGITS]]\n\ ++ number lines, use DIGITS (5) digits, then SEP (TAB),\n\ ++ default counting starts with 1st line of input file\n\ ++ -N, --first-line-number=NUMBER\n\ ++ start counting with NUMBER at 1st line of first\n\ ++ page printed (see +FIRST_PAGE)\n\ ++"), stdout); ++ fputs (_("\ ++ -o, --indent=MARGIN\n\ ++ offset each line with MARGIN (zero) spaces, do not\n\ ++ affect -w or -W, MARGIN will be added to PAGE_WIDTH\n\ ++ -r, --no-file-warnings\n\ ++ omit warning when a file cannot be opened\n\ ++"), stdout); ++ fputs (_("\ ++ -s[CHAR],--separator[=CHAR]\n\ ++ separate columns by a single character, default for CHAR\n\ ++ is the character without -w and \'no char\' with -w\n\ ++ -s[CHAR] turns off line truncation of all 3 column\n\ ++ options (-COLUMN|-a -COLUMN|-m) except -w is set\n\ ++"), stdout); ++ fputs (_("\ ++ -SSTRING, --sep-string[=STRING]\n\ ++ separate columns by STRING,\n\ ++ without -S: Default separator with -J and \n\ ++ otherwise (same as -S\" \"), no effect on column options\n\ ++ -t, --omit-header omit page headers and trailers\n\ ++"), stdout); ++ fputs (_("\ ++ -T, --omit-pagination\n\ ++ omit page headers and trailers, eliminate any pagination\n\ ++ by form feeds set in input files\n\ ++ -v, --show-nonprinting\n\ ++ use octal backslash notation\n\ ++ -w, --width=PAGE_WIDTH\n\ ++ set page width to PAGE_WIDTH (72) characters for\n\ ++ multiple text-column output only, -s[char] turns off (72)\n\ ++"), stdout); ++ fputs (_("\ ++ -W, --page-width=PAGE_WIDTH\n\ ++ set page width to PAGE_WIDTH (72) characters always,\n\ ++ truncate lines, except -J option is set, no interference\n\ ++ with -S or -s\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++-t is implied if PAGE_LENGTH <= 10. With no FILE, or when\n\ ++FILE is -, read standard input.\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} +diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c +--- coreutils-8.0-orig/src/sort.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/sort.c 2009-10-07 10:07:16.000000000 +0200 +@@ -22,10 +22,19 @@ #include @@ -1599,7 +8380,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -116,14 +125,38 @@ +@@ -122,14 +131,38 @@ static int decimal_point; /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; @@ -1639,7 +8420,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -261,13 +294,11 @@ +@@ -268,13 +301,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -1656,7 +8437,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -639,6 +670,44 @@ +@@ -712,6 +743,44 @@ reap_some (void) update_proc (pid); } @@ -1701,7 +8482,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* Clean up any remaining temporary files. */ static void -@@ -978,7 +1047,7 @@ +@@ -1093,7 +1162,7 @@ zaptemp (const char *name) free (node); } @@ -1710,7 +8491,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c static int struct_month_cmp (const void *m1, const void *m2) -@@ -993,7 +1062,7 @@ +@@ -1108,7 +1177,7 @@ struct_month_cmp (const void *m1, const /* Initialize the character class tables. */ static void @@ -1719,7 +8500,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { size_t i; -@@ -1005,7 +1074,7 @@ +@@ -1120,7 +1189,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -1728,7 +8509,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1031,6 +1100,64 @@ +@@ -1202,6 +1271,64 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -1793,7 +8574,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1241,7 +1368,7 @@ +@@ -1412,7 +1539,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -1802,7 +8583,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1251,10 +1378,10 @@ +@@ -1421,10 +1548,10 @@ begfield (const struct line *line, const /* The leading field separator itself is included in a field when -t is absent. */ @@ -1815,7 +8596,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c ++ptr; if (ptr < lim) ++ptr; -@@ -1282,11 +1409,70 @@ +@@ -1450,11 +1577,70 @@ begfield (const struct line *line, const return ptr; } @@ -1887,7 +8668,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1299,10 +1485,10 @@ +@@ -1469,10 +1655,10 @@ limfield (const struct line *line, const `beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first `blank' character after the preceding field. */ @@ -1898,9 +8679,9 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c - while (ptr < lim && *ptr != tab) + while (ptr < lim && *ptr != tab[0]) ++ptr; - if (ptr < lim && (eword | echar)) + if (ptr < lim && (eword || echar)) ++ptr; -@@ -1348,10 +1534,10 @@ +@@ -1518,10 +1704,10 @@ limfield (const struct line *line, const */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -1913,7 +8694,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c if (newlim) lim = newlim; } -@@ -1384,6 +1570,113 @@ +@@ -1552,6 +1738,113 @@ limfield (const struct line *line, const return ptr; } @@ -2027,7 +8808,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* 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 -@@ -1466,8 +1753,24 @@ +@@ -1634,8 +1927,24 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2054,7 +8835,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c line->keybeg = line_start; } } -@@ -1500,7 +1803,7 @@ +@@ -1673,7 +1982,7 @@ fillbuf (struct buffer *buf, FILE *fp, c hideously fast. */ static int @@ -2063,7 +8844,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { while (blanks[to_uchar (*a)]) a++; -@@ -1510,6 +1813,25 @@ +@@ -1782,6 +2091,25 @@ human_numcompare (const char *a, const c : strnumcmp (a, b, decimal_point, thousands_sep)); } @@ -2089,7 +8870,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c static int general_numcompare (const char *sa, const char *sb) { -@@ -1543,7 +1865,7 @@ +@@ -1815,7 +2143,7 @@ general_numcompare (const char *sa, cons Return 0 if the name in S is not recognized. */ static int @@ -2098,7 +8879,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -1698,11 +2020,79 @@ +@@ -1996,11 +2324,79 @@ compare_version (char *restrict texta, s return diff; } @@ -2179,7 +8960,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c { struct keyfield *key = keylist; -@@ -1875,6 +2265,179 @@ +@@ -2180,6 +2576,179 @@ keycompare (const struct line *a, const return key->reverse ? -diff : diff; } @@ -2358,8 +9139,8 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c + /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ - -@@ -2744,7 +3307,7 @@ + +@@ -3178,7 +3747,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2368,7 +9149,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -2765,6 +3328,27 @@ +@@ -3199,6 +3768,27 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -2396,7 +9177,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c have_read_stdin = false; inittables (); -@@ -3015,13 +3599,35 @@ +@@ -3459,13 +4049,35 @@ main (int argc, char **argv) case 't': { @@ -2436,7 +9217,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c else { /* Provoke with `sort -txx'. Complain about -@@ -3032,9 +3638,12 @@ +@@ -3476,9 +4088,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -2451,9 +9232,3711 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c } break; ---- coreutils-6.8+/src/unexpand.c.i18n 2007-01-14 15:41:28.000000000 +0000 -+++ coreutils-6.8+/src/unexpand.c 2007-03-01 15:08:24.000000000 +0000 -@@ -39,11 +39,28 @@ +diff -urNp coreutils-8.0-orig/src/sort.c.orig coreutils-8.0/src/sort.c.orig +--- coreutils-8.0-orig/src/sort.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/sort.c.orig 2009-09-29 15:27:54.000000000 +0200 +@@ -0,0 +1,3697 @@ ++/* sort - sort lines of text (with all kinds of options). ++ Copyright (C) 1988, 1991-2009 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 December 1988 by Mike Haertel. ++ The author may be reached (Email) at the address mike@gnu.ai.mit.edu, ++ or (US mail) as Mike Haertel c/o Free Software Foundation. ++ ++ Ørn E. Hansen added NLS support in 1997. */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include "system.h" ++#include "argmatch.h" ++#include "error.h" ++#include "filevercmp.h" ++#include "hard-locale.h" ++#include "hash.h" ++#include "md5.h" ++#include "physmem.h" ++#include "posixver.h" ++#include "quote.h" ++#include "quotearg.h" ++#include "randread.h" ++#include "readtokens0.h" ++#include "stdio--.h" ++#include "stdlib--.h" ++#include "strnumcmp.h" ++#include "xmemcoll.h" ++#include "xmemxfrm.h" ++#include "xstrtol.h" ++ ++#if HAVE_SYS_RESOURCE_H ++# include ++#endif ++#ifndef RLIMIT_DATA ++struct rlimit { size_t rlim_cur; }; ++# define getrlimit(Resource, Rlp) (-1) ++#endif ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "sort" ++ ++#define AUTHORS \ ++ proper_name ("Mike Haertel"), \ ++ proper_name ("Paul Eggert") ++ ++#if HAVE_LANGINFO_CODESET ++# include ++#endif ++ ++/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is ++ present. */ ++#ifndef SA_NOCLDSTOP ++# define SA_NOCLDSTOP 0 ++/* No sigprocmask. Always 'return' zero. */ ++# define sigprocmask(How, Set, Oset) (0) ++# define sigset_t int ++# if ! HAVE_SIGINTERRUPT ++# define siginterrupt(sig, flag) /* empty */ ++# endif ++#endif ++ ++#if !defined OPEN_MAX && defined NR_OPEN ++# define OPEN_MAX NR_OPEN ++#endif ++#if !defined OPEN_MAX ++# define OPEN_MAX 20 ++#endif ++ ++#define UCHAR_LIM (UCHAR_MAX + 1) ++ ++#ifndef DEFAULT_TMPDIR ++# define DEFAULT_TMPDIR "/tmp" ++#endif ++ ++/* Exit statuses. */ ++enum ++ { ++ /* POSIX says to exit with status 1 if invoked with -c and the ++ input is not properly sorted. */ ++ SORT_OUT_OF_ORDER = 1, ++ ++ /* POSIX says any other irregular exit must exit with a status ++ code greater than 1. */ ++ SORT_FAILURE = 2 ++ }; ++ ++enum ++ { ++ /* The number of times we should try to fork a compression process ++ (we retry if the fork call fails). We don't _need_ to compress ++ temp files, this is just to reduce disk access, so this number ++ can be small. */ ++ MAX_FORK_TRIES_COMPRESS = 2, ++ ++ /* The number of times we should try to fork a decompression process. ++ If we can't fork a decompression process, we can't sort, so this ++ number should be big. */ ++ MAX_FORK_TRIES_DECOMPRESS = 8 ++ }; ++ ++/* The representation of the decimal point in the current locale. */ ++static int decimal_point; ++ ++/* Thousands separator; if -1, then there isn't one. */ ++static int thousands_sep; ++ ++/* Nonzero if the corresponding locales are hard. */ ++static bool hard_LC_COLLATE; ++#if HAVE_NL_LANGINFO ++static bool hard_LC_TIME; ++#endif ++ ++#define NONZERO(x) ((x) != 0) ++ ++/* The kind of blanks for '-b' to skip in various options. */ ++enum blanktype { bl_start, bl_end, bl_both }; ++ ++/* The character marking end of line. Default to \n. */ ++static char eolchar = '\n'; ++ ++/* Lines are held in core as counted strings. */ ++struct line ++{ ++ char *text; /* Text of the line. */ ++ size_t length; /* Length including final newline. */ ++ char *keybeg; /* Start of first key. */ ++ char *keylim; /* Limit of first key. */ ++}; ++ ++/* Input buffers. */ ++struct buffer ++{ ++ char *buf; /* Dynamically allocated buffer, ++ partitioned into 3 regions: ++ - input data; ++ - unused area; ++ - an array of lines, in reverse order. */ ++ size_t used; /* Number of bytes used for input data. */ ++ size_t nlines; /* Number of lines in the line array. */ ++ size_t alloc; /* Number of bytes allocated. */ ++ size_t left; /* Number of bytes left from previous reads. */ ++ size_t line_bytes; /* Number of bytes to reserve for each line. */ ++ bool eof; /* An EOF has been read. */ ++}; ++ ++struct keyfield ++{ ++ size_t sword; /* Zero-origin 'word' to start at. */ ++ size_t schar; /* Additional characters to skip. */ ++ size_t eword; /* Zero-origin first word after field. */ ++ size_t echar; /* Additional characters in field. */ ++ bool const *ignore; /* Boolean array of characters to ignore. */ ++ char const *translate; /* Translation applied to characters. */ ++ bool skipsblanks; /* Skip leading blanks when finding start. */ ++ bool skipeblanks; /* Skip leading blanks when finding end. */ ++ bool numeric; /* Flag for numeric comparison. Handle ++ strings of digits with optional decimal ++ point, but no exponential notation. */ ++ bool random; /* Sort by random hash of key. */ ++ bool general_numeric; /* Flag for general, numeric comparison. ++ Handle numbers in exponential notation. */ ++ bool human_numeric; /* Flag for sorting by human readable ++ units with either SI xor IEC prefixes. */ ++ int si_present; /* Flag for checking for mixed SI and IEC. */ ++ bool month; /* Flag for comparison by month name. */ ++ bool reverse; /* Reverse the sense of comparison. */ ++ bool version; /* sort by version number */ ++ struct keyfield *next; /* Next keyfield to try. */ ++}; ++ ++struct month ++{ ++ char const *name; ++ int val; ++}; ++ ++/* FIXME: None of these tables work with multibyte character sets. ++ Also, there are many other bugs when handling multibyte characters. ++ One way to fix this is to rewrite `sort' to use wide characters ++ internally, but doing this with good performance is a bit ++ tricky. */ ++ ++/* Table of blanks. */ ++static bool blanks[UCHAR_LIM]; ++ ++/* Table of non-printing characters. */ ++static bool nonprinting[UCHAR_LIM]; ++ ++/* Table of non-dictionary characters (not letters, digits, or blanks). */ ++static bool nondictionary[UCHAR_LIM]; ++ ++/* Translation table folding lower case to upper. */ ++static char fold_toupper[UCHAR_LIM]; ++ ++#define MONTHS_PER_YEAR 12 ++ ++/* Table mapping month names to integers. ++ Alphabetic order allows binary search. */ ++static struct month monthtab[] = ++{ ++ {"APR", 4}, ++ {"AUG", 8}, ++ {"DEC", 12}, ++ {"FEB", 2}, ++ {"JAN", 1}, ++ {"JUL", 7}, ++ {"JUN", 6}, ++ {"MAR", 3}, ++ {"MAY", 5}, ++ {"NOV", 11}, ++ {"OCT", 10}, ++ {"SEP", 9} ++}; ++ ++/* During the merge phase, the number of files to merge at once. */ ++#define NMERGE_DEFAULT 16 ++ ++/* Minimum size for a merge or check buffer. */ ++#define MIN_MERGE_BUFFER_SIZE (2 + sizeof (struct line)) ++ ++/* Minimum sort size; the code might not work with smaller sizes. */ ++#define MIN_SORT_SIZE (nmerge * MIN_MERGE_BUFFER_SIZE) ++ ++/* The number of bytes needed for a merge or check buffer, which can ++ function relatively efficiently even if it holds only one line. If ++ a longer line is seen, this value is increased. */ ++static size_t merge_buffer_size = MAX (MIN_MERGE_BUFFER_SIZE, 256 * 1024); ++ ++/* The approximate maximum number of bytes of main memory to use, as ++ specified by the user. Zero if the user has not specified a size. */ ++static size_t sort_size; ++ ++/* The guessed size for non-regular files. */ ++#define INPUT_FILE_SIZE_GUESS (1024 * 1024) ++ ++/* Array of directory names in which any temporary files are to be created. */ ++static char const **temp_dirs; ++ ++/* Number of temporary directory names used. */ ++static size_t temp_dir_count; ++ ++/* Number of allocated slots in temp_dirs. */ ++static size_t temp_dir_alloc; ++ ++/* Flag to reverse the order of all comparisons. */ ++static bool reverse; ++ ++/* Flag for stable sort. This turns off the last ditch bytewise ++ comparison of lines, and instead leaves lines in the same order ++ 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 ++ separated by the empty string between a non-blank character and a blank ++ character. */ ++static int tab = TAB_DEFAULT; ++ ++/* Flag to remove consecutive duplicate lines from the output. ++ Only the last of a sequence of equal lines will be output. */ ++static bool unique; ++ ++/* Nonzero if any of the input files are the standard input. */ ++static bool have_read_stdin; ++ ++/* List of key field comparisons to be tried. */ ++static struct keyfield *keylist; ++ ++/* Program used to (de)compress temp files. Must accept -d. */ ++static char const *compress_program; ++ ++/* Maximum number of files to merge in one go. If more than this ++ number are present, temp files will be used. */ ++static unsigned int nmerge = NMERGE_DEFAULT; ++ ++static void sortlines_temp (struct line *, size_t, struct line *); ++ ++/* Report MESSAGE for FILE, then clean up and exit. ++ If FILE is null, it represents standard output. */ ++ ++static void die (char const *, char const *) ATTRIBUTE_NORETURN; ++static void ++die (char const *message, char const *file) ++{ ++ error (0, errno, "%s: %s", message, file ? file : _("standard output")); ++ exit (SORT_FAILURE); ++} ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... [FILE]...\n\ ++ or: %s [OPTION]... --files0-from=F\n\ ++"), ++ program_name, program_name); ++ fputs (_("\ ++Write sorted concatenation of all FILE(s) to standard output.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++Ordering options:\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++ -b, --ignore-leading-blanks ignore leading blanks\n\ ++ -d, --dictionary-order consider only blanks and alphanumeric characters\n\ ++ -f, --ignore-case fold lower case to upper case characters\n\ ++"), stdout); ++ fputs (_("\ ++ -g, --general-numeric-sort compare according to general numerical value\n\ ++ -i, --ignore-nonprinting consider only printable characters\n\ ++ -M, --month-sort compare (unknown) < `JAN' < ... < `DEC'\n\ ++"), stdout); ++ fputs (_("\ ++ -h, --human-numeric-sort compare human readable numbers (e.g., 2K 1G)\n\ ++"), stdout); ++ fputs (_("\ ++ -n, --numeric-sort compare according to string numerical value\n\ ++ -R, --random-sort sort by random hash of keys\n\ ++ --random-source=FILE get random bytes from FILE\n\ ++ -r, --reverse reverse the result of comparisons\n\ ++"), stdout); ++ fputs (_("\ ++ --sort=WORD sort according to WORD:\n\ ++ general-numeric -g, human-numeric -h, month -M,\n\ ++ numeric -n, random -R, version -V\n\ ++ -V, --version-sort natural sort of (version) numbers within text\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Other options:\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++ --batch-size=NMERGE merge at most NMERGE inputs at once;\n\ ++ for more use temp files\n\ ++"), stdout); ++ fputs (_("\ ++ -c, --check, --check=diagnose-first check for sorted input; do not sort\n\ ++ -C, --check=quiet, --check=silent like -c, but do not report first bad line\n\ ++ --compress-program=PROG compress temporaries with PROG;\n\ ++ decompress them with PROG -d\n\ ++ --files0-from=F read input from the files specified by\n\ ++ NUL-terminated names in file F;\n\ ++ If F is - then read names from standard input\n\ ++"), stdout); ++ fputs (_("\ ++ -k, --key=POS1[,POS2] start a key at POS1 (origin 1), end it at POS2\n\ ++ (default end of line)\n\ ++ -m, --merge merge already sorted files; do not sort\n\ ++"), stdout); ++ fputs (_("\ ++ -o, --output=FILE write result to FILE instead of standard output\n\ ++ -s, --stable stabilize sort by disabling last-resort comparison\n\ ++ -S, --buffer-size=SIZE use SIZE for main memory buffer\n\ ++"), stdout); ++ printf (_("\ ++ -t, --field-separator=SEP use SEP instead of non-blank to blank transition\n\ ++ -T, --temporary-directory=DIR use DIR for temporaries, not $TMPDIR or %s;\n\ ++ multiple options specify multiple directories\n\ ++ -u, --unique with -c, check for strict ordering;\n\ ++ without -c, output only the first of an equal run\n\ ++"), DEFAULT_TMPDIR); ++ fputs (_("\ ++ -z, --zero-terminated end lines with 0 byte, not newline\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++POS is F[.C][OPTS], where F is the field number and C the character position\n\ ++in the field; both are origin 1. If neither -t nor -b is in effect, characters\n\ ++in a field are counted from the beginning of the preceding whitespace. OPTS is\n\ ++one or more single-letter ordering options, which override global ordering\n\ ++options for that key. If no key is given, use the entire line as the key.\n\ ++\n\ ++SIZE may be followed by the following multiplicative suffixes:\n\ ++"), stdout); ++ fputs (_("\ ++% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y.\n\ ++\n\ ++With no FILE, or when FILE is -, read standard input.\n\ ++\n\ ++*** WARNING ***\n\ ++The locale specified by the environment affects sort order.\n\ ++Set LC_ALL=C to get the traditional sort order that uses\n\ ++native byte values.\n\ ++"), stdout ); ++ emit_ancillary_info (); ++ } ++ ++ exit (status); ++} ++ ++/* For long options that have no equivalent short option, use a ++ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ ++enum ++{ ++ CHECK_OPTION = CHAR_MAX + 1, ++ COMPRESS_PROGRAM_OPTION, ++ FILES0_FROM_OPTION, ++ NMERGE_OPTION, ++ RANDOM_SOURCE_OPTION, ++ SORT_OPTION ++}; ++ ++static char const short_options[] = "-bcCdfghik:mMno:rRsS:t:T:uVy:z"; ++ ++static struct option const long_options[] = ++{ ++ {"ignore-leading-blanks", no_argument, NULL, 'b'}, ++ {"check", optional_argument, NULL, CHECK_OPTION}, ++ {"compress-program", required_argument, NULL, COMPRESS_PROGRAM_OPTION}, ++ {"dictionary-order", no_argument, NULL, 'd'}, ++ {"ignore-case", no_argument, NULL, 'f'}, ++ {"files0-from", required_argument, NULL, FILES0_FROM_OPTION}, ++ {"general-numeric-sort", no_argument, NULL, 'g'}, ++ {"ignore-nonprinting", no_argument, NULL, 'i'}, ++ {"key", required_argument, NULL, 'k'}, ++ {"merge", no_argument, NULL, 'm'}, ++ {"month-sort", no_argument, NULL, 'M'}, ++ {"numeric-sort", no_argument, NULL, 'n'}, ++ {"human-numeric-sort", no_argument, NULL, 'h'}, ++ {"version-sort", no_argument, NULL, 'V'}, ++ {"random-sort", no_argument, NULL, 'R'}, ++ {"random-source", required_argument, NULL, RANDOM_SOURCE_OPTION}, ++ {"sort", required_argument, NULL, SORT_OPTION}, ++ {"output", required_argument, NULL, 'o'}, ++ {"reverse", no_argument, NULL, 'r'}, ++ {"stable", no_argument, NULL, 's'}, ++ {"batch-size", required_argument, NULL, NMERGE_OPTION}, ++ {"buffer-size", required_argument, NULL, 'S'}, ++ {"field-separator", required_argument, NULL, 't'}, ++ {"temporary-directory", required_argument, NULL, 'T'}, ++ {"unique", no_argument, NULL, 'u'}, ++ {"zero-terminated", no_argument, NULL, 'z'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0}, ++}; ++ ++#define CHECK_TABLE \ ++ _ct_("quiet", 'C') \ ++ _ct_("silent", 'C') \ ++ _ct_("diagnose-first", 'c') ++ ++static char const *const check_args[] = ++{ ++#define _ct_(_s, _c) _s, ++ CHECK_TABLE NULL ++#undef _ct_ ++}; ++static char const check_types[] = ++{ ++#define _ct_(_s, _c) _c, ++ CHECK_TABLE ++#undef _ct_ ++}; ++ ++#define SORT_TABLE \ ++ _st_("general-numeric", 'g') \ ++ _st_("human-numeric", 'h') \ ++ _st_("month", 'M') \ ++ _st_("numeric", 'n') \ ++ _st_("random", 'R') \ ++ _st_("version", 'V') ++ ++static char const *const sort_args[] = ++{ ++#define _st_(_s, _c) _s, ++ SORT_TABLE NULL ++#undef _st_ ++}; ++static char const sort_types[] = ++{ ++#define _st_(_s, _c) _c, ++ SORT_TABLE ++#undef _st_ ++}; ++ ++/* The set of signals that are caught. */ ++static sigset_t caught_signals; ++ ++/* Critical section status. */ ++struct cs_status ++{ ++ bool valid; ++ sigset_t sigs; ++}; ++ ++/* Enter a critical section. */ ++static struct cs_status ++cs_enter (void) ++{ ++ struct cs_status status; ++ status.valid = (sigprocmask (SIG_BLOCK, &caught_signals, &status.sigs) == 0); ++ return status; ++} ++ ++/* Leave a critical section. */ ++static void ++cs_leave (struct cs_status status) ++{ ++ if (status.valid) ++ { ++ /* Ignore failure when restoring the signal mask. */ ++ sigprocmask (SIG_SETMASK, &status.sigs, NULL); ++ } ++} ++ ++/* The list of temporary files. */ ++struct tempnode ++{ ++ struct tempnode *volatile next; ++ pid_t pid; /* If compressed, the pid of compressor, else zero */ ++ char name[1]; /* Actual size is 1 + file name length. */ ++}; ++static struct tempnode *volatile temphead; ++static struct tempnode *volatile *temptail = &temphead; ++ ++struct sortfile ++{ ++ char const *name; ++ pid_t pid; /* If compressed, the pid of compressor, else zero */ ++}; ++ ++/* A table where we store compression process states. We clean up all ++ processes in a timely manner so as not to exhaust system resources, ++ so we store the info on whether the process is still running, or has ++ been reaped here. */ ++static Hash_table *proctab; ++ ++enum { INIT_PROCTAB_SIZE = 47 }; ++ ++enum procstate { ALIVE, ZOMBIE }; ++ ++/* A proctab entry. The COUNT field is there in case we fork a new ++ compression process that has the same PID as an old zombie process ++ that is still in the table (because the process to decompress the ++ temp file it was associated with hasn't started yet). */ ++struct procnode ++{ ++ pid_t pid; ++ enum procstate state; ++ size_t count; ++}; ++ ++static size_t ++proctab_hasher (const void *entry, size_t tabsize) ++{ ++ const struct procnode *node = entry; ++ return node->pid % tabsize; ++} ++ ++static bool ++proctab_comparator (const void *e1, const void *e2) ++{ ++ const struct procnode *n1 = e1, *n2 = e2; ++ return n1->pid == n2->pid; ++} ++ ++/* The total number of forked processes (compressors and decompressors) ++ that have not been reaped yet. */ ++static size_t nprocs; ++ ++/* The number of child processes we'll allow before we try to reap some. */ ++enum { MAX_PROCS_BEFORE_REAP = 2 }; ++ ++/* If 0 < PID, wait for the child process with that PID to exit. ++ If PID is -1, clean up a random child process which has finished and ++ return the process ID of that child. If PID is -1 and no processes ++ have quit yet, return 0 without waiting. */ ++ ++static pid_t ++reap (pid_t pid) ++{ ++ int status; ++ pid_t cpid = waitpid (pid, &status, pid < 0 ? WNOHANG : 0); ++ ++ if (cpid < 0) ++ error (SORT_FAILURE, errno, _("waiting for %s [-d]"), ++ compress_program); ++ else if (0 < cpid) ++ { ++ if (! WIFEXITED (status) || WEXITSTATUS (status)) ++ error (SORT_FAILURE, 0, _("%s [-d] terminated abnormally"), ++ compress_program); ++ --nprocs; ++ } ++ ++ return cpid; ++} ++ ++/* Add the PID of a running compression process to proctab, or update ++ the entry COUNT and STATE fields if it's already there. This also ++ creates the table for us the first time it's called. */ ++ ++static void ++register_proc (pid_t pid) ++{ ++ struct procnode test, *node; ++ ++ if (! proctab) ++ { ++ proctab = hash_initialize (INIT_PROCTAB_SIZE, NULL, ++ proctab_hasher, ++ proctab_comparator, ++ free); ++ if (! proctab) ++ xalloc_die (); ++ } ++ ++ test.pid = pid; ++ node = hash_lookup (proctab, &test); ++ if (node) ++ { ++ node->state = ALIVE; ++ ++node->count; ++ } ++ else ++ { ++ node = xmalloc (sizeof *node); ++ node->pid = pid; ++ node->state = ALIVE; ++ node->count = 1; ++ if (hash_insert (proctab, node) == NULL) ++ xalloc_die (); ++ } ++} ++ ++/* This is called when we reap a random process. We don't know ++ whether we have reaped a compression process or a decompression ++ process until we look in the table. If there's an ALIVE entry for ++ it, then we have reaped a compression process, so change the state ++ to ZOMBIE. Otherwise, it's a decompression processes, so ignore it. */ ++ ++static void ++update_proc (pid_t pid) ++{ ++ struct procnode test, *node; ++ ++ test.pid = pid; ++ node = hash_lookup (proctab, &test); ++ if (node) ++ node->state = ZOMBIE; ++} ++ ++/* This is for when we need to wait for a compression process to exit. ++ If it has a ZOMBIE entry in the table then it's already dead and has ++ been reaped. Note that if there's an ALIVE entry for it, it still may ++ already have died and been reaped if a second process was created with ++ the same PID. This is probably exceedingly rare, but to be on the safe ++ side we will have to wait for any compression process with this PID. */ ++ ++static void ++wait_proc (pid_t pid) ++{ ++ struct procnode test, *node; ++ ++ test.pid = pid; ++ node = hash_lookup (proctab, &test); ++ if (node->state == ALIVE) ++ reap (pid); ++ ++ node->state = ZOMBIE; ++ if (! --node->count) ++ { ++ hash_delete (proctab, node); ++ free (node); ++ } ++} ++ ++/* Keep reaping finished children as long as there are more to reap. ++ This doesn't block waiting for any of them, it only reaps those ++ that are already dead. */ ++ ++static void ++reap_some (void) ++{ ++ pid_t pid; ++ ++ while (0 < nprocs && (pid = reap (-1))) ++ update_proc (pid); ++} ++ ++/* Clean up any remaining temporary files. */ ++ ++static void ++cleanup (void) ++{ ++ struct tempnode const *node; ++ ++ for (node = temphead; node; node = node->next) ++ unlink (node->name); ++ temphead = NULL; ++} ++ ++/* Cleanup actions to take when exiting. */ ++ ++static void ++exit_cleanup (void) ++{ ++ if (temphead) ++ { ++ /* Clean up any remaining temporary files in a critical section so ++ that a signal handler does not try to clean them too. */ ++ struct cs_status cs = cs_enter (); ++ cleanup (); ++ cs_leave (cs); ++ } ++ ++ close_stdout (); ++} ++ ++/* Create a new temporary file, returning its newly allocated tempnode. ++ Store into *PFD the file descriptor open for writing. ++ If the creation fails, return NULL and store -1 into *PFD if the ++ failure is due to file descriptor exhaustion and ++ SURVIVE_FD_EXHAUSTION; otherwise, die. */ ++ ++static struct tempnode * ++create_temp_file (int *pfd, bool survive_fd_exhaustion) ++{ ++ static char const slashbase[] = "/sortXXXXXX"; ++ static size_t temp_dir_index; ++ int fd; ++ int saved_errno; ++ char const *temp_dir = temp_dirs[temp_dir_index]; ++ size_t len = strlen (temp_dir); ++ struct tempnode *node = ++ xmalloc (offsetof (struct tempnode, name) + len + sizeof slashbase); ++ char *file = node->name; ++ struct cs_status cs; ++ ++ memcpy (file, temp_dir, len); ++ memcpy (file + len, slashbase, sizeof slashbase); ++ node->next = NULL; ++ node->pid = 0; ++ if (++temp_dir_index == temp_dir_count) ++ temp_dir_index = 0; ++ ++ /* Create the temporary file in a critical section, to avoid races. */ ++ cs = cs_enter (); ++ fd = mkstemp (file); ++ if (0 <= fd) ++ { ++ *temptail = node; ++ temptail = &node->next; ++ } ++ saved_errno = errno; ++ cs_leave (cs); ++ errno = saved_errno; ++ ++ if (fd < 0) ++ { ++ if (! (survive_fd_exhaustion && errno == EMFILE)) ++ error (SORT_FAILURE, errno, _("cannot create temporary file in %s"), ++ quote (temp_dir)); ++ free (node); ++ node = NULL; ++ } ++ ++ *pfd = fd; ++ return node; ++} ++ ++/* Return a stream for FILE, opened with mode HOW. A null FILE means ++ standard output; HOW should be "w". When opening for input, "-" ++ means standard input. To avoid confusion, do not return file ++ descriptors STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO when ++ opening an ordinary FILE. Return NULL if unsuccessful. */ ++ ++static FILE * ++stream_open (const char *file, const char *how) ++{ ++ if (!file) ++ return stdout; ++ if (STREQ (file, "-") && *how == 'r') ++ { ++ have_read_stdin = true; ++ return stdin; ++ } ++ return fopen (file, how); ++} ++ ++/* Same as stream_open, except always return a non-null value; die on ++ failure. */ ++ ++static FILE * ++xfopen (const char *file, const char *how) ++ { ++ FILE *fp = stream_open (file, how); ++ if (!fp) ++ die (_("open failed"), file); ++ return fp; ++} ++ ++/* Close FP, whose name is FILE, and report any errors. */ ++ ++static void ++xfclose (FILE *fp, char const *file) ++{ ++ switch (fileno (fp)) ++ { ++ case STDIN_FILENO: ++ /* Allow reading stdin from tty more than once. */ ++ if (feof (fp)) ++ clearerr (fp); ++ break; ++ ++ case STDOUT_FILENO: ++ /* Don't close stdout just yet. close_stdout does that. */ ++ if (fflush (fp) != 0) ++ die (_("fflush failed"), file); ++ break; ++ ++ default: ++ if (fclose (fp) != 0) ++ die (_("close failed"), file); ++ break; ++ } ++} ++ ++static void ++dup2_or_die (int oldfd, int newfd) ++{ ++ if (dup2 (oldfd, newfd) < 0) ++ error (SORT_FAILURE, errno, _("dup2 failed")); ++} ++ ++/* Fork a child process for piping to and do common cleanup. The ++ TRIES parameter tells us how many times to try to fork before ++ giving up. Return the PID of the child, or -1 (setting errno) ++ on failure. */ ++ ++static pid_t ++pipe_fork (int pipefds[2], size_t tries) ++{ ++#if HAVE_WORKING_FORK ++ struct tempnode *saved_temphead; ++ int saved_errno; ++ unsigned int wait_retry = 1; ++ pid_t pid IF_LINT (= -1); ++ struct cs_status cs; ++ ++ if (pipe (pipefds) < 0) ++ return -1; ++ ++ while (tries--) ++ { ++ /* This is so the child process won't delete our temp files ++ if it receives a signal before exec-ing. */ ++ cs = cs_enter (); ++ saved_temphead = temphead; ++ temphead = NULL; ++ ++ pid = fork (); ++ saved_errno = errno; ++ if (pid) ++ temphead = saved_temphead; ++ ++ cs_leave (cs); ++ errno = saved_errno; ++ ++ if (0 <= pid || errno != EAGAIN) ++ break; ++ else ++ { ++ sleep (wait_retry); ++ wait_retry *= 2; ++ reap_some (); ++ } ++ } ++ ++ if (pid < 0) ++ { ++ saved_errno = errno; ++ close (pipefds[0]); ++ close (pipefds[1]); ++ errno = saved_errno; ++ } ++ else if (pid == 0) ++ { ++ close (STDIN_FILENO); ++ close (STDOUT_FILENO); ++ } ++ else ++ ++nprocs; ++ ++ return pid; ++ ++#else /* ! HAVE_WORKING_FORK */ ++ return -1; ++#endif ++} ++ ++/* Create a temporary file and start a compression program to filter output ++ to that file. Set *PFP to the file handle and if PPID is non-NULL, ++ set *PPID to the PID of the newly-created process. If the creation ++ fails, return NULL if the failure is due to file descriptor ++ exhaustion and SURVIVE_FD_EXHAUSTION; otherwise, die. */ ++ ++static char * ++maybe_create_temp (FILE **pfp, pid_t *ppid, bool survive_fd_exhaustion) ++{ ++ int tempfd; ++ struct tempnode *node = create_temp_file (&tempfd, survive_fd_exhaustion); ++ char *name; ++ ++ if (! node) ++ return NULL; ++ ++ name = node->name; ++ ++ if (compress_program) ++ { ++ int pipefds[2]; ++ ++ node->pid = pipe_fork (pipefds, MAX_FORK_TRIES_COMPRESS); ++ if (0 < node->pid) ++ { ++ close (tempfd); ++ close (pipefds[0]); ++ tempfd = pipefds[1]; ++ ++ register_proc (node->pid); ++ } ++ else if (node->pid == 0) ++ { ++ close (pipefds[1]); ++ dup2_or_die (tempfd, STDOUT_FILENO); ++ close (tempfd); ++ dup2_or_die (pipefds[0], STDIN_FILENO); ++ close (pipefds[0]); ++ ++ if (execlp (compress_program, compress_program, (char *) NULL) < 0) ++ error (SORT_FAILURE, errno, _("couldn't execute %s"), ++ compress_program); ++ } ++ else ++ node->pid = 0; ++ } ++ ++ *pfp = fdopen (tempfd, "w"); ++ if (! *pfp) ++ die (_("couldn't create temporary file"), name); ++ ++ if (ppid) ++ *ppid = node->pid; ++ ++ return name; ++} ++ ++/* Create a temporary file and start a compression program to filter output ++ to that file. Set *PFP to the file handle and if *PPID is non-NULL, ++ set it to the PID of the newly-created process. Die on failure. */ ++ ++static char * ++create_temp (FILE **pfp, pid_t *ppid) ++{ ++ return maybe_create_temp (pfp, ppid, false); ++} ++ ++/* Open a compressed temp file and start a decompression process through ++ which to filter the input. PID must be the valid processes ID of the ++ process used to compress the file. Return NULL (setting errno to ++ EMFILE) if we ran out of file descriptors, and die on any other ++ kind of failure. */ ++ ++static FILE * ++open_temp (const char *name, pid_t pid) ++{ ++ int tempfd, pipefds[2]; ++ FILE *fp = NULL; ++ ++ wait_proc (pid); ++ ++ tempfd = open (name, O_RDONLY); ++ if (tempfd < 0) ++ return NULL; ++ ++ switch (pipe_fork (pipefds, MAX_FORK_TRIES_DECOMPRESS)) ++ { ++ case -1: ++ if (errno != EMFILE) ++ error (SORT_FAILURE, errno, _("couldn't create process for %s -d"), ++ compress_program); ++ close (tempfd); ++ errno = EMFILE; ++ break; ++ ++ case 0: ++ close (pipefds[0]); ++ dup2_or_die (tempfd, STDIN_FILENO); ++ close (tempfd); ++ dup2_or_die (pipefds[1], STDOUT_FILENO); ++ close (pipefds[1]); ++ ++ execlp (compress_program, compress_program, "-d", (char *) NULL); ++ error (SORT_FAILURE, errno, _("couldn't execute %s -d"), ++ compress_program); ++ ++ default: ++ close (tempfd); ++ close (pipefds[1]); ++ ++ fp = fdopen (pipefds[0], "r"); ++ if (! fp) ++ { ++ int saved_errno = errno; ++ close (pipefds[0]); ++ errno = saved_errno; ++ } ++ break; ++ } ++ ++ return fp; ++} ++ ++static void ++write_bytes (const char *buf, size_t n_bytes, FILE *fp, const char *output_file) ++{ ++ if (fwrite (buf, 1, n_bytes, fp) != n_bytes) ++ die (_("write failed"), output_file); ++} ++ ++/* Append DIR to the array of temporary directory names. */ ++static void ++add_temp_dir (char const *dir) ++{ ++ if (temp_dir_count == temp_dir_alloc) ++ temp_dirs = X2NREALLOC (temp_dirs, &temp_dir_alloc); ++ ++ temp_dirs[temp_dir_count++] = dir; ++} ++ ++/* Remove NAME from the list of temporary files. */ ++ ++static void ++zaptemp (const char *name) ++{ ++ struct tempnode *volatile *pnode; ++ struct tempnode *node; ++ struct tempnode *next; ++ int unlink_status; ++ int unlink_errno = 0; ++ struct cs_status cs; ++ ++ for (pnode = &temphead; (node = *pnode)->name != name; pnode = &node->next) ++ continue; ++ ++ /* Unlink the temporary file in a critical section to avoid races. */ ++ next = node->next; ++ cs = cs_enter (); ++ unlink_status = unlink (name); ++ unlink_errno = errno; ++ *pnode = next; ++ cs_leave (cs); ++ ++ if (unlink_status != 0) ++ error (0, unlink_errno, _("warning: cannot remove: %s"), name); ++ if (! next) ++ temptail = pnode; ++ free (node); ++} ++ ++#if HAVE_NL_LANGINFO ++ ++static int ++struct_month_cmp (const void *m1, const void *m2) ++{ ++ struct month const *month1 = m1; ++ struct month const *month2 = m2; ++ return strcmp (month1->name, month2->name); ++} ++ ++#endif ++ ++/* Initialize the character class tables. */ ++ ++static void ++inittables (void) ++{ ++ size_t i; ++ ++ for (i = 0; i < UCHAR_LIM; ++i) ++ { ++ blanks[i] = !! isblank (i); ++ nonprinting[i] = ! isprint (i); ++ nondictionary[i] = ! isalnum (i) && ! isblank (i); ++ fold_toupper[i] = toupper (i); ++ } ++ ++#if HAVE_NL_LANGINFO ++ /* If we're not in the "C" locale, read different names for months. */ ++ if (hard_LC_TIME) ++ { ++ for (i = 0; i < MONTHS_PER_YEAR; i++) ++ { ++ char const *s; ++ size_t s_len; ++ size_t j; ++ char *name; ++ ++ s = (char *) nl_langinfo (ABMON_1 + i); ++ s_len = strlen (s); ++ monthtab[i].name = name = xmalloc (s_len + 1); ++ monthtab[i].val = i + 1; ++ ++ for (j = 0; j < s_len; j++) ++ name[j] = fold_toupper[to_uchar (s[j])]; ++ name[j] = '\0'; ++ } ++ qsort ((void *) monthtab, MONTHS_PER_YEAR, ++ sizeof *monthtab, struct_month_cmp); ++ } ++#endif ++} ++ ++/* Specify how many inputs may be merged at once. ++ This may be set on the command-line with the ++ --batch-size option. */ ++static void ++specify_nmerge (int oi, char c, char const *s) ++{ ++ uintmax_t n; ++ struct rlimit rlimit; ++ enum strtol_error e = xstrtoumax (s, NULL, 10, &n, NULL); ++ ++ /* Try to find out how many file descriptors we'll be able ++ to open. We need at least nmerge + 3 (STDIN_FILENO, ++ STDOUT_FILENO and STDERR_FILENO). */ ++ unsigned int max_nmerge = ((getrlimit (RLIMIT_NOFILE, &rlimit) == 0 ++ ? rlimit.rlim_cur ++ : OPEN_MAX) ++ - 3); ++ ++ if (e == LONGINT_OK) ++ { ++ nmerge = n; ++ if (nmerge != n) ++ e = LONGINT_OVERFLOW; ++ else ++ { ++ if (nmerge < 2) ++ { ++ error (0, 0, _("invalid --%s argument %s"), ++ long_options[oi].name, quote(s)); ++ error (SORT_FAILURE, 0, ++ _("minimum --%s argument is %s"), ++ long_options[oi].name, quote("2")); ++ } ++ else if (max_nmerge < nmerge) ++ { ++ e = LONGINT_OVERFLOW; ++ } ++ else ++ return; ++ } ++ } ++ ++ if (e == LONGINT_OVERFLOW) ++ { ++ char max_nmerge_buf[INT_BUFSIZE_BOUND (unsigned int)]; ++ error (0, 0, _("--%s argument %s too large"), ++ long_options[oi].name, quote(s)); ++ error (SORT_FAILURE, 0, ++ _("maximum --%s argument with current rlimit is %s"), ++ long_options[oi].name, ++ uinttostr (max_nmerge, max_nmerge_buf)); ++ } ++ else ++ xstrtol_fatal (e, oi, c, long_options, s); ++} ++ ++/* Specify the amount of main memory to use when sorting. */ ++static void ++specify_sort_size (int oi, char c, char const *s) ++{ ++ uintmax_t n; ++ char *suffix; ++ enum strtol_error e = xstrtoumax (s, &suffix, 10, &n, "EgGkKmMPtTYZ"); ++ ++ /* The default unit is KiB. */ ++ if (e == LONGINT_OK && ISDIGIT (suffix[-1])) ++ { ++ if (n <= UINTMAX_MAX / 1024) ++ n *= 1024; ++ else ++ e = LONGINT_OVERFLOW; ++ } ++ ++ /* A 'b' suffix means bytes; a '%' suffix means percent of memory. */ ++ if (e == LONGINT_INVALID_SUFFIX_CHAR && ISDIGIT (suffix[-1]) && ! suffix[1]) ++ switch (suffix[0]) ++ { ++ case 'b': ++ e = LONGINT_OK; ++ break; ++ ++ case '%': ++ { ++ double mem = physmem_total () * n / 100; ++ ++ /* Use "<", not "<=", to avoid problems with rounding. */ ++ if (mem < UINTMAX_MAX) ++ { ++ n = mem; ++ e = LONGINT_OK; ++ } ++ else ++ e = LONGINT_OVERFLOW; ++ } ++ break; ++ } ++ ++ if (e == LONGINT_OK) ++ { ++ /* If multiple sort sizes are specified, take the maximum, so ++ that option order does not matter. */ ++ if (n < sort_size) ++ return; ++ ++ sort_size = n; ++ if (sort_size == n) ++ { ++ sort_size = MAX (sort_size, MIN_SORT_SIZE); ++ return; ++ } ++ ++ e = LONGINT_OVERFLOW; ++ } ++ ++ xstrtol_fatal (e, oi, c, long_options, s); ++} ++ ++/* Return the default sort size. */ ++static size_t ++default_sort_size (void) ++{ ++ /* Let MEM be available memory or 1/8 of total memory, whichever ++ is greater. */ ++ double avail = physmem_available (); ++ double total = physmem_total (); ++ double mem = MAX (avail, total / 8); ++ struct rlimit rlimit; ++ ++ /* Let SIZE be MEM, but no more than the maximum object size or ++ system resource limits. Avoid the MIN macro here, as it is not ++ quite right when only one argument is floating point. Don't ++ bother to check for values like RLIM_INFINITY since in practice ++ they are not much less than SIZE_MAX. */ ++ size_t size = SIZE_MAX; ++ if (mem < size) ++ size = mem; ++ if (getrlimit (RLIMIT_DATA, &rlimit) == 0 && rlimit.rlim_cur < size) ++ size = rlimit.rlim_cur; ++#ifdef RLIMIT_AS ++ if (getrlimit (RLIMIT_AS, &rlimit) == 0 && rlimit.rlim_cur < size) ++ size = rlimit.rlim_cur; ++#endif ++ ++ /* Leave a large safety margin for the above limits, as failure can ++ occur when they are exceeded. */ ++ size /= 2; ++ ++#ifdef RLIMIT_RSS ++ /* Leave a 1/16 margin for RSS to leave room for code, stack, etc. ++ Exceeding RSS is not fatal, but can be quite slow. */ ++ if (getrlimit (RLIMIT_RSS, &rlimit) == 0 && rlimit.rlim_cur / 16 * 15 < size) ++ size = rlimit.rlim_cur / 16 * 15; ++#endif ++ ++ /* Use no less than the minimum. */ ++ return MAX (size, MIN_SORT_SIZE); ++} ++ ++/* Return the sort buffer size to use with the input files identified ++ by FPS and FILES, which are alternate names of the same files. ++ NFILES gives the number of input files; NFPS may be less. Assume ++ that each input line requires LINE_BYTES extra bytes' worth of line ++ information. Do not exceed the size bound specified by the user ++ (or a default size bound, if the user does not specify one). */ ++ ++static size_t ++sort_buffer_size (FILE *const *fps, size_t nfps, ++ char *const *files, size_t nfiles, ++ size_t line_bytes) ++{ ++ /* A bound on the input size. If zero, the bound hasn't been ++ determined yet. */ ++ static size_t size_bound; ++ ++ /* In the worst case, each input byte is a newline. */ ++ size_t worst_case_per_input_byte = line_bytes + 1; ++ ++ /* Keep enough room for one extra input line and an extra byte. ++ This extra room might be needed when preparing to read EOF. */ ++ size_t size = worst_case_per_input_byte + 1; ++ ++ size_t i; ++ ++ for (i = 0; i < nfiles; i++) ++ { ++ struct stat st; ++ off_t file_size; ++ size_t worst_case; ++ ++ if ((i < nfps ? fstat (fileno (fps[i]), &st) ++ : STREQ (files[i], "-") ? fstat (STDIN_FILENO, &st) ++ : stat (files[i], &st)) ++ != 0) ++ die (_("stat failed"), files[i]); ++ ++ if (S_ISREG (st.st_mode)) ++ file_size = st.st_size; ++ else ++ { ++ /* The file has unknown size. If the user specified a sort ++ buffer size, use that; otherwise, guess the size. */ ++ if (sort_size) ++ return sort_size; ++ file_size = INPUT_FILE_SIZE_GUESS; ++ } ++ ++ if (! size_bound) ++ { ++ size_bound = sort_size; ++ if (! size_bound) ++ size_bound = default_sort_size (); ++ } ++ ++ /* Add the amount of memory needed to represent the worst case ++ where the input consists entirely of newlines followed by a ++ single non-newline. Check for overflow. */ ++ worst_case = file_size * worst_case_per_input_byte + 1; ++ if (file_size != worst_case / worst_case_per_input_byte ++ || size_bound - size <= worst_case) ++ return size_bound; ++ size += worst_case; ++ } ++ ++ return size; ++} ++ ++/* Initialize BUF. Reserve LINE_BYTES bytes for each line; LINE_BYTES ++ must be at least sizeof (struct line). Allocate ALLOC bytes ++ initially. */ ++ ++static void ++initbuf (struct buffer *buf, size_t line_bytes, size_t alloc) ++{ ++ /* Ensure that the line array is properly aligned. If the desired ++ size cannot be allocated, repeatedly halve it until allocation ++ succeeds. The smaller allocation may hurt overall performance, ++ but that's better than failing. */ ++ for (;;) ++ { ++ alloc += sizeof (struct line) - alloc % sizeof (struct line); ++ buf->buf = malloc (alloc); ++ if (buf->buf) ++ break; ++ alloc /= 2; ++ if (alloc <= line_bytes + 1) ++ xalloc_die (); ++ } ++ ++ buf->line_bytes = line_bytes; ++ buf->alloc = alloc; ++ buf->used = buf->left = buf->nlines = 0; ++ buf->eof = false; ++} ++ ++/* Return one past the limit of the line array. */ ++ ++static inline struct line * ++buffer_linelim (struct buffer const *buf) ++{ ++ return (struct line *) (buf->buf + buf->alloc); ++} ++ ++/* Return a pointer to the first character of the field specified ++ by KEY in LINE. */ ++ ++static char * ++begfield (const struct line *line, const struct keyfield *key) ++{ ++ char *ptr = line->text, *lim = ptr + line->length - 1; ++ size_t sword = key->sword; ++ size_t schar = key->schar; ++ ++ /* The leading field separator itself is included in a field when -t ++ is absent. */ ++ ++ if (tab != TAB_DEFAULT) ++ while (ptr < lim && sword--) ++ { ++ while (ptr < lim && *ptr != tab) ++ ++ptr; ++ if (ptr < lim) ++ ++ptr; ++ } ++ else ++ while (ptr < lim && sword--) ++ { ++ while (ptr < lim && blanks[to_uchar (*ptr)]) ++ ++ptr; ++ while (ptr < lim && !blanks[to_uchar (*ptr)]) ++ ++ptr; ++ } ++ ++ /* If we're ignoring leading blanks when computing the Start ++ of the field, skip past them here. */ ++ if (key->skipsblanks) ++ while (ptr < lim && blanks[to_uchar (*ptr)]) ++ ++ptr; ++ ++ /* Advance PTR by SCHAR (if possible), but no further than LIM. */ ++ ptr = MIN (lim, ptr + schar); ++ ++ return ptr; ++} ++ ++/* Return the limit of (a pointer to the first character after) the field ++ in LINE specified by KEY. */ ++ ++static char * ++limfield (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; ++ ++ if (echar == 0) ++ eword++; /* Skip all of end field. */ ++ ++ /* Move PTR past EWORD fields or to one past the last byte on LINE, ++ whichever comes first. If there are more than EWORD fields, leave ++ PTR pointing at the beginning of the field having zero-based index, ++ EWORD. If a delimiter character was specified (via -t), then that ++ `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) ++ while (ptr < lim && eword--) ++ { ++ while (ptr < lim && *ptr != tab) ++ ++ptr; ++ if (ptr < lim && (eword || echar)) ++ ++ptr; ++ } ++ else ++ while (ptr < lim && eword--) ++ { ++ while (ptr < lim && blanks[to_uchar (*ptr)]) ++ ++ptr; ++ while (ptr < lim && !blanks[to_uchar (*ptr)]) ++ ++ptr; ++ } ++ ++#ifdef POSIX_UNSPECIFIED ++ /* The following block of code makes GNU sort incompatible with ++ standard Unix sort, so it's ifdef'd out for now. ++ The POSIX spec isn't clear on how to interpret this. ++ FIXME: request clarification. ++ ++ From: kwzh@gnu.ai.mit.edu (Karl Heuer) ++ Date: Thu, 30 May 96 12:20:41 -0400 ++ [Translated to POSIX 1003.1-2001 terminology by Paul Eggert.] ++ ++ [...]I believe I've found another bug in `sort'. ++ ++ $ cat /tmp/sort.in ++ a b c 2 d ++ pq rs 1 t ++ $ textutils-1.15/src/sort -k1.7,1.7 skipeblanks) ++ while (ptr < lim && blanks[to_uchar (*ptr)]) ++ ++ptr; ++ ++ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ ++ ptr = MIN (lim, ptr + echar); ++ } ++ ++ return ptr; ++} ++ ++/* 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 ++ table too. FILE is the name of the file corresponding to FP. ++ Return true if some input was read. */ ++ ++static bool ++fillbuf (struct buffer *buf, FILE *fp, char const *file) ++{ ++ struct keyfield const *key = keylist; ++ char eol = eolchar; ++ size_t line_bytes = buf->line_bytes; ++ size_t mergesize = merge_buffer_size - MIN_MERGE_BUFFER_SIZE; ++ ++ if (buf->eof) ++ return false; ++ ++ if (buf->used != buf->left) ++ { ++ memmove (buf->buf, buf->buf + buf->used - buf->left, buf->left); ++ buf->used = buf->left; ++ buf->nlines = 0; ++ } ++ ++ for (;;) ++ { ++ char *ptr = buf->buf + buf->used; ++ struct line *linelim = buffer_linelim (buf); ++ struct line *line = linelim - buf->nlines; ++ size_t avail = (char *) linelim - buf->nlines * line_bytes - ptr; ++ char *line_start = buf->nlines ? line->text + line->length : buf->buf; ++ ++ while (line_bytes + 1 < avail) ++ { ++ /* Read as many bytes as possible, but do not read so many ++ bytes that there might not be enough room for the ++ corresponding line array. The worst case is when the ++ rest of the input file consists entirely of newlines, ++ except that the last byte is not a newline. */ ++ size_t readsize = (avail - 1) / (line_bytes + 1); ++ size_t bytes_read = fread (ptr, 1, readsize, fp); ++ char *ptrlim = ptr + bytes_read; ++ char *p; ++ avail -= bytes_read; ++ ++ if (bytes_read != readsize) ++ { ++ if (ferror (fp)) ++ die (_("read failed"), file); ++ if (feof (fp)) ++ { ++ buf->eof = true; ++ if (buf->buf == ptrlim) ++ return false; ++ if (ptrlim[-1] != eol) ++ *ptrlim++ = eol; ++ } ++ } ++ ++ /* Find and record each line in the just-read input. */ ++ while ((p = memchr (ptr, eol, ptrlim - ptr))) ++ { ++ ptr = p + 1; ++ line--; ++ line->text = line_start; ++ line->length = ptr - line_start; ++ mergesize = MAX (mergesize, line->length); ++ avail -= line_bytes; ++ ++ if (key) ++ { ++ /* Precompute the position of the first key for ++ efficiency. */ ++ line->keylim = (key->eword == SIZE_MAX ++ ? p ++ : limfield (line, key)); ++ ++ if (key->sword != SIZE_MAX) ++ line->keybeg = begfield (line, key); ++ else ++ { ++ if (key->skipsblanks) ++ while (blanks[to_uchar (*line_start)]) ++ line_start++; ++ line->keybeg = line_start; ++ } ++ } ++ ++ line_start = ptr; ++ } ++ ++ ptr = ptrlim; ++ if (buf->eof) ++ break; ++ } ++ ++ buf->used = ptr - buf->buf; ++ buf->nlines = buffer_linelim (buf) - line; ++ if (buf->nlines != 0) ++ { ++ buf->left = ptr - line_start; ++ merge_buffer_size = mergesize + MIN_MERGE_BUFFER_SIZE; ++ return true; ++ } ++ ++ { ++ /* The current input line is too long to fit in the buffer. ++ Double the buffer size and try again, keeping it properly ++ aligned. */ ++ size_t line_alloc = buf->alloc / sizeof (struct line); ++ buf->buf = x2nrealloc (buf->buf, &line_alloc, sizeof (struct line)); ++ buf->alloc = line_alloc * sizeof (struct line); ++ } ++ } ++} ++ ++/* Compare strings A and B as numbers without explicitly converting them to ++ machine numbers. Comparatively slow for short strings, but asymptotically ++ hideously fast. */ ++ ++static int ++numcompare (const char *a, const char *b) ++{ ++ while (blanks[to_uchar (*a)]) ++ a++; ++ while (blanks[to_uchar (*b)]) ++ b++; ++ ++ return strnumcmp (a, b, decimal_point, thousands_sep); ++} ++ ++/* Exit with an error if a mixture of SI and IEC units detected. */ ++ ++static void ++check_mixed_SI_IEC (char prefix, struct keyfield *key) ++{ ++ int si_present = prefix == 'i'; ++ if (key->si_present != -1 && si_present != key->si_present) ++ error (SORT_FAILURE, 0, _("both SI and IEC prefixes present on units")); ++ key->si_present = si_present; ++} ++ ++/* Return an integer which represents the order of magnitude of ++ the unit following the number. NUMBER can contain thousands separators ++ or a decimal point, but not have preceeding blanks. ++ Negative numbers return a negative unit order. */ ++ ++static int ++find_unit_order (const char *number, struct keyfield *key) ++{ ++ static const char orders [UCHAR_LIM] = ++ { ++#if SOME_DAY_WE_WILL_REQUIRE_C99 ++ ['K']=1, ['M']=2, ['G']=3, ['T']=4, ['P']=5, ['E']=6, ['Z']=7, ['Y']=8, ++ ['k']=1, ++#else ++ /* Generate the following table with this command: ++ perl -e 'my %a=(k=>1, K=>1, M=>2, G=>3, T=>4, P=>5, E=>6, Z=>7, Y=>8); ++ foreach my $i (0..255) {my $c=chr($i); $a{$c} ||= 0;print "$a{$c}, "}'\ ++ |fmt */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, ++ 0, 0, 0, 1, 0, 2, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++#endif ++ }; ++ ++ const unsigned char *p = number; ++ ++ int sign = 1; ++ ++ if (*p == '-') ++ { ++ sign = -1; ++ p++; ++ } ++ ++ /* Scan to end of number. ++ Decimals or separators not followed by digits stop the scan. ++ Numbers ending in decimals or separators are thus considered ++ to be lacking in units. ++ FIXME: add support for multibyte thousands_sep and decimal_point. */ ++ ++ while (ISDIGIT (*p)) ++ { ++ p++; ++ ++ if (*p == decimal_point && ISDIGIT (*(p + 1))) ++ p += 2; ++ else if (*p == thousands_sep && ISDIGIT (*(p + 1))) ++ p += 2; ++ } ++ ++ int order = orders[*p]; ++ ++ /* For valid units check for MiB vs MB etc. */ ++ if (order) ++ check_mixed_SI_IEC (*(p + 1), key); ++ ++ return sign * order; ++} ++ ++/* Compare numbers ending in units with SI xor IEC prefixes ++ < K/k < M < G < T < P < E < Z < Y ++ Assume that numbers are properly abbreviated. ++ i.e. input will never have both 6000K and 5M. */ ++ ++static int ++human_numcompare (const char *a, const char *b, struct keyfield *key) ++{ ++ while (blanks[to_uchar (*a)]) ++ a++; ++ while (blanks[to_uchar (*b)]) ++ b++; ++ ++ int order_a = find_unit_order (a, key); ++ int order_b = find_unit_order (b, key); ++ ++ return (order_a > order_b ? 1 ++ : order_a < order_b ? -1 ++ : strnumcmp (a, b, decimal_point, thousands_sep)); ++} ++ ++static int ++general_numcompare (const char *sa, const char *sb) ++{ ++ /* FIXME: add option to warn about failed conversions. */ ++ /* FIXME: maybe add option to try expensive FP conversion ++ only if A and B can't be compared more cheaply/accurately. */ ++ ++ char *ea; ++ char *eb; ++ double a = strtod (sa, &ea); ++ double b = strtod (sb, &eb); ++ ++ /* Put conversion errors at the start of the collating sequence. */ ++ if (sa == ea) ++ return sb == eb ? 0 : -1; ++ if (sb == eb) ++ return 1; ++ ++ /* Sort numbers in the usual way, where -0 == +0. Put NaNs after ++ conversion errors but before numbers; sort them by internal ++ bit-pattern, for lack of a more portable alternative. */ ++ return (a < b ? -1 ++ : a > b ? 1 ++ : a == b ? 0 ++ : b == b ? -1 ++ : a == a ? 1 ++ : memcmp ((char *) &a, (char *) &b, sizeof a)); ++} ++ ++/* Return an integer in 1..12 of the month name MONTH with length LEN. ++ Return 0 if the name in S is not recognized. */ ++ ++static int ++getmonth (char const *month, size_t len) ++{ ++ size_t lo = 0; ++ size_t hi = MONTHS_PER_YEAR; ++ char const *monthlim = month + len; ++ ++ for (;;) ++ { ++ if (month == monthlim) ++ return 0; ++ if (!blanks[to_uchar (*month)]) ++ break; ++ ++month; ++ } ++ ++ do ++ { ++ size_t ix = (lo + hi) / 2; ++ char const *m = month; ++ char const *n = monthtab[ix].name; ++ ++ for (;; m++, n++) ++ { ++ if (!*n) ++ return monthtab[ix].val; ++ if (m == monthlim || fold_toupper[to_uchar (*m)] < to_uchar (*n)) ++ { ++ hi = ix; ++ break; ++ } ++ else if (fold_toupper[to_uchar (*m)] > to_uchar (*n)) ++ { ++ lo = ix + 1; ++ break; ++ } ++ } ++ } ++ while (lo < hi); ++ ++ return 0; ++} ++ ++/* A source of random data. */ ++static struct randread_source *randread_source; ++ ++/* Return the Ith randomly-generated state. The caller must invoke ++ random_state (H) for all H less than I before invoking random_state ++ (I). */ ++ ++static struct md5_ctx ++random_state (size_t i) ++{ ++ /* An array of states resulting from the random data, and counts of ++ its used and allocated members. */ ++ static struct md5_ctx *state; ++ static size_t used; ++ static size_t allocated; ++ ++ struct md5_ctx *s = &state[i]; ++ ++ if (used <= i) ++ { ++ unsigned char buf[MD5_DIGEST_SIZE]; ++ ++ used++; ++ ++ if (allocated <= i) ++ { ++ state = X2NREALLOC (state, &allocated); ++ s = &state[i]; ++ } ++ ++ randread (randread_source, buf, sizeof buf); ++ md5_init_ctx (s); ++ md5_process_bytes (buf, sizeof buf, s); ++ } ++ ++ return *s; ++} ++ ++/* Compare the hashes of TEXTA with length LENGTHA to those of TEXTB ++ with length LENGTHB. Return negative if less, zero if equal, ++ positive if greater. */ ++ ++static int ++cmp_hashes (char const *texta, size_t lena, ++ char const *textb, size_t lenb) ++{ ++ /* Try random hashes until a pair of hashes disagree. But if the ++ first pair of random hashes agree, check whether the keys are ++ identical and if so report no difference. */ ++ int diff; ++ size_t i; ++ for (i = 0; ; i++) ++ { ++ uint32_t dig[2][MD5_DIGEST_SIZE / sizeof (uint32_t)]; ++ struct md5_ctx s[2]; ++ s[0] = s[1] = random_state (i); ++ md5_process_bytes (texta, lena, &s[0]); md5_finish_ctx (&s[0], dig[0]); ++ md5_process_bytes (textb, lenb, &s[1]); md5_finish_ctx (&s[1], dig[1]); ++ diff = memcmp (dig[0], dig[1], sizeof dig[0]); ++ if (diff != 0) ++ break; ++ if (i == 0 && lena == lenb && memcmp (texta, textb, lena) == 0) ++ break; ++ } ++ ++ return diff; ++} ++ ++/* Compare the keys TEXTA (of length LENA) and TEXTB (of length LENB) ++ using one or more random hash functions. */ ++ ++static int ++compare_random (char *restrict texta, size_t lena, ++ char *restrict textb, size_t lenb) ++{ ++ int diff; ++ ++ if (! hard_LC_COLLATE) ++ diff = cmp_hashes (texta, lena, textb, lenb); ++ else ++ { ++ /* Transform the text into the basis of comparison, so that byte ++ strings that would otherwise considered to be equal are ++ considered equal here even if their bytes differ. */ ++ ++ char *buf = NULL; ++ char stackbuf[4000]; ++ size_t tlena = xmemxfrm (stackbuf, sizeof stackbuf, texta, lena); ++ bool a_fits = tlena <= sizeof stackbuf; ++ size_t tlenb = xmemxfrm ((a_fits ? stackbuf + tlena : NULL), ++ (a_fits ? sizeof stackbuf - tlena : 0), ++ textb, lenb); ++ ++ if (a_fits && tlena + tlenb <= sizeof stackbuf) ++ buf = stackbuf; ++ else ++ { ++ /* Adding 1 to the buffer size lets xmemxfrm run a bit ++ faster by avoiding the need for an extra buffer copy. */ ++ buf = xmalloc (tlena + tlenb + 1); ++ xmemxfrm (buf, tlena + 1, texta, lena); ++ xmemxfrm (buf + tlena, tlenb + 1, textb, lenb); ++ } ++ ++ diff = cmp_hashes (buf, tlena, buf + tlena, tlenb); ++ ++ if (buf != stackbuf) ++ free (buf); ++ } ++ ++ return diff; ++} ++ ++/* Compare the keys TEXTA (of length LENA) and TEXTB (of length LENB) ++ using filevercmp. See lib/filevercmp.h for function description. */ ++ ++static int ++compare_version (char *restrict texta, size_t lena, ++ char *restrict textb, size_t lenb) ++{ ++ int diff; ++ ++ /* It is necessary to save the character after the end of the field. ++ "filevercmp" works with NUL terminated strings. Our blocks of ++ text are not necessarily terminated with a NUL byte. */ ++ char sv_a = texta[lena]; ++ char sv_b = textb[lenb]; ++ ++ texta[lena] = '\0'; ++ textb[lenb] = '\0'; ++ ++ diff = filevercmp (texta, textb); ++ ++ texta[lena] = sv_a; ++ textb[lenb] = sv_b; ++ ++ return diff; ++} ++ ++/* 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 (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; ++ ++ int diff; ++ ++ for (;;) ++ { ++ char const *translate = key->translate; ++ bool const *ignore = key->ignore; ++ ++ /* Treat field ends before field starts as empty fields. */ ++ lima = MAX (texta, lima); ++ limb = MAX (textb, limb); ++ ++ /* Find the lengths. */ ++ size_t lena = lima - texta; ++ size_t lenb = limb - textb; ++ ++ /* Actually compare the fields. */ ++ ++ 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, key)); ++ *lima = savea, *limb = saveb; ++ } ++ else if (key->version) ++ diff = compare_version (texta, lena, textb, lenb); ++ else if (key->month) ++ diff = getmonth (texta, lena) - getmonth (textb, lenb); ++ /* Sorting like this may become slow, so in a simple locale the user ++ can select a faster sort that is similar to ascii sort. */ ++ else if (hard_LC_COLLATE) ++ { ++ if (ignore || translate) ++ { ++ char buf[4000]; ++ size_t size = lena + 1 + lenb + 1; ++ char *copy_a = (size <= sizeof buf ? buf : xmalloc (size)); ++ char *copy_b = copy_a + lena + 1; ++ size_t new_len_a, new_len_b, i; ++ ++ /* Ignore and/or translate chars before comparing. */ ++ for (new_len_a = new_len_b = i = 0; i < MAX (lena, lenb); i++) ++ { ++ if (i < lena) ++ { ++ copy_a[new_len_a] = (translate ++ ? translate[to_uchar (texta[i])] ++ : texta[i]); ++ if (!ignore || !ignore[to_uchar (texta[i])]) ++ ++new_len_a; ++ } ++ if (i < lenb) ++ { ++ copy_b[new_len_b] = (translate ++ ? translate[to_uchar (textb[i])] ++ : textb [i]); ++ if (!ignore || !ignore[to_uchar (textb[i])]) ++ ++new_len_b; ++ } ++ } ++ ++ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b); ++ ++ if (sizeof buf < size) ++ free (copy_a); ++ } ++ else if (lena == 0) ++ diff = - NONZERO (lenb); ++ else if (lenb == 0) ++ goto greater; ++ else ++ diff = xmemcoll (texta, lena, textb, lenb); ++ } ++ else if (ignore) ++ { ++#define CMP_WITH_IGNORE(A, B) \ ++ do \ ++ { \ ++ for (;;) \ ++ { \ ++ while (texta < lima && ignore[to_uchar (*texta)]) \ ++ ++texta; \ ++ while (textb < limb && ignore[to_uchar (*textb)]) \ ++ ++textb; \ ++ if (! (texta < lima && textb < limb)) \ ++ break; \ ++ diff = to_uchar (A) - to_uchar (B); \ ++ if (diff) \ ++ goto not_equal; \ ++ ++texta; \ ++ ++textb; \ ++ } \ ++ \ ++ diff = (texta < lima) - (textb < limb); \ ++ } \ ++ while (0) ++ ++ if (translate) ++ CMP_WITH_IGNORE (translate[to_uchar (*texta)], ++ translate[to_uchar (*textb)]); ++ else ++ CMP_WITH_IGNORE (*texta, *textb); ++ } ++ else if (lena == 0) ++ diff = - NONZERO (lenb); ++ else if (lenb == 0) ++ goto greater; ++ else ++ { ++ if (translate) ++ { ++ while (texta < lima && textb < limb) ++ { ++ diff = (to_uchar (translate[to_uchar (*texta++)]) ++ - to_uchar (translate[to_uchar (*textb++)])); ++ if (diff) ++ goto not_equal; ++ } ++ } ++ else ++ { ++ diff = memcmp (texta, textb, MIN (lena, lenb)); ++ if (diff) ++ goto not_equal; ++ } ++ diff = lena < lenb ? -1 : lena != lenb; ++ } ++ ++ if (diff) ++ goto not_equal; ++ ++ key = key->next; ++ if (! key) ++ break; ++ ++ /* Find the beginning and limit of the next field. */ ++ if (key->eword != SIZE_MAX) ++ lima = limfield (a, key), limb = limfield (b, key); ++ else ++ lima = a->text + a->length - 1, limb = b->text + b->length - 1; ++ ++ if (key->sword != SIZE_MAX) ++ texta = begfield (a, key), textb = begfield (b, key); ++ else ++ { ++ texta = a->text, textb = b->text; ++ if (key->skipsblanks) ++ { ++ while (texta < lima && blanks[to_uchar (*texta)]) ++ ++texta; ++ while (textb < limb && blanks[to_uchar (*textb)]) ++ ++textb; ++ } ++ } ++ } ++ ++ return 0; ++ ++ greater: ++ diff = 1; ++ not_equal: ++ return key->reverse ? -diff : diff; ++} ++ ++/* Compare two lines A and B, returning negative, zero, or positive ++ depending on whether A compares less than, equal to, or greater than B. */ ++ ++static int ++compare (const struct line *a, const struct line *b) ++{ ++ int diff; ++ size_t alen, blen; ++ ++ /* First try to compare on the specified keys (if any). ++ The only two cases with no key at all are unadorned sort, ++ and unadorned sort -r. */ ++ if (keylist) ++ { ++ diff = keycompare (a, b); ++ if (diff || unique || stable) ++ return diff; ++ } ++ ++ /* If the keys all compare equal (or no keys were specified) ++ fall through to the default comparison. */ ++ alen = a->length - 1, blen = b->length - 1; ++ ++ if (alen == 0) ++ diff = - NONZERO (blen); ++ else if (blen == 0) ++ diff = 1; ++ else if (hard_LC_COLLATE) ++ diff = xmemcoll (a->text, alen, b->text, blen); ++ else if (! (diff = memcmp (a->text, b->text, MIN (alen, blen)))) ++ diff = alen < blen ? -1 : alen != blen; ++ ++ return reverse ? -diff : diff; ++} ++ ++/* Check that the lines read from FILE_NAME come in order. Return ++ true if they are in order. If CHECKONLY == 'c', also print a ++ diagnostic (FILE_NAME, line number, contents of line) to stderr if ++ they are not in order. */ ++ ++static bool ++check (char const *file_name, char checkonly) ++{ ++ FILE *fp = xfopen (file_name, "r"); ++ struct buffer buf; /* Input buffer. */ ++ struct line temp; /* Copy of previous line. */ ++ size_t alloc = 0; ++ uintmax_t line_number = 0; ++ struct keyfield const *key = keylist; ++ bool nonunique = ! unique; ++ bool ordered = true; ++ ++ initbuf (&buf, sizeof (struct line), ++ MAX (merge_buffer_size, sort_size)); ++ temp.text = NULL; ++ ++ while (fillbuf (&buf, fp, file_name)) ++ { ++ struct line const *line = buffer_linelim (&buf); ++ struct line const *linebase = line - buf.nlines; ++ ++ /* Make sure the line saved from the old buffer contents is ++ less than or equal to the first line of the new buffer. */ ++ if (alloc && nonunique <= compare (&temp, line - 1)) ++ { ++ found_disorder: ++ { ++ if (checkonly == 'c') ++ { ++ struct line const *disorder_line = line - 1; ++ uintmax_t disorder_line_number = ++ buffer_linelim (&buf) - disorder_line + line_number; ++ char hr_buf[INT_BUFSIZE_BOUND (uintmax_t)]; ++ fprintf (stderr, _("%s: %s:%s: disorder: "), ++ program_name, file_name, ++ umaxtostr (disorder_line_number, hr_buf)); ++ write_bytes (disorder_line->text, disorder_line->length, ++ stderr, _("standard error")); ++ } ++ ++ ordered = false; ++ break; ++ } ++ } ++ ++ /* Compare each line in the buffer with its successor. */ ++ while (linebase < --line) ++ if (nonunique <= compare (line, line - 1)) ++ goto found_disorder; ++ ++ line_number += buf.nlines; ++ ++ /* Save the last line of the buffer. */ ++ if (alloc < line->length) ++ { ++ do ++ { ++ alloc *= 2; ++ if (! alloc) ++ { ++ alloc = line->length; ++ break; ++ } ++ } ++ while (alloc < line->length); ++ ++ temp.text = xrealloc (temp.text, alloc); ++ } ++ memcpy (temp.text, line->text, line->length); ++ temp.length = line->length; ++ if (key) ++ { ++ temp.keybeg = temp.text + (line->keybeg - line->text); ++ temp.keylim = temp.text + (line->keylim - line->text); ++ } ++ } ++ ++ xfclose (fp, file_name); ++ free (buf.buf); ++ free (temp.text); ++ return ordered; ++} ++ ++/* Open FILES (there are NFILES of them) and store the resulting array ++ of stream pointers into (*PFPS). Allocate the array. Return the ++ number of successfully opened files, setting errno if this value is ++ less than NFILES. */ ++ ++static size_t ++open_input_files (struct sortfile *files, size_t nfiles, FILE ***pfps) ++{ ++ FILE **fps = *pfps = xnmalloc (nfiles, sizeof *fps); ++ int i; ++ ++ /* Open as many input files as we can. */ ++ for (i = 0; i < nfiles; i++) ++ { ++ fps[i] = (files[i].pid ++ ? open_temp (files[i].name, files[i].pid) ++ : stream_open (files[i].name, "r")); ++ if (!fps[i]) ++ break; ++ } ++ ++ return i; ++} ++ ++/* Merge lines from FILES onto OFP. NTEMPS is the number of temporary ++ files (all of which are at the start of the FILES array), and ++ NFILES is the number of files; 0 <= NTEMPS <= NFILES <= NMERGE. ++ FPS is the vector of open stream corresponding to the files. ++ Close input and output streams before returning. ++ OUTPUT_FILE gives the name of the output file. If it is NULL, ++ the output file is standard output. */ ++ ++static void ++mergefps (struct sortfile *files, size_t ntemps, size_t nfiles, ++ FILE *ofp, char const *output_file, FILE **fps) ++{ ++ struct buffer *buffer = xnmalloc (nfiles, sizeof *buffer); ++ /* Input buffers for each file. */ ++ struct line saved; /* Saved line storage for unique check. */ ++ struct line const *savedline = NULL; ++ /* &saved if there is a saved line. */ ++ size_t savealloc = 0; /* Size allocated for the saved line. */ ++ struct line const **cur = xnmalloc (nfiles, sizeof *cur); ++ /* Current line in each line table. */ ++ struct line const **base = xnmalloc (nfiles, sizeof *base); ++ /* Base of each line table. */ ++ size_t *ord = xnmalloc (nfiles, sizeof *ord); ++ /* Table representing a permutation of fps, ++ such that cur[ord[0]] is the smallest line ++ and will be next output. */ ++ size_t i; ++ size_t j; ++ size_t t; ++ struct keyfield const *key = keylist; ++ saved.text = NULL; ++ ++ /* Read initial lines from each input file. */ ++ for (i = 0; i < nfiles; ) ++ { ++ initbuf (&buffer[i], sizeof (struct line), ++ MAX (merge_buffer_size, sort_size / nfiles)); ++ if (fillbuf (&buffer[i], fps[i], files[i].name)) ++ { ++ struct line const *linelim = buffer_linelim (&buffer[i]); ++ cur[i] = linelim - 1; ++ base[i] = linelim - buffer[i].nlines; ++ i++; ++ } ++ else ++ { ++ /* fps[i] is empty; eliminate it from future consideration. */ ++ xfclose (fps[i], files[i].name); ++ if (i < ntemps) ++ { ++ ntemps--; ++ zaptemp (files[i].name); ++ } ++ free (buffer[i].buf); ++ --nfiles; ++ for (j = i; j < nfiles; ++j) ++ { ++ files[j] = files[j + 1]; ++ fps[j] = fps[j + 1]; ++ } ++ } ++ } ++ ++ /* Set up the ord table according to comparisons among input lines. ++ Since this only reorders two items if one is strictly greater than ++ the other, it is stable. */ ++ for (i = 0; i < nfiles; ++i) ++ ord[i] = i; ++ for (i = 1; i < nfiles; ++i) ++ if (0 < compare (cur[ord[i - 1]], cur[ord[i]])) ++ t = ord[i - 1], ord[i - 1] = ord[i], ord[i] = t, i = 0; ++ ++ /* Repeatedly output the smallest line until no input remains. */ ++ while (nfiles) ++ { ++ struct line const *smallest = cur[ord[0]]; ++ ++ /* If uniquified output is turned on, output only the first of ++ an identical series of lines. */ ++ if (unique) ++ { ++ if (savedline && compare (savedline, smallest)) ++ { ++ savedline = NULL; ++ write_bytes (saved.text, saved.length, ofp, output_file); ++ } ++ if (!savedline) ++ { ++ savedline = &saved; ++ if (savealloc < smallest->length) ++ { ++ do ++ if (! savealloc) ++ { ++ savealloc = smallest->length; ++ break; ++ } ++ while ((savealloc *= 2) < smallest->length); ++ ++ saved.text = xrealloc (saved.text, savealloc); ++ } ++ saved.length = smallest->length; ++ memcpy (saved.text, smallest->text, saved.length); ++ if (key) ++ { ++ saved.keybeg = ++ saved.text + (smallest->keybeg - smallest->text); ++ saved.keylim = ++ saved.text + (smallest->keylim - smallest->text); ++ } ++ } ++ } ++ else ++ write_bytes (smallest->text, smallest->length, ofp, output_file); ++ ++ /* Check if we need to read more lines into core. */ ++ if (base[ord[0]] < smallest) ++ cur[ord[0]] = smallest - 1; ++ else ++ { ++ if (fillbuf (&buffer[ord[0]], fps[ord[0]], files[ord[0]].name)) ++ { ++ struct line const *linelim = buffer_linelim (&buffer[ord[0]]); ++ cur[ord[0]] = linelim - 1; ++ base[ord[0]] = linelim - buffer[ord[0]].nlines; ++ } ++ else ++ { ++ /* We reached EOF on fps[ord[0]]. */ ++ for (i = 1; i < nfiles; ++i) ++ if (ord[i] > ord[0]) ++ --ord[i]; ++ --nfiles; ++ xfclose (fps[ord[0]], files[ord[0]].name); ++ if (ord[0] < ntemps) ++ { ++ ntemps--; ++ zaptemp (files[ord[0]].name); ++ } ++ free (buffer[ord[0]].buf); ++ for (i = ord[0]; i < nfiles; ++i) ++ { ++ fps[i] = fps[i + 1]; ++ files[i] = files[i + 1]; ++ buffer[i] = buffer[i + 1]; ++ cur[i] = cur[i + 1]; ++ base[i] = base[i + 1]; ++ } ++ for (i = 0; i < nfiles; ++i) ++ ord[i] = ord[i + 1]; ++ continue; ++ } ++ } ++ ++ /* The new line just read in may be larger than other lines ++ already in main memory; push it back in the queue until we ++ encounter a line larger than it. Optimize for the common ++ case where the new line is smallest. */ ++ { ++ size_t lo = 1; ++ size_t hi = nfiles; ++ size_t probe = lo; ++ size_t ord0 = ord[0]; ++ size_t count_of_smaller_lines; ++ ++ while (lo < hi) ++ { ++ int cmp = compare (cur[ord0], cur[ord[probe]]); ++ if (cmp < 0 || (cmp == 0 && ord0 < ord[probe])) ++ hi = probe; ++ else ++ lo = probe + 1; ++ probe = (lo + hi) / 2; ++ } ++ ++ count_of_smaller_lines = lo - 1; ++ for (j = 0; j < count_of_smaller_lines; j++) ++ ord[j] = ord[j + 1]; ++ ord[count_of_smaller_lines] = ord0; ++ } ++ ++ /* Free up some resources every once in a while. */ ++ if (MAX_PROCS_BEFORE_REAP < nprocs) ++ reap_some (); ++ } ++ ++ if (unique && savedline) ++ { ++ write_bytes (saved.text, saved.length, ofp, output_file); ++ free (saved.text); ++ } ++ ++ xfclose (ofp, output_file); ++ free(fps); ++ free(buffer); ++ free(ord); ++ free(base); ++ free(cur); ++} ++ ++/* Merge lines from FILES onto OFP. NTEMPS is the number of temporary ++ files (all of which are at the start of the FILES array), and ++ NFILES is the number of files; 0 <= NTEMPS <= NFILES <= NMERGE. ++ Close input and output files before returning. ++ OUTPUT_FILE gives the name of the output file. ++ ++ Return the number of files successfully merged. This number can be ++ less than NFILES if we ran low on file descriptors, but in this ++ case it is never less than 2. */ ++ ++static size_t ++mergefiles (struct sortfile *files, size_t ntemps, size_t nfiles, ++ FILE *ofp, char const *output_file) ++{ ++ FILE **fps; ++ size_t nopened = open_input_files (files, nfiles, &fps); ++ if (nopened < nfiles && nopened < 2) ++ die (_("open failed"), files[nopened].name); ++ mergefps (files, ntemps, nopened, ofp, output_file, fps); ++ return nopened; ++} ++ ++/* Merge into T the two sorted arrays of lines LO (with NLO members) ++ and HI (with NHI members). T, LO, and HI point just past their ++ respective arrays, and the arrays are in reverse order. NLO and ++ NHI must be positive, and HI - NHI must equal T - (NLO + NHI). */ ++ ++static inline void ++mergelines (struct line *t, ++ struct line const *lo, size_t nlo, ++ struct line const *hi, size_t nhi) ++{ ++ for (;;) ++ if (compare (lo - 1, hi - 1) <= 0) ++ { ++ *--t = *--lo; ++ if (! --nlo) ++ { ++ /* HI - NHI equalled T - (NLO + NHI) when this function ++ began. Therefore HI must equal T now, and there is no ++ need to copy from HI to T. */ ++ return; ++ } ++ } ++ else ++ { ++ *--t = *--hi; ++ if (! --nhi) ++ { ++ do ++ *--t = *--lo; ++ while (--nlo); ++ ++ return; ++ } ++ } ++} ++ ++/* Sort the array LINES with NLINES members, using TEMP for temporary space. ++ NLINES must be at least 2. ++ The input and output arrays are in reverse order, and LINES and ++ TEMP point just past the end of their respective arrays. ++ ++ Use a recursive divide-and-conquer algorithm, in the style ++ suggested by Knuth volume 3 (2nd edition), exercise 5.2.4-23. Use ++ the optimization suggested by exercise 5.2.4-10; this requires room ++ for only 1.5*N lines, rather than the usual 2*N lines. Knuth ++ writes that this memory optimization was originally published by ++ D. A. Bell, Comp J. 1 (1958), 75. */ ++ ++static void ++sortlines (struct line *lines, size_t nlines, struct line *temp) ++{ ++ if (nlines == 2) ++ { ++ if (0 < compare (&lines[-1], &lines[-2])) ++ { ++ struct line tmp = lines[-1]; ++ lines[-1] = lines[-2]; ++ lines[-2] = tmp; ++ } ++ } ++ else ++ { ++ size_t nlo = nlines / 2; ++ size_t nhi = nlines - nlo; ++ struct line *lo = lines; ++ struct line *hi = lines - nlo; ++ struct line *sorted_lo = temp; ++ ++ sortlines (hi, nhi, temp); ++ if (1 < nlo) ++ sortlines_temp (lo, nlo, sorted_lo); ++ else ++ sorted_lo[-1] = lo[-1]; ++ ++ mergelines (lines, sorted_lo, nlo, hi, nhi); ++ } ++} ++ ++/* Like sortlines (LINES, NLINES, TEMP), except output into TEMP ++ rather than sorting in place. */ ++ ++static void ++sortlines_temp (struct line *lines, size_t nlines, struct line *temp) ++{ ++ if (nlines == 2) ++ { ++ /* Declare `swap' as int, not bool, to work around a bug ++ ++ in the IBM xlc 6.0.0.0 compiler in 64-bit mode. */ ++ int swap = (0 < compare (&lines[-1], &lines[-2])); ++ temp[-1] = lines[-1 - swap]; ++ temp[-2] = lines[-2 + swap]; ++ } ++ else ++ { ++ size_t nlo = nlines / 2; ++ size_t nhi = nlines - nlo; ++ struct line *lo = lines; ++ struct line *hi = lines - nlo; ++ struct line *sorted_hi = temp - nlo; ++ ++ sortlines_temp (hi, nhi, sorted_hi); ++ if (1 < nlo) ++ sortlines (lo, nlo, temp); ++ ++ mergelines (temp, lo, nlo, sorted_hi, nhi); ++ } ++} ++ ++/* Scan through FILES[NTEMPS .. NFILES-1] looking for a file that is ++ the same as OUTFILE. If found, merge the found instances (and perhaps ++ some other files) into a temporary file so that it can in turn be ++ merged into OUTFILE without destroying OUTFILE before it is completely ++ read. Return the new value of NFILES, which differs from the old if ++ some merging occurred. ++ ++ This test ensures that an otherwise-erroneous use like ++ "sort -m -o FILE ... FILE ..." copies FILE before writing to it. ++ It's not clear that POSIX requires this nicety. ++ Detect common error cases, but don't try to catch obscure cases like ++ "cat ... FILE ... | sort -m -o FILE" ++ where traditional "sort" doesn't copy the input and where ++ people should know that they're getting into trouble anyway. ++ Catching these obscure cases would slow down performance in ++ common cases. */ ++ ++static size_t ++avoid_trashing_input (struct sortfile *files, size_t ntemps, ++ size_t nfiles, char const *outfile) ++{ ++ size_t i; ++ bool got_outstat = false; ++ struct stat outstat; ++ ++ for (i = ntemps; i < nfiles; i++) ++ { ++ bool is_stdin = STREQ (files[i].name, "-"); ++ bool same; ++ struct stat instat; ++ ++ if (outfile && STREQ (outfile, files[i].name) && !is_stdin) ++ same = true; ++ else ++ { ++ if (! got_outstat) ++ { ++ if ((outfile ++ ? stat (outfile, &outstat) ++ : fstat (STDOUT_FILENO, &outstat)) ++ != 0) ++ break; ++ got_outstat = true; ++ } ++ ++ same = (((is_stdin ++ ? fstat (STDIN_FILENO, &instat) ++ : stat (files[i].name, &instat)) ++ == 0) ++ && SAME_INODE (instat, outstat)); ++ } ++ ++ if (same) ++ { ++ FILE *tftp; ++ pid_t pid; ++ char *temp = create_temp (&tftp, &pid); ++ size_t num_merged = 0; ++ do ++ { ++ num_merged += mergefiles (&files[i], 0, nfiles - i, tftp, temp); ++ files[i].name = temp; ++ files[i].pid = pid; ++ ++ if (i + num_merged < nfiles) ++ memmove(&files[i + 1], &files[i + num_merged], ++ num_merged * sizeof *files); ++ ntemps += 1; ++ nfiles -= num_merged - 1;; ++ i += num_merged; ++ } ++ while (i < nfiles); ++ } ++ } ++ ++ return nfiles; ++} ++ ++/* Merge the input FILES. NTEMPS is the number of files at the ++ start of FILES that are temporary; it is zero at the top level. ++ NFILES is the total number of files. Put the output in ++ OUTPUT_FILE; a null OUTPUT_FILE stands for standard output. */ ++ ++static void ++merge (struct sortfile *files, size_t ntemps, size_t nfiles, ++ char const *output_file) ++{ ++ while (nmerge < nfiles) ++ { ++ /* Number of input files processed so far. */ ++ size_t in; ++ ++ /* Number of output files generated so far. */ ++ size_t out; ++ ++ /* nfiles % NMERGE; this counts input files that are left over ++ after all full-sized merges have been done. */ ++ size_t remainder; ++ ++ /* Number of easily-available slots at the next loop iteration. */ ++ size_t cheap_slots; ++ ++ /* Do as many NMERGE-size merges as possible. In the case that ++ nmerge is bogus, increment by the maximum number of file ++ descriptors allowed. */ ++ for (out = in = 0; nmerge <= nfiles - in; out++) ++ { ++ FILE *tfp; ++ pid_t pid; ++ char *temp = create_temp (&tfp, &pid); ++ size_t num_merged = mergefiles (&files[in], MIN (ntemps, nmerge), ++ nmerge, tfp, temp); ++ ntemps -= MIN (ntemps, num_merged); ++ files[out].name = temp; ++ files[out].pid = pid; ++ in += num_merged; ++ } ++ ++ remainder = nfiles - in; ++ cheap_slots = nmerge - out % nmerge; ++ ++ if (cheap_slots < remainder) ++ { ++ /* So many files remain that they can't all be put into the last ++ NMERGE-sized output window. Do one more merge. Merge as few ++ files as possible, to avoid needless I/O. */ ++ size_t nshortmerge = remainder - cheap_slots + 1; ++ FILE *tfp; ++ pid_t pid; ++ char *temp = create_temp (&tfp, &pid); ++ size_t num_merged = mergefiles (&files[in], MIN (ntemps, nshortmerge), ++ nshortmerge, tfp, temp); ++ ntemps -= MIN (ntemps, num_merged); ++ files[out].name = temp; ++ files[out++].pid = pid; ++ in += num_merged; ++ } ++ ++ /* Put the remaining input files into the last NMERGE-sized output ++ window, so they will be merged in the next pass. */ ++ memmove(&files[out], &files[in], (nfiles - in) * sizeof *files); ++ ntemps += out; ++ nfiles -= in - out; ++ } ++ ++ nfiles = avoid_trashing_input (files, ntemps, nfiles, output_file); ++ ++ /* We aren't guaranteed that this final mergefiles will work, therefore we ++ try to merge into the output, and then merge as much as we can into a ++ temp file if we can't. Repeat. */ ++ ++ for (;;) ++ { ++ /* Merge directly into the output file if possible. */ ++ FILE **fps; ++ size_t nopened = open_input_files (files, nfiles, &fps); ++ ++ if (nopened == nfiles) ++ { ++ FILE *ofp = stream_open (output_file, "w"); ++ if (ofp) ++ { ++ mergefps (files, ntemps, nfiles, ofp, output_file, fps); ++ break; ++ } ++ if (errno != EMFILE || nopened <= 2) ++ die (_("open failed"), output_file); ++ } ++ else if (nopened <= 2) ++ die (_("open failed"), files[nopened].name); ++ ++ /* We ran out of file descriptors. Close one of the input ++ files, to gain a file descriptor. Then create a temporary ++ file with our spare file descriptor. Retry if that failed ++ (e.g., some other process could open a file between the time ++ we closed and tried to create). */ ++ FILE *tfp; ++ pid_t pid; ++ char *temp; ++ do ++ { ++ nopened--; ++ xfclose (fps[nopened], files[nopened].name); ++ temp = maybe_create_temp (&tfp, &pid, ! (nopened <= 2)); ++ } ++ while (!temp); ++ ++ /* Merge into the newly allocated temporary. */ ++ mergefps (&files[0], MIN (ntemps, nopened), nopened, tfp, temp, fps); ++ ntemps -= MIN (ntemps, nopened); ++ files[0].name = temp; ++ files[0].pid = pid; ++ ++ memmove (&files[1], &files[nopened], (nfiles - nopened) * sizeof *files); ++ ntemps++; ++ nfiles -= nopened - 1; ++ } ++} ++ ++/* Sort NFILES FILES onto OUTPUT_FILE. */ ++ ++static void ++sort (char * const *files, size_t nfiles, char const *output_file) ++{ ++ struct buffer buf; ++ size_t ntemps = 0; ++ bool output_file_created = false; ++ ++ buf.alloc = 0; ++ ++ while (nfiles) ++ { ++ char const *temp_output; ++ char const *file = *files; ++ FILE *fp = xfopen (file, "r"); ++ FILE *tfp; ++ size_t bytes_per_line = (2 * sizeof (struct line) ++ - sizeof (struct line) / 2); ++ ++ if (! buf.alloc) ++ initbuf (&buf, bytes_per_line, ++ sort_buffer_size (&fp, 1, files, nfiles, bytes_per_line)); ++ buf.eof = false; ++ files++; ++ nfiles--; ++ ++ while (fillbuf (&buf, fp, file)) ++ { ++ struct line *line; ++ struct line *linebase; ++ ++ if (buf.eof && nfiles ++ && (bytes_per_line + 1 ++ < (buf.alloc - buf.used - bytes_per_line * buf.nlines))) ++ { ++ /* End of file, but there is more input and buffer room. ++ Concatenate the next input file; this is faster in ++ the usual case. */ ++ buf.left = buf.used; ++ break; ++ } ++ ++ line = buffer_linelim (&buf); ++ linebase = line - buf.nlines; ++ if (1 < buf.nlines) ++ sortlines (line, buf.nlines, linebase); ++ if (buf.eof && !nfiles && !ntemps && !buf.left) ++ { ++ xfclose (fp, file); ++ tfp = xfopen (output_file, "w"); ++ temp_output = output_file; ++ output_file_created = true; ++ } ++ else ++ { ++ ++ntemps; ++ temp_output = create_temp (&tfp, NULL); ++ } ++ ++ do ++ { ++ line--; ++ write_bytes (line->text, line->length, tfp, temp_output); ++ if (unique) ++ while (linebase < line && compare (line, line - 1) == 0) ++ line--; ++ } ++ while (linebase < line); ++ ++ xfclose (tfp, temp_output); ++ ++ /* Free up some resources every once in a while. */ ++ if (MAX_PROCS_BEFORE_REAP < nprocs) ++ reap_some (); ++ ++ if (output_file_created) ++ goto finish; ++ } ++ xfclose (fp, file); ++ } ++ ++ finish: ++ free (buf.buf); ++ ++ if (! output_file_created) ++ { ++ size_t i; ++ struct tempnode *node = temphead; ++ struct sortfile *tempfiles = xnmalloc (ntemps, sizeof *tempfiles); ++ for (i = 0; node; i++) ++ { ++ tempfiles[i].name = node->name; ++ tempfiles[i].pid = node->pid; ++ node = node->next; ++ } ++ merge (tempfiles, ntemps, ntemps, output_file); ++ free (tempfiles); ++ } ++} ++ ++/* Insert a malloc'd copy of key KEY_ARG at the end of the key list. */ ++ ++static void ++insertkey (struct keyfield *key_arg) ++{ ++ struct keyfield **p; ++ struct keyfield *key = xmemdup (key_arg, sizeof *key); ++ ++ for (p = &keylist; *p; p = &(*p)->next) ++ continue; ++ *p = key; ++ key->next = NULL; ++} ++ ++/* Report a bad field specification SPEC, with extra info MSGID. */ ++ ++static void badfieldspec (char const *, char const *) ++ ATTRIBUTE_NORETURN; ++static void ++badfieldspec (char const *spec, char const *msgid) ++{ ++ error (SORT_FAILURE, 0, _("%s: invalid field specification %s"), ++ _(msgid), quote (spec)); ++ abort (); ++} ++ ++/* Report incompatible options. */ ++ ++static void incompatible_options (char const *) ATTRIBUTE_NORETURN; ++static void ++incompatible_options (char const *opts) ++{ ++ error (SORT_FAILURE, 0, _("options `-%s' are incompatible"), opts); ++ abort (); ++} ++ ++/* Check compatibility of ordering options. */ ++ ++static void ++check_ordering_compatibility (void) ++{ ++ struct keyfield const *key; ++ ++ for (key = keylist; key; key = key->next) ++ if ((1 < (key->random + key->numeric + key->general_numeric + key->month ++ + key->version + !!key->ignore + key->human_numeric)) ++ || (key->random && key->translate)) ++ { ++ /* The following is too big, but guaranteed to be "big enough". */ ++ char opts[sizeof short_options]; ++ char *p = opts; ++ if (key->ignore == nondictionary) ++ *p++ = 'd'; ++ if (key->translate) ++ *p++ = 'f'; ++ if (key->general_numeric) ++ *p++ = 'g'; ++ if (key->human_numeric) ++ *p++ = 'h'; ++ if (key->ignore == nonprinting) ++ *p++ = 'i'; ++ if (key->month) ++ *p++ = 'M'; ++ if (key->numeric) ++ *p++ = 'n'; ++ if (key->version) ++ *p++ = 'V'; ++ if (key->random) ++ *p++ = 'R'; ++ *p = '\0'; ++ incompatible_options (opts); ++ } ++} ++ ++/* Parse the leading integer in STRING and store the resulting value ++ (which must fit into size_t) into *VAL. Return the address of the ++ suffix after the integer. If the value is too large, silently ++ substitute SIZE_MAX. If MSGID is NULL, return NULL after ++ failure; otherwise, report MSGID and exit on failure. */ ++ ++static char const * ++parse_field_count (char const *string, size_t *val, char const *msgid) ++{ ++ char *suffix; ++ uintmax_t n; ++ ++ switch (xstrtoumax (string, &suffix, 10, &n, "")) ++ { ++ case LONGINT_OK: ++ case LONGINT_INVALID_SUFFIX_CHAR: ++ *val = n; ++ if (*val == n) ++ break; ++ /* Fall through. */ ++ case LONGINT_OVERFLOW: ++ case LONGINT_OVERFLOW | LONGINT_INVALID_SUFFIX_CHAR: ++ *val = SIZE_MAX; ++ break; ++ ++ case LONGINT_INVALID: ++ if (msgid) ++ error (SORT_FAILURE, 0, _("%s: invalid count at start of %s"), ++ _(msgid), quote (string)); ++ return NULL; ++ } ++ ++ return suffix; ++} ++ ++/* Handle interrupts and hangups. */ ++ ++static void ++sighandler (int sig) ++{ ++ if (! SA_NOCLDSTOP) ++ signal (sig, SIG_IGN); ++ ++ cleanup (); ++ ++ signal (sig, SIG_DFL); ++ raise (sig); ++} ++ ++/* Set the ordering options for KEY specified in S. ++ Return the address of the first character in S that ++ is not a valid ordering option. ++ BLANKTYPE is the kind of blanks that 'b' should skip. */ ++ ++static char * ++set_ordering (const char *s, struct keyfield *key, enum blanktype blanktype) ++{ ++ while (*s) ++ { ++ switch (*s) ++ { ++ case 'b': ++ if (blanktype == bl_start || blanktype == bl_both) ++ key->skipsblanks = true; ++ if (blanktype == bl_end || blanktype == bl_both) ++ key->skipeblanks = true; ++ break; ++ case 'd': ++ key->ignore = nondictionary; ++ break; ++ case 'f': ++ key->translate = fold_toupper; ++ break; ++ case 'g': ++ key->general_numeric = true; ++ break; ++ case 'h': ++ key->human_numeric = true; ++ break; ++ case 'i': ++ /* Option order should not matter, so don't let -i override ++ -d. -d implies -i, but -i does not imply -d. */ ++ if (! key->ignore) ++ key->ignore = nonprinting; ++ break; ++ case 'M': ++ key->month = true; ++ break; ++ case 'n': ++ key->numeric = true; ++ break; ++ case 'R': ++ key->random = true; ++ break; ++ case 'r': ++ key->reverse = true; ++ break; ++ case 'V': ++ key->version = true; ++ break; ++ default: ++ return (char *) s; ++ } ++ ++s; ++ } ++ return (char *) s; ++} ++ ++static struct keyfield * ++key_init (struct keyfield *key) ++{ ++ memset (key, 0, sizeof *key); ++ key->eword = SIZE_MAX; ++ key->si_present = -1; ++ return key; ++} ++ ++int ++main (int argc, char **argv) ++{ ++ struct keyfield *key; ++ struct keyfield key_buf; ++ struct keyfield gkey; ++ char const *s; ++ int c = 0; ++ char checkonly = 0; ++ bool mergeonly = false; ++ char *random_source = NULL; ++ bool need_random = false; ++ size_t nfiles = 0; ++ bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL); ++ bool obsolete_usage = (posix2_version () < 200112); ++ char **files; ++ char *files_from = NULL; ++ struct Tokens tok; ++ char const *outfile = NULL; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ initialize_exit_failure (SORT_FAILURE); ++ ++ hard_LC_COLLATE = hard_locale (LC_COLLATE); ++#if HAVE_NL_LANGINFO ++ hard_LC_TIME = hard_locale (LC_TIME); ++#endif ++ ++ /* Get locale's representation of the decimal point. */ ++ { ++ struct lconv const *locale = localeconv (); ++ ++ /* If the locale doesn't define a decimal point, or if the decimal ++ point is multibyte, use the C locale's decimal point. FIXME: ++ add support for multibyte decimal points. */ ++ decimal_point = to_uchar (locale->decimal_point[0]); ++ if (! decimal_point || locale->decimal_point[1]) ++ decimal_point = '.'; ++ ++ /* FIXME: add support for multibyte thousands separators. */ ++ thousands_sep = to_uchar (*locale->thousands_sep); ++ if (! thousands_sep || locale->thousands_sep[1]) ++ thousands_sep = -1; ++ } ++ ++ have_read_stdin = false; ++ inittables (); ++ ++ { ++ size_t i; ++ static int const sig[] = ++ { ++ /* The usual suspects. */ ++ SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, ++#ifdef SIGPOLL ++ SIGPOLL, ++#endif ++#ifdef SIGPROF ++ SIGPROF, ++#endif ++#ifdef SIGVTALRM ++ SIGVTALRM, ++#endif ++#ifdef SIGXCPU ++ SIGXCPU, ++#endif ++#ifdef SIGXFSZ ++ SIGXFSZ, ++#endif ++ }; ++ enum { nsigs = ARRAY_CARDINALITY (sig) }; ++ ++#if SA_NOCLDSTOP ++ struct sigaction act; ++ ++ sigemptyset (&caught_signals); ++ for (i = 0; i < nsigs; i++) ++ { ++ sigaction (sig[i], NULL, &act); ++ if (act.sa_handler != SIG_IGN) ++ sigaddset (&caught_signals, sig[i]); ++ } ++ ++ act.sa_handler = sighandler; ++ act.sa_mask = caught_signals; ++ act.sa_flags = 0; ++ ++ for (i = 0; i < nsigs; i++) ++ if (sigismember (&caught_signals, sig[i])) ++ sigaction (sig[i], &act, NULL); ++#else ++ for (i = 0; i < nsigs; i++) ++ if (signal (sig[i], SIG_IGN) != SIG_IGN) ++ { ++ signal (sig[i], sighandler); ++ siginterrupt (sig[i], 1); ++ } ++#endif ++ } ++ ++ /* The signal mask is known, so it is safe to invoke exit_cleanup. */ ++ atexit (exit_cleanup); ++ ++ gkey.sword = gkey.eword = SIZE_MAX; ++ gkey.ignore = NULL; ++ gkey.translate = NULL; ++ gkey.numeric = gkey.general_numeric = gkey.human_numeric = false; ++ gkey.si_present = -1; ++ gkey.random = gkey.version = false; ++ gkey.month = gkey.reverse = false; ++ gkey.skipsblanks = gkey.skipeblanks = false; ++ ++ files = xnmalloc (argc, sizeof *files); ++ ++ for (;;) ++ { ++ /* Parse an operand as a file after "--" was seen; or if ++ pedantic and a file was seen, unless the POSIX version ++ predates 1003.1-2001 and -c was not seen and the operand is ++ "-o FILE" or "-oFILE". */ ++ int oi = -1; ++ ++ if (c == -1 ++ || (posixly_correct && nfiles != 0 ++ && ! (obsolete_usage ++ && ! checkonly ++ && optind != argc ++ && argv[optind][0] == '-' && argv[optind][1] == 'o' ++ && (argv[optind][2] || optind + 1 != argc))) ++ || ((c = getopt_long (argc, argv, short_options, ++ long_options, &oi)) ++ == -1)) ++ { ++ if (argc <= optind) ++ break; ++ files[nfiles++] = argv[optind++]; ++ } ++ else switch (c) ++ { ++ case 1: ++ key = NULL; ++ if (optarg[0] == '+') ++ { ++ bool minus_pos_usage = (optind != argc && argv[optind][0] == '-' ++ && ISDIGIT (argv[optind][1])); ++ obsolete_usage |= minus_pos_usage && !posixly_correct; ++ if (obsolete_usage) ++ { ++ /* Treat +POS1 [-POS2] as a key if possible; but silently ++ treat an operand as a file if it is not a valid +POS1. */ ++ key = key_init (&key_buf); ++ s = parse_field_count (optarg + 1, &key->sword, NULL); ++ if (s && *s == '.') ++ s = parse_field_count (s + 1, &key->schar, NULL); ++ if (! (key->sword || key->schar)) ++ key->sword = SIZE_MAX; ++ if (! s || *set_ordering (s, key, bl_start)) ++ key = NULL; ++ else ++ { ++ if (minus_pos_usage) ++ { ++ char const *optarg1 = argv[optind++]; ++ s = parse_field_count (optarg1 + 1, &key->eword, ++ N_("invalid number after `-'")); ++ if (*s == '.') ++ s = parse_field_count (s + 1, &key->echar, ++ N_("invalid number after `.'")); ++ if (*set_ordering (s, key, bl_end)) ++ badfieldspec (optarg1, ++ N_("stray character in field spec")); ++ } ++ insertkey (key); ++ } ++ } ++ } ++ if (! key) ++ files[nfiles++] = optarg; ++ break; ++ ++ case SORT_OPTION: ++ c = XARGMATCH ("--sort", optarg, sort_args, sort_types); ++ /* Fall through. */ ++ case 'b': ++ case 'd': ++ case 'f': ++ case 'g': ++ case 'h': ++ case 'i': ++ case 'M': ++ case 'n': ++ case 'r': ++ case 'R': ++ case 'V': ++ { ++ char str[2]; ++ str[0] = c; ++ str[1] = '\0'; ++ set_ordering (str, &gkey, bl_both); ++ } ++ break; ++ ++ case CHECK_OPTION: ++ c = (optarg ++ ? XARGMATCH ("--check", optarg, check_args, check_types) ++ : 'c'); ++ /* Fall through. */ ++ case 'c': ++ case 'C': ++ if (checkonly && checkonly != c) ++ incompatible_options ("cC"); ++ checkonly = c; ++ break; ++ ++ case COMPRESS_PROGRAM_OPTION: ++ if (compress_program && !STREQ (compress_program, optarg)) ++ error (SORT_FAILURE, 0, _("multiple compress programs specified")); ++ compress_program = optarg; ++ break; ++ ++ case FILES0_FROM_OPTION: ++ files_from = optarg; ++ break; ++ ++ case 'k': ++ key = key_init (&key_buf); ++ ++ /* Get POS1. */ ++ s = parse_field_count (optarg, &key->sword, ++ N_("invalid number at field start")); ++ if (! key->sword--) ++ { ++ /* Provoke with `sort -k0' */ ++ badfieldspec (optarg, N_("field number is zero")); ++ } ++ if (*s == '.') ++ { ++ s = parse_field_count (s + 1, &key->schar, ++ N_("invalid number after `.'")); ++ if (! key->schar--) ++ { ++ /* Provoke with `sort -k1.0' */ ++ badfieldspec (optarg, N_("character offset is zero")); ++ } ++ } ++ if (! (key->sword || key->schar)) ++ key->sword = SIZE_MAX; ++ s = set_ordering (s, key, bl_start); ++ if (*s != ',') ++ { ++ key->eword = SIZE_MAX; ++ key->echar = 0; ++ } ++ else ++ { ++ /* Get POS2. */ ++ s = parse_field_count (s + 1, &key->eword, ++ N_("invalid number after `,'")); ++ if (! key->eword--) ++ { ++ /* Provoke with `sort -k1,0' */ ++ badfieldspec (optarg, N_("field number is zero")); ++ } ++ if (*s == '.') ++ { ++ s = parse_field_count (s + 1, &key->echar, ++ N_("invalid number after `.'")); ++ } ++ s = set_ordering (s, key, bl_end); ++ } ++ if (*s) ++ badfieldspec (optarg, N_("stray character in field spec")); ++ insertkey (key); ++ break; ++ ++ case 'm': ++ mergeonly = true; ++ break; ++ ++ case NMERGE_OPTION: ++ specify_nmerge (oi, c, optarg); ++ break; ++ ++ case 'o': ++ if (outfile && !STREQ (outfile, optarg)) ++ error (SORT_FAILURE, 0, _("multiple output files specified")); ++ outfile = optarg; ++ break; ++ ++ case RANDOM_SOURCE_OPTION: ++ if (random_source && !STREQ (random_source, optarg)) ++ error (SORT_FAILURE, 0, _("multiple random sources specified")); ++ random_source = optarg; ++ break; ++ ++ case 's': ++ stable = true; ++ break; ++ ++ case 'S': ++ specify_sort_size (oi, c, optarg); ++ break; ++ ++ case 't': ++ { ++ char newtab = optarg[0]; ++ if (! newtab) ++ error (SORT_FAILURE, 0, _("empty tab")); ++ if (optarg[1]) ++ { ++ if (STREQ (optarg, "\\0")) ++ newtab = '\0'; ++ else ++ { ++ /* Provoke with `sort -txx'. Complain about ++ "multi-character tab" instead of "multibyte tab", so ++ that the diagnostic's wording does not need to be ++ changed once multibyte characters are supported. */ ++ error (SORT_FAILURE, 0, _("multi-character tab %s"), ++ quote (optarg)); ++ } ++ } ++ if (tab != TAB_DEFAULT && tab != newtab) ++ error (SORT_FAILURE, 0, _("incompatible tabs")); ++ tab = newtab; ++ } ++ break; ++ ++ case 'T': ++ add_temp_dir (optarg); ++ break; ++ ++ case 'u': ++ unique = true; ++ break; ++ ++ case 'y': ++ /* Accept and ignore e.g. -y0 for compatibility with Solaris 2.x ++ through Solaris 7. It is also accepted by many non-Solaris ++ "sort" implementations, e.g., AIX 5.2, HP-UX 11i v2, IRIX 6.5. ++ -y is marked as obsolete starting with Solaris 8 (1999), but is ++ still accepted as of Solaris 10 prerelease (2004). ++ ++ Solaris 2.5.1 "sort -y 100" reads the input file "100", but ++ emulate Solaris 8 and 9 "sort -y 100" which ignores the "100", ++ and which in general ignores the argument after "-y" if it ++ consists entirely of digits (it can even be empty). */ ++ if (optarg == argv[optind - 1]) ++ { ++ char const *p; ++ for (p = optarg; ISDIGIT (*p); p++) ++ continue; ++ optind -= (*p != '\0'); ++ } ++ break; ++ ++ case 'z': ++ eolchar = 0; ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (SORT_FAILURE); ++ } ++ } ++ ++ if (files_from) ++ { ++ FILE *stream; ++ ++ /* When using --files0-from=F, you may not specify any files ++ on the command-line. */ ++ if (nfiles) ++ { ++ error (0, 0, _("extra operand %s"), quote (files[0])); ++ fprintf (stderr, "%s\n", ++ _("file operands cannot be combined with --files0-from")); ++ usage (SORT_FAILURE); ++ } ++ ++ if (STREQ (files_from, "-")) ++ stream = stdin; ++ else ++ { ++ stream = fopen (files_from, "r"); ++ if (stream == NULL) ++ error (SORT_FAILURE, errno, _("cannot open %s for reading"), ++ quote (files_from)); ++ } ++ ++ readtokens0_init (&tok); ++ ++ if (! readtokens0 (stream, &tok) || fclose (stream) != 0) ++ error (SORT_FAILURE, 0, _("cannot read file names from %s"), ++ quote (files_from)); ++ ++ if (tok.n_tok) ++ { ++ size_t i; ++ free (files); ++ files = tok.tok; ++ nfiles = tok.n_tok; ++ for (i = 0; i < nfiles; i++) ++ { ++ if (STREQ (files[i], "-")) ++ error (SORT_FAILURE, 0, _("when reading file names from stdin, " ++ "no file name of %s allowed"), ++ quote (files[i])); ++ else if (files[i][0] == '\0') ++ { ++ /* Using the standard `filename:line-number:' prefix here is ++ not totally appropriate, since NUL is the separator, not NL, ++ but it might be better than nothing. */ ++ unsigned long int file_number = i + 1; ++ error (SORT_FAILURE, 0, ++ _("%s:%lu: invalid zero-length file name"), ++ quotearg_colon (files_from), file_number); ++ } ++ } ++ } ++ else ++ error (SORT_FAILURE, 0, _("no input from %s"), ++ quote (files_from)); ++ } ++ ++ /* Inheritance of global options to individual keys. */ ++ for (key = keylist; key; key = key->next) ++ { ++ if (! (key->ignore ++ || key->translate ++ || (key->skipsblanks ++ || key->reverse ++ || key->skipeblanks ++ || key->month ++ || key->numeric ++ || key->version ++ || key->general_numeric ++ || key->human_numeric ++ || key->random))) ++ { ++ key->ignore = gkey.ignore; ++ key->translate = gkey.translate; ++ key->skipsblanks = gkey.skipsblanks; ++ key->skipeblanks = gkey.skipeblanks; ++ key->month = gkey.month; ++ key->numeric = gkey.numeric; ++ key->general_numeric = gkey.general_numeric; ++ key->human_numeric = gkey.human_numeric; ++ key->random = gkey.random; ++ key->reverse = gkey.reverse; ++ key->version = gkey.version; ++ } ++ ++ need_random |= key->random; ++ } ++ ++ if (!keylist && (gkey.ignore ++ || gkey.translate ++ || (gkey.skipsblanks ++ || gkey.skipeblanks ++ || gkey.month ++ || gkey.numeric ++ || gkey.general_numeric ++ || gkey.human_numeric ++ || gkey.random ++ || gkey.version))) ++ { ++ insertkey (&gkey); ++ need_random |= gkey.random; ++ } ++ ++ check_ordering_compatibility (); ++ ++ reverse = gkey.reverse; ++ ++ if (need_random) ++ { ++ randread_source = randread_new (random_source, MD5_DIGEST_SIZE); ++ if (! randread_source) ++ die (_("open failed"), random_source); ++ } ++ ++ if (temp_dir_count == 0) ++ { ++ char const *tmp_dir = getenv ("TMPDIR"); ++ add_temp_dir (tmp_dir ? tmp_dir : DEFAULT_TMPDIR); ++ } ++ ++ if (nfiles == 0) ++ { ++ static char *minus = (char *) "-"; ++ nfiles = 1; ++ free (files); ++ files = − ++ } ++ ++ /* Need to re-check that we meet the minimum requirement for memory ++ usage with the final value for NMERGE. */ ++ if (0 < sort_size) ++ sort_size = MAX (sort_size, MIN_SORT_SIZE); ++ ++ if (checkonly) ++ { ++ if (nfiles > 1) ++ error (SORT_FAILURE, 0, _("extra operand %s not allowed with -%c"), ++ quote (files[1]), checkonly); ++ ++ if (outfile) ++ { ++ static char opts[] = {0, 'o', 0}; ++ opts[0] = checkonly; ++ incompatible_options (opts); ++ } ++ ++ /* POSIX requires that sort return 1 IFF invoked with -c or -C and the ++ input is not properly sorted. */ ++ exit (check (files[0], checkonly) ? EXIT_SUCCESS : SORT_OUT_OF_ORDER); ++ } ++ ++ if (mergeonly) ++ { ++ struct sortfile *sortfiles = xcalloc (nfiles, sizeof *sortfiles); ++ size_t i; ++ ++ for (i = 0; i < nfiles; ++i) ++ sortfiles[i].name = files[i]; ++ ++ merge (sortfiles, 0, nfiles, outfile); ++ IF_LINT (free (sortfiles)); ++ } ++ else ++ sort (files, nfiles, outfile); ++ ++ if (have_read_stdin && fclose (stdin) == EOF) ++ die (_("close failed"), "-"); ++ ++ exit (EXIT_SUCCESS); ++} +diff -urNp coreutils-8.0-orig/src/unexpand.c coreutils-8.0/src/unexpand.c +--- coreutils-8.0-orig/src/unexpand.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/unexpand.c 2009-10-07 10:07:16.000000000 +0200 +@@ -38,11 +38,28 @@ #include #include #include @@ -2482,7 +12965,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "unexpand" -@@ -110,6 +127,208 @@ +@@ -102,6 +119,208 @@ static struct option const longopts[] = {NULL, 0, NULL, 0} }; @@ -2691,7 +13174,7 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c void usage (int status) { -@@ -531,7 +750,12 @@ +@@ -523,7 +742,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -2705,752 +13188,572 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); ---- coreutils-6.8+/src/pr.c.i18n 2007-01-14 15:41:28.000000000 +0000 -+++ coreutils-6.8+/src/pr.c 2007-03-01 15:08:24.000000000 +0000 -@@ -313,6 +313,32 @@ - - #include - #include +diff -urNp coreutils-8.0-orig/src/unexpand.c.orig coreutils-8.0/src/unexpand.c.orig +--- coreutils-8.0-orig/src/unexpand.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/unexpand.c.orig 2009-09-29 15:27:54.000000000 +0200 +@@ -0,0 +1,532 @@ ++/* unexpand - convert blanks to tabs ++ Copyright (C) 89, 91, 1995-2006, 2008-2009 Free Software Foundation, Inc. + -+/* 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 ++ 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. + -+/* Get MB_CUR_MAX. */ -+#include ++ 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. + -+/* Solaris 2.5 has a bug: must be included before . */ -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ + -+/* Get iswprint(). -- for wcwidth(). */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+#if !defined iswprint && !HAVE_ISWPRINT -+# define iswprint(wc) 1 -+#endif ++/* By default, convert only maximal strings of initial blanks and tabs ++ into tabs. ++ Preserves backspace characters in the output; they decrement the ++ column count for tab calculations. ++ The default action is equivalent to -8. + - #include "system.h" - #include "error.h" - #include "mbswidth.h" -@@ -324,6 +350,18 @@ - #include "strftime.h" - #include "xstrtol.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 ++ Options: ++ --tabs=tab1[,tab2[,...]] ++ -t tab1[,tab2[,...]] ++ -tab1[,tab2[,...]] If only one tab stop is given, set the tabs tab1 ++ columns apart instead of the default 8. Otherwise, ++ set the tabs at columns tab1, tab2, etc. (numbered from ++ 0); preserve any blanks beyond the tab stops given. ++ --all ++ -a Use tabs wherever they would replace 2 or more blanks, ++ not just at the beginnings of lines. + -+#ifndef HAVE_DECL_WCWIDTH -+"this configure-time declaration test was not run" -+#endif -+#if !HAVE_DECL_WCWIDTH -+extern int wcwidth (); -+#endif ++ David MacKenzie */ + - /* The official name of this program (e.g., no `g' prefix). */ - #define PROGRAM_NAME "pr" - -@@ -416,7 +454,20 @@ - - 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); ++#include + -+/* Functions for single byte locale. */ -+static void print_char_single (char c); -+static int char_to_clump_single (char c); ++#include ++#include ++#include ++#include "system.h" ++#include "error.h" ++#include "quote.h" ++#include "xstrndup.h" + -+/* Functions for multibyte locale. */ -+static void print_char_multi (char c); -+static int char_to_clump_multi (char c); ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "unexpand" + - static bool read_line (COLUMN *p); - static bool print_page (void); - static bool print_stored (COLUMN *p); -@@ -426,6 +477,7 @@ - static void pad_across_to (int position); - static void add_line_number (COLUMN *p); - static void getoptarg (char *arg, char switch_char, char *character, -+ int *character_length, int *character_width, - int *number); - void usage (int status); - static void print_files (int number_of_files, char **av); -@@ -440,7 +492,6 @@ - static void pad_down (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); -@@ -455,7 +506,7 @@ - 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. */ -@@ -559,7 +610,7 @@ - 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. */ -@@ -569,7 +620,10 @@ - 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"; ++#define AUTHORS proper_name ("David MacKenzie") + -+/* (-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; -@@ -643,7 +697,13 @@ - 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"; ++/* If true, convert blanks even after nonblank characters have been ++ read on the line. */ ++static bool convert_entire_line; + -+/* (-n) The byte length of the character which follows each line number. */ -+static int number_separator_length = 1; ++/* If nonzero, the size of all tab stops. If zero, use `tab_list' instead. */ ++static size_t tab_size; + -+/* (-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). */ -@@ -696,6 +756,7 @@ - -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ - static char *col_sep_string = (char *) ""; - 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 +913,13 @@ - col_sep_length = (int) strlen (optarg_S); - col_sep_string = xmalloc (col_sep_length + 1); - strcpy (col_sep_string, optarg_S); ++/* The maximum distance between tab stops. */ ++static size_t max_column_width; + -+#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 -@@ -877,6 +945,21 @@ - - 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; -+ } ++/* Array of the explicit column numbers of the tab stops; ++ after `tab_list' is exhausted, the rest of the line is printed ++ unchanged. The first column is column 0. */ ++static uintmax_t *tab_list; + - n_files = 0; - file_names = (argc > 1 - ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -949,8 +1032,12 @@ - break; - case 'e': - if (optarg) -- getoptarg (optarg, 'e', &input_tab_char, -- &chars_per_input_tab); -+ { -+ int dummy_length, dummy_width; ++/* The number of allocated entries in `tab_list'. */ ++static size_t n_tabs_allocated; + -+ getoptarg (optarg, 'e', input_tab_char, &dummy_length, -+ &dummy_width, &chars_per_input_tab); -+ } - /* Could check tab width > 0. */ - untabify_input = true; - break; -@@ -963,8 +1050,12 @@ - break; - case 'i': - if (optarg) -- getoptarg (optarg, 'i', &output_tab_char, -- &chars_per_output_tab); -+ { -+ int dummy_width; ++/* The index of the first invalid element of `tab_list', ++ where the next element can be added. */ ++static size_t first_free_tab; + -+ 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; -@@ -991,8 +1082,8 @@ - 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; -@@ -1031,7 +1122,7 @@ - old_s = false; - /* Reset an additional input of -s, -S dominates -s */ - col_sep_string = bad_cast (""); -- col_sep_length = 0; -+ col_sep_length = col_sep_width = 0; - use_col_separator = true; - if (optarg) - separator_string (optarg); -@@ -1188,10 +1279,45 @@ - 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'}; ++/* Null-terminated array of input filenames. */ ++static char **file_list; + -+ 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; -@@ -1256,7 +1382,7 @@ - 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 -@@ -1288,11 +1414,11 @@ - 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. */ -@@ -1307,7 +1433,7 @@ - } - - chars_per_column = (chars_per_line - chars_used_by_number - -- (columns - 1) * col_sep_length) / columns; -+ (columns - 1) * col_sep_width) / columns; - - if (chars_per_column < 1) - error (EXIT_FAILURE, 0, _("page width too narrow")); -@@ -1432,7 +1558,7 @@ - - /* 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. */ - -@@ -1466,7 +1592,7 @@ - } - else - { -- h = h_next + col_sep_length; -+ h = h_next + col_sep_width; - h_next = h + chars_per_column; - } - } -@@ -1756,9 +1882,9 @@ - align_column (COLUMN *p) - { - padding_not_printed = p->start_position; -- if (padding_not_printed - col_sep_length > 0) -+ if (padding_not_printed - col_sep_width > 0) - { -- pad_across_to (padding_not_printed - col_sep_length); -+ pad_across_to (padding_not_printed - col_sep_width); - padding_not_printed = ANYWHERE; - } - -@@ -2029,13 +2155,13 @@ - /* 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 left_cut; - -@@ -2058,22 +2184,24 @@ - /* 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); - } -@@ -2234,7 +2362,7 @@ - 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) -@@ -2254,6 +2382,7 @@ - { - char *s; - int l = col_sep_length; -+ int not_space_flag; - - s = col_sep_string; - -@@ -2267,6 +2396,7 @@ - { - 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, -@@ -2280,12 +2410,15 @@ - } - 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 (); -@@ -2313,7 +2446,7 @@ - required number of tabs and spaces. */ - - static void --print_char (char c) -+print_char_single (char c) - { - if (tabify_output) - { -@@ -2337,6 +2470,74 @@ - putchar (c); - } - -+#ifdef HAVE_MBRTOWC -+static void -+print_char_multi (char c) ++/* Default for `file_list' if no files are given on the command line. */ ++static char *stdin_argv[] = +{ -+ 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; ++ (char *) "-", NULL ++}; + -+ if (tabify_output) ++/* True if we have ever read standard input. */ ++static bool have_read_stdin; ++ ++/* The desired exit status. */ ++static int exit_status; ++ ++/* For long options that have no equivalent short option, use a ++ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ ++enum ++{ ++ CONVERT_FIRST_ONLY_OPTION = CHAR_MAX + 1 ++}; ++ ++static struct option const longopts[] = ++{ ++ {"tabs", required_argument, NULL, 't'}, ++ {"all", no_argument, NULL, 'a'}, ++ {"first-only", no_argument, NULL, CONVERT_FIRST_ONLY_OPTION}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else + { -+ 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; ++ printf (_("\ ++Usage: %s [OPTION]... [FILE]...\n\ ++"), ++ program_name); ++ fputs (_("\ ++Convert blanks in each FILE to tabs, writing to standard output.\n\ ++With no FILE, or when FILE is -, read standard input.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ -a, --all convert all blanks, instead of just initial blanks\n\ ++ --first-only convert only leading sequences of blanks (overrides -a)\n\ ++ -t, --tabs=N have tabs N characters apart instead of 8 (enables -a)\n\ ++ -t, --tabs=LIST use comma separated LIST of tab positions (enables -a)\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ emit_ancillary_info (); + } -+ putchar (c); ++ exit (status); +} -+#endif + - /* Skip to page PAGE before printing. - PAGE may be larger than total number of pages. */ - -@@ -2517,9 +2718,9 @@ - align_empty_cols = false; - } - -- if (padding_not_printed - col_sep_length > 0) -+ if (padding_not_printed - col_sep_width > 0) - { -- pad_across_to (padding_not_printed - col_sep_length); -+ pad_across_to (padding_not_printed - col_sep_width); - padding_not_printed = ANYWHERE; - } - -@@ -2620,9 +2821,9 @@ - } - } - -- if (padding_not_printed - col_sep_length > 0) -+ if (padding_not_printed - col_sep_width > 0) - { -- pad_across_to (padding_not_printed - col_sep_length); -+ pad_across_to (padding_not_printed - col_sep_width); - padding_not_printed = ANYWHERE; - } - -@@ -2635,8 +2836,8 @@ - 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; -@@ -2655,7 +2856,7 @@ - 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; -@@ -2665,10 +2866,10 @@ - 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); - -@@ -2739,6 +2940,154 @@ - return chars; - } - -+#ifdef HAVE_MBRTOWC -+static int -+char_to_clump_multi (char c) ++/* Add tab stop TABVAL to the end of `tab_list'. */ ++ ++static void ++add_tab_stop (uintmax_t tabval) +{ -+ 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; ++ uintmax_t prev_column = first_free_tab ? tab_list[first_free_tab - 1] : 0; ++ uintmax_t column_width = prev_column <= tabval ? tabval - prev_column : 0; + -+ state_bak = state; -+ mbc[mbc_pos++] = c; -+ mblength = mbrtowc (&wc, mbc, mbc_pos, &state); ++ if (first_free_tab == n_tabs_allocated) ++ tab_list = X2NREALLOC (tab_list, &n_tabs_allocated); ++ tab_list[first_free_tab++] = tabval; + -+ width = 0; -+ chars = 0; -+ while (mbc_pos > 0) ++ if (max_column_width < column_width) + { -+ switch (mblength) ++ if (SIZE_MAX < column_width) ++ error (EXIT_FAILURE, 0, _("tabs are too far apart")); ++ max_column_width = column_width; ++ } ++} ++ ++/* Add the comma or blank separated list of tab stops STOPS ++ to the list of tab stops. */ ++ ++static void ++parse_tab_stops (char const *stops) ++{ ++ bool have_tabval = false; ++ uintmax_t tabval IF_LINT (= 0); ++ char const *num_start IF_LINT (= NULL); ++ bool ok = true; ++ ++ for (; *stops; stops++) ++ { ++ if (*stops == ',' || isblank (to_uchar (*stops))) + { -+ 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) ++ if (have_tabval) ++ add_tab_stop (tabval); ++ have_tabval = false; ++ } ++ else if (ISDIGIT (*stops)) ++ { ++ if (!have_tabval) + { -+ width = +4; -+ chars = +4; -+ *s++ = '\\'; -+ sprintf (esc_buff, "%03o", mbc[0]); -+ for (i = 0; i <= 2; ++i) -+ *s++ = (int) esc_buff[i]; ++ tabval = 0; ++ have_tabval = true; ++ num_start = stops; + } -+ else ++ ++ /* Detect overflow. */ ++ if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) + { -+ width += 1; -+ chars += 1; -+ *s++ = mbc[0]; ++ size_t len = strspn (num_start, "0123456789"); ++ char *bad_num = xstrndup (num_start, len); ++ error (0, 0, _("tab stop is too large %s"), quote (bad_num)); ++ free (bad_num); ++ ok = false; ++ stops = num_start + len - 1; + } ++ } ++ else ++ { ++ error (0, 0, _("tab size contains invalid character(s): %s"), ++ quote (stops)); ++ ok = false; + break; ++ } ++ } + -+ case 0: -+ mblength = 1; -+ /* Fall through */ ++ if (!ok) ++ exit (EXIT_FAILURE); + -+ default: -+ if (memcmp (mbc, input_tab_char, mblength) == 0) -+ chars_per_c = chars_per_input_tab; ++ if (have_tabval) ++ add_tab_stop (tabval); ++} + -+ if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') ++/* Check that the list of tab stops TABS, with ENTRIES entries, ++ contains only nonzero, ascending values. */ ++ ++static void ++validate_tab_stops (uintmax_t const *tabs, size_t entries) ++{ ++ uintmax_t prev_tab = 0; ++ size_t i; ++ ++ for (i = 0; i < entries; i++) ++ { ++ if (tabs[i] == 0) ++ error (EXIT_FAILURE, 0, _("tab size cannot be 0")); ++ if (tabs[i] <= prev_tab) ++ error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); ++ prev_tab = tabs[i]; ++ } ++} ++ ++/* Close the old stream pointer FP if it is non-NULL, ++ and return a new one opened to read the next input file. ++ Open a filename of `-' as the standard input. ++ Return NULL if there are no more input files. */ ++ ++static FILE * ++next_file (FILE *fp) ++{ ++ static char *prev_file; ++ char *file; ++ ++ if (fp) ++ { ++ if (ferror (fp)) ++ { ++ error (0, errno, "%s", prev_file); ++ exit_status = EXIT_FAILURE; ++ } ++ if (STREQ (prev_file, "-")) ++ clearerr (fp); /* Also clear EOF. */ ++ else if (fclose (fp) != 0) ++ { ++ error (0, errno, "%s", prev_file); ++ exit_status = EXIT_FAILURE; ++ } ++ } ++ ++ while ((file = *file_list++) != NULL) ++ { ++ if (STREQ (file, "-")) ++ { ++ have_read_stdin = true; ++ prev_file = file; ++ return stdin; ++ } ++ fp = fopen (file, "r"); ++ if (fp) ++ { ++ prev_file = file; ++ return fp; ++ } ++ error (0, errno, "%s", file); ++ exit_status = EXIT_FAILURE; ++ } ++ return NULL; ++} ++ ++/* Change blanks to tabs, writing to stdout. ++ Read each file in `file_list', in order. */ ++ ++static void ++unexpand (void) ++{ ++ /* Input stream. */ ++ FILE *fp = next_file (NULL); ++ ++ /* 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; ++ ++ if (!fp) ++ return; ++ ++ /* 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); ++ ++ for (;;) ++ { ++ /* Input character, or EOF. */ ++ int c; ++ ++ /* If true, perform translations. */ ++ bool convert = true; ++ ++ ++ /* The following variables have valid values only when CONVERT ++ is true: */ ++ ++ /* Column of next input character. */ ++ uintmax_t column = 0; ++ ++ /* Column the next input tab stop is on. */ ++ uintmax_t next_tab_column = 0; ++ ++ /* Index in TAB_LIST of next tab stop to examine. */ ++ size_t tab_index = 0; ++ ++ /* If true, the first pending blank came just before a tab stop. */ ++ bool one_blank_before_tab_stop = false; ++ ++ /* If true, the previous input character was a blank. This is ++ initially true, since initial strings of blanks are treated ++ as if the line was preceded by a blank. */ ++ bool prev_blank = true; ++ ++ /* Number of pending columns of blanks. */ ++ size_t pending = 0; ++ ++ ++ /* Convert a line of text. */ ++ ++ do ++ { ++ while ((c = getc (fp)) < 0 && (fp = next_file (fp))) ++ continue; ++ ++ if (convert) + { -+ int width_inc; ++ bool blank = !! isblank (c); + -+ width_inc = TAB_WIDTH (chars_per_c, input_position); -+ width += width_inc; ++ if (blank) ++ { ++ if (next_tab_column <= column) ++ { ++ if (tab_size) ++ next_tab_column = ++ column + (tab_size - column % tab_size); ++ else ++ for (;;) ++ if (tab_index == first_free_tab) ++ { ++ convert = false; ++ break; ++ } ++ else ++ { ++ uintmax_t tab = tab_list[tab_index++]; ++ if (column < tab) ++ { ++ next_tab_column = tab; ++ break; ++ } ++ } ++ } + -+ 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++) ++ if (convert) + { -+ width += 4; -+ chars += 4; -+ *s++ = '\\'; -+ sprintf (esc_buff, "%03o", c); -+ 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++) ++ if (next_tab_column < column) ++ error (EXIT_FAILURE, 0, _("input line is too long")); ++ ++ if (c == '\t') + { -+ width += 4; -+ chars += 4; -+ *s++ = '\\'; -+ sprintf (esc_buff, "%03o", c); -+ for (j = 0; j <= 2; ++j) -+ *s++ = (int) esc_buff[j]; ++ column = next_tab_column; ++ ++ /* Discard pending blanks, unless it was a single ++ blank just before the previous tab stop. */ ++ if (! (pending == 1 && one_blank_before_tab_stop)) ++ { ++ pending = 0; ++ one_blank_before_tab_stop = false; ++ } ++ } ++ else ++ { ++ column++; ++ ++ if (! (prev_blank && column == next_tab_column)) ++ { ++ /* It is not yet known whether the pending blanks ++ will be replaced by tabs. */ ++ if (column == next_tab_column) ++ one_blank_before_tab_stop = true; ++ pending_blank[pending++] = c; ++ prev_blank = true; ++ continue; ++ } ++ ++ /* Replace the pending blanks by a tab or two. */ ++ pending_blank[0] = c = '\t'; ++ pending = one_blank_before_tab_stop; + } + } + } -+ else if (wc == L'\b') ++ else if (c == '\b') + { -+ width += -1; -+ chars += 1; -+ *s++ = c; ++ /* Go back one column, and force recalculation of the ++ next tab stop. */ ++ column -= !!column; ++ next_tab_column = column; ++ tab_index -= !!tab_index; + } + else + { -+ width += 0; -+ chars += mblength; -+ for (i = 0; i < mblength; i++) -+ *s++ = mbc[i]; ++ column++; ++ if (!column) ++ error (EXIT_FAILURE, 0, _("input line is too long")); + } ++ ++ if (pending) ++ { ++ if (fwrite (pending_blank, 1, pending, stdout) != pending) ++ error (EXIT_FAILURE, errno, _("write error")); ++ pending = 0; ++ one_blank_before_tab_stop = false; ++ } ++ ++ prev_blank = blank; ++ convert &= convert_entire_line || blank; + } -+ else ++ ++ if (c < 0) + { -+ width += wc_width; -+ chars += mblength; -+ for (i = 0; i < mblength; i++) -+ *s++ = mbc[i]; ++ free (pending_blank); ++ return; + } ++ ++ if (putchar (c) < 0) ++ error (EXIT_FAILURE, errno, _("write error")); ++ } ++ while (c != '\n'); ++ } ++} ++ ++int ++main (int argc, char **argv) ++{ ++ bool have_tabval = false; ++ uintmax_t tabval IF_LINT (= 0); ++ int c; ++ ++ /* If true, cancel the effect of any -a (explicit or implicit in -t), ++ so that only leading blanks will be considered. */ ++ bool convert_first_only = false; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ atexit (close_stdout); ++ ++ have_read_stdin = false; ++ exit_status = EXIT_SUCCESS; ++ convert_entire_line = false; ++ tab_list = NULL; ++ first_free_tab = 0; ++ ++ while ((c = getopt_long (argc, argv, ",0123456789at:", longopts, NULL)) ++ != -1) ++ { ++ switch (c) ++ { ++ case '?': ++ usage (EXIT_FAILURE); ++ case 'a': ++ convert_entire_line = true; ++ break; ++ case 't': ++ convert_entire_line = true; ++ parse_tab_stops (optarg); ++ break; ++ case CONVERT_FIRST_ONLY_OPTION: ++ convert_first_only = true; ++ break; ++ case ',': ++ if (have_tabval) ++ add_tab_stop (tabval); ++ have_tabval = false; ++ break; ++ case_GETOPT_HELP_CHAR; ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ default: ++ if (!have_tabval) ++ { ++ tabval = 0; ++ have_tabval = true; ++ } ++ if (!DECIMAL_DIGIT_ACCUMULATE (tabval, c - '0', uintmax_t)) ++ error (EXIT_FAILURE, 0, _("tab stop value is too large")); ++ break; + } -+ memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); -+ mbc_pos -= mblength; + } + -+ input_position += width; -+ return chars; -+} -+#endif ++ if (convert_first_only) ++ convert_entire_line = false; + - /* We've just printed some files and need to clean up things before - looking for more options and printing the next batch of files. - ---- coreutils-6.8+/src/cut.c.i18n 2007-01-14 15:41:28.000000000 +0000 -+++ coreutils-6.8+/src/cut.c 2007-03-01 15:08:24.000000000 +0000 -@@ -29,6 +29,11 @@ - #include ++ if (have_tabval) ++ add_tab_stop (tabval); ++ ++ validate_tab_stops (tab_list, first_free_tab); ++ ++ if (first_free_tab == 0) ++ tab_size = max_column_width = 8; ++ else if (first_free_tab == 1) ++ tab_size = tab_list[0]; ++ else ++ tab_size = 0; ++ ++ file_list = (optind < argc ? &argv[optind] : stdin_argv); ++ ++ unexpand (); ++ ++ if (have_read_stdin && fclose (stdin) != 0) ++ error (EXIT_FAILURE, errno, "-"); ++ ++ exit (exit_status); ++} +diff -urNp coreutils-8.0-orig/src/uniq.c coreutils-8.0/src/uniq.c +--- coreutils-8.0-orig/src/uniq.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/uniq.c 2009-10-07 10:07:16.000000000 +0200 +@@ -22,6 +22,16 @@ #include #include -+ -+/* Get mbstate_t, mbrtowc(). */ + ++/* Get mbstate_t, mbrtowc(). */ +#if HAVE_WCHAR_H +# include +#endif ++ ++/* Get isw* functions. */ ++#if HAVE_WCTYPE_H ++# include ++#endif ++ #include "system.h" - - #include "error.h" -@@ -37,6 +42,18 @@ + #include "argmatch.h" + #include "linebuffer.h" +@@ -31,7 +41,19 @@ #include "quote.h" - #include "xstrndup.h" - + #include "xmemcoll.h" + #include "xstrtol.h" +-#include "memcasecmp.h" ++#include "xmemcoll.h" ++ +/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC -+ installation; work around this configuration error. */ ++ 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 + @@ -3459,581 +13762,1660 @@ diff -urNp coreutils-6.11-orig/src/join.c coreutils-6.11/src/join.c +# 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" + #define PROGRAM_NAME "uniq" +@@ -107,6 +129,10 @@ static enum delimit_method const delimit + /* Select whether/how to delimit groups of duplicate lines. */ + static enum delimit_method delimit_groups; -@@ -67,6 +84,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) ++/* Function pointers. */ ++static char * ++(*find_field) (struct linebuffer *line); + -+/* Get wide character on BUFPOS. BUFPOS is not included after that. -+ If byte sequence is not valid as a character, CONVFAIL is 1. Otherwise 0. */ -+#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ + static struct option const longopts[] = + { + {"count", no_argument, NULL, 'c'}, +@@ -206,7 +232,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 * +-find_field (struct linebuffer const *line) ++find_field_uni (struct linebuffer *line) + { + size_t count; + char const *lp = line->buffer; +@@ -227,6 +253,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; \ + \ -+ if (BUFLEN < 1) \ -+ { \ -+ WC = WEOF; \ -+ break; \ -+ } \ -+ \ -+ /* Get a wide character. */ \ + CONVFAIL = 0; \ -+ state_bak = STATE; \ -+ MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ ++ state_bak = *STATEP; \ ++ \ ++ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ + \ + switch (MBLENGTH) \ + { \ -+ case (size_t)-1: \ + case (size_t)-2: \ ++ case (size_t)-1: \ ++ *STATEP = state_bak; \ + CONVFAIL++; \ -+ STATE = state_bak; \ -+ /* Fall througn. */ \ -+ \ ++ /* Fall through */ \ + case 0: \ + MBLENGTH = 1; \ -+ break; \ + } \ + } \ + while (0) + - struct range_pair - { - size_t lo; -@@ -85,7 +148,7 @@ - /* The number of bytes allocated for FIELD_1_BUFFER. */ - static size_t field_1_bufsize; - --/* The largest field or byte index used as an endpoint of a closed -+/* The largest byte, character or field index used as an endpoint of a closed - or degenerate range specification; this doesn't include the starting - index of right-open-ended ranges. For example, with either range spec - `2-5,9-', `2-3,5,9-' this variable would be set to 5. */ -@@ -97,10 +160,11 @@ - - /* This is a bit vector. - In byte mode, which bytes to output. -+ In character mode, which characters to output. - In field mode, which DELIM-separated fields to output. -- Both bytes and fields are numbered starting with 1, -+ Bytes, characters and fields are numbered starting with 1, - so the zeroth bit of this array is unused. -- A field or byte K has been selected if -+ A byte, character or field K has been selected if - (K <= MAX_RANGE_ENDPOINT and is_printable_field(K)) - || (EOL_RANGE_START > 0 && K >= EOL_RANGE_START). */ - static unsigned char *printable_field; -@@ -109,9 +173,12 @@ - { - 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, ++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; + - /* Output the given delimeter-separated fields. */ - field_mode - }; -@@ -121,6 +188,13 @@ - - static enum operating_mode operating_mode; - -+/* If nonzero, when in byte mode, don't split multibyte characters. */ -+static int byte_mode_character_aware; ++ pos = 0; ++ statep = &(line->state); + -+/* 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 delimeter characters. - Otherwise, all such lines are printed. This option is valid only - with field mode. */ -@@ -132,6 +206,9 @@ - - /* The delimeter character for field mode. */ - static unsigned char delim; -+#if HAVE_WCHAR_H -+static wchar_t wcdelim; -+#endif - - /* True if the --output-delimiter=STRING option was specified. */ - static bool output_delimiter_specified; -@@ -205,7 +282,7 @@ - -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\ -@@ -362,7 +439,7 @@ - in_digits = false; - /* Starting a range. */ - if (dash_found) -- FATAL_ERROR (_("invalid byte or field list")); -+ FATAL_ERROR (_("invalid byte, character or field list")); - dash_found = true; - fieldstr++; - -@@ -387,14 +464,16 @@ - if (!rhs_specified) - { - /* `n-'. From `initial' to end of line. */ -- eol_range_start = initial; -+ if (eol_range_start == 0 || -+ (eol_range_start != 0 && eol_range_start > initial)) -+ eol_range_start = initial; - field_found = true; - } - else - { - /* `m-n' or `-n' (1-n). */ - if (value < initial) -- FATAL_ERROR (_("invalid decreasing range")); -+ FATAL_ERROR (_("invalid byte, character or field list")); - - /* Is there already a range going to end of line? */ - if (eol_range_start != 0) -@@ -467,6 +546,9 @@ - if (operating_mode == byte_mode) - error (0, 0, - _("byte offset %s is too large"), quote (bad_num)); -+ else if (operating_mode == character_mode) -+ error (0, 0, -+ _("character offset %s is too large"), quote (bad_num)); - else - error (0, 0, - _("field number %s is too large"), quote (bad_num)); -@@ -477,7 +559,7 @@ - fieldstr++; - } - else -- FATAL_ERROR (_("invalid byte or field list")); -+ FATAL_ERROR (_("invalid byte, character or field list")); - } - - max_range_endpoint = 0; -@@ -570,6 +652,63 @@ - } - } - -+#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. */ ++ /* skip fields. */ ++ for (count = 0; count < skip_fields && pos < size; count++) ++ { ++ while (pos < size) ++ { ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); + -+static void -+cut_characters_or_cut_bytes_no_split (FILE *stream) -+{ -+ int 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. */ -+ int convfail; /* 1, when conversion is failed. Otherwise 0. */ -+ -+ idx = 0; -+ buflen = 0; -+ bufpos = buf; -+ memset (&state, '\0', sizeof(mbstate_t)); -+ -+ while (1) -+ { -+ REFILL_BUFFER (buf, bufpos, buflen, stream); -+ -+ GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); -+ -+ if (wc == WEOF) -+ { -+ if (idx > 0) -+ putchar ('\n'); -+ break; -+ } -+ else if (wc == L'\n') -+ { -+ putchar ('\n'); -+ idx = 0; -+ } -+ else -+ { -+ idx += (operating_mode == byte_mode) ? mblength : 1; -+ if (print_kth (idx, NULL)) -+ fwrite (bufpos, mblength, sizeof(char), stdout); -+ } -+ -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+} -+#endif -+ - /* Read from stream STREAM, printing to standard output any selected fields. */ - - static void -@@ -692,13 +831,192 @@ - } - } - -+#if HAVE_MBRTOWC -+static void -+cut_fields_mb (FILE *stream) -+{ -+ int c; -+ unsigned int 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. */ -+ int convfail; /* 1, when conversion is failed. Otherwise 0. */ -+ -+ 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); -+ 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, NULL)); -+ -+ while (1) -+ { -+ if (field_idx == 1 && buffer_first_field) -+ { -+ int len = 0; -+ -+ while (1) ++ if (convfail || !iswblank (wc)) + { -+ 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 == L'\n' || wc == wcdelim)) -+ break; ++ pos += mblength; ++ break; + } ++ pos += mblength; ++ } + -+ if (wc == WEOF) ++ while (pos < size) ++ { ++ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); ++ ++ if (!convfail && iswblank (wc)) + 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)) ++ 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. +@@ -235,6 +338,8 @@ find_field (struct linebuffer const *lin + static bool + different (char *old, char *new, size_t oldlen, size_t newlen) + { ++ char *copy_old, *copy_new; ++ + if (check_chars < oldlen) + oldlen = check_chars; + if (check_chars < newlen) +@@ -242,14 +347,92 @@ different (char *old, char *new, size_t + + if (ignore_case) + { +- /* FIXME: This should invoke strcoll somehow. */ +- return oldlen != newlen || memcasecmp (old, new, oldlen); ++ size_t i; ++ ++ copy_old = alloca (oldlen + 1); ++ copy_new = alloca (oldlen + 1); ++ ++ for (i = 0; i < oldlen; i++) ++ { ++ copy_old[i] = toupper (old[i]); ++ copy_new[i] = toupper (new[i]); ++ } + } +- else if (hard_LC_COLLATE) +- return xmemcoll (old, oldlen, new, newlen) != 0; + else +- return oldlen != newlen || memcmp (old, new, oldlen); ++ { ++ copy_old = (char *)old; ++ copy_new = (char *)new; ++ } ++ ++ return xmemcoll (copy_old, oldlen, copy_new, newlen); ++} ++ ++#if HAVE_MBRTOWC ++static int ++different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) ++{ ++ size_t i, j, chars; ++ const char *str[2]; ++ char *copy[2]; ++ size_t len[2]; ++ mbstate_t state[2]; ++ size_t mblength; ++ wchar_t wc, uwc; ++ mbstate_t state_bak; ++ ++ str[0] = old; ++ str[1] = new; ++ len[0] = oldlen; ++ len[1] = newlen; ++ state[0] = oldstate; ++ state[1] = newstate; ++ ++ for (i = 0; i < 2; i++) ++ { ++ copy[i] = alloca (len[i] + 1); ++ ++ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) ++ { ++ state_bak = state[i]; ++ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); ++ ++ switch (mblength) + { -+ if (suppress_non_delimited) ++ case (size_t)-1: ++ case (size_t)-2: ++ state[i] = state_bak; ++ /* Fall through */ ++ case 0: ++ mblength = 1; ++ break; ++ ++ default: ++ if (ignore_case) + { -+ /* Empty. */ ++ uwc = towupper (wc); ++ ++ if (uwc != wc) ++ { ++ mbstate_t state_wc; ++ ++ memset (&state_wc, '\0', sizeof(mbstate_t)); ++ wcrtomb (copy[i] + j, uwc, &state_wc); ++ } ++ else ++ memcpy (copy[i] + j, str[i] + j, mblength); + } + else -+ { -+ fwrite (field_1_buffer, sizeof (char), len, stdout); -+ /* Make sure the output line is newline terminated. */ -+ if (convfail || (!convfail && wc != L'\n')) -+ putchar ('\n'); -+ } -+ continue; ++ memcpy (copy[i] + j, str[i] + j, mblength); + } -+ -+ if (print_kth (1, NULL)) -+ { -+ /* Print the field, but not the trailing delimiter. */ -+ fwrite (field_1_buffer, sizeof (char), len - 1, stdout); -+ found_any_selected_field = 1; -+ } -+ ++field_idx; -+ } -+ -+ if (wc != WEOF) -+ { -+ if (print_kth (field_idx, NULL)) -+ { -+ 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 == L'\n')) -+ { -+ buflen -= mblength; -+ bufpos += mblength; -+ break; -+ } -+ -+ if (print_kth (field_idx, NULL)) -+ fwrite (bufpos, mblength, sizeof(char), stdout); -+ -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+ } -+ -+ if ((!convfail || wc == L'\n') && buflen < 1) -+ wc = WEOF; -+ -+ if (!convfail && wc == wcdelim) -+ ++field_idx; -+ else if (wc == WEOF || (!convfail && wc == L'\n')) -+ { -+ if (found_any_selected_field -+ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) -+ putchar ('\n'); -+ if (wc == WEOF) -+ break; -+ field_idx = 1; -+ found_any_selected_field = 0; ++ j += mblength; + } ++ copy[i][j] = '\0'; ++ len[i] = j; + } -+} -+#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: -+ cut_fields_mb (stream); -+ break; -+ -+ default: -+ abort (); -+ } -+ } - else -- cut_fields (stream); -+#endif -+ { -+ if (operating_mode == field_mode) -+ cut_fields (stream); -+ else -+ cut_bytes (stream); -+ } ++ return xmemcoll (copy[0], len[0], copy[1], len[1]); } - - /* Process file FILE to standard output. -@@ -748,6 +1066,8 @@ - bool ok; - bool delim_specified = false; - char *spec_list_string IF_LINT(= NULL); -+ char mbdelim[MB_LEN_MAX + 1]; -+ size_t delimlen = 0; - - initialize_main (&argc, &argv); - set_program_name (argv[0]); -@@ -770,7 +1090,6 @@ - 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")); -@@ -778,6 +1097,14 @@ - 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) -@@ -789,10 +1116,35 @@ - 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); -+ } -+ } -+ -+ 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: -@@ -805,6 +1157,7 @@ - break; - - case 'n': -+ byte_mode_character_aware = 1; - break; - - case 's': -@@ -827,7 +1180,7 @@ - if (operating_mode == undefined_mode) - FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); - -- if (delim != '\0' && operating_mode != field_mode) -+ if (delim_specified && operating_mode != field_mode) - FATAL_ERROR (_("an input delimiter may be specified only\ - when operating on fields")); - -@@ -854,15 +1207,34 @@ - } - - 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) + /* Output the line in linebuffer LINE to standard output + provided that the switches say it should be output. +@@ -303,15 +486,43 @@ check_file (const char *infile, const ch { -- 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; -+ } + char *prevfield IF_LINT (= NULL); + size_t prevlen IF_LINT (= 0); ++#if HAVE_MBRTOWC ++ mbstate_t prevstate; + -+ if (MB_CUR_MAX <= 1 || force_singlebyte_mode) ++ memset (&prevstate, '\0', sizeof (mbstate_t)); +#endif -+ { -+ static char dummy[2]; -+ dummy[0] = delim; -+ dummy[1] = '\0'; -+ output_delimiter_string = dummy; -+ output_delimiter_length = 1; -+ } - } - if (optind == argc) -diff -urNp coreutils-6.12/src/join.c coreutils-6.12-orig/src/join.c ---- coreutils-6.12/src/join.c 2008-07-16 14:08:01.000000000 +0200 -+++ coreutils-6.12-orig/src/join.c 2008-07-16 14:07:02.000000000 +0200 -@@ -634,6 +634,11 @@ get_line (FILE *fp, struct line *line, i - return false; - } + while (!feof (stdin)) + { + char *thisfield; + size_t thislen; ++#if HAVE_MBRTOWC ++ mbstate_t thisstate; ++#endif ++ + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) + break; + thisfield = find_field (thisline); + thislen = thisline->length - 1 - (thisfield - thisline->buffer); ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ thisstate = thisline->state; ++ ++ if (prevline->length == 0 || different_multi ++ (thisfield, prevfield, thislen, prevlen, thisstate, prevstate)) ++ { ++ fwrite (thisline->buffer, sizeof (char), ++ thisline->length, stdout); ++ ++ SWAP_LINES (prevline, thisline); ++ prevfield = thisfield; ++ prevlen = thislen; ++ prevstate = thisstate; ++ } ++ } ++ else ++#endif + if (prevline->length == 0 + || different (thisfield, prevfield, thislen, prevlen)) + { +@@ -330,17 +541,26 @@ check_file (const char *infile, const ch + size_t prevlen; + uintmax_t match_count = 0; + bool first_delimiter = true; ++#if HAVE_MBRTOWC ++ mbstate_t prevstate; ++#endif + + if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) + goto closefiles; + prevfield = find_field (prevline); + prevlen = prevline->length - 1 - (prevfield - prevline->buffer); ++#if HAVE_MBRTOWC ++ prevstate = prevline->state; ++#endif + + while (!feof (stdin)) + { + bool match; + char *thisfield; + size_t thislen; ++#if HAVE_MBRTOWC ++ mbstate_t thisstate; ++#endif + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) + { + if (ferror (stdin)) +@@ -349,6 +569,15 @@ check_file (const char *infile, const ch + } + thisfield = find_field (thisline); + thislen = thisline->length - 1 - (thisfield - thisline->buffer); ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ { ++ thisstate = thisline->state; ++ match = !different_multi (thisfield, prevfield, ++ thislen, prevlen, thisstate, prevstate); ++ } ++ else ++#endif + match = !different (thisfield, prevfield, thislen, prevlen); + match_count += match; + +@@ -381,6 +610,9 @@ check_file (const char *infile, const ch + SWAP_LINES (prevline, thisline); + prevfield = thisfield; + prevlen = thislen; ++#if HAVE_MBRTOWC ++ prevstate = thisstate; ++#endif + if (!match) + match_count = 0; + } +@@ -426,6 +658,19 @@ main (int argc, char **argv) + + atexit (close_stdout); +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) -+ xfields_multibyte (line); ++ { ++ find_field = find_field_multi; ++ } + else +#endif - xfields (line); ++ { ++ find_field = find_field_uni; ++ } ++ ++ ++ + skip_chars = 0; + skip_fields = 0; + check_chars = SIZE_MAX; +diff -urNp coreutils-8.0-orig/src/uniq.c.orig coreutils-8.0/src/uniq.c.orig +--- coreutils-8.0-orig/src/uniq.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/uniq.c.orig 2009-09-23 10:25:44.000000000 +0200 +@@ -0,0 +1,565 @@ ++/* uniq -- remove duplicate lines from a sorted file ++ Copyright (C) 86, 91, 1995-2009 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 Richard M. Stallman and David MacKenzie. */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#include "system.h" ++#include "argmatch.h" ++#include "linebuffer.h" ++#include "error.h" ++#include "hard-locale.h" ++#include "posixver.h" ++#include "quote.h" ++#include "xmemcoll.h" ++#include "xstrtol.h" ++#include "memcasecmp.h" ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "uniq" ++ ++#define AUTHORS \ ++ proper_name ("Richard M. Stallman"), \ ++ proper_name ("David MacKenzie") ++ ++#define SWAP_LINES(A, B) \ ++ do \ ++ { \ ++ struct linebuffer *_tmp; \ ++ _tmp = (A); \ ++ (A) = (B); \ ++ (B) = _tmp; \ ++ } \ ++ while (0) ++ ++/* True if the LC_COLLATE locale is hard. */ ++static bool hard_LC_COLLATE; ++ ++/* Number of fields to skip on each line when doing comparisons. */ ++static size_t skip_fields; ++ ++/* Number of chars to skip after skipping any fields. */ ++static size_t skip_chars; ++ ++/* Number of chars to compare. */ ++static size_t check_chars; ++ ++enum countmode ++{ ++ count_occurrences, /* -c Print count before output lines. */ ++ count_none /* Default. Do not print counts. */ ++}; ++ ++/* Whether and how to precede the output lines with a count of the number of ++ times they occurred in the input. */ ++static enum countmode countmode; ++ ++/* Which lines to output: unique lines, the first of a group of ++ repeated lines, and the second and subsequented of a group of ++ repeated lines. */ ++static bool output_unique; ++static bool output_first_repeated; ++static bool output_later_repeated; ++ ++/* If true, ignore case when comparing. */ ++static bool ignore_case; ++ ++enum delimit_method ++{ ++ /* No delimiters output. --all-repeated[=none] */ ++ DM_NONE, ++ ++ /* Delimiter precedes all groups. --all-repeated=prepend */ ++ DM_PREPEND, ++ ++ /* Delimit all groups. --all-repeated=separate */ ++ DM_SEPARATE ++}; ++ ++static char const *const delimit_method_string[] = ++{ ++ "none", "prepend", "separate", NULL ++}; ++ ++static enum delimit_method const delimit_method_map[] = ++{ ++ DM_NONE, DM_PREPEND, DM_SEPARATE ++}; ++ ++/* Select whether/how to delimit groups of duplicate lines. */ ++static enum delimit_method delimit_groups; ++ ++static struct option const longopts[] = ++{ ++ {"count", no_argument, NULL, 'c'}, ++ {"repeated", no_argument, NULL, 'd'}, ++ {"all-repeated", optional_argument, NULL, 'D'}, ++ {"ignore-case", no_argument, NULL, 'i'}, ++ {"unique", no_argument, NULL, 'u'}, ++ {"skip-fields", required_argument, NULL, 'f'}, ++ {"skip-chars", required_argument, NULL, 's'}, ++ {"check-chars", required_argument, NULL, 'w'}, ++ {"zero-terminated", no_argument, NULL, 'z'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... [INPUT [OUTPUT]]\n\ ++"), ++ program_name); ++ fputs (_("\ ++Filter adjacent matching lines from INPUT (or standard input),\n\ ++writing to OUTPUT (or standard output).\n\ ++\n\ ++With no options, matching lines are merged to the first occurrence.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ -c, --count prefix lines by the number of occurrences\n\ ++ -d, --repeated only print duplicate lines\n\ ++"), stdout); ++ fputs (_("\ ++ -D, --all-repeated[=delimit-method] print all duplicate lines\n\ ++ delimit-method={none(default),prepend,separate}\n\ ++ Delimiting is done with blank lines.\n\ ++ -f, --skip-fields=N avoid comparing the first N fields\n\ ++ -i, --ignore-case ignore differences in case when comparing\n\ ++ -s, --skip-chars=N avoid comparing the first N characters\n\ ++ -u, --unique only print unique lines\n\ ++ -z, --zero-terminated end lines with 0 byte, not newline\n\ ++"), stdout); ++ fputs (_("\ ++ -w, --check-chars=N compare no more than N characters in lines\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++A field is a run of blanks (usually spaces and/or TABs), then non-blank\n\ ++characters. Fields are skipped before chars.\n\ ++"), stdout); ++ fputs (_("\ ++\n\ ++Note: 'uniq' does not detect repeated lines unless they are adjacent.\n\ ++You may want to sort the input first, or use `sort -u' without `uniq'.\n\ ++Also, comparisons honor the rules specified by `LC_COLLATE'.\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++/* Convert OPT to size_t, reporting an error using MSGID if OPT is ++ invalid. Silently convert too-large values to SIZE_MAX. */ ++ ++static size_t ++size_opt (char const *opt, char const *msgid) ++{ ++ unsigned long int size; ++ verify (SIZE_MAX <= ULONG_MAX); ++ ++ switch (xstrtoul (opt, NULL, 10, &size, "")) ++ { ++ case LONGINT_OK: ++ case LONGINT_OVERFLOW: ++ break; ++ ++ default: ++ error (EXIT_FAILURE, 0, "%s: %s", opt, _(msgid)); ++ } ++ ++ return MIN (size, SIZE_MAX); ++} ++ ++/* Given a linebuffer LINE, ++ return a pointer to the beginning of the line's field to be compared. */ ++ ++static char * ++find_field (struct linebuffer const *line) ++{ ++ size_t count; ++ char const *lp = line->buffer; ++ size_t size = line->length - 1; ++ size_t i = 0; ++ ++ for (count = 0; count < skip_fields; count++) ++ { ++ while (i < size && isblank (to_uchar (lp[i]))) ++ i++; ++ while (i < size && !isblank (to_uchar (lp[i]))) ++ i++; ++ } ++ ++ for (count = 0; count < skip_chars && i < size; count++) ++ i++; ++ ++ return line->buffer + i; ++} ++ ++/* 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. ++ OLDLEN and NEWLEN are their lengths. */ ++ ++static bool ++different (char *old, char *new, size_t oldlen, size_t newlen) ++{ ++ if (check_chars < oldlen) ++ oldlen = check_chars; ++ if (check_chars < newlen) ++ newlen = check_chars; ++ ++ if (ignore_case) ++ { ++ /* FIXME: This should invoke strcoll somehow. */ ++ return oldlen != newlen || memcasecmp (old, new, oldlen); ++ } ++ else if (hard_LC_COLLATE) ++ return xmemcoll (old, oldlen, new, newlen) != 0; ++ else ++ return oldlen != newlen || memcmp (old, new, oldlen); ++} ++ ++/* Output the line in linebuffer LINE to standard output ++ provided that the switches say it should be output. ++ MATCH is true if the line matches the previous line. ++ If requested, print the number of times it occurred, as well; ++ LINECOUNT + 1 is the number of times that the line occurred. */ ++ ++static void ++writeline (struct linebuffer const *line, ++ bool match, uintmax_t linecount) ++{ ++ if (! (linecount == 0 ? output_unique ++ : !match ? output_first_repeated ++ : output_later_repeated)) ++ return; ++ ++ if (countmode == count_occurrences) ++ printf ("%7" PRIuMAX " ", linecount + 1); ++ ++ fwrite (line->buffer, sizeof (char), line->length, stdout); ++} ++ ++/* Process input file INFILE with output to OUTFILE. ++ If either is "-", use the standard I/O stream for it instead. */ ++ ++static void ++check_file (const char *infile, const char *outfile, char delimiter) ++{ ++ struct linebuffer lb1, lb2; ++ struct linebuffer *thisline, *prevline; ++ ++ if (! (STREQ (infile, "-") || freopen (infile, "r", stdin))) ++ error (EXIT_FAILURE, errno, "%s", infile); ++ if (! (STREQ (outfile, "-") || freopen (outfile, "w", stdout))) ++ error (EXIT_FAILURE, errno, "%s", outfile); ++ ++ thisline = &lb1; ++ prevline = &lb2; ++ ++ initbuffer (thisline); ++ initbuffer (prevline); ++ ++ /* The duplication in the following `if' and `else' blocks is an ++ optimization to distinguish the common case (in which none of ++ the following options has been specified: --count, -repeated, ++ --all-repeated, --unique) from the others. In the common case, ++ this optimization lets uniq output each different line right away, ++ without waiting to see if the next one is different. */ ++ ++ if (output_unique && output_first_repeated && countmode == count_none) ++ { ++ char *prevfield IF_LINT (= NULL); ++ size_t prevlen IF_LINT (= 0); ++ ++ while (!feof (stdin)) ++ { ++ char *thisfield; ++ size_t thislen; ++ if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) ++ break; ++ thisfield = find_field (thisline); ++ thislen = thisline->length - 1 - (thisfield - thisline->buffer); ++ if (prevline->length == 0 ++ || different (thisfield, prevfield, thislen, prevlen)) ++ { ++ fwrite (thisline->buffer, sizeof (char), ++ thisline->length, stdout); ++ ++ SWAP_LINES (prevline, thisline); ++ prevfield = thisfield; ++ prevlen = thislen; ++ } ++ } ++ } ++ else ++ { ++ char *prevfield; ++ size_t prevlen; ++ uintmax_t match_count = 0; ++ bool first_delimiter = true; ++ ++ if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) ++ goto closefiles; ++ prevfield = find_field (prevline); ++ prevlen = prevline->length - 1 - (prevfield - prevline->buffer); ++ ++ while (!feof (stdin)) ++ { ++ bool match; ++ char *thisfield; ++ size_t thislen; ++ if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) ++ { ++ if (ferror (stdin)) ++ goto closefiles; ++ break; ++ } ++ thisfield = find_field (thisline); ++ thislen = thisline->length - 1 - (thisfield - thisline->buffer); ++ match = !different (thisfield, prevfield, thislen, prevlen); ++ match_count += match; ++ ++ if (match_count == UINTMAX_MAX) ++ { ++ if (count_occurrences) ++ error (EXIT_FAILURE, 0, _("too many repeated lines")); ++ match_count--; ++ } ++ ++ if (delimit_groups != DM_NONE) ++ { ++ if (!match) ++ { ++ if (match_count) /* a previous match */ ++ first_delimiter = false; /* Only used when DM_SEPARATE */ ++ } ++ else if (match_count == 1) ++ { ++ if ((delimit_groups == DM_PREPEND) ++ || (delimit_groups == DM_SEPARATE ++ && !first_delimiter)) ++ putchar (delimiter); ++ } ++ } ++ ++ if (!match || output_later_repeated) ++ { ++ writeline (prevline, match, match_count); ++ SWAP_LINES (prevline, thisline); ++ prevfield = thisfield; ++ prevlen = thislen; ++ if (!match) ++ match_count = 0; ++ } ++ } ++ ++ writeline (prevline, false, match_count); ++ } ++ ++ closefiles: ++ if (ferror (stdin) || fclose (stdin) != 0) ++ error (EXIT_FAILURE, 0, _("error reading %s"), infile); ++ ++ /* stdout is handled via the atexit-invoked close_stdout function. */ ++ ++ free (lb1.buffer); ++ free (lb2.buffer); ++} ++ ++enum Skip_field_option_type ++ { ++ SFO_NONE, ++ SFO_OBSOLETE, ++ SFO_NEW ++ }; ++ ++int ++main (int argc, char **argv) ++{ ++ int optc = 0; ++ bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL); ++ enum Skip_field_option_type skip_field_option_type = SFO_NONE; ++ int nfiles = 0; ++ char const *file[2]; ++ char delimiter = '\n'; /* change with --zero-terminated, -z */ ++ ++ file[0] = file[1] = "-"; ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ hard_LC_COLLATE = hard_locale (LC_COLLATE); ++ ++ atexit (close_stdout); ++ ++ skip_chars = 0; ++ skip_fields = 0; ++ check_chars = SIZE_MAX; ++ output_unique = output_first_repeated = true; ++ output_later_repeated = false; ++ countmode = count_none; ++ delimit_groups = DM_NONE; ++ ++ for (;;) ++ { ++ /* Parse an operand with leading "+" as a file after "--" was ++ seen; or if pedantic and a file was seen; or if not ++ obsolete. */ ++ ++ if (optc == -1 ++ || (posixly_correct && nfiles != 0) ++ || ((optc = getopt_long (argc, argv, ++ "-0123456789Dcdf:is:uw:z", longopts, NULL)) ++ == -1)) ++ { ++ if (argc <= optind) ++ break; ++ if (nfiles == 2) ++ { ++ error (0, 0, _("extra operand %s"), quote (argv[optind])); ++ usage (EXIT_FAILURE); ++ } ++ file[nfiles++] = argv[optind++]; ++ } ++ else switch (optc) ++ { ++ case 1: ++ { ++ unsigned long int size; ++ if (optarg[0] == '+' ++ && posix2_version () < 200112 ++ && xstrtoul (optarg, NULL, 10, &size, "") == LONGINT_OK ++ && size <= SIZE_MAX) ++ skip_chars = size; ++ else if (nfiles == 2) ++ { ++ error (0, 0, _("extra operand %s"), quote (optarg)); ++ usage (EXIT_FAILURE); ++ } ++ else ++ file[nfiles++] = optarg; ++ } ++ break; ++ ++ case '0': ++ case '1': ++ case '2': ++ case '3': ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ case '8': ++ case '9': ++ { ++ if (skip_field_option_type == SFO_NEW) ++ skip_fields = 0; ++ ++ if (!DECIMAL_DIGIT_ACCUMULATE (skip_fields, optc - '0', size_t)) ++ skip_fields = SIZE_MAX; ++ ++ skip_field_option_type = SFO_OBSOLETE; ++ } ++ break; ++ ++ case 'c': ++ countmode = count_occurrences; ++ break; ++ ++ case 'd': ++ output_unique = false; ++ break; ++ ++ case 'D': ++ output_unique = false; ++ output_later_repeated = true; ++ if (optarg == NULL) ++ delimit_groups = DM_NONE; ++ else ++ delimit_groups = XARGMATCH ("--all-repeated", optarg, ++ delimit_method_string, ++ delimit_method_map); ++ break; ++ ++ case 'f': ++ skip_field_option_type = SFO_NEW; ++ skip_fields = size_opt (optarg, ++ N_("invalid number of fields to skip")); ++ break; ++ ++ case 'i': ++ ignore_case = true; ++ break; ++ ++ case 's': ++ skip_chars = size_opt (optarg, ++ N_("invalid number of bytes to skip")); ++ break; ++ ++ case 'u': ++ output_first_repeated = false; ++ break; ++ ++ case 'w': ++ check_chars = size_opt (optarg, ++ N_("invalid number of bytes to compare")); ++ break; ++ ++ case 'z': ++ delimiter = '\0'; ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (EXIT_FAILURE); ++ } ++ } ++ ++ if (countmode == count_occurrences && output_later_repeated) ++ { ++ error (0, 0, ++ _("printing all duplicated lines and repeat counts is meaningless")); ++ usage (EXIT_FAILURE); ++ } ++ ++ check_file (file[0], file[1], delimiter); ++ ++ exit (EXIT_SUCCESS); ++} +diff -urNp coreutils-8.0-orig/tests/Makefile.am coreutils-8.0/tests/Makefile.am +--- coreutils-8.0-orig/tests/Makefile.am 2009-09-29 16:25:44.000000000 +0200 ++++ coreutils-8.0/tests/Makefile.am 2009-10-07 10:07:16.000000000 +0200 +@@ -208,6 +208,7 @@ TESTS = \ + misc/sort-compress \ + misc/sort-continue \ + misc/sort-files0-from \ ++ misc/sort-mb-tests \ + misc/sort-merge \ + misc/sort-merge-fdlimit \ + misc/sort-rand \ +@@ -452,6 +453,10 @@ TESTS = \ + $(root_tests) - if (prevline[which - 1]) + pr_data = \ ++ misc/mb1.X \ ++ misc/mb1.I \ ++ misc/mb2.X \ ++ misc/mb2.I \ + pr/0F \ + pr/0FF \ + pr/0FFnt \ +diff -urNp coreutils-8.0-orig/tests/Makefile.am.orig coreutils-8.0/tests/Makefile.am.orig +--- coreutils-8.0-orig/tests/Makefile.am.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/Makefile.am.orig 2009-09-29 16:25:44.000000000 +0200 +@@ -0,0 +1,616 @@ ++## Process this file with automake to produce Makefile.in -*-Makefile-*-. ++ ++# Sort in traditional ASCII order, regardless of the current locale; ++# otherwise we may get into trouble with distinct strings that the ++# current locale considers to be equal. ++ASSORT = LC_ALL=C sort ++ ++EXTRA_DIST = \ ++ Coreutils.pm \ ++ CuTmpdir.pm \ ++ README \ ++ check.mk \ ++ envvar-check \ ++ lang-default \ ++ other-fs-tmpdir \ ++ require-perl \ ++ sample-test \ ++ test-lib.sh \ ++ $(pr_data) ++ ++root_tests = \ ++ chown/basic \ ++ cp/cp-a-selinux \ ++ cp/preserve-gid \ ++ cp/special-bits \ ++ cp/cp-mv-enotsup-xattr \ ++ chroot/credentials \ ++ dd/skip-seek-past-dev \ ++ install/install-C-root \ ++ ls/capability \ ++ ls/nameless-uid \ ++ misc/chcon \ ++ misc/selinux \ ++ misc/truncate-owned-by-other \ ++ mkdir/writable-under-readonly \ ++ mv/sticky-to-xpart \ ++ rm/fail-2eperm \ ++ rm/no-give-up \ ++ rm/one-file-system \ ++ tail-2/append-only \ ++ touch/now-owned-by-other ++ ++.PHONY: check-root ++check-root: ++ $(MAKE) check TESTS='$(root_tests)' ++ ++check-recursive: root-hint ++ ++# Advertise `check-root' target. ++.PHONY: root-hint ++root-hint: ++ @echo '***********************************************************' ++ @echo "NOTICE: Some tests may be run only as root." ++ @echo " See the 'Running tests as root' section in README." ++ @echo '***********************************************************' ++ ++EXTRA_DIST += $(TESTS) ++ ++# Do not choose a name that is a shell keyword like 'if', or a ++# commonly-used utility like 'cat' or 'test', as the name of a test. ++# Otherwise, VPATH builds will fail on hosts like Solaris, since they ++# will expand 'if test ...' to 'if .../test ...', and the '.../test' ++# will execute the test script rather than the standard utility. ++ ++# Notes on the ordering of these tests: ++# Place early in the list tests of the tools that ++# are most commonly used in test scripts themselves. ++# E.g., nearly every test script uses rm and chmod. ++# help-version comes early because it's a basic sanity test. ++# Put seq early, since lots of other tests use it. ++# Put tests that sleep early, but not all together, so in parallel builds ++# they share time with tests that burn CPU, not with others that sleep. ++# Put head-elide-tail early, because it's long-running. ++ ++TESTS = \ ++ misc/help-version \ ++ misc/invalid-opt \ ++ rm/ext3-perf \ ++ rm/cycle \ ++ cp/link-heap \ ++ chmod/no-x \ ++ chgrp/basic \ ++ rm/dangling-symlink \ ++ misc/ls-time \ ++ rm/deep-1 \ ++ rm/deep-2 \ ++ rm/dir-no-w \ ++ rm/dir-nonrecur \ ++ rm/dot-rel \ ++ rm/isatty \ ++ rm/empty-inacc \ ++ rm/empty-name \ ++ rm/f-1 \ ++ rm/fail-eacces \ ++ rm/fail-eperm \ ++ tail-2/assert \ ++ rm/hash \ ++ rm/i-1 \ ++ rm/i-never \ ++ rm/i-no-r \ ++ tail-2/infloop-1 \ ++ rm/ignorable \ ++ rm/inaccessible \ ++ rm/interactive-always \ ++ rm/interactive-once \ ++ rm/ir-1 \ ++ rm/r-1 \ ++ rm/r-2 \ ++ rm/r-3 \ ++ rm/r-4 \ ++ rm/readdir-bug \ ++ rm/rm1 \ ++ touch/empty-file \ ++ rm/rm2 \ ++ rm/rm3 \ ++ rm/rm4 \ ++ rm/rm5 \ ++ rm/sunos-1 \ ++ rm/unread2 \ ++ rm/unread3 \ ++ rm/unreadable \ ++ rm/v-slash \ ++ chgrp/default-no-deref \ ++ chgrp/deref \ ++ chgrp/no-x \ ++ chgrp/posix-H \ ++ chgrp/recurse \ ++ misc/ptx \ ++ misc/test \ ++ misc/seq \ ++ misc/seq-long-double \ ++ misc/head \ ++ misc/head-elide-tail \ ++ tail-2/tail-n0f \ ++ misc/ls-misc \ ++ misc/date \ ++ misc/date-next-dow \ ++ misc/ptx-overrun \ ++ misc/xstrtol \ ++ tail-2/pid \ ++ misc/od \ ++ misc/mktemp \ ++ misc/arch \ ++ misc/pr \ ++ misc/join \ ++ pr/pr-tests \ ++ misc/df-P \ ++ misc/pwd-option \ ++ misc/pwd-unreadable-parent \ ++ misc/chcon-fail \ ++ misc/cut \ ++ misc/wc \ ++ misc/wc-files0-from \ ++ misc/wc-files0 \ ++ misc/cat-proc \ ++ misc/cat-buf \ ++ misc/base64 \ ++ misc/basename \ ++ misc/close-stdout \ ++ misc/comm \ ++ misc/csplit \ ++ misc/date-sec \ ++ misc/dircolors \ ++ misc/df \ ++ misc/dirname \ ++ misc/expand \ ++ misc/expr \ ++ misc/factor \ ++ misc/false-status \ ++ misc/fmt \ ++ misc/fmt-long-line \ ++ misc/fold \ ++ misc/groups-dash \ ++ misc/groups-version \ ++ misc/head-c \ ++ misc/head-pos \ ++ misc/id-context \ ++ misc/id-groups \ ++ misc/md5sum \ ++ misc/md5sum-newline \ ++ misc/mknod \ ++ misc/nice \ ++ misc/nl \ ++ misc/nohup \ ++ misc/od-N \ ++ misc/od-multiple-t \ ++ misc/od-x8 \ ++ misc/paste \ ++ misc/pathchk1 \ ++ misc/printf \ ++ misc/printf-cov \ ++ misc/printf-hex \ ++ misc/printf-surprise \ ++ misc/pwd-long \ ++ misc/readlink-fp-loop \ ++ misc/runcon-no-reorder \ ++ misc/sha1sum \ ++ misc/sha1sum-vec \ ++ misc/sha224sum \ ++ misc/sha256sum \ ++ misc/sha384sum \ ++ misc/sha512sum \ ++ misc/shred-exact \ ++ misc/shred-passes \ ++ misc/shred-remove \ ++ misc/shuf \ ++ misc/sort \ ++ misc/sort-compress \ ++ misc/sort-continue \ ++ misc/sort-files0-from \ ++ misc/sort-merge \ ++ misc/sort-merge-fdlimit \ ++ misc/sort-rand \ ++ misc/sort-version \ ++ misc/split-a \ ++ misc/split-fail \ ++ misc/split-l \ ++ misc/stat-fmt \ ++ misc/stat-hyphen \ ++ misc/stat-printf \ ++ misc/stdbuf \ ++ misc/stty \ ++ misc/stty-invalid \ ++ misc/stty-row-col \ ++ misc/sum \ ++ misc/sum-sysv \ ++ misc/tac \ ++ misc/tac-continue \ ++ misc/tail \ ++ misc/tee \ ++ misc/tee-dash \ ++ misc/test-diag \ ++ misc/timeout \ ++ misc/timeout-parameters \ ++ misc/tr \ ++ misc/truncate-dangling-symlink \ ++ misc/truncate-dir-fail \ ++ misc/truncate-fail-diag \ ++ misc/truncate-fifo \ ++ misc/truncate-no-create-missing \ ++ misc/truncate-overflow \ ++ misc/truncate-parameters \ ++ misc/truncate-relative \ ++ misc/tsort \ ++ misc/tty-eof \ ++ misc/unexpand \ ++ misc/uniq \ ++ misc/xattr \ ++ tail-2/wait \ ++ chmod/c-option \ ++ chmod/equal-x \ ++ chmod/equals \ ++ chmod/inaccessible \ ++ chmod/octal \ ++ chmod/setgid \ ++ chmod/silent \ ++ chmod/thru-dangling \ ++ chmod/umask-x \ ++ chmod/usage \ ++ chown/deref \ ++ chown/preserve-root \ ++ chown/separator \ ++ cp/abuse \ ++ cp/acl \ ++ cp/backup-1 \ ++ cp/backup-dir \ ++ cp/backup-is-src \ ++ cp/cp-HL \ ++ cp/cp-deref \ ++ cp/cp-i \ ++ cp/cp-mv-backup \ ++ cp/cp-parents \ ++ cp/deref-slink \ ++ cp/dir-rm-dest \ ++ cp/dir-slash \ ++ cp/dir-vs-file \ ++ cp/existing-perm-race \ ++ cp/fail-perm \ ++ cp/file-perm-race \ ++ cp/into-self \ ++ cp/link \ ++ cp/link-no-deref \ ++ cp/link-preserve \ ++ cp/no-deref-link1 \ ++ cp/no-deref-link2 \ ++ cp/no-deref-link3 \ ++ cp/parent-perm \ ++ cp/parent-perm-race \ ++ cp/perm \ ++ cp/preserve-2 \ ++ cp/preserve-slink-time \ ++ cp/proc-short-read \ ++ cp/proc-zero-len \ ++ cp/r-vs-symlink \ ++ cp/reflink-auto \ ++ cp/reflink-perm \ ++ cp/same-file \ ++ cp/slink-2-slink \ ++ cp/sparse \ ++ cp/special-f \ ++ cp/src-base-dot \ ++ cp/symlink-slash \ ++ cp/thru-dangling \ ++ df/unreadable \ ++ dd/direct \ ++ dd/misc \ ++ dd/not-rewound \ ++ dd/reblock \ ++ dd/skip-seek \ ++ dd/skip-seek2 \ ++ dd/skip-seek-past-file \ ++ dd/stderr \ ++ dd/unblock \ ++ dd/unblock-sync \ ++ df/total-verify \ ++ du/2g \ ++ du/8gb \ ++ du/basic \ ++ du/deref \ ++ du/deref-args \ ++ du/exclude \ ++ du/fd-leak \ ++ du/files0-from \ ++ du/hard-link \ ++ du/inacc-dest \ ++ du/inacc-dir \ ++ du/inaccessible-cwd \ ++ du/long-from-unreadable \ ++ du/long-sloop \ ++ du/no-deref \ ++ du/no-x \ ++ du/one-file-system \ ++ du/restore-wd \ ++ du/slash \ ++ du/slink \ ++ du/trailing-slash \ ++ du/two-args \ ++ id/no-context \ ++ install/basic-1 \ ++ install/create-leading \ ++ install/d-slashdot \ ++ install/install-C \ ++ install/install-C-selinux \ ++ install/strip-program \ ++ install/trap \ ++ ln/backup-1 \ ++ ln/hard-backup \ ++ ln/hard-to-sym \ ++ ln/misc \ ++ ln/sf-1 \ ++ ln/slash-decorated-nonexistent-dest \ ++ ln/target-1 \ ++ ls/abmon-align \ ++ ls/color-clear-to-eol \ ++ ls/color-dtype-dir \ ++ ls/dangle \ ++ ls/dired \ ++ ls/file-type \ ++ ls/follow-slink \ ++ ls/infloop \ ++ ls/inode \ ++ ls/m-option \ ++ ls/multihardlink \ ++ ls/no-arg \ ++ ls/no-cap \ ++ ls/proc-selinux-segfault \ ++ ls/readdir-mountpoint-inode \ ++ ls/recursive \ ++ ls/rt-1 \ ++ ls/stat-dtype \ ++ ls/stat-failed \ ++ ls/stat-free-symlinks \ ++ ls/stat-vs-dirent \ ++ ls/symlink-slash \ ++ ls/x-option \ ++ mkdir/p-1 \ ++ mkdir/p-2 \ ++ mkdir/p-3 \ ++ mkdir/p-slashdot \ ++ mkdir/p-thru-slink \ ++ mkdir/p-v \ ++ mkdir/parents \ ++ mkdir/perm \ ++ mkdir/selinux \ ++ mkdir/special-1 \ ++ mkdir/t-slash \ ++ mv/acl \ ++ mv/atomic \ ++ mv/atomic2 \ ++ mv/backup-dir \ ++ mv/backup-is-src \ ++ mv/childproof \ ++ mv/diag \ ++ mv/dir-file \ ++ mv/dir2dir \ ++ mv/dup-source \ ++ mv/force \ ++ mv/hard-2 \ ++ mv/hard-3 \ ++ mv/hard-4 \ ++ mv/hard-link-1 \ ++ mv/hard-verbose \ ++ mv/i-1 \ ++ mv/i-2 \ ++ mv/i-3 \ ++ mv/i-4 \ ++ mv/i-5 \ ++ mv/i-link-no \ ++ mv/into-self \ ++ mv/into-self-2 \ ++ mv/into-self-3 \ ++ mv/into-self-4 \ ++ mv/leak-fd \ ++ mv/mv-n \ ++ mv/mv-special-1 \ ++ mv/no-target-dir \ ++ mv/part-fail \ ++ mv/part-hardlink \ ++ mv/part-rename \ ++ mv/part-symlink \ ++ mv/partition-perm \ ++ mv/perm-1 \ ++ mv/to-symlink \ ++ mv/trailing-slash \ ++ mv/update \ ++ readlink/can-e \ ++ readlink/can-f \ ++ readlink/can-m \ ++ readlink/rl-1 \ ++ rmdir/fail-perm \ ++ rmdir/ignore \ ++ rmdir/t-slash \ ++ tail-2/assert-2 \ ++ tail-2/big-4gb \ ++ tail-2/flush-initial \ ++ tail-2/follow-stdin \ ++ tail-2/pipe-f \ ++ tail-2/pipe-f2 \ ++ tail-2/proc-ksyms \ ++ tail-2/start-middle \ ++ touch/60-seconds \ ++ touch/dangling-symlink \ ++ touch/dir-1 \ ++ touch/fail-diag \ ++ touch/fifo \ ++ touch/no-create-missing \ ++ touch/no-rights \ ++ touch/not-owner \ ++ touch/obsolescent \ ++ touch/read-only \ ++ touch/relative \ ++ $(root_tests) ++ ++pr_data = \ ++ pr/0F \ ++ pr/0FF \ ++ pr/0FFnt \ ++ pr/0FFt \ ++ pr/0FnFnt \ ++ pr/0FnFt \ ++ pr/0Fnt \ ++ pr/0Ft \ ++ pr/2-S_f-t_notab \ ++ pr/2-Sf-t_notab \ ++ pr/2f-t_notab \ ++ pr/2s_f-t_notab \ ++ pr/2s_w60f-t_nota \ ++ pr/2sf-t_notab \ ++ pr/2sw60f-t_notab \ ++ pr/2w60f-t_notab \ ++ pr/3-0F \ ++ pr/3-5l24f-t \ ++ pr/3-FF \ ++ pr/3a2l17-FF \ ++ pr/3a3f-0F \ ++ pr/3a3l15-t \ ++ pr/3a3l15f-t \ ++ pr/3b2l17-FF \ ++ pr/3b3f-0F \ ++ pr/3b3f-0FF \ ++ pr/3b3f-FF \ ++ pr/3b3l15-t \ ++ pr/3b3l15f-t \ ++ pr/3f-0F \ ++ pr/3f-FF \ ++ pr/3l24-t \ ++ pr/3l24f-t \ ++ pr/3ml24-FF \ ++ pr/3ml24-t \ ++ pr/3ml24-t-FF \ ++ pr/3ml24f-t \ ++ pr/4-7l24-FF \ ++ pr/4l24-FF \ ++ pr/FF \ ++ pr/FFn \ ++ pr/FFtn \ ++ pr/FnFn \ ++ pr/Ja3l24f-lm \ ++ pr/Jb3l24f-lm \ ++ pr/Jml24f-lm-lo \ ++ pr/W-72l24f-ll \ ++ pr/W20l24f-ll \ ++ pr/W26l24f-ll \ ++ pr/W27l24f-ll \ ++ pr/W28l24f-ll \ ++ pr/W35Ja3l24f-lm \ ++ pr/W35Jb3l24f-lm \ ++ pr/W35Jml24f-lmlo \ ++ pr/W35a3l24f-lm \ ++ pr/W35b3l24f-lm \ ++ pr/W35ml24f-lm-lo \ ++ pr/W72Jl24f-ll \ ++ pr/a2l15-FF \ ++ pr/a2l17-FF \ ++ pr/a3-0F \ ++ pr/a3f-0F \ ++ pr/a3f-0FF \ ++ pr/a3f-FF \ ++ pr/a3l15-t \ ++ pr/a3l15f-t \ ++ pr/a3l24f-lm \ ++ pr/b2l15-FF \ ++ pr/b2l17-FF \ ++ pr/b3-0F \ ++ pr/b3f-0F \ ++ pr/b3f-0FF \ ++ pr/b3f-FF \ ++ pr/b3l15-t \ ++ pr/b3l15f-t \ ++ pr/b3l24f-lm \ ++ pr/l24-FF \ ++ pr/l24-t \ ++ pr/l24f-t \ ++ pr/loli \ ++ pr/ml20-FF-t \ ++ pr/ml24-FF \ ++ pr/ml24-t \ ++ pr/ml24-t-FF \ ++ pr/ml24f-0F \ ++ pr/ml24f-lm-lo \ ++ pr/ml24f-t \ ++ pr/ml24f-t-0F \ ++ pr/n+2-5l24f-0FF \ ++ pr/n+2l24f-0FF \ ++ pr/n+2l24f-bl \ ++ pr/n+3-7l24-FF \ ++ pr/n+3l24f-0FF \ ++ pr/n+3l24f-bl \ ++ pr/n+3ml20f-bl-FF \ ++ pr/n+3ml24f-bl-tn \ ++ pr/n+3ml24f-tn-bl \ ++ pr/n+4-8a2l17-FF \ ++ pr/n+4b2l17f-0FF \ ++ pr/n+5-8b3l17f-FF \ ++ pr/n+5a3l13f-0FF \ ++ pr/n+6a2l17-FF \ ++ pr/n+6b3l13f-FF \ ++ pr/n+7l24-FF \ ++ pr/n+8l20-FF \ ++ pr/nJml24f-lmlmlo \ ++ pr/nJml24f-lmlolm \ ++ pr/nN1+3l24f-bl \ ++ pr/nN15l24f-bl \ ++ pr/nSml20-bl-FF \ ++ pr/nSml20-t-t-FF \ ++ pr/nSml20-t-tFFFF \ ++ pr/nSml24-bl-FF \ ++ pr/nSml24-t-t-FF \ ++ pr/nSml24-t-tFFFF \ ++ pr/nl24f-bl \ ++ pr/o3Jml24f-lm-lo \ ++ pr/o3a3Sl24f-tn \ ++ pr/o3a3Snl24f-tn \ ++ pr/o3a3l24f-tn \ ++ pr/o3b3Sl24f-tn \ ++ pr/o3b3Snl24f-tn \ ++ pr/o3b3l24f-tn \ ++ pr/o3mSl24f-bl-tn \ ++ pr/o3mSnl24fbltn \ ++ pr/o3ml24f-bl-tn \ ++ pr/t-0FF \ ++ pr/t-FF \ ++ pr/t-bl \ ++ pr/t-t \ ++ pr/tFFn \ ++ pr/tFFt \ ++ pr/tFFt-bl \ ++ pr/tFFt-ll \ ++ pr/tFFt-lm \ ++ pr/tFnFt \ ++ pr/t_notab \ ++ pr/t_tab \ ++ pr/t_tab_ \ ++ pr/ta3-0FF \ ++ pr/ta3-FF \ ++ pr/tb3-0FF \ ++ pr/tb3-FF \ ++ pr/tn \ ++ pr/tn2e5o3-t_tab \ ++ pr/tn2e8-t_tab \ ++ pr/tn2e8o3-t_tab \ ++ pr/tn_2e8-t_tab \ ++ pr/tn_2e8S-t_tab \ ++ pr/tne8-t_tab \ ++ pr/tne8o3-t_tab \ ++ pr/tt-0FF \ ++ pr/tt-FF \ ++ pr/tt-bl \ ++ pr/tt-t \ ++ pr/tta3-0FF \ ++ pr/tta3-FF \ ++ pr/ttb3-0FF \ ++ pr/ttb3-FF \ ++ pr/w72l24f-ll ++ ++include $(srcdir)/check.mk +diff -urNp coreutils-8.0-orig/tests/misc/cut coreutils-8.0/tests/misc/cut +--- coreutils-8.0-orig/tests/misc/cut 2009-09-21 14:29:33.000000000 +0200 ++++ coreutils-8.0/tests/misc/cut 2009-10-07 10:07:16.000000000 +0200 +@@ -26,7 +26,7 @@ use strict; + my $prog = 'cut'; + my $try = "Try \`$prog --help' for more information.\n"; + my $from_1 = "$prog: fields and positions are numbered from 1\n$try"; +-my $inval = "$prog: invalid byte or field list\n$try"; ++my $inval = "$prog: invalid byte, character or field list\n$try"; + my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; + + my @Tests = +@@ -141,7 +141,7 @@ my @Tests = + + # None of the following invalid ranges provoked an error up to coreutils-6.9. + ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, +- {ERR=>"$prog: invalid decreasing range\n$try"}], ++ {ERR=>"$prog: invalid byte, character or field list\n$try"}], + ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], + ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], + ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], +diff -urNp coreutils-8.0-orig/tests/misc/mb1.I coreutils-8.0/tests/misc/mb1.I +--- coreutils-8.0-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/mb1.I 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,4 @@ ++Apple@10 ++Banana@5 ++Citrus@20 ++Cherry@30 +diff -urNp coreutils-8.0-orig/tests/misc/mb1.X coreutils-8.0/tests/misc/mb1.X +--- coreutils-8.0-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/mb1.X 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,4 @@ ++Banana@5 ++Apple@10 ++Citrus@20 ++Cherry@30 +diff -urNp coreutils-8.0-orig/tests/misc/mb2.I coreutils-8.0/tests/misc/mb2.I +--- coreutils-8.0-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/mb2.I 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,4 @@ ++Apple@AA10@@20 ++Banana@AA5@@30 ++Citrus@AA20@@5 ++Cherry@AA30@@10 +diff -urNp coreutils-8.0-orig/tests/misc/mb2.X coreutils-8.0/tests/misc/mb2.X +--- coreutils-8.0-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/mb2.X 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,4 @@ ++Citrus@AA20@@5 ++Cherry@AA30@@10 ++Apple@AA10@@20 ++Banana@AA5@@30 +diff -urNp coreutils-8.0-orig/tests/misc/sort-mb-tests coreutils-8.0/tests/misc/sort-mb-tests +--- coreutils-8.0-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/tests/misc/sort-mb-tests 2009-10-07 10:07:16.000000000 +0200 +@@ -0,0 +1,58 @@ ++#! /bin/sh ++case $# in ++ 0) xx='../src/sort';; ++ *) xx="$1";; ++esac ++test "$VERBOSE" && echo=echo || echo=: ++$echo testing program: $xx ++errors=0 ++test "$srcdir" || srcdir=. ++test "$VERBOSE" && $xx --version 2> /dev/null ++ ++export LC_ALL=en_US.UTF-8 ++locale -k LC_CTYPE 2>&1 | grep -q charmap.*UTF-8 || exit 77 ++errors=0 ++ ++$xx -t @ -k2 -n misc/mb1.I > misc/mb1.O ++code=$? ++if test $code != 0; then ++ $echo "Test mb1 failed: $xx return code $code differs from expected value 0" 1>&2 ++ errors=`expr $errors + 1` ++else ++ cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1 ++ case $? in ++ 0) if test "$VERBOSE"; then $echo "passed mb1"; fi;; ++ 1) $echo "Test mb1 failed: files misc/mb1.O and $srcdir/misc/mb1.X differ" 1>&2 ++ (diff -c misc/mb1.O $srcdir/misc/mb1.X) 2> /dev/null ++ errors=`expr $errors + 1`;; ++ 2) $echo "Test mb1 may have failed." 1>&2 ++ $echo The command "cmp misc/mb1.O $srcdir/misc/mb1.X" failed. 1>&2 ++ errors=`expr $errors + 1`;; ++ esac ++fi ++ ++$xx -t @ -k4 -n misc/mb2.I > misc/mb2.O ++code=$? ++if test $code != 0; then ++ $echo "Test mb2 failed: $xx return code $code differs from expected value 0" 1>&2 ++ errors=`expr $errors + 1` ++else ++ cmp misc/mb2.O $srcdir/misc/mb2.X > /dev/null 2>&1 ++ case $? in ++ 0) if test "$VERBOSE"; then $echo "passed mb2"; fi;; ++ 1) $echo "Test mb2 failed: files misc/mb2.O and $srcdir/misc/mb2.X differ" 1>&2 ++ (diff -c misc/mb2.O $srcdir/misc/mb2.X) 2> /dev/null ++ errors=`expr $errors + 1`;; ++ 2) $echo "Test mb2 may have failed." 1>&2 ++ $echo The command "cmp misc/mb2.O $srcdir/misc/mb2.X" failed. 1>&2 ++ errors=`expr $errors + 1`;; ++ esac ++fi ++ ++if test $errors = 0; then ++ $echo Passed all 113 tests. 1>&2 ++else ++ $echo Failed $errors tests. 1>&2 ++fi ++test $errors = 0 || errors=1 ++exit $errors diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 3bfb9d3..2a6334f 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -1,6 +1,16366 @@ ---- coreutils-6.7/src/Makefile.am.pam 2006-11-24 21:28:10.000000000 +0000 -+++ coreutils-6.7/src/Makefile.am 2007-01-09 17:00:01.000000000 +0000 -@@ -103,7 +103,7 @@ +diff -urNp coreutils-8.0-orig/configure.ac coreutils-8.0/configure.ac +--- coreutils-8.0-orig/configure.ac 2009-09-29 15:27:11.000000000 +0200 ++++ coreutils-8.0/configure.ac 2009-10-07 10:04:27.000000000 +0200 +@@ -115,6 +115,13 @@ if test "$gl_gcc_warnings" = yes; then + AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) + fi + ++dnl Give the chance to enable PAM ++AC_ARG_ENABLE(pam, dnl ++[ --enable-pam Enable use of the PAM libraries], ++[AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) ++LIB_PAM="-ldl -lpam -lpam_misc" ++AC_SUBST(LIB_PAM)]) ++ + AC_FUNC_FORK + + optional_bin_progs= +diff -urNp coreutils-8.0-orig/configure.ac.orig coreutils-8.0/configure.ac.orig +--- coreutils-8.0-orig/configure.ac.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/configure.ac.orig 2009-09-29 15:27:11.000000000 +0200 +@@ -0,0 +1,439 @@ ++# -*- autoconf -*- ++# Process this file with autoconf to produce a configure script. ++ ++# Copyright (C) 1991, 1993-2009 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 . ++ ++dnl Written by Jim Meyering. ++ ++AC_PREREQ([2.61]) ++ ++# Make inter-release version strings look like, e.g., v6.9-219-g58ddd, which ++# indicates that it is built from the 219th delta (in _some_ repository) ++# following the v6.9 tag, and that 58ddd is a prefix of the commit SHA1. ++AC_INIT([GNU coreutils], ++ m4_esyscmd([build-aux/git-version-gen .tarball-version]), ++ [bug-coreutils@gnu.org]) ++ ++AC_CONFIG_SRCDIR([src/ls.c]) ++ ++AC_CONFIG_AUX_DIR([build-aux]) ++AC_CONFIG_HEADERS([lib/config.h:lib/config.hin]) ++ ++AM_INIT_AUTOMAKE([1.11 dist-xz color-tests parallel-tests]) ++AM_SILENT_RULES([yes]) # make --enable-silent-rules the default. ++ ++AC_PROG_CC_STDC ++AM_PROG_CC_C_O ++AC_PROG_CPP ++AC_PROG_GCC_TRADITIONAL ++AC_PROG_RANLIB ++AC_PROG_LN_S ++gl_EARLY ++gl_INIT ++coreutils_MACROS ++ ++AC_ARG_ENABLE([gcc-warnings], ++ [AS_HELP_STRING([--enable-gcc-warnings], ++ [turn on lots of GCC warnings (for developers)])], ++ [case $enableval in ++ yes|no) ;; ++ *) AC_MSG_ERROR([bad value $enableval for gcc-warnings option]) ;; ++ esac ++ gl_gcc_warnings=$enableval], ++ [gl_gcc_warnings=no] ++) ++ ++if test "$gl_gcc_warnings" = yes; then ++ gl_WARN_ADD([-Werror], [WERROR_CFLAGS]) ++ AC_SUBST([WERROR_CFLAGS]) ++ ++ nw= ++ # This, $nw, is the list of warnings we disable. ++ nw="$nw -Wdeclaration-after-statement" # too useful to forbid ++ nw="$nw -Waggregate-return" # anachronistic ++ nw="$nw -Wlong-long" # C90 is anachronistic (lib/gethrxtime.h) ++ nw="$nw -Wc++-compat" # We don't care about C++ compilers ++ nw="$nw -Wundef" # Warns on '#if GNULIB_FOO' etc in gnulib ++ nw="$nw -Wtraditional" # Warns on #elif which we use often ++ nw="$nw -Wcast-qual" # Too many warnings for now ++ nw="$nw -Wconversion" # Too many warnings for now ++ nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings ++ nw="$nw -Wsign-conversion" # Too many warnings for now ++ nw="$nw -Wtraditional-conversion" # Too many warnings for now ++ nw="$nw -Wunreachable-code" # Too many warnings for now ++ nw="$nw -Wpadded" # Our structs are not padded ++ nw="$nw -Wredundant-decls" # openat.h declares e.g., mkdirat ++ nw="$nw -Wlogical-op" # any use of fwrite provokes this ++ nw="$nw -Wformat-nonliteral" # who.c and pinky.c strftime uses ++ nw="$nw -Wvla" # warnings in gettext.h ++ nw="$nw -Wnested-externs" # use of XARGMATCH/verify_function__ ++ nw="$nw -Wswitch-enum" # Too many warnings for now ++ nw="$nw -Wswitch-default" # Too many warnings for now ++ nw="$nw -Wstack-protector" # not worth working around ++ # things I might fix soon: ++ nw="$nw -Wfloat-equal" # sort.c, seq.c ++ nw="$nw -Wmissing-format-attribute" # copy.c ++ nw="$nw -Wunsafe-loop-optimizations" # a few src/*.c ++ nw="$nw -Winline" # system.h's readdir_ignoring_dot_and_dotdot ++ nw="$nw -Wstrict-overflow" # expr.c, pr.c, tr.c, factor.c ++ # ?? -Wstrict-overflow ++ ++ gl_MANYWARN_ALL_GCC([ws]) ++ gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw]) ++ for w in $ws; do ++ gl_WARN_ADD([$w]) ++ done ++ gl_WARN_ADD([-Wno-missing-field-initializers]) # We need this one ++ gl_WARN_ADD([-Wno-sign-compare]) # Too many warnings for now ++ gl_WARN_ADD([-Wno-pointer-sign]) # Too many warnings for now ++ gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now ++ ++ # In spite of excluding -Wlogical-op above, it is enabled, as of ++ # gcc 4.5.0 20090517, and it provokes warnings in cat.c, dd.c, truncate.c ++ gl_WARN_ADD([-Wno-logical-op]) ++ ++ gl_WARN_ADD([-fdiagnostics-show-option]) ++ ++ AC_SUBST([WARN_CFLAGS]) ++ ++ AC_DEFINE([lint], [1], [Define to 1 if the compiler is checking for lint.]) ++ AC_DEFINE([_FORTIFY_SOURCE], [2], ++ [enable compile-time and run-time bounds-checking, and some warnings]) ++ AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) ++fi ++ ++AC_FUNC_FORK ++ ++optional_bin_progs= ++AC_CHECK_FUNCS([uname], ++ gl_ADD_PROG([optional_bin_progs], [uname])) ++AC_CHECK_FUNCS([chroot], ++ gl_ADD_PROG([optional_bin_progs], [chroot])) ++AC_CHECK_FUNCS([gethostid], ++ gl_ADD_PROG([optional_bin_progs], [hostid])) ++ ++gl_WINSIZE_IN_PTEM ++ ++AC_MSG_CHECKING([whether localtime caches TZ]) ++AC_CACHE_VAL([utils_cv_localtime_cache], ++[if test x$ac_cv_func_tzset = xyes; then ++AC_RUN_IFELSE([AC_LANG_SOURCE([[#include ++#if STDC_HEADERS ++# include ++#endif ++extern char **environ; ++void unset_TZ (void) ++{ ++ char **from, **to; ++ for (to = from = environ; (*to = *from); from++) ++ if (! (to[0][0] == 'T' && to[0][1] == 'Z' && to[0][2] == '=')) ++ to++; ++} ++int main() ++{ ++ time_t now = time ((time_t *) 0); ++ int hour_GMT0, hour_unset; ++ if (putenv ("TZ=GMT0") != 0) ++ exit (1); ++ hour_GMT0 = localtime (&now)->tm_hour; ++ unset_TZ (); ++ hour_unset = localtime (&now)->tm_hour; ++ if (putenv ("TZ=PST8") != 0) ++ exit (1); ++ if (localtime (&now)->tm_hour == hour_GMT0) ++ exit (1); ++ unset_TZ (); ++ if (localtime (&now)->tm_hour != hour_unset) ++ exit (1); ++ exit (0); ++}]])], ++[utils_cv_localtime_cache=no], ++[utils_cv_localtime_cache=yes], ++[# If we have tzset, assume the worst when cross-compiling. ++utils_cv_localtime_cache=yes]) ++else ++ # If we lack tzset, report that localtime does not cache TZ, ++ # since we can't invalidate the cache if we don't have tzset. ++ utils_cv_localtime_cache=no ++fi])dnl ++AC_MSG_RESULT([$utils_cv_localtime_cache]) ++if test $utils_cv_localtime_cache = yes; then ++ AC_DEFINE([LOCALTIME_CACHE], [1], [FIXME]) ++fi ++ ++# SCO-ODT-3.0 is reported to need -los to link programs using initgroups ++AC_CHECK_FUNCS([initgroups]) ++if test $ac_cv_func_initgroups = no; then ++ AC_CHECK_LIB([os], [initgroups]) ++fi ++ ++AC_CHECK_FUNCS([syslog]) ++if test $ac_cv_func_syslog = no; then ++ # syslog is not in the default libraries. See if it's in some other. ++ for lib in bsd socket inet; do ++ AC_CHECK_LIB([$lib], [syslog], [AC_DEFINE([HAVE_SYSLOG], [1], [FIXME]) ++ LIBS="$LIBS -l$lib"; break]) ++ done ++fi ++ ++AC_CACHE_CHECK([for 3-argument setpriority function], ++ [utils_cv_func_setpriority], ++ [AC_LINK_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#include ++ #include ++ ]], ++ [[setpriority (0, 0, 0);]])], ++ [utils_cv_func_setpriority=yes], ++ [utils_cv_func_setpriority=no])]) ++if test $utils_cv_func_setpriority = no; then ++ AC_CHECK_FUNCS([nice]) ++fi ++case $utils_cv_func_setpriority,$ac_cv_func_nice in ++*yes*) ++ gl_ADD_PROG([optional_bin_progs], [nice]) ++esac ++ ++AC_DEFUN([coreutils_DUMMY_1], ++[ ++ AC_REQUIRE([gl_READUTMP]) ++ if test $ac_cv_header_utmp_h = yes || test $ac_cv_header_utmpx_h = yes; then ++ gl_ADD_PROG([optional_bin_progs], [who]) ++ gl_ADD_PROG([optional_bin_progs], [users]) ++ gl_ADD_PROG([optional_bin_progs], [pinky]) ++ fi ++]) ++coreutils_DUMMY_1 ++ ++AC_MSG_CHECKING([ut_host in struct utmp]) ++AC_CACHE_VAL([su_cv_func_ut_host_in_utmp], ++[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ++#include ]], [[struct utmp ut; return !sizeof ut.ut_host;]])], ++ [su_cv_func_ut_host_in_utmp=yes], ++ [su_cv_func_ut_host_in_utmp=no])]) ++AC_MSG_RESULT([$su_cv_func_ut_host_in_utmp]) ++if test $su_cv_func_ut_host_in_utmp = yes; then ++ have_ut_host=1 ++ AC_DEFINE([HAVE_UT_HOST], [1], [FIXME]) ++fi ++ ++if test -z "$have_ut_host"; then ++ AC_MSG_CHECKING([ut_host in struct utmpx]) ++ AC_CACHE_VAL([su_cv_func_ut_host_in_utmpx], ++ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ++#include ]], [[struct utmpx ut; return !sizeof ut.ut_host;]])], ++ [su_cv_func_ut_host_in_utmpx=yes], ++ [su_cv_func_ut_host_in_utmpx=no])]) ++ AC_MSG_RESULT([$su_cv_func_ut_host_in_utmpx]) ++ if test $su_cv_func_ut_host_in_utmpx = yes; then ++ AC_DEFINE([HAVE_UTMPX_H], [1], [FIXME]) ++ AC_DEFINE([HAVE_UT_HOST], [1], [FIXME]) ++ fi ++fi ++ ++GNULIB_BOOT_TIME([gl_ADD_PROG([optional_bin_progs], [uptime])]) ++ ++AC_SYS_POSIX_TERMIOS() ++gl_HEADER_TIOCGWINSZ_NEEDS_SYS_IOCTL ++ ++if test $ac_cv_sys_posix_termios = yes; then ++ gl_ADD_PROG([optional_bin_progs], [stty]) ++ ++ AC_MSG_CHECKING([whether termios.h needs _XOPEN_SOURCE]) ++ AC_CACHE_VAL([su_cv_sys_termios_needs_xopen_source], ++ [AC_EGREP_CPP([yes], [#include ++#ifdef IUCLC ++yes ++#endif], su_cv_sys_termios_needs_xopen_source=no, ++ AC_EGREP_CPP([yes], [#define _XOPEN_SOURCE ++#include ++#ifdef IUCLC ++yes ++#endif], su_cv_sys_termios_needs_xopen_source=yes, ++ su_cv_sys_termios_needs_xopen_source=no))]) ++ AC_MSG_RESULT([$su_cv_sys_termios_needs_xopen_source]) ++ test $su_cv_sys_termios_needs_xopen_source = yes && ++ AC_DEFINE([TERMIOS_NEEDS_XOPEN_SOURCE], [1], [FIXME]) ++ ++ AC_MSG_CHECKING([c_line in struct termios]) ++ AC_CACHE_VAL([su_cv_sys_c_line_in_termios], ++ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if TERMIOS_NEEDS_XOPEN_SOURCE ++#define _XOPEN_SOURCE ++#endif ++#include ++#include ]], [[struct termios t; return !sizeof t.c_line;]])], ++ [su_cv_sys_c_line_in_termios=yes], ++ [su_cv_sys_c_line_in_termios=no])]) ++ AC_MSG_RESULT([$su_cv_sys_c_line_in_termios]) ++ test $su_cv_sys_c_line_in_termios = yes \ ++ && AC_DEFINE([HAVE_C_LINE], [1], [FIXME]) ++fi ++ ++# FIXME: note that this macro appears above, too. ++# I'm leaving it here for now. This whole thing needs to be modernized... ++gl_WINSIZE_IN_PTEM ++ ++gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H ++ ++if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ ++ test $gl_cv_sys_tiocgwinsz_needs_sys_ioctl_h = no; then ++ AC_MSG_CHECKING([TIOCGWINSZ in sys/pty.h]) ++ AC_CACHE_VAL([su_cv_sys_tiocgwinsz_in_sys_pty_h], ++ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ++#ifdef WINSIZE_IN_PTEM ++# include ++# include ++#endif ++#include ++#include ++#include ]], [[int x = TIOCGWINSZ;]])], ++ [su_cv_sys_tiocgwinsz_in_sys_pty_h=yes], ++ [su_cv_sys_tiocgwinsz_in_sys_pty_h=no])]) ++ AC_MSG_RESULT([$su_cv_sys_tiocgwinsz_in_sys_pty_h]) ++ ++ test $su_cv_sys_tiocgwinsz_in_sys_pty_h = yes \ ++ && AC_DEFINE([GWINSZ_IN_SYS_PTY], [1], ++ [Define if your system defines TIOCGWINSZ in sys/pty.h.]) ++fi ++ ++# For src/kill.c. ++AC_CHECK_DECLS([strsignal, sys_siglist, _sys_siglist, __sys_siglist], , , ++ [AC_INCLUDES_DEFAULT ++#include ]) ++ ++cu_LIB_CHECK ++cu_GMP ++ ++# Build df only if there's a point to it. ++if test $gl_cv_list_mounted_fs = yes && test $gl_cv_fs_space = yes; then ++ gl_ADD_PROG([optional_bin_progs], [df]) ++fi ++ ++# Limit stdbuf to ELF systems with GCC ++optional_pkglib_progs= ++AC_MSG_CHECKING([whether this is an ELF system]) ++AC_EGREP_CPP([yes], [#if __ELF__ ++yes ++#endif], [elf_sys=yes], [elf_sys=no]) ++AC_MSG_RESULT([$elf_sys]) ++if test "$elf_sys" = "yes" && \ ++ test "$GCC" = "yes"; then ++ gl_ADD_PROG([optional_bin_progs], [stdbuf]) ++ gl_ADD_PROG([optional_pkglib_progs], [libstdbuf.so]) ++fi ++ ++############################################################################ ++mk="$srcdir/src/Makefile.am" ++# Extract all literal names from the definition of $(EXTRA_PROGRAMS) ++# in $mk but don't expand the variable references. ++# Append each literal name to $optional_bin_progs. ++v=EXTRA_PROGRAMS ++for gl_i in `sed -n '/^'$v' =/,/[[^\]]$/p' $mk \ ++ | sed 's/^ *//;/^\$.*/d;/^'$v' =/d' \ ++ | tr -s '\\015\\012\\\\' ' '`; do ++ gl_ADD_PROG([optional_bin_progs], $gl_i) ++done ++ ++# As above, extract literal names from the definition of $(no_install__progs) ++# in $mk but don't expand the variable references. ++v=no_install__progs ++t=`sed -n '/^'$v' =/,/[[^\]]$/p' $mk \ ++ | sed 's/^ *//;/^\$.*/d;/^'$v' =/d' \ ++ | tr -s '\\015\\012\\\\' ' '` ++# Remove any trailing space. ++no_install_progs_default=`echo "$t"|sed 's/ $//'` ++ ++# Unfortunately, due to the way autoconf's AS_HELP_STRING works, the list ++# of default-not-installed programs, "arch hostname su", must appear in two ++# places: in this file below, and in $mk. Using "$no_install_progs_default" ++# below cannot work. And we can't substitute the names into $mk because ++# automake needs the literals, too. ++# The compromise is to ensure that the space-separated list extracted ++# above matches the literal 2nd argument below. ++c="$srcdir/configure.ac" ++re='^g''l_INCLUDE_EXCLUDE_PROG(.* [\[\(.*\)\]])' ++t=`sed -n '/'"$re"'/{s/'"$re"'/\1/;s/,/ /gp ++}' $c` ++case $t in ++ $no_install_progs_default) ;; ++ *) AC_MSG_ERROR([[internal error: g'l_INCLUDE_EXCLUDE_PROG's 2nd arg, $t, ++ does not match the list of default-not-installed programs ++ ($no_install_progs_default) also recorded in $mk]], ++ 1) ;; ++esac ++ ++# Given the name of a variable containing a space-separated list of ++# install-by-default programs and the actual list do-not-install-by-default ++# programs, modify the former variable to reflect any "do-install" and ++# "don't-install" requests. ++# I.e., add any program name specified via --enable-install-program=..., and ++# remove any program name specified via --enable-no-install-program=... ++# Note how the second argument below is a literal, with "," separators. ++# That is required due to the way the macro works, and since the ++# corresponding ./configure option argument is comma-separated on input. ++gl_INCLUDE_EXCLUDE_PROG([optional_bin_progs], [arch,hostname,su]) ++ ++# Set INSTALL_SU if su installation has been requested via ++# --enable-install-program=su. ++AC_SUBST([INSTALL_SU]) ++case " $optional_bin_progs " in ++ *' su '*) INSTALL_SU=yes ;; ++ *) INSTALL_SU=no ;; ++esac ++ ++MAN=`echo "$optional_bin_progs "|sed 's/ /.1 /g;s/ $//'|tr -d '\\015\\012'` ++ ++# Change ginstall.1 to "install.h" in $MAN. ++MAN=`for m in $MAN; do test $m = ginstall.1 && m=install.1; echo $m; done \ ++ | tr '\015\012' ' '; echo` ++ ++# Remove [.1, since writing a portable rule for it in man/Makefile.am ++# is not practical. The sed LHS below uses the autoconf quadrigraph ++# representing '['. ++MAN=`echo "$MAN"|sed 's/\@<:@\.1//'` ++ ++OPTIONAL_BIN_PROGS=`echo "$optional_bin_progs "|sed 's/ /\$(EXEEXT) /g;s/ $//'` ++AC_SUBST([OPTIONAL_BIN_PROGS]) ++OPTIONAL_PKGLIB_PROGS=`echo "$optional_pkglib_progs " | sed 's/ $//'` ++AC_SUBST([OPTIONAL_PKGLIB_PROGS]) ++NO_INSTALL_PROGS_DEFAULT=$no_install_progs_default ++AC_SUBST([NO_INSTALL_PROGS_DEFAULT]) ++ ++AM_CONDITIONAL([CROSS_COMPILING], [test "$cross_compiling" = yes]) ++ ++# Arrange to rerun configure whenever the file, src/Makefile.am, ++# containing the list of program names changes. ++CONFIG_STATUS_DEPENDENCIES='$(top_srcdir)/src/Makefile.am' ++AC_SUBST([CONFIG_STATUS_DEPENDENCIES]) ++############################################################################ ++ ++AM_GNU_GETTEXT([external], [need-formatstring-macros]) ++AM_GNU_GETTEXT_VERSION([0.15]) ++ ++# For a test of uniq: it uses the $LOCALE_FR envvar. ++gt_LOCALE_FR ++ ++AC_CONFIG_FILES( ++ Makefile ++ doc/Makefile ++ lib/Makefile ++ man/Makefile ++ po/Makefile.in ++ src/Makefile ++ tests/Makefile ++ gnulib-tests/Makefile ++ ) ++AC_OUTPUT +diff -urNp coreutils-8.0-orig/doc/coreutils.texi coreutils-8.0/doc/coreutils.texi +--- coreutils-8.0-orig/doc/coreutils.texi 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/doc/coreutils.texi 2009-10-07 10:04:27.000000000 +0200 +@@ -14742,8 +14742,11 @@ to certain shells, etc.). + @findex syslog + @command{su} can optionally be compiled to use @code{syslog} to report + failed, and optionally successful, @command{su} attempts. (If the system +-supports @code{syslog}.) However, GNU @command{su} does not check if the +-user is a member of the @code{wheel} group; see below. ++supports @code{syslog}.) ++ ++This version of @command{su} has support for using PAM for ++authentication. You can edit @file{/etc/pam.d/su} to customize its ++behaviour. + + The program accepts the following options. Also see @ref{Common options}. + +@@ -14785,6 +14788,8 @@ environment variables except @env{TERM}, + @env{PATH} to a compiled-in default value. Change to @var{user}'s home + directory. Prepend @samp{-} to the shell's name, intended to make it + read its login startup file(s). ++Additionaly @env{DISPLAY} and @env{XAUTHORITY} environment variables ++are preserved as well for PAM functionality. + + @item -m + @itemx -p +@@ -14824,33 +14829,6 @@ Exit status: + the exit status of the subshell otherwise + @end display + +-@cindex wheel group, not supported +-@cindex group wheel, not supported +-@cindex fascism +-@subsection Why GNU @command{su} does not support the @samp{wheel} group +- +-(This section is by Richard Stallman.) +- +-@cindex Twenex +-@cindex MIT AI lab +-Sometimes a few of the users try to hold total power over all the +-rest. For example, in 1984, a few users at the MIT AI lab decided to +-seize power by changing the operator password on the Twenex system and +-keeping it secret from everyone else. (I was able to thwart this coup +-and give power back to the users by patching the kernel, but I +-wouldn't know how to do that in Unix.) +- +-However, occasionally the rulers do tell someone. Under the usual +-@command{su} mechanism, once someone learns the root password who +-sympathizes with the ordinary users, he or she can tell the rest. The +-``wheel group'' feature would make this impossible, and thus cement the +-power of the rulers. +- +-I'm on the side of the masses, not that of the rulers. If you are +-used to supporting the bosses and sysadmins in whatever they do, you +-might find this idea strange at first. +- +- + @node timeout invocation + @section @command{timeout}: Run a command with a time limit + +diff -urNp coreutils-8.0-orig/doc/coreutils.texi.orig coreutils-8.0/doc/coreutils.texi.orig +--- coreutils-8.0-orig/doc/coreutils.texi.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/doc/coreutils.texi.orig 2009-09-29 15:27:54.000000000 +0200 +@@ -0,0 +1,15835 @@ ++\input texinfo ++@c %**start of header ++@setfilename coreutils.info ++@settitle @sc{gnu} Coreutils ++ ++@c %**end of header ++ ++@include version.texi ++@include constants.texi ++ ++@c Define new indices. ++@defcodeindex op ++@defcodeindex fl ++ ++@c Put everything in one index (arbitrarily chosen to be the concept index). ++@syncodeindex fl cp ++@syncodeindex fn cp ++@syncodeindex ky cp ++@syncodeindex op cp ++@syncodeindex pg cp ++@syncodeindex vr cp ++ ++@dircategory Basics ++@direntry ++* Coreutils: (coreutils). Core GNU (file, text, shell) utilities. ++* Common options: (coreutils)Common options. Common options. ++* File permissions: (coreutils)File permissions. Access modes. ++* Date input formats: (coreutils)Date input formats. ++@end direntry ++ ++@c FIXME: the following need documentation ++@c * [: (coreutils)[ invocation. File/string tests. ++@c * pinky: (coreutils)pinky invocation. FIXME. ++@c * mktemp: (coreutils)mktemp invocation. FIXME. ++ ++@dircategory Individual utilities ++@direntry ++* arch: (coreutils)arch invocation. Print machine hardware name. ++* base64: (coreutils)base64 invocation. Base64 encode/decode data. ++* basename: (coreutils)basename invocation. Strip directory and suffix. ++* cat: (coreutils)cat invocation. Concatenate and write files. ++* chcon: (coreutils)chcon invocation. Change SELinux CTX of files. ++* chgrp: (coreutils)chgrp invocation. Change file groups. ++* chmod: (coreutils)chmod invocation. Change file permissions. ++* chown: (coreutils)chown invocation. Change file owners/groups. ++* chroot: (coreutils)chroot invocation. Specify the root directory. ++* cksum: (coreutils)cksum invocation. Print POSIX CRC checksum. ++* comm: (coreutils)comm invocation. Compare sorted files by line. ++* cp: (coreutils)cp invocation. Copy files. ++* csplit: (coreutils)csplit invocation. Split by context. ++* cut: (coreutils)cut invocation. Print selected parts of lines. ++* date: (coreutils)date invocation. Print/set system date and time. ++* dd: (coreutils)dd invocation. Copy and convert a file. ++* df: (coreutils)df invocation. Report file system disk usage. ++* dir: (coreutils)dir invocation. List directories briefly. ++* dircolors: (coreutils)dircolors invocation. Color setup for ls. ++* dirname: (coreutils)dirname invocation. Strip non-directory suffix. ++* du: (coreutils)du invocation. Report on disk usage. ++* echo: (coreutils)echo invocation. Print a line of text. ++* env: (coreutils)env invocation. Modify the environment. ++* expand: (coreutils)expand invocation. Convert tabs to spaces. ++* expr: (coreutils)expr invocation. Evaluate expressions. ++* factor: (coreutils)factor invocation. Print prime factors ++* false: (coreutils)false invocation. Do nothing, unsuccessfully. ++* fmt: (coreutils)fmt invocation. Reformat paragraph text. ++* fold: (coreutils)fold invocation. Wrap long input lines. ++* 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 and change 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. ++* ls: (coreutils)ls invocation. List directory contents. ++* md5sum: (coreutils)md5sum invocation. Print or check MD5 digests. ++* mkdir: (coreutils)mkdir invocation. Create directories. ++* mkfifo: (coreutils)mkfifo invocation. Create FIFOs (named pipes). ++* mknod: (coreutils)mknod invocation. Create special files. ++* mv: (coreutils)mv invocation. Rename files. ++* nice: (coreutils)nice invocation. Modify niceness. ++* nl: (coreutils)nl invocation. Number lines and write files. ++* nohup: (coreutils)nohup invocation. Immunize to hangups. ++* od: (coreutils)od invocation. Dump files in octal, etc. ++* paste: (coreutils)paste invocation. Merge lines of files. ++* pathchk: (coreutils)pathchk invocation. Check file name portability. ++* pr: (coreutils)pr invocation. Paginate or columnate files. ++* printenv: (coreutils)printenv invocation. Print environment variables. ++* printf: (coreutils)printf invocation. Format and print data. ++* ptx: (coreutils)ptx invocation. Produce permuted indexes. ++* pwd: (coreutils)pwd invocation. Print working directory. ++* readlink: (coreutils)readlink invocation. Print referent of a symlink. ++* rm: (coreutils)rm invocation. Remove files. ++* rmdir: (coreutils)rmdir invocation. Remove empty directories. ++* runcon: (coreutils)runcon invocation. Run in specified SELinux CTX. ++* seq: (coreutils)seq invocation. Print numeric sequences ++* sha1sum: (coreutils)sha1sum invocation. Print or check SHA-1 digests. ++* sha2: (coreutils)sha2 utilities. Print or check SHA-2 digests. ++* shred: (coreutils)shred invocation. Remove files more securely. ++* shuf: (coreutils)shuf invocation. Shuffling text files. ++* sleep: (coreutils)sleep invocation. Delay for a specified time. ++* sort: (coreutils)sort invocation. Sort text files. ++* split: (coreutils)split invocation. Split into fixed-size pieces. ++* stat: (coreutils)stat invocation. Report file(system) status. ++* stdbuf: (coreutils)stdbuf invocation. Modify stdio buffering. ++* stty: (coreutils)stty invocation. Print/change terminal settings. ++* su: (coreutils)su invocation. Modify user and group ID. ++* sum: (coreutils)sum invocation. Print traditional checksum. ++* sync: (coreutils)sync invocation. Synchronize memory and disk. ++* tac: (coreutils)tac invocation. Reverse files. ++* tail: (coreutils)tail invocation. Output the last part of files. ++* tee: (coreutils)tee invocation. Redirect to multiple files. ++* test: (coreutils)test invocation. File/string tests. ++* timeout: (coreutils)timeout invocation. Run with time limit. ++* touch: (coreutils)touch invocation. Change file timestamps. ++* tr: (coreutils)tr invocation. Translate characters. ++* true: (coreutils)true invocation. Do nothing, successfully. ++* truncate: (coreutils)truncate invocation. Shrink/extend size of a file. ++* tsort: (coreutils)tsort invocation. Topological sort. ++* tty: (coreutils)tty invocation. Print terminal name. ++* uname: (coreutils)uname invocation. Print system information. ++* unexpand: (coreutils)unexpand invocation. Convert spaces to tabs. ++* uniq: (coreutils)uniq invocation. Uniquify files. ++* unlink: (coreutils)unlink invocation. Removal via unlink(2). ++* uptime: (coreutils)uptime invocation. Print uptime and load. ++* users: (coreutils)users invocation. Print current user names. ++* vdir: (coreutils)vdir invocation. List directories verbosely. ++* wc: (coreutils)wc invocation. Line, word, and byte counts. ++* who: (coreutils)who invocation. Print who is logged in. ++* whoami: (coreutils)whoami invocation. Print effective user ID. ++* yes: (coreutils)yes invocation. Print a string indefinitely. ++@end direntry ++ ++@copying ++This manual documents version @value{VERSION} of the @sc{gnu} core ++utilities, including the standard programs for text and file manipulation. ++ ++Copyright @copyright{} 1994-1996, 2000-2009 Free Software Foundation, Inc. ++ ++@quotation ++Permission is granted to copy, distribute and/or modify this document ++under the terms of the GNU Free Documentation License, Version 1.3 or ++any later version published by the Free Software Foundation; with no ++Invariant Sections, with no Front-Cover Texts, and with no Back-Cover ++Texts. A copy of the license is included in the section entitled ``GNU ++Free Documentation License''. ++@end quotation ++@end copying ++ ++@titlepage ++@title @sc{gnu} @code{Coreutils} ++@subtitle Core GNU utilities ++@subtitle for version @value{VERSION}, @value{UPDATED} ++@author David MacKenzie et al. ++ ++@page ++@vskip 0pt plus 1filll ++@insertcopying ++@end titlepage ++@shortcontents ++@contents ++ ++@ifnottex ++@node Top ++@top GNU Coreutils ++ ++@insertcopying ++@end ifnottex ++ ++@cindex core utilities ++@cindex text utilities ++@cindex shell utilities ++@cindex file utilities ++ ++@menu ++* Introduction:: Caveats, overview, and authors ++* Common options:: Common options ++* Output of entire files:: cat tac nl od base64 ++* Formatting file contents:: fmt pr fold ++* Output of parts of files:: head tail split csplit ++* Summarizing files:: wc sum cksum md5sum sha1sum sha2 ++* Operating on sorted files:: sort shuf uniq comm ptx tsort ++* Operating on fields:: cut paste join ++* Operating on characters:: tr expand unexpand ++* Directory listing:: ls dir vdir dircolors ++* Basic operations:: cp dd install mv rm shred ++* Special file types:: mkdir rmdir unlink mkfifo mknod ln link readlink ++* Changing file attributes:: chgrp chmod chown touch ++* Disk usage:: df du stat sync truncate ++* Printing text:: echo printf yes ++* Conditions:: false true test expr ++* Redirection:: tee ++* File name manipulation:: dirname basename pathchk ++* Working context:: pwd stty printenv tty ++* User information:: id logname whoami groups users who ++* System context:: date arch uname hostname hostid uptime ++* SELinux context:: chcon runcon ++* Modified command invocation:: chroot env nice nohup stdbuf su timeout ++* Process control:: kill ++* Delaying:: sleep ++* Numeric operations:: factor seq ++* File permissions:: Access modes ++* Date input formats:: Specifying date strings ++* Opening the software toolbox:: The software tools philosophy ++* GNU Free Documentation License:: Copying and sharing this manual ++* Concept index:: General index ++ ++@detailmenu ++ --- The Detailed Node Listing --- ++ ++Common Options ++ ++* Exit status:: Indicating program success or failure ++* Backup options:: Backup options ++* Block size:: Block size ++* Signal specifications:: Specifying signals ++* Disambiguating names and IDs:: chgrp and chown owner and group syntax ++* Random sources:: Sources of random data ++* Target directory:: Target directory ++* Trailing slashes:: Trailing slashes ++* Traversing symlinks:: Traversing symlinks to directories ++* Treating / specially:: Treating / specially ++* Standards conformance:: Standards conformance ++ ++Output of entire files ++ ++* cat invocation:: Concatenate and write files ++* tac invocation:: Concatenate and write files in reverse ++* nl invocation:: Number lines and write files ++* od invocation:: Write files in octal or other formats ++* base64 invocation:: Transform data into printable data ++ ++Formatting file contents ++ ++* fmt invocation:: Reformat paragraph text ++* pr invocation:: Paginate or columnate files for printing ++* fold invocation:: Wrap input lines to fit in specified width ++ ++Output of parts of files ++ ++* head invocation:: Output the first part of files ++* tail invocation:: Output the last part of files ++* split invocation:: Split a file into fixed-size pieces ++* csplit invocation:: Split a file into context-determined pieces ++ ++Summarizing files ++ ++* wc invocation:: Print newline, word, and byte counts ++* sum invocation:: Print checksum and block counts ++* cksum invocation:: Print CRC checksum and byte counts ++* md5sum invocation:: Print or check MD5 digests ++* sha1sum invocation:: Print or check SHA-1 digests ++* sha2 utilities:: Print or check SHA-2 digests ++ ++Operating on sorted files ++ ++* sort invocation:: Sort text files ++* shuf invocation:: Shuffle text files ++* uniq invocation:: Uniquify files ++* comm invocation:: Compare two sorted files line by line ++* ptx invocation:: Produce a permuted index of file contents ++* tsort invocation:: Topological sort ++ ++@command{ptx}: Produce permuted indexes ++ ++* General options in ptx:: Options which affect general program behavior ++* Charset selection in ptx:: Underlying character set considerations ++* Input processing in ptx:: Input fields, contexts, and keyword selection ++* Output formatting in ptx:: Types of output format, and sizing the fields ++* Compatibility in ptx:: The @acronym{GNU} extensions to @command{ptx} ++ ++Operating on fields ++ ++* cut invocation:: Print selected parts of lines ++* paste invocation:: Merge lines of files ++* join invocation:: Join lines on a common field ++ ++Operating on characters ++ ++* tr invocation:: Translate, squeeze, and/or delete characters ++* expand invocation:: Convert tabs to spaces ++* unexpand invocation:: Convert spaces to tabs ++ ++@command{tr}: Translate, squeeze, and/or delete characters ++ ++* Character sets:: Specifying sets of characters ++* Translating:: Changing one set of characters to another ++* Squeezing:: Squeezing repeats and deleting ++ ++Directory listing ++ ++* ls invocation:: List directory contents ++* dir invocation:: Briefly list directory contents ++* vdir invocation:: Verbosely list directory contents ++* dircolors invocation:: Color setup for @command{ls} ++ ++@command{ls}: List directory contents ++ ++* Which files are listed:: Which files are listed ++* What information is listed:: What information is listed ++* Sorting the output:: Sorting the output ++* Details about version sort:: More details about version sort ++* General output formatting:: General output formatting ++* Formatting the file names:: Formatting the file names ++ ++Basic operations ++ ++* cp invocation:: Copy files and directories ++* dd invocation:: Convert and copy a file ++* install invocation:: Copy files and set attributes ++* mv invocation:: Move (rename) files ++* rm invocation:: Remove files or directories ++* shred invocation:: Remove files more securely ++ ++Special file types ++ ++* link invocation:: Make a hard link via the link syscall ++* ln invocation:: Make links between files ++* mkdir invocation:: Make directories ++* mkfifo invocation:: Make FIFOs (named pipes) ++* mknod invocation:: Make block or character special files ++* readlink invocation:: Print value of a symlink or canonical file name ++* rmdir invocation:: Remove empty directories ++* unlink invocation:: Remove files via unlink syscall ++ ++Changing file attributes ++ ++* chown invocation:: Change file owner and group ++* chgrp invocation:: Change group ownership ++* chmod invocation:: Change access permissions ++* touch invocation:: Change file timestamps ++ ++Disk usage ++ ++* df invocation:: Report file system disk space usage ++* du invocation:: Estimate file space usage ++* stat invocation:: Report file or file system status ++* sync invocation:: Synchronize data on disk with memory ++* truncate invocation:: Shrink or extend the size of a file ++ ++Printing text ++ ++* echo invocation:: Print a line of text ++* printf invocation:: Format and print data ++* yes invocation:: Print a string until interrupted ++ ++Conditions ++ ++* false invocation:: Do nothing, unsuccessfully ++* true invocation:: Do nothing, successfully ++* test invocation:: Check file types and compare values ++* expr invocation:: Evaluate expressions ++ ++@command{test}: Check file types and compare values ++ ++* File type tests:: File type tests ++* Access permission tests:: Access permission tests ++* File characteristic tests:: File characteristic tests ++* String tests:: String tests ++* Numeric tests:: Numeric tests ++ ++@command{expr}: Evaluate expression ++ ++* String expressions:: + : match substr index length ++* Numeric expressions:: + - * / % ++* Relations for expr:: | & < <= = == != >= > ++* Examples of expr:: Examples of using @command{expr} ++ ++Redirection ++ ++* tee invocation:: Redirect output to multiple files or processes ++ ++File name manipulation ++ ++* basename invocation:: Strip directory and suffix from a file name ++* dirname invocation:: Strip non-directory suffix from a file name ++* pathchk invocation:: Check file name validity and portability ++ ++Working context ++ ++* pwd invocation:: Print working directory ++* stty invocation:: Print or change terminal characteristics ++* printenv invocation:: Print all or some environment variables ++* tty invocation:: Print file name of terminal on standard input ++ ++@command{stty}: Print or change terminal characteristics ++ ++* Control:: Control settings ++* Input:: Input settings ++* Output:: Output settings ++* Local:: Local settings ++* Combination:: Combination settings ++* Characters:: Special characters ++* Special:: Special settings ++ ++User information ++ ++* id invocation:: Print user identity ++* logname invocation:: Print current login name ++* whoami invocation:: Print effective user ID ++* groups invocation:: Print group names a user is in ++* users invocation:: Print login names of users currently logged in ++* who invocation:: Print who is currently logged in ++ ++System context ++ ++* arch invocation:: Print machine hardware name ++* date invocation:: Print or set system date and time ++* 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 ++ ++@command{date}: Print or set system date and time ++ ++* Time conversion specifiers:: %[HIklMNpPrRsSTXzZ] ++* Date conversion specifiers:: %[aAbBcCdDeFgGhjmuUVwWxyY] ++* Literal conversion specifiers:: %[%nt] ++* Padding and other flags:: Pad with zeros, spaces, etc. ++* Setting the time:: Changing the system clock ++* Options for date:: Instead of the current time ++* Date input formats:: Specifying date strings ++* Examples of date:: Examples ++ ++SELinux context ++ ++* chcon invocation:: Change SELinux context of file ++* runcon invocation:: Run a command in specified SELinux context ++ ++Modified command invocation ++ ++* chroot invocation:: Run a command with a different root directory ++* env invocation:: Run a command in a modified environment ++* nice invocation:: Run a command with modified niceness ++* nohup invocation:: Run a command immune to hangups ++* stdbuf invocation:: Run a command with modified I/O buffering ++* su invocation:: Run a command with substitute user and group ID ++* 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 ++ ++Numeric operations ++ ++* factor invocation:: Print prime factors ++* seq invocation:: Print numeric sequences ++ ++File permissions ++ ++* Mode Structure:: Structure of file mode bits ++* Symbolic Modes:: Mnemonic representation of file mode bits ++* Numeric Modes:: File mode bits as octal numbers ++* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories ++ ++Date input formats ++ ++* General date syntax:: Common rules ++* Calendar date items:: 19 Dec 1994 ++* Time of day items:: 9:20pm ++* Time zone items:: @sc{est}, @sc{pdt}, @sc{gmt} ++* Day of week items:: Monday and others ++* Relative items in date strings:: next tuesday, 2 years ago ++* Pure numbers in date strings:: 19931219, 1440 ++* Seconds since the Epoch:: @@1078100502 ++* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0" ++* Authors of get_date:: Bellovin, Eggert, Salz, Berets, et al ++ ++Opening the software toolbox ++ ++* Toolbox introduction:: Toolbox introduction ++* I/O redirection:: I/O redirection ++* The who command:: The @command{who} command ++* The cut command:: The @command{cut} command ++* The sort command:: The @command{sort} command ++* The uniq command:: The @command{uniq} command ++* Putting the tools together:: Putting the tools together ++ ++Copying This Manual ++ ++* GNU Free Documentation License:: Copying and sharing this manual ++ ++@end detailmenu ++@end menu ++ ++ ++@node Introduction ++@chapter Introduction ++ ++This manual is a work in progress: many sections make no attempt to explain ++basic concepts in a way suitable for novices. Thus, if you are interested, ++please get involved in improving this manual. The entire @sc{gnu} community ++will benefit. ++ ++@cindex @acronym{POSIX} ++The @sc{gnu} utilities documented here are mostly compatible with the ++@acronym{POSIX} standard. ++@cindex bugs, reporting ++Please report bugs to @email{bug-coreutils@@gnu.org}. Remember ++to include the version number, machine architecture, input files, and ++any other information needed to reproduce the bug: your input, what you ++expected, what you got, and why it is wrong. Diffs are welcome, but ++please include a description of the problem as well, since this is ++sometimes difficult to infer. @xref{Bugs, , , gcc, Using and Porting GNU CC}. ++ ++@cindex Berry, K. ++@cindex Paterson, R. ++@cindex Stallman, R. ++@cindex Pinard, F. ++@cindex MacKenzie, D. ++@cindex Meyering, J. ++@cindex Youmans, B. ++This manual was originally derived from the Unix man pages in the ++distributions, which were written by David MacKenzie and updated by Jim ++Meyering. What you are reading now is the authoritative documentation ++for these utilities; the man pages are no longer being maintained. The ++original @command{fmt} man page was written by Ross Paterson. Fran@,{c}ois ++Pinard did the initial conversion to Texinfo format. Karl Berry did the ++indexing, some reorganization, and editing of the results. Brian ++Youmans of the Free Software Foundation office staff combined the ++manuals for textutils, fileutils, and sh-utils to produce the present ++omnibus manual. Richard Stallman contributed his usual invaluable ++insights to the overall process. ++ ++@node Common options ++@chapter Common options ++ ++@macro optBackup ++@item -b ++@itemx @w{@kbd{--backup}[=@var{method}]} ++@opindex -b ++@opindex --backup ++@vindex VERSION_CONTROL ++@cindex backups, making ++@xref{Backup options}. ++Make a backup of each file that would otherwise be overwritten or removed. ++@end macro ++ ++@macro optBackupSuffix ++@item -S @var{suffix} ++@itemx --suffix=@var{suffix} ++@opindex -S ++@opindex --suffix ++Append @var{suffix} to each backup file made with @option{-b}. ++@xref{Backup options}. ++@end macro ++ ++@macro optTargetDirectory ++@item -t @var{directory} ++@itemx @w{@kbd{--target-directory}=@var{directory}} ++@opindex -t ++@opindex --target-directory ++@cindex target directory ++@cindex destination directory ++Specify the destination @var{directory}. ++@xref{Target directory}. ++@end macro ++ ++@macro optNoTargetDirectory ++@item -T ++@itemx --no-target-directory ++@opindex -T ++@opindex --no-target-directory ++@cindex target directory ++@cindex destination directory ++Do not treat the last operand specially when it is a directory or a ++symbolic link to a directory. @xref{Target directory}. ++@end macro ++ ++@macro optSi ++@itemx --si ++@opindex --si ++@cindex SI output ++Append an SI-style abbreviation to each size, such as @samp{M} for ++megabytes. Powers of 1000 are used, not 1024; @samp{M} stands for ++1,000,000 bytes. This option is equivalent to ++@option{--block-size=si}. Use the @option{-h} or ++@option{--human-readable} option if ++you prefer powers of 1024. ++@end macro ++ ++@macro optHumanReadable ++@item -h ++@itemx --human-readable ++@opindex -h ++@opindex --human-readable ++@cindex human-readable output ++Append a size letter to each size, such as @samp{M} for mebibytes. ++Powers of 1024 are used, not 1000; @samp{M} stands for 1,048,576 bytes. ++This option is equivalent to @option{--block-size=human-readable}. ++Use the @option{--si} option if you prefer powers of 1000. ++@end macro ++ ++@macro optStripTrailingSlashes ++@itemx @w{@kbd{--strip-trailing-slashes}} ++@opindex --strip-trailing-slashes ++@cindex stripping trailing slashes ++Remove any trailing slashes from each @var{source} argument. ++@xref{Trailing slashes}. ++@end macro ++ ++@macro mayConflictWithShellBuiltIn{cmd} ++@cindex conflicts with shell built-ins ++@cindex built-in shell commands, conflicts with ++Due to shell aliases and built-in @command{\cmd\} command, using an ++unadorned @command{\cmd\} interactively or in a script may get you ++different functionality than that described here. Invoke it via ++@command{env} (i.e., @code{env \cmd\ @dots{}}) to avoid interference ++from the shell. ++ ++@end macro ++ ++@macro multiplierSuffixes{varName} ++@var{\varName\} may be, or may be an integer optionally followed by, ++one of the following multiplicative suffixes: ++@example ++@samp{b} => 512 ("blocks") ++@samp{KB} => 1000 (KiloBytes) ++@samp{K} => 1024 (KibiBytes) ++@samp{MB} => 1000*1000 (MegaBytes) ++@samp{M} => 1024*1024 (MebiBytes) ++@samp{GB} => 1000*1000*1000 (GigaBytes) ++@samp{G} => 1024*1024*1024 (GibiBytes) ++@end example ++and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}. ++@end macro ++ ++@c FIXME: same as above, but no ``blocks'' line. ++@macro multiplierSuffixesNoBlocks{varName} ++@var{\varName\} may be, or may be an integer optionally followed by, ++one of the following multiplicative suffixes: ++@example ++@samp{KB} => 1000 (KiloBytes) ++@samp{K} => 1024 (KibiBytes) ++@samp{MB} => 1000*1000 (MegaBytes) ++@samp{M} => 1024*1024 (MebiBytes) ++@samp{GB} => 1000*1000*1000 (GigaBytes) ++@samp{G} => 1024*1024*1024 (GibiBytes) ++@end example ++and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}. ++@end macro ++ ++@cindex common options ++ ++Certain options are available in all of these programs. Rather than ++writing identical descriptions for each of the programs, they are ++described here. (In fact, every @sc{gnu} program accepts (or should accept) ++these options.) ++ ++@vindex POSIXLY_CORRECT ++Normally options and operands can appear in any order, and programs act ++as if all the options appear before any operands. For example, ++@samp{sort -r passwd -t :} acts like @samp{sort -r -t : passwd}, since ++@samp{:} is an option-argument of @option{-t}. However, if the ++@env{POSIXLY_CORRECT} environment variable is set, options must appear ++before operands, unless otherwise specified for a particular command. ++ ++A few programs can usefully have trailing operands with leading ++@samp{-}. With such a program, options must precede operands even if ++@env{POSIXLY_CORRECT} is not set, and this fact is noted in the ++program description. For example, the @command{env} command's options ++must appear before its operands, since in some cases the operands ++specify a command that itself contains options. ++ ++Most programs that accept long options recognize unambiguous ++abbreviations of those options. For example, @samp{rmdir ++--ignore-fail-on-non-empty} can be invoked as @samp{rmdir ++--ignore-fail} or even @samp{rmdir --i}. Ambiguous options, such as ++@samp{ls --h}, are identified as such. ++ ++Some of these programs recognize the @option{--help} and @option{--version} ++options only when one of them is the sole command line argument. For ++these programs, abbreviations of the long options are not always recognized. ++ ++@table @samp ++ ++@item --help ++@opindex --help ++@cindex help, online ++Print a usage message listing all available options, then exit successfully. ++ ++@item --version ++@opindex --version ++@cindex version number, finding ++Print the version number, then exit successfully. ++ ++@item -- ++@opindex -- ++@cindex option delimiter ++Delimit the option list. Later arguments, if any, are treated as ++operands even if they begin with @samp{-}. For example, @samp{sort -- ++-r} reads from the file named @file{-r}. ++ ++@end table ++ ++@cindex standard input ++@cindex standard output ++A single @samp{-} operand is not really an option, though it looks like one. It ++stands for standard input, or for standard output if that is clear from ++the context. For example, @samp{sort -} reads from standard input, ++and is equivalent to plain @samp{sort}, and @samp{tee -} writes an ++extra copy of its input to standard output. Unless otherwise ++specified, @samp{-} can appear as any operand that requires a file ++name. ++ ++@menu ++* Exit status:: Indicating program success or failure. ++* Backup options:: -b -S, in some programs. ++* Block size:: BLOCK_SIZE and --block-size, in some programs. ++* Signal specifications:: Specifying signals using the --signal option. ++* Disambiguating names and IDs:: chgrp and chown owner and group syntax ++* Random sources:: --random-source, in some programs. ++* Target directory:: Specifying a target directory, in some programs. ++* Trailing slashes:: --strip-trailing-slashes, in some programs. ++* Traversing symlinks:: -H, -L, or -P, in some programs. ++* Treating / specially:: --preserve-root and --no-preserve-root. ++* Special built-in utilities:: @command{break}, @command{:}, @command{eval}, @dots{} ++* Standards conformance:: Conformance to the @acronym{POSIX} standard. ++@end menu ++ ++ ++@node Exit status ++@section Exit status ++ ++@macro exitstatus ++An exit status of zero indicates success, ++and a nonzero value indicates failure. ++@end macro ++ ++Nearly every command invocation yields an integral @dfn{exit status} ++that can be used to change how other commands work. ++For the vast majority of commands, an exit status of zero indicates ++success. Failure is indicated by a nonzero value---typically ++@samp{1}, though it may differ on unusual platforms as @acronym{POSIX} ++requires only that it be nonzero. ++ ++However, some of the programs documented here do produce ++other exit status values and a few associate different ++meanings with the values @samp{0} and @samp{1}. ++Here are some of the exceptions: ++@command{chroot}, @command{env}, @command{expr}, @command{nice}, ++@command{nohup}, @command{printenv}, @command{sort}, @command{stdbuf}, ++@command{su}, @command{test}, @command{timeout}, @command{tty}. ++ ++ ++@node Backup options ++@section Backup options ++ ++@cindex backup options ++ ++Some @sc{gnu} programs (at least @command{cp}, @command{install}, ++@command{ln}, and @command{mv}) optionally make backups of files ++before writing new versions. ++These options control the details of these backups. The options are also ++briefly mentioned in the descriptions of the particular programs. ++ ++@table @samp ++ ++@item -b ++@itemx @w{@kbd{--backup}[=@var{method}]} ++@opindex -b ++@opindex --backup ++@vindex VERSION_CONTROL ++@cindex backups, making ++Make a backup of each file that would otherwise be overwritten or removed. ++Without this option, the original versions are destroyed. ++Use @var{method} to determine the type of backups to make. ++When this option is used but @var{method} is not specified, ++then the value of the @env{VERSION_CONTROL} ++environment variable is used. And if @env{VERSION_CONTROL} is not set, ++the default backup type is @samp{existing}. ++ ++Note that the short form of this option, @option{-b} does not accept any ++argument. Using @option{-b} is equivalent to using @option{--backup=existing}. ++ ++@vindex version-control @r{Emacs variable} ++This option corresponds to the Emacs variable @samp{version-control}; ++the values for @var{method} are the same as those used in Emacs. ++This option also accepts more descriptive names. ++The valid @var{method}s are (unique abbreviations are accepted): ++ ++@table @samp ++@item none ++@itemx off ++@opindex none @r{backup method} ++Never make backups. ++ ++@item numbered ++@itemx t ++@opindex numbered @r{backup method} ++Always make numbered backups. ++ ++@item existing ++@itemx nil ++@opindex existing @r{backup method} ++Make numbered backups of files that already have them, simple backups ++of the others. ++ ++@item simple ++@itemx never ++@opindex simple @r{backup method} ++Always make simple backups. Please note @samp{never} is not to be ++confused with @samp{none}. ++ ++@end table ++ ++@item -S @var{suffix} ++@itemx --suffix=@var{suffix} ++@opindex -S ++@opindex --suffix ++@cindex backup suffix ++@vindex SIMPLE_BACKUP_SUFFIX ++Append @var{suffix} to each backup file made with @option{-b}. If this ++option is not specified, the value of the @env{SIMPLE_BACKUP_SUFFIX} ++environment variable is used. And if @env{SIMPLE_BACKUP_SUFFIX} is not ++set, the default is @samp{~}, just as in Emacs. ++ ++@end table ++ ++@node Block size ++@section Block size ++ ++@cindex block size ++ ++Some @sc{gnu} programs (at least @command{df}, @command{du}, and ++@command{ls}) display sizes in ``blocks''. You can adjust the block size ++and method of display to make sizes easier to read. The block size ++used for display is independent of any file system block size. ++Fractional block counts are rounded up to the nearest integer. ++ ++@opindex --block-size=@var{size} ++@vindex BLOCKSIZE ++@vindex BLOCK_SIZE ++@vindex DF_BLOCK_SIZE ++@vindex DU_BLOCK_SIZE ++@vindex LS_BLOCK_SIZE ++@vindex POSIXLY_CORRECT@r{, and block size} ++ ++The default block size is chosen by examining the following environment ++variables in turn; the first one that is set determines the block size. ++ ++@table @code ++ ++@item DF_BLOCK_SIZE ++This specifies the default block size for the @command{df} command. ++Similarly, @env{DU_BLOCK_SIZE} specifies the default for @command{du} and ++@env{LS_BLOCK_SIZE} for @command{ls}. ++ ++@item BLOCK_SIZE ++This specifies the default block size for all three commands, if the ++above command-specific environment variables are not set. ++ ++@item BLOCKSIZE ++This specifies the default block size for all values that are normally ++printed as blocks, if neither @env{BLOCK_SIZE} nor the above ++command-specific environment variables are set. Unlike the other ++environment variables, @env{BLOCKSIZE} does not affect values that are ++normally printed as byte counts, e.g., the file sizes contained in ++@code{ls -l} output. ++ ++@item POSIXLY_CORRECT ++If neither @env{@var{command}_BLOCK_SIZE}, nor @env{BLOCK_SIZE}, nor ++@env{BLOCKSIZE} is set, but this variable is set, the block size ++defaults to 512. ++ ++@end table ++ ++If none of the above environment variables are set, the block size ++currently defaults to 1024 bytes in most contexts, but this number may ++change in the future. For @command{ls} file sizes, the block size ++defaults to 1 byte. ++ ++@cindex human-readable output ++@cindex SI output ++ ++A block size specification can be a positive integer specifying the number ++of bytes per block, or it can be @code{human-readable} or @code{si} to ++select a human-readable format. Integers may be followed by suffixes ++that are upward compatible with the ++@uref{http://www.bipm.fr/enus/3_SI/si-prefixes.html, SI prefixes} ++for decimal multiples and with the ++@uref{http://physics.nist.gov/cuu/Units/binary.html, IEC 60027-2 ++prefixes for binary multiples}. ++ ++With human-readable formats, output sizes are followed by a size letter ++such as @samp{M} for megabytes. @code{BLOCK_SIZE=human-readable} uses ++powers of 1024; @samp{M} stands for 1,048,576 bytes. ++@code{BLOCK_SIZE=si} is similar, but uses powers of 1000 and appends ++@samp{B}; @samp{MB} stands for 1,000,000 bytes. ++ ++@vindex LC_NUMERIC ++A block size specification preceded by @samp{'} causes output sizes to ++be displayed with thousands separators. The @env{LC_NUMERIC} locale ++specifies the thousands separator and grouping. For example, in an ++American English locale, @samp{--block-size="'1kB"} would cause a size ++of 1234000 bytes to be displayed as @samp{1,234}. In the default C ++locale, there is no thousands separator so a leading @samp{'} has no ++effect. ++ ++An integer block size can be followed by a suffix to specify a ++multiple of that size. A bare size letter, ++or one followed by @samp{iB}, specifies ++a multiple using powers of 1024. A size letter followed by @samp{B} ++specifies powers of 1000 instead. For example, @samp{1M} and ++@samp{1MiB} are equivalent to @samp{1048576}, whereas @samp{1MB} is ++equivalent to @samp{1000000}. ++ ++A plain suffix without a preceding integer acts as if @samp{1} were ++prepended, except that it causes a size indication to be appended to ++the output. For example, @samp{--block-size="kB"} displays 3000 as ++@samp{3kB}. ++ ++The following suffixes are defined. Large sizes like @code{1Y} ++may be rejected by your computer due to limitations of its arithmetic. ++ ++@table @samp ++@item kB ++@cindex kilobyte, definition of ++kilobyte: @math{10^3 = 1000}. ++@item k ++@itemx K ++@itemx KiB ++@cindex kibibyte, definition of ++kibibyte: @math{2^{10} = 1024}. @samp{K} is special: the SI prefix is ++@samp{k} and the IEC 60027-2 prefix is @samp{Ki}, but tradition and ++@acronym{POSIX} use @samp{k} to mean @samp{KiB}. ++@item MB ++@cindex megabyte, definition of ++megabyte: @math{10^6 = 1,000,000}. ++@item M ++@itemx MiB ++@cindex mebibyte, definition of ++mebibyte: @math{2^{20} = 1,048,576}. ++@item GB ++@cindex gigabyte, definition of ++gigabyte: @math{10^9 = 1,000,000,000}. ++@item G ++@itemx GiB ++@cindex gibibyte, definition of ++gibibyte: @math{2^{30} = 1,073,741,824}. ++@item TB ++@cindex terabyte, definition of ++terabyte: @math{10^{12} = 1,000,000,000,000}. ++@item T ++@itemx TiB ++@cindex tebibyte, definition of ++tebibyte: @math{2^{40} = 1,099,511,627,776}. ++@item PB ++@cindex petabyte, definition of ++petabyte: @math{10^{15} = 1,000,000,000,000,000}. ++@item P ++@itemx PiB ++@cindex pebibyte, definition of ++pebibyte: @math{2^{50} = 1,125,899,906,842,624}. ++@item EB ++@cindex exabyte, definition of ++exabyte: @math{10^{18} = 1,000,000,000,000,000,000}. ++@item E ++@itemx EiB ++@cindex exbibyte, definition of ++exbibyte: @math{2^{60} = 1,152,921,504,606,846,976}. ++@item ZB ++@cindex zettabyte, definition of ++zettabyte: @math{10^{21} = 1,000,000,000,000,000,000,000} ++@item Z ++@itemx ZiB ++@math{2^{70} = 1,180,591,620,717,411,303,424}. ++(@samp{Zi} is a @acronym{GNU} extension to IEC 60027-2.) ++@item YB ++@cindex yottabyte, definition of ++yottabyte: @math{10^{24} = 1,000,000,000,000,000,000,000,000}. ++@item Y ++@itemx YiB ++@math{2^{80} = 1,208,925,819,614,629,174,706,176}. ++(@samp{Yi} is a @acronym{GNU} extension to IEC 60027-2.) ++@end table ++ ++@opindex -k ++@opindex -h ++@opindex --block-size ++@opindex --human-readable ++@opindex --si ++ ++Block size defaults can be overridden by an explicit ++@option{--block-size=@var{size}} option. The @option{-k} ++option is equivalent to @option{--block-size=1K}, which ++is the default unless the @env{POSIXLY_CORRECT} environment variable is ++set. The @option{-h} or @option{--human-readable} option is equivalent to ++@option{--block-size=human-readable}. The @option{--si} option is ++equivalent to @option{--block-size=si}. ++ ++@node Signal specifications ++@section Signal specifications ++@cindex signals, specifying ++ ++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. The following signal names ++and numbers are supported on all @acronym{POSIX} compliant systems: ++ ++@table @samp ++@item HUP ++1. Hangup. ++@item INT ++2. Terminal interrupt. ++@item QUIT ++3. Terminal quit. ++@item ABRT ++6. Process abort. ++@item KILL ++9. Kill (cannot be caught or ignored). ++@item ALRM ++14. Alarm Clock. ++@item TERM ++15. Termination. ++@end table ++ ++@noindent ++Other supported signal names have system-dependent corresponding ++numbers. All systems conforming to @acronym{POSIX} 1003.1-2001 also ++support the following signals: ++ ++@table @samp ++@item BUS ++Access to an undefined portion of a memory object. ++@item CHLD ++Child process terminated, stopped, or continued. ++@item CONT ++Continue executing, if stopped. ++@item FPE ++Erroneous arithmetic operation. ++@item ILL ++Illegal Instruction. ++@item PIPE ++Write on a pipe with no one to read it. ++@item SEGV ++Invalid memory reference. ++@item STOP ++Stop executing (cannot be caught or ignored). ++@item TSTP ++Terminal stop. ++@item TTIN ++Background process attempting read. ++@item TTOU ++Background process attempting write. ++@item URG ++High bandwidth data is available at a socket. ++@item USR1 ++User-defined signal 1. ++@item USR2 ++User-defined signal 2. ++@end table ++ ++@noindent ++@acronym{POSIX} 1003.1-2001 systems that support the @acronym{XSI} extension ++also support the following signals: ++ ++@table @samp ++@item POLL ++Pollable event. ++@item PROF ++Profiling timer expired. ++@item SYS ++Bad system call. ++@item TRAP ++Trace/breakpoint trap. ++@item VTALRM ++Virtual timer expired. ++@item XCPU ++CPU time limit exceeded. ++@item XFSZ ++File size limit exceeded. ++@end table ++ ++@noindent ++@acronym{POSIX} 1003.1-2001 systems that support the @acronym{XRT} extension ++also support at least eight real-time signals called @samp{RTMIN}, ++@samp{RTMIN+1}, @dots{}, @samp{RTMAX-1}, @samp{RTMAX}. ++ ++@node Disambiguating names and IDs ++@section chown and chgrp: Disambiguating user names and IDs ++@cindex user names, disambiguating ++@cindex user IDs, disambiguating ++@cindex group names, disambiguating ++@cindex group IDs, disambiguating ++@cindex disambiguating group names and IDs ++ ++Since the @var{owner} and @var{group} arguments to @command{chown} and ++@command{chgrp} may be specified as names or numeric IDs, there is an ++apparent ambiguity. ++What if a user or group @emph{name} is a string of digits? ++@footnote{Using a number as a user name is common in some environments.} ++Should the command interpret it as a user name or as an ID? ++@acronym{POSIX} requires that @command{chown} and @command{chgrp} ++first attempt to resolve the specified string as a name, and ++only once that fails, then try to interpret it as an ID. ++This is troublesome when you want to specify a numeric ID, say 42, ++and it must work even in a pathological situation where ++@samp{42} is a user name that maps to some other user ID, say 1000. ++Simply invoking @code{chown 42 F}, will set @file{F}s owner ID to ++1000---not what you intended. ++ ++GNU @command{chown} and @command{chgrp} provide a way to work around this, ++that at the same time may result in a significant performance improvement ++by eliminating a database look-up. ++Simply precede each numeric user ID and/or group ID with a @samp{+}, ++in order to force its interpretation as an integer: ++ ++@example ++chown +42 F ++chgrp +$numeric_group_id another-file ++chown +0:+0 / ++@end example ++ ++GNU @command{chown} and @command{chgrp} ++skip the name look-up process for each @samp{+}-prefixed string, ++because a string containing @samp{+} is never a valid user or group name. ++This syntax is accepted on most common Unix systems, but not on Solaris 10. ++ ++@node Random sources ++@section Sources of random data ++ ++@cindex random sources ++ ++The @command{shuf}, @command{shred}, and @command{sort} commands ++sometimes need random data to do their work. For example, @samp{sort ++-R} must choose a hash function at random, and it needs random data to ++make this selection. ++ ++By default these commands use an internal pseudorandom generator ++initialized by a small amount of entropy, but can be directed to use ++an external source with the @option{--random-source=@var{file}} option. ++An error is reported if @var{file} does not contain enough bytes. ++ ++For example, the device file @file{/dev/urandom} could be used as the ++source of random data. Typically, this device gathers environmental ++noise from device drivers and other sources into an entropy pool, and ++uses the pool to generate random bits. If the pool is short of data, ++the device reuses the internal pool to produce more bits, using a ++cryptographically secure pseudorandom number generator. But be aware ++that this device is not designed for bulk random data generation ++and is relatively slow. ++ ++@file{/dev/urandom} suffices for most practical uses, but applications ++requiring high-value or long-term protection of private data may ++require an alternate data source like @file{/dev/random} or ++@file{/dev/arandom}. The set of available sources depends on your ++operating system. ++ ++To reproduce the results of an earlier invocation of a command, you ++can save some random data into a file and then use that file as the ++random source in earlier and later invocations of the command. ++ ++@node Target directory ++@section Target directory ++ ++@cindex target directory ++ ++The @command{cp}, @command{install}, @command{ln}, and @command{mv} ++commands normally treat the last operand specially when it is a ++directory or a symbolic link to a directory. For example, @samp{cp ++source dest} is equivalent to @samp{cp source dest/source} if ++@file{dest} is a directory. Sometimes this behavior is not exactly ++what is wanted, so these commands support the following options to ++allow more fine-grained control: ++ ++@table @samp ++ ++@item -T ++@itemx --no-target-directory ++@opindex --no-target-directory ++@cindex target directory ++@cindex destination directory ++Do not treat the last operand specially when it is a directory or a ++symbolic link to a directory. This can help avoid race conditions in ++programs that operate in a shared area. For example, when the command ++@samp{mv /tmp/source /tmp/dest} succeeds, there is no guarantee that ++@file{/tmp/source} was renamed to @file{/tmp/dest}: it could have been ++renamed to @file{/tmp/dest/source} instead, if some other process ++created @file{/tmp/dest} as a directory. However, if @file{mv ++-T /tmp/source /tmp/dest} succeeds, there is no ++question that @file{/tmp/source} was renamed to @file{/tmp/dest}. ++ ++In the opposite situation, where you want the last operand to be ++treated as a directory and want a diagnostic otherwise, you can use ++the @option{--target-directory} (@option{-t}) option. ++ ++@item -t @var{directory} ++@itemx @w{@kbd{--target-directory}=@var{directory}} ++@opindex --target-directory ++@cindex target directory ++@cindex destination directory ++Use @var{directory} as the directory component of each destination ++file name. ++ ++The interface for most programs is that after processing options and a ++finite (possibly zero) number of fixed-position arguments, the remaining ++argument list is either expected to be empty, or is a list of items ++(usually files) that will all be handled identically. The @command{xargs} ++program is designed to work well with this convention. ++ ++The commands in the @command{mv}-family are unusual in that they take ++a variable number of arguments with a special case at the @emph{end} ++(namely, the target directory). This makes it nontrivial to perform some ++operations, e.g., ``move all files from here to ../d/'', because ++@code{mv * ../d/} might exhaust the argument space, and @code{ls | xargs ...} ++doesn't have a clean way to specify an extra final argument for each ++invocation of the subject command. (It can be done by going through a ++shell command, but that requires more human labor and brain power than ++it should.) ++ ++The @w{@kbd{--target-directory}} (@option{-t}) option allows the @command{cp}, ++@command{install}, @command{ln}, and @command{mv} programs to be used ++conveniently with @command{xargs}. For example, you can move the files ++from the current directory to a sibling directory, @code{d} like this: ++ ++@smallexample ++ls | xargs mv -t ../d -- ++@end smallexample ++ ++However, this doesn't move files whose names begin with @samp{.}. ++If you use the @sc{gnu} @command{find} program, you can move those ++files too, with this command: ++ ++@example ++find . -mindepth 1 -maxdepth 1 \ ++ | xargs mv -t ../d ++@end example ++ ++But both of the above approaches fail if there are no files in the ++current directory, or if any file has a name containing a blank or ++some other special characters. ++The following example removes those limitations and requires both ++@sc{gnu} @command{find} and @sc{gnu} @command{xargs}: ++ ++@example ++find . -mindepth 1 -maxdepth 1 -print0 \ ++ | xargs --null --no-run-if-empty \ ++ mv -t ../d ++@end example ++ ++@end table ++ ++@noindent ++The @option{--target-directory} (@option{-t}) and ++@option{--no-target-directory} (@option{-T}) ++options cannot be combined. ++ ++@node Trailing slashes ++@section Trailing slashes ++ ++@cindex trailing slashes ++ ++Some @sc{gnu} programs (at least @command{cp} and @command{mv}) allow you to ++remove any trailing slashes from each @var{source} argument before ++operating on it. The @w{@kbd{--strip-trailing-slashes}} option enables ++this behavior. ++ ++This is useful when a @var{source} argument may have a trailing slash and ++@c FIXME: mv's behavior in this case is system-dependent ++specify a symbolic link to a directory. This scenario is in fact rather ++common because some shells can automatically append a trailing slash when ++performing file name completion on such symbolic links. Without this ++option, @command{mv}, for example, (via the system's rename function) must ++interpret a trailing slash as a request to dereference the symbolic link ++and so must rename the indirectly referenced @emph{directory} and not ++the symbolic link. Although it may seem surprising that such behavior ++be the default, it is required by @acronym{POSIX} and is consistent with ++other parts of that standard. ++ ++@node Traversing symlinks ++@section Traversing symlinks ++ ++@cindex symbolic link to directory, controlling traversal of ++ ++The following options modify how @command{chown} and @command{chgrp} ++@c FIXME: note that `du' has these options, too, but they have slightly ++@c different meaning. ++traverse a hierarchy when the @option{--recursive} (@option{-R}) ++option is also specified. ++If more than one of the following options is specified, only the final ++one takes effect. ++These options specify whether processing a symbolic link to a directory ++entails operating on just the symbolic link or on all files in the ++hierarchy rooted at that directory. ++ ++These options are independent of @option{--dereference} and ++@option{--no-dereference} (@option{-h}), which control whether to modify ++a symlink or its referent. ++ ++@table @samp ++ ++@macro choptH ++@item -H ++@opindex -H ++@cindex symbolic link to directory, traverse each that is specified on the command line ++If @option{--recursive} (@option{-R}) is specified and ++a command line argument is a symbolic link to a directory, traverse it. ++@end macro ++@choptH ++ ++@macro choptL ++@item -L ++@opindex -L ++@cindex symbolic link to directory, traverse each that is encountered ++In a recursive traversal, traverse every symbolic link to a directory ++that is encountered. ++@end macro ++@choptL ++ ++@macro choptP ++@item -P ++@opindex -P ++@cindex symbolic link to directory, never traverse ++Do not traverse any symbolic links. ++This is the default if none of @option{-H}, @option{-L}, ++or @option{-P} is specified. ++@end macro ++@choptP ++ ++@end table ++ ++ ++@node Treating / specially ++@section Treating @file{/} specially ++ ++Certain commands can operate destructively on entire hierarchies. ++For example, if a user with appropriate privileges mistakenly runs ++@samp{rm -rf / tmp/junk}, that may remove ++all files on the entire system. Since there are so few ++legitimate uses for such a command, ++@sc{gnu} @command{rm} normally declines to operate on any directory ++that resolves to @file{/}. If you really want to try to remove all ++the files on your system, you can use the @option{--no-preserve-root} ++option, but the default behavior, specified by the ++@option{--preserve-option}, is safer for most purposes. ++ ++The commands @command{chgrp}, @command{chmod} and @command{chown} ++can also operate destructively on entire hierarchies, so they too ++support these options. Although, unlike @command{rm}, they don't ++actually unlink files, these commands are arguably more dangerous ++when operating recursively on @file{/}, since they often work much ++more quickly, and hence damage more files before an alert user can ++interrupt them. Tradition and @acronym{POSIX} require these commands ++to operate recursively on @file{/}, so they default to ++@option{--no-preserve-root}, but using the @option{--preserve-root} ++option makes them safer for most purposes. For convenience you can ++specify @option{--preserve-root} in an alias or in a shell function. ++ ++Note that the @option{--preserve-root} option also ensures ++that @command{chgrp} and @command{chown} do not modify @file{/} ++even when dereferencing a symlink pointing to @file{/}. ++ ++@node Special built-in utilities ++@section Special built-in utilities ++ ++Some programs like @command{nice} can invoke other programs; for ++example, the command @samp{nice cat file} invokes the program ++@command{cat} by executing the command @samp{cat file}. However, ++@dfn{special built-in utilities} like @command{exit} cannot be invoked ++this way. For example, the command @samp{nice exit} does not have a ++well-defined behavior: it may generate an error message instead of ++exiting. ++ ++Here is a list of the special built-in utilities that are standardized ++by @acronym{POSIX} 1003.1-2004. ++ ++@quotation ++@t{.@: : break continue eval exec exit export readonly ++return set shift times trap unset} ++@end quotation ++ ++For example, because @samp{.}, @samp{:}, and @samp{exec} are special, ++the commands @samp{nice . foo.sh}, @samp{nice :}, and @samp{nice exec ++pwd} do not work as you might expect. ++ ++Many shells extend this list. For example, Bash has several extra ++special built-in utilities like @command{history}, and ++@command{suspend}, and with Bash the command @samp{nice suspend} ++generates an error message instead of suspending. ++ ++@node Standards conformance ++@section Standards conformance ++ ++@vindex POSIXLY_CORRECT ++In a few cases, the @sc{gnu} utilities' default behavior is ++incompatible with the @acronym{POSIX} standard. To suppress these ++incompatibilities, define the @env{POSIXLY_CORRECT} environment ++variable. Unless you are checking for @acronym{POSIX} conformance, you ++probably do not need to define @env{POSIXLY_CORRECT}. ++ ++Newer versions of @acronym{POSIX} are occasionally incompatible with older ++versions. For example, older versions of @acronym{POSIX} required the ++command @samp{sort +1} to sort based on the second and succeeding ++fields in each input line, but starting with @acronym{POSIX} 1003.1-2001 ++the same command is required to sort the file named @file{+1}, and you ++must instead use the command @samp{sort -k 2} to get the field-based ++sort. ++ ++@vindex _POSIX2_VERSION ++The @sc{gnu} utilities normally conform to the version of @acronym{POSIX} ++that is standard for your system. To cause them to conform to a ++different version of @acronym{POSIX}, define the @env{_POSIX2_VERSION} ++environment variable to a value of the form @var{yyyymm} specifying ++the year and month the standard was adopted. Two values are currently ++supported for @env{_POSIX2_VERSION}: @samp{199209} stands for ++@acronym{POSIX} 1003.2-1992, and @samp{200112} stands for @acronym{POSIX} ++1003.1-2001. For example, if you have a newer system but are running software ++that assumes an older version of @acronym{POSIX} and uses @samp{sort +1} ++or @samp{tail +10}, you can work around any compatibility problems by setting ++@samp{_POSIX2_VERSION=199209} in your environment. ++ ++@node Output of entire files ++@chapter Output of entire files ++ ++@cindex output of entire files ++@cindex entire files, output of ++ ++These commands read and write entire files, possibly transforming them ++in some way. ++ ++@menu ++* cat invocation:: Concatenate and write files. ++* tac invocation:: Concatenate and write files in reverse. ++* nl invocation:: Number lines and write files. ++* od invocation:: Write files in octal or other formats. ++* base64 invocation:: Transform data into printable data. ++@end menu ++ ++@node cat invocation ++@section @command{cat}: Concatenate and write files ++ ++@pindex cat ++@cindex concatenate and write files ++@cindex copying files ++ ++@command{cat} copies each @var{file} (@samp{-} means standard input), or ++standard input if none are given, to standard output. Synopsis: ++ ++@example ++cat [@var{option}] [@var{file}]@dots{} ++@end example ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -A ++@itemx --show-all ++@opindex -A ++@opindex --show-all ++Equivalent to @option{-vET}. ++ ++@item -b ++@itemx --number-nonblank ++@opindex -b ++@opindex --number-nonblank ++Number all nonempty output lines, starting with 1. ++ ++@item -e ++@opindex -e ++Equivalent to @option{-vE}. ++ ++@item -E ++@itemx --show-ends ++@opindex -E ++@opindex --show-ends ++Display a @samp{$} after the end of each line. ++ ++@item -n ++@itemx --number ++@opindex -n ++@opindex --number ++Number all output lines, starting with 1. ++ ++@item -s ++@itemx --squeeze-blank ++@opindex -s ++@opindex --squeeze-blank ++@cindex squeezing empty lines ++Suppress repeated adjacent empty lines; output just one empty line ++instead of several. ++ ++@item -t ++@opindex -t ++Equivalent to @option{-vT}. ++ ++@item -T ++@itemx --show-tabs ++@opindex -T ++@opindex --show-tabs ++Display TAB characters as @samp{^I}. ++ ++@item -u ++@opindex -u ++Ignored; for @acronym{POSIX} compatibility. ++ ++@item -v ++@itemx --show-nonprinting ++@opindex -v ++@opindex --show-nonprinting ++Display control characters except for LFD and TAB using ++@samp{^} notation and precede characters that have the high bit set with ++@samp{M-}. ++ ++@end table ++ ++On systems like MS-DOS that distinguish between text and binary files, ++@command{cat} normally reads and writes in binary mode. However, ++@command{cat} reads in text mode if one of the options ++@option{-bensAE} is used or if @command{cat} is reading from standard ++input and standard input is a terminal. Similarly, @command{cat} ++writes in text mode if one of the options @option{-bensAE} is used or ++if standard output is a terminal. ++ ++@exitstatus ++ ++Examples: ++ ++@smallexample ++# Output f's contents, then standard input, then g's contents. ++cat f - g ++ ++# Copy standard input to standard output. ++cat ++@end smallexample ++ ++ ++@node tac invocation ++@section @command{tac}: Concatenate and write files in reverse ++ ++@pindex tac ++@cindex reversing files ++ ++@command{tac} copies each @var{file} (@samp{-} means standard input), or ++standard input if none are given, to standard output, reversing the ++records (lines by default) in each separately. Synopsis: ++ ++@example ++tac [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++@dfn{Records} are separated by instances of a string (newline by ++default). By default, this separator string is attached to the end of ++the record that it follows in the file. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -b ++@itemx --before ++@opindex -b ++@opindex --before ++The separator is attached to the beginning of the record that it ++precedes in the file. ++ ++@item -r ++@itemx --regex ++@opindex -r ++@opindex --regex ++Treat the separator string as a regular expression. Users of @command{tac} ++on MS-DOS/MS-Windows should note that, since @command{tac} reads files in ++binary mode, each line of a text file might end with a CR/LF pair ++instead of the Unix-style LF. ++ ++@item -s @var{separator} ++@itemx --separator=@var{separator} ++@opindex -s ++@opindex --separator ++Use @var{separator} as the record separator, instead of newline. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node nl invocation ++@section @command{nl}: Number lines and write files ++ ++@pindex nl ++@cindex numbering lines ++@cindex line numbering ++ ++@command{nl} writes each @var{file} (@samp{-} means standard input), or ++standard input if none are given, to standard output, with line numbers ++added to some or all of the lines. Synopsis: ++ ++@example ++nl [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++@cindex logical pages, numbering on ++@command{nl} decomposes its input into (logical) pages; by default, the ++line number is reset to 1 at the top of each logical page. @command{nl} ++treats all of the input files as a single document; it does not reset ++line numbers or logical pages between files. ++ ++@cindex headers, numbering ++@cindex body, numbering ++@cindex footers, numbering ++A logical page consists of three sections: header, body, and footer. ++Any of the sections can be empty. Each can be numbered in a different ++style from the others. ++ ++The beginnings of the sections of logical pages are indicated in the ++input file by a line containing exactly one of these delimiter strings: ++ ++@table @samp ++@item \:\:\: ++start of header; ++@item \:\: ++start of body; ++@item \: ++start of footer. ++@end table ++ ++The two characters from which these strings are made can be changed from ++@samp{\} and @samp{:} via options (see below), but the pattern and ++length of each string cannot be changed. ++ ++A section delimiter is replaced by an empty line on output. Any text ++that comes before the first section delimiter string in the input file ++is considered to be part of a body section, so @command{nl} treats a ++file that contains no section delimiters as a single body section. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -b @var{style} ++@itemx --body-numbering=@var{style} ++@opindex -b ++@opindex --body-numbering ++Select the numbering style for lines in the body section of each ++logical page. When a line is not numbered, the current line number ++is not incremented, but the line number separator character is still ++prepended to the line. The styles are: ++ ++@table @samp ++@item a ++number all lines, ++@item t ++number only nonempty lines (default for body), ++@item n ++do not number lines (default for header and footer), ++@item p@var{bre} ++number only lines that contain a match for the basic regular ++expression @var{bre}. ++@xref{Regular Expressions, , Regular Expressions, grep, The GNU Grep Manual}. ++@end table ++ ++@item -d @var{cd} ++@itemx --section-delimiter=@var{cd} ++@opindex -d ++@opindex --section-delimiter ++@cindex section delimiters of pages ++Set the section delimiter characters to @var{cd}; default is ++@samp{\:}. If only @var{c} is given, the second remains @samp{:}. ++(Remember to protect @samp{\} or other metacharacters from shell ++expansion with quotes or extra backslashes.) ++ ++@item -f @var{style} ++@itemx --footer-numbering=@var{style} ++@opindex -f ++@opindex --footer-numbering ++Analogous to @option{--body-numbering}. ++ ++@item -h @var{style} ++@itemx --header-numbering=@var{style} ++@opindex -h ++@opindex --header-numbering ++Analogous to @option{--body-numbering}. ++ ++@item -i @var{number} ++@itemx --line-increment=@var{number} ++@opindex -i ++@opindex --line-increment ++Increment line numbers by @var{number} (default 1). ++ ++@item -l @var{number} ++@itemx --join-blank-lines=@var{number} ++@opindex -l ++@opindex --join-blank-lines ++@cindex empty lines, numbering ++@cindex blank lines, numbering ++Consider @var{number} (default 1) consecutive empty lines to be one ++logical line for numbering, and only number the last one. Where fewer ++than @var{number} consecutive empty lines occur, do not number them. ++An empty line is one that contains no characters, not even spaces ++or tabs. ++ ++@item -n @var{format} ++@itemx --number-format=@var{format} ++@opindex -n ++@opindex --number-format ++Select the line numbering format (default is @code{rn}): ++ ++@table @samp ++@item ln ++@opindex ln @r{format for @command{nl}} ++left justified, no leading zeros; ++@item rn ++@opindex rn @r{format for @command{nl}} ++right justified, no leading zeros; ++@item rz ++@opindex rz @r{format for @command{nl}} ++right justified, leading zeros. ++@end table ++ ++@item -p ++@itemx --no-renumber ++@opindex -p ++@opindex --no-renumber ++Do not reset the line number at the start of a logical page. ++ ++@item -s @var{string} ++@itemx --number-separator=@var{string} ++@opindex -s ++@opindex --number-separator ++Separate the line number from the text line in the output with ++@var{string} (default is the TAB character). ++ ++@item -v @var{number} ++@itemx --starting-line-number=@var{number} ++@opindex -v ++@opindex --starting-line-number ++Set the initial line number on each logical page to @var{number} (default 1). ++ ++@item -w @var{number} ++@itemx --number-width=@var{number} ++@opindex -w ++@opindex --number-width ++Use @var{number} characters for line numbers (default 6). ++ ++@end table ++ ++@exitstatus ++ ++ ++@node od invocation ++@section @command{od}: Write files in octal or other formats ++ ++@pindex od ++@cindex octal dump of files ++@cindex hex dump of files ++@cindex ASCII dump of files ++@cindex file contents, dumping unambiguously ++ ++@command{od} writes an unambiguous representation of each @var{file} ++(@samp{-} means standard input), or standard input if none are given. ++Synopses: ++ ++@smallexample ++od [@var{option}]@dots{} [@var{file}]@dots{} ++od [-abcdfilosx]@dots{} [@var{file}] [[+]@var{offset}[.][b]] ++od [@var{option}]@dots{} --traditional [@var{file}] [[+]@var{offset}[.][b] [[+]@var{label}[.][b]]] ++@end smallexample ++ ++Each line of output consists of the offset in the input, followed by ++groups of data from the file. By default, @command{od} prints the offset in ++octal, and each group of file data is a C @code{short int}'s worth of input ++printed as a single octal number. ++ ++If @var{offset} is given, it specifies how many input bytes to skip ++before formatting and writing. By default, it is interpreted as an ++octal number, but the optional trailing decimal point causes it to be ++interpreted as decimal. If no decimal is specified and the offset ++begins with @samp{0x} or @samp{0X} it is interpreted as a hexadecimal ++number. If there is a trailing @samp{b}, the number of bytes skipped ++will be @var{offset} multiplied by 512. ++ ++If a command is of both the first and second forms, the second form is ++assumed if the last operand begins with @samp{+} or (if there are two ++operands) a digit. For example, in @samp{od foo 10} and @samp{od +10} ++the @samp{10} is an offset, whereas in @samp{od 10} the @samp{10} is a ++file name. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -A @var{radix} ++@itemx --address-radix=@var{radix} ++@opindex -A ++@opindex --address-radix ++@cindex radix for file offsets ++@cindex file offset radix ++Select the base in which file offsets are printed. @var{radix} can ++be one of the following: ++ ++@table @samp ++@item d ++decimal; ++@item o ++octal; ++@item x ++hexadecimal; ++@item n ++none (do not print offsets). ++@end table ++ ++The default is octal. ++ ++@item -j @var{bytes} ++@itemx --skip-bytes=@var{bytes} ++@opindex -j ++@opindex --skip-bytes ++Skip @var{bytes} input bytes before formatting and writing. If ++@var{bytes} begins with @samp{0x} or @samp{0X}, it is interpreted in ++hexadecimal; otherwise, if it begins with @samp{0}, in octal; otherwise, ++in decimal. ++@multiplierSuffixes{bytes} ++ ++@item -N @var{bytes} ++@itemx --read-bytes=@var{bytes} ++@opindex -N ++@opindex --read-bytes ++Output at most @var{bytes} bytes of the input. Prefixes and suffixes on ++@code{bytes} are interpreted as for the @option{-j} option. ++ ++@item -S @var{bytes} ++@itemx --strings[=@var{bytes}] ++@opindex -S ++@opindex --strings ++@cindex string constants, outputting ++Instead of the normal output, output only @dfn{string constants}: at ++least @var{bytes} consecutive @acronym{ASCII} graphic characters, ++followed by a zero byte (@acronym{ASCII} @sc{nul}). ++Prefixes and suffixes on @code{bytes} are interpreted as for the ++@option{-j} option. ++ ++If @var{n} is omitted with @option{--strings}, the default is 3. ++ ++@item -t @var{type} ++@itemx --format=@var{type} ++@opindex -t ++@opindex --format ++Select the format in which to output the file data. @var{type} is a ++string of one or more of the below type indicator characters. If you ++include more than one type indicator character in a single @var{type} ++string, or use this option more than once, @command{od} writes one copy ++of each output line using each of the data types that you specified, ++in the order that you specified. ++ ++Adding a trailing ``z'' to any type specification appends a display ++of the @acronym{ASCII} character representation of the printable characters ++to the output line generated by the type specification. ++ ++@table @samp ++@item a ++named character, ignoring high-order bit ++@item c ++@acronym{ASCII} character or backslash escape, ++@item d ++signed decimal ++@item f ++floating point ++@item o ++octal ++@item u ++unsigned decimal ++@item x ++hexadecimal ++@end table ++ ++The type @code{a} outputs things like @samp{sp} for space, @samp{nl} for ++newline, and @samp{nul} for a zero byte. Only the least significant ++seven bits of each byte is used; the high-order bit is ignored. ++Type @code{c} outputs ++@samp{ }, @samp{\n}, and @code{\0}, respectively. ++ ++@cindex type size ++Except for types @samp{a} and @samp{c}, you can specify the number ++of bytes to use in interpreting each number in the given data type ++by following the type indicator character with a decimal integer. ++Alternately, you can specify the size of one of the C compiler's ++built-in data types by following the type indicator character with ++one of the following characters. For integers (@samp{d}, @samp{o}, ++@samp{u}, @samp{x}): ++ ++@table @samp ++@item C ++char ++@item S ++short ++@item I ++int ++@item L ++long ++@end table ++ ++For floating point (@code{f}): ++ ++@table @asis ++@item F ++float ++@item D ++double ++@item L ++long double ++@end table ++ ++@item -v ++@itemx --output-duplicates ++@opindex -v ++@opindex --output-duplicates ++Output consecutive lines that are identical. By default, when two or ++more consecutive output lines would be identical, @command{od} outputs only ++the first line, and puts just an asterisk on the following line to ++indicate the elision. ++ ++@item -w[@var{n}] ++@itemx --width[=@var{n}] ++@opindex -w ++@opindex --width ++Dump @code{n} input bytes per output line. This must be a multiple of ++the least common multiple of the sizes associated with the specified ++output types. ++ ++If this option is not given at all, the default is 16. If @var{n} is ++omitted, the default is 32. ++ ++@end table ++ ++The next several options are shorthands for format specifications. ++@sc{gnu} @command{od} accepts any combination of shorthands and format ++specification options. These options accumulate. ++ ++@table @samp ++ ++@item -a ++@opindex -a ++Output as named characters. Equivalent to @samp{-t a}. ++ ++@item -b ++@opindex -b ++Output as octal bytes. Equivalent to @samp{-t o1}. ++ ++@item -c ++@opindex -c ++Output as @acronym{ASCII} characters or backslash escapes. Equivalent to ++@samp{-t c}. ++ ++@item -d ++@opindex -d ++Output as unsigned decimal two-byte units. Equivalent to @samp{-t u2}. ++ ++@item -f ++@opindex -f ++Output as floats. Equivalent to @samp{-t fF}. ++ ++@item -i ++@opindex -i ++Output as decimal ints. Equivalent to @samp{-t dI}. ++ ++@item -l ++@opindex -l ++Output as decimal long ints. Equivalent to @samp{-t dL}. ++ ++@item -o ++@opindex -o ++Output as octal two-byte units. Equivalent to @option{-t o2}. ++ ++@item -s ++@opindex -s ++Output as decimal two-byte units. Equivalent to @option{-t d2}. ++ ++@item -x ++@opindex -x ++Output as hexadecimal two-byte units. Equivalent to @samp{-t x2}. ++ ++@item --traditional ++@opindex --traditional ++Recognize the non-option label argument that traditional @command{od} ++accepted. The following syntax: ++ ++@smallexample ++od --traditional [@var{file}] [[+]@var{offset}[.][b] [[+]@var{label}[.][b]]] ++@end smallexample ++ ++@noindent ++can be used to specify at most one file and optional arguments ++specifying an offset and a pseudo-start address, @var{label}. ++The @var{label} argument is interpreted ++just like @var{offset}, but it specifies an initial pseudo-address. The ++pseudo-addresses are displayed in parentheses following any normal ++address. ++ ++@end table ++ ++@exitstatus ++ ++@node base64 invocation ++@section @command{base64}: Transform data into printable data ++ ++@pindex base64 ++@cindex base64 encoding ++ ++@command{base64} transforms data read from a file, or standard input, ++into (or from) base64 encoded form. The base64 encoded form uses ++printable @acronym{ASCII} characters to represent binary data. ++Synopses: ++ ++@smallexample ++base64 [@var{option}]@dots{} [@var{file}] ++base64 --decode [@var{option}]@dots{} [@var{file}] ++@end smallexample ++ ++The base64 encoding expands data to roughly 133% of the original. ++The format conforms to ++@uref{ftp://ftp.rfc-editor.org/in-notes/rfc4648.txt, RFC 4648}. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -w @var{cols} ++@itemx --wrap=@var{cols} ++@opindex -w ++@opindex --wrap ++@cindex wrap data ++@cindex column to wrap data after ++During encoding, wrap lines after @var{cols} characters. This must be ++a positive number. ++ ++The default is to wrap after 76 characters. Use the value 0 to ++disable line wrapping altogether. ++ ++@item -d ++@itemx --decode ++@opindex -d ++@opindex --decode ++@cindex Decode base64 data ++@cindex Base64 decoding ++Change the mode of operation, from the default of encoding data, to ++decoding data. Input is expected to be base64 encoded data, and the ++output will be the original data. ++ ++@item -i ++@itemx --ignore-garbage ++@opindex -i ++@opindex --ignore-garbage ++@cindex Ignore garbage in base64 stream ++When decoding, newlines are always accepted. ++During decoding, ignore unrecognized bytes, ++to permit distorted data to be decoded. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node Formatting file contents ++@chapter Formatting file contents ++ ++@cindex formatting file contents ++ ++These commands reformat the contents of files. ++ ++@menu ++* fmt invocation:: Reformat paragraph text. ++* pr invocation:: Paginate or columnate files for printing. ++* fold invocation:: Wrap input lines to fit in specified width. ++@end menu ++ ++ ++@node fmt invocation ++@section @command{fmt}: Reformat paragraph text ++ ++@pindex fmt ++@cindex reformatting paragraph text ++@cindex paragraphs, reformatting ++@cindex text, reformatting ++ ++@command{fmt} fills and joins lines to produce output lines of (at most) ++a given number of characters (75 by default). Synopsis: ++ ++@example ++fmt [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++@command{fmt} reads from the specified @var{file} arguments (or standard ++input if none are given), and writes to standard output. ++ ++By default, blank lines, spaces between words, and indentation are ++preserved in the output; successive input lines with different ++indentation are not joined; tabs are expanded on input and introduced on ++output. ++ ++@cindex line-breaking ++@cindex sentences and line-breaking ++@cindex Knuth, Donald E. ++@cindex Plass, Michael F. ++@command{fmt} prefers breaking lines at the end of a sentence, and tries to ++avoid line breaks after the first word of a sentence or before the last ++word of a sentence. A @dfn{sentence break} is defined as either the end ++of a paragraph or a word ending in any of @samp{.?!}, followed by two ++spaces or end of line, ignoring any intervening parentheses or quotes. ++Like @TeX{}, @command{fmt} reads entire ``paragraphs'' before choosing line ++breaks; the algorithm is a variant of that given by Donald E. Knuth ++and Michael F. Plass in ``Breaking Paragraphs Into Lines'', ++@cite{Software---Practice & Experience} @b{11}, 11 (November 1981), ++1119--1184. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -c ++@itemx --crown-margin ++@opindex -c ++@opindex --crown-margin ++@cindex crown margin ++@dfn{Crown margin} mode: preserve the indentation of the first two ++lines within a paragraph, and align the left margin of each subsequent ++line with that of the second line. ++ ++@item -t ++@itemx --tagged-paragraph ++@opindex -t ++@opindex --tagged-paragraph ++@cindex tagged paragraphs ++@dfn{Tagged paragraph} mode: like crown margin mode, except that if ++indentation of the first line of a paragraph is the same as the ++indentation of the second, the first line is treated as a one-line ++paragraph. ++ ++@item -s ++@itemx --split-only ++@opindex -s ++@opindex --split-only ++Split lines only. Do not join short lines to form longer ones. This ++prevents sample lines of code, and other such ``formatted'' text from ++being unduly combined. ++ ++@item -u ++@itemx --uniform-spacing ++@opindex -u ++@opindex --uniform-spacing ++Uniform spacing. Reduce spacing between words to one space, and spacing ++between sentences to two spaces. ++ ++@item -@var{width} ++@itemx -w @var{width} ++@itemx --width=@var{width} ++@opindex -@var{width} ++@opindex -w ++@opindex --width ++Fill output lines up to @var{width} characters (default 75). @command{fmt} ++initially tries to make lines about 7% shorter than this, to give it ++room to balance line lengths. ++ ++@item -p @var{prefix} ++@itemx --prefix=@var{prefix} ++Only lines beginning with @var{prefix} (possibly preceded by whitespace) ++are subject to formatting. The prefix and any preceding whitespace are ++stripped for the formatting and then re-attached to each formatted output ++line. One use is to format certain kinds of program comments, while ++leaving the code unchanged. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node pr invocation ++@section @command{pr}: Paginate or columnate files for printing ++ ++@pindex pr ++@cindex printing, preparing files for ++@cindex multicolumn output, generating ++@cindex merging files in parallel ++ ++@command{pr} writes each @var{file} (@samp{-} means standard input), or ++standard input if none are given, to standard output, paginating and ++optionally outputting in multicolumn format; optionally merges all ++@var{file}s, printing all in parallel, one per column. Synopsis: ++ ++@example ++pr [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++@vindex LC_MESSAGES ++By default, a 5-line header is printed at each page: two blank lines; ++a line with the date, the file name, and the page count; and two more ++blank lines. A footer of five blank lines is also printed. ++The default @var{page_length} is 66 ++lines. The default number of text lines is therefore 56. ++The text line of the header takes the form ++@samp{@var{date} @var{string} @var{page}}, with spaces inserted around ++@var{string} so that the line takes up the full @var{page_width}. Here, ++@var{date} is the date (see the @option{-D} or @option{--date-format} ++option for details), @var{string} is the centered header string, and ++@var{page} identifies the page number. The @env{LC_MESSAGES} locale ++category affects the spelling of @var{page}; in the default C locale, it ++is @samp{Page @var{number}} where @var{number} is the decimal page ++number. ++ ++Form feeds in the input cause page breaks in the output. Multiple form ++feeds produce empty pages. ++ ++Columns are of equal width, separated by an optional string (default ++is @samp{space}). For multicolumn output, lines will always be truncated to ++@var{page_width} (default 72), unless you use the @option{-J} option. ++For single ++column output no line truncation occurs by default. Use @option{-W} option to ++truncate lines in that case. ++ ++The following changes were made in version 1.22i and apply to later ++versions of @command{pr}: ++@c FIXME: this whole section here sounds very awkward to me. I ++@c made a few small changes, but really it all needs to be redone. - Brian ++@c OK, I fixed another sentence or two, but some of it I just don't understand. ++@ - Brian ++@itemize @bullet ++ ++@item ++Some small @var{letter options} (@option{-s}, @option{-w}) have been ++redefined for better @acronym{POSIX} compliance. The output of some further ++cases has been adapted to other Unix systems. These changes are not ++compatible with earlier versions of the program. ++ ++@item ++Some @var{new capital letter} options (@option{-J}, @option{-S}, @option{-W}) ++have been introduced to turn off unexpected interferences of small letter ++options. The @option{-N} option and the second argument @var{last_page} ++of @samp{+FIRST_PAGE} offer more flexibility. The detailed handling of ++form feeds set in the input files requires the @option{-T} option. ++ ++@item ++Capital letter options override small letter ones. ++ ++@item ++Some of the option-arguments (compare @option{-s}, @option{-e}, ++@option{-i}, @option{-n}) cannot be specified as separate arguments from the ++preceding option letter (already stated in the @acronym{POSIX} specification). ++@end itemize ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item +@var{first_page}[:@var{last_page}] ++@itemx --pages=@var{first_page}[:@var{last_page}] ++@c The two following @opindex lines evoke warnings because they contain `:' ++@c The `info' spec does not permit that. If we use those lines, we end ++@c up with truncated index entries that don't work. ++@c @opindex +@var{first_page}[:@var{last_page}] ++@c @opindex --pages=@var{first_page}[:@var{last_page}] ++@opindex +@var{page_range} ++@opindex --pages=@var{page_range} ++Begin printing with page @var{first_page} and stop with @var{last_page}. ++Missing @samp{:@var{last_page}} implies end of file. While estimating ++the number of skipped pages each form feed in the input file results ++in a new page. Page counting with and without @samp{+@var{first_page}} ++is identical. By default, counting starts with the first page of input ++file (not first page printed). Line numbering may be altered by @option{-N} ++option. ++ ++@item -@var{column} ++@itemx --columns=@var{column} ++@opindex -@var{column} ++@opindex --columns ++@cindex down columns ++With each single @var{file}, produce @var{column} columns of output ++(default is 1) and print columns down, unless @option{-a} is used. The ++column width is automatically decreased as @var{column} increases; unless ++you use the @option{-W/-w} option to increase @var{page_width} as well. ++This option might well cause some lines to be truncated. The number of ++lines in the columns on each page are balanced. The options @option{-e} ++and @option{-i} are on for multiple text-column output. Together with ++@option{-J} option column alignment and line truncation is turned off. ++Lines of full length are joined in a free field format and @option{-S} ++option may set field separators. @option{-@var{column}} may not be used ++with @option{-m} option. ++ ++@item -a ++@itemx --across ++@opindex -a ++@opindex --across ++@cindex across columns ++With each single @var{file}, print columns across rather than down. The ++@option{-@var{column}} option must be given with @var{column} greater than one. ++If a line is too long to fit in a column, it is truncated. ++ ++@item -c ++@itemx --show-control-chars ++@opindex -c ++@opindex --show-control-chars ++Print control characters using hat notation (e.g., @samp{^G}); print ++other nonprinting characters in octal backslash notation. By default, ++nonprinting characters are not changed. ++ ++@item -d ++@itemx --double-space ++@opindex -d ++@opindex --double-space ++@cindex double spacing ++Double space the output. ++ ++@item -D @var{format} ++@itemx --date-format=@var{format} ++@cindex time formats ++@cindex formatting times ++Format header dates using @var{format}, using the same conventions as ++for the command @samp{date +@var{format}}; @xref{date invocation}. ++Except for directives, which start with ++@samp{%}, characters in @var{format} are printed unchanged. You can use ++this option to specify an arbitrary string in place of the header date, ++e.g., @option{--date-format="Monday morning"}. ++ ++@vindex POSIXLY_CORRECT ++@vindex LC_TIME ++The default date format is @samp{%Y-%m-%d %H:%M} (for example, ++@samp{2001-12-04 23:59}); ++but if the @env{POSIXLY_CORRECT} environment variable is set ++and the @env{LC_TIME} locale category specifies the @acronym{POSIX} ++locale, the default is @samp{%b %e %H:%M %Y} (for example, ++@samp{Dec@ @ 4 23:59 2001}. ++ ++@vindex TZ ++Time stamps are listed according to the time zone rules specified by ++the @env{TZ} environment variable, or by the system default rules if ++@env{TZ} is not set. @xref{TZ Variable,, Specifying the Time Zone ++with @env{TZ}, libc, The GNU C Library Reference Manual}. ++ ++@item -e[@var{in-tabchar}[@var{in-tabwidth}]] ++@itemx --expand-tabs[=@var{in-tabchar}[@var{in-tabwidth}]] ++@opindex -e ++@opindex --expand-tabs ++@cindex input tabs ++Expand @var{tab}s to spaces on input. Optional argument @var{in-tabchar} is ++the input tab character (default is the TAB character). Second optional ++argument @var{in-tabwidth} is the input tab character's width (default ++is 8). ++ ++@item -f ++@itemx -F ++@itemx --form-feed ++@opindex -F ++@opindex -f ++@opindex --form-feed ++Use a form feed instead of newlines to separate output pages. This does ++not alter the default page length of 66 lines. ++ ++@item -h @var{header} ++@itemx --header=@var{header} ++@opindex -h ++@opindex --header ++Replace the file name in the header with the centered string @var{header}. ++When using the shell, @var{header} should be quoted and should be ++separated from @option{-h} by a space. ++ ++@item -i[@var{out-tabchar}[@var{out-tabwidth}]] ++@itemx --output-tabs[=@var{out-tabchar}[@var{out-tabwidth}]] ++@opindex -i ++@opindex --output-tabs ++@cindex output tabs ++Replace spaces with @var{tab}s on output. Optional argument @var{out-tabchar} ++is the output tab character (default is the TAB character). Second optional ++argument @var{out-tabwidth} is the output tab character's width (default ++is 8). ++ ++@item -J ++@itemx --join-lines ++@opindex -J ++@opindex --join-lines ++Merge lines of full length. Used together with the column options ++@option{-@var{column}}, @option{-a -@var{column}} or @option{-m}. Turns off ++@option{-W/-w} line truncation; ++no column alignment used; may be used with ++@option{--sep-string[=@var{string}]}. @option{-J} has been introduced ++(together with @option{-W} and @option{--sep-string}) ++to disentangle the old (@acronym{POSIX}-compliant) options @option{-w} and ++@option{-s} along with the three column options. ++ ++ ++@item -l @var{page_length} ++@itemx --length=@var{page_length} ++@opindex -l ++@opindex --length ++Set the page length to @var{page_length} (default 66) lines, including ++the lines of the header [and the footer]. If @var{page_length} is less ++than or equal to 10, the header and footer are omitted, as if the ++@option{-t} option had been given. ++ ++@item -m ++@itemx --merge ++@opindex -m ++@opindex --merge ++Merge and print all @var{file}s in parallel, one in each column. If a ++line is too long to fit in a column, it is truncated, unless the @option{-J} ++option is used. @option{--sep-string[=@var{string}]} may be used. ++Empty pages in ++some @var{file}s (form feeds set) produce empty columns, still marked ++by @var{string}. The result is a continuous line numbering and column ++marking throughout the whole merged file. Completely empty merged pages ++show no separators or line numbers. The default header becomes ++@samp{@var{date} @var{page}} with spaces inserted in the middle; this ++may be used with the @option{-h} or @option{--header} option to fill up ++the middle blank part. ++ ++@item -n[@var{number-separator}[@var{digits}]] ++@itemx --number-lines[=@var{number-separator}[@var{digits}]] ++@opindex -n ++@opindex --number-lines ++Provide @var{digits} digit line numbering (default for @var{digits} is ++5). With multicolumn output the number occupies the first @var{digits} ++column positions of each text column or only each line of @option{-m} ++output. With single column output the number precedes each line just as ++@option{-m} does. Default counting of the line numbers starts with the ++first line of the input file (not the first line printed, compare the ++@option{--page} option and @option{-N} option). ++Optional argument @var{number-separator} is the character appended to ++the line number to separate it from the text followed. The default ++separator is the TAB character. In a strict sense a TAB is always ++printed with single column output only. The TAB width varies ++with the TAB position, e.g., with the left @var{margin} specified ++by @option{-o} option. With multicolumn output priority is given to ++@samp{equal width of output columns} (a @acronym{POSIX} specification). ++The TAB width is fixed to the value of the first column and does ++not change with different values of left @var{margin}. That means a ++fixed number of spaces is always printed in the place of the ++@var{number-separator} TAB. The tabification depends upon the output ++position. ++ ++@item -N @var{line_number} ++@itemx --first-line-number=@var{line_number} ++@opindex -N ++@opindex --first-line-number ++Start line counting with the number @var{line_number} at first line of ++first page printed (in most cases not the first line of the input file). ++ ++@item -o @var{margin} ++@itemx --indent=@var{margin} ++@opindex -o ++@opindex --indent ++@cindex indenting lines ++@cindex left margin ++Indent each line with a margin @var{margin} spaces wide (default is zero). ++The total page width is the size of the margin plus the @var{page_width} ++set with the @option{-W/-w} option. A limited overflow may occur with ++numbered single column output (compare @option{-n} option). ++ ++@item -r ++@itemx --no-file-warnings ++@opindex -r ++@opindex --no-file-warnings ++Do not print a warning message when an argument @var{file} cannot be ++opened. (The exit status will still be nonzero, however.) ++ ++@item -s[@var{char}] ++@itemx --separator[=@var{char}] ++@opindex -s ++@opindex --separator ++Separate columns by a single character @var{char}. The default for ++@var{char} is the TAB character without @option{-w} and @samp{no ++character} with @option{-w}. Without @option{-s} the default separator ++@samp{space} is set. @option{-s[char]} turns off line truncation of all ++three column options (@option{-COLUMN}|@option{-a -COLUMN}|@option{-m}) unless ++@option{-w} is set. This is a @acronym{POSIX}-compliant formulation. ++ ++ ++@item -S@var{string} ++@itemx --sep-string[=@var{string}] ++@opindex -S ++@opindex --sep-string ++Use @var{string} to separate output columns. The @option{-S} option doesn't ++affect the @option{-W/-w} option, unlike the @option{-s} option which does. It ++does not affect line truncation or column alignment. ++Without @option{-S}, and with @option{-J}, @command{pr} uses the default output ++separator, TAB@. ++Without @option{-S} or @option{-J}, @command{pr} uses a @samp{space} ++(same as @option{-S"@w{ }"}). @option{--sep-string} with no ++@samp{=@var{string}} is equivalent to @option{--sep-string=""}. ++ ++@item -t ++@itemx --omit-header ++@opindex -t ++@opindex --omit-header ++Do not print the usual header [and footer] on each page, and do not fill ++out the bottom of pages (with blank lines or a form feed). No page ++structure is produced, but form feeds set in the input files are retained. ++The predefined pagination is not changed. @option{-t} or @option{-T} may be ++useful together with other options; e.g.: @option{-t -e4}, expand TAB characters ++in the input file to 4 spaces but don't make any other changes. Use of ++@option{-t} overrides @option{-h}. ++ ++@item -T ++@itemx --omit-pagination ++@opindex -T ++@opindex --omit-pagination ++Do not print header [and footer]. In addition eliminate all form feeds ++set in the input files. ++ ++@item -v ++@itemx --show-nonprinting ++@opindex -v ++@opindex --show-nonprinting ++Print nonprinting characters in octal backslash notation. ++ ++@item -w @var{page_width} ++@itemx --width=@var{page_width} ++@opindex -w ++@opindex --width ++Set page width to @var{page_width} characters for multiple text-column ++output only (default for @var{page_width} is 72). @option{-s[CHAR]} turns ++off the default page width and any line truncation and column alignment. ++Lines of full length are merged, regardless of the column options ++set. No @var{page_width} setting is possible with single column output. ++A @acronym{POSIX}-compliant formulation. ++ ++@item -W @var{page_width} ++@itemx --page_width=@var{page_width} ++@opindex -W ++@opindex --page_width ++Set the page width to @var{page_width} characters. That's valid with and ++without a column option. Text lines are truncated, unless @option{-J} ++is used. Together with one of the three column options ++(@option{-@var{column}}, @option{-a -@var{column}} or @option{-m}) column ++alignment is always used. The separator options @option{-S} or @option{-s} ++don't affect the @option{-W} option. Default is 72 characters. Without ++@option{-W @var{page_width}} and without any of the column options NO line ++truncation is used (defined to keep downward compatibility and to meet ++most frequent tasks). That's equivalent to @option{-W 72 -J}. The header ++line is never truncated. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node fold invocation ++@section @command{fold}: Wrap input lines to fit in specified width ++ ++@pindex fold ++@cindex wrapping long input lines ++@cindex folding long input lines ++ ++@command{fold} writes each @var{file} (@option{-} means standard input), or ++standard input if none are given, to standard output, breaking long ++lines. Synopsis: ++ ++@example ++fold [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++By default, @command{fold} breaks lines wider than 80 columns. The output ++is split into as many lines as necessary. ++ ++@cindex screen columns ++@command{fold} counts screen columns by default; thus, a tab may count more ++than one column, backspace decreases the column count, and carriage ++return sets the column to zero. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -b ++@itemx --bytes ++@opindex -b ++@opindex --bytes ++Count bytes rather than columns, so that tabs, backspaces, and carriage ++returns are each counted as taking up one column, just like other ++characters. ++ ++@item -s ++@itemx --spaces ++@opindex -s ++@opindex --spaces ++Break at word boundaries: the line is broken after the last blank before ++the maximum line length. If the line contains no such blanks, the line ++is broken at the maximum line length as usual. ++ ++@item -w @var{width} ++@itemx --width=@var{width} ++@opindex -w ++@opindex --width ++Use a maximum line length of @var{width} columns instead of 80. ++ ++For compatibility @command{fold} supports an obsolete option syntax ++@option{-@var{width}}. New scripts should use @option{-w @var{width}} ++instead. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node Output of parts of files ++@chapter Output of parts of files ++ ++@cindex output of parts of files ++@cindex parts of files, output of ++ ++These commands output pieces of the input. ++ ++@menu ++* head invocation:: Output the first part of files. ++* tail invocation:: Output the last part of files. ++* split invocation:: Split a file into fixed-size pieces. ++* csplit invocation:: Split a file into context-determined pieces. ++@end menu ++ ++@node head invocation ++@section @command{head}: Output the first part of files ++ ++@pindex head ++@cindex initial part of files, outputting ++@cindex first part of files, outputting ++ ++@command{head} prints the first part (10 lines by default) of each ++@var{file}; it reads from standard input if no files are given or ++when given a @var{file} of @option{-}. Synopsis: ++ ++@example ++head [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++If more than one @var{file} is specified, @command{head} prints a ++one-line header consisting of: ++ ++@example ++==> @var{file name} <== ++@end example ++ ++@noindent ++before the output for each @var{file}. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -c @var{k} ++@itemx --bytes=@var{k} ++@opindex -c ++@opindex --bytes ++Print the first @var{k} bytes, instead of initial lines. ++However, if @var{k} starts with a @samp{-}, ++print all but the last @var{k} bytes of each file. ++@multiplierSuffixes{k} ++ ++@itemx -n @var{k} ++@itemx --lines=@var{k} ++@opindex -n ++@opindex --lines ++Output the first @var{k} lines. ++However, if @var{k} starts with a @samp{-}, ++print all but the last @var{k} lines of each file. ++Size multiplier suffixes are the same as with the @option{-c} option. ++ ++@item -q ++@itemx --quiet ++@itemx --silent ++@opindex -q ++@opindex --quiet ++@opindex --silent ++Never print file name headers. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Always print file name headers. ++ ++@end table ++ ++For compatibility @command{head} also supports an obsolete option syntax ++@option{-@var{count}@var{options}}, which is recognized only if it is ++specified first. @var{count} is a decimal number optionally followed ++by a size letter (@samp{b}, @samp{k}, @samp{m}) as in @option{-c}, or ++@samp{l} to mean count by lines, or other option letters (@samp{cqv}). ++Scripts intended for standard hosts should use @option{-c @var{count}} ++or @option{-n @var{count}} instead. If your script must also run on ++hosts that support only the obsolete syntax, it is usually simpler to ++avoid @command{head}, e.g., by using @samp{sed 5q} instead of ++@samp{head -5}. ++ ++@exitstatus ++ ++ ++@node tail invocation ++@section @command{tail}: Output the last part of files ++ ++@pindex tail ++@cindex last part of files, outputting ++ ++@command{tail} prints the last part (10 lines by default) of each ++@var{file}; it reads from standard input if no files are given or ++when given a @var{file} of @samp{-}. Synopsis: ++ ++@example ++tail [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++If more than one @var{file} is specified, @command{tail} prints a ++one-line header consisting of: ++ ++@example ++==> @var{file name} <== ++@end example ++ ++@noindent ++before the output for each @var{file}. ++ ++@cindex BSD @command{tail} ++@sc{gnu} @command{tail} can output any amount of data (some other versions of ++@command{tail} cannot). It also has no @option{-r} option (print in ++reverse), since reversing a file is really a different job from printing ++the end of a file; BSD @command{tail} (which is the one with @option{-r}) can ++only reverse files that are at most as large as its buffer, which is ++typically 32 KiB@. A more reliable and versatile way to reverse files is ++the @sc{gnu} @command{tac} command. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -c @var{k} ++@itemx --bytes=@var{k} ++@opindex -c ++@opindex --bytes ++Output the last @var{k} bytes, instead of final lines. ++However, if @var{k} starts with a @samp{+}, start printing with the ++@var{k}th byte from the start of each file, instead of from the end. ++@multiplierSuffixes{k} ++ ++@item -f ++@itemx --follow[=@var{how}] ++@opindex -f ++@opindex --follow ++@cindex growing files ++@vindex name @r{follow option} ++@vindex descriptor @r{follow option} ++Loop forever trying to read more characters at the end of the file, ++presumably because the file is growing. ++If more than one file is given, @command{tail} prints a header whenever it ++gets output from a different file, to indicate which file that output is ++from. ++ ++There are two ways to specify how you'd like to track files with this option, ++but that difference is noticeable only when a followed file is removed or ++renamed. ++If you'd like to continue to track the end of a growing file even after ++it has been unlinked, use @option{--follow=descriptor}. This is the default ++behavior, but it is not useful if you're tracking a log file that may be ++rotated (removed or renamed, then reopened). In that case, use ++@option{--follow=name} to track the named file by reopening it periodically ++to see if it has been removed and recreated by some other program. ++ ++No matter which method you use, if the tracked file is determined to have ++shrunk, @command{tail} prints a message saying the file has been truncated ++and resumes tracking the end of the file from the newly-determined endpoint. ++ ++When a file is removed, @command{tail}'s behavior depends on whether it is ++following the name or the descriptor. When following by name, tail can ++detect that a file has been removed and gives a message to that effect, ++and if @option{--retry} has been specified it will continue checking ++periodically to see if the file reappears. ++When following a descriptor, tail does not detect that the file has ++been unlinked or renamed and issues no message; even though the file ++may no longer be accessible via its original name, it may still be ++growing. ++ ++The option values @samp{descriptor} and @samp{name} may be specified only ++with the long form of the option, not with @option{-f}. ++ ++The @option{-f} option is ignored if ++no @var{file} operand is specified and standard input is a FIFO or a pipe. ++Likewise, the @option{-f} option has no effect for any ++operand specified as @samp{-}, when standard input is a FIFO or a pipe. ++ ++@item -F ++@opindex -F ++This option is the same as @option{--follow=name --retry}. That is, tail ++will attempt to reopen a file when it is removed. Should this fail, tail ++will keep trying until it becomes accessible again. ++ ++@itemx --retry ++@opindex --retry ++This option is useful mainly when following by name (i.e., with ++@option{--follow=name}). ++Without this option, when tail encounters a file that doesn't ++exist or is otherwise inaccessible, it reports that fact and ++never checks it again. ++ ++@itemx --sleep-interval=@var{number} ++@opindex --sleep-interval ++Change the number of seconds to wait between iterations (the default is 1.0). ++During one iteration, every specified file is checked to see if it has ++changed size. ++Historical implementations of @command{tail} have required that ++@var{number} be an integer. However, GNU @command{tail} accepts ++an arbitrary floating point number (using a period before any ++fractional digits). ++ ++@itemx --pid=@var{pid} ++@opindex --pid ++When following by name or by descriptor, you may specify the process ID, ++@var{pid}, of the sole writer of all @var{file} arguments. Then, shortly ++after that process terminates, tail will also terminate. This will ++work properly only if the writer and the tailing process are running on ++the same machine. For example, to save the output of a build in a file ++and to watch the file grow, if you invoke @command{make} and @command{tail} ++like this then the tail process will stop when your build completes. ++Without this option, you would have had to kill the @code{tail -f} ++process yourself. ++ ++@example ++$ make >& makerr & tail --pid=$! -f makerr ++@end example ++ ++If you specify a @var{pid} that is not in use or that does not correspond ++to the process that is writing to the tailed files, then @command{tail} ++may terminate long before any @var{file}s stop growing or it may not ++terminate until long after the real writer has terminated. ++Note that @option{--pid} cannot be supported on some systems; @command{tail} ++will print a warning if this is the case. ++ ++@itemx --max-unchanged-stats=@var{n} ++@opindex --max-unchanged-stats ++When tailing a file by name, if there have been @var{n} (default ++n=@value{DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS}) consecutive ++iterations for which the file has not changed, then ++@code{open}/@code{fstat} the file to determine if that file name is ++still associated with the same device/inode-number pair as before. ++When following a log file that is rotated, this is approximately the ++number of seconds between when tail prints the last pre-rotation lines ++and when it prints the lines that have accumulated in the new log file. ++This option is meaningful only when following by name. ++ ++@itemx -n @var{k} ++@itemx --lines=@var{k} ++@opindex -n ++@opindex --lines ++Output the last @var{k} lines. ++However, if @var{k} starts with a @samp{+}, start printing with the ++@var{k}th line from the start of each file, instead of from the end. ++Size multiplier suffixes are the same as with the @option{-c} option. ++ ++@item -q ++@itemx --quiet ++@itemx --silent ++@opindex -q ++@opindex --quiet ++@opindex --silent ++Never print file name headers. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Always print file name headers. ++ ++@end table ++ ++For compatibility @command{tail} also supports an obsolete usage ++@samp{tail -[@var{count}][bcl][f] [@var{file}]}, which is recognized ++only if it does not conflict with the usage described ++above. This obsolete form uses exactly one option and at most one ++file. In the option, @var{count} is an optional decimal number optionally ++followed by a size letter (@samp{b}, @samp{c}, @samp{l}) to mean count ++by 512-byte blocks, bytes, or lines, optionally followed by @samp{f} ++which has the same meaning as @option{-f}. ++ ++@vindex _POSIX2_VERSION ++On older systems, the leading @samp{-} can be replaced by @samp{+} in ++the obsolete option syntax with the same meaning as in counts, and ++obsolete usage overrides normal usage when the two conflict. ++This obsolete behavior can be enabled or disabled with the ++@env{_POSIX2_VERSION} environment variable (@pxref{Standards ++conformance}). ++ ++Scripts intended for use on standard hosts should avoid obsolete ++syntax and should use @option{-c @var{count}[b]}, @option{-n ++@var{count}}, and/or @option{-f} instead. If your script must also ++run on hosts that support only the obsolete syntax, you can often ++rewrite it to avoid problematic usages, e.g., by using @samp{sed -n ++'$p'} rather than @samp{tail -1}. If that's not possible, the script ++can use a test like @samp{if tail -c +1 /dev/null 2>&1; ++then @dots{}} to decide which syntax to use. ++ ++Even if your script assumes the standard behavior, you should still ++beware usages whose behaviors differ depending on the @acronym{POSIX} ++version. For example, avoid @samp{tail - main.c}, since it might be ++interpreted as either @samp{tail main.c} or as @samp{tail -- - ++main.c}; avoid @samp{tail -c 4}, since it might mean either @samp{tail ++-c4} or @samp{tail -c 10 4}; and avoid @samp{tail +4}, since it might ++mean either @samp{tail ./+4} or @samp{tail -n +4}. ++ ++@exitstatus ++ ++ ++@node split invocation ++@section @command{split}: Split a file into fixed-size pieces ++ ++@pindex split ++@cindex splitting a file into pieces ++@cindex pieces, splitting a file into ++ ++@command{split} creates output files containing consecutive sections of ++@var{input} (standard input if none is given or @var{input} is ++@samp{-}). Synopsis: ++ ++@example ++split [@var{option}] [@var{input} [@var{prefix}]] ++@end example ++ ++By default, @command{split} puts 1000 lines of @var{input} (or whatever is ++left over for the last section), into each output file. ++ ++@cindex output file name prefix ++The output files' names consist of @var{prefix} (@samp{x} by default) ++followed by a group of characters (@samp{aa}, @samp{ab}, @dots{} by ++default), such that concatenating the output files in traditional ++sorted order by file name produces ++the original input file. If the output file names are exhausted, ++@command{split} reports an error without deleting the output files ++that it did create. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -l @var{lines} ++@itemx --lines=@var{lines} ++@opindex -l ++@opindex --lines ++Put @var{lines} lines of @var{input} into each output file. ++ ++For compatibility @command{split} also supports an obsolete ++option syntax @option{-@var{lines}}. New scripts should use @option{-l ++@var{lines}} instead. ++ ++@item -b @var{size} ++@itemx --bytes=@var{size} ++@opindex -b ++@opindex --bytes ++Put @var{size} bytes of @var{input} into each output file. ++@multiplierSuffixes{size} ++ ++@item -C @var{size} ++@itemx --line-bytes=@var{size} ++@opindex -C ++@opindex --line-bytes ++Put into each output file as many complete lines of @var{input} as ++possible without exceeding @var{size} bytes. Individual lines longer than ++@var{size} bytes are broken into multiple files. ++@var{size} has the same format as for the @option{--bytes} option. ++ ++@item -a @var{length} ++@itemx --suffix-length=@var{length} ++@opindex -a ++@opindex --suffix-length ++Use suffixes of length @var{length}. The default @var{length} is 2. ++ ++@item -d ++@itemx --numeric-suffixes ++@opindex -d ++@opindex --numeric-suffixes ++Use digits in suffixes rather than lower-case letters. ++ ++@itemx --verbose ++@opindex --verbose ++Write a diagnostic just before each output file is opened. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node csplit invocation ++@section @command{csplit}: Split a file into context-determined pieces ++ ++@pindex csplit ++@cindex context splitting ++@cindex splitting a file into pieces by context ++ ++@command{csplit} creates zero or more output files containing sections of ++@var{input} (standard input if @var{input} is @samp{-}). Synopsis: ++ ++@example ++csplit [@var{option}]@dots{} @var{input} @var{pattern}@dots{} ++@end example ++ ++The contents of the output files are determined by the @var{pattern} ++arguments, as detailed below. An error occurs if a @var{pattern} ++argument refers to a nonexistent line of the input file (e.g., if no ++remaining line matches a given regular expression). After every ++@var{pattern} has been matched, any remaining input is copied into one ++last output file. ++ ++By default, @command{csplit} prints the number of bytes written to each ++output file after it has been created. ++ ++The types of pattern arguments are: ++ ++@table @samp ++ ++@item @var{n} ++Create an output file containing the input up to but not including line ++@var{n} (a positive integer). If followed by a repeat count, also ++create an output file containing the next @var{n} lines of the input ++file once for each repeat. ++ ++@item /@var{regexp}/[@var{offset}] ++Create an output file containing the current line up to (but not ++including) the next line of the input file that contains a match for ++@var{regexp}. The optional @var{offset} is an integer. ++If it is given, the input up to (but not including) the ++matching line plus or minus @var{offset} is put into the output file, ++and the line after that begins the next section of input. ++ ++@item %@var{regexp}%[@var{offset}] ++Like the previous type, except that it does not create an output ++file, so that section of the input file is effectively ignored. ++ ++@item @{@var{repeat-count}@} ++Repeat the previous pattern @var{repeat-count} additional ++times. The @var{repeat-count} can either be a positive integer or an ++asterisk, meaning repeat as many times as necessary until the input is ++exhausted. ++ ++@end table ++ ++The output files' names consist of a prefix (@samp{xx} by default) ++followed by a suffix. By default, the suffix is an ascending sequence ++of two-digit decimal numbers from @samp{00} to @samp{99}. In any case, ++concatenating the output files in sorted order by file name produces the ++original input file. ++ ++By default, if @command{csplit} encounters an error or receives a hangup, ++interrupt, quit, or terminate signal, it removes any output files ++that it has created so far before it exits. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -f @var{prefix} ++@itemx --prefix=@var{prefix} ++@opindex -f ++@opindex --prefix ++@cindex output file name prefix ++Use @var{prefix} as the output file name prefix. ++ ++@item -b @var{suffix} ++@itemx --suffix=@var{suffix} ++@opindex -b ++@opindex --suffix ++@cindex output file name suffix ++Use @var{suffix} as the output file name suffix. When this option is ++specified, the suffix string must include exactly one ++@code{printf(3)}-style conversion specification, possibly including ++format specification flags, a field width, a precision specifications, ++or all of these kinds of modifiers. The format letter must convert a ++binary integer argument to readable form; thus, only @samp{d}, @samp{i}, ++@samp{u}, @samp{o}, @samp{x}, and @samp{X} conversions are allowed. The ++entire @var{suffix} is given (with the current output file number) to ++@code{sprintf(3)} to form the file name suffixes for each of the ++individual output files in turn. If this option is used, the ++@option{--digits} option is ignored. ++ ++@item -n @var{digits} ++@itemx --digits=@var{digits} ++@opindex -n ++@opindex --digits ++Use output file names containing numbers that are @var{digits} digits ++long instead of the default 2. ++ ++@item -k ++@itemx --keep-files ++@opindex -k ++@opindex --keep-files ++Do not remove output files when errors are encountered. ++ ++@item -z ++@itemx --elide-empty-files ++@opindex -z ++@opindex --elide-empty-files ++Suppress the generation of zero-length output files. (In cases where ++the section delimiters of the input file are supposed to mark the first ++lines of each of the sections, the first output file will generally be a ++zero-length file unless you use this option.) The output file sequence ++numbers always run consecutively starting from 0, even when this option ++is specified. ++ ++@item -s ++@itemx -q ++@itemx --silent ++@itemx --quiet ++@opindex -s ++@opindex -q ++@opindex --silent ++@opindex --quiet ++Do not print counts of output file sizes. ++ ++@end table ++ ++@exitstatus ++ ++Here is an example of its usage. ++First, create an empty directory for the exercise, ++and cd into it: ++ ++@example ++$ mkdir d && cd d ++@end example ++ ++Now, split the sequence of 1..14 on lines that end with 0 or 5: ++ ++@example ++$ seq 14 | csplit - '/[05]$/' '@{*@}' ++8 ++10 ++15 ++@end example ++ ++Each number printed above is the size of an output ++file that csplit has just created. ++List the names of those output files: ++ ++@example ++$ ls ++xx00 xx01 xx02 ++@end example ++ ++Use @command{head} to show their contents: ++ ++@example ++$ head xx* ++==> xx00 <== ++1 ++2 ++3 ++4 ++ ++==> xx01 <== ++5 ++6 ++7 ++8 ++9 ++ ++==> xx02 <== ++10 ++11 ++12 ++13 ++14 ++@end example ++ ++@node Summarizing files ++@chapter Summarizing files ++ ++@cindex summarizing files ++ ++These commands generate just a few numbers representing entire ++contents of files. ++ ++@menu ++* wc invocation:: Print newline, word, and byte counts. ++* sum invocation:: Print checksum and block counts. ++* cksum invocation:: Print CRC checksum and byte counts. ++* md5sum invocation:: Print or check MD5 digests. ++* sha1sum invocation:: Print or check SHA-1 digests. ++* sha2 utilities:: Print or check SHA-2 digests. ++@end menu ++ ++ ++@node wc invocation ++@section @command{wc}: Print newline, word, and byte counts ++ ++@pindex wc ++@cindex byte count ++@cindex character count ++@cindex word count ++@cindex line count ++ ++@command{wc} counts the number of bytes, characters, whitespace-separated ++words, and newlines in each given @var{file}, or standard input if none ++are given or for a @var{file} of @samp{-}. Synopsis: ++ ++@example ++wc [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++@cindex total counts ++@command{wc} prints one line of counts for each file, and if the file was ++given as an argument, it prints the file name following the counts. If ++more than one @var{file} is given, @command{wc} prints a final line ++containing the cumulative counts, with the file name @file{total}. The ++counts are printed in this order: newlines, words, characters, bytes, ++maximum line length. ++Each count is printed right-justified in a field with at least one ++space between fields so that the numbers and file names normally line ++up nicely in columns. The width of the count fields varies depending ++on the inputs, so you should not depend on a particular field width. ++However, as a @acronym{GNU} extension, if only one count is printed, ++it is guaranteed to be printed without leading spaces. ++ ++By default, @command{wc} prints three counts: the newline, words, and byte ++counts. Options can specify that only certain counts be printed. ++Options do not undo others previously given, so ++ ++@example ++wc --bytes --words ++@end example ++ ++@noindent ++prints both the byte counts and the word counts. ++ ++With the @option{--max-line-length} option, @command{wc} prints the length ++of the longest line per file, and if there is more than one file it ++prints the maximum (not the sum) of those lengths. The line lengths here ++are measured in screen columns, according to the current locale and ++assuming tab positions in every 8th column. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -c ++@itemx --bytes ++@opindex -c ++@opindex --bytes ++Print only the byte counts. ++ ++@item -m ++@itemx --chars ++@opindex -m ++@opindex --chars ++Print only the character counts. ++ ++@item -w ++@itemx --words ++@opindex -w ++@opindex --words ++Print only the word counts. ++ ++@item -l ++@itemx --lines ++@opindex -l ++@opindex --lines ++Print only the newline counts. ++ ++@item -L ++@itemx --max-line-length ++@opindex -L ++@opindex --max-line-length ++Print only the maximum line lengths. ++ ++@macro filesZeroFromOption{cmd,withTotalOption,subListOutput} ++@itemx --files0-from=@var{file} ++@opindex --files0-from=@var{file} ++@c This is commented out to avoid a texi2dvi failure. ++@c texi2dvi (GNU Texinfo 4.11) 1.104 ++@c @cindex including files from @command{\cmd\} ++Disallow processing files named on the command line, and instead process ++those named in file @var{file}; each name being terminated by a zero byte ++(@acronym{ASCII} @sc{nul}). ++This is useful \withTotalOption\ ++when the list of file names is so long that it may exceed a command line ++length limitation. ++In such cases, running @command{\cmd\} via @command{xargs} is undesirable ++because it splits the list into pieces and makes @command{\cmd\} print ++\subListOutput\ for each sublist rather than for the entire list. ++One way to produce a list of @acronym{ASCII} @sc{nul} terminated file names is with @sc{gnu} ++@command{find}, using its @option{-print0} predicate. ++If @var{file} is @samp{-} then the @acronym{ASCII} @sc{nul} terminated file names ++are read from standard input. ++@end macro ++@filesZeroFromOption{wc,,a total} ++ ++For example, to find the length of the longest line in any @file{.c} or ++@file{.h} file in the current hierarchy, do this: ++ ++@example ++find . -name '*.[ch]' -print0 | ++ wc -L --files0-from=- | tail -n1 ++@end example ++ ++@end table ++ ++@exitstatus ++ ++ ++@node sum invocation ++@section @command{sum}: Print checksum and block counts ++ ++@pindex sum ++@cindex 16-bit checksum ++@cindex checksum, 16-bit ++ ++@command{sum} computes a 16-bit checksum for each given @var{file}, or ++standard input if none are given or for a @var{file} of @samp{-}. Synopsis: ++ ++@example ++sum [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++@command{sum} prints the checksum for each @var{file} followed by the ++number of blocks in the file (rounded up). If more than one @var{file} ++is given, file names are also printed (by default). (With the ++@option{--sysv} option, corresponding file names are printed when there is ++at least one file argument.) ++ ++By default, @sc{gnu} @command{sum} computes checksums using an algorithm ++compatible with BSD @command{sum} and prints file sizes in units of ++1024-byte blocks. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -r ++@opindex -r ++@cindex BSD @command{sum} ++Use the default (BSD compatible) algorithm. This option is included for ++compatibility with the System V @command{sum}. Unless @option{-s} was also ++given, it has no effect. ++ ++@item -s ++@itemx --sysv ++@opindex -s ++@opindex --sysv ++@cindex System V @command{sum} ++Compute checksums using an algorithm compatible with System V ++@command{sum}'s default, and print file sizes in units of 512-byte blocks. ++ ++@end table ++ ++@command{sum} is provided for compatibility; the @command{cksum} program (see ++next section) is preferable in new applications. ++ ++@exitstatus ++ ++ ++@node cksum invocation ++@section @command{cksum}: Print CRC checksum and byte counts ++ ++@pindex cksum ++@cindex cyclic redundancy check ++@cindex CRC checksum ++ ++@command{cksum} computes a cyclic redundancy check (CRC) checksum for each ++given @var{file}, or standard input if none are given or for a ++@var{file} of @samp{-}. Synopsis: ++ ++@example ++cksum [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++@command{cksum} prints the CRC checksum for each file along with the number ++of bytes in the file, and the file name unless no arguments were given. ++ ++@command{cksum} is typically used to ensure that files ++transferred by unreliable means (e.g., netnews) have not been corrupted, ++by comparing the @command{cksum} output for the received files with the ++@command{cksum} output for the original files (typically given in the ++distribution). ++ ++The CRC algorithm is specified by the @acronym{POSIX} standard. It is not ++compatible with the BSD or System V @command{sum} algorithms (see the ++previous section); it is more robust. ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. ++ ++@exitstatus ++ ++ ++@node md5sum invocation ++@section @command{md5sum}: Print or check MD5 digests ++ ++@pindex md5sum ++@cindex MD5 ++@cindex 128-bit checksum ++@cindex checksum, 128-bit ++@cindex fingerprint, 128-bit ++@cindex message-digest, 128-bit ++ ++@command{md5sum} computes a 128-bit checksum (or @dfn{fingerprint} or ++@dfn{message-digest}) for each specified @var{file}. ++ ++Note: The MD5 digest is more reliable than a simple CRC (provided by ++the @command{cksum} command) for detecting accidental file corruption, ++as the chances of accidentally having two files with identical MD5 ++are vanishingly small. However, it should not be considered truly ++secure against malicious tampering: although finding a file with a ++given MD5 fingerprint, or modifying a file so as to retain its MD5 are ++considered infeasible at the moment, it is known how to produce ++different files with identical MD5 (a ``collision''), something which ++can be a security issue in certain contexts. For more secure hashes, ++consider using SHA-1 or SHA-2. @xref{sha1sum invocation}, and ++@ref{sha2 utilities}. ++ ++If a @var{file} is specified as @samp{-} or if no files are given ++@command{md5sum} computes the checksum for the standard input. ++@command{md5sum} can also determine whether a file and checksum are ++consistent. Synopsis: ++ ++@example ++md5sum [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++For each @var{file}, @samp{md5sum} outputs the MD5 checksum, a flag ++indicating a binary or text input file, and the file name. ++If @var{file} contains a backslash or newline, the ++line is started with a backslash, and each problematic character in ++the file name is escaped with a backslash, making the output ++unambiguous even in the presence of arbitrary file names. ++If @var{file} is omitted or specified as @samp{-}, standard input is read. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -b ++@itemx --binary ++@opindex -b ++@opindex --binary ++@cindex binary input files ++Treat each input file as binary, by reading it in binary mode and ++outputting a @samp{*} flag. This is the inverse of @option{--text}. ++On systems like @acronym{GNU} that do not distinguish between binary ++and text files, this option merely flags each input file as binary: ++the MD5 checksum is unaffected. This option is the default on systems ++like MS-DOS that distinguish between binary and text files, except ++for reading standard input when standard input is a terminal. ++ ++@item -c ++@itemx --check ++Read file names and checksum information (not data) from each ++@var{file} (or from stdin if no @var{file} was specified) and report ++whether the checksums match the contents of the named files. ++The input to this mode of @command{md5sum} is usually the output of ++a prior, checksum-generating run of @samp{md5sum}. ++Each valid line of input consists of an MD5 checksum, a binary/text ++flag, and then a file name. ++Binary files are marked with @samp{*}, text with @samp{ }. ++For each such line, @command{md5sum} reads the named file and computes its ++MD5 checksum. Then, if the computed message digest does not match the ++one on the line with the file name, the file is noted as having ++failed the test. Otherwise, the file passes the test. ++By default, for each valid line, one line is written to standard ++output indicating whether the named file passed the test. ++After all checks have been performed, if there were any failures, ++a warning is issued to standard error. ++Use the @option{--status} option to inhibit that output. ++If any listed file cannot be opened or read, if any valid line has ++an MD5 checksum inconsistent with the associated file, or if no valid ++line is found, @command{md5sum} exits with nonzero status. Otherwise, ++it exits successfully. ++ ++@itemx --quiet ++@opindex --quiet ++@cindex verifying MD5 checksums ++This option is useful only when verifying checksums. ++When verifying checksums, don't generate an 'OK' message per successfully ++checked file. Files that fail the verification are reported in the ++default one-line-per-file format. If there is any checksum mismatch, ++print a warning summarizing the failures to standard error. ++ ++@itemx --status ++@opindex --status ++@cindex verifying MD5 checksums ++This option is useful only when verifying checksums. ++When verifying checksums, don't generate the default one-line-per-file ++diagnostic and don't output the warning summarizing any failures. ++Failures to open or read a file still evoke individual diagnostics to ++standard error. ++If all listed files are readable and are consistent with the associated ++MD5 checksums, exit successfully. Otherwise exit with a status code ++indicating there was a failure. ++ ++@item -t ++@itemx --text ++@opindex -t ++@opindex --text ++@cindex text input files ++Treat each input file as text, by reading it in text mode and ++outputting a @samp{ } flag. This is the inverse of @option{--binary}. ++This option is the default on systems like @acronym{GNU} that do not ++distinguish between binary and text files. On other systems, it is ++the default for reading standard input when standard input is a ++terminal. ++ ++@item -w ++@itemx --warn ++@opindex -w ++@opindex --warn ++@cindex verifying MD5 checksums ++When verifying checksums, warn about improperly formatted MD5 checksum lines. ++This option is useful only if all but a few lines in the checked input ++are valid. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node sha1sum invocation ++@section @command{sha1sum}: Print or check SHA-1 digests ++ ++@pindex sha1sum ++@cindex SHA-1 ++@cindex 160-bit checksum ++@cindex checksum, 160-bit ++@cindex fingerprint, 160-bit ++@cindex message-digest, 160-bit ++ ++@command{sha1sum} computes a 160-bit checksum for each specified ++@var{file}. The usage and options of this command are precisely the ++same as for @command{md5sum}. @xref{md5sum invocation}. ++ ++Note: The SHA-1 digest is more secure than MD5, and no collisions of ++it are known (different files having the same fingerprint). However, ++it is known that they can be produced with considerable, but not ++unreasonable, resources. For this reason, it is generally considered ++that SHA-1 should be gradually phased out in favor of the more secure ++SHA-2 hash algorithms. @xref{sha2 utilities}. ++ ++ ++@node sha2 utilities ++@section sha2 utilities: Print or check SHA-2 digests ++ ++@pindex sha224sum ++@pindex sha256sum ++@pindex sha384sum ++@pindex sha512sum ++@cindex SHA-2 ++@cindex 224-bit checksum ++@cindex 256-bit checksum ++@cindex 384-bit checksum ++@cindex 512-bit checksum ++@cindex checksum, 224-bit ++@cindex checksum, 256-bit ++@cindex checksum, 384-bit ++@cindex checksum, 512-bit ++@cindex fingerprint, 224-bit ++@cindex fingerprint, 256-bit ++@cindex fingerprint, 384-bit ++@cindex fingerprint, 512-bit ++@cindex message-digest, 224-bit ++@cindex message-digest, 256-bit ++@cindex message-digest, 384-bit ++@cindex message-digest, 512-bit ++ ++The commands @command{sha224sum}, @command{sha256sum}, ++@command{sha384sum} and @command{sha512sum} compute checksums of ++various lengths (respectively 224, 256, 384 and 512 bits), ++collectively known as the SHA-2 hashes. The usage and options of ++these commands are precisely the same as for @command{md5sum}. ++@xref{md5sum invocation}. ++ ++Note: The SHA384 and SHA512 digests are considerably slower to ++compute, especially on 32-bit computers, than SHA224 or SHA256. ++ ++ ++@node Operating on sorted files ++@chapter Operating on sorted files ++ ++@cindex operating on sorted files ++@cindex sorted files, operations on ++ ++These commands work with (or produce) sorted files. ++ ++@menu ++* sort invocation:: Sort text files. ++* shuf invocation:: Shuffle text files. ++* uniq invocation:: Uniquify files. ++* comm invocation:: Compare two sorted files line by line. ++* ptx invocation:: Produce a permuted index of file contents. ++* tsort invocation:: Topological sort. ++@end menu ++ ++ ++@node sort invocation ++@section @command{sort}: Sort text files ++ ++@pindex sort ++@cindex sorting files ++ ++@command{sort} sorts, merges, or compares all the lines from the given ++files, or standard input if none are given or for a @var{file} of ++@samp{-}. By default, @command{sort} writes the results to standard ++output. Synopsis: ++ ++@example ++sort [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++@command{sort} has three modes of operation: sort (the default), merge, ++and check for sortedness. The following options change the operation ++mode: ++ ++@table @samp ++ ++@item -c ++@itemx --check ++@itemx --check=diagnose-first ++@opindex -c ++@opindex --check ++@cindex checking for sortedness ++Check whether the given file is already sorted: if it is not all ++sorted, print a diagnostic containing the first out-of-order line and ++exit with a status of 1. ++Otherwise, exit successfully. ++At most one input file can be given. ++ ++@item -C ++@itemx --check=quiet ++@itemx --check=silent ++@opindex -c ++@opindex --check ++@cindex checking for sortedness ++Exit successfully if the given file is already sorted, and ++exit with status 1 otherwise. ++At most one input file can be given. ++This is like @option{-c}, except it does not print a diagnostic. ++ ++@item -m ++@itemx --merge ++@opindex -m ++@opindex --merge ++@cindex merging sorted files ++Merge the given files by sorting them as a group. Each input file must ++always be individually sorted. It always works to sort instead of ++merge; merging is provided because it is faster, in the case where it ++works. ++ ++@end table ++ ++@cindex sort stability ++@cindex sort's last-resort comparison ++A pair of lines is compared as follows: ++@command{sort} compares each pair of fields, in the ++order specified on the command line, according to the associated ++ordering options, until a difference is found or no fields are left. ++If no key fields are specified, @command{sort} uses a default key of ++the entire line. Finally, as a last resort when all keys compare ++equal, @command{sort} compares entire lines as if no ordering options ++other than @option{--reverse} (@option{-r}) were specified. The ++@option{--stable} (@option{-s}) option disables this @dfn{last-resort ++comparison} so that lines in which all fields compare equal are left ++in their original relative order. The @option{--unique} ++(@option{-u}) option also disables the last-resort comparison. ++ ++@vindex LC_ALL ++@vindex LC_COLLATE ++Unless otherwise specified, all comparisons use the character collating ++sequence specified by the @env{LC_COLLATE} locale.@footnote{If you ++use a non-@acronym{POSIX} locale (e.g., by setting @env{LC_ALL} ++to @samp{en_US}), then @command{sort} may produce output that is sorted ++differently than you're accustomed to. In that case, set the @env{LC_ALL} ++environment variable to @samp{C}. Note that setting only @env{LC_COLLATE} ++has two problems. First, it is ineffective if @env{LC_ALL} is also set. ++Second, it has undefined behavior if @env{LC_CTYPE} (or @env{LANG}, if ++@env{LC_CTYPE} is unset) is set to an incompatible value. For example, ++you get undefined behavior if @env{LC_CTYPE} is @code{ja_JP.PCK} but ++@env{LC_COLLATE} is @code{en_US.UTF-8}.} ++ ++@sc{gnu} @command{sort} (as specified for all @sc{gnu} utilities) has no ++limit on input line length or restrictions on bytes allowed within lines. ++In addition, if the final byte of an input file is not a newline, @sc{gnu} ++@command{sort} silently supplies one. A line's trailing newline is not ++part of the line for comparison purposes. ++ ++@cindex exit status of @command{sort} ++Exit status: ++ ++@display ++0 if no error occurred ++1 if invoked with @option{-c} or @option{-C} and the input is not sorted ++2 if an error occurred ++@end display ++ ++@vindex TMPDIR ++If the environment variable @env{TMPDIR} is set, @command{sort} uses its ++value as the directory for temporary files instead of @file{/tmp}. The ++@option{--temporary-directory} (@option{-T}) option in turn overrides ++the environment variable. ++ ++The following options affect the ordering of output lines. They may be ++specified globally or as part of a specific key field. If no key ++fields are specified, global options apply to comparison of entire ++lines; otherwise the global options are inherited by key fields that do ++not specify any special options of their own. In pre-@acronym{POSIX} ++versions of @command{sort}, global options affect only later key fields, ++so portable shell scripts should specify global options first. ++ ++@table @samp ++ ++@item -b ++@itemx --ignore-leading-blanks ++@opindex -b ++@opindex --ignore-leading-blanks ++@cindex blanks, ignoring leading ++@vindex LC_CTYPE ++Ignore leading blanks when finding sort keys in each line. ++By default a blank is a space or a tab, but the @env{LC_CTYPE} locale ++can change this. Note blanks may be ignored by your locale's collating ++rules, but without this option they will be significant for character ++positions specified in keys with the @option{-k} option. ++ ++@item -d ++@itemx --dictionary-order ++@opindex -d ++@opindex --dictionary-order ++@cindex dictionary order ++@cindex phone directory order ++@cindex telephone directory order ++@vindex LC_CTYPE ++Sort in @dfn{phone directory} order: ignore all characters except ++letters, digits and blanks when sorting. ++By default letters and digits are those of @acronym{ASCII} and a blank ++is a space or a tab, but the @env{LC_CTYPE} locale can change this. ++ ++@item -f ++@itemx --ignore-case ++@opindex -f ++@opindex --ignore-case ++@cindex ignoring case ++@cindex case folding ++@vindex LC_CTYPE ++Fold lowercase characters into the equivalent uppercase characters when ++comparing so that, for example, @samp{b} and @samp{B} sort as equal. ++The @env{LC_CTYPE} locale determines character types. ++When used with @option{--unique} those lower case equivalent lines are ++thrown away. (There is currently no way to throw away the upper case ++equivalent instead. (Any @option{--reverse} given would only affect ++the final result, after the throwing away.)) ++ ++@item -g ++@itemx --general-numeric-sort ++@itemx --sort=general-numeric ++@opindex -g ++@opindex --general-numeric-sort ++@opindex --sort ++@cindex general numeric sort ++@vindex LC_NUMERIC ++Sort numerically, using the standard C function @code{strtod} to convert ++a prefix of each line to a double-precision floating point number. ++This allows floating point numbers to be specified in scientific notation, ++like @code{1.0e-34} and @code{10e100}. ++The @env{LC_NUMERIC} locale determines the decimal-point character. ++Do not report overflow, underflow, or conversion errors. ++Use the following collating sequence: ++ ++@itemize @bullet ++@item ++Lines that do not start with numbers (all considered to be equal). ++@item ++NaNs (``Not a Number'' values, in IEEE floating point arithmetic) ++in a consistent but machine-dependent order. ++@item ++Minus infinity. ++@item ++Finite numbers in ascending numeric order (with @math{-0} and @math{+0} equal). ++@item ++Plus infinity. ++@end itemize ++ ++Use this option only if there is no alternative; it is much slower than ++@option{--numeric-sort} (@option{-n}) and it can lose information when ++converting to floating point. ++ ++@item -h ++@itemx --human-numeric-sort ++@itemx --sort=human-numeric ++@opindex -h ++@opindex --human-numeric-sort ++@opindex --sort ++@cindex human numeric sort ++@vindex LC_NUMERIC ++Sort numerically, as per the @option{--numeric-sort} option below, and in ++addition handle IEC or SI suffixes like MiB, MB etc (@ref{Block size}). ++Note a mixture of IEC and SI suffixes is not supported and will ++be flagged as an error. Also the numbers must be abbreviated uniformly. ++I.E. values with different precisions like 6000K and 5M will be sorted ++incorrectly. ++ ++@item -i ++@itemx --ignore-nonprinting ++@opindex -i ++@opindex --ignore-nonprinting ++@cindex nonprinting characters, ignoring ++@cindex unprintable characters, ignoring ++@vindex LC_CTYPE ++Ignore nonprinting characters. ++The @env{LC_CTYPE} locale determines character types. ++This option has no effect if the stronger @option{--dictionary-order} ++(@option{-d}) option is also given. ++ ++@item -M ++@itemx --month-sort ++@itemx --sort=month ++@opindex -M ++@opindex --month-sort ++@opindex --sort ++@cindex months, sorting by ++@vindex LC_TIME ++An initial string, consisting of any amount of blanks, followed ++by a month name abbreviation, is folded to UPPER case and ++compared in the order @samp{JAN} < @samp{FEB} < @dots{} < @samp{DEC}. ++Invalid names compare low to valid names. The @env{LC_TIME} locale ++category determines the month spellings. ++By default a blank is a space or a tab, but the @env{LC_CTYPE} locale ++can change this. ++ ++@item -n ++@itemx --numeric-sort ++@itemx --sort=numeric ++@opindex -n ++@opindex --numeric-sort ++@opindex --sort ++@cindex numeric sort ++@vindex LC_NUMERIC ++Sort numerically. The number begins each line and consists ++of optional blanks, an optional @samp{-} sign, and zero or more ++digits possibly separated by thousands separators, optionally followed ++by a decimal-point character and zero or more digits. An empty ++number is treated as @samp{0}. The @env{LC_NUMERIC} ++locale specifies the decimal-point character and thousands separator. ++By default a blank is a space or a tab, but the @env{LC_CTYPE} locale ++can change this. ++ ++Comparison is exact; there is no rounding error. ++ ++Neither a leading @samp{+} nor exponential notation is recognized. ++To compare such strings numerically, use the ++@option{--general-numeric-sort} (@option{-g}) option. ++ ++@item -V ++@itemx --version-sort ++@opindex -V ++@opindex --version-sort ++@cindex version number sort ++@vindex LC_NUMERIC ++Sort per @code{strverscmp(3)}. This is a normal string comparison, except ++that embedded decimal numbers are sorted by numeric value ++(see @option{--numeric-sort} above). ++ ++@item -r ++@itemx --reverse ++@opindex -r ++@opindex --reverse ++@cindex reverse sorting ++Reverse the result of comparison, so that lines with greater key values ++appear earlier in the output instead of later. ++ ++@item -R ++@itemx --random-sort ++@itemx --sort=random ++@opindex -R ++@opindex --random-sort ++@opindex --sort ++@cindex random sort ++Sort by hashing the input keys and then sorting the hash values. ++Choose the hash function at random, ensuring that it is free of ++collisions so that differing keys have differing hash values. This is ++like a random permutation of the inputs (@pxref{shuf invocation}), ++except that keys with the same value sort together. ++ ++If multiple random sort fields are specified, the same random hash ++function is used for all fields. To use different random hash ++functions for different fields, you can invoke @command{sort} more ++than once. ++ ++The choice of hash function is affected by the ++@option{--random-source} option. ++ ++@end table ++ ++Other options are: ++ ++@table @samp ++ ++@item --compress-program=@var{prog} ++Compress any temporary files with the program @var{prog}. ++ ++With no arguments, @var{prog} must compress standard input to standard ++output, and when given the @option{-d} option it must decompress ++standard input to standard output. ++ ++Terminate with an error if @var{prog} exits with nonzero status. ++ ++White space and the backslash character should not appear in ++@var{prog}; they are reserved for future use. ++ ++@filesZeroFromOption{sort,,sorted output} ++ ++@item -k @var{pos1}[,@var{pos2}] ++@itemx --key=@var{pos1}[,@var{pos2}] ++@opindex -k ++@opindex --key ++@cindex sort field ++Specify a sort field that consists of the part of the line between ++@var{pos1} and @var{pos2} (or the end of the line, if @var{pos2} is ++omitted), @emph{inclusive}. ++ ++Each @var{pos} has the form @samp{@var{f}[.@var{c}][@var{opts}]}, ++where @var{f} is the number of the field to use, and @var{c} is the number ++of the first character from the beginning of the field. Fields and character ++positions are numbered starting with 1; a character position of zero in ++@var{pos2} indicates the field's last character. If @samp{.@var{c}} is ++omitted from @var{pos1}, it defaults to 1 (the beginning of the field); ++if omitted from @var{pos2}, it defaults to 0 (the end of the field). ++@var{opts} are ordering options, allowing individual keys to be sorted ++according to different rules; see below for details. Keys can span ++multiple fields. ++ ++Example: To sort on the second field, use @option{--key=2,2} ++(@option{-k 2,2}). See below for more notes on keys and more examples. ++ ++@item --batch-size=@var{nmerge} ++@opindex --batch-size ++@cindex number of inputs to merge, nmerge ++Merge at most @var{nmerge} inputs at once. ++ ++When @command{sort} has to merge more than @var{nmerge} inputs, ++it merges them in groups of @var{nmerge}, saving the result in ++a temporary file, which is then used as an input in a subsequent merge. ++ ++A large value of @var{nmerge} may improve merge performance and decrease ++temporary storage utilization at the expense of increased memory usage ++and I/0. Conversely a small value of @var{nmerge} may reduce memory ++requirements and I/0 at the expense of temporary storage consumption and ++merge performance. ++ ++The value of @var{nmerge} must be at least 2. The default value is ++currently 16, but this is implementation-dependent and may change in ++the future. ++ ++The value of @var{nmerge} may be bounded by a resource limit for open ++file descriptors. The commands @samp{ulimit -n} or @samp{getconf ++OPEN_MAX} may display limits for your systems; these limits may be ++modified further if your program already has some files open, or if ++the operating system has other limits on the number of open files. If ++the value of @var{nmerge} exceeds the resource limit, @command{sort} ++silently uses a smaller value. ++ ++@item -o @var{output-file} ++@itemx --output=@var{output-file} ++@opindex -o ++@opindex --output ++@cindex overwriting of input, allowed ++Write output to @var{output-file} instead of standard output. ++Normally, @command{sort} reads all input before opening ++@var{output-file}, so you can safely sort a file in place by using ++commands like @code{sort -o F F} and @code{cat F | sort -o F}. ++However, @command{sort} with @option{--merge} (@option{-m}) can open ++the output file before reading all input, so a command like @code{cat ++F | sort -m -o F - G} is not safe as @command{sort} might start ++writing @file{F} before @command{cat} is done reading it. ++ ++@vindex POSIXLY_CORRECT ++On newer systems, @option{-o} cannot appear after an input file if ++@env{POSIXLY_CORRECT} is set, e.g., @samp{sort F -o F}. Portable ++scripts should specify @option{-o @var{output-file}} before any input ++files. ++ ++@item --random-source=@var{file} ++@opindex --random-source ++@cindex random source for sorting ++Use @var{file} as a source of random data used to determine which ++random hash function to use with the @option{-R} option. @xref{Random ++sources}. ++ ++@item -s ++@itemx --stable ++@opindex -s ++@opindex --stable ++@cindex sort stability ++@cindex sort's last-resort comparison ++ ++Make @command{sort} stable by disabling its last-resort comparison. ++This option has no effect if no fields or global ordering options ++other than @option{--reverse} (@option{-r}) are specified. ++ ++@item -S @var{size} ++@itemx --buffer-size=@var{size} ++@opindex -S ++@opindex --buffer-size ++@cindex size for main memory sorting ++Use a main-memory sort buffer of the given @var{size}. By default, ++@var{size} is in units of 1024 bytes. Appending @samp{%} causes ++@var{size} to be interpreted as a percentage of physical memory. ++Appending @samp{K} multiplies @var{size} by 1024 (the default), ++@samp{M} by 1,048,576, @samp{G} by 1,073,741,824, and so on for ++@samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}. Appending ++@samp{b} causes @var{size} to be interpreted as a byte count, with no ++multiplication. ++ ++This option can improve the performance of @command{sort} by causing it ++to start with a larger or smaller sort buffer than the default. ++However, this option affects only the initial buffer size. The buffer ++grows beyond @var{size} if @command{sort} encounters input lines larger ++than @var{size}. ++ ++@item -t @var{separator} ++@itemx --field-separator=@var{separator} ++@opindex -t ++@opindex --field-separator ++@cindex field separator character ++Use character @var{separator} as the field separator when finding the ++sort keys in each line. By default, fields are separated by the empty ++string between a non-blank character and a blank character. ++By default a blank is a space or a tab, but the @env{LC_CTYPE} locale ++can change this. ++ ++That is, given the input line @w{@samp{ foo bar}}, @command{sort} breaks it ++into fields @w{@samp{ foo}} and @w{@samp{ bar}}. The field separator is ++not considered to be part of either the field preceding or the field ++following, so with @samp{sort @w{-t " "}} the same input line has ++three fields: an empty field, @samp{foo}, and @samp{bar}. ++However, fields that extend to the end of the line, ++as @option{-k 2}, or fields consisting of a range, as @option{-k 2,3}, ++retain the field separators present between the endpoints of the range. ++ ++To specify @acronym{ASCII} @sc{nul} as the field separator, ++use the two-character string @samp{\0}, e.g., @samp{sort -t '\0'}. ++ ++@item -T @var{tempdir} ++@itemx --temporary-directory=@var{tempdir} ++@opindex -T ++@opindex --temporary-directory ++@cindex temporary directory ++@vindex TMPDIR ++Use directory @var{tempdir} to store temporary files, overriding the ++@env{TMPDIR} environment variable. If this option is given more than ++once, temporary files are stored in all the directories given. If you ++have a large sort or merge that is I/O-bound, you can often improve ++performance by using this option to specify directories on different ++disks and controllers. ++ ++@item -u ++@itemx --unique ++@opindex -u ++@opindex --unique ++@cindex uniquifying output ++ ++Normally, output only the first of a sequence of lines that compare ++equal. For the @option{--check} (@option{-c} or @option{-C}) option, ++check that no pair of consecutive lines compares equal. ++ ++This option also disables the default last-resort comparison. ++ ++The commands @code{sort -u} and @code{sort | uniq} are equivalent, but ++this equivalence does not extend to arbitrary @command{sort} options. ++For example, @code{sort -n -u} inspects only the value of the initial ++numeric string when checking for uniqueness, whereas @code{sort -n | ++uniq} inspects the entire line. @xref{uniq invocation}. ++ ++@macro zeroTerminatedOption ++@item -z ++@itemx --zero-terminated ++@opindex -z ++@opindex --zero-terminated ++@cindex process zero-terminated items ++Delimit items with a zero byte rather than a newline (@acronym{ASCII} @sc{lf}). ++I.E. treat input as items separated by @acronym{ASCII} @sc{nul} ++and terminate output items with @acronym{ASCII} @sc{nul}. ++This option can be useful in conjunction with @samp{perl -0} or ++@samp{find -print0} and @samp{xargs -0} which do the same in order to ++reliably handle arbitrary file names (even those containing blanks ++or other special characters). ++@end macro ++@zeroTerminatedOption ++ ++@end table ++ ++Historical (BSD and System V) implementations of @command{sort} have ++differed in their interpretation of some options, particularly ++@option{-b}, @option{-f}, and @option{-n}. @sc{gnu} sort follows the @acronym{POSIX} ++behavior, which is usually (but not always!) like the System V behavior. ++According to @acronym{POSIX}, @option{-n} no longer implies @option{-b}. For ++consistency, @option{-M} has been changed in the same way. This may ++affect the meaning of character positions in field specifications in ++obscure cases. The only fix is to add an explicit @option{-b}. ++ ++A position in a sort field specified with @option{-k} may have any ++of the option letters @samp{MbdfghinRrV} appended to it, in which case no ++global ordering options are inherited by that particular field. The ++@option{-b} option may be independently attached to either or both of ++the start and end positions of a field specification, and if it is ++inherited from the global options it will be attached to both. ++If input lines can contain leading or adjacent blanks and @option{-t} ++is not used, then @option{-k} is typically combined with @option{-b} or ++an option that implicitly ignores leading blanks (@samp{MghnV}) as otherwise ++the varying numbers of leading blanks in fields can cause confusing results. ++ ++If the start position in a sort field specifier falls after the end of ++the line or after the end field, the field is empty. If the @option{-b} ++option was specified, the @samp{.@var{c}} part of a field specification ++is counted from the first nonblank character of the field. ++ ++@vindex _POSIX2_VERSION ++@vindex POSIXLY_CORRECT ++On older systems, @command{sort} supports an obsolete origin-zero ++syntax @samp{+@var{pos1} [-@var{pos2}]} for specifying sort keys. ++This obsolete behavior can be enabled or disabled with the ++@env{_POSIX2_VERSION} environment variable (@pxref{Standards ++conformance}); it can also be enabled when @env{POSIXLY_CORRECT} is ++not set by using the obsolete syntax with @samp{-@var{pos2}} present. ++ ++Scripts intended for use on standard hosts should avoid obsolete ++syntax and should use @option{-k} instead. For example, avoid ++@samp{sort +2}, since it might be interpreted as either @samp{sort ++./+2} or @samp{sort -k 3}. If your script must also run on hosts that ++support only the obsolete syntax, it can use a test like @samp{if sort ++-k 1 /dev/null 2>&1; then @dots{}} to decide which syntax ++to use. ++ ++Here are some examples to illustrate various combinations of options. ++ ++@itemize @bullet ++ ++@item ++Sort in descending (reverse) numeric order. ++ ++@example ++sort -n -r ++@end example ++ ++@item ++Sort alphabetically, omitting the first and second fields ++and the blanks at the start of the third field. ++This uses a single key composed of the characters beginning ++at the start of the first nonblank character in field three ++and extending to the end of each line. ++ ++@example ++sort -k 3b ++@end example ++ ++@item ++Sort numerically on the second field and resolve ties by sorting ++alphabetically on the third and fourth characters of field five. ++Use @samp{:} as the field delimiter. ++ ++@example ++sort -t : -k 2,2n -k 5.3,5.4 ++@end example ++ ++Note that if you had written @option{-k 2n} instead of @option{-k 2,2n} ++@command{sort} would have used all characters beginning in the second field ++and extending to the end of the line as the primary @emph{numeric} ++key. For the large majority of applications, treating keys spanning ++more than one field as numeric will not do what you expect. ++ ++Also note that the @samp{n} modifier was applied to the field-end ++specifier for the first key. It would have been equivalent to ++specify @option{-k 2n,2} or @option{-k 2n,2n}. All modifiers except ++@samp{b} apply to the associated @emph{field}, regardless of whether ++the modifier character is attached to the field-start and/or the ++field-end part of the key specifier. ++ ++@item ++Sort the password file on the fifth field and ignore any ++leading blanks. Sort lines with equal values in field five ++on the numeric user ID in field three. Fields are separated ++by @samp{:}. ++ ++@example ++sort -t : -k 5b,5 -k 3,3n /etc/passwd ++sort -t : -n -k 5b,5 -k 3,3 /etc/passwd ++sort -t : -b -k 5,5 -k 3,3n /etc/passwd ++@end example ++ ++These three commands have equivalent effect. The first specifies that ++the first key's start position ignores leading blanks and the second ++key is sorted numerically. The other two commands rely on global ++options being inherited by sort keys that lack modifiers. The inheritance ++works in this case because @option{-k 5b,5b} and @option{-k 5b,5} are ++equivalent, as the location of a field-end lacking a @samp{.@var{c}} ++character position is not affected by whether initial blanks are ++skipped. ++ ++@item ++Sort a set of log files, primarily by IPv4 address and secondarily by ++time stamp. If two lines' primary and secondary keys are identical, ++output the lines in the same order that they were input. The log ++files contain lines that look like this: ++ ++@example ++4.150.156.3 - - [01/Apr/2004:06:31:51 +0000] message 1 ++211.24.3.231 - - [24/Apr/2004:20:17:39 +0000] message 2 ++@end example ++ ++Fields are separated by exactly one space. Sort IPv4 addresses ++lexicographically, e.g., 212.61.52.2 sorts before 212.129.233.201 ++because 61 is less than 129. ++ ++@example ++sort -s -t ' ' -k 4.9n -k 4.5M -k 4.2n -k 4.14,4.21 file*.log | ++sort -s -t '.' -k 1,1n -k 2,2n -k 3,3n -k 4,4n ++@end example ++ ++This example cannot be done with a single @command{sort} invocation, ++since IPv4 address components are separated by @samp{.} while dates ++come just after a space. So it is broken down into two invocations of ++@command{sort}: the first sorts by time stamp and the second by IPv4 ++address. The time stamp is sorted by year, then month, then day, and ++finally by hour-minute-second field, using @option{-k} to isolate each ++field. Except for hour-minute-second there's no need to specify the ++end of each key field, since the @samp{n} and @samp{M} modifiers sort ++based on leading prefixes that cannot cross field boundaries. The ++IPv4 addresses are sorted lexicographically. The second sort uses ++@samp{-s} so that ties in the primary key are broken by the secondary ++key; the first sort uses @samp{-s} so that the combination of the two ++sorts is stable. ++ ++@item ++Generate a tags file in case-insensitive sorted order. ++ ++@smallexample ++find src -type f -print0 | sort -z -f | xargs -0 etags --append ++@end smallexample ++ ++The use of @option{-print0}, @option{-z}, and @option{-0} in this case means ++that file names that contain blanks or other special characters are ++not broken up ++by the sort operation. ++ ++@c This example is a bit contrived and needs more explanation. ++@c @item ++@c Sort records separated by an arbitrary string by using a pipe to convert ++@c each record delimiter string to @samp{\0}, then using sort's -z option, ++@c and converting each @samp{\0} back to the original record delimiter. ++@c ++@c @example ++@c printf 'c\n\nb\n\na\n'|perl -0pe 's/\n\n/\n\0/g'|sort -z|perl -0pe 's/\0/\n/g' ++@c @end example ++ ++@item ++Use the common @acronym{DSU, Decorate Sort Undecorate} idiom to ++sort lines according to their length. ++ ++@example ++awk '@{print length, $0@}' /etc/passwd | sort -n | cut -f2- -d' ' ++@end example ++ ++In general this technique can be used to sort data that the @command{sort} ++command does not support, or is inefficient at, sorting directly. ++ ++@item ++Shuffle a list of directories, but preserve the order of files within ++each directory. For instance, one could use this to generate a music ++playlist in which albums are shuffled but the songs of each album are ++played in order. ++ ++@example ++ls */* | sort -t / -k 1,1R -k 2,2 ++@end example ++ ++@end itemize ++ ++ ++@node shuf invocation ++@section @command{shuf}: Shuffling text ++ ++@pindex shuf ++@cindex shuffling files ++ ++@command{shuf} shuffles its input by outputting a random permutation ++of its input lines. Each output permutation is equally likely. ++Synopses: ++ ++@example ++shuf [@var{option}]@dots{} [@var{file}] ++shuf -e [@var{option}]@dots{} [@var{arg}]@dots{} ++shuf -i @var{lo}-@var{hi} [@var{option}]@dots{} ++@end example ++ ++@command{shuf} has three modes of operation that affect where it ++obtains its input lines. By default, it reads lines from standard ++input. The following options change the operation mode: ++ ++@table @samp ++ ++@item -e ++@itemx --echo ++@opindex -c ++@opindex --echo ++@cindex command-line operands to shuffle ++Treat each command-line operand as an input line. ++ ++@item -i @var{lo}-@var{hi} ++@itemx --input-range=@var{lo}-@var{hi} ++@opindex -i ++@opindex --input-range ++@cindex input range to shuffle ++Act as if input came from a file containing the range of unsigned ++decimal integers @var{lo}@dots{}@var{hi}, one per line. ++ ++@end table ++ ++@command{shuf}'s other options can affect its behavior in all ++operation modes: ++ ++@table @samp ++ ++@item -n @var{lines} ++@itemx --head-count=@var{count} ++@opindex -n ++@opindex --head-count ++@cindex head of output ++Output at most @var{count} lines. By default, all input lines are ++output. ++ ++@item -o @var{output-file} ++@itemx --output=@var{output-file} ++@opindex -o ++@opindex --output ++@cindex overwriting of input, allowed ++Write output to @var{output-file} instead of standard output. ++@command{shuf} reads all input before opening ++@var{output-file}, so you can safely shuffle a file in place by using ++commands like @code{shuf -o F out ++$ dd bs=1 skip=222 count=6 < out 2>/dev/null; echo ++deeper ++@end example ++ ++Note that although the listing above includes a trailing slash ++for the @samp{deeper} entry, the offsets select the name without ++the trailing slash. However, if you invoke @command{ls} with @option{--dired} ++along with an option like @option{--escape} (aka @option{-b}) and operate ++on a file whose name contains special characters, notice that the backslash ++@emph{is} included: ++ ++@example ++$ touch 'a b' ++$ ls -blog --dired 'a b' ++ -rw-r--r-- 1 0 Jun 10 12:28 a\ b ++//DIRED// 30 34 ++//DIRED-OPTIONS// --quoting-style=escape ++@end example ++ ++If you use a quoting style that adds quote marks ++(e.g., @option{--quoting-style=c}), then the offsets include the quote marks. ++So beware that the user may select the quoting style via the environment ++variable @env{QUOTING_STYLE}. Hence, applications using @option{--dired} ++should either specify an explicit @option{--quoting-style=literal} option ++(aka @option{-N} or @option{--literal}) on the command line, or else be ++prepared to parse the escaped names. ++ ++@item --full-time ++@opindex --full-time ++Produce long format directory listings, and list times in full. It is ++equivalent to using @option{--format=long} with ++@option{--time-style=full-iso} (@pxref{Formatting file timestamps}). ++ ++@item -g ++@opindex -g ++Produce long format directory listings, but don't display owner information. ++ ++@item -G ++@itemx --no-group ++@opindex -G ++@opindex --no-group ++Inhibit display of group information in a long format directory listing. ++(This is the default in some non-@sc{gnu} versions of @command{ls}, so we ++provide this option for compatibility.) ++ ++@optHumanReadable ++ ++@item -i ++@itemx --inode ++@opindex -i ++@opindex --inode ++@cindex inode number, printing ++Print the inode number (also called the file serial number and index ++number) of each file to the left of the file name. (This number ++uniquely identifies each file within a particular file system.) ++ ++@item -l ++@itemx --format=long ++@itemx --format=verbose ++@opindex -l ++@opindex --format ++@opindex long ls @r{format} ++@opindex verbose ls @r{format} ++In addition to the name of each file, print the file type, file mode bits, ++number of hard links, owner name, group name, size, and ++timestamp (@pxref{Formatting file timestamps}), normally ++the modification time. Print question marks for information that ++cannot be determined. ++ ++Normally the size is printed as a byte count without punctuation, but ++this can be overridden (@pxref{Block size}). For example, @option{-h} ++prints an abbreviated, human-readable count, and ++@samp{--block-size="'1"} prints a byte count with the thousands ++separator of the current locale. ++ ++For each directory that is listed, preface the files with a line ++@samp{total @var{blocks}}, where @var{blocks} is the total disk allocation ++for all files in that directory. The block size currently defaults to 1024 ++bytes, but this can be overridden (@pxref{Block size}). ++The @var{blocks} computed counts each hard link separately; ++this is arguably a deficiency. ++ ++The file type is one of the following characters: ++ ++@c The commented-out entries are ones we're not sure about. ++ ++@table @samp ++@item - ++regular file ++@item b ++block special file ++@item c ++character special file ++@item C ++high performance (``contiguous data'') file ++@item d ++directory ++@item D ++door (Solaris 2.5 and up) ++@c @item F ++@c semaphore, if this is a distinct file type ++@item l ++symbolic link ++@c @item m ++@c multiplexed file (7th edition Unix; obsolete) ++@item M ++off-line (``migrated'') file (Cray DMF) ++@item n ++network special file (HP-UX) ++@item p ++FIFO (named pipe) ++@item P ++port (Solaris 10 and up) ++@c @item Q ++@c message queue, if this is a distinct file type ++@item s ++socket ++@c @item S ++@c shared memory object, if this is a distinct file type ++@c @item T ++@c typed memory object, if this is a distinct file type ++@c @item w ++@c whiteout (4.4BSD; not implemented) ++@item ? ++some other file type ++@end table ++ ++@cindex permissions, output by @command{ls} ++The file mode bits listed are similar to symbolic mode specifications ++(@pxref{Symbolic Modes}). But @command{ls} combines multiple bits into the ++third character of each set of permissions as follows: ++ ++@table @samp ++@item s ++If the set-user-ID or set-group-ID bit and the corresponding executable bit ++are both set. ++ ++@item S ++If the set-user-ID or set-group-ID bit is set but the corresponding ++executable bit is not set. ++ ++@item t ++If the restricted deletion flag or sticky bit, and the ++other-executable bit, are both set. The restricted deletion flag is ++another name for the sticky bit. @xref{Mode Structure}. ++ ++@item T ++If the restricted deletion flag or sticky bit is set but the ++other-executable bit is not set. ++ ++@item x ++If the executable bit is set and none of the above apply. ++ ++@item - ++Otherwise. ++@end table ++ ++Following the file mode bits is a single character that specifies ++whether an alternate access method such as an access control list ++applies to the file. When the character following the file mode bits is a ++space, there is no alternate access method. When it is a printing ++character, then there is such a method. ++ ++GNU @command{ls} uses a @samp{.} character to indicate a file ++with an SELinux security context, but no other alternate access method. ++ ++A file with any other combination of alternate access methods ++is marked with a @samp{+} character. ++ ++@item -n ++@itemx --numeric-uid-gid ++@opindex -n ++@opindex --numeric-uid-gid ++@cindex numeric uid and gid ++@cindex numeric user and group IDs ++Produce long format directory listings, but ++display numeric user and group IDs instead of the owner and group names. ++ ++@item -o ++@opindex -o ++Produce long format directory listings, but don't display group information. ++It is equivalent to using @option{--format=long} with @option{--no-group} . ++ ++@item -s ++@itemx --size ++@opindex -s ++@opindex --size ++@cindex disk allocation ++@cindex size of files, reporting ++Print the disk allocation of each file to the left of the file name. ++This is the amount of disk space used by the file, which is usually a ++bit more than the file's size, but it can be less if the file has holes. ++ ++Normally the disk allocation is printed in units of ++1024 bytes, but this can be overridden (@pxref{Block size}). ++ ++@cindex NFS mounts from BSD to HP-UX ++For files that are NFS-mounted from an HP-UX system to a BSD system, ++this option reports sizes that are half the correct values. On HP-UX ++systems, it reports sizes that are twice the correct values for files ++that are NFS-mounted from BSD systems. This is due to a flaw in HP-UX; ++it also affects the HP-UX @command{ls} program. ++ ++@optSi ++ ++@item -Z ++@itemx --context ++@opindex -Z ++@opindex --context ++@cindex SELinux ++@cindex security context ++Display the SELinux security context or @samp{?} if none is found. ++When used with the @option{-l} option, print the security context ++to the left of the size column. ++ ++@end table ++ ++ ++@node Sorting the output ++@subsection Sorting the output ++ ++@cindex sorting @command{ls} output ++These options change the order in which @command{ls} sorts the information ++it outputs. By default, sorting is done by character code ++(e.g., @acronym{ASCII} order). ++ ++@table @samp ++ ++@item -c ++@itemx --time=ctime ++@itemx --time=status ++@opindex -c ++@opindex --time ++@opindex ctime@r{, printing or sorting by} ++@opindex status time@r{, printing or sorting by} ++@opindex use time@r{, printing or sorting files by} ++If the long listing format (e.g., @option{-l}, @option{-o}) is being used, ++print the status change time (the @samp{ctime} in the inode) instead of ++the modification time. ++When explicitly sorting by time (@option{--sort=time} or @option{-t}) ++or when not using a long listing format, ++sort according to the status change time. ++ ++@item -f ++@opindex -f ++@cindex unsorted directory listing ++@cindex directory order, listing by ++Primarily, like @option{-U}---do not sort; list the files in whatever ++order they are stored in the directory. But also enable @option{-a} (list ++all files) and disable @option{-l}, @option{--color}, and @option{-s} (if they ++were specified before the @option{-f}). ++ ++@item -r ++@itemx --reverse ++@opindex -r ++@opindex --reverse ++@cindex reverse sorting ++Reverse whatever the sorting method is---e.g., list files in reverse ++alphabetical order, youngest first, smallest first, or whatever. ++ ++@item -S ++@itemx --sort=size ++@opindex -S ++@opindex --sort ++@opindex size of files@r{, sorting files by} ++Sort by file size, largest first. ++ ++@item -t ++@itemx --sort=time ++@opindex -t ++@opindex --sort ++@opindex modification time@r{, sorting files by} ++Sort by modification time (the @samp{mtime} in the inode), newest first. ++ ++@item -u ++@itemx --time=atime ++@itemx --time=access ++@itemx --time=use ++@opindex -u ++@opindex --time ++@opindex use time@r{, printing or sorting files by} ++@opindex atime@r{, printing or sorting files by} ++@opindex access time@r{, printing or sorting files by} ++If the long listing format (e.g., @option{--format=long}) is being used, ++print the last access time (the @samp{atime} in the inode). ++When explicitly sorting by time (@option{--sort=time} or @option{-t}) ++or when not using a long listing format, sort according to the access time. ++ ++@item -U ++@itemx --sort=none ++@opindex -U ++@opindex --sort ++@opindex none@r{, sorting option for @command{ls}} ++Do not sort; list the files in whatever order they are ++stored in the directory. (Do not do any of the other unrelated things ++that @option{-f} does.) This is especially useful when listing very large ++directories, since not doing any sorting can be noticeably faster. ++ ++@item -v ++@itemx --sort=version ++@opindex -v ++@opindex --sort ++@opindex version@r{, sorting option for @command{ls}} ++Sort by version name and number, lowest first. It behaves like a default ++sort, except that each sequence of decimal digits is treated numerically ++as an index/version number. (@xref{Details about version sort}.) ++ ++@item -X ++@itemx --sort=extension ++@opindex -X ++@opindex --sort ++@opindex extension@r{, sorting files by} ++Sort directory contents alphabetically by file extension (characters ++after the last @samp{.}); files with no extension are sorted first. ++ ++@end table ++ ++ ++@node Details about version sort ++@subsection Details about version sort ++ ++The version sort takes into account the fact that file names frequently include ++indices or version numbers. Standard sorting functions usually do not produce ++the ordering that people expect because comparisons are made on a ++character-by-character basis. The version ++sort addresses this problem, and is especially useful when browsing ++directories that contain many files with indices/version numbers in their ++names: ++ ++@example ++$ ls -1 $ ls -1v ++foo.zml-1.gz foo.zml-1.gz ++foo.zml-100.gz foo.zml-2.gz ++foo.zml-12.gz foo.zml-6.gz ++foo.zml-13.gz foo.zml-12.gz ++foo.zml-2.gz foo.zml-13.gz ++foo.zml-25.gz foo.zml-25.gz ++foo.zml-6.gz foo.zml-100.gz ++@end example ++ ++Version-sorted strings are compared such that if @var{ver1} and @var{ver2} ++are version numbers and @var{prefix} and @var{suffix} (@var{suffix} matching ++the regular expression @samp{(\.[A-Za-z~][A-Za-z0-9~]*)*}) are strings then ++@var{ver1} < @var{ver2} implies that the name composed of ++``@var{prefix} @var{ver1} @var{suffix}'' sorts before ++``@var{prefix} @var{ver2} @var{suffix}''. ++ ++Note also that leading zeros of numeric parts are ignored: ++ ++@example ++$ ls -1 $ ls -1v ++abc-1.007.tgz abc-1.01a.tgz ++abc-1.012b.tgz abc-1.007.tgz ++abc-1.01a.tgz abc-1.012b.tgz ++@end example ++ ++This functionality is implemented using gnulib's @code{filevercmp} function. ++One result of that implementation decision is that @samp{ls -v} ++and @samp{sort -V} do not use the locale category, @env{LC_COLLATE}, ++which means non-numeric prefixes are sorted as if @env{LC_COLLATE} were set ++to @samp{C}. ++ ++@node General output formatting ++@subsection General output formatting ++ ++These options affect the appearance of the overall output. ++ ++@table @samp ++ ++@item -1 ++@itemx --format=single-column ++@opindex -1 ++@opindex --format ++@opindex single-column @r{output of files} ++List one file per line. This is the default for @command{ls} when standard ++output is not a terminal. ++ ++@item -C ++@itemx --format=vertical ++@opindex -C ++@opindex --format ++@opindex vertical @r{sorted files in columns} ++List files in columns, sorted vertically. This is the default for ++@command{ls} if standard output is a terminal. It is always the default ++for the @command{dir} program. ++@sc{gnu} @command{ls} uses variable width columns to display as many files as ++possible in the fewest lines. ++ ++@item --color [=@var{when}] ++@opindex --color ++@cindex color, distinguishing file types with ++Specify whether to use color for distinguishing file types. @var{when} ++may be omitted, or one of: ++@itemize @bullet ++@item none ++@vindex none @r{color option} ++- Do not use color at all. This is the default. ++@item auto ++@vindex auto @r{color option} ++@cindex terminal, using color iff ++- Only use color if standard output is a terminal. ++@item always ++@vindex always @r{color option} ++- Always use color. ++@end itemize ++Specifying @option{--color} and no @var{when} is equivalent to ++@option{--color=always}. ++Piping a colorized listing through a pager like @command{more} or ++@command{less} usually produces unreadable results. However, using ++@code{more -f} does seem to work. ++ ++@item -F ++@itemx --classify ++@itemx --indicator-style=classify ++@opindex -F ++@opindex --classify ++@opindex --indicator-style ++@cindex file type and executables, marking ++@cindex executables and file type, marking ++Append a character to each file name indicating the file type. Also, ++for regular files that are executable, append @samp{*}. The file type ++indicators are @samp{/} for directories, @samp{@@} for symbolic links, ++@samp{|} for FIFOs, @samp{=} for sockets, @samp{>} for doors, ++and nothing for regular files. ++@c The following sentence is the same as the one for -d. ++Do not follow symbolic links listed on the ++command line unless the @option{--dereference-command-line} (@option{-H}), ++@option{--dereference} (@option{-L}), or ++@option{--dereference-command-line-symlink-to-dir} options are specified. ++ ++@item --file-type ++@itemx --indicator-style=file-type ++@opindex --file-type ++@opindex --indicator-style ++@cindex file type, marking ++Append a character to each file name indicating the file type. This is ++like @option{-F}, except that executables are not marked. ++ ++@item --indicator-style=@var{word} ++@opindex --indicator-style ++Append a character indicator with style @var{word} to entry names, ++as follows: ++ ++@table @samp ++@item none ++Do not append any character indicator; this is the default. ++@item slash ++Append @samp{/} for directories. This is the same as the @option{-p} ++option. ++@item file-type ++Append @samp{/} for directories, @samp{@@} for symbolic links, @samp{|} ++for FIFOs, @samp{=} for sockets, and nothing for regular files. This is ++the same as the @option{--file-type} option. ++@item classify ++Append @samp{*} for executable regular files, otherwise behave as for ++@samp{file-type}. This is the same as the @option{-F} or ++@option{--classify} option. ++@end table ++ ++@item -k ++@opindex -k ++Print file sizes in 1024-byte blocks, overriding the default block ++size (@pxref{Block size}). ++This option is equivalent to @option{--block-size=1K}. ++ ++@item -m ++@itemx --format=commas ++@opindex -m ++@opindex --format ++@opindex commas@r{, outputting between files} ++List files horizontally, with as many as will fit on each line, ++separated by @samp{, } (a comma and a space). ++ ++@item -p ++@itemx --indicator-style=slash ++@opindex -p ++@opindex --indicator-style ++@cindex file type, marking ++Append a @samp{/} to directory names. ++ ++@item -x ++@itemx --format=across ++@itemx --format=horizontal ++@opindex -x ++@opindex --format ++@opindex across@r{, listing files} ++@opindex horizontal@r{, listing files} ++List the files in columns, sorted horizontally. ++ ++@item -T @var{cols} ++@itemx --tabsize=@var{cols} ++@opindex -T ++@opindex --tabsize ++Assume that each tab stop is @var{cols} columns wide. The default is 8. ++@command{ls} uses tabs where possible in the output, for efficiency. If ++@var{cols} is zero, do not use tabs at all. ++ ++@c FIXME: remove in 2009, if Apple Terminal has been fixed for long enough. ++Some terminal emulators (at least Apple Terminal 1.5 (133) from Mac OS X 10.4.8) ++do not properly align columns to the right of a TAB following a ++non-@acronym{ASCII} byte. If you use such a terminal emulator, use the ++@option{-T0} option or put @code{TABSIZE=0} in your environment to tell ++@command{ls} to align using spaces, not tabs. ++ ++@item -w ++@itemx --width=@var{cols} ++@opindex -w ++@opindex --width ++@vindex COLUMNS ++Assume the screen is @var{cols} columns wide. The default is taken ++from the terminal settings if possible; otherwise the environment ++variable @env{COLUMNS} is used if it is set; otherwise the default ++is 80. ++ ++@end table ++ ++ ++@node Formatting file timestamps ++@subsection Formatting file timestamps ++ ++By default, file timestamps are listed in abbreviated form. Most ++locales use a timestamp like @samp{2002-03-30 23:45}. However, the ++default @acronym{POSIX} locale uses a date like @samp{Mar 30@ @ 2002} ++for non-recent timestamps, and a date-without-year and time like ++@samp{Mar 30 23:45} for recent timestamps. ++ ++A timestamp is considered to be @dfn{recent} if it is less than six ++months old, and is not dated in the future. If a timestamp dated ++today is not listed in recent form, the timestamp is in the future, ++which means you probably have clock skew problems which may break ++programs like @command{make} that rely on file timestamps. ++ ++@vindex TZ ++Time stamps are listed according to the time zone rules specified by ++the @env{TZ} environment variable, or by the system default rules if ++@env{TZ} is not set. @xref{TZ Variable,, Specifying the Time Zone ++with @env{TZ}, libc, The GNU C Library Reference Manual}. ++ ++The following option changes how file timestamps are printed. ++ ++@table @samp ++@item --time-style=@var{style} ++@opindex --time-style ++@cindex time style ++List timestamps in style @var{style}. The @var{style} should ++be one of the following: ++ ++@table @samp ++@item +@var{format} ++@vindex LC_TIME ++List timestamps using @var{format}, where @var{format} is interpreted ++like the format argument of @command{date} (@pxref{date invocation}). ++For example, @option{--time-style="+%Y-%m-%d %H:%M:%S"} causes ++@command{ls} to list timestamps like @samp{2002-03-30 23:45:56}. As ++with @command{date}, @var{format}'s interpretation is affected by the ++@env{LC_TIME} locale category. ++ ++If @var{format} contains two format strings separated by a newline, ++the former is used for non-recent files and the latter for recent ++files; if you want output columns to line up, you may need to insert ++spaces in one of the two formats. ++ ++@item full-iso ++List timestamps in full using @acronym{ISO} 8601 date, time, and time zone ++format with nanosecond precision, e.g., @samp{2002-03-30 ++23:45:56.477817180 -0700}. This style is equivalent to ++@samp{+%Y-%m-%d %H:%M:%S.%N %z}. ++ ++This is useful because the time output includes all the information that ++is available from the operating system. For example, this can help ++explain @command{make}'s behavior, since @acronym{GNU} @command{make} ++uses the full timestamp to determine whether a file is out of date. ++ ++@item long-iso ++List @acronym{ISO} 8601 date and time in minutes, e.g., ++@samp{2002-03-30 23:45}. These timestamps are shorter than ++@samp{full-iso} timestamps, and are usually good enough for everyday ++work. This style is equivalent to @samp{+%Y-%m-%d %H:%M}. ++ ++@item iso ++List @acronym{ISO} 8601 dates for non-recent timestamps (e.g., ++@samp{2002-03-30@ }), and @acronym{ISO} 8601 month, day, hour, and ++minute for recent timestamps (e.g., @samp{03-30 23:45}). These ++timestamps are uglier than @samp{long-iso} timestamps, but they carry ++nearly the same information in a smaller space and their brevity helps ++@command{ls} output fit within traditional 80-column output lines. ++The following two @command{ls} invocations are equivalent: ++ ++@example ++newline=' ++' ++ls -l --time-style="+%Y-%m-%d $newline%m-%d %H:%M" ++ls -l --time-style="iso" ++@end example ++ ++@item locale ++@vindex LC_TIME ++List timestamps in a locale-dependent form. For example, a Finnish ++locale might list non-recent timestamps like @samp{maalis 30@ @ 2002} ++and recent timestamps like @samp{maalis 30 23:45}. Locale-dependent ++timestamps typically consume more space than @samp{iso} timestamps and ++are harder for programs to parse because locale conventions vary so ++widely, but they are easier for many people to read. ++ ++The @env{LC_TIME} locale category specifies the timestamp format. The ++default @acronym{POSIX} locale uses timestamps like @samp{Mar 30@ ++@ 2002} and @samp{Mar 30 23:45}; in this locale, the following two ++@command{ls} invocations are equivalent: ++ ++@example ++newline=' ++' ++ls -l --time-style="+%b %e %Y$newline%b %e %H:%M" ++ls -l --time-style="locale" ++@end example ++ ++Other locales behave differently. For example, in a German locale, ++@option{--time-style="locale"} might be equivalent to ++@option{--time-style="+%e. %b %Y $newline%e. %b %H:%M"} ++and might generate timestamps like @samp{30. M@"ar 2002@ } and ++@samp{30. M@"ar 23:45}. ++ ++@item posix-@var{style} ++@vindex LC_TIME ++List @acronym{POSIX}-locale timestamps if the @env{LC_TIME} locale ++category is @acronym{POSIX}, @var{style} timestamps otherwise. For ++example, the @samp{posix-long-iso} style lists ++timestamps like @samp{Mar 30@ @ 2002} and @samp{Mar 30 23:45} when in ++the @acronym{POSIX} locale, and like @samp{2002-03-30 23:45} otherwise. ++@end table ++@end table ++ ++@vindex TIME_STYLE ++You can specify the default value of the @option{--time-style} option ++with the environment variable @env{TIME_STYLE}; if @env{TIME_STYLE} is not set ++the default style is @samp{locale}. @acronym{GNU} Emacs 21.3 and ++later use the @option{--dired} option and therefore can parse any date ++format, but if you are using Emacs 21.1 or 21.2 and specify a ++non-@acronym{POSIX} locale you may need to set ++@samp{TIME_STYLE="posix-long-iso"}. ++ ++To avoid certain denial-of-service attacks, timestamps that would be ++longer than 1000 bytes may be treated as errors. ++ ++ ++@node Formatting the file names ++@subsection Formatting the file names ++ ++These options change how file names themselves are printed. ++ ++@table @samp ++ ++@item -b ++@itemx --escape ++@itemx --quoting-style=escape ++@opindex -b ++@opindex --escape ++@opindex --quoting-style ++@cindex backslash sequences for file names ++Quote nongraphic characters in file names using alphabetic and octal ++backslash sequences like those used in C. ++ ++@item -N ++@itemx --literal ++@itemx --quoting-style=literal ++@opindex -N ++@opindex --literal ++@opindex --quoting-style ++Do not quote file names. However, with @command{ls} nongraphic ++characters are still printed as question marks if the output is a ++terminal and you do not specify the @option{--show-control-chars} ++option. ++ ++@item -q ++@itemx --hide-control-chars ++@opindex -q ++@opindex --hide-control-chars ++Print question marks instead of nongraphic characters in file names. ++This is the default if the output is a terminal and the program is ++@command{ls}. ++ ++@item -Q ++@itemx --quote-name ++@itemx --quoting-style=c ++@opindex -Q ++@opindex --quote-name ++@opindex --quoting-style ++Enclose file names in double quotes and quote nongraphic characters as ++in C. ++ ++@item --quoting-style=@var{word} ++@opindex --quoting-style ++@cindex quoting style ++Use style @var{word} to quote file names and other strings that may ++contain arbitrary characters. The @var{word} should ++be one of the following: ++ ++@table @samp ++@item literal ++Output strings as-is; this is the same as the @option{-N} or ++@option{--literal} option. ++@item shell ++Quote strings for the shell if they contain shell metacharacters or would ++cause ambiguous output. ++The quoting is suitable for @acronym{POSIX}-compatible shells like ++@command{bash}, but it does not always work for incompatible shells ++like @command{csh}. ++@item shell-always ++Quote strings for the shell, even if they would normally not require quoting. ++@item c ++Quote strings as for C character string literals, including the ++surrounding double-quote characters; this is the same as the ++@option{-Q} or @option{--quote-name} option. ++@item escape ++Quote strings as for C character string literals, except omit the ++surrounding double-quote ++characters; this is the same as the @option{-b} or @option{--escape} option. ++@item clocale ++Quote strings as for C character string literals, except use ++surrounding quotation marks appropriate for the ++locale. ++@item locale ++@c Use @t instead of @samp to avoid duplicate quoting in some output styles. ++Quote strings as for C character string literals, except use ++surrounding quotation marks appropriate for the locale, and quote ++@t{`like this'} instead of @t{"like ++this"} in the default C locale. This looks nicer on many displays. ++@end table ++ ++You can specify the default value of the @option{--quoting-style} option ++with the environment variable @env{QUOTING_STYLE}. If that environment ++variable is not set, the default value is @samp{literal}, but this ++default may change to @samp{shell} in a future version of this package. ++ ++@item --show-control-chars ++@opindex --show-control-chars ++Print nongraphic characters as-is in file names. ++This is the default unless the output is a terminal and the program is ++@command{ls}. ++ ++@end table ++ ++ ++@node dir invocation ++@section @command{dir}: Briefly list directory contents ++ ++@pindex dir ++@cindex directory listing, brief ++ ++@command{dir} is equivalent to @code{ls -C ++-b}; that is, by default files are listed in columns, sorted vertically, ++and special characters are represented by backslash escape sequences. ++ ++@xref{ls invocation, @command{ls}}. ++ ++ ++@node vdir invocation ++@section @command{vdir}: Verbosely list directory contents ++ ++@pindex vdir ++@cindex directory listing, verbose ++ ++@command{vdir} is equivalent to @code{ls -l ++-b}; that is, by default files are listed in long format and special ++characters are represented by backslash escape sequences. ++ ++@node dircolors invocation ++@section @command{dircolors}: Color setup for @command{ls} ++ ++@pindex dircolors ++@cindex color setup ++@cindex setup for color ++ ++@command{dircolors} outputs a sequence of shell commands to set up the ++terminal for color output from @command{ls} (and @command{dir}, etc.). ++Typical usage: ++ ++@example ++eval "`dircolors [@var{option}]@dots{} [@var{file}]`" ++@end example ++ ++If @var{file} is specified, @command{dircolors} reads it to determine which ++colors to use for which file types and extensions. Otherwise, a ++precompiled database is used. For details on the format of these files, ++run @samp{dircolors --print-database}. ++ ++To make @command{dircolors} read a @file{~/.dircolors} file if it ++exists, you can put the following lines in your @file{~/.bashrc} (or ++adapt them to your favorite shell): ++ ++@example ++d=.dircolors ++test -r $d && eval "$(dircolors $d)" ++@end example ++ ++@vindex LS_COLORS ++@vindex SHELL @r{environment variable, and color} ++The output is a shell command to set the @env{LS_COLORS} environment ++variable. You can specify the shell syntax to use on the command line, ++or @command{dircolors} will guess it from the value of the @env{SHELL} ++environment variable. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++@item -b ++@itemx --sh ++@itemx --bourne-shell ++@opindex -b ++@opindex --sh ++@opindex --bourne-shell ++@cindex Bourne shell syntax for color setup ++@cindex @command{sh} syntax for color setup ++Output Bourne shell commands. This is the default if the @env{SHELL} ++environment variable is set and does not end with @samp{csh} or ++@samp{tcsh}. ++ ++@item -c ++@itemx --csh ++@itemx --c-shell ++@opindex -c ++@opindex --csh ++@opindex --c-shell ++@cindex C shell syntax for color setup ++@cindex @command{csh} syntax for color setup ++Output C shell commands. This is the default if @code{SHELL} ends with ++@command{csh} or @command{tcsh}. ++ ++@item -p ++@itemx --print-database ++@opindex -p ++@opindex --print-database ++@cindex color database, printing ++@cindex database for color setup, printing ++@cindex printing color database ++Print the (compiled-in) default color configuration database. This ++output is itself a valid configuration file, and is fairly descriptive ++of the possibilities. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node Basic operations ++@chapter Basic operations ++ ++@cindex manipulating files ++ ++This chapter describes the commands for basic file manipulation: ++copying, moving (renaming), and deleting (removing). ++ ++@menu ++* cp invocation:: Copy files. ++* dd invocation:: Convert and copy a file. ++* install invocation:: Copy files and set attributes. ++* mv invocation:: Move (rename) files. ++* rm invocation:: Remove files or directories. ++* shred invocation:: Remove files more securely. ++@end menu ++ ++ ++@node cp invocation ++@section @command{cp}: Copy files and directories ++ ++@pindex cp ++@cindex copying files and directories ++@cindex files, copying ++@cindex directories, copying ++ ++@command{cp} copies files (or, optionally, directories). The copy is ++completely independent of the original. You can either copy one file to ++another, or copy arbitrarily many files to a destination directory. ++Synopses: ++ ++@example ++cp [@var{option}]@dots{} [-T] @var{source} @var{dest} ++cp [@var{option}]@dots{} @var{source}@dots{} @var{directory} ++cp [@var{option}]@dots{} -t @var{directory} @var{source}@dots{} ++@end example ++ ++@itemize @bullet ++@item ++If two file names are given, @command{cp} copies the first file to the ++second. ++ ++@item ++If the @option{--target-directory} (@option{-t}) option is given, or ++failing that if the last file is a directory and the ++@option{--no-target-directory} (@option{-T}) option is not given, ++@command{cp} copies each @var{source} file to the specified directory, ++using the @var{source}s' names. ++@end itemize ++ ++Generally, files are written just as they are read. For exceptions, ++see the @option{--sparse} option below. ++ ++By default, @command{cp} does not copy directories. However, the ++@option{-R}, @option{-a}, and @option{-r} options cause @command{cp} to ++copy recursively by descending into source directories and copying files ++to corresponding destination directories. ++ ++When copying from a symbolic link, @command{cp} normally follows the ++link only when not copying ++recursively. This default can be overridden with the ++@option{--archive} (@option{-a}), @option{-d}, @option{--dereference} ++(@option{-L}), @option{--no-dereference} (@option{-P}), and ++@option{-H} options. If more than one of these options is specified, ++the last one silently overrides the others. ++ ++When copying to a symbolic link, @command{cp} follows the ++link only when it refers to an existing regular file. ++However, when copying to a dangling symbolic link, @command{cp} ++refuses by default, and fails with a diagnostic, since the operation ++is inherently dangerous. This behavior is contrary to historical ++practice and to @acronym{POSIX}. ++Set @env{POSIXLY_CORRECT} to make @command{cp} attempt to create ++the target of a dangling destination symlink, in spite of the possible risk. ++Also, when an option like ++@option{--backup} or @option{--link} acts to rename or remove the ++destination before copying, @command{cp} renames or removes the ++symbolic link rather than the file it points to. ++ ++By default, @command{cp} copies the contents of special files only ++when not copying recursively. This default can be overridden with the ++@option{--copy-contents} option. ++ ++@cindex self-backups ++@cindex backups, making only ++@command{cp} generally refuses to copy a file onto itself, with the ++following exception: if @option{--force --backup} is specified with ++@var{source} and @var{dest} identical, and referring to a regular file, ++@command{cp} will make a backup file, either regular or numbered, as ++specified in the usual ways (@pxref{Backup options}). This is useful when ++you simply want to make a backup of an existing file before changing it. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++@item -a ++@itemx --archive ++@opindex -a ++@opindex --archive ++Preserve as much as possible of the structure and attributes of the ++original files in the copy (but do not attempt to preserve internal ++directory structure; i.e., @samp{ls -U} may list the entries in a copied ++directory in a different order). ++Try to preserve SELinux security context and extended attributes (xattr), ++but ignore any failure to do that and print no corresponding diagnostic. ++Equivalent to @option{-dR --preserve=all} with the reduced diagnostics. ++ ++@item -b ++@itemx @w{@kbd{--backup}[=@var{method}]} ++@opindex -b ++@opindex --backup ++@vindex VERSION_CONTROL ++@cindex backups, making ++@xref{Backup options}. ++Make a backup of each file that would otherwise be overwritten or removed. ++As a special case, @command{cp} makes a backup of @var{source} when the force ++and backup options are given and @var{source} and @var{dest} are the same ++name for an existing, regular file. One useful application of this ++combination of options is this tiny Bourne shell script: ++ ++@example ++#!/bin/sh ++# Usage: backup FILE... ++# Create a @sc{gnu}-style backup of each listed FILE. ++for i; do ++ cp --backup --force -- "$i" "$i" ++done ++@end example ++ ++@item --copy-contents ++@cindex directories, copying recursively ++@cindex copying directories recursively ++@cindex recursively copying directories ++@cindex non-directories, copying as special files ++If copying recursively, copy the contents of any special files (e.g., ++FIFOs and device files) as if they were regular files. This means ++trying to read the data in each source file and writing it to the ++destination. It is usually a mistake to use this option, as it ++normally has undesirable effects on special files like FIFOs and the ++ones typically found in the @file{/dev} directory. In most cases, ++@code{cp -R --copy-contents} will hang indefinitely trying to read ++from FIFOs and special files like @file{/dev/console}, and it will ++fill up your destination disk if you use it to copy @file{/dev/zero}. ++This option has no effect unless copying recursively, and it does not ++affect the copying of symbolic links. ++ ++@item -d ++@opindex -d ++@cindex symbolic links, copying ++@cindex hard links, preserving ++Copy symbolic links as symbolic links rather than copying the files that ++they point to, and preserve hard links between source files in the copies. ++Equivalent to @option{--no-dereference --preserve=links}. ++ ++@item -f ++@itemx --force ++@opindex -f ++@opindex --force ++When copying without this option and an existing destination file cannot ++be opened for writing, the copy fails. However, with @option{--force}), ++when a destination file cannot be opened, @command{cp} then removes it and ++tries to open it again. Contrast this behavior with that enabled by ++@option{--link} and @option{--symbolic-link}, whereby the destination file ++is never opened but rather is removed unconditionally. Also see the ++description of @option{--remove-destination}. ++ ++This option is independent of the @option{--interactive} or ++@option{-i} option: neither cancels the effect of the other. ++ ++This option is redundant if the @option{--no-clobber} or @option{-n} option is ++used. ++ ++@item -H ++@opindex -H ++If a command line argument specifies a symbolic link, then copy the ++file it points to rather than the symbolic link itself. However, ++copy (preserving its nature) any symbolic link that is encountered ++via recursive traversal. ++ ++@item -i ++@itemx --interactive ++@opindex -i ++@opindex --interactive ++When copying a file other than a directory, prompt whether to ++overwrite an existing destination file. The @option{-i} option overrides ++a previous @option{-n} option. ++ ++@item -l ++@itemx --link ++@opindex -l ++@opindex --link ++Make hard links instead of copies of non-directories. ++ ++@item -L ++@itemx --dereference ++@opindex -L ++@opindex --dereference ++Follow symbolic links when copying from them. ++With this option, @command{cp} cannot create a symbolic link. ++For example, a symlink (to regular file) in the source tree will be copied to ++a regular file in the destination tree. ++ ++@item -n ++@itemx --no-clobber ++@opindex -n ++@opindex --no-clobber ++Do not overwrite an existing file. The @option{-n} option overrides a previous ++@option{-i} option. This option is mutually exclusive with @option{-b} or ++@option{--backup} option. ++ ++@item -P ++@itemx --no-dereference ++@opindex -P ++@opindex --no-dereference ++@cindex symbolic links, copying ++Copy symbolic links as symbolic links rather than copying the files that ++they point to. This option affects only symbolic links in the source; ++symbolic links in the destination are always followed if possible. ++ ++@item -p ++@itemx @w{@kbd{--preserve}[=@var{attribute_list}]} ++@opindex -p ++@opindex --preserve ++@cindex file information, preserving, extended attributes, xattr ++Preserve the specified attributes of the original files. ++If specified, the @var{attribute_list} must be a comma-separated list ++of one or more of the following strings: ++ ++@table @samp ++@itemx mode ++Preserve the file mode bits and access control lists. ++@itemx ownership ++Preserve the owner and group. On most modern systems, ++only users with appropriate privileges may change the owner of a file, ++and ordinary users ++may preserve the group ownership of a file only if they happen to be ++a member of the desired group. ++@itemx timestamps ++Preserve the times of last access and last modification, when possible. ++On older systems, it is not possible to preserve these attributes ++when the affected file is a symbolic link. ++However, many systems now provide the @code{utimensat} function, ++which makes it possible even for symbolic links. ++@itemx links ++Preserve in the destination files ++any links between corresponding source files. ++Note that with @option{-L} or @option{-H}, this option can convert ++symbolic links to hard links. For example, ++@example ++$ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c ++74161745 a ++74161745 b ++@end example ++@noindent ++Note the inputs: @file{b} is a symlink to regular file @file{a}, ++yet the files in destination directory, @file{c/}, are hard-linked. ++Since @option{-a} implies @option{--preserve=links}, and since @option{-H} ++tells @command{cp} to dereference command line arguments, it sees two files ++with the same inode number, and preserves the perceived hard link. ++ ++Here is a similar example that exercises @command{cp}'s @option{-L} option: ++@smallexample ++$ mkdir b c; (cd b; : > a; ln -s a b); cp -aL b c; ls -i1 c/b ++74163295 a ++74163295 b ++@end smallexample ++ ++@itemx context ++Preserve SELinux security context of the file. @command{cp} will fail ++if the preserving of SELinux security context is not succesful. ++@itemx xattr ++Preserve extended attributes if @command{cp} is built with xattr support, ++and xattrs are supported and enabled on your file system. ++If SELinux context and/or ACLs are implemented using xattrs, ++they are preserved by this option as well. ++@itemx all ++Preserve all file attributes. ++Equivalent to specifying all of the above, but with the difference ++that failure to preserve SELinux security context or extended attributes ++does not change @command{cp}'s exit status. ++@command{cp} does diagnose such failures. ++@end table ++ ++Using @option{--preserve} with no @var{attribute_list} is equivalent ++to @option{--preserve=mode,ownership,timestamps}. ++ ++In the absence of this option, each destination file is created with the ++mode bits of the corresponding source file, minus the bits set in the ++umask and minus the set-user-ID and set-group-ID bits. ++@xref{File permissions}. ++ ++@itemx @w{@kbd{--no-preserve}=@var{attribute_list}} ++@cindex file information, preserving ++Do not preserve the specified attributes. The @var{attribute_list} ++has the same form as for @option{--preserve}. ++ ++@itemx --parents ++@opindex --parents ++@cindex parent directories and @command{cp} ++Form the name of each destination file by appending to the target ++directory a slash and the specified name of the source file. The last ++argument given to @command{cp} must be the name of an existing directory. ++For example, the command: ++ ++@example ++cp --parents a/b/c existing_dir ++@end example ++ ++@noindent ++copies the file @file{a/b/c} to @file{existing_dir/a/b/c}, creating ++any missing intermediate directories. ++ ++@item -R ++@itemx -r ++@itemx --recursive ++@opindex -R ++@opindex -r ++@opindex --recursive ++@cindex directories, copying recursively ++@cindex copying directories recursively ++@cindex recursively copying directories ++@cindex non-directories, copying as special files ++Copy directories recursively. By default, do not follow symbolic ++links in the source; see the @option{--archive} (@option{-a}), @option{-d}, ++@option{--dereference} (@option{-L}), @option{--no-dereference} ++(@option{-P}), and @option{-H} options. Special files are copied by ++creating a destination file of the same type as the source; see the ++@option{--copy-contents} option. It is not portable to use ++@option{-r} to copy symbolic links or special files. On some ++non-@sc{gnu} systems, @option{-r} implies the equivalent of ++@option{-L} and @option{--copy-contents} for historical reasons. ++Also, it is not portable to use @option{-R} to copy symbolic links ++unless you also specify @option{-P}, as @acronym{POSIX} allows ++implementations that dereference symbolic links by default. ++ ++@item --reflink[=@var{when}] ++@opindex --reflink[=@var{when}] ++@cindex COW ++@cindex clone ++@cindex copy on write ++Perform a lightweight, copy-on-write (COW) copy. ++Copying with this option can succeed only on some file systems. ++Once it has succeeded, beware that the source and destination files ++share the same disk data blocks as long as they remain unmodified. ++Thus, if a disk I/O error affects data blocks of one of the files, ++the other suffers the exact same fate. ++ ++The @var{when} value can be one of the following: ++ ++@table @samp ++@item always ++The default behavior: if the copy-on-write operation is not supported ++then report the failure for each file and exit with a failure status. ++ ++@item auto ++If the copy-on-write operation is not supported then fall back ++to the standard copy behaviour. ++@end table ++ ++ ++@item --remove-destination ++@opindex --remove-destination ++Remove each existing destination file before attempting to open it ++(contrast with @option{-f} above). ++ ++@item --sparse=@var{when} ++@opindex --sparse=@var{when} ++@cindex sparse files, copying ++@cindex holes, copying files with ++@findex read @r{system call, and holes} ++A @dfn{sparse file} contains @dfn{holes}---a sequence of zero bytes that ++does not occupy any physical disk blocks; the @samp{read} system call ++reads these as zeros. This can both save considerable disk space and ++increase speed, since many binary files contain lots of consecutive zero ++bytes. By default, @command{cp} detects holes in input source files via a crude ++heuristic and makes the corresponding output file sparse as well. ++Only regular files may be sparse. ++ ++The @var{when} value can be one of the following: ++ ++@table @samp ++@item auto ++The default behavior: if the input file is sparse, attempt to make ++the output file sparse, too. However, if an output file exists but ++refers to a non-regular file, then do not attempt to make it sparse. ++ ++@item always ++For each sufficiently long sequence of zero bytes in the input file, ++attempt to create a corresponding hole in the output file, even if the ++input file does not appear to be sparse. ++This is useful when the input file resides on a file system ++that does not support sparse files ++(for example, @samp{efs} file systems in SGI IRIX 5.3 and earlier), ++but the output file is on a type of file system that does support them. ++Holes may be created only in regular files, so if the destination file ++is of some other type, @command{cp} does not even try to make it sparse. ++ ++@item never ++Never make the output file sparse. ++This is useful in creating a file for use with the @command{mkswap} command, ++since such a file must not have any holes. ++@end table ++ ++@optStripTrailingSlashes ++ ++@item -s ++@itemx --symbolic-link ++@opindex -s ++@opindex --symbolic-link ++@cindex symbolic links, copying with ++Make symbolic links instead of copies of non-directories. All source ++file names must be absolute (starting with @samp{/}) unless the ++destination files are in the current directory. This option merely ++results in an error message on systems that do not support symbolic links. ++ ++@optBackupSuffix ++ ++@optTargetDirectory ++ ++@optNoTargetDirectory ++ ++@item -u ++@itemx --update ++@opindex -u ++@opindex --update ++@cindex newer files, copying only ++Do not copy a non-directory that has an existing destination with the ++same or newer modification time. If time stamps are being preserved, ++the comparison is to the source time stamp truncated to the ++resolutions of the destination file system and of the system calls ++used to update time stamps; this avoids duplicate work if several ++@samp{cp -pu} commands are executed with the same source and ++destination. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Print the name of each file before copying it. ++ ++@item -x ++@itemx --one-file-system ++@opindex -x ++@opindex --one-file-system ++@cindex file systems, omitting copying to different ++Skip subdirectories that are on different file systems from the one that ++the copy started on. ++However, mount point directories @emph{are} copied. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node dd invocation ++@section @command{dd}: Convert and copy a file ++ ++@pindex dd ++@cindex converting while copying a file ++ ++@command{dd} copies a file (from standard input to standard output, by ++default) with a changeable I/O block size, while optionally performing ++conversions on it. Synopses: ++ ++@example ++dd [@var{operand}]@dots{} ++dd @var{option} ++@end example ++ ++The only options are @option{--help} and @option{--version}. ++@xref{Common options}. @command{dd} accepts the following operands. ++ ++@table @samp ++ ++@item if=@var{file} ++@opindex if ++Read from @var{file} instead of standard input. ++ ++@item of=@var{file} ++@opindex of ++Write to @var{file} instead of standard output. Unless ++@samp{conv=notrunc} is given, @command{dd} truncates @var{file} to zero ++bytes (or the size specified with @samp{seek=}). ++ ++@item ibs=@var{bytes} ++@opindex ibs ++@cindex block size of input ++@cindex input block size ++Set the input block size to @var{bytes}. ++This makes @command{dd} read @var{bytes} per block. ++The default is 512 bytes. ++ ++@item obs=@var{bytes} ++@opindex obs ++@cindex block size of output ++@cindex output block size ++Set the output block size to @var{bytes}. ++This makes @command{dd} write @var{bytes} per block. ++The default is 512 bytes. ++ ++@item bs=@var{bytes} ++@opindex bs ++@cindex block size ++Set both input and output block sizes to @var{bytes}. ++This makes @command{dd} read and write @var{bytes} per block, ++overriding any @samp{ibs} and @samp{obs} settings. ++In addition, if no data-transforming @option{conv} option is specified, ++each input block is copied to the output as a single block, ++without aggregating short reads. ++ ++@item cbs=@var{bytes} ++@opindex cbs ++@cindex block size of conversion ++@cindex conversion block size ++@cindex fixed-length records, converting to variable-length ++@cindex variable-length records, converting to fixed-length ++Set the conversion block size to @var{bytes}. ++When converting variable-length records to fixed-length ones ++(@option{conv=block}) or the reverse (@option{conv=unblock}), ++use @var{bytes} as the fixed record length. ++ ++@item skip=@var{blocks} ++@opindex skip ++Skip @var{blocks} @samp{ibs}-byte blocks in the input file before copying. ++ ++@item seek=@var{blocks} ++@opindex seek ++Skip @var{blocks} @samp{obs}-byte blocks in the output file before copying. ++ ++@item count=@var{blocks} ++@opindex count ++Copy @var{blocks} @samp{ibs}-byte blocks from the input file, instead ++of everything until the end of the file. ++ ++@item status=noxfer ++@opindex status ++Do not print the overall transfer rate and volume statistics ++that normally make up the third status line when @command{dd} exits. ++ ++@item conv=@var{conversion}[,@var{conversion}]@dots{} ++@opindex conv ++Convert the file as specified by the @var{conversion} argument(s). ++(No spaces around any comma(s).) ++ ++Conversions: ++ ++@table @samp ++ ++@item ascii ++@opindex ascii@r{, converting to} ++Convert @acronym{EBCDIC} to @acronym{ASCII}, ++using the conversion table specified by @acronym{POSIX}. ++This provides a 1:1 translation for all 256 bytes. ++ ++@item ebcdic ++@opindex ebcdic@r{, converting to} ++Convert @acronym{ASCII} to @acronym{EBCDIC}. ++This is the inverse of the @samp{ascii} conversion. ++ ++@item ibm ++@opindex alternate ebcdic@r{, converting to} ++Convert @acronym{ASCII} to alternate @acronym{EBCDIC}, ++using the alternate conversion table specified by @acronym{POSIX}. ++This is not a 1:1 translation, but reflects common historical practice ++for @samp{~}, @samp{[}, and @samp{]}. ++ ++The @samp{ascii}, @samp{ebcdic}, and @samp{ibm} conversions are ++mutually exclusive. ++ ++@item block ++@opindex block @r{(space-padding)} ++For each line in the input, output @samp{cbs} bytes, replacing the ++input newline with a space and padding with spaces as necessary. ++ ++@item unblock ++@opindex unblock ++Remove any trailing spaces in each @samp{cbs}-sized input block, ++and append a newline. ++ ++The @samp{block} and @samp{unblock} conversions are mutually exclusive. ++ ++@item lcase ++@opindex lcase@r{, converting to} ++Change uppercase letters to lowercase. ++ ++@item ucase ++@opindex ucase@r{, converting to} ++Change lowercase letters to uppercase. ++ ++The @samp{lcase} and @samp{ucase} conversions are mutually exclusive. ++ ++@item swab ++@opindex swab @r{(byte-swapping)} ++@cindex byte-swapping ++Swap every pair of input bytes. @sc{gnu} @command{dd}, unlike others, works ++when an odd number of bytes are read---the last byte is simply copied ++(since there is nothing to swap it with). ++ ++@item noerror ++@opindex noerror ++@cindex read errors, ignoring ++Continue after read errors. ++ ++@item nocreat ++@opindex nocreat ++@cindex creating output file, avoiding ++Do not create the output file; the output file must already exist. ++ ++@item excl ++@opindex excl ++@cindex creating output file, requiring ++Fail if the output file already exists; @command{dd} must create the ++output file itself. ++ ++The @samp{excl} and @samp{nocreat} conversions are mutually exclusive. ++ ++@item notrunc ++@opindex notrunc ++@cindex truncating output file, avoiding ++Do not truncate the output file. ++ ++@item sync ++@opindex sync @r{(padding with @acronym{ASCII} @sc{nul}s)} ++Pad every input block to size of @samp{ibs} with trailing zero bytes. ++When used with @samp{block} or @samp{unblock}, pad with spaces instead of ++zero bytes. ++ ++@item fdatasync ++@opindex fdatasync ++@cindex synchronized data writes, before finishing ++Synchronize output data just before finishing. This forces a physical ++write of output data. ++ ++@item fsync ++@opindex fsync ++@cindex synchronized data and metadata writes, before finishing ++Synchronize output data and metadata just before finishing. This ++forces a physical write of output data and metadata. ++ ++@end table ++ ++@item iflag=@var{flag}[,@var{flag}]@dots{} ++@opindex iflag ++Access the input file using the flags specified by the @var{flag} ++argument(s). (No spaces around any comma(s).) ++ ++@item oflag=@var{flag}[,@var{flag}]@dots{} ++@opindex oflag ++Access the output file using the flags specified by the @var{flag} ++argument(s). (No spaces around any comma(s).) ++ ++Here are the flags. Not every flag is supported on every operating ++system. ++ ++@table @samp ++ ++@item append ++@opindex append ++@cindex appending to the output file ++Write in append mode, so that even if some other process is writing to ++this file, every @command{dd} write will append to the current ++contents of the file. This flag makes sense only for output. ++If you combine this flag with the @samp{of=@var{file}} operand, ++you should also specify @samp{conv=notrunc} unless you want the ++output file to be truncated before being appended to. ++ ++@item cio ++@opindex cio ++@cindex concurrent I/O ++Use concurrent I/O mode for data. This mode performs direct I/O ++and drops the @acronym{POSIX} requirement to serialize all I/O to the same file. ++A file cannot be opened in CIO mode and with a standard open at the ++same time. ++ ++@item direct ++@opindex direct ++@cindex direct I/O ++Use direct I/O for data, avoiding the buffer cache. ++Note that the kernel may impose restrictions on read or write buffer sizes. ++For example, with an ext4 destination file system and a linux-based kernel, ++using @samp{oflag=direct} will cause writes to fail with @code{EINVAL} if the ++output buffer size is not a multiple of 512. ++ ++@item directory ++@opindex directory ++@cindex directory I/O ++ ++Fail unless the file is a directory. Most operating systems do not ++allow I/O to a directory, so this flag has limited utility. ++ ++@item dsync ++@opindex dsync ++@cindex synchronized data reads ++Use synchronized I/O for data. For the output file, this forces a ++physical write of output data on each write. For the input file, ++this flag can matter when reading from a remote file that has been ++written to synchronously by some other process. Metadata (e.g., ++last-access and last-modified time) is not necessarily synchronized. ++ ++@item sync ++@opindex sync ++@cindex synchronized data and metadata I/O ++Use synchronized I/O for both data and metadata. ++ ++@item nonblock ++@opindex nonblock ++@cindex nonblocking I/O ++Use non-blocking I/O. ++ ++@item noatime ++@opindex noatime ++@cindex access time ++Do not update the file's access time. ++Some older file systems silently ignore this flag, so it is a good ++idea to test it on your files before relying on it. ++ ++@item noctty ++@opindex noctty ++@cindex controlling terminal ++Do not assign the file to be a controlling terminal for @command{dd}. ++This has no effect when the file is not a terminal. ++On many hosts (e.g., @acronym{GNU}/Linux hosts), this option has no effect ++at all. ++ ++@item nofollow ++@opindex nofollow ++@cindex symbolic links, following ++Do not follow symbolic links. ++ ++@item nolinks ++@opindex nolinks ++@cindex hard links ++Fail if the file has multiple hard links. ++ ++@item binary ++@opindex binary ++@cindex binary I/O ++Use binary I/O. This option has an effect only on nonstandard ++platforms that distinguish binary from text I/O. ++ ++@item text ++@opindex text ++@cindex text I/O ++Use text I/O. Like @samp{binary}, this option has no effect on ++standard platforms. ++ ++@item fullblock ++@opindex fullblock ++Accumulate full blocks from input. The @code{read} system call ++may return early if a full block is not available. ++When that happens, continue calling @code{read} to fill the remainder ++of the block. ++This flag can be used only with @code{iflag}. ++ ++@end table ++ ++These flags are not supported on all systems, and @samp{dd} rejects ++attempts to use them when they are not supported. When reading from ++standard input or writing to standard output, the @samp{nofollow} and ++@samp{noctty} flags should not be specified, and the other flags ++(e.g., @samp{nonblock}) can affect how other processes behave with the ++affected file descriptors, even after @command{dd} exits. ++ ++@end table ++ ++@cindex multipliers after numbers ++The numeric-valued strings above (@var{bytes} and @var{blocks}) can be ++followed by a multiplier: @samp{b}=512, @samp{c}=1, ++@samp{w}=2, @samp{x@var{m}}=@var{m}, or any of the ++standard block size suffixes like @samp{k}=1024 (@pxref{Block size}). ++ ++Use different @command{dd} invocations to use different block sizes for ++skipping and I/O@. For example, the following shell commands copy data ++in 512 KiB blocks between a disk and a tape, but do not save or restore a ++4 KiB label at the start of the disk: ++ ++@example ++disk=/dev/rdsk/c0t1d0s2 ++tape=/dev/rmt/0 ++ ++# Copy all but the label from disk to tape. ++(dd bs=4k skip=1 count=0 && dd bs=512k) <$disk >$tape ++ ++# Copy from tape back to disk, but leave the disk label alone. ++(dd bs=4k seek=1 count=0 && dd bs=512k) <$tape >$disk ++@end example ++ ++Sending an @samp{INFO} signal to a running @command{dd} ++process makes it print I/O statistics to standard error ++and then resume copying. In the example below, ++@command{dd} is run in the background to copy 10 million blocks. ++The @command{kill} command makes it output intermediate I/O statistics, ++and when @command{dd} completes normally or is killed by the ++@code{SIGINT} signal, it outputs the final statistics. ++ ++@example ++$ dd if=/dev/zero of=/dev/null count=10MB & pid=$! ++$ kill -s INFO $pid; wait $pid ++3385223+0 records in ++3385223+0 records out ++1733234176 bytes (1.7 GB) copied, 6.42173 seconds, 270 MB/s ++10000000+0 records in ++10000000+0 records out ++5120000000 bytes (5.1 GB) copied, 18.913 seconds, 271 MB/s ++@end example ++ ++@vindex POSIXLY_CORRECT ++On systems lacking the @samp{INFO} signal @command{dd} responds to the ++@samp{USR1} signal instead, unless the @env{POSIXLY_CORRECT} ++environment variable is set. ++ ++@exitstatus ++ ++ ++@node install invocation ++@section @command{install}: Copy files and set attributes ++ ++@pindex install ++@cindex copying files and setting attributes ++ ++@command{install} copies files while setting their file mode bits and, if ++possible, their owner and group. Synopses: ++ ++@example ++install [@var{option}]@dots{} [-T] @var{source} @var{dest} ++install [@var{option}]@dots{} @var{source}@dots{} @var{directory} ++install [@var{option}]@dots{} -t @var{directory} @var{source}@dots{} ++install [@var{option}]@dots{} -d @var{directory}@dots{} ++@end example ++ ++@itemize @bullet ++@item ++If two file names are given, @command{install} copies the first file to the ++second. ++ ++@item ++If the @option{--target-directory} (@option{-t}) option is given, or ++failing that if the last file is a directory and the ++@option{--no-target-directory} (@option{-T}) option is not given, ++@command{install} copies each @var{source} file to the specified ++directory, using the @var{source}s' names. ++ ++@item ++If the @option{--directory} (@option{-d}) option is given, ++@command{install} creates each @var{directory} and any missing parent ++directories. Parent directories are created with mode ++@samp{u=rwx,go=rx} (755), regardless of the @option{-m} option or the ++current umask. @xref{Directory Setuid and Setgid}, for how the ++set-user-ID and set-group-ID bits of parent directories are inherited. ++@end itemize ++ ++@cindex Makefiles, installing programs in ++@command{install} is similar to @command{cp}, but allows you to control the ++attributes of destination files. It is typically used in Makefiles to ++copy programs into their destination directories. It refuses to copy ++files onto themselves. ++ ++@cindex extended attributes, xattr ++@command{install} never preserves extended attributes (xattr). ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@optBackup ++ ++@item -C ++@itemx --compare ++@opindex -C ++@opindex --compare ++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. ++ ++@item -c ++@opindex -c ++Ignored; for compatibility with old Unix versions of @command{install}. ++ ++@item -D ++@opindex -D ++Create any missing parent directories of @var{dest}, ++then copy @var{source} to @var{dest}. ++This option is ignored if a destination directory is specified ++via @option{--target-directory=DIR}. ++ ++@item -d ++@itemx --directory ++@opindex -d ++@opindex --directory ++@cindex directories, creating with given attributes ++@cindex parent directories, creating missing ++@cindex leading directories, creating missing ++Create any missing parent directories, giving them the default ++attributes. Then create each given directory, setting their owner, ++group and mode as given on the command line or to the defaults. ++ ++@item -g @var{group} ++@itemx --group=@var{group} ++@opindex -g ++@opindex --group ++@cindex group ownership of installed files, setting ++Set the group ownership of installed files or directories to ++@var{group}. The default is the process's current group. @var{group} ++may be either a group name or a numeric group ID. ++ ++@item -m @var{mode} ++@itemx --mode=@var{mode} ++@opindex -m ++@opindex --mode ++@cindex permissions of installed files, setting ++Set the file mode bits for the installed file or directory to @var{mode}, ++which can be either an octal number, or a symbolic mode as in ++@command{chmod}, with @samp{a=} (no access allowed to anyone) as the ++point of departure (@pxref{File permissions}). ++The default mode is @samp{u=rwx,go=rx,a-s}---read, write, and ++execute for the owner, read and execute for group and other, and with ++set-user-ID and set-group-ID disabled. ++This default is not quite the same as @samp{755}, since it disables ++instead of preserving set-user-ID and set-group-ID on directories. ++@xref{Directory Setuid and Setgid}. ++ ++@item -o @var{owner} ++@itemx --owner=@var{owner} ++@opindex -o ++@opindex --owner ++@cindex ownership of installed files, setting ++@cindex appropriate privileges ++@vindex root @r{as default owner} ++If @command{install} has appropriate privileges (is run as root), set the ++ownership of installed files or directories to @var{owner}. The default ++is @code{root}. @var{owner} may be either a user name or a numeric user ++ID. ++ ++@item --preserve-context ++@opindex --preserve-context ++@cindex SELinux ++@cindex security context ++Preserve the SELinux security context of files and directories. ++Failure to preserve the context in all of the files or directories ++will result in an exit status of 1. If SELinux is disabled then ++print a warning and ignore the option. ++ ++@item -p ++@itemx --preserve-timestamps ++@opindex -p ++@opindex --preserve-timestamps ++@cindex timestamps of installed files, preserving ++Set the time of last access and the time of last modification of each ++installed file to match those of each corresponding original file. ++When a file is installed without this option, its last access and ++last modification times are both set to the time of installation. ++This option is useful if you want to use the last modification times ++of installed files to keep track of when they were last built as opposed ++to when they were last installed. ++ ++@item -s ++@itemx --strip ++@opindex -s ++@opindex --strip ++@cindex symbol table information, stripping ++@cindex stripping symbol table information ++Strip the symbol tables from installed binary executables. ++ ++@itemx --strip-program=@var{program} ++@opindex --strip-program ++@cindex symbol table information, stripping, program ++Program used to strip binaries. ++ ++@optBackupSuffix ++ ++@optTargetDirectory ++ ++@optNoTargetDirectory ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Print the name of each file before copying it. ++ ++@item -Z @var{context} ++@itemx --context=@var{context} ++@opindex -Z ++@opindex --context ++@cindex SELinux ++@cindex security context ++Set the default SELinux security context to be used for any ++created files and directories. If SELinux is disabled then ++print a warning and ignore the option. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node mv invocation ++@section @command{mv}: Move (rename) files ++ ++@pindex mv ++ ++@command{mv} moves or renames files (or directories). Synopses: ++ ++@example ++mv [@var{option}]@dots{} [-T] @var{source} @var{dest} ++mv [@var{option}]@dots{} @var{source}@dots{} @var{directory} ++mv [@var{option}]@dots{} -t @var{directory} @var{source}@dots{} ++@end example ++ ++@itemize @bullet ++@item ++If two file names are given, @command{mv} moves the first file to the ++second. ++ ++@item ++If the @option{--target-directory} (@option{-t}) option is given, or ++failing that if the last file is a directory and the ++@option{--no-target-directory} (@option{-T}) option is not given, ++@command{mv} moves each @var{source} file to the specified ++directory, using the @var{source}s' names. ++@end itemize ++ ++@command{mv} can move any type of file from one file system to another. ++Prior to version @code{4.0} of the fileutils, ++@command{mv} could move only regular files between file systems. ++For example, now @command{mv} can move an entire directory hierarchy ++including special device files from one partition to another. It first ++uses some of the same code that's used by @code{cp -a} to copy the ++requested directories and files, then (assuming the copy succeeded) ++it removes the originals. If the copy fails, then the part that was ++copied to the destination partition is removed. If you were to copy ++three directories from one partition to another and the copy of the first ++directory succeeded, but the second didn't, the first would be left on ++the destination partition and the second and third would be left on the ++original partition. ++ ++@cindex extended attributes, xattr ++@command{mv} always tries to copy extended attributes (xattr). ++ ++@cindex prompting, and @command{mv} ++If a destination file exists but is normally unwritable, standard input ++is a terminal, and the @option{-f} or @option{--force} option is not given, ++@command{mv} prompts the user for whether to replace the file. (You might ++own the file, or have write permission on its directory.) If the ++response is not affirmative, the file is skipped. ++ ++@emph{Warning}: Avoid specifying a source name with a trailing slash, ++when it might be a symlink to a directory. ++Otherwise, @command{mv} may do something very surprising, since ++its behavior depends on the underlying rename system call. ++On a system with a modern Linux-based kernel, it fails with @code{errno=ENOTDIR}. ++However, on other systems (at least FreeBSD 6.1 and Solaris 10) it silently ++renames not the symlink but rather the directory referenced by the symlink. ++@xref{Trailing slashes}. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@optBackup ++ ++@item -f ++@itemx --force ++@opindex -f ++@opindex --force ++@cindex prompts, omitting ++Do not prompt the user before removing a destination file. ++@macro mvOptsIfn ++If you specify more than one of the @option{-i}, @option{-f}, @option{-n} ++options, only the final one takes effect. ++@end macro ++@mvOptsIfn ++ ++@item -i ++@itemx --interactive ++@opindex -i ++@opindex --interactive ++@cindex prompts, forcing ++Prompt whether to overwrite each existing destination file, regardless ++of its permissions. ++If the response is not affirmative, the file is skipped. ++@mvOptsIfn ++ ++@item -n ++@itemx --no-clobber ++@opindex -n ++@opindex --no-clobber ++@cindex prompts, omitting ++Do not overwrite an existing file. ++@mvOptsIfn ++This option is mutually exclusive with @option{-b} or @option{--backup} option. ++ ++@item -u ++@itemx --update ++@opindex -u ++@opindex --update ++@cindex newer files, moving only ++Do not move a non-directory that has an existing destination with the ++same or newer modification time. ++If the move is across file system boundaries, the comparison is to the ++source time stamp truncated to the resolutions of the destination file ++system and of the system calls used to update time stamps; this avoids ++duplicate work if several @samp{mv -u} commands are executed with the ++same source and destination. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Print the name of each file before moving it. ++ ++@optStripTrailingSlashes ++ ++@optBackupSuffix ++ ++@optTargetDirectory ++ ++@optNoTargetDirectory ++ ++@end table ++ ++@exitstatus ++ ++ ++@node rm invocation ++@section @command{rm}: Remove files or directories ++ ++@pindex rm ++@cindex removing files or directories ++ ++@command{rm} removes each given @var{file}. By default, it does not remove ++directories. Synopsis: ++ ++@example ++rm [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++@cindex prompting, and @command{rm} ++If the @option{-I} or @option{--interactive=once} option is given, ++and there are more than three files or the @option{-r}, @option{-R}, ++or @option{--recursive} are given, then @command{rm} prompts the user ++for whether to proceed with the entire operation. If the response is ++not affirmative, the entire command is aborted. ++ ++Otherwise, if a file is unwritable, standard input is a terminal, and ++the @option{-f} or @option{--force} option is not given, or the ++@option{-i} or @option{--interactive=always} option @emph{is} given, ++@command{rm} prompts the user for whether to remove the file. ++If the response is not affirmative, the file is skipped. ++ ++Any attempt to remove a file whose last file name component is ++@file{.} or @file{..} is rejected without any prompting. ++ ++@emph{Warning}: If you use @command{rm} to remove a file, it is usually ++possible to recover the contents of that file. If you want more assurance ++that the contents are truly unrecoverable, consider using @command{shred}. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -f ++@itemx --force ++@opindex -f ++@opindex --force ++Ignore nonexistent files and never prompt the user. ++Ignore any previous @option{--interactive} (@option{-i}) option. ++ ++@item -i ++@opindex -i ++Prompt whether to remove each file. ++If the response is not affirmative, the file is skipped. ++Ignore any previous @option{--force} (@option{-f}) option. ++Equivalent to @option{--interactive=always}. ++ ++@item -I ++@opindex -I ++Prompt once whether to proceed with the command, if more than three ++files are named or if a recursive removal is requested. Ignore any ++previous @option{--force} (@option{-f}) option. Equivalent to ++@option{--interactive=once}. ++ ++@itemx --interactive [=@var{when}] ++@opindex --interactive ++Specify when to issue an interactive prompt. @var{when} may be ++omitted, or one of: ++@itemize @bullet ++@item never ++@vindex never @r{interactive option} ++- Do not prompt at all. ++@item once ++@vindex once @r{interactive option} ++- Prompt once if more than three files are named or if a recursive ++removal is requested. Equivalent to @option{-I}. ++@item always ++@vindex always @r{interactive option} ++- Prompt for every file being removed. Equivalent to @option{-i}. ++@end itemize ++@option{--interactive} with no @var{when} is equivalent to ++@option{--interactive=always}. ++ ++@itemx --one-file-system ++@opindex --one-file-system ++@cindex one file system, restricting @command{rm} to ++When removing a hierarchy recursively, skip any directory that is on a ++file system different from that of the corresponding command line argument. ++ ++This option is useful when removing a build ``chroot'' hierarchy, ++which normally contains no valuable data. However, it is not uncommon ++to bind-mount @file{/home} into such a hierarchy, to make it easier to ++use one's start-up file. The catch is that it's easy to forget to ++unmount @file{/home}. Then, when you use @command{rm -rf} to remove ++your normally throw-away chroot, that command will remove everything ++under @file{/home}, too. ++Use the @option{--one-file-system} option, and it will ++warn about and skip directories on other file systems. ++Of course, this will not save your @file{/home} if it and your ++chroot happen to be on the same file system. ++ ++@itemx --preserve-root ++@opindex --preserve-root ++@cindex root directory, disallow recursive destruction ++Fail upon any attempt to remove the root directory, @file{/}, ++when used with the @option{--recursive} option. ++This is the default behavior. ++@xref{Treating / specially}. ++ ++@itemx --no-preserve-root ++@opindex --no-preserve-root ++@cindex root directory, allow recursive destruction ++Do not treat @file{/} specially when removing recursively. ++This option is not recommended unless you really want to ++remove all the files on your computer. ++@xref{Treating / specially}. ++ ++@item -r ++@itemx -R ++@itemx --recursive ++@opindex -r ++@opindex -R ++@opindex --recursive ++@cindex directories, removing (recursively) ++Remove the listed directories and their contents recursively. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Print the name of each file before removing it. ++ ++@end table ++ ++@cindex files beginning with @samp{-}, removing ++@cindex @samp{-}, removing files beginning with ++One common question is how to remove files whose names begin with a ++@samp{-}. @sc{gnu} @command{rm}, like every program that uses the @code{getopt} ++function to parse its arguments, lets you use the @samp{--} option to ++indicate that all following arguments are non-options. To remove a file ++called @file{-f} in the current directory, you could type either: ++ ++@example ++rm -- -f ++@end example ++ ++@noindent ++or: ++ ++@example ++rm ./-f ++@end example ++ ++@opindex - @r{and Unix @command{rm}} ++The Unix @command{rm} program's use of a single @samp{-} for this purpose ++predates the development of the getopt standard syntax. ++ ++@exitstatus ++ ++ ++@node shred invocation ++@section @command{shred}: Remove files more securely ++ ++@pindex shred ++@cindex data, erasing ++@cindex erasing data ++ ++@command{shred} overwrites devices or files, to help prevent even ++very expensive hardware from recovering the data. ++ ++Ordinarily when you remove a file (@pxref{rm invocation}), the data is ++not actually destroyed. Only the index listing where the file is ++stored is destroyed, and the storage is made available for reuse. ++There are undelete utilities that will attempt to reconstruct the index ++and can bring the file back if the parts were not reused. ++ ++On a busy system with a nearly-full drive, space can get reused in a few ++seconds. But there is no way to know for sure. If you have sensitive ++data, you may want to be sure that recovery is not possible by actually ++overwriting the file with non-sensitive data. ++ ++However, even after doing that, it is possible to take the disk back ++to a laboratory and use a lot of sensitive (and expensive) equipment ++to look for the faint ``echoes'' of the original data underneath the ++overwritten data. If the data has only been overwritten once, it's not ++even that hard. ++ ++The best way to remove something irretrievably is to destroy the media ++it's on with acid, melt it down, or the like. For cheap removable media ++like floppy disks, this is the preferred method. However, hard drives ++are expensive and hard to melt, so the @command{shred} utility tries ++to achieve a similar effect non-destructively. ++ ++This uses many overwrite passes, with the data patterns chosen to ++maximize the damage they do to the old data. While this will work on ++floppies, the patterns are designed for best effect on hard drives. ++For more details, see the source code and Peter Gutmann's paper ++@uref{http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html, ++@cite{Secure Deletion of Data from Magnetic and Solid-State Memory}}, ++from the proceedings of the Sixth @acronym{USENIX} Security Symposium (San Jose, ++California, July 22--25, 1996). ++ ++@strong{Please note} that @command{shred} relies on a very important assumption: ++that the file system overwrites data in place. This is the traditional ++way to do things, but many modern file system designs do not satisfy this ++assumption. Exceptions include: ++ ++@itemize @bullet ++ ++@item ++Log-structured or journaled file systems, such as those supplied with ++AIX and Solaris, and JFS, ReiserFS, XFS, Ext3 (in @code{data=journal} mode), ++BFS, NTFS, etc.@: when they are configured to journal @emph{data}. ++ ++@item ++File systems that write redundant data and carry on even if some writes ++fail, such as RAID-based file systems. ++ ++@item ++File systems that make snapshots, such as Network Appliance's NFS server. ++ ++@item ++File systems that cache in temporary locations, such as NFS version 3 ++clients. ++ ++@item ++Compressed file systems. ++@end itemize ++ ++In the particular case of ext3 file systems, the above disclaimer applies (and ++@command{shred} is thus of limited effectiveness) only in @code{data=journal} ++mode, which journals file data in addition to just metadata. In both ++the @code{data=ordered} (default) and @code{data=writeback} modes, ++@command{shred} works as usual. Ext3 journaling modes can be changed ++by adding the @code{data=something} option to the mount options for a ++particular file system in the @file{/etc/fstab} file, as documented in ++the mount man page (man mount). ++ ++If you are not sure how your file system operates, then you should assume ++that it does not overwrite data in place, which means that shred cannot ++reliably operate on regular files in your file system. ++ ++Generally speaking, it is more reliable to shred a device than a file, ++since this bypasses the problem of file system design mentioned above. ++However, even shredding devices is not always completely reliable. For ++example, most disks map out bad sectors invisibly to the application; if ++the bad sectors contain sensitive data, @command{shred} won't be able to ++destroy it. ++ ++@command{shred} makes no attempt to detect or report this problem, just as ++it makes no attempt to do anything about backups. However, since it is ++more reliable to shred devices than files, @command{shred} by default does ++not truncate or remove the output file. This default is more suitable ++for devices, which typically cannot be truncated and should not be ++removed. ++ ++Finally, consider the risk of backups and mirrors. ++File system backups and remote mirrors may contain copies of the ++file that cannot be removed, and that will allow a shredded file ++to be recovered later. So if you keep any data you may later want ++to destroy using @command{shred}, be sure that it is not backed up or mirrored. ++ ++@example ++shred [@var{option}]@dots{} @var{file}[@dots{}] ++@end example ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -f ++@itemx --force ++@opindex -f ++@opindex --force ++@cindex force deletion ++Override file permissions if necessary to allow overwriting. ++ ++@item -@var{number} ++@itemx -n @var{number} ++@itemx --iterations=@var{number} ++@opindex -n @var{number} ++@opindex --iterations=@var{number} ++@cindex iterations, selecting the number of ++By default, @command{shred} uses @value{SHRED_DEFAULT_PASSES} passes of ++overwrite. You can reduce this to save time, or increase it if you think it's ++appropriate. After 25 passes all of the internal overwrite patterns will have ++been used at least once. ++ ++@item --random-source=@var{file} ++@opindex --random-source ++@cindex random source for shredding ++Use @var{file} as a source of random data used to overwrite and to ++choose pass ordering. @xref{Random sources}. ++ ++@item -s @var{bytes} ++@itemx --size=@var{bytes} ++@opindex -s @var{bytes} ++@opindex --size=@var{bytes} ++@cindex size of file to shred ++Shred the first @var{bytes} bytes of the file. The default is to shred ++the whole file. @var{bytes} can be followed by a size specification like ++@samp{K}, @samp{M}, or @samp{G} to specify a multiple. @xref{Block size}. ++ ++@item -u ++@itemx --remove ++@opindex -u ++@opindex --remove ++@cindex removing files after shredding ++After shredding a file, truncate it (if possible) and then remove it. ++If a file has multiple links, only the named links will be removed. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Display to standard error all status updates as sterilization proceeds. ++ ++@item -x ++@itemx --exact ++@opindex -x ++@opindex --exact ++By default, @command{shred} rounds the size of a regular file up to the next ++multiple of the file system block size to fully erase the last block of the file. ++Use @option{--exact} to suppress that behavior. ++Thus, by default if you shred a 10-byte regular file on a system with 512-byte ++blocks, the resulting file will be 512 bytes long. With this option, ++shred does not increase the apparent size of the file. ++ ++@item -z ++@itemx --zero ++@opindex -z ++@opindex --zero ++Normally, the last pass that @command{shred} writes is made up of ++random data. If this would be conspicuous on your hard drive (for ++example, because it looks like encrypted data), or you just think ++it's tidier, the @option{--zero} option adds an additional overwrite pass with ++all zero bits. This is in addition to the number of passes specified ++by the @option{--iterations} option. ++ ++@end table ++ ++You might use the following command to erase all trace of the ++file system you'd created on the floppy disk in your first drive. ++That command takes about 20 minutes to erase a ``1.44MB'' (actually ++1440 KiB) floppy. ++ ++@example ++shred --verbose /dev/fd0 ++@end example ++ ++Similarly, to erase all data on a selected partition of ++your hard disk, you could give a command like this: ++ ++@example ++shred --verbose /dev/sda5 ++@end example ++ ++A @var{file} of @samp{-} denotes standard output. ++The intended use of this is to shred a removed temporary file. ++For example: ++ ++@example ++i=`tempfile -m 0600` ++exec 3<>"$i" ++rm -- "$i" ++echo "Hello, world" >&3 ++shred - >&3 ++exec 3>- ++@end example ++ ++However, the command @samp{shred - >file} does not shred the contents ++of @var{file}, since the shell truncates @var{file} before invoking ++@command{shred}. Use the command @samp{shred file} or (if using a ++Bourne-compatible shell) the command @samp{shred - 1<>file} instead. ++ ++@exitstatus ++ ++ ++@node Special file types ++@chapter Special file types ++ ++@cindex special file types ++@cindex file types, special ++ ++This chapter describes commands which create special types of files (and ++@command{rmdir}, which removes directories, one special file type). ++ ++@cindex special file types ++@cindex file types ++Although Unix-like operating systems have markedly fewer special file ++types than others, not @emph{everything} can be treated only as the ++undifferentiated byte stream of @dfn{normal files}. For example, when a ++file is created or removed, the system must record this information, ++which it does in a @dfn{directory}---a special type of file. Although ++you can read directories as normal files, if you're curious, in order ++for the system to do its job it must impose a structure, a certain ++order, on the bytes of the file. Thus it is a ``special'' type of file. ++ ++Besides directories, other special file types include named pipes ++(FIFOs), symbolic links, sockets, and so-called @dfn{special files}. ++ ++@menu ++* link invocation:: Make a hard link via the link syscall ++* ln invocation:: Make links between files. ++* mkdir invocation:: Make directories. ++* mkfifo invocation:: Make FIFOs (named pipes). ++* mknod invocation:: Make block or character special files. ++* readlink invocation:: Print value of a symlink or canonical file name. ++* rmdir invocation:: Remove empty directories. ++* unlink invocation:: Remove files via the unlink syscall ++@end menu ++ ++ ++@node link invocation ++@section @command{link}: Make a hard link via the link syscall ++ ++@pindex link ++@cindex links, creating ++@cindex hard links, creating ++@cindex creating links (hard only) ++ ++@command{link} creates a single hard link at a time. ++It is a minimalist interface to the system-provided ++@code{link} function. @xref{Hard Links, , , libc, ++The GNU C Library Reference Manual}. ++It avoids the bells and whistles of the more commonly-used ++@command{ln} command (@pxref{ln invocation}). ++Synopsis: ++ ++@example ++link @var{filename} @var{linkname} ++@end example ++ ++@var{filename} must specify an existing file, and @var{linkname} ++must specify a nonexistent entry in an existing directory. ++@command{link} simply calls @code{link (@var{filename}, @var{linkname})} ++to create the link. ++ ++On a @acronym{GNU} system, this command acts like @samp{ln --directory ++--no-target-directory @var{filename} @var{linkname}}. However, the ++@option{--directory} and @option{--no-target-directory} options are ++not specified by @acronym{POSIX}, and the @command{link} command is ++more portable in practice. ++ ++If @var{filename} is a symbolic link, it is unspecified whether ++@var{linkname} will be a hard link to the symbolic link or to the ++target of the symbolic link. Use @command{ln -P} or @command{ln -L} ++to specify which behavior is desired. ++ ++@exitstatus ++ ++ ++@node ln invocation ++@section @command{ln}: Make links between files ++ ++@pindex ln ++@cindex links, creating ++@cindex hard links, creating ++@cindex symbolic (soft) links, creating ++@cindex creating links (hard or soft) ++ ++@cindex file systems and hard links ++@command{ln} makes links between files. By default, it makes hard links; ++with the @option{-s} option, it makes symbolic (or @dfn{soft}) links. ++Synopses: ++ ++@example ++ln [@var{option}]@dots{} [-T] @var{target} @var{linkname} ++ln [@var{option}]@dots{} @var{target} ++ln [@var{option}]@dots{} @var{target}@dots{} @var{directory} ++ln [@var{option}]@dots{} -t @var{directory} @var{target}@dots{} ++@end example ++ ++@itemize @bullet ++ ++@item ++If two file names are given, @command{ln} creates a link to the first ++file from the second. ++ ++@item ++If one @var{target} is given, @command{ln} creates a link to that file ++in the current directory. ++ ++@item ++If the @option{--target-directory} (@option{-t}) option is given, or ++failing that if the last file is a directory and the ++@option{--no-target-directory} (@option{-T}) option is not given, ++@command{ln} creates a link to each @var{target} file in the specified ++directory, using the @var{target}s' names. ++ ++@end itemize ++ ++Normally @command{ln} does not remove existing files. Use the ++@option{--force} (@option{-f}) option to remove them unconditionally, ++the @option{--interactive} (@option{-i}) option to remove them ++conditionally, and the @option{--backup} (@option{-b}) option to ++rename them. ++ ++@cindex hard link, defined ++@cindex inode, and hard links ++A @dfn{hard link} is another name for an existing file; the link and the ++original are indistinguishable. Technically speaking, they share the ++same inode, and the inode contains all the information about a ++file---indeed, it is not incorrect to say that the inode @emph{is} the ++file. Most systems prohibit making a hard link to ++a directory; on those where it is allowed, only the super-user can do ++so (and with caution, since creating a cycle will cause problems to many ++other utilities). Hard links cannot cross file system boundaries. (These ++restrictions are not mandated by @acronym{POSIX}, however.) ++ ++@cindex dereferencing symbolic links ++@cindex symbolic link, defined ++@dfn{Symbolic links} (@dfn{symlinks} for short), on the other hand, are ++a special file type (which not all kernels support: System V release 3 ++(and older) systems lack symlinks) in which the link file actually ++refers to a different file, by name. When most operations (opening, ++reading, writing, and so on) are passed the symbolic link file, the ++kernel automatically @dfn{dereferences} the link and operates on the ++target of the link. But some operations (e.g., removing) work on the ++link file itself, rather than on its target. The owner and group of a ++symlink are not significant to file access performed through ++the link, but do have implications on deleting a symbolic link from a ++directory with the restricted deletion bit set. On the GNU system, ++the mode of a symlink has no significance and cannot be changed, but ++on some BSD systems, the mode can be changed and will affect whether ++the symlink will be traversed in file name resolution. @xref{Symbolic Links,,, ++libc, The GNU C Library Reference Manual}. ++ ++Symbolic links can contain arbitrary strings; a @dfn{dangling symlink} ++occurs when the string in the symlink does not resolve to a file. ++There are no restrictions against creating dangling symbolic links. ++There are trade-offs to using absolute or relative symlinks. An ++absolute symlink always points to the same file, even if the directory ++containing the link is moved. However, if the symlink is visible from ++more than one machine (such as on a networked file system), the file ++pointed to might not always be the same. A relative symbolic link is ++resolved in relation to the directory that contains the link, and is ++often useful in referring to files on the same device without regards ++to what name that device is mounted on when accessed via networked ++machines. ++ ++When creating a relative symlink in a different location than the ++current directory, the resolution of the symlink will be different ++than the resolution of the same string from the current directory. ++Therefore, many users prefer to first change directories to the ++location where the relative symlink will be created, so that ++tab-completion or other file resolution will find the same target as ++what will be placed in the symlink. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@optBackup ++ ++@item -d ++@itemx -F ++@itemx --directory ++@opindex -d ++@opindex -F ++@opindex --directory ++@cindex hard links to directories ++Allow users with appropriate privileges to attempt to make hard links ++to directories. ++However, note that this will probably fail due to ++system restrictions, even for the super-user. ++ ++@item -f ++@itemx --force ++@opindex -f ++@opindex --force ++Remove existing destination files. ++ ++@item -i ++@itemx --interactive ++@opindex -i ++@opindex --interactive ++@cindex prompting, and @command{ln} ++Prompt whether to remove existing destination files. ++ ++@item -L ++@itemx --logical ++@opindex -L ++@opindex --logical ++If @option{-s} is not in effect, and the source file is a symbolic ++link, create the hard link to the file referred to by the symbolic ++link, rather than the symbolic link itself. ++ ++@item -n ++@itemx --no-dereference ++@opindex -n ++@opindex --no-dereference ++Do not treat the last operand specially when it is a symbolic link to ++a directory. Instead, treat it as if it were a normal file. ++ ++When the destination is an actual directory (not a symlink to one), ++there is no ambiguity. The link is created in that directory. ++But when the specified destination is a symlink to a directory, ++there are two ways to treat the user's request. @command{ln} can ++treat the destination just as it would a normal directory and create ++the link in it. On the other hand, the destination can be viewed as a ++non-directory---as the symlink itself. In that case, @command{ln} ++must delete or backup that symlink before creating the new link. ++The default is to treat a destination that is a symlink to a directory ++just like a directory. ++ ++This option is weaker than the @option{--no-target-directory} ++(@option{-T}) option, so it has no effect if both options are given. ++ ++@item -P ++@itemx --physical ++@opindex -P ++@opindex --physical ++If @option{-s} is not in effect, and the source file is a symbolic ++link, create the hard link to the symbolic link itself. On platforms ++where this is not supported by the kernel, this option creates a ++symbolic link with identical contents; since symbolic link contents ++cannot be edited, any file name resolution performed through either ++link will be the same as if a hard link had been created. ++ ++@item -s ++@itemx --symbolic ++@opindex -s ++@opindex --symbolic ++Make symbolic links instead of hard links. This option merely produces ++an error message on systems that do not support symbolic links. ++ ++@optBackupSuffix ++ ++@optTargetDirectory ++ ++@optNoTargetDirectory ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Print the name of each file after linking it successfully. ++ ++@end table ++ ++@cindex hard links to symbolic links ++@cindex symbolic links and @command{ln} ++If @option{-L} and @option{-P} are both given, the last one takes ++precedence. If @option{-s} is also given, @option{-L} and @option{-P} ++are silently ignored. If neither option is given, then this ++implementation defaults to @option{-P} if the system @code{link} supports ++hard links to symbolic links (such as the GNU system), and @option{-L} ++if @code{link} follows symbolic links (such as on BSD). ++ ++@exitstatus ++ ++Examples: ++ ++@smallexample ++Bad Example: ++ ++# Create link ../a pointing to a in that directory. ++# Not really useful because it points to itself. ++ln -s a .. ++ ++Better Example: ++ ++# Change to the target before creating symlinks to avoid being confused. ++cd .. ++ln -s adir/a . ++ ++Bad Example: ++ ++# Hard coded file names don't move well. ++ln -s $(pwd)/a /some/dir/ ++ ++Better Example: ++ ++# Relative file names survive directory moves and also ++# work across networked file systems. ++ln -s afile anotherfile ++ln -s ../adir/afile yetanotherfile ++@end smallexample ++ ++ ++@node mkdir invocation ++@section @command{mkdir}: Make directories ++ ++@pindex mkdir ++@cindex directories, creating ++@cindex creating directories ++ ++@command{mkdir} creates directories with the specified names. Synopsis: ++ ++@example ++mkdir [@var{option}]@dots{} @var{name}@dots{} ++@end example ++ ++@command{mkdir} creates each directory @var{name} in the order given. ++It reports an error if @var{name} already exists, unless the ++@option{-p} option is given and @var{name} is a directory. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -m @var{mode} ++@itemx --mode=@var{mode} ++@opindex -m ++@opindex --mode ++@cindex modes of created directories, setting ++Set the file permission bits of created directories to @var{mode}, ++which uses the same syntax as ++in @command{chmod} and uses @samp{a=rwx} (read, write and execute allowed for ++everyone) for the point of the departure. @xref{File permissions}. ++ ++Normally the directory has the desired file mode bits at the moment it ++is created. As a @acronym{GNU} extension, @var{mode} may also mention ++special mode bits, but in this case there may be a temporary window ++during which the directory exists but its special mode bits are ++incorrect. @xref{Directory Setuid and Setgid}, for how the ++set-user-ID and set-group-ID bits of directories are inherited unless ++overridden in this way. ++ ++@item -p ++@itemx --parents ++@opindex -p ++@opindex --parents ++@cindex parent directories, creating ++Make any missing parent directories for each argument, setting their ++file permission bits to the umask modified by @samp{u+wx}. Ignore ++existing parent directories, and do not change their file permission ++bits. ++ ++To set the file permission bits of any newly-created parent ++directories to a value that includes @samp{u+wx}, you can set the ++umask before invoking @command{mkdir}. For example, if the shell ++command @samp{(umask u=rwx,go=rx; mkdir -p P/Q)} creates the parent ++@file{P} it sets the parent's permission bits to @samp{u=rwx,go=rx}. ++To set a parent's special mode bits as well, you can invoke ++@command{chmod} after @command{mkdir}. @xref{Directory Setuid and ++Setgid}, for how the set-user-ID and set-group-ID bits of ++newly-created parent directories are inherited. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Print a message for each created directory. This is most useful with ++@option{--parents}. ++ ++@item -Z @var{context} ++@itemx --context=@var{context} ++@opindex -Z ++@opindex --context ++@cindex SELinux ++@cindex security context ++Set the default SELinux security context to be used for created directories. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node mkfifo invocation ++@section @command{mkfifo}: Make FIFOs (named pipes) ++ ++@pindex mkfifo ++@cindex FIFOs, creating ++@cindex named pipes, creating ++@cindex creating FIFOs (named pipes) ++ ++@command{mkfifo} creates FIFOs (also called @dfn{named pipes}) with the ++specified names. Synopsis: ++ ++@example ++mkfifo [@var{option}] @var{name}@dots{} ++@end example ++ ++A @dfn{FIFO} is a special file type that permits independent processes ++to communicate. One process opens the FIFO file for writing, and ++another for reading, after which data can flow as with the usual ++anonymous pipe in shells or elsewhere. ++ ++The program accepts the following option. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -m @var{mode} ++@itemx --mode=@var{mode} ++@opindex -m ++@opindex --mode ++@cindex modes of created FIFOs, setting ++Set the mode of created FIFOs to @var{mode}, which is symbolic as in ++@command{chmod} and uses @samp{a=rw} (read and write allowed for everyone) ++for the point of departure. @var{mode} should specify only file ++permission bits. @xref{File permissions}. ++ ++@item -Z @var{context} ++@itemx --context=@var{context} ++@opindex -Z ++@opindex --context ++@cindex SELinux ++@cindex security context ++Set the default SELinux security context to be used for created FIFOs. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node mknod invocation ++@section @command{mknod}: Make block or character special files ++ ++@pindex mknod ++@cindex block special files, creating ++@cindex character special files, creating ++ ++@command{mknod} creates a FIFO, character special file, or block special ++file with the specified name. Synopsis: ++ ++@example ++mknod [@var{option}]@dots{} @var{name} @var{type} [@var{major} @var{minor}] ++@end example ++ ++@cindex special files ++@cindex block special files ++@cindex character special files ++Unlike the phrase ``special file type'' above, the term @dfn{special ++file} has a technical meaning on Unix: something that can generate or ++receive data. Usually this corresponds to a physical piece of hardware, ++e.g., a printer or a disk. (These files are typically created at ++system-configuration time.) The @command{mknod} command is what creates ++files of this type. Such devices can be read either a character at a ++time or a ``block'' (many characters) at a time, hence we say there are ++@dfn{block special} files and @dfn{character special} files. ++ ++@c mknod is a shell built-in at least with OpenBSD's /bin/sh ++@mayConflictWithShellBuiltIn{mknod} ++ ++The arguments after @var{name} specify the type of file to make: ++ ++@table @samp ++ ++@item p ++@opindex p @r{for FIFO file} ++for a FIFO ++ ++@item b ++@opindex b @r{for block special file} ++for a block special file ++ ++@item c ++@c Don't document the `u' option -- it's just a synonym for `c'. ++@c Do *any* versions of mknod still use it? ++@c @itemx u ++@opindex c @r{for character special file} ++@c @opindex u @r{for character special file} ++for a character special file ++ ++@end table ++ ++When making a block or character special file, the major and minor ++device numbers must be given after the file type. ++If a major or minor device number begins with @samp{0x} or @samp{0X}, ++it is interpreted as hexadecimal; otherwise, if it begins with @samp{0}, ++as octal; otherwise, as decimal. ++ ++The program accepts the following option. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -m @var{mode} ++@itemx --mode=@var{mode} ++@opindex -m ++@opindex --mode ++Set the mode of created files to @var{mode}, which is symbolic as in ++@command{chmod} and uses @samp{a=rw} as the point of departure. ++@var{mode} should specify only file permission bits. ++@xref{File permissions}. ++ ++@item -Z @var{context} ++@itemx --context=@var{context} ++@opindex -Z ++@opindex --context ++@cindex SELinux ++@cindex security context ++Set the default SELinux security context to be used for created files. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node readlink invocation ++@section @command{readlink}: Print value of a symlink or canonical file name ++ ++@pindex readlink ++@cindex displaying value of a symbolic link ++@cindex canonical file name ++@cindex canonicalize a file name ++@pindex realpath ++@findex realpath ++ ++@command{readlink} may work in one of two supported modes: ++ ++@table @samp ++ ++@item Readlink mode ++ ++@command{readlink} outputs the value of the given symbolic link. ++If @command{readlink} is invoked with an argument other than the name ++of a symbolic link, it produces no output and exits with a nonzero exit code. ++ ++@item Canonicalize mode ++ ++@command{readlink} outputs the absolute name of the given file which contains ++no @file{.}, @file{..} components nor any repeated separators ++(@file{/}) or symbolic links. ++ ++@end table ++ ++@example ++readlink [@var{option}] @var{file} ++@end example ++ ++By default, @command{readlink} operates in readlink mode. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -f ++@itemx --canonicalize ++@opindex -f ++@opindex --canonicalize ++Activate canonicalize mode. ++If any component of the file name except the last one is missing or unavailable, ++@command{readlink} produces no output and exits with a nonzero exit ++code. A trailing slash is ignored. ++ ++@item -e ++@itemx --canonicalize-existing ++@opindex -e ++@opindex --canonicalize-existing ++Activate canonicalize mode. ++If any component is missing or unavailable, @command{readlink} produces ++no output and exits with a nonzero exit code. A trailing slash ++requires that the name resolve to a directory. ++ ++@item -m ++@itemx --canonicalize-missing ++@opindex -m ++@opindex --canonicalize-missing ++Activate canonicalize mode. ++If any component is missing or unavailable, @command{readlink} treats it ++as a directory. ++ ++@item -n ++@itemx --no-newline ++@opindex -n ++@opindex --no-newline ++Do not output the trailing newline. ++ ++@item -s ++@itemx -q ++@itemx --silent ++@itemx --quiet ++@opindex -s ++@opindex -q ++@opindex --silent ++@opindex --quiet ++Suppress most error messages. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Report error messages. ++ ++@end table ++ ++The @command{readlink} utility first appeared in OpenBSD 2.1. ++ ++There is a @command{realpath} command on some systems ++which operates like @command{readlink} in canonicalize mode. ++ ++@exitstatus ++ ++ ++@node rmdir invocation ++@section @command{rmdir}: Remove empty directories ++ ++@pindex rmdir ++@cindex removing empty directories ++@cindex directories, removing empty ++ ++@command{rmdir} removes empty directories. Synopsis: ++ ++@example ++rmdir [@var{option}]@dots{} @var{directory}@dots{} ++@end example ++ ++If any @var{directory} argument does not refer to an existing empty ++directory, it is an error. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item --ignore-fail-on-non-empty ++@opindex --ignore-fail-on-non-empty ++@cindex directory deletion, ignoring failures ++Ignore each failure to remove a directory that is solely because ++the directory is non-empty. ++ ++@item -p ++@itemx --parents ++@opindex -p ++@opindex --parents ++@cindex parent directories, removing ++Remove @var{directory}, then try to remove each component of @var{directory}. ++So, for example, @samp{rmdir -p a/b/c} is similar to @samp{rmdir a/b/c a/b a}. ++As such, it fails if any of those directories turns out not to be empty. ++Use the @option{--ignore-fail-on-non-empty} option to make it so such ++a failure does not evoke a diagnostic and does not cause @command{rmdir} to ++exit unsuccessfully. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++@cindex directory deletion, reporting ++Give a diagnostic for each successful removal. ++@var{directory} is removed. ++ ++@end table ++ ++@xref{rm invocation}, for how to remove non-empty directories (recursively). ++ ++@exitstatus ++ ++ ++@node unlink invocation ++@section @command{unlink}: Remove files via the unlink syscall ++ ++@pindex unlink ++@cindex removing files or directories (via the unlink syscall) ++ ++@command{unlink} deletes a single specified file name. ++It is a minimalist interface to the system-provided ++@code{unlink} function. @xref{Deleting Files, , , libc, ++The GNU C Library Reference Manual}. Synopsis: ++It avoids the bells and whistles of the more commonly-used ++@command{rm} command (@pxref{rm invocation}). ++ ++@example ++unlink @var{filename} ++@end example ++ ++On some systems @code{unlink} can be used to delete the name of a ++directory. On others, it can be used that way only by a privileged user. ++In the GNU system @code{unlink} can never delete the name of a directory. ++ ++The @command{unlink} command honors the @option{--help} and ++@option{--version} options. To remove a file whose name begins with ++@samp{-}, prefix the name with @samp{./}, e.g., @samp{unlink ./--help}. ++ ++@exitstatus ++ ++ ++@node Changing file attributes ++@chapter Changing file attributes ++ ++@cindex changing file attributes ++@cindex file attributes, changing ++@cindex attributes, file ++ ++A file is not merely its contents, a name, and a file type ++(@pxref{Special file types}). A file also has an owner (a user ID), a ++group (a group ID), permissions (what the owner can do with the file, ++what people in the group can do, and what everyone else can do), various ++timestamps, and other information. Collectively, we call these a file's ++@dfn{attributes}. ++ ++These commands change file attributes. ++ ++@menu ++* chgrp invocation:: Change file groups. ++* chmod invocation:: Change access permissions. ++* chown invocation:: Change file owners and groups. ++* touch invocation:: Change file timestamps. ++@end menu ++ ++ ++@node chown invocation ++@section @command{chown}: Change file owner and group ++ ++@pindex chown ++@cindex file ownership, changing ++@cindex group ownership, changing ++@cindex changing file ownership ++@cindex changing group ownership ++ ++@command{chown} changes the user and/or group ownership of each given @var{file} ++to @var{new-owner} or to the user and group of an existing reference file. ++Synopsis: ++ ++@example ++chown [@var{option}]@dots{} @{@var{new-owner} | --reference=@var{ref_file}@} @var{file}@dots{} ++@end example ++ ++If used, @var{new-owner} specifies the new owner and/or group as follows ++(with no embedded white space): ++ ++@example ++[@var{owner}] [ : [@var{group}] ] ++@end example ++ ++Specifically: ++ ++@table @var ++@item owner ++If only an @var{owner} (a user name or numeric user ID) is given, that ++user is made the owner of each given file, and the files' group is not ++changed. ++ ++@item owner@samp{:}group ++If the @var{owner} is followed by a colon and a @var{group} (a ++group name or numeric group ID), with no spaces between them, the group ++ownership of the files is changed as well (to @var{group}). ++ ++@item owner@samp{:} ++If a colon but no group name follows @var{owner}, that user is ++made the owner of the files and the group of the files is changed to ++@var{owner}'s login group. ++ ++@item @samp{:}group ++If the colon and following @var{group} are given, but the owner ++is omitted, only the group of the files is changed; in this case, ++@command{chown} performs the same function as @command{chgrp}. ++ ++@item @samp{:} ++If only a colon is given, or if @var{new-owner} is empty, neither the ++owner nor the group is changed. ++ ++@end table ++ ++If @var{owner} or @var{group} is intended to represent a numeric user ++or group ID, then you may specify it with a leading @samp{+}. ++@xref{Disambiguating names and IDs}. ++ ++Some older scripts may still use @samp{.} in place of the @samp{:} separator. ++@acronym{POSIX} 1003.1-2001 (@pxref{Standards conformance}) does not ++require support for that, but for backward compatibility @acronym{GNU} ++@command{chown} supports @samp{.} so long as no ambiguity results. ++New scripts should avoid the use of @samp{.} because it is not ++portable, and because it has undesirable results if the entire ++@var{owner@samp{.}group} happens to identify a user whose name ++contains @samp{.}. ++ ++The @command{chown} command sometimes clears the set-user-ID or ++set-group-ID permission bits. This behavior depends on the policy and ++functionality of the underlying @code{chown} system call, which may ++make system-dependent file mode modifications outside the control of ++the @command{chown} command. For example, the @command{chown} command ++might not affect those bits when invoked by a user with appropriate ++privileges, or when the ++bits signify some function other than executable permission (e.g., ++mandatory locking). ++When in doubt, check the underlying system behavior. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -c ++@itemx --changes ++@opindex -c ++@opindex --changes ++@cindex changed owners, verbosely describing ++Verbosely describe the action for each @var{file} whose ownership ++actually changes. ++ ++@item -f ++@itemx --silent ++@itemx --quiet ++@opindex -f ++@opindex --silent ++@opindex --quiet ++@cindex error messages, omitting ++Do not print error messages about files whose ownership cannot be ++changed. ++ ++@itemx @w{@kbd{--from}=@var{old-owner}} ++@opindex --from ++@cindex symbolic links, changing owner ++Change a @var{file}'s ownership only if it has current attributes specified ++by @var{old-owner}. @var{old-owner} has the same form as @var{new-owner} ++described above. ++This option is useful primarily from a security standpoint in that ++it narrows considerably the window of potential abuse. ++For example, to reflect a user ID numbering change for one user's files ++without an option like this, @code{root} might run ++ ++@smallexample ++find / -owner OLDUSER -print0 | xargs -0 chown -h NEWUSER ++@end smallexample ++ ++But that is dangerous because the interval between when the @command{find} ++tests the existing file's owner and when the @command{chown} is actually run ++may be quite large. ++One way to narrow the gap would be to invoke chown for each file ++as it is found: ++ ++@example ++find / -owner OLDUSER -exec chown -h NEWUSER @{@} \; ++@end example ++ ++But that is very slow if there are many affected files. ++With this option, it is safer (the gap is narrower still) ++though still not perfect: ++ ++@example ++chown -h -R --from=OLDUSER NEWUSER / ++@end example ++ ++@item --dereference ++@opindex --dereference ++@cindex symbolic links, changing owner ++@findex lchown ++Do not act on symbolic links themselves but rather on what they point to. ++This is the default. ++ ++@item -h ++@itemx --no-dereference ++@opindex -h ++@opindex --no-dereference ++@cindex symbolic links, changing owner ++@findex lchown ++Act on symbolic links themselves instead of what they point to. ++This mode relies on the @code{lchown} system call. ++On systems that do not provide the @code{lchown} system call, ++@command{chown} fails when a file specified on the command line ++is a symbolic link. ++By default, no diagnostic is issued for symbolic links encountered ++during a recursive traversal, but see @option{--verbose}. ++ ++@itemx --preserve-root ++@opindex --preserve-root ++@cindex root directory, disallow recursive modification ++Fail upon any attempt to recursively change the root directory, @file{/}. ++Without @option{--recursive}, this option has no effect. ++@xref{Treating / specially}. ++ ++@itemx --no-preserve-root ++@opindex --no-preserve-root ++@cindex root directory, allow recursive modification ++Cancel the effect of any preceding @option{--preserve-root} option. ++@xref{Treating / specially}. ++ ++@item --reference=@var{ref_file} ++@opindex --reference ++Change the user and group of each @var{file} to be the same as those of ++@var{ref_file}. If @var{ref_file} is a symbolic link, do not use the ++user and group of the symbolic link, but rather those of the file it ++refers to. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Output a diagnostic for every file processed. ++If a symbolic link is encountered during a recursive traversal ++on a system without the @code{lchown} system call, and @option{--no-dereference} ++is in effect, then issue a diagnostic saying neither the symbolic link nor ++its referent is being changed. ++ ++@item -R ++@itemx --recursive ++@opindex -R ++@opindex --recursive ++@cindex recursively changing file ownership ++Recursively change ownership of directories and their contents. ++ ++@choptH ++@xref{Traversing symlinks}. ++ ++@choptL ++@xref{Traversing symlinks}. ++ ++@choptP ++@xref{Traversing symlinks}. ++ ++@end table ++ ++@exitstatus ++ ++Examples: ++ ++@smallexample ++# Change the owner of /u to "root". ++chown root /u ++ ++# Likewise, but also change its group to "staff". ++chown root:staff /u ++ ++# Change the owner of /u and subfiles to "root". ++chown -hR root /u ++@end smallexample ++ ++ ++@node chgrp invocation ++@section @command{chgrp}: Change group ownership ++ ++@pindex chgrp ++@cindex group ownership, changing ++@cindex changing group ownership ++ ++@command{chgrp} changes the group ownership of each given @var{file} ++to @var{group} (which can be either a group name or a numeric group ID) ++or to the group of an existing reference file. Synopsis: ++ ++@example ++chgrp [@var{option}]@dots{} @{@var{group} | --reference=@var{ref_file}@} @var{file}@dots{} ++@end example ++ ++If @var{group} is intended to represent a ++numeric group ID, then you may specify it with a leading @samp{+}. ++@xref{Disambiguating names and IDs}. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -c ++@itemx --changes ++@opindex -c ++@opindex --changes ++@cindex changed files, verbosely describing ++Verbosely describe the action for each @var{file} whose group actually ++changes. ++ ++@item -f ++@itemx --silent ++@itemx --quiet ++@opindex -f ++@opindex --silent ++@opindex --quiet ++@cindex error messages, omitting ++Do not print error messages about files whose group cannot be ++changed. ++ ++@item --dereference ++@opindex --dereference ++@cindex symbolic links, changing owner ++@findex lchown ++Do not act on symbolic links themselves but rather on what they point to. ++This is the default. ++ ++@item -h ++@itemx --no-dereference ++@opindex -h ++@opindex --no-dereference ++@cindex symbolic links, changing group ++@findex lchown ++Act on symbolic links themselves instead of what they point to. ++This mode relies on the @code{lchown} system call. ++On systems that do not provide the @code{lchown} system call, ++@command{chgrp} fails when a file specified on the command line ++is a symbolic link. ++By default, no diagnostic is issued for symbolic links encountered ++during a recursive traversal, but see @option{--verbose}. ++ ++@itemx --preserve-root ++@opindex --preserve-root ++@cindex root directory, disallow recursive modification ++Fail upon any attempt to recursively change the root directory, @file{/}. ++Without @option{--recursive}, this option has no effect. ++@xref{Treating / specially}. ++ ++@itemx --no-preserve-root ++@opindex --no-preserve-root ++@cindex root directory, allow recursive modification ++Cancel the effect of any preceding @option{--preserve-root} option. ++@xref{Treating / specially}. ++ ++@item --reference=@var{ref_file} ++@opindex --reference ++Change the group of each @var{file} to be the same as that of ++@var{ref_file}. If @var{ref_file} is a symbolic link, do not use the ++group of the symbolic link, but rather that of the file it refers to. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Output a diagnostic for every file processed. ++If a symbolic link is encountered during a recursive traversal ++on a system without the @code{lchown} system call, and @option{--no-dereference} ++is in effect, then issue a diagnostic saying neither the symbolic link nor ++its referent is being changed. ++ ++@item -R ++@itemx --recursive ++@opindex -R ++@opindex --recursive ++@cindex recursively changing group ownership ++Recursively change the group ownership of directories and their contents. ++ ++@choptH ++@xref{Traversing symlinks}. ++ ++@choptL ++@xref{Traversing symlinks}. ++ ++@choptP ++@xref{Traversing symlinks}. ++ ++@end table ++ ++@exitstatus ++ ++Examples: ++ ++@smallexample ++# Change the group of /u to "staff". ++chgrp staff /u ++ ++# Change the group of /u and subfiles to "staff". ++chgrp -hR staff /u ++@end smallexample ++ ++ ++@node chmod invocation ++@section @command{chmod}: Change access permissions ++ ++@pindex chmod ++@cindex changing access permissions ++@cindex access permissions, changing ++@cindex permissions, changing access ++ ++@command{chmod} changes the access permissions of the named files. Synopsis: ++ ++@example ++chmod [@var{option}]@dots{} @{@var{mode} | --reference=@var{ref_file}@} @var{file}@dots{} ++@end example ++ ++@cindex symbolic links, permissions of ++@command{chmod} never changes the permissions of symbolic links, since ++the @command{chmod} system call cannot change their permissions. ++This is not a problem since the permissions of symbolic links are ++never used. However, for each symbolic link listed on the command ++line, @command{chmod} changes the permissions of the pointed-to file. ++In contrast, @command{chmod} ignores symbolic links encountered during ++recursive directory traversals. ++ ++A successful use of @command{chmod} clears the set-group-ID bit of a ++regular file if the file's group ID does not match the user's ++effective group ID or one of the user's supplementary group IDs, ++unless the user has appropriate privileges. Additional restrictions ++may cause the set-user-ID and set-group-ID bits of @var{mode} or ++@var{ref_file} to be ignored. This behavior depends on the policy and ++functionality of the underlying @code{chmod} system call. When in ++doubt, check the underlying system behavior. ++ ++If used, @var{mode} specifies the new file mode bits. ++For details, see the section on @ref{File permissions}. ++If you really want @var{mode} to have a leading @samp{-}, you should ++use @option{--} first, e.g., @samp{chmod -- -w file}. Typically, ++though, @samp{chmod a-w file} is preferable, and @command{chmod -w ++file} (without the @option{--}) complains if it behaves differently ++from what @samp{chmod a-w file} would do. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -c ++@itemx --changes ++@opindex -c ++@opindex --changes ++Verbosely describe the action for each @var{file} whose permissions ++actually changes. ++ ++@item -f ++@itemx --silent ++@itemx --quiet ++@opindex -f ++@opindex --silent ++@opindex --quiet ++@cindex error messages, omitting ++Do not print error messages about files whose permissions cannot be ++changed. ++ ++@itemx --preserve-root ++@opindex --preserve-root ++@cindex root directory, disallow recursive modification ++Fail upon any attempt to recursively change the root directory, @file{/}. ++Without @option{--recursive}, this option has no effect. ++@xref{Treating / specially}. ++ ++@itemx --no-preserve-root ++@opindex --no-preserve-root ++@cindex root directory, allow recursive modification ++Cancel the effect of any preceding @option{--preserve-root} option. ++@xref{Treating / specially}. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++Verbosely describe the action or non-action taken for every @var{file}. ++ ++@item --reference=@var{ref_file} ++@opindex --reference ++Change the mode of each @var{file} to be the same as that of @var{ref_file}. ++@xref{File permissions}. ++If @var{ref_file} is a symbolic link, do not use the mode ++of the symbolic link, but rather that of the file it refers to. ++ ++@item -R ++@itemx --recursive ++@opindex -R ++@opindex --recursive ++@cindex recursively changing access permissions ++Recursively change permissions of directories and their contents. ++ ++@end table ++ ++@exitstatus ++ ++ ++@node touch invocation ++@section @command{touch}: Change file timestamps ++ ++@pindex touch ++@cindex changing file timestamps ++@cindex file timestamps, changing ++@cindex timestamps, changing file ++ ++@command{touch} changes the access and/or modification times of the ++specified files. Synopsis: ++ ++@example ++touch [@var{option}]@dots{} @var{file}@dots{} ++@end example ++ ++@cindex empty files, creating ++Any @var{file} argument that does not exist is created empty. ++ ++A @var{file} argument string of @samp{-} is handled specially and ++causes @command{touch} to change the times of the file associated with ++standard output. ++ ++@cindex permissions, for changing file timestamps ++If changing both the access and modification times to the current ++time, @command{touch} can change the timestamps for files that the user ++running it does not own but has write permission for. Otherwise, the ++user must own the files. ++ ++Although @command{touch} provides options for changing two of the times---the ++times of last access and modification---of a file, there is actually ++a third one as well: the inode change time. This is often referred to ++as a file's @code{ctime}. ++The inode change time represents the time when the file's meta-information ++last changed. One common example of this is when the permissions of a ++file change. Changing the permissions doesn't access the file, so ++the atime doesn't change, nor does it modify the file, so the mtime ++doesn't change. Yet, something about the file itself has changed, ++and this must be noted somewhere. This is the job of the ctime field. ++This is necessary, so that, for example, a backup program can make a ++fresh copy of the file, including the new permissions value. ++Another operation that modifies a file's ctime without affecting ++the others is renaming. In any case, it is not possible, in normal ++operations, for a user to change the ctime field to a user-specified value. ++ ++@vindex TZ ++Time stamps assume the time zone rules specified by the @env{TZ} ++environment variable, or by the system default rules if @env{TZ} is ++not set. @xref{TZ Variable,, Specifying the Time Zone with @env{TZ}, ++libc, The GNU C Library Reference Manual}. ++You can avoid ambiguities during ++daylight saving transitions by using @sc{utc} time stamps. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -a ++@itemx --time=atime ++@itemx --time=access ++@itemx --time=use ++@opindex -a ++@opindex --time ++@opindex atime@r{, changing} ++@opindex access @r{time, changing} ++@opindex use @r{time, changing} ++Change the access time only. ++ ++@item -c ++@itemx --no-create ++@opindex -c ++@opindex --no-create ++Do not create files that do not exist. ++ ++@item -d ++@itemx --date=@var{time} ++@opindex -d ++@opindex --date ++@opindex time ++Use @var{time} instead of the current time. It can contain month names, ++time zones, @samp{am} and @samp{pm}, @samp{yesterday}, etc. For ++example, @option{--date="2004-02-27 14:19:13.489392193 +0530"} ++specifies the instant of time that is 489,392,193 nanoseconds after ++February 27, 2004 at 2:19:13 PM in a time zone that is 5 hours and 30 ++minutes east of @acronym{UTC}. @xref{Date input formats}. ++File systems that do not support high-resolution time stamps ++silently ignore any excess precision here. ++ ++@item -f ++@opindex -f ++@cindex BSD @command{touch} compatibility ++Ignored; for compatibility with BSD versions of @command{touch}. ++ ++@item -m ++@itemx --time=mtime ++@itemx --time=modify ++@opindex -m ++@opindex --time ++@opindex mtime@r{, changing} ++@opindex modify @r{time, changing} ++Change the modification time only. ++ ++@item -r @var{file} ++@itemx --reference=@var{file} ++@opindex -r ++@opindex --reference ++Use the times of the reference @var{file} instead of the current time. ++If this option is combined with the @option{--date=@var{time}} ++(@option{-d @var{time}}) option, the reference @var{file}'s time is ++the origin for any relative @var{time}s given, but is otherwise ignored. ++For example, @samp{-r foo -d '-5 seconds'} specifies a time stamp ++equal to five seconds before the corresponding time stamp for @file{foo}. ++ ++@item -t [[@var{cc}]@var{yy}]@var{mmddhhmm}[.@var{ss}] ++Use the argument (optional four-digit or two-digit years, months, ++days, hours, minutes, optional seconds) instead of the current time. ++If the year is specified with only two digits, then @var{cc} ++is 20 for years in the range 0 @dots{} 68, and 19 for years in ++69 @dots{} 99. If no digits of the year are specified, ++the argument is interpreted as a date in the current year. ++Note that @var{ss} may be @samp{60}, to accommodate leap seconds. ++ ++@end table ++ ++@vindex _POSIX2_VERSION ++On older systems, @command{touch} supports an obsolete syntax, as follows. ++If no timestamp is given with any of the @option{-d}, @option{-r}, or ++@option{-t} options, and if there are two or more @var{file}s and the ++first @var{file} is of the form @samp{@var{mmddhhmm}[@var{yy}]} and this ++would be a valid argument to the @option{-t} option (if the @var{yy}, if ++any, were moved to the front), and if the represented year ++is in the range 1969--1999, that argument is interpreted as the time ++for the other files instead of as a file name. ++This obsolete behavior can be enabled or disabled with the ++@env{_POSIX2_VERSION} environment variable (@pxref{Standards ++conformance}), but portable scripts should avoid commands whose ++behavior depends on this variable. ++For example, use @samp{touch ./12312359 main.c} or @samp{touch -t ++12312359 main.c} rather than the ambiguous @samp{touch 12312359 main.c}. ++ ++@exitstatus ++ ++ ++@node Disk usage ++@chapter Disk usage ++ ++@cindex disk usage ++ ++No disk can hold an infinite amount of data. These commands report ++how much disk storage is in use or available, report other file and ++file status information, and write buffers to disk. ++ ++@menu ++* df invocation:: Report file system disk space usage. ++* du invocation:: Estimate file space usage. ++* stat invocation:: Report file or file system status. ++* sync invocation:: Synchronize memory and disk. ++* truncate invocation:: Shrink or extend the size of a file. ++@end menu ++ ++ ++@node df invocation ++@section @command{df}: Report file system disk space usage ++ ++@pindex df ++@cindex file system disk usage ++@cindex disk usage by file system ++ ++@command{df} reports the amount of disk space used and available on ++file systems. Synopsis: ++ ++@example ++df [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++With no arguments, @command{df} reports the space used and available on all ++currently mounted file systems (of all types). Otherwise, @command{df} ++reports on the file system containing each argument @var{file}. ++ ++Normally the disk space is printed in units of ++1024 bytes, but this can be overridden (@pxref{Block size}). ++Non-integer quantities are rounded up to the next higher unit. ++ ++@cindex disk device file ++@cindex device file, disk ++If an argument @var{file} is a disk device file containing a mounted ++file system, @command{df} shows the space available on that file system ++rather than on the file system containing the device node (i.e., the root ++file system). @sc{gnu} @command{df} does not attempt to determine the disk usage ++on unmounted file systems, because on most kinds of systems doing so ++requires extremely nonportable intimate knowledge of file system ++structures. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -a ++@itemx --all ++@opindex -a ++@opindex --all ++@cindex automounter file systems ++@cindex ignore file systems ++Include in the listing dummy file systems, which ++are omitted by default. Such file systems are typically special-purpose ++pseudo-file-systems, such as automounter entries. ++ ++@item -B @var{size} ++@itemx --block-size=@var{size} ++@opindex -B ++@opindex --block-size ++@cindex file system sizes ++Scale sizes by @var{size} before printing them (@pxref{Block size}). ++For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. ++ ++@itemx --total ++@opindex --total ++@cindex grand total of disk size, usage and available space ++Print a grand total of all arguments after all arguments have ++been processed. This can be used to find out the total disk size, usage ++and available space of all listed devices. ++ ++@optHumanReadable ++ ++@item -H ++@opindex -H ++Equivalent to @option{--si}. ++ ++@item -i ++@itemx --inodes ++@opindex -i ++@opindex --inodes ++@cindex inode usage ++List inode usage information instead of block usage. An inode (short ++for index node) contains information about a file such as its owner, ++permissions, timestamps, and location on the disk. ++ ++@item -k ++@opindex -k ++@cindex kibibytes for file system sizes ++Print sizes in 1024-byte blocks, overriding the default block size ++(@pxref{Block size}). ++This option is equivalent to @option{--block-size=1K}. ++ ++@item -l ++@itemx --local ++@opindex -l ++@opindex --local ++@cindex file system types, limiting output to certain ++Limit the listing to local file systems. By default, remote file systems ++are also listed. ++ ++@item --no-sync ++@opindex --no-sync ++@cindex file system space, retrieving old data more quickly ++Do not invoke the @code{sync} system call before getting any usage data. ++This may make @command{df} run significantly faster on systems with many ++disks, but on some systems (notably SunOS) the results may be slightly ++out of date. This is the default. ++ ++@item -P ++@itemx --portability ++@opindex -P ++@opindex --portability ++@cindex one-line output format ++@cindex @acronym{POSIX} output format ++@cindex portable output format ++@cindex output format, portable ++Use the @acronym{POSIX} output format. This is like the default format except ++for the following: ++ ++@enumerate ++@item ++The information about each file system is always printed on exactly ++one line; a mount device is never put on a line by itself. This means ++that if the mount device name is more than 20 characters long (e.g., for ++some network mounts), the columns are misaligned. ++ ++@item ++The labels in the header output line are changed to conform to @acronym{POSIX}. ++ ++@item ++The default block size and output format are unaffected by the ++@env{DF_BLOCK_SIZE}, @env{BLOCK_SIZE} and @env{BLOCKSIZE} environment ++variables. However, the default block size is still affected by ++@env{POSIXLY_CORRECT}: it is 512 if @env{POSIXLY_CORRECT} is set, 1024 ++otherwise. @xref{Block size}. ++@end enumerate ++ ++@optSi ++ ++@item --sync ++@opindex --sync ++@cindex file system space, retrieving current data more slowly ++Invoke the @code{sync} system call before getting any usage data. On ++some systems (notably SunOS), doing this yields more up to date results, ++but in general this option makes @command{df} much slower, especially when ++there are many or very busy file systems. ++ ++@item -t @var{fstype} ++@itemx --type=@var{fstype} ++@opindex -t ++@opindex --type ++@cindex file system types, limiting output to certain ++Limit the listing to file systems of type @var{fstype}. Multiple ++file system types can be specified by giving multiple @option{-t} options. ++By default, nothing is omitted. ++ ++@item -T ++@itemx --print-type ++@opindex -T ++@opindex --print-type ++@cindex file system types, printing ++Print each file system's type. The types printed here are the same ones ++you can include or exclude with @option{-t} and @option{-x}. The particular ++types printed are whatever is supported by the system. Here are some of ++the common names (this list is certainly not exhaustive): ++ ++@table @samp ++ ++@item nfs ++@cindex @acronym{NFS} file system type ++An @acronym{NFS} file system, i.e., one mounted over a network from another ++machine. This is the one type name which seems to be used uniformly by ++all systems. ++ ++@item 4.2@r{, }ufs@r{, }efs@dots{} ++@cindex Linux file system types ++@cindex local file system types ++@opindex 4.2 @r{file system type} ++@opindex ufs @r{file system type} ++@opindex efs @r{file system type} ++A file system on a locally-mounted hard disk. (The system might even ++support more than one type here; Linux does.) ++ ++@item hsfs@r{, }cdfs ++@cindex CD-ROM file system type ++@cindex High Sierra file system ++@opindex hsfs @r{file system type} ++@opindex cdfs @r{file system type} ++A file system on a CD-ROM drive. HP-UX uses @samp{cdfs}, most other ++systems use @samp{hsfs} (@samp{hs} for ``High Sierra''). ++ ++@item pcfs ++@cindex PC file system ++@cindex DOS file system ++@cindex MS-DOS file system ++@cindex diskette file system ++@opindex pcfs ++An MS-DOS file system, usually on a diskette. ++ ++@end table ++ ++@item -x @var{fstype} ++@itemx --exclude-type=@var{fstype} ++@opindex -x ++@opindex --exclude-type ++Limit the listing to file systems not of type @var{fstype}. ++Multiple file system types can be eliminated by giving multiple ++@option{-x} options. By default, no file system types are omitted. ++ ++@item -v ++Ignored; for compatibility with System V versions of @command{df}. ++ ++@end table ++ ++@exitstatus ++Failure includes the case where no output is generated, so you can ++inspect the exit status of a command like @samp{df -t ext3 -t reiserfs ++@var{dir}} to test whether @var{dir} is on a file system of type ++@samp{ext3} or @samp{reiserfs}. ++ ++ ++@node du invocation ++@section @command{du}: Estimate file space usage ++ ++@pindex du ++@cindex file space usage ++@cindex disk usage for files ++ ++@command{du} reports the amount of disk space used by the specified files ++and for each subdirectory (of directory arguments). Synopsis: ++ ++@example ++du [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++With no arguments, @command{du} reports the disk space for the current ++directory. Normally the disk space is printed in units of ++1024 bytes, but this can be overridden (@pxref{Block size}). ++Non-integer quantities are rounded up to the next higher unit. ++ ++If two or more hard links point to the same file, only one of the hard ++links is counted. The @var{file} argument order affects which links ++are counted, and changing the argument order may change the numbers ++that @command{du} outputs. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -a ++@itemx --all ++@opindex -a ++@opindex --all ++Show counts for all files, not just directories. ++ ++@itemx --apparent-size ++@opindex --apparent-size ++Print apparent sizes, rather than disk usage. The apparent size of a ++file is the number of bytes reported by @code{wc -c} on regular files, ++or more generally, @code{ls -l --block-size=1} or @code{stat --format=%s}. ++For example, a file containing the word @samp{zoo} with no newline would, ++of course, have an apparent size of 3. Such a small file may require ++anywhere from 0 to 16 KiB or more of disk space, depending on ++the type and configuration of the file system on which the file resides. ++However, a sparse file created with this command: ++ ++@example ++dd bs=1 seek=2GiB if=/dev/null of=big ++@end example ++ ++@noindent ++has an apparent size of 2 GiB, yet on most modern ++systems, it actually uses almost no disk space. ++ ++@item -b ++@itemx --bytes ++@opindex -b ++@opindex --bytes ++Equivalent to @code{--apparent-size --block-size=1}. ++ ++@item -B @var{size} ++@itemx --block-size=@var{size} ++@opindex -B ++@opindex --block-size ++@cindex file sizes ++Scale sizes by @var{size} before printing them (@pxref{Block size}). ++For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. ++ ++@item -c ++@itemx --total ++@opindex -c ++@opindex --total ++@cindex grand total of disk space ++Print a grand total of all arguments after all arguments have ++been processed. This can be used to find out the total disk usage of ++a given set of files or directories. ++ ++@item -D ++@itemx --dereference-args ++@opindex -D ++@opindex --dereference-args ++Dereference symbolic links that are command line arguments. ++Does not affect other symbolic links. This is helpful for finding ++out the disk usage of directories, such as @file{/usr/tmp}, which ++are often symbolic links. ++ ++@c --files0-from=FILE ++@filesZeroFromOption{du,, with the @option{--total} (@option{-c}) option} ++ ++@optHumanReadable ++ ++@item -H ++@opindex -H ++Equivalent to @option{--dereference-args} (@option{-D}). ++ ++@item -k ++@opindex -k ++@cindex kibibytes for file sizes ++Print sizes in 1024-byte blocks, overriding the default block size ++(@pxref{Block size}). ++This option is equivalent to @option{--block-size=1K}. ++ ++@item -l ++@itemx --count-links ++@opindex -l ++@opindex --count-links ++@cindex hard links, counting in @command{du} ++Count the size of all files, even if they have appeared already (as a ++hard link). ++ ++@item -L ++@itemx --dereference ++@opindex -L ++@opindex --dereference ++@cindex symbolic links, dereferencing in @command{du} ++Dereference symbolic links (show the disk space used by the file ++or directory that the link points to instead of the space used by ++the link). ++ ++@item -m ++@opindex -m ++@cindex mebibytes for file sizes ++Print sizes in 1,048,576-byte blocks, overriding the default block size ++(@pxref{Block size}). ++This option is equivalent to @option{--block-size=1M}. ++ ++@item -P ++@itemx --no-dereference ++@opindex -P ++@opindex --no-dereference ++@cindex symbolic links, dereferencing in @command{du} ++For each symbolic links encountered by @command{du}, ++consider the disk space used by the symbolic link. ++ ++@item --max-depth=@var{depth} ++@opindex --max-depth=@var{depth} ++@cindex limiting output of @command{du} ++Show the total for each directory (and file if --all) that is at ++most MAX_DEPTH levels down from the root of the hierarchy. The root ++is at level 0, so @code{du --max-depth=0} is equivalent to @code{du -s}. ++ ++@item -0 ++@opindex -0 ++@itemx --null ++@opindex --null ++@cindex output null-byte-terminated lines ++Output a zero byte (@acronym{ASCII} @sc{nul}) at the end of each line, ++rather than a newline. This option enables other programs to parse the ++output of @command{du} even when that output would contain file names ++with embedded newlines. ++ ++@optSi ++ ++@item -s ++@itemx --summarize ++@opindex -s ++@opindex --summarize ++Display only a total for each argument. ++ ++@item -S ++@itemx --separate-dirs ++@opindex -S ++@opindex --separate-dirs ++Normally, in the output of @command{du} (when not using @option{--summarize}), ++the size listed next to a directory name, @var{d}, represents the sum ++of sizes of all entries beneath @var{d} as well as the size of @var{d} itself. ++With @option{--separate-dirs}, the size reported for a directory name, ++@var{d}, is merely the @code{stat.st_size}-derived size of the directory ++entry, @var{d}. ++ ++@itemx --time ++@opindex --time ++@cindex last modified dates, displaying in @command{du} ++Show time of the most recent modification of any file in the directory, ++or any of its subdirectories. ++ ++@itemx --time=ctime ++@itemx --time=status ++@itemx --time=use ++@opindex --time ++@opindex ctime@r{, show the most recent} ++@opindex status time@r{, show the most recent} ++@opindex use time@r{, show the most recent} ++Show the most recent status change time (the @samp{ctime} in the inode) of ++any file in the directory, instead of the modification time. ++ ++@itemx --time=atime ++@itemx --time=access ++@opindex --time ++@opindex atime@r{, show the most recent} ++@opindex access time@r{, show the most recent} ++Show the most recent access time (the @samp{atime} in the inode) of ++any file in the directory, instead of the modification time. ++ ++@item --time-style=@var{style} ++@opindex --time-style ++@cindex time style ++List timestamps in style @var{style}. This option has an effect only if ++the @option{--time} option is also specified. The @var{style} should ++be one of the following: ++ ++@table @samp ++@item +@var{format} ++@vindex LC_TIME ++List timestamps using @var{format}, where @var{format} is interpreted ++like the format argument of @command{date} (@pxref{date invocation}). ++For example, @option{--time-style="+%Y-%m-%d %H:%M:%S"} causes ++@command{du} to list timestamps like @samp{2002-03-30 23:45:56}. As ++with @command{date}, @var{format}'s interpretation is affected by the ++@env{LC_TIME} locale category. ++ ++@item full-iso ++List timestamps in full using @acronym{ISO} 8601 date, time, and time zone ++format with nanosecond precision, e.g., @samp{2002-03-30 ++23:45:56.477817180 -0700}. This style is equivalent to ++@samp{+%Y-%m-%d %H:%M:%S.%N %z}. ++ ++@item long-iso ++List @acronym{ISO} 8601 date and time in minutes, e.g., ++@samp{2002-03-30 23:45}. These timestamps are shorter than ++@samp{full-iso} timestamps, and are usually good enough for everyday ++work. This style is equivalent to @samp{+%Y-%m-%d %H:%M}. ++ ++@item iso ++List @acronym{ISO} 8601 dates for timestamps, e.g., @samp{2002-03-30}. ++This style is equivalent to @samp{+%Y-%m-%d}. ++@end table ++ ++@vindex TIME_STYLE ++You can specify the default value of the @option{--time-style} option ++with the environment variable @env{TIME_STYLE}; if @env{TIME_STYLE} is not set ++the default style is @samp{long-iso}. For compatibility with @command{ls}, ++if @env{TIME_STYLE} begins with @samp{+} and contains a newline, ++the newline and any later characters are ignored; if @env{TIME_STYLE} ++begins with @samp{posix-} the @samp{posix-} is ignored; and if ++@env{TIME_STYLE} is @samp{locale} it is ignored. ++ ++@item -x ++@itemx --one-file-system ++@opindex -x ++@opindex --one-file-system ++@cindex one file system, restricting @command{du} to ++Skip directories that are on different file systems from the one that ++the argument being processed is on. ++ ++@item --exclude=@var{pattern} ++@opindex --exclude=@var{pattern} ++@cindex excluding files from @command{du} ++When recursing, skip subdirectories or files matching @var{pattern}. ++For example, @code{du --exclude='*.o'} excludes files whose names ++end in @samp{.o}. ++ ++@item -X @var{file} ++@itemx --exclude-from=@var{file} ++@opindex -X @var{file} ++@opindex --exclude-from=@var{file} ++@cindex excluding files from @command{du} ++Like @option{--exclude}, except take the patterns to exclude from @var{file}, ++one per line. If @var{file} is @samp{-}, take the patterns from standard ++input. ++ ++@end table ++ ++@cindex NFS mounts from BSD to HP-UX ++On BSD systems, @command{du} reports sizes that are half the correct ++values for files that are NFS-mounted from HP-UX systems. On HP-UX ++systems, it reports sizes that are twice the correct values for ++files that are NFS-mounted from BSD systems. This is due to a flaw ++in HP-UX; it also affects the HP-UX @command{du} program. ++ ++@exitstatus ++ ++ ++@node stat invocation ++@section @command{stat}: Report file or file system status ++ ++@pindex stat ++@cindex file status ++@cindex file system status ++ ++@command{stat} displays information about the specified file(s). Synopsis: ++ ++@example ++stat [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++With no option, @command{stat} reports all information about the given files. ++But it also can be used to report the information of the file systems the ++given files are located on. If the files are links, @command{stat} can ++also give information about the files the links point to. ++ ++@mayConflictWithShellBuiltIn{stat} ++ ++@table @samp ++ ++@item -L ++@itemx --dereference ++@opindex -L ++@opindex --dereference ++@cindex symbolic links, dereferencing in @command{stat} ++Change how @command{stat} treats symbolic links. ++With this option, @command{stat} acts on the file referenced ++by each symbolic link argument. ++Without it, @command{stat} acts on any symbolic link argument directly. ++ ++@item -f ++@itemx --file-system ++@opindex -f ++@opindex --file-system ++@cindex file systems ++Report information about the file systems where the given files are located ++instead of information about the files themselves. ++ ++@item -c ++@itemx --format=@var{format} ++@opindex -c ++@opindex --format=@var{format} ++@cindex output format ++Use @var{format} rather than the default format. ++@var{format} is automatically newline-terminated, so ++running a command like the following with two or more @var{file} ++operands produces a line of output for each operand: ++@example ++$ stat --format=%d:%i / /usr ++2050:2 ++2057:2 ++@end example ++ ++@itemx --printf=@var{format} ++@opindex --printf=@var{format} ++@cindex output format ++Use @var{format} rather than the default format. ++Like @option{--format}, but interpret backslash escapes, ++and do not output a mandatory trailing newline. ++If you want a newline, include @samp{\n} in the @var{format}. ++Here's how you would use @option{--printf} to print the device ++and inode numbers of @file{/} and @file{/usr}: ++@example ++$ stat --printf='%d:%i\n' / /usr ++2050:2 ++2057:2 ++@end example ++ ++@item -t ++@itemx --terse ++@opindex -t ++@opindex --terse ++@cindex terse output ++Print the information in terse form, suitable for parsing by other programs. ++ ++@end table ++ ++The valid @var{format} directives for files with @option{--format} and ++@option{--printf} are: ++ ++@itemize @bullet ++@item %a - Access rights in octal ++@item %A - Access rights in human readable form ++@item %b - Number of blocks allocated (see @samp{%B}) ++@item %B - The size in bytes of each block reported by @samp{%b} ++@item %d - Device number in decimal ++@item %D - Device number in hex ++@item %f - Raw mode in hex ++@item %F - File type ++@item %g - Group ID of owner ++@item %G - Group name of owner ++@item %h - Number of hard links ++@item %i - Inode number ++@item %n - File name ++@item %N - Quoted file name with dereference if symbolic link ++@item %o - I/O block size ++@item %s - Total size, in bytes ++@item %t - Major device type in hex ++@item %T - Minor device type in hex ++@item %u - User ID of owner ++@item %U - User name of owner ++@item %x - Time of last access ++@item %X - Time of last access as seconds since Epoch ++@item %y - Time of last modification ++@item %Y - Time of last modification as seconds since Epoch ++@item %z - Time of last change ++@item %Z - Time of last change as seconds since Epoch ++@end itemize ++ ++When listing file system information (@option{--file-system} (@option{-f})), ++you must use a different set of @var{format} directives: ++ ++@itemize @bullet ++@item %a - Free blocks available to non-super-user ++@item %b - Total data blocks in file system ++@item %c - Total file nodes in file system ++@item %d - Free file nodes in file system ++@item %f - Free blocks in file system ++@item %i - File System ID in hex ++@item %l - Maximum length of file names ++@item %n - File name ++@item %s - Block size (for faster transfers) ++@item %S - Fundamental block size (for block counts) ++@item %t - Type in hex ++@item %T - Type in human readable form ++@end itemize ++ ++@vindex TZ ++Time stamps are listed according to the time zone rules specified by ++the @env{TZ} environment variable, or by the system default rules if ++@env{TZ} is not set. @xref{TZ Variable,, Specifying the Time Zone ++with @env{TZ}, libc, The GNU C Library Reference Manual}. ++ ++@exitstatus ++ ++ ++@node sync invocation ++@section @command{sync}: Synchronize data on disk with memory ++ ++@pindex sync ++@cindex synchronize disk and memory ++ ++@cindex superblock, writing ++@cindex inodes, written buffered ++@command{sync} writes any data buffered in memory out to disk. This can ++include (but is not limited to) modified superblocks, modified inodes, ++and delayed reads and writes. This must be implemented by the kernel; ++The @command{sync} program does nothing but exercise the @code{sync} system ++call. ++ ++@cindex crashes and corruption ++The kernel keeps data in memory to avoid doing (relatively slow) disk ++reads and writes. This improves performance, but if the computer ++crashes, data may be lost or the file system corrupted as a ++result. The @command{sync} command ensures everything in memory ++is written to disk. ++ ++Any arguments are ignored, except for a lone @option{--help} or ++@option{--version} (@pxref{Common options}). ++ ++@exitstatus ++ ++ ++@node truncate invocation ++@section @command{truncate}: Shrink or extend the size of a file ++ ++@pindex truncate ++@cindex truncating, file sizes ++ ++@command{truncate} shrinks or extends the size of each @var{file} to the ++specified size. Synopsis: ++ ++@example ++truncate @var{option}@dots{} @var{file}@dots{} ++@end example ++ ++@cindex files, creating ++Any @var{file} that does not exist is created. ++ ++@cindex sparse files, creating ++@cindex holes, creating files with ++If a @var{file} is larger than the specified size, the extra data is lost. ++If a @var{file} is shorter, it is extended and the extended part (or hole) ++reads as zero bytes. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -c ++@itemx --no-create ++@opindex -c ++@opindex --no-create ++Do not create files that do not exist. ++ ++@item -o ++@itemx --io-blocks ++@opindex -o ++@opindex --io-blocks ++Treat @var{size} as number of I/O blocks of the @var{file} rather than bytes. ++ ++@item -r @var{rfile} ++@itemx --reference=@var{rfile} ++@opindex -r ++@opindex --reference ++Set the size of each @var{file} to the same size as @var{rfile}. ++ ++@item -s @var{size} ++@itemx --size=@var{size} ++@opindex -s ++@opindex --size ++Set the size of each @var{file} to this @var{size}. ++@multiplierSuffixesNoBlocks{size} ++ ++@var{size} may also be prefixed by one of the following to adjust ++the size of each @var{file} based on their current size: ++@example ++@samp{+} => extend by ++@samp{-} => reduce by ++@samp{<} => at most ++@samp{>} => at least ++@samp{/} => round down to multiple of ++@samp{%} => round up to multiple of ++@end example ++ ++@end table ++ ++@exitstatus ++ ++ ++@node Printing text ++@chapter Printing text ++ ++@cindex printing text, commands for ++@cindex commands for printing text ++ ++This section describes commands that display text strings. ++ ++@menu ++* echo invocation:: Print a line of text. ++* printf invocation:: Format and print data. ++* yes invocation:: Print a string until interrupted. ++@end menu ++ ++ ++@node echo invocation ++@section @command{echo}: Print a line of text ++ ++@pindex echo ++@cindex displaying text ++@cindex printing text ++@cindex text, displaying ++@cindex arbitrary text, displaying ++ ++@command{echo} writes each given @var{string} to standard output, with a ++space between each and a newline after the last one. Synopsis: ++ ++@example ++echo [@var{option}]@dots{} [@var{string}]@dots{} ++@end example ++ ++@mayConflictWithShellBuiltIn{echo} ++ ++The program accepts the following options. Also see @ref{Common options}. ++Options must precede operands, and the normally-special argument ++@samp{--} has no special meaning and is treated like any other ++@var{string}. ++ ++@table @samp ++@item -n ++@opindex -n ++Do not output the trailing newline. ++ ++@item -e ++@opindex -e ++@cindex backslash escapes ++Enable interpretation of the following backslash-escaped characters in ++each @var{string}: ++ ++@table @samp ++@item \a ++alert (bell) ++@item \b ++backspace ++@item \c ++produce no further output ++@item \f ++form feed ++@item \n ++newline ++@item \r ++carriage return ++@item \t ++horizontal tab ++@item \v ++vertical tab ++@item \\ ++backslash ++@item \0@var{nnn} ++the eight-bit value that is the octal number @var{nnn} ++(zero to three octal digits) ++@item \@var{nnn} ++the eight-bit value that is the octal number @var{nnn} ++(one to three octal digits) ++@item \x@var{hh} ++the eight-bit value that is the hexadecimal number @var{hh} ++(one or two hexadecimal digits) ++@end table ++ ++@item -E ++@opindex -E ++@cindex backslash escapes ++Disable interpretation of backslash escapes in each @var{string}. ++This is the default. If @option{-e} and @option{-E} are both ++specified, the last one given takes effect. ++ ++@end table ++ ++@vindex POSIXLY_CORRECT ++If the @env{POSIXLY_CORRECT} environment variable is set, then when ++@command{echo}'s first argument is not @option{-n} it outputs ++option-like arguments instead of treating them as options. For ++example, @code{echo -ne hello} outputs @samp{-ne hello} instead of ++plain @samp{hello}. ++ ++@acronym{POSIX} does not require support for any options, and says ++that the behavior of @command{echo} is implementation-defined if any ++@var{string} contains a backslash or if the first argument is ++@option{-n}. Portable programs can use the @command{printf} command ++if they need to omit trailing newlines or output control characters or ++backslashes. @xref{printf invocation}. ++ ++@exitstatus ++ ++ ++@node printf invocation ++@section @command{printf}: Format and print data ++ ++@pindex printf ++@command{printf} does formatted printing of text. Synopsis: ++ ++@example ++printf @var{format} [@var{argument}]@dots{} ++@end example ++ ++@command{printf} prints the @var{format} string, interpreting @samp{%} ++directives and @samp{\} escapes to format numeric and string arguments ++in a way that is mostly similar to the C @samp{printf} function. ++@xref{Output Conversion Syntax,, @command{printf} format directives, ++libc, The GNU C Library Reference Manual}, for details. ++The differences are listed below. ++ ++@mayConflictWithShellBuiltIn{printf} ++ ++@itemize @bullet ++ ++@item ++The @var{format} argument is reused as necessary to convert all the ++given @var{argument}s. For example, the command @samp{printf %s a b} ++outputs @samp{ab}. ++ ++@item ++Missing @var{argument}s are treated as null strings or as zeros, ++depending on whether the context expects a string or a number. For ++example, the command @samp{printf %sx%d} prints @samp{x0}. ++ ++@item ++@kindex \c ++An additional escape, @samp{\c}, causes @command{printf} to produce no ++further output. For example, the command @samp{printf 'A%sC\cD%sF' B ++E} prints @samp{ABC}. ++ ++@item ++The hexadecimal escape sequence @samp{\x@var{hh}} has at most two ++digits, as opposed to C where it can have an unlimited number of ++digits. For example, the command @samp{printf '\x07e'} prints two ++bytes, whereas the C statement @samp{printf ("\x07e")} prints just ++one. ++ ++@item ++@kindex %b ++@command{printf} has an additional directive, @samp{%b}, which prints its ++argument string with @samp{\} escapes interpreted in the same way as in ++the @var{format} string, except that octal escapes are of the form ++@samp{\0@var{ooo}} where @var{ooo} is 0 to 3 octal digits. ++If a precision is also given, it limits the number of bytes printed ++from the converted string. ++ ++@item ++Numeric arguments must be single C constants, possibly with leading ++@samp{+} or @samp{-}. For example, @samp{printf %.4d -3} outputs ++@samp{-0003}. ++ ++@item ++@vindex POSIXLY_CORRECT ++If the leading character of a numeric argument is @samp{"} or @samp{'} ++then its value is the numeric value of the immediately following ++character. Any remaining characters are silently ignored if the ++@env{POSIXLY_CORRECT} environment variable is set; otherwise, a ++warning is printed. For example, @samp{printf "%d" "'a"} outputs ++@samp{97} on hosts that use the @acronym{ASCII} character set, since ++@samp{a} has the numeric value 97 in @acronym{ASCII}. ++ ++@end itemize ++ ++@vindex LC_NUMERIC ++A floating-point argument must use a period before any fractional ++digits, but is printed according to the @env{LC_NUMERIC} category of the ++current locale. For example, in a locale whose radix character is a ++comma, the command @samp{printf %g 3.14} outputs @samp{3,14} whereas ++the command @samp{printf %g 3,14} is an error. ++ ++@kindex \@var{ooo} ++@kindex \x@var{hh} ++@command{printf} interprets @samp{\@var{ooo}} in @var{format} as an octal number ++(if @var{ooo} is 1 to 3 octal digits) specifying a character to print, ++and @samp{\x@var{hh}} as a hexadecimal number (if @var{hh} is 1 to 2 hex ++digits) specifying a character to print. ++ ++@kindex \uhhhh ++@kindex \Uhhhhhhhh ++@cindex Unicode ++@cindex ISO/IEC 10646 ++@vindex LC_CTYPE ++@command{printf} interprets two character syntaxes introduced in ++@acronym{ISO} C 99: ++@samp{\u} for 16-bit Unicode (@acronym{ISO}/@acronym{IEC} 10646) ++characters, specified as ++four hexadecimal digits @var{hhhh}, and @samp{\U} for 32-bit Unicode ++characters, specified as eight hexadecimal digits @var{hhhhhhhh}. ++@command{printf} outputs the Unicode characters ++according to the @env{LC_CTYPE} locale. Unicode characters in the ranges ++U+0000...U+009F, U+D800...U+DFFF cannot be specified by this syntax, except ++for U+0024 ($), U+0040 (@@), and U+0060 (@`). ++ ++The processing of @samp{\u} and @samp{\U} requires a full-featured ++@code{iconv} facility. It is activated on systems with glibc 2.2 (or newer), ++or when @code{libiconv} is installed prior to this package. Otherwise ++@samp{\u} and @samp{\U} will print as-is. ++ ++The only options are a lone @option{--help} or ++@option{--version}. @xref{Common options}. ++Options must precede operands. ++ ++The Unicode character syntaxes are useful for writing strings in a locale ++independent way. For example, a string containing the Euro currency symbol ++ ++@example ++$ env printf '\u20AC 14.95' ++@end example ++ ++@noindent ++will be output correctly in all locales supporting the Euro symbol ++(@acronym{ISO}-8859-15, UTF-8, and others). Similarly, a Chinese string ++ ++@example ++$ env printf '\u4e2d\u6587' ++@end example ++ ++@noindent ++will be output correctly in all Chinese locales (GB2312, BIG5, UTF-8, etc). ++ ++Note that in these examples, the @command{printf} command has been ++invoked via @command{env} to ensure that we run the program found via ++your shell's search path, and not a shell alias or a built-in function. ++ ++For larger strings, you don't need to look up the hexadecimal code ++values of each character one by one. @acronym{ASCII} characters mixed with \u ++escape sequences is also known as the JAVA source file encoding. You can ++use GNU recode 3.5c (or newer) to convert strings to this encoding. Here ++is how to convert a piece of text into a shell script which will output ++this text in a locale-independent way: ++ ++@smallexample ++$ LC_CTYPE=zh_CN.big5 /usr/local/bin/printf \ ++ '\u4e2d\u6587\n' > sample.txt ++$ recode BIG5..JAVA < sample.txt \ ++ | sed -e "s|^|/usr/local/bin/printf '|" -e "s|$|\\\\n'|" \ ++ > sample.sh ++@end smallexample ++ ++@exitstatus ++ ++ ++@node yes invocation ++@section @command{yes}: Print a string until interrupted ++ ++@pindex yes ++@cindex repeated output of a string ++ ++@command{yes} prints the command line arguments, separated by spaces and ++followed by a newline, forever until it is killed. If no arguments are ++given, it prints @samp{y} followed by a newline forever until killed. ++ ++Upon a write error, @command{yes} exits with status @samp{1}. ++ ++The only options are a lone @option{--help} or @option{--version}. ++To output an argument that begins with ++@samp{-}, precede it with @option{--}, e.g., @samp{yes -- --help}. ++@xref{Common options}. ++ ++ ++@node Conditions ++@chapter Conditions ++ ++@cindex conditions ++@cindex commands for exit status ++@cindex exit status commands ++ ++This section describes commands that are primarily useful for their exit ++status, rather than their output. Thus, they are often used as the ++condition of shell @code{if} statements, or as the last command in a ++pipeline. ++ ++@menu ++* false invocation:: Do nothing, unsuccessfully. ++* true invocation:: Do nothing, successfully. ++* test invocation:: Check file types and compare values. ++* expr invocation:: Evaluate expressions. ++@end menu ++ ++ ++@node false invocation ++@section @command{false}: Do nothing, unsuccessfully ++ ++@pindex false ++@cindex do nothing, unsuccessfully ++@cindex failure exit status ++@cindex exit status of @command{false} ++ ++@command{false} does nothing except return an exit status of 1, meaning ++@dfn{failure}. It can be used as a place holder in shell scripts ++where an unsuccessful command is needed. ++In most modern shells, @command{false} is a built-in command, so when ++you use @samp{false} in a script, you're probably using the built-in ++command, not the one documented here. ++ ++@command{false} honors the @option{--help} and @option{--version} options. ++ ++This version of @command{false} is implemented as a C program, and is thus ++more secure and faster than a shell script implementation, and may safely ++be used as a dummy shell for the purpose of disabling accounts. ++ ++Note that @command{false} (unlike all other programs documented herein) ++exits unsuccessfully, even when invoked with ++@option{--help} or @option{--version}. ++ ++Portable programs should not assume that the exit status of ++@command{false} is 1, as it is greater than 1 on some ++non-@acronym{GNU} hosts. ++ ++ ++@node true invocation ++@section @command{true}: Do nothing, successfully ++ ++@pindex true ++@cindex do nothing, successfully ++@cindex no-op ++@cindex successful exit ++@cindex exit status of @command{true} ++ ++@command{true} does nothing except return an exit status of 0, meaning ++@dfn{success}. It can be used as a place holder in shell scripts ++where a successful command is needed, although the shell built-in ++command @code{:} (colon) may do the same thing faster. ++In most modern shells, @command{true} is a built-in command, so when ++you use @samp{true} in a script, you're probably using the built-in ++command, not the one documented here. ++ ++@command{true} honors the @option{--help} and @option{--version} options. ++ ++Note, however, that it is possible to cause @command{true} ++to exit with nonzero status: with the @option{--help} or @option{--version} ++option, and with standard ++output already closed or redirected to a file that evokes an I/O error. ++For example, using a Bourne-compatible shell: ++ ++@example ++$ ./true --version >&- ++./true: write error: Bad file number ++$ ./true --version > /dev/full ++./true: write error: No space left on device ++@end example ++ ++This version of @command{true} is implemented as a C program, and is thus ++more secure and faster than a shell script implementation, and may safely ++be used as a dummy shell for the purpose of disabling accounts. ++ ++@node test invocation ++@section @command{test}: Check file types and compare values ++ ++@pindex test ++@cindex check file types ++@cindex compare values ++@cindex expression evaluation ++ ++@command{test} returns a status of 0 (true) or 1 (false) depending on the ++evaluation of the conditional expression @var{expr}. Each part of the ++expression must be a separate argument. ++ ++@command{test} has file status checks, string operators, and numeric ++comparison operators. ++ ++@command{test} has an alternate form that uses opening and closing ++square brackets instead a leading @samp{test}. For example, instead ++of @samp{test -d /}, you can write @samp{[ -d / ]}. The square ++brackets must be separate arguments; for example, @samp{[-d /]} does ++not have the desired effect. Since @samp{test @var{expr}} and @samp{[ ++@var{expr} ]} have the same meaning, only the former form is discussed ++below. ++ ++Synopses: ++ ++@example ++test @var{expression} ++test ++[ @var{expression} ] ++[ ] ++[ @var{option} ++@end example ++ ++@mayConflictWithShellBuiltIn{test} ++ ++If @var{expression} is omitted, @command{test} returns false. ++If @var{expression} is a single argument, ++@command{test} returns false if the argument is null and true otherwise. The argument ++can be any string, including strings like @samp{-d}, @samp{-1}, ++@samp{--}, @samp{--help}, and @samp{--version} that most other ++programs would treat as options. To get help and version information, ++invoke the commands @samp{[ --help} and @samp{[ --version}, without ++the usual closing brackets. @xref{Common options}. ++ ++@cindex exit status of @command{test} ++Exit status: ++ ++@display ++0 if the expression is true, ++1 if the expression is false, ++2 if an error occurred. ++@end display ++ ++@menu ++* File type tests:: -[bcdfhLpSt] ++* Access permission tests:: -[gkruwxOG] ++* File characteristic tests:: -e -s -nt -ot -ef ++* String tests:: -z -n = != ++* Numeric tests:: -eq -ne -lt -le -gt -ge ++* Connectives for test:: ! -a -o ++@end menu ++ ++ ++@node File type tests ++@subsection File type tests ++ ++@cindex file type tests ++ ++These options test for particular types of files. (Everything's a file, ++but not all files are the same!) ++ ++@table @samp ++ ++@item -b @var{file} ++@opindex -b ++@cindex block special check ++True if @var{file} exists and is a block special device. ++ ++@item -c @var{file} ++@opindex -c ++@cindex character special check ++True if @var{file} exists and is a character special device. ++ ++@item -d @var{file} ++@opindex -d ++@cindex directory check ++True if @var{file} exists and is a directory. ++ ++@item -f @var{file} ++@opindex -f ++@cindex regular file check ++True if @var{file} exists and is a regular file. ++ ++@item -h @var{file} ++@itemx -L @var{file} ++@opindex -L ++@opindex -h ++@cindex symbolic link check ++True if @var{file} exists and is a symbolic link. ++Unlike all other file-related tests, this test does not dereference ++@var{file} if it is a symbolic link. ++ ++@item -p @var{file} ++@opindex -p ++@cindex named pipe check ++True if @var{file} exists and is a named pipe. ++ ++@item -S @var{file} ++@opindex -S ++@cindex socket check ++True if @var{file} exists and is a socket. ++ ++@item -t @var{fd} ++@opindex -t ++@cindex terminal check ++True if @var{fd} is a file descriptor that is associated with a ++terminal. ++ ++@end table ++ ++ ++@node Access permission tests ++@subsection Access permission tests ++ ++@cindex access permission tests ++@cindex permission tests ++ ++These options test for particular access permissions. ++ ++@table @samp ++ ++@item -g @var{file} ++@opindex -g ++@cindex set-group-ID check ++True if @var{file} exists and has its set-group-ID bit set. ++ ++@item -k @var{file} ++@opindex -k ++@cindex sticky bit check ++True if @var{file} exists and has its @dfn{sticky} bit set. ++ ++@item -r @var{file} ++@opindex -r ++@cindex readable file check ++True if @var{file} exists and read permission is granted. ++ ++@item -u @var{file} ++@opindex -u ++@cindex set-user-ID check ++True if @var{file} exists and has its set-user-ID bit set. ++ ++@item -w @var{file} ++@opindex -w ++@cindex writable file check ++True if @var{file} exists and write permission is granted. ++ ++@item -x @var{file} ++@opindex -x ++@cindex executable file check ++True if @var{file} exists and execute permission is granted ++(or search permission, if it is a directory). ++ ++@item -O @var{file} ++@opindex -O ++@cindex owned by effective user ID check ++True if @var{file} exists and is owned by the current effective user ID. ++ ++@item -G @var{file} ++@opindex -G ++@cindex owned by effective group ID check ++True if @var{file} exists and is owned by the current effective group ID. ++ ++@end table ++ ++@node File characteristic tests ++@subsection File characteristic tests ++ ++@cindex file characteristic tests ++ ++These options test other file characteristics. ++ ++@table @samp ++ ++@item -e @var{file} ++@opindex -e ++@cindex existence-of-file check ++True if @var{file} exists. ++ ++@item -s @var{file} ++@opindex -s ++@cindex nonempty file check ++True if @var{file} exists and has a size greater than zero. ++ ++@item @var{file1} -nt @var{file2} ++@opindex -nt ++@cindex newer-than file check ++True if @var{file1} is newer (according to modification date) than ++@var{file2}, or if @var{file1} exists and @var{file2} does not. ++ ++@item @var{file1} -ot @var{file2} ++@opindex -ot ++@cindex older-than file check ++True if @var{file1} is older (according to modification date) than ++@var{file2}, or if @var{file2} exists and @var{file1} does not. ++ ++@item @var{file1} -ef @var{file2} ++@opindex -ef ++@cindex same file check ++@cindex hard link check ++True if @var{file1} and @var{file2} have the same device and inode ++numbers, i.e., if they are hard links to each other. ++ ++@end table ++ ++ ++@node String tests ++@subsection String tests ++ ++@cindex string tests ++ ++These options test string characteristics. You may need to quote ++@var{string} arguments for the shell. For example: ++ ++@example ++test -n "$V" ++@end example ++ ++The quotes here prevent the wrong arguments from being passed to ++@command{test} if @samp{$V} is empty or contains special characters. ++ ++@table @samp ++ ++@item -z @var{string} ++@opindex -z ++@cindex zero-length string check ++True if the length of @var{string} is zero. ++ ++@item -n @var{string} ++@itemx @var{string} ++@opindex -n ++@cindex nonzero-length string check ++True if the length of @var{string} is nonzero. ++ ++@item @var{string1} = @var{string2} ++@opindex = ++@cindex equal string check ++True if the strings are equal. ++ ++@item @var{string1} != @var{string2} ++@opindex != ++@cindex not-equal string check ++True if the strings are not equal. ++ ++@end table ++ ++ ++@node Numeric tests ++@subsection Numeric tests ++ ++@cindex numeric tests ++@cindex arithmetic tests ++ ++Numeric relational operators. The arguments must be entirely numeric ++(possibly negative), or the special expression @w{@code{-l @var{string}}}, ++which evaluates to the length of @var{string}. ++ ++@table @samp ++ ++@item @var{arg1} -eq @var{arg2} ++@itemx @var{arg1} -ne @var{arg2} ++@itemx @var{arg1} -lt @var{arg2} ++@itemx @var{arg1} -le @var{arg2} ++@itemx @var{arg1} -gt @var{arg2} ++@itemx @var{arg1} -ge @var{arg2} ++@opindex -eq ++@opindex -ne ++@opindex -lt ++@opindex -le ++@opindex -gt ++@opindex -ge ++These arithmetic binary operators return true if @var{arg1} is equal, ++not-equal, less-than, less-than-or-equal, greater-than, or ++greater-than-or-equal than @var{arg2}, respectively. ++ ++@end table ++ ++For example: ++ ++@example ++test -1 -gt -2 && echo yes ++@result{} yes ++test -l abc -gt 1 && echo yes ++@result{} yes ++test 0x100 -eq 1 ++@error{} test: integer expression expected before -eq ++@end example ++ ++ ++@node Connectives for test ++@subsection Connectives for @command{test} ++ ++@cindex logical connectives ++@cindex connectives, logical ++ ++The usual logical connectives. ++ ++@table @samp ++ ++@item ! @var{expr} ++@opindex ! ++True if @var{expr} is false. ++ ++@item @var{expr1} -a @var{expr2} ++@opindex -a ++@cindex logical and operator ++@cindex and operator ++True if both @var{expr1} and @var{expr2} are true. ++ ++@item @var{expr1} -o @var{expr2} ++@opindex -o ++@cindex logical or operator ++@cindex or operator ++True if either @var{expr1} or @var{expr2} is true. ++ ++@end table ++ ++ ++@node expr invocation ++@section @command{expr}: Evaluate expressions ++ ++@pindex expr ++@cindex expression evaluation ++@cindex evaluation of expressions ++ ++@command{expr} evaluates an expression and writes the result on standard ++output. Each token of the expression must be a separate argument. ++ ++Operands are either integers or strings. Integers consist of one or ++more decimal digits, with an optional leading @samp{-}. ++@command{expr} converts ++anything appearing in an operand position to an integer or a string ++depending on the operation being applied to it. ++ ++Strings are not quoted for @command{expr} itself, though you may need to ++quote them to protect characters with special meaning to the shell, ++e.g., spaces. However, regardless of whether it is quoted, a string ++operand should not be a parenthesis or any of @command{expr}'s ++operators like @code{+}, so you cannot safely pass an arbitrary string ++@code{$str} to expr merely by quoting it to the shell. One way to ++work around this is to use the @sc{gnu} extension @code{+}, ++(e.g., @code{+ "$str" = foo}); a more portable way is to use ++@code{@w{" $str"}} and to adjust the rest of the expression to take ++the leading space into account (e.g., @code{@w{" $str" = " foo"}}). ++ ++You should not pass a negative integer or a string with leading ++@samp{-} as @command{expr}'s first argument, as it might be ++misinterpreted as an option; this can be avoided by parenthesization. ++Also, portable scripts should not use a string operand that happens to ++take the form of an integer; this can be worked around by inserting ++leading spaces as mentioned above. ++ ++@cindex parentheses for grouping ++Operators may be given as infix symbols or prefix keywords. Parentheses ++may be used for grouping in the usual manner. You must quote ++parentheses and many operators to avoid the shell evaluating them, ++however. ++ ++When built with support for the GNU MP library, @command{expr} uses ++arbitrary-precision arithmetic; otherwise, it uses native arithmetic ++types and may fail due to arithmetic overflow. ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. Options must precede operands. ++ ++@cindex exit status of @command{expr} ++Exit status: ++ ++@display ++0 if the expression is neither null nor 0, ++1 if the expression is null or 0, ++2 if the expression is invalid, ++3 if an internal error occurred (e.g., arithmetic overflow). ++@end display ++ ++@menu ++* String expressions:: + : match substr index length ++* Numeric expressions:: + - * / % ++* Relations for expr:: | & < <= = == != >= > ++* Examples of expr:: Examples. ++@end menu ++ ++ ++@node String expressions ++@subsection String expressions ++ ++@cindex string expressions ++@cindex expressions, string ++ ++@command{expr} supports pattern matching and other string operators. These ++have higher precedence than both the numeric and relational operators (in ++the next sections). ++ ++@table @samp ++ ++@item @var{string} : @var{regex} ++@cindex pattern matching ++@cindex regular expression matching ++@cindex matching patterns ++Perform pattern matching. The arguments are converted to strings and the ++second is considered to be a (basic, a la GNU @code{grep}) regular ++expression, with a @code{^} implicitly prepended. The first argument is ++then matched against this regular expression. ++ ++If the match succeeds and @var{regex} uses @samp{\(} and @samp{\)}, the ++@code{:} expression returns the part of @var{string} that matched the ++subexpression; otherwise, it returns the number of characters matched. ++ ++If the match fails, the @code{:} operator returns the null string if ++@samp{\(} and @samp{\)} are used in @var{regex}, otherwise 0. ++ ++@kindex \( @r{regexp operator} ++Only the first @samp{\( @dots{} \)} pair is relevant to the return ++value; additional pairs are meaningful only for grouping the regular ++expression operators. ++ ++@kindex \+ @r{regexp operator} ++@kindex \? @r{regexp operator} ++@kindex \| @r{regexp operator} ++In the regular expression, @code{\+}, @code{\?}, and @code{\|} are ++operators which respectively match one or more, zero or one, or separate ++alternatives. SunOS and other @command{expr}'s treat these as regular ++characters. (@acronym{POSIX} allows either behavior.) ++@xref{Top, , Regular Expression Library, regex, Regex}, for details of ++regular expression syntax. Some examples are in @ref{Examples of expr}. ++ ++@item match @var{string} @var{regex} ++@findex match ++An alternative way to do pattern matching. This is the same as ++@w{@samp{@var{string} : @var{regex}}}. ++ ++@item substr @var{string} @var{position} @var{length} ++@findex substr ++Returns the substring of @var{string} beginning at @var{position} ++with length at most @var{length}. If either @var{position} or ++@var{length} is negative, zero, or non-numeric, returns the null string. ++ ++@item index @var{string} @var{charset} ++@findex index ++Returns the first position in @var{string} where the first character in ++@var{charset} was found. If no character in @var{charset} is found in ++@var{string}, return 0. ++ ++@item length @var{string} ++@findex length ++Returns the length of @var{string}. ++ ++@item + @var{token} ++@kindex + ++Interpret @var{token} as a string, even if it is a keyword like @var{match} ++or an operator like @code{/}. ++This makes it possible to test @code{expr length + "$x"} or ++@code{expr + "$x" : '.*/\(.\)'} and have it do the right thing even if ++the value of @var{$x} happens to be (for example) @code{/} or @code{index}. ++This operator is a @acronym{GNU} extension. Portable shell scripts should use ++@code{@w{" $token"} : @w{' \(.*\)'}} instead of @code{+ "$token"}. ++ ++@end table ++ ++To make @command{expr} interpret keywords as strings, you must use the ++@code{quote} operator. ++ ++ ++@node Numeric expressions ++@subsection Numeric expressions ++ ++@cindex numeric expressions ++@cindex expressions, numeric ++ ++@command{expr} supports the usual numeric operators, in order of increasing ++precedence. These numeric operators have lower precedence than the ++string operators described in the previous section, and higher precedence ++than the connectives (next section). ++ ++@table @samp ++ ++@item + - ++@kindex + ++@kindex - ++@cindex addition ++@cindex subtraction ++Addition and subtraction. Both arguments are converted to integers; ++an error occurs if this cannot be done. ++ ++@item * / % ++@kindex * ++@kindex / ++@kindex % ++@cindex multiplication ++@cindex division ++@cindex remainder ++Multiplication, division, remainder. Both arguments are converted to ++integers; an error occurs if this cannot be done. ++ ++@end table ++ ++ ++@node Relations for expr ++@subsection Relations for @command{expr} ++ ++@cindex connectives, logical ++@cindex logical connectives ++@cindex relations, numeric or string ++ ++@command{expr} supports the usual logical connectives and relations. These ++have lower precedence than the string and numeric operators ++(previous sections). Here is the list, lowest-precedence operator first. ++ ++@table @samp ++ ++@item | ++@kindex | ++@cindex logical or operator ++@cindex or operator ++Returns its first argument if that is neither null nor zero, otherwise ++its second argument if it is neither null nor zero, otherwise 0. It ++does not evaluate its second argument if its first argument is neither ++null nor zero. ++ ++@item & ++@kindex & ++@cindex logical and operator ++@cindex and operator ++Return its first argument if neither argument is null or zero, otherwise ++0. It does not evaluate its second argument if its first argument is ++null or zero. ++ ++@item < <= = == != >= > ++@kindex < ++@kindex <= ++@kindex = ++@kindex == ++@kindex > ++@kindex >= ++@cindex comparison operators ++@vindex LC_COLLATE ++Compare the arguments and return 1 if the relation is true, 0 otherwise. ++@code{==} is a synonym for @code{=}. @command{expr} first tries to convert ++both arguments to integers and do a numeric comparison; if either ++conversion fails, it does a lexicographic comparison using the character ++collating sequence specified by the @env{LC_COLLATE} locale. ++ ++@end table ++ ++ ++@node Examples of expr ++@subsection Examples of using @command{expr} ++ ++@cindex examples of @command{expr} ++Here are a few examples, including quoting for shell metacharacters. ++ ++To add 1 to the shell variable @code{foo}, in Bourne-compatible shells: ++ ++@example ++foo=`expr $foo + 1` ++@end example ++ ++To print the non-directory part of the file name stored in ++@code{$fname}, which need not contain a @code{/}: ++ ++@example ++expr $fname : '.*/\(.*\)' '|' $fname ++@end example ++ ++An example showing that @code{\+} is an operator: ++ ++@example ++expr aaa : 'a\+' ++@result{} 3 ++@end example ++ ++@example ++expr abc : 'a\(.\)c' ++@result{} b ++expr index abcdef cz ++@result{} 3 ++expr index index a ++@error{} expr: syntax error ++expr index + index a ++@result{} 0 ++@end example ++ ++ ++@node Redirection ++@chapter Redirection ++ ++@cindex redirection ++@cindex commands for redirection ++ ++Unix shells commonly provide several forms of @dfn{redirection}---ways ++to change the input source or output destination of a command. But one ++useful redirection is performed by a separate command, not by the shell; ++it's described here. ++ ++@menu ++* tee invocation:: Redirect output to multiple files or processes. ++@end menu ++ ++ ++@node tee invocation ++@section @command{tee}: Redirect output to multiple files or processes ++ ++@pindex tee ++@cindex pipe fitting ++@cindex destinations, multiple output ++@cindex read from stdin and write to stdout and files ++ ++The @command{tee} command copies standard input to standard output and also ++to any files given as arguments. This is useful when you want not only ++to send some data down a pipe, but also to save a copy. Synopsis: ++ ++@example ++tee [@var{option}]@dots{} [@var{file}]@dots{} ++@end example ++ ++If a file being written to does not already exist, it is created. If a ++file being written to already exists, the data it previously contained ++is overwritten unless the @option{-a} option is used. ++ ++A @var{file} of @samp{-} causes @command{tee} to send another copy of ++input to standard output, but this is typically not that useful as the ++copies are interleaved. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++@item -a ++@itemx --append ++@opindex -a ++@opindex --append ++Append standard input to the given files rather than overwriting ++them. ++ ++@item -i ++@itemx --ignore-interrupts ++@opindex -i ++@opindex --ignore-interrupts ++Ignore interrupt signals. ++ ++@end table ++ ++The @command{tee} command is useful when you happen to be transferring a large ++amount of data and also want to summarize that data without reading ++it a second time. For example, when you are downloading a DVD image, ++you often want to verify its signature or checksum right away. ++The inefficient way to do it is simply: ++ ++@example ++wget http://example.com/some.iso && sha1sum some.iso ++@end example ++ ++One problem with the above is that it makes you wait for the ++download to complete before starting the time-consuming SHA1 computation. ++Perhaps even more importantly, the above requires reading ++the DVD image a second time (the first was from the network). ++ ++The efficient way to do it is to interleave the download ++and SHA1 computation. Then, you'll get the checksum for ++free, because the entire process parallelizes so well: ++ ++@example ++# slightly contrived, to demonstrate process substitution ++wget -O - http://example.com/dvd.iso \ ++ | tee >(sha1sum > dvd.sha1) > dvd.iso ++@end example ++ ++That makes @command{tee} write not just to the expected output file, ++but also to a pipe running @command{sha1sum} and saving the final ++checksum in a file named @file{dvd.sha1}. ++ ++Note, however, that this example relies on a feature of modern shells ++called @dfn{process substitution} ++(the @samp{>(command)} syntax, above; ++@xref{Process Substitution,,Process Substitution, bashref, ++The Bash Reference Manual}.), ++so it works with @command{zsh}, @command{bash}, and @command{ksh}, ++but not with @command{/bin/sh}. So if you write code like this ++in a shell script, be sure to start the script with @samp{#!/bin/bash}. ++ ++Since the above example writes to one file and one process, ++a more conventional and portable use of @command{tee} is even better: ++ ++@example ++wget -O - http://example.com/dvd.iso \ ++ | tee dvd.iso | sha1sum > dvd.sha1 ++@end example ++ ++You can extend this example to make @command{tee} write to two processes, ++computing MD5 and SHA1 checksums in parallel. In this case, ++process substitution is required: ++ ++@example ++wget -O - http://example.com/dvd.iso \ ++ | tee >(sha1sum > dvd.sha1) \ ++ >(md5sum > dvd.md5) \ ++ > dvd.iso ++@end example ++ ++This technique is also useful when you want to make a @emph{compressed} ++copy of the contents of a pipe. ++Consider a tool to graphically summarize disk usage data from @samp{du -ak}. ++For a large hierarchy, @samp{du -ak} can run for a long time, ++and can easily produce terabytes of data, so you won't want to ++rerun the command unnecessarily. Nor will you want to save ++the uncompressed output. ++ ++Doing it the inefficient way, you can't even start the GUI ++until after you've compressed all of the @command{du} output: ++ ++@example ++du -ak | gzip -9 > /tmp/du.gz ++gzip -d /tmp/du.gz | xdiskusage -a ++@end example ++ ++With @command{tee} and process substitution, you start the GUI ++right away and eliminate the decompression completely: ++ ++@example ++du -ak | tee >(gzip -9 > /tmp/du.gz) | xdiskusage -a ++@end example ++ ++Finally, if you regularly create more than one type of ++compressed tarball at once, for example when @code{make dist} creates ++both @command{gzip}-compressed and @command{bzip2}-compressed tarballs, ++there may be a better way. ++Typical @command{automake}-generated @file{Makefile} rules create ++the two compressed tar archives with commands in sequence, like this ++(slightly simplified): ++ ++@example ++tardir=your-pkg-M.N ++tar chof - "$tardir" | gzip -9 -c > your-pkg-M.N.tar.gz ++tar chof - "$tardir" | bzip2 -9 -c > your-pkg-M.N.tar.bz2 ++@end example ++ ++However, if the hierarchy you are archiving and compressing is larger ++than a couple megabytes, and especially if you are using a multi-processor ++system with plenty of memory, then you can do much better by reading the ++directory contents only once and running the compression programs in parallel: ++ ++@example ++tardir=your-pkg-M.N ++tar chof - "$tardir" \ ++ | tee >(gzip -9 -c > your-pkg-M.N.tar.gz) \ ++ | bzip2 -9 -c > your-pkg-M.N.tar.bz2 ++@end example ++ ++@exitstatus ++ ++ ++@node File name manipulation ++@chapter File name manipulation ++ ++@cindex file name manipulation ++@cindex manipulation of file names ++@cindex commands for file name manipulation ++ ++This section describes commands that manipulate file names. ++ ++@menu ++* basename invocation:: Strip directory and suffix from a file name. ++* dirname invocation:: Strip non-directory suffix from a file name. ++* pathchk invocation:: Check file name validity and portability. ++@end menu ++ ++ ++@node basename invocation ++@section @command{basename}: Strip directory and suffix from a file name ++ ++@pindex basename ++@cindex strip directory and suffix from file names ++@cindex directory, stripping from file names ++@cindex suffix, stripping from file names ++@cindex file names, stripping directory and suffix ++@cindex leading directory components, stripping ++ ++@command{basename} removes any leading directory components from ++@var{name}. Synopsis: ++ ++@example ++basename @var{name} [@var{suffix}] ++@end example ++ ++If @var{suffix} is specified and is identical to the end of @var{name}, ++it is removed from @var{name} as well. Note that since trailing slashes ++are removed prior to suffix matching, @var{suffix} will do nothing if it ++contains slashes. @command{basename} prints the result on standard ++output. ++ ++@c This test is used both here and in the section on dirname. ++@macro basenameAndDirname ++Together, @command{basename} and @command{dirname} are designed such ++that if @samp{ls "$name"} succeeds, then the command sequence @samp{cd ++"$(dirname "$name")"; ls "$(basename "$name")"} will, too. This works ++for everything except file names containing a trailing newline. ++@end macro ++@basenameAndDirname ++ ++@acronym{POSIX} allows the implementation to define the results if ++@var{name} is empty or @samp{//}. In the former case, @acronym{GNU} ++@command{basename} returns the empty string. In the latter case, the ++result is @samp{//} on platforms where @var{//} is distinct from ++@var{/}, and @samp{/} on platforms where there is no difference. ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. Options must precede operands. ++ ++@exitstatus ++ ++Examples: ++ ++@smallexample ++# Output "sort". ++basename /usr/bin/sort ++ ++# Output "stdio". ++basename include/stdio.h .h ++@end smallexample ++ ++ ++@node dirname invocation ++@section @command{dirname}: Strip non-directory suffix from a file name ++ ++@pindex dirname ++@cindex directory components, printing ++@cindex stripping non-directory suffix ++@cindex non-directory suffix, stripping ++ ++@command{dirname} prints all but the final slash-delimited component of ++a string (presumably a file name). Synopsis: ++ ++@example ++dirname @var{name} ++@end example ++ ++If @var{name} is a single component, @command{dirname} prints @samp{.} ++(meaning the current directory). ++ ++@basenameAndDirname ++ ++@acronym{POSIX} allows the implementation to define the results if ++@var{name} is @samp{//}. With @acronym{GNU} @command{dirname}, the ++result is @samp{//} on platforms where @var{//} is distinct from ++@var{/}, and @samp{/} on platforms where there is no difference. ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. ++ ++@exitstatus ++ ++Examples: ++ ++@smallexample ++# Output "/usr/bin". ++dirname /usr/bin/sort ++ ++# Output ".". ++dirname stdio.h ++@end smallexample ++ ++ ++@node pathchk invocation ++@section @command{pathchk}: Check file name validity and portability ++ ++@pindex pathchk ++@cindex file names, checking validity and portability ++@cindex valid file names, checking for ++@cindex portable file names, checking for ++ ++@command{pathchk} checks validity and portability of file names. Synopsis: ++ ++@example ++pathchk [@var{option}]@dots{} @var{name}@dots{} ++@end example ++ ++For each @var{name}, @command{pathchk} prints an error message if any of ++these conditions is true: ++ ++@enumerate ++@item ++One of the existing directories in @var{name} does not have search ++(execute) permission, ++@item ++The length of @var{name} is larger than the maximum supported by the ++operating system. ++@item ++The length of one component of @var{name} is longer than ++its file system's maximum. ++@end enumerate ++ ++A nonexistent @var{name} is not an error, so long a file with that ++name could be created under the above conditions. ++ ++The program accepts the following options. Also see @ref{Common options}. ++Options must precede operands. ++ ++@table @samp ++ ++@item -p ++@opindex -p ++Instead of performing checks based on the underlying file system, ++print an error message if any of these conditions is true: ++ ++@enumerate ++@item ++A file name is empty. ++ ++@item ++A file name contains a character outside the @acronym{POSIX} portable file ++name character set, namely, the ASCII letters and digits, @samp{.}, ++@samp{_}, @samp{-}, and @samp{/}. ++ ++@item ++The length of a file name or one of its components exceeds the ++@acronym{POSIX} minimum limits for portability. ++@end enumerate ++ ++@item -P ++@opindex -P ++Print an error message if a file name is empty, or if it contains a component ++that begins with @samp{-}. ++ ++@item --portability ++@opindex --portability ++Print an error message if a file name is not portable to all @acronym{POSIX} ++hosts. This option is equivalent to @samp{-p -P}. ++ ++@end table ++ ++@cindex exit status of @command{pathchk} ++Exit status: ++ ++@display ++0 if all specified file names passed all checks, ++1 otherwise. ++@end display ++ ++ ++@node Working context ++@chapter Working context ++ ++@cindex working context ++@cindex commands for printing the working context ++ ++This section describes commands that display or alter the context in ++which you are working: the current directory, the terminal settings, and ++so forth. See also the user-related commands in the next section. ++ ++@menu ++* pwd invocation:: Print working directory. ++* stty invocation:: Print or change terminal characteristics. ++* printenv invocation:: Print environment variables. ++* tty invocation:: Print file name of terminal on standard input. ++@end menu ++ ++ ++@node pwd invocation ++@section @command{pwd}: Print working directory ++ ++@pindex pwd ++@cindex print name of current directory ++@cindex current working directory, printing ++@cindex working directory, printing ++ ++ ++@command{pwd} prints the name of the current directory. Synopsis: ++ ++@example ++pwd [@var{option}]@dots{} ++@end example ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++@item -L ++@itemx --logical ++@opindex -L ++@opindex --logical ++If the contents of the environment variable @env{PWD} provide an ++absolute name of the current directory with no @samp{.} or @samp{..} ++components, but possibly with symbolic links, then output those ++contents. Otherwise, fall back to default @option{-P} handling. ++ ++@item -P ++@itemx --physical ++@opindex -P ++@opindex --physical ++Print a fully resolved name for the current directory. That is, all ++components of the printed name will be actual directory names---none ++will be symbolic links. ++@end table ++ ++@cindex symbolic links and @command{pwd} ++If @option{-L} and @option{-P} are both given, the last one takes ++precedence. If neither option is given, then this implementation uses ++@option{-P} as the default unless the @env{POSIXLY_CORRECT} ++environment variable is set. ++ ++@mayConflictWithShellBuiltIn{pwd} ++ ++@exitstatus ++ ++ ++@node stty invocation ++@section @command{stty}: Print or change terminal characteristics ++ ++@pindex stty ++@cindex change or print terminal settings ++@cindex terminal settings ++@cindex line settings of terminal ++ ++@command{stty} prints or changes terminal characteristics, such as baud rate. ++Synopses: ++ ++@example ++stty [@var{option}] [@var{setting}]@dots{} ++stty [@var{option}] ++@end example ++ ++If given no line settings, @command{stty} prints the baud rate, line ++discipline number (on systems that support it), and line settings ++that have been changed from the values set by @samp{stty sane}. ++By default, mode reading and setting are performed on the tty line ++connected to standard input, although this can be modified by the ++@option{--file} option. ++ ++@command{stty} accepts many non-option arguments that change aspects of ++the terminal line operation, as described below. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++@item -a ++@itemx --all ++@opindex -a ++@opindex --all ++Print all current settings in human-readable form. This option may not ++be used in combination with any line settings. ++ ++@item -F @var{device} ++@itemx --file=@var{device} ++@opindex -F ++@opindex --file ++Set the line opened by the file name specified in @var{device} instead of ++the tty line connected to standard input. This option is necessary ++because opening a @acronym{POSIX} tty requires use of the @code{O_NONDELAY} flag to ++prevent a @acronym{POSIX} tty from blocking until the carrier detect line is high if ++the @code{clocal} flag is not set. Hence, it is not always possible ++to allow the shell to open the device in the traditional manner. ++ ++@item -g ++@itemx --save ++@opindex -g ++@opindex --save ++@cindex machine-readable @command{stty} output ++Print all current settings in a form that can be used as an argument to ++another @command{stty} command to restore the current settings. This option ++may not be used in combination with any line settings. ++ ++@end table ++ ++Many settings can be turned off by preceding them with a @samp{-}. ++Such arguments are marked below with ``May be negated'' in their ++description. The descriptions themselves refer to the positive ++case, that is, when @emph{not} negated (unless stated otherwise, ++of course). ++ ++Some settings are not available on all @acronym{POSIX} systems, since they use ++extensions. Such arguments are marked below with ``Non-@acronym{POSIX}'' in their ++description. On non-@acronym{POSIX} systems, those or other settings also may not ++be available, but it's not feasible to document all the variations: just ++try it and see. ++ ++@exitstatus ++ ++@menu ++* Control:: Control settings ++* Input:: Input settings ++* Output:: Output settings ++* Local:: Local settings ++* Combination:: Combination settings ++* Characters:: Special characters ++* Special:: Special settings ++@end menu ++ ++ ++@node Control ++@subsection Control settings ++ ++@cindex control settings ++Control settings: ++ ++@table @samp ++@item parenb ++@opindex parenb ++@cindex two-way parity ++Generate parity bit in output and expect parity bit in input. ++May be negated. ++ ++@item parodd ++@opindex parodd ++@cindex odd parity ++@cindex even parity ++Set odd parity (even if negated). May be negated. ++ ++@item cs5 ++@itemx cs6 ++@itemx cs7 ++@itemx cs8 ++@opindex cs@var{n} ++@cindex character size ++@cindex eight-bit characters ++Set character size to 5, 6, 7, or 8 bits. ++ ++@item hup ++@itemx hupcl ++@opindex hup[cl] ++Send a hangup signal when the last process closes the tty. May be ++negated. ++ ++@item cstopb ++@opindex cstopb ++@cindex stop bits ++Use two stop bits per character (one if negated). May be negated. ++ ++@item cread ++@opindex cread ++Allow input to be received. May be negated. ++ ++@item clocal ++@opindex clocal ++@cindex modem control ++Disable modem control signals. May be negated. ++ ++@item crtscts ++@opindex crtscts ++@cindex hardware flow control ++@cindex flow control, hardware ++@cindex RTS/CTS flow control ++Enable RTS/CTS flow control. Non-@acronym{POSIX}. May be negated. ++@end table ++ ++ ++@node Input ++@subsection Input settings ++ ++@cindex input settings ++These settings control operations on data received from the terminal. ++ ++@table @samp ++@item ignbrk ++@opindex ignbrk ++@cindex breaks, ignoring ++Ignore break characters. May be negated. ++ ++@item brkint ++@opindex brkint ++@cindex breaks, cause interrupts ++Make breaks cause an interrupt signal. May be negated. ++ ++@item ignpar ++@opindex ignpar ++@cindex parity, ignoring ++Ignore characters with parity errors. May be negated. ++ ++@item parmrk ++@opindex parmrk ++@cindex parity errors, marking ++Mark parity errors (with a 255-0-character sequence). May be negated. ++ ++@item inpck ++@opindex inpck ++Enable input parity checking. May be negated. ++ ++@item istrip ++@opindex istrip ++@cindex eight-bit input ++Clear high (8th) bit of input characters. May be negated. ++ ++@item inlcr ++@opindex inlcr ++@cindex newline, translating to return ++Translate newline to carriage return. May be negated. ++ ++@item igncr ++@opindex igncr ++@cindex return, ignoring ++Ignore carriage return. May be negated. ++ ++@item icrnl ++@opindex icrnl ++@cindex return, translating to newline ++Translate carriage return to newline. May be negated. ++ ++@item iutf8 ++@opindex iutf8 ++@cindex input encoding, UTF-8 ++Assume input characters are UTF-8 encoded. May be negated. ++ ++@item ixon ++@opindex ixon ++@kindex C-s/C-q flow control ++@cindex XON/XOFF flow control ++Enable XON/XOFF flow control (that is, @kbd{CTRL-S}/@kbd{CTRL-Q}). May ++be negated. ++ ++@item ixoff ++@itemx tandem ++@opindex ixoff ++@opindex tandem ++@cindex software flow control ++@cindex flow control, software ++Enable sending of @code{stop} character when the system input buffer ++is almost full, and @code{start} character when it becomes almost ++empty again. May be negated. ++ ++@item iuclc ++@opindex iuclc ++@cindex uppercase, translating to lowercase ++Translate uppercase characters to lowercase. Non-@acronym{POSIX}. May be ++negated. Note ilcuc is not implemented, as one would not be able to issue ++almost any (lowercase) Unix command, after invoking it. ++ ++@item ixany ++@opindex ixany ++Allow any character to restart output (only the start character ++if negated). Non-@acronym{POSIX}. May be negated. ++ ++@item imaxbel ++@opindex imaxbel ++@cindex beeping at input buffer full ++Enable beeping and not flushing input buffer if a character arrives ++when the input buffer is full. Non-@acronym{POSIX}. May be negated. ++@end table ++ ++ ++@node Output ++@subsection Output settings ++ ++@cindex output settings ++These settings control operations on data sent to the terminal. ++ ++@table @samp ++@item opost ++@opindex opost ++Postprocess output. May be negated. ++ ++@item olcuc ++@opindex olcuc ++@cindex lowercase, translating to output ++Translate lowercase characters to uppercase. Non-@acronym{POSIX}. May be ++negated. (Note ouclc is not currently implemented.) ++ ++@item ocrnl ++@opindex ocrnl ++@cindex return, translating to newline ++Translate carriage return to newline. Non-@acronym{POSIX}. May be negated. ++ ++@item onlcr ++@opindex onlcr ++@cindex newline, translating to crlf ++Translate newline to carriage return-newline. Non-@acronym{POSIX}. May be ++negated. ++ ++@item onocr ++@opindex onocr ++Do not print carriage returns in the first column. Non-@acronym{POSIX}. ++May be negated. ++ ++@item onlret ++@opindex onlret ++Newline performs a carriage return. Non-@acronym{POSIX}. May be negated. ++ ++@item ofill ++@opindex ofill ++@cindex pad instead of timing for delaying ++Use fill (padding) characters instead of timing for delays. Non-@acronym{POSIX}. ++May be negated. ++ ++@item ofdel ++@opindex ofdel ++@cindex pad character ++Use @acronym{ASCII} @sc{del} characters for fill instead of ++@acronym{ASCII} @sc{nul} characters. Non-@acronym{POSIX}. ++May be negated. ++ ++@item nl1 ++@itemx nl0 ++@opindex nl@var{n} ++Newline delay style. Non-@acronym{POSIX}. ++ ++@item cr3 ++@itemx cr2 ++@itemx cr1 ++@itemx cr0 ++@opindex cr@var{n} ++Carriage return delay style. Non-@acronym{POSIX}. ++ ++@item tab3 ++@itemx tab2 ++@itemx tab1 ++@itemx tab0 ++@opindex tab@var{n} ++Horizontal tab delay style. Non-@acronym{POSIX}. ++ ++@item bs1 ++@itemx bs0 ++@opindex bs@var{n} ++Backspace delay style. Non-@acronym{POSIX}. ++ ++@item vt1 ++@itemx vt0 ++@opindex vt@var{n} ++Vertical tab delay style. Non-@acronym{POSIX}. ++ ++@item ff1 ++@itemx ff0 ++@opindex ff@var{n} ++Form feed delay style. Non-@acronym{POSIX}. ++@end table ++ ++ ++@node Local ++@subsection Local settings ++ ++@cindex local settings ++ ++@table @samp ++@item isig ++@opindex isig ++Enable @code{interrupt}, @code{quit}, and @code{suspend} special ++characters. May be negated. ++ ++@item icanon ++@opindex icanon ++Enable @code{erase}, @code{kill}, @code{werase}, and @code{rprnt} ++special characters. May be negated. ++ ++@item iexten ++@opindex iexten ++Enable non-@acronym{POSIX} special characters. May be negated. ++ ++@item echo ++@opindex echo ++Echo input characters. May be negated. ++ ++@item echoe ++@itemx crterase ++@opindex echoe ++@opindex crterase ++Echo @code{erase} characters as backspace-space-backspace. May be ++negated. ++ ++@item echok ++@opindex echok ++@cindex newline echoing after @code{kill} ++Echo a newline after a @code{kill} character. May be negated. ++ ++@item echonl ++@opindex echonl ++@cindex newline, echoing ++Echo newline even if not echoing other characters. May be negated. ++ ++@item noflsh ++@opindex noflsh ++@cindex flushing, disabling ++Disable flushing after @code{interrupt} and @code{quit} special ++characters. May be negated. ++ ++@item xcase ++@opindex xcase ++@cindex case translation ++Enable input and output of uppercase characters by preceding their ++lowercase equivalents with @samp{\}, when @code{icanon} is set. ++Non-@acronym{POSIX}. May be negated. ++ ++@item tostop ++@opindex tostop ++@cindex background jobs, stopping at terminal write ++Stop background jobs that try to write to the terminal. Non-@acronym{POSIX}. ++May be negated. ++ ++@item echoprt ++@itemx prterase ++@opindex echoprt ++@opindex prterase ++Echo erased characters backward, between @samp{\} and @samp{/}. ++Non-@acronym{POSIX}. May be negated. ++ ++@item echoctl ++@itemx ctlecho ++@opindex echoctl ++@opindex ctlecho ++@cindex control characters, using @samp{^@var{c}} ++@cindex hat notation for control characters ++Echo control characters in hat notation (@samp{^@var{c}}) instead ++of literally. Non-@acronym{POSIX}. May be negated. ++ ++@item echoke ++@itemx crtkill ++@opindex echoke ++@opindex crtkill ++Echo the @code{kill} special character by erasing each character on ++the line as indicated by the @code{echoprt} and @code{echoe} settings, ++instead of by the @code{echoctl} and @code{echok} settings. Non-@acronym{POSIX}. ++May be negated. ++@end table ++ ++ ++@node Combination ++@subsection Combination settings ++ ++@cindex combination settings ++Combination settings: ++ ++@table @samp ++@item evenp ++@opindex evenp ++@itemx parity ++@opindex parity ++Same as @code{parenb -parodd cs7}. May be negated. If negated, same ++as @code{-parenb cs8}. ++ ++@item oddp ++@opindex oddp ++Same as @code{parenb parodd cs7}. May be negated. If negated, same ++as @code{-parenb cs8}. ++ ++@item nl ++@opindex nl ++Same as @code{-icrnl -onlcr}. May be negated. If negated, same as ++@code{icrnl -inlcr -igncr onlcr -ocrnl -onlret}. ++ ++@item ek ++@opindex ek ++Reset the @code{erase} and @code{kill} special characters to their default ++values. ++ ++@item sane ++@opindex sane ++Same as: ++ ++@c This is too long to write inline. ++@example ++cread -ignbrk brkint -inlcr -igncr icrnl -ixoff ++-iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr ++-onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ++ff0 isig icanon iexten echo echoe echok -echonl ++-noflsh -xcase -tostop -echoprt echoctl echoke ++@end example ++ ++@noindent ++and also sets all special characters to their default values. ++ ++@item cooked ++@opindex cooked ++Same as @code{brkint ignpar istrip icrnl ixon opost isig icanon}, plus ++sets the @code{eof} and @code{eol} characters to their default values ++if they are the same as the @code{min} and @code{time} characters. ++May be negated. If negated, same as @code{raw}. ++ ++@item raw ++@opindex raw ++Same as: ++ ++@example ++-ignbrk -brkint -ignpar -parmrk -inpck -istrip ++-inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany ++-imaxbel -opost -isig -icanon -xcase min 1 time 0 ++@end example ++ ++@noindent ++May be negated. If negated, same as @code{cooked}. ++ ++@item cbreak ++@opindex cbreak ++Same as @option{-icanon}. May be negated. If negated, same as ++@code{icanon}. ++ ++@item pass8 ++@opindex pass8 ++@cindex eight-bit characters ++Same as @code{-parenb -istrip cs8}. May be negated. If negated, ++same as @code{parenb istrip cs7}. ++ ++@item litout ++@opindex litout ++Same as @option{-parenb -istrip -opost cs8}. May be negated. ++If negated, same as @code{parenb istrip opost cs7}. ++ ++@item decctlq ++@opindex decctlq ++Same as @option{-ixany}. Non-@acronym{POSIX}. May be negated. ++ ++@item tabs ++@opindex tabs ++Same as @code{tab0}. Non-@acronym{POSIX}. May be negated. If negated, same ++as @code{tab3}. ++ ++@item lcase ++@itemx LCASE ++@opindex lcase ++@opindex LCASE ++Same as @code{xcase iuclc olcuc}. Non-@acronym{POSIX}. May be negated. ++(Used for terminals with uppercase characters only.) ++ ++@item crt ++@opindex crt ++Same as @code{echoe echoctl echoke}. ++ ++@item dec ++@opindex dec ++Same as @code{echoe echoctl echoke -ixany intr ^C erase ^? kill C-u}. ++@end table ++ ++ ++@node Characters ++@subsection Special characters ++ ++@cindex special characters ++@cindex characters, special ++ ++The special characters' default values vary from system to system. ++They are set with the syntax @samp{name value}, where the names are ++listed below and the value can be given either literally, in hat ++notation (@samp{^@var{c}}), or as an integer which may start with ++@samp{0x} to indicate hexadecimal, @samp{0} to indicate octal, or ++any other digit to indicate decimal. ++ ++@cindex disabling special characters ++@kindex u@r{, and disabling special characters} ++For GNU stty, giving a value of @code{^-} or @code{undef} disables that ++special character. (This is incompatible with Ultrix @command{stty}, ++which uses a value of @samp{u} to disable a special character. GNU ++@command{stty} treats a value @samp{u} like any other, namely to set that ++special character to @key{U}.) ++ ++@table @samp ++ ++@item intr ++@opindex intr ++Send an interrupt signal. ++ ++@item quit ++@opindex quit ++Send a quit signal. ++ ++@item erase ++@opindex erase ++Erase the last character typed. ++ ++@item kill ++@opindex kill ++Erase the current line. ++ ++@item eof ++@opindex eof ++Send an end of file (terminate the input). ++ ++@item eol ++@opindex eol ++End the line. ++ ++@item eol2 ++@opindex eol2 ++Alternate character to end the line. Non-@acronym{POSIX}. ++ ++@item swtch ++@opindex swtch ++Switch to a different shell layer. Non-@acronym{POSIX}. ++ ++@item start ++@opindex start ++Restart the output after stopping it. ++ ++@item stop ++@opindex stop ++Stop the output. ++ ++@item susp ++@opindex susp ++Send a terminal stop signal. ++ ++@item dsusp ++@opindex dsusp ++Send a terminal stop signal after flushing the input. Non-@acronym{POSIX}. ++ ++@item rprnt ++@opindex rprnt ++Redraw the current line. Non-@acronym{POSIX}. ++ ++@item werase ++@opindex werase ++Erase the last word typed. Non-@acronym{POSIX}. ++ ++@item lnext ++@opindex lnext ++Enter the next character typed literally, even if it is a special ++character. Non-@acronym{POSIX}. ++@end table ++ ++ ++@node Special ++@subsection Special settings ++ ++@cindex special settings ++ ++@table @samp ++@item min @var{n} ++@opindex min ++Set the minimum number of characters that will satisfy a read until ++the time value has expired, when @option{-icanon} is set. ++ ++@item time @var{n} ++@opindex time ++Set the number of tenths of a second before reads time out if the minimum ++number of characters have not been read, when @option{-icanon} is set. ++ ++@item ispeed @var{n} ++@opindex ispeed ++Set the input speed to @var{n}. ++ ++@item ospeed @var{n} ++@opindex ospeed ++Set the output speed to @var{n}. ++ ++@item rows @var{n} ++@opindex rows ++Tell the tty kernel driver that the terminal has @var{n} rows. Non-@acronym{POSIX}. ++ ++@item cols @var{n} ++@itemx columns @var{n} ++@opindex cols ++@opindex columns ++Tell the kernel that the terminal has @var{n} columns. Non-@acronym{POSIX}. ++ ++@item size ++@opindex size ++@vindex LINES ++@vindex COLUMNS ++Print the number of rows and columns that the kernel thinks the ++terminal has. (Systems that don't support rows and columns in the kernel ++typically use the environment variables @env{LINES} and @env{COLUMNS} ++instead; however, GNU @command{stty} does not know anything about them.) ++Non-@acronym{POSIX}. ++ ++@item line @var{n} ++@opindex line ++Use line discipline @var{n}. Non-@acronym{POSIX}. ++ ++@item speed ++@opindex speed ++Print the terminal speed. ++ ++@item @var{n} ++@cindex baud rate, setting ++Set the input and output speeds to @var{n}. @var{n} can be one of: 0 ++50 75 110 134 134.5 150 200 300 600 1200 1800 2400 4800 9600 19200 ++38400 @code{exta} @code{extb}. @code{exta} is the same as 19200; ++@code{extb} is the same as 38400. Many systems, including GNU/Linux, ++support higher speeds. The @command{stty} command includes support ++for speeds of ++57600, ++115200, ++230400, ++460800, ++500000, ++576000, ++921600, ++1000000, ++1152000, ++1500000, ++2000000, ++2500000, ++3000000, ++3500000, ++or ++4000000 where the system supports these. ++0 hangs up the line if @option{-clocal} is set. ++@end table ++ ++ ++@node printenv invocation ++@section @command{printenv}: Print all or some environment variables ++ ++@pindex printenv ++@cindex printing all or some environment variables ++@cindex environment variables, printing ++ ++@command{printenv} prints environment variable values. Synopsis: ++ ++@example ++printenv [@var{option}] [@var{variable}]@dots{} ++@end example ++ ++If no @var{variable}s are specified, @command{printenv} prints the value of ++every environment variable. Otherwise, it prints the value of each ++@var{variable} that is set, and nothing for those that are not set. ++ ++The only options are a lone @option{--help} or @option{--version}. ++@xref{Common options}. ++ ++@cindex exit status of @command{printenv} ++Exit status: ++ ++@display ++0 if all variables specified were found ++1 if at least one specified variable was not found ++2 if a write error occurred ++@end display ++ ++ ++@node tty invocation ++@section @command{tty}: Print file name of terminal on standard input ++ ++@pindex tty ++@cindex print terminal file name ++@cindex terminal file name, printing ++ ++@command{tty} prints the file name of the terminal connected to its standard ++input. It prints @samp{not a tty} if standard input is not a terminal. ++Synopsis: ++ ++@example ++tty [@var{option}]@dots{} ++@end example ++ ++The program accepts the following option. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -s ++@itemx --silent ++@itemx --quiet ++@opindex -s ++@opindex --silent ++@opindex --quiet ++Print nothing; only return an exit status. ++ ++@end table ++ ++@cindex exit status of @command{tty} ++Exit status: ++ ++@display ++0 if standard input is a terminal ++1 if standard input is not a terminal ++2 if given incorrect arguments ++3 if a write error occurs ++@end display ++ ++ ++@node User information ++@chapter User information ++ ++@cindex user information, commands for ++@cindex commands for printing user information ++ ++This section describes commands that print user-related information: ++logins, groups, and so forth. ++ ++@menu ++* id invocation:: Print user identity. ++* logname invocation:: Print current login name. ++* whoami invocation:: Print effective user ID. ++* groups invocation:: Print group names a user is in. ++* users invocation:: Print login names of users currently logged in. ++* who invocation:: Print who is currently logged in. ++@end menu ++ ++ ++@node id invocation ++@section @command{id}: Print user identity ++ ++@pindex id ++@cindex real user and group IDs, printing ++@cindex effective user and group IDs, printing ++@cindex printing real and effective user and group IDs ++ ++@command{id} prints information about the given user, or the process ++running it if no user is specified. Synopsis: ++ ++@example ++id [@var{option}]@dots{} [@var{username}] ++@end example ++ ++@vindex POSIXLY_CORRECT ++By default, it prints the real user ID, real group ID, effective user ID ++if different from the real user ID, effective group ID if different from ++the real group ID, and supplemental group IDs. ++In addition, if SELinux ++is enabled and the @env{POSIXLY_CORRECT} environment variable is not set, ++then print @samp{context=@var{c}}, where @var{c} is the security context. ++ ++Each of these numeric values is preceded by an identifying string and ++followed by the corresponding user or group name in parentheses. ++ ++The options cause @command{id} to print only part of the above information. ++Also see @ref{Common options}. ++ ++@table @samp ++@item -g ++@itemx --group ++@opindex -g ++@opindex --group ++Print only the group ID. ++ ++@item -G ++@itemx --groups ++@opindex -G ++@opindex --groups ++Print only the group ID and the supplementary groups. ++ ++@item -n ++@itemx --name ++@opindex -n ++@opindex --name ++Print the user or group name instead of the ID number. Requires ++@option{-u}, @option{-g}, or @option{-G}. ++ ++@item -r ++@itemx --real ++@opindex -r ++@opindex --real ++Print the real, instead of effective, user or group ID. Requires ++@option{-u}, @option{-g}, or @option{-G}. ++ ++@item -u ++@itemx --user ++@opindex -u ++@opindex --user ++Print only the user ID. ++ ++@item -Z ++@itemx --context ++@opindex -Z ++@opindex --context ++@cindex SELinux ++@cindex security context ++Print only the security context of the current user. ++If SELinux is disabled then print a warning and ++set the exit status to 1. ++ ++@end table ++ ++@exitstatus ++ ++@macro primaryAndSupplementaryGroups{cmd,arg} ++Primary and supplementary groups for a process are normally inherited ++from its parent and are usually unchanged since login. This means ++that if you change the group database after logging in, @command{\cmd\} ++will not reflect your changes within your existing login session. ++Running @command{\cmd\} with a \arg\ causes the user and group ++database to be consulted afresh, and so will give a different result. ++@end macro ++@primaryAndSupplementaryGroups{id,user argument} ++ ++@node logname invocation ++@section @command{logname}: Print current login name ++ ++@pindex logname ++@cindex printing user's login name ++@cindex login name, printing ++@cindex user name, printing ++ ++@flindex utmp ++@command{logname} prints the calling user's name, as found in a ++system-maintained file (often @file{/var/run/utmp} or ++@file{/etc/utmp}), and exits with a status of 0. If there is no entry ++for the calling process, @command{logname} prints ++an error message and exits with a status of 1. ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. ++ ++@exitstatus ++ ++ ++@node whoami invocation ++@section @command{whoami}: Print effective user ID ++ ++@pindex whoami ++@cindex effective user ID, printing ++@cindex printing the effective user ID ++ ++@command{whoami} prints the user name associated with the current ++effective user ID. It is equivalent to the command @samp{id -un}. ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. ++ ++@exitstatus ++ ++ ++@node groups invocation ++@section @command{groups}: Print group names a user is in ++ ++@pindex groups ++@cindex printing groups a user is in ++@cindex supplementary groups, printing ++ ++@command{groups} prints the names of the primary and any supplementary ++groups for each given @var{username}, or the current process if no names ++are given. If more than one name is given, the name of each user is ++printed before ++the list of that user's groups and the user name is separated from the ++group list by a colon. Synopsis: ++ ++@example ++groups [@var{username}]@dots{} ++@end example ++ ++The group lists are equivalent to the output of the command @samp{id -Gn}. ++ ++@primaryAndSupplementaryGroups{groups,list of users} ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. ++ ++@exitstatus ++ ++ ++@node users invocation ++@section @command{users}: Print login names of users currently logged in ++ ++@pindex users ++@cindex printing current usernames ++@cindex usernames, printing current ++ ++@cindex login sessions, printing users with ++@command{users} prints on a single line a blank-separated list of user ++names of users currently logged in to the current host. Each user name ++corresponds to a login session, so if a user has more than one login ++session, that user's name will appear the same number of times in the ++output. Synopsis: ++ ++@example ++users [@var{file}] ++@end example ++ ++@flindex utmp ++@flindex wtmp ++With no @var{file} argument, @command{users} extracts its information from ++a system-maintained file (often @file{/var/run/utmp} or ++@file{/etc/utmp}). If a file argument is given, @command{users} uses ++that file instead. A common choice is @file{/var/log/wtmp}. ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. ++ ++@exitstatus ++ ++ ++@node who invocation ++@section @command{who}: Print who is currently logged in ++ ++@pindex who ++@cindex printing current user information ++@cindex information, about current users ++ ++@command{who} prints information about users who are currently logged on. ++Synopsis: ++ ++@example ++@command{who} [@var{option}] [@var{file}] [am i] ++@end example ++ ++@cindex terminal lines, currently used ++@cindex login time ++@cindex remote hostname ++If given no non-option arguments, @command{who} prints the following ++information for each user currently logged on: login name, terminal ++line, login time, and remote hostname or X display. ++ ++@flindex utmp ++@flindex wtmp ++If given one non-option argument, @command{who} uses that instead of ++a default system-maintained file (often @file{/var/run/utmp} or ++@file{/etc/utmp}) as the name of the file containing the record of ++users logged on. @file{/var/log/wtmp} is commonly given as an argument ++to @command{who} to look at who has previously logged on. ++ ++@opindex am i ++@opindex who am i ++If given two non-option arguments, @command{who} prints only the entry ++for the user running it (determined from its standard input), preceded ++by the hostname. Traditionally, the two arguments given are @samp{am ++i}, as in @samp{who am i}. ++ ++@vindex TZ ++Time stamps are listed according to the time zone rules specified by ++the @env{TZ} environment variable, or by the system default rules if ++@env{TZ} is not set. @xref{TZ Variable,, Specifying the Time Zone ++with @env{TZ}, libc, The GNU C Library Reference Manual}. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -a ++@itemx --all ++@opindex -a ++@opindex --all ++Same as @samp{-b -d --login -p -r -t -T -u}. ++ ++@item -b ++@itemx --boot ++@opindex -b ++@opindex --boot ++Print the date and time of last system boot. ++ ++@item -d ++@itemx --dead ++@opindex -d ++@opindex --dead ++Print information corresponding to dead processes. ++ ++@item -H ++@itemx --heading ++@opindex -H ++@opindex --heading ++Print a line of column headings. ++ ++@item -l ++@itemx --login ++@opindex -l ++@opindex --login ++List only the entries that correspond to processes via which the ++system is waiting for a user to login. The user name is always @samp{LOGIN}. ++ ++@itemx --lookup ++@opindex --lookup ++Attempt to canonicalize hostnames found in utmp through a DNS lookup. This ++is not the default because it can cause significant delays on systems with ++automatic dial-up internet access. ++ ++@item -m ++@opindex -m ++Same as @samp{who am i}. ++ ++@item -p ++@itemx --process ++@opindex -p ++@opindex --process ++List active processes spawned by init. ++ ++@item -q ++@itemx --count ++@opindex -q ++@opindex --count ++Print only the login names and the number of users logged on. ++Overrides all other options. ++ ++@item -r ++@itemx --runlevel ++@opindex -r ++@opindex --runlevel ++Print the current (and maybe previous) run-level of the init process. ++ ++@item -s ++@opindex -s ++Ignored; for compatibility with other versions of @command{who}. ++ ++@item -t ++@itemx --time ++@opindex -t ++@opindex --time ++Print last system clock change. ++ ++@itemx -u ++@opindex -u ++@cindex idle time ++After the login time, print the number of hours and minutes that the ++user has been idle. @samp{.} means the user was active in the last minute. ++@samp{old} means the user has been idle for more than 24 hours. ++ ++@item -w ++@itemx -T ++@itemx --mesg ++@itemx --message ++@itemx --writable ++@opindex -w ++@opindex -T ++@opindex --mesg ++@opindex --message ++@opindex --writable ++@cindex message status ++@pindex write@r{, allowed} ++After each login name print a character indicating the user's message status: ++ ++@display ++@samp{+} allowing @code{write} messages ++@samp{-} disallowing @code{write} messages ++@samp{?} cannot find terminal device ++@end display ++ ++@end table ++ ++@exitstatus ++ ++ ++@node System context ++@chapter System context ++ ++@cindex system context ++@cindex context, system ++@cindex commands for system context ++ ++This section describes commands that print or change system-wide ++information. ++ ++@menu ++* date invocation:: Print or set system date and time. ++* arch invocation:: Print machine hardware name. ++* 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 ++ ++@node date invocation ++@section @command{date}: Print or set system date and time ++ ++@pindex date ++@cindex time, printing or setting ++@cindex printing the current time ++ ++Synopses: ++ ++@example ++date [@var{option}]@dots{} [+@var{format}] ++date [-u|--utc|--universal] @c this avoids a newline in the output ++[ MMDDhhmm[[CC]YY][.ss] ] ++@end example ++ ++@vindex LC_TIME ++Invoking @command{date} with no @var{format} argument is equivalent to invoking ++it with a default format that depends on the @env{LC_TIME} locale category. ++In the default C locale, this format is @samp{'+%a %b %e %H:%M:%S %Z %Y'}, ++so the output looks like @samp{Thu Mar @ 3 13:47:51 PST 2005}. ++ ++@vindex TZ ++Normally, @command{date} uses the time zone rules indicated by the ++@env{TZ} environment variable, or the system default rules if @env{TZ} ++is not set. @xref{TZ Variable,, Specifying the Time Zone with ++@env{TZ}, libc, The GNU C Library Reference Manual}. ++ ++@findex strftime @r{and @command{date}} ++@cindex time formats ++@cindex formatting times ++If given an argument that starts with a @samp{+}, @command{date} prints the ++current date and time (or the date and time specified by the ++@option{--date} option, see below) in the format defined by that argument, ++which is similar to that of the @code{strftime} function. Except for ++conversion specifiers, which start with @samp{%}, characters in the ++format string are printed unchanged. The conversion specifiers are ++described below. ++ ++@exitstatus ++ ++@menu ++* Time conversion specifiers:: %[HIklMNpPrRsSTXzZ] ++* Date conversion specifiers:: %[aAbBcCdDeFgGhjmuUVwWxyY] ++* Literal conversion specifiers:: %[%nt] ++* Padding and other flags:: Pad with zeros, spaces, etc. ++* Setting the time:: Changing the system clock. ++* Options for date:: Instead of the current time. ++@detailmenu ++* Date input formats:: Specifying date strings. ++@end detailmenu ++* Examples of date:: Examples. ++@end menu ++ ++@node Time conversion specifiers ++@subsection Time conversion specifiers ++ ++@cindex time conversion specifiers ++@cindex conversion specifiers, time ++ ++@command{date} conversion specifiers related to times. ++ ++@table @samp ++@item %H ++hour (@samp{00}@dots{}@samp{23}) ++@item %I ++hour (@samp{01}@dots{}@samp{12}) ++@item %k ++hour (@samp{ 0}@dots{}@samp{23}). ++This is a @acronym{GNU} extension. ++@item %l ++hour (@samp{ 1}@dots{}@samp{12}). ++This is a @acronym{GNU} extension. ++@item %M ++minute (@samp{00}@dots{}@samp{59}) ++@item %N ++nanoseconds (@samp{000000000}@dots{}@samp{999999999}). ++This is a @acronym{GNU} extension. ++@item %p ++locale's equivalent of either @samp{AM} or @samp{PM}; ++blank in many locales. ++Noon is treated as @samp{PM} and midnight as @samp{AM}. ++@item %P ++like @samp{%p}, except lower case. ++This is a @acronym{GNU} extension. ++@item %r ++locale's 12-hour clock time (e.g., @samp{11:11:04 PM}) ++@item %R ++24-hour hour and minute. Same as @samp{%H:%M}. ++This is a @acronym{GNU} extension. ++@item %s ++@cindex epoch, seconds since ++@cindex seconds since the epoch ++@cindex beginning of time ++seconds since the epoch, i.e., since 1970-01-01 00:00:00 UTC. ++Leap seconds are not counted unless leap second support is available. ++@xref{%s-examples}, for examples. ++This is a @acronym{GNU} extension. ++@item %S ++second (@samp{00}@dots{}@samp{60}). ++This may be @samp{60} if leap seconds are supported. ++@item %T ++24-hour hour, minute, and second. Same as @samp{%H:%M:%S}. ++@item %X ++locale's time representation (e.g., @samp{23:13:48}) ++@item %z ++@w{@acronym{RFC} 2822/@acronym{ISO} 8601} style numeric time zone ++(e.g., @samp{-0600} or @samp{+0530}), or nothing if no ++time zone is determinable. This value reflects the numeric time zone ++appropriate for the current time, using the time zone rules specified ++by the @env{TZ} environment variable. ++The time (and optionally, the time zone rules) can be overridden ++by the @option{--date} option. ++This is a @acronym{GNU} extension. ++@item %:z ++@w{@acronym{RFC} 3339/@acronym{ISO} 8601} style numeric time zone with ++@samp{:} (e.g., @samp{-06:00} or @samp{+05:30}), or nothing if no time ++zone is determinable. ++This is a @acronym{GNU} extension. ++@item %::z ++Numeric time zone to the nearest second with @samp{:} (e.g., ++@samp{-06:00:00} or @samp{+05:30:00}), or nothing if no time zone is ++determinable. ++This is a @acronym{GNU} extension. ++@item %:::z ++Numeric time zone with @samp{:} using the minimum necessary precision ++(e.g., @samp{-06}, @samp{+05:30}, or @samp{-04:56:02}), or nothing if ++no time zone is determinable. ++This is a @acronym{GNU} extension. ++@item %Z ++alphabetic time zone abbreviation (e.g., @samp{EDT}), or nothing if no ++time zone is determinable. See @samp{%z} for how it is determined. ++@end table ++ ++ ++@node Date conversion specifiers ++@subsection Date conversion specifiers ++ ++@cindex date conversion specifiers ++@cindex conversion specifiers, date ++ ++@command{date} conversion specifiers related to dates. ++ ++@table @samp ++@item %a ++locale's abbreviated weekday name (e.g., @samp{Sun}) ++@item %A ++locale's full weekday name, variable length (e.g., @samp{Sunday}) ++@item %b ++locale's abbreviated month name (e.g., @samp{Jan}) ++@item %B ++locale's full month name, variable length (e.g., @samp{January}) ++@item %c ++locale's date and time (e.g., @samp{Thu Mar @ 3 23:05:25 2005}) ++@item %C ++century. This is like @samp{%Y}, except the last two digits are omitted. ++For example, it is @samp{20} if @samp{%Y} is @samp{2000}, ++and is @samp{-0} if @samp{%Y} is @samp{-001}. ++It is normally at least two characters, but it may be more. ++@item %d ++day of month (e.g., @samp{01}) ++@item %D ++date; same as @samp{%m/%d/%y} ++@item %e ++day of month, space padded; same as @samp{%_d} ++@item %F ++full date in @acronym{ISO} 8601 format; same as @samp{%Y-%m-%d}. ++This is a good choice for a date format, as it is standard and ++is easy to sort in the usual case where years are in the range ++0000@dots{}9999. ++This is a @acronym{GNU} extension. ++@item %g ++year corresponding to the @acronym{ISO} week number, but without the century ++(range @samp{00} through @samp{99}). This has the same format and value ++as @samp{%y}, except that if the @acronym{ISO} week number (see ++@samp{%V}) belongs ++to the previous or next year, that year is used instead. ++This is a @acronym{GNU} extension. ++@item %G ++year corresponding to the @acronym{ISO} week number. This has the ++same format and value as @samp{%Y}, except that if the @acronym{ISO} ++week number (see ++@samp{%V}) belongs to the previous or next year, that year is used ++instead. ++It is normally useful only if @samp{%V} is also used; ++for example, the format @samp{%G-%m-%d} is probably a mistake, ++since it combines the ISO week number year with the conventional month and day. ++This is a @acronym{GNU} extension. ++@item %h ++same as @samp{%b} ++@item %j ++day of year (@samp{001}@dots{}@samp{366}) ++@item %m ++month (@samp{01}@dots{}@samp{12}) ++@item %u ++day of week (@samp{1}@dots{}@samp{7}) with @samp{1} corresponding to Monday ++@item %U ++week number of year, with Sunday as the first day of the week ++(@samp{00}@dots{}@samp{53}). ++Days in a new year preceding the first Sunday are in week zero. ++@item %V ++@acronym{ISO} week number, that is, the ++week number of year, with Monday as the first day of the week ++(@samp{01}@dots{}@samp{53}). ++If the week containing January 1 has four or more days in ++the new year, then it is considered week 1; otherwise, it is week 53 of ++the previous year, and the next week is week 1. (See the @acronym{ISO} 8601 ++standard.) ++@item %w ++day of week (@samp{0}@dots{}@samp{6}) with 0 corresponding to Sunday ++@item %W ++week number of year, with Monday as first day of week ++(@samp{00}@dots{}@samp{53}). ++Days in a new year preceding the first Monday are in week zero. ++@item %x ++locale's date representation (e.g., @samp{12/31/99}) ++@item %y ++last two digits of year (@samp{00}@dots{}@samp{99}) ++@item %Y ++year. This is normally at least four characters, but it may be more. ++Year @samp{0000} precedes year @samp{0001}, and year @samp{-001} ++precedes year @samp{0000}. ++@end table ++ ++ ++@node Literal conversion specifiers ++@subsection Literal conversion specifiers ++ ++@cindex literal conversion specifiers ++@cindex conversion specifiers, literal ++ ++@command{date} conversion specifiers that produce literal strings. ++ ++@table @samp ++@item %% ++a literal % ++@item %n ++a newline ++@item %t ++a horizontal tab ++@end table ++ ++ ++@node Padding and other flags ++@subsection Padding and other flags ++ ++@cindex numeric field padding ++@cindex padding of numeric fields ++@cindex fields, padding numeric ++ ++Unless otherwise specified, @command{date} normally pads numeric fields ++with zeros, so that, for ++example, numeric months are always output as two digits. ++Seconds since the epoch are not padded, though, ++since there is no natural width for them. ++ ++As a @acronym{GNU} extension, @command{date} recognizes any of the ++following optional flags after the @samp{%}: ++ ++@table @samp ++@item - ++(hyphen) Do not pad the field; useful if the output is intended for ++human consumption. ++@item _ ++(underscore) Pad with spaces; useful if you need a fixed ++number of characters in the output, but zeros are too distracting. ++@item 0 ++(zero) Pad with zeros even if the conversion specifier ++would normally pad with spaces. ++@item ^ ++Use upper case characters if possible. ++@item # ++Use opposite case characters if possible. ++A field that is normally upper case becomes lower case, and vice versa. ++@end table ++ ++@noindent ++Here are some examples of padding: ++ ++@example ++date +%d/%m -d "Feb 1" ++@result{} 01/02 ++date +%-d/%-m -d "Feb 1" ++@result{} 1/2 ++date +%_d/%_m -d "Feb 1" ++@result{} 1/ 2 ++@end example ++ ++As a @acronym{GNU} extension, you can specify the field width ++(after any flag, if present) as a decimal number. If the natural size of the ++output of the field has less than the specified number of characters, ++the result is written right adjusted and padded to the given ++size. For example, @samp{%9B} prints the right adjusted month name in ++a field of width 9. ++ ++An optional modifier can follow the optional flag and width ++specification. The modifiers are: ++ ++@table @samp ++@item E ++Use the locale's alternate representation for date and time. This ++modifier applies to the @samp{%c}, @samp{%C}, @samp{%x}, @samp{%X}, ++@samp{%y} and @samp{%Y} conversion specifiers. In a Japanese locale, for ++example, @samp{%Ex} might yield a date format based on the Japanese ++Emperors' reigns. ++ ++@item O ++Use the locale's alternate numeric symbols for numbers. This modifier ++applies only to numeric conversion specifiers. ++@end table ++ ++If the format supports the modifier but no alternate representation ++is available, it is ignored. ++ ++ ++@node Setting the time ++@subsection Setting the time ++ ++@cindex setting the time ++@cindex time setting ++@cindex appropriate privileges ++ ++If given an argument that does not start with @samp{+}, @command{date} sets ++the system clock to the date and time specified by that argument (as ++described below). You must have appropriate privileges to set the ++system clock. The @option{--date} and @option{--set} options may not be ++used with such an argument. The @option{--universal} option may be used ++with such an argument to indicate that the specified date and time are ++relative to Coordinated Universal Time rather than to the local time ++zone. ++ ++The argument must consist entirely of digits, which have the following ++meaning: ++ ++@table @samp ++@item MM ++month ++@item DD ++day within month ++@item hh ++hour ++@item mm ++minute ++@item CC ++first two digits of year (optional) ++@item YY ++last two digits of year (optional) ++@item ss ++second (optional) ++@end table ++ ++The @option{--set} option also sets the system clock; see the next section. ++ ++ ++@node Options for date ++@subsection Options for @command{date} ++ ++@cindex @command{date} options ++@cindex options for @command{date} ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -d @var{datestr} ++@itemx --date=@var{datestr} ++@opindex -d ++@opindex --date ++@cindex parsing date strings ++@cindex date strings, parsing ++@cindex arbitrary date strings, parsing ++@opindex yesterday ++@opindex tomorrow ++@opindex next @var{day} ++@opindex last @var{day} ++Display the date and time specified in @var{datestr} instead of the ++current date and time. @var{datestr} can be in almost any common ++format. It can contain month names, time zones, @samp{am} and @samp{pm}, ++@samp{yesterday}, etc. For example, @option{--date="2004-02-27 ++14:19:13.489392193 +0530"} specifies the instant of time that is ++489,392,193 nanoseconds after February 27, 2004 at 2:19:13 PM in a ++time zone that is 5 hours and 30 minutes east of @acronym{UTC}.@* ++Note: input currently must be in locale independent format. E.g., the ++LC_TIME=C below is needed to print back the correct date in many locales: ++@example ++date -d "$(LC_TIME=C date)" ++@end example ++@xref{Date input formats}. ++ ++@item -f @var{datefile} ++@itemx --file=@var{datefile} ++@opindex -f ++@opindex --file ++Parse each line in @var{datefile} as with @option{-d} and display the ++resulting date and time. If @var{datefile} is @samp{-}, use standard ++input. This is useful when you have many dates to process, because the ++system overhead of starting up the @command{date} executable many times can ++be considerable. ++ ++@item -r @var{file} ++@itemx --reference=@var{file} ++@opindex -r ++@opindex --reference ++Display the date and time of the last modification of @var{file}, ++instead of the current date and time. ++ ++@item -R ++@itemx --rfc-822 ++@itemx --rfc-2822 ++@opindex -R ++@opindex --rfc-822 ++@opindex --rfc-2822 ++Display the date and time using the format @samp{%a, %d %b %Y %H:%M:%S ++%z}, evaluated in the C locale so abbreviations are always in English. ++For example: ++ ++@example ++Fri, 09 Sep 2005 13:51:39 -0700 ++@end example ++ ++This format conforms to ++@uref{ftp://ftp.rfc-editor.org/in-notes/rfc2822.txt, Internet ++@acronym{RFCs} 2822} and ++@uref{ftp://ftp.rfc-editor.org/in-notes/rfc822.txt, 822}, the ++current and previous standards for Internet email. ++ ++@item --rfc-3339=@var{timespec} ++@opindex --rfc-3339=@var{timespec} ++Display the date using a format specified by ++@uref{ftp://ftp.rfc-editor.org/in-notes/rfc3339.txt, Internet ++@acronym{RFC} 3339}. This is a subset of the @acronym{ISO} 8601 ++format, except that it also permits applications to use a space rather ++than a @samp{T} to separate dates from times. Unlike the other ++standard formats, @acronym{RFC} 3339 format is always suitable as ++input for the @option{--date} (@option{-d}) and @option{--file} ++(@option{-f}) options, regardless of the current locale. ++ ++The argument @var{timespec} specifies how much of the time to include. ++It can be one of the following: ++ ++@table @samp ++@item date ++Print just the full-date, e.g., @samp{2005-09-14}. ++This is equivalent to the format @samp{%Y-%m-%d}. ++ ++@item seconds ++Print the full-date and full-time separated by a space, e.g., ++@samp{2005-09-14 00:56:06+05:30}. The output ends with a numeric ++time-offset; here the @samp{+05:30} means that local time is five ++hours and thirty minutes east of @acronym{UTC}. This is equivalent to ++the format @samp{%Y-%m-%d %H:%M:%S%:z}. ++ ++@item ns ++Like @samp{seconds}, but also print nanoseconds, e.g., ++@samp{2005-09-14 00:56:06.998458565+05:30}. ++This is equivalent to the format @samp{%Y-%m-%d %H:%M:%S.%N%:z}. ++ ++@end table ++ ++@item -s @var{datestr} ++@itemx --set=@var{datestr} ++@opindex -s ++@opindex --set ++Set the date and time to @var{datestr}. See @option{-d} above. ++ ++@item -u ++@itemx --utc ++@itemx --universal ++@opindex -u ++@opindex --utc ++@opindex --universal ++@cindex Coordinated Universal Time ++@cindex UTC ++@cindex Greenwich Mean Time ++@cindex GMT ++@vindex TZ ++Use Coordinated Universal Time (@acronym{UTC}) by operating as if the ++@env{TZ} environment variable were set to the string @samp{UTC0}. ++Coordinated ++Universal Time is often called ``Greenwich Mean Time'' (@sc{gmt}) for ++historical reasons. ++@end table ++ ++ ++@node Examples of date ++@subsection Examples of @command{date} ++ ++@cindex examples of @command{date} ++ ++Here are a few examples. Also see the documentation for the @option{-d} ++option in the previous section. ++ ++@itemize @bullet ++ ++@item ++To print the date of the day before yesterday: ++ ++@example ++date --date='2 days ago' ++@end example ++ ++@item ++To print the date of the day three months and one day hence: ++ ++@example ++date --date='3 months 1 day' ++@end example ++ ++@item ++To print the day of year of Christmas in the current year: ++ ++@example ++date --date='25 Dec' +%j ++@end example ++ ++@item ++To print the current full month name and the day of the month: ++ ++@example ++date '+%B %d' ++@end example ++ ++But this may not be what you want because for the first nine days of ++the month, the @samp{%d} expands to a zero-padded two-digit field, ++for example @samp{date -d 1may '+%B %d'} will print @samp{May 01}. ++ ++@item ++To print a date without the leading zero for one-digit days ++of the month, you can use the (@acronym{GNU} extension) ++@samp{-} flag to suppress ++the padding altogether: ++ ++@example ++date -d 1may '+%B %-d ++@end example ++ ++@item ++To print the current date and time in the format required by many ++non-@acronym{GNU} versions of @command{date} when setting the system clock: ++ ++@example ++date +%m%d%H%M%Y.%S ++@end example ++ ++@item ++To set the system clock forward by two minutes: ++ ++@example ++date --set='+2 minutes' ++@end example ++ ++@item ++To print the date in @acronym{RFC} 2822 format, ++use @samp{date --rfc-2822}. Here is some example output: ++ ++@example ++Fri, 09 Sep 2005 13:51:39 -0700 ++@end example ++ ++@anchor{%s-examples} ++@item ++To convert a date string to the number of seconds since the epoch ++(which is 1970-01-01 00:00:00 UTC), use the @option{--date} option with ++the @samp{%s} format. That can be useful in sorting and/or graphing ++and/or comparing data by date. The following command outputs the ++number of the seconds since the epoch for the time two minutes after the ++epoch: ++ ++@example ++date --date='1970-01-01 00:02:00 +0000' +%s ++120 ++@end example ++ ++If you do not specify time zone information in the date string, ++@command{date} uses your computer's idea of the time zone when ++interpreting the string. For example, if your computer's time zone is ++that of Cambridge, Massachusetts, which was then 5 hours (i.e., 18,000 ++seconds) behind UTC: ++ ++@example ++# local time zone used ++date --date='1970-01-01 00:02:00' +%s ++18120 ++@end example ++ ++@item ++If you're sorting or graphing dated data, your raw date values may be ++represented as seconds since the epoch. But few people can look at ++the date @samp{946684800} and casually note ``Oh, that's the first second ++of the year 2000 in Greenwich, England.'' ++ ++@example ++date --date='2000-01-01 UTC' +%s ++946684800 ++@end example ++ ++An alternative is to use the @option{--utc} (@option{-u}) option. ++Then you may omit @samp{UTC} from the date string. Although this ++produces the same result for @samp{%s} and many other format sequences, ++with a time zone offset different from zero, it would give a different ++result for zone-dependent formats like @samp{%z}. ++ ++@example ++date -u --date=2000-01-01 +%s ++946684800 ++@end example ++ ++To convert such an unwieldy number of seconds back to ++a more readable form, use a command like this: ++ ++@smallexample ++# local time zone used ++date -d '1970-01-01 UTC 946684800 seconds' +"%Y-%m-%d %T %z" ++1999-12-31 19:00:00 -0500 ++@end smallexample ++ ++Or if you do not mind depending on the @samp{@@} feature present since ++coreutils 5.3.0, you could shorten this to: ++ ++@smallexample ++date -d @@946684800 +"%F %T %z" ++1999-12-31 19:00:00 -0500 ++@end smallexample ++ ++Often it is better to output UTC-relative date and time: ++ ++@smallexample ++date -u -d '1970-01-01 946684800 seconds' +"%Y-%m-%d %T %z" ++2000-01-01 00:00:00 +0000 ++@end smallexample ++ ++@end itemize ++ ++ ++@node arch invocation ++@section @command{arch}: Print machine hardware name ++ ++@pindex arch ++@cindex print machine hardware name ++@cindex system information, printing ++ ++@command{arch} prints the machine hardware name, ++and is equivalent to @samp{uname -m}. ++Synopsis: ++ ++@example ++arch [@var{option}] ++@end example ++ ++The program accepts the @ref{Common options} only. ++ ++@exitstatus ++ ++ ++@node uname invocation ++@section @command{uname}: Print system information ++ ++@pindex uname ++@cindex print system information ++@cindex system information, printing ++ ++@command{uname} prints information about the machine and operating system ++it is run on. If no options are given, @command{uname} acts as if the ++@option{-s} option were given. Synopsis: ++ ++@example ++uname [@var{option}]@dots{} ++@end example ++ ++If multiple options or @option{-a} are given, the selected information is ++printed in this order: ++ ++@example ++@var{kernel-name} @var{nodename} @var{kernel-release} @var{kernel-version} ++@var{machine} @var{processor} @var{hardware-platform} @var{operating-system} ++@end example ++ ++The information may contain internal spaces, so such output cannot be ++parsed reliably. In the following example, @var{release} is ++@samp{2.2.18ss.e820-bda652a #4 SMP Tue Jun 5 11:24:08 PDT 2001}: ++ ++@smallexample ++uname -a ++@result{} Linux dum 2.2.18 #4 SMP Tue Jun 5 11:24:08 PDT 2001 i686 unknown unknown GNU/Linux ++@end smallexample ++ ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -a ++@itemx --all ++@opindex -a ++@opindex --all ++Print all of the below information, except omit the processor type ++and the hardware platform name if they are unknown. ++ ++@item -i ++@itemx --hardware-platform ++@opindex -i ++@opindex --hardware-platform ++@cindex implementation, hardware ++@cindex hardware platform ++@cindex platform, hardware ++Print the hardware platform name ++(sometimes called the hardware implementation). ++Print @samp{unknown} if the kernel does not make this information ++easily available, as is the case with Linux kernels. ++ ++@item -m ++@itemx --machine ++@opindex -m ++@opindex --machine ++@cindex machine type ++@cindex hardware class ++@cindex hardware type ++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 ++@opindex --processor ++@cindex host processor type ++Print the processor type (sometimes called the instruction set ++architecture or ISA). ++Print @samp{unknown} if the kernel does not make this information ++easily available, as is the case with Linux kernels. ++ ++@item -o ++@itemx --operating-system ++@opindex -o ++@opindex --operating-system ++@cindex operating system name ++Print the name of the operating system. ++ ++@item -r ++@itemx --kernel-release ++@opindex -r ++@opindex --kernel-release ++@cindex kernel release ++@cindex release of kernel ++Print the kernel release. ++ ++@item -s ++@itemx --kernel-name ++@opindex -s ++@opindex --kernel-name ++@cindex kernel name ++@cindex name of kernel ++Print the kernel name. ++@acronym{POSIX} 1003.1-2001 (@pxref{Standards conformance}) calls this ++``the implementation of the operating system'', because the ++@acronym{POSIX} specification itself has no notion of ``kernel''. ++The kernel name might be the same as the operating system name printed ++by the @option{-o} or @option{--operating-system} option, but it might ++differ. Some operating systems (e.g., FreeBSD, HP-UX) have the same ++name as their underlying kernels; others (e.g., GNU/Linux, Solaris) ++do not. ++ ++@item -v ++@itemx --kernel-version ++@opindex -v ++@opindex --kernel-version ++@cindex kernel version ++@cindex version of kernel ++Print the kernel version. ++ ++@end table ++ ++@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}. ++ ++@exitstatus ++ ++ ++@node hostid invocation ++@section @command{hostid}: Print numeric host identifier ++ ++@pindex hostid ++@cindex printing the host identifier ++ ++@command{hostid} prints the numeric identifier of the current host ++in hexadecimal. This command accepts no arguments. ++The only options are @option{--help} and @option{--version}. ++@xref{Common options}. ++ ++For example, here's what it prints on one system I use: ++ ++@example ++$ hostid ++1bac013d ++@end example ++ ++On that system, the 32-bit quantity happens to be closely ++related to the system's Internet address, but that isn't always ++the case. ++ ++@exitstatus ++ ++@node uptime invocation ++@section @command{uptime}: Print system uptime and load ++ ++@pindex uptime ++@cindex printing the system uptime and load ++ ++@command{uptime} prints the current time, the system's uptime, the ++number of logged-in users and the current load average. ++ ++If an argument is specified, it is used as the file to be read ++to discover how many users are logged in. If no argument is ++specified, a system default is used (@command{uptime --help} indicates ++the default setting). ++ ++The only options are @option{--help} and @option{--version}. ++@xref{Common options}. ++ ++For example, here's what it prints right now on one system I use: ++ ++@example ++$ uptime ++ 14:07 up 3:35, 3 users, load average: 1.39, 1.15, 1.04 ++@end example ++ ++The precise method of calculation of load average varies somewhat ++between systems. Some systems calculate it as the average number of ++runnable processes over the last 1, 5 and 15 minutes, but some systems ++also include processes in the uninterruptible sleep state (that is, ++those processes which are waiting for disk I/O). The Linux kernel ++includes uninterruptible processes. ++ ++@node SELinux context ++@chapter SELinux context ++ ++@cindex SELinux context ++@cindex SELinux, context ++@cindex commands for SELinux context ++ ++This section describes commands for operations with SELinux ++contexts. ++ ++@menu ++* chcon invocation:: Change SELinux context of file ++* runcon invocation:: Run a command in specified SELinux context ++@end menu ++ ++@node chcon invocation ++@section @command{chcon}: Change SELinux context of file ++ ++@pindex chcon ++@cindex changing security context ++@cindex change SELinux context ++ ++@command{chcon} changes the SELinux security context of the selected files. ++Synopses: ++ ++@smallexample ++chcon [@var{option}]@dots{} @var{context} @var{file}@dots{} ++chcon [@var{option}]@dots{} [-u @var{user}] [-r @var{role}] [-l @var{range}] [-t @var{type}] @var{file}@dots{} ++chcon [@var{option}]@dots{} --reference=@var{rfile} @var{file}@dots{} ++@end smallexample ++ ++Change the SELinux security context of each @var{file} to @var{context}. ++With @option{--reference}, change the security context of each @var{file} ++to that of @var{rfile}. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -h ++@itemx --no-dereference ++@opindex -h ++@opindex --no-dereference ++@cindex no dereference ++Affect symbolic links instead of any referenced file. ++ ++@item --reference=@var{rfile} ++@opindex --reference ++@cindex reference file ++Use @var{rfile}'s security context rather than specifying a @var{context} value. ++ ++@item -R ++@itemx --recursive ++@opindex -R ++@opindex --recursive ++Operate on files and directories recursively. ++ ++@choptH ++@xref{Traversing symlinks}. ++ ++@choptL ++@xref{Traversing symlinks}. ++ ++@choptP ++@xref{Traversing symlinks}. ++ ++@item -v ++@itemx --verbose ++@opindex -v ++@opindex --verbose ++@cindex diagnostic ++Output a diagnostic for every file processed. ++ ++@item -u @var{user} ++@itemx --user=@var{user} ++@opindex -u ++@opindex --user ++Set user @var{user} in the target security context. ++ ++@item -r @var{role} ++@itemx --role=@var{role} ++@opindex -r ++@opindex --role ++Set role @var{role} in the target security context. ++ ++@item -t @var{type} ++@itemx --type=@var{type} ++@opindex -t ++@opindex --type ++Set type @var{type} in the target security context. ++ ++@item -l @var{range} ++@itemx --range=@var{range} ++@opindex -l ++@opindex --range ++Set range @var{range} in the target security context. ++ ++@end table ++ ++@exitstatus ++ ++@node runcon invocation ++@section @command{runcon}: Run a command in specified SELinux context ++ ++@pindex runcon ++@cindex run with security context ++ ++ ++@command{runcon} runs file in specified SELinux security context. ++ ++Synopses: ++@smallexample ++runcon @var{context} @var{command} [@var{args}] ++runcon [ -c ] [-u @var{user}] [-r @var{role}] [-t @var{type}] [-l @var{range}] @var{command} [@var{args}] ++@end smallexample ++ ++Run @var{command} with completely-specified @var{context}, or with ++current or transitioned security context modified by one or more of @var{level}, ++@var{role}, @var{type} and @var{user}. ++ ++If none of @option{-c}, @option{-t}, @option{-u}, @option{-r}, or @option{-l} ++is specified, the first argument is used as the complete context. ++Any additional arguments after @var{command} ++are interpreted as arguments to the command. ++ ++With neither @var{context} nor @var{command}, print the current security context. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -c ++@itemx --compute ++@opindex -c ++@opindex --compute ++Compute process transition context before modifying. ++ ++@item -u @var{user} ++@itemx --user=@var{user} ++@opindex -u ++@opindex --user ++Set user @var{user} in the target security context. ++ ++@item -r @var{role} ++@itemx --role=@var{role} ++@opindex -r ++@opindex --role ++Set role @var{role} in the target security context. ++ ++@item -t @var{type} ++@itemx --type=@var{type} ++@opindex -t ++@opindex --type ++Set type @var{type} in the target security context. ++ ++@item -l @var{range} ++@itemx --range=@var{range} ++@opindex -l ++@opindex --range ++Set range @var{range} in the target security context. ++ ++@end table ++ ++@cindex exit status of @command{runcon} ++Exit status: ++ ++@display ++126 if @var{command} is found but cannot be invoked ++127 if @command{runcon} itself fails or if @var{command} cannot be found ++the exit status of @var{command} otherwise ++@end display ++ ++@node Modified command invocation ++@chapter Modified command invocation ++ ++@cindex modified command invocation ++@cindex invocation of commands, modified ++@cindex commands for invoking other commands ++ ++This section describes commands that run other commands in some context ++different than the current one: a modified environment, as a different ++user, etc. ++ ++@menu ++* chroot invocation:: Modify the root directory. ++* env invocation:: Modify environment variables. ++* nice invocation:: Modify niceness. ++* nohup invocation:: Immunize to hangups. ++* stdbuf invocation:: Modify buffering of standard streams. ++* su invocation:: Modify user and group ID. ++* timeout invocation:: Run with time limit. ++@end menu ++ ++ ++@node chroot invocation ++@section @command{chroot}: Run a command with a different root directory ++ ++@pindex chroot ++@cindex running a program in a specified root directory ++@cindex root directory, running a program in a specified ++ ++@command{chroot} runs a command with a specified root directory. ++On many systems, only the super-user can do this.@footnote{However, ++some systems (e.g., FreeBSD) can be configured to allow certain regular ++users to use the @code{chroot} system call, and hence to run this program. ++Also, on Cygwin, anyone can run the @command{chroot} command, because the ++underlying function is non-privileged due to lack of support in MS-Windows.} ++Synopses: ++ ++@example ++chroot @var{option} @var{newroot} [@var{command} [@var{args}]@dots{}] ++chroot @var{option} ++@end example ++ ++Ordinarily, file names are looked up starting at the root of the ++directory structure, i.e., @file{/}. @command{chroot} changes the root to ++the directory @var{newroot} (which must exist) and then runs ++@var{command} with optional @var{args}. If @var{command} is not ++specified, the default is the value of the @env{SHELL} environment ++variable or @command{/bin/sh} if not set, invoked with the @option{-i} option. ++@var{command} must not be a special built-in utility ++(@pxref{Special built-in utilities}). ++ ++The program accepts the following options. Also see @ref{Common options}. ++Options must precede operands. ++ ++@table @samp ++ ++@itemx --userspec=@var{user}[:@var{group}] ++@opindex --userspec ++By default, @var{command} is run with the same credentials ++as the invoking process. ++Use this option to run it as a different @var{user} and/or with a ++different primary @var{group}. ++ ++@itemx --groups=@var{groups} ++@opindex --groups ++Use this option to specify the supplementary @var{groups} to be ++used by the new process. ++The items in the list (names or numeric IDs) must be separated by commas. ++ ++@end table ++ ++Here are a few tips to help avoid common problems in using chroot. ++To start with a simple example, make @var{command} refer to a statically ++linked binary. If you were to use a dynamically linked executable, then ++you'd have to arrange to have the shared libraries in the right place under ++your new root directory. ++ ++For example, if you create a statically linked @command{ls} executable, ++and put it in @file{/tmp/empty}, you can run this command as root: ++ ++@example ++$ chroot /tmp/empty /ls -Rl / ++@end example ++ ++Then you'll see output like this: ++ ++@example ++/: ++total 1023 ++-rwxr-xr-x 1 0 0 1041745 Aug 16 11:17 ls ++@end example ++ ++If you want to use a dynamically linked executable, say @command{bash}, ++then first run @samp{ldd bash} to see what shared objects it needs. ++Then, in addition to copying the actual binary, also copy the listed ++files to the required positions under your intended new root directory. ++Finally, if the executable requires any other files (e.g., data, state, ++device files), copy them into place, too. ++ ++@cindex exit status of @command{chroot} ++Exit status: ++ ++@display ++1 if @command{chroot} itself fails ++126 if @var{command} is found but cannot be invoked ++127 if @var{command} cannot be found ++the exit status of @var{command} otherwise ++@end display ++ ++ ++@node env invocation ++@section @command{env}: Run a command in a modified environment ++ ++@pindex env ++@cindex environment, running a program in a modified ++@cindex modified environment, running a program in a ++@cindex running a program in a modified environment ++ ++@command{env} runs a command with a modified environment. Synopses: ++ ++@example ++env [@var{option}]@dots{} [@var{name}=@var{value}]@dots{} @c ++[@var{command} [@var{args}]@dots{}] ++env ++@end example ++ ++Operands of the form @samp{@var{variable}=@var{value}} set ++the environment variable @var{variable} to value @var{value}. ++@var{value} may be empty (@samp{@var{variable}=}). Setting a variable ++to an empty value is different from unsetting it. ++These operands are evaluated left-to-right, so if two operands ++mention the same variable the earlier is ignored. ++ ++Environment variable names can be empty, and can contain any ++characters other than @samp{=} and @acronym{ASCII} @sc{nul}. ++However, it is wise to limit yourself to names that ++consist solely of underscores, digits, and @acronym{ASCII} letters, ++and that begin with a non-digit, as applications like the shell do not ++work well with other names. ++ ++@vindex PATH ++The first operand that does not contain the character @samp{=} ++specifies the program to invoke; it is ++searched for according to the @env{PATH} environment variable. Any ++remaining arguments are passed as arguments to that program. ++The program should not be a special built-in utility ++(@pxref{Special built-in utilities}). ++ ++@cindex environment, printing ++ ++If no command name is specified following the environment ++specifications, the resulting environment is printed. This is like ++specifying the @command{printenv} program. ++ ++The program accepts the following options. Also see @ref{Common options}. ++Options must precede operands. ++ ++@table @samp ++ ++@item -u @var{name} ++@itemx --unset=@var{name} ++@opindex -u ++@opindex --unset ++Remove variable @var{name} from the environment, if it was in the ++environment. ++ ++@item - ++@itemx -i ++@itemx --ignore-environment ++@opindex - ++@opindex -i ++@opindex --ignore-environment ++Start with an empty environment, ignoring the inherited environment. ++ ++@end table ++ ++@cindex exit status of @command{env} ++Exit status: ++ ++@display ++0 if no @var{command} is specified and the environment is output ++1 if @command{env} itself fails ++126 if @var{command} is found but cannot be invoked ++127 if @var{command} cannot be found ++the exit status of @var{command} otherwise ++@end display ++ ++ ++@node nice invocation ++@section @command{nice}: Run a command with modified niceness ++ ++@pindex nice ++@cindex niceness ++@cindex scheduling, affecting ++@cindex appropriate privileges ++ ++@command{nice} prints or modifies a process's @dfn{niceness}, ++a parameter that affects whether the process is scheduled favorably. ++Synopsis: ++ ++@example ++nice [@var{option}]@dots{} [@var{command} [@var{arg}]@dots{}] ++@end example ++ ++If no arguments are given, @command{nice} prints the current niceness. ++Otherwise, @command{nice} runs the given @var{command} with its ++niceness adjusted. By default, its niceness is incremented by 10. ++ ++Niceness values range at least from @minus{}20 (process has high priority ++and gets more resources, thus slowing down other processes) through 19 ++(process has lower priority and runs slowly itself, but has less impact ++on the speed of other running processes). Some systems ++may have a wider range of nicenesses; conversely, other systems may ++enforce more restrictive limits. An attempt to set the niceness ++outside the supported range is treated as an attempt to use the ++minimum or maximum supported value. ++ ++A niceness should not be confused with a scheduling priority, which ++lets applications determine the order in which threads are scheduled ++to run. Unlike a priority, a niceness is merely advice to the ++scheduler, which the scheduler is free to ignore. Also, as a point of ++terminology, @acronym{POSIX} defines the behavior of @command{nice} in ++terms of a @dfn{nice value}, which is the nonnegative difference ++between a niceness and the minimum niceness. Though @command{nice} ++conforms to @acronym{POSIX}, its documentation and diagnostics use the ++term ``niceness'' for compatibility with historical practice. ++ ++@var{command} must not be a special built-in utility (@pxref{Special ++built-in utilities}). ++ ++@mayConflictWithShellBuiltIn{nice} ++ ++The program accepts the following option. Also see @ref{Common options}. ++Options must precede operands. ++ ++@table @samp ++@item -n @var{adjustment} ++@itemx --adjustment=@var{adjustment} ++@opindex -n ++@opindex --adjustment ++Add @var{adjustment} instead of 10 to the command's niceness. If ++@var{adjustment} is negative and you lack appropriate privileges, ++@command{nice} issues a warning but otherwise acts as if you specified ++a zero adjustment. ++ ++For compatibility @command{nice} also supports an obsolete ++option syntax @option{-@var{adjustment}}. New scripts should use ++@option{-n @var{adjustment}} instead. ++ ++@end table ++ ++@cindex exit status of @command{nice} ++Exit status: ++ ++@display ++0 if no @var{command} is specified and the niceness is output ++1 if @command{nice} itself fails ++126 if @var{command} is found but cannot be invoked ++127 if @var{command} cannot be found ++the exit status of @var{command} otherwise ++@end display ++ ++It is sometimes useful to run a non-interactive program with reduced niceness. ++ ++@example ++$ nice factor 4611686018427387903 ++@end example ++ ++Since @command{nice} prints the current niceness, ++you can invoke it through itself to demonstrate how it works. ++ ++The default behavior is to increase the niceness by @samp{10}: ++ ++@example ++$ nice ++0 ++$ nice nice ++10 ++$ nice -n 10 nice ++10 ++@end example ++ ++The @var{adjustment} is relative to the current niceness. In the ++next example, the first @command{nice} invocation runs the second one ++with niceness 10, and it in turn runs the final one with a niceness ++that is 3 more: ++ ++@example ++$ nice nice -n 3 nice ++13 ++@end example ++ ++Specifying a niceness larger than the supported range ++is the same as specifying the maximum supported value: ++ ++@example ++$ nice -n 10000000000 nice ++19 ++@end example ++ ++Only a privileged user may run a process with lower niceness: ++ ++@example ++$ nice -n -1 nice ++nice: cannot set niceness: Permission denied ++0 ++$ sudo nice -n -1 nice ++-1 ++@end example ++ ++ ++@node nohup invocation ++@section @command{nohup}: Run a command immune to hangups ++ ++@pindex nohup ++@cindex hangups, immunity to ++@cindex immunity to hangups ++@cindex logging out and continuing to run ++ ++@flindex nohup.out ++@command{nohup} runs the given @var{command} with hangup signals ignored, ++so that the command can continue running in the background after you log ++out. Synopsis: ++ ++@example ++nohup @var{command} [@var{arg}]@dots{} ++@end example ++ ++If standard input is a terminal, it is redirected from ++@file{/dev/null} so that terminal sessions do not mistakenly consider ++the terminal to be used by the command. This is a @acronym{GNU} ++extension; programs intended to be portable to non-@acronym{GNU} hosts ++should use @samp{nohup @var{command} [@var{arg}]@dots{} make.log ++@end example ++ ++@command{nohup} does not automatically put the command it runs in the ++background; you must do that explicitly, by ending the command line ++with an @samp{&}. Also, @command{nohup} does not alter the ++niceness of @var{command}; use @command{nice} for that, ++e.g., @samp{nohup nice @var{command}}. ++ ++@var{command} must not be a special built-in utility (@pxref{Special ++built-in utilities}). ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. Options must precede operands. ++ ++@cindex exit status of @command{nohup} ++Exit status: ++ ++@display ++126 if @var{command} is found but cannot be invoked ++127 if @command{nohup} itself fails or if @var{command} cannot be found ++the exit status of @var{command} otherwise ++@end display ++ ++ ++@node stdbuf invocation ++@section @command{stdbuf}: Run a command with modified I/O stream buffering ++ ++@pindex stdbuf ++@cindex standard streams, buffering ++@cindex line buffered ++ ++@command{stdbuf} allows one to modify the buffering operations of the ++three standard I/O streams associated with a program. Synopsis: ++ ++@example ++stdbuf @var{option}@dots{} @var{command} ++@end example ++ ++Any additional @var{arg}s are passed as additional arguments to the ++@var{command}. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++ ++@item -i @var{mode} ++@itemx --input=@var{mode} ++@opindex -i ++@opindex --input ++Adjust the standard input stream buffering. ++ ++@item -o @var{mode} ++@itemx --output=@var{mode} ++@opindex -o ++@opindex --output ++Adjust the standard output stream buffering. ++ ++@item -e @var{mode} ++@itemx --error=@var{mode} ++@opindex -e ++@opindex --error ++Adjust the standard error stream buffering. ++ ++@end table ++ ++The @var{mode} can be specified as follows: ++ ++@table @samp ++ ++@item L ++Set the stream to line buffered mode. ++In this mode data is coalesced until a newline is output or ++input is read from any stream attached to a terminal device. ++This option is invalid with standard input. ++ ++@item 0 ++Disable buffering of the selected stream. ++In this mode data is output immediately and only the ++amount of data requested is read from input. ++ ++@item @var{size} ++Specify the size of the buffer to use in fully buffered mode. ++@multiplierSuffixesNoBlocks{size} ++ ++@end table ++ ++NOTE: If @var{command} adjusts the buffering of its standard streams ++(@command{tee} does for e.g.) then that will override corresponding settings ++changed by @command{stdbuf}. Also some filters (like @command{dd} and ++@command{cat} etc.) don't use streams for I/O, and are thus unaffected ++by @command{stdbuf} settings. ++ ++@cindex exit status of @command{stdbuf} ++Exit status: ++ ++@display ++125 if @command{stdbuf} itself fails ++126 if @var{command} is found but cannot be invoked ++127 if @var{command} cannot be found ++the exit status of @var{command} otherwise ++@end display ++ ++ ++@node su invocation ++@section @command{su}: Run a command with substitute user and group ID ++ ++@pindex su ++@cindex substitute user and group IDs ++@cindex user ID, switching ++@cindex super-user, becoming ++@cindex root, becoming ++ ++@command{su} allows one user to temporarily become another user. It runs a ++command (often an interactive shell) with the real and effective user ++ID, group ID, and supplemental groups of a given @var{user}. Synopsis: ++ ++@example ++su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}] ++@end example ++ ++@cindex passwd entry, and @command{su} shell ++@flindex /bin/sh ++@flindex /etc/passwd ++If no @var{user} is given, the default is @code{root}, the super-user. ++The shell to use is taken from @var{user}'s @code{passwd} entry, or ++@file{/bin/sh} if none is specified there. If @var{user} has a ++password, @command{su} prompts for the password unless run by a user with ++effective user ID of zero (the super-user). ++ ++@vindex HOME ++@vindex SHELL ++@vindex USER ++@vindex LOGNAME ++@cindex login shell ++By default, @command{su} does not change the current directory. ++It sets the environment variables @env{HOME} and @env{SHELL} ++from the password entry for @var{user}, and if @var{user} is not ++the super-user, sets @env{USER} and @env{LOGNAME} to @var{user}. ++By default, the shell is not a login shell. ++ ++Any additional @var{arg}s are passed as additional arguments to the ++shell. ++ ++@cindex @option{-su} ++GNU @command{su} does not treat @file{/bin/sh} or any other shells specially ++(e.g., by setting @code{argv[0]} to @option{-su}, passing @option{-c} only ++to certain shells, etc.). ++ ++@findex syslog ++@command{su} can optionally be compiled to use @code{syslog} to report ++failed, and optionally successful, @command{su} attempts. (If the system ++supports @code{syslog}.) However, GNU @command{su} does not check if the ++user is a member of the @code{wheel} group; see below. ++ ++The program accepts the following options. Also see @ref{Common options}. ++ ++@table @samp ++@item -c @var{command} ++@itemx --command=@var{command} ++@opindex -c ++@opindex --command ++Pass @var{command}, a single command line to run, to the shell with ++a @option{-c} option instead of starting an interactive shell. ++ ++@item -f ++@itemx --fast ++@opindex -f ++@opindex --fast ++@flindex .cshrc ++@cindex file name pattern expansion, disabled ++@cindex globbing, disabled ++Pass the @option{-f} option to the shell. This probably only makes sense ++if the shell run is @command{csh} or @command{tcsh}, for which the @option{-f} ++option prevents reading the startup file (@file{.cshrc}). With ++Bourne-like shells, the @option{-f} option disables file name pattern ++expansion (globbing), which is not likely to be useful. ++ ++@item - ++@itemx -l ++@itemx --login ++@opindex - ++@opindex -l ++@opindex --login ++@c other variables already indexed above ++@vindex TERM ++@vindex PATH ++@cindex login shell, creating ++Make the shell a login shell. This means the following. Unset all ++environment variables except @env{TERM}, @env{HOME}, and @env{SHELL} ++(which are set as described above), and @env{USER} and @env{LOGNAME} ++(which are set, even for the super-user, as described above), and set ++@env{PATH} to a compiled-in default value. Change to @var{user}'s home ++directory. Prepend @samp{-} to the shell's name, intended to make it ++read its login startup file(s). ++ ++@item -m ++@itemx -p ++@itemx --preserve-environment ++@opindex -m ++@opindex -p ++@opindex --preserve-environment ++@cindex environment, preserving ++@flindex /etc/shells ++@cindex restricted shell ++Do not change the environment variables @env{HOME}, @env{USER}, ++@env{LOGNAME}, or @env{SHELL}. Run the shell given in the environment ++variable @env{SHELL} instead of the shell from @var{user}'s passwd ++entry, unless the user running @command{su} is not the super-user and ++@var{user}'s shell is restricted. A @dfn{restricted shell} is one that ++is not listed in the file @file{/etc/shells}, or in a compiled-in list ++if that file does not exist. Parts of what this option does can be ++overridden by @option{--login} and @option{--shell}. ++ ++@item -s @var{shell} ++@itemx --shell=@var{shell} ++@opindex -s ++@opindex --shell ++Run @var{shell} instead of the shell from @var{user}'s passwd entry, ++unless the user running @command{su} is not the super-user and @var{user}'s ++shell is restricted (see @option{-m} just above). ++ ++@end table ++ ++@cindex exit status of @command{su} ++Exit status: ++ ++@display ++1 if @command{su} itself fails ++126 if subshell is found but cannot be invoked ++127 if subshell cannot be found ++the exit status of the subshell otherwise ++@end display ++ ++@cindex wheel group, not supported ++@cindex group wheel, not supported ++@cindex fascism ++@subsection Why GNU @command{su} does not support the @samp{wheel} group ++ ++(This section is by Richard Stallman.) ++ ++@cindex Twenex ++@cindex MIT AI lab ++Sometimes a few of the users try to hold total power over all the ++rest. For example, in 1984, a few users at the MIT AI lab decided to ++seize power by changing the operator password on the Twenex system and ++keeping it secret from everyone else. (I was able to thwart this coup ++and give power back to the users by patching the kernel, but I ++wouldn't know how to do that in Unix.) ++ ++However, occasionally the rulers do tell someone. Under the usual ++@command{su} mechanism, once someone learns the root password who ++sympathizes with the ordinary users, he or she can tell the rest. The ++``wheel group'' feature would make this impossible, and thus cement the ++power of the rulers. ++ ++I'm on the side of the masses, not that of the rulers. If you are ++used to supporting the bosses and sysadmins in whatever they do, you ++might find this idea strange at first. ++ ++ ++@node timeout invocation ++@section @command{timeout}: Run a command with a time limit ++ ++@pindex timeout ++@cindex time limit ++@cindex run commands with bounded time ++ ++@command{timeout} runs the given @var{command} and kills it if it is ++still running after the specified time interval. Synopsis: ++ ++@example ++timeout [@var{option}] @var{number}[smhd] @var{command} [@var{arg}]@dots{} ++@end example ++ ++@cindex time units ++@var{number} is an integer followed by an optional unit; the default ++is seconds. The units are: ++ ++@table @samp ++@item s ++seconds ++@item m ++minutes ++@item h ++hours ++@item d ++days ++@end table ++ ++@var{command} must not be a special built-in utility (@pxref{Special ++built-in utilities}). ++ ++The program accepts the following option. Also see @ref{Common options}. ++Options must precede operands. ++ ++@table @samp ++@item -s @var{signal} ++@itemx --signal=@var{signal} ++@opindex -s ++@opindex --signal ++Send this @var{signal} to @var{command} on timeout, rather than the ++default @samp{TERM} signal. @var{signal} may be a name like @samp{HUP} ++or a number. Also see @xref{Signal specifications}. ++ ++@end table ++ ++@cindex exit status of @command{timeout} ++Exit status: ++ ++@display ++124 if @var{command} times out ++125 if @command{timeout} itself fails ++126 if @var{command} is found but cannot be invoked ++127 if @var{command} cannot be found ++the exit status of @var{command} otherwise ++@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 ++@acronym{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. For a list of supported ++signal names and numbers see @xref{Signal specifications}. ++ ++@node Delaying ++@chapter Delaying ++ ++@cindex delaying commands ++@cindex commands for delaying ++ ++@c Perhaps @command{wait} or other commands should be described here also? ++ ++@menu ++* sleep invocation:: Delay for a specified time. ++@end menu ++ ++ ++@node sleep invocation ++@section @command{sleep}: Delay for a specified time ++ ++@pindex sleep ++@cindex delay for a specified time ++ ++@command{sleep} pauses for an amount of time specified by the sum of ++the values of the command line arguments. ++Synopsis: ++ ++@example ++sleep @var{number}[smhd]@dots{} ++@end example ++ ++@cindex time units ++Each argument is a number followed by an optional unit; the default ++is seconds. The units are: ++ ++@table @samp ++@item s ++seconds ++@item m ++minutes ++@item h ++hours ++@item d ++days ++@end table ++ ++Historical implementations of @command{sleep} have required that ++@var{number} be an integer, and only accepted a single argument ++without a suffix. However, GNU @command{sleep} accepts ++arbitrary floating point numbers (using a period before any fractional ++digits). ++ ++The only options are @option{--help} and @option{--version}. @xref{Common ++options}. ++ ++@c sleep is a shell built-in at least with Solaris 11's /bin/sh ++@mayConflictWithShellBuiltIn{sleep} ++ ++@exitstatus ++ ++ ++@node Numeric operations ++@chapter Numeric operations ++ ++@cindex numeric operations ++These programs do numerically-related operations. ++ ++@menu ++* factor invocation:: Show factors of numbers. ++* seq invocation:: Print sequences of numbers. ++@end menu ++ ++ ++@node factor invocation ++@section @command{factor}: Print prime factors ++ ++@pindex factor ++@cindex prime factors ++ ++@command{factor} prints prime factors. Synopses: ++ ++@example ++factor [@var{number}]@dots{} ++factor @var{option} ++@end example ++ ++If no @var{number} is specified on the command line, @command{factor} reads ++numbers from standard input, delimited by newlines, tabs, or spaces. ++ ++The @command{factor} command supports only a small number of options: ++ ++@table @samp ++@item --help ++Print a short help on standard output, then exit without further ++processing. ++ ++@item --version ++Print the program version on standard output, then exit without further ++processing. ++@end table ++ ++Factoring the product of the eighth and ninth Mersenne primes ++takes about 30 milliseconds of CPU time on a 2.2 GHz Athlon. ++ ++@example ++M8=`echo 2^31-1|bc` ; M9=`echo 2^61-1|bc` ++/usr/bin/time -f '%U' factor $(echo "$M8 * $M9" | bc) ++4951760154835678088235319297: 2147483647 2305843009213693951 ++0.03 ++@end example ++ ++Similarly, factoring the eighth Fermat number @math{2^{256}+1} takes ++about 20 seconds on the same machine. ++ ++Factoring large prime numbers is, in general, hard. The Pollard Rho ++algorithm used by @command{factor} is particularly effective for ++numbers with relatively small factors. If you wish to factor large ++numbers which do not have small factors (for example, numbers which ++are the product of two large primes), other methods are far better. ++ ++If @command{factor} is built without using GNU MP, only ++single-precision arithmetic is available, and so large numbers ++(typically @math{2^{64}} and above) will not be supported. The single-precision ++code uses an algorithm which is designed for factoring smaller ++numbers. ++ ++@exitstatus ++ ++ ++@node seq invocation ++@section @command{seq}: Print numeric sequences ++ ++@pindex seq ++@cindex numeric sequences ++@cindex sequence of numbers ++ ++@command{seq} prints a sequence of numbers to standard output. Synopses: ++ ++@example ++seq [@var{option}]@dots{} @var{last} ++seq [@var{option}]@dots{} @var{first} @var{last} ++seq [@var{option}]@dots{} @var{first} @var{increment} @var{last} ++@end example ++ ++@command{seq} prints the numbers from @var{first} to @var{last} by ++@var{increment}. By default, each number is printed on a separate line. ++When @var{increment} is not specified, it defaults to @samp{1}, ++even when @var{first} is larger than @var{last}. ++@var{first} also defaults to @samp{1}. So @code{seq 1} prints ++@samp{1}, but @code{seq 0} and @code{seq 10 5} produce no output. ++Floating-point numbers ++may be specified (using a period before any fractional digits). ++ ++The program accepts the following options. Also see @ref{Common options}. ++Options must precede operands. ++ ++@table @samp ++@item -f @var{format} ++@itemx --format=@var{format} ++@opindex -f @var{format} ++@opindex --format=@var{format} ++@cindex formatting of numbers in @command{seq} ++Print all numbers using @var{format}. ++@var{format} must contain exactly one of the @samp{printf}-style ++floating point conversion specifications @samp{%a}, @samp{%e}, ++@samp{%f}, @samp{%g}, @samp{%A}, @samp{%E}, @samp{%F}, @samp{%G}. ++The @samp{%} may be followed by zero or more flags taken from the set ++@samp{-+#0 '}, then an optional width containing one or more digits, ++then an optional precision consisting of a @samp{.} followed by zero ++or more digits. @var{format} may also contain any number of @samp{%%} ++conversion specifications. All conversion specifications have the ++same meaning as with @samp{printf}. ++ ++The default format is derived from @var{first}, @var{step}, and ++@var{last}. If these all use a fixed point decimal representation, ++the default format is @samp{%.@var{p}f}, where @var{p} is the minimum ++precision that can represent the output numbers exactly. Otherwise, ++the default format is @samp{%g}. ++ ++@item -s @var{string} ++@itemx --separator=@var{string} ++@cindex separator for numbers in @command{seq} ++Separate numbers with @var{string}; default is a newline. ++The output always terminates with a newline. ++ ++@item -w ++@itemx --equal-width ++Print all numbers with the same width, by padding with leading zeros. ++@var{first}, @var{step}, and @var{last} should all use a fixed point ++decimal representation. ++(To have other kinds of padding, use @option{--format}). ++ ++@end table ++ ++You can get finer-grained control over output with @option{-f}: ++ ++@example ++$ seq -f '(%9.2E)' -9e5 1.1e6 1.3e6 ++(-9.00E+05) ++( 2.00E+05) ++( 1.30E+06) ++@end example ++ ++If you want hexadecimal integer output, you can use @command{printf} ++to perform the conversion: ++ ++@example ++$ printf '%x\n' `seq 1048575 1024 1050623` ++fffff ++1003ff ++1007ff ++@end example ++ ++For very long lists of numbers, use xargs to avoid ++system limitations on the length of an argument list: ++ ++@example ++$ seq 1000000 | xargs printf '%x\n' | tail -n 3 ++f423e ++f423f ++f4240 ++@end example ++ ++To generate octal output, use the printf @code{%o} format instead ++of @code{%x}. ++ ++On most systems, seq can produce whole-number output for values up to ++at least @math{2^{53}}. Larger integers are approximated. The details ++differ depending on your floating-point implementation, but a common ++case is that @command{seq} works with integers through @math{2^{64}}, ++and larger integers may not be numerically correct: ++ ++@example ++$ seq 18446744073709551616 1 18446744073709551618 ++18446744073709551616 ++18446744073709551616 ++18446744073709551618 ++@end example ++ ++Be careful when using @command{seq} with outlandish values: otherwise ++you may see surprising results, as @command{seq} uses floating point ++internally. For example, on the x86 platform, where the internal ++representation uses a 64-bit fraction, the command: ++ ++@example ++seq 1 0.0000000000000000001 1.0000000000000000009 ++@end example ++ ++outputs 1.0000000000000000007 twice and skips 1.0000000000000000008. ++ ++@exitstatus ++ ++ ++@node File permissions ++@chapter File permissions ++@include perm.texi ++ ++@include getdate.texi ++ ++@c What's GNU? ++@c Arnold Robbins ++@node Opening the software toolbox ++@chapter Opening the Software Toolbox ++ ++An earlier version of this chapter appeared in ++@uref{http://www.linuxjournal.com/article.php?sid=2762, the ++@cite{What's GNU?} column of @cite{Linux Journal}, 2 (June, 1994)}. ++It was written by Arnold Robbins. ++ ++@menu ++* Toolbox introduction:: Toolbox introduction ++* I/O redirection:: I/O redirection ++* The who command:: The @command{who} command ++* The cut command:: The @command{cut} command ++* The sort command:: The @command{sort} command ++* The uniq command:: The @command{uniq} command ++* Putting the tools together:: Putting the tools together ++@end menu ++ ++ ++@node Toolbox introduction ++@unnumberedsec Toolbox Introduction ++ ++This month's column is only peripherally related to the GNU Project, in ++that it describes a number of the GNU tools on your GNU/Linux system and how they ++might be used. What it's really about is the ``Software Tools'' philosophy ++of program development and usage. ++ ++The software tools philosophy was an important and integral concept ++in the initial design and development of Unix (of which Linux and GNU are ++essentially clones). Unfortunately, in the modern day press of ++Internetworking and flashy GUIs, it seems to have fallen by the ++wayside. This is a shame, since it provides a powerful mental model ++for solving many kinds of problems. ++ ++Many people carry a Swiss Army knife around in their pants pockets (or ++purse). A Swiss Army knife is a handy tool to have: it has several knife ++blades, a screwdriver, tweezers, toothpick, nail file, corkscrew, and perhaps ++a number of other things on it. For the everyday, small miscellaneous jobs ++where you need a simple, general purpose tool, it's just the thing. ++ ++On the other hand, an experienced carpenter doesn't build a house using ++a Swiss Army knife. Instead, he has a toolbox chock full of specialized ++tools---a saw, a hammer, a screwdriver, a plane, and so on. And he knows ++exactly when and where to use each tool; you won't catch him hammering nails ++with the handle of his screwdriver. ++ ++The Unix developers at Bell Labs were all professional programmers and trained ++computer scientists. They had found that while a one-size-fits-all program ++might appeal to a user because there's only one program to use, in practice ++such programs are ++ ++@enumerate a ++@item ++difficult to write, ++ ++@item ++difficult to maintain and ++debug, and ++ ++@item ++difficult to extend to meet new situations. ++@end enumerate ++ ++Instead, they felt that programs should be specialized tools. In short, each ++program ``should do one thing well.'' No more and no less. Such programs are ++simpler to design, write, and get right---they only do one thing. ++ ++Furthermore, they found that with the right machinery for hooking programs ++together, that the whole was greater than the sum of the parts. By combining ++several special purpose programs, you could accomplish a specific task ++that none of the programs was designed for, and accomplish it much more ++quickly and easily than if you had to write a special purpose program. ++We will see some (classic) examples of this further on in the column. ++(An important additional point was that, if necessary, take a detour ++and build any software tools you may need first, if you don't already ++have something appropriate in the toolbox.) ++ ++@node I/O redirection ++@unnumberedsec I/O Redirection ++ ++Hopefully, you are familiar with the basics of I/O redirection in the ++shell, in particular the concepts of ``standard input,'' ``standard output,'' ++and ``standard error''. Briefly, ``standard input'' is a data source, where ++data comes from. A program should not need to either know or care if the ++data source is a disk file, a keyboard, a magnetic tape, or even a punched ++card reader. Similarly, ``standard output'' is a data sink, where data goes ++to. The program should neither know nor care where this might be. ++Programs that only read their standard input, do something to the data, ++and then send it on, are called @dfn{filters}, by analogy to filters in a ++water pipeline. ++ ++With the Unix shell, it's very easy to set up data pipelines: ++ ++@smallexample ++program_to_create_data | filter1 | ... | filterN > final.pretty.data ++@end smallexample ++ ++We start out by creating the raw data; each filter applies some successive ++transformation to the data, until by the time it comes out of the pipeline, ++it is in the desired form. ++ ++This is fine and good for standard input and standard output. Where does the ++standard error come in to play? Well, think about @command{filter1} in ++the pipeline above. What happens if it encounters an error in the data it ++sees? If it writes an error message to standard output, it will just ++disappear down the pipeline into @command{filter2}'s input, and the ++user will probably never see it. So programs need a place where they can send ++error messages so that the user will notice them. This is standard error, ++and it is usually connected to your console or window, even if you have ++redirected standard output of your program away from your screen. ++ ++For filter programs to work together, the format of the data has to be ++agreed upon. The most straightforward and easiest format to use is simply ++lines of text. Unix data files are generally just streams of bytes, with ++lines delimited by the @acronym{ASCII} @sc{lf} (Line Feed) character, ++conventionally called a ``newline'' in the Unix literature. (This is ++@code{'\n'} if you're a C programmer.) This is the format used by all ++the traditional filtering programs. (Many earlier operating systems ++had elaborate facilities and special purpose programs for managing ++binary data. Unix has always shied away from such things, under the ++philosophy that it's easiest to simply be able to view and edit your ++data with a text editor.) ++ ++OK, enough introduction. Let's take a look at some of the tools, and then ++we'll see how to hook them together in interesting ways. In the following ++discussion, we will only present those command line options that interest ++us. As you should always do, double check your system documentation ++for the full story. ++ ++@node The who command ++@unnumberedsec The @command{who} Command ++ ++The first program is the @command{who} command. By itself, it generates a ++list of the users who are currently logged in. Although I'm writing ++this on a single-user system, we'll pretend that several people are ++logged in: ++ ++@example ++$ who ++@print{} arnold console Jan 22 19:57 ++@print{} miriam ttyp0 Jan 23 14:19(:0.0) ++@print{} bill ttyp1 Jan 21 09:32(:0.0) ++@print{} arnold ttyp2 Jan 23 20:48(:0.0) ++@end example ++ ++Here, the @samp{$} is the usual shell prompt, at which I typed @samp{who}. ++There are three people logged in, and I am logged in twice. On traditional ++Unix systems, user names are never more than eight characters long. This ++little bit of trivia will be useful later. The output of @command{who} is nice, ++but the data is not all that exciting. ++ ++@node The cut command ++@unnumberedsec The @command{cut} Command ++ ++The next program we'll look at is the @command{cut} command. This program ++cuts out columns or fields of input data. For example, we can tell it ++to print just the login name and full name from the @file{/etc/passwd} ++file. The @file{/etc/passwd} file has seven fields, separated by ++colons: ++ ++@example ++arnold:xyzzy:2076:10:Arnold D. Robbins:/home/arnold:/bin/bash ++@end example ++ ++To get the first and fifth fields, we would use @command{cut} like this: ++ ++@example ++$ cut -d: -f1,5 /etc/passwd ++@print{} root:Operator ++@dots{} ++@print{} arnold:Arnold D. Robbins ++@print{} miriam:Miriam A. Robbins ++@dots{} ++@end example ++ ++With the @option{-c} option, @command{cut} will cut out specific characters ++(i.e., columns) in the input lines. This is useful for input data ++that has fixed width fields, and does not have a field separator. For ++example, list the Monday dates for the current month: ++ ++@c Is using cal ok? Looked at gcal, but I don't like it. ++@example ++$ cal | cut -c 3-5 ++@print{}Mo ++@print{} ++@print{} 6 ++@print{} 13 ++@print{} 20 ++@print{} 27 ++@end example ++ ++@node The sort command ++@unnumberedsec The @command{sort} Command ++ ++Next we'll look at the @command{sort} command. This is one of the most ++powerful commands on a Unix-style system; one that you will often find ++yourself using when setting up fancy data plumbing. ++ ++The @command{sort} ++command reads and sorts each file named on the command line. It then ++merges the sorted data and writes it to standard output. It will read ++standard input if no files are given on the command line (thus ++making it into a filter). The sort is based on the character collating ++sequence or based on user-supplied ordering criteria. ++ ++ ++@node The uniq command ++@unnumberedsec The @command{uniq} Command ++ ++Finally (at least for now), we'll look at the @command{uniq} program. When ++sorting data, you will often end up with duplicate lines, lines that ++are identical. Usually, all you need is one instance of each line. ++This is where @command{uniq} comes in. The @command{uniq} program reads its ++standard input. It prints only one ++copy of each repeated line. It does have several options. Later on, ++we'll use the @option{-c} option, which prints each unique line, preceded ++by a count of the number of times that line occurred in the input. ++ ++ ++@node Putting the tools together ++@unnumberedsec Putting the Tools Together ++ ++Now, let's suppose this is a large ISP server system with dozens of users ++logged in. The management wants the system administrator to write a program that will ++generate a sorted list of logged in users. Furthermore, even if a user ++is logged in multiple times, his or her name should only show up in the ++output once. ++ ++The administrator could sit down with the system documentation and write a C ++program that did this. It would take perhaps a couple of hundred lines ++of code and about two hours to write it, test it, and debug it. ++However, knowing the software toolbox, the administrator can instead start out ++by generating just a list of logged on users: ++ ++@example ++$ who | cut -c1-8 ++@print{} arnold ++@print{} miriam ++@print{} bill ++@print{} arnold ++@end example ++ ++Next, sort the list: ++ ++@example ++$ who | cut -c1-8 | sort ++@print{} arnold ++@print{} arnold ++@print{} bill ++@print{} miriam ++@end example ++ ++Finally, run the sorted list through @command{uniq}, to weed out duplicates: ++ ++@example ++$ who | cut -c1-8 | sort | uniq ++@print{} arnold ++@print{} bill ++@print{} miriam ++@end example ++ ++The @command{sort} command actually has a @option{-u} option that does what ++@command{uniq} does. However, @command{uniq} has other uses for which one ++cannot substitute @samp{sort -u}. ++ ++The administrator puts this pipeline into a shell script, and makes it available for ++all the users on the system (@samp{#} is the system administrator, ++or @code{root}, prompt): ++ ++@example ++# cat > /usr/local/bin/listusers ++who | cut -c1-8 | sort | uniq ++^D ++# chmod +x /usr/local/bin/listusers ++@end example ++ ++There are four major points to note here. First, with just four ++programs, on one command line, the administrator was able to save about two ++hours worth of work. Furthermore, the shell pipeline is just about as ++efficient as the C program would be, and it is much more efficient in ++terms of programmer time. People time is much more expensive than ++computer time, and in our modern ``there's never enough time to do ++everything'' society, saving two hours of programmer time is no mean ++feat. ++ ++Second, it is also important to emphasize that with the ++@emph{combination} of the tools, it is possible to do a special ++purpose job never imagined by the authors of the individual programs. ++ ++Third, it is also valuable to build up your pipeline in stages, as we did here. ++This allows you to view the data at each stage in the pipeline, which helps ++you acquire the confidence that you are indeed using these tools correctly. ++ ++Finally, by bundling the pipeline in a shell script, other users can use ++your command, without having to remember the fancy plumbing you set up for ++them. In terms of how you run them, shell scripts and compiled programs are ++indistinguishable. ++ ++After the previous warm-up exercise, we'll look at two additional, more ++complicated pipelines. For them, we need to introduce two more tools. ++ ++The first is the @command{tr} command, which stands for ``transliterate.'' ++The @command{tr} command works on a character-by-character basis, changing ++characters. Normally it is used for things like mapping upper case to ++lower case: ++ ++@example ++$ echo ThIs ExAmPlE HaS MIXED case! | tr '[:upper:]' '[:lower:]' ++@print{} this example has mixed case! ++@end example ++ ++There are several options of interest: ++ ++@table @code ++@item -c ++work on the complement of the listed characters, i.e., ++operations apply to characters not in the given set ++ ++@item -d ++delete characters in the first set from the output ++ ++@item -s ++squeeze repeated characters in the output into just one character. ++@end table ++ ++We will be using all three options in a moment. ++ ++The other command we'll look at is @command{comm}. The @command{comm} ++command takes two sorted input files as input data, and prints out the ++files' lines in three columns. The output columns are the data lines ++unique to the first file, the data lines unique to the second file, and ++the data lines that are common to both. The @option{-1}, @option{-2}, and ++@option{-3} command line options @emph{omit} the respective columns. (This is ++non-intuitive and takes a little getting used to.) For example: ++ ++@example ++$ cat f1 ++@print{} 11111 ++@print{} 22222 ++@print{} 33333 ++@print{} 44444 ++$ cat f2 ++@print{} 00000 ++@print{} 22222 ++@print{} 33333 ++@print{} 55555 ++$ comm f1 f2 ++@print{} 00000 ++@print{} 11111 ++@print{} 22222 ++@print{} 33333 ++@print{} 44444 ++@print{} 55555 ++@end example ++ ++The file name @file{-} tells @command{comm} to read standard input ++instead of a regular file. ++ ++Now we're ready to build a fancy pipeline. The first application is a word ++frequency counter. This helps an author determine if he or she is over-using ++certain words. ++ ++The first step is to change the case of all the letters in our input file ++to one case. ``The'' and ``the'' are the same word when doing counting. ++ ++@example ++$ tr '[:upper:]' '[:lower:]' < whats.gnu | ... ++@end example ++ ++The next step is to get rid of punctuation. Quoted words and unquoted words ++should be treated identically; it's easiest to just get the punctuation out of ++the way. ++ ++@smallexample ++$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | ... ++@end smallexample ++ ++The second @command{tr} command operates on the complement of the listed ++characters, which are all the letters, the digits, the underscore, and ++the blank. The @samp{\n} represents the newline character; it has to ++be left alone. (The @acronym{ASCII} tab character should also be included for ++good measure in a production script.) ++ ++At this point, we have data consisting of words separated by blank space. ++The words only contain alphanumeric characters (and the underscore). The ++next step is break the data apart so that we have one word per line. This ++makes the counting operation much easier, as we will see shortly. ++ ++@smallexample ++$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | ++> tr -s ' ' '\n' | ... ++@end smallexample ++ ++This command turns blanks into newlines. The @option{-s} option squeezes ++multiple newline characters in the output into just one. This helps us ++avoid blank lines. (The @samp{>} is the shell's ``secondary prompt.'' ++This is what the shell prints when it notices you haven't finished ++typing in all of a command.) ++ ++We now have data consisting of one word per line, no punctuation, all one ++case. We're ready to count each word: ++ ++@smallexample ++$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | ++> tr -s ' ' '\n' | sort | uniq -c | ... ++@end smallexample ++ ++At this point, the data might look something like this: ++ ++@example ++ 60 a ++ 2 able ++ 6 about ++ 1 above ++ 2 accomplish ++ 1 acquire ++ 1 actually ++ 2 additional ++@end example ++ ++The output is sorted by word, not by count! What we want is the most ++frequently used words first. Fortunately, this is easy to accomplish, ++with the help of two more @command{sort} options: ++ ++@table @code ++@item -n ++do a numeric sort, not a textual one ++ ++@item -r ++reverse the order of the sort ++@end table ++ ++The final pipeline looks like this: ++ ++@smallexample ++$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | ++> tr -s ' ' '\n' | sort | uniq -c | sort -n -r ++@print{} 156 the ++@print{} 60 a ++@print{} 58 to ++@print{} 51 of ++@print{} 51 and ++@dots{} ++@end smallexample ++ ++Whew! That's a lot to digest. Yet, the same principles apply. With six ++commands, on two lines (really one long one split for convenience), we've ++created a program that does something interesting and useful, in much ++less time than we could have written a C program to do the same thing. ++ ++A minor modification to the above pipeline can give us a simple spelling ++checker! To determine if you've spelled a word correctly, all you have to ++do is look it up in a dictionary. If it is not there, then chances are ++that your spelling is incorrect. So, we need a dictionary. ++The conventional location for a dictionary is @file{/usr/dict/words}. ++On my GNU/Linux system,@footnote{Redhat Linux 6.1, for the November 2000 ++revision of this article.} ++this is a sorted, 45,402 word dictionary. ++ ++Now, how to compare our file with the dictionary? As before, we generate ++a sorted list of words, one per line: ++ ++@smallexample ++$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | ++> tr -s ' ' '\n' | sort -u | ... ++@end smallexample ++ ++Now, all we need is a list of words that are @emph{not} in the ++dictionary. Here is where the @command{comm} command comes in. ++ ++@smallexample ++$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | ++> tr -s ' ' '\n' | sort -u | ++> comm -23 - /usr/dict/words ++@end smallexample ++ ++The @option{-2} and @option{-3} options eliminate lines that are only in the ++dictionary (the second file), and lines that are in both files. Lines ++only in the first file (standard input, our stream of words), are ++words that are not in the dictionary. These are likely candidates for ++spelling errors. This pipeline was the first cut at a production ++spelling checker on Unix. ++ ++There are some other tools that deserve brief mention. ++ ++@table @command ++@item grep ++search files for text that matches a regular expression ++ ++@item wc ++count lines, words, characters ++ ++@item tee ++a T-fitting for data pipes, copies data to files and to standard output ++ ++@item sed ++the stream editor, an advanced tool ++ ++@item awk ++a data manipulation language, another advanced tool ++@end table ++ ++The software tools philosophy also espoused the following bit of ++advice: ``Let someone else do the hard part.'' This means, take ++something that gives you most of what you need, and then massage it the ++rest of the way until it's in the form that you want. ++ ++To summarize: ++ ++@enumerate 1 ++@item ++Each program should do one thing well. No more, no less. ++ ++@item ++Combining programs with appropriate plumbing leads to results where ++the whole is greater than the sum of the parts. It also leads to novel ++uses of programs that the authors might never have imagined. ++ ++@item ++Programs should never print extraneous header or trailer data, since these ++could get sent on down a pipeline. (A point we didn't mention earlier.) ++ ++@item ++Let someone else do the hard part. ++ ++@item ++Know your toolbox! Use each program appropriately. If you don't have an ++appropriate tool, build one. ++@end enumerate ++ ++As of this writing, all the programs we've discussed are available via ++anonymous @command{ftp} from: @* ++@uref{ftp://gnudist.gnu.org/textutils/textutils-1.22.tar.gz}. (There may ++be more recent versions available now.) ++ ++None of what I have presented in this column is new. The Software Tools ++philosophy was first introduced in the book @cite{Software Tools}, by ++Brian Kernighan and P.J. Plauger (Addison-Wesley, ISBN 0-201-03669-X). ++This book showed how to write and use software tools. It was written in ++1976, using a preprocessor for FORTRAN named @command{ratfor} (RATional ++FORtran). At the time, C was not as ubiquitous as it is now; FORTRAN ++was. The last chapter presented a @command{ratfor} to FORTRAN ++processor, written in @command{ratfor}. @command{ratfor} looks an awful ++lot like C; if you know C, you won't have any problem following the ++code. ++ ++In 1981, the book was updated and made available as @cite{Software Tools ++in Pascal} (Addison-Wesley, ISBN 0-201-10342-7). Both books are ++still in print and are well worth ++reading if you're a programmer. They certainly made a major change in ++how I view programming. ++ ++The programs in both books are available from ++@uref{http://cm.bell-labs.com/who/bwk, Brian Kernighan's home page}. ++For a number of years, there was an active ++Software Tools Users Group, whose members had ported the original ++@command{ratfor} programs to essentially every computer system with a ++FORTRAN compiler. The popularity of the group waned in the middle 1980s ++as Unix began to spread beyond universities. ++ ++With the current proliferation of GNU code and other clones of Unix programs, ++these programs now receive little attention; modern C versions are ++much more efficient and do more than these programs do. Nevertheless, as ++exposition of good programming style, and evangelism for a still-valuable ++philosophy, these books are unparalleled, and I recommend them highly. ++ ++Acknowledgment: I would like to express my gratitude to Brian Kernighan ++of Bell Labs, the original Software Toolsmith, for reviewing this column. ++ ++@node GNU Free Documentation License ++@appendix GNU Free Documentation License ++ ++@include fdl.texi ++ ++@node Concept index ++@unnumbered Index ++ ++@printindex cp ++ ++@bye ++ ++@c Local variables: ++@c texinfo-column-for-description: 32 ++@c End: +diff -urNp coreutils-8.0-orig/src/Makefile.am coreutils-8.0/src/Makefile.am +--- coreutils-8.0-orig/src/Makefile.am 2009-09-21 14:29:33.000000000 +0200 ++++ coreutils-8.0/src/Makefile.am 2009-10-07 10:04:27.000000000 +0200 +@@ -154,7 +154,7 @@ tail_LDADD = $(nanosec_libs) # If necessary, add -lm to resolve use of pow in lib/strtod.c. uptime_LDADD = $(LDADD) $(POW_LIB) $(GETLOADAVG_LIBS) @@ -9,9 +16369,494 @@ dir_LDADD += $(LIB_ACL) ls_LDADD += $(LIB_ACL) ---- coreutils-6.7/src/su.c.pam 2007-01-09 17:00:01.000000000 +0000 -+++ coreutils-6.7/src/su.c 2007-01-09 17:16:43.000000000 +0000 -@@ -38,6 +38,16 @@ +diff -urNp coreutils-8.0-orig/src/Makefile.am.orig coreutils-8.0/src/Makefile.am.orig +--- coreutils-8.0-orig/src/Makefile.am.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/Makefile.am.orig 2009-09-21 14:29:33.000000000 +0200 +@@ -0,0 +1,480 @@ ++## Process this file with automake to produce Makefile.in -*-Makefile-*- ++ ++## Copyright (C) 1990, 1991, 1993-2009 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 . ++ ++# These are the names of programs that are not installed by default. ++# This list is *not* intended for programs like who, nice, chroot, etc., ++# that are built only when certain requisite system features are detected. ++# Hence, if you want to install programs from this list anyway, say A and B, ++# use --enable-install-program=A,B ++no_install__progs = \ ++ arch hostname su ++ ++build_if_possible__progs = \ ++ chroot df hostid nice pinky stdbuf libstdbuf.so stty su uname uptime users who ++ ++AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS) ++ ++EXTRA_PROGRAMS = \ ++ $(no_install__progs) \ ++ $(build_if_possible__progs) \ ++ [ chcon chgrp chown chmod cp dd dircolors du \ ++ ginstall link ln dir vdir ls mkdir \ ++ mkfifo mknod mktemp \ ++ mv nohup readlink rm rmdir shred stat sync touch unlink \ ++ cat cksum comm csplit cut expand fmt fold head join groups md5sum \ ++ nl od paste pr ptx sha1sum sha224sum sha256sum sha384sum sha512sum \ ++ shuf sort split sum tac tail tr tsort unexpand uniq wc \ ++ basename date dirname echo env expr factor false \ ++ id kill logname pathchk printenv printf pwd \ ++ runcon seq sleep tee \ ++ test timeout true truncate tty whoami yes \ ++ base64 ++ ++bin_PROGRAMS = $(OPTIONAL_BIN_PROGS) ++ ++noinst_PROGRAMS = setuidgid getlimits ++ ++pkglib_PROGRAMS = $(OPTIONAL_PKGLIB_PROGS) ++ ++noinst_HEADERS = \ ++ chown-core.h \ ++ copy.h \ ++ cp-hash.h \ ++ dircolors.h \ ++ fs.h \ ++ group-list.h \ ++ ls.h \ ++ operand2sig.h \ ++ prog-fprintf.h \ ++ remove.h \ ++ system.h \ ++ wheel-size.h \ ++ wheel.h \ ++ uname.h ++ ++EXTRA_DIST = dcgen dircolors.hin tac-pipe.c \ ++ wheel-gen.pl extract-magic c99-to-c89.diff ++BUILT_SOURCES = ++CLEANFILES = $(SCRIPTS) su ++ ++# Also remove these sometimes-built programs. ++# For example, even when excluded, they're built via sc_check-AUTHORS. ++CLEANFILES += $(no_install__progs) ++ ++AM_CPPFLAGS = -I$(top_srcdir)/lib ++ ++noinst_LIBRARIES = libver.a ++nodist_libver_a_SOURCES = version.c version.h ++ ++# Sometimes, the expansion of $(LIBINTL) includes -lc which may ++# include modules defining variables like `optind', so libcoreutils.a ++# must precede $(LIBINTL) in order to ensure we use GNU getopt. ++# But libcoreutils.a must also follow $(LIBINTL), since libintl uses ++# replacement functions defined in libcoreutils.a. ++LDADD = libver.a ../lib/libcoreutils.a $(LIBINTL) ../lib/libcoreutils.a ++ ++cat_LDADD = $(LDADD) ++df_LDADD = $(LDADD) ++du_LDADD = $(LDADD) ++getlimits_LDADD = $(LDADD) ++ptx_LDADD = $(LDADD) ++split_LDADD = $(LDADD) ++stdbuf_LDADD = $(LDADD) ++timeout_LDADD = $(LDADD) ++truncate_LDADD = $(LDADD) ++ ++# for eaccess in lib/euidaccess.c. ++chcon_LDADD = $(LDADD) $(LIB_SELINUX) ++cp_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX) ++ginstall_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX) ++mkdir_LDADD = $(LDADD) $(LIB_SELINUX) ++mkfifo_LDADD = $(LDADD) $(LIB_SELINUX) ++mknod_LDADD = $(LDADD) $(LIB_SELINUX) ++mv_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX) ++runcon_LDADD = $(LDADD) $(LIB_SELINUX) ++pathchk_LDADD = $(LDADD) $(LIB_EACCESS) ++rm_LDADD = $(LDADD) $(LIB_EACCESS) ++test_LDADD = $(LDADD) $(LIB_EACCESS) ++# This is for the '[' program. Automake transliterates '[' to '_'. ++__LDADD = $(LDADD) $(LIB_EACCESS) ++ ++# for clock_gettime and fdatasync ++dd_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC) ++dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) ++id_LDADD = $(LDADD) $(LIB_SELINUX) ++ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) ++mktemp_LDADD = $(LDADD) $(LIB_GETHRXTIME) ++pr_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) ++shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC) ++shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME) ++tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) ++vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) ++ ++## If necessary, add -lm to resolve use of pow in lib/strtod.c. ++sort_LDADD = $(LDADD) $(POW_LIB) $(LIB_GETHRXTIME) ++ ++# for get_date and gettime ++date_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) ++touch_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) ++ ++# If necessary, add -lm to resolve use of pow in lib/strtod.c. ++# If necessary, add -liconv to resolve use of iconv in lib/unicodeio.c. ++printf_LDADD = $(LDADD) $(POW_LIB) $(LIBICONV) ++ ++# If necessary, add -lm to resolve use of pow in lib/strtod.c. ++seq_LDADD = $(LDADD) $(POW_LIB) ++ ++# If necessary, add libraries to resolve the `pow' reference in lib/strtod.c ++# and the `nanosleep' reference in lib/xnanosleep.c. ++nanosec_libs = $(LDADD) $(POW_LIB) $(LIB_NANOSLEEP) ++ ++# for various GMP functions ++expr_LDADD = $(LDADD) $(LIB_GMP) ++ ++# for various GMP functions ++factor_LDADD = $(LDADD) $(LIB_GMP) ++ ++sleep_LDADD = $(nanosec_libs) ++tail_LDADD = $(nanosec_libs) ++ ++# If necessary, add -lm to resolve use of pow in lib/strtod.c. ++uptime_LDADD = $(LDADD) $(POW_LIB) $(GETLOADAVG_LIBS) ++ ++su_LDADD = $(LDADD) $(LIB_CRYPT) ++ ++dir_LDADD += $(LIB_ACL) ++ls_LDADD += $(LIB_ACL) ++vdir_LDADD += $(LIB_ACL) ++cp_LDADD += $(LIB_ACL) $(LIB_XATTR) ++mv_LDADD += $(LIB_ACL) $(LIB_XATTR) ++ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR) ++ ++stat_LDADD = $(LDADD) $(LIB_SELINUX) ++ ++# Append $(LIBICONV) to each program that uses proper_name_utf8. ++cat_LDADD += $(LIBICONV) ++cp_LDADD += $(LIBICONV) ++df_LDADD += $(LIBICONV) ++du_LDADD += $(LIBICONV) ++getlimits_LDADD += $(LIBICONV) ++ptx_LDADD += $(LIBICONV) ++split_LDADD += $(LIBICONV) ++stdbuf_LDADD += $(LIBICONV) ++timeout_LDADD += $(LIBICONV) ++truncate_LDADD += $(LIBICONV) ++ ++# programs that use getaddrinfo (e.g., via canon_host) ++pinky_LDADD = $(LDADD) $(GETADDRINFO_LIB) ++who_LDADD = $(LDADD) $(GETADDRINFO_LIB) ++ ++$(PROGRAMS): ../lib/libcoreutils.a ++ ++# Get the release year from ../lib/version-etc.c. ++RELEASE_YEAR = \ ++ `sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \ ++ $(top_srcdir)/lib/version-etc.c` ++ ++all-local: su$(EXEEXT) ++ ++installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'` ++ ++setuid_root_mode = a=rx,u+s ++ ++install_su = \ ++ if test "$(INSTALL_SU)" = yes; then \ ++ p=su; \ ++ echo " $(INSTALL_PROGRAM) $$p $(installed_su)"; \ ++ $(INSTALL_PROGRAM) $$p $(installed_su); \ ++ echo " chown root $(installed_su)"; \ ++ chown root $(installed_su); \ ++ echo " chmod $(setuid_root_mode) $(installed_su)"; \ ++ chmod $(setuid_root_mode) $(installed_su); \ ++ else \ ++ :; \ ++ fi ++ ++install-root: su$(EXEEXT) ++ @$(install_su) ++ ++install-exec-hook: su$(EXEEXT) ++ @if test "$(INSTALL_SU)" = yes; then \ ++ TMPFILE=$(DESTDIR)$(bindir)/.su-$$$$; \ ++ rm -f $$TMPFILE; \ ++ echo > $$TMPFILE; \ ++## See if we can create a setuid root executable in $(bindir). ++## If not, then don't even try to install su. ++ can_create_suid_root_executable=no; \ ++ chown root $$TMPFILE > /dev/null 2>&1 \ ++ && chmod $(setuid_root_mode) $$TMPFILE > /dev/null 2>&1 \ ++ && can_create_suid_root_executable=yes; \ ++ rm -f $$TMPFILE; \ ++ if test $$can_create_suid_root_executable = yes; then \ ++ $(install_su); \ ++ else \ ++ echo "WARNING: insufficient access; not installing su"; \ ++ echo "NOTE: to install su, run 'make install-root' as root"; \ ++ rm -f $(installed_su); \ ++ fi; \ ++ else :; \ ++ fi ++ ++uninstall-local: ++# Remove su only if it's one we installed. ++ @if test "$(INSTALL_SU)" = yes; then \ ++ if grep '$(PACKAGE_NAME)' $(installed_su) > /dev/null 2>&1; then \ ++ echo " rm -f $(installed_su)"; \ ++ rm -f $(installed_su); \ ++ else :; \ ++ fi; \ ++ fi ++ ++copy_sources = copy.c cp-hash.c ++ ++# Use `ginstall' in the definition of PROGRAMS and in dependencies to avoid ++# confusion with the `install' target. The install rule transforms `ginstall' ++# to install before applying any user-specified name transformations. ++ ++transform = s/ginstall/install/; $(program_transform_name) ++ginstall_SOURCES = install.c prog-fprintf.c $(copy_sources) ++ ++# This is for the '[' program. Automake transliterates '[' to '_'. ++__SOURCES = lbracket.c ++ ++cp_SOURCES = cp.c $(copy_sources) ++dir_SOURCES = ls.c ls-dir.c ++vdir_SOURCES = ls.c ls-vdir.c ++id_SOURCES = id.c group-list.c ++groups_SOURCES = groups.c group-list.c ++ln_SOURCES = ln.c ++ls_SOURCES = ls.c ls-ls.c ++chown_SOURCES = chown.c chown-core.c ++chgrp_SOURCES = chgrp.c chown-core.c ++kill_SOURCES = kill.c operand2sig.c ++timeout_SOURCES = timeout.c operand2sig.c ++ ++mv_SOURCES = mv.c remove.c $(copy_sources) ++rm_SOURCES = rm.c remove.c ++ ++mkdir_SOURCES = mkdir.c prog-fprintf.c ++rmdir_SOURCES = rmdir.c prog-fprintf.c ++ ++uname_SOURCES = uname.c uname-uname.c ++arch_SOURCES = uname.c uname-arch.c ++ ++md5sum_SOURCES = md5sum.c ++md5sum_CPPFLAGS = -DHASH_ALGO_MD5=1 $(AM_CPPFLAGS) ++sha1sum_SOURCES = md5sum.c ++sha1sum_CPPFLAGS = -DHASH_ALGO_SHA1=1 $(AM_CPPFLAGS) ++sha224sum_SOURCES = md5sum.c ++sha224sum_CPPFLAGS = -DHASH_ALGO_SHA224=1 $(AM_CPPFLAGS) ++sha256sum_SOURCES = md5sum.c ++sha256sum_CPPFLAGS = -DHASH_ALGO_SHA256=1 $(AM_CPPFLAGS) ++sha384sum_SOURCES = md5sum.c ++sha384sum_CPPFLAGS = -DHASH_ALGO_SHA384=1 $(AM_CPPFLAGS) ++sha512sum_SOURCES = md5sum.c ++sha512sum_CPPFLAGS = -DHASH_ALGO_SHA512=1 $(AM_CPPFLAGS) ++ ++ginstall_CPPFLAGS = -DENABLE_MATCHPATHCON=1 $(AM_CPPFLAGS) ++ ++# Ensure we don't link against libcoreutils.a as that lib is ++# not compiled with -fPIC which causes issues on 64 bit at least ++libstdbuf_so_LDADD = ++ ++# Note libstdbuf is only compiled if GCC is available ++# (as per the check in configure.ac), so these flags should be available. ++# libtool is probably required to relax this dependency. ++libstdbuf_so_LDFLAGS = -shared ++libstdbuf_so_CFLAGS = -fPIC $(AM_CFLAGS) ++ ++editpl = sed -e 's,@''PERL''@,$(PERL),g' ++ ++BUILT_SOURCES += dircolors.h ++dircolors.h: dcgen dircolors.hin ++ $(AM_V_GEN)rm -f $@ $@-t ++ $(AM_V_at)$(PERL) -w -- $(srcdir)/dcgen $(srcdir)/dircolors.hin > $@-t ++ $(AM_V_at)chmod a-w $@-t ++ $(AM_V_at)mv $@-t $@ ++ ++wheel_size = 5 ++ ++BUILT_SOURCES += wheel-size.h ++wheel-size.h: Makefile.am ++ $(AM_V_GEN)rm -f $@ $@-t ++ $(AM_V_at)echo '#define WHEEL_SIZE $(wheel_size)' > $@-t ++ $(AM_V_at)chmod a-w $@-t ++ $(AM_V_at)mv $@-t $@ ++ ++BUILT_SOURCES += wheel.h ++wheel.h: wheel-gen.pl Makefile.am ++ $(AM_V_GEN)rm -f $@ $@-t ++ $(AM_V_at)$(srcdir)/wheel-gen.pl $(wheel_size) > $@-t ++ $(AM_V_at)chmod a-w $@-t ++ $(AM_V_at)mv $@-t $@ ++ ++# false exits nonzero even with --help or --version. ++# test doesn't support --help or --version. ++# Tell automake to exempt then from that installcheck test. ++AM_INSTALLCHECK_STD_OPTIONS_EXEMPT = false test ++ ++BUILT_SOURCES += fs.h ++fs.h: stat.c extract-magic ++ $(AM_V_GEN)rm -f $@ ++ $(AM_V_at)$(PERL) $(srcdir)/extract-magic $(srcdir)/stat.c > $@t ++ $(AM_V_at)chmod a-w $@t ++ $(AM_V_at)mv $@t $@ ++ ++BUILT_SOURCES += version.c ++version.c: Makefile ++ $(AM_V_GEN)rm -f $@ ++ $(AM_V_at)printf '#include \n' > $@t ++ $(AM_V_at)printf 'char const *Version = "$(PACKAGE_VERSION)";\n' >> $@t ++ $(AM_V_at)chmod a-w $@t ++ $(AM_V_at)mv $@t $@ ++ ++BUILT_SOURCES += version.h ++version.h: Makefile ++ $(AM_V_GEN)rm -f $@ ++ $(AM_V_at)printf 'extern char const *Version;\n' > $@t ++ $(AM_V_at)chmod a-w $@t ++ $(AM_V_at)mv $@t $@ ++ ++DISTCLEANFILES = version.c version.h ++MAINTAINERCLEANFILES = $(BUILT_SOURCES) ++ ++# Sort in traditional ASCII order, regardless of the current locale; ++# otherwise we may get into trouble with distinct strings that the ++# current locale considers to be equal. ++ASSORT = LC_ALL=C sort ++ ++all_programs = \ ++ $(bin_PROGRAMS) \ ++ $(bin_SCRIPTS) \ ++ $(EXTRA_PROGRAMS) ++ ++built_programs.list: ++ @echo $(bin_PROGRAMS) $(bin_SCRIPTS) | tr ' ' '\n' \ ++ | sed -e 's,$(EXEEXT)$$,,' | $(ASSORT) -u | tr '\n' ' ' ++ ++all_programs.list: ++ @echo $(all_programs) | tr ' ' '\n' | sed -e 's,$(EXEEXT)$$,,' \ ++ | $(ASSORT) -u ++ ++# This is required because we have broken inter-directory dependencies: ++# in order to generate all man pages, even those for which we don't ++# install a binary, require that all programs be built at distribution time. ++dist-hook: $(all_programs) ++ ++pm = progs-makefile ++pr = progs-readme ++# Ensure that the list of programs in README matches the list ++# of programs we can build. ++check: check-README check-duplicate-no-install ++.PHONY: check-README ++check-README: ++ $(AM_V_GEN)rm -rf $(pr) $(pm) ++ $(AM_V_at)echo $(all_programs) \ ++ | tr -s ' ' '\n' | sed -e 's,$(EXEEXT)$$,,;s/ginstall/install/' \ ++ | sed /libstdbuf/d \ ++ | $(ASSORT) -u > $(pm) && \ ++ sed -n '/^The programs .* are:/,/^[a-zA-Z]/p' $(top_srcdir)/README \ ++ | sed -n '/^ */s///p' | tr -s ' ' '\n' > $(pr) ++ $(AM_V_at)diff $(pm) $(pr) && rm -rf $(pr) $(pm) ++ ++# Ensure that a by-default-not-installed program (listed in ++# $(no_install__progs) is not also listed in $(EXTRA_PROGRAMS), because ++# if that were to happen, it *would* be installed by default. ++.PHONY: check-duplicate-no-install ++check-duplicate-no-install: tr ++ $(AM_V_GEN)test -z "`echo '$(EXTRA_PROGRAMS)'| ./tr ' ' '\n' | uniq -d`" ++ ++# Ensure that the list of programs and author names is accurate. ++# We need a UTF8 locale. If a lack of locale support or a missing ++# translation inhibits printing of UTF-8 names, just skip this test. ++au_dotdot = authors-dotdot ++au_actual = authors-actual ++.PHONY: sc_check-AUTHORS ++sc_check-AUTHORS: $(all_programs) ++ $(AM_V_GEN)locale=en_US.UTF-8; \ ++ LC_ALL="$$locale" ./cat --version \ ++ | grep ' Torbjorn ' > /dev/null \ ++ && { echo "$@: skipping this check"; exit 0; }; \ ++ rm -f $(au_actual) $(au_dotdot); \ ++ for i in `ls $(all_programs) | sed -e 's,$(EXEEXT)$$,,' \ ++ | sed /libstdbuf/d \ ++ | $(ASSORT) -u`; do \ ++ test "$$i" = '[' && continue; \ ++ exe=$$i; \ ++ if test "$$i" = install; then \ ++ exe=ginstall; \ ++ elif test "$$i" = test; then \ ++ exe='['; \ ++ fi; \ ++ LC_ALL="$$locale" ./$$exe --version \ ++ | perl -0 -pi -e 's/,\n/, /gm' \ ++ | sed -n -e '/Written by /{ s//'"$$i"': /;' \ ++ -e 's/,* and /, /; s/\.$$//; p; }'; \ ++ done > $(au_actual) && \ ++ sed -n '/^[^ ][^ ]*:/p' $(top_srcdir)/AUTHORS > $(au_dotdot) && \ ++ diff $(au_actual) $(au_dotdot) && rm -f $(au_actual) $(au_dotdot) ++ ++# The following rule is not designed to be portable, ++# and relies on tools that not everyone has. ++ ++# Most functions in src/*.c should have static scope. ++# Any that don't must be marked with `extern', but `main' ++# and `usage' are exceptions. They're always extern, but ++# don't need to be marked. Also functions starting with __ ++# are exempted due to possibly being added by the compiler ++# (when compiled as a shared library for example). ++# ++# The second nm|grep checks for file-scope variables with `extern' scope. ++.PHONY: sc_tight_scope ++sc_tight_scope: $(bin_PROGRAMS) ++ $(AM_V_GEN)t=exceptions-$$$$; \ ++ trap "s=$$?; rm -f $$t; exit $$s" 0 1 2 13 15; \ ++ src=`for f in $(SOURCES); do \ ++ test -f $$f && d= || d=$(srcdir)/; echo $$d$$f; done`; \ ++ hdr=`for f in $(noinst_HEADERS); do \ ++ test -f $$f && d= || d=$(srcdir)/; echo $$d$$f; done`; \ ++ ( printf 'main\nusage\n_.*\n'; \ ++ grep -h -A1 '^extern .*[^;]$$' $$src \ ++ | grep -vE '^(extern |--)' | sed 's/ .*//'; \ ++ perl -ne '/^extern (?:enum )?\S+ (\S*) \(/ and print "$$1\n"' $$hdr; \ ++ ) | $(ASSORT) -u | sed 's/^/^/;s/$$/$$/' > $$t; \ ++ nm -e *.$(OBJEXT) \ ++ | sed -n 's/.* T //p' \ ++ | sed 's/^_//' \ ++ | grep -Ev -f $$t && \ ++ { echo 'the above functions should have static scope' 1>&2; \ ++ exit 1; } || : ; \ ++ ( printf '^program_name$$\n'; \ ++ perl -ne '/^extern .*?\**(\w+);/ and print "^$$1\$$\n"' \ ++ $$hdr *.h ) | $(ASSORT) -u > $$t; \ ++ nm -e *.$(OBJEXT) \ ++ | sed -n 's/.* [BD] //p' \ ++ | sed 's/^_//' \ ++ | grep -Ev -f $$t && \ ++ { echo 'the above variables should have static scope' 1>&2; \ ++ exit 1; } || : ++ ++# Use the just-built ./ginstall, when not cross-compiling. ++if CROSS_COMPILING ++cu_install_program = @INSTALL_PROGRAM@ ++else ++cu_install_program = ./ginstall ++endif ++INSTALL_PROGRAM = $(cu_install_program) +diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c +--- coreutils-8.0-orig/src/su.c 2009-10-07 10:03:29.000000000 +0200 ++++ coreutils-8.0/src/su.c 2009-10-07 10:04:27.000000000 +0200 +@@ -37,6 +37,16 @@ restricts who can su to UID 0 accounts. RMS considers that to be fascist. @@ -28,9 +16873,9 @@ Compile-time options: -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. -@@ -59,6 +69,15 @@ - prototype (returning `int') in . */ - #define getusershell _getusershell_sys_proto_ +@@ -53,6 +63,15 @@ + #include + #include +#ifdef USE_PAM +# include @@ -44,7 +16889,7 @@ #include "system.h" #include "getpass.h" -@@ -128,12 +147,19 @@ +@@ -120,12 +139,19 @@ /* The user to become if none is specified. */ #define DEFAULT_USER "root" @@ -65,7 +16910,7 @@ /* If true, pass the `-f' option to the subshell. */ static bool fast_startup; -@@ -225,7 +251,26 @@ +@@ -211,7 +237,26 @@ log_su (struct passwd const *pw, bool su } #endif @@ -92,7 +16937,7 @@ Return true if the user gives the correct password for entry PW, false if not. Return true without asking for a password if run by UID 0 or if PW has an empty password. */ -@@ -233,6 +278,44 @@ +@@ -219,6 +264,44 @@ log_su (struct passwd const *pw, bool su static bool correct_password (const struct passwd *pw) { @@ -137,7 +16982,7 @@ char *unencrypted, *encrypted, *correct; #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP /* Shadow passwd stuff for SVR3 and maybe other systems. */ -@@ -257,6 +340,7 @@ +@@ -243,6 +326,7 @@ correct_password (const struct passwd *p encrypted = crypt (unencrypted, correct); memset (unencrypted, 0, strlen (unencrypted)); return STREQ (encrypted, correct); @@ -145,7 +16990,7 @@ } /* Update `environ' for the new shell based on PW, with SHELL being -@@ -270,12 +354,18 @@ +@@ -256,12 +340,18 @@ modify_environment (const struct passwd /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. Unset all other environment variables. */ char const *term = getenv ("TERM"); @@ -164,7 +17009,7 @@ xsetenv ("HOME", pw->pw_dir); xsetenv ("SHELL", shell); xsetenv ("USER", pw->pw_name); -@@ -308,8 +398,13 @@ +@@ -294,8 +384,13 @@ change_identity (const struct passwd *pw { #ifdef HAVE_INITGROUPS errno = 0; @@ -179,7 +17024,7 @@ endgrent (); #endif if (setgid (pw->pw_gid)) -@@ -318,6 +413,31 @@ +@@ -304,6 +399,31 @@ change_identity (const struct passwd *pw error (EXIT_FAILURE, errno, _("cannot set user id")); } @@ -211,7 +17056,7 @@ /* Run SHELL, or DEFAULT_SHELL if SHELL is empty. If COMMAND is nonzero, pass it to the shell with the -c option. Pass ADDITIONAL_ARGS to the shell as more arguments; there -@@ -325,17 +445,49 @@ +@@ -311,17 +431,49 @@ change_identity (const struct passwd *pw static void run_shell (char const *shell, char const *command, char **additional_args, @@ -262,7 +17107,7 @@ shell_basename = last_component (shell); arg0 = xmalloc (strlen (shell_basename) + 2); arg0[0] = '-'; -@@ -360,6 +512,66 @@ +@@ -346,6 +498,66 @@ run_shell (char const *shell, char const error (0, errno, "%s", shell); exit (exit_status); } @@ -329,7 +17174,7 @@ } /* Return true if SHELL is a restricted shell (one not returned by -@@ -527,9 +739,9 @@ +@@ -513,9 +725,9 @@ main (int argc, char **argv) shell = xstrdup (shell ? shell : pw->pw_shell); modify_environment (pw, shell); @@ -342,78 +17187,528 @@ - run_shell (shell, command, argv + optind, MAX (0, argc - optind)); + run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); } ---- coreutils-6.7/doc/coreutils.texi.pam 2006-10-27 15:30:48.000000000 +0100 -+++ coreutils-6.7/doc/coreutils.texi 2007-01-09 17:00:01.000000000 +0000 -@@ -13395,8 +13395,11 @@ - @findex syslog - @command{su} can optionally be compiled to use @code{syslog} to report - failed, and optionally successful, @command{su} attempts. (If the system --supports @code{syslog}.) However, GNU @command{su} does not check if the --user is a member of the @code{wheel} group; see below. -+supports @code{syslog}.) +diff -urNp coreutils-8.0-orig/src/su.c.orig coreutils-8.0/src/su.c.orig +--- coreutils-8.0-orig/src/su.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/su.c.orig 2009-10-07 10:03:29.000000000 +0200 +@@ -0,0 +1,521 @@ ++/* su for GNU. Run a shell with substitute user and group IDs. ++ Copyright (C) 1992-2006, 2008-2009 Free Software Foundation, Inc. + -+This version of @command{su} has support for using PAM for -+authentication. You can edit @file{/etc/pam.d/su} to customize its -+behaviour. - - The program accepts the following options. Also see @ref{Common options}. - -@@ -12815,6 +12815,8 @@ - @env{PATH} to a compiled-in default value. Change to @var{user}'s home - directory. Prepend @samp{-} to the shell's name, intended to make it - read its login startup file(s). -+Additionaly @env{DISPLAY} and @env{XAUTHORITY} environment variables -+are preserved as well for PAM functionality. - - @item -m - @itemx -p -@@ -13477,33 +13480,6 @@ - the exit status of the subshell otherwise - @end display - --@cindex wheel group, not supported --@cindex group wheel, not supported --@cindex fascism --@subsection Why GNU @command{su} does not support the @samp{wheel} group -- --(This section is by Richard Stallman.) -- --@cindex Twenex --@cindex MIT AI lab --Sometimes a few of the users try to hold total power over all the --rest. For example, in 1984, a few users at the MIT AI lab decided to --seize power by changing the operator password on the Twenex system and --keeping it secret from everyone else. (I was able to thwart this coup --and give power back to the users by patching the kernel, but I --wouldn't know how to do that in Unix.) -- --However, occasionally the rulers do tell someone. Under the usual --@command{su} mechanism, once someone learns the root password who --sympathizes with the ordinary users, he or she can tell the rest. The --``wheel group'' feature would make this impossible, and thus cement the --power of the rulers. -- --I'm on the side of the masses, not that of the rulers. If you are --used to supporting the bosses and sysadmins in whatever they do, you --might find this idea strange at first. -- -- - @node timeout invocation - @section @command{timeout}: Run a command with a time limit - ---- coreutils-7.1/configure.ac.pam -+++ coreutils-7.1/configure.ac -@@ -44,6 +44,13 @@ - AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) - fi - -+dnl Give the chance to enable PAM -+AC_ARG_ENABLE(pam, dnl -+[ --enable-pam Enable use of the PAM libraries], -+[AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) -+LIB_PAM="-ldl -lpam -lpam_misc" -+AC_SUBST(LIB_PAM)]) ++ 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. + - AC_FUNC_FORK - - optional_bin_progs= ++ 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 . */ ++ ++/* Run a shell with the real and effective UID and GID and groups ++ of USER, default `root'. ++ ++ The shell run is taken from USER's password entry, /bin/sh if ++ none is specified there. If the account has a password, su ++ prompts for a password unless run by a user with real UID 0. ++ ++ Does not change the current directory. ++ Sets `HOME' and `SHELL' from the password entry for USER, and if ++ USER is not root, sets `USER' and `LOGNAME' to USER. ++ The subshell is not a login shell. ++ ++ If one or more ARGs are given, they are passed as additional ++ arguments to the subshell. ++ ++ Does not handle /bin/sh or other shells specially ++ (setting argv[0] to "-su", passing -c only to certain shells, etc.). ++ I don't see the point in doing that, and it's ugly. ++ ++ This program intentionally does not support a "wheel group" that ++ restricts who can su to UID 0 accounts. RMS considers that to ++ be fascist. ++ ++ Compile-time options: ++ -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. ++ -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. ++ ++ -DSYSLOG_NON_ROOT Log all su's, not just those to root (UID 0). ++ Never logs attempted su's to nonexistent accounts. ++ ++ Written by David MacKenzie . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "system.h" ++#include "getpass.h" ++ ++#if HAVE_SYSLOG_H && HAVE_SYSLOG ++# include ++#else ++# undef SYSLOG_SUCCESS ++# undef SYSLOG_FAILURE ++# undef SYSLOG_NON_ROOT ++#endif ++ ++#if HAVE_SYS_PARAM_H ++# include ++#endif ++ ++#ifndef HAVE_ENDGRENT ++# define endgrent() ((void) 0) ++#endif ++ ++#ifndef HAVE_ENDPWENT ++# define endpwent() ((void) 0) ++#endif ++ ++#if HAVE_SHADOW_H ++# include ++#endif ++ ++#include "error.h" ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "su" ++ ++#define AUTHORS proper_name ("David MacKenzie") ++ ++#if HAVE_PATHS_H ++# include ++#endif ++ ++/* The default PATH for simulated logins to non-superuser accounts. */ ++#ifdef _PATH_DEFPATH ++# define DEFAULT_LOGIN_PATH _PATH_DEFPATH ++#else ++# define DEFAULT_LOGIN_PATH ":/usr/ucb:/bin:/usr/bin" ++#endif ++ ++/* The default PATH for simulated logins to superuser accounts. */ ++#ifdef _PATH_DEFPATH_ROOT ++# define DEFAULT_ROOT_LOGIN_PATH _PATH_DEFPATH_ROOT ++#else ++# define DEFAULT_ROOT_LOGIN_PATH "/usr/ucb:/bin:/usr/bin:/etc" ++#endif ++ ++/* The default paths which get set are both bogus and oddly influenced ++ by and -D on the commands line. Just to be clear, we'll set ++ these explicitly. -ewt */ ++#undef DEFAULT_LOGIN_PATH ++#undef DEFAULT_ROOT_LOGIN_PATH ++#define DEFAULT_LOGIN_PATH "/usr/local/bin:/bin:/usr/bin" ++#define DEFAULT_ROOT_LOGIN_PATH \ ++ "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" ++ ++/* The shell to run if none is given in the user's passwd entry. */ ++#define DEFAULT_SHELL "/bin/sh" ++ ++/* The user to become if none is specified. */ ++#define DEFAULT_USER "root" ++ ++char *crypt (char const *key, char const *salt); ++ ++extern char **environ; ++ ++static void run_shell (char const *, char const *, char **, size_t) ++ ATTRIBUTE_NORETURN; ++ ++/* If true, pass the `-f' option to the subshell. */ ++static bool fast_startup; ++ ++/* If true, simulate a login instead of just starting a shell. */ ++static bool simulate_login; ++ ++/* If true, change some environment vars to indicate the user su'd to. */ ++static bool change_environment; ++ ++static struct option const longopts[] = ++{ ++ {"command", required_argument, NULL, 'c'}, ++ {"fast", no_argument, NULL, 'f'}, ++ {"login", no_argument, NULL, 'l'}, ++ {"preserve-environment", no_argument, NULL, 'p'}, ++ {"shell", required_argument, NULL, 's'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++/* Add NAME=VAL to the environment, checking for out of memory errors. */ ++ ++static void ++xsetenv (char const *name, char const *val) ++{ ++ size_t namelen = strlen (name); ++ size_t vallen = strlen (val); ++ char *string = xmalloc (namelen + 1 + vallen + 1); ++ strcpy (string, name); ++ string[namelen] = '='; ++ strcpy (string + namelen + 1, val); ++ if (putenv (string) != 0) ++ xalloc_die (); ++} ++ ++#if defined SYSLOG_SUCCESS || defined SYSLOG_FAILURE ++/* Log the fact that someone has run su to the user given by PW; ++ if SUCCESSFUL is true, they gave the correct password, etc. */ ++ ++static void ++log_su (struct passwd const *pw, bool successful) ++{ ++ const char *new_user, *old_user, *tty; ++ ++# ifndef SYSLOG_NON_ROOT ++ if (pw->pw_uid) ++ return; ++# endif ++ new_user = pw->pw_name; ++ /* The utmp entry (via getlogin) is probably the best way to identify ++ the user, especially if someone su's from a su-shell. */ ++ old_user = getlogin (); ++ if (!old_user) ++ { ++ /* getlogin can fail -- usually due to lack of utmp entry. ++ Resort to getpwuid. */ ++ struct passwd *pwd = getpwuid (getuid ()); ++ old_user = (pwd ? pwd->pw_name : ""); ++ } ++ tty = ttyname (STDERR_FILENO); ++ if (!tty) ++ tty = "none"; ++ /* 4.2BSD openlog doesn't have the third parameter. */ ++ openlog (last_component (program_name), 0 ++# ifdef LOG_AUTH ++ , LOG_AUTH ++# endif ++ ); ++ syslog (LOG_NOTICE, ++# ifdef SYSLOG_NON_ROOT ++ "%s(to %s) %s on %s", ++# else ++ "%s%s on %s", ++# endif ++ successful ? "" : "FAILED SU ", ++# ifdef SYSLOG_NON_ROOT ++ new_user, ++# endif ++ old_user, tty); ++ closelog (); ++} ++#endif ++ ++/* Ask the user for a password. ++ Return true if the user gives the correct password for entry PW, ++ false if not. Return true without asking for a password if run by UID 0 ++ or if PW has an empty password. */ ++ ++static bool ++correct_password (const struct passwd *pw) ++{ ++ char *unencrypted, *encrypted, *correct; ++#if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP ++ /* Shadow passwd stuff for SVR3 and maybe other systems. */ ++ struct spwd *sp = getspnam (pw->pw_name); ++ ++ endspent (); ++ if (sp) ++ correct = sp->sp_pwdp; ++ else ++#endif ++ correct = pw->pw_passwd; ++ ++ if (getuid () == 0 || !correct || correct[0] == '\0') ++ return true; ++ ++ unencrypted = getpass (_("Password:")); ++ if (!unencrypted) ++ { ++ error (0, 0, _("getpass: cannot open /dev/tty")); ++ return false; ++ } ++ encrypted = crypt (unencrypted, correct); ++ memset (unencrypted, 0, strlen (unencrypted)); ++ return STREQ (encrypted, correct); ++} ++ ++/* Update `environ' for the new shell based on PW, with SHELL being ++ the value for the SHELL environment variable. */ ++ ++static void ++modify_environment (const struct passwd *pw, const char *shell) ++{ ++ if (simulate_login) ++ { ++ /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. ++ Unset all other environment variables. */ ++ char const *term = getenv ("TERM"); ++ if (term) ++ term = xstrdup (term); ++ environ = xmalloc ((6 + !!term) * sizeof (char *)); ++ environ[0] = NULL; ++ if (term) ++ xsetenv ("TERM", term); ++ xsetenv ("HOME", pw->pw_dir); ++ xsetenv ("SHELL", shell); ++ xsetenv ("USER", pw->pw_name); ++ xsetenv ("LOGNAME", pw->pw_name); ++ xsetenv ("PATH", (pw->pw_uid ++ ? DEFAULT_LOGIN_PATH ++ : DEFAULT_ROOT_LOGIN_PATH)); ++ } ++ else ++ { ++ /* Set HOME, SHELL, and if not becoming a super-user, ++ USER and LOGNAME. */ ++ if (change_environment) ++ { ++ xsetenv ("HOME", pw->pw_dir); ++ xsetenv ("SHELL", shell); ++ if (pw->pw_uid) ++ { ++ xsetenv ("USER", pw->pw_name); ++ xsetenv ("LOGNAME", pw->pw_name); ++ } ++ } ++ } ++} ++ ++/* Become the user and group(s) specified by PW. */ ++ ++static void ++change_identity (const struct passwd *pw) ++{ ++#ifdef HAVE_INITGROUPS ++ errno = 0; ++ if (initgroups (pw->pw_name, pw->pw_gid) == -1) ++ error (EXIT_FAILURE, errno, _("cannot set groups")); ++ endgrent (); ++#endif ++ if (setgid (pw->pw_gid)) ++ error (EXIT_FAILURE, errno, _("cannot set group id")); ++ if (setuid (pw->pw_uid)) ++ error (EXIT_FAILURE, errno, _("cannot set user id")); ++} ++ ++/* Run SHELL, or DEFAULT_SHELL if SHELL is empty. ++ If COMMAND is nonzero, pass it to the shell with the -c option. ++ Pass ADDITIONAL_ARGS to the shell as more arguments; there ++ are N_ADDITIONAL_ARGS extra arguments. */ ++ ++static void ++run_shell (char const *shell, char const *command, char **additional_args, ++ size_t n_additional_args) ++{ ++ size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; ++ char const **args = xnmalloc (n_args, sizeof *args); ++ size_t argno = 1; ++ ++ if (simulate_login) ++ { ++ char *arg0; ++ char *shell_basename; ++ ++ shell_basename = last_component (shell); ++ arg0 = xmalloc (strlen (shell_basename) + 2); ++ arg0[0] = '-'; ++ strcpy (arg0 + 1, shell_basename); ++ args[0] = arg0; ++ } ++ else ++ args[0] = last_component (shell); ++ if (fast_startup) ++ args[argno++] = "-f"; ++ if (command) ++ { ++ args[argno++] = "-c"; ++ args[argno++] = command; ++ } ++ memcpy (args + argno, additional_args, n_additional_args * sizeof *args); ++ args[argno + n_additional_args] = NULL; ++ execv (shell, (char **) args); ++ ++ { ++ int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); ++ error (0, errno, "%s", shell); ++ exit (exit_status); ++ } ++} ++ ++/* Return true if SHELL is a restricted shell (one not returned by ++ getusershell), else false, meaning it is a standard shell. */ ++ ++static bool ++restricted_shell (const char *shell) ++{ ++ char *line; ++ ++ setusershell (); ++ while ((line = getusershell ()) != NULL) ++ { ++ if (*line != '#' && STREQ (line, shell)) ++ { ++ endusershell (); ++ return false; ++ } ++ } ++ endusershell (); ++ return true; ++} ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name); ++ fputs (_("\ ++Change the effective user id and group id to that of USER.\n\ ++\n\ ++ -, -l, --login make the shell a login shell\n\ ++ -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\ ++ -f, --fast pass -f to the shell (for csh or tcsh)\n\ ++ -m, --preserve-environment do not reset environment variables\n\ ++ -p same as -m\n\ ++ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++A mere - implies -l. If USER not given, assume root.\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int optc; ++ const char *new_user = DEFAULT_USER; ++ char *command = NULL; ++ char *shell = NULL; ++ struct passwd *pw; ++ struct passwd pw_copy; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ initialize_exit_failure (EXIT_FAILURE); ++ atexit (close_stdout); ++ ++ fast_startup = false; ++ simulate_login = false; ++ change_environment = true; ++ ++ while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1) ++ { ++ switch (optc) ++ { ++ case 'c': ++ command = optarg; ++ break; ++ ++ case 'f': ++ fast_startup = true; ++ break; ++ ++ case 'l': ++ simulate_login = true; ++ break; ++ ++ case 'm': ++ case 'p': ++ change_environment = false; ++ break; ++ ++ case 's': ++ shell = optarg; ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (EXIT_FAILURE); ++ } ++ } ++ ++ if (optind < argc && STREQ (argv[optind], "-")) ++ { ++ simulate_login = true; ++ ++optind; ++ } ++ if (optind < argc) ++ new_user = argv[optind++]; ++ ++ pw = getpwnam (new_user); ++ if (! (pw && pw->pw_name && pw->pw_name[0] && pw->pw_dir && pw->pw_dir[0] ++ && pw->pw_passwd)) ++ error (EXIT_FAILURE, 0, _("user %s does not exist"), new_user); ++ ++ /* Make a copy of the password information and point pw at the local ++ copy instead. Otherwise, some systems (e.g. GNU/Linux) would clobber ++ the static data through the getlogin call from log_su. ++ Also, make sure pw->pw_shell is a nonempty string. ++ It may be NULL when NEW_USER is a username that is retrieved via NIS (YP), ++ but that doesn't have a default shell listed. */ ++ pw_copy = *pw; ++ pw = &pw_copy; ++ pw->pw_name = xstrdup (pw->pw_name); ++ pw->pw_passwd = xstrdup (pw->pw_passwd); ++ pw->pw_dir = xstrdup (pw->pw_dir); ++ pw->pw_shell = xstrdup (pw->pw_shell && pw->pw_shell[0] ++ ? pw->pw_shell ++ : DEFAULT_SHELL); ++ endpwent (); ++ ++ if (!correct_password (pw)) ++ { ++#ifdef SYSLOG_FAILURE ++ log_su (pw, false); ++#endif ++ error (EXIT_FAILURE, 0, _("incorrect password")); ++ } ++#ifdef SYSLOG_SUCCESS ++ else ++ { ++ log_su (pw, true); ++ } ++#endif ++ ++ if (!shell && !change_environment) ++ shell = getenv ("SHELL"); ++ if (shell && getuid () != 0 && restricted_shell (pw->pw_shell)) ++ { ++ /* The user being su'd to has a nonstandard shell, and so is ++ probably a uucp account or has restricted access. Don't ++ compromise the account by allowing access with a standard ++ shell. */ ++ error (0, 0, _("using restricted shell %s"), pw->pw_shell); ++ shell = NULL; ++ } ++ shell = xstrdup (shell ? shell : pw->pw_shell); ++ modify_environment (pw, shell); ++ ++ change_identity (pw); ++ if (simulate_login && chdir (pw->pw_dir) != 0) ++ error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); ++ ++ run_shell (shell, command, argv + optind, MAX (0, argc - optind)); ++} diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index c646812..12995d2 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-7.1-orig/configure.ac coreutils-7.1/configure.ac ---- coreutils-7.1-orig/configure.ac 2009-02-24 13:47:15.000000000 +0100 -+++ coreutils-7.1/configure.ac 2009-02-24 13:47:15.000000000 +0100 -@@ -84,6 +84,13 @@ AC_ARG_ENABLE(pam, dnl +diff -urNp coreutils-8.0-orig/configure.ac coreutils-8.0/configure.ac +--- coreutils-8.0-orig/configure.ac 2009-10-07 10:09:43.000000000 +0200 ++++ coreutils-8.0/configure.ac 2009-10-07 10:10:11.000000000 +0200 +@@ -122,6 +122,13 @@ AC_ARG_ENABLE(pam, dnl LIB_PAM="-ldl -lpam -lpam_misc" AC_SUBST(LIB_PAM)]) @@ -15,18 +15,35 @@ diff -urNp coreutils-7.1-orig/configure.ac coreutils-7.1/configure.ac AC_FUNC_FORK optional_bin_progs= -diff -urNp coreutils-7.1-orig/man/chcon.x coreutils-7.1/man/chcon.x ---- coreutils-7.1-orig/man/chcon.x 2008-09-18 09:06:57.000000000 +0200 -+++ coreutils-7.1/man/chcon.x 2009-02-24 13:47:15.000000000 +0100 +diff -urNp coreutils-8.0-orig/configure.ac.orig coreutils-8.0/configure.ac.orig +--- coreutils-8.0-orig/configure.ac.orig 2009-10-07 10:09:43.000000000 +0200 ++++ coreutils-8.0/configure.ac.orig 2009-10-07 10:09:43.000000000 +0200 +@@ -115,6 +115,13 @@ if test "$gl_gcc_warnings" = yes; then + AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) + fi + ++dnl Give the chance to enable PAM ++AC_ARG_ENABLE(pam, dnl ++[ --enable-pam Enable use of the PAM libraries], ++[AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) ++LIB_PAM="-ldl -lpam -lpam_misc" ++AC_SUBST(LIB_PAM)]) ++ + AC_FUNC_FORK + + optional_bin_progs= +diff -urNp coreutils-8.0-orig/man/chcon.x coreutils-8.0/man/chcon.x +--- coreutils-8.0-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.0/man/chcon.x 2009-10-07 10:10:11.000000000 +0200 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-7.1-orig/man/runcon.x coreutils-7.1/man/runcon.x ---- coreutils-7.1-orig/man/runcon.x 2008-09-18 09:06:57.000000000 +0200 -+++ coreutils-7.1/man/runcon.x 2009-02-24 13:47:15.000000000 +0100 +diff -urNp coreutils-8.0-orig/man/runcon.x coreutils-8.0/man/runcon.x +--- coreutils-8.0-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.0/man/runcon.x 2009-10-07 10:10:11.000000000 +0200 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,10 +51,10 @@ diff -urNp coreutils-7.1-orig/man/runcon.x coreutils-7.1/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-7.1-orig/src/copy.c coreutils-7.1/src/copy.c ---- coreutils-7.1-orig/src/copy.c 2009-02-18 15:32:52.000000000 +0100 -+++ coreutils-7.1/src/copy.c 2009-02-24 13:47:15.000000000 +0100 -@@ -1830,6 +1830,8 @@ copy_internal (char const *src_name, cha +diff -urNp coreutils-8.0-orig/src/copy.c coreutils-8.0/src/copy.c +--- coreutils-8.0-orig/src/copy.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/copy.c 2009-10-07 10:10:11.000000000 +0200 +@@ -1943,6 +1943,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -46,10 +63,2383 @@ diff -urNp coreutils-7.1-orig/src/copy.c coreutils-7.1/src/copy.c } else { -diff -urNp coreutils-7.1-orig/src/copy.h coreutils-7.1/src/copy.h ---- coreutils-7.1-orig/src/copy.h 2009-02-18 15:32:52.000000000 +0100 -+++ coreutils-7.1/src/copy.h 2009-02-24 13:47:15.000000000 +0100 -@@ -140,6 +140,9 @@ struct cp_options +diff -urNp coreutils-8.0-orig/src/copy.c.orig coreutils-8.0/src/copy.c.orig +--- coreutils-8.0-orig/src/copy.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/copy.c.orig 2009-09-29 15:27:54.000000000 +0200 +@@ -0,0 +1,2369 @@ ++/* copy.c -- core functions for copying files and directories ++ Copyright (C) 89, 90, 91, 1995-2009 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 . */ ++ ++/* Extracted from cp.c and librarified by Jim Meyering. */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#if HAVE_HURD_H ++# include ++#endif ++#if HAVE_PRIV_H ++# include ++#endif ++ ++#include "system.h" ++#include "acl.h" ++#include "backupfile.h" ++#include "buffer-lcm.h" ++#include "copy.h" ++#include "cp-hash.h" ++#include "error.h" ++#include "fcntl--.h" ++#include "file-set.h" ++#include "filemode.h" ++#include "filenamecat.h" ++#include "full-write.h" ++#include "hash.h" ++#include "hash-triple.h" ++#include "ignore-value.h" ++#include "quote.h" ++#include "same.h" ++#include "savedir.h" ++#include "stat-time.h" ++#include "utimecmp.h" ++#include "utimens.h" ++#include "write-any-file.h" ++#include "areadlink.h" ++#include "yesno.h" ++ ++#if USE_XATTR ++# include ++# include ++# include ++# include "verror.h" ++#endif ++ ++#if HAVE_SYS_IOCTL_H ++# include ++#endif ++ ++#ifndef HAVE_FCHOWN ++# define HAVE_FCHOWN false ++# define fchown(fd, uid, gid) (-1) ++#endif ++ ++#ifndef HAVE_LCHOWN ++# define HAVE_LCHOWN false ++# define lchown(name, uid, gid) chown (name, uid, gid) ++#endif ++ ++#ifndef HAVE_MKFIFO ++static int ++rpl_mkfifo (char const *file, mode_t mode) ++{ ++ errno = ENOTSUP; ++ return -1; ++} ++# define mkfifo rpl_mkfifo ++#endif ++ ++#ifndef USE_ACL ++# define USE_ACL 0 ++#endif ++ ++#define SAME_OWNER(A, B) ((A).st_uid == (B).st_uid) ++#define SAME_GROUP(A, B) ((A).st_gid == (B).st_gid) ++#define SAME_OWNER_AND_GROUP(A, B) (SAME_OWNER (A, B) && SAME_GROUP (A, B)) ++ ++struct dir_list ++{ ++ struct dir_list *parent; ++ ino_t ino; ++ dev_t dev; ++}; ++ ++/* Initial size of the cp.dest_info hash table. */ ++#define DEST_INFO_INITIAL_CAPACITY 61 ++ ++static bool copy_internal (char const *src_name, char const *dst_name, ++ bool new_dst, dev_t device, ++ struct dir_list *ancestors, ++ const struct cp_options *x, ++ bool command_line_arg, ++ bool *first_dir_created_per_command_line_arg, ++ bool *copy_into_self, ++ bool *rename_succeeded); ++static bool owner_failure_ok (struct cp_options const *x); ++ ++/* Pointers to the file names: they're used in the diagnostic that is issued ++ when we detect the user is trying to copy a directory into itself. */ ++static char const *top_level_src_name; ++static char const *top_level_dst_name; ++ ++/* Set the timestamp of symlink, FILE, to TIMESPEC. ++ If this system lacks support for that, simply return 0. */ ++static inline int ++utimens_symlink (char const *file, struct timespec const *timespec) ++{ ++ int err = 0; ++ ++#if HAVE_UTIMENSAT ++ err = utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW); ++ /* When configuring on a system with new headers and libraries, and ++ running on one with a kernel that is old enough to lack the syscall, ++ utimensat fails with ENOSYS. Ignore that. */ ++ if (err && errno == ENOSYS) ++ err = 0; ++#else ++ (void) file; ++ (void) timespec; ++#endif ++ ++ return err; ++} ++ ++/* Perform the O(1) btrfs clone operation, if possible. ++ Upon success, return 0. Otherwise, return -1 and set errno. */ ++static inline int ++clone_file (int dest_fd, int src_fd) ++{ ++#ifdef __linux__ ++# undef BTRFS_IOCTL_MAGIC ++# define BTRFS_IOCTL_MAGIC 0x94 ++# undef BTRFS_IOC_CLONE ++# define BTRFS_IOC_CLONE _IOW (BTRFS_IOCTL_MAGIC, 9, int) ++ return ioctl (dest_fd, BTRFS_IOC_CLONE, src_fd); ++#else ++ (void) dest_fd; ++ (void) src_fd; ++ errno = ENOTSUP; ++ return -1; ++#endif ++} ++ ++/* FIXME: describe */ ++/* FIXME: rewrite this to use a hash table so we avoid the quadratic ++ performance hit that's probably noticeable only on trees deeper ++ than a few hundred levels. See use of active_dir_map in remove.c */ ++ ++static bool ++is_ancestor (const struct stat *sb, const struct dir_list *ancestors) ++{ ++ while (ancestors != 0) ++ { ++ if (ancestors->ino == sb->st_ino && ancestors->dev == sb->st_dev) ++ return true; ++ ancestors = ancestors->parent; ++ } ++ return false; ++} ++ ++static bool ++errno_unsupported (int err) ++{ ++ return err == ENOTSUP || err == ENODATA; ++} ++ ++#if USE_XATTR ++static void ++copy_attr_error (struct error_context *ctx ATTRIBUTE_UNUSED, ++ char const *fmt, ...) ++{ ++ int err = errno; ++ va_list ap; ++ ++ if (!errno_unsupported (errno)) ++ { ++ /* use verror module to print error message */ ++ va_start (ap, fmt); ++ verror (0, err, fmt, ap); ++ va_end (ap); ++ } ++} ++ ++static void ++copy_attr_allerror (struct error_context *ctx ATTRIBUTE_UNUSED, ++ char const *fmt, ...) ++{ ++ int err = errno; ++ va_list ap; ++ ++ /* use verror module to print error message */ ++ va_start (ap, fmt); ++ verror (0, err, fmt, ap); ++ va_end (ap); ++} ++ ++static char const * ++copy_attr_quote (struct error_context *ctx ATTRIBUTE_UNUSED, char const *str) ++{ ++ return quote (str); ++} ++ ++static void ++copy_attr_free (struct error_context *ctx ATTRIBUTE_UNUSED, ++ char const *str ATTRIBUTE_UNUSED) ++{ ++} ++ ++static bool ++copy_attr_by_fd (char const *src_path, int src_fd, ++ char const *dst_path, int dst_fd, const struct cp_options *x) ++{ ++ struct error_context ctx = ++ { ++ .error = x->require_preserve_xattr ? copy_attr_allerror : copy_attr_error, ++ .quote = copy_attr_quote, ++ .quote_free = copy_attr_free ++ }; ++ return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0, ++ (x->reduce_diagnostics ++ && !x->require_preserve_xattr)? NULL : &ctx); ++} ++ ++static bool ++copy_attr_by_name (char const *src_path, char const *dst_path, ++ const struct cp_options *x) ++{ ++ struct error_context ctx = ++ { ++ .error = x->require_preserve_xattr ? copy_attr_allerror : copy_attr_error, ++ .quote = copy_attr_quote, ++ .quote_free = copy_attr_free ++ }; ++ return 0 == attr_copy_file (src_path, dst_path, 0, ++ (x-> reduce_diagnostics ++ && !x->require_preserve_xattr) ? NULL : &ctx); ++} ++#else /* USE_XATTR */ ++ ++static bool ++copy_attr_by_fd (char const *src_path ATTRIBUTE_UNUSED, ++ int src_fd ATTRIBUTE_UNUSED, ++ char const *dst_path ATTRIBUTE_UNUSED, ++ int dst_fd ATTRIBUTE_UNUSED, ++ const struct cp_options *x ATTRIBUTE_UNUSED) ++{ ++ return true; ++} ++ ++static bool ++copy_attr_by_name (char const *src_path ATTRIBUTE_UNUSED, ++ char const *dst_path ATTRIBUTE_UNUSED, ++ const struct cp_options *x ATTRIBUTE_UNUSED) ++{ ++ return true; ++} ++#endif /* USE_XATTR */ ++ ++/* Read the contents of the directory SRC_NAME_IN, and recursively ++ copy the contents to DST_NAME_IN. NEW_DST is true if ++ DST_NAME_IN is a directory that was created previously in the ++ recursion. SRC_SB and ANCESTORS describe SRC_NAME_IN. ++ Set *COPY_INTO_SELF if SRC_NAME_IN is a parent of ++ FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG FIXME ++ (or the same as) DST_NAME_IN; otherwise, clear it. ++ Return true if successful. */ ++ ++static bool ++copy_dir (char const *src_name_in, char const *dst_name_in, bool new_dst, ++ const struct stat *src_sb, struct dir_list *ancestors, ++ const struct cp_options *x, ++ bool *first_dir_created_per_command_line_arg, ++ bool *copy_into_self) ++{ ++ char *name_space; ++ char *namep; ++ struct cp_options non_command_line_options = *x; ++ bool ok = true; ++ ++ name_space = savedir (src_name_in); ++ if (name_space == NULL) ++ { ++ /* This diagnostic is a bit vague because savedir can fail in ++ several different ways. */ ++ error (0, errno, _("cannot access %s"), quote (src_name_in)); ++ return false; ++ } ++ ++ /* For cp's -H option, dereference command line arguments, but do not ++ dereference symlinks that are found via recursive traversal. */ ++ if (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS) ++ non_command_line_options.dereference = DEREF_NEVER; ++ ++ namep = name_space; ++ while (*namep != '\0') ++ { ++ bool local_copy_into_self; ++ char *src_name = file_name_concat (src_name_in, namep, NULL); ++ char *dst_name = file_name_concat (dst_name_in, namep, NULL); ++ ++ ok &= copy_internal (src_name, dst_name, new_dst, src_sb->st_dev, ++ ancestors, &non_command_line_options, false, ++ first_dir_created_per_command_line_arg, ++ &local_copy_into_self, NULL); ++ *copy_into_self |= local_copy_into_self; ++ ++ free (dst_name); ++ free (src_name); ++ ++ /* If we're copying into self, there's no point in continuing, ++ and in fact, that would even infloop, now that we record only ++ the first created directory per command line argument. */ ++ if (local_copy_into_self) ++ break; ++ ++ namep += strlen (namep) + 1; ++ } ++ free (name_space); ++ return ok; ++} ++ ++/* Set the owner and owning group of DEST_DESC to the st_uid and ++ st_gid fields of SRC_SB. If DEST_DESC is undefined (-1), set ++ the owner and owning group of DST_NAME instead; for ++ safety prefer lchown if the system supports it since no ++ symbolic links should be involved. DEST_DESC must ++ refer to the same file as DEST_NAME if defined. ++ Upon failure to set both UID and GID, try to set only the GID. ++ NEW_DST is true if the file was newly created; otherwise, ++ DST_SB is the status of the destination. ++ Return 1 if the initial syscall succeeds, 0 if it fails but it's OK ++ not to preserve ownership, -1 otherwise. */ ++ ++static int ++set_owner (const struct cp_options *x, char const *dst_name, int dest_desc, ++ struct stat const *src_sb, bool new_dst, ++ struct stat const *dst_sb) ++{ ++ uid_t uid = src_sb->st_uid; ++ gid_t gid = src_sb->st_gid; ++ ++ /* Naively changing the ownership of an already-existing file before ++ changing its permissions would create a window of vulnerability if ++ the file's old permissions are too generous for the new owner and ++ group. Avoid the window by first changing to a restrictive ++ temporary mode if necessary. */ ++ ++ if (!new_dst && (x->preserve_mode || x->move_mode || x->set_mode)) ++ { ++ mode_t old_mode = dst_sb->st_mode; ++ mode_t new_mode = ++ (x->preserve_mode || x->move_mode ? src_sb->st_mode : x->mode); ++ mode_t restrictive_temp_mode = old_mode & new_mode & S_IRWXU; ++ ++ if ((USE_ACL ++ || (old_mode & CHMOD_MODE_BITS ++ & (~new_mode | S_ISUID | S_ISGID | S_ISVTX))) ++ && qset_acl (dst_name, dest_desc, restrictive_temp_mode) != 0) ++ { ++ if (! owner_failure_ok (x)) ++ error (0, errno, _("clearing permissions for %s"), quote (dst_name)); ++ return -x->require_preserve; ++ } ++ } ++ ++ if (HAVE_FCHOWN && dest_desc != -1) ++ { ++ if (fchown (dest_desc, uid, gid) == 0) ++ return 1; ++ if (errno == EPERM || errno == EINVAL) ++ { ++ /* We've failed to set *both*. Now, try to set just the group ++ ID, but ignore any failure here, and don't change errno. */ ++ int saved_errno = errno; ++ ignore_value (fchown (dest_desc, -1, gid)); ++ errno = saved_errno; ++ } ++ } ++ else ++ { ++ if (lchown (dst_name, uid, gid) == 0) ++ return 1; ++ if (errno == EPERM || errno == EINVAL) ++ { ++ /* We've failed to set *both*. Now, try to set just the group ++ ID, but ignore any failure here, and don't change errno. */ ++ int saved_errno = errno; ++ ignore_value (lchown (dst_name, -1, gid)); ++ errno = saved_errno; ++ } ++ } ++ ++ if (! chown_failure_ok (x)) ++ { ++ error (0, errno, _("failed to preserve ownership for %s"), ++ quote (dst_name)); ++ if (x->require_preserve) ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* Set the st_author field of DEST_DESC to the st_author field of ++ SRC_SB. If DEST_DESC is undefined (-1), set the st_author field ++ of DST_NAME instead. DEST_DESC must refer to the same file as ++ DEST_NAME if defined. */ ++ ++static void ++set_author (const char *dst_name, int dest_desc, const struct stat *src_sb) ++{ ++#if HAVE_STRUCT_STAT_ST_AUTHOR ++ /* FIXME: Modify the following code so that it does not ++ follow symbolic links. */ ++ ++ /* Preserve the st_author field. */ ++ file_t file = (dest_desc < 0 ++ ? file_name_lookup (dst_name, 0, 0) ++ : getdport (dest_desc)); ++ if (file == MACH_PORT_NULL) ++ error (0, errno, _("failed to lookup file %s"), quote (dst_name)); ++ else ++ { ++ error_t err = file_chauthor (file, src_sb->st_author); ++ if (err) ++ error (0, err, _("failed to preserve authorship for %s"), ++ quote (dst_name)); ++ mach_port_deallocate (mach_task_self (), file); ++ } ++#else ++ (void) dst_name; ++ (void) dest_desc; ++ (void) src_sb; ++#endif ++} ++ ++/* Change the file mode bits of the file identified by DESC or NAME to MODE. ++ Use DESC if DESC is valid and fchmod is available, NAME otherwise. */ ++ ++static int ++fchmod_or_lchmod (int desc, char const *name, mode_t mode) ++{ ++#if HAVE_FCHMOD ++ if (0 <= desc) ++ return fchmod (desc, mode); ++#endif ++ return lchmod (name, mode); ++} ++ ++/* Copy a regular file from SRC_NAME to DST_NAME. ++ If the source file contains holes, copies holes and blocks of zeros ++ in the source file as holes in the destination file. ++ (Holes are read as zeroes by the `read' system call.) ++ When creating the destination, use DST_MODE & ~OMITTED_PERMISSIONS ++ as the third argument in the call to open, adding ++ OMITTED_PERMISSIONS after copying as needed. ++ X provides many option settings. ++ Return true if successful. ++ *NEW_DST is as in copy_internal. ++ SRC_SB is the result of calling XSTAT (aka stat) on SRC_NAME. */ ++ ++static bool ++copy_reg (char const *src_name, char const *dst_name, ++ const struct cp_options *x, ++ mode_t dst_mode, mode_t omitted_permissions, bool *new_dst, ++ struct stat const *src_sb) ++{ ++ char *buf; ++ char *buf_alloc = NULL; ++ char *name_alloc = NULL; ++ int dest_desc; ++ int dest_errno; ++ int source_desc; ++ mode_t src_mode = src_sb->st_mode; ++ struct stat sb; ++ struct stat src_open_sb; ++ bool return_val = true; ++ bool data_copy_required = true; ++ ++ source_desc = open (src_name, ++ (O_RDONLY | O_BINARY ++ | (x->dereference == DEREF_NEVER ? O_NOFOLLOW : 0))); ++ if (source_desc < 0) ++ { ++ error (0, errno, _("cannot open %s for reading"), quote (src_name)); ++ return false; ++ } ++ ++ if (fstat (source_desc, &src_open_sb) != 0) ++ { ++ error (0, errno, _("cannot fstat %s"), quote (src_name)); ++ return_val = false; ++ goto close_src_desc; ++ } ++ ++ /* Compare the source dev/ino from the open file to the incoming, ++ saved ones obtained via a previous call to stat. */ ++ if (! SAME_INODE (*src_sb, src_open_sb)) ++ { ++ error (0, 0, ++ _("skipping file %s, as it was replaced while being copied"), ++ quote (src_name)); ++ return_val = false; ++ goto close_src_desc; ++ } ++ ++ /* The semantics of the following open calls are mandated ++ by the specs for both cp and mv. */ ++ if (! *new_dst) ++ { ++ dest_desc = open (dst_name, O_WRONLY | O_TRUNC | O_BINARY); ++ dest_errno = errno; ++ ++ /* When using cp --preserve=context to copy to an existing destination, ++ use the default context rather than that of the source. Why? ++ 1) the src context may prohibit writing, and ++ 2) because it's more consistent to use the same context ++ that is used when the destination file doesn't already exist. */ ++ if (x->preserve_security_context && 0 <= dest_desc) ++ { ++ security_context_t con = NULL; ++ if (getfscreatecon (&con) < 0) ++ { ++ if (!x->reduce_diagnostics || x->require_preserve_context) ++ error (0, errno, _("failed to get file system create context")); ++ if (x->require_preserve_context) ++ { ++ return_val = false; ++ goto close_src_and_dst_desc; ++ } ++ } ++ ++ if (con) ++ { ++ if (fsetfilecon (dest_desc, con) < 0) ++ { ++ if (!x->reduce_diagnostics || x->require_preserve_context) ++ error (0, errno, ++ _("failed to set the security context of %s to %s"), ++ quote_n (0, dst_name), quote_n (1, con)); ++ if (x->require_preserve_context) ++ { ++ return_val = false; ++ freecon (con); ++ goto close_src_and_dst_desc; ++ } ++ } ++ freecon (con); ++ } ++ } ++ ++ if (dest_desc < 0 && x->unlink_dest_after_failed_open) ++ { ++ if (unlink (dst_name) != 0) ++ { ++ error (0, errno, _("cannot remove %s"), quote (dst_name)); ++ return_val = false; ++ goto close_src_desc; ++ } ++ if (x->verbose) ++ printf (_("removed %s\n"), quote (dst_name)); ++ ++ /* Tell caller that the destination file was unlinked. */ ++ *new_dst = true; ++ } ++ } ++ ++ if (*new_dst) ++ { ++ int open_flags = O_WRONLY | O_CREAT | O_BINARY; ++ dest_desc = open (dst_name, open_flags | O_EXCL, ++ dst_mode & ~omitted_permissions); ++ dest_errno = errno; ++ ++ /* When trying to copy through a dangling destination symlink, ++ the above open fails with EEXIST. If that happens, and ++ lstat'ing the DST_NAME shows that it is a symlink, then we ++ have a problem: trying to resolve this dangling symlink to ++ a directory/destination-entry pair is fundamentally racy, ++ so punt. If POSIXLY_CORRECT is set, simply call open again, ++ but without O_EXCL (potentially dangerous). If not, fail ++ with a diagnostic. These shenanigans are necessary only ++ when copying, i.e., not in move_mode. */ ++ if (dest_desc < 0 && dest_errno == EEXIST && ! x->move_mode) ++ { ++ struct stat dangling_link_sb; ++ if (lstat (dst_name, &dangling_link_sb) == 0 ++ && S_ISLNK (dangling_link_sb.st_mode)) ++ { ++ if (x->open_dangling_dest_symlink) ++ { ++ dest_desc = open (dst_name, open_flags, ++ dst_mode & ~omitted_permissions); ++ dest_errno = errno; ++ } ++ else ++ { ++ error (0, 0, _("not writing through dangling symlink %s"), ++ quote (dst_name)); ++ return_val = false; ++ goto close_src_desc; ++ } ++ } ++ } ++ } ++ else ++ omitted_permissions = 0; ++ ++ if (dest_desc < 0) ++ { ++ error (0, dest_errno, _("cannot create regular file %s"), ++ quote (dst_name)); ++ return_val = false; ++ goto close_src_desc; ++ } ++ ++ if (fstat (dest_desc, &sb) != 0) ++ { ++ error (0, errno, _("cannot fstat %s"), quote (dst_name)); ++ return_val = false; ++ goto close_src_and_dst_desc; ++ } ++ ++ if (x->reflink_mode) ++ { ++ bool clone_ok = clone_file (dest_desc, source_desc) == 0; ++ if (clone_ok || x->reflink_mode == REFLINK_ALWAYS) ++ { ++ if (!clone_ok) ++ { ++ error (0, errno, _("failed to clone %s"), quote (dst_name)); ++ return_val = false; ++ goto close_src_and_dst_desc; ++ } ++ data_copy_required = false; ++ } ++ } ++ ++ if (data_copy_required) ++ { ++ typedef uintptr_t word; ++ off_t n_read_total = 0; ++ ++ /* Choose a suitable buffer size; it may be adjusted later. */ ++ size_t buf_alignment = lcm (getpagesize (), sizeof (word)); ++ size_t buf_alignment_slop = sizeof (word) + buf_alignment - 1; ++ size_t buf_size = io_blksize (sb); ++ ++ /* Deal with sparse files. */ ++ bool last_write_made_hole = false; ++ bool make_holes = false; ++ ++ if (S_ISREG (sb.st_mode)) ++ { ++ /* Even with --sparse=always, try to create holes only ++ if the destination is a regular file. */ ++ if (x->sparse_mode == SPARSE_ALWAYS) ++ make_holes = true; ++ ++#if HAVE_STRUCT_STAT_ST_BLOCKS ++ /* Use a heuristic to determine whether SRC_NAME contains any sparse ++ blocks. If the file has fewer blocks than would normally be ++ needed for a file of its size, then at least one of the blocks in ++ the file is a hole. */ ++ if (x->sparse_mode == SPARSE_AUTO && S_ISREG (src_open_sb.st_mode) ++ && ST_NBLOCKS (src_open_sb) < src_open_sb.st_size / ST_NBLOCKSIZE) ++ make_holes = true; ++#endif ++ } ++ ++ /* If not making a sparse file, try to use a more-efficient ++ buffer size. */ ++ if (! make_holes) ++ { ++ /* Compute the least common multiple of the input and output ++ buffer sizes, adjusting for outlandish values. */ ++ size_t blcm_max = MIN (SIZE_MAX, SSIZE_MAX) - buf_alignment_slop; ++ size_t blcm = buffer_lcm (io_blksize (src_open_sb), buf_size, ++ blcm_max); ++ ++ /* Do not bother with a buffer larger than the input file, plus one ++ byte to make sure the file has not grown while reading it. */ ++ if (S_ISREG (src_open_sb.st_mode) && src_open_sb.st_size < buf_size) ++ buf_size = src_open_sb.st_size + 1; ++ ++ /* However, stick with a block size that is a positive multiple of ++ blcm, overriding the above adjustments. Watch out for ++ overflow. */ ++ buf_size += blcm - 1; ++ buf_size -= buf_size % blcm; ++ if (buf_size == 0 || blcm_max < buf_size) ++ buf_size = blcm; ++ } ++ ++ /* Make a buffer with space for a sentinel at the end. */ ++ buf_alloc = xmalloc (buf_size + buf_alignment_slop); ++ buf = ptr_align (buf_alloc, buf_alignment); ++ ++ for (;;) ++ { ++ word *wp = NULL; ++ ++ ssize_t n_read = read (source_desc, buf, buf_size); ++ if (n_read < 0) ++ { ++#ifdef EINTR ++ if (errno == EINTR) ++ continue; ++#endif ++ error (0, errno, _("reading %s"), quote (src_name)); ++ return_val = false; ++ goto close_src_and_dst_desc; ++ } ++ if (n_read == 0) ++ break; ++ ++ n_read_total += n_read; ++ ++ if (make_holes) ++ { ++ char *cp; ++ ++ /* Sentinel to stop loop. */ ++ buf[n_read] = '\1'; ++#ifdef lint ++ /* Usually, buf[n_read] is not the byte just before a "word" ++ (aka uintptr_t) boundary. In that case, the word-oriented ++ test below (*wp++ == 0) would read some uninitialized bytes ++ after the sentinel. To avoid false-positive reports about ++ this condition (e.g., from a tool like valgrind), set the ++ remaining bytes -- to any value. */ ++ memset (buf + n_read + 1, 0, sizeof (word) - 1); ++#endif ++ ++ /* Find first nonzero *word*, or the word with the sentinel. */ ++ ++ wp = (word *) buf; ++ while (*wp++ == 0) ++ continue; ++ ++ /* Find the first nonzero *byte*, or the sentinel. */ ++ ++ cp = (char *) (wp - 1); ++ while (*cp++ == 0) ++ continue; ++ ++ if (cp <= buf + n_read) ++ /* Clear to indicate that a normal write is needed. */ ++ wp = NULL; ++ else ++ { ++ /* We found the sentinel, so the whole input block was zero. ++ Make a hole. */ ++ if (lseek (dest_desc, n_read, SEEK_CUR) < 0) ++ { ++ error (0, errno, _("cannot lseek %s"), quote (dst_name)); ++ return_val = false; ++ goto close_src_and_dst_desc; ++ } ++ last_write_made_hole = true; ++ } ++ } ++ ++ if (!wp) ++ { ++ size_t n = n_read; ++ if (full_write (dest_desc, buf, n) != n) ++ { ++ error (0, errno, _("writing %s"), quote (dst_name)); ++ return_val = false; ++ goto close_src_and_dst_desc; ++ } ++ last_write_made_hole = false; ++ ++ /* It is tempting to return early here upon a short read from a ++ regular file. That would save the final read syscall for each ++ file. Unfortunately that doesn't work for certain files in ++ /proc with linux kernels from at least 2.6.9 .. 2.6.29. */ ++ } ++ } ++ ++ /* If the file ends with a `hole', we need to do something to record ++ the length of the file. On modern systems, calling ftruncate does ++ the job. On systems without native ftruncate support, we have to ++ write a byte at the ending position. Otherwise the kernel would ++ truncate the file at the end of the last write operation. */ ++ ++ if (last_write_made_hole) ++ { ++ if (HAVE_FTRUNCATE ++ ? /* ftruncate sets the file size, ++ so there is no need for a write. */ ++ ftruncate (dest_desc, n_read_total) < 0 ++ : /* Seek backwards one character and write a null. */ ++ (lseek (dest_desc, (off_t) -1, SEEK_CUR) < 0L ++ || full_write (dest_desc, "", 1) != 1)) ++ { ++ error (0, errno, _("writing %s"), quote (dst_name)); ++ return_val = false; ++ goto close_src_and_dst_desc; ++ } ++ } ++ } ++ ++ if (x->preserve_timestamps) ++ { ++ struct timespec timespec[2]; ++ timespec[0] = get_stat_atime (src_sb); ++ timespec[1] = get_stat_mtime (src_sb); ++ ++ if (gl_futimens (dest_desc, dst_name, timespec) != 0) ++ { ++ error (0, errno, _("preserving times for %s"), quote (dst_name)); ++ if (x->require_preserve) ++ { ++ return_val = false; ++ goto close_src_and_dst_desc; ++ } ++ } ++ } ++ ++ /* To allow copying xattrs on read-only files, temporarily chmod u+rw. ++ This workaround is required as an inode permission check is done ++ by xattr_permission() in fs/xattr.c of the GNU/Linux kernel tree. */ ++ if (x->preserve_xattr) ++ { ++ bool access_changed = false; ++ ++ if (!(sb.st_mode & S_IWUSR) && geteuid() != 0) ++ access_changed = fchmod_or_lchmod (dest_desc, dst_name, 0600) == 0; ++ ++ if (!copy_attr_by_fd (src_name, source_desc, dst_name, dest_desc, x) ++ && x->require_preserve_xattr) ++ return_val = false; ++ ++ if (access_changed) ++ fchmod_or_lchmod (dest_desc, dst_name, dst_mode & ~omitted_permissions); ++ } ++ ++ if (x->preserve_ownership && ! SAME_OWNER_AND_GROUP (*src_sb, sb)) ++ { ++ switch (set_owner (x, dst_name, dest_desc, src_sb, *new_dst, &sb)) ++ { ++ case -1: ++ return_val = false; ++ goto close_src_and_dst_desc; ++ ++ case 0: ++ src_mode &= ~ (S_ISUID | S_ISGID | S_ISVTX); ++ break; ++ } ++ } ++ ++ set_author (dst_name, dest_desc, src_sb); ++ ++ if (x->preserve_mode || x->move_mode) ++ { ++ if (copy_acl (src_name, source_desc, dst_name, dest_desc, src_mode) != 0 ++ && x->require_preserve) ++ return_val = false; ++ } ++ else if (x->set_mode) ++ { ++ if (set_acl (dst_name, dest_desc, x->mode) != 0) ++ return_val = false; ++ } ++ else if (omitted_permissions) ++ { ++ omitted_permissions &= ~ cached_umask (); ++ if (omitted_permissions ++ && fchmod_or_lchmod (dest_desc, dst_name, dst_mode) != 0) ++ { ++ error (0, errno, _("preserving permissions for %s"), ++ quote (dst_name)); ++ if (x->require_preserve) ++ return_val = false; ++ } ++ } ++ ++close_src_and_dst_desc: ++ if (close (dest_desc) < 0) ++ { ++ error (0, errno, _("closing %s"), quote (dst_name)); ++ return_val = false; ++ } ++close_src_desc: ++ if (close (source_desc) < 0) ++ { ++ error (0, errno, _("closing %s"), quote (src_name)); ++ return_val = false; ++ } ++ ++ free (buf_alloc); ++ free (name_alloc); ++ return return_val; ++} ++ ++/* Return true if it's ok that the source and destination ++ files are the `same' by some measure. The goal is to avoid ++ making the `copy' operation remove both copies of the file ++ in that case, while still allowing the user to e.g., move or ++ copy a regular file onto a symlink that points to it. ++ Try to minimize the cost of this function in the common case. ++ Set *RETURN_NOW if we've determined that the caller has no more ++ work to do and should return successfully, right away. ++ ++ Set *UNLINK_SRC if we've determined that the caller wants to do ++ `rename (a, b)' where `a' and `b' are distinct hard links to the same ++ file. In that case, the caller should try to unlink `a' and then return ++ successfully. Ideally, we wouldn't have to do that, and we'd be ++ able to rely on rename to remove the source file. However, POSIX ++ mistakenly requires that such a rename call do *nothing* and return ++ successfully. */ ++ ++static bool ++same_file_ok (char const *src_name, struct stat const *src_sb, ++ char const *dst_name, struct stat const *dst_sb, ++ const struct cp_options *x, bool *return_now, bool *unlink_src) ++{ ++ const struct stat *src_sb_link; ++ const struct stat *dst_sb_link; ++ struct stat tmp_dst_sb; ++ struct stat tmp_src_sb; ++ ++ bool same_link; ++ bool same = SAME_INODE (*src_sb, *dst_sb); ++ ++ *return_now = false; ++ *unlink_src = false; ++ ++ /* FIXME: this should (at the very least) be moved into the following ++ if-block. More likely, it should be removed, because it inhibits ++ making backups. But removing it will result in a change in behavior ++ that will probably have to be documented -- and tests will have to ++ be updated. */ ++ if (same && x->hard_link) ++ { ++ *return_now = true; ++ return true; ++ } ++ ++ if (x->dereference == DEREF_NEVER) ++ { ++ same_link = same; ++ ++ /* If both the source and destination files are symlinks (and we'll ++ know this here IFF preserving symlinks), then it's ok -- as long ++ as they are distinct. */ ++ if (S_ISLNK (src_sb->st_mode) && S_ISLNK (dst_sb->st_mode)) ++ return ! same_name (src_name, dst_name); ++ ++ src_sb_link = src_sb; ++ dst_sb_link = dst_sb; ++ } ++ else ++ { ++ if (!same) ++ return true; ++ ++ if (lstat (dst_name, &tmp_dst_sb) != 0 ++ || lstat (src_name, &tmp_src_sb) != 0) ++ return true; ++ ++ src_sb_link = &tmp_src_sb; ++ dst_sb_link = &tmp_dst_sb; ++ ++ same_link = SAME_INODE (*src_sb_link, *dst_sb_link); ++ ++ /* If both are symlinks, then it's ok, but only if the destination ++ will be unlinked before being opened. This is like the test ++ above, but with the addition of the unlink_dest_before_opening ++ conjunct because otherwise, with two symlinks to the same target, ++ we'd end up truncating the source file. */ ++ if (S_ISLNK (src_sb_link->st_mode) && S_ISLNK (dst_sb_link->st_mode) ++ && x->unlink_dest_before_opening) ++ return true; ++ } ++ ++ /* The backup code ensures there's a copy, so it's usually ok to ++ remove any destination file. One exception is when both ++ source and destination are the same directory entry. In that ++ case, moving the destination file aside (in making the backup) ++ would also rename the source file and result in an error. */ ++ if (x->backup_type != no_backups) ++ { ++ if (!same_link) ++ { ++ /* In copy mode when dereferencing symlinks, if the source is a ++ symlink and the dest is not, then backing up the destination ++ (moving it aside) would make it a dangling symlink, and the ++ subsequent attempt to open it in copy_reg would fail with ++ a misleading diagnostic. Avoid that by returning zero in ++ that case so the caller can make cp (or mv when it has to ++ resort to reading the source file) fail now. */ ++ ++ /* FIXME-note: even with the following kludge, we can still provoke ++ the offending diagnostic. It's just a little harder to do :-) ++ $ rm -f a b c; touch c; ln -s c b; ln -s b a; cp -b a b ++ cp: cannot open `a' for reading: No such file or directory ++ That's misleading, since a subsequent `ls' shows that `a' ++ is still there. ++ One solution would be to open the source file *before* moving ++ aside the destination, but that'd involve a big rewrite. */ ++ if ( ! x->move_mode ++ && x->dereference != DEREF_NEVER ++ && S_ISLNK (src_sb_link->st_mode) ++ && ! S_ISLNK (dst_sb_link->st_mode)) ++ return false; ++ ++ return true; ++ } ++ ++ return ! same_name (src_name, dst_name); ++ } ++ ++#if 0 ++ /* FIXME: use or remove */ ++ ++ /* If we're making a backup, we'll detect the problem case in ++ copy_reg because SRC_NAME will no longer exist. Allowing ++ the test to be deferred lets cp do some useful things. ++ But when creating hardlinks and SRC_NAME is a symlink ++ but DST_NAME is not we must test anyway. */ ++ if (x->hard_link ++ || !S_ISLNK (src_sb_link->st_mode) ++ || S_ISLNK (dst_sb_link->st_mode)) ++ return true; ++ ++ if (x->dereference != DEREF_NEVER) ++ return true; ++#endif ++ ++ /* They may refer to the same file if we're in move mode and the ++ target is a symlink. That is ok, since we remove any existing ++ destination file before opening it -- via `rename' if they're on ++ the same file system, via `unlink (DST_NAME)' otherwise. ++ It's also ok if they're distinct hard links to the same file. */ ++ if (x->move_mode || x->unlink_dest_before_opening) ++ { ++ if (S_ISLNK (dst_sb_link->st_mode)) ++ return true; ++ ++ if (same_link ++ && 1 < dst_sb_link->st_nlink ++ && ! same_name (src_name, dst_name)) ++ { ++ if (x->move_mode) ++ { ++ *unlink_src = true; ++ *return_now = true; ++ } ++ return true; ++ } ++ } ++ ++ /* If neither is a symlink, then it's ok as long as they aren't ++ hard links to the same file. */ ++ if (!S_ISLNK (src_sb_link->st_mode) && !S_ISLNK (dst_sb_link->st_mode)) ++ { ++ if (!SAME_INODE (*src_sb_link, *dst_sb_link)) ++ return true; ++ ++ /* If they are the same file, it's ok if we're making hard links. */ ++ if (x->hard_link) ++ { ++ *return_now = true; ++ return true; ++ } ++ } ++ ++ /* It's ok to remove a destination symlink. But that works only when we ++ unlink before opening the destination and when the source and destination ++ files are on the same partition. */ ++ if (x->unlink_dest_before_opening ++ && S_ISLNK (dst_sb_link->st_mode)) ++ return dst_sb_link->st_dev == src_sb_link->st_dev; ++ ++ if (x->dereference == DEREF_NEVER) ++ { ++ if ( ! S_ISLNK (src_sb_link->st_mode)) ++ tmp_src_sb = *src_sb_link; ++ else if (stat (src_name, &tmp_src_sb) != 0) ++ return true; ++ ++ if ( ! S_ISLNK (dst_sb_link->st_mode)) ++ tmp_dst_sb = *dst_sb_link; ++ else if (stat (dst_name, &tmp_dst_sb) != 0) ++ return true; ++ ++ if ( ! SAME_INODE (tmp_src_sb, tmp_dst_sb)) ++ return true; ++ ++ /* FIXME: shouldn't this be testing whether we're making symlinks? */ ++ if (x->hard_link) ++ { ++ *return_now = true; ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++/* Return true if FILE, with mode MODE, is writable in the sense of 'mv'. ++ Always consider a symbolic link to be writable. */ ++static bool ++writable_destination (char const *file, mode_t mode) ++{ ++ return (S_ISLNK (mode) ++ || can_write_any_file () ++ || euidaccess (file, W_OK) == 0); ++} ++ ++static void ++overwrite_prompt (char const *dst_name, struct stat const *dst_sb) ++{ ++ if (! writable_destination (dst_name, dst_sb->st_mode)) ++ { ++ char perms[12]; /* "-rwxrwxrwx " ls-style modes. */ ++ strmode (dst_sb->st_mode, perms); ++ perms[10] = '\0'; ++ fprintf (stderr, ++ _("%s: try to overwrite %s, overriding mode %04lo (%s)? "), ++ program_name, quote (dst_name), ++ (unsigned long int) (dst_sb->st_mode & CHMOD_MODE_BITS), ++ &perms[1]); ++ } ++ else ++ { ++ fprintf (stderr, _("%s: overwrite %s? "), ++ program_name, quote (dst_name)); ++ } ++} ++ ++/* Initialize the hash table implementing a set of F_triple entries ++ corresponding to destination files. */ ++extern void ++dest_info_init (struct cp_options *x) ++{ ++ x->dest_info ++ = hash_initialize (DEST_INFO_INITIAL_CAPACITY, ++ NULL, ++ triple_hash, ++ triple_compare, ++ triple_free); ++} ++ ++/* Initialize the hash table implementing a set of F_triple entries ++ corresponding to source files listed on the command line. */ ++extern void ++src_info_init (struct cp_options *x) ++{ ++ ++ /* Note that we use triple_hash_no_name here. ++ Contrast with the use of triple_hash above. ++ That is necessary because a source file may be specified ++ in many different ways. We want to warn about this ++ cp a a d/ ++ as well as this: ++ cp a ./a d/ ++ */ ++ x->src_info ++ = hash_initialize (DEST_INFO_INITIAL_CAPACITY, ++ NULL, ++ triple_hash_no_name, ++ triple_compare, ++ triple_free); ++} ++ ++/* When effecting a move (e.g., for mv(1)), and given the name DST_NAME ++ of the destination and a corresponding stat buffer, DST_SB, return ++ true if the logical `move' operation should _not_ proceed. ++ Otherwise, return false. ++ Depending on options specified in X, this code may issue an ++ interactive prompt asking whether it's ok to overwrite DST_NAME. */ ++static bool ++abandon_move (const struct cp_options *x, ++ char const *dst_name, ++ struct stat const *dst_sb) ++{ ++ assert (x->move_mode); ++ return (x->interactive == I_ALWAYS_NO ++ || ((x->interactive == I_ASK_USER ++ || (x->interactive == I_UNSPECIFIED ++ && x->stdin_tty ++ && ! writable_destination (dst_name, dst_sb->st_mode))) ++ && (overwrite_prompt (dst_name, dst_sb), 1) ++ && ! yesno ())); ++} ++ ++/* Print --verbose output on standard output, e.g. `new' -> `old'. ++ If BACKUP_DST_NAME is non-NULL, then also indicate that it is ++ the name of a backup file. */ ++static void ++emit_verbose (char const *src, char const *dst, char const *backup_dst_name) ++{ ++ printf ("%s -> %s", quote_n (0, src), quote_n (1, dst)); ++ if (backup_dst_name) ++ printf (_(" (backup: %s)"), quote (backup_dst_name)); ++ putchar ('\n'); ++} ++ ++/* A wrapper around "setfscreatecon (NULL)" that exits upon failure. */ ++static void ++restore_default_fscreatecon_or_die (void) ++{ ++ if (setfscreatecon (NULL) != 0) ++ error (EXIT_FAILURE, errno, ++ _("failed to restore the default file creation context")); ++} ++ ++/* Copy the file SRC_NAME to the file DST_NAME. The files may be of ++ any type. NEW_DST should be true if the file DST_NAME cannot ++ exist because its parent directory was just created; NEW_DST should ++ be false if DST_NAME might already exist. DEVICE is the device ++ number of the parent directory, or 0 if the parent of this file is ++ not known. ANCESTORS points to a linked, null terminated list of ++ devices and inodes of parent directories of SRC_NAME. COMMAND_LINE_ARG ++ is true iff SRC_NAME was specified on the command line. ++ FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG is both input and output. ++ Set *COPY_INTO_SELF if SRC_NAME is a parent of (or the ++ same as) DST_NAME; otherwise, clear it. ++ Return true if successful. */ ++static bool ++copy_internal (char const *src_name, char const *dst_name, ++ bool new_dst, ++ dev_t device, ++ struct dir_list *ancestors, ++ const struct cp_options *x, ++ bool command_line_arg, ++ bool *first_dir_created_per_command_line_arg, ++ bool *copy_into_self, ++ bool *rename_succeeded) ++{ ++ struct stat src_sb; ++ struct stat dst_sb; ++ mode_t src_mode; ++ mode_t dst_mode IF_LINT (= 0); ++ mode_t dst_mode_bits; ++ mode_t omitted_permissions; ++ bool restore_dst_mode = false; ++ char *earlier_file = NULL; ++ char *dst_backup = NULL; ++ bool backup_succeeded = false; ++ bool delayed_ok; ++ bool copied_as_regular = false; ++ bool dest_is_symlink = false; ++ bool have_dst_lstat = false; ++ ++ if (x->move_mode && rename_succeeded) ++ *rename_succeeded = false; ++ ++ *copy_into_self = false; ++ ++ if (XSTAT (x, src_name, &src_sb) != 0) ++ { ++ error (0, errno, _("cannot stat %s"), quote (src_name)); ++ return false; ++ } ++ ++ src_mode = src_sb.st_mode; ++ ++ if (S_ISDIR (src_mode) && !x->recursive) ++ { ++ error (0, 0, _("omitting directory %s"), quote (src_name)); ++ return false; ++ } ++ ++ /* Detect the case in which the same source file appears more than ++ once on the command line and no backup option has been selected. ++ If so, simply warn and don't copy it the second time. ++ This check is enabled only if x->src_info is non-NULL. */ ++ if (command_line_arg) ++ { ++ if ( ! S_ISDIR (src_sb.st_mode) ++ && x->backup_type == no_backups ++ && seen_file (x->src_info, src_name, &src_sb)) ++ { ++ error (0, 0, _("warning: source file %s specified more than once"), ++ quote (src_name)); ++ return true; ++ } ++ ++ record_file (x->src_info, src_name, &src_sb); ++ } ++ ++ if (!new_dst) ++ { ++ /* Regular files can be created by writing through symbolic ++ links, but other files cannot. So use stat on the ++ destination when copying a regular file, and lstat otherwise. ++ However, if we intend to unlink or remove the destination ++ first, use lstat, since a copy won't actually be made to the ++ destination in that case. */ ++ bool use_stat = ++ ((S_ISREG (src_mode) ++ || (x->copy_as_regular ++ && ! (S_ISDIR (src_mode) || S_ISLNK (src_mode)))) ++ && ! (x->move_mode || x->symbolic_link || x->hard_link ++ || x->backup_type != no_backups ++ || x->unlink_dest_before_opening)); ++ if ((use_stat ++ ? stat (dst_name, &dst_sb) ++ : lstat (dst_name, &dst_sb)) ++ != 0) ++ { ++ if (errno != ENOENT) ++ { ++ error (0, errno, _("cannot stat %s"), quote (dst_name)); ++ return false; ++ } ++ else ++ { ++ new_dst = true; ++ } ++ } ++ else ++ { /* Here, we know that dst_name exists, at least to the point ++ that it is stat'able or lstat'able. */ ++ bool return_now; ++ bool unlink_src; ++ ++ have_dst_lstat = !use_stat; ++ if (! same_file_ok (src_name, &src_sb, dst_name, &dst_sb, ++ x, &return_now, &unlink_src)) ++ { ++ error (0, 0, _("%s and %s are the same file"), ++ quote_n (0, src_name), quote_n (1, dst_name)); ++ return false; ++ } ++ ++ if (!S_ISDIR (src_mode) && x->update) ++ { ++ /* When preserving time stamps (but not moving within a file ++ system), don't worry if the destination time stamp is ++ less than the source merely because of time stamp ++ truncation. */ ++ int options = ((x->preserve_timestamps ++ && ! (x->move_mode ++ && dst_sb.st_dev == src_sb.st_dev)) ++ ? UTIMECMP_TRUNCATE_SOURCE ++ : 0); ++ ++ if (0 <= utimecmp (dst_name, &dst_sb, &src_sb, options)) ++ { ++ /* We're using --update and the destination is not older ++ than the source, so do not copy or move. Pretend the ++ rename succeeded, so the caller (if it's mv) doesn't ++ end up removing the source file. */ ++ if (rename_succeeded) ++ *rename_succeeded = true; ++ return true; ++ } ++ } ++ ++ /* When there is an existing destination file, we may end up ++ returning early, and hence not copying/moving the file. ++ This may be due to an interactive `negative' reply to the ++ prompt about the existing file. It may also be due to the ++ use of the --reply=no option. ++ ++ cp and mv treat -i and -f differently. */ ++ if (x->move_mode) ++ { ++ if (abandon_move (x, dst_name, &dst_sb) ++ || (unlink_src && unlink (src_name) == 0)) ++ { ++ /* Pretend the rename succeeded, so the caller (mv) ++ doesn't end up removing the source file. */ ++ if (rename_succeeded) ++ *rename_succeeded = true; ++ if (unlink_src && x->verbose) ++ printf (_("removed %s\n"), quote (src_name)); ++ return true; ++ } ++ if (unlink_src) ++ { ++ error (0, errno, _("cannot remove %s"), quote (src_name)); ++ return false; ++ } ++ } ++ else ++ { ++ if (! S_ISDIR (src_mode) ++ && (x->interactive == I_ALWAYS_NO ++ || (x->interactive == I_ASK_USER ++ && (overwrite_prompt (dst_name, &dst_sb), 1) ++ && ! yesno ()))) ++ return true; ++ } ++ ++ if (return_now) ++ return true; ++ ++ if (!S_ISDIR (dst_sb.st_mode)) ++ { ++ if (S_ISDIR (src_mode)) ++ { ++ if (x->move_mode && x->backup_type != no_backups) ++ { ++ /* Moving a directory onto an existing ++ non-directory is ok only with --backup. */ ++ } ++ else ++ { ++ error (0, 0, ++ _("cannot overwrite non-directory %s with directory %s"), ++ quote_n (0, dst_name), quote_n (1, src_name)); ++ return false; ++ } ++ } ++ ++ /* Don't let the user destroy their data, even if they try hard: ++ This mv command must fail (likewise for cp): ++ rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c ++ Otherwise, the contents of b/f would be lost. ++ In the case of `cp', b/f would be lost if the user simulated ++ a move using cp and rm. ++ Note that it works fine if you use --backup=numbered. */ ++ if (command_line_arg ++ && x->backup_type != numbered_backups ++ && seen_file (x->dest_info, dst_name, &dst_sb)) ++ { ++ error (0, 0, ++ _("will not overwrite just-created %s with %s"), ++ quote_n (0, dst_name), quote_n (1, src_name)); ++ return false; ++ } ++ } ++ ++ if (!S_ISDIR (src_mode)) ++ { ++ if (S_ISDIR (dst_sb.st_mode)) ++ { ++ if (x->move_mode && x->backup_type != no_backups) ++ { ++ /* Moving a non-directory onto an existing ++ directory is ok only with --backup. */ ++ } ++ else ++ { ++ error (0, 0, ++ _("cannot overwrite directory %s with non-directory"), ++ quote (dst_name)); ++ return false; ++ } ++ } ++ } ++ ++ if (x->move_mode) ++ { ++ /* Don't allow user to move a directory onto a non-directory. */ ++ if (S_ISDIR (src_sb.st_mode) && !S_ISDIR (dst_sb.st_mode) ++ && x->backup_type == no_backups) ++ { ++ error (0, 0, ++ _("cannot move directory onto non-directory: %s -> %s"), ++ quote_n (0, src_name), quote_n (0, dst_name)); ++ return false; ++ } ++ } ++ ++ if (x->backup_type != no_backups ++ /* Don't try to back up a destination if the last ++ component of src_name is "." or "..". */ ++ && ! dot_or_dotdot (last_component (src_name)) ++ /* Create a backup of each destination directory in move mode, ++ but not in copy mode. FIXME: it might make sense to add an ++ option to suppress backup creation also for move mode. ++ That would let one use mv to merge new content into an ++ existing hierarchy. */ ++ && (x->move_mode || ! S_ISDIR (dst_sb.st_mode))) ++ { ++ char *tmp_backup = find_backup_file_name (dst_name, ++ x->backup_type); ++ ++ /* Detect (and fail) when creating the backup file would ++ destroy the source file. Before, running the commands ++ cd /tmp; rm -f a a~; : > a; echo A > a~; cp --b=simple a~ a ++ would leave two zero-length files: a and a~. */ ++ /* FIXME: but simply change e.g., the final a~ to `./a~' ++ and the source will still be destroyed. */ ++ if (STREQ (tmp_backup, src_name)) ++ { ++ const char *fmt; ++ fmt = (x->move_mode ++ ? _("backing up %s would destroy source; %s not moved") ++ : _("backing up %s would destroy source; %s not copied")); ++ error (0, 0, fmt, ++ quote_n (0, dst_name), ++ quote_n (1, src_name)); ++ free (tmp_backup); ++ return false; ++ } ++ ++ /* FIXME: use fts: ++ Using alloca for a file name that may be arbitrarily ++ long is not recommended. In fact, even forming such a name ++ should be discouraged. Eventually, this code will be rewritten ++ to use fts, so using alloca here will be less of a problem. */ ++ ASSIGN_STRDUPA (dst_backup, tmp_backup); ++ free (tmp_backup); ++ if (rename (dst_name, dst_backup) != 0) ++ { ++ if (errno != ENOENT) ++ { ++ error (0, errno, _("cannot backup %s"), quote (dst_name)); ++ return false; ++ } ++ else ++ { ++ dst_backup = NULL; ++ } ++ } ++ else ++ { ++ backup_succeeded = true; ++ } ++ new_dst = true; ++ } ++ else if (! S_ISDIR (dst_sb.st_mode) ++ /* Never unlink dst_name when in move mode. */ ++ && ! x->move_mode ++ && (x->unlink_dest_before_opening ++ || (x->preserve_links && 1 < dst_sb.st_nlink) ++ || (x->dereference == DEREF_NEVER ++ && ! S_ISREG (src_sb.st_mode)) ++ )) ++ { ++ if (unlink (dst_name) != 0 && errno != ENOENT) ++ { ++ error (0, errno, _("cannot remove %s"), quote (dst_name)); ++ return false; ++ } ++ new_dst = true; ++ if (x->verbose) ++ printf (_("removed %s\n"), quote (dst_name)); ++ } ++ } ++ } ++ ++ /* Ensure we don't try to copy through a symlink that was ++ created by a prior call to this function. */ ++ if (command_line_arg ++ && x->dest_info ++ && ! x->move_mode ++ && x->backup_type == no_backups) ++ { ++ bool lstat_ok = true; ++ struct stat tmp_buf; ++ struct stat *dst_lstat_sb; ++ ++ /* If we called lstat above, good: use that data. ++ Otherwise, call lstat here, in case dst_name is a symlink. */ ++ if (have_dst_lstat) ++ dst_lstat_sb = &dst_sb; ++ else ++ { ++ if (lstat (dst_name, &tmp_buf) == 0) ++ dst_lstat_sb = &tmp_buf; ++ else ++ lstat_ok = false; ++ } ++ ++ /* Never copy through a symlink we've just created. */ ++ if (lstat_ok ++ && S_ISLNK (dst_lstat_sb->st_mode) ++ && seen_file (x->dest_info, dst_name, dst_lstat_sb)) ++ { ++ error (0, 0, ++ _("will not copy %s through just-created symlink %s"), ++ quote_n (0, src_name), quote_n (1, dst_name)); ++ return false; ++ } ++ } ++ ++ /* If the source is a directory, we don't always create the destination ++ directory. So --verbose should not announce anything until we're ++ sure we'll create a directory. */ ++ if (x->verbose && !S_ISDIR (src_mode)) ++ emit_verbose (src_name, dst_name, backup_succeeded ? dst_backup : NULL); ++ ++ /* Associate the destination file name with the source device and inode ++ so that if we encounter a matching dev/ino pair in the source tree ++ we can arrange to create a hard link between the corresponding names ++ in the destination tree. ++ ++ When using the --link (-l) option, there is no need to take special ++ measures, because (barring race conditions) files that are hard-linked ++ in the source tree will also be hard-linked in the destination tree. ++ ++ Sometimes, when preserving links, we have to record dev/ino even ++ though st_nlink == 1: ++ - when in move_mode, since we may be moving a group of N hard-linked ++ files (via two or more command line arguments) to a different ++ partition; the links may be distributed among the command line ++ arguments (possibly hierarchies) so that the link count of ++ the final, once-linked source file is reduced to 1 when it is ++ considered below. But in this case (for mv) we don't need to ++ incur the expense of recording the dev/ino => name mapping; all we ++ really need is a lookup, to see if the dev/ino pair has already ++ been copied. ++ - when using -H and processing a command line argument; ++ that command line argument could be a symlink pointing to another ++ command line argument. With `cp -H --preserve=link', we hard-link ++ those two destination files. ++ - likewise for -L except that it applies to all files, not just ++ command line arguments. ++ ++ Also, with --recursive, record dev/ino of each command-line directory. ++ We'll use that info to detect this problem: cp -R dir dir. */ ++ ++ if (x->move_mode && src_sb.st_nlink == 1) ++ { ++ earlier_file = src_to_dest_lookup (src_sb.st_ino, src_sb.st_dev); ++ } ++ else if (x->preserve_links ++ && !x->hard_link ++ && (1 < src_sb.st_nlink ++ || (command_line_arg ++ && x->dereference == DEREF_COMMAND_LINE_ARGUMENTS) ++ || x->dereference == DEREF_ALWAYS)) ++ { ++ earlier_file = remember_copied (dst_name, src_sb.st_ino, src_sb.st_dev); ++ } ++ else if (x->recursive && S_ISDIR (src_mode)) ++ { ++ if (command_line_arg) ++ earlier_file = remember_copied (dst_name, src_sb.st_ino, src_sb.st_dev); ++ else ++ earlier_file = src_to_dest_lookup (src_sb.st_ino, src_sb.st_dev); ++ } ++ ++ /* Did we copy this inode somewhere else (in this command line argument) ++ and therefore this is a second hard link to the inode? */ ++ ++ if (earlier_file) ++ { ++ /* Avoid damaging the destination file system by refusing to preserve ++ hard-linked directories (which are found at least in Netapp snapshot ++ directories). */ ++ if (S_ISDIR (src_mode)) ++ { ++ /* If src_name and earlier_file refer to the same directory entry, ++ then warn about copying a directory into itself. */ ++ if (same_name (src_name, earlier_file)) ++ { ++ error (0, 0, _("cannot copy a directory, %s, into itself, %s"), ++ quote_n (0, top_level_src_name), ++ quote_n (1, top_level_dst_name)); ++ *copy_into_self = true; ++ goto un_backup; ++ } ++ else if (x->dereference == DEREF_ALWAYS) ++ { ++ /* This happens when e.g., encountering a directory for the ++ second or subsequent time via symlinks when cp is invoked ++ with -R and -L. E.g., ++ rm -rf a b c d; mkdir a b c d; ln -s ../c a; ln -s ../c b; ++ cp -RL a b d ++ */ ++ } ++ else ++ { ++ error (0, 0, _("will not create hard link %s to directory %s"), ++ quote_n (0, dst_name), quote_n (1, earlier_file)); ++ goto un_backup; ++ } ++ } ++ else ++ { ++ /* We want to guarantee that symlinks are not followed. */ ++ bool link_failed = (linkat (AT_FDCWD, earlier_file, AT_FDCWD, ++ dst_name, 0) != 0); ++ ++ /* If the link failed because of an existing destination, ++ remove that file and then call link again. */ ++ if (link_failed && errno == EEXIST) ++ { ++ if (unlink (dst_name) != 0) ++ { ++ error (0, errno, _("cannot remove %s"), quote (dst_name)); ++ goto un_backup; ++ } ++ if (x->verbose) ++ printf (_("removed %s\n"), quote (dst_name)); ++ link_failed = (linkat (AT_FDCWD, earlier_file, AT_FDCWD, ++ dst_name, 0) != 0); ++ } ++ ++ if (link_failed) ++ { ++ error (0, errno, _("cannot create hard link %s to %s"), ++ quote_n (0, dst_name), quote_n (1, earlier_file)); ++ goto un_backup; ++ } ++ ++ return true; ++ } ++ } ++ ++ if (x->move_mode) ++ { ++ if (rename (src_name, dst_name) == 0) ++ { ++ if (x->verbose && S_ISDIR (src_mode)) ++ emit_verbose (src_name, dst_name, ++ backup_succeeded ? dst_backup : NULL); ++ ++ if (rename_succeeded) ++ *rename_succeeded = true; ++ ++ if (command_line_arg) ++ { ++ /* Record destination dev/ino/name, so that if we are asked ++ to overwrite that file again, we can detect it and fail. */ ++ /* It's fine to use the _source_ stat buffer (src_sb) to get the ++ _destination_ dev/ino, since the rename above can't have ++ changed those, and `mv' always uses lstat. ++ We could limit it further by operating ++ only on non-directories. */ ++ record_file (x->dest_info, dst_name, &src_sb); ++ } ++ ++ return true; ++ } ++ ++ /* FIXME: someday, consider what to do when moving a directory into ++ itself but when source and destination are on different devices. */ ++ ++ /* This happens when attempting to rename a directory to a ++ subdirectory of itself. */ ++ if (errno == EINVAL) ++ { ++ /* FIXME: this is a little fragile in that it relies on rename(2) ++ failing with a specific errno value. Expect problems on ++ non-POSIX systems. */ ++ error (0, 0, _("cannot move %s to a subdirectory of itself, %s"), ++ quote_n (0, top_level_src_name), ++ quote_n (1, top_level_dst_name)); ++ ++ /* Note that there is no need to call forget_created here, ++ (compare with the other calls in this file) since the ++ destination directory didn't exist before. */ ++ ++ *copy_into_self = true; ++ /* FIXME-cleanup: Don't return true here; adjust mv.c accordingly. ++ The only caller that uses this code (mv.c) ends up setting its ++ exit status to nonzero when copy_into_self is nonzero. */ ++ return true; ++ } ++ ++ /* WARNING: there probably exist systems for which an inter-device ++ rename fails with a value of errno not handled here. ++ If/as those are reported, add them to the condition below. ++ If this happens to you, please do the following and send the output ++ to the bug-reporting address (e.g., in the output of cp --help): ++ touch k; perl -e 'rename "k","/tmp/k" or print "$!(",$!+0,")\n"' ++ where your current directory is on one partion and /tmp is the other. ++ Also, please try to find the E* errno macro name corresponding to ++ the diagnostic and parenthesized integer, and include that in your ++ e-mail. One way to do that is to run a command like this ++ find /usr/include/. -type f \ ++ | xargs grep 'define.*\.*\<18\>' /dev/null ++ where you'd replace `18' with the integer in parentheses that ++ was output from the perl one-liner above. ++ If necessary, of course, change `/tmp' to some other directory. */ ++ if (errno != EXDEV) ++ { ++ /* There are many ways this can happen due to a race condition. ++ When something happens between the initial XSTAT and the ++ subsequent rename, we can get many different types of errors. ++ For example, if the destination is initially a non-directory ++ or non-existent, but it is created as a directory, the rename ++ fails. If two `mv' commands try to rename the same file at ++ about the same time, one will succeed and the other will fail. ++ If the permissions on the directory containing the source or ++ destination file are made too restrictive, the rename will ++ fail. Etc. */ ++ error (0, errno, ++ _("cannot move %s to %s"), ++ quote_n (0, src_name), quote_n (1, dst_name)); ++ forget_created (src_sb.st_ino, src_sb.st_dev); ++ return false; ++ } ++ ++ /* The rename attempt has failed. Remove any existing destination ++ file so that a cross-device `mv' acts as if it were really using ++ the rename syscall. */ ++ if (unlink (dst_name) != 0 && errno != ENOENT) ++ { ++ error (0, errno, ++ _("inter-device move failed: %s to %s; unable to remove target"), ++ quote_n (0, src_name), quote_n (1, dst_name)); ++ forget_created (src_sb.st_ino, src_sb.st_dev); ++ return false; ++ } ++ ++ new_dst = true; ++ } ++ ++ /* If the ownership might change, or if it is a directory (whose ++ special mode bits may change after the directory is created), ++ omit some permissions at first, so unauthorized users cannot nip ++ in before the file is ready. */ ++ dst_mode_bits = (x->set_mode ? x->mode : src_mode) & CHMOD_MODE_BITS; ++ omitted_permissions = ++ (dst_mode_bits ++ & (x->preserve_ownership ? S_IRWXG | S_IRWXO ++ : S_ISDIR (src_mode) ? S_IWGRP | S_IWOTH ++ : 0)); ++ ++ delayed_ok = true; ++ ++ if (x->preserve_security_context) ++ { ++ security_context_t con; ++ ++ if (0 <= lgetfilecon (src_name, &con)) ++ { ++ if (setfscreatecon (con) < 0) ++ { ++ if (!x->reduce_diagnostics || x->require_preserve_context) ++ error (0, errno, ++ _("failed to set default file creation context to %s"), ++ quote (con)); ++ if (x->require_preserve_context) ++ { ++ freecon (con); ++ return false; ++ } ++ } ++ freecon (con); ++ } ++ else ++ { ++ if (!errno_unsupported (errno) || x->require_preserve_context) ++ { ++ if (!x->reduce_diagnostics || x->require_preserve_context) ++ error (0, errno, ++ _("failed to get security context of %s"), ++ quote (src_name)); ++ if (x->require_preserve_context) ++ return false; ++ } ++ } ++ } ++ ++ if (S_ISDIR (src_mode)) ++ { ++ struct dir_list *dir; ++ ++ /* If this directory has been copied before during the ++ recursion, there is a symbolic link to an ancestor ++ directory of the symbolic link. It is impossible to ++ continue to copy this, unless we've got an infinite disk. */ ++ ++ if (is_ancestor (&src_sb, ancestors)) ++ { ++ error (0, 0, _("cannot copy cyclic symbolic link %s"), ++ quote (src_name)); ++ goto un_backup; ++ } ++ ++ /* Insert the current directory in the list of parents. */ ++ ++ dir = alloca (sizeof *dir); ++ dir->parent = ancestors; ++ dir->ino = src_sb.st_ino; ++ dir->dev = src_sb.st_dev; ++ ++ if (new_dst || !S_ISDIR (dst_sb.st_mode)) ++ { ++ /* POSIX says mkdir's behavior is implementation-defined when ++ (src_mode & ~S_IRWXUGO) != 0. However, common practice is ++ to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir ++ decide what to do with S_ISUID | S_ISGID | S_ISVTX. */ ++ if (mkdir (dst_name, dst_mode_bits & ~omitted_permissions) != 0) ++ { ++ error (0, errno, _("cannot create directory %s"), ++ quote (dst_name)); ++ goto un_backup; ++ } ++ ++ /* We need search and write permissions to the new directory ++ for writing the directory's contents. Check if these ++ permissions are there. */ ++ ++ if (lstat (dst_name, &dst_sb) != 0) ++ { ++ error (0, errno, _("cannot stat %s"), quote (dst_name)); ++ goto un_backup; ++ } ++ else if ((dst_sb.st_mode & S_IRWXU) != S_IRWXU) ++ { ++ /* Make the new directory searchable and writable. */ ++ ++ dst_mode = dst_sb.st_mode; ++ restore_dst_mode = true; ++ ++ if (lchmod (dst_name, dst_mode | S_IRWXU) != 0) ++ { ++ error (0, errno, _("setting permissions for %s"), ++ quote (dst_name)); ++ goto un_backup; ++ } ++ } ++ ++ /* Record the created directory's inode and device numbers into ++ the search structure, so that we can avoid copying it again. ++ Do this only for the first directory that is created for each ++ source command line argument. */ ++ if (!*first_dir_created_per_command_line_arg) ++ { ++ remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev); ++ *first_dir_created_per_command_line_arg = true; ++ } ++ ++ if (x->verbose) ++ emit_verbose (src_name, dst_name, NULL); ++ } ++ ++ /* Decide whether to copy the contents of the directory. */ ++ if (x->one_file_system && device != 0 && device != src_sb.st_dev) ++ { ++ /* Here, we are crossing a file system boundary and cp's -x option ++ is in effect: so don't copy the contents of this directory. */ ++ } ++ else ++ { ++ /* Copy the contents of the directory. Don't just return if ++ this fails -- otherwise, the failure to read a single file ++ in a source directory would cause the containing destination ++ directory not to have owner/perms set properly. */ ++ delayed_ok = copy_dir (src_name, dst_name, new_dst, &src_sb, dir, x, ++ first_dir_created_per_command_line_arg, ++ copy_into_self); ++ } ++ } ++ else if (x->symbolic_link) ++ { ++ dest_is_symlink = true; ++ if (*src_name != '/') ++ { ++ /* Check that DST_NAME denotes a file in the current directory. */ ++ struct stat dot_sb; ++ struct stat dst_parent_sb; ++ char *dst_parent; ++ bool in_current_dir; ++ ++ dst_parent = dir_name (dst_name); ++ ++ in_current_dir = (STREQ (".", dst_parent) ++ /* If either stat call fails, it's ok not to report ++ the failure and say dst_name is in the current ++ directory. Other things will fail later. */ ++ || stat (".", &dot_sb) != 0 ++ || stat (dst_parent, &dst_parent_sb) != 0 ++ || SAME_INODE (dot_sb, dst_parent_sb)); ++ free (dst_parent); ++ ++ if (! in_current_dir) ++ { ++ error (0, 0, ++ _("%s: can make relative symbolic links only in current directory"), ++ quote (dst_name)); ++ goto un_backup; ++ } ++ } ++ if (symlink (src_name, dst_name) != 0) ++ { ++ error (0, errno, _("cannot create symbolic link %s to %s"), ++ quote_n (0, dst_name), quote_n (1, src_name)); ++ goto un_backup; ++ } ++ } ++ ++ /* cp, invoked with `--link --no-dereference', should not follow the ++ link; we guarantee this with gnulib's linkat module (on systems ++ where link(2) follows the link, gnulib creates a symlink with ++ identical contents, which is good enough for our purposes). */ ++ else if (x->hard_link ++ && (!S_ISLNK (src_mode) ++ || x->dereference != DEREF_NEVER)) ++ { ++ if (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, 0)) ++ { ++ error (0, errno, _("cannot create link %s"), quote (dst_name)); ++ goto un_backup; ++ } ++ } ++ else if (S_ISREG (src_mode) ++ || (x->copy_as_regular && !S_ISLNK (src_mode))) ++ { ++ copied_as_regular = true; ++ /* POSIX says the permission bits of the source file must be ++ used as the 3rd argument in the open call. Historical ++ practice passed all the source mode bits to 'open', but the extra ++ bits were ignored, so it should be the same either way. */ ++ if (! copy_reg (src_name, dst_name, x, src_mode & S_IRWXUGO, ++ omitted_permissions, &new_dst, &src_sb)) ++ goto un_backup; ++ } ++ else if (S_ISFIFO (src_mode)) ++ { ++ /* Use mknod, rather than mkfifo, because the former preserves ++ the special mode bits of a fifo on Solaris 10, while mkfifo ++ does not. But fall back on mkfifo, because on some BSD systems, ++ mknod always fails when asked to create a FIFO. */ ++ if (mknod (dst_name, src_mode & ~omitted_permissions, 0) != 0) ++ if (mkfifo (dst_name, src_mode & ~S_IFIFO & ~omitted_permissions) != 0) ++ { ++ error (0, errno, _("cannot create fifo %s"), quote (dst_name)); ++ goto un_backup; ++ } ++ } ++ else if (S_ISBLK (src_mode) || S_ISCHR (src_mode) || S_ISSOCK (src_mode)) ++ { ++ if (mknod (dst_name, src_mode & ~omitted_permissions, src_sb.st_rdev) ++ != 0) ++ { ++ error (0, errno, _("cannot create special file %s"), ++ quote (dst_name)); ++ goto un_backup; ++ } ++ } ++ else if (S_ISLNK (src_mode)) ++ { ++ char *src_link_val = areadlink_with_size (src_name, src_sb.st_size); ++ dest_is_symlink = true; ++ if (src_link_val == NULL) ++ { ++ error (0, errno, _("cannot read symbolic link %s"), quote (src_name)); ++ goto un_backup; ++ } ++ ++ if (symlink (src_link_val, dst_name) == 0) ++ free (src_link_val); ++ else ++ { ++ int saved_errno = errno; ++ bool same_link = false; ++ if (x->update && !new_dst && S_ISLNK (dst_sb.st_mode) ++ && dst_sb.st_size == strlen (src_link_val)) ++ { ++ /* See if the destination is already the desired symlink. ++ FIXME: This behavior isn't documented, and seems wrong ++ in some cases, e.g., if the destination symlink has the ++ wrong ownership, permissions, or time stamps. */ ++ char *dest_link_val = ++ areadlink_with_size (dst_name, dst_sb.st_size); ++ if (dest_link_val && STREQ (dest_link_val, src_link_val)) ++ same_link = true; ++ free (dest_link_val); ++ } ++ free (src_link_val); ++ ++ if (! same_link) ++ { ++ error (0, saved_errno, _("cannot create symbolic link %s"), ++ quote (dst_name)); ++ goto un_backup; ++ } ++ } ++ ++ if (x->preserve_security_context) ++ restore_default_fscreatecon_or_die (); ++ ++ if (x->preserve_ownership) ++ { ++ /* Preserve the owner and group of the just-`copied' ++ symbolic link, if possible. */ ++ if (HAVE_LCHOWN ++ && lchown (dst_name, src_sb.st_uid, src_sb.st_gid) != 0 ++ && ! chown_failure_ok (x)) ++ { ++ error (0, errno, _("failed to preserve ownership for %s"), ++ dst_name); ++ goto un_backup; ++ } ++ else ++ { ++ /* Can't preserve ownership of symlinks. ++ FIXME: maybe give a warning or even error for symlinks ++ in directories with the sticky bit set -- there, not ++ preserving owner/group is a potential security problem. */ ++ } ++ } ++ } ++ else ++ { ++ error (0, 0, _("%s has unknown file type"), quote (src_name)); ++ goto un_backup; ++ } ++ ++ if (command_line_arg && x->dest_info) ++ { ++ /* Now that the destination file is very likely to exist, ++ add its info to the set. */ ++ struct stat sb; ++ if (lstat (dst_name, &sb) == 0) ++ record_file (x->dest_info, dst_name, &sb); ++ } ++ ++ /* If we've just created a hard-link due to cp's --link option, ++ we're done. */ ++ if (x->hard_link && ! S_ISDIR (src_mode)) ++ return delayed_ok; ++ ++ if (copied_as_regular) ++ return delayed_ok; ++ ++ /* POSIX says that `cp -p' must restore the following: ++ - permission bits ++ - setuid, setgid bits ++ - owner and group ++ If it fails to restore any of those, we may give a warning but ++ the destination must not be removed. ++ FIXME: implement the above. */ ++ ++ /* Adjust the times (and if possible, ownership) for the copy. ++ chown turns off set[ug]id bits for non-root, ++ so do the chmod last. */ ++ ++ if (x->preserve_timestamps) ++ { ++ struct timespec timespec[2]; ++ timespec[0] = get_stat_atime (&src_sb); ++ timespec[1] = get_stat_mtime (&src_sb); ++ ++ if ((dest_is_symlink ++ ? utimens_symlink (dst_name, timespec) ++ : utimens (dst_name, timespec)) ++ != 0) ++ { ++ error (0, errno, _("preserving times for %s"), quote (dst_name)); ++ if (x->require_preserve) ++ return false; ++ } ++ } ++ ++ /* The operations beyond this point may dereference a symlink. */ ++ if (dest_is_symlink) ++ return delayed_ok; ++ ++ /* Avoid calling chown if we know it's not necessary. */ ++ if (x->preserve_ownership ++ && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb))) ++ { ++ switch (set_owner (x, dst_name, -1, &src_sb, new_dst, &dst_sb)) ++ { ++ case -1: ++ return false; ++ ++ case 0: ++ src_mode &= ~ (S_ISUID | S_ISGID | S_ISVTX); ++ break; ++ } ++ } ++ ++ set_author (dst_name, -1, &src_sb); ++ ++ if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name, x) ++ && x->require_preserve_xattr) ++ return false; ++ ++ if (x->preserve_mode || x->move_mode) ++ { ++ if (copy_acl (src_name, -1, dst_name, -1, src_mode) != 0 ++ && x->require_preserve) ++ return false; ++ } ++ else if (x->set_mode) ++ { ++ if (set_acl (dst_name, -1, x->mode) != 0) ++ return false; ++ } ++ else ++ { ++ if (omitted_permissions) ++ { ++ omitted_permissions &= ~ cached_umask (); ++ ++ if (omitted_permissions && !restore_dst_mode) ++ { ++ /* Permissions were deliberately omitted when the file ++ was created due to security concerns. See whether ++ they need to be re-added now. It'd be faster to omit ++ the lstat, but deducing the current destination mode ++ is tricky in the presence of implementation-defined ++ rules for special mode bits. */ ++ if (new_dst && lstat (dst_name, &dst_sb) != 0) ++ { ++ error (0, errno, _("cannot stat %s"), quote (dst_name)); ++ return false; ++ } ++ dst_mode = dst_sb.st_mode; ++ if (omitted_permissions & ~dst_mode) ++ restore_dst_mode = true; ++ } ++ } ++ ++ if (restore_dst_mode) ++ { ++ if (lchmod (dst_name, dst_mode | omitted_permissions) != 0) ++ { ++ error (0, errno, _("preserving permissions for %s"), ++ quote (dst_name)); ++ if (x->require_preserve) ++ return false; ++ } ++ } ++ } ++ ++ return delayed_ok; ++ ++un_backup: ++ ++ if (x->preserve_security_context) ++ restore_default_fscreatecon_or_die (); ++ ++ /* We have failed to create the destination file. ++ If we've just added a dev/ino entry via the remember_copied ++ call above (i.e., unless we've just failed to create a hard link), ++ remove the entry associating the source dev/ino with the ++ destination file name, so we don't try to `preserve' a link ++ to a file we didn't create. */ ++ if (earlier_file == NULL) ++ forget_created (src_sb.st_ino, src_sb.st_dev); ++ ++ if (dst_backup) ++ { ++ if (rename (dst_backup, dst_name) != 0) ++ error (0, errno, _("cannot un-backup %s"), quote (dst_name)); ++ else ++ { ++ if (x->verbose) ++ printf (_("%s -> %s (unbackup)\n"), ++ quote_n (0, dst_backup), quote_n (1, dst_name)); ++ } ++ } ++ return false; ++} ++ ++static bool ++valid_options (const struct cp_options *co) ++{ ++ assert (co != NULL); ++ assert (VALID_BACKUP_TYPE (co->backup_type)); ++ assert (VALID_SPARSE_MODE (co->sparse_mode)); ++ assert (VALID_REFLINK_MODE (co->reflink_mode)); ++ assert (!(co->hard_link && co->symbolic_link)); ++ assert (! ++ (co->reflink_mode == REFLINK_ALWAYS ++ && co->sparse_mode != SPARSE_AUTO)); ++ return true; ++} ++ ++/* Copy the file SRC_NAME to the file DST_NAME. The files may be of ++ any type. NONEXISTENT_DST should be true if the file DST_NAME ++ is known not to exist (e.g., because its parent directory was just ++ created); NONEXISTENT_DST should be false if DST_NAME might already ++ exist. OPTIONS is ... FIXME-describe ++ Set *COPY_INTO_SELF if SRC_NAME is a parent of (or the ++ same as) DST_NAME; otherwise, set clear it. ++ Return true if successful. */ ++ ++extern bool ++copy (char const *src_name, char const *dst_name, ++ bool nonexistent_dst, const struct cp_options *options, ++ bool *copy_into_self, bool *rename_succeeded) ++{ ++ assert (valid_options (options)); ++ ++ /* Record the file names: they're used in case of error, when copying ++ a directory into itself. I don't like to make these tools do *any* ++ extra work in the common case when that work is solely to handle ++ exceptional cases, but in this case, I don't see a way to derive the ++ top level source and destination directory names where they're used. ++ An alternative is to use COPY_INTO_SELF and print the diagnostic ++ from every caller -- but I don't want to do that. */ ++ top_level_src_name = src_name; ++ top_level_dst_name = dst_name; ++ ++ bool first_dir_created_per_command_line_arg = false; ++ return copy_internal (src_name, dst_name, nonexistent_dst, 0, NULL, ++ options, true, ++ &first_dir_created_per_command_line_arg, ++ copy_into_self, rename_succeeded); ++} ++ ++/* Set *X to the default options for a value of type struct cp_options. */ ++ ++extern void ++cp_options_default (struct cp_options *x) ++{ ++ memset (x, 0, sizeof *x); ++#ifdef PRIV_FILE_CHOWN ++ { ++ priv_set_t *pset = priv_allocset (); ++ if (!pset) ++ xalloc_die (); ++ if (getppriv (PRIV_EFFECTIVE, pset) == 0) ++ { ++ x->chown_privileges = priv_ismember (pset, PRIV_FILE_CHOWN); ++ x->owner_privileges = priv_ismember (pset, PRIV_FILE_OWNER); ++ } ++ priv_freeset (pset); ++ } ++#else ++ x->chown_privileges = x->owner_privileges = (geteuid () == 0); ++#endif ++} ++ ++/* Return true if it's OK for chown to fail, where errno is ++ the error number that chown failed with and X is the copying ++ option set. */ ++ ++extern bool ++chown_failure_ok (struct cp_options const *x) ++{ ++ /* If non-root uses -p, it's ok if we can't preserve ownership. ++ But root probably wants to know, e.g. if NFS disallows it, ++ or if the target system doesn't support file ownership. */ ++ ++ return ((errno == EPERM || errno == EINVAL) && !x->chown_privileges); ++} ++ ++/* Similarly, return true if it's OK for chmod and similar operations ++ to fail, where errno is the error number that chmod failed with and ++ X is the copying option set. */ ++ ++static bool ++owner_failure_ok (struct cp_options const *x) ++{ ++ return ((errno == EPERM || errno == EINVAL) && !x->owner_privileges); ++} ++ ++/* Return the user's umask, caching the result. */ ++ ++extern mode_t ++cached_umask (void) ++{ ++ static mode_t mask = (mode_t) -1; ++ if (mask == (mode_t) -1) ++ { ++ mask = umask (0); ++ umask (mask); ++ } ++ return mask; ++} +diff -urNp coreutils-8.0-orig/src/copy.h coreutils-8.0/src/copy.h +--- coreutils-8.0-orig/src/copy.h 2009-09-21 14:29:33.000000000 +0200 ++++ coreutils-8.0/src/copy.h 2009-10-07 10:10:11.000000000 +0200 +@@ -158,6 +158,9 @@ struct cp_options bool preserve_mode; bool preserve_timestamps; @@ -59,10 +2449,297 @@ diff -urNp coreutils-7.1-orig/src/copy.h coreutils-7.1/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c ---- coreutils-7.1-orig/src/cp.c 2009-02-18 15:32:52.000000000 +0100 -+++ coreutils-7.1/src/cp.c 2009-02-24 13:47:15.000000000 +0100 -@@ -133,6 +133,7 @@ static struct option const long_opts[] = +diff -urNp coreutils-8.0-orig/src/copy.h.orig coreutils-8.0/src/copy.h.orig +--- coreutils-8.0-orig/src/copy.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/copy.h.orig 2009-09-21 14:29:33.000000000 +0200 +@@ -0,0 +1,283 @@ ++/* core functions for copying files and directories ++ Copyright (C) 89, 90, 91, 1995-2009 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 . */ ++ ++/* Extracted from cp.c and librarified by Jim Meyering. */ ++ ++#ifndef COPY_H ++# define COPY_H ++ ++# include ++# include "hash.h" ++ ++/* Control creation of sparse files (files with holes). */ ++enum Sparse_type ++{ ++ SPARSE_UNUSED, ++ ++ /* Never create holes in DEST. */ ++ SPARSE_NEVER, ++ ++ /* This is the default. Use a crude (and sometimes inaccurate) ++ heuristic to determine if SOURCE has holes. If so, try to create ++ holes in DEST. */ ++ SPARSE_AUTO, ++ ++ /* For every sufficiently long sequence of bytes in SOURCE, try to ++ create a corresponding hole in DEST. There is a performance penalty ++ here because CP has to search for holes in SRC. But if the holes are ++ big enough, that penalty can be offset by the decrease in the amount ++ of data written to disk. */ ++ SPARSE_ALWAYS ++}; ++ ++/* Control creation of COW files. */ ++enum Reflink_type ++{ ++ /* Default to a standard copy. */ ++ REFLINK_NEVER, ++ ++ /* Try a COW copy and fall back to a standard copy. */ ++ REFLINK_AUTO, ++ ++ /* Require a COW copy and fail if not available. */ ++ REFLINK_ALWAYS ++}; ++ ++/* This type is used to help mv (via copy.c) distinguish these cases. */ ++enum Interactive ++{ ++ I_ALWAYS_YES = 1, ++ I_ALWAYS_NO, ++ I_ASK_USER, ++ I_UNSPECIFIED ++}; ++ ++/* How to handle symbolic links. */ ++enum Dereference_symlink ++{ ++ DEREF_UNDEFINED = 1, ++ ++ /* Copy the symbolic link itself. -P */ ++ DEREF_NEVER, ++ ++ /* If the symbolic is a command line argument, then copy ++ its referent. Otherwise, copy the symbolic link itself. -H */ ++ DEREF_COMMAND_LINE_ARGUMENTS, ++ ++ /* Copy the referent of the symbolic link. -L */ ++ DEREF_ALWAYS ++}; ++ ++# define VALID_SPARSE_MODE(Mode) \ ++ ((Mode) == SPARSE_NEVER \ ++ || (Mode) == SPARSE_AUTO \ ++ || (Mode) == SPARSE_ALWAYS) ++ ++# define VALID_REFLINK_MODE(Mode) \ ++ ((Mode) == REFLINK_NEVER \ ++ || (Mode) == REFLINK_AUTO \ ++ || (Mode) == REFLINK_ALWAYS) ++ ++/* These options control how files are copied by at least the ++ following programs: mv (when rename doesn't work), cp, install. ++ So, if you add a new member, be sure to initialize it in ++ mv.c, cp.c, and install.c. */ ++struct cp_options ++{ ++ enum backup_type backup_type; ++ ++ /* How to handle symlinks in the source. */ ++ enum Dereference_symlink dereference; ++ ++ /* This value is used to determine whether to prompt before removing ++ each existing destination file. It works differently depending on ++ whether move_mode is set. See code/comments in copy.c. */ ++ enum Interactive interactive; ++ ++ /* Control creation of sparse files. */ ++ enum Sparse_type sparse_mode; ++ ++ /* Set the mode of the destination file to exactly this value ++ if SET_MODE is nonzero. */ ++ mode_t mode; ++ ++ /* If true, copy all files except (directories and, if not dereferencing ++ them, symbolic links,) as if they were regular files. */ ++ bool copy_as_regular; ++ ++ /* If true, remove each existing destination nondirectory before ++ trying to open it. */ ++ bool unlink_dest_before_opening; ++ ++ /* If true, first try to open each existing destination nondirectory, ++ then, if the open fails, unlink and try again. ++ This option must be set for `cp -f', in case the destination file ++ exists when the open is attempted. It is irrelevant to `mv' since ++ any destination is sure to be removed before the open. */ ++ bool unlink_dest_after_failed_open; ++ ++ /* If true, create hard links instead of copying files. ++ Create destination directories as usual. */ ++ bool hard_link; ++ ++ /* If true, rather than copying, first attempt to use rename. ++ If that fails, then resort to copying. */ ++ bool move_mode; ++ ++ /* Whether this process has appropriate privileges to chown a file ++ whose owner is not the effective user ID. */ ++ bool chown_privileges; ++ ++ /* Whether this process has appropriate privileges to do the ++ following operations on a file even when it is owned by some ++ other user: set the file's atime, mtime, mode, or ACL; remove or ++ rename an entry in the file even though it is a sticky directory, ++ or to mount on the file. */ ++ bool owner_privileges; ++ ++ /* If true, when copying recursively, skip any subdirectories that are ++ on different file systems from the one we started on. */ ++ bool one_file_system; ++ ++ /* If true, attempt to give the copies the original files' permissions, ++ owner, group, and timestamps. */ ++ bool preserve_ownership; ++ bool preserve_mode; ++ bool preserve_timestamps; ++ ++ /* Enabled for mv, and for cp by the --preserve=links option. ++ If true, attempt to preserve in the destination files any ++ logical hard links between the source files. If used with cp's ++ --no-dereference option, and copying two hard-linked files, ++ the two corresponding destination files will also be hard linked. ++ ++ If used with cp's --dereference (-L) option, then, as that option implies, ++ hard links are *not* preserved. However, when copying a file F and ++ a symlink S to F, the resulting S and F in the destination directory ++ will be hard links to the same file (a copy of F). */ ++ bool preserve_links; ++ ++ /* If true and any of the above (for preserve) file attributes cannot ++ be applied to a destination file, treat it as a failure and return ++ nonzero immediately. E.g. for cp -p this must be true, for mv it ++ must be false. */ ++ bool require_preserve; ++ ++ /* If true, attempt to preserve the SELinux security context, too. ++ Set this only if the kernel is SELinux enabled. */ ++ bool preserve_security_context; ++ ++ /* Useful only when preserve_security_context is true. ++ If true, a failed attempt to preserve a file's security context ++ propagates failure "out" to the caller. If false, a failure to ++ preserve a file's security context does not change the invoking ++ application's exit status. Give diagnostics for failed syscalls ++ regardless of this setting. For example, with "cp --preserve=context" ++ this flag is "true", while with "cp -a", it is false. That means ++ "cp -a" attempts to preserve any security context, but does not ++ fail if it is unable to do so. */ ++ bool require_preserve_context; ++ ++ /* If true, attempt to preserve extended attributes using libattr. ++ Ignored if coreutils are compiled without xattr support. */ ++ bool preserve_xattr; ++ ++ /* Useful only when preserve_xattr is true. ++ If true, a failed attempt to preserve file's extended attributes ++ propagates failure "out" to the caller. If false, a failure to ++ preserve file's extended attributes does not change the invoking ++ application's exit status. Give diagnostics for failed syscalls ++ regardless of this setting. For example, with "cp --preserve=xattr" ++ this flag is "true", while with "cp --preserve=all", it is false. */ ++ bool require_preserve_xattr; ++ ++ /* Used as difference boolean between cp -a and cp -dR --preserve=all. ++ If true, non-mandatory failure diagnostics are not displayed. This ++ should prevent poluting cp -a output. ++ */ ++ bool reduce_diagnostics; ++ ++ /* If true, copy directories recursively and copy special files ++ as themselves rather than copying their contents. */ ++ bool recursive; ++ ++ /* If true, set file mode to value of MODE. Otherwise, ++ set it based on current umask modified by UMASK_KILL. */ ++ bool set_mode; ++ ++ /* If true, create symbolic links instead of copying files. ++ Create destination directories as usual. */ ++ bool symbolic_link; ++ ++ /* If true, do not copy a nondirectory that has an existing destination ++ with the same or newer modification time. */ ++ bool update; ++ ++ /* If true, display the names of the files before copying them. */ ++ bool verbose; ++ ++ /* If true, stdin is a tty. */ ++ bool stdin_tty; ++ ++ /* If true, open a dangling destination symlink when not in move_mode. ++ Otherwise, copy_reg gives a diagnostic (it refuses to write through ++ such a symlink) and returns false. */ ++ bool open_dangling_dest_symlink; ++ ++ /* Control creation of COW files. */ ++ enum Reflink_type reflink_mode; ++ ++ /* This is a set of destination name/inode/dev triples. Each such triple ++ represents a file we have created corresponding to a source file name ++ that was specified on the command line. Use it to avoid clobbering ++ source files in commands like this: ++ rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c ++ For now, it protects only regular files when copying (i.e. not renaming). ++ When renaming, it protects all non-directories. ++ Use dest_info_init to initialize it, or set it to NULL to disable ++ this feature. */ ++ Hash_table *dest_info; ++ ++ /* FIXME */ ++ Hash_table *src_info; ++}; ++ ++# define XSTAT(X, Src_name, Src_sb) \ ++ ((X)->dereference == DEREF_NEVER \ ++ ? lstat (Src_name, Src_sb) \ ++ : stat (Src_name, Src_sb)) ++ ++/* Arrange to make rename calls go through the wrapper function ++ on systems with a rename function that fails for a source file name ++ specified with a trailing slash. */ ++# if RENAME_TRAILING_SLASH_BUG ++int rpl_rename (const char *, const char *); ++# undef rename ++# define rename rpl_rename ++# endif ++ ++bool copy (char const *src_name, char const *dst_name, ++ bool nonexistent_dst, const struct cp_options *options, ++ bool *copy_into_self, bool *rename_succeeded); ++ ++void dest_info_init (struct cp_options *); ++void src_info_init (struct cp_options *); ++ ++void cp_options_default (struct cp_options *); ++bool chown_failure_ok (struct cp_options const *); ++mode_t cached_umask (void); ++ ++#endif +diff -urNp coreutils-8.0-orig/src/cp.c coreutils-8.0/src/cp.c +--- coreutils-8.0-orig/src/cp.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/cp.c 2009-10-07 10:10:11.000000000 +0200 +@@ -139,6 +139,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, {"verbose", no_argument, NULL, 'v'}, @@ -70,7 +2747,7 @@ diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -191,6 +192,9 @@ Mandatory arguments to long options are +@@ -197,6 +198,9 @@ Mandatory arguments to long options are all\n\ "), stdout); fputs (_("\ @@ -80,7 +2757,7 @@ diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents use full source file name under DIRECTORY\n\ "), stdout); -@@ -216,6 +220,7 @@ Mandatory arguments to long options are +@@ -223,6 +227,7 @@ Mandatory arguments to long options are destination file is missing\n\ -v, --verbose explain what is being done\n\ -x, --one-file-system stay on this file system\n\ @@ -88,7 +2765,7 @@ diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); -@@ -765,6 +770,7 @@ cp_option_init (struct cp_options *x) +@@ -777,6 +782,7 @@ cp_option_init (struct cp_options *x) x->preserve_timestamps = false; x->preserve_security_context = false; x->require_preserve_context = false; @@ -96,7 +2773,7 @@ diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c x->preserve_xattr = false; x->reduce_diagnostics = false; x->require_preserve_xattr = false; -@@ -911,7 +917,7 @@ main (int argc, char **argv) +@@ -923,7 +929,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -105,7 +2782,7 @@ diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c long_opts, NULL)) != -1) { -@@ -945,6 +951,16 @@ main (int argc, char **argv) +@@ -966,6 +972,16 @@ main (int argc, char **argv) copy_contents = true; break; @@ -122,7 +2799,7 @@ diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -@@ -1054,6 +1070,27 @@ main (int argc, char **argv) +@@ -1075,6 +1091,27 @@ main (int argc, char **argv) x.one_file_system = true; break; @@ -150,10 +2827,1174 @@ diff -urNp coreutils-7.1-orig/src/cp.c coreutils-7.1/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urNp coreutils-7.1-orig/src/chcon.c coreutils-7.1/src/chcon.c ---- coreutils-7.1-orig/src/chcon.c 2008-10-12 16:12:56.000000000 +0200 -+++ coreutils-7.1/src/chcon.c 2009-02-24 13:47:15.000000000 +0100 -@@ -346,7 +346,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ +diff -urNp coreutils-8.0-orig/src/cp.c.orig coreutils-8.0/src/cp.c.orig +--- coreutils-8.0-orig/src/cp.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/cp.c.orig 2009-09-29 15:27:54.000000000 +0200 +@@ -0,0 +1,1160 @@ ++/* cp.c -- file copying (main routines) ++ Copyright (C) 89, 90, 91, 1995-2009 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 Torbjorn Granlund, David MacKenzie, and Jim Meyering. */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "system.h" ++#include "argmatch.h" ++#include "backupfile.h" ++#include "copy.h" ++#include "cp-hash.h" ++#include "error.h" ++#include "filenamecat.h" ++#include "ignore-value.h" ++#include "quote.h" ++#include "stat-time.h" ++#include "utimens.h" ++#include "acl.h" ++ ++#if ! HAVE_LCHOWN ++# define lchown(name, uid, gid) chown (name, uid, gid) ++#endif ++ ++#define ASSIGN_BASENAME_STRDUPA(Dest, File_name) \ ++ do \ ++ { \ ++ char *tmp_abns_; \ ++ ASSIGN_STRDUPA (tmp_abns_, (File_name)); \ ++ Dest = last_component (tmp_abns_); \ ++ strip_trailing_slashes (Dest); \ ++ } \ ++ while (0) ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "cp" ++ ++#define AUTHORS \ ++ proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \ ++ proper_name ("David MacKenzie"), \ ++ proper_name ("Jim Meyering") ++ ++/* Used by do_copy, make_dir_parents_private, and re_protect ++ to keep a list of leading directories whose protections ++ need to be fixed after copying. */ ++struct dir_attr ++{ ++ struct stat st; ++ bool restore_mode; ++ size_t slash_offset; ++ struct dir_attr *next; ++}; ++ ++/* For long options that have no equivalent short option, use a ++ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ ++enum ++{ ++ COPY_CONTENTS_OPTION = CHAR_MAX + 1, ++ NO_PRESERVE_ATTRIBUTES_OPTION, ++ PARENTS_OPTION, ++ PRESERVE_ATTRIBUTES_OPTION, ++ REFLINK_OPTION, ++ SPARSE_OPTION, ++ STRIP_TRAILING_SLASHES_OPTION, ++ UNLINK_DEST_BEFORE_OPENING ++}; ++ ++/* True if the kernel is SELinux enabled. */ ++static bool selinux_enabled; ++ ++/* If true, the command "cp x/e_file e_dir" uses "e_dir/x/e_file" ++ as its destination instead of the usual "e_dir/e_file." */ ++static bool parents_option = false; ++ ++/* Remove any trailing slashes from each SOURCE argument. */ ++static bool remove_trailing_slashes; ++ ++static char const *const sparse_type_string[] = ++{ ++ "never", "auto", "always", NULL ++}; ++static enum Sparse_type const sparse_type[] = ++{ ++ SPARSE_NEVER, SPARSE_AUTO, SPARSE_ALWAYS ++}; ++ARGMATCH_VERIFY (sparse_type_string, sparse_type); ++ ++static char const *const reflink_type_string[] = ++{ ++ "auto", "always", NULL ++}; ++static enum Reflink_type const reflink_type[] = ++{ ++ REFLINK_AUTO, REFLINK_ALWAYS ++}; ++ARGMATCH_VERIFY (reflink_type_string, reflink_type); ++ ++static struct option const long_opts[] = ++{ ++ {"archive", no_argument, NULL, 'a'}, ++ {"backup", optional_argument, NULL, 'b'}, ++ {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION}, ++ {"dereference", no_argument, NULL, 'L'}, ++ {"force", no_argument, NULL, 'f'}, ++ {"interactive", no_argument, NULL, 'i'}, ++ {"link", no_argument, NULL, 'l'}, ++ {"no-clobber", no_argument, NULL, 'n'}, ++ {"no-dereference", no_argument, NULL, 'P'}, ++ {"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION}, ++ {"no-target-directory", no_argument, NULL, 'T'}, ++ {"one-file-system", no_argument, NULL, 'x'}, ++ {"parents", no_argument, NULL, PARENTS_OPTION}, ++ {"path", no_argument, NULL, PARENTS_OPTION}, /* Deprecated. */ ++ {"preserve", optional_argument, NULL, PRESERVE_ATTRIBUTES_OPTION}, ++ {"recursive", no_argument, NULL, 'R'}, ++ {"remove-destination", no_argument, NULL, UNLINK_DEST_BEFORE_OPENING}, ++ {"sparse", required_argument, NULL, SPARSE_OPTION}, ++ {"reflink", optional_argument, NULL, REFLINK_OPTION}, ++ {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION}, ++ {"suffix", required_argument, NULL, 'S'}, ++ {"symbolic-link", no_argument, NULL, 's'}, ++ {"target-directory", required_argument, NULL, 't'}, ++ {"update", no_argument, NULL, 'u'}, ++ {"verbose", no_argument, NULL, 'v'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... [-T] SOURCE DEST\n\ ++ or: %s [OPTION]... SOURCE... DIRECTORY\n\ ++ or: %s [OPTION]... -t DIRECTORY SOURCE...\n\ ++"), ++ program_name, program_name, program_name); ++ fputs (_("\ ++Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ -a, --archive same as -dR --preserve=all\n\ ++ --backup[=CONTROL] make a backup of each existing destination file\n\ ++ -b like --backup but does not accept an argument\n\ ++ --copy-contents copy contents of special files when recursive\n\ ++ -d same as --no-dereference --preserve=links\n\ ++"), stdout); ++ fputs (_("\ ++ -f, --force if an existing destination file cannot be\n\ ++ opened, remove it and try again (redundant if\n\ ++ the -n option is used)\n\ ++ -i, --interactive prompt before overwrite (overrides a previous -n\n\ ++ option)\n\ ++ -H follow command-line symbolic links in SOURCE\n\ ++"), stdout); ++ fputs (_("\ ++ -l, --link link files instead of copying\n\ ++ -L, --dereference always follow symbolic links in SOURCE\n\ ++"), stdout); ++ fputs (_("\ ++ -n, --no-clobber do not overwrite an existing file (overrides\n\ ++ a previous -i option)\n\ ++ -P, --no-dereference never follow symbolic links in SOURCE\n\ ++"), stdout); ++ fputs (_("\ ++ -p same as --preserve=mode,ownership,timestamps\n\ ++ --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\ ++ mode,ownership,timestamps), if possible\n\ ++ additional attributes: context, links, xattr,\n\ ++ all\n\ ++"), stdout); ++ fputs (_("\ ++ --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ ++ --parents use full source file name under DIRECTORY\n\ ++"), stdout); ++ fputs (_("\ ++ -R, -r, --recursive copy directories recursively\n\ ++ --reflink[=WHEN] control clone/CoW copies. See below.\n\ ++ --remove-destination remove each existing destination file before\n\ ++ attempting to open it (contrast with --force)\n\ ++"), stdout); ++ fputs (_("\ ++ --sparse=WHEN control creation of sparse files. See below.\n\ ++ --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\ ++ argument\n\ ++"), stdout); ++ fputs (_("\ ++ -s, --symbolic-link make symbolic links instead of copying\n\ ++ -S, --suffix=SUFFIX override the usual backup suffix\n\ ++ -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\ ++ -T, --no-target-directory treat DEST as a normal file\n\ ++"), stdout); ++ fputs (_("\ ++ -u, --update copy only when the SOURCE file is newer\n\ ++ than the destination file or when the\n\ ++ destination file is missing\n\ ++ -v, --verbose explain what is being done\n\ ++ -x, --one-file-system stay on this file system\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++By default, sparse SOURCE files are detected by a crude heuristic and the\n\ ++corresponding DEST file is made sparse as well. That is the behavior\n\ ++selected by --sparse=auto. Specify --sparse=always to create a sparse DEST\n\ ++file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\ ++Use --sparse=never to inhibit creation of sparse files.\n\ ++\n\ ++When --reflink[=always] is specified, perform a lightweight copy, where the\n\ ++data blocks are copied only when modified. If this is not possible the copy\n\ ++fails, or if --reflink=auto is specified, fall back to a standard copy.\n\ ++"), stdout); ++ fputs (_("\ ++\n\ ++The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\ ++The version control method may be selected via the --backup option or through\n\ ++the VERSION_CONTROL environment variable. Here are the values:\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++ none, off never make backups (even if --backup is given)\n\ ++ numbered, t make numbered backups\n\ ++ existing, nil numbered if numbered backups exist, simple otherwise\n\ ++ simple, never always make simple backups\n\ ++"), stdout); ++ fputs (_("\ ++\n\ ++As a special case, cp makes a backup of SOURCE when the force and backup\n\ ++options are given and SOURCE and DEST are the same name for an existing,\n\ ++regular file.\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++/* Ensure that the parent directories of CONST_DST_NAME have the ++ correct protections, for the --parents option. This is done ++ after all copying has been completed, to allow permissions ++ that don't include user write/execute. ++ ++ SRC_OFFSET is the index in CONST_DST_NAME of the beginning of the ++ source directory name. ++ ++ ATTR_LIST is a null-terminated linked list of structures that ++ indicates the end of the filename of each intermediate directory ++ in CONST_DST_NAME that may need to have its attributes changed. ++ The command `cp --parents --preserve a/b/c d/e_dir' changes the ++ attributes of the directories d/e_dir/a and d/e_dir/a/b to match ++ the corresponding source directories regardless of whether they ++ existed before the `cp' command was given. ++ ++ Return true if the parent of CONST_DST_NAME and any intermediate ++ directories specified by ATTR_LIST have the proper permissions ++ when done. */ ++ ++static bool ++re_protect (char const *const_dst_name, size_t src_offset, ++ struct dir_attr *attr_list, const struct cp_options *x) ++{ ++ struct dir_attr *p; ++ char *dst_name; /* A copy of CONST_DST_NAME we can change. */ ++ char *src_name; /* The source name in `dst_name'. */ ++ ++ ASSIGN_STRDUPA (dst_name, const_dst_name); ++ src_name = dst_name + src_offset; ++ ++ for (p = attr_list; p; p = p->next) ++ { ++ dst_name[p->slash_offset] = '\0'; ++ ++ /* Adjust the times (and if possible, ownership) for the copy. ++ chown turns off set[ug]id bits for non-root, ++ so do the chmod last. */ ++ ++ if (x->preserve_timestamps) ++ { ++ struct timespec timespec[2]; ++ ++ timespec[0] = get_stat_atime (&p->st); ++ timespec[1] = get_stat_mtime (&p->st); ++ ++ if (utimens (dst_name, timespec)) ++ { ++ error (0, errno, _("failed to preserve times for %s"), ++ quote (dst_name)); ++ return false; ++ } ++ } ++ ++ if (x->preserve_ownership) ++ { ++ if (lchown (dst_name, p->st.st_uid, p->st.st_gid) != 0) ++ { ++ if (! chown_failure_ok (x)) ++ { ++ error (0, errno, _("failed to preserve ownership for %s"), ++ quote (dst_name)); ++ return false; ++ } ++ /* Failing to preserve ownership is OK. Still, try to preserve ++ the group, but ignore the possible error. */ ++ ignore_value (lchown (dst_name, -1, p->st.st_gid)); ++ } ++ } ++ ++ if (x->preserve_mode) ++ { ++ if (copy_acl (src_name, -1, dst_name, -1, p->st.st_mode) != 0) ++ return false; ++ } ++ else if (p->restore_mode) ++ { ++ if (lchmod (dst_name, p->st.st_mode) != 0) ++ { ++ error (0, errno, _("failed to preserve permissions for %s"), ++ quote (dst_name)); ++ return false; ++ } ++ } ++ ++ dst_name[p->slash_offset] = '/'; ++ } ++ return true; ++} ++ ++/* Ensure that the parent directory of CONST_DIR exists, for ++ the --parents option. ++ ++ SRC_OFFSET is the index in CONST_DIR (which is a destination ++ directory) of the beginning of the source directory name. ++ Create any leading directories that don't already exist. ++ If VERBOSE_FMT_STRING is nonzero, use it as a printf format ++ string for printing a message after successfully making a directory. ++ The format should take two string arguments: the names of the ++ source and destination directories. ++ Creates a linked list of attributes of intermediate directories, ++ *ATTR_LIST, for re_protect to use after calling copy. ++ Sets *NEW_DST if this function creates parent of CONST_DIR. ++ ++ Return true if parent of CONST_DIR exists as a directory with the proper ++ permissions when done. */ ++ ++/* FIXME: Synch this function with the one in ../lib/mkdir-p.c. */ ++ ++static bool ++make_dir_parents_private (char const *const_dir, size_t src_offset, ++ char const *verbose_fmt_string, ++ struct dir_attr **attr_list, bool *new_dst, ++ const struct cp_options *x) ++{ ++ struct stat stats; ++ char *dir; /* A copy of CONST_DIR we can change. */ ++ char *src; /* Source name in DIR. */ ++ char *dst_dir; /* Leading directory of DIR. */ ++ size_t dirlen; /* Length of DIR. */ ++ ++ ASSIGN_STRDUPA (dir, const_dir); ++ ++ src = dir + src_offset; ++ ++ dirlen = dir_len (dir); ++ dst_dir = alloca (dirlen + 1); ++ memcpy (dst_dir, dir, dirlen); ++ dst_dir[dirlen] = '\0'; ++ ++ *attr_list = NULL; ++ ++ if (stat (dst_dir, &stats) != 0) ++ { ++ /* A parent of CONST_DIR does not exist. ++ Make all missing intermediate directories. */ ++ char *slash; ++ ++ slash = src; ++ while (*slash == '/') ++ slash++; ++ while ((slash = strchr (slash, '/'))) ++ { ++ struct dir_attr *new IF_LINT (= NULL); ++ bool missing_dir; ++ ++ *slash = '\0'; ++ missing_dir = (stat (dir, &stats) != 0); ++ ++ if (missing_dir | x->preserve_ownership | x->preserve_mode ++ | x->preserve_timestamps) ++ { ++ /* Add this directory to the list of directories whose ++ modes might need fixing later. */ ++ struct stat src_st; ++ int src_errno = (stat (src, &src_st) != 0 ++ ? errno ++ : S_ISDIR (src_st.st_mode) ++ ? 0 ++ : ENOTDIR); ++ if (src_errno) ++ { ++ error (0, src_errno, _("failed to get attributes of %s"), ++ quote (src)); ++ return false; ++ } ++ ++ new = xmalloc (sizeof *new); ++ new->st = src_st; ++ new->slash_offset = slash - dir; ++ new->restore_mode = false; ++ new->next = *attr_list; ++ *attr_list = new; ++ } ++ ++ if (missing_dir) ++ { ++ mode_t src_mode; ++ mode_t omitted_permissions; ++ mode_t mkdir_mode; ++ ++ /* This component does not exist. We must set ++ *new_dst and new->st.st_mode inside this loop because, ++ for example, in the command `cp --parents ../a/../b/c e_dir', ++ make_dir_parents_private creates only e_dir/../a if ++ ./b already exists. */ ++ *new_dst = true; ++ src_mode = new->st.st_mode; ++ ++ /* If the ownership or special mode bits might change, ++ omit some permissions at first, so unauthorized users ++ cannot nip in before the file is ready. */ ++ omitted_permissions = (src_mode ++ & (x->preserve_ownership ++ ? S_IRWXG | S_IRWXO ++ : x->preserve_mode ++ ? S_IWGRP | S_IWOTH ++ : 0)); ++ ++ /* POSIX says mkdir's behavior is implementation-defined when ++ (src_mode & ~S_IRWXUGO) != 0. However, common practice is ++ to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir ++ decide what to do with S_ISUID | S_ISGID | S_ISVTX. */ ++ mkdir_mode = src_mode & CHMOD_MODE_BITS & ~omitted_permissions; ++ if (mkdir (dir, mkdir_mode) != 0) ++ { ++ error (0, errno, _("cannot make directory %s"), ++ quote (dir)); ++ return false; ++ } ++ else ++ { ++ if (verbose_fmt_string != NULL) ++ printf (verbose_fmt_string, src, dir); ++ } ++ ++ /* We need search and write permissions to the new directory ++ for writing the directory's contents. Check if these ++ permissions are there. */ ++ ++ if (lstat (dir, &stats)) ++ { ++ error (0, errno, _("failed to get attributes of %s"), ++ quote (dir)); ++ return false; ++ } ++ ++ ++ if (! x->preserve_mode) ++ { ++ if (omitted_permissions & ~stats.st_mode) ++ omitted_permissions &= ~ cached_umask (); ++ if (omitted_permissions & ~stats.st_mode ++ || (stats.st_mode & S_IRWXU) != S_IRWXU) ++ { ++ new->st.st_mode = stats.st_mode | omitted_permissions; ++ new->restore_mode = true; ++ } ++ } ++ ++ if ((stats.st_mode & S_IRWXU) != S_IRWXU) ++ { ++ /* Make the new directory searchable and writable. ++ The original permissions will be restored later. */ ++ ++ if (lchmod (dir, stats.st_mode | S_IRWXU) != 0) ++ { ++ error (0, errno, _("setting permissions for %s"), ++ quote (dir)); ++ return false; ++ } ++ } ++ } ++ else if (!S_ISDIR (stats.st_mode)) ++ { ++ error (0, 0, _("%s exists but is not a directory"), ++ quote (dir)); ++ return false; ++ } ++ else ++ *new_dst = false; ++ *slash++ = '/'; ++ ++ /* Avoid unnecessary calls to `stat' when given ++ file names containing multiple adjacent slashes. */ ++ while (*slash == '/') ++ slash++; ++ } ++ } ++ ++ /* We get here if the parent of DIR already exists. */ ++ ++ else if (!S_ISDIR (stats.st_mode)) ++ { ++ error (0, 0, _("%s exists but is not a directory"), quote (dst_dir)); ++ return false; ++ } ++ else ++ { ++ *new_dst = false; ++ } ++ return true; ++} ++ ++/* FILE is the last operand of this command. ++ Return true if FILE is a directory. ++ But report an error and exit if there is a problem accessing FILE, ++ or if FILE does not exist but would have to refer to an existing ++ directory if it referred to anything at all. ++ ++ If the file exists, store the file's status into *ST. ++ Otherwise, set *NEW_DST. */ ++ ++static bool ++target_directory_operand (char const *file, struct stat *st, bool *new_dst) ++{ ++ int err = (stat (file, st) == 0 ? 0 : errno); ++ bool is_a_dir = !err && S_ISDIR (st->st_mode); ++ if (err) ++ { ++ if (err != ENOENT) ++ error (EXIT_FAILURE, err, _("accessing %s"), quote (file)); ++ *new_dst = true; ++ } ++ return is_a_dir; ++} ++ ++/* Scan the arguments, and copy each by calling copy. ++ Return true if successful. */ ++ ++static bool ++do_copy (int n_files, char **file, const char *target_directory, ++ bool no_target_directory, struct cp_options *x) ++{ ++ struct stat sb; ++ bool new_dst = false; ++ bool ok = true; ++ ++ if (n_files <= !target_directory) ++ { ++ if (n_files <= 0) ++ error (0, 0, _("missing file operand")); ++ else ++ error (0, 0, _("missing destination file operand after %s"), ++ quote (file[0])); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (no_target_directory) ++ { ++ if (target_directory) ++ error (EXIT_FAILURE, 0, ++ _("cannot combine --target-directory (-t) " ++ "and --no-target-directory (-T)")); ++ if (2 < n_files) ++ { ++ error (0, 0, _("extra operand %s"), quote (file[2])); ++ usage (EXIT_FAILURE); ++ } ++ } ++ else if (!target_directory) ++ { ++ if (2 <= n_files ++ && target_directory_operand (file[n_files - 1], &sb, &new_dst)) ++ target_directory = file[--n_files]; ++ else if (2 < n_files) ++ error (EXIT_FAILURE, 0, _("target %s is not a directory"), ++ quote (file[n_files - 1])); ++ } ++ ++ if (target_directory) ++ { ++ /* cp file1...filen edir ++ Copy the files `file1' through `filen' ++ to the existing directory `edir'. */ ++ int i; ++ ++ /* Initialize these hash tables only if we'll need them. ++ The problems they're used to detect can arise only if ++ there are two or more files to copy. */ ++ if (2 <= n_files) ++ { ++ dest_info_init (x); ++ src_info_init (x); ++ } ++ ++ for (i = 0; i < n_files; i++) ++ { ++ char *dst_name; ++ bool parent_exists = true; /* True if dir_name (dst_name) exists. */ ++ struct dir_attr *attr_list; ++ char *arg_in_concat = NULL; ++ char *arg = file[i]; ++ ++ /* Trailing slashes are meaningful (i.e., maybe worth preserving) ++ only in the source file names. */ ++ if (remove_trailing_slashes) ++ strip_trailing_slashes (arg); ++ ++ if (parents_option) ++ { ++ char *arg_no_trailing_slash; ++ ++ /* Use `arg' without trailing slashes in constructing destination ++ file names. Otherwise, we can end up trying to create a ++ directory via `mkdir ("dst/foo/"...', which is not portable. ++ It fails, due to the trailing slash, on at least ++ NetBSD 1.[34] systems. */ ++ ASSIGN_STRDUPA (arg_no_trailing_slash, arg); ++ strip_trailing_slashes (arg_no_trailing_slash); ++ ++ /* Append all of `arg' (minus any trailing slash) to `dest'. */ ++ dst_name = file_name_concat (target_directory, ++ arg_no_trailing_slash, ++ &arg_in_concat); ++ ++ /* For --parents, we have to make sure that the directory ++ dir_name (dst_name) exists. We may have to create a few ++ leading directories. */ ++ parent_exists = ++ (make_dir_parents_private ++ (dst_name, arg_in_concat - dst_name, ++ (x->verbose ? "%s -> %s\n" : NULL), ++ &attr_list, &new_dst, x)); ++ } ++ else ++ { ++ char *arg_base; ++ /* Append the last component of `arg' to `target_directory'. */ ++ ++ ASSIGN_BASENAME_STRDUPA (arg_base, arg); ++ /* For `cp -R source/.. dest', don't copy into `dest/..'. */ ++ dst_name = (STREQ (arg_base, "..") ++ ? xstrdup (target_directory) ++ : file_name_concat (target_directory, arg_base, ++ NULL)); ++ } ++ ++ if (!parent_exists) ++ { ++ /* make_dir_parents_private failed, so don't even ++ attempt the copy. */ ++ ok = false; ++ } ++ else ++ { ++ bool copy_into_self; ++ ok &= copy (arg, dst_name, new_dst, x, ©_into_self, NULL); ++ ++ if (parents_option) ++ ok &= re_protect (dst_name, arg_in_concat - dst_name, ++ attr_list, x); ++ } ++ ++ if (parents_option) ++ { ++ while (attr_list) ++ { ++ struct dir_attr *p = attr_list; ++ attr_list = attr_list->next; ++ free (p); ++ } ++ } ++ ++ free (dst_name); ++ } ++ } ++ else /* !target_directory */ ++ { ++ char const *new_dest; ++ char const *source = file[0]; ++ char const *dest = file[1]; ++ bool unused; ++ ++ if (parents_option) ++ { ++ error (0, 0, ++ _("with --parents, the destination must be a directory")); ++ usage (EXIT_FAILURE); ++ } ++ ++ /* When the force and backup options have been specified and ++ the source and destination are the same name for an existing ++ regular file, convert the user's command, e.g., ++ `cp --force --backup foo foo' to `cp --force foo fooSUFFIX' ++ where SUFFIX is determined by any version control options used. */ ++ ++ if (x->unlink_dest_after_failed_open ++ && x->backup_type != no_backups ++ && STREQ (source, dest) ++ && !new_dst && S_ISREG (sb.st_mode)) ++ { ++ static struct cp_options x_tmp; ++ ++ new_dest = find_backup_file_name (dest, x->backup_type); ++ /* Set x->backup_type to `no_backups' so that the normal backup ++ mechanism is not used when performing the actual copy. ++ backup_type must be set to `no_backups' only *after* the above ++ call to find_backup_file_name -- that function uses ++ backup_type to determine the suffix it applies. */ ++ x_tmp = *x; ++ x_tmp.backup_type = no_backups; ++ x = &x_tmp; ++ } ++ else ++ { ++ new_dest = dest; ++ } ++ ++ ok = copy (source, new_dest, 0, x, &unused, NULL); ++ } ++ ++ return ok; ++} ++ ++static void ++cp_option_init (struct cp_options *x) ++{ ++ cp_options_default (x); ++ x->copy_as_regular = true; ++ x->dereference = DEREF_UNDEFINED; ++ x->unlink_dest_before_opening = false; ++ x->unlink_dest_after_failed_open = false; ++ x->hard_link = false; ++ x->interactive = I_UNSPECIFIED; ++ x->move_mode = false; ++ x->one_file_system = false; ++ x->reflink_mode = REFLINK_NEVER; ++ ++ x->preserve_ownership = false; ++ x->preserve_links = false; ++ x->preserve_mode = false; ++ x->preserve_timestamps = false; ++ x->preserve_security_context = false; ++ x->require_preserve_context = false; ++ x->preserve_xattr = false; ++ x->reduce_diagnostics = false; ++ x->require_preserve_xattr = false; ++ ++ x->require_preserve = false; ++ x->recursive = false; ++ x->sparse_mode = SPARSE_AUTO; ++ x->symbolic_link = false; ++ x->set_mode = false; ++ x->mode = 0; ++ ++ /* Not used. */ ++ x->stdin_tty = false; ++ ++ x->update = false; ++ x->verbose = false; ++ ++ /* By default, refuse to open a dangling destination symlink, because ++ in general one cannot do that safely, give the current semantics of ++ open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw). ++ But POSIX requires it. */ ++ x->open_dangling_dest_symlink = getenv ("POSIXLY_CORRECT") != NULL; ++ ++ x->dest_info = NULL; ++ x->src_info = NULL; ++} ++ ++/* Given a string, ARG, containing a comma-separated list of arguments ++ to the --preserve option, set the appropriate fields of X to ON_OFF. */ ++static void ++decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off) ++{ ++ enum File_attribute ++ { ++ PRESERVE_MODE, ++ PRESERVE_TIMESTAMPS, ++ PRESERVE_OWNERSHIP, ++ PRESERVE_LINK, ++ PRESERVE_CONTEXT, ++ PRESERVE_XATTR, ++ PRESERVE_ALL ++ }; ++ static enum File_attribute const preserve_vals[] = ++ { ++ PRESERVE_MODE, PRESERVE_TIMESTAMPS, ++ PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_XATTR, ++ PRESERVE_ALL ++ }; ++ /* Valid arguments to the `--preserve' option. */ ++ static char const* const preserve_args[] = ++ { ++ "mode", "timestamps", ++ "ownership", "links", "context", "xattr", "all", NULL ++ }; ++ ARGMATCH_VERIFY (preserve_args, preserve_vals); ++ ++ char *arg_writable = xstrdup (arg); ++ char *s = arg_writable; ++ do ++ { ++ /* find next comma */ ++ char *comma = strchr (s, ','); ++ enum File_attribute val; ++ ++ /* If we found a comma, put a NUL in its place and advance. */ ++ if (comma) ++ *comma++ = 0; ++ ++ /* process S. */ ++ val = XARGMATCH ("--preserve", s, preserve_args, preserve_vals); ++ switch (val) ++ { ++ case PRESERVE_MODE: ++ x->preserve_mode = on_off; ++ break; ++ ++ case PRESERVE_TIMESTAMPS: ++ x->preserve_timestamps = on_off; ++ break; ++ ++ case PRESERVE_OWNERSHIP: ++ x->preserve_ownership = on_off; ++ break; ++ ++ case PRESERVE_LINK: ++ x->preserve_links = on_off; ++ break; ++ ++ case PRESERVE_CONTEXT: ++ x->preserve_security_context = on_off; ++ x->require_preserve_context = on_off; ++ break; ++ ++ case PRESERVE_XATTR: ++ x->preserve_xattr = on_off; ++ x->require_preserve_xattr = on_off; ++ break; ++ ++ case PRESERVE_ALL: ++ x->preserve_mode = on_off; ++ x->preserve_timestamps = on_off; ++ x->preserve_ownership = on_off; ++ x->preserve_links = on_off; ++ if (selinux_enabled) ++ x->preserve_security_context = on_off; ++ x->preserve_xattr = on_off; ++ break; ++ ++ default: ++ abort (); ++ } ++ s = comma; ++ } ++ while (s); ++ ++ free (arg_writable); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int c; ++ bool ok; ++ bool make_backups = false; ++ char *backup_suffix_string; ++ char *version_control_string = NULL; ++ struct cp_options x; ++ bool copy_contents = false; ++ char *target_directory = NULL; ++ bool no_target_directory = false; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ atexit (close_stdin); ++ ++ selinux_enabled = (0 < is_selinux_enabled ()); ++ cp_option_init (&x); ++ ++ /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless ++ we'll actually use backup_suffix_string. */ ++ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); ++ ++ while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T", ++ long_opts, NULL)) ++ != -1) ++ { ++ switch (c) ++ { ++ case SPARSE_OPTION: ++ x.sparse_mode = XARGMATCH ("--sparse", optarg, ++ sparse_type_string, sparse_type); ++ break; ++ ++ case REFLINK_OPTION: ++ if (optarg == NULL) ++ x.reflink_mode = REFLINK_ALWAYS; ++ else ++ x.reflink_mode = XARGMATCH ("--reflink", optarg, ++ reflink_type_string, reflink_type); ++ break; ++ ++ case 'a': /* Like -dR --preserve=all with reduced failure diagnostics. */ ++ x.dereference = DEREF_NEVER; ++ x.preserve_links = true; ++ x.preserve_ownership = true; ++ x.preserve_mode = true; ++ x.preserve_timestamps = true; ++ x.require_preserve = true; ++ if (selinux_enabled) ++ x.preserve_security_context = true; ++ x.preserve_xattr = true; ++ x.reduce_diagnostics = true; ++ x.recursive = true; ++ break; ++ ++ case 'b': ++ make_backups = true; ++ if (optarg) ++ version_control_string = optarg; ++ break; ++ ++ case COPY_CONTENTS_OPTION: ++ copy_contents = true; ++ break; ++ ++ case 'd': ++ x.preserve_links = true; ++ x.dereference = DEREF_NEVER; ++ break; ++ ++ case 'f': ++ x.unlink_dest_after_failed_open = true; ++ break; ++ ++ case 'H': ++ x.dereference = DEREF_COMMAND_LINE_ARGUMENTS; ++ break; ++ ++ case 'i': ++ x.interactive = I_ASK_USER; ++ break; ++ ++ case 'l': ++ x.hard_link = true; ++ break; ++ ++ case 'L': ++ x.dereference = DEREF_ALWAYS; ++ break; ++ ++ case 'n': ++ x.interactive = I_ALWAYS_NO; ++ break; ++ ++ case 'P': ++ x.dereference = DEREF_NEVER; ++ break; ++ ++ case NO_PRESERVE_ATTRIBUTES_OPTION: ++ decode_preserve_arg (optarg, &x, false); ++ break; ++ ++ case PRESERVE_ATTRIBUTES_OPTION: ++ if (optarg == NULL) ++ { ++ /* Fall through to the case for `p' below. */ ++ } ++ else ++ { ++ decode_preserve_arg (optarg, &x, true); ++ x.require_preserve = true; ++ break; ++ } ++ ++ case 'p': ++ x.preserve_ownership = true; ++ x.preserve_mode = true; ++ x.preserve_timestamps = true; ++ x.require_preserve = true; ++ break; ++ ++ case PARENTS_OPTION: ++ parents_option = true; ++ break; ++ ++ case 'r': ++ case 'R': ++ x.recursive = true; ++ break; ++ ++ case UNLINK_DEST_BEFORE_OPENING: ++ x.unlink_dest_before_opening = true; ++ break; ++ ++ case STRIP_TRAILING_SLASHES_OPTION: ++ remove_trailing_slashes = true; ++ break; ++ ++ case 's': ++ x.symbolic_link = true; ++ break; ++ ++ case 't': ++ if (target_directory) ++ error (EXIT_FAILURE, 0, ++ _("multiple target directories specified")); ++ else ++ { ++ struct stat st; ++ if (stat (optarg, &st) != 0) ++ error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg)); ++ if (! S_ISDIR (st.st_mode)) ++ error (EXIT_FAILURE, 0, _("target %s is not a directory"), ++ quote (optarg)); ++ } ++ target_directory = optarg; ++ break; ++ ++ case 'T': ++ no_target_directory = true; ++ break; ++ ++ case 'u': ++ x.update = true; ++ break; ++ ++ case 'v': ++ x.verbose = true; ++ break; ++ ++ case 'x': ++ x.one_file_system = true; ++ break; ++ ++ case 'S': ++ make_backups = true; ++ backup_suffix_string = optarg; ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (EXIT_FAILURE); ++ } ++ } ++ ++ if (x.hard_link && x.symbolic_link) ++ { ++ error (0, 0, _("cannot make both hard and symbolic links")); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (make_backups && x.interactive == I_ALWAYS_NO) ++ { ++ error (0, 0, ++ _("options --backup and --no-clobber are mutually exclusive")); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (x.reflink_mode == REFLINK_ALWAYS && x.sparse_mode != SPARSE_AUTO) ++ { ++ error (0, 0, _("--reflink can be used only with --sparse=auto")); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (backup_suffix_string) ++ simple_backup_suffix = xstrdup (backup_suffix_string); ++ ++ x.backup_type = (make_backups ++ ? xget_version (_("backup type"), ++ version_control_string) ++ : no_backups); ++ ++ if (x.dereference == DEREF_UNDEFINED) ++ { ++ if (x.recursive) ++ /* This is compatible with FreeBSD. */ ++ x.dereference = DEREF_NEVER; ++ else ++ x.dereference = DEREF_ALWAYS; ++ } ++ ++ if (x.recursive) ++ x.copy_as_regular = copy_contents; ++ ++ /* If --force (-f) was specified and we're in link-creation mode, ++ first remove any existing destination file. */ ++ if (x.unlink_dest_after_failed_open && (x.hard_link || x.symbolic_link)) ++ x.unlink_dest_before_opening = true; ++ ++ if (x.preserve_security_context) ++ { ++ if (!selinux_enabled) ++ error (EXIT_FAILURE, 0, ++ _("cannot preserve security context " ++ "without an SELinux-enabled kernel")); ++ } ++ ++#if !USE_XATTR ++ if (x.require_preserve_xattr) ++ error (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is " ++ "built without xattr support")); ++#endif ++ ++ /* Allocate space for remembering copied and created files. */ ++ ++ hash_init (); ++ ++ ok = do_copy (argc - optind, argv + optind, ++ target_directory, no_target_directory, &x); ++ ++ forget_all (); ++ ++ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); ++} +diff -urNp coreutils-8.0-orig/src/chcon.c coreutils-8.0/src/chcon.c +--- coreutils-8.0-orig/src/chcon.c 2009-10-06 10:55:34.000000000 +0200 ++++ coreutils-8.0/src/chcon.c 2009-10-07 10:10:11.000000000 +0200 +@@ -348,7 +348,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), program_name, program_name, program_name); fputs (_("\ @@ -162,9 +4003,9 @@ diff -urNp coreutils-7.1-orig/src/chcon.c coreutils-7.1/src/chcon.c With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ -h, --no-dereference affect symbolic links instead of any referenced file\n\ -@@ -519,6 +519,10 @@ main (int argc, char **argv) - usage (EXIT_FAILURE); - } +@@ -523,6 +523,10 @@ main (int argc, char **argv) + error (EXIT_FAILURE, 0, + _("%s may be used only on a SELinux kernel"), program_name); + if (is_selinux_enabled () != 1) + error (EXIT_FAILURE, 0, @@ -173,9 +4014,585 @@ diff -urNp coreutils-7.1-orig/src/chcon.c coreutils-7.1/src/chcon.c if (reference_file) { if (getfilecon (reference_file, &ref_context) < 0) -diff -urNp coreutils-7.1-orig/src/id.c coreutils-7.1/src/id.c ---- coreutils-7.1-orig/src/id.c 2009-02-16 15:57:44.000000000 +0100 -+++ coreutils-7.1/src/id.c 2009-02-24 13:47:15.000000000 +0100 +diff -urNp coreutils-8.0-orig/src/chcon.c.orig coreutils-8.0/src/chcon.c.orig +--- coreutils-8.0-orig/src/chcon.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/chcon.c.orig 2009-10-06 10:55:34.000000000 +0200 +@@ -0,0 +1,572 @@ ++/* chcon -- change security context of files ++ Copyright (C) 2005-2009 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 . */ ++ ++#include ++#include ++#include ++#include ++ ++#include "system.h" ++#include "dev-ino.h" ++#include "error.h" ++#include "ignore-value.h" ++#include "quote.h" ++#include "quotearg.h" ++#include "root-dev-ino.h" ++#include "selinux-at.h" ++#include "xfts.h" ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "chcon" ++ ++#define AUTHORS \ ++ proper_name ("Russell Coker"), \ ++ proper_name ("Jim Meyering") ++ ++/* If nonzero, and the systems has support for it, change the context ++ of symbolic links rather than any files they point to. */ ++static bool affect_symlink_referent; ++ ++/* If true, change the modes of directories recursively. */ ++static bool recurse; ++ ++/* Level of verbosity. */ ++static bool verbose; ++ ++/* Pointer to the device and inode numbers of `/', when --recursive. ++ Otherwise NULL. */ ++static struct dev_ino *root_dev_ino; ++ ++/* The name of the context file is being given. */ ++static char const *specified_context; ++ ++/* Specific components of the context */ ++static char const *specified_user; ++static char const *specified_role; ++static char const *specified_range; ++static char const *specified_type; ++ ++/* For long options that have no equivalent short option, use a ++ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ ++enum ++{ ++ DEREFERENCE_OPTION = CHAR_MAX + 1, ++ NO_PRESERVE_ROOT, ++ PRESERVE_ROOT, ++ REFERENCE_FILE_OPTION ++}; ++ ++static struct option const long_options[] = ++{ ++ {"recursive", no_argument, NULL, 'R'}, ++ {"dereference", no_argument, NULL, DEREFERENCE_OPTION}, ++ {"no-dereference", no_argument, NULL, 'h'}, ++ {"no-preserve-root", no_argument, NULL, NO_PRESERVE_ROOT}, ++ {"preserve-root", no_argument, NULL, PRESERVE_ROOT}, ++ {"reference", required_argument, NULL, REFERENCE_FILE_OPTION}, ++ {"user", required_argument, NULL, 'u'}, ++ {"role", required_argument, NULL, 'r'}, ++ {"type", required_argument, NULL, 't'}, ++ {"range", required_argument, NULL, 'l'}, ++ {"verbose", no_argument, NULL, 'v'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++/* Given a security context, CONTEXT, derive a context_t (*RET), ++ setting any portions selected via the global variables, specified_user, ++ specified_role, etc. */ ++static int ++compute_context_from_mask (security_context_t context, context_t *ret) ++{ ++ bool ok = true; ++ context_t new_context = context_new (context); ++ if (!new_context) ++ { ++ error (0, errno, _("failed to create security context: %s"), ++ quotearg_colon (context)); ++ return 1; ++ } ++ ++#define SET_COMPONENT(C, comp) \ ++ do \ ++ { \ ++ if (specified_ ## comp \ ++ && context_ ## comp ## _set ((C), specified_ ## comp)) \ ++ { \ ++ error (0, errno, \ ++ _("failed to set %s security context component to %s"), \ ++ #comp, quote (specified_ ## comp)); \ ++ ok = false; \ ++ } \ ++ } \ ++ while (0) ++ ++ SET_COMPONENT (new_context, user); ++ SET_COMPONENT (new_context, range); ++ SET_COMPONENT (new_context, role); ++ SET_COMPONENT (new_context, type); ++ ++ if (!ok) ++ { ++ int saved_errno = errno; ++ context_free (new_context); ++ errno = saved_errno; ++ return 1; ++ } ++ ++ *ret = new_context; ++ return 0; ++} ++ ++/* Change the context of FILE, using specified components. ++ If it is a directory and -R is given, recurse. ++ Return 0 if successful, 1 if errors occurred. */ ++ ++static int ++change_file_context (int fd, char const *file) ++{ ++ security_context_t file_context = NULL; ++ context_t context; ++ security_context_t context_string; ++ int errors = 0; ++ ++ if (specified_context == NULL) ++ { ++ int status = (affect_symlink_referent ++ ? getfileconat (fd, file, &file_context) ++ : lgetfileconat (fd, file, &file_context)); ++ ++ if (status < 0 && errno != ENODATA) ++ { ++ error (0, errno, _("failed to get security context of %s"), ++ quote (file)); ++ return 1; ++ } ++ ++ /* If the file doesn't have a context, and we're not setting all of ++ the context components, there isn't really an obvious default. ++ Thus, we just give up. */ ++ if (file_context == NULL) ++ { ++ error (0, 0, _("can't apply partial context to unlabeled file %s"), ++ quote (file)); ++ return 1; ++ } ++ ++ if (compute_context_from_mask (file_context, &context)) ++ return 1; ++ } ++ else ++ { ++ /* FIXME: this should be done exactly once, in main. */ ++ context = context_new (specified_context); ++ if (!context) ++ abort (); ++ } ++ ++ context_string = context_str (context); ++ ++ if (file_context == NULL || ! STREQ (context_string, file_context)) ++ { ++ int fail = (affect_symlink_referent ++ ? setfileconat (fd, file, context_string) ++ : lsetfileconat (fd, file, context_string)); ++ ++ if (fail) ++ { ++ errors = 1; ++ error (0, errno, _("failed to change context of %s to %s"), ++ quote_n (0, file), quote_n (1, context_string)); ++ } ++ } ++ ++ context_free (context); ++ freecon (file_context); ++ ++ return errors; ++} ++ ++/* Change the context of FILE. ++ Return true if successful. This function is called ++ once for every file system object that fts encounters. */ ++ ++static bool ++process_file (FTS *fts, FTSENT *ent) ++{ ++ char const *file_full_name = ent->fts_path; ++ char const *file = ent->fts_accpath; ++ const struct stat *file_stats = ent->fts_statp; ++ bool ok = true; ++ ++ switch (ent->fts_info) ++ { ++ case FTS_D: ++ if (recurse) ++ { ++ if (ROOT_DEV_INO_CHECK (root_dev_ino, ent->fts_statp)) ++ { ++ /* This happens e.g., with "chcon -R --preserve-root ... /" ++ and with "chcon -RH --preserve-root ... symlink-to-root". */ ++ ROOT_DEV_INO_WARN (file_full_name); ++ /* Tell fts not to traverse into this hierarchy. */ ++ fts_set (fts, ent, FTS_SKIP); ++ /* Ensure that we do not process "/" on the second visit. */ ++ ignore_ptr (fts_read (fts)); ++ return false; ++ } ++ return true; ++ } ++ break; ++ ++ case FTS_DP: ++ if (! recurse) ++ return true; ++ break; ++ ++ case FTS_NS: ++ /* For a top-level file or directory, this FTS_NS (stat failed) ++ indicator is determined at the time of the initial fts_open call. ++ With programs like chmod, chown, and chgrp, that modify ++ permissions, it is possible that the file in question is ++ accessible when control reaches this point. So, if this is ++ the first time we've seen the FTS_NS for this file, tell ++ fts_read to stat it "again". */ ++ if (ent->fts_level == 0 && ent->fts_number == 0) ++ { ++ ent->fts_number = 1; ++ fts_set (fts, ent, FTS_AGAIN); ++ return true; ++ } ++ error (0, ent->fts_errno, _("cannot access %s"), quote (file_full_name)); ++ ok = false; ++ break; ++ ++ case FTS_ERR: ++ error (0, ent->fts_errno, _("%s"), quote (file_full_name)); ++ ok = false; ++ break; ++ ++ case FTS_DNR: ++ error (0, ent->fts_errno, _("cannot read directory %s"), ++ quote (file_full_name)); ++ ok = false; ++ break; ++ ++ default: ++ break; ++ } ++ ++ if (ent->fts_info == FTS_DP ++ && ok && ROOT_DEV_INO_CHECK (root_dev_ino, file_stats)) ++ { ++ ROOT_DEV_INO_WARN (file_full_name); ++ ok = false; ++ } ++ ++ if (ok) ++ { ++ if (verbose) ++ printf (_("changing security context of %s\n"), ++ quote (file_full_name)); ++ ++ if (change_file_context (fts->fts_cwd_fd, file) != 0) ++ ok = false; ++ } ++ ++ if ( ! recurse) ++ fts_set (fts, ent, FTS_SKIP); ++ ++ return ok; ++} ++ ++/* Recursively operate on the specified FILES (the last entry ++ of which is NULL). BIT_FLAGS controls how fts works. ++ Return true if successful. */ ++ ++static bool ++process_files (char **files, int bit_flags) ++{ ++ bool ok = true; ++ ++ FTS *fts = xfts_open (files, bit_flags, NULL); ++ ++ while (1) ++ { ++ FTSENT *ent; ++ ++ ent = fts_read (fts); ++ if (ent == NULL) ++ { ++ if (errno != 0) ++ { ++ /* FIXME: try to give a better message */ ++ error (0, errno, _("fts_read failed")); ++ ok = false; ++ } ++ break; ++ } ++ ++ ok &= process_file (fts, ent); ++ } ++ ++ if (fts_close (fts) != 0) ++ { ++ error (0, errno, _("fts_close failed")); ++ ok = false; ++ } ++ ++ return ok; ++} ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... CONTEXT FILE...\n\ ++ or: %s [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...\n\ ++ or: %s [OPTION]... --reference=RFILE FILE...\n\ ++"), ++ program_name, program_name, program_name); ++ fputs (_("\ ++Change the security context of each FILE to CONTEXT.\n\ ++With --reference, change the security context of each FILE to that of RFILE.\n\ ++\n\ ++ -h, --no-dereference affect symbolic links instead of any referenced file\n\ ++"), stdout); ++ fputs (_("\ ++ --reference=RFILE use RFILE's security context rather than specifying\n\ ++ a CONTEXT value\n\ ++ -R, --recursive operate on files and directories recursively\n\ ++ -v, --verbose output a diagnostic for every file processed\n\ ++"), stdout); ++ fputs (_("\ ++ -u, --user=USER set user USER in the target security context\n\ ++ -r, --role=ROLE set role ROLE in the target security context\n\ ++ -t, --type=TYPE set type TYPE in the target security context\n\ ++ -l, --range=RANGE set range RANGE in the target security context\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++The following options modify how a hierarchy is traversed when the -R\n\ ++option is also specified. If more than one is specified, only the final\n\ ++one takes effect.\n\ ++\n\ ++ -H if a command line argument is a symbolic link\n\ ++ to a directory, traverse it\n\ ++ -L traverse every symbolic link to a directory\n\ ++ encountered\n\ ++ -P do not traverse any symbolic links (default)\n\ ++\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ security_context_t ref_context = NULL; ++ ++ /* Bit flags that control how fts works. */ ++ int bit_flags = FTS_PHYSICAL; ++ ++ /* 1 if --dereference, 0 if --no-dereference, -1 if neither has been ++ specified. */ ++ int dereference = -1; ++ ++ bool ok; ++ bool preserve_root = false; ++ bool component_specified = false; ++ char *reference_file = NULL; ++ int optc; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ atexit (close_stdout); ++ ++ while ((optc = getopt_long (argc, argv, "HLPRhvu:r:t:l:", long_options, NULL)) ++ != -1) ++ { ++ switch (optc) ++ { ++ case 'H': /* Traverse command-line symlinks-to-directories. */ ++ bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL; ++ break; ++ ++ case 'L': /* Traverse all symlinks-to-directories. */ ++ bit_flags = FTS_LOGICAL; ++ break; ++ ++ case 'P': /* Traverse no symlinks-to-directories. */ ++ bit_flags = FTS_PHYSICAL; ++ break; ++ ++ case 'h': /* --no-dereference: affect symlinks */ ++ dereference = 0; ++ break; ++ ++ case DEREFERENCE_OPTION: /* --dereference: affect the referent ++ of each symlink */ ++ dereference = 1; ++ break; ++ ++ case NO_PRESERVE_ROOT: ++ preserve_root = false; ++ break; ++ ++ case PRESERVE_ROOT: ++ preserve_root = true; ++ break; ++ ++ case REFERENCE_FILE_OPTION: ++ reference_file = optarg; ++ break; ++ ++ case 'R': ++ recurse = true; ++ break; ++ ++ case 'f': ++ /* ignore */ ++ break; ++ ++ case 'v': ++ verbose = true; ++ break; ++ ++ case 'u': ++ specified_user = optarg; ++ component_specified = true; ++ break; ++ ++ case 'r': ++ specified_role = optarg; ++ component_specified = true; ++ break; ++ ++ case 't': ++ specified_type = optarg; ++ component_specified = true; ++ break; ++ ++ case 'l': ++ specified_range = optarg; ++ component_specified = true; ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ default: ++ usage (EXIT_FAILURE); ++ } ++ } ++ ++ if (recurse) ++ { ++ if (bit_flags == FTS_PHYSICAL) ++ { ++ if (dereference == 1) ++ error (EXIT_FAILURE, 0, ++ _("-R --dereference requires either -H or -L")); ++ affect_symlink_referent = false; ++ } ++ else ++ { ++ if (dereference == 0) ++ error (EXIT_FAILURE, 0, _("-R -h requires -P")); ++ affect_symlink_referent = true; ++ } ++ } ++ else ++ { ++ bit_flags = FTS_PHYSICAL; ++ affect_symlink_referent = (dereference != 0); ++ } ++ ++ if (argc - optind < (reference_file || component_specified ? 1 : 2)) ++ { ++ if (argc <= optind) ++ error (0, 0, _("missing operand")); ++ else ++ error (0, 0, _("missing operand after %s"), quote (argv[argc - 1])); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (is_selinux_enabled () != 1) ++ error (EXIT_FAILURE, 0, ++ _("%s may be used only on a SELinux kernel"), program_name); ++ ++ if (reference_file) ++ { ++ if (getfilecon (reference_file, &ref_context) < 0) ++ error (EXIT_FAILURE, errno, _("failed to get security context of %s"), ++ quote (reference_file)); ++ ++ specified_context = ref_context; ++ } ++ else if (component_specified) ++ { ++ /* FIXME: it's already null, so this is a no-op. */ ++ specified_context = NULL; ++ } ++ else ++ { ++ context_t context; ++ specified_context = argv[optind++]; ++ context = context_new (specified_context); ++ if (!context) ++ error (EXIT_FAILURE, 0, _("invalid context: %s"), ++ quotearg_colon (specified_context)); ++ context_free (context); ++ } ++ ++ if (reference_file && component_specified) ++ { ++ error (0, 0, _("conflicting security context specifiers given")); ++ usage (1); ++ } ++ ++ if (recurse && preserve_root) ++ { ++ static struct dev_ino dev_ino_buf; ++ root_dev_ino = get_root_dev_ino (&dev_ino_buf); ++ if (root_dev_ino == NULL) ++ error (EXIT_FAILURE, errno, _("failed to get attributes of %s"), ++ quote ("/")); ++ } ++ else ++ { ++ root_dev_ino = NULL; ++ } ++ ++ ok = process_files (argv + optind, bit_flags | FTS_NOSTAT); ++ ++ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); ++} +diff -urNp coreutils-8.0-orig/src/id.c coreutils-8.0/src/id.c +--- coreutils-8.0-orig/src/id.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/id.c 2009-10-07 10:10:11.000000000 +0200 @@ -107,7 +107,7 @@ int main (int argc, char **argv) { @@ -185,10 +4602,10 @@ diff -urNp coreutils-7.1-orig/src/id.c coreutils-7.1/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c ---- coreutils-7.1-orig/src/install.c 2009-02-18 15:32:52.000000000 +0100 -+++ coreutils-7.1/src/install.c 2009-02-24 13:47:15.000000000 +0100 -@@ -292,6 +292,7 @@ cp_option_init (struct cp_options *x) +diff -urNp coreutils-8.0-orig/src/install.c coreutils-8.0/src/install.c +--- coreutils-8.0-orig/src/install.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.0/src/install.c 2009-10-07 10:10:11.000000000 +0200 +@@ -284,6 +284,7 @@ cp_option_init (struct cp_options *x) x->reduce_diagnostics=false; x->require_preserve = false; x->require_preserve_context = false; @@ -196,7 +4613,7 @@ diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c x->require_preserve_xattr = false; x->recursive = false; x->sparse_mode = SPARSE_AUTO; -@@ -469,7 +470,7 @@ main (int argc, char **argv) +@@ -461,7 +462,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -205,7 +4622,7 @@ diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c NULL)) != -1) { switch (optc) -@@ -539,6 +540,7 @@ main (int argc, char **argv) +@@ -535,6 +536,7 @@ main (int argc, char **argv) error (0, 0, _("WARNING: --preserve_context is deprecated; " "use --preserve-context instead")); /* fall through */ @@ -213,7 +4630,7 @@ diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c case PRESERVE_CONTEXT_OPTION: if ( ! selinux_enabled) { -@@ -546,6 +548,10 @@ main (int argc, char **argv) +@@ -542,6 +544,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } @@ -224,7 +4641,7 @@ diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c x.preserve_security_context = true; use_default_selinux_context = false; break; -@@ -557,6 +563,7 @@ main (int argc, char **argv) +@@ -553,6 +559,7 @@ main (int argc, char **argv) break; } scontext = optarg; @@ -232,7 +4649,7 @@ diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c use_default_selinux_context = false; break; case_GETOPT_HELP_CHAR; -@@ -990,8 +997,8 @@ Mandatory arguments to long options are +@@ -986,8 +993,8 @@ Mandatory arguments to long options are -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ @@ -243,10 +4660,1025 @@ diff -urNp coreutils-7.1-orig/src/install.c coreutils-7.1/src/install.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); -diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c ---- coreutils-7.1-orig/src/ls.c 2009-02-20 19:34:02.000000000 +0100 -+++ coreutils-7.1/src/ls.c 2009-02-24 13:47:15.000000000 +0100 -@@ -136,7 +136,8 @@ enum filetype +diff -urNp coreutils-8.0-orig/src/install.c.orig coreutils-8.0/src/install.c.orig +--- coreutils-8.0-orig/src/install.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/install.c.orig 2009-09-29 15:27:54.000000000 +0200 +@@ -0,0 +1,1011 @@ ++/* install - copy files and set attributes ++ Copyright (C) 89, 90, 91, 1995-2009 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 David MacKenzie */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "system.h" ++#include "backupfile.h" ++#include "error.h" ++#include "cp-hash.h" ++#include "copy.h" ++#include "filenamecat.h" ++#include "full-read.h" ++#include "mkancesdirs.h" ++#include "mkdir-p.h" ++#include "modechange.h" ++#include "prog-fprintf.h" ++#include "quote.h" ++#include "quotearg.h" ++#include "savewd.h" ++#include "stat-time.h" ++#include "utimens.h" ++#include "xstrtol.h" ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "install" ++ ++#define AUTHORS proper_name ("David MacKenzie") ++ ++#if HAVE_SYS_WAIT_H ++# include ++#endif ++ ++static int selinux_enabled = 0; ++static bool use_default_selinux_context = true; ++ ++#if ! HAVE_ENDGRENT ++# define endgrent() ((void) 0) ++#endif ++ ++#if ! HAVE_ENDPWENT ++# define endpwent() ((void) 0) ++#endif ++ ++#if ! HAVE_LCHOWN ++# define lchown(name, uid, gid) chown (name, uid, gid) ++#endif ++ ++#if ! HAVE_MATCHPATHCON_INIT_PREFIX ++# define matchpathcon_init_prefix(a, p) /* empty */ ++#endif ++ ++static bool change_timestamps (struct stat const *from_sb, char const *to); ++static bool change_attributes (char const *name); ++static bool copy_file (const char *from, const char *to, ++ const struct cp_options *x); ++static bool install_file_in_file_parents (char const *from, char *to, ++ struct cp_options *x); ++static bool install_file_in_dir (const char *from, const char *to_dir, ++ const struct cp_options *x); ++static bool install_file_in_file (const char *from, const char *to, ++ const struct cp_options *x); ++static void get_ids (void); ++static void strip (char const *name); ++static void announce_mkdir (char const *dir, void *options); ++static int make_ancestor (char const *dir, char const *component, ++ void *options); ++void usage (int status); ++ ++/* The user name that will own the files, or NULL to make the owner ++ the current user ID. */ ++static char *owner_name; ++ ++/* The user ID corresponding to `owner_name'. */ ++static uid_t owner_id; ++ ++/* The group name that will own the files, or NULL to make the group ++ the current group ID. */ ++static char *group_name; ++ ++/* The group ID corresponding to `group_name'. */ ++static gid_t group_id; ++ ++#define DEFAULT_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) ++ ++/* The file mode bits to which non-directory files will be set. The umask has ++ no effect. */ ++static mode_t mode = DEFAULT_MODE; ++ ++/* Similar, but for directories. */ ++static mode_t dir_mode = DEFAULT_MODE; ++ ++/* The file mode bits that the user cares about. This should be a ++ superset of DIR_MODE and a subset of CHMOD_MODE_BITS. This matters ++ for directories, since otherwise directories may keep their S_ISUID ++ or S_ISGID bits. */ ++static mode_t dir_mode_bits = CHMOD_MODE_BITS; ++ ++/* Compare files before installing (-C) */ ++static bool copy_only_if_needed; ++ ++/* If true, strip executable files after copying them. */ ++static bool strip_files; ++ ++/* If true, install a directory instead of a regular file. */ ++static bool dir_arg; ++ ++/* Program used to strip binaries, "strip" is default */ ++static char const *strip_program = "strip"; ++ ++/* For long options that have no equivalent short option, use a ++ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ ++enum ++{ ++ PRESERVE_CONTEXT_OPTION = CHAR_MAX + 1, ++ PRESERVE_CONTEXT_OPTION_DEPRECATED, ++ STRIP_PROGRAM_OPTION ++}; ++ ++static struct option const long_options[] = ++{ ++ {"backup", optional_argument, NULL, 'b'}, ++ {"compare", no_argument, NULL, 'C'}, ++ {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, ++ {"directory", no_argument, NULL, 'd'}, ++ {"group", required_argument, NULL, 'g'}, ++ {"mode", required_argument, NULL, 'm'}, ++ {"no-target-directory", no_argument, NULL, 'T'}, ++ {"owner", required_argument, NULL, 'o'}, ++ {"preserve-timestamps", no_argument, NULL, 'p'}, ++ {"preserve-context", no_argument, NULL, PRESERVE_CONTEXT_OPTION}, ++ /* --preserve_context was silently supported until Apr 2009. ++ FIXME: disable altogether in a year or so. */ ++ {"preserve_context", no_argument, NULL, PRESERVE_CONTEXT_OPTION_DEPRECATED}, ++ {"strip", no_argument, NULL, 's'}, ++ {"strip-program", required_argument, NULL, STRIP_PROGRAM_OPTION}, ++ {"suffix", required_argument, NULL, 'S'}, ++ {"target-directory", required_argument, NULL, 't'}, ++ {"verbose", no_argument, NULL, 'v'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++/* Compare content of opened files using file descriptors A_FD and B_FD. Return ++ true if files are equal. */ ++static bool ++have_same_content (int a_fd, int b_fd) ++{ ++ enum { CMP_BLOCK_SIZE = 4096 }; ++ static char a_buff[CMP_BLOCK_SIZE]; ++ static char b_buff[CMP_BLOCK_SIZE]; ++ ++ size_t size; ++ while (0 < (size = full_read (a_fd, a_buff, sizeof a_buff))) { ++ if (size != full_read (b_fd, b_buff, sizeof b_buff)) ++ return false; ++ ++ if (memcmp (a_buff, b_buff, size) != 0) ++ return false; ++ } ++ ++ return size == 0; ++} ++ ++/* Return true for mode with non-permission bits. */ ++static bool ++extra_mode (mode_t input) ++{ ++ const mode_t mask = ~S_IRWXUGO & ~S_IFMT; ++ return !! (input & mask); ++} ++ ++/* Return true if copy of file SRC_NAME to file DEST_NAME is necessary. */ ++static bool ++need_copy (const char *src_name, const char *dest_name, ++ const struct cp_options *x) ++{ ++ struct stat src_sb, dest_sb; ++ int src_fd, dest_fd; ++ bool content_match; ++ ++ if (extra_mode (mode)) ++ return true; ++ ++ /* compare files using stat */ ++ if (lstat (src_name, &src_sb) != 0) ++ return true; ++ ++ if (lstat (dest_name, &dest_sb) != 0) ++ return true; ++ ++ if (!S_ISREG (src_sb.st_mode) || !S_ISREG (dest_sb.st_mode) ++ || extra_mode (src_sb.st_mode) || extra_mode (dest_sb.st_mode)) ++ return true; ++ ++ if (src_sb.st_size != dest_sb.st_size ++ || (dest_sb.st_mode & CHMOD_MODE_BITS) != mode ++ || dest_sb.st_uid != (owner_id == (uid_t) -1 ? getuid () : owner_id) ++ || dest_sb.st_gid != (group_id == (gid_t) -1 ? getgid () : group_id)) ++ return true; ++ ++ /* compare SELinux context if preserving */ ++ if (selinux_enabled && x->preserve_security_context) ++ { ++ security_context_t file_scontext = NULL; ++ security_context_t to_scontext = NULL; ++ bool scontext_match; ++ ++ if (getfilecon (src_name, &file_scontext) == -1) ++ return true; ++ ++ if (getfilecon (dest_name, &to_scontext) == -1) ++ { ++ freecon (file_scontext); ++ return true; ++ } ++ ++ scontext_match = STREQ (file_scontext, to_scontext); ++ ++ freecon (file_scontext); ++ freecon (to_scontext); ++ if (!scontext_match) ++ return true; ++ } ++ ++ /* compare files content */ ++ src_fd = open (src_name, O_RDONLY | O_BINARY); ++ if (src_fd < 0) ++ return true; ++ ++ dest_fd = open (dest_name, O_RDONLY | O_BINARY); ++ if (dest_fd < 0) ++ { ++ close (src_fd); ++ return true; ++ } ++ ++ content_match = have_same_content (src_fd, dest_fd); ++ ++ close (src_fd); ++ close (dest_fd); ++ return !content_match; ++} ++ ++static void ++cp_option_init (struct cp_options *x) ++{ ++ cp_options_default (x); ++ x->copy_as_regular = true; ++ x->reflink_mode = REFLINK_NEVER; ++ x->dereference = DEREF_ALWAYS; ++ x->unlink_dest_before_opening = true; ++ x->unlink_dest_after_failed_open = false; ++ x->hard_link = false; ++ x->interactive = I_UNSPECIFIED; ++ x->move_mode = false; ++ x->one_file_system = false; ++ x->preserve_ownership = false; ++ x->preserve_links = false; ++ x->preserve_mode = false; ++ x->preserve_timestamps = false; ++ x->reduce_diagnostics=false; ++ x->require_preserve = false; ++ x->require_preserve_context = false; ++ x->require_preserve_xattr = false; ++ x->recursive = false; ++ x->sparse_mode = SPARSE_AUTO; ++ x->symbolic_link = false; ++ x->backup_type = no_backups; ++ ++ /* Create destination files initially writable so we can run strip on them. ++ Although GNU strip works fine on read-only files, some others ++ would fail. */ ++ x->set_mode = true; ++ x->mode = S_IRUSR | S_IWUSR; ++ x->stdin_tty = false; ++ ++ x->open_dangling_dest_symlink = false; ++ x->update = false; ++ x->preserve_security_context = false; ++ x->preserve_xattr = false; ++ x->verbose = false; ++ x->dest_info = NULL; ++ x->src_info = NULL; ++} ++ ++#ifdef ENABLE_MATCHPATHCON ++/* Modify file context to match the specified policy. ++ If an error occurs the file will remain with the default directory ++ context. */ ++static void ++setdefaultfilecon (char const *file) ++{ ++ struct stat st; ++ security_context_t scontext = NULL; ++ static bool first_call = true; ++ ++ if (selinux_enabled != 1) ++ { ++ /* Indicate no context found. */ ++ return; ++ } ++ if (lstat (file, &st) != 0) ++ return; ++ ++ if (first_call && IS_ABSOLUTE_FILE_NAME (file)) ++ { ++ /* Calling matchpathcon_init_prefix (NULL, "/first_component/") ++ is an optimization to minimize the expense of the following ++ matchpathcon call. Do it only once, just before the first ++ matchpathcon call. We *could* call matchpathcon_fini after ++ the final matchpathcon call, but that's not necessary, since ++ by then we're about to exit, and besides, the buffers it ++ would free are still reachable. */ ++ char const *p0; ++ char const *p = file + 1; ++ while (ISSLASH (*p)) ++ ++p; ++ ++ /* Record final leading slash, for when FILE starts with two or more. */ ++ p0 = p - 1; ++ ++ if (*p) ++ { ++ char *prefix; ++ do ++ { ++ ++p; ++ } ++ while (*p && !ISSLASH (*p)); ++ ++ prefix = malloc (p - p0 + 2); ++ if (prefix) ++ { ++ stpcpy (stpncpy (prefix, p0, p - p0), "/"); ++ matchpathcon_init_prefix (NULL, prefix); ++ free (prefix); ++ } ++ } ++ } ++ first_call = false; ++ ++ /* If there's an error determining the context, or it has none, ++ return to allow default context */ ++ if ((matchpathcon (file, st.st_mode, &scontext) != 0) || ++ STREQ (scontext, "<>")) ++ { ++ if (scontext != NULL) ++ freecon (scontext); ++ return; ++ } ++ ++ if (lsetfilecon (file, scontext) < 0 && errno != ENOTSUP) ++ error (0, errno, ++ _("warning: %s: failed to change context to %s"), ++ quotearg_colon (file), scontext); ++ ++ freecon (scontext); ++ return; ++} ++#else ++static void ++setdefaultfilecon (char const *file) ++{ ++ (void) file; ++} ++#endif ++ ++/* FILE is the last operand of this command. Return true if FILE is a ++ directory. But report an error there is a problem accessing FILE, ++ or if FILE does not exist but would have to refer to an existing ++ directory if it referred to anything at all. */ ++ ++static bool ++target_directory_operand (char const *file) ++{ ++ char const *b = last_component (file); ++ size_t blen = strlen (b); ++ bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1])); ++ struct stat st; ++ int err = (stat (file, &st) == 0 ? 0 : errno); ++ bool is_a_dir = !err && S_ISDIR (st.st_mode); ++ if (err && err != ENOENT) ++ error (EXIT_FAILURE, err, _("accessing %s"), quote (file)); ++ if (is_a_dir < looks_like_a_dir) ++ error (EXIT_FAILURE, err, _("target %s is not a directory"), quote (file)); ++ return is_a_dir; ++} ++ ++/* Process a command-line file name, for the -d option. */ ++static int ++process_dir (char *dir, struct savewd *wd, void *options) ++{ ++ return (make_dir_parents (dir, wd, ++ make_ancestor, options, ++ dir_mode, announce_mkdir, ++ dir_mode_bits, owner_id, group_id, false) ++ ? EXIT_SUCCESS ++ : EXIT_FAILURE); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int optc; ++ int exit_status = EXIT_SUCCESS; ++ const char *specified_mode = NULL; ++ bool make_backups = false; ++ char *backup_suffix_string; ++ char *version_control_string = NULL; ++ bool mkdir_and_install = false; ++ struct cp_options x; ++ char const *target_directory = NULL; ++ bool no_target_directory = false; ++ int n_files; ++ char **file; ++ bool strip_program_specified = false; ++ security_context_t scontext = NULL; ++ /* set iff kernel has extra selinux system calls */ ++ selinux_enabled = (0 < is_selinux_enabled ()); ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ atexit (close_stdin); ++ ++ cp_option_init (&x); ++ ++ owner_name = NULL; ++ group_name = NULL; ++ strip_files = false; ++ dir_arg = false; ++ umask (0); ++ ++ /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless ++ we'll actually use backup_suffix_string. */ ++ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); ++ ++ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options, ++ NULL)) != -1) ++ { ++ switch (optc) ++ { ++ case 'b': ++ make_backups = true; ++ if (optarg) ++ version_control_string = optarg; ++ break; ++ case 'c': ++ break; ++ case 'C': ++ copy_only_if_needed = true; ++ break; ++ case 's': ++ strip_files = true; ++#ifdef SIGCHLD ++ /* System V fork+wait does not work if SIGCHLD is ignored. */ ++ signal (SIGCHLD, SIG_DFL); ++#endif ++ break; ++ case STRIP_PROGRAM_OPTION: ++ strip_program = xstrdup (optarg); ++ strip_program_specified = true; ++ break; ++ case 'd': ++ dir_arg = true; ++ break; ++ case 'D': ++ mkdir_and_install = true; ++ break; ++ case 'v': ++ x.verbose = true; ++ break; ++ case 'g': ++ group_name = optarg; ++ break; ++ case 'm': ++ specified_mode = optarg; ++ break; ++ case 'o': ++ owner_name = optarg; ++ break; ++ case 'p': ++ x.preserve_timestamps = true; ++ break; ++ case 'S': ++ make_backups = true; ++ backup_suffix_string = optarg; ++ break; ++ case 't': ++ if (target_directory) ++ error (EXIT_FAILURE, 0, ++ _("multiple target directories specified")); ++ else ++ { ++ struct stat st; ++ if (stat (optarg, &st) != 0) ++ error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg)); ++ if (! S_ISDIR (st.st_mode)) ++ error (EXIT_FAILURE, 0, _("target %s is not a directory"), ++ quote (optarg)); ++ } ++ target_directory = optarg; ++ break; ++ case 'T': ++ no_target_directory = true; ++ break; ++ ++ case PRESERVE_CONTEXT_OPTION_DEPRECATED: ++ error (0, 0, _("WARNING: --preserve_context is deprecated; " ++ "use --preserve-context instead")); ++ /* fall through */ ++ case PRESERVE_CONTEXT_OPTION: ++ if ( ! selinux_enabled) ++ { ++ error (0, 0, _("WARNING: ignoring --preserve-context; " ++ "this kernel is not SELinux-enabled")); ++ break; ++ } ++ x.preserve_security_context = true; ++ use_default_selinux_context = false; ++ break; ++ case 'Z': ++ if ( ! selinux_enabled) ++ { ++ error (0, 0, _("WARNING: ignoring --context (-Z); " ++ "this kernel is not SELinux-enabled")); ++ break; ++ } ++ scontext = optarg; ++ use_default_selinux_context = false; ++ break; ++ case_GETOPT_HELP_CHAR; ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ default: ++ usage (EXIT_FAILURE); ++ } ++ } ++ ++ /* Check for invalid combinations of arguments. */ ++ if (dir_arg && strip_files) ++ error (EXIT_FAILURE, 0, ++ _("the strip option may not be used when installing a directory")); ++ if (dir_arg && target_directory) ++ error (EXIT_FAILURE, 0, ++ _("target directory not allowed when installing a directory")); ++ ++ if (x.preserve_security_context && scontext != NULL) ++ error (EXIT_FAILURE, 0, ++ _("cannot force target context to %s and preserve it"), ++ quote (scontext)); ++ ++ if (backup_suffix_string) ++ simple_backup_suffix = xstrdup (backup_suffix_string); ++ ++ x.backup_type = (make_backups ++ ? xget_version (_("backup type"), ++ version_control_string) ++ : no_backups); ++ ++ if (scontext && setfscreatecon (scontext) < 0) ++ error (EXIT_FAILURE, errno, ++ _("failed to set default file creation context to %s"), ++ quote (scontext)); ++ ++ n_files = argc - optind; ++ file = argv + optind; ++ ++ if (n_files <= ! (dir_arg || target_directory)) ++ { ++ if (n_files <= 0) ++ error (0, 0, _("missing file operand")); ++ else ++ error (0, 0, _("missing destination file operand after %s"), ++ quote (file[0])); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (no_target_directory) ++ { ++ if (target_directory) ++ error (EXIT_FAILURE, 0, ++ _("cannot combine --target-directory (-t) " ++ "and --no-target-directory (-T)")); ++ if (2 < n_files) ++ { ++ error (0, 0, _("extra operand %s"), quote (file[2])); ++ usage (EXIT_FAILURE); ++ } ++ } ++ else if (! (dir_arg || target_directory)) ++ { ++ if (2 <= n_files && target_directory_operand (file[n_files - 1])) ++ target_directory = file[--n_files]; ++ else if (2 < n_files) ++ error (EXIT_FAILURE, 0, _("target %s is not a directory"), ++ quote (file[n_files - 1])); ++ } ++ ++ if (specified_mode) ++ { ++ struct mode_change *change = mode_compile (specified_mode); ++ if (!change) ++ error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode)); ++ mode = mode_adjust (0, false, 0, change, NULL); ++ dir_mode = mode_adjust (0, true, 0, change, &dir_mode_bits); ++ free (change); ++ } ++ ++ if (strip_program_specified && !strip_files) ++ error (0, 0, _("WARNING: ignoring --strip-program option as -s option was " ++ "not specified")); ++ ++ if (copy_only_if_needed && x.preserve_timestamps) ++ { ++ error (0, 0, _("options --compare (-C) and --preserve-timestamps are " ++ "mutually exclusive")); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (copy_only_if_needed && strip_files) ++ { ++ error (0, 0, _("options --compare (-C) and --strip are mutually " ++ "exclusive")); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (copy_only_if_needed && extra_mode (mode)) ++ error (0, 0, _("the --compare (-C) option is ignored when you" ++ " specify a mode with non-permission bits")); ++ ++ get_ids (); ++ ++ if (dir_arg) ++ exit_status = savewd_process_files (n_files, file, process_dir, &x); ++ else ++ { ++ /* FIXME: it's a little gross that this initialization is ++ required by copy.c::copy. */ ++ hash_init (); ++ ++ if (!target_directory) ++ { ++ if (! (mkdir_and_install ++ ? install_file_in_file_parents (file[0], file[1], &x) ++ : install_file_in_file (file[0], file[1], &x))) ++ exit_status = EXIT_FAILURE; ++ } ++ else ++ { ++ int i; ++ dest_info_init (&x); ++ for (i = 0; i < n_files; i++) ++ if (! install_file_in_dir (file[i], target_directory, &x)) ++ exit_status = EXIT_FAILURE; ++ } ++ } ++ ++ exit (exit_status); ++} ++ ++/* Copy file FROM onto file TO, creating any missing parent directories of TO. ++ Return true if successful. */ ++ ++static bool ++install_file_in_file_parents (char const *from, char *to, ++ struct cp_options *x) ++{ ++ bool save_working_directory = ++ ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to)); ++ int status = EXIT_SUCCESS; ++ ++ struct savewd wd; ++ savewd_init (&wd); ++ if (! save_working_directory) ++ savewd_finish (&wd); ++ ++ if (mkancesdirs (to, &wd, make_ancestor, x) == -1) ++ { ++ error (0, errno, _("cannot create directory %s"), to); ++ status = EXIT_FAILURE; ++ } ++ ++ if (save_working_directory) ++ { ++ int restore_result = savewd_restore (&wd, status); ++ int restore_errno = errno; ++ savewd_finish (&wd); ++ if (EXIT_SUCCESS < restore_result) ++ return false; ++ if (restore_result < 0 && status == EXIT_SUCCESS) ++ { ++ error (0, restore_errno, _("cannot create directory %s"), to); ++ return false; ++ } ++ } ++ ++ return (status == EXIT_SUCCESS && install_file_in_file (from, to, x)); ++} ++ ++/* Copy file FROM onto file TO and give TO the appropriate ++ attributes. ++ Return true if successful. */ ++ ++static bool ++install_file_in_file (const char *from, const char *to, ++ const struct cp_options *x) ++{ ++ struct stat from_sb; ++ if (x->preserve_timestamps && stat (from, &from_sb) != 0) ++ { ++ error (0, errno, _("cannot stat %s"), quote (from)); ++ return false; ++ } ++ if (! copy_file (from, to, x)) ++ return false; ++ if (strip_files) ++ strip (to); ++ if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode)) ++ && ! change_timestamps (&from_sb, to)) ++ return false; ++ return change_attributes (to); ++} ++ ++/* Copy file FROM into directory TO_DIR, keeping its same name, ++ and give the copy the appropriate attributes. ++ Return true if successful. */ ++ ++static bool ++install_file_in_dir (const char *from, const char *to_dir, ++ const struct cp_options *x) ++{ ++ const char *from_base = last_component (from); ++ char *to = file_name_concat (to_dir, from_base, NULL); ++ bool ret = install_file_in_file (from, to, x); ++ free (to); ++ return ret; ++} ++ ++/* Copy file FROM onto file TO, creating TO if necessary. ++ Return true if successful. */ ++ ++static bool ++copy_file (const char *from, const char *to, const struct cp_options *x) ++{ ++ bool copy_into_self; ++ ++ if (copy_only_if_needed && !need_copy (from, to, x)) ++ return true; ++ ++ /* Allow installing from non-regular files like /dev/null. ++ Charles Karney reported that some Sun version of install allows that ++ and that sendmail's installation process relies on the behavior. ++ However, since !x->recursive, the call to "copy" will fail if FROM ++ is a directory. */ ++ ++ return copy (from, to, false, x, ©_into_self, NULL); ++} ++ ++/* Set the attributes of file or directory NAME. ++ Return true if successful. */ ++ ++static bool ++change_attributes (char const *name) ++{ ++ bool ok = false; ++ /* chown must precede chmod because on some systems, ++ chown clears the set[ug]id bits for non-superusers, ++ resulting in incorrect permissions. ++ On System V, users can give away files with chown and then not ++ be able to chmod them. So don't give files away. ++ ++ We don't normally ignore errors from chown because the idea of ++ the install command is that the file is supposed to end up with ++ precisely the attributes that the user specified (or defaulted). ++ If the file doesn't end up with the group they asked for, they'll ++ want to know. */ ++ ++ if (! (owner_id == (uid_t) -1 && group_id == (gid_t) -1) ++ && lchown (name, owner_id, group_id) != 0) ++ error (0, errno, _("cannot change ownership of %s"), quote (name)); ++ else if (chmod (name, mode) != 0) ++ error (0, errno, _("cannot change permissions of %s"), quote (name)); ++ else ++ ok = true; ++ ++ if (use_default_selinux_context) ++ setdefaultfilecon (name); ++ ++ return ok; ++} ++ ++/* Set the timestamps of file TO to match those of file FROM. ++ Return true if successful. */ ++ ++static bool ++change_timestamps (struct stat const *from_sb, char const *to) ++{ ++ struct timespec timespec[2]; ++ timespec[0] = get_stat_atime (from_sb); ++ timespec[1] = get_stat_mtime (from_sb); ++ ++ if (utimens (to, timespec)) ++ { ++ error (0, errno, _("cannot set time stamps for %s"), quote (to)); ++ return false; ++ } ++ return true; ++} ++ ++/* Strip the symbol table from the file NAME. ++ We could dig the magic number out of the file first to ++ determine whether to strip it, but the header files and ++ magic numbers vary so much from system to system that making ++ it portable would be very difficult. Not worth the effort. */ ++ ++static void ++strip (char const *name) ++{ ++ int status; ++ pid_t pid = fork (); ++ ++ switch (pid) ++ { ++ case -1: ++ error (EXIT_FAILURE, errno, _("fork system call failed")); ++ break; ++ case 0: /* Child. */ ++ execlp (strip_program, strip_program, name, NULL); ++ error (EXIT_FAILURE, errno, _("cannot run %s"), strip_program); ++ break; ++ default: /* Parent. */ ++ if (waitpid (pid, &status, 0) < 0) ++ error (EXIT_FAILURE, errno, _("waiting for strip")); ++ else if (! WIFEXITED (status) || WEXITSTATUS (status)) ++ error (EXIT_FAILURE, 0, _("strip process terminated abnormally")); ++ break; ++ } ++} ++ ++/* Initialize the user and group ownership of the files to install. */ ++ ++static void ++get_ids (void) ++{ ++ struct passwd *pw; ++ struct group *gr; ++ ++ if (owner_name) ++ { ++ pw = getpwnam (owner_name); ++ if (pw == NULL) ++ { ++ unsigned long int tmp; ++ if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK ++ || UID_T_MAX < tmp) ++ error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name)); ++ owner_id = tmp; ++ } ++ else ++ owner_id = pw->pw_uid; ++ endpwent (); ++ } ++ else ++ owner_id = (uid_t) -1; ++ ++ if (group_name) ++ { ++ gr = getgrnam (group_name); ++ if (gr == NULL) ++ { ++ unsigned long int tmp; ++ if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK ++ || GID_T_MAX < tmp) ++ error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name)); ++ group_id = tmp; ++ } ++ else ++ group_id = gr->gr_gid; ++ endgrent (); ++ } ++ else ++ group_id = (gid_t) -1; ++} ++ ++/* Report that directory DIR was made, if OPTIONS requests this. */ ++static void ++announce_mkdir (char const *dir, void *options) ++{ ++ struct cp_options const *x = options; ++ if (x->verbose) ++ prog_fprintf (stdout, _("creating directory %s"), quote (dir)); ++} ++ ++/* Make ancestor directory DIR, whose last file name component is ++ COMPONENT, with options OPTIONS. Assume the working directory is ++ COMPONENT's parent. */ ++static int ++make_ancestor (char const *dir, char const *component, void *options) ++{ ++ int r = mkdir (component, DEFAULT_MODE); ++ if (r == 0) ++ announce_mkdir (dir, options); ++ return r; ++} ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... [-T] SOURCE DEST\n\ ++ or: %s [OPTION]... SOURCE... DIRECTORY\n\ ++ or: %s [OPTION]... -t DIRECTORY SOURCE...\n\ ++ or: %s [OPTION]... -d DIRECTORY...\n\ ++"), ++ program_name, program_name, program_name, program_name); ++ fputs (_("\ ++\n\ ++This install program copies files (often just compiled) into destination\n\ ++locations you choose. If you want to download and install a ready-to-use\n\ ++package on a GNU/Linux system, you should instead be using a package manager\n\ ++like yum(1) or apt-get(1).\n\ ++\n\ ++In the first three forms, copy SOURCE to DEST or multiple SOURCE(s) to\n\ ++the existing DIRECTORY, while setting permission modes and owner/group.\n\ ++In the 4th form, create all components of the given DIRECTORY(ies).\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ --backup[=CONTROL] make a backup of each existing destination file\n\ ++ -b like --backup but does not accept an argument\n\ ++ -c (ignored)\n\ ++ -C, --compare compare each pair of source and destination files, and\n\ ++ in some cases, do not modify the destination at all\n\ ++ -d, --directory treat all arguments as directory names; create all\n\ ++ components of the specified directories\n\ ++"), stdout); ++ fputs (_("\ ++ -D create all leading components of DEST except the last,\n\ ++ then copy SOURCE to DEST\n\ ++ -g, --group=GROUP set group ownership, instead of process' current group\n\ ++ -m, --mode=MODE set permission mode (as in chmod), instead of rwxr-xr-x\n\ ++ -o, --owner=OWNER set ownership (super-user only)\n\ ++"), stdout); ++ fputs (_("\ ++ -p, --preserve-timestamps apply access/modification times of SOURCE files\n\ ++ to corresponding destination files\n\ ++ -s, --strip strip symbol tables\n\ ++ --strip-program=PROGRAM program used to strip binaries\n\ ++ -S, --suffix=SUFFIX override the usual backup suffix\n\ ++ -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\ ++ -T, --no-target-directory treat DEST as a normal file\n\ ++ -v, --verbose print the name of each directory as it is created\n\ ++"), stdout); ++ fputs (_("\ ++ --preserve-context preserve SELinux security context\n\ ++ -Z, --context=CONTEXT set SELinux security context of files and directories\n\ ++"), stdout); ++ ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\ ++The version control method may be selected via the --backup option or through\n\ ++the VERSION_CONTROL environment variable. Here are the values:\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++ none, off never make backups (even if --backup is given)\n\ ++ numbered, t make numbered backups\n\ ++ existing, nil numbered if numbered backups exist, simple otherwise\n\ ++ simple, never always make simple backups\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} +diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c +--- coreutils-8.0-orig/src/ls.c 2009-10-07 10:09:43.000000000 +0200 ++++ coreutils-8.0/src/ls.c 2009-10-07 10:10:11.000000000 +0200 +@@ -162,7 +162,8 @@ enum filetype symbolic_link, sock, whiteout, @@ -256,7 +5688,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c }; /* Display letters and indicators for each filetype. -@@ -253,6 +254,7 @@ static void queue_directory (char const +@@ -279,6 +280,7 @@ static void queue_directory (char const static void sort_files (void); static void parse_ls_color (void); void usage (int status); @@ -264,7 +5696,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c /* Initial size of hash table. Most hierarchies are likely to be shallower than this. */ -@@ -322,7 +324,7 @@ static struct pending *pending_dirs; +@@ -348,7 +350,7 @@ static struct pending *pending_dirs; static struct timespec current_time; @@ -273,7 +5705,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c static char UNKNOWN_SECURITY_CONTEXT[] = "?"; /* Whether any of the files has an ACL. This affects the width of the -@@ -362,7 +364,9 @@ enum format +@@ -388,7 +390,9 @@ enum format one_per_line, /* -1 */ many_per_line, /* -C */ horizontal, /* -x */ @@ -284,7 +5716,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c }; static enum format format; -@@ -754,6 +758,9 @@ enum +@@ -790,6 +794,9 @@ enum SHOW_CONTROL_CHARS_OPTION, SI_OPTION, SORT_OPTION, @@ -294,7 +5726,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c TIME_OPTION, TIME_STYLE_OPTION }; -@@ -799,7 +806,9 @@ static struct option const long_options[ +@@ -835,7 +842,9 @@ static struct option const long_options[ {"time-style", required_argument, NULL, TIME_STYLE_OPTION}, {"color", optional_argument, NULL, COLOR_OPTION}, {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION}, @@ -305,7 +5737,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c {"author", no_argument, NULL, AUTHOR_OPTION}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -@@ -809,12 +818,12 @@ static struct option const long_options[ +@@ -845,12 +854,12 @@ static struct option const long_options[ static char const *const format_args[] = { "verbose", "long", "commas", "horizontal", "across", @@ -320,7 +5752,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c }; ARGMATCH_VERIFY (format_args, format_types); -@@ -1194,7 +1203,8 @@ main (int argc, char **argv) +@@ -1281,7 +1290,8 @@ main (int argc, char **argv) /* Avoid following symbolic links when possible. */ if (is_colored (C_ORPHAN) || (is_colored (C_EXEC) && color_symlink_as_referent) @@ -330,7 +5762,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c check_symlink_color = true; /* If the standard output is a controlling terminal, watch out -@@ -1241,7 +1251,7 @@ main (int argc, char **argv) +@@ -1328,7 +1338,7 @@ main (int argc, char **argv) if (dereference == DEREF_UNDEFINED) dereference = ((immediate_dirs || indicator_style == classify @@ -339,7 +5771,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c ? DEREF_NEVER : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); -@@ -1261,7 +1271,7 @@ main (int argc, char **argv) +@@ -1348,7 +1358,7 @@ main (int argc, char **argv) format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format @@ -348,7 +5780,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c || print_block_size; format_needs_type = (! format_needs_stat && (recursive -@@ -1292,7 +1302,7 @@ main (int argc, char **argv) +@@ -1379,7 +1389,7 @@ main (int argc, char **argv) } else do @@ -357,7 +5789,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c while (i < argc); if (cwd_n_used) -@@ -1455,7 +1465,7 @@ decode_switches (int argc, char **argv) +@@ -1542,7 +1552,7 @@ decode_switches (int argc, char **argv) ignore_mode = IGNORE_DEFAULT; ignore_patterns = NULL; hide_patterns = NULL; @@ -366,7 +5798,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c /* FIXME: put this in a function. */ { -@@ -1837,13 +1847,27 @@ decode_switches (int argc, char **argv) +@@ -1924,13 +1934,27 @@ decode_switches (int argc, char **argv) break; case 'Z': @@ -395,7 +5827,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c default: usage (LS_FAILURE); } -@@ -2557,8 +2581,10 @@ clear_files (void) +@@ -2651,8 +2675,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); @@ -408,7 +5840,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c } cwd_n_used = 0; -@@ -2600,6 +2626,7 @@ gobble_file (char const *name, enum file +@@ -2694,6 +2720,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -416,7 +5848,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c if (command_line_arg || format_needs_stat -@@ -2699,7 +2726,7 @@ gobble_file (char const *name, enum file +@@ -2793,7 +2820,7 @@ gobble_file (char const *name, enum file f->stat_ok = true; @@ -425,7 +5857,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c { bool have_selinux = false; bool have_acl = false; -@@ -2732,7 +2760,7 @@ gobble_file (char const *name, enum file +@@ -2827,7 +2854,7 @@ gobble_file (char const *name, enum file err = 0; } @@ -434,7 +5866,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c { int n = file_has_acl (absolute_name, &f->stat); err = (n < 0); -@@ -2751,7 +2779,8 @@ gobble_file (char const *name, enum file +@@ -2846,7 +2873,8 @@ gobble_file (char const *name, enum file } if (S_ISLNK (f->stat.st_mode) @@ -444,7 +5876,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c { char *linkname; struct stat linkstats; -@@ -2771,6 +2800,7 @@ gobble_file (char const *name, enum file +@@ -2866,6 +2894,7 @@ gobble_file (char const *name, enum file command line are automatically traced if not being listed as files. */ if (!command_line_arg || format == long_format @@ -452,7 +5884,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c || !S_ISDIR (linkstats.st_mode)) { /* Get the linked-to file's mode for the filetype indicator -@@ -2810,7 +2840,7 @@ gobble_file (char const *name, enum file +@@ -2905,7 +2934,7 @@ gobble_file (char const *name, enum file block_size_width = len; } @@ -461,7 +5893,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c { if (print_owner) { -@@ -3312,6 +3341,13 @@ print_current_files (void) +@@ -3406,6 +3435,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -475,10 +5907,10 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c break; } } -@@ -3434,6 +3470,69 @@ format_group_width (gid_t g) +@@ -3568,6 +3604,69 @@ format_inode (char *buf, size_t buflen, + : (char *) "?"); } - +/* Print info about f in scontext format */ +static void +print_scontext_format (const struct fileinfo *f) @@ -543,9 +5975,9 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c +} + /* Print information about F in long format. */ - static void -@@ -3528,9 +3627,15 @@ print_long_format (const struct fileinfo + print_long_format (const struct fileinfo *f) +@@ -3659,9 +3758,15 @@ print_long_format (const struct fileinfo The latter is wrong when nlink_width is zero. */ p += strlen (p); @@ -562,7 +5994,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c { DIRED_FPUTS (buf, stdout, p - buf); -@@ -3543,9 +3648,6 @@ print_long_format (const struct fileinfo +@@ -3674,9 +3779,6 @@ print_long_format (const struct fileinfo if (print_author) format_user (f->stat.st_author, author_width, f->stat_ok); @@ -572,9 +6004,9 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c p = buf; } -@@ -3888,9 +3990,6 @@ print_file_name_and_frills (const struct - human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, - ST_NBLOCKSIZE, output_block_size)); +@@ -4020,9 +4122,6 @@ print_file_name_and_frills (const struct + : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, + ST_NBLOCKSIZE, output_block_size)); - if (print_scontext) - printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext); @@ -582,8 +6014,8 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, f->stat_ok, f->filetype, NULL, f->stat.st_nlink, start_col); -@@ -4105,9 +4204,6 @@ length_of_file_name_and_frills (const st - output_block_size)) +@@ -4241,9 +4340,6 @@ length_of_file_name_and_frills (const st + output_block_size)) : block_size_width); - if (print_scontext) @@ -592,7 +6024,7 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c quote_name (NULL, f->name, filename_quoting_options, &name_width); len += name_width; -@@ -4538,9 +4634,16 @@ Mandatory arguments to long options are +@@ -4674,9 +4770,16 @@ Mandatory arguments to long options are -w, --width=COLS assume screen width instead of current value\n\ -x list entries by lines instead of by columns\n\ -X sort alphabetically by entry extension\n\ @@ -610,9 +6042,4713 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-7.1-orig/src/mkdir.c coreutils-7.1/src/mkdir.c ---- coreutils-7.1-orig/src/mkdir.c 2008-10-19 21:47:57.000000000 +0200 -+++ coreutils-7.1/src/mkdir.c 2009-02-24 13:47:15.000000000 +0100 +diff -urNp coreutils-8.0-orig/src/ls.c.orig coreutils-8.0/src/ls.c.orig +--- coreutils-8.0-orig/src/ls.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/ls.c.orig 2009-10-07 10:09:43.000000000 +0200 +@@ -0,0 +1,4700 @@ ++/* `dir', `vdir' and `ls' directory listing programs for GNU. ++ Copyright (C) 85, 88, 90, 91, 1995-2009 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 . */ ++ ++/* If ls_mode is LS_MULTI_COL, ++ the multi-column format is the default regardless ++ of the type of output device. ++ This is for the `dir' program. ++ ++ If ls_mode is LS_LONG_FORMAT, ++ the long format is the default regardless of the ++ type of output device. ++ This is for the `vdir' program. ++ ++ If ls_mode is LS_LS, ++ the output format depends on whether the output ++ device is a terminal. ++ This is for the `ls' program. */ ++ ++/* Written by Richard Stallman and David MacKenzie. */ ++ ++/* Color support by Peter Anvin and Dennis ++ Flaherty based on original patches by ++ Greg Lee . */ ++ ++#include ++#include ++ ++#if HAVE_TERMIOS_H ++# include ++#endif ++#if HAVE_STROPTS_H ++# include ++#endif ++#if HAVE_SYS_IOCTL_H ++# include ++#endif ++ ++#ifdef WINSIZE_IN_PTEM ++# include ++# include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if HAVE_LANGINFO_CODESET ++# include ++#endif ++ ++/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is ++ present. */ ++#ifndef SA_NOCLDSTOP ++# define SA_NOCLDSTOP 0 ++# define sigprocmask(How, Set, Oset) /* empty */ ++# define sigset_t int ++# if ! HAVE_SIGINTERRUPT ++# define siginterrupt(sig, flag) /* empty */ ++# endif ++#endif ++#ifndef SA_RESTART ++# define SA_RESTART 0 ++#endif ++ ++#include "system.h" ++#include ++ ++#ifdef HAVE_CAP ++# include ++#endif ++ ++#include "acl.h" ++#include "argmatch.h" ++#include "dev-ino.h" ++#include "error.h" ++#include "filenamecat.h" ++#include "hard-locale.h" ++#include "hash.h" ++#include "human.h" ++#include "filemode.h" ++#include "filevercmp.h" ++#include "idcache.h" ++#include "ls.h" ++#include "mbswidth.h" ++#include "mpsort.h" ++#include "obstack.h" ++#include "quote.h" ++#include "quotearg.h" ++#include "same.h" ++#include "stat-time.h" ++#include "strftime.h" ++#include "xstrtol.h" ++#include "areadlink.h" ++#include "mbsalign.h" ++ ++#define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \ ++ : (ls_mode == LS_MULTI_COL \ ++ ? "dir" : "vdir")) ++ ++#define AUTHORS \ ++ proper_name ("Richard M. Stallman"), \ ++ proper_name ("David MacKenzie") ++ ++#define obstack_chunk_alloc malloc ++#define obstack_chunk_free free ++ ++/* Return an int indicating the result of comparing two integers. ++ Subtracting doesn't always work, due to overflow. */ ++#define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b)) ++ ++/* Unix-based readdir implementations have historically returned a dirent.d_ino ++ value that is sometimes not equal to the stat-obtained st_ino value for ++ that same entry. This error occurs for a readdir entry that refers ++ to a mount point. readdir's error is to return the inode number of ++ the underlying directory -- one that typically cannot be stat'ed, as ++ long as a file system is mounted on that directory. RELIABLE_D_INO ++ encapsulates whether we can use the more efficient approach of relying ++ on readdir-supplied d_ino values, or whether we must incur the cost of ++ calling stat or lstat to obtain each guaranteed-valid inode number. */ ++ ++#ifndef READDIR_LIES_ABOUT_MOUNTPOINT_D_INO ++# define READDIR_LIES_ABOUT_MOUNTPOINT_D_INO 1 ++#endif ++ ++#if READDIR_LIES_ABOUT_MOUNTPOINT_D_INO ++# define RELIABLE_D_INO(dp) NOT_AN_INODE_NUMBER ++#else ++# define RELIABLE_D_INO(dp) D_INO (dp) ++#endif ++ ++#if ! HAVE_STRUCT_STAT_ST_AUTHOR ++# define st_author st_uid ++#endif ++ ++enum filetype ++ { ++ unknown, ++ fifo, ++ chardev, ++ directory, ++ blockdev, ++ normal, ++ symbolic_link, ++ sock, ++ whiteout, ++ arg_directory ++ }; ++ ++/* Display letters and indicators for each filetype. ++ Keep these in sync with enum filetype. */ ++static char const filetype_letter[] = "?pcdb-lswd"; ++ ++/* Ensure that filetype and filetype_letter have the same ++ number of elements. */ ++verify (sizeof filetype_letter - 1 == arg_directory + 1); ++ ++#define FILETYPE_INDICATORS \ ++ { \ ++ C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE, \ ++ C_LINK, C_SOCK, C_FILE, C_DIR \ ++ } ++ ++enum acl_type ++ { ++ ACL_T_NONE, ++ ACL_T_SELINUX_ONLY, ++ ACL_T_YES ++ }; ++ ++struct fileinfo ++ { ++ /* The file name. */ ++ char *name; ++ ++ /* For symbolic link, name of the file linked to, otherwise zero. */ ++ char *linkname; ++ ++ struct stat stat; ++ ++ enum filetype filetype; ++ ++ /* For symbolic link and long listing, st_mode of file linked to, otherwise ++ zero. */ ++ mode_t linkmode; ++ ++ /* SELinux security context. */ ++ security_context_t scontext; ++ ++ bool stat_ok; ++ ++ /* For symbolic link and color printing, true if linked-to file ++ exists, otherwise false. */ ++ bool linkok; ++ ++ /* For long listings, true if the file has an access control list, ++ or an SELinux security context. */ ++ enum acl_type acl_type; ++ }; ++ ++#define LEN_STR_PAIR(s) sizeof (s) - 1, s ++ ++/* Null is a valid character in a color indicator (think about Epson ++ printers, for example) so we have to use a length/buffer string ++ type. */ ++ ++struct bin_str ++ { ++ size_t len; /* Number of bytes */ ++ const char *string; /* Pointer to the same */ ++ }; ++ ++#if ! HAVE_TCGETPGRP ++# define tcgetpgrp(Fd) 0 ++#endif ++ ++static size_t quote_name (FILE *out, const char *name, ++ struct quoting_options const *options, ++ size_t *width); ++static char *make_link_name (char const *name, char const *linkname); ++static int decode_switches (int argc, char **argv); ++static bool file_ignored (char const *name); ++static uintmax_t gobble_file (char const *name, enum filetype type, ++ ino_t inode, bool command_line_arg, ++ char const *dirname); ++static bool print_color_indicator (const char *name, mode_t mode, int linkok, ++ bool stat_ok, enum filetype type, ++ nlink_t nlink); ++static void put_indicator (const struct bin_str *ind); ++static void add_ignore_pattern (const char *pattern); ++static void attach (char *dest, const char *dirname, const char *name); ++static void clear_files (void); ++static void extract_dirs_from_files (char const *dirname, ++ bool command_line_arg); ++static void get_link_name (char const *filename, struct fileinfo *f, ++ bool command_line_arg); ++static void indent (size_t from, size_t to); ++static size_t calculate_columns (bool by_columns); ++static void print_current_files (void); ++static void print_dir (char const *name, char const *realname, ++ bool command_line_arg); ++static size_t print_file_name_and_frills (const struct fileinfo *f, ++ size_t start_col); ++static void print_horizontal (void); ++static int format_user_width (uid_t u); ++static int format_group_width (gid_t g); ++static void print_long_format (const struct fileinfo *f); ++static void print_many_per_line (void); ++static size_t print_name_with_quoting (const char *p, mode_t mode, ++ int linkok, bool stat_ok, ++ enum filetype type, ++ struct obstack *stack, ++ nlink_t nlink, ++ size_t start_col); ++static void prep_non_filename_text (void); ++static bool print_type_indicator (bool stat_ok, mode_t mode, ++ enum filetype type); ++static void print_with_commas (void); ++static void queue_directory (char const *name, char const *realname, ++ bool command_line_arg); ++static void sort_files (void); ++static void parse_ls_color (void); ++void usage (int status); ++ ++/* Initial size of hash table. ++ Most hierarchies are likely to be shallower than this. */ ++#define INITIAL_TABLE_SIZE 30 ++ ++/* The set of `active' directories, from the current command-line argument ++ to the level in the hierarchy at which files are being listed. ++ A directory is represented by its device and inode numbers (struct dev_ino). ++ A directory is added to this set when ls begins listing it or its ++ entries, and it is removed from the set just after ls has finished ++ processing it. This set is used solely to detect loops, e.g., with ++ mkdir loop; cd loop; ln -s ../loop sub; ls -RL */ ++static Hash_table *active_dir_set; ++ ++#define LOOP_DETECT (!!active_dir_set) ++ ++/* The table of files in the current directory: ++ ++ `cwd_file' points to a vector of `struct fileinfo', one per file. ++ `cwd_n_alloc' is the number of elements space has been allocated for. ++ `cwd_n_used' is the number actually in use. */ ++ ++/* Address of block containing the files that are described. */ ++static struct fileinfo *cwd_file; ++ ++/* Length of block that `cwd_file' points to, measured in files. */ ++static size_t cwd_n_alloc; ++ ++/* Index of first unused slot in `cwd_file'. */ ++static size_t cwd_n_used; ++ ++/* Vector of pointers to files, in proper sorted order, and the number ++ of entries allocated for it. */ ++static void **sorted_file; ++static size_t sorted_file_alloc; ++ ++/* When true, in a color listing, color each symlink name according to the ++ type of file it points to. Otherwise, color them according to the `ln' ++ directive in LS_COLORS. Dangling (orphan) symlinks are treated specially, ++ regardless. This is set when `ln=target' appears in LS_COLORS. */ ++ ++static bool color_symlink_as_referent; ++ ++/* mode of appropriate file for colorization */ ++#define FILE_OR_LINK_MODE(File) \ ++ ((color_symlink_as_referent && (File)->linkok) \ ++ ? (File)->linkmode : (File)->stat.st_mode) ++ ++ ++/* Record of one pending directory waiting to be listed. */ ++ ++struct pending ++ { ++ char *name; ++ /* If the directory is actually the file pointed to by a symbolic link we ++ were told to list, `realname' will contain the name of the symbolic ++ link, otherwise zero. */ ++ char *realname; ++ bool command_line_arg; ++ struct pending *next; ++ }; ++ ++static struct pending *pending_dirs; ++ ++/* Current time in seconds and nanoseconds since 1970, updated as ++ needed when deciding whether a file is recent. */ ++ ++static struct timespec current_time; ++ ++static bool print_scontext; ++static char UNKNOWN_SECURITY_CONTEXT[] = "?"; ++ ++/* Whether any of the files has an ACL. This affects the width of the ++ mode column. */ ++ ++static bool any_has_acl; ++ ++/* The number of columns to use for columns containing inode numbers, ++ block sizes, link counts, owners, groups, authors, major device ++ numbers, minor device numbers, and file sizes, respectively. */ ++ ++static int inode_number_width; ++static int block_size_width; ++static int nlink_width; ++static int scontext_width; ++static int owner_width; ++static int group_width; ++static int author_width; ++static int major_device_number_width; ++static int minor_device_number_width; ++static int file_size_width; ++ ++/* Option flags */ ++ ++/* long_format for lots of info, one per line. ++ one_per_line for just names, one per line. ++ many_per_line for just names, many per line, sorted vertically. ++ horizontal for just names, many per line, sorted horizontally. ++ with_commas for just names, many per line, separated by commas. ++ ++ -l (and other options that imply -l), -1, -C, -x and -m control ++ this parameter. */ ++ ++enum format ++ { ++ long_format, /* -l and other options that imply -l */ ++ one_per_line, /* -1 */ ++ many_per_line, /* -C */ ++ horizontal, /* -x */ ++ with_commas /* -m */ ++ }; ++ ++static enum format format; ++ ++/* `full-iso' uses full ISO-style dates and times. `long-iso' uses longer ++ ISO-style time stamps, though shorter than `full-iso'. `iso' uses shorter ++ ISO-style time stamps. `locale' uses locale-dependent time stamps. */ ++enum time_style ++ { ++ full_iso_time_style, /* --time-style=full-iso */ ++ long_iso_time_style, /* --time-style=long-iso */ ++ iso_time_style, /* --time-style=iso */ ++ locale_time_style /* --time-style=locale */ ++ }; ++ ++static char const *const time_style_args[] = ++{ ++ "full-iso", "long-iso", "iso", "locale", NULL ++}; ++static enum time_style const time_style_types[] = ++{ ++ full_iso_time_style, long_iso_time_style, iso_time_style, ++ locale_time_style ++}; ++ARGMATCH_VERIFY (time_style_args, time_style_types); ++ ++/* Type of time to print or sort by. Controlled by -c and -u. ++ The values of each item of this enum are important since they are ++ used as indices in the sort functions array (see sort_files()). */ ++ ++enum time_type ++ { ++ time_mtime, /* default */ ++ time_ctime, /* -c */ ++ time_atime, /* -u */ ++ time_numtypes /* the number of elements of this enum */ ++ }; ++ ++static enum time_type time_type; ++ ++/* The file characteristic to sort by. Controlled by -t, -S, -U, -X, -v. ++ The values of each item of this enum are important since they are ++ used as indices in the sort functions array (see sort_files()). */ ++ ++enum sort_type ++ { ++ sort_none = -1, /* -U */ ++ sort_name, /* default */ ++ sort_extension, /* -X */ ++ sort_size, /* -S */ ++ sort_version, /* -v */ ++ sort_time, /* -t */ ++ sort_numtypes /* the number of elements of this enum */ ++ }; ++ ++static enum sort_type sort_type; ++ ++/* Direction of sort. ++ false means highest first if numeric, ++ lowest first if alphabetic; ++ these are the defaults. ++ true means the opposite order in each case. -r */ ++ ++static bool sort_reverse; ++ ++/* True means to display owner information. -g turns this off. */ ++ ++static bool print_owner = true; ++ ++/* True means to display author information. */ ++ ++static bool print_author; ++ ++/* True means to display group information. -G and -o turn this off. */ ++ ++static bool print_group = true; ++ ++/* True means print the user and group id's as numbers rather ++ than as names. -n */ ++ ++static bool numeric_ids; ++ ++/* True means mention the size in blocks of each file. -s */ ++ ++static bool print_block_size; ++ ++/* Human-readable options for output. */ ++static int human_output_opts; ++ ++/* The units to use when printing sizes other than file sizes. */ ++static uintmax_t output_block_size; ++ ++/* Likewise, but for file sizes. */ ++static uintmax_t file_output_block_size = 1; ++ ++/* Follow the output with a special string. Using this format, ++ Emacs' dired mode starts up twice as fast, and can handle all ++ strange characters in file names. */ ++static bool dired; ++ ++/* `none' means don't mention the type of files. ++ `slash' means mention directories only, with a '/'. ++ `file_type' means mention file types. ++ `classify' means mention file types and mark executables. ++ ++ Controlled by -F, -p, and --indicator-style. */ ++ ++enum indicator_style ++ { ++ none, /* --indicator-style=none */ ++ slash, /* -p, --indicator-style=slash */ ++ file_type, /* --indicator-style=file-type */ ++ classify /* -F, --indicator-style=classify */ ++ }; ++ ++static enum indicator_style indicator_style; ++ ++/* Names of indicator styles. */ ++static char const *const indicator_style_args[] = ++{ ++ "none", "slash", "file-type", "classify", NULL ++}; ++static enum indicator_style const indicator_style_types[] = ++{ ++ none, slash, file_type, classify ++}; ++ARGMATCH_VERIFY (indicator_style_args, indicator_style_types); ++ ++/* True means use colors to mark types. Also define the different ++ colors as well as the stuff for the LS_COLORS environment variable. ++ The LS_COLORS variable is now in a termcap-like format. */ ++ ++static bool print_with_color; ++ ++/* Whether we used any colors in the output so far. If so, we will ++ need to restore the default color later. If not, we will need to ++ call prep_non_filename_text before using color for the first time. */ ++ ++static bool used_color = false; ++ ++enum color_type ++ { ++ color_never, /* 0: default or --color=never */ ++ color_always, /* 1: --color=always */ ++ color_if_tty /* 2: --color=tty */ ++ }; ++ ++enum Dereference_symlink ++ { ++ DEREF_UNDEFINED = 1, ++ DEREF_NEVER, ++ DEREF_COMMAND_LINE_ARGUMENTS, /* -H */ ++ DEREF_COMMAND_LINE_SYMLINK_TO_DIR, /* the default, in certain cases */ ++ DEREF_ALWAYS /* -L */ ++ }; ++ ++enum indicator_no ++ { ++ C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK, ++ C_FIFO, C_SOCK, ++ C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID, ++ C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_MULTIHARDLINK, ++ C_CLR_TO_EOL ++ }; ++ ++static const char *const indicator_name[]= ++ { ++ "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so", ++ "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st", ++ "ow", "tw", "ca", "mh", "cl", NULL ++ }; ++ ++struct color_ext_type ++ { ++ struct bin_str ext; /* The extension we're looking for */ ++ struct bin_str seq; /* The sequence to output when we do */ ++ struct color_ext_type *next; /* Next in list */ ++ }; ++ ++static struct bin_str color_indicator[] = ++ { ++ { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ ++ { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ ++ { 0, NULL }, /* ec: End color (replaces lc+no+rc) */ ++ { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ ++ { 0, NULL }, /* no: Normal */ ++ { 0, NULL }, /* fi: File: default */ ++ { LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */ ++ { LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */ ++ { LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */ ++ { LEN_STR_PAIR ("01;35") }, /* so: Socket: bright magenta */ ++ { LEN_STR_PAIR ("01;33") }, /* bd: Block device: bright yellow */ ++ { LEN_STR_PAIR ("01;33") }, /* cd: Char device: bright yellow */ ++ { 0, NULL }, /* mi: Missing file: undefined */ ++ { 0, NULL }, /* or: Orphaned symlink: undefined */ ++ { LEN_STR_PAIR ("01;32") }, /* ex: Executable: bright green */ ++ { LEN_STR_PAIR ("01;35") }, /* do: Door: bright magenta */ ++ { LEN_STR_PAIR ("37;41") }, /* su: setuid: white on red */ ++ { LEN_STR_PAIR ("30;43") }, /* sg: setgid: black on yellow */ ++ { LEN_STR_PAIR ("37;44") }, /* st: sticky: black on blue */ ++ { LEN_STR_PAIR ("34;42") }, /* ow: other-writable: blue on green */ ++ { LEN_STR_PAIR ("30;42") }, /* tw: ow w/ sticky: black on green */ ++ { LEN_STR_PAIR ("30;41") }, /* ca: black on red */ ++ { 0, NULL }, /* mh: disabled by default */ ++ { LEN_STR_PAIR ("\033[K") }, /* cl: clear to end of line */ ++ }; ++ ++/* FIXME: comment */ ++static struct color_ext_type *color_ext_list = NULL; ++ ++/* Buffer for color sequences */ ++static char *color_buf; ++ ++/* True means to check for orphaned symbolic link, for displaying ++ colors. */ ++ ++static bool check_symlink_color; ++ ++/* True means mention the inode number of each file. -i */ ++ ++static bool print_inode; ++ ++/* What to do with symbolic links. Affected by -d, -F, -H, -l (and ++ other options that imply -l), and -L. */ ++ ++static enum Dereference_symlink dereference; ++ ++/* True means when a directory is found, display info on its ++ contents. -R */ ++ ++static bool recursive; ++ ++/* True means when an argument is a directory name, display info ++ on it itself. -d */ ++ ++static bool immediate_dirs; ++ ++/* True means that directories are grouped before files. */ ++ ++static bool directories_first; ++ ++/* Which files to ignore. */ ++ ++static enum ++{ ++ /* Ignore files whose names start with `.', and files specified by ++ --hide and --ignore. */ ++ IGNORE_DEFAULT, ++ ++ /* Ignore `.', `..', and files specified by --ignore. */ ++ IGNORE_DOT_AND_DOTDOT, ++ ++ /* Ignore only files specified by --ignore. */ ++ IGNORE_MINIMAL ++} ignore_mode; ++ ++/* A linked list of shell-style globbing patterns. If a non-argument ++ file name matches any of these patterns, it is ignored. ++ Controlled by -I. Multiple -I options accumulate. ++ The -B option adds `*~' and `.*~' to this list. */ ++ ++struct ignore_pattern ++ { ++ const char *pattern; ++ struct ignore_pattern *next; ++ }; ++ ++static struct ignore_pattern *ignore_patterns; ++ ++/* Similar to IGNORE_PATTERNS, except that -a or -A causes this ++ variable itself to be ignored. */ ++static struct ignore_pattern *hide_patterns; ++ ++/* True means output nongraphic chars in file names as `?'. ++ (-q, --hide-control-chars) ++ qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are ++ independent. The algorithm is: first, obey the quoting style to get a ++ string representing the file name; then, if qmark_funny_chars is set, ++ replace all nonprintable chars in that string with `?'. It's necessary ++ to replace nonprintable chars even in quoted strings, because we don't ++ want to mess up the terminal if control chars get sent to it, and some ++ quoting methods pass through control chars as-is. */ ++static bool qmark_funny_chars; ++ ++/* Quoting options for file and dir name output. */ ++ ++static struct quoting_options *filename_quoting_options; ++static struct quoting_options *dirname_quoting_options; ++ ++/* The number of chars per hardware tab stop. Setting this to zero ++ inhibits the use of TAB characters for separating columns. -T */ ++static size_t tabsize; ++ ++/* True means print each directory name before listing it. */ ++ ++static bool print_dir_name; ++ ++/* The line length to use for breaking lines in many-per-line format. ++ Can be set with -w. */ ++ ++static size_t line_length; ++ ++/* If true, the file listing format requires that stat be called on ++ each file. */ ++ ++static bool format_needs_stat; ++ ++/* Similar to `format_needs_stat', but set if only the file type is ++ needed. */ ++ ++static bool format_needs_type; ++ ++/* An arbitrary limit on the number of bytes in a printed time stamp. ++ This is set to a relatively small value to avoid the need to worry ++ about denial-of-service attacks on servers that run "ls" on behalf ++ of remote clients. 1000 bytes should be enough for any practical ++ time stamp format. */ ++ ++enum { TIME_STAMP_LEN_MAXIMUM = MAX (1000, INT_STRLEN_BOUND (time_t)) }; ++ ++/* strftime formats for non-recent and recent files, respectively, in ++ -l output. */ ++ ++static char const *long_time_format[2] = ++ { ++ /* strftime format for non-recent files (older than 6 months), in ++ -l output. This should contain the year, month and day (at ++ least), in an order that is understood by people in your ++ locale's territory. Please try to keep the number of used ++ screen columns small, because many people work in windows with ++ only 80 columns. But make this as wide as the other string ++ below, for recent files. */ ++ /* TRANSLATORS: ls output needs to be aligned for ease of reading, ++ so be wary of using variable width fields from the locale. ++ Note %b is handled specially by ls and aligned correctly. ++ Note also that specifying a width as in %5b is erroneous as strftime ++ will count bytes rather than characters in multibyte locales. */ ++ N_("%b %e %Y"), ++ /* strftime format for recent files (younger than 6 months), in -l ++ output. This should contain the month, day and time (at ++ least), in an order that is understood by people in your ++ locale's territory. Please try to keep the number of used ++ screen columns small, because many people work in windows with ++ only 80 columns. But make this as wide as the other string ++ above, for non-recent files. */ ++ /* TRANSLATORS: ls output needs to be aligned for ease of reading, ++ so be wary of using variable width fields from the locale. ++ Note %b is handled specially by ls and aligned correctly. ++ Note also that specifying a width as in %5b is erroneous as strftime ++ will count bytes rather than characters in multibyte locales. */ ++ N_("%b %e %H:%M") ++ }; ++ ++/* The set of signals that are caught. */ ++ ++static sigset_t caught_signals; ++ ++/* If nonzero, the value of the pending fatal signal. */ ++ ++static sig_atomic_t volatile interrupt_signal; ++ ++/* A count of the number of pending stop signals that have been received. */ ++ ++static sig_atomic_t volatile stop_signal_count; ++ ++/* Desired exit status. */ ++ ++static int exit_status; ++ ++/* Exit statuses. */ ++enum ++ { ++ /* "ls" had a minor problem. E.g., while processing a directory, ++ ls obtained the name of an entry via readdir, yet was later ++ unable to stat that name. This happens when listing a directory ++ in which entries are actively being removed or renamed. */ ++ LS_MINOR_PROBLEM = 1, ++ ++ /* "ls" had more serious trouble (e.g., memory exhausted, invalid ++ option or failure to stat a command line argument. */ ++ LS_FAILURE = 2 ++ }; ++ ++/* For long options that have no equivalent short option, use a ++ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ ++enum ++{ ++ AUTHOR_OPTION = CHAR_MAX + 1, ++ BLOCK_SIZE_OPTION, ++ COLOR_OPTION, ++ DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION, ++ FILE_TYPE_INDICATOR_OPTION, ++ FORMAT_OPTION, ++ FULL_TIME_OPTION, ++ GROUP_DIRECTORIES_FIRST_OPTION, ++ HIDE_OPTION, ++ INDICATOR_STYLE_OPTION, ++ QUOTING_STYLE_OPTION, ++ SHOW_CONTROL_CHARS_OPTION, ++ SI_OPTION, ++ SORT_OPTION, ++ TIME_OPTION, ++ TIME_STYLE_OPTION ++}; ++ ++static struct option const long_options[] = ++{ ++ {"all", no_argument, NULL, 'a'}, ++ {"escape", no_argument, NULL, 'b'}, ++ {"directory", no_argument, NULL, 'd'}, ++ {"dired", no_argument, NULL, 'D'}, ++ {"full-time", no_argument, NULL, FULL_TIME_OPTION}, ++ {"group-directories-first", no_argument, NULL, ++ GROUP_DIRECTORIES_FIRST_OPTION}, ++ {"human-readable", no_argument, NULL, 'h'}, ++ {"inode", no_argument, NULL, 'i'}, ++ {"numeric-uid-gid", no_argument, NULL, 'n'}, ++ {"no-group", no_argument, NULL, 'G'}, ++ {"hide-control-chars", no_argument, NULL, 'q'}, ++ {"reverse", no_argument, NULL, 'r'}, ++ {"size", no_argument, NULL, 's'}, ++ {"width", required_argument, NULL, 'w'}, ++ {"almost-all", no_argument, NULL, 'A'}, ++ {"ignore-backups", no_argument, NULL, 'B'}, ++ {"classify", no_argument, NULL, 'F'}, ++ {"file-type", no_argument, NULL, FILE_TYPE_INDICATOR_OPTION}, ++ {"si", no_argument, NULL, SI_OPTION}, ++ {"dereference-command-line", no_argument, NULL, 'H'}, ++ {"dereference-command-line-symlink-to-dir", no_argument, NULL, ++ DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION}, ++ {"hide", required_argument, NULL, HIDE_OPTION}, ++ {"ignore", required_argument, NULL, 'I'}, ++ {"indicator-style", required_argument, NULL, INDICATOR_STYLE_OPTION}, ++ {"dereference", no_argument, NULL, 'L'}, ++ {"literal", no_argument, NULL, 'N'}, ++ {"quote-name", no_argument, NULL, 'Q'}, ++ {"quoting-style", required_argument, NULL, QUOTING_STYLE_OPTION}, ++ {"recursive", no_argument, NULL, 'R'}, ++ {"format", required_argument, NULL, FORMAT_OPTION}, ++ {"show-control-chars", no_argument, NULL, SHOW_CONTROL_CHARS_OPTION}, ++ {"sort", required_argument, NULL, SORT_OPTION}, ++ {"tabsize", required_argument, NULL, 'T'}, ++ {"time", required_argument, NULL, TIME_OPTION}, ++ {"time-style", required_argument, NULL, TIME_STYLE_OPTION}, ++ {"color", optional_argument, NULL, COLOR_OPTION}, ++ {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION}, ++ {"context", no_argument, 0, 'Z'}, ++ {"author", no_argument, NULL, AUTHOR_OPTION}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++static char const *const format_args[] = ++{ ++ "verbose", "long", "commas", "horizontal", "across", ++ "vertical", "single-column", NULL ++}; ++static enum format const format_types[] = ++{ ++ long_format, long_format, with_commas, horizontal, horizontal, ++ many_per_line, one_per_line ++}; ++ARGMATCH_VERIFY (format_args, format_types); ++ ++static char const *const sort_args[] = ++{ ++ "none", "time", "size", "extension", "version", NULL ++}; ++static enum sort_type const sort_types[] = ++{ ++ sort_none, sort_time, sort_size, sort_extension, sort_version ++}; ++ARGMATCH_VERIFY (sort_args, sort_types); ++ ++static char const *const time_args[] = ++{ ++ "atime", "access", "use", "ctime", "status", NULL ++}; ++static enum time_type const time_types[] = ++{ ++ time_atime, time_atime, time_atime, time_ctime, time_ctime ++}; ++ARGMATCH_VERIFY (time_args, time_types); ++ ++static char const *const color_args[] = ++{ ++ /* force and none are for compatibility with another color-ls version */ ++ "always", "yes", "force", ++ "never", "no", "none", ++ "auto", "tty", "if-tty", NULL ++}; ++static enum color_type const color_types[] = ++{ ++ color_always, color_always, color_always, ++ color_never, color_never, color_never, ++ color_if_tty, color_if_tty, color_if_tty ++}; ++ARGMATCH_VERIFY (color_args, color_types); ++ ++/* Information about filling a column. */ ++struct column_info ++{ ++ bool valid_len; ++ size_t line_len; ++ size_t *col_arr; ++}; ++ ++/* Array with information about column filledness. */ ++static struct column_info *column_info; ++ ++/* Maximum number of columns ever possible for this display. */ ++static size_t max_idx; ++ ++/* The minimum width of a column is 3: 1 character for the name and 2 ++ for the separating white space. */ ++#define MIN_COLUMN_WIDTH 3 ++ ++ ++/* This zero-based index is used solely with the --dired option. ++ When that option is in effect, this counter is incremented for each ++ byte of output generated by this program so that the beginning ++ and ending indices (in that output) of every file name can be recorded ++ and later output themselves. */ ++static size_t dired_pos; ++ ++#define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0) ++ ++/* Write S to STREAM and increment DIRED_POS by S_LEN. */ ++#define DIRED_FPUTS(s, stream, s_len) \ ++ do {fputs (s, stream); dired_pos += s_len;} while (0) ++ ++/* Like DIRED_FPUTS, but for use when S is a literal string. */ ++#define DIRED_FPUTS_LITERAL(s, stream) \ ++ do {fputs (s, stream); dired_pos += sizeof (s) - 1;} while (0) ++ ++#define DIRED_INDENT() \ ++ do \ ++ { \ ++ if (dired) \ ++ DIRED_FPUTS_LITERAL (" ", stdout); \ ++ } \ ++ while (0) ++ ++/* With --dired, store pairs of beginning and ending indices of filenames. */ ++static struct obstack dired_obstack; ++ ++/* With --dired, store pairs of beginning and ending indices of any ++ directory names that appear as headers (just before `total' line) ++ for lists of directory entries. Such directory names are seen when ++ listing hierarchies using -R and when a directory is listed with at ++ least one other command line argument. */ ++static struct obstack subdired_obstack; ++ ++/* Save the current index on the specified obstack, OBS. */ ++#define PUSH_CURRENT_DIRED_POS(obs) \ ++ do \ ++ { \ ++ if (dired) \ ++ obstack_grow (obs, &dired_pos, sizeof (dired_pos)); \ ++ } \ ++ while (0) ++ ++/* With -R, this stack is used to help detect directory cycles. ++ The device/inode pairs on this stack mirror the pairs in the ++ active_dir_set hash table. */ ++static struct obstack dev_ino_obstack; ++ ++/* Push a pair onto the device/inode stack. */ ++#define DEV_INO_PUSH(Dev, Ino) \ ++ do \ ++ { \ ++ struct dev_ino *di; \ ++ obstack_blank (&dev_ino_obstack, sizeof (struct dev_ino)); \ ++ di = -1 + (struct dev_ino *) obstack_next_free (&dev_ino_obstack); \ ++ di->st_dev = (Dev); \ ++ di->st_ino = (Ino); \ ++ } \ ++ while (0) ++ ++/* Pop a dev/ino struct off the global dev_ino_obstack ++ and return that struct. */ ++static struct dev_ino ++dev_ino_pop (void) ++{ ++ assert (sizeof (struct dev_ino) <= obstack_object_size (&dev_ino_obstack)); ++ obstack_blank (&dev_ino_obstack, -(int) (sizeof (struct dev_ino))); ++ return *(struct dev_ino *) obstack_next_free (&dev_ino_obstack); ++} ++ ++/* Note the use commented out below: ++#define ASSERT_MATCHING_DEV_INO(Name, Di) \ ++ do \ ++ { \ ++ struct stat sb; \ ++ assert (Name); \ ++ assert (0 <= stat (Name, &sb)); \ ++ assert (sb.st_dev == Di.st_dev); \ ++ assert (sb.st_ino == Di.st_ino); \ ++ } \ ++ while (0) ++*/ ++ ++/* Write to standard output PREFIX, followed by the quoting style and ++ a space-separated list of the integers stored in OS all on one line. */ ++ ++static void ++dired_dump_obstack (const char *prefix, struct obstack *os) ++{ ++ size_t n_pos; ++ ++ n_pos = obstack_object_size (os) / sizeof (dired_pos); ++ if (n_pos > 0) ++ { ++ size_t i; ++ size_t *pos; ++ ++ pos = (size_t *) obstack_finish (os); ++ fputs (prefix, stdout); ++ for (i = 0; i < n_pos; i++) ++ printf (" %lu", (unsigned long int) pos[i]); ++ putchar ('\n'); ++ } ++} ++ ++/* Read the abbreviated month names from the locale, to align them ++ and to determine the max width of the field and to truncate names ++ greater than our max allowed. ++ Note even though this handles multibyte locales correctly ++ it's not restricted to them as single byte locales can have ++ variable width abbreviated months and also precomputing/caching ++ the names was seen to increase the performance of ls significantly. */ ++ ++/* max number of display cells to use */ ++enum { MAX_MON_WIDTH = 5 }; ++/* In the unlikely event that the abmon[] storage is not big enough ++ an error message will be displayed, and we revert to using ++ unmodified abbreviated month names from the locale database. */ ++static char abmon[12][MAX_MON_WIDTH * 2 * MB_LEN_MAX + 1]; ++/* minimum width needed to align %b, 0 => don't use precomputed values. */ ++static size_t required_mon_width; ++ ++static size_t ++abmon_init (void) ++{ ++#ifdef HAVE_NL_LANGINFO ++ required_mon_width = MAX_MON_WIDTH; ++ size_t curr_max_width; ++ do ++ { ++ curr_max_width = required_mon_width; ++ required_mon_width = 0; ++ for (int i = 0; i < 12; i++) ++ { ++ size_t width = curr_max_width; ++ ++ size_t req = mbsalign (nl_langinfo (ABMON_1 + i), ++ abmon[i], sizeof (abmon[i]), ++ &width, MBS_ALIGN_LEFT, 0); ++ ++ if (req == (size_t) -1 || req >= sizeof (abmon[i])) ++ { ++ required_mon_width = 0; /* ignore precomputed strings. */ ++ return required_mon_width; ++ } ++ ++ required_mon_width = MAX (required_mon_width, width); ++ } ++ } ++ while (curr_max_width > required_mon_width); ++#endif ++ ++ return required_mon_width; ++} ++ ++static size_t ++dev_ino_hash (void const *x, size_t table_size) ++{ ++ struct dev_ino const *p = x; ++ return (uintmax_t) p->st_ino % table_size; ++} ++ ++static bool ++dev_ino_compare (void const *x, void const *y) ++{ ++ struct dev_ino const *a = x; ++ struct dev_ino const *b = y; ++ return SAME_INODE (*a, *b) ? true : false; ++} ++ ++static void ++dev_ino_free (void *x) ++{ ++ free (x); ++} ++ ++/* Add the device/inode pair (P->st_dev/P->st_ino) to the set of ++ active directories. Return true if there is already a matching ++ entry in the table. */ ++ ++static bool ++visit_dir (dev_t dev, ino_t ino) ++{ ++ struct dev_ino *ent; ++ struct dev_ino *ent_from_table; ++ bool found_match; ++ ++ ent = xmalloc (sizeof *ent); ++ ent->st_ino = ino; ++ ent->st_dev = dev; ++ ++ /* Attempt to insert this entry into the table. */ ++ ent_from_table = hash_insert (active_dir_set, ent); ++ ++ if (ent_from_table == NULL) ++ { ++ /* Insertion failed due to lack of memory. */ ++ xalloc_die (); ++ } ++ ++ found_match = (ent_from_table != ent); ++ ++ if (found_match) ++ { ++ /* ent was not inserted, so free it. */ ++ free (ent); ++ } ++ ++ return found_match; ++} ++ ++static void ++free_pending_ent (struct pending *p) ++{ ++ free (p->name); ++ free (p->realname); ++ free (p); ++} ++ ++static bool ++is_colored (enum indicator_no type) ++{ ++ size_t len = color_indicator[type].len; ++ char const *s = color_indicator[type].string; ++ return ! (len == 0 ++ || (len == 1 && strncmp (s, "0", 1) == 0) ++ || (len == 2 && strncmp (s, "00", 2) == 0)); ++} ++ ++static void ++restore_default_color (void) ++{ ++ put_indicator (&color_indicator[C_LEFT]); ++ put_indicator (&color_indicator[C_RIGHT]); ++} ++ ++/* An ordinary signal was received; arrange for the program to exit. */ ++ ++static void ++sighandler (int sig) ++{ ++ if (! SA_NOCLDSTOP) ++ signal (sig, SIG_IGN); ++ if (! interrupt_signal) ++ interrupt_signal = sig; ++} ++ ++/* A SIGTSTP was received; arrange for the program to suspend itself. */ ++ ++static void ++stophandler (int sig) ++{ ++ if (! SA_NOCLDSTOP) ++ signal (sig, stophandler); ++ if (! interrupt_signal) ++ stop_signal_count++; ++} ++ ++/* Process any pending signals. If signals are caught, this function ++ should be called periodically. Ideally there should never be an ++ unbounded amount of time when signals are not being processed. ++ Signal handling can restore the default colors, so callers must ++ immediately change colors after invoking this function. */ ++ ++static void ++process_signals (void) ++{ ++ while (interrupt_signal || stop_signal_count) ++ { ++ int sig; ++ int stops; ++ sigset_t oldset; ++ ++ if (used_color) ++ restore_default_color (); ++ fflush (stdout); ++ ++ sigprocmask (SIG_BLOCK, &caught_signals, &oldset); ++ ++ /* Reload interrupt_signal and stop_signal_count, in case a new ++ signal was handled before sigprocmask took effect. */ ++ sig = interrupt_signal; ++ stops = stop_signal_count; ++ ++ /* SIGTSTP is special, since the application can receive that signal ++ more than once. In this case, don't set the signal handler to the ++ default. Instead, just raise the uncatchable SIGSTOP. */ ++ if (stops) ++ { ++ stop_signal_count = stops - 1; ++ sig = SIGSTOP; ++ } ++ else ++ signal (sig, SIG_DFL); ++ ++ /* Exit or suspend the program. */ ++ raise (sig); ++ sigprocmask (SIG_SETMASK, &oldset, NULL); ++ ++ /* If execution reaches here, then the program has been ++ continued (after being suspended). */ ++ } ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int i; ++ struct pending *thispend; ++ int n_files; ++ ++ /* The signals that are trapped, and the number of such signals. */ ++ static int const sig[] = ++ { ++ /* This one is handled specially. */ ++ SIGTSTP, ++ ++ /* The usual suspects. */ ++ SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, ++#ifdef SIGPOLL ++ SIGPOLL, ++#endif ++#ifdef SIGPROF ++ SIGPROF, ++#endif ++#ifdef SIGVTALRM ++ SIGVTALRM, ++#endif ++#ifdef SIGXCPU ++ SIGXCPU, ++#endif ++#ifdef SIGXFSZ ++ SIGXFSZ, ++#endif ++ }; ++ enum { nsigs = ARRAY_CARDINALITY (sig) }; ++ ++#if ! SA_NOCLDSTOP ++ bool caught_sig[nsigs]; ++#endif ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ initialize_exit_failure (LS_FAILURE); ++ atexit (close_stdout); ++ ++ assert (ARRAY_CARDINALITY (color_indicator) + 1 ++ == ARRAY_CARDINALITY (indicator_name)); ++ ++ exit_status = EXIT_SUCCESS; ++ print_dir_name = true; ++ pending_dirs = NULL; ++ ++ current_time.tv_sec = TYPE_MINIMUM (time_t); ++ current_time.tv_nsec = -1; ++ ++ i = decode_switches (argc, argv); ++ ++ if (print_with_color) ++ parse_ls_color (); ++ ++ /* Test print_with_color again, because the call to parse_ls_color ++ may have just reset it -- e.g., if LS_COLORS is invalid. */ ++ if (print_with_color) ++ { ++ /* Avoid following symbolic links when possible. */ ++ if (is_colored (C_ORPHAN) ++ || (is_colored (C_EXEC) && color_symlink_as_referent) ++ || (is_colored (C_MISSING) && format == long_format)) ++ check_symlink_color = true; ++ ++ /* If the standard output is a controlling terminal, watch out ++ for signals, so that the colors can be restored to the ++ default state if "ls" is suspended or interrupted. */ ++ ++ if (0 <= tcgetpgrp (STDOUT_FILENO)) ++ { ++ int j; ++#if SA_NOCLDSTOP ++ struct sigaction act; ++ ++ sigemptyset (&caught_signals); ++ for (j = 0; j < nsigs; j++) ++ { ++ sigaction (sig[j], NULL, &act); ++ if (act.sa_handler != SIG_IGN) ++ sigaddset (&caught_signals, sig[j]); ++ } ++ ++ act.sa_mask = caught_signals; ++ act.sa_flags = SA_RESTART; ++ ++ for (j = 0; j < nsigs; j++) ++ if (sigismember (&caught_signals, sig[j])) ++ { ++ act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; ++ sigaction (sig[j], &act, NULL); ++ } ++#else ++ for (j = 0; j < nsigs; j++) ++ { ++ caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); ++ if (caught_sig[j]) ++ { ++ signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); ++ siginterrupt (sig[j], 0); ++ } ++ } ++#endif ++ } ++ } ++ ++ if (dereference == DEREF_UNDEFINED) ++ dereference = ((immediate_dirs ++ || indicator_style == classify ++ || format == long_format) ++ ? DEREF_NEVER ++ : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); ++ ++ /* When using -R, initialize a data structure we'll use to ++ detect any directory cycles. */ ++ if (recursive) ++ { ++ active_dir_set = hash_initialize (INITIAL_TABLE_SIZE, NULL, ++ dev_ino_hash, ++ dev_ino_compare, ++ dev_ino_free); ++ if (active_dir_set == NULL) ++ xalloc_die (); ++ ++ obstack_init (&dev_ino_obstack); ++ } ++ ++ format_needs_stat = sort_type == sort_time || sort_type == sort_size ++ || format == long_format ++ || print_scontext ++ || print_block_size; ++ format_needs_type = (! format_needs_stat ++ && (recursive ++ || print_with_color ++ || indicator_style != none ++ || directories_first)); ++ ++ if (dired) ++ { ++ obstack_init (&dired_obstack); ++ obstack_init (&subdired_obstack); ++ } ++ ++ cwd_n_alloc = 100; ++ cwd_file = xnmalloc (cwd_n_alloc, sizeof *cwd_file); ++ cwd_n_used = 0; ++ ++ clear_files (); ++ ++ n_files = argc - i; ++ ++ if (n_files <= 0) ++ { ++ if (immediate_dirs) ++ gobble_file (".", directory, NOT_AN_INODE_NUMBER, true, ""); ++ else ++ queue_directory (".", NULL, true); ++ } ++ else ++ do ++ gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, ""); ++ while (i < argc); ++ ++ if (cwd_n_used) ++ { ++ sort_files (); ++ if (!immediate_dirs) ++ extract_dirs_from_files (NULL, true); ++ /* `cwd_n_used' might be zero now. */ ++ } ++ ++ /* In the following if/else blocks, it is sufficient to test `pending_dirs' ++ (and not pending_dirs->name) because there may be no markers in the queue ++ at this point. A marker may be enqueued when extract_dirs_from_files is ++ called with a non-empty string or via print_dir. */ ++ if (cwd_n_used) ++ { ++ print_current_files (); ++ if (pending_dirs) ++ DIRED_PUTCHAR ('\n'); ++ } ++ else if (n_files <= 1 && pending_dirs && pending_dirs->next == 0) ++ print_dir_name = false; ++ ++ while (pending_dirs) ++ { ++ thispend = pending_dirs; ++ pending_dirs = pending_dirs->next; ++ ++ if (LOOP_DETECT) ++ { ++ if (thispend->name == NULL) ++ { ++ /* thispend->name == NULL means this is a marker entry ++ indicating we've finished processing the directory. ++ Use its dev/ino numbers to remove the corresponding ++ entry from the active_dir_set hash table. */ ++ struct dev_ino di = dev_ino_pop (); ++ struct dev_ino *found = hash_delete (active_dir_set, &di); ++ /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */ ++ assert (found); ++ dev_ino_free (found); ++ free_pending_ent (thispend); ++ continue; ++ } ++ } ++ ++ print_dir (thispend->name, thispend->realname, ++ thispend->command_line_arg); ++ ++ free_pending_ent (thispend); ++ print_dir_name = true; ++ } ++ ++ if (print_with_color) ++ { ++ int j; ++ ++ if (used_color) ++ restore_default_color (); ++ fflush (stdout); ++ ++ /* Restore the default signal handling. */ ++#if SA_NOCLDSTOP ++ for (j = 0; j < nsigs; j++) ++ if (sigismember (&caught_signals, sig[j])) ++ signal (sig[j], SIG_DFL); ++#else ++ for (j = 0; j < nsigs; j++) ++ if (caught_sig[j]) ++ signal (sig[j], SIG_DFL); ++#endif ++ ++ /* Act on any signals that arrived before the default was restored. ++ This can process signals out of order, but there doesn't seem to ++ be an easy way to do them in order, and the order isn't that ++ important anyway. */ ++ for (j = stop_signal_count; j; j--) ++ raise (SIGSTOP); ++ j = interrupt_signal; ++ if (j) ++ raise (j); ++ } ++ ++ if (dired) ++ { ++ /* No need to free these since we're about to exit. */ ++ dired_dump_obstack ("//DIRED//", &dired_obstack); ++ dired_dump_obstack ("//SUBDIRED//", &subdired_obstack); ++ printf ("//DIRED-OPTIONS// --quoting-style=%s\n", ++ quoting_style_args[get_quoting_style (filename_quoting_options)]); ++ } ++ ++ if (LOOP_DETECT) ++ { ++ assert (hash_get_n_entries (active_dir_set) == 0); ++ hash_free (active_dir_set); ++ } ++ ++ exit (exit_status); ++} ++ ++/* Set all the option flags according to the switches specified. ++ Return the index of the first non-option argument. */ ++ ++static int ++decode_switches (int argc, char **argv) ++{ ++ char *time_style_option = NULL; ++ ++ /* Record whether there is an option specifying sort type. */ ++ bool sort_type_specified = false; ++ ++ qmark_funny_chars = false; ++ ++ /* initialize all switches to default settings */ ++ ++ switch (ls_mode) ++ { ++ case LS_MULTI_COL: ++ /* This is for the `dir' program. */ ++ format = many_per_line; ++ set_quoting_style (NULL, escape_quoting_style); ++ break; ++ ++ case LS_LONG_FORMAT: ++ /* This is for the `vdir' program. */ ++ format = long_format; ++ set_quoting_style (NULL, escape_quoting_style); ++ break; ++ ++ case LS_LS: ++ /* This is for the `ls' program. */ ++ if (isatty (STDOUT_FILENO)) ++ { ++ format = many_per_line; ++ /* See description of qmark_funny_chars, above. */ ++ qmark_funny_chars = true; ++ } ++ else ++ { ++ format = one_per_line; ++ qmark_funny_chars = false; ++ } ++ break; ++ ++ default: ++ abort (); ++ } ++ ++ time_type = time_mtime; ++ sort_type = sort_name; ++ sort_reverse = false; ++ numeric_ids = false; ++ print_block_size = false; ++ indicator_style = none; ++ print_inode = false; ++ dereference = DEREF_UNDEFINED; ++ recursive = false; ++ immediate_dirs = false; ++ ignore_mode = IGNORE_DEFAULT; ++ ignore_patterns = NULL; ++ hide_patterns = NULL; ++ print_scontext = false; ++ ++ /* FIXME: put this in a function. */ ++ { ++ char const *q_style = getenv ("QUOTING_STYLE"); ++ if (q_style) ++ { ++ int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals); ++ if (0 <= i) ++ set_quoting_style (NULL, quoting_style_vals[i]); ++ else ++ error (0, 0, ++ _("ignoring invalid value of environment variable QUOTING_STYLE: %s"), ++ quotearg (q_style)); ++ } ++ } ++ ++ { ++ char const *ls_block_size = getenv ("LS_BLOCK_SIZE"); ++ human_options (ls_block_size, ++ &human_output_opts, &output_block_size); ++ if (ls_block_size || getenv ("BLOCK_SIZE")) ++ file_output_block_size = output_block_size; ++ } ++ ++ line_length = 80; ++ { ++ char const *p = getenv ("COLUMNS"); ++ if (p && *p) ++ { ++ unsigned long int tmp_ulong; ++ if (xstrtoul (p, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK ++ && 0 < tmp_ulong && tmp_ulong <= SIZE_MAX) ++ { ++ line_length = tmp_ulong; ++ } ++ else ++ { ++ error (0, 0, ++ _("ignoring invalid width in environment variable COLUMNS: %s"), ++ quotearg (p)); ++ } ++ } ++ } ++ ++#ifdef TIOCGWINSZ ++ { ++ struct winsize ws; ++ ++ if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 ++ && 0 < ws.ws_col && ws.ws_col == (size_t) ws.ws_col) ++ line_length = ws.ws_col; ++ } ++#endif ++ ++ { ++ char const *p = getenv ("TABSIZE"); ++ tabsize = 8; ++ if (p) ++ { ++ unsigned long int tmp_ulong; ++ if (xstrtoul (p, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK ++ && tmp_ulong <= SIZE_MAX) ++ { ++ tabsize = tmp_ulong; ++ } ++ else ++ { ++ error (0, 0, ++ _("ignoring invalid tab size in environment variable TABSIZE: %s"), ++ quotearg (p)); ++ } ++ } ++ } ++ ++ for (;;) ++ { ++ int oi = -1; ++ int c = getopt_long (argc, argv, ++ "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1", ++ long_options, &oi); ++ if (c == -1) ++ break; ++ ++ switch (c) ++ { ++ case 'a': ++ ignore_mode = IGNORE_MINIMAL; ++ break; ++ ++ case 'b': ++ set_quoting_style (NULL, escape_quoting_style); ++ break; ++ ++ case 'c': ++ time_type = time_ctime; ++ break; ++ ++ case 'd': ++ immediate_dirs = true; ++ break; ++ ++ case 'f': ++ /* Same as enabling -a -U and disabling -l -s. */ ++ ignore_mode = IGNORE_MINIMAL; ++ sort_type = sort_none; ++ sort_type_specified = true; ++ /* disable -l */ ++ if (format == long_format) ++ format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line); ++ print_block_size = false; /* disable -s */ ++ print_with_color = false; /* disable --color */ ++ break; ++ ++ case FILE_TYPE_INDICATOR_OPTION: /* --file-type */ ++ indicator_style = file_type; ++ break; ++ ++ case 'g': ++ format = long_format; ++ print_owner = false; ++ break; ++ ++ case 'h': ++ human_output_opts = human_autoscale | human_SI | human_base_1024; ++ file_output_block_size = output_block_size = 1; ++ break; ++ ++ case 'i': ++ print_inode = true; ++ break; ++ ++ case 'k': ++ human_output_opts = 0; ++ file_output_block_size = output_block_size = 1024; ++ break; ++ ++ case 'l': ++ format = long_format; ++ break; ++ ++ case 'm': ++ format = with_commas; ++ break; ++ ++ case 'n': ++ numeric_ids = true; ++ format = long_format; ++ break; ++ ++ case 'o': /* Just like -l, but don't display group info. */ ++ format = long_format; ++ print_group = false; ++ break; ++ ++ case 'p': ++ indicator_style = slash; ++ break; ++ ++ case 'q': ++ qmark_funny_chars = true; ++ break; ++ ++ case 'r': ++ sort_reverse = true; ++ break; ++ ++ case 's': ++ print_block_size = true; ++ break; ++ ++ case 't': ++ sort_type = sort_time; ++ sort_type_specified = true; ++ break; ++ ++ case 'u': ++ time_type = time_atime; ++ break; ++ ++ case 'v': ++ sort_type = sort_version; ++ sort_type_specified = true; ++ break; ++ ++ case 'w': ++ { ++ unsigned long int tmp_ulong; ++ if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK ++ || ! (0 < tmp_ulong && tmp_ulong <= SIZE_MAX)) ++ error (LS_FAILURE, 0, _("invalid line width: %s"), ++ quotearg (optarg)); ++ line_length = tmp_ulong; ++ break; ++ } ++ ++ case 'x': ++ format = horizontal; ++ break; ++ ++ case 'A': ++ if (ignore_mode == IGNORE_DEFAULT) ++ ignore_mode = IGNORE_DOT_AND_DOTDOT; ++ break; ++ ++ case 'B': ++ add_ignore_pattern ("*~"); ++ add_ignore_pattern (".*~"); ++ break; ++ ++ case 'C': ++ format = many_per_line; ++ break; ++ ++ case 'D': ++ dired = true; ++ break; ++ ++ case 'F': ++ indicator_style = classify; ++ break; ++ ++ case 'G': /* inhibit display of group info */ ++ print_group = false; ++ break; ++ ++ case 'H': ++ dereference = DEREF_COMMAND_LINE_ARGUMENTS; ++ break; ++ ++ case DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION: ++ dereference = DEREF_COMMAND_LINE_SYMLINK_TO_DIR; ++ break; ++ ++ case 'I': ++ add_ignore_pattern (optarg); ++ break; ++ ++ case 'L': ++ dereference = DEREF_ALWAYS; ++ break; ++ ++ case 'N': ++ set_quoting_style (NULL, literal_quoting_style); ++ break; ++ ++ case 'Q': ++ set_quoting_style (NULL, c_quoting_style); ++ break; ++ ++ case 'R': ++ recursive = true; ++ break; ++ ++ case 'S': ++ sort_type = sort_size; ++ sort_type_specified = true; ++ break; ++ ++ case 'T': ++ { ++ unsigned long int tmp_ulong; ++ if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK ++ || SIZE_MAX < tmp_ulong) ++ error (LS_FAILURE, 0, _("invalid tab size: %s"), ++ quotearg (optarg)); ++ tabsize = tmp_ulong; ++ break; ++ } ++ ++ case 'U': ++ sort_type = sort_none; ++ sort_type_specified = true; ++ break; ++ ++ case 'X': ++ sort_type = sort_extension; ++ sort_type_specified = true; ++ break; ++ ++ case '1': ++ /* -1 has no effect after -l. */ ++ if (format != long_format) ++ format = one_per_line; ++ break; ++ ++ case AUTHOR_OPTION: ++ print_author = true; ++ break; ++ ++ case HIDE_OPTION: ++ { ++ struct ignore_pattern *hide = xmalloc (sizeof *hide); ++ hide->pattern = optarg; ++ hide->next = hide_patterns; ++ hide_patterns = hide; ++ } ++ break; ++ ++ case SORT_OPTION: ++ sort_type = XARGMATCH ("--sort", optarg, sort_args, sort_types); ++ sort_type_specified = true; ++ break; ++ ++ case GROUP_DIRECTORIES_FIRST_OPTION: ++ directories_first = true; ++ break; ++ ++ case TIME_OPTION: ++ time_type = XARGMATCH ("--time", optarg, time_args, time_types); ++ break; ++ ++ case FORMAT_OPTION: ++ format = XARGMATCH ("--format", optarg, format_args, format_types); ++ break; ++ ++ case FULL_TIME_OPTION: ++ format = long_format; ++ time_style_option = bad_cast ("full-iso"); ++ break; ++ ++ case COLOR_OPTION: ++ { ++ int i; ++ if (optarg) ++ i = XARGMATCH ("--color", optarg, color_args, color_types); ++ else ++ /* Using --color with no argument is equivalent to using ++ --color=always. */ ++ i = color_always; ++ ++ print_with_color = (i == color_always ++ || (i == color_if_tty ++ && isatty (STDOUT_FILENO))); ++ ++ if (print_with_color) ++ { ++ /* Don't use TAB characters in output. Some terminal ++ emulators can't handle the combination of tabs and ++ color codes on the same line. */ ++ tabsize = 0; ++ } ++ break; ++ } ++ ++ case INDICATOR_STYLE_OPTION: ++ indicator_style = XARGMATCH ("--indicator-style", optarg, ++ indicator_style_args, ++ indicator_style_types); ++ break; ++ ++ case QUOTING_STYLE_OPTION: ++ set_quoting_style (NULL, ++ XARGMATCH ("--quoting-style", optarg, ++ quoting_style_args, ++ quoting_style_vals)); ++ break; ++ ++ case TIME_STYLE_OPTION: ++ time_style_option = optarg; ++ break; ++ ++ case SHOW_CONTROL_CHARS_OPTION: ++ qmark_funny_chars = false; ++ break; ++ ++ case BLOCK_SIZE_OPTION: ++ { ++ enum strtol_error e = human_options (optarg, &human_output_opts, ++ &output_block_size); ++ if (e != LONGINT_OK) ++ xstrtol_fatal (e, oi, 0, long_options, optarg); ++ file_output_block_size = output_block_size; ++ } ++ break; ++ ++ case SI_OPTION: ++ human_output_opts = human_autoscale | human_SI; ++ file_output_block_size = output_block_size = 1; ++ break; ++ ++ case 'Z': ++ print_scontext = true; ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (LS_FAILURE); ++ } ++ } ++ ++ max_idx = MAX (1, line_length / MIN_COLUMN_WIDTH); ++ ++ filename_quoting_options = clone_quoting_options (NULL); ++ if (get_quoting_style (filename_quoting_options) == escape_quoting_style) ++ set_char_quoting (filename_quoting_options, ' ', 1); ++ if (file_type <= indicator_style) ++ { ++ char const *p; ++ for (p = "*=>@|" + indicator_style - file_type; *p; p++) ++ set_char_quoting (filename_quoting_options, *p, 1); ++ } ++ ++ dirname_quoting_options = clone_quoting_options (NULL); ++ set_char_quoting (dirname_quoting_options, ':', 1); ++ ++ /* --dired is meaningful only with --format=long (-l). ++ Otherwise, ignore it. FIXME: warn about this? ++ Alternatively, make --dired imply --format=long? */ ++ if (dired && format != long_format) ++ dired = false; ++ ++ /* If -c or -u is specified and not -l (or any other option that implies -l), ++ and no sort-type was specified, then sort by the ctime (-c) or atime (-u). ++ The behavior of ls when using either -c or -u but with neither -l nor -t ++ appears to be unspecified by POSIX. So, with GNU ls, `-u' alone means ++ sort by atime (this is the one that's not specified by the POSIX spec), ++ -lu means show atime and sort by name, -lut means show atime and sort ++ by atime. */ ++ ++ if ((time_type == time_ctime || time_type == time_atime) ++ && !sort_type_specified && format != long_format) ++ { ++ sort_type = sort_time; ++ } ++ ++ if (format == long_format) ++ { ++ char *style = time_style_option; ++ static char const posix_prefix[] = "posix-"; ++ ++ if (! style) ++ if (! (style = getenv ("TIME_STYLE"))) ++ style = bad_cast ("locale"); ++ ++ while (strncmp (style, posix_prefix, sizeof posix_prefix - 1) == 0) ++ { ++ if (! hard_locale (LC_TIME)) ++ return optind; ++ style += sizeof posix_prefix - 1; ++ } ++ ++ if (*style == '+') ++ { ++ char *p0 = style + 1; ++ char *p1 = strchr (p0, '\n'); ++ if (! p1) ++ p1 = p0; ++ else ++ { ++ if (strchr (p1 + 1, '\n')) ++ error (LS_FAILURE, 0, _("invalid time style format %s"), ++ quote (p0)); ++ *p1++ = '\0'; ++ } ++ long_time_format[0] = p0; ++ long_time_format[1] = p1; ++ } ++ else ++ switch (XARGMATCH ("time style", style, ++ time_style_args, ++ time_style_types)) ++ { ++ case full_iso_time_style: ++ long_time_format[0] = long_time_format[1] = ++ "%Y-%m-%d %H:%M:%S.%N %z"; ++ break; ++ ++ case long_iso_time_style: ++ case_long_iso_time_style: ++ long_time_format[0] = long_time_format[1] = "%Y-%m-%d %H:%M"; ++ break; ++ ++ case iso_time_style: ++ long_time_format[0] = "%Y-%m-%d "; ++ long_time_format[1] = "%m-%d %H:%M"; ++ break; ++ ++ case locale_time_style: ++ if (hard_locale (LC_TIME)) ++ { ++ /* Ensure that the locale has translations for both ++ formats. If not, fall back on long-iso format. */ ++ int i; ++ for (i = 0; i < 2; i++) ++ { ++ char const *locale_format = ++ dcgettext (NULL, long_time_format[i], LC_TIME); ++ if (locale_format == long_time_format[i]) ++ goto case_long_iso_time_style; ++ long_time_format[i] = locale_format; ++ } ++ } ++ } ++ /* Note we leave %5b etc. alone so user widths/flags are honored. */ ++ if (strstr (long_time_format[0],"%b") || strstr (long_time_format[1],"%b")) ++ if (!abmon_init ()) ++ error (0, 0, _("error initializing month strings")); ++ } ++ ++ return optind; ++} ++ ++/* Parse a string as part of the LS_COLORS variable; this may involve ++ decoding all kinds of escape characters. If equals_end is set an ++ unescaped equal sign ends the string, otherwise only a : or \0 ++ does. Set *OUTPUT_COUNT to the number of bytes output. Return ++ true if successful. ++ ++ The resulting string is *not* null-terminated, but may contain ++ embedded nulls. ++ ++ Note that both dest and src are char **; on return they point to ++ the first free byte after the array and the character that ended ++ the input string, respectively. */ ++ ++static bool ++get_funky_string (char **dest, const char **src, bool equals_end, ++ size_t *output_count) ++{ ++ char num; /* For numerical codes */ ++ size_t count; /* Something to count with */ ++ enum { ++ ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR ++ } state; ++ const char *p; ++ char *q; ++ ++ p = *src; /* We don't want to double-indirect */ ++ q = *dest; /* the whole darn time. */ ++ ++ count = 0; /* No characters counted in yet. */ ++ num = 0; ++ ++ state = ST_GND; /* Start in ground state. */ ++ while (state < ST_END) ++ { ++ switch (state) ++ { ++ case ST_GND: /* Ground state (no escapes) */ ++ switch (*p) ++ { ++ case ':': ++ case '\0': ++ state = ST_END; /* End of string */ ++ break; ++ case '\\': ++ state = ST_BACKSLASH; /* Backslash scape sequence */ ++ ++p; ++ break; ++ case '^': ++ state = ST_CARET; /* Caret escape */ ++ ++p; ++ break; ++ case '=': ++ if (equals_end) ++ { ++ state = ST_END; /* End */ ++ break; ++ } ++ /* else fall through */ ++ default: ++ *(q++) = *(p++); ++ ++count; ++ break; ++ } ++ break; ++ ++ case ST_BACKSLASH: /* Backslash escaped character */ ++ switch (*p) ++ { ++ case '0': ++ case '1': ++ case '2': ++ case '3': ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ state = ST_OCTAL; /* Octal sequence */ ++ num = *p - '0'; ++ break; ++ case 'x': ++ case 'X': ++ state = ST_HEX; /* Hex sequence */ ++ num = 0; ++ break; ++ case 'a': /* Bell */ ++ num = '\a'; ++ break; ++ case 'b': /* Backspace */ ++ num = '\b'; ++ break; ++ case 'e': /* Escape */ ++ num = 27; ++ break; ++ case 'f': /* Form feed */ ++ num = '\f'; ++ break; ++ case 'n': /* Newline */ ++ num = '\n'; ++ break; ++ case 'r': /* Carriage return */ ++ num = '\r'; ++ break; ++ case 't': /* Tab */ ++ num = '\t'; ++ break; ++ case 'v': /* Vtab */ ++ num = '\v'; ++ break; ++ case '?': /* Delete */ ++ num = 127; ++ break; ++ case '_': /* Space */ ++ num = ' '; ++ break; ++ case '\0': /* End of string */ ++ state = ST_ERROR; /* Error! */ ++ break; ++ default: /* Escaped character like \ ^ : = */ ++ num = *p; ++ break; ++ } ++ if (state == ST_BACKSLASH) ++ { ++ *(q++) = num; ++ ++count; ++ state = ST_GND; ++ } ++ ++p; ++ break; ++ ++ case ST_OCTAL: /* Octal sequence */ ++ if (*p < '0' || *p > '7') ++ { ++ *(q++) = num; ++ ++count; ++ state = ST_GND; ++ } ++ else ++ num = (num << 3) + (*(p++) - '0'); ++ break; ++ ++ case ST_HEX: /* Hex sequence */ ++ switch (*p) ++ { ++ case '0': ++ case '1': ++ case '2': ++ case '3': ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ case '8': ++ case '9': ++ num = (num << 4) + (*(p++) - '0'); ++ break; ++ case 'a': ++ case 'b': ++ case 'c': ++ case 'd': ++ case 'e': ++ case 'f': ++ num = (num << 4) + (*(p++) - 'a') + 10; ++ break; ++ case 'A': ++ case 'B': ++ case 'C': ++ case 'D': ++ case 'E': ++ case 'F': ++ num = (num << 4) + (*(p++) - 'A') + 10; ++ break; ++ default: ++ *(q++) = num; ++ ++count; ++ state = ST_GND; ++ break; ++ } ++ break; ++ ++ case ST_CARET: /* Caret escape */ ++ state = ST_GND; /* Should be the next state... */ ++ if (*p >= '@' && *p <= '~') ++ { ++ *(q++) = *(p++) & 037; ++ ++count; ++ } ++ else if (*p == '?') ++ { ++ *(q++) = 127; ++ ++count; ++ } ++ else ++ state = ST_ERROR; ++ break; ++ ++ default: ++ abort (); ++ } ++ } ++ ++ *dest = q; ++ *src = p; ++ *output_count = count; ++ ++ return state != ST_ERROR; ++} ++ ++static void ++parse_ls_color (void) ++{ ++ const char *p; /* Pointer to character being parsed */ ++ char *buf; /* color_buf buffer pointer */ ++ int state; /* State of parser */ ++ int ind_no; /* Indicator number */ ++ char label[3]; /* Indicator label */ ++ struct color_ext_type *ext; /* Extension we are working on */ ++ ++ if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0') ++ return; ++ ++ ext = NULL; ++ strcpy (label, "??"); ++ ++ /* This is an overly conservative estimate, but any possible ++ LS_COLORS string will *not* generate a color_buf longer than ++ itself, so it is a safe way of allocating a buffer in ++ advance. */ ++ buf = color_buf = xstrdup (p); ++ ++ state = 1; ++ while (state > 0) ++ { ++ switch (state) ++ { ++ case 1: /* First label character */ ++ switch (*p) ++ { ++ case ':': ++ ++p; ++ break; ++ ++ case '*': ++ /* Allocate new extension block and add to head of ++ linked list (this way a later definition will ++ override an earlier one, which can be useful for ++ having terminal-specific defs override global). */ ++ ++ ext = xmalloc (sizeof *ext); ++ ext->next = color_ext_list; ++ color_ext_list = ext; ++ ++ ++p; ++ ext->ext.string = buf; ++ ++ state = (get_funky_string (&buf, &p, true, &ext->ext.len) ++ ? 4 : -1); ++ break; ++ ++ case '\0': ++ state = 0; /* Done! */ ++ break; ++ ++ default: /* Assume it is file type label */ ++ label[0] = *(p++); ++ state = 2; ++ break; ++ } ++ break; ++ ++ case 2: /* Second label character */ ++ if (*p) ++ { ++ label[1] = *(p++); ++ state = 3; ++ } ++ else ++ state = -1; /* Error */ ++ break; ++ ++ case 3: /* Equal sign after indicator label */ ++ state = -1; /* Assume failure... */ ++ if (*(p++) == '=')/* It *should* be... */ ++ { ++ for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) ++ { ++ if (STREQ (label, indicator_name[ind_no])) ++ { ++ color_indicator[ind_no].string = buf; ++ state = (get_funky_string (&buf, &p, false, ++ &color_indicator[ind_no].len) ++ ? 1 : -1); ++ break; ++ } ++ } ++ if (state == -1) ++ error (0, 0, _("unrecognized prefix: %s"), quotearg (label)); ++ } ++ break; ++ ++ case 4: /* Equal sign after *.ext */ ++ if (*(p++) == '=') ++ { ++ ext->seq.string = buf; ++ state = (get_funky_string (&buf, &p, false, &ext->seq.len) ++ ? 1 : -1); ++ } ++ else ++ state = -1; ++ break; ++ } ++ } ++ ++ if (state < 0) ++ { ++ struct color_ext_type *e; ++ struct color_ext_type *e2; ++ ++ error (0, 0, ++ _("unparsable value for LS_COLORS environment variable")); ++ free (color_buf); ++ for (e = color_ext_list; e != NULL; /* empty */) ++ { ++ e2 = e; ++ e = e->next; ++ free (e2); ++ } ++ print_with_color = false; ++ } ++ ++ if (color_indicator[C_LINK].len == 6 ++ && !strncmp (color_indicator[C_LINK].string, "target", 6)) ++ color_symlink_as_referent = true; ++} ++ ++/* Set the exit status to report a failure. If SERIOUS, it is a ++ serious failure; otherwise, it is merely a minor problem. */ ++ ++static void ++set_exit_status (bool serious) ++{ ++ if (serious) ++ exit_status = LS_FAILURE; ++ else if (exit_status == EXIT_SUCCESS) ++ exit_status = LS_MINOR_PROBLEM; ++} ++ ++/* Assuming a failure is serious if SERIOUS, use the printf-style ++ MESSAGE to report the failure to access a file named FILE. Assume ++ errno is set appropriately for the failure. */ ++ ++static void ++file_failure (bool serious, char const *message, char const *file) ++{ ++ error (0, errno, message, quotearg_colon (file)); ++ set_exit_status (serious); ++} ++ ++/* Request that the directory named NAME have its contents listed later. ++ If REALNAME is nonzero, it will be used instead of NAME when the ++ directory name is printed. This allows symbolic links to directories ++ to be treated as regular directories but still be listed under their ++ real names. NAME == NULL is used to insert a marker entry for the ++ directory named in REALNAME. ++ If NAME is non-NULL, we use its dev/ino information to save ++ a call to stat -- when doing a recursive (-R) traversal. ++ COMMAND_LINE_ARG means this directory was mentioned on the command line. */ ++ ++static void ++queue_directory (char const *name, char const *realname, bool command_line_arg) ++{ ++ struct pending *new = xmalloc (sizeof *new); ++ new->realname = realname ? xstrdup (realname) : NULL; ++ new->name = name ? xstrdup (name) : NULL; ++ new->command_line_arg = command_line_arg; ++ new->next = pending_dirs; ++ pending_dirs = new; ++} ++ ++/* Read directory NAME, and list the files in it. ++ If REALNAME is nonzero, print its name instead of NAME; ++ this is used for symbolic links to directories. ++ COMMAND_LINE_ARG means this directory was mentioned on the command line. */ ++ ++static void ++print_dir (char const *name, char const *realname, bool command_line_arg) ++{ ++ DIR *dirp; ++ struct dirent *next; ++ uintmax_t total_blocks = 0; ++ static bool first = true; ++ ++ errno = 0; ++ dirp = opendir (name); ++ if (!dirp) ++ { ++ file_failure (command_line_arg, _("cannot open directory %s"), name); ++ return; ++ } ++ ++ if (LOOP_DETECT) ++ { ++ struct stat dir_stat; ++ int fd = dirfd (dirp); ++ ++ /* If dirfd failed, endure the overhead of using stat. */ ++ if ((0 <= fd ++ ? fstat (fd, &dir_stat) ++ : stat (name, &dir_stat)) < 0) ++ { ++ file_failure (command_line_arg, ++ _("cannot determine device and inode of %s"), name); ++ closedir (dirp); ++ return; ++ } ++ ++ /* If we've already visited this dev/inode pair, warn that ++ we've found a loop, and do not process this directory. */ ++ if (visit_dir (dir_stat.st_dev, dir_stat.st_ino)) ++ { ++ error (0, 0, _("%s: not listing already-listed directory"), ++ quotearg_colon (name)); ++ closedir (dirp); ++ set_exit_status (true); ++ return; ++ } ++ ++ DEV_INO_PUSH (dir_stat.st_dev, dir_stat.st_ino); ++ } ++ ++ if (recursive || print_dir_name) ++ { ++ if (!first) ++ DIRED_PUTCHAR ('\n'); ++ first = false; ++ DIRED_INDENT (); ++ PUSH_CURRENT_DIRED_POS (&subdired_obstack); ++ dired_pos += quote_name (stdout, realname ? realname : name, ++ dirname_quoting_options, NULL); ++ PUSH_CURRENT_DIRED_POS (&subdired_obstack); ++ DIRED_FPUTS_LITERAL (":\n", stdout); ++ } ++ ++ /* Read the directory entries, and insert the subfiles into the `cwd_file' ++ table. */ ++ ++ clear_files (); ++ ++ while (1) ++ { ++ /* Set errno to zero so we can distinguish between a readdir failure ++ and when readdir simply finds that there are no more entries. */ ++ errno = 0; ++ next = readdir (dirp); ++ if (next) ++ { ++ if (! file_ignored (next->d_name)) ++ { ++ enum filetype type = unknown; ++ ++#if HAVE_STRUCT_DIRENT_D_TYPE ++ switch (next->d_type) ++ { ++ case DT_BLK: type = blockdev; break; ++ case DT_CHR: type = chardev; break; ++ case DT_DIR: type = directory; break; ++ case DT_FIFO: type = fifo; break; ++ case DT_LNK: type = symbolic_link; break; ++ case DT_REG: type = normal; break; ++ case DT_SOCK: type = sock; break; ++# ifdef DT_WHT ++ case DT_WHT: type = whiteout; break; ++# endif ++ } ++#endif ++ total_blocks += gobble_file (next->d_name, type, ++ RELIABLE_D_INO (next), ++ false, name); ++ ++ /* In this narrow case, print out each name right away, so ++ ls uses constant memory while processing the entries of ++ this directory. Useful when there are many (millions) ++ of entries in a directory. */ ++ if (format == one_per_line && sort_type == sort_none ++ && !print_block_size && !recursive) ++ { ++ /* We must call sort_files in spite of ++ "sort_type == sort_none" for its initialization ++ of the sorted_file vector. */ ++ sort_files (); ++ print_current_files (); ++ clear_files (); ++ } ++ } ++ } ++ else if (errno != 0) ++ { ++ file_failure (command_line_arg, _("reading directory %s"), name); ++ if (errno != EOVERFLOW) ++ break; ++ } ++ else ++ break; ++ } ++ ++ if (closedir (dirp) != 0) ++ { ++ file_failure (command_line_arg, _("closing directory %s"), name); ++ /* Don't return; print whatever we got. */ ++ } ++ ++ /* Sort the directory contents. */ ++ sort_files (); ++ ++ /* If any member files are subdirectories, perhaps they should have their ++ contents listed rather than being mentioned here as files. */ ++ ++ if (recursive) ++ extract_dirs_from_files (name, command_line_arg); ++ ++ if (format == long_format || print_block_size) ++ { ++ const char *p; ++ char buf[LONGEST_HUMAN_READABLE + 1]; ++ ++ DIRED_INDENT (); ++ p = _("total"); ++ DIRED_FPUTS (p, stdout, strlen (p)); ++ DIRED_PUTCHAR (' '); ++ p = human_readable (total_blocks, buf, human_output_opts, ++ ST_NBLOCKSIZE, output_block_size); ++ DIRED_FPUTS (p, stdout, strlen (p)); ++ DIRED_PUTCHAR ('\n'); ++ } ++ ++ if (cwd_n_used) ++ print_current_files (); ++} ++ ++/* Add `pattern' to the list of patterns for which files that match are ++ not listed. */ ++ ++static void ++add_ignore_pattern (const char *pattern) ++{ ++ struct ignore_pattern *ignore; ++ ++ ignore = xmalloc (sizeof *ignore); ++ ignore->pattern = pattern; ++ /* Add it to the head of the linked list. */ ++ ignore->next = ignore_patterns; ++ ignore_patterns = ignore; ++} ++ ++/* Return true if one of the PATTERNS matches FILE. */ ++ ++static bool ++patterns_match (struct ignore_pattern const *patterns, char const *file) ++{ ++ struct ignore_pattern const *p; ++ for (p = patterns; p; p = p->next) ++ if (fnmatch (p->pattern, file, FNM_PERIOD) == 0) ++ return true; ++ return false; ++} ++ ++/* Return true if FILE should be ignored. */ ++ ++static bool ++file_ignored (char const *name) ++{ ++ return ((ignore_mode != IGNORE_MINIMAL ++ && name[0] == '.' ++ && (ignore_mode == IGNORE_DEFAULT || ! name[1 + (name[1] == '.')])) ++ || (ignore_mode == IGNORE_DEFAULT ++ && patterns_match (hide_patterns, name)) ++ || patterns_match (ignore_patterns, name)); ++} ++ ++/* POSIX requires that a file size be printed without a sign, even ++ when negative. Assume the typical case where negative sizes are ++ actually positive values that have wrapped around. */ ++ ++static uintmax_t ++unsigned_file_size (off_t size) ++{ ++ return size + (size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1); ++} ++ ++/* Enter and remove entries in the table `cwd_file'. */ ++ ++/* Empty the table of files. */ ++ ++static void ++clear_files (void) ++{ ++ size_t i; ++ ++ for (i = 0; i < cwd_n_used; i++) ++ { ++ struct fileinfo *f = sorted_file[i]; ++ free (f->name); ++ free (f->linkname); ++ if (f->scontext != UNKNOWN_SECURITY_CONTEXT) ++ freecon (f->scontext); ++ } ++ ++ cwd_n_used = 0; ++ any_has_acl = false; ++ inode_number_width = 0; ++ block_size_width = 0; ++ nlink_width = 0; ++ owner_width = 0; ++ group_width = 0; ++ author_width = 0; ++ scontext_width = 0; ++ major_device_number_width = 0; ++ minor_device_number_width = 0; ++ file_size_width = 0; ++} ++ ++/* Add a file to the current table of files. ++ Verify that the file exists, and print an error message if it does not. ++ Return the number of blocks that the file occupies. */ ++ ++static uintmax_t ++gobble_file (char const *name, enum filetype type, ino_t inode, ++ bool command_line_arg, char const *dirname) ++{ ++ uintmax_t blocks = 0; ++ struct fileinfo *f; ++ ++ /* An inode value prior to gobble_file necessarily came from readdir, ++ which is not used for command line arguments. */ ++ assert (! command_line_arg || inode == NOT_AN_INODE_NUMBER); ++ ++ if (cwd_n_used == cwd_n_alloc) ++ { ++ cwd_file = xnrealloc (cwd_file, cwd_n_alloc, 2 * sizeof *cwd_file); ++ cwd_n_alloc *= 2; ++ } ++ ++ f = &cwd_file[cwd_n_used]; ++ memset (f, '\0', sizeof *f); ++ f->stat.st_ino = inode; ++ f->filetype = type; ++ ++ if (command_line_arg ++ || format_needs_stat ++ /* When coloring a directory (we may know the type from ++ direct.d_type), we have to stat it in order to indicate ++ sticky and/or other-writable attributes. */ ++ || (type == directory && print_with_color) ++ /* When dereferencing symlinks, the inode and type must come from ++ stat, but readdir provides the inode and type of lstat. */ ++ || ((print_inode || format_needs_type) ++ && (type == symbolic_link || type == unknown) ++ && (dereference == DEREF_ALWAYS ++ || (command_line_arg && dereference != DEREF_NEVER) ++ || color_symlink_as_referent || check_symlink_color)) ++ /* Command line dereferences are already taken care of by the above ++ assertion that the inode number is not yet known. */ ++ || (print_inode && inode == NOT_AN_INODE_NUMBER) ++ || (format_needs_type ++ && (type == unknown || command_line_arg ++ /* --indicator-style=classify (aka -F) ++ requires that we stat each regular file ++ to see if it's executable. */ ++ || (type == normal && (indicator_style == classify ++ /* This is so that --color ends up ++ highlighting files with the executable ++ bit set even when options like -F are ++ not specified. */ ++ || (print_with_color ++ && is_colored (C_EXEC)) ++ ))))) ++ ++ { ++ /* Absolute name of this file. */ ++ char *absolute_name; ++ bool do_deref; ++ int err; ++ ++ if (name[0] == '/' || dirname[0] == 0) ++ absolute_name = (char *) name; ++ else ++ { ++ absolute_name = alloca (strlen (name) + strlen (dirname) + 2); ++ attach (absolute_name, dirname, name); ++ } ++ ++ switch (dereference) ++ { ++ case DEREF_ALWAYS: ++ err = stat (absolute_name, &f->stat); ++ do_deref = true; ++ break; ++ ++ case DEREF_COMMAND_LINE_ARGUMENTS: ++ case DEREF_COMMAND_LINE_SYMLINK_TO_DIR: ++ if (command_line_arg) ++ { ++ bool need_lstat; ++ err = stat (absolute_name, &f->stat); ++ do_deref = true; ++ ++ if (dereference == DEREF_COMMAND_LINE_ARGUMENTS) ++ break; ++ ++ need_lstat = (err < 0 ++ ? errno == ENOENT ++ : ! S_ISDIR (f->stat.st_mode)); ++ if (!need_lstat) ++ break; ++ ++ /* stat failed because of ENOENT, maybe indicating a dangling ++ symlink. Or stat succeeded, ABSOLUTE_NAME does not refer to a ++ directory, and --dereference-command-line-symlink-to-dir is ++ in effect. Fall through so that we call lstat instead. */ ++ } ++ ++ default: /* DEREF_NEVER */ ++ err = lstat (absolute_name, &f->stat); ++ do_deref = false; ++ break; ++ } ++ ++ if (err != 0) ++ { ++ /* Failure to stat a command line argument leads to ++ an exit status of 2. For other files, stat failure ++ provokes an exit status of 1. */ ++ file_failure (command_line_arg, ++ _("cannot access %s"), absolute_name); ++ if (command_line_arg) ++ return 0; ++ ++ f->name = xstrdup (name); ++ cwd_n_used++; ++ ++ return 0; ++ } ++ ++ f->stat_ok = true; ++ ++ if (format == long_format || print_scontext) ++ { ++ bool have_selinux = false; ++ bool have_acl = false; ++ int attr_len = (do_deref ++ ? getfilecon (absolute_name, &f->scontext) ++ : lgetfilecon (absolute_name, &f->scontext)); ++ err = (attr_len < 0); ++ ++ /* Contrary to its documented API, getfilecon may return 0, ++ yet set f->scontext to NULL (on at least Debian's libselinux1 ++ 2.0.15-2+b1), so work around that bug. ++ FIXME: remove this work-around in 2011, or whenever affected ++ versions of libselinux are long gone. */ ++ if (attr_len == 0) ++ { ++ err = 0; ++ f->scontext = xstrdup ("unlabeled"); ++ } ++ ++ if (err == 0) ++ have_selinux = ! STREQ ("unlabeled", f->scontext); ++ else ++ { ++ f->scontext = UNKNOWN_SECURITY_CONTEXT; ++ ++ /* When requesting security context information, don't make ++ ls fail just because the file (even a command line argument) ++ isn't on the right type of file system. I.e., a getfilecon ++ failure isn't in the same class as a stat failure. */ ++ if (errno == ENOTSUP || errno == EOPNOTSUPP || errno == ENODATA) ++ err = 0; ++ } ++ ++ if (err == 0 && format == long_format) ++ { ++ int n = file_has_acl (absolute_name, &f->stat); ++ err = (n < 0); ++ have_acl = (0 < n); ++ } ++ ++ f->acl_type = (!have_selinux && !have_acl ++ ? ACL_T_NONE ++ : (have_selinux && !have_acl ++ ? ACL_T_SELINUX_ONLY ++ : ACL_T_YES)); ++ any_has_acl |= f->acl_type != ACL_T_NONE; ++ ++ if (err) ++ error (0, errno, "%s", quotearg_colon (absolute_name)); ++ } ++ ++ if (S_ISLNK (f->stat.st_mode) ++ && (format == long_format || check_symlink_color)) ++ { ++ char *linkname; ++ struct stat linkstats; ++ ++ get_link_name (absolute_name, f, command_line_arg); ++ linkname = make_link_name (absolute_name, f->linkname); ++ ++ /* Avoid following symbolic links when possible, ie, when ++ they won't be traced and when no indicator is needed. */ ++ if (linkname ++ && (file_type <= indicator_style || check_symlink_color) ++ && stat (linkname, &linkstats) == 0) ++ { ++ f->linkok = true; ++ ++ /* Symbolic links to directories that are mentioned on the ++ command line are automatically traced if not being ++ listed as files. */ ++ if (!command_line_arg || format == long_format ++ || !S_ISDIR (linkstats.st_mode)) ++ { ++ /* Get the linked-to file's mode for the filetype indicator ++ in long listings. */ ++ f->linkmode = linkstats.st_mode; ++ } ++ } ++ free (linkname); ++ } ++ ++ /* When not distinguishing types of symlinks, pretend we know that ++ it is stat'able, so that it will be colored as a regular symlink, ++ and not as an orphan. */ ++ if (S_ISLNK (f->stat.st_mode) && !check_symlink_color) ++ f->linkok = true; ++ ++ if (S_ISLNK (f->stat.st_mode)) ++ f->filetype = symbolic_link; ++ else if (S_ISDIR (f->stat.st_mode)) ++ { ++ if (command_line_arg && !immediate_dirs) ++ f->filetype = arg_directory; ++ else ++ f->filetype = directory; ++ } ++ else ++ f->filetype = normal; ++ ++ blocks = ST_NBLOCKS (f->stat); ++ if (format == long_format || print_block_size) ++ { ++ char buf[LONGEST_HUMAN_READABLE + 1]; ++ int len = mbswidth (human_readable (blocks, buf, human_output_opts, ++ ST_NBLOCKSIZE, output_block_size), ++ 0); ++ if (block_size_width < len) ++ block_size_width = len; ++ } ++ ++ if (format == long_format) ++ { ++ if (print_owner) ++ { ++ int len = format_user_width (f->stat.st_uid); ++ if (owner_width < len) ++ owner_width = len; ++ } ++ ++ if (print_group) ++ { ++ int len = format_group_width (f->stat.st_gid); ++ if (group_width < len) ++ group_width = len; ++ } ++ ++ if (print_author) ++ { ++ int len = format_user_width (f->stat.st_author); ++ if (author_width < len) ++ author_width = len; ++ } ++ } ++ ++ if (print_scontext) ++ { ++ int len = strlen (f->scontext); ++ if (scontext_width < len) ++ scontext_width = len; ++ } ++ ++ if (format == long_format) ++ { ++ char b[INT_BUFSIZE_BOUND (uintmax_t)]; ++ int b_len = strlen (umaxtostr (f->stat.st_nlink, b)); ++ if (nlink_width < b_len) ++ nlink_width = b_len; ++ ++ if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode)) ++ { ++ char buf[INT_BUFSIZE_BOUND (uintmax_t)]; ++ int len = strlen (umaxtostr (major (f->stat.st_rdev), buf)); ++ if (major_device_number_width < len) ++ major_device_number_width = len; ++ len = strlen (umaxtostr (minor (f->stat.st_rdev), buf)); ++ if (minor_device_number_width < len) ++ minor_device_number_width = len; ++ len = major_device_number_width + 2 + minor_device_number_width; ++ if (file_size_width < len) ++ file_size_width = len; ++ } ++ else ++ { ++ char buf[LONGEST_HUMAN_READABLE + 1]; ++ uintmax_t size = unsigned_file_size (f->stat.st_size); ++ int len = mbswidth (human_readable (size, buf, human_output_opts, ++ 1, file_output_block_size), ++ 0); ++ if (file_size_width < len) ++ file_size_width = len; ++ } ++ } ++ } ++ ++ if (print_inode) ++ { ++ char buf[INT_BUFSIZE_BOUND (uintmax_t)]; ++ int len = strlen (umaxtostr (f->stat.st_ino, buf)); ++ if (inode_number_width < len) ++ inode_number_width = len; ++ } ++ ++ f->name = xstrdup (name); ++ cwd_n_used++; ++ ++ return blocks; ++} ++ ++/* Return true if F refers to a directory. */ ++static bool ++is_directory (const struct fileinfo *f) ++{ ++ return f->filetype == directory || f->filetype == arg_directory; ++} ++ ++/* Put the name of the file that FILENAME is a symbolic link to ++ into the LINKNAME field of `f'. COMMAND_LINE_ARG indicates whether ++ FILENAME is a command-line argument. */ ++ ++static void ++get_link_name (char const *filename, struct fileinfo *f, bool command_line_arg) ++{ ++ f->linkname = areadlink_with_size (filename, f->stat.st_size); ++ if (f->linkname == NULL) ++ file_failure (command_line_arg, _("cannot read symbolic link %s"), ++ filename); ++} ++ ++/* If `linkname' is a relative name and `name' contains one or more ++ leading directories, return `linkname' with those directories ++ prepended; otherwise, return a copy of `linkname'. ++ If `linkname' is zero, return zero. */ ++ ++static char * ++make_link_name (char const *name, char const *linkname) ++{ ++ char *linkbuf; ++ size_t bufsiz; ++ ++ if (!linkname) ++ return NULL; ++ ++ if (*linkname == '/') ++ return xstrdup (linkname); ++ ++ /* The link is to a relative name. Prepend any leading directory ++ in `name' to the link name. */ ++ linkbuf = strrchr (name, '/'); ++ if (linkbuf == 0) ++ return xstrdup (linkname); ++ ++ bufsiz = linkbuf - name + 1; ++ linkbuf = xmalloc (bufsiz + strlen (linkname) + 1); ++ strncpy (linkbuf, name, bufsiz); ++ strcpy (linkbuf + bufsiz, linkname); ++ return linkbuf; ++} ++ ++/* Return true if the last component of NAME is `.' or `..' ++ This is so we don't try to recurse on `././././. ...' */ ++ ++static bool ++basename_is_dot_or_dotdot (const char *name) ++{ ++ char const *base = last_component (name); ++ return dot_or_dotdot (base); ++} ++ ++/* Remove any entries from CWD_FILE that are for directories, ++ and queue them to be listed as directories instead. ++ DIRNAME is the prefix to prepend to each dirname ++ to make it correct relative to ls's working dir; ++ if it is null, no prefix is needed and "." and ".." should not be ignored. ++ If COMMAND_LINE_ARG is true, this directory was mentioned at the top level, ++ This is desirable when processing directories recursively. */ ++ ++static void ++extract_dirs_from_files (char const *dirname, bool command_line_arg) ++{ ++ size_t i; ++ size_t j; ++ bool ignore_dot_and_dot_dot = (dirname != NULL); ++ ++ if (dirname && LOOP_DETECT) ++ { ++ /* Insert a marker entry first. When we dequeue this marker entry, ++ we'll know that DIRNAME has been processed and may be removed ++ from the set of active directories. */ ++ queue_directory (NULL, dirname, false); ++ } ++ ++ /* Queue the directories last one first, because queueing reverses the ++ order. */ ++ for (i = cwd_n_used; i-- != 0; ) ++ { ++ struct fileinfo *f = sorted_file[i]; ++ ++ if (is_directory (f) ++ && (! ignore_dot_and_dot_dot ++ || ! basename_is_dot_or_dotdot (f->name))) ++ { ++ if (!dirname || f->name[0] == '/') ++ queue_directory (f->name, f->linkname, command_line_arg); ++ else ++ { ++ char *name = file_name_concat (dirname, f->name, NULL); ++ queue_directory (name, f->linkname, command_line_arg); ++ free (name); ++ } ++ if (f->filetype == arg_directory) ++ free (f->name); ++ } ++ } ++ ++ /* Now delete the directories from the table, compacting all the remaining ++ entries. */ ++ ++ for (i = 0, j = 0; i < cwd_n_used; i++) ++ { ++ struct fileinfo *f = sorted_file[i]; ++ sorted_file[j] = f; ++ j += (f->filetype != arg_directory); ++ } ++ cwd_n_used = j; ++} ++ ++/* Use strcoll to compare strings in this locale. If an error occurs, ++ report an error and longjmp to failed_strcoll. */ ++ ++static jmp_buf failed_strcoll; ++ ++static int ++xstrcoll (char const *a, char const *b) ++{ ++ int diff; ++ errno = 0; ++ diff = strcoll (a, b); ++ if (errno) ++ { ++ error (0, errno, _("cannot compare file names %s and %s"), ++ quote_n (0, a), quote_n (1, b)); ++ set_exit_status (false); ++ longjmp (failed_strcoll, 1); ++ } ++ return diff; ++} ++ ++/* Comparison routines for sorting the files. */ ++ ++typedef void const *V; ++typedef int (*qsortFunc)(V a, V b); ++ ++/* Used below in DEFINE_SORT_FUNCTIONS for _df_ sort function variants. ++ The do { ... } while(0) makes it possible to use the macro more like ++ a statement, without violating C89 rules: */ ++#define DIRFIRST_CHECK(a, b) \ ++ do \ ++ { \ ++ bool a_is_dir = is_directory ((struct fileinfo const *) a); \ ++ bool b_is_dir = is_directory ((struct fileinfo const *) b); \ ++ if (a_is_dir && !b_is_dir) \ ++ return -1; /* a goes before b */ \ ++ if (!a_is_dir && b_is_dir) \ ++ return 1; /* b goes before a */ \ ++ } \ ++ while (0) ++ ++/* Define the 8 different sort function variants required for each sortkey. ++ KEY_NAME is a token describing the sort key, e.g., ctime, atime, size. ++ KEY_CMP_FUNC is a function to compare records based on that key, e.g., ++ ctime_cmp, atime_cmp, size_cmp. Append KEY_NAME to the string, ++ '[rev_][x]str{cmp|coll}[_df]_', to create each function name. */ ++#define DEFINE_SORT_FUNCTIONS(key_name, key_cmp_func) \ ++ /* direct, non-dirfirst versions */ \ ++ static int xstrcoll_##key_name (V a, V b) \ ++ { return key_cmp_func (a, b, xstrcoll); } \ ++ static int strcmp_##key_name (V a, V b) \ ++ { return key_cmp_func (a, b, strcmp); } \ ++ \ ++ /* reverse, non-dirfirst versions */ \ ++ static int rev_xstrcoll_##key_name (V a, V b) \ ++ { return key_cmp_func (b, a, xstrcoll); } \ ++ static int rev_strcmp_##key_name (V a, V b) \ ++ { return key_cmp_func (b, a, strcmp); } \ ++ \ ++ /* direct, dirfirst versions */ \ ++ static int xstrcoll_df_##key_name (V a, V b) \ ++ { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, xstrcoll); } \ ++ static int strcmp_df_##key_name (V a, V b) \ ++ { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, strcmp); } \ ++ \ ++ /* reverse, dirfirst versions */ \ ++ static int rev_xstrcoll_df_##key_name (V a, V b) \ ++ { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, xstrcoll); } \ ++ static int rev_strcmp_df_##key_name (V a, V b) \ ++ { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, strcmp); } ++ ++static inline int ++cmp_ctime (struct fileinfo const *a, struct fileinfo const *b, ++ int (*cmp) (char const *, char const *)) ++{ ++ int diff = timespec_cmp (get_stat_ctime (&b->stat), ++ get_stat_ctime (&a->stat)); ++ return diff ? diff : cmp (a->name, b->name); ++} ++ ++static inline int ++cmp_mtime (struct fileinfo const *a, struct fileinfo const *b, ++ int (*cmp) (char const *, char const *)) ++{ ++ int diff = timespec_cmp (get_stat_mtime (&b->stat), ++ get_stat_mtime (&a->stat)); ++ return diff ? diff : cmp (a->name, b->name); ++} ++ ++static inline int ++cmp_atime (struct fileinfo const *a, struct fileinfo const *b, ++ int (*cmp) (char const *, char const *)) ++{ ++ int diff = timespec_cmp (get_stat_atime (&b->stat), ++ get_stat_atime (&a->stat)); ++ return diff ? diff : cmp (a->name, b->name); ++} ++ ++static inline int ++cmp_size (struct fileinfo const *a, struct fileinfo const *b, ++ int (*cmp) (char const *, char const *)) ++{ ++ int diff = longdiff (b->stat.st_size, a->stat.st_size); ++ return diff ? diff : cmp (a->name, b->name); ++} ++ ++static inline int ++cmp_name (struct fileinfo const *a, struct fileinfo const *b, ++ int (*cmp) (char const *, char const *)) ++{ ++ return cmp (a->name, b->name); ++} ++ ++/* Compare file extensions. Files with no extension are `smallest'. ++ If extensions are the same, compare by filenames instead. */ ++ ++static inline int ++cmp_extension (struct fileinfo const *a, struct fileinfo const *b, ++ int (*cmp) (char const *, char const *)) ++{ ++ char const *base1 = strrchr (a->name, '.'); ++ char const *base2 = strrchr (b->name, '.'); ++ int diff = cmp (base1 ? base1 : "", base2 ? base2 : ""); ++ return diff ? diff : cmp (a->name, b->name); ++} ++ ++DEFINE_SORT_FUNCTIONS (ctime, cmp_ctime) ++DEFINE_SORT_FUNCTIONS (mtime, cmp_mtime) ++DEFINE_SORT_FUNCTIONS (atime, cmp_atime) ++DEFINE_SORT_FUNCTIONS (size, cmp_size) ++DEFINE_SORT_FUNCTIONS (name, cmp_name) ++DEFINE_SORT_FUNCTIONS (extension, cmp_extension) ++ ++/* Compare file versions. ++ Unlike all other compare functions above, cmp_version depends only ++ on filevercmp, which does not fail (even for locale reasons), and does not ++ need a secondary sort key. See lib/filevercmp.h for function description. ++ ++ All the other sort options, in fact, need xstrcoll and strcmp variants, ++ because they all use a string comparison (either as the primary or secondary ++ sort key), and xstrcoll has the ability to do a longjmp if strcoll fails for ++ locale reasons. Last, strverscmp is ALWAYS available in coreutils, ++ thanks to the gnulib library. */ ++static inline int ++cmp_version (struct fileinfo const *a, struct fileinfo const *b) ++{ ++ return filevercmp (a->name, b->name); ++} ++ ++static int xstrcoll_version (V a, V b) ++{ return cmp_version (a, b); } ++static int rev_xstrcoll_version (V a, V b) ++{ return cmp_version (b, a); } ++static int xstrcoll_df_version (V a, V b) ++{ DIRFIRST_CHECK (a, b); return cmp_version (a, b); } ++static int rev_xstrcoll_df_version (V a, V b) ++{ DIRFIRST_CHECK (a, b); return cmp_version (b, a); } ++ ++ ++/* We have 2^3 different variants for each sortkey function ++ (for 3 independent sort modes). ++ The function pointers stored in this array must be dereferenced as: ++ ++ sort_variants[sort_key][use_strcmp][reverse][dirs_first] ++ ++ Note that the order in which sortkeys are listed in the function pointer ++ array below is defined by the order of the elements in the time_type and ++ sort_type enums! */ ++ ++#define LIST_SORTFUNCTION_VARIANTS(key_name) \ ++ { \ ++ { \ ++ { xstrcoll_##key_name, xstrcoll_df_##key_name }, \ ++ { rev_xstrcoll_##key_name, rev_xstrcoll_df_##key_name }, \ ++ }, \ ++ { \ ++ { strcmp_##key_name, strcmp_df_##key_name }, \ ++ { rev_strcmp_##key_name, rev_strcmp_df_##key_name }, \ ++ } \ ++ } ++ ++static qsortFunc const sort_functions[][2][2][2] = ++ { ++ LIST_SORTFUNCTION_VARIANTS (name), ++ LIST_SORTFUNCTION_VARIANTS (extension), ++ LIST_SORTFUNCTION_VARIANTS (size), ++ ++ { ++ { ++ { xstrcoll_version, xstrcoll_df_version }, ++ { rev_xstrcoll_version, rev_xstrcoll_df_version }, ++ }, ++ ++ /* We use NULL for the strcmp variants of version comparison ++ since as explained in cmp_version definition, version comparison ++ does not rely on xstrcoll, so it will never longjmp, and never ++ need to try the strcmp fallback. */ ++ { ++ { NULL, NULL }, ++ { NULL, NULL }, ++ } ++ }, ++ ++ /* last are time sort functions */ ++ LIST_SORTFUNCTION_VARIANTS (mtime), ++ LIST_SORTFUNCTION_VARIANTS (ctime), ++ LIST_SORTFUNCTION_VARIANTS (atime) ++ }; ++ ++/* The number of sortkeys is calculated as ++ the number of elements in the sort_type enum (i.e. sort_numtypes) + ++ the number of elements in the time_type enum (i.e. time_numtypes) - 1 ++ This is because when sort_type==sort_time, we have up to ++ time_numtypes possible sortkeys. ++ ++ This line verifies at compile-time that the array of sort functions has been ++ initialized for all possible sortkeys. */ ++verify (ARRAY_CARDINALITY (sort_functions) ++ == sort_numtypes + time_numtypes - 1 ); ++ ++/* Set up SORTED_FILE to point to the in-use entries in CWD_FILE, in order. */ ++ ++static void ++initialize_ordering_vector (void) ++{ ++ size_t i; ++ for (i = 0; i < cwd_n_used; i++) ++ sorted_file[i] = &cwd_file[i]; ++} ++ ++/* Sort the files now in the table. */ ++ ++static void ++sort_files (void) ++{ ++ bool use_strcmp; ++ ++ if (sorted_file_alloc < cwd_n_used + cwd_n_used / 2) ++ { ++ free (sorted_file); ++ sorted_file = xnmalloc (cwd_n_used, 3 * sizeof *sorted_file); ++ sorted_file_alloc = 3 * cwd_n_used; ++ } ++ ++ initialize_ordering_vector (); ++ ++ if (sort_type == sort_none) ++ return; ++ ++ /* Try strcoll. If it fails, fall back on strcmp. We can't safely ++ ignore strcoll failures, as a failing strcoll might be a ++ comparison function that is not a total order, and if we ignored ++ the failure this might cause qsort to dump core. */ ++ ++ if (! setjmp (failed_strcoll)) ++ use_strcmp = false; /* strcoll() succeeded */ ++ else ++ { ++ use_strcmp = true; ++ assert (sort_type != sort_version); ++ initialize_ordering_vector (); ++ } ++ ++ /* When sort_type == sort_time, use time_type as subindex. */ ++ mpsort ((void const **) sorted_file, cwd_n_used, ++ sort_functions[sort_type + (sort_type == sort_time ? time_type : 0)] ++ [use_strcmp][sort_reverse] ++ [directories_first]); ++} ++ ++/* List all the files now in the table. */ ++ ++static void ++print_current_files (void) ++{ ++ size_t i; ++ ++ switch (format) ++ { ++ case one_per_line: ++ for (i = 0; i < cwd_n_used; i++) ++ { ++ print_file_name_and_frills (sorted_file[i], 0); ++ putchar ('\n'); ++ } ++ break; ++ ++ case many_per_line: ++ print_many_per_line (); ++ break; ++ ++ case horizontal: ++ print_horizontal (); ++ break; ++ ++ case with_commas: ++ print_with_commas (); ++ break; ++ ++ case long_format: ++ for (i = 0; i < cwd_n_used; i++) ++ { ++ print_long_format (sorted_file[i]); ++ DIRED_PUTCHAR ('\n'); ++ } ++ break; ++ } ++} ++ ++/* Replace the first %b with precomputed aligned month names. ++ Note on glibc-2.7 at least, this speeds up the whole `ls -lU` ++ process by around 17%, compared to letting strftime() handle the %b. */ ++ ++static size_t ++align_nstrftime (char *buf, size_t size, char const *fmt, struct tm const *tm, ++ int __utc, int __ns) ++{ ++ const char *nfmt = fmt; ++ /* In the unlikely event that rpl_fmt below is not large enough, ++ the replacement is not done. A malloc here slows ls down by 2% */ ++ char rpl_fmt[sizeof (abmon[0]) + 100]; ++ const char *pb; ++ if (required_mon_width && (pb = strstr (fmt, "%b"))) ++ { ++ if (strlen (fmt) < (sizeof (rpl_fmt) - sizeof (abmon[0]) + 2)) ++ { ++ char *pfmt = rpl_fmt; ++ nfmt = rpl_fmt; ++ ++ pfmt = mempcpy (pfmt, fmt, pb - fmt); ++ pfmt = stpcpy (pfmt, abmon[tm->tm_mon]); ++ strcpy (pfmt, pb + 2); ++ } ++ } ++ size_t ret = nstrftime (buf, size, nfmt, tm, __utc, __ns); ++ return ret; ++} ++ ++/* Return the expected number of columns in a long-format time stamp, ++ or zero if it cannot be calculated. */ ++ ++static int ++long_time_expected_width (void) ++{ ++ static int width = -1; ++ ++ if (width < 0) ++ { ++ time_t epoch = 0; ++ struct tm const *tm = localtime (&epoch); ++ char buf[TIME_STAMP_LEN_MAXIMUM + 1]; ++ ++ /* In case you're wondering if localtime can fail with an input time_t ++ value of 0, let's just say it's very unlikely, but not inconceivable. ++ The TZ environment variable would have to specify a time zone that ++ is 2**31-1900 years or more ahead of UTC. This could happen only on ++ a 64-bit system that blindly accepts e.g., TZ=UTC+20000000000000. ++ However, this is not possible with Solaris 10 or glibc-2.3.5, since ++ their implementations limit the offset to 167:59 and 24:00, resp. */ ++ if (tm) ++ { ++ size_t len = ++ align_nstrftime (buf, sizeof buf, long_time_format[0], tm, 0, 0); ++ if (len != 0) ++ width = mbsnwidth (buf, len, 0); ++ } ++ ++ if (width < 0) ++ width = 0; ++ } ++ ++ return width; ++} ++ ++/* Print the user or group name NAME, with numeric id ID, using a ++ print width of WIDTH columns. */ ++ ++static void ++format_user_or_group (char const *name, unsigned long int id, int width) ++{ ++ size_t len; ++ ++ if (name) ++ { ++ int width_gap = width - mbswidth (name, 0); ++ int pad = MAX (0, width_gap); ++ fputs (name, stdout); ++ len = strlen (name) + pad; ++ ++ do ++ putchar (' '); ++ while (pad--); ++ } ++ else ++ { ++ printf ("%*lu ", width, id); ++ len = width; ++ } ++ ++ dired_pos += len + 1; ++} ++ ++/* Print the name or id of the user with id U, using a print width of ++ WIDTH. */ ++ ++static void ++format_user (uid_t u, int width, bool stat_ok) ++{ ++ format_user_or_group (! stat_ok ? "?" : ++ (numeric_ids ? NULL : getuser (u)), u, width); ++} ++ ++/* Likewise, for groups. */ ++ ++static void ++format_group (gid_t g, int width, bool stat_ok) ++{ ++ format_user_or_group (! stat_ok ? "?" : ++ (numeric_ids ? NULL : getgroup (g)), g, width); ++} ++ ++/* Return the number of columns that format_user_or_group will print. */ ++ ++static int ++format_user_or_group_width (char const *name, unsigned long int id) ++{ ++ if (name) ++ { ++ int len = mbswidth (name, 0); ++ return MAX (0, len); ++ } ++ else ++ { ++ char buf[INT_BUFSIZE_BOUND (unsigned long int)]; ++ sprintf (buf, "%lu", id); ++ return strlen (buf); ++ } ++} ++ ++/* Return the number of columns that format_user will print. */ ++ ++static int ++format_user_width (uid_t u) ++{ ++ return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u); ++} ++ ++/* Likewise, for groups. */ ++ ++static int ++format_group_width (gid_t g) ++{ ++ return format_user_or_group_width (numeric_ids ? NULL : getgroup (g), g); ++} ++ ++/* Return a pointer to a formatted version of F->stat.st_ino, ++ possibly using buffer, BUF, of length BUFLEN, which must be at least ++ INT_BUFSIZE_BOUND (uintmax_t) bytes. */ ++static char * ++format_inode (char *buf, size_t buflen, const struct fileinfo *f) ++{ ++ assert (INT_BUFSIZE_BOUND (uintmax_t) <= buflen); ++ return (f->stat_ok && f->stat.st_ino != NOT_AN_INODE_NUMBER ++ ? umaxtostr (f->stat.st_ino, buf) ++ : (char *) "?"); ++} ++ ++/* Print information about F in long format. */ ++static void ++print_long_format (const struct fileinfo *f) ++{ ++ char modebuf[12]; ++ char buf ++ [LONGEST_HUMAN_READABLE + 1 /* inode */ ++ + LONGEST_HUMAN_READABLE + 1 /* size in blocks */ ++ + sizeof (modebuf) - 1 + 1 /* mode string */ ++ + INT_BUFSIZE_BOUND (uintmax_t) /* st_nlink */ ++ + LONGEST_HUMAN_READABLE + 2 /* major device number */ ++ + LONGEST_HUMAN_READABLE + 1 /* minor device number */ ++ + TIME_STAMP_LEN_MAXIMUM + 1 /* max length of time/date */ ++ ]; ++ size_t s; ++ char *p; ++ struct timespec when_timespec; ++ struct tm *when_local; ++ ++ /* Compute the mode string, except remove the trailing space if no ++ file in this directory has an ACL or SELinux security context. */ ++ if (f->stat_ok) ++ filemodestring (&f->stat, modebuf); ++ else ++ { ++ modebuf[0] = filetype_letter[f->filetype]; ++ memset (modebuf + 1, '?', 10); ++ modebuf[11] = '\0'; ++ } ++ if (! any_has_acl) ++ modebuf[10] = '\0'; ++ else if (f->acl_type == ACL_T_SELINUX_ONLY) ++ modebuf[10] = '.'; ++ else if (f->acl_type == ACL_T_YES) ++ modebuf[10] = '+'; ++ ++ switch (time_type) ++ { ++ case time_ctime: ++ when_timespec = get_stat_ctime (&f->stat); ++ break; ++ case time_mtime: ++ when_timespec = get_stat_mtime (&f->stat); ++ break; ++ case time_atime: ++ when_timespec = get_stat_atime (&f->stat); ++ break; ++ default: ++ abort (); ++ } ++ ++ p = buf; ++ ++ if (print_inode) ++ { ++ char hbuf[INT_BUFSIZE_BOUND (uintmax_t)]; ++ sprintf (p, "%*s ", inode_number_width, ++ format_inode (hbuf, sizeof hbuf, f)); ++ /* Increment by strlen (p) here, rather than by inode_number_width + 1. ++ The latter is wrong when inode_number_width is zero. */ ++ p += strlen (p); ++ } ++ ++ if (print_block_size) ++ { ++ char hbuf[LONGEST_HUMAN_READABLE + 1]; ++ char const *blocks = ++ (! f->stat_ok ++ ? "?" ++ : human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts, ++ ST_NBLOCKSIZE, output_block_size)); ++ int pad; ++ for (pad = block_size_width - mbswidth (blocks, 0); 0 < pad; pad--) ++ *p++ = ' '; ++ while ((*p++ = *blocks++)) ++ continue; ++ p[-1] = ' '; ++ } ++ ++ /* The last byte of the mode string is the POSIX ++ "optional alternate access method flag". */ ++ { ++ char hbuf[INT_BUFSIZE_BOUND (uintmax_t)]; ++ sprintf (p, "%s %*s ", modebuf, nlink_width, ++ ! f->stat_ok ? "?" : umaxtostr (f->stat.st_nlink, hbuf)); ++ } ++ /* Increment by strlen (p) here, rather than by, e.g., ++ sizeof modebuf - 2 + any_has_acl + 1 + nlink_width + 1. ++ The latter is wrong when nlink_width is zero. */ ++ p += strlen (p); ++ ++ DIRED_INDENT (); ++ ++ if (print_owner || print_group || print_author || print_scontext) ++ { ++ DIRED_FPUTS (buf, stdout, p - buf); ++ ++ if (print_owner) ++ format_user (f->stat.st_uid, owner_width, f->stat_ok); ++ ++ if (print_group) ++ format_group (f->stat.st_gid, group_width, f->stat_ok); ++ ++ if (print_author) ++ format_user (f->stat.st_author, author_width, f->stat_ok); ++ ++ if (print_scontext) ++ format_user_or_group (f->scontext, 0, scontext_width); ++ ++ p = buf; ++ } ++ ++ if (f->stat_ok ++ && (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))) ++ { ++ char majorbuf[INT_BUFSIZE_BOUND (uintmax_t)]; ++ char minorbuf[INT_BUFSIZE_BOUND (uintmax_t)]; ++ int blanks_width = (file_size_width ++ - (major_device_number_width + 2 ++ + minor_device_number_width)); ++ sprintf (p, "%*s, %*s ", ++ major_device_number_width + MAX (0, blanks_width), ++ umaxtostr (major (f->stat.st_rdev), majorbuf), ++ minor_device_number_width, ++ umaxtostr (minor (f->stat.st_rdev), minorbuf)); ++ p += file_size_width + 1; ++ } ++ else ++ { ++ char hbuf[LONGEST_HUMAN_READABLE + 1]; ++ char const *size = ++ (! f->stat_ok ++ ? "?" ++ : human_readable (unsigned_file_size (f->stat.st_size), ++ hbuf, human_output_opts, 1, file_output_block_size)); ++ int pad; ++ for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--) ++ *p++ = ' '; ++ while ((*p++ = *size++)) ++ continue; ++ p[-1] = ' '; ++ } ++ ++ when_local = localtime (&when_timespec.tv_sec); ++ s = 0; ++ *p = '\1'; ++ ++ if (f->stat_ok && when_local) ++ { ++ struct timespec six_months_ago; ++ bool recent; ++ char const *fmt; ++ ++ /* If the file appears to be in the future, update the current ++ time, in case the file happens to have been modified since ++ the last time we checked the clock. */ ++ if (timespec_cmp (current_time, when_timespec) < 0) ++ { ++ /* Note that gettime may call gettimeofday which, on some non- ++ compliant systems, clobbers the buffer used for localtime's result. ++ But it's ok here, because we use a gettimeofday wrapper that ++ saves and restores the buffer around the gettimeofday call. */ ++ gettime (¤t_time); ++ } ++ ++ /* Consider a time to be recent if it is within the past six ++ months. A Gregorian year has 365.2425 * 24 * 60 * 60 == ++ 31556952 seconds on the average. Write this value as an ++ integer constant to avoid floating point hassles. */ ++ six_months_ago.tv_sec = current_time.tv_sec - 31556952 / 2; ++ six_months_ago.tv_nsec = current_time.tv_nsec; ++ ++ recent = (timespec_cmp (six_months_ago, when_timespec) < 0 ++ && (timespec_cmp (when_timespec, current_time) < 0)); ++ fmt = long_time_format[recent]; ++ ++ /* We assume here that all time zones are offset from UTC by a ++ whole number of seconds. */ ++ s = align_nstrftime (p, TIME_STAMP_LEN_MAXIMUM + 1, fmt, ++ when_local, 0, when_timespec.tv_nsec); ++ } ++ ++ if (s || !*p) ++ { ++ p += s; ++ *p++ = ' '; ++ ++ /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it. */ ++ *p = '\0'; ++ } ++ else ++ { ++ /* The time cannot be converted using the desired format, so ++ print it as a huge integer number of seconds. */ ++ char hbuf[INT_BUFSIZE_BOUND (intmax_t)]; ++ sprintf (p, "%*s ", long_time_expected_width (), ++ (! f->stat_ok ++ ? "?" ++ : timetostr (when_timespec.tv_sec, hbuf))); ++ /* FIXME: (maybe) We discarded when_timespec.tv_nsec. */ ++ p += strlen (p); ++ } ++ ++ DIRED_FPUTS (buf, stdout, p - buf); ++ size_t w = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, ++ f->stat_ok, f->filetype, &dired_obstack, ++ f->stat.st_nlink, p - buf); ++ ++ if (f->filetype == symbolic_link) ++ { ++ if (f->linkname) ++ { ++ DIRED_FPUTS_LITERAL (" -> ", stdout); ++ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, ++ f->stat_ok, f->filetype, NULL, ++ f->stat.st_nlink, (p - buf) + w + 4); ++ if (indicator_style != none) ++ print_type_indicator (true, f->linkmode, unknown); ++ } ++ } ++ else if (indicator_style != none) ++ print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); ++} ++ ++/* Output to OUT a quoted representation of the file name NAME, ++ using OPTIONS to control quoting. Produce no output if OUT is NULL. ++ Store the number of screen columns occupied by NAME's quoted ++ representation into WIDTH, if non-NULL. Return the number of bytes ++ produced. */ ++ ++static size_t ++quote_name (FILE *out, const char *name, struct quoting_options const *options, ++ size_t *width) ++{ ++ char smallbuf[BUFSIZ]; ++ size_t len = quotearg_buffer (smallbuf, sizeof smallbuf, name, -1, options); ++ char *buf; ++ size_t displayed_width IF_LINT (= 0); ++ ++ if (len < sizeof smallbuf) ++ buf = smallbuf; ++ else ++ { ++ buf = alloca (len + 1); ++ quotearg_buffer (buf, len + 1, name, -1, options); ++ } ++ ++ if (qmark_funny_chars) ++ { ++ if (MB_CUR_MAX > 1) ++ { ++ char const *p = buf; ++ char const *plimit = buf + len; ++ char *q = buf; ++ displayed_width = 0; ++ ++ while (p < plimit) ++ switch (*p) ++ { ++ case ' ': case '!': case '"': case '#': case '%': ++ case '&': case '\'': case '(': case ')': case '*': ++ case '+': case ',': case '-': case '.': case '/': ++ case '0': case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': case '8': case '9': ++ case ':': case ';': case '<': case '=': case '>': ++ case '?': ++ case 'A': case 'B': case 'C': case 'D': case 'E': ++ case 'F': case 'G': case 'H': case 'I': case 'J': ++ case 'K': case 'L': case 'M': case 'N': case 'O': ++ case 'P': case 'Q': case 'R': case 'S': case 'T': ++ case 'U': case 'V': case 'W': case 'X': case 'Y': ++ case 'Z': ++ case '[': case '\\': case ']': case '^': case '_': ++ case 'a': case 'b': case 'c': case 'd': case 'e': ++ case 'f': case 'g': case 'h': case 'i': case 'j': ++ case 'k': case 'l': case 'm': case 'n': case 'o': ++ case 'p': case 'q': case 'r': case 's': case 't': ++ case 'u': case 'v': case 'w': case 'x': case 'y': ++ case 'z': case '{': case '|': case '}': case '~': ++ /* These characters are printable ASCII characters. */ ++ *q++ = *p++; ++ displayed_width += 1; ++ break; ++ default: ++ /* If we have a multibyte sequence, copy it until we ++ reach its end, replacing each non-printable multibyte ++ character with a single question mark. */ ++ { ++ DECLARE_ZEROED_AGGREGATE (mbstate_t, mbstate); ++ do ++ { ++ wchar_t wc; ++ size_t bytes; ++ int w; ++ ++ bytes = mbrtowc (&wc, p, plimit - p, &mbstate); ++ ++ if (bytes == (size_t) -1) ++ { ++ /* An invalid multibyte sequence was ++ encountered. Skip one input byte, and ++ put a question mark. */ ++ p++; ++ *q++ = '?'; ++ displayed_width += 1; ++ break; ++ } ++ ++ if (bytes == (size_t) -2) ++ { ++ /* An incomplete multibyte character ++ at the end. Replace it entirely with ++ a question mark. */ ++ p = plimit; ++ *q++ = '?'; ++ displayed_width += 1; ++ break; ++ } ++ ++ if (bytes == 0) ++ /* A null wide character was encountered. */ ++ bytes = 1; ++ ++ w = wcwidth (wc); ++ if (w >= 0) ++ { ++ /* A printable multibyte character. ++ Keep it. */ ++ for (; bytes > 0; --bytes) ++ *q++ = *p++; ++ displayed_width += w; ++ } ++ else ++ { ++ /* An unprintable multibyte character. ++ Replace it entirely with a question ++ mark. */ ++ p += bytes; ++ *q++ = '?'; ++ displayed_width += 1; ++ } ++ } ++ while (! mbsinit (&mbstate)); ++ } ++ break; ++ } ++ ++ /* The buffer may have shrunk. */ ++ len = q - buf; ++ } ++ else ++ { ++ char *p = buf; ++ char const *plimit = buf + len; ++ ++ while (p < plimit) ++ { ++ if (! isprint (to_uchar (*p))) ++ *p = '?'; ++ p++; ++ } ++ displayed_width = len; ++ } ++ } ++ else if (width != NULL) ++ { ++ if (MB_CUR_MAX > 1) ++ displayed_width = mbsnwidth (buf, len, 0); ++ else ++ { ++ char const *p = buf; ++ char const *plimit = buf + len; ++ ++ displayed_width = 0; ++ while (p < plimit) ++ { ++ if (isprint (to_uchar (*p))) ++ displayed_width++; ++ p++; ++ } ++ } ++ } ++ ++ if (out != NULL) ++ fwrite (buf, 1, len, out); ++ if (width != NULL) ++ *width = displayed_width; ++ return len; ++} ++ ++static size_t ++print_name_with_quoting (const char *p, mode_t mode, int linkok, ++ bool stat_ok, enum filetype type, ++ struct obstack *stack, nlink_t nlink, ++ size_t start_col) ++{ ++ bool used_color_this_time ++ = (print_with_color ++ && print_color_indicator (p, mode, linkok, stat_ok, type, nlink)); ++ ++ if (stack) ++ PUSH_CURRENT_DIRED_POS (stack); ++ ++ size_t width = quote_name (stdout, p, filename_quoting_options, NULL); ++ dired_pos += width; ++ ++ if (stack) ++ PUSH_CURRENT_DIRED_POS (stack); ++ ++ if (used_color_this_time) ++ { ++ process_signals (); ++ prep_non_filename_text (); ++ if (start_col / line_length != (start_col + width - 1) / line_length) ++ put_indicator (&color_indicator[C_CLR_TO_EOL]); ++ } ++ ++ return width; ++} ++ ++static void ++prep_non_filename_text (void) ++{ ++ if (color_indicator[C_END].string != NULL) ++ put_indicator (&color_indicator[C_END]); ++ else ++ { ++ put_indicator (&color_indicator[C_LEFT]); ++ put_indicator (&color_indicator[C_RESET]); ++ put_indicator (&color_indicator[C_RIGHT]); ++ } ++} ++ ++/* Print the file name of `f' with appropriate quoting. ++ Also print file size, inode number, and filetype indicator character, ++ as requested by switches. */ ++ ++static size_t ++print_file_name_and_frills (const struct fileinfo *f, size_t start_col) ++{ ++ char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))]; ++ ++ if (print_inode) ++ printf ("%*s ", format == with_commas ? 0 : inode_number_width, ++ format_inode (buf, sizeof buf, f)); ++ ++ if (print_block_size) ++ printf ("%*s ", format == with_commas ? 0 : block_size_width, ++ ! f->stat_ok ? "?" ++ : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ++ ST_NBLOCKSIZE, output_block_size)); ++ ++ if (print_scontext) ++ printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext); ++ ++ size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), ++ f->linkok, f->stat_ok, f->filetype, ++ NULL, f->stat.st_nlink, start_col); ++ ++ if (indicator_style != none) ++ width += print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); ++ ++ return width; ++} ++ ++/* Given these arguments describing a file, return the single-byte ++ type indicator, or 0. */ ++static char ++get_type_indicator (bool stat_ok, mode_t mode, enum filetype type) ++{ ++ char c; ++ ++ if (stat_ok ? S_ISREG (mode) : type == normal) ++ { ++ if (stat_ok && indicator_style == classify && (mode & S_IXUGO)) ++ c = '*'; ++ else ++ c = 0; ++ } ++ else ++ { ++ if (stat_ok ? S_ISDIR (mode) : type == directory || type == arg_directory) ++ c = '/'; ++ else if (indicator_style == slash) ++ c = 0; ++ else if (stat_ok ? S_ISLNK (mode) : type == symbolic_link) ++ c = '@'; ++ else if (stat_ok ? S_ISFIFO (mode) : type == fifo) ++ c = '|'; ++ else if (stat_ok ? S_ISSOCK (mode) : type == sock) ++ c = '='; ++ else if (stat_ok && S_ISDOOR (mode)) ++ c = '>'; ++ else ++ c = 0; ++ } ++ return c; ++} ++ ++static bool ++print_type_indicator (bool stat_ok, mode_t mode, enum filetype type) ++{ ++ char c = get_type_indicator (stat_ok, mode, type); ++ if (c) ++ DIRED_PUTCHAR (c); ++ return !!c; ++} ++ ++#ifdef HAVE_CAP ++/* Return true if NAME has a capability (see linux/capability.h) */ ++static bool ++has_capability (char const *name) ++{ ++ char *result; ++ bool has_cap; ++ ++ cap_t cap_d = cap_get_file (name); ++ if (cap_d == NULL) ++ return false; ++ ++ result = cap_to_text (cap_d, NULL); ++ cap_free (cap_d); ++ if (!result) ++ return false; ++ ++ /* check if human-readable capability string is empty */ ++ has_cap = !!*result; ++ ++ cap_free (result); ++ return has_cap; ++} ++#else ++static bool ++has_capability (char const *name ATTRIBUTE_UNUSED) ++{ ++ return false; ++} ++#endif ++ ++/* Returns whether any color sequence was printed. */ ++static bool ++print_color_indicator (const char *name, mode_t mode, int linkok, ++ bool stat_ok, enum filetype filetype, ++ nlink_t nlink) ++{ ++ enum indicator_no type; ++ struct color_ext_type *ext; /* Color extension */ ++ size_t len; /* Length of name */ ++ ++ /* Is this a nonexistent file? If so, linkok == -1. */ ++ ++ if (linkok == -1 && color_indicator[C_MISSING].string != NULL) ++ type = C_MISSING; ++ else if (! stat_ok) ++ { ++ static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS; ++ type = filetype_indicator[filetype]; ++ } ++ else ++ { ++ if (S_ISREG (mode)) ++ { ++ type = C_FILE; ++ ++ if ((mode & S_ISUID) != 0 && is_colored (C_SETUID)) ++ type = C_SETUID; ++ else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID)) ++ type = C_SETGID; ++ /* has_capability() called second for performance. */ ++ else if (is_colored (C_CAP) && has_capability (name)) ++ type = C_CAP; ++ else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC)) ++ type = C_EXEC; ++ else if ((1 < nlink) && is_colored (C_MULTIHARDLINK)) ++ type = C_MULTIHARDLINK; ++ } ++ else if (S_ISDIR (mode)) ++ { ++ type = C_DIR; ++ ++ if ((mode & S_ISVTX) && (mode & S_IWOTH) ++ && is_colored (C_STICKY_OTHER_WRITABLE)) ++ type = C_STICKY_OTHER_WRITABLE; ++ else if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE)) ++ type = C_OTHER_WRITABLE; ++ else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY)) ++ type = C_STICKY; ++ } ++ else if (S_ISLNK (mode)) ++ type = ((!linkok && color_indicator[C_ORPHAN].string) ++ ? C_ORPHAN : C_LINK); ++ else if (S_ISFIFO (mode)) ++ type = C_FIFO; ++ else if (S_ISSOCK (mode)) ++ type = C_SOCK; ++ else if (S_ISBLK (mode)) ++ type = C_BLK; ++ else if (S_ISCHR (mode)) ++ type = C_CHR; ++ else if (S_ISDOOR (mode)) ++ type = C_DOOR; ++ else ++ { ++ /* Classify a file of some other type as C_ORPHAN. */ ++ type = C_ORPHAN; ++ } ++ } ++ ++ /* Check the file's suffix only if still classified as C_FILE. */ ++ ext = NULL; ++ if (type == C_FILE) ++ { ++ /* Test if NAME has a recognized suffix. */ ++ ++ len = strlen (name); ++ name += len; /* Pointer to final \0. */ ++ for (ext = color_ext_list; ext != NULL; ext = ext->next) ++ { ++ if (ext->ext.len <= len ++ && strncmp (name - ext->ext.len, ext->ext.string, ++ ext->ext.len) == 0) ++ break; ++ } ++ } ++ ++ { ++ const struct bin_str *const s ++ = ext ? &(ext->seq) : &color_indicator[type]; ++ if (s->string != NULL) ++ { ++ put_indicator (&color_indicator[C_LEFT]); ++ put_indicator (s); ++ put_indicator (&color_indicator[C_RIGHT]); ++ return true; ++ } ++ else ++ return false; ++ } ++} ++ ++/* Output a color indicator (which may contain nulls). */ ++static void ++put_indicator (const struct bin_str *ind) ++{ ++ if (! used_color) ++ { ++ used_color = true; ++ prep_non_filename_text (); ++ } ++ ++ fwrite (ind->string, ind->len, 1, stdout); ++} ++ ++static size_t ++length_of_file_name_and_frills (const struct fileinfo *f) ++{ ++ size_t len = 0; ++ size_t name_width; ++ char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))]; ++ ++ if (print_inode) ++ len += 1 + (format == with_commas ++ ? strlen (umaxtostr (f->stat.st_ino, buf)) ++ : inode_number_width); ++ ++ if (print_block_size) ++ len += 1 + (format == with_commas ++ ? strlen (! f->stat_ok ? "?" ++ : human_readable (ST_NBLOCKS (f->stat), buf, ++ human_output_opts, ST_NBLOCKSIZE, ++ output_block_size)) ++ : block_size_width); ++ ++ if (print_scontext) ++ len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width); ++ ++ quote_name (NULL, f->name, filename_quoting_options, &name_width); ++ len += name_width; ++ ++ if (indicator_style != none) ++ { ++ char c = get_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); ++ len += (c != 0); ++ } ++ ++ return len; ++} ++ ++static void ++print_many_per_line (void) ++{ ++ size_t row; /* Current row. */ ++ size_t cols = calculate_columns (true); ++ struct column_info const *line_fmt = &column_info[cols - 1]; ++ ++ /* Calculate the number of rows that will be in each column except possibly ++ for a short column on the right. */ ++ size_t rows = cwd_n_used / cols + (cwd_n_used % cols != 0); ++ ++ for (row = 0; row < rows; row++) ++ { ++ size_t col = 0; ++ size_t filesno = row; ++ size_t pos = 0; ++ ++ /* Print the next row. */ ++ while (1) ++ { ++ struct fileinfo const *f = sorted_file[filesno]; ++ size_t name_length = length_of_file_name_and_frills (f); ++ size_t max_name_length = line_fmt->col_arr[col++]; ++ print_file_name_and_frills (f, pos); ++ ++ filesno += rows; ++ if (filesno >= cwd_n_used) ++ break; ++ ++ indent (pos + name_length, pos + max_name_length); ++ pos += max_name_length; ++ } ++ putchar ('\n'); ++ } ++} ++ ++static void ++print_horizontal (void) ++{ ++ size_t filesno; ++ size_t pos = 0; ++ size_t cols = calculate_columns (false); ++ struct column_info const *line_fmt = &column_info[cols - 1]; ++ struct fileinfo const *f = sorted_file[0]; ++ size_t name_length = length_of_file_name_and_frills (f); ++ size_t max_name_length = line_fmt->col_arr[0]; ++ ++ /* Print first entry. */ ++ print_file_name_and_frills (f, 0); ++ ++ /* Now the rest. */ ++ for (filesno = 1; filesno < cwd_n_used; ++filesno) ++ { ++ size_t col = filesno % cols; ++ ++ if (col == 0) ++ { ++ putchar ('\n'); ++ pos = 0; ++ } ++ else ++ { ++ indent (pos + name_length, pos + max_name_length); ++ pos += max_name_length; ++ } ++ ++ f = sorted_file[filesno]; ++ print_file_name_and_frills (f, pos); ++ ++ name_length = length_of_file_name_and_frills (f); ++ max_name_length = line_fmt->col_arr[col]; ++ } ++ putchar ('\n'); ++} ++ ++static void ++print_with_commas (void) ++{ ++ size_t filesno; ++ size_t pos = 0; ++ ++ for (filesno = 0; filesno < cwd_n_used; filesno++) ++ { ++ struct fileinfo const *f = sorted_file[filesno]; ++ size_t len = length_of_file_name_and_frills (f); ++ ++ if (filesno != 0) ++ { ++ char separator; ++ ++ if (pos + len + 2 < line_length) ++ { ++ pos += 2; ++ separator = ' '; ++ } ++ else ++ { ++ pos = 0; ++ separator = '\n'; ++ } ++ ++ putchar (','); ++ putchar (separator); ++ } ++ ++ print_file_name_and_frills (f, pos); ++ pos += len; ++ } ++ putchar ('\n'); ++} ++ ++/* Assuming cursor is at position FROM, indent up to position TO. ++ Use a TAB character instead of two or more spaces whenever possible. */ ++ ++static void ++indent (size_t from, size_t to) ++{ ++ while (from < to) ++ { ++ if (tabsize != 0 && to / tabsize > (from + 1) / tabsize) ++ { ++ putchar ('\t'); ++ from += tabsize - from % tabsize; ++ } ++ else ++ { ++ putchar (' '); ++ from++; ++ } ++ } ++} ++ ++/* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */ ++/* FIXME: maybe remove this function someday. See about using a ++ non-malloc'ing version of file_name_concat. */ ++ ++static void ++attach (char *dest, const char *dirname, const char *name) ++{ ++ const char *dirnamep = dirname; ++ ++ /* Copy dirname if it is not ".". */ ++ if (dirname[0] != '.' || dirname[1] != 0) ++ { ++ while (*dirnamep) ++ *dest++ = *dirnamep++; ++ /* Add '/' if `dirname' doesn't already end with it. */ ++ if (dirnamep > dirname && dirnamep[-1] != '/') ++ *dest++ = '/'; ++ } ++ while (*name) ++ *dest++ = *name++; ++ *dest = 0; ++} ++ ++/* Allocate enough column info suitable for the current number of ++ files and display columns, and initialize the info to represent the ++ narrowest possible columns. */ ++ ++static void ++init_column_info (void) ++{ ++ size_t i; ++ size_t max_cols = MIN (max_idx, cwd_n_used); ++ ++ /* Currently allocated columns in column_info. */ ++ static size_t column_info_alloc; ++ ++ if (column_info_alloc < max_cols) ++ { ++ size_t new_column_info_alloc; ++ size_t *p; ++ ++ if (max_cols < max_idx / 2) ++ { ++ /* The number of columns is far less than the display width ++ allows. Grow the allocation, but only so that it's ++ double the current requirements. If the display is ++ extremely wide, this avoids allocating a lot of memory ++ that is never needed. */ ++ column_info = xnrealloc (column_info, max_cols, ++ 2 * sizeof *column_info); ++ new_column_info_alloc = 2 * max_cols; ++ } ++ else ++ { ++ column_info = xnrealloc (column_info, max_idx, sizeof *column_info); ++ new_column_info_alloc = max_idx; ++ } ++ ++ /* Allocate the new size_t objects by computing the triangle ++ formula n * (n + 1) / 2, except that we don't need to ++ allocate the part of the triangle that we've already ++ allocated. Check for address arithmetic overflow. */ ++ { ++ size_t column_info_growth = new_column_info_alloc - column_info_alloc; ++ size_t s = column_info_alloc + 1 + new_column_info_alloc; ++ size_t t = s * column_info_growth; ++ if (s < new_column_info_alloc || t / column_info_growth != s) ++ xalloc_die (); ++ p = xnmalloc (t / 2, sizeof *p); ++ } ++ ++ /* Grow the triangle by parceling out the cells just allocated. */ ++ for (i = column_info_alloc; i < new_column_info_alloc; i++) ++ { ++ column_info[i].col_arr = p; ++ p += i + 1; ++ } ++ ++ column_info_alloc = new_column_info_alloc; ++ } ++ ++ for (i = 0; i < max_cols; ++i) ++ { ++ size_t j; ++ ++ column_info[i].valid_len = true; ++ column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH; ++ for (j = 0; j <= i; ++j) ++ column_info[i].col_arr[j] = MIN_COLUMN_WIDTH; ++ } ++} ++ ++/* Calculate the number of columns needed to represent the current set ++ of files in the current display width. */ ++ ++static size_t ++calculate_columns (bool by_columns) ++{ ++ size_t filesno; /* Index into cwd_file. */ ++ size_t cols; /* Number of files across. */ ++ ++ /* Normally the maximum number of columns is determined by the ++ screen width. But if few files are available this might limit it ++ as well. */ ++ size_t max_cols = MIN (max_idx, cwd_n_used); ++ ++ init_column_info (); ++ ++ /* Compute the maximum number of possible columns. */ ++ for (filesno = 0; filesno < cwd_n_used; ++filesno) ++ { ++ struct fileinfo const *f = sorted_file[filesno]; ++ size_t name_length = length_of_file_name_and_frills (f); ++ size_t i; ++ ++ for (i = 0; i < max_cols; ++i) ++ { ++ if (column_info[i].valid_len) ++ { ++ size_t idx = (by_columns ++ ? filesno / ((cwd_n_used + i) / (i + 1)) ++ : filesno % (i + 1)); ++ size_t real_length = name_length + (idx == i ? 0 : 2); ++ ++ if (column_info[i].col_arr[idx] < real_length) ++ { ++ column_info[i].line_len += (real_length ++ - column_info[i].col_arr[idx]); ++ column_info[i].col_arr[idx] = real_length; ++ column_info[i].valid_len = (column_info[i].line_len ++ < line_length); ++ } ++ } ++ } ++ } ++ ++ /* Find maximum allowed columns. */ ++ for (cols = max_cols; 1 < cols; --cols) ++ { ++ if (column_info[cols - 1].valid_len) ++ break; ++ } ++ ++ return cols; ++} ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name); ++ fputs (_("\ ++List information about the FILEs (the current directory by default).\n\ ++Sort entries alphabetically if none of -cftuvSUX nor --sort.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ -a, --all do not ignore entries starting with .\n\ ++ -A, --almost-all do not list implied . and ..\n\ ++ --author with -l, print the author of each file\n\ ++ -b, --escape print octal escapes for nongraphic characters\n\ ++"), stdout); ++ fputs (_("\ ++ --block-size=SIZE use SIZE-byte blocks. See SIZE format below\n\ ++ -B, --ignore-backups do not list implied entries ending with ~\n\ ++ -c with -lt: sort by, and show, ctime (time of last\n\ ++ modification of file status information)\n\ ++ with -l: show ctime and sort by name\n\ ++ otherwise: sort by ctime\n\ ++"), stdout); ++ fputs (_("\ ++ -C list entries by columns\n\ ++ --color[=WHEN] colorize the output. WHEN defaults to `always'\n\ ++ or can be `never' or `auto'. More info below\n\ ++ -d, --directory list directory entries instead of contents,\n\ ++ and do not dereference symbolic links\n\ ++ -D, --dired generate output designed for Emacs' dired mode\n\ ++"), stdout); ++ fputs (_("\ ++ -f do not sort, enable -aU, disable -ls --color\n\ ++ -F, --classify append indicator (one of */=>@|) to entries\n\ ++ --file-type likewise, except do not append `*'\n\ ++ --format=WORD across -x, commas -m, horizontal -x, long -l,\n\ ++ single-column -1, verbose -l, vertical -C\n\ ++ --full-time like -l --time-style=full-iso\n\ ++"), stdout); ++ fputs (_("\ ++ -g like -l, but do not list owner\n\ ++"), stdout); ++ fputs (_("\ ++ --group-directories-first\n\ ++ group directories before files.\n\ ++ augment with a --sort option, but any\n\ ++ use of --sort=none (-U) disables grouping\n\ ++"), stdout); ++ fputs (_("\ ++ -G, --no-group in a long listing, don't print group names\n\ ++ -h, --human-readable with -l, print sizes in human readable format\n\ ++ (e.g., 1K 234M 2G)\n\ ++ --si likewise, but use powers of 1000 not 1024\n\ ++"), stdout); ++ fputs (_("\ ++ -H, --dereference-command-line\n\ ++ follow symbolic links listed on the command line\n\ ++ --dereference-command-line-symlink-to-dir\n\ ++ follow each command line symbolic link\n\ ++ that points to a directory\n\ ++ --hide=PATTERN do not list implied entries matching shell PATTERN\n\ ++ (overridden by -a or -A)\n\ ++"), stdout); ++ fputs (_("\ ++ --indicator-style=WORD append indicator with style WORD to entry names:\n\ ++ none (default), slash (-p),\n\ ++ file-type (--file-type), classify (-F)\n\ ++ -i, --inode print the index number of each file\n\ ++ -I, --ignore=PATTERN do not list implied entries matching shell PATTERN\n\ ++ -k like --block-size=1K\n\ ++"), stdout); ++ fputs (_("\ ++ -l use a long listing format\n\ ++ -L, --dereference when showing file information for a symbolic\n\ ++ link, show information for the file the link\n\ ++ references rather than for the link itself\n\ ++ -m fill width with a comma separated list of entries\n\ ++"), stdout); ++ fputs (_("\ ++ -n, --numeric-uid-gid like -l, but list numeric user and group IDs\n\ ++ -N, --literal print raw entry names (don't treat e.g. control\n\ ++ characters specially)\n\ ++ -o like -l, but do not list group information\n\ ++ -p, --indicator-style=slash\n\ ++ append / indicator to directories\n\ ++"), stdout); ++ fputs (_("\ ++ -q, --hide-control-chars print ? instead of non graphic characters\n\ ++ --show-control-chars show non graphic characters as-is (default\n\ ++ unless program is `ls' and output is a terminal)\n\ ++ -Q, --quote-name enclose entry names in double quotes\n\ ++ --quoting-style=WORD use quoting style WORD for entry names:\n\ ++ literal, locale, shell, shell-always, c, escape\n\ ++"), stdout); ++ fputs (_("\ ++ -r, --reverse reverse order while sorting\n\ ++ -R, --recursive list subdirectories recursively\n\ ++ -s, --size print the allocated size of each file, in blocks\n\ ++"), stdout); ++ fputs (_("\ ++ -S sort by file size\n\ ++ --sort=WORD sort by WORD instead of name: none -U,\n\ ++ extension -X, size -S, time -t, version -v\n\ ++ --time=WORD with -l, show time as WORD instead of modification\n\ ++ time: atime -u, access -u, use -u, ctime -c,\n\ ++ or status -c; use specified time as sort key\n\ ++ if --sort=time\n\ ++"), stdout); ++ fputs (_("\ ++ --time-style=STYLE with -l, show times using style STYLE:\n\ ++ full-iso, long-iso, iso, locale, +FORMAT.\n\ ++ FORMAT is interpreted like `date'; if FORMAT is\n\ ++ FORMAT1FORMAT2, FORMAT1 applies to\n\ ++ non-recent files and FORMAT2 to recent files;\n\ ++ if STYLE is prefixed with `posix-', STYLE\n\ ++ takes effect only outside the POSIX locale\n\ ++"), stdout); ++ fputs (_("\ ++ -t sort by modification time\n\ ++ -T, --tabsize=COLS assume tab stops at each COLS instead of 8\n\ ++"), stdout); ++ fputs (_("\ ++ -u with -lt: sort by, and show, access time\n\ ++ with -l: show access time and sort by name\n\ ++ otherwise: sort by access time\n\ ++ -U do not sort; list entries in directory order\n\ ++ -v natural sort of (version) numbers within text\n\ ++"), stdout); ++ fputs (_("\ ++ -w, --width=COLS assume screen width instead of current value\n\ ++ -x list entries by lines instead of by columns\n\ ++ -X sort alphabetically by entry extension\n\ ++ -Z, --context print any SELinux security context of each file\n\ ++ -1 list one file per line\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ emit_size_note (); ++ fputs (_("\ ++\n\ ++Using color to distinguish file types is disabled both by default and\n\ ++with --color=never. With --color=auto, ls emits color codes only when\n\ ++standard output is connected to a terminal. The LS_COLORS environment\n\ ++variable can change the settings. Use the dircolors command to set it.\n\ ++"), stdout); ++ fputs (_("\ ++\n\ ++Exit status:\n\ ++ 0 if OK,\n\ ++ 1 if minor problems (e.g., cannot access subdirectory),\n\ ++ 2 if serious trouble (e.g., cannot access command-line argument).\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} +diff -urNp coreutils-8.0-orig/src/mkdir.c coreutils-8.0/src/mkdir.c +--- coreutils-8.0-orig/src/mkdir.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/mkdir.c 2009-10-07 10:10:11.000000000 +0200 @@ -38,6 +38,7 @@ static struct option const longopts[] = { @@ -621,9 +10757,9 @@ diff -urNp coreutils-7.1-orig/src/mkdir.c coreutils-7.1/src/mkdir.c {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, -diff -urNp coreutils-7.1-orig/src/mknod.c coreutils-7.1/src/mknod.c ---- coreutils-7.1-orig/src/mknod.c 2008-09-22 16:01:21.000000000 +0200 -+++ coreutils-7.1/src/mknod.c 2009-02-24 13:47:15.000000000 +0100 +diff -urNp coreutils-8.0-orig/src/mknod.c coreutils-8.0/src/mknod.c +--- coreutils-8.0-orig/src/mknod.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/mknod.c 2009-10-07 10:10:11.000000000 +0200 @@ -35,7 +35,7 @@ static struct option const longopts[] = @@ -633,10 +10769,10 @@ diff -urNp coreutils-7.1-orig/src/mknod.c coreutils-7.1/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urNp coreutils-7.1-orig/src/mv.c coreutils-7.1/src/mv.c ---- coreutils-7.1-orig/src/mv.c 2009-02-18 15:32:52.000000000 +0100 -+++ coreutils-7.1/src/mv.c 2009-02-24 13:47:15.000000000 +0100 -@@ -122,6 +122,7 @@ cp_option_init (struct cp_options *x) +diff -urNp coreutils-8.0-orig/src/mv.c coreutils-8.0/src/mv.c +--- coreutils-8.0-orig/src/mv.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.0/src/mv.c 2009-10-07 10:10:11.000000000 +0200 +@@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x) x->preserve_mode = true; x->preserve_timestamps = true; x->preserve_security_context = selinux_enabled; @@ -644,9 +10780,508 @@ diff -urNp coreutils-7.1-orig/src/mv.c coreutils-7.1/src/mv.c x->reduce_diagnostics = false; x->require_preserve = false; /* FIXME: maybe make this an option */ x->require_preserve_context = false; -diff -urNp coreutils-7.1-orig/src/runcon.c coreutils-7.1/src/runcon.c ---- coreutils-7.1-orig/src/runcon.c 2008-09-18 09:06:57.000000000 +0200 -+++ coreutils-7.1/src/runcon.c 2009-02-24 13:47:15.000000000 +0100 +diff -urNp coreutils-8.0-orig/src/mv.c.orig coreutils-8.0/src/mv.c.orig +--- coreutils-8.0-orig/src/mv.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/mv.c.orig 2009-09-23 10:25:44.000000000 +0200 +@@ -0,0 +1,495 @@ ++/* mv -- move or rename files ++ Copyright (C) 86, 89, 90, 91, 1995-2009 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 Mike Parker, David MacKenzie, and Jim Meyering */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "system.h" ++#include "backupfile.h" ++#include "copy.h" ++#include "cp-hash.h" ++#include "error.h" ++#include "filenamecat.h" ++#include "quote.h" ++#include "remove.h" ++#include "root-dev-ino.h" ++#include "priv-set.h" ++ ++/* The official name of this program (e.g., no `g' prefix). */ ++#define PROGRAM_NAME "mv" ++ ++#define AUTHORS \ ++ proper_name ("Mike Parker"), \ ++ proper_name ("David MacKenzie"), \ ++ proper_name ("Jim Meyering") ++ ++/* For long options that have no equivalent short option, use a ++ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ ++enum ++{ ++ STRIP_TRAILING_SLASHES_OPTION = CHAR_MAX + 1 ++}; ++ ++/* Remove any trailing slashes from each SOURCE argument. */ ++static bool remove_trailing_slashes; ++ ++static struct option const long_options[] = ++{ ++ {"backup", optional_argument, NULL, 'b'}, ++ {"force", no_argument, NULL, 'f'}, ++ {"interactive", no_argument, NULL, 'i'}, ++ {"no-clobber", no_argument, NULL, 'n'}, ++ {"no-target-directory", no_argument, NULL, 'T'}, ++ {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION}, ++ {"suffix", required_argument, NULL, 'S'}, ++ {"target-directory", required_argument, NULL, 't'}, ++ {"update", no_argument, NULL, 'u'}, ++ {"verbose", no_argument, NULL, 'v'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++static void ++rm_option_init (struct rm_options *x) ++{ ++ x->ignore_missing_files = false; ++ x->recursive = true; ++ x->one_file_system = false; ++ ++ /* Should we prompt for removal, too? No. Prompting for the `move' ++ part is enough. It implies removal. */ ++ x->interactive = RMI_NEVER; ++ x->stdin_tty = false; ++ ++ x->verbose = false; ++ ++ /* Since this program may well have to process additional command ++ line arguments after any call to `rm', that function must preserve ++ the initial working directory, in case one of those is a ++ `.'-relative name. */ ++ x->require_restore_cwd = true; ++ ++ { ++ static struct dev_ino dev_ino_buf; ++ x->root_dev_ino = get_root_dev_ino (&dev_ino_buf); ++ if (x->root_dev_ino == NULL) ++ error (EXIT_FAILURE, errno, _("failed to get attributes of %s"), ++ quote ("/")); ++ } ++} ++ ++static void ++cp_option_init (struct cp_options *x) ++{ ++ bool selinux_enabled = (0 < is_selinux_enabled ()); ++ ++ cp_options_default (x); ++ x->copy_as_regular = false; /* FIXME: maybe make this an option */ ++ x->reflink_mode = REFLINK_NEVER; ++ x->dereference = DEREF_NEVER; ++ x->unlink_dest_before_opening = false; ++ x->unlink_dest_after_failed_open = false; ++ x->hard_link = false; ++ x->interactive = I_UNSPECIFIED; ++ x->move_mode = true; ++ x->one_file_system = false; ++ x->preserve_ownership = true; ++ x->preserve_links = true; ++ x->preserve_mode = true; ++ x->preserve_timestamps = true; ++ x->preserve_security_context = selinux_enabled; ++ x->reduce_diagnostics = false; ++ x->require_preserve = false; /* FIXME: maybe make this an option */ ++ x->require_preserve_context = false; ++ x->preserve_xattr = true; ++ x->require_preserve_xattr = false; ++ x->recursive = true; ++ x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */ ++ x->symbolic_link = false; ++ x->set_mode = false; ++ x->mode = 0; ++ x->stdin_tty = isatty (STDIN_FILENO); ++ ++ x->open_dangling_dest_symlink = false; ++ x->update = false; ++ x->verbose = false; ++ x->dest_info = NULL; ++ x->src_info = NULL; ++} ++ ++/* FILE is the last operand of this command. Return true if FILE is a ++ directory. But report an error if there is a problem accessing FILE, other ++ than nonexistence (errno == ENOENT). */ ++ ++static bool ++target_directory_operand (char const *file) ++{ ++ struct stat st; ++ int err = (stat (file, &st) == 0 ? 0 : errno); ++ bool is_a_dir = !err && S_ISDIR (st.st_mode); ++ if (err && err != ENOENT) ++ error (EXIT_FAILURE, err, _("accessing %s"), quote (file)); ++ return is_a_dir; ++} ++ ++/* Move SOURCE onto DEST. Handles cross-file-system moves. ++ If SOURCE is a directory, DEST must not exist. ++ Return true if successful. */ ++ ++static bool ++do_move (const char *source, const char *dest, const struct cp_options *x) ++{ ++ bool copy_into_self; ++ bool rename_succeeded; ++ bool ok = copy (source, dest, false, x, ©_into_self, &rename_succeeded); ++ ++ if (ok) ++ { ++ char const *dir_to_remove; ++ if (copy_into_self) ++ { ++ /* In general, when copy returns with copy_into_self set, SOURCE is ++ the same as, or a parent of DEST. In this case we know it's a ++ parent. It doesn't make sense to move a directory into itself, and ++ besides in some situations doing so would give highly nonintuitive ++ results. Run this `mkdir b; touch a c; mv * b' in an empty ++ directory. Here's the result of running echo `find b -print`: ++ b b/a b/b b/b/a b/c. Notice that only file `a' was copied ++ into b/b. Handle this by giving a diagnostic, removing the ++ copied-into-self directory, DEST (`b/b' in the example), ++ and failing. */ ++ ++ dir_to_remove = NULL; ++ ok = false; ++ } ++ else if (rename_succeeded) ++ { ++ /* No need to remove anything. SOURCE was successfully ++ renamed to DEST. Or the user declined to rename a file. */ ++ dir_to_remove = NULL; ++ } ++ else ++ { ++ /* This may mean SOURCE and DEST referred to different devices. ++ It may also conceivably mean that even though they referred ++ to the same device, rename wasn't implemented for that device. ++ ++ E.g., (from Joel N. Weber), ++ [...] there might someday be cases where you can't rename ++ but you can copy where the device name is the same, especially ++ on Hurd. Consider an ftpfs with a primitive ftp server that ++ supports uploading, downloading and deleting, but not renaming. ++ ++ Also, note that comparing device numbers is not a reliable ++ check for `can-rename'. Some systems can be set up so that ++ files from many different physical devices all have the same ++ st_dev field. This is a feature of some NFS mounting ++ configurations. ++ ++ We reach this point if SOURCE has been successfully copied ++ to DEST. Now we have to remove SOURCE. ++ ++ This function used to resort to copying only when rename ++ failed and set errno to EXDEV. */ ++ ++ dir_to_remove = source; ++ } ++ ++ if (dir_to_remove != NULL) ++ { ++ struct rm_options rm_options; ++ enum RM_status status; ++ char const *dir[2]; ++ ++ rm_option_init (&rm_options); ++ rm_options.verbose = x->verbose; ++ dir[0] = dir_to_remove; ++ dir[1] = NULL; ++ ++ status = rm ((void*) dir, &rm_options); ++ assert (VALID_STATUS (status)); ++ if (status == RM_ERROR) ++ ok = false; ++ } ++ } ++ ++ return ok; ++} ++ ++/* Move file SOURCE onto DEST. Handles the case when DEST is a directory. ++ Treat DEST as a directory if DEST_IS_DIR. ++ Return true if successful. */ ++ ++static bool ++movefile (char *source, char *dest, bool dest_is_dir, ++ const struct cp_options *x) ++{ ++ bool ok; ++ ++ /* This code was introduced to handle the ambiguity in the semantics ++ of mv that is induced by the varying semantics of the rename function. ++ Some systems (e.g., GNU/Linux) have a rename function that honors a ++ trailing slash, while others (like Solaris 5,6,7) have a rename ++ function that ignores a trailing slash. I believe the GNU/Linux ++ rename semantics are POSIX and susv2 compliant. */ ++ ++ if (remove_trailing_slashes) ++ strip_trailing_slashes (source); ++ ++ if (dest_is_dir) ++ { ++ /* Treat DEST as a directory; build the full filename. */ ++ char const *src_basename = last_component (source); ++ char *new_dest = file_name_concat (dest, src_basename, NULL); ++ strip_trailing_slashes (new_dest); ++ ok = do_move (source, new_dest, x); ++ free (new_dest); ++ } ++ else ++ { ++ ok = do_move (source, dest, x); ++ } ++ ++ return ok; ++} ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("\ ++Usage: %s [OPTION]... [-T] SOURCE DEST\n\ ++ or: %s [OPTION]... SOURCE... DIRECTORY\n\ ++ or: %s [OPTION]... -t DIRECTORY SOURCE...\n\ ++"), ++ program_name, program_name, program_name); ++ fputs (_("\ ++Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++Mandatory arguments to long options are mandatory for short options too.\n\ ++"), stdout); ++ fputs (_("\ ++ --backup[=CONTROL] make a backup of each existing destination file\n\ ++ -b like --backup but does not accept an argument\n\ ++ -f, --force do not prompt before overwriting\n\ ++ -i, --interactive prompt before overwrite\n\ ++ -n, --no-clobber do not overwrite an existing file\n\ ++If you specify more than one of -i, -f, -n, only the final one takes effect.\n\ ++"), stdout); ++ fputs (_("\ ++ --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\ ++ argument\n\ ++ -S, --suffix=SUFFIX override the usual backup suffix\n\ ++"), stdout); ++ fputs (_("\ ++ -t, --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY\n\ ++ -T, --no-target-directory treat DEST as a normal file\n\ ++ -u, --update move only when the SOURCE file is newer\n\ ++ than the destination file or when the\n\ ++ destination file is missing\n\ ++ -v, --verbose explain what is being done\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ fputs (_("\ ++\n\ ++The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\ ++The version control method may be selected via the --backup option or through\n\ ++the VERSION_CONTROL environment variable. Here are the values:\n\ ++\n\ ++"), stdout); ++ fputs (_("\ ++ none, off never make backups (even if --backup is given)\n\ ++ numbered, t make numbered backups\n\ ++ existing, nil numbered if numbered backups exist, simple otherwise\n\ ++ simple, never always make simple backups\n\ ++"), stdout); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int c; ++ bool ok; ++ bool make_backups = false; ++ char *backup_suffix_string; ++ char *version_control_string = NULL; ++ struct cp_options x; ++ char *target_directory = NULL; ++ bool no_target_directory = false; ++ int n_files; ++ char **file; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ atexit (close_stdin); ++ ++ cp_option_init (&x); ++ ++ /* Try to disable the ability to unlink a directory. */ ++ priv_set_remove_linkdir (); ++ ++ /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless ++ we'll actually use backup_suffix_string. */ ++ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); ++ ++ while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL)) ++ != -1) ++ { ++ switch (c) ++ { ++ case 'b': ++ make_backups = true; ++ if (optarg) ++ version_control_string = optarg; ++ break; ++ case 'f': ++ x.interactive = I_ALWAYS_YES; ++ break; ++ case 'i': ++ x.interactive = I_ASK_USER; ++ break; ++ case 'n': ++ x.interactive = I_ALWAYS_NO; ++ break; ++ case STRIP_TRAILING_SLASHES_OPTION: ++ remove_trailing_slashes = true; ++ break; ++ case 't': ++ if (target_directory) ++ error (EXIT_FAILURE, 0, _("multiple target directories specified")); ++ else ++ { ++ struct stat st; ++ if (stat (optarg, &st) != 0) ++ error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg)); ++ if (! S_ISDIR (st.st_mode)) ++ error (EXIT_FAILURE, 0, _("target %s is not a directory"), ++ quote (optarg)); ++ } ++ target_directory = optarg; ++ break; ++ case 'T': ++ no_target_directory = true; ++ break; ++ case 'u': ++ x.update = true; ++ break; ++ case 'v': ++ x.verbose = true; ++ break; ++ case 'S': ++ make_backups = true; ++ backup_suffix_string = optarg; ++ break; ++ case_GETOPT_HELP_CHAR; ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ default: ++ usage (EXIT_FAILURE); ++ } ++ } ++ ++ n_files = argc - optind; ++ file = argv + optind; ++ ++ if (n_files <= !target_directory) ++ { ++ if (n_files <= 0) ++ error (0, 0, _("missing file operand")); ++ else ++ error (0, 0, _("missing destination file operand after %s"), ++ quote (file[0])); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (no_target_directory) ++ { ++ if (target_directory) ++ error (EXIT_FAILURE, 0, ++ _("cannot combine --target-directory (-t) " ++ "and --no-target-directory (-T)")); ++ if (2 < n_files) ++ { ++ error (0, 0, _("extra operand %s"), quote (file[2])); ++ usage (EXIT_FAILURE); ++ } ++ } ++ else if (!target_directory) ++ { ++ assert (2 <= n_files); ++ if (target_directory_operand (file[n_files - 1])) ++ target_directory = file[--n_files]; ++ else if (2 < n_files) ++ error (EXIT_FAILURE, 0, _("target %s is not a directory"), ++ quote (file[n_files - 1])); ++ } ++ ++ if (make_backups && x.interactive == I_ALWAYS_NO) ++ { ++ error (0, 0, ++ _("options --backup and --no-clobber are mutually exclusive")); ++ usage (EXIT_FAILURE); ++ } ++ ++ if (backup_suffix_string) ++ simple_backup_suffix = xstrdup (backup_suffix_string); ++ ++ x.backup_type = (make_backups ++ ? xget_version (_("backup type"), ++ version_control_string) ++ : no_backups); ++ ++ hash_init (); ++ ++ if (target_directory) ++ { ++ int i; ++ ++ /* Initialize the hash table only if we'll need it. ++ The problem it is used to detect can arise only if there are ++ two or more files to move. */ ++ if (2 <= n_files) ++ dest_info_init (&x); ++ ++ ok = true; ++ for (i = 0; i < n_files; ++i) ++ ok &= movefile (file[i], target_directory, true, &x); ++ } ++ else ++ ok = movefile (file[0], file[1], false, &x); ++ ++ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); ++} +diff -urNp coreutils-8.0-orig/src/runcon.c coreutils-8.0/src/runcon.c +--- coreutils-8.0-orig/src/runcon.c 2009-10-06 10:55:34.000000000 +0200 ++++ coreutils-8.0/src/runcon.c 2009-10-07 10:10:11.000000000 +0200 @@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ "), program_name, program_name); @@ -656,9 +11291,9 @@ diff -urNp coreutils-7.1-orig/src/runcon.c coreutils-7.1/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c ---- coreutils-7.1-orig/src/stat.c 2009-01-27 22:11:25.000000000 +0100 -+++ coreutils-7.1/src/stat.c 2009-02-24 13:47:15.000000000 +0100 +diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c +--- coreutils-8.0-orig/src/stat.c 2009-09-29 16:25:44.000000000 +0200 ++++ coreutils-8.0/src/stat.c 2009-10-07 10:10:11.000000000 +0200 @@ -825,7 +825,7 @@ print_it (char const *format, char const /* Stat the file system and print what we find. */ @@ -668,7 +11303,7 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c { STRUCT_STATVFS statfsbuf; -@@ -837,15 +837,31 @@ do_statfs (char const *filename, bool te +@@ -844,15 +844,31 @@ do_statfs (char const *filename, bool te } if (format == NULL) @@ -678,22 +11313,20 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c - format = (terse - ? "%n %i %l %t %s %S %b %f %a %c %d\n" - : " File: \"%n\"\n" -- " ID: %-8i Namelen: %-7l Type: %T\n" -- "Block size: %-10s Fundamental block size: %S\n" -- "Blocks: Total: %-10b Free: %-10f Available: %a\n" -- "Inodes: Total: %-10c Free: %d\n"); + if (secure) + format = "%n %i %l %t %s %S %b %f %a %c %d %C\n"; + else + format = "%n %i %l %t %s %S %b %f %a %c %d\n"; - } ++ } + else + { + if (secure) + format = " File: \"%n\"\n" -+ " ID: %-8i Namelen: %-7l Type: %T\n" -+ "Block size: %-10s Fundamental block size: %S\n" -+ "Blocks: Total: %-10b Free: %-10f Available: %a\n" + " ID: %-8i Namelen: %-7l Type: %T\n" + "Block size: %-10s Fundamental block size: %S\n" + "Blocks: Total: %-10b Free: %-10f Available: %a\n" +- "Inodes: Total: %-10c Free: %d\n"); +- } + "Inodes: Total: %-10c Free: %d\n" + " S_Context: %C\n"; + else @@ -707,7 +11340,7 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c print_it (format, filename, print_statfs, &statfsbuf); return true; -@@ -853,7 +869,7 @@ do_statfs (char const *filename, bool te +@@ -860,7 +876,7 @@ do_statfs (char const *filename, bool te /* stat the file and print what we find */ static bool @@ -716,7 +11349,7 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c { struct stat statbuf; -@@ -866,9 +882,12 @@ do_stat (char const *filename, bool ters +@@ -881,9 +897,12 @@ do_stat (char const *filename, bool ters if (format == NULL) { if (terse) @@ -732,7 +11365,7 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c else { /* Temporary hack to match original output until conditional -@@ -885,12 +904,22 @@ do_stat (char const *filename, bool ters +@@ -900,12 +919,22 @@ do_stat (char const *filename, bool ters } else { @@ -761,7 +11394,7 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c } } } -@@ -911,6 +940,7 @@ usage (int status) +@@ -926,6 +955,7 @@ usage (int status) Display file or file system status.\n\ \n\ -L, --dereference follow links\n\ @@ -769,7 +11402,7 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c -f, --file-system display file system status instead of file status\n\ "), stdout); fputs (_("\ -@@ -995,6 +1025,7 @@ main (int argc, char *argv[]) +@@ -1010,6 +1040,7 @@ main (int argc, char *argv[]) int i; bool fs = false; bool terse = false; @@ -777,7 +11410,7 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c char *format = NULL; bool ok = true; -@@ -1034,13 +1065,13 @@ main (int argc, char *argv[]) +@@ -1049,13 +1080,13 @@ main (int argc, char *argv[]) terse = true; break; @@ -798,7 +11431,7 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c break; case_GETOPT_HELP_CHAR; -@@ -1060,8 +1091,8 @@ main (int argc, char *argv[]) +@@ -1075,8 +1106,8 @@ main (int argc, char *argv[]) for (i = optind; i < argc; i++) ok &= (fs @@ -809,9 +11442,1095 @@ diff -urNp coreutils-7.1-orig/src/stat.c coreutils-7.1/src/stat.c exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } -diff -urNp coreutils-7.1-orig/tests/misc/selinux coreutils-7.1/tests/misc/selinux ---- coreutils-7.1-orig/tests/misc/selinux 2008-10-25 14:20:26.000000000 +0200 -+++ coreutils-7.1/tests/misc/selinux 2009-02-24 13:47:15.000000000 +0100 +diff -urNp coreutils-8.0-orig/src/stat.c.orig coreutils-8.0/src/stat.c.orig +--- coreutils-8.0-orig/src/stat.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.0/src/stat.c.orig 2009-09-29 16:25:44.000000000 +0200 +@@ -0,0 +1,1082 @@ ++/* stat.c -- display file or file system status ++ Copyright (C) 2001-2009 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 Michael Meskes. */ ++ ++#include ++ ++/* Keep this conditional in sync with the similar conditional in ++ ../m4/stat-prog.m4. */ ++#if (STAT_STATVFS \ ++ && (HAVE_STRUCT_STATVFS_F_BASETYPE || HAVE_STRUCT_STATVFS_F_FSTYPENAME \ ++ || (! HAVE_STRUCT_STATFS_F_FSTYPENAME && HAVE_STRUCT_STATVFS_F_TYPE))) ++# define USE_STATVFS 1 ++#else ++# define USE_STATVFS 0 ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#if USE_STATVFS ++# include ++#elif HAVE_SYS_VFS_H ++# include ++#elif HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H ++/* NOTE: freebsd5.0 needs sys/param.h and sys/mount.h for statfs. ++ It does have statvfs.h, but shouldn't use it, since it doesn't ++ HAVE_STRUCT_STATVFS_F_BASETYPE. So find a clean way to fix it. */ ++/* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */ ++# include ++# include ++# if HAVE_NETINET_IN_H && HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H ++/* Ultrix 4.4 needs these for the declaration of struct statfs. */ ++# include ++# include ++# include ++# endif ++#elif HAVE_OS_H /* BeOS */ ++# include ++#endif ++#include ++ ++#include "system.h" ++ ++#include "error.h" ++#include "filemode.h" ++#include "file-type.h" ++#include "fs.h" ++#include "getopt.h" ++#include "quote.h" ++#include "quotearg.h" ++#include "stat-time.h" ++#include "strftime.h" ++#include "areadlink.h" ++ ++#define alignof(type) offsetof (struct { char c; type x; }, x) ++ ++#if USE_STATVFS ++# define STRUCT_STATVFS struct statvfs ++# define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATVFS_F_FSID_IS_INTEGER ++# define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS_F_TYPE ++# if HAVE_STRUCT_STATVFS_F_NAMEMAX ++# define SB_F_NAMEMAX(S) ((S)->f_namemax) ++# endif ++# define STATFS statvfs ++# define STATFS_FRSIZE(S) ((S)->f_frsize) ++#else ++# define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATFS_F_TYPE ++# if HAVE_STRUCT_STATFS_F_NAMELEN ++# define SB_F_NAMEMAX(S) ((S)->f_namelen) ++# endif ++# define STATFS statfs ++# if HAVE_OS_H /* BeOS */ ++/* BeOS has a statvfs function, but it does not return sensible values ++ for f_files, f_ffree and f_favail, and lacks f_type, f_basetype and ++ f_fstypename. Use 'struct fs_info' instead. */ ++static int ++statfs (char const *filename, struct fs_info *buf) ++{ ++ dev_t device = dev_for_path (filename); ++ if (device < 0) ++ { ++ errno = (device == B_ENTRY_NOT_FOUND ? ENOENT ++ : device == B_BAD_VALUE ? EINVAL ++ : device == B_NAME_TOO_LONG ? ENAMETOOLONG ++ : device == B_NO_MEMORY ? ENOMEM ++ : device == B_FILE_ERROR ? EIO ++ : 0); ++ return -1; ++ } ++ /* If successful, buf->dev will be == device. */ ++ return fs_stat_dev (device, buf); ++} ++# define f_fsid dev ++# define f_blocks total_blocks ++# define f_bfree free_blocks ++# define f_bavail free_blocks ++# define f_bsize io_size ++# define f_files total_nodes ++# define f_ffree free_nodes ++# define STRUCT_STATVFS struct fs_info ++# define STRUCT_STATXFS_F_FSID_IS_INTEGER true ++# define STATFS_FRSIZE(S) ((S)->block_size) ++# else ++# define STRUCT_STATVFS struct statfs ++# define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATFS_F_FSID_IS_INTEGER ++# define STATFS_FRSIZE(S) 0 ++# endif ++#endif ++ ++#ifdef SB_F_NAMEMAX ++# define OUT_NAMEMAX out_uint ++#else ++/* NetBSD 1.5.2 has neither f_namemax nor f_namelen. */ ++# define SB_F_NAMEMAX(S) "*" ++# define OUT_NAMEMAX out_string ++#endif ++ ++#if HAVE_STRUCT_STATVFS_F_BASETYPE ++# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_basetype ++#else ++# if HAVE_STRUCT_STATVFS_F_FSTYPENAME || HAVE_STRUCT_STATFS_F_FSTYPENAME ++# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_fstypename ++# elif HAVE_OS_H /* BeOS */ ++# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME fsh_name ++# endif ++#endif ++ ++/* FIXME: these are used by printf.c, too */ ++#define isodigit(c) ('0' <= (c) && (c) <= '7') ++#define octtobin(c) ((c) - '0') ++#define hextobin(c) ((c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \ ++ (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : (c) - '0') ++ ++#define PROGRAM_NAME "stat" ++ ++#define AUTHORS proper_name ("Michael Meskes") ++ ++enum ++{ ++ PRINTF_OPTION = CHAR_MAX + 1 ++}; ++ ++static struct option const long_options[] = ++{ ++ {"context", no_argument, 0, 'Z'}, ++ {"dereference", no_argument, NULL, 'L'}, ++ {"file-system", no_argument, NULL, 'f'}, ++ {"format", required_argument, NULL, 'c'}, ++ {"printf", required_argument, NULL, PRINTF_OPTION}, ++ {"terse", no_argument, NULL, 't'}, ++ {GETOPT_HELP_OPTION_DECL}, ++ {GETOPT_VERSION_OPTION_DECL}, ++ {NULL, 0, NULL, 0} ++}; ++ ++/* Whether to follow symbolic links; True for --dereference (-L). */ ++static bool follow_links; ++ ++/* Whether to interpret backslash-escape sequences. ++ True for --printf=FMT, not for --format=FMT (-c). */ ++static bool interpret_backslash_escapes; ++ ++/* The trailing delimiter string: ++ "" for --printf=FMT, "\n" for --format=FMT (-c). */ ++static char const *trailing_delim = ""; ++ ++/* Return the type of the specified file system. ++ Some systems have statfvs.f_basetype[FSTYPSZ] (AIX, HP-UX, and Solaris). ++ Others have statvfs.f_fstypename[_VFS_NAMELEN] (NetBSD 3.0). ++ Others have statfs.f_fstypename[MFSNAMELEN] (NetBSD 1.5.2). ++ Still others have neither and have to get by with f_type (GNU/Linux). ++ But f_type may only exist in statfs (Cygwin). */ ++static char const * ++human_fstype (STRUCT_STATVFS const *statfsbuf) ++{ ++#ifdef STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME ++ return statfsbuf->STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME; ++#else ++ switch (statfsbuf->f_type) ++ { ++# if defined __linux__ ++ ++ /* Compare with what's in libc: ++ f=/a/libc/sysdeps/unix/sysv/linux/linux_fsinfo.h ++ sed -n '/ADFS_SUPER_MAGIC/,/SYSFS_MAGIC/p' $f \ ++ | perl -n -e '/#define (.*?)_(?:SUPER_)MAGIC\s+0x(\S+)/' \ ++ -e 'and print "case S_MAGIC_$1: /\* 0x" . uc($2) . " *\/\n"' \ ++ | sort > sym_libc ++ perl -ne '/^\s+(case S_MAGIC_.*?): \/\* 0x(\S+) \*\//' \ ++ -e 'and do { $v=uc$2; print "$1: /\* 0x$v *\/\n"}' stat.c \ ++ | sort > sym_stat ++ diff -u sym_stat sym_libc ++ */ ++ ++ /* Also sync from the list in "man 2 statfs". */ ++ ++ /* IMPORTANT NOTE: Each of the following `case S_MAGIC_...:' ++ statements must be followed by a hexadecimal constant in ++ a comment. The S_MAGIC_... name and constant are automatically ++ combined to produce the #define directives in fs.h. */ ++ ++ case S_MAGIC_ADFS: /* 0xADF5 */ ++ return "adfs"; ++ case S_MAGIC_AFFS: /* 0xADFF */ ++ return "affs"; ++ case S_MAGIC_AUTOFS: /* 0x187 */ ++ return "autofs"; ++ case S_MAGIC_BEFS: /* 0x42465331 */ ++ return "befs"; ++ case S_MAGIC_BFS: /* 0x1BADFACE */ ++ return "bfs"; ++ case S_MAGIC_BINFMT_MISC: /* 0x42494e4d */ ++ return "binfmt_misc"; ++ case S_MAGIC_CODA: /* 0x73757245 */ ++ return "coda"; ++ case S_MAGIC_COH: /* 0x012FF7B7 */ ++ return "coh"; ++ case S_MAGIC_CRAMFS: /* 0x28CD3D45 */ ++ return "cramfs"; ++ case S_MAGIC_DEVFS: /* 0x1373 */ ++ return "devfs"; ++ case S_MAGIC_DEVPTS: /* 0x1CD1 */ ++ return "devpts"; ++ case S_MAGIC_EFS: /* 0x414A53 */ ++ return "efs"; ++ case S_MAGIC_EXT: /* 0x137D */ ++ return "ext"; ++ case S_MAGIC_EXT2: /* 0xEF53 */ ++ return "ext2/ext3"; ++ case S_MAGIC_EXT2_OLD: /* 0xEF51 */ ++ return "ext2"; ++ case S_MAGIC_FAT: /* 0x4006 */ ++ return "fat"; ++ case S_MAGIC_FUSECTL: /* 0x65735543 */ ++ return "fusectl"; ++ case S_MAGIC_HPFS: /* 0xF995E849 */ ++ return "hpfs"; ++ case S_MAGIC_HUGETLBFS: /* 0x958458f6 */ ++ return "hugetlbfs"; ++ case S_MAGIC_ISOFS: /* 0x9660 */ ++ return "isofs"; ++ case S_MAGIC_ISOFS_R_WIN: /* 0x4004 */ ++ return "isofs"; ++ case S_MAGIC_ISOFS_WIN: /* 0x4000 */ ++ return "isofs"; ++ case S_MAGIC_JFFS2: /* 0x72B6 */ ++ return "jffs2"; ++ case S_MAGIC_JFFS: /* 0x07C0 */ ++ return "jffs"; ++ case S_MAGIC_JFS: /* 0x3153464A */ ++ return "jfs"; ++ case S_MAGIC_LUSTRE: /* 0x0BD00BD0 */ ++ return "lustre"; ++ case S_MAGIC_MINIX: /* 0x137F */ ++ return "minix"; ++ case S_MAGIC_MINIX_30: /* 0x138F */ ++ return "minix (30 char.)"; ++ case S_MAGIC_MINIX_V2: /* 0x2468 */ ++ return "minix v2"; ++ case S_MAGIC_MINIX_V2_30: /* 0x2478 */ ++ return "minix v2 (30 char.)"; ++ case S_MAGIC_MSDOS: /* 0x4D44 */ ++ return "msdos"; ++ case S_MAGIC_NCP: /* 0x564C */ ++ return "novell"; ++ case S_MAGIC_NFS: /* 0x6969 */ ++ return "nfs"; ++ case S_MAGIC_NFSD: /* 0x6E667364 */ ++ return "nfsd"; ++ case S_MAGIC_NTFS: /* 0x5346544E */ ++ return "ntfs"; ++ case S_MAGIC_OPENPROM: /* 0x9fa1 */ ++ return "openprom"; ++ case S_MAGIC_PROC: /* 0x9FA0 */ ++ return "proc"; ++ case S_MAGIC_QNX4: /* 0x002F */ ++ return "qnx4"; ++ case S_MAGIC_RAMFS: /* 0x858458F6 */ ++ return "ramfs"; ++ case S_MAGIC_REISERFS: /* 0x52654973 */ ++ return "reiserfs"; ++ case S_MAGIC_ROMFS: /* 0x7275 */ ++ return "romfs"; ++ case S_MAGIC_SMB: /* 0x517B */ ++ return "smb"; ++ case S_MAGIC_SQUASHFS: /* 0x73717368 */ ++ return "squashfs"; ++ case S_MAGIC_SYSFS: /* 0x62656572 */ ++ return "sysfs"; ++ case S_MAGIC_SYSV2: /* 0x012FF7B6 */ ++ return "sysv2"; ++ case S_MAGIC_SYSV4: /* 0x012FF7B5 */ ++ return "sysv4"; ++ case S_MAGIC_TMPFS: /* 0x1021994 */ ++ return "tmpfs"; ++ case S_MAGIC_UDF: /* 0x15013346 */ ++ return "udf"; ++ case S_MAGIC_UFS: /* 0x00011954 */ ++ return "ufs"; ++ case S_MAGIC_UFS_BYTESWAPPED: /* 0x54190100 */ ++ return "ufs"; ++ case S_MAGIC_USBDEVFS: /* 0x9FA2 */ ++ return "usbdevfs"; ++ case S_MAGIC_VXFS: /* 0xA501FCF5 */ ++ return "vxfs"; ++ case S_MAGIC_XENIX: /* 0x012FF7B4 */ ++ return "xenix"; ++ case S_MAGIC_XFS: /* 0x58465342 */ ++ return "xfs"; ++ case S_MAGIC_XIAFS: /* 0x012FD16D */ ++ return "xia"; ++ ++# elif __GNU__ ++ case FSTYPE_UFS: ++ return "ufs"; ++ case FSTYPE_NFS: ++ return "nfs"; ++ case FSTYPE_GFS: ++ return "gfs"; ++ case FSTYPE_LFS: ++ return "lfs"; ++ case FSTYPE_SYSV: ++ return "sysv"; ++ case FSTYPE_FTP: ++ return "ftp"; ++ case FSTYPE_TAR: ++ return "tar"; ++ case FSTYPE_AR: ++ return "ar"; ++ case FSTYPE_CPIO: ++ return "cpio"; ++ case FSTYPE_MSLOSS: ++ return "msloss"; ++ case FSTYPE_CPM: ++ return "cpm"; ++ case FSTYPE_HFS: ++ return "hfs"; ++ case FSTYPE_DTFS: ++ return "dtfs"; ++ case FSTYPE_GRFS: ++ return "grfs"; ++ case FSTYPE_TERM: ++ return "term"; ++ case FSTYPE_DEV: ++ return "dev"; ++ case FSTYPE_PROC: ++ return "proc"; ++ case FSTYPE_IFSOCK: ++ return "ifsock"; ++ case FSTYPE_AFS: ++ return "afs"; ++ case FSTYPE_DFS: ++ return "dfs"; ++ case FSTYPE_PROC9: ++ return "proc9"; ++ case FSTYPE_SOCKET: ++ return "socket"; ++ case FSTYPE_MISC: ++ return "misc"; ++ case FSTYPE_EXT2FS: ++ return "ext2/ext3"; ++ case FSTYPE_HTTP: ++ return "http"; ++ case FSTYPE_MEMFS: ++ return "memfs"; ++ case FSTYPE_ISO9660: ++ return "iso9660"; ++# endif ++ default: ++ { ++ unsigned long int type = statfsbuf->f_type; ++ static char buf[sizeof "UNKNOWN (0x%lx)" - 3 ++ + (sizeof type * CHAR_BIT + 3) / 4]; ++ sprintf (buf, "UNKNOWN (0x%lx)", type); ++ return buf; ++ } ++ } ++#endif ++} ++ ++static char * ++human_access (struct stat const *statbuf) ++{ ++ static char modebuf[12]; ++ filemodestring (statbuf, modebuf); ++ modebuf[10] = 0; ++ return modebuf; ++} ++ ++static char * ++human_time (struct timespec t) ++{ ++ static char str[MAX (INT_BUFSIZE_BOUND (intmax_t), ++ (INT_STRLEN_BOUND (int) /* YYYY */ ++ + 1 /* because YYYY might equal INT_MAX + 1900 */ ++ + sizeof "-MM-DD HH:MM:SS.NNNNNNNNN +ZZZZ"))]; ++ struct tm const *tm = localtime (&t.tv_sec); ++ if (tm == NULL) ++ return timetostr (t.tv_sec, str); ++ nstrftime (str, sizeof str, "%Y-%m-%d %H:%M:%S.%N %z", tm, 0, t.tv_nsec); ++ return str; ++} ++ ++static void ++out_string (char *pformat, size_t prefix_len, char const *arg) ++{ ++ strcpy (pformat + prefix_len, "s"); ++ printf (pformat, arg); ++} ++static void ++out_int (char *pformat, size_t prefix_len, intmax_t arg) ++{ ++ strcpy (pformat + prefix_len, PRIdMAX); ++ printf (pformat, arg); ++} ++static void ++out_uint (char *pformat, size_t prefix_len, uintmax_t arg) ++{ ++ strcpy (pformat + prefix_len, PRIuMAX); ++ printf (pformat, arg); ++} ++static void ++out_uint_o (char *pformat, size_t prefix_len, uintmax_t arg) ++{ ++ strcpy (pformat + prefix_len, PRIoMAX); ++ printf (pformat, arg); ++} ++static void ++out_uint_x (char *pformat, size_t prefix_len, uintmax_t arg) ++{ ++ strcpy (pformat + prefix_len, PRIxMAX); ++ printf (pformat, arg); ++} ++ ++/* Very specialized function (modifies FORMAT), just so as to avoid ++ duplicating this code between both print_statfs and print_stat. */ ++static void ++out_file_context (char const *filename, char *pformat, size_t prefix_len) ++{ ++ char *scontext; ++ if ((follow_links ++ ? getfilecon (filename, &scontext) ++ : lgetfilecon (filename, &scontext)) < 0) ++ { ++ error (0, errno, _("failed to get security context of %s"), ++ quote (filename)); ++ scontext = NULL; ++ } ++ strcpy (pformat + prefix_len, "s"); ++ printf (pformat, (scontext ? scontext : "?")); ++ if (scontext) ++ freecon (scontext); ++} ++ ++/* print statfs info */ ++static void ++print_statfs (char *pformat, size_t prefix_len, char m, char const *filename, ++ void const *data) ++{ ++ STRUCT_STATVFS const *statfsbuf = data; ++ ++ switch (m) ++ { ++ case 'n': ++ out_string (pformat, prefix_len, filename); ++ break; ++ ++ case 'i': ++ { ++#if STRUCT_STATXFS_F_FSID_IS_INTEGER ++ uintmax_t fsid = statfsbuf->f_fsid; ++#else ++ typedef unsigned int fsid_word; ++ verify (alignof (STRUCT_STATVFS) % alignof (fsid_word) == 0); ++ verify (offsetof (STRUCT_STATVFS, f_fsid) % alignof (fsid_word) == 0); ++ verify (sizeof statfsbuf->f_fsid % alignof (fsid_word) == 0); ++ fsid_word const *p = (fsid_word *) &statfsbuf->f_fsid; ++ ++ /* Assume a little-endian word order, as that is compatible ++ with glibc's statvfs implementation. */ ++ uintmax_t fsid = 0; ++ int words = sizeof statfsbuf->f_fsid / sizeof *p; ++ int i; ++ for (i = 0; i < words && i * sizeof *p < sizeof fsid; i++) ++ { ++ uintmax_t u = p[words - 1 - i]; ++ fsid |= u << (i * CHAR_BIT * sizeof *p); ++ } ++#endif ++ out_uint_x (pformat, prefix_len, fsid); ++ } ++ break; ++ ++ case 'l': ++ OUT_NAMEMAX (pformat, prefix_len, SB_F_NAMEMAX (statfsbuf)); ++ break; ++ case 't': ++#if HAVE_STRUCT_STATXFS_F_TYPE ++ out_uint_x (pformat, prefix_len, statfsbuf->f_type); ++#else ++ fputc ('?', stdout); ++#endif ++ break; ++ case 'T': ++ out_string (pformat, prefix_len, human_fstype (statfsbuf)); ++ break; ++ case 'b': ++ out_int (pformat, prefix_len, statfsbuf->f_blocks); ++ break; ++ case 'f': ++ out_int (pformat, prefix_len, statfsbuf->f_bfree); ++ break; ++ case 'a': ++ out_int (pformat, prefix_len, statfsbuf->f_bavail); ++ break; ++ case 's': ++ out_uint (pformat, prefix_len, statfsbuf->f_bsize); ++ break; ++ case 'S': ++ { ++ uintmax_t frsize = STATFS_FRSIZE (statfsbuf); ++ if (! frsize) ++ frsize = statfsbuf->f_bsize; ++ out_uint (pformat, prefix_len, frsize); ++ } ++ break; ++ case 'c': ++ out_uint (pformat, prefix_len, statfsbuf->f_files); ++ break; ++ case 'd': ++ out_int (pformat, prefix_len, statfsbuf->f_ffree); ++ break; ++ case 'C': ++ out_file_context (filename, pformat, prefix_len); ++ break; ++ default: ++ fputc ('?', stdout); ++ break; ++ } ++} ++ ++/* print stat info */ ++static void ++print_stat (char *pformat, size_t prefix_len, char m, ++ char const *filename, void const *data) ++{ ++ struct stat *statbuf = (struct stat *) data; ++ struct passwd *pw_ent; ++ struct group *gw_ent; ++ ++ switch (m) ++ { ++ case 'n': ++ out_string (pformat, prefix_len, filename); ++ break; ++ case 'N': ++ out_string (pformat, prefix_len, quote (filename)); ++ if (S_ISLNK (statbuf->st_mode)) ++ { ++ char *linkname = areadlink_with_size (filename, statbuf->st_size); ++ if (linkname == NULL) ++ { ++ error (0, errno, _("cannot read symbolic link %s"), ++ quote (filename)); ++ return; ++ } ++ printf (" -> "); ++ out_string (pformat, prefix_len, quote (linkname)); ++ } ++ break; ++ case 'd': ++ out_uint (pformat, prefix_len, statbuf->st_dev); ++ break; ++ case 'D': ++ out_uint_x (pformat, prefix_len, statbuf->st_dev); ++ break; ++ case 'i': ++ out_uint (pformat, prefix_len, statbuf->st_ino); ++ break; ++ case 'a': ++ out_uint_o (pformat, prefix_len, statbuf->st_mode & CHMOD_MODE_BITS); ++ break; ++ case 'A': ++ out_string (pformat, prefix_len, human_access (statbuf)); ++ break; ++ case 'f': ++ out_uint_x (pformat, prefix_len, statbuf->st_mode); ++ break; ++ case 'F': ++ out_string (pformat, prefix_len, file_type (statbuf)); ++ break; ++ case 'h': ++ out_uint (pformat, prefix_len, statbuf->st_nlink); ++ break; ++ case 'u': ++ out_uint (pformat, prefix_len, statbuf->st_uid); ++ break; ++ case 'U': ++ setpwent (); ++ pw_ent = getpwuid (statbuf->st_uid); ++ out_string (pformat, prefix_len, ++ pw_ent ? pw_ent->pw_name : "UNKNOWN"); ++ break; ++ case 'g': ++ out_uint (pformat, prefix_len, statbuf->st_gid); ++ break; ++ case 'G': ++ setgrent (); ++ gw_ent = getgrgid (statbuf->st_gid); ++ out_string (pformat, prefix_len, ++ gw_ent ? gw_ent->gr_name : "UNKNOWN"); ++ break; ++ case 't': ++ out_uint_x (pformat, prefix_len, major (statbuf->st_rdev)); ++ break; ++ case 'T': ++ out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev)); ++ break; ++ case 's': ++ out_uint (pformat, prefix_len, statbuf->st_size); ++ break; ++ case 'B': ++ out_uint (pformat, prefix_len, ST_NBLOCKSIZE); ++ break; ++ case 'b': ++ out_uint (pformat, prefix_len, ST_NBLOCKS (*statbuf)); ++ break; ++ case 'o': ++ out_uint (pformat, prefix_len, statbuf->st_blksize); ++ break; ++ case 'x': ++ out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); ++ break; ++ case 'X': ++ if (TYPE_SIGNED (time_t)) ++ out_int (pformat, prefix_len, statbuf->st_atime); ++ else ++ out_uint (pformat, prefix_len, statbuf->st_atime); ++ break; ++ case 'y': ++ out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf))); ++ break; ++ case 'Y': ++ if (TYPE_SIGNED (time_t)) ++ out_int (pformat, prefix_len, statbuf->st_mtime); ++ else ++ out_uint (pformat, prefix_len, statbuf->st_mtime); ++ break; ++ case 'z': ++ out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf))); ++ break; ++ case 'Z': ++ if (TYPE_SIGNED (time_t)) ++ out_int (pformat, prefix_len, statbuf->st_ctime); ++ else ++ out_uint (pformat, prefix_len, statbuf->st_ctime); ++ break; ++ case 'C': ++ out_file_context (filename, pformat, prefix_len); ++ break; ++ default: ++ fputc ('?', stdout); ++ break; ++ } ++} ++ ++/* Output a single-character \ escape. */ ++ ++static void ++print_esc_char (char c) ++{ ++ switch (c) ++ { ++ case 'a': /* Alert. */ ++ c ='\a'; ++ break; ++ case 'b': /* Backspace. */ ++ c ='\b'; ++ break; ++ case 'f': /* Form feed. */ ++ c ='\f'; ++ break; ++ case 'n': /* New line. */ ++ c ='\n'; ++ break; ++ case 'r': /* Carriage return. */ ++ c ='\r'; ++ break; ++ case 't': /* Horizontal tab. */ ++ c ='\t'; ++ break; ++ case 'v': /* Vertical tab. */ ++ c ='\v'; ++ break; ++ case '"': ++ case '\\': ++ break; ++ default: ++ error (0, 0, _("warning: unrecognized escape `\\%c'"), c); ++ break; ++ } ++ putchar (c); ++} ++ ++static void ++print_it (char const *format, char const *filename, ++ void (*print_func) (char *, size_t, char, char const *, void const *), ++ void const *data) ++{ ++ /* Add 2 to accommodate our conversion of the stat `%s' format string ++ to the longer printf `%llu' one. */ ++ enum ++ { ++ MAX_ADDITIONAL_BYTES = ++ (MAX (sizeof PRIdMAX, ++ MAX (sizeof PRIoMAX, MAX (sizeof PRIuMAX, sizeof PRIxMAX))) ++ - 1) ++ }; ++ size_t n_alloc = strlen (format) + MAX_ADDITIONAL_BYTES + 1; ++ char *dest = xmalloc (n_alloc); ++ char const *b; ++ for (b = format; *b; b++) ++ { ++ switch (*b) ++ { ++ case '%': ++ { ++ size_t len = strspn (b + 1, "#-+.I 0123456789"); ++ char const *fmt_char = b + len + 1; ++ memcpy (dest, b, len + 1); ++ ++ b = fmt_char; ++ switch (*fmt_char) ++ { ++ case '\0': ++ --b; ++ /* fall through */ ++ case '%': ++ if (0 < len) ++ { ++ dest[len + 1] = *fmt_char; ++ dest[len + 2] = '\0'; ++ error (EXIT_FAILURE, 0, _("%s: invalid directive"), ++ quotearg_colon (dest)); ++ } ++ putchar ('%'); ++ break; ++ default: ++ print_func (dest, len + 1, *fmt_char, filename, data); ++ break; ++ } ++ break; ++ } ++ ++ case '\\': ++ if ( ! interpret_backslash_escapes) ++ { ++ putchar ('\\'); ++ break; ++ } ++ ++b; ++ if (isodigit (*b)) ++ { ++ int esc_value = octtobin (*b); ++ int esc_length = 1; /* number of octal digits */ ++ for (++b; esc_length < 3 && isodigit (*b); ++ ++esc_length, ++b) ++ { ++ esc_value = esc_value * 8 + octtobin (*b); ++ } ++ putchar (esc_value); ++ --b; ++ } ++ else if (*b == 'x' && isxdigit (to_uchar (b[1]))) ++ { ++ int esc_value = hextobin (b[1]); /* Value of \xhh escape. */ ++ /* A hexadecimal \xhh escape sequence must have ++ 1 or 2 hex. digits. */ ++ ++b; ++ if (isxdigit (to_uchar (b[1]))) ++ { ++ ++b; ++ esc_value = esc_value * 16 + hextobin (*b); ++ } ++ putchar (esc_value); ++ } ++ else if (*b == '\0') ++ { ++ error (0, 0, _("warning: backslash at end of format")); ++ putchar ('\\'); ++ /* Arrange to exit the loop. */ ++ --b; ++ } ++ else ++ { ++ print_esc_char (*b); ++ } ++ break; ++ ++ default: ++ putchar (*b); ++ break; ++ } ++ } ++ free (dest); ++ ++ fputs (trailing_delim, stdout); ++} ++ ++/* Stat the file system and print what we find. */ ++static bool ++do_statfs (char const *filename, bool terse, char const *format) ++{ ++ STRUCT_STATVFS statfsbuf; ++ ++ if (STREQ (filename, "-")) ++ { ++ error (0, 0, _("using %s to denote standard input does not work" ++ " in file system mode"), quote (filename)); ++ return false; ++ } ++ ++ if (STATFS (filename, &statfsbuf) != 0) ++ { ++ error (0, errno, _("cannot read file system information for %s"), ++ quote (filename)); ++ return false; ++ } ++ ++ if (format == NULL) ++ { ++ format = (terse ++ ? "%n %i %l %t %s %S %b %f %a %c %d\n" ++ : " File: \"%n\"\n" ++ " ID: %-8i Namelen: %-7l Type: %T\n" ++ "Block size: %-10s Fundamental block size: %S\n" ++ "Blocks: Total: %-10b Free: %-10f Available: %a\n" ++ "Inodes: Total: %-10c Free: %d\n"); ++ } ++ ++ print_it (format, filename, print_statfs, &statfsbuf); ++ return true; ++} ++ ++/* stat the file and print what we find */ ++static bool ++do_stat (char const *filename, bool terse, char const *format) ++{ ++ struct stat statbuf; ++ ++ if (STREQ (filename, "-")) ++ { ++ if (fstat (STDIN_FILENO, &statbuf) != 0) ++ { ++ error (0, errno, _("cannot stat standard input")); ++ return false; ++ } ++ } ++ else if ((follow_links ? stat : lstat) (filename, &statbuf) != 0) ++ { ++ error (0, errno, _("cannot stat %s"), quote (filename)); ++ return false; ++ } ++ ++ if (format == NULL) ++ { ++ if (terse) ++ { ++ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; ++ } ++ else ++ { ++ /* Temporary hack to match original output until conditional ++ implemented. */ ++ if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode)) ++ { ++ format = ++ " File: %N\n" ++ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" ++ "Device: %Dh/%dd\tInode: %-10i Links: %-5h" ++ " Device type: %t,%T\n" ++ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" ++ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; ++ } ++ else ++ { ++ format = ++ " File: %N\n" ++ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" ++ "Device: %Dh/%dd\tInode: %-10i Links: %h\n" ++ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" ++ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; ++ } ++ } ++ } ++ print_it (format, filename, print_stat, &statbuf); ++ return true; ++} ++ ++void ++usage (int status) ++{ ++ if (status != EXIT_SUCCESS) ++ fprintf (stderr, _("Try `%s --help' for more information.\n"), ++ program_name); ++ else ++ { ++ printf (_("Usage: %s [OPTION]... FILE...\n"), program_name); ++ fputs (_("\ ++Display file or file system status.\n\ ++\n\ ++ -L, --dereference follow links\n\ ++ -f, --file-system display file system status instead of file status\n\ ++"), stdout); ++ fputs (_("\ ++ -c --format=FORMAT use the specified FORMAT instead of the default;\n\ ++ output a newline after each use of FORMAT\n\ ++ --printf=FORMAT like --format, but interpret backslash escapes,\n\ ++ and do not output a mandatory trailing newline.\n\ ++ If you want a newline, include \\n in FORMAT.\n\ ++ -t, --terse print the information in terse form\n\ ++"), stdout); ++ fputs (HELP_OPTION_DESCRIPTION, stdout); ++ fputs (VERSION_OPTION_DESCRIPTION, stdout); ++ ++ fputs (_("\n\ ++The valid format sequences for files (without --file-system):\n\ ++\n\ ++ %a Access rights in octal\n\ ++ %A Access rights in human readable form\n\ ++ %b Number of blocks allocated (see %B)\n\ ++ %B The size in bytes of each block reported by %b\n\ ++ %C SELinux security context string\n\ ++"), stdout); ++ fputs (_("\ ++ %d Device number in decimal\n\ ++ %D Device number in hex\n\ ++ %f Raw mode in hex\n\ ++ %F File type\n\ ++ %g Group ID of owner\n\ ++ %G Group name of owner\n\ ++"), stdout); ++ fputs (_("\ ++ %h Number of hard links\n\ ++ %i Inode number\n\ ++ %n File name\n\ ++ %N Quoted file name with dereference if symbolic link\n\ ++ %o I/O block size\n\ ++ %s Total size, in bytes\n\ ++ %t Major device type in hex\n\ ++ %T Minor device type in hex\n\ ++"), stdout); ++ fputs (_("\ ++ %u User ID of owner\n\ ++ %U User name of owner\n\ ++ %x Time of last access\n\ ++ %X Time of last access as seconds since Epoch\n\ ++ %y Time of last modification\n\ ++ %Y Time of last modification as seconds since Epoch\n\ ++ %z Time of last change\n\ ++ %Z Time of last change as seconds since Epoch\n\ ++\n\ ++"), stdout); ++ ++ fputs (_("\ ++Valid format sequences for file systems:\n\ ++\n\ ++ %a Free blocks available to non-superuser\n\ ++ %b Total data blocks in file system\n\ ++ %c Total file nodes in file system\n\ ++ %d Free file nodes in file system\n\ ++ %f Free blocks in file system\n\ ++ %C SELinux security context string\n\ ++"), stdout); ++ fputs (_("\ ++ %i File System ID in hex\n\ ++ %l Maximum length of filenames\n\ ++ %n File name\n\ ++ %s Block size (for faster transfers)\n\ ++ %S Fundamental block size (for block counts)\n\ ++ %t Type in hex\n\ ++ %T Type in human readable form\n\ ++"), stdout); ++ printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME); ++ emit_ancillary_info (); ++ } ++ exit (status); ++} ++ ++int ++main (int argc, char *argv[]) ++{ ++ int c; ++ int i; ++ bool fs = false; ++ bool terse = false; ++ char *format = NULL; ++ bool ok = true; ++ ++ initialize_main (&argc, &argv); ++ set_program_name (argv[0]); ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ ++ atexit (close_stdout); ++ ++ while ((c = getopt_long (argc, argv, "c:fLtZ", long_options, NULL)) != -1) ++ { ++ switch (c) ++ { ++ case PRINTF_OPTION: ++ format = optarg; ++ interpret_backslash_escapes = true; ++ trailing_delim = ""; ++ break; ++ ++ case 'c': ++ format = optarg; ++ interpret_backslash_escapes = false; ++ trailing_delim = "\n"; ++ break; ++ ++ case 'L': ++ follow_links = true; ++ break; ++ ++ case 'f': ++ fs = true; ++ break; ++ ++ case 't': ++ terse = true; ++ break; ++ ++ case 'Z': /* FIXME: remove in 2010 */ ++ /* Ignore, for compatibility with distributions ++ that implemented this before upstream. ++ But warn of impending removal. */ ++ error (0, 0, ++ _("the --context (-Z) option is obsolete and will be removed\n" ++ "in a future release")); ++ break; ++ ++ case_GETOPT_HELP_CHAR; ++ ++ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); ++ ++ default: ++ usage (EXIT_FAILURE); ++ } ++ } ++ ++ if (argc == optind) ++ { ++ error (0, 0, _("missing operand")); ++ usage (EXIT_FAILURE); ++ } ++ ++ for (i = optind; i < argc; i++) ++ ok &= (fs ++ ? do_statfs (argv[i], terse, format) ++ : do_stat (argv[i], terse, format)); ++ ++ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); ++} +diff -urNp coreutils-8.0-orig/tests/misc/selinux coreutils-8.0/tests/misc/selinux +--- coreutils-8.0-orig/tests/misc/selinux 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.0/tests/misc/selinux 2009-10-07 10:10:11.000000000 +0200 @@ -30,7 +30,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. diff --git a/coreutils.spec b/coreutils.spec index 9af4d8a..c34eeb2 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -6,7 +6,7 @@ License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color From 4f2a56081b2cae569b006d6dcc097032f7e4aab3 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 7 Oct 2009 08:16:26 +0000 Subject: [PATCH 060/523] oops... use .xz tarball instead of my local .gz --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index c34eeb2..9af4d8a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -6,7 +6,7 @@ License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color From af1fb4eb122a69ef06413284a42a645f13c1082b Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 7 Oct 2009 08:42:15 +0000 Subject: [PATCH 061/523] update /etc/DIR_COLORS* files --- coreutils-DIR_COLORS | 2 ++ coreutils-DIR_COLORS.256color | 2 ++ coreutils-DIR_COLORS.lightbgcolor | 2 ++ coreutils.spec | 5 ++++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 0e07569..47386de 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -183,6 +183,8 @@ EXEC 01;32 .xcf 01;35 .xwd 01;35 .yuv 01;35 +.cgm 01;35 +.emf 01;35 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions .axv 01;35 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 4628941..8155775 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -158,6 +158,8 @@ EXEC 01;38;5;34 .xcf 01;38;5;13 .xwd 01;38;5;13 .yuv 01;38;5;13 +.cgm 01;38;5;13 +.emf 01;38;5;13 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions .axv 01;38;5;13 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index d254559..fbd1609 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -160,6 +160,8 @@ EXEC 00;32 .xcf 00;35 .xwd 00;35 .yuv 00;35 +.cgm 00;35 +.emf 00;35 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions .axv 00;35 diff --git a/coreutils.spec b/coreutils.spec index 9af4d8a..1937dff 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.0 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -325,6 +325,9 @@ fi %{_libdir}/coreutils %changelog +* Wed Oct 07 2009 Ondrej Vasik - 8.0-2 +- update /etc/DIR_COLORS* files + * Wed Oct 07 2009 Ondrej Vasik - 8.0-1 - New upstream release 8.0 (beta), defuzz patches, remove applied patches From 66a4fe9b1acf28e5d156be7d84a2d7830a776b8b Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 18 Nov 2009 14:48:00 +0000 Subject: [PATCH 062/523] remove accidently added .orig files from patches :( --- coreutils-i18n.patch | 11377 ------------------------- coreutils-pam.patch | 17292 +------------------------------------- coreutils-selinux.patch | 11732 -------------------------- coreutils.spec | 2 +- 4 files changed, 2 insertions(+), 40401 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 2d56736..731ca3f 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -23,63 +23,6 @@ diff -urNp coreutils-8.0-orig/lib/linebuffer.h coreutils-8.0/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.0-orig/lib/linebuffer.h.orig coreutils-8.0/lib/linebuffer.h.orig ---- coreutils-8.0-orig/lib/linebuffer.h.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/lib/linebuffer.h.orig 2009-10-06 10:59:48.000000000 +0200 -@@ -0,0 +1,53 @@ -+/* linebuffer.h -- declarations for reading arbitrarily long lines -+ -+ Copyright (C) 1986, 1991, 1998, 1999, 2002, 2003, 2007 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 . */ -+ -+#if !defined LINEBUFFER_H -+# define LINEBUFFER_H -+ -+# include -+ -+/* A `struct linebuffer' holds a line of text. */ -+ -+struct linebuffer -+{ -+ size_t size; /* Allocated. */ -+ size_t length; /* Used. */ -+ char *buffer; -+}; -+ -+/* Initialize linebuffer LINEBUFFER for use. */ -+void initbuffer (struct linebuffer *linebuffer); -+ -+/* Read an arbitrarily long line of text from STREAM into LINEBUFFER. -+ Consider lines to be terminated by DELIMITER. -+ Keep the delimiter; append DELIMITER if we reach EOF and it wasn't -+ the last character in the file. Do not NUL-terminate. -+ Return LINEBUFFER, except at end of file return NULL. */ -+struct linebuffer *readlinebuffer_delim (struct linebuffer *linebuffer, -+ FILE *stream, char delimiter); -+ -+/* Read an arbitrarily long line of text from STREAM into LINEBUFFER. -+ Keep the newline; append a newline if it's the last line of a file -+ that ends in a non-newline character. Do not NUL-terminate. -+ Return LINEBUFFER, except at end of file return NULL. */ -+struct linebuffer *readlinebuffer (struct linebuffer *linebuffer, FILE *stream); -+ -+/* Free linebuffer LINEBUFFER and its data, all allocated with malloc. */ -+void freebuffer (struct linebuffer *); -+ -+#endif /* LINEBUFFER_H */ diff -urNp coreutils-8.0-orig/src/cut.c coreutils-8.0/src/cut.c --- coreutils-8.0-orig/src/cut.c 2009-09-23 10:25:44.000000000 +0200 +++ coreutils-8.0/src/cut.c 2009-10-07 10:07:16.000000000 +0200 @@ -673,903 +616,6 @@ diff -urNp coreutils-8.0-orig/src/cut.c coreutils-8.0/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.0-orig/src/cut.c.orig coreutils-8.0/src/cut.c.orig ---- coreutils-8.0-orig/src/cut.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/cut.c.orig 2009-09-23 10:25:44.000000000 +0200 -@@ -0,0 +1,893 @@ -+/* cut - remove parts of lines of files -+ Copyright (C) 1997-2009 Free Software Foundation, Inc. -+ Copyright (C) 1984 David M. Ihnat -+ -+ 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 David Ihnat. */ -+ -+/* POSIX changes, bug fixes, long-named options, and cleanup -+ by David MacKenzie . -+ -+ Rewrite cut_fields and cut_bytes -- Jim Meyering. */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include "system.h" -+ -+#include "error.h" -+#include "getndelim2.h" -+#include "hash.h" -+#include "quote.h" -+#include "xstrndup.h" -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "cut" -+ -+#define AUTHORS \ -+ proper_name ("David M. Ihnat"), \ -+ proper_name ("David MacKenzie"), \ -+ proper_name ("Jim Meyering") -+ -+#define FATAL_ERROR(Message) \ -+ do \ -+ { \ -+ error (0, 0, (Message)); \ -+ usage (EXIT_FAILURE); \ -+ } \ -+ while (0) -+ -+/* Append LOW, HIGH to the list RP of range pairs, allocating additional -+ space if necessary. Update local variable N_RP. When allocating, -+ update global variable N_RP_ALLOCATED. */ -+ -+#define ADD_RANGE_PAIR(rp, low, high) \ -+ do \ -+ { \ -+ if (low == 0 || high == 0) \ -+ FATAL_ERROR (_("fields and positions are numbered from 1")); \ -+ if (n_rp >= n_rp_allocated) \ -+ { \ -+ (rp) = X2NREALLOC (rp, &n_rp_allocated); \ -+ } \ -+ rp[n_rp].lo = (low); \ -+ rp[n_rp].hi = (high); \ -+ ++n_rp; \ -+ } \ -+ while (0) -+ -+struct range_pair -+ { -+ size_t lo; -+ size_t hi; -+ }; -+ -+/* 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 -+ first field must be read into this buffer to determine whether it -+ is followed by a delimiter or a newline before any of it may be -+ output. Otherwise, cut_fields can do the job without using this -+ buffer. */ -+static char *field_1_buffer; -+ -+/* The number of bytes allocated for FIELD_1_BUFFER. */ -+static size_t field_1_bufsize; -+ -+/* The largest field or byte index used as an endpoint of a closed -+ or degenerate range specification; this doesn't include the starting -+ index of right-open-ended ranges. For example, with either range spec -+ `2-5,9-', `2-3,5,9-' this variable would be set to 5. */ -+static size_t max_range_endpoint; -+ -+/* If nonzero, this is the index of the first field in a range that goes -+ to end of line. */ -+static size_t eol_range_start; -+ -+/* This is a bit vector. -+ In byte mode, which bytes to output. -+ In field mode, which DELIM-separated fields to output. -+ Both bytes and fields are numbered starting with 1, -+ so the zeroth bit of this array is unused. -+ A field or byte K has been selected if -+ (K <= MAX_RANGE_ENDPOINT and is_printable_field(K)) -+ || (EOL_RANGE_START > 0 && K >= EOL_RANGE_START). */ -+static unsigned char *printable_field; -+ -+enum operating_mode -+ { -+ undefined_mode, -+ -+ /* Output characters that are in the given bytes. */ -+ byte_mode, -+ -+ /* Output the given delimeter-separated fields. */ -+ field_mode -+ }; -+ -+static enum operating_mode operating_mode; -+ -+/* If true do not output lines containing no delimeter characters. -+ Otherwise, all such lines are printed. This option is valid only -+ with field mode. */ -+static bool suppress_non_delimited; -+ -+/* If nonzero, print all bytes, characters, or fields _except_ -+ those that were specified. */ -+static bool complement; -+ -+/* The delimeter character for field mode. */ -+static unsigned char delim; -+ -+/* True if the --output-delimiter=STRING option was specified. */ -+static bool output_delimiter_specified; -+ -+/* The length of output_delimiter_string. */ -+static size_t output_delimiter_length; -+ -+/* The output field separator string. Defaults to the 1-character -+ string consisting of the input delimiter. */ -+static char *output_delimiter_string; -+ -+/* True if we have ever read standard input. */ -+static bool have_read_stdin; -+ -+#define HT_RANGE_START_INDEX_INITIAL_CAPACITY 31 -+ -+/* The set of range-start indices. For example, given a range-spec list like -+ `-b1,3-5,4-9,15-', the following indices will be recorded here: 1, 3, 15. -+ Note that although `4' looks like a range-start index, it is in the middle -+ of the `3-5' range, so it doesn't count. -+ This table is created/used IFF output_delimiter_specified is set. */ -+static Hash_table *range_start_ht; -+ -+/* For long options that have no equivalent short option, use a -+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -+enum -+{ -+ OUTPUT_DELIMITER_OPTION = CHAR_MAX + 1, -+ COMPLEMENT_OPTION -+}; -+ -+static struct option const longopts[] = -+{ -+ {"bytes", required_argument, NULL, 'b'}, -+ {"characters", required_argument, NULL, 'c'}, -+ {"fields", required_argument, NULL, 'f'}, -+ {"delimiter", required_argument, NULL, 'd'}, -+ {"only-delimited", no_argument, NULL, 's'}, -+ {"output-delimiter", required_argument, NULL, OUTPUT_DELIMITER_OPTION}, -+ {"complement", no_argument, NULL, COMPLEMENT_OPTION}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s OPTION... [FILE]...\n\ -+"), -+ program_name); -+ fputs (_("\ -+Print selected parts of lines from each FILE to standard output.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ -b, --bytes=LIST select only these bytes\n\ -+ -c, --characters=LIST select only these characters\n\ -+ -d, --delimiter=DELIM use DELIM instead of TAB for field delimiter\n\ -+"), stdout); -+ fputs (_("\ -+ -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\ -+"), stdout); -+ fputs (_("\ -+ --complement complement the set of selected bytes, characters\n\ -+ or fields\n\ -+"), stdout); -+ fputs (_("\ -+ -s, --only-delimited do not print lines not containing delimiters\n\ -+ --output-delimiter=STRING use STRING as the output delimiter\n\ -+ the default is to use the input delimiter\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ fputs (_("\ -+\n\ -+Use one, and only one of -b, -c or -f. Each LIST is made up of one\n\ -+range, or many ranges separated by commas. Selected input is written\n\ -+in the same order that it is read, and is written exactly once.\n\ -+"), stdout); -+ fputs (_("\ -+Each range is one of:\n\ -+\n\ -+ N N'th byte, character or field, counted from 1\n\ -+ N- from N'th byte, character or field, to end of line\n\ -+ N-M from N'th to M'th (included) byte, character or field\n\ -+ -M from first to M'th (included) byte, character or field\n\ -+\n\ -+With no FILE, or when FILE is -, read standard input.\n\ -+"), stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+static inline void -+mark_range_start (size_t i) -+{ -+ /* Record the fact that `i' is a range-start index. */ -+ void *ent_from_table = hash_insert (range_start_ht, (void*) i); -+ if (ent_from_table == NULL) -+ { -+ /* Insertion failed due to lack of memory. */ -+ xalloc_die (); -+ } -+ assert ((size_t) ent_from_table == i); -+} -+ -+static inline void -+mark_printable_field (size_t i) -+{ -+ size_t n = i / CHAR_BIT; -+ printable_field[n] |= (1 << (i % CHAR_BIT)); -+} -+ -+static inline bool -+is_printable_field (size_t i) -+{ -+ size_t n = i / CHAR_BIT; -+ return (printable_field[n] >> (i % CHAR_BIT)) & 1; -+} -+ -+static size_t -+hash_int (const void *x, size_t tablesize) -+{ -+#ifdef UINTPTR_MAX -+ uintptr_t y = (uintptr_t) x; -+#else -+ size_t y = (size_t) x; -+#endif -+ return y % tablesize; -+} -+ -+static bool -+hash_compare_ints (void const *x, void const *y) -+{ -+ return (x == y) ? true : false; -+} -+ -+static bool -+is_range_start_index (size_t i) -+{ -+ return hash_lookup (range_start_ht, (void *) i) ? true : false; -+} -+ -+/* Return nonzero if the K'th field or byte is printable. -+ When returning nonzero, if RANGE_START is non-NULL, -+ set *RANGE_START to true if K is the beginning of a range, and to -+ false otherwise. */ -+ -+static bool -+print_kth (size_t k, bool *range_start) -+{ -+ bool k_selected -+ = ((0 < eol_range_start && eol_range_start <= k) -+ || (k <= max_range_endpoint && is_printable_field (k))); -+ -+ bool is_selected = k_selected ^ complement; -+ if (range_start && is_selected) -+ *range_start = is_range_start_index (k); -+ -+ return is_selected; -+} -+ -+/* Comparison function for qsort to order the list of -+ struct range_pairs. */ -+static int -+compare_ranges (const void *a, const void *b) -+{ -+ int a_start = ((const struct range_pair *) a)->lo; -+ int b_start = ((const struct range_pair *) b)->lo; -+ return a_start < b_start ? -1 : a_start > b_start; -+} -+ -+/* Given the list of field or byte range specifications FIELDSTR, set -+ MAX_RANGE_ENDPOINT and allocate and initialize the PRINTABLE_FIELD -+ array. If there is a right-open-ended range, set EOL_RANGE_START -+ to its starting index. FIELDSTR should be composed of one or more -+ numbers or ranges of numbers, separated by blanks or commas. -+ Incomplete ranges may be given: `-m' means `1-m'; `n-' means `n' -+ through end of line. Return true if FIELDSTR contains at least -+ one field specification, false otherwise. */ -+ -+/* FIXME-someday: What if the user wants to cut out the 1,000,000-th -+ field of some huge input file? This function shouldn't have to -+ allocate a table of a million bits just so we can test every -+ field < 10^6 with an array dereference. Instead, consider using -+ an adaptive approach: if the range of selected fields is too large, -+ but only a few fields/byte-offsets are actually selected, use a -+ hash table. If the range of selected fields is too large, and -+ too many are selected, then resort to using the range-pairs (the -+ `rp' array) directly. */ -+ -+static bool -+set_fields (const char *fieldstr) -+{ -+ size_t initial = 1; /* Value of first number in a range. */ -+ size_t value = 0; /* If nonzero, a number being accumulated. */ -+ bool lhs_specified = false; -+ bool rhs_specified = false; -+ bool dash_found = false; /* True if a '-' is found in this field. */ -+ bool field_found = false; /* True if at least one field spec -+ has been processed. */ -+ -+ struct range_pair *rp = NULL; -+ size_t n_rp = 0; -+ size_t n_rp_allocated = 0; -+ size_t i; -+ bool in_digits = false; -+ -+ /* Collect and store in RP the range end points. -+ It also sets EOL_RANGE_START if appropriate. */ -+ -+ for (;;) -+ { -+ if (*fieldstr == '-') -+ { -+ in_digits = false; -+ /* Starting a range. */ -+ if (dash_found) -+ FATAL_ERROR (_("invalid byte or field list")); -+ dash_found = true; -+ fieldstr++; -+ -+ initial = (lhs_specified ? value : 1); -+ value = 0; -+ } -+ else if (*fieldstr == ',' || -+ isblank (to_uchar (*fieldstr)) || *fieldstr == '\0') -+ { -+ in_digits = false; -+ /* Ending the string, or this field/byte sublist. */ -+ if (dash_found) -+ { -+ dash_found = false; -+ -+ if (!lhs_specified && !rhs_specified) -+ FATAL_ERROR (_("invalid range with no endpoint: -")); -+ -+ /* A range. Possibilities: -n, m-n, n-. -+ In any case, `initial' contains the start of the range. */ -+ if (!rhs_specified) -+ { -+ /* `n-'. From `initial' to end of line. */ -+ eol_range_start = initial; -+ field_found = true; -+ } -+ else -+ { -+ /* `m-n' or `-n' (1-n). */ -+ if (value < initial) -+ FATAL_ERROR (_("invalid decreasing range")); -+ -+ /* Is there already a range going to end of line? */ -+ if (eol_range_start != 0) -+ { -+ /* Yes. Is the new sequence already contained -+ in the old one? If so, no processing is -+ necessary. */ -+ if (initial < eol_range_start) -+ { -+ /* No, the new sequence starts before the -+ old. Does the old range going to end of line -+ extend into the new range? */ -+ if (eol_range_start <= value) -+ { -+ /* Yes. Simply move the end of line marker. */ -+ eol_range_start = initial; -+ } -+ else -+ { -+ /* No. A simple range, before and disjoint from -+ the range going to end of line. Fill it. */ -+ ADD_RANGE_PAIR (rp, initial, value); -+ } -+ -+ /* In any case, some fields were selected. */ -+ field_found = true; -+ } -+ } -+ else -+ { -+ /* There is no range going to end of line. */ -+ ADD_RANGE_PAIR (rp, initial, value); -+ field_found = true; -+ } -+ value = 0; -+ } -+ } -+ else -+ { -+ /* A simple field number, not a range. */ -+ ADD_RANGE_PAIR (rp, value, value); -+ value = 0; -+ field_found = true; -+ } -+ -+ if (*fieldstr == '\0') -+ { -+ break; -+ } -+ -+ fieldstr++; -+ lhs_specified = false; -+ rhs_specified = false; -+ } -+ else if (ISDIGIT (*fieldstr)) -+ { -+ /* Record beginning of digit string, in case we have to -+ complain about it. */ -+ static char const *num_start; -+ if (!in_digits || !num_start) -+ num_start = fieldstr; -+ in_digits = true; -+ -+ if (dash_found) -+ rhs_specified = 1; -+ else -+ lhs_specified = 1; -+ -+ /* Detect overflow. */ -+ if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t)) -+ { -+ /* In case the user specified -c$(echo 2^64|bc),22, -+ complain only about the first number. */ -+ /* Determine the length of the offending number. */ -+ size_t len = strspn (num_start, "0123456789"); -+ char *bad_num = xstrndup (num_start, len); -+ if (operating_mode == byte_mode) -+ error (0, 0, -+ _("byte offset %s is too large"), quote (bad_num)); -+ else -+ error (0, 0, -+ _("field number %s is too large"), quote (bad_num)); -+ free (bad_num); -+ exit (EXIT_FAILURE); -+ } -+ -+ fieldstr++; -+ } -+ else -+ FATAL_ERROR (_("invalid byte or field list")); -+ } -+ -+ max_range_endpoint = 0; -+ for (i = 0; i < n_rp; i++) -+ { -+ if (rp[i].hi > max_range_endpoint) -+ max_range_endpoint = rp[i].hi; -+ } -+ -+ /* Allocate an array large enough so that it may be indexed by -+ the field numbers corresponding to all finite ranges -+ (i.e. `2-6' or `-4', but not `5-') in FIELDSTR. */ -+ -+ printable_field = xzalloc (max_range_endpoint / CHAR_BIT + 1); -+ -+ qsort (rp, n_rp, sizeof (rp[0]), compare_ranges); -+ -+ /* Set the array entries corresponding to integers in the ranges of RP. */ -+ for (i = 0; i < n_rp; i++) -+ { -+ size_t j; -+ size_t rsi_candidate; -+ -+ /* Record the range-start indices, i.e., record each start -+ index that is not part of any other (lo..hi] range. */ -+ rsi_candidate = complement ? rp[i].hi + 1 : rp[i].lo; -+ if (output_delimiter_specified -+ && !is_printable_field (rsi_candidate)) -+ mark_range_start (rsi_candidate); -+ -+ for (j = rp[i].lo; j <= rp[i].hi; j++) -+ mark_printable_field (j); -+ } -+ -+ if (output_delimiter_specified -+ && !complement -+ && eol_range_start && !is_printable_field (eol_range_start)) -+ mark_range_start (eol_range_start); -+ -+ free (rp); -+ -+ return field_found; -+} -+ -+/* Read from stream STREAM, printing to standard output any selected bytes. */ -+ -+static void -+cut_bytes (FILE *stream) -+{ -+ size_t byte_idx; /* Number of bytes in the line so far. */ -+ /* 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; -+ -+ byte_idx = 0; -+ print_delimiter = false; -+ while (1) -+ { -+ int c; /* Each character from the file. */ -+ -+ c = getc (stream); -+ -+ if (c == '\n') -+ { -+ putchar ('\n'); -+ byte_idx = 0; -+ print_delimiter = false; -+ } -+ else if (c == EOF) -+ { -+ if (byte_idx > 0) -+ putchar ('\n'); -+ break; -+ } -+ else -+ { -+ bool range_start; -+ bool *rs = output_delimiter_specified ? &range_start : NULL; -+ if (print_kth (++byte_idx, rs)) -+ { -+ if (rs && *rs && print_delimiter) -+ { -+ fwrite (output_delimiter_string, sizeof (char), -+ output_delimiter_length, stdout); -+ } -+ print_delimiter = true; -+ putchar (c); -+ } -+ } -+ } -+} -+ -+/* Read from stream STREAM, printing to standard output any selected fields. */ -+ -+static void -+cut_fields (FILE *stream) -+{ -+ int c; -+ size_t field_idx = 1; -+ bool found_any_selected_field = false; -+ bool buffer_first_field; -+ -+ c = getc (stream); -+ if (c == EOF) -+ return; -+ -+ ungetc (c, stream); -+ -+ /* 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, NULL)); -+ -+ while (1) -+ { -+ if (field_idx == 1 && buffer_first_field) -+ { -+ ssize_t len; -+ size_t n_bytes; -+ -+ len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0, -+ GETNLINE_NO_LIMIT, delim, '\n', stream); -+ if (len < 0) -+ { -+ free (field_1_buffer); -+ field_1_buffer = NULL; -+ if (ferror (stream) || feof (stream)) -+ break; -+ xalloc_die (); -+ } -+ -+ n_bytes = len; -+ assert (n_bytes != 0); -+ -+ /* 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 (to_uchar (field_1_buffer[n_bytes - 1]) != delim) -+ { -+ if (suppress_non_delimited) -+ { -+ /* Empty. */ -+ } -+ else -+ { -+ fwrite (field_1_buffer, sizeof (char), n_bytes, stdout); -+ /* Make sure the output line is newline terminated. */ -+ if (field_1_buffer[n_bytes - 1] != '\n') -+ putchar ('\n'); -+ } -+ continue; -+ } -+ if (print_kth (1, NULL)) -+ { -+ /* Print the field, but not the trailing delimiter. */ -+ fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout); -+ found_any_selected_field = true; -+ } -+ ++field_idx; -+ } -+ -+ if (c != EOF) -+ { -+ if (print_kth (field_idx, NULL)) -+ { -+ if (found_any_selected_field) -+ { -+ fwrite (output_delimiter_string, sizeof (char), -+ output_delimiter_length, stdout); -+ } -+ found_any_selected_field = true; -+ -+ while ((c = getc (stream)) != delim && c != '\n' && c != EOF) -+ { -+ putchar (c); -+ } -+ } -+ else -+ { -+ while ((c = getc (stream)) != delim && c != '\n' && c != EOF) -+ { -+ /* Empty. */ -+ } -+ } -+ } -+ -+ if (c == '\n') -+ { -+ c = getc (stream); -+ if (c != EOF) -+ { -+ ungetc (c, stream); -+ c = '\n'; -+ } -+ } -+ -+ if (c == delim) -+ ++field_idx; -+ else if (c == '\n' || c == EOF) -+ { -+ if (found_any_selected_field -+ || !(suppress_non_delimited && field_idx == 1)) -+ putchar ('\n'); -+ if (c == EOF) -+ break; -+ field_idx = 1; -+ found_any_selected_field = false; -+ } -+ } -+} -+ -+static void -+cut_stream (FILE *stream) -+{ -+ if (operating_mode == byte_mode) -+ cut_bytes (stream); -+ else -+ cut_fields (stream); -+} -+ -+/* Process file FILE to standard output. -+ Return true if successful. */ -+ -+static bool -+cut_file (char const *file) -+{ -+ FILE *stream; -+ -+ if (STREQ (file, "-")) -+ { -+ have_read_stdin = true; -+ stream = stdin; -+ } -+ else -+ { -+ stream = fopen (file, "r"); -+ if (stream == NULL) -+ { -+ error (0, errno, "%s", file); -+ return false; -+ } -+ } -+ -+ cut_stream (stream); -+ -+ if (ferror (stream)) -+ { -+ error (0, errno, "%s", file); -+ return false; -+ } -+ if (STREQ (file, "-")) -+ clearerr (stream); /* Also clear EOF. */ -+ else if (fclose (stream) == EOF) -+ { -+ error (0, errno, "%s", file); -+ return false; -+ } -+ return true; -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int optc; -+ bool ok; -+ bool delim_specified = false; -+ char *spec_list_string IF_LINT(= NULL); -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdout); -+ -+ operating_mode = undefined_mode; -+ -+ /* By default, all non-delimited lines are printed. */ -+ suppress_non_delimited = false; -+ -+ delim = '\0'; -+ have_read_stdin = false; -+ -+ while ((optc = getopt_long (argc, argv, "b:c:d:f:ns", longopts, NULL)) != -1) -+ { -+ 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")); -+ operating_mode = byte_mode; -+ spec_list_string = optarg; -+ break; -+ -+ case 'f': -+ /* Build the field list. */ -+ if (operating_mode != undefined_mode) -+ FATAL_ERROR (_("only one type of list may be specified")); -+ operating_mode = field_mode; -+ spec_list_string = optarg; -+ break; -+ -+ 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; -+ break; -+ -+ case OUTPUT_DELIMITER_OPTION: -+ output_delimiter_specified = true; -+ /* Interpret --output-delimiter='' to mean -+ `use the NUL byte as the delimiter.' */ -+ output_delimiter_length = (optarg[0] == '\0' -+ ? 1 : strlen (optarg)); -+ output_delimiter_string = xstrdup (optarg); -+ break; -+ -+ case 'n': -+ break; -+ -+ case 's': -+ suppress_non_delimited = true; -+ break; -+ -+ case COMPLEMENT_OPTION: -+ complement = true; -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (operating_mode == undefined_mode) -+ FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); -+ -+ if (delim != '\0' && operating_mode != field_mode) -+ FATAL_ERROR (_("an input delimiter may be specified only\ -+ when operating on fields")); -+ -+ if (suppress_non_delimited && operating_mode != field_mode) -+ FATAL_ERROR (_("suppressing non-delimited lines makes sense\n\ -+\tonly when operating on fields")); -+ -+ if (output_delimiter_specified) -+ { -+ range_start_ht = hash_initialize (HT_RANGE_START_INDEX_INITIAL_CAPACITY, -+ NULL, hash_int, -+ hash_compare_ints, NULL); -+ if (range_start_ht == NULL) -+ xalloc_die (); -+ -+ } -+ -+ if (! set_fields (spec_list_string)) -+ { -+ if (operating_mode == field_mode) -+ FATAL_ERROR (_("missing list of fields")); -+ else -+ FATAL_ERROR (_("missing list of positions")); -+ } -+ -+ if (!delim_specified) -+ delim = '\t'; -+ -+ if (output_delimiter_string == NULL) -+ { -+ static char dummy[2]; -+ dummy[0] = delim; -+ dummy[1] = '\0'; -+ output_delimiter_string = dummy; -+ output_delimiter_length = 1; -+ } -+ -+ if (optind == argc) -+ ok = cut_file ("-"); -+ else -+ for (ok = true; optind < argc; optind++) -+ ok &= cut_file (argv[optind]); -+ -+ if (range_start_ht) -+ hash_free (range_start_ht); -+ -+ if (have_read_stdin && fclose (stdin) == EOF) -+ { -+ error (0, errno, "-"); -+ ok = false; -+ } -+ -+ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); -+} diff -urNp coreutils-8.0-orig/src/expand.c coreutils-8.0/src/expand.c --- coreutils-8.0-orig/src/expand.c 2009-09-29 15:27:54.000000000 +0200 +++ coreutils-8.0/src/expand.c 2009-10-07 10:07:16.000000000 +0200 @@ -1759,440 +805,6 @@ diff -urNp coreutils-8.0-orig/src/expand.c coreutils-8.0/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.0-orig/src/expand.c.orig coreutils-8.0/src/expand.c.orig ---- coreutils-8.0-orig/src/expand.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/expand.c.orig 2009-09-29 15:27:54.000000000 +0200 -@@ -0,0 +1,430 @@ -+/* expand - convert tabs to spaces -+ Copyright (C) 89, 91, 1995-2006, 2008-2009 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 . */ -+ -+/* By default, convert all tabs to spaces. -+ Preserves backspace characters in the output; they decrement the -+ column count for tab calculations. -+ The default action is equivalent to -8. -+ -+ Options: -+ --tabs=tab1[,tab2[,...]] -+ -t tab1[,tab2[,...]] -+ -tab1[,tab2[,...]] If only one tab stop is given, set the tabs tab1 -+ columns apart instead of the default 8. Otherwise, -+ set the tabs at columns tab1, tab2, etc. (numbered from -+ 0); replace any tabs beyond the tab stops given with -+ single spaces. -+ --initial -+ -i Only convert initial tabs on each line to spaces. -+ -+ David MacKenzie */ -+ -+#include -+ -+#include -+#include -+#include -+#include "system.h" -+#include "error.h" -+#include "quote.h" -+#include "xstrndup.h" -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "expand" -+ -+#define AUTHORS proper_name ("David MacKenzie") -+ -+/* If true, convert blanks even after nonblank characters have been -+ read on the line. */ -+static bool convert_entire_line; -+ -+/* If nonzero, the size of all tab stops. If zero, use `tab_list' instead. */ -+static uintmax_t tab_size; -+ -+/* Array of the explicit column numbers of the tab stops; -+ after `tab_list' is exhausted, each additional tab is replaced -+ by a space. The first column is column 0. */ -+static uintmax_t *tab_list; -+ -+/* The number of allocated entries in `tab_list'. */ -+static size_t n_tabs_allocated; -+ -+/* The index of the first invalid element of `tab_list', -+ where the next element can be added. */ -+static size_t first_free_tab; -+ -+/* Null-terminated array of input filenames. */ -+static char **file_list; -+ -+/* Default for `file_list' if no files are given on the command line. */ -+static char *stdin_argv[] = -+{ -+ (char *) "-", NULL -+}; -+ -+/* True if we have ever read standard input. */ -+static bool have_read_stdin; -+ -+/* The desired exit status. */ -+static int exit_status; -+ -+static char const shortopts[] = "it:0::1::2::3::4::5::6::7::8::9::"; -+ -+static struct option const longopts[] = -+{ -+ {"tabs", required_argument, NULL, 't'}, -+ {"initial", no_argument, NULL, 'i'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... [FILE]...\n\ -+"), -+ program_name); -+ fputs (_("\ -+Convert tabs in each FILE to spaces, writing to standard output.\n\ -+With no FILE, or when FILE is -, read standard input.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ -i, --initial do not convert tabs after non blanks\n\ -+ -t, --tabs=NUMBER have tabs NUMBER characters apart, not 8\n\ -+"), stdout); -+ fputs (_("\ -+ -t, --tabs=LIST use comma separated list of explicit tab positions\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+/* Add tab stop TABVAL to the end of `tab_list'. */ -+ -+static void -+add_tab_stop (uintmax_t tabval) -+{ -+ if (first_free_tab == n_tabs_allocated) -+ tab_list = X2NREALLOC (tab_list, &n_tabs_allocated); -+ tab_list[first_free_tab++] = tabval; -+} -+ -+/* Add the comma or blank separated list of tab stops STOPS -+ to the list of tab stops. */ -+ -+static void -+parse_tab_stops (char const *stops) -+{ -+ bool have_tabval = false; -+ uintmax_t tabval IF_LINT (= 0); -+ char const *num_start IF_LINT (= NULL); -+ bool ok = true; -+ -+ for (; *stops; stops++) -+ { -+ if (*stops == ',' || isblank (to_uchar (*stops))) -+ { -+ if (have_tabval) -+ add_tab_stop (tabval); -+ have_tabval = false; -+ } -+ else if (ISDIGIT (*stops)) -+ { -+ if (!have_tabval) -+ { -+ tabval = 0; -+ have_tabval = true; -+ num_start = stops; -+ } -+ -+ /* Detect overflow. */ -+ if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) -+ { -+ size_t len = strspn (num_start, "0123456789"); -+ char *bad_num = xstrndup (num_start, len); -+ error (0, 0, _("tab stop is too large %s"), quote (bad_num)); -+ free (bad_num); -+ ok = false; -+ stops = num_start + len - 1; -+ } -+ } -+ else -+ { -+ error (0, 0, _("tab size contains invalid character(s): %s"), -+ quote (stops)); -+ ok = false; -+ break; -+ } -+ } -+ -+ if (!ok) -+ exit (EXIT_FAILURE); -+ -+ if (have_tabval) -+ add_tab_stop (tabval); -+} -+ -+/* Check that the list of tab stops TABS, with ENTRIES entries, -+ contains only nonzero, ascending values. */ -+ -+static void -+validate_tab_stops (uintmax_t const *tabs, size_t entries) -+{ -+ uintmax_t prev_tab = 0; -+ size_t i; -+ -+ for (i = 0; i < entries; i++) -+ { -+ if (tabs[i] == 0) -+ error (EXIT_FAILURE, 0, _("tab size cannot be 0")); -+ if (tabs[i] <= prev_tab) -+ error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); -+ prev_tab = tabs[i]; -+ } -+} -+ -+/* Close the old stream pointer FP if it is non-NULL, -+ and return a new one opened to read the next input file. -+ Open a filename of `-' as the standard input. -+ Return NULL if there are no more input files. */ -+ -+static FILE * -+next_file (FILE *fp) -+{ -+ static char *prev_file; -+ char *file; -+ -+ if (fp) -+ { -+ if (ferror (fp)) -+ { -+ error (0, errno, "%s", prev_file); -+ exit_status = EXIT_FAILURE; -+ } -+ if (STREQ (prev_file, "-")) -+ clearerr (fp); /* Also clear EOF. */ -+ else if (fclose (fp) != 0) -+ { -+ error (0, errno, "%s", prev_file); -+ exit_status = EXIT_FAILURE; -+ } -+ } -+ -+ while ((file = *file_list++) != NULL) -+ { -+ if (STREQ (file, "-")) -+ { -+ have_read_stdin = true; -+ prev_file = file; -+ return stdin; -+ } -+ fp = fopen (file, "r"); -+ if (fp) -+ { -+ prev_file = file; -+ return fp; -+ } -+ error (0, errno, "%s", file); -+ exit_status = EXIT_FAILURE; -+ } -+ return NULL; -+} -+ -+/* Change tabs to spaces, writing to stdout. -+ Read each file in `file_list', in order. */ -+ -+static void -+expand (void) -+{ -+ /* Input stream. */ -+ FILE *fp = next_file (NULL); -+ -+ if (!fp) -+ return; -+ -+ for (;;) -+ { -+ /* Input character, or EOF. */ -+ int c; -+ -+ /* If true, perform translations. */ -+ bool convert = true; -+ -+ -+ /* The following variables have valid values only when CONVERT -+ is true: */ -+ -+ /* Column of next input character. */ -+ uintmax_t column = 0; -+ -+ /* 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; -+ -+ if (convert) -+ { -+ if (c == '\t') -+ { -+ /* Column the next input tab stop is on. */ -+ uintmax_t next_tab_column; -+ -+ if (tab_size) -+ next_tab_column = column + (tab_size - column % tab_size); -+ else -+ for (;;) -+ if (tab_index == first_free_tab) -+ { -+ next_tab_column = column + 1; -+ break; -+ } -+ else -+ { -+ uintmax_t tab = tab_list[tab_index++]; -+ if (column < tab) -+ { -+ next_tab_column = tab; -+ break; -+ } -+ } -+ -+ if (next_tab_column < column) -+ error (EXIT_FAILURE, 0, _("input line is too long")); -+ -+ while (++column < next_tab_column) -+ if (putchar (' ') < 0) -+ error (EXIT_FAILURE, errno, _("write error")); -+ -+ c = ' '; -+ } -+ else if (c == '\b') -+ { -+ /* Go back one column, and force recalculation of the -+ next tab stop. */ -+ column -= !!column; -+ tab_index -= !!tab_index; -+ } -+ else -+ { -+ column++; -+ if (!column) -+ error (EXIT_FAILURE, 0, _("input line is too long")); -+ } -+ -+ convert &= convert_entire_line || !! isblank (c); -+ } -+ -+ if (c < 0) -+ return; -+ -+ if (putchar (c) < 0) -+ error (EXIT_FAILURE, errno, _("write error")); -+ } -+ while (c != '\n'); -+ } -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int c; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdout); -+ -+ have_read_stdin = false; -+ exit_status = EXIT_SUCCESS; -+ convert_entire_line = true; -+ tab_list = NULL; -+ first_free_tab = 0; -+ -+ while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) -+ { -+ switch (c) -+ { -+ case 'i': -+ convert_entire_line = false; -+ break; -+ -+ case 't': -+ parse_tab_stops (optarg); -+ break; -+ -+ case '0': case '1': case '2': case '3': case '4': -+ case '5': case '6': case '7': case '8': case '9': -+ if (optarg) -+ parse_tab_stops (optarg - 1); -+ else -+ { -+ char tab_stop[2]; -+ tab_stop[0] = c; -+ tab_stop[1] = '\0'; -+ parse_tab_stops (tab_stop); -+ } -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ validate_tab_stops (tab_list, first_free_tab); -+ -+ if (first_free_tab == 0) -+ tab_size = 8; -+ else if (first_free_tab == 1) -+ tab_size = tab_list[0]; -+ else -+ tab_size = 0; -+ -+ file_list = (optind < argc ? &argv[optind] : stdin_argv); -+ -+ expand (); -+ -+ if (have_read_stdin && fclose (stdin) != 0) -+ error (EXIT_FAILURE, errno, "-"); -+ -+ exit (exit_status); -+} diff -urNp coreutils-8.0-orig/src/fold.c coreutils-8.0/src/fold.c --- coreutils-8.0-orig/src/fold.c 2009-09-23 10:25:44.000000000 +0200 +++ coreutils-8.0/src/fold.c 2009-10-07 10:07:16.000000000 +0200 @@ -2593,324 +1205,6 @@ diff -urNp coreutils-8.0-orig/src/fold.c coreutils-8.0/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.0-orig/src/fold.c.orig coreutils-8.0/src/fold.c.orig ---- coreutils-8.0-orig/src/fold.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/fold.c.orig 2009-09-23 10:25:44.000000000 +0200 -@@ -0,0 +1,314 @@ -+/* fold -- wrap each input line to fit in specified width. -+ Copyright (C) 91, 1995-2006, 2008-2009 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 David MacKenzie, djm@gnu.ai.mit.edu. */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#include "system.h" -+#include "error.h" -+#include "quote.h" -+#include "xstrtol.h" -+ -+#define TAB_WIDTH 8 -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "fold" -+ -+#define AUTHORS proper_name ("David MacKenzie") -+ -+/* 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 struct option const longopts[] = -+{ -+ {"bytes", no_argument, NULL, 'b'}, -+ {"spaces", no_argument, NULL, 's'}, -+ {"width", required_argument, NULL, 'w'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... [FILE]...\n\ -+"), -+ program_name); -+ fputs (_("\ -+Wrap input lines in each FILE (standard input by default), writing to\n\ -+standard output.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ -b, --bytes count bytes rather than columns\n\ -+ -s, --spaces break at spaces\n\ -+ -w, --width=WIDTH use WIDTH columns instead of 80\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+/* Assuming the current column is COLUMN, return the column that -+ printing C will move the cursor to. -+ The first column is 0. */ -+ -+static size_t -+adjust_column (size_t column, char c) -+{ -+ if (!count_bytes) -+ { -+ if (c == '\b') -+ { -+ if (column > 0) -+ column--; -+ } -+ else if (c == '\r') -+ column = 0; -+ else if (c == '\t') -+ column += TAB_WIDTH - column % TAB_WIDTH; -+ else /* if (isprint (c)) */ -+ column++; -+ } -+ else -+ column++; -+ return column; -+} -+ -+/* Fold file FILENAME, or standard input if FILENAME is "-", -+ to stdout, with maximum line length WIDTH. -+ Return true if successful. */ -+ -+static bool -+fold_file (char const *filename, size_t width) -+{ -+ FILE *istream; -+ int 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", filename); -+ return false; -+ } -+ -+ while ((c = getc (istream)) != EOF) -+ { -+ if (offset_out + 1 >= allocated_out) -+ line_out = X2REALLOC (line_out, &allocated_out); -+ -+ if (c == '\n') -+ { -+ line_out[offset_out++] = c; -+ fwrite (line_out, sizeof (char), offset_out, stdout); -+ column = offset_out = 0; -+ continue; -+ } -+ -+ rescan: -+ column = adjust_column (column, c); -+ -+ if (column > width) -+ { -+ /* This character would make the line too long. -+ Print the line plus a newline, and make this character -+ start the next line. */ -+ if (break_spaces) -+ { -+ bool found_blank = false; -+ size_t logical_end = offset_out; -+ -+ /* Look for the last blank. */ -+ while (logical_end) -+ { -+ --logical_end; -+ if (isblank (to_uchar (line_out[logical_end]))) -+ { -+ found_blank = true; -+ break; -+ } -+ } -+ -+ if (found_blank) -+ { -+ size_t i; -+ -+ /* Found a blank. Don't output the part after it. */ -+ logical_end++; -+ fwrite (line_out, sizeof (char), (size_t) logical_end, -+ stdout); -+ putchar ('\n'); -+ /* Move the remainder to the beginning of the next line. -+ The areas being copied here might overlap. */ -+ memmove (line_out, line_out + logical_end, -+ offset_out - logical_end); -+ offset_out -= logical_end; -+ for (column = i = 0; i < offset_out; i++) -+ column = adjust_column (column, line_out[i]); -+ goto rescan; -+ } -+ } -+ -+ if (offset_out == 0) -+ { -+ line_out[offset_out++] = c; -+ continue; -+ } -+ -+ line_out[offset_out++] = '\n'; -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); -+ column = offset_out = 0; -+ goto rescan; -+ } -+ -+ line_out[offset_out++] = c; -+ } -+ -+ saved_errno = errno; -+ -+ if (offset_out) -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); -+ -+ if (ferror (istream)) -+ { -+ error (0, saved_errno, "%s", filename); -+ if (!STREQ (filename, "-")) -+ fclose (istream); -+ return false; -+ } -+ if (!STREQ (filename, "-") && fclose (istream) == EOF) -+ { -+ error (0, errno, "%s", filename); -+ return false; -+ } -+ -+ return true; -+} -+ -+int -+main (int argc, char **argv) -+{ -+ size_t width = 80; -+ int i; -+ int optc; -+ bool ok; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdout); -+ -+ break_spaces = count_bytes = have_read_stdin = false; -+ -+ while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) -+ { -+ char optargbuf[2]; -+ -+ switch (optc) -+ { -+ case 'b': /* Count bytes rather than columns. */ -+ count_bytes = true; -+ break; -+ -+ case 's': /* Break at word boundaries. */ -+ break_spaces = true; -+ break; -+ -+ case '0': case '1': case '2': case '3': case '4': -+ case '5': case '6': case '7': case '8': case '9': -+ if (optarg) -+ optarg--; -+ else -+ { -+ optargbuf[0] = optc; -+ optargbuf[1] = '\0'; -+ optarg = optargbuf; -+ } -+ /* Fall through. */ -+ case 'w': /* Line width. */ -+ { -+ unsigned long int tmp_ulong; -+ if (! (xstrtoul (optarg, NULL, 10, &tmp_ulong, "") == LONGINT_OK -+ && 0 < tmp_ulong && tmp_ulong < SIZE_MAX - TAB_WIDTH)) -+ error (EXIT_FAILURE, 0, -+ _("invalid number of columns: %s"), quote (optarg)); -+ width = tmp_ulong; -+ } -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (argc == optind) -+ ok = fold_file ("-", width); -+ else -+ { -+ ok = true; -+ for (i = optind; i < argc; i++) -+ ok &= fold_file (argv[i], width); -+ } -+ -+ if (have_read_stdin && fclose (stdin) == EOF) -+ error (EXIT_FAILURE, errno, "-"); -+ -+ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); -+} diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c --- coreutils-8.0-orig/src/join.c 2009-09-23 10:25:44.000000000 +0200 +++ coreutils-8.0/src/join.c 2009-10-07 10:07:16.000000000 +0200 @@ -3387,1370 +1681,6 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c } break; -diff -urNp coreutils-8.0-orig/src/join.c.orig coreutils-8.0/src/join.c.orig ---- coreutils-8.0-orig/src/join.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/join.c.orig 2009-10-07 10:07:16.000000000 +0200 -@@ -0,0 +1,1360 @@ -+/* join - join lines of two files on a common field -+ Copyright (C) 91, 1995-2006, 2008-2009 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 Mike Haertel, mike@gnu.ai.mit.edu. */ -+ -+#include -+ -+#include -+#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 "error.h" -+#include "hard-locale.h" -+#include "linebuffer.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" -+ -+#define AUTHORS proper_name ("Mike Haertel") -+ -+#define join system_join -+ -+#define SWAPLINES(a, b) do { \ -+ struct line *tmp = a; \ -+ a = b; \ -+ b = tmp; \ -+} while (0); -+ -+/* An element of the list identifying which fields to print for each -+ output line. */ -+struct outlist -+ { -+ /* File number: 0, 1, or 2. 0 means use the join field. -+ 1 means use the first file argument, 2 the second. */ -+ int file; -+ -+ /* Field index (zero-based), specified only when FILE is 1 or 2. */ -+ size_t field; -+ -+ struct outlist *next; -+ }; -+ -+/* A field of a line. */ -+struct field -+ { -+ char *beg; /* First character in field. */ -+ size_t len; /* The length of the field. */ -+ }; -+ -+/* A line read from an input file. */ -+struct line -+ { -+ struct linebuffer buf; /* The line itself. */ -+ size_t nfields; /* Number of elements in `fields'. */ -+ size_t nfields_allocated; /* Number of elements allocated for `fields'. */ -+ struct field *fields; -+ }; -+ -+/* One or more consecutive lines read from a file that all have the -+ same join field value. */ -+struct seq -+ { -+ size_t count; /* Elements used in `lines'. */ -+ size_t alloc; /* Elements allocated in `lines'. */ -+ struct line **lines; -+ }; -+ -+/* The previous line read from each file. */ -+static struct line *prevline[2] = {NULL, NULL}; -+ -+/* This provides an extra line buffer for each file. We need these if we -+ try to read two consecutive lines into the same buffer, since we don't -+ want to overwrite the previous buffer before we check order. */ -+static struct line *spareline[2] = {NULL, NULL}; -+ -+/* True if the LC_COLLATE locale is hard. */ -+static bool hard_LC_COLLATE; -+ -+/* If nonzero, print unpairable lines in file 1 or 2. */ -+static bool print_unpairables_1, print_unpairables_2; -+ -+/* If nonzero, print pairable lines. */ -+static bool print_pairables; -+ -+/* If nonzero, we have seen at least one unpairable line. */ -+static bool seen_unpairable; -+ -+/* If nonzero, we have warned about disorder in that file. */ -+static bool issued_disorder_warning[2]; -+ -+/* Empty output field filler. */ -+static char const *empty_filler; -+ -+/* Field to join on; SIZE_MAX means they haven't been determined yet. */ -+static size_t join_field_1 = SIZE_MAX; -+static size_t join_field_2 = SIZE_MAX; -+ -+/* List of fields to print. */ -+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 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 -+ { -+ CHECK_ORDER_DEFAULT, -+ CHECK_ORDER_ENABLED, -+ CHECK_ORDER_DISABLED -+ } check_input_order; -+ -+enum -+{ -+ CHECK_ORDER_OPTION = CHAR_MAX + 1, -+ NOCHECK_ORDER_OPTION -+}; -+ -+ -+static struct option const longopts[] = -+{ -+ {"ignore-case", no_argument, NULL, 'i'}, -+ {"check-order", no_argument, NULL, CHECK_ORDER_OPTION}, -+ {"nocheck-order", no_argument, NULL, NOCHECK_ORDER_OPTION}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+/* Used to print non-joining lines */ -+static struct line uni_blank; -+ -+/* If nonzero, ignore case when comparing join fields. */ -+static bool ignore_case; -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... FILE1 FILE2\n\ -+"), -+ program_name); -+ fputs (_("\ -+For each pair of input lines with identical join fields, write a line to\n\ -+standard output. The default join field is the first, delimited\n\ -+by whitespace. When FILE1 or FILE2 (not both) is -, read standard input.\n\ -+\n\ -+ -a FILENUM print unpairable lines coming from file FILENUM, where\n\ -+ FILENUM is 1 or 2, corresponding to FILE1 or FILE2\n\ -+ -e EMPTY replace missing input fields with EMPTY\n\ -+"), stdout); -+ fputs (_("\ -+ -i, --ignore-case ignore differences in case when comparing fields\n\ -+ -j FIELD equivalent to `-1 FIELD -2 FIELD'\n\ -+ -o FORMAT obey FORMAT while constructing output line\n\ -+ -t CHAR use CHAR as input and output field separator\n\ -+"), stdout); -+ fputs (_("\ -+ -v FILENUM like -a FILENUM, but suppress joined output lines\n\ -+ -1 FIELD join on this FIELD of file 1\n\ -+ -2 FIELD join on this FIELD of file 2\n\ -+ --check-order check that the input is correctly sorted, even\n\ -+ if all input lines are pairable\n\ -+ --nocheck-order do not check that the input is correctly sorted\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ fputs (_("\ -+\n\ -+Unless -t CHAR is given, leading blanks separate fields and are ignored,\n\ -+else fields are separated by CHAR. Any FIELD is a field number counted\n\ -+from 1. FORMAT is one or more comma or blank separated specifications,\n\ -+each being `FILENUM.FIELD' or `0'. Default FORMAT outputs the join field,\n\ -+the remaining fields from FILE1, the remaining fields from FILE2, all\n\ -+separated by CHAR.\n\ -+\n\ -+Important: FILE1 and FILE2 must be sorted on the join fields.\n\ -+E.g., use `sort -k 1b,1' if `join' has no options.\n\ -+Note, comparisons honor the rules specified by `LC_COLLATE'.\n\ -+If the input is not sorted and some lines cannot be joined, a\n\ -+warning message will be given.\n\ -+"), stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+/* Record a field in LINE, with location FIELD and size LEN. */ -+ -+static void -+extract_field (struct line *line, char *field, size_t len) -+{ -+ if (line->nfields >= line->nfields_allocated) -+ { -+ line->fields = X2NREALLOC (line->fields, &line->nfields_allocated); -+ } -+ line->fields[line->nfields].beg = field; -+ line->fields[line->nfields].len = len; -+ ++(line->nfields); -+} -+ -+/* Fill in the `fields' structure in LINE. */ -+ -+static void -+xfields (struct line *line) -+{ -+ char *ptr = line->buf.buffer; -+ char const *lim = ptr + line->buf.length - 1; -+ -+ if (ptr == lim) -+ return; -+ -+ if (tab != NULL) -+ { -+ unsigned char t = tab[0]; -+ char *sep; -+ for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) -+ extract_field (line, ptr, sep - ptr); -+ } -+ else -+ { -+ /* Skip leading blanks before the first field. */ -+ while (isblank (to_uchar (*ptr))) -+ if (++ptr == lim) -+ return; -+ -+ do -+ { -+ char *sep; -+ for (sep = ptr + 1; sep != lim && ! isblank (to_uchar (*sep)); sep++) -+ continue; -+ extract_field (line, ptr, sep - ptr); -+ if (sep == lim) -+ return; -+ for (ptr = sep + 1; ptr != lim && isblank (to_uchar (*ptr)); ptr++) -+ continue; -+ } -+ while (ptr != lim); -+ } -+ -+ 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) -+ { -+ unsigned char t = tab[0]; -+ 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)) -+ 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)) -+ 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)) -+ break; -+ -+ ptr += mblength; -+ } -+ } -+ while (ptr < lim); -+ } -+ -+ extract_field (line, ptr, lim - ptr); -+} -+#endif -+ -+static void -+freeline (struct line *line) -+{ -+ free (line->fields); -+ free (line->buf.buffer); -+ line->buf.buffer = NULL; -+} -+ -+/* Return <0 if the join field in LINE1 compares less than the one in LINE2; -+ >0 if it compares greater; 0 if it compares equal. -+ Report an error and exit if the comparison fails. -+ Use join fields JF_1 and JF_2 respectively. */ -+ -+static int -+keycmp (struct line const *line1, struct line const *line2, -+ size_t jf_1, size_t jf_2) -+{ -+ /* Start of field to compare in each file. */ -+ char *beg[2]; -+ char *copy[2]; -+ size_t len[2]; /* Length of fields to compare. */ -+ int diff; -+ int i, j; -+ -+ if (jf_1 < line1->nfields) -+ { -+ beg[0] = line1->fields[jf_1].beg; -+ len[0] = line1->fields[jf_1].len; -+ } -+ else -+ { -+ beg[0] = NULL; -+ len[0] = 0; -+ } -+ -+ if (jf_2 < line2->nfields) -+ { -+ beg[1] = line2->fields[jf_2].beg; -+ len[1] = line2->fields[jf_2].len; -+ } -+ else -+ { -+ beg[1] = NULL; -+ len[1] = 0; -+ } -+ -+ if (len[0] == 0) -+ return len[1] == 0 ? 0 : -1; -+ if (len[1] == 0) -+ return 1; -+ -+ if (ignore_case) -+ { -+#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++) -+ { -+ copy[i] = alloca (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; -+ -+ memset (&state_wc, '\0', sizeof (mbstate_t)); -+ wcrtomb (copy[i] + j, uwc, &state_wc); -+ } -+ else -+ memcpy (copy[i] + j, beg[i] + j, mblength); -+ } -+ j += mblength; -+ } -+ copy[i][j] = '\0'; -+ } -+ } -+ else -+#endif -+ { -+ for (i = 0; i < 2; i++) -+ { -+ copy[i] = alloca (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 -+ { -+ copy[0] = (unsigned char *) beg[0]; -+ copy[1] = (unsigned char *) beg[1]; -+ } -+ -+ if (hard_LC_COLLATE) -+ return xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); -+ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); -+ -+ -+ if (diff) -+ return diff; -+ return len[0] - len[1]; -+} -+ -+/* Check that successive input lines PREV and CURRENT from input file -+ WHATFILE are presented in order, unless the user may be relying on -+ the GNU extension that input lines may be out of order if no input -+ lines are unpairable. -+ -+ If the user specified --nocheck-order, the check is not made. -+ If the user specified --check-order, the problem is fatal. -+ Otherwise (the default), the message is simply a warning. -+ -+ A message is printed at most once per input file. */ -+ -+static void -+check_order (const struct line *prev, -+ const struct line *current, -+ int whatfile) -+{ -+ if (check_input_order != CHECK_ORDER_DISABLED -+ && ((check_input_order == CHECK_ORDER_ENABLED) || seen_unpairable)) -+ { -+ if (!issued_disorder_warning[whatfile-1]) -+ { -+ size_t join_field = whatfile == 1 ? join_field_1 : join_field_2; -+ if (keycmp (prev, current, join_field, join_field) > 0) -+ { -+ error ((check_input_order == CHECK_ORDER_ENABLED -+ ? EXIT_FAILURE : 0), -+ 0, _("file %d is not in sorted order"), whatfile); -+ -+ /* If we get to here, the message was just a warning, but we -+ want only to issue it once. */ -+ issued_disorder_warning[whatfile-1] = true; -+ } -+ } -+ } -+} -+ -+static inline void -+reset_line (struct line *line) -+{ -+ line->nfields = 0; -+} -+ -+static struct line * -+init_linep (struct line **linep) -+{ -+ struct line *line = xmalloc (sizeof *line); -+ memset (line, '\0', sizeof *line); -+ *linep = line; -+ return line; -+} -+ -+/* Read a line from FP into LINE and split it into fields. -+ Return true if successful. */ -+ -+static bool -+get_line (FILE *fp, struct line **linep, int which) -+{ -+ struct line *line = *linep; -+ -+ if (line == prevline[which - 1]) -+ { -+ SWAPLINES (line, spareline[which - 1]); -+ *linep = line; -+ } -+ -+ if (line) -+ reset_line (line); -+ else -+ line = init_linep (linep); -+ -+ if (! readlinebuffer (&line->buf, fp)) -+ { -+ if (ferror (fp)) -+ error (EXIT_FAILURE, errno, _("read error")); -+ freeline (line); -+ return false; -+ } -+ -+ xfields (line); -+ -+ if (prevline[which - 1]) -+ check_order (prevline[which - 1], line, which); -+ -+ prevline[which - 1] = line; -+ return true; -+} -+ -+static void -+free_spareline (void) -+{ -+ size_t i; -+ -+ for (i = 0; i < ARRAY_CARDINALITY (spareline); i++) -+ { -+ if (spareline[i]) -+ { -+ freeline (spareline[i]); -+ free (spareline[i]); -+ } -+ } -+} -+ -+static void -+initseq (struct seq *seq) -+{ -+ seq->count = 0; -+ seq->alloc = 0; -+ seq->lines = NULL; -+} -+ -+/* Read a line from FP and add it to SEQ. Return true if successful. */ -+ -+static bool -+getseq (FILE *fp, struct seq *seq, int whichfile) -+{ -+ if (seq->count == seq->alloc) -+ { -+ size_t i; -+ seq->lines = X2NREALLOC (seq->lines, &seq->alloc); -+ for (i = seq->count; i < seq->alloc; i++) -+ seq->lines[i] = NULL; -+ } -+ -+ if (get_line (fp, &seq->lines[seq->count], whichfile)) -+ { -+ ++seq->count; -+ return true; -+ } -+ return false; -+} -+ -+/* Read a line from FP and add it to SEQ, as the first item if FIRST is -+ true, else as the next. */ -+static bool -+advance_seq (FILE *fp, struct seq *seq, bool first, int whichfile) -+{ -+ if (first) -+ seq->count = 0; -+ -+ return getseq (fp, seq, whichfile); -+} -+ -+static void -+delseq (struct seq *seq) -+{ -+ size_t i; -+ for (i = 0; i < seq->alloc; i++) -+ if (seq->lines[i]) -+ { -+ if (seq->lines[i]->buf.buffer) -+ freeline (seq->lines[i]); -+ free (seq->lines[i]); -+ } -+ free (seq->lines); -+} -+ -+ -+/* Print field N of LINE if it exists and is nonempty, otherwise -+ `empty_filler' if it is nonempty. */ -+ -+static void -+prfield (size_t n, struct line const *line) -+{ -+ size_t len; -+ -+ if (n < line->nfields) -+ { -+ len = line->fields[n].len; -+ if (len) -+ fwrite (line->fields[n].beg, 1, len, stdout); -+ else if (empty_filler) -+ fputs (empty_filler, stdout); -+ } -+ else if (empty_filler) -+ fputs (empty_filler, stdout); -+} -+ -+/* Print the join of LINE1 and LINE2. */ -+ -+#define PUT_TAB_CHAR \ -+ do \ -+ { \ -+ (tab != NULL) ? \ -+ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ -+ } \ -+ while (0) -+ -+static void -+prjoin (struct line const *line1, struct line const *line2) -+{ -+ const struct outlist *outlist; -+ -+ outlist = outlist_head.next; -+ if (outlist) -+ { -+ const struct outlist *o; -+ -+ o = outlist; -+ while (1) -+ { -+ size_t field; -+ struct line const *line; -+ -+ if (o->file == 0) -+ { -+ if (line1 == &uni_blank) -+ { -+ line = line2; -+ field = join_field_2; -+ } -+ else -+ { -+ line = line1; -+ field = join_field_1; -+ } -+ } -+ else -+ { -+ line = (o->file == 1 ? line1 : line2); -+ field = o->field; -+ } -+ prfield (field, line); -+ o = o->next; -+ if (o == NULL) -+ break; -+ PUT_TAB_CHAR; -+ } -+ putchar ('\n'); -+ } -+ else -+ { -+ size_t i; -+ -+ if (line1 == &uni_blank) -+ { -+ struct line const *t; -+ t = line1; -+ line1 = line2; -+ line2 = t; -+ } -+ prfield (join_field_1, line1); -+ for (i = 0; i < join_field_1 && i < line1->nfields; ++i) -+ { -+ PUT_TAB_CHAR; -+ prfield (i, line1); -+ } -+ for (i = join_field_1 + 1; i < line1->nfields; ++i) -+ { -+ PUT_TAB_CHAR; -+ prfield (i, line1); -+ } -+ -+ for (i = 0; i < join_field_2 && i < line2->nfields; ++i) -+ { -+ PUT_TAB_CHAR; -+ prfield (i, line2); -+ } -+ for (i = join_field_2 + 1; i < line2->nfields; ++i) -+ { -+ PUT_TAB_CHAR; -+ prfield (i, line2); -+ } -+ putchar ('\n'); -+ } -+} -+ -+/* Print the join of the files in FP1 and FP2. */ -+ -+static void -+join (FILE *fp1, FILE *fp2) -+{ -+ struct seq seq1, seq2; -+ struct line **linep = xmalloc (sizeof *linep); -+ int diff; -+ bool eof1, eof2, checktail; -+ -+ *linep = NULL; -+ -+ /* Read the first line of each file. */ -+ initseq (&seq1); -+ getseq (fp1, &seq1, 1); -+ initseq (&seq2); -+ getseq (fp2, &seq2, 2); -+ -+ while (seq1.count && seq2.count) -+ { -+ size_t i; -+ diff = keycmp (seq1.lines[0], seq2.lines[0], -+ join_field_1, join_field_2); -+ if (diff < 0) -+ { -+ if (print_unpairables_1) -+ prjoin (seq1.lines[0], &uni_blank); -+ advance_seq (fp1, &seq1, true, 1); -+ seen_unpairable = true; -+ continue; -+ } -+ if (diff > 0) -+ { -+ if (print_unpairables_2) -+ prjoin (&uni_blank, seq2.lines[0]); -+ advance_seq (fp2, &seq2, true, 2); -+ seen_unpairable = true; -+ continue; -+ } -+ -+ /* Keep reading lines from file1 as long as they continue to -+ match the current line from file2. */ -+ eof1 = false; -+ do -+ if (!advance_seq (fp1, &seq1, false, 1)) -+ { -+ eof1 = true; -+ ++seq1.count; -+ break; -+ } -+ while (!keycmp (seq1.lines[seq1.count - 1], seq2.lines[0], -+ join_field_1, join_field_2)); -+ -+ /* Keep reading lines from file2 as long as they continue to -+ match the current line from file1. */ -+ eof2 = false; -+ do -+ if (!advance_seq (fp2, &seq2, false, 2)) -+ { -+ eof2 = true; -+ ++seq2.count; -+ break; -+ } -+ while (!keycmp (seq1.lines[0], seq2.lines[seq2.count - 1], -+ join_field_1, join_field_2)); -+ -+ if (print_pairables) -+ { -+ for (i = 0; i < seq1.count - 1; ++i) -+ { -+ size_t j; -+ for (j = 0; j < seq2.count - 1; ++j) -+ prjoin (seq1.lines[i], seq2.lines[j]); -+ } -+ } -+ -+ if (!eof1) -+ { -+ SWAPLINES (seq1.lines[0], seq1.lines[seq1.count - 1]); -+ seq1.count = 1; -+ } -+ else -+ seq1.count = 0; -+ -+ if (!eof2) -+ { -+ SWAPLINES (seq2.lines[0], seq2.lines[seq2.count - 1]); -+ seq2.count = 1; -+ } -+ else -+ seq2.count = 0; -+ } -+ -+ /* If the user did not specify --check-order, and the we read the -+ tail ends of both inputs to verify that they are in order. We -+ skip the rest of the tail once we have issued a warning for that -+ file, unless we actually need to print the unpairable lines. */ -+ if (check_input_order != CHECK_ORDER_DISABLED -+ && !(issued_disorder_warning[0] && issued_disorder_warning[1])) -+ checktail = true; -+ else -+ checktail = false; -+ -+ if ((print_unpairables_1 || checktail) && seq1.count) -+ { -+ if (print_unpairables_1) -+ prjoin (seq1.lines[0], &uni_blank); -+ seen_unpairable = true; -+ while (get_line (fp1, linep, 1)) -+ { -+ if (print_unpairables_1) -+ prjoin (*linep, &uni_blank); -+ if (issued_disorder_warning[0] && !print_unpairables_1) -+ break; -+ } -+ } -+ -+ if ((print_unpairables_2 || checktail) && seq2.count) -+ { -+ if (print_unpairables_2) -+ prjoin (&uni_blank, seq2.lines[0]); -+ seen_unpairable = true; -+ while (get_line (fp2, linep, 2)) -+ { -+ if (print_unpairables_2) -+ prjoin (&uni_blank, *linep); -+ if (issued_disorder_warning[1] && !print_unpairables_2) -+ break; -+ } -+ } -+ -+ free (*linep); -+ -+ free (linep); -+ delseq (&seq1); -+ delseq (&seq2); -+} -+ -+/* Add a field spec for field FIELD of file FILE to `outlist'. */ -+ -+static void -+add_field (int file, size_t field) -+{ -+ struct outlist *o; -+ -+ assert (file == 0 || file == 1 || file == 2); -+ assert (file != 0 || field == 0); -+ -+ o = xmalloc (sizeof *o); -+ o->file = file; -+ o->field = field; -+ o->next = NULL; -+ -+ /* Add to the end of the list so the fields are in the right order. */ -+ outlist_end->next = o; -+ outlist_end = o; -+} -+ -+/* Convert a string of decimal digits, STR (the 1-based join field number), -+ to an integral value. Upon successful conversion, return one less -+ (the zero-based field number). Silently convert too-large values -+ to SIZE_MAX - 1. Otherwise, if a value cannot be converted, give a -+ diagnostic and exit. */ -+ -+static size_t -+string_to_join_field (char const *str) -+{ -+ size_t result; -+ unsigned long int val; -+ verify (SIZE_MAX <= ULONG_MAX); -+ -+ strtol_error s_err = xstrtoul (str, NULL, 10, &val, ""); -+ if (s_err == LONGINT_OVERFLOW || (s_err == LONGINT_OK && SIZE_MAX < val)) -+ val = SIZE_MAX; -+ else if (s_err != LONGINT_OK || val == 0) -+ error (EXIT_FAILURE, 0, _("invalid field number: %s"), quote (str)); -+ -+ result = val - 1; -+ -+ return result; -+} -+ -+/* Convert a single field specifier string, S, to a *FILE_INDEX, *FIELD_INDEX -+ pair. In S, the field index string is 1-based; *FIELD_INDEX is zero-based. -+ If S is valid, return true. Otherwise, give a diagnostic and exit. */ -+ -+static void -+decode_field_spec (const char *s, int *file_index, size_t *field_index) -+{ -+ /* The first character must be 0, 1, or 2. */ -+ switch (s[0]) -+ { -+ case '0': -+ if (s[1]) -+ { -+ /* `0' must be all alone -- no `.FIELD'. */ -+ error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s)); -+ } -+ *file_index = 0; -+ *field_index = 0; -+ break; -+ -+ case '1': -+ case '2': -+ if (s[1] != '.') -+ error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s)); -+ *file_index = s[0] - '0'; -+ *field_index = string_to_join_field (s + 2); -+ break; -+ -+ default: -+ error (EXIT_FAILURE, 0, -+ _("invalid file number in field spec: %s"), quote (s)); -+ -+ /* Tell gcc -W -Wall that we can't get beyond this point. -+ This avoids a warning (otherwise legit) that the caller's copies -+ of *file_index and *field_index might be used uninitialized. */ -+ abort (); -+ -+ break; -+ } -+} -+ -+/* Add the comma or blank separated field spec(s) in STR to `outlist'. */ -+ -+static void -+add_field_list (char *str) -+{ -+ char *p = str; -+ -+ do -+ { -+ int file_index; -+ size_t field_index; -+ char const *spec_item = p; -+ -+ p = strpbrk (p, ", \t"); -+ if (p) -+ *p++ = '\0'; -+ decode_field_spec (spec_item, &file_index, &field_index); -+ add_field (file_index, field_index); -+ } -+ while (p); -+} -+ -+/* Set the join field *VAR to VAL, but report an error if *VAR is set -+ more than once to incompatible values. */ -+ -+static void -+set_join_field (size_t *var, size_t val) -+{ -+ if (*var != SIZE_MAX && *var != val) -+ { -+ unsigned long int var1 = *var + 1; -+ unsigned long int val1 = val + 1; -+ error (EXIT_FAILURE, 0, _("incompatible join fields %lu, %lu"), -+ var1, val1); -+ } -+ *var = val; -+} -+ -+/* Status of command-line arguments. */ -+ -+enum operand_status -+ { -+ /* This argument must be an operand, i.e., one of the files to be -+ joined. */ -+ MUST_BE_OPERAND, -+ -+ /* This might be the argument of the preceding -j1 or -j2 option, -+ or it might be an operand. */ -+ MIGHT_BE_J1_ARG, -+ MIGHT_BE_J2_ARG, -+ -+ /* This might be the argument of the preceding -o option, or it might be -+ an operand. */ -+ MIGHT_BE_O_ARG -+ }; -+ -+/* Add NAME to the array of input file NAMES with operand statuses -+ OPERAND_STATUS; currently there are NFILES names in the list. */ -+ -+static void -+add_file_name (char *name, char *names[2], -+ int operand_status[2], int joption_count[2], int *nfiles, -+ int *prev_optc_status, int *optc_status) -+{ -+ int n = *nfiles; -+ -+ if (n == 2) -+ { -+ bool op0 = (operand_status[0] == MUST_BE_OPERAND); -+ char *arg = names[op0]; -+ switch (operand_status[op0]) -+ { -+ case MUST_BE_OPERAND: -+ error (0, 0, _("extra operand %s"), quote (name)); -+ usage (EXIT_FAILURE); -+ -+ case MIGHT_BE_J1_ARG: -+ joption_count[0]--; -+ set_join_field (&join_field_1, string_to_join_field (arg)); -+ break; -+ -+ case MIGHT_BE_J2_ARG: -+ joption_count[1]--; -+ set_join_field (&join_field_2, string_to_join_field (arg)); -+ break; -+ -+ case MIGHT_BE_O_ARG: -+ add_field_list (arg); -+ break; -+ } -+ if (!op0) -+ { -+ operand_status[0] = operand_status[1]; -+ names[0] = names[1]; -+ } -+ n = 1; -+ } -+ -+ operand_status[n] = *prev_optc_status; -+ names[n] = name; -+ *nfiles = n + 1; -+ if (*prev_optc_status == MIGHT_BE_O_ARG) -+ *optc_status = MIGHT_BE_O_ARG; -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int optc_status; -+ int prev_optc_status = MUST_BE_OPERAND; -+ int operand_status[2]; -+ int joption_count[2] = { 0, 0 }; -+ char *names[2]; -+ FILE *fp1, *fp2; -+ int optc; -+ int nfiles = 0; -+ int i; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ hard_LC_COLLATE = hard_locale (LC_COLLATE); -+ -+ atexit (close_stdout); -+ atexit (free_spareline); -+ -+ print_pairables = true; -+ seen_unpairable = false; -+ issued_disorder_warning[0] = issued_disorder_warning[1] = false; -+ check_input_order = CHECK_ORDER_DEFAULT; -+ -+ while ((optc = getopt_long (argc, argv, "-a:e:i1:2:j:o:t:v:", -+ longopts, NULL)) -+ != -1) -+ { -+ optc_status = MUST_BE_OPERAND; -+ -+ switch (optc) -+ { -+ case 'v': -+ print_pairables = false; -+ /* Fall through. */ -+ -+ case 'a': -+ { -+ unsigned long int val; -+ if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK -+ || (val != 1 && val != 2)) -+ error (EXIT_FAILURE, 0, -+ _("invalid field number: %s"), quote (optarg)); -+ if (val == 1) -+ print_unpairables_1 = true; -+ else -+ print_unpairables_2 = true; -+ } -+ break; -+ -+ case 'e': -+ if (empty_filler && ! STREQ (empty_filler, optarg)) -+ error (EXIT_FAILURE, 0, -+ _("conflicting empty-field replacement strings")); -+ empty_filler = optarg; -+ break; -+ -+ case 'i': -+ ignore_case = true; -+ break; -+ -+ case '1': -+ set_join_field (&join_field_1, string_to_join_field (optarg)); -+ break; -+ -+ case '2': -+ set_join_field (&join_field_2, string_to_join_field (optarg)); -+ break; -+ -+ case 'j': -+ if ((optarg[0] == '1' || optarg[0] == '2') && !optarg[1] -+ && optarg == argv[optind - 1] + 2) -+ { -+ /* The argument was either "-j1" or "-j2". */ -+ bool is_j2 = (optarg[0] == '2'); -+ joption_count[is_j2]++; -+ optc_status = MIGHT_BE_J1_ARG + is_j2; -+ } -+ else -+ { -+ set_join_field (&join_field_1, string_to_join_field (optarg)); -+ set_join_field (&join_field_2, join_field_1); -+ } -+ break; -+ -+ case 'o': -+ add_field_list (optarg); -+ optc_status = MIGHT_BE_O_ARG; -+ break; -+ -+ case 't': -+ { -+ char *newtab; -+ size_t newtablen; -+ if (! optarg[0]) -+ error (EXIT_FAILURE, 0, _("empty tab")); -+ 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 (newtablen == 1 && newtab[1]) -+ { -+ if (STREQ (newtab, "\\0")) -+ newtab[0] = '\0'; -+ } -+ if (tab != NULL && strcmp (tab, newtab)) -+ { -+ free (newtab); -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); -+ } -+ tab = newtab; -+ tablen = newtablen; -+ } -+ break; -+ -+ case NOCHECK_ORDER_OPTION: -+ check_input_order = CHECK_ORDER_DISABLED; -+ break; -+ -+ case CHECK_ORDER_OPTION: -+ check_input_order = CHECK_ORDER_ENABLED; -+ break; -+ -+ case 1: /* Non-option argument. */ -+ add_file_name (optarg, names, operand_status, joption_count, -+ &nfiles, &prev_optc_status, &optc_status); -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ -+ prev_optc_status = optc_status; -+ } -+ -+ /* Process any operands after "--". */ -+ prev_optc_status = MUST_BE_OPERAND; -+ while (optind < argc) -+ add_file_name (argv[optind++], names, operand_status, joption_count, -+ &nfiles, &prev_optc_status, &optc_status); -+ -+ if (nfiles != 2) -+ { -+ if (nfiles == 0) -+ error (0, 0, _("missing operand")); -+ else -+ error (0, 0, _("missing operand after %s"), quote (argv[argc - 1])); -+ usage (EXIT_FAILURE); -+ } -+ -+ /* If "-j1" was specified and it turns out not to have had an argument, -+ treat it as "-j 1". Likewise for -j2. */ -+ for (i = 0; i < 2; i++) -+ if (joption_count[i] != 0) -+ { -+ set_join_field (&join_field_1, i); -+ set_join_field (&join_field_2, i); -+ } -+ -+ if (join_field_1 == SIZE_MAX) -+ join_field_1 = 0; -+ if (join_field_2 == SIZE_MAX) -+ join_field_2 = 0; -+ -+ fp1 = STREQ (names[0], "-") ? stdin : fopen (names[0], "r"); -+ if (!fp1) -+ error (EXIT_FAILURE, errno, "%s", names[0]); -+ fp2 = STREQ (names[1], "-") ? stdin : fopen (names[1], "r"); -+ if (!fp2) -+ error (EXIT_FAILURE, errno, "%s", names[1]); -+ if (fp1 == fp2) -+ error (EXIT_FAILURE, errno, _("both files cannot be standard input")); -+ join (fp1, fp2); -+ -+ if (fclose (fp1) != 0) -+ error (EXIT_FAILURE, errno, "%s", names[0]); -+ if (fclose (fp2) != 0) -+ error (EXIT_FAILURE, errno, "%s", names[1]); -+ -+ if (issued_disorder_warning[0] || issued_disorder_warning[1]) -+ exit (EXIT_FAILURE); -+ else -+ exit (EXIT_SUCCESS); -+} diff -urNp coreutils-8.0-orig/src/pr.c coreutils-8.0/src/pr.c --- coreutils-8.0-orig/src/pr.c 2009-09-29 15:27:54.000000000 +0200 +++ coreutils-8.0/src/pr.c 2009-10-07 10:07:16.000000000 +0200 @@ -5476,2887 +2406,6 @@ diff -urNp coreutils-8.0-orig/src/pr.c coreutils-8.0/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.0-orig/src/pr.c.orig coreutils-8.0/src/pr.c.orig ---- coreutils-8.0-orig/src/pr.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/pr.c.orig 2009-09-29 15:27:54.000000000 +0200 -@@ -0,0 +1,2877 @@ -+/* pr -- convert text files for printing. -+ Copyright (C) 88, 91, 1995-2009 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 . */ -+ -+/* By Pete TerMaat, with considerable refinement by Roland Huebner. */ -+ -+/* Things to watch: Sys V screws up on ... -+ pr -n -3 -s: /usr/dict/words -+ pr -m -o10 -n /usr/dict/words{,,,} -+ pr -6 -a -n -o5 /usr/dict/words -+ -+ Ideas: -+ -+ Keep a things_to_do list of functions to call when we know we have -+ something to print. Cleaner than current series of checks. -+ -+ Improve the printing of control prefixes. -+ -+ Expand the file name in the centered header line to a full file name. -+ -+ -+ Concept: -+ -+ If the input_tab_char differs from the default value TAB -+ (`-e[CHAR[...]]' is used), any input text tab is expanded to the -+ default width of 8 spaces (compare char_to_clump). - Same as SunOS -+ does. -+ -+ The treatment of the number_separator (compare add_line_number): -+ The default value TAB of the number_separator (`-n[SEP[...]]') doesn't -+ be thought to be an input character. An optional `-e'-input has no -+ effect. -+ - With single column output -+ only one POSIX requirement has to be met: -+ The default n-separator should be a TAB. The consequence is a -+ different width between the number and the text if the output position -+ of the separator changes, i.e. it depends upon the left margin used. -+ That's not nice but easy-to-use together with the defaults of other -+ utilities, e.g. sort or cut. - Same as SunOS does. -+ - With multicolumn output -+ two conflicting POSIX requirements exist: -+ First `default n-separator is TAB', second `output text columns shall -+ be of equal width'. Moreover POSIX specifies the number+separator a -+ part of the column, together with `-COLUMN' and `-a -COLUMN'. -+ (With -m output the number shall occupy each line only once. Exactly -+ the same situation as single column output exists.) -+ GNU pr gives priority to the 2nd requirement and observes POSIX -+ column definition. The n-separator TAB is expanded to the same number -+ of spaces in each column using the default value 8. Tabification is -+ only performed if it is compatible with the output position. -+ Consequence: The output text columns are of equal width. The layout -+ of a page does not change if the left margin varies. - Looks better -+ than the SunOS approach. -+ SunOS pr gives priority to the 1st requirement. n-separator TAB -+ width varies with each column. Only the width of text part of the -+ column is fixed. -+ Consequence: The output text columns don't have equal width. The -+ widths and the layout of the whole page varies with the left margin. -+ An overflow of the line length (without margin) over the input value -+ PAGE_WIDTH may occur. -+ -+ The interference of the POSIX-compliant small letter options -w and -s: -+ (`interference' means `setting a _separator_ with -s switches off the -+ column structure and the default - not generally - page_width, -+ acts on -w option') -+ options: text form / separator: equivalent new options: -+ -w l -s[x] -+ -------------------------------------------------------------------- -+ 1. -- -- columns / space -- -+ trunc. to page_width = 72 -+ 2. -- -s[:] full lines / TAB[:] -J --sep-string[=""|:] -+ no truncation -+ 3. -w l -- columns / space -W l -+ trunc. to page_width = l -+ 4. -w l -s[:] columns / no sep.[:] -W l --sep-string[=:] -+ trunc. to page_width = l -+ -------------------------------------------------------------------- -+ -+ -+ Options: -+ -+ Including version 1.22i: -+ Some SMALL LETTER options have been redefined with the object of a -+ better POSIX compliance. The output of some further cases has been -+ adapted to other UNIXes. A violation of downward compatibility has to -+ be accepted. -+ Some NEW CAPITAL LETTER options ( -J, -S, -W) has been introduced to -+ turn off unexpected interferences of small letter options (-s and -w -+ together with the three column options). -+ -N option and the second argument LAST_PAGE of +FIRST_PAGE offer more -+ flexibility; The detailed handling of form feeds set in the input -+ files requires -T option. -+ -+ Capital letter options dominate small letter ones. -+ -+ Some of the option-arguments cannot be specified as separate arguments -+ from the preceding option letter (already stated in POSIX specification). -+ -+ Form feeds in the input cause page breaks in the output. Multiple -+ form feeds produce empty pages. -+ -+ +FIRST_PAGE[:LAST_PAGE], --pages=FIRST_PAGE[:LAST_PAGE] -+ begin [stop] printing with page FIRST_[LAST_]PAGE -+ -+ -COLUMN, --columns=COLUMN -+ Produce output that is COLUMN columns wide and -+ print columns down, unless -a is used. Balance number of -+ lines in the columns on each page. -+ -+ -a, --across Print columns across rather than down, used -+ together with -COLUMN. The input -+ one -+ two -+ three -+ four -+ will be printed with `-a -3' as -+ one two three -+ four -+ -+ -b Balance columns on the last page. -+ -b is no longer an independent option. It's always used -+ together with -COLUMN (unless -a is used) to get a -+ consistent formulation with "FF set by hand" in input -+ files. Each formfeed found terminates the number of lines -+ to be read with the actual page. The situation for -+ printing columns down is equivalent to that on the last -+ page. So we need a balancing. -+ -+ Keeping -b as an underground option guarantees some -+ downward compatibility. Utilities using pr with -b -+ (a most frequently used form) still work as usual. -+ -+ -c, --show-control-chars -+ Print unprintable characters as control prefixes. -+ Control-g is printed as ^G (use hat notation) and -+ octal backslash notation. -+ -+ -d, --double-space Double space the output. -+ -+ -D FORMAT, --date-format=FORMAT Use FORMAT for the header date. -+ -+ -e[CHAR[WIDTH]], --expand-tabs[=CHAR[WIDTH]] -+ Expand tabs to spaces on input. Optional argument CHAR -+ is the input TAB character. (Default is TAB). Optional -+ argument WIDTH is the input TAB character's width. -+ (Default is 8.) -+ -+ -F, -f, --form-feed Use formfeeds instead of newlines to separate -+ pages. A three line HEADER is used, no TRAILER with -F, -+ without -F both HEADER and TRAILER are made of five lines. -+ -+ -h HEADER, --header=HEADER -+ Replace the filename in the header with the string HEADER. -+ A centered header is used. -+ -+ -i[CHAR[WIDTH]], --output-tabs[=CHAR[WIDTH]] -+ Replace spaces with tabs on output. Optional argument -+ CHAR is the output TAB character. (Default is TAB). -+ Optional argument WIDTH is the output TAB character's -+ width. (Default is 8) -+ -+ -J, --join-lines Merge lines of full length, turns off -W/-w -+ line truncation, no column alignment, --sep-string[=STRING] -+ sets separators, works with all column options -+ (-COLUMN | -a -COLUMN | -m). -+ -J has been introduced (together with -W and --sep-string) to -+ disentangle the old (POSIX compliant) options -w, -s -+ along with the 3 column options. -+ -+ -l PAGE_LENGTH, --length=PAGE_LENGTH -+ Set the page length to PAGE_LENGTH lines. Default is 66, -+ including 5 lines of HEADER and 5 lines of TRAILER -+ without -F, but only 3 lines of HEADER and no TRAILER -+ with -F (i.e the number of text lines defaults to 56 or -+ 63 respectively). -+ -+ -m, --merge Print files in parallel; pad_across_to align -+ columns; truncate lines and print separator strings; -+ Do it also with empty columns to get a continuous line -+ numbering and column marking by separators throughout -+ the whole merged file. -+ -+ Empty pages in some input files produce empty columns -+ [marked by separators] in the merged pages. Completely -+ empty merged pages show no column separators at all. -+ -+ The layout of a merged page is ruled by the largest form -+ feed distance of the single pages at that page. Shorter -+ columns will be filled up with empty lines. -+ -+ Together with -J option join lines of full length and -+ set separators when -S option is used. -+ -+ -n[SEP[DIGITS]], --number-lines[=SEP[DIGITS]] -+ Provide DIGITS digit line numbering (default for DIGITS -+ is 5). With multicolumn output the number occupies the -+ first DIGITS column positions of each text column or only -+ each line of -m output. -+ With single column output the number precedes each line -+ just as -m output. -+ Optional argument SEP is the character appended to the -+ line number to separate it from the text followed. -+ The default separator is a TAB. In a strict sense a TAB -+ is always printed with single column output only. The -+ TAB-width varies with the TAB-position, e.g. with the -+ left margin specified by -o option. -+ With multicolumn output priority is given to `equal width -+ of output columns' (a POSIX specification). The TAB-width -+ is fixed to the value of the 1st column and does not -+ change with different values of left margin. That means a -+ fixed number of spaces is always printed in the place of -+ a TAB. The tabification depends upon the output -+ position. -+ -+ Default counting of the line numbers starts with 1st -+ line of the input file (not the 1st line printed, -+ compare the --page option and -N option). -+ -+ -N NUMBER, --first-line-number=NUMBER -+ Start line counting with the number NUMBER at the 1st -+ line of first page printed (mostly not the 1st line of -+ the input file). -+ -+ -o MARGIN, --indent=MARGIN -+ Offset each line with a margin MARGIN spaces wide. -+ Total page width is the size of the margin plus the -+ PAGE_WIDTH set with -W/-w option. -+ -+ -r, --no-file-warnings -+ Omit warning when a file cannot be opened. -+ -+ -s[CHAR], --separator[=CHAR] -+ Separate columns by a single character CHAR, default for -+ CHAR is the TAB character without -w and 'no char' with -w. -+ Without `-s' default separator `space' is set. -+ -s[CHAR] turns off line truncation of all 3 column options -+ (-COLUMN|-a -COLUMN|-m) except -w is set. That is a POSIX -+ compliant formulation. The source code translates -s into -+ the new options -S and -J, also -W if required. -+ -+ -S STRING, --sep-string[=STRING] -+ Separate columns by any string STRING. The -S option -+ doesn't react upon the -W/-w option (unlike -s option -+ does). It defines a separator nothing else. -+ Without -S: Default separator TAB is used with -J and -+ `space' otherwise (same as -S" "). -+ With -S "": No separator is used. -+ Quotes should be used with blanks and some shell active -+ characters. -+ -S is problematic because in its obsolete form you -+ cannot use -S "STRING", but in its standard form you -+ must use -S "STRING" if STRING is empty. Use -+ --sep-string to avoid the ambiguity. -+ -+ -t, --omit-header Do not print headers or footers but retain form -+ feeds set in the input files. -+ -+ -T, --omit-pagination -+ Do not print headers or footers, eliminate any pagination -+ by form feeds set in the input files. -+ -+ -v, --show-nonprinting -+ Print unprintable characters as escape sequences. Use -+ octal backslash notation. Control-G becomes \007. -+ -+ -w PAGE_WIDTH, --width=PAGE_WIDTH -+ Set page width to PAGE_WIDTH characters for multiple -+ text-column output only (default for PAGE_WIDTH is 72). -+ -s[CHAR] turns off the default page width and any line -+ truncation. Lines of full length will be merged, -+ regardless of the column options set. A POSIX compliant -+ formulation. -+ -+ -W PAGE_WIDTH, --page-width=PAGE_WIDTH -+ Set the page width to PAGE_WIDTH characters. That's valid -+ with and without a column option. Text lines will be -+ truncated, unless -J is used. Together with one of the -+ column options (-COLUMN| -a -COLUMN| -m) column alignment -+ is always used. -+ Default is 72 characters. -+ Without -W PAGE_WIDTH -+ - but with one of the column options default truncation of -+ 72 characters is used (to keep downward compatibility -+ and to simplify most frequently met column tasks). -+ Column alignment and column separators are used. -+ - and without any of the column options NO line truncation -+ is used (to keep downward compatibility and to meet most -+ frequent tasks). That's equivalent to -W 72 -J . -+ -+ With/without -W PAGE_WIDTH the header line is always -+ truncated to avoid line overflow. -+ -+ (In pr versions newer than 1.14 -S option does no longer -+ affect -W option.) -+ -+*/ -+ -+ -+#include -+ -+#include -+#include -+#include "system.h" -+#include "error.h" -+#include "hard-locale.h" -+#include "mbswidth.h" -+#include "quote.h" -+#include "stat-time.h" -+#include "stdio--.h" -+#include "strftime.h" -+#include "xstrtol.h" -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "pr" -+ -+#define AUTHORS \ -+ proper_name ("Pete TerMaat"), \ -+ proper_name ("Roland Huebner") -+ -+/* Used with start_position in the struct COLUMN described below. -+ If start_position == ANYWHERE, we aren't truncating columns and -+ can begin printing a column anywhere. Otherwise we must pad to -+ the horizontal position start_position. */ -+#define ANYWHERE 0 -+ -+/* Each column has one of these structures allocated for it. -+ If we're only dealing with one file, fp is the same for all -+ columns. -+ -+ The general strategy is to spend time setting up these column -+ structures (storing columns if necessary), after which printing -+ is a matter of flitting from column to column and calling -+ print_func. -+ -+ Parallel files, single files printing across in multiple -+ columns, and single files printing down in multiple columns all -+ fit the same printing loop. -+ -+ print_func Function used to print lines in this column. -+ If we're storing this column it will be -+ print_stored(), Otherwise it will be read_line(). -+ -+ char_func Function used to process characters in this column. -+ If we're storing this column it will be store_char(), -+ otherwise it will be print_char(). -+ -+ current_line Index of the current entry in line_vector, which -+ contains the index of the first character of the -+ current line in buff[]. -+ -+ lines_stored Number of lines in this column which are stored in -+ buff. -+ -+ lines_to_print If we're storing this column, lines_to_print is -+ the number of stored_lines which remain to be -+ printed. Otherwise it is the number of lines -+ we can print without exceeding lines_per_body. -+ -+ start_position The horizontal position we want to be in before we -+ print the first character in this column. -+ -+ numbered True means precede this column with a line number. */ -+ -+/* FIXME: There are many unchecked integer overflows in this file, -+ that will cause this command to misbehave given large inputs or -+ options. Many of the "int" values below should be "size_t" or -+ something else like that. */ -+ -+struct COLUMN; -+struct COLUMN -+ { -+ FILE *fp; /* Input stream for this column. */ -+ char const *name; /* File name. */ -+ enum -+ { -+ OPEN, -+ FF_FOUND, /* used with -b option, set with \f, changed -+ to ON_HOLD after print_header */ -+ ON_HOLD, /* Hit a form feed. */ -+ CLOSED -+ } -+ status; /* Status of the file pointer. */ -+ -+ /* Func to print lines in this col. */ -+ bool (*print_func) (struct COLUMN *); -+ -+ /* Func to print/store chars in this col. */ -+ void (*char_func) (char); -+ -+ int current_line; /* Index of current place in line_vector. */ -+ int lines_stored; /* Number of lines stored in buff. */ -+ int lines_to_print; /* No. lines stored or space left on page. */ -+ int start_position; /* Horizontal position of first char. */ -+ bool numbered; -+ bool full_page_printed; /* True means printed without a FF found. */ -+ -+ /* p->full_page_printed controls a special case of "FF set by hand": -+ True means a full page has been printed without FF found. To avoid an -+ additional empty page we have to ignore a FF immediately following in -+ the next line. */ -+ }; -+ -+typedef struct COLUMN COLUMN; -+ -+static int char_to_clump (char c); -+static bool read_line (COLUMN *p); -+static bool print_page (void); -+static bool print_stored (COLUMN *p); -+static bool open_file (char *name, COLUMN *p); -+static bool skip_to_page (uintmax_t page); -+static void print_header (void); -+static void pad_across_to (int position); -+static void add_line_number (COLUMN *p); -+static void getoptarg (char *arg, char switch_char, char *character, -+ int *number); -+void usage (int status); -+static void print_files (int number_of_files, char **av); -+static void init_parameters (int number_of_files); -+static void init_header (char const *filename, int desc); -+static bool init_fps (int number_of_files, char **av); -+static void init_funcs (void); -+static void init_store_cols (void); -+static void store_columns (void); -+static void balance (int total_stored); -+static void store_char (char c); -+static void pad_down (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); -+ -+/* All of the columns to print. */ -+static COLUMN *column_vector; -+ -+/* When printing a single file in multiple downward columns, -+ 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; -+ -+/* Index of the position in buff where the next character -+ will be stored. */ -+static unsigned int buff_current; -+ -+/* The number of characters in buff. -+ Used for allocation of buff and to detect overflow of buff. */ -+static size_t buff_allocated; -+ -+/* Array of indices into buff. -+ Each entry is an index of the first character of a line. -+ This is used when storing lines to facilitate shuffling when -+ we do column balancing on the last page. */ -+static int *line_vector; -+ -+/* Array of horizonal positions. -+ For each line in line_vector, end_vector[line] is the horizontal -+ position we are in after printing that line. We keep track of this -+ so that we know how much we need to pad to prepare for the next -+ column. */ -+static int *end_vector; -+ -+/* (-m) True means we're printing multiple files in parallel. */ -+static bool parallel_files = false; -+ -+/* (-m) True means a line starts with some empty columns (some files -+ already CLOSED or ON_HOLD) which we have to align. */ -+static bool align_empty_cols; -+ -+/* (-m) True means we have not yet found any printable column in a line. -+ align_empty_cols = true has to be maintained. */ -+static bool empty_line; -+ -+/* (-m) False means printable column output precedes a form feed found. -+ Column alignment is done only once. No additional action with that form -+ feed. -+ True means we found only a form feed in a column. Maybe we have to do -+ some column alignment with that form feed. */ -+static bool FF_only; -+ -+/* (-[0-9]+) True means we're given an option explicitly specifying -+ number of columns. Used to detect when this option is used with -m -+ and when translating old options to new/long options. */ -+static bool explicit_columns = false; -+ -+/* (-t|-T) False means we aren't printing headers and footers. */ -+static bool extremities = true; -+ -+/* (-t) True means we retain all FF set by hand in input files. -+ False is set with -T option. */ -+static bool keep_FF = false; -+static bool print_a_FF = false; -+ -+/* True means we need to print a header as soon as we know we've got input -+ to print after it. */ -+static bool print_a_header; -+ -+/* (-f) True means use formfeeds instead of newlines to separate pages. */ -+static bool use_form_feed = false; -+ -+/* True means we have read the standard input. */ -+static bool have_read_stdin = false; -+ -+/* True means the -a flag has been given. */ -+static bool print_across_flag = false; -+ -+/* True means we're printing one file in multiple (>1) downward columns. */ -+static bool storing_columns = true; -+ -+/* (-b) True means balance columns on the last page as Sys V does. */ -+/* That's no longer an independent option. With storing_columns = true -+ balance_columns = true is used too (s. function init_parameters). -+ We get a consistent formulation with "FF set by hand" in input files. */ -+static bool balance_columns = false; -+ -+/* (-l) Number of lines on a page, including header and footer lines. */ -+static int lines_per_page = 66; -+ -+/* Number of lines in the header and footer can be reset to 0 using -+ the -t flag. */ -+enum { lines_per_header = 5 }; -+static int lines_per_body; -+enum { lines_per_footer = 5 }; -+ -+/* (-w|-W) Width in characters of the page. Does not include the width of -+ the margin. */ -+static int chars_per_line = 72; -+ -+/* (-w|W) True means we truncate lines longer than chars_per_column. */ -+static bool truncate_lines = false; -+ -+/* (-J) True means we join lines without any line truncation. -J -+ dominates -w option. */ -+static bool join_lines = false; -+ -+/* Number of characters in a column. Based on col_sep_length and -+ page width. */ -+static int chars_per_column; -+ -+/* (-e) True means convert tabs to spaces on input. */ -+static bool untabify_input = false; -+ -+/* (-e) The input tab character. */ -+static char input_tab_char = '\t'; -+ -+/* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... -+ where the leftmost column is 1. */ -+static int chars_per_input_tab = 8; -+ -+/* (-i) True means convert spaces to tabs on output. */ -+static bool tabify_output = false; -+ -+/* (-i) The output tab character. */ -+static char output_tab_char = '\t'; -+ -+/* (-i) The width of the output tab. */ -+static int chars_per_output_tab = 8; -+ -+/* Keeps track of pending white space. When we hit a nonspace -+ character after some whitespace, we print whitespace, tabbing -+ if necessary to get to output_position + spaces_not_printed. */ -+static int spaces_not_printed; -+ -+/* (-o) Number of spaces in the left margin (tabs used when possible). */ -+static int chars_per_margin = 0; -+ -+/* Position where the next character will fall. -+ Leftmost position is 0 + chars_per_margin. -+ Rightmost position is chars_per_margin + chars_per_line - 1. -+ This is important for converting spaces to tabs on output. */ -+static int output_position; -+ -+/* Horizontal position relative to the current file. -+ (output_position depends on where we are on the page; -+ input_position depends on where we are in the file.) -+ Important for converting tabs to spaces on input. */ -+static int input_position; -+ -+/* True if there were any failed opens so we can exit with nonzero -+ status. */ -+static bool failed_opens = false; -+ -+/* The number of spaces taken up if we print a tab character with width -+ c_ from position h_. */ -+#define TAB_WIDTH(c_, h_) ((c_) - ((h_) % (c_))) -+ -+/* The horizontal position we'll be at after printing a tab character -+ of width c_ from the position h_. */ -+#define POS_AFTER_TAB(c_, h_) ((h_) + TAB_WIDTH (c_, h_)) -+ -+/* (-NNN) Number of columns of text to print. */ -+static int columns = 1; -+ -+/* (+NNN:MMM) Page numbers on which to begin and stop printing. -+ first_page_number = 0 will be used to check input only. */ -+static uintmax_t first_page_number = 0; -+static uintmax_t last_page_number = UINTMAX_MAX; -+ -+/* Number of files open (not closed, not on hold). */ -+static int files_ready_to_read = 0; -+ -+/* Current page number. Displayed in header. */ -+static uintmax_t page_number; -+ -+/* Current line number. Displayed when -n flag is specified. -+ -+ When printing files in parallel (-m flag), line numbering is as follows: -+ 1 foo goo moo -+ 2 hoo too zoo -+ -+ When printing files across (-a flag), ... -+ 1 foo 2 moo 3 goo -+ 4 hoo 5 too 6 zoo -+ -+ Otherwise, line numbering is as follows: -+ 1 foo 3 goo 5 too -+ 2 moo 4 hoo 6 zoo */ -+static int line_number; -+ -+/* With line_number overflow, we use power_10 to cut off the higher-order -+ digits of the line_number */ -+static int power_10; -+ -+/* (-n) True means lines should be preceded by numbers. */ -+static bool numbered_lines = false; -+ -+/* (-n) Character which follows each line number. */ -+static char number_separator = '\t'; -+ -+/* (-n) line counting starts with 1st line of input file (not with 1st -+ line of 1st page printed). */ -+static int line_count = 1; -+ -+/* (-n) True means counting of skipped lines starts with 1st line of -+ input file. False means -N option is used in addition, counting of -+ skipped lines not required. */ -+static bool skip_count = true; -+ -+/* (-N) Counting starts with start_line_number = NUMBER at 1st line of -+ first page printed, usually not 1st page of input file. */ -+static int start_line_num = 1; -+ -+/* (-n) Width in characters of a line number. */ -+static int chars_per_number = 5; -+ -+/* Used when widening the first column to accommodate numbers -- only -+ needed when printing files in parallel. Includes width of both the -+ number and the number_separator. */ -+static int number_width; -+ -+/* Buffer sprintf uses to format a line number. */ -+static char *number_buff; -+ -+/* (-v) True means unprintable characters are printed as escape sequences. -+ control-g becomes \007. */ -+static bool use_esc_sequence = false; -+ -+/* (-c) True means unprintable characters are printed as control prefixes. -+ control-g becomes ^G. */ -+static bool use_cntrl_prefix = false; -+ -+/* (-d) True means output is double spaced. */ -+static bool double_space = false; -+ -+/* Number of files opened initially in init_files. Should be 1 -+ unless we're printing multiple files in parallel. */ -+static int total_files = 0; -+ -+/* (-r) True means don't complain if we can't open a file. */ -+static bool ignore_failed_opens = false; -+ -+/* (-S) True means we separate columns with a specified string. -+ -S option does not affect line truncation nor column alignment. */ -+static bool use_col_separator = false; -+ -+/* String used to separate columns if the -S option has been specified. -+ Default without -S but together with one of the column options -+ -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ -+static char *col_sep_string = (char *) ""; -+static int col_sep_length = 0; -+static char *column_separator = (char *) " "; -+static char *line_separator = (char *) "\t"; -+ -+/* Number of separator characters waiting to be printed as soon as we -+ know that we have any input remaining to be printed. */ -+static int separators_not_printed; -+ -+/* Position we need to pad to, as soon as we know that we have input -+ remaining to be printed. */ -+static int padding_not_printed; -+ -+/* True means we should pad the end of the page. Remains false until we -+ know we have a page to print. */ -+static bool pad_vertically; -+ -+/* (-h) String of characters used in place of the filename in the header. */ -+static char *custom_header; -+ -+/* (-D) Date format for the header. */ -+static char const *date_format; -+ -+/* Date and file name for the header. */ -+static char *date_text; -+static char const *file_text; -+ -+/* Output columns available, not counting the date and file name. */ -+static int header_width_available; -+ -+static char *clump_buff; -+ -+/* True means we read the line no. lines_per_body in skip_read -+ called by skip_to_page. That variable controls the coincidence of a -+ "FF set by hand" and "full_page_printed", see above the definition of -+ structure COLUMN. */ -+static bool last_line = false; -+ -+/* For long options that have no equivalent short option, use a -+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -+enum -+{ -+ COLUMNS_OPTION = CHAR_MAX + 1, -+ PAGES_OPTION -+}; -+ -+static char const short_options[] = -+ "-0123456789D:FJN:S::TW:abcde::fh:i::l:mn::o:rs::tvw:"; -+ -+static struct option const long_options[] = -+{ -+ {"pages", required_argument, NULL, PAGES_OPTION}, -+ {"columns", required_argument, NULL, COLUMNS_OPTION}, -+ {"across", no_argument, NULL, 'a'}, -+ {"show-control-chars", no_argument, NULL, 'c'}, -+ {"double-space", no_argument, NULL, 'd'}, -+ {"date-format", required_argument, NULL, 'D'}, -+ {"expand-tabs", optional_argument, NULL, 'e'}, -+ {"form-feed", no_argument, NULL, 'f'}, -+ {"header", required_argument, NULL, 'h'}, -+ {"output-tabs", optional_argument, NULL, 'i'}, -+ {"join-lines", no_argument, NULL, 'J'}, -+ {"length", required_argument, NULL, 'l'}, -+ {"merge", no_argument, NULL, 'm'}, -+ {"number-lines", optional_argument, NULL, 'n'}, -+ {"first-line-number", required_argument, NULL, 'N'}, -+ {"indent", required_argument, NULL, 'o'}, -+ {"no-file-warnings", no_argument, NULL, 'r'}, -+ {"separator", optional_argument, NULL, 's'}, -+ {"sep-string", optional_argument, NULL, 'S'}, -+ {"omit-header", no_argument, NULL, 't'}, -+ {"omit-pagination", no_argument, NULL, 'T'}, -+ {"show-nonprinting", no_argument, NULL, 'v'}, -+ {"width", required_argument, NULL, 'w'}, -+ {"page-width", required_argument, NULL, 'W'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+/* Return the number of columns that have either an open file or -+ stored lines. */ -+ -+static int -+cols_ready_to_print (void) -+{ -+ COLUMN *q; -+ int i; -+ int n; -+ -+ n = 0; -+ for (q = column_vector, i = 0; i < columns; ++q, ++i) -+ if (q->status == OPEN || -+ q->status == FF_FOUND || /* With -b: To print a header only */ -+ (storing_columns && q->lines_stored > 0 && q->lines_to_print > 0)) -+ ++n; -+ return n; -+} -+ -+/* Estimate first_ / last_page_number -+ using option +FIRST_PAGE:LAST_PAGE */ -+ -+static bool -+first_last_page (int oi, char c, char const *pages) -+{ -+ char *p; -+ uintmax_t first; -+ uintmax_t last = UINTMAX_MAX; -+ strtol_error err = xstrtoumax (pages, &p, 10, &first, ""); -+ if (err != LONGINT_OK && err != LONGINT_INVALID_SUFFIX_CHAR) -+ xstrtol_fatal (err, oi, c, long_options, pages); -+ -+ if (p == pages || !first) -+ return false; -+ -+ if (*p == ':') -+ { -+ char const *p1 = p + 1; -+ err = xstrtoumax (p1, &p, 10, &last, ""); -+ if (err != LONGINT_OK) -+ xstrtol_fatal (err, oi, c, long_options, pages); -+ if (p1 == p || last < first) -+ return false; -+ } -+ -+ if (*p) -+ return false; -+ -+ first_page_number = first; -+ last_page_number = last; -+ return true; -+} -+ -+/* Parse column count string S, and if it's valid (1 or larger and -+ within range of the type of `columns') set the global variables -+ columns and explicit_columns and return true. -+ Otherwise, exit with a diagnostic. */ -+static void -+parse_column_count (char const *s) -+{ -+ long int tmp_long; -+ if (xstrtol (s, NULL, 10, &tmp_long, "") != LONGINT_OK -+ || !(1 <= tmp_long && tmp_long <= INT_MAX)) -+ error (EXIT_FAILURE, 0, -+ _("invalid number of columns: %s"), quote (s)); -+ -+ columns = tmp_long; -+ explicit_columns = true; -+} -+ -+/* Estimate length of col_sep_string with option -S. */ -+ -+static void -+separator_string (const char *optarg_S) -+{ -+ col_sep_length = (int) strlen (optarg_S); -+ col_sep_string = xmalloc (col_sep_length + 1); -+ strcpy (col_sep_string, optarg_S); -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int n_files; -+ bool old_options = false; -+ bool old_w = false; -+ bool old_s = false; -+ char **file_names; -+ -+ /* Accumulate the digits of old-style options like -99. */ -+ char *column_count_string = NULL; -+ size_t n_digits = 0; -+ size_t n_alloc = 0; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdout); -+ -+ n_files = 0; -+ file_names = (argc > 1 -+ ? xmalloc ((argc - 1) * sizeof (char *)) -+ : NULL); -+ -+ for (;;) -+ { -+ int oi = -1; -+ int c = getopt_long (argc, argv, short_options, long_options, &oi); -+ if (c == -1) -+ break; -+ -+ if (ISDIGIT (c)) -+ { -+ /* Accumulate column-count digits specified via old-style options. */ -+ if (n_digits + 1 >= n_alloc) -+ column_count_string -+ = X2REALLOC (column_count_string, &n_alloc); -+ column_count_string[n_digits++] = c; -+ column_count_string[n_digits] = '\0'; -+ continue; -+ } -+ -+ n_digits = 0; -+ -+ switch (c) -+ { -+ case 1: /* Non-option argument. */ -+ /* long option --page dominates old `+FIRST_PAGE ...'. */ -+ if (! (first_page_number == 0 -+ && *optarg == '+' && first_last_page (-2, '+', optarg + 1))) -+ file_names[n_files++] = optarg; -+ break; -+ -+ case PAGES_OPTION: /* --pages=FIRST_PAGE[:LAST_PAGE] */ -+ { /* dominates old opt +... */ -+ if (! optarg) -+ error (EXIT_FAILURE, 0, -+ _("`--pages=FIRST_PAGE[:LAST_PAGE]' missing argument")); -+ else if (! first_last_page (oi, 0, optarg)) -+ error (EXIT_FAILURE, 0, _("invalid page range %s"), -+ quote (optarg)); -+ break; -+ } -+ -+ case COLUMNS_OPTION: /* --columns=COLUMN */ -+ { -+ parse_column_count (optarg); -+ -+ /* If there was a prior column count specified via the -+ short-named option syntax, e.g., -9, ensure that this -+ long-name-specified value overrides it. */ -+ free (column_count_string); -+ column_count_string = NULL; -+ n_alloc = 0; -+ break; -+ } -+ -+ case 'a': -+ print_across_flag = true; -+ storing_columns = false; -+ break; -+ case 'b': -+ balance_columns = true; -+ break; -+ case 'c': -+ use_cntrl_prefix = true; -+ break; -+ case 'd': -+ double_space = true; -+ break; -+ case 'D': -+ date_format = optarg; -+ break; -+ case 'e': -+ if (optarg) -+ getoptarg (optarg, 'e', &input_tab_char, -+ &chars_per_input_tab); -+ /* Could check tab width > 0. */ -+ untabify_input = true; -+ break; -+ case 'f': -+ case 'F': -+ use_form_feed = true; -+ break; -+ case 'h': -+ custom_header = optarg; -+ break; -+ case 'i': -+ if (optarg) -+ getoptarg (optarg, 'i', &output_tab_char, -+ &chars_per_output_tab); -+ /* Could check tab width > 0. */ -+ tabify_output = true; -+ break; -+ case 'J': -+ join_lines = true; -+ break; -+ case 'l': -+ { -+ long int tmp_long; -+ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK -+ || tmp_long <= 0 || tmp_long > INT_MAX) -+ { -+ error (EXIT_FAILURE, 0, -+ _("`-l PAGE_LENGTH' invalid number of lines: %s"), -+ quote (optarg)); -+ } -+ lines_per_page = tmp_long; -+ break; -+ } -+ case 'm': -+ parallel_files = true; -+ storing_columns = false; -+ break; -+ case 'n': -+ numbered_lines = true; -+ if (optarg) -+ getoptarg (optarg, 'n', &number_separator, -+ &chars_per_number); -+ break; -+ case 'N': -+ skip_count = false; -+ { -+ long int tmp_long; -+ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK -+ || tmp_long > INT_MAX) -+ { -+ error (EXIT_FAILURE, 0, -+ _("`-N NUMBER' invalid starting line number: %s"), -+ quote (optarg)); -+ } -+ start_line_num = tmp_long; -+ break; -+ } -+ case 'o': -+ { -+ long int tmp_long; -+ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK -+ || tmp_long < 0 || tmp_long > INT_MAX) -+ error (EXIT_FAILURE, 0, -+ _("`-o MARGIN' invalid line offset: %s"), quote (optarg)); -+ chars_per_margin = tmp_long; -+ break; -+ } -+ case 'r': -+ ignore_failed_opens = true; -+ break; -+ case 's': -+ old_options = true; -+ old_s = true; -+ if (!use_col_separator && optarg) -+ separator_string (optarg); -+ break; -+ case 'S': -+ old_s = false; -+ /* Reset an additional input of -s, -S dominates -s */ -+ col_sep_string = bad_cast (""); -+ col_sep_length = 0; -+ use_col_separator = true; -+ if (optarg) -+ separator_string (optarg); -+ break; -+ case 't': -+ extremities = false; -+ keep_FF = true; -+ break; -+ case 'T': -+ extremities = false; -+ keep_FF = false; -+ break; -+ case 'v': -+ use_esc_sequence = true; -+ break; -+ case 'w': -+ old_options = true; -+ old_w = true; -+ { -+ long int tmp_long; -+ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK -+ || tmp_long <= 0 || tmp_long > INT_MAX) -+ error (EXIT_FAILURE, 0, -+ _("`-w PAGE_WIDTH' invalid number of characters: %s"), -+ quote (optarg)); -+ if (!truncate_lines) -+ chars_per_line = tmp_long; -+ break; -+ } -+ case 'W': -+ old_w = false; /* dominates -w */ -+ truncate_lines = true; -+ { -+ long int tmp_long; -+ if (xstrtol (optarg, NULL, 10, &tmp_long, "") != LONGINT_OK -+ || tmp_long <= 0 || tmp_long > INT_MAX) -+ error (EXIT_FAILURE, 0, -+ _("`-W PAGE_WIDTH' invalid number of characters: %s"), -+ quote (optarg)); -+ chars_per_line = tmp_long; -+ break; -+ } -+ case_GETOPT_HELP_CHAR; -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ default: -+ usage (EXIT_FAILURE); -+ break; -+ } -+ } -+ -+ if (column_count_string) -+ { -+ parse_column_count (column_count_string); -+ free (column_count_string); -+ } -+ -+ if (! date_format) -+ date_format = (getenv ("POSIXLY_CORRECT") && !hard_locale (LC_TIME) -+ ? "%b %e %H:%M %Y" -+ : "%Y-%m-%d %H:%M"); -+ -+ /* Now we can set a reasonable initial value: */ -+ if (first_page_number == 0) -+ first_page_number = 1; -+ -+ if (parallel_files && explicit_columns) -+ error (EXIT_FAILURE, 0, -+ _("cannot specify number of columns when printing in parallel")); -+ -+ if (parallel_files && print_across_flag) -+ error (EXIT_FAILURE, 0, -+ _("cannot specify both printing across and printing in parallel")); -+ -+/* Translate some old short options to new/long options. -+ To meet downward compatibility with other UNIX pr utilities -+ and some POSIX specifications. */ -+ -+ if (old_options) -+ { -+ if (old_w) -+ { -+ if (parallel_files || explicit_columns) -+ { -+ /* activate -W */ -+ truncate_lines = true; -+ if (old_s) -+ /* adapt HP-UX and SunOS: -s = no separator; -+ activate -S */ -+ use_col_separator = true; -+ } -+ else -+ /* old -w sets width with columns only -+ activate -J */ -+ join_lines = true; -+ } -+ else if (!use_col_separator) -+ { -+ /* No -S option read */ -+ if (old_s && (parallel_files || explicit_columns)) -+ { -+ if (!truncate_lines) -+ { -+ /* old -s (without -w and -W) annuls column alignment, -+ uses fields, activate -J */ -+ join_lines = true; -+ if (col_sep_length > 0) -+ /* activate -S */ -+ use_col_separator = true; -+ } -+ else -+ /* with -W */ -+ /* adapt HP-UX and SunOS: -s = no separator; -+ activate -S */ -+ use_col_separator = true; -+ } -+ } -+ } -+ -+ for (; optind < argc; optind++) -+ { -+ file_names[n_files++] = argv[optind]; -+ } -+ -+ if (n_files == 0) -+ { -+ /* No file arguments specified; read from standard input. */ -+ print_files (0, NULL); -+ } -+ else -+ { -+ if (parallel_files) -+ print_files (n_files, file_names); -+ else -+ { -+ int i; -+ for (i = 0; i < n_files; i++) -+ print_files (1, &file_names[i]); -+ } -+ } -+ -+ cleanup (); -+ -+ if (have_read_stdin && fclose (stdin) == EOF) -+ error (EXIT_FAILURE, errno, _("standard input")); -+ if (failed_opens) -+ exit (EXIT_FAILURE); -+ exit (EXIT_SUCCESS); -+} -+ -+/* Parse options of the form -scNNN. -+ -+ Example: -nck, where 'n' is the option, c is the optional number -+ separator, and k is the optional width of the field used when printing -+ a number. */ -+ -+static void -+getoptarg (char *arg, char switch_char, char *character, int *number) -+{ -+ if (!ISDIGIT (*arg)) -+ *character = *arg++; -+ if (*arg) -+ { -+ long int tmp_long; -+ if (xstrtol (arg, NULL, 10, &tmp_long, "") != LONGINT_OK -+ || tmp_long <= 0 || tmp_long > INT_MAX) -+ { -+ error (0, 0, -+ _("`-%c' extra characters or invalid number in the argument: %s"), -+ switch_char, quote (arg)); -+ usage (EXIT_FAILURE); -+ } -+ *number = tmp_long; -+ } -+} -+ -+/* Set parameters related to formatting. */ -+ -+static void -+init_parameters (int number_of_files) -+{ -+ int chars_used_by_number = 0; -+ -+ lines_per_body = lines_per_page - lines_per_header - lines_per_footer; -+ if (lines_per_body <= 0) -+ { -+ extremities = false; -+ keep_FF = true; -+ } -+ if (extremities == false) -+ lines_per_body = lines_per_page; -+ -+ if (double_space) -+ lines_per_body = lines_per_body / 2; -+ -+ /* If input is stdin, cannot print parallel files. BSD dumps core -+ on this. */ -+ if (number_of_files == 0) -+ parallel_files = false; -+ -+ if (parallel_files) -+ columns = number_of_files; -+ -+ /* One file, multi columns down: -b option is set to get a consistent -+ formulation with "FF set by hand" in input files. */ -+ if (storing_columns) -+ balance_columns = true; -+ -+ /* Tabification is assumed for multiple columns. */ -+ if (columns > 1) -+ { -+ if (!use_col_separator) -+ { -+ /* Use default separator */ -+ if (join_lines) -+ col_sep_string = line_separator; -+ else -+ col_sep_string = column_separator; -+ -+ col_sep_length = 1; -+ use_col_separator = true; -+ } -+ /* It's rather pointless to define a TAB separator with column -+ alignment */ -+ else if (!join_lines && *col_sep_string == '\t') -+ col_sep_string = column_separator; -+ -+ truncate_lines = true; -+ tabify_output = true; -+ } -+ else -+ storing_columns = false; -+ -+ /* -J dominates -w in any case */ -+ if (join_lines) -+ truncate_lines = false; -+ -+ if (numbered_lines) -+ { -+ int tmp_i; -+ int chars_per_default_tab = 8; -+ -+ line_count = start_line_num; -+ -+ /* To allow input tab-expansion (-e sensitive) use: -+ if (number_separator == input_tab_char) -+ number_width = chars_per_number + -+ TAB_WIDTH (chars_per_input_tab, chars_per_number); */ -+ -+ /* Estimate chars_per_text without any margin and keep it constant. */ -+ if (number_separator == '\t') -+ number_width = chars_per_number + -+ TAB_WIDTH (chars_per_default_tab, chars_per_number); -+ else -+ number_width = chars_per_number + 1; -+ -+ /* The number is part of the column width unless we are -+ printing files in parallel. */ -+ if (parallel_files) -+ chars_used_by_number = number_width; -+ -+ /* We use power_10 to cut off the higher-order digits of the -+ line_number in function add_line_number */ -+ tmp_i = chars_per_number; -+ for (power_10 = 1; tmp_i > 0; --tmp_i) -+ power_10 = 10 * power_10; -+ } -+ -+ chars_per_column = (chars_per_line - chars_used_by_number - -+ (columns - 1) * col_sep_length) / columns; -+ -+ if (chars_per_column < 1) -+ error (EXIT_FAILURE, 0, _("page width too narrow")); -+ -+ if (numbered_lines) -+ { -+ free (number_buff); -+ number_buff = xmalloc (2 * chars_per_number); -+ } -+ -+ /* Pick the maximum between the tab width and the width of an -+ escape sequence. -+ The width of an escape sequence (4) isn't the lower limit any longer. -+ 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)); -+} -+ -+/* Open the necessary files, -+ maintaining a COLUMN structure for each column. -+ -+ With multiple files, each column p has a different p->fp. -+ With single files, each column p has the same p->fp. -+ Return false if (number_of_files > 0) and no files can be opened, -+ true otherwise. -+ -+ With each column/file p, p->full_page_printed is initialized, -+ see also open_file. */ -+ -+static bool -+init_fps (int number_of_files, char **av) -+{ -+ int i, files_left; -+ COLUMN *p; -+ FILE *firstfp; -+ char const *firstname; -+ -+ total_files = 0; -+ -+ free (column_vector); -+ column_vector = xnmalloc (columns, sizeof (COLUMN)); -+ -+ if (parallel_files) -+ { -+ files_left = number_of_files; -+ for (p = column_vector; files_left--; ++p, ++av) -+ { -+ if (! open_file (*av, p)) -+ { -+ --p; -+ --columns; -+ } -+ } -+ if (columns == 0) -+ return false; -+ init_header ("", -1); -+ } -+ else -+ { -+ p = column_vector; -+ if (number_of_files > 0) -+ { -+ if (! open_file (*av, p)) -+ return false; -+ init_header (*av, fileno (p->fp)); -+ p->lines_stored = 0; -+ } -+ else -+ { -+ p->name = _("standard input"); -+ p->fp = stdin; -+ have_read_stdin = true; -+ p->status = OPEN; -+ p->full_page_printed = false; -+ ++total_files; -+ init_header ("", -1); -+ p->lines_stored = 0; -+ } -+ -+ firstname = p->name; -+ firstfp = p->fp; -+ for (i = columns - 1, ++p; i; --i, ++p) -+ { -+ p->name = firstname; -+ p->fp = firstfp; -+ p->status = OPEN; -+ p->full_page_printed = false; -+ p->lines_stored = 0; -+ } -+ } -+ files_ready_to_read = total_files; -+ return true; -+} -+ -+/* Determine print_func and char_func, the functions -+ used by each column for printing and/or storing. -+ -+ Determine the horizontal position desired when we begin -+ printing a column (p->start_position). */ -+ -+static void -+init_funcs (void) -+{ -+ int i, h, h_next; -+ COLUMN *p; -+ -+ h = chars_per_margin; -+ -+ if (!truncate_lines) -+ h_next = ANYWHERE; -+ else -+ { -+ /* When numbering lines of parallel files, we enlarge the -+ first column to accomodate the number. Looks better than -+ the Sys V approach. */ -+ if (parallel_files && numbered_lines) -+ h_next = h + chars_per_column + number_width; -+ else -+ h_next = h + chars_per_column; -+ } -+ -+ /* Enlarge p->start_position of first column to use the same form of -+ padding_not_printed with all columns. */ -+ h = h + col_sep_length; -+ -+ /* This loop takes care of all but the rightmost column. */ -+ -+ for (p = column_vector, i = 1; i < columns; ++p, ++i) -+ { -+ if (storing_columns) /* One file, multi columns down. */ -+ { -+ p->char_func = store_char; -+ p->print_func = print_stored; -+ } -+ else -+ /* One file, multi columns across; or parallel files. */ -+ { -+ p->char_func = print_char; -+ p->print_func = read_line; -+ } -+ -+ /* Number only the first column when printing files in -+ parallel. */ -+ p->numbered = numbered_lines && (!parallel_files || i == 1); -+ p->start_position = h; -+ -+ /* If we don't truncate lines, all start_positions are -+ ANYWHERE, except the first column's start_position when -+ using a margin. */ -+ -+ if (!truncate_lines) -+ { -+ h = ANYWHERE; -+ h_next = ANYWHERE; -+ } -+ else -+ { -+ h = h_next + col_sep_length; -+ h_next = h + chars_per_column; -+ } -+ } -+ -+ /* The rightmost column. -+ -+ Doesn't need to be stored unless we intend to balance -+ columns on the last page. */ -+ if (storing_columns && balance_columns) -+ { -+ p->char_func = store_char; -+ p->print_func = print_stored; -+ } -+ else -+ { -+ p->char_func = print_char; -+ p->print_func = read_line; -+ } -+ -+ p->numbered = numbered_lines && (!parallel_files || i == 1); -+ p->start_position = h; -+} -+ -+/* Open a file. Return true if successful. -+ -+ With each file p, p->full_page_printed is initialized, -+ see also init_fps. */ -+ -+static bool -+open_file (char *name, COLUMN *p) -+{ -+ if (STREQ (name, "-")) -+ { -+ p->name = _("standard input"); -+ p->fp = stdin; -+ have_read_stdin = true; -+ } -+ else -+ { -+ p->name = name; -+ p->fp = fopen (name, "r"); -+ } -+ if (p->fp == NULL) -+ { -+ failed_opens = true; -+ if (!ignore_failed_opens) -+ error (0, errno, "%s", name); -+ return false; -+ } -+ p->status = OPEN; -+ p->full_page_printed = false; -+ ++total_files; -+ return true; -+} -+ -+/* Close the file in P. -+ -+ If we aren't dealing with multiple files in parallel, we change -+ the status of all columns in the column list to reflect the close. */ -+ -+static void -+close_file (COLUMN *p) -+{ -+ COLUMN *q; -+ int i; -+ -+ if (p->status == CLOSED) -+ return; -+ if (ferror (p->fp)) -+ error (EXIT_FAILURE, errno, "%s", p->name); -+ if (fileno (p->fp) != STDIN_FILENO && fclose (p->fp) != 0) -+ error (EXIT_FAILURE, errno, "%s", p->name); -+ -+ if (!parallel_files) -+ { -+ for (q = column_vector, i = columns; i; ++q, --i) -+ { -+ q->status = CLOSED; -+ if (q->lines_stored == 0) -+ { -+ q->lines_to_print = 0; -+ } -+ } -+ } -+ else -+ { -+ p->status = CLOSED; -+ p->lines_to_print = 0; -+ } -+ -+ --files_ready_to_read; -+} -+ -+/* Put a file on hold until we start a new page, -+ since we've hit a form feed. -+ -+ If we aren't dealing with parallel files, we must change the -+ status of all columns in the column list. */ -+ -+static void -+hold_file (COLUMN *p) -+{ -+ COLUMN *q; -+ int i; -+ -+ if (!parallel_files) -+ for (q = column_vector, i = columns; i; ++q, --i) -+ { -+ if (storing_columns) -+ q->status = FF_FOUND; -+ else -+ q->status = ON_HOLD; -+ } -+ else -+ p->status = ON_HOLD; -+ -+ p->lines_to_print = 0; -+ --files_ready_to_read; -+} -+ -+/* Undo hold_file -- go through the column list and change any -+ ON_HOLD columns to OPEN. Used at the end of each page. */ -+ -+static void -+reset_status (void) -+{ -+ int i = columns; -+ COLUMN *p; -+ -+ for (p = column_vector; i; --i, ++p) -+ if (p->status == ON_HOLD) -+ { -+ p->status = OPEN; -+ files_ready_to_read++; -+ } -+ -+ if (storing_columns) -+ { -+ if (column_vector->status == CLOSED) -+ /* We use the info to output an error message in skip_to_page. */ -+ files_ready_to_read = 0; -+ else -+ files_ready_to_read = 1; -+ } -+} -+ -+/* Print a single file, or multiple files in parallel. -+ -+ Set up the list of columns, opening the necessary files. -+ Allocate space for storing columns, if necessary. -+ Skip to first_page_number, if user has asked to skip leading pages. -+ Determine which functions are appropriate to store/print lines -+ in each column. -+ Print the file(s). */ -+ -+static void -+print_files (int number_of_files, char **av) -+{ -+ init_parameters (number_of_files); -+ if (! init_fps (number_of_files, av)) -+ return; -+ if (storing_columns) -+ init_store_cols (); -+ -+ if (first_page_number > 1) -+ { -+ if (!skip_to_page (first_page_number)) -+ return; -+ else -+ page_number = first_page_number; -+ } -+ else -+ page_number = 1; -+ -+ init_funcs (); -+ -+ line_number = line_count; -+ while (print_page ()) -+ ; -+} -+ -+/* Initialize header information. -+ If DESC is non-negative, it is a file descriptor open to -+ FILENAME for reading. */ -+ -+static void -+init_header (char const *filename, int desc) -+{ -+ char *buf = NULL; -+ struct stat st; -+ struct timespec t; -+ int ns; -+ struct tm *tm; -+ -+ /* If parallel files or standard input, use current date. */ -+ if (STREQ (filename, "-")) -+ desc = -1; -+ if (0 <= desc && fstat (desc, &st) == 0) -+ t = get_stat_mtime (&st); -+ else -+ { -+ static struct timespec timespec; -+ if (! timespec.tv_sec) -+ gettime (×pec); -+ t = timespec; -+ } -+ -+ ns = t.tv_nsec; -+ tm = localtime (&t.tv_sec); -+ if (tm == NULL) -+ { -+ buf = xmalloc (INT_BUFSIZE_BOUND (long int) -+ + MAX (10, INT_BUFSIZE_BOUND (int))); -+ sprintf (buf, "%ld.%09d", (long int) t.tv_sec, ns); -+ } -+ else -+ { -+ size_t bufsize = nstrftime (NULL, SIZE_MAX, date_format, tm, 0, ns) + 1; -+ buf = xmalloc (bufsize); -+ nstrftime (buf, bufsize, date_format, tm, 0, ns); -+ } -+ -+ free (date_text); -+ date_text = buf; -+ file_text = custom_header ? custom_header : desc < 0 ? "" : filename; -+ header_width_available = (chars_per_line -+ - mbswidth (date_text, 0) -+ - mbswidth (file_text, 0)); -+} -+ -+/* Set things up for printing a page -+ -+ Scan through the columns ... -+ Determine which are ready to print -+ (i.e., which have lines stored or open files) -+ Set p->lines_to_print appropriately -+ (to p->lines_stored if we're storing, or lines_per_body -+ if we're reading straight from the file) -+ Keep track of this total so we know when to stop printing */ -+ -+static void -+init_page (void) -+{ -+ int j; -+ COLUMN *p; -+ -+ if (storing_columns) -+ { -+ store_columns (); -+ for (j = columns - 1, p = column_vector; j; --j, ++p) -+ { -+ p->lines_to_print = p->lines_stored; -+ } -+ -+ /* Last column. */ -+ if (balance_columns) -+ { -+ p->lines_to_print = p->lines_stored; -+ } -+ /* Since we're not balancing columns, we don't need to store -+ the rightmost column. Read it straight from the file. */ -+ else -+ { -+ if (p->status == OPEN) -+ { -+ p->lines_to_print = lines_per_body; -+ } -+ else -+ p->lines_to_print = 0; -+ } -+ } -+ else -+ for (j = columns, p = column_vector; j; --j, ++p) -+ if (p->status == OPEN) -+ { -+ p->lines_to_print = lines_per_body; -+ } -+ else -+ p->lines_to_print = 0; -+} -+ -+/* Align empty columns and print separators. -+ Empty columns will be formed by files with status ON_HOLD or CLOSED -+ when printing multiple files in parallel. */ -+ -+static void -+align_column (COLUMN *p) -+{ -+ padding_not_printed = p->start_position; -+ if (padding_not_printed - col_sep_length > 0) -+ { -+ pad_across_to (padding_not_printed - col_sep_length); -+ padding_not_printed = ANYWHERE; -+ } -+ -+ if (use_col_separator) -+ print_sep_string (); -+ -+ if (p->numbered) -+ add_line_number (p); -+} -+ -+/* Print one page. -+ -+ As long as there are lines left on the page and columns ready to print, -+ Scan across the column list -+ if the column has stored lines or the file is open -+ pad to the appropriate spot -+ print the column -+ pad the remainder of the page with \n or \f as requested -+ reset the status of all files -- any files which where on hold because -+ of formfeeds are now put back into the lineup. */ -+ -+static bool -+print_page (void) -+{ -+ int j; -+ int lines_left_on_page; -+ COLUMN *p; -+ -+ /* Used as an accumulator (with | operator) of successive values of -+ pad_vertically. The trick is to set pad_vertically -+ to false before each run through the inner loop, then after that -+ loop, it tells us whether a line was actually printed (whether a -+ newline needs to be output -- or two for double spacing). But those -+ values have to be accumulated (in pv) so we can invoke pad_down -+ properly after the outer loop completes. */ -+ bool pv; -+ -+ init_page (); -+ -+ if (cols_ready_to_print () == 0) -+ return false; -+ -+ if (extremities) -+ print_a_header = true; -+ -+ /* Don't pad unless we know a page was printed. */ -+ pad_vertically = false; -+ pv = false; -+ -+ lines_left_on_page = lines_per_body; -+ if (double_space) -+ lines_left_on_page *= 2; -+ -+ while (lines_left_on_page > 0 && cols_ready_to_print () > 0) -+ { -+ output_position = 0; -+ spaces_not_printed = 0; -+ separators_not_printed = 0; -+ pad_vertically = false; -+ align_empty_cols = false; -+ empty_line = true; -+ -+ for (j = 1, p = column_vector; j <= columns; ++j, ++p) -+ { -+ input_position = 0; -+ if (p->lines_to_print > 0 || p->status == FF_FOUND) -+ { -+ FF_only = false; -+ padding_not_printed = p->start_position; -+ if (!(p->print_func) (p)) -+ read_rest_of_line (p); -+ pv |= pad_vertically; -+ -+ --p->lines_to_print; -+ if (p->lines_to_print <= 0) -+ { -+ if (cols_ready_to_print () <= 0) -+ break; -+ } -+ -+ /* File p changed its status to ON_HOLD or CLOSED */ -+ if (parallel_files && p->status != OPEN) -+ { -+ if (empty_line) -+ align_empty_cols = true; -+ else if (p->status == CLOSED || -+ (p->status == ON_HOLD && FF_only)) -+ align_column (p); -+ } -+ } -+ else if (parallel_files) -+ { -+ /* File status ON_HOLD or CLOSED */ -+ if (empty_line) -+ align_empty_cols = true; -+ else -+ align_column (p); -+ } -+ -+ /* We need it also with an empty column */ -+ if (use_col_separator) -+ ++separators_not_printed; -+ } -+ -+ if (pad_vertically) -+ { -+ putchar ('\n'); -+ --lines_left_on_page; -+ } -+ -+ if (cols_ready_to_print () <= 0 && !extremities) -+ break; -+ -+ if (double_space && pv) -+ { -+ putchar ('\n'); -+ --lines_left_on_page; -+ } -+ } -+ -+ if (lines_left_on_page == 0) -+ for (j = 1, p = column_vector; j <= columns; ++j, ++p) -+ if (p->status == OPEN) -+ p->full_page_printed = true; -+ -+ pad_vertically = pv; -+ -+ if (pad_vertically && extremities) -+ pad_down (lines_left_on_page + lines_per_footer); -+ else if (keep_FF && print_a_FF) -+ { -+ putchar ('\f'); -+ print_a_FF = false; -+ } -+ -+ if (last_page_number < page_number) -+ return false; /* Stop printing with LAST_PAGE */ -+ -+ reset_status (); /* Change ON_HOLD to OPEN. */ -+ -+ return true; /* More pages to go. */ -+} -+ -+/* Allocate space for storing columns. -+ -+ This is necessary when printing multiple columns from a single file. -+ Lines are stored consecutively in buff, separated by '\0'. -+ -+ The following doesn't apply any longer - any tuning possible? -+ (We can't use a fixed offset since with the '-s' flag lines aren't -+ truncated.) -+ -+ We maintain a list (line_vector) of pointers to the beginnings -+ of lines in buff. We allocate one more than the number of lines -+ because the last entry tells us the index of the last character, -+ which we need to know in order to print the last line in buff. */ -+ -+static void -+init_store_cols (void) -+{ -+ int total_lines = lines_per_body * columns; -+ int chars_if_truncate = total_lines * (chars_per_column + 1); -+ -+ free (line_vector); -+ /* FIXME: here's where it was allocated. */ -+ line_vector = xmalloc ((total_lines + 1) * sizeof (int *)); -+ -+ free (end_vector); -+ end_vector = xmalloc (total_lines * sizeof (int *)); -+ -+ free (buff); -+ buff_allocated = (use_col_separator -+ ? 2 * chars_if_truncate -+ : chars_if_truncate); /* Tune this. */ -+ buff = xmalloc (buff_allocated); -+} -+ -+/* Store all but the rightmost column. -+ (Used when printing a single file in multiple downward columns) -+ -+ For each column -+ set p->current_line to be the index in line_vector of the -+ first line in the column -+ For each line in the column -+ store the line in buff -+ add to line_vector the index of the line's first char -+ buff_start is the index in buff of the first character in the -+ current line. */ -+ -+static void -+store_columns (void) -+{ -+ int i, j; -+ unsigned int line = 0; -+ unsigned int buff_start; -+ int last_col; /* The rightmost column which will be saved in buff */ -+ COLUMN *p; -+ -+ buff_current = 0; -+ buff_start = 0; -+ -+ if (balance_columns) -+ last_col = columns; -+ else -+ last_col = columns - 1; -+ -+ for (i = 1, p = column_vector; i <= last_col; ++i, ++p) -+ p->lines_stored = 0; -+ -+ for (i = 1, p = column_vector; i <= last_col && files_ready_to_read; -+ ++i, ++p) -+ { -+ p->current_line = line; -+ for (j = lines_per_body; j && files_ready_to_read; --j) -+ -+ if (p->status == OPEN) /* Redundant. Clean up. */ -+ { -+ input_position = 0; -+ -+ if (!read_line (p)) -+ read_rest_of_line (p); -+ -+ if (p->status == OPEN -+ || buff_start != buff_current) -+ { -+ ++p->lines_stored; -+ line_vector[line] = buff_start; -+ end_vector[line++] = input_position; -+ buff_start = buff_current; -+ } -+ } -+ } -+ -+ /* Keep track of the location of the last char in buff. */ -+ line_vector[line] = buff_start; -+ -+ if (balance_columns) -+ balance (line); -+} -+ -+static void -+balance (int total_stored) -+{ -+ COLUMN *p; -+ int i, lines; -+ int first_line = 0; -+ -+ for (i = 1, p = column_vector; i <= columns; ++i, ++p) -+ { -+ lines = total_stored / columns; -+ if (i <= total_stored % columns) -+ ++lines; -+ -+ p->lines_stored = lines; -+ p->current_line = first_line; -+ -+ first_line += lines; -+ } -+} -+ -+/* Store a character in the buffer. */ -+ -+static void -+store_char (char c) -+{ -+ if (buff_current >= buff_allocated) -+ { -+ /* May be too generous. */ -+ buff = X2REALLOC (buff, &buff_allocated); -+ } -+ buff[buff_current++] = c; -+} -+ -+static void -+add_line_number (COLUMN *p) -+{ -+ int i; -+ char *s; -+ int left_cut; -+ -+ /* Cutting off the higher-order digits is more informative than -+ lower-order cut off*/ -+ if (line_number < power_10) -+ sprintf (number_buff, "%*d", chars_per_number, line_number); -+ else -+ { -+ left_cut = line_number % power_10; -+ sprintf (number_buff, "%0*d", chars_per_number, left_cut); -+ } -+ line_number++; -+ s = number_buff; -+ for (i = chars_per_number; i > 0; i--) -+ (p->char_func) (*s++); -+ -+ if (columns > 1) -+ { -+ /* 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') -+ { -+ i = number_width - chars_per_number; -+ while (i-- > 0) -+ (p->char_func) (' '); -+ } -+ else -+ (p->char_func) (number_separator); -+ } -+ 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') -+ output_position = POS_AFTER_TAB (chars_per_output_tab, -+ output_position); -+ } -+ -+ if (truncate_lines && !parallel_files) -+ input_position += number_width; -+} -+ -+/* Print (or store) padding until the current horizontal position -+ is position. */ -+ -+static void -+pad_across_to (int position) -+{ -+ int h = output_position; -+ -+ if (tabify_output) -+ spaces_not_printed = position - output_position; -+ else -+ { -+ while (++h <= position) -+ putchar (' '); -+ output_position = position; -+ } -+} -+ -+/* Pad to the bottom of the page. -+ -+ If the user has requested a formfeed, use one. -+ Otherwise, use newlines. */ -+ -+static void -+pad_down (int lines) -+{ -+ int i; -+ -+ if (use_form_feed) -+ putchar ('\f'); -+ else -+ for (i = lines; i; --i) -+ putchar ('\n'); -+} -+ -+/* Read the rest of the line. -+ -+ Read from the current column's file until an end of line is -+ hit. Used when we've truncated a line and we no longer need -+ to print or store its characters. */ -+ -+static void -+read_rest_of_line (COLUMN *p) -+{ -+ int c; -+ FILE *f = p->fp; -+ -+ while ((c = getc (f)) != '\n') -+ { -+ if (c == '\f') -+ { -+ if ((c = getc (f)) != '\n') -+ ungetc (c, f); -+ if (keep_FF) -+ print_a_FF = true; -+ hold_file (p); -+ break; -+ } -+ else if (c == EOF) -+ { -+ close_file (p); -+ break; -+ } -+ } -+} -+ -+/* Read a line with skip_to_page. -+ -+ Read from the current column's file until an end of line is -+ hit. Used when we read full lines to skip pages. -+ With skip_to_page we have to check for FF-coincidence which is done -+ in function read_line otherwise. -+ Count lines of skipped pages to find the line number of 1st page -+ printed relative to 1st line of input file (start_line_num). */ -+ -+static void -+skip_read (COLUMN *p, int column_number) -+{ -+ int c; -+ FILE *f = p->fp; -+ int i; -+ bool single_ff = false; -+ COLUMN *q; -+ -+ /* Read 1st character in a line or any character succeeding a FF */ -+ if ((c = getc (f)) == '\f' && p->full_page_printed) -+ /* A FF-coincidence with a previous full_page_printed. -+ To avoid an additional empty page, eliminate the FF */ -+ if ((c = getc (f)) == '\n') -+ c = getc (f); -+ -+ p->full_page_printed = false; -+ -+ /* 1st character a FF means a single FF without any printable -+ characters. Don't count it as a line with -n option. */ -+ if (c == '\f') -+ single_ff = true; -+ -+ /* Preparing for a FF-coincidence: Maybe we finish that page -+ without a FF found */ -+ if (last_line) -+ p->full_page_printed = true; -+ -+ while (c != '\n') -+ { -+ if (c == '\f') -+ { -+ /* No FF-coincidence possible, -+ no catching up of a FF-coincidence with next page */ -+ if (last_line) -+ { -+ if (!parallel_files) -+ for (q = column_vector, i = columns; i; ++q, --i) -+ q->full_page_printed = false; -+ else -+ p->full_page_printed = false; -+ } -+ -+ if ((c = getc (f)) != '\n') -+ ungetc (c, f); -+ hold_file (p); -+ break; -+ } -+ else if (c == EOF) -+ { -+ close_file (p); -+ break; -+ } -+ c = getc (f); -+ } -+ -+ if (skip_count) -+ if ((!parallel_files || column_number == 1) && !single_ff) -+ ++line_count; -+} -+ -+/* If we're tabifying output, -+ -+ When print_char encounters white space it keeps track -+ of our desired horizontal position and delays printing -+ until this function is called. */ -+ -+static void -+print_white_space (void) -+{ -+ int h_new; -+ int h_old = output_position; -+ int goal = h_old + spaces_not_printed; -+ -+ while (goal - h_old > 1 -+ && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) -+ { -+ putchar (output_tab_char); -+ h_old = h_new; -+ } -+ while (++h_old <= goal) -+ putchar (' '); -+ -+ output_position = goal; -+ spaces_not_printed = 0; -+} -+ -+/* Print column separators. -+ -+ We keep a count until we know that we'll be printing a line, -+ then print_sep_string() is called. */ -+ -+static void -+print_sep_string (void) -+{ -+ char *s; -+ int l = col_sep_length; -+ -+ s = col_sep_string; -+ -+ if (separators_not_printed <= 0) -+ { -+ /* We'll be starting a line with chars_per_margin, anything else? */ -+ if (spaces_not_printed > 0) -+ print_white_space (); -+ } -+ else -+ { -+ for (; separators_not_printed > 0; --separators_not_printed) -+ { -+ while (l-- > 0) -+ { -+ /* 3 types of sep_strings: spaces only, spaces and chars, -+ chars only */ -+ if (*s == ' ') -+ { -+ /* We're tabifying output; consecutive spaces in -+ sep_string may have to be converted to tabs */ -+ s++; -+ ++spaces_not_printed; -+ } -+ else -+ { -+ if (spaces_not_printed > 0) -+ print_white_space (); -+ putchar (*s++); -+ ++output_position; -+ } -+ } -+ /* sep_string ends with some spaces */ -+ if (spaces_not_printed > 0) -+ print_white_space (); -+ } -+ } -+} -+ -+/* Print (or store, depending on p->char_func) a clump of N -+ characters. */ -+ -+static void -+print_clump (COLUMN *p, int n, char *clump) -+{ -+ while (n--) -+ (p->char_func) (*clump++); -+} -+ -+/* Print a character. -+ -+ Update the following comment: process-char hasn't been used any -+ longer. -+ If we're tabifying, all tabs have been converted to spaces by -+ process_char(). Keep a count of consecutive spaces, and when -+ a nonspace is encountered, call print_white_space() to print the -+ required number of tabs and spaces. */ -+ -+static void -+print_char (char c) -+{ -+ if (tabify_output) -+ { -+ if (c == ' ') -+ { -+ ++spaces_not_printed; -+ return; -+ } -+ else if (spaces_not_printed > 0) -+ print_white_space (); -+ -+ /* Nonprintables are assumed to have width 0, except '\b'. */ -+ if (! isprint (to_uchar (c))) -+ { -+ if (c == '\b') -+ --output_position; -+ } -+ else -+ ++output_position; -+ } -+ putchar (c); -+} -+ -+/* Skip to page PAGE before printing. -+ PAGE may be larger than total number of pages. */ -+ -+static bool -+skip_to_page (uintmax_t page) -+{ -+ uintmax_t n; -+ int i; -+ int j; -+ COLUMN *p; -+ -+ for (n = 1; n < page; ++n) -+ { -+ for (i = 1; i < lines_per_body; ++i) -+ { -+ for (j = 1, p = column_vector; j <= columns; ++j, ++p) -+ if (p->status == OPEN) -+ skip_read (p, j); -+ } -+ last_line = true; -+ for (j = 1, p = column_vector; j <= columns; ++j, ++p) -+ if (p->status == OPEN) -+ skip_read (p, j); -+ -+ if (storing_columns) /* change FF_FOUND to ON_HOLD */ -+ for (j = 1, p = column_vector; j <= columns; ++j, ++p) -+ if (p->status != CLOSED) -+ p->status = ON_HOLD; -+ -+ reset_status (); -+ last_line = false; -+ -+ if (files_ready_to_read < 1) -+ { -+ /* It's very helpful, normally the total number of pages is -+ not known in advance. */ -+ error (0, 0, -+ _("starting page number %"PRIuMAX -+ " exceeds page count %"PRIuMAX), -+ page, n); -+ break; -+ } -+ } -+ return files_ready_to_read > 0; -+} -+ -+/* Print a header. -+ -+ Formfeeds are assumed to use up two lines at the beginning of -+ the page. */ -+ -+static void -+print_header (void) -+{ -+ char page_text[256 + INT_STRLEN_BOUND (page_number)]; -+ int available_width; -+ int lhs_spaces; -+ int rhs_spaces; -+ -+ output_position = 0; -+ pad_across_to (chars_per_margin); -+ print_white_space (); -+ -+ if (page_number == 0) -+ error (EXIT_FAILURE, 0, _("page number overflow")); -+ -+ /* The translator must ensure that formatting the translation of -+ "Page %"PRIuMAX does not generate more than (sizeof page_text - 1) -+ bytes. */ -+ sprintf (page_text, _("Page %"PRIuMAX), page_number++); -+ available_width = header_width_available - mbswidth (page_text, 0); -+ available_width = MAX (0, available_width); -+ lhs_spaces = available_width >> 1; -+ rhs_spaces = available_width - lhs_spaces; -+ -+ printf ("\n\n%*.*s%s%*.*s%s%*.*s%s\n\n\n", -+ chars_per_margin, chars_per_margin, " ", -+ date_text, lhs_spaces, lhs_spaces, " ", -+ file_text, rhs_spaces, rhs_spaces, " ", page_text); -+ -+ print_a_header = false; -+ output_position = 0; -+} -+ -+/* Print (or store, if p->char_func is store_char()) a line. -+ -+ Read a character to determine whether we have a line or not. -+ (We may hit EOF, \n, or \f) -+ -+ Once we know we have a line, -+ set pad_vertically = true, meaning it's safe -+ to pad down at the end of the page, since we do have a page. -+ print a header if needed. -+ pad across to padding_not_printed if needed. -+ print any separators which need to be printed. -+ print a line number if it needs to be printed. -+ -+ Print the clump which corresponds to the first character. -+ -+ Enter a loop and keep printing until an end of line condition -+ exists, or until we exceed chars_per_column. -+ -+ Return false if we exceed chars_per_column before reading -+ an end of line character, true otherwise. */ -+ -+static bool -+read_line (COLUMN *p) -+{ -+ int c; -+ int chars IF_LINT (= 0); -+ int last_input_position; -+ int j, k; -+ COLUMN *q; -+ -+ /* read 1st character in each line or any character succeeding a FF: */ -+ c = getc (p->fp); -+ -+ last_input_position = input_position; -+ -+ if (c == '\f' && p->full_page_printed) -+ if ((c = getc (p->fp)) == '\n') -+ c = getc (p->fp); -+ p->full_page_printed = false; -+ -+ switch (c) -+ { -+ case '\f': -+ if ((c = getc (p->fp)) != '\n') -+ ungetc (c, p->fp); -+ FF_only = true; -+ if (print_a_header && !storing_columns) -+ { -+ pad_vertically = true; -+ print_header (); -+ } -+ else if (keep_FF) -+ print_a_FF = true; -+ hold_file (p); -+ return true; -+ case EOF: -+ close_file (p); -+ return true; -+ case '\n': -+ break; -+ default: -+ chars = char_to_clump (c); -+ } -+ -+ if (truncate_lines && input_position > chars_per_column) -+ { -+ input_position = last_input_position; -+ return false; -+ } -+ -+ if (p->char_func != store_char) -+ { -+ pad_vertically = true; -+ -+ if (print_a_header && !storing_columns) -+ print_header (); -+ -+ if (parallel_files && align_empty_cols) -+ { -+ /* We have to align empty columns at the beginning of a line. */ -+ k = separators_not_printed; -+ separators_not_printed = 0; -+ for (j = 1, q = column_vector; j <= k; ++j, ++q) -+ { -+ align_column (q); -+ separators_not_printed += 1; -+ } -+ padding_not_printed = p->start_position; -+ if (truncate_lines) -+ spaces_not_printed = chars_per_column; -+ else -+ spaces_not_printed = 0; -+ align_empty_cols = false; -+ } -+ -+ if (padding_not_printed - col_sep_length > 0) -+ { -+ pad_across_to (padding_not_printed - col_sep_length); -+ padding_not_printed = ANYWHERE; -+ } -+ -+ if (use_col_separator) -+ print_sep_string (); -+ } -+ -+ if (p->numbered) -+ add_line_number (p); -+ -+ empty_line = false; -+ if (c == '\n') -+ return true; -+ -+ print_clump (p, chars, clump_buff); -+ -+ for (;;) -+ { -+ c = getc (p->fp); -+ -+ switch (c) -+ { -+ case '\n': -+ return true; -+ case '\f': -+ if ((c = getc (p->fp)) != '\n') -+ ungetc (c, p->fp); -+ if (keep_FF) -+ print_a_FF = true; -+ hold_file (p); -+ return true; -+ case EOF: -+ close_file (p); -+ return true; -+ } -+ -+ last_input_position = input_position; -+ chars = char_to_clump (c); -+ if (truncate_lines && input_position > chars_per_column) -+ { -+ input_position = last_input_position; -+ return false; -+ } -+ -+ print_clump (p, chars, clump_buff); -+ } -+} -+ -+/* Print a line from buff. -+ -+ If this function has been called, we know we have "something to -+ print". But it remains to be seen whether we have a real text page -+ or an empty page (a single form feed) with/without a header only. -+ Therefore first we set pad_vertically to true and print a header -+ if necessary. -+ If FF_FOUND and we are using -t|-T option we omit any newline by -+ setting pad_vertically to false (see print_page). -+ Otherwise we pad across if necessary, print separators if necessary -+ and text of COLUMN *p. -+ -+ Return true, meaning there is no need to call read_rest_of_line. */ -+ -+static bool -+print_stored (COLUMN *p) -+{ -+ COLUMN *q; -+ int i; -+ -+ int line = p->current_line++; -+ char *first = &buff[line_vector[line]]; -+ /* FIXME -+ UMR: Uninitialized memory read: -+ * This is occurring while in: -+ print_stored [pr.c:2239] -+ * Reading 4 bytes from 0x5148c in the heap. -+ * Address 0x5148c is 4 bytes into a malloc'd block at 0x51488 of 676 bytes -+ * This block was allocated from: -+ malloc [rtlib.o] -+ xmalloc [xmalloc.c:94] -+ init_store_cols [pr.c:1648] -+ */ -+ char *last = &buff[line_vector[line + 1]]; -+ -+ pad_vertically = true; -+ -+ if (print_a_header) -+ print_header (); -+ -+ if (p->status == FF_FOUND) -+ { -+ for (i = 1, q = column_vector; i <= columns; ++i, ++q) -+ q->status = ON_HOLD; -+ if (column_vector->lines_to_print <= 0) -+ { -+ if (!extremities) -+ pad_vertically = false; -+ return true; /* print a header only */ -+ } -+ } -+ -+ if (padding_not_printed - col_sep_length > 0) -+ { -+ pad_across_to (padding_not_printed - col_sep_length); -+ padding_not_printed = ANYWHERE; -+ } -+ -+ if (use_col_separator) -+ print_sep_string (); -+ -+ while (first != last) -+ print_char (*first++); -+ -+ 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; -+ } -+ -+ return true; -+} -+ -+/* Convert a character to the proper format and return the number of -+ characters in the resulting clump. Increment input_position by -+ the width of the clump. -+ -+ Tabs are converted to clumps of spaces. -+ Nonprintable characters may be converted to clumps of escape -+ sequences or control prefixes. -+ -+ Note: the width of a clump is not necessarily equal to the number of -+ characters in clump_buff. (e.g, the width of '\b' is -1, while the -+ number of characters is 1.) */ -+ -+static int -+char_to_clump (char c) -+{ -+ unsigned char uc = c; -+ char *s = clump_buff; -+ int i; -+ char esc_buff[4]; -+ int width; -+ int chars; -+ int chars_per_c = 8; -+ -+ if (c == input_tab_char) -+ chars_per_c = chars_per_input_tab; -+ -+ if (c == input_tab_char || c == '\t') -+ { -+ width = TAB_WIDTH (chars_per_c, input_position); -+ -+ if (untabify_input) -+ { -+ for (i = width; i; --i) -+ *s++ = ' '; -+ chars = width; -+ } -+ else -+ { -+ *s = c; -+ chars = 1; -+ } -+ -+ } -+ else if (! isprint (uc)) -+ { -+ if (use_esc_sequence) -+ { -+ width = 4; -+ chars = 4; -+ *s++ = '\\'; -+ sprintf (esc_buff, "%03o", uc); -+ for (i = 0; i <= 2; ++i) -+ *s++ = esc_buff[i]; -+ } -+ else if (use_cntrl_prefix) -+ { -+ if (uc < 0200) -+ { -+ width = 2; -+ chars = 2; -+ *s++ = '^'; -+ *s++ = c ^ 0100; -+ } -+ else -+ { -+ width = 4; -+ chars = 4; -+ *s++ = '\\'; -+ sprintf (esc_buff, "%03o", uc); -+ for (i = 0; i <= 2; ++i) -+ *s++ = esc_buff[i]; -+ } -+ } -+ else if (c == '\b') -+ { -+ width = -1; -+ chars = 1; -+ *s = c; -+ } -+ else -+ { -+ width = 0; -+ chars = 1; -+ *s = c; -+ } -+ } -+ else -+ { -+ width = 1; -+ chars = 1; -+ *s = c; -+ } -+ -+ /* 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; -+} -+ -+/* We've just printed some files and need to clean up things before -+ looking for more options and printing the next batch of files. -+ -+ Free everything we've xmalloc'ed, except `header'. */ -+ -+static void -+cleanup (void) -+{ -+ free (number_buff); -+ free (clump_buff); -+ free (column_vector); -+ free (line_vector); -+ free (end_vector); -+ free (buff); -+} -+ -+/* Complain, print a usage message, and die. */ -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... [FILE]...\n\ -+"), -+ program_name); -+ -+ fputs (_("\ -+Paginate or columnate FILE(s) for printing.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ +FIRST_PAGE[:LAST_PAGE], --pages=FIRST_PAGE[:LAST_PAGE]\n\ -+ begin [stop] printing with page FIRST_[LAST_]PAGE\n\ -+ -COLUMN, --columns=COLUMN\n\ -+ output COLUMN columns and print columns down,\n\ -+ unless -a is used. Balance number of lines in the\n\ -+ columns on each page.\n\ -+"), stdout); -+ fputs (_("\ -+ -a, --across print columns across rather than down, used together\n\ -+ with -COLUMN\n\ -+ -c, --show-control-chars\n\ -+ use hat notation (^G) and octal backslash notation\n\ -+ -d, --double-space\n\ -+ double space the output\n\ -+"), stdout); -+ fputs (_("\ -+ -D, --date-format=FORMAT\n\ -+ use FORMAT for the header date\n\ -+ -e[CHAR[WIDTH]], --expand-tabs[=CHAR[WIDTH]]\n\ -+ expand input CHARs (TABs) to tab WIDTH (8)\n\ -+ -F, -f, --form-feed\n\ -+ use form feeds instead of newlines to separate pages\n\ -+ (by a 3-line page header with -F or a 5-line header\n\ -+ and trailer without -F)\n\ -+"), stdout); -+ fputs (_("\ -+ -h, --header=HEADER\n\ -+ use a centered HEADER instead of filename in page header,\n\ -+ -h \"\" prints a blank line, don't use -h\"\"\n\ -+ -i[CHAR[WIDTH]], --output-tabs[=CHAR[WIDTH]]\n\ -+ replace spaces with CHARs (TABs) to tab WIDTH (8)\n\ -+ -J, --join-lines merge full lines, turns off -W line truncation, no column\n\ -+ alignment, --sep-string[=STRING] sets separators\n\ -+"), stdout); -+ fputs (_("\ -+ -l, --length=PAGE_LENGTH\n\ -+ set the page length to PAGE_LENGTH (66) lines\n\ -+ (default number of lines of text 56, and with -F 63)\n\ -+ -m, --merge print all files in parallel, one in each column,\n\ -+ truncate lines, but join lines of full length with -J\n\ -+"), stdout); -+ fputs (_("\ -+ -n[SEP[DIGITS]], --number-lines[=SEP[DIGITS]]\n\ -+ number lines, use DIGITS (5) digits, then SEP (TAB),\n\ -+ default counting starts with 1st line of input file\n\ -+ -N, --first-line-number=NUMBER\n\ -+ start counting with NUMBER at 1st line of first\n\ -+ page printed (see +FIRST_PAGE)\n\ -+"), stdout); -+ fputs (_("\ -+ -o, --indent=MARGIN\n\ -+ offset each line with MARGIN (zero) spaces, do not\n\ -+ affect -w or -W, MARGIN will be added to PAGE_WIDTH\n\ -+ -r, --no-file-warnings\n\ -+ omit warning when a file cannot be opened\n\ -+"), stdout); -+ fputs (_("\ -+ -s[CHAR],--separator[=CHAR]\n\ -+ separate columns by a single character, default for CHAR\n\ -+ is the character without -w and \'no char\' with -w\n\ -+ -s[CHAR] turns off line truncation of all 3 column\n\ -+ options (-COLUMN|-a -COLUMN|-m) except -w is set\n\ -+"), stdout); -+ fputs (_("\ -+ -SSTRING, --sep-string[=STRING]\n\ -+ separate columns by STRING,\n\ -+ without -S: Default separator with -J and \n\ -+ otherwise (same as -S\" \"), no effect on column options\n\ -+ -t, --omit-header omit page headers and trailers\n\ -+"), stdout); -+ fputs (_("\ -+ -T, --omit-pagination\n\ -+ omit page headers and trailers, eliminate any pagination\n\ -+ by form feeds set in input files\n\ -+ -v, --show-nonprinting\n\ -+ use octal backslash notation\n\ -+ -w, --width=PAGE_WIDTH\n\ -+ set page width to PAGE_WIDTH (72) characters for\n\ -+ multiple text-column output only, -s[char] turns off (72)\n\ -+"), stdout); -+ fputs (_("\ -+ -W, --page-width=PAGE_WIDTH\n\ -+ set page width to PAGE_WIDTH (72) characters always,\n\ -+ truncate lines, except -J option is set, no interference\n\ -+ with -S or -s\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ fputs (_("\ -+\n\ -+-t is implied if PAGE_LENGTH <= 10. With no FILE, or when\n\ -+FILE is -, read standard input.\n\ -+"), stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c --- coreutils-8.0-orig/src/sort.c 2009-09-29 15:27:54.000000000 +0200 +++ coreutils-8.0/src/sort.c 2009-10-07 10:07:16.000000000 +0200 @@ -9232,3707 +3281,6 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c } break; -diff -urNp coreutils-8.0-orig/src/sort.c.orig coreutils-8.0/src/sort.c.orig ---- coreutils-8.0-orig/src/sort.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/sort.c.orig 2009-09-29 15:27:54.000000000 +0200 -@@ -0,0 +1,3697 @@ -+/* sort - sort lines of text (with all kinds of options). -+ Copyright (C) 1988, 1991-2009 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 December 1988 by Mike Haertel. -+ The author may be reached (Email) at the address mike@gnu.ai.mit.edu, -+ or (US mail) as Mike Haertel c/o Free Software Foundation. -+ -+ Ørn E. Hansen added NLS support in 1997. */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include "system.h" -+#include "argmatch.h" -+#include "error.h" -+#include "filevercmp.h" -+#include "hard-locale.h" -+#include "hash.h" -+#include "md5.h" -+#include "physmem.h" -+#include "posixver.h" -+#include "quote.h" -+#include "quotearg.h" -+#include "randread.h" -+#include "readtokens0.h" -+#include "stdio--.h" -+#include "stdlib--.h" -+#include "strnumcmp.h" -+#include "xmemcoll.h" -+#include "xmemxfrm.h" -+#include "xstrtol.h" -+ -+#if HAVE_SYS_RESOURCE_H -+# include -+#endif -+#ifndef RLIMIT_DATA -+struct rlimit { size_t rlim_cur; }; -+# define getrlimit(Resource, Rlp) (-1) -+#endif -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "sort" -+ -+#define AUTHORS \ -+ proper_name ("Mike Haertel"), \ -+ proper_name ("Paul Eggert") -+ -+#if HAVE_LANGINFO_CODESET -+# include -+#endif -+ -+/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is -+ present. */ -+#ifndef SA_NOCLDSTOP -+# define SA_NOCLDSTOP 0 -+/* No sigprocmask. Always 'return' zero. */ -+# define sigprocmask(How, Set, Oset) (0) -+# define sigset_t int -+# if ! HAVE_SIGINTERRUPT -+# define siginterrupt(sig, flag) /* empty */ -+# endif -+#endif -+ -+#if !defined OPEN_MAX && defined NR_OPEN -+# define OPEN_MAX NR_OPEN -+#endif -+#if !defined OPEN_MAX -+# define OPEN_MAX 20 -+#endif -+ -+#define UCHAR_LIM (UCHAR_MAX + 1) -+ -+#ifndef DEFAULT_TMPDIR -+# define DEFAULT_TMPDIR "/tmp" -+#endif -+ -+/* Exit statuses. */ -+enum -+ { -+ /* POSIX says to exit with status 1 if invoked with -c and the -+ input is not properly sorted. */ -+ SORT_OUT_OF_ORDER = 1, -+ -+ /* POSIX says any other irregular exit must exit with a status -+ code greater than 1. */ -+ SORT_FAILURE = 2 -+ }; -+ -+enum -+ { -+ /* The number of times we should try to fork a compression process -+ (we retry if the fork call fails). We don't _need_ to compress -+ temp files, this is just to reduce disk access, so this number -+ can be small. */ -+ MAX_FORK_TRIES_COMPRESS = 2, -+ -+ /* The number of times we should try to fork a decompression process. -+ If we can't fork a decompression process, we can't sort, so this -+ number should be big. */ -+ MAX_FORK_TRIES_DECOMPRESS = 8 -+ }; -+ -+/* The representation of the decimal point in the current locale. */ -+static int decimal_point; -+ -+/* Thousands separator; if -1, then there isn't one. */ -+static int thousands_sep; -+ -+/* Nonzero if the corresponding locales are hard. */ -+static bool hard_LC_COLLATE; -+#if HAVE_NL_LANGINFO -+static bool hard_LC_TIME; -+#endif -+ -+#define NONZERO(x) ((x) != 0) -+ -+/* The kind of blanks for '-b' to skip in various options. */ -+enum blanktype { bl_start, bl_end, bl_both }; -+ -+/* The character marking end of line. Default to \n. */ -+static char eolchar = '\n'; -+ -+/* Lines are held in core as counted strings. */ -+struct line -+{ -+ char *text; /* Text of the line. */ -+ size_t length; /* Length including final newline. */ -+ char *keybeg; /* Start of first key. */ -+ char *keylim; /* Limit of first key. */ -+}; -+ -+/* Input buffers. */ -+struct buffer -+{ -+ char *buf; /* Dynamically allocated buffer, -+ partitioned into 3 regions: -+ - input data; -+ - unused area; -+ - an array of lines, in reverse order. */ -+ size_t used; /* Number of bytes used for input data. */ -+ size_t nlines; /* Number of lines in the line array. */ -+ size_t alloc; /* Number of bytes allocated. */ -+ size_t left; /* Number of bytes left from previous reads. */ -+ size_t line_bytes; /* Number of bytes to reserve for each line. */ -+ bool eof; /* An EOF has been read. */ -+}; -+ -+struct keyfield -+{ -+ size_t sword; /* Zero-origin 'word' to start at. */ -+ size_t schar; /* Additional characters to skip. */ -+ size_t eword; /* Zero-origin first word after field. */ -+ size_t echar; /* Additional characters in field. */ -+ bool const *ignore; /* Boolean array of characters to ignore. */ -+ char const *translate; /* Translation applied to characters. */ -+ bool skipsblanks; /* Skip leading blanks when finding start. */ -+ bool skipeblanks; /* Skip leading blanks when finding end. */ -+ bool numeric; /* Flag for numeric comparison. Handle -+ strings of digits with optional decimal -+ point, but no exponential notation. */ -+ bool random; /* Sort by random hash of key. */ -+ bool general_numeric; /* Flag for general, numeric comparison. -+ Handle numbers in exponential notation. */ -+ bool human_numeric; /* Flag for sorting by human readable -+ units with either SI xor IEC prefixes. */ -+ int si_present; /* Flag for checking for mixed SI and IEC. */ -+ bool month; /* Flag for comparison by month name. */ -+ bool reverse; /* Reverse the sense of comparison. */ -+ bool version; /* sort by version number */ -+ struct keyfield *next; /* Next keyfield to try. */ -+}; -+ -+struct month -+{ -+ char const *name; -+ int val; -+}; -+ -+/* FIXME: None of these tables work with multibyte character sets. -+ Also, there are many other bugs when handling multibyte characters. -+ One way to fix this is to rewrite `sort' to use wide characters -+ internally, but doing this with good performance is a bit -+ tricky. */ -+ -+/* Table of blanks. */ -+static bool blanks[UCHAR_LIM]; -+ -+/* Table of non-printing characters. */ -+static bool nonprinting[UCHAR_LIM]; -+ -+/* Table of non-dictionary characters (not letters, digits, or blanks). */ -+static bool nondictionary[UCHAR_LIM]; -+ -+/* Translation table folding lower case to upper. */ -+static char fold_toupper[UCHAR_LIM]; -+ -+#define MONTHS_PER_YEAR 12 -+ -+/* Table mapping month names to integers. -+ Alphabetic order allows binary search. */ -+static struct month monthtab[] = -+{ -+ {"APR", 4}, -+ {"AUG", 8}, -+ {"DEC", 12}, -+ {"FEB", 2}, -+ {"JAN", 1}, -+ {"JUL", 7}, -+ {"JUN", 6}, -+ {"MAR", 3}, -+ {"MAY", 5}, -+ {"NOV", 11}, -+ {"OCT", 10}, -+ {"SEP", 9} -+}; -+ -+/* During the merge phase, the number of files to merge at once. */ -+#define NMERGE_DEFAULT 16 -+ -+/* Minimum size for a merge or check buffer. */ -+#define MIN_MERGE_BUFFER_SIZE (2 + sizeof (struct line)) -+ -+/* Minimum sort size; the code might not work with smaller sizes. */ -+#define MIN_SORT_SIZE (nmerge * MIN_MERGE_BUFFER_SIZE) -+ -+/* The number of bytes needed for a merge or check buffer, which can -+ function relatively efficiently even if it holds only one line. If -+ a longer line is seen, this value is increased. */ -+static size_t merge_buffer_size = MAX (MIN_MERGE_BUFFER_SIZE, 256 * 1024); -+ -+/* The approximate maximum number of bytes of main memory to use, as -+ specified by the user. Zero if the user has not specified a size. */ -+static size_t sort_size; -+ -+/* The guessed size for non-regular files. */ -+#define INPUT_FILE_SIZE_GUESS (1024 * 1024) -+ -+/* Array of directory names in which any temporary files are to be created. */ -+static char const **temp_dirs; -+ -+/* Number of temporary directory names used. */ -+static size_t temp_dir_count; -+ -+/* Number of allocated slots in temp_dirs. */ -+static size_t temp_dir_alloc; -+ -+/* Flag to reverse the order of all comparisons. */ -+static bool reverse; -+ -+/* Flag for stable sort. This turns off the last ditch bytewise -+ comparison of lines, and instead leaves lines in the same order -+ 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 -+ separated by the empty string between a non-blank character and a blank -+ character. */ -+static int tab = TAB_DEFAULT; -+ -+/* Flag to remove consecutive duplicate lines from the output. -+ Only the last of a sequence of equal lines will be output. */ -+static bool unique; -+ -+/* Nonzero if any of the input files are the standard input. */ -+static bool have_read_stdin; -+ -+/* List of key field comparisons to be tried. */ -+static struct keyfield *keylist; -+ -+/* Program used to (de)compress temp files. Must accept -d. */ -+static char const *compress_program; -+ -+/* Maximum number of files to merge in one go. If more than this -+ number are present, temp files will be used. */ -+static unsigned int nmerge = NMERGE_DEFAULT; -+ -+static void sortlines_temp (struct line *, size_t, struct line *); -+ -+/* Report MESSAGE for FILE, then clean up and exit. -+ If FILE is null, it represents standard output. */ -+ -+static void die (char const *, char const *) ATTRIBUTE_NORETURN; -+static void -+die (char const *message, char const *file) -+{ -+ error (0, errno, "%s: %s", message, file ? file : _("standard output")); -+ exit (SORT_FAILURE); -+} -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... [FILE]...\n\ -+ or: %s [OPTION]... --files0-from=F\n\ -+"), -+ program_name, program_name); -+ fputs (_("\ -+Write sorted concatenation of all FILE(s) to standard output.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+Ordering options:\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+ -b, --ignore-leading-blanks ignore leading blanks\n\ -+ -d, --dictionary-order consider only blanks and alphanumeric characters\n\ -+ -f, --ignore-case fold lower case to upper case characters\n\ -+"), stdout); -+ fputs (_("\ -+ -g, --general-numeric-sort compare according to general numerical value\n\ -+ -i, --ignore-nonprinting consider only printable characters\n\ -+ -M, --month-sort compare (unknown) < `JAN' < ... < `DEC'\n\ -+"), stdout); -+ fputs (_("\ -+ -h, --human-numeric-sort compare human readable numbers (e.g., 2K 1G)\n\ -+"), stdout); -+ fputs (_("\ -+ -n, --numeric-sort compare according to string numerical value\n\ -+ -R, --random-sort sort by random hash of keys\n\ -+ --random-source=FILE get random bytes from FILE\n\ -+ -r, --reverse reverse the result of comparisons\n\ -+"), stdout); -+ fputs (_("\ -+ --sort=WORD sort according to WORD:\n\ -+ general-numeric -g, human-numeric -h, month -M,\n\ -+ numeric -n, random -R, version -V\n\ -+ -V, --version-sort natural sort of (version) numbers within text\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Other options:\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+ --batch-size=NMERGE merge at most NMERGE inputs at once;\n\ -+ for more use temp files\n\ -+"), stdout); -+ fputs (_("\ -+ -c, --check, --check=diagnose-first check for sorted input; do not sort\n\ -+ -C, --check=quiet, --check=silent like -c, but do not report first bad line\n\ -+ --compress-program=PROG compress temporaries with PROG;\n\ -+ decompress them with PROG -d\n\ -+ --files0-from=F read input from the files specified by\n\ -+ NUL-terminated names in file F;\n\ -+ If F is - then read names from standard input\n\ -+"), stdout); -+ fputs (_("\ -+ -k, --key=POS1[,POS2] start a key at POS1 (origin 1), end it at POS2\n\ -+ (default end of line)\n\ -+ -m, --merge merge already sorted files; do not sort\n\ -+"), stdout); -+ fputs (_("\ -+ -o, --output=FILE write result to FILE instead of standard output\n\ -+ -s, --stable stabilize sort by disabling last-resort comparison\n\ -+ -S, --buffer-size=SIZE use SIZE for main memory buffer\n\ -+"), stdout); -+ printf (_("\ -+ -t, --field-separator=SEP use SEP instead of non-blank to blank transition\n\ -+ -T, --temporary-directory=DIR use DIR for temporaries, not $TMPDIR or %s;\n\ -+ multiple options specify multiple directories\n\ -+ -u, --unique with -c, check for strict ordering;\n\ -+ without -c, output only the first of an equal run\n\ -+"), DEFAULT_TMPDIR); -+ fputs (_("\ -+ -z, --zero-terminated end lines with 0 byte, not newline\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ fputs (_("\ -+\n\ -+POS is F[.C][OPTS], where F is the field number and C the character position\n\ -+in the field; both are origin 1. If neither -t nor -b is in effect, characters\n\ -+in a field are counted from the beginning of the preceding whitespace. OPTS is\n\ -+one or more single-letter ordering options, which override global ordering\n\ -+options for that key. If no key is given, use the entire line as the key.\n\ -+\n\ -+SIZE may be followed by the following multiplicative suffixes:\n\ -+"), stdout); -+ fputs (_("\ -+% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y.\n\ -+\n\ -+With no FILE, or when FILE is -, read standard input.\n\ -+\n\ -+*** WARNING ***\n\ -+The locale specified by the environment affects sort order.\n\ -+Set LC_ALL=C to get the traditional sort order that uses\n\ -+native byte values.\n\ -+"), stdout ); -+ emit_ancillary_info (); -+ } -+ -+ exit (status); -+} -+ -+/* For long options that have no equivalent short option, use a -+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -+enum -+{ -+ CHECK_OPTION = CHAR_MAX + 1, -+ COMPRESS_PROGRAM_OPTION, -+ FILES0_FROM_OPTION, -+ NMERGE_OPTION, -+ RANDOM_SOURCE_OPTION, -+ SORT_OPTION -+}; -+ -+static char const short_options[] = "-bcCdfghik:mMno:rRsS:t:T:uVy:z"; -+ -+static struct option const long_options[] = -+{ -+ {"ignore-leading-blanks", no_argument, NULL, 'b'}, -+ {"check", optional_argument, NULL, CHECK_OPTION}, -+ {"compress-program", required_argument, NULL, COMPRESS_PROGRAM_OPTION}, -+ {"dictionary-order", no_argument, NULL, 'd'}, -+ {"ignore-case", no_argument, NULL, 'f'}, -+ {"files0-from", required_argument, NULL, FILES0_FROM_OPTION}, -+ {"general-numeric-sort", no_argument, NULL, 'g'}, -+ {"ignore-nonprinting", no_argument, NULL, 'i'}, -+ {"key", required_argument, NULL, 'k'}, -+ {"merge", no_argument, NULL, 'm'}, -+ {"month-sort", no_argument, NULL, 'M'}, -+ {"numeric-sort", no_argument, NULL, 'n'}, -+ {"human-numeric-sort", no_argument, NULL, 'h'}, -+ {"version-sort", no_argument, NULL, 'V'}, -+ {"random-sort", no_argument, NULL, 'R'}, -+ {"random-source", required_argument, NULL, RANDOM_SOURCE_OPTION}, -+ {"sort", required_argument, NULL, SORT_OPTION}, -+ {"output", required_argument, NULL, 'o'}, -+ {"reverse", no_argument, NULL, 'r'}, -+ {"stable", no_argument, NULL, 's'}, -+ {"batch-size", required_argument, NULL, NMERGE_OPTION}, -+ {"buffer-size", required_argument, NULL, 'S'}, -+ {"field-separator", required_argument, NULL, 't'}, -+ {"temporary-directory", required_argument, NULL, 'T'}, -+ {"unique", no_argument, NULL, 'u'}, -+ {"zero-terminated", no_argument, NULL, 'z'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0}, -+}; -+ -+#define CHECK_TABLE \ -+ _ct_("quiet", 'C') \ -+ _ct_("silent", 'C') \ -+ _ct_("diagnose-first", 'c') -+ -+static char const *const check_args[] = -+{ -+#define _ct_(_s, _c) _s, -+ CHECK_TABLE NULL -+#undef _ct_ -+}; -+static char const check_types[] = -+{ -+#define _ct_(_s, _c) _c, -+ CHECK_TABLE -+#undef _ct_ -+}; -+ -+#define SORT_TABLE \ -+ _st_("general-numeric", 'g') \ -+ _st_("human-numeric", 'h') \ -+ _st_("month", 'M') \ -+ _st_("numeric", 'n') \ -+ _st_("random", 'R') \ -+ _st_("version", 'V') -+ -+static char const *const sort_args[] = -+{ -+#define _st_(_s, _c) _s, -+ SORT_TABLE NULL -+#undef _st_ -+}; -+static char const sort_types[] = -+{ -+#define _st_(_s, _c) _c, -+ SORT_TABLE -+#undef _st_ -+}; -+ -+/* The set of signals that are caught. */ -+static sigset_t caught_signals; -+ -+/* Critical section status. */ -+struct cs_status -+{ -+ bool valid; -+ sigset_t sigs; -+}; -+ -+/* Enter a critical section. */ -+static struct cs_status -+cs_enter (void) -+{ -+ struct cs_status status; -+ status.valid = (sigprocmask (SIG_BLOCK, &caught_signals, &status.sigs) == 0); -+ return status; -+} -+ -+/* Leave a critical section. */ -+static void -+cs_leave (struct cs_status status) -+{ -+ if (status.valid) -+ { -+ /* Ignore failure when restoring the signal mask. */ -+ sigprocmask (SIG_SETMASK, &status.sigs, NULL); -+ } -+} -+ -+/* The list of temporary files. */ -+struct tempnode -+{ -+ struct tempnode *volatile next; -+ pid_t pid; /* If compressed, the pid of compressor, else zero */ -+ char name[1]; /* Actual size is 1 + file name length. */ -+}; -+static struct tempnode *volatile temphead; -+static struct tempnode *volatile *temptail = &temphead; -+ -+struct sortfile -+{ -+ char const *name; -+ pid_t pid; /* If compressed, the pid of compressor, else zero */ -+}; -+ -+/* A table where we store compression process states. We clean up all -+ processes in a timely manner so as not to exhaust system resources, -+ so we store the info on whether the process is still running, or has -+ been reaped here. */ -+static Hash_table *proctab; -+ -+enum { INIT_PROCTAB_SIZE = 47 }; -+ -+enum procstate { ALIVE, ZOMBIE }; -+ -+/* A proctab entry. The COUNT field is there in case we fork a new -+ compression process that has the same PID as an old zombie process -+ that is still in the table (because the process to decompress the -+ temp file it was associated with hasn't started yet). */ -+struct procnode -+{ -+ pid_t pid; -+ enum procstate state; -+ size_t count; -+}; -+ -+static size_t -+proctab_hasher (const void *entry, size_t tabsize) -+{ -+ const struct procnode *node = entry; -+ return node->pid % tabsize; -+} -+ -+static bool -+proctab_comparator (const void *e1, const void *e2) -+{ -+ const struct procnode *n1 = e1, *n2 = e2; -+ return n1->pid == n2->pid; -+} -+ -+/* The total number of forked processes (compressors and decompressors) -+ that have not been reaped yet. */ -+static size_t nprocs; -+ -+/* The number of child processes we'll allow before we try to reap some. */ -+enum { MAX_PROCS_BEFORE_REAP = 2 }; -+ -+/* If 0 < PID, wait for the child process with that PID to exit. -+ If PID is -1, clean up a random child process which has finished and -+ return the process ID of that child. If PID is -1 and no processes -+ have quit yet, return 0 without waiting. */ -+ -+static pid_t -+reap (pid_t pid) -+{ -+ int status; -+ pid_t cpid = waitpid (pid, &status, pid < 0 ? WNOHANG : 0); -+ -+ if (cpid < 0) -+ error (SORT_FAILURE, errno, _("waiting for %s [-d]"), -+ compress_program); -+ else if (0 < cpid) -+ { -+ if (! WIFEXITED (status) || WEXITSTATUS (status)) -+ error (SORT_FAILURE, 0, _("%s [-d] terminated abnormally"), -+ compress_program); -+ --nprocs; -+ } -+ -+ return cpid; -+} -+ -+/* Add the PID of a running compression process to proctab, or update -+ the entry COUNT and STATE fields if it's already there. This also -+ creates the table for us the first time it's called. */ -+ -+static void -+register_proc (pid_t pid) -+{ -+ struct procnode test, *node; -+ -+ if (! proctab) -+ { -+ proctab = hash_initialize (INIT_PROCTAB_SIZE, NULL, -+ proctab_hasher, -+ proctab_comparator, -+ free); -+ if (! proctab) -+ xalloc_die (); -+ } -+ -+ test.pid = pid; -+ node = hash_lookup (proctab, &test); -+ if (node) -+ { -+ node->state = ALIVE; -+ ++node->count; -+ } -+ else -+ { -+ node = xmalloc (sizeof *node); -+ node->pid = pid; -+ node->state = ALIVE; -+ node->count = 1; -+ if (hash_insert (proctab, node) == NULL) -+ xalloc_die (); -+ } -+} -+ -+/* This is called when we reap a random process. We don't know -+ whether we have reaped a compression process or a decompression -+ process until we look in the table. If there's an ALIVE entry for -+ it, then we have reaped a compression process, so change the state -+ to ZOMBIE. Otherwise, it's a decompression processes, so ignore it. */ -+ -+static void -+update_proc (pid_t pid) -+{ -+ struct procnode test, *node; -+ -+ test.pid = pid; -+ node = hash_lookup (proctab, &test); -+ if (node) -+ node->state = ZOMBIE; -+} -+ -+/* This is for when we need to wait for a compression process to exit. -+ If it has a ZOMBIE entry in the table then it's already dead and has -+ been reaped. Note that if there's an ALIVE entry for it, it still may -+ already have died and been reaped if a second process was created with -+ the same PID. This is probably exceedingly rare, but to be on the safe -+ side we will have to wait for any compression process with this PID. */ -+ -+static void -+wait_proc (pid_t pid) -+{ -+ struct procnode test, *node; -+ -+ test.pid = pid; -+ node = hash_lookup (proctab, &test); -+ if (node->state == ALIVE) -+ reap (pid); -+ -+ node->state = ZOMBIE; -+ if (! --node->count) -+ { -+ hash_delete (proctab, node); -+ free (node); -+ } -+} -+ -+/* Keep reaping finished children as long as there are more to reap. -+ This doesn't block waiting for any of them, it only reaps those -+ that are already dead. */ -+ -+static void -+reap_some (void) -+{ -+ pid_t pid; -+ -+ while (0 < nprocs && (pid = reap (-1))) -+ update_proc (pid); -+} -+ -+/* Clean up any remaining temporary files. */ -+ -+static void -+cleanup (void) -+{ -+ struct tempnode const *node; -+ -+ for (node = temphead; node; node = node->next) -+ unlink (node->name); -+ temphead = NULL; -+} -+ -+/* Cleanup actions to take when exiting. */ -+ -+static void -+exit_cleanup (void) -+{ -+ if (temphead) -+ { -+ /* Clean up any remaining temporary files in a critical section so -+ that a signal handler does not try to clean them too. */ -+ struct cs_status cs = cs_enter (); -+ cleanup (); -+ cs_leave (cs); -+ } -+ -+ close_stdout (); -+} -+ -+/* Create a new temporary file, returning its newly allocated tempnode. -+ Store into *PFD the file descriptor open for writing. -+ If the creation fails, return NULL and store -1 into *PFD if the -+ failure is due to file descriptor exhaustion and -+ SURVIVE_FD_EXHAUSTION; otherwise, die. */ -+ -+static struct tempnode * -+create_temp_file (int *pfd, bool survive_fd_exhaustion) -+{ -+ static char const slashbase[] = "/sortXXXXXX"; -+ static size_t temp_dir_index; -+ int fd; -+ int saved_errno; -+ char const *temp_dir = temp_dirs[temp_dir_index]; -+ size_t len = strlen (temp_dir); -+ struct tempnode *node = -+ xmalloc (offsetof (struct tempnode, name) + len + sizeof slashbase); -+ char *file = node->name; -+ struct cs_status cs; -+ -+ memcpy (file, temp_dir, len); -+ memcpy (file + len, slashbase, sizeof slashbase); -+ node->next = NULL; -+ node->pid = 0; -+ if (++temp_dir_index == temp_dir_count) -+ temp_dir_index = 0; -+ -+ /* Create the temporary file in a critical section, to avoid races. */ -+ cs = cs_enter (); -+ fd = mkstemp (file); -+ if (0 <= fd) -+ { -+ *temptail = node; -+ temptail = &node->next; -+ } -+ saved_errno = errno; -+ cs_leave (cs); -+ errno = saved_errno; -+ -+ if (fd < 0) -+ { -+ if (! (survive_fd_exhaustion && errno == EMFILE)) -+ error (SORT_FAILURE, errno, _("cannot create temporary file in %s"), -+ quote (temp_dir)); -+ free (node); -+ node = NULL; -+ } -+ -+ *pfd = fd; -+ return node; -+} -+ -+/* Return a stream for FILE, opened with mode HOW. A null FILE means -+ standard output; HOW should be "w". When opening for input, "-" -+ means standard input. To avoid confusion, do not return file -+ descriptors STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO when -+ opening an ordinary FILE. Return NULL if unsuccessful. */ -+ -+static FILE * -+stream_open (const char *file, const char *how) -+{ -+ if (!file) -+ return stdout; -+ if (STREQ (file, "-") && *how == 'r') -+ { -+ have_read_stdin = true; -+ return stdin; -+ } -+ return fopen (file, how); -+} -+ -+/* Same as stream_open, except always return a non-null value; die on -+ failure. */ -+ -+static FILE * -+xfopen (const char *file, const char *how) -+ { -+ FILE *fp = stream_open (file, how); -+ if (!fp) -+ die (_("open failed"), file); -+ return fp; -+} -+ -+/* Close FP, whose name is FILE, and report any errors. */ -+ -+static void -+xfclose (FILE *fp, char const *file) -+{ -+ switch (fileno (fp)) -+ { -+ case STDIN_FILENO: -+ /* Allow reading stdin from tty more than once. */ -+ if (feof (fp)) -+ clearerr (fp); -+ break; -+ -+ case STDOUT_FILENO: -+ /* Don't close stdout just yet. close_stdout does that. */ -+ if (fflush (fp) != 0) -+ die (_("fflush failed"), file); -+ break; -+ -+ default: -+ if (fclose (fp) != 0) -+ die (_("close failed"), file); -+ break; -+ } -+} -+ -+static void -+dup2_or_die (int oldfd, int newfd) -+{ -+ if (dup2 (oldfd, newfd) < 0) -+ error (SORT_FAILURE, errno, _("dup2 failed")); -+} -+ -+/* Fork a child process for piping to and do common cleanup. The -+ TRIES parameter tells us how many times to try to fork before -+ giving up. Return the PID of the child, or -1 (setting errno) -+ on failure. */ -+ -+static pid_t -+pipe_fork (int pipefds[2], size_t tries) -+{ -+#if HAVE_WORKING_FORK -+ struct tempnode *saved_temphead; -+ int saved_errno; -+ unsigned int wait_retry = 1; -+ pid_t pid IF_LINT (= -1); -+ struct cs_status cs; -+ -+ if (pipe (pipefds) < 0) -+ return -1; -+ -+ while (tries--) -+ { -+ /* This is so the child process won't delete our temp files -+ if it receives a signal before exec-ing. */ -+ cs = cs_enter (); -+ saved_temphead = temphead; -+ temphead = NULL; -+ -+ pid = fork (); -+ saved_errno = errno; -+ if (pid) -+ temphead = saved_temphead; -+ -+ cs_leave (cs); -+ errno = saved_errno; -+ -+ if (0 <= pid || errno != EAGAIN) -+ break; -+ else -+ { -+ sleep (wait_retry); -+ wait_retry *= 2; -+ reap_some (); -+ } -+ } -+ -+ if (pid < 0) -+ { -+ saved_errno = errno; -+ close (pipefds[0]); -+ close (pipefds[1]); -+ errno = saved_errno; -+ } -+ else if (pid == 0) -+ { -+ close (STDIN_FILENO); -+ close (STDOUT_FILENO); -+ } -+ else -+ ++nprocs; -+ -+ return pid; -+ -+#else /* ! HAVE_WORKING_FORK */ -+ return -1; -+#endif -+} -+ -+/* Create a temporary file and start a compression program to filter output -+ to that file. Set *PFP to the file handle and if PPID is non-NULL, -+ set *PPID to the PID of the newly-created process. If the creation -+ fails, return NULL if the failure is due to file descriptor -+ exhaustion and SURVIVE_FD_EXHAUSTION; otherwise, die. */ -+ -+static char * -+maybe_create_temp (FILE **pfp, pid_t *ppid, bool survive_fd_exhaustion) -+{ -+ int tempfd; -+ struct tempnode *node = create_temp_file (&tempfd, survive_fd_exhaustion); -+ char *name; -+ -+ if (! node) -+ return NULL; -+ -+ name = node->name; -+ -+ if (compress_program) -+ { -+ int pipefds[2]; -+ -+ node->pid = pipe_fork (pipefds, MAX_FORK_TRIES_COMPRESS); -+ if (0 < node->pid) -+ { -+ close (tempfd); -+ close (pipefds[0]); -+ tempfd = pipefds[1]; -+ -+ register_proc (node->pid); -+ } -+ else if (node->pid == 0) -+ { -+ close (pipefds[1]); -+ dup2_or_die (tempfd, STDOUT_FILENO); -+ close (tempfd); -+ dup2_or_die (pipefds[0], STDIN_FILENO); -+ close (pipefds[0]); -+ -+ if (execlp (compress_program, compress_program, (char *) NULL) < 0) -+ error (SORT_FAILURE, errno, _("couldn't execute %s"), -+ compress_program); -+ } -+ else -+ node->pid = 0; -+ } -+ -+ *pfp = fdopen (tempfd, "w"); -+ if (! *pfp) -+ die (_("couldn't create temporary file"), name); -+ -+ if (ppid) -+ *ppid = node->pid; -+ -+ return name; -+} -+ -+/* Create a temporary file and start a compression program to filter output -+ to that file. Set *PFP to the file handle and if *PPID is non-NULL, -+ set it to the PID of the newly-created process. Die on failure. */ -+ -+static char * -+create_temp (FILE **pfp, pid_t *ppid) -+{ -+ return maybe_create_temp (pfp, ppid, false); -+} -+ -+/* Open a compressed temp file and start a decompression process through -+ which to filter the input. PID must be the valid processes ID of the -+ process used to compress the file. Return NULL (setting errno to -+ EMFILE) if we ran out of file descriptors, and die on any other -+ kind of failure. */ -+ -+static FILE * -+open_temp (const char *name, pid_t pid) -+{ -+ int tempfd, pipefds[2]; -+ FILE *fp = NULL; -+ -+ wait_proc (pid); -+ -+ tempfd = open (name, O_RDONLY); -+ if (tempfd < 0) -+ return NULL; -+ -+ switch (pipe_fork (pipefds, MAX_FORK_TRIES_DECOMPRESS)) -+ { -+ case -1: -+ if (errno != EMFILE) -+ error (SORT_FAILURE, errno, _("couldn't create process for %s -d"), -+ compress_program); -+ close (tempfd); -+ errno = EMFILE; -+ break; -+ -+ case 0: -+ close (pipefds[0]); -+ dup2_or_die (tempfd, STDIN_FILENO); -+ close (tempfd); -+ dup2_or_die (pipefds[1], STDOUT_FILENO); -+ close (pipefds[1]); -+ -+ execlp (compress_program, compress_program, "-d", (char *) NULL); -+ error (SORT_FAILURE, errno, _("couldn't execute %s -d"), -+ compress_program); -+ -+ default: -+ close (tempfd); -+ close (pipefds[1]); -+ -+ fp = fdopen (pipefds[0], "r"); -+ if (! fp) -+ { -+ int saved_errno = errno; -+ close (pipefds[0]); -+ errno = saved_errno; -+ } -+ break; -+ } -+ -+ return fp; -+} -+ -+static void -+write_bytes (const char *buf, size_t n_bytes, FILE *fp, const char *output_file) -+{ -+ if (fwrite (buf, 1, n_bytes, fp) != n_bytes) -+ die (_("write failed"), output_file); -+} -+ -+/* Append DIR to the array of temporary directory names. */ -+static void -+add_temp_dir (char const *dir) -+{ -+ if (temp_dir_count == temp_dir_alloc) -+ temp_dirs = X2NREALLOC (temp_dirs, &temp_dir_alloc); -+ -+ temp_dirs[temp_dir_count++] = dir; -+} -+ -+/* Remove NAME from the list of temporary files. */ -+ -+static void -+zaptemp (const char *name) -+{ -+ struct tempnode *volatile *pnode; -+ struct tempnode *node; -+ struct tempnode *next; -+ int unlink_status; -+ int unlink_errno = 0; -+ struct cs_status cs; -+ -+ for (pnode = &temphead; (node = *pnode)->name != name; pnode = &node->next) -+ continue; -+ -+ /* Unlink the temporary file in a critical section to avoid races. */ -+ next = node->next; -+ cs = cs_enter (); -+ unlink_status = unlink (name); -+ unlink_errno = errno; -+ *pnode = next; -+ cs_leave (cs); -+ -+ if (unlink_status != 0) -+ error (0, unlink_errno, _("warning: cannot remove: %s"), name); -+ if (! next) -+ temptail = pnode; -+ free (node); -+} -+ -+#if HAVE_NL_LANGINFO -+ -+static int -+struct_month_cmp (const void *m1, const void *m2) -+{ -+ struct month const *month1 = m1; -+ struct month const *month2 = m2; -+ return strcmp (month1->name, month2->name); -+} -+ -+#endif -+ -+/* Initialize the character class tables. */ -+ -+static void -+inittables (void) -+{ -+ size_t i; -+ -+ for (i = 0; i < UCHAR_LIM; ++i) -+ { -+ blanks[i] = !! isblank (i); -+ nonprinting[i] = ! isprint (i); -+ nondictionary[i] = ! isalnum (i) && ! isblank (i); -+ fold_toupper[i] = toupper (i); -+ } -+ -+#if HAVE_NL_LANGINFO -+ /* If we're not in the "C" locale, read different names for months. */ -+ if (hard_LC_TIME) -+ { -+ for (i = 0; i < MONTHS_PER_YEAR; i++) -+ { -+ char const *s; -+ size_t s_len; -+ size_t j; -+ char *name; -+ -+ s = (char *) nl_langinfo (ABMON_1 + i); -+ s_len = strlen (s); -+ monthtab[i].name = name = xmalloc (s_len + 1); -+ monthtab[i].val = i + 1; -+ -+ for (j = 0; j < s_len; j++) -+ name[j] = fold_toupper[to_uchar (s[j])]; -+ name[j] = '\0'; -+ } -+ qsort ((void *) monthtab, MONTHS_PER_YEAR, -+ sizeof *monthtab, struct_month_cmp); -+ } -+#endif -+} -+ -+/* Specify how many inputs may be merged at once. -+ This may be set on the command-line with the -+ --batch-size option. */ -+static void -+specify_nmerge (int oi, char c, char const *s) -+{ -+ uintmax_t n; -+ struct rlimit rlimit; -+ enum strtol_error e = xstrtoumax (s, NULL, 10, &n, NULL); -+ -+ /* Try to find out how many file descriptors we'll be able -+ to open. We need at least nmerge + 3 (STDIN_FILENO, -+ STDOUT_FILENO and STDERR_FILENO). */ -+ unsigned int max_nmerge = ((getrlimit (RLIMIT_NOFILE, &rlimit) == 0 -+ ? rlimit.rlim_cur -+ : OPEN_MAX) -+ - 3); -+ -+ if (e == LONGINT_OK) -+ { -+ nmerge = n; -+ if (nmerge != n) -+ e = LONGINT_OVERFLOW; -+ else -+ { -+ if (nmerge < 2) -+ { -+ error (0, 0, _("invalid --%s argument %s"), -+ long_options[oi].name, quote(s)); -+ error (SORT_FAILURE, 0, -+ _("minimum --%s argument is %s"), -+ long_options[oi].name, quote("2")); -+ } -+ else if (max_nmerge < nmerge) -+ { -+ e = LONGINT_OVERFLOW; -+ } -+ else -+ return; -+ } -+ } -+ -+ if (e == LONGINT_OVERFLOW) -+ { -+ char max_nmerge_buf[INT_BUFSIZE_BOUND (unsigned int)]; -+ error (0, 0, _("--%s argument %s too large"), -+ long_options[oi].name, quote(s)); -+ error (SORT_FAILURE, 0, -+ _("maximum --%s argument with current rlimit is %s"), -+ long_options[oi].name, -+ uinttostr (max_nmerge, max_nmerge_buf)); -+ } -+ else -+ xstrtol_fatal (e, oi, c, long_options, s); -+} -+ -+/* Specify the amount of main memory to use when sorting. */ -+static void -+specify_sort_size (int oi, char c, char const *s) -+{ -+ uintmax_t n; -+ char *suffix; -+ enum strtol_error e = xstrtoumax (s, &suffix, 10, &n, "EgGkKmMPtTYZ"); -+ -+ /* The default unit is KiB. */ -+ if (e == LONGINT_OK && ISDIGIT (suffix[-1])) -+ { -+ if (n <= UINTMAX_MAX / 1024) -+ n *= 1024; -+ else -+ e = LONGINT_OVERFLOW; -+ } -+ -+ /* A 'b' suffix means bytes; a '%' suffix means percent of memory. */ -+ if (e == LONGINT_INVALID_SUFFIX_CHAR && ISDIGIT (suffix[-1]) && ! suffix[1]) -+ switch (suffix[0]) -+ { -+ case 'b': -+ e = LONGINT_OK; -+ break; -+ -+ case '%': -+ { -+ double mem = physmem_total () * n / 100; -+ -+ /* Use "<", not "<=", to avoid problems with rounding. */ -+ if (mem < UINTMAX_MAX) -+ { -+ n = mem; -+ e = LONGINT_OK; -+ } -+ else -+ e = LONGINT_OVERFLOW; -+ } -+ break; -+ } -+ -+ if (e == LONGINT_OK) -+ { -+ /* If multiple sort sizes are specified, take the maximum, so -+ that option order does not matter. */ -+ if (n < sort_size) -+ return; -+ -+ sort_size = n; -+ if (sort_size == n) -+ { -+ sort_size = MAX (sort_size, MIN_SORT_SIZE); -+ return; -+ } -+ -+ e = LONGINT_OVERFLOW; -+ } -+ -+ xstrtol_fatal (e, oi, c, long_options, s); -+} -+ -+/* Return the default sort size. */ -+static size_t -+default_sort_size (void) -+{ -+ /* Let MEM be available memory or 1/8 of total memory, whichever -+ is greater. */ -+ double avail = physmem_available (); -+ double total = physmem_total (); -+ double mem = MAX (avail, total / 8); -+ struct rlimit rlimit; -+ -+ /* Let SIZE be MEM, but no more than the maximum object size or -+ system resource limits. Avoid the MIN macro here, as it is not -+ quite right when only one argument is floating point. Don't -+ bother to check for values like RLIM_INFINITY since in practice -+ they are not much less than SIZE_MAX. */ -+ size_t size = SIZE_MAX; -+ if (mem < size) -+ size = mem; -+ if (getrlimit (RLIMIT_DATA, &rlimit) == 0 && rlimit.rlim_cur < size) -+ size = rlimit.rlim_cur; -+#ifdef RLIMIT_AS -+ if (getrlimit (RLIMIT_AS, &rlimit) == 0 && rlimit.rlim_cur < size) -+ size = rlimit.rlim_cur; -+#endif -+ -+ /* Leave a large safety margin for the above limits, as failure can -+ occur when they are exceeded. */ -+ size /= 2; -+ -+#ifdef RLIMIT_RSS -+ /* Leave a 1/16 margin for RSS to leave room for code, stack, etc. -+ Exceeding RSS is not fatal, but can be quite slow. */ -+ if (getrlimit (RLIMIT_RSS, &rlimit) == 0 && rlimit.rlim_cur / 16 * 15 < size) -+ size = rlimit.rlim_cur / 16 * 15; -+#endif -+ -+ /* Use no less than the minimum. */ -+ return MAX (size, MIN_SORT_SIZE); -+} -+ -+/* Return the sort buffer size to use with the input files identified -+ by FPS and FILES, which are alternate names of the same files. -+ NFILES gives the number of input files; NFPS may be less. Assume -+ that each input line requires LINE_BYTES extra bytes' worth of line -+ information. Do not exceed the size bound specified by the user -+ (or a default size bound, if the user does not specify one). */ -+ -+static size_t -+sort_buffer_size (FILE *const *fps, size_t nfps, -+ char *const *files, size_t nfiles, -+ size_t line_bytes) -+{ -+ /* A bound on the input size. If zero, the bound hasn't been -+ determined yet. */ -+ static size_t size_bound; -+ -+ /* In the worst case, each input byte is a newline. */ -+ size_t worst_case_per_input_byte = line_bytes + 1; -+ -+ /* Keep enough room for one extra input line and an extra byte. -+ This extra room might be needed when preparing to read EOF. */ -+ size_t size = worst_case_per_input_byte + 1; -+ -+ size_t i; -+ -+ for (i = 0; i < nfiles; i++) -+ { -+ struct stat st; -+ off_t file_size; -+ size_t worst_case; -+ -+ if ((i < nfps ? fstat (fileno (fps[i]), &st) -+ : STREQ (files[i], "-") ? fstat (STDIN_FILENO, &st) -+ : stat (files[i], &st)) -+ != 0) -+ die (_("stat failed"), files[i]); -+ -+ if (S_ISREG (st.st_mode)) -+ file_size = st.st_size; -+ else -+ { -+ /* The file has unknown size. If the user specified a sort -+ buffer size, use that; otherwise, guess the size. */ -+ if (sort_size) -+ return sort_size; -+ file_size = INPUT_FILE_SIZE_GUESS; -+ } -+ -+ if (! size_bound) -+ { -+ size_bound = sort_size; -+ if (! size_bound) -+ size_bound = default_sort_size (); -+ } -+ -+ /* Add the amount of memory needed to represent the worst case -+ where the input consists entirely of newlines followed by a -+ single non-newline. Check for overflow. */ -+ worst_case = file_size * worst_case_per_input_byte + 1; -+ if (file_size != worst_case / worst_case_per_input_byte -+ || size_bound - size <= worst_case) -+ return size_bound; -+ size += worst_case; -+ } -+ -+ return size; -+} -+ -+/* Initialize BUF. Reserve LINE_BYTES bytes for each line; LINE_BYTES -+ must be at least sizeof (struct line). Allocate ALLOC bytes -+ initially. */ -+ -+static void -+initbuf (struct buffer *buf, size_t line_bytes, size_t alloc) -+{ -+ /* Ensure that the line array is properly aligned. If the desired -+ size cannot be allocated, repeatedly halve it until allocation -+ succeeds. The smaller allocation may hurt overall performance, -+ but that's better than failing. */ -+ for (;;) -+ { -+ alloc += sizeof (struct line) - alloc % sizeof (struct line); -+ buf->buf = malloc (alloc); -+ if (buf->buf) -+ break; -+ alloc /= 2; -+ if (alloc <= line_bytes + 1) -+ xalloc_die (); -+ } -+ -+ buf->line_bytes = line_bytes; -+ buf->alloc = alloc; -+ buf->used = buf->left = buf->nlines = 0; -+ buf->eof = false; -+} -+ -+/* Return one past the limit of the line array. */ -+ -+static inline struct line * -+buffer_linelim (struct buffer const *buf) -+{ -+ return (struct line *) (buf->buf + buf->alloc); -+} -+ -+/* Return a pointer to the first character of the field specified -+ by KEY in LINE. */ -+ -+static char * -+begfield (const struct line *line, const struct keyfield *key) -+{ -+ char *ptr = line->text, *lim = ptr + line->length - 1; -+ size_t sword = key->sword; -+ size_t schar = key->schar; -+ -+ /* The leading field separator itself is included in a field when -t -+ is absent. */ -+ -+ if (tab != TAB_DEFAULT) -+ while (ptr < lim && sword--) -+ { -+ while (ptr < lim && *ptr != tab) -+ ++ptr; -+ if (ptr < lim) -+ ++ptr; -+ } -+ else -+ while (ptr < lim && sword--) -+ { -+ while (ptr < lim && blanks[to_uchar (*ptr)]) -+ ++ptr; -+ while (ptr < lim && !blanks[to_uchar (*ptr)]) -+ ++ptr; -+ } -+ -+ /* If we're ignoring leading blanks when computing the Start -+ of the field, skip past them here. */ -+ if (key->skipsblanks) -+ while (ptr < lim && blanks[to_uchar (*ptr)]) -+ ++ptr; -+ -+ /* Advance PTR by SCHAR (if possible), but no further than LIM. */ -+ ptr = MIN (lim, ptr + schar); -+ -+ return ptr; -+} -+ -+/* Return the limit of (a pointer to the first character after) the field -+ in LINE specified by KEY. */ -+ -+static char * -+limfield (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; -+ -+ if (echar == 0) -+ eword++; /* Skip all of end field. */ -+ -+ /* Move PTR past EWORD fields or to one past the last byte on LINE, -+ whichever comes first. If there are more than EWORD fields, leave -+ PTR pointing at the beginning of the field having zero-based index, -+ EWORD. If a delimiter character was specified (via -t), then that -+ `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) -+ while (ptr < lim && eword--) -+ { -+ while (ptr < lim && *ptr != tab) -+ ++ptr; -+ if (ptr < lim && (eword || echar)) -+ ++ptr; -+ } -+ else -+ while (ptr < lim && eword--) -+ { -+ while (ptr < lim && blanks[to_uchar (*ptr)]) -+ ++ptr; -+ while (ptr < lim && !blanks[to_uchar (*ptr)]) -+ ++ptr; -+ } -+ -+#ifdef POSIX_UNSPECIFIED -+ /* The following block of code makes GNU sort incompatible with -+ standard Unix sort, so it's ifdef'd out for now. -+ The POSIX spec isn't clear on how to interpret this. -+ FIXME: request clarification. -+ -+ From: kwzh@gnu.ai.mit.edu (Karl Heuer) -+ Date: Thu, 30 May 96 12:20:41 -0400 -+ [Translated to POSIX 1003.1-2001 terminology by Paul Eggert.] -+ -+ [...]I believe I've found another bug in `sort'. -+ -+ $ cat /tmp/sort.in -+ a b c 2 d -+ pq rs 1 t -+ $ textutils-1.15/src/sort -k1.7,1.7 skipeblanks) -+ while (ptr < lim && blanks[to_uchar (*ptr)]) -+ ++ptr; -+ -+ /* Advance PTR by ECHAR (if possible), but no further than LIM. */ -+ ptr = MIN (lim, ptr + echar); -+ } -+ -+ return ptr; -+} -+ -+/* 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 -+ table too. FILE is the name of the file corresponding to FP. -+ Return true if some input was read. */ -+ -+static bool -+fillbuf (struct buffer *buf, FILE *fp, char const *file) -+{ -+ struct keyfield const *key = keylist; -+ char eol = eolchar; -+ size_t line_bytes = buf->line_bytes; -+ size_t mergesize = merge_buffer_size - MIN_MERGE_BUFFER_SIZE; -+ -+ if (buf->eof) -+ return false; -+ -+ if (buf->used != buf->left) -+ { -+ memmove (buf->buf, buf->buf + buf->used - buf->left, buf->left); -+ buf->used = buf->left; -+ buf->nlines = 0; -+ } -+ -+ for (;;) -+ { -+ char *ptr = buf->buf + buf->used; -+ struct line *linelim = buffer_linelim (buf); -+ struct line *line = linelim - buf->nlines; -+ size_t avail = (char *) linelim - buf->nlines * line_bytes - ptr; -+ char *line_start = buf->nlines ? line->text + line->length : buf->buf; -+ -+ while (line_bytes + 1 < avail) -+ { -+ /* Read as many bytes as possible, but do not read so many -+ bytes that there might not be enough room for the -+ corresponding line array. The worst case is when the -+ rest of the input file consists entirely of newlines, -+ except that the last byte is not a newline. */ -+ size_t readsize = (avail - 1) / (line_bytes + 1); -+ size_t bytes_read = fread (ptr, 1, readsize, fp); -+ char *ptrlim = ptr + bytes_read; -+ char *p; -+ avail -= bytes_read; -+ -+ if (bytes_read != readsize) -+ { -+ if (ferror (fp)) -+ die (_("read failed"), file); -+ if (feof (fp)) -+ { -+ buf->eof = true; -+ if (buf->buf == ptrlim) -+ return false; -+ if (ptrlim[-1] != eol) -+ *ptrlim++ = eol; -+ } -+ } -+ -+ /* Find and record each line in the just-read input. */ -+ while ((p = memchr (ptr, eol, ptrlim - ptr))) -+ { -+ ptr = p + 1; -+ line--; -+ line->text = line_start; -+ line->length = ptr - line_start; -+ mergesize = MAX (mergesize, line->length); -+ avail -= line_bytes; -+ -+ if (key) -+ { -+ /* Precompute the position of the first key for -+ efficiency. */ -+ line->keylim = (key->eword == SIZE_MAX -+ ? p -+ : limfield (line, key)); -+ -+ if (key->sword != SIZE_MAX) -+ line->keybeg = begfield (line, key); -+ else -+ { -+ if (key->skipsblanks) -+ while (blanks[to_uchar (*line_start)]) -+ line_start++; -+ line->keybeg = line_start; -+ } -+ } -+ -+ line_start = ptr; -+ } -+ -+ ptr = ptrlim; -+ if (buf->eof) -+ break; -+ } -+ -+ buf->used = ptr - buf->buf; -+ buf->nlines = buffer_linelim (buf) - line; -+ if (buf->nlines != 0) -+ { -+ buf->left = ptr - line_start; -+ merge_buffer_size = mergesize + MIN_MERGE_BUFFER_SIZE; -+ return true; -+ } -+ -+ { -+ /* The current input line is too long to fit in the buffer. -+ Double the buffer size and try again, keeping it properly -+ aligned. */ -+ size_t line_alloc = buf->alloc / sizeof (struct line); -+ buf->buf = x2nrealloc (buf->buf, &line_alloc, sizeof (struct line)); -+ buf->alloc = line_alloc * sizeof (struct line); -+ } -+ } -+} -+ -+/* Compare strings A and B as numbers without explicitly converting them to -+ machine numbers. Comparatively slow for short strings, but asymptotically -+ hideously fast. */ -+ -+static int -+numcompare (const char *a, const char *b) -+{ -+ while (blanks[to_uchar (*a)]) -+ a++; -+ while (blanks[to_uchar (*b)]) -+ b++; -+ -+ return strnumcmp (a, b, decimal_point, thousands_sep); -+} -+ -+/* Exit with an error if a mixture of SI and IEC units detected. */ -+ -+static void -+check_mixed_SI_IEC (char prefix, struct keyfield *key) -+{ -+ int si_present = prefix == 'i'; -+ if (key->si_present != -1 && si_present != key->si_present) -+ error (SORT_FAILURE, 0, _("both SI and IEC prefixes present on units")); -+ key->si_present = si_present; -+} -+ -+/* Return an integer which represents the order of magnitude of -+ the unit following the number. NUMBER can contain thousands separators -+ or a decimal point, but not have preceeding blanks. -+ Negative numbers return a negative unit order. */ -+ -+static int -+find_unit_order (const char *number, struct keyfield *key) -+{ -+ static const char orders [UCHAR_LIM] = -+ { -+#if SOME_DAY_WE_WILL_REQUIRE_C99 -+ ['K']=1, ['M']=2, ['G']=3, ['T']=4, ['P']=5, ['E']=6, ['Z']=7, ['Y']=8, -+ ['k']=1, -+#else -+ /* Generate the following table with this command: -+ perl -e 'my %a=(k=>1, K=>1, M=>2, G=>3, T=>4, P=>5, E=>6, Z=>7, Y=>8); -+ foreach my $i (0..255) {my $c=chr($i); $a{$c} ||= 0;print "$a{$c}, "}'\ -+ |fmt */ -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, -+ 0, 0, 0, 1, 0, 2, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+#endif -+ }; -+ -+ const unsigned char *p = number; -+ -+ int sign = 1; -+ -+ if (*p == '-') -+ { -+ sign = -1; -+ p++; -+ } -+ -+ /* Scan to end of number. -+ Decimals or separators not followed by digits stop the scan. -+ Numbers ending in decimals or separators are thus considered -+ to be lacking in units. -+ FIXME: add support for multibyte thousands_sep and decimal_point. */ -+ -+ while (ISDIGIT (*p)) -+ { -+ p++; -+ -+ if (*p == decimal_point && ISDIGIT (*(p + 1))) -+ p += 2; -+ else if (*p == thousands_sep && ISDIGIT (*(p + 1))) -+ p += 2; -+ } -+ -+ int order = orders[*p]; -+ -+ /* For valid units check for MiB vs MB etc. */ -+ if (order) -+ check_mixed_SI_IEC (*(p + 1), key); -+ -+ return sign * order; -+} -+ -+/* Compare numbers ending in units with SI xor IEC prefixes -+ < K/k < M < G < T < P < E < Z < Y -+ Assume that numbers are properly abbreviated. -+ i.e. input will never have both 6000K and 5M. */ -+ -+static int -+human_numcompare (const char *a, const char *b, struct keyfield *key) -+{ -+ while (blanks[to_uchar (*a)]) -+ a++; -+ while (blanks[to_uchar (*b)]) -+ b++; -+ -+ int order_a = find_unit_order (a, key); -+ int order_b = find_unit_order (b, key); -+ -+ return (order_a > order_b ? 1 -+ : order_a < order_b ? -1 -+ : strnumcmp (a, b, decimal_point, thousands_sep)); -+} -+ -+static int -+general_numcompare (const char *sa, const char *sb) -+{ -+ /* FIXME: add option to warn about failed conversions. */ -+ /* FIXME: maybe add option to try expensive FP conversion -+ only if A and B can't be compared more cheaply/accurately. */ -+ -+ char *ea; -+ char *eb; -+ double a = strtod (sa, &ea); -+ double b = strtod (sb, &eb); -+ -+ /* Put conversion errors at the start of the collating sequence. */ -+ if (sa == ea) -+ return sb == eb ? 0 : -1; -+ if (sb == eb) -+ return 1; -+ -+ /* Sort numbers in the usual way, where -0 == +0. Put NaNs after -+ conversion errors but before numbers; sort them by internal -+ bit-pattern, for lack of a more portable alternative. */ -+ return (a < b ? -1 -+ : a > b ? 1 -+ : a == b ? 0 -+ : b == b ? -1 -+ : a == a ? 1 -+ : memcmp ((char *) &a, (char *) &b, sizeof a)); -+} -+ -+/* Return an integer in 1..12 of the month name MONTH with length LEN. -+ Return 0 if the name in S is not recognized. */ -+ -+static int -+getmonth (char const *month, size_t len) -+{ -+ size_t lo = 0; -+ size_t hi = MONTHS_PER_YEAR; -+ char const *monthlim = month + len; -+ -+ for (;;) -+ { -+ if (month == monthlim) -+ return 0; -+ if (!blanks[to_uchar (*month)]) -+ break; -+ ++month; -+ } -+ -+ do -+ { -+ size_t ix = (lo + hi) / 2; -+ char const *m = month; -+ char const *n = monthtab[ix].name; -+ -+ for (;; m++, n++) -+ { -+ if (!*n) -+ return monthtab[ix].val; -+ if (m == monthlim || fold_toupper[to_uchar (*m)] < to_uchar (*n)) -+ { -+ hi = ix; -+ break; -+ } -+ else if (fold_toupper[to_uchar (*m)] > to_uchar (*n)) -+ { -+ lo = ix + 1; -+ break; -+ } -+ } -+ } -+ while (lo < hi); -+ -+ return 0; -+} -+ -+/* A source of random data. */ -+static struct randread_source *randread_source; -+ -+/* Return the Ith randomly-generated state. The caller must invoke -+ random_state (H) for all H less than I before invoking random_state -+ (I). */ -+ -+static struct md5_ctx -+random_state (size_t i) -+{ -+ /* An array of states resulting from the random data, and counts of -+ its used and allocated members. */ -+ static struct md5_ctx *state; -+ static size_t used; -+ static size_t allocated; -+ -+ struct md5_ctx *s = &state[i]; -+ -+ if (used <= i) -+ { -+ unsigned char buf[MD5_DIGEST_SIZE]; -+ -+ used++; -+ -+ if (allocated <= i) -+ { -+ state = X2NREALLOC (state, &allocated); -+ s = &state[i]; -+ } -+ -+ randread (randread_source, buf, sizeof buf); -+ md5_init_ctx (s); -+ md5_process_bytes (buf, sizeof buf, s); -+ } -+ -+ return *s; -+} -+ -+/* Compare the hashes of TEXTA with length LENGTHA to those of TEXTB -+ with length LENGTHB. Return negative if less, zero if equal, -+ positive if greater. */ -+ -+static int -+cmp_hashes (char const *texta, size_t lena, -+ char const *textb, size_t lenb) -+{ -+ /* Try random hashes until a pair of hashes disagree. But if the -+ first pair of random hashes agree, check whether the keys are -+ identical and if so report no difference. */ -+ int diff; -+ size_t i; -+ for (i = 0; ; i++) -+ { -+ uint32_t dig[2][MD5_DIGEST_SIZE / sizeof (uint32_t)]; -+ struct md5_ctx s[2]; -+ s[0] = s[1] = random_state (i); -+ md5_process_bytes (texta, lena, &s[0]); md5_finish_ctx (&s[0], dig[0]); -+ md5_process_bytes (textb, lenb, &s[1]); md5_finish_ctx (&s[1], dig[1]); -+ diff = memcmp (dig[0], dig[1], sizeof dig[0]); -+ if (diff != 0) -+ break; -+ if (i == 0 && lena == lenb && memcmp (texta, textb, lena) == 0) -+ break; -+ } -+ -+ return diff; -+} -+ -+/* Compare the keys TEXTA (of length LENA) and TEXTB (of length LENB) -+ using one or more random hash functions. */ -+ -+static int -+compare_random (char *restrict texta, size_t lena, -+ char *restrict textb, size_t lenb) -+{ -+ int diff; -+ -+ if (! hard_LC_COLLATE) -+ diff = cmp_hashes (texta, lena, textb, lenb); -+ else -+ { -+ /* Transform the text into the basis of comparison, so that byte -+ strings that would otherwise considered to be equal are -+ considered equal here even if their bytes differ. */ -+ -+ char *buf = NULL; -+ char stackbuf[4000]; -+ size_t tlena = xmemxfrm (stackbuf, sizeof stackbuf, texta, lena); -+ bool a_fits = tlena <= sizeof stackbuf; -+ size_t tlenb = xmemxfrm ((a_fits ? stackbuf + tlena : NULL), -+ (a_fits ? sizeof stackbuf - tlena : 0), -+ textb, lenb); -+ -+ if (a_fits && tlena + tlenb <= sizeof stackbuf) -+ buf = stackbuf; -+ else -+ { -+ /* Adding 1 to the buffer size lets xmemxfrm run a bit -+ faster by avoiding the need for an extra buffer copy. */ -+ buf = xmalloc (tlena + tlenb + 1); -+ xmemxfrm (buf, tlena + 1, texta, lena); -+ xmemxfrm (buf + tlena, tlenb + 1, textb, lenb); -+ } -+ -+ diff = cmp_hashes (buf, tlena, buf + tlena, tlenb); -+ -+ if (buf != stackbuf) -+ free (buf); -+ } -+ -+ return diff; -+} -+ -+/* Compare the keys TEXTA (of length LENA) and TEXTB (of length LENB) -+ using filevercmp. See lib/filevercmp.h for function description. */ -+ -+static int -+compare_version (char *restrict texta, size_t lena, -+ char *restrict textb, size_t lenb) -+{ -+ int diff; -+ -+ /* It is necessary to save the character after the end of the field. -+ "filevercmp" works with NUL terminated strings. Our blocks of -+ text are not necessarily terminated with a NUL byte. */ -+ char sv_a = texta[lena]; -+ char sv_b = textb[lenb]; -+ -+ texta[lena] = '\0'; -+ textb[lenb] = '\0'; -+ -+ diff = filevercmp (texta, textb); -+ -+ texta[lena] = sv_a; -+ textb[lenb] = sv_b; -+ -+ return diff; -+} -+ -+/* 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 (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; -+ -+ int diff; -+ -+ for (;;) -+ { -+ char const *translate = key->translate; -+ bool const *ignore = key->ignore; -+ -+ /* Treat field ends before field starts as empty fields. */ -+ lima = MAX (texta, lima); -+ limb = MAX (textb, limb); -+ -+ /* Find the lengths. */ -+ size_t lena = lima - texta; -+ size_t lenb = limb - textb; -+ -+ /* Actually compare the fields. */ -+ -+ 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, key)); -+ *lima = savea, *limb = saveb; -+ } -+ else if (key->version) -+ diff = compare_version (texta, lena, textb, lenb); -+ else if (key->month) -+ diff = getmonth (texta, lena) - getmonth (textb, lenb); -+ /* Sorting like this may become slow, so in a simple locale the user -+ can select a faster sort that is similar to ascii sort. */ -+ else if (hard_LC_COLLATE) -+ { -+ if (ignore || translate) -+ { -+ char buf[4000]; -+ size_t size = lena + 1 + lenb + 1; -+ char *copy_a = (size <= sizeof buf ? buf : xmalloc (size)); -+ char *copy_b = copy_a + lena + 1; -+ size_t new_len_a, new_len_b, i; -+ -+ /* Ignore and/or translate chars before comparing. */ -+ for (new_len_a = new_len_b = i = 0; i < MAX (lena, lenb); i++) -+ { -+ if (i < lena) -+ { -+ copy_a[new_len_a] = (translate -+ ? translate[to_uchar (texta[i])] -+ : texta[i]); -+ if (!ignore || !ignore[to_uchar (texta[i])]) -+ ++new_len_a; -+ } -+ if (i < lenb) -+ { -+ copy_b[new_len_b] = (translate -+ ? translate[to_uchar (textb[i])] -+ : textb [i]); -+ if (!ignore || !ignore[to_uchar (textb[i])]) -+ ++new_len_b; -+ } -+ } -+ -+ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b); -+ -+ if (sizeof buf < size) -+ free (copy_a); -+ } -+ else if (lena == 0) -+ diff = - NONZERO (lenb); -+ else if (lenb == 0) -+ goto greater; -+ else -+ diff = xmemcoll (texta, lena, textb, lenb); -+ } -+ else if (ignore) -+ { -+#define CMP_WITH_IGNORE(A, B) \ -+ do \ -+ { \ -+ for (;;) \ -+ { \ -+ while (texta < lima && ignore[to_uchar (*texta)]) \ -+ ++texta; \ -+ while (textb < limb && ignore[to_uchar (*textb)]) \ -+ ++textb; \ -+ if (! (texta < lima && textb < limb)) \ -+ break; \ -+ diff = to_uchar (A) - to_uchar (B); \ -+ if (diff) \ -+ goto not_equal; \ -+ ++texta; \ -+ ++textb; \ -+ } \ -+ \ -+ diff = (texta < lima) - (textb < limb); \ -+ } \ -+ while (0) -+ -+ if (translate) -+ CMP_WITH_IGNORE (translate[to_uchar (*texta)], -+ translate[to_uchar (*textb)]); -+ else -+ CMP_WITH_IGNORE (*texta, *textb); -+ } -+ else if (lena == 0) -+ diff = - NONZERO (lenb); -+ else if (lenb == 0) -+ goto greater; -+ else -+ { -+ if (translate) -+ { -+ while (texta < lima && textb < limb) -+ { -+ diff = (to_uchar (translate[to_uchar (*texta++)]) -+ - to_uchar (translate[to_uchar (*textb++)])); -+ if (diff) -+ goto not_equal; -+ } -+ } -+ else -+ { -+ diff = memcmp (texta, textb, MIN (lena, lenb)); -+ if (diff) -+ goto not_equal; -+ } -+ diff = lena < lenb ? -1 : lena != lenb; -+ } -+ -+ if (diff) -+ goto not_equal; -+ -+ key = key->next; -+ if (! key) -+ break; -+ -+ /* Find the beginning and limit of the next field. */ -+ if (key->eword != SIZE_MAX) -+ lima = limfield (a, key), limb = limfield (b, key); -+ else -+ lima = a->text + a->length - 1, limb = b->text + b->length - 1; -+ -+ if (key->sword != SIZE_MAX) -+ texta = begfield (a, key), textb = begfield (b, key); -+ else -+ { -+ texta = a->text, textb = b->text; -+ if (key->skipsblanks) -+ { -+ while (texta < lima && blanks[to_uchar (*texta)]) -+ ++texta; -+ while (textb < limb && blanks[to_uchar (*textb)]) -+ ++textb; -+ } -+ } -+ } -+ -+ return 0; -+ -+ greater: -+ diff = 1; -+ not_equal: -+ return key->reverse ? -diff : diff; -+} -+ -+/* Compare two lines A and B, returning negative, zero, or positive -+ depending on whether A compares less than, equal to, or greater than B. */ -+ -+static int -+compare (const struct line *a, const struct line *b) -+{ -+ int diff; -+ size_t alen, blen; -+ -+ /* First try to compare on the specified keys (if any). -+ The only two cases with no key at all are unadorned sort, -+ and unadorned sort -r. */ -+ if (keylist) -+ { -+ diff = keycompare (a, b); -+ if (diff || unique || stable) -+ return diff; -+ } -+ -+ /* If the keys all compare equal (or no keys were specified) -+ fall through to the default comparison. */ -+ alen = a->length - 1, blen = b->length - 1; -+ -+ if (alen == 0) -+ diff = - NONZERO (blen); -+ else if (blen == 0) -+ diff = 1; -+ else if (hard_LC_COLLATE) -+ diff = xmemcoll (a->text, alen, b->text, blen); -+ else if (! (diff = memcmp (a->text, b->text, MIN (alen, blen)))) -+ diff = alen < blen ? -1 : alen != blen; -+ -+ return reverse ? -diff : diff; -+} -+ -+/* Check that the lines read from FILE_NAME come in order. Return -+ true if they are in order. If CHECKONLY == 'c', also print a -+ diagnostic (FILE_NAME, line number, contents of line) to stderr if -+ they are not in order. */ -+ -+static bool -+check (char const *file_name, char checkonly) -+{ -+ FILE *fp = xfopen (file_name, "r"); -+ struct buffer buf; /* Input buffer. */ -+ struct line temp; /* Copy of previous line. */ -+ size_t alloc = 0; -+ uintmax_t line_number = 0; -+ struct keyfield const *key = keylist; -+ bool nonunique = ! unique; -+ bool ordered = true; -+ -+ initbuf (&buf, sizeof (struct line), -+ MAX (merge_buffer_size, sort_size)); -+ temp.text = NULL; -+ -+ while (fillbuf (&buf, fp, file_name)) -+ { -+ struct line const *line = buffer_linelim (&buf); -+ struct line const *linebase = line - buf.nlines; -+ -+ /* Make sure the line saved from the old buffer contents is -+ less than or equal to the first line of the new buffer. */ -+ if (alloc && nonunique <= compare (&temp, line - 1)) -+ { -+ found_disorder: -+ { -+ if (checkonly == 'c') -+ { -+ struct line const *disorder_line = line - 1; -+ uintmax_t disorder_line_number = -+ buffer_linelim (&buf) - disorder_line + line_number; -+ char hr_buf[INT_BUFSIZE_BOUND (uintmax_t)]; -+ fprintf (stderr, _("%s: %s:%s: disorder: "), -+ program_name, file_name, -+ umaxtostr (disorder_line_number, hr_buf)); -+ write_bytes (disorder_line->text, disorder_line->length, -+ stderr, _("standard error")); -+ } -+ -+ ordered = false; -+ break; -+ } -+ } -+ -+ /* Compare each line in the buffer with its successor. */ -+ while (linebase < --line) -+ if (nonunique <= compare (line, line - 1)) -+ goto found_disorder; -+ -+ line_number += buf.nlines; -+ -+ /* Save the last line of the buffer. */ -+ if (alloc < line->length) -+ { -+ do -+ { -+ alloc *= 2; -+ if (! alloc) -+ { -+ alloc = line->length; -+ break; -+ } -+ } -+ while (alloc < line->length); -+ -+ temp.text = xrealloc (temp.text, alloc); -+ } -+ memcpy (temp.text, line->text, line->length); -+ temp.length = line->length; -+ if (key) -+ { -+ temp.keybeg = temp.text + (line->keybeg - line->text); -+ temp.keylim = temp.text + (line->keylim - line->text); -+ } -+ } -+ -+ xfclose (fp, file_name); -+ free (buf.buf); -+ free (temp.text); -+ return ordered; -+} -+ -+/* Open FILES (there are NFILES of them) and store the resulting array -+ of stream pointers into (*PFPS). Allocate the array. Return the -+ number of successfully opened files, setting errno if this value is -+ less than NFILES. */ -+ -+static size_t -+open_input_files (struct sortfile *files, size_t nfiles, FILE ***pfps) -+{ -+ FILE **fps = *pfps = xnmalloc (nfiles, sizeof *fps); -+ int i; -+ -+ /* Open as many input files as we can. */ -+ for (i = 0; i < nfiles; i++) -+ { -+ fps[i] = (files[i].pid -+ ? open_temp (files[i].name, files[i].pid) -+ : stream_open (files[i].name, "r")); -+ if (!fps[i]) -+ break; -+ } -+ -+ return i; -+} -+ -+/* Merge lines from FILES onto OFP. NTEMPS is the number of temporary -+ files (all of which are at the start of the FILES array), and -+ NFILES is the number of files; 0 <= NTEMPS <= NFILES <= NMERGE. -+ FPS is the vector of open stream corresponding to the files. -+ Close input and output streams before returning. -+ OUTPUT_FILE gives the name of the output file. If it is NULL, -+ the output file is standard output. */ -+ -+static void -+mergefps (struct sortfile *files, size_t ntemps, size_t nfiles, -+ FILE *ofp, char const *output_file, FILE **fps) -+{ -+ struct buffer *buffer = xnmalloc (nfiles, sizeof *buffer); -+ /* Input buffers for each file. */ -+ struct line saved; /* Saved line storage for unique check. */ -+ struct line const *savedline = NULL; -+ /* &saved if there is a saved line. */ -+ size_t savealloc = 0; /* Size allocated for the saved line. */ -+ struct line const **cur = xnmalloc (nfiles, sizeof *cur); -+ /* Current line in each line table. */ -+ struct line const **base = xnmalloc (nfiles, sizeof *base); -+ /* Base of each line table. */ -+ size_t *ord = xnmalloc (nfiles, sizeof *ord); -+ /* Table representing a permutation of fps, -+ such that cur[ord[0]] is the smallest line -+ and will be next output. */ -+ size_t i; -+ size_t j; -+ size_t t; -+ struct keyfield const *key = keylist; -+ saved.text = NULL; -+ -+ /* Read initial lines from each input file. */ -+ for (i = 0; i < nfiles; ) -+ { -+ initbuf (&buffer[i], sizeof (struct line), -+ MAX (merge_buffer_size, sort_size / nfiles)); -+ if (fillbuf (&buffer[i], fps[i], files[i].name)) -+ { -+ struct line const *linelim = buffer_linelim (&buffer[i]); -+ cur[i] = linelim - 1; -+ base[i] = linelim - buffer[i].nlines; -+ i++; -+ } -+ else -+ { -+ /* fps[i] is empty; eliminate it from future consideration. */ -+ xfclose (fps[i], files[i].name); -+ if (i < ntemps) -+ { -+ ntemps--; -+ zaptemp (files[i].name); -+ } -+ free (buffer[i].buf); -+ --nfiles; -+ for (j = i; j < nfiles; ++j) -+ { -+ files[j] = files[j + 1]; -+ fps[j] = fps[j + 1]; -+ } -+ } -+ } -+ -+ /* Set up the ord table according to comparisons among input lines. -+ Since this only reorders two items if one is strictly greater than -+ the other, it is stable. */ -+ for (i = 0; i < nfiles; ++i) -+ ord[i] = i; -+ for (i = 1; i < nfiles; ++i) -+ if (0 < compare (cur[ord[i - 1]], cur[ord[i]])) -+ t = ord[i - 1], ord[i - 1] = ord[i], ord[i] = t, i = 0; -+ -+ /* Repeatedly output the smallest line until no input remains. */ -+ while (nfiles) -+ { -+ struct line const *smallest = cur[ord[0]]; -+ -+ /* If uniquified output is turned on, output only the first of -+ an identical series of lines. */ -+ if (unique) -+ { -+ if (savedline && compare (savedline, smallest)) -+ { -+ savedline = NULL; -+ write_bytes (saved.text, saved.length, ofp, output_file); -+ } -+ if (!savedline) -+ { -+ savedline = &saved; -+ if (savealloc < smallest->length) -+ { -+ do -+ if (! savealloc) -+ { -+ savealloc = smallest->length; -+ break; -+ } -+ while ((savealloc *= 2) < smallest->length); -+ -+ saved.text = xrealloc (saved.text, savealloc); -+ } -+ saved.length = smallest->length; -+ memcpy (saved.text, smallest->text, saved.length); -+ if (key) -+ { -+ saved.keybeg = -+ saved.text + (smallest->keybeg - smallest->text); -+ saved.keylim = -+ saved.text + (smallest->keylim - smallest->text); -+ } -+ } -+ } -+ else -+ write_bytes (smallest->text, smallest->length, ofp, output_file); -+ -+ /* Check if we need to read more lines into core. */ -+ if (base[ord[0]] < smallest) -+ cur[ord[0]] = smallest - 1; -+ else -+ { -+ if (fillbuf (&buffer[ord[0]], fps[ord[0]], files[ord[0]].name)) -+ { -+ struct line const *linelim = buffer_linelim (&buffer[ord[0]]); -+ cur[ord[0]] = linelim - 1; -+ base[ord[0]] = linelim - buffer[ord[0]].nlines; -+ } -+ else -+ { -+ /* We reached EOF on fps[ord[0]]. */ -+ for (i = 1; i < nfiles; ++i) -+ if (ord[i] > ord[0]) -+ --ord[i]; -+ --nfiles; -+ xfclose (fps[ord[0]], files[ord[0]].name); -+ if (ord[0] < ntemps) -+ { -+ ntemps--; -+ zaptemp (files[ord[0]].name); -+ } -+ free (buffer[ord[0]].buf); -+ for (i = ord[0]; i < nfiles; ++i) -+ { -+ fps[i] = fps[i + 1]; -+ files[i] = files[i + 1]; -+ buffer[i] = buffer[i + 1]; -+ cur[i] = cur[i + 1]; -+ base[i] = base[i + 1]; -+ } -+ for (i = 0; i < nfiles; ++i) -+ ord[i] = ord[i + 1]; -+ continue; -+ } -+ } -+ -+ /* The new line just read in may be larger than other lines -+ already in main memory; push it back in the queue until we -+ encounter a line larger than it. Optimize for the common -+ case where the new line is smallest. */ -+ { -+ size_t lo = 1; -+ size_t hi = nfiles; -+ size_t probe = lo; -+ size_t ord0 = ord[0]; -+ size_t count_of_smaller_lines; -+ -+ while (lo < hi) -+ { -+ int cmp = compare (cur[ord0], cur[ord[probe]]); -+ if (cmp < 0 || (cmp == 0 && ord0 < ord[probe])) -+ hi = probe; -+ else -+ lo = probe + 1; -+ probe = (lo + hi) / 2; -+ } -+ -+ count_of_smaller_lines = lo - 1; -+ for (j = 0; j < count_of_smaller_lines; j++) -+ ord[j] = ord[j + 1]; -+ ord[count_of_smaller_lines] = ord0; -+ } -+ -+ /* Free up some resources every once in a while. */ -+ if (MAX_PROCS_BEFORE_REAP < nprocs) -+ reap_some (); -+ } -+ -+ if (unique && savedline) -+ { -+ write_bytes (saved.text, saved.length, ofp, output_file); -+ free (saved.text); -+ } -+ -+ xfclose (ofp, output_file); -+ free(fps); -+ free(buffer); -+ free(ord); -+ free(base); -+ free(cur); -+} -+ -+/* Merge lines from FILES onto OFP. NTEMPS is the number of temporary -+ files (all of which are at the start of the FILES array), and -+ NFILES is the number of files; 0 <= NTEMPS <= NFILES <= NMERGE. -+ Close input and output files before returning. -+ OUTPUT_FILE gives the name of the output file. -+ -+ Return the number of files successfully merged. This number can be -+ less than NFILES if we ran low on file descriptors, but in this -+ case it is never less than 2. */ -+ -+static size_t -+mergefiles (struct sortfile *files, size_t ntemps, size_t nfiles, -+ FILE *ofp, char const *output_file) -+{ -+ FILE **fps; -+ size_t nopened = open_input_files (files, nfiles, &fps); -+ if (nopened < nfiles && nopened < 2) -+ die (_("open failed"), files[nopened].name); -+ mergefps (files, ntemps, nopened, ofp, output_file, fps); -+ return nopened; -+} -+ -+/* Merge into T the two sorted arrays of lines LO (with NLO members) -+ and HI (with NHI members). T, LO, and HI point just past their -+ respective arrays, and the arrays are in reverse order. NLO and -+ NHI must be positive, and HI - NHI must equal T - (NLO + NHI). */ -+ -+static inline void -+mergelines (struct line *t, -+ struct line const *lo, size_t nlo, -+ struct line const *hi, size_t nhi) -+{ -+ for (;;) -+ if (compare (lo - 1, hi - 1) <= 0) -+ { -+ *--t = *--lo; -+ if (! --nlo) -+ { -+ /* HI - NHI equalled T - (NLO + NHI) when this function -+ began. Therefore HI must equal T now, and there is no -+ need to copy from HI to T. */ -+ return; -+ } -+ } -+ else -+ { -+ *--t = *--hi; -+ if (! --nhi) -+ { -+ do -+ *--t = *--lo; -+ while (--nlo); -+ -+ return; -+ } -+ } -+} -+ -+/* Sort the array LINES with NLINES members, using TEMP for temporary space. -+ NLINES must be at least 2. -+ The input and output arrays are in reverse order, and LINES and -+ TEMP point just past the end of their respective arrays. -+ -+ Use a recursive divide-and-conquer algorithm, in the style -+ suggested by Knuth volume 3 (2nd edition), exercise 5.2.4-23. Use -+ the optimization suggested by exercise 5.2.4-10; this requires room -+ for only 1.5*N lines, rather than the usual 2*N lines. Knuth -+ writes that this memory optimization was originally published by -+ D. A. Bell, Comp J. 1 (1958), 75. */ -+ -+static void -+sortlines (struct line *lines, size_t nlines, struct line *temp) -+{ -+ if (nlines == 2) -+ { -+ if (0 < compare (&lines[-1], &lines[-2])) -+ { -+ struct line tmp = lines[-1]; -+ lines[-1] = lines[-2]; -+ lines[-2] = tmp; -+ } -+ } -+ else -+ { -+ size_t nlo = nlines / 2; -+ size_t nhi = nlines - nlo; -+ struct line *lo = lines; -+ struct line *hi = lines - nlo; -+ struct line *sorted_lo = temp; -+ -+ sortlines (hi, nhi, temp); -+ if (1 < nlo) -+ sortlines_temp (lo, nlo, sorted_lo); -+ else -+ sorted_lo[-1] = lo[-1]; -+ -+ mergelines (lines, sorted_lo, nlo, hi, nhi); -+ } -+} -+ -+/* Like sortlines (LINES, NLINES, TEMP), except output into TEMP -+ rather than sorting in place. */ -+ -+static void -+sortlines_temp (struct line *lines, size_t nlines, struct line *temp) -+{ -+ if (nlines == 2) -+ { -+ /* Declare `swap' as int, not bool, to work around a bug -+ -+ in the IBM xlc 6.0.0.0 compiler in 64-bit mode. */ -+ int swap = (0 < compare (&lines[-1], &lines[-2])); -+ temp[-1] = lines[-1 - swap]; -+ temp[-2] = lines[-2 + swap]; -+ } -+ else -+ { -+ size_t nlo = nlines / 2; -+ size_t nhi = nlines - nlo; -+ struct line *lo = lines; -+ struct line *hi = lines - nlo; -+ struct line *sorted_hi = temp - nlo; -+ -+ sortlines_temp (hi, nhi, sorted_hi); -+ if (1 < nlo) -+ sortlines (lo, nlo, temp); -+ -+ mergelines (temp, lo, nlo, sorted_hi, nhi); -+ } -+} -+ -+/* Scan through FILES[NTEMPS .. NFILES-1] looking for a file that is -+ the same as OUTFILE. If found, merge the found instances (and perhaps -+ some other files) into a temporary file so that it can in turn be -+ merged into OUTFILE without destroying OUTFILE before it is completely -+ read. Return the new value of NFILES, which differs from the old if -+ some merging occurred. -+ -+ This test ensures that an otherwise-erroneous use like -+ "sort -m -o FILE ... FILE ..." copies FILE before writing to it. -+ It's not clear that POSIX requires this nicety. -+ Detect common error cases, but don't try to catch obscure cases like -+ "cat ... FILE ... | sort -m -o FILE" -+ where traditional "sort" doesn't copy the input and where -+ people should know that they're getting into trouble anyway. -+ Catching these obscure cases would slow down performance in -+ common cases. */ -+ -+static size_t -+avoid_trashing_input (struct sortfile *files, size_t ntemps, -+ size_t nfiles, char const *outfile) -+{ -+ size_t i; -+ bool got_outstat = false; -+ struct stat outstat; -+ -+ for (i = ntemps; i < nfiles; i++) -+ { -+ bool is_stdin = STREQ (files[i].name, "-"); -+ bool same; -+ struct stat instat; -+ -+ if (outfile && STREQ (outfile, files[i].name) && !is_stdin) -+ same = true; -+ else -+ { -+ if (! got_outstat) -+ { -+ if ((outfile -+ ? stat (outfile, &outstat) -+ : fstat (STDOUT_FILENO, &outstat)) -+ != 0) -+ break; -+ got_outstat = true; -+ } -+ -+ same = (((is_stdin -+ ? fstat (STDIN_FILENO, &instat) -+ : stat (files[i].name, &instat)) -+ == 0) -+ && SAME_INODE (instat, outstat)); -+ } -+ -+ if (same) -+ { -+ FILE *tftp; -+ pid_t pid; -+ char *temp = create_temp (&tftp, &pid); -+ size_t num_merged = 0; -+ do -+ { -+ num_merged += mergefiles (&files[i], 0, nfiles - i, tftp, temp); -+ files[i].name = temp; -+ files[i].pid = pid; -+ -+ if (i + num_merged < nfiles) -+ memmove(&files[i + 1], &files[i + num_merged], -+ num_merged * sizeof *files); -+ ntemps += 1; -+ nfiles -= num_merged - 1;; -+ i += num_merged; -+ } -+ while (i < nfiles); -+ } -+ } -+ -+ return nfiles; -+} -+ -+/* Merge the input FILES. NTEMPS is the number of files at the -+ start of FILES that are temporary; it is zero at the top level. -+ NFILES is the total number of files. Put the output in -+ OUTPUT_FILE; a null OUTPUT_FILE stands for standard output. */ -+ -+static void -+merge (struct sortfile *files, size_t ntemps, size_t nfiles, -+ char const *output_file) -+{ -+ while (nmerge < nfiles) -+ { -+ /* Number of input files processed so far. */ -+ size_t in; -+ -+ /* Number of output files generated so far. */ -+ size_t out; -+ -+ /* nfiles % NMERGE; this counts input files that are left over -+ after all full-sized merges have been done. */ -+ size_t remainder; -+ -+ /* Number of easily-available slots at the next loop iteration. */ -+ size_t cheap_slots; -+ -+ /* Do as many NMERGE-size merges as possible. In the case that -+ nmerge is bogus, increment by the maximum number of file -+ descriptors allowed. */ -+ for (out = in = 0; nmerge <= nfiles - in; out++) -+ { -+ FILE *tfp; -+ pid_t pid; -+ char *temp = create_temp (&tfp, &pid); -+ size_t num_merged = mergefiles (&files[in], MIN (ntemps, nmerge), -+ nmerge, tfp, temp); -+ ntemps -= MIN (ntemps, num_merged); -+ files[out].name = temp; -+ files[out].pid = pid; -+ in += num_merged; -+ } -+ -+ remainder = nfiles - in; -+ cheap_slots = nmerge - out % nmerge; -+ -+ if (cheap_slots < remainder) -+ { -+ /* So many files remain that they can't all be put into the last -+ NMERGE-sized output window. Do one more merge. Merge as few -+ files as possible, to avoid needless I/O. */ -+ size_t nshortmerge = remainder - cheap_slots + 1; -+ FILE *tfp; -+ pid_t pid; -+ char *temp = create_temp (&tfp, &pid); -+ size_t num_merged = mergefiles (&files[in], MIN (ntemps, nshortmerge), -+ nshortmerge, tfp, temp); -+ ntemps -= MIN (ntemps, num_merged); -+ files[out].name = temp; -+ files[out++].pid = pid; -+ in += num_merged; -+ } -+ -+ /* Put the remaining input files into the last NMERGE-sized output -+ window, so they will be merged in the next pass. */ -+ memmove(&files[out], &files[in], (nfiles - in) * sizeof *files); -+ ntemps += out; -+ nfiles -= in - out; -+ } -+ -+ nfiles = avoid_trashing_input (files, ntemps, nfiles, output_file); -+ -+ /* We aren't guaranteed that this final mergefiles will work, therefore we -+ try to merge into the output, and then merge as much as we can into a -+ temp file if we can't. Repeat. */ -+ -+ for (;;) -+ { -+ /* Merge directly into the output file if possible. */ -+ FILE **fps; -+ size_t nopened = open_input_files (files, nfiles, &fps); -+ -+ if (nopened == nfiles) -+ { -+ FILE *ofp = stream_open (output_file, "w"); -+ if (ofp) -+ { -+ mergefps (files, ntemps, nfiles, ofp, output_file, fps); -+ break; -+ } -+ if (errno != EMFILE || nopened <= 2) -+ die (_("open failed"), output_file); -+ } -+ else if (nopened <= 2) -+ die (_("open failed"), files[nopened].name); -+ -+ /* We ran out of file descriptors. Close one of the input -+ files, to gain a file descriptor. Then create a temporary -+ file with our spare file descriptor. Retry if that failed -+ (e.g., some other process could open a file between the time -+ we closed and tried to create). */ -+ FILE *tfp; -+ pid_t pid; -+ char *temp; -+ do -+ { -+ nopened--; -+ xfclose (fps[nopened], files[nopened].name); -+ temp = maybe_create_temp (&tfp, &pid, ! (nopened <= 2)); -+ } -+ while (!temp); -+ -+ /* Merge into the newly allocated temporary. */ -+ mergefps (&files[0], MIN (ntemps, nopened), nopened, tfp, temp, fps); -+ ntemps -= MIN (ntemps, nopened); -+ files[0].name = temp; -+ files[0].pid = pid; -+ -+ memmove (&files[1], &files[nopened], (nfiles - nopened) * sizeof *files); -+ ntemps++; -+ nfiles -= nopened - 1; -+ } -+} -+ -+/* Sort NFILES FILES onto OUTPUT_FILE. */ -+ -+static void -+sort (char * const *files, size_t nfiles, char const *output_file) -+{ -+ struct buffer buf; -+ size_t ntemps = 0; -+ bool output_file_created = false; -+ -+ buf.alloc = 0; -+ -+ while (nfiles) -+ { -+ char const *temp_output; -+ char const *file = *files; -+ FILE *fp = xfopen (file, "r"); -+ FILE *tfp; -+ size_t bytes_per_line = (2 * sizeof (struct line) -+ - sizeof (struct line) / 2); -+ -+ if (! buf.alloc) -+ initbuf (&buf, bytes_per_line, -+ sort_buffer_size (&fp, 1, files, nfiles, bytes_per_line)); -+ buf.eof = false; -+ files++; -+ nfiles--; -+ -+ while (fillbuf (&buf, fp, file)) -+ { -+ struct line *line; -+ struct line *linebase; -+ -+ if (buf.eof && nfiles -+ && (bytes_per_line + 1 -+ < (buf.alloc - buf.used - bytes_per_line * buf.nlines))) -+ { -+ /* End of file, but there is more input and buffer room. -+ Concatenate the next input file; this is faster in -+ the usual case. */ -+ buf.left = buf.used; -+ break; -+ } -+ -+ line = buffer_linelim (&buf); -+ linebase = line - buf.nlines; -+ if (1 < buf.nlines) -+ sortlines (line, buf.nlines, linebase); -+ if (buf.eof && !nfiles && !ntemps && !buf.left) -+ { -+ xfclose (fp, file); -+ tfp = xfopen (output_file, "w"); -+ temp_output = output_file; -+ output_file_created = true; -+ } -+ else -+ { -+ ++ntemps; -+ temp_output = create_temp (&tfp, NULL); -+ } -+ -+ do -+ { -+ line--; -+ write_bytes (line->text, line->length, tfp, temp_output); -+ if (unique) -+ while (linebase < line && compare (line, line - 1) == 0) -+ line--; -+ } -+ while (linebase < line); -+ -+ xfclose (tfp, temp_output); -+ -+ /* Free up some resources every once in a while. */ -+ if (MAX_PROCS_BEFORE_REAP < nprocs) -+ reap_some (); -+ -+ if (output_file_created) -+ goto finish; -+ } -+ xfclose (fp, file); -+ } -+ -+ finish: -+ free (buf.buf); -+ -+ if (! output_file_created) -+ { -+ size_t i; -+ struct tempnode *node = temphead; -+ struct sortfile *tempfiles = xnmalloc (ntemps, sizeof *tempfiles); -+ for (i = 0; node; i++) -+ { -+ tempfiles[i].name = node->name; -+ tempfiles[i].pid = node->pid; -+ node = node->next; -+ } -+ merge (tempfiles, ntemps, ntemps, output_file); -+ free (tempfiles); -+ } -+} -+ -+/* Insert a malloc'd copy of key KEY_ARG at the end of the key list. */ -+ -+static void -+insertkey (struct keyfield *key_arg) -+{ -+ struct keyfield **p; -+ struct keyfield *key = xmemdup (key_arg, sizeof *key); -+ -+ for (p = &keylist; *p; p = &(*p)->next) -+ continue; -+ *p = key; -+ key->next = NULL; -+} -+ -+/* Report a bad field specification SPEC, with extra info MSGID. */ -+ -+static void badfieldspec (char const *, char const *) -+ ATTRIBUTE_NORETURN; -+static void -+badfieldspec (char const *spec, char const *msgid) -+{ -+ error (SORT_FAILURE, 0, _("%s: invalid field specification %s"), -+ _(msgid), quote (spec)); -+ abort (); -+} -+ -+/* Report incompatible options. */ -+ -+static void incompatible_options (char const *) ATTRIBUTE_NORETURN; -+static void -+incompatible_options (char const *opts) -+{ -+ error (SORT_FAILURE, 0, _("options `-%s' are incompatible"), opts); -+ abort (); -+} -+ -+/* Check compatibility of ordering options. */ -+ -+static void -+check_ordering_compatibility (void) -+{ -+ struct keyfield const *key; -+ -+ for (key = keylist; key; key = key->next) -+ if ((1 < (key->random + key->numeric + key->general_numeric + key->month -+ + key->version + !!key->ignore + key->human_numeric)) -+ || (key->random && key->translate)) -+ { -+ /* The following is too big, but guaranteed to be "big enough". */ -+ char opts[sizeof short_options]; -+ char *p = opts; -+ if (key->ignore == nondictionary) -+ *p++ = 'd'; -+ if (key->translate) -+ *p++ = 'f'; -+ if (key->general_numeric) -+ *p++ = 'g'; -+ if (key->human_numeric) -+ *p++ = 'h'; -+ if (key->ignore == nonprinting) -+ *p++ = 'i'; -+ if (key->month) -+ *p++ = 'M'; -+ if (key->numeric) -+ *p++ = 'n'; -+ if (key->version) -+ *p++ = 'V'; -+ if (key->random) -+ *p++ = 'R'; -+ *p = '\0'; -+ incompatible_options (opts); -+ } -+} -+ -+/* Parse the leading integer in STRING and store the resulting value -+ (which must fit into size_t) into *VAL. Return the address of the -+ suffix after the integer. If the value is too large, silently -+ substitute SIZE_MAX. If MSGID is NULL, return NULL after -+ failure; otherwise, report MSGID and exit on failure. */ -+ -+static char const * -+parse_field_count (char const *string, size_t *val, char const *msgid) -+{ -+ char *suffix; -+ uintmax_t n; -+ -+ switch (xstrtoumax (string, &suffix, 10, &n, "")) -+ { -+ case LONGINT_OK: -+ case LONGINT_INVALID_SUFFIX_CHAR: -+ *val = n; -+ if (*val == n) -+ break; -+ /* Fall through. */ -+ case LONGINT_OVERFLOW: -+ case LONGINT_OVERFLOW | LONGINT_INVALID_SUFFIX_CHAR: -+ *val = SIZE_MAX; -+ break; -+ -+ case LONGINT_INVALID: -+ if (msgid) -+ error (SORT_FAILURE, 0, _("%s: invalid count at start of %s"), -+ _(msgid), quote (string)); -+ return NULL; -+ } -+ -+ return suffix; -+} -+ -+/* Handle interrupts and hangups. */ -+ -+static void -+sighandler (int sig) -+{ -+ if (! SA_NOCLDSTOP) -+ signal (sig, SIG_IGN); -+ -+ cleanup (); -+ -+ signal (sig, SIG_DFL); -+ raise (sig); -+} -+ -+/* Set the ordering options for KEY specified in S. -+ Return the address of the first character in S that -+ is not a valid ordering option. -+ BLANKTYPE is the kind of blanks that 'b' should skip. */ -+ -+static char * -+set_ordering (const char *s, struct keyfield *key, enum blanktype blanktype) -+{ -+ while (*s) -+ { -+ switch (*s) -+ { -+ case 'b': -+ if (blanktype == bl_start || blanktype == bl_both) -+ key->skipsblanks = true; -+ if (blanktype == bl_end || blanktype == bl_both) -+ key->skipeblanks = true; -+ break; -+ case 'd': -+ key->ignore = nondictionary; -+ break; -+ case 'f': -+ key->translate = fold_toupper; -+ break; -+ case 'g': -+ key->general_numeric = true; -+ break; -+ case 'h': -+ key->human_numeric = true; -+ break; -+ case 'i': -+ /* Option order should not matter, so don't let -i override -+ -d. -d implies -i, but -i does not imply -d. */ -+ if (! key->ignore) -+ key->ignore = nonprinting; -+ break; -+ case 'M': -+ key->month = true; -+ break; -+ case 'n': -+ key->numeric = true; -+ break; -+ case 'R': -+ key->random = true; -+ break; -+ case 'r': -+ key->reverse = true; -+ break; -+ case 'V': -+ key->version = true; -+ break; -+ default: -+ return (char *) s; -+ } -+ ++s; -+ } -+ return (char *) s; -+} -+ -+static struct keyfield * -+key_init (struct keyfield *key) -+{ -+ memset (key, 0, sizeof *key); -+ key->eword = SIZE_MAX; -+ key->si_present = -1; -+ return key; -+} -+ -+int -+main (int argc, char **argv) -+{ -+ struct keyfield *key; -+ struct keyfield key_buf; -+ struct keyfield gkey; -+ char const *s; -+ int c = 0; -+ char checkonly = 0; -+ bool mergeonly = false; -+ char *random_source = NULL; -+ bool need_random = false; -+ size_t nfiles = 0; -+ bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL); -+ bool obsolete_usage = (posix2_version () < 200112); -+ char **files; -+ char *files_from = NULL; -+ struct Tokens tok; -+ char const *outfile = NULL; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ initialize_exit_failure (SORT_FAILURE); -+ -+ hard_LC_COLLATE = hard_locale (LC_COLLATE); -+#if HAVE_NL_LANGINFO -+ hard_LC_TIME = hard_locale (LC_TIME); -+#endif -+ -+ /* Get locale's representation of the decimal point. */ -+ { -+ struct lconv const *locale = localeconv (); -+ -+ /* If the locale doesn't define a decimal point, or if the decimal -+ point is multibyte, use the C locale's decimal point. FIXME: -+ add support for multibyte decimal points. */ -+ decimal_point = to_uchar (locale->decimal_point[0]); -+ if (! decimal_point || locale->decimal_point[1]) -+ decimal_point = '.'; -+ -+ /* FIXME: add support for multibyte thousands separators. */ -+ thousands_sep = to_uchar (*locale->thousands_sep); -+ if (! thousands_sep || locale->thousands_sep[1]) -+ thousands_sep = -1; -+ } -+ -+ have_read_stdin = false; -+ inittables (); -+ -+ { -+ size_t i; -+ static int const sig[] = -+ { -+ /* The usual suspects. */ -+ SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, -+#ifdef SIGPOLL -+ SIGPOLL, -+#endif -+#ifdef SIGPROF -+ SIGPROF, -+#endif -+#ifdef SIGVTALRM -+ SIGVTALRM, -+#endif -+#ifdef SIGXCPU -+ SIGXCPU, -+#endif -+#ifdef SIGXFSZ -+ SIGXFSZ, -+#endif -+ }; -+ enum { nsigs = ARRAY_CARDINALITY (sig) }; -+ -+#if SA_NOCLDSTOP -+ struct sigaction act; -+ -+ sigemptyset (&caught_signals); -+ for (i = 0; i < nsigs; i++) -+ { -+ sigaction (sig[i], NULL, &act); -+ if (act.sa_handler != SIG_IGN) -+ sigaddset (&caught_signals, sig[i]); -+ } -+ -+ act.sa_handler = sighandler; -+ act.sa_mask = caught_signals; -+ act.sa_flags = 0; -+ -+ for (i = 0; i < nsigs; i++) -+ if (sigismember (&caught_signals, sig[i])) -+ sigaction (sig[i], &act, NULL); -+#else -+ for (i = 0; i < nsigs; i++) -+ if (signal (sig[i], SIG_IGN) != SIG_IGN) -+ { -+ signal (sig[i], sighandler); -+ siginterrupt (sig[i], 1); -+ } -+#endif -+ } -+ -+ /* The signal mask is known, so it is safe to invoke exit_cleanup. */ -+ atexit (exit_cleanup); -+ -+ gkey.sword = gkey.eword = SIZE_MAX; -+ gkey.ignore = NULL; -+ gkey.translate = NULL; -+ gkey.numeric = gkey.general_numeric = gkey.human_numeric = false; -+ gkey.si_present = -1; -+ gkey.random = gkey.version = false; -+ gkey.month = gkey.reverse = false; -+ gkey.skipsblanks = gkey.skipeblanks = false; -+ -+ files = xnmalloc (argc, sizeof *files); -+ -+ for (;;) -+ { -+ /* Parse an operand as a file after "--" was seen; or if -+ pedantic and a file was seen, unless the POSIX version -+ predates 1003.1-2001 and -c was not seen and the operand is -+ "-o FILE" or "-oFILE". */ -+ int oi = -1; -+ -+ if (c == -1 -+ || (posixly_correct && nfiles != 0 -+ && ! (obsolete_usage -+ && ! checkonly -+ && optind != argc -+ && argv[optind][0] == '-' && argv[optind][1] == 'o' -+ && (argv[optind][2] || optind + 1 != argc))) -+ || ((c = getopt_long (argc, argv, short_options, -+ long_options, &oi)) -+ == -1)) -+ { -+ if (argc <= optind) -+ break; -+ files[nfiles++] = argv[optind++]; -+ } -+ else switch (c) -+ { -+ case 1: -+ key = NULL; -+ if (optarg[0] == '+') -+ { -+ bool minus_pos_usage = (optind != argc && argv[optind][0] == '-' -+ && ISDIGIT (argv[optind][1])); -+ obsolete_usage |= minus_pos_usage && !posixly_correct; -+ if (obsolete_usage) -+ { -+ /* Treat +POS1 [-POS2] as a key if possible; but silently -+ treat an operand as a file if it is not a valid +POS1. */ -+ key = key_init (&key_buf); -+ s = parse_field_count (optarg + 1, &key->sword, NULL); -+ if (s && *s == '.') -+ s = parse_field_count (s + 1, &key->schar, NULL); -+ if (! (key->sword || key->schar)) -+ key->sword = SIZE_MAX; -+ if (! s || *set_ordering (s, key, bl_start)) -+ key = NULL; -+ else -+ { -+ if (minus_pos_usage) -+ { -+ char const *optarg1 = argv[optind++]; -+ s = parse_field_count (optarg1 + 1, &key->eword, -+ N_("invalid number after `-'")); -+ if (*s == '.') -+ s = parse_field_count (s + 1, &key->echar, -+ N_("invalid number after `.'")); -+ if (*set_ordering (s, key, bl_end)) -+ badfieldspec (optarg1, -+ N_("stray character in field spec")); -+ } -+ insertkey (key); -+ } -+ } -+ } -+ if (! key) -+ files[nfiles++] = optarg; -+ break; -+ -+ case SORT_OPTION: -+ c = XARGMATCH ("--sort", optarg, sort_args, sort_types); -+ /* Fall through. */ -+ case 'b': -+ case 'd': -+ case 'f': -+ case 'g': -+ case 'h': -+ case 'i': -+ case 'M': -+ case 'n': -+ case 'r': -+ case 'R': -+ case 'V': -+ { -+ char str[2]; -+ str[0] = c; -+ str[1] = '\0'; -+ set_ordering (str, &gkey, bl_both); -+ } -+ break; -+ -+ case CHECK_OPTION: -+ c = (optarg -+ ? XARGMATCH ("--check", optarg, check_args, check_types) -+ : 'c'); -+ /* Fall through. */ -+ case 'c': -+ case 'C': -+ if (checkonly && checkonly != c) -+ incompatible_options ("cC"); -+ checkonly = c; -+ break; -+ -+ case COMPRESS_PROGRAM_OPTION: -+ if (compress_program && !STREQ (compress_program, optarg)) -+ error (SORT_FAILURE, 0, _("multiple compress programs specified")); -+ compress_program = optarg; -+ break; -+ -+ case FILES0_FROM_OPTION: -+ files_from = optarg; -+ break; -+ -+ case 'k': -+ key = key_init (&key_buf); -+ -+ /* Get POS1. */ -+ s = parse_field_count (optarg, &key->sword, -+ N_("invalid number at field start")); -+ if (! key->sword--) -+ { -+ /* Provoke with `sort -k0' */ -+ badfieldspec (optarg, N_("field number is zero")); -+ } -+ if (*s == '.') -+ { -+ s = parse_field_count (s + 1, &key->schar, -+ N_("invalid number after `.'")); -+ if (! key->schar--) -+ { -+ /* Provoke with `sort -k1.0' */ -+ badfieldspec (optarg, N_("character offset is zero")); -+ } -+ } -+ if (! (key->sword || key->schar)) -+ key->sword = SIZE_MAX; -+ s = set_ordering (s, key, bl_start); -+ if (*s != ',') -+ { -+ key->eword = SIZE_MAX; -+ key->echar = 0; -+ } -+ else -+ { -+ /* Get POS2. */ -+ s = parse_field_count (s + 1, &key->eword, -+ N_("invalid number after `,'")); -+ if (! key->eword--) -+ { -+ /* Provoke with `sort -k1,0' */ -+ badfieldspec (optarg, N_("field number is zero")); -+ } -+ if (*s == '.') -+ { -+ s = parse_field_count (s + 1, &key->echar, -+ N_("invalid number after `.'")); -+ } -+ s = set_ordering (s, key, bl_end); -+ } -+ if (*s) -+ badfieldspec (optarg, N_("stray character in field spec")); -+ insertkey (key); -+ break; -+ -+ case 'm': -+ mergeonly = true; -+ break; -+ -+ case NMERGE_OPTION: -+ specify_nmerge (oi, c, optarg); -+ break; -+ -+ case 'o': -+ if (outfile && !STREQ (outfile, optarg)) -+ error (SORT_FAILURE, 0, _("multiple output files specified")); -+ outfile = optarg; -+ break; -+ -+ case RANDOM_SOURCE_OPTION: -+ if (random_source && !STREQ (random_source, optarg)) -+ error (SORT_FAILURE, 0, _("multiple random sources specified")); -+ random_source = optarg; -+ break; -+ -+ case 's': -+ stable = true; -+ break; -+ -+ case 'S': -+ specify_sort_size (oi, c, optarg); -+ break; -+ -+ case 't': -+ { -+ char newtab = optarg[0]; -+ if (! newtab) -+ error (SORT_FAILURE, 0, _("empty tab")); -+ if (optarg[1]) -+ { -+ if (STREQ (optarg, "\\0")) -+ newtab = '\0'; -+ else -+ { -+ /* Provoke with `sort -txx'. Complain about -+ "multi-character tab" instead of "multibyte tab", so -+ that the diagnostic's wording does not need to be -+ changed once multibyte characters are supported. */ -+ error (SORT_FAILURE, 0, _("multi-character tab %s"), -+ quote (optarg)); -+ } -+ } -+ if (tab != TAB_DEFAULT && tab != newtab) -+ error (SORT_FAILURE, 0, _("incompatible tabs")); -+ tab = newtab; -+ } -+ break; -+ -+ case 'T': -+ add_temp_dir (optarg); -+ break; -+ -+ case 'u': -+ unique = true; -+ break; -+ -+ case 'y': -+ /* Accept and ignore e.g. -y0 for compatibility with Solaris 2.x -+ through Solaris 7. It is also accepted by many non-Solaris -+ "sort" implementations, e.g., AIX 5.2, HP-UX 11i v2, IRIX 6.5. -+ -y is marked as obsolete starting with Solaris 8 (1999), but is -+ still accepted as of Solaris 10 prerelease (2004). -+ -+ Solaris 2.5.1 "sort -y 100" reads the input file "100", but -+ emulate Solaris 8 and 9 "sort -y 100" which ignores the "100", -+ and which in general ignores the argument after "-y" if it -+ consists entirely of digits (it can even be empty). */ -+ if (optarg == argv[optind - 1]) -+ { -+ char const *p; -+ for (p = optarg; ISDIGIT (*p); p++) -+ continue; -+ optind -= (*p != '\0'); -+ } -+ break; -+ -+ case 'z': -+ eolchar = 0; -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (SORT_FAILURE); -+ } -+ } -+ -+ if (files_from) -+ { -+ FILE *stream; -+ -+ /* When using --files0-from=F, you may not specify any files -+ on the command-line. */ -+ if (nfiles) -+ { -+ error (0, 0, _("extra operand %s"), quote (files[0])); -+ fprintf (stderr, "%s\n", -+ _("file operands cannot be combined with --files0-from")); -+ usage (SORT_FAILURE); -+ } -+ -+ if (STREQ (files_from, "-")) -+ stream = stdin; -+ else -+ { -+ stream = fopen (files_from, "r"); -+ if (stream == NULL) -+ error (SORT_FAILURE, errno, _("cannot open %s for reading"), -+ quote (files_from)); -+ } -+ -+ readtokens0_init (&tok); -+ -+ if (! readtokens0 (stream, &tok) || fclose (stream) != 0) -+ error (SORT_FAILURE, 0, _("cannot read file names from %s"), -+ quote (files_from)); -+ -+ if (tok.n_tok) -+ { -+ size_t i; -+ free (files); -+ files = tok.tok; -+ nfiles = tok.n_tok; -+ for (i = 0; i < nfiles; i++) -+ { -+ if (STREQ (files[i], "-")) -+ error (SORT_FAILURE, 0, _("when reading file names from stdin, " -+ "no file name of %s allowed"), -+ quote (files[i])); -+ else if (files[i][0] == '\0') -+ { -+ /* Using the standard `filename:line-number:' prefix here is -+ not totally appropriate, since NUL is the separator, not NL, -+ but it might be better than nothing. */ -+ unsigned long int file_number = i + 1; -+ error (SORT_FAILURE, 0, -+ _("%s:%lu: invalid zero-length file name"), -+ quotearg_colon (files_from), file_number); -+ } -+ } -+ } -+ else -+ error (SORT_FAILURE, 0, _("no input from %s"), -+ quote (files_from)); -+ } -+ -+ /* Inheritance of global options to individual keys. */ -+ for (key = keylist; key; key = key->next) -+ { -+ if (! (key->ignore -+ || key->translate -+ || (key->skipsblanks -+ || key->reverse -+ || key->skipeblanks -+ || key->month -+ || key->numeric -+ || key->version -+ || key->general_numeric -+ || key->human_numeric -+ || key->random))) -+ { -+ key->ignore = gkey.ignore; -+ key->translate = gkey.translate; -+ key->skipsblanks = gkey.skipsblanks; -+ key->skipeblanks = gkey.skipeblanks; -+ key->month = gkey.month; -+ key->numeric = gkey.numeric; -+ key->general_numeric = gkey.general_numeric; -+ key->human_numeric = gkey.human_numeric; -+ key->random = gkey.random; -+ key->reverse = gkey.reverse; -+ key->version = gkey.version; -+ } -+ -+ need_random |= key->random; -+ } -+ -+ if (!keylist && (gkey.ignore -+ || gkey.translate -+ || (gkey.skipsblanks -+ || gkey.skipeblanks -+ || gkey.month -+ || gkey.numeric -+ || gkey.general_numeric -+ || gkey.human_numeric -+ || gkey.random -+ || gkey.version))) -+ { -+ insertkey (&gkey); -+ need_random |= gkey.random; -+ } -+ -+ check_ordering_compatibility (); -+ -+ reverse = gkey.reverse; -+ -+ if (need_random) -+ { -+ randread_source = randread_new (random_source, MD5_DIGEST_SIZE); -+ if (! randread_source) -+ die (_("open failed"), random_source); -+ } -+ -+ if (temp_dir_count == 0) -+ { -+ char const *tmp_dir = getenv ("TMPDIR"); -+ add_temp_dir (tmp_dir ? tmp_dir : DEFAULT_TMPDIR); -+ } -+ -+ if (nfiles == 0) -+ { -+ static char *minus = (char *) "-"; -+ nfiles = 1; -+ free (files); -+ files = − -+ } -+ -+ /* Need to re-check that we meet the minimum requirement for memory -+ usage with the final value for NMERGE. */ -+ if (0 < sort_size) -+ sort_size = MAX (sort_size, MIN_SORT_SIZE); -+ -+ if (checkonly) -+ { -+ if (nfiles > 1) -+ error (SORT_FAILURE, 0, _("extra operand %s not allowed with -%c"), -+ quote (files[1]), checkonly); -+ -+ if (outfile) -+ { -+ static char opts[] = {0, 'o', 0}; -+ opts[0] = checkonly; -+ incompatible_options (opts); -+ } -+ -+ /* POSIX requires that sort return 1 IFF invoked with -c or -C and the -+ input is not properly sorted. */ -+ exit (check (files[0], checkonly) ? EXIT_SUCCESS : SORT_OUT_OF_ORDER); -+ } -+ -+ if (mergeonly) -+ { -+ struct sortfile *sortfiles = xcalloc (nfiles, sizeof *sortfiles); -+ size_t i; -+ -+ for (i = 0; i < nfiles; ++i) -+ sortfiles[i].name = files[i]; -+ -+ merge (sortfiles, 0, nfiles, outfile); -+ IF_LINT (free (sortfiles)); -+ } -+ else -+ sort (files, nfiles, outfile); -+ -+ if (have_read_stdin && fclose (stdin) == EOF) -+ die (_("close failed"), "-"); -+ -+ exit (EXIT_SUCCESS); -+} diff -urNp coreutils-8.0-orig/src/unexpand.c coreutils-8.0/src/unexpand.c --- coreutils-8.0-orig/src/unexpand.c 2009-09-29 15:27:54.000000000 +0200 +++ coreutils-8.0/src/unexpand.c 2009-10-07 10:07:16.000000000 +0200 @@ -13188,542 +3536,6 @@ diff -urNp coreutils-8.0-orig/src/unexpand.c coreutils-8.0/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.0-orig/src/unexpand.c.orig coreutils-8.0/src/unexpand.c.orig ---- coreutils-8.0-orig/src/unexpand.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/unexpand.c.orig 2009-09-29 15:27:54.000000000 +0200 -@@ -0,0 +1,532 @@ -+/* unexpand - convert blanks to tabs -+ Copyright (C) 89, 91, 1995-2006, 2008-2009 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 . */ -+ -+/* By default, convert only maximal strings of initial blanks and tabs -+ into tabs. -+ Preserves backspace characters in the output; they decrement the -+ column count for tab calculations. -+ The default action is equivalent to -8. -+ -+ Options: -+ --tabs=tab1[,tab2[,...]] -+ -t tab1[,tab2[,...]] -+ -tab1[,tab2[,...]] If only one tab stop is given, set the tabs tab1 -+ columns apart instead of the default 8. Otherwise, -+ set the tabs at columns tab1, tab2, etc. (numbered from -+ 0); preserve any blanks beyond the tab stops given. -+ --all -+ -a Use tabs wherever they would replace 2 or more blanks, -+ not just at the beginnings of lines. -+ -+ David MacKenzie */ -+ -+#include -+ -+#include -+#include -+#include -+#include "system.h" -+#include "error.h" -+#include "quote.h" -+#include "xstrndup.h" -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "unexpand" -+ -+#define AUTHORS proper_name ("David MacKenzie") -+ -+/* If true, convert blanks even after nonblank characters have been -+ read on the line. */ -+static bool convert_entire_line; -+ -+/* If nonzero, the size of all tab stops. If zero, use `tab_list' instead. */ -+static size_t tab_size; -+ -+/* The maximum distance between tab stops. */ -+static size_t max_column_width; -+ -+/* Array of the explicit column numbers of the tab stops; -+ after `tab_list' is exhausted, the rest of the line is printed -+ unchanged. The first column is column 0. */ -+static uintmax_t *tab_list; -+ -+/* The number of allocated entries in `tab_list'. */ -+static size_t n_tabs_allocated; -+ -+/* The index of the first invalid element of `tab_list', -+ where the next element can be added. */ -+static size_t first_free_tab; -+ -+/* Null-terminated array of input filenames. */ -+static char **file_list; -+ -+/* Default for `file_list' if no files are given on the command line. */ -+static char *stdin_argv[] = -+{ -+ (char *) "-", NULL -+}; -+ -+/* True if we have ever read standard input. */ -+static bool have_read_stdin; -+ -+/* The desired exit status. */ -+static int exit_status; -+ -+/* For long options that have no equivalent short option, use a -+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -+enum -+{ -+ CONVERT_FIRST_ONLY_OPTION = CHAR_MAX + 1 -+}; -+ -+static struct option const longopts[] = -+{ -+ {"tabs", required_argument, NULL, 't'}, -+ {"all", no_argument, NULL, 'a'}, -+ {"first-only", no_argument, NULL, CONVERT_FIRST_ONLY_OPTION}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... [FILE]...\n\ -+"), -+ program_name); -+ fputs (_("\ -+Convert blanks in each FILE to tabs, writing to standard output.\n\ -+With no FILE, or when FILE is -, read standard input.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ -a, --all convert all blanks, instead of just initial blanks\n\ -+ --first-only convert only leading sequences of blanks (overrides -a)\n\ -+ -t, --tabs=N have tabs N characters apart instead of 8 (enables -a)\n\ -+ -t, --tabs=LIST use comma separated LIST of tab positions (enables -a)\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+/* Add tab stop TABVAL to the end of `tab_list'. */ -+ -+static void -+add_tab_stop (uintmax_t tabval) -+{ -+ uintmax_t prev_column = first_free_tab ? tab_list[first_free_tab - 1] : 0; -+ uintmax_t column_width = prev_column <= tabval ? tabval - prev_column : 0; -+ -+ if (first_free_tab == n_tabs_allocated) -+ tab_list = X2NREALLOC (tab_list, &n_tabs_allocated); -+ tab_list[first_free_tab++] = tabval; -+ -+ if (max_column_width < column_width) -+ { -+ if (SIZE_MAX < column_width) -+ error (EXIT_FAILURE, 0, _("tabs are too far apart")); -+ max_column_width = column_width; -+ } -+} -+ -+/* Add the comma or blank separated list of tab stops STOPS -+ to the list of tab stops. */ -+ -+static void -+parse_tab_stops (char const *stops) -+{ -+ bool have_tabval = false; -+ uintmax_t tabval IF_LINT (= 0); -+ char const *num_start IF_LINT (= NULL); -+ bool ok = true; -+ -+ for (; *stops; stops++) -+ { -+ if (*stops == ',' || isblank (to_uchar (*stops))) -+ { -+ if (have_tabval) -+ add_tab_stop (tabval); -+ have_tabval = false; -+ } -+ else if (ISDIGIT (*stops)) -+ { -+ if (!have_tabval) -+ { -+ tabval = 0; -+ have_tabval = true; -+ num_start = stops; -+ } -+ -+ /* Detect overflow. */ -+ if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) -+ { -+ size_t len = strspn (num_start, "0123456789"); -+ char *bad_num = xstrndup (num_start, len); -+ error (0, 0, _("tab stop is too large %s"), quote (bad_num)); -+ free (bad_num); -+ ok = false; -+ stops = num_start + len - 1; -+ } -+ } -+ else -+ { -+ error (0, 0, _("tab size contains invalid character(s): %s"), -+ quote (stops)); -+ ok = false; -+ break; -+ } -+ } -+ -+ if (!ok) -+ exit (EXIT_FAILURE); -+ -+ if (have_tabval) -+ add_tab_stop (tabval); -+} -+ -+/* Check that the list of tab stops TABS, with ENTRIES entries, -+ contains only nonzero, ascending values. */ -+ -+static void -+validate_tab_stops (uintmax_t const *tabs, size_t entries) -+{ -+ uintmax_t prev_tab = 0; -+ size_t i; -+ -+ for (i = 0; i < entries; i++) -+ { -+ if (tabs[i] == 0) -+ error (EXIT_FAILURE, 0, _("tab size cannot be 0")); -+ if (tabs[i] <= prev_tab) -+ error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); -+ prev_tab = tabs[i]; -+ } -+} -+ -+/* Close the old stream pointer FP if it is non-NULL, -+ and return a new one opened to read the next input file. -+ Open a filename of `-' as the standard input. -+ Return NULL if there are no more input files. */ -+ -+static FILE * -+next_file (FILE *fp) -+{ -+ static char *prev_file; -+ char *file; -+ -+ if (fp) -+ { -+ if (ferror (fp)) -+ { -+ error (0, errno, "%s", prev_file); -+ exit_status = EXIT_FAILURE; -+ } -+ if (STREQ (prev_file, "-")) -+ clearerr (fp); /* Also clear EOF. */ -+ else if (fclose (fp) != 0) -+ { -+ error (0, errno, "%s", prev_file); -+ exit_status = EXIT_FAILURE; -+ } -+ } -+ -+ while ((file = *file_list++) != NULL) -+ { -+ if (STREQ (file, "-")) -+ { -+ have_read_stdin = true; -+ prev_file = file; -+ return stdin; -+ } -+ fp = fopen (file, "r"); -+ if (fp) -+ { -+ prev_file = file; -+ return fp; -+ } -+ error (0, errno, "%s", file); -+ exit_status = EXIT_FAILURE; -+ } -+ return NULL; -+} -+ -+/* Change blanks to tabs, writing to stdout. -+ Read each file in `file_list', in order. */ -+ -+static void -+unexpand (void) -+{ -+ /* Input stream. */ -+ FILE *fp = next_file (NULL); -+ -+ /* 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; -+ -+ if (!fp) -+ return; -+ -+ /* 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); -+ -+ for (;;) -+ { -+ /* Input character, or EOF. */ -+ int c; -+ -+ /* If true, perform translations. */ -+ bool convert = true; -+ -+ -+ /* The following variables have valid values only when CONVERT -+ is true: */ -+ -+ /* Column of next input character. */ -+ uintmax_t column = 0; -+ -+ /* Column the next input tab stop is on. */ -+ uintmax_t next_tab_column = 0; -+ -+ /* Index in TAB_LIST of next tab stop to examine. */ -+ size_t tab_index = 0; -+ -+ /* If true, the first pending blank came just before a tab stop. */ -+ bool one_blank_before_tab_stop = false; -+ -+ /* If true, the previous input character was a blank. This is -+ initially true, since initial strings of blanks are treated -+ as if the line was preceded by a blank. */ -+ bool prev_blank = true; -+ -+ /* Number of pending columns of blanks. */ -+ size_t pending = 0; -+ -+ -+ /* Convert a line of text. */ -+ -+ do -+ { -+ while ((c = getc (fp)) < 0 && (fp = next_file (fp))) -+ continue; -+ -+ if (convert) -+ { -+ bool blank = !! isblank (c); -+ -+ if (blank) -+ { -+ if (next_tab_column <= column) -+ { -+ if (tab_size) -+ next_tab_column = -+ column + (tab_size - column % tab_size); -+ else -+ for (;;) -+ if (tab_index == first_free_tab) -+ { -+ convert = false; -+ break; -+ } -+ else -+ { -+ uintmax_t tab = tab_list[tab_index++]; -+ if (column < tab) -+ { -+ next_tab_column = tab; -+ break; -+ } -+ } -+ } -+ -+ if (convert) -+ { -+ if (next_tab_column < column) -+ error (EXIT_FAILURE, 0, _("input line is too long")); -+ -+ if (c == '\t') -+ { -+ column = next_tab_column; -+ -+ /* Discard pending blanks, unless it was a single -+ blank just before the previous tab stop. */ -+ if (! (pending == 1 && one_blank_before_tab_stop)) -+ { -+ pending = 0; -+ one_blank_before_tab_stop = false; -+ } -+ } -+ else -+ { -+ column++; -+ -+ if (! (prev_blank && column == next_tab_column)) -+ { -+ /* It is not yet known whether the pending blanks -+ will be replaced by tabs. */ -+ if (column == next_tab_column) -+ one_blank_before_tab_stop = true; -+ pending_blank[pending++] = c; -+ prev_blank = true; -+ continue; -+ } -+ -+ /* Replace the pending blanks by a tab or two. */ -+ pending_blank[0] = c = '\t'; -+ pending = one_blank_before_tab_stop; -+ } -+ } -+ } -+ else if (c == '\b') -+ { -+ /* Go back one column, and force recalculation of the -+ next tab stop. */ -+ column -= !!column; -+ next_tab_column = column; -+ tab_index -= !!tab_index; -+ } -+ else -+ { -+ column++; -+ if (!column) -+ error (EXIT_FAILURE, 0, _("input line is too long")); -+ } -+ -+ if (pending) -+ { -+ if (fwrite (pending_blank, 1, pending, stdout) != pending) -+ error (EXIT_FAILURE, errno, _("write error")); -+ pending = 0; -+ one_blank_before_tab_stop = false; -+ } -+ -+ prev_blank = blank; -+ convert &= convert_entire_line || blank; -+ } -+ -+ if (c < 0) -+ { -+ free (pending_blank); -+ return; -+ } -+ -+ if (putchar (c) < 0) -+ error (EXIT_FAILURE, errno, _("write error")); -+ } -+ while (c != '\n'); -+ } -+} -+ -+int -+main (int argc, char **argv) -+{ -+ bool have_tabval = false; -+ uintmax_t tabval IF_LINT (= 0); -+ int c; -+ -+ /* If true, cancel the effect of any -a (explicit or implicit in -t), -+ so that only leading blanks will be considered. */ -+ bool convert_first_only = false; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdout); -+ -+ have_read_stdin = false; -+ exit_status = EXIT_SUCCESS; -+ convert_entire_line = false; -+ tab_list = NULL; -+ first_free_tab = 0; -+ -+ while ((c = getopt_long (argc, argv, ",0123456789at:", longopts, NULL)) -+ != -1) -+ { -+ switch (c) -+ { -+ case '?': -+ usage (EXIT_FAILURE); -+ case 'a': -+ convert_entire_line = true; -+ break; -+ case 't': -+ convert_entire_line = true; -+ parse_tab_stops (optarg); -+ break; -+ case CONVERT_FIRST_ONLY_OPTION: -+ convert_first_only = true; -+ break; -+ case ',': -+ if (have_tabval) -+ add_tab_stop (tabval); -+ have_tabval = false; -+ break; -+ case_GETOPT_HELP_CHAR; -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ default: -+ if (!have_tabval) -+ { -+ tabval = 0; -+ have_tabval = true; -+ } -+ if (!DECIMAL_DIGIT_ACCUMULATE (tabval, c - '0', uintmax_t)) -+ error (EXIT_FAILURE, 0, _("tab stop value is too large")); -+ break; -+ } -+ } -+ -+ if (convert_first_only) -+ convert_entire_line = false; -+ -+ if (have_tabval) -+ add_tab_stop (tabval); -+ -+ validate_tab_stops (tab_list, first_free_tab); -+ -+ if (first_free_tab == 0) -+ tab_size = max_column_width = 8; -+ else if (first_free_tab == 1) -+ tab_size = tab_list[0]; -+ else -+ tab_size = 0; -+ -+ file_list = (optind < argc ? &argv[optind] : stdin_argv); -+ -+ unexpand (); -+ -+ if (have_read_stdin && fclose (stdin) != 0) -+ error (EXIT_FAILURE, errno, "-"); -+ -+ exit (exit_status); -+} diff -urNp coreutils-8.0-orig/src/uniq.c coreutils-8.0/src/uniq.c --- coreutils-8.0-orig/src/uniq.c 2009-09-23 10:25:44.000000000 +0200 +++ coreutils-8.0/src/uniq.c 2009-10-07 10:07:16.000000000 +0200 @@ -14093,575 +3905,6 @@ diff -urNp coreutils-8.0-orig/src/uniq.c coreutils-8.0/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.0-orig/src/uniq.c.orig coreutils-8.0/src/uniq.c.orig ---- coreutils-8.0-orig/src/uniq.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/uniq.c.orig 2009-09-23 10:25:44.000000000 +0200 -@@ -0,0 +1,565 @@ -+/* uniq -- remove duplicate lines from a sorted file -+ Copyright (C) 86, 91, 1995-2009 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 Richard M. Stallman and David MacKenzie. */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#include "system.h" -+#include "argmatch.h" -+#include "linebuffer.h" -+#include "error.h" -+#include "hard-locale.h" -+#include "posixver.h" -+#include "quote.h" -+#include "xmemcoll.h" -+#include "xstrtol.h" -+#include "memcasecmp.h" -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "uniq" -+ -+#define AUTHORS \ -+ proper_name ("Richard M. Stallman"), \ -+ proper_name ("David MacKenzie") -+ -+#define SWAP_LINES(A, B) \ -+ do \ -+ { \ -+ struct linebuffer *_tmp; \ -+ _tmp = (A); \ -+ (A) = (B); \ -+ (B) = _tmp; \ -+ } \ -+ while (0) -+ -+/* True if the LC_COLLATE locale is hard. */ -+static bool hard_LC_COLLATE; -+ -+/* Number of fields to skip on each line when doing comparisons. */ -+static size_t skip_fields; -+ -+/* Number of chars to skip after skipping any fields. */ -+static size_t skip_chars; -+ -+/* Number of chars to compare. */ -+static size_t check_chars; -+ -+enum countmode -+{ -+ count_occurrences, /* -c Print count before output lines. */ -+ count_none /* Default. Do not print counts. */ -+}; -+ -+/* Whether and how to precede the output lines with a count of the number of -+ times they occurred in the input. */ -+static enum countmode countmode; -+ -+/* Which lines to output: unique lines, the first of a group of -+ repeated lines, and the second and subsequented of a group of -+ repeated lines. */ -+static bool output_unique; -+static bool output_first_repeated; -+static bool output_later_repeated; -+ -+/* If true, ignore case when comparing. */ -+static bool ignore_case; -+ -+enum delimit_method -+{ -+ /* No delimiters output. --all-repeated[=none] */ -+ DM_NONE, -+ -+ /* Delimiter precedes all groups. --all-repeated=prepend */ -+ DM_PREPEND, -+ -+ /* Delimit all groups. --all-repeated=separate */ -+ DM_SEPARATE -+}; -+ -+static char const *const delimit_method_string[] = -+{ -+ "none", "prepend", "separate", NULL -+}; -+ -+static enum delimit_method const delimit_method_map[] = -+{ -+ DM_NONE, DM_PREPEND, DM_SEPARATE -+}; -+ -+/* Select whether/how to delimit groups of duplicate lines. */ -+static enum delimit_method delimit_groups; -+ -+static struct option const longopts[] = -+{ -+ {"count", no_argument, NULL, 'c'}, -+ {"repeated", no_argument, NULL, 'd'}, -+ {"all-repeated", optional_argument, NULL, 'D'}, -+ {"ignore-case", no_argument, NULL, 'i'}, -+ {"unique", no_argument, NULL, 'u'}, -+ {"skip-fields", required_argument, NULL, 'f'}, -+ {"skip-chars", required_argument, NULL, 's'}, -+ {"check-chars", required_argument, NULL, 'w'}, -+ {"zero-terminated", no_argument, NULL, 'z'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... [INPUT [OUTPUT]]\n\ -+"), -+ program_name); -+ fputs (_("\ -+Filter adjacent matching lines from INPUT (or standard input),\n\ -+writing to OUTPUT (or standard output).\n\ -+\n\ -+With no options, matching lines are merged to the first occurrence.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ -c, --count prefix lines by the number of occurrences\n\ -+ -d, --repeated only print duplicate lines\n\ -+"), stdout); -+ fputs (_("\ -+ -D, --all-repeated[=delimit-method] print all duplicate lines\n\ -+ delimit-method={none(default),prepend,separate}\n\ -+ Delimiting is done with blank lines.\n\ -+ -f, --skip-fields=N avoid comparing the first N fields\n\ -+ -i, --ignore-case ignore differences in case when comparing\n\ -+ -s, --skip-chars=N avoid comparing the first N characters\n\ -+ -u, --unique only print unique lines\n\ -+ -z, --zero-terminated end lines with 0 byte, not newline\n\ -+"), stdout); -+ fputs (_("\ -+ -w, --check-chars=N compare no more than N characters in lines\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ fputs (_("\ -+\n\ -+A field is a run of blanks (usually spaces and/or TABs), then non-blank\n\ -+characters. Fields are skipped before chars.\n\ -+"), stdout); -+ fputs (_("\ -+\n\ -+Note: 'uniq' does not detect repeated lines unless they are adjacent.\n\ -+You may want to sort the input first, or use `sort -u' without `uniq'.\n\ -+Also, comparisons honor the rules specified by `LC_COLLATE'.\n\ -+"), stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+/* Convert OPT to size_t, reporting an error using MSGID if OPT is -+ invalid. Silently convert too-large values to SIZE_MAX. */ -+ -+static size_t -+size_opt (char const *opt, char const *msgid) -+{ -+ unsigned long int size; -+ verify (SIZE_MAX <= ULONG_MAX); -+ -+ switch (xstrtoul (opt, NULL, 10, &size, "")) -+ { -+ case LONGINT_OK: -+ case LONGINT_OVERFLOW: -+ break; -+ -+ default: -+ error (EXIT_FAILURE, 0, "%s: %s", opt, _(msgid)); -+ } -+ -+ return MIN (size, SIZE_MAX); -+} -+ -+/* Given a linebuffer LINE, -+ return a pointer to the beginning of the line's field to be compared. */ -+ -+static char * -+find_field (struct linebuffer const *line) -+{ -+ size_t count; -+ char const *lp = line->buffer; -+ size_t size = line->length - 1; -+ size_t i = 0; -+ -+ for (count = 0; count < skip_fields; count++) -+ { -+ while (i < size && isblank (to_uchar (lp[i]))) -+ i++; -+ while (i < size && !isblank (to_uchar (lp[i]))) -+ i++; -+ } -+ -+ for (count = 0; count < skip_chars && i < size; count++) -+ i++; -+ -+ return line->buffer + i; -+} -+ -+/* 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. -+ OLDLEN and NEWLEN are their lengths. */ -+ -+static bool -+different (char *old, char *new, size_t oldlen, size_t newlen) -+{ -+ if (check_chars < oldlen) -+ oldlen = check_chars; -+ if (check_chars < newlen) -+ newlen = check_chars; -+ -+ if (ignore_case) -+ { -+ /* FIXME: This should invoke strcoll somehow. */ -+ return oldlen != newlen || memcasecmp (old, new, oldlen); -+ } -+ else if (hard_LC_COLLATE) -+ return xmemcoll (old, oldlen, new, newlen) != 0; -+ else -+ return oldlen != newlen || memcmp (old, new, oldlen); -+} -+ -+/* Output the line in linebuffer LINE to standard output -+ provided that the switches say it should be output. -+ MATCH is true if the line matches the previous line. -+ If requested, print the number of times it occurred, as well; -+ LINECOUNT + 1 is the number of times that the line occurred. */ -+ -+static void -+writeline (struct linebuffer const *line, -+ bool match, uintmax_t linecount) -+{ -+ if (! (linecount == 0 ? output_unique -+ : !match ? output_first_repeated -+ : output_later_repeated)) -+ return; -+ -+ if (countmode == count_occurrences) -+ printf ("%7" PRIuMAX " ", linecount + 1); -+ -+ fwrite (line->buffer, sizeof (char), line->length, stdout); -+} -+ -+/* Process input file INFILE with output to OUTFILE. -+ If either is "-", use the standard I/O stream for it instead. */ -+ -+static void -+check_file (const char *infile, const char *outfile, char delimiter) -+{ -+ struct linebuffer lb1, lb2; -+ struct linebuffer *thisline, *prevline; -+ -+ if (! (STREQ (infile, "-") || freopen (infile, "r", stdin))) -+ error (EXIT_FAILURE, errno, "%s", infile); -+ if (! (STREQ (outfile, "-") || freopen (outfile, "w", stdout))) -+ error (EXIT_FAILURE, errno, "%s", outfile); -+ -+ thisline = &lb1; -+ prevline = &lb2; -+ -+ initbuffer (thisline); -+ initbuffer (prevline); -+ -+ /* The duplication in the following `if' and `else' blocks is an -+ optimization to distinguish the common case (in which none of -+ the following options has been specified: --count, -repeated, -+ --all-repeated, --unique) from the others. In the common case, -+ this optimization lets uniq output each different line right away, -+ without waiting to see if the next one is different. */ -+ -+ if (output_unique && output_first_repeated && countmode == count_none) -+ { -+ char *prevfield IF_LINT (= NULL); -+ size_t prevlen IF_LINT (= 0); -+ -+ while (!feof (stdin)) -+ { -+ char *thisfield; -+ size_t thislen; -+ if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) -+ break; -+ thisfield = find_field (thisline); -+ thislen = thisline->length - 1 - (thisfield - thisline->buffer); -+ if (prevline->length == 0 -+ || different (thisfield, prevfield, thislen, prevlen)) -+ { -+ fwrite (thisline->buffer, sizeof (char), -+ thisline->length, stdout); -+ -+ SWAP_LINES (prevline, thisline); -+ prevfield = thisfield; -+ prevlen = thislen; -+ } -+ } -+ } -+ else -+ { -+ char *prevfield; -+ size_t prevlen; -+ uintmax_t match_count = 0; -+ bool first_delimiter = true; -+ -+ if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) -+ goto closefiles; -+ prevfield = find_field (prevline); -+ prevlen = prevline->length - 1 - (prevfield - prevline->buffer); -+ -+ while (!feof (stdin)) -+ { -+ bool match; -+ char *thisfield; -+ size_t thislen; -+ if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) -+ { -+ if (ferror (stdin)) -+ goto closefiles; -+ break; -+ } -+ thisfield = find_field (thisline); -+ thislen = thisline->length - 1 - (thisfield - thisline->buffer); -+ match = !different (thisfield, prevfield, thislen, prevlen); -+ match_count += match; -+ -+ if (match_count == UINTMAX_MAX) -+ { -+ if (count_occurrences) -+ error (EXIT_FAILURE, 0, _("too many repeated lines")); -+ match_count--; -+ } -+ -+ if (delimit_groups != DM_NONE) -+ { -+ if (!match) -+ { -+ if (match_count) /* a previous match */ -+ first_delimiter = false; /* Only used when DM_SEPARATE */ -+ } -+ else if (match_count == 1) -+ { -+ if ((delimit_groups == DM_PREPEND) -+ || (delimit_groups == DM_SEPARATE -+ && !first_delimiter)) -+ putchar (delimiter); -+ } -+ } -+ -+ if (!match || output_later_repeated) -+ { -+ writeline (prevline, match, match_count); -+ SWAP_LINES (prevline, thisline); -+ prevfield = thisfield; -+ prevlen = thislen; -+ if (!match) -+ match_count = 0; -+ } -+ } -+ -+ writeline (prevline, false, match_count); -+ } -+ -+ closefiles: -+ if (ferror (stdin) || fclose (stdin) != 0) -+ error (EXIT_FAILURE, 0, _("error reading %s"), infile); -+ -+ /* stdout is handled via the atexit-invoked close_stdout function. */ -+ -+ free (lb1.buffer); -+ free (lb2.buffer); -+} -+ -+enum Skip_field_option_type -+ { -+ SFO_NONE, -+ SFO_OBSOLETE, -+ SFO_NEW -+ }; -+ -+int -+main (int argc, char **argv) -+{ -+ int optc = 0; -+ bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL); -+ enum Skip_field_option_type skip_field_option_type = SFO_NONE; -+ int nfiles = 0; -+ char const *file[2]; -+ char delimiter = '\n'; /* change with --zero-terminated, -z */ -+ -+ file[0] = file[1] = "-"; -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ hard_LC_COLLATE = hard_locale (LC_COLLATE); -+ -+ atexit (close_stdout); -+ -+ skip_chars = 0; -+ skip_fields = 0; -+ check_chars = SIZE_MAX; -+ output_unique = output_first_repeated = true; -+ output_later_repeated = false; -+ countmode = count_none; -+ delimit_groups = DM_NONE; -+ -+ for (;;) -+ { -+ /* Parse an operand with leading "+" as a file after "--" was -+ seen; or if pedantic and a file was seen; or if not -+ obsolete. */ -+ -+ if (optc == -1 -+ || (posixly_correct && nfiles != 0) -+ || ((optc = getopt_long (argc, argv, -+ "-0123456789Dcdf:is:uw:z", longopts, NULL)) -+ == -1)) -+ { -+ if (argc <= optind) -+ break; -+ if (nfiles == 2) -+ { -+ error (0, 0, _("extra operand %s"), quote (argv[optind])); -+ usage (EXIT_FAILURE); -+ } -+ file[nfiles++] = argv[optind++]; -+ } -+ else switch (optc) -+ { -+ case 1: -+ { -+ unsigned long int size; -+ if (optarg[0] == '+' -+ && posix2_version () < 200112 -+ && xstrtoul (optarg, NULL, 10, &size, "") == LONGINT_OK -+ && size <= SIZE_MAX) -+ skip_chars = size; -+ else if (nfiles == 2) -+ { -+ error (0, 0, _("extra operand %s"), quote (optarg)); -+ usage (EXIT_FAILURE); -+ } -+ else -+ file[nfiles++] = optarg; -+ } -+ break; -+ -+ case '0': -+ case '1': -+ case '2': -+ case '3': -+ case '4': -+ case '5': -+ case '6': -+ case '7': -+ case '8': -+ case '9': -+ { -+ if (skip_field_option_type == SFO_NEW) -+ skip_fields = 0; -+ -+ if (!DECIMAL_DIGIT_ACCUMULATE (skip_fields, optc - '0', size_t)) -+ skip_fields = SIZE_MAX; -+ -+ skip_field_option_type = SFO_OBSOLETE; -+ } -+ break; -+ -+ case 'c': -+ countmode = count_occurrences; -+ break; -+ -+ case 'd': -+ output_unique = false; -+ break; -+ -+ case 'D': -+ output_unique = false; -+ output_later_repeated = true; -+ if (optarg == NULL) -+ delimit_groups = DM_NONE; -+ else -+ delimit_groups = XARGMATCH ("--all-repeated", optarg, -+ delimit_method_string, -+ delimit_method_map); -+ break; -+ -+ case 'f': -+ skip_field_option_type = SFO_NEW; -+ skip_fields = size_opt (optarg, -+ N_("invalid number of fields to skip")); -+ break; -+ -+ case 'i': -+ ignore_case = true; -+ break; -+ -+ case 's': -+ skip_chars = size_opt (optarg, -+ N_("invalid number of bytes to skip")); -+ break; -+ -+ case 'u': -+ output_first_repeated = false; -+ break; -+ -+ case 'w': -+ check_chars = size_opt (optarg, -+ N_("invalid number of bytes to compare")); -+ break; -+ -+ case 'z': -+ delimiter = '\0'; -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (countmode == count_occurrences && output_later_repeated) -+ { -+ error (0, 0, -+ _("printing all duplicated lines and repeat counts is meaningless")); -+ usage (EXIT_FAILURE); -+ } -+ -+ check_file (file[0], file[1], delimiter); -+ -+ exit (EXIT_SUCCESS); -+} diff -urNp coreutils-8.0-orig/tests/Makefile.am coreutils-8.0/tests/Makefile.am --- coreutils-8.0-orig/tests/Makefile.am 2009-09-29 16:25:44.000000000 +0200 +++ coreutils-8.0/tests/Makefile.am 2009-10-07 10:07:16.000000000 +0200 @@ -14684,626 +3927,6 @@ diff -urNp coreutils-8.0-orig/tests/Makefile.am coreutils-8.0/tests/Makefile.am pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.0-orig/tests/Makefile.am.orig coreutils-8.0/tests/Makefile.am.orig ---- coreutils-8.0-orig/tests/Makefile.am.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/tests/Makefile.am.orig 2009-09-29 16:25:44.000000000 +0200 -@@ -0,0 +1,616 @@ -+## Process this file with automake to produce Makefile.in -*-Makefile-*-. -+ -+# Sort in traditional ASCII order, regardless of the current locale; -+# otherwise we may get into trouble with distinct strings that the -+# current locale considers to be equal. -+ASSORT = LC_ALL=C sort -+ -+EXTRA_DIST = \ -+ Coreutils.pm \ -+ CuTmpdir.pm \ -+ README \ -+ check.mk \ -+ envvar-check \ -+ lang-default \ -+ other-fs-tmpdir \ -+ require-perl \ -+ sample-test \ -+ test-lib.sh \ -+ $(pr_data) -+ -+root_tests = \ -+ chown/basic \ -+ cp/cp-a-selinux \ -+ cp/preserve-gid \ -+ cp/special-bits \ -+ cp/cp-mv-enotsup-xattr \ -+ chroot/credentials \ -+ dd/skip-seek-past-dev \ -+ install/install-C-root \ -+ ls/capability \ -+ ls/nameless-uid \ -+ misc/chcon \ -+ misc/selinux \ -+ misc/truncate-owned-by-other \ -+ mkdir/writable-under-readonly \ -+ mv/sticky-to-xpart \ -+ rm/fail-2eperm \ -+ rm/no-give-up \ -+ rm/one-file-system \ -+ tail-2/append-only \ -+ touch/now-owned-by-other -+ -+.PHONY: check-root -+check-root: -+ $(MAKE) check TESTS='$(root_tests)' -+ -+check-recursive: root-hint -+ -+# Advertise `check-root' target. -+.PHONY: root-hint -+root-hint: -+ @echo '***********************************************************' -+ @echo "NOTICE: Some tests may be run only as root." -+ @echo " See the 'Running tests as root' section in README." -+ @echo '***********************************************************' -+ -+EXTRA_DIST += $(TESTS) -+ -+# Do not choose a name that is a shell keyword like 'if', or a -+# commonly-used utility like 'cat' or 'test', as the name of a test. -+# Otherwise, VPATH builds will fail on hosts like Solaris, since they -+# will expand 'if test ...' to 'if .../test ...', and the '.../test' -+# will execute the test script rather than the standard utility. -+ -+# Notes on the ordering of these tests: -+# Place early in the list tests of the tools that -+# are most commonly used in test scripts themselves. -+# E.g., nearly every test script uses rm and chmod. -+# help-version comes early because it's a basic sanity test. -+# Put seq early, since lots of other tests use it. -+# Put tests that sleep early, but not all together, so in parallel builds -+# they share time with tests that burn CPU, not with others that sleep. -+# Put head-elide-tail early, because it's long-running. -+ -+TESTS = \ -+ misc/help-version \ -+ misc/invalid-opt \ -+ rm/ext3-perf \ -+ rm/cycle \ -+ cp/link-heap \ -+ chmod/no-x \ -+ chgrp/basic \ -+ rm/dangling-symlink \ -+ misc/ls-time \ -+ rm/deep-1 \ -+ rm/deep-2 \ -+ rm/dir-no-w \ -+ rm/dir-nonrecur \ -+ rm/dot-rel \ -+ rm/isatty \ -+ rm/empty-inacc \ -+ rm/empty-name \ -+ rm/f-1 \ -+ rm/fail-eacces \ -+ rm/fail-eperm \ -+ tail-2/assert \ -+ rm/hash \ -+ rm/i-1 \ -+ rm/i-never \ -+ rm/i-no-r \ -+ tail-2/infloop-1 \ -+ rm/ignorable \ -+ rm/inaccessible \ -+ rm/interactive-always \ -+ rm/interactive-once \ -+ rm/ir-1 \ -+ rm/r-1 \ -+ rm/r-2 \ -+ rm/r-3 \ -+ rm/r-4 \ -+ rm/readdir-bug \ -+ rm/rm1 \ -+ touch/empty-file \ -+ rm/rm2 \ -+ rm/rm3 \ -+ rm/rm4 \ -+ rm/rm5 \ -+ rm/sunos-1 \ -+ rm/unread2 \ -+ rm/unread3 \ -+ rm/unreadable \ -+ rm/v-slash \ -+ chgrp/default-no-deref \ -+ chgrp/deref \ -+ chgrp/no-x \ -+ chgrp/posix-H \ -+ chgrp/recurse \ -+ misc/ptx \ -+ misc/test \ -+ misc/seq \ -+ misc/seq-long-double \ -+ misc/head \ -+ misc/head-elide-tail \ -+ tail-2/tail-n0f \ -+ misc/ls-misc \ -+ misc/date \ -+ misc/date-next-dow \ -+ misc/ptx-overrun \ -+ misc/xstrtol \ -+ tail-2/pid \ -+ misc/od \ -+ misc/mktemp \ -+ misc/arch \ -+ misc/pr \ -+ misc/join \ -+ pr/pr-tests \ -+ misc/df-P \ -+ misc/pwd-option \ -+ misc/pwd-unreadable-parent \ -+ misc/chcon-fail \ -+ misc/cut \ -+ misc/wc \ -+ misc/wc-files0-from \ -+ misc/wc-files0 \ -+ misc/cat-proc \ -+ misc/cat-buf \ -+ misc/base64 \ -+ misc/basename \ -+ misc/close-stdout \ -+ misc/comm \ -+ misc/csplit \ -+ misc/date-sec \ -+ misc/dircolors \ -+ misc/df \ -+ misc/dirname \ -+ misc/expand \ -+ misc/expr \ -+ misc/factor \ -+ misc/false-status \ -+ misc/fmt \ -+ misc/fmt-long-line \ -+ misc/fold \ -+ misc/groups-dash \ -+ misc/groups-version \ -+ misc/head-c \ -+ misc/head-pos \ -+ misc/id-context \ -+ misc/id-groups \ -+ misc/md5sum \ -+ misc/md5sum-newline \ -+ misc/mknod \ -+ misc/nice \ -+ misc/nl \ -+ misc/nohup \ -+ misc/od-N \ -+ misc/od-multiple-t \ -+ misc/od-x8 \ -+ misc/paste \ -+ misc/pathchk1 \ -+ misc/printf \ -+ misc/printf-cov \ -+ misc/printf-hex \ -+ misc/printf-surprise \ -+ misc/pwd-long \ -+ misc/readlink-fp-loop \ -+ misc/runcon-no-reorder \ -+ misc/sha1sum \ -+ misc/sha1sum-vec \ -+ misc/sha224sum \ -+ misc/sha256sum \ -+ misc/sha384sum \ -+ misc/sha512sum \ -+ misc/shred-exact \ -+ misc/shred-passes \ -+ misc/shred-remove \ -+ misc/shuf \ -+ misc/sort \ -+ misc/sort-compress \ -+ misc/sort-continue \ -+ misc/sort-files0-from \ -+ misc/sort-merge \ -+ misc/sort-merge-fdlimit \ -+ misc/sort-rand \ -+ misc/sort-version \ -+ misc/split-a \ -+ misc/split-fail \ -+ misc/split-l \ -+ misc/stat-fmt \ -+ misc/stat-hyphen \ -+ misc/stat-printf \ -+ misc/stdbuf \ -+ misc/stty \ -+ misc/stty-invalid \ -+ misc/stty-row-col \ -+ misc/sum \ -+ misc/sum-sysv \ -+ misc/tac \ -+ misc/tac-continue \ -+ misc/tail \ -+ misc/tee \ -+ misc/tee-dash \ -+ misc/test-diag \ -+ misc/timeout \ -+ misc/timeout-parameters \ -+ misc/tr \ -+ misc/truncate-dangling-symlink \ -+ misc/truncate-dir-fail \ -+ misc/truncate-fail-diag \ -+ misc/truncate-fifo \ -+ misc/truncate-no-create-missing \ -+ misc/truncate-overflow \ -+ misc/truncate-parameters \ -+ misc/truncate-relative \ -+ misc/tsort \ -+ misc/tty-eof \ -+ misc/unexpand \ -+ misc/uniq \ -+ misc/xattr \ -+ tail-2/wait \ -+ chmod/c-option \ -+ chmod/equal-x \ -+ chmod/equals \ -+ chmod/inaccessible \ -+ chmod/octal \ -+ chmod/setgid \ -+ chmod/silent \ -+ chmod/thru-dangling \ -+ chmod/umask-x \ -+ chmod/usage \ -+ chown/deref \ -+ chown/preserve-root \ -+ chown/separator \ -+ cp/abuse \ -+ cp/acl \ -+ cp/backup-1 \ -+ cp/backup-dir \ -+ cp/backup-is-src \ -+ cp/cp-HL \ -+ cp/cp-deref \ -+ cp/cp-i \ -+ cp/cp-mv-backup \ -+ cp/cp-parents \ -+ cp/deref-slink \ -+ cp/dir-rm-dest \ -+ cp/dir-slash \ -+ cp/dir-vs-file \ -+ cp/existing-perm-race \ -+ cp/fail-perm \ -+ cp/file-perm-race \ -+ cp/into-self \ -+ cp/link \ -+ cp/link-no-deref \ -+ cp/link-preserve \ -+ cp/no-deref-link1 \ -+ cp/no-deref-link2 \ -+ cp/no-deref-link3 \ -+ cp/parent-perm \ -+ cp/parent-perm-race \ -+ cp/perm \ -+ cp/preserve-2 \ -+ cp/preserve-slink-time \ -+ cp/proc-short-read \ -+ cp/proc-zero-len \ -+ cp/r-vs-symlink \ -+ cp/reflink-auto \ -+ cp/reflink-perm \ -+ cp/same-file \ -+ cp/slink-2-slink \ -+ cp/sparse \ -+ cp/special-f \ -+ cp/src-base-dot \ -+ cp/symlink-slash \ -+ cp/thru-dangling \ -+ df/unreadable \ -+ dd/direct \ -+ dd/misc \ -+ dd/not-rewound \ -+ dd/reblock \ -+ dd/skip-seek \ -+ dd/skip-seek2 \ -+ dd/skip-seek-past-file \ -+ dd/stderr \ -+ dd/unblock \ -+ dd/unblock-sync \ -+ df/total-verify \ -+ du/2g \ -+ du/8gb \ -+ du/basic \ -+ du/deref \ -+ du/deref-args \ -+ du/exclude \ -+ du/fd-leak \ -+ du/files0-from \ -+ du/hard-link \ -+ du/inacc-dest \ -+ du/inacc-dir \ -+ du/inaccessible-cwd \ -+ du/long-from-unreadable \ -+ du/long-sloop \ -+ du/no-deref \ -+ du/no-x \ -+ du/one-file-system \ -+ du/restore-wd \ -+ du/slash \ -+ du/slink \ -+ du/trailing-slash \ -+ du/two-args \ -+ id/no-context \ -+ install/basic-1 \ -+ install/create-leading \ -+ install/d-slashdot \ -+ install/install-C \ -+ install/install-C-selinux \ -+ install/strip-program \ -+ install/trap \ -+ ln/backup-1 \ -+ ln/hard-backup \ -+ ln/hard-to-sym \ -+ ln/misc \ -+ ln/sf-1 \ -+ ln/slash-decorated-nonexistent-dest \ -+ ln/target-1 \ -+ ls/abmon-align \ -+ ls/color-clear-to-eol \ -+ ls/color-dtype-dir \ -+ ls/dangle \ -+ ls/dired \ -+ ls/file-type \ -+ ls/follow-slink \ -+ ls/infloop \ -+ ls/inode \ -+ ls/m-option \ -+ ls/multihardlink \ -+ ls/no-arg \ -+ ls/no-cap \ -+ ls/proc-selinux-segfault \ -+ ls/readdir-mountpoint-inode \ -+ ls/recursive \ -+ ls/rt-1 \ -+ ls/stat-dtype \ -+ ls/stat-failed \ -+ ls/stat-free-symlinks \ -+ ls/stat-vs-dirent \ -+ ls/symlink-slash \ -+ ls/x-option \ -+ mkdir/p-1 \ -+ mkdir/p-2 \ -+ mkdir/p-3 \ -+ mkdir/p-slashdot \ -+ mkdir/p-thru-slink \ -+ mkdir/p-v \ -+ mkdir/parents \ -+ mkdir/perm \ -+ mkdir/selinux \ -+ mkdir/special-1 \ -+ mkdir/t-slash \ -+ mv/acl \ -+ mv/atomic \ -+ mv/atomic2 \ -+ mv/backup-dir \ -+ mv/backup-is-src \ -+ mv/childproof \ -+ mv/diag \ -+ mv/dir-file \ -+ mv/dir2dir \ -+ mv/dup-source \ -+ mv/force \ -+ mv/hard-2 \ -+ mv/hard-3 \ -+ mv/hard-4 \ -+ mv/hard-link-1 \ -+ mv/hard-verbose \ -+ mv/i-1 \ -+ mv/i-2 \ -+ mv/i-3 \ -+ mv/i-4 \ -+ mv/i-5 \ -+ mv/i-link-no \ -+ mv/into-self \ -+ mv/into-self-2 \ -+ mv/into-self-3 \ -+ mv/into-self-4 \ -+ mv/leak-fd \ -+ mv/mv-n \ -+ mv/mv-special-1 \ -+ mv/no-target-dir \ -+ mv/part-fail \ -+ mv/part-hardlink \ -+ mv/part-rename \ -+ mv/part-symlink \ -+ mv/partition-perm \ -+ mv/perm-1 \ -+ mv/to-symlink \ -+ mv/trailing-slash \ -+ mv/update \ -+ readlink/can-e \ -+ readlink/can-f \ -+ readlink/can-m \ -+ readlink/rl-1 \ -+ rmdir/fail-perm \ -+ rmdir/ignore \ -+ rmdir/t-slash \ -+ tail-2/assert-2 \ -+ tail-2/big-4gb \ -+ tail-2/flush-initial \ -+ tail-2/follow-stdin \ -+ tail-2/pipe-f \ -+ tail-2/pipe-f2 \ -+ tail-2/proc-ksyms \ -+ tail-2/start-middle \ -+ touch/60-seconds \ -+ touch/dangling-symlink \ -+ touch/dir-1 \ -+ touch/fail-diag \ -+ touch/fifo \ -+ touch/no-create-missing \ -+ touch/no-rights \ -+ touch/not-owner \ -+ touch/obsolescent \ -+ touch/read-only \ -+ touch/relative \ -+ $(root_tests) -+ -+pr_data = \ -+ pr/0F \ -+ pr/0FF \ -+ pr/0FFnt \ -+ pr/0FFt \ -+ pr/0FnFnt \ -+ pr/0FnFt \ -+ pr/0Fnt \ -+ pr/0Ft \ -+ pr/2-S_f-t_notab \ -+ pr/2-Sf-t_notab \ -+ pr/2f-t_notab \ -+ pr/2s_f-t_notab \ -+ pr/2s_w60f-t_nota \ -+ pr/2sf-t_notab \ -+ pr/2sw60f-t_notab \ -+ pr/2w60f-t_notab \ -+ pr/3-0F \ -+ pr/3-5l24f-t \ -+ pr/3-FF \ -+ pr/3a2l17-FF \ -+ pr/3a3f-0F \ -+ pr/3a3l15-t \ -+ pr/3a3l15f-t \ -+ pr/3b2l17-FF \ -+ pr/3b3f-0F \ -+ pr/3b3f-0FF \ -+ pr/3b3f-FF \ -+ pr/3b3l15-t \ -+ pr/3b3l15f-t \ -+ pr/3f-0F \ -+ pr/3f-FF \ -+ pr/3l24-t \ -+ pr/3l24f-t \ -+ pr/3ml24-FF \ -+ pr/3ml24-t \ -+ pr/3ml24-t-FF \ -+ pr/3ml24f-t \ -+ pr/4-7l24-FF \ -+ pr/4l24-FF \ -+ pr/FF \ -+ pr/FFn \ -+ pr/FFtn \ -+ pr/FnFn \ -+ pr/Ja3l24f-lm \ -+ pr/Jb3l24f-lm \ -+ pr/Jml24f-lm-lo \ -+ pr/W-72l24f-ll \ -+ pr/W20l24f-ll \ -+ pr/W26l24f-ll \ -+ pr/W27l24f-ll \ -+ pr/W28l24f-ll \ -+ pr/W35Ja3l24f-lm \ -+ pr/W35Jb3l24f-lm \ -+ pr/W35Jml24f-lmlo \ -+ pr/W35a3l24f-lm \ -+ pr/W35b3l24f-lm \ -+ pr/W35ml24f-lm-lo \ -+ pr/W72Jl24f-ll \ -+ pr/a2l15-FF \ -+ pr/a2l17-FF \ -+ pr/a3-0F \ -+ pr/a3f-0F \ -+ pr/a3f-0FF \ -+ pr/a3f-FF \ -+ pr/a3l15-t \ -+ pr/a3l15f-t \ -+ pr/a3l24f-lm \ -+ pr/b2l15-FF \ -+ pr/b2l17-FF \ -+ pr/b3-0F \ -+ pr/b3f-0F \ -+ pr/b3f-0FF \ -+ pr/b3f-FF \ -+ pr/b3l15-t \ -+ pr/b3l15f-t \ -+ pr/b3l24f-lm \ -+ pr/l24-FF \ -+ pr/l24-t \ -+ pr/l24f-t \ -+ pr/loli \ -+ pr/ml20-FF-t \ -+ pr/ml24-FF \ -+ pr/ml24-t \ -+ pr/ml24-t-FF \ -+ pr/ml24f-0F \ -+ pr/ml24f-lm-lo \ -+ pr/ml24f-t \ -+ pr/ml24f-t-0F \ -+ pr/n+2-5l24f-0FF \ -+ pr/n+2l24f-0FF \ -+ pr/n+2l24f-bl \ -+ pr/n+3-7l24-FF \ -+ pr/n+3l24f-0FF \ -+ pr/n+3l24f-bl \ -+ pr/n+3ml20f-bl-FF \ -+ pr/n+3ml24f-bl-tn \ -+ pr/n+3ml24f-tn-bl \ -+ pr/n+4-8a2l17-FF \ -+ pr/n+4b2l17f-0FF \ -+ pr/n+5-8b3l17f-FF \ -+ pr/n+5a3l13f-0FF \ -+ pr/n+6a2l17-FF \ -+ pr/n+6b3l13f-FF \ -+ pr/n+7l24-FF \ -+ pr/n+8l20-FF \ -+ pr/nJml24f-lmlmlo \ -+ pr/nJml24f-lmlolm \ -+ pr/nN1+3l24f-bl \ -+ pr/nN15l24f-bl \ -+ pr/nSml20-bl-FF \ -+ pr/nSml20-t-t-FF \ -+ pr/nSml20-t-tFFFF \ -+ pr/nSml24-bl-FF \ -+ pr/nSml24-t-t-FF \ -+ pr/nSml24-t-tFFFF \ -+ pr/nl24f-bl \ -+ pr/o3Jml24f-lm-lo \ -+ pr/o3a3Sl24f-tn \ -+ pr/o3a3Snl24f-tn \ -+ pr/o3a3l24f-tn \ -+ pr/o3b3Sl24f-tn \ -+ pr/o3b3Snl24f-tn \ -+ pr/o3b3l24f-tn \ -+ pr/o3mSl24f-bl-tn \ -+ pr/o3mSnl24fbltn \ -+ pr/o3ml24f-bl-tn \ -+ pr/t-0FF \ -+ pr/t-FF \ -+ pr/t-bl \ -+ pr/t-t \ -+ pr/tFFn \ -+ pr/tFFt \ -+ pr/tFFt-bl \ -+ pr/tFFt-ll \ -+ pr/tFFt-lm \ -+ pr/tFnFt \ -+ pr/t_notab \ -+ pr/t_tab \ -+ pr/t_tab_ \ -+ pr/ta3-0FF \ -+ pr/ta3-FF \ -+ pr/tb3-0FF \ -+ pr/tb3-FF \ -+ pr/tn \ -+ pr/tn2e5o3-t_tab \ -+ pr/tn2e8-t_tab \ -+ pr/tn2e8o3-t_tab \ -+ pr/tn_2e8-t_tab \ -+ pr/tn_2e8S-t_tab \ -+ pr/tne8-t_tab \ -+ pr/tne8o3-t_tab \ -+ pr/tt-0FF \ -+ pr/tt-FF \ -+ pr/tt-bl \ -+ pr/tt-t \ -+ pr/tta3-0FF \ -+ pr/tta3-FF \ -+ pr/ttb3-0FF \ -+ pr/ttb3-FF \ -+ pr/w72l24f-ll -+ -+include $(srcdir)/check.mk diff -urNp coreutils-8.0-orig/tests/misc/cut coreutils-8.0/tests/misc/cut --- coreutils-8.0-orig/tests/misc/cut 2009-09-21 14:29:33.000000000 +0200 +++ coreutils-8.0/tests/misc/cut 2009-10-07 10:07:16.000000000 +0200 diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 2a6334f..24f7437 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -15,449 +15,6 @@ diff -urNp coreutils-8.0-orig/configure.ac coreutils-8.0/configure.ac AC_FUNC_FORK optional_bin_progs= -diff -urNp coreutils-8.0-orig/configure.ac.orig coreutils-8.0/configure.ac.orig ---- coreutils-8.0-orig/configure.ac.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/configure.ac.orig 2009-09-29 15:27:11.000000000 +0200 -@@ -0,0 +1,439 @@ -+# -*- autoconf -*- -+# Process this file with autoconf to produce a configure script. -+ -+# Copyright (C) 1991, 1993-2009 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 . -+ -+dnl Written by Jim Meyering. -+ -+AC_PREREQ([2.61]) -+ -+# Make inter-release version strings look like, e.g., v6.9-219-g58ddd, which -+# indicates that it is built from the 219th delta (in _some_ repository) -+# following the v6.9 tag, and that 58ddd is a prefix of the commit SHA1. -+AC_INIT([GNU coreutils], -+ m4_esyscmd([build-aux/git-version-gen .tarball-version]), -+ [bug-coreutils@gnu.org]) -+ -+AC_CONFIG_SRCDIR([src/ls.c]) -+ -+AC_CONFIG_AUX_DIR([build-aux]) -+AC_CONFIG_HEADERS([lib/config.h:lib/config.hin]) -+ -+AM_INIT_AUTOMAKE([1.11 dist-xz color-tests parallel-tests]) -+AM_SILENT_RULES([yes]) # make --enable-silent-rules the default. -+ -+AC_PROG_CC_STDC -+AM_PROG_CC_C_O -+AC_PROG_CPP -+AC_PROG_GCC_TRADITIONAL -+AC_PROG_RANLIB -+AC_PROG_LN_S -+gl_EARLY -+gl_INIT -+coreutils_MACROS -+ -+AC_ARG_ENABLE([gcc-warnings], -+ [AS_HELP_STRING([--enable-gcc-warnings], -+ [turn on lots of GCC warnings (for developers)])], -+ [case $enableval in -+ yes|no) ;; -+ *) AC_MSG_ERROR([bad value $enableval for gcc-warnings option]) ;; -+ esac -+ gl_gcc_warnings=$enableval], -+ [gl_gcc_warnings=no] -+) -+ -+if test "$gl_gcc_warnings" = yes; then -+ gl_WARN_ADD([-Werror], [WERROR_CFLAGS]) -+ AC_SUBST([WERROR_CFLAGS]) -+ -+ nw= -+ # This, $nw, is the list of warnings we disable. -+ nw="$nw -Wdeclaration-after-statement" # too useful to forbid -+ nw="$nw -Waggregate-return" # anachronistic -+ nw="$nw -Wlong-long" # C90 is anachronistic (lib/gethrxtime.h) -+ nw="$nw -Wc++-compat" # We don't care about C++ compilers -+ nw="$nw -Wundef" # Warns on '#if GNULIB_FOO' etc in gnulib -+ nw="$nw -Wtraditional" # Warns on #elif which we use often -+ nw="$nw -Wcast-qual" # Too many warnings for now -+ nw="$nw -Wconversion" # Too many warnings for now -+ nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings -+ nw="$nw -Wsign-conversion" # Too many warnings for now -+ nw="$nw -Wtraditional-conversion" # Too many warnings for now -+ nw="$nw -Wunreachable-code" # Too many warnings for now -+ nw="$nw -Wpadded" # Our structs are not padded -+ nw="$nw -Wredundant-decls" # openat.h declares e.g., mkdirat -+ nw="$nw -Wlogical-op" # any use of fwrite provokes this -+ nw="$nw -Wformat-nonliteral" # who.c and pinky.c strftime uses -+ nw="$nw -Wvla" # warnings in gettext.h -+ nw="$nw -Wnested-externs" # use of XARGMATCH/verify_function__ -+ nw="$nw -Wswitch-enum" # Too many warnings for now -+ nw="$nw -Wswitch-default" # Too many warnings for now -+ nw="$nw -Wstack-protector" # not worth working around -+ # things I might fix soon: -+ nw="$nw -Wfloat-equal" # sort.c, seq.c -+ nw="$nw -Wmissing-format-attribute" # copy.c -+ nw="$nw -Wunsafe-loop-optimizations" # a few src/*.c -+ nw="$nw -Winline" # system.h's readdir_ignoring_dot_and_dotdot -+ nw="$nw -Wstrict-overflow" # expr.c, pr.c, tr.c, factor.c -+ # ?? -Wstrict-overflow -+ -+ gl_MANYWARN_ALL_GCC([ws]) -+ gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw]) -+ for w in $ws; do -+ gl_WARN_ADD([$w]) -+ done -+ gl_WARN_ADD([-Wno-missing-field-initializers]) # We need this one -+ gl_WARN_ADD([-Wno-sign-compare]) # Too many warnings for now -+ gl_WARN_ADD([-Wno-pointer-sign]) # Too many warnings for now -+ gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now -+ -+ # In spite of excluding -Wlogical-op above, it is enabled, as of -+ # gcc 4.5.0 20090517, and it provokes warnings in cat.c, dd.c, truncate.c -+ gl_WARN_ADD([-Wno-logical-op]) -+ -+ gl_WARN_ADD([-fdiagnostics-show-option]) -+ -+ AC_SUBST([WARN_CFLAGS]) -+ -+ AC_DEFINE([lint], [1], [Define to 1 if the compiler is checking for lint.]) -+ AC_DEFINE([_FORTIFY_SOURCE], [2], -+ [enable compile-time and run-time bounds-checking, and some warnings]) -+ AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) -+fi -+ -+AC_FUNC_FORK -+ -+optional_bin_progs= -+AC_CHECK_FUNCS([uname], -+ gl_ADD_PROG([optional_bin_progs], [uname])) -+AC_CHECK_FUNCS([chroot], -+ gl_ADD_PROG([optional_bin_progs], [chroot])) -+AC_CHECK_FUNCS([gethostid], -+ gl_ADD_PROG([optional_bin_progs], [hostid])) -+ -+gl_WINSIZE_IN_PTEM -+ -+AC_MSG_CHECKING([whether localtime caches TZ]) -+AC_CACHE_VAL([utils_cv_localtime_cache], -+[if test x$ac_cv_func_tzset = xyes; then -+AC_RUN_IFELSE([AC_LANG_SOURCE([[#include -+#if STDC_HEADERS -+# include -+#endif -+extern char **environ; -+void unset_TZ (void) -+{ -+ char **from, **to; -+ for (to = from = environ; (*to = *from); from++) -+ if (! (to[0][0] == 'T' && to[0][1] == 'Z' && to[0][2] == '=')) -+ to++; -+} -+int main() -+{ -+ time_t now = time ((time_t *) 0); -+ int hour_GMT0, hour_unset; -+ if (putenv ("TZ=GMT0") != 0) -+ exit (1); -+ hour_GMT0 = localtime (&now)->tm_hour; -+ unset_TZ (); -+ hour_unset = localtime (&now)->tm_hour; -+ if (putenv ("TZ=PST8") != 0) -+ exit (1); -+ if (localtime (&now)->tm_hour == hour_GMT0) -+ exit (1); -+ unset_TZ (); -+ if (localtime (&now)->tm_hour != hour_unset) -+ exit (1); -+ exit (0); -+}]])], -+[utils_cv_localtime_cache=no], -+[utils_cv_localtime_cache=yes], -+[# If we have tzset, assume the worst when cross-compiling. -+utils_cv_localtime_cache=yes]) -+else -+ # If we lack tzset, report that localtime does not cache TZ, -+ # since we can't invalidate the cache if we don't have tzset. -+ utils_cv_localtime_cache=no -+fi])dnl -+AC_MSG_RESULT([$utils_cv_localtime_cache]) -+if test $utils_cv_localtime_cache = yes; then -+ AC_DEFINE([LOCALTIME_CACHE], [1], [FIXME]) -+fi -+ -+# SCO-ODT-3.0 is reported to need -los to link programs using initgroups -+AC_CHECK_FUNCS([initgroups]) -+if test $ac_cv_func_initgroups = no; then -+ AC_CHECK_LIB([os], [initgroups]) -+fi -+ -+AC_CHECK_FUNCS([syslog]) -+if test $ac_cv_func_syslog = no; then -+ # syslog is not in the default libraries. See if it's in some other. -+ for lib in bsd socket inet; do -+ AC_CHECK_LIB([$lib], [syslog], [AC_DEFINE([HAVE_SYSLOG], [1], [FIXME]) -+ LIBS="$LIBS -l$lib"; break]) -+ done -+fi -+ -+AC_CACHE_CHECK([for 3-argument setpriority function], -+ [utils_cv_func_setpriority], -+ [AC_LINK_IFELSE( -+ [AC_LANG_PROGRAM( -+ [[#include -+ #include -+ ]], -+ [[setpriority (0, 0, 0);]])], -+ [utils_cv_func_setpriority=yes], -+ [utils_cv_func_setpriority=no])]) -+if test $utils_cv_func_setpriority = no; then -+ AC_CHECK_FUNCS([nice]) -+fi -+case $utils_cv_func_setpriority,$ac_cv_func_nice in -+*yes*) -+ gl_ADD_PROG([optional_bin_progs], [nice]) -+esac -+ -+AC_DEFUN([coreutils_DUMMY_1], -+[ -+ AC_REQUIRE([gl_READUTMP]) -+ if test $ac_cv_header_utmp_h = yes || test $ac_cv_header_utmpx_h = yes; then -+ gl_ADD_PROG([optional_bin_progs], [who]) -+ gl_ADD_PROG([optional_bin_progs], [users]) -+ gl_ADD_PROG([optional_bin_progs], [pinky]) -+ fi -+]) -+coreutils_DUMMY_1 -+ -+AC_MSG_CHECKING([ut_host in struct utmp]) -+AC_CACHE_VAL([su_cv_func_ut_host_in_utmp], -+[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include -+#include ]], [[struct utmp ut; return !sizeof ut.ut_host;]])], -+ [su_cv_func_ut_host_in_utmp=yes], -+ [su_cv_func_ut_host_in_utmp=no])]) -+AC_MSG_RESULT([$su_cv_func_ut_host_in_utmp]) -+if test $su_cv_func_ut_host_in_utmp = yes; then -+ have_ut_host=1 -+ AC_DEFINE([HAVE_UT_HOST], [1], [FIXME]) -+fi -+ -+if test -z "$have_ut_host"; then -+ AC_MSG_CHECKING([ut_host in struct utmpx]) -+ AC_CACHE_VAL([su_cv_func_ut_host_in_utmpx], -+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include -+#include ]], [[struct utmpx ut; return !sizeof ut.ut_host;]])], -+ [su_cv_func_ut_host_in_utmpx=yes], -+ [su_cv_func_ut_host_in_utmpx=no])]) -+ AC_MSG_RESULT([$su_cv_func_ut_host_in_utmpx]) -+ if test $su_cv_func_ut_host_in_utmpx = yes; then -+ AC_DEFINE([HAVE_UTMPX_H], [1], [FIXME]) -+ AC_DEFINE([HAVE_UT_HOST], [1], [FIXME]) -+ fi -+fi -+ -+GNULIB_BOOT_TIME([gl_ADD_PROG([optional_bin_progs], [uptime])]) -+ -+AC_SYS_POSIX_TERMIOS() -+gl_HEADER_TIOCGWINSZ_NEEDS_SYS_IOCTL -+ -+if test $ac_cv_sys_posix_termios = yes; then -+ gl_ADD_PROG([optional_bin_progs], [stty]) -+ -+ AC_MSG_CHECKING([whether termios.h needs _XOPEN_SOURCE]) -+ AC_CACHE_VAL([su_cv_sys_termios_needs_xopen_source], -+ [AC_EGREP_CPP([yes], [#include -+#ifdef IUCLC -+yes -+#endif], su_cv_sys_termios_needs_xopen_source=no, -+ AC_EGREP_CPP([yes], [#define _XOPEN_SOURCE -+#include -+#ifdef IUCLC -+yes -+#endif], su_cv_sys_termios_needs_xopen_source=yes, -+ su_cv_sys_termios_needs_xopen_source=no))]) -+ AC_MSG_RESULT([$su_cv_sys_termios_needs_xopen_source]) -+ test $su_cv_sys_termios_needs_xopen_source = yes && -+ AC_DEFINE([TERMIOS_NEEDS_XOPEN_SOURCE], [1], [FIXME]) -+ -+ AC_MSG_CHECKING([c_line in struct termios]) -+ AC_CACHE_VAL([su_cv_sys_c_line_in_termios], -+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if TERMIOS_NEEDS_XOPEN_SOURCE -+#define _XOPEN_SOURCE -+#endif -+#include -+#include ]], [[struct termios t; return !sizeof t.c_line;]])], -+ [su_cv_sys_c_line_in_termios=yes], -+ [su_cv_sys_c_line_in_termios=no])]) -+ AC_MSG_RESULT([$su_cv_sys_c_line_in_termios]) -+ test $su_cv_sys_c_line_in_termios = yes \ -+ && AC_DEFINE([HAVE_C_LINE], [1], [FIXME]) -+fi -+ -+# FIXME: note that this macro appears above, too. -+# I'm leaving it here for now. This whole thing needs to be modernized... -+gl_WINSIZE_IN_PTEM -+ -+gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H -+ -+if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ -+ test $gl_cv_sys_tiocgwinsz_needs_sys_ioctl_h = no; then -+ AC_MSG_CHECKING([TIOCGWINSZ in sys/pty.h]) -+ AC_CACHE_VAL([su_cv_sys_tiocgwinsz_in_sys_pty_h], -+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include -+#ifdef WINSIZE_IN_PTEM -+# include -+# include -+#endif -+#include -+#include -+#include ]], [[int x = TIOCGWINSZ;]])], -+ [su_cv_sys_tiocgwinsz_in_sys_pty_h=yes], -+ [su_cv_sys_tiocgwinsz_in_sys_pty_h=no])]) -+ AC_MSG_RESULT([$su_cv_sys_tiocgwinsz_in_sys_pty_h]) -+ -+ test $su_cv_sys_tiocgwinsz_in_sys_pty_h = yes \ -+ && AC_DEFINE([GWINSZ_IN_SYS_PTY], [1], -+ [Define if your system defines TIOCGWINSZ in sys/pty.h.]) -+fi -+ -+# For src/kill.c. -+AC_CHECK_DECLS([strsignal, sys_siglist, _sys_siglist, __sys_siglist], , , -+ [AC_INCLUDES_DEFAULT -+#include ]) -+ -+cu_LIB_CHECK -+cu_GMP -+ -+# Build df only if there's a point to it. -+if test $gl_cv_list_mounted_fs = yes && test $gl_cv_fs_space = yes; then -+ gl_ADD_PROG([optional_bin_progs], [df]) -+fi -+ -+# Limit stdbuf to ELF systems with GCC -+optional_pkglib_progs= -+AC_MSG_CHECKING([whether this is an ELF system]) -+AC_EGREP_CPP([yes], [#if __ELF__ -+yes -+#endif], [elf_sys=yes], [elf_sys=no]) -+AC_MSG_RESULT([$elf_sys]) -+if test "$elf_sys" = "yes" && \ -+ test "$GCC" = "yes"; then -+ gl_ADD_PROG([optional_bin_progs], [stdbuf]) -+ gl_ADD_PROG([optional_pkglib_progs], [libstdbuf.so]) -+fi -+ -+############################################################################ -+mk="$srcdir/src/Makefile.am" -+# Extract all literal names from the definition of $(EXTRA_PROGRAMS) -+# in $mk but don't expand the variable references. -+# Append each literal name to $optional_bin_progs. -+v=EXTRA_PROGRAMS -+for gl_i in `sed -n '/^'$v' =/,/[[^\]]$/p' $mk \ -+ | sed 's/^ *//;/^\$.*/d;/^'$v' =/d' \ -+ | tr -s '\\015\\012\\\\' ' '`; do -+ gl_ADD_PROG([optional_bin_progs], $gl_i) -+done -+ -+# As above, extract literal names from the definition of $(no_install__progs) -+# in $mk but don't expand the variable references. -+v=no_install__progs -+t=`sed -n '/^'$v' =/,/[[^\]]$/p' $mk \ -+ | sed 's/^ *//;/^\$.*/d;/^'$v' =/d' \ -+ | tr -s '\\015\\012\\\\' ' '` -+# Remove any trailing space. -+no_install_progs_default=`echo "$t"|sed 's/ $//'` -+ -+# Unfortunately, due to the way autoconf's AS_HELP_STRING works, the list -+# of default-not-installed programs, "arch hostname su", must appear in two -+# places: in this file below, and in $mk. Using "$no_install_progs_default" -+# below cannot work. And we can't substitute the names into $mk because -+# automake needs the literals, too. -+# The compromise is to ensure that the space-separated list extracted -+# above matches the literal 2nd argument below. -+c="$srcdir/configure.ac" -+re='^g''l_INCLUDE_EXCLUDE_PROG(.* [\[\(.*\)\]])' -+t=`sed -n '/'"$re"'/{s/'"$re"'/\1/;s/,/ /gp -+}' $c` -+case $t in -+ $no_install_progs_default) ;; -+ *) AC_MSG_ERROR([[internal error: g'l_INCLUDE_EXCLUDE_PROG's 2nd arg, $t, -+ does not match the list of default-not-installed programs -+ ($no_install_progs_default) also recorded in $mk]], -+ 1) ;; -+esac -+ -+# Given the name of a variable containing a space-separated list of -+# install-by-default programs and the actual list do-not-install-by-default -+# programs, modify the former variable to reflect any "do-install" and -+# "don't-install" requests. -+# I.e., add any program name specified via --enable-install-program=..., and -+# remove any program name specified via --enable-no-install-program=... -+# Note how the second argument below is a literal, with "," separators. -+# That is required due to the way the macro works, and since the -+# corresponding ./configure option argument is comma-separated on input. -+gl_INCLUDE_EXCLUDE_PROG([optional_bin_progs], [arch,hostname,su]) -+ -+# Set INSTALL_SU if su installation has been requested via -+# --enable-install-program=su. -+AC_SUBST([INSTALL_SU]) -+case " $optional_bin_progs " in -+ *' su '*) INSTALL_SU=yes ;; -+ *) INSTALL_SU=no ;; -+esac -+ -+MAN=`echo "$optional_bin_progs "|sed 's/ /.1 /g;s/ $//'|tr -d '\\015\\012'` -+ -+# Change ginstall.1 to "install.h" in $MAN. -+MAN=`for m in $MAN; do test $m = ginstall.1 && m=install.1; echo $m; done \ -+ | tr '\015\012' ' '; echo` -+ -+# Remove [.1, since writing a portable rule for it in man/Makefile.am -+# is not practical. The sed LHS below uses the autoconf quadrigraph -+# representing '['. -+MAN=`echo "$MAN"|sed 's/\@<:@\.1//'` -+ -+OPTIONAL_BIN_PROGS=`echo "$optional_bin_progs "|sed 's/ /\$(EXEEXT) /g;s/ $//'` -+AC_SUBST([OPTIONAL_BIN_PROGS]) -+OPTIONAL_PKGLIB_PROGS=`echo "$optional_pkglib_progs " | sed 's/ $//'` -+AC_SUBST([OPTIONAL_PKGLIB_PROGS]) -+NO_INSTALL_PROGS_DEFAULT=$no_install_progs_default -+AC_SUBST([NO_INSTALL_PROGS_DEFAULT]) -+ -+AM_CONDITIONAL([CROSS_COMPILING], [test "$cross_compiling" = yes]) -+ -+# Arrange to rerun configure whenever the file, src/Makefile.am, -+# containing the list of program names changes. -+CONFIG_STATUS_DEPENDENCIES='$(top_srcdir)/src/Makefile.am' -+AC_SUBST([CONFIG_STATUS_DEPENDENCIES]) -+############################################################################ -+ -+AM_GNU_GETTEXT([external], [need-formatstring-macros]) -+AM_GNU_GETTEXT_VERSION([0.15]) -+ -+# For a test of uniq: it uses the $LOCALE_FR envvar. -+gt_LOCALE_FR -+ -+AC_CONFIG_FILES( -+ Makefile -+ doc/Makefile -+ lib/Makefile -+ man/Makefile -+ po/Makefile.in -+ src/Makefile -+ tests/Makefile -+ gnulib-tests/Makefile -+ ) -+AC_OUTPUT diff -urNp coreutils-8.0-orig/doc/coreutils.texi coreutils-8.0/doc/coreutils.texi --- coreutils-8.0-orig/doc/coreutils.texi 2009-09-29 15:27:54.000000000 +0200 +++ coreutils-8.0/doc/coreutils.texi 2009-10-07 10:04:27.000000000 +0200 @@ -518,15845 +75,6 @@ diff -urNp coreutils-8.0-orig/doc/coreutils.texi coreutils-8.0/doc/coreutils.tex @node timeout invocation @section @command{timeout}: Run a command with a time limit -diff -urNp coreutils-8.0-orig/doc/coreutils.texi.orig coreutils-8.0/doc/coreutils.texi.orig ---- coreutils-8.0-orig/doc/coreutils.texi.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/doc/coreutils.texi.orig 2009-09-29 15:27:54.000000000 +0200 -@@ -0,0 +1,15835 @@ -+\input texinfo -+@c %**start of header -+@setfilename coreutils.info -+@settitle @sc{gnu} Coreutils -+ -+@c %**end of header -+ -+@include version.texi -+@include constants.texi -+ -+@c Define new indices. -+@defcodeindex op -+@defcodeindex fl -+ -+@c Put everything in one index (arbitrarily chosen to be the concept index). -+@syncodeindex fl cp -+@syncodeindex fn cp -+@syncodeindex ky cp -+@syncodeindex op cp -+@syncodeindex pg cp -+@syncodeindex vr cp -+ -+@dircategory Basics -+@direntry -+* Coreutils: (coreutils). Core GNU (file, text, shell) utilities. -+* Common options: (coreutils)Common options. Common options. -+* File permissions: (coreutils)File permissions. Access modes. -+* Date input formats: (coreutils)Date input formats. -+@end direntry -+ -+@c FIXME: the following need documentation -+@c * [: (coreutils)[ invocation. File/string tests. -+@c * pinky: (coreutils)pinky invocation. FIXME. -+@c * mktemp: (coreutils)mktemp invocation. FIXME. -+ -+@dircategory Individual utilities -+@direntry -+* arch: (coreutils)arch invocation. Print machine hardware name. -+* base64: (coreutils)base64 invocation. Base64 encode/decode data. -+* basename: (coreutils)basename invocation. Strip directory and suffix. -+* cat: (coreutils)cat invocation. Concatenate and write files. -+* chcon: (coreutils)chcon invocation. Change SELinux CTX of files. -+* chgrp: (coreutils)chgrp invocation. Change file groups. -+* chmod: (coreutils)chmod invocation. Change file permissions. -+* chown: (coreutils)chown invocation. Change file owners/groups. -+* chroot: (coreutils)chroot invocation. Specify the root directory. -+* cksum: (coreutils)cksum invocation. Print POSIX CRC checksum. -+* comm: (coreutils)comm invocation. Compare sorted files by line. -+* cp: (coreutils)cp invocation. Copy files. -+* csplit: (coreutils)csplit invocation. Split by context. -+* cut: (coreutils)cut invocation. Print selected parts of lines. -+* date: (coreutils)date invocation. Print/set system date and time. -+* dd: (coreutils)dd invocation. Copy and convert a file. -+* df: (coreutils)df invocation. Report file system disk usage. -+* dir: (coreutils)dir invocation. List directories briefly. -+* dircolors: (coreutils)dircolors invocation. Color setup for ls. -+* dirname: (coreutils)dirname invocation. Strip non-directory suffix. -+* du: (coreutils)du invocation. Report on disk usage. -+* echo: (coreutils)echo invocation. Print a line of text. -+* env: (coreutils)env invocation. Modify the environment. -+* expand: (coreutils)expand invocation. Convert tabs to spaces. -+* expr: (coreutils)expr invocation. Evaluate expressions. -+* factor: (coreutils)factor invocation. Print prime factors -+* false: (coreutils)false invocation. Do nothing, unsuccessfully. -+* fmt: (coreutils)fmt invocation. Reformat paragraph text. -+* fold: (coreutils)fold invocation. Wrap long input lines. -+* 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 and change 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. -+* ls: (coreutils)ls invocation. List directory contents. -+* md5sum: (coreutils)md5sum invocation. Print or check MD5 digests. -+* mkdir: (coreutils)mkdir invocation. Create directories. -+* mkfifo: (coreutils)mkfifo invocation. Create FIFOs (named pipes). -+* mknod: (coreutils)mknod invocation. Create special files. -+* mv: (coreutils)mv invocation. Rename files. -+* nice: (coreutils)nice invocation. Modify niceness. -+* nl: (coreutils)nl invocation. Number lines and write files. -+* nohup: (coreutils)nohup invocation. Immunize to hangups. -+* od: (coreutils)od invocation. Dump files in octal, etc. -+* paste: (coreutils)paste invocation. Merge lines of files. -+* pathchk: (coreutils)pathchk invocation. Check file name portability. -+* pr: (coreutils)pr invocation. Paginate or columnate files. -+* printenv: (coreutils)printenv invocation. Print environment variables. -+* printf: (coreutils)printf invocation. Format and print data. -+* ptx: (coreutils)ptx invocation. Produce permuted indexes. -+* pwd: (coreutils)pwd invocation. Print working directory. -+* readlink: (coreutils)readlink invocation. Print referent of a symlink. -+* rm: (coreutils)rm invocation. Remove files. -+* rmdir: (coreutils)rmdir invocation. Remove empty directories. -+* runcon: (coreutils)runcon invocation. Run in specified SELinux CTX. -+* seq: (coreutils)seq invocation. Print numeric sequences -+* sha1sum: (coreutils)sha1sum invocation. Print or check SHA-1 digests. -+* sha2: (coreutils)sha2 utilities. Print or check SHA-2 digests. -+* shred: (coreutils)shred invocation. Remove files more securely. -+* shuf: (coreutils)shuf invocation. Shuffling text files. -+* sleep: (coreutils)sleep invocation. Delay for a specified time. -+* sort: (coreutils)sort invocation. Sort text files. -+* split: (coreutils)split invocation. Split into fixed-size pieces. -+* stat: (coreutils)stat invocation. Report file(system) status. -+* stdbuf: (coreutils)stdbuf invocation. Modify stdio buffering. -+* stty: (coreutils)stty invocation. Print/change terminal settings. -+* su: (coreutils)su invocation. Modify user and group ID. -+* sum: (coreutils)sum invocation. Print traditional checksum. -+* sync: (coreutils)sync invocation. Synchronize memory and disk. -+* tac: (coreutils)tac invocation. Reverse files. -+* tail: (coreutils)tail invocation. Output the last part of files. -+* tee: (coreutils)tee invocation. Redirect to multiple files. -+* test: (coreutils)test invocation. File/string tests. -+* timeout: (coreutils)timeout invocation. Run with time limit. -+* touch: (coreutils)touch invocation. Change file timestamps. -+* tr: (coreutils)tr invocation. Translate characters. -+* true: (coreutils)true invocation. Do nothing, successfully. -+* truncate: (coreutils)truncate invocation. Shrink/extend size of a file. -+* tsort: (coreutils)tsort invocation. Topological sort. -+* tty: (coreutils)tty invocation. Print terminal name. -+* uname: (coreutils)uname invocation. Print system information. -+* unexpand: (coreutils)unexpand invocation. Convert spaces to tabs. -+* uniq: (coreutils)uniq invocation. Uniquify files. -+* unlink: (coreutils)unlink invocation. Removal via unlink(2). -+* uptime: (coreutils)uptime invocation. Print uptime and load. -+* users: (coreutils)users invocation. Print current user names. -+* vdir: (coreutils)vdir invocation. List directories verbosely. -+* wc: (coreutils)wc invocation. Line, word, and byte counts. -+* who: (coreutils)who invocation. Print who is logged in. -+* whoami: (coreutils)whoami invocation. Print effective user ID. -+* yes: (coreutils)yes invocation. Print a string indefinitely. -+@end direntry -+ -+@copying -+This manual documents version @value{VERSION} of the @sc{gnu} core -+utilities, including the standard programs for text and file manipulation. -+ -+Copyright @copyright{} 1994-1996, 2000-2009 Free Software Foundation, Inc. -+ -+@quotation -+Permission is granted to copy, distribute and/or modify this document -+under the terms of the GNU Free Documentation License, Version 1.3 or -+any later version published by the Free Software Foundation; with no -+Invariant Sections, with no Front-Cover Texts, and with no Back-Cover -+Texts. A copy of the license is included in the section entitled ``GNU -+Free Documentation License''. -+@end quotation -+@end copying -+ -+@titlepage -+@title @sc{gnu} @code{Coreutils} -+@subtitle Core GNU utilities -+@subtitle for version @value{VERSION}, @value{UPDATED} -+@author David MacKenzie et al. -+ -+@page -+@vskip 0pt plus 1filll -+@insertcopying -+@end titlepage -+@shortcontents -+@contents -+ -+@ifnottex -+@node Top -+@top GNU Coreutils -+ -+@insertcopying -+@end ifnottex -+ -+@cindex core utilities -+@cindex text utilities -+@cindex shell utilities -+@cindex file utilities -+ -+@menu -+* Introduction:: Caveats, overview, and authors -+* Common options:: Common options -+* Output of entire files:: cat tac nl od base64 -+* Formatting file contents:: fmt pr fold -+* Output of parts of files:: head tail split csplit -+* Summarizing files:: wc sum cksum md5sum sha1sum sha2 -+* Operating on sorted files:: sort shuf uniq comm ptx tsort -+* Operating on fields:: cut paste join -+* Operating on characters:: tr expand unexpand -+* Directory listing:: ls dir vdir dircolors -+* Basic operations:: cp dd install mv rm shred -+* Special file types:: mkdir rmdir unlink mkfifo mknod ln link readlink -+* Changing file attributes:: chgrp chmod chown touch -+* Disk usage:: df du stat sync truncate -+* Printing text:: echo printf yes -+* Conditions:: false true test expr -+* Redirection:: tee -+* File name manipulation:: dirname basename pathchk -+* Working context:: pwd stty printenv tty -+* User information:: id logname whoami groups users who -+* System context:: date arch uname hostname hostid uptime -+* SELinux context:: chcon runcon -+* Modified command invocation:: chroot env nice nohup stdbuf su timeout -+* Process control:: kill -+* Delaying:: sleep -+* Numeric operations:: factor seq -+* File permissions:: Access modes -+* Date input formats:: Specifying date strings -+* Opening the software toolbox:: The software tools philosophy -+* GNU Free Documentation License:: Copying and sharing this manual -+* Concept index:: General index -+ -+@detailmenu -+ --- The Detailed Node Listing --- -+ -+Common Options -+ -+* Exit status:: Indicating program success or failure -+* Backup options:: Backup options -+* Block size:: Block size -+* Signal specifications:: Specifying signals -+* Disambiguating names and IDs:: chgrp and chown owner and group syntax -+* Random sources:: Sources of random data -+* Target directory:: Target directory -+* Trailing slashes:: Trailing slashes -+* Traversing symlinks:: Traversing symlinks to directories -+* Treating / specially:: Treating / specially -+* Standards conformance:: Standards conformance -+ -+Output of entire files -+ -+* cat invocation:: Concatenate and write files -+* tac invocation:: Concatenate and write files in reverse -+* nl invocation:: Number lines and write files -+* od invocation:: Write files in octal or other formats -+* base64 invocation:: Transform data into printable data -+ -+Formatting file contents -+ -+* fmt invocation:: Reformat paragraph text -+* pr invocation:: Paginate or columnate files for printing -+* fold invocation:: Wrap input lines to fit in specified width -+ -+Output of parts of files -+ -+* head invocation:: Output the first part of files -+* tail invocation:: Output the last part of files -+* split invocation:: Split a file into fixed-size pieces -+* csplit invocation:: Split a file into context-determined pieces -+ -+Summarizing files -+ -+* wc invocation:: Print newline, word, and byte counts -+* sum invocation:: Print checksum and block counts -+* cksum invocation:: Print CRC checksum and byte counts -+* md5sum invocation:: Print or check MD5 digests -+* sha1sum invocation:: Print or check SHA-1 digests -+* sha2 utilities:: Print or check SHA-2 digests -+ -+Operating on sorted files -+ -+* sort invocation:: Sort text files -+* shuf invocation:: Shuffle text files -+* uniq invocation:: Uniquify files -+* comm invocation:: Compare two sorted files line by line -+* ptx invocation:: Produce a permuted index of file contents -+* tsort invocation:: Topological sort -+ -+@command{ptx}: Produce permuted indexes -+ -+* General options in ptx:: Options which affect general program behavior -+* Charset selection in ptx:: Underlying character set considerations -+* Input processing in ptx:: Input fields, contexts, and keyword selection -+* Output formatting in ptx:: Types of output format, and sizing the fields -+* Compatibility in ptx:: The @acronym{GNU} extensions to @command{ptx} -+ -+Operating on fields -+ -+* cut invocation:: Print selected parts of lines -+* paste invocation:: Merge lines of files -+* join invocation:: Join lines on a common field -+ -+Operating on characters -+ -+* tr invocation:: Translate, squeeze, and/or delete characters -+* expand invocation:: Convert tabs to spaces -+* unexpand invocation:: Convert spaces to tabs -+ -+@command{tr}: Translate, squeeze, and/or delete characters -+ -+* Character sets:: Specifying sets of characters -+* Translating:: Changing one set of characters to another -+* Squeezing:: Squeezing repeats and deleting -+ -+Directory listing -+ -+* ls invocation:: List directory contents -+* dir invocation:: Briefly list directory contents -+* vdir invocation:: Verbosely list directory contents -+* dircolors invocation:: Color setup for @command{ls} -+ -+@command{ls}: List directory contents -+ -+* Which files are listed:: Which files are listed -+* What information is listed:: What information is listed -+* Sorting the output:: Sorting the output -+* Details about version sort:: More details about version sort -+* General output formatting:: General output formatting -+* Formatting the file names:: Formatting the file names -+ -+Basic operations -+ -+* cp invocation:: Copy files and directories -+* dd invocation:: Convert and copy a file -+* install invocation:: Copy files and set attributes -+* mv invocation:: Move (rename) files -+* rm invocation:: Remove files or directories -+* shred invocation:: Remove files more securely -+ -+Special file types -+ -+* link invocation:: Make a hard link via the link syscall -+* ln invocation:: Make links between files -+* mkdir invocation:: Make directories -+* mkfifo invocation:: Make FIFOs (named pipes) -+* mknod invocation:: Make block or character special files -+* readlink invocation:: Print value of a symlink or canonical file name -+* rmdir invocation:: Remove empty directories -+* unlink invocation:: Remove files via unlink syscall -+ -+Changing file attributes -+ -+* chown invocation:: Change file owner and group -+* chgrp invocation:: Change group ownership -+* chmod invocation:: Change access permissions -+* touch invocation:: Change file timestamps -+ -+Disk usage -+ -+* df invocation:: Report file system disk space usage -+* du invocation:: Estimate file space usage -+* stat invocation:: Report file or file system status -+* sync invocation:: Synchronize data on disk with memory -+* truncate invocation:: Shrink or extend the size of a file -+ -+Printing text -+ -+* echo invocation:: Print a line of text -+* printf invocation:: Format and print data -+* yes invocation:: Print a string until interrupted -+ -+Conditions -+ -+* false invocation:: Do nothing, unsuccessfully -+* true invocation:: Do nothing, successfully -+* test invocation:: Check file types and compare values -+* expr invocation:: Evaluate expressions -+ -+@command{test}: Check file types and compare values -+ -+* File type tests:: File type tests -+* Access permission tests:: Access permission tests -+* File characteristic tests:: File characteristic tests -+* String tests:: String tests -+* Numeric tests:: Numeric tests -+ -+@command{expr}: Evaluate expression -+ -+* String expressions:: + : match substr index length -+* Numeric expressions:: + - * / % -+* Relations for expr:: | & < <= = == != >= > -+* Examples of expr:: Examples of using @command{expr} -+ -+Redirection -+ -+* tee invocation:: Redirect output to multiple files or processes -+ -+File name manipulation -+ -+* basename invocation:: Strip directory and suffix from a file name -+* dirname invocation:: Strip non-directory suffix from a file name -+* pathchk invocation:: Check file name validity and portability -+ -+Working context -+ -+* pwd invocation:: Print working directory -+* stty invocation:: Print or change terminal characteristics -+* printenv invocation:: Print all or some environment variables -+* tty invocation:: Print file name of terminal on standard input -+ -+@command{stty}: Print or change terminal characteristics -+ -+* Control:: Control settings -+* Input:: Input settings -+* Output:: Output settings -+* Local:: Local settings -+* Combination:: Combination settings -+* Characters:: Special characters -+* Special:: Special settings -+ -+User information -+ -+* id invocation:: Print user identity -+* logname invocation:: Print current login name -+* whoami invocation:: Print effective user ID -+* groups invocation:: Print group names a user is in -+* users invocation:: Print login names of users currently logged in -+* who invocation:: Print who is currently logged in -+ -+System context -+ -+* arch invocation:: Print machine hardware name -+* date invocation:: Print or set system date and time -+* 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 -+ -+@command{date}: Print or set system date and time -+ -+* Time conversion specifiers:: %[HIklMNpPrRsSTXzZ] -+* Date conversion specifiers:: %[aAbBcCdDeFgGhjmuUVwWxyY] -+* Literal conversion specifiers:: %[%nt] -+* Padding and other flags:: Pad with zeros, spaces, etc. -+* Setting the time:: Changing the system clock -+* Options for date:: Instead of the current time -+* Date input formats:: Specifying date strings -+* Examples of date:: Examples -+ -+SELinux context -+ -+* chcon invocation:: Change SELinux context of file -+* runcon invocation:: Run a command in specified SELinux context -+ -+Modified command invocation -+ -+* chroot invocation:: Run a command with a different root directory -+* env invocation:: Run a command in a modified environment -+* nice invocation:: Run a command with modified niceness -+* nohup invocation:: Run a command immune to hangups -+* stdbuf invocation:: Run a command with modified I/O buffering -+* su invocation:: Run a command with substitute user and group ID -+* 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 -+ -+Numeric operations -+ -+* factor invocation:: Print prime factors -+* seq invocation:: Print numeric sequences -+ -+File permissions -+ -+* Mode Structure:: Structure of file mode bits -+* Symbolic Modes:: Mnemonic representation of file mode bits -+* Numeric Modes:: File mode bits as octal numbers -+* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories -+ -+Date input formats -+ -+* General date syntax:: Common rules -+* Calendar date items:: 19 Dec 1994 -+* Time of day items:: 9:20pm -+* Time zone items:: @sc{est}, @sc{pdt}, @sc{gmt} -+* Day of week items:: Monday and others -+* Relative items in date strings:: next tuesday, 2 years ago -+* Pure numbers in date strings:: 19931219, 1440 -+* Seconds since the Epoch:: @@1078100502 -+* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0" -+* Authors of get_date:: Bellovin, Eggert, Salz, Berets, et al -+ -+Opening the software toolbox -+ -+* Toolbox introduction:: Toolbox introduction -+* I/O redirection:: I/O redirection -+* The who command:: The @command{who} command -+* The cut command:: The @command{cut} command -+* The sort command:: The @command{sort} command -+* The uniq command:: The @command{uniq} command -+* Putting the tools together:: Putting the tools together -+ -+Copying This Manual -+ -+* GNU Free Documentation License:: Copying and sharing this manual -+ -+@end detailmenu -+@end menu -+ -+ -+@node Introduction -+@chapter Introduction -+ -+This manual is a work in progress: many sections make no attempt to explain -+basic concepts in a way suitable for novices. Thus, if you are interested, -+please get involved in improving this manual. The entire @sc{gnu} community -+will benefit. -+ -+@cindex @acronym{POSIX} -+The @sc{gnu} utilities documented here are mostly compatible with the -+@acronym{POSIX} standard. -+@cindex bugs, reporting -+Please report bugs to @email{bug-coreutils@@gnu.org}. Remember -+to include the version number, machine architecture, input files, and -+any other information needed to reproduce the bug: your input, what you -+expected, what you got, and why it is wrong. Diffs are welcome, but -+please include a description of the problem as well, since this is -+sometimes difficult to infer. @xref{Bugs, , , gcc, Using and Porting GNU CC}. -+ -+@cindex Berry, K. -+@cindex Paterson, R. -+@cindex Stallman, R. -+@cindex Pinard, F. -+@cindex MacKenzie, D. -+@cindex Meyering, J. -+@cindex Youmans, B. -+This manual was originally derived from the Unix man pages in the -+distributions, which were written by David MacKenzie and updated by Jim -+Meyering. What you are reading now is the authoritative documentation -+for these utilities; the man pages are no longer being maintained. The -+original @command{fmt} man page was written by Ross Paterson. Fran@,{c}ois -+Pinard did the initial conversion to Texinfo format. Karl Berry did the -+indexing, some reorganization, and editing of the results. Brian -+Youmans of the Free Software Foundation office staff combined the -+manuals for textutils, fileutils, and sh-utils to produce the present -+omnibus manual. Richard Stallman contributed his usual invaluable -+insights to the overall process. -+ -+@node Common options -+@chapter Common options -+ -+@macro optBackup -+@item -b -+@itemx @w{@kbd{--backup}[=@var{method}]} -+@opindex -b -+@opindex --backup -+@vindex VERSION_CONTROL -+@cindex backups, making -+@xref{Backup options}. -+Make a backup of each file that would otherwise be overwritten or removed. -+@end macro -+ -+@macro optBackupSuffix -+@item -S @var{suffix} -+@itemx --suffix=@var{suffix} -+@opindex -S -+@opindex --suffix -+Append @var{suffix} to each backup file made with @option{-b}. -+@xref{Backup options}. -+@end macro -+ -+@macro optTargetDirectory -+@item -t @var{directory} -+@itemx @w{@kbd{--target-directory}=@var{directory}} -+@opindex -t -+@opindex --target-directory -+@cindex target directory -+@cindex destination directory -+Specify the destination @var{directory}. -+@xref{Target directory}. -+@end macro -+ -+@macro optNoTargetDirectory -+@item -T -+@itemx --no-target-directory -+@opindex -T -+@opindex --no-target-directory -+@cindex target directory -+@cindex destination directory -+Do not treat the last operand specially when it is a directory or a -+symbolic link to a directory. @xref{Target directory}. -+@end macro -+ -+@macro optSi -+@itemx --si -+@opindex --si -+@cindex SI output -+Append an SI-style abbreviation to each size, such as @samp{M} for -+megabytes. Powers of 1000 are used, not 1024; @samp{M} stands for -+1,000,000 bytes. This option is equivalent to -+@option{--block-size=si}. Use the @option{-h} or -+@option{--human-readable} option if -+you prefer powers of 1024. -+@end macro -+ -+@macro optHumanReadable -+@item -h -+@itemx --human-readable -+@opindex -h -+@opindex --human-readable -+@cindex human-readable output -+Append a size letter to each size, such as @samp{M} for mebibytes. -+Powers of 1024 are used, not 1000; @samp{M} stands for 1,048,576 bytes. -+This option is equivalent to @option{--block-size=human-readable}. -+Use the @option{--si} option if you prefer powers of 1000. -+@end macro -+ -+@macro optStripTrailingSlashes -+@itemx @w{@kbd{--strip-trailing-slashes}} -+@opindex --strip-trailing-slashes -+@cindex stripping trailing slashes -+Remove any trailing slashes from each @var{source} argument. -+@xref{Trailing slashes}. -+@end macro -+ -+@macro mayConflictWithShellBuiltIn{cmd} -+@cindex conflicts with shell built-ins -+@cindex built-in shell commands, conflicts with -+Due to shell aliases and built-in @command{\cmd\} command, using an -+unadorned @command{\cmd\} interactively or in a script may get you -+different functionality than that described here. Invoke it via -+@command{env} (i.e., @code{env \cmd\ @dots{}}) to avoid interference -+from the shell. -+ -+@end macro -+ -+@macro multiplierSuffixes{varName} -+@var{\varName\} may be, or may be an integer optionally followed by, -+one of the following multiplicative suffixes: -+@example -+@samp{b} => 512 ("blocks") -+@samp{KB} => 1000 (KiloBytes) -+@samp{K} => 1024 (KibiBytes) -+@samp{MB} => 1000*1000 (MegaBytes) -+@samp{M} => 1024*1024 (MebiBytes) -+@samp{GB} => 1000*1000*1000 (GigaBytes) -+@samp{G} => 1024*1024*1024 (GibiBytes) -+@end example -+and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}. -+@end macro -+ -+@c FIXME: same as above, but no ``blocks'' line. -+@macro multiplierSuffixesNoBlocks{varName} -+@var{\varName\} may be, or may be an integer optionally followed by, -+one of the following multiplicative suffixes: -+@example -+@samp{KB} => 1000 (KiloBytes) -+@samp{K} => 1024 (KibiBytes) -+@samp{MB} => 1000*1000 (MegaBytes) -+@samp{M} => 1024*1024 (MebiBytes) -+@samp{GB} => 1000*1000*1000 (GigaBytes) -+@samp{G} => 1024*1024*1024 (GibiBytes) -+@end example -+and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}. -+@end macro -+ -+@cindex common options -+ -+Certain options are available in all of these programs. Rather than -+writing identical descriptions for each of the programs, they are -+described here. (In fact, every @sc{gnu} program accepts (or should accept) -+these options.) -+ -+@vindex POSIXLY_CORRECT -+Normally options and operands can appear in any order, and programs act -+as if all the options appear before any operands. For example, -+@samp{sort -r passwd -t :} acts like @samp{sort -r -t : passwd}, since -+@samp{:} is an option-argument of @option{-t}. However, if the -+@env{POSIXLY_CORRECT} environment variable is set, options must appear -+before operands, unless otherwise specified for a particular command. -+ -+A few programs can usefully have trailing operands with leading -+@samp{-}. With such a program, options must precede operands even if -+@env{POSIXLY_CORRECT} is not set, and this fact is noted in the -+program description. For example, the @command{env} command's options -+must appear before its operands, since in some cases the operands -+specify a command that itself contains options. -+ -+Most programs that accept long options recognize unambiguous -+abbreviations of those options. For example, @samp{rmdir -+--ignore-fail-on-non-empty} can be invoked as @samp{rmdir -+--ignore-fail} or even @samp{rmdir --i}. Ambiguous options, such as -+@samp{ls --h}, are identified as such. -+ -+Some of these programs recognize the @option{--help} and @option{--version} -+options only when one of them is the sole command line argument. For -+these programs, abbreviations of the long options are not always recognized. -+ -+@table @samp -+ -+@item --help -+@opindex --help -+@cindex help, online -+Print a usage message listing all available options, then exit successfully. -+ -+@item --version -+@opindex --version -+@cindex version number, finding -+Print the version number, then exit successfully. -+ -+@item -- -+@opindex -- -+@cindex option delimiter -+Delimit the option list. Later arguments, if any, are treated as -+operands even if they begin with @samp{-}. For example, @samp{sort -- -+-r} reads from the file named @file{-r}. -+ -+@end table -+ -+@cindex standard input -+@cindex standard output -+A single @samp{-} operand is not really an option, though it looks like one. It -+stands for standard input, or for standard output if that is clear from -+the context. For example, @samp{sort -} reads from standard input, -+and is equivalent to plain @samp{sort}, and @samp{tee -} writes an -+extra copy of its input to standard output. Unless otherwise -+specified, @samp{-} can appear as any operand that requires a file -+name. -+ -+@menu -+* Exit status:: Indicating program success or failure. -+* Backup options:: -b -S, in some programs. -+* Block size:: BLOCK_SIZE and --block-size, in some programs. -+* Signal specifications:: Specifying signals using the --signal option. -+* Disambiguating names and IDs:: chgrp and chown owner and group syntax -+* Random sources:: --random-source, in some programs. -+* Target directory:: Specifying a target directory, in some programs. -+* Trailing slashes:: --strip-trailing-slashes, in some programs. -+* Traversing symlinks:: -H, -L, or -P, in some programs. -+* Treating / specially:: --preserve-root and --no-preserve-root. -+* Special built-in utilities:: @command{break}, @command{:}, @command{eval}, @dots{} -+* Standards conformance:: Conformance to the @acronym{POSIX} standard. -+@end menu -+ -+ -+@node Exit status -+@section Exit status -+ -+@macro exitstatus -+An exit status of zero indicates success, -+and a nonzero value indicates failure. -+@end macro -+ -+Nearly every command invocation yields an integral @dfn{exit status} -+that can be used to change how other commands work. -+For the vast majority of commands, an exit status of zero indicates -+success. Failure is indicated by a nonzero value---typically -+@samp{1}, though it may differ on unusual platforms as @acronym{POSIX} -+requires only that it be nonzero. -+ -+However, some of the programs documented here do produce -+other exit status values and a few associate different -+meanings with the values @samp{0} and @samp{1}. -+Here are some of the exceptions: -+@command{chroot}, @command{env}, @command{expr}, @command{nice}, -+@command{nohup}, @command{printenv}, @command{sort}, @command{stdbuf}, -+@command{su}, @command{test}, @command{timeout}, @command{tty}. -+ -+ -+@node Backup options -+@section Backup options -+ -+@cindex backup options -+ -+Some @sc{gnu} programs (at least @command{cp}, @command{install}, -+@command{ln}, and @command{mv}) optionally make backups of files -+before writing new versions. -+These options control the details of these backups. The options are also -+briefly mentioned in the descriptions of the particular programs. -+ -+@table @samp -+ -+@item -b -+@itemx @w{@kbd{--backup}[=@var{method}]} -+@opindex -b -+@opindex --backup -+@vindex VERSION_CONTROL -+@cindex backups, making -+Make a backup of each file that would otherwise be overwritten or removed. -+Without this option, the original versions are destroyed. -+Use @var{method} to determine the type of backups to make. -+When this option is used but @var{method} is not specified, -+then the value of the @env{VERSION_CONTROL} -+environment variable is used. And if @env{VERSION_CONTROL} is not set, -+the default backup type is @samp{existing}. -+ -+Note that the short form of this option, @option{-b} does not accept any -+argument. Using @option{-b} is equivalent to using @option{--backup=existing}. -+ -+@vindex version-control @r{Emacs variable} -+This option corresponds to the Emacs variable @samp{version-control}; -+the values for @var{method} are the same as those used in Emacs. -+This option also accepts more descriptive names. -+The valid @var{method}s are (unique abbreviations are accepted): -+ -+@table @samp -+@item none -+@itemx off -+@opindex none @r{backup method} -+Never make backups. -+ -+@item numbered -+@itemx t -+@opindex numbered @r{backup method} -+Always make numbered backups. -+ -+@item existing -+@itemx nil -+@opindex existing @r{backup method} -+Make numbered backups of files that already have them, simple backups -+of the others. -+ -+@item simple -+@itemx never -+@opindex simple @r{backup method} -+Always make simple backups. Please note @samp{never} is not to be -+confused with @samp{none}. -+ -+@end table -+ -+@item -S @var{suffix} -+@itemx --suffix=@var{suffix} -+@opindex -S -+@opindex --suffix -+@cindex backup suffix -+@vindex SIMPLE_BACKUP_SUFFIX -+Append @var{suffix} to each backup file made with @option{-b}. If this -+option is not specified, the value of the @env{SIMPLE_BACKUP_SUFFIX} -+environment variable is used. And if @env{SIMPLE_BACKUP_SUFFIX} is not -+set, the default is @samp{~}, just as in Emacs. -+ -+@end table -+ -+@node Block size -+@section Block size -+ -+@cindex block size -+ -+Some @sc{gnu} programs (at least @command{df}, @command{du}, and -+@command{ls}) display sizes in ``blocks''. You can adjust the block size -+and method of display to make sizes easier to read. The block size -+used for display is independent of any file system block size. -+Fractional block counts are rounded up to the nearest integer. -+ -+@opindex --block-size=@var{size} -+@vindex BLOCKSIZE -+@vindex BLOCK_SIZE -+@vindex DF_BLOCK_SIZE -+@vindex DU_BLOCK_SIZE -+@vindex LS_BLOCK_SIZE -+@vindex POSIXLY_CORRECT@r{, and block size} -+ -+The default block size is chosen by examining the following environment -+variables in turn; the first one that is set determines the block size. -+ -+@table @code -+ -+@item DF_BLOCK_SIZE -+This specifies the default block size for the @command{df} command. -+Similarly, @env{DU_BLOCK_SIZE} specifies the default for @command{du} and -+@env{LS_BLOCK_SIZE} for @command{ls}. -+ -+@item BLOCK_SIZE -+This specifies the default block size for all three commands, if the -+above command-specific environment variables are not set. -+ -+@item BLOCKSIZE -+This specifies the default block size for all values that are normally -+printed as blocks, if neither @env{BLOCK_SIZE} nor the above -+command-specific environment variables are set. Unlike the other -+environment variables, @env{BLOCKSIZE} does not affect values that are -+normally printed as byte counts, e.g., the file sizes contained in -+@code{ls -l} output. -+ -+@item POSIXLY_CORRECT -+If neither @env{@var{command}_BLOCK_SIZE}, nor @env{BLOCK_SIZE}, nor -+@env{BLOCKSIZE} is set, but this variable is set, the block size -+defaults to 512. -+ -+@end table -+ -+If none of the above environment variables are set, the block size -+currently defaults to 1024 bytes in most contexts, but this number may -+change in the future. For @command{ls} file sizes, the block size -+defaults to 1 byte. -+ -+@cindex human-readable output -+@cindex SI output -+ -+A block size specification can be a positive integer specifying the number -+of bytes per block, or it can be @code{human-readable} or @code{si} to -+select a human-readable format. Integers may be followed by suffixes -+that are upward compatible with the -+@uref{http://www.bipm.fr/enus/3_SI/si-prefixes.html, SI prefixes} -+for decimal multiples and with the -+@uref{http://physics.nist.gov/cuu/Units/binary.html, IEC 60027-2 -+prefixes for binary multiples}. -+ -+With human-readable formats, output sizes are followed by a size letter -+such as @samp{M} for megabytes. @code{BLOCK_SIZE=human-readable} uses -+powers of 1024; @samp{M} stands for 1,048,576 bytes. -+@code{BLOCK_SIZE=si} is similar, but uses powers of 1000 and appends -+@samp{B}; @samp{MB} stands for 1,000,000 bytes. -+ -+@vindex LC_NUMERIC -+A block size specification preceded by @samp{'} causes output sizes to -+be displayed with thousands separators. The @env{LC_NUMERIC} locale -+specifies the thousands separator and grouping. For example, in an -+American English locale, @samp{--block-size="'1kB"} would cause a size -+of 1234000 bytes to be displayed as @samp{1,234}. In the default C -+locale, there is no thousands separator so a leading @samp{'} has no -+effect. -+ -+An integer block size can be followed by a suffix to specify a -+multiple of that size. A bare size letter, -+or one followed by @samp{iB}, specifies -+a multiple using powers of 1024. A size letter followed by @samp{B} -+specifies powers of 1000 instead. For example, @samp{1M} and -+@samp{1MiB} are equivalent to @samp{1048576}, whereas @samp{1MB} is -+equivalent to @samp{1000000}. -+ -+A plain suffix without a preceding integer acts as if @samp{1} were -+prepended, except that it causes a size indication to be appended to -+the output. For example, @samp{--block-size="kB"} displays 3000 as -+@samp{3kB}. -+ -+The following suffixes are defined. Large sizes like @code{1Y} -+may be rejected by your computer due to limitations of its arithmetic. -+ -+@table @samp -+@item kB -+@cindex kilobyte, definition of -+kilobyte: @math{10^3 = 1000}. -+@item k -+@itemx K -+@itemx KiB -+@cindex kibibyte, definition of -+kibibyte: @math{2^{10} = 1024}. @samp{K} is special: the SI prefix is -+@samp{k} and the IEC 60027-2 prefix is @samp{Ki}, but tradition and -+@acronym{POSIX} use @samp{k} to mean @samp{KiB}. -+@item MB -+@cindex megabyte, definition of -+megabyte: @math{10^6 = 1,000,000}. -+@item M -+@itemx MiB -+@cindex mebibyte, definition of -+mebibyte: @math{2^{20} = 1,048,576}. -+@item GB -+@cindex gigabyte, definition of -+gigabyte: @math{10^9 = 1,000,000,000}. -+@item G -+@itemx GiB -+@cindex gibibyte, definition of -+gibibyte: @math{2^{30} = 1,073,741,824}. -+@item TB -+@cindex terabyte, definition of -+terabyte: @math{10^{12} = 1,000,000,000,000}. -+@item T -+@itemx TiB -+@cindex tebibyte, definition of -+tebibyte: @math{2^{40} = 1,099,511,627,776}. -+@item PB -+@cindex petabyte, definition of -+petabyte: @math{10^{15} = 1,000,000,000,000,000}. -+@item P -+@itemx PiB -+@cindex pebibyte, definition of -+pebibyte: @math{2^{50} = 1,125,899,906,842,624}. -+@item EB -+@cindex exabyte, definition of -+exabyte: @math{10^{18} = 1,000,000,000,000,000,000}. -+@item E -+@itemx EiB -+@cindex exbibyte, definition of -+exbibyte: @math{2^{60} = 1,152,921,504,606,846,976}. -+@item ZB -+@cindex zettabyte, definition of -+zettabyte: @math{10^{21} = 1,000,000,000,000,000,000,000} -+@item Z -+@itemx ZiB -+@math{2^{70} = 1,180,591,620,717,411,303,424}. -+(@samp{Zi} is a @acronym{GNU} extension to IEC 60027-2.) -+@item YB -+@cindex yottabyte, definition of -+yottabyte: @math{10^{24} = 1,000,000,000,000,000,000,000,000}. -+@item Y -+@itemx YiB -+@math{2^{80} = 1,208,925,819,614,629,174,706,176}. -+(@samp{Yi} is a @acronym{GNU} extension to IEC 60027-2.) -+@end table -+ -+@opindex -k -+@opindex -h -+@opindex --block-size -+@opindex --human-readable -+@opindex --si -+ -+Block size defaults can be overridden by an explicit -+@option{--block-size=@var{size}} option. The @option{-k} -+option is equivalent to @option{--block-size=1K}, which -+is the default unless the @env{POSIXLY_CORRECT} environment variable is -+set. The @option{-h} or @option{--human-readable} option is equivalent to -+@option{--block-size=human-readable}. The @option{--si} option is -+equivalent to @option{--block-size=si}. -+ -+@node Signal specifications -+@section Signal specifications -+@cindex signals, specifying -+ -+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. The following signal names -+and numbers are supported on all @acronym{POSIX} compliant systems: -+ -+@table @samp -+@item HUP -+1. Hangup. -+@item INT -+2. Terminal interrupt. -+@item QUIT -+3. Terminal quit. -+@item ABRT -+6. Process abort. -+@item KILL -+9. Kill (cannot be caught or ignored). -+@item ALRM -+14. Alarm Clock. -+@item TERM -+15. Termination. -+@end table -+ -+@noindent -+Other supported signal names have system-dependent corresponding -+numbers. All systems conforming to @acronym{POSIX} 1003.1-2001 also -+support the following signals: -+ -+@table @samp -+@item BUS -+Access to an undefined portion of a memory object. -+@item CHLD -+Child process terminated, stopped, or continued. -+@item CONT -+Continue executing, if stopped. -+@item FPE -+Erroneous arithmetic operation. -+@item ILL -+Illegal Instruction. -+@item PIPE -+Write on a pipe with no one to read it. -+@item SEGV -+Invalid memory reference. -+@item STOP -+Stop executing (cannot be caught or ignored). -+@item TSTP -+Terminal stop. -+@item TTIN -+Background process attempting read. -+@item TTOU -+Background process attempting write. -+@item URG -+High bandwidth data is available at a socket. -+@item USR1 -+User-defined signal 1. -+@item USR2 -+User-defined signal 2. -+@end table -+ -+@noindent -+@acronym{POSIX} 1003.1-2001 systems that support the @acronym{XSI} extension -+also support the following signals: -+ -+@table @samp -+@item POLL -+Pollable event. -+@item PROF -+Profiling timer expired. -+@item SYS -+Bad system call. -+@item TRAP -+Trace/breakpoint trap. -+@item VTALRM -+Virtual timer expired. -+@item XCPU -+CPU time limit exceeded. -+@item XFSZ -+File size limit exceeded. -+@end table -+ -+@noindent -+@acronym{POSIX} 1003.1-2001 systems that support the @acronym{XRT} extension -+also support at least eight real-time signals called @samp{RTMIN}, -+@samp{RTMIN+1}, @dots{}, @samp{RTMAX-1}, @samp{RTMAX}. -+ -+@node Disambiguating names and IDs -+@section chown and chgrp: Disambiguating user names and IDs -+@cindex user names, disambiguating -+@cindex user IDs, disambiguating -+@cindex group names, disambiguating -+@cindex group IDs, disambiguating -+@cindex disambiguating group names and IDs -+ -+Since the @var{owner} and @var{group} arguments to @command{chown} and -+@command{chgrp} may be specified as names or numeric IDs, there is an -+apparent ambiguity. -+What if a user or group @emph{name} is a string of digits? -+@footnote{Using a number as a user name is common in some environments.} -+Should the command interpret it as a user name or as an ID? -+@acronym{POSIX} requires that @command{chown} and @command{chgrp} -+first attempt to resolve the specified string as a name, and -+only once that fails, then try to interpret it as an ID. -+This is troublesome when you want to specify a numeric ID, say 42, -+and it must work even in a pathological situation where -+@samp{42} is a user name that maps to some other user ID, say 1000. -+Simply invoking @code{chown 42 F}, will set @file{F}s owner ID to -+1000---not what you intended. -+ -+GNU @command{chown} and @command{chgrp} provide a way to work around this, -+that at the same time may result in a significant performance improvement -+by eliminating a database look-up. -+Simply precede each numeric user ID and/or group ID with a @samp{+}, -+in order to force its interpretation as an integer: -+ -+@example -+chown +42 F -+chgrp +$numeric_group_id another-file -+chown +0:+0 / -+@end example -+ -+GNU @command{chown} and @command{chgrp} -+skip the name look-up process for each @samp{+}-prefixed string, -+because a string containing @samp{+} is never a valid user or group name. -+This syntax is accepted on most common Unix systems, but not on Solaris 10. -+ -+@node Random sources -+@section Sources of random data -+ -+@cindex random sources -+ -+The @command{shuf}, @command{shred}, and @command{sort} commands -+sometimes need random data to do their work. For example, @samp{sort -+-R} must choose a hash function at random, and it needs random data to -+make this selection. -+ -+By default these commands use an internal pseudorandom generator -+initialized by a small amount of entropy, but can be directed to use -+an external source with the @option{--random-source=@var{file}} option. -+An error is reported if @var{file} does not contain enough bytes. -+ -+For example, the device file @file{/dev/urandom} could be used as the -+source of random data. Typically, this device gathers environmental -+noise from device drivers and other sources into an entropy pool, and -+uses the pool to generate random bits. If the pool is short of data, -+the device reuses the internal pool to produce more bits, using a -+cryptographically secure pseudorandom number generator. But be aware -+that this device is not designed for bulk random data generation -+and is relatively slow. -+ -+@file{/dev/urandom} suffices for most practical uses, but applications -+requiring high-value or long-term protection of private data may -+require an alternate data source like @file{/dev/random} or -+@file{/dev/arandom}. The set of available sources depends on your -+operating system. -+ -+To reproduce the results of an earlier invocation of a command, you -+can save some random data into a file and then use that file as the -+random source in earlier and later invocations of the command. -+ -+@node Target directory -+@section Target directory -+ -+@cindex target directory -+ -+The @command{cp}, @command{install}, @command{ln}, and @command{mv} -+commands normally treat the last operand specially when it is a -+directory or a symbolic link to a directory. For example, @samp{cp -+source dest} is equivalent to @samp{cp source dest/source} if -+@file{dest} is a directory. Sometimes this behavior is not exactly -+what is wanted, so these commands support the following options to -+allow more fine-grained control: -+ -+@table @samp -+ -+@item -T -+@itemx --no-target-directory -+@opindex --no-target-directory -+@cindex target directory -+@cindex destination directory -+Do not treat the last operand specially when it is a directory or a -+symbolic link to a directory. This can help avoid race conditions in -+programs that operate in a shared area. For example, when the command -+@samp{mv /tmp/source /tmp/dest} succeeds, there is no guarantee that -+@file{/tmp/source} was renamed to @file{/tmp/dest}: it could have been -+renamed to @file{/tmp/dest/source} instead, if some other process -+created @file{/tmp/dest} as a directory. However, if @file{mv -+-T /tmp/source /tmp/dest} succeeds, there is no -+question that @file{/tmp/source} was renamed to @file{/tmp/dest}. -+ -+In the opposite situation, where you want the last operand to be -+treated as a directory and want a diagnostic otherwise, you can use -+the @option{--target-directory} (@option{-t}) option. -+ -+@item -t @var{directory} -+@itemx @w{@kbd{--target-directory}=@var{directory}} -+@opindex --target-directory -+@cindex target directory -+@cindex destination directory -+Use @var{directory} as the directory component of each destination -+file name. -+ -+The interface for most programs is that after processing options and a -+finite (possibly zero) number of fixed-position arguments, the remaining -+argument list is either expected to be empty, or is a list of items -+(usually files) that will all be handled identically. The @command{xargs} -+program is designed to work well with this convention. -+ -+The commands in the @command{mv}-family are unusual in that they take -+a variable number of arguments with a special case at the @emph{end} -+(namely, the target directory). This makes it nontrivial to perform some -+operations, e.g., ``move all files from here to ../d/'', because -+@code{mv * ../d/} might exhaust the argument space, and @code{ls | xargs ...} -+doesn't have a clean way to specify an extra final argument for each -+invocation of the subject command. (It can be done by going through a -+shell command, but that requires more human labor and brain power than -+it should.) -+ -+The @w{@kbd{--target-directory}} (@option{-t}) option allows the @command{cp}, -+@command{install}, @command{ln}, and @command{mv} programs to be used -+conveniently with @command{xargs}. For example, you can move the files -+from the current directory to a sibling directory, @code{d} like this: -+ -+@smallexample -+ls | xargs mv -t ../d -- -+@end smallexample -+ -+However, this doesn't move files whose names begin with @samp{.}. -+If you use the @sc{gnu} @command{find} program, you can move those -+files too, with this command: -+ -+@example -+find . -mindepth 1 -maxdepth 1 \ -+ | xargs mv -t ../d -+@end example -+ -+But both of the above approaches fail if there are no files in the -+current directory, or if any file has a name containing a blank or -+some other special characters. -+The following example removes those limitations and requires both -+@sc{gnu} @command{find} and @sc{gnu} @command{xargs}: -+ -+@example -+find . -mindepth 1 -maxdepth 1 -print0 \ -+ | xargs --null --no-run-if-empty \ -+ mv -t ../d -+@end example -+ -+@end table -+ -+@noindent -+The @option{--target-directory} (@option{-t}) and -+@option{--no-target-directory} (@option{-T}) -+options cannot be combined. -+ -+@node Trailing slashes -+@section Trailing slashes -+ -+@cindex trailing slashes -+ -+Some @sc{gnu} programs (at least @command{cp} and @command{mv}) allow you to -+remove any trailing slashes from each @var{source} argument before -+operating on it. The @w{@kbd{--strip-trailing-slashes}} option enables -+this behavior. -+ -+This is useful when a @var{source} argument may have a trailing slash and -+@c FIXME: mv's behavior in this case is system-dependent -+specify a symbolic link to a directory. This scenario is in fact rather -+common because some shells can automatically append a trailing slash when -+performing file name completion on such symbolic links. Without this -+option, @command{mv}, for example, (via the system's rename function) must -+interpret a trailing slash as a request to dereference the symbolic link -+and so must rename the indirectly referenced @emph{directory} and not -+the symbolic link. Although it may seem surprising that such behavior -+be the default, it is required by @acronym{POSIX} and is consistent with -+other parts of that standard. -+ -+@node Traversing symlinks -+@section Traversing symlinks -+ -+@cindex symbolic link to directory, controlling traversal of -+ -+The following options modify how @command{chown} and @command{chgrp} -+@c FIXME: note that `du' has these options, too, but they have slightly -+@c different meaning. -+traverse a hierarchy when the @option{--recursive} (@option{-R}) -+option is also specified. -+If more than one of the following options is specified, only the final -+one takes effect. -+These options specify whether processing a symbolic link to a directory -+entails operating on just the symbolic link or on all files in the -+hierarchy rooted at that directory. -+ -+These options are independent of @option{--dereference} and -+@option{--no-dereference} (@option{-h}), which control whether to modify -+a symlink or its referent. -+ -+@table @samp -+ -+@macro choptH -+@item -H -+@opindex -H -+@cindex symbolic link to directory, traverse each that is specified on the command line -+If @option{--recursive} (@option{-R}) is specified and -+a command line argument is a symbolic link to a directory, traverse it. -+@end macro -+@choptH -+ -+@macro choptL -+@item -L -+@opindex -L -+@cindex symbolic link to directory, traverse each that is encountered -+In a recursive traversal, traverse every symbolic link to a directory -+that is encountered. -+@end macro -+@choptL -+ -+@macro choptP -+@item -P -+@opindex -P -+@cindex symbolic link to directory, never traverse -+Do not traverse any symbolic links. -+This is the default if none of @option{-H}, @option{-L}, -+or @option{-P} is specified. -+@end macro -+@choptP -+ -+@end table -+ -+ -+@node Treating / specially -+@section Treating @file{/} specially -+ -+Certain commands can operate destructively on entire hierarchies. -+For example, if a user with appropriate privileges mistakenly runs -+@samp{rm -rf / tmp/junk}, that may remove -+all files on the entire system. Since there are so few -+legitimate uses for such a command, -+@sc{gnu} @command{rm} normally declines to operate on any directory -+that resolves to @file{/}. If you really want to try to remove all -+the files on your system, you can use the @option{--no-preserve-root} -+option, but the default behavior, specified by the -+@option{--preserve-option}, is safer for most purposes. -+ -+The commands @command{chgrp}, @command{chmod} and @command{chown} -+can also operate destructively on entire hierarchies, so they too -+support these options. Although, unlike @command{rm}, they don't -+actually unlink files, these commands are arguably more dangerous -+when operating recursively on @file{/}, since they often work much -+more quickly, and hence damage more files before an alert user can -+interrupt them. Tradition and @acronym{POSIX} require these commands -+to operate recursively on @file{/}, so they default to -+@option{--no-preserve-root}, but using the @option{--preserve-root} -+option makes them safer for most purposes. For convenience you can -+specify @option{--preserve-root} in an alias or in a shell function. -+ -+Note that the @option{--preserve-root} option also ensures -+that @command{chgrp} and @command{chown} do not modify @file{/} -+even when dereferencing a symlink pointing to @file{/}. -+ -+@node Special built-in utilities -+@section Special built-in utilities -+ -+Some programs like @command{nice} can invoke other programs; for -+example, the command @samp{nice cat file} invokes the program -+@command{cat} by executing the command @samp{cat file}. However, -+@dfn{special built-in utilities} like @command{exit} cannot be invoked -+this way. For example, the command @samp{nice exit} does not have a -+well-defined behavior: it may generate an error message instead of -+exiting. -+ -+Here is a list of the special built-in utilities that are standardized -+by @acronym{POSIX} 1003.1-2004. -+ -+@quotation -+@t{.@: : break continue eval exec exit export readonly -+return set shift times trap unset} -+@end quotation -+ -+For example, because @samp{.}, @samp{:}, and @samp{exec} are special, -+the commands @samp{nice . foo.sh}, @samp{nice :}, and @samp{nice exec -+pwd} do not work as you might expect. -+ -+Many shells extend this list. For example, Bash has several extra -+special built-in utilities like @command{history}, and -+@command{suspend}, and with Bash the command @samp{nice suspend} -+generates an error message instead of suspending. -+ -+@node Standards conformance -+@section Standards conformance -+ -+@vindex POSIXLY_CORRECT -+In a few cases, the @sc{gnu} utilities' default behavior is -+incompatible with the @acronym{POSIX} standard. To suppress these -+incompatibilities, define the @env{POSIXLY_CORRECT} environment -+variable. Unless you are checking for @acronym{POSIX} conformance, you -+probably do not need to define @env{POSIXLY_CORRECT}. -+ -+Newer versions of @acronym{POSIX} are occasionally incompatible with older -+versions. For example, older versions of @acronym{POSIX} required the -+command @samp{sort +1} to sort based on the second and succeeding -+fields in each input line, but starting with @acronym{POSIX} 1003.1-2001 -+the same command is required to sort the file named @file{+1}, and you -+must instead use the command @samp{sort -k 2} to get the field-based -+sort. -+ -+@vindex _POSIX2_VERSION -+The @sc{gnu} utilities normally conform to the version of @acronym{POSIX} -+that is standard for your system. To cause them to conform to a -+different version of @acronym{POSIX}, define the @env{_POSIX2_VERSION} -+environment variable to a value of the form @var{yyyymm} specifying -+the year and month the standard was adopted. Two values are currently -+supported for @env{_POSIX2_VERSION}: @samp{199209} stands for -+@acronym{POSIX} 1003.2-1992, and @samp{200112} stands for @acronym{POSIX} -+1003.1-2001. For example, if you have a newer system but are running software -+that assumes an older version of @acronym{POSIX} and uses @samp{sort +1} -+or @samp{tail +10}, you can work around any compatibility problems by setting -+@samp{_POSIX2_VERSION=199209} in your environment. -+ -+@node Output of entire files -+@chapter Output of entire files -+ -+@cindex output of entire files -+@cindex entire files, output of -+ -+These commands read and write entire files, possibly transforming them -+in some way. -+ -+@menu -+* cat invocation:: Concatenate and write files. -+* tac invocation:: Concatenate and write files in reverse. -+* nl invocation:: Number lines and write files. -+* od invocation:: Write files in octal or other formats. -+* base64 invocation:: Transform data into printable data. -+@end menu -+ -+@node cat invocation -+@section @command{cat}: Concatenate and write files -+ -+@pindex cat -+@cindex concatenate and write files -+@cindex copying files -+ -+@command{cat} copies each @var{file} (@samp{-} means standard input), or -+standard input if none are given, to standard output. Synopsis: -+ -+@example -+cat [@var{option}] [@var{file}]@dots{} -+@end example -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -A -+@itemx --show-all -+@opindex -A -+@opindex --show-all -+Equivalent to @option{-vET}. -+ -+@item -b -+@itemx --number-nonblank -+@opindex -b -+@opindex --number-nonblank -+Number all nonempty output lines, starting with 1. -+ -+@item -e -+@opindex -e -+Equivalent to @option{-vE}. -+ -+@item -E -+@itemx --show-ends -+@opindex -E -+@opindex --show-ends -+Display a @samp{$} after the end of each line. -+ -+@item -n -+@itemx --number -+@opindex -n -+@opindex --number -+Number all output lines, starting with 1. -+ -+@item -s -+@itemx --squeeze-blank -+@opindex -s -+@opindex --squeeze-blank -+@cindex squeezing empty lines -+Suppress repeated adjacent empty lines; output just one empty line -+instead of several. -+ -+@item -t -+@opindex -t -+Equivalent to @option{-vT}. -+ -+@item -T -+@itemx --show-tabs -+@opindex -T -+@opindex --show-tabs -+Display TAB characters as @samp{^I}. -+ -+@item -u -+@opindex -u -+Ignored; for @acronym{POSIX} compatibility. -+ -+@item -v -+@itemx --show-nonprinting -+@opindex -v -+@opindex --show-nonprinting -+Display control characters except for LFD and TAB using -+@samp{^} notation and precede characters that have the high bit set with -+@samp{M-}. -+ -+@end table -+ -+On systems like MS-DOS that distinguish between text and binary files, -+@command{cat} normally reads and writes in binary mode. However, -+@command{cat} reads in text mode if one of the options -+@option{-bensAE} is used or if @command{cat} is reading from standard -+input and standard input is a terminal. Similarly, @command{cat} -+writes in text mode if one of the options @option{-bensAE} is used or -+if standard output is a terminal. -+ -+@exitstatus -+ -+Examples: -+ -+@smallexample -+# Output f's contents, then standard input, then g's contents. -+cat f - g -+ -+# Copy standard input to standard output. -+cat -+@end smallexample -+ -+ -+@node tac invocation -+@section @command{tac}: Concatenate and write files in reverse -+ -+@pindex tac -+@cindex reversing files -+ -+@command{tac} copies each @var{file} (@samp{-} means standard input), or -+standard input if none are given, to standard output, reversing the -+records (lines by default) in each separately. Synopsis: -+ -+@example -+tac [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+@dfn{Records} are separated by instances of a string (newline by -+default). By default, this separator string is attached to the end of -+the record that it follows in the file. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -b -+@itemx --before -+@opindex -b -+@opindex --before -+The separator is attached to the beginning of the record that it -+precedes in the file. -+ -+@item -r -+@itemx --regex -+@opindex -r -+@opindex --regex -+Treat the separator string as a regular expression. Users of @command{tac} -+on MS-DOS/MS-Windows should note that, since @command{tac} reads files in -+binary mode, each line of a text file might end with a CR/LF pair -+instead of the Unix-style LF. -+ -+@item -s @var{separator} -+@itemx --separator=@var{separator} -+@opindex -s -+@opindex --separator -+Use @var{separator} as the record separator, instead of newline. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node nl invocation -+@section @command{nl}: Number lines and write files -+ -+@pindex nl -+@cindex numbering lines -+@cindex line numbering -+ -+@command{nl} writes each @var{file} (@samp{-} means standard input), or -+standard input if none are given, to standard output, with line numbers -+added to some or all of the lines. Synopsis: -+ -+@example -+nl [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+@cindex logical pages, numbering on -+@command{nl} decomposes its input into (logical) pages; by default, the -+line number is reset to 1 at the top of each logical page. @command{nl} -+treats all of the input files as a single document; it does not reset -+line numbers or logical pages between files. -+ -+@cindex headers, numbering -+@cindex body, numbering -+@cindex footers, numbering -+A logical page consists of three sections: header, body, and footer. -+Any of the sections can be empty. Each can be numbered in a different -+style from the others. -+ -+The beginnings of the sections of logical pages are indicated in the -+input file by a line containing exactly one of these delimiter strings: -+ -+@table @samp -+@item \:\:\: -+start of header; -+@item \:\: -+start of body; -+@item \: -+start of footer. -+@end table -+ -+The two characters from which these strings are made can be changed from -+@samp{\} and @samp{:} via options (see below), but the pattern and -+length of each string cannot be changed. -+ -+A section delimiter is replaced by an empty line on output. Any text -+that comes before the first section delimiter string in the input file -+is considered to be part of a body section, so @command{nl} treats a -+file that contains no section delimiters as a single body section. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -b @var{style} -+@itemx --body-numbering=@var{style} -+@opindex -b -+@opindex --body-numbering -+Select the numbering style for lines in the body section of each -+logical page. When a line is not numbered, the current line number -+is not incremented, but the line number separator character is still -+prepended to the line. The styles are: -+ -+@table @samp -+@item a -+number all lines, -+@item t -+number only nonempty lines (default for body), -+@item n -+do not number lines (default for header and footer), -+@item p@var{bre} -+number only lines that contain a match for the basic regular -+expression @var{bre}. -+@xref{Regular Expressions, , Regular Expressions, grep, The GNU Grep Manual}. -+@end table -+ -+@item -d @var{cd} -+@itemx --section-delimiter=@var{cd} -+@opindex -d -+@opindex --section-delimiter -+@cindex section delimiters of pages -+Set the section delimiter characters to @var{cd}; default is -+@samp{\:}. If only @var{c} is given, the second remains @samp{:}. -+(Remember to protect @samp{\} or other metacharacters from shell -+expansion with quotes or extra backslashes.) -+ -+@item -f @var{style} -+@itemx --footer-numbering=@var{style} -+@opindex -f -+@opindex --footer-numbering -+Analogous to @option{--body-numbering}. -+ -+@item -h @var{style} -+@itemx --header-numbering=@var{style} -+@opindex -h -+@opindex --header-numbering -+Analogous to @option{--body-numbering}. -+ -+@item -i @var{number} -+@itemx --line-increment=@var{number} -+@opindex -i -+@opindex --line-increment -+Increment line numbers by @var{number} (default 1). -+ -+@item -l @var{number} -+@itemx --join-blank-lines=@var{number} -+@opindex -l -+@opindex --join-blank-lines -+@cindex empty lines, numbering -+@cindex blank lines, numbering -+Consider @var{number} (default 1) consecutive empty lines to be one -+logical line for numbering, and only number the last one. Where fewer -+than @var{number} consecutive empty lines occur, do not number them. -+An empty line is one that contains no characters, not even spaces -+or tabs. -+ -+@item -n @var{format} -+@itemx --number-format=@var{format} -+@opindex -n -+@opindex --number-format -+Select the line numbering format (default is @code{rn}): -+ -+@table @samp -+@item ln -+@opindex ln @r{format for @command{nl}} -+left justified, no leading zeros; -+@item rn -+@opindex rn @r{format for @command{nl}} -+right justified, no leading zeros; -+@item rz -+@opindex rz @r{format for @command{nl}} -+right justified, leading zeros. -+@end table -+ -+@item -p -+@itemx --no-renumber -+@opindex -p -+@opindex --no-renumber -+Do not reset the line number at the start of a logical page. -+ -+@item -s @var{string} -+@itemx --number-separator=@var{string} -+@opindex -s -+@opindex --number-separator -+Separate the line number from the text line in the output with -+@var{string} (default is the TAB character). -+ -+@item -v @var{number} -+@itemx --starting-line-number=@var{number} -+@opindex -v -+@opindex --starting-line-number -+Set the initial line number on each logical page to @var{number} (default 1). -+ -+@item -w @var{number} -+@itemx --number-width=@var{number} -+@opindex -w -+@opindex --number-width -+Use @var{number} characters for line numbers (default 6). -+ -+@end table -+ -+@exitstatus -+ -+ -+@node od invocation -+@section @command{od}: Write files in octal or other formats -+ -+@pindex od -+@cindex octal dump of files -+@cindex hex dump of files -+@cindex ASCII dump of files -+@cindex file contents, dumping unambiguously -+ -+@command{od} writes an unambiguous representation of each @var{file} -+(@samp{-} means standard input), or standard input if none are given. -+Synopses: -+ -+@smallexample -+od [@var{option}]@dots{} [@var{file}]@dots{} -+od [-abcdfilosx]@dots{} [@var{file}] [[+]@var{offset}[.][b]] -+od [@var{option}]@dots{} --traditional [@var{file}] [[+]@var{offset}[.][b] [[+]@var{label}[.][b]]] -+@end smallexample -+ -+Each line of output consists of the offset in the input, followed by -+groups of data from the file. By default, @command{od} prints the offset in -+octal, and each group of file data is a C @code{short int}'s worth of input -+printed as a single octal number. -+ -+If @var{offset} is given, it specifies how many input bytes to skip -+before formatting and writing. By default, it is interpreted as an -+octal number, but the optional trailing decimal point causes it to be -+interpreted as decimal. If no decimal is specified and the offset -+begins with @samp{0x} or @samp{0X} it is interpreted as a hexadecimal -+number. If there is a trailing @samp{b}, the number of bytes skipped -+will be @var{offset} multiplied by 512. -+ -+If a command is of both the first and second forms, the second form is -+assumed if the last operand begins with @samp{+} or (if there are two -+operands) a digit. For example, in @samp{od foo 10} and @samp{od +10} -+the @samp{10} is an offset, whereas in @samp{od 10} the @samp{10} is a -+file name. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -A @var{radix} -+@itemx --address-radix=@var{radix} -+@opindex -A -+@opindex --address-radix -+@cindex radix for file offsets -+@cindex file offset radix -+Select the base in which file offsets are printed. @var{radix} can -+be one of the following: -+ -+@table @samp -+@item d -+decimal; -+@item o -+octal; -+@item x -+hexadecimal; -+@item n -+none (do not print offsets). -+@end table -+ -+The default is octal. -+ -+@item -j @var{bytes} -+@itemx --skip-bytes=@var{bytes} -+@opindex -j -+@opindex --skip-bytes -+Skip @var{bytes} input bytes before formatting and writing. If -+@var{bytes} begins with @samp{0x} or @samp{0X}, it is interpreted in -+hexadecimal; otherwise, if it begins with @samp{0}, in octal; otherwise, -+in decimal. -+@multiplierSuffixes{bytes} -+ -+@item -N @var{bytes} -+@itemx --read-bytes=@var{bytes} -+@opindex -N -+@opindex --read-bytes -+Output at most @var{bytes} bytes of the input. Prefixes and suffixes on -+@code{bytes} are interpreted as for the @option{-j} option. -+ -+@item -S @var{bytes} -+@itemx --strings[=@var{bytes}] -+@opindex -S -+@opindex --strings -+@cindex string constants, outputting -+Instead of the normal output, output only @dfn{string constants}: at -+least @var{bytes} consecutive @acronym{ASCII} graphic characters, -+followed by a zero byte (@acronym{ASCII} @sc{nul}). -+Prefixes and suffixes on @code{bytes} are interpreted as for the -+@option{-j} option. -+ -+If @var{n} is omitted with @option{--strings}, the default is 3. -+ -+@item -t @var{type} -+@itemx --format=@var{type} -+@opindex -t -+@opindex --format -+Select the format in which to output the file data. @var{type} is a -+string of one or more of the below type indicator characters. If you -+include more than one type indicator character in a single @var{type} -+string, or use this option more than once, @command{od} writes one copy -+of each output line using each of the data types that you specified, -+in the order that you specified. -+ -+Adding a trailing ``z'' to any type specification appends a display -+of the @acronym{ASCII} character representation of the printable characters -+to the output line generated by the type specification. -+ -+@table @samp -+@item a -+named character, ignoring high-order bit -+@item c -+@acronym{ASCII} character or backslash escape, -+@item d -+signed decimal -+@item f -+floating point -+@item o -+octal -+@item u -+unsigned decimal -+@item x -+hexadecimal -+@end table -+ -+The type @code{a} outputs things like @samp{sp} for space, @samp{nl} for -+newline, and @samp{nul} for a zero byte. Only the least significant -+seven bits of each byte is used; the high-order bit is ignored. -+Type @code{c} outputs -+@samp{ }, @samp{\n}, and @code{\0}, respectively. -+ -+@cindex type size -+Except for types @samp{a} and @samp{c}, you can specify the number -+of bytes to use in interpreting each number in the given data type -+by following the type indicator character with a decimal integer. -+Alternately, you can specify the size of one of the C compiler's -+built-in data types by following the type indicator character with -+one of the following characters. For integers (@samp{d}, @samp{o}, -+@samp{u}, @samp{x}): -+ -+@table @samp -+@item C -+char -+@item S -+short -+@item I -+int -+@item L -+long -+@end table -+ -+For floating point (@code{f}): -+ -+@table @asis -+@item F -+float -+@item D -+double -+@item L -+long double -+@end table -+ -+@item -v -+@itemx --output-duplicates -+@opindex -v -+@opindex --output-duplicates -+Output consecutive lines that are identical. By default, when two or -+more consecutive output lines would be identical, @command{od} outputs only -+the first line, and puts just an asterisk on the following line to -+indicate the elision. -+ -+@item -w[@var{n}] -+@itemx --width[=@var{n}] -+@opindex -w -+@opindex --width -+Dump @code{n} input bytes per output line. This must be a multiple of -+the least common multiple of the sizes associated with the specified -+output types. -+ -+If this option is not given at all, the default is 16. If @var{n} is -+omitted, the default is 32. -+ -+@end table -+ -+The next several options are shorthands for format specifications. -+@sc{gnu} @command{od} accepts any combination of shorthands and format -+specification options. These options accumulate. -+ -+@table @samp -+ -+@item -a -+@opindex -a -+Output as named characters. Equivalent to @samp{-t a}. -+ -+@item -b -+@opindex -b -+Output as octal bytes. Equivalent to @samp{-t o1}. -+ -+@item -c -+@opindex -c -+Output as @acronym{ASCII} characters or backslash escapes. Equivalent to -+@samp{-t c}. -+ -+@item -d -+@opindex -d -+Output as unsigned decimal two-byte units. Equivalent to @samp{-t u2}. -+ -+@item -f -+@opindex -f -+Output as floats. Equivalent to @samp{-t fF}. -+ -+@item -i -+@opindex -i -+Output as decimal ints. Equivalent to @samp{-t dI}. -+ -+@item -l -+@opindex -l -+Output as decimal long ints. Equivalent to @samp{-t dL}. -+ -+@item -o -+@opindex -o -+Output as octal two-byte units. Equivalent to @option{-t o2}. -+ -+@item -s -+@opindex -s -+Output as decimal two-byte units. Equivalent to @option{-t d2}. -+ -+@item -x -+@opindex -x -+Output as hexadecimal two-byte units. Equivalent to @samp{-t x2}. -+ -+@item --traditional -+@opindex --traditional -+Recognize the non-option label argument that traditional @command{od} -+accepted. The following syntax: -+ -+@smallexample -+od --traditional [@var{file}] [[+]@var{offset}[.][b] [[+]@var{label}[.][b]]] -+@end smallexample -+ -+@noindent -+can be used to specify at most one file and optional arguments -+specifying an offset and a pseudo-start address, @var{label}. -+The @var{label} argument is interpreted -+just like @var{offset}, but it specifies an initial pseudo-address. The -+pseudo-addresses are displayed in parentheses following any normal -+address. -+ -+@end table -+ -+@exitstatus -+ -+@node base64 invocation -+@section @command{base64}: Transform data into printable data -+ -+@pindex base64 -+@cindex base64 encoding -+ -+@command{base64} transforms data read from a file, or standard input, -+into (or from) base64 encoded form. The base64 encoded form uses -+printable @acronym{ASCII} characters to represent binary data. -+Synopses: -+ -+@smallexample -+base64 [@var{option}]@dots{} [@var{file}] -+base64 --decode [@var{option}]@dots{} [@var{file}] -+@end smallexample -+ -+The base64 encoding expands data to roughly 133% of the original. -+The format conforms to -+@uref{ftp://ftp.rfc-editor.org/in-notes/rfc4648.txt, RFC 4648}. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -w @var{cols} -+@itemx --wrap=@var{cols} -+@opindex -w -+@opindex --wrap -+@cindex wrap data -+@cindex column to wrap data after -+During encoding, wrap lines after @var{cols} characters. This must be -+a positive number. -+ -+The default is to wrap after 76 characters. Use the value 0 to -+disable line wrapping altogether. -+ -+@item -d -+@itemx --decode -+@opindex -d -+@opindex --decode -+@cindex Decode base64 data -+@cindex Base64 decoding -+Change the mode of operation, from the default of encoding data, to -+decoding data. Input is expected to be base64 encoded data, and the -+output will be the original data. -+ -+@item -i -+@itemx --ignore-garbage -+@opindex -i -+@opindex --ignore-garbage -+@cindex Ignore garbage in base64 stream -+When decoding, newlines are always accepted. -+During decoding, ignore unrecognized bytes, -+to permit distorted data to be decoded. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node Formatting file contents -+@chapter Formatting file contents -+ -+@cindex formatting file contents -+ -+These commands reformat the contents of files. -+ -+@menu -+* fmt invocation:: Reformat paragraph text. -+* pr invocation:: Paginate or columnate files for printing. -+* fold invocation:: Wrap input lines to fit in specified width. -+@end menu -+ -+ -+@node fmt invocation -+@section @command{fmt}: Reformat paragraph text -+ -+@pindex fmt -+@cindex reformatting paragraph text -+@cindex paragraphs, reformatting -+@cindex text, reformatting -+ -+@command{fmt} fills and joins lines to produce output lines of (at most) -+a given number of characters (75 by default). Synopsis: -+ -+@example -+fmt [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+@command{fmt} reads from the specified @var{file} arguments (or standard -+input if none are given), and writes to standard output. -+ -+By default, blank lines, spaces between words, and indentation are -+preserved in the output; successive input lines with different -+indentation are not joined; tabs are expanded on input and introduced on -+output. -+ -+@cindex line-breaking -+@cindex sentences and line-breaking -+@cindex Knuth, Donald E. -+@cindex Plass, Michael F. -+@command{fmt} prefers breaking lines at the end of a sentence, and tries to -+avoid line breaks after the first word of a sentence or before the last -+word of a sentence. A @dfn{sentence break} is defined as either the end -+of a paragraph or a word ending in any of @samp{.?!}, followed by two -+spaces or end of line, ignoring any intervening parentheses or quotes. -+Like @TeX{}, @command{fmt} reads entire ``paragraphs'' before choosing line -+breaks; the algorithm is a variant of that given by Donald E. Knuth -+and Michael F. Plass in ``Breaking Paragraphs Into Lines'', -+@cite{Software---Practice & Experience} @b{11}, 11 (November 1981), -+1119--1184. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -c -+@itemx --crown-margin -+@opindex -c -+@opindex --crown-margin -+@cindex crown margin -+@dfn{Crown margin} mode: preserve the indentation of the first two -+lines within a paragraph, and align the left margin of each subsequent -+line with that of the second line. -+ -+@item -t -+@itemx --tagged-paragraph -+@opindex -t -+@opindex --tagged-paragraph -+@cindex tagged paragraphs -+@dfn{Tagged paragraph} mode: like crown margin mode, except that if -+indentation of the first line of a paragraph is the same as the -+indentation of the second, the first line is treated as a one-line -+paragraph. -+ -+@item -s -+@itemx --split-only -+@opindex -s -+@opindex --split-only -+Split lines only. Do not join short lines to form longer ones. This -+prevents sample lines of code, and other such ``formatted'' text from -+being unduly combined. -+ -+@item -u -+@itemx --uniform-spacing -+@opindex -u -+@opindex --uniform-spacing -+Uniform spacing. Reduce spacing between words to one space, and spacing -+between sentences to two spaces. -+ -+@item -@var{width} -+@itemx -w @var{width} -+@itemx --width=@var{width} -+@opindex -@var{width} -+@opindex -w -+@opindex --width -+Fill output lines up to @var{width} characters (default 75). @command{fmt} -+initially tries to make lines about 7% shorter than this, to give it -+room to balance line lengths. -+ -+@item -p @var{prefix} -+@itemx --prefix=@var{prefix} -+Only lines beginning with @var{prefix} (possibly preceded by whitespace) -+are subject to formatting. The prefix and any preceding whitespace are -+stripped for the formatting and then re-attached to each formatted output -+line. One use is to format certain kinds of program comments, while -+leaving the code unchanged. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node pr invocation -+@section @command{pr}: Paginate or columnate files for printing -+ -+@pindex pr -+@cindex printing, preparing files for -+@cindex multicolumn output, generating -+@cindex merging files in parallel -+ -+@command{pr} writes each @var{file} (@samp{-} means standard input), or -+standard input if none are given, to standard output, paginating and -+optionally outputting in multicolumn format; optionally merges all -+@var{file}s, printing all in parallel, one per column. Synopsis: -+ -+@example -+pr [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+@vindex LC_MESSAGES -+By default, a 5-line header is printed at each page: two blank lines; -+a line with the date, the file name, and the page count; and two more -+blank lines. A footer of five blank lines is also printed. -+The default @var{page_length} is 66 -+lines. The default number of text lines is therefore 56. -+The text line of the header takes the form -+@samp{@var{date} @var{string} @var{page}}, with spaces inserted around -+@var{string} so that the line takes up the full @var{page_width}. Here, -+@var{date} is the date (see the @option{-D} or @option{--date-format} -+option for details), @var{string} is the centered header string, and -+@var{page} identifies the page number. The @env{LC_MESSAGES} locale -+category affects the spelling of @var{page}; in the default C locale, it -+is @samp{Page @var{number}} where @var{number} is the decimal page -+number. -+ -+Form feeds in the input cause page breaks in the output. Multiple form -+feeds produce empty pages. -+ -+Columns are of equal width, separated by an optional string (default -+is @samp{space}). For multicolumn output, lines will always be truncated to -+@var{page_width} (default 72), unless you use the @option{-J} option. -+For single -+column output no line truncation occurs by default. Use @option{-W} option to -+truncate lines in that case. -+ -+The following changes were made in version 1.22i and apply to later -+versions of @command{pr}: -+@c FIXME: this whole section here sounds very awkward to me. I -+@c made a few small changes, but really it all needs to be redone. - Brian -+@c OK, I fixed another sentence or two, but some of it I just don't understand. -+@ - Brian -+@itemize @bullet -+ -+@item -+Some small @var{letter options} (@option{-s}, @option{-w}) have been -+redefined for better @acronym{POSIX} compliance. The output of some further -+cases has been adapted to other Unix systems. These changes are not -+compatible with earlier versions of the program. -+ -+@item -+Some @var{new capital letter} options (@option{-J}, @option{-S}, @option{-W}) -+have been introduced to turn off unexpected interferences of small letter -+options. The @option{-N} option and the second argument @var{last_page} -+of @samp{+FIRST_PAGE} offer more flexibility. The detailed handling of -+form feeds set in the input files requires the @option{-T} option. -+ -+@item -+Capital letter options override small letter ones. -+ -+@item -+Some of the option-arguments (compare @option{-s}, @option{-e}, -+@option{-i}, @option{-n}) cannot be specified as separate arguments from the -+preceding option letter (already stated in the @acronym{POSIX} specification). -+@end itemize -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item +@var{first_page}[:@var{last_page}] -+@itemx --pages=@var{first_page}[:@var{last_page}] -+@c The two following @opindex lines evoke warnings because they contain `:' -+@c The `info' spec does not permit that. If we use those lines, we end -+@c up with truncated index entries that don't work. -+@c @opindex +@var{first_page}[:@var{last_page}] -+@c @opindex --pages=@var{first_page}[:@var{last_page}] -+@opindex +@var{page_range} -+@opindex --pages=@var{page_range} -+Begin printing with page @var{first_page} and stop with @var{last_page}. -+Missing @samp{:@var{last_page}} implies end of file. While estimating -+the number of skipped pages each form feed in the input file results -+in a new page. Page counting with and without @samp{+@var{first_page}} -+is identical. By default, counting starts with the first page of input -+file (not first page printed). Line numbering may be altered by @option{-N} -+option. -+ -+@item -@var{column} -+@itemx --columns=@var{column} -+@opindex -@var{column} -+@opindex --columns -+@cindex down columns -+With each single @var{file}, produce @var{column} columns of output -+(default is 1) and print columns down, unless @option{-a} is used. The -+column width is automatically decreased as @var{column} increases; unless -+you use the @option{-W/-w} option to increase @var{page_width} as well. -+This option might well cause some lines to be truncated. The number of -+lines in the columns on each page are balanced. The options @option{-e} -+and @option{-i} are on for multiple text-column output. Together with -+@option{-J} option column alignment and line truncation is turned off. -+Lines of full length are joined in a free field format and @option{-S} -+option may set field separators. @option{-@var{column}} may not be used -+with @option{-m} option. -+ -+@item -a -+@itemx --across -+@opindex -a -+@opindex --across -+@cindex across columns -+With each single @var{file}, print columns across rather than down. The -+@option{-@var{column}} option must be given with @var{column} greater than one. -+If a line is too long to fit in a column, it is truncated. -+ -+@item -c -+@itemx --show-control-chars -+@opindex -c -+@opindex --show-control-chars -+Print control characters using hat notation (e.g., @samp{^G}); print -+other nonprinting characters in octal backslash notation. By default, -+nonprinting characters are not changed. -+ -+@item -d -+@itemx --double-space -+@opindex -d -+@opindex --double-space -+@cindex double spacing -+Double space the output. -+ -+@item -D @var{format} -+@itemx --date-format=@var{format} -+@cindex time formats -+@cindex formatting times -+Format header dates using @var{format}, using the same conventions as -+for the command @samp{date +@var{format}}; @xref{date invocation}. -+Except for directives, which start with -+@samp{%}, characters in @var{format} are printed unchanged. You can use -+this option to specify an arbitrary string in place of the header date, -+e.g., @option{--date-format="Monday morning"}. -+ -+@vindex POSIXLY_CORRECT -+@vindex LC_TIME -+The default date format is @samp{%Y-%m-%d %H:%M} (for example, -+@samp{2001-12-04 23:59}); -+but if the @env{POSIXLY_CORRECT} environment variable is set -+and the @env{LC_TIME} locale category specifies the @acronym{POSIX} -+locale, the default is @samp{%b %e %H:%M %Y} (for example, -+@samp{Dec@ @ 4 23:59 2001}. -+ -+@vindex TZ -+Time stamps are listed according to the time zone rules specified by -+the @env{TZ} environment variable, or by the system default rules if -+@env{TZ} is not set. @xref{TZ Variable,, Specifying the Time Zone -+with @env{TZ}, libc, The GNU C Library Reference Manual}. -+ -+@item -e[@var{in-tabchar}[@var{in-tabwidth}]] -+@itemx --expand-tabs[=@var{in-tabchar}[@var{in-tabwidth}]] -+@opindex -e -+@opindex --expand-tabs -+@cindex input tabs -+Expand @var{tab}s to spaces on input. Optional argument @var{in-tabchar} is -+the input tab character (default is the TAB character). Second optional -+argument @var{in-tabwidth} is the input tab character's width (default -+is 8). -+ -+@item -f -+@itemx -F -+@itemx --form-feed -+@opindex -F -+@opindex -f -+@opindex --form-feed -+Use a form feed instead of newlines to separate output pages. This does -+not alter the default page length of 66 lines. -+ -+@item -h @var{header} -+@itemx --header=@var{header} -+@opindex -h -+@opindex --header -+Replace the file name in the header with the centered string @var{header}. -+When using the shell, @var{header} should be quoted and should be -+separated from @option{-h} by a space. -+ -+@item -i[@var{out-tabchar}[@var{out-tabwidth}]] -+@itemx --output-tabs[=@var{out-tabchar}[@var{out-tabwidth}]] -+@opindex -i -+@opindex --output-tabs -+@cindex output tabs -+Replace spaces with @var{tab}s on output. Optional argument @var{out-tabchar} -+is the output tab character (default is the TAB character). Second optional -+argument @var{out-tabwidth} is the output tab character's width (default -+is 8). -+ -+@item -J -+@itemx --join-lines -+@opindex -J -+@opindex --join-lines -+Merge lines of full length. Used together with the column options -+@option{-@var{column}}, @option{-a -@var{column}} or @option{-m}. Turns off -+@option{-W/-w} line truncation; -+no column alignment used; may be used with -+@option{--sep-string[=@var{string}]}. @option{-J} has been introduced -+(together with @option{-W} and @option{--sep-string}) -+to disentangle the old (@acronym{POSIX}-compliant) options @option{-w} and -+@option{-s} along with the three column options. -+ -+ -+@item -l @var{page_length} -+@itemx --length=@var{page_length} -+@opindex -l -+@opindex --length -+Set the page length to @var{page_length} (default 66) lines, including -+the lines of the header [and the footer]. If @var{page_length} is less -+than or equal to 10, the header and footer are omitted, as if the -+@option{-t} option had been given. -+ -+@item -m -+@itemx --merge -+@opindex -m -+@opindex --merge -+Merge and print all @var{file}s in parallel, one in each column. If a -+line is too long to fit in a column, it is truncated, unless the @option{-J} -+option is used. @option{--sep-string[=@var{string}]} may be used. -+Empty pages in -+some @var{file}s (form feeds set) produce empty columns, still marked -+by @var{string}. The result is a continuous line numbering and column -+marking throughout the whole merged file. Completely empty merged pages -+show no separators or line numbers. The default header becomes -+@samp{@var{date} @var{page}} with spaces inserted in the middle; this -+may be used with the @option{-h} or @option{--header} option to fill up -+the middle blank part. -+ -+@item -n[@var{number-separator}[@var{digits}]] -+@itemx --number-lines[=@var{number-separator}[@var{digits}]] -+@opindex -n -+@opindex --number-lines -+Provide @var{digits} digit line numbering (default for @var{digits} is -+5). With multicolumn output the number occupies the first @var{digits} -+column positions of each text column or only each line of @option{-m} -+output. With single column output the number precedes each line just as -+@option{-m} does. Default counting of the line numbers starts with the -+first line of the input file (not the first line printed, compare the -+@option{--page} option and @option{-N} option). -+Optional argument @var{number-separator} is the character appended to -+the line number to separate it from the text followed. The default -+separator is the TAB character. In a strict sense a TAB is always -+printed with single column output only. The TAB width varies -+with the TAB position, e.g., with the left @var{margin} specified -+by @option{-o} option. With multicolumn output priority is given to -+@samp{equal width of output columns} (a @acronym{POSIX} specification). -+The TAB width is fixed to the value of the first column and does -+not change with different values of left @var{margin}. That means a -+fixed number of spaces is always printed in the place of the -+@var{number-separator} TAB. The tabification depends upon the output -+position. -+ -+@item -N @var{line_number} -+@itemx --first-line-number=@var{line_number} -+@opindex -N -+@opindex --first-line-number -+Start line counting with the number @var{line_number} at first line of -+first page printed (in most cases not the first line of the input file). -+ -+@item -o @var{margin} -+@itemx --indent=@var{margin} -+@opindex -o -+@opindex --indent -+@cindex indenting lines -+@cindex left margin -+Indent each line with a margin @var{margin} spaces wide (default is zero). -+The total page width is the size of the margin plus the @var{page_width} -+set with the @option{-W/-w} option. A limited overflow may occur with -+numbered single column output (compare @option{-n} option). -+ -+@item -r -+@itemx --no-file-warnings -+@opindex -r -+@opindex --no-file-warnings -+Do not print a warning message when an argument @var{file} cannot be -+opened. (The exit status will still be nonzero, however.) -+ -+@item -s[@var{char}] -+@itemx --separator[=@var{char}] -+@opindex -s -+@opindex --separator -+Separate columns by a single character @var{char}. The default for -+@var{char} is the TAB character without @option{-w} and @samp{no -+character} with @option{-w}. Without @option{-s} the default separator -+@samp{space} is set. @option{-s[char]} turns off line truncation of all -+three column options (@option{-COLUMN}|@option{-a -COLUMN}|@option{-m}) unless -+@option{-w} is set. This is a @acronym{POSIX}-compliant formulation. -+ -+ -+@item -S@var{string} -+@itemx --sep-string[=@var{string}] -+@opindex -S -+@opindex --sep-string -+Use @var{string} to separate output columns. The @option{-S} option doesn't -+affect the @option{-W/-w} option, unlike the @option{-s} option which does. It -+does not affect line truncation or column alignment. -+Without @option{-S}, and with @option{-J}, @command{pr} uses the default output -+separator, TAB@. -+Without @option{-S} or @option{-J}, @command{pr} uses a @samp{space} -+(same as @option{-S"@w{ }"}). @option{--sep-string} with no -+@samp{=@var{string}} is equivalent to @option{--sep-string=""}. -+ -+@item -t -+@itemx --omit-header -+@opindex -t -+@opindex --omit-header -+Do not print the usual header [and footer] on each page, and do not fill -+out the bottom of pages (with blank lines or a form feed). No page -+structure is produced, but form feeds set in the input files are retained. -+The predefined pagination is not changed. @option{-t} or @option{-T} may be -+useful together with other options; e.g.: @option{-t -e4}, expand TAB characters -+in the input file to 4 spaces but don't make any other changes. Use of -+@option{-t} overrides @option{-h}. -+ -+@item -T -+@itemx --omit-pagination -+@opindex -T -+@opindex --omit-pagination -+Do not print header [and footer]. In addition eliminate all form feeds -+set in the input files. -+ -+@item -v -+@itemx --show-nonprinting -+@opindex -v -+@opindex --show-nonprinting -+Print nonprinting characters in octal backslash notation. -+ -+@item -w @var{page_width} -+@itemx --width=@var{page_width} -+@opindex -w -+@opindex --width -+Set page width to @var{page_width} characters for multiple text-column -+output only (default for @var{page_width} is 72). @option{-s[CHAR]} turns -+off the default page width and any line truncation and column alignment. -+Lines of full length are merged, regardless of the column options -+set. No @var{page_width} setting is possible with single column output. -+A @acronym{POSIX}-compliant formulation. -+ -+@item -W @var{page_width} -+@itemx --page_width=@var{page_width} -+@opindex -W -+@opindex --page_width -+Set the page width to @var{page_width} characters. That's valid with and -+without a column option. Text lines are truncated, unless @option{-J} -+is used. Together with one of the three column options -+(@option{-@var{column}}, @option{-a -@var{column}} or @option{-m}) column -+alignment is always used. The separator options @option{-S} or @option{-s} -+don't affect the @option{-W} option. Default is 72 characters. Without -+@option{-W @var{page_width}} and without any of the column options NO line -+truncation is used (defined to keep downward compatibility and to meet -+most frequent tasks). That's equivalent to @option{-W 72 -J}. The header -+line is never truncated. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node fold invocation -+@section @command{fold}: Wrap input lines to fit in specified width -+ -+@pindex fold -+@cindex wrapping long input lines -+@cindex folding long input lines -+ -+@command{fold} writes each @var{file} (@option{-} means standard input), or -+standard input if none are given, to standard output, breaking long -+lines. Synopsis: -+ -+@example -+fold [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+By default, @command{fold} breaks lines wider than 80 columns. The output -+is split into as many lines as necessary. -+ -+@cindex screen columns -+@command{fold} counts screen columns by default; thus, a tab may count more -+than one column, backspace decreases the column count, and carriage -+return sets the column to zero. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -b -+@itemx --bytes -+@opindex -b -+@opindex --bytes -+Count bytes rather than columns, so that tabs, backspaces, and carriage -+returns are each counted as taking up one column, just like other -+characters. -+ -+@item -s -+@itemx --spaces -+@opindex -s -+@opindex --spaces -+Break at word boundaries: the line is broken after the last blank before -+the maximum line length. If the line contains no such blanks, the line -+is broken at the maximum line length as usual. -+ -+@item -w @var{width} -+@itemx --width=@var{width} -+@opindex -w -+@opindex --width -+Use a maximum line length of @var{width} columns instead of 80. -+ -+For compatibility @command{fold} supports an obsolete option syntax -+@option{-@var{width}}. New scripts should use @option{-w @var{width}} -+instead. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node Output of parts of files -+@chapter Output of parts of files -+ -+@cindex output of parts of files -+@cindex parts of files, output of -+ -+These commands output pieces of the input. -+ -+@menu -+* head invocation:: Output the first part of files. -+* tail invocation:: Output the last part of files. -+* split invocation:: Split a file into fixed-size pieces. -+* csplit invocation:: Split a file into context-determined pieces. -+@end menu -+ -+@node head invocation -+@section @command{head}: Output the first part of files -+ -+@pindex head -+@cindex initial part of files, outputting -+@cindex first part of files, outputting -+ -+@command{head} prints the first part (10 lines by default) of each -+@var{file}; it reads from standard input if no files are given or -+when given a @var{file} of @option{-}. Synopsis: -+ -+@example -+head [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+If more than one @var{file} is specified, @command{head} prints a -+one-line header consisting of: -+ -+@example -+==> @var{file name} <== -+@end example -+ -+@noindent -+before the output for each @var{file}. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -c @var{k} -+@itemx --bytes=@var{k} -+@opindex -c -+@opindex --bytes -+Print the first @var{k} bytes, instead of initial lines. -+However, if @var{k} starts with a @samp{-}, -+print all but the last @var{k} bytes of each file. -+@multiplierSuffixes{k} -+ -+@itemx -n @var{k} -+@itemx --lines=@var{k} -+@opindex -n -+@opindex --lines -+Output the first @var{k} lines. -+However, if @var{k} starts with a @samp{-}, -+print all but the last @var{k} lines of each file. -+Size multiplier suffixes are the same as with the @option{-c} option. -+ -+@item -q -+@itemx --quiet -+@itemx --silent -+@opindex -q -+@opindex --quiet -+@opindex --silent -+Never print file name headers. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Always print file name headers. -+ -+@end table -+ -+For compatibility @command{head} also supports an obsolete option syntax -+@option{-@var{count}@var{options}}, which is recognized only if it is -+specified first. @var{count} is a decimal number optionally followed -+by a size letter (@samp{b}, @samp{k}, @samp{m}) as in @option{-c}, or -+@samp{l} to mean count by lines, or other option letters (@samp{cqv}). -+Scripts intended for standard hosts should use @option{-c @var{count}} -+or @option{-n @var{count}} instead. If your script must also run on -+hosts that support only the obsolete syntax, it is usually simpler to -+avoid @command{head}, e.g., by using @samp{sed 5q} instead of -+@samp{head -5}. -+ -+@exitstatus -+ -+ -+@node tail invocation -+@section @command{tail}: Output the last part of files -+ -+@pindex tail -+@cindex last part of files, outputting -+ -+@command{tail} prints the last part (10 lines by default) of each -+@var{file}; it reads from standard input if no files are given or -+when given a @var{file} of @samp{-}. Synopsis: -+ -+@example -+tail [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+If more than one @var{file} is specified, @command{tail} prints a -+one-line header consisting of: -+ -+@example -+==> @var{file name} <== -+@end example -+ -+@noindent -+before the output for each @var{file}. -+ -+@cindex BSD @command{tail} -+@sc{gnu} @command{tail} can output any amount of data (some other versions of -+@command{tail} cannot). It also has no @option{-r} option (print in -+reverse), since reversing a file is really a different job from printing -+the end of a file; BSD @command{tail} (which is the one with @option{-r}) can -+only reverse files that are at most as large as its buffer, which is -+typically 32 KiB@. A more reliable and versatile way to reverse files is -+the @sc{gnu} @command{tac} command. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -c @var{k} -+@itemx --bytes=@var{k} -+@opindex -c -+@opindex --bytes -+Output the last @var{k} bytes, instead of final lines. -+However, if @var{k} starts with a @samp{+}, start printing with the -+@var{k}th byte from the start of each file, instead of from the end. -+@multiplierSuffixes{k} -+ -+@item -f -+@itemx --follow[=@var{how}] -+@opindex -f -+@opindex --follow -+@cindex growing files -+@vindex name @r{follow option} -+@vindex descriptor @r{follow option} -+Loop forever trying to read more characters at the end of the file, -+presumably because the file is growing. -+If more than one file is given, @command{tail} prints a header whenever it -+gets output from a different file, to indicate which file that output is -+from. -+ -+There are two ways to specify how you'd like to track files with this option, -+but that difference is noticeable only when a followed file is removed or -+renamed. -+If you'd like to continue to track the end of a growing file even after -+it has been unlinked, use @option{--follow=descriptor}. This is the default -+behavior, but it is not useful if you're tracking a log file that may be -+rotated (removed or renamed, then reopened). In that case, use -+@option{--follow=name} to track the named file by reopening it periodically -+to see if it has been removed and recreated by some other program. -+ -+No matter which method you use, if the tracked file is determined to have -+shrunk, @command{tail} prints a message saying the file has been truncated -+and resumes tracking the end of the file from the newly-determined endpoint. -+ -+When a file is removed, @command{tail}'s behavior depends on whether it is -+following the name or the descriptor. When following by name, tail can -+detect that a file has been removed and gives a message to that effect, -+and if @option{--retry} has been specified it will continue checking -+periodically to see if the file reappears. -+When following a descriptor, tail does not detect that the file has -+been unlinked or renamed and issues no message; even though the file -+may no longer be accessible via its original name, it may still be -+growing. -+ -+The option values @samp{descriptor} and @samp{name} may be specified only -+with the long form of the option, not with @option{-f}. -+ -+The @option{-f} option is ignored if -+no @var{file} operand is specified and standard input is a FIFO or a pipe. -+Likewise, the @option{-f} option has no effect for any -+operand specified as @samp{-}, when standard input is a FIFO or a pipe. -+ -+@item -F -+@opindex -F -+This option is the same as @option{--follow=name --retry}. That is, tail -+will attempt to reopen a file when it is removed. Should this fail, tail -+will keep trying until it becomes accessible again. -+ -+@itemx --retry -+@opindex --retry -+This option is useful mainly when following by name (i.e., with -+@option{--follow=name}). -+Without this option, when tail encounters a file that doesn't -+exist or is otherwise inaccessible, it reports that fact and -+never checks it again. -+ -+@itemx --sleep-interval=@var{number} -+@opindex --sleep-interval -+Change the number of seconds to wait between iterations (the default is 1.0). -+During one iteration, every specified file is checked to see if it has -+changed size. -+Historical implementations of @command{tail} have required that -+@var{number} be an integer. However, GNU @command{tail} accepts -+an arbitrary floating point number (using a period before any -+fractional digits). -+ -+@itemx --pid=@var{pid} -+@opindex --pid -+When following by name or by descriptor, you may specify the process ID, -+@var{pid}, of the sole writer of all @var{file} arguments. Then, shortly -+after that process terminates, tail will also terminate. This will -+work properly only if the writer and the tailing process are running on -+the same machine. For example, to save the output of a build in a file -+and to watch the file grow, if you invoke @command{make} and @command{tail} -+like this then the tail process will stop when your build completes. -+Without this option, you would have had to kill the @code{tail -f} -+process yourself. -+ -+@example -+$ make >& makerr & tail --pid=$! -f makerr -+@end example -+ -+If you specify a @var{pid} that is not in use or that does not correspond -+to the process that is writing to the tailed files, then @command{tail} -+may terminate long before any @var{file}s stop growing or it may not -+terminate until long after the real writer has terminated. -+Note that @option{--pid} cannot be supported on some systems; @command{tail} -+will print a warning if this is the case. -+ -+@itemx --max-unchanged-stats=@var{n} -+@opindex --max-unchanged-stats -+When tailing a file by name, if there have been @var{n} (default -+n=@value{DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS}) consecutive -+iterations for which the file has not changed, then -+@code{open}/@code{fstat} the file to determine if that file name is -+still associated with the same device/inode-number pair as before. -+When following a log file that is rotated, this is approximately the -+number of seconds between when tail prints the last pre-rotation lines -+and when it prints the lines that have accumulated in the new log file. -+This option is meaningful only when following by name. -+ -+@itemx -n @var{k} -+@itemx --lines=@var{k} -+@opindex -n -+@opindex --lines -+Output the last @var{k} lines. -+However, if @var{k} starts with a @samp{+}, start printing with the -+@var{k}th line from the start of each file, instead of from the end. -+Size multiplier suffixes are the same as with the @option{-c} option. -+ -+@item -q -+@itemx --quiet -+@itemx --silent -+@opindex -q -+@opindex --quiet -+@opindex --silent -+Never print file name headers. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Always print file name headers. -+ -+@end table -+ -+For compatibility @command{tail} also supports an obsolete usage -+@samp{tail -[@var{count}][bcl][f] [@var{file}]}, which is recognized -+only if it does not conflict with the usage described -+above. This obsolete form uses exactly one option and at most one -+file. In the option, @var{count} is an optional decimal number optionally -+followed by a size letter (@samp{b}, @samp{c}, @samp{l}) to mean count -+by 512-byte blocks, bytes, or lines, optionally followed by @samp{f} -+which has the same meaning as @option{-f}. -+ -+@vindex _POSIX2_VERSION -+On older systems, the leading @samp{-} can be replaced by @samp{+} in -+the obsolete option syntax with the same meaning as in counts, and -+obsolete usage overrides normal usage when the two conflict. -+This obsolete behavior can be enabled or disabled with the -+@env{_POSIX2_VERSION} environment variable (@pxref{Standards -+conformance}). -+ -+Scripts intended for use on standard hosts should avoid obsolete -+syntax and should use @option{-c @var{count}[b]}, @option{-n -+@var{count}}, and/or @option{-f} instead. If your script must also -+run on hosts that support only the obsolete syntax, you can often -+rewrite it to avoid problematic usages, e.g., by using @samp{sed -n -+'$p'} rather than @samp{tail -1}. If that's not possible, the script -+can use a test like @samp{if tail -c +1 /dev/null 2>&1; -+then @dots{}} to decide which syntax to use. -+ -+Even if your script assumes the standard behavior, you should still -+beware usages whose behaviors differ depending on the @acronym{POSIX} -+version. For example, avoid @samp{tail - main.c}, since it might be -+interpreted as either @samp{tail main.c} or as @samp{tail -- - -+main.c}; avoid @samp{tail -c 4}, since it might mean either @samp{tail -+-c4} or @samp{tail -c 10 4}; and avoid @samp{tail +4}, since it might -+mean either @samp{tail ./+4} or @samp{tail -n +4}. -+ -+@exitstatus -+ -+ -+@node split invocation -+@section @command{split}: Split a file into fixed-size pieces -+ -+@pindex split -+@cindex splitting a file into pieces -+@cindex pieces, splitting a file into -+ -+@command{split} creates output files containing consecutive sections of -+@var{input} (standard input if none is given or @var{input} is -+@samp{-}). Synopsis: -+ -+@example -+split [@var{option}] [@var{input} [@var{prefix}]] -+@end example -+ -+By default, @command{split} puts 1000 lines of @var{input} (or whatever is -+left over for the last section), into each output file. -+ -+@cindex output file name prefix -+The output files' names consist of @var{prefix} (@samp{x} by default) -+followed by a group of characters (@samp{aa}, @samp{ab}, @dots{} by -+default), such that concatenating the output files in traditional -+sorted order by file name produces -+the original input file. If the output file names are exhausted, -+@command{split} reports an error without deleting the output files -+that it did create. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -l @var{lines} -+@itemx --lines=@var{lines} -+@opindex -l -+@opindex --lines -+Put @var{lines} lines of @var{input} into each output file. -+ -+For compatibility @command{split} also supports an obsolete -+option syntax @option{-@var{lines}}. New scripts should use @option{-l -+@var{lines}} instead. -+ -+@item -b @var{size} -+@itemx --bytes=@var{size} -+@opindex -b -+@opindex --bytes -+Put @var{size} bytes of @var{input} into each output file. -+@multiplierSuffixes{size} -+ -+@item -C @var{size} -+@itemx --line-bytes=@var{size} -+@opindex -C -+@opindex --line-bytes -+Put into each output file as many complete lines of @var{input} as -+possible without exceeding @var{size} bytes. Individual lines longer than -+@var{size} bytes are broken into multiple files. -+@var{size} has the same format as for the @option{--bytes} option. -+ -+@item -a @var{length} -+@itemx --suffix-length=@var{length} -+@opindex -a -+@opindex --suffix-length -+Use suffixes of length @var{length}. The default @var{length} is 2. -+ -+@item -d -+@itemx --numeric-suffixes -+@opindex -d -+@opindex --numeric-suffixes -+Use digits in suffixes rather than lower-case letters. -+ -+@itemx --verbose -+@opindex --verbose -+Write a diagnostic just before each output file is opened. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node csplit invocation -+@section @command{csplit}: Split a file into context-determined pieces -+ -+@pindex csplit -+@cindex context splitting -+@cindex splitting a file into pieces by context -+ -+@command{csplit} creates zero or more output files containing sections of -+@var{input} (standard input if @var{input} is @samp{-}). Synopsis: -+ -+@example -+csplit [@var{option}]@dots{} @var{input} @var{pattern}@dots{} -+@end example -+ -+The contents of the output files are determined by the @var{pattern} -+arguments, as detailed below. An error occurs if a @var{pattern} -+argument refers to a nonexistent line of the input file (e.g., if no -+remaining line matches a given regular expression). After every -+@var{pattern} has been matched, any remaining input is copied into one -+last output file. -+ -+By default, @command{csplit} prints the number of bytes written to each -+output file after it has been created. -+ -+The types of pattern arguments are: -+ -+@table @samp -+ -+@item @var{n} -+Create an output file containing the input up to but not including line -+@var{n} (a positive integer). If followed by a repeat count, also -+create an output file containing the next @var{n} lines of the input -+file once for each repeat. -+ -+@item /@var{regexp}/[@var{offset}] -+Create an output file containing the current line up to (but not -+including) the next line of the input file that contains a match for -+@var{regexp}. The optional @var{offset} is an integer. -+If it is given, the input up to (but not including) the -+matching line plus or minus @var{offset} is put into the output file, -+and the line after that begins the next section of input. -+ -+@item %@var{regexp}%[@var{offset}] -+Like the previous type, except that it does not create an output -+file, so that section of the input file is effectively ignored. -+ -+@item @{@var{repeat-count}@} -+Repeat the previous pattern @var{repeat-count} additional -+times. The @var{repeat-count} can either be a positive integer or an -+asterisk, meaning repeat as many times as necessary until the input is -+exhausted. -+ -+@end table -+ -+The output files' names consist of a prefix (@samp{xx} by default) -+followed by a suffix. By default, the suffix is an ascending sequence -+of two-digit decimal numbers from @samp{00} to @samp{99}. In any case, -+concatenating the output files in sorted order by file name produces the -+original input file. -+ -+By default, if @command{csplit} encounters an error or receives a hangup, -+interrupt, quit, or terminate signal, it removes any output files -+that it has created so far before it exits. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -f @var{prefix} -+@itemx --prefix=@var{prefix} -+@opindex -f -+@opindex --prefix -+@cindex output file name prefix -+Use @var{prefix} as the output file name prefix. -+ -+@item -b @var{suffix} -+@itemx --suffix=@var{suffix} -+@opindex -b -+@opindex --suffix -+@cindex output file name suffix -+Use @var{suffix} as the output file name suffix. When this option is -+specified, the suffix string must include exactly one -+@code{printf(3)}-style conversion specification, possibly including -+format specification flags, a field width, a precision specifications, -+or all of these kinds of modifiers. The format letter must convert a -+binary integer argument to readable form; thus, only @samp{d}, @samp{i}, -+@samp{u}, @samp{o}, @samp{x}, and @samp{X} conversions are allowed. The -+entire @var{suffix} is given (with the current output file number) to -+@code{sprintf(3)} to form the file name suffixes for each of the -+individual output files in turn. If this option is used, the -+@option{--digits} option is ignored. -+ -+@item -n @var{digits} -+@itemx --digits=@var{digits} -+@opindex -n -+@opindex --digits -+Use output file names containing numbers that are @var{digits} digits -+long instead of the default 2. -+ -+@item -k -+@itemx --keep-files -+@opindex -k -+@opindex --keep-files -+Do not remove output files when errors are encountered. -+ -+@item -z -+@itemx --elide-empty-files -+@opindex -z -+@opindex --elide-empty-files -+Suppress the generation of zero-length output files. (In cases where -+the section delimiters of the input file are supposed to mark the first -+lines of each of the sections, the first output file will generally be a -+zero-length file unless you use this option.) The output file sequence -+numbers always run consecutively starting from 0, even when this option -+is specified. -+ -+@item -s -+@itemx -q -+@itemx --silent -+@itemx --quiet -+@opindex -s -+@opindex -q -+@opindex --silent -+@opindex --quiet -+Do not print counts of output file sizes. -+ -+@end table -+ -+@exitstatus -+ -+Here is an example of its usage. -+First, create an empty directory for the exercise, -+and cd into it: -+ -+@example -+$ mkdir d && cd d -+@end example -+ -+Now, split the sequence of 1..14 on lines that end with 0 or 5: -+ -+@example -+$ seq 14 | csplit - '/[05]$/' '@{*@}' -+8 -+10 -+15 -+@end example -+ -+Each number printed above is the size of an output -+file that csplit has just created. -+List the names of those output files: -+ -+@example -+$ ls -+xx00 xx01 xx02 -+@end example -+ -+Use @command{head} to show their contents: -+ -+@example -+$ head xx* -+==> xx00 <== -+1 -+2 -+3 -+4 -+ -+==> xx01 <== -+5 -+6 -+7 -+8 -+9 -+ -+==> xx02 <== -+10 -+11 -+12 -+13 -+14 -+@end example -+ -+@node Summarizing files -+@chapter Summarizing files -+ -+@cindex summarizing files -+ -+These commands generate just a few numbers representing entire -+contents of files. -+ -+@menu -+* wc invocation:: Print newline, word, and byte counts. -+* sum invocation:: Print checksum and block counts. -+* cksum invocation:: Print CRC checksum and byte counts. -+* md5sum invocation:: Print or check MD5 digests. -+* sha1sum invocation:: Print or check SHA-1 digests. -+* sha2 utilities:: Print or check SHA-2 digests. -+@end menu -+ -+ -+@node wc invocation -+@section @command{wc}: Print newline, word, and byte counts -+ -+@pindex wc -+@cindex byte count -+@cindex character count -+@cindex word count -+@cindex line count -+ -+@command{wc} counts the number of bytes, characters, whitespace-separated -+words, and newlines in each given @var{file}, or standard input if none -+are given or for a @var{file} of @samp{-}. Synopsis: -+ -+@example -+wc [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+@cindex total counts -+@command{wc} prints one line of counts for each file, and if the file was -+given as an argument, it prints the file name following the counts. If -+more than one @var{file} is given, @command{wc} prints a final line -+containing the cumulative counts, with the file name @file{total}. The -+counts are printed in this order: newlines, words, characters, bytes, -+maximum line length. -+Each count is printed right-justified in a field with at least one -+space between fields so that the numbers and file names normally line -+up nicely in columns. The width of the count fields varies depending -+on the inputs, so you should not depend on a particular field width. -+However, as a @acronym{GNU} extension, if only one count is printed, -+it is guaranteed to be printed without leading spaces. -+ -+By default, @command{wc} prints three counts: the newline, words, and byte -+counts. Options can specify that only certain counts be printed. -+Options do not undo others previously given, so -+ -+@example -+wc --bytes --words -+@end example -+ -+@noindent -+prints both the byte counts and the word counts. -+ -+With the @option{--max-line-length} option, @command{wc} prints the length -+of the longest line per file, and if there is more than one file it -+prints the maximum (not the sum) of those lengths. The line lengths here -+are measured in screen columns, according to the current locale and -+assuming tab positions in every 8th column. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -c -+@itemx --bytes -+@opindex -c -+@opindex --bytes -+Print only the byte counts. -+ -+@item -m -+@itemx --chars -+@opindex -m -+@opindex --chars -+Print only the character counts. -+ -+@item -w -+@itemx --words -+@opindex -w -+@opindex --words -+Print only the word counts. -+ -+@item -l -+@itemx --lines -+@opindex -l -+@opindex --lines -+Print only the newline counts. -+ -+@item -L -+@itemx --max-line-length -+@opindex -L -+@opindex --max-line-length -+Print only the maximum line lengths. -+ -+@macro filesZeroFromOption{cmd,withTotalOption,subListOutput} -+@itemx --files0-from=@var{file} -+@opindex --files0-from=@var{file} -+@c This is commented out to avoid a texi2dvi failure. -+@c texi2dvi (GNU Texinfo 4.11) 1.104 -+@c @cindex including files from @command{\cmd\} -+Disallow processing files named on the command line, and instead process -+those named in file @var{file}; each name being terminated by a zero byte -+(@acronym{ASCII} @sc{nul}). -+This is useful \withTotalOption\ -+when the list of file names is so long that it may exceed a command line -+length limitation. -+In such cases, running @command{\cmd\} via @command{xargs} is undesirable -+because it splits the list into pieces and makes @command{\cmd\} print -+\subListOutput\ for each sublist rather than for the entire list. -+One way to produce a list of @acronym{ASCII} @sc{nul} terminated file names is with @sc{gnu} -+@command{find}, using its @option{-print0} predicate. -+If @var{file} is @samp{-} then the @acronym{ASCII} @sc{nul} terminated file names -+are read from standard input. -+@end macro -+@filesZeroFromOption{wc,,a total} -+ -+For example, to find the length of the longest line in any @file{.c} or -+@file{.h} file in the current hierarchy, do this: -+ -+@example -+find . -name '*.[ch]' -print0 | -+ wc -L --files0-from=- | tail -n1 -+@end example -+ -+@end table -+ -+@exitstatus -+ -+ -+@node sum invocation -+@section @command{sum}: Print checksum and block counts -+ -+@pindex sum -+@cindex 16-bit checksum -+@cindex checksum, 16-bit -+ -+@command{sum} computes a 16-bit checksum for each given @var{file}, or -+standard input if none are given or for a @var{file} of @samp{-}. Synopsis: -+ -+@example -+sum [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+@command{sum} prints the checksum for each @var{file} followed by the -+number of blocks in the file (rounded up). If more than one @var{file} -+is given, file names are also printed (by default). (With the -+@option{--sysv} option, corresponding file names are printed when there is -+at least one file argument.) -+ -+By default, @sc{gnu} @command{sum} computes checksums using an algorithm -+compatible with BSD @command{sum} and prints file sizes in units of -+1024-byte blocks. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -r -+@opindex -r -+@cindex BSD @command{sum} -+Use the default (BSD compatible) algorithm. This option is included for -+compatibility with the System V @command{sum}. Unless @option{-s} was also -+given, it has no effect. -+ -+@item -s -+@itemx --sysv -+@opindex -s -+@opindex --sysv -+@cindex System V @command{sum} -+Compute checksums using an algorithm compatible with System V -+@command{sum}'s default, and print file sizes in units of 512-byte blocks. -+ -+@end table -+ -+@command{sum} is provided for compatibility; the @command{cksum} program (see -+next section) is preferable in new applications. -+ -+@exitstatus -+ -+ -+@node cksum invocation -+@section @command{cksum}: Print CRC checksum and byte counts -+ -+@pindex cksum -+@cindex cyclic redundancy check -+@cindex CRC checksum -+ -+@command{cksum} computes a cyclic redundancy check (CRC) checksum for each -+given @var{file}, or standard input if none are given or for a -+@var{file} of @samp{-}. Synopsis: -+ -+@example -+cksum [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+@command{cksum} prints the CRC checksum for each file along with the number -+of bytes in the file, and the file name unless no arguments were given. -+ -+@command{cksum} is typically used to ensure that files -+transferred by unreliable means (e.g., netnews) have not been corrupted, -+by comparing the @command{cksum} output for the received files with the -+@command{cksum} output for the original files (typically given in the -+distribution). -+ -+The CRC algorithm is specified by the @acronym{POSIX} standard. It is not -+compatible with the BSD or System V @command{sum} algorithms (see the -+previous section); it is more robust. -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. -+ -+@exitstatus -+ -+ -+@node md5sum invocation -+@section @command{md5sum}: Print or check MD5 digests -+ -+@pindex md5sum -+@cindex MD5 -+@cindex 128-bit checksum -+@cindex checksum, 128-bit -+@cindex fingerprint, 128-bit -+@cindex message-digest, 128-bit -+ -+@command{md5sum} computes a 128-bit checksum (or @dfn{fingerprint} or -+@dfn{message-digest}) for each specified @var{file}. -+ -+Note: The MD5 digest is more reliable than a simple CRC (provided by -+the @command{cksum} command) for detecting accidental file corruption, -+as the chances of accidentally having two files with identical MD5 -+are vanishingly small. However, it should not be considered truly -+secure against malicious tampering: although finding a file with a -+given MD5 fingerprint, or modifying a file so as to retain its MD5 are -+considered infeasible at the moment, it is known how to produce -+different files with identical MD5 (a ``collision''), something which -+can be a security issue in certain contexts. For more secure hashes, -+consider using SHA-1 or SHA-2. @xref{sha1sum invocation}, and -+@ref{sha2 utilities}. -+ -+If a @var{file} is specified as @samp{-} or if no files are given -+@command{md5sum} computes the checksum for the standard input. -+@command{md5sum} can also determine whether a file and checksum are -+consistent. Synopsis: -+ -+@example -+md5sum [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+For each @var{file}, @samp{md5sum} outputs the MD5 checksum, a flag -+indicating a binary or text input file, and the file name. -+If @var{file} contains a backslash or newline, the -+line is started with a backslash, and each problematic character in -+the file name is escaped with a backslash, making the output -+unambiguous even in the presence of arbitrary file names. -+If @var{file} is omitted or specified as @samp{-}, standard input is read. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -b -+@itemx --binary -+@opindex -b -+@opindex --binary -+@cindex binary input files -+Treat each input file as binary, by reading it in binary mode and -+outputting a @samp{*} flag. This is the inverse of @option{--text}. -+On systems like @acronym{GNU} that do not distinguish between binary -+and text files, this option merely flags each input file as binary: -+the MD5 checksum is unaffected. This option is the default on systems -+like MS-DOS that distinguish between binary and text files, except -+for reading standard input when standard input is a terminal. -+ -+@item -c -+@itemx --check -+Read file names and checksum information (not data) from each -+@var{file} (or from stdin if no @var{file} was specified) and report -+whether the checksums match the contents of the named files. -+The input to this mode of @command{md5sum} is usually the output of -+a prior, checksum-generating run of @samp{md5sum}. -+Each valid line of input consists of an MD5 checksum, a binary/text -+flag, and then a file name. -+Binary files are marked with @samp{*}, text with @samp{ }. -+For each such line, @command{md5sum} reads the named file and computes its -+MD5 checksum. Then, if the computed message digest does not match the -+one on the line with the file name, the file is noted as having -+failed the test. Otherwise, the file passes the test. -+By default, for each valid line, one line is written to standard -+output indicating whether the named file passed the test. -+After all checks have been performed, if there were any failures, -+a warning is issued to standard error. -+Use the @option{--status} option to inhibit that output. -+If any listed file cannot be opened or read, if any valid line has -+an MD5 checksum inconsistent with the associated file, or if no valid -+line is found, @command{md5sum} exits with nonzero status. Otherwise, -+it exits successfully. -+ -+@itemx --quiet -+@opindex --quiet -+@cindex verifying MD5 checksums -+This option is useful only when verifying checksums. -+When verifying checksums, don't generate an 'OK' message per successfully -+checked file. Files that fail the verification are reported in the -+default one-line-per-file format. If there is any checksum mismatch, -+print a warning summarizing the failures to standard error. -+ -+@itemx --status -+@opindex --status -+@cindex verifying MD5 checksums -+This option is useful only when verifying checksums. -+When verifying checksums, don't generate the default one-line-per-file -+diagnostic and don't output the warning summarizing any failures. -+Failures to open or read a file still evoke individual diagnostics to -+standard error. -+If all listed files are readable and are consistent with the associated -+MD5 checksums, exit successfully. Otherwise exit with a status code -+indicating there was a failure. -+ -+@item -t -+@itemx --text -+@opindex -t -+@opindex --text -+@cindex text input files -+Treat each input file as text, by reading it in text mode and -+outputting a @samp{ } flag. This is the inverse of @option{--binary}. -+This option is the default on systems like @acronym{GNU} that do not -+distinguish between binary and text files. On other systems, it is -+the default for reading standard input when standard input is a -+terminal. -+ -+@item -w -+@itemx --warn -+@opindex -w -+@opindex --warn -+@cindex verifying MD5 checksums -+When verifying checksums, warn about improperly formatted MD5 checksum lines. -+This option is useful only if all but a few lines in the checked input -+are valid. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node sha1sum invocation -+@section @command{sha1sum}: Print or check SHA-1 digests -+ -+@pindex sha1sum -+@cindex SHA-1 -+@cindex 160-bit checksum -+@cindex checksum, 160-bit -+@cindex fingerprint, 160-bit -+@cindex message-digest, 160-bit -+ -+@command{sha1sum} computes a 160-bit checksum for each specified -+@var{file}. The usage and options of this command are precisely the -+same as for @command{md5sum}. @xref{md5sum invocation}. -+ -+Note: The SHA-1 digest is more secure than MD5, and no collisions of -+it are known (different files having the same fingerprint). However, -+it is known that they can be produced with considerable, but not -+unreasonable, resources. For this reason, it is generally considered -+that SHA-1 should be gradually phased out in favor of the more secure -+SHA-2 hash algorithms. @xref{sha2 utilities}. -+ -+ -+@node sha2 utilities -+@section sha2 utilities: Print or check SHA-2 digests -+ -+@pindex sha224sum -+@pindex sha256sum -+@pindex sha384sum -+@pindex sha512sum -+@cindex SHA-2 -+@cindex 224-bit checksum -+@cindex 256-bit checksum -+@cindex 384-bit checksum -+@cindex 512-bit checksum -+@cindex checksum, 224-bit -+@cindex checksum, 256-bit -+@cindex checksum, 384-bit -+@cindex checksum, 512-bit -+@cindex fingerprint, 224-bit -+@cindex fingerprint, 256-bit -+@cindex fingerprint, 384-bit -+@cindex fingerprint, 512-bit -+@cindex message-digest, 224-bit -+@cindex message-digest, 256-bit -+@cindex message-digest, 384-bit -+@cindex message-digest, 512-bit -+ -+The commands @command{sha224sum}, @command{sha256sum}, -+@command{sha384sum} and @command{sha512sum} compute checksums of -+various lengths (respectively 224, 256, 384 and 512 bits), -+collectively known as the SHA-2 hashes. The usage and options of -+these commands are precisely the same as for @command{md5sum}. -+@xref{md5sum invocation}. -+ -+Note: The SHA384 and SHA512 digests are considerably slower to -+compute, especially on 32-bit computers, than SHA224 or SHA256. -+ -+ -+@node Operating on sorted files -+@chapter Operating on sorted files -+ -+@cindex operating on sorted files -+@cindex sorted files, operations on -+ -+These commands work with (or produce) sorted files. -+ -+@menu -+* sort invocation:: Sort text files. -+* shuf invocation:: Shuffle text files. -+* uniq invocation:: Uniquify files. -+* comm invocation:: Compare two sorted files line by line. -+* ptx invocation:: Produce a permuted index of file contents. -+* tsort invocation:: Topological sort. -+@end menu -+ -+ -+@node sort invocation -+@section @command{sort}: Sort text files -+ -+@pindex sort -+@cindex sorting files -+ -+@command{sort} sorts, merges, or compares all the lines from the given -+files, or standard input if none are given or for a @var{file} of -+@samp{-}. By default, @command{sort} writes the results to standard -+output. Synopsis: -+ -+@example -+sort [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+@command{sort} has three modes of operation: sort (the default), merge, -+and check for sortedness. The following options change the operation -+mode: -+ -+@table @samp -+ -+@item -c -+@itemx --check -+@itemx --check=diagnose-first -+@opindex -c -+@opindex --check -+@cindex checking for sortedness -+Check whether the given file is already sorted: if it is not all -+sorted, print a diagnostic containing the first out-of-order line and -+exit with a status of 1. -+Otherwise, exit successfully. -+At most one input file can be given. -+ -+@item -C -+@itemx --check=quiet -+@itemx --check=silent -+@opindex -c -+@opindex --check -+@cindex checking for sortedness -+Exit successfully if the given file is already sorted, and -+exit with status 1 otherwise. -+At most one input file can be given. -+This is like @option{-c}, except it does not print a diagnostic. -+ -+@item -m -+@itemx --merge -+@opindex -m -+@opindex --merge -+@cindex merging sorted files -+Merge the given files by sorting them as a group. Each input file must -+always be individually sorted. It always works to sort instead of -+merge; merging is provided because it is faster, in the case where it -+works. -+ -+@end table -+ -+@cindex sort stability -+@cindex sort's last-resort comparison -+A pair of lines is compared as follows: -+@command{sort} compares each pair of fields, in the -+order specified on the command line, according to the associated -+ordering options, until a difference is found or no fields are left. -+If no key fields are specified, @command{sort} uses a default key of -+the entire line. Finally, as a last resort when all keys compare -+equal, @command{sort} compares entire lines as if no ordering options -+other than @option{--reverse} (@option{-r}) were specified. The -+@option{--stable} (@option{-s}) option disables this @dfn{last-resort -+comparison} so that lines in which all fields compare equal are left -+in their original relative order. The @option{--unique} -+(@option{-u}) option also disables the last-resort comparison. -+ -+@vindex LC_ALL -+@vindex LC_COLLATE -+Unless otherwise specified, all comparisons use the character collating -+sequence specified by the @env{LC_COLLATE} locale.@footnote{If you -+use a non-@acronym{POSIX} locale (e.g., by setting @env{LC_ALL} -+to @samp{en_US}), then @command{sort} may produce output that is sorted -+differently than you're accustomed to. In that case, set the @env{LC_ALL} -+environment variable to @samp{C}. Note that setting only @env{LC_COLLATE} -+has two problems. First, it is ineffective if @env{LC_ALL} is also set. -+Second, it has undefined behavior if @env{LC_CTYPE} (or @env{LANG}, if -+@env{LC_CTYPE} is unset) is set to an incompatible value. For example, -+you get undefined behavior if @env{LC_CTYPE} is @code{ja_JP.PCK} but -+@env{LC_COLLATE} is @code{en_US.UTF-8}.} -+ -+@sc{gnu} @command{sort} (as specified for all @sc{gnu} utilities) has no -+limit on input line length or restrictions on bytes allowed within lines. -+In addition, if the final byte of an input file is not a newline, @sc{gnu} -+@command{sort} silently supplies one. A line's trailing newline is not -+part of the line for comparison purposes. -+ -+@cindex exit status of @command{sort} -+Exit status: -+ -+@display -+0 if no error occurred -+1 if invoked with @option{-c} or @option{-C} and the input is not sorted -+2 if an error occurred -+@end display -+ -+@vindex TMPDIR -+If the environment variable @env{TMPDIR} is set, @command{sort} uses its -+value as the directory for temporary files instead of @file{/tmp}. The -+@option{--temporary-directory} (@option{-T}) option in turn overrides -+the environment variable. -+ -+The following options affect the ordering of output lines. They may be -+specified globally or as part of a specific key field. If no key -+fields are specified, global options apply to comparison of entire -+lines; otherwise the global options are inherited by key fields that do -+not specify any special options of their own. In pre-@acronym{POSIX} -+versions of @command{sort}, global options affect only later key fields, -+so portable shell scripts should specify global options first. -+ -+@table @samp -+ -+@item -b -+@itemx --ignore-leading-blanks -+@opindex -b -+@opindex --ignore-leading-blanks -+@cindex blanks, ignoring leading -+@vindex LC_CTYPE -+Ignore leading blanks when finding sort keys in each line. -+By default a blank is a space or a tab, but the @env{LC_CTYPE} locale -+can change this. Note blanks may be ignored by your locale's collating -+rules, but without this option they will be significant for character -+positions specified in keys with the @option{-k} option. -+ -+@item -d -+@itemx --dictionary-order -+@opindex -d -+@opindex --dictionary-order -+@cindex dictionary order -+@cindex phone directory order -+@cindex telephone directory order -+@vindex LC_CTYPE -+Sort in @dfn{phone directory} order: ignore all characters except -+letters, digits and blanks when sorting. -+By default letters and digits are those of @acronym{ASCII} and a blank -+is a space or a tab, but the @env{LC_CTYPE} locale can change this. -+ -+@item -f -+@itemx --ignore-case -+@opindex -f -+@opindex --ignore-case -+@cindex ignoring case -+@cindex case folding -+@vindex LC_CTYPE -+Fold lowercase characters into the equivalent uppercase characters when -+comparing so that, for example, @samp{b} and @samp{B} sort as equal. -+The @env{LC_CTYPE} locale determines character types. -+When used with @option{--unique} those lower case equivalent lines are -+thrown away. (There is currently no way to throw away the upper case -+equivalent instead. (Any @option{--reverse} given would only affect -+the final result, after the throwing away.)) -+ -+@item -g -+@itemx --general-numeric-sort -+@itemx --sort=general-numeric -+@opindex -g -+@opindex --general-numeric-sort -+@opindex --sort -+@cindex general numeric sort -+@vindex LC_NUMERIC -+Sort numerically, using the standard C function @code{strtod} to convert -+a prefix of each line to a double-precision floating point number. -+This allows floating point numbers to be specified in scientific notation, -+like @code{1.0e-34} and @code{10e100}. -+The @env{LC_NUMERIC} locale determines the decimal-point character. -+Do not report overflow, underflow, or conversion errors. -+Use the following collating sequence: -+ -+@itemize @bullet -+@item -+Lines that do not start with numbers (all considered to be equal). -+@item -+NaNs (``Not a Number'' values, in IEEE floating point arithmetic) -+in a consistent but machine-dependent order. -+@item -+Minus infinity. -+@item -+Finite numbers in ascending numeric order (with @math{-0} and @math{+0} equal). -+@item -+Plus infinity. -+@end itemize -+ -+Use this option only if there is no alternative; it is much slower than -+@option{--numeric-sort} (@option{-n}) and it can lose information when -+converting to floating point. -+ -+@item -h -+@itemx --human-numeric-sort -+@itemx --sort=human-numeric -+@opindex -h -+@opindex --human-numeric-sort -+@opindex --sort -+@cindex human numeric sort -+@vindex LC_NUMERIC -+Sort numerically, as per the @option{--numeric-sort} option below, and in -+addition handle IEC or SI suffixes like MiB, MB etc (@ref{Block size}). -+Note a mixture of IEC and SI suffixes is not supported and will -+be flagged as an error. Also the numbers must be abbreviated uniformly. -+I.E. values with different precisions like 6000K and 5M will be sorted -+incorrectly. -+ -+@item -i -+@itemx --ignore-nonprinting -+@opindex -i -+@opindex --ignore-nonprinting -+@cindex nonprinting characters, ignoring -+@cindex unprintable characters, ignoring -+@vindex LC_CTYPE -+Ignore nonprinting characters. -+The @env{LC_CTYPE} locale determines character types. -+This option has no effect if the stronger @option{--dictionary-order} -+(@option{-d}) option is also given. -+ -+@item -M -+@itemx --month-sort -+@itemx --sort=month -+@opindex -M -+@opindex --month-sort -+@opindex --sort -+@cindex months, sorting by -+@vindex LC_TIME -+An initial string, consisting of any amount of blanks, followed -+by a month name abbreviation, is folded to UPPER case and -+compared in the order @samp{JAN} < @samp{FEB} < @dots{} < @samp{DEC}. -+Invalid names compare low to valid names. The @env{LC_TIME} locale -+category determines the month spellings. -+By default a blank is a space or a tab, but the @env{LC_CTYPE} locale -+can change this. -+ -+@item -n -+@itemx --numeric-sort -+@itemx --sort=numeric -+@opindex -n -+@opindex --numeric-sort -+@opindex --sort -+@cindex numeric sort -+@vindex LC_NUMERIC -+Sort numerically. The number begins each line and consists -+of optional blanks, an optional @samp{-} sign, and zero or more -+digits possibly separated by thousands separators, optionally followed -+by a decimal-point character and zero or more digits. An empty -+number is treated as @samp{0}. The @env{LC_NUMERIC} -+locale specifies the decimal-point character and thousands separator. -+By default a blank is a space or a tab, but the @env{LC_CTYPE} locale -+can change this. -+ -+Comparison is exact; there is no rounding error. -+ -+Neither a leading @samp{+} nor exponential notation is recognized. -+To compare such strings numerically, use the -+@option{--general-numeric-sort} (@option{-g}) option. -+ -+@item -V -+@itemx --version-sort -+@opindex -V -+@opindex --version-sort -+@cindex version number sort -+@vindex LC_NUMERIC -+Sort per @code{strverscmp(3)}. This is a normal string comparison, except -+that embedded decimal numbers are sorted by numeric value -+(see @option{--numeric-sort} above). -+ -+@item -r -+@itemx --reverse -+@opindex -r -+@opindex --reverse -+@cindex reverse sorting -+Reverse the result of comparison, so that lines with greater key values -+appear earlier in the output instead of later. -+ -+@item -R -+@itemx --random-sort -+@itemx --sort=random -+@opindex -R -+@opindex --random-sort -+@opindex --sort -+@cindex random sort -+Sort by hashing the input keys and then sorting the hash values. -+Choose the hash function at random, ensuring that it is free of -+collisions so that differing keys have differing hash values. This is -+like a random permutation of the inputs (@pxref{shuf invocation}), -+except that keys with the same value sort together. -+ -+If multiple random sort fields are specified, the same random hash -+function is used for all fields. To use different random hash -+functions for different fields, you can invoke @command{sort} more -+than once. -+ -+The choice of hash function is affected by the -+@option{--random-source} option. -+ -+@end table -+ -+Other options are: -+ -+@table @samp -+ -+@item --compress-program=@var{prog} -+Compress any temporary files with the program @var{prog}. -+ -+With no arguments, @var{prog} must compress standard input to standard -+output, and when given the @option{-d} option it must decompress -+standard input to standard output. -+ -+Terminate with an error if @var{prog} exits with nonzero status. -+ -+White space and the backslash character should not appear in -+@var{prog}; they are reserved for future use. -+ -+@filesZeroFromOption{sort,,sorted output} -+ -+@item -k @var{pos1}[,@var{pos2}] -+@itemx --key=@var{pos1}[,@var{pos2}] -+@opindex -k -+@opindex --key -+@cindex sort field -+Specify a sort field that consists of the part of the line between -+@var{pos1} and @var{pos2} (or the end of the line, if @var{pos2} is -+omitted), @emph{inclusive}. -+ -+Each @var{pos} has the form @samp{@var{f}[.@var{c}][@var{opts}]}, -+where @var{f} is the number of the field to use, and @var{c} is the number -+of the first character from the beginning of the field. Fields and character -+positions are numbered starting with 1; a character position of zero in -+@var{pos2} indicates the field's last character. If @samp{.@var{c}} is -+omitted from @var{pos1}, it defaults to 1 (the beginning of the field); -+if omitted from @var{pos2}, it defaults to 0 (the end of the field). -+@var{opts} are ordering options, allowing individual keys to be sorted -+according to different rules; see below for details. Keys can span -+multiple fields. -+ -+Example: To sort on the second field, use @option{--key=2,2} -+(@option{-k 2,2}). See below for more notes on keys and more examples. -+ -+@item --batch-size=@var{nmerge} -+@opindex --batch-size -+@cindex number of inputs to merge, nmerge -+Merge at most @var{nmerge} inputs at once. -+ -+When @command{sort} has to merge more than @var{nmerge} inputs, -+it merges them in groups of @var{nmerge}, saving the result in -+a temporary file, which is then used as an input in a subsequent merge. -+ -+A large value of @var{nmerge} may improve merge performance and decrease -+temporary storage utilization at the expense of increased memory usage -+and I/0. Conversely a small value of @var{nmerge} may reduce memory -+requirements and I/0 at the expense of temporary storage consumption and -+merge performance. -+ -+The value of @var{nmerge} must be at least 2. The default value is -+currently 16, but this is implementation-dependent and may change in -+the future. -+ -+The value of @var{nmerge} may be bounded by a resource limit for open -+file descriptors. The commands @samp{ulimit -n} or @samp{getconf -+OPEN_MAX} may display limits for your systems; these limits may be -+modified further if your program already has some files open, or if -+the operating system has other limits on the number of open files. If -+the value of @var{nmerge} exceeds the resource limit, @command{sort} -+silently uses a smaller value. -+ -+@item -o @var{output-file} -+@itemx --output=@var{output-file} -+@opindex -o -+@opindex --output -+@cindex overwriting of input, allowed -+Write output to @var{output-file} instead of standard output. -+Normally, @command{sort} reads all input before opening -+@var{output-file}, so you can safely sort a file in place by using -+commands like @code{sort -o F F} and @code{cat F | sort -o F}. -+However, @command{sort} with @option{--merge} (@option{-m}) can open -+the output file before reading all input, so a command like @code{cat -+F | sort -m -o F - G} is not safe as @command{sort} might start -+writing @file{F} before @command{cat} is done reading it. -+ -+@vindex POSIXLY_CORRECT -+On newer systems, @option{-o} cannot appear after an input file if -+@env{POSIXLY_CORRECT} is set, e.g., @samp{sort F -o F}. Portable -+scripts should specify @option{-o @var{output-file}} before any input -+files. -+ -+@item --random-source=@var{file} -+@opindex --random-source -+@cindex random source for sorting -+Use @var{file} as a source of random data used to determine which -+random hash function to use with the @option{-R} option. @xref{Random -+sources}. -+ -+@item -s -+@itemx --stable -+@opindex -s -+@opindex --stable -+@cindex sort stability -+@cindex sort's last-resort comparison -+ -+Make @command{sort} stable by disabling its last-resort comparison. -+This option has no effect if no fields or global ordering options -+other than @option{--reverse} (@option{-r}) are specified. -+ -+@item -S @var{size} -+@itemx --buffer-size=@var{size} -+@opindex -S -+@opindex --buffer-size -+@cindex size for main memory sorting -+Use a main-memory sort buffer of the given @var{size}. By default, -+@var{size} is in units of 1024 bytes. Appending @samp{%} causes -+@var{size} to be interpreted as a percentage of physical memory. -+Appending @samp{K} multiplies @var{size} by 1024 (the default), -+@samp{M} by 1,048,576, @samp{G} by 1,073,741,824, and so on for -+@samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}. Appending -+@samp{b} causes @var{size} to be interpreted as a byte count, with no -+multiplication. -+ -+This option can improve the performance of @command{sort} by causing it -+to start with a larger or smaller sort buffer than the default. -+However, this option affects only the initial buffer size. The buffer -+grows beyond @var{size} if @command{sort} encounters input lines larger -+than @var{size}. -+ -+@item -t @var{separator} -+@itemx --field-separator=@var{separator} -+@opindex -t -+@opindex --field-separator -+@cindex field separator character -+Use character @var{separator} as the field separator when finding the -+sort keys in each line. By default, fields are separated by the empty -+string between a non-blank character and a blank character. -+By default a blank is a space or a tab, but the @env{LC_CTYPE} locale -+can change this. -+ -+That is, given the input line @w{@samp{ foo bar}}, @command{sort} breaks it -+into fields @w{@samp{ foo}} and @w{@samp{ bar}}. The field separator is -+not considered to be part of either the field preceding or the field -+following, so with @samp{sort @w{-t " "}} the same input line has -+three fields: an empty field, @samp{foo}, and @samp{bar}. -+However, fields that extend to the end of the line, -+as @option{-k 2}, or fields consisting of a range, as @option{-k 2,3}, -+retain the field separators present between the endpoints of the range. -+ -+To specify @acronym{ASCII} @sc{nul} as the field separator, -+use the two-character string @samp{\0}, e.g., @samp{sort -t '\0'}. -+ -+@item -T @var{tempdir} -+@itemx --temporary-directory=@var{tempdir} -+@opindex -T -+@opindex --temporary-directory -+@cindex temporary directory -+@vindex TMPDIR -+Use directory @var{tempdir} to store temporary files, overriding the -+@env{TMPDIR} environment variable. If this option is given more than -+once, temporary files are stored in all the directories given. If you -+have a large sort or merge that is I/O-bound, you can often improve -+performance by using this option to specify directories on different -+disks and controllers. -+ -+@item -u -+@itemx --unique -+@opindex -u -+@opindex --unique -+@cindex uniquifying output -+ -+Normally, output only the first of a sequence of lines that compare -+equal. For the @option{--check} (@option{-c} or @option{-C}) option, -+check that no pair of consecutive lines compares equal. -+ -+This option also disables the default last-resort comparison. -+ -+The commands @code{sort -u} and @code{sort | uniq} are equivalent, but -+this equivalence does not extend to arbitrary @command{sort} options. -+For example, @code{sort -n -u} inspects only the value of the initial -+numeric string when checking for uniqueness, whereas @code{sort -n | -+uniq} inspects the entire line. @xref{uniq invocation}. -+ -+@macro zeroTerminatedOption -+@item -z -+@itemx --zero-terminated -+@opindex -z -+@opindex --zero-terminated -+@cindex process zero-terminated items -+Delimit items with a zero byte rather than a newline (@acronym{ASCII} @sc{lf}). -+I.E. treat input as items separated by @acronym{ASCII} @sc{nul} -+and terminate output items with @acronym{ASCII} @sc{nul}. -+This option can be useful in conjunction with @samp{perl -0} or -+@samp{find -print0} and @samp{xargs -0} which do the same in order to -+reliably handle arbitrary file names (even those containing blanks -+or other special characters). -+@end macro -+@zeroTerminatedOption -+ -+@end table -+ -+Historical (BSD and System V) implementations of @command{sort} have -+differed in their interpretation of some options, particularly -+@option{-b}, @option{-f}, and @option{-n}. @sc{gnu} sort follows the @acronym{POSIX} -+behavior, which is usually (but not always!) like the System V behavior. -+According to @acronym{POSIX}, @option{-n} no longer implies @option{-b}. For -+consistency, @option{-M} has been changed in the same way. This may -+affect the meaning of character positions in field specifications in -+obscure cases. The only fix is to add an explicit @option{-b}. -+ -+A position in a sort field specified with @option{-k} may have any -+of the option letters @samp{MbdfghinRrV} appended to it, in which case no -+global ordering options are inherited by that particular field. The -+@option{-b} option may be independently attached to either or both of -+the start and end positions of a field specification, and if it is -+inherited from the global options it will be attached to both. -+If input lines can contain leading or adjacent blanks and @option{-t} -+is not used, then @option{-k} is typically combined with @option{-b} or -+an option that implicitly ignores leading blanks (@samp{MghnV}) as otherwise -+the varying numbers of leading blanks in fields can cause confusing results. -+ -+If the start position in a sort field specifier falls after the end of -+the line or after the end field, the field is empty. If the @option{-b} -+option was specified, the @samp{.@var{c}} part of a field specification -+is counted from the first nonblank character of the field. -+ -+@vindex _POSIX2_VERSION -+@vindex POSIXLY_CORRECT -+On older systems, @command{sort} supports an obsolete origin-zero -+syntax @samp{+@var{pos1} [-@var{pos2}]} for specifying sort keys. -+This obsolete behavior can be enabled or disabled with the -+@env{_POSIX2_VERSION} environment variable (@pxref{Standards -+conformance}); it can also be enabled when @env{POSIXLY_CORRECT} is -+not set by using the obsolete syntax with @samp{-@var{pos2}} present. -+ -+Scripts intended for use on standard hosts should avoid obsolete -+syntax and should use @option{-k} instead. For example, avoid -+@samp{sort +2}, since it might be interpreted as either @samp{sort -+./+2} or @samp{sort -k 3}. If your script must also run on hosts that -+support only the obsolete syntax, it can use a test like @samp{if sort -+-k 1 /dev/null 2>&1; then @dots{}} to decide which syntax -+to use. -+ -+Here are some examples to illustrate various combinations of options. -+ -+@itemize @bullet -+ -+@item -+Sort in descending (reverse) numeric order. -+ -+@example -+sort -n -r -+@end example -+ -+@item -+Sort alphabetically, omitting the first and second fields -+and the blanks at the start of the third field. -+This uses a single key composed of the characters beginning -+at the start of the first nonblank character in field three -+and extending to the end of each line. -+ -+@example -+sort -k 3b -+@end example -+ -+@item -+Sort numerically on the second field and resolve ties by sorting -+alphabetically on the third and fourth characters of field five. -+Use @samp{:} as the field delimiter. -+ -+@example -+sort -t : -k 2,2n -k 5.3,5.4 -+@end example -+ -+Note that if you had written @option{-k 2n} instead of @option{-k 2,2n} -+@command{sort} would have used all characters beginning in the second field -+and extending to the end of the line as the primary @emph{numeric} -+key. For the large majority of applications, treating keys spanning -+more than one field as numeric will not do what you expect. -+ -+Also note that the @samp{n} modifier was applied to the field-end -+specifier for the first key. It would have been equivalent to -+specify @option{-k 2n,2} or @option{-k 2n,2n}. All modifiers except -+@samp{b} apply to the associated @emph{field}, regardless of whether -+the modifier character is attached to the field-start and/or the -+field-end part of the key specifier. -+ -+@item -+Sort the password file on the fifth field and ignore any -+leading blanks. Sort lines with equal values in field five -+on the numeric user ID in field three. Fields are separated -+by @samp{:}. -+ -+@example -+sort -t : -k 5b,5 -k 3,3n /etc/passwd -+sort -t : -n -k 5b,5 -k 3,3 /etc/passwd -+sort -t : -b -k 5,5 -k 3,3n /etc/passwd -+@end example -+ -+These three commands have equivalent effect. The first specifies that -+the first key's start position ignores leading blanks and the second -+key is sorted numerically. The other two commands rely on global -+options being inherited by sort keys that lack modifiers. The inheritance -+works in this case because @option{-k 5b,5b} and @option{-k 5b,5} are -+equivalent, as the location of a field-end lacking a @samp{.@var{c}} -+character position is not affected by whether initial blanks are -+skipped. -+ -+@item -+Sort a set of log files, primarily by IPv4 address and secondarily by -+time stamp. If two lines' primary and secondary keys are identical, -+output the lines in the same order that they were input. The log -+files contain lines that look like this: -+ -+@example -+4.150.156.3 - - [01/Apr/2004:06:31:51 +0000] message 1 -+211.24.3.231 - - [24/Apr/2004:20:17:39 +0000] message 2 -+@end example -+ -+Fields are separated by exactly one space. Sort IPv4 addresses -+lexicographically, e.g., 212.61.52.2 sorts before 212.129.233.201 -+because 61 is less than 129. -+ -+@example -+sort -s -t ' ' -k 4.9n -k 4.5M -k 4.2n -k 4.14,4.21 file*.log | -+sort -s -t '.' -k 1,1n -k 2,2n -k 3,3n -k 4,4n -+@end example -+ -+This example cannot be done with a single @command{sort} invocation, -+since IPv4 address components are separated by @samp{.} while dates -+come just after a space. So it is broken down into two invocations of -+@command{sort}: the first sorts by time stamp and the second by IPv4 -+address. The time stamp is sorted by year, then month, then day, and -+finally by hour-minute-second field, using @option{-k} to isolate each -+field. Except for hour-minute-second there's no need to specify the -+end of each key field, since the @samp{n} and @samp{M} modifiers sort -+based on leading prefixes that cannot cross field boundaries. The -+IPv4 addresses are sorted lexicographically. The second sort uses -+@samp{-s} so that ties in the primary key are broken by the secondary -+key; the first sort uses @samp{-s} so that the combination of the two -+sorts is stable. -+ -+@item -+Generate a tags file in case-insensitive sorted order. -+ -+@smallexample -+find src -type f -print0 | sort -z -f | xargs -0 etags --append -+@end smallexample -+ -+The use of @option{-print0}, @option{-z}, and @option{-0} in this case means -+that file names that contain blanks or other special characters are -+not broken up -+by the sort operation. -+ -+@c This example is a bit contrived and needs more explanation. -+@c @item -+@c Sort records separated by an arbitrary string by using a pipe to convert -+@c each record delimiter string to @samp{\0}, then using sort's -z option, -+@c and converting each @samp{\0} back to the original record delimiter. -+@c -+@c @example -+@c printf 'c\n\nb\n\na\n'|perl -0pe 's/\n\n/\n\0/g'|sort -z|perl -0pe 's/\0/\n/g' -+@c @end example -+ -+@item -+Use the common @acronym{DSU, Decorate Sort Undecorate} idiom to -+sort lines according to their length. -+ -+@example -+awk '@{print length, $0@}' /etc/passwd | sort -n | cut -f2- -d' ' -+@end example -+ -+In general this technique can be used to sort data that the @command{sort} -+command does not support, or is inefficient at, sorting directly. -+ -+@item -+Shuffle a list of directories, but preserve the order of files within -+each directory. For instance, one could use this to generate a music -+playlist in which albums are shuffled but the songs of each album are -+played in order. -+ -+@example -+ls */* | sort -t / -k 1,1R -k 2,2 -+@end example -+ -+@end itemize -+ -+ -+@node shuf invocation -+@section @command{shuf}: Shuffling text -+ -+@pindex shuf -+@cindex shuffling files -+ -+@command{shuf} shuffles its input by outputting a random permutation -+of its input lines. Each output permutation is equally likely. -+Synopses: -+ -+@example -+shuf [@var{option}]@dots{} [@var{file}] -+shuf -e [@var{option}]@dots{} [@var{arg}]@dots{} -+shuf -i @var{lo}-@var{hi} [@var{option}]@dots{} -+@end example -+ -+@command{shuf} has three modes of operation that affect where it -+obtains its input lines. By default, it reads lines from standard -+input. The following options change the operation mode: -+ -+@table @samp -+ -+@item -e -+@itemx --echo -+@opindex -c -+@opindex --echo -+@cindex command-line operands to shuffle -+Treat each command-line operand as an input line. -+ -+@item -i @var{lo}-@var{hi} -+@itemx --input-range=@var{lo}-@var{hi} -+@opindex -i -+@opindex --input-range -+@cindex input range to shuffle -+Act as if input came from a file containing the range of unsigned -+decimal integers @var{lo}@dots{}@var{hi}, one per line. -+ -+@end table -+ -+@command{shuf}'s other options can affect its behavior in all -+operation modes: -+ -+@table @samp -+ -+@item -n @var{lines} -+@itemx --head-count=@var{count} -+@opindex -n -+@opindex --head-count -+@cindex head of output -+Output at most @var{count} lines. By default, all input lines are -+output. -+ -+@item -o @var{output-file} -+@itemx --output=@var{output-file} -+@opindex -o -+@opindex --output -+@cindex overwriting of input, allowed -+Write output to @var{output-file} instead of standard output. -+@command{shuf} reads all input before opening -+@var{output-file}, so you can safely shuffle a file in place by using -+commands like @code{shuf -o F out -+$ dd bs=1 skip=222 count=6 < out 2>/dev/null; echo -+deeper -+@end example -+ -+Note that although the listing above includes a trailing slash -+for the @samp{deeper} entry, the offsets select the name without -+the trailing slash. However, if you invoke @command{ls} with @option{--dired} -+along with an option like @option{--escape} (aka @option{-b}) and operate -+on a file whose name contains special characters, notice that the backslash -+@emph{is} included: -+ -+@example -+$ touch 'a b' -+$ ls -blog --dired 'a b' -+ -rw-r--r-- 1 0 Jun 10 12:28 a\ b -+//DIRED// 30 34 -+//DIRED-OPTIONS// --quoting-style=escape -+@end example -+ -+If you use a quoting style that adds quote marks -+(e.g., @option{--quoting-style=c}), then the offsets include the quote marks. -+So beware that the user may select the quoting style via the environment -+variable @env{QUOTING_STYLE}. Hence, applications using @option{--dired} -+should either specify an explicit @option{--quoting-style=literal} option -+(aka @option{-N} or @option{--literal}) on the command line, or else be -+prepared to parse the escaped names. -+ -+@item --full-time -+@opindex --full-time -+Produce long format directory listings, and list times in full. It is -+equivalent to using @option{--format=long} with -+@option{--time-style=full-iso} (@pxref{Formatting file timestamps}). -+ -+@item -g -+@opindex -g -+Produce long format directory listings, but don't display owner information. -+ -+@item -G -+@itemx --no-group -+@opindex -G -+@opindex --no-group -+Inhibit display of group information in a long format directory listing. -+(This is the default in some non-@sc{gnu} versions of @command{ls}, so we -+provide this option for compatibility.) -+ -+@optHumanReadable -+ -+@item -i -+@itemx --inode -+@opindex -i -+@opindex --inode -+@cindex inode number, printing -+Print the inode number (also called the file serial number and index -+number) of each file to the left of the file name. (This number -+uniquely identifies each file within a particular file system.) -+ -+@item -l -+@itemx --format=long -+@itemx --format=verbose -+@opindex -l -+@opindex --format -+@opindex long ls @r{format} -+@opindex verbose ls @r{format} -+In addition to the name of each file, print the file type, file mode bits, -+number of hard links, owner name, group name, size, and -+timestamp (@pxref{Formatting file timestamps}), normally -+the modification time. Print question marks for information that -+cannot be determined. -+ -+Normally the size is printed as a byte count without punctuation, but -+this can be overridden (@pxref{Block size}). For example, @option{-h} -+prints an abbreviated, human-readable count, and -+@samp{--block-size="'1"} prints a byte count with the thousands -+separator of the current locale. -+ -+For each directory that is listed, preface the files with a line -+@samp{total @var{blocks}}, where @var{blocks} is the total disk allocation -+for all files in that directory. The block size currently defaults to 1024 -+bytes, but this can be overridden (@pxref{Block size}). -+The @var{blocks} computed counts each hard link separately; -+this is arguably a deficiency. -+ -+The file type is one of the following characters: -+ -+@c The commented-out entries are ones we're not sure about. -+ -+@table @samp -+@item - -+regular file -+@item b -+block special file -+@item c -+character special file -+@item C -+high performance (``contiguous data'') file -+@item d -+directory -+@item D -+door (Solaris 2.5 and up) -+@c @item F -+@c semaphore, if this is a distinct file type -+@item l -+symbolic link -+@c @item m -+@c multiplexed file (7th edition Unix; obsolete) -+@item M -+off-line (``migrated'') file (Cray DMF) -+@item n -+network special file (HP-UX) -+@item p -+FIFO (named pipe) -+@item P -+port (Solaris 10 and up) -+@c @item Q -+@c message queue, if this is a distinct file type -+@item s -+socket -+@c @item S -+@c shared memory object, if this is a distinct file type -+@c @item T -+@c typed memory object, if this is a distinct file type -+@c @item w -+@c whiteout (4.4BSD; not implemented) -+@item ? -+some other file type -+@end table -+ -+@cindex permissions, output by @command{ls} -+The file mode bits listed are similar to symbolic mode specifications -+(@pxref{Symbolic Modes}). But @command{ls} combines multiple bits into the -+third character of each set of permissions as follows: -+ -+@table @samp -+@item s -+If the set-user-ID or set-group-ID bit and the corresponding executable bit -+are both set. -+ -+@item S -+If the set-user-ID or set-group-ID bit is set but the corresponding -+executable bit is not set. -+ -+@item t -+If the restricted deletion flag or sticky bit, and the -+other-executable bit, are both set. The restricted deletion flag is -+another name for the sticky bit. @xref{Mode Structure}. -+ -+@item T -+If the restricted deletion flag or sticky bit is set but the -+other-executable bit is not set. -+ -+@item x -+If the executable bit is set and none of the above apply. -+ -+@item - -+Otherwise. -+@end table -+ -+Following the file mode bits is a single character that specifies -+whether an alternate access method such as an access control list -+applies to the file. When the character following the file mode bits is a -+space, there is no alternate access method. When it is a printing -+character, then there is such a method. -+ -+GNU @command{ls} uses a @samp{.} character to indicate a file -+with an SELinux security context, but no other alternate access method. -+ -+A file with any other combination of alternate access methods -+is marked with a @samp{+} character. -+ -+@item -n -+@itemx --numeric-uid-gid -+@opindex -n -+@opindex --numeric-uid-gid -+@cindex numeric uid and gid -+@cindex numeric user and group IDs -+Produce long format directory listings, but -+display numeric user and group IDs instead of the owner and group names. -+ -+@item -o -+@opindex -o -+Produce long format directory listings, but don't display group information. -+It is equivalent to using @option{--format=long} with @option{--no-group} . -+ -+@item -s -+@itemx --size -+@opindex -s -+@opindex --size -+@cindex disk allocation -+@cindex size of files, reporting -+Print the disk allocation of each file to the left of the file name. -+This is the amount of disk space used by the file, which is usually a -+bit more than the file's size, but it can be less if the file has holes. -+ -+Normally the disk allocation is printed in units of -+1024 bytes, but this can be overridden (@pxref{Block size}). -+ -+@cindex NFS mounts from BSD to HP-UX -+For files that are NFS-mounted from an HP-UX system to a BSD system, -+this option reports sizes that are half the correct values. On HP-UX -+systems, it reports sizes that are twice the correct values for files -+that are NFS-mounted from BSD systems. This is due to a flaw in HP-UX; -+it also affects the HP-UX @command{ls} program. -+ -+@optSi -+ -+@item -Z -+@itemx --context -+@opindex -Z -+@opindex --context -+@cindex SELinux -+@cindex security context -+Display the SELinux security context or @samp{?} if none is found. -+When used with the @option{-l} option, print the security context -+to the left of the size column. -+ -+@end table -+ -+ -+@node Sorting the output -+@subsection Sorting the output -+ -+@cindex sorting @command{ls} output -+These options change the order in which @command{ls} sorts the information -+it outputs. By default, sorting is done by character code -+(e.g., @acronym{ASCII} order). -+ -+@table @samp -+ -+@item -c -+@itemx --time=ctime -+@itemx --time=status -+@opindex -c -+@opindex --time -+@opindex ctime@r{, printing or sorting by} -+@opindex status time@r{, printing or sorting by} -+@opindex use time@r{, printing or sorting files by} -+If the long listing format (e.g., @option{-l}, @option{-o}) is being used, -+print the status change time (the @samp{ctime} in the inode) instead of -+the modification time. -+When explicitly sorting by time (@option{--sort=time} or @option{-t}) -+or when not using a long listing format, -+sort according to the status change time. -+ -+@item -f -+@opindex -f -+@cindex unsorted directory listing -+@cindex directory order, listing by -+Primarily, like @option{-U}---do not sort; list the files in whatever -+order they are stored in the directory. But also enable @option{-a} (list -+all files) and disable @option{-l}, @option{--color}, and @option{-s} (if they -+were specified before the @option{-f}). -+ -+@item -r -+@itemx --reverse -+@opindex -r -+@opindex --reverse -+@cindex reverse sorting -+Reverse whatever the sorting method is---e.g., list files in reverse -+alphabetical order, youngest first, smallest first, or whatever. -+ -+@item -S -+@itemx --sort=size -+@opindex -S -+@opindex --sort -+@opindex size of files@r{, sorting files by} -+Sort by file size, largest first. -+ -+@item -t -+@itemx --sort=time -+@opindex -t -+@opindex --sort -+@opindex modification time@r{, sorting files by} -+Sort by modification time (the @samp{mtime} in the inode), newest first. -+ -+@item -u -+@itemx --time=atime -+@itemx --time=access -+@itemx --time=use -+@opindex -u -+@opindex --time -+@opindex use time@r{, printing or sorting files by} -+@opindex atime@r{, printing or sorting files by} -+@opindex access time@r{, printing or sorting files by} -+If the long listing format (e.g., @option{--format=long}) is being used, -+print the last access time (the @samp{atime} in the inode). -+When explicitly sorting by time (@option{--sort=time} or @option{-t}) -+or when not using a long listing format, sort according to the access time. -+ -+@item -U -+@itemx --sort=none -+@opindex -U -+@opindex --sort -+@opindex none@r{, sorting option for @command{ls}} -+Do not sort; list the files in whatever order they are -+stored in the directory. (Do not do any of the other unrelated things -+that @option{-f} does.) This is especially useful when listing very large -+directories, since not doing any sorting can be noticeably faster. -+ -+@item -v -+@itemx --sort=version -+@opindex -v -+@opindex --sort -+@opindex version@r{, sorting option for @command{ls}} -+Sort by version name and number, lowest first. It behaves like a default -+sort, except that each sequence of decimal digits is treated numerically -+as an index/version number. (@xref{Details about version sort}.) -+ -+@item -X -+@itemx --sort=extension -+@opindex -X -+@opindex --sort -+@opindex extension@r{, sorting files by} -+Sort directory contents alphabetically by file extension (characters -+after the last @samp{.}); files with no extension are sorted first. -+ -+@end table -+ -+ -+@node Details about version sort -+@subsection Details about version sort -+ -+The version sort takes into account the fact that file names frequently include -+indices or version numbers. Standard sorting functions usually do not produce -+the ordering that people expect because comparisons are made on a -+character-by-character basis. The version -+sort addresses this problem, and is especially useful when browsing -+directories that contain many files with indices/version numbers in their -+names: -+ -+@example -+$ ls -1 $ ls -1v -+foo.zml-1.gz foo.zml-1.gz -+foo.zml-100.gz foo.zml-2.gz -+foo.zml-12.gz foo.zml-6.gz -+foo.zml-13.gz foo.zml-12.gz -+foo.zml-2.gz foo.zml-13.gz -+foo.zml-25.gz foo.zml-25.gz -+foo.zml-6.gz foo.zml-100.gz -+@end example -+ -+Version-sorted strings are compared such that if @var{ver1} and @var{ver2} -+are version numbers and @var{prefix} and @var{suffix} (@var{suffix} matching -+the regular expression @samp{(\.[A-Za-z~][A-Za-z0-9~]*)*}) are strings then -+@var{ver1} < @var{ver2} implies that the name composed of -+``@var{prefix} @var{ver1} @var{suffix}'' sorts before -+``@var{prefix} @var{ver2} @var{suffix}''. -+ -+Note also that leading zeros of numeric parts are ignored: -+ -+@example -+$ ls -1 $ ls -1v -+abc-1.007.tgz abc-1.01a.tgz -+abc-1.012b.tgz abc-1.007.tgz -+abc-1.01a.tgz abc-1.012b.tgz -+@end example -+ -+This functionality is implemented using gnulib's @code{filevercmp} function. -+One result of that implementation decision is that @samp{ls -v} -+and @samp{sort -V} do not use the locale category, @env{LC_COLLATE}, -+which means non-numeric prefixes are sorted as if @env{LC_COLLATE} were set -+to @samp{C}. -+ -+@node General output formatting -+@subsection General output formatting -+ -+These options affect the appearance of the overall output. -+ -+@table @samp -+ -+@item -1 -+@itemx --format=single-column -+@opindex -1 -+@opindex --format -+@opindex single-column @r{output of files} -+List one file per line. This is the default for @command{ls} when standard -+output is not a terminal. -+ -+@item -C -+@itemx --format=vertical -+@opindex -C -+@opindex --format -+@opindex vertical @r{sorted files in columns} -+List files in columns, sorted vertically. This is the default for -+@command{ls} if standard output is a terminal. It is always the default -+for the @command{dir} program. -+@sc{gnu} @command{ls} uses variable width columns to display as many files as -+possible in the fewest lines. -+ -+@item --color [=@var{when}] -+@opindex --color -+@cindex color, distinguishing file types with -+Specify whether to use color for distinguishing file types. @var{when} -+may be omitted, or one of: -+@itemize @bullet -+@item none -+@vindex none @r{color option} -+- Do not use color at all. This is the default. -+@item auto -+@vindex auto @r{color option} -+@cindex terminal, using color iff -+- Only use color if standard output is a terminal. -+@item always -+@vindex always @r{color option} -+- Always use color. -+@end itemize -+Specifying @option{--color} and no @var{when} is equivalent to -+@option{--color=always}. -+Piping a colorized listing through a pager like @command{more} or -+@command{less} usually produces unreadable results. However, using -+@code{more -f} does seem to work. -+ -+@item -F -+@itemx --classify -+@itemx --indicator-style=classify -+@opindex -F -+@opindex --classify -+@opindex --indicator-style -+@cindex file type and executables, marking -+@cindex executables and file type, marking -+Append a character to each file name indicating the file type. Also, -+for regular files that are executable, append @samp{*}. The file type -+indicators are @samp{/} for directories, @samp{@@} for symbolic links, -+@samp{|} for FIFOs, @samp{=} for sockets, @samp{>} for doors, -+and nothing for regular files. -+@c The following sentence is the same as the one for -d. -+Do not follow symbolic links listed on the -+command line unless the @option{--dereference-command-line} (@option{-H}), -+@option{--dereference} (@option{-L}), or -+@option{--dereference-command-line-symlink-to-dir} options are specified. -+ -+@item --file-type -+@itemx --indicator-style=file-type -+@opindex --file-type -+@opindex --indicator-style -+@cindex file type, marking -+Append a character to each file name indicating the file type. This is -+like @option{-F}, except that executables are not marked. -+ -+@item --indicator-style=@var{word} -+@opindex --indicator-style -+Append a character indicator with style @var{word} to entry names, -+as follows: -+ -+@table @samp -+@item none -+Do not append any character indicator; this is the default. -+@item slash -+Append @samp{/} for directories. This is the same as the @option{-p} -+option. -+@item file-type -+Append @samp{/} for directories, @samp{@@} for symbolic links, @samp{|} -+for FIFOs, @samp{=} for sockets, and nothing for regular files. This is -+the same as the @option{--file-type} option. -+@item classify -+Append @samp{*} for executable regular files, otherwise behave as for -+@samp{file-type}. This is the same as the @option{-F} or -+@option{--classify} option. -+@end table -+ -+@item -k -+@opindex -k -+Print file sizes in 1024-byte blocks, overriding the default block -+size (@pxref{Block size}). -+This option is equivalent to @option{--block-size=1K}. -+ -+@item -m -+@itemx --format=commas -+@opindex -m -+@opindex --format -+@opindex commas@r{, outputting between files} -+List files horizontally, with as many as will fit on each line, -+separated by @samp{, } (a comma and a space). -+ -+@item -p -+@itemx --indicator-style=slash -+@opindex -p -+@opindex --indicator-style -+@cindex file type, marking -+Append a @samp{/} to directory names. -+ -+@item -x -+@itemx --format=across -+@itemx --format=horizontal -+@opindex -x -+@opindex --format -+@opindex across@r{, listing files} -+@opindex horizontal@r{, listing files} -+List the files in columns, sorted horizontally. -+ -+@item -T @var{cols} -+@itemx --tabsize=@var{cols} -+@opindex -T -+@opindex --tabsize -+Assume that each tab stop is @var{cols} columns wide. The default is 8. -+@command{ls} uses tabs where possible in the output, for efficiency. If -+@var{cols} is zero, do not use tabs at all. -+ -+@c FIXME: remove in 2009, if Apple Terminal has been fixed for long enough. -+Some terminal emulators (at least Apple Terminal 1.5 (133) from Mac OS X 10.4.8) -+do not properly align columns to the right of a TAB following a -+non-@acronym{ASCII} byte. If you use such a terminal emulator, use the -+@option{-T0} option or put @code{TABSIZE=0} in your environment to tell -+@command{ls} to align using spaces, not tabs. -+ -+@item -w -+@itemx --width=@var{cols} -+@opindex -w -+@opindex --width -+@vindex COLUMNS -+Assume the screen is @var{cols} columns wide. The default is taken -+from the terminal settings if possible; otherwise the environment -+variable @env{COLUMNS} is used if it is set; otherwise the default -+is 80. -+ -+@end table -+ -+ -+@node Formatting file timestamps -+@subsection Formatting file timestamps -+ -+By default, file timestamps are listed in abbreviated form. Most -+locales use a timestamp like @samp{2002-03-30 23:45}. However, the -+default @acronym{POSIX} locale uses a date like @samp{Mar 30@ @ 2002} -+for non-recent timestamps, and a date-without-year and time like -+@samp{Mar 30 23:45} for recent timestamps. -+ -+A timestamp is considered to be @dfn{recent} if it is less than six -+months old, and is not dated in the future. If a timestamp dated -+today is not listed in recent form, the timestamp is in the future, -+which means you probably have clock skew problems which may break -+programs like @command{make} that rely on file timestamps. -+ -+@vindex TZ -+Time stamps are listed according to the time zone rules specified by -+the @env{TZ} environment variable, or by the system default rules if -+@env{TZ} is not set. @xref{TZ Variable,, Specifying the Time Zone -+with @env{TZ}, libc, The GNU C Library Reference Manual}. -+ -+The following option changes how file timestamps are printed. -+ -+@table @samp -+@item --time-style=@var{style} -+@opindex --time-style -+@cindex time style -+List timestamps in style @var{style}. The @var{style} should -+be one of the following: -+ -+@table @samp -+@item +@var{format} -+@vindex LC_TIME -+List timestamps using @var{format}, where @var{format} is interpreted -+like the format argument of @command{date} (@pxref{date invocation}). -+For example, @option{--time-style="+%Y-%m-%d %H:%M:%S"} causes -+@command{ls} to list timestamps like @samp{2002-03-30 23:45:56}. As -+with @command{date}, @var{format}'s interpretation is affected by the -+@env{LC_TIME} locale category. -+ -+If @var{format} contains two format strings separated by a newline, -+the former is used for non-recent files and the latter for recent -+files; if you want output columns to line up, you may need to insert -+spaces in one of the two formats. -+ -+@item full-iso -+List timestamps in full using @acronym{ISO} 8601 date, time, and time zone -+format with nanosecond precision, e.g., @samp{2002-03-30 -+23:45:56.477817180 -0700}. This style is equivalent to -+@samp{+%Y-%m-%d %H:%M:%S.%N %z}. -+ -+This is useful because the time output includes all the information that -+is available from the operating system. For example, this can help -+explain @command{make}'s behavior, since @acronym{GNU} @command{make} -+uses the full timestamp to determine whether a file is out of date. -+ -+@item long-iso -+List @acronym{ISO} 8601 date and time in minutes, e.g., -+@samp{2002-03-30 23:45}. These timestamps are shorter than -+@samp{full-iso} timestamps, and are usually good enough for everyday -+work. This style is equivalent to @samp{+%Y-%m-%d %H:%M}. -+ -+@item iso -+List @acronym{ISO} 8601 dates for non-recent timestamps (e.g., -+@samp{2002-03-30@ }), and @acronym{ISO} 8601 month, day, hour, and -+minute for recent timestamps (e.g., @samp{03-30 23:45}). These -+timestamps are uglier than @samp{long-iso} timestamps, but they carry -+nearly the same information in a smaller space and their brevity helps -+@command{ls} output fit within traditional 80-column output lines. -+The following two @command{ls} invocations are equivalent: -+ -+@example -+newline=' -+' -+ls -l --time-style="+%Y-%m-%d $newline%m-%d %H:%M" -+ls -l --time-style="iso" -+@end example -+ -+@item locale -+@vindex LC_TIME -+List timestamps in a locale-dependent form. For example, a Finnish -+locale might list non-recent timestamps like @samp{maalis 30@ @ 2002} -+and recent timestamps like @samp{maalis 30 23:45}. Locale-dependent -+timestamps typically consume more space than @samp{iso} timestamps and -+are harder for programs to parse because locale conventions vary so -+widely, but they are easier for many people to read. -+ -+The @env{LC_TIME} locale category specifies the timestamp format. The -+default @acronym{POSIX} locale uses timestamps like @samp{Mar 30@ -+@ 2002} and @samp{Mar 30 23:45}; in this locale, the following two -+@command{ls} invocations are equivalent: -+ -+@example -+newline=' -+' -+ls -l --time-style="+%b %e %Y$newline%b %e %H:%M" -+ls -l --time-style="locale" -+@end example -+ -+Other locales behave differently. For example, in a German locale, -+@option{--time-style="locale"} might be equivalent to -+@option{--time-style="+%e. %b %Y $newline%e. %b %H:%M"} -+and might generate timestamps like @samp{30. M@"ar 2002@ } and -+@samp{30. M@"ar 23:45}. -+ -+@item posix-@var{style} -+@vindex LC_TIME -+List @acronym{POSIX}-locale timestamps if the @env{LC_TIME} locale -+category is @acronym{POSIX}, @var{style} timestamps otherwise. For -+example, the @samp{posix-long-iso} style lists -+timestamps like @samp{Mar 30@ @ 2002} and @samp{Mar 30 23:45} when in -+the @acronym{POSIX} locale, and like @samp{2002-03-30 23:45} otherwise. -+@end table -+@end table -+ -+@vindex TIME_STYLE -+You can specify the default value of the @option{--time-style} option -+with the environment variable @env{TIME_STYLE}; if @env{TIME_STYLE} is not set -+the default style is @samp{locale}. @acronym{GNU} Emacs 21.3 and -+later use the @option{--dired} option and therefore can parse any date -+format, but if you are using Emacs 21.1 or 21.2 and specify a -+non-@acronym{POSIX} locale you may need to set -+@samp{TIME_STYLE="posix-long-iso"}. -+ -+To avoid certain denial-of-service attacks, timestamps that would be -+longer than 1000 bytes may be treated as errors. -+ -+ -+@node Formatting the file names -+@subsection Formatting the file names -+ -+These options change how file names themselves are printed. -+ -+@table @samp -+ -+@item -b -+@itemx --escape -+@itemx --quoting-style=escape -+@opindex -b -+@opindex --escape -+@opindex --quoting-style -+@cindex backslash sequences for file names -+Quote nongraphic characters in file names using alphabetic and octal -+backslash sequences like those used in C. -+ -+@item -N -+@itemx --literal -+@itemx --quoting-style=literal -+@opindex -N -+@opindex --literal -+@opindex --quoting-style -+Do not quote file names. However, with @command{ls} nongraphic -+characters are still printed as question marks if the output is a -+terminal and you do not specify the @option{--show-control-chars} -+option. -+ -+@item -q -+@itemx --hide-control-chars -+@opindex -q -+@opindex --hide-control-chars -+Print question marks instead of nongraphic characters in file names. -+This is the default if the output is a terminal and the program is -+@command{ls}. -+ -+@item -Q -+@itemx --quote-name -+@itemx --quoting-style=c -+@opindex -Q -+@opindex --quote-name -+@opindex --quoting-style -+Enclose file names in double quotes and quote nongraphic characters as -+in C. -+ -+@item --quoting-style=@var{word} -+@opindex --quoting-style -+@cindex quoting style -+Use style @var{word} to quote file names and other strings that may -+contain arbitrary characters. The @var{word} should -+be one of the following: -+ -+@table @samp -+@item literal -+Output strings as-is; this is the same as the @option{-N} or -+@option{--literal} option. -+@item shell -+Quote strings for the shell if they contain shell metacharacters or would -+cause ambiguous output. -+The quoting is suitable for @acronym{POSIX}-compatible shells like -+@command{bash}, but it does not always work for incompatible shells -+like @command{csh}. -+@item shell-always -+Quote strings for the shell, even if they would normally not require quoting. -+@item c -+Quote strings as for C character string literals, including the -+surrounding double-quote characters; this is the same as the -+@option{-Q} or @option{--quote-name} option. -+@item escape -+Quote strings as for C character string literals, except omit the -+surrounding double-quote -+characters; this is the same as the @option{-b} or @option{--escape} option. -+@item clocale -+Quote strings as for C character string literals, except use -+surrounding quotation marks appropriate for the -+locale. -+@item locale -+@c Use @t instead of @samp to avoid duplicate quoting in some output styles. -+Quote strings as for C character string literals, except use -+surrounding quotation marks appropriate for the locale, and quote -+@t{`like this'} instead of @t{"like -+this"} in the default C locale. This looks nicer on many displays. -+@end table -+ -+You can specify the default value of the @option{--quoting-style} option -+with the environment variable @env{QUOTING_STYLE}. If that environment -+variable is not set, the default value is @samp{literal}, but this -+default may change to @samp{shell} in a future version of this package. -+ -+@item --show-control-chars -+@opindex --show-control-chars -+Print nongraphic characters as-is in file names. -+This is the default unless the output is a terminal and the program is -+@command{ls}. -+ -+@end table -+ -+ -+@node dir invocation -+@section @command{dir}: Briefly list directory contents -+ -+@pindex dir -+@cindex directory listing, brief -+ -+@command{dir} is equivalent to @code{ls -C -+-b}; that is, by default files are listed in columns, sorted vertically, -+and special characters are represented by backslash escape sequences. -+ -+@xref{ls invocation, @command{ls}}. -+ -+ -+@node vdir invocation -+@section @command{vdir}: Verbosely list directory contents -+ -+@pindex vdir -+@cindex directory listing, verbose -+ -+@command{vdir} is equivalent to @code{ls -l -+-b}; that is, by default files are listed in long format and special -+characters are represented by backslash escape sequences. -+ -+@node dircolors invocation -+@section @command{dircolors}: Color setup for @command{ls} -+ -+@pindex dircolors -+@cindex color setup -+@cindex setup for color -+ -+@command{dircolors} outputs a sequence of shell commands to set up the -+terminal for color output from @command{ls} (and @command{dir}, etc.). -+Typical usage: -+ -+@example -+eval "`dircolors [@var{option}]@dots{} [@var{file}]`" -+@end example -+ -+If @var{file} is specified, @command{dircolors} reads it to determine which -+colors to use for which file types and extensions. Otherwise, a -+precompiled database is used. For details on the format of these files, -+run @samp{dircolors --print-database}. -+ -+To make @command{dircolors} read a @file{~/.dircolors} file if it -+exists, you can put the following lines in your @file{~/.bashrc} (or -+adapt them to your favorite shell): -+ -+@example -+d=.dircolors -+test -r $d && eval "$(dircolors $d)" -+@end example -+ -+@vindex LS_COLORS -+@vindex SHELL @r{environment variable, and color} -+The output is a shell command to set the @env{LS_COLORS} environment -+variable. You can specify the shell syntax to use on the command line, -+or @command{dircolors} will guess it from the value of the @env{SHELL} -+environment variable. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+@item -b -+@itemx --sh -+@itemx --bourne-shell -+@opindex -b -+@opindex --sh -+@opindex --bourne-shell -+@cindex Bourne shell syntax for color setup -+@cindex @command{sh} syntax for color setup -+Output Bourne shell commands. This is the default if the @env{SHELL} -+environment variable is set and does not end with @samp{csh} or -+@samp{tcsh}. -+ -+@item -c -+@itemx --csh -+@itemx --c-shell -+@opindex -c -+@opindex --csh -+@opindex --c-shell -+@cindex C shell syntax for color setup -+@cindex @command{csh} syntax for color setup -+Output C shell commands. This is the default if @code{SHELL} ends with -+@command{csh} or @command{tcsh}. -+ -+@item -p -+@itemx --print-database -+@opindex -p -+@opindex --print-database -+@cindex color database, printing -+@cindex database for color setup, printing -+@cindex printing color database -+Print the (compiled-in) default color configuration database. This -+output is itself a valid configuration file, and is fairly descriptive -+of the possibilities. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node Basic operations -+@chapter Basic operations -+ -+@cindex manipulating files -+ -+This chapter describes the commands for basic file manipulation: -+copying, moving (renaming), and deleting (removing). -+ -+@menu -+* cp invocation:: Copy files. -+* dd invocation:: Convert and copy a file. -+* install invocation:: Copy files and set attributes. -+* mv invocation:: Move (rename) files. -+* rm invocation:: Remove files or directories. -+* shred invocation:: Remove files more securely. -+@end menu -+ -+ -+@node cp invocation -+@section @command{cp}: Copy files and directories -+ -+@pindex cp -+@cindex copying files and directories -+@cindex files, copying -+@cindex directories, copying -+ -+@command{cp} copies files (or, optionally, directories). The copy is -+completely independent of the original. You can either copy one file to -+another, or copy arbitrarily many files to a destination directory. -+Synopses: -+ -+@example -+cp [@var{option}]@dots{} [-T] @var{source} @var{dest} -+cp [@var{option}]@dots{} @var{source}@dots{} @var{directory} -+cp [@var{option}]@dots{} -t @var{directory} @var{source}@dots{} -+@end example -+ -+@itemize @bullet -+@item -+If two file names are given, @command{cp} copies the first file to the -+second. -+ -+@item -+If the @option{--target-directory} (@option{-t}) option is given, or -+failing that if the last file is a directory and the -+@option{--no-target-directory} (@option{-T}) option is not given, -+@command{cp} copies each @var{source} file to the specified directory, -+using the @var{source}s' names. -+@end itemize -+ -+Generally, files are written just as they are read. For exceptions, -+see the @option{--sparse} option below. -+ -+By default, @command{cp} does not copy directories. However, the -+@option{-R}, @option{-a}, and @option{-r} options cause @command{cp} to -+copy recursively by descending into source directories and copying files -+to corresponding destination directories. -+ -+When copying from a symbolic link, @command{cp} normally follows the -+link only when not copying -+recursively. This default can be overridden with the -+@option{--archive} (@option{-a}), @option{-d}, @option{--dereference} -+(@option{-L}), @option{--no-dereference} (@option{-P}), and -+@option{-H} options. If more than one of these options is specified, -+the last one silently overrides the others. -+ -+When copying to a symbolic link, @command{cp} follows the -+link only when it refers to an existing regular file. -+However, when copying to a dangling symbolic link, @command{cp} -+refuses by default, and fails with a diagnostic, since the operation -+is inherently dangerous. This behavior is contrary to historical -+practice and to @acronym{POSIX}. -+Set @env{POSIXLY_CORRECT} to make @command{cp} attempt to create -+the target of a dangling destination symlink, in spite of the possible risk. -+Also, when an option like -+@option{--backup} or @option{--link} acts to rename or remove the -+destination before copying, @command{cp} renames or removes the -+symbolic link rather than the file it points to. -+ -+By default, @command{cp} copies the contents of special files only -+when not copying recursively. This default can be overridden with the -+@option{--copy-contents} option. -+ -+@cindex self-backups -+@cindex backups, making only -+@command{cp} generally refuses to copy a file onto itself, with the -+following exception: if @option{--force --backup} is specified with -+@var{source} and @var{dest} identical, and referring to a regular file, -+@command{cp} will make a backup file, either regular or numbered, as -+specified in the usual ways (@pxref{Backup options}). This is useful when -+you simply want to make a backup of an existing file before changing it. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+@item -a -+@itemx --archive -+@opindex -a -+@opindex --archive -+Preserve as much as possible of the structure and attributes of the -+original files in the copy (but do not attempt to preserve internal -+directory structure; i.e., @samp{ls -U} may list the entries in a copied -+directory in a different order). -+Try to preserve SELinux security context and extended attributes (xattr), -+but ignore any failure to do that and print no corresponding diagnostic. -+Equivalent to @option{-dR --preserve=all} with the reduced diagnostics. -+ -+@item -b -+@itemx @w{@kbd{--backup}[=@var{method}]} -+@opindex -b -+@opindex --backup -+@vindex VERSION_CONTROL -+@cindex backups, making -+@xref{Backup options}. -+Make a backup of each file that would otherwise be overwritten or removed. -+As a special case, @command{cp} makes a backup of @var{source} when the force -+and backup options are given and @var{source} and @var{dest} are the same -+name for an existing, regular file. One useful application of this -+combination of options is this tiny Bourne shell script: -+ -+@example -+#!/bin/sh -+# Usage: backup FILE... -+# Create a @sc{gnu}-style backup of each listed FILE. -+for i; do -+ cp --backup --force -- "$i" "$i" -+done -+@end example -+ -+@item --copy-contents -+@cindex directories, copying recursively -+@cindex copying directories recursively -+@cindex recursively copying directories -+@cindex non-directories, copying as special files -+If copying recursively, copy the contents of any special files (e.g., -+FIFOs and device files) as if they were regular files. This means -+trying to read the data in each source file and writing it to the -+destination. It is usually a mistake to use this option, as it -+normally has undesirable effects on special files like FIFOs and the -+ones typically found in the @file{/dev} directory. In most cases, -+@code{cp -R --copy-contents} will hang indefinitely trying to read -+from FIFOs and special files like @file{/dev/console}, and it will -+fill up your destination disk if you use it to copy @file{/dev/zero}. -+This option has no effect unless copying recursively, and it does not -+affect the copying of symbolic links. -+ -+@item -d -+@opindex -d -+@cindex symbolic links, copying -+@cindex hard links, preserving -+Copy symbolic links as symbolic links rather than copying the files that -+they point to, and preserve hard links between source files in the copies. -+Equivalent to @option{--no-dereference --preserve=links}. -+ -+@item -f -+@itemx --force -+@opindex -f -+@opindex --force -+When copying without this option and an existing destination file cannot -+be opened for writing, the copy fails. However, with @option{--force}), -+when a destination file cannot be opened, @command{cp} then removes it and -+tries to open it again. Contrast this behavior with that enabled by -+@option{--link} and @option{--symbolic-link}, whereby the destination file -+is never opened but rather is removed unconditionally. Also see the -+description of @option{--remove-destination}. -+ -+This option is independent of the @option{--interactive} or -+@option{-i} option: neither cancels the effect of the other. -+ -+This option is redundant if the @option{--no-clobber} or @option{-n} option is -+used. -+ -+@item -H -+@opindex -H -+If a command line argument specifies a symbolic link, then copy the -+file it points to rather than the symbolic link itself. However, -+copy (preserving its nature) any symbolic link that is encountered -+via recursive traversal. -+ -+@item -i -+@itemx --interactive -+@opindex -i -+@opindex --interactive -+When copying a file other than a directory, prompt whether to -+overwrite an existing destination file. The @option{-i} option overrides -+a previous @option{-n} option. -+ -+@item -l -+@itemx --link -+@opindex -l -+@opindex --link -+Make hard links instead of copies of non-directories. -+ -+@item -L -+@itemx --dereference -+@opindex -L -+@opindex --dereference -+Follow symbolic links when copying from them. -+With this option, @command{cp} cannot create a symbolic link. -+For example, a symlink (to regular file) in the source tree will be copied to -+a regular file in the destination tree. -+ -+@item -n -+@itemx --no-clobber -+@opindex -n -+@opindex --no-clobber -+Do not overwrite an existing file. The @option{-n} option overrides a previous -+@option{-i} option. This option is mutually exclusive with @option{-b} or -+@option{--backup} option. -+ -+@item -P -+@itemx --no-dereference -+@opindex -P -+@opindex --no-dereference -+@cindex symbolic links, copying -+Copy symbolic links as symbolic links rather than copying the files that -+they point to. This option affects only symbolic links in the source; -+symbolic links in the destination are always followed if possible. -+ -+@item -p -+@itemx @w{@kbd{--preserve}[=@var{attribute_list}]} -+@opindex -p -+@opindex --preserve -+@cindex file information, preserving, extended attributes, xattr -+Preserve the specified attributes of the original files. -+If specified, the @var{attribute_list} must be a comma-separated list -+of one or more of the following strings: -+ -+@table @samp -+@itemx mode -+Preserve the file mode bits and access control lists. -+@itemx ownership -+Preserve the owner and group. On most modern systems, -+only users with appropriate privileges may change the owner of a file, -+and ordinary users -+may preserve the group ownership of a file only if they happen to be -+a member of the desired group. -+@itemx timestamps -+Preserve the times of last access and last modification, when possible. -+On older systems, it is not possible to preserve these attributes -+when the affected file is a symbolic link. -+However, many systems now provide the @code{utimensat} function, -+which makes it possible even for symbolic links. -+@itemx links -+Preserve in the destination files -+any links between corresponding source files. -+Note that with @option{-L} or @option{-H}, this option can convert -+symbolic links to hard links. For example, -+@example -+$ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c -+74161745 a -+74161745 b -+@end example -+@noindent -+Note the inputs: @file{b} is a symlink to regular file @file{a}, -+yet the files in destination directory, @file{c/}, are hard-linked. -+Since @option{-a} implies @option{--preserve=links}, and since @option{-H} -+tells @command{cp} to dereference command line arguments, it sees two files -+with the same inode number, and preserves the perceived hard link. -+ -+Here is a similar example that exercises @command{cp}'s @option{-L} option: -+@smallexample -+$ mkdir b c; (cd b; : > a; ln -s a b); cp -aL b c; ls -i1 c/b -+74163295 a -+74163295 b -+@end smallexample -+ -+@itemx context -+Preserve SELinux security context of the file. @command{cp} will fail -+if the preserving of SELinux security context is not succesful. -+@itemx xattr -+Preserve extended attributes if @command{cp} is built with xattr support, -+and xattrs are supported and enabled on your file system. -+If SELinux context and/or ACLs are implemented using xattrs, -+they are preserved by this option as well. -+@itemx all -+Preserve all file attributes. -+Equivalent to specifying all of the above, but with the difference -+that failure to preserve SELinux security context or extended attributes -+does not change @command{cp}'s exit status. -+@command{cp} does diagnose such failures. -+@end table -+ -+Using @option{--preserve} with no @var{attribute_list} is equivalent -+to @option{--preserve=mode,ownership,timestamps}. -+ -+In the absence of this option, each destination file is created with the -+mode bits of the corresponding source file, minus the bits set in the -+umask and minus the set-user-ID and set-group-ID bits. -+@xref{File permissions}. -+ -+@itemx @w{@kbd{--no-preserve}=@var{attribute_list}} -+@cindex file information, preserving -+Do not preserve the specified attributes. The @var{attribute_list} -+has the same form as for @option{--preserve}. -+ -+@itemx --parents -+@opindex --parents -+@cindex parent directories and @command{cp} -+Form the name of each destination file by appending to the target -+directory a slash and the specified name of the source file. The last -+argument given to @command{cp} must be the name of an existing directory. -+For example, the command: -+ -+@example -+cp --parents a/b/c existing_dir -+@end example -+ -+@noindent -+copies the file @file{a/b/c} to @file{existing_dir/a/b/c}, creating -+any missing intermediate directories. -+ -+@item -R -+@itemx -r -+@itemx --recursive -+@opindex -R -+@opindex -r -+@opindex --recursive -+@cindex directories, copying recursively -+@cindex copying directories recursively -+@cindex recursively copying directories -+@cindex non-directories, copying as special files -+Copy directories recursively. By default, do not follow symbolic -+links in the source; see the @option{--archive} (@option{-a}), @option{-d}, -+@option{--dereference} (@option{-L}), @option{--no-dereference} -+(@option{-P}), and @option{-H} options. Special files are copied by -+creating a destination file of the same type as the source; see the -+@option{--copy-contents} option. It is not portable to use -+@option{-r} to copy symbolic links or special files. On some -+non-@sc{gnu} systems, @option{-r} implies the equivalent of -+@option{-L} and @option{--copy-contents} for historical reasons. -+Also, it is not portable to use @option{-R} to copy symbolic links -+unless you also specify @option{-P}, as @acronym{POSIX} allows -+implementations that dereference symbolic links by default. -+ -+@item --reflink[=@var{when}] -+@opindex --reflink[=@var{when}] -+@cindex COW -+@cindex clone -+@cindex copy on write -+Perform a lightweight, copy-on-write (COW) copy. -+Copying with this option can succeed only on some file systems. -+Once it has succeeded, beware that the source and destination files -+share the same disk data blocks as long as they remain unmodified. -+Thus, if a disk I/O error affects data blocks of one of the files, -+the other suffers the exact same fate. -+ -+The @var{when} value can be one of the following: -+ -+@table @samp -+@item always -+The default behavior: if the copy-on-write operation is not supported -+then report the failure for each file and exit with a failure status. -+ -+@item auto -+If the copy-on-write operation is not supported then fall back -+to the standard copy behaviour. -+@end table -+ -+ -+@item --remove-destination -+@opindex --remove-destination -+Remove each existing destination file before attempting to open it -+(contrast with @option{-f} above). -+ -+@item --sparse=@var{when} -+@opindex --sparse=@var{when} -+@cindex sparse files, copying -+@cindex holes, copying files with -+@findex read @r{system call, and holes} -+A @dfn{sparse file} contains @dfn{holes}---a sequence of zero bytes that -+does not occupy any physical disk blocks; the @samp{read} system call -+reads these as zeros. This can both save considerable disk space and -+increase speed, since many binary files contain lots of consecutive zero -+bytes. By default, @command{cp} detects holes in input source files via a crude -+heuristic and makes the corresponding output file sparse as well. -+Only regular files may be sparse. -+ -+The @var{when} value can be one of the following: -+ -+@table @samp -+@item auto -+The default behavior: if the input file is sparse, attempt to make -+the output file sparse, too. However, if an output file exists but -+refers to a non-regular file, then do not attempt to make it sparse. -+ -+@item always -+For each sufficiently long sequence of zero bytes in the input file, -+attempt to create a corresponding hole in the output file, even if the -+input file does not appear to be sparse. -+This is useful when the input file resides on a file system -+that does not support sparse files -+(for example, @samp{efs} file systems in SGI IRIX 5.3 and earlier), -+but the output file is on a type of file system that does support them. -+Holes may be created only in regular files, so if the destination file -+is of some other type, @command{cp} does not even try to make it sparse. -+ -+@item never -+Never make the output file sparse. -+This is useful in creating a file for use with the @command{mkswap} command, -+since such a file must not have any holes. -+@end table -+ -+@optStripTrailingSlashes -+ -+@item -s -+@itemx --symbolic-link -+@opindex -s -+@opindex --symbolic-link -+@cindex symbolic links, copying with -+Make symbolic links instead of copies of non-directories. All source -+file names must be absolute (starting with @samp{/}) unless the -+destination files are in the current directory. This option merely -+results in an error message on systems that do not support symbolic links. -+ -+@optBackupSuffix -+ -+@optTargetDirectory -+ -+@optNoTargetDirectory -+ -+@item -u -+@itemx --update -+@opindex -u -+@opindex --update -+@cindex newer files, copying only -+Do not copy a non-directory that has an existing destination with the -+same or newer modification time. If time stamps are being preserved, -+the comparison is to the source time stamp truncated to the -+resolutions of the destination file system and of the system calls -+used to update time stamps; this avoids duplicate work if several -+@samp{cp -pu} commands are executed with the same source and -+destination. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Print the name of each file before copying it. -+ -+@item -x -+@itemx --one-file-system -+@opindex -x -+@opindex --one-file-system -+@cindex file systems, omitting copying to different -+Skip subdirectories that are on different file systems from the one that -+the copy started on. -+However, mount point directories @emph{are} copied. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node dd invocation -+@section @command{dd}: Convert and copy a file -+ -+@pindex dd -+@cindex converting while copying a file -+ -+@command{dd} copies a file (from standard input to standard output, by -+default) with a changeable I/O block size, while optionally performing -+conversions on it. Synopses: -+ -+@example -+dd [@var{operand}]@dots{} -+dd @var{option} -+@end example -+ -+The only options are @option{--help} and @option{--version}. -+@xref{Common options}. @command{dd} accepts the following operands. -+ -+@table @samp -+ -+@item if=@var{file} -+@opindex if -+Read from @var{file} instead of standard input. -+ -+@item of=@var{file} -+@opindex of -+Write to @var{file} instead of standard output. Unless -+@samp{conv=notrunc} is given, @command{dd} truncates @var{file} to zero -+bytes (or the size specified with @samp{seek=}). -+ -+@item ibs=@var{bytes} -+@opindex ibs -+@cindex block size of input -+@cindex input block size -+Set the input block size to @var{bytes}. -+This makes @command{dd} read @var{bytes} per block. -+The default is 512 bytes. -+ -+@item obs=@var{bytes} -+@opindex obs -+@cindex block size of output -+@cindex output block size -+Set the output block size to @var{bytes}. -+This makes @command{dd} write @var{bytes} per block. -+The default is 512 bytes. -+ -+@item bs=@var{bytes} -+@opindex bs -+@cindex block size -+Set both input and output block sizes to @var{bytes}. -+This makes @command{dd} read and write @var{bytes} per block, -+overriding any @samp{ibs} and @samp{obs} settings. -+In addition, if no data-transforming @option{conv} option is specified, -+each input block is copied to the output as a single block, -+without aggregating short reads. -+ -+@item cbs=@var{bytes} -+@opindex cbs -+@cindex block size of conversion -+@cindex conversion block size -+@cindex fixed-length records, converting to variable-length -+@cindex variable-length records, converting to fixed-length -+Set the conversion block size to @var{bytes}. -+When converting variable-length records to fixed-length ones -+(@option{conv=block}) or the reverse (@option{conv=unblock}), -+use @var{bytes} as the fixed record length. -+ -+@item skip=@var{blocks} -+@opindex skip -+Skip @var{blocks} @samp{ibs}-byte blocks in the input file before copying. -+ -+@item seek=@var{blocks} -+@opindex seek -+Skip @var{blocks} @samp{obs}-byte blocks in the output file before copying. -+ -+@item count=@var{blocks} -+@opindex count -+Copy @var{blocks} @samp{ibs}-byte blocks from the input file, instead -+of everything until the end of the file. -+ -+@item status=noxfer -+@opindex status -+Do not print the overall transfer rate and volume statistics -+that normally make up the third status line when @command{dd} exits. -+ -+@item conv=@var{conversion}[,@var{conversion}]@dots{} -+@opindex conv -+Convert the file as specified by the @var{conversion} argument(s). -+(No spaces around any comma(s).) -+ -+Conversions: -+ -+@table @samp -+ -+@item ascii -+@opindex ascii@r{, converting to} -+Convert @acronym{EBCDIC} to @acronym{ASCII}, -+using the conversion table specified by @acronym{POSIX}. -+This provides a 1:1 translation for all 256 bytes. -+ -+@item ebcdic -+@opindex ebcdic@r{, converting to} -+Convert @acronym{ASCII} to @acronym{EBCDIC}. -+This is the inverse of the @samp{ascii} conversion. -+ -+@item ibm -+@opindex alternate ebcdic@r{, converting to} -+Convert @acronym{ASCII} to alternate @acronym{EBCDIC}, -+using the alternate conversion table specified by @acronym{POSIX}. -+This is not a 1:1 translation, but reflects common historical practice -+for @samp{~}, @samp{[}, and @samp{]}. -+ -+The @samp{ascii}, @samp{ebcdic}, and @samp{ibm} conversions are -+mutually exclusive. -+ -+@item block -+@opindex block @r{(space-padding)} -+For each line in the input, output @samp{cbs} bytes, replacing the -+input newline with a space and padding with spaces as necessary. -+ -+@item unblock -+@opindex unblock -+Remove any trailing spaces in each @samp{cbs}-sized input block, -+and append a newline. -+ -+The @samp{block} and @samp{unblock} conversions are mutually exclusive. -+ -+@item lcase -+@opindex lcase@r{, converting to} -+Change uppercase letters to lowercase. -+ -+@item ucase -+@opindex ucase@r{, converting to} -+Change lowercase letters to uppercase. -+ -+The @samp{lcase} and @samp{ucase} conversions are mutually exclusive. -+ -+@item swab -+@opindex swab @r{(byte-swapping)} -+@cindex byte-swapping -+Swap every pair of input bytes. @sc{gnu} @command{dd}, unlike others, works -+when an odd number of bytes are read---the last byte is simply copied -+(since there is nothing to swap it with). -+ -+@item noerror -+@opindex noerror -+@cindex read errors, ignoring -+Continue after read errors. -+ -+@item nocreat -+@opindex nocreat -+@cindex creating output file, avoiding -+Do not create the output file; the output file must already exist. -+ -+@item excl -+@opindex excl -+@cindex creating output file, requiring -+Fail if the output file already exists; @command{dd} must create the -+output file itself. -+ -+The @samp{excl} and @samp{nocreat} conversions are mutually exclusive. -+ -+@item notrunc -+@opindex notrunc -+@cindex truncating output file, avoiding -+Do not truncate the output file. -+ -+@item sync -+@opindex sync @r{(padding with @acronym{ASCII} @sc{nul}s)} -+Pad every input block to size of @samp{ibs} with trailing zero bytes. -+When used with @samp{block} or @samp{unblock}, pad with spaces instead of -+zero bytes. -+ -+@item fdatasync -+@opindex fdatasync -+@cindex synchronized data writes, before finishing -+Synchronize output data just before finishing. This forces a physical -+write of output data. -+ -+@item fsync -+@opindex fsync -+@cindex synchronized data and metadata writes, before finishing -+Synchronize output data and metadata just before finishing. This -+forces a physical write of output data and metadata. -+ -+@end table -+ -+@item iflag=@var{flag}[,@var{flag}]@dots{} -+@opindex iflag -+Access the input file using the flags specified by the @var{flag} -+argument(s). (No spaces around any comma(s).) -+ -+@item oflag=@var{flag}[,@var{flag}]@dots{} -+@opindex oflag -+Access the output file using the flags specified by the @var{flag} -+argument(s). (No spaces around any comma(s).) -+ -+Here are the flags. Not every flag is supported on every operating -+system. -+ -+@table @samp -+ -+@item append -+@opindex append -+@cindex appending to the output file -+Write in append mode, so that even if some other process is writing to -+this file, every @command{dd} write will append to the current -+contents of the file. This flag makes sense only for output. -+If you combine this flag with the @samp{of=@var{file}} operand, -+you should also specify @samp{conv=notrunc} unless you want the -+output file to be truncated before being appended to. -+ -+@item cio -+@opindex cio -+@cindex concurrent I/O -+Use concurrent I/O mode for data. This mode performs direct I/O -+and drops the @acronym{POSIX} requirement to serialize all I/O to the same file. -+A file cannot be opened in CIO mode and with a standard open at the -+same time. -+ -+@item direct -+@opindex direct -+@cindex direct I/O -+Use direct I/O for data, avoiding the buffer cache. -+Note that the kernel may impose restrictions on read or write buffer sizes. -+For example, with an ext4 destination file system and a linux-based kernel, -+using @samp{oflag=direct} will cause writes to fail with @code{EINVAL} if the -+output buffer size is not a multiple of 512. -+ -+@item directory -+@opindex directory -+@cindex directory I/O -+ -+Fail unless the file is a directory. Most operating systems do not -+allow I/O to a directory, so this flag has limited utility. -+ -+@item dsync -+@opindex dsync -+@cindex synchronized data reads -+Use synchronized I/O for data. For the output file, this forces a -+physical write of output data on each write. For the input file, -+this flag can matter when reading from a remote file that has been -+written to synchronously by some other process. Metadata (e.g., -+last-access and last-modified time) is not necessarily synchronized. -+ -+@item sync -+@opindex sync -+@cindex synchronized data and metadata I/O -+Use synchronized I/O for both data and metadata. -+ -+@item nonblock -+@opindex nonblock -+@cindex nonblocking I/O -+Use non-blocking I/O. -+ -+@item noatime -+@opindex noatime -+@cindex access time -+Do not update the file's access time. -+Some older file systems silently ignore this flag, so it is a good -+idea to test it on your files before relying on it. -+ -+@item noctty -+@opindex noctty -+@cindex controlling terminal -+Do not assign the file to be a controlling terminal for @command{dd}. -+This has no effect when the file is not a terminal. -+On many hosts (e.g., @acronym{GNU}/Linux hosts), this option has no effect -+at all. -+ -+@item nofollow -+@opindex nofollow -+@cindex symbolic links, following -+Do not follow symbolic links. -+ -+@item nolinks -+@opindex nolinks -+@cindex hard links -+Fail if the file has multiple hard links. -+ -+@item binary -+@opindex binary -+@cindex binary I/O -+Use binary I/O. This option has an effect only on nonstandard -+platforms that distinguish binary from text I/O. -+ -+@item text -+@opindex text -+@cindex text I/O -+Use text I/O. Like @samp{binary}, this option has no effect on -+standard platforms. -+ -+@item fullblock -+@opindex fullblock -+Accumulate full blocks from input. The @code{read} system call -+may return early if a full block is not available. -+When that happens, continue calling @code{read} to fill the remainder -+of the block. -+This flag can be used only with @code{iflag}. -+ -+@end table -+ -+These flags are not supported on all systems, and @samp{dd} rejects -+attempts to use them when they are not supported. When reading from -+standard input or writing to standard output, the @samp{nofollow} and -+@samp{noctty} flags should not be specified, and the other flags -+(e.g., @samp{nonblock}) can affect how other processes behave with the -+affected file descriptors, even after @command{dd} exits. -+ -+@end table -+ -+@cindex multipliers after numbers -+The numeric-valued strings above (@var{bytes} and @var{blocks}) can be -+followed by a multiplier: @samp{b}=512, @samp{c}=1, -+@samp{w}=2, @samp{x@var{m}}=@var{m}, or any of the -+standard block size suffixes like @samp{k}=1024 (@pxref{Block size}). -+ -+Use different @command{dd} invocations to use different block sizes for -+skipping and I/O@. For example, the following shell commands copy data -+in 512 KiB blocks between a disk and a tape, but do not save or restore a -+4 KiB label at the start of the disk: -+ -+@example -+disk=/dev/rdsk/c0t1d0s2 -+tape=/dev/rmt/0 -+ -+# Copy all but the label from disk to tape. -+(dd bs=4k skip=1 count=0 && dd bs=512k) <$disk >$tape -+ -+# Copy from tape back to disk, but leave the disk label alone. -+(dd bs=4k seek=1 count=0 && dd bs=512k) <$tape >$disk -+@end example -+ -+Sending an @samp{INFO} signal to a running @command{dd} -+process makes it print I/O statistics to standard error -+and then resume copying. In the example below, -+@command{dd} is run in the background to copy 10 million blocks. -+The @command{kill} command makes it output intermediate I/O statistics, -+and when @command{dd} completes normally or is killed by the -+@code{SIGINT} signal, it outputs the final statistics. -+ -+@example -+$ dd if=/dev/zero of=/dev/null count=10MB & pid=$! -+$ kill -s INFO $pid; wait $pid -+3385223+0 records in -+3385223+0 records out -+1733234176 bytes (1.7 GB) copied, 6.42173 seconds, 270 MB/s -+10000000+0 records in -+10000000+0 records out -+5120000000 bytes (5.1 GB) copied, 18.913 seconds, 271 MB/s -+@end example -+ -+@vindex POSIXLY_CORRECT -+On systems lacking the @samp{INFO} signal @command{dd} responds to the -+@samp{USR1} signal instead, unless the @env{POSIXLY_CORRECT} -+environment variable is set. -+ -+@exitstatus -+ -+ -+@node install invocation -+@section @command{install}: Copy files and set attributes -+ -+@pindex install -+@cindex copying files and setting attributes -+ -+@command{install} copies files while setting their file mode bits and, if -+possible, their owner and group. Synopses: -+ -+@example -+install [@var{option}]@dots{} [-T] @var{source} @var{dest} -+install [@var{option}]@dots{} @var{source}@dots{} @var{directory} -+install [@var{option}]@dots{} -t @var{directory} @var{source}@dots{} -+install [@var{option}]@dots{} -d @var{directory}@dots{} -+@end example -+ -+@itemize @bullet -+@item -+If two file names are given, @command{install} copies the first file to the -+second. -+ -+@item -+If the @option{--target-directory} (@option{-t}) option is given, or -+failing that if the last file is a directory and the -+@option{--no-target-directory} (@option{-T}) option is not given, -+@command{install} copies each @var{source} file to the specified -+directory, using the @var{source}s' names. -+ -+@item -+If the @option{--directory} (@option{-d}) option is given, -+@command{install} creates each @var{directory} and any missing parent -+directories. Parent directories are created with mode -+@samp{u=rwx,go=rx} (755), regardless of the @option{-m} option or the -+current umask. @xref{Directory Setuid and Setgid}, for how the -+set-user-ID and set-group-ID bits of parent directories are inherited. -+@end itemize -+ -+@cindex Makefiles, installing programs in -+@command{install} is similar to @command{cp}, but allows you to control the -+attributes of destination files. It is typically used in Makefiles to -+copy programs into their destination directories. It refuses to copy -+files onto themselves. -+ -+@cindex extended attributes, xattr -+@command{install} never preserves extended attributes (xattr). -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@optBackup -+ -+@item -C -+@itemx --compare -+@opindex -C -+@opindex --compare -+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. -+ -+@item -c -+@opindex -c -+Ignored; for compatibility with old Unix versions of @command{install}. -+ -+@item -D -+@opindex -D -+Create any missing parent directories of @var{dest}, -+then copy @var{source} to @var{dest}. -+This option is ignored if a destination directory is specified -+via @option{--target-directory=DIR}. -+ -+@item -d -+@itemx --directory -+@opindex -d -+@opindex --directory -+@cindex directories, creating with given attributes -+@cindex parent directories, creating missing -+@cindex leading directories, creating missing -+Create any missing parent directories, giving them the default -+attributes. Then create each given directory, setting their owner, -+group and mode as given on the command line or to the defaults. -+ -+@item -g @var{group} -+@itemx --group=@var{group} -+@opindex -g -+@opindex --group -+@cindex group ownership of installed files, setting -+Set the group ownership of installed files or directories to -+@var{group}. The default is the process's current group. @var{group} -+may be either a group name or a numeric group ID. -+ -+@item -m @var{mode} -+@itemx --mode=@var{mode} -+@opindex -m -+@opindex --mode -+@cindex permissions of installed files, setting -+Set the file mode bits for the installed file or directory to @var{mode}, -+which can be either an octal number, or a symbolic mode as in -+@command{chmod}, with @samp{a=} (no access allowed to anyone) as the -+point of departure (@pxref{File permissions}). -+The default mode is @samp{u=rwx,go=rx,a-s}---read, write, and -+execute for the owner, read and execute for group and other, and with -+set-user-ID and set-group-ID disabled. -+This default is not quite the same as @samp{755}, since it disables -+instead of preserving set-user-ID and set-group-ID on directories. -+@xref{Directory Setuid and Setgid}. -+ -+@item -o @var{owner} -+@itemx --owner=@var{owner} -+@opindex -o -+@opindex --owner -+@cindex ownership of installed files, setting -+@cindex appropriate privileges -+@vindex root @r{as default owner} -+If @command{install} has appropriate privileges (is run as root), set the -+ownership of installed files or directories to @var{owner}. The default -+is @code{root}. @var{owner} may be either a user name or a numeric user -+ID. -+ -+@item --preserve-context -+@opindex --preserve-context -+@cindex SELinux -+@cindex security context -+Preserve the SELinux security context of files and directories. -+Failure to preserve the context in all of the files or directories -+will result in an exit status of 1. If SELinux is disabled then -+print a warning and ignore the option. -+ -+@item -p -+@itemx --preserve-timestamps -+@opindex -p -+@opindex --preserve-timestamps -+@cindex timestamps of installed files, preserving -+Set the time of last access and the time of last modification of each -+installed file to match those of each corresponding original file. -+When a file is installed without this option, its last access and -+last modification times are both set to the time of installation. -+This option is useful if you want to use the last modification times -+of installed files to keep track of when they were last built as opposed -+to when they were last installed. -+ -+@item -s -+@itemx --strip -+@opindex -s -+@opindex --strip -+@cindex symbol table information, stripping -+@cindex stripping symbol table information -+Strip the symbol tables from installed binary executables. -+ -+@itemx --strip-program=@var{program} -+@opindex --strip-program -+@cindex symbol table information, stripping, program -+Program used to strip binaries. -+ -+@optBackupSuffix -+ -+@optTargetDirectory -+ -+@optNoTargetDirectory -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Print the name of each file before copying it. -+ -+@item -Z @var{context} -+@itemx --context=@var{context} -+@opindex -Z -+@opindex --context -+@cindex SELinux -+@cindex security context -+Set the default SELinux security context to be used for any -+created files and directories. If SELinux is disabled then -+print a warning and ignore the option. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node mv invocation -+@section @command{mv}: Move (rename) files -+ -+@pindex mv -+ -+@command{mv} moves or renames files (or directories). Synopses: -+ -+@example -+mv [@var{option}]@dots{} [-T] @var{source} @var{dest} -+mv [@var{option}]@dots{} @var{source}@dots{} @var{directory} -+mv [@var{option}]@dots{} -t @var{directory} @var{source}@dots{} -+@end example -+ -+@itemize @bullet -+@item -+If two file names are given, @command{mv} moves the first file to the -+second. -+ -+@item -+If the @option{--target-directory} (@option{-t}) option is given, or -+failing that if the last file is a directory and the -+@option{--no-target-directory} (@option{-T}) option is not given, -+@command{mv} moves each @var{source} file to the specified -+directory, using the @var{source}s' names. -+@end itemize -+ -+@command{mv} can move any type of file from one file system to another. -+Prior to version @code{4.0} of the fileutils, -+@command{mv} could move only regular files between file systems. -+For example, now @command{mv} can move an entire directory hierarchy -+including special device files from one partition to another. It first -+uses some of the same code that's used by @code{cp -a} to copy the -+requested directories and files, then (assuming the copy succeeded) -+it removes the originals. If the copy fails, then the part that was -+copied to the destination partition is removed. If you were to copy -+three directories from one partition to another and the copy of the first -+directory succeeded, but the second didn't, the first would be left on -+the destination partition and the second and third would be left on the -+original partition. -+ -+@cindex extended attributes, xattr -+@command{mv} always tries to copy extended attributes (xattr). -+ -+@cindex prompting, and @command{mv} -+If a destination file exists but is normally unwritable, standard input -+is a terminal, and the @option{-f} or @option{--force} option is not given, -+@command{mv} prompts the user for whether to replace the file. (You might -+own the file, or have write permission on its directory.) If the -+response is not affirmative, the file is skipped. -+ -+@emph{Warning}: Avoid specifying a source name with a trailing slash, -+when it might be a symlink to a directory. -+Otherwise, @command{mv} may do something very surprising, since -+its behavior depends on the underlying rename system call. -+On a system with a modern Linux-based kernel, it fails with @code{errno=ENOTDIR}. -+However, on other systems (at least FreeBSD 6.1 and Solaris 10) it silently -+renames not the symlink but rather the directory referenced by the symlink. -+@xref{Trailing slashes}. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@optBackup -+ -+@item -f -+@itemx --force -+@opindex -f -+@opindex --force -+@cindex prompts, omitting -+Do not prompt the user before removing a destination file. -+@macro mvOptsIfn -+If you specify more than one of the @option{-i}, @option{-f}, @option{-n} -+options, only the final one takes effect. -+@end macro -+@mvOptsIfn -+ -+@item -i -+@itemx --interactive -+@opindex -i -+@opindex --interactive -+@cindex prompts, forcing -+Prompt whether to overwrite each existing destination file, regardless -+of its permissions. -+If the response is not affirmative, the file is skipped. -+@mvOptsIfn -+ -+@item -n -+@itemx --no-clobber -+@opindex -n -+@opindex --no-clobber -+@cindex prompts, omitting -+Do not overwrite an existing file. -+@mvOptsIfn -+This option is mutually exclusive with @option{-b} or @option{--backup} option. -+ -+@item -u -+@itemx --update -+@opindex -u -+@opindex --update -+@cindex newer files, moving only -+Do not move a non-directory that has an existing destination with the -+same or newer modification time. -+If the move is across file system boundaries, the comparison is to the -+source time stamp truncated to the resolutions of the destination file -+system and of the system calls used to update time stamps; this avoids -+duplicate work if several @samp{mv -u} commands are executed with the -+same source and destination. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Print the name of each file before moving it. -+ -+@optStripTrailingSlashes -+ -+@optBackupSuffix -+ -+@optTargetDirectory -+ -+@optNoTargetDirectory -+ -+@end table -+ -+@exitstatus -+ -+ -+@node rm invocation -+@section @command{rm}: Remove files or directories -+ -+@pindex rm -+@cindex removing files or directories -+ -+@command{rm} removes each given @var{file}. By default, it does not remove -+directories. Synopsis: -+ -+@example -+rm [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+@cindex prompting, and @command{rm} -+If the @option{-I} or @option{--interactive=once} option is given, -+and there are more than three files or the @option{-r}, @option{-R}, -+or @option{--recursive} are given, then @command{rm} prompts the user -+for whether to proceed with the entire operation. If the response is -+not affirmative, the entire command is aborted. -+ -+Otherwise, if a file is unwritable, standard input is a terminal, and -+the @option{-f} or @option{--force} option is not given, or the -+@option{-i} or @option{--interactive=always} option @emph{is} given, -+@command{rm} prompts the user for whether to remove the file. -+If the response is not affirmative, the file is skipped. -+ -+Any attempt to remove a file whose last file name component is -+@file{.} or @file{..} is rejected without any prompting. -+ -+@emph{Warning}: If you use @command{rm} to remove a file, it is usually -+possible to recover the contents of that file. If you want more assurance -+that the contents are truly unrecoverable, consider using @command{shred}. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -f -+@itemx --force -+@opindex -f -+@opindex --force -+Ignore nonexistent files and never prompt the user. -+Ignore any previous @option{--interactive} (@option{-i}) option. -+ -+@item -i -+@opindex -i -+Prompt whether to remove each file. -+If the response is not affirmative, the file is skipped. -+Ignore any previous @option{--force} (@option{-f}) option. -+Equivalent to @option{--interactive=always}. -+ -+@item -I -+@opindex -I -+Prompt once whether to proceed with the command, if more than three -+files are named or if a recursive removal is requested. Ignore any -+previous @option{--force} (@option{-f}) option. Equivalent to -+@option{--interactive=once}. -+ -+@itemx --interactive [=@var{when}] -+@opindex --interactive -+Specify when to issue an interactive prompt. @var{when} may be -+omitted, or one of: -+@itemize @bullet -+@item never -+@vindex never @r{interactive option} -+- Do not prompt at all. -+@item once -+@vindex once @r{interactive option} -+- Prompt once if more than three files are named or if a recursive -+removal is requested. Equivalent to @option{-I}. -+@item always -+@vindex always @r{interactive option} -+- Prompt for every file being removed. Equivalent to @option{-i}. -+@end itemize -+@option{--interactive} with no @var{when} is equivalent to -+@option{--interactive=always}. -+ -+@itemx --one-file-system -+@opindex --one-file-system -+@cindex one file system, restricting @command{rm} to -+When removing a hierarchy recursively, skip any directory that is on a -+file system different from that of the corresponding command line argument. -+ -+This option is useful when removing a build ``chroot'' hierarchy, -+which normally contains no valuable data. However, it is not uncommon -+to bind-mount @file{/home} into such a hierarchy, to make it easier to -+use one's start-up file. The catch is that it's easy to forget to -+unmount @file{/home}. Then, when you use @command{rm -rf} to remove -+your normally throw-away chroot, that command will remove everything -+under @file{/home}, too. -+Use the @option{--one-file-system} option, and it will -+warn about and skip directories on other file systems. -+Of course, this will not save your @file{/home} if it and your -+chroot happen to be on the same file system. -+ -+@itemx --preserve-root -+@opindex --preserve-root -+@cindex root directory, disallow recursive destruction -+Fail upon any attempt to remove the root directory, @file{/}, -+when used with the @option{--recursive} option. -+This is the default behavior. -+@xref{Treating / specially}. -+ -+@itemx --no-preserve-root -+@opindex --no-preserve-root -+@cindex root directory, allow recursive destruction -+Do not treat @file{/} specially when removing recursively. -+This option is not recommended unless you really want to -+remove all the files on your computer. -+@xref{Treating / specially}. -+ -+@item -r -+@itemx -R -+@itemx --recursive -+@opindex -r -+@opindex -R -+@opindex --recursive -+@cindex directories, removing (recursively) -+Remove the listed directories and their contents recursively. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Print the name of each file before removing it. -+ -+@end table -+ -+@cindex files beginning with @samp{-}, removing -+@cindex @samp{-}, removing files beginning with -+One common question is how to remove files whose names begin with a -+@samp{-}. @sc{gnu} @command{rm}, like every program that uses the @code{getopt} -+function to parse its arguments, lets you use the @samp{--} option to -+indicate that all following arguments are non-options. To remove a file -+called @file{-f} in the current directory, you could type either: -+ -+@example -+rm -- -f -+@end example -+ -+@noindent -+or: -+ -+@example -+rm ./-f -+@end example -+ -+@opindex - @r{and Unix @command{rm}} -+The Unix @command{rm} program's use of a single @samp{-} for this purpose -+predates the development of the getopt standard syntax. -+ -+@exitstatus -+ -+ -+@node shred invocation -+@section @command{shred}: Remove files more securely -+ -+@pindex shred -+@cindex data, erasing -+@cindex erasing data -+ -+@command{shred} overwrites devices or files, to help prevent even -+very expensive hardware from recovering the data. -+ -+Ordinarily when you remove a file (@pxref{rm invocation}), the data is -+not actually destroyed. Only the index listing where the file is -+stored is destroyed, and the storage is made available for reuse. -+There are undelete utilities that will attempt to reconstruct the index -+and can bring the file back if the parts were not reused. -+ -+On a busy system with a nearly-full drive, space can get reused in a few -+seconds. But there is no way to know for sure. If you have sensitive -+data, you may want to be sure that recovery is not possible by actually -+overwriting the file with non-sensitive data. -+ -+However, even after doing that, it is possible to take the disk back -+to a laboratory and use a lot of sensitive (and expensive) equipment -+to look for the faint ``echoes'' of the original data underneath the -+overwritten data. If the data has only been overwritten once, it's not -+even that hard. -+ -+The best way to remove something irretrievably is to destroy the media -+it's on with acid, melt it down, or the like. For cheap removable media -+like floppy disks, this is the preferred method. However, hard drives -+are expensive and hard to melt, so the @command{shred} utility tries -+to achieve a similar effect non-destructively. -+ -+This uses many overwrite passes, with the data patterns chosen to -+maximize the damage they do to the old data. While this will work on -+floppies, the patterns are designed for best effect on hard drives. -+For more details, see the source code and Peter Gutmann's paper -+@uref{http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html, -+@cite{Secure Deletion of Data from Magnetic and Solid-State Memory}}, -+from the proceedings of the Sixth @acronym{USENIX} Security Symposium (San Jose, -+California, July 22--25, 1996). -+ -+@strong{Please note} that @command{shred} relies on a very important assumption: -+that the file system overwrites data in place. This is the traditional -+way to do things, but many modern file system designs do not satisfy this -+assumption. Exceptions include: -+ -+@itemize @bullet -+ -+@item -+Log-structured or journaled file systems, such as those supplied with -+AIX and Solaris, and JFS, ReiserFS, XFS, Ext3 (in @code{data=journal} mode), -+BFS, NTFS, etc.@: when they are configured to journal @emph{data}. -+ -+@item -+File systems that write redundant data and carry on even if some writes -+fail, such as RAID-based file systems. -+ -+@item -+File systems that make snapshots, such as Network Appliance's NFS server. -+ -+@item -+File systems that cache in temporary locations, such as NFS version 3 -+clients. -+ -+@item -+Compressed file systems. -+@end itemize -+ -+In the particular case of ext3 file systems, the above disclaimer applies (and -+@command{shred} is thus of limited effectiveness) only in @code{data=journal} -+mode, which journals file data in addition to just metadata. In both -+the @code{data=ordered} (default) and @code{data=writeback} modes, -+@command{shred} works as usual. Ext3 journaling modes can be changed -+by adding the @code{data=something} option to the mount options for a -+particular file system in the @file{/etc/fstab} file, as documented in -+the mount man page (man mount). -+ -+If you are not sure how your file system operates, then you should assume -+that it does not overwrite data in place, which means that shred cannot -+reliably operate on regular files in your file system. -+ -+Generally speaking, it is more reliable to shred a device than a file, -+since this bypasses the problem of file system design mentioned above. -+However, even shredding devices is not always completely reliable. For -+example, most disks map out bad sectors invisibly to the application; if -+the bad sectors contain sensitive data, @command{shred} won't be able to -+destroy it. -+ -+@command{shred} makes no attempt to detect or report this problem, just as -+it makes no attempt to do anything about backups. However, since it is -+more reliable to shred devices than files, @command{shred} by default does -+not truncate or remove the output file. This default is more suitable -+for devices, which typically cannot be truncated and should not be -+removed. -+ -+Finally, consider the risk of backups and mirrors. -+File system backups and remote mirrors may contain copies of the -+file that cannot be removed, and that will allow a shredded file -+to be recovered later. So if you keep any data you may later want -+to destroy using @command{shred}, be sure that it is not backed up or mirrored. -+ -+@example -+shred [@var{option}]@dots{} @var{file}[@dots{}] -+@end example -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -f -+@itemx --force -+@opindex -f -+@opindex --force -+@cindex force deletion -+Override file permissions if necessary to allow overwriting. -+ -+@item -@var{number} -+@itemx -n @var{number} -+@itemx --iterations=@var{number} -+@opindex -n @var{number} -+@opindex --iterations=@var{number} -+@cindex iterations, selecting the number of -+By default, @command{shred} uses @value{SHRED_DEFAULT_PASSES} passes of -+overwrite. You can reduce this to save time, or increase it if you think it's -+appropriate. After 25 passes all of the internal overwrite patterns will have -+been used at least once. -+ -+@item --random-source=@var{file} -+@opindex --random-source -+@cindex random source for shredding -+Use @var{file} as a source of random data used to overwrite and to -+choose pass ordering. @xref{Random sources}. -+ -+@item -s @var{bytes} -+@itemx --size=@var{bytes} -+@opindex -s @var{bytes} -+@opindex --size=@var{bytes} -+@cindex size of file to shred -+Shred the first @var{bytes} bytes of the file. The default is to shred -+the whole file. @var{bytes} can be followed by a size specification like -+@samp{K}, @samp{M}, or @samp{G} to specify a multiple. @xref{Block size}. -+ -+@item -u -+@itemx --remove -+@opindex -u -+@opindex --remove -+@cindex removing files after shredding -+After shredding a file, truncate it (if possible) and then remove it. -+If a file has multiple links, only the named links will be removed. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Display to standard error all status updates as sterilization proceeds. -+ -+@item -x -+@itemx --exact -+@opindex -x -+@opindex --exact -+By default, @command{shred} rounds the size of a regular file up to the next -+multiple of the file system block size to fully erase the last block of the file. -+Use @option{--exact} to suppress that behavior. -+Thus, by default if you shred a 10-byte regular file on a system with 512-byte -+blocks, the resulting file will be 512 bytes long. With this option, -+shred does not increase the apparent size of the file. -+ -+@item -z -+@itemx --zero -+@opindex -z -+@opindex --zero -+Normally, the last pass that @command{shred} writes is made up of -+random data. If this would be conspicuous on your hard drive (for -+example, because it looks like encrypted data), or you just think -+it's tidier, the @option{--zero} option adds an additional overwrite pass with -+all zero bits. This is in addition to the number of passes specified -+by the @option{--iterations} option. -+ -+@end table -+ -+You might use the following command to erase all trace of the -+file system you'd created on the floppy disk in your first drive. -+That command takes about 20 minutes to erase a ``1.44MB'' (actually -+1440 KiB) floppy. -+ -+@example -+shred --verbose /dev/fd0 -+@end example -+ -+Similarly, to erase all data on a selected partition of -+your hard disk, you could give a command like this: -+ -+@example -+shred --verbose /dev/sda5 -+@end example -+ -+A @var{file} of @samp{-} denotes standard output. -+The intended use of this is to shred a removed temporary file. -+For example: -+ -+@example -+i=`tempfile -m 0600` -+exec 3<>"$i" -+rm -- "$i" -+echo "Hello, world" >&3 -+shred - >&3 -+exec 3>- -+@end example -+ -+However, the command @samp{shred - >file} does not shred the contents -+of @var{file}, since the shell truncates @var{file} before invoking -+@command{shred}. Use the command @samp{shred file} or (if using a -+Bourne-compatible shell) the command @samp{shred - 1<>file} instead. -+ -+@exitstatus -+ -+ -+@node Special file types -+@chapter Special file types -+ -+@cindex special file types -+@cindex file types, special -+ -+This chapter describes commands which create special types of files (and -+@command{rmdir}, which removes directories, one special file type). -+ -+@cindex special file types -+@cindex file types -+Although Unix-like operating systems have markedly fewer special file -+types than others, not @emph{everything} can be treated only as the -+undifferentiated byte stream of @dfn{normal files}. For example, when a -+file is created or removed, the system must record this information, -+which it does in a @dfn{directory}---a special type of file. Although -+you can read directories as normal files, if you're curious, in order -+for the system to do its job it must impose a structure, a certain -+order, on the bytes of the file. Thus it is a ``special'' type of file. -+ -+Besides directories, other special file types include named pipes -+(FIFOs), symbolic links, sockets, and so-called @dfn{special files}. -+ -+@menu -+* link invocation:: Make a hard link via the link syscall -+* ln invocation:: Make links between files. -+* mkdir invocation:: Make directories. -+* mkfifo invocation:: Make FIFOs (named pipes). -+* mknod invocation:: Make block or character special files. -+* readlink invocation:: Print value of a symlink or canonical file name. -+* rmdir invocation:: Remove empty directories. -+* unlink invocation:: Remove files via the unlink syscall -+@end menu -+ -+ -+@node link invocation -+@section @command{link}: Make a hard link via the link syscall -+ -+@pindex link -+@cindex links, creating -+@cindex hard links, creating -+@cindex creating links (hard only) -+ -+@command{link} creates a single hard link at a time. -+It is a minimalist interface to the system-provided -+@code{link} function. @xref{Hard Links, , , libc, -+The GNU C Library Reference Manual}. -+It avoids the bells and whistles of the more commonly-used -+@command{ln} command (@pxref{ln invocation}). -+Synopsis: -+ -+@example -+link @var{filename} @var{linkname} -+@end example -+ -+@var{filename} must specify an existing file, and @var{linkname} -+must specify a nonexistent entry in an existing directory. -+@command{link} simply calls @code{link (@var{filename}, @var{linkname})} -+to create the link. -+ -+On a @acronym{GNU} system, this command acts like @samp{ln --directory -+--no-target-directory @var{filename} @var{linkname}}. However, the -+@option{--directory} and @option{--no-target-directory} options are -+not specified by @acronym{POSIX}, and the @command{link} command is -+more portable in practice. -+ -+If @var{filename} is a symbolic link, it is unspecified whether -+@var{linkname} will be a hard link to the symbolic link or to the -+target of the symbolic link. Use @command{ln -P} or @command{ln -L} -+to specify which behavior is desired. -+ -+@exitstatus -+ -+ -+@node ln invocation -+@section @command{ln}: Make links between files -+ -+@pindex ln -+@cindex links, creating -+@cindex hard links, creating -+@cindex symbolic (soft) links, creating -+@cindex creating links (hard or soft) -+ -+@cindex file systems and hard links -+@command{ln} makes links between files. By default, it makes hard links; -+with the @option{-s} option, it makes symbolic (or @dfn{soft}) links. -+Synopses: -+ -+@example -+ln [@var{option}]@dots{} [-T] @var{target} @var{linkname} -+ln [@var{option}]@dots{} @var{target} -+ln [@var{option}]@dots{} @var{target}@dots{} @var{directory} -+ln [@var{option}]@dots{} -t @var{directory} @var{target}@dots{} -+@end example -+ -+@itemize @bullet -+ -+@item -+If two file names are given, @command{ln} creates a link to the first -+file from the second. -+ -+@item -+If one @var{target} is given, @command{ln} creates a link to that file -+in the current directory. -+ -+@item -+If the @option{--target-directory} (@option{-t}) option is given, or -+failing that if the last file is a directory and the -+@option{--no-target-directory} (@option{-T}) option is not given, -+@command{ln} creates a link to each @var{target} file in the specified -+directory, using the @var{target}s' names. -+ -+@end itemize -+ -+Normally @command{ln} does not remove existing files. Use the -+@option{--force} (@option{-f}) option to remove them unconditionally, -+the @option{--interactive} (@option{-i}) option to remove them -+conditionally, and the @option{--backup} (@option{-b}) option to -+rename them. -+ -+@cindex hard link, defined -+@cindex inode, and hard links -+A @dfn{hard link} is another name for an existing file; the link and the -+original are indistinguishable. Technically speaking, they share the -+same inode, and the inode contains all the information about a -+file---indeed, it is not incorrect to say that the inode @emph{is} the -+file. Most systems prohibit making a hard link to -+a directory; on those where it is allowed, only the super-user can do -+so (and with caution, since creating a cycle will cause problems to many -+other utilities). Hard links cannot cross file system boundaries. (These -+restrictions are not mandated by @acronym{POSIX}, however.) -+ -+@cindex dereferencing symbolic links -+@cindex symbolic link, defined -+@dfn{Symbolic links} (@dfn{symlinks} for short), on the other hand, are -+a special file type (which not all kernels support: System V release 3 -+(and older) systems lack symlinks) in which the link file actually -+refers to a different file, by name. When most operations (opening, -+reading, writing, and so on) are passed the symbolic link file, the -+kernel automatically @dfn{dereferences} the link and operates on the -+target of the link. But some operations (e.g., removing) work on the -+link file itself, rather than on its target. The owner and group of a -+symlink are not significant to file access performed through -+the link, but do have implications on deleting a symbolic link from a -+directory with the restricted deletion bit set. On the GNU system, -+the mode of a symlink has no significance and cannot be changed, but -+on some BSD systems, the mode can be changed and will affect whether -+the symlink will be traversed in file name resolution. @xref{Symbolic Links,,, -+libc, The GNU C Library Reference Manual}. -+ -+Symbolic links can contain arbitrary strings; a @dfn{dangling symlink} -+occurs when the string in the symlink does not resolve to a file. -+There are no restrictions against creating dangling symbolic links. -+There are trade-offs to using absolute or relative symlinks. An -+absolute symlink always points to the same file, even if the directory -+containing the link is moved. However, if the symlink is visible from -+more than one machine (such as on a networked file system), the file -+pointed to might not always be the same. A relative symbolic link is -+resolved in relation to the directory that contains the link, and is -+often useful in referring to files on the same device without regards -+to what name that device is mounted on when accessed via networked -+machines. -+ -+When creating a relative symlink in a different location than the -+current directory, the resolution of the symlink will be different -+than the resolution of the same string from the current directory. -+Therefore, many users prefer to first change directories to the -+location where the relative symlink will be created, so that -+tab-completion or other file resolution will find the same target as -+what will be placed in the symlink. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@optBackup -+ -+@item -d -+@itemx -F -+@itemx --directory -+@opindex -d -+@opindex -F -+@opindex --directory -+@cindex hard links to directories -+Allow users with appropriate privileges to attempt to make hard links -+to directories. -+However, note that this will probably fail due to -+system restrictions, even for the super-user. -+ -+@item -f -+@itemx --force -+@opindex -f -+@opindex --force -+Remove existing destination files. -+ -+@item -i -+@itemx --interactive -+@opindex -i -+@opindex --interactive -+@cindex prompting, and @command{ln} -+Prompt whether to remove existing destination files. -+ -+@item -L -+@itemx --logical -+@opindex -L -+@opindex --logical -+If @option{-s} is not in effect, and the source file is a symbolic -+link, create the hard link to the file referred to by the symbolic -+link, rather than the symbolic link itself. -+ -+@item -n -+@itemx --no-dereference -+@opindex -n -+@opindex --no-dereference -+Do not treat the last operand specially when it is a symbolic link to -+a directory. Instead, treat it as if it were a normal file. -+ -+When the destination is an actual directory (not a symlink to one), -+there is no ambiguity. The link is created in that directory. -+But when the specified destination is a symlink to a directory, -+there are two ways to treat the user's request. @command{ln} can -+treat the destination just as it would a normal directory and create -+the link in it. On the other hand, the destination can be viewed as a -+non-directory---as the symlink itself. In that case, @command{ln} -+must delete or backup that symlink before creating the new link. -+The default is to treat a destination that is a symlink to a directory -+just like a directory. -+ -+This option is weaker than the @option{--no-target-directory} -+(@option{-T}) option, so it has no effect if both options are given. -+ -+@item -P -+@itemx --physical -+@opindex -P -+@opindex --physical -+If @option{-s} is not in effect, and the source file is a symbolic -+link, create the hard link to the symbolic link itself. On platforms -+where this is not supported by the kernel, this option creates a -+symbolic link with identical contents; since symbolic link contents -+cannot be edited, any file name resolution performed through either -+link will be the same as if a hard link had been created. -+ -+@item -s -+@itemx --symbolic -+@opindex -s -+@opindex --symbolic -+Make symbolic links instead of hard links. This option merely produces -+an error message on systems that do not support symbolic links. -+ -+@optBackupSuffix -+ -+@optTargetDirectory -+ -+@optNoTargetDirectory -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Print the name of each file after linking it successfully. -+ -+@end table -+ -+@cindex hard links to symbolic links -+@cindex symbolic links and @command{ln} -+If @option{-L} and @option{-P} are both given, the last one takes -+precedence. If @option{-s} is also given, @option{-L} and @option{-P} -+are silently ignored. If neither option is given, then this -+implementation defaults to @option{-P} if the system @code{link} supports -+hard links to symbolic links (such as the GNU system), and @option{-L} -+if @code{link} follows symbolic links (such as on BSD). -+ -+@exitstatus -+ -+Examples: -+ -+@smallexample -+Bad Example: -+ -+# Create link ../a pointing to a in that directory. -+# Not really useful because it points to itself. -+ln -s a .. -+ -+Better Example: -+ -+# Change to the target before creating symlinks to avoid being confused. -+cd .. -+ln -s adir/a . -+ -+Bad Example: -+ -+# Hard coded file names don't move well. -+ln -s $(pwd)/a /some/dir/ -+ -+Better Example: -+ -+# Relative file names survive directory moves and also -+# work across networked file systems. -+ln -s afile anotherfile -+ln -s ../adir/afile yetanotherfile -+@end smallexample -+ -+ -+@node mkdir invocation -+@section @command{mkdir}: Make directories -+ -+@pindex mkdir -+@cindex directories, creating -+@cindex creating directories -+ -+@command{mkdir} creates directories with the specified names. Synopsis: -+ -+@example -+mkdir [@var{option}]@dots{} @var{name}@dots{} -+@end example -+ -+@command{mkdir} creates each directory @var{name} in the order given. -+It reports an error if @var{name} already exists, unless the -+@option{-p} option is given and @var{name} is a directory. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -m @var{mode} -+@itemx --mode=@var{mode} -+@opindex -m -+@opindex --mode -+@cindex modes of created directories, setting -+Set the file permission bits of created directories to @var{mode}, -+which uses the same syntax as -+in @command{chmod} and uses @samp{a=rwx} (read, write and execute allowed for -+everyone) for the point of the departure. @xref{File permissions}. -+ -+Normally the directory has the desired file mode bits at the moment it -+is created. As a @acronym{GNU} extension, @var{mode} may also mention -+special mode bits, but in this case there may be a temporary window -+during which the directory exists but its special mode bits are -+incorrect. @xref{Directory Setuid and Setgid}, for how the -+set-user-ID and set-group-ID bits of directories are inherited unless -+overridden in this way. -+ -+@item -p -+@itemx --parents -+@opindex -p -+@opindex --parents -+@cindex parent directories, creating -+Make any missing parent directories for each argument, setting their -+file permission bits to the umask modified by @samp{u+wx}. Ignore -+existing parent directories, and do not change their file permission -+bits. -+ -+To set the file permission bits of any newly-created parent -+directories to a value that includes @samp{u+wx}, you can set the -+umask before invoking @command{mkdir}. For example, if the shell -+command @samp{(umask u=rwx,go=rx; mkdir -p P/Q)} creates the parent -+@file{P} it sets the parent's permission bits to @samp{u=rwx,go=rx}. -+To set a parent's special mode bits as well, you can invoke -+@command{chmod} after @command{mkdir}. @xref{Directory Setuid and -+Setgid}, for how the set-user-ID and set-group-ID bits of -+newly-created parent directories are inherited. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Print a message for each created directory. This is most useful with -+@option{--parents}. -+ -+@item -Z @var{context} -+@itemx --context=@var{context} -+@opindex -Z -+@opindex --context -+@cindex SELinux -+@cindex security context -+Set the default SELinux security context to be used for created directories. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node mkfifo invocation -+@section @command{mkfifo}: Make FIFOs (named pipes) -+ -+@pindex mkfifo -+@cindex FIFOs, creating -+@cindex named pipes, creating -+@cindex creating FIFOs (named pipes) -+ -+@command{mkfifo} creates FIFOs (also called @dfn{named pipes}) with the -+specified names. Synopsis: -+ -+@example -+mkfifo [@var{option}] @var{name}@dots{} -+@end example -+ -+A @dfn{FIFO} is a special file type that permits independent processes -+to communicate. One process opens the FIFO file for writing, and -+another for reading, after which data can flow as with the usual -+anonymous pipe in shells or elsewhere. -+ -+The program accepts the following option. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -m @var{mode} -+@itemx --mode=@var{mode} -+@opindex -m -+@opindex --mode -+@cindex modes of created FIFOs, setting -+Set the mode of created FIFOs to @var{mode}, which is symbolic as in -+@command{chmod} and uses @samp{a=rw} (read and write allowed for everyone) -+for the point of departure. @var{mode} should specify only file -+permission bits. @xref{File permissions}. -+ -+@item -Z @var{context} -+@itemx --context=@var{context} -+@opindex -Z -+@opindex --context -+@cindex SELinux -+@cindex security context -+Set the default SELinux security context to be used for created FIFOs. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node mknod invocation -+@section @command{mknod}: Make block or character special files -+ -+@pindex mknod -+@cindex block special files, creating -+@cindex character special files, creating -+ -+@command{mknod} creates a FIFO, character special file, or block special -+file with the specified name. Synopsis: -+ -+@example -+mknod [@var{option}]@dots{} @var{name} @var{type} [@var{major} @var{minor}] -+@end example -+ -+@cindex special files -+@cindex block special files -+@cindex character special files -+Unlike the phrase ``special file type'' above, the term @dfn{special -+file} has a technical meaning on Unix: something that can generate or -+receive data. Usually this corresponds to a physical piece of hardware, -+e.g., a printer or a disk. (These files are typically created at -+system-configuration time.) The @command{mknod} command is what creates -+files of this type. Such devices can be read either a character at a -+time or a ``block'' (many characters) at a time, hence we say there are -+@dfn{block special} files and @dfn{character special} files. -+ -+@c mknod is a shell built-in at least with OpenBSD's /bin/sh -+@mayConflictWithShellBuiltIn{mknod} -+ -+The arguments after @var{name} specify the type of file to make: -+ -+@table @samp -+ -+@item p -+@opindex p @r{for FIFO file} -+for a FIFO -+ -+@item b -+@opindex b @r{for block special file} -+for a block special file -+ -+@item c -+@c Don't document the `u' option -- it's just a synonym for `c'. -+@c Do *any* versions of mknod still use it? -+@c @itemx u -+@opindex c @r{for character special file} -+@c @opindex u @r{for character special file} -+for a character special file -+ -+@end table -+ -+When making a block or character special file, the major and minor -+device numbers must be given after the file type. -+If a major or minor device number begins with @samp{0x} or @samp{0X}, -+it is interpreted as hexadecimal; otherwise, if it begins with @samp{0}, -+as octal; otherwise, as decimal. -+ -+The program accepts the following option. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -m @var{mode} -+@itemx --mode=@var{mode} -+@opindex -m -+@opindex --mode -+Set the mode of created files to @var{mode}, which is symbolic as in -+@command{chmod} and uses @samp{a=rw} as the point of departure. -+@var{mode} should specify only file permission bits. -+@xref{File permissions}. -+ -+@item -Z @var{context} -+@itemx --context=@var{context} -+@opindex -Z -+@opindex --context -+@cindex SELinux -+@cindex security context -+Set the default SELinux security context to be used for created files. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node readlink invocation -+@section @command{readlink}: Print value of a symlink or canonical file name -+ -+@pindex readlink -+@cindex displaying value of a symbolic link -+@cindex canonical file name -+@cindex canonicalize a file name -+@pindex realpath -+@findex realpath -+ -+@command{readlink} may work in one of two supported modes: -+ -+@table @samp -+ -+@item Readlink mode -+ -+@command{readlink} outputs the value of the given symbolic link. -+If @command{readlink} is invoked with an argument other than the name -+of a symbolic link, it produces no output and exits with a nonzero exit code. -+ -+@item Canonicalize mode -+ -+@command{readlink} outputs the absolute name of the given file which contains -+no @file{.}, @file{..} components nor any repeated separators -+(@file{/}) or symbolic links. -+ -+@end table -+ -+@example -+readlink [@var{option}] @var{file} -+@end example -+ -+By default, @command{readlink} operates in readlink mode. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -f -+@itemx --canonicalize -+@opindex -f -+@opindex --canonicalize -+Activate canonicalize mode. -+If any component of the file name except the last one is missing or unavailable, -+@command{readlink} produces no output and exits with a nonzero exit -+code. A trailing slash is ignored. -+ -+@item -e -+@itemx --canonicalize-existing -+@opindex -e -+@opindex --canonicalize-existing -+Activate canonicalize mode. -+If any component is missing or unavailable, @command{readlink} produces -+no output and exits with a nonzero exit code. A trailing slash -+requires that the name resolve to a directory. -+ -+@item -m -+@itemx --canonicalize-missing -+@opindex -m -+@opindex --canonicalize-missing -+Activate canonicalize mode. -+If any component is missing or unavailable, @command{readlink} treats it -+as a directory. -+ -+@item -n -+@itemx --no-newline -+@opindex -n -+@opindex --no-newline -+Do not output the trailing newline. -+ -+@item -s -+@itemx -q -+@itemx --silent -+@itemx --quiet -+@opindex -s -+@opindex -q -+@opindex --silent -+@opindex --quiet -+Suppress most error messages. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Report error messages. -+ -+@end table -+ -+The @command{readlink} utility first appeared in OpenBSD 2.1. -+ -+There is a @command{realpath} command on some systems -+which operates like @command{readlink} in canonicalize mode. -+ -+@exitstatus -+ -+ -+@node rmdir invocation -+@section @command{rmdir}: Remove empty directories -+ -+@pindex rmdir -+@cindex removing empty directories -+@cindex directories, removing empty -+ -+@command{rmdir} removes empty directories. Synopsis: -+ -+@example -+rmdir [@var{option}]@dots{} @var{directory}@dots{} -+@end example -+ -+If any @var{directory} argument does not refer to an existing empty -+directory, it is an error. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item --ignore-fail-on-non-empty -+@opindex --ignore-fail-on-non-empty -+@cindex directory deletion, ignoring failures -+Ignore each failure to remove a directory that is solely because -+the directory is non-empty. -+ -+@item -p -+@itemx --parents -+@opindex -p -+@opindex --parents -+@cindex parent directories, removing -+Remove @var{directory}, then try to remove each component of @var{directory}. -+So, for example, @samp{rmdir -p a/b/c} is similar to @samp{rmdir a/b/c a/b a}. -+As such, it fails if any of those directories turns out not to be empty. -+Use the @option{--ignore-fail-on-non-empty} option to make it so such -+a failure does not evoke a diagnostic and does not cause @command{rmdir} to -+exit unsuccessfully. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+@cindex directory deletion, reporting -+Give a diagnostic for each successful removal. -+@var{directory} is removed. -+ -+@end table -+ -+@xref{rm invocation}, for how to remove non-empty directories (recursively). -+ -+@exitstatus -+ -+ -+@node unlink invocation -+@section @command{unlink}: Remove files via the unlink syscall -+ -+@pindex unlink -+@cindex removing files or directories (via the unlink syscall) -+ -+@command{unlink} deletes a single specified file name. -+It is a minimalist interface to the system-provided -+@code{unlink} function. @xref{Deleting Files, , , libc, -+The GNU C Library Reference Manual}. Synopsis: -+It avoids the bells and whistles of the more commonly-used -+@command{rm} command (@pxref{rm invocation}). -+ -+@example -+unlink @var{filename} -+@end example -+ -+On some systems @code{unlink} can be used to delete the name of a -+directory. On others, it can be used that way only by a privileged user. -+In the GNU system @code{unlink} can never delete the name of a directory. -+ -+The @command{unlink} command honors the @option{--help} and -+@option{--version} options. To remove a file whose name begins with -+@samp{-}, prefix the name with @samp{./}, e.g., @samp{unlink ./--help}. -+ -+@exitstatus -+ -+ -+@node Changing file attributes -+@chapter Changing file attributes -+ -+@cindex changing file attributes -+@cindex file attributes, changing -+@cindex attributes, file -+ -+A file is not merely its contents, a name, and a file type -+(@pxref{Special file types}). A file also has an owner (a user ID), a -+group (a group ID), permissions (what the owner can do with the file, -+what people in the group can do, and what everyone else can do), various -+timestamps, and other information. Collectively, we call these a file's -+@dfn{attributes}. -+ -+These commands change file attributes. -+ -+@menu -+* chgrp invocation:: Change file groups. -+* chmod invocation:: Change access permissions. -+* chown invocation:: Change file owners and groups. -+* touch invocation:: Change file timestamps. -+@end menu -+ -+ -+@node chown invocation -+@section @command{chown}: Change file owner and group -+ -+@pindex chown -+@cindex file ownership, changing -+@cindex group ownership, changing -+@cindex changing file ownership -+@cindex changing group ownership -+ -+@command{chown} changes the user and/or group ownership of each given @var{file} -+to @var{new-owner} or to the user and group of an existing reference file. -+Synopsis: -+ -+@example -+chown [@var{option}]@dots{} @{@var{new-owner} | --reference=@var{ref_file}@} @var{file}@dots{} -+@end example -+ -+If used, @var{new-owner} specifies the new owner and/or group as follows -+(with no embedded white space): -+ -+@example -+[@var{owner}] [ : [@var{group}] ] -+@end example -+ -+Specifically: -+ -+@table @var -+@item owner -+If only an @var{owner} (a user name or numeric user ID) is given, that -+user is made the owner of each given file, and the files' group is not -+changed. -+ -+@item owner@samp{:}group -+If the @var{owner} is followed by a colon and a @var{group} (a -+group name or numeric group ID), with no spaces between them, the group -+ownership of the files is changed as well (to @var{group}). -+ -+@item owner@samp{:} -+If a colon but no group name follows @var{owner}, that user is -+made the owner of the files and the group of the files is changed to -+@var{owner}'s login group. -+ -+@item @samp{:}group -+If the colon and following @var{group} are given, but the owner -+is omitted, only the group of the files is changed; in this case, -+@command{chown} performs the same function as @command{chgrp}. -+ -+@item @samp{:} -+If only a colon is given, or if @var{new-owner} is empty, neither the -+owner nor the group is changed. -+ -+@end table -+ -+If @var{owner} or @var{group} is intended to represent a numeric user -+or group ID, then you may specify it with a leading @samp{+}. -+@xref{Disambiguating names and IDs}. -+ -+Some older scripts may still use @samp{.} in place of the @samp{:} separator. -+@acronym{POSIX} 1003.1-2001 (@pxref{Standards conformance}) does not -+require support for that, but for backward compatibility @acronym{GNU} -+@command{chown} supports @samp{.} so long as no ambiguity results. -+New scripts should avoid the use of @samp{.} because it is not -+portable, and because it has undesirable results if the entire -+@var{owner@samp{.}group} happens to identify a user whose name -+contains @samp{.}. -+ -+The @command{chown} command sometimes clears the set-user-ID or -+set-group-ID permission bits. This behavior depends on the policy and -+functionality of the underlying @code{chown} system call, which may -+make system-dependent file mode modifications outside the control of -+the @command{chown} command. For example, the @command{chown} command -+might not affect those bits when invoked by a user with appropriate -+privileges, or when the -+bits signify some function other than executable permission (e.g., -+mandatory locking). -+When in doubt, check the underlying system behavior. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -c -+@itemx --changes -+@opindex -c -+@opindex --changes -+@cindex changed owners, verbosely describing -+Verbosely describe the action for each @var{file} whose ownership -+actually changes. -+ -+@item -f -+@itemx --silent -+@itemx --quiet -+@opindex -f -+@opindex --silent -+@opindex --quiet -+@cindex error messages, omitting -+Do not print error messages about files whose ownership cannot be -+changed. -+ -+@itemx @w{@kbd{--from}=@var{old-owner}} -+@opindex --from -+@cindex symbolic links, changing owner -+Change a @var{file}'s ownership only if it has current attributes specified -+by @var{old-owner}. @var{old-owner} has the same form as @var{new-owner} -+described above. -+This option is useful primarily from a security standpoint in that -+it narrows considerably the window of potential abuse. -+For example, to reflect a user ID numbering change for one user's files -+without an option like this, @code{root} might run -+ -+@smallexample -+find / -owner OLDUSER -print0 | xargs -0 chown -h NEWUSER -+@end smallexample -+ -+But that is dangerous because the interval between when the @command{find} -+tests the existing file's owner and when the @command{chown} is actually run -+may be quite large. -+One way to narrow the gap would be to invoke chown for each file -+as it is found: -+ -+@example -+find / -owner OLDUSER -exec chown -h NEWUSER @{@} \; -+@end example -+ -+But that is very slow if there are many affected files. -+With this option, it is safer (the gap is narrower still) -+though still not perfect: -+ -+@example -+chown -h -R --from=OLDUSER NEWUSER / -+@end example -+ -+@item --dereference -+@opindex --dereference -+@cindex symbolic links, changing owner -+@findex lchown -+Do not act on symbolic links themselves but rather on what they point to. -+This is the default. -+ -+@item -h -+@itemx --no-dereference -+@opindex -h -+@opindex --no-dereference -+@cindex symbolic links, changing owner -+@findex lchown -+Act on symbolic links themselves instead of what they point to. -+This mode relies on the @code{lchown} system call. -+On systems that do not provide the @code{lchown} system call, -+@command{chown} fails when a file specified on the command line -+is a symbolic link. -+By default, no diagnostic is issued for symbolic links encountered -+during a recursive traversal, but see @option{--verbose}. -+ -+@itemx --preserve-root -+@opindex --preserve-root -+@cindex root directory, disallow recursive modification -+Fail upon any attempt to recursively change the root directory, @file{/}. -+Without @option{--recursive}, this option has no effect. -+@xref{Treating / specially}. -+ -+@itemx --no-preserve-root -+@opindex --no-preserve-root -+@cindex root directory, allow recursive modification -+Cancel the effect of any preceding @option{--preserve-root} option. -+@xref{Treating / specially}. -+ -+@item --reference=@var{ref_file} -+@opindex --reference -+Change the user and group of each @var{file} to be the same as those of -+@var{ref_file}. If @var{ref_file} is a symbolic link, do not use the -+user and group of the symbolic link, but rather those of the file it -+refers to. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Output a diagnostic for every file processed. -+If a symbolic link is encountered during a recursive traversal -+on a system without the @code{lchown} system call, and @option{--no-dereference} -+is in effect, then issue a diagnostic saying neither the symbolic link nor -+its referent is being changed. -+ -+@item -R -+@itemx --recursive -+@opindex -R -+@opindex --recursive -+@cindex recursively changing file ownership -+Recursively change ownership of directories and their contents. -+ -+@choptH -+@xref{Traversing symlinks}. -+ -+@choptL -+@xref{Traversing symlinks}. -+ -+@choptP -+@xref{Traversing symlinks}. -+ -+@end table -+ -+@exitstatus -+ -+Examples: -+ -+@smallexample -+# Change the owner of /u to "root". -+chown root /u -+ -+# Likewise, but also change its group to "staff". -+chown root:staff /u -+ -+# Change the owner of /u and subfiles to "root". -+chown -hR root /u -+@end smallexample -+ -+ -+@node chgrp invocation -+@section @command{chgrp}: Change group ownership -+ -+@pindex chgrp -+@cindex group ownership, changing -+@cindex changing group ownership -+ -+@command{chgrp} changes the group ownership of each given @var{file} -+to @var{group} (which can be either a group name or a numeric group ID) -+or to the group of an existing reference file. Synopsis: -+ -+@example -+chgrp [@var{option}]@dots{} @{@var{group} | --reference=@var{ref_file}@} @var{file}@dots{} -+@end example -+ -+If @var{group} is intended to represent a -+numeric group ID, then you may specify it with a leading @samp{+}. -+@xref{Disambiguating names and IDs}. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -c -+@itemx --changes -+@opindex -c -+@opindex --changes -+@cindex changed files, verbosely describing -+Verbosely describe the action for each @var{file} whose group actually -+changes. -+ -+@item -f -+@itemx --silent -+@itemx --quiet -+@opindex -f -+@opindex --silent -+@opindex --quiet -+@cindex error messages, omitting -+Do not print error messages about files whose group cannot be -+changed. -+ -+@item --dereference -+@opindex --dereference -+@cindex symbolic links, changing owner -+@findex lchown -+Do not act on symbolic links themselves but rather on what they point to. -+This is the default. -+ -+@item -h -+@itemx --no-dereference -+@opindex -h -+@opindex --no-dereference -+@cindex symbolic links, changing group -+@findex lchown -+Act on symbolic links themselves instead of what they point to. -+This mode relies on the @code{lchown} system call. -+On systems that do not provide the @code{lchown} system call, -+@command{chgrp} fails when a file specified on the command line -+is a symbolic link. -+By default, no diagnostic is issued for symbolic links encountered -+during a recursive traversal, but see @option{--verbose}. -+ -+@itemx --preserve-root -+@opindex --preserve-root -+@cindex root directory, disallow recursive modification -+Fail upon any attempt to recursively change the root directory, @file{/}. -+Without @option{--recursive}, this option has no effect. -+@xref{Treating / specially}. -+ -+@itemx --no-preserve-root -+@opindex --no-preserve-root -+@cindex root directory, allow recursive modification -+Cancel the effect of any preceding @option{--preserve-root} option. -+@xref{Treating / specially}. -+ -+@item --reference=@var{ref_file} -+@opindex --reference -+Change the group of each @var{file} to be the same as that of -+@var{ref_file}. If @var{ref_file} is a symbolic link, do not use the -+group of the symbolic link, but rather that of the file it refers to. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Output a diagnostic for every file processed. -+If a symbolic link is encountered during a recursive traversal -+on a system without the @code{lchown} system call, and @option{--no-dereference} -+is in effect, then issue a diagnostic saying neither the symbolic link nor -+its referent is being changed. -+ -+@item -R -+@itemx --recursive -+@opindex -R -+@opindex --recursive -+@cindex recursively changing group ownership -+Recursively change the group ownership of directories and their contents. -+ -+@choptH -+@xref{Traversing symlinks}. -+ -+@choptL -+@xref{Traversing symlinks}. -+ -+@choptP -+@xref{Traversing symlinks}. -+ -+@end table -+ -+@exitstatus -+ -+Examples: -+ -+@smallexample -+# Change the group of /u to "staff". -+chgrp staff /u -+ -+# Change the group of /u and subfiles to "staff". -+chgrp -hR staff /u -+@end smallexample -+ -+ -+@node chmod invocation -+@section @command{chmod}: Change access permissions -+ -+@pindex chmod -+@cindex changing access permissions -+@cindex access permissions, changing -+@cindex permissions, changing access -+ -+@command{chmod} changes the access permissions of the named files. Synopsis: -+ -+@example -+chmod [@var{option}]@dots{} @{@var{mode} | --reference=@var{ref_file}@} @var{file}@dots{} -+@end example -+ -+@cindex symbolic links, permissions of -+@command{chmod} never changes the permissions of symbolic links, since -+the @command{chmod} system call cannot change their permissions. -+This is not a problem since the permissions of symbolic links are -+never used. However, for each symbolic link listed on the command -+line, @command{chmod} changes the permissions of the pointed-to file. -+In contrast, @command{chmod} ignores symbolic links encountered during -+recursive directory traversals. -+ -+A successful use of @command{chmod} clears the set-group-ID bit of a -+regular file if the file's group ID does not match the user's -+effective group ID or one of the user's supplementary group IDs, -+unless the user has appropriate privileges. Additional restrictions -+may cause the set-user-ID and set-group-ID bits of @var{mode} or -+@var{ref_file} to be ignored. This behavior depends on the policy and -+functionality of the underlying @code{chmod} system call. When in -+doubt, check the underlying system behavior. -+ -+If used, @var{mode} specifies the new file mode bits. -+For details, see the section on @ref{File permissions}. -+If you really want @var{mode} to have a leading @samp{-}, you should -+use @option{--} first, e.g., @samp{chmod -- -w file}. Typically, -+though, @samp{chmod a-w file} is preferable, and @command{chmod -w -+file} (without the @option{--}) complains if it behaves differently -+from what @samp{chmod a-w file} would do. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -c -+@itemx --changes -+@opindex -c -+@opindex --changes -+Verbosely describe the action for each @var{file} whose permissions -+actually changes. -+ -+@item -f -+@itemx --silent -+@itemx --quiet -+@opindex -f -+@opindex --silent -+@opindex --quiet -+@cindex error messages, omitting -+Do not print error messages about files whose permissions cannot be -+changed. -+ -+@itemx --preserve-root -+@opindex --preserve-root -+@cindex root directory, disallow recursive modification -+Fail upon any attempt to recursively change the root directory, @file{/}. -+Without @option{--recursive}, this option has no effect. -+@xref{Treating / specially}. -+ -+@itemx --no-preserve-root -+@opindex --no-preserve-root -+@cindex root directory, allow recursive modification -+Cancel the effect of any preceding @option{--preserve-root} option. -+@xref{Treating / specially}. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+Verbosely describe the action or non-action taken for every @var{file}. -+ -+@item --reference=@var{ref_file} -+@opindex --reference -+Change the mode of each @var{file} to be the same as that of @var{ref_file}. -+@xref{File permissions}. -+If @var{ref_file} is a symbolic link, do not use the mode -+of the symbolic link, but rather that of the file it refers to. -+ -+@item -R -+@itemx --recursive -+@opindex -R -+@opindex --recursive -+@cindex recursively changing access permissions -+Recursively change permissions of directories and their contents. -+ -+@end table -+ -+@exitstatus -+ -+ -+@node touch invocation -+@section @command{touch}: Change file timestamps -+ -+@pindex touch -+@cindex changing file timestamps -+@cindex file timestamps, changing -+@cindex timestamps, changing file -+ -+@command{touch} changes the access and/or modification times of the -+specified files. Synopsis: -+ -+@example -+touch [@var{option}]@dots{} @var{file}@dots{} -+@end example -+ -+@cindex empty files, creating -+Any @var{file} argument that does not exist is created empty. -+ -+A @var{file} argument string of @samp{-} is handled specially and -+causes @command{touch} to change the times of the file associated with -+standard output. -+ -+@cindex permissions, for changing file timestamps -+If changing both the access and modification times to the current -+time, @command{touch} can change the timestamps for files that the user -+running it does not own but has write permission for. Otherwise, the -+user must own the files. -+ -+Although @command{touch} provides options for changing two of the times---the -+times of last access and modification---of a file, there is actually -+a third one as well: the inode change time. This is often referred to -+as a file's @code{ctime}. -+The inode change time represents the time when the file's meta-information -+last changed. One common example of this is when the permissions of a -+file change. Changing the permissions doesn't access the file, so -+the atime doesn't change, nor does it modify the file, so the mtime -+doesn't change. Yet, something about the file itself has changed, -+and this must be noted somewhere. This is the job of the ctime field. -+This is necessary, so that, for example, a backup program can make a -+fresh copy of the file, including the new permissions value. -+Another operation that modifies a file's ctime without affecting -+the others is renaming. In any case, it is not possible, in normal -+operations, for a user to change the ctime field to a user-specified value. -+ -+@vindex TZ -+Time stamps assume the time zone rules specified by the @env{TZ} -+environment variable, or by the system default rules if @env{TZ} is -+not set. @xref{TZ Variable,, Specifying the Time Zone with @env{TZ}, -+libc, The GNU C Library Reference Manual}. -+You can avoid ambiguities during -+daylight saving transitions by using @sc{utc} time stamps. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -a -+@itemx --time=atime -+@itemx --time=access -+@itemx --time=use -+@opindex -a -+@opindex --time -+@opindex atime@r{, changing} -+@opindex access @r{time, changing} -+@opindex use @r{time, changing} -+Change the access time only. -+ -+@item -c -+@itemx --no-create -+@opindex -c -+@opindex --no-create -+Do not create files that do not exist. -+ -+@item -d -+@itemx --date=@var{time} -+@opindex -d -+@opindex --date -+@opindex time -+Use @var{time} instead of the current time. It can contain month names, -+time zones, @samp{am} and @samp{pm}, @samp{yesterday}, etc. For -+example, @option{--date="2004-02-27 14:19:13.489392193 +0530"} -+specifies the instant of time that is 489,392,193 nanoseconds after -+February 27, 2004 at 2:19:13 PM in a time zone that is 5 hours and 30 -+minutes east of @acronym{UTC}. @xref{Date input formats}. -+File systems that do not support high-resolution time stamps -+silently ignore any excess precision here. -+ -+@item -f -+@opindex -f -+@cindex BSD @command{touch} compatibility -+Ignored; for compatibility with BSD versions of @command{touch}. -+ -+@item -m -+@itemx --time=mtime -+@itemx --time=modify -+@opindex -m -+@opindex --time -+@opindex mtime@r{, changing} -+@opindex modify @r{time, changing} -+Change the modification time only. -+ -+@item -r @var{file} -+@itemx --reference=@var{file} -+@opindex -r -+@opindex --reference -+Use the times of the reference @var{file} instead of the current time. -+If this option is combined with the @option{--date=@var{time}} -+(@option{-d @var{time}}) option, the reference @var{file}'s time is -+the origin for any relative @var{time}s given, but is otherwise ignored. -+For example, @samp{-r foo -d '-5 seconds'} specifies a time stamp -+equal to five seconds before the corresponding time stamp for @file{foo}. -+ -+@item -t [[@var{cc}]@var{yy}]@var{mmddhhmm}[.@var{ss}] -+Use the argument (optional four-digit or two-digit years, months, -+days, hours, minutes, optional seconds) instead of the current time. -+If the year is specified with only two digits, then @var{cc} -+is 20 for years in the range 0 @dots{} 68, and 19 for years in -+69 @dots{} 99. If no digits of the year are specified, -+the argument is interpreted as a date in the current year. -+Note that @var{ss} may be @samp{60}, to accommodate leap seconds. -+ -+@end table -+ -+@vindex _POSIX2_VERSION -+On older systems, @command{touch} supports an obsolete syntax, as follows. -+If no timestamp is given with any of the @option{-d}, @option{-r}, or -+@option{-t} options, and if there are two or more @var{file}s and the -+first @var{file} is of the form @samp{@var{mmddhhmm}[@var{yy}]} and this -+would be a valid argument to the @option{-t} option (if the @var{yy}, if -+any, were moved to the front), and if the represented year -+is in the range 1969--1999, that argument is interpreted as the time -+for the other files instead of as a file name. -+This obsolete behavior can be enabled or disabled with the -+@env{_POSIX2_VERSION} environment variable (@pxref{Standards -+conformance}), but portable scripts should avoid commands whose -+behavior depends on this variable. -+For example, use @samp{touch ./12312359 main.c} or @samp{touch -t -+12312359 main.c} rather than the ambiguous @samp{touch 12312359 main.c}. -+ -+@exitstatus -+ -+ -+@node Disk usage -+@chapter Disk usage -+ -+@cindex disk usage -+ -+No disk can hold an infinite amount of data. These commands report -+how much disk storage is in use or available, report other file and -+file status information, and write buffers to disk. -+ -+@menu -+* df invocation:: Report file system disk space usage. -+* du invocation:: Estimate file space usage. -+* stat invocation:: Report file or file system status. -+* sync invocation:: Synchronize memory and disk. -+* truncate invocation:: Shrink or extend the size of a file. -+@end menu -+ -+ -+@node df invocation -+@section @command{df}: Report file system disk space usage -+ -+@pindex df -+@cindex file system disk usage -+@cindex disk usage by file system -+ -+@command{df} reports the amount of disk space used and available on -+file systems. Synopsis: -+ -+@example -+df [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+With no arguments, @command{df} reports the space used and available on all -+currently mounted file systems (of all types). Otherwise, @command{df} -+reports on the file system containing each argument @var{file}. -+ -+Normally the disk space is printed in units of -+1024 bytes, but this can be overridden (@pxref{Block size}). -+Non-integer quantities are rounded up to the next higher unit. -+ -+@cindex disk device file -+@cindex device file, disk -+If an argument @var{file} is a disk device file containing a mounted -+file system, @command{df} shows the space available on that file system -+rather than on the file system containing the device node (i.e., the root -+file system). @sc{gnu} @command{df} does not attempt to determine the disk usage -+on unmounted file systems, because on most kinds of systems doing so -+requires extremely nonportable intimate knowledge of file system -+structures. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -a -+@itemx --all -+@opindex -a -+@opindex --all -+@cindex automounter file systems -+@cindex ignore file systems -+Include in the listing dummy file systems, which -+are omitted by default. Such file systems are typically special-purpose -+pseudo-file-systems, such as automounter entries. -+ -+@item -B @var{size} -+@itemx --block-size=@var{size} -+@opindex -B -+@opindex --block-size -+@cindex file system sizes -+Scale sizes by @var{size} before printing them (@pxref{Block size}). -+For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. -+ -+@itemx --total -+@opindex --total -+@cindex grand total of disk size, usage and available space -+Print a grand total of all arguments after all arguments have -+been processed. This can be used to find out the total disk size, usage -+and available space of all listed devices. -+ -+@optHumanReadable -+ -+@item -H -+@opindex -H -+Equivalent to @option{--si}. -+ -+@item -i -+@itemx --inodes -+@opindex -i -+@opindex --inodes -+@cindex inode usage -+List inode usage information instead of block usage. An inode (short -+for index node) contains information about a file such as its owner, -+permissions, timestamps, and location on the disk. -+ -+@item -k -+@opindex -k -+@cindex kibibytes for file system sizes -+Print sizes in 1024-byte blocks, overriding the default block size -+(@pxref{Block size}). -+This option is equivalent to @option{--block-size=1K}. -+ -+@item -l -+@itemx --local -+@opindex -l -+@opindex --local -+@cindex file system types, limiting output to certain -+Limit the listing to local file systems. By default, remote file systems -+are also listed. -+ -+@item --no-sync -+@opindex --no-sync -+@cindex file system space, retrieving old data more quickly -+Do not invoke the @code{sync} system call before getting any usage data. -+This may make @command{df} run significantly faster on systems with many -+disks, but on some systems (notably SunOS) the results may be slightly -+out of date. This is the default. -+ -+@item -P -+@itemx --portability -+@opindex -P -+@opindex --portability -+@cindex one-line output format -+@cindex @acronym{POSIX} output format -+@cindex portable output format -+@cindex output format, portable -+Use the @acronym{POSIX} output format. This is like the default format except -+for the following: -+ -+@enumerate -+@item -+The information about each file system is always printed on exactly -+one line; a mount device is never put on a line by itself. This means -+that if the mount device name is more than 20 characters long (e.g., for -+some network mounts), the columns are misaligned. -+ -+@item -+The labels in the header output line are changed to conform to @acronym{POSIX}. -+ -+@item -+The default block size and output format are unaffected by the -+@env{DF_BLOCK_SIZE}, @env{BLOCK_SIZE} and @env{BLOCKSIZE} environment -+variables. However, the default block size is still affected by -+@env{POSIXLY_CORRECT}: it is 512 if @env{POSIXLY_CORRECT} is set, 1024 -+otherwise. @xref{Block size}. -+@end enumerate -+ -+@optSi -+ -+@item --sync -+@opindex --sync -+@cindex file system space, retrieving current data more slowly -+Invoke the @code{sync} system call before getting any usage data. On -+some systems (notably SunOS), doing this yields more up to date results, -+but in general this option makes @command{df} much slower, especially when -+there are many or very busy file systems. -+ -+@item -t @var{fstype} -+@itemx --type=@var{fstype} -+@opindex -t -+@opindex --type -+@cindex file system types, limiting output to certain -+Limit the listing to file systems of type @var{fstype}. Multiple -+file system types can be specified by giving multiple @option{-t} options. -+By default, nothing is omitted. -+ -+@item -T -+@itemx --print-type -+@opindex -T -+@opindex --print-type -+@cindex file system types, printing -+Print each file system's type. The types printed here are the same ones -+you can include or exclude with @option{-t} and @option{-x}. The particular -+types printed are whatever is supported by the system. Here are some of -+the common names (this list is certainly not exhaustive): -+ -+@table @samp -+ -+@item nfs -+@cindex @acronym{NFS} file system type -+An @acronym{NFS} file system, i.e., one mounted over a network from another -+machine. This is the one type name which seems to be used uniformly by -+all systems. -+ -+@item 4.2@r{, }ufs@r{, }efs@dots{} -+@cindex Linux file system types -+@cindex local file system types -+@opindex 4.2 @r{file system type} -+@opindex ufs @r{file system type} -+@opindex efs @r{file system type} -+A file system on a locally-mounted hard disk. (The system might even -+support more than one type here; Linux does.) -+ -+@item hsfs@r{, }cdfs -+@cindex CD-ROM file system type -+@cindex High Sierra file system -+@opindex hsfs @r{file system type} -+@opindex cdfs @r{file system type} -+A file system on a CD-ROM drive. HP-UX uses @samp{cdfs}, most other -+systems use @samp{hsfs} (@samp{hs} for ``High Sierra''). -+ -+@item pcfs -+@cindex PC file system -+@cindex DOS file system -+@cindex MS-DOS file system -+@cindex diskette file system -+@opindex pcfs -+An MS-DOS file system, usually on a diskette. -+ -+@end table -+ -+@item -x @var{fstype} -+@itemx --exclude-type=@var{fstype} -+@opindex -x -+@opindex --exclude-type -+Limit the listing to file systems not of type @var{fstype}. -+Multiple file system types can be eliminated by giving multiple -+@option{-x} options. By default, no file system types are omitted. -+ -+@item -v -+Ignored; for compatibility with System V versions of @command{df}. -+ -+@end table -+ -+@exitstatus -+Failure includes the case where no output is generated, so you can -+inspect the exit status of a command like @samp{df -t ext3 -t reiserfs -+@var{dir}} to test whether @var{dir} is on a file system of type -+@samp{ext3} or @samp{reiserfs}. -+ -+ -+@node du invocation -+@section @command{du}: Estimate file space usage -+ -+@pindex du -+@cindex file space usage -+@cindex disk usage for files -+ -+@command{du} reports the amount of disk space used by the specified files -+and for each subdirectory (of directory arguments). Synopsis: -+ -+@example -+du [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+With no arguments, @command{du} reports the disk space for the current -+directory. Normally the disk space is printed in units of -+1024 bytes, but this can be overridden (@pxref{Block size}). -+Non-integer quantities are rounded up to the next higher unit. -+ -+If two or more hard links point to the same file, only one of the hard -+links is counted. The @var{file} argument order affects which links -+are counted, and changing the argument order may change the numbers -+that @command{du} outputs. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -a -+@itemx --all -+@opindex -a -+@opindex --all -+Show counts for all files, not just directories. -+ -+@itemx --apparent-size -+@opindex --apparent-size -+Print apparent sizes, rather than disk usage. The apparent size of a -+file is the number of bytes reported by @code{wc -c} on regular files, -+or more generally, @code{ls -l --block-size=1} or @code{stat --format=%s}. -+For example, a file containing the word @samp{zoo} with no newline would, -+of course, have an apparent size of 3. Such a small file may require -+anywhere from 0 to 16 KiB or more of disk space, depending on -+the type and configuration of the file system on which the file resides. -+However, a sparse file created with this command: -+ -+@example -+dd bs=1 seek=2GiB if=/dev/null of=big -+@end example -+ -+@noindent -+has an apparent size of 2 GiB, yet on most modern -+systems, it actually uses almost no disk space. -+ -+@item -b -+@itemx --bytes -+@opindex -b -+@opindex --bytes -+Equivalent to @code{--apparent-size --block-size=1}. -+ -+@item -B @var{size} -+@itemx --block-size=@var{size} -+@opindex -B -+@opindex --block-size -+@cindex file sizes -+Scale sizes by @var{size} before printing them (@pxref{Block size}). -+For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. -+ -+@item -c -+@itemx --total -+@opindex -c -+@opindex --total -+@cindex grand total of disk space -+Print a grand total of all arguments after all arguments have -+been processed. This can be used to find out the total disk usage of -+a given set of files or directories. -+ -+@item -D -+@itemx --dereference-args -+@opindex -D -+@opindex --dereference-args -+Dereference symbolic links that are command line arguments. -+Does not affect other symbolic links. This is helpful for finding -+out the disk usage of directories, such as @file{/usr/tmp}, which -+are often symbolic links. -+ -+@c --files0-from=FILE -+@filesZeroFromOption{du,, with the @option{--total} (@option{-c}) option} -+ -+@optHumanReadable -+ -+@item -H -+@opindex -H -+Equivalent to @option{--dereference-args} (@option{-D}). -+ -+@item -k -+@opindex -k -+@cindex kibibytes for file sizes -+Print sizes in 1024-byte blocks, overriding the default block size -+(@pxref{Block size}). -+This option is equivalent to @option{--block-size=1K}. -+ -+@item -l -+@itemx --count-links -+@opindex -l -+@opindex --count-links -+@cindex hard links, counting in @command{du} -+Count the size of all files, even if they have appeared already (as a -+hard link). -+ -+@item -L -+@itemx --dereference -+@opindex -L -+@opindex --dereference -+@cindex symbolic links, dereferencing in @command{du} -+Dereference symbolic links (show the disk space used by the file -+or directory that the link points to instead of the space used by -+the link). -+ -+@item -m -+@opindex -m -+@cindex mebibytes for file sizes -+Print sizes in 1,048,576-byte blocks, overriding the default block size -+(@pxref{Block size}). -+This option is equivalent to @option{--block-size=1M}. -+ -+@item -P -+@itemx --no-dereference -+@opindex -P -+@opindex --no-dereference -+@cindex symbolic links, dereferencing in @command{du} -+For each symbolic links encountered by @command{du}, -+consider the disk space used by the symbolic link. -+ -+@item --max-depth=@var{depth} -+@opindex --max-depth=@var{depth} -+@cindex limiting output of @command{du} -+Show the total for each directory (and file if --all) that is at -+most MAX_DEPTH levels down from the root of the hierarchy. The root -+is at level 0, so @code{du --max-depth=0} is equivalent to @code{du -s}. -+ -+@item -0 -+@opindex -0 -+@itemx --null -+@opindex --null -+@cindex output null-byte-terminated lines -+Output a zero byte (@acronym{ASCII} @sc{nul}) at the end of each line, -+rather than a newline. This option enables other programs to parse the -+output of @command{du} even when that output would contain file names -+with embedded newlines. -+ -+@optSi -+ -+@item -s -+@itemx --summarize -+@opindex -s -+@opindex --summarize -+Display only a total for each argument. -+ -+@item -S -+@itemx --separate-dirs -+@opindex -S -+@opindex --separate-dirs -+Normally, in the output of @command{du} (when not using @option{--summarize}), -+the size listed next to a directory name, @var{d}, represents the sum -+of sizes of all entries beneath @var{d} as well as the size of @var{d} itself. -+With @option{--separate-dirs}, the size reported for a directory name, -+@var{d}, is merely the @code{stat.st_size}-derived size of the directory -+entry, @var{d}. -+ -+@itemx --time -+@opindex --time -+@cindex last modified dates, displaying in @command{du} -+Show time of the most recent modification of any file in the directory, -+or any of its subdirectories. -+ -+@itemx --time=ctime -+@itemx --time=status -+@itemx --time=use -+@opindex --time -+@opindex ctime@r{, show the most recent} -+@opindex status time@r{, show the most recent} -+@opindex use time@r{, show the most recent} -+Show the most recent status change time (the @samp{ctime} in the inode) of -+any file in the directory, instead of the modification time. -+ -+@itemx --time=atime -+@itemx --time=access -+@opindex --time -+@opindex atime@r{, show the most recent} -+@opindex access time@r{, show the most recent} -+Show the most recent access time (the @samp{atime} in the inode) of -+any file in the directory, instead of the modification time. -+ -+@item --time-style=@var{style} -+@opindex --time-style -+@cindex time style -+List timestamps in style @var{style}. This option has an effect only if -+the @option{--time} option is also specified. The @var{style} should -+be one of the following: -+ -+@table @samp -+@item +@var{format} -+@vindex LC_TIME -+List timestamps using @var{format}, where @var{format} is interpreted -+like the format argument of @command{date} (@pxref{date invocation}). -+For example, @option{--time-style="+%Y-%m-%d %H:%M:%S"} causes -+@command{du} to list timestamps like @samp{2002-03-30 23:45:56}. As -+with @command{date}, @var{format}'s interpretation is affected by the -+@env{LC_TIME} locale category. -+ -+@item full-iso -+List timestamps in full using @acronym{ISO} 8601 date, time, and time zone -+format with nanosecond precision, e.g., @samp{2002-03-30 -+23:45:56.477817180 -0700}. This style is equivalent to -+@samp{+%Y-%m-%d %H:%M:%S.%N %z}. -+ -+@item long-iso -+List @acronym{ISO} 8601 date and time in minutes, e.g., -+@samp{2002-03-30 23:45}. These timestamps are shorter than -+@samp{full-iso} timestamps, and are usually good enough for everyday -+work. This style is equivalent to @samp{+%Y-%m-%d %H:%M}. -+ -+@item iso -+List @acronym{ISO} 8601 dates for timestamps, e.g., @samp{2002-03-30}. -+This style is equivalent to @samp{+%Y-%m-%d}. -+@end table -+ -+@vindex TIME_STYLE -+You can specify the default value of the @option{--time-style} option -+with the environment variable @env{TIME_STYLE}; if @env{TIME_STYLE} is not set -+the default style is @samp{long-iso}. For compatibility with @command{ls}, -+if @env{TIME_STYLE} begins with @samp{+} and contains a newline, -+the newline and any later characters are ignored; if @env{TIME_STYLE} -+begins with @samp{posix-} the @samp{posix-} is ignored; and if -+@env{TIME_STYLE} is @samp{locale} it is ignored. -+ -+@item -x -+@itemx --one-file-system -+@opindex -x -+@opindex --one-file-system -+@cindex one file system, restricting @command{du} to -+Skip directories that are on different file systems from the one that -+the argument being processed is on. -+ -+@item --exclude=@var{pattern} -+@opindex --exclude=@var{pattern} -+@cindex excluding files from @command{du} -+When recursing, skip subdirectories or files matching @var{pattern}. -+For example, @code{du --exclude='*.o'} excludes files whose names -+end in @samp{.o}. -+ -+@item -X @var{file} -+@itemx --exclude-from=@var{file} -+@opindex -X @var{file} -+@opindex --exclude-from=@var{file} -+@cindex excluding files from @command{du} -+Like @option{--exclude}, except take the patterns to exclude from @var{file}, -+one per line. If @var{file} is @samp{-}, take the patterns from standard -+input. -+ -+@end table -+ -+@cindex NFS mounts from BSD to HP-UX -+On BSD systems, @command{du} reports sizes that are half the correct -+values for files that are NFS-mounted from HP-UX systems. On HP-UX -+systems, it reports sizes that are twice the correct values for -+files that are NFS-mounted from BSD systems. This is due to a flaw -+in HP-UX; it also affects the HP-UX @command{du} program. -+ -+@exitstatus -+ -+ -+@node stat invocation -+@section @command{stat}: Report file or file system status -+ -+@pindex stat -+@cindex file status -+@cindex file system status -+ -+@command{stat} displays information about the specified file(s). Synopsis: -+ -+@example -+stat [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+With no option, @command{stat} reports all information about the given files. -+But it also can be used to report the information of the file systems the -+given files are located on. If the files are links, @command{stat} can -+also give information about the files the links point to. -+ -+@mayConflictWithShellBuiltIn{stat} -+ -+@table @samp -+ -+@item -L -+@itemx --dereference -+@opindex -L -+@opindex --dereference -+@cindex symbolic links, dereferencing in @command{stat} -+Change how @command{stat} treats symbolic links. -+With this option, @command{stat} acts on the file referenced -+by each symbolic link argument. -+Without it, @command{stat} acts on any symbolic link argument directly. -+ -+@item -f -+@itemx --file-system -+@opindex -f -+@opindex --file-system -+@cindex file systems -+Report information about the file systems where the given files are located -+instead of information about the files themselves. -+ -+@item -c -+@itemx --format=@var{format} -+@opindex -c -+@opindex --format=@var{format} -+@cindex output format -+Use @var{format} rather than the default format. -+@var{format} is automatically newline-terminated, so -+running a command like the following with two or more @var{file} -+operands produces a line of output for each operand: -+@example -+$ stat --format=%d:%i / /usr -+2050:2 -+2057:2 -+@end example -+ -+@itemx --printf=@var{format} -+@opindex --printf=@var{format} -+@cindex output format -+Use @var{format} rather than the default format. -+Like @option{--format}, but interpret backslash escapes, -+and do not output a mandatory trailing newline. -+If you want a newline, include @samp{\n} in the @var{format}. -+Here's how you would use @option{--printf} to print the device -+and inode numbers of @file{/} and @file{/usr}: -+@example -+$ stat --printf='%d:%i\n' / /usr -+2050:2 -+2057:2 -+@end example -+ -+@item -t -+@itemx --terse -+@opindex -t -+@opindex --terse -+@cindex terse output -+Print the information in terse form, suitable for parsing by other programs. -+ -+@end table -+ -+The valid @var{format} directives for files with @option{--format} and -+@option{--printf} are: -+ -+@itemize @bullet -+@item %a - Access rights in octal -+@item %A - Access rights in human readable form -+@item %b - Number of blocks allocated (see @samp{%B}) -+@item %B - The size in bytes of each block reported by @samp{%b} -+@item %d - Device number in decimal -+@item %D - Device number in hex -+@item %f - Raw mode in hex -+@item %F - File type -+@item %g - Group ID of owner -+@item %G - Group name of owner -+@item %h - Number of hard links -+@item %i - Inode number -+@item %n - File name -+@item %N - Quoted file name with dereference if symbolic link -+@item %o - I/O block size -+@item %s - Total size, in bytes -+@item %t - Major device type in hex -+@item %T - Minor device type in hex -+@item %u - User ID of owner -+@item %U - User name of owner -+@item %x - Time of last access -+@item %X - Time of last access as seconds since Epoch -+@item %y - Time of last modification -+@item %Y - Time of last modification as seconds since Epoch -+@item %z - Time of last change -+@item %Z - Time of last change as seconds since Epoch -+@end itemize -+ -+When listing file system information (@option{--file-system} (@option{-f})), -+you must use a different set of @var{format} directives: -+ -+@itemize @bullet -+@item %a - Free blocks available to non-super-user -+@item %b - Total data blocks in file system -+@item %c - Total file nodes in file system -+@item %d - Free file nodes in file system -+@item %f - Free blocks in file system -+@item %i - File System ID in hex -+@item %l - Maximum length of file names -+@item %n - File name -+@item %s - Block size (for faster transfers) -+@item %S - Fundamental block size (for block counts) -+@item %t - Type in hex -+@item %T - Type in human readable form -+@end itemize -+ -+@vindex TZ -+Time stamps are listed according to the time zone rules specified by -+the @env{TZ} environment variable, or by the system default rules if -+@env{TZ} is not set. @xref{TZ Variable,, Specifying the Time Zone -+with @env{TZ}, libc, The GNU C Library Reference Manual}. -+ -+@exitstatus -+ -+ -+@node sync invocation -+@section @command{sync}: Synchronize data on disk with memory -+ -+@pindex sync -+@cindex synchronize disk and memory -+ -+@cindex superblock, writing -+@cindex inodes, written buffered -+@command{sync} writes any data buffered in memory out to disk. This can -+include (but is not limited to) modified superblocks, modified inodes, -+and delayed reads and writes. This must be implemented by the kernel; -+The @command{sync} program does nothing but exercise the @code{sync} system -+call. -+ -+@cindex crashes and corruption -+The kernel keeps data in memory to avoid doing (relatively slow) disk -+reads and writes. This improves performance, but if the computer -+crashes, data may be lost or the file system corrupted as a -+result. The @command{sync} command ensures everything in memory -+is written to disk. -+ -+Any arguments are ignored, except for a lone @option{--help} or -+@option{--version} (@pxref{Common options}). -+ -+@exitstatus -+ -+ -+@node truncate invocation -+@section @command{truncate}: Shrink or extend the size of a file -+ -+@pindex truncate -+@cindex truncating, file sizes -+ -+@command{truncate} shrinks or extends the size of each @var{file} to the -+specified size. Synopsis: -+ -+@example -+truncate @var{option}@dots{} @var{file}@dots{} -+@end example -+ -+@cindex files, creating -+Any @var{file} that does not exist is created. -+ -+@cindex sparse files, creating -+@cindex holes, creating files with -+If a @var{file} is larger than the specified size, the extra data is lost. -+If a @var{file} is shorter, it is extended and the extended part (or hole) -+reads as zero bytes. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -c -+@itemx --no-create -+@opindex -c -+@opindex --no-create -+Do not create files that do not exist. -+ -+@item -o -+@itemx --io-blocks -+@opindex -o -+@opindex --io-blocks -+Treat @var{size} as number of I/O blocks of the @var{file} rather than bytes. -+ -+@item -r @var{rfile} -+@itemx --reference=@var{rfile} -+@opindex -r -+@opindex --reference -+Set the size of each @var{file} to the same size as @var{rfile}. -+ -+@item -s @var{size} -+@itemx --size=@var{size} -+@opindex -s -+@opindex --size -+Set the size of each @var{file} to this @var{size}. -+@multiplierSuffixesNoBlocks{size} -+ -+@var{size} may also be prefixed by one of the following to adjust -+the size of each @var{file} based on their current size: -+@example -+@samp{+} => extend by -+@samp{-} => reduce by -+@samp{<} => at most -+@samp{>} => at least -+@samp{/} => round down to multiple of -+@samp{%} => round up to multiple of -+@end example -+ -+@end table -+ -+@exitstatus -+ -+ -+@node Printing text -+@chapter Printing text -+ -+@cindex printing text, commands for -+@cindex commands for printing text -+ -+This section describes commands that display text strings. -+ -+@menu -+* echo invocation:: Print a line of text. -+* printf invocation:: Format and print data. -+* yes invocation:: Print a string until interrupted. -+@end menu -+ -+ -+@node echo invocation -+@section @command{echo}: Print a line of text -+ -+@pindex echo -+@cindex displaying text -+@cindex printing text -+@cindex text, displaying -+@cindex arbitrary text, displaying -+ -+@command{echo} writes each given @var{string} to standard output, with a -+space between each and a newline after the last one. Synopsis: -+ -+@example -+echo [@var{option}]@dots{} [@var{string}]@dots{} -+@end example -+ -+@mayConflictWithShellBuiltIn{echo} -+ -+The program accepts the following options. Also see @ref{Common options}. -+Options must precede operands, and the normally-special argument -+@samp{--} has no special meaning and is treated like any other -+@var{string}. -+ -+@table @samp -+@item -n -+@opindex -n -+Do not output the trailing newline. -+ -+@item -e -+@opindex -e -+@cindex backslash escapes -+Enable interpretation of the following backslash-escaped characters in -+each @var{string}: -+ -+@table @samp -+@item \a -+alert (bell) -+@item \b -+backspace -+@item \c -+produce no further output -+@item \f -+form feed -+@item \n -+newline -+@item \r -+carriage return -+@item \t -+horizontal tab -+@item \v -+vertical tab -+@item \\ -+backslash -+@item \0@var{nnn} -+the eight-bit value that is the octal number @var{nnn} -+(zero to three octal digits) -+@item \@var{nnn} -+the eight-bit value that is the octal number @var{nnn} -+(one to three octal digits) -+@item \x@var{hh} -+the eight-bit value that is the hexadecimal number @var{hh} -+(one or two hexadecimal digits) -+@end table -+ -+@item -E -+@opindex -E -+@cindex backslash escapes -+Disable interpretation of backslash escapes in each @var{string}. -+This is the default. If @option{-e} and @option{-E} are both -+specified, the last one given takes effect. -+ -+@end table -+ -+@vindex POSIXLY_CORRECT -+If the @env{POSIXLY_CORRECT} environment variable is set, then when -+@command{echo}'s first argument is not @option{-n} it outputs -+option-like arguments instead of treating them as options. For -+example, @code{echo -ne hello} outputs @samp{-ne hello} instead of -+plain @samp{hello}. -+ -+@acronym{POSIX} does not require support for any options, and says -+that the behavior of @command{echo} is implementation-defined if any -+@var{string} contains a backslash or if the first argument is -+@option{-n}. Portable programs can use the @command{printf} command -+if they need to omit trailing newlines or output control characters or -+backslashes. @xref{printf invocation}. -+ -+@exitstatus -+ -+ -+@node printf invocation -+@section @command{printf}: Format and print data -+ -+@pindex printf -+@command{printf} does formatted printing of text. Synopsis: -+ -+@example -+printf @var{format} [@var{argument}]@dots{} -+@end example -+ -+@command{printf} prints the @var{format} string, interpreting @samp{%} -+directives and @samp{\} escapes to format numeric and string arguments -+in a way that is mostly similar to the C @samp{printf} function. -+@xref{Output Conversion Syntax,, @command{printf} format directives, -+libc, The GNU C Library Reference Manual}, for details. -+The differences are listed below. -+ -+@mayConflictWithShellBuiltIn{printf} -+ -+@itemize @bullet -+ -+@item -+The @var{format} argument is reused as necessary to convert all the -+given @var{argument}s. For example, the command @samp{printf %s a b} -+outputs @samp{ab}. -+ -+@item -+Missing @var{argument}s are treated as null strings or as zeros, -+depending on whether the context expects a string or a number. For -+example, the command @samp{printf %sx%d} prints @samp{x0}. -+ -+@item -+@kindex \c -+An additional escape, @samp{\c}, causes @command{printf} to produce no -+further output. For example, the command @samp{printf 'A%sC\cD%sF' B -+E} prints @samp{ABC}. -+ -+@item -+The hexadecimal escape sequence @samp{\x@var{hh}} has at most two -+digits, as opposed to C where it can have an unlimited number of -+digits. For example, the command @samp{printf '\x07e'} prints two -+bytes, whereas the C statement @samp{printf ("\x07e")} prints just -+one. -+ -+@item -+@kindex %b -+@command{printf} has an additional directive, @samp{%b}, which prints its -+argument string with @samp{\} escapes interpreted in the same way as in -+the @var{format} string, except that octal escapes are of the form -+@samp{\0@var{ooo}} where @var{ooo} is 0 to 3 octal digits. -+If a precision is also given, it limits the number of bytes printed -+from the converted string. -+ -+@item -+Numeric arguments must be single C constants, possibly with leading -+@samp{+} or @samp{-}. For example, @samp{printf %.4d -3} outputs -+@samp{-0003}. -+ -+@item -+@vindex POSIXLY_CORRECT -+If the leading character of a numeric argument is @samp{"} or @samp{'} -+then its value is the numeric value of the immediately following -+character. Any remaining characters are silently ignored if the -+@env{POSIXLY_CORRECT} environment variable is set; otherwise, a -+warning is printed. For example, @samp{printf "%d" "'a"} outputs -+@samp{97} on hosts that use the @acronym{ASCII} character set, since -+@samp{a} has the numeric value 97 in @acronym{ASCII}. -+ -+@end itemize -+ -+@vindex LC_NUMERIC -+A floating-point argument must use a period before any fractional -+digits, but is printed according to the @env{LC_NUMERIC} category of the -+current locale. For example, in a locale whose radix character is a -+comma, the command @samp{printf %g 3.14} outputs @samp{3,14} whereas -+the command @samp{printf %g 3,14} is an error. -+ -+@kindex \@var{ooo} -+@kindex \x@var{hh} -+@command{printf} interprets @samp{\@var{ooo}} in @var{format} as an octal number -+(if @var{ooo} is 1 to 3 octal digits) specifying a character to print, -+and @samp{\x@var{hh}} as a hexadecimal number (if @var{hh} is 1 to 2 hex -+digits) specifying a character to print. -+ -+@kindex \uhhhh -+@kindex \Uhhhhhhhh -+@cindex Unicode -+@cindex ISO/IEC 10646 -+@vindex LC_CTYPE -+@command{printf} interprets two character syntaxes introduced in -+@acronym{ISO} C 99: -+@samp{\u} for 16-bit Unicode (@acronym{ISO}/@acronym{IEC} 10646) -+characters, specified as -+four hexadecimal digits @var{hhhh}, and @samp{\U} for 32-bit Unicode -+characters, specified as eight hexadecimal digits @var{hhhhhhhh}. -+@command{printf} outputs the Unicode characters -+according to the @env{LC_CTYPE} locale. Unicode characters in the ranges -+U+0000...U+009F, U+D800...U+DFFF cannot be specified by this syntax, except -+for U+0024 ($), U+0040 (@@), and U+0060 (@`). -+ -+The processing of @samp{\u} and @samp{\U} requires a full-featured -+@code{iconv} facility. It is activated on systems with glibc 2.2 (or newer), -+or when @code{libiconv} is installed prior to this package. Otherwise -+@samp{\u} and @samp{\U} will print as-is. -+ -+The only options are a lone @option{--help} or -+@option{--version}. @xref{Common options}. -+Options must precede operands. -+ -+The Unicode character syntaxes are useful for writing strings in a locale -+independent way. For example, a string containing the Euro currency symbol -+ -+@example -+$ env printf '\u20AC 14.95' -+@end example -+ -+@noindent -+will be output correctly in all locales supporting the Euro symbol -+(@acronym{ISO}-8859-15, UTF-8, and others). Similarly, a Chinese string -+ -+@example -+$ env printf '\u4e2d\u6587' -+@end example -+ -+@noindent -+will be output correctly in all Chinese locales (GB2312, BIG5, UTF-8, etc). -+ -+Note that in these examples, the @command{printf} command has been -+invoked via @command{env} to ensure that we run the program found via -+your shell's search path, and not a shell alias or a built-in function. -+ -+For larger strings, you don't need to look up the hexadecimal code -+values of each character one by one. @acronym{ASCII} characters mixed with \u -+escape sequences is also known as the JAVA source file encoding. You can -+use GNU recode 3.5c (or newer) to convert strings to this encoding. Here -+is how to convert a piece of text into a shell script which will output -+this text in a locale-independent way: -+ -+@smallexample -+$ LC_CTYPE=zh_CN.big5 /usr/local/bin/printf \ -+ '\u4e2d\u6587\n' > sample.txt -+$ recode BIG5..JAVA < sample.txt \ -+ | sed -e "s|^|/usr/local/bin/printf '|" -e "s|$|\\\\n'|" \ -+ > sample.sh -+@end smallexample -+ -+@exitstatus -+ -+ -+@node yes invocation -+@section @command{yes}: Print a string until interrupted -+ -+@pindex yes -+@cindex repeated output of a string -+ -+@command{yes} prints the command line arguments, separated by spaces and -+followed by a newline, forever until it is killed. If no arguments are -+given, it prints @samp{y} followed by a newline forever until killed. -+ -+Upon a write error, @command{yes} exits with status @samp{1}. -+ -+The only options are a lone @option{--help} or @option{--version}. -+To output an argument that begins with -+@samp{-}, precede it with @option{--}, e.g., @samp{yes -- --help}. -+@xref{Common options}. -+ -+ -+@node Conditions -+@chapter Conditions -+ -+@cindex conditions -+@cindex commands for exit status -+@cindex exit status commands -+ -+This section describes commands that are primarily useful for their exit -+status, rather than their output. Thus, they are often used as the -+condition of shell @code{if} statements, or as the last command in a -+pipeline. -+ -+@menu -+* false invocation:: Do nothing, unsuccessfully. -+* true invocation:: Do nothing, successfully. -+* test invocation:: Check file types and compare values. -+* expr invocation:: Evaluate expressions. -+@end menu -+ -+ -+@node false invocation -+@section @command{false}: Do nothing, unsuccessfully -+ -+@pindex false -+@cindex do nothing, unsuccessfully -+@cindex failure exit status -+@cindex exit status of @command{false} -+ -+@command{false} does nothing except return an exit status of 1, meaning -+@dfn{failure}. It can be used as a place holder in shell scripts -+where an unsuccessful command is needed. -+In most modern shells, @command{false} is a built-in command, so when -+you use @samp{false} in a script, you're probably using the built-in -+command, not the one documented here. -+ -+@command{false} honors the @option{--help} and @option{--version} options. -+ -+This version of @command{false} is implemented as a C program, and is thus -+more secure and faster than a shell script implementation, and may safely -+be used as a dummy shell for the purpose of disabling accounts. -+ -+Note that @command{false} (unlike all other programs documented herein) -+exits unsuccessfully, even when invoked with -+@option{--help} or @option{--version}. -+ -+Portable programs should not assume that the exit status of -+@command{false} is 1, as it is greater than 1 on some -+non-@acronym{GNU} hosts. -+ -+ -+@node true invocation -+@section @command{true}: Do nothing, successfully -+ -+@pindex true -+@cindex do nothing, successfully -+@cindex no-op -+@cindex successful exit -+@cindex exit status of @command{true} -+ -+@command{true} does nothing except return an exit status of 0, meaning -+@dfn{success}. It can be used as a place holder in shell scripts -+where a successful command is needed, although the shell built-in -+command @code{:} (colon) may do the same thing faster. -+In most modern shells, @command{true} is a built-in command, so when -+you use @samp{true} in a script, you're probably using the built-in -+command, not the one documented here. -+ -+@command{true} honors the @option{--help} and @option{--version} options. -+ -+Note, however, that it is possible to cause @command{true} -+to exit with nonzero status: with the @option{--help} or @option{--version} -+option, and with standard -+output already closed or redirected to a file that evokes an I/O error. -+For example, using a Bourne-compatible shell: -+ -+@example -+$ ./true --version >&- -+./true: write error: Bad file number -+$ ./true --version > /dev/full -+./true: write error: No space left on device -+@end example -+ -+This version of @command{true} is implemented as a C program, and is thus -+more secure and faster than a shell script implementation, and may safely -+be used as a dummy shell for the purpose of disabling accounts. -+ -+@node test invocation -+@section @command{test}: Check file types and compare values -+ -+@pindex test -+@cindex check file types -+@cindex compare values -+@cindex expression evaluation -+ -+@command{test} returns a status of 0 (true) or 1 (false) depending on the -+evaluation of the conditional expression @var{expr}. Each part of the -+expression must be a separate argument. -+ -+@command{test} has file status checks, string operators, and numeric -+comparison operators. -+ -+@command{test} has an alternate form that uses opening and closing -+square brackets instead a leading @samp{test}. For example, instead -+of @samp{test -d /}, you can write @samp{[ -d / ]}. The square -+brackets must be separate arguments; for example, @samp{[-d /]} does -+not have the desired effect. Since @samp{test @var{expr}} and @samp{[ -+@var{expr} ]} have the same meaning, only the former form is discussed -+below. -+ -+Synopses: -+ -+@example -+test @var{expression} -+test -+[ @var{expression} ] -+[ ] -+[ @var{option} -+@end example -+ -+@mayConflictWithShellBuiltIn{test} -+ -+If @var{expression} is omitted, @command{test} returns false. -+If @var{expression} is a single argument, -+@command{test} returns false if the argument is null and true otherwise. The argument -+can be any string, including strings like @samp{-d}, @samp{-1}, -+@samp{--}, @samp{--help}, and @samp{--version} that most other -+programs would treat as options. To get help and version information, -+invoke the commands @samp{[ --help} and @samp{[ --version}, without -+the usual closing brackets. @xref{Common options}. -+ -+@cindex exit status of @command{test} -+Exit status: -+ -+@display -+0 if the expression is true, -+1 if the expression is false, -+2 if an error occurred. -+@end display -+ -+@menu -+* File type tests:: -[bcdfhLpSt] -+* Access permission tests:: -[gkruwxOG] -+* File characteristic tests:: -e -s -nt -ot -ef -+* String tests:: -z -n = != -+* Numeric tests:: -eq -ne -lt -le -gt -ge -+* Connectives for test:: ! -a -o -+@end menu -+ -+ -+@node File type tests -+@subsection File type tests -+ -+@cindex file type tests -+ -+These options test for particular types of files. (Everything's a file, -+but not all files are the same!) -+ -+@table @samp -+ -+@item -b @var{file} -+@opindex -b -+@cindex block special check -+True if @var{file} exists and is a block special device. -+ -+@item -c @var{file} -+@opindex -c -+@cindex character special check -+True if @var{file} exists and is a character special device. -+ -+@item -d @var{file} -+@opindex -d -+@cindex directory check -+True if @var{file} exists and is a directory. -+ -+@item -f @var{file} -+@opindex -f -+@cindex regular file check -+True if @var{file} exists and is a regular file. -+ -+@item -h @var{file} -+@itemx -L @var{file} -+@opindex -L -+@opindex -h -+@cindex symbolic link check -+True if @var{file} exists and is a symbolic link. -+Unlike all other file-related tests, this test does not dereference -+@var{file} if it is a symbolic link. -+ -+@item -p @var{file} -+@opindex -p -+@cindex named pipe check -+True if @var{file} exists and is a named pipe. -+ -+@item -S @var{file} -+@opindex -S -+@cindex socket check -+True if @var{file} exists and is a socket. -+ -+@item -t @var{fd} -+@opindex -t -+@cindex terminal check -+True if @var{fd} is a file descriptor that is associated with a -+terminal. -+ -+@end table -+ -+ -+@node Access permission tests -+@subsection Access permission tests -+ -+@cindex access permission tests -+@cindex permission tests -+ -+These options test for particular access permissions. -+ -+@table @samp -+ -+@item -g @var{file} -+@opindex -g -+@cindex set-group-ID check -+True if @var{file} exists and has its set-group-ID bit set. -+ -+@item -k @var{file} -+@opindex -k -+@cindex sticky bit check -+True if @var{file} exists and has its @dfn{sticky} bit set. -+ -+@item -r @var{file} -+@opindex -r -+@cindex readable file check -+True if @var{file} exists and read permission is granted. -+ -+@item -u @var{file} -+@opindex -u -+@cindex set-user-ID check -+True if @var{file} exists and has its set-user-ID bit set. -+ -+@item -w @var{file} -+@opindex -w -+@cindex writable file check -+True if @var{file} exists and write permission is granted. -+ -+@item -x @var{file} -+@opindex -x -+@cindex executable file check -+True if @var{file} exists and execute permission is granted -+(or search permission, if it is a directory). -+ -+@item -O @var{file} -+@opindex -O -+@cindex owned by effective user ID check -+True if @var{file} exists and is owned by the current effective user ID. -+ -+@item -G @var{file} -+@opindex -G -+@cindex owned by effective group ID check -+True if @var{file} exists and is owned by the current effective group ID. -+ -+@end table -+ -+@node File characteristic tests -+@subsection File characteristic tests -+ -+@cindex file characteristic tests -+ -+These options test other file characteristics. -+ -+@table @samp -+ -+@item -e @var{file} -+@opindex -e -+@cindex existence-of-file check -+True if @var{file} exists. -+ -+@item -s @var{file} -+@opindex -s -+@cindex nonempty file check -+True if @var{file} exists and has a size greater than zero. -+ -+@item @var{file1} -nt @var{file2} -+@opindex -nt -+@cindex newer-than file check -+True if @var{file1} is newer (according to modification date) than -+@var{file2}, or if @var{file1} exists and @var{file2} does not. -+ -+@item @var{file1} -ot @var{file2} -+@opindex -ot -+@cindex older-than file check -+True if @var{file1} is older (according to modification date) than -+@var{file2}, or if @var{file2} exists and @var{file1} does not. -+ -+@item @var{file1} -ef @var{file2} -+@opindex -ef -+@cindex same file check -+@cindex hard link check -+True if @var{file1} and @var{file2} have the same device and inode -+numbers, i.e., if they are hard links to each other. -+ -+@end table -+ -+ -+@node String tests -+@subsection String tests -+ -+@cindex string tests -+ -+These options test string characteristics. You may need to quote -+@var{string} arguments for the shell. For example: -+ -+@example -+test -n "$V" -+@end example -+ -+The quotes here prevent the wrong arguments from being passed to -+@command{test} if @samp{$V} is empty or contains special characters. -+ -+@table @samp -+ -+@item -z @var{string} -+@opindex -z -+@cindex zero-length string check -+True if the length of @var{string} is zero. -+ -+@item -n @var{string} -+@itemx @var{string} -+@opindex -n -+@cindex nonzero-length string check -+True if the length of @var{string} is nonzero. -+ -+@item @var{string1} = @var{string2} -+@opindex = -+@cindex equal string check -+True if the strings are equal. -+ -+@item @var{string1} != @var{string2} -+@opindex != -+@cindex not-equal string check -+True if the strings are not equal. -+ -+@end table -+ -+ -+@node Numeric tests -+@subsection Numeric tests -+ -+@cindex numeric tests -+@cindex arithmetic tests -+ -+Numeric relational operators. The arguments must be entirely numeric -+(possibly negative), or the special expression @w{@code{-l @var{string}}}, -+which evaluates to the length of @var{string}. -+ -+@table @samp -+ -+@item @var{arg1} -eq @var{arg2} -+@itemx @var{arg1} -ne @var{arg2} -+@itemx @var{arg1} -lt @var{arg2} -+@itemx @var{arg1} -le @var{arg2} -+@itemx @var{arg1} -gt @var{arg2} -+@itemx @var{arg1} -ge @var{arg2} -+@opindex -eq -+@opindex -ne -+@opindex -lt -+@opindex -le -+@opindex -gt -+@opindex -ge -+These arithmetic binary operators return true if @var{arg1} is equal, -+not-equal, less-than, less-than-or-equal, greater-than, or -+greater-than-or-equal than @var{arg2}, respectively. -+ -+@end table -+ -+For example: -+ -+@example -+test -1 -gt -2 && echo yes -+@result{} yes -+test -l abc -gt 1 && echo yes -+@result{} yes -+test 0x100 -eq 1 -+@error{} test: integer expression expected before -eq -+@end example -+ -+ -+@node Connectives for test -+@subsection Connectives for @command{test} -+ -+@cindex logical connectives -+@cindex connectives, logical -+ -+The usual logical connectives. -+ -+@table @samp -+ -+@item ! @var{expr} -+@opindex ! -+True if @var{expr} is false. -+ -+@item @var{expr1} -a @var{expr2} -+@opindex -a -+@cindex logical and operator -+@cindex and operator -+True if both @var{expr1} and @var{expr2} are true. -+ -+@item @var{expr1} -o @var{expr2} -+@opindex -o -+@cindex logical or operator -+@cindex or operator -+True if either @var{expr1} or @var{expr2} is true. -+ -+@end table -+ -+ -+@node expr invocation -+@section @command{expr}: Evaluate expressions -+ -+@pindex expr -+@cindex expression evaluation -+@cindex evaluation of expressions -+ -+@command{expr} evaluates an expression and writes the result on standard -+output. Each token of the expression must be a separate argument. -+ -+Operands are either integers or strings. Integers consist of one or -+more decimal digits, with an optional leading @samp{-}. -+@command{expr} converts -+anything appearing in an operand position to an integer or a string -+depending on the operation being applied to it. -+ -+Strings are not quoted for @command{expr} itself, though you may need to -+quote them to protect characters with special meaning to the shell, -+e.g., spaces. However, regardless of whether it is quoted, a string -+operand should not be a parenthesis or any of @command{expr}'s -+operators like @code{+}, so you cannot safely pass an arbitrary string -+@code{$str} to expr merely by quoting it to the shell. One way to -+work around this is to use the @sc{gnu} extension @code{+}, -+(e.g., @code{+ "$str" = foo}); a more portable way is to use -+@code{@w{" $str"}} and to adjust the rest of the expression to take -+the leading space into account (e.g., @code{@w{" $str" = " foo"}}). -+ -+You should not pass a negative integer or a string with leading -+@samp{-} as @command{expr}'s first argument, as it might be -+misinterpreted as an option; this can be avoided by parenthesization. -+Also, portable scripts should not use a string operand that happens to -+take the form of an integer; this can be worked around by inserting -+leading spaces as mentioned above. -+ -+@cindex parentheses for grouping -+Operators may be given as infix symbols or prefix keywords. Parentheses -+may be used for grouping in the usual manner. You must quote -+parentheses and many operators to avoid the shell evaluating them, -+however. -+ -+When built with support for the GNU MP library, @command{expr} uses -+arbitrary-precision arithmetic; otherwise, it uses native arithmetic -+types and may fail due to arithmetic overflow. -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. Options must precede operands. -+ -+@cindex exit status of @command{expr} -+Exit status: -+ -+@display -+0 if the expression is neither null nor 0, -+1 if the expression is null or 0, -+2 if the expression is invalid, -+3 if an internal error occurred (e.g., arithmetic overflow). -+@end display -+ -+@menu -+* String expressions:: + : match substr index length -+* Numeric expressions:: + - * / % -+* Relations for expr:: | & < <= = == != >= > -+* Examples of expr:: Examples. -+@end menu -+ -+ -+@node String expressions -+@subsection String expressions -+ -+@cindex string expressions -+@cindex expressions, string -+ -+@command{expr} supports pattern matching and other string operators. These -+have higher precedence than both the numeric and relational operators (in -+the next sections). -+ -+@table @samp -+ -+@item @var{string} : @var{regex} -+@cindex pattern matching -+@cindex regular expression matching -+@cindex matching patterns -+Perform pattern matching. The arguments are converted to strings and the -+second is considered to be a (basic, a la GNU @code{grep}) regular -+expression, with a @code{^} implicitly prepended. The first argument is -+then matched against this regular expression. -+ -+If the match succeeds and @var{regex} uses @samp{\(} and @samp{\)}, the -+@code{:} expression returns the part of @var{string} that matched the -+subexpression; otherwise, it returns the number of characters matched. -+ -+If the match fails, the @code{:} operator returns the null string if -+@samp{\(} and @samp{\)} are used in @var{regex}, otherwise 0. -+ -+@kindex \( @r{regexp operator} -+Only the first @samp{\( @dots{} \)} pair is relevant to the return -+value; additional pairs are meaningful only for grouping the regular -+expression operators. -+ -+@kindex \+ @r{regexp operator} -+@kindex \? @r{regexp operator} -+@kindex \| @r{regexp operator} -+In the regular expression, @code{\+}, @code{\?}, and @code{\|} are -+operators which respectively match one or more, zero or one, or separate -+alternatives. SunOS and other @command{expr}'s treat these as regular -+characters. (@acronym{POSIX} allows either behavior.) -+@xref{Top, , Regular Expression Library, regex, Regex}, for details of -+regular expression syntax. Some examples are in @ref{Examples of expr}. -+ -+@item match @var{string} @var{regex} -+@findex match -+An alternative way to do pattern matching. This is the same as -+@w{@samp{@var{string} : @var{regex}}}. -+ -+@item substr @var{string} @var{position} @var{length} -+@findex substr -+Returns the substring of @var{string} beginning at @var{position} -+with length at most @var{length}. If either @var{position} or -+@var{length} is negative, zero, or non-numeric, returns the null string. -+ -+@item index @var{string} @var{charset} -+@findex index -+Returns the first position in @var{string} where the first character in -+@var{charset} was found. If no character in @var{charset} is found in -+@var{string}, return 0. -+ -+@item length @var{string} -+@findex length -+Returns the length of @var{string}. -+ -+@item + @var{token} -+@kindex + -+Interpret @var{token} as a string, even if it is a keyword like @var{match} -+or an operator like @code{/}. -+This makes it possible to test @code{expr length + "$x"} or -+@code{expr + "$x" : '.*/\(.\)'} and have it do the right thing even if -+the value of @var{$x} happens to be (for example) @code{/} or @code{index}. -+This operator is a @acronym{GNU} extension. Portable shell scripts should use -+@code{@w{" $token"} : @w{' \(.*\)'}} instead of @code{+ "$token"}. -+ -+@end table -+ -+To make @command{expr} interpret keywords as strings, you must use the -+@code{quote} operator. -+ -+ -+@node Numeric expressions -+@subsection Numeric expressions -+ -+@cindex numeric expressions -+@cindex expressions, numeric -+ -+@command{expr} supports the usual numeric operators, in order of increasing -+precedence. These numeric operators have lower precedence than the -+string operators described in the previous section, and higher precedence -+than the connectives (next section). -+ -+@table @samp -+ -+@item + - -+@kindex + -+@kindex - -+@cindex addition -+@cindex subtraction -+Addition and subtraction. Both arguments are converted to integers; -+an error occurs if this cannot be done. -+ -+@item * / % -+@kindex * -+@kindex / -+@kindex % -+@cindex multiplication -+@cindex division -+@cindex remainder -+Multiplication, division, remainder. Both arguments are converted to -+integers; an error occurs if this cannot be done. -+ -+@end table -+ -+ -+@node Relations for expr -+@subsection Relations for @command{expr} -+ -+@cindex connectives, logical -+@cindex logical connectives -+@cindex relations, numeric or string -+ -+@command{expr} supports the usual logical connectives and relations. These -+have lower precedence than the string and numeric operators -+(previous sections). Here is the list, lowest-precedence operator first. -+ -+@table @samp -+ -+@item | -+@kindex | -+@cindex logical or operator -+@cindex or operator -+Returns its first argument if that is neither null nor zero, otherwise -+its second argument if it is neither null nor zero, otherwise 0. It -+does not evaluate its second argument if its first argument is neither -+null nor zero. -+ -+@item & -+@kindex & -+@cindex logical and operator -+@cindex and operator -+Return its first argument if neither argument is null or zero, otherwise -+0. It does not evaluate its second argument if its first argument is -+null or zero. -+ -+@item < <= = == != >= > -+@kindex < -+@kindex <= -+@kindex = -+@kindex == -+@kindex > -+@kindex >= -+@cindex comparison operators -+@vindex LC_COLLATE -+Compare the arguments and return 1 if the relation is true, 0 otherwise. -+@code{==} is a synonym for @code{=}. @command{expr} first tries to convert -+both arguments to integers and do a numeric comparison; if either -+conversion fails, it does a lexicographic comparison using the character -+collating sequence specified by the @env{LC_COLLATE} locale. -+ -+@end table -+ -+ -+@node Examples of expr -+@subsection Examples of using @command{expr} -+ -+@cindex examples of @command{expr} -+Here are a few examples, including quoting for shell metacharacters. -+ -+To add 1 to the shell variable @code{foo}, in Bourne-compatible shells: -+ -+@example -+foo=`expr $foo + 1` -+@end example -+ -+To print the non-directory part of the file name stored in -+@code{$fname}, which need not contain a @code{/}: -+ -+@example -+expr $fname : '.*/\(.*\)' '|' $fname -+@end example -+ -+An example showing that @code{\+} is an operator: -+ -+@example -+expr aaa : 'a\+' -+@result{} 3 -+@end example -+ -+@example -+expr abc : 'a\(.\)c' -+@result{} b -+expr index abcdef cz -+@result{} 3 -+expr index index a -+@error{} expr: syntax error -+expr index + index a -+@result{} 0 -+@end example -+ -+ -+@node Redirection -+@chapter Redirection -+ -+@cindex redirection -+@cindex commands for redirection -+ -+Unix shells commonly provide several forms of @dfn{redirection}---ways -+to change the input source or output destination of a command. But one -+useful redirection is performed by a separate command, not by the shell; -+it's described here. -+ -+@menu -+* tee invocation:: Redirect output to multiple files or processes. -+@end menu -+ -+ -+@node tee invocation -+@section @command{tee}: Redirect output to multiple files or processes -+ -+@pindex tee -+@cindex pipe fitting -+@cindex destinations, multiple output -+@cindex read from stdin and write to stdout and files -+ -+The @command{tee} command copies standard input to standard output and also -+to any files given as arguments. This is useful when you want not only -+to send some data down a pipe, but also to save a copy. Synopsis: -+ -+@example -+tee [@var{option}]@dots{} [@var{file}]@dots{} -+@end example -+ -+If a file being written to does not already exist, it is created. If a -+file being written to already exists, the data it previously contained -+is overwritten unless the @option{-a} option is used. -+ -+A @var{file} of @samp{-} causes @command{tee} to send another copy of -+input to standard output, but this is typically not that useful as the -+copies are interleaved. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+@item -a -+@itemx --append -+@opindex -a -+@opindex --append -+Append standard input to the given files rather than overwriting -+them. -+ -+@item -i -+@itemx --ignore-interrupts -+@opindex -i -+@opindex --ignore-interrupts -+Ignore interrupt signals. -+ -+@end table -+ -+The @command{tee} command is useful when you happen to be transferring a large -+amount of data and also want to summarize that data without reading -+it a second time. For example, when you are downloading a DVD image, -+you often want to verify its signature or checksum right away. -+The inefficient way to do it is simply: -+ -+@example -+wget http://example.com/some.iso && sha1sum some.iso -+@end example -+ -+One problem with the above is that it makes you wait for the -+download to complete before starting the time-consuming SHA1 computation. -+Perhaps even more importantly, the above requires reading -+the DVD image a second time (the first was from the network). -+ -+The efficient way to do it is to interleave the download -+and SHA1 computation. Then, you'll get the checksum for -+free, because the entire process parallelizes so well: -+ -+@example -+# slightly contrived, to demonstrate process substitution -+wget -O - http://example.com/dvd.iso \ -+ | tee >(sha1sum > dvd.sha1) > dvd.iso -+@end example -+ -+That makes @command{tee} write not just to the expected output file, -+but also to a pipe running @command{sha1sum} and saving the final -+checksum in a file named @file{dvd.sha1}. -+ -+Note, however, that this example relies on a feature of modern shells -+called @dfn{process substitution} -+(the @samp{>(command)} syntax, above; -+@xref{Process Substitution,,Process Substitution, bashref, -+The Bash Reference Manual}.), -+so it works with @command{zsh}, @command{bash}, and @command{ksh}, -+but not with @command{/bin/sh}. So if you write code like this -+in a shell script, be sure to start the script with @samp{#!/bin/bash}. -+ -+Since the above example writes to one file and one process, -+a more conventional and portable use of @command{tee} is even better: -+ -+@example -+wget -O - http://example.com/dvd.iso \ -+ | tee dvd.iso | sha1sum > dvd.sha1 -+@end example -+ -+You can extend this example to make @command{tee} write to two processes, -+computing MD5 and SHA1 checksums in parallel. In this case, -+process substitution is required: -+ -+@example -+wget -O - http://example.com/dvd.iso \ -+ | tee >(sha1sum > dvd.sha1) \ -+ >(md5sum > dvd.md5) \ -+ > dvd.iso -+@end example -+ -+This technique is also useful when you want to make a @emph{compressed} -+copy of the contents of a pipe. -+Consider a tool to graphically summarize disk usage data from @samp{du -ak}. -+For a large hierarchy, @samp{du -ak} can run for a long time, -+and can easily produce terabytes of data, so you won't want to -+rerun the command unnecessarily. Nor will you want to save -+the uncompressed output. -+ -+Doing it the inefficient way, you can't even start the GUI -+until after you've compressed all of the @command{du} output: -+ -+@example -+du -ak | gzip -9 > /tmp/du.gz -+gzip -d /tmp/du.gz | xdiskusage -a -+@end example -+ -+With @command{tee} and process substitution, you start the GUI -+right away and eliminate the decompression completely: -+ -+@example -+du -ak | tee >(gzip -9 > /tmp/du.gz) | xdiskusage -a -+@end example -+ -+Finally, if you regularly create more than one type of -+compressed tarball at once, for example when @code{make dist} creates -+both @command{gzip}-compressed and @command{bzip2}-compressed tarballs, -+there may be a better way. -+Typical @command{automake}-generated @file{Makefile} rules create -+the two compressed tar archives with commands in sequence, like this -+(slightly simplified): -+ -+@example -+tardir=your-pkg-M.N -+tar chof - "$tardir" | gzip -9 -c > your-pkg-M.N.tar.gz -+tar chof - "$tardir" | bzip2 -9 -c > your-pkg-M.N.tar.bz2 -+@end example -+ -+However, if the hierarchy you are archiving and compressing is larger -+than a couple megabytes, and especially if you are using a multi-processor -+system with plenty of memory, then you can do much better by reading the -+directory contents only once and running the compression programs in parallel: -+ -+@example -+tardir=your-pkg-M.N -+tar chof - "$tardir" \ -+ | tee >(gzip -9 -c > your-pkg-M.N.tar.gz) \ -+ | bzip2 -9 -c > your-pkg-M.N.tar.bz2 -+@end example -+ -+@exitstatus -+ -+ -+@node File name manipulation -+@chapter File name manipulation -+ -+@cindex file name manipulation -+@cindex manipulation of file names -+@cindex commands for file name manipulation -+ -+This section describes commands that manipulate file names. -+ -+@menu -+* basename invocation:: Strip directory and suffix from a file name. -+* dirname invocation:: Strip non-directory suffix from a file name. -+* pathchk invocation:: Check file name validity and portability. -+@end menu -+ -+ -+@node basename invocation -+@section @command{basename}: Strip directory and suffix from a file name -+ -+@pindex basename -+@cindex strip directory and suffix from file names -+@cindex directory, stripping from file names -+@cindex suffix, stripping from file names -+@cindex file names, stripping directory and suffix -+@cindex leading directory components, stripping -+ -+@command{basename} removes any leading directory components from -+@var{name}. Synopsis: -+ -+@example -+basename @var{name} [@var{suffix}] -+@end example -+ -+If @var{suffix} is specified and is identical to the end of @var{name}, -+it is removed from @var{name} as well. Note that since trailing slashes -+are removed prior to suffix matching, @var{suffix} will do nothing if it -+contains slashes. @command{basename} prints the result on standard -+output. -+ -+@c This test is used both here and in the section on dirname. -+@macro basenameAndDirname -+Together, @command{basename} and @command{dirname} are designed such -+that if @samp{ls "$name"} succeeds, then the command sequence @samp{cd -+"$(dirname "$name")"; ls "$(basename "$name")"} will, too. This works -+for everything except file names containing a trailing newline. -+@end macro -+@basenameAndDirname -+ -+@acronym{POSIX} allows the implementation to define the results if -+@var{name} is empty or @samp{//}. In the former case, @acronym{GNU} -+@command{basename} returns the empty string. In the latter case, the -+result is @samp{//} on platforms where @var{//} is distinct from -+@var{/}, and @samp{/} on platforms where there is no difference. -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. Options must precede operands. -+ -+@exitstatus -+ -+Examples: -+ -+@smallexample -+# Output "sort". -+basename /usr/bin/sort -+ -+# Output "stdio". -+basename include/stdio.h .h -+@end smallexample -+ -+ -+@node dirname invocation -+@section @command{dirname}: Strip non-directory suffix from a file name -+ -+@pindex dirname -+@cindex directory components, printing -+@cindex stripping non-directory suffix -+@cindex non-directory suffix, stripping -+ -+@command{dirname} prints all but the final slash-delimited component of -+a string (presumably a file name). Synopsis: -+ -+@example -+dirname @var{name} -+@end example -+ -+If @var{name} is a single component, @command{dirname} prints @samp{.} -+(meaning the current directory). -+ -+@basenameAndDirname -+ -+@acronym{POSIX} allows the implementation to define the results if -+@var{name} is @samp{//}. With @acronym{GNU} @command{dirname}, the -+result is @samp{//} on platforms where @var{//} is distinct from -+@var{/}, and @samp{/} on platforms where there is no difference. -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. -+ -+@exitstatus -+ -+Examples: -+ -+@smallexample -+# Output "/usr/bin". -+dirname /usr/bin/sort -+ -+# Output ".". -+dirname stdio.h -+@end smallexample -+ -+ -+@node pathchk invocation -+@section @command{pathchk}: Check file name validity and portability -+ -+@pindex pathchk -+@cindex file names, checking validity and portability -+@cindex valid file names, checking for -+@cindex portable file names, checking for -+ -+@command{pathchk} checks validity and portability of file names. Synopsis: -+ -+@example -+pathchk [@var{option}]@dots{} @var{name}@dots{} -+@end example -+ -+For each @var{name}, @command{pathchk} prints an error message if any of -+these conditions is true: -+ -+@enumerate -+@item -+One of the existing directories in @var{name} does not have search -+(execute) permission, -+@item -+The length of @var{name} is larger than the maximum supported by the -+operating system. -+@item -+The length of one component of @var{name} is longer than -+its file system's maximum. -+@end enumerate -+ -+A nonexistent @var{name} is not an error, so long a file with that -+name could be created under the above conditions. -+ -+The program accepts the following options. Also see @ref{Common options}. -+Options must precede operands. -+ -+@table @samp -+ -+@item -p -+@opindex -p -+Instead of performing checks based on the underlying file system, -+print an error message if any of these conditions is true: -+ -+@enumerate -+@item -+A file name is empty. -+ -+@item -+A file name contains a character outside the @acronym{POSIX} portable file -+name character set, namely, the ASCII letters and digits, @samp{.}, -+@samp{_}, @samp{-}, and @samp{/}. -+ -+@item -+The length of a file name or one of its components exceeds the -+@acronym{POSIX} minimum limits for portability. -+@end enumerate -+ -+@item -P -+@opindex -P -+Print an error message if a file name is empty, or if it contains a component -+that begins with @samp{-}. -+ -+@item --portability -+@opindex --portability -+Print an error message if a file name is not portable to all @acronym{POSIX} -+hosts. This option is equivalent to @samp{-p -P}. -+ -+@end table -+ -+@cindex exit status of @command{pathchk} -+Exit status: -+ -+@display -+0 if all specified file names passed all checks, -+1 otherwise. -+@end display -+ -+ -+@node Working context -+@chapter Working context -+ -+@cindex working context -+@cindex commands for printing the working context -+ -+This section describes commands that display or alter the context in -+which you are working: the current directory, the terminal settings, and -+so forth. See also the user-related commands in the next section. -+ -+@menu -+* pwd invocation:: Print working directory. -+* stty invocation:: Print or change terminal characteristics. -+* printenv invocation:: Print environment variables. -+* tty invocation:: Print file name of terminal on standard input. -+@end menu -+ -+ -+@node pwd invocation -+@section @command{pwd}: Print working directory -+ -+@pindex pwd -+@cindex print name of current directory -+@cindex current working directory, printing -+@cindex working directory, printing -+ -+ -+@command{pwd} prints the name of the current directory. Synopsis: -+ -+@example -+pwd [@var{option}]@dots{} -+@end example -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+@item -L -+@itemx --logical -+@opindex -L -+@opindex --logical -+If the contents of the environment variable @env{PWD} provide an -+absolute name of the current directory with no @samp{.} or @samp{..} -+components, but possibly with symbolic links, then output those -+contents. Otherwise, fall back to default @option{-P} handling. -+ -+@item -P -+@itemx --physical -+@opindex -P -+@opindex --physical -+Print a fully resolved name for the current directory. That is, all -+components of the printed name will be actual directory names---none -+will be symbolic links. -+@end table -+ -+@cindex symbolic links and @command{pwd} -+If @option{-L} and @option{-P} are both given, the last one takes -+precedence. If neither option is given, then this implementation uses -+@option{-P} as the default unless the @env{POSIXLY_CORRECT} -+environment variable is set. -+ -+@mayConflictWithShellBuiltIn{pwd} -+ -+@exitstatus -+ -+ -+@node stty invocation -+@section @command{stty}: Print or change terminal characteristics -+ -+@pindex stty -+@cindex change or print terminal settings -+@cindex terminal settings -+@cindex line settings of terminal -+ -+@command{stty} prints or changes terminal characteristics, such as baud rate. -+Synopses: -+ -+@example -+stty [@var{option}] [@var{setting}]@dots{} -+stty [@var{option}] -+@end example -+ -+If given no line settings, @command{stty} prints the baud rate, line -+discipline number (on systems that support it), and line settings -+that have been changed from the values set by @samp{stty sane}. -+By default, mode reading and setting are performed on the tty line -+connected to standard input, although this can be modified by the -+@option{--file} option. -+ -+@command{stty} accepts many non-option arguments that change aspects of -+the terminal line operation, as described below. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+@item -a -+@itemx --all -+@opindex -a -+@opindex --all -+Print all current settings in human-readable form. This option may not -+be used in combination with any line settings. -+ -+@item -F @var{device} -+@itemx --file=@var{device} -+@opindex -F -+@opindex --file -+Set the line opened by the file name specified in @var{device} instead of -+the tty line connected to standard input. This option is necessary -+because opening a @acronym{POSIX} tty requires use of the @code{O_NONDELAY} flag to -+prevent a @acronym{POSIX} tty from blocking until the carrier detect line is high if -+the @code{clocal} flag is not set. Hence, it is not always possible -+to allow the shell to open the device in the traditional manner. -+ -+@item -g -+@itemx --save -+@opindex -g -+@opindex --save -+@cindex machine-readable @command{stty} output -+Print all current settings in a form that can be used as an argument to -+another @command{stty} command to restore the current settings. This option -+may not be used in combination with any line settings. -+ -+@end table -+ -+Many settings can be turned off by preceding them with a @samp{-}. -+Such arguments are marked below with ``May be negated'' in their -+description. The descriptions themselves refer to the positive -+case, that is, when @emph{not} negated (unless stated otherwise, -+of course). -+ -+Some settings are not available on all @acronym{POSIX} systems, since they use -+extensions. Such arguments are marked below with ``Non-@acronym{POSIX}'' in their -+description. On non-@acronym{POSIX} systems, those or other settings also may not -+be available, but it's not feasible to document all the variations: just -+try it and see. -+ -+@exitstatus -+ -+@menu -+* Control:: Control settings -+* Input:: Input settings -+* Output:: Output settings -+* Local:: Local settings -+* Combination:: Combination settings -+* Characters:: Special characters -+* Special:: Special settings -+@end menu -+ -+ -+@node Control -+@subsection Control settings -+ -+@cindex control settings -+Control settings: -+ -+@table @samp -+@item parenb -+@opindex parenb -+@cindex two-way parity -+Generate parity bit in output and expect parity bit in input. -+May be negated. -+ -+@item parodd -+@opindex parodd -+@cindex odd parity -+@cindex even parity -+Set odd parity (even if negated). May be negated. -+ -+@item cs5 -+@itemx cs6 -+@itemx cs7 -+@itemx cs8 -+@opindex cs@var{n} -+@cindex character size -+@cindex eight-bit characters -+Set character size to 5, 6, 7, or 8 bits. -+ -+@item hup -+@itemx hupcl -+@opindex hup[cl] -+Send a hangup signal when the last process closes the tty. May be -+negated. -+ -+@item cstopb -+@opindex cstopb -+@cindex stop bits -+Use two stop bits per character (one if negated). May be negated. -+ -+@item cread -+@opindex cread -+Allow input to be received. May be negated. -+ -+@item clocal -+@opindex clocal -+@cindex modem control -+Disable modem control signals. May be negated. -+ -+@item crtscts -+@opindex crtscts -+@cindex hardware flow control -+@cindex flow control, hardware -+@cindex RTS/CTS flow control -+Enable RTS/CTS flow control. Non-@acronym{POSIX}. May be negated. -+@end table -+ -+ -+@node Input -+@subsection Input settings -+ -+@cindex input settings -+These settings control operations on data received from the terminal. -+ -+@table @samp -+@item ignbrk -+@opindex ignbrk -+@cindex breaks, ignoring -+Ignore break characters. May be negated. -+ -+@item brkint -+@opindex brkint -+@cindex breaks, cause interrupts -+Make breaks cause an interrupt signal. May be negated. -+ -+@item ignpar -+@opindex ignpar -+@cindex parity, ignoring -+Ignore characters with parity errors. May be negated. -+ -+@item parmrk -+@opindex parmrk -+@cindex parity errors, marking -+Mark parity errors (with a 255-0-character sequence). May be negated. -+ -+@item inpck -+@opindex inpck -+Enable input parity checking. May be negated. -+ -+@item istrip -+@opindex istrip -+@cindex eight-bit input -+Clear high (8th) bit of input characters. May be negated. -+ -+@item inlcr -+@opindex inlcr -+@cindex newline, translating to return -+Translate newline to carriage return. May be negated. -+ -+@item igncr -+@opindex igncr -+@cindex return, ignoring -+Ignore carriage return. May be negated. -+ -+@item icrnl -+@opindex icrnl -+@cindex return, translating to newline -+Translate carriage return to newline. May be negated. -+ -+@item iutf8 -+@opindex iutf8 -+@cindex input encoding, UTF-8 -+Assume input characters are UTF-8 encoded. May be negated. -+ -+@item ixon -+@opindex ixon -+@kindex C-s/C-q flow control -+@cindex XON/XOFF flow control -+Enable XON/XOFF flow control (that is, @kbd{CTRL-S}/@kbd{CTRL-Q}). May -+be negated. -+ -+@item ixoff -+@itemx tandem -+@opindex ixoff -+@opindex tandem -+@cindex software flow control -+@cindex flow control, software -+Enable sending of @code{stop} character when the system input buffer -+is almost full, and @code{start} character when it becomes almost -+empty again. May be negated. -+ -+@item iuclc -+@opindex iuclc -+@cindex uppercase, translating to lowercase -+Translate uppercase characters to lowercase. Non-@acronym{POSIX}. May be -+negated. Note ilcuc is not implemented, as one would not be able to issue -+almost any (lowercase) Unix command, after invoking it. -+ -+@item ixany -+@opindex ixany -+Allow any character to restart output (only the start character -+if negated). Non-@acronym{POSIX}. May be negated. -+ -+@item imaxbel -+@opindex imaxbel -+@cindex beeping at input buffer full -+Enable beeping and not flushing input buffer if a character arrives -+when the input buffer is full. Non-@acronym{POSIX}. May be negated. -+@end table -+ -+ -+@node Output -+@subsection Output settings -+ -+@cindex output settings -+These settings control operations on data sent to the terminal. -+ -+@table @samp -+@item opost -+@opindex opost -+Postprocess output. May be negated. -+ -+@item olcuc -+@opindex olcuc -+@cindex lowercase, translating to output -+Translate lowercase characters to uppercase. Non-@acronym{POSIX}. May be -+negated. (Note ouclc is not currently implemented.) -+ -+@item ocrnl -+@opindex ocrnl -+@cindex return, translating to newline -+Translate carriage return to newline. Non-@acronym{POSIX}. May be negated. -+ -+@item onlcr -+@opindex onlcr -+@cindex newline, translating to crlf -+Translate newline to carriage return-newline. Non-@acronym{POSIX}. May be -+negated. -+ -+@item onocr -+@opindex onocr -+Do not print carriage returns in the first column. Non-@acronym{POSIX}. -+May be negated. -+ -+@item onlret -+@opindex onlret -+Newline performs a carriage return. Non-@acronym{POSIX}. May be negated. -+ -+@item ofill -+@opindex ofill -+@cindex pad instead of timing for delaying -+Use fill (padding) characters instead of timing for delays. Non-@acronym{POSIX}. -+May be negated. -+ -+@item ofdel -+@opindex ofdel -+@cindex pad character -+Use @acronym{ASCII} @sc{del} characters for fill instead of -+@acronym{ASCII} @sc{nul} characters. Non-@acronym{POSIX}. -+May be negated. -+ -+@item nl1 -+@itemx nl0 -+@opindex nl@var{n} -+Newline delay style. Non-@acronym{POSIX}. -+ -+@item cr3 -+@itemx cr2 -+@itemx cr1 -+@itemx cr0 -+@opindex cr@var{n} -+Carriage return delay style. Non-@acronym{POSIX}. -+ -+@item tab3 -+@itemx tab2 -+@itemx tab1 -+@itemx tab0 -+@opindex tab@var{n} -+Horizontal tab delay style. Non-@acronym{POSIX}. -+ -+@item bs1 -+@itemx bs0 -+@opindex bs@var{n} -+Backspace delay style. Non-@acronym{POSIX}. -+ -+@item vt1 -+@itemx vt0 -+@opindex vt@var{n} -+Vertical tab delay style. Non-@acronym{POSIX}. -+ -+@item ff1 -+@itemx ff0 -+@opindex ff@var{n} -+Form feed delay style. Non-@acronym{POSIX}. -+@end table -+ -+ -+@node Local -+@subsection Local settings -+ -+@cindex local settings -+ -+@table @samp -+@item isig -+@opindex isig -+Enable @code{interrupt}, @code{quit}, and @code{suspend} special -+characters. May be negated. -+ -+@item icanon -+@opindex icanon -+Enable @code{erase}, @code{kill}, @code{werase}, and @code{rprnt} -+special characters. May be negated. -+ -+@item iexten -+@opindex iexten -+Enable non-@acronym{POSIX} special characters. May be negated. -+ -+@item echo -+@opindex echo -+Echo input characters. May be negated. -+ -+@item echoe -+@itemx crterase -+@opindex echoe -+@opindex crterase -+Echo @code{erase} characters as backspace-space-backspace. May be -+negated. -+ -+@item echok -+@opindex echok -+@cindex newline echoing after @code{kill} -+Echo a newline after a @code{kill} character. May be negated. -+ -+@item echonl -+@opindex echonl -+@cindex newline, echoing -+Echo newline even if not echoing other characters. May be negated. -+ -+@item noflsh -+@opindex noflsh -+@cindex flushing, disabling -+Disable flushing after @code{interrupt} and @code{quit} special -+characters. May be negated. -+ -+@item xcase -+@opindex xcase -+@cindex case translation -+Enable input and output of uppercase characters by preceding their -+lowercase equivalents with @samp{\}, when @code{icanon} is set. -+Non-@acronym{POSIX}. May be negated. -+ -+@item tostop -+@opindex tostop -+@cindex background jobs, stopping at terminal write -+Stop background jobs that try to write to the terminal. Non-@acronym{POSIX}. -+May be negated. -+ -+@item echoprt -+@itemx prterase -+@opindex echoprt -+@opindex prterase -+Echo erased characters backward, between @samp{\} and @samp{/}. -+Non-@acronym{POSIX}. May be negated. -+ -+@item echoctl -+@itemx ctlecho -+@opindex echoctl -+@opindex ctlecho -+@cindex control characters, using @samp{^@var{c}} -+@cindex hat notation for control characters -+Echo control characters in hat notation (@samp{^@var{c}}) instead -+of literally. Non-@acronym{POSIX}. May be negated. -+ -+@item echoke -+@itemx crtkill -+@opindex echoke -+@opindex crtkill -+Echo the @code{kill} special character by erasing each character on -+the line as indicated by the @code{echoprt} and @code{echoe} settings, -+instead of by the @code{echoctl} and @code{echok} settings. Non-@acronym{POSIX}. -+May be negated. -+@end table -+ -+ -+@node Combination -+@subsection Combination settings -+ -+@cindex combination settings -+Combination settings: -+ -+@table @samp -+@item evenp -+@opindex evenp -+@itemx parity -+@opindex parity -+Same as @code{parenb -parodd cs7}. May be negated. If negated, same -+as @code{-parenb cs8}. -+ -+@item oddp -+@opindex oddp -+Same as @code{parenb parodd cs7}. May be negated. If negated, same -+as @code{-parenb cs8}. -+ -+@item nl -+@opindex nl -+Same as @code{-icrnl -onlcr}. May be negated. If negated, same as -+@code{icrnl -inlcr -igncr onlcr -ocrnl -onlret}. -+ -+@item ek -+@opindex ek -+Reset the @code{erase} and @code{kill} special characters to their default -+values. -+ -+@item sane -+@opindex sane -+Same as: -+ -+@c This is too long to write inline. -+@example -+cread -ignbrk brkint -inlcr -igncr icrnl -ixoff -+-iuclc -ixany imaxbel opost -olcuc -ocrnl onlcr -+-onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 -+ff0 isig icanon iexten echo echoe echok -echonl -+-noflsh -xcase -tostop -echoprt echoctl echoke -+@end example -+ -+@noindent -+and also sets all special characters to their default values. -+ -+@item cooked -+@opindex cooked -+Same as @code{brkint ignpar istrip icrnl ixon opost isig icanon}, plus -+sets the @code{eof} and @code{eol} characters to their default values -+if they are the same as the @code{min} and @code{time} characters. -+May be negated. If negated, same as @code{raw}. -+ -+@item raw -+@opindex raw -+Same as: -+ -+@example -+-ignbrk -brkint -ignpar -parmrk -inpck -istrip -+-inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -+-imaxbel -opost -isig -icanon -xcase min 1 time 0 -+@end example -+ -+@noindent -+May be negated. If negated, same as @code{cooked}. -+ -+@item cbreak -+@opindex cbreak -+Same as @option{-icanon}. May be negated. If negated, same as -+@code{icanon}. -+ -+@item pass8 -+@opindex pass8 -+@cindex eight-bit characters -+Same as @code{-parenb -istrip cs8}. May be negated. If negated, -+same as @code{parenb istrip cs7}. -+ -+@item litout -+@opindex litout -+Same as @option{-parenb -istrip -opost cs8}. May be negated. -+If negated, same as @code{parenb istrip opost cs7}. -+ -+@item decctlq -+@opindex decctlq -+Same as @option{-ixany}. Non-@acronym{POSIX}. May be negated. -+ -+@item tabs -+@opindex tabs -+Same as @code{tab0}. Non-@acronym{POSIX}. May be negated. If negated, same -+as @code{tab3}. -+ -+@item lcase -+@itemx LCASE -+@opindex lcase -+@opindex LCASE -+Same as @code{xcase iuclc olcuc}. Non-@acronym{POSIX}. May be negated. -+(Used for terminals with uppercase characters only.) -+ -+@item crt -+@opindex crt -+Same as @code{echoe echoctl echoke}. -+ -+@item dec -+@opindex dec -+Same as @code{echoe echoctl echoke -ixany intr ^C erase ^? kill C-u}. -+@end table -+ -+ -+@node Characters -+@subsection Special characters -+ -+@cindex special characters -+@cindex characters, special -+ -+The special characters' default values vary from system to system. -+They are set with the syntax @samp{name value}, where the names are -+listed below and the value can be given either literally, in hat -+notation (@samp{^@var{c}}), or as an integer which may start with -+@samp{0x} to indicate hexadecimal, @samp{0} to indicate octal, or -+any other digit to indicate decimal. -+ -+@cindex disabling special characters -+@kindex u@r{, and disabling special characters} -+For GNU stty, giving a value of @code{^-} or @code{undef} disables that -+special character. (This is incompatible with Ultrix @command{stty}, -+which uses a value of @samp{u} to disable a special character. GNU -+@command{stty} treats a value @samp{u} like any other, namely to set that -+special character to @key{U}.) -+ -+@table @samp -+ -+@item intr -+@opindex intr -+Send an interrupt signal. -+ -+@item quit -+@opindex quit -+Send a quit signal. -+ -+@item erase -+@opindex erase -+Erase the last character typed. -+ -+@item kill -+@opindex kill -+Erase the current line. -+ -+@item eof -+@opindex eof -+Send an end of file (terminate the input). -+ -+@item eol -+@opindex eol -+End the line. -+ -+@item eol2 -+@opindex eol2 -+Alternate character to end the line. Non-@acronym{POSIX}. -+ -+@item swtch -+@opindex swtch -+Switch to a different shell layer. Non-@acronym{POSIX}. -+ -+@item start -+@opindex start -+Restart the output after stopping it. -+ -+@item stop -+@opindex stop -+Stop the output. -+ -+@item susp -+@opindex susp -+Send a terminal stop signal. -+ -+@item dsusp -+@opindex dsusp -+Send a terminal stop signal after flushing the input. Non-@acronym{POSIX}. -+ -+@item rprnt -+@opindex rprnt -+Redraw the current line. Non-@acronym{POSIX}. -+ -+@item werase -+@opindex werase -+Erase the last word typed. Non-@acronym{POSIX}. -+ -+@item lnext -+@opindex lnext -+Enter the next character typed literally, even if it is a special -+character. Non-@acronym{POSIX}. -+@end table -+ -+ -+@node Special -+@subsection Special settings -+ -+@cindex special settings -+ -+@table @samp -+@item min @var{n} -+@opindex min -+Set the minimum number of characters that will satisfy a read until -+the time value has expired, when @option{-icanon} is set. -+ -+@item time @var{n} -+@opindex time -+Set the number of tenths of a second before reads time out if the minimum -+number of characters have not been read, when @option{-icanon} is set. -+ -+@item ispeed @var{n} -+@opindex ispeed -+Set the input speed to @var{n}. -+ -+@item ospeed @var{n} -+@opindex ospeed -+Set the output speed to @var{n}. -+ -+@item rows @var{n} -+@opindex rows -+Tell the tty kernel driver that the terminal has @var{n} rows. Non-@acronym{POSIX}. -+ -+@item cols @var{n} -+@itemx columns @var{n} -+@opindex cols -+@opindex columns -+Tell the kernel that the terminal has @var{n} columns. Non-@acronym{POSIX}. -+ -+@item size -+@opindex size -+@vindex LINES -+@vindex COLUMNS -+Print the number of rows and columns that the kernel thinks the -+terminal has. (Systems that don't support rows and columns in the kernel -+typically use the environment variables @env{LINES} and @env{COLUMNS} -+instead; however, GNU @command{stty} does not know anything about them.) -+Non-@acronym{POSIX}. -+ -+@item line @var{n} -+@opindex line -+Use line discipline @var{n}. Non-@acronym{POSIX}. -+ -+@item speed -+@opindex speed -+Print the terminal speed. -+ -+@item @var{n} -+@cindex baud rate, setting -+Set the input and output speeds to @var{n}. @var{n} can be one of: 0 -+50 75 110 134 134.5 150 200 300 600 1200 1800 2400 4800 9600 19200 -+38400 @code{exta} @code{extb}. @code{exta} is the same as 19200; -+@code{extb} is the same as 38400. Many systems, including GNU/Linux, -+support higher speeds. The @command{stty} command includes support -+for speeds of -+57600, -+115200, -+230400, -+460800, -+500000, -+576000, -+921600, -+1000000, -+1152000, -+1500000, -+2000000, -+2500000, -+3000000, -+3500000, -+or -+4000000 where the system supports these. -+0 hangs up the line if @option{-clocal} is set. -+@end table -+ -+ -+@node printenv invocation -+@section @command{printenv}: Print all or some environment variables -+ -+@pindex printenv -+@cindex printing all or some environment variables -+@cindex environment variables, printing -+ -+@command{printenv} prints environment variable values. Synopsis: -+ -+@example -+printenv [@var{option}] [@var{variable}]@dots{} -+@end example -+ -+If no @var{variable}s are specified, @command{printenv} prints the value of -+every environment variable. Otherwise, it prints the value of each -+@var{variable} that is set, and nothing for those that are not set. -+ -+The only options are a lone @option{--help} or @option{--version}. -+@xref{Common options}. -+ -+@cindex exit status of @command{printenv} -+Exit status: -+ -+@display -+0 if all variables specified were found -+1 if at least one specified variable was not found -+2 if a write error occurred -+@end display -+ -+ -+@node tty invocation -+@section @command{tty}: Print file name of terminal on standard input -+ -+@pindex tty -+@cindex print terminal file name -+@cindex terminal file name, printing -+ -+@command{tty} prints the file name of the terminal connected to its standard -+input. It prints @samp{not a tty} if standard input is not a terminal. -+Synopsis: -+ -+@example -+tty [@var{option}]@dots{} -+@end example -+ -+The program accepts the following option. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -s -+@itemx --silent -+@itemx --quiet -+@opindex -s -+@opindex --silent -+@opindex --quiet -+Print nothing; only return an exit status. -+ -+@end table -+ -+@cindex exit status of @command{tty} -+Exit status: -+ -+@display -+0 if standard input is a terminal -+1 if standard input is not a terminal -+2 if given incorrect arguments -+3 if a write error occurs -+@end display -+ -+ -+@node User information -+@chapter User information -+ -+@cindex user information, commands for -+@cindex commands for printing user information -+ -+This section describes commands that print user-related information: -+logins, groups, and so forth. -+ -+@menu -+* id invocation:: Print user identity. -+* logname invocation:: Print current login name. -+* whoami invocation:: Print effective user ID. -+* groups invocation:: Print group names a user is in. -+* users invocation:: Print login names of users currently logged in. -+* who invocation:: Print who is currently logged in. -+@end menu -+ -+ -+@node id invocation -+@section @command{id}: Print user identity -+ -+@pindex id -+@cindex real user and group IDs, printing -+@cindex effective user and group IDs, printing -+@cindex printing real and effective user and group IDs -+ -+@command{id} prints information about the given user, or the process -+running it if no user is specified. Synopsis: -+ -+@example -+id [@var{option}]@dots{} [@var{username}] -+@end example -+ -+@vindex POSIXLY_CORRECT -+By default, it prints the real user ID, real group ID, effective user ID -+if different from the real user ID, effective group ID if different from -+the real group ID, and supplemental group IDs. -+In addition, if SELinux -+is enabled and the @env{POSIXLY_CORRECT} environment variable is not set, -+then print @samp{context=@var{c}}, where @var{c} is the security context. -+ -+Each of these numeric values is preceded by an identifying string and -+followed by the corresponding user or group name in parentheses. -+ -+The options cause @command{id} to print only part of the above information. -+Also see @ref{Common options}. -+ -+@table @samp -+@item -g -+@itemx --group -+@opindex -g -+@opindex --group -+Print only the group ID. -+ -+@item -G -+@itemx --groups -+@opindex -G -+@opindex --groups -+Print only the group ID and the supplementary groups. -+ -+@item -n -+@itemx --name -+@opindex -n -+@opindex --name -+Print the user or group name instead of the ID number. Requires -+@option{-u}, @option{-g}, or @option{-G}. -+ -+@item -r -+@itemx --real -+@opindex -r -+@opindex --real -+Print the real, instead of effective, user or group ID. Requires -+@option{-u}, @option{-g}, or @option{-G}. -+ -+@item -u -+@itemx --user -+@opindex -u -+@opindex --user -+Print only the user ID. -+ -+@item -Z -+@itemx --context -+@opindex -Z -+@opindex --context -+@cindex SELinux -+@cindex security context -+Print only the security context of the current user. -+If SELinux is disabled then print a warning and -+set the exit status to 1. -+ -+@end table -+ -+@exitstatus -+ -+@macro primaryAndSupplementaryGroups{cmd,arg} -+Primary and supplementary groups for a process are normally inherited -+from its parent and are usually unchanged since login. This means -+that if you change the group database after logging in, @command{\cmd\} -+will not reflect your changes within your existing login session. -+Running @command{\cmd\} with a \arg\ causes the user and group -+database to be consulted afresh, and so will give a different result. -+@end macro -+@primaryAndSupplementaryGroups{id,user argument} -+ -+@node logname invocation -+@section @command{logname}: Print current login name -+ -+@pindex logname -+@cindex printing user's login name -+@cindex login name, printing -+@cindex user name, printing -+ -+@flindex utmp -+@command{logname} prints the calling user's name, as found in a -+system-maintained file (often @file{/var/run/utmp} or -+@file{/etc/utmp}), and exits with a status of 0. If there is no entry -+for the calling process, @command{logname} prints -+an error message and exits with a status of 1. -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. -+ -+@exitstatus -+ -+ -+@node whoami invocation -+@section @command{whoami}: Print effective user ID -+ -+@pindex whoami -+@cindex effective user ID, printing -+@cindex printing the effective user ID -+ -+@command{whoami} prints the user name associated with the current -+effective user ID. It is equivalent to the command @samp{id -un}. -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. -+ -+@exitstatus -+ -+ -+@node groups invocation -+@section @command{groups}: Print group names a user is in -+ -+@pindex groups -+@cindex printing groups a user is in -+@cindex supplementary groups, printing -+ -+@command{groups} prints the names of the primary and any supplementary -+groups for each given @var{username}, or the current process if no names -+are given. If more than one name is given, the name of each user is -+printed before -+the list of that user's groups and the user name is separated from the -+group list by a colon. Synopsis: -+ -+@example -+groups [@var{username}]@dots{} -+@end example -+ -+The group lists are equivalent to the output of the command @samp{id -Gn}. -+ -+@primaryAndSupplementaryGroups{groups,list of users} -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. -+ -+@exitstatus -+ -+ -+@node users invocation -+@section @command{users}: Print login names of users currently logged in -+ -+@pindex users -+@cindex printing current usernames -+@cindex usernames, printing current -+ -+@cindex login sessions, printing users with -+@command{users} prints on a single line a blank-separated list of user -+names of users currently logged in to the current host. Each user name -+corresponds to a login session, so if a user has more than one login -+session, that user's name will appear the same number of times in the -+output. Synopsis: -+ -+@example -+users [@var{file}] -+@end example -+ -+@flindex utmp -+@flindex wtmp -+With no @var{file} argument, @command{users} extracts its information from -+a system-maintained file (often @file{/var/run/utmp} or -+@file{/etc/utmp}). If a file argument is given, @command{users} uses -+that file instead. A common choice is @file{/var/log/wtmp}. -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. -+ -+@exitstatus -+ -+ -+@node who invocation -+@section @command{who}: Print who is currently logged in -+ -+@pindex who -+@cindex printing current user information -+@cindex information, about current users -+ -+@command{who} prints information about users who are currently logged on. -+Synopsis: -+ -+@example -+@command{who} [@var{option}] [@var{file}] [am i] -+@end example -+ -+@cindex terminal lines, currently used -+@cindex login time -+@cindex remote hostname -+If given no non-option arguments, @command{who} prints the following -+information for each user currently logged on: login name, terminal -+line, login time, and remote hostname or X display. -+ -+@flindex utmp -+@flindex wtmp -+If given one non-option argument, @command{who} uses that instead of -+a default system-maintained file (often @file{/var/run/utmp} or -+@file{/etc/utmp}) as the name of the file containing the record of -+users logged on. @file{/var/log/wtmp} is commonly given as an argument -+to @command{who} to look at who has previously logged on. -+ -+@opindex am i -+@opindex who am i -+If given two non-option arguments, @command{who} prints only the entry -+for the user running it (determined from its standard input), preceded -+by the hostname. Traditionally, the two arguments given are @samp{am -+i}, as in @samp{who am i}. -+ -+@vindex TZ -+Time stamps are listed according to the time zone rules specified by -+the @env{TZ} environment variable, or by the system default rules if -+@env{TZ} is not set. @xref{TZ Variable,, Specifying the Time Zone -+with @env{TZ}, libc, The GNU C Library Reference Manual}. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -a -+@itemx --all -+@opindex -a -+@opindex --all -+Same as @samp{-b -d --login -p -r -t -T -u}. -+ -+@item -b -+@itemx --boot -+@opindex -b -+@opindex --boot -+Print the date and time of last system boot. -+ -+@item -d -+@itemx --dead -+@opindex -d -+@opindex --dead -+Print information corresponding to dead processes. -+ -+@item -H -+@itemx --heading -+@opindex -H -+@opindex --heading -+Print a line of column headings. -+ -+@item -l -+@itemx --login -+@opindex -l -+@opindex --login -+List only the entries that correspond to processes via which the -+system is waiting for a user to login. The user name is always @samp{LOGIN}. -+ -+@itemx --lookup -+@opindex --lookup -+Attempt to canonicalize hostnames found in utmp through a DNS lookup. This -+is not the default because it can cause significant delays on systems with -+automatic dial-up internet access. -+ -+@item -m -+@opindex -m -+Same as @samp{who am i}. -+ -+@item -p -+@itemx --process -+@opindex -p -+@opindex --process -+List active processes spawned by init. -+ -+@item -q -+@itemx --count -+@opindex -q -+@opindex --count -+Print only the login names and the number of users logged on. -+Overrides all other options. -+ -+@item -r -+@itemx --runlevel -+@opindex -r -+@opindex --runlevel -+Print the current (and maybe previous) run-level of the init process. -+ -+@item -s -+@opindex -s -+Ignored; for compatibility with other versions of @command{who}. -+ -+@item -t -+@itemx --time -+@opindex -t -+@opindex --time -+Print last system clock change. -+ -+@itemx -u -+@opindex -u -+@cindex idle time -+After the login time, print the number of hours and minutes that the -+user has been idle. @samp{.} means the user was active in the last minute. -+@samp{old} means the user has been idle for more than 24 hours. -+ -+@item -w -+@itemx -T -+@itemx --mesg -+@itemx --message -+@itemx --writable -+@opindex -w -+@opindex -T -+@opindex --mesg -+@opindex --message -+@opindex --writable -+@cindex message status -+@pindex write@r{, allowed} -+After each login name print a character indicating the user's message status: -+ -+@display -+@samp{+} allowing @code{write} messages -+@samp{-} disallowing @code{write} messages -+@samp{?} cannot find terminal device -+@end display -+ -+@end table -+ -+@exitstatus -+ -+ -+@node System context -+@chapter System context -+ -+@cindex system context -+@cindex context, system -+@cindex commands for system context -+ -+This section describes commands that print or change system-wide -+information. -+ -+@menu -+* date invocation:: Print or set system date and time. -+* arch invocation:: Print machine hardware name. -+* 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 -+ -+@node date invocation -+@section @command{date}: Print or set system date and time -+ -+@pindex date -+@cindex time, printing or setting -+@cindex printing the current time -+ -+Synopses: -+ -+@example -+date [@var{option}]@dots{} [+@var{format}] -+date [-u|--utc|--universal] @c this avoids a newline in the output -+[ MMDDhhmm[[CC]YY][.ss] ] -+@end example -+ -+@vindex LC_TIME -+Invoking @command{date} with no @var{format} argument is equivalent to invoking -+it with a default format that depends on the @env{LC_TIME} locale category. -+In the default C locale, this format is @samp{'+%a %b %e %H:%M:%S %Z %Y'}, -+so the output looks like @samp{Thu Mar @ 3 13:47:51 PST 2005}. -+ -+@vindex TZ -+Normally, @command{date} uses the time zone rules indicated by the -+@env{TZ} environment variable, or the system default rules if @env{TZ} -+is not set. @xref{TZ Variable,, Specifying the Time Zone with -+@env{TZ}, libc, The GNU C Library Reference Manual}. -+ -+@findex strftime @r{and @command{date}} -+@cindex time formats -+@cindex formatting times -+If given an argument that starts with a @samp{+}, @command{date} prints the -+current date and time (or the date and time specified by the -+@option{--date} option, see below) in the format defined by that argument, -+which is similar to that of the @code{strftime} function. Except for -+conversion specifiers, which start with @samp{%}, characters in the -+format string are printed unchanged. The conversion specifiers are -+described below. -+ -+@exitstatus -+ -+@menu -+* Time conversion specifiers:: %[HIklMNpPrRsSTXzZ] -+* Date conversion specifiers:: %[aAbBcCdDeFgGhjmuUVwWxyY] -+* Literal conversion specifiers:: %[%nt] -+* Padding and other flags:: Pad with zeros, spaces, etc. -+* Setting the time:: Changing the system clock. -+* Options for date:: Instead of the current time. -+@detailmenu -+* Date input formats:: Specifying date strings. -+@end detailmenu -+* Examples of date:: Examples. -+@end menu -+ -+@node Time conversion specifiers -+@subsection Time conversion specifiers -+ -+@cindex time conversion specifiers -+@cindex conversion specifiers, time -+ -+@command{date} conversion specifiers related to times. -+ -+@table @samp -+@item %H -+hour (@samp{00}@dots{}@samp{23}) -+@item %I -+hour (@samp{01}@dots{}@samp{12}) -+@item %k -+hour (@samp{ 0}@dots{}@samp{23}). -+This is a @acronym{GNU} extension. -+@item %l -+hour (@samp{ 1}@dots{}@samp{12}). -+This is a @acronym{GNU} extension. -+@item %M -+minute (@samp{00}@dots{}@samp{59}) -+@item %N -+nanoseconds (@samp{000000000}@dots{}@samp{999999999}). -+This is a @acronym{GNU} extension. -+@item %p -+locale's equivalent of either @samp{AM} or @samp{PM}; -+blank in many locales. -+Noon is treated as @samp{PM} and midnight as @samp{AM}. -+@item %P -+like @samp{%p}, except lower case. -+This is a @acronym{GNU} extension. -+@item %r -+locale's 12-hour clock time (e.g., @samp{11:11:04 PM}) -+@item %R -+24-hour hour and minute. Same as @samp{%H:%M}. -+This is a @acronym{GNU} extension. -+@item %s -+@cindex epoch, seconds since -+@cindex seconds since the epoch -+@cindex beginning of time -+seconds since the epoch, i.e., since 1970-01-01 00:00:00 UTC. -+Leap seconds are not counted unless leap second support is available. -+@xref{%s-examples}, for examples. -+This is a @acronym{GNU} extension. -+@item %S -+second (@samp{00}@dots{}@samp{60}). -+This may be @samp{60} if leap seconds are supported. -+@item %T -+24-hour hour, minute, and second. Same as @samp{%H:%M:%S}. -+@item %X -+locale's time representation (e.g., @samp{23:13:48}) -+@item %z -+@w{@acronym{RFC} 2822/@acronym{ISO} 8601} style numeric time zone -+(e.g., @samp{-0600} or @samp{+0530}), or nothing if no -+time zone is determinable. This value reflects the numeric time zone -+appropriate for the current time, using the time zone rules specified -+by the @env{TZ} environment variable. -+The time (and optionally, the time zone rules) can be overridden -+by the @option{--date} option. -+This is a @acronym{GNU} extension. -+@item %:z -+@w{@acronym{RFC} 3339/@acronym{ISO} 8601} style numeric time zone with -+@samp{:} (e.g., @samp{-06:00} or @samp{+05:30}), or nothing if no time -+zone is determinable. -+This is a @acronym{GNU} extension. -+@item %::z -+Numeric time zone to the nearest second with @samp{:} (e.g., -+@samp{-06:00:00} or @samp{+05:30:00}), or nothing if no time zone is -+determinable. -+This is a @acronym{GNU} extension. -+@item %:::z -+Numeric time zone with @samp{:} using the minimum necessary precision -+(e.g., @samp{-06}, @samp{+05:30}, or @samp{-04:56:02}), or nothing if -+no time zone is determinable. -+This is a @acronym{GNU} extension. -+@item %Z -+alphabetic time zone abbreviation (e.g., @samp{EDT}), or nothing if no -+time zone is determinable. See @samp{%z} for how it is determined. -+@end table -+ -+ -+@node Date conversion specifiers -+@subsection Date conversion specifiers -+ -+@cindex date conversion specifiers -+@cindex conversion specifiers, date -+ -+@command{date} conversion specifiers related to dates. -+ -+@table @samp -+@item %a -+locale's abbreviated weekday name (e.g., @samp{Sun}) -+@item %A -+locale's full weekday name, variable length (e.g., @samp{Sunday}) -+@item %b -+locale's abbreviated month name (e.g., @samp{Jan}) -+@item %B -+locale's full month name, variable length (e.g., @samp{January}) -+@item %c -+locale's date and time (e.g., @samp{Thu Mar @ 3 23:05:25 2005}) -+@item %C -+century. This is like @samp{%Y}, except the last two digits are omitted. -+For example, it is @samp{20} if @samp{%Y} is @samp{2000}, -+and is @samp{-0} if @samp{%Y} is @samp{-001}. -+It is normally at least two characters, but it may be more. -+@item %d -+day of month (e.g., @samp{01}) -+@item %D -+date; same as @samp{%m/%d/%y} -+@item %e -+day of month, space padded; same as @samp{%_d} -+@item %F -+full date in @acronym{ISO} 8601 format; same as @samp{%Y-%m-%d}. -+This is a good choice for a date format, as it is standard and -+is easy to sort in the usual case where years are in the range -+0000@dots{}9999. -+This is a @acronym{GNU} extension. -+@item %g -+year corresponding to the @acronym{ISO} week number, but without the century -+(range @samp{00} through @samp{99}). This has the same format and value -+as @samp{%y}, except that if the @acronym{ISO} week number (see -+@samp{%V}) belongs -+to the previous or next year, that year is used instead. -+This is a @acronym{GNU} extension. -+@item %G -+year corresponding to the @acronym{ISO} week number. This has the -+same format and value as @samp{%Y}, except that if the @acronym{ISO} -+week number (see -+@samp{%V}) belongs to the previous or next year, that year is used -+instead. -+It is normally useful only if @samp{%V} is also used; -+for example, the format @samp{%G-%m-%d} is probably a mistake, -+since it combines the ISO week number year with the conventional month and day. -+This is a @acronym{GNU} extension. -+@item %h -+same as @samp{%b} -+@item %j -+day of year (@samp{001}@dots{}@samp{366}) -+@item %m -+month (@samp{01}@dots{}@samp{12}) -+@item %u -+day of week (@samp{1}@dots{}@samp{7}) with @samp{1} corresponding to Monday -+@item %U -+week number of year, with Sunday as the first day of the week -+(@samp{00}@dots{}@samp{53}). -+Days in a new year preceding the first Sunday are in week zero. -+@item %V -+@acronym{ISO} week number, that is, the -+week number of year, with Monday as the first day of the week -+(@samp{01}@dots{}@samp{53}). -+If the week containing January 1 has four or more days in -+the new year, then it is considered week 1; otherwise, it is week 53 of -+the previous year, and the next week is week 1. (See the @acronym{ISO} 8601 -+standard.) -+@item %w -+day of week (@samp{0}@dots{}@samp{6}) with 0 corresponding to Sunday -+@item %W -+week number of year, with Monday as first day of week -+(@samp{00}@dots{}@samp{53}). -+Days in a new year preceding the first Monday are in week zero. -+@item %x -+locale's date representation (e.g., @samp{12/31/99}) -+@item %y -+last two digits of year (@samp{00}@dots{}@samp{99}) -+@item %Y -+year. This is normally at least four characters, but it may be more. -+Year @samp{0000} precedes year @samp{0001}, and year @samp{-001} -+precedes year @samp{0000}. -+@end table -+ -+ -+@node Literal conversion specifiers -+@subsection Literal conversion specifiers -+ -+@cindex literal conversion specifiers -+@cindex conversion specifiers, literal -+ -+@command{date} conversion specifiers that produce literal strings. -+ -+@table @samp -+@item %% -+a literal % -+@item %n -+a newline -+@item %t -+a horizontal tab -+@end table -+ -+ -+@node Padding and other flags -+@subsection Padding and other flags -+ -+@cindex numeric field padding -+@cindex padding of numeric fields -+@cindex fields, padding numeric -+ -+Unless otherwise specified, @command{date} normally pads numeric fields -+with zeros, so that, for -+example, numeric months are always output as two digits. -+Seconds since the epoch are not padded, though, -+since there is no natural width for them. -+ -+As a @acronym{GNU} extension, @command{date} recognizes any of the -+following optional flags after the @samp{%}: -+ -+@table @samp -+@item - -+(hyphen) Do not pad the field; useful if the output is intended for -+human consumption. -+@item _ -+(underscore) Pad with spaces; useful if you need a fixed -+number of characters in the output, but zeros are too distracting. -+@item 0 -+(zero) Pad with zeros even if the conversion specifier -+would normally pad with spaces. -+@item ^ -+Use upper case characters if possible. -+@item # -+Use opposite case characters if possible. -+A field that is normally upper case becomes lower case, and vice versa. -+@end table -+ -+@noindent -+Here are some examples of padding: -+ -+@example -+date +%d/%m -d "Feb 1" -+@result{} 01/02 -+date +%-d/%-m -d "Feb 1" -+@result{} 1/2 -+date +%_d/%_m -d "Feb 1" -+@result{} 1/ 2 -+@end example -+ -+As a @acronym{GNU} extension, you can specify the field width -+(after any flag, if present) as a decimal number. If the natural size of the -+output of the field has less than the specified number of characters, -+the result is written right adjusted and padded to the given -+size. For example, @samp{%9B} prints the right adjusted month name in -+a field of width 9. -+ -+An optional modifier can follow the optional flag and width -+specification. The modifiers are: -+ -+@table @samp -+@item E -+Use the locale's alternate representation for date and time. This -+modifier applies to the @samp{%c}, @samp{%C}, @samp{%x}, @samp{%X}, -+@samp{%y} and @samp{%Y} conversion specifiers. In a Japanese locale, for -+example, @samp{%Ex} might yield a date format based on the Japanese -+Emperors' reigns. -+ -+@item O -+Use the locale's alternate numeric symbols for numbers. This modifier -+applies only to numeric conversion specifiers. -+@end table -+ -+If the format supports the modifier but no alternate representation -+is available, it is ignored. -+ -+ -+@node Setting the time -+@subsection Setting the time -+ -+@cindex setting the time -+@cindex time setting -+@cindex appropriate privileges -+ -+If given an argument that does not start with @samp{+}, @command{date} sets -+the system clock to the date and time specified by that argument (as -+described below). You must have appropriate privileges to set the -+system clock. The @option{--date} and @option{--set} options may not be -+used with such an argument. The @option{--universal} option may be used -+with such an argument to indicate that the specified date and time are -+relative to Coordinated Universal Time rather than to the local time -+zone. -+ -+The argument must consist entirely of digits, which have the following -+meaning: -+ -+@table @samp -+@item MM -+month -+@item DD -+day within month -+@item hh -+hour -+@item mm -+minute -+@item CC -+first two digits of year (optional) -+@item YY -+last two digits of year (optional) -+@item ss -+second (optional) -+@end table -+ -+The @option{--set} option also sets the system clock; see the next section. -+ -+ -+@node Options for date -+@subsection Options for @command{date} -+ -+@cindex @command{date} options -+@cindex options for @command{date} -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -d @var{datestr} -+@itemx --date=@var{datestr} -+@opindex -d -+@opindex --date -+@cindex parsing date strings -+@cindex date strings, parsing -+@cindex arbitrary date strings, parsing -+@opindex yesterday -+@opindex tomorrow -+@opindex next @var{day} -+@opindex last @var{day} -+Display the date and time specified in @var{datestr} instead of the -+current date and time. @var{datestr} can be in almost any common -+format. It can contain month names, time zones, @samp{am} and @samp{pm}, -+@samp{yesterday}, etc. For example, @option{--date="2004-02-27 -+14:19:13.489392193 +0530"} specifies the instant of time that is -+489,392,193 nanoseconds after February 27, 2004 at 2:19:13 PM in a -+time zone that is 5 hours and 30 minutes east of @acronym{UTC}.@* -+Note: input currently must be in locale independent format. E.g., the -+LC_TIME=C below is needed to print back the correct date in many locales: -+@example -+date -d "$(LC_TIME=C date)" -+@end example -+@xref{Date input formats}. -+ -+@item -f @var{datefile} -+@itemx --file=@var{datefile} -+@opindex -f -+@opindex --file -+Parse each line in @var{datefile} as with @option{-d} and display the -+resulting date and time. If @var{datefile} is @samp{-}, use standard -+input. This is useful when you have many dates to process, because the -+system overhead of starting up the @command{date} executable many times can -+be considerable. -+ -+@item -r @var{file} -+@itemx --reference=@var{file} -+@opindex -r -+@opindex --reference -+Display the date and time of the last modification of @var{file}, -+instead of the current date and time. -+ -+@item -R -+@itemx --rfc-822 -+@itemx --rfc-2822 -+@opindex -R -+@opindex --rfc-822 -+@opindex --rfc-2822 -+Display the date and time using the format @samp{%a, %d %b %Y %H:%M:%S -+%z}, evaluated in the C locale so abbreviations are always in English. -+For example: -+ -+@example -+Fri, 09 Sep 2005 13:51:39 -0700 -+@end example -+ -+This format conforms to -+@uref{ftp://ftp.rfc-editor.org/in-notes/rfc2822.txt, Internet -+@acronym{RFCs} 2822} and -+@uref{ftp://ftp.rfc-editor.org/in-notes/rfc822.txt, 822}, the -+current and previous standards for Internet email. -+ -+@item --rfc-3339=@var{timespec} -+@opindex --rfc-3339=@var{timespec} -+Display the date using a format specified by -+@uref{ftp://ftp.rfc-editor.org/in-notes/rfc3339.txt, Internet -+@acronym{RFC} 3339}. This is a subset of the @acronym{ISO} 8601 -+format, except that it also permits applications to use a space rather -+than a @samp{T} to separate dates from times. Unlike the other -+standard formats, @acronym{RFC} 3339 format is always suitable as -+input for the @option{--date} (@option{-d}) and @option{--file} -+(@option{-f}) options, regardless of the current locale. -+ -+The argument @var{timespec} specifies how much of the time to include. -+It can be one of the following: -+ -+@table @samp -+@item date -+Print just the full-date, e.g., @samp{2005-09-14}. -+This is equivalent to the format @samp{%Y-%m-%d}. -+ -+@item seconds -+Print the full-date and full-time separated by a space, e.g., -+@samp{2005-09-14 00:56:06+05:30}. The output ends with a numeric -+time-offset; here the @samp{+05:30} means that local time is five -+hours and thirty minutes east of @acronym{UTC}. This is equivalent to -+the format @samp{%Y-%m-%d %H:%M:%S%:z}. -+ -+@item ns -+Like @samp{seconds}, but also print nanoseconds, e.g., -+@samp{2005-09-14 00:56:06.998458565+05:30}. -+This is equivalent to the format @samp{%Y-%m-%d %H:%M:%S.%N%:z}. -+ -+@end table -+ -+@item -s @var{datestr} -+@itemx --set=@var{datestr} -+@opindex -s -+@opindex --set -+Set the date and time to @var{datestr}. See @option{-d} above. -+ -+@item -u -+@itemx --utc -+@itemx --universal -+@opindex -u -+@opindex --utc -+@opindex --universal -+@cindex Coordinated Universal Time -+@cindex UTC -+@cindex Greenwich Mean Time -+@cindex GMT -+@vindex TZ -+Use Coordinated Universal Time (@acronym{UTC}) by operating as if the -+@env{TZ} environment variable were set to the string @samp{UTC0}. -+Coordinated -+Universal Time is often called ``Greenwich Mean Time'' (@sc{gmt}) for -+historical reasons. -+@end table -+ -+ -+@node Examples of date -+@subsection Examples of @command{date} -+ -+@cindex examples of @command{date} -+ -+Here are a few examples. Also see the documentation for the @option{-d} -+option in the previous section. -+ -+@itemize @bullet -+ -+@item -+To print the date of the day before yesterday: -+ -+@example -+date --date='2 days ago' -+@end example -+ -+@item -+To print the date of the day three months and one day hence: -+ -+@example -+date --date='3 months 1 day' -+@end example -+ -+@item -+To print the day of year of Christmas in the current year: -+ -+@example -+date --date='25 Dec' +%j -+@end example -+ -+@item -+To print the current full month name and the day of the month: -+ -+@example -+date '+%B %d' -+@end example -+ -+But this may not be what you want because for the first nine days of -+the month, the @samp{%d} expands to a zero-padded two-digit field, -+for example @samp{date -d 1may '+%B %d'} will print @samp{May 01}. -+ -+@item -+To print a date without the leading zero for one-digit days -+of the month, you can use the (@acronym{GNU} extension) -+@samp{-} flag to suppress -+the padding altogether: -+ -+@example -+date -d 1may '+%B %-d -+@end example -+ -+@item -+To print the current date and time in the format required by many -+non-@acronym{GNU} versions of @command{date} when setting the system clock: -+ -+@example -+date +%m%d%H%M%Y.%S -+@end example -+ -+@item -+To set the system clock forward by two minutes: -+ -+@example -+date --set='+2 minutes' -+@end example -+ -+@item -+To print the date in @acronym{RFC} 2822 format, -+use @samp{date --rfc-2822}. Here is some example output: -+ -+@example -+Fri, 09 Sep 2005 13:51:39 -0700 -+@end example -+ -+@anchor{%s-examples} -+@item -+To convert a date string to the number of seconds since the epoch -+(which is 1970-01-01 00:00:00 UTC), use the @option{--date} option with -+the @samp{%s} format. That can be useful in sorting and/or graphing -+and/or comparing data by date. The following command outputs the -+number of the seconds since the epoch for the time two minutes after the -+epoch: -+ -+@example -+date --date='1970-01-01 00:02:00 +0000' +%s -+120 -+@end example -+ -+If you do not specify time zone information in the date string, -+@command{date} uses your computer's idea of the time zone when -+interpreting the string. For example, if your computer's time zone is -+that of Cambridge, Massachusetts, which was then 5 hours (i.e., 18,000 -+seconds) behind UTC: -+ -+@example -+# local time zone used -+date --date='1970-01-01 00:02:00' +%s -+18120 -+@end example -+ -+@item -+If you're sorting or graphing dated data, your raw date values may be -+represented as seconds since the epoch. But few people can look at -+the date @samp{946684800} and casually note ``Oh, that's the first second -+of the year 2000 in Greenwich, England.'' -+ -+@example -+date --date='2000-01-01 UTC' +%s -+946684800 -+@end example -+ -+An alternative is to use the @option{--utc} (@option{-u}) option. -+Then you may omit @samp{UTC} from the date string. Although this -+produces the same result for @samp{%s} and many other format sequences, -+with a time zone offset different from zero, it would give a different -+result for zone-dependent formats like @samp{%z}. -+ -+@example -+date -u --date=2000-01-01 +%s -+946684800 -+@end example -+ -+To convert such an unwieldy number of seconds back to -+a more readable form, use a command like this: -+ -+@smallexample -+# local time zone used -+date -d '1970-01-01 UTC 946684800 seconds' +"%Y-%m-%d %T %z" -+1999-12-31 19:00:00 -0500 -+@end smallexample -+ -+Or if you do not mind depending on the @samp{@@} feature present since -+coreutils 5.3.0, you could shorten this to: -+ -+@smallexample -+date -d @@946684800 +"%F %T %z" -+1999-12-31 19:00:00 -0500 -+@end smallexample -+ -+Often it is better to output UTC-relative date and time: -+ -+@smallexample -+date -u -d '1970-01-01 946684800 seconds' +"%Y-%m-%d %T %z" -+2000-01-01 00:00:00 +0000 -+@end smallexample -+ -+@end itemize -+ -+ -+@node arch invocation -+@section @command{arch}: Print machine hardware name -+ -+@pindex arch -+@cindex print machine hardware name -+@cindex system information, printing -+ -+@command{arch} prints the machine hardware name, -+and is equivalent to @samp{uname -m}. -+Synopsis: -+ -+@example -+arch [@var{option}] -+@end example -+ -+The program accepts the @ref{Common options} only. -+ -+@exitstatus -+ -+ -+@node uname invocation -+@section @command{uname}: Print system information -+ -+@pindex uname -+@cindex print system information -+@cindex system information, printing -+ -+@command{uname} prints information about the machine and operating system -+it is run on. If no options are given, @command{uname} acts as if the -+@option{-s} option were given. Synopsis: -+ -+@example -+uname [@var{option}]@dots{} -+@end example -+ -+If multiple options or @option{-a} are given, the selected information is -+printed in this order: -+ -+@example -+@var{kernel-name} @var{nodename} @var{kernel-release} @var{kernel-version} -+@var{machine} @var{processor} @var{hardware-platform} @var{operating-system} -+@end example -+ -+The information may contain internal spaces, so such output cannot be -+parsed reliably. In the following example, @var{release} is -+@samp{2.2.18ss.e820-bda652a #4 SMP Tue Jun 5 11:24:08 PDT 2001}: -+ -+@smallexample -+uname -a -+@result{} Linux dum 2.2.18 #4 SMP Tue Jun 5 11:24:08 PDT 2001 i686 unknown unknown GNU/Linux -+@end smallexample -+ -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -a -+@itemx --all -+@opindex -a -+@opindex --all -+Print all of the below information, except omit the processor type -+and the hardware platform name if they are unknown. -+ -+@item -i -+@itemx --hardware-platform -+@opindex -i -+@opindex --hardware-platform -+@cindex implementation, hardware -+@cindex hardware platform -+@cindex platform, hardware -+Print the hardware platform name -+(sometimes called the hardware implementation). -+Print @samp{unknown} if the kernel does not make this information -+easily available, as is the case with Linux kernels. -+ -+@item -m -+@itemx --machine -+@opindex -m -+@opindex --machine -+@cindex machine type -+@cindex hardware class -+@cindex hardware type -+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 -+@opindex --processor -+@cindex host processor type -+Print the processor type (sometimes called the instruction set -+architecture or ISA). -+Print @samp{unknown} if the kernel does not make this information -+easily available, as is the case with Linux kernels. -+ -+@item -o -+@itemx --operating-system -+@opindex -o -+@opindex --operating-system -+@cindex operating system name -+Print the name of the operating system. -+ -+@item -r -+@itemx --kernel-release -+@opindex -r -+@opindex --kernel-release -+@cindex kernel release -+@cindex release of kernel -+Print the kernel release. -+ -+@item -s -+@itemx --kernel-name -+@opindex -s -+@opindex --kernel-name -+@cindex kernel name -+@cindex name of kernel -+Print the kernel name. -+@acronym{POSIX} 1003.1-2001 (@pxref{Standards conformance}) calls this -+``the implementation of the operating system'', because the -+@acronym{POSIX} specification itself has no notion of ``kernel''. -+The kernel name might be the same as the operating system name printed -+by the @option{-o} or @option{--operating-system} option, but it might -+differ. Some operating systems (e.g., FreeBSD, HP-UX) have the same -+name as their underlying kernels; others (e.g., GNU/Linux, Solaris) -+do not. -+ -+@item -v -+@itemx --kernel-version -+@opindex -v -+@opindex --kernel-version -+@cindex kernel version -+@cindex version of kernel -+Print the kernel version. -+ -+@end table -+ -+@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}. -+ -+@exitstatus -+ -+ -+@node hostid invocation -+@section @command{hostid}: Print numeric host identifier -+ -+@pindex hostid -+@cindex printing the host identifier -+ -+@command{hostid} prints the numeric identifier of the current host -+in hexadecimal. This command accepts no arguments. -+The only options are @option{--help} and @option{--version}. -+@xref{Common options}. -+ -+For example, here's what it prints on one system I use: -+ -+@example -+$ hostid -+1bac013d -+@end example -+ -+On that system, the 32-bit quantity happens to be closely -+related to the system's Internet address, but that isn't always -+the case. -+ -+@exitstatus -+ -+@node uptime invocation -+@section @command{uptime}: Print system uptime and load -+ -+@pindex uptime -+@cindex printing the system uptime and load -+ -+@command{uptime} prints the current time, the system's uptime, the -+number of logged-in users and the current load average. -+ -+If an argument is specified, it is used as the file to be read -+to discover how many users are logged in. If no argument is -+specified, a system default is used (@command{uptime --help} indicates -+the default setting). -+ -+The only options are @option{--help} and @option{--version}. -+@xref{Common options}. -+ -+For example, here's what it prints right now on one system I use: -+ -+@example -+$ uptime -+ 14:07 up 3:35, 3 users, load average: 1.39, 1.15, 1.04 -+@end example -+ -+The precise method of calculation of load average varies somewhat -+between systems. Some systems calculate it as the average number of -+runnable processes over the last 1, 5 and 15 minutes, but some systems -+also include processes in the uninterruptible sleep state (that is, -+those processes which are waiting for disk I/O). The Linux kernel -+includes uninterruptible processes. -+ -+@node SELinux context -+@chapter SELinux context -+ -+@cindex SELinux context -+@cindex SELinux, context -+@cindex commands for SELinux context -+ -+This section describes commands for operations with SELinux -+contexts. -+ -+@menu -+* chcon invocation:: Change SELinux context of file -+* runcon invocation:: Run a command in specified SELinux context -+@end menu -+ -+@node chcon invocation -+@section @command{chcon}: Change SELinux context of file -+ -+@pindex chcon -+@cindex changing security context -+@cindex change SELinux context -+ -+@command{chcon} changes the SELinux security context of the selected files. -+Synopses: -+ -+@smallexample -+chcon [@var{option}]@dots{} @var{context} @var{file}@dots{} -+chcon [@var{option}]@dots{} [-u @var{user}] [-r @var{role}] [-l @var{range}] [-t @var{type}] @var{file}@dots{} -+chcon [@var{option}]@dots{} --reference=@var{rfile} @var{file}@dots{} -+@end smallexample -+ -+Change the SELinux security context of each @var{file} to @var{context}. -+With @option{--reference}, change the security context of each @var{file} -+to that of @var{rfile}. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -h -+@itemx --no-dereference -+@opindex -h -+@opindex --no-dereference -+@cindex no dereference -+Affect symbolic links instead of any referenced file. -+ -+@item --reference=@var{rfile} -+@opindex --reference -+@cindex reference file -+Use @var{rfile}'s security context rather than specifying a @var{context} value. -+ -+@item -R -+@itemx --recursive -+@opindex -R -+@opindex --recursive -+Operate on files and directories recursively. -+ -+@choptH -+@xref{Traversing symlinks}. -+ -+@choptL -+@xref{Traversing symlinks}. -+ -+@choptP -+@xref{Traversing symlinks}. -+ -+@item -v -+@itemx --verbose -+@opindex -v -+@opindex --verbose -+@cindex diagnostic -+Output a diagnostic for every file processed. -+ -+@item -u @var{user} -+@itemx --user=@var{user} -+@opindex -u -+@opindex --user -+Set user @var{user} in the target security context. -+ -+@item -r @var{role} -+@itemx --role=@var{role} -+@opindex -r -+@opindex --role -+Set role @var{role} in the target security context. -+ -+@item -t @var{type} -+@itemx --type=@var{type} -+@opindex -t -+@opindex --type -+Set type @var{type} in the target security context. -+ -+@item -l @var{range} -+@itemx --range=@var{range} -+@opindex -l -+@opindex --range -+Set range @var{range} in the target security context. -+ -+@end table -+ -+@exitstatus -+ -+@node runcon invocation -+@section @command{runcon}: Run a command in specified SELinux context -+ -+@pindex runcon -+@cindex run with security context -+ -+ -+@command{runcon} runs file in specified SELinux security context. -+ -+Synopses: -+@smallexample -+runcon @var{context} @var{command} [@var{args}] -+runcon [ -c ] [-u @var{user}] [-r @var{role}] [-t @var{type}] [-l @var{range}] @var{command} [@var{args}] -+@end smallexample -+ -+Run @var{command} with completely-specified @var{context}, or with -+current or transitioned security context modified by one or more of @var{level}, -+@var{role}, @var{type} and @var{user}. -+ -+If none of @option{-c}, @option{-t}, @option{-u}, @option{-r}, or @option{-l} -+is specified, the first argument is used as the complete context. -+Any additional arguments after @var{command} -+are interpreted as arguments to the command. -+ -+With neither @var{context} nor @var{command}, print the current security context. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -c -+@itemx --compute -+@opindex -c -+@opindex --compute -+Compute process transition context before modifying. -+ -+@item -u @var{user} -+@itemx --user=@var{user} -+@opindex -u -+@opindex --user -+Set user @var{user} in the target security context. -+ -+@item -r @var{role} -+@itemx --role=@var{role} -+@opindex -r -+@opindex --role -+Set role @var{role} in the target security context. -+ -+@item -t @var{type} -+@itemx --type=@var{type} -+@opindex -t -+@opindex --type -+Set type @var{type} in the target security context. -+ -+@item -l @var{range} -+@itemx --range=@var{range} -+@opindex -l -+@opindex --range -+Set range @var{range} in the target security context. -+ -+@end table -+ -+@cindex exit status of @command{runcon} -+Exit status: -+ -+@display -+126 if @var{command} is found but cannot be invoked -+127 if @command{runcon} itself fails or if @var{command} cannot be found -+the exit status of @var{command} otherwise -+@end display -+ -+@node Modified command invocation -+@chapter Modified command invocation -+ -+@cindex modified command invocation -+@cindex invocation of commands, modified -+@cindex commands for invoking other commands -+ -+This section describes commands that run other commands in some context -+different than the current one: a modified environment, as a different -+user, etc. -+ -+@menu -+* chroot invocation:: Modify the root directory. -+* env invocation:: Modify environment variables. -+* nice invocation:: Modify niceness. -+* nohup invocation:: Immunize to hangups. -+* stdbuf invocation:: Modify buffering of standard streams. -+* su invocation:: Modify user and group ID. -+* timeout invocation:: Run with time limit. -+@end menu -+ -+ -+@node chroot invocation -+@section @command{chroot}: Run a command with a different root directory -+ -+@pindex chroot -+@cindex running a program in a specified root directory -+@cindex root directory, running a program in a specified -+ -+@command{chroot} runs a command with a specified root directory. -+On many systems, only the super-user can do this.@footnote{However, -+some systems (e.g., FreeBSD) can be configured to allow certain regular -+users to use the @code{chroot} system call, and hence to run this program. -+Also, on Cygwin, anyone can run the @command{chroot} command, because the -+underlying function is non-privileged due to lack of support in MS-Windows.} -+Synopses: -+ -+@example -+chroot @var{option} @var{newroot} [@var{command} [@var{args}]@dots{}] -+chroot @var{option} -+@end example -+ -+Ordinarily, file names are looked up starting at the root of the -+directory structure, i.e., @file{/}. @command{chroot} changes the root to -+the directory @var{newroot} (which must exist) and then runs -+@var{command} with optional @var{args}. If @var{command} is not -+specified, the default is the value of the @env{SHELL} environment -+variable or @command{/bin/sh} if not set, invoked with the @option{-i} option. -+@var{command} must not be a special built-in utility -+(@pxref{Special built-in utilities}). -+ -+The program accepts the following options. Also see @ref{Common options}. -+Options must precede operands. -+ -+@table @samp -+ -+@itemx --userspec=@var{user}[:@var{group}] -+@opindex --userspec -+By default, @var{command} is run with the same credentials -+as the invoking process. -+Use this option to run it as a different @var{user} and/or with a -+different primary @var{group}. -+ -+@itemx --groups=@var{groups} -+@opindex --groups -+Use this option to specify the supplementary @var{groups} to be -+used by the new process. -+The items in the list (names or numeric IDs) must be separated by commas. -+ -+@end table -+ -+Here are a few tips to help avoid common problems in using chroot. -+To start with a simple example, make @var{command} refer to a statically -+linked binary. If you were to use a dynamically linked executable, then -+you'd have to arrange to have the shared libraries in the right place under -+your new root directory. -+ -+For example, if you create a statically linked @command{ls} executable, -+and put it in @file{/tmp/empty}, you can run this command as root: -+ -+@example -+$ chroot /tmp/empty /ls -Rl / -+@end example -+ -+Then you'll see output like this: -+ -+@example -+/: -+total 1023 -+-rwxr-xr-x 1 0 0 1041745 Aug 16 11:17 ls -+@end example -+ -+If you want to use a dynamically linked executable, say @command{bash}, -+then first run @samp{ldd bash} to see what shared objects it needs. -+Then, in addition to copying the actual binary, also copy the listed -+files to the required positions under your intended new root directory. -+Finally, if the executable requires any other files (e.g., data, state, -+device files), copy them into place, too. -+ -+@cindex exit status of @command{chroot} -+Exit status: -+ -+@display -+1 if @command{chroot} itself fails -+126 if @var{command} is found but cannot be invoked -+127 if @var{command} cannot be found -+the exit status of @var{command} otherwise -+@end display -+ -+ -+@node env invocation -+@section @command{env}: Run a command in a modified environment -+ -+@pindex env -+@cindex environment, running a program in a modified -+@cindex modified environment, running a program in a -+@cindex running a program in a modified environment -+ -+@command{env} runs a command with a modified environment. Synopses: -+ -+@example -+env [@var{option}]@dots{} [@var{name}=@var{value}]@dots{} @c -+[@var{command} [@var{args}]@dots{}] -+env -+@end example -+ -+Operands of the form @samp{@var{variable}=@var{value}} set -+the environment variable @var{variable} to value @var{value}. -+@var{value} may be empty (@samp{@var{variable}=}). Setting a variable -+to an empty value is different from unsetting it. -+These operands are evaluated left-to-right, so if two operands -+mention the same variable the earlier is ignored. -+ -+Environment variable names can be empty, and can contain any -+characters other than @samp{=} and @acronym{ASCII} @sc{nul}. -+However, it is wise to limit yourself to names that -+consist solely of underscores, digits, and @acronym{ASCII} letters, -+and that begin with a non-digit, as applications like the shell do not -+work well with other names. -+ -+@vindex PATH -+The first operand that does not contain the character @samp{=} -+specifies the program to invoke; it is -+searched for according to the @env{PATH} environment variable. Any -+remaining arguments are passed as arguments to that program. -+The program should not be a special built-in utility -+(@pxref{Special built-in utilities}). -+ -+@cindex environment, printing -+ -+If no command name is specified following the environment -+specifications, the resulting environment is printed. This is like -+specifying the @command{printenv} program. -+ -+The program accepts the following options. Also see @ref{Common options}. -+Options must precede operands. -+ -+@table @samp -+ -+@item -u @var{name} -+@itemx --unset=@var{name} -+@opindex -u -+@opindex --unset -+Remove variable @var{name} from the environment, if it was in the -+environment. -+ -+@item - -+@itemx -i -+@itemx --ignore-environment -+@opindex - -+@opindex -i -+@opindex --ignore-environment -+Start with an empty environment, ignoring the inherited environment. -+ -+@end table -+ -+@cindex exit status of @command{env} -+Exit status: -+ -+@display -+0 if no @var{command} is specified and the environment is output -+1 if @command{env} itself fails -+126 if @var{command} is found but cannot be invoked -+127 if @var{command} cannot be found -+the exit status of @var{command} otherwise -+@end display -+ -+ -+@node nice invocation -+@section @command{nice}: Run a command with modified niceness -+ -+@pindex nice -+@cindex niceness -+@cindex scheduling, affecting -+@cindex appropriate privileges -+ -+@command{nice} prints or modifies a process's @dfn{niceness}, -+a parameter that affects whether the process is scheduled favorably. -+Synopsis: -+ -+@example -+nice [@var{option}]@dots{} [@var{command} [@var{arg}]@dots{}] -+@end example -+ -+If no arguments are given, @command{nice} prints the current niceness. -+Otherwise, @command{nice} runs the given @var{command} with its -+niceness adjusted. By default, its niceness is incremented by 10. -+ -+Niceness values range at least from @minus{}20 (process has high priority -+and gets more resources, thus slowing down other processes) through 19 -+(process has lower priority and runs slowly itself, but has less impact -+on the speed of other running processes). Some systems -+may have a wider range of nicenesses; conversely, other systems may -+enforce more restrictive limits. An attempt to set the niceness -+outside the supported range is treated as an attempt to use the -+minimum or maximum supported value. -+ -+A niceness should not be confused with a scheduling priority, which -+lets applications determine the order in which threads are scheduled -+to run. Unlike a priority, a niceness is merely advice to the -+scheduler, which the scheduler is free to ignore. Also, as a point of -+terminology, @acronym{POSIX} defines the behavior of @command{nice} in -+terms of a @dfn{nice value}, which is the nonnegative difference -+between a niceness and the minimum niceness. Though @command{nice} -+conforms to @acronym{POSIX}, its documentation and diagnostics use the -+term ``niceness'' for compatibility with historical practice. -+ -+@var{command} must not be a special built-in utility (@pxref{Special -+built-in utilities}). -+ -+@mayConflictWithShellBuiltIn{nice} -+ -+The program accepts the following option. Also see @ref{Common options}. -+Options must precede operands. -+ -+@table @samp -+@item -n @var{adjustment} -+@itemx --adjustment=@var{adjustment} -+@opindex -n -+@opindex --adjustment -+Add @var{adjustment} instead of 10 to the command's niceness. If -+@var{adjustment} is negative and you lack appropriate privileges, -+@command{nice} issues a warning but otherwise acts as if you specified -+a zero adjustment. -+ -+For compatibility @command{nice} also supports an obsolete -+option syntax @option{-@var{adjustment}}. New scripts should use -+@option{-n @var{adjustment}} instead. -+ -+@end table -+ -+@cindex exit status of @command{nice} -+Exit status: -+ -+@display -+0 if no @var{command} is specified and the niceness is output -+1 if @command{nice} itself fails -+126 if @var{command} is found but cannot be invoked -+127 if @var{command} cannot be found -+the exit status of @var{command} otherwise -+@end display -+ -+It is sometimes useful to run a non-interactive program with reduced niceness. -+ -+@example -+$ nice factor 4611686018427387903 -+@end example -+ -+Since @command{nice} prints the current niceness, -+you can invoke it through itself to demonstrate how it works. -+ -+The default behavior is to increase the niceness by @samp{10}: -+ -+@example -+$ nice -+0 -+$ nice nice -+10 -+$ nice -n 10 nice -+10 -+@end example -+ -+The @var{adjustment} is relative to the current niceness. In the -+next example, the first @command{nice} invocation runs the second one -+with niceness 10, and it in turn runs the final one with a niceness -+that is 3 more: -+ -+@example -+$ nice nice -n 3 nice -+13 -+@end example -+ -+Specifying a niceness larger than the supported range -+is the same as specifying the maximum supported value: -+ -+@example -+$ nice -n 10000000000 nice -+19 -+@end example -+ -+Only a privileged user may run a process with lower niceness: -+ -+@example -+$ nice -n -1 nice -+nice: cannot set niceness: Permission denied -+0 -+$ sudo nice -n -1 nice -+-1 -+@end example -+ -+ -+@node nohup invocation -+@section @command{nohup}: Run a command immune to hangups -+ -+@pindex nohup -+@cindex hangups, immunity to -+@cindex immunity to hangups -+@cindex logging out and continuing to run -+ -+@flindex nohup.out -+@command{nohup} runs the given @var{command} with hangup signals ignored, -+so that the command can continue running in the background after you log -+out. Synopsis: -+ -+@example -+nohup @var{command} [@var{arg}]@dots{} -+@end example -+ -+If standard input is a terminal, it is redirected from -+@file{/dev/null} so that terminal sessions do not mistakenly consider -+the terminal to be used by the command. This is a @acronym{GNU} -+extension; programs intended to be portable to non-@acronym{GNU} hosts -+should use @samp{nohup @var{command} [@var{arg}]@dots{} make.log -+@end example -+ -+@command{nohup} does not automatically put the command it runs in the -+background; you must do that explicitly, by ending the command line -+with an @samp{&}. Also, @command{nohup} does not alter the -+niceness of @var{command}; use @command{nice} for that, -+e.g., @samp{nohup nice @var{command}}. -+ -+@var{command} must not be a special built-in utility (@pxref{Special -+built-in utilities}). -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. Options must precede operands. -+ -+@cindex exit status of @command{nohup} -+Exit status: -+ -+@display -+126 if @var{command} is found but cannot be invoked -+127 if @command{nohup} itself fails or if @var{command} cannot be found -+the exit status of @var{command} otherwise -+@end display -+ -+ -+@node stdbuf invocation -+@section @command{stdbuf}: Run a command with modified I/O stream buffering -+ -+@pindex stdbuf -+@cindex standard streams, buffering -+@cindex line buffered -+ -+@command{stdbuf} allows one to modify the buffering operations of the -+three standard I/O streams associated with a program. Synopsis: -+ -+@example -+stdbuf @var{option}@dots{} @var{command} -+@end example -+ -+Any additional @var{arg}s are passed as additional arguments to the -+@var{command}. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+ -+@item -i @var{mode} -+@itemx --input=@var{mode} -+@opindex -i -+@opindex --input -+Adjust the standard input stream buffering. -+ -+@item -o @var{mode} -+@itemx --output=@var{mode} -+@opindex -o -+@opindex --output -+Adjust the standard output stream buffering. -+ -+@item -e @var{mode} -+@itemx --error=@var{mode} -+@opindex -e -+@opindex --error -+Adjust the standard error stream buffering. -+ -+@end table -+ -+The @var{mode} can be specified as follows: -+ -+@table @samp -+ -+@item L -+Set the stream to line buffered mode. -+In this mode data is coalesced until a newline is output or -+input is read from any stream attached to a terminal device. -+This option is invalid with standard input. -+ -+@item 0 -+Disable buffering of the selected stream. -+In this mode data is output immediately and only the -+amount of data requested is read from input. -+ -+@item @var{size} -+Specify the size of the buffer to use in fully buffered mode. -+@multiplierSuffixesNoBlocks{size} -+ -+@end table -+ -+NOTE: If @var{command} adjusts the buffering of its standard streams -+(@command{tee} does for e.g.) then that will override corresponding settings -+changed by @command{stdbuf}. Also some filters (like @command{dd} and -+@command{cat} etc.) don't use streams for I/O, and are thus unaffected -+by @command{stdbuf} settings. -+ -+@cindex exit status of @command{stdbuf} -+Exit status: -+ -+@display -+125 if @command{stdbuf} itself fails -+126 if @var{command} is found but cannot be invoked -+127 if @var{command} cannot be found -+the exit status of @var{command} otherwise -+@end display -+ -+ -+@node su invocation -+@section @command{su}: Run a command with substitute user and group ID -+ -+@pindex su -+@cindex substitute user and group IDs -+@cindex user ID, switching -+@cindex super-user, becoming -+@cindex root, becoming -+ -+@command{su} allows one user to temporarily become another user. It runs a -+command (often an interactive shell) with the real and effective user -+ID, group ID, and supplemental groups of a given @var{user}. Synopsis: -+ -+@example -+su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}] -+@end example -+ -+@cindex passwd entry, and @command{su} shell -+@flindex /bin/sh -+@flindex /etc/passwd -+If no @var{user} is given, the default is @code{root}, the super-user. -+The shell to use is taken from @var{user}'s @code{passwd} entry, or -+@file{/bin/sh} if none is specified there. If @var{user} has a -+password, @command{su} prompts for the password unless run by a user with -+effective user ID of zero (the super-user). -+ -+@vindex HOME -+@vindex SHELL -+@vindex USER -+@vindex LOGNAME -+@cindex login shell -+By default, @command{su} does not change the current directory. -+It sets the environment variables @env{HOME} and @env{SHELL} -+from the password entry for @var{user}, and if @var{user} is not -+the super-user, sets @env{USER} and @env{LOGNAME} to @var{user}. -+By default, the shell is not a login shell. -+ -+Any additional @var{arg}s are passed as additional arguments to the -+shell. -+ -+@cindex @option{-su} -+GNU @command{su} does not treat @file{/bin/sh} or any other shells specially -+(e.g., by setting @code{argv[0]} to @option{-su}, passing @option{-c} only -+to certain shells, etc.). -+ -+@findex syslog -+@command{su} can optionally be compiled to use @code{syslog} to report -+failed, and optionally successful, @command{su} attempts. (If the system -+supports @code{syslog}.) However, GNU @command{su} does not check if the -+user is a member of the @code{wheel} group; see below. -+ -+The program accepts the following options. Also see @ref{Common options}. -+ -+@table @samp -+@item -c @var{command} -+@itemx --command=@var{command} -+@opindex -c -+@opindex --command -+Pass @var{command}, a single command line to run, to the shell with -+a @option{-c} option instead of starting an interactive shell. -+ -+@item -f -+@itemx --fast -+@opindex -f -+@opindex --fast -+@flindex .cshrc -+@cindex file name pattern expansion, disabled -+@cindex globbing, disabled -+Pass the @option{-f} option to the shell. This probably only makes sense -+if the shell run is @command{csh} or @command{tcsh}, for which the @option{-f} -+option prevents reading the startup file (@file{.cshrc}). With -+Bourne-like shells, the @option{-f} option disables file name pattern -+expansion (globbing), which is not likely to be useful. -+ -+@item - -+@itemx -l -+@itemx --login -+@opindex - -+@opindex -l -+@opindex --login -+@c other variables already indexed above -+@vindex TERM -+@vindex PATH -+@cindex login shell, creating -+Make the shell a login shell. This means the following. Unset all -+environment variables except @env{TERM}, @env{HOME}, and @env{SHELL} -+(which are set as described above), and @env{USER} and @env{LOGNAME} -+(which are set, even for the super-user, as described above), and set -+@env{PATH} to a compiled-in default value. Change to @var{user}'s home -+directory. Prepend @samp{-} to the shell's name, intended to make it -+read its login startup file(s). -+ -+@item -m -+@itemx -p -+@itemx --preserve-environment -+@opindex -m -+@opindex -p -+@opindex --preserve-environment -+@cindex environment, preserving -+@flindex /etc/shells -+@cindex restricted shell -+Do not change the environment variables @env{HOME}, @env{USER}, -+@env{LOGNAME}, or @env{SHELL}. Run the shell given in the environment -+variable @env{SHELL} instead of the shell from @var{user}'s passwd -+entry, unless the user running @command{su} is not the super-user and -+@var{user}'s shell is restricted. A @dfn{restricted shell} is one that -+is not listed in the file @file{/etc/shells}, or in a compiled-in list -+if that file does not exist. Parts of what this option does can be -+overridden by @option{--login} and @option{--shell}. -+ -+@item -s @var{shell} -+@itemx --shell=@var{shell} -+@opindex -s -+@opindex --shell -+Run @var{shell} instead of the shell from @var{user}'s passwd entry, -+unless the user running @command{su} is not the super-user and @var{user}'s -+shell is restricted (see @option{-m} just above). -+ -+@end table -+ -+@cindex exit status of @command{su} -+Exit status: -+ -+@display -+1 if @command{su} itself fails -+126 if subshell is found but cannot be invoked -+127 if subshell cannot be found -+the exit status of the subshell otherwise -+@end display -+ -+@cindex wheel group, not supported -+@cindex group wheel, not supported -+@cindex fascism -+@subsection Why GNU @command{su} does not support the @samp{wheel} group -+ -+(This section is by Richard Stallman.) -+ -+@cindex Twenex -+@cindex MIT AI lab -+Sometimes a few of the users try to hold total power over all the -+rest. For example, in 1984, a few users at the MIT AI lab decided to -+seize power by changing the operator password on the Twenex system and -+keeping it secret from everyone else. (I was able to thwart this coup -+and give power back to the users by patching the kernel, but I -+wouldn't know how to do that in Unix.) -+ -+However, occasionally the rulers do tell someone. Under the usual -+@command{su} mechanism, once someone learns the root password who -+sympathizes with the ordinary users, he or she can tell the rest. The -+``wheel group'' feature would make this impossible, and thus cement the -+power of the rulers. -+ -+I'm on the side of the masses, not that of the rulers. If you are -+used to supporting the bosses and sysadmins in whatever they do, you -+might find this idea strange at first. -+ -+ -+@node timeout invocation -+@section @command{timeout}: Run a command with a time limit -+ -+@pindex timeout -+@cindex time limit -+@cindex run commands with bounded time -+ -+@command{timeout} runs the given @var{command} and kills it if it is -+still running after the specified time interval. Synopsis: -+ -+@example -+timeout [@var{option}] @var{number}[smhd] @var{command} [@var{arg}]@dots{} -+@end example -+ -+@cindex time units -+@var{number} is an integer followed by an optional unit; the default -+is seconds. The units are: -+ -+@table @samp -+@item s -+seconds -+@item m -+minutes -+@item h -+hours -+@item d -+days -+@end table -+ -+@var{command} must not be a special built-in utility (@pxref{Special -+built-in utilities}). -+ -+The program accepts the following option. Also see @ref{Common options}. -+Options must precede operands. -+ -+@table @samp -+@item -s @var{signal} -+@itemx --signal=@var{signal} -+@opindex -s -+@opindex --signal -+Send this @var{signal} to @var{command} on timeout, rather than the -+default @samp{TERM} signal. @var{signal} may be a name like @samp{HUP} -+or a number. Also see @xref{Signal specifications}. -+ -+@end table -+ -+@cindex exit status of @command{timeout} -+Exit status: -+ -+@display -+124 if @var{command} times out -+125 if @command{timeout} itself fails -+126 if @var{command} is found but cannot be invoked -+127 if @var{command} cannot be found -+the exit status of @var{command} otherwise -+@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 -+@acronym{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. For a list of supported -+signal names and numbers see @xref{Signal specifications}. -+ -+@node Delaying -+@chapter Delaying -+ -+@cindex delaying commands -+@cindex commands for delaying -+ -+@c Perhaps @command{wait} or other commands should be described here also? -+ -+@menu -+* sleep invocation:: Delay for a specified time. -+@end menu -+ -+ -+@node sleep invocation -+@section @command{sleep}: Delay for a specified time -+ -+@pindex sleep -+@cindex delay for a specified time -+ -+@command{sleep} pauses for an amount of time specified by the sum of -+the values of the command line arguments. -+Synopsis: -+ -+@example -+sleep @var{number}[smhd]@dots{} -+@end example -+ -+@cindex time units -+Each argument is a number followed by an optional unit; the default -+is seconds. The units are: -+ -+@table @samp -+@item s -+seconds -+@item m -+minutes -+@item h -+hours -+@item d -+days -+@end table -+ -+Historical implementations of @command{sleep} have required that -+@var{number} be an integer, and only accepted a single argument -+without a suffix. However, GNU @command{sleep} accepts -+arbitrary floating point numbers (using a period before any fractional -+digits). -+ -+The only options are @option{--help} and @option{--version}. @xref{Common -+options}. -+ -+@c sleep is a shell built-in at least with Solaris 11's /bin/sh -+@mayConflictWithShellBuiltIn{sleep} -+ -+@exitstatus -+ -+ -+@node Numeric operations -+@chapter Numeric operations -+ -+@cindex numeric operations -+These programs do numerically-related operations. -+ -+@menu -+* factor invocation:: Show factors of numbers. -+* seq invocation:: Print sequences of numbers. -+@end menu -+ -+ -+@node factor invocation -+@section @command{factor}: Print prime factors -+ -+@pindex factor -+@cindex prime factors -+ -+@command{factor} prints prime factors. Synopses: -+ -+@example -+factor [@var{number}]@dots{} -+factor @var{option} -+@end example -+ -+If no @var{number} is specified on the command line, @command{factor} reads -+numbers from standard input, delimited by newlines, tabs, or spaces. -+ -+The @command{factor} command supports only a small number of options: -+ -+@table @samp -+@item --help -+Print a short help on standard output, then exit without further -+processing. -+ -+@item --version -+Print the program version on standard output, then exit without further -+processing. -+@end table -+ -+Factoring the product of the eighth and ninth Mersenne primes -+takes about 30 milliseconds of CPU time on a 2.2 GHz Athlon. -+ -+@example -+M8=`echo 2^31-1|bc` ; M9=`echo 2^61-1|bc` -+/usr/bin/time -f '%U' factor $(echo "$M8 * $M9" | bc) -+4951760154835678088235319297: 2147483647 2305843009213693951 -+0.03 -+@end example -+ -+Similarly, factoring the eighth Fermat number @math{2^{256}+1} takes -+about 20 seconds on the same machine. -+ -+Factoring large prime numbers is, in general, hard. The Pollard Rho -+algorithm used by @command{factor} is particularly effective for -+numbers with relatively small factors. If you wish to factor large -+numbers which do not have small factors (for example, numbers which -+are the product of two large primes), other methods are far better. -+ -+If @command{factor} is built without using GNU MP, only -+single-precision arithmetic is available, and so large numbers -+(typically @math{2^{64}} and above) will not be supported. The single-precision -+code uses an algorithm which is designed for factoring smaller -+numbers. -+ -+@exitstatus -+ -+ -+@node seq invocation -+@section @command{seq}: Print numeric sequences -+ -+@pindex seq -+@cindex numeric sequences -+@cindex sequence of numbers -+ -+@command{seq} prints a sequence of numbers to standard output. Synopses: -+ -+@example -+seq [@var{option}]@dots{} @var{last} -+seq [@var{option}]@dots{} @var{first} @var{last} -+seq [@var{option}]@dots{} @var{first} @var{increment} @var{last} -+@end example -+ -+@command{seq} prints the numbers from @var{first} to @var{last} by -+@var{increment}. By default, each number is printed on a separate line. -+When @var{increment} is not specified, it defaults to @samp{1}, -+even when @var{first} is larger than @var{last}. -+@var{first} also defaults to @samp{1}. So @code{seq 1} prints -+@samp{1}, but @code{seq 0} and @code{seq 10 5} produce no output. -+Floating-point numbers -+may be specified (using a period before any fractional digits). -+ -+The program accepts the following options. Also see @ref{Common options}. -+Options must precede operands. -+ -+@table @samp -+@item -f @var{format} -+@itemx --format=@var{format} -+@opindex -f @var{format} -+@opindex --format=@var{format} -+@cindex formatting of numbers in @command{seq} -+Print all numbers using @var{format}. -+@var{format} must contain exactly one of the @samp{printf}-style -+floating point conversion specifications @samp{%a}, @samp{%e}, -+@samp{%f}, @samp{%g}, @samp{%A}, @samp{%E}, @samp{%F}, @samp{%G}. -+The @samp{%} may be followed by zero or more flags taken from the set -+@samp{-+#0 '}, then an optional width containing one or more digits, -+then an optional precision consisting of a @samp{.} followed by zero -+or more digits. @var{format} may also contain any number of @samp{%%} -+conversion specifications. All conversion specifications have the -+same meaning as with @samp{printf}. -+ -+The default format is derived from @var{first}, @var{step}, and -+@var{last}. If these all use a fixed point decimal representation, -+the default format is @samp{%.@var{p}f}, where @var{p} is the minimum -+precision that can represent the output numbers exactly. Otherwise, -+the default format is @samp{%g}. -+ -+@item -s @var{string} -+@itemx --separator=@var{string} -+@cindex separator for numbers in @command{seq} -+Separate numbers with @var{string}; default is a newline. -+The output always terminates with a newline. -+ -+@item -w -+@itemx --equal-width -+Print all numbers with the same width, by padding with leading zeros. -+@var{first}, @var{step}, and @var{last} should all use a fixed point -+decimal representation. -+(To have other kinds of padding, use @option{--format}). -+ -+@end table -+ -+You can get finer-grained control over output with @option{-f}: -+ -+@example -+$ seq -f '(%9.2E)' -9e5 1.1e6 1.3e6 -+(-9.00E+05) -+( 2.00E+05) -+( 1.30E+06) -+@end example -+ -+If you want hexadecimal integer output, you can use @command{printf} -+to perform the conversion: -+ -+@example -+$ printf '%x\n' `seq 1048575 1024 1050623` -+fffff -+1003ff -+1007ff -+@end example -+ -+For very long lists of numbers, use xargs to avoid -+system limitations on the length of an argument list: -+ -+@example -+$ seq 1000000 | xargs printf '%x\n' | tail -n 3 -+f423e -+f423f -+f4240 -+@end example -+ -+To generate octal output, use the printf @code{%o} format instead -+of @code{%x}. -+ -+On most systems, seq can produce whole-number output for values up to -+at least @math{2^{53}}. Larger integers are approximated. The details -+differ depending on your floating-point implementation, but a common -+case is that @command{seq} works with integers through @math{2^{64}}, -+and larger integers may not be numerically correct: -+ -+@example -+$ seq 18446744073709551616 1 18446744073709551618 -+18446744073709551616 -+18446744073709551616 -+18446744073709551618 -+@end example -+ -+Be careful when using @command{seq} with outlandish values: otherwise -+you may see surprising results, as @command{seq} uses floating point -+internally. For example, on the x86 platform, where the internal -+representation uses a 64-bit fraction, the command: -+ -+@example -+seq 1 0.0000000000000000001 1.0000000000000000009 -+@end example -+ -+outputs 1.0000000000000000007 twice and skips 1.0000000000000000008. -+ -+@exitstatus -+ -+ -+@node File permissions -+@chapter File permissions -+@include perm.texi -+ -+@include getdate.texi -+ -+@c What's GNU? -+@c Arnold Robbins -+@node Opening the software toolbox -+@chapter Opening the Software Toolbox -+ -+An earlier version of this chapter appeared in -+@uref{http://www.linuxjournal.com/article.php?sid=2762, the -+@cite{What's GNU?} column of @cite{Linux Journal}, 2 (June, 1994)}. -+It was written by Arnold Robbins. -+ -+@menu -+* Toolbox introduction:: Toolbox introduction -+* I/O redirection:: I/O redirection -+* The who command:: The @command{who} command -+* The cut command:: The @command{cut} command -+* The sort command:: The @command{sort} command -+* The uniq command:: The @command{uniq} command -+* Putting the tools together:: Putting the tools together -+@end menu -+ -+ -+@node Toolbox introduction -+@unnumberedsec Toolbox Introduction -+ -+This month's column is only peripherally related to the GNU Project, in -+that it describes a number of the GNU tools on your GNU/Linux system and how they -+might be used. What it's really about is the ``Software Tools'' philosophy -+of program development and usage. -+ -+The software tools philosophy was an important and integral concept -+in the initial design and development of Unix (of which Linux and GNU are -+essentially clones). Unfortunately, in the modern day press of -+Internetworking and flashy GUIs, it seems to have fallen by the -+wayside. This is a shame, since it provides a powerful mental model -+for solving many kinds of problems. -+ -+Many people carry a Swiss Army knife around in their pants pockets (or -+purse). A Swiss Army knife is a handy tool to have: it has several knife -+blades, a screwdriver, tweezers, toothpick, nail file, corkscrew, and perhaps -+a number of other things on it. For the everyday, small miscellaneous jobs -+where you need a simple, general purpose tool, it's just the thing. -+ -+On the other hand, an experienced carpenter doesn't build a house using -+a Swiss Army knife. Instead, he has a toolbox chock full of specialized -+tools---a saw, a hammer, a screwdriver, a plane, and so on. And he knows -+exactly when and where to use each tool; you won't catch him hammering nails -+with the handle of his screwdriver. -+ -+The Unix developers at Bell Labs were all professional programmers and trained -+computer scientists. They had found that while a one-size-fits-all program -+might appeal to a user because there's only one program to use, in practice -+such programs are -+ -+@enumerate a -+@item -+difficult to write, -+ -+@item -+difficult to maintain and -+debug, and -+ -+@item -+difficult to extend to meet new situations. -+@end enumerate -+ -+Instead, they felt that programs should be specialized tools. In short, each -+program ``should do one thing well.'' No more and no less. Such programs are -+simpler to design, write, and get right---they only do one thing. -+ -+Furthermore, they found that with the right machinery for hooking programs -+together, that the whole was greater than the sum of the parts. By combining -+several special purpose programs, you could accomplish a specific task -+that none of the programs was designed for, and accomplish it much more -+quickly and easily than if you had to write a special purpose program. -+We will see some (classic) examples of this further on in the column. -+(An important additional point was that, if necessary, take a detour -+and build any software tools you may need first, if you don't already -+have something appropriate in the toolbox.) -+ -+@node I/O redirection -+@unnumberedsec I/O Redirection -+ -+Hopefully, you are familiar with the basics of I/O redirection in the -+shell, in particular the concepts of ``standard input,'' ``standard output,'' -+and ``standard error''. Briefly, ``standard input'' is a data source, where -+data comes from. A program should not need to either know or care if the -+data source is a disk file, a keyboard, a magnetic tape, or even a punched -+card reader. Similarly, ``standard output'' is a data sink, where data goes -+to. The program should neither know nor care where this might be. -+Programs that only read their standard input, do something to the data, -+and then send it on, are called @dfn{filters}, by analogy to filters in a -+water pipeline. -+ -+With the Unix shell, it's very easy to set up data pipelines: -+ -+@smallexample -+program_to_create_data | filter1 | ... | filterN > final.pretty.data -+@end smallexample -+ -+We start out by creating the raw data; each filter applies some successive -+transformation to the data, until by the time it comes out of the pipeline, -+it is in the desired form. -+ -+This is fine and good for standard input and standard output. Where does the -+standard error come in to play? Well, think about @command{filter1} in -+the pipeline above. What happens if it encounters an error in the data it -+sees? If it writes an error message to standard output, it will just -+disappear down the pipeline into @command{filter2}'s input, and the -+user will probably never see it. So programs need a place where they can send -+error messages so that the user will notice them. This is standard error, -+and it is usually connected to your console or window, even if you have -+redirected standard output of your program away from your screen. -+ -+For filter programs to work together, the format of the data has to be -+agreed upon. The most straightforward and easiest format to use is simply -+lines of text. Unix data files are generally just streams of bytes, with -+lines delimited by the @acronym{ASCII} @sc{lf} (Line Feed) character, -+conventionally called a ``newline'' in the Unix literature. (This is -+@code{'\n'} if you're a C programmer.) This is the format used by all -+the traditional filtering programs. (Many earlier operating systems -+had elaborate facilities and special purpose programs for managing -+binary data. Unix has always shied away from such things, under the -+philosophy that it's easiest to simply be able to view and edit your -+data with a text editor.) -+ -+OK, enough introduction. Let's take a look at some of the tools, and then -+we'll see how to hook them together in interesting ways. In the following -+discussion, we will only present those command line options that interest -+us. As you should always do, double check your system documentation -+for the full story. -+ -+@node The who command -+@unnumberedsec The @command{who} Command -+ -+The first program is the @command{who} command. By itself, it generates a -+list of the users who are currently logged in. Although I'm writing -+this on a single-user system, we'll pretend that several people are -+logged in: -+ -+@example -+$ who -+@print{} arnold console Jan 22 19:57 -+@print{} miriam ttyp0 Jan 23 14:19(:0.0) -+@print{} bill ttyp1 Jan 21 09:32(:0.0) -+@print{} arnold ttyp2 Jan 23 20:48(:0.0) -+@end example -+ -+Here, the @samp{$} is the usual shell prompt, at which I typed @samp{who}. -+There are three people logged in, and I am logged in twice. On traditional -+Unix systems, user names are never more than eight characters long. This -+little bit of trivia will be useful later. The output of @command{who} is nice, -+but the data is not all that exciting. -+ -+@node The cut command -+@unnumberedsec The @command{cut} Command -+ -+The next program we'll look at is the @command{cut} command. This program -+cuts out columns or fields of input data. For example, we can tell it -+to print just the login name and full name from the @file{/etc/passwd} -+file. The @file{/etc/passwd} file has seven fields, separated by -+colons: -+ -+@example -+arnold:xyzzy:2076:10:Arnold D. Robbins:/home/arnold:/bin/bash -+@end example -+ -+To get the first and fifth fields, we would use @command{cut} like this: -+ -+@example -+$ cut -d: -f1,5 /etc/passwd -+@print{} root:Operator -+@dots{} -+@print{} arnold:Arnold D. Robbins -+@print{} miriam:Miriam A. Robbins -+@dots{} -+@end example -+ -+With the @option{-c} option, @command{cut} will cut out specific characters -+(i.e., columns) in the input lines. This is useful for input data -+that has fixed width fields, and does not have a field separator. For -+example, list the Monday dates for the current month: -+ -+@c Is using cal ok? Looked at gcal, but I don't like it. -+@example -+$ cal | cut -c 3-5 -+@print{}Mo -+@print{} -+@print{} 6 -+@print{} 13 -+@print{} 20 -+@print{} 27 -+@end example -+ -+@node The sort command -+@unnumberedsec The @command{sort} Command -+ -+Next we'll look at the @command{sort} command. This is one of the most -+powerful commands on a Unix-style system; one that you will often find -+yourself using when setting up fancy data plumbing. -+ -+The @command{sort} -+command reads and sorts each file named on the command line. It then -+merges the sorted data and writes it to standard output. It will read -+standard input if no files are given on the command line (thus -+making it into a filter). The sort is based on the character collating -+sequence or based on user-supplied ordering criteria. -+ -+ -+@node The uniq command -+@unnumberedsec The @command{uniq} Command -+ -+Finally (at least for now), we'll look at the @command{uniq} program. When -+sorting data, you will often end up with duplicate lines, lines that -+are identical. Usually, all you need is one instance of each line. -+This is where @command{uniq} comes in. The @command{uniq} program reads its -+standard input. It prints only one -+copy of each repeated line. It does have several options. Later on, -+we'll use the @option{-c} option, which prints each unique line, preceded -+by a count of the number of times that line occurred in the input. -+ -+ -+@node Putting the tools together -+@unnumberedsec Putting the Tools Together -+ -+Now, let's suppose this is a large ISP server system with dozens of users -+logged in. The management wants the system administrator to write a program that will -+generate a sorted list of logged in users. Furthermore, even if a user -+is logged in multiple times, his or her name should only show up in the -+output once. -+ -+The administrator could sit down with the system documentation and write a C -+program that did this. It would take perhaps a couple of hundred lines -+of code and about two hours to write it, test it, and debug it. -+However, knowing the software toolbox, the administrator can instead start out -+by generating just a list of logged on users: -+ -+@example -+$ who | cut -c1-8 -+@print{} arnold -+@print{} miriam -+@print{} bill -+@print{} arnold -+@end example -+ -+Next, sort the list: -+ -+@example -+$ who | cut -c1-8 | sort -+@print{} arnold -+@print{} arnold -+@print{} bill -+@print{} miriam -+@end example -+ -+Finally, run the sorted list through @command{uniq}, to weed out duplicates: -+ -+@example -+$ who | cut -c1-8 | sort | uniq -+@print{} arnold -+@print{} bill -+@print{} miriam -+@end example -+ -+The @command{sort} command actually has a @option{-u} option that does what -+@command{uniq} does. However, @command{uniq} has other uses for which one -+cannot substitute @samp{sort -u}. -+ -+The administrator puts this pipeline into a shell script, and makes it available for -+all the users on the system (@samp{#} is the system administrator, -+or @code{root}, prompt): -+ -+@example -+# cat > /usr/local/bin/listusers -+who | cut -c1-8 | sort | uniq -+^D -+# chmod +x /usr/local/bin/listusers -+@end example -+ -+There are four major points to note here. First, with just four -+programs, on one command line, the administrator was able to save about two -+hours worth of work. Furthermore, the shell pipeline is just about as -+efficient as the C program would be, and it is much more efficient in -+terms of programmer time. People time is much more expensive than -+computer time, and in our modern ``there's never enough time to do -+everything'' society, saving two hours of programmer time is no mean -+feat. -+ -+Second, it is also important to emphasize that with the -+@emph{combination} of the tools, it is possible to do a special -+purpose job never imagined by the authors of the individual programs. -+ -+Third, it is also valuable to build up your pipeline in stages, as we did here. -+This allows you to view the data at each stage in the pipeline, which helps -+you acquire the confidence that you are indeed using these tools correctly. -+ -+Finally, by bundling the pipeline in a shell script, other users can use -+your command, without having to remember the fancy plumbing you set up for -+them. In terms of how you run them, shell scripts and compiled programs are -+indistinguishable. -+ -+After the previous warm-up exercise, we'll look at two additional, more -+complicated pipelines. For them, we need to introduce two more tools. -+ -+The first is the @command{tr} command, which stands for ``transliterate.'' -+The @command{tr} command works on a character-by-character basis, changing -+characters. Normally it is used for things like mapping upper case to -+lower case: -+ -+@example -+$ echo ThIs ExAmPlE HaS MIXED case! | tr '[:upper:]' '[:lower:]' -+@print{} this example has mixed case! -+@end example -+ -+There are several options of interest: -+ -+@table @code -+@item -c -+work on the complement of the listed characters, i.e., -+operations apply to characters not in the given set -+ -+@item -d -+delete characters in the first set from the output -+ -+@item -s -+squeeze repeated characters in the output into just one character. -+@end table -+ -+We will be using all three options in a moment. -+ -+The other command we'll look at is @command{comm}. The @command{comm} -+command takes two sorted input files as input data, and prints out the -+files' lines in three columns. The output columns are the data lines -+unique to the first file, the data lines unique to the second file, and -+the data lines that are common to both. The @option{-1}, @option{-2}, and -+@option{-3} command line options @emph{omit} the respective columns. (This is -+non-intuitive and takes a little getting used to.) For example: -+ -+@example -+$ cat f1 -+@print{} 11111 -+@print{} 22222 -+@print{} 33333 -+@print{} 44444 -+$ cat f2 -+@print{} 00000 -+@print{} 22222 -+@print{} 33333 -+@print{} 55555 -+$ comm f1 f2 -+@print{} 00000 -+@print{} 11111 -+@print{} 22222 -+@print{} 33333 -+@print{} 44444 -+@print{} 55555 -+@end example -+ -+The file name @file{-} tells @command{comm} to read standard input -+instead of a regular file. -+ -+Now we're ready to build a fancy pipeline. The first application is a word -+frequency counter. This helps an author determine if he or she is over-using -+certain words. -+ -+The first step is to change the case of all the letters in our input file -+to one case. ``The'' and ``the'' are the same word when doing counting. -+ -+@example -+$ tr '[:upper:]' '[:lower:]' < whats.gnu | ... -+@end example -+ -+The next step is to get rid of punctuation. Quoted words and unquoted words -+should be treated identically; it's easiest to just get the punctuation out of -+the way. -+ -+@smallexample -+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | ... -+@end smallexample -+ -+The second @command{tr} command operates on the complement of the listed -+characters, which are all the letters, the digits, the underscore, and -+the blank. The @samp{\n} represents the newline character; it has to -+be left alone. (The @acronym{ASCII} tab character should also be included for -+good measure in a production script.) -+ -+At this point, we have data consisting of words separated by blank space. -+The words only contain alphanumeric characters (and the underscore). The -+next step is break the data apart so that we have one word per line. This -+makes the counting operation much easier, as we will see shortly. -+ -+@smallexample -+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | -+> tr -s ' ' '\n' | ... -+@end smallexample -+ -+This command turns blanks into newlines. The @option{-s} option squeezes -+multiple newline characters in the output into just one. This helps us -+avoid blank lines. (The @samp{>} is the shell's ``secondary prompt.'' -+This is what the shell prints when it notices you haven't finished -+typing in all of a command.) -+ -+We now have data consisting of one word per line, no punctuation, all one -+case. We're ready to count each word: -+ -+@smallexample -+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | -+> tr -s ' ' '\n' | sort | uniq -c | ... -+@end smallexample -+ -+At this point, the data might look something like this: -+ -+@example -+ 60 a -+ 2 able -+ 6 about -+ 1 above -+ 2 accomplish -+ 1 acquire -+ 1 actually -+ 2 additional -+@end example -+ -+The output is sorted by word, not by count! What we want is the most -+frequently used words first. Fortunately, this is easy to accomplish, -+with the help of two more @command{sort} options: -+ -+@table @code -+@item -n -+do a numeric sort, not a textual one -+ -+@item -r -+reverse the order of the sort -+@end table -+ -+The final pipeline looks like this: -+ -+@smallexample -+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | -+> tr -s ' ' '\n' | sort | uniq -c | sort -n -r -+@print{} 156 the -+@print{} 60 a -+@print{} 58 to -+@print{} 51 of -+@print{} 51 and -+@dots{} -+@end smallexample -+ -+Whew! That's a lot to digest. Yet, the same principles apply. With six -+commands, on two lines (really one long one split for convenience), we've -+created a program that does something interesting and useful, in much -+less time than we could have written a C program to do the same thing. -+ -+A minor modification to the above pipeline can give us a simple spelling -+checker! To determine if you've spelled a word correctly, all you have to -+do is look it up in a dictionary. If it is not there, then chances are -+that your spelling is incorrect. So, we need a dictionary. -+The conventional location for a dictionary is @file{/usr/dict/words}. -+On my GNU/Linux system,@footnote{Redhat Linux 6.1, for the November 2000 -+revision of this article.} -+this is a sorted, 45,402 word dictionary. -+ -+Now, how to compare our file with the dictionary? As before, we generate -+a sorted list of words, one per line: -+ -+@smallexample -+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | -+> tr -s ' ' '\n' | sort -u | ... -+@end smallexample -+ -+Now, all we need is a list of words that are @emph{not} in the -+dictionary. Here is where the @command{comm} command comes in. -+ -+@smallexample -+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | -+> tr -s ' ' '\n' | sort -u | -+> comm -23 - /usr/dict/words -+@end smallexample -+ -+The @option{-2} and @option{-3} options eliminate lines that are only in the -+dictionary (the second file), and lines that are in both files. Lines -+only in the first file (standard input, our stream of words), are -+words that are not in the dictionary. These are likely candidates for -+spelling errors. This pipeline was the first cut at a production -+spelling checker on Unix. -+ -+There are some other tools that deserve brief mention. -+ -+@table @command -+@item grep -+search files for text that matches a regular expression -+ -+@item wc -+count lines, words, characters -+ -+@item tee -+a T-fitting for data pipes, copies data to files and to standard output -+ -+@item sed -+the stream editor, an advanced tool -+ -+@item awk -+a data manipulation language, another advanced tool -+@end table -+ -+The software tools philosophy also espoused the following bit of -+advice: ``Let someone else do the hard part.'' This means, take -+something that gives you most of what you need, and then massage it the -+rest of the way until it's in the form that you want. -+ -+To summarize: -+ -+@enumerate 1 -+@item -+Each program should do one thing well. No more, no less. -+ -+@item -+Combining programs with appropriate plumbing leads to results where -+the whole is greater than the sum of the parts. It also leads to novel -+uses of programs that the authors might never have imagined. -+ -+@item -+Programs should never print extraneous header or trailer data, since these -+could get sent on down a pipeline. (A point we didn't mention earlier.) -+ -+@item -+Let someone else do the hard part. -+ -+@item -+Know your toolbox! Use each program appropriately. If you don't have an -+appropriate tool, build one. -+@end enumerate -+ -+As of this writing, all the programs we've discussed are available via -+anonymous @command{ftp} from: @* -+@uref{ftp://gnudist.gnu.org/textutils/textutils-1.22.tar.gz}. (There may -+be more recent versions available now.) -+ -+None of what I have presented in this column is new. The Software Tools -+philosophy was first introduced in the book @cite{Software Tools}, by -+Brian Kernighan and P.J. Plauger (Addison-Wesley, ISBN 0-201-03669-X). -+This book showed how to write and use software tools. It was written in -+1976, using a preprocessor for FORTRAN named @command{ratfor} (RATional -+FORtran). At the time, C was not as ubiquitous as it is now; FORTRAN -+was. The last chapter presented a @command{ratfor} to FORTRAN -+processor, written in @command{ratfor}. @command{ratfor} looks an awful -+lot like C; if you know C, you won't have any problem following the -+code. -+ -+In 1981, the book was updated and made available as @cite{Software Tools -+in Pascal} (Addison-Wesley, ISBN 0-201-10342-7). Both books are -+still in print and are well worth -+reading if you're a programmer. They certainly made a major change in -+how I view programming. -+ -+The programs in both books are available from -+@uref{http://cm.bell-labs.com/who/bwk, Brian Kernighan's home page}. -+For a number of years, there was an active -+Software Tools Users Group, whose members had ported the original -+@command{ratfor} programs to essentially every computer system with a -+FORTRAN compiler. The popularity of the group waned in the middle 1980s -+as Unix began to spread beyond universities. -+ -+With the current proliferation of GNU code and other clones of Unix programs, -+these programs now receive little attention; modern C versions are -+much more efficient and do more than these programs do. Nevertheless, as -+exposition of good programming style, and evangelism for a still-valuable -+philosophy, these books are unparalleled, and I recommend them highly. -+ -+Acknowledgment: I would like to express my gratitude to Brian Kernighan -+of Bell Labs, the original Software Toolsmith, for reviewing this column. -+ -+@node GNU Free Documentation License -+@appendix GNU Free Documentation License -+ -+@include fdl.texi -+ -+@node Concept index -+@unnumbered Index -+ -+@printindex cp -+ -+@bye -+ -+@c Local variables: -+@c texinfo-column-for-description: 32 -+@c End: diff -urNp coreutils-8.0-orig/src/Makefile.am coreutils-8.0/src/Makefile.am --- coreutils-8.0-orig/src/Makefile.am 2009-09-21 14:29:33.000000000 +0200 +++ coreutils-8.0/src/Makefile.am 2009-10-07 10:04:27.000000000 +0200 @@ -16369,490 +87,6 @@ diff -urNp coreutils-8.0-orig/src/Makefile.am coreutils-8.0/src/Makefile.am dir_LDADD += $(LIB_ACL) ls_LDADD += $(LIB_ACL) -diff -urNp coreutils-8.0-orig/src/Makefile.am.orig coreutils-8.0/src/Makefile.am.orig ---- coreutils-8.0-orig/src/Makefile.am.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/Makefile.am.orig 2009-09-21 14:29:33.000000000 +0200 -@@ -0,0 +1,480 @@ -+## Process this file with automake to produce Makefile.in -*-Makefile-*- -+ -+## Copyright (C) 1990, 1991, 1993-2009 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 . -+ -+# These are the names of programs that are not installed by default. -+# This list is *not* intended for programs like who, nice, chroot, etc., -+# that are built only when certain requisite system features are detected. -+# Hence, if you want to install programs from this list anyway, say A and B, -+# use --enable-install-program=A,B -+no_install__progs = \ -+ arch hostname su -+ -+build_if_possible__progs = \ -+ chroot df hostid nice pinky stdbuf libstdbuf.so stty su uname uptime users who -+ -+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS) -+ -+EXTRA_PROGRAMS = \ -+ $(no_install__progs) \ -+ $(build_if_possible__progs) \ -+ [ chcon chgrp chown chmod cp dd dircolors du \ -+ ginstall link ln dir vdir ls mkdir \ -+ mkfifo mknod mktemp \ -+ mv nohup readlink rm rmdir shred stat sync touch unlink \ -+ cat cksum comm csplit cut expand fmt fold head join groups md5sum \ -+ nl od paste pr ptx sha1sum sha224sum sha256sum sha384sum sha512sum \ -+ shuf sort split sum tac tail tr tsort unexpand uniq wc \ -+ basename date dirname echo env expr factor false \ -+ id kill logname pathchk printenv printf pwd \ -+ runcon seq sleep tee \ -+ test timeout true truncate tty whoami yes \ -+ base64 -+ -+bin_PROGRAMS = $(OPTIONAL_BIN_PROGS) -+ -+noinst_PROGRAMS = setuidgid getlimits -+ -+pkglib_PROGRAMS = $(OPTIONAL_PKGLIB_PROGS) -+ -+noinst_HEADERS = \ -+ chown-core.h \ -+ copy.h \ -+ cp-hash.h \ -+ dircolors.h \ -+ fs.h \ -+ group-list.h \ -+ ls.h \ -+ operand2sig.h \ -+ prog-fprintf.h \ -+ remove.h \ -+ system.h \ -+ wheel-size.h \ -+ wheel.h \ -+ uname.h -+ -+EXTRA_DIST = dcgen dircolors.hin tac-pipe.c \ -+ wheel-gen.pl extract-magic c99-to-c89.diff -+BUILT_SOURCES = -+CLEANFILES = $(SCRIPTS) su -+ -+# Also remove these sometimes-built programs. -+# For example, even when excluded, they're built via sc_check-AUTHORS. -+CLEANFILES += $(no_install__progs) -+ -+AM_CPPFLAGS = -I$(top_srcdir)/lib -+ -+noinst_LIBRARIES = libver.a -+nodist_libver_a_SOURCES = version.c version.h -+ -+# Sometimes, the expansion of $(LIBINTL) includes -lc which may -+# include modules defining variables like `optind', so libcoreutils.a -+# must precede $(LIBINTL) in order to ensure we use GNU getopt. -+# But libcoreutils.a must also follow $(LIBINTL), since libintl uses -+# replacement functions defined in libcoreutils.a. -+LDADD = libver.a ../lib/libcoreutils.a $(LIBINTL) ../lib/libcoreutils.a -+ -+cat_LDADD = $(LDADD) -+df_LDADD = $(LDADD) -+du_LDADD = $(LDADD) -+getlimits_LDADD = $(LDADD) -+ptx_LDADD = $(LDADD) -+split_LDADD = $(LDADD) -+stdbuf_LDADD = $(LDADD) -+timeout_LDADD = $(LDADD) -+truncate_LDADD = $(LDADD) -+ -+# for eaccess in lib/euidaccess.c. -+chcon_LDADD = $(LDADD) $(LIB_SELINUX) -+cp_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX) -+ginstall_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX) -+mkdir_LDADD = $(LDADD) $(LIB_SELINUX) -+mkfifo_LDADD = $(LDADD) $(LIB_SELINUX) -+mknod_LDADD = $(LDADD) $(LIB_SELINUX) -+mv_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX) -+runcon_LDADD = $(LDADD) $(LIB_SELINUX) -+pathchk_LDADD = $(LDADD) $(LIB_EACCESS) -+rm_LDADD = $(LDADD) $(LIB_EACCESS) -+test_LDADD = $(LDADD) $(LIB_EACCESS) -+# This is for the '[' program. Automake transliterates '[' to '_'. -+__LDADD = $(LDADD) $(LIB_EACCESS) -+ -+# for clock_gettime and fdatasync -+dd_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC) -+dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) -+id_LDADD = $(LDADD) $(LIB_SELINUX) -+ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) -+mktemp_LDADD = $(LDADD) $(LIB_GETHRXTIME) -+pr_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) -+shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC) -+shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME) -+tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) -+vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP) -+ -+## If necessary, add -lm to resolve use of pow in lib/strtod.c. -+sort_LDADD = $(LDADD) $(POW_LIB) $(LIB_GETHRXTIME) -+ -+# for get_date and gettime -+date_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) -+touch_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) -+ -+# If necessary, add -lm to resolve use of pow in lib/strtod.c. -+# If necessary, add -liconv to resolve use of iconv in lib/unicodeio.c. -+printf_LDADD = $(LDADD) $(POW_LIB) $(LIBICONV) -+ -+# If necessary, add -lm to resolve use of pow in lib/strtod.c. -+seq_LDADD = $(LDADD) $(POW_LIB) -+ -+# If necessary, add libraries to resolve the `pow' reference in lib/strtod.c -+# and the `nanosleep' reference in lib/xnanosleep.c. -+nanosec_libs = $(LDADD) $(POW_LIB) $(LIB_NANOSLEEP) -+ -+# for various GMP functions -+expr_LDADD = $(LDADD) $(LIB_GMP) -+ -+# for various GMP functions -+factor_LDADD = $(LDADD) $(LIB_GMP) -+ -+sleep_LDADD = $(nanosec_libs) -+tail_LDADD = $(nanosec_libs) -+ -+# If necessary, add -lm to resolve use of pow in lib/strtod.c. -+uptime_LDADD = $(LDADD) $(POW_LIB) $(GETLOADAVG_LIBS) -+ -+su_LDADD = $(LDADD) $(LIB_CRYPT) -+ -+dir_LDADD += $(LIB_ACL) -+ls_LDADD += $(LIB_ACL) -+vdir_LDADD += $(LIB_ACL) -+cp_LDADD += $(LIB_ACL) $(LIB_XATTR) -+mv_LDADD += $(LIB_ACL) $(LIB_XATTR) -+ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR) -+ -+stat_LDADD = $(LDADD) $(LIB_SELINUX) -+ -+# Append $(LIBICONV) to each program that uses proper_name_utf8. -+cat_LDADD += $(LIBICONV) -+cp_LDADD += $(LIBICONV) -+df_LDADD += $(LIBICONV) -+du_LDADD += $(LIBICONV) -+getlimits_LDADD += $(LIBICONV) -+ptx_LDADD += $(LIBICONV) -+split_LDADD += $(LIBICONV) -+stdbuf_LDADD += $(LIBICONV) -+timeout_LDADD += $(LIBICONV) -+truncate_LDADD += $(LIBICONV) -+ -+# programs that use getaddrinfo (e.g., via canon_host) -+pinky_LDADD = $(LDADD) $(GETADDRINFO_LIB) -+who_LDADD = $(LDADD) $(GETADDRINFO_LIB) -+ -+$(PROGRAMS): ../lib/libcoreutils.a -+ -+# Get the release year from ../lib/version-etc.c. -+RELEASE_YEAR = \ -+ `sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \ -+ $(top_srcdir)/lib/version-etc.c` -+ -+all-local: su$(EXEEXT) -+ -+installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'` -+ -+setuid_root_mode = a=rx,u+s -+ -+install_su = \ -+ if test "$(INSTALL_SU)" = yes; then \ -+ p=su; \ -+ echo " $(INSTALL_PROGRAM) $$p $(installed_su)"; \ -+ $(INSTALL_PROGRAM) $$p $(installed_su); \ -+ echo " chown root $(installed_su)"; \ -+ chown root $(installed_su); \ -+ echo " chmod $(setuid_root_mode) $(installed_su)"; \ -+ chmod $(setuid_root_mode) $(installed_su); \ -+ else \ -+ :; \ -+ fi -+ -+install-root: su$(EXEEXT) -+ @$(install_su) -+ -+install-exec-hook: su$(EXEEXT) -+ @if test "$(INSTALL_SU)" = yes; then \ -+ TMPFILE=$(DESTDIR)$(bindir)/.su-$$$$; \ -+ rm -f $$TMPFILE; \ -+ echo > $$TMPFILE; \ -+## See if we can create a setuid root executable in $(bindir). -+## If not, then don't even try to install su. -+ can_create_suid_root_executable=no; \ -+ chown root $$TMPFILE > /dev/null 2>&1 \ -+ && chmod $(setuid_root_mode) $$TMPFILE > /dev/null 2>&1 \ -+ && can_create_suid_root_executable=yes; \ -+ rm -f $$TMPFILE; \ -+ if test $$can_create_suid_root_executable = yes; then \ -+ $(install_su); \ -+ else \ -+ echo "WARNING: insufficient access; not installing su"; \ -+ echo "NOTE: to install su, run 'make install-root' as root"; \ -+ rm -f $(installed_su); \ -+ fi; \ -+ else :; \ -+ fi -+ -+uninstall-local: -+# Remove su only if it's one we installed. -+ @if test "$(INSTALL_SU)" = yes; then \ -+ if grep '$(PACKAGE_NAME)' $(installed_su) > /dev/null 2>&1; then \ -+ echo " rm -f $(installed_su)"; \ -+ rm -f $(installed_su); \ -+ else :; \ -+ fi; \ -+ fi -+ -+copy_sources = copy.c cp-hash.c -+ -+# Use `ginstall' in the definition of PROGRAMS and in dependencies to avoid -+# confusion with the `install' target. The install rule transforms `ginstall' -+# to install before applying any user-specified name transformations. -+ -+transform = s/ginstall/install/; $(program_transform_name) -+ginstall_SOURCES = install.c prog-fprintf.c $(copy_sources) -+ -+# This is for the '[' program. Automake transliterates '[' to '_'. -+__SOURCES = lbracket.c -+ -+cp_SOURCES = cp.c $(copy_sources) -+dir_SOURCES = ls.c ls-dir.c -+vdir_SOURCES = ls.c ls-vdir.c -+id_SOURCES = id.c group-list.c -+groups_SOURCES = groups.c group-list.c -+ln_SOURCES = ln.c -+ls_SOURCES = ls.c ls-ls.c -+chown_SOURCES = chown.c chown-core.c -+chgrp_SOURCES = chgrp.c chown-core.c -+kill_SOURCES = kill.c operand2sig.c -+timeout_SOURCES = timeout.c operand2sig.c -+ -+mv_SOURCES = mv.c remove.c $(copy_sources) -+rm_SOURCES = rm.c remove.c -+ -+mkdir_SOURCES = mkdir.c prog-fprintf.c -+rmdir_SOURCES = rmdir.c prog-fprintf.c -+ -+uname_SOURCES = uname.c uname-uname.c -+arch_SOURCES = uname.c uname-arch.c -+ -+md5sum_SOURCES = md5sum.c -+md5sum_CPPFLAGS = -DHASH_ALGO_MD5=1 $(AM_CPPFLAGS) -+sha1sum_SOURCES = md5sum.c -+sha1sum_CPPFLAGS = -DHASH_ALGO_SHA1=1 $(AM_CPPFLAGS) -+sha224sum_SOURCES = md5sum.c -+sha224sum_CPPFLAGS = -DHASH_ALGO_SHA224=1 $(AM_CPPFLAGS) -+sha256sum_SOURCES = md5sum.c -+sha256sum_CPPFLAGS = -DHASH_ALGO_SHA256=1 $(AM_CPPFLAGS) -+sha384sum_SOURCES = md5sum.c -+sha384sum_CPPFLAGS = -DHASH_ALGO_SHA384=1 $(AM_CPPFLAGS) -+sha512sum_SOURCES = md5sum.c -+sha512sum_CPPFLAGS = -DHASH_ALGO_SHA512=1 $(AM_CPPFLAGS) -+ -+ginstall_CPPFLAGS = -DENABLE_MATCHPATHCON=1 $(AM_CPPFLAGS) -+ -+# Ensure we don't link against libcoreutils.a as that lib is -+# not compiled with -fPIC which causes issues on 64 bit at least -+libstdbuf_so_LDADD = -+ -+# Note libstdbuf is only compiled if GCC is available -+# (as per the check in configure.ac), so these flags should be available. -+# libtool is probably required to relax this dependency. -+libstdbuf_so_LDFLAGS = -shared -+libstdbuf_so_CFLAGS = -fPIC $(AM_CFLAGS) -+ -+editpl = sed -e 's,@''PERL''@,$(PERL),g' -+ -+BUILT_SOURCES += dircolors.h -+dircolors.h: dcgen dircolors.hin -+ $(AM_V_GEN)rm -f $@ $@-t -+ $(AM_V_at)$(PERL) -w -- $(srcdir)/dcgen $(srcdir)/dircolors.hin > $@-t -+ $(AM_V_at)chmod a-w $@-t -+ $(AM_V_at)mv $@-t $@ -+ -+wheel_size = 5 -+ -+BUILT_SOURCES += wheel-size.h -+wheel-size.h: Makefile.am -+ $(AM_V_GEN)rm -f $@ $@-t -+ $(AM_V_at)echo '#define WHEEL_SIZE $(wheel_size)' > $@-t -+ $(AM_V_at)chmod a-w $@-t -+ $(AM_V_at)mv $@-t $@ -+ -+BUILT_SOURCES += wheel.h -+wheel.h: wheel-gen.pl Makefile.am -+ $(AM_V_GEN)rm -f $@ $@-t -+ $(AM_V_at)$(srcdir)/wheel-gen.pl $(wheel_size) > $@-t -+ $(AM_V_at)chmod a-w $@-t -+ $(AM_V_at)mv $@-t $@ -+ -+# false exits nonzero even with --help or --version. -+# test doesn't support --help or --version. -+# Tell automake to exempt then from that installcheck test. -+AM_INSTALLCHECK_STD_OPTIONS_EXEMPT = false test -+ -+BUILT_SOURCES += fs.h -+fs.h: stat.c extract-magic -+ $(AM_V_GEN)rm -f $@ -+ $(AM_V_at)$(PERL) $(srcdir)/extract-magic $(srcdir)/stat.c > $@t -+ $(AM_V_at)chmod a-w $@t -+ $(AM_V_at)mv $@t $@ -+ -+BUILT_SOURCES += version.c -+version.c: Makefile -+ $(AM_V_GEN)rm -f $@ -+ $(AM_V_at)printf '#include \n' > $@t -+ $(AM_V_at)printf 'char const *Version = "$(PACKAGE_VERSION)";\n' >> $@t -+ $(AM_V_at)chmod a-w $@t -+ $(AM_V_at)mv $@t $@ -+ -+BUILT_SOURCES += version.h -+version.h: Makefile -+ $(AM_V_GEN)rm -f $@ -+ $(AM_V_at)printf 'extern char const *Version;\n' > $@t -+ $(AM_V_at)chmod a-w $@t -+ $(AM_V_at)mv $@t $@ -+ -+DISTCLEANFILES = version.c version.h -+MAINTAINERCLEANFILES = $(BUILT_SOURCES) -+ -+# Sort in traditional ASCII order, regardless of the current locale; -+# otherwise we may get into trouble with distinct strings that the -+# current locale considers to be equal. -+ASSORT = LC_ALL=C sort -+ -+all_programs = \ -+ $(bin_PROGRAMS) \ -+ $(bin_SCRIPTS) \ -+ $(EXTRA_PROGRAMS) -+ -+built_programs.list: -+ @echo $(bin_PROGRAMS) $(bin_SCRIPTS) | tr ' ' '\n' \ -+ | sed -e 's,$(EXEEXT)$$,,' | $(ASSORT) -u | tr '\n' ' ' -+ -+all_programs.list: -+ @echo $(all_programs) | tr ' ' '\n' | sed -e 's,$(EXEEXT)$$,,' \ -+ | $(ASSORT) -u -+ -+# This is required because we have broken inter-directory dependencies: -+# in order to generate all man pages, even those for which we don't -+# install a binary, require that all programs be built at distribution time. -+dist-hook: $(all_programs) -+ -+pm = progs-makefile -+pr = progs-readme -+# Ensure that the list of programs in README matches the list -+# of programs we can build. -+check: check-README check-duplicate-no-install -+.PHONY: check-README -+check-README: -+ $(AM_V_GEN)rm -rf $(pr) $(pm) -+ $(AM_V_at)echo $(all_programs) \ -+ | tr -s ' ' '\n' | sed -e 's,$(EXEEXT)$$,,;s/ginstall/install/' \ -+ | sed /libstdbuf/d \ -+ | $(ASSORT) -u > $(pm) && \ -+ sed -n '/^The programs .* are:/,/^[a-zA-Z]/p' $(top_srcdir)/README \ -+ | sed -n '/^ */s///p' | tr -s ' ' '\n' > $(pr) -+ $(AM_V_at)diff $(pm) $(pr) && rm -rf $(pr) $(pm) -+ -+# Ensure that a by-default-not-installed program (listed in -+# $(no_install__progs) is not also listed in $(EXTRA_PROGRAMS), because -+# if that were to happen, it *would* be installed by default. -+.PHONY: check-duplicate-no-install -+check-duplicate-no-install: tr -+ $(AM_V_GEN)test -z "`echo '$(EXTRA_PROGRAMS)'| ./tr ' ' '\n' | uniq -d`" -+ -+# Ensure that the list of programs and author names is accurate. -+# We need a UTF8 locale. If a lack of locale support or a missing -+# translation inhibits printing of UTF-8 names, just skip this test. -+au_dotdot = authors-dotdot -+au_actual = authors-actual -+.PHONY: sc_check-AUTHORS -+sc_check-AUTHORS: $(all_programs) -+ $(AM_V_GEN)locale=en_US.UTF-8; \ -+ LC_ALL="$$locale" ./cat --version \ -+ | grep ' Torbjorn ' > /dev/null \ -+ && { echo "$@: skipping this check"; exit 0; }; \ -+ rm -f $(au_actual) $(au_dotdot); \ -+ for i in `ls $(all_programs) | sed -e 's,$(EXEEXT)$$,,' \ -+ | sed /libstdbuf/d \ -+ | $(ASSORT) -u`; do \ -+ test "$$i" = '[' && continue; \ -+ exe=$$i; \ -+ if test "$$i" = install; then \ -+ exe=ginstall; \ -+ elif test "$$i" = test; then \ -+ exe='['; \ -+ fi; \ -+ LC_ALL="$$locale" ./$$exe --version \ -+ | perl -0 -pi -e 's/,\n/, /gm' \ -+ | sed -n -e '/Written by /{ s//'"$$i"': /;' \ -+ -e 's/,* and /, /; s/\.$$//; p; }'; \ -+ done > $(au_actual) && \ -+ sed -n '/^[^ ][^ ]*:/p' $(top_srcdir)/AUTHORS > $(au_dotdot) && \ -+ diff $(au_actual) $(au_dotdot) && rm -f $(au_actual) $(au_dotdot) -+ -+# The following rule is not designed to be portable, -+# and relies on tools that not everyone has. -+ -+# Most functions in src/*.c should have static scope. -+# Any that don't must be marked with `extern', but `main' -+# and `usage' are exceptions. They're always extern, but -+# don't need to be marked. Also functions starting with __ -+# are exempted due to possibly being added by the compiler -+# (when compiled as a shared library for example). -+# -+# The second nm|grep checks for file-scope variables with `extern' scope. -+.PHONY: sc_tight_scope -+sc_tight_scope: $(bin_PROGRAMS) -+ $(AM_V_GEN)t=exceptions-$$$$; \ -+ trap "s=$$?; rm -f $$t; exit $$s" 0 1 2 13 15; \ -+ src=`for f in $(SOURCES); do \ -+ test -f $$f && d= || d=$(srcdir)/; echo $$d$$f; done`; \ -+ hdr=`for f in $(noinst_HEADERS); do \ -+ test -f $$f && d= || d=$(srcdir)/; echo $$d$$f; done`; \ -+ ( printf 'main\nusage\n_.*\n'; \ -+ grep -h -A1 '^extern .*[^;]$$' $$src \ -+ | grep -vE '^(extern |--)' | sed 's/ .*//'; \ -+ perl -ne '/^extern (?:enum )?\S+ (\S*) \(/ and print "$$1\n"' $$hdr; \ -+ ) | $(ASSORT) -u | sed 's/^/^/;s/$$/$$/' > $$t; \ -+ nm -e *.$(OBJEXT) \ -+ | sed -n 's/.* T //p' \ -+ | sed 's/^_//' \ -+ | grep -Ev -f $$t && \ -+ { echo 'the above functions should have static scope' 1>&2; \ -+ exit 1; } || : ; \ -+ ( printf '^program_name$$\n'; \ -+ perl -ne '/^extern .*?\**(\w+);/ and print "^$$1\$$\n"' \ -+ $$hdr *.h ) | $(ASSORT) -u > $$t; \ -+ nm -e *.$(OBJEXT) \ -+ | sed -n 's/.* [BD] //p' \ -+ | sed 's/^_//' \ -+ | grep -Ev -f $$t && \ -+ { echo 'the above variables should have static scope' 1>&2; \ -+ exit 1; } || : -+ -+# Use the just-built ./ginstall, when not cross-compiling. -+if CROSS_COMPILING -+cu_install_program = @INSTALL_PROGRAM@ -+else -+cu_install_program = ./ginstall -+endif -+INSTALL_PROGRAM = $(cu_install_program) diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c --- coreutils-8.0-orig/src/su.c 2009-10-07 10:03:29.000000000 +0200 +++ coreutils-8.0/src/su.c 2009-10-07 10:04:27.000000000 +0200 @@ -17187,528 +421,4 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c - run_shell (shell, command, argv + optind, MAX (0, argc - optind)); + run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); } -diff -urNp coreutils-8.0-orig/src/su.c.orig coreutils-8.0/src/su.c.orig ---- coreutils-8.0-orig/src/su.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/su.c.orig 2009-10-07 10:03:29.000000000 +0200 -@@ -0,0 +1,521 @@ -+/* su for GNU. Run a shell with substitute user and group IDs. -+ Copyright (C) 1992-2006, 2008-2009 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 . */ -+ -+/* Run a shell with the real and effective UID and GID and groups -+ of USER, default `root'. -+ -+ The shell run is taken from USER's password entry, /bin/sh if -+ none is specified there. If the account has a password, su -+ prompts for a password unless run by a user with real UID 0. -+ -+ Does not change the current directory. -+ Sets `HOME' and `SHELL' from the password entry for USER, and if -+ USER is not root, sets `USER' and `LOGNAME' to USER. -+ The subshell is not a login shell. -+ -+ If one or more ARGs are given, they are passed as additional -+ arguments to the subshell. -+ -+ Does not handle /bin/sh or other shells specially -+ (setting argv[0] to "-su", passing -c only to certain shells, etc.). -+ I don't see the point in doing that, and it's ugly. -+ -+ This program intentionally does not support a "wheel group" that -+ restricts who can su to UID 0 accounts. RMS considers that to -+ be fascist. -+ -+ Compile-time options: -+ -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. -+ -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. -+ -+ -DSYSLOG_NON_ROOT Log all su's, not just those to root (UID 0). -+ Never logs attempted su's to nonexistent accounts. -+ -+ Written by David MacKenzie . */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "system.h" -+#include "getpass.h" -+ -+#if HAVE_SYSLOG_H && HAVE_SYSLOG -+# include -+#else -+# undef SYSLOG_SUCCESS -+# undef SYSLOG_FAILURE -+# undef SYSLOG_NON_ROOT -+#endif -+ -+#if HAVE_SYS_PARAM_H -+# include -+#endif -+ -+#ifndef HAVE_ENDGRENT -+# define endgrent() ((void) 0) -+#endif -+ -+#ifndef HAVE_ENDPWENT -+# define endpwent() ((void) 0) -+#endif -+ -+#if HAVE_SHADOW_H -+# include -+#endif -+ -+#include "error.h" -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "su" -+ -+#define AUTHORS proper_name ("David MacKenzie") -+ -+#if HAVE_PATHS_H -+# include -+#endif -+ -+/* The default PATH for simulated logins to non-superuser accounts. */ -+#ifdef _PATH_DEFPATH -+# define DEFAULT_LOGIN_PATH _PATH_DEFPATH -+#else -+# define DEFAULT_LOGIN_PATH ":/usr/ucb:/bin:/usr/bin" -+#endif -+ -+/* The default PATH for simulated logins to superuser accounts. */ -+#ifdef _PATH_DEFPATH_ROOT -+# define DEFAULT_ROOT_LOGIN_PATH _PATH_DEFPATH_ROOT -+#else -+# define DEFAULT_ROOT_LOGIN_PATH "/usr/ucb:/bin:/usr/bin:/etc" -+#endif -+ -+/* The default paths which get set are both bogus and oddly influenced -+ by and -D on the commands line. Just to be clear, we'll set -+ these explicitly. -ewt */ -+#undef DEFAULT_LOGIN_PATH -+#undef DEFAULT_ROOT_LOGIN_PATH -+#define DEFAULT_LOGIN_PATH "/usr/local/bin:/bin:/usr/bin" -+#define DEFAULT_ROOT_LOGIN_PATH \ -+ "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" -+ -+/* The shell to run if none is given in the user's passwd entry. */ -+#define DEFAULT_SHELL "/bin/sh" -+ -+/* The user to become if none is specified. */ -+#define DEFAULT_USER "root" -+ -+char *crypt (char const *key, char const *salt); -+ -+extern char **environ; -+ -+static void run_shell (char const *, char const *, char **, size_t) -+ ATTRIBUTE_NORETURN; -+ -+/* If true, pass the `-f' option to the subshell. */ -+static bool fast_startup; -+ -+/* If true, simulate a login instead of just starting a shell. */ -+static bool simulate_login; -+ -+/* If true, change some environment vars to indicate the user su'd to. */ -+static bool change_environment; -+ -+static struct option const longopts[] = -+{ -+ {"command", required_argument, NULL, 'c'}, -+ {"fast", no_argument, NULL, 'f'}, -+ {"login", no_argument, NULL, 'l'}, -+ {"preserve-environment", no_argument, NULL, 'p'}, -+ {"shell", required_argument, NULL, 's'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+/* Add NAME=VAL to the environment, checking for out of memory errors. */ -+ -+static void -+xsetenv (char const *name, char const *val) -+{ -+ size_t namelen = strlen (name); -+ size_t vallen = strlen (val); -+ char *string = xmalloc (namelen + 1 + vallen + 1); -+ strcpy (string, name); -+ string[namelen] = '='; -+ strcpy (string + namelen + 1, val); -+ if (putenv (string) != 0) -+ xalloc_die (); -+} -+ -+#if defined SYSLOG_SUCCESS || defined SYSLOG_FAILURE -+/* Log the fact that someone has run su to the user given by PW; -+ if SUCCESSFUL is true, they gave the correct password, etc. */ -+ -+static void -+log_su (struct passwd const *pw, bool successful) -+{ -+ const char *new_user, *old_user, *tty; -+ -+# ifndef SYSLOG_NON_ROOT -+ if (pw->pw_uid) -+ return; -+# endif -+ new_user = pw->pw_name; -+ /* The utmp entry (via getlogin) is probably the best way to identify -+ the user, especially if someone su's from a su-shell. */ -+ old_user = getlogin (); -+ if (!old_user) -+ { -+ /* getlogin can fail -- usually due to lack of utmp entry. -+ Resort to getpwuid. */ -+ struct passwd *pwd = getpwuid (getuid ()); -+ old_user = (pwd ? pwd->pw_name : ""); -+ } -+ tty = ttyname (STDERR_FILENO); -+ if (!tty) -+ tty = "none"; -+ /* 4.2BSD openlog doesn't have the third parameter. */ -+ openlog (last_component (program_name), 0 -+# ifdef LOG_AUTH -+ , LOG_AUTH -+# endif -+ ); -+ syslog (LOG_NOTICE, -+# ifdef SYSLOG_NON_ROOT -+ "%s(to %s) %s on %s", -+# else -+ "%s%s on %s", -+# endif -+ successful ? "" : "FAILED SU ", -+# ifdef SYSLOG_NON_ROOT -+ new_user, -+# endif -+ old_user, tty); -+ closelog (); -+} -+#endif -+ -+/* Ask the user for a password. -+ Return true if the user gives the correct password for entry PW, -+ false if not. Return true without asking for a password if run by UID 0 -+ or if PW has an empty password. */ -+ -+static bool -+correct_password (const struct passwd *pw) -+{ -+ char *unencrypted, *encrypted, *correct; -+#if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP -+ /* Shadow passwd stuff for SVR3 and maybe other systems. */ -+ struct spwd *sp = getspnam (pw->pw_name); -+ -+ endspent (); -+ if (sp) -+ correct = sp->sp_pwdp; -+ else -+#endif -+ correct = pw->pw_passwd; -+ -+ if (getuid () == 0 || !correct || correct[0] == '\0') -+ return true; -+ -+ unencrypted = getpass (_("Password:")); -+ if (!unencrypted) -+ { -+ error (0, 0, _("getpass: cannot open /dev/tty")); -+ return false; -+ } -+ encrypted = crypt (unencrypted, correct); -+ memset (unencrypted, 0, strlen (unencrypted)); -+ return STREQ (encrypted, correct); -+} -+ -+/* Update `environ' for the new shell based on PW, with SHELL being -+ the value for the SHELL environment variable. */ -+ -+static void -+modify_environment (const struct passwd *pw, const char *shell) -+{ -+ if (simulate_login) -+ { -+ /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. -+ Unset all other environment variables. */ -+ char const *term = getenv ("TERM"); -+ if (term) -+ term = xstrdup (term); -+ environ = xmalloc ((6 + !!term) * sizeof (char *)); -+ environ[0] = NULL; -+ if (term) -+ xsetenv ("TERM", term); -+ xsetenv ("HOME", pw->pw_dir); -+ xsetenv ("SHELL", shell); -+ xsetenv ("USER", pw->pw_name); -+ xsetenv ("LOGNAME", pw->pw_name); -+ xsetenv ("PATH", (pw->pw_uid -+ ? DEFAULT_LOGIN_PATH -+ : DEFAULT_ROOT_LOGIN_PATH)); -+ } -+ else -+ { -+ /* Set HOME, SHELL, and if not becoming a super-user, -+ USER and LOGNAME. */ -+ if (change_environment) -+ { -+ xsetenv ("HOME", pw->pw_dir); -+ xsetenv ("SHELL", shell); -+ if (pw->pw_uid) -+ { -+ xsetenv ("USER", pw->pw_name); -+ xsetenv ("LOGNAME", pw->pw_name); -+ } -+ } -+ } -+} -+ -+/* Become the user and group(s) specified by PW. */ -+ -+static void -+change_identity (const struct passwd *pw) -+{ -+#ifdef HAVE_INITGROUPS -+ errno = 0; -+ if (initgroups (pw->pw_name, pw->pw_gid) == -1) -+ error (EXIT_FAILURE, errno, _("cannot set groups")); -+ endgrent (); -+#endif -+ if (setgid (pw->pw_gid)) -+ error (EXIT_FAILURE, errno, _("cannot set group id")); -+ if (setuid (pw->pw_uid)) -+ error (EXIT_FAILURE, errno, _("cannot set user id")); -+} -+ -+/* Run SHELL, or DEFAULT_SHELL if SHELL is empty. -+ If COMMAND is nonzero, pass it to the shell with the -c option. -+ Pass ADDITIONAL_ARGS to the shell as more arguments; there -+ are N_ADDITIONAL_ARGS extra arguments. */ -+ -+static void -+run_shell (char const *shell, char const *command, char **additional_args, -+ size_t n_additional_args) -+{ -+ size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; -+ char const **args = xnmalloc (n_args, sizeof *args); -+ size_t argno = 1; -+ -+ if (simulate_login) -+ { -+ char *arg0; -+ char *shell_basename; -+ -+ shell_basename = last_component (shell); -+ arg0 = xmalloc (strlen (shell_basename) + 2); -+ arg0[0] = '-'; -+ strcpy (arg0 + 1, shell_basename); -+ args[0] = arg0; -+ } -+ else -+ args[0] = last_component (shell); -+ if (fast_startup) -+ args[argno++] = "-f"; -+ if (command) -+ { -+ args[argno++] = "-c"; -+ args[argno++] = command; -+ } -+ memcpy (args + argno, additional_args, n_additional_args * sizeof *args); -+ args[argno + n_additional_args] = NULL; -+ execv (shell, (char **) args); -+ -+ { -+ int exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); -+ error (0, errno, "%s", shell); -+ exit (exit_status); -+ } -+} -+ -+/* Return true if SHELL is a restricted shell (one not returned by -+ getusershell), else false, meaning it is a standard shell. */ -+ -+static bool -+restricted_shell (const char *shell) -+{ -+ char *line; -+ -+ setusershell (); -+ while ((line = getusershell ()) != NULL) -+ { -+ if (*line != '#' && STREQ (line, shell)) -+ { -+ endusershell (); -+ return false; -+ } -+ } -+ endusershell (); -+ return true; -+} -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name); -+ fputs (_("\ -+Change the effective user id and group id to that of USER.\n\ -+\n\ -+ -, -l, --login make the shell a login shell\n\ -+ -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\ -+ -f, --fast pass -f to the shell (for csh or tcsh)\n\ -+ -m, --preserve-environment do not reset environment variables\n\ -+ -p same as -m\n\ -+ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ fputs (_("\ -+\n\ -+A mere - implies -l. If USER not given, assume root.\n\ -+"), stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int optc; -+ const char *new_user = DEFAULT_USER; -+ char *command = NULL; -+ char *shell = NULL; -+ struct passwd *pw; -+ struct passwd pw_copy; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ initialize_exit_failure (EXIT_FAILURE); -+ atexit (close_stdout); -+ -+ fast_startup = false; -+ simulate_login = false; -+ change_environment = true; -+ -+ while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1) -+ { -+ switch (optc) -+ { -+ case 'c': -+ command = optarg; -+ break; -+ -+ case 'f': -+ fast_startup = true; -+ break; -+ -+ case 'l': -+ simulate_login = true; -+ break; -+ -+ case 'm': -+ case 'p': -+ change_environment = false; -+ break; -+ -+ case 's': -+ shell = optarg; -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (optind < argc && STREQ (argv[optind], "-")) -+ { -+ simulate_login = true; -+ ++optind; -+ } -+ if (optind < argc) -+ new_user = argv[optind++]; -+ -+ pw = getpwnam (new_user); -+ if (! (pw && pw->pw_name && pw->pw_name[0] && pw->pw_dir && pw->pw_dir[0] -+ && pw->pw_passwd)) -+ error (EXIT_FAILURE, 0, _("user %s does not exist"), new_user); -+ -+ /* Make a copy of the password information and point pw at the local -+ copy instead. Otherwise, some systems (e.g. GNU/Linux) would clobber -+ the static data through the getlogin call from log_su. -+ Also, make sure pw->pw_shell is a nonempty string. -+ It may be NULL when NEW_USER is a username that is retrieved via NIS (YP), -+ but that doesn't have a default shell listed. */ -+ pw_copy = *pw; -+ pw = &pw_copy; -+ pw->pw_name = xstrdup (pw->pw_name); -+ pw->pw_passwd = xstrdup (pw->pw_passwd); -+ pw->pw_dir = xstrdup (pw->pw_dir); -+ pw->pw_shell = xstrdup (pw->pw_shell && pw->pw_shell[0] -+ ? pw->pw_shell -+ : DEFAULT_SHELL); -+ endpwent (); -+ -+ if (!correct_password (pw)) -+ { -+#ifdef SYSLOG_FAILURE -+ log_su (pw, false); -+#endif -+ error (EXIT_FAILURE, 0, _("incorrect password")); -+ } -+#ifdef SYSLOG_SUCCESS -+ else -+ { -+ log_su (pw, true); -+ } -+#endif -+ -+ if (!shell && !change_environment) -+ shell = getenv ("SHELL"); -+ if (shell && getuid () != 0 && restricted_shell (pw->pw_shell)) -+ { -+ /* The user being su'd to has a nonstandard shell, and so is -+ probably a uucp account or has restricted access. Don't -+ compromise the account by allowing access with a standard -+ shell. */ -+ error (0, 0, _("using restricted shell %s"), pw->pw_shell); -+ shell = NULL; -+ } -+ shell = xstrdup (shell ? shell : pw->pw_shell); -+ modify_environment (pw, shell); -+ -+ change_identity (pw); -+ if (simulate_login && chdir (pw->pw_dir) != 0) -+ error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); -+ -+ run_shell (shell, command, argv + optind, MAX (0, argc - optind)); -+} + diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 12995d2..a2dc61d 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -14,23 +14,6 @@ diff -urNp coreutils-8.0-orig/configure.ac coreutils-8.0/configure.ac + AC_FUNC_FORK - optional_bin_progs= -diff -urNp coreutils-8.0-orig/configure.ac.orig coreutils-8.0/configure.ac.orig ---- coreutils-8.0-orig/configure.ac.orig 2009-10-07 10:09:43.000000000 +0200 -+++ coreutils-8.0/configure.ac.orig 2009-10-07 10:09:43.000000000 +0200 -@@ -115,6 +115,13 @@ if test "$gl_gcc_warnings" = yes; then - AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) - fi - -+dnl Give the chance to enable PAM -+AC_ARG_ENABLE(pam, dnl -+[ --enable-pam Enable use of the PAM libraries], -+[AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) -+LIB_PAM="-ldl -lpam -lpam_misc" -+AC_SUBST(LIB_PAM)]) -+ - AC_FUNC_FORK - optional_bin_progs= diff -urNp coreutils-8.0-orig/man/chcon.x coreutils-8.0/man/chcon.x --- coreutils-8.0-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 @@ -63,2379 +46,6 @@ diff -urNp coreutils-8.0-orig/src/copy.c coreutils-8.0/src/copy.c } else { -diff -urNp coreutils-8.0-orig/src/copy.c.orig coreutils-8.0/src/copy.c.orig ---- coreutils-8.0-orig/src/copy.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/copy.c.orig 2009-09-29 15:27:54.000000000 +0200 -@@ -0,0 +1,2369 @@ -+/* copy.c -- core functions for copying files and directories -+ Copyright (C) 89, 90, 91, 1995-2009 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 . */ -+ -+/* Extracted from cp.c and librarified by Jim Meyering. */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#if HAVE_HURD_H -+# include -+#endif -+#if HAVE_PRIV_H -+# include -+#endif -+ -+#include "system.h" -+#include "acl.h" -+#include "backupfile.h" -+#include "buffer-lcm.h" -+#include "copy.h" -+#include "cp-hash.h" -+#include "error.h" -+#include "fcntl--.h" -+#include "file-set.h" -+#include "filemode.h" -+#include "filenamecat.h" -+#include "full-write.h" -+#include "hash.h" -+#include "hash-triple.h" -+#include "ignore-value.h" -+#include "quote.h" -+#include "same.h" -+#include "savedir.h" -+#include "stat-time.h" -+#include "utimecmp.h" -+#include "utimens.h" -+#include "write-any-file.h" -+#include "areadlink.h" -+#include "yesno.h" -+ -+#if USE_XATTR -+# include -+# include -+# include -+# include "verror.h" -+#endif -+ -+#if HAVE_SYS_IOCTL_H -+# include -+#endif -+ -+#ifndef HAVE_FCHOWN -+# define HAVE_FCHOWN false -+# define fchown(fd, uid, gid) (-1) -+#endif -+ -+#ifndef HAVE_LCHOWN -+# define HAVE_LCHOWN false -+# define lchown(name, uid, gid) chown (name, uid, gid) -+#endif -+ -+#ifndef HAVE_MKFIFO -+static int -+rpl_mkfifo (char const *file, mode_t mode) -+{ -+ errno = ENOTSUP; -+ return -1; -+} -+# define mkfifo rpl_mkfifo -+#endif -+ -+#ifndef USE_ACL -+# define USE_ACL 0 -+#endif -+ -+#define SAME_OWNER(A, B) ((A).st_uid == (B).st_uid) -+#define SAME_GROUP(A, B) ((A).st_gid == (B).st_gid) -+#define SAME_OWNER_AND_GROUP(A, B) (SAME_OWNER (A, B) && SAME_GROUP (A, B)) -+ -+struct dir_list -+{ -+ struct dir_list *parent; -+ ino_t ino; -+ dev_t dev; -+}; -+ -+/* Initial size of the cp.dest_info hash table. */ -+#define DEST_INFO_INITIAL_CAPACITY 61 -+ -+static bool copy_internal (char const *src_name, char const *dst_name, -+ bool new_dst, dev_t device, -+ struct dir_list *ancestors, -+ const struct cp_options *x, -+ bool command_line_arg, -+ bool *first_dir_created_per_command_line_arg, -+ bool *copy_into_self, -+ bool *rename_succeeded); -+static bool owner_failure_ok (struct cp_options const *x); -+ -+/* Pointers to the file names: they're used in the diagnostic that is issued -+ when we detect the user is trying to copy a directory into itself. */ -+static char const *top_level_src_name; -+static char const *top_level_dst_name; -+ -+/* Set the timestamp of symlink, FILE, to TIMESPEC. -+ If this system lacks support for that, simply return 0. */ -+static inline int -+utimens_symlink (char const *file, struct timespec const *timespec) -+{ -+ int err = 0; -+ -+#if HAVE_UTIMENSAT -+ err = utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW); -+ /* When configuring on a system with new headers and libraries, and -+ running on one with a kernel that is old enough to lack the syscall, -+ utimensat fails with ENOSYS. Ignore that. */ -+ if (err && errno == ENOSYS) -+ err = 0; -+#else -+ (void) file; -+ (void) timespec; -+#endif -+ -+ return err; -+} -+ -+/* Perform the O(1) btrfs clone operation, if possible. -+ Upon success, return 0. Otherwise, return -1 and set errno. */ -+static inline int -+clone_file (int dest_fd, int src_fd) -+{ -+#ifdef __linux__ -+# undef BTRFS_IOCTL_MAGIC -+# define BTRFS_IOCTL_MAGIC 0x94 -+# undef BTRFS_IOC_CLONE -+# define BTRFS_IOC_CLONE _IOW (BTRFS_IOCTL_MAGIC, 9, int) -+ return ioctl (dest_fd, BTRFS_IOC_CLONE, src_fd); -+#else -+ (void) dest_fd; -+ (void) src_fd; -+ errno = ENOTSUP; -+ return -1; -+#endif -+} -+ -+/* FIXME: describe */ -+/* FIXME: rewrite this to use a hash table so we avoid the quadratic -+ performance hit that's probably noticeable only on trees deeper -+ than a few hundred levels. See use of active_dir_map in remove.c */ -+ -+static bool -+is_ancestor (const struct stat *sb, const struct dir_list *ancestors) -+{ -+ while (ancestors != 0) -+ { -+ if (ancestors->ino == sb->st_ino && ancestors->dev == sb->st_dev) -+ return true; -+ ancestors = ancestors->parent; -+ } -+ return false; -+} -+ -+static bool -+errno_unsupported (int err) -+{ -+ return err == ENOTSUP || err == ENODATA; -+} -+ -+#if USE_XATTR -+static void -+copy_attr_error (struct error_context *ctx ATTRIBUTE_UNUSED, -+ char const *fmt, ...) -+{ -+ int err = errno; -+ va_list ap; -+ -+ if (!errno_unsupported (errno)) -+ { -+ /* use verror module to print error message */ -+ va_start (ap, fmt); -+ verror (0, err, fmt, ap); -+ va_end (ap); -+ } -+} -+ -+static void -+copy_attr_allerror (struct error_context *ctx ATTRIBUTE_UNUSED, -+ char const *fmt, ...) -+{ -+ int err = errno; -+ va_list ap; -+ -+ /* use verror module to print error message */ -+ va_start (ap, fmt); -+ verror (0, err, fmt, ap); -+ va_end (ap); -+} -+ -+static char const * -+copy_attr_quote (struct error_context *ctx ATTRIBUTE_UNUSED, char const *str) -+{ -+ return quote (str); -+} -+ -+static void -+copy_attr_free (struct error_context *ctx ATTRIBUTE_UNUSED, -+ char const *str ATTRIBUTE_UNUSED) -+{ -+} -+ -+static bool -+copy_attr_by_fd (char const *src_path, int src_fd, -+ char const *dst_path, int dst_fd, const struct cp_options *x) -+{ -+ struct error_context ctx = -+ { -+ .error = x->require_preserve_xattr ? copy_attr_allerror : copy_attr_error, -+ .quote = copy_attr_quote, -+ .quote_free = copy_attr_free -+ }; -+ return 0 == attr_copy_fd (src_path, src_fd, dst_path, dst_fd, 0, -+ (x->reduce_diagnostics -+ && !x->require_preserve_xattr)? NULL : &ctx); -+} -+ -+static bool -+copy_attr_by_name (char const *src_path, char const *dst_path, -+ const struct cp_options *x) -+{ -+ struct error_context ctx = -+ { -+ .error = x->require_preserve_xattr ? copy_attr_allerror : copy_attr_error, -+ .quote = copy_attr_quote, -+ .quote_free = copy_attr_free -+ }; -+ return 0 == attr_copy_file (src_path, dst_path, 0, -+ (x-> reduce_diagnostics -+ && !x->require_preserve_xattr) ? NULL : &ctx); -+} -+#else /* USE_XATTR */ -+ -+static bool -+copy_attr_by_fd (char const *src_path ATTRIBUTE_UNUSED, -+ int src_fd ATTRIBUTE_UNUSED, -+ char const *dst_path ATTRIBUTE_UNUSED, -+ int dst_fd ATTRIBUTE_UNUSED, -+ const struct cp_options *x ATTRIBUTE_UNUSED) -+{ -+ return true; -+} -+ -+static bool -+copy_attr_by_name (char const *src_path ATTRIBUTE_UNUSED, -+ char const *dst_path ATTRIBUTE_UNUSED, -+ const struct cp_options *x ATTRIBUTE_UNUSED) -+{ -+ return true; -+} -+#endif /* USE_XATTR */ -+ -+/* Read the contents of the directory SRC_NAME_IN, and recursively -+ copy the contents to DST_NAME_IN. NEW_DST is true if -+ DST_NAME_IN is a directory that was created previously in the -+ recursion. SRC_SB and ANCESTORS describe SRC_NAME_IN. -+ Set *COPY_INTO_SELF if SRC_NAME_IN is a parent of -+ FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG FIXME -+ (or the same as) DST_NAME_IN; otherwise, clear it. -+ Return true if successful. */ -+ -+static bool -+copy_dir (char const *src_name_in, char const *dst_name_in, bool new_dst, -+ const struct stat *src_sb, struct dir_list *ancestors, -+ const struct cp_options *x, -+ bool *first_dir_created_per_command_line_arg, -+ bool *copy_into_self) -+{ -+ char *name_space; -+ char *namep; -+ struct cp_options non_command_line_options = *x; -+ bool ok = true; -+ -+ name_space = savedir (src_name_in); -+ if (name_space == NULL) -+ { -+ /* This diagnostic is a bit vague because savedir can fail in -+ several different ways. */ -+ error (0, errno, _("cannot access %s"), quote (src_name_in)); -+ return false; -+ } -+ -+ /* For cp's -H option, dereference command line arguments, but do not -+ dereference symlinks that are found via recursive traversal. */ -+ if (x->dereference == DEREF_COMMAND_LINE_ARGUMENTS) -+ non_command_line_options.dereference = DEREF_NEVER; -+ -+ namep = name_space; -+ while (*namep != '\0') -+ { -+ bool local_copy_into_self; -+ char *src_name = file_name_concat (src_name_in, namep, NULL); -+ char *dst_name = file_name_concat (dst_name_in, namep, NULL); -+ -+ ok &= copy_internal (src_name, dst_name, new_dst, src_sb->st_dev, -+ ancestors, &non_command_line_options, false, -+ first_dir_created_per_command_line_arg, -+ &local_copy_into_self, NULL); -+ *copy_into_self |= local_copy_into_self; -+ -+ free (dst_name); -+ free (src_name); -+ -+ /* If we're copying into self, there's no point in continuing, -+ and in fact, that would even infloop, now that we record only -+ the first created directory per command line argument. */ -+ if (local_copy_into_self) -+ break; -+ -+ namep += strlen (namep) + 1; -+ } -+ free (name_space); -+ return ok; -+} -+ -+/* Set the owner and owning group of DEST_DESC to the st_uid and -+ st_gid fields of SRC_SB. If DEST_DESC is undefined (-1), set -+ the owner and owning group of DST_NAME instead; for -+ safety prefer lchown if the system supports it since no -+ symbolic links should be involved. DEST_DESC must -+ refer to the same file as DEST_NAME if defined. -+ Upon failure to set both UID and GID, try to set only the GID. -+ NEW_DST is true if the file was newly created; otherwise, -+ DST_SB is the status of the destination. -+ Return 1 if the initial syscall succeeds, 0 if it fails but it's OK -+ not to preserve ownership, -1 otherwise. */ -+ -+static int -+set_owner (const struct cp_options *x, char const *dst_name, int dest_desc, -+ struct stat const *src_sb, bool new_dst, -+ struct stat const *dst_sb) -+{ -+ uid_t uid = src_sb->st_uid; -+ gid_t gid = src_sb->st_gid; -+ -+ /* Naively changing the ownership of an already-existing file before -+ changing its permissions would create a window of vulnerability if -+ the file's old permissions are too generous for the new owner and -+ group. Avoid the window by first changing to a restrictive -+ temporary mode if necessary. */ -+ -+ if (!new_dst && (x->preserve_mode || x->move_mode || x->set_mode)) -+ { -+ mode_t old_mode = dst_sb->st_mode; -+ mode_t new_mode = -+ (x->preserve_mode || x->move_mode ? src_sb->st_mode : x->mode); -+ mode_t restrictive_temp_mode = old_mode & new_mode & S_IRWXU; -+ -+ if ((USE_ACL -+ || (old_mode & CHMOD_MODE_BITS -+ & (~new_mode | S_ISUID | S_ISGID | S_ISVTX))) -+ && qset_acl (dst_name, dest_desc, restrictive_temp_mode) != 0) -+ { -+ if (! owner_failure_ok (x)) -+ error (0, errno, _("clearing permissions for %s"), quote (dst_name)); -+ return -x->require_preserve; -+ } -+ } -+ -+ if (HAVE_FCHOWN && dest_desc != -1) -+ { -+ if (fchown (dest_desc, uid, gid) == 0) -+ return 1; -+ if (errno == EPERM || errno == EINVAL) -+ { -+ /* We've failed to set *both*. Now, try to set just the group -+ ID, but ignore any failure here, and don't change errno. */ -+ int saved_errno = errno; -+ ignore_value (fchown (dest_desc, -1, gid)); -+ errno = saved_errno; -+ } -+ } -+ else -+ { -+ if (lchown (dst_name, uid, gid) == 0) -+ return 1; -+ if (errno == EPERM || errno == EINVAL) -+ { -+ /* We've failed to set *both*. Now, try to set just the group -+ ID, but ignore any failure here, and don't change errno. */ -+ int saved_errno = errno; -+ ignore_value (lchown (dst_name, -1, gid)); -+ errno = saved_errno; -+ } -+ } -+ -+ if (! chown_failure_ok (x)) -+ { -+ error (0, errno, _("failed to preserve ownership for %s"), -+ quote (dst_name)); -+ if (x->require_preserve) -+ return -1; -+ } -+ -+ return 0; -+} -+ -+/* Set the st_author field of DEST_DESC to the st_author field of -+ SRC_SB. If DEST_DESC is undefined (-1), set the st_author field -+ of DST_NAME instead. DEST_DESC must refer to the same file as -+ DEST_NAME if defined. */ -+ -+static void -+set_author (const char *dst_name, int dest_desc, const struct stat *src_sb) -+{ -+#if HAVE_STRUCT_STAT_ST_AUTHOR -+ /* FIXME: Modify the following code so that it does not -+ follow symbolic links. */ -+ -+ /* Preserve the st_author field. */ -+ file_t file = (dest_desc < 0 -+ ? file_name_lookup (dst_name, 0, 0) -+ : getdport (dest_desc)); -+ if (file == MACH_PORT_NULL) -+ error (0, errno, _("failed to lookup file %s"), quote (dst_name)); -+ else -+ { -+ error_t err = file_chauthor (file, src_sb->st_author); -+ if (err) -+ error (0, err, _("failed to preserve authorship for %s"), -+ quote (dst_name)); -+ mach_port_deallocate (mach_task_self (), file); -+ } -+#else -+ (void) dst_name; -+ (void) dest_desc; -+ (void) src_sb; -+#endif -+} -+ -+/* Change the file mode bits of the file identified by DESC or NAME to MODE. -+ Use DESC if DESC is valid and fchmod is available, NAME otherwise. */ -+ -+static int -+fchmod_or_lchmod (int desc, char const *name, mode_t mode) -+{ -+#if HAVE_FCHMOD -+ if (0 <= desc) -+ return fchmod (desc, mode); -+#endif -+ return lchmod (name, mode); -+} -+ -+/* Copy a regular file from SRC_NAME to DST_NAME. -+ If the source file contains holes, copies holes and blocks of zeros -+ in the source file as holes in the destination file. -+ (Holes are read as zeroes by the `read' system call.) -+ When creating the destination, use DST_MODE & ~OMITTED_PERMISSIONS -+ as the third argument in the call to open, adding -+ OMITTED_PERMISSIONS after copying as needed. -+ X provides many option settings. -+ Return true if successful. -+ *NEW_DST is as in copy_internal. -+ SRC_SB is the result of calling XSTAT (aka stat) on SRC_NAME. */ -+ -+static bool -+copy_reg (char const *src_name, char const *dst_name, -+ const struct cp_options *x, -+ mode_t dst_mode, mode_t omitted_permissions, bool *new_dst, -+ struct stat const *src_sb) -+{ -+ char *buf; -+ char *buf_alloc = NULL; -+ char *name_alloc = NULL; -+ int dest_desc; -+ int dest_errno; -+ int source_desc; -+ mode_t src_mode = src_sb->st_mode; -+ struct stat sb; -+ struct stat src_open_sb; -+ bool return_val = true; -+ bool data_copy_required = true; -+ -+ source_desc = open (src_name, -+ (O_RDONLY | O_BINARY -+ | (x->dereference == DEREF_NEVER ? O_NOFOLLOW : 0))); -+ if (source_desc < 0) -+ { -+ error (0, errno, _("cannot open %s for reading"), quote (src_name)); -+ return false; -+ } -+ -+ if (fstat (source_desc, &src_open_sb) != 0) -+ { -+ error (0, errno, _("cannot fstat %s"), quote (src_name)); -+ return_val = false; -+ goto close_src_desc; -+ } -+ -+ /* Compare the source dev/ino from the open file to the incoming, -+ saved ones obtained via a previous call to stat. */ -+ if (! SAME_INODE (*src_sb, src_open_sb)) -+ { -+ error (0, 0, -+ _("skipping file %s, as it was replaced while being copied"), -+ quote (src_name)); -+ return_val = false; -+ goto close_src_desc; -+ } -+ -+ /* The semantics of the following open calls are mandated -+ by the specs for both cp and mv. */ -+ if (! *new_dst) -+ { -+ dest_desc = open (dst_name, O_WRONLY | O_TRUNC | O_BINARY); -+ dest_errno = errno; -+ -+ /* When using cp --preserve=context to copy to an existing destination, -+ use the default context rather than that of the source. Why? -+ 1) the src context may prohibit writing, and -+ 2) because it's more consistent to use the same context -+ that is used when the destination file doesn't already exist. */ -+ if (x->preserve_security_context && 0 <= dest_desc) -+ { -+ security_context_t con = NULL; -+ if (getfscreatecon (&con) < 0) -+ { -+ if (!x->reduce_diagnostics || x->require_preserve_context) -+ error (0, errno, _("failed to get file system create context")); -+ if (x->require_preserve_context) -+ { -+ return_val = false; -+ goto close_src_and_dst_desc; -+ } -+ } -+ -+ if (con) -+ { -+ if (fsetfilecon (dest_desc, con) < 0) -+ { -+ if (!x->reduce_diagnostics || x->require_preserve_context) -+ error (0, errno, -+ _("failed to set the security context of %s to %s"), -+ quote_n (0, dst_name), quote_n (1, con)); -+ if (x->require_preserve_context) -+ { -+ return_val = false; -+ freecon (con); -+ goto close_src_and_dst_desc; -+ } -+ } -+ freecon (con); -+ } -+ } -+ -+ if (dest_desc < 0 && x->unlink_dest_after_failed_open) -+ { -+ if (unlink (dst_name) != 0) -+ { -+ error (0, errno, _("cannot remove %s"), quote (dst_name)); -+ return_val = false; -+ goto close_src_desc; -+ } -+ if (x->verbose) -+ printf (_("removed %s\n"), quote (dst_name)); -+ -+ /* Tell caller that the destination file was unlinked. */ -+ *new_dst = true; -+ } -+ } -+ -+ if (*new_dst) -+ { -+ int open_flags = O_WRONLY | O_CREAT | O_BINARY; -+ dest_desc = open (dst_name, open_flags | O_EXCL, -+ dst_mode & ~omitted_permissions); -+ dest_errno = errno; -+ -+ /* When trying to copy through a dangling destination symlink, -+ the above open fails with EEXIST. If that happens, and -+ lstat'ing the DST_NAME shows that it is a symlink, then we -+ have a problem: trying to resolve this dangling symlink to -+ a directory/destination-entry pair is fundamentally racy, -+ so punt. If POSIXLY_CORRECT is set, simply call open again, -+ but without O_EXCL (potentially dangerous). If not, fail -+ with a diagnostic. These shenanigans are necessary only -+ when copying, i.e., not in move_mode. */ -+ if (dest_desc < 0 && dest_errno == EEXIST && ! x->move_mode) -+ { -+ struct stat dangling_link_sb; -+ if (lstat (dst_name, &dangling_link_sb) == 0 -+ && S_ISLNK (dangling_link_sb.st_mode)) -+ { -+ if (x->open_dangling_dest_symlink) -+ { -+ dest_desc = open (dst_name, open_flags, -+ dst_mode & ~omitted_permissions); -+ dest_errno = errno; -+ } -+ else -+ { -+ error (0, 0, _("not writing through dangling symlink %s"), -+ quote (dst_name)); -+ return_val = false; -+ goto close_src_desc; -+ } -+ } -+ } -+ } -+ else -+ omitted_permissions = 0; -+ -+ if (dest_desc < 0) -+ { -+ error (0, dest_errno, _("cannot create regular file %s"), -+ quote (dst_name)); -+ return_val = false; -+ goto close_src_desc; -+ } -+ -+ if (fstat (dest_desc, &sb) != 0) -+ { -+ error (0, errno, _("cannot fstat %s"), quote (dst_name)); -+ return_val = false; -+ goto close_src_and_dst_desc; -+ } -+ -+ if (x->reflink_mode) -+ { -+ bool clone_ok = clone_file (dest_desc, source_desc) == 0; -+ if (clone_ok || x->reflink_mode == REFLINK_ALWAYS) -+ { -+ if (!clone_ok) -+ { -+ error (0, errno, _("failed to clone %s"), quote (dst_name)); -+ return_val = false; -+ goto close_src_and_dst_desc; -+ } -+ data_copy_required = false; -+ } -+ } -+ -+ if (data_copy_required) -+ { -+ typedef uintptr_t word; -+ off_t n_read_total = 0; -+ -+ /* Choose a suitable buffer size; it may be adjusted later. */ -+ size_t buf_alignment = lcm (getpagesize (), sizeof (word)); -+ size_t buf_alignment_slop = sizeof (word) + buf_alignment - 1; -+ size_t buf_size = io_blksize (sb); -+ -+ /* Deal with sparse files. */ -+ bool last_write_made_hole = false; -+ bool make_holes = false; -+ -+ if (S_ISREG (sb.st_mode)) -+ { -+ /* Even with --sparse=always, try to create holes only -+ if the destination is a regular file. */ -+ if (x->sparse_mode == SPARSE_ALWAYS) -+ make_holes = true; -+ -+#if HAVE_STRUCT_STAT_ST_BLOCKS -+ /* Use a heuristic to determine whether SRC_NAME contains any sparse -+ blocks. If the file has fewer blocks than would normally be -+ needed for a file of its size, then at least one of the blocks in -+ the file is a hole. */ -+ if (x->sparse_mode == SPARSE_AUTO && S_ISREG (src_open_sb.st_mode) -+ && ST_NBLOCKS (src_open_sb) < src_open_sb.st_size / ST_NBLOCKSIZE) -+ make_holes = true; -+#endif -+ } -+ -+ /* If not making a sparse file, try to use a more-efficient -+ buffer size. */ -+ if (! make_holes) -+ { -+ /* Compute the least common multiple of the input and output -+ buffer sizes, adjusting for outlandish values. */ -+ size_t blcm_max = MIN (SIZE_MAX, SSIZE_MAX) - buf_alignment_slop; -+ size_t blcm = buffer_lcm (io_blksize (src_open_sb), buf_size, -+ blcm_max); -+ -+ /* Do not bother with a buffer larger than the input file, plus one -+ byte to make sure the file has not grown while reading it. */ -+ if (S_ISREG (src_open_sb.st_mode) && src_open_sb.st_size < buf_size) -+ buf_size = src_open_sb.st_size + 1; -+ -+ /* However, stick with a block size that is a positive multiple of -+ blcm, overriding the above adjustments. Watch out for -+ overflow. */ -+ buf_size += blcm - 1; -+ buf_size -= buf_size % blcm; -+ if (buf_size == 0 || blcm_max < buf_size) -+ buf_size = blcm; -+ } -+ -+ /* Make a buffer with space for a sentinel at the end. */ -+ buf_alloc = xmalloc (buf_size + buf_alignment_slop); -+ buf = ptr_align (buf_alloc, buf_alignment); -+ -+ for (;;) -+ { -+ word *wp = NULL; -+ -+ ssize_t n_read = read (source_desc, buf, buf_size); -+ if (n_read < 0) -+ { -+#ifdef EINTR -+ if (errno == EINTR) -+ continue; -+#endif -+ error (0, errno, _("reading %s"), quote (src_name)); -+ return_val = false; -+ goto close_src_and_dst_desc; -+ } -+ if (n_read == 0) -+ break; -+ -+ n_read_total += n_read; -+ -+ if (make_holes) -+ { -+ char *cp; -+ -+ /* Sentinel to stop loop. */ -+ buf[n_read] = '\1'; -+#ifdef lint -+ /* Usually, buf[n_read] is not the byte just before a "word" -+ (aka uintptr_t) boundary. In that case, the word-oriented -+ test below (*wp++ == 0) would read some uninitialized bytes -+ after the sentinel. To avoid false-positive reports about -+ this condition (e.g., from a tool like valgrind), set the -+ remaining bytes -- to any value. */ -+ memset (buf + n_read + 1, 0, sizeof (word) - 1); -+#endif -+ -+ /* Find first nonzero *word*, or the word with the sentinel. */ -+ -+ wp = (word *) buf; -+ while (*wp++ == 0) -+ continue; -+ -+ /* Find the first nonzero *byte*, or the sentinel. */ -+ -+ cp = (char *) (wp - 1); -+ while (*cp++ == 0) -+ continue; -+ -+ if (cp <= buf + n_read) -+ /* Clear to indicate that a normal write is needed. */ -+ wp = NULL; -+ else -+ { -+ /* We found the sentinel, so the whole input block was zero. -+ Make a hole. */ -+ if (lseek (dest_desc, n_read, SEEK_CUR) < 0) -+ { -+ error (0, errno, _("cannot lseek %s"), quote (dst_name)); -+ return_val = false; -+ goto close_src_and_dst_desc; -+ } -+ last_write_made_hole = true; -+ } -+ } -+ -+ if (!wp) -+ { -+ size_t n = n_read; -+ if (full_write (dest_desc, buf, n) != n) -+ { -+ error (0, errno, _("writing %s"), quote (dst_name)); -+ return_val = false; -+ goto close_src_and_dst_desc; -+ } -+ last_write_made_hole = false; -+ -+ /* It is tempting to return early here upon a short read from a -+ regular file. That would save the final read syscall for each -+ file. Unfortunately that doesn't work for certain files in -+ /proc with linux kernels from at least 2.6.9 .. 2.6.29. */ -+ } -+ } -+ -+ /* If the file ends with a `hole', we need to do something to record -+ the length of the file. On modern systems, calling ftruncate does -+ the job. On systems without native ftruncate support, we have to -+ write a byte at the ending position. Otherwise the kernel would -+ truncate the file at the end of the last write operation. */ -+ -+ if (last_write_made_hole) -+ { -+ if (HAVE_FTRUNCATE -+ ? /* ftruncate sets the file size, -+ so there is no need for a write. */ -+ ftruncate (dest_desc, n_read_total) < 0 -+ : /* Seek backwards one character and write a null. */ -+ (lseek (dest_desc, (off_t) -1, SEEK_CUR) < 0L -+ || full_write (dest_desc, "", 1) != 1)) -+ { -+ error (0, errno, _("writing %s"), quote (dst_name)); -+ return_val = false; -+ goto close_src_and_dst_desc; -+ } -+ } -+ } -+ -+ if (x->preserve_timestamps) -+ { -+ struct timespec timespec[2]; -+ timespec[0] = get_stat_atime (src_sb); -+ timespec[1] = get_stat_mtime (src_sb); -+ -+ if (gl_futimens (dest_desc, dst_name, timespec) != 0) -+ { -+ error (0, errno, _("preserving times for %s"), quote (dst_name)); -+ if (x->require_preserve) -+ { -+ return_val = false; -+ goto close_src_and_dst_desc; -+ } -+ } -+ } -+ -+ /* To allow copying xattrs on read-only files, temporarily chmod u+rw. -+ This workaround is required as an inode permission check is done -+ by xattr_permission() in fs/xattr.c of the GNU/Linux kernel tree. */ -+ if (x->preserve_xattr) -+ { -+ bool access_changed = false; -+ -+ if (!(sb.st_mode & S_IWUSR) && geteuid() != 0) -+ access_changed = fchmod_or_lchmod (dest_desc, dst_name, 0600) == 0; -+ -+ if (!copy_attr_by_fd (src_name, source_desc, dst_name, dest_desc, x) -+ && x->require_preserve_xattr) -+ return_val = false; -+ -+ if (access_changed) -+ fchmod_or_lchmod (dest_desc, dst_name, dst_mode & ~omitted_permissions); -+ } -+ -+ if (x->preserve_ownership && ! SAME_OWNER_AND_GROUP (*src_sb, sb)) -+ { -+ switch (set_owner (x, dst_name, dest_desc, src_sb, *new_dst, &sb)) -+ { -+ case -1: -+ return_val = false; -+ goto close_src_and_dst_desc; -+ -+ case 0: -+ src_mode &= ~ (S_ISUID | S_ISGID | S_ISVTX); -+ break; -+ } -+ } -+ -+ set_author (dst_name, dest_desc, src_sb); -+ -+ if (x->preserve_mode || x->move_mode) -+ { -+ if (copy_acl (src_name, source_desc, dst_name, dest_desc, src_mode) != 0 -+ && x->require_preserve) -+ return_val = false; -+ } -+ else if (x->set_mode) -+ { -+ if (set_acl (dst_name, dest_desc, x->mode) != 0) -+ return_val = false; -+ } -+ else if (omitted_permissions) -+ { -+ omitted_permissions &= ~ cached_umask (); -+ if (omitted_permissions -+ && fchmod_or_lchmod (dest_desc, dst_name, dst_mode) != 0) -+ { -+ error (0, errno, _("preserving permissions for %s"), -+ quote (dst_name)); -+ if (x->require_preserve) -+ return_val = false; -+ } -+ } -+ -+close_src_and_dst_desc: -+ if (close (dest_desc) < 0) -+ { -+ error (0, errno, _("closing %s"), quote (dst_name)); -+ return_val = false; -+ } -+close_src_desc: -+ if (close (source_desc) < 0) -+ { -+ error (0, errno, _("closing %s"), quote (src_name)); -+ return_val = false; -+ } -+ -+ free (buf_alloc); -+ free (name_alloc); -+ return return_val; -+} -+ -+/* Return true if it's ok that the source and destination -+ files are the `same' by some measure. The goal is to avoid -+ making the `copy' operation remove both copies of the file -+ in that case, while still allowing the user to e.g., move or -+ copy a regular file onto a symlink that points to it. -+ Try to minimize the cost of this function in the common case. -+ Set *RETURN_NOW if we've determined that the caller has no more -+ work to do and should return successfully, right away. -+ -+ Set *UNLINK_SRC if we've determined that the caller wants to do -+ `rename (a, b)' where `a' and `b' are distinct hard links to the same -+ file. In that case, the caller should try to unlink `a' and then return -+ successfully. Ideally, we wouldn't have to do that, and we'd be -+ able to rely on rename to remove the source file. However, POSIX -+ mistakenly requires that such a rename call do *nothing* and return -+ successfully. */ -+ -+static bool -+same_file_ok (char const *src_name, struct stat const *src_sb, -+ char const *dst_name, struct stat const *dst_sb, -+ const struct cp_options *x, bool *return_now, bool *unlink_src) -+{ -+ const struct stat *src_sb_link; -+ const struct stat *dst_sb_link; -+ struct stat tmp_dst_sb; -+ struct stat tmp_src_sb; -+ -+ bool same_link; -+ bool same = SAME_INODE (*src_sb, *dst_sb); -+ -+ *return_now = false; -+ *unlink_src = false; -+ -+ /* FIXME: this should (at the very least) be moved into the following -+ if-block. More likely, it should be removed, because it inhibits -+ making backups. But removing it will result in a change in behavior -+ that will probably have to be documented -- and tests will have to -+ be updated. */ -+ if (same && x->hard_link) -+ { -+ *return_now = true; -+ return true; -+ } -+ -+ if (x->dereference == DEREF_NEVER) -+ { -+ same_link = same; -+ -+ /* If both the source and destination files are symlinks (and we'll -+ know this here IFF preserving symlinks), then it's ok -- as long -+ as they are distinct. */ -+ if (S_ISLNK (src_sb->st_mode) && S_ISLNK (dst_sb->st_mode)) -+ return ! same_name (src_name, dst_name); -+ -+ src_sb_link = src_sb; -+ dst_sb_link = dst_sb; -+ } -+ else -+ { -+ if (!same) -+ return true; -+ -+ if (lstat (dst_name, &tmp_dst_sb) != 0 -+ || lstat (src_name, &tmp_src_sb) != 0) -+ return true; -+ -+ src_sb_link = &tmp_src_sb; -+ dst_sb_link = &tmp_dst_sb; -+ -+ same_link = SAME_INODE (*src_sb_link, *dst_sb_link); -+ -+ /* If both are symlinks, then it's ok, but only if the destination -+ will be unlinked before being opened. This is like the test -+ above, but with the addition of the unlink_dest_before_opening -+ conjunct because otherwise, with two symlinks to the same target, -+ we'd end up truncating the source file. */ -+ if (S_ISLNK (src_sb_link->st_mode) && S_ISLNK (dst_sb_link->st_mode) -+ && x->unlink_dest_before_opening) -+ return true; -+ } -+ -+ /* The backup code ensures there's a copy, so it's usually ok to -+ remove any destination file. One exception is when both -+ source and destination are the same directory entry. In that -+ case, moving the destination file aside (in making the backup) -+ would also rename the source file and result in an error. */ -+ if (x->backup_type != no_backups) -+ { -+ if (!same_link) -+ { -+ /* In copy mode when dereferencing symlinks, if the source is a -+ symlink and the dest is not, then backing up the destination -+ (moving it aside) would make it a dangling symlink, and the -+ subsequent attempt to open it in copy_reg would fail with -+ a misleading diagnostic. Avoid that by returning zero in -+ that case so the caller can make cp (or mv when it has to -+ resort to reading the source file) fail now. */ -+ -+ /* FIXME-note: even with the following kludge, we can still provoke -+ the offending diagnostic. It's just a little harder to do :-) -+ $ rm -f a b c; touch c; ln -s c b; ln -s b a; cp -b a b -+ cp: cannot open `a' for reading: No such file or directory -+ That's misleading, since a subsequent `ls' shows that `a' -+ is still there. -+ One solution would be to open the source file *before* moving -+ aside the destination, but that'd involve a big rewrite. */ -+ if ( ! x->move_mode -+ && x->dereference != DEREF_NEVER -+ && S_ISLNK (src_sb_link->st_mode) -+ && ! S_ISLNK (dst_sb_link->st_mode)) -+ return false; -+ -+ return true; -+ } -+ -+ return ! same_name (src_name, dst_name); -+ } -+ -+#if 0 -+ /* FIXME: use or remove */ -+ -+ /* If we're making a backup, we'll detect the problem case in -+ copy_reg because SRC_NAME will no longer exist. Allowing -+ the test to be deferred lets cp do some useful things. -+ But when creating hardlinks and SRC_NAME is a symlink -+ but DST_NAME is not we must test anyway. */ -+ if (x->hard_link -+ || !S_ISLNK (src_sb_link->st_mode) -+ || S_ISLNK (dst_sb_link->st_mode)) -+ return true; -+ -+ if (x->dereference != DEREF_NEVER) -+ return true; -+#endif -+ -+ /* They may refer to the same file if we're in move mode and the -+ target is a symlink. That is ok, since we remove any existing -+ destination file before opening it -- via `rename' if they're on -+ the same file system, via `unlink (DST_NAME)' otherwise. -+ It's also ok if they're distinct hard links to the same file. */ -+ if (x->move_mode || x->unlink_dest_before_opening) -+ { -+ if (S_ISLNK (dst_sb_link->st_mode)) -+ return true; -+ -+ if (same_link -+ && 1 < dst_sb_link->st_nlink -+ && ! same_name (src_name, dst_name)) -+ { -+ if (x->move_mode) -+ { -+ *unlink_src = true; -+ *return_now = true; -+ } -+ return true; -+ } -+ } -+ -+ /* If neither is a symlink, then it's ok as long as they aren't -+ hard links to the same file. */ -+ if (!S_ISLNK (src_sb_link->st_mode) && !S_ISLNK (dst_sb_link->st_mode)) -+ { -+ if (!SAME_INODE (*src_sb_link, *dst_sb_link)) -+ return true; -+ -+ /* If they are the same file, it's ok if we're making hard links. */ -+ if (x->hard_link) -+ { -+ *return_now = true; -+ return true; -+ } -+ } -+ -+ /* It's ok to remove a destination symlink. But that works only when we -+ unlink before opening the destination and when the source and destination -+ files are on the same partition. */ -+ if (x->unlink_dest_before_opening -+ && S_ISLNK (dst_sb_link->st_mode)) -+ return dst_sb_link->st_dev == src_sb_link->st_dev; -+ -+ if (x->dereference == DEREF_NEVER) -+ { -+ if ( ! S_ISLNK (src_sb_link->st_mode)) -+ tmp_src_sb = *src_sb_link; -+ else if (stat (src_name, &tmp_src_sb) != 0) -+ return true; -+ -+ if ( ! S_ISLNK (dst_sb_link->st_mode)) -+ tmp_dst_sb = *dst_sb_link; -+ else if (stat (dst_name, &tmp_dst_sb) != 0) -+ return true; -+ -+ if ( ! SAME_INODE (tmp_src_sb, tmp_dst_sb)) -+ return true; -+ -+ /* FIXME: shouldn't this be testing whether we're making symlinks? */ -+ if (x->hard_link) -+ { -+ *return_now = true; -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+/* Return true if FILE, with mode MODE, is writable in the sense of 'mv'. -+ Always consider a symbolic link to be writable. */ -+static bool -+writable_destination (char const *file, mode_t mode) -+{ -+ return (S_ISLNK (mode) -+ || can_write_any_file () -+ || euidaccess (file, W_OK) == 0); -+} -+ -+static void -+overwrite_prompt (char const *dst_name, struct stat const *dst_sb) -+{ -+ if (! writable_destination (dst_name, dst_sb->st_mode)) -+ { -+ char perms[12]; /* "-rwxrwxrwx " ls-style modes. */ -+ strmode (dst_sb->st_mode, perms); -+ perms[10] = '\0'; -+ fprintf (stderr, -+ _("%s: try to overwrite %s, overriding mode %04lo (%s)? "), -+ program_name, quote (dst_name), -+ (unsigned long int) (dst_sb->st_mode & CHMOD_MODE_BITS), -+ &perms[1]); -+ } -+ else -+ { -+ fprintf (stderr, _("%s: overwrite %s? "), -+ program_name, quote (dst_name)); -+ } -+} -+ -+/* Initialize the hash table implementing a set of F_triple entries -+ corresponding to destination files. */ -+extern void -+dest_info_init (struct cp_options *x) -+{ -+ x->dest_info -+ = hash_initialize (DEST_INFO_INITIAL_CAPACITY, -+ NULL, -+ triple_hash, -+ triple_compare, -+ triple_free); -+} -+ -+/* Initialize the hash table implementing a set of F_triple entries -+ corresponding to source files listed on the command line. */ -+extern void -+src_info_init (struct cp_options *x) -+{ -+ -+ /* Note that we use triple_hash_no_name here. -+ Contrast with the use of triple_hash above. -+ That is necessary because a source file may be specified -+ in many different ways. We want to warn about this -+ cp a a d/ -+ as well as this: -+ cp a ./a d/ -+ */ -+ x->src_info -+ = hash_initialize (DEST_INFO_INITIAL_CAPACITY, -+ NULL, -+ triple_hash_no_name, -+ triple_compare, -+ triple_free); -+} -+ -+/* When effecting a move (e.g., for mv(1)), and given the name DST_NAME -+ of the destination and a corresponding stat buffer, DST_SB, return -+ true if the logical `move' operation should _not_ proceed. -+ Otherwise, return false. -+ Depending on options specified in X, this code may issue an -+ interactive prompt asking whether it's ok to overwrite DST_NAME. */ -+static bool -+abandon_move (const struct cp_options *x, -+ char const *dst_name, -+ struct stat const *dst_sb) -+{ -+ assert (x->move_mode); -+ return (x->interactive == I_ALWAYS_NO -+ || ((x->interactive == I_ASK_USER -+ || (x->interactive == I_UNSPECIFIED -+ && x->stdin_tty -+ && ! writable_destination (dst_name, dst_sb->st_mode))) -+ && (overwrite_prompt (dst_name, dst_sb), 1) -+ && ! yesno ())); -+} -+ -+/* Print --verbose output on standard output, e.g. `new' -> `old'. -+ If BACKUP_DST_NAME is non-NULL, then also indicate that it is -+ the name of a backup file. */ -+static void -+emit_verbose (char const *src, char const *dst, char const *backup_dst_name) -+{ -+ printf ("%s -> %s", quote_n (0, src), quote_n (1, dst)); -+ if (backup_dst_name) -+ printf (_(" (backup: %s)"), quote (backup_dst_name)); -+ putchar ('\n'); -+} -+ -+/* A wrapper around "setfscreatecon (NULL)" that exits upon failure. */ -+static void -+restore_default_fscreatecon_or_die (void) -+{ -+ if (setfscreatecon (NULL) != 0) -+ error (EXIT_FAILURE, errno, -+ _("failed to restore the default file creation context")); -+} -+ -+/* Copy the file SRC_NAME to the file DST_NAME. The files may be of -+ any type. NEW_DST should be true if the file DST_NAME cannot -+ exist because its parent directory was just created; NEW_DST should -+ be false if DST_NAME might already exist. DEVICE is the device -+ number of the parent directory, or 0 if the parent of this file is -+ not known. ANCESTORS points to a linked, null terminated list of -+ devices and inodes of parent directories of SRC_NAME. COMMAND_LINE_ARG -+ is true iff SRC_NAME was specified on the command line. -+ FIRST_DIR_CREATED_PER_COMMAND_LINE_ARG is both input and output. -+ Set *COPY_INTO_SELF if SRC_NAME is a parent of (or the -+ same as) DST_NAME; otherwise, clear it. -+ Return true if successful. */ -+static bool -+copy_internal (char const *src_name, char const *dst_name, -+ bool new_dst, -+ dev_t device, -+ struct dir_list *ancestors, -+ const struct cp_options *x, -+ bool command_line_arg, -+ bool *first_dir_created_per_command_line_arg, -+ bool *copy_into_self, -+ bool *rename_succeeded) -+{ -+ struct stat src_sb; -+ struct stat dst_sb; -+ mode_t src_mode; -+ mode_t dst_mode IF_LINT (= 0); -+ mode_t dst_mode_bits; -+ mode_t omitted_permissions; -+ bool restore_dst_mode = false; -+ char *earlier_file = NULL; -+ char *dst_backup = NULL; -+ bool backup_succeeded = false; -+ bool delayed_ok; -+ bool copied_as_regular = false; -+ bool dest_is_symlink = false; -+ bool have_dst_lstat = false; -+ -+ if (x->move_mode && rename_succeeded) -+ *rename_succeeded = false; -+ -+ *copy_into_self = false; -+ -+ if (XSTAT (x, src_name, &src_sb) != 0) -+ { -+ error (0, errno, _("cannot stat %s"), quote (src_name)); -+ return false; -+ } -+ -+ src_mode = src_sb.st_mode; -+ -+ if (S_ISDIR (src_mode) && !x->recursive) -+ { -+ error (0, 0, _("omitting directory %s"), quote (src_name)); -+ return false; -+ } -+ -+ /* Detect the case in which the same source file appears more than -+ once on the command line and no backup option has been selected. -+ If so, simply warn and don't copy it the second time. -+ This check is enabled only if x->src_info is non-NULL. */ -+ if (command_line_arg) -+ { -+ if ( ! S_ISDIR (src_sb.st_mode) -+ && x->backup_type == no_backups -+ && seen_file (x->src_info, src_name, &src_sb)) -+ { -+ error (0, 0, _("warning: source file %s specified more than once"), -+ quote (src_name)); -+ return true; -+ } -+ -+ record_file (x->src_info, src_name, &src_sb); -+ } -+ -+ if (!new_dst) -+ { -+ /* Regular files can be created by writing through symbolic -+ links, but other files cannot. So use stat on the -+ destination when copying a regular file, and lstat otherwise. -+ However, if we intend to unlink or remove the destination -+ first, use lstat, since a copy won't actually be made to the -+ destination in that case. */ -+ bool use_stat = -+ ((S_ISREG (src_mode) -+ || (x->copy_as_regular -+ && ! (S_ISDIR (src_mode) || S_ISLNK (src_mode)))) -+ && ! (x->move_mode || x->symbolic_link || x->hard_link -+ || x->backup_type != no_backups -+ || x->unlink_dest_before_opening)); -+ if ((use_stat -+ ? stat (dst_name, &dst_sb) -+ : lstat (dst_name, &dst_sb)) -+ != 0) -+ { -+ if (errno != ENOENT) -+ { -+ error (0, errno, _("cannot stat %s"), quote (dst_name)); -+ return false; -+ } -+ else -+ { -+ new_dst = true; -+ } -+ } -+ else -+ { /* Here, we know that dst_name exists, at least to the point -+ that it is stat'able or lstat'able. */ -+ bool return_now; -+ bool unlink_src; -+ -+ have_dst_lstat = !use_stat; -+ if (! same_file_ok (src_name, &src_sb, dst_name, &dst_sb, -+ x, &return_now, &unlink_src)) -+ { -+ error (0, 0, _("%s and %s are the same file"), -+ quote_n (0, src_name), quote_n (1, dst_name)); -+ return false; -+ } -+ -+ if (!S_ISDIR (src_mode) && x->update) -+ { -+ /* When preserving time stamps (but not moving within a file -+ system), don't worry if the destination time stamp is -+ less than the source merely because of time stamp -+ truncation. */ -+ int options = ((x->preserve_timestamps -+ && ! (x->move_mode -+ && dst_sb.st_dev == src_sb.st_dev)) -+ ? UTIMECMP_TRUNCATE_SOURCE -+ : 0); -+ -+ if (0 <= utimecmp (dst_name, &dst_sb, &src_sb, options)) -+ { -+ /* We're using --update and the destination is not older -+ than the source, so do not copy or move. Pretend the -+ rename succeeded, so the caller (if it's mv) doesn't -+ end up removing the source file. */ -+ if (rename_succeeded) -+ *rename_succeeded = true; -+ return true; -+ } -+ } -+ -+ /* When there is an existing destination file, we may end up -+ returning early, and hence not copying/moving the file. -+ This may be due to an interactive `negative' reply to the -+ prompt about the existing file. It may also be due to the -+ use of the --reply=no option. -+ -+ cp and mv treat -i and -f differently. */ -+ if (x->move_mode) -+ { -+ if (abandon_move (x, dst_name, &dst_sb) -+ || (unlink_src && unlink (src_name) == 0)) -+ { -+ /* Pretend the rename succeeded, so the caller (mv) -+ doesn't end up removing the source file. */ -+ if (rename_succeeded) -+ *rename_succeeded = true; -+ if (unlink_src && x->verbose) -+ printf (_("removed %s\n"), quote (src_name)); -+ return true; -+ } -+ if (unlink_src) -+ { -+ error (0, errno, _("cannot remove %s"), quote (src_name)); -+ return false; -+ } -+ } -+ else -+ { -+ if (! S_ISDIR (src_mode) -+ && (x->interactive == I_ALWAYS_NO -+ || (x->interactive == I_ASK_USER -+ && (overwrite_prompt (dst_name, &dst_sb), 1) -+ && ! yesno ()))) -+ return true; -+ } -+ -+ if (return_now) -+ return true; -+ -+ if (!S_ISDIR (dst_sb.st_mode)) -+ { -+ if (S_ISDIR (src_mode)) -+ { -+ if (x->move_mode && x->backup_type != no_backups) -+ { -+ /* Moving a directory onto an existing -+ non-directory is ok only with --backup. */ -+ } -+ else -+ { -+ error (0, 0, -+ _("cannot overwrite non-directory %s with directory %s"), -+ quote_n (0, dst_name), quote_n (1, src_name)); -+ return false; -+ } -+ } -+ -+ /* Don't let the user destroy their data, even if they try hard: -+ This mv command must fail (likewise for cp): -+ rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c -+ Otherwise, the contents of b/f would be lost. -+ In the case of `cp', b/f would be lost if the user simulated -+ a move using cp and rm. -+ Note that it works fine if you use --backup=numbered. */ -+ if (command_line_arg -+ && x->backup_type != numbered_backups -+ && seen_file (x->dest_info, dst_name, &dst_sb)) -+ { -+ error (0, 0, -+ _("will not overwrite just-created %s with %s"), -+ quote_n (0, dst_name), quote_n (1, src_name)); -+ return false; -+ } -+ } -+ -+ if (!S_ISDIR (src_mode)) -+ { -+ if (S_ISDIR (dst_sb.st_mode)) -+ { -+ if (x->move_mode && x->backup_type != no_backups) -+ { -+ /* Moving a non-directory onto an existing -+ directory is ok only with --backup. */ -+ } -+ else -+ { -+ error (0, 0, -+ _("cannot overwrite directory %s with non-directory"), -+ quote (dst_name)); -+ return false; -+ } -+ } -+ } -+ -+ if (x->move_mode) -+ { -+ /* Don't allow user to move a directory onto a non-directory. */ -+ if (S_ISDIR (src_sb.st_mode) && !S_ISDIR (dst_sb.st_mode) -+ && x->backup_type == no_backups) -+ { -+ error (0, 0, -+ _("cannot move directory onto non-directory: %s -> %s"), -+ quote_n (0, src_name), quote_n (0, dst_name)); -+ return false; -+ } -+ } -+ -+ if (x->backup_type != no_backups -+ /* Don't try to back up a destination if the last -+ component of src_name is "." or "..". */ -+ && ! dot_or_dotdot (last_component (src_name)) -+ /* Create a backup of each destination directory in move mode, -+ but not in copy mode. FIXME: it might make sense to add an -+ option to suppress backup creation also for move mode. -+ That would let one use mv to merge new content into an -+ existing hierarchy. */ -+ && (x->move_mode || ! S_ISDIR (dst_sb.st_mode))) -+ { -+ char *tmp_backup = find_backup_file_name (dst_name, -+ x->backup_type); -+ -+ /* Detect (and fail) when creating the backup file would -+ destroy the source file. Before, running the commands -+ cd /tmp; rm -f a a~; : > a; echo A > a~; cp --b=simple a~ a -+ would leave two zero-length files: a and a~. */ -+ /* FIXME: but simply change e.g., the final a~ to `./a~' -+ and the source will still be destroyed. */ -+ if (STREQ (tmp_backup, src_name)) -+ { -+ const char *fmt; -+ fmt = (x->move_mode -+ ? _("backing up %s would destroy source; %s not moved") -+ : _("backing up %s would destroy source; %s not copied")); -+ error (0, 0, fmt, -+ quote_n (0, dst_name), -+ quote_n (1, src_name)); -+ free (tmp_backup); -+ return false; -+ } -+ -+ /* FIXME: use fts: -+ Using alloca for a file name that may be arbitrarily -+ long is not recommended. In fact, even forming such a name -+ should be discouraged. Eventually, this code will be rewritten -+ to use fts, so using alloca here will be less of a problem. */ -+ ASSIGN_STRDUPA (dst_backup, tmp_backup); -+ free (tmp_backup); -+ if (rename (dst_name, dst_backup) != 0) -+ { -+ if (errno != ENOENT) -+ { -+ error (0, errno, _("cannot backup %s"), quote (dst_name)); -+ return false; -+ } -+ else -+ { -+ dst_backup = NULL; -+ } -+ } -+ else -+ { -+ backup_succeeded = true; -+ } -+ new_dst = true; -+ } -+ else if (! S_ISDIR (dst_sb.st_mode) -+ /* Never unlink dst_name when in move mode. */ -+ && ! x->move_mode -+ && (x->unlink_dest_before_opening -+ || (x->preserve_links && 1 < dst_sb.st_nlink) -+ || (x->dereference == DEREF_NEVER -+ && ! S_ISREG (src_sb.st_mode)) -+ )) -+ { -+ if (unlink (dst_name) != 0 && errno != ENOENT) -+ { -+ error (0, errno, _("cannot remove %s"), quote (dst_name)); -+ return false; -+ } -+ new_dst = true; -+ if (x->verbose) -+ printf (_("removed %s\n"), quote (dst_name)); -+ } -+ } -+ } -+ -+ /* Ensure we don't try to copy through a symlink that was -+ created by a prior call to this function. */ -+ if (command_line_arg -+ && x->dest_info -+ && ! x->move_mode -+ && x->backup_type == no_backups) -+ { -+ bool lstat_ok = true; -+ struct stat tmp_buf; -+ struct stat *dst_lstat_sb; -+ -+ /* If we called lstat above, good: use that data. -+ Otherwise, call lstat here, in case dst_name is a symlink. */ -+ if (have_dst_lstat) -+ dst_lstat_sb = &dst_sb; -+ else -+ { -+ if (lstat (dst_name, &tmp_buf) == 0) -+ dst_lstat_sb = &tmp_buf; -+ else -+ lstat_ok = false; -+ } -+ -+ /* Never copy through a symlink we've just created. */ -+ if (lstat_ok -+ && S_ISLNK (dst_lstat_sb->st_mode) -+ && seen_file (x->dest_info, dst_name, dst_lstat_sb)) -+ { -+ error (0, 0, -+ _("will not copy %s through just-created symlink %s"), -+ quote_n (0, src_name), quote_n (1, dst_name)); -+ return false; -+ } -+ } -+ -+ /* If the source is a directory, we don't always create the destination -+ directory. So --verbose should not announce anything until we're -+ sure we'll create a directory. */ -+ if (x->verbose && !S_ISDIR (src_mode)) -+ emit_verbose (src_name, dst_name, backup_succeeded ? dst_backup : NULL); -+ -+ /* Associate the destination file name with the source device and inode -+ so that if we encounter a matching dev/ino pair in the source tree -+ we can arrange to create a hard link between the corresponding names -+ in the destination tree. -+ -+ When using the --link (-l) option, there is no need to take special -+ measures, because (barring race conditions) files that are hard-linked -+ in the source tree will also be hard-linked in the destination tree. -+ -+ Sometimes, when preserving links, we have to record dev/ino even -+ though st_nlink == 1: -+ - when in move_mode, since we may be moving a group of N hard-linked -+ files (via two or more command line arguments) to a different -+ partition; the links may be distributed among the command line -+ arguments (possibly hierarchies) so that the link count of -+ the final, once-linked source file is reduced to 1 when it is -+ considered below. But in this case (for mv) we don't need to -+ incur the expense of recording the dev/ino => name mapping; all we -+ really need is a lookup, to see if the dev/ino pair has already -+ been copied. -+ - when using -H and processing a command line argument; -+ that command line argument could be a symlink pointing to another -+ command line argument. With `cp -H --preserve=link', we hard-link -+ those two destination files. -+ - likewise for -L except that it applies to all files, not just -+ command line arguments. -+ -+ Also, with --recursive, record dev/ino of each command-line directory. -+ We'll use that info to detect this problem: cp -R dir dir. */ -+ -+ if (x->move_mode && src_sb.st_nlink == 1) -+ { -+ earlier_file = src_to_dest_lookup (src_sb.st_ino, src_sb.st_dev); -+ } -+ else if (x->preserve_links -+ && !x->hard_link -+ && (1 < src_sb.st_nlink -+ || (command_line_arg -+ && x->dereference == DEREF_COMMAND_LINE_ARGUMENTS) -+ || x->dereference == DEREF_ALWAYS)) -+ { -+ earlier_file = remember_copied (dst_name, src_sb.st_ino, src_sb.st_dev); -+ } -+ else if (x->recursive && S_ISDIR (src_mode)) -+ { -+ if (command_line_arg) -+ earlier_file = remember_copied (dst_name, src_sb.st_ino, src_sb.st_dev); -+ else -+ earlier_file = src_to_dest_lookup (src_sb.st_ino, src_sb.st_dev); -+ } -+ -+ /* Did we copy this inode somewhere else (in this command line argument) -+ and therefore this is a second hard link to the inode? */ -+ -+ if (earlier_file) -+ { -+ /* Avoid damaging the destination file system by refusing to preserve -+ hard-linked directories (which are found at least in Netapp snapshot -+ directories). */ -+ if (S_ISDIR (src_mode)) -+ { -+ /* If src_name and earlier_file refer to the same directory entry, -+ then warn about copying a directory into itself. */ -+ if (same_name (src_name, earlier_file)) -+ { -+ error (0, 0, _("cannot copy a directory, %s, into itself, %s"), -+ quote_n (0, top_level_src_name), -+ quote_n (1, top_level_dst_name)); -+ *copy_into_self = true; -+ goto un_backup; -+ } -+ else if (x->dereference == DEREF_ALWAYS) -+ { -+ /* This happens when e.g., encountering a directory for the -+ second or subsequent time via symlinks when cp is invoked -+ with -R and -L. E.g., -+ rm -rf a b c d; mkdir a b c d; ln -s ../c a; ln -s ../c b; -+ cp -RL a b d -+ */ -+ } -+ else -+ { -+ error (0, 0, _("will not create hard link %s to directory %s"), -+ quote_n (0, dst_name), quote_n (1, earlier_file)); -+ goto un_backup; -+ } -+ } -+ else -+ { -+ /* We want to guarantee that symlinks are not followed. */ -+ bool link_failed = (linkat (AT_FDCWD, earlier_file, AT_FDCWD, -+ dst_name, 0) != 0); -+ -+ /* If the link failed because of an existing destination, -+ remove that file and then call link again. */ -+ if (link_failed && errno == EEXIST) -+ { -+ if (unlink (dst_name) != 0) -+ { -+ error (0, errno, _("cannot remove %s"), quote (dst_name)); -+ goto un_backup; -+ } -+ if (x->verbose) -+ printf (_("removed %s\n"), quote (dst_name)); -+ link_failed = (linkat (AT_FDCWD, earlier_file, AT_FDCWD, -+ dst_name, 0) != 0); -+ } -+ -+ if (link_failed) -+ { -+ error (0, errno, _("cannot create hard link %s to %s"), -+ quote_n (0, dst_name), quote_n (1, earlier_file)); -+ goto un_backup; -+ } -+ -+ return true; -+ } -+ } -+ -+ if (x->move_mode) -+ { -+ if (rename (src_name, dst_name) == 0) -+ { -+ if (x->verbose && S_ISDIR (src_mode)) -+ emit_verbose (src_name, dst_name, -+ backup_succeeded ? dst_backup : NULL); -+ -+ if (rename_succeeded) -+ *rename_succeeded = true; -+ -+ if (command_line_arg) -+ { -+ /* Record destination dev/ino/name, so that if we are asked -+ to overwrite that file again, we can detect it and fail. */ -+ /* It's fine to use the _source_ stat buffer (src_sb) to get the -+ _destination_ dev/ino, since the rename above can't have -+ changed those, and `mv' always uses lstat. -+ We could limit it further by operating -+ only on non-directories. */ -+ record_file (x->dest_info, dst_name, &src_sb); -+ } -+ -+ return true; -+ } -+ -+ /* FIXME: someday, consider what to do when moving a directory into -+ itself but when source and destination are on different devices. */ -+ -+ /* This happens when attempting to rename a directory to a -+ subdirectory of itself. */ -+ if (errno == EINVAL) -+ { -+ /* FIXME: this is a little fragile in that it relies on rename(2) -+ failing with a specific errno value. Expect problems on -+ non-POSIX systems. */ -+ error (0, 0, _("cannot move %s to a subdirectory of itself, %s"), -+ quote_n (0, top_level_src_name), -+ quote_n (1, top_level_dst_name)); -+ -+ /* Note that there is no need to call forget_created here, -+ (compare with the other calls in this file) since the -+ destination directory didn't exist before. */ -+ -+ *copy_into_self = true; -+ /* FIXME-cleanup: Don't return true here; adjust mv.c accordingly. -+ The only caller that uses this code (mv.c) ends up setting its -+ exit status to nonzero when copy_into_self is nonzero. */ -+ return true; -+ } -+ -+ /* WARNING: there probably exist systems for which an inter-device -+ rename fails with a value of errno not handled here. -+ If/as those are reported, add them to the condition below. -+ If this happens to you, please do the following and send the output -+ to the bug-reporting address (e.g., in the output of cp --help): -+ touch k; perl -e 'rename "k","/tmp/k" or print "$!(",$!+0,")\n"' -+ where your current directory is on one partion and /tmp is the other. -+ Also, please try to find the E* errno macro name corresponding to -+ the diagnostic and parenthesized integer, and include that in your -+ e-mail. One way to do that is to run a command like this -+ find /usr/include/. -type f \ -+ | xargs grep 'define.*\.*\<18\>' /dev/null -+ where you'd replace `18' with the integer in parentheses that -+ was output from the perl one-liner above. -+ If necessary, of course, change `/tmp' to some other directory. */ -+ if (errno != EXDEV) -+ { -+ /* There are many ways this can happen due to a race condition. -+ When something happens between the initial XSTAT and the -+ subsequent rename, we can get many different types of errors. -+ For example, if the destination is initially a non-directory -+ or non-existent, but it is created as a directory, the rename -+ fails. If two `mv' commands try to rename the same file at -+ about the same time, one will succeed and the other will fail. -+ If the permissions on the directory containing the source or -+ destination file are made too restrictive, the rename will -+ fail. Etc. */ -+ error (0, errno, -+ _("cannot move %s to %s"), -+ quote_n (0, src_name), quote_n (1, dst_name)); -+ forget_created (src_sb.st_ino, src_sb.st_dev); -+ return false; -+ } -+ -+ /* The rename attempt has failed. Remove any existing destination -+ file so that a cross-device `mv' acts as if it were really using -+ the rename syscall. */ -+ if (unlink (dst_name) != 0 && errno != ENOENT) -+ { -+ error (0, errno, -+ _("inter-device move failed: %s to %s; unable to remove target"), -+ quote_n (0, src_name), quote_n (1, dst_name)); -+ forget_created (src_sb.st_ino, src_sb.st_dev); -+ return false; -+ } -+ -+ new_dst = true; -+ } -+ -+ /* If the ownership might change, or if it is a directory (whose -+ special mode bits may change after the directory is created), -+ omit some permissions at first, so unauthorized users cannot nip -+ in before the file is ready. */ -+ dst_mode_bits = (x->set_mode ? x->mode : src_mode) & CHMOD_MODE_BITS; -+ omitted_permissions = -+ (dst_mode_bits -+ & (x->preserve_ownership ? S_IRWXG | S_IRWXO -+ : S_ISDIR (src_mode) ? S_IWGRP | S_IWOTH -+ : 0)); -+ -+ delayed_ok = true; -+ -+ if (x->preserve_security_context) -+ { -+ security_context_t con; -+ -+ if (0 <= lgetfilecon (src_name, &con)) -+ { -+ if (setfscreatecon (con) < 0) -+ { -+ if (!x->reduce_diagnostics || x->require_preserve_context) -+ error (0, errno, -+ _("failed to set default file creation context to %s"), -+ quote (con)); -+ if (x->require_preserve_context) -+ { -+ freecon (con); -+ return false; -+ } -+ } -+ freecon (con); -+ } -+ else -+ { -+ if (!errno_unsupported (errno) || x->require_preserve_context) -+ { -+ if (!x->reduce_diagnostics || x->require_preserve_context) -+ error (0, errno, -+ _("failed to get security context of %s"), -+ quote (src_name)); -+ if (x->require_preserve_context) -+ return false; -+ } -+ } -+ } -+ -+ if (S_ISDIR (src_mode)) -+ { -+ struct dir_list *dir; -+ -+ /* If this directory has been copied before during the -+ recursion, there is a symbolic link to an ancestor -+ directory of the symbolic link. It is impossible to -+ continue to copy this, unless we've got an infinite disk. */ -+ -+ if (is_ancestor (&src_sb, ancestors)) -+ { -+ error (0, 0, _("cannot copy cyclic symbolic link %s"), -+ quote (src_name)); -+ goto un_backup; -+ } -+ -+ /* Insert the current directory in the list of parents. */ -+ -+ dir = alloca (sizeof *dir); -+ dir->parent = ancestors; -+ dir->ino = src_sb.st_ino; -+ dir->dev = src_sb.st_dev; -+ -+ if (new_dst || !S_ISDIR (dst_sb.st_mode)) -+ { -+ /* POSIX says mkdir's behavior is implementation-defined when -+ (src_mode & ~S_IRWXUGO) != 0. However, common practice is -+ to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir -+ decide what to do with S_ISUID | S_ISGID | S_ISVTX. */ -+ if (mkdir (dst_name, dst_mode_bits & ~omitted_permissions) != 0) -+ { -+ error (0, errno, _("cannot create directory %s"), -+ quote (dst_name)); -+ goto un_backup; -+ } -+ -+ /* We need search and write permissions to the new directory -+ for writing the directory's contents. Check if these -+ permissions are there. */ -+ -+ if (lstat (dst_name, &dst_sb) != 0) -+ { -+ error (0, errno, _("cannot stat %s"), quote (dst_name)); -+ goto un_backup; -+ } -+ else if ((dst_sb.st_mode & S_IRWXU) != S_IRWXU) -+ { -+ /* Make the new directory searchable and writable. */ -+ -+ dst_mode = dst_sb.st_mode; -+ restore_dst_mode = true; -+ -+ if (lchmod (dst_name, dst_mode | S_IRWXU) != 0) -+ { -+ error (0, errno, _("setting permissions for %s"), -+ quote (dst_name)); -+ goto un_backup; -+ } -+ } -+ -+ /* Record the created directory's inode and device numbers into -+ the search structure, so that we can avoid copying it again. -+ Do this only for the first directory that is created for each -+ source command line argument. */ -+ if (!*first_dir_created_per_command_line_arg) -+ { -+ remember_copied (dst_name, dst_sb.st_ino, dst_sb.st_dev); -+ *first_dir_created_per_command_line_arg = true; -+ } -+ -+ if (x->verbose) -+ emit_verbose (src_name, dst_name, NULL); -+ } -+ -+ /* Decide whether to copy the contents of the directory. */ -+ if (x->one_file_system && device != 0 && device != src_sb.st_dev) -+ { -+ /* Here, we are crossing a file system boundary and cp's -x option -+ is in effect: so don't copy the contents of this directory. */ -+ } -+ else -+ { -+ /* Copy the contents of the directory. Don't just return if -+ this fails -- otherwise, the failure to read a single file -+ in a source directory would cause the containing destination -+ directory not to have owner/perms set properly. */ -+ delayed_ok = copy_dir (src_name, dst_name, new_dst, &src_sb, dir, x, -+ first_dir_created_per_command_line_arg, -+ copy_into_self); -+ } -+ } -+ else if (x->symbolic_link) -+ { -+ dest_is_symlink = true; -+ if (*src_name != '/') -+ { -+ /* Check that DST_NAME denotes a file in the current directory. */ -+ struct stat dot_sb; -+ struct stat dst_parent_sb; -+ char *dst_parent; -+ bool in_current_dir; -+ -+ dst_parent = dir_name (dst_name); -+ -+ in_current_dir = (STREQ (".", dst_parent) -+ /* If either stat call fails, it's ok not to report -+ the failure and say dst_name is in the current -+ directory. Other things will fail later. */ -+ || stat (".", &dot_sb) != 0 -+ || stat (dst_parent, &dst_parent_sb) != 0 -+ || SAME_INODE (dot_sb, dst_parent_sb)); -+ free (dst_parent); -+ -+ if (! in_current_dir) -+ { -+ error (0, 0, -+ _("%s: can make relative symbolic links only in current directory"), -+ quote (dst_name)); -+ goto un_backup; -+ } -+ } -+ if (symlink (src_name, dst_name) != 0) -+ { -+ error (0, errno, _("cannot create symbolic link %s to %s"), -+ quote_n (0, dst_name), quote_n (1, src_name)); -+ goto un_backup; -+ } -+ } -+ -+ /* cp, invoked with `--link --no-dereference', should not follow the -+ link; we guarantee this with gnulib's linkat module (on systems -+ where link(2) follows the link, gnulib creates a symlink with -+ identical contents, which is good enough for our purposes). */ -+ else if (x->hard_link -+ && (!S_ISLNK (src_mode) -+ || x->dereference != DEREF_NEVER)) -+ { -+ if (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, 0)) -+ { -+ error (0, errno, _("cannot create link %s"), quote (dst_name)); -+ goto un_backup; -+ } -+ } -+ else if (S_ISREG (src_mode) -+ || (x->copy_as_regular && !S_ISLNK (src_mode))) -+ { -+ copied_as_regular = true; -+ /* POSIX says the permission bits of the source file must be -+ used as the 3rd argument in the open call. Historical -+ practice passed all the source mode bits to 'open', but the extra -+ bits were ignored, so it should be the same either way. */ -+ if (! copy_reg (src_name, dst_name, x, src_mode & S_IRWXUGO, -+ omitted_permissions, &new_dst, &src_sb)) -+ goto un_backup; -+ } -+ else if (S_ISFIFO (src_mode)) -+ { -+ /* Use mknod, rather than mkfifo, because the former preserves -+ the special mode bits of a fifo on Solaris 10, while mkfifo -+ does not. But fall back on mkfifo, because on some BSD systems, -+ mknod always fails when asked to create a FIFO. */ -+ if (mknod (dst_name, src_mode & ~omitted_permissions, 0) != 0) -+ if (mkfifo (dst_name, src_mode & ~S_IFIFO & ~omitted_permissions) != 0) -+ { -+ error (0, errno, _("cannot create fifo %s"), quote (dst_name)); -+ goto un_backup; -+ } -+ } -+ else if (S_ISBLK (src_mode) || S_ISCHR (src_mode) || S_ISSOCK (src_mode)) -+ { -+ if (mknod (dst_name, src_mode & ~omitted_permissions, src_sb.st_rdev) -+ != 0) -+ { -+ error (0, errno, _("cannot create special file %s"), -+ quote (dst_name)); -+ goto un_backup; -+ } -+ } -+ else if (S_ISLNK (src_mode)) -+ { -+ char *src_link_val = areadlink_with_size (src_name, src_sb.st_size); -+ dest_is_symlink = true; -+ if (src_link_val == NULL) -+ { -+ error (0, errno, _("cannot read symbolic link %s"), quote (src_name)); -+ goto un_backup; -+ } -+ -+ if (symlink (src_link_val, dst_name) == 0) -+ free (src_link_val); -+ else -+ { -+ int saved_errno = errno; -+ bool same_link = false; -+ if (x->update && !new_dst && S_ISLNK (dst_sb.st_mode) -+ && dst_sb.st_size == strlen (src_link_val)) -+ { -+ /* See if the destination is already the desired symlink. -+ FIXME: This behavior isn't documented, and seems wrong -+ in some cases, e.g., if the destination symlink has the -+ wrong ownership, permissions, or time stamps. */ -+ char *dest_link_val = -+ areadlink_with_size (dst_name, dst_sb.st_size); -+ if (dest_link_val && STREQ (dest_link_val, src_link_val)) -+ same_link = true; -+ free (dest_link_val); -+ } -+ free (src_link_val); -+ -+ if (! same_link) -+ { -+ error (0, saved_errno, _("cannot create symbolic link %s"), -+ quote (dst_name)); -+ goto un_backup; -+ } -+ } -+ -+ if (x->preserve_security_context) -+ restore_default_fscreatecon_or_die (); -+ -+ if (x->preserve_ownership) -+ { -+ /* Preserve the owner and group of the just-`copied' -+ symbolic link, if possible. */ -+ if (HAVE_LCHOWN -+ && lchown (dst_name, src_sb.st_uid, src_sb.st_gid) != 0 -+ && ! chown_failure_ok (x)) -+ { -+ error (0, errno, _("failed to preserve ownership for %s"), -+ dst_name); -+ goto un_backup; -+ } -+ else -+ { -+ /* Can't preserve ownership of symlinks. -+ FIXME: maybe give a warning or even error for symlinks -+ in directories with the sticky bit set -- there, not -+ preserving owner/group is a potential security problem. */ -+ } -+ } -+ } -+ else -+ { -+ error (0, 0, _("%s has unknown file type"), quote (src_name)); -+ goto un_backup; -+ } -+ -+ if (command_line_arg && x->dest_info) -+ { -+ /* Now that the destination file is very likely to exist, -+ add its info to the set. */ -+ struct stat sb; -+ if (lstat (dst_name, &sb) == 0) -+ record_file (x->dest_info, dst_name, &sb); -+ } -+ -+ /* If we've just created a hard-link due to cp's --link option, -+ we're done. */ -+ if (x->hard_link && ! S_ISDIR (src_mode)) -+ return delayed_ok; -+ -+ if (copied_as_regular) -+ return delayed_ok; -+ -+ /* POSIX says that `cp -p' must restore the following: -+ - permission bits -+ - setuid, setgid bits -+ - owner and group -+ If it fails to restore any of those, we may give a warning but -+ the destination must not be removed. -+ FIXME: implement the above. */ -+ -+ /* Adjust the times (and if possible, ownership) for the copy. -+ chown turns off set[ug]id bits for non-root, -+ so do the chmod last. */ -+ -+ if (x->preserve_timestamps) -+ { -+ struct timespec timespec[2]; -+ timespec[0] = get_stat_atime (&src_sb); -+ timespec[1] = get_stat_mtime (&src_sb); -+ -+ if ((dest_is_symlink -+ ? utimens_symlink (dst_name, timespec) -+ : utimens (dst_name, timespec)) -+ != 0) -+ { -+ error (0, errno, _("preserving times for %s"), quote (dst_name)); -+ if (x->require_preserve) -+ return false; -+ } -+ } -+ -+ /* The operations beyond this point may dereference a symlink. */ -+ if (dest_is_symlink) -+ return delayed_ok; -+ -+ /* Avoid calling chown if we know it's not necessary. */ -+ if (x->preserve_ownership -+ && (new_dst || !SAME_OWNER_AND_GROUP (src_sb, dst_sb))) -+ { -+ switch (set_owner (x, dst_name, -1, &src_sb, new_dst, &dst_sb)) -+ { -+ case -1: -+ return false; -+ -+ case 0: -+ src_mode &= ~ (S_ISUID | S_ISGID | S_ISVTX); -+ break; -+ } -+ } -+ -+ set_author (dst_name, -1, &src_sb); -+ -+ if (x->preserve_xattr && ! copy_attr_by_name (src_name, dst_name, x) -+ && x->require_preserve_xattr) -+ return false; -+ -+ if (x->preserve_mode || x->move_mode) -+ { -+ if (copy_acl (src_name, -1, dst_name, -1, src_mode) != 0 -+ && x->require_preserve) -+ return false; -+ } -+ else if (x->set_mode) -+ { -+ if (set_acl (dst_name, -1, x->mode) != 0) -+ return false; -+ } -+ else -+ { -+ if (omitted_permissions) -+ { -+ omitted_permissions &= ~ cached_umask (); -+ -+ if (omitted_permissions && !restore_dst_mode) -+ { -+ /* Permissions were deliberately omitted when the file -+ was created due to security concerns. See whether -+ they need to be re-added now. It'd be faster to omit -+ the lstat, but deducing the current destination mode -+ is tricky in the presence of implementation-defined -+ rules for special mode bits. */ -+ if (new_dst && lstat (dst_name, &dst_sb) != 0) -+ { -+ error (0, errno, _("cannot stat %s"), quote (dst_name)); -+ return false; -+ } -+ dst_mode = dst_sb.st_mode; -+ if (omitted_permissions & ~dst_mode) -+ restore_dst_mode = true; -+ } -+ } -+ -+ if (restore_dst_mode) -+ { -+ if (lchmod (dst_name, dst_mode | omitted_permissions) != 0) -+ { -+ error (0, errno, _("preserving permissions for %s"), -+ quote (dst_name)); -+ if (x->require_preserve) -+ return false; -+ } -+ } -+ } -+ -+ return delayed_ok; -+ -+un_backup: -+ -+ if (x->preserve_security_context) -+ restore_default_fscreatecon_or_die (); -+ -+ /* We have failed to create the destination file. -+ If we've just added a dev/ino entry via the remember_copied -+ call above (i.e., unless we've just failed to create a hard link), -+ remove the entry associating the source dev/ino with the -+ destination file name, so we don't try to `preserve' a link -+ to a file we didn't create. */ -+ if (earlier_file == NULL) -+ forget_created (src_sb.st_ino, src_sb.st_dev); -+ -+ if (dst_backup) -+ { -+ if (rename (dst_backup, dst_name) != 0) -+ error (0, errno, _("cannot un-backup %s"), quote (dst_name)); -+ else -+ { -+ if (x->verbose) -+ printf (_("%s -> %s (unbackup)\n"), -+ quote_n (0, dst_backup), quote_n (1, dst_name)); -+ } -+ } -+ return false; -+} -+ -+static bool -+valid_options (const struct cp_options *co) -+{ -+ assert (co != NULL); -+ assert (VALID_BACKUP_TYPE (co->backup_type)); -+ assert (VALID_SPARSE_MODE (co->sparse_mode)); -+ assert (VALID_REFLINK_MODE (co->reflink_mode)); -+ assert (!(co->hard_link && co->symbolic_link)); -+ assert (! -+ (co->reflink_mode == REFLINK_ALWAYS -+ && co->sparse_mode != SPARSE_AUTO)); -+ return true; -+} -+ -+/* Copy the file SRC_NAME to the file DST_NAME. The files may be of -+ any type. NONEXISTENT_DST should be true if the file DST_NAME -+ is known not to exist (e.g., because its parent directory was just -+ created); NONEXISTENT_DST should be false if DST_NAME might already -+ exist. OPTIONS is ... FIXME-describe -+ Set *COPY_INTO_SELF if SRC_NAME is a parent of (or the -+ same as) DST_NAME; otherwise, set clear it. -+ Return true if successful. */ -+ -+extern bool -+copy (char const *src_name, char const *dst_name, -+ bool nonexistent_dst, const struct cp_options *options, -+ bool *copy_into_self, bool *rename_succeeded) -+{ -+ assert (valid_options (options)); -+ -+ /* Record the file names: they're used in case of error, when copying -+ a directory into itself. I don't like to make these tools do *any* -+ extra work in the common case when that work is solely to handle -+ exceptional cases, but in this case, I don't see a way to derive the -+ top level source and destination directory names where they're used. -+ An alternative is to use COPY_INTO_SELF and print the diagnostic -+ from every caller -- but I don't want to do that. */ -+ top_level_src_name = src_name; -+ top_level_dst_name = dst_name; -+ -+ bool first_dir_created_per_command_line_arg = false; -+ return copy_internal (src_name, dst_name, nonexistent_dst, 0, NULL, -+ options, true, -+ &first_dir_created_per_command_line_arg, -+ copy_into_self, rename_succeeded); -+} -+ -+/* Set *X to the default options for a value of type struct cp_options. */ -+ -+extern void -+cp_options_default (struct cp_options *x) -+{ -+ memset (x, 0, sizeof *x); -+#ifdef PRIV_FILE_CHOWN -+ { -+ priv_set_t *pset = priv_allocset (); -+ if (!pset) -+ xalloc_die (); -+ if (getppriv (PRIV_EFFECTIVE, pset) == 0) -+ { -+ x->chown_privileges = priv_ismember (pset, PRIV_FILE_CHOWN); -+ x->owner_privileges = priv_ismember (pset, PRIV_FILE_OWNER); -+ } -+ priv_freeset (pset); -+ } -+#else -+ x->chown_privileges = x->owner_privileges = (geteuid () == 0); -+#endif -+} -+ -+/* Return true if it's OK for chown to fail, where errno is -+ the error number that chown failed with and X is the copying -+ option set. */ -+ -+extern bool -+chown_failure_ok (struct cp_options const *x) -+{ -+ /* If non-root uses -p, it's ok if we can't preserve ownership. -+ But root probably wants to know, e.g. if NFS disallows it, -+ or if the target system doesn't support file ownership. */ -+ -+ return ((errno == EPERM || errno == EINVAL) && !x->chown_privileges); -+} -+ -+/* Similarly, return true if it's OK for chmod and similar operations -+ to fail, where errno is the error number that chmod failed with and -+ X is the copying option set. */ -+ -+static bool -+owner_failure_ok (struct cp_options const *x) -+{ -+ return ((errno == EPERM || errno == EINVAL) && !x->owner_privileges); -+} -+ -+/* Return the user's umask, caching the result. */ -+ -+extern mode_t -+cached_umask (void) -+{ -+ static mode_t mask = (mode_t) -1; -+ if (mask == (mode_t) -1) -+ { -+ mask = umask (0); -+ umask (mask); -+ } -+ return mask; -+} diff -urNp coreutils-8.0-orig/src/copy.h coreutils-8.0/src/copy.h --- coreutils-8.0-orig/src/copy.h 2009-09-21 14:29:33.000000000 +0200 +++ coreutils-8.0/src/copy.h 2009-10-07 10:10:11.000000000 +0200 @@ -2449,293 +59,6 @@ diff -urNp coreutils-8.0-orig/src/copy.h coreutils-8.0/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urNp coreutils-8.0-orig/src/copy.h.orig coreutils-8.0/src/copy.h.orig ---- coreutils-8.0-orig/src/copy.h.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/copy.h.orig 2009-09-21 14:29:33.000000000 +0200 -@@ -0,0 +1,283 @@ -+/* core functions for copying files and directories -+ Copyright (C) 89, 90, 91, 1995-2009 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 . */ -+ -+/* Extracted from cp.c and librarified by Jim Meyering. */ -+ -+#ifndef COPY_H -+# define COPY_H -+ -+# include -+# include "hash.h" -+ -+/* Control creation of sparse files (files with holes). */ -+enum Sparse_type -+{ -+ SPARSE_UNUSED, -+ -+ /* Never create holes in DEST. */ -+ SPARSE_NEVER, -+ -+ /* This is the default. Use a crude (and sometimes inaccurate) -+ heuristic to determine if SOURCE has holes. If so, try to create -+ holes in DEST. */ -+ SPARSE_AUTO, -+ -+ /* For every sufficiently long sequence of bytes in SOURCE, try to -+ create a corresponding hole in DEST. There is a performance penalty -+ here because CP has to search for holes in SRC. But if the holes are -+ big enough, that penalty can be offset by the decrease in the amount -+ of data written to disk. */ -+ SPARSE_ALWAYS -+}; -+ -+/* Control creation of COW files. */ -+enum Reflink_type -+{ -+ /* Default to a standard copy. */ -+ REFLINK_NEVER, -+ -+ /* Try a COW copy and fall back to a standard copy. */ -+ REFLINK_AUTO, -+ -+ /* Require a COW copy and fail if not available. */ -+ REFLINK_ALWAYS -+}; -+ -+/* This type is used to help mv (via copy.c) distinguish these cases. */ -+enum Interactive -+{ -+ I_ALWAYS_YES = 1, -+ I_ALWAYS_NO, -+ I_ASK_USER, -+ I_UNSPECIFIED -+}; -+ -+/* How to handle symbolic links. */ -+enum Dereference_symlink -+{ -+ DEREF_UNDEFINED = 1, -+ -+ /* Copy the symbolic link itself. -P */ -+ DEREF_NEVER, -+ -+ /* If the symbolic is a command line argument, then copy -+ its referent. Otherwise, copy the symbolic link itself. -H */ -+ DEREF_COMMAND_LINE_ARGUMENTS, -+ -+ /* Copy the referent of the symbolic link. -L */ -+ DEREF_ALWAYS -+}; -+ -+# define VALID_SPARSE_MODE(Mode) \ -+ ((Mode) == SPARSE_NEVER \ -+ || (Mode) == SPARSE_AUTO \ -+ || (Mode) == SPARSE_ALWAYS) -+ -+# define VALID_REFLINK_MODE(Mode) \ -+ ((Mode) == REFLINK_NEVER \ -+ || (Mode) == REFLINK_AUTO \ -+ || (Mode) == REFLINK_ALWAYS) -+ -+/* These options control how files are copied by at least the -+ following programs: mv (when rename doesn't work), cp, install. -+ So, if you add a new member, be sure to initialize it in -+ mv.c, cp.c, and install.c. */ -+struct cp_options -+{ -+ enum backup_type backup_type; -+ -+ /* How to handle symlinks in the source. */ -+ enum Dereference_symlink dereference; -+ -+ /* This value is used to determine whether to prompt before removing -+ each existing destination file. It works differently depending on -+ whether move_mode is set. See code/comments in copy.c. */ -+ enum Interactive interactive; -+ -+ /* Control creation of sparse files. */ -+ enum Sparse_type sparse_mode; -+ -+ /* Set the mode of the destination file to exactly this value -+ if SET_MODE is nonzero. */ -+ mode_t mode; -+ -+ /* If true, copy all files except (directories and, if not dereferencing -+ them, symbolic links,) as if they were regular files. */ -+ bool copy_as_regular; -+ -+ /* If true, remove each existing destination nondirectory before -+ trying to open it. */ -+ bool unlink_dest_before_opening; -+ -+ /* If true, first try to open each existing destination nondirectory, -+ then, if the open fails, unlink and try again. -+ This option must be set for `cp -f', in case the destination file -+ exists when the open is attempted. It is irrelevant to `mv' since -+ any destination is sure to be removed before the open. */ -+ bool unlink_dest_after_failed_open; -+ -+ /* If true, create hard links instead of copying files. -+ Create destination directories as usual. */ -+ bool hard_link; -+ -+ /* If true, rather than copying, first attempt to use rename. -+ If that fails, then resort to copying. */ -+ bool move_mode; -+ -+ /* Whether this process has appropriate privileges to chown a file -+ whose owner is not the effective user ID. */ -+ bool chown_privileges; -+ -+ /* Whether this process has appropriate privileges to do the -+ following operations on a file even when it is owned by some -+ other user: set the file's atime, mtime, mode, or ACL; remove or -+ rename an entry in the file even though it is a sticky directory, -+ or to mount on the file. */ -+ bool owner_privileges; -+ -+ /* If true, when copying recursively, skip any subdirectories that are -+ on different file systems from the one we started on. */ -+ bool one_file_system; -+ -+ /* If true, attempt to give the copies the original files' permissions, -+ owner, group, and timestamps. */ -+ bool preserve_ownership; -+ bool preserve_mode; -+ bool preserve_timestamps; -+ -+ /* Enabled for mv, and for cp by the --preserve=links option. -+ If true, attempt to preserve in the destination files any -+ logical hard links between the source files. If used with cp's -+ --no-dereference option, and copying two hard-linked files, -+ the two corresponding destination files will also be hard linked. -+ -+ If used with cp's --dereference (-L) option, then, as that option implies, -+ hard links are *not* preserved. However, when copying a file F and -+ a symlink S to F, the resulting S and F in the destination directory -+ will be hard links to the same file (a copy of F). */ -+ bool preserve_links; -+ -+ /* If true and any of the above (for preserve) file attributes cannot -+ be applied to a destination file, treat it as a failure and return -+ nonzero immediately. E.g. for cp -p this must be true, for mv it -+ must be false. */ -+ bool require_preserve; -+ -+ /* If true, attempt to preserve the SELinux security context, too. -+ Set this only if the kernel is SELinux enabled. */ -+ bool preserve_security_context; -+ -+ /* Useful only when preserve_security_context is true. -+ If true, a failed attempt to preserve a file's security context -+ propagates failure "out" to the caller. If false, a failure to -+ preserve a file's security context does not change the invoking -+ application's exit status. Give diagnostics for failed syscalls -+ regardless of this setting. For example, with "cp --preserve=context" -+ this flag is "true", while with "cp -a", it is false. That means -+ "cp -a" attempts to preserve any security context, but does not -+ fail if it is unable to do so. */ -+ bool require_preserve_context; -+ -+ /* If true, attempt to preserve extended attributes using libattr. -+ Ignored if coreutils are compiled without xattr support. */ -+ bool preserve_xattr; -+ -+ /* Useful only when preserve_xattr is true. -+ If true, a failed attempt to preserve file's extended attributes -+ propagates failure "out" to the caller. If false, a failure to -+ preserve file's extended attributes does not change the invoking -+ application's exit status. Give diagnostics for failed syscalls -+ regardless of this setting. For example, with "cp --preserve=xattr" -+ this flag is "true", while with "cp --preserve=all", it is false. */ -+ bool require_preserve_xattr; -+ -+ /* Used as difference boolean between cp -a and cp -dR --preserve=all. -+ If true, non-mandatory failure diagnostics are not displayed. This -+ should prevent poluting cp -a output. -+ */ -+ bool reduce_diagnostics; -+ -+ /* If true, copy directories recursively and copy special files -+ as themselves rather than copying their contents. */ -+ bool recursive; -+ -+ /* If true, set file mode to value of MODE. Otherwise, -+ set it based on current umask modified by UMASK_KILL. */ -+ bool set_mode; -+ -+ /* If true, create symbolic links instead of copying files. -+ Create destination directories as usual. */ -+ bool symbolic_link; -+ -+ /* If true, do not copy a nondirectory that has an existing destination -+ with the same or newer modification time. */ -+ bool update; -+ -+ /* If true, display the names of the files before copying them. */ -+ bool verbose; -+ -+ /* If true, stdin is a tty. */ -+ bool stdin_tty; -+ -+ /* If true, open a dangling destination symlink when not in move_mode. -+ Otherwise, copy_reg gives a diagnostic (it refuses to write through -+ such a symlink) and returns false. */ -+ bool open_dangling_dest_symlink; -+ -+ /* Control creation of COW files. */ -+ enum Reflink_type reflink_mode; -+ -+ /* This is a set of destination name/inode/dev triples. Each such triple -+ represents a file we have created corresponding to a source file name -+ that was specified on the command line. Use it to avoid clobbering -+ source files in commands like this: -+ rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c -+ For now, it protects only regular files when copying (i.e. not renaming). -+ When renaming, it protects all non-directories. -+ Use dest_info_init to initialize it, or set it to NULL to disable -+ this feature. */ -+ Hash_table *dest_info; -+ -+ /* FIXME */ -+ Hash_table *src_info; -+}; -+ -+# define XSTAT(X, Src_name, Src_sb) \ -+ ((X)->dereference == DEREF_NEVER \ -+ ? lstat (Src_name, Src_sb) \ -+ : stat (Src_name, Src_sb)) -+ -+/* Arrange to make rename calls go through the wrapper function -+ on systems with a rename function that fails for a source file name -+ specified with a trailing slash. */ -+# if RENAME_TRAILING_SLASH_BUG -+int rpl_rename (const char *, const char *); -+# undef rename -+# define rename rpl_rename -+# endif -+ -+bool copy (char const *src_name, char const *dst_name, -+ bool nonexistent_dst, const struct cp_options *options, -+ bool *copy_into_self, bool *rename_succeeded); -+ -+void dest_info_init (struct cp_options *); -+void src_info_init (struct cp_options *); -+ -+void cp_options_default (struct cp_options *); -+bool chown_failure_ok (struct cp_options const *); -+mode_t cached_umask (void); -+ -+#endif diff -urNp coreutils-8.0-orig/src/cp.c coreutils-8.0/src/cp.c --- coreutils-8.0-orig/src/cp.c 2009-09-29 15:27:54.000000000 +0200 +++ coreutils-8.0/src/cp.c 2009-10-07 10:10:11.000000000 +0200 @@ -2827,1170 +150,6 @@ diff -urNp coreutils-8.0-orig/src/cp.c coreutils-8.0/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urNp coreutils-8.0-orig/src/cp.c.orig coreutils-8.0/src/cp.c.orig ---- coreutils-8.0-orig/src/cp.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/cp.c.orig 2009-09-29 15:27:54.000000000 +0200 -@@ -0,0 +1,1160 @@ -+/* cp.c -- file copying (main routines) -+ Copyright (C) 89, 90, 91, 1995-2009 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 Torbjorn Granlund, David MacKenzie, and Jim Meyering. */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "system.h" -+#include "argmatch.h" -+#include "backupfile.h" -+#include "copy.h" -+#include "cp-hash.h" -+#include "error.h" -+#include "filenamecat.h" -+#include "ignore-value.h" -+#include "quote.h" -+#include "stat-time.h" -+#include "utimens.h" -+#include "acl.h" -+ -+#if ! HAVE_LCHOWN -+# define lchown(name, uid, gid) chown (name, uid, gid) -+#endif -+ -+#define ASSIGN_BASENAME_STRDUPA(Dest, File_name) \ -+ do \ -+ { \ -+ char *tmp_abns_; \ -+ ASSIGN_STRDUPA (tmp_abns_, (File_name)); \ -+ Dest = last_component (tmp_abns_); \ -+ strip_trailing_slashes (Dest); \ -+ } \ -+ while (0) -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "cp" -+ -+#define AUTHORS \ -+ proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \ -+ proper_name ("David MacKenzie"), \ -+ proper_name ("Jim Meyering") -+ -+/* Used by do_copy, make_dir_parents_private, and re_protect -+ to keep a list of leading directories whose protections -+ need to be fixed after copying. */ -+struct dir_attr -+{ -+ struct stat st; -+ bool restore_mode; -+ size_t slash_offset; -+ struct dir_attr *next; -+}; -+ -+/* For long options that have no equivalent short option, use a -+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -+enum -+{ -+ COPY_CONTENTS_OPTION = CHAR_MAX + 1, -+ NO_PRESERVE_ATTRIBUTES_OPTION, -+ PARENTS_OPTION, -+ PRESERVE_ATTRIBUTES_OPTION, -+ REFLINK_OPTION, -+ SPARSE_OPTION, -+ STRIP_TRAILING_SLASHES_OPTION, -+ UNLINK_DEST_BEFORE_OPENING -+}; -+ -+/* True if the kernel is SELinux enabled. */ -+static bool selinux_enabled; -+ -+/* If true, the command "cp x/e_file e_dir" uses "e_dir/x/e_file" -+ as its destination instead of the usual "e_dir/e_file." */ -+static bool parents_option = false; -+ -+/* Remove any trailing slashes from each SOURCE argument. */ -+static bool remove_trailing_slashes; -+ -+static char const *const sparse_type_string[] = -+{ -+ "never", "auto", "always", NULL -+}; -+static enum Sparse_type const sparse_type[] = -+{ -+ SPARSE_NEVER, SPARSE_AUTO, SPARSE_ALWAYS -+}; -+ARGMATCH_VERIFY (sparse_type_string, sparse_type); -+ -+static char const *const reflink_type_string[] = -+{ -+ "auto", "always", NULL -+}; -+static enum Reflink_type const reflink_type[] = -+{ -+ REFLINK_AUTO, REFLINK_ALWAYS -+}; -+ARGMATCH_VERIFY (reflink_type_string, reflink_type); -+ -+static struct option const long_opts[] = -+{ -+ {"archive", no_argument, NULL, 'a'}, -+ {"backup", optional_argument, NULL, 'b'}, -+ {"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION}, -+ {"dereference", no_argument, NULL, 'L'}, -+ {"force", no_argument, NULL, 'f'}, -+ {"interactive", no_argument, NULL, 'i'}, -+ {"link", no_argument, NULL, 'l'}, -+ {"no-clobber", no_argument, NULL, 'n'}, -+ {"no-dereference", no_argument, NULL, 'P'}, -+ {"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION}, -+ {"no-target-directory", no_argument, NULL, 'T'}, -+ {"one-file-system", no_argument, NULL, 'x'}, -+ {"parents", no_argument, NULL, PARENTS_OPTION}, -+ {"path", no_argument, NULL, PARENTS_OPTION}, /* Deprecated. */ -+ {"preserve", optional_argument, NULL, PRESERVE_ATTRIBUTES_OPTION}, -+ {"recursive", no_argument, NULL, 'R'}, -+ {"remove-destination", no_argument, NULL, UNLINK_DEST_BEFORE_OPENING}, -+ {"sparse", required_argument, NULL, SPARSE_OPTION}, -+ {"reflink", optional_argument, NULL, REFLINK_OPTION}, -+ {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION}, -+ {"suffix", required_argument, NULL, 'S'}, -+ {"symbolic-link", no_argument, NULL, 's'}, -+ {"target-directory", required_argument, NULL, 't'}, -+ {"update", no_argument, NULL, 'u'}, -+ {"verbose", no_argument, NULL, 'v'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... [-T] SOURCE DEST\n\ -+ or: %s [OPTION]... SOURCE... DIRECTORY\n\ -+ or: %s [OPTION]... -t DIRECTORY SOURCE...\n\ -+"), -+ program_name, program_name, program_name); -+ fputs (_("\ -+Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ -a, --archive same as -dR --preserve=all\n\ -+ --backup[=CONTROL] make a backup of each existing destination file\n\ -+ -b like --backup but does not accept an argument\n\ -+ --copy-contents copy contents of special files when recursive\n\ -+ -d same as --no-dereference --preserve=links\n\ -+"), stdout); -+ fputs (_("\ -+ -f, --force if an existing destination file cannot be\n\ -+ opened, remove it and try again (redundant if\n\ -+ the -n option is used)\n\ -+ -i, --interactive prompt before overwrite (overrides a previous -n\n\ -+ option)\n\ -+ -H follow command-line symbolic links in SOURCE\n\ -+"), stdout); -+ fputs (_("\ -+ -l, --link link files instead of copying\n\ -+ -L, --dereference always follow symbolic links in SOURCE\n\ -+"), stdout); -+ fputs (_("\ -+ -n, --no-clobber do not overwrite an existing file (overrides\n\ -+ a previous -i option)\n\ -+ -P, --no-dereference never follow symbolic links in SOURCE\n\ -+"), stdout); -+ fputs (_("\ -+ -p same as --preserve=mode,ownership,timestamps\n\ -+ --preserve[=ATTR_LIST] preserve the specified attributes (default:\n\ -+ mode,ownership,timestamps), if possible\n\ -+ additional attributes: context, links, xattr,\n\ -+ all\n\ -+"), stdout); -+ fputs (_("\ -+ --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ -+ --parents use full source file name under DIRECTORY\n\ -+"), stdout); -+ fputs (_("\ -+ -R, -r, --recursive copy directories recursively\n\ -+ --reflink[=WHEN] control clone/CoW copies. See below.\n\ -+ --remove-destination remove each existing destination file before\n\ -+ attempting to open it (contrast with --force)\n\ -+"), stdout); -+ fputs (_("\ -+ --sparse=WHEN control creation of sparse files. See below.\n\ -+ --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\ -+ argument\n\ -+"), stdout); -+ fputs (_("\ -+ -s, --symbolic-link make symbolic links instead of copying\n\ -+ -S, --suffix=SUFFIX override the usual backup suffix\n\ -+ -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\ -+ -T, --no-target-directory treat DEST as a normal file\n\ -+"), stdout); -+ fputs (_("\ -+ -u, --update copy only when the SOURCE file is newer\n\ -+ than the destination file or when the\n\ -+ destination file is missing\n\ -+ -v, --verbose explain what is being done\n\ -+ -x, --one-file-system stay on this file system\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ fputs (_("\ -+\n\ -+By default, sparse SOURCE files are detected by a crude heuristic and the\n\ -+corresponding DEST file is made sparse as well. That is the behavior\n\ -+selected by --sparse=auto. Specify --sparse=always to create a sparse DEST\n\ -+file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\ -+Use --sparse=never to inhibit creation of sparse files.\n\ -+\n\ -+When --reflink[=always] is specified, perform a lightweight copy, where the\n\ -+data blocks are copied only when modified. If this is not possible the copy\n\ -+fails, or if --reflink=auto is specified, fall back to a standard copy.\n\ -+"), stdout); -+ fputs (_("\ -+\n\ -+The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\ -+The version control method may be selected via the --backup option or through\n\ -+the VERSION_CONTROL environment variable. Here are the values:\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+ none, off never make backups (even if --backup is given)\n\ -+ numbered, t make numbered backups\n\ -+ existing, nil numbered if numbered backups exist, simple otherwise\n\ -+ simple, never always make simple backups\n\ -+"), stdout); -+ fputs (_("\ -+\n\ -+As a special case, cp makes a backup of SOURCE when the force and backup\n\ -+options are given and SOURCE and DEST are the same name for an existing,\n\ -+regular file.\n\ -+"), stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+/* Ensure that the parent directories of CONST_DST_NAME have the -+ correct protections, for the --parents option. This is done -+ after all copying has been completed, to allow permissions -+ that don't include user write/execute. -+ -+ SRC_OFFSET is the index in CONST_DST_NAME of the beginning of the -+ source directory name. -+ -+ ATTR_LIST is a null-terminated linked list of structures that -+ indicates the end of the filename of each intermediate directory -+ in CONST_DST_NAME that may need to have its attributes changed. -+ The command `cp --parents --preserve a/b/c d/e_dir' changes the -+ attributes of the directories d/e_dir/a and d/e_dir/a/b to match -+ the corresponding source directories regardless of whether they -+ existed before the `cp' command was given. -+ -+ Return true if the parent of CONST_DST_NAME and any intermediate -+ directories specified by ATTR_LIST have the proper permissions -+ when done. */ -+ -+static bool -+re_protect (char const *const_dst_name, size_t src_offset, -+ struct dir_attr *attr_list, const struct cp_options *x) -+{ -+ struct dir_attr *p; -+ char *dst_name; /* A copy of CONST_DST_NAME we can change. */ -+ char *src_name; /* The source name in `dst_name'. */ -+ -+ ASSIGN_STRDUPA (dst_name, const_dst_name); -+ src_name = dst_name + src_offset; -+ -+ for (p = attr_list; p; p = p->next) -+ { -+ dst_name[p->slash_offset] = '\0'; -+ -+ /* Adjust the times (and if possible, ownership) for the copy. -+ chown turns off set[ug]id bits for non-root, -+ so do the chmod last. */ -+ -+ if (x->preserve_timestamps) -+ { -+ struct timespec timespec[2]; -+ -+ timespec[0] = get_stat_atime (&p->st); -+ timespec[1] = get_stat_mtime (&p->st); -+ -+ if (utimens (dst_name, timespec)) -+ { -+ error (0, errno, _("failed to preserve times for %s"), -+ quote (dst_name)); -+ return false; -+ } -+ } -+ -+ if (x->preserve_ownership) -+ { -+ if (lchown (dst_name, p->st.st_uid, p->st.st_gid) != 0) -+ { -+ if (! chown_failure_ok (x)) -+ { -+ error (0, errno, _("failed to preserve ownership for %s"), -+ quote (dst_name)); -+ return false; -+ } -+ /* Failing to preserve ownership is OK. Still, try to preserve -+ the group, but ignore the possible error. */ -+ ignore_value (lchown (dst_name, -1, p->st.st_gid)); -+ } -+ } -+ -+ if (x->preserve_mode) -+ { -+ if (copy_acl (src_name, -1, dst_name, -1, p->st.st_mode) != 0) -+ return false; -+ } -+ else if (p->restore_mode) -+ { -+ if (lchmod (dst_name, p->st.st_mode) != 0) -+ { -+ error (0, errno, _("failed to preserve permissions for %s"), -+ quote (dst_name)); -+ return false; -+ } -+ } -+ -+ dst_name[p->slash_offset] = '/'; -+ } -+ return true; -+} -+ -+/* Ensure that the parent directory of CONST_DIR exists, for -+ the --parents option. -+ -+ SRC_OFFSET is the index in CONST_DIR (which is a destination -+ directory) of the beginning of the source directory name. -+ Create any leading directories that don't already exist. -+ If VERBOSE_FMT_STRING is nonzero, use it as a printf format -+ string for printing a message after successfully making a directory. -+ The format should take two string arguments: the names of the -+ source and destination directories. -+ Creates a linked list of attributes of intermediate directories, -+ *ATTR_LIST, for re_protect to use after calling copy. -+ Sets *NEW_DST if this function creates parent of CONST_DIR. -+ -+ Return true if parent of CONST_DIR exists as a directory with the proper -+ permissions when done. */ -+ -+/* FIXME: Synch this function with the one in ../lib/mkdir-p.c. */ -+ -+static bool -+make_dir_parents_private (char const *const_dir, size_t src_offset, -+ char const *verbose_fmt_string, -+ struct dir_attr **attr_list, bool *new_dst, -+ const struct cp_options *x) -+{ -+ struct stat stats; -+ char *dir; /* A copy of CONST_DIR we can change. */ -+ char *src; /* Source name in DIR. */ -+ char *dst_dir; /* Leading directory of DIR. */ -+ size_t dirlen; /* Length of DIR. */ -+ -+ ASSIGN_STRDUPA (dir, const_dir); -+ -+ src = dir + src_offset; -+ -+ dirlen = dir_len (dir); -+ dst_dir = alloca (dirlen + 1); -+ memcpy (dst_dir, dir, dirlen); -+ dst_dir[dirlen] = '\0'; -+ -+ *attr_list = NULL; -+ -+ if (stat (dst_dir, &stats) != 0) -+ { -+ /* A parent of CONST_DIR does not exist. -+ Make all missing intermediate directories. */ -+ char *slash; -+ -+ slash = src; -+ while (*slash == '/') -+ slash++; -+ while ((slash = strchr (slash, '/'))) -+ { -+ struct dir_attr *new IF_LINT (= NULL); -+ bool missing_dir; -+ -+ *slash = '\0'; -+ missing_dir = (stat (dir, &stats) != 0); -+ -+ if (missing_dir | x->preserve_ownership | x->preserve_mode -+ | x->preserve_timestamps) -+ { -+ /* Add this directory to the list of directories whose -+ modes might need fixing later. */ -+ struct stat src_st; -+ int src_errno = (stat (src, &src_st) != 0 -+ ? errno -+ : S_ISDIR (src_st.st_mode) -+ ? 0 -+ : ENOTDIR); -+ if (src_errno) -+ { -+ error (0, src_errno, _("failed to get attributes of %s"), -+ quote (src)); -+ return false; -+ } -+ -+ new = xmalloc (sizeof *new); -+ new->st = src_st; -+ new->slash_offset = slash - dir; -+ new->restore_mode = false; -+ new->next = *attr_list; -+ *attr_list = new; -+ } -+ -+ if (missing_dir) -+ { -+ mode_t src_mode; -+ mode_t omitted_permissions; -+ mode_t mkdir_mode; -+ -+ /* This component does not exist. We must set -+ *new_dst and new->st.st_mode inside this loop because, -+ for example, in the command `cp --parents ../a/../b/c e_dir', -+ make_dir_parents_private creates only e_dir/../a if -+ ./b already exists. */ -+ *new_dst = true; -+ src_mode = new->st.st_mode; -+ -+ /* If the ownership or special mode bits might change, -+ omit some permissions at first, so unauthorized users -+ cannot nip in before the file is ready. */ -+ omitted_permissions = (src_mode -+ & (x->preserve_ownership -+ ? S_IRWXG | S_IRWXO -+ : x->preserve_mode -+ ? S_IWGRP | S_IWOTH -+ : 0)); -+ -+ /* POSIX says mkdir's behavior is implementation-defined when -+ (src_mode & ~S_IRWXUGO) != 0. However, common practice is -+ to ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdir -+ decide what to do with S_ISUID | S_ISGID | S_ISVTX. */ -+ mkdir_mode = src_mode & CHMOD_MODE_BITS & ~omitted_permissions; -+ if (mkdir (dir, mkdir_mode) != 0) -+ { -+ error (0, errno, _("cannot make directory %s"), -+ quote (dir)); -+ return false; -+ } -+ else -+ { -+ if (verbose_fmt_string != NULL) -+ printf (verbose_fmt_string, src, dir); -+ } -+ -+ /* We need search and write permissions to the new directory -+ for writing the directory's contents. Check if these -+ permissions are there. */ -+ -+ if (lstat (dir, &stats)) -+ { -+ error (0, errno, _("failed to get attributes of %s"), -+ quote (dir)); -+ return false; -+ } -+ -+ -+ if (! x->preserve_mode) -+ { -+ if (omitted_permissions & ~stats.st_mode) -+ omitted_permissions &= ~ cached_umask (); -+ if (omitted_permissions & ~stats.st_mode -+ || (stats.st_mode & S_IRWXU) != S_IRWXU) -+ { -+ new->st.st_mode = stats.st_mode | omitted_permissions; -+ new->restore_mode = true; -+ } -+ } -+ -+ if ((stats.st_mode & S_IRWXU) != S_IRWXU) -+ { -+ /* Make the new directory searchable and writable. -+ The original permissions will be restored later. */ -+ -+ if (lchmod (dir, stats.st_mode | S_IRWXU) != 0) -+ { -+ error (0, errno, _("setting permissions for %s"), -+ quote (dir)); -+ return false; -+ } -+ } -+ } -+ else if (!S_ISDIR (stats.st_mode)) -+ { -+ error (0, 0, _("%s exists but is not a directory"), -+ quote (dir)); -+ return false; -+ } -+ else -+ *new_dst = false; -+ *slash++ = '/'; -+ -+ /* Avoid unnecessary calls to `stat' when given -+ file names containing multiple adjacent slashes. */ -+ while (*slash == '/') -+ slash++; -+ } -+ } -+ -+ /* We get here if the parent of DIR already exists. */ -+ -+ else if (!S_ISDIR (stats.st_mode)) -+ { -+ error (0, 0, _("%s exists but is not a directory"), quote (dst_dir)); -+ return false; -+ } -+ else -+ { -+ *new_dst = false; -+ } -+ return true; -+} -+ -+/* FILE is the last operand of this command. -+ Return true if FILE is a directory. -+ But report an error and exit if there is a problem accessing FILE, -+ or if FILE does not exist but would have to refer to an existing -+ directory if it referred to anything at all. -+ -+ If the file exists, store the file's status into *ST. -+ Otherwise, set *NEW_DST. */ -+ -+static bool -+target_directory_operand (char const *file, struct stat *st, bool *new_dst) -+{ -+ int err = (stat (file, st) == 0 ? 0 : errno); -+ bool is_a_dir = !err && S_ISDIR (st->st_mode); -+ if (err) -+ { -+ if (err != ENOENT) -+ error (EXIT_FAILURE, err, _("accessing %s"), quote (file)); -+ *new_dst = true; -+ } -+ return is_a_dir; -+} -+ -+/* Scan the arguments, and copy each by calling copy. -+ Return true if successful. */ -+ -+static bool -+do_copy (int n_files, char **file, const char *target_directory, -+ bool no_target_directory, struct cp_options *x) -+{ -+ struct stat sb; -+ bool new_dst = false; -+ bool ok = true; -+ -+ if (n_files <= !target_directory) -+ { -+ if (n_files <= 0) -+ error (0, 0, _("missing file operand")); -+ else -+ error (0, 0, _("missing destination file operand after %s"), -+ quote (file[0])); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (no_target_directory) -+ { -+ if (target_directory) -+ error (EXIT_FAILURE, 0, -+ _("cannot combine --target-directory (-t) " -+ "and --no-target-directory (-T)")); -+ if (2 < n_files) -+ { -+ error (0, 0, _("extra operand %s"), quote (file[2])); -+ usage (EXIT_FAILURE); -+ } -+ } -+ else if (!target_directory) -+ { -+ if (2 <= n_files -+ && target_directory_operand (file[n_files - 1], &sb, &new_dst)) -+ target_directory = file[--n_files]; -+ else if (2 < n_files) -+ error (EXIT_FAILURE, 0, _("target %s is not a directory"), -+ quote (file[n_files - 1])); -+ } -+ -+ if (target_directory) -+ { -+ /* cp file1...filen edir -+ Copy the files `file1' through `filen' -+ to the existing directory `edir'. */ -+ int i; -+ -+ /* Initialize these hash tables only if we'll need them. -+ The problems they're used to detect can arise only if -+ there are two or more files to copy. */ -+ if (2 <= n_files) -+ { -+ dest_info_init (x); -+ src_info_init (x); -+ } -+ -+ for (i = 0; i < n_files; i++) -+ { -+ char *dst_name; -+ bool parent_exists = true; /* True if dir_name (dst_name) exists. */ -+ struct dir_attr *attr_list; -+ char *arg_in_concat = NULL; -+ char *arg = file[i]; -+ -+ /* Trailing slashes are meaningful (i.e., maybe worth preserving) -+ only in the source file names. */ -+ if (remove_trailing_slashes) -+ strip_trailing_slashes (arg); -+ -+ if (parents_option) -+ { -+ char *arg_no_trailing_slash; -+ -+ /* Use `arg' without trailing slashes in constructing destination -+ file names. Otherwise, we can end up trying to create a -+ directory via `mkdir ("dst/foo/"...', which is not portable. -+ It fails, due to the trailing slash, on at least -+ NetBSD 1.[34] systems. */ -+ ASSIGN_STRDUPA (arg_no_trailing_slash, arg); -+ strip_trailing_slashes (arg_no_trailing_slash); -+ -+ /* Append all of `arg' (minus any trailing slash) to `dest'. */ -+ dst_name = file_name_concat (target_directory, -+ arg_no_trailing_slash, -+ &arg_in_concat); -+ -+ /* For --parents, we have to make sure that the directory -+ dir_name (dst_name) exists. We may have to create a few -+ leading directories. */ -+ parent_exists = -+ (make_dir_parents_private -+ (dst_name, arg_in_concat - dst_name, -+ (x->verbose ? "%s -> %s\n" : NULL), -+ &attr_list, &new_dst, x)); -+ } -+ else -+ { -+ char *arg_base; -+ /* Append the last component of `arg' to `target_directory'. */ -+ -+ ASSIGN_BASENAME_STRDUPA (arg_base, arg); -+ /* For `cp -R source/.. dest', don't copy into `dest/..'. */ -+ dst_name = (STREQ (arg_base, "..") -+ ? xstrdup (target_directory) -+ : file_name_concat (target_directory, arg_base, -+ NULL)); -+ } -+ -+ if (!parent_exists) -+ { -+ /* make_dir_parents_private failed, so don't even -+ attempt the copy. */ -+ ok = false; -+ } -+ else -+ { -+ bool copy_into_self; -+ ok &= copy (arg, dst_name, new_dst, x, ©_into_self, NULL); -+ -+ if (parents_option) -+ ok &= re_protect (dst_name, arg_in_concat - dst_name, -+ attr_list, x); -+ } -+ -+ if (parents_option) -+ { -+ while (attr_list) -+ { -+ struct dir_attr *p = attr_list; -+ attr_list = attr_list->next; -+ free (p); -+ } -+ } -+ -+ free (dst_name); -+ } -+ } -+ else /* !target_directory */ -+ { -+ char const *new_dest; -+ char const *source = file[0]; -+ char const *dest = file[1]; -+ bool unused; -+ -+ if (parents_option) -+ { -+ error (0, 0, -+ _("with --parents, the destination must be a directory")); -+ usage (EXIT_FAILURE); -+ } -+ -+ /* When the force and backup options have been specified and -+ the source and destination are the same name for an existing -+ regular file, convert the user's command, e.g., -+ `cp --force --backup foo foo' to `cp --force foo fooSUFFIX' -+ where SUFFIX is determined by any version control options used. */ -+ -+ if (x->unlink_dest_after_failed_open -+ && x->backup_type != no_backups -+ && STREQ (source, dest) -+ && !new_dst && S_ISREG (sb.st_mode)) -+ { -+ static struct cp_options x_tmp; -+ -+ new_dest = find_backup_file_name (dest, x->backup_type); -+ /* Set x->backup_type to `no_backups' so that the normal backup -+ mechanism is not used when performing the actual copy. -+ backup_type must be set to `no_backups' only *after* the above -+ call to find_backup_file_name -- that function uses -+ backup_type to determine the suffix it applies. */ -+ x_tmp = *x; -+ x_tmp.backup_type = no_backups; -+ x = &x_tmp; -+ } -+ else -+ { -+ new_dest = dest; -+ } -+ -+ ok = copy (source, new_dest, 0, x, &unused, NULL); -+ } -+ -+ return ok; -+} -+ -+static void -+cp_option_init (struct cp_options *x) -+{ -+ cp_options_default (x); -+ x->copy_as_regular = true; -+ x->dereference = DEREF_UNDEFINED; -+ x->unlink_dest_before_opening = false; -+ x->unlink_dest_after_failed_open = false; -+ x->hard_link = false; -+ x->interactive = I_UNSPECIFIED; -+ x->move_mode = false; -+ x->one_file_system = false; -+ x->reflink_mode = REFLINK_NEVER; -+ -+ x->preserve_ownership = false; -+ x->preserve_links = false; -+ x->preserve_mode = false; -+ x->preserve_timestamps = false; -+ x->preserve_security_context = false; -+ x->require_preserve_context = false; -+ x->preserve_xattr = false; -+ x->reduce_diagnostics = false; -+ x->require_preserve_xattr = false; -+ -+ x->require_preserve = false; -+ x->recursive = false; -+ x->sparse_mode = SPARSE_AUTO; -+ x->symbolic_link = false; -+ x->set_mode = false; -+ x->mode = 0; -+ -+ /* Not used. */ -+ x->stdin_tty = false; -+ -+ x->update = false; -+ x->verbose = false; -+ -+ /* By default, refuse to open a dangling destination symlink, because -+ in general one cannot do that safely, give the current semantics of -+ open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw). -+ But POSIX requires it. */ -+ x->open_dangling_dest_symlink = getenv ("POSIXLY_CORRECT") != NULL; -+ -+ x->dest_info = NULL; -+ x->src_info = NULL; -+} -+ -+/* Given a string, ARG, containing a comma-separated list of arguments -+ to the --preserve option, set the appropriate fields of X to ON_OFF. */ -+static void -+decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off) -+{ -+ enum File_attribute -+ { -+ PRESERVE_MODE, -+ PRESERVE_TIMESTAMPS, -+ PRESERVE_OWNERSHIP, -+ PRESERVE_LINK, -+ PRESERVE_CONTEXT, -+ PRESERVE_XATTR, -+ PRESERVE_ALL -+ }; -+ static enum File_attribute const preserve_vals[] = -+ { -+ PRESERVE_MODE, PRESERVE_TIMESTAMPS, -+ PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_XATTR, -+ PRESERVE_ALL -+ }; -+ /* Valid arguments to the `--preserve' option. */ -+ static char const* const preserve_args[] = -+ { -+ "mode", "timestamps", -+ "ownership", "links", "context", "xattr", "all", NULL -+ }; -+ ARGMATCH_VERIFY (preserve_args, preserve_vals); -+ -+ char *arg_writable = xstrdup (arg); -+ char *s = arg_writable; -+ do -+ { -+ /* find next comma */ -+ char *comma = strchr (s, ','); -+ enum File_attribute val; -+ -+ /* If we found a comma, put a NUL in its place and advance. */ -+ if (comma) -+ *comma++ = 0; -+ -+ /* process S. */ -+ val = XARGMATCH ("--preserve", s, preserve_args, preserve_vals); -+ switch (val) -+ { -+ case PRESERVE_MODE: -+ x->preserve_mode = on_off; -+ break; -+ -+ case PRESERVE_TIMESTAMPS: -+ x->preserve_timestamps = on_off; -+ break; -+ -+ case PRESERVE_OWNERSHIP: -+ x->preserve_ownership = on_off; -+ break; -+ -+ case PRESERVE_LINK: -+ x->preserve_links = on_off; -+ break; -+ -+ case PRESERVE_CONTEXT: -+ x->preserve_security_context = on_off; -+ x->require_preserve_context = on_off; -+ break; -+ -+ case PRESERVE_XATTR: -+ x->preserve_xattr = on_off; -+ x->require_preserve_xattr = on_off; -+ break; -+ -+ case PRESERVE_ALL: -+ x->preserve_mode = on_off; -+ x->preserve_timestamps = on_off; -+ x->preserve_ownership = on_off; -+ x->preserve_links = on_off; -+ if (selinux_enabled) -+ x->preserve_security_context = on_off; -+ x->preserve_xattr = on_off; -+ break; -+ -+ default: -+ abort (); -+ } -+ s = comma; -+ } -+ while (s); -+ -+ free (arg_writable); -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int c; -+ bool ok; -+ bool make_backups = false; -+ char *backup_suffix_string; -+ char *version_control_string = NULL; -+ struct cp_options x; -+ bool copy_contents = false; -+ char *target_directory = NULL; -+ bool no_target_directory = false; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdin); -+ -+ selinux_enabled = (0 < is_selinux_enabled ()); -+ cp_option_init (&x); -+ -+ /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless -+ we'll actually use backup_suffix_string. */ -+ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); -+ -+ while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T", -+ long_opts, NULL)) -+ != -1) -+ { -+ switch (c) -+ { -+ case SPARSE_OPTION: -+ x.sparse_mode = XARGMATCH ("--sparse", optarg, -+ sparse_type_string, sparse_type); -+ break; -+ -+ case REFLINK_OPTION: -+ if (optarg == NULL) -+ x.reflink_mode = REFLINK_ALWAYS; -+ else -+ x.reflink_mode = XARGMATCH ("--reflink", optarg, -+ reflink_type_string, reflink_type); -+ break; -+ -+ case 'a': /* Like -dR --preserve=all with reduced failure diagnostics. */ -+ x.dereference = DEREF_NEVER; -+ x.preserve_links = true; -+ x.preserve_ownership = true; -+ x.preserve_mode = true; -+ x.preserve_timestamps = true; -+ x.require_preserve = true; -+ if (selinux_enabled) -+ x.preserve_security_context = true; -+ x.preserve_xattr = true; -+ x.reduce_diagnostics = true; -+ x.recursive = true; -+ break; -+ -+ case 'b': -+ make_backups = true; -+ if (optarg) -+ version_control_string = optarg; -+ break; -+ -+ case COPY_CONTENTS_OPTION: -+ copy_contents = true; -+ break; -+ -+ case 'd': -+ x.preserve_links = true; -+ x.dereference = DEREF_NEVER; -+ break; -+ -+ case 'f': -+ x.unlink_dest_after_failed_open = true; -+ break; -+ -+ case 'H': -+ x.dereference = DEREF_COMMAND_LINE_ARGUMENTS; -+ break; -+ -+ case 'i': -+ x.interactive = I_ASK_USER; -+ break; -+ -+ case 'l': -+ x.hard_link = true; -+ break; -+ -+ case 'L': -+ x.dereference = DEREF_ALWAYS; -+ break; -+ -+ case 'n': -+ x.interactive = I_ALWAYS_NO; -+ break; -+ -+ case 'P': -+ x.dereference = DEREF_NEVER; -+ break; -+ -+ case NO_PRESERVE_ATTRIBUTES_OPTION: -+ decode_preserve_arg (optarg, &x, false); -+ break; -+ -+ case PRESERVE_ATTRIBUTES_OPTION: -+ if (optarg == NULL) -+ { -+ /* Fall through to the case for `p' below. */ -+ } -+ else -+ { -+ decode_preserve_arg (optarg, &x, true); -+ x.require_preserve = true; -+ break; -+ } -+ -+ case 'p': -+ x.preserve_ownership = true; -+ x.preserve_mode = true; -+ x.preserve_timestamps = true; -+ x.require_preserve = true; -+ break; -+ -+ case PARENTS_OPTION: -+ parents_option = true; -+ break; -+ -+ case 'r': -+ case 'R': -+ x.recursive = true; -+ break; -+ -+ case UNLINK_DEST_BEFORE_OPENING: -+ x.unlink_dest_before_opening = true; -+ break; -+ -+ case STRIP_TRAILING_SLASHES_OPTION: -+ remove_trailing_slashes = true; -+ break; -+ -+ case 's': -+ x.symbolic_link = true; -+ break; -+ -+ case 't': -+ if (target_directory) -+ error (EXIT_FAILURE, 0, -+ _("multiple target directories specified")); -+ else -+ { -+ struct stat st; -+ if (stat (optarg, &st) != 0) -+ error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg)); -+ if (! S_ISDIR (st.st_mode)) -+ error (EXIT_FAILURE, 0, _("target %s is not a directory"), -+ quote (optarg)); -+ } -+ target_directory = optarg; -+ break; -+ -+ case 'T': -+ no_target_directory = true; -+ break; -+ -+ case 'u': -+ x.update = true; -+ break; -+ -+ case 'v': -+ x.verbose = true; -+ break; -+ -+ case 'x': -+ x.one_file_system = true; -+ break; -+ -+ case 'S': -+ make_backups = true; -+ backup_suffix_string = optarg; -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (x.hard_link && x.symbolic_link) -+ { -+ error (0, 0, _("cannot make both hard and symbolic links")); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (make_backups && x.interactive == I_ALWAYS_NO) -+ { -+ error (0, 0, -+ _("options --backup and --no-clobber are mutually exclusive")); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (x.reflink_mode == REFLINK_ALWAYS && x.sparse_mode != SPARSE_AUTO) -+ { -+ error (0, 0, _("--reflink can be used only with --sparse=auto")); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (backup_suffix_string) -+ simple_backup_suffix = xstrdup (backup_suffix_string); -+ -+ x.backup_type = (make_backups -+ ? xget_version (_("backup type"), -+ version_control_string) -+ : no_backups); -+ -+ if (x.dereference == DEREF_UNDEFINED) -+ { -+ if (x.recursive) -+ /* This is compatible with FreeBSD. */ -+ x.dereference = DEREF_NEVER; -+ else -+ x.dereference = DEREF_ALWAYS; -+ } -+ -+ if (x.recursive) -+ x.copy_as_regular = copy_contents; -+ -+ /* If --force (-f) was specified and we're in link-creation mode, -+ first remove any existing destination file. */ -+ if (x.unlink_dest_after_failed_open && (x.hard_link || x.symbolic_link)) -+ x.unlink_dest_before_opening = true; -+ -+ if (x.preserve_security_context) -+ { -+ if (!selinux_enabled) -+ error (EXIT_FAILURE, 0, -+ _("cannot preserve security context " -+ "without an SELinux-enabled kernel")); -+ } -+ -+#if !USE_XATTR -+ if (x.require_preserve_xattr) -+ error (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is " -+ "built without xattr support")); -+#endif -+ -+ /* Allocate space for remembering copied and created files. */ -+ -+ hash_init (); -+ -+ ok = do_copy (argc - optind, argv + optind, -+ target_directory, no_target_directory, &x); -+ -+ forget_all (); -+ -+ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); -+} diff -urNp coreutils-8.0-orig/src/chcon.c coreutils-8.0/src/chcon.c --- coreutils-8.0-orig/src/chcon.c 2009-10-06 10:55:34.000000000 +0200 +++ coreutils-8.0/src/chcon.c 2009-10-07 10:10:11.000000000 +0200 @@ -4003,593 +162,6 @@ diff -urNp coreutils-8.0-orig/src/chcon.c coreutils-8.0/src/chcon.c With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ -h, --no-dereference affect symbolic links instead of any referenced file\n\ -@@ -523,6 +523,10 @@ main (int argc, char **argv) - error (EXIT_FAILURE, 0, - _("%s may be used only on a SELinux kernel"), program_name); - -+ if (is_selinux_enabled () != 1) -+ error (EXIT_FAILURE, 0, -+ _("%s may be used only on a SELinux kernel"), program_name); -+ - if (reference_file) - { - if (getfilecon (reference_file, &ref_context) < 0) -diff -urNp coreutils-8.0-orig/src/chcon.c.orig coreutils-8.0/src/chcon.c.orig ---- coreutils-8.0-orig/src/chcon.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/chcon.c.orig 2009-10-06 10:55:34.000000000 +0200 -@@ -0,0 +1,572 @@ -+/* chcon -- change security context of files -+ Copyright (C) 2005-2009 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 . */ -+ -+#include -+#include -+#include -+#include -+ -+#include "system.h" -+#include "dev-ino.h" -+#include "error.h" -+#include "ignore-value.h" -+#include "quote.h" -+#include "quotearg.h" -+#include "root-dev-ino.h" -+#include "selinux-at.h" -+#include "xfts.h" -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "chcon" -+ -+#define AUTHORS \ -+ proper_name ("Russell Coker"), \ -+ proper_name ("Jim Meyering") -+ -+/* If nonzero, and the systems has support for it, change the context -+ of symbolic links rather than any files they point to. */ -+static bool affect_symlink_referent; -+ -+/* If true, change the modes of directories recursively. */ -+static bool recurse; -+ -+/* Level of verbosity. */ -+static bool verbose; -+ -+/* Pointer to the device and inode numbers of `/', when --recursive. -+ Otherwise NULL. */ -+static struct dev_ino *root_dev_ino; -+ -+/* The name of the context file is being given. */ -+static char const *specified_context; -+ -+/* Specific components of the context */ -+static char const *specified_user; -+static char const *specified_role; -+static char const *specified_range; -+static char const *specified_type; -+ -+/* For long options that have no equivalent short option, use a -+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -+enum -+{ -+ DEREFERENCE_OPTION = CHAR_MAX + 1, -+ NO_PRESERVE_ROOT, -+ PRESERVE_ROOT, -+ REFERENCE_FILE_OPTION -+}; -+ -+static struct option const long_options[] = -+{ -+ {"recursive", no_argument, NULL, 'R'}, -+ {"dereference", no_argument, NULL, DEREFERENCE_OPTION}, -+ {"no-dereference", no_argument, NULL, 'h'}, -+ {"no-preserve-root", no_argument, NULL, NO_PRESERVE_ROOT}, -+ {"preserve-root", no_argument, NULL, PRESERVE_ROOT}, -+ {"reference", required_argument, NULL, REFERENCE_FILE_OPTION}, -+ {"user", required_argument, NULL, 'u'}, -+ {"role", required_argument, NULL, 'r'}, -+ {"type", required_argument, NULL, 't'}, -+ {"range", required_argument, NULL, 'l'}, -+ {"verbose", no_argument, NULL, 'v'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+/* Given a security context, CONTEXT, derive a context_t (*RET), -+ setting any portions selected via the global variables, specified_user, -+ specified_role, etc. */ -+static int -+compute_context_from_mask (security_context_t context, context_t *ret) -+{ -+ bool ok = true; -+ context_t new_context = context_new (context); -+ if (!new_context) -+ { -+ error (0, errno, _("failed to create security context: %s"), -+ quotearg_colon (context)); -+ return 1; -+ } -+ -+#define SET_COMPONENT(C, comp) \ -+ do \ -+ { \ -+ if (specified_ ## comp \ -+ && context_ ## comp ## _set ((C), specified_ ## comp)) \ -+ { \ -+ error (0, errno, \ -+ _("failed to set %s security context component to %s"), \ -+ #comp, quote (specified_ ## comp)); \ -+ ok = false; \ -+ } \ -+ } \ -+ while (0) -+ -+ SET_COMPONENT (new_context, user); -+ SET_COMPONENT (new_context, range); -+ SET_COMPONENT (new_context, role); -+ SET_COMPONENT (new_context, type); -+ -+ if (!ok) -+ { -+ int saved_errno = errno; -+ context_free (new_context); -+ errno = saved_errno; -+ return 1; -+ } -+ -+ *ret = new_context; -+ return 0; -+} -+ -+/* Change the context of FILE, using specified components. -+ If it is a directory and -R is given, recurse. -+ Return 0 if successful, 1 if errors occurred. */ -+ -+static int -+change_file_context (int fd, char const *file) -+{ -+ security_context_t file_context = NULL; -+ context_t context; -+ security_context_t context_string; -+ int errors = 0; -+ -+ if (specified_context == NULL) -+ { -+ int status = (affect_symlink_referent -+ ? getfileconat (fd, file, &file_context) -+ : lgetfileconat (fd, file, &file_context)); -+ -+ if (status < 0 && errno != ENODATA) -+ { -+ error (0, errno, _("failed to get security context of %s"), -+ quote (file)); -+ return 1; -+ } -+ -+ /* If the file doesn't have a context, and we're not setting all of -+ the context components, there isn't really an obvious default. -+ Thus, we just give up. */ -+ if (file_context == NULL) -+ { -+ error (0, 0, _("can't apply partial context to unlabeled file %s"), -+ quote (file)); -+ return 1; -+ } -+ -+ if (compute_context_from_mask (file_context, &context)) -+ return 1; -+ } -+ else -+ { -+ /* FIXME: this should be done exactly once, in main. */ -+ context = context_new (specified_context); -+ if (!context) -+ abort (); -+ } -+ -+ context_string = context_str (context); -+ -+ if (file_context == NULL || ! STREQ (context_string, file_context)) -+ { -+ int fail = (affect_symlink_referent -+ ? setfileconat (fd, file, context_string) -+ : lsetfileconat (fd, file, context_string)); -+ -+ if (fail) -+ { -+ errors = 1; -+ error (0, errno, _("failed to change context of %s to %s"), -+ quote_n (0, file), quote_n (1, context_string)); -+ } -+ } -+ -+ context_free (context); -+ freecon (file_context); -+ -+ return errors; -+} -+ -+/* Change the context of FILE. -+ Return true if successful. This function is called -+ once for every file system object that fts encounters. */ -+ -+static bool -+process_file (FTS *fts, FTSENT *ent) -+{ -+ char const *file_full_name = ent->fts_path; -+ char const *file = ent->fts_accpath; -+ const struct stat *file_stats = ent->fts_statp; -+ bool ok = true; -+ -+ switch (ent->fts_info) -+ { -+ case FTS_D: -+ if (recurse) -+ { -+ if (ROOT_DEV_INO_CHECK (root_dev_ino, ent->fts_statp)) -+ { -+ /* This happens e.g., with "chcon -R --preserve-root ... /" -+ and with "chcon -RH --preserve-root ... symlink-to-root". */ -+ ROOT_DEV_INO_WARN (file_full_name); -+ /* Tell fts not to traverse into this hierarchy. */ -+ fts_set (fts, ent, FTS_SKIP); -+ /* Ensure that we do not process "/" on the second visit. */ -+ ignore_ptr (fts_read (fts)); -+ return false; -+ } -+ return true; -+ } -+ break; -+ -+ case FTS_DP: -+ if (! recurse) -+ return true; -+ break; -+ -+ case FTS_NS: -+ /* For a top-level file or directory, this FTS_NS (stat failed) -+ indicator is determined at the time of the initial fts_open call. -+ With programs like chmod, chown, and chgrp, that modify -+ permissions, it is possible that the file in question is -+ accessible when control reaches this point. So, if this is -+ the first time we've seen the FTS_NS for this file, tell -+ fts_read to stat it "again". */ -+ if (ent->fts_level == 0 && ent->fts_number == 0) -+ { -+ ent->fts_number = 1; -+ fts_set (fts, ent, FTS_AGAIN); -+ return true; -+ } -+ error (0, ent->fts_errno, _("cannot access %s"), quote (file_full_name)); -+ ok = false; -+ break; -+ -+ case FTS_ERR: -+ error (0, ent->fts_errno, _("%s"), quote (file_full_name)); -+ ok = false; -+ break; -+ -+ case FTS_DNR: -+ error (0, ent->fts_errno, _("cannot read directory %s"), -+ quote (file_full_name)); -+ ok = false; -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (ent->fts_info == FTS_DP -+ && ok && ROOT_DEV_INO_CHECK (root_dev_ino, file_stats)) -+ { -+ ROOT_DEV_INO_WARN (file_full_name); -+ ok = false; -+ } -+ -+ if (ok) -+ { -+ if (verbose) -+ printf (_("changing security context of %s\n"), -+ quote (file_full_name)); -+ -+ if (change_file_context (fts->fts_cwd_fd, file) != 0) -+ ok = false; -+ } -+ -+ if ( ! recurse) -+ fts_set (fts, ent, FTS_SKIP); -+ -+ return ok; -+} -+ -+/* Recursively operate on the specified FILES (the last entry -+ of which is NULL). BIT_FLAGS controls how fts works. -+ Return true if successful. */ -+ -+static bool -+process_files (char **files, int bit_flags) -+{ -+ bool ok = true; -+ -+ FTS *fts = xfts_open (files, bit_flags, NULL); -+ -+ while (1) -+ { -+ FTSENT *ent; -+ -+ ent = fts_read (fts); -+ if (ent == NULL) -+ { -+ if (errno != 0) -+ { -+ /* FIXME: try to give a better message */ -+ error (0, errno, _("fts_read failed")); -+ ok = false; -+ } -+ break; -+ } -+ -+ ok &= process_file (fts, ent); -+ } -+ -+ if (fts_close (fts) != 0) -+ { -+ error (0, errno, _("fts_close failed")); -+ ok = false; -+ } -+ -+ return ok; -+} -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... CONTEXT FILE...\n\ -+ or: %s [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...\n\ -+ or: %s [OPTION]... --reference=RFILE FILE...\n\ -+"), -+ program_name, program_name, program_name); -+ fputs (_("\ -+Change the security context of each FILE to CONTEXT.\n\ -+With --reference, change the security context of each FILE to that of RFILE.\n\ -+\n\ -+ -h, --no-dereference affect symbolic links instead of any referenced file\n\ -+"), stdout); -+ fputs (_("\ -+ --reference=RFILE use RFILE's security context rather than specifying\n\ -+ a CONTEXT value\n\ -+ -R, --recursive operate on files and directories recursively\n\ -+ -v, --verbose output a diagnostic for every file processed\n\ -+"), stdout); -+ fputs (_("\ -+ -u, --user=USER set user USER in the target security context\n\ -+ -r, --role=ROLE set role ROLE in the target security context\n\ -+ -t, --type=TYPE set type TYPE in the target security context\n\ -+ -l, --range=RANGE set range RANGE in the target security context\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+The following options modify how a hierarchy is traversed when the -R\n\ -+option is also specified. If more than one is specified, only the final\n\ -+one takes effect.\n\ -+\n\ -+ -H if a command line argument is a symbolic link\n\ -+ to a directory, traverse it\n\ -+ -L traverse every symbolic link to a directory\n\ -+ encountered\n\ -+ -P do not traverse any symbolic links (default)\n\ -+\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+int -+main (int argc, char **argv) -+{ -+ security_context_t ref_context = NULL; -+ -+ /* Bit flags that control how fts works. */ -+ int bit_flags = FTS_PHYSICAL; -+ -+ /* 1 if --dereference, 0 if --no-dereference, -1 if neither has been -+ specified. */ -+ int dereference = -1; -+ -+ bool ok; -+ bool preserve_root = false; -+ bool component_specified = false; -+ char *reference_file = NULL; -+ int optc; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdout); -+ -+ while ((optc = getopt_long (argc, argv, "HLPRhvu:r:t:l:", long_options, NULL)) -+ != -1) -+ { -+ switch (optc) -+ { -+ case 'H': /* Traverse command-line symlinks-to-directories. */ -+ bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL; -+ break; -+ -+ case 'L': /* Traverse all symlinks-to-directories. */ -+ bit_flags = FTS_LOGICAL; -+ break; -+ -+ case 'P': /* Traverse no symlinks-to-directories. */ -+ bit_flags = FTS_PHYSICAL; -+ break; -+ -+ case 'h': /* --no-dereference: affect symlinks */ -+ dereference = 0; -+ break; -+ -+ case DEREFERENCE_OPTION: /* --dereference: affect the referent -+ of each symlink */ -+ dereference = 1; -+ break; -+ -+ case NO_PRESERVE_ROOT: -+ preserve_root = false; -+ break; -+ -+ case PRESERVE_ROOT: -+ preserve_root = true; -+ break; -+ -+ case REFERENCE_FILE_OPTION: -+ reference_file = optarg; -+ break; -+ -+ case 'R': -+ recurse = true; -+ break; -+ -+ case 'f': -+ /* ignore */ -+ break; -+ -+ case 'v': -+ verbose = true; -+ break; -+ -+ case 'u': -+ specified_user = optarg; -+ component_specified = true; -+ break; -+ -+ case 'r': -+ specified_role = optarg; -+ component_specified = true; -+ break; -+ -+ case 't': -+ specified_type = optarg; -+ component_specified = true; -+ break; -+ -+ case 'l': -+ specified_range = optarg; -+ component_specified = true; -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (recurse) -+ { -+ if (bit_flags == FTS_PHYSICAL) -+ { -+ if (dereference == 1) -+ error (EXIT_FAILURE, 0, -+ _("-R --dereference requires either -H or -L")); -+ affect_symlink_referent = false; -+ } -+ else -+ { -+ if (dereference == 0) -+ error (EXIT_FAILURE, 0, _("-R -h requires -P")); -+ affect_symlink_referent = true; -+ } -+ } -+ else -+ { -+ bit_flags = FTS_PHYSICAL; -+ affect_symlink_referent = (dereference != 0); -+ } -+ -+ if (argc - optind < (reference_file || component_specified ? 1 : 2)) -+ { -+ if (argc <= optind) -+ error (0, 0, _("missing operand")); -+ else -+ error (0, 0, _("missing operand after %s"), quote (argv[argc - 1])); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (is_selinux_enabled () != 1) -+ error (EXIT_FAILURE, 0, -+ _("%s may be used only on a SELinux kernel"), program_name); -+ -+ if (reference_file) -+ { -+ if (getfilecon (reference_file, &ref_context) < 0) -+ error (EXIT_FAILURE, errno, _("failed to get security context of %s"), -+ quote (reference_file)); -+ -+ specified_context = ref_context; -+ } -+ else if (component_specified) -+ { -+ /* FIXME: it's already null, so this is a no-op. */ -+ specified_context = NULL; -+ } -+ else -+ { -+ context_t context; -+ specified_context = argv[optind++]; -+ context = context_new (specified_context); -+ if (!context) -+ error (EXIT_FAILURE, 0, _("invalid context: %s"), -+ quotearg_colon (specified_context)); -+ context_free (context); -+ } -+ -+ if (reference_file && component_specified) -+ { -+ error (0, 0, _("conflicting security context specifiers given")); -+ usage (1); -+ } -+ -+ if (recurse && preserve_root) -+ { -+ static struct dev_ino dev_ino_buf; -+ root_dev_ino = get_root_dev_ino (&dev_ino_buf); -+ if (root_dev_ino == NULL) -+ error (EXIT_FAILURE, errno, _("failed to get attributes of %s"), -+ quote ("/")); -+ } -+ else -+ { -+ root_dev_ino = NULL; -+ } -+ -+ ok = process_files (argv + optind, bit_flags | FTS_NOSTAT); -+ -+ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); -+} diff -urNp coreutils-8.0-orig/src/id.c coreutils-8.0/src/id.c --- coreutils-8.0-orig/src/id.c 2009-09-29 15:27:54.000000000 +0200 +++ coreutils-8.0/src/id.c 2009-10-07 10:10:11.000000000 +0200 @@ -4660,1021 +232,6 @@ diff -urNp coreutils-8.0-orig/src/install.c coreutils-8.0/src/install.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); -diff -urNp coreutils-8.0-orig/src/install.c.orig coreutils-8.0/src/install.c.orig ---- coreutils-8.0-orig/src/install.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/install.c.orig 2009-09-29 15:27:54.000000000 +0200 -@@ -0,0 +1,1011 @@ -+/* install - copy files and set attributes -+ Copyright (C) 89, 90, 91, 1995-2009 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 David MacKenzie */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "system.h" -+#include "backupfile.h" -+#include "error.h" -+#include "cp-hash.h" -+#include "copy.h" -+#include "filenamecat.h" -+#include "full-read.h" -+#include "mkancesdirs.h" -+#include "mkdir-p.h" -+#include "modechange.h" -+#include "prog-fprintf.h" -+#include "quote.h" -+#include "quotearg.h" -+#include "savewd.h" -+#include "stat-time.h" -+#include "utimens.h" -+#include "xstrtol.h" -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "install" -+ -+#define AUTHORS proper_name ("David MacKenzie") -+ -+#if HAVE_SYS_WAIT_H -+# include -+#endif -+ -+static int selinux_enabled = 0; -+static bool use_default_selinux_context = true; -+ -+#if ! HAVE_ENDGRENT -+# define endgrent() ((void) 0) -+#endif -+ -+#if ! HAVE_ENDPWENT -+# define endpwent() ((void) 0) -+#endif -+ -+#if ! HAVE_LCHOWN -+# define lchown(name, uid, gid) chown (name, uid, gid) -+#endif -+ -+#if ! HAVE_MATCHPATHCON_INIT_PREFIX -+# define matchpathcon_init_prefix(a, p) /* empty */ -+#endif -+ -+static bool change_timestamps (struct stat const *from_sb, char const *to); -+static bool change_attributes (char const *name); -+static bool copy_file (const char *from, const char *to, -+ const struct cp_options *x); -+static bool install_file_in_file_parents (char const *from, char *to, -+ struct cp_options *x); -+static bool install_file_in_dir (const char *from, const char *to_dir, -+ const struct cp_options *x); -+static bool install_file_in_file (const char *from, const char *to, -+ const struct cp_options *x); -+static void get_ids (void); -+static void strip (char const *name); -+static void announce_mkdir (char const *dir, void *options); -+static int make_ancestor (char const *dir, char const *component, -+ void *options); -+void usage (int status); -+ -+/* The user name that will own the files, or NULL to make the owner -+ the current user ID. */ -+static char *owner_name; -+ -+/* The user ID corresponding to `owner_name'. */ -+static uid_t owner_id; -+ -+/* The group name that will own the files, or NULL to make the group -+ the current group ID. */ -+static char *group_name; -+ -+/* The group ID corresponding to `group_name'. */ -+static gid_t group_id; -+ -+#define DEFAULT_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) -+ -+/* The file mode bits to which non-directory files will be set. The umask has -+ no effect. */ -+static mode_t mode = DEFAULT_MODE; -+ -+/* Similar, but for directories. */ -+static mode_t dir_mode = DEFAULT_MODE; -+ -+/* The file mode bits that the user cares about. This should be a -+ superset of DIR_MODE and a subset of CHMOD_MODE_BITS. This matters -+ for directories, since otherwise directories may keep their S_ISUID -+ or S_ISGID bits. */ -+static mode_t dir_mode_bits = CHMOD_MODE_BITS; -+ -+/* Compare files before installing (-C) */ -+static bool copy_only_if_needed; -+ -+/* If true, strip executable files after copying them. */ -+static bool strip_files; -+ -+/* If true, install a directory instead of a regular file. */ -+static bool dir_arg; -+ -+/* Program used to strip binaries, "strip" is default */ -+static char const *strip_program = "strip"; -+ -+/* For long options that have no equivalent short option, use a -+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -+enum -+{ -+ PRESERVE_CONTEXT_OPTION = CHAR_MAX + 1, -+ PRESERVE_CONTEXT_OPTION_DEPRECATED, -+ STRIP_PROGRAM_OPTION -+}; -+ -+static struct option const long_options[] = -+{ -+ {"backup", optional_argument, NULL, 'b'}, -+ {"compare", no_argument, NULL, 'C'}, -+ {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, -+ {"directory", no_argument, NULL, 'd'}, -+ {"group", required_argument, NULL, 'g'}, -+ {"mode", required_argument, NULL, 'm'}, -+ {"no-target-directory", no_argument, NULL, 'T'}, -+ {"owner", required_argument, NULL, 'o'}, -+ {"preserve-timestamps", no_argument, NULL, 'p'}, -+ {"preserve-context", no_argument, NULL, PRESERVE_CONTEXT_OPTION}, -+ /* --preserve_context was silently supported until Apr 2009. -+ FIXME: disable altogether in a year or so. */ -+ {"preserve_context", no_argument, NULL, PRESERVE_CONTEXT_OPTION_DEPRECATED}, -+ {"strip", no_argument, NULL, 's'}, -+ {"strip-program", required_argument, NULL, STRIP_PROGRAM_OPTION}, -+ {"suffix", required_argument, NULL, 'S'}, -+ {"target-directory", required_argument, NULL, 't'}, -+ {"verbose", no_argument, NULL, 'v'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+/* Compare content of opened files using file descriptors A_FD and B_FD. Return -+ true if files are equal. */ -+static bool -+have_same_content (int a_fd, int b_fd) -+{ -+ enum { CMP_BLOCK_SIZE = 4096 }; -+ static char a_buff[CMP_BLOCK_SIZE]; -+ static char b_buff[CMP_BLOCK_SIZE]; -+ -+ size_t size; -+ while (0 < (size = full_read (a_fd, a_buff, sizeof a_buff))) { -+ if (size != full_read (b_fd, b_buff, sizeof b_buff)) -+ return false; -+ -+ if (memcmp (a_buff, b_buff, size) != 0) -+ return false; -+ } -+ -+ return size == 0; -+} -+ -+/* Return true for mode with non-permission bits. */ -+static bool -+extra_mode (mode_t input) -+{ -+ const mode_t mask = ~S_IRWXUGO & ~S_IFMT; -+ return !! (input & mask); -+} -+ -+/* Return true if copy of file SRC_NAME to file DEST_NAME is necessary. */ -+static bool -+need_copy (const char *src_name, const char *dest_name, -+ const struct cp_options *x) -+{ -+ struct stat src_sb, dest_sb; -+ int src_fd, dest_fd; -+ bool content_match; -+ -+ if (extra_mode (mode)) -+ return true; -+ -+ /* compare files using stat */ -+ if (lstat (src_name, &src_sb) != 0) -+ return true; -+ -+ if (lstat (dest_name, &dest_sb) != 0) -+ return true; -+ -+ if (!S_ISREG (src_sb.st_mode) || !S_ISREG (dest_sb.st_mode) -+ || extra_mode (src_sb.st_mode) || extra_mode (dest_sb.st_mode)) -+ return true; -+ -+ if (src_sb.st_size != dest_sb.st_size -+ || (dest_sb.st_mode & CHMOD_MODE_BITS) != mode -+ || dest_sb.st_uid != (owner_id == (uid_t) -1 ? getuid () : owner_id) -+ || dest_sb.st_gid != (group_id == (gid_t) -1 ? getgid () : group_id)) -+ return true; -+ -+ /* compare SELinux context if preserving */ -+ if (selinux_enabled && x->preserve_security_context) -+ { -+ security_context_t file_scontext = NULL; -+ security_context_t to_scontext = NULL; -+ bool scontext_match; -+ -+ if (getfilecon (src_name, &file_scontext) == -1) -+ return true; -+ -+ if (getfilecon (dest_name, &to_scontext) == -1) -+ { -+ freecon (file_scontext); -+ return true; -+ } -+ -+ scontext_match = STREQ (file_scontext, to_scontext); -+ -+ freecon (file_scontext); -+ freecon (to_scontext); -+ if (!scontext_match) -+ return true; -+ } -+ -+ /* compare files content */ -+ src_fd = open (src_name, O_RDONLY | O_BINARY); -+ if (src_fd < 0) -+ return true; -+ -+ dest_fd = open (dest_name, O_RDONLY | O_BINARY); -+ if (dest_fd < 0) -+ { -+ close (src_fd); -+ return true; -+ } -+ -+ content_match = have_same_content (src_fd, dest_fd); -+ -+ close (src_fd); -+ close (dest_fd); -+ return !content_match; -+} -+ -+static void -+cp_option_init (struct cp_options *x) -+{ -+ cp_options_default (x); -+ x->copy_as_regular = true; -+ x->reflink_mode = REFLINK_NEVER; -+ x->dereference = DEREF_ALWAYS; -+ x->unlink_dest_before_opening = true; -+ x->unlink_dest_after_failed_open = false; -+ x->hard_link = false; -+ x->interactive = I_UNSPECIFIED; -+ x->move_mode = false; -+ x->one_file_system = false; -+ x->preserve_ownership = false; -+ x->preserve_links = false; -+ x->preserve_mode = false; -+ x->preserve_timestamps = false; -+ x->reduce_diagnostics=false; -+ x->require_preserve = false; -+ x->require_preserve_context = false; -+ x->require_preserve_xattr = false; -+ x->recursive = false; -+ x->sparse_mode = SPARSE_AUTO; -+ x->symbolic_link = false; -+ x->backup_type = no_backups; -+ -+ /* Create destination files initially writable so we can run strip on them. -+ Although GNU strip works fine on read-only files, some others -+ would fail. */ -+ x->set_mode = true; -+ x->mode = S_IRUSR | S_IWUSR; -+ x->stdin_tty = false; -+ -+ x->open_dangling_dest_symlink = false; -+ x->update = false; -+ x->preserve_security_context = false; -+ x->preserve_xattr = false; -+ x->verbose = false; -+ x->dest_info = NULL; -+ x->src_info = NULL; -+} -+ -+#ifdef ENABLE_MATCHPATHCON -+/* Modify file context to match the specified policy. -+ If an error occurs the file will remain with the default directory -+ context. */ -+static void -+setdefaultfilecon (char const *file) -+{ -+ struct stat st; -+ security_context_t scontext = NULL; -+ static bool first_call = true; -+ -+ if (selinux_enabled != 1) -+ { -+ /* Indicate no context found. */ -+ return; -+ } -+ if (lstat (file, &st) != 0) -+ return; -+ -+ if (first_call && IS_ABSOLUTE_FILE_NAME (file)) -+ { -+ /* Calling matchpathcon_init_prefix (NULL, "/first_component/") -+ is an optimization to minimize the expense of the following -+ matchpathcon call. Do it only once, just before the first -+ matchpathcon call. We *could* call matchpathcon_fini after -+ the final matchpathcon call, but that's not necessary, since -+ by then we're about to exit, and besides, the buffers it -+ would free are still reachable. */ -+ char const *p0; -+ char const *p = file + 1; -+ while (ISSLASH (*p)) -+ ++p; -+ -+ /* Record final leading slash, for when FILE starts with two or more. */ -+ p0 = p - 1; -+ -+ if (*p) -+ { -+ char *prefix; -+ do -+ { -+ ++p; -+ } -+ while (*p && !ISSLASH (*p)); -+ -+ prefix = malloc (p - p0 + 2); -+ if (prefix) -+ { -+ stpcpy (stpncpy (prefix, p0, p - p0), "/"); -+ matchpathcon_init_prefix (NULL, prefix); -+ free (prefix); -+ } -+ } -+ } -+ first_call = false; -+ -+ /* If there's an error determining the context, or it has none, -+ return to allow default context */ -+ if ((matchpathcon (file, st.st_mode, &scontext) != 0) || -+ STREQ (scontext, "<>")) -+ { -+ if (scontext != NULL) -+ freecon (scontext); -+ return; -+ } -+ -+ if (lsetfilecon (file, scontext) < 0 && errno != ENOTSUP) -+ error (0, errno, -+ _("warning: %s: failed to change context to %s"), -+ quotearg_colon (file), scontext); -+ -+ freecon (scontext); -+ return; -+} -+#else -+static void -+setdefaultfilecon (char const *file) -+{ -+ (void) file; -+} -+#endif -+ -+/* FILE is the last operand of this command. Return true if FILE is a -+ directory. But report an error there is a problem accessing FILE, -+ or if FILE does not exist but would have to refer to an existing -+ directory if it referred to anything at all. */ -+ -+static bool -+target_directory_operand (char const *file) -+{ -+ char const *b = last_component (file); -+ size_t blen = strlen (b); -+ bool looks_like_a_dir = (blen == 0 || ISSLASH (b[blen - 1])); -+ struct stat st; -+ int err = (stat (file, &st) == 0 ? 0 : errno); -+ bool is_a_dir = !err && S_ISDIR (st.st_mode); -+ if (err && err != ENOENT) -+ error (EXIT_FAILURE, err, _("accessing %s"), quote (file)); -+ if (is_a_dir < looks_like_a_dir) -+ error (EXIT_FAILURE, err, _("target %s is not a directory"), quote (file)); -+ return is_a_dir; -+} -+ -+/* Process a command-line file name, for the -d option. */ -+static int -+process_dir (char *dir, struct savewd *wd, void *options) -+{ -+ return (make_dir_parents (dir, wd, -+ make_ancestor, options, -+ dir_mode, announce_mkdir, -+ dir_mode_bits, owner_id, group_id, false) -+ ? EXIT_SUCCESS -+ : EXIT_FAILURE); -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int optc; -+ int exit_status = EXIT_SUCCESS; -+ const char *specified_mode = NULL; -+ bool make_backups = false; -+ char *backup_suffix_string; -+ char *version_control_string = NULL; -+ bool mkdir_and_install = false; -+ struct cp_options x; -+ char const *target_directory = NULL; -+ bool no_target_directory = false; -+ int n_files; -+ char **file; -+ bool strip_program_specified = false; -+ security_context_t scontext = NULL; -+ /* set iff kernel has extra selinux system calls */ -+ selinux_enabled = (0 < is_selinux_enabled ()); -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdin); -+ -+ cp_option_init (&x); -+ -+ owner_name = NULL; -+ group_name = NULL; -+ strip_files = false; -+ dir_arg = false; -+ umask (0); -+ -+ /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless -+ we'll actually use backup_suffix_string. */ -+ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); -+ -+ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options, -+ NULL)) != -1) -+ { -+ switch (optc) -+ { -+ case 'b': -+ make_backups = true; -+ if (optarg) -+ version_control_string = optarg; -+ break; -+ case 'c': -+ break; -+ case 'C': -+ copy_only_if_needed = true; -+ break; -+ case 's': -+ strip_files = true; -+#ifdef SIGCHLD -+ /* System V fork+wait does not work if SIGCHLD is ignored. */ -+ signal (SIGCHLD, SIG_DFL); -+#endif -+ break; -+ case STRIP_PROGRAM_OPTION: -+ strip_program = xstrdup (optarg); -+ strip_program_specified = true; -+ break; -+ case 'd': -+ dir_arg = true; -+ break; -+ case 'D': -+ mkdir_and_install = true; -+ break; -+ case 'v': -+ x.verbose = true; -+ break; -+ case 'g': -+ group_name = optarg; -+ break; -+ case 'm': -+ specified_mode = optarg; -+ break; -+ case 'o': -+ owner_name = optarg; -+ break; -+ case 'p': -+ x.preserve_timestamps = true; -+ break; -+ case 'S': -+ make_backups = true; -+ backup_suffix_string = optarg; -+ break; -+ case 't': -+ if (target_directory) -+ error (EXIT_FAILURE, 0, -+ _("multiple target directories specified")); -+ else -+ { -+ struct stat st; -+ if (stat (optarg, &st) != 0) -+ error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg)); -+ if (! S_ISDIR (st.st_mode)) -+ error (EXIT_FAILURE, 0, _("target %s is not a directory"), -+ quote (optarg)); -+ } -+ target_directory = optarg; -+ break; -+ case 'T': -+ no_target_directory = true; -+ break; -+ -+ case PRESERVE_CONTEXT_OPTION_DEPRECATED: -+ error (0, 0, _("WARNING: --preserve_context is deprecated; " -+ "use --preserve-context instead")); -+ /* fall through */ -+ case PRESERVE_CONTEXT_OPTION: -+ if ( ! selinux_enabled) -+ { -+ error (0, 0, _("WARNING: ignoring --preserve-context; " -+ "this kernel is not SELinux-enabled")); -+ break; -+ } -+ x.preserve_security_context = true; -+ use_default_selinux_context = false; -+ break; -+ case 'Z': -+ if ( ! selinux_enabled) -+ { -+ error (0, 0, _("WARNING: ignoring --context (-Z); " -+ "this kernel is not SELinux-enabled")); -+ break; -+ } -+ scontext = optarg; -+ use_default_selinux_context = false; -+ break; -+ case_GETOPT_HELP_CHAR; -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ /* Check for invalid combinations of arguments. */ -+ if (dir_arg && strip_files) -+ error (EXIT_FAILURE, 0, -+ _("the strip option may not be used when installing a directory")); -+ if (dir_arg && target_directory) -+ error (EXIT_FAILURE, 0, -+ _("target directory not allowed when installing a directory")); -+ -+ if (x.preserve_security_context && scontext != NULL) -+ error (EXIT_FAILURE, 0, -+ _("cannot force target context to %s and preserve it"), -+ quote (scontext)); -+ -+ if (backup_suffix_string) -+ simple_backup_suffix = xstrdup (backup_suffix_string); -+ -+ x.backup_type = (make_backups -+ ? xget_version (_("backup type"), -+ version_control_string) -+ : no_backups); -+ -+ if (scontext && setfscreatecon (scontext) < 0) -+ error (EXIT_FAILURE, errno, -+ _("failed to set default file creation context to %s"), -+ quote (scontext)); -+ -+ n_files = argc - optind; -+ file = argv + optind; -+ -+ if (n_files <= ! (dir_arg || target_directory)) -+ { -+ if (n_files <= 0) -+ error (0, 0, _("missing file operand")); -+ else -+ error (0, 0, _("missing destination file operand after %s"), -+ quote (file[0])); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (no_target_directory) -+ { -+ if (target_directory) -+ error (EXIT_FAILURE, 0, -+ _("cannot combine --target-directory (-t) " -+ "and --no-target-directory (-T)")); -+ if (2 < n_files) -+ { -+ error (0, 0, _("extra operand %s"), quote (file[2])); -+ usage (EXIT_FAILURE); -+ } -+ } -+ else if (! (dir_arg || target_directory)) -+ { -+ if (2 <= n_files && target_directory_operand (file[n_files - 1])) -+ target_directory = file[--n_files]; -+ else if (2 < n_files) -+ error (EXIT_FAILURE, 0, _("target %s is not a directory"), -+ quote (file[n_files - 1])); -+ } -+ -+ if (specified_mode) -+ { -+ struct mode_change *change = mode_compile (specified_mode); -+ if (!change) -+ error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode)); -+ mode = mode_adjust (0, false, 0, change, NULL); -+ dir_mode = mode_adjust (0, true, 0, change, &dir_mode_bits); -+ free (change); -+ } -+ -+ if (strip_program_specified && !strip_files) -+ error (0, 0, _("WARNING: ignoring --strip-program option as -s option was " -+ "not specified")); -+ -+ if (copy_only_if_needed && x.preserve_timestamps) -+ { -+ error (0, 0, _("options --compare (-C) and --preserve-timestamps are " -+ "mutually exclusive")); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (copy_only_if_needed && strip_files) -+ { -+ error (0, 0, _("options --compare (-C) and --strip are mutually " -+ "exclusive")); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (copy_only_if_needed && extra_mode (mode)) -+ error (0, 0, _("the --compare (-C) option is ignored when you" -+ " specify a mode with non-permission bits")); -+ -+ get_ids (); -+ -+ if (dir_arg) -+ exit_status = savewd_process_files (n_files, file, process_dir, &x); -+ else -+ { -+ /* FIXME: it's a little gross that this initialization is -+ required by copy.c::copy. */ -+ hash_init (); -+ -+ if (!target_directory) -+ { -+ if (! (mkdir_and_install -+ ? install_file_in_file_parents (file[0], file[1], &x) -+ : install_file_in_file (file[0], file[1], &x))) -+ exit_status = EXIT_FAILURE; -+ } -+ else -+ { -+ int i; -+ dest_info_init (&x); -+ for (i = 0; i < n_files; i++) -+ if (! install_file_in_dir (file[i], target_directory, &x)) -+ exit_status = EXIT_FAILURE; -+ } -+ } -+ -+ exit (exit_status); -+} -+ -+/* Copy file FROM onto file TO, creating any missing parent directories of TO. -+ Return true if successful. */ -+ -+static bool -+install_file_in_file_parents (char const *from, char *to, -+ struct cp_options *x) -+{ -+ bool save_working_directory = -+ ! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to)); -+ int status = EXIT_SUCCESS; -+ -+ struct savewd wd; -+ savewd_init (&wd); -+ if (! save_working_directory) -+ savewd_finish (&wd); -+ -+ if (mkancesdirs (to, &wd, make_ancestor, x) == -1) -+ { -+ error (0, errno, _("cannot create directory %s"), to); -+ status = EXIT_FAILURE; -+ } -+ -+ if (save_working_directory) -+ { -+ int restore_result = savewd_restore (&wd, status); -+ int restore_errno = errno; -+ savewd_finish (&wd); -+ if (EXIT_SUCCESS < restore_result) -+ return false; -+ if (restore_result < 0 && status == EXIT_SUCCESS) -+ { -+ error (0, restore_errno, _("cannot create directory %s"), to); -+ return false; -+ } -+ } -+ -+ return (status == EXIT_SUCCESS && install_file_in_file (from, to, x)); -+} -+ -+/* Copy file FROM onto file TO and give TO the appropriate -+ attributes. -+ Return true if successful. */ -+ -+static bool -+install_file_in_file (const char *from, const char *to, -+ const struct cp_options *x) -+{ -+ struct stat from_sb; -+ if (x->preserve_timestamps && stat (from, &from_sb) != 0) -+ { -+ error (0, errno, _("cannot stat %s"), quote (from)); -+ return false; -+ } -+ if (! copy_file (from, to, x)) -+ return false; -+ if (strip_files) -+ strip (to); -+ if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode)) -+ && ! change_timestamps (&from_sb, to)) -+ return false; -+ return change_attributes (to); -+} -+ -+/* Copy file FROM into directory TO_DIR, keeping its same name, -+ and give the copy the appropriate attributes. -+ Return true if successful. */ -+ -+static bool -+install_file_in_dir (const char *from, const char *to_dir, -+ const struct cp_options *x) -+{ -+ const char *from_base = last_component (from); -+ char *to = file_name_concat (to_dir, from_base, NULL); -+ bool ret = install_file_in_file (from, to, x); -+ free (to); -+ return ret; -+} -+ -+/* Copy file FROM onto file TO, creating TO if necessary. -+ Return true if successful. */ -+ -+static bool -+copy_file (const char *from, const char *to, const struct cp_options *x) -+{ -+ bool copy_into_self; -+ -+ if (copy_only_if_needed && !need_copy (from, to, x)) -+ return true; -+ -+ /* Allow installing from non-regular files like /dev/null. -+ Charles Karney reported that some Sun version of install allows that -+ and that sendmail's installation process relies on the behavior. -+ However, since !x->recursive, the call to "copy" will fail if FROM -+ is a directory. */ -+ -+ return copy (from, to, false, x, ©_into_self, NULL); -+} -+ -+/* Set the attributes of file or directory NAME. -+ Return true if successful. */ -+ -+static bool -+change_attributes (char const *name) -+{ -+ bool ok = false; -+ /* chown must precede chmod because on some systems, -+ chown clears the set[ug]id bits for non-superusers, -+ resulting in incorrect permissions. -+ On System V, users can give away files with chown and then not -+ be able to chmod them. So don't give files away. -+ -+ We don't normally ignore errors from chown because the idea of -+ the install command is that the file is supposed to end up with -+ precisely the attributes that the user specified (or defaulted). -+ If the file doesn't end up with the group they asked for, they'll -+ want to know. */ -+ -+ if (! (owner_id == (uid_t) -1 && group_id == (gid_t) -1) -+ && lchown (name, owner_id, group_id) != 0) -+ error (0, errno, _("cannot change ownership of %s"), quote (name)); -+ else if (chmod (name, mode) != 0) -+ error (0, errno, _("cannot change permissions of %s"), quote (name)); -+ else -+ ok = true; -+ -+ if (use_default_selinux_context) -+ setdefaultfilecon (name); -+ -+ return ok; -+} -+ -+/* Set the timestamps of file TO to match those of file FROM. -+ Return true if successful. */ -+ -+static bool -+change_timestamps (struct stat const *from_sb, char const *to) -+{ -+ struct timespec timespec[2]; -+ timespec[0] = get_stat_atime (from_sb); -+ timespec[1] = get_stat_mtime (from_sb); -+ -+ if (utimens (to, timespec)) -+ { -+ error (0, errno, _("cannot set time stamps for %s"), quote (to)); -+ return false; -+ } -+ return true; -+} -+ -+/* Strip the symbol table from the file NAME. -+ We could dig the magic number out of the file first to -+ determine whether to strip it, but the header files and -+ magic numbers vary so much from system to system that making -+ it portable would be very difficult. Not worth the effort. */ -+ -+static void -+strip (char const *name) -+{ -+ int status; -+ pid_t pid = fork (); -+ -+ switch (pid) -+ { -+ case -1: -+ error (EXIT_FAILURE, errno, _("fork system call failed")); -+ break; -+ case 0: /* Child. */ -+ execlp (strip_program, strip_program, name, NULL); -+ error (EXIT_FAILURE, errno, _("cannot run %s"), strip_program); -+ break; -+ default: /* Parent. */ -+ if (waitpid (pid, &status, 0) < 0) -+ error (EXIT_FAILURE, errno, _("waiting for strip")); -+ else if (! WIFEXITED (status) || WEXITSTATUS (status)) -+ error (EXIT_FAILURE, 0, _("strip process terminated abnormally")); -+ break; -+ } -+} -+ -+/* Initialize the user and group ownership of the files to install. */ -+ -+static void -+get_ids (void) -+{ -+ struct passwd *pw; -+ struct group *gr; -+ -+ if (owner_name) -+ { -+ pw = getpwnam (owner_name); -+ if (pw == NULL) -+ { -+ unsigned long int tmp; -+ if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK -+ || UID_T_MAX < tmp) -+ error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name)); -+ owner_id = tmp; -+ } -+ else -+ owner_id = pw->pw_uid; -+ endpwent (); -+ } -+ else -+ owner_id = (uid_t) -1; -+ -+ if (group_name) -+ { -+ gr = getgrnam (group_name); -+ if (gr == NULL) -+ { -+ unsigned long int tmp; -+ if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK -+ || GID_T_MAX < tmp) -+ error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name)); -+ group_id = tmp; -+ } -+ else -+ group_id = gr->gr_gid; -+ endgrent (); -+ } -+ else -+ group_id = (gid_t) -1; -+} -+ -+/* Report that directory DIR was made, if OPTIONS requests this. */ -+static void -+announce_mkdir (char const *dir, void *options) -+{ -+ struct cp_options const *x = options; -+ if (x->verbose) -+ prog_fprintf (stdout, _("creating directory %s"), quote (dir)); -+} -+ -+/* Make ancestor directory DIR, whose last file name component is -+ COMPONENT, with options OPTIONS. Assume the working directory is -+ COMPONENT's parent. */ -+static int -+make_ancestor (char const *dir, char const *component, void *options) -+{ -+ int r = mkdir (component, DEFAULT_MODE); -+ if (r == 0) -+ announce_mkdir (dir, options); -+ return r; -+} -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... [-T] SOURCE DEST\n\ -+ or: %s [OPTION]... SOURCE... DIRECTORY\n\ -+ or: %s [OPTION]... -t DIRECTORY SOURCE...\n\ -+ or: %s [OPTION]... -d DIRECTORY...\n\ -+"), -+ program_name, program_name, program_name, program_name); -+ fputs (_("\ -+\n\ -+This install program copies files (often just compiled) into destination\n\ -+locations you choose. If you want to download and install a ready-to-use\n\ -+package on a GNU/Linux system, you should instead be using a package manager\n\ -+like yum(1) or apt-get(1).\n\ -+\n\ -+In the first three forms, copy SOURCE to DEST or multiple SOURCE(s) to\n\ -+the existing DIRECTORY, while setting permission modes and owner/group.\n\ -+In the 4th form, create all components of the given DIRECTORY(ies).\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ --backup[=CONTROL] make a backup of each existing destination file\n\ -+ -b like --backup but does not accept an argument\n\ -+ -c (ignored)\n\ -+ -C, --compare compare each pair of source and destination files, and\n\ -+ in some cases, do not modify the destination at all\n\ -+ -d, --directory treat all arguments as directory names; create all\n\ -+ components of the specified directories\n\ -+"), stdout); -+ fputs (_("\ -+ -D create all leading components of DEST except the last,\n\ -+ then copy SOURCE to DEST\n\ -+ -g, --group=GROUP set group ownership, instead of process' current group\n\ -+ -m, --mode=MODE set permission mode (as in chmod), instead of rwxr-xr-x\n\ -+ -o, --owner=OWNER set ownership (super-user only)\n\ -+"), stdout); -+ fputs (_("\ -+ -p, --preserve-timestamps apply access/modification times of SOURCE files\n\ -+ to corresponding destination files\n\ -+ -s, --strip strip symbol tables\n\ -+ --strip-program=PROGRAM program used to strip binaries\n\ -+ -S, --suffix=SUFFIX override the usual backup suffix\n\ -+ -t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY\n\ -+ -T, --no-target-directory treat DEST as a normal file\n\ -+ -v, --verbose print the name of each directory as it is created\n\ -+"), stdout); -+ fputs (_("\ -+ --preserve-context preserve SELinux security context\n\ -+ -Z, --context=CONTEXT set SELinux security context of files and directories\n\ -+"), stdout); -+ -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ fputs (_("\ -+\n\ -+The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\ -+The version control method may be selected via the --backup option or through\n\ -+the VERSION_CONTROL environment variable. Here are the values:\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+ none, off never make backups (even if --backup is given)\n\ -+ numbered, t make numbered backups\n\ -+ existing, nil numbered if numbered backups exist, simple otherwise\n\ -+ simple, never always make simple backups\n\ -+"), stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c --- coreutils-8.0-orig/src/ls.c 2009-10-07 10:09:43.000000000 +0200 +++ coreutils-8.0/src/ls.c 2009-10-07 10:10:11.000000000 +0200 @@ -6042,4710 +599,6 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-8.0-orig/src/ls.c.orig coreutils-8.0/src/ls.c.orig ---- coreutils-8.0-orig/src/ls.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/ls.c.orig 2009-10-07 10:09:43.000000000 +0200 -@@ -0,0 +1,4700 @@ -+/* `dir', `vdir' and `ls' directory listing programs for GNU. -+ Copyright (C) 85, 88, 90, 91, 1995-2009 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 . */ -+ -+/* If ls_mode is LS_MULTI_COL, -+ the multi-column format is the default regardless -+ of the type of output device. -+ This is for the `dir' program. -+ -+ If ls_mode is LS_LONG_FORMAT, -+ the long format is the default regardless of the -+ type of output device. -+ This is for the `vdir' program. -+ -+ If ls_mode is LS_LS, -+ the output format depends on whether the output -+ device is a terminal. -+ This is for the `ls' program. */ -+ -+/* Written by Richard Stallman and David MacKenzie. */ -+ -+/* Color support by Peter Anvin and Dennis -+ Flaherty based on original patches by -+ Greg Lee . */ -+ -+#include -+#include -+ -+#if HAVE_TERMIOS_H -+# include -+#endif -+#if HAVE_STROPTS_H -+# include -+#endif -+#if HAVE_SYS_IOCTL_H -+# include -+#endif -+ -+#ifdef WINSIZE_IN_PTEM -+# include -+# include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if HAVE_LANGINFO_CODESET -+# include -+#endif -+ -+/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is -+ present. */ -+#ifndef SA_NOCLDSTOP -+# define SA_NOCLDSTOP 0 -+# define sigprocmask(How, Set, Oset) /* empty */ -+# define sigset_t int -+# if ! HAVE_SIGINTERRUPT -+# define siginterrupt(sig, flag) /* empty */ -+# endif -+#endif -+#ifndef SA_RESTART -+# define SA_RESTART 0 -+#endif -+ -+#include "system.h" -+#include -+ -+#ifdef HAVE_CAP -+# include -+#endif -+ -+#include "acl.h" -+#include "argmatch.h" -+#include "dev-ino.h" -+#include "error.h" -+#include "filenamecat.h" -+#include "hard-locale.h" -+#include "hash.h" -+#include "human.h" -+#include "filemode.h" -+#include "filevercmp.h" -+#include "idcache.h" -+#include "ls.h" -+#include "mbswidth.h" -+#include "mpsort.h" -+#include "obstack.h" -+#include "quote.h" -+#include "quotearg.h" -+#include "same.h" -+#include "stat-time.h" -+#include "strftime.h" -+#include "xstrtol.h" -+#include "areadlink.h" -+#include "mbsalign.h" -+ -+#define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \ -+ : (ls_mode == LS_MULTI_COL \ -+ ? "dir" : "vdir")) -+ -+#define AUTHORS \ -+ proper_name ("Richard M. Stallman"), \ -+ proper_name ("David MacKenzie") -+ -+#define obstack_chunk_alloc malloc -+#define obstack_chunk_free free -+ -+/* Return an int indicating the result of comparing two integers. -+ Subtracting doesn't always work, due to overflow. */ -+#define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b)) -+ -+/* Unix-based readdir implementations have historically returned a dirent.d_ino -+ value that is sometimes not equal to the stat-obtained st_ino value for -+ that same entry. This error occurs for a readdir entry that refers -+ to a mount point. readdir's error is to return the inode number of -+ the underlying directory -- one that typically cannot be stat'ed, as -+ long as a file system is mounted on that directory. RELIABLE_D_INO -+ encapsulates whether we can use the more efficient approach of relying -+ on readdir-supplied d_ino values, or whether we must incur the cost of -+ calling stat or lstat to obtain each guaranteed-valid inode number. */ -+ -+#ifndef READDIR_LIES_ABOUT_MOUNTPOINT_D_INO -+# define READDIR_LIES_ABOUT_MOUNTPOINT_D_INO 1 -+#endif -+ -+#if READDIR_LIES_ABOUT_MOUNTPOINT_D_INO -+# define RELIABLE_D_INO(dp) NOT_AN_INODE_NUMBER -+#else -+# define RELIABLE_D_INO(dp) D_INO (dp) -+#endif -+ -+#if ! HAVE_STRUCT_STAT_ST_AUTHOR -+# define st_author st_uid -+#endif -+ -+enum filetype -+ { -+ unknown, -+ fifo, -+ chardev, -+ directory, -+ blockdev, -+ normal, -+ symbolic_link, -+ sock, -+ whiteout, -+ arg_directory -+ }; -+ -+/* Display letters and indicators for each filetype. -+ Keep these in sync with enum filetype. */ -+static char const filetype_letter[] = "?pcdb-lswd"; -+ -+/* Ensure that filetype and filetype_letter have the same -+ number of elements. */ -+verify (sizeof filetype_letter - 1 == arg_directory + 1); -+ -+#define FILETYPE_INDICATORS \ -+ { \ -+ C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE, \ -+ C_LINK, C_SOCK, C_FILE, C_DIR \ -+ } -+ -+enum acl_type -+ { -+ ACL_T_NONE, -+ ACL_T_SELINUX_ONLY, -+ ACL_T_YES -+ }; -+ -+struct fileinfo -+ { -+ /* The file name. */ -+ char *name; -+ -+ /* For symbolic link, name of the file linked to, otherwise zero. */ -+ char *linkname; -+ -+ struct stat stat; -+ -+ enum filetype filetype; -+ -+ /* For symbolic link and long listing, st_mode of file linked to, otherwise -+ zero. */ -+ mode_t linkmode; -+ -+ /* SELinux security context. */ -+ security_context_t scontext; -+ -+ bool stat_ok; -+ -+ /* For symbolic link and color printing, true if linked-to file -+ exists, otherwise false. */ -+ bool linkok; -+ -+ /* For long listings, true if the file has an access control list, -+ or an SELinux security context. */ -+ enum acl_type acl_type; -+ }; -+ -+#define LEN_STR_PAIR(s) sizeof (s) - 1, s -+ -+/* Null is a valid character in a color indicator (think about Epson -+ printers, for example) so we have to use a length/buffer string -+ type. */ -+ -+struct bin_str -+ { -+ size_t len; /* Number of bytes */ -+ const char *string; /* Pointer to the same */ -+ }; -+ -+#if ! HAVE_TCGETPGRP -+# define tcgetpgrp(Fd) 0 -+#endif -+ -+static size_t quote_name (FILE *out, const char *name, -+ struct quoting_options const *options, -+ size_t *width); -+static char *make_link_name (char const *name, char const *linkname); -+static int decode_switches (int argc, char **argv); -+static bool file_ignored (char const *name); -+static uintmax_t gobble_file (char const *name, enum filetype type, -+ ino_t inode, bool command_line_arg, -+ char const *dirname); -+static bool print_color_indicator (const char *name, mode_t mode, int linkok, -+ bool stat_ok, enum filetype type, -+ nlink_t nlink); -+static void put_indicator (const struct bin_str *ind); -+static void add_ignore_pattern (const char *pattern); -+static void attach (char *dest, const char *dirname, const char *name); -+static void clear_files (void); -+static void extract_dirs_from_files (char const *dirname, -+ bool command_line_arg); -+static void get_link_name (char const *filename, struct fileinfo *f, -+ bool command_line_arg); -+static void indent (size_t from, size_t to); -+static size_t calculate_columns (bool by_columns); -+static void print_current_files (void); -+static void print_dir (char const *name, char const *realname, -+ bool command_line_arg); -+static size_t print_file_name_and_frills (const struct fileinfo *f, -+ size_t start_col); -+static void print_horizontal (void); -+static int format_user_width (uid_t u); -+static int format_group_width (gid_t g); -+static void print_long_format (const struct fileinfo *f); -+static void print_many_per_line (void); -+static size_t print_name_with_quoting (const char *p, mode_t mode, -+ int linkok, bool stat_ok, -+ enum filetype type, -+ struct obstack *stack, -+ nlink_t nlink, -+ size_t start_col); -+static void prep_non_filename_text (void); -+static bool print_type_indicator (bool stat_ok, mode_t mode, -+ enum filetype type); -+static void print_with_commas (void); -+static void queue_directory (char const *name, char const *realname, -+ bool command_line_arg); -+static void sort_files (void); -+static void parse_ls_color (void); -+void usage (int status); -+ -+/* Initial size of hash table. -+ Most hierarchies are likely to be shallower than this. */ -+#define INITIAL_TABLE_SIZE 30 -+ -+/* The set of `active' directories, from the current command-line argument -+ to the level in the hierarchy at which files are being listed. -+ A directory is represented by its device and inode numbers (struct dev_ino). -+ A directory is added to this set when ls begins listing it or its -+ entries, and it is removed from the set just after ls has finished -+ processing it. This set is used solely to detect loops, e.g., with -+ mkdir loop; cd loop; ln -s ../loop sub; ls -RL */ -+static Hash_table *active_dir_set; -+ -+#define LOOP_DETECT (!!active_dir_set) -+ -+/* The table of files in the current directory: -+ -+ `cwd_file' points to a vector of `struct fileinfo', one per file. -+ `cwd_n_alloc' is the number of elements space has been allocated for. -+ `cwd_n_used' is the number actually in use. */ -+ -+/* Address of block containing the files that are described. */ -+static struct fileinfo *cwd_file; -+ -+/* Length of block that `cwd_file' points to, measured in files. */ -+static size_t cwd_n_alloc; -+ -+/* Index of first unused slot in `cwd_file'. */ -+static size_t cwd_n_used; -+ -+/* Vector of pointers to files, in proper sorted order, and the number -+ of entries allocated for it. */ -+static void **sorted_file; -+static size_t sorted_file_alloc; -+ -+/* When true, in a color listing, color each symlink name according to the -+ type of file it points to. Otherwise, color them according to the `ln' -+ directive in LS_COLORS. Dangling (orphan) symlinks are treated specially, -+ regardless. This is set when `ln=target' appears in LS_COLORS. */ -+ -+static bool color_symlink_as_referent; -+ -+/* mode of appropriate file for colorization */ -+#define FILE_OR_LINK_MODE(File) \ -+ ((color_symlink_as_referent && (File)->linkok) \ -+ ? (File)->linkmode : (File)->stat.st_mode) -+ -+ -+/* Record of one pending directory waiting to be listed. */ -+ -+struct pending -+ { -+ char *name; -+ /* If the directory is actually the file pointed to by a symbolic link we -+ were told to list, `realname' will contain the name of the symbolic -+ link, otherwise zero. */ -+ char *realname; -+ bool command_line_arg; -+ struct pending *next; -+ }; -+ -+static struct pending *pending_dirs; -+ -+/* Current time in seconds and nanoseconds since 1970, updated as -+ needed when deciding whether a file is recent. */ -+ -+static struct timespec current_time; -+ -+static bool print_scontext; -+static char UNKNOWN_SECURITY_CONTEXT[] = "?"; -+ -+/* Whether any of the files has an ACL. This affects the width of the -+ mode column. */ -+ -+static bool any_has_acl; -+ -+/* The number of columns to use for columns containing inode numbers, -+ block sizes, link counts, owners, groups, authors, major device -+ numbers, minor device numbers, and file sizes, respectively. */ -+ -+static int inode_number_width; -+static int block_size_width; -+static int nlink_width; -+static int scontext_width; -+static int owner_width; -+static int group_width; -+static int author_width; -+static int major_device_number_width; -+static int minor_device_number_width; -+static int file_size_width; -+ -+/* Option flags */ -+ -+/* long_format for lots of info, one per line. -+ one_per_line for just names, one per line. -+ many_per_line for just names, many per line, sorted vertically. -+ horizontal for just names, many per line, sorted horizontally. -+ with_commas for just names, many per line, separated by commas. -+ -+ -l (and other options that imply -l), -1, -C, -x and -m control -+ this parameter. */ -+ -+enum format -+ { -+ long_format, /* -l and other options that imply -l */ -+ one_per_line, /* -1 */ -+ many_per_line, /* -C */ -+ horizontal, /* -x */ -+ with_commas /* -m */ -+ }; -+ -+static enum format format; -+ -+/* `full-iso' uses full ISO-style dates and times. `long-iso' uses longer -+ ISO-style time stamps, though shorter than `full-iso'. `iso' uses shorter -+ ISO-style time stamps. `locale' uses locale-dependent time stamps. */ -+enum time_style -+ { -+ full_iso_time_style, /* --time-style=full-iso */ -+ long_iso_time_style, /* --time-style=long-iso */ -+ iso_time_style, /* --time-style=iso */ -+ locale_time_style /* --time-style=locale */ -+ }; -+ -+static char const *const time_style_args[] = -+{ -+ "full-iso", "long-iso", "iso", "locale", NULL -+}; -+static enum time_style const time_style_types[] = -+{ -+ full_iso_time_style, long_iso_time_style, iso_time_style, -+ locale_time_style -+}; -+ARGMATCH_VERIFY (time_style_args, time_style_types); -+ -+/* Type of time to print or sort by. Controlled by -c and -u. -+ The values of each item of this enum are important since they are -+ used as indices in the sort functions array (see sort_files()). */ -+ -+enum time_type -+ { -+ time_mtime, /* default */ -+ time_ctime, /* -c */ -+ time_atime, /* -u */ -+ time_numtypes /* the number of elements of this enum */ -+ }; -+ -+static enum time_type time_type; -+ -+/* The file characteristic to sort by. Controlled by -t, -S, -U, -X, -v. -+ The values of each item of this enum are important since they are -+ used as indices in the sort functions array (see sort_files()). */ -+ -+enum sort_type -+ { -+ sort_none = -1, /* -U */ -+ sort_name, /* default */ -+ sort_extension, /* -X */ -+ sort_size, /* -S */ -+ sort_version, /* -v */ -+ sort_time, /* -t */ -+ sort_numtypes /* the number of elements of this enum */ -+ }; -+ -+static enum sort_type sort_type; -+ -+/* Direction of sort. -+ false means highest first if numeric, -+ lowest first if alphabetic; -+ these are the defaults. -+ true means the opposite order in each case. -r */ -+ -+static bool sort_reverse; -+ -+/* True means to display owner information. -g turns this off. */ -+ -+static bool print_owner = true; -+ -+/* True means to display author information. */ -+ -+static bool print_author; -+ -+/* True means to display group information. -G and -o turn this off. */ -+ -+static bool print_group = true; -+ -+/* True means print the user and group id's as numbers rather -+ than as names. -n */ -+ -+static bool numeric_ids; -+ -+/* True means mention the size in blocks of each file. -s */ -+ -+static bool print_block_size; -+ -+/* Human-readable options for output. */ -+static int human_output_opts; -+ -+/* The units to use when printing sizes other than file sizes. */ -+static uintmax_t output_block_size; -+ -+/* Likewise, but for file sizes. */ -+static uintmax_t file_output_block_size = 1; -+ -+/* Follow the output with a special string. Using this format, -+ Emacs' dired mode starts up twice as fast, and can handle all -+ strange characters in file names. */ -+static bool dired; -+ -+/* `none' means don't mention the type of files. -+ `slash' means mention directories only, with a '/'. -+ `file_type' means mention file types. -+ `classify' means mention file types and mark executables. -+ -+ Controlled by -F, -p, and --indicator-style. */ -+ -+enum indicator_style -+ { -+ none, /* --indicator-style=none */ -+ slash, /* -p, --indicator-style=slash */ -+ file_type, /* --indicator-style=file-type */ -+ classify /* -F, --indicator-style=classify */ -+ }; -+ -+static enum indicator_style indicator_style; -+ -+/* Names of indicator styles. */ -+static char const *const indicator_style_args[] = -+{ -+ "none", "slash", "file-type", "classify", NULL -+}; -+static enum indicator_style const indicator_style_types[] = -+{ -+ none, slash, file_type, classify -+}; -+ARGMATCH_VERIFY (indicator_style_args, indicator_style_types); -+ -+/* True means use colors to mark types. Also define the different -+ colors as well as the stuff for the LS_COLORS environment variable. -+ The LS_COLORS variable is now in a termcap-like format. */ -+ -+static bool print_with_color; -+ -+/* Whether we used any colors in the output so far. If so, we will -+ need to restore the default color later. If not, we will need to -+ call prep_non_filename_text before using color for the first time. */ -+ -+static bool used_color = false; -+ -+enum color_type -+ { -+ color_never, /* 0: default or --color=never */ -+ color_always, /* 1: --color=always */ -+ color_if_tty /* 2: --color=tty */ -+ }; -+ -+enum Dereference_symlink -+ { -+ DEREF_UNDEFINED = 1, -+ DEREF_NEVER, -+ DEREF_COMMAND_LINE_ARGUMENTS, /* -H */ -+ DEREF_COMMAND_LINE_SYMLINK_TO_DIR, /* the default, in certain cases */ -+ DEREF_ALWAYS /* -L */ -+ }; -+ -+enum indicator_no -+ { -+ C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK, -+ C_FIFO, C_SOCK, -+ C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID, -+ C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_MULTIHARDLINK, -+ C_CLR_TO_EOL -+ }; -+ -+static const char *const indicator_name[]= -+ { -+ "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so", -+ "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st", -+ "ow", "tw", "ca", "mh", "cl", NULL -+ }; -+ -+struct color_ext_type -+ { -+ struct bin_str ext; /* The extension we're looking for */ -+ struct bin_str seq; /* The sequence to output when we do */ -+ struct color_ext_type *next; /* Next in list */ -+ }; -+ -+static struct bin_str color_indicator[] = -+ { -+ { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ -+ { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ -+ { 0, NULL }, /* ec: End color (replaces lc+no+rc) */ -+ { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ -+ { 0, NULL }, /* no: Normal */ -+ { 0, NULL }, /* fi: File: default */ -+ { LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */ -+ { LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */ -+ { LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */ -+ { LEN_STR_PAIR ("01;35") }, /* so: Socket: bright magenta */ -+ { LEN_STR_PAIR ("01;33") }, /* bd: Block device: bright yellow */ -+ { LEN_STR_PAIR ("01;33") }, /* cd: Char device: bright yellow */ -+ { 0, NULL }, /* mi: Missing file: undefined */ -+ { 0, NULL }, /* or: Orphaned symlink: undefined */ -+ { LEN_STR_PAIR ("01;32") }, /* ex: Executable: bright green */ -+ { LEN_STR_PAIR ("01;35") }, /* do: Door: bright magenta */ -+ { LEN_STR_PAIR ("37;41") }, /* su: setuid: white on red */ -+ { LEN_STR_PAIR ("30;43") }, /* sg: setgid: black on yellow */ -+ { LEN_STR_PAIR ("37;44") }, /* st: sticky: black on blue */ -+ { LEN_STR_PAIR ("34;42") }, /* ow: other-writable: blue on green */ -+ { LEN_STR_PAIR ("30;42") }, /* tw: ow w/ sticky: black on green */ -+ { LEN_STR_PAIR ("30;41") }, /* ca: black on red */ -+ { 0, NULL }, /* mh: disabled by default */ -+ { LEN_STR_PAIR ("\033[K") }, /* cl: clear to end of line */ -+ }; -+ -+/* FIXME: comment */ -+static struct color_ext_type *color_ext_list = NULL; -+ -+/* Buffer for color sequences */ -+static char *color_buf; -+ -+/* True means to check for orphaned symbolic link, for displaying -+ colors. */ -+ -+static bool check_symlink_color; -+ -+/* True means mention the inode number of each file. -i */ -+ -+static bool print_inode; -+ -+/* What to do with symbolic links. Affected by -d, -F, -H, -l (and -+ other options that imply -l), and -L. */ -+ -+static enum Dereference_symlink dereference; -+ -+/* True means when a directory is found, display info on its -+ contents. -R */ -+ -+static bool recursive; -+ -+/* True means when an argument is a directory name, display info -+ on it itself. -d */ -+ -+static bool immediate_dirs; -+ -+/* True means that directories are grouped before files. */ -+ -+static bool directories_first; -+ -+/* Which files to ignore. */ -+ -+static enum -+{ -+ /* Ignore files whose names start with `.', and files specified by -+ --hide and --ignore. */ -+ IGNORE_DEFAULT, -+ -+ /* Ignore `.', `..', and files specified by --ignore. */ -+ IGNORE_DOT_AND_DOTDOT, -+ -+ /* Ignore only files specified by --ignore. */ -+ IGNORE_MINIMAL -+} ignore_mode; -+ -+/* A linked list of shell-style globbing patterns. If a non-argument -+ file name matches any of these patterns, it is ignored. -+ Controlled by -I. Multiple -I options accumulate. -+ The -B option adds `*~' and `.*~' to this list. */ -+ -+struct ignore_pattern -+ { -+ const char *pattern; -+ struct ignore_pattern *next; -+ }; -+ -+static struct ignore_pattern *ignore_patterns; -+ -+/* Similar to IGNORE_PATTERNS, except that -a or -A causes this -+ variable itself to be ignored. */ -+static struct ignore_pattern *hide_patterns; -+ -+/* True means output nongraphic chars in file names as `?'. -+ (-q, --hide-control-chars) -+ qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are -+ independent. The algorithm is: first, obey the quoting style to get a -+ string representing the file name; then, if qmark_funny_chars is set, -+ replace all nonprintable chars in that string with `?'. It's necessary -+ to replace nonprintable chars even in quoted strings, because we don't -+ want to mess up the terminal if control chars get sent to it, and some -+ quoting methods pass through control chars as-is. */ -+static bool qmark_funny_chars; -+ -+/* Quoting options for file and dir name output. */ -+ -+static struct quoting_options *filename_quoting_options; -+static struct quoting_options *dirname_quoting_options; -+ -+/* The number of chars per hardware tab stop. Setting this to zero -+ inhibits the use of TAB characters for separating columns. -T */ -+static size_t tabsize; -+ -+/* True means print each directory name before listing it. */ -+ -+static bool print_dir_name; -+ -+/* The line length to use for breaking lines in many-per-line format. -+ Can be set with -w. */ -+ -+static size_t line_length; -+ -+/* If true, the file listing format requires that stat be called on -+ each file. */ -+ -+static bool format_needs_stat; -+ -+/* Similar to `format_needs_stat', but set if only the file type is -+ needed. */ -+ -+static bool format_needs_type; -+ -+/* An arbitrary limit on the number of bytes in a printed time stamp. -+ This is set to a relatively small value to avoid the need to worry -+ about denial-of-service attacks on servers that run "ls" on behalf -+ of remote clients. 1000 bytes should be enough for any practical -+ time stamp format. */ -+ -+enum { TIME_STAMP_LEN_MAXIMUM = MAX (1000, INT_STRLEN_BOUND (time_t)) }; -+ -+/* strftime formats for non-recent and recent files, respectively, in -+ -l output. */ -+ -+static char const *long_time_format[2] = -+ { -+ /* strftime format for non-recent files (older than 6 months), in -+ -l output. This should contain the year, month and day (at -+ least), in an order that is understood by people in your -+ locale's territory. Please try to keep the number of used -+ screen columns small, because many people work in windows with -+ only 80 columns. But make this as wide as the other string -+ below, for recent files. */ -+ /* TRANSLATORS: ls output needs to be aligned for ease of reading, -+ so be wary of using variable width fields from the locale. -+ Note %b is handled specially by ls and aligned correctly. -+ Note also that specifying a width as in %5b is erroneous as strftime -+ will count bytes rather than characters in multibyte locales. */ -+ N_("%b %e %Y"), -+ /* strftime format for recent files (younger than 6 months), in -l -+ output. This should contain the month, day and time (at -+ least), in an order that is understood by people in your -+ locale's territory. Please try to keep the number of used -+ screen columns small, because many people work in windows with -+ only 80 columns. But make this as wide as the other string -+ above, for non-recent files. */ -+ /* TRANSLATORS: ls output needs to be aligned for ease of reading, -+ so be wary of using variable width fields from the locale. -+ Note %b is handled specially by ls and aligned correctly. -+ Note also that specifying a width as in %5b is erroneous as strftime -+ will count bytes rather than characters in multibyte locales. */ -+ N_("%b %e %H:%M") -+ }; -+ -+/* The set of signals that are caught. */ -+ -+static sigset_t caught_signals; -+ -+/* If nonzero, the value of the pending fatal signal. */ -+ -+static sig_atomic_t volatile interrupt_signal; -+ -+/* A count of the number of pending stop signals that have been received. */ -+ -+static sig_atomic_t volatile stop_signal_count; -+ -+/* Desired exit status. */ -+ -+static int exit_status; -+ -+/* Exit statuses. */ -+enum -+ { -+ /* "ls" had a minor problem. E.g., while processing a directory, -+ ls obtained the name of an entry via readdir, yet was later -+ unable to stat that name. This happens when listing a directory -+ in which entries are actively being removed or renamed. */ -+ LS_MINOR_PROBLEM = 1, -+ -+ /* "ls" had more serious trouble (e.g., memory exhausted, invalid -+ option or failure to stat a command line argument. */ -+ LS_FAILURE = 2 -+ }; -+ -+/* For long options that have no equivalent short option, use a -+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -+enum -+{ -+ AUTHOR_OPTION = CHAR_MAX + 1, -+ BLOCK_SIZE_OPTION, -+ COLOR_OPTION, -+ DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION, -+ FILE_TYPE_INDICATOR_OPTION, -+ FORMAT_OPTION, -+ FULL_TIME_OPTION, -+ GROUP_DIRECTORIES_FIRST_OPTION, -+ HIDE_OPTION, -+ INDICATOR_STYLE_OPTION, -+ QUOTING_STYLE_OPTION, -+ SHOW_CONTROL_CHARS_OPTION, -+ SI_OPTION, -+ SORT_OPTION, -+ TIME_OPTION, -+ TIME_STYLE_OPTION -+}; -+ -+static struct option const long_options[] = -+{ -+ {"all", no_argument, NULL, 'a'}, -+ {"escape", no_argument, NULL, 'b'}, -+ {"directory", no_argument, NULL, 'd'}, -+ {"dired", no_argument, NULL, 'D'}, -+ {"full-time", no_argument, NULL, FULL_TIME_OPTION}, -+ {"group-directories-first", no_argument, NULL, -+ GROUP_DIRECTORIES_FIRST_OPTION}, -+ {"human-readable", no_argument, NULL, 'h'}, -+ {"inode", no_argument, NULL, 'i'}, -+ {"numeric-uid-gid", no_argument, NULL, 'n'}, -+ {"no-group", no_argument, NULL, 'G'}, -+ {"hide-control-chars", no_argument, NULL, 'q'}, -+ {"reverse", no_argument, NULL, 'r'}, -+ {"size", no_argument, NULL, 's'}, -+ {"width", required_argument, NULL, 'w'}, -+ {"almost-all", no_argument, NULL, 'A'}, -+ {"ignore-backups", no_argument, NULL, 'B'}, -+ {"classify", no_argument, NULL, 'F'}, -+ {"file-type", no_argument, NULL, FILE_TYPE_INDICATOR_OPTION}, -+ {"si", no_argument, NULL, SI_OPTION}, -+ {"dereference-command-line", no_argument, NULL, 'H'}, -+ {"dereference-command-line-symlink-to-dir", no_argument, NULL, -+ DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION}, -+ {"hide", required_argument, NULL, HIDE_OPTION}, -+ {"ignore", required_argument, NULL, 'I'}, -+ {"indicator-style", required_argument, NULL, INDICATOR_STYLE_OPTION}, -+ {"dereference", no_argument, NULL, 'L'}, -+ {"literal", no_argument, NULL, 'N'}, -+ {"quote-name", no_argument, NULL, 'Q'}, -+ {"quoting-style", required_argument, NULL, QUOTING_STYLE_OPTION}, -+ {"recursive", no_argument, NULL, 'R'}, -+ {"format", required_argument, NULL, FORMAT_OPTION}, -+ {"show-control-chars", no_argument, NULL, SHOW_CONTROL_CHARS_OPTION}, -+ {"sort", required_argument, NULL, SORT_OPTION}, -+ {"tabsize", required_argument, NULL, 'T'}, -+ {"time", required_argument, NULL, TIME_OPTION}, -+ {"time-style", required_argument, NULL, TIME_STYLE_OPTION}, -+ {"color", optional_argument, NULL, COLOR_OPTION}, -+ {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION}, -+ {"context", no_argument, 0, 'Z'}, -+ {"author", no_argument, NULL, AUTHOR_OPTION}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+static char const *const format_args[] = -+{ -+ "verbose", "long", "commas", "horizontal", "across", -+ "vertical", "single-column", NULL -+}; -+static enum format const format_types[] = -+{ -+ long_format, long_format, with_commas, horizontal, horizontal, -+ many_per_line, one_per_line -+}; -+ARGMATCH_VERIFY (format_args, format_types); -+ -+static char const *const sort_args[] = -+{ -+ "none", "time", "size", "extension", "version", NULL -+}; -+static enum sort_type const sort_types[] = -+{ -+ sort_none, sort_time, sort_size, sort_extension, sort_version -+}; -+ARGMATCH_VERIFY (sort_args, sort_types); -+ -+static char const *const time_args[] = -+{ -+ "atime", "access", "use", "ctime", "status", NULL -+}; -+static enum time_type const time_types[] = -+{ -+ time_atime, time_atime, time_atime, time_ctime, time_ctime -+}; -+ARGMATCH_VERIFY (time_args, time_types); -+ -+static char const *const color_args[] = -+{ -+ /* force and none are for compatibility with another color-ls version */ -+ "always", "yes", "force", -+ "never", "no", "none", -+ "auto", "tty", "if-tty", NULL -+}; -+static enum color_type const color_types[] = -+{ -+ color_always, color_always, color_always, -+ color_never, color_never, color_never, -+ color_if_tty, color_if_tty, color_if_tty -+}; -+ARGMATCH_VERIFY (color_args, color_types); -+ -+/* Information about filling a column. */ -+struct column_info -+{ -+ bool valid_len; -+ size_t line_len; -+ size_t *col_arr; -+}; -+ -+/* Array with information about column filledness. */ -+static struct column_info *column_info; -+ -+/* Maximum number of columns ever possible for this display. */ -+static size_t max_idx; -+ -+/* The minimum width of a column is 3: 1 character for the name and 2 -+ for the separating white space. */ -+#define MIN_COLUMN_WIDTH 3 -+ -+ -+/* This zero-based index is used solely with the --dired option. -+ When that option is in effect, this counter is incremented for each -+ byte of output generated by this program so that the beginning -+ and ending indices (in that output) of every file name can be recorded -+ and later output themselves. */ -+static size_t dired_pos; -+ -+#define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0) -+ -+/* Write S to STREAM and increment DIRED_POS by S_LEN. */ -+#define DIRED_FPUTS(s, stream, s_len) \ -+ do {fputs (s, stream); dired_pos += s_len;} while (0) -+ -+/* Like DIRED_FPUTS, but for use when S is a literal string. */ -+#define DIRED_FPUTS_LITERAL(s, stream) \ -+ do {fputs (s, stream); dired_pos += sizeof (s) - 1;} while (0) -+ -+#define DIRED_INDENT() \ -+ do \ -+ { \ -+ if (dired) \ -+ DIRED_FPUTS_LITERAL (" ", stdout); \ -+ } \ -+ while (0) -+ -+/* With --dired, store pairs of beginning and ending indices of filenames. */ -+static struct obstack dired_obstack; -+ -+/* With --dired, store pairs of beginning and ending indices of any -+ directory names that appear as headers (just before `total' line) -+ for lists of directory entries. Such directory names are seen when -+ listing hierarchies using -R and when a directory is listed with at -+ least one other command line argument. */ -+static struct obstack subdired_obstack; -+ -+/* Save the current index on the specified obstack, OBS. */ -+#define PUSH_CURRENT_DIRED_POS(obs) \ -+ do \ -+ { \ -+ if (dired) \ -+ obstack_grow (obs, &dired_pos, sizeof (dired_pos)); \ -+ } \ -+ while (0) -+ -+/* With -R, this stack is used to help detect directory cycles. -+ The device/inode pairs on this stack mirror the pairs in the -+ active_dir_set hash table. */ -+static struct obstack dev_ino_obstack; -+ -+/* Push a pair onto the device/inode stack. */ -+#define DEV_INO_PUSH(Dev, Ino) \ -+ do \ -+ { \ -+ struct dev_ino *di; \ -+ obstack_blank (&dev_ino_obstack, sizeof (struct dev_ino)); \ -+ di = -1 + (struct dev_ino *) obstack_next_free (&dev_ino_obstack); \ -+ di->st_dev = (Dev); \ -+ di->st_ino = (Ino); \ -+ } \ -+ while (0) -+ -+/* Pop a dev/ino struct off the global dev_ino_obstack -+ and return that struct. */ -+static struct dev_ino -+dev_ino_pop (void) -+{ -+ assert (sizeof (struct dev_ino) <= obstack_object_size (&dev_ino_obstack)); -+ obstack_blank (&dev_ino_obstack, -(int) (sizeof (struct dev_ino))); -+ return *(struct dev_ino *) obstack_next_free (&dev_ino_obstack); -+} -+ -+/* Note the use commented out below: -+#define ASSERT_MATCHING_DEV_INO(Name, Di) \ -+ do \ -+ { \ -+ struct stat sb; \ -+ assert (Name); \ -+ assert (0 <= stat (Name, &sb)); \ -+ assert (sb.st_dev == Di.st_dev); \ -+ assert (sb.st_ino == Di.st_ino); \ -+ } \ -+ while (0) -+*/ -+ -+/* Write to standard output PREFIX, followed by the quoting style and -+ a space-separated list of the integers stored in OS all on one line. */ -+ -+static void -+dired_dump_obstack (const char *prefix, struct obstack *os) -+{ -+ size_t n_pos; -+ -+ n_pos = obstack_object_size (os) / sizeof (dired_pos); -+ if (n_pos > 0) -+ { -+ size_t i; -+ size_t *pos; -+ -+ pos = (size_t *) obstack_finish (os); -+ fputs (prefix, stdout); -+ for (i = 0; i < n_pos; i++) -+ printf (" %lu", (unsigned long int) pos[i]); -+ putchar ('\n'); -+ } -+} -+ -+/* Read the abbreviated month names from the locale, to align them -+ and to determine the max width of the field and to truncate names -+ greater than our max allowed. -+ Note even though this handles multibyte locales correctly -+ it's not restricted to them as single byte locales can have -+ variable width abbreviated months and also precomputing/caching -+ the names was seen to increase the performance of ls significantly. */ -+ -+/* max number of display cells to use */ -+enum { MAX_MON_WIDTH = 5 }; -+/* In the unlikely event that the abmon[] storage is not big enough -+ an error message will be displayed, and we revert to using -+ unmodified abbreviated month names from the locale database. */ -+static char abmon[12][MAX_MON_WIDTH * 2 * MB_LEN_MAX + 1]; -+/* minimum width needed to align %b, 0 => don't use precomputed values. */ -+static size_t required_mon_width; -+ -+static size_t -+abmon_init (void) -+{ -+#ifdef HAVE_NL_LANGINFO -+ required_mon_width = MAX_MON_WIDTH; -+ size_t curr_max_width; -+ do -+ { -+ curr_max_width = required_mon_width; -+ required_mon_width = 0; -+ for (int i = 0; i < 12; i++) -+ { -+ size_t width = curr_max_width; -+ -+ size_t req = mbsalign (nl_langinfo (ABMON_1 + i), -+ abmon[i], sizeof (abmon[i]), -+ &width, MBS_ALIGN_LEFT, 0); -+ -+ if (req == (size_t) -1 || req >= sizeof (abmon[i])) -+ { -+ required_mon_width = 0; /* ignore precomputed strings. */ -+ return required_mon_width; -+ } -+ -+ required_mon_width = MAX (required_mon_width, width); -+ } -+ } -+ while (curr_max_width > required_mon_width); -+#endif -+ -+ return required_mon_width; -+} -+ -+static size_t -+dev_ino_hash (void const *x, size_t table_size) -+{ -+ struct dev_ino const *p = x; -+ return (uintmax_t) p->st_ino % table_size; -+} -+ -+static bool -+dev_ino_compare (void const *x, void const *y) -+{ -+ struct dev_ino const *a = x; -+ struct dev_ino const *b = y; -+ return SAME_INODE (*a, *b) ? true : false; -+} -+ -+static void -+dev_ino_free (void *x) -+{ -+ free (x); -+} -+ -+/* Add the device/inode pair (P->st_dev/P->st_ino) to the set of -+ active directories. Return true if there is already a matching -+ entry in the table. */ -+ -+static bool -+visit_dir (dev_t dev, ino_t ino) -+{ -+ struct dev_ino *ent; -+ struct dev_ino *ent_from_table; -+ bool found_match; -+ -+ ent = xmalloc (sizeof *ent); -+ ent->st_ino = ino; -+ ent->st_dev = dev; -+ -+ /* Attempt to insert this entry into the table. */ -+ ent_from_table = hash_insert (active_dir_set, ent); -+ -+ if (ent_from_table == NULL) -+ { -+ /* Insertion failed due to lack of memory. */ -+ xalloc_die (); -+ } -+ -+ found_match = (ent_from_table != ent); -+ -+ if (found_match) -+ { -+ /* ent was not inserted, so free it. */ -+ free (ent); -+ } -+ -+ return found_match; -+} -+ -+static void -+free_pending_ent (struct pending *p) -+{ -+ free (p->name); -+ free (p->realname); -+ free (p); -+} -+ -+static bool -+is_colored (enum indicator_no type) -+{ -+ size_t len = color_indicator[type].len; -+ char const *s = color_indicator[type].string; -+ return ! (len == 0 -+ || (len == 1 && strncmp (s, "0", 1) == 0) -+ || (len == 2 && strncmp (s, "00", 2) == 0)); -+} -+ -+static void -+restore_default_color (void) -+{ -+ put_indicator (&color_indicator[C_LEFT]); -+ put_indicator (&color_indicator[C_RIGHT]); -+} -+ -+/* An ordinary signal was received; arrange for the program to exit. */ -+ -+static void -+sighandler (int sig) -+{ -+ if (! SA_NOCLDSTOP) -+ signal (sig, SIG_IGN); -+ if (! interrupt_signal) -+ interrupt_signal = sig; -+} -+ -+/* A SIGTSTP was received; arrange for the program to suspend itself. */ -+ -+static void -+stophandler (int sig) -+{ -+ if (! SA_NOCLDSTOP) -+ signal (sig, stophandler); -+ if (! interrupt_signal) -+ stop_signal_count++; -+} -+ -+/* Process any pending signals. If signals are caught, this function -+ should be called periodically. Ideally there should never be an -+ unbounded amount of time when signals are not being processed. -+ Signal handling can restore the default colors, so callers must -+ immediately change colors after invoking this function. */ -+ -+static void -+process_signals (void) -+{ -+ while (interrupt_signal || stop_signal_count) -+ { -+ int sig; -+ int stops; -+ sigset_t oldset; -+ -+ if (used_color) -+ restore_default_color (); -+ fflush (stdout); -+ -+ sigprocmask (SIG_BLOCK, &caught_signals, &oldset); -+ -+ /* Reload interrupt_signal and stop_signal_count, in case a new -+ signal was handled before sigprocmask took effect. */ -+ sig = interrupt_signal; -+ stops = stop_signal_count; -+ -+ /* SIGTSTP is special, since the application can receive that signal -+ more than once. In this case, don't set the signal handler to the -+ default. Instead, just raise the uncatchable SIGSTOP. */ -+ if (stops) -+ { -+ stop_signal_count = stops - 1; -+ sig = SIGSTOP; -+ } -+ else -+ signal (sig, SIG_DFL); -+ -+ /* Exit or suspend the program. */ -+ raise (sig); -+ sigprocmask (SIG_SETMASK, &oldset, NULL); -+ -+ /* If execution reaches here, then the program has been -+ continued (after being suspended). */ -+ } -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int i; -+ struct pending *thispend; -+ int n_files; -+ -+ /* The signals that are trapped, and the number of such signals. */ -+ static int const sig[] = -+ { -+ /* This one is handled specially. */ -+ SIGTSTP, -+ -+ /* The usual suspects. */ -+ SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, -+#ifdef SIGPOLL -+ SIGPOLL, -+#endif -+#ifdef SIGPROF -+ SIGPROF, -+#endif -+#ifdef SIGVTALRM -+ SIGVTALRM, -+#endif -+#ifdef SIGXCPU -+ SIGXCPU, -+#endif -+#ifdef SIGXFSZ -+ SIGXFSZ, -+#endif -+ }; -+ enum { nsigs = ARRAY_CARDINALITY (sig) }; -+ -+#if ! SA_NOCLDSTOP -+ bool caught_sig[nsigs]; -+#endif -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ initialize_exit_failure (LS_FAILURE); -+ atexit (close_stdout); -+ -+ assert (ARRAY_CARDINALITY (color_indicator) + 1 -+ == ARRAY_CARDINALITY (indicator_name)); -+ -+ exit_status = EXIT_SUCCESS; -+ print_dir_name = true; -+ pending_dirs = NULL; -+ -+ current_time.tv_sec = TYPE_MINIMUM (time_t); -+ current_time.tv_nsec = -1; -+ -+ i = decode_switches (argc, argv); -+ -+ if (print_with_color) -+ parse_ls_color (); -+ -+ /* Test print_with_color again, because the call to parse_ls_color -+ may have just reset it -- e.g., if LS_COLORS is invalid. */ -+ if (print_with_color) -+ { -+ /* Avoid following symbolic links when possible. */ -+ if (is_colored (C_ORPHAN) -+ || (is_colored (C_EXEC) && color_symlink_as_referent) -+ || (is_colored (C_MISSING) && format == long_format)) -+ check_symlink_color = true; -+ -+ /* If the standard output is a controlling terminal, watch out -+ for signals, so that the colors can be restored to the -+ default state if "ls" is suspended or interrupted. */ -+ -+ if (0 <= tcgetpgrp (STDOUT_FILENO)) -+ { -+ int j; -+#if SA_NOCLDSTOP -+ struct sigaction act; -+ -+ sigemptyset (&caught_signals); -+ for (j = 0; j < nsigs; j++) -+ { -+ sigaction (sig[j], NULL, &act); -+ if (act.sa_handler != SIG_IGN) -+ sigaddset (&caught_signals, sig[j]); -+ } -+ -+ act.sa_mask = caught_signals; -+ act.sa_flags = SA_RESTART; -+ -+ for (j = 0; j < nsigs; j++) -+ if (sigismember (&caught_signals, sig[j])) -+ { -+ act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; -+ sigaction (sig[j], &act, NULL); -+ } -+#else -+ for (j = 0; j < nsigs; j++) -+ { -+ caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); -+ if (caught_sig[j]) -+ { -+ signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); -+ siginterrupt (sig[j], 0); -+ } -+ } -+#endif -+ } -+ } -+ -+ if (dereference == DEREF_UNDEFINED) -+ dereference = ((immediate_dirs -+ || indicator_style == classify -+ || format == long_format) -+ ? DEREF_NEVER -+ : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); -+ -+ /* When using -R, initialize a data structure we'll use to -+ detect any directory cycles. */ -+ if (recursive) -+ { -+ active_dir_set = hash_initialize (INITIAL_TABLE_SIZE, NULL, -+ dev_ino_hash, -+ dev_ino_compare, -+ dev_ino_free); -+ if (active_dir_set == NULL) -+ xalloc_die (); -+ -+ obstack_init (&dev_ino_obstack); -+ } -+ -+ format_needs_stat = sort_type == sort_time || sort_type == sort_size -+ || format == long_format -+ || print_scontext -+ || print_block_size; -+ format_needs_type = (! format_needs_stat -+ && (recursive -+ || print_with_color -+ || indicator_style != none -+ || directories_first)); -+ -+ if (dired) -+ { -+ obstack_init (&dired_obstack); -+ obstack_init (&subdired_obstack); -+ } -+ -+ cwd_n_alloc = 100; -+ cwd_file = xnmalloc (cwd_n_alloc, sizeof *cwd_file); -+ cwd_n_used = 0; -+ -+ clear_files (); -+ -+ n_files = argc - i; -+ -+ if (n_files <= 0) -+ { -+ if (immediate_dirs) -+ gobble_file (".", directory, NOT_AN_INODE_NUMBER, true, ""); -+ else -+ queue_directory (".", NULL, true); -+ } -+ else -+ do -+ gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, ""); -+ while (i < argc); -+ -+ if (cwd_n_used) -+ { -+ sort_files (); -+ if (!immediate_dirs) -+ extract_dirs_from_files (NULL, true); -+ /* `cwd_n_used' might be zero now. */ -+ } -+ -+ /* In the following if/else blocks, it is sufficient to test `pending_dirs' -+ (and not pending_dirs->name) because there may be no markers in the queue -+ at this point. A marker may be enqueued when extract_dirs_from_files is -+ called with a non-empty string or via print_dir. */ -+ if (cwd_n_used) -+ { -+ print_current_files (); -+ if (pending_dirs) -+ DIRED_PUTCHAR ('\n'); -+ } -+ else if (n_files <= 1 && pending_dirs && pending_dirs->next == 0) -+ print_dir_name = false; -+ -+ while (pending_dirs) -+ { -+ thispend = pending_dirs; -+ pending_dirs = pending_dirs->next; -+ -+ if (LOOP_DETECT) -+ { -+ if (thispend->name == NULL) -+ { -+ /* thispend->name == NULL means this is a marker entry -+ indicating we've finished processing the directory. -+ Use its dev/ino numbers to remove the corresponding -+ entry from the active_dir_set hash table. */ -+ struct dev_ino di = dev_ino_pop (); -+ struct dev_ino *found = hash_delete (active_dir_set, &di); -+ /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */ -+ assert (found); -+ dev_ino_free (found); -+ free_pending_ent (thispend); -+ continue; -+ } -+ } -+ -+ print_dir (thispend->name, thispend->realname, -+ thispend->command_line_arg); -+ -+ free_pending_ent (thispend); -+ print_dir_name = true; -+ } -+ -+ if (print_with_color) -+ { -+ int j; -+ -+ if (used_color) -+ restore_default_color (); -+ fflush (stdout); -+ -+ /* Restore the default signal handling. */ -+#if SA_NOCLDSTOP -+ for (j = 0; j < nsigs; j++) -+ if (sigismember (&caught_signals, sig[j])) -+ signal (sig[j], SIG_DFL); -+#else -+ for (j = 0; j < nsigs; j++) -+ if (caught_sig[j]) -+ signal (sig[j], SIG_DFL); -+#endif -+ -+ /* Act on any signals that arrived before the default was restored. -+ This can process signals out of order, but there doesn't seem to -+ be an easy way to do them in order, and the order isn't that -+ important anyway. */ -+ for (j = stop_signal_count; j; j--) -+ raise (SIGSTOP); -+ j = interrupt_signal; -+ if (j) -+ raise (j); -+ } -+ -+ if (dired) -+ { -+ /* No need to free these since we're about to exit. */ -+ dired_dump_obstack ("//DIRED//", &dired_obstack); -+ dired_dump_obstack ("//SUBDIRED//", &subdired_obstack); -+ printf ("//DIRED-OPTIONS// --quoting-style=%s\n", -+ quoting_style_args[get_quoting_style (filename_quoting_options)]); -+ } -+ -+ if (LOOP_DETECT) -+ { -+ assert (hash_get_n_entries (active_dir_set) == 0); -+ hash_free (active_dir_set); -+ } -+ -+ exit (exit_status); -+} -+ -+/* Set all the option flags according to the switches specified. -+ Return the index of the first non-option argument. */ -+ -+static int -+decode_switches (int argc, char **argv) -+{ -+ char *time_style_option = NULL; -+ -+ /* Record whether there is an option specifying sort type. */ -+ bool sort_type_specified = false; -+ -+ qmark_funny_chars = false; -+ -+ /* initialize all switches to default settings */ -+ -+ switch (ls_mode) -+ { -+ case LS_MULTI_COL: -+ /* This is for the `dir' program. */ -+ format = many_per_line; -+ set_quoting_style (NULL, escape_quoting_style); -+ break; -+ -+ case LS_LONG_FORMAT: -+ /* This is for the `vdir' program. */ -+ format = long_format; -+ set_quoting_style (NULL, escape_quoting_style); -+ break; -+ -+ case LS_LS: -+ /* This is for the `ls' program. */ -+ if (isatty (STDOUT_FILENO)) -+ { -+ format = many_per_line; -+ /* See description of qmark_funny_chars, above. */ -+ qmark_funny_chars = true; -+ } -+ else -+ { -+ format = one_per_line; -+ qmark_funny_chars = false; -+ } -+ break; -+ -+ default: -+ abort (); -+ } -+ -+ time_type = time_mtime; -+ sort_type = sort_name; -+ sort_reverse = false; -+ numeric_ids = false; -+ print_block_size = false; -+ indicator_style = none; -+ print_inode = false; -+ dereference = DEREF_UNDEFINED; -+ recursive = false; -+ immediate_dirs = false; -+ ignore_mode = IGNORE_DEFAULT; -+ ignore_patterns = NULL; -+ hide_patterns = NULL; -+ print_scontext = false; -+ -+ /* FIXME: put this in a function. */ -+ { -+ char const *q_style = getenv ("QUOTING_STYLE"); -+ if (q_style) -+ { -+ int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals); -+ if (0 <= i) -+ set_quoting_style (NULL, quoting_style_vals[i]); -+ else -+ error (0, 0, -+ _("ignoring invalid value of environment variable QUOTING_STYLE: %s"), -+ quotearg (q_style)); -+ } -+ } -+ -+ { -+ char const *ls_block_size = getenv ("LS_BLOCK_SIZE"); -+ human_options (ls_block_size, -+ &human_output_opts, &output_block_size); -+ if (ls_block_size || getenv ("BLOCK_SIZE")) -+ file_output_block_size = output_block_size; -+ } -+ -+ line_length = 80; -+ { -+ char const *p = getenv ("COLUMNS"); -+ if (p && *p) -+ { -+ unsigned long int tmp_ulong; -+ if (xstrtoul (p, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK -+ && 0 < tmp_ulong && tmp_ulong <= SIZE_MAX) -+ { -+ line_length = tmp_ulong; -+ } -+ else -+ { -+ error (0, 0, -+ _("ignoring invalid width in environment variable COLUMNS: %s"), -+ quotearg (p)); -+ } -+ } -+ } -+ -+#ifdef TIOCGWINSZ -+ { -+ struct winsize ws; -+ -+ if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 -+ && 0 < ws.ws_col && ws.ws_col == (size_t) ws.ws_col) -+ line_length = ws.ws_col; -+ } -+#endif -+ -+ { -+ char const *p = getenv ("TABSIZE"); -+ tabsize = 8; -+ if (p) -+ { -+ unsigned long int tmp_ulong; -+ if (xstrtoul (p, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK -+ && tmp_ulong <= SIZE_MAX) -+ { -+ tabsize = tmp_ulong; -+ } -+ else -+ { -+ error (0, 0, -+ _("ignoring invalid tab size in environment variable TABSIZE: %s"), -+ quotearg (p)); -+ } -+ } -+ } -+ -+ for (;;) -+ { -+ int oi = -1; -+ int c = getopt_long (argc, argv, -+ "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1", -+ long_options, &oi); -+ if (c == -1) -+ break; -+ -+ switch (c) -+ { -+ case 'a': -+ ignore_mode = IGNORE_MINIMAL; -+ break; -+ -+ case 'b': -+ set_quoting_style (NULL, escape_quoting_style); -+ break; -+ -+ case 'c': -+ time_type = time_ctime; -+ break; -+ -+ case 'd': -+ immediate_dirs = true; -+ break; -+ -+ case 'f': -+ /* Same as enabling -a -U and disabling -l -s. */ -+ ignore_mode = IGNORE_MINIMAL; -+ sort_type = sort_none; -+ sort_type_specified = true; -+ /* disable -l */ -+ if (format == long_format) -+ format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line); -+ print_block_size = false; /* disable -s */ -+ print_with_color = false; /* disable --color */ -+ break; -+ -+ case FILE_TYPE_INDICATOR_OPTION: /* --file-type */ -+ indicator_style = file_type; -+ break; -+ -+ case 'g': -+ format = long_format; -+ print_owner = false; -+ break; -+ -+ case 'h': -+ human_output_opts = human_autoscale | human_SI | human_base_1024; -+ file_output_block_size = output_block_size = 1; -+ break; -+ -+ case 'i': -+ print_inode = true; -+ break; -+ -+ case 'k': -+ human_output_opts = 0; -+ file_output_block_size = output_block_size = 1024; -+ break; -+ -+ case 'l': -+ format = long_format; -+ break; -+ -+ case 'm': -+ format = with_commas; -+ break; -+ -+ case 'n': -+ numeric_ids = true; -+ format = long_format; -+ break; -+ -+ case 'o': /* Just like -l, but don't display group info. */ -+ format = long_format; -+ print_group = false; -+ break; -+ -+ case 'p': -+ indicator_style = slash; -+ break; -+ -+ case 'q': -+ qmark_funny_chars = true; -+ break; -+ -+ case 'r': -+ sort_reverse = true; -+ break; -+ -+ case 's': -+ print_block_size = true; -+ break; -+ -+ case 't': -+ sort_type = sort_time; -+ sort_type_specified = true; -+ break; -+ -+ case 'u': -+ time_type = time_atime; -+ break; -+ -+ case 'v': -+ sort_type = sort_version; -+ sort_type_specified = true; -+ break; -+ -+ case 'w': -+ { -+ unsigned long int tmp_ulong; -+ if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK -+ || ! (0 < tmp_ulong && tmp_ulong <= SIZE_MAX)) -+ error (LS_FAILURE, 0, _("invalid line width: %s"), -+ quotearg (optarg)); -+ line_length = tmp_ulong; -+ break; -+ } -+ -+ case 'x': -+ format = horizontal; -+ break; -+ -+ case 'A': -+ if (ignore_mode == IGNORE_DEFAULT) -+ ignore_mode = IGNORE_DOT_AND_DOTDOT; -+ break; -+ -+ case 'B': -+ add_ignore_pattern ("*~"); -+ add_ignore_pattern (".*~"); -+ break; -+ -+ case 'C': -+ format = many_per_line; -+ break; -+ -+ case 'D': -+ dired = true; -+ break; -+ -+ case 'F': -+ indicator_style = classify; -+ break; -+ -+ case 'G': /* inhibit display of group info */ -+ print_group = false; -+ break; -+ -+ case 'H': -+ dereference = DEREF_COMMAND_LINE_ARGUMENTS; -+ break; -+ -+ case DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION: -+ dereference = DEREF_COMMAND_LINE_SYMLINK_TO_DIR; -+ break; -+ -+ case 'I': -+ add_ignore_pattern (optarg); -+ break; -+ -+ case 'L': -+ dereference = DEREF_ALWAYS; -+ break; -+ -+ case 'N': -+ set_quoting_style (NULL, literal_quoting_style); -+ break; -+ -+ case 'Q': -+ set_quoting_style (NULL, c_quoting_style); -+ break; -+ -+ case 'R': -+ recursive = true; -+ break; -+ -+ case 'S': -+ sort_type = sort_size; -+ sort_type_specified = true; -+ break; -+ -+ case 'T': -+ { -+ unsigned long int tmp_ulong; -+ if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK -+ || SIZE_MAX < tmp_ulong) -+ error (LS_FAILURE, 0, _("invalid tab size: %s"), -+ quotearg (optarg)); -+ tabsize = tmp_ulong; -+ break; -+ } -+ -+ case 'U': -+ sort_type = sort_none; -+ sort_type_specified = true; -+ break; -+ -+ case 'X': -+ sort_type = sort_extension; -+ sort_type_specified = true; -+ break; -+ -+ case '1': -+ /* -1 has no effect after -l. */ -+ if (format != long_format) -+ format = one_per_line; -+ break; -+ -+ case AUTHOR_OPTION: -+ print_author = true; -+ break; -+ -+ case HIDE_OPTION: -+ { -+ struct ignore_pattern *hide = xmalloc (sizeof *hide); -+ hide->pattern = optarg; -+ hide->next = hide_patterns; -+ hide_patterns = hide; -+ } -+ break; -+ -+ case SORT_OPTION: -+ sort_type = XARGMATCH ("--sort", optarg, sort_args, sort_types); -+ sort_type_specified = true; -+ break; -+ -+ case GROUP_DIRECTORIES_FIRST_OPTION: -+ directories_first = true; -+ break; -+ -+ case TIME_OPTION: -+ time_type = XARGMATCH ("--time", optarg, time_args, time_types); -+ break; -+ -+ case FORMAT_OPTION: -+ format = XARGMATCH ("--format", optarg, format_args, format_types); -+ break; -+ -+ case FULL_TIME_OPTION: -+ format = long_format; -+ time_style_option = bad_cast ("full-iso"); -+ break; -+ -+ case COLOR_OPTION: -+ { -+ int i; -+ if (optarg) -+ i = XARGMATCH ("--color", optarg, color_args, color_types); -+ else -+ /* Using --color with no argument is equivalent to using -+ --color=always. */ -+ i = color_always; -+ -+ print_with_color = (i == color_always -+ || (i == color_if_tty -+ && isatty (STDOUT_FILENO))); -+ -+ if (print_with_color) -+ { -+ /* Don't use TAB characters in output. Some terminal -+ emulators can't handle the combination of tabs and -+ color codes on the same line. */ -+ tabsize = 0; -+ } -+ break; -+ } -+ -+ case INDICATOR_STYLE_OPTION: -+ indicator_style = XARGMATCH ("--indicator-style", optarg, -+ indicator_style_args, -+ indicator_style_types); -+ break; -+ -+ case QUOTING_STYLE_OPTION: -+ set_quoting_style (NULL, -+ XARGMATCH ("--quoting-style", optarg, -+ quoting_style_args, -+ quoting_style_vals)); -+ break; -+ -+ case TIME_STYLE_OPTION: -+ time_style_option = optarg; -+ break; -+ -+ case SHOW_CONTROL_CHARS_OPTION: -+ qmark_funny_chars = false; -+ break; -+ -+ case BLOCK_SIZE_OPTION: -+ { -+ enum strtol_error e = human_options (optarg, &human_output_opts, -+ &output_block_size); -+ if (e != LONGINT_OK) -+ xstrtol_fatal (e, oi, 0, long_options, optarg); -+ file_output_block_size = output_block_size; -+ } -+ break; -+ -+ case SI_OPTION: -+ human_output_opts = human_autoscale | human_SI; -+ file_output_block_size = output_block_size = 1; -+ break; -+ -+ case 'Z': -+ print_scontext = true; -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (LS_FAILURE); -+ } -+ } -+ -+ max_idx = MAX (1, line_length / MIN_COLUMN_WIDTH); -+ -+ filename_quoting_options = clone_quoting_options (NULL); -+ if (get_quoting_style (filename_quoting_options) == escape_quoting_style) -+ set_char_quoting (filename_quoting_options, ' ', 1); -+ if (file_type <= indicator_style) -+ { -+ char const *p; -+ for (p = "*=>@|" + indicator_style - file_type; *p; p++) -+ set_char_quoting (filename_quoting_options, *p, 1); -+ } -+ -+ dirname_quoting_options = clone_quoting_options (NULL); -+ set_char_quoting (dirname_quoting_options, ':', 1); -+ -+ /* --dired is meaningful only with --format=long (-l). -+ Otherwise, ignore it. FIXME: warn about this? -+ Alternatively, make --dired imply --format=long? */ -+ if (dired && format != long_format) -+ dired = false; -+ -+ /* If -c or -u is specified and not -l (or any other option that implies -l), -+ and no sort-type was specified, then sort by the ctime (-c) or atime (-u). -+ The behavior of ls when using either -c or -u but with neither -l nor -t -+ appears to be unspecified by POSIX. So, with GNU ls, `-u' alone means -+ sort by atime (this is the one that's not specified by the POSIX spec), -+ -lu means show atime and sort by name, -lut means show atime and sort -+ by atime. */ -+ -+ if ((time_type == time_ctime || time_type == time_atime) -+ && !sort_type_specified && format != long_format) -+ { -+ sort_type = sort_time; -+ } -+ -+ if (format == long_format) -+ { -+ char *style = time_style_option; -+ static char const posix_prefix[] = "posix-"; -+ -+ if (! style) -+ if (! (style = getenv ("TIME_STYLE"))) -+ style = bad_cast ("locale"); -+ -+ while (strncmp (style, posix_prefix, sizeof posix_prefix - 1) == 0) -+ { -+ if (! hard_locale (LC_TIME)) -+ return optind; -+ style += sizeof posix_prefix - 1; -+ } -+ -+ if (*style == '+') -+ { -+ char *p0 = style + 1; -+ char *p1 = strchr (p0, '\n'); -+ if (! p1) -+ p1 = p0; -+ else -+ { -+ if (strchr (p1 + 1, '\n')) -+ error (LS_FAILURE, 0, _("invalid time style format %s"), -+ quote (p0)); -+ *p1++ = '\0'; -+ } -+ long_time_format[0] = p0; -+ long_time_format[1] = p1; -+ } -+ else -+ switch (XARGMATCH ("time style", style, -+ time_style_args, -+ time_style_types)) -+ { -+ case full_iso_time_style: -+ long_time_format[0] = long_time_format[1] = -+ "%Y-%m-%d %H:%M:%S.%N %z"; -+ break; -+ -+ case long_iso_time_style: -+ case_long_iso_time_style: -+ long_time_format[0] = long_time_format[1] = "%Y-%m-%d %H:%M"; -+ break; -+ -+ case iso_time_style: -+ long_time_format[0] = "%Y-%m-%d "; -+ long_time_format[1] = "%m-%d %H:%M"; -+ break; -+ -+ case locale_time_style: -+ if (hard_locale (LC_TIME)) -+ { -+ /* Ensure that the locale has translations for both -+ formats. If not, fall back on long-iso format. */ -+ int i; -+ for (i = 0; i < 2; i++) -+ { -+ char const *locale_format = -+ dcgettext (NULL, long_time_format[i], LC_TIME); -+ if (locale_format == long_time_format[i]) -+ goto case_long_iso_time_style; -+ long_time_format[i] = locale_format; -+ } -+ } -+ } -+ /* Note we leave %5b etc. alone so user widths/flags are honored. */ -+ if (strstr (long_time_format[0],"%b") || strstr (long_time_format[1],"%b")) -+ if (!abmon_init ()) -+ error (0, 0, _("error initializing month strings")); -+ } -+ -+ return optind; -+} -+ -+/* Parse a string as part of the LS_COLORS variable; this may involve -+ decoding all kinds of escape characters. If equals_end is set an -+ unescaped equal sign ends the string, otherwise only a : or \0 -+ does. Set *OUTPUT_COUNT to the number of bytes output. Return -+ true if successful. -+ -+ The resulting string is *not* null-terminated, but may contain -+ embedded nulls. -+ -+ Note that both dest and src are char **; on return they point to -+ the first free byte after the array and the character that ended -+ the input string, respectively. */ -+ -+static bool -+get_funky_string (char **dest, const char **src, bool equals_end, -+ size_t *output_count) -+{ -+ char num; /* For numerical codes */ -+ size_t count; /* Something to count with */ -+ enum { -+ ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR -+ } state; -+ const char *p; -+ char *q; -+ -+ p = *src; /* We don't want to double-indirect */ -+ q = *dest; /* the whole darn time. */ -+ -+ count = 0; /* No characters counted in yet. */ -+ num = 0; -+ -+ state = ST_GND; /* Start in ground state. */ -+ while (state < ST_END) -+ { -+ switch (state) -+ { -+ case ST_GND: /* Ground state (no escapes) */ -+ switch (*p) -+ { -+ case ':': -+ case '\0': -+ state = ST_END; /* End of string */ -+ break; -+ case '\\': -+ state = ST_BACKSLASH; /* Backslash scape sequence */ -+ ++p; -+ break; -+ case '^': -+ state = ST_CARET; /* Caret escape */ -+ ++p; -+ break; -+ case '=': -+ if (equals_end) -+ { -+ state = ST_END; /* End */ -+ break; -+ } -+ /* else fall through */ -+ default: -+ *(q++) = *(p++); -+ ++count; -+ break; -+ } -+ break; -+ -+ case ST_BACKSLASH: /* Backslash escaped character */ -+ switch (*p) -+ { -+ case '0': -+ case '1': -+ case '2': -+ case '3': -+ case '4': -+ case '5': -+ case '6': -+ case '7': -+ state = ST_OCTAL; /* Octal sequence */ -+ num = *p - '0'; -+ break; -+ case 'x': -+ case 'X': -+ state = ST_HEX; /* Hex sequence */ -+ num = 0; -+ break; -+ case 'a': /* Bell */ -+ num = '\a'; -+ break; -+ case 'b': /* Backspace */ -+ num = '\b'; -+ break; -+ case 'e': /* Escape */ -+ num = 27; -+ break; -+ case 'f': /* Form feed */ -+ num = '\f'; -+ break; -+ case 'n': /* Newline */ -+ num = '\n'; -+ break; -+ case 'r': /* Carriage return */ -+ num = '\r'; -+ break; -+ case 't': /* Tab */ -+ num = '\t'; -+ break; -+ case 'v': /* Vtab */ -+ num = '\v'; -+ break; -+ case '?': /* Delete */ -+ num = 127; -+ break; -+ case '_': /* Space */ -+ num = ' '; -+ break; -+ case '\0': /* End of string */ -+ state = ST_ERROR; /* Error! */ -+ break; -+ default: /* Escaped character like \ ^ : = */ -+ num = *p; -+ break; -+ } -+ if (state == ST_BACKSLASH) -+ { -+ *(q++) = num; -+ ++count; -+ state = ST_GND; -+ } -+ ++p; -+ break; -+ -+ case ST_OCTAL: /* Octal sequence */ -+ if (*p < '0' || *p > '7') -+ { -+ *(q++) = num; -+ ++count; -+ state = ST_GND; -+ } -+ else -+ num = (num << 3) + (*(p++) - '0'); -+ break; -+ -+ case ST_HEX: /* Hex sequence */ -+ switch (*p) -+ { -+ case '0': -+ case '1': -+ case '2': -+ case '3': -+ case '4': -+ case '5': -+ case '6': -+ case '7': -+ case '8': -+ case '9': -+ num = (num << 4) + (*(p++) - '0'); -+ break; -+ case 'a': -+ case 'b': -+ case 'c': -+ case 'd': -+ case 'e': -+ case 'f': -+ num = (num << 4) + (*(p++) - 'a') + 10; -+ break; -+ case 'A': -+ case 'B': -+ case 'C': -+ case 'D': -+ case 'E': -+ case 'F': -+ num = (num << 4) + (*(p++) - 'A') + 10; -+ break; -+ default: -+ *(q++) = num; -+ ++count; -+ state = ST_GND; -+ break; -+ } -+ break; -+ -+ case ST_CARET: /* Caret escape */ -+ state = ST_GND; /* Should be the next state... */ -+ if (*p >= '@' && *p <= '~') -+ { -+ *(q++) = *(p++) & 037; -+ ++count; -+ } -+ else if (*p == '?') -+ { -+ *(q++) = 127; -+ ++count; -+ } -+ else -+ state = ST_ERROR; -+ break; -+ -+ default: -+ abort (); -+ } -+ } -+ -+ *dest = q; -+ *src = p; -+ *output_count = count; -+ -+ return state != ST_ERROR; -+} -+ -+static void -+parse_ls_color (void) -+{ -+ const char *p; /* Pointer to character being parsed */ -+ char *buf; /* color_buf buffer pointer */ -+ int state; /* State of parser */ -+ int ind_no; /* Indicator number */ -+ char label[3]; /* Indicator label */ -+ struct color_ext_type *ext; /* Extension we are working on */ -+ -+ if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0') -+ return; -+ -+ ext = NULL; -+ strcpy (label, "??"); -+ -+ /* This is an overly conservative estimate, but any possible -+ LS_COLORS string will *not* generate a color_buf longer than -+ itself, so it is a safe way of allocating a buffer in -+ advance. */ -+ buf = color_buf = xstrdup (p); -+ -+ state = 1; -+ while (state > 0) -+ { -+ switch (state) -+ { -+ case 1: /* First label character */ -+ switch (*p) -+ { -+ case ':': -+ ++p; -+ break; -+ -+ case '*': -+ /* Allocate new extension block and add to head of -+ linked list (this way a later definition will -+ override an earlier one, which can be useful for -+ having terminal-specific defs override global). */ -+ -+ ext = xmalloc (sizeof *ext); -+ ext->next = color_ext_list; -+ color_ext_list = ext; -+ -+ ++p; -+ ext->ext.string = buf; -+ -+ state = (get_funky_string (&buf, &p, true, &ext->ext.len) -+ ? 4 : -1); -+ break; -+ -+ case '\0': -+ state = 0; /* Done! */ -+ break; -+ -+ default: /* Assume it is file type label */ -+ label[0] = *(p++); -+ state = 2; -+ break; -+ } -+ break; -+ -+ case 2: /* Second label character */ -+ if (*p) -+ { -+ label[1] = *(p++); -+ state = 3; -+ } -+ else -+ state = -1; /* Error */ -+ break; -+ -+ case 3: /* Equal sign after indicator label */ -+ state = -1; /* Assume failure... */ -+ if (*(p++) == '=')/* It *should* be... */ -+ { -+ for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) -+ { -+ if (STREQ (label, indicator_name[ind_no])) -+ { -+ color_indicator[ind_no].string = buf; -+ state = (get_funky_string (&buf, &p, false, -+ &color_indicator[ind_no].len) -+ ? 1 : -1); -+ break; -+ } -+ } -+ if (state == -1) -+ error (0, 0, _("unrecognized prefix: %s"), quotearg (label)); -+ } -+ break; -+ -+ case 4: /* Equal sign after *.ext */ -+ if (*(p++) == '=') -+ { -+ ext->seq.string = buf; -+ state = (get_funky_string (&buf, &p, false, &ext->seq.len) -+ ? 1 : -1); -+ } -+ else -+ state = -1; -+ break; -+ } -+ } -+ -+ if (state < 0) -+ { -+ struct color_ext_type *e; -+ struct color_ext_type *e2; -+ -+ error (0, 0, -+ _("unparsable value for LS_COLORS environment variable")); -+ free (color_buf); -+ for (e = color_ext_list; e != NULL; /* empty */) -+ { -+ e2 = e; -+ e = e->next; -+ free (e2); -+ } -+ print_with_color = false; -+ } -+ -+ if (color_indicator[C_LINK].len == 6 -+ && !strncmp (color_indicator[C_LINK].string, "target", 6)) -+ color_symlink_as_referent = true; -+} -+ -+/* Set the exit status to report a failure. If SERIOUS, it is a -+ serious failure; otherwise, it is merely a minor problem. */ -+ -+static void -+set_exit_status (bool serious) -+{ -+ if (serious) -+ exit_status = LS_FAILURE; -+ else if (exit_status == EXIT_SUCCESS) -+ exit_status = LS_MINOR_PROBLEM; -+} -+ -+/* Assuming a failure is serious if SERIOUS, use the printf-style -+ MESSAGE to report the failure to access a file named FILE. Assume -+ errno is set appropriately for the failure. */ -+ -+static void -+file_failure (bool serious, char const *message, char const *file) -+{ -+ error (0, errno, message, quotearg_colon (file)); -+ set_exit_status (serious); -+} -+ -+/* Request that the directory named NAME have its contents listed later. -+ If REALNAME is nonzero, it will be used instead of NAME when the -+ directory name is printed. This allows symbolic links to directories -+ to be treated as regular directories but still be listed under their -+ real names. NAME == NULL is used to insert a marker entry for the -+ directory named in REALNAME. -+ If NAME is non-NULL, we use its dev/ino information to save -+ a call to stat -- when doing a recursive (-R) traversal. -+ COMMAND_LINE_ARG means this directory was mentioned on the command line. */ -+ -+static void -+queue_directory (char const *name, char const *realname, bool command_line_arg) -+{ -+ struct pending *new = xmalloc (sizeof *new); -+ new->realname = realname ? xstrdup (realname) : NULL; -+ new->name = name ? xstrdup (name) : NULL; -+ new->command_line_arg = command_line_arg; -+ new->next = pending_dirs; -+ pending_dirs = new; -+} -+ -+/* Read directory NAME, and list the files in it. -+ If REALNAME is nonzero, print its name instead of NAME; -+ this is used for symbolic links to directories. -+ COMMAND_LINE_ARG means this directory was mentioned on the command line. */ -+ -+static void -+print_dir (char const *name, char const *realname, bool command_line_arg) -+{ -+ DIR *dirp; -+ struct dirent *next; -+ uintmax_t total_blocks = 0; -+ static bool first = true; -+ -+ errno = 0; -+ dirp = opendir (name); -+ if (!dirp) -+ { -+ file_failure (command_line_arg, _("cannot open directory %s"), name); -+ return; -+ } -+ -+ if (LOOP_DETECT) -+ { -+ struct stat dir_stat; -+ int fd = dirfd (dirp); -+ -+ /* If dirfd failed, endure the overhead of using stat. */ -+ if ((0 <= fd -+ ? fstat (fd, &dir_stat) -+ : stat (name, &dir_stat)) < 0) -+ { -+ file_failure (command_line_arg, -+ _("cannot determine device and inode of %s"), name); -+ closedir (dirp); -+ return; -+ } -+ -+ /* If we've already visited this dev/inode pair, warn that -+ we've found a loop, and do not process this directory. */ -+ if (visit_dir (dir_stat.st_dev, dir_stat.st_ino)) -+ { -+ error (0, 0, _("%s: not listing already-listed directory"), -+ quotearg_colon (name)); -+ closedir (dirp); -+ set_exit_status (true); -+ return; -+ } -+ -+ DEV_INO_PUSH (dir_stat.st_dev, dir_stat.st_ino); -+ } -+ -+ if (recursive || print_dir_name) -+ { -+ if (!first) -+ DIRED_PUTCHAR ('\n'); -+ first = false; -+ DIRED_INDENT (); -+ PUSH_CURRENT_DIRED_POS (&subdired_obstack); -+ dired_pos += quote_name (stdout, realname ? realname : name, -+ dirname_quoting_options, NULL); -+ PUSH_CURRENT_DIRED_POS (&subdired_obstack); -+ DIRED_FPUTS_LITERAL (":\n", stdout); -+ } -+ -+ /* Read the directory entries, and insert the subfiles into the `cwd_file' -+ table. */ -+ -+ clear_files (); -+ -+ while (1) -+ { -+ /* Set errno to zero so we can distinguish between a readdir failure -+ and when readdir simply finds that there are no more entries. */ -+ errno = 0; -+ next = readdir (dirp); -+ if (next) -+ { -+ if (! file_ignored (next->d_name)) -+ { -+ enum filetype type = unknown; -+ -+#if HAVE_STRUCT_DIRENT_D_TYPE -+ switch (next->d_type) -+ { -+ case DT_BLK: type = blockdev; break; -+ case DT_CHR: type = chardev; break; -+ case DT_DIR: type = directory; break; -+ case DT_FIFO: type = fifo; break; -+ case DT_LNK: type = symbolic_link; break; -+ case DT_REG: type = normal; break; -+ case DT_SOCK: type = sock; break; -+# ifdef DT_WHT -+ case DT_WHT: type = whiteout; break; -+# endif -+ } -+#endif -+ total_blocks += gobble_file (next->d_name, type, -+ RELIABLE_D_INO (next), -+ false, name); -+ -+ /* In this narrow case, print out each name right away, so -+ ls uses constant memory while processing the entries of -+ this directory. Useful when there are many (millions) -+ of entries in a directory. */ -+ if (format == one_per_line && sort_type == sort_none -+ && !print_block_size && !recursive) -+ { -+ /* We must call sort_files in spite of -+ "sort_type == sort_none" for its initialization -+ of the sorted_file vector. */ -+ sort_files (); -+ print_current_files (); -+ clear_files (); -+ } -+ } -+ } -+ else if (errno != 0) -+ { -+ file_failure (command_line_arg, _("reading directory %s"), name); -+ if (errno != EOVERFLOW) -+ break; -+ } -+ else -+ break; -+ } -+ -+ if (closedir (dirp) != 0) -+ { -+ file_failure (command_line_arg, _("closing directory %s"), name); -+ /* Don't return; print whatever we got. */ -+ } -+ -+ /* Sort the directory contents. */ -+ sort_files (); -+ -+ /* If any member files are subdirectories, perhaps they should have their -+ contents listed rather than being mentioned here as files. */ -+ -+ if (recursive) -+ extract_dirs_from_files (name, command_line_arg); -+ -+ if (format == long_format || print_block_size) -+ { -+ const char *p; -+ char buf[LONGEST_HUMAN_READABLE + 1]; -+ -+ DIRED_INDENT (); -+ p = _("total"); -+ DIRED_FPUTS (p, stdout, strlen (p)); -+ DIRED_PUTCHAR (' '); -+ p = human_readable (total_blocks, buf, human_output_opts, -+ ST_NBLOCKSIZE, output_block_size); -+ DIRED_FPUTS (p, stdout, strlen (p)); -+ DIRED_PUTCHAR ('\n'); -+ } -+ -+ if (cwd_n_used) -+ print_current_files (); -+} -+ -+/* Add `pattern' to the list of patterns for which files that match are -+ not listed. */ -+ -+static void -+add_ignore_pattern (const char *pattern) -+{ -+ struct ignore_pattern *ignore; -+ -+ ignore = xmalloc (sizeof *ignore); -+ ignore->pattern = pattern; -+ /* Add it to the head of the linked list. */ -+ ignore->next = ignore_patterns; -+ ignore_patterns = ignore; -+} -+ -+/* Return true if one of the PATTERNS matches FILE. */ -+ -+static bool -+patterns_match (struct ignore_pattern const *patterns, char const *file) -+{ -+ struct ignore_pattern const *p; -+ for (p = patterns; p; p = p->next) -+ if (fnmatch (p->pattern, file, FNM_PERIOD) == 0) -+ return true; -+ return false; -+} -+ -+/* Return true if FILE should be ignored. */ -+ -+static bool -+file_ignored (char const *name) -+{ -+ return ((ignore_mode != IGNORE_MINIMAL -+ && name[0] == '.' -+ && (ignore_mode == IGNORE_DEFAULT || ! name[1 + (name[1] == '.')])) -+ || (ignore_mode == IGNORE_DEFAULT -+ && patterns_match (hide_patterns, name)) -+ || patterns_match (ignore_patterns, name)); -+} -+ -+/* POSIX requires that a file size be printed without a sign, even -+ when negative. Assume the typical case where negative sizes are -+ actually positive values that have wrapped around. */ -+ -+static uintmax_t -+unsigned_file_size (off_t size) -+{ -+ return size + (size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1); -+} -+ -+/* Enter and remove entries in the table `cwd_file'. */ -+ -+/* Empty the table of files. */ -+ -+static void -+clear_files (void) -+{ -+ size_t i; -+ -+ for (i = 0; i < cwd_n_used; i++) -+ { -+ struct fileinfo *f = sorted_file[i]; -+ free (f->name); -+ free (f->linkname); -+ if (f->scontext != UNKNOWN_SECURITY_CONTEXT) -+ freecon (f->scontext); -+ } -+ -+ cwd_n_used = 0; -+ any_has_acl = false; -+ inode_number_width = 0; -+ block_size_width = 0; -+ nlink_width = 0; -+ owner_width = 0; -+ group_width = 0; -+ author_width = 0; -+ scontext_width = 0; -+ major_device_number_width = 0; -+ minor_device_number_width = 0; -+ file_size_width = 0; -+} -+ -+/* Add a file to the current table of files. -+ Verify that the file exists, and print an error message if it does not. -+ Return the number of blocks that the file occupies. */ -+ -+static uintmax_t -+gobble_file (char const *name, enum filetype type, ino_t inode, -+ bool command_line_arg, char const *dirname) -+{ -+ uintmax_t blocks = 0; -+ struct fileinfo *f; -+ -+ /* An inode value prior to gobble_file necessarily came from readdir, -+ which is not used for command line arguments. */ -+ assert (! command_line_arg || inode == NOT_AN_INODE_NUMBER); -+ -+ if (cwd_n_used == cwd_n_alloc) -+ { -+ cwd_file = xnrealloc (cwd_file, cwd_n_alloc, 2 * sizeof *cwd_file); -+ cwd_n_alloc *= 2; -+ } -+ -+ f = &cwd_file[cwd_n_used]; -+ memset (f, '\0', sizeof *f); -+ f->stat.st_ino = inode; -+ f->filetype = type; -+ -+ if (command_line_arg -+ || format_needs_stat -+ /* When coloring a directory (we may know the type from -+ direct.d_type), we have to stat it in order to indicate -+ sticky and/or other-writable attributes. */ -+ || (type == directory && print_with_color) -+ /* When dereferencing symlinks, the inode and type must come from -+ stat, but readdir provides the inode and type of lstat. */ -+ || ((print_inode || format_needs_type) -+ && (type == symbolic_link || type == unknown) -+ && (dereference == DEREF_ALWAYS -+ || (command_line_arg && dereference != DEREF_NEVER) -+ || color_symlink_as_referent || check_symlink_color)) -+ /* Command line dereferences are already taken care of by the above -+ assertion that the inode number is not yet known. */ -+ || (print_inode && inode == NOT_AN_INODE_NUMBER) -+ || (format_needs_type -+ && (type == unknown || command_line_arg -+ /* --indicator-style=classify (aka -F) -+ requires that we stat each regular file -+ to see if it's executable. */ -+ || (type == normal && (indicator_style == classify -+ /* This is so that --color ends up -+ highlighting files with the executable -+ bit set even when options like -F are -+ not specified. */ -+ || (print_with_color -+ && is_colored (C_EXEC)) -+ ))))) -+ -+ { -+ /* Absolute name of this file. */ -+ char *absolute_name; -+ bool do_deref; -+ int err; -+ -+ if (name[0] == '/' || dirname[0] == 0) -+ absolute_name = (char *) name; -+ else -+ { -+ absolute_name = alloca (strlen (name) + strlen (dirname) + 2); -+ attach (absolute_name, dirname, name); -+ } -+ -+ switch (dereference) -+ { -+ case DEREF_ALWAYS: -+ err = stat (absolute_name, &f->stat); -+ do_deref = true; -+ break; -+ -+ case DEREF_COMMAND_LINE_ARGUMENTS: -+ case DEREF_COMMAND_LINE_SYMLINK_TO_DIR: -+ if (command_line_arg) -+ { -+ bool need_lstat; -+ err = stat (absolute_name, &f->stat); -+ do_deref = true; -+ -+ if (dereference == DEREF_COMMAND_LINE_ARGUMENTS) -+ break; -+ -+ need_lstat = (err < 0 -+ ? errno == ENOENT -+ : ! S_ISDIR (f->stat.st_mode)); -+ if (!need_lstat) -+ break; -+ -+ /* stat failed because of ENOENT, maybe indicating a dangling -+ symlink. Or stat succeeded, ABSOLUTE_NAME does not refer to a -+ directory, and --dereference-command-line-symlink-to-dir is -+ in effect. Fall through so that we call lstat instead. */ -+ } -+ -+ default: /* DEREF_NEVER */ -+ err = lstat (absolute_name, &f->stat); -+ do_deref = false; -+ break; -+ } -+ -+ if (err != 0) -+ { -+ /* Failure to stat a command line argument leads to -+ an exit status of 2. For other files, stat failure -+ provokes an exit status of 1. */ -+ file_failure (command_line_arg, -+ _("cannot access %s"), absolute_name); -+ if (command_line_arg) -+ return 0; -+ -+ f->name = xstrdup (name); -+ cwd_n_used++; -+ -+ return 0; -+ } -+ -+ f->stat_ok = true; -+ -+ if (format == long_format || print_scontext) -+ { -+ bool have_selinux = false; -+ bool have_acl = false; -+ int attr_len = (do_deref -+ ? getfilecon (absolute_name, &f->scontext) -+ : lgetfilecon (absolute_name, &f->scontext)); -+ err = (attr_len < 0); -+ -+ /* Contrary to its documented API, getfilecon may return 0, -+ yet set f->scontext to NULL (on at least Debian's libselinux1 -+ 2.0.15-2+b1), so work around that bug. -+ FIXME: remove this work-around in 2011, or whenever affected -+ versions of libselinux are long gone. */ -+ if (attr_len == 0) -+ { -+ err = 0; -+ f->scontext = xstrdup ("unlabeled"); -+ } -+ -+ if (err == 0) -+ have_selinux = ! STREQ ("unlabeled", f->scontext); -+ else -+ { -+ f->scontext = UNKNOWN_SECURITY_CONTEXT; -+ -+ /* When requesting security context information, don't make -+ ls fail just because the file (even a command line argument) -+ isn't on the right type of file system. I.e., a getfilecon -+ failure isn't in the same class as a stat failure. */ -+ if (errno == ENOTSUP || errno == EOPNOTSUPP || errno == ENODATA) -+ err = 0; -+ } -+ -+ if (err == 0 && format == long_format) -+ { -+ int n = file_has_acl (absolute_name, &f->stat); -+ err = (n < 0); -+ have_acl = (0 < n); -+ } -+ -+ f->acl_type = (!have_selinux && !have_acl -+ ? ACL_T_NONE -+ : (have_selinux && !have_acl -+ ? ACL_T_SELINUX_ONLY -+ : ACL_T_YES)); -+ any_has_acl |= f->acl_type != ACL_T_NONE; -+ -+ if (err) -+ error (0, errno, "%s", quotearg_colon (absolute_name)); -+ } -+ -+ if (S_ISLNK (f->stat.st_mode) -+ && (format == long_format || check_symlink_color)) -+ { -+ char *linkname; -+ struct stat linkstats; -+ -+ get_link_name (absolute_name, f, command_line_arg); -+ linkname = make_link_name (absolute_name, f->linkname); -+ -+ /* Avoid following symbolic links when possible, ie, when -+ they won't be traced and when no indicator is needed. */ -+ if (linkname -+ && (file_type <= indicator_style || check_symlink_color) -+ && stat (linkname, &linkstats) == 0) -+ { -+ f->linkok = true; -+ -+ /* Symbolic links to directories that are mentioned on the -+ command line are automatically traced if not being -+ listed as files. */ -+ if (!command_line_arg || format == long_format -+ || !S_ISDIR (linkstats.st_mode)) -+ { -+ /* Get the linked-to file's mode for the filetype indicator -+ in long listings. */ -+ f->linkmode = linkstats.st_mode; -+ } -+ } -+ free (linkname); -+ } -+ -+ /* When not distinguishing types of symlinks, pretend we know that -+ it is stat'able, so that it will be colored as a regular symlink, -+ and not as an orphan. */ -+ if (S_ISLNK (f->stat.st_mode) && !check_symlink_color) -+ f->linkok = true; -+ -+ if (S_ISLNK (f->stat.st_mode)) -+ f->filetype = symbolic_link; -+ else if (S_ISDIR (f->stat.st_mode)) -+ { -+ if (command_line_arg && !immediate_dirs) -+ f->filetype = arg_directory; -+ else -+ f->filetype = directory; -+ } -+ else -+ f->filetype = normal; -+ -+ blocks = ST_NBLOCKS (f->stat); -+ if (format == long_format || print_block_size) -+ { -+ char buf[LONGEST_HUMAN_READABLE + 1]; -+ int len = mbswidth (human_readable (blocks, buf, human_output_opts, -+ ST_NBLOCKSIZE, output_block_size), -+ 0); -+ if (block_size_width < len) -+ block_size_width = len; -+ } -+ -+ if (format == long_format) -+ { -+ if (print_owner) -+ { -+ int len = format_user_width (f->stat.st_uid); -+ if (owner_width < len) -+ owner_width = len; -+ } -+ -+ if (print_group) -+ { -+ int len = format_group_width (f->stat.st_gid); -+ if (group_width < len) -+ group_width = len; -+ } -+ -+ if (print_author) -+ { -+ int len = format_user_width (f->stat.st_author); -+ if (author_width < len) -+ author_width = len; -+ } -+ } -+ -+ if (print_scontext) -+ { -+ int len = strlen (f->scontext); -+ if (scontext_width < len) -+ scontext_width = len; -+ } -+ -+ if (format == long_format) -+ { -+ char b[INT_BUFSIZE_BOUND (uintmax_t)]; -+ int b_len = strlen (umaxtostr (f->stat.st_nlink, b)); -+ if (nlink_width < b_len) -+ nlink_width = b_len; -+ -+ if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode)) -+ { -+ char buf[INT_BUFSIZE_BOUND (uintmax_t)]; -+ int len = strlen (umaxtostr (major (f->stat.st_rdev), buf)); -+ if (major_device_number_width < len) -+ major_device_number_width = len; -+ len = strlen (umaxtostr (minor (f->stat.st_rdev), buf)); -+ if (minor_device_number_width < len) -+ minor_device_number_width = len; -+ len = major_device_number_width + 2 + minor_device_number_width; -+ if (file_size_width < len) -+ file_size_width = len; -+ } -+ else -+ { -+ char buf[LONGEST_HUMAN_READABLE + 1]; -+ uintmax_t size = unsigned_file_size (f->stat.st_size); -+ int len = mbswidth (human_readable (size, buf, human_output_opts, -+ 1, file_output_block_size), -+ 0); -+ if (file_size_width < len) -+ file_size_width = len; -+ } -+ } -+ } -+ -+ if (print_inode) -+ { -+ char buf[INT_BUFSIZE_BOUND (uintmax_t)]; -+ int len = strlen (umaxtostr (f->stat.st_ino, buf)); -+ if (inode_number_width < len) -+ inode_number_width = len; -+ } -+ -+ f->name = xstrdup (name); -+ cwd_n_used++; -+ -+ return blocks; -+} -+ -+/* Return true if F refers to a directory. */ -+static bool -+is_directory (const struct fileinfo *f) -+{ -+ return f->filetype == directory || f->filetype == arg_directory; -+} -+ -+/* Put the name of the file that FILENAME is a symbolic link to -+ into the LINKNAME field of `f'. COMMAND_LINE_ARG indicates whether -+ FILENAME is a command-line argument. */ -+ -+static void -+get_link_name (char const *filename, struct fileinfo *f, bool command_line_arg) -+{ -+ f->linkname = areadlink_with_size (filename, f->stat.st_size); -+ if (f->linkname == NULL) -+ file_failure (command_line_arg, _("cannot read symbolic link %s"), -+ filename); -+} -+ -+/* If `linkname' is a relative name and `name' contains one or more -+ leading directories, return `linkname' with those directories -+ prepended; otherwise, return a copy of `linkname'. -+ If `linkname' is zero, return zero. */ -+ -+static char * -+make_link_name (char const *name, char const *linkname) -+{ -+ char *linkbuf; -+ size_t bufsiz; -+ -+ if (!linkname) -+ return NULL; -+ -+ if (*linkname == '/') -+ return xstrdup (linkname); -+ -+ /* The link is to a relative name. Prepend any leading directory -+ in `name' to the link name. */ -+ linkbuf = strrchr (name, '/'); -+ if (linkbuf == 0) -+ return xstrdup (linkname); -+ -+ bufsiz = linkbuf - name + 1; -+ linkbuf = xmalloc (bufsiz + strlen (linkname) + 1); -+ strncpy (linkbuf, name, bufsiz); -+ strcpy (linkbuf + bufsiz, linkname); -+ return linkbuf; -+} -+ -+/* Return true if the last component of NAME is `.' or `..' -+ This is so we don't try to recurse on `././././. ...' */ -+ -+static bool -+basename_is_dot_or_dotdot (const char *name) -+{ -+ char const *base = last_component (name); -+ return dot_or_dotdot (base); -+} -+ -+/* Remove any entries from CWD_FILE that are for directories, -+ and queue them to be listed as directories instead. -+ DIRNAME is the prefix to prepend to each dirname -+ to make it correct relative to ls's working dir; -+ if it is null, no prefix is needed and "." and ".." should not be ignored. -+ If COMMAND_LINE_ARG is true, this directory was mentioned at the top level, -+ This is desirable when processing directories recursively. */ -+ -+static void -+extract_dirs_from_files (char const *dirname, bool command_line_arg) -+{ -+ size_t i; -+ size_t j; -+ bool ignore_dot_and_dot_dot = (dirname != NULL); -+ -+ if (dirname && LOOP_DETECT) -+ { -+ /* Insert a marker entry first. When we dequeue this marker entry, -+ we'll know that DIRNAME has been processed and may be removed -+ from the set of active directories. */ -+ queue_directory (NULL, dirname, false); -+ } -+ -+ /* Queue the directories last one first, because queueing reverses the -+ order. */ -+ for (i = cwd_n_used; i-- != 0; ) -+ { -+ struct fileinfo *f = sorted_file[i]; -+ -+ if (is_directory (f) -+ && (! ignore_dot_and_dot_dot -+ || ! basename_is_dot_or_dotdot (f->name))) -+ { -+ if (!dirname || f->name[0] == '/') -+ queue_directory (f->name, f->linkname, command_line_arg); -+ else -+ { -+ char *name = file_name_concat (dirname, f->name, NULL); -+ queue_directory (name, f->linkname, command_line_arg); -+ free (name); -+ } -+ if (f->filetype == arg_directory) -+ free (f->name); -+ } -+ } -+ -+ /* Now delete the directories from the table, compacting all the remaining -+ entries. */ -+ -+ for (i = 0, j = 0; i < cwd_n_used; i++) -+ { -+ struct fileinfo *f = sorted_file[i]; -+ sorted_file[j] = f; -+ j += (f->filetype != arg_directory); -+ } -+ cwd_n_used = j; -+} -+ -+/* Use strcoll to compare strings in this locale. If an error occurs, -+ report an error and longjmp to failed_strcoll. */ -+ -+static jmp_buf failed_strcoll; -+ -+static int -+xstrcoll (char const *a, char const *b) -+{ -+ int diff; -+ errno = 0; -+ diff = strcoll (a, b); -+ if (errno) -+ { -+ error (0, errno, _("cannot compare file names %s and %s"), -+ quote_n (0, a), quote_n (1, b)); -+ set_exit_status (false); -+ longjmp (failed_strcoll, 1); -+ } -+ return diff; -+} -+ -+/* Comparison routines for sorting the files. */ -+ -+typedef void const *V; -+typedef int (*qsortFunc)(V a, V b); -+ -+/* Used below in DEFINE_SORT_FUNCTIONS for _df_ sort function variants. -+ The do { ... } while(0) makes it possible to use the macro more like -+ a statement, without violating C89 rules: */ -+#define DIRFIRST_CHECK(a, b) \ -+ do \ -+ { \ -+ bool a_is_dir = is_directory ((struct fileinfo const *) a); \ -+ bool b_is_dir = is_directory ((struct fileinfo const *) b); \ -+ if (a_is_dir && !b_is_dir) \ -+ return -1; /* a goes before b */ \ -+ if (!a_is_dir && b_is_dir) \ -+ return 1; /* b goes before a */ \ -+ } \ -+ while (0) -+ -+/* Define the 8 different sort function variants required for each sortkey. -+ KEY_NAME is a token describing the sort key, e.g., ctime, atime, size. -+ KEY_CMP_FUNC is a function to compare records based on that key, e.g., -+ ctime_cmp, atime_cmp, size_cmp. Append KEY_NAME to the string, -+ '[rev_][x]str{cmp|coll}[_df]_', to create each function name. */ -+#define DEFINE_SORT_FUNCTIONS(key_name, key_cmp_func) \ -+ /* direct, non-dirfirst versions */ \ -+ static int xstrcoll_##key_name (V a, V b) \ -+ { return key_cmp_func (a, b, xstrcoll); } \ -+ static int strcmp_##key_name (V a, V b) \ -+ { return key_cmp_func (a, b, strcmp); } \ -+ \ -+ /* reverse, non-dirfirst versions */ \ -+ static int rev_xstrcoll_##key_name (V a, V b) \ -+ { return key_cmp_func (b, a, xstrcoll); } \ -+ static int rev_strcmp_##key_name (V a, V b) \ -+ { return key_cmp_func (b, a, strcmp); } \ -+ \ -+ /* direct, dirfirst versions */ \ -+ static int xstrcoll_df_##key_name (V a, V b) \ -+ { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, xstrcoll); } \ -+ static int strcmp_df_##key_name (V a, V b) \ -+ { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, strcmp); } \ -+ \ -+ /* reverse, dirfirst versions */ \ -+ static int rev_xstrcoll_df_##key_name (V a, V b) \ -+ { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, xstrcoll); } \ -+ static int rev_strcmp_df_##key_name (V a, V b) \ -+ { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, strcmp); } -+ -+static inline int -+cmp_ctime (struct fileinfo const *a, struct fileinfo const *b, -+ int (*cmp) (char const *, char const *)) -+{ -+ int diff = timespec_cmp (get_stat_ctime (&b->stat), -+ get_stat_ctime (&a->stat)); -+ return diff ? diff : cmp (a->name, b->name); -+} -+ -+static inline int -+cmp_mtime (struct fileinfo const *a, struct fileinfo const *b, -+ int (*cmp) (char const *, char const *)) -+{ -+ int diff = timespec_cmp (get_stat_mtime (&b->stat), -+ get_stat_mtime (&a->stat)); -+ return diff ? diff : cmp (a->name, b->name); -+} -+ -+static inline int -+cmp_atime (struct fileinfo const *a, struct fileinfo const *b, -+ int (*cmp) (char const *, char const *)) -+{ -+ int diff = timespec_cmp (get_stat_atime (&b->stat), -+ get_stat_atime (&a->stat)); -+ return diff ? diff : cmp (a->name, b->name); -+} -+ -+static inline int -+cmp_size (struct fileinfo const *a, struct fileinfo const *b, -+ int (*cmp) (char const *, char const *)) -+{ -+ int diff = longdiff (b->stat.st_size, a->stat.st_size); -+ return diff ? diff : cmp (a->name, b->name); -+} -+ -+static inline int -+cmp_name (struct fileinfo const *a, struct fileinfo const *b, -+ int (*cmp) (char const *, char const *)) -+{ -+ return cmp (a->name, b->name); -+} -+ -+/* Compare file extensions. Files with no extension are `smallest'. -+ If extensions are the same, compare by filenames instead. */ -+ -+static inline int -+cmp_extension (struct fileinfo const *a, struct fileinfo const *b, -+ int (*cmp) (char const *, char const *)) -+{ -+ char const *base1 = strrchr (a->name, '.'); -+ char const *base2 = strrchr (b->name, '.'); -+ int diff = cmp (base1 ? base1 : "", base2 ? base2 : ""); -+ return diff ? diff : cmp (a->name, b->name); -+} -+ -+DEFINE_SORT_FUNCTIONS (ctime, cmp_ctime) -+DEFINE_SORT_FUNCTIONS (mtime, cmp_mtime) -+DEFINE_SORT_FUNCTIONS (atime, cmp_atime) -+DEFINE_SORT_FUNCTIONS (size, cmp_size) -+DEFINE_SORT_FUNCTIONS (name, cmp_name) -+DEFINE_SORT_FUNCTIONS (extension, cmp_extension) -+ -+/* Compare file versions. -+ Unlike all other compare functions above, cmp_version depends only -+ on filevercmp, which does not fail (even for locale reasons), and does not -+ need a secondary sort key. See lib/filevercmp.h for function description. -+ -+ All the other sort options, in fact, need xstrcoll and strcmp variants, -+ because they all use a string comparison (either as the primary or secondary -+ sort key), and xstrcoll has the ability to do a longjmp if strcoll fails for -+ locale reasons. Last, strverscmp is ALWAYS available in coreutils, -+ thanks to the gnulib library. */ -+static inline int -+cmp_version (struct fileinfo const *a, struct fileinfo const *b) -+{ -+ return filevercmp (a->name, b->name); -+} -+ -+static int xstrcoll_version (V a, V b) -+{ return cmp_version (a, b); } -+static int rev_xstrcoll_version (V a, V b) -+{ return cmp_version (b, a); } -+static int xstrcoll_df_version (V a, V b) -+{ DIRFIRST_CHECK (a, b); return cmp_version (a, b); } -+static int rev_xstrcoll_df_version (V a, V b) -+{ DIRFIRST_CHECK (a, b); return cmp_version (b, a); } -+ -+ -+/* We have 2^3 different variants for each sortkey function -+ (for 3 independent sort modes). -+ The function pointers stored in this array must be dereferenced as: -+ -+ sort_variants[sort_key][use_strcmp][reverse][dirs_first] -+ -+ Note that the order in which sortkeys are listed in the function pointer -+ array below is defined by the order of the elements in the time_type and -+ sort_type enums! */ -+ -+#define LIST_SORTFUNCTION_VARIANTS(key_name) \ -+ { \ -+ { \ -+ { xstrcoll_##key_name, xstrcoll_df_##key_name }, \ -+ { rev_xstrcoll_##key_name, rev_xstrcoll_df_##key_name }, \ -+ }, \ -+ { \ -+ { strcmp_##key_name, strcmp_df_##key_name }, \ -+ { rev_strcmp_##key_name, rev_strcmp_df_##key_name }, \ -+ } \ -+ } -+ -+static qsortFunc const sort_functions[][2][2][2] = -+ { -+ LIST_SORTFUNCTION_VARIANTS (name), -+ LIST_SORTFUNCTION_VARIANTS (extension), -+ LIST_SORTFUNCTION_VARIANTS (size), -+ -+ { -+ { -+ { xstrcoll_version, xstrcoll_df_version }, -+ { rev_xstrcoll_version, rev_xstrcoll_df_version }, -+ }, -+ -+ /* We use NULL for the strcmp variants of version comparison -+ since as explained in cmp_version definition, version comparison -+ does not rely on xstrcoll, so it will never longjmp, and never -+ need to try the strcmp fallback. */ -+ { -+ { NULL, NULL }, -+ { NULL, NULL }, -+ } -+ }, -+ -+ /* last are time sort functions */ -+ LIST_SORTFUNCTION_VARIANTS (mtime), -+ LIST_SORTFUNCTION_VARIANTS (ctime), -+ LIST_SORTFUNCTION_VARIANTS (atime) -+ }; -+ -+/* The number of sortkeys is calculated as -+ the number of elements in the sort_type enum (i.e. sort_numtypes) + -+ the number of elements in the time_type enum (i.e. time_numtypes) - 1 -+ This is because when sort_type==sort_time, we have up to -+ time_numtypes possible sortkeys. -+ -+ This line verifies at compile-time that the array of sort functions has been -+ initialized for all possible sortkeys. */ -+verify (ARRAY_CARDINALITY (sort_functions) -+ == sort_numtypes + time_numtypes - 1 ); -+ -+/* Set up SORTED_FILE to point to the in-use entries in CWD_FILE, in order. */ -+ -+static void -+initialize_ordering_vector (void) -+{ -+ size_t i; -+ for (i = 0; i < cwd_n_used; i++) -+ sorted_file[i] = &cwd_file[i]; -+} -+ -+/* Sort the files now in the table. */ -+ -+static void -+sort_files (void) -+{ -+ bool use_strcmp; -+ -+ if (sorted_file_alloc < cwd_n_used + cwd_n_used / 2) -+ { -+ free (sorted_file); -+ sorted_file = xnmalloc (cwd_n_used, 3 * sizeof *sorted_file); -+ sorted_file_alloc = 3 * cwd_n_used; -+ } -+ -+ initialize_ordering_vector (); -+ -+ if (sort_type == sort_none) -+ return; -+ -+ /* Try strcoll. If it fails, fall back on strcmp. We can't safely -+ ignore strcoll failures, as a failing strcoll might be a -+ comparison function that is not a total order, and if we ignored -+ the failure this might cause qsort to dump core. */ -+ -+ if (! setjmp (failed_strcoll)) -+ use_strcmp = false; /* strcoll() succeeded */ -+ else -+ { -+ use_strcmp = true; -+ assert (sort_type != sort_version); -+ initialize_ordering_vector (); -+ } -+ -+ /* When sort_type == sort_time, use time_type as subindex. */ -+ mpsort ((void const **) sorted_file, cwd_n_used, -+ sort_functions[sort_type + (sort_type == sort_time ? time_type : 0)] -+ [use_strcmp][sort_reverse] -+ [directories_first]); -+} -+ -+/* List all the files now in the table. */ -+ -+static void -+print_current_files (void) -+{ -+ size_t i; -+ -+ switch (format) -+ { -+ case one_per_line: -+ for (i = 0; i < cwd_n_used; i++) -+ { -+ print_file_name_and_frills (sorted_file[i], 0); -+ putchar ('\n'); -+ } -+ break; -+ -+ case many_per_line: -+ print_many_per_line (); -+ break; -+ -+ case horizontal: -+ print_horizontal (); -+ break; -+ -+ case with_commas: -+ print_with_commas (); -+ break; -+ -+ case long_format: -+ for (i = 0; i < cwd_n_used; i++) -+ { -+ print_long_format (sorted_file[i]); -+ DIRED_PUTCHAR ('\n'); -+ } -+ break; -+ } -+} -+ -+/* Replace the first %b with precomputed aligned month names. -+ Note on glibc-2.7 at least, this speeds up the whole `ls -lU` -+ process by around 17%, compared to letting strftime() handle the %b. */ -+ -+static size_t -+align_nstrftime (char *buf, size_t size, char const *fmt, struct tm const *tm, -+ int __utc, int __ns) -+{ -+ const char *nfmt = fmt; -+ /* In the unlikely event that rpl_fmt below is not large enough, -+ the replacement is not done. A malloc here slows ls down by 2% */ -+ char rpl_fmt[sizeof (abmon[0]) + 100]; -+ const char *pb; -+ if (required_mon_width && (pb = strstr (fmt, "%b"))) -+ { -+ if (strlen (fmt) < (sizeof (rpl_fmt) - sizeof (abmon[0]) + 2)) -+ { -+ char *pfmt = rpl_fmt; -+ nfmt = rpl_fmt; -+ -+ pfmt = mempcpy (pfmt, fmt, pb - fmt); -+ pfmt = stpcpy (pfmt, abmon[tm->tm_mon]); -+ strcpy (pfmt, pb + 2); -+ } -+ } -+ size_t ret = nstrftime (buf, size, nfmt, tm, __utc, __ns); -+ return ret; -+} -+ -+/* Return the expected number of columns in a long-format time stamp, -+ or zero if it cannot be calculated. */ -+ -+static int -+long_time_expected_width (void) -+{ -+ static int width = -1; -+ -+ if (width < 0) -+ { -+ time_t epoch = 0; -+ struct tm const *tm = localtime (&epoch); -+ char buf[TIME_STAMP_LEN_MAXIMUM + 1]; -+ -+ /* In case you're wondering if localtime can fail with an input time_t -+ value of 0, let's just say it's very unlikely, but not inconceivable. -+ The TZ environment variable would have to specify a time zone that -+ is 2**31-1900 years or more ahead of UTC. This could happen only on -+ a 64-bit system that blindly accepts e.g., TZ=UTC+20000000000000. -+ However, this is not possible with Solaris 10 or glibc-2.3.5, since -+ their implementations limit the offset to 167:59 and 24:00, resp. */ -+ if (tm) -+ { -+ size_t len = -+ align_nstrftime (buf, sizeof buf, long_time_format[0], tm, 0, 0); -+ if (len != 0) -+ width = mbsnwidth (buf, len, 0); -+ } -+ -+ if (width < 0) -+ width = 0; -+ } -+ -+ return width; -+} -+ -+/* Print the user or group name NAME, with numeric id ID, using a -+ print width of WIDTH columns. */ -+ -+static void -+format_user_or_group (char const *name, unsigned long int id, int width) -+{ -+ size_t len; -+ -+ if (name) -+ { -+ int width_gap = width - mbswidth (name, 0); -+ int pad = MAX (0, width_gap); -+ fputs (name, stdout); -+ len = strlen (name) + pad; -+ -+ do -+ putchar (' '); -+ while (pad--); -+ } -+ else -+ { -+ printf ("%*lu ", width, id); -+ len = width; -+ } -+ -+ dired_pos += len + 1; -+} -+ -+/* Print the name or id of the user with id U, using a print width of -+ WIDTH. */ -+ -+static void -+format_user (uid_t u, int width, bool stat_ok) -+{ -+ format_user_or_group (! stat_ok ? "?" : -+ (numeric_ids ? NULL : getuser (u)), u, width); -+} -+ -+/* Likewise, for groups. */ -+ -+static void -+format_group (gid_t g, int width, bool stat_ok) -+{ -+ format_user_or_group (! stat_ok ? "?" : -+ (numeric_ids ? NULL : getgroup (g)), g, width); -+} -+ -+/* Return the number of columns that format_user_or_group will print. */ -+ -+static int -+format_user_or_group_width (char const *name, unsigned long int id) -+{ -+ if (name) -+ { -+ int len = mbswidth (name, 0); -+ return MAX (0, len); -+ } -+ else -+ { -+ char buf[INT_BUFSIZE_BOUND (unsigned long int)]; -+ sprintf (buf, "%lu", id); -+ return strlen (buf); -+ } -+} -+ -+/* Return the number of columns that format_user will print. */ -+ -+static int -+format_user_width (uid_t u) -+{ -+ return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u); -+} -+ -+/* Likewise, for groups. */ -+ -+static int -+format_group_width (gid_t g) -+{ -+ return format_user_or_group_width (numeric_ids ? NULL : getgroup (g), g); -+} -+ -+/* Return a pointer to a formatted version of F->stat.st_ino, -+ possibly using buffer, BUF, of length BUFLEN, which must be at least -+ INT_BUFSIZE_BOUND (uintmax_t) bytes. */ -+static char * -+format_inode (char *buf, size_t buflen, const struct fileinfo *f) -+{ -+ assert (INT_BUFSIZE_BOUND (uintmax_t) <= buflen); -+ return (f->stat_ok && f->stat.st_ino != NOT_AN_INODE_NUMBER -+ ? umaxtostr (f->stat.st_ino, buf) -+ : (char *) "?"); -+} -+ -+/* Print information about F in long format. */ -+static void -+print_long_format (const struct fileinfo *f) -+{ -+ char modebuf[12]; -+ char buf -+ [LONGEST_HUMAN_READABLE + 1 /* inode */ -+ + LONGEST_HUMAN_READABLE + 1 /* size in blocks */ -+ + sizeof (modebuf) - 1 + 1 /* mode string */ -+ + INT_BUFSIZE_BOUND (uintmax_t) /* st_nlink */ -+ + LONGEST_HUMAN_READABLE + 2 /* major device number */ -+ + LONGEST_HUMAN_READABLE + 1 /* minor device number */ -+ + TIME_STAMP_LEN_MAXIMUM + 1 /* max length of time/date */ -+ ]; -+ size_t s; -+ char *p; -+ struct timespec when_timespec; -+ struct tm *when_local; -+ -+ /* Compute the mode string, except remove the trailing space if no -+ file in this directory has an ACL or SELinux security context. */ -+ if (f->stat_ok) -+ filemodestring (&f->stat, modebuf); -+ else -+ { -+ modebuf[0] = filetype_letter[f->filetype]; -+ memset (modebuf + 1, '?', 10); -+ modebuf[11] = '\0'; -+ } -+ if (! any_has_acl) -+ modebuf[10] = '\0'; -+ else if (f->acl_type == ACL_T_SELINUX_ONLY) -+ modebuf[10] = '.'; -+ else if (f->acl_type == ACL_T_YES) -+ modebuf[10] = '+'; -+ -+ switch (time_type) -+ { -+ case time_ctime: -+ when_timespec = get_stat_ctime (&f->stat); -+ break; -+ case time_mtime: -+ when_timespec = get_stat_mtime (&f->stat); -+ break; -+ case time_atime: -+ when_timespec = get_stat_atime (&f->stat); -+ break; -+ default: -+ abort (); -+ } -+ -+ p = buf; -+ -+ if (print_inode) -+ { -+ char hbuf[INT_BUFSIZE_BOUND (uintmax_t)]; -+ sprintf (p, "%*s ", inode_number_width, -+ format_inode (hbuf, sizeof hbuf, f)); -+ /* Increment by strlen (p) here, rather than by inode_number_width + 1. -+ The latter is wrong when inode_number_width is zero. */ -+ p += strlen (p); -+ } -+ -+ if (print_block_size) -+ { -+ char hbuf[LONGEST_HUMAN_READABLE + 1]; -+ char const *blocks = -+ (! f->stat_ok -+ ? "?" -+ : human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts, -+ ST_NBLOCKSIZE, output_block_size)); -+ int pad; -+ for (pad = block_size_width - mbswidth (blocks, 0); 0 < pad; pad--) -+ *p++ = ' '; -+ while ((*p++ = *blocks++)) -+ continue; -+ p[-1] = ' '; -+ } -+ -+ /* The last byte of the mode string is the POSIX -+ "optional alternate access method flag". */ -+ { -+ char hbuf[INT_BUFSIZE_BOUND (uintmax_t)]; -+ sprintf (p, "%s %*s ", modebuf, nlink_width, -+ ! f->stat_ok ? "?" : umaxtostr (f->stat.st_nlink, hbuf)); -+ } -+ /* Increment by strlen (p) here, rather than by, e.g., -+ sizeof modebuf - 2 + any_has_acl + 1 + nlink_width + 1. -+ The latter is wrong when nlink_width is zero. */ -+ p += strlen (p); -+ -+ DIRED_INDENT (); -+ -+ if (print_owner || print_group || print_author || print_scontext) -+ { -+ DIRED_FPUTS (buf, stdout, p - buf); -+ -+ if (print_owner) -+ format_user (f->stat.st_uid, owner_width, f->stat_ok); -+ -+ if (print_group) -+ format_group (f->stat.st_gid, group_width, f->stat_ok); -+ -+ if (print_author) -+ format_user (f->stat.st_author, author_width, f->stat_ok); -+ -+ if (print_scontext) -+ format_user_or_group (f->scontext, 0, scontext_width); -+ -+ p = buf; -+ } -+ -+ if (f->stat_ok -+ && (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))) -+ { -+ char majorbuf[INT_BUFSIZE_BOUND (uintmax_t)]; -+ char minorbuf[INT_BUFSIZE_BOUND (uintmax_t)]; -+ int blanks_width = (file_size_width -+ - (major_device_number_width + 2 -+ + minor_device_number_width)); -+ sprintf (p, "%*s, %*s ", -+ major_device_number_width + MAX (0, blanks_width), -+ umaxtostr (major (f->stat.st_rdev), majorbuf), -+ minor_device_number_width, -+ umaxtostr (minor (f->stat.st_rdev), minorbuf)); -+ p += file_size_width + 1; -+ } -+ else -+ { -+ char hbuf[LONGEST_HUMAN_READABLE + 1]; -+ char const *size = -+ (! f->stat_ok -+ ? "?" -+ : human_readable (unsigned_file_size (f->stat.st_size), -+ hbuf, human_output_opts, 1, file_output_block_size)); -+ int pad; -+ for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--) -+ *p++ = ' '; -+ while ((*p++ = *size++)) -+ continue; -+ p[-1] = ' '; -+ } -+ -+ when_local = localtime (&when_timespec.tv_sec); -+ s = 0; -+ *p = '\1'; -+ -+ if (f->stat_ok && when_local) -+ { -+ struct timespec six_months_ago; -+ bool recent; -+ char const *fmt; -+ -+ /* If the file appears to be in the future, update the current -+ time, in case the file happens to have been modified since -+ the last time we checked the clock. */ -+ if (timespec_cmp (current_time, when_timespec) < 0) -+ { -+ /* Note that gettime may call gettimeofday which, on some non- -+ compliant systems, clobbers the buffer used for localtime's result. -+ But it's ok here, because we use a gettimeofday wrapper that -+ saves and restores the buffer around the gettimeofday call. */ -+ gettime (¤t_time); -+ } -+ -+ /* Consider a time to be recent if it is within the past six -+ months. A Gregorian year has 365.2425 * 24 * 60 * 60 == -+ 31556952 seconds on the average. Write this value as an -+ integer constant to avoid floating point hassles. */ -+ six_months_ago.tv_sec = current_time.tv_sec - 31556952 / 2; -+ six_months_ago.tv_nsec = current_time.tv_nsec; -+ -+ recent = (timespec_cmp (six_months_ago, when_timespec) < 0 -+ && (timespec_cmp (when_timespec, current_time) < 0)); -+ fmt = long_time_format[recent]; -+ -+ /* We assume here that all time zones are offset from UTC by a -+ whole number of seconds. */ -+ s = align_nstrftime (p, TIME_STAMP_LEN_MAXIMUM + 1, fmt, -+ when_local, 0, when_timespec.tv_nsec); -+ } -+ -+ if (s || !*p) -+ { -+ p += s; -+ *p++ = ' '; -+ -+ /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it. */ -+ *p = '\0'; -+ } -+ else -+ { -+ /* The time cannot be converted using the desired format, so -+ print it as a huge integer number of seconds. */ -+ char hbuf[INT_BUFSIZE_BOUND (intmax_t)]; -+ sprintf (p, "%*s ", long_time_expected_width (), -+ (! f->stat_ok -+ ? "?" -+ : timetostr (when_timespec.tv_sec, hbuf))); -+ /* FIXME: (maybe) We discarded when_timespec.tv_nsec. */ -+ p += strlen (p); -+ } -+ -+ DIRED_FPUTS (buf, stdout, p - buf); -+ size_t w = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok, -+ f->stat_ok, f->filetype, &dired_obstack, -+ f->stat.st_nlink, p - buf); -+ -+ if (f->filetype == symbolic_link) -+ { -+ if (f->linkname) -+ { -+ DIRED_FPUTS_LITERAL (" -> ", stdout); -+ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, -+ f->stat_ok, f->filetype, NULL, -+ f->stat.st_nlink, (p - buf) + w + 4); -+ if (indicator_style != none) -+ print_type_indicator (true, f->linkmode, unknown); -+ } -+ } -+ else if (indicator_style != none) -+ print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); -+} -+ -+/* Output to OUT a quoted representation of the file name NAME, -+ using OPTIONS to control quoting. Produce no output if OUT is NULL. -+ Store the number of screen columns occupied by NAME's quoted -+ representation into WIDTH, if non-NULL. Return the number of bytes -+ produced. */ -+ -+static size_t -+quote_name (FILE *out, const char *name, struct quoting_options const *options, -+ size_t *width) -+{ -+ char smallbuf[BUFSIZ]; -+ size_t len = quotearg_buffer (smallbuf, sizeof smallbuf, name, -1, options); -+ char *buf; -+ size_t displayed_width IF_LINT (= 0); -+ -+ if (len < sizeof smallbuf) -+ buf = smallbuf; -+ else -+ { -+ buf = alloca (len + 1); -+ quotearg_buffer (buf, len + 1, name, -1, options); -+ } -+ -+ if (qmark_funny_chars) -+ { -+ if (MB_CUR_MAX > 1) -+ { -+ char const *p = buf; -+ char const *plimit = buf + len; -+ char *q = buf; -+ displayed_width = 0; -+ -+ while (p < plimit) -+ switch (*p) -+ { -+ case ' ': case '!': case '"': case '#': case '%': -+ case '&': case '\'': case '(': case ')': case '*': -+ case '+': case ',': case '-': case '.': case '/': -+ case '0': case '1': case '2': case '3': case '4': -+ case '5': case '6': case '7': case '8': case '9': -+ case ':': case ';': case '<': case '=': case '>': -+ case '?': -+ case 'A': case 'B': case 'C': case 'D': case 'E': -+ case 'F': case 'G': case 'H': case 'I': case 'J': -+ case 'K': case 'L': case 'M': case 'N': case 'O': -+ case 'P': case 'Q': case 'R': case 'S': case 'T': -+ case 'U': case 'V': case 'W': case 'X': case 'Y': -+ case 'Z': -+ case '[': case '\\': case ']': case '^': case '_': -+ case 'a': case 'b': case 'c': case 'd': case 'e': -+ case 'f': case 'g': case 'h': case 'i': case 'j': -+ case 'k': case 'l': case 'm': case 'n': case 'o': -+ case 'p': case 'q': case 'r': case 's': case 't': -+ case 'u': case 'v': case 'w': case 'x': case 'y': -+ case 'z': case '{': case '|': case '}': case '~': -+ /* These characters are printable ASCII characters. */ -+ *q++ = *p++; -+ displayed_width += 1; -+ break; -+ default: -+ /* If we have a multibyte sequence, copy it until we -+ reach its end, replacing each non-printable multibyte -+ character with a single question mark. */ -+ { -+ DECLARE_ZEROED_AGGREGATE (mbstate_t, mbstate); -+ do -+ { -+ wchar_t wc; -+ size_t bytes; -+ int w; -+ -+ bytes = mbrtowc (&wc, p, plimit - p, &mbstate); -+ -+ if (bytes == (size_t) -1) -+ { -+ /* An invalid multibyte sequence was -+ encountered. Skip one input byte, and -+ put a question mark. */ -+ p++; -+ *q++ = '?'; -+ displayed_width += 1; -+ break; -+ } -+ -+ if (bytes == (size_t) -2) -+ { -+ /* An incomplete multibyte character -+ at the end. Replace it entirely with -+ a question mark. */ -+ p = plimit; -+ *q++ = '?'; -+ displayed_width += 1; -+ break; -+ } -+ -+ if (bytes == 0) -+ /* A null wide character was encountered. */ -+ bytes = 1; -+ -+ w = wcwidth (wc); -+ if (w >= 0) -+ { -+ /* A printable multibyte character. -+ Keep it. */ -+ for (; bytes > 0; --bytes) -+ *q++ = *p++; -+ displayed_width += w; -+ } -+ else -+ { -+ /* An unprintable multibyte character. -+ Replace it entirely with a question -+ mark. */ -+ p += bytes; -+ *q++ = '?'; -+ displayed_width += 1; -+ } -+ } -+ while (! mbsinit (&mbstate)); -+ } -+ break; -+ } -+ -+ /* The buffer may have shrunk. */ -+ len = q - buf; -+ } -+ else -+ { -+ char *p = buf; -+ char const *plimit = buf + len; -+ -+ while (p < plimit) -+ { -+ if (! isprint (to_uchar (*p))) -+ *p = '?'; -+ p++; -+ } -+ displayed_width = len; -+ } -+ } -+ else if (width != NULL) -+ { -+ if (MB_CUR_MAX > 1) -+ displayed_width = mbsnwidth (buf, len, 0); -+ else -+ { -+ char const *p = buf; -+ char const *plimit = buf + len; -+ -+ displayed_width = 0; -+ while (p < plimit) -+ { -+ if (isprint (to_uchar (*p))) -+ displayed_width++; -+ p++; -+ } -+ } -+ } -+ -+ if (out != NULL) -+ fwrite (buf, 1, len, out); -+ if (width != NULL) -+ *width = displayed_width; -+ return len; -+} -+ -+static size_t -+print_name_with_quoting (const char *p, mode_t mode, int linkok, -+ bool stat_ok, enum filetype type, -+ struct obstack *stack, nlink_t nlink, -+ size_t start_col) -+{ -+ bool used_color_this_time -+ = (print_with_color -+ && print_color_indicator (p, mode, linkok, stat_ok, type, nlink)); -+ -+ if (stack) -+ PUSH_CURRENT_DIRED_POS (stack); -+ -+ size_t width = quote_name (stdout, p, filename_quoting_options, NULL); -+ dired_pos += width; -+ -+ if (stack) -+ PUSH_CURRENT_DIRED_POS (stack); -+ -+ if (used_color_this_time) -+ { -+ process_signals (); -+ prep_non_filename_text (); -+ if (start_col / line_length != (start_col + width - 1) / line_length) -+ put_indicator (&color_indicator[C_CLR_TO_EOL]); -+ } -+ -+ return width; -+} -+ -+static void -+prep_non_filename_text (void) -+{ -+ if (color_indicator[C_END].string != NULL) -+ put_indicator (&color_indicator[C_END]); -+ else -+ { -+ put_indicator (&color_indicator[C_LEFT]); -+ put_indicator (&color_indicator[C_RESET]); -+ put_indicator (&color_indicator[C_RIGHT]); -+ } -+} -+ -+/* Print the file name of `f' with appropriate quoting. -+ Also print file size, inode number, and filetype indicator character, -+ as requested by switches. */ -+ -+static size_t -+print_file_name_and_frills (const struct fileinfo *f, size_t start_col) -+{ -+ char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))]; -+ -+ if (print_inode) -+ printf ("%*s ", format == with_commas ? 0 : inode_number_width, -+ format_inode (buf, sizeof buf, f)); -+ -+ if (print_block_size) -+ printf ("%*s ", format == with_commas ? 0 : block_size_width, -+ ! f->stat_ok ? "?" -+ : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, -+ ST_NBLOCKSIZE, output_block_size)); -+ -+ if (print_scontext) -+ printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext); -+ -+ size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), -+ f->linkok, f->stat_ok, f->filetype, -+ NULL, f->stat.st_nlink, start_col); -+ -+ if (indicator_style != none) -+ width += print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); -+ -+ return width; -+} -+ -+/* Given these arguments describing a file, return the single-byte -+ type indicator, or 0. */ -+static char -+get_type_indicator (bool stat_ok, mode_t mode, enum filetype type) -+{ -+ char c; -+ -+ if (stat_ok ? S_ISREG (mode) : type == normal) -+ { -+ if (stat_ok && indicator_style == classify && (mode & S_IXUGO)) -+ c = '*'; -+ else -+ c = 0; -+ } -+ else -+ { -+ if (stat_ok ? S_ISDIR (mode) : type == directory || type == arg_directory) -+ c = '/'; -+ else if (indicator_style == slash) -+ c = 0; -+ else if (stat_ok ? S_ISLNK (mode) : type == symbolic_link) -+ c = '@'; -+ else if (stat_ok ? S_ISFIFO (mode) : type == fifo) -+ c = '|'; -+ else if (stat_ok ? S_ISSOCK (mode) : type == sock) -+ c = '='; -+ else if (stat_ok && S_ISDOOR (mode)) -+ c = '>'; -+ else -+ c = 0; -+ } -+ return c; -+} -+ -+static bool -+print_type_indicator (bool stat_ok, mode_t mode, enum filetype type) -+{ -+ char c = get_type_indicator (stat_ok, mode, type); -+ if (c) -+ DIRED_PUTCHAR (c); -+ return !!c; -+} -+ -+#ifdef HAVE_CAP -+/* Return true if NAME has a capability (see linux/capability.h) */ -+static bool -+has_capability (char const *name) -+{ -+ char *result; -+ bool has_cap; -+ -+ cap_t cap_d = cap_get_file (name); -+ if (cap_d == NULL) -+ return false; -+ -+ result = cap_to_text (cap_d, NULL); -+ cap_free (cap_d); -+ if (!result) -+ return false; -+ -+ /* check if human-readable capability string is empty */ -+ has_cap = !!*result; -+ -+ cap_free (result); -+ return has_cap; -+} -+#else -+static bool -+has_capability (char const *name ATTRIBUTE_UNUSED) -+{ -+ return false; -+} -+#endif -+ -+/* Returns whether any color sequence was printed. */ -+static bool -+print_color_indicator (const char *name, mode_t mode, int linkok, -+ bool stat_ok, enum filetype filetype, -+ nlink_t nlink) -+{ -+ enum indicator_no type; -+ struct color_ext_type *ext; /* Color extension */ -+ size_t len; /* Length of name */ -+ -+ /* Is this a nonexistent file? If so, linkok == -1. */ -+ -+ if (linkok == -1 && color_indicator[C_MISSING].string != NULL) -+ type = C_MISSING; -+ else if (! stat_ok) -+ { -+ static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS; -+ type = filetype_indicator[filetype]; -+ } -+ else -+ { -+ if (S_ISREG (mode)) -+ { -+ type = C_FILE; -+ -+ if ((mode & S_ISUID) != 0 && is_colored (C_SETUID)) -+ type = C_SETUID; -+ else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID)) -+ type = C_SETGID; -+ /* has_capability() called second for performance. */ -+ else if (is_colored (C_CAP) && has_capability (name)) -+ type = C_CAP; -+ else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC)) -+ type = C_EXEC; -+ else if ((1 < nlink) && is_colored (C_MULTIHARDLINK)) -+ type = C_MULTIHARDLINK; -+ } -+ else if (S_ISDIR (mode)) -+ { -+ type = C_DIR; -+ -+ if ((mode & S_ISVTX) && (mode & S_IWOTH) -+ && is_colored (C_STICKY_OTHER_WRITABLE)) -+ type = C_STICKY_OTHER_WRITABLE; -+ else if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE)) -+ type = C_OTHER_WRITABLE; -+ else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY)) -+ type = C_STICKY; -+ } -+ else if (S_ISLNK (mode)) -+ type = ((!linkok && color_indicator[C_ORPHAN].string) -+ ? C_ORPHAN : C_LINK); -+ else if (S_ISFIFO (mode)) -+ type = C_FIFO; -+ else if (S_ISSOCK (mode)) -+ type = C_SOCK; -+ else if (S_ISBLK (mode)) -+ type = C_BLK; -+ else if (S_ISCHR (mode)) -+ type = C_CHR; -+ else if (S_ISDOOR (mode)) -+ type = C_DOOR; -+ else -+ { -+ /* Classify a file of some other type as C_ORPHAN. */ -+ type = C_ORPHAN; -+ } -+ } -+ -+ /* Check the file's suffix only if still classified as C_FILE. */ -+ ext = NULL; -+ if (type == C_FILE) -+ { -+ /* Test if NAME has a recognized suffix. */ -+ -+ len = strlen (name); -+ name += len; /* Pointer to final \0. */ -+ for (ext = color_ext_list; ext != NULL; ext = ext->next) -+ { -+ if (ext->ext.len <= len -+ && strncmp (name - ext->ext.len, ext->ext.string, -+ ext->ext.len) == 0) -+ break; -+ } -+ } -+ -+ { -+ const struct bin_str *const s -+ = ext ? &(ext->seq) : &color_indicator[type]; -+ if (s->string != NULL) -+ { -+ put_indicator (&color_indicator[C_LEFT]); -+ put_indicator (s); -+ put_indicator (&color_indicator[C_RIGHT]); -+ return true; -+ } -+ else -+ return false; -+ } -+} -+ -+/* Output a color indicator (which may contain nulls). */ -+static void -+put_indicator (const struct bin_str *ind) -+{ -+ if (! used_color) -+ { -+ used_color = true; -+ prep_non_filename_text (); -+ } -+ -+ fwrite (ind->string, ind->len, 1, stdout); -+} -+ -+static size_t -+length_of_file_name_and_frills (const struct fileinfo *f) -+{ -+ size_t len = 0; -+ size_t name_width; -+ char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))]; -+ -+ if (print_inode) -+ len += 1 + (format == with_commas -+ ? strlen (umaxtostr (f->stat.st_ino, buf)) -+ : inode_number_width); -+ -+ if (print_block_size) -+ len += 1 + (format == with_commas -+ ? strlen (! f->stat_ok ? "?" -+ : human_readable (ST_NBLOCKS (f->stat), buf, -+ human_output_opts, ST_NBLOCKSIZE, -+ output_block_size)) -+ : block_size_width); -+ -+ if (print_scontext) -+ len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width); -+ -+ quote_name (NULL, f->name, filename_quoting_options, &name_width); -+ len += name_width; -+ -+ if (indicator_style != none) -+ { -+ char c = get_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); -+ len += (c != 0); -+ } -+ -+ return len; -+} -+ -+static void -+print_many_per_line (void) -+{ -+ size_t row; /* Current row. */ -+ size_t cols = calculate_columns (true); -+ struct column_info const *line_fmt = &column_info[cols - 1]; -+ -+ /* Calculate the number of rows that will be in each column except possibly -+ for a short column on the right. */ -+ size_t rows = cwd_n_used / cols + (cwd_n_used % cols != 0); -+ -+ for (row = 0; row < rows; row++) -+ { -+ size_t col = 0; -+ size_t filesno = row; -+ size_t pos = 0; -+ -+ /* Print the next row. */ -+ while (1) -+ { -+ struct fileinfo const *f = sorted_file[filesno]; -+ size_t name_length = length_of_file_name_and_frills (f); -+ size_t max_name_length = line_fmt->col_arr[col++]; -+ print_file_name_and_frills (f, pos); -+ -+ filesno += rows; -+ if (filesno >= cwd_n_used) -+ break; -+ -+ indent (pos + name_length, pos + max_name_length); -+ pos += max_name_length; -+ } -+ putchar ('\n'); -+ } -+} -+ -+static void -+print_horizontal (void) -+{ -+ size_t filesno; -+ size_t pos = 0; -+ size_t cols = calculate_columns (false); -+ struct column_info const *line_fmt = &column_info[cols - 1]; -+ struct fileinfo const *f = sorted_file[0]; -+ size_t name_length = length_of_file_name_and_frills (f); -+ size_t max_name_length = line_fmt->col_arr[0]; -+ -+ /* Print first entry. */ -+ print_file_name_and_frills (f, 0); -+ -+ /* Now the rest. */ -+ for (filesno = 1; filesno < cwd_n_used; ++filesno) -+ { -+ size_t col = filesno % cols; -+ -+ if (col == 0) -+ { -+ putchar ('\n'); -+ pos = 0; -+ } -+ else -+ { -+ indent (pos + name_length, pos + max_name_length); -+ pos += max_name_length; -+ } -+ -+ f = sorted_file[filesno]; -+ print_file_name_and_frills (f, pos); -+ -+ name_length = length_of_file_name_and_frills (f); -+ max_name_length = line_fmt->col_arr[col]; -+ } -+ putchar ('\n'); -+} -+ -+static void -+print_with_commas (void) -+{ -+ size_t filesno; -+ size_t pos = 0; -+ -+ for (filesno = 0; filesno < cwd_n_used; filesno++) -+ { -+ struct fileinfo const *f = sorted_file[filesno]; -+ size_t len = length_of_file_name_and_frills (f); -+ -+ if (filesno != 0) -+ { -+ char separator; -+ -+ if (pos + len + 2 < line_length) -+ { -+ pos += 2; -+ separator = ' '; -+ } -+ else -+ { -+ pos = 0; -+ separator = '\n'; -+ } -+ -+ putchar (','); -+ putchar (separator); -+ } -+ -+ print_file_name_and_frills (f, pos); -+ pos += len; -+ } -+ putchar ('\n'); -+} -+ -+/* Assuming cursor is at position FROM, indent up to position TO. -+ Use a TAB character instead of two or more spaces whenever possible. */ -+ -+static void -+indent (size_t from, size_t to) -+{ -+ while (from < to) -+ { -+ if (tabsize != 0 && to / tabsize > (from + 1) / tabsize) -+ { -+ putchar ('\t'); -+ from += tabsize - from % tabsize; -+ } -+ else -+ { -+ putchar (' '); -+ from++; -+ } -+ } -+} -+ -+/* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */ -+/* FIXME: maybe remove this function someday. See about using a -+ non-malloc'ing version of file_name_concat. */ -+ -+static void -+attach (char *dest, const char *dirname, const char *name) -+{ -+ const char *dirnamep = dirname; -+ -+ /* Copy dirname if it is not ".". */ -+ if (dirname[0] != '.' || dirname[1] != 0) -+ { -+ while (*dirnamep) -+ *dest++ = *dirnamep++; -+ /* Add '/' if `dirname' doesn't already end with it. */ -+ if (dirnamep > dirname && dirnamep[-1] != '/') -+ *dest++ = '/'; -+ } -+ while (*name) -+ *dest++ = *name++; -+ *dest = 0; -+} -+ -+/* Allocate enough column info suitable for the current number of -+ files and display columns, and initialize the info to represent the -+ narrowest possible columns. */ -+ -+static void -+init_column_info (void) -+{ -+ size_t i; -+ size_t max_cols = MIN (max_idx, cwd_n_used); -+ -+ /* Currently allocated columns in column_info. */ -+ static size_t column_info_alloc; -+ -+ if (column_info_alloc < max_cols) -+ { -+ size_t new_column_info_alloc; -+ size_t *p; -+ -+ if (max_cols < max_idx / 2) -+ { -+ /* The number of columns is far less than the display width -+ allows. Grow the allocation, but only so that it's -+ double the current requirements. If the display is -+ extremely wide, this avoids allocating a lot of memory -+ that is never needed. */ -+ column_info = xnrealloc (column_info, max_cols, -+ 2 * sizeof *column_info); -+ new_column_info_alloc = 2 * max_cols; -+ } -+ else -+ { -+ column_info = xnrealloc (column_info, max_idx, sizeof *column_info); -+ new_column_info_alloc = max_idx; -+ } -+ -+ /* Allocate the new size_t objects by computing the triangle -+ formula n * (n + 1) / 2, except that we don't need to -+ allocate the part of the triangle that we've already -+ allocated. Check for address arithmetic overflow. */ -+ { -+ size_t column_info_growth = new_column_info_alloc - column_info_alloc; -+ size_t s = column_info_alloc + 1 + new_column_info_alloc; -+ size_t t = s * column_info_growth; -+ if (s < new_column_info_alloc || t / column_info_growth != s) -+ xalloc_die (); -+ p = xnmalloc (t / 2, sizeof *p); -+ } -+ -+ /* Grow the triangle by parceling out the cells just allocated. */ -+ for (i = column_info_alloc; i < new_column_info_alloc; i++) -+ { -+ column_info[i].col_arr = p; -+ p += i + 1; -+ } -+ -+ column_info_alloc = new_column_info_alloc; -+ } -+ -+ for (i = 0; i < max_cols; ++i) -+ { -+ size_t j; -+ -+ column_info[i].valid_len = true; -+ column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH; -+ for (j = 0; j <= i; ++j) -+ column_info[i].col_arr[j] = MIN_COLUMN_WIDTH; -+ } -+} -+ -+/* Calculate the number of columns needed to represent the current set -+ of files in the current display width. */ -+ -+static size_t -+calculate_columns (bool by_columns) -+{ -+ size_t filesno; /* Index into cwd_file. */ -+ size_t cols; /* Number of files across. */ -+ -+ /* Normally the maximum number of columns is determined by the -+ screen width. But if few files are available this might limit it -+ as well. */ -+ size_t max_cols = MIN (max_idx, cwd_n_used); -+ -+ init_column_info (); -+ -+ /* Compute the maximum number of possible columns. */ -+ for (filesno = 0; filesno < cwd_n_used; ++filesno) -+ { -+ struct fileinfo const *f = sorted_file[filesno]; -+ size_t name_length = length_of_file_name_and_frills (f); -+ size_t i; -+ -+ for (i = 0; i < max_cols; ++i) -+ { -+ if (column_info[i].valid_len) -+ { -+ size_t idx = (by_columns -+ ? filesno / ((cwd_n_used + i) / (i + 1)) -+ : filesno % (i + 1)); -+ size_t real_length = name_length + (idx == i ? 0 : 2); -+ -+ if (column_info[i].col_arr[idx] < real_length) -+ { -+ column_info[i].line_len += (real_length -+ - column_info[i].col_arr[idx]); -+ column_info[i].col_arr[idx] = real_length; -+ column_info[i].valid_len = (column_info[i].line_len -+ < line_length); -+ } -+ } -+ } -+ } -+ -+ /* Find maximum allowed columns. */ -+ for (cols = max_cols; 1 < cols; --cols) -+ { -+ if (column_info[cols - 1].valid_len) -+ break; -+ } -+ -+ return cols; -+} -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name); -+ fputs (_("\ -+List information about the FILEs (the current directory by default).\n\ -+Sort entries alphabetically if none of -cftuvSUX nor --sort.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ -a, --all do not ignore entries starting with .\n\ -+ -A, --almost-all do not list implied . and ..\n\ -+ --author with -l, print the author of each file\n\ -+ -b, --escape print octal escapes for nongraphic characters\n\ -+"), stdout); -+ fputs (_("\ -+ --block-size=SIZE use SIZE-byte blocks. See SIZE format below\n\ -+ -B, --ignore-backups do not list implied entries ending with ~\n\ -+ -c with -lt: sort by, and show, ctime (time of last\n\ -+ modification of file status information)\n\ -+ with -l: show ctime and sort by name\n\ -+ otherwise: sort by ctime\n\ -+"), stdout); -+ fputs (_("\ -+ -C list entries by columns\n\ -+ --color[=WHEN] colorize the output. WHEN defaults to `always'\n\ -+ or can be `never' or `auto'. More info below\n\ -+ -d, --directory list directory entries instead of contents,\n\ -+ and do not dereference symbolic links\n\ -+ -D, --dired generate output designed for Emacs' dired mode\n\ -+"), stdout); -+ fputs (_("\ -+ -f do not sort, enable -aU, disable -ls --color\n\ -+ -F, --classify append indicator (one of */=>@|) to entries\n\ -+ --file-type likewise, except do not append `*'\n\ -+ --format=WORD across -x, commas -m, horizontal -x, long -l,\n\ -+ single-column -1, verbose -l, vertical -C\n\ -+ --full-time like -l --time-style=full-iso\n\ -+"), stdout); -+ fputs (_("\ -+ -g like -l, but do not list owner\n\ -+"), stdout); -+ fputs (_("\ -+ --group-directories-first\n\ -+ group directories before files.\n\ -+ augment with a --sort option, but any\n\ -+ use of --sort=none (-U) disables grouping\n\ -+"), stdout); -+ fputs (_("\ -+ -G, --no-group in a long listing, don't print group names\n\ -+ -h, --human-readable with -l, print sizes in human readable format\n\ -+ (e.g., 1K 234M 2G)\n\ -+ --si likewise, but use powers of 1000 not 1024\n\ -+"), stdout); -+ fputs (_("\ -+ -H, --dereference-command-line\n\ -+ follow symbolic links listed on the command line\n\ -+ --dereference-command-line-symlink-to-dir\n\ -+ follow each command line symbolic link\n\ -+ that points to a directory\n\ -+ --hide=PATTERN do not list implied entries matching shell PATTERN\n\ -+ (overridden by -a or -A)\n\ -+"), stdout); -+ fputs (_("\ -+ --indicator-style=WORD append indicator with style WORD to entry names:\n\ -+ none (default), slash (-p),\n\ -+ file-type (--file-type), classify (-F)\n\ -+ -i, --inode print the index number of each file\n\ -+ -I, --ignore=PATTERN do not list implied entries matching shell PATTERN\n\ -+ -k like --block-size=1K\n\ -+"), stdout); -+ fputs (_("\ -+ -l use a long listing format\n\ -+ -L, --dereference when showing file information for a symbolic\n\ -+ link, show information for the file the link\n\ -+ references rather than for the link itself\n\ -+ -m fill width with a comma separated list of entries\n\ -+"), stdout); -+ fputs (_("\ -+ -n, --numeric-uid-gid like -l, but list numeric user and group IDs\n\ -+ -N, --literal print raw entry names (don't treat e.g. control\n\ -+ characters specially)\n\ -+ -o like -l, but do not list group information\n\ -+ -p, --indicator-style=slash\n\ -+ append / indicator to directories\n\ -+"), stdout); -+ fputs (_("\ -+ -q, --hide-control-chars print ? instead of non graphic characters\n\ -+ --show-control-chars show non graphic characters as-is (default\n\ -+ unless program is `ls' and output is a terminal)\n\ -+ -Q, --quote-name enclose entry names in double quotes\n\ -+ --quoting-style=WORD use quoting style WORD for entry names:\n\ -+ literal, locale, shell, shell-always, c, escape\n\ -+"), stdout); -+ fputs (_("\ -+ -r, --reverse reverse order while sorting\n\ -+ -R, --recursive list subdirectories recursively\n\ -+ -s, --size print the allocated size of each file, in blocks\n\ -+"), stdout); -+ fputs (_("\ -+ -S sort by file size\n\ -+ --sort=WORD sort by WORD instead of name: none -U,\n\ -+ extension -X, size -S, time -t, version -v\n\ -+ --time=WORD with -l, show time as WORD instead of modification\n\ -+ time: atime -u, access -u, use -u, ctime -c,\n\ -+ or status -c; use specified time as sort key\n\ -+ if --sort=time\n\ -+"), stdout); -+ fputs (_("\ -+ --time-style=STYLE with -l, show times using style STYLE:\n\ -+ full-iso, long-iso, iso, locale, +FORMAT.\n\ -+ FORMAT is interpreted like `date'; if FORMAT is\n\ -+ FORMAT1FORMAT2, FORMAT1 applies to\n\ -+ non-recent files and FORMAT2 to recent files;\n\ -+ if STYLE is prefixed with `posix-', STYLE\n\ -+ takes effect only outside the POSIX locale\n\ -+"), stdout); -+ fputs (_("\ -+ -t sort by modification time\n\ -+ -T, --tabsize=COLS assume tab stops at each COLS instead of 8\n\ -+"), stdout); -+ fputs (_("\ -+ -u with -lt: sort by, and show, access time\n\ -+ with -l: show access time and sort by name\n\ -+ otherwise: sort by access time\n\ -+ -U do not sort; list entries in directory order\n\ -+ -v natural sort of (version) numbers within text\n\ -+"), stdout); -+ fputs (_("\ -+ -w, --width=COLS assume screen width instead of current value\n\ -+ -x list entries by lines instead of by columns\n\ -+ -X sort alphabetically by entry extension\n\ -+ -Z, --context print any SELinux security context of each file\n\ -+ -1 list one file per line\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ emit_size_note (); -+ fputs (_("\ -+\n\ -+Using color to distinguish file types is disabled both by default and\n\ -+with --color=never. With --color=auto, ls emits color codes only when\n\ -+standard output is connected to a terminal. The LS_COLORS environment\n\ -+variable can change the settings. Use the dircolors command to set it.\n\ -+"), stdout); -+ fputs (_("\ -+\n\ -+Exit status:\n\ -+ 0 if OK,\n\ -+ 1 if minor problems (e.g., cannot access subdirectory),\n\ -+ 2 if serious trouble (e.g., cannot access command-line argument).\n\ -+"), stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} diff -urNp coreutils-8.0-orig/src/mkdir.c coreutils-8.0/src/mkdir.c --- coreutils-8.0-orig/src/mkdir.c 2009-09-23 10:25:44.000000000 +0200 +++ coreutils-8.0/src/mkdir.c 2009-10-07 10:10:11.000000000 +0200 @@ -10780,505 +633,6 @@ diff -urNp coreutils-8.0-orig/src/mv.c coreutils-8.0/src/mv.c x->reduce_diagnostics = false; x->require_preserve = false; /* FIXME: maybe make this an option */ x->require_preserve_context = false; -diff -urNp coreutils-8.0-orig/src/mv.c.orig coreutils-8.0/src/mv.c.orig ---- coreutils-8.0-orig/src/mv.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/mv.c.orig 2009-09-23 10:25:44.000000000 +0200 -@@ -0,0 +1,495 @@ -+/* mv -- move or rename files -+ Copyright (C) 86, 89, 90, 91, 1995-2009 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 Mike Parker, David MacKenzie, and Jim Meyering */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "system.h" -+#include "backupfile.h" -+#include "copy.h" -+#include "cp-hash.h" -+#include "error.h" -+#include "filenamecat.h" -+#include "quote.h" -+#include "remove.h" -+#include "root-dev-ino.h" -+#include "priv-set.h" -+ -+/* The official name of this program (e.g., no `g' prefix). */ -+#define PROGRAM_NAME "mv" -+ -+#define AUTHORS \ -+ proper_name ("Mike Parker"), \ -+ proper_name ("David MacKenzie"), \ -+ proper_name ("Jim Meyering") -+ -+/* For long options that have no equivalent short option, use a -+ non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -+enum -+{ -+ STRIP_TRAILING_SLASHES_OPTION = CHAR_MAX + 1 -+}; -+ -+/* Remove any trailing slashes from each SOURCE argument. */ -+static bool remove_trailing_slashes; -+ -+static struct option const long_options[] = -+{ -+ {"backup", optional_argument, NULL, 'b'}, -+ {"force", no_argument, NULL, 'f'}, -+ {"interactive", no_argument, NULL, 'i'}, -+ {"no-clobber", no_argument, NULL, 'n'}, -+ {"no-target-directory", no_argument, NULL, 'T'}, -+ {"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION}, -+ {"suffix", required_argument, NULL, 'S'}, -+ {"target-directory", required_argument, NULL, 't'}, -+ {"update", no_argument, NULL, 'u'}, -+ {"verbose", no_argument, NULL, 'v'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+static void -+rm_option_init (struct rm_options *x) -+{ -+ x->ignore_missing_files = false; -+ x->recursive = true; -+ x->one_file_system = false; -+ -+ /* Should we prompt for removal, too? No. Prompting for the `move' -+ part is enough. It implies removal. */ -+ x->interactive = RMI_NEVER; -+ x->stdin_tty = false; -+ -+ x->verbose = false; -+ -+ /* Since this program may well have to process additional command -+ line arguments after any call to `rm', that function must preserve -+ the initial working directory, in case one of those is a -+ `.'-relative name. */ -+ x->require_restore_cwd = true; -+ -+ { -+ static struct dev_ino dev_ino_buf; -+ x->root_dev_ino = get_root_dev_ino (&dev_ino_buf); -+ if (x->root_dev_ino == NULL) -+ error (EXIT_FAILURE, errno, _("failed to get attributes of %s"), -+ quote ("/")); -+ } -+} -+ -+static void -+cp_option_init (struct cp_options *x) -+{ -+ bool selinux_enabled = (0 < is_selinux_enabled ()); -+ -+ cp_options_default (x); -+ x->copy_as_regular = false; /* FIXME: maybe make this an option */ -+ x->reflink_mode = REFLINK_NEVER; -+ x->dereference = DEREF_NEVER; -+ x->unlink_dest_before_opening = false; -+ x->unlink_dest_after_failed_open = false; -+ x->hard_link = false; -+ x->interactive = I_UNSPECIFIED; -+ x->move_mode = true; -+ x->one_file_system = false; -+ x->preserve_ownership = true; -+ x->preserve_links = true; -+ x->preserve_mode = true; -+ x->preserve_timestamps = true; -+ x->preserve_security_context = selinux_enabled; -+ x->reduce_diagnostics = false; -+ x->require_preserve = false; /* FIXME: maybe make this an option */ -+ x->require_preserve_context = false; -+ x->preserve_xattr = true; -+ x->require_preserve_xattr = false; -+ x->recursive = true; -+ x->sparse_mode = SPARSE_AUTO; /* FIXME: maybe make this an option */ -+ x->symbolic_link = false; -+ x->set_mode = false; -+ x->mode = 0; -+ x->stdin_tty = isatty (STDIN_FILENO); -+ -+ x->open_dangling_dest_symlink = false; -+ x->update = false; -+ x->verbose = false; -+ x->dest_info = NULL; -+ x->src_info = NULL; -+} -+ -+/* FILE is the last operand of this command. Return true if FILE is a -+ directory. But report an error if there is a problem accessing FILE, other -+ than nonexistence (errno == ENOENT). */ -+ -+static bool -+target_directory_operand (char const *file) -+{ -+ struct stat st; -+ int err = (stat (file, &st) == 0 ? 0 : errno); -+ bool is_a_dir = !err && S_ISDIR (st.st_mode); -+ if (err && err != ENOENT) -+ error (EXIT_FAILURE, err, _("accessing %s"), quote (file)); -+ return is_a_dir; -+} -+ -+/* Move SOURCE onto DEST. Handles cross-file-system moves. -+ If SOURCE is a directory, DEST must not exist. -+ Return true if successful. */ -+ -+static bool -+do_move (const char *source, const char *dest, const struct cp_options *x) -+{ -+ bool copy_into_self; -+ bool rename_succeeded; -+ bool ok = copy (source, dest, false, x, ©_into_self, &rename_succeeded); -+ -+ if (ok) -+ { -+ char const *dir_to_remove; -+ if (copy_into_self) -+ { -+ /* In general, when copy returns with copy_into_self set, SOURCE is -+ the same as, or a parent of DEST. In this case we know it's a -+ parent. It doesn't make sense to move a directory into itself, and -+ besides in some situations doing so would give highly nonintuitive -+ results. Run this `mkdir b; touch a c; mv * b' in an empty -+ directory. Here's the result of running echo `find b -print`: -+ b b/a b/b b/b/a b/c. Notice that only file `a' was copied -+ into b/b. Handle this by giving a diagnostic, removing the -+ copied-into-self directory, DEST (`b/b' in the example), -+ and failing. */ -+ -+ dir_to_remove = NULL; -+ ok = false; -+ } -+ else if (rename_succeeded) -+ { -+ /* No need to remove anything. SOURCE was successfully -+ renamed to DEST. Or the user declined to rename a file. */ -+ dir_to_remove = NULL; -+ } -+ else -+ { -+ /* This may mean SOURCE and DEST referred to different devices. -+ It may also conceivably mean that even though they referred -+ to the same device, rename wasn't implemented for that device. -+ -+ E.g., (from Joel N. Weber), -+ [...] there might someday be cases where you can't rename -+ but you can copy where the device name is the same, especially -+ on Hurd. Consider an ftpfs with a primitive ftp server that -+ supports uploading, downloading and deleting, but not renaming. -+ -+ Also, note that comparing device numbers is not a reliable -+ check for `can-rename'. Some systems can be set up so that -+ files from many different physical devices all have the same -+ st_dev field. This is a feature of some NFS mounting -+ configurations. -+ -+ We reach this point if SOURCE has been successfully copied -+ to DEST. Now we have to remove SOURCE. -+ -+ This function used to resort to copying only when rename -+ failed and set errno to EXDEV. */ -+ -+ dir_to_remove = source; -+ } -+ -+ if (dir_to_remove != NULL) -+ { -+ struct rm_options rm_options; -+ enum RM_status status; -+ char const *dir[2]; -+ -+ rm_option_init (&rm_options); -+ rm_options.verbose = x->verbose; -+ dir[0] = dir_to_remove; -+ dir[1] = NULL; -+ -+ status = rm ((void*) dir, &rm_options); -+ assert (VALID_STATUS (status)); -+ if (status == RM_ERROR) -+ ok = false; -+ } -+ } -+ -+ return ok; -+} -+ -+/* Move file SOURCE onto DEST. Handles the case when DEST is a directory. -+ Treat DEST as a directory if DEST_IS_DIR. -+ Return true if successful. */ -+ -+static bool -+movefile (char *source, char *dest, bool dest_is_dir, -+ const struct cp_options *x) -+{ -+ bool ok; -+ -+ /* This code was introduced to handle the ambiguity in the semantics -+ of mv that is induced by the varying semantics of the rename function. -+ Some systems (e.g., GNU/Linux) have a rename function that honors a -+ trailing slash, while others (like Solaris 5,6,7) have a rename -+ function that ignores a trailing slash. I believe the GNU/Linux -+ rename semantics are POSIX and susv2 compliant. */ -+ -+ if (remove_trailing_slashes) -+ strip_trailing_slashes (source); -+ -+ if (dest_is_dir) -+ { -+ /* Treat DEST as a directory; build the full filename. */ -+ char const *src_basename = last_component (source); -+ char *new_dest = file_name_concat (dest, src_basename, NULL); -+ strip_trailing_slashes (new_dest); -+ ok = do_move (source, new_dest, x); -+ free (new_dest); -+ } -+ else -+ { -+ ok = do_move (source, dest, x); -+ } -+ -+ return ok; -+} -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("\ -+Usage: %s [OPTION]... [-T] SOURCE DEST\n\ -+ or: %s [OPTION]... SOURCE... DIRECTORY\n\ -+ or: %s [OPTION]... -t DIRECTORY SOURCE...\n\ -+"), -+ program_name, program_name, program_name); -+ fputs (_("\ -+Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+Mandatory arguments to long options are mandatory for short options too.\n\ -+"), stdout); -+ fputs (_("\ -+ --backup[=CONTROL] make a backup of each existing destination file\n\ -+ -b like --backup but does not accept an argument\n\ -+ -f, --force do not prompt before overwriting\n\ -+ -i, --interactive prompt before overwrite\n\ -+ -n, --no-clobber do not overwrite an existing file\n\ -+If you specify more than one of -i, -f, -n, only the final one takes effect.\n\ -+"), stdout); -+ fputs (_("\ -+ --strip-trailing-slashes remove any trailing slashes from each SOURCE\n\ -+ argument\n\ -+ -S, --suffix=SUFFIX override the usual backup suffix\n\ -+"), stdout); -+ fputs (_("\ -+ -t, --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY\n\ -+ -T, --no-target-directory treat DEST as a normal file\n\ -+ -u, --update move only when the SOURCE file is newer\n\ -+ than the destination file or when the\n\ -+ destination file is missing\n\ -+ -v, --verbose explain what is being done\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ fputs (_("\ -+\n\ -+The backup suffix is `~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.\n\ -+The version control method may be selected via the --backup option or through\n\ -+the VERSION_CONTROL environment variable. Here are the values:\n\ -+\n\ -+"), stdout); -+ fputs (_("\ -+ none, off never make backups (even if --backup is given)\n\ -+ numbered, t make numbered backups\n\ -+ existing, nil numbered if numbered backups exist, simple otherwise\n\ -+ simple, never always make simple backups\n\ -+"), stdout); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int c; -+ bool ok; -+ bool make_backups = false; -+ char *backup_suffix_string; -+ char *version_control_string = NULL; -+ struct cp_options x; -+ char *target_directory = NULL; -+ bool no_target_directory = false; -+ int n_files; -+ char **file; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdin); -+ -+ cp_option_init (&x); -+ -+ /* Try to disable the ability to unlink a directory. */ -+ priv_set_remove_linkdir (); -+ -+ /* FIXME: consider not calling getenv for SIMPLE_BACKUP_SUFFIX unless -+ we'll actually use backup_suffix_string. */ -+ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); -+ -+ while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL)) -+ != -1) -+ { -+ switch (c) -+ { -+ case 'b': -+ make_backups = true; -+ if (optarg) -+ version_control_string = optarg; -+ break; -+ case 'f': -+ x.interactive = I_ALWAYS_YES; -+ break; -+ case 'i': -+ x.interactive = I_ASK_USER; -+ break; -+ case 'n': -+ x.interactive = I_ALWAYS_NO; -+ break; -+ case STRIP_TRAILING_SLASHES_OPTION: -+ remove_trailing_slashes = true; -+ break; -+ case 't': -+ if (target_directory) -+ error (EXIT_FAILURE, 0, _("multiple target directories specified")); -+ else -+ { -+ struct stat st; -+ if (stat (optarg, &st) != 0) -+ error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg)); -+ if (! S_ISDIR (st.st_mode)) -+ error (EXIT_FAILURE, 0, _("target %s is not a directory"), -+ quote (optarg)); -+ } -+ target_directory = optarg; -+ break; -+ case 'T': -+ no_target_directory = true; -+ break; -+ case 'u': -+ x.update = true; -+ break; -+ case 'v': -+ x.verbose = true; -+ break; -+ case 'S': -+ make_backups = true; -+ backup_suffix_string = optarg; -+ break; -+ case_GETOPT_HELP_CHAR; -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ n_files = argc - optind; -+ file = argv + optind; -+ -+ if (n_files <= !target_directory) -+ { -+ if (n_files <= 0) -+ error (0, 0, _("missing file operand")); -+ else -+ error (0, 0, _("missing destination file operand after %s"), -+ quote (file[0])); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (no_target_directory) -+ { -+ if (target_directory) -+ error (EXIT_FAILURE, 0, -+ _("cannot combine --target-directory (-t) " -+ "and --no-target-directory (-T)")); -+ if (2 < n_files) -+ { -+ error (0, 0, _("extra operand %s"), quote (file[2])); -+ usage (EXIT_FAILURE); -+ } -+ } -+ else if (!target_directory) -+ { -+ assert (2 <= n_files); -+ if (target_directory_operand (file[n_files - 1])) -+ target_directory = file[--n_files]; -+ else if (2 < n_files) -+ error (EXIT_FAILURE, 0, _("target %s is not a directory"), -+ quote (file[n_files - 1])); -+ } -+ -+ if (make_backups && x.interactive == I_ALWAYS_NO) -+ { -+ error (0, 0, -+ _("options --backup and --no-clobber are mutually exclusive")); -+ usage (EXIT_FAILURE); -+ } -+ -+ if (backup_suffix_string) -+ simple_backup_suffix = xstrdup (backup_suffix_string); -+ -+ x.backup_type = (make_backups -+ ? xget_version (_("backup type"), -+ version_control_string) -+ : no_backups); -+ -+ hash_init (); -+ -+ if (target_directory) -+ { -+ int i; -+ -+ /* Initialize the hash table only if we'll need it. -+ The problem it is used to detect can arise only if there are -+ two or more files to move. */ -+ if (2 <= n_files) -+ dest_info_init (&x); -+ -+ ok = true; -+ for (i = 0; i < n_files; ++i) -+ ok &= movefile (file[i], target_directory, true, &x); -+ } -+ else -+ ok = movefile (file[0], file[1], false, &x); -+ -+ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); -+} diff -urNp coreutils-8.0-orig/src/runcon.c coreutils-8.0/src/runcon.c --- coreutils-8.0-orig/src/runcon.c 2009-10-06 10:55:34.000000000 +0200 +++ coreutils-8.0/src/runcon.c 2009-10-07 10:10:11.000000000 +0200 @@ -11442,1092 +796,6 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } -diff -urNp coreutils-8.0-orig/src/stat.c.orig coreutils-8.0/src/stat.c.orig ---- coreutils-8.0-orig/src/stat.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/src/stat.c.orig 2009-09-29 16:25:44.000000000 +0200 -@@ -0,0 +1,1082 @@ -+/* stat.c -- display file or file system status -+ Copyright (C) 2001-2009 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 Michael Meskes. */ -+ -+#include -+ -+/* Keep this conditional in sync with the similar conditional in -+ ../m4/stat-prog.m4. */ -+#if (STAT_STATVFS \ -+ && (HAVE_STRUCT_STATVFS_F_BASETYPE || HAVE_STRUCT_STATVFS_F_FSTYPENAME \ -+ || (! HAVE_STRUCT_STATFS_F_FSTYPENAME && HAVE_STRUCT_STATVFS_F_TYPE))) -+# define USE_STATVFS 1 -+#else -+# define USE_STATVFS 0 -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#if USE_STATVFS -+# include -+#elif HAVE_SYS_VFS_H -+# include -+#elif HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H -+/* NOTE: freebsd5.0 needs sys/param.h and sys/mount.h for statfs. -+ It does have statvfs.h, but shouldn't use it, since it doesn't -+ HAVE_STRUCT_STATVFS_F_BASETYPE. So find a clean way to fix it. */ -+/* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */ -+# include -+# include -+# if HAVE_NETINET_IN_H && HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H -+/* Ultrix 4.4 needs these for the declaration of struct statfs. */ -+# include -+# include -+# include -+# endif -+#elif HAVE_OS_H /* BeOS */ -+# include -+#endif -+#include -+ -+#include "system.h" -+ -+#include "error.h" -+#include "filemode.h" -+#include "file-type.h" -+#include "fs.h" -+#include "getopt.h" -+#include "quote.h" -+#include "quotearg.h" -+#include "stat-time.h" -+#include "strftime.h" -+#include "areadlink.h" -+ -+#define alignof(type) offsetof (struct { char c; type x; }, x) -+ -+#if USE_STATVFS -+# define STRUCT_STATVFS struct statvfs -+# define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATVFS_F_FSID_IS_INTEGER -+# define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS_F_TYPE -+# if HAVE_STRUCT_STATVFS_F_NAMEMAX -+# define SB_F_NAMEMAX(S) ((S)->f_namemax) -+# endif -+# define STATFS statvfs -+# define STATFS_FRSIZE(S) ((S)->f_frsize) -+#else -+# define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATFS_F_TYPE -+# if HAVE_STRUCT_STATFS_F_NAMELEN -+# define SB_F_NAMEMAX(S) ((S)->f_namelen) -+# endif -+# define STATFS statfs -+# if HAVE_OS_H /* BeOS */ -+/* BeOS has a statvfs function, but it does not return sensible values -+ for f_files, f_ffree and f_favail, and lacks f_type, f_basetype and -+ f_fstypename. Use 'struct fs_info' instead. */ -+static int -+statfs (char const *filename, struct fs_info *buf) -+{ -+ dev_t device = dev_for_path (filename); -+ if (device < 0) -+ { -+ errno = (device == B_ENTRY_NOT_FOUND ? ENOENT -+ : device == B_BAD_VALUE ? EINVAL -+ : device == B_NAME_TOO_LONG ? ENAMETOOLONG -+ : device == B_NO_MEMORY ? ENOMEM -+ : device == B_FILE_ERROR ? EIO -+ : 0); -+ return -1; -+ } -+ /* If successful, buf->dev will be == device. */ -+ return fs_stat_dev (device, buf); -+} -+# define f_fsid dev -+# define f_blocks total_blocks -+# define f_bfree free_blocks -+# define f_bavail free_blocks -+# define f_bsize io_size -+# define f_files total_nodes -+# define f_ffree free_nodes -+# define STRUCT_STATVFS struct fs_info -+# define STRUCT_STATXFS_F_FSID_IS_INTEGER true -+# define STATFS_FRSIZE(S) ((S)->block_size) -+# else -+# define STRUCT_STATVFS struct statfs -+# define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATFS_F_FSID_IS_INTEGER -+# define STATFS_FRSIZE(S) 0 -+# endif -+#endif -+ -+#ifdef SB_F_NAMEMAX -+# define OUT_NAMEMAX out_uint -+#else -+/* NetBSD 1.5.2 has neither f_namemax nor f_namelen. */ -+# define SB_F_NAMEMAX(S) "*" -+# define OUT_NAMEMAX out_string -+#endif -+ -+#if HAVE_STRUCT_STATVFS_F_BASETYPE -+# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_basetype -+#else -+# if HAVE_STRUCT_STATVFS_F_FSTYPENAME || HAVE_STRUCT_STATFS_F_FSTYPENAME -+# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_fstypename -+# elif HAVE_OS_H /* BeOS */ -+# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME fsh_name -+# endif -+#endif -+ -+/* FIXME: these are used by printf.c, too */ -+#define isodigit(c) ('0' <= (c) && (c) <= '7') -+#define octtobin(c) ((c) - '0') -+#define hextobin(c) ((c) >= 'a' && (c) <= 'f' ? (c) - 'a' + 10 : \ -+ (c) >= 'A' && (c) <= 'F' ? (c) - 'A' + 10 : (c) - '0') -+ -+#define PROGRAM_NAME "stat" -+ -+#define AUTHORS proper_name ("Michael Meskes") -+ -+enum -+{ -+ PRINTF_OPTION = CHAR_MAX + 1 -+}; -+ -+static struct option const long_options[] = -+{ -+ {"context", no_argument, 0, 'Z'}, -+ {"dereference", no_argument, NULL, 'L'}, -+ {"file-system", no_argument, NULL, 'f'}, -+ {"format", required_argument, NULL, 'c'}, -+ {"printf", required_argument, NULL, PRINTF_OPTION}, -+ {"terse", no_argument, NULL, 't'}, -+ {GETOPT_HELP_OPTION_DECL}, -+ {GETOPT_VERSION_OPTION_DECL}, -+ {NULL, 0, NULL, 0} -+}; -+ -+/* Whether to follow symbolic links; True for --dereference (-L). */ -+static bool follow_links; -+ -+/* Whether to interpret backslash-escape sequences. -+ True for --printf=FMT, not for --format=FMT (-c). */ -+static bool interpret_backslash_escapes; -+ -+/* The trailing delimiter string: -+ "" for --printf=FMT, "\n" for --format=FMT (-c). */ -+static char const *trailing_delim = ""; -+ -+/* Return the type of the specified file system. -+ Some systems have statfvs.f_basetype[FSTYPSZ] (AIX, HP-UX, and Solaris). -+ Others have statvfs.f_fstypename[_VFS_NAMELEN] (NetBSD 3.0). -+ Others have statfs.f_fstypename[MFSNAMELEN] (NetBSD 1.5.2). -+ Still others have neither and have to get by with f_type (GNU/Linux). -+ But f_type may only exist in statfs (Cygwin). */ -+static char const * -+human_fstype (STRUCT_STATVFS const *statfsbuf) -+{ -+#ifdef STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME -+ return statfsbuf->STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME; -+#else -+ switch (statfsbuf->f_type) -+ { -+# if defined __linux__ -+ -+ /* Compare with what's in libc: -+ f=/a/libc/sysdeps/unix/sysv/linux/linux_fsinfo.h -+ sed -n '/ADFS_SUPER_MAGIC/,/SYSFS_MAGIC/p' $f \ -+ | perl -n -e '/#define (.*?)_(?:SUPER_)MAGIC\s+0x(\S+)/' \ -+ -e 'and print "case S_MAGIC_$1: /\* 0x" . uc($2) . " *\/\n"' \ -+ | sort > sym_libc -+ perl -ne '/^\s+(case S_MAGIC_.*?): \/\* 0x(\S+) \*\//' \ -+ -e 'and do { $v=uc$2; print "$1: /\* 0x$v *\/\n"}' stat.c \ -+ | sort > sym_stat -+ diff -u sym_stat sym_libc -+ */ -+ -+ /* Also sync from the list in "man 2 statfs". */ -+ -+ /* IMPORTANT NOTE: Each of the following `case S_MAGIC_...:' -+ statements must be followed by a hexadecimal constant in -+ a comment. The S_MAGIC_... name and constant are automatically -+ combined to produce the #define directives in fs.h. */ -+ -+ case S_MAGIC_ADFS: /* 0xADF5 */ -+ return "adfs"; -+ case S_MAGIC_AFFS: /* 0xADFF */ -+ return "affs"; -+ case S_MAGIC_AUTOFS: /* 0x187 */ -+ return "autofs"; -+ case S_MAGIC_BEFS: /* 0x42465331 */ -+ return "befs"; -+ case S_MAGIC_BFS: /* 0x1BADFACE */ -+ return "bfs"; -+ case S_MAGIC_BINFMT_MISC: /* 0x42494e4d */ -+ return "binfmt_misc"; -+ case S_MAGIC_CODA: /* 0x73757245 */ -+ return "coda"; -+ case S_MAGIC_COH: /* 0x012FF7B7 */ -+ return "coh"; -+ case S_MAGIC_CRAMFS: /* 0x28CD3D45 */ -+ return "cramfs"; -+ case S_MAGIC_DEVFS: /* 0x1373 */ -+ return "devfs"; -+ case S_MAGIC_DEVPTS: /* 0x1CD1 */ -+ return "devpts"; -+ case S_MAGIC_EFS: /* 0x414A53 */ -+ return "efs"; -+ case S_MAGIC_EXT: /* 0x137D */ -+ return "ext"; -+ case S_MAGIC_EXT2: /* 0xEF53 */ -+ return "ext2/ext3"; -+ case S_MAGIC_EXT2_OLD: /* 0xEF51 */ -+ return "ext2"; -+ case S_MAGIC_FAT: /* 0x4006 */ -+ return "fat"; -+ case S_MAGIC_FUSECTL: /* 0x65735543 */ -+ return "fusectl"; -+ case S_MAGIC_HPFS: /* 0xF995E849 */ -+ return "hpfs"; -+ case S_MAGIC_HUGETLBFS: /* 0x958458f6 */ -+ return "hugetlbfs"; -+ case S_MAGIC_ISOFS: /* 0x9660 */ -+ return "isofs"; -+ case S_MAGIC_ISOFS_R_WIN: /* 0x4004 */ -+ return "isofs"; -+ case S_MAGIC_ISOFS_WIN: /* 0x4000 */ -+ return "isofs"; -+ case S_MAGIC_JFFS2: /* 0x72B6 */ -+ return "jffs2"; -+ case S_MAGIC_JFFS: /* 0x07C0 */ -+ return "jffs"; -+ case S_MAGIC_JFS: /* 0x3153464A */ -+ return "jfs"; -+ case S_MAGIC_LUSTRE: /* 0x0BD00BD0 */ -+ return "lustre"; -+ case S_MAGIC_MINIX: /* 0x137F */ -+ return "minix"; -+ case S_MAGIC_MINIX_30: /* 0x138F */ -+ return "minix (30 char.)"; -+ case S_MAGIC_MINIX_V2: /* 0x2468 */ -+ return "minix v2"; -+ case S_MAGIC_MINIX_V2_30: /* 0x2478 */ -+ return "minix v2 (30 char.)"; -+ case S_MAGIC_MSDOS: /* 0x4D44 */ -+ return "msdos"; -+ case S_MAGIC_NCP: /* 0x564C */ -+ return "novell"; -+ case S_MAGIC_NFS: /* 0x6969 */ -+ return "nfs"; -+ case S_MAGIC_NFSD: /* 0x6E667364 */ -+ return "nfsd"; -+ case S_MAGIC_NTFS: /* 0x5346544E */ -+ return "ntfs"; -+ case S_MAGIC_OPENPROM: /* 0x9fa1 */ -+ return "openprom"; -+ case S_MAGIC_PROC: /* 0x9FA0 */ -+ return "proc"; -+ case S_MAGIC_QNX4: /* 0x002F */ -+ return "qnx4"; -+ case S_MAGIC_RAMFS: /* 0x858458F6 */ -+ return "ramfs"; -+ case S_MAGIC_REISERFS: /* 0x52654973 */ -+ return "reiserfs"; -+ case S_MAGIC_ROMFS: /* 0x7275 */ -+ return "romfs"; -+ case S_MAGIC_SMB: /* 0x517B */ -+ return "smb"; -+ case S_MAGIC_SQUASHFS: /* 0x73717368 */ -+ return "squashfs"; -+ case S_MAGIC_SYSFS: /* 0x62656572 */ -+ return "sysfs"; -+ case S_MAGIC_SYSV2: /* 0x012FF7B6 */ -+ return "sysv2"; -+ case S_MAGIC_SYSV4: /* 0x012FF7B5 */ -+ return "sysv4"; -+ case S_MAGIC_TMPFS: /* 0x1021994 */ -+ return "tmpfs"; -+ case S_MAGIC_UDF: /* 0x15013346 */ -+ return "udf"; -+ case S_MAGIC_UFS: /* 0x00011954 */ -+ return "ufs"; -+ case S_MAGIC_UFS_BYTESWAPPED: /* 0x54190100 */ -+ return "ufs"; -+ case S_MAGIC_USBDEVFS: /* 0x9FA2 */ -+ return "usbdevfs"; -+ case S_MAGIC_VXFS: /* 0xA501FCF5 */ -+ return "vxfs"; -+ case S_MAGIC_XENIX: /* 0x012FF7B4 */ -+ return "xenix"; -+ case S_MAGIC_XFS: /* 0x58465342 */ -+ return "xfs"; -+ case S_MAGIC_XIAFS: /* 0x012FD16D */ -+ return "xia"; -+ -+# elif __GNU__ -+ case FSTYPE_UFS: -+ return "ufs"; -+ case FSTYPE_NFS: -+ return "nfs"; -+ case FSTYPE_GFS: -+ return "gfs"; -+ case FSTYPE_LFS: -+ return "lfs"; -+ case FSTYPE_SYSV: -+ return "sysv"; -+ case FSTYPE_FTP: -+ return "ftp"; -+ case FSTYPE_TAR: -+ return "tar"; -+ case FSTYPE_AR: -+ return "ar"; -+ case FSTYPE_CPIO: -+ return "cpio"; -+ case FSTYPE_MSLOSS: -+ return "msloss"; -+ case FSTYPE_CPM: -+ return "cpm"; -+ case FSTYPE_HFS: -+ return "hfs"; -+ case FSTYPE_DTFS: -+ return "dtfs"; -+ case FSTYPE_GRFS: -+ return "grfs"; -+ case FSTYPE_TERM: -+ return "term"; -+ case FSTYPE_DEV: -+ return "dev"; -+ case FSTYPE_PROC: -+ return "proc"; -+ case FSTYPE_IFSOCK: -+ return "ifsock"; -+ case FSTYPE_AFS: -+ return "afs"; -+ case FSTYPE_DFS: -+ return "dfs"; -+ case FSTYPE_PROC9: -+ return "proc9"; -+ case FSTYPE_SOCKET: -+ return "socket"; -+ case FSTYPE_MISC: -+ return "misc"; -+ case FSTYPE_EXT2FS: -+ return "ext2/ext3"; -+ case FSTYPE_HTTP: -+ return "http"; -+ case FSTYPE_MEMFS: -+ return "memfs"; -+ case FSTYPE_ISO9660: -+ return "iso9660"; -+# endif -+ default: -+ { -+ unsigned long int type = statfsbuf->f_type; -+ static char buf[sizeof "UNKNOWN (0x%lx)" - 3 -+ + (sizeof type * CHAR_BIT + 3) / 4]; -+ sprintf (buf, "UNKNOWN (0x%lx)", type); -+ return buf; -+ } -+ } -+#endif -+} -+ -+static char * -+human_access (struct stat const *statbuf) -+{ -+ static char modebuf[12]; -+ filemodestring (statbuf, modebuf); -+ modebuf[10] = 0; -+ return modebuf; -+} -+ -+static char * -+human_time (struct timespec t) -+{ -+ static char str[MAX (INT_BUFSIZE_BOUND (intmax_t), -+ (INT_STRLEN_BOUND (int) /* YYYY */ -+ + 1 /* because YYYY might equal INT_MAX + 1900 */ -+ + sizeof "-MM-DD HH:MM:SS.NNNNNNNNN +ZZZZ"))]; -+ struct tm const *tm = localtime (&t.tv_sec); -+ if (tm == NULL) -+ return timetostr (t.tv_sec, str); -+ nstrftime (str, sizeof str, "%Y-%m-%d %H:%M:%S.%N %z", tm, 0, t.tv_nsec); -+ return str; -+} -+ -+static void -+out_string (char *pformat, size_t prefix_len, char const *arg) -+{ -+ strcpy (pformat + prefix_len, "s"); -+ printf (pformat, arg); -+} -+static void -+out_int (char *pformat, size_t prefix_len, intmax_t arg) -+{ -+ strcpy (pformat + prefix_len, PRIdMAX); -+ printf (pformat, arg); -+} -+static void -+out_uint (char *pformat, size_t prefix_len, uintmax_t arg) -+{ -+ strcpy (pformat + prefix_len, PRIuMAX); -+ printf (pformat, arg); -+} -+static void -+out_uint_o (char *pformat, size_t prefix_len, uintmax_t arg) -+{ -+ strcpy (pformat + prefix_len, PRIoMAX); -+ printf (pformat, arg); -+} -+static void -+out_uint_x (char *pformat, size_t prefix_len, uintmax_t arg) -+{ -+ strcpy (pformat + prefix_len, PRIxMAX); -+ printf (pformat, arg); -+} -+ -+/* Very specialized function (modifies FORMAT), just so as to avoid -+ duplicating this code between both print_statfs and print_stat. */ -+static void -+out_file_context (char const *filename, char *pformat, size_t prefix_len) -+{ -+ char *scontext; -+ if ((follow_links -+ ? getfilecon (filename, &scontext) -+ : lgetfilecon (filename, &scontext)) < 0) -+ { -+ error (0, errno, _("failed to get security context of %s"), -+ quote (filename)); -+ scontext = NULL; -+ } -+ strcpy (pformat + prefix_len, "s"); -+ printf (pformat, (scontext ? scontext : "?")); -+ if (scontext) -+ freecon (scontext); -+} -+ -+/* print statfs info */ -+static void -+print_statfs (char *pformat, size_t prefix_len, char m, char const *filename, -+ void const *data) -+{ -+ STRUCT_STATVFS const *statfsbuf = data; -+ -+ switch (m) -+ { -+ case 'n': -+ out_string (pformat, prefix_len, filename); -+ break; -+ -+ case 'i': -+ { -+#if STRUCT_STATXFS_F_FSID_IS_INTEGER -+ uintmax_t fsid = statfsbuf->f_fsid; -+#else -+ typedef unsigned int fsid_word; -+ verify (alignof (STRUCT_STATVFS) % alignof (fsid_word) == 0); -+ verify (offsetof (STRUCT_STATVFS, f_fsid) % alignof (fsid_word) == 0); -+ verify (sizeof statfsbuf->f_fsid % alignof (fsid_word) == 0); -+ fsid_word const *p = (fsid_word *) &statfsbuf->f_fsid; -+ -+ /* Assume a little-endian word order, as that is compatible -+ with glibc's statvfs implementation. */ -+ uintmax_t fsid = 0; -+ int words = sizeof statfsbuf->f_fsid / sizeof *p; -+ int i; -+ for (i = 0; i < words && i * sizeof *p < sizeof fsid; i++) -+ { -+ uintmax_t u = p[words - 1 - i]; -+ fsid |= u << (i * CHAR_BIT * sizeof *p); -+ } -+#endif -+ out_uint_x (pformat, prefix_len, fsid); -+ } -+ break; -+ -+ case 'l': -+ OUT_NAMEMAX (pformat, prefix_len, SB_F_NAMEMAX (statfsbuf)); -+ break; -+ case 't': -+#if HAVE_STRUCT_STATXFS_F_TYPE -+ out_uint_x (pformat, prefix_len, statfsbuf->f_type); -+#else -+ fputc ('?', stdout); -+#endif -+ break; -+ case 'T': -+ out_string (pformat, prefix_len, human_fstype (statfsbuf)); -+ break; -+ case 'b': -+ out_int (pformat, prefix_len, statfsbuf->f_blocks); -+ break; -+ case 'f': -+ out_int (pformat, prefix_len, statfsbuf->f_bfree); -+ break; -+ case 'a': -+ out_int (pformat, prefix_len, statfsbuf->f_bavail); -+ break; -+ case 's': -+ out_uint (pformat, prefix_len, statfsbuf->f_bsize); -+ break; -+ case 'S': -+ { -+ uintmax_t frsize = STATFS_FRSIZE (statfsbuf); -+ if (! frsize) -+ frsize = statfsbuf->f_bsize; -+ out_uint (pformat, prefix_len, frsize); -+ } -+ break; -+ case 'c': -+ out_uint (pformat, prefix_len, statfsbuf->f_files); -+ break; -+ case 'd': -+ out_int (pformat, prefix_len, statfsbuf->f_ffree); -+ break; -+ case 'C': -+ out_file_context (filename, pformat, prefix_len); -+ break; -+ default: -+ fputc ('?', stdout); -+ break; -+ } -+} -+ -+/* print stat info */ -+static void -+print_stat (char *pformat, size_t prefix_len, char m, -+ char const *filename, void const *data) -+{ -+ struct stat *statbuf = (struct stat *) data; -+ struct passwd *pw_ent; -+ struct group *gw_ent; -+ -+ switch (m) -+ { -+ case 'n': -+ out_string (pformat, prefix_len, filename); -+ break; -+ case 'N': -+ out_string (pformat, prefix_len, quote (filename)); -+ if (S_ISLNK (statbuf->st_mode)) -+ { -+ char *linkname = areadlink_with_size (filename, statbuf->st_size); -+ if (linkname == NULL) -+ { -+ error (0, errno, _("cannot read symbolic link %s"), -+ quote (filename)); -+ return; -+ } -+ printf (" -> "); -+ out_string (pformat, prefix_len, quote (linkname)); -+ } -+ break; -+ case 'd': -+ out_uint (pformat, prefix_len, statbuf->st_dev); -+ break; -+ case 'D': -+ out_uint_x (pformat, prefix_len, statbuf->st_dev); -+ break; -+ case 'i': -+ out_uint (pformat, prefix_len, statbuf->st_ino); -+ break; -+ case 'a': -+ out_uint_o (pformat, prefix_len, statbuf->st_mode & CHMOD_MODE_BITS); -+ break; -+ case 'A': -+ out_string (pformat, prefix_len, human_access (statbuf)); -+ break; -+ case 'f': -+ out_uint_x (pformat, prefix_len, statbuf->st_mode); -+ break; -+ case 'F': -+ out_string (pformat, prefix_len, file_type (statbuf)); -+ break; -+ case 'h': -+ out_uint (pformat, prefix_len, statbuf->st_nlink); -+ break; -+ case 'u': -+ out_uint (pformat, prefix_len, statbuf->st_uid); -+ break; -+ case 'U': -+ setpwent (); -+ pw_ent = getpwuid (statbuf->st_uid); -+ out_string (pformat, prefix_len, -+ pw_ent ? pw_ent->pw_name : "UNKNOWN"); -+ break; -+ case 'g': -+ out_uint (pformat, prefix_len, statbuf->st_gid); -+ break; -+ case 'G': -+ setgrent (); -+ gw_ent = getgrgid (statbuf->st_gid); -+ out_string (pformat, prefix_len, -+ gw_ent ? gw_ent->gr_name : "UNKNOWN"); -+ break; -+ case 't': -+ out_uint_x (pformat, prefix_len, major (statbuf->st_rdev)); -+ break; -+ case 'T': -+ out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev)); -+ break; -+ case 's': -+ out_uint (pformat, prefix_len, statbuf->st_size); -+ break; -+ case 'B': -+ out_uint (pformat, prefix_len, ST_NBLOCKSIZE); -+ break; -+ case 'b': -+ out_uint (pformat, prefix_len, ST_NBLOCKS (*statbuf)); -+ break; -+ case 'o': -+ out_uint (pformat, prefix_len, statbuf->st_blksize); -+ break; -+ case 'x': -+ out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); -+ break; -+ case 'X': -+ if (TYPE_SIGNED (time_t)) -+ out_int (pformat, prefix_len, statbuf->st_atime); -+ else -+ out_uint (pformat, prefix_len, statbuf->st_atime); -+ break; -+ case 'y': -+ out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf))); -+ break; -+ case 'Y': -+ if (TYPE_SIGNED (time_t)) -+ out_int (pformat, prefix_len, statbuf->st_mtime); -+ else -+ out_uint (pformat, prefix_len, statbuf->st_mtime); -+ break; -+ case 'z': -+ out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf))); -+ break; -+ case 'Z': -+ if (TYPE_SIGNED (time_t)) -+ out_int (pformat, prefix_len, statbuf->st_ctime); -+ else -+ out_uint (pformat, prefix_len, statbuf->st_ctime); -+ break; -+ case 'C': -+ out_file_context (filename, pformat, prefix_len); -+ break; -+ default: -+ fputc ('?', stdout); -+ break; -+ } -+} -+ -+/* Output a single-character \ escape. */ -+ -+static void -+print_esc_char (char c) -+{ -+ switch (c) -+ { -+ case 'a': /* Alert. */ -+ c ='\a'; -+ break; -+ case 'b': /* Backspace. */ -+ c ='\b'; -+ break; -+ case 'f': /* Form feed. */ -+ c ='\f'; -+ break; -+ case 'n': /* New line. */ -+ c ='\n'; -+ break; -+ case 'r': /* Carriage return. */ -+ c ='\r'; -+ break; -+ case 't': /* Horizontal tab. */ -+ c ='\t'; -+ break; -+ case 'v': /* Vertical tab. */ -+ c ='\v'; -+ break; -+ case '"': -+ case '\\': -+ break; -+ default: -+ error (0, 0, _("warning: unrecognized escape `\\%c'"), c); -+ break; -+ } -+ putchar (c); -+} -+ -+static void -+print_it (char const *format, char const *filename, -+ void (*print_func) (char *, size_t, char, char const *, void const *), -+ void const *data) -+{ -+ /* Add 2 to accommodate our conversion of the stat `%s' format string -+ to the longer printf `%llu' one. */ -+ enum -+ { -+ MAX_ADDITIONAL_BYTES = -+ (MAX (sizeof PRIdMAX, -+ MAX (sizeof PRIoMAX, MAX (sizeof PRIuMAX, sizeof PRIxMAX))) -+ - 1) -+ }; -+ size_t n_alloc = strlen (format) + MAX_ADDITIONAL_BYTES + 1; -+ char *dest = xmalloc (n_alloc); -+ char const *b; -+ for (b = format; *b; b++) -+ { -+ switch (*b) -+ { -+ case '%': -+ { -+ size_t len = strspn (b + 1, "#-+.I 0123456789"); -+ char const *fmt_char = b + len + 1; -+ memcpy (dest, b, len + 1); -+ -+ b = fmt_char; -+ switch (*fmt_char) -+ { -+ case '\0': -+ --b; -+ /* fall through */ -+ case '%': -+ if (0 < len) -+ { -+ dest[len + 1] = *fmt_char; -+ dest[len + 2] = '\0'; -+ error (EXIT_FAILURE, 0, _("%s: invalid directive"), -+ quotearg_colon (dest)); -+ } -+ putchar ('%'); -+ break; -+ default: -+ print_func (dest, len + 1, *fmt_char, filename, data); -+ break; -+ } -+ break; -+ } -+ -+ case '\\': -+ if ( ! interpret_backslash_escapes) -+ { -+ putchar ('\\'); -+ break; -+ } -+ ++b; -+ if (isodigit (*b)) -+ { -+ int esc_value = octtobin (*b); -+ int esc_length = 1; /* number of octal digits */ -+ for (++b; esc_length < 3 && isodigit (*b); -+ ++esc_length, ++b) -+ { -+ esc_value = esc_value * 8 + octtobin (*b); -+ } -+ putchar (esc_value); -+ --b; -+ } -+ else if (*b == 'x' && isxdigit (to_uchar (b[1]))) -+ { -+ int esc_value = hextobin (b[1]); /* Value of \xhh escape. */ -+ /* A hexadecimal \xhh escape sequence must have -+ 1 or 2 hex. digits. */ -+ ++b; -+ if (isxdigit (to_uchar (b[1]))) -+ { -+ ++b; -+ esc_value = esc_value * 16 + hextobin (*b); -+ } -+ putchar (esc_value); -+ } -+ else if (*b == '\0') -+ { -+ error (0, 0, _("warning: backslash at end of format")); -+ putchar ('\\'); -+ /* Arrange to exit the loop. */ -+ --b; -+ } -+ else -+ { -+ print_esc_char (*b); -+ } -+ break; -+ -+ default: -+ putchar (*b); -+ break; -+ } -+ } -+ free (dest); -+ -+ fputs (trailing_delim, stdout); -+} -+ -+/* Stat the file system and print what we find. */ -+static bool -+do_statfs (char const *filename, bool terse, char const *format) -+{ -+ STRUCT_STATVFS statfsbuf; -+ -+ if (STREQ (filename, "-")) -+ { -+ error (0, 0, _("using %s to denote standard input does not work" -+ " in file system mode"), quote (filename)); -+ return false; -+ } -+ -+ if (STATFS (filename, &statfsbuf) != 0) -+ { -+ error (0, errno, _("cannot read file system information for %s"), -+ quote (filename)); -+ return false; -+ } -+ -+ if (format == NULL) -+ { -+ format = (terse -+ ? "%n %i %l %t %s %S %b %f %a %c %d\n" -+ : " File: \"%n\"\n" -+ " ID: %-8i Namelen: %-7l Type: %T\n" -+ "Block size: %-10s Fundamental block size: %S\n" -+ "Blocks: Total: %-10b Free: %-10f Available: %a\n" -+ "Inodes: Total: %-10c Free: %d\n"); -+ } -+ -+ print_it (format, filename, print_statfs, &statfsbuf); -+ return true; -+} -+ -+/* stat the file and print what we find */ -+static bool -+do_stat (char const *filename, bool terse, char const *format) -+{ -+ struct stat statbuf; -+ -+ if (STREQ (filename, "-")) -+ { -+ if (fstat (STDIN_FILENO, &statbuf) != 0) -+ { -+ error (0, errno, _("cannot stat standard input")); -+ return false; -+ } -+ } -+ else if ((follow_links ? stat : lstat) (filename, &statbuf) != 0) -+ { -+ error (0, errno, _("cannot stat %s"), quote (filename)); -+ return false; -+ } -+ -+ if (format == NULL) -+ { -+ if (terse) -+ { -+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; -+ } -+ else -+ { -+ /* Temporary hack to match original output until conditional -+ implemented. */ -+ if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode)) -+ { -+ format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h" -+ " Device type: %t,%T\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; -+ } -+ else -+ { -+ format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %h\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; -+ } -+ } -+ } -+ print_it (format, filename, print_stat, &statbuf); -+ return true; -+} -+ -+void -+usage (int status) -+{ -+ if (status != EXIT_SUCCESS) -+ fprintf (stderr, _("Try `%s --help' for more information.\n"), -+ program_name); -+ else -+ { -+ printf (_("Usage: %s [OPTION]... FILE...\n"), program_name); -+ fputs (_("\ -+Display file or file system status.\n\ -+\n\ -+ -L, --dereference follow links\n\ -+ -f, --file-system display file system status instead of file status\n\ -+"), stdout); -+ fputs (_("\ -+ -c --format=FORMAT use the specified FORMAT instead of the default;\n\ -+ output a newline after each use of FORMAT\n\ -+ --printf=FORMAT like --format, but interpret backslash escapes,\n\ -+ and do not output a mandatory trailing newline.\n\ -+ If you want a newline, include \\n in FORMAT.\n\ -+ -t, --terse print the information in terse form\n\ -+"), stdout); -+ fputs (HELP_OPTION_DESCRIPTION, stdout); -+ fputs (VERSION_OPTION_DESCRIPTION, stdout); -+ -+ fputs (_("\n\ -+The valid format sequences for files (without --file-system):\n\ -+\n\ -+ %a Access rights in octal\n\ -+ %A Access rights in human readable form\n\ -+ %b Number of blocks allocated (see %B)\n\ -+ %B The size in bytes of each block reported by %b\n\ -+ %C SELinux security context string\n\ -+"), stdout); -+ fputs (_("\ -+ %d Device number in decimal\n\ -+ %D Device number in hex\n\ -+ %f Raw mode in hex\n\ -+ %F File type\n\ -+ %g Group ID of owner\n\ -+ %G Group name of owner\n\ -+"), stdout); -+ fputs (_("\ -+ %h Number of hard links\n\ -+ %i Inode number\n\ -+ %n File name\n\ -+ %N Quoted file name with dereference if symbolic link\n\ -+ %o I/O block size\n\ -+ %s Total size, in bytes\n\ -+ %t Major device type in hex\n\ -+ %T Minor device type in hex\n\ -+"), stdout); -+ fputs (_("\ -+ %u User ID of owner\n\ -+ %U User name of owner\n\ -+ %x Time of last access\n\ -+ %X Time of last access as seconds since Epoch\n\ -+ %y Time of last modification\n\ -+ %Y Time of last modification as seconds since Epoch\n\ -+ %z Time of last change\n\ -+ %Z Time of last change as seconds since Epoch\n\ -+\n\ -+"), stdout); -+ -+ fputs (_("\ -+Valid format sequences for file systems:\n\ -+\n\ -+ %a Free blocks available to non-superuser\n\ -+ %b Total data blocks in file system\n\ -+ %c Total file nodes in file system\n\ -+ %d Free file nodes in file system\n\ -+ %f Free blocks in file system\n\ -+ %C SELinux security context string\n\ -+"), stdout); -+ fputs (_("\ -+ %i File System ID in hex\n\ -+ %l Maximum length of filenames\n\ -+ %n File name\n\ -+ %s Block size (for faster transfers)\n\ -+ %S Fundamental block size (for block counts)\n\ -+ %t Type in hex\n\ -+ %T Type in human readable form\n\ -+"), stdout); -+ printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME); -+ emit_ancillary_info (); -+ } -+ exit (status); -+} -+ -+int -+main (int argc, char *argv[]) -+{ -+ int c; -+ int i; -+ bool fs = false; -+ bool terse = false; -+ char *format = NULL; -+ bool ok = true; -+ -+ initialize_main (&argc, &argv); -+ set_program_name (argv[0]); -+ setlocale (LC_ALL, ""); -+ bindtextdomain (PACKAGE, LOCALEDIR); -+ textdomain (PACKAGE); -+ -+ atexit (close_stdout); -+ -+ while ((c = getopt_long (argc, argv, "c:fLtZ", long_options, NULL)) != -1) -+ { -+ switch (c) -+ { -+ case PRINTF_OPTION: -+ format = optarg; -+ interpret_backslash_escapes = true; -+ trailing_delim = ""; -+ break; -+ -+ case 'c': -+ format = optarg; -+ interpret_backslash_escapes = false; -+ trailing_delim = "\n"; -+ break; -+ -+ case 'L': -+ follow_links = true; -+ break; -+ -+ case 'f': -+ fs = true; -+ break; -+ -+ case 't': -+ terse = true; -+ break; -+ -+ case 'Z': /* FIXME: remove in 2010 */ -+ /* Ignore, for compatibility with distributions -+ that implemented this before upstream. -+ But warn of impending removal. */ -+ error (0, 0, -+ _("the --context (-Z) option is obsolete and will be removed\n" -+ "in a future release")); -+ break; -+ -+ case_GETOPT_HELP_CHAR; -+ -+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -+ -+ default: -+ usage (EXIT_FAILURE); -+ } -+ } -+ -+ if (argc == optind) -+ { -+ error (0, 0, _("missing operand")); -+ usage (EXIT_FAILURE); -+ } -+ -+ for (i = optind; i < argc; i++) -+ ok &= (fs -+ ? do_statfs (argv[i], terse, format) -+ : do_stat (argv[i], terse, format)); -+ -+ exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); -+} diff -urNp coreutils-8.0-orig/tests/misc/selinux coreutils-8.0/tests/misc/selinux --- coreutils-8.0-orig/tests/misc/selinux 2009-09-01 13:01:16.000000000 +0200 +++ coreutils-8.0/tests/misc/selinux 2009-10-07 10:10:11.000000000 +0200 diff --git a/coreutils.spec b/coreutils.spec index 1937dff..cb36081 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -6,7 +6,7 @@ License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color From c8937976c4a8f7a49dd8bcfcdd5404fb2fb4d191 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 18 Nov 2009 14:51:34 +0000 Subject: [PATCH 063/523] return .xz source extension ;) --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index cb36081..1937dff 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -6,7 +6,7 @@ License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color From 4bef77de29e980c66d12d4b1d48a56c8ffaa227a Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Wed, 25 Nov 2009 22:47:36 +0000 Subject: [PATCH 064/523] Fix typo that causes a failure to update the common directory. (releng #2781) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 00f96eb..cdca58a 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ NAME := coreutils SPECFILE = $(firstword $(wildcard *.spec)) define find-makefile-common -for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done +for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done endef MAKEFILE_COMMON := $(shell $(find-makefile-common)) From 3cf2695be6c52e14051b41dbc908c37aeaf9743e Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Thu, 26 Nov 2009 01:33:08 +0000 Subject: [PATCH 065/523] Fix typo that causes a failure to update the common directory. (releng #2781) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 00f96eb..cdca58a 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ NAME := coreutils SPECFILE = $(firstword $(wildcard *.spec)) define find-makefile-common -for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done +for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done endef MAKEFILE_COMMON := $(shell $(find-makefile-common)) From c77f9b75dc94eec6cbce80acd4bc39a87174fc73 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 27 Nov 2009 13:24:09 +0000 Subject: [PATCH 066/523] new upstream release 8.1, rediffed patches, fix builds under koji --- .cvsignore | 2 +- coreutils-5.2.1-runuser.patch | 165 ++++++++++++---------- coreutils-6.10-configuration.patch | 12 ++ coreutils-8.1-kojiutimens-symlinks.patch | 75 ++++++++++ coreutils-8.1-unsearchablepath.patch | 43 ++++++ coreutils-DIR_COLORS | 2 +- coreutils-DIR_COLORS.256color | 2 +- coreutils-DIR_COLORS.lightbgcolor | 2 +- coreutils-getgrouplist.patch | 8 +- coreutils-i18n.patch | 2 +- coreutils-pam.patch | 81 +++++------ coreutils-selinux.patch | 166 +++++++++++------------ coreutils.spec | 17 ++- sources | 2 +- 14 files changed, 371 insertions(+), 208 deletions(-) create mode 100644 coreutils-8.1-kojiutimens-symlinks.patch create mode 100644 coreutils-8.1-unsearchablepath.patch diff --git a/.cvsignore b/.cvsignore index 245b011..17b0073 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-8.0.tar.xz +coreutils-8.1.tar.xz diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index ce80533..21efa5b 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-7.0.orig/AUTHORS coreutils-7.0/AUTHORS ---- coreutils-7.0.orig/AUTHORS 2008-08-24 22:58:15.000000000 +0200 -+++ coreutils-7.0/AUTHORS 2009-01-28 18:11:00.316247411 +0100 -@@ -64,6 +64,7 @@ pwd: Jim Meyering +diff -urNp coreutils-8.1-orig/AUTHORS coreutils-8.1/AUTHORS +--- coreutils-8.1-orig/AUTHORS 2009-11-06 18:04:10.000000000 +0100 ++++ coreutils-8.1/AUTHORS 2009-11-20 13:06:26.000000000 +0100 +@@ -65,6 +65,7 @@ readlink: Dmitry V. Levin rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering rmdir: David MacKenzie runcon: Russell Coker @@ -9,10 +9,23 @@ diff -urNp coreutils-7.0.orig/AUTHORS coreutils-7.0/AUTHORS seq: Ulrich Drepper sha1sum: Ulrich Drepper, Scott Miller, David Madore sha224sum: Ulrich Drepper, Scott Miller, David Madore -diff -urNp coreutils-7.0.orig/man/Makefile.am coreutils-7.0/man/Makefile.am ---- coreutils-7.0.orig/man/Makefile.am 2008-09-27 19:28:54.000000000 +0200 -+++ coreutils-7.0/man/Makefile.am 2009-01-28 18:11:00.317247417 +0100 -@@ -93,6 +93,7 @@ readlink.1: $(common_dep) $(srcdir)/read +diff -urNp coreutils-8.1-orig/man/help2man coreutils-8.1/man/help2man +--- coreutils-8.1-orig/man/help2man 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.1/man/help2man 2009-11-20 13:06:26.000000000 +0100 +@@ -556,6 +556,9 @@ while (length) + $include{$sect} .= $content; + } + ++# There is no info documentation for runuser (shared with su). ++$opt_no_info = 1 if $program eq 'runuser'; ++ + # Refer to the real documentation. + unless ($opt_no_info) + { +diff -urNp coreutils-8.1-orig/man/Makefile.am coreutils-8.1/man/Makefile.am +--- coreutils-8.1-orig/man/Makefile.am 2009-11-06 18:04:10.000000000 +0100 ++++ coreutils-8.1/man/Makefile.am 2009-11-20 13:06:26.000000000 +0100 +@@ -94,6 +94,7 @@ readlink.1: $(common_dep) $(srcdir)/read rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c @@ -20,9 +33,9 @@ diff -urNp coreutils-7.0.orig/man/Makefile.am coreutils-7.0/man/Makefile.am seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c -diff -urNp coreutils-7.0.orig/man/runuser.x coreutils-7.0/man/runuser.x ---- coreutils-7.0.orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-7.0/man/runuser.x 2009-01-28 18:11:00.321247443 +0100 +diff -urNp coreutils-8.1-orig/man/runuser.x coreutils-8.1/man/runuser.x +--- coreutils-8.1-orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.1/man/runuser.x 2009-11-20 13:06:26.000000000 +0100 @@ -0,0 +1,12 @@ +[NAME] +runuser \- run a shell with substitute user and group IDs @@ -36,13 +49,13 @@ diff -urNp coreutils-7.0.orig/man/runuser.x coreutils-7.0/man/runuser.x +.TP +since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR. +.br -diff -urNp coreutils-7.0.orig/README coreutils-7.0/README ---- coreutils-7.0.orig/README 2008-08-24 22:30:10.000000000 +0200 -+++ coreutils-7.0/README 2009-01-28 18:11:00.318247424 +0100 +diff -urNp coreutils-8.1-orig/README coreutils-8.1/README +--- coreutils-8.1-orig/README 2009-11-06 18:04:10.000000000 +0100 ++++ coreutils-8.1/README 2009-11-20 13:06:26.000000000 +0100 @@ -12,10 +12,10 @@ The programs that can be built with this factor false fmt fold groups head hostid hostname id install join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup - od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir + nproc od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir - runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf - sleep sort split stat stdbuf stty su sum sync tac tail tee test timeout - touch tr true truncate tsort tty uname unexpand uniq unlink uptime users @@ -54,30 +67,29 @@ diff -urNp coreutils-7.0.orig/README coreutils-7.0/README See the file NEWS for a list of major changes in the current release. -diff -urNp coreutils-7.0.orig/src/Makefile.am coreutils-7.0/src/Makefile.am ---- coreutils-7.0.orig/src/Makefile.am 2009-01-28 18:10:10.756926000 +0100 -+++ coreutils-7.0/src/Makefile.am 2009-01-28 18:11:59.658631933 +0100 -@@ -38,7 +38,7 @@ EXTRA_PROGRAMS = \ - shuf sort split sum tac tail tr tsort unexpand uniq wc \ - basename date dirname echo env expr factor false \ - id kill logname pathchk printenv printf pwd \ -- runcon seq sleep tee \ -+ runcon runuser seq sleep tee \ - test timeout true truncate tty whoami yes \ - base64 - -@@ -154,6 +154,10 @@ cp_LDADD += $(LIB_ACL) $(LIB_XATTR) - mv_LDADD += $(LIB_ACL) $(LIB_XATTR) - ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR) +diff -urNp coreutils-8.1-orig/src/Makefile.am coreutils-8.1/src/Makefile.am +--- coreutils-8.1-orig/src/Makefile.am 2009-11-20 13:06:00.000000000 +0100 ++++ coreutils-8.1/src/Makefile.am 2009-11-20 13:06:26.000000000 +0100 +@@ -100,6 +100,7 @@ EXTRA_PROGRAMS = \ + rm \ + rmdir \ + runcon \ ++ runuser \ + seq \ + sha1sum \ + sha224sum \ +@@ -296,6 +297,10 @@ cp_LDADD += $(copy_LDADD) + ginstall_LDADD += $(copy_LDADD) + mv_LDADD += $(copy_LDADD) +runuser_SOURCES = su.c +runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\"" +runuser_LDADD = $(LDADD) $(LIB_CRYPT) @LIB_PAM@ + - stat_LDADD = $(LDADD) $(LIB_SELINUX) - - # Append $(LIBICONV) to each program that uses proper_name_utf8. -@@ -173,7 +177,7 @@ RELEASE_YEAR = \ + remove_LDADD = + mv_LDADD += $(remove_LDADD) + rm_LDADD += $(remove_LDADD) +@@ -396,7 +401,7 @@ RELEASE_YEAR = \ `sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \ $(top_srcdir)/lib/version-etc.c` @@ -86,10 +98,10 @@ diff -urNp coreutils-7.0.orig/src/Makefile.am coreutils-7.0/src/Makefile.am installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'` -diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c ---- coreutils-7.0.orig/src/su.c 2009-01-28 18:10:10.801926000 +0100 -+++ coreutils-7.0/src/su.c 2009-01-28 18:11:00.320247437 +0100 -@@ -109,9 +109,15 @@ +diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c +--- coreutils-8.1-orig/src/su.c 2009-11-20 13:06:00.000000000 +0100 ++++ coreutils-8.1/src/su.c 2009-11-20 13:06:26.000000000 +0100 +@@ -102,9 +102,15 @@ #include "error.h" /* The official name of this program (e.g., no `g' prefix). */ @@ -105,7 +117,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c #if HAVE_PATHS_H # include -@@ -149,11 +155,18 @@ +@@ -142,9 +148,16 @@ #ifndef USE_PAM char *crypt (char const *key, char const *salt); #endif @@ -113,8 +125,6 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c +#define CHECKPASSWD 1 +#endif - extern char **environ; - static void run_shell (char const *, char const *, char **, size_t, - const struct passwd *) + const struct passwd * @@ -125,7 +135,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c #ifdef USE_PAM ; #else -@@ -183,6 +197,10 @@ static struct option const longopts[] = +@@ -171,6 +184,10 @@ static struct option const longopts[] = {"login", no_argument, NULL, 'l'}, {"preserve-environment", no_argument, NULL, 'p'}, {"shell", required_argument, NULL, 's'}, @@ -136,7 +146,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -284,10 +302,12 @@ correct_password (const struct passwd *p +@@ -272,10 +289,12 @@ correct_password (const struct passwd *p retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh); PAM_BAIL_P; @@ -149,7 +159,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c caller = getpwuid(getuid()); if(caller != NULL && caller->pw_name != NULL) { -@@ -304,6 +324,11 @@ correct_password (const struct passwd *p +@@ -292,6 +311,11 @@ correct_password (const struct passwd *p retval = pam_set_item(pamh, PAM_TTY, tty_name); PAM_BAIL_P; } @@ -161,7 +171,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c retval = pam_authenticate(pamh, 0); PAM_BAIL_P; retval = pam_acct_mgmt(pamh, 0); -@@ -313,6 +338,7 @@ correct_password (const struct passwd *p +@@ -301,6 +325,7 @@ correct_password (const struct passwd *p PAM_BAIL_P; } PAM_BAIL_P; @@ -169,7 +179,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c /* must be authenticated if this point was reached */ return 1; #else /* !USE_PAM */ -@@ -394,11 +420,22 @@ modify_environment (const struct passwd +@@ -382,11 +407,22 @@ modify_environment (const struct passwd /* Become the user and group(s) specified by PW. */ static void @@ -194,7 +204,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c #ifdef USE_PAM pam_close_session(pamh, 0); pam_end(pamh, PAM_ABORT); -@@ -445,7 +482,11 @@ pam_copyenv (pam_handle_t *pamh) +@@ -433,7 +469,11 @@ pam_copyenv (pam_handle_t *pamh) static void run_shell (char const *shell, char const *command, char **additional_args, @@ -207,7 +217,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c { size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; char const **args = xnmalloc (n_args, sizeof *args); -@@ -476,7 +517,11 @@ run_shell (char const *shell, char const +@@ -464,7 +504,11 @@ run_shell (char const *shell, char const child = fork(); if (child == 0) { /* child shell */ @@ -220,7 +230,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c pam_end(pamh, 0); if (!same_session) setsid (); -@@ -620,6 +665,28 @@ usage (int status) +@@ -608,6 +652,28 @@ usage (int status) else { printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name); @@ -249,7 +259,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c fputs (_("\ Change the effective user id and group id to that of USER.\n\ \n\ -@@ -632,6 +697,7 @@ Change the effective user id and group i +@@ -620,6 +686,7 @@ Change the effective user id and group i -p same as -m\n\ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ "), stdout); @@ -257,7 +267,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_("\ -@@ -653,6 +719,12 @@ main (int argc, char **argv) +@@ -641,6 +708,12 @@ main (int argc, char **argv) char *shell = NULL; struct passwd *pw; struct passwd pw_copy; @@ -270,7 +280,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -667,7 +739,11 @@ main (int argc, char **argv) +@@ -655,7 +728,11 @@ main (int argc, char **argv) simulate_login = false; change_environment = true; @@ -283,7 +293,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c { switch (optc) { -@@ -697,6 +773,28 @@ main (int argc, char **argv) +@@ -685,6 +762,28 @@ main (int argc, char **argv) shell = optarg; break; @@ -312,7 +322,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -@@ -735,7 +833,20 @@ main (int argc, char **argv) +@@ -723,7 +822,20 @@ main (int argc, char **argv) : DEFAULT_SHELL); endpwent (); @@ -334,7 +344,7 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c { #ifdef SYSLOG_FAILURE log_su (pw, false); -@@ -767,8 +878,16 @@ main (int argc, char **argv) +@@ -755,7 +867,11 @@ main (int argc, char **argv) modify_environment (pw, shell); #ifndef USE_PAM @@ -346,6 +356,11 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c + ); #endif + /* error() flushes stderr, but does not check for write failure. +@@ -766,5 +882,9 @@ main (int argc, char **argv) + if (ferror (stderr)) + exit (EXIT_CANCELED); + - run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); + run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw +#ifdef RUNUSER @@ -353,10 +368,18 @@ diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c +#endif + ); } -diff -urNp coreutils-7.5.orig/tests/misc/help-version coreutils-7.5/tests/misc/help-version ---- coreutils-7.5.orig/tests/misc/help-version -+++ coreutils-7.5/tests/misc/help-version -@@ -150,6 +150,7 @@ printf_args=foo +diff -urNp coreutils-8.1-orig/tests/misc/help-version coreutils-8.1/tests/misc/help-version +--- coreutils-8.1-orig/tests/misc/help-version 2009-11-14 15:01:44.000000000 +0100 ++++ coreutils-8.1/tests/misc/help-version 2009-11-20 13:06:26.000000000 +0100 +@@ -34,6 +34,7 @@ expected_failure_status_nohup=125 + expected_failure_status_stdbuf=125 + expected_failure_status_su=125 + expected_failure_status_timeout=125 ++expected_failure_status_runuser=125 + expected_failure_status_printenv=2 + expected_failure_status_tty=3 + expected_failure_status_sort=2 +@@ -153,6 +154,7 @@ seq_args=10 sleep_args=0 su_args=--version stdbuf_args="-oL true" @@ -364,16 +387,14 @@ diff -urNp coreutils-7.5.orig/tests/misc/help-version coreutils-7.5/tests/misc/h timeout_args=--version # I'd rather not run sync, since it spins up disks that I've -diff -urNp coreutils-7.6-orig/man/help2man coreutils-7.6/man/help2man ---- coreutils-7.6-orig/man/help2man 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-7.6/man/help2man 2009-09-22 15:15:01.000000000 +0200 -@@ -550,6 +550,9 @@ while (length) - $include{$sect} .= $content; - } - -+# There is no info documentation for runuser (shared with su). -+$opt_no_info = 1 if $program eq 'runuser'; -+ - # Refer to the real documentation. - unless ($opt_no_info) - { +diff -urNp coreutils-8.1-orig/tests/misc/invalid-opt coreutils-8.1/tests/misc/invalid-opt +--- coreutils-8.1-orig/tests/misc/invalid-opt 2009-10-26 10:05:25.000000000 +0100 ++++ coreutils-8.1/tests/misc/invalid-opt 2009-11-20 13:06:26.000000000 +0100 +@@ -37,6 +37,7 @@ my %exit_status = + sort => 2, + stdbuf => 125, + su => 125, ++ runuser => 125, + test => 0, + timeout => 125, + true => 0, diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 9b1ec54..ec832ac 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -66,3 +66,15 @@ diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c #include "acl.h" #include "argmatch.h" #include "dev-ino.h" +diff -urNp coreutils-8.1-orig/tests/touch/no-dereference coreutils-8.1/tests/touch/no-dereference +--- coreutils-8.1-orig/tests/touch/no-dereference 2009-10-30 12:51:07.000000000 +0100 ++++ coreutils-8.1/tests/touch/no-dereference 2009-11-27 13:31:10.000000000 +0100 +@@ -46,6 +46,8 @@ test -f nowhere && fail=1 + grep '^#define HAVE_UTIMENSAT' "$CONFIG_HEADER" > /dev/null || + grep '^#define HAVE_LUTIMES' "$CONFIG_HEADER" > /dev/null || + skip_test_ 'this system lacks the utimensat function' ++grep '^#define HAVE_WORKINGKOJI' "$CONFIG_HEADER" > /dev/null || ++ skip_test_ 'rest of the test disabled due to koji lack of utimensat function' + + # Changing time of dangling symlink is okay. + touch -h dangling || fail=1 diff --git a/coreutils-8.1-kojiutimens-symlinks.patch b/coreutils-8.1-kojiutimens-symlinks.patch new file mode 100644 index 0000000..94b6ee4 --- /dev/null +++ b/coreutils-8.1-kojiutimens-symlinks.patch @@ -0,0 +1,75 @@ +diff -urNp coreutils-8.1-orig/lib/utimens.c coreutils-8.1/lib/utimens.c +--- coreutils-8.1-orig/lib/utimens.c 2009-11-18 15:57:45.000000000 +0100 ++++ coreutils-8.1/lib/utimens.c 2009-11-27 13:02:03.000000000 +0100 +@@ -54,10 +54,12 @@ struct utimbuf + #undef utimensat + + #if HAVE_UTIMENSAT || HAVE_FUTIMENS +-/* Cache variable for whether syscall works; used to avoid calling the +- syscall if we know it will just fail with ENOSYS. 0 = unknown, 1 = +- yes, -1 = no. */ ++/* Cache variables for whether the utimensat syscall works; used to ++ avoid calling the syscall if we know it will just fail with ENOSYS. ++ There are some Linux kernel versions where a flag of 0 passes, but ++ not AT_SYMLINK_NOFOLLOW. 0 = unknown, 1 = yes, -1 = no. */ + static int utimensat_works_really; ++static int lutimensat_works_really; + #endif /* HAVE_UTIMENSAT || HAVE_UTIMENSAT */ + + /* Solaris 9 mistakenly succeeds when given a non-directory with a +@@ -242,6 +244,7 @@ fdutimens (char const *file, int fd, str + # endif /* HAVE_FUTIMENS */ + } + utimensat_works_really = -1; ++ lutimensat_works_really = -1; + #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ + + /* The platform lacks an interface to set file timestamps with +@@ -381,7 +384,7 @@ lutimens (char const *file, struct times + worry about bogus return values. */ + + #if HAVE_UTIMENSAT +- if (0 <= utimensat_works_really) ++ if (0 <= lutimensat_works_really) + { + int result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); + # ifdef __linux__ +@@ -397,11 +400,11 @@ lutimens (char const *file, struct times + # endif + if (result == 0 || errno != ENOSYS) + { +- utimensat_works_really = 1; ++ lutimensat_works_really = 1; + return result; + } + } +- utimensat_works_really = -1; ++ lutimensat_works_really = -1; + #endif /* HAVE_UTIMENSAT */ + + /* The platform lacks an interface to set file timestamps with +@@ -416,7 +419,9 @@ lutimens (char const *file, struct times + return 0; + } + +-#if HAVE_LUTIMES ++/* On Linux, lutimes is a thin wrapper around utimensat, so there is ++ no point trying lutimes if utimensat failed with ENOSYS. */ ++#if HAVE_LUTIMES && !HAVE_UTIMENSAT + { + struct timeval timeval[2]; + struct timeval const *t; +@@ -431,9 +436,11 @@ lutimens (char const *file, struct times + else + t = NULL; + +- return lutimes (file, t); ++ result = lutimes (file, t); ++ if (result == 0 || errno != ENOSYS) ++ return result; + } +-#endif /* HAVE_LUTIMES */ ++#endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */ + + /* Out of luck for symlinks, but we still handle regular files. */ + if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st)) diff --git a/coreutils-8.1-unsearchablepath.patch b/coreutils-8.1-unsearchablepath.patch new file mode 100644 index 0000000..ac71950 --- /dev/null +++ b/coreutils-8.1-unsearchablepath.patch @@ -0,0 +1,43 @@ +diff -urNp coreutils-8.1-orig/tests/test-lib.sh coreutils-8.1/tests/test-lib.sh +--- coreutils-8.1-orig/tests/test-lib.sh 2009-11-24 09:35:12.000000000 +0100 ++++ coreutils-8.1/tests/test-lib.sh 2009-11-24 09:37:17.000000000 +0100 +@@ -23,6 +23,31 @@ if test $? != 11; then + Exit 77 + fi + ++# Having an unsearchable directory in PATH causes execve to fail with EACCES ++# when applied to an unresolvable program name, contrary to the desired ENOENT. ++# Avoid the problem by rewriting PATH to exclude unsearchable directories. ++sanitize_path_() ++{ ++ local saved_IFS=$IFS ++ IFS=: ++ set - $PATH ++ IFS=$saved_IFS ++ ++ local d d1 ++ local colon= ++ local new_path= ++ for d in "$@"; do ++ test -z "$d" && d1=. || d1=$d ++ if ls -d "$d1/." > /dev/null 2>&1; then ++ new_path="$new_path$colon$d" ++ colon=':' ++ fi ++ done ++ ++ PATH=$new_path ++ export PATH ++} ++ + skip_test_() + { + echo "$0: skipping test: $@" | head -1 1>&9 +@@ -396,5 +421,7 @@ else + compare() { cmp "$@"; } + fi + ++sanitize_path_ ++ + # Initialize; all bourne shell scripts end with "Exit $fail". + fail=0 diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 47386de..8aec576 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -1,5 +1,5 @@ # Configuration file for the color ls utility -# Synchronized with coreutils 7.1 dircolors +# Synchronized with coreutils 8.1 dircolors # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 8155775..e757fe1 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -1,6 +1,6 @@ # Configuration file for the 256color ls utility # This file goes in the /etc directory, and must be world readable. -# Synchronized with coreutils 7.1 dircolors +# Synchronized with coreutils 8.1 dircolors # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. # In the case that you are not satisfied with supplied colors, please diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index fbd1609..ce55538 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -1,5 +1,5 @@ # Configuration file for the color ls utility - modified for gray backgrounds -# Synchronized with coreutils 7.1 dircolors +# Synchronized with coreutils 8.1 dircolors # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch index 9ef6ad0..e5c2985 100644 --- a/coreutils-getgrouplist.patch +++ b/coreutils-getgrouplist.patch @@ -10,11 +10,11 @@ diff -urp coreutils-6.10-orig/lib/getugroups.c coreutils-6.10/lib/getugroups.c + #include "getugroups.h" - #include -@@ -114,3 +117,4 @@ getugroups (int maxcount, GETGROUPS_T *g - - return count; + #include +@@ -123,3 +126,4 @@ getugroups (int maxcount, GETGROUPS_T *g } + + #endif /* HAVE_GRP_H */ +#endif /* have getgrouplist */ diff -urp coreutils-6.10-orig/m4/jm-macros.m4 coreutils-6.10/m4/jm-macros.m4 --- coreutils-6.10-orig/m4/jm-macros.m4 2007-11-25 14:23:31.000000000 +0100 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 731ca3f..6c34d06 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -3557,7 +3557,7 @@ diff -urNp coreutils-8.0-orig/src/uniq.c coreutils-8.0/src/uniq.c #include "argmatch.h" #include "linebuffer.h" @@ -31,7 +41,19 @@ - #include "quote.h" + #include "stdio--.h" #include "xmemcoll.h" #include "xstrtol.h" -#include "memcasecmp.h" diff --git a/coreutils-pam.patch b/coreutils-pam.patch index 24f7437..ae6d1be 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -1,8 +1,8 @@ -diff -urNp coreutils-8.0-orig/configure.ac coreutils-8.0/configure.ac ---- coreutils-8.0-orig/configure.ac 2009-09-29 15:27:11.000000000 +0200 -+++ coreutils-8.0/configure.ac 2009-10-07 10:04:27.000000000 +0200 -@@ -115,6 +115,13 @@ if test "$gl_gcc_warnings" = yes; then - AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) +diff -urNp coreutils-8.1-orig/configure.ac coreutils-8.1/configure.ac +--- coreutils-8.1-orig/configure.ac 2009-11-14 15:01:44.000000000 +0100 ++++ coreutils-8.1/configure.ac 2009-11-20 13:00:10.000000000 +0100 +@@ -126,6 +126,13 @@ if test "$gl_gcc_warnings" = yes; then + AC_SUBST([GNULIB_WARN_CFLAGS]) fi +dnl Give the chance to enable PAM @@ -15,10 +15,10 @@ diff -urNp coreutils-8.0-orig/configure.ac coreutils-8.0/configure.ac AC_FUNC_FORK optional_bin_progs= -diff -urNp coreutils-8.0-orig/doc/coreutils.texi coreutils-8.0/doc/coreutils.texi ---- coreutils-8.0-orig/doc/coreutils.texi 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.0/doc/coreutils.texi 2009-10-07 10:04:27.000000000 +0200 -@@ -14742,8 +14742,11 @@ to certain shells, etc.). +diff -urNp coreutils-8.1-orig/doc/coreutils.texi coreutils-8.1/doc/coreutils.texi +--- coreutils-8.1-orig/doc/coreutils.texi 2009-11-10 13:57:56.000000000 +0100 ++++ coreutils-8.1/doc/coreutils.texi 2009-11-20 13:00:10.000000000 +0100 +@@ -15070,8 +15070,11 @@ to certain shells, etc.). @findex syslog @command{su} can optionally be compiled to use @code{syslog} to report failed, and optionally successful, @command{su} attempts. (If the system @@ -32,7 +32,7 @@ diff -urNp coreutils-8.0-orig/doc/coreutils.texi coreutils-8.0/doc/coreutils.tex The program accepts the following options. Also see @ref{Common options}. -@@ -14785,6 +14788,8 @@ environment variables except @env{TERM}, +@@ -15113,6 +15116,8 @@ environment variables except @env{TERM}, @env{PATH} to a compiled-in default value. Change to @var{user}'s home directory. Prepend @samp{-} to the shell's name, intended to make it read its login startup file(s). @@ -41,7 +41,7 @@ diff -urNp coreutils-8.0-orig/doc/coreutils.texi coreutils-8.0/doc/coreutils.tex @item -m @itemx -p -@@ -14824,33 +14829,6 @@ Exit status: +@@ -15152,33 +15157,6 @@ Exit status: the exit status of the subshell otherwise @end display @@ -75,21 +75,21 @@ diff -urNp coreutils-8.0-orig/doc/coreutils.texi coreutils-8.0/doc/coreutils.tex @node timeout invocation @section @command{timeout}: Run a command with a time limit -diff -urNp coreutils-8.0-orig/src/Makefile.am coreutils-8.0/src/Makefile.am ---- coreutils-8.0-orig/src/Makefile.am 2009-09-21 14:29:33.000000000 +0200 -+++ coreutils-8.0/src/Makefile.am 2009-10-07 10:04:27.000000000 +0200 -@@ -154,7 +154,7 @@ tail_LDADD = $(nanosec_libs) - # If necessary, add -lm to resolve use of pow in lib/strtod.c. - uptime_LDADD = $(LDADD) $(POW_LIB) $(GETLOADAVG_LIBS) +diff -urNp coreutils-8.1-orig/src/Makefile.am coreutils-8.1/src/Makefile.am +--- coreutils-8.1-orig/src/Makefile.am 2009-11-06 18:04:10.000000000 +0100 ++++ coreutils-8.1/src/Makefile.am 2009-11-20 13:00:10.000000000 +0100 +@@ -359,7 +359,7 @@ factor_LDADD += $(LIB_GMP) + uptime_LDADD += $(GETLOADAVG_LIBS) --su_LDADD = $(LDADD) $(LIB_CRYPT) -+su_LDADD = $(LDADD) $(LIB_CRYPT) @LIB_PAM@ + # for crypt +-su_LDADD += $(LIB_CRYPT) ++su_LDADD += $(LIB_CRYPT) @LIB_PAM@ - dir_LDADD += $(LIB_ACL) - ls_LDADD += $(LIB_ACL) -diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c ---- coreutils-8.0-orig/src/su.c 2009-10-07 10:03:29.000000000 +0200 -+++ coreutils-8.0/src/su.c 2009-10-07 10:04:27.000000000 +0200 + # for various ACL functions + copy_LDADD += $(LIB_ACL) +diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c +--- coreutils-8.1-orig/src/su.c 2009-11-20 12:59:39.000000000 +0100 ++++ coreutils-8.1/src/su.c 2009-11-20 13:00:10.000000000 +0100 @@ -37,6 +37,16 @@ restricts who can su to UID 0 accounts. RMS considers that to be fascist. @@ -123,7 +123,7 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c #include "system.h" #include "getpass.h" -@@ -120,12 +139,19 @@ +@@ -120,10 +139,17 @@ /* The user to become if none is specified. */ #define DEFAULT_USER "root" @@ -131,8 +131,6 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c char *crypt (char const *key, char const *salt); +#endif - extern char **environ; - -static void run_shell (char const *, char const *, char **, size_t) +static void run_shell (char const *, char const *, char **, size_t, + const struct passwd *) @@ -144,7 +142,7 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c /* If true, pass the `-f' option to the subshell. */ static bool fast_startup; -@@ -211,7 +237,26 @@ log_su (struct passwd const *pw, bool su +@@ -209,7 +235,26 @@ log_su (struct passwd const *pw, bool su } #endif @@ -171,7 +169,7 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c Return true if the user gives the correct password for entry PW, false if not. Return true without asking for a password if run by UID 0 or if PW has an empty password. */ -@@ -219,6 +264,44 @@ log_su (struct passwd const *pw, bool su +@@ -217,6 +262,44 @@ log_su (struct passwd const *pw, bool su static bool correct_password (const struct passwd *pw) { @@ -216,7 +214,7 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c char *unencrypted, *encrypted, *correct; #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP /* Shadow passwd stuff for SVR3 and maybe other systems. */ -@@ -243,6 +326,7 @@ correct_password (const struct passwd *p +@@ -241,6 +324,7 @@ correct_password (const struct passwd *p encrypted = crypt (unencrypted, correct); memset (unencrypted, 0, strlen (unencrypted)); return STREQ (encrypted, correct); @@ -224,7 +222,7 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c } /* Update `environ' for the new shell based on PW, with SHELL being -@@ -256,12 +340,18 @@ modify_environment (const struct passwd +@@ -254,12 +338,18 @@ modify_environment (const struct passwd /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. Unset all other environment variables. */ char const *term = getenv ("TERM"); @@ -243,7 +241,7 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c xsetenv ("HOME", pw->pw_dir); xsetenv ("SHELL", shell); xsetenv ("USER", pw->pw_name); -@@ -294,8 +384,13 @@ change_identity (const struct passwd *pw +@@ -292,8 +382,13 @@ change_identity (const struct passwd *pw { #ifdef HAVE_INITGROUPS errno = 0; @@ -253,13 +251,13 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c + pam_close_session(pamh, 0); + pam_end(pamh, PAM_ABORT); +#endif - error (EXIT_FAILURE, errno, _("cannot set groups")); + error (EXIT_CANCELED, errno, _("cannot set groups")); + } endgrent (); #endif if (setgid (pw->pw_gid)) -@@ -304,6 +399,31 @@ change_identity (const struct passwd *pw - error (EXIT_FAILURE, errno, _("cannot set user id")); +@@ -302,6 +397,31 @@ change_identity (const struct passwd *pw + error (EXIT_CANCELED, errno, _("cannot set user id")); } +#ifdef USE_PAM @@ -290,7 +288,7 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c /* Run SHELL, or DEFAULT_SHELL if SHELL is empty. If COMMAND is nonzero, pass it to the shell with the -c option. Pass ADDITIONAL_ARGS to the shell as more arguments; there -@@ -311,17 +431,49 @@ change_identity (const struct passwd *pw +@@ -309,17 +429,49 @@ change_identity (const struct passwd *pw static void run_shell (char const *shell, char const *command, char **additional_args, @@ -341,7 +339,7 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c shell_basename = last_component (shell); arg0 = xmalloc (strlen (shell_basename) + 2); arg0[0] = '-'; -@@ -346,6 +498,66 @@ run_shell (char const *shell, char const +@@ -344,6 +496,66 @@ run_shell (char const *shell, char const error (0, errno, "%s", shell); exit (exit_status); } @@ -408,7 +406,7 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c } /* Return true if SHELL is a restricted shell (one not returned by -@@ -513,9 +725,9 @@ main (int argc, char **argv) +@@ -511,9 +723,9 @@ main (int argc, char **argv) shell = xstrdup (shell ? shell : pw->pw_shell); modify_environment (pw, shell); @@ -418,7 +416,12 @@ diff -urNp coreutils-8.0-orig/src/su.c coreutils-8.0/src/su.c - error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); +#endif + /* error() flushes stderr, but does not check for write failure. + Normally, we would catch this via our atexit() hook of +@@ -523,5 +735,5 @@ main (int argc, char **argv) + if (ferror (stderr)) + exit (EXIT_CANCELED); + - run_shell (shell, command, argv + optind, MAX (0, argc - optind)); + run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); } - diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index a2dc61d..f557dca 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.0-orig/configure.ac coreutils-8.0/configure.ac ---- coreutils-8.0-orig/configure.ac 2009-10-07 10:09:43.000000000 +0200 -+++ coreutils-8.0/configure.ac 2009-10-07 10:10:11.000000000 +0200 -@@ -122,6 +122,13 @@ AC_ARG_ENABLE(pam, dnl +diff -urNp coreutils-8.1-orig/configure.ac coreutils-8.1/configure.ac +--- coreutils-8.1-orig/configure.ac 2009-11-20 13:11:20.000000000 +0100 ++++ coreutils-8.1/configure.ac 2009-11-20 13:11:40.000000000 +0100 +@@ -133,6 +133,13 @@ AC_ARG_ENABLE(pam, dnl LIB_PAM="-ldl -lpam -lpam_misc" AC_SUBST(LIB_PAM)]) @@ -15,18 +15,18 @@ diff -urNp coreutils-8.0-orig/configure.ac coreutils-8.0/configure.ac AC_FUNC_FORK optional_bin_progs= -diff -urNp coreutils-8.0-orig/man/chcon.x coreutils-8.0/man/chcon.x ---- coreutils-8.0-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.0/man/chcon.x 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/man/chcon.x coreutils-8.1/man/chcon.x +--- coreutils-8.1-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.1/man/chcon.x 2009-11-20 13:11:40.000000000 +0100 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-8.0-orig/man/runcon.x coreutils-8.0/man/runcon.x ---- coreutils-8.0-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.0/man/runcon.x 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/man/runcon.x coreutils-8.1/man/runcon.x +--- coreutils-8.1-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.1/man/runcon.x 2009-11-20 13:11:40.000000000 +0100 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,10 +34,10 @@ diff -urNp coreutils-8.0-orig/man/runcon.x coreutils-8.0/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.0-orig/src/copy.c coreutils-8.0/src/copy.c ---- coreutils-8.0-orig/src/copy.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.0/src/copy.c 2009-10-07 10:10:11.000000000 +0200 -@@ -1943,6 +1943,8 @@ copy_internal (char const *src_name, cha +diff -urNp coreutils-8.1-orig/src/copy.c coreutils-8.1/src/copy.c +--- coreutils-8.1-orig/src/copy.c 2009-10-22 11:18:05.000000000 +0200 ++++ coreutils-8.1/src/copy.c 2009-11-20 13:11:40.000000000 +0100 +@@ -1935,6 +1935,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -46,9 +46,9 @@ diff -urNp coreutils-8.0-orig/src/copy.c coreutils-8.0/src/copy.c } else { -diff -urNp coreutils-8.0-orig/src/copy.h coreutils-8.0/src/copy.h ---- coreutils-8.0-orig/src/copy.h 2009-09-21 14:29:33.000000000 +0200 -+++ coreutils-8.0/src/copy.h 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/src/copy.h coreutils-8.1/src/copy.h +--- coreutils-8.1-orig/src/copy.h 2009-09-21 14:29:33.000000000 +0200 ++++ coreutils-8.1/src/copy.h 2009-11-20 13:11:40.000000000 +0100 @@ -158,6 +158,9 @@ struct cp_options bool preserve_mode; bool preserve_timestamps; @@ -59,9 +59,9 @@ diff -urNp coreutils-8.0-orig/src/copy.h coreutils-8.0/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urNp coreutils-8.0-orig/src/cp.c coreutils-8.0/src/cp.c ---- coreutils-8.0-orig/src/cp.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.0/src/cp.c 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/src/cp.c coreutils-8.1/src/cp.c +--- coreutils-8.1-orig/src/cp.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.1/src/cp.c 2009-11-20 13:11:40.000000000 +0100 @@ -139,6 +139,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, @@ -150,10 +150,10 @@ diff -urNp coreutils-8.0-orig/src/cp.c coreutils-8.0/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urNp coreutils-8.0-orig/src/chcon.c coreutils-8.0/src/chcon.c ---- coreutils-8.0-orig/src/chcon.c 2009-10-06 10:55:34.000000000 +0200 -+++ coreutils-8.0/src/chcon.c 2009-10-07 10:10:11.000000000 +0200 -@@ -348,7 +348,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ +diff -urNp coreutils-8.1-orig/src/chcon.c coreutils-8.1/src/chcon.c +--- coreutils-8.1-orig/src/chcon.c 2009-11-07 08:46:30.000000000 +0100 ++++ coreutils-8.1/src/chcon.c 2009-11-20 13:11:40.000000000 +0100 +@@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), program_name, program_name, program_name); fputs (_("\ @@ -162,9 +162,9 @@ diff -urNp coreutils-8.0-orig/src/chcon.c coreutils-8.0/src/chcon.c With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ -h, --no-dereference affect symbolic links instead of any referenced file\n\ -diff -urNp coreutils-8.0-orig/src/id.c coreutils-8.0/src/id.c ---- coreutils-8.0-orig/src/id.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.0/src/id.c 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/src/id.c coreutils-8.1/src/id.c +--- coreutils-8.1-orig/src/id.c 2009-11-13 15:56:41.000000000 +0100 ++++ coreutils-8.1/src/id.c 2009-11-20 13:11:40.000000000 +0100 @@ -107,7 +107,7 @@ int main (int argc, char **argv) { @@ -174,9 +174,9 @@ diff -urNp coreutils-8.0-orig/src/id.c coreutils-8.0/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urNp coreutils-8.0-orig/src/install.c coreutils-8.0/src/install.c ---- coreutils-8.0-orig/src/install.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.0/src/install.c 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/src/install.c coreutils-8.1/src/install.c +--- coreutils-8.1-orig/src/install.c 2009-09-29 15:27:54.000000000 +0200 ++++ coreutils-8.1/src/install.c 2009-11-20 13:11:40.000000000 +0100 @@ -284,6 +284,7 @@ cp_option_init (struct cp_options *x) x->reduce_diagnostics=false; x->require_preserve = false; @@ -232,9 +232,9 @@ diff -urNp coreutils-8.0-orig/src/install.c coreutils-8.0/src/install.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); -diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c ---- coreutils-8.0-orig/src/ls.c 2009-10-07 10:09:43.000000000 +0200 -+++ coreutils-8.0/src/ls.c 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c +--- coreutils-8.1-orig/src/ls.c 2009-11-20 13:11:20.000000000 +0100 ++++ coreutils-8.1/src/ls.c 2009-11-20 13:11:40.000000000 +0100 @@ -162,7 +162,8 @@ enum filetype symbolic_link, sock, @@ -384,7 +384,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c default: usage (LS_FAILURE); } -@@ -2651,8 +2675,10 @@ clear_files (void) +@@ -2682,8 +2706,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); @@ -397,7 +397,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c } cwd_n_used = 0; -@@ -2694,6 +2720,7 @@ gobble_file (char const *name, enum file +@@ -2725,6 +2751,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -405,16 +405,16 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c if (command_line_arg || format_needs_stat -@@ -2793,7 +2820,7 @@ gobble_file (char const *name, enum file - - f->stat_ok = true; +@@ -2834,7 +2861,7 @@ gobble_file (char const *name, enum file + && print_with_color && is_colored (C_CAP)) + f->has_capability = has_capability (absolute_name); - if (format == long_format || print_scontext) + if (format == long_format || format == security_format || print_scontext) { bool have_selinux = false; bool have_acl = false; -@@ -2827,7 +2854,7 @@ gobble_file (char const *name, enum file +@@ -2857,7 +2884,7 @@ gobble_file (char const *name, enum file err = 0; } @@ -423,7 +423,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c { int n = file_has_acl (absolute_name, &f->stat); err = (n < 0); -@@ -2846,7 +2873,8 @@ gobble_file (char const *name, enum file +@@ -2876,7 +2903,8 @@ gobble_file (char const *name, enum file } if (S_ISLNK (f->stat.st_mode) @@ -433,7 +433,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c { char *linkname; struct stat linkstats; -@@ -2866,6 +2894,7 @@ gobble_file (char const *name, enum file +@@ -2896,6 +2924,7 @@ gobble_file (char const *name, enum file command line are automatically traced if not being listed as files. */ if (!command_line_arg || format == long_format @@ -441,7 +441,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c || !S_ISDIR (linkstats.st_mode)) { /* Get the linked-to file's mode for the filetype indicator -@@ -2905,7 +2934,7 @@ gobble_file (char const *name, enum file +@@ -2935,7 +2964,7 @@ gobble_file (char const *name, enum file block_size_width = len; } @@ -450,7 +450,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c { if (print_owner) { -@@ -3406,6 +3435,13 @@ print_current_files (void) +@@ -3436,6 +3465,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -464,7 +464,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c break; } } -@@ -3568,6 +3604,69 @@ format_inode (char *buf, size_t buflen, +@@ -3598,6 +3634,67 @@ format_inode (char *buf, size_t buflen, : (char *) "?"); } @@ -513,14 +513,12 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c + + DIRED_INDENT (); + DIRED_FPUTS (buf, stdout, p - buf); -+ size_t w = print_name_with_quoting (f->name, FILE_OR_LINK_MODE(f), f->linkok, -+ f->stat_ok, f->filetype, &dired_obstack, f->stat.st_nlink, p - buf); ++ size_t w = print_name_with_quoting (f, false, &dired_obstack, p - buf); + + if (f->filetype == symbolic_link) { + if (f->linkname) { + DIRED_FPUTS_LITERAL (" -> ", stdout); -+ print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1, -+ f->stat_ok, f->filetype, NULL, f->stat.st_nlink, (p-buf) + w + 4 ); ++ print_name_with_quoting (f, true, NULL, (p - buf) + w + 4); + if (indicator_style != none) + print_type_indicator (f->stat_ok, f->linkmode, f->filetype); + } @@ -534,7 +532,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c /* Print information about F in long format. */ static void print_long_format (const struct fileinfo *f) -@@ -3659,9 +3758,15 @@ print_long_format (const struct fileinfo +@@ -3689,9 +3786,15 @@ print_long_format (const struct fileinfo The latter is wrong when nlink_width is zero. */ p += strlen (p); @@ -551,7 +549,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c { DIRED_FPUTS (buf, stdout, p - buf); -@@ -3674,9 +3779,6 @@ print_long_format (const struct fileinfo +@@ -3704,9 +3807,6 @@ print_long_format (const struct fileinfo if (print_author) format_user (f->stat.st_author, author_width, f->stat_ok); @@ -561,17 +559,17 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c p = buf; } -@@ -4020,9 +4122,6 @@ print_file_name_and_frills (const struct +@@ -4047,9 +4147,6 @@ print_file_name_and_frills (const struct : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ST_NBLOCKSIZE, output_block_size)); - if (print_scontext) - printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext); - - size_t width = print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), - f->linkok, f->stat_ok, f->filetype, - NULL, f->stat.st_nlink, start_col); -@@ -4241,9 +4340,6 @@ length_of_file_name_and_frills (const st + size_t width = print_name_with_quoting (f, false, NULL, start_col); + + if (indicator_style != none) +@@ -4248,9 +4345,6 @@ length_of_file_name_and_frills (const st output_block_size)) : block_size_width); @@ -581,7 +579,7 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c quote_name (NULL, f->name, filename_quoting_options, &name_width); len += name_width; -@@ -4674,9 +4770,16 @@ Mandatory arguments to long options are +@@ -4681,9 +4775,16 @@ Mandatory arguments to long options are -w, --width=COLS assume screen width instead of current value\n\ -x list entries by lines instead of by columns\n\ -X sort alphabetically by entry extension\n\ @@ -599,9 +597,9 @@ diff -urNp coreutils-8.0-orig/src/ls.c coreutils-8.0/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-8.0-orig/src/mkdir.c coreutils-8.0/src/mkdir.c ---- coreutils-8.0-orig/src/mkdir.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.0/src/mkdir.c 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/src/mkdir.c coreutils-8.1/src/mkdir.c +--- coreutils-8.1-orig/src/mkdir.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.1/src/mkdir.c 2009-11-20 13:11:40.000000000 +0100 @@ -38,6 +38,7 @@ static struct option const longopts[] = { @@ -610,9 +608,9 @@ diff -urNp coreutils-8.0-orig/src/mkdir.c coreutils-8.0/src/mkdir.c {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, -diff -urNp coreutils-8.0-orig/src/mknod.c coreutils-8.0/src/mknod.c ---- coreutils-8.0-orig/src/mknod.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.0/src/mknod.c 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/src/mknod.c coreutils-8.1/src/mknod.c +--- coreutils-8.1-orig/src/mknod.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.1/src/mknod.c 2009-11-20 13:11:40.000000000 +0100 @@ -35,7 +35,7 @@ static struct option const longopts[] = @@ -622,9 +620,9 @@ diff -urNp coreutils-8.0-orig/src/mknod.c coreutils-8.0/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urNp coreutils-8.0-orig/src/mv.c coreutils-8.0/src/mv.c ---- coreutils-8.0-orig/src/mv.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.0/src/mv.c 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/src/mv.c coreutils-8.1/src/mv.c +--- coreutils-8.1-orig/src/mv.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.1/src/mv.c 2009-11-20 13:11:40.000000000 +0100 @@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x) x->preserve_mode = true; x->preserve_timestamps = true; @@ -633,9 +631,9 @@ diff -urNp coreutils-8.0-orig/src/mv.c coreutils-8.0/src/mv.c x->reduce_diagnostics = false; x->require_preserve = false; /* FIXME: maybe make this an option */ x->require_preserve_context = false; -diff -urNp coreutils-8.0-orig/src/runcon.c coreutils-8.0/src/runcon.c ---- coreutils-8.0-orig/src/runcon.c 2009-10-06 10:55:34.000000000 +0200 -+++ coreutils-8.0/src/runcon.c 2009-10-07 10:10:11.000000000 +0200 +diff -urNp coreutils-8.1-orig/src/runcon.c coreutils-8.1/src/runcon.c +--- coreutils-8.1-orig/src/runcon.c 2009-10-29 14:53:40.000000000 +0100 ++++ coreutils-8.1/src/runcon.c 2009-11-20 13:11:40.000000000 +0100 @@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ "), program_name, program_name); @@ -645,10 +643,10 @@ diff -urNp coreutils-8.0-orig/src/runcon.c coreutils-8.0/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c ---- coreutils-8.0-orig/src/stat.c 2009-09-29 16:25:44.000000000 +0200 -+++ coreutils-8.0/src/stat.c 2009-10-07 10:10:11.000000000 +0200 -@@ -825,7 +825,7 @@ print_it (char const *format, char const +diff -urNp coreutils-8.1-orig/src/stat.c coreutils-8.1/src/stat.c +--- coreutils-8.1-orig/src/stat.c 2009-10-29 11:11:29.000000000 +0100 ++++ coreutils-8.1/src/stat.c 2009-11-20 13:11:40.000000000 +0100 +@@ -858,7 +858,7 @@ print_it (char const *format, char const /* Stat the file system and print what we find. */ static bool @@ -657,7 +655,7 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c { STRUCT_STATVFS statfsbuf; -@@ -844,15 +844,31 @@ do_statfs (char const *filename, bool te +@@ -877,15 +877,31 @@ do_statfs (char const *filename, bool te } if (format == NULL) @@ -694,7 +692,7 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c print_it (format, filename, print_statfs, &statfsbuf); return true; -@@ -860,7 +876,7 @@ do_statfs (char const *filename, bool te +@@ -893,7 +909,7 @@ do_statfs (char const *filename, bool te /* stat the file and print what we find */ static bool @@ -703,7 +701,7 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c { struct stat statbuf; -@@ -881,9 +897,12 @@ do_stat (char const *filename, bool ters +@@ -919,9 +935,12 @@ do_stat (char const *filename, bool ters if (format == NULL) { if (terse) @@ -719,7 +717,7 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c else { /* Temporary hack to match original output until conditional -@@ -900,12 +919,22 @@ do_stat (char const *filename, bool ters +@@ -938,12 +957,22 @@ do_stat (char const *filename, bool ters } else { @@ -748,7 +746,7 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c } } } -@@ -926,6 +955,7 @@ usage (int status) +@@ -964,6 +993,7 @@ usage (int status) Display file or file system status.\n\ \n\ -L, --dereference follow links\n\ @@ -756,7 +754,7 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c -f, --file-system display file system status instead of file status\n\ "), stdout); fputs (_("\ -@@ -1010,6 +1040,7 @@ main (int argc, char *argv[]) +@@ -1048,6 +1078,7 @@ main (int argc, char *argv[]) int i; bool fs = false; bool terse = false; @@ -764,7 +762,7 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c char *format = NULL; bool ok = true; -@@ -1049,13 +1080,13 @@ main (int argc, char *argv[]) +@@ -1087,13 +1118,13 @@ main (int argc, char *argv[]) terse = true; break; @@ -785,7 +783,7 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c break; case_GETOPT_HELP_CHAR; -@@ -1075,8 +1106,8 @@ main (int argc, char *argv[]) +@@ -1113,8 +1144,8 @@ main (int argc, char *argv[]) for (i = optind; i < argc; i++) ok &= (fs @@ -796,10 +794,10 @@ diff -urNp coreutils-8.0-orig/src/stat.c coreutils-8.0/src/stat.c exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } -diff -urNp coreutils-8.0-orig/tests/misc/selinux coreutils-8.0/tests/misc/selinux ---- coreutils-8.0-orig/tests/misc/selinux 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.0/tests/misc/selinux 2009-10-07 10:10:11.000000000 +0200 -@@ -30,7 +30,7 @@ chcon $ctx f d p || +diff -urNp coreutils-8.1-orig/tests/misc/selinux coreutils-8.1/tests/misc/selinux +--- coreutils-8.1-orig/tests/misc/selinux 2009-10-30 12:51:07.000000000 +0100 ++++ coreutils-8.1/tests/misc/selinux 2009-11-20 13:11:40.000000000 +0100 +@@ -29,7 +29,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. for i in d f p; do diff --git a/coreutils.spec b/coreutils.spec index 1937dff..026f914 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.0 -Release: 2%{?dist} +Version: 8.1 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,6 +18,8 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream +Patch1: coreutils-8.1-unsearchablepath.patch +Patch2: coreutils-8.1-kojiutimens-symlinks.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -59,6 +61,7 @@ BuildRequires: automake >= 1.10.1 BuildRequires: libcap-devel >= 2.0.6 BuildRequires: libattr-devel BuildRequires: attr +BuildRequires: strace Requires(post): libselinux >= 1.25.6-1 Requires: libattr @@ -107,6 +110,8 @@ Libraries for coreutils package. %setup -q # From upstream +%patch1 -p1 -b .path +%patch2 -p1 -b .koji # Our patches %patch100 -p1 -b .configure @@ -154,7 +159,7 @@ touch aclocal.m4 configure config.hin Makefile.in */Makefile.in aclocal -I m4 autoconf --force automake --copy --add-missing -%configure --enable-largefile --with-afs %{?!nopam:--enable-pam} \ +%configure --enable-largefile %{?!nopam:--enable-pam} \ --enable-selinux \ --enable-install-program=su,hostname,arch \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : @@ -325,6 +330,12 @@ fi %{_libdir}/coreutils %changelog +* Fri Nov 27 2009 Ondrej Vasik - 8.1-1 +- new upstream release 8.1 +- fix build under koji (no test failures with underlying + RHEL-5 XEN kernel due to unsearchable path and lack of + futimens functionality) + * Wed Oct 07 2009 Ondrej Vasik - 8.0-2 - update /etc/DIR_COLORS* files diff --git a/sources b/sources index e831813..1da9204 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -fe3bb9376150acb5af4a2a280d6fd91a coreutils-8.0.tar.xz +e8ab20814c61924197c0951ee292c38a coreutils-8.1.tar.xz From e6c89339d82a8e50339eed2ccb039af89e5b3369 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 11 Dec 2009 16:38:48 +0000 Subject: [PATCH 067/523] new upstream release 8.2, remove applied patches --- coreutils-8.1-kojiutimens-symlinks.patch | 75 ------------------------ coreutils-8.1-unsearchablepath.patch | 43 -------------- coreutils.spec | 10 ++-- sources | 2 +- 4 files changed, 6 insertions(+), 124 deletions(-) delete mode 100644 coreutils-8.1-kojiutimens-symlinks.patch delete mode 100644 coreutils-8.1-unsearchablepath.patch diff --git a/coreutils-8.1-kojiutimens-symlinks.patch b/coreutils-8.1-kojiutimens-symlinks.patch deleted file mode 100644 index 94b6ee4..0000000 --- a/coreutils-8.1-kojiutimens-symlinks.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff -urNp coreutils-8.1-orig/lib/utimens.c coreutils-8.1/lib/utimens.c ---- coreutils-8.1-orig/lib/utimens.c 2009-11-18 15:57:45.000000000 +0100 -+++ coreutils-8.1/lib/utimens.c 2009-11-27 13:02:03.000000000 +0100 -@@ -54,10 +54,12 @@ struct utimbuf - #undef utimensat - - #if HAVE_UTIMENSAT || HAVE_FUTIMENS --/* Cache variable for whether syscall works; used to avoid calling the -- syscall if we know it will just fail with ENOSYS. 0 = unknown, 1 = -- yes, -1 = no. */ -+/* Cache variables for whether the utimensat syscall works; used to -+ avoid calling the syscall if we know it will just fail with ENOSYS. -+ There are some Linux kernel versions where a flag of 0 passes, but -+ not AT_SYMLINK_NOFOLLOW. 0 = unknown, 1 = yes, -1 = no. */ - static int utimensat_works_really; -+static int lutimensat_works_really; - #endif /* HAVE_UTIMENSAT || HAVE_UTIMENSAT */ - - /* Solaris 9 mistakenly succeeds when given a non-directory with a -@@ -242,6 +244,7 @@ fdutimens (char const *file, int fd, str - # endif /* HAVE_FUTIMENS */ - } - utimensat_works_really = -1; -+ lutimensat_works_really = -1; - #endif /* HAVE_UTIMENSAT || HAVE_FUTIMENS */ - - /* The platform lacks an interface to set file timestamps with -@@ -381,7 +384,7 @@ lutimens (char const *file, struct times - worry about bogus return values. */ - - #if HAVE_UTIMENSAT -- if (0 <= utimensat_works_really) -+ if (0 <= lutimensat_works_really) - { - int result = utimensat (AT_FDCWD, file, ts, AT_SYMLINK_NOFOLLOW); - # ifdef __linux__ -@@ -397,11 +400,11 @@ lutimens (char const *file, struct times - # endif - if (result == 0 || errno != ENOSYS) - { -- utimensat_works_really = 1; -+ lutimensat_works_really = 1; - return result; - } - } -- utimensat_works_really = -1; -+ lutimensat_works_really = -1; - #endif /* HAVE_UTIMENSAT */ - - /* The platform lacks an interface to set file timestamps with -@@ -416,7 +419,9 @@ lutimens (char const *file, struct times - return 0; - } - --#if HAVE_LUTIMES -+/* On Linux, lutimes is a thin wrapper around utimensat, so there is -+ no point trying lutimes if utimensat failed with ENOSYS. */ -+#if HAVE_LUTIMES && !HAVE_UTIMENSAT - { - struct timeval timeval[2]; - struct timeval const *t; -@@ -431,9 +436,11 @@ lutimens (char const *file, struct times - else - t = NULL; - -- return lutimes (file, t); -+ result = lutimes (file, t); -+ if (result == 0 || errno != ENOSYS) -+ return result; - } --#endif /* HAVE_LUTIMES */ -+#endif /* HAVE_LUTIMES && !HAVE_UTIMENSAT */ - - /* Out of luck for symlinks, but we still handle regular files. */ - if (!(adjustment_needed || REPLACE_FUNC_STAT_FILE) && lstat (file, &st)) diff --git a/coreutils-8.1-unsearchablepath.patch b/coreutils-8.1-unsearchablepath.patch deleted file mode 100644 index ac71950..0000000 --- a/coreutils-8.1-unsearchablepath.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff -urNp coreutils-8.1-orig/tests/test-lib.sh coreutils-8.1/tests/test-lib.sh ---- coreutils-8.1-orig/tests/test-lib.sh 2009-11-24 09:35:12.000000000 +0100 -+++ coreutils-8.1/tests/test-lib.sh 2009-11-24 09:37:17.000000000 +0100 -@@ -23,6 +23,31 @@ if test $? != 11; then - Exit 77 - fi - -+# Having an unsearchable directory in PATH causes execve to fail with EACCES -+# when applied to an unresolvable program name, contrary to the desired ENOENT. -+# Avoid the problem by rewriting PATH to exclude unsearchable directories. -+sanitize_path_() -+{ -+ local saved_IFS=$IFS -+ IFS=: -+ set - $PATH -+ IFS=$saved_IFS -+ -+ local d d1 -+ local colon= -+ local new_path= -+ for d in "$@"; do -+ test -z "$d" && d1=. || d1=$d -+ if ls -d "$d1/." > /dev/null 2>&1; then -+ new_path="$new_path$colon$d" -+ colon=':' -+ fi -+ done -+ -+ PATH=$new_path -+ export PATH -+} -+ - skip_test_() - { - echo "$0: skipping test: $@" | head -1 1>&9 -@@ -396,5 +421,7 @@ else - compare() { cmp "$@"; } - fi - -+sanitize_path_ -+ - # Initialize; all bourne shell scripts end with "Exit $fail". - fail=0 diff --git a/coreutils.spec b/coreutils.spec index 026f914..a3cbd5f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,6 +1,6 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.1 +Version: 8.2 Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base @@ -18,8 +18,6 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -Patch1: coreutils-8.1-unsearchablepath.patch -Patch2: coreutils-8.1-kojiutimens-symlinks.patch # Our patches Patch100: coreutils-6.10-configuration.patch @@ -110,8 +108,6 @@ Libraries for coreutils package. %setup -q # From upstream -%patch1 -p1 -b .path -%patch2 -p1 -b .koji # Our patches %patch100 -p1 -b .configure @@ -330,6 +326,10 @@ fi %{_libdir}/coreutils %changelog +* Fri Dec 11 2009 Ondrej Vasik - 8.2-1 +- new upstream release 8.2 +- removed applied patches + * Fri Nov 27 2009 Ondrej Vasik - 8.1-1 - new upstream release 8.1 - fix build under koji (no test failures with underlying diff --git a/sources b/sources index 1da9204..0612393 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -e8ab20814c61924197c0951ee292c38a coreutils-8.1.tar.xz +e037fcb353de2df7762406e0a170b152 coreutils-8.2.tar.xz From 422af9d036dcfe38bd7e204855c4574e1133d006 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 11 Dec 2009 17:07:21 +0000 Subject: [PATCH 068/523] temporarily do not run dup_cloexec(), dependent gnulib tests failing in koji --- coreutils-6.10-configuration.patch | 55 ++++++++++++++++++++++++++++++ coreutils.spec | 3 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index ec832ac..8ff3aa6 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -78,3 +78,58 @@ diff -urNp coreutils-8.1-orig/tests/touch/no-dereference coreutils-8.1/tests/tou # Changing time of dangling symlink is okay. touch -h dangling || fail=1 +diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/gnulib.mk +--- coreutils-8.2-orig/gnulib-tests/gnulib.mk 2009-12-11 17:54:36.850815863 +0100 ++++ coreutils-8.2/gnulib-tests/gnulib.mk 2009-12-11 18:03:01.034460289 +0100 +@@ -233,9 +233,9 @@ EXTRA_DIST += test-chown.h test-chown.c + + ## begin gnulib module cloexec-tests + +-TESTS += test-cloexec +-check_PROGRAMS += test-cloexec +-EXTRA_DIST += test-cloexec.c ++#TESTS += test-cloexec ++#check_PROGRAMS += test-cloexec ++#EXTRA_DIST += test-cloexec.c + + ## end gnulib module cloexec-tests + +@@ -293,9 +293,9 @@ EXTRA_DIST += test-dirname.c + + ## begin gnulib module dup2-tests + +-TESTS += test-dup2 +-check_PROGRAMS += test-dup2 +-EXTRA_DIST += test-dup2.c ++#TESTS += test-dup2 ++#check_PROGRAMS += test-dup2 ++#EXTRA_DIST += test-dup2.c + + ## end gnulib module dup2-tests + +@@ -337,9 +337,9 @@ EXTRA_DIST += test-exclude.c test-exclud + + ## begin gnulib module fchdir-tests + +-TESTS += test-fchdir +-check_PROGRAMS += test-fchdir +-EXTRA_DIST += test-fchdir.c ++#TESTS += test-fchdir ++#check_PROGRAMS += test-fchdir ++#EXTRA_DIST += test-fchdir.c + + ## end gnulib module fchdir-tests + +@@ -1463,9 +1463,9 @@ EXTRA_DIST += test-uname.c + + ## begin gnulib module unistd-safer-tests + +-TESTS += test-dup-safer +-check_PROGRAMS += test-dup-safer +-EXTRA_DIST += test-dup-safer.c ++#TESTS += test-dup-safer ++#check_PROGRAMS += test-dup-safer ++#EXTRA_DIST += test-dup-safer.c + + ## end gnulib module unistd-safer-tests + diff --git a/coreutils.spec b/coreutils.spec index a3cbd5f..9a583fb 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -328,7 +328,8 @@ fi %changelog * Fri Dec 11 2009 Ondrej Vasik - 8.2-1 - new upstream release 8.2 -- removed applied patches +- removed applied patches, temporarily do not run dup_cloexec() + dependent gnulib tests failing in koji * Fri Nov 27 2009 Ondrej Vasik - 8.1-1 - new upstream release 8.1 From 0ab9d455d1db5c1ccaa6ff0db05a1d7ae0b9d4bc Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 16 Dec 2009 12:17:58 +0000 Subject: [PATCH 069/523] fix DIR_COLORS.256color file --- coreutils-6.10-configuration.patch | 29 ---- coreutils-DIR_COLORS.256color | 216 ++++++++++++++--------------- coreutils.spec | 5 +- 3 files changed, 112 insertions(+), 138 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 8ff3aa6..ae3d3a1 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,32 +1,3 @@ -diff -urNp coreutils-7.2-orig/gnulib-tests/gnulib.mk coreutils-7.2/gnulib-tests/gnulib.mk ---- coreutils-7.2-orig/gnulib-tests/gnulib.mk 2009-03-31 14:28:30.000000000 +0200 -+++ coreutils-7.2/gnulib-tests/gnulib.mk 2009-04-01 12:37:00.000000000 +0200 -@@ -606,9 +606,9 @@ EXTRA_DIST += test-mbsstr1.c test-mbsstr - - ## begin gnulib module memchr-tests - --TESTS += test-memchr --check_PROGRAMS += test-memchr --EXTRA_DIST += test-memchr.c zerosize-ptr.h -+#TESTS += test-memchr -+#check_PROGRAMS += test-memchr -+#EXTRA_DIST += test-memchr.c zerosize-ptr.h - - ## end gnulib module memchr-tests - -@@ -910,9 +910,9 @@ EXTRA_DIST += test-strtod.c - - ## begin gnulib module strverscmp-tests - --TESTS += test-strverscmp --check_PROGRAMS += test-strverscmp --EXTRA_DIST += test-strverscmp.c -+#TESTS += test-strverscmp -+#check_PROGRAMS += test-strverscmp -+#EXTRA_DIST += test-strverscmp.c - - ## end gnulib module strverscmp-tests - diff -urNp coreutils-6.11-orig/tests/test-lib.sh coreutils-6.11/tests/test-lib.sh --- coreutils-6.11-orig/tests/test-lib.sh 2008-04-19 23:34:23.000000000 +0200 +++ coreutils-6.11/tests/test-lib.sh 2008-04-24 14:18:59.000000000 +0200 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index e757fe1..1c0d3b3 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -52,17 +52,17 @@ EIGHTBIT 1 #NORMAL 00 # global default, no color code at all #FILE 00 # normal file, use no color at all RESET 0 # reset to "normal" color -DIR 01;38;5;27 # directory -LINK 01;38;5;51 # symbolic link (If you set this to 'target' instead of a +DIR 38;5;27 # directory +LINK 38;5;51 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) MULTIHARDLINK 44;38;5;15 # regular file with more than one link FIFO 40;38;5;11 # pipe -SOCK 01;38;5;13 # socket -DOOR 01;38;5;5 # door -BLK 01;48;5;232;38;5;11 # block device driver -CHR 01;48;5;232;38;5;3 # character device driver -ORPHAN 01;48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file -MISSING 01;05;48;5;232;38;5;15 # ... and the files they point to +SOCK 38;5;13 # socket +DOOR 38;5;5 # door +BLK 48;5;232;38;5;11 # block device driver +CHR 48;5;232;38;5;3 # character device driver +ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file +MISSING 05;48;5;232;38;5;15 # ... and the files they point to SETUID 48;5;196;38;5;15 # file that is setuid (u+s) SETGID 48;5;11;38;5;16 # file that is setgid (g+s) CAPABILITY 48;5;196;38;5;226 # file with capability @@ -71,117 +71,117 @@ OTHER_WRITABLE 48;5;10;38;5;21 # dir that is other-writable (o+w) and not sticky STICKY 48;5;21;38;5;15 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: -EXEC 01;38;5;34 +EXEC 38;5;34 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. # (and any comments you want to add after a '#') # executables (bright green) -#.cmd 01;38;5;34 -#.exe 01;38;5;34 -#.com 01;38;5;34 -#.btm 01;38;5;34 -#.bat 01;38;5;34 -#.sh 01;38;5;34 -#.csh 01;38;5;34 +#.cmd 38;5;34 +#.exe 38;5;34 +#.com 38;5;34 +#.btm 38;5;34 +#.bat 38;5;34 +#.sh 38;5;34 +#.csh 38;5;34 # archives or compressed (bright red) -.tar 01;38;5;9 -.tgz 01;38;5;9 -.arj 01;38;5;9 -.taz 01;38;5;9 -.lzh 01;38;5;9 -.lzma 01;38;5;9 -.tlz 01;38;5;9 -.txz 01;38;5;9 -.zip 01;38;5;9 -.z 01;38;5;9 -.Z 01;38;5;9 -.dz 01;38;5;9 -.gz 01;38;5;9 -.lz 01;38;5;9 -.xz 01;38;5;9 -.bz2 01;38;5;9 -.tbz 01;38;5;9 -.tbz2 01;38;5;9 -.bz 01;38;5;9 -.tz 01;38;5;9 -.deb 01;38;5;9 -.rpm 01;38;5;9 -.jar 01;38;5;9 -.rar 01;38;5;9 -.ace 01;38;5;9 -.zoo 01;38;5;9 -.cpio 01;38;5;9 -.7z 01;38;5;9 -.rz 01;38;5;9 +.tar 38;5;9 +.tgz 38;5;9 +.arj 38;5;9 +.taz 38;5;9 +.lzh 38;5;9 +.lzma 38;5;9 +.tlz 38;5;9 +.txz 38;5;9 +.zip 38;5;9 +.z 38;5;9 +.Z 38;5;9 +.dz 38;5;9 +.gz 38;5;9 +.lz 38;5;9 +.xz 38;5;9 +.bz2 38;5;9 +.tbz 38;5;9 +.tbz2 38;5;9 +.bz 38;5;9 +.tz 38;5;9 +.deb 38;5;9 +.rpm 38;5;9 +.jar 38;5;9 +.rar 38;5;9 +.ace 38;5;9 +.zoo 38;5;9 +.cpio 38;5;9 +.7z 38;5;9 +.rz 38;5;9 # image formats (magenta) -.jpg 01;38;5;13 -.jpeg 01;38;5;13 -.gif 01;38;5;13 -.bmp 01;38;5;13 -.pbm 01;38;5;13 -.pgm 01;38;5;13 -.ppm 01;38;5;13 -.tga 01;38;5;13 -.xbm 01;38;5;13 -.xpm 01;38;5;13 -.tif 01;38;5;13 -.tiff 01;38;5;13 -.png 01;38;5;13 -.svg 01;38;5;13 -.svgz 01;38;5;13 -.mng 01;38;5;13 -.pcx 01;38;5;13 -.mov 01;38;5;13 -.mpg 01;38;5;13 -.mpeg 01;38;5;13 -.m2v 01;38;5;13 -.mkv 01;38;5;13 -.ogm 01;38;5;13 -.mp4 01;38;5;13 -.m4v 01;38;5;13 -.mp4v 01;38;5;13 -.vob 01;38;5;13 -.qt 01;38;5;13 -.nuv 01;38;5;13 -.wmv 01;38;5;13 -.asf 01;38;5;13 -.rm 01;38;5;13 -.rmvb 01;38;5;13 -.flc 01;38;5;13 -.avi 01;38;5;13 -.fli 01;38;5;13 -.flv 01;38;5;13 -.gl 01;38;5;13 -.dl 01;38;5;13 -.xcf 01;38;5;13 -.xwd 01;38;5;13 -.yuv 01;38;5;13 -.cgm 01;38;5;13 -.emf 01;38;5;13 +.jpg 38;5;13 +.jpeg 38;5;13 +.gif 38;5;13 +.bmp 38;5;13 +.pbm 38;5;13 +.pgm 38;5;13 +.ppm 38;5;13 +.tga 38;5;13 +.xbm 38;5;13 +.xpm 38;5;13 +.tif 38;5;13 +.tiff 38;5;13 +.png 38;5;13 +.svg 38;5;13 +.svgz 38;5;13 +.mng 38;5;13 +.pcx 38;5;13 +.mov 38;5;13 +.mpg 38;5;13 +.mpeg 38;5;13 +.m2v 38;5;13 +.mkv 38;5;13 +.ogm 38;5;13 +.mp4 38;5;13 +.m4v 38;5;13 +.mp4v 38;5;13 +.vob 38;5;13 +.qt 38;5;13 +.nuv 38;5;13 +.wmv 38;5;13 +.asf 38;5;13 +.rm 38;5;13 +.rmvb 38;5;13 +.flc 38;5;13 +.avi 38;5;13 +.fli 38;5;13 +.flv 38;5;13 +.gl 38;5;13 +.dl 38;5;13 +.xcf 38;5;13 +.xwd 38;5;13 +.yuv 38;5;13 +.cgm 38;5;13 +.emf 38;5;13 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.axv 01;38;5;13 -.anx 01;38;5;13 -.ogv 01;38;5;13 -.ogx 01;38;5;13 +.axv 38;5;13 +.anx 38;5;13 +.ogv 38;5;13 +.ogx 38;5;13 # audio formats (cyan) -.aac 01;38;5;45 -.au 01;38;5;45 -.flac 01;38;5;45 -.mid 01;38;5;45 -.midi 01;38;5;45 -.mka 01;38;5;45 -.mp3 01;38;5;45 -.mpc 01;38;5;45 -.ogg 01;38;5;45 -.ra 01;38;5;45 -.wav 01;38;5;45 +.aac 38;5;45 +.au 38;5;45 +.flac 38;5;45 +.mid 38;5;45 +.midi 38;5;45 +.mka 38;5;45 +.mp3 38;5;45 +.mpc 38;5;45 +.ogg 38;5;45 +.ra 38;5;45 +.wav 38;5;45 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.axa 01;38;5;45 -.oga 01;38;5;45 -.spx 01;38;5;45 -.xspf 01;38;5;45 +.axa 38;5;45 +.oga 38;5;45 +.spx 38;5;45 +.xspf 38;5;45 diff --git a/coreutils.spec b/coreutils.spec index 9a583fb..f1bec27 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.2 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -326,6 +326,9 @@ fi %{_libdir}/coreutils %changelog +* Wed Dec 16 2009 Ondrej Vasik - 8.2-2 +- fix DIR_COLORS.256color file + * Fri Dec 11 2009 Ondrej Vasik - 8.2-1 - new upstream release 8.2 - removed applied patches, temporarily do not run dup_cloexec() From 75e385fc3e9bcc6ceaf0070b5f985ba7b085577c Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 16 Dec 2009 21:00:11 +0000 Subject: [PATCH 070/523] use grep instead of deprecated egrep in colorls.sh script, remove unnecessary versioned requires/conflicts, remove non-upstream hack for uname -p --- coreutils-4.5.3-sysinfo.patch | 72 ----------------------------------- coreutils-colorls.sh | 2 +- coreutils.spec | 34 ++++++++--------- 3 files changed, 16 insertions(+), 92 deletions(-) delete mode 100644 coreutils-4.5.3-sysinfo.patch diff --git a/coreutils-4.5.3-sysinfo.patch b/coreutils-4.5.3-sysinfo.patch deleted file mode 100644 index cb61d81..0000000 --- a/coreutils-4.5.3-sysinfo.patch +++ /dev/null @@ -1,72 +0,0 @@ ---- coreutils-5.97/src/uname.c.sysinfo 2005-09-15 20:57:04.000000000 +0100 -+++ coreutils-5.97/src/uname.c 2006-08-24 17:15:56.000000000 +0100 -@@ -263,7 +263,7 @@ - int - main (int argc, char **argv) - { -- static char const unknown[] = "unknown"; -+ static char unknown[] = "unknown"; - - /* Mask indicating which elements to print. */ - unsigned int toprint = 0; -@@ -306,13 +306,35 @@ - - if (toprint & PRINT_PROCESSOR) - { -- char const *element = unknown; -+ char *element = unknown; - #if HAVE_SYSINFO && defined SI_ARCHITECTURE - { - static char processor[257]; - if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) - element = processor; - } -+#else -+ { -+ struct utsname u; -+ uname(&u); -+ element = u.machine; -+#ifdef linux -+ if(!strcmp(element, "i686")) { /* Check for Athlon */ -+ char cinfo[1024]; -+ FILE *f=fopen("/proc/cpuinfo", "r"); -+ if(f) { -+ while(fgets(cinfo, 1024, f)) { -+ if(!strncmp(cinfo, "vendor_id", 9)) { -+ if(strstr(cinfo, "AuthenticAMD")) -+ element="athlon"; -+ break; -+ } -+ } -+ fclose(f); -+ } -+ } -+#endif -+ } - #endif - #ifdef UNAME_PROCESSOR - if (element == unknown) -@@ -348,7 +370,7 @@ - - if (toprint & PRINT_HARDWARE_PLATFORM) - { -- char const *element = unknown; -+ char *element = unknown; - #if HAVE_SYSINFO && defined SI_PLATFORM - { - static char hardware_platform[257]; -@@ -356,6 +378,14 @@ - hardware_platform, sizeof hardware_platform)) - element = hardware_platform; - } -+#else -+ { -+ struct utsname u; -+ uname(&u); -+ element = u.machine; -+ if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6') -+ element[1]='3'; -+ } - #endif - #ifdef UNAME_HARDWARE_PLATFORM - if (element == unknown) diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index e73cc42..928667e 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -32,7 +32,7 @@ if [ -z "$USER_LS_COLORS" ]; then eval `dircolors --sh "$COLORS" 2>/dev/null` [ -z "$LS_COLORS" ] && return - egrep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return + grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return fi alias ll='ls -l --color=auto' 2>/dev/null diff --git a/coreutils.spec b/coreutils.spec index f1bec27..7bb32e2 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.2 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -32,7 +32,6 @@ Patch704: sh-utils-1.16-paths.patch # it here indefinitely. Patch706: coreutils-pam.patch Patch713: coreutils-4.5.3-langinfo.patch -Patch715: coreutils-4.5.3-sysinfo.patch # (sb) lin18nux/lsb compliance Patch800: coreutils-i18n.patch @@ -49,35 +48,29 @@ Patch916: coreutils-getfacl-exit-code.patch Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch -BuildRequires: libselinux-devel >= 1.25.6-1 +BuildRequires: libselinux-devel BuildRequires: libacl-devel BuildRequires: gettext bison -BuildRequires: texinfo >= 4.3 -BuildRequires: autoconf >= 2.58 -BuildRequires: automake >= 1.10.1 +BuildRequires: texinfo +BuildRequires: autoconf +BuildRequires: automake %{?!nopam:BuildRequires: pam-devel} -BuildRequires: libcap-devel >= 2.0.6 +BuildRequires: libcap-devel BuildRequires: libattr-devel BuildRequires: attr BuildRequires: strace -Requires(post): libselinux >= 1.25.6-1 +Requires(post): libselinux Requires: libattr -#util-linux-ng requirement is here only to prevent /bin/arch conflict -#(could be removed after F-11/F-12 split, no idea how to solve it better) -Requires: util-linux-ng >= 2.14 Requires(pre): /sbin/install-info Requires(preun): /sbin/install-info Requires(post): /sbin/install-info Requires(post): grep -%{?!nopam:Requires: pam >= 0.66-12} -Requires(post): libcap >= 2.0.6 +%{?!nopam:Requires: pam } +Requires(post): libcap Requires: ncurses Requires: %{name}-libs = %{version}-%{release} -# Require a C library that doesn't put LC_TIME files in our way. -Conflicts: glibc < 2.2 - Provides: fileutils = %{version}-%{release} Provides: sh-utils = %{version}-%{release} Provides: stat = %{version}-%{release} @@ -89,8 +82,6 @@ Obsoletes: fileutils <= 4.1.9 Obsoletes: sh-utils <= 2.0.12 Obsoletes: stat <= 3.3 Obsoletes: textutils <= 2.0.21 -# readlink(1) moved here from tetex. -Conflicts: tetex < 1.0.7-66 %description These are the GNU core utilities. This package is the combination of @@ -119,7 +110,6 @@ Libraries for coreutils package. %patch704 -p1 -b .paths %patch706 -p1 -b .pam %patch713 -p1 -b .langinfo -%patch715 -p1 -b .sysinfo # li18nux/lsb %patch800 -p1 -b .i18n @@ -326,6 +316,12 @@ fi %{_libdir}/coreutils %changelog +* Wed Dec 16 2009 Ondrej Vasik - 8.2-3 +- use grep instead of deprecated egrep in colorls.sh script + (#548174) +- remove unnecessary versioned requires +- remove non-upstream hack for uname -p + * Wed Dec 16 2009 Ondrej Vasik - 8.2-2 - fix DIR_COLORS.256color file From 99cafffe1000517f9af550210c84fed4c4ceb49d Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Sat, 19 Dec 2009 08:42:03 +0000 Subject: [PATCH 071/523] bring back uname -p/-i functionality except of the athlon hack(#548834), comment patches --- coreutils-8.2-uname-processortype.patch | 49 +++++++++++++++++++++++++ coreutils.spec | 26 +++++++++++-- 2 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 coreutils-8.2-uname-processortype.patch diff --git a/coreutils-8.2-uname-processortype.patch b/coreutils-8.2-uname-processortype.patch new file mode 100644 index 0000000..166520d --- /dev/null +++ b/coreutils-8.2-uname-processortype.patch @@ -0,0 +1,49 @@ +diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c +--- coreutils-8.2-orig/src/uname.c 2009-09-23 10:25:44.000000000 +0200 ++++ coreutils-8.2/src/uname.c 2009-12-19 09:09:11.663607110 +0100 +@@ -301,7 +301,7 @@ main (int argc, char **argv) + + if (toprint & PRINT_PROCESSOR) + { +- char const *element = unknown; ++ char *element = unknown; + #if HAVE_SYSINFO && defined SI_ARCHITECTURE + { + static char processor[257]; +@@ -308,6 +308,12 @@ main (int argc, char **argv) + if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) + element = processor; + } ++#else ++ { ++ struct utsname u; ++ uname(&u); ++ element = u.machine; ++ } + #endif + #ifdef UNAME_PROCESSOR + if (element == unknown) +@@ -351,7 +357,7 @@ main (int argc, char **argv) + + if (toprint & PRINT_HARDWARE_PLATFORM) + { +- char const *element = unknown; ++ char *element = unknown; + #if HAVE_SYSINFO && defined SI_PLATFORM + { + static char hardware_platform[257]; +@@ -353,6 +359,14 @@ main (int argc, char **argv) + hardware_platform, sizeof hardware_platform)) + element = hardware_platform; + } ++#else ++ { ++ struct utsname u; ++ uname(&u); ++ element = u.machine; ++ if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6') ++ element[1]='3'; ++ } + #endif + #ifdef UNAME_HARDWARE_PLATFORM + if (element == unknown) diff --git a/coreutils.spec b/coreutils.spec index 7bb32e2..6ca3de5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.2 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -20,12 +20,19 @@ Source203: coreutils-runuser-l.pamd # From upstream # Our patches +#general patch to workaround koji build system issues Patch100: coreutils-6.10-configuration.patch +#add note about no difference between binary/text mode on Linux - md5sum manpage Patch101: coreutils-6.10-manpages.patch +#temporarily workaround probable kernel issue with TCSADRAIN(#504798) Patch102: coreutils-7.4-sttytcsadrain.patch +#do display processor type for uname -p/-i based on uname(2) syscall +Patch103: coreutils-8.2-uname-processortype.patch # sh-utils +#add info about TZ envvar to date manpage Patch703: sh-utils-2.0.11-dateman.patch +#set paths for su explicitly, don't get influenced by paths.h Patch704: sh-utils-1.16-paths.patch # RMS will never accept the PAM patch because it removes his historical # rant about Twenex and the wheel group, so we'll continue to maintain @@ -33,14 +40,21 @@ Patch704: sh-utils-1.16-paths.patch Patch706: coreutils-pam.patch Patch713: coreutils-4.5.3-langinfo.patch -# (sb) lin18nux/lsb compliance +# (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch +#Call setsid() in su under some circumstances (bug #173008). Patch900: coreutils-setsid.patch +#make runuser binary based on su.c Patch907: coreutils-5.2.1-runuser.patch +#getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch +#Prevent buffer overflow in who(1) (bug #158405). Patch912: coreutils-overflow.patch +#split the PAM scripts for "su -l"/"runuser -l" from that of normal "su" and +#"runuser" (#198639) Patch915: coreutils-split-pam.patch +#prevent koji build failure with wrong getfacl exit code Patch916: coreutils-getfacl-exit-code.patch #SELINUX Patch - implements Redhat changes @@ -104,6 +118,7 @@ Libraries for coreutils package. %patch100 -p1 -b .configure %patch101 -p1 -b .manpages %patch102 -p1 -b .tcsadrain +%patch103 -p1 -b .sysinfo # sh-utils %patch703 -p1 -b .dateman @@ -316,10 +331,15 @@ fi %{_libdir}/coreutils %changelog +* Sat Dec 19 2009 Ondrej Vasik - 8.2-4 +- bring back uname -p/-i functionality except of the + athlon hack(#548834) +- comment patches + * Wed Dec 16 2009 Ondrej Vasik - 8.2-3 - use grep instead of deprecated egrep in colorls.sh script (#548174) -- remove unnecessary versioned requires +- remove unnecessary versioned requires/conflicts - remove non-upstream hack for uname -p * Wed Dec 16 2009 Ondrej Vasik - 8.2-2 From 437c9e4ea2e3f23eade5688578f52d3c90b401bb Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Sun, 27 Dec 2009 11:40:37 +0000 Subject: [PATCH 072/523] fix misc/selinux root-only test(#550494) --- coreutils-selinux.patch | 2 +- coreutils.spec | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index f557dca..388f75c 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -802,7 +802,7 @@ diff -urNp coreutils-8.1-orig/tests/misc/selinux coreutils-8.1/tests/misc/selinu # inspect that context with both ls -Z and stat. for i in d f p; do - c=`ls -dogZ $i|cut -d' ' -f3`; test x$c = x$ctx || fail=1 -+ c=`ls -dogZ $i|cut -d' ' -f5`; test x$c = x$ctx || fail=1 ++ c=`ls -dogZ $i|cut -d' ' -f4`; test x$c = x$ctx || fail=1 c=`stat --printf %C $i`; test x$c = x$ctx || fail=1 done diff --git a/coreutils.spec b/coreutils.spec index 6ca3de5..1242717 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.2 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -331,6 +331,9 @@ fi %{_libdir}/coreutils %changelog +* Sun Dec 27 2009 Ondrej Vasik - 8.2-5 +- fix misc/selinux root-only test(#550494) + * Sat Dec 19 2009 Ondrej Vasik - 8.2-4 - bring back uname -p/-i functionality except of the athlon hack(#548834) From 9956da53099d0d2f1e85747125304801ad689436 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 6 Jan 2010 11:10:34 +0000 Subject: [PATCH 073/523] require gpm-devel/gpm for large numbers support(#552846) --- coreutils.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 1242717..1ba4e10 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.2 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -71,6 +71,7 @@ BuildRequires: automake %{?!nopam:BuildRequires: pam-devel} BuildRequires: libcap-devel BuildRequires: libattr-devel +BuildRequires: gpm-devel BuildRequires: attr BuildRequires: strace @@ -83,6 +84,7 @@ Requires(post): grep %{?!nopam:Requires: pam } Requires(post): libcap Requires: ncurses +Requires: gpm Requires: %{name}-libs = %{version}-%{release} Provides: fileutils = %{version}-%{release} @@ -331,6 +333,9 @@ fi %{_libdir}/coreutils %changelog +* Wed Jan 06 2010 Ondrej Vasik - 8.2-6 +- require gpm-devel/gpm for large numbers support(#552846) + * Sun Dec 27 2009 Ondrej Vasik - 8.2-5 - fix misc/selinux root-only test(#550494) From 083eee0f58d418791826a0722b1676528d90cf9a Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Wed, 6 Jan 2010 11:13:16 +0000 Subject: [PATCH 074/523] fix typo --- coreutils.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 1ba4e10..751c6e6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -71,7 +71,7 @@ BuildRequires: automake %{?!nopam:BuildRequires: pam-devel} BuildRequires: libcap-devel BuildRequires: libattr-devel -BuildRequires: gpm-devel +BuildRequires: gmp-devel BuildRequires: attr BuildRequires: strace @@ -84,7 +84,7 @@ Requires(post): grep %{?!nopam:Requires: pam } Requires(post): libcap Requires: ncurses -Requires: gpm +Requires: gmp Requires: %{name}-libs = %{version}-%{release} Provides: fileutils = %{version}-%{release} @@ -334,7 +334,7 @@ fi %changelog * Wed Jan 06 2010 Ondrej Vasik - 8.2-6 -- require gpm-devel/gpm for large numbers support(#552846) +- require gmp-devel/gmp for large numbers support(#552846) * Sun Dec 27 2009 Ondrej Vasik - 8.2-5 - fix misc/selinux root-only test(#550494) From dc24bf67e6c4a736b3ce4e13c5193ce93e4ee22b Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 8 Jan 2010 08:10:16 +0000 Subject: [PATCH 075/523] new upstream release coreutils-8.3 --- .cvsignore | 2 +- coreutils-6.10-configuration.patch | 16 ++++++++-------- coreutils-i18n.patch | 4 ++-- coreutils.spec | 7 +++++-- sources | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.cvsignore b/.cvsignore index 17b0073..9d0f2da 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-8.1.tar.xz +coreutils-8.3.tar.xz diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index ae3d3a1..cc19710 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -58,10 +58,10 @@ diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/ -TESTS += test-cloexec -check_PROGRAMS += test-cloexec --EXTRA_DIST += test-cloexec.c +-EXTRA_DIST += test-cloexec.c macros.h +#TESTS += test-cloexec +#check_PROGRAMS += test-cloexec -+#EXTRA_DIST += test-cloexec.c ++#EXTRA_DIST += test-cloexec.c macros.h ## end gnulib module cloexec-tests @@ -71,10 +71,10 @@ diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/ -TESTS += test-dup2 -check_PROGRAMS += test-dup2 --EXTRA_DIST += test-dup2.c +-EXTRA_DIST += test-dup2.c signature.h macros.h +#TESTS += test-dup2 +#check_PROGRAMS += test-dup2 -+#EXTRA_DIST += test-dup2.c ++#EXTRA_DIST += test-dup2.c signature.h macros.h ## end gnulib module dup2-tests @@ -84,10 +84,10 @@ diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/ -TESTS += test-fchdir -check_PROGRAMS += test-fchdir --EXTRA_DIST += test-fchdir.c +-EXTRA_DIST += test-fchdir.c signature.h macros.h +#TESTS += test-fchdir +#check_PROGRAMS += test-fchdir -+#EXTRA_DIST += test-fchdir.c ++#EXTRA_DIST += test-fchdir.c signature.h macros.h ## end gnulib module fchdir-tests @@ -97,10 +97,10 @@ diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/ -TESTS += test-dup-safer -check_PROGRAMS += test-dup-safer --EXTRA_DIST += test-dup-safer.c +-EXTRA_DIST += test-dup-safer.c macros.h +#TESTS += test-dup-safer +#check_PROGRAMS += test-dup-safer -+#EXTRA_DIST += test-dup-safer.c ++#EXTRA_DIST += test-dup-safer.c macros.h ## end gnulib module unistd-safer-tests diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 6c34d06..a8faefe 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -14,8 +14,8 @@ diff -urNp coreutils-8.0-orig/lib/linebuffer.h coreutils-8.0/lib/linebuffer.h struct linebuffer @@ -28,6 +33,9 @@ struct linebuffer - size_t size; /* Allocated. */ - size_t length; /* Used. */ + size_t size; /* Allocated. */ + size_t length; /* Used. */ char *buffer; +# if HAVE_WCHAR_H + mbstate_t state; diff --git a/coreutils.spec b/coreutils.spec index 751c6e6..c38b458 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.2 -Release: 6%{?dist} +Version: 8.3 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -333,6 +333,9 @@ fi %{_libdir}/coreutils %changelog +* Fri Jan 08 2010 Ondrej Vasik - 8.3-1 +- new upstream release 8.3 + * Wed Jan 06 2010 Ondrej Vasik - 8.2-6 - require gmp-devel/gmp for large numbers support(#552846) diff --git a/sources b/sources index 0612393..0e80a5c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -e037fcb353de2df7762406e0a170b152 coreutils-8.2.tar.xz +90dcc992ecb6ce76390d11134aabc830 coreutils-8.3.tar.xz From 3376fb410c4ed663e5508eb559ea21747fe40eb9 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 8 Jan 2010 14:07:53 +0000 Subject: [PATCH 076/523] disable tail-2/inotify-hash-abuse test failing in koji, upstream notified --- coreutils-6.10-configuration.patch | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index cc19710..842d4f1 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -104,3 +104,14 @@ diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/ ## end gnulib module unistd-safer-tests +diff -urNp coreutils-8.3-orig/tests/Makefile.am coreutils-8.3/tests/Makefile.am +--- coreutils-8.3-orig/tests/Makefile.am 2010-01-08 13:06:44.000000000 +0100 ++++ coreutils-8.3/tests/Makefile.am 2010-01-08 13:25:14.000000000 +0100 +@@ -79,7 +79,6 @@ TESTS = \ + rm/ext3-perf \ + rm/cycle \ + cp/link-heap \ +- tail-2/inotify-hash-abuse \ + tail-2/inotify-hash-abuse2 \ + tail-2/F-vs-rename \ + tail-2/inotify-rotate \ From d3f2dba129ed2f93a995a75761db0c7b80ef92fa Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 14 Jan 2010 09:36:45 +0000 Subject: [PATCH 077/523] new upstream release 8.4 --- .cvsignore | 2 +- coreutils-6.10-configuration.patch | 97 +++++++++++------------------- coreutils.spec | 5 +- sources | 2 +- 4 files changed, 42 insertions(+), 64 deletions(-) diff --git a/.cvsignore b/.cvsignore index 9d0f2da..58cb487 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-8.3.tar.xz +coreutils-8.4.tar.xz diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 842d4f1..894dc29 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,58 +1,7 @@ -diff -urNp coreutils-6.11-orig/tests/test-lib.sh coreutils-6.11/tests/test-lib.sh ---- coreutils-6.11-orig/tests/test-lib.sh 2008-04-19 23:34:23.000000000 +0200 -+++ coreutils-6.11/tests/test-lib.sh 2008-04-24 14:18:59.000000000 +0200 -@@ -97,8 +97,8 @@ skip_if_() - - require_selinux_() - { -- case `ls -Zd .` in -- '? .'|'unlabeled .') -+ case `ls --scontext -d . | cut -f1 -d" "` in -+ '?'|'unlabeled') - skip_test_ "this system (or maybe just" \ - "the current file system) lacks SELinux support" - ;; -diff -urNp coreutils-7.1-orig/src/ls.c coreutils-7.1/src/ls.c ---- coreutils-7.1-orig/src/ls.c 2009-02-25 13:23:59.000000000 +0100 -+++ coreutils-7.1/src/ls.c 2009-02-25 13:25:20.000000000 +0100 -@@ -38,10 +38,6 @@ - #include - #include - --#ifdef HAVE_CAP --# include --#endif -- - #if HAVE_TERMIOS_H - # include - #endif -@@ -84,6 +80,10 @@ - #include "system.h" - #include - -+#ifdef HAVE_CAP -+# include -+#endif -+ - #include "acl.h" - #include "argmatch.h" - #include "dev-ino.h" -diff -urNp coreutils-8.1-orig/tests/touch/no-dereference coreutils-8.1/tests/touch/no-dereference ---- coreutils-8.1-orig/tests/touch/no-dereference 2009-10-30 12:51:07.000000000 +0100 -+++ coreutils-8.1/tests/touch/no-dereference 2009-11-27 13:31:10.000000000 +0100 -@@ -46,6 +46,8 @@ test -f nowhere && fail=1 - grep '^#define HAVE_UTIMENSAT' "$CONFIG_HEADER" > /dev/null || - grep '^#define HAVE_LUTIMES' "$CONFIG_HEADER" > /dev/null || - skip_test_ 'this system lacks the utimensat function' -+grep '^#define HAVE_WORKINGKOJI' "$CONFIG_HEADER" > /dev/null || -+ skip_test_ 'rest of the test disabled due to koji lack of utimensat function' - - # Changing time of dangling symlink is okay. - touch -h dangling || fail=1 -diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/gnulib.mk ---- coreutils-8.2-orig/gnulib-tests/gnulib.mk 2009-12-11 17:54:36.850815863 +0100 -+++ coreutils-8.2/gnulib-tests/gnulib.mk 2009-12-11 18:03:01.034460289 +0100 -@@ -233,9 +233,9 @@ EXTRA_DIST += test-chown.h test-chown.c +diff -urNp coreutils-8.4-orig/gnulib-tests/gnulib.mk coreutils-8.4/gnulib-tests/gnulib.mk +--- coreutils-8.4-orig/gnulib-tests/gnulib.mk 2010-01-13 22:01:30.000000000 +0100 ++++ coreutils-8.4/gnulib-tests/gnulib.mk 2010-01-14 10:28:17.000000000 +0100 +@@ -256,9 +256,9 @@ EXTRA_DIST += nap.h test-chown.h test-ch ## begin gnulib module cloexec-tests @@ -65,7 +14,7 @@ diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/ ## end gnulib module cloexec-tests -@@ -293,9 +293,9 @@ EXTRA_DIST += test-dirname.c +@@ -332,9 +332,9 @@ EXTRA_DIST += test-dirname.c ## begin gnulib module dup2-tests @@ -78,7 +27,7 @@ diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/ ## end gnulib module dup2-tests -@@ -337,9 +337,9 @@ EXTRA_DIST += test-exclude.c test-exclud +@@ -376,9 +376,9 @@ EXTRA_DIST += test-exclude.c test-exclud ## begin gnulib module fchdir-tests @@ -91,7 +40,7 @@ diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/ ## end gnulib module fchdir-tests -@@ -1463,9 +1463,9 @@ EXTRA_DIST += test-uname.c +@@ -1532,9 +1532,9 @@ EXTRA_DIST += test-uname.c signature.h m ## begin gnulib module unistd-safer-tests @@ -104,9 +53,9 @@ diff -urNp coreutils-8.2-orig/gnulib-tests/gnulib.mk coreutils-8.2/gnulib-tests/ ## end gnulib module unistd-safer-tests -diff -urNp coreutils-8.3-orig/tests/Makefile.am coreutils-8.3/tests/Makefile.am ---- coreutils-8.3-orig/tests/Makefile.am 2010-01-08 13:06:44.000000000 +0100 -+++ coreutils-8.3/tests/Makefile.am 2010-01-08 13:25:14.000000000 +0100 +diff -urNp coreutils-8.4-orig/tests/Makefile.am coreutils-8.4/tests/Makefile.am +--- coreutils-8.4-orig/tests/Makefile.am 2010-01-03 18:06:20.000000000 +0100 ++++ coreutils-8.4/tests/Makefile.am 2010-01-14 10:28:17.000000000 +0100 @@ -79,7 +79,6 @@ TESTS = \ rm/ext3-perf \ rm/cycle \ @@ -115,3 +64,29 @@ diff -urNp coreutils-8.3-orig/tests/Makefile.am coreutils-8.3/tests/Makefile.am tail-2/inotify-hash-abuse2 \ tail-2/F-vs-rename \ tail-2/inotify-rotate \ +diff -urNp coreutils-8.4-orig/tests/test-lib.sh coreutils-8.4/tests/test-lib.sh +--- coreutils-8.4-orig/tests/test-lib.sh 2010-01-03 18:06:20.000000000 +0100 ++++ coreutils-8.4/tests/test-lib.sh 2010-01-14 10:28:17.000000000 +0100 +@@ -218,8 +218,8 @@ skip_if_() + + require_selinux_() + { +- case `ls -Zd .` in +- '? .'|'unlabeled .') ++ case `ls --scontext -d . | cut -f1 -d" "` in ++ '?'|'unlabeled') + skip_test_ "this system (or maybe just" \ + "the current file system) lacks SELinux support" + ;; +diff -urNp coreutils-8.4-orig/tests/touch/no-dereference coreutils-8.4/tests/touch/no-dereference +--- coreutils-8.4-orig/tests/touch/no-dereference 2010-01-12 15:36:17.000000000 +0100 ++++ coreutils-8.4/tests/touch/no-dereference 2010-01-14 10:28:17.000000000 +0100 +@@ -46,6 +46,8 @@ test -f nowhere && fail=1 + grep '^#define HAVE_UTIMENSAT' "$CONFIG_HEADER" > /dev/null || + grep '^#define HAVE_LUTIMES' "$CONFIG_HEADER" > /dev/null || + skip_test_ 'this system lacks the utimensat function' ++grep '^#define HAVE_WORKINGKOJI' "$CONFIG_HEADER" > /dev/null || ++ skip_test_ 'rest of the test disabled due to koji lack of utimensat function' + + # Changing time of dangling symlink is okay. + # Skip the test if this fails, but the error text corresponds to diff --git a/coreutils.spec b/coreutils.spec index c38b458..9234993 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,6 +1,6 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.3 +Version: 8.4 Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base @@ -333,6 +333,9 @@ fi %{_libdir}/coreutils %changelog +* Thu Jan 14 2010 Ondrej Vasik - 8.4-1 +- new upstream release 8.4 + * Fri Jan 08 2010 Ondrej Vasik - 8.3-1 - new upstream release 8.3 diff --git a/sources b/sources index 0e80a5c..9ff0def 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -90dcc992ecb6ce76390d11134aabc830 coreutils-8.3.tar.xz +1fde97f144b4699b18f36c2ec18b1f18 coreutils-8.4.tar.xz From c6e08c02773ca1a14eb4eee09f694574e1a0bba6 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 14 Jan 2010 09:56:42 +0000 Subject: [PATCH 078/523] disable gnulib linkat test, failing in koji --- coreutils-6.10-configuration.patch | 15 +++++++++++++++ coreutils.spec | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 894dc29..e601965 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -40,6 +40,21 @@ diff -urNp coreutils-8.4-orig/gnulib-tests/gnulib.mk coreutils-8.4/gnulib-tests/ ## end gnulib module fchdir-tests +@@ -855,10 +855,10 @@ EXTRA_DIST += $(top_srcdir)/build-aux/li + + ## begin gnulib module linkat-tests + +-TESTS += test-linkat +-check_PROGRAMS += test-linkat +-test_linkat_LDADD = $(LDADD) @LIBINTL@ +-EXTRA_DIST += test-link.h test-linkat.c signature.h macros.h ++#TESTS += test-linkat ++#check_PROGRAMS += test-linkat ++#test_linkat_LDADD = $(LDADD) @LIBINTL@ ++#EXTRA_DIST += test-link.h test-linkat.c signature.h macros.h + + ## end gnulib module linkat-tests + @@ -1532,9 +1532,9 @@ EXTRA_DIST += test-uname.c signature.h m ## begin gnulib module unistd-safer-tests diff --git a/coreutils.spec b/coreutils.spec index 9234993..f8fe837 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -6,7 +6,7 @@ License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color From 5e9aa7bfb423bcade7f18f5b77b10f02b737f0a5 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 14 Jan 2010 09:57:20 +0000 Subject: [PATCH 079/523] oops --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index f8fe837..9234993 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -6,7 +6,7 @@ License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color From f27ce018bdc797e1aa685663477da687c395cb5f Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 26 Jan 2010 11:41:52 +0000 Subject: [PATCH 080/523] who doesn't determine user's message status correctly(#454261) --- coreutils-8.4-who-msgstatus.patch | 98 +++++++++++++++++++++++++++++++ coreutils.spec | 10 +++- 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.4-who-msgstatus.patch diff --git a/coreutils-8.4-who-msgstatus.patch b/coreutils-8.4-who-msgstatus.patch new file mode 100644 index 0000000..6cb74b4 --- /dev/null +++ b/coreutils-8.4-who-msgstatus.patch @@ -0,0 +1,98 @@ +From aad0bde0b5aa6ccf2714f43676d4941f820c6283 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 22 Jan 2010 15:17:19 +0100 +Subject: [PATCH] who --mesg (-T) can use a more accurate test for TTY writability + +Enabled when coreutils is configured with --with-tty-group. +Based on a patch written by Piotr Gackiewicz. Details at +http://bugzilla.redhat.com/454261 + +* src/who.c (is_tty_writable): A new function returning true if a TTY +device is writable by the group. Additionally it checks the group to be +the same as TTY_GROUP_NAME when compiled with --with-tty-group. +* m4/jm-macros.m4: Introduce a new configure option --with-tty-group. +--- + m4/jm-macros.m4 | 19 +++++++++++++++++++ + src/who.c | 22 +++++++++++++++++++++- + 2 files changed, 40 insertions(+), 1 deletions(-) + +diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 +index 2713827..0ddbf2f 100644 +--- a/m4/jm-macros.m4 ++++ b/m4/jm-macros.m4 +@@ -144,6 +144,25 @@ AC_DEFUN([coreutils_MACROS], + ]) + + AC_REQUIRE([AM_LANGINFO_CODESET]) ++ ++ # Accept configure options: --with-tty-group[=GROUP], --without-tty-group ++ # You can determine the group of a TTY via 'stat --format %G /dev/tty' ++ # Omitting this option is equivalent to using --without-tty-group. ++ AC_ARG_WITH([tty-group], ++ AS_HELP_STRING([--with-tty-group[[[=NAME]]]], ++ [group used by system for TTYs, "tty" when not specified] ++ [ (default: do not rely on any group used for TTYs)]), ++ [tty_group_name=$withval], ++ [tty_group_name=no]) ++ ++ if test "x$tty_group_name" != xno; then ++ if test "x$tty_group_name" = xyes; then ++ tty_group_name=tty ++ fi ++ AC_MSG_NOTICE([TTY group used by system set to "$tty_group_name"]) ++ AC_DEFINE_UNQUOTED([TTY_GROUP_NAME], ["$tty_group_name"], ++ [group used by system for TTYs]) ++ fi + ]) + + AC_DEFUN([gl_CHECK_ALL_HEADERS], +diff --git a/src/who.c b/src/who.c +index f71db3b..4859694 100644 +--- a/src/who.c ++++ b/src/who.c +@@ -37,6 +37,10 @@ + #include "hard-locale.h" + #include "quote.h" + ++#ifdef TTY_GROUP_NAME ++# include ++#endif ++ + /* The official name of this program (e.g., no `g' prefix). */ + #define PROGRAM_NAME "who" + +@@ -308,6 +312,22 @@ print_line (int userlen, const char *user, const char state, + free (x_exitstr); + } + ++/* Return true if a terminal device given as PSTAT allows other users ++ to send messages to; false otherwise */ ++static bool ++is_tty_writable (struct stat const *pstat) ++{ ++#ifdef TTY_GROUP_NAME ++ /* Ensure the group of the TTY device matches TTY_GROUP_NAME, more info at ++ https://bugzilla.redhat.com/454261 */ ++ struct group *ttygr = getgrnam (TTY_GROUP_NAME); ++ if (!ttygr || (pstat->st_gid != ttygr->gr_gid)) ++ return false; ++#endif ++ ++ return pstat->st_mode & S_IWGRP; ++} ++ + /* Send properly parsed USER_PROCESS info to print_line. The most + recent boot time is BOOTTIME. */ + static void +@@ -346,7 +366,7 @@ print_user (const STRUCT_UTMP *utmp_ent, time_t boottime) + + if (stat (line, &stats) == 0) + { +- mesg = (stats.st_mode & S_IWGRP) ? '+' : '-'; ++ mesg = is_tty_writable (&stats) ? '+' : '-'; + last_change = stats.st_atime; + } + else +-- +1.6.5 + diff --git a/coreutils.spec b/coreutils.spec index 9234993..788d756 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.4 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,6 +18,8 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream +#"who" doesn't determine user's message status correctly - #454261 +Patch1: coreutils-8.4-who-msgstatus.patch # Our patches #general patch to workaround koji build system issues @@ -115,6 +117,7 @@ Libraries for coreutils package. %setup -q # From upstream +%patch1 -p1 -b .whomsg # Our patches %patch100 -p1 -b .configure @@ -165,6 +168,7 @@ automake --copy --add-missing %configure --enable-largefile %{?!nopam:--enable-pam} \ --enable-selinux \ --enable-install-program=su,hostname,arch \ + --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : # Regenerate manpages @@ -333,6 +337,10 @@ fi %{_libdir}/coreutils %changelog +* Tue Jan 26 2010 Ondrej Vasik - 8.4-2 +- who doesn't determine user's message status correctly + (#454261) + * Thu Jan 14 2010 Ondrej Vasik - 8.4-1 - new upstream release 8.4 From 6a2111b547a77d13f07d81550f9dc37ff35d51ea Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 29 Jan 2010 11:33:06 +0000 Subject: [PATCH 081/523] do not fail tests if there are no loopdevices left(#558898) --- coreutils-6.10-configuration.patch | 22 ++++++++++++++++++++++ coreutils.spec | 6 +++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index e601965..6bbe3a0 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -105,3 +105,25 @@ diff -urNp coreutils-8.4-orig/tests/touch/no-dereference coreutils-8.4/tests/tou # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to +diff -urNp coreutils-8.4-orig/tests/cp/cp-a-selinux coreutils-8.4/tests/cp/cp-a-selinux +--- coreutils-8.4-orig/tests/cp/cp-a-selinux 2010-01-03 18:06:20.000000000 +0100 ++++ coreutils-8.4/tests/cp/cp-a-selinux 2010-01-29 09:39:43.000000000 +0100 +@@ -48,12 +48,15 @@ ls -Z f | grep $ctx || fail=1 + + # Create a file system, then mount it with the context=... option. + dd if=/dev/zero of=blob bs=8192 count=200 > /dev/null 2>&1 \ +- || framework_failure +-mkdir mnt || framework_failure ++ || skip=1 ++mkdir mnt || skip=1 + mkfs -t ext2 -F blob || + skip_test_ "failed to create an ext2 file system" + +-mount -oloop,context=$ctx blob mnt || framework_failure ++mount -oloop,context=$ctx blob mnt || skip=1 ++test $skip = 1 \ ++ && skip_test_ "insufficient mount/ext2 support" ++ + cd mnt || framework_failure + + echo > f || framework_failure diff --git a/coreutils.spec b/coreutils.spec index 788d756..3384e04 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.4 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -337,6 +337,10 @@ fi %{_libdir}/coreutils %changelog +* Fri Jan 29 2010 Ondrej Vasik - 8.4-3 +- do not fail tests if there are no loopdevices left + (#558898) + * Tue Jan 26 2010 Ondrej Vasik - 8.4-2 - who doesn't determine user's message status correctly (#454261) From 20666c9d9c874c53d85d9ad88868458c8d7c8a41 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 5 Feb 2010 16:21:42 +0000 Subject: [PATCH 082/523] do not depend on selinux patch application in _require_selinux tests(#556350) --- coreutils-6.10-configuration.patch | 14 -------------- coreutils-selinux.patch | 14 ++++++++++++++ coreutils.spec | 6 +++++- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 6bbe3a0..2fbd3e8 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -79,20 +79,6 @@ diff -urNp coreutils-8.4-orig/tests/Makefile.am coreutils-8.4/tests/Makefile.am tail-2/inotify-hash-abuse2 \ tail-2/F-vs-rename \ tail-2/inotify-rotate \ -diff -urNp coreutils-8.4-orig/tests/test-lib.sh coreutils-8.4/tests/test-lib.sh ---- coreutils-8.4-orig/tests/test-lib.sh 2010-01-03 18:06:20.000000000 +0100 -+++ coreutils-8.4/tests/test-lib.sh 2010-01-14 10:28:17.000000000 +0100 -@@ -218,8 +218,8 @@ skip_if_() - - require_selinux_() - { -- case `ls -Zd .` in -- '? .'|'unlabeled .') -+ case `ls --scontext -d . | cut -f1 -d" "` in -+ '?'|'unlabeled') - skip_test_ "this system (or maybe just" \ - "the current file system) lacks SELinux support" - ;; diff -urNp coreutils-8.4-orig/tests/touch/no-dereference coreutils-8.4/tests/touch/no-dereference --- coreutils-8.4-orig/tests/touch/no-dereference 2010-01-12 15:36:17.000000000 +0100 +++ coreutils-8.4/tests/touch/no-dereference 2010-01-14 10:28:17.000000000 +0100 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 388f75c..26cd0dc 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -794,6 +794,20 @@ diff -urNp coreutils-8.1-orig/src/stat.c coreutils-8.1/src/stat.c exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); } +diff -urNp coreutils-8.4-orig/tests/test-lib.sh coreutils-8.4/tests/test-lib.sh +--- coreutils-8.4-orig/tests/test-lib.sh 2010-01-03 18:06:20.000000000 +0100 ++++ coreutils-8.4/tests/test-lib.sh 2010-01-14 10:28:17.000000000 +0100 +@@ -218,8 +218,8 @@ skip_if_() + + require_selinux_() + { +- case `ls -Zd .` in +- '? .'|'unlabeled .') ++ case `ls -Zd . | cut -f4 -d" "` in ++ '?'|'unlabeled') + skip_test_ "this system (or maybe just" \ + "the current file system) lacks SELinux support" + ;; diff -urNp coreutils-8.1-orig/tests/misc/selinux coreutils-8.1/tests/misc/selinux --- coreutils-8.1-orig/tests/misc/selinux 2009-10-30 12:51:07.000000000 +0100 +++ coreutils-8.1/tests/misc/selinux 2009-11-20 13:11:40.000000000 +0100 diff --git a/coreutils.spec b/coreutils.spec index 3384e04..0b50783 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.4 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -337,6 +337,10 @@ fi %{_libdir}/coreutils %changelog +- Fri Feb 05 2010 Ondrej Vasik - 8.4-4 +- do not depend on selinux patch application in + _require_selinux tests(#556350) + * Fri Jan 29 2010 Ondrej Vasik - 8.4-3 - do not fail tests if there are no loopdevices left (#558898) From 5e503604265b4ea29585ca53381384b4515c59e4 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 5 Feb 2010 16:23:22 +0000 Subject: [PATCH 083/523] ooops --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 0b50783..47b54d8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -337,7 +337,7 @@ fi %{_libdir}/coreutils %changelog -- Fri Feb 05 2010 Ondrej Vasik - 8.4-4 +* Fri Feb 05 2010 Ondrej Vasik - 8.4-4 - do not depend on selinux patch application in _require_selinux tests(#556350) From edc268cf05a8699c825dc677c00e767c440889aa Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 12 Feb 2010 09:28:31 +0000 Subject: [PATCH 084/523] fix exit status of terminated child processes in su with pam(#559098) --- coreutils-pam.patch | 47 +++++++++++++++++++++++---------------------- coreutils.spec | 6 +++++- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/coreutils-pam.patch b/coreutils-pam.patch index ae6d1be..e61908f 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.1-orig/configure.ac coreutils-8.1/configure.ac ---- coreutils-8.1-orig/configure.ac 2009-11-14 15:01:44.000000000 +0100 -+++ coreutils-8.1/configure.ac 2009-11-20 13:00:10.000000000 +0100 +diff -urNp coreutils-8.4-orig/configure.ac coreutils-8.4/configure.ac +--- coreutils-8.4-orig/configure.ac 2010-01-11 18:20:42.000000000 +0100 ++++ coreutils-8.4/configure.ac 2010-02-12 10:17:46.000000000 +0100 @@ -126,6 +126,13 @@ if test "$gl_gcc_warnings" = yes; then AC_SUBST([GNULIB_WARN_CFLAGS]) fi @@ -15,10 +15,10 @@ diff -urNp coreutils-8.1-orig/configure.ac coreutils-8.1/configure.ac AC_FUNC_FORK optional_bin_progs= -diff -urNp coreutils-8.1-orig/doc/coreutils.texi coreutils-8.1/doc/coreutils.texi ---- coreutils-8.1-orig/doc/coreutils.texi 2009-11-10 13:57:56.000000000 +0100 -+++ coreutils-8.1/doc/coreutils.texi 2009-11-20 13:00:10.000000000 +0100 -@@ -15070,8 +15070,11 @@ to certain shells, etc.). +diff -urNp coreutils-8.4-orig/doc/coreutils.texi coreutils-8.4/doc/coreutils.texi +--- coreutils-8.4-orig/doc/coreutils.texi 2010-01-03 18:06:20.000000000 +0100 ++++ coreutils-8.4/doc/coreutils.texi 2010-02-12 10:17:46.000000000 +0100 +@@ -15081,8 +15081,11 @@ to certain shells, etc.). @findex syslog @command{su} can optionally be compiled to use @code{syslog} to report failed, and optionally successful, @command{su} attempts. (If the system @@ -32,7 +32,7 @@ diff -urNp coreutils-8.1-orig/doc/coreutils.texi coreutils-8.1/doc/coreutils.tex The program accepts the following options. Also see @ref{Common options}. -@@ -15113,6 +15116,8 @@ environment variables except @env{TERM}, +@@ -15124,6 +15127,8 @@ environment variables except @env{TERM}, @env{PATH} to a compiled-in default value. Change to @var{user}'s home directory. Prepend @samp{-} to the shell's name, intended to make it read its login startup file(s). @@ -41,7 +41,7 @@ diff -urNp coreutils-8.1-orig/doc/coreutils.texi coreutils-8.1/doc/coreutils.tex @item -m @itemx -p -@@ -15152,33 +15157,6 @@ Exit status: +@@ -15163,33 +15168,6 @@ Exit status: the exit status of the subshell otherwise @end display @@ -75,10 +75,10 @@ diff -urNp coreutils-8.1-orig/doc/coreutils.texi coreutils-8.1/doc/coreutils.tex @node timeout invocation @section @command{timeout}: Run a command with a time limit -diff -urNp coreutils-8.1-orig/src/Makefile.am coreutils-8.1/src/Makefile.am ---- coreutils-8.1-orig/src/Makefile.am 2009-11-06 18:04:10.000000000 +0100 -+++ coreutils-8.1/src/Makefile.am 2009-11-20 13:00:10.000000000 +0100 -@@ -359,7 +359,7 @@ factor_LDADD += $(LIB_GMP) +diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am +--- coreutils-8.4-orig/src/Makefile.am 2010-01-03 18:06:20.000000000 +0100 ++++ coreutils-8.4/src/Makefile.am 2010-02-12 10:17:46.000000000 +0100 +@@ -361,7 +361,7 @@ factor_LDADD += $(LIB_GMP) uptime_LDADD += $(GETLOADAVG_LIBS) # for crypt @@ -87,9 +87,9 @@ diff -urNp coreutils-8.1-orig/src/Makefile.am coreutils-8.1/src/Makefile.am # for various ACL functions copy_LDADD += $(LIB_ACL) -diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c ---- coreutils-8.1-orig/src/su.c 2009-11-20 12:59:39.000000000 +0100 -+++ coreutils-8.1/src/su.c 2009-11-20 13:00:10.000000000 +0100 +diff -urNp coreutils-8.4-orig/src/su.c coreutils-8.4/src/su.c +--- coreutils-8.4-orig/src/su.c 2010-02-12 10:15:15.000000000 +0100 ++++ coreutils-8.4/src/su.c 2010-02-12 10:24:29.000000000 +0100 @@ -37,6 +37,16 @@ restricts who can su to UID 0 accounts. RMS considers that to be fascist. @@ -339,7 +339,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c shell_basename = last_component (shell); arg0 = xmalloc (strlen (shell_basename) + 2); arg0[0] = '-'; -@@ -344,6 +496,66 @@ run_shell (char const *shell, char const +@@ -344,6 +496,67 @@ run_shell (char const *shell, char const error (0, errno, "%s", shell); exit (exit_status); } @@ -377,12 +377,12 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c + + pid = waitpid(-1, &status, WUNTRACED); + -+ if (WIFSTOPPED(status)) { -+ kill(getpid(), SIGSTOP); ++ if (((pid_t)-1 != pid) && (0 != WIFSTOPPED (status))) { ++ kill(getpid(), WSTOPSIG(status)); + /* once we get here, we must have resumed */ + kill(pid, SIGCONT); + } -+ } while (WIFSTOPPED(status)); ++ } while (0 != WIFSTOPPED(status)); + } + + if (caught) { @@ -401,12 +401,13 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c + fprintf(stderr, " ...killed.\n"); + exit(-1); + } -+ exit (WEXITSTATUS(status)); ++ exit ((0 != WIFEXITED (status)) ? WEXITSTATUS (status) ++ : WTERMSIG (status) + 128); +#endif /* USE_PAM */ } /* Return true if SHELL is a restricted shell (one not returned by -@@ -511,9 +723,9 @@ main (int argc, char **argv) +@@ -511,9 +724,9 @@ main (int argc, char **argv) shell = xstrdup (shell ? shell : pw->pw_shell); modify_environment (pw, shell); @@ -418,7 +419,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c /* error() flushes stderr, but does not check for write failure. Normally, we would catch this via our atexit() hook of -@@ -523,5 +735,5 @@ main (int argc, char **argv) +@@ -523,5 +736,5 @@ main (int argc, char **argv) if (ferror (stderr)) exit (EXIT_CANCELED); diff --git a/coreutils.spec b/coreutils.spec index 47b54d8..dfa141a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.4 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -337,6 +337,10 @@ fi %{_libdir}/coreutils %changelog +* Fri Feb 12 2010 Ondrej Vasik - 8.4-5 +- fix exit status of terminated child processes in su with + pam(#559098) + * Fri Feb 05 2010 Ondrej Vasik - 8.4-4 - do not depend on selinux patch application in _require_selinux tests(#556350) From 515305b108a6abf6d04f9c865871294a33fca38e Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Sat, 20 Mar 2010 07:44:52 +0000 Subject: [PATCH 085/523] run tput colors in colorls profile.d scripts only in the interactive mode(#450424) --- coreutils-colorls.csh | 2 +- coreutils-colorls.sh | 2 +- coreutils.spec | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 2d259a8..317cd0c 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -17,7 +17,7 @@ if ($?TERM) then endif endif if ( -e "/etc/DIR_COLORS.256color" ) then - if ( "`tput colors`" == "256" ) then + if ( "`tty -s && tput colors`" == "256" ) then set COLORS=/etc/DIR_COLORS.256color endif endif diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index 928667e..f4d6400 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -18,7 +18,7 @@ if [ -z "$USER_LS_COLORS" ]; then done [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \ - [ "x`tput colors 2>/dev/null`" = "x256" ] && \ + [ "x`tty -s && tput colors 2>/dev/null`" = "x256" ] && \ COLORS="/etc/DIR_COLORS.256color" if [ -z "$COLORS" ]; then diff --git a/coreutils.spec b/coreutils.spec index dfa141a..5efab8e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.4 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -337,6 +337,10 @@ fi %{_libdir}/coreutils %changelog +* Sat Mar 20 2010 Ondrej Vasik - 8.4-6 +- run tput colors in colorls profile.d scripts only + in the interactive mode(#450424) + * Fri Feb 12 2010 Ondrej Vasik - 8.4-5 - fix exit status of terminated child processes in su with pam(#559098) From 80779cc2b95db5ad4fb90e00e1882ee3653eda51 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 22 Mar 2010 09:02:28 +0000 Subject: [PATCH 086/523] Spring cleanup --- coreutils-6.11-matchpathconinstall.patch | 46 ------------------------ coreutils-6.7.tar.bz2.sig | 7 ---- coreutils-6.9.tar.bz2.sig | 7 ---- coreutils-silentmv.patch | 21 ----------- 4 files changed, 81 deletions(-) delete mode 100644 coreutils-6.11-matchpathconinstall.patch delete mode 100644 coreutils-6.7.tar.bz2.sig delete mode 100644 coreutils-6.9.tar.bz2.sig delete mode 100644 coreutils-silentmv.patch diff --git a/coreutils-6.11-matchpathconinstall.patch b/coreutils-6.11-matchpathconinstall.patch deleted file mode 100644 index 87a31ca..0000000 --- a/coreutils-6.11-matchpathconinstall.patch +++ /dev/null @@ -1,46 +0,0 @@ -From a089634c855312a28f2ff3c2e7c08df5d030e2f5 Mon Sep 17 00:00:00 2001 -From: Jim Meyering redhat.com> -Date: Tue, 20 May 2008 17:58:42 +0200 -Subject: [PATCH] install: avoid a leak in currently-ifdef'd-out code - -* src/install.c (setdefaultfilecon) -[ENABLE_WHEN_MATCHPATHCON_IS_MORE_EFFICIENT]: -Call matchpathcon_init_prefix only once. -Suggestion from Stephen Smalley. Reported by Ben Webb in -. ---- - src/install.c | 5 ++++- - 1 files changed, 4 insertions(+), 1 deletions(-) - -diff --git a/src/install.c b/src/install.c -index 964ab36..b531f45 100644 ---- a/src/install.c -+++ b/src/install.c -@@ -208,6 +208,8 @@ setdefaultfilecon (char const *file) - { - struct stat st; - security_context_t scontext = NULL; -+ static bool first_call = true; -+ - if (selinux_enabled != 1) - { - /* Indicate no context found. */ -@@ -216,7 +218,7 @@ setdefaultfilecon (char const *file) - if (lstat (file, &st) != 0) - return; - -- if (IS_ABSOLUTE_FILE_NAME (file)) -+ if (first_call && IS_ABSOLUTE_FILE_NAME (file)) - { - /* Calling matchpathcon_init_prefix (NULL, "/first_component/") - is an optimization to minimize the expense of the following -@@ -247,6 +249,7 @@ setdefaultfilecon (char const *file) - } - } - } -+ first_call = false; - - /* If there's an error determining the context, or it has none, - return to allow default context */ --- -1.5.5.1.249.g68ef3 diff --git a/coreutils-6.7.tar.bz2.sig b/coreutils-6.7.tar.bz2.sig deleted file mode 100644 index cc2977f..0000000 --- a/coreutils-6.7.tar.bz2.sig +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQBFeKRc/dLerNMzy6ERAiEJAJ435eWCOpfJkoCKoSpnh8Fwwb9XugCgnQ5H -SYg6l7M/jyvUdsFM1yS4RKk= -=GOOc ------END PGP SIGNATURE----- diff --git a/coreutils-6.9.tar.bz2.sig b/coreutils-6.9.tar.bz2.sig deleted file mode 100644 index a39ac66..0000000 --- a/coreutils-6.9.tar.bz2.sig +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQBGAvc3/dLerNMzy6ERAnyfAKC4MPj62hCSRYNu0ysD9SahdQvZIACgsNl/ -CzQjwTNo5FUiiNm0FxtL5Ow= -=gl3O ------END PGP SIGNATURE----- diff --git a/coreutils-silentmv.patch b/coreutils-silentmv.patch deleted file mode 100644 index 2f7f02b..0000000 --- a/coreutils-silentmv.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -urNp coreutils-7.2-orig/src/copy.c coreutils-7.2/src/copy.c ---- coreutils-7.2-orig/src/copy.c 2009-04-17 15:21:26.000000000 +0200 -+++ coreutils-7.2/src/copy.c 2009-04-17 15:24:17.000000000 +0200 -@@ -139,10 +139,13 @@ copy_attr_error (struct error_context *c - int err = errno; - va_list ap; - -- /* use verror module to print error message */ -- va_start (ap, fmt); -- verror (0, err, fmt, ap); -- va_end (ap); -+ if (errno != ENOTSUP && errno != ENODATA) -+ { -+ /* use verror module to print error message */ -+ va_start (ap, fmt); -+ verror (0, err, fmt, ap); -+ va_end (ap); -+ } - } - - static char const * From d059274f5345f1ad226b302a572defddad32890b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH 087/523] - a new option df --direct --- coreutils-df-direct.patch | 188 ++++++++++++++++++++++++++++++++++++++ coreutils.spec | 10 +- 2 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 coreutils-df-direct.patch diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch new file mode 100644 index 0000000..380f1b1 --- /dev/null +++ b/coreutils-df-direct.patch @@ -0,0 +1,188 @@ +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index fa21f03..7b8b622 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -10104,6 +10104,13 @@ pseudo-file-systems, such as automounter entries. + Scale sizes by @var{size} before printing them (@pxref{Block size}). + For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. + ++@itemx --direct ++@opindex --direct ++@cindex direct statfs for a file ++Do not resolve mount point and show statistics directly for a file. It can be ++especially useful for NFS mount points if there is a boundary between two ++storage policies behind the mount point. ++ + @itemx --total + @opindex --total + @cindex grand total of disk size, usage and available space +diff --git a/src/df.c b/src/df.c +index b862879..a74c353 100644 +--- a/src/df.c ++++ b/src/df.c +@@ -110,6 +110,9 @@ static bool print_type; + /* If true, print a grand total at the end. */ + static bool print_grand_total; + ++/* If true, show statistics for a file instead of mount point. */ ++static bool direct_statfs; ++ + /* Grand total data. */ + static struct fs_usage grand_fsu; + +@@ -118,13 +121,15 @@ static struct fs_usage grand_fsu; + enum + { + NO_SYNC_OPTION = CHAR_MAX + 1, +- SYNC_OPTION ++ SYNC_OPTION, ++ DIRECT_OPTION + }; + + static struct option const long_options[] = + { + {"all", no_argument, NULL, 'a'}, + {"block-size", required_argument, NULL, 'B'}, ++ {"direct", no_argument, NULL, DIRECT_OPTION}, + {"inodes", no_argument, NULL, 'i'}, + {"human-readable", no_argument, NULL, 'h'}, + {"si", no_argument, NULL, 'H'}, +@@ -205,7 +210,10 @@ print_header (void) + human_readable (output_block_size, buf, opts, 1, 1)); + } + +- fputs (_(" Mounted on\n"), stdout); ++ if (direct_statfs) ++ fputs (_(" File\n"), stdout); ++ else ++ fputs (_(" Mounted on\n"), stdout); + } + + /* Is FSTYPE a type of file system that should be listed? */ +@@ -754,6 +762,17 @@ show_point (const char *point, const struct stat *statp) + static void + show_entry (char const *name, struct stat const *statp) + { ++ if (direct_statfs) ++ { ++ char *resolved = canonicalize_file_name (name); ++ if (resolved) ++ { ++ show_dev (NULL, resolved, NULL, NULL, false, false, NULL); ++ free (resolved); ++ return; ++ } ++ } ++ + if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) + && show_disk (name)) + return; +@@ -820,6 +839,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\ + fputs (_("\ + -a, --all include dummy file systems\n\ + -B, --block-size=SIZE use SIZE-byte blocks\n\ ++ --direct show statistics for a file instead of mount point\n\ + --total produce a grand total\n\ + -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\n\ + -H, --si likewise, but use powers of 1000 not 1024\n\ +@@ -894,6 +914,9 @@ main (int argc, char **argv) + xstrtol_fatal (e, oi, c, long_options, optarg); + } + break; ++ case DIRECT_OPTION: ++ direct_statfs = true; ++ break; + case 'i': + inode_format = true; + break; +@@ -954,6 +977,13 @@ main (int argc, char **argv) + } + } + ++ if (direct_statfs && show_local_fs) ++ { ++ error (0, 0, _("options --direct and --local (-l) are mutually " ++ "exclusive")); ++ usage (EXIT_FAILURE); ++ } ++ + if (human_output_opts == -1) + { + if (posix_format) +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 1cb5a76..ab7abb4 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -328,6 +328,7 @@ TESTS = \ + dd/stderr \ + dd/unblock \ + dd/unblock-sync \ ++ df/direct \ + df/total-verify \ + du/2g \ + du/8gb \ +diff --git a/tests/df/direct b/tests/df/direct +new file mode 100644 +index 0000000..9088f27 +--- /dev/null ++++ b/tests/df/direct +@@ -0,0 +1,59 @@ ++#!/bin/sh ++# Ensure "df --direct" works as documented ++ ++# Copyright (C) 2010 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 . ++ ++if test "$VERBOSE" = yes; then ++ set -x ++ df --version ++fi ++ ++. $srcdir/test-lib.sh ++ ++df || skip_test_ "df fails" ++ ++DIR=`pwd` || framework_failure ++FILE="$DIR/file" ++touch "$FILE" || framework_failure ++echo "$FILE" > file_exp || framework_failure ++echo "Mounted on" > header_mounted_exp || framework_failure ++echo "File" > header_file_exp || framework_failure ++ ++fail=0 ++ ++df --portability "$FILE" > df_out || fail=1 ++df --portability --direct "$FILE" > df_direct_out || fail=1 ++df --portability --direct --local "$FILE" > /dev/null 2>&1 && fail=1 ++ ++# check df header ++$AWK '{ if (NR==1) print $6 " " $7; }' df_out > header_mounted_out \ ++ || framework_failure ++$AWK '{ if (NR==1) print $6; }' df_direct_out > header_file_out \ ++ || framework_failure ++compare header_mounted_out header_mounted_exp || fail=1 ++compare header_file_out header_file_exp || fail=1 ++ ++# check df output (without --direct) ++$AWK '{ if (NR==2) print $6; }' df_out > file_out \ ++ || framework_failure ++compare file_out file_exp && fail=1 ++ ++# check df output (with --direct) ++$AWK '{ if (NR==2) print $6; }' df_direct_out > file_out \ ++ || framework_failure ++compare file_out file_exp || fail=1 ++ ++Exit $fail diff --git a/coreutils.spec b/coreutils.spec index 5efab8e..ba4d842 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.4 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -30,6 +30,8 @@ Patch101: coreutils-6.10-manpages.patch Patch102: coreutils-7.4-sttytcsadrain.patch #do display processor type for uname -p/-i based on uname(2) syscall Patch103: coreutils-8.2-uname-processortype.patch +#df --direct +Patch104: coreutils-df-direct.patch # sh-utils #add info about TZ envvar to date manpage @@ -124,6 +126,7 @@ Libraries for coreutils package. %patch101 -p1 -b .manpages %patch102 -p1 -b .tcsadrain %patch103 -p1 -b .sysinfo +%patch104 -p1 -b .dfdirect # sh-utils %patch703 -p1 -b .dateman @@ -145,7 +148,7 @@ Libraries for coreutils package. %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -chmod a+x tests/misc/sort-mb-tests +chmod a+x tests/misc/sort-mb-tests tests/df/direct #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -337,6 +340,9 @@ fi %{_libdir}/coreutils %changelog +* Mon Mar 29 2010 Kamil Dudka - 8.4-7 +- a new option df --direct + * Sat Mar 20 2010 Ondrej Vasik - 8.4-6 - run tput colors in colorls profile.d scripts only in the interactive mode(#450424) From a5bbdc735f98b9f1d84c12c43ee452ba86577d2a Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 15 Apr 2010 12:08:16 +0000 Subject: [PATCH 088/523] move readlink from /usr/bin to bin, keep symlink in /usr/bin(#580682) --- coreutils.spec | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index ba4d842..82ad271 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.4 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -207,15 +207,15 @@ bzip2 -9f ChangeLog # let be compatible with old fileutils, sh-utils and textutils packages : mkdir -p $RPM_BUILD_ROOT{/bin,%_bindir,%_sbindir,/sbin} %{?!nopam:mkdir -p $RPM_BUILD_ROOT%_sysconfdir/pam.d} -for f in arch basename cat chgrp chmod chown cp cut date dd df echo env false link ln ls mkdir mknod mktemp mv nice pwd rm rmdir sleep sort stty sync touch true uname unlink +for f in arch basename cat chgrp chmod chown cp cut date dd df echo env false link ln ls mkdir mknod mktemp mv nice pwd readlink rm rmdir sleep sort stty sync touch true uname unlink do mv $RPM_BUILD_ROOT{%_bindir,/bin}/$f done # chroot was in /usr/sbin : mv $RPM_BUILD_ROOT{%_bindir,%_sbindir}/chroot -# {cat,sort,cut} were previously moved from bin to /usr/bin and linked into -for i in env cut; do ln -sf ../../bin/$i $RPM_BUILD_ROOT/usr/bin; done +# {env,cut,readlink} were previously moved from /usr/bin to /bin and linked into +for i in env cut readlink; do ln -sf ../../bin/$i $RPM_BUILD_ROOT/usr/bin; done mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d install -p -c -m644 %SOURCE101 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS @@ -317,6 +317,7 @@ fi /bin/mv /bin/nice /bin/pwd +/bin/readlink /bin/rm /bin/rmdir /bin/sleep @@ -340,6 +341,10 @@ fi %{_libdir}/coreutils %changelog +* Thu Apr 15 2010 Ondrej Vasik - 8.4-8 +- move readlink from /usr/bin to bin, keep symlink in + /usr/bin(#580682) + * Mon Mar 29 2010 Kamil Dudka - 8.4-7 - a new option df --direct From 12996d09a189f05cb78e424a97c1c57d8be7b882 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 26 Apr 2010 13:15:37 +0000 Subject: [PATCH 089/523] new upstream release 8.5 --- .cvsignore | 2 +- coreutils-5.2.1-runuser.patch | 10 +- coreutils-6.10-configuration.patch | 28 +--- coreutils-8.4-who-msgstatus.patch | 98 -------------- coreutils-i18n.patch | 208 +++++++++++++++-------------- coreutils.spec | 10 +- sources | 2 +- 7 files changed, 121 insertions(+), 237 deletions(-) delete mode 100644 coreutils-8.4-who-msgstatus.patch diff --git a/.cvsignore b/.cvsignore index 58cb487..adf3112 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -coreutils-8.4.tar.xz +coreutils-8.5.tar.xz diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-5.2.1-runuser.patch index 21efa5b..640b230 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-5.2.1-runuser.patch @@ -380,11 +380,11 @@ diff -urNp coreutils-8.1-orig/tests/misc/help-version coreutils-8.1/tests/misc/h expected_failure_status_tty=3 expected_failure_status_sort=2 @@ -153,6 +154,7 @@ seq_args=10 - sleep_args=0 - su_args=--version - stdbuf_args="-oL true" -+runuser_args=--version - timeout_args=--version + sleep_setup () { args=0; } + su_setup () { args=--version; } + stdbuf_setup () { args="-oL true"; } ++runuser_setup () { args=--version; } + timeout_setup () { args=--version; } # I'd rather not run sync, since it spins up disks that I've diff -urNp coreutils-8.1-orig/tests/misc/invalid-opt coreutils-8.1/tests/misc/invalid-opt diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 2fbd3e8..d1cb20c 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -83,33 +83,11 @@ diff -urNp coreutils-8.4-orig/tests/touch/no-dereference coreutils-8.4/tests/tou --- coreutils-8.4-orig/tests/touch/no-dereference 2010-01-12 15:36:17.000000000 +0100 +++ coreutils-8.4/tests/touch/no-dereference 2010-01-14 10:28:17.000000000 +0100 @@ -46,6 +46,8 @@ test -f nowhere && fail=1 - grep '^#define HAVE_UTIMENSAT' "$CONFIG_HEADER" > /dev/null || - grep '^#define HAVE_LUTIMES' "$CONFIG_HEADER" > /dev/null || + grep '^#define HAVE_UTIMENSAT 1' "$CONFIG_HEADER" > /dev/null || + grep '^#define HAVE_LUTIMES 1' "$CONFIG_HEADER" > /dev/null || skip_test_ 'this system lacks the utimensat function' -+grep '^#define HAVE_WORKINGKOJI' "$CONFIG_HEADER" > /dev/null || ++grep '^#define HAVE_WORKINGKOJI 1' "$CONFIG_HEADER" > /dev/null || + skip_test_ 'rest of the test disabled due to koji lack of utimensat function' # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to -diff -urNp coreutils-8.4-orig/tests/cp/cp-a-selinux coreutils-8.4/tests/cp/cp-a-selinux ---- coreutils-8.4-orig/tests/cp/cp-a-selinux 2010-01-03 18:06:20.000000000 +0100 -+++ coreutils-8.4/tests/cp/cp-a-selinux 2010-01-29 09:39:43.000000000 +0100 -@@ -48,12 +48,15 @@ ls -Z f | grep $ctx || fail=1 - - # Create a file system, then mount it with the context=... option. - dd if=/dev/zero of=blob bs=8192 count=200 > /dev/null 2>&1 \ -- || framework_failure --mkdir mnt || framework_failure -+ || skip=1 -+mkdir mnt || skip=1 - mkfs -t ext2 -F blob || - skip_test_ "failed to create an ext2 file system" - --mount -oloop,context=$ctx blob mnt || framework_failure -+mount -oloop,context=$ctx blob mnt || skip=1 -+test $skip = 1 \ -+ && skip_test_ "insufficient mount/ext2 support" -+ - cd mnt || framework_failure - - echo > f || framework_failure diff --git a/coreutils-8.4-who-msgstatus.patch b/coreutils-8.4-who-msgstatus.patch deleted file mode 100644 index 6cb74b4..0000000 --- a/coreutils-8.4-who-msgstatus.patch +++ /dev/null @@ -1,98 +0,0 @@ -From aad0bde0b5aa6ccf2714f43676d4941f820c6283 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Fri, 22 Jan 2010 15:17:19 +0100 -Subject: [PATCH] who --mesg (-T) can use a more accurate test for TTY writability - -Enabled when coreutils is configured with --with-tty-group. -Based on a patch written by Piotr Gackiewicz. Details at -http://bugzilla.redhat.com/454261 - -* src/who.c (is_tty_writable): A new function returning true if a TTY -device is writable by the group. Additionally it checks the group to be -the same as TTY_GROUP_NAME when compiled with --with-tty-group. -* m4/jm-macros.m4: Introduce a new configure option --with-tty-group. ---- - m4/jm-macros.m4 | 19 +++++++++++++++++++ - src/who.c | 22 +++++++++++++++++++++- - 2 files changed, 40 insertions(+), 1 deletions(-) - -diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 -index 2713827..0ddbf2f 100644 ---- a/m4/jm-macros.m4 -+++ b/m4/jm-macros.m4 -@@ -144,6 +144,25 @@ AC_DEFUN([coreutils_MACROS], - ]) - - AC_REQUIRE([AM_LANGINFO_CODESET]) -+ -+ # Accept configure options: --with-tty-group[=GROUP], --without-tty-group -+ # You can determine the group of a TTY via 'stat --format %G /dev/tty' -+ # Omitting this option is equivalent to using --without-tty-group. -+ AC_ARG_WITH([tty-group], -+ AS_HELP_STRING([--with-tty-group[[[=NAME]]]], -+ [group used by system for TTYs, "tty" when not specified] -+ [ (default: do not rely on any group used for TTYs)]), -+ [tty_group_name=$withval], -+ [tty_group_name=no]) -+ -+ if test "x$tty_group_name" != xno; then -+ if test "x$tty_group_name" = xyes; then -+ tty_group_name=tty -+ fi -+ AC_MSG_NOTICE([TTY group used by system set to "$tty_group_name"]) -+ AC_DEFINE_UNQUOTED([TTY_GROUP_NAME], ["$tty_group_name"], -+ [group used by system for TTYs]) -+ fi - ]) - - AC_DEFUN([gl_CHECK_ALL_HEADERS], -diff --git a/src/who.c b/src/who.c -index f71db3b..4859694 100644 ---- a/src/who.c -+++ b/src/who.c -@@ -37,6 +37,10 @@ - #include "hard-locale.h" - #include "quote.h" - -+#ifdef TTY_GROUP_NAME -+# include -+#endif -+ - /* The official name of this program (e.g., no `g' prefix). */ - #define PROGRAM_NAME "who" - -@@ -308,6 +312,22 @@ print_line (int userlen, const char *user, const char state, - free (x_exitstr); - } - -+/* Return true if a terminal device given as PSTAT allows other users -+ to send messages to; false otherwise */ -+static bool -+is_tty_writable (struct stat const *pstat) -+{ -+#ifdef TTY_GROUP_NAME -+ /* Ensure the group of the TTY device matches TTY_GROUP_NAME, more info at -+ https://bugzilla.redhat.com/454261 */ -+ struct group *ttygr = getgrnam (TTY_GROUP_NAME); -+ if (!ttygr || (pstat->st_gid != ttygr->gr_gid)) -+ return false; -+#endif -+ -+ return pstat->st_mode & S_IWGRP; -+} -+ - /* Send properly parsed USER_PROCESS info to print_line. The most - recent boot time is BOOTTIME. */ - static void -@@ -346,7 +366,7 @@ print_user (const STRUCT_UTMP *utmp_ent, time_t boottime) - - if (stat (line, &stats) == 0) - { -- mesg = (stats.st_mode & S_IWGRP) ? '+' : '-'; -+ mesg = is_tty_writable (&stats) ? '+' : '-'; - last_change = stats.st_atime; - } - else --- -1.6.5 - diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index a8faefe..d6e6c46 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.0-orig/lib/linebuffer.h coreutils-8.0/lib/linebuffer.h ---- coreutils-8.0-orig/lib/linebuffer.h 2009-10-06 10:59:48.000000000 +0200 -+++ coreutils-8.0/lib/linebuffer.h 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/lib/linebuffer.h coreutils-8.5/lib/linebuffer.h +--- coreutils-8.5-orig/lib/linebuffer.h 2010-04-23 15:44:00.000000000 +0200 ++++ coreutils-8.5/lib/linebuffer.h 2010-04-26 14:24:33.000000000 +0200 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.0-orig/lib/linebuffer.h coreutils-8.0/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.0-orig/src/cut.c coreutils-8.0/src/cut.c ---- coreutils-8.0-orig/src/cut.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.0/src/cut.c 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c +--- coreutils-8.5-orig/src/cut.c 2010-04-20 21:52:04.000000000 +0200 ++++ coreutils-8.5/src/cut.c 2010-04-26 14:24:33.000000000 +0200 @@ -28,6 +28,11 @@ #include #include @@ -489,7 +489,7 @@ diff -urNp coreutils-8.0-orig/src/cut.c coreutils-8.0/src/cut.c @@ -757,6 +1075,8 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; - char *spec_list_string IF_LINT(= NULL); + char *spec_list_string IF_LINT (= NULL); + char mbdelim[MB_LEN_MAX + 1]; + size_t delimlen = 0; @@ -616,10 +616,10 @@ diff -urNp coreutils-8.0-orig/src/cut.c coreutils-8.0/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.0-orig/src/expand.c coreutils-8.0/src/expand.c ---- coreutils-8.0-orig/src/expand.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.0/src/expand.c 2009-10-07 10:07:16.000000000 +0200 -@@ -37,11 +37,28 @@ +diff -urNp coreutils-8.5-orig/src/expand.c coreutils-8.5/src/expand.c +--- coreutils-8.5-orig/src/expand.c 2010-01-01 14:06:47.000000000 +0100 ++++ coreutils-8.5/src/expand.c 2010-04-26 14:24:33.000000000 +0200 +@@ -38,11 +38,28 @@ #include #include #include @@ -648,7 +648,7 @@ diff -urNp coreutils-8.0-orig/src/expand.c coreutils-8.0/src/expand.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "expand" -@@ -357,6 +374,142 @@ expand (void) +@@ -358,6 +375,142 @@ expand (void) } } @@ -791,7 +791,7 @@ diff -urNp coreutils-8.0-orig/src/expand.c coreutils-8.0/src/expand.c int main (int argc, char **argv) { -@@ -421,7 +574,12 @@ main (int argc, char **argv) +@@ -422,7 +575,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -805,9 +805,9 @@ diff -urNp coreutils-8.0-orig/src/expand.c coreutils-8.0/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.0-orig/src/fold.c coreutils-8.0/src/fold.c ---- coreutils-8.0-orig/src/fold.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.0/src/fold.c 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c +--- coreutils-8.5-orig/src/fold.c 2010-01-01 14:06:47.000000000 +0100 ++++ coreutils-8.5/src/fold.c 2010-04-26 14:24:33.000000000 +0200 @@ -22,11 +22,33 @@ #include #include @@ -1205,9 +1205,9 @@ diff -urNp coreutils-8.0-orig/src/fold.c coreutils-8.0/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c ---- coreutils-8.0-orig/src/join.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.0/src/join.c 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c +--- coreutils-8.5-orig/src/join.c 2010-04-20 21:52:04.000000000 +0200 ++++ coreutils-8.5/src/join.c 2010-04-26 14:24:33.000000000 +0200 @@ -22,17 +22,31 @@ #include #include @@ -1258,7 +1258,7 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -239,10 +255,11 @@ xfields (struct line *line) +@@ -248,10 +264,11 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1272,7 +1272,7 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c extract_field (line, ptr, sep - ptr); } else -@@ -269,6 +286,148 @@ xfields (struct line *line) +@@ -278,6 +295,148 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1421,7 +1421,7 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c static void freeline (struct line *line) { -@@ -287,56 +446,115 @@ keycmp (struct line const *line1, struct +@@ -299,56 +458,115 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1560,7 +1560,7 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -417,6 +635,11 @@ get_line (FILE *fp, struct line **linep, +@@ -429,6 +647,11 @@ get_line (FILE *fp, struct line **linep, return false; } @@ -1572,7 +1572,7 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c xfields (line); if (prevline[which - 1]) -@@ -518,11 +741,18 @@ prfield (size_t n, struct line const *li +@@ -528,11 +751,18 @@ prfield (size_t n, struct line const *li /* Print the join of LINE1 and LINE2. */ @@ -1592,7 +1592,7 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c outlist = outlist_head.next; if (outlist) -@@ -557,7 +787,7 @@ prjoin (struct line const *line1, struct +@@ -567,7 +797,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1601,7 +1601,7 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c } putchar ('\n'); } -@@ -575,23 +805,23 @@ prjoin (struct line const *line1, struct +@@ -585,23 +815,23 @@ prjoin (struct line const *line1, struct prfield (join_field_1, line1); for (i = 0; i < join_field_1 && i < line1->nfields; ++i) { @@ -1629,17 +1629,13 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c prfield (i, line2); } putchar ('\n'); -@@ -1022,20 +1252,41 @@ main (int argc, char **argv) +@@ -1039,21 +1269,46 @@ main (int argc, char **argv) case 't': { - unsigned char newtab = optarg[0]; -- if (! newtab) + char *newtab; + size_t newtablen; -+ if (! optarg[0]) - error (EXIT_FAILURE, 0, _("empty tab")); -- if (optarg[1]) + newtab = xstrdup (optarg); +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) @@ -1658,32 +1654,40 @@ diff -urNp coreutils-8.0-orig/src/join.c coreutils-8.0/src/join.c + else +#endif + newtablen = 1; -+ -+ if (newtablen == 1 && newtab[1]) -+ { -+ if (STREQ (newtab, "\\0")) -+ newtab[0] = '\0'; -+ } -+ if (tab != NULL && strcmp (tab, newtab)) + if (! newtab) ++ { + newtab = '\n'; /* '' => process the whole line. */ ++ } + else if (optarg[1]) { - if (STREQ (optarg, "\\0")) - newtab = '\0'; - else - error (EXIT_FAILURE, 0, _("multi-character tab %s"), - quote (optarg)); ++ if (newtablen == 1 && newtab[1]) ++ { ++ if (STREQ (newtab, "\\0")) ++ newtab[0] = '\0'; ++ } ++ } ++ if (tab != NULL && strcmp (tab, newtab)) ++ { + free (newtab); + error (EXIT_FAILURE, 0, _("incompatible tabs")); } - if (0 <= tab && tab != newtab) - error (EXIT_FAILURE, 0, _("incompatible tabs")); tab = newtab; +- } + tablen = newtablen; - } ++ } break; -diff -urNp coreutils-8.0-orig/src/pr.c coreutils-8.0/src/pr.c ---- coreutils-8.0-orig/src/pr.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.0/src/pr.c 2009-10-07 10:07:16.000000000 +0200 + case NOCHECK_ORDER_OPTION: +diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c +--- coreutils-8.5-orig/src/pr.c 2010-03-13 16:14:09.000000000 +0100 ++++ coreutils-8.5/src/pr.c 2010-04-26 14:24:33.000000000 +0200 @@ -312,6 +312,32 @@ #include @@ -2406,9 +2410,9 @@ diff -urNp coreutils-8.0-orig/src/pr.c coreutils-8.0/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c ---- coreutils-8.0-orig/src/sort.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.0/src/sort.c 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c +--- coreutils-8.5-orig/src/sort.c 2010-04-21 09:06:17.000000000 +0200 ++++ coreutils-8.5/src/sort.c 2010-04-26 14:24:33.000000000 +0200 @@ -22,10 +22,19 @@ #include @@ -2429,7 +2433,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -122,14 +131,38 @@ static int decimal_point; +@@ -124,14 +133,38 @@ static int decimal_point; /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; @@ -2469,7 +2473,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -268,13 +301,11 @@ static bool reverse; +@@ -270,13 +303,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2486,7 +2490,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -712,6 +743,44 @@ reap_some (void) +@@ -714,6 +745,44 @@ reap_some (void) update_proc (pid); } @@ -2531,7 +2535,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1093,7 +1162,7 @@ zaptemp (const char *name) +@@ -1158,7 +1227,7 @@ zaptemp (const char *name) free (node); } @@ -2540,7 +2544,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c static int struct_month_cmp (const void *m1, const void *m2) -@@ -1108,7 +1177,7 @@ struct_month_cmp (const void *m1, const +@@ -1173,7 +1242,7 @@ struct_month_cmp (const void *m1, const /* Initialize the character class tables. */ static void @@ -2549,7 +2553,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c { size_t i; -@@ -1120,7 +1189,7 @@ inittables (void) +@@ -1185,7 +1254,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2558,7 +2562,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1202,6 +1271,64 @@ specify_nmerge (int oi, char c, char con +@@ -1268,6 +1337,64 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2623,7 +2627,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1412,7 +1539,7 @@ buffer_linelim (struct buffer const *buf +@@ -1478,7 +1605,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2632,7 +2636,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1421,10 +1548,10 @@ begfield (const struct line *line, const +@@ -1487,10 +1614,10 @@ begfield (const struct line *line, const /* The leading field separator itself is included in a field when -t is absent. */ @@ -2645,7 +2649,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1450,11 +1577,70 @@ begfield (const struct line *line, const +@@ -1516,11 +1643,70 @@ begfield (const struct line *line, const return ptr; } @@ -2717,7 +2721,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1469,10 +1655,10 @@ limfield (const struct line *line, const +@@ -1535,10 +1721,10 @@ limfield (const struct line *line, const `beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first `blank' character after the preceding field. */ @@ -2730,7 +2734,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1518,10 +1704,10 @@ limfield (const struct line *line, const +@@ -1584,10 +1770,10 @@ limfield (const struct line *line, const */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2743,7 +2747,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c if (newlim) lim = newlim; } -@@ -1552,6 +1738,113 @@ limfield (const struct line *line, const +@@ -1618,6 +1804,113 @@ limfield (const struct line *line, const return ptr; } @@ -2857,7 +2861,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c /* 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 -@@ -1634,8 +1927,24 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1700,8 +1993,24 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2884,7 +2888,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c line->keybeg = line_start; } } -@@ -1673,7 +1982,7 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1739,7 +2048,7 @@ fillbuf (struct buffer *buf, FILE *fp, c hideously fast. */ static int @@ -2893,7 +2897,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1782,6 +2091,25 @@ human_numcompare (const char *a, const c +@@ -1848,6 +2157,25 @@ human_numcompare (const char *a, const c : strnumcmp (a, b, decimal_point, thousands_sep)); } @@ -2919,7 +2923,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c static int general_numcompare (const char *sa, const char *sb) { -@@ -1815,7 +2143,7 @@ general_numcompare (const char *sa, cons +@@ -1881,7 +2209,7 @@ general_numcompare (const char *sa, cons Return 0 if the name in S is not recognized. */ static int @@ -2928,7 +2932,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -1996,11 +2324,79 @@ compare_version (char *restrict texta, s +@@ -2062,11 +2390,79 @@ compare_version (char *restrict texta, s return diff; } @@ -3009,7 +3013,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c { struct keyfield *key = keylist; -@@ -2180,6 +2576,179 @@ keycompare (const struct line *a, const +@@ -2246,6 +2642,179 @@ keycompare (const struct line *a, const return key->reverse ? -diff : diff; } @@ -3189,7 +3193,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -3178,7 +3747,7 @@ main (int argc, char **argv) +@@ -3244,7 +3813,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3198,7 +3202,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -3199,6 +3768,27 @@ main (int argc, char **argv) +@@ -3265,6 +3834,27 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3226,7 +3230,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c have_read_stdin = false; inittables (); -@@ -3459,13 +4049,35 @@ main (int argc, char **argv) +@@ -3536,13 +4126,35 @@ main (int argc, char **argv) case 't': { @@ -3266,7 +3270,7 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -3476,9 +4088,12 @@ main (int argc, char **argv) +@@ -3553,9 +4165,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3281,10 +3285,10 @@ diff -urNp coreutils-8.0-orig/src/sort.c coreutils-8.0/src/sort.c } break; -diff -urNp coreutils-8.0-orig/src/unexpand.c coreutils-8.0/src/unexpand.c ---- coreutils-8.0-orig/src/unexpand.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.0/src/unexpand.c 2009-10-07 10:07:16.000000000 +0200 -@@ -38,11 +38,28 @@ +diff -urNp coreutils-8.5-orig/src/unexpand.c coreutils-8.5/src/unexpand.c +--- coreutils-8.5-orig/src/unexpand.c 2010-01-01 14:06:47.000000000 +0100 ++++ coreutils-8.5/src/unexpand.c 2010-04-26 14:24:33.000000000 +0200 +@@ -39,11 +39,28 @@ #include #include #include @@ -3313,7 +3317,7 @@ diff -urNp coreutils-8.0-orig/src/unexpand.c coreutils-8.0/src/unexpand.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "unexpand" -@@ -102,6 +119,208 @@ static struct option const longopts[] = +@@ -103,6 +120,208 @@ static struct option const longopts[] = {NULL, 0, NULL, 0} }; @@ -3522,7 +3526,7 @@ diff -urNp coreutils-8.0-orig/src/unexpand.c coreutils-8.0/src/unexpand.c void usage (int status) { -@@ -523,7 +742,12 @@ main (int argc, char **argv) +@@ -524,7 +743,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -3536,10 +3540,10 @@ diff -urNp coreutils-8.0-orig/src/unexpand.c coreutils-8.0/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.0-orig/src/uniq.c coreutils-8.0/src/uniq.c ---- coreutils-8.0-orig/src/uniq.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.0/src/uniq.c 2009-10-07 10:07:16.000000000 +0200 -@@ -22,6 +22,16 @@ +diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c +--- coreutils-8.5-orig/src/uniq.c 2010-03-13 16:14:09.000000000 +0100 ++++ coreutils-8.5/src/uniq.c 2010-04-26 14:24:33.000000000 +0200 +@@ -21,6 +21,16 @@ #include #include @@ -3905,18 +3909,18 @@ diff -urNp coreutils-8.0-orig/src/uniq.c coreutils-8.0/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.0-orig/tests/Makefile.am coreutils-8.0/tests/Makefile.am ---- coreutils-8.0-orig/tests/Makefile.am 2009-09-29 16:25:44.000000000 +0200 -+++ coreutils-8.0/tests/Makefile.am 2009-10-07 10:07:16.000000000 +0200 -@@ -208,6 +208,7 @@ TESTS = \ +diff -urNp coreutils-8.5-orig/tests/Makefile.am coreutils-8.5/tests/Makefile.am +--- coreutils-8.5-orig/tests/Makefile.am 2010-04-26 14:24:10.000000000 +0200 ++++ coreutils-8.5/tests/Makefile.am 2010-04-26 14:24:33.000000000 +0200 +@@ -224,6 +224,7 @@ TESTS = \ misc/sort-compress \ misc/sort-continue \ misc/sort-files0-from \ + misc/sort-mb-tests \ misc/sort-merge \ misc/sort-merge-fdlimit \ - misc/sort-rand \ -@@ -452,6 +453,10 @@ TESTS = \ + misc/sort-month \ +@@ -475,6 +476,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -3927,9 +3931,9 @@ diff -urNp coreutils-8.0-orig/tests/Makefile.am coreutils-8.0/tests/Makefile.am pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.0-orig/tests/misc/cut coreutils-8.0/tests/misc/cut ---- coreutils-8.0-orig/tests/misc/cut 2009-09-21 14:29:33.000000000 +0200 -+++ coreutils-8.0/tests/misc/cut 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/tests/misc/cut coreutils-8.5/tests/misc/cut +--- coreutils-8.5-orig/tests/misc/cut 2010-01-01 14:06:47.000000000 +0100 ++++ coreutils-8.5/tests/misc/cut 2010-04-26 14:24:33.000000000 +0200 @@ -26,7 +26,7 @@ use strict; my $prog = 'cut'; my $try = "Try \`$prog --help' for more information.\n"; @@ -3948,41 +3952,41 @@ diff -urNp coreutils-8.0-orig/tests/misc/cut coreutils-8.0/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], -diff -urNp coreutils-8.0-orig/tests/misc/mb1.I coreutils-8.0/tests/misc/mb1.I ---- coreutils-8.0-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/tests/misc/mb1.I 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/tests/misc/mb1.I coreutils-8.5/tests/misc/mb1.I +--- coreutils-8.5-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.5/tests/misc/mb1.I 2010-04-26 14:24:33.000000000 +0200 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.0-orig/tests/misc/mb1.X coreutils-8.0/tests/misc/mb1.X ---- coreutils-8.0-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/tests/misc/mb1.X 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/tests/misc/mb1.X coreutils-8.5/tests/misc/mb1.X +--- coreutils-8.5-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.5/tests/misc/mb1.X 2010-04-26 14:24:33.000000000 +0200 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.0-orig/tests/misc/mb2.I coreutils-8.0/tests/misc/mb2.I ---- coreutils-8.0-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/tests/misc/mb2.I 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/tests/misc/mb2.I coreutils-8.5/tests/misc/mb2.I +--- coreutils-8.5-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.5/tests/misc/mb2.I 2010-04-26 14:24:33.000000000 +0200 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.0-orig/tests/misc/mb2.X coreutils-8.0/tests/misc/mb2.X ---- coreutils-8.0-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/tests/misc/mb2.X 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/tests/misc/mb2.X coreutils-8.5/tests/misc/mb2.X +--- coreutils-8.5-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.5/tests/misc/mb2.X 2010-04-26 14:24:33.000000000 +0200 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.0-orig/tests/misc/sort-mb-tests coreutils-8.0/tests/misc/sort-mb-tests ---- coreutils-8.0-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.0/tests/misc/sort-mb-tests 2009-10-07 10:07:16.000000000 +0200 +diff -urNp coreutils-8.5-orig/tests/misc/sort-mb-tests coreutils-8.5/tests/misc/sort-mb-tests +--- coreutils-8.5-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.5/tests/misc/sort-mb-tests 2010-04-26 14:24:33.000000000 +0200 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils.spec b/coreutils.spec index 82ad271..19e14f4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.4 -Release: 8%{?dist} +Version: 8.5 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,8 +18,6 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -#"who" doesn't determine user's message status correctly - #454261 -Patch1: coreutils-8.4-who-msgstatus.patch # Our patches #general patch to workaround koji build system issues @@ -119,7 +117,6 @@ Libraries for coreutils package. %setup -q # From upstream -%patch1 -p1 -b .whomsg # Our patches %patch100 -p1 -b .configure @@ -341,6 +338,9 @@ fi %{_libdir}/coreutils %changelog +* Mon Apr 26 2010 Ondrej Vasik - 8.5-1 +- new upstream release 8.5 + * Thu Apr 15 2010 Ondrej Vasik - 8.4-8 - move readlink from /usr/bin to bin, keep symlink in /usr/bin(#580682) diff --git a/sources b/sources index 9ff0def..f6e9894 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -1fde97f144b4699b18f36c2ec18b1f18 coreutils-8.4.tar.xz +55170ed640e300f5b81640c6f4641513 coreutils-8.5.tar.xz From 5421281a0daef7aec89a7215734ee38cd2670f8a Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 27 Apr 2010 10:30:50 +0000 Subject: [PATCH 090/523] doublequote LS_COLORS in colorls.*sh scripts to speedup shell start(#586029), add patch for mkstemp on sparc64(Dennis Gilmore), update /etc/DIR_COLORS* files --- coreutils-DIR_COLORS | 5 +++-- coreutils-DIR_COLORS.256color | 3 ++- coreutils-DIR_COLORS.lightbgcolor | 4 +++- coreutils-colorls.csh | 10 +++++----- coreutils-colorls.sh | 2 +- coreutils-mkstemp.patch | 9 +++++++++ coreutils.spec | 11 ++++++++++- 7 files changed, 33 insertions(+), 11 deletions(-) create mode 100644 coreutils-mkstemp.patch diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 8aec576..a045303 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -1,5 +1,5 @@ # Configuration file for the color ls utility -# Synchronized with coreutils 8.1 dircolors +# Synchronized with coreutils 8.5 dircolors # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. @@ -45,9 +45,11 @@ TERM mach-color TERM mlterm TERM putty TERM rxvt +TERM rxvt-256color TERM rxvt-cygwin TERM rxvt-cygwin-native TERM rxvt-unicode +TERM rxvt-unicode256 TERM screen TERM screen-256color TERM screen-256color-bce @@ -94,7 +96,6 @@ STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable - # This is for files with execute permission: EXEC 01;32 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 1c0d3b3..b682ea2 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -1,6 +1,6 @@ # Configuration file for the 256color ls utility # This file goes in the /etc directory, and must be world readable. -# Synchronized with coreutils 8.1 dircolors +# Synchronized with coreutils 8.5 dircolors # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. # In the case that you are not satisfied with supplied colors, please @@ -23,6 +23,7 @@ OPTIONS -F -T 0 # Below, there should be one TERM entry for each termtype that is colorizable TERM putty-256color TERM rxvt-256color +TERM rxvt-unicode256 TERM screen-256color TERM xterm-256color TERM gnome-256color diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index ce55538..2400e1e 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -1,5 +1,5 @@ # Configuration file for the color ls utility - modified for gray backgrounds -# Synchronized with coreutils 8.1 dircolors +# Synchronized with coreutils 8.5 dircolors # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. @@ -34,7 +34,9 @@ TERM xterm-16color TERM xterm-88color TERM xterm-256color TERM rxvt +TERM rxvt-256color TERM rxvt-unicode +TERM rxvt-unicode256 TERM xterm-color TERM color-xterm TERM vt100 diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 317cd0c..7e3d794 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -2,7 +2,7 @@ # color-ls initialization if ( $?USER_LS_COLORS ) then if ( "$USER_LS_COLORS" != "" ) then - #when USER_LS_COLORS defined do not override user + #when USER_LS_COLORS defined do not override user #specified LS_COLORS and use them goto finish endif @@ -12,14 +12,14 @@ alias ll 'ls -l' alias l. 'ls -d .*' set COLORS=/etc/DIR_COLORS if ($?TERM) then - if ( -e "/etc/DIR_COLORS.$TERM" ) then + if ( -e "/etc/DIR_COLORS.$TERM" ) then set COLORS="/etc/DIR_COLORS.$TERM" endif endif if ( -e "/etc/DIR_COLORS.256color" ) then if ( "`tty -s && tput colors`" == "256" ) then set COLORS=/etc/DIR_COLORS.256color - endif + endif endif if ( -f ~/.dircolors ) set COLORS=~/.dircolors if ( -f ~/.dir_colors ) set COLORS=~/.dir_colors @@ -30,11 +30,11 @@ endif if ( ! -e "$COLORS" ) exit -eval `dircolors -c $COLORS` +eval "`dircolors -c $COLORS`" if ( "$LS_COLORS" == '' ) exit set color_none=`sed -n '/^COLOR.*none/Ip' < $COLORS` -if ( "$color_none" != '' ) then +if ( "$color_none" != '' ) then unset color_none exit endif diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index f4d6400..dc5c223 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -30,7 +30,7 @@ if [ -z "$USER_LS_COLORS" ]; then # Existence of $COLORS already checked above. [ -n "$COLORS" ] || return - eval `dircolors --sh "$COLORS" 2>/dev/null` + eval "`dircolors --sh "$COLORS" 2>/dev/null`" [ -z "$LS_COLORS" ] && return grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return fi diff --git a/coreutils-mkstemp.patch b/coreutils-mkstemp.patch new file mode 100644 index 0000000..96cc9e4 --- /dev/null +++ b/coreutils-mkstemp.patch @@ -0,0 +1,9 @@ +--- coreutils-7.6/lib/mkstemp.c.BAD 2010-03-03 18:17:52.000000000 +0000 ++++ coreutils-7.6/lib/mkstemp.c 2010-03-03 18:18:28.000000000 +0000 +@@ -40,5 +40,5 @@ + int + mkstemp (char *xtemplate; + { +- return __gen_tempname (xtemplate, 0, 0, __GT_FILE); ++ return __gen_tempname (xtemplate, __GT_FILE); + } diff --git a/coreutils.spec b/coreutils.spec index 19e14f4..fc8ea2d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.5 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -30,6 +30,8 @@ Patch102: coreutils-7.4-sttytcsadrain.patch Patch103: coreutils-8.2-uname-processortype.patch #df --direct Patch104: coreutils-df-direct.patch +#Fix mkstemp on sparc64 +Patch105: coreutils-mkstemp.patch # sh-utils #add info about TZ envvar to date manpage @@ -124,6 +126,7 @@ Libraries for coreutils package. %patch102 -p1 -b .tcsadrain %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect +%patch105 -p1 -b .sparc # sh-utils %patch703 -p1 -b .dateman @@ -338,6 +341,12 @@ fi %{_libdir}/coreutils %changelog +* Tue Apr 27 2010 Ondrej Vasik - 8.5-2 +- doublequote LS_COLORS in colorls.*sh scripts to speedup + shell start(#586029) +- add patch for mkstemp on sparc64(Dennis Gilmore) +- update /etc/DIR_COLORS* files + * Mon Apr 26 2010 Ondrej Vasik - 8.5-1 - new upstream release 8.5 From 09425ca8ae5a1017de390af2ea1ac0179477bf65 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 27 Apr 2010 10:45:41 +0000 Subject: [PATCH 091/523] fix typo --- coreutils-mkstemp.patch | 2 +- coreutils.spec | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coreutils-mkstemp.patch b/coreutils-mkstemp.patch index 96cc9e4..cc4c338 100644 --- a/coreutils-mkstemp.patch +++ b/coreutils-mkstemp.patch @@ -2,7 +2,7 @@ +++ coreutils-7.6/lib/mkstemp.c 2010-03-03 18:18:28.000000000 +0000 @@ -40,5 +40,5 @@ int - mkstemp (char *xtemplate; + mkstemp (char *xtemplate); { - return __gen_tempname (xtemplate, 0, 0, __GT_FILE); + return __gen_tempname (xtemplate, __GT_FILE); diff --git a/coreutils.spec b/coreutils.spec index fc8ea2d..6609e1b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -6,7 +6,7 @@ License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color @@ -126,7 +126,7 @@ Libraries for coreutils package. %patch102 -p1 -b .tcsadrain %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect -%patch105 -p1 -b .sparc +#%patch105 -p1 -b .sparc # sh-utils %patch703 -p1 -b .dateman From c61df8518bd1e91bd17535c11270e5a670f4d7cd Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 27 Apr 2010 10:46:10 +0000 Subject: [PATCH 092/523] fix oops --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 6609e1b..738040a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -6,7 +6,7 @@ License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz +Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color From c9dda99c50470ef2c7f5c05c3926feec093b06bf Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 27 Apr 2010 10:47:17 +0000 Subject: [PATCH 093/523] fix oops^2 - coffee needed --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 738040a..fc8ea2d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -126,7 +126,7 @@ Libraries for coreutils package. %patch102 -p1 -b .tcsadrain %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect -#%patch105 -p1 -b .sparc +%patch105 -p1 -b .sparc # sh-utils %patch703 -p1 -b .dateman From 5408b3bda32b7d2dafa743893b326330b450faad Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 27 Apr 2010 10:58:42 +0000 Subject: [PATCH 094/523] coffee here...fix oops^3 --- coreutils-mkstemp.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-mkstemp.patch b/coreutils-mkstemp.patch index cc4c338..af8d273 100644 --- a/coreutils-mkstemp.patch +++ b/coreutils-mkstemp.patch @@ -2,7 +2,7 @@ +++ coreutils-7.6/lib/mkstemp.c 2010-03-03 18:18:28.000000000 +0000 @@ -40,5 +40,5 @@ int - mkstemp (char *xtemplate); + mkstemp (char *xtemplate) { - return __gen_tempname (xtemplate, 0, 0, __GT_FILE); + return __gen_tempname (xtemplate, __GT_FILE); From 2fb3ab2d41620e98eb68991b448e4d9d6df9c403 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 14 May 2010 12:36:48 +0000 Subject: [PATCH 095/523] restore a part of coreutils-getgrouplist.patch which has been lost during rediff --- coreutils-getgrouplist.patch | 73 ++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch index e5c2985..6dfb424 100644 --- a/coreutils-getgrouplist.patch +++ b/coreutils-getgrouplist.patch @@ -1,6 +1,7 @@ -diff -urp coreutils-6.10-orig/lib/getugroups.c coreutils-6.10/lib/getugroups.c ---- coreutils-6.10-orig/lib/getugroups.c 2007-10-17 15:47:25.000000000 +0200 -+++ coreutils-6.10/lib/getugroups.c 2008-01-24 16:37:04.000000000 +0100 +diff --git a/lib/getugroups.c b/lib/getugroups.c +index 299bae6..8ece29b 100644 +--- a/lib/getugroups.c ++++ b/lib/getugroups.c @@ -19,6 +19,9 @@ #include @@ -11,15 +12,71 @@ diff -urp coreutils-6.10-orig/lib/getugroups.c coreutils-6.10/lib/getugroups.c #include "getugroups.h" #include -@@ -123,3 +126,4 @@ getugroups (int maxcount, GETGROUPS_T *g +@@ -123,3 +126,4 @@ getugroups (int maxcount, gid_t *grouplist, char const *username, } #endif /* HAVE_GRP_H */ +#endif /* have getgrouplist */ -diff -urp coreutils-6.10-orig/m4/jm-macros.m4 coreutils-6.10/m4/jm-macros.m4 ---- coreutils-6.10-orig/m4/jm-macros.m4 2007-11-25 14:23:31.000000000 +0100 -+++ coreutils-6.10/m4/jm-macros.m4 2008-01-24 16:42:00.000000000 +0100 -@@ -52,6 +52,7 @@ AC_DEFUN([coreutils_MACROS], +diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c +index 76474c2..0a9d221 100644 +--- a/lib/mgetgroups.c ++++ b/lib/mgetgroups.c +@@ -115,9 +115,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) + /* else no username, so fall through and use getgroups. */ + #endif + +- max_n_groups = (username +- ? getugroups (0, NULL, username, gid) +- : getgroups (0, NULL)); ++ if (!username) ++ max_n_groups = getgroups(0, NULL); ++ else ++ { ++#ifdef HAVE_GETGROUPLIST ++ max_n_groups = 0; ++ getgrouplist (username, gid, NULL, &max_n_groups); ++#else ++ max_n_groups = getugroups (0, NULL, username, gid); ++#endif ++ } + + /* If we failed to count groups because there is no supplemental + group support, then return an array containing just GID. +@@ -139,10 +147,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) + if (g == NULL) + return -1; + +- ng = (username +- ? getugroups (max_n_groups, g, username, gid) +- : getgroups (max_n_groups - (gid != (gid_t) -1), +- g + (gid != (gid_t) -1))); ++ if (!username) ++ ng = getgroups (max_n_groups, g); ++ else ++ { ++#ifdef HAVE_GETGROUPLIST ++ int e; ++ ng = max_n_groups; ++ while ((e = getgrouplist (username, gid, g, &ng)) == -1 ++ && ng > max_n_groups) ++ { ++ max_n_groups = ng; ++ g = xrealloc (g, max_n_groups * sizeof (GETGROUPS_T)); ++ } ++ if (e == -1) ++ ng = -1; ++#else ++ ng = getugroups (max_n_groups, g, username, gid); ++#endif ++ } + + if (ng < 0) + { +diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 +index 62777c7..5180243 100644 +--- a/m4/jm-macros.m4 ++++ b/m4/jm-macros.m4 +@@ -78,6 +78,7 @@ AC_DEFUN([coreutils_MACROS], fchown \ fchmod \ ftruncate \ From 182b0889a6fed6f55331e9c91920fddd7baac5a4 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Tue, 25 May 2010 07:52:58 +0000 Subject: [PATCH 096/523] fix build on s390 with old kernels - disable gnulib's test-utimens --- coreutils-6.10-configuration.patch | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index d1cb20c..7d165b9 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -68,6 +68,22 @@ diff -urNp coreutils-8.4-orig/gnulib-tests/gnulib.mk coreutils-8.4/gnulib-tests/ ## end gnulib module unistd-safer-tests +@@ -1644,10 +1644,10 @@ EXTRA_DIST += test-usleep.c signature.h + + ## begin gnulib module utimens-tests + +-TESTS += test-utimens +-check_PROGRAMS += test-utimens +-test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBINTL@ +-EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h ++#TESTS += test-utimens ++#check_PROGRAMS += test-utimens ++#test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBINTL@ ++#EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h + + ## end gnulib module utimens-tests + + diff -urNp coreutils-8.4-orig/tests/Makefile.am coreutils-8.4/tests/Makefile.am --- coreutils-8.4-orig/tests/Makefile.am 2010-01-03 18:06:20.000000000 +0100 +++ coreutils-8.4/tests/Makefile.am 2010-01-14 10:28:17.000000000 +0100 From 4bdb7ac78002635fbcbe6500666f4a2fdca9eb3b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 2 Jul 2010 11:42:29 +0000 Subject: [PATCH 097/523] coreutils-getgrouplist.patch: fix regression introduced in r1.7 --- coreutils-getgrouplist.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch index 6dfb424..0c8eb41 100644 --- a/coreutils-getgrouplist.patch +++ b/coreutils-getgrouplist.patch @@ -51,7 +51,7 @@ index 76474c2..0a9d221 100644 - : getgroups (max_n_groups - (gid != (gid_t) -1), - g + (gid != (gid_t) -1))); + if (!username) -+ ng = getgroups (max_n_groups, g); ++ ng = getgroups (max_n_groups - (gid != (gid_t)-1), g + (gid != (gid_t)-1)); + else + { +#ifdef HAVE_GETGROUPLIST From 93d4e3a79f7508e83cc64ca0bca4537d1c1154b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Hor=C3=A1k?= Date: Fri, 2 Jul 2010 12:57:45 +0000 Subject: [PATCH 098/523] - rebuilt with the updated configuration patch - drop the old -O1 exception for s390(x) - updated the getgrouplist patch (Kamil Dudka) --- coreutils.spec | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index fc8ea2d..3b945a2 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.5 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -156,12 +156,7 @@ find ./po/ -name "*.p*" | xargs \ -e 's/-dpR/-cdpR/' %build -%ifarch s390 s390x -# Build at -O1 for the moment (bug #196369). -export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fPIC -O1" -%else export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" -%endif %{expand:%%global optflags %{optflags} -D_GNU_SOURCE=1} #autoreconf -i -v touch aclocal.m4 configure config.hin Makefile.in */Makefile.in @@ -341,6 +336,11 @@ fi %{_libdir}/coreutils %changelog +* Fri Jul 2 2010 Dan Horák - 8.5-3 +- rebuilt with the updated configuration patch +- drop the old -O1 exception for s390(x) +- updated the getgrouplist patch (Kamil Dudka) + * Tue Apr 27 2010 Ondrej Vasik - 8.5-2 - doublequote LS_COLORS in colorls.*sh scripts to speedup shell start(#586029) From 437af5569d1f5224ad966c86a56728bd942c780d Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 22 Jul 2010 14:23:44 +0000 Subject: [PATCH 099/523] Add .ear, .war, .sar , for Java jar-like archives to dircolors (#616497) --- coreutils-8.5-dircolors.patch | 13 +++++++++++++ coreutils-DIR_COLORS | 3 +++ coreutils-DIR_COLORS.256color | 3 +++ coreutils-DIR_COLORS.lightbgcolor | 3 +++ coreutils.spec | 9 ++++++++- 5 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.5-dircolors.patch diff --git a/coreutils-8.5-dircolors.patch b/coreutils-8.5-dircolors.patch new file mode 100644 index 0000000..8707c0a --- /dev/null +++ b/coreutils-8.5-dircolors.patch @@ -0,0 +1,13 @@ +diff -urNp coreutils-8.5-orig/src/dircolors.hin coreutils-8.5/src/dircolors.hin +--- coreutils-8.5-orig/src/dircolors.hin 2010-04-20 21:52:04.000000000 +0200 ++++ coreutils-8.5/src/dircolors.hin 2010-07-22 16:18:41.978036926 +0200 +@@ -127,6 +127,9 @@ EXEC 01;32 + .deb 01;31 + .rpm 01;31 + .jar 01;31 ++.war 01;31 ++.ear 01;31 ++.sar 01;31 + .rar 01;31 + .ace 01;31 + .zoo 01;31 diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index a045303..4befd4c 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -134,6 +134,9 @@ EXEC 01;32 .deb 01;31 .rpm 01;31 .jar 01;31 +.war 01;31 +.ear 01;31 +.sar 01;31 .rar 01;31 .ace 01;31 .zoo 01;31 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index b682ea2..1b2d628 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -109,6 +109,9 @@ EXEC 38;5;34 .deb 38;5;9 .rpm 38;5;9 .jar 38;5;9 +.war 38;5;9 +.ear 38;5;9 +.sar 38;5;9 .rar 38;5;9 .ace 38;5;9 .zoo 38;5;9 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index 2400e1e..a843bff 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -113,6 +113,9 @@ EXEC 00;32 .deb 00;31 .rpm 00;31 .jar 00;31 +.war 00;31 +.ear 00;31 +.sar 00;31 .rar 00;31 .ace 00;31 .zoo 00;31 diff --git a/coreutils.spec b/coreutils.spec index 3b945a2..7c313d5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.5 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -32,6 +32,8 @@ Patch103: coreutils-8.2-uname-processortype.patch Patch104: coreutils-df-direct.patch #Fix mkstemp on sparc64 Patch105: coreutils-mkstemp.patch +#add jar-like archives to colored ones +Patch106: coreutils-8.5-dircolors.patch # sh-utils #add info about TZ envvar to date manpage @@ -127,6 +129,7 @@ Libraries for coreutils package. %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect %patch105 -p1 -b .sparc +%patch106 -p1 -b .java # sh-utils %patch703 -p1 -b .dateman @@ -336,6 +339,10 @@ fi %{_libdir}/coreutils %changelog +* Thu Jul 22 2010 Ondrej Vasik - 8.5-4 +- Add .ear, .war, .sar , for Java jar-like archives to + dircolors (#616497) + * Fri Jul 2 2010 Dan Horák - 8.5-3 - rebuilt with the updated configuration patch - drop the old -O1 exception for s390(x) From e0981f3d304fbbe5013b6c464f015e6fae5db6d2 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 28 Jul 2010 12:11:27 +0000 Subject: [PATCH 100/523] dist-git conversion --- .cvsignore => .gitignore | 0 Makefile | 21 --------------------- branch | 1 - 3 files changed, 22 deletions(-) rename .cvsignore => .gitignore (100%) delete mode 100644 Makefile delete mode 100644 branch diff --git a/.cvsignore b/.gitignore similarity index 100% rename from .cvsignore rename to .gitignore diff --git a/Makefile b/Makefile deleted file mode 100644 index cdca58a..0000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Makefile for source rpm: coreutils -# $Id$ -NAME := coreutils -SPECFILE = $(firstword $(wildcard *.spec)) - -define find-makefile-common -for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done -endef - -MAKEFILE_COMMON := $(shell $(find-makefile-common)) - -ifeq ($(MAKEFILE_COMMON),) -# attempt a checkout -define checkout-makefile-common -test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2 -endef - -MAKEFILE_COMMON := $(shell $(checkout-makefile-common)) -endif - -include $(MAKEFILE_COMMON) diff --git a/branch b/branch deleted file mode 100644 index dc32377..0000000 --- a/branch +++ /dev/null @@ -1 +0,0 @@ -F-10 From 24132a00a84bedfca37f88c053611738087c8195 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 28 Jul 2010 12:11:43 +0000 Subject: [PATCH 101/523] dist-git conversion --- .cvsignore => .gitignore | 0 Makefile | 21 --------------------- 2 files changed, 21 deletions(-) rename .cvsignore => .gitignore (100%) delete mode 100644 Makefile diff --git a/.cvsignore b/.gitignore similarity index 100% rename from .cvsignore rename to .gitignore diff --git a/Makefile b/Makefile deleted file mode 100644 index cdca58a..0000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Makefile for source rpm: coreutils -# $Id$ -NAME := coreutils -SPECFILE = $(firstword $(wildcard *.spec)) - -define find-makefile-common -for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done -endef - -MAKEFILE_COMMON := $(shell $(find-makefile-common)) - -ifeq ($(MAKEFILE_COMMON),) -# attempt a checkout -define checkout-makefile-common -test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2 -endef - -MAKEFILE_COMMON := $(shell $(checkout-makefile-common)) -endif - -include $(MAKEFILE_COMMON) From 2a672b5b694ddc9174f140a713c6da10c6e6e555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 30 Aug 2010 15:29:35 +0200 Subject: [PATCH 102/523] fix double free abort in tac (#628213) --- coreutils-8.5-tac-doublefree.patch | 82 ++++++++++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.5-tac-doublefree.patch diff --git a/coreutils-8.5-tac-doublefree.patch b/coreutils-8.5-tac-doublefree.patch new file mode 100644 index 0000000..e8298c1 --- /dev/null +++ b/coreutils-8.5-tac-doublefree.patch @@ -0,0 +1,82 @@ +From b3959fc691e606857a3c6e9b316ec34819972245 Mon Sep 17 00:00:00 2001 +From: Jim Meyering +Date: Sat, 28 Aug 2010 17:45:29 +0200 +Subject: [PATCH] tac: avoid double free + +* src/tac.c (main): Reading a line longer than 16KiB would cause +tac to realloc its primary buffer. Then, just before exit, tac +would mistakenly free the original (now free'd) buffer. +This bug was introduced by commit be6c13e7, "maint: always free a +buffer, to avoid even semblance of a leak". +* NEWS (Bug fixes): Mention it. +* tests/misc/tac (double-free): New test, to exercise this. +Reported by Salvo Tomaselli in . +--- + NEWS | 3 +++ + src/tac.c | 6 ++++-- + tests/misc/tac | 6 ++++++ + 3 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/NEWS b/NEWS +index 85f55a2..f29d311 100644 +--- a/NEWS ++++ b/NEWS +@@ -11,6 +11,9 @@ GNU coreutils NEWS -*- outline -*- + du -H and -L now consistently count pointed-to files instead of + symbolic links, and correctly diagnose dangling symlinks. + ++ tac would perform a double-free when given an input line longer than 16KiB. ++ [bug introduced in coreutils-8.3] ++ + ** New features + + cp now accepts the --attributes-only option to not copy file data, +diff --git a/src/tac.c b/src/tac.c +index cec9736..859e006 100644 +--- a/src/tac.c ++++ b/src/tac.c +@@ -633,7 +633,6 @@ main (int argc, char **argv) + if (! (read_size < half_buffer_size && half_buffer_size < G_buffer_size)) + xalloc_die (); + G_buffer = xmalloc (G_buffer_size); +- void *buf = G_buffer; + if (sentinel_length) + { + strcpy (G_buffer, separator); +@@ -666,6 +665,9 @@ main (int argc, char **argv) + error (0, errno, "-"); + ok = false; + } +- free (buf); ++ ++ size_t offset = sentinel_length ? sentinel_length : 1; ++ free (G_buffer - offset); ++ + exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); + } +diff --git a/tests/misc/tac b/tests/misc/tac +index 7631049..4130c00 100755 +--- a/tests/misc/tac ++++ b/tests/misc/tac +@@ -24,6 +24,9 @@ my $prog = 'tac'; + + my $bad_dir = 'no/such/dir'; + ++# This must be longer than 16KiB to trigger the double free in coreutils-8.5. ++my $long_line = 'o' x (16 * 1024 + 1); ++ + my @Tests = + ( + ['segfault', '-r', {IN=>"a\n"}, {IN=>"b\n"}, {OUT=>"a\nb\n"}], +@@ -67,6 +70,9 @@ my @Tests = + {ERR_SUBST => "s,`$bad_dir': .*,...,"}, + {ERR => "$prog: cannot create temporary file in ...\n"}, + {EXIT => 1}], ++ ++ # coreutils-8.5's tac would double-free its primary buffer. ++ ['double-free', {IN=>$long_line}, {OUT=>$long_line}], + ); + + @Tests = triple_test \@Tests; +-- +1.7.2.2.510.g7180a diff --git a/coreutils.spec b/coreutils.spec index 7c313d5..34ed34d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.5 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,6 +18,8 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream +#fix double free error in tac (reported in debian bug #594666) +Patch1: coreutils-8.5-tac-doublefree.patch # Our patches #general patch to workaround koji build system issues @@ -121,6 +123,7 @@ Libraries for coreutils package. %setup -q # From upstream +%patch1 -p1 -b .doublefree # Our patches %patch100 -p1 -b .configure @@ -339,6 +342,9 @@ fi %{_libdir}/coreutils %changelog +* Mon Aug 30 2010 Ondrej Vasik - 8.5-5 +- fix double free abort in tac (#628213) + * Thu Jul 22 2010 Ondrej Vasik - 8.5-4 - Add .ear, .war, .sar , for Java jar-like archives to dircolors (#616497) From 28c58ff02cb5d7bdbdd6998368c929f04bc85431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 31 Aug 2010 10:52:40 +0200 Subject: [PATCH 103/523] No need for NEWS modification, it only causes troubles in our case --- coreutils-8.5-tac-doublefree.patch | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/coreutils-8.5-tac-doublefree.patch b/coreutils-8.5-tac-doublefree.patch index e8298c1..467c202 100644 --- a/coreutils-8.5-tac-doublefree.patch +++ b/coreutils-8.5-tac-doublefree.patch @@ -8,29 +8,13 @@ tac to realloc its primary buffer. Then, just before exit, tac would mistakenly free the original (now free'd) buffer. This bug was introduced by commit be6c13e7, "maint: always free a buffer, to avoid even semblance of a leak". -* NEWS (Bug fixes): Mention it. * tests/misc/tac (double-free): New test, to exercise this. Reported by Salvo Tomaselli in . --- - NEWS | 3 +++ src/tac.c | 6 ++++-- tests/misc/tac | 6 ++++++ - 3 files changed, 13 insertions(+), 2 deletions(-) + 2 files changed, 10 insertions(+), 2 deletions(-) -diff --git a/NEWS b/NEWS -index 85f55a2..f29d311 100644 ---- a/NEWS -+++ b/NEWS -@@ -11,6 +11,9 @@ GNU coreutils NEWS -*- outline -*- - du -H and -L now consistently count pointed-to files instead of - symbolic links, and correctly diagnose dangling symlinks. - -+ tac would perform a double-free when given an input line longer than 16KiB. -+ [bug introduced in coreutils-8.3] -+ - ** New features - - cp now accepts the --attributes-only option to not copy file data, diff --git a/src/tac.c b/src/tac.c index cec9736..859e006 100644 --- a/src/tac.c From f050d2d59c0d109ea80a273036c32ec0df68ae14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 6 Sep 2010 09:31:40 +0200 Subject: [PATCH 104/523] compile su with pie again (#630017) --- coreutils-8.4-su-pie.patch | 11 +++++++++++ coreutils.spec | 11 ++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 coreutils-8.4-su-pie.patch diff --git a/coreutils-8.4-su-pie.patch b/coreutils-8.4-su-pie.patch new file mode 100644 index 0000000..75db725 --- /dev/null +++ b/coreutils-8.4-su-pie.patch @@ -0,0 +1,11 @@ +diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am +--- coreutils-8.4-orig/src/Makefile.am 2010-09-03 17:34:43.399747649 +0200 ++++ coreutils-8.4/src/Makefile.am 2010-09-03 17:36:13.005765125 +0200 +@@ -367,6 +367,7 @@ factor_LDADD += $(LIB_GMP) + + # for crypt + su_LDADD += $(LIB_CRYPT) @LIB_PAM@ ++su_LDFLAGS = -pie + + # for various ACL functions + copy_LDADD += $(LIB_ACL) diff --git a/coreutils.spec b/coreutils.spec index 34ed34d..3f0c69a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.5 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -64,6 +64,8 @@ Patch912: coreutils-overflow.patch Patch915: coreutils-split-pam.patch #prevent koji build failure with wrong getfacl exit code Patch916: coreutils-getfacl-exit-code.patch +#compile su with pie flag +Patch917: coreutils-8.4-su-pie.patch #SELINUX Patch - implements Redhat changes #(upstream did some SELinux implementation unlike with RedHat patch) @@ -149,6 +151,7 @@ Libraries for coreutils package. %patch912 -p1 -b .overflow %patch915 -p1 -b .splitl %patch916 -p1 -b .getfacl-exit-code +%patch917 -p1 -b .pie #SELinux %patch950 -p1 -b .selinux @@ -179,8 +182,7 @@ automake --copy --add-missing touch man/*.x make all %{?_smp_mflags} \ - %{?!nopam:CPPFLAGS="-DUSE_PAM"} \ - su_LDFLAGS="-pie %{?!nopam:-lpam -lpam_misc}" + %{?!nopam:CPPFLAGS="-DUSE_PAM"} # XXX docs should say /var/run/[uw]tmp not /etc/[uw]tmp sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi @@ -342,6 +344,9 @@ fi %{_libdir}/coreutils %changelog +* Mon Sep 06 2010 Ondrej Vasik - 8.5-6 +- compile su with pie again (#630017) + * Mon Aug 30 2010 Ondrej Vasik - 8.5-5 - fix double free abort in tac (#628213) From c28546fac45c8b31a2282ab0790f4bd8aaea06f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 8 Sep 2010 10:25:18 +0200 Subject: [PATCH 105/523] add RELRO protection to su as well (#630017) --- coreutils-8.4-su-pie.patch | 2 +- coreutils.spec | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/coreutils-8.4-su-pie.patch b/coreutils-8.4-su-pie.patch index 75db725..07d1d5e 100644 --- a/coreutils-8.4-su-pie.patch +++ b/coreutils-8.4-su-pie.patch @@ -5,7 +5,7 @@ diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am # for crypt su_LDADD += $(LIB_CRYPT) @LIB_PAM@ -+su_LDFLAGS = -pie ++su_LDFLAGS = -pie -Wl,-z,relro,-z,now # for various ACL functions copy_LDADD += $(LIB_ACL) diff --git a/coreutils.spec b/coreutils.spec index 3f0c69a..3774910 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.5 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -64,7 +64,7 @@ Patch912: coreutils-overflow.patch Patch915: coreutils-split-pam.patch #prevent koji build failure with wrong getfacl exit code Patch916: coreutils-getfacl-exit-code.patch -#compile su with pie flag +#compile su with pie flag and RELRO protection Patch917: coreutils-8.4-su-pie.patch #SELINUX Patch - implements Redhat changes @@ -344,6 +344,9 @@ fi %{_libdir}/coreutils %changelog +* Wed Sep 09 2010 Ondrej Vasik - 8.5-7 +- add RELRO protection to su as well (#630017) + * Mon Sep 06 2010 Ondrej Vasik - 8.5-6 - compile su with pie again (#630017) From a921d1b238a341c5196e2a726e106892fbc6402f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 20 Sep 2010 13:19:42 +0200 Subject: [PATCH 106/523] change assertion failure for invalid multibyte input in sort to less confusing error message(#591352) --- coreutils-i18n.patch | 5 +++-- coreutils.spec | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index d6e6c46..9bd30c6 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2932,7 +2932,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2062,11 +2390,79 @@ compare_version (char *restrict texta, s +@@ -2062,11 +2390,80 @@ compare_version (char *restrict texta, s return diff; } @@ -2969,7 +2969,8 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c + memset (&state, '\0', sizeof(mbstate_t)); + + wclength = mbsrtowcs (month_wcs, pp, len + 1, &state); -+ assert (wclength != (size_t)-1 && *pp == NULL); ++ if (wclength == (size_t)-1 || *pp != NULL) ++ error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s)); + + for (i = 0; i < wclength; i++) + { diff --git a/coreutils.spec b/coreutils.spec index 3774910..79fc848 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.5 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -344,6 +344,10 @@ fi %{_libdir}/coreutils %changelog +* Mon Sep 20 2010 Ondrej Vasik - 8.5-8 +- change assertion failure for invalid multibyte input + in sort to less confusing error message(#591352) + * Wed Sep 09 2010 Ondrej Vasik - 8.5-7 - add RELRO protection to su as well (#630017) From eacfb88d2c288c6b6b625e347c2f2fe771b558e7 Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Wed, 29 Sep 2010 14:03:39 -0700 Subject: [PATCH 107/523] - Rebuilt for gcc bug 634757 --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 79fc848..cc92fa7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.5 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -344,6 +344,9 @@ fi %{_libdir}/coreutils %changelog +* Wed Sep 29 2010 jkeating - 8.5-9 +- Rebuilt for gcc bug 634757 + * Mon Sep 20 2010 Ondrej Vasik - 8.5-8 - change assertion failure for invalid multibyte input in sort to less confusing error message(#591352) From 0a5116219c371d29b78c0ad59a8359d47c57f564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 30 Sep 2010 17:43:34 +0200 Subject: [PATCH 108/523] various fixes in tr case conversion --- coreutils-8.5-trcaseconversion.patch | 431 +++++++++++++++++++++++++++ coreutils.spec | 9 +- 2 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.5-trcaseconversion.patch diff --git a/coreutils-8.5-trcaseconversion.patch b/coreutils-8.5-trcaseconversion.patch new file mode 100644 index 0000000..6cd66ba --- /dev/null +++ b/coreutils-8.5-trcaseconversion.patch @@ -0,0 +1,431 @@ +From: Pádraig Brady +Date: Mon, 27 Sep 2010 06:16:44 +0000 (+0100) +Subject: tr: fix various issues with case conversion +X-Git-Url: http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff_plain;h=3f48829c;hp=704eedab034e24814067c535d3577f165c9a8b68 + +tr: fix various issues with case conversion + +This valid translation spec aborted: + LC_ALL=en_US.iso-8859-1 tr '[:upper:]- ' '[:lower:]_' +This invalid translation spec aborted: + LC_ALL=en_US.iso-8859-1 tr '[:upper:] ' '[:lower:]' +This was caused by commit 6efd1046, 05-01-2008, +"Avoid tr case-conversion failure in some locales" + +This misaligned conversion spec was allowed: + LC_ALL=C tr 'A-Y[:lower:]' 'a-z[:upper:]' +This was caused by commit af5d0c36, 21-10-2007, +"tr: do not reject an unmatched [:lower:] or [:upper:] in SET1" + +This misaligned spec was allowed by extending the class: + LC_ALL=C tr '[:upper:] ' '[:lower:]' + +* src/tr.c (validate_case_classes): A new function to check +alignment of case conversion classes. Also it adjusts the +length of the sets so that locales with different numbers of +upper and lower case characters, don't cause issues. +(string2_extend): Disallow extending the case conversion +class as in the above example. That is locale dependent +and most likely not what the user wants. +(validate): Do the simple test for "restricted" char classes +earlier, so we don't redundantly do more expensive validation. +(main): Remove the case class validation, and simplify. +* tests/misc/tr-case-class: A new test to test the various +alignment and locale issues, associated with case conversion. +* tests/misc/tr: Move case conversion tests to new tr-case-class. +* tests/Makefile.am: Reference the new test. +--- + +diff --git a/src/tr.c b/src/tr.c +index a5b6810..479d3d3 100644 +--- a/src/tr.c ++++ b/src/tr.c +@@ -1177,6 +1177,78 @@ card_of_complement (struct Spec_list *s) + return cardinality; + } + ++/* Discard the lengths associated with a case conversion, ++ as using the actual number of upper or lower case characters ++ is problematic when they don't match in some locales. ++ Also ensure the case conversion classes in string2 are ++ aligned correctly with those in string1. ++ Note POSIX says the behavior of `tr "[:upper:]" "[:upper:]"' ++ is undefined. Therefore we allow it (unlike Solaris) ++ and treat it as a no-op. */ ++ ++static void ++validate_case_classes (struct Spec_list *s1, struct Spec_list *s2) ++{ ++ size_t n_upper = 0; ++ size_t n_lower = 0; ++ unsigned int i; ++ int c1 = 0; ++ int c2 = 0; ++ count old_s1_len = s1->length; ++ count old_s2_len = s2->length; ++ struct List_element *s1_tail = s1->tail; ++ struct List_element *s2_tail = s2->tail; ++ bool s1_new_element = true; ++ bool s2_new_element = true; ++ ++ if (!s2->has_char_class) ++ return; ++ ++ for (i = 0; i < N_CHARS; i++) ++ { ++ if (isupper (i)) ++ n_upper++; ++ if (islower (i)) ++ n_lower++; ++ } ++ ++ s1->state = BEGIN_STATE; ++ s2->state = BEGIN_STATE; ++ ++ while (c1 != -1 && c2 != -1) ++ { ++ enum Upper_Lower_class class_s1, class_s2; ++ ++ c1 = get_next (s1, &class_s1); ++ c2 = get_next (s2, &class_s2); ++ ++ /* If c2 transitions to a new case class, then ++ c1 must also transition at the same time. */ ++ if (s2_new_element && class_s2 != UL_NONE ++ && !(s1_new_element && class_s1 != UL_NONE)) ++ error (EXIT_FAILURE, 0, ++ _("misaligned [:upper:] and/or [:lower:] construct")); ++ ++ /* If case converting, quickly skip over the elements. */ ++ if (class_s2 != UL_NONE) ++ { ++ skip_construct (s1); ++ skip_construct (s2); ++ /* Discount insignificant/problematic lengths. */ ++ s1->length -= (class_s1 == UL_UPPER ? n_upper : n_lower) - 1; ++ s2->length -= (class_s2 == UL_UPPER ? n_upper : n_lower) - 1; ++ } ++ ++ s1_new_element = s1->state == NEW_ELEMENT; /* Next element is new. */ ++ s2_new_element = s2->state == NEW_ELEMENT; /* Next element is new. */ ++ } ++ ++ assert (old_s1_len >= s1->length && old_s2_len >= s2->length); ++ ++ s1->tail = s1_tail; ++ s2->tail = s2_tail; ++} ++ + /* Gather statistics about the spec-list S in preparation for the tests + in validate that determine the consistency of the specs. This function + is called at most twice; once for string1, and again for any string2. +@@ -1318,20 +1390,14 @@ parse_str (char const *s, struct Spec_list *spec_list) + Upon successful completion, S2->length is set to S1->length. The only + way this function can fail to make S2 as long as S1 is when S2 has + zero-length, since in that case, there is no last character to repeat. +- So S2->length is required to be at least 1. ++ So S2->length is required to be at least 1. */ + +- Providing this functionality allows the user to do some pretty +- non-BSD (and non-portable) things: For example, the command +- tr -cs '[:upper:]0-9' '[:lower:]' +- is almost guaranteed to give results that depend on your collating +- sequence. */ + + static void + string2_extend (const struct Spec_list *s1, struct Spec_list *s2) + { + struct List_element *p; + unsigned char char_to_repeat; +- int i; + + assert (translating); + assert (s1->length > s2->length); +@@ -1347,11 +1413,13 @@ string2_extend (const struct Spec_list *s1, struct Spec_list *s2) + char_to_repeat = p->u.range.last_char; + break; + case RE_CHAR_CLASS: +- for (i = N_CHARS - 1; i >= 0; i--) +- if (is_char_class_member (p->u.char_class, i)) +- break; +- assert (i >= 0); +- char_to_repeat = i; ++ /* Note BSD allows extending of classes in string2. For example: ++ tr '[:upper:]0-9' '[:lower:]' ++ That's not portable however, contradicts POSIX and is dependent ++ on your collating sequence. */ ++ error (EXIT_FAILURE, 0, ++ _("when translating with string1 longer than string2,\n\ ++the latter string must not end with a character class")); + break; + + case RE_REPEATED_CHAR: +@@ -1431,6 +1499,15 @@ validate (struct Spec_list *s1, struct Spec_list *s2) + when translating")); + } + ++ if (s2->has_restricted_char_class) ++ { ++ error (EXIT_FAILURE, 0, ++ _("when translating, the only character classes that may \ ++appear in\nstring2 are `upper' and `lower'")); ++ } ++ ++ validate_case_classes (s1, s2); ++ + if (s1->length > s2->length) + { + if (!truncate_set1) +@@ -1452,13 +1529,6 @@ when translating")); + _("when translating with complemented character classes,\ + \nstring2 must map all characters in the domain to one")); + } +- +- if (s2->has_restricted_char_class) +- { +- error (EXIT_FAILURE, 0, +- _("when translating, the only character classes that may \ +-appear in\nstring2 are `upper' and `lower'")); +- } + } + else + /* Not translating. */ +@@ -1812,7 +1882,6 @@ main (int argc, char **argv) + { + int c1, c2; + int i; +- bool case_convert = false; + enum Upper_Lower_class class_s1; + enum Upper_Lower_class class_s2; + +@@ -1822,47 +1891,21 @@ main (int argc, char **argv) + s2->state = BEGIN_STATE; + while (true) + { +- /* When the previous pair identified case-converting classes, +- advance S1 and S2 so that each points to the following +- construct. */ +- if (case_convert) +- { +- skip_construct (s1); +- skip_construct (s2); +- case_convert = false; +- } +- + c1 = get_next (s1, &class_s1); + c2 = get_next (s2, &class_s2); + +- /* When translating and there is an [:upper:] or [:lower:] +- class in SET2, then there must be a corresponding [:lower:] +- or [:upper:] class in SET1. */ +- if (class_s1 == UL_NONE +- && (class_s2 == UL_LOWER || class_s2 == UL_UPPER)) +- error (EXIT_FAILURE, 0, +- _("misaligned [:upper:] and/or [:lower:] construct")); +- + if (class_s1 == UL_LOWER && class_s2 == UL_UPPER) + { +- case_convert = true; + for (i = 0; i < N_CHARS; i++) + if (islower (i)) + xlate[i] = toupper (i); + } + else if (class_s1 == UL_UPPER && class_s2 == UL_LOWER) + { +- case_convert = true; + for (i = 0; i < N_CHARS; i++) + if (isupper (i)) + xlate[i] = tolower (i); + } +- else if ((class_s1 == UL_LOWER && class_s2 == UL_LOWER) +- || (class_s1 == UL_UPPER && class_s2 == UL_UPPER)) +- { +- /* POSIX says the behavior of `tr "[:upper:]" "[:upper:]"' +- is undefined. Treat it as a no-op. */ +- } + else + { + /* The following should have been checked by validate... */ +@@ -1870,6 +1913,13 @@ main (int argc, char **argv) + break; + xlate[c1] = c2; + } ++ ++ /* When case-converting, skip the elements as an optimization. */ ++ if (class_s2 != UL_NONE) ++ { ++ skip_construct (s1); ++ skip_construct (s2); ++ } + } + assert (c1 == -1 || truncate_set1); + } +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 5619d0b..3236637 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -260,6 +260,7 @@ TESTS = \ + misc/timeout \ + misc/timeout-parameters \ + misc/tr \ ++ misc/tr-case-class \ + misc/truncate-dangling-symlink \ + misc/truncate-dir-fail \ + misc/truncate-fail-diag \ +diff --git a/tests/misc/tr b/tests/misc/tr +index ca7a960..00cd8e6 100755 +--- a/tests/misc/tr ++++ b/tests/misc/tr +@@ -155,34 +155,8 @@ my @Tests = + + # Up to coreutils-6.9, this would provoke a failed assertion. + ['no-abort-1', qw(-c a '[b*256]'), {IN=>'abc'}, {OUT=>'abb'}], +- +- # Up to coreutils-6.9, tr rejected an unmatched [:lower:] or [:upper:] in SET1. +- ['s1-lower', qw('[:lower:]' '[.*]'), +- {IN=>'#$%123abcABC'}, {OUT=>'#$%123...ABC'}], +- ['s1-upper', qw('[:upper:]' '[.*]'), +- {IN=>'#$%123abcABC'}, {OUT=>'#$%123abc...'}], +- +- # Up to coreutils-6.9.91, this would fail with the diagnostic: +- # tr: misaligned [:upper:] and/or [:lower:] construct +- # with LC_CTYPE=en_US.ISO-8859-1. +- ['tolower-F', qw('[:upper:]' '[:lower:]'), {IN=>'A'}, {OUT=>'a'}], +- +- # When doing a case-converting translation with something after the +- # [:upper:] and [:lower:] elements, ensure that tr honors the following byte. +- ['upcase-xtra', qw('[:lower:].' '[:upper:]x'), {IN=>'abc.'}, {OUT=>'ABCx'}], +- ['dncase-xtra', qw('[:upper:].' '[:lower:]x'), {IN=>'ABC.'}, {OUT=>'abcx'}], + ); + +-# Set LC_CTYPE=en_US.ISO-8859-1 in the environment of the tolower-F test. +-foreach my $t (@Tests) +- { +- if ($t->[0] eq 'tolower-F') +- { +- push @$t, {ENV=>'LC_CTYPE=en_US.ISO-8859-1'}; +- last; +- } +- } +- + @Tests = triple_test \@Tests; + + # tr takes its input only from stdin, not from a file argument, so +diff --git a/tests/misc/tr-case-class b/tests/misc/tr-case-class +new file mode 100755 +index 0000000..d81c676 +--- /dev/null ++++ b/tests/misc/tr-case-class +@@ -0,0 +1,112 @@ ++#!/bin/sh ++# Test case conversion classes ++ ++# Copyright (C) 2010 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/test-lib.sh ++ ++# Ensure we support translation of case classes with extension ++echo '01234567899999999999999999' > exp ++echo 'abcdefghijklmnopqrstuvwxyz' | ++tr '[:lower:]' '0-9' > out || fail=1 ++compare out exp || fail=1 ++echo 'abcdefghijklmnopqrstuvwxyz' | ++tr '[:lower:][:lower:]' '[:upper:]0-9' > out || fail=1 ++compare out exp || fail=1 ++ ++# Validate the alignment of case classes ++tr 'A-Z[:lower:]' 'a-y[:upper:]' < /dev/null && fail=1 ++tr '[:upper:][:lower:]' 'a-y[:upper:]' < /dev/null && fail=1 ++tr 'A-Y[:lower:]' 'a-z[:upper:]' < /dev/null && fail=1 ++tr 'A-Z[:lower:]' '[:lower:][:upper:]' < /dev/null && fail=1 ++tr 'A-Z[:lower:]' '[:lower:]A-Z' < /dev/null && fail=1 ++tr '[:upper:][:lower:]' 'a-z[:upper:]' < /dev/null || fail=1 ++tr '[:upper:][:lower:]' '[:upper:]a-z' < /dev/null || fail=1 ++ ++# Before coreutils 8.6 the trailing space in string1 ++# caused the case class in string2 to be extended. ++# However that was not portable, dependent on locale ++# and in contravention of POSIX. ++tr '[:upper:] ' '[:lower:]' < /dev/null 2>out && fail=1 ++echo 'tr: when translating with string1 longer than string2, ++the latter string must not end with a character class' > exp ++compare out exp || fail=1 ++ ++# Up to coreutils-6.9, tr rejected an unmatched [:lower:] or [:upper:] in SET1. ++echo '#$%123abcABC' | tr '[:lower:]' '[.*]' > out || fail=1 ++echo '#$%123...ABC' > exp ++compare out exp || fail=1 ++echo '#$%123abcABC' | tr '[:upper:]' '[.*]' > out || fail=1 ++echo '#$%123abc...' > exp ++compare out exp || fail=1 ++ ++# When doing a case-converting translation with something after the ++# [:upper:] and [:lower:] elements, ensure that tr honors the following byte. ++echo 'abc.' | tr '[:lower:].' '[:upper:]x' > out || fail=1 ++echo 'ABCx' > exp ++compare out exp || fail=1 ++ ++# Before coreutils 8.6 the disparate number of upper and lower ++# characters in some locales, triggered abort()s and invalid behavior ++export LC_ALL=en_US.ISO-8859-1 ++ ++if test "$(locale charmap 2>/dev/null)" = ISO-8859-1; then ++ # Up to coreutils-6.9.91, this would fail with the diagnostic: ++ # tr: misaligned [:upper:] and/or [:lower:] construct ++ # with LC_CTYPE=en_US.ISO-8859-1. ++ tr '[:upper:]' '[:lower:]' < /dev/null || fail=1 ++ ++ tr '[:upper:] ' '[:lower:]' < /dev/null 2>out && fail=1 ++ echo 'tr: when translating with string1 longer than string2, ++the latter string must not end with a character class' > exp ++ compare out exp || fail=1 ++ ++ # Ensure when there are a different number of elements ++ # in each string, we validate the case mapping correctly ++ echo 'abc.xyz' | ++ tr 'ab[:lower:]' '0-1[:upper:]' > out || fail=1 ++ echo 'ABC.XYZ' > exp ++ compare out exp || fail=1 ++ ++ # Ensure we extend string2 appropriately ++ echo 'ABC- XYZ' | ++ tr '[:upper:]- ' '[:lower:]_' > out || fail=1 ++ echo 'abc__xyz' > exp ++ compare out exp || fail=1 ++ ++ # Ensure the size of the case classes are accounted ++ # for as a unit. ++ echo 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | ++ tr '[:upper:]A-B' '[:lower:]0' >out || fail=1 ++ echo '00cdefghijklmnopqrstuvwxyz' > exp ++ compare out exp || fail=1 ++ ++ # Ensure the size of the case classes are accounted ++ # for as a unit. ++ echo 'a' | ++ tr -t '[:lower:]a' '[:upper:]0' >out || fail=1 ++ echo '0' > exp ++ compare out exp || fail=1 ++ ++ # Ensure the size of the case classes are accounted ++ # for as a unit. ++ echo 'a' | ++ tr -t '[:lower:][:lower:]a' '[:lower:][:upper:]0' >out || fail=1 ++ echo '0' > exp ++ compare out exp || fail=1 ++fi ++ ++Exit $fail diff --git a/coreutils.spec b/coreutils.spec index cc92fa7..af90919 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.5 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -20,6 +20,8 @@ Source203: coreutils-runuser-l.pamd # From upstream #fix double free error in tac (reported in debian bug #594666) Patch1: coreutils-8.5-tac-doublefree.patch +#fix various case conversion issues in tr(#611274) +Patch2: coreutils-8.5-trcaseconversion.patch # Our patches #general patch to workaround koji build system issues @@ -126,6 +128,7 @@ Libraries for coreutils package. # From upstream %patch1 -p1 -b .doublefree +%patch2 -p1 -b .caseconvert # Our patches %patch100 -p1 -b .configure @@ -158,6 +161,7 @@ Libraries for coreutils package. %patch951 -p1 -b .selinuxman chmod a+x tests/misc/sort-mb-tests tests/df/direct +chmod a+x tests/misc/tr-case-class #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -344,6 +348,9 @@ fi %{_libdir}/coreutils %changelog +* Thu Sep 30 2010 Ondrej Vasik - 8.5-10 +- various fixes for case conversion in tr(#611274) + * Wed Sep 29 2010 jkeating - 8.5-9 - Rebuilt for gcc bug 634757 From 801235770d826ef63ba287ece74e71991238f91c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 1 Oct 2010 09:57:26 +0200 Subject: [PATCH 109/523] defuzz the patch --- coreutils-8.5-trcaseconversion.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-8.5-trcaseconversion.patch b/coreutils-8.5-trcaseconversion.patch index 6cd66ba..8fb1a07 100644 --- a/coreutils-8.5-trcaseconversion.patch +++ b/coreutils-8.5-trcaseconversion.patch @@ -200,7 +200,7 @@ index a5b6810..479d3d3 100644 @@ -1822,47 +1891,21 @@ main (int argc, char **argv) s2->state = BEGIN_STATE; - while (true) + for (;;) { - /* When the previous pair identified case-converting classes, - advance S1 and S2 so that each points to the following From 98ff9fee21c1fd1614361b50cc467371957fa0fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 20 Oct 2010 14:03:53 +0200 Subject: [PATCH 110/523] new upstream release 8.6 --- .gitignore | 1 + coreutils-4.5.3-langinfo.patch | 2 +- coreutils-6.10-configuration.patch | 2 +- coreutils-df-direct.patch | 6 +- coreutils-getfacl-exit-code.patch | 23 -- coreutils-i18n.patch | 459 +++++++++++++++++------------ coreutils-pam.patch | 2 +- coreutils-selinux.patch | 339 ++++++--------------- coreutils.spec | 24 +- sources | 2 +- 10 files changed, 378 insertions(+), 482 deletions(-) delete mode 100644 coreutils-getfacl-exit-code.patch diff --git a/.gitignore b/.gitignore index adf3112..fae4898 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ coreutils-8.5.tar.xz +/coreutils-8.6.tar.xz diff --git a/coreutils-4.5.3-langinfo.patch b/coreutils-4.5.3-langinfo.patch index a45dcb3..25dec6c 100644 --- a/coreutils-4.5.3-langinfo.patch +++ b/coreutils-4.5.3-langinfo.patch @@ -5,7 +5,7 @@ if (! *format) { - /* Do not wrap the following literal format string with _(...). -- For example, suppose LC_ALL is unset, LC_TIME="POSIX", +- For example, suppose LC_ALL is unset, LC_TIME=POSIX, - and LANG="ko_KR". In that case, POSIX says that LC_TIME - determines the format and contents of date and time strings - written by date, which means "date" must generate output diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 7d165b9..4f52076 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -93,8 +93,8 @@ diff -urNp coreutils-8.4-orig/tests/Makefile.am coreutils-8.4/tests/Makefile.am cp/link-heap \ - tail-2/inotify-hash-abuse \ tail-2/inotify-hash-abuse2 \ + tail-2/F-vs-missing \ tail-2/F-vs-rename \ - tail-2/inotify-rotate \ diff -urNp coreutils-8.4-orig/tests/touch/no-dereference coreutils-8.4/tests/touch/no-dereference --- coreutils-8.4-orig/tests/touch/no-dereference 2010-01-12 15:36:17.000000000 +0100 +++ coreutils-8.4/tests/touch/no-dereference 2010-01-14 10:28:17.000000000 +0100 diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 380f1b1..24d0057 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -78,9 +78,9 @@ index b862879..a74c353 100644 && show_disk (name)) return; @@ -820,6 +839,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\ - fputs (_("\ - -a, --all include dummy file systems\n\ - -B, --block-size=SIZE use SIZE-byte blocks\n\ + -B, --block-size=SIZE scale sizes by SIZE before printing them. E.g.,\n\ + `-BM' prints sizes in units of 1,048,576 bytes.\n\ + See SIZE format below.\n\ + --direct show statistics for a file instead of mount point\n\ --total produce a grand total\n\ -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\n\ diff --git a/coreutils-getfacl-exit-code.patch b/coreutils-getfacl-exit-code.patch deleted file mode 100644 index 5a04525..0000000 --- a/coreutils-getfacl-exit-code.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- coreutils-6.8+/tests/cp/acl.getfacl-exit-code 2007-03-01 16:48:29.000000000 +0000 -+++ coreutils-6.8+/tests/cp/acl 2007-03-01 16:49:35.000000000 +0000 -@@ -70,16 +70,16 @@ - # copy a file without preserving permissions - cp a/file b/ || fail=1 - --acl2=`cd b && getfacl file` || framework_failure -+acl2=`cd b && getfacl file` - test "$acl1" = "$acl2" || fail=1 - rm a/file || framework_failure - - # copy a file, preserving permissions - touch a/file || framework_failure --setfacl -m user:bin:rw a/file || framework_failure --acl1=`cd a && getfacl file` || framework_failure -+setfacl -m user:bin:rw a/file -+acl1=`cd a && getfacl file` - cp -p a/file b/ || fail=1 --acl2=`cd b && getfacl file` || framework_failure -+acl2=`cd b && getfacl file` - test "$acl1" = "$acl2" || fail=1 - - Exit $fail diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 9bd30c6..89dde2c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.5-orig/lib/linebuffer.h coreutils-8.5/lib/linebuffer.h ---- coreutils-8.5-orig/lib/linebuffer.h 2010-04-23 15:44:00.000000000 +0200 -+++ coreutils-8.5/lib/linebuffer.h 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/lib/linebuffer.h coreutils-8.6/lib/linebuffer.h +--- coreutils-8.6-orig/lib/linebuffer.h 2010-06-10 18:45:26.000000000 +0200 ++++ coreutils-8.6/lib/linebuffer.h 2010-10-18 15:18:11.932209034 +0200 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.5-orig/lib/linebuffer.h coreutils-8.5/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c ---- coreutils-8.5-orig/src/cut.c 2010-04-20 21:52:04.000000000 +0200 -+++ coreutils-8.5/src/cut.c 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/src/cut.c coreutils-8.6/src/cut.c +--- coreutils-8.6-orig/src/cut.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/cut.c 2010-10-18 15:18:11.933208545 +0200 @@ -28,6 +28,11 @@ #include #include @@ -38,7 +38,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c #include "system.h" #include "error.h" -@@ -36,6 +41,18 @@ +@@ -37,6 +42,18 @@ #include "quote.h" #include "xstrndup.h" @@ -57,7 +57,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "cut" -@@ -71,6 +88,52 @@ +@@ -72,6 +89,52 @@ } \ while (0) @@ -110,7 +110,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c struct range_pair { size_t lo; -@@ -89,7 +152,7 @@ static char *field_1_buffer; +@@ -90,7 +153,7 @@ static char *field_1_buffer; /* The number of bytes allocated for FIELD_1_BUFFER. */ static size_t field_1_bufsize; @@ -119,7 +119,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c or degenerate range specification; this doesn't include the starting index of right-open-ended ranges. For example, with either range spec `2-5,9-', `2-3,5,9-' this variable would be set to 5. */ -@@ -101,10 +164,11 @@ static size_t eol_range_start; +@@ -102,10 +165,11 @@ static size_t eol_range_start; /* This is a bit vector. In byte mode, which bytes to output. @@ -133,7 +133,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c (K <= MAX_RANGE_ENDPOINT and is_printable_field(K)) || (EOL_RANGE_START > 0 && K >= EOL_RANGE_START). */ static unsigned char *printable_field; -@@ -113,15 +177,25 @@ enum operating_mode +@@ -114,15 +178,25 @@ enum operating_mode { undefined_mode, @@ -160,7 +160,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c /* If true do not output lines containing no delimeter characters. Otherwise, all such lines are printed. This option is valid only with field mode. */ -@@ -133,6 +207,9 @@ static bool complement; +@@ -134,6 +208,9 @@ static bool complement; /* The delimeter character for field mode. */ static unsigned char delim; @@ -170,7 +170,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -206,7 +283,7 @@ Mandatory arguments to long options are +@@ -207,7 +284,7 @@ Mandatory arguments to long options are -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\ @@ -179,7 +179,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -365,7 +442,7 @@ set_fields (const char *fieldstr) +@@ -366,7 +443,7 @@ set_fields (const char *fieldstr) in_digits = false; /* Starting a range. */ if (dash_found) @@ -188,7 +188,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c dash_found = true; fieldstr++; -@@ -389,14 +466,16 @@ set_fields (const char *fieldstr) +@@ -390,14 +467,16 @@ set_fields (const char *fieldstr) if (!rhs_specified) { /* `n-'. From `initial' to end of line. */ @@ -207,7 +207,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c /* Is there already a range going to end of line? */ if (eol_range_start != 0) -@@ -476,6 +555,9 @@ set_fields (const char *fieldstr) +@@ -477,6 +556,9 @@ set_fields (const char *fieldstr) if (operating_mode == byte_mode) error (0, 0, _("byte offset %s is too large"), quote (bad_num)); @@ -217,7 +217,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c else error (0, 0, _("field number %s is too large"), quote (bad_num)); -@@ -486,7 +568,7 @@ set_fields (const char *fieldstr) +@@ -487,7 +569,7 @@ set_fields (const char *fieldstr) fieldstr++; } else @@ -226,7 +226,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c } max_range_endpoint = 0; -@@ -579,6 +661,63 @@ cut_bytes (FILE *stream) +@@ -580,6 +662,63 @@ cut_bytes (FILE *stream) } } @@ -290,7 +290,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -701,13 +840,192 @@ cut_fields (FILE *stream) +@@ -702,13 +841,192 @@ cut_fields (FILE *stream) } } @@ -486,16 +486,16 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c } /* Process file FILE to standard output. -@@ -757,6 +1075,8 @@ main (int argc, char **argv) +@@ -760,6 +1078,8 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; - char *spec_list_string IF_LINT (= NULL); + char *spec_list_string IF_LINT ( = NULL); + char mbdelim[MB_LEN_MAX + 1]; + size_t delimlen = 0; initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -779,7 +1099,6 @@ main (int argc, char **argv) +@@ -782,7 +1102,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -503,7 +503,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -787,6 +1106,14 @@ main (int argc, char **argv) +@@ -790,6 +1109,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -518,7 +518,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -798,10 +1125,35 @@ main (int argc, char **argv) +@@ -801,10 +1128,35 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean `use the NUL byte as the delimiter.' */ @@ -558,7 +558,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -814,6 +1166,7 @@ main (int argc, char **argv) +@@ -817,6 +1169,7 @@ main (int argc, char **argv) break; case 'n': @@ -566,7 +566,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c break; case 's': -@@ -836,7 +1189,7 @@ main (int argc, char **argv) +@@ -839,7 +1192,7 @@ main (int argc, char **argv) if (operating_mode == undefined_mode) FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); @@ -575,7 +575,7 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c FATAL_ERROR (_("an input delimiter may be specified only\ when operating on fields")); -@@ -863,15 +1216,34 @@ main (int argc, char **argv) +@@ -866,15 +1219,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -616,10 +616,10 @@ diff -urNp coreutils-8.5-orig/src/cut.c coreutils-8.5/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.5-orig/src/expand.c coreutils-8.5/src/expand.c ---- coreutils-8.5-orig/src/expand.c 2010-01-01 14:06:47.000000000 +0100 -+++ coreutils-8.5/src/expand.c 2010-04-26 14:24:33.000000000 +0200 -@@ -38,11 +38,28 @@ +diff -urNp coreutils-8.6-orig/src/expand.c coreutils-8.6/src/expand.c +--- coreutils-8.6-orig/src/expand.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/expand.c 2010-10-18 15:18:11.937209243 +0200 +@@ -38,12 +38,29 @@ #include #include #include @@ -631,6 +631,7 @@ diff -urNp coreutils-8.5-orig/src/expand.c coreutils-8.5/src/expand.c + #include "system.h" #include "error.h" + #include "fadvise.h" #include "quote.h" #include "xstrndup.h" @@ -648,7 +649,7 @@ diff -urNp coreutils-8.5-orig/src/expand.c coreutils-8.5/src/expand.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "expand" -@@ -358,6 +375,142 @@ expand (void) +@@ -360,6 +377,142 @@ expand (void) } } @@ -791,7 +792,7 @@ diff -urNp coreutils-8.5-orig/src/expand.c coreutils-8.5/src/expand.c int main (int argc, char **argv) { -@@ -422,7 +575,12 @@ main (int argc, char **argv) +@@ -424,7 +577,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -805,10 +806,10 @@ diff -urNp coreutils-8.5-orig/src/expand.c coreutils-8.5/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c ---- coreutils-8.5-orig/src/fold.c 2010-01-01 14:06:47.000000000 +0100 -+++ coreutils-8.5/src/fold.c 2010-04-26 14:24:33.000000000 +0200 -@@ -22,11 +22,33 @@ +diff -urNp coreutils-8.6-orig/src/fold.c coreutils-8.6/src/fold.c +--- coreutils-8.6-orig/src/fold.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/fold.c 2010-10-18 15:18:11.938208475 +0200 +@@ -22,12 +22,34 @@ #include #include @@ -824,6 +825,7 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c + #include "system.h" #include "error.h" + #include "fadvise.h" #include "quote.h" #include "xstrtol.h" @@ -842,7 +844,7 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c #define TAB_WIDTH 8 /* The official name of this program (e.g., no `g' prefix). */ -@@ -34,20 +56,41 @@ +@@ -35,20 +57,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -888,7 +890,7 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c {"spaces", no_argument, NULL, 's'}, {"width", required_argument, NULL, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -77,6 +120,7 @@ Mandatory arguments to long options are +@@ -78,6 +121,7 @@ Mandatory arguments to long options are "), stdout); fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -896,7 +898,7 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -94,7 +138,7 @@ Mandatory arguments to long options are +@@ -95,7 +139,7 @@ Mandatory arguments to long options are static size_t adjust_column (size_t column, char c) { @@ -905,7 +907,7 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c { if (c == '\b') { -@@ -117,30 +161,14 @@ adjust_column (size_t column, char c) +@@ -118,30 +162,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -936,9 +938,9 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c - return false; - } - while ((c = getc (istream)) != EOF) - { -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t + fadvise (stdin, FADVISE_SEQUENTIAL); + +@@ -171,6 +199,15 @@ fold_file (char const *filename, size_t bool found_blank = false; size_t logical_end = offset_out; @@ -954,7 +956,7 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -214,11 +251,222 @@ fold_file (char const *filename, size_t +@@ -217,11 +254,222 @@ fold_file (char const *filename, size_t line_out[offset_out++] = c; } @@ -1178,7 +1180,7 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c if (ferror (istream)) { error (0, saved_errno, "%s", filename); -@@ -251,7 +499,8 @@ main (int argc, char **argv) +@@ -254,7 +502,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1188,7 +1190,7 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -260,7 +509,15 @@ main (int argc, char **argv) +@@ -263,7 +512,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1205,10 +1207,10 @@ diff -urNp coreutils-8.5-orig/src/fold.c coreutils-8.5/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c ---- coreutils-8.5-orig/src/join.c 2010-04-20 21:52:04.000000000 +0200 -+++ coreutils-8.5/src/join.c 2010-04-26 14:24:33.000000000 +0200 -@@ -22,17 +22,31 @@ +diff -urNp coreutils-8.6-orig/src/join.c coreutils-8.6/src/join.c +--- coreutils-8.6-orig/src/join.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/join.c 2010-10-18 15:18:11.940208824 +0200 +@@ -22,18 +22,32 @@ #include #include @@ -1224,6 +1226,7 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c + #include "system.h" #include "error.h" + #include "fadvise.h" #include "hard-locale.h" #include "linebuffer.h" -#include "memcasecmp.h" @@ -1241,7 +1244,7 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "join" -@@ -121,10 +135,12 @@ static struct outlist outlist_head; +@@ -122,10 +136,12 @@ static struct outlist outlist_head; /* Last element in `outlist', where a new element can be added. */ static struct outlist *outlist_end = &outlist_head; @@ -1258,11 +1261,11 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -248,10 +264,11 @@ xfields (struct line *line) +@@ -249,13 +265,14 @@ xfields (struct line *line) if (ptr == lim) return; -- if (0 <= tab) +- if (0 <= tab && tab != '\n') + if (tab != NULL) { + unsigned char t = tab[0]; @@ -1271,8 +1274,12 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c + for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) extract_field (line, ptr, sep - ptr); } - else -@@ -278,6 +295,148 @@ xfields (struct line *line) +- else if (tab < 0) ++ else + { + /* Skip leading blanks before the first field. */ + while (isblank (to_uchar (*ptr))) +@@ -279,6 +296,148 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1421,7 +1428,7 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c static void freeline (struct line *line) { -@@ -299,56 +458,115 @@ keycmp (struct line const *line1, struct +@@ -300,56 +459,115 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1560,7 +1567,7 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -429,6 +647,11 @@ get_line (FILE *fp, struct line **linep, +@@ -430,6 +648,11 @@ get_line (FILE *fp, struct line **linep, return false; } @@ -1572,7 +1579,7 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c xfields (line); if (prevline[which - 1]) -@@ -528,11 +751,18 @@ prfield (size_t n, struct line const *li +@@ -529,11 +752,18 @@ prfield (size_t n, struct line const *li /* Print the join of LINE1 and LINE2. */ @@ -1592,7 +1599,7 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c outlist = outlist_head.next; if (outlist) -@@ -567,7 +797,7 @@ prjoin (struct line const *line1, struct +@@ -568,7 +798,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1601,7 +1608,7 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c } putchar ('\n'); } -@@ -585,23 +815,23 @@ prjoin (struct line const *line1, struct +@@ -586,23 +816,23 @@ prjoin (struct line const *line1, struct prfield (join_field_1, line1); for (i = 0; i < join_field_1 && i < line1->nfields; ++i) { @@ -1629,7 +1636,7 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c prfield (i, line2); } putchar ('\n'); -@@ -1039,21 +1269,46 @@ main (int argc, char **argv) +@@ -1043,21 +1273,46 @@ main (int argc, char **argv) case 't': { @@ -1685,9 +1692,9 @@ diff -urNp coreutils-8.5-orig/src/join.c coreutils-8.5/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c ---- coreutils-8.5-orig/src/pr.c 2010-03-13 16:14:09.000000000 +0100 -+++ coreutils-8.5/src/pr.c 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/src/pr.c coreutils-8.6/src/pr.c +--- coreutils-8.6-orig/src/pr.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/pr.c 2010-10-18 15:18:11.942208964 +0200 @@ -312,6 +312,32 @@ #include @@ -1720,8 +1727,8 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c + #include "system.h" #include "error.h" - #include "hard-locale.h" -@@ -322,6 +348,18 @@ + #include "fadvise.h" +@@ -323,6 +349,18 @@ #include "strftime.h" #include "xstrtol.h" @@ -1740,7 +1747,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "pr" -@@ -414,7 +452,20 @@ struct COLUMN +@@ -415,7 +453,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -1762,7 +1769,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -424,6 +475,7 @@ static void print_header (void); +@@ -425,6 +476,7 @@ static void print_header (void); static void pad_across_to (int position); static void add_line_number (COLUMN *p); static void getoptarg (char *arg, char switch_char, char *character, @@ -1770,7 +1777,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c int *number); void usage (int status); static void print_files (int number_of_files, char **av); -@@ -438,7 +490,6 @@ static void store_char (char c); +@@ -439,7 +491,6 @@ static void store_char (char c); static void pad_down (int lines); static void read_rest_of_line (COLUMN *p); static void skip_read (COLUMN *p, int column_number); @@ -1778,7 +1785,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c static void cleanup (void); static void print_sep_string (void); static void separator_string (const char *optarg_S); -@@ -450,7 +501,7 @@ static COLUMN *column_vector; +@@ -451,7 +502,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]. */ @@ -1787,7 +1794,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* Index of the position in buff where the next character will be stored. */ -@@ -554,7 +605,7 @@ static int chars_per_column; +@@ -555,7 +606,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -1796,7 +1803,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... where the leftmost column is 1. */ -@@ -564,7 +615,10 @@ static int chars_per_input_tab = 8; +@@ -565,7 +616,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -1808,7 +1815,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -638,7 +692,13 @@ static int power_10; +@@ -639,7 +693,13 @@ static int power_10; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1823,7 +1830,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -691,6 +751,7 @@ static bool use_col_separator = false; +@@ -692,6 +752,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ static char *col_sep_string = (char *) ""; static int col_sep_length = 0; @@ -1831,7 +1838,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -847,6 +908,13 @@ separator_string (const char *optarg_S) +@@ -848,6 +909,13 @@ separator_string (const char *optarg_S) col_sep_length = (int) strlen (optarg_S); col_sep_string = xmalloc (col_sep_length + 1); strcpy (col_sep_string, optarg_S); @@ -1845,7 +1852,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c } int -@@ -871,6 +939,21 @@ main (int argc, char **argv) +@@ -872,6 +940,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1867,7 +1874,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c n_files = 0; file_names = (argc > 1 ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -947,8 +1030,12 @@ main (int argc, char **argv) +@@ -948,8 +1031,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1882,7 +1889,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -961,8 +1048,12 @@ main (int argc, char **argv) +@@ -962,8 +1049,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1897,7 +1904,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -989,8 +1080,8 @@ main (int argc, char **argv) +@@ -990,8 +1081,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1908,7 +1915,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c break; case 'N': skip_count = false; -@@ -1029,7 +1120,7 @@ main (int argc, char **argv) +@@ -1030,7 +1121,7 @@ main (int argc, char **argv) old_s = false; /* Reset an additional input of -s, -S dominates -s */ col_sep_string = bad_cast (""); @@ -1917,7 +1924,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1186,10 +1277,45 @@ main (int argc, char **argv) +@@ -1187,10 +1278,45 @@ main (int argc, char **argv) a number. */ static void @@ -1965,7 +1972,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c if (*arg) { long int tmp_long; -@@ -1248,7 +1374,7 @@ init_parameters (int number_of_files) +@@ -1249,7 +1375,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -1974,7 +1981,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1279,11 +1405,11 @@ init_parameters (int number_of_files) +@@ -1280,11 +1406,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. */ @@ -1988,7 +1995,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1298,7 +1424,7 @@ init_parameters (int number_of_files) +@@ -1299,7 +1425,7 @@ init_parameters (int number_of_files) } chars_per_column = (chars_per_line - chars_used_by_number - @@ -1997,7 +2004,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c if (chars_per_column < 1) error (EXIT_FAILURE, 0, _("page width too narrow")); -@@ -1423,7 +1549,7 @@ init_funcs (void) +@@ -1424,7 +1550,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2006,7 +2013,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* This loop takes care of all but the rightmost column. */ -@@ -1457,7 +1583,7 @@ init_funcs (void) +@@ -1458,7 +1584,7 @@ init_funcs (void) } else { @@ -2015,7 +2022,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c h_next = h + chars_per_column; } } -@@ -1747,9 +1873,9 @@ static void +@@ -1749,9 +1875,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2027,7 +2034,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2020,13 +2146,13 @@ store_char (char c) +@@ -2022,13 +2148,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2043,7 +2050,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c char *s; int left_cut; -@@ -2049,22 +2175,24 @@ add_line_number (COLUMN *p) +@@ -2051,22 +2177,24 @@ add_line_number (COLUMN *p) /* Tabification is assumed for multiple columns, also for n-separators, but `default n-separator = TAB' hasn't been given priority over equal column_width also specified by POSIX. */ @@ -2072,7 +2079,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2225,7 +2353,7 @@ print_white_space (void) +@@ -2227,7 +2355,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2081,7 +2088,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c h_old = h_new; } while (++h_old <= goal) -@@ -2245,6 +2373,7 @@ print_sep_string (void) +@@ -2247,6 +2375,7 @@ print_sep_string (void) { char *s; int l = col_sep_length; @@ -2089,7 +2096,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c s = col_sep_string; -@@ -2258,6 +2387,7 @@ print_sep_string (void) +@@ -2260,6 +2389,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2097,7 +2104,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2271,12 +2401,15 @@ print_sep_string (void) +@@ -2273,12 +2403,15 @@ print_sep_string (void) } else { @@ -2114,7 +2121,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2304,7 +2437,7 @@ print_clump (COLUMN *p, int n, char *clu +@@ -2306,7 +2439,7 @@ print_clump (COLUMN *p, int n, char *clu required number of tabs and spaces. */ static void @@ -2123,7 +2130,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c { if (tabify_output) { -@@ -2328,6 +2461,74 @@ print_char (char c) +@@ -2330,6 +2463,74 @@ print_char (char c) putchar (c); } @@ -2198,7 +2205,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2507,9 +2708,9 @@ read_line (COLUMN *p) +@@ -2509,9 +2710,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2210,7 +2217,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2610,9 +2811,9 @@ print_stored (COLUMN *p) +@@ -2612,9 +2813,9 @@ print_stored (COLUMN *p) } } @@ -2222,7 +2229,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2625,8 +2826,8 @@ print_stored (COLUMN *p) +@@ -2627,8 +2828,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2233,7 +2240,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c } return true; -@@ -2645,7 +2846,7 @@ print_stored (COLUMN *p) +@@ -2647,7 +2848,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2242,7 +2249,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c { unsigned char uc = c; char *s = clump_buff; -@@ -2655,10 +2856,10 @@ char_to_clump (char c) +@@ -2657,10 +2858,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2255,7 +2262,7 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2739,6 +2940,154 @@ char_to_clump (char c) +@@ -2741,6 +2942,154 @@ char_to_clump (char c) return chars; } @@ -2410,15 +2417,16 @@ diff -urNp coreutils-8.5-orig/src/pr.c coreutils-8.5/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c ---- coreutils-8.5-orig/src/sort.c 2010-04-21 09:06:17.000000000 +0200 -+++ coreutils-8.5/src/sort.c 2010-04-26 14:24:33.000000000 +0200 -@@ -22,10 +22,19 @@ +diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c +--- coreutils-8.6-orig/src/sort.c 2010-10-14 11:39:14.000000000 +0200 ++++ coreutils-8.6/src/sort.c 2010-10-18 15:16:14.976458929 +0200 +@@ -22,11 +22,20 @@ #include +#include #include + #include #include #include #include @@ -2433,7 +2441,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -124,14 +133,38 @@ static int decimal_point; +@@ -157,14 +166,38 @@ static int decimal_point; /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; @@ -2473,7 +2481,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -270,13 +303,11 @@ static bool reverse; +@@ -328,13 +361,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2490,7 +2498,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -714,6 +745,44 @@ reap_some (void) +@@ -782,6 +813,44 @@ reap_some (void) update_proc (pid); } @@ -2502,7 +2510,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c +static char * +(*limfield) (const struct line*, const struct keyfield *); +static int -+(*getmonth) (char const *, size_t); ++(*getmonth) (char const *, size_t, char **); +static int +(*keycompare) (const struct line *, const struct line *); +static int @@ -2535,7 +2543,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1158,7 +1227,7 @@ zaptemp (const char *name) +@@ -1205,7 +1274,7 @@ zaptemp (char const *name) free (node); } @@ -2543,8 +2551,8 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c +#if HAVE_LANGINFO_CODESET static int - struct_month_cmp (const void *m1, const void *m2) -@@ -1173,7 +1242,7 @@ struct_month_cmp (const void *m1, const + struct_month_cmp (void const *m1, void const *m2) +@@ -1220,7 +1289,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2553,7 +2561,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c { size_t i; -@@ -1185,7 +1254,7 @@ inittables (void) +@@ -1232,7 +1301,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2562,7 +2570,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1268,6 +1337,64 @@ specify_nmerge (int oi, char c, char con +@@ -1314,6 +1383,64 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2627,16 +2635,16 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1478,7 +1605,7 @@ buffer_linelim (struct buffer const *buf +@@ -1540,7 +1667,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * --begfield (const struct line *line, const struct keyfield *key) +-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; -@@ -1487,10 +1614,10 @@ begfield (const struct line *line, const +@@ -1549,10 +1676,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2649,7 +2657,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1516,11 +1643,70 @@ begfield (const struct line *line, const +@@ -1578,11 +1705,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2716,12 +2724,12 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c in LINE specified by KEY. */ static char * --limfield (const struct line *line, const struct keyfield *key) +-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; -@@ -1535,10 +1721,10 @@ limfield (const struct line *line, const +@@ -1597,10 +1783,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. */ @@ -2734,7 +2742,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1584,10 +1770,10 @@ limfield (const struct line *line, const +@@ -1646,10 +1832,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2747,7 +2755,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c if (newlim) lim = newlim; } -@@ -1618,6 +1804,113 @@ limfield (const struct line *line, const +@@ -1680,6 +1866,113 @@ limfield (struct line const *line, struc return ptr; } @@ -2861,7 +2869,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c /* 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 -@@ -1700,8 +1993,24 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1766,8 +2059,24 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2888,17 +2896,17 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c line->keybeg = line_start; } } -@@ -1739,7 +2048,7 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1888,7 +2197,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int --numcompare (const char *a, const char *b) +-numcompare (char const *a, char const *b) +numcompare_uni (const char *a, const char *b) { while (blanks[to_uchar (*a)]) a++; -@@ -1848,6 +2157,25 @@ human_numcompare (const char *a, const c - : strnumcmp (a, b, decimal_point, thousands_sep)); +@@ -1898,6 +2207,25 @@ numcompare (char const *a, char const *b + return strnumcmp (a, b, decimal_point, thousands_sep); } +#if HAVE_MBRTOWC @@ -2921,24 +2929,42 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c +#endif /* HAV_EMBRTOWC */ + static int - general_numcompare (const char *sa, const char *sb) + general_numcompare (char const *sa, char const *sb) { -@@ -1881,7 +2209,7 @@ general_numcompare (const char *sa, cons +@@ -1930,7 +2258,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int --getmonth (char const *month, size_t len) -+getmonth_uni (char const *month, size_t len) +-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; -@@ -2062,11 +2390,80 @@ compare_version (char *restrict texta, s - return diff; +@@ -2210,7 +2538,7 @@ debug_key (struct line const *line, stru + char *tighter_lim = beg; + + 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) +@@ -2354,7 +2682,7 @@ key_warnings (struct keyfield const *gke + bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) + && !(key->schar || key->echar); + bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ +- if (!gkey_only && tab == TAB_DEFAULT && !line_offset ++ if (!gkey_only && !tab_length && !line_offset + && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) + || (!key->skipsblanks && key->schar) + || (!key->skipeblanks && key->echar))) +@@ -2412,11 +2740,83 @@ 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) ++getmonth_mb (const char *s, size_t len, char **ea) +{ + char *month; + register size_t i; @@ -2998,6 +3024,9 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c + } + while (hi - lo > 1); + ++ if (ea) ++ *ea = (char *) month; ++ + result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) + ? monthtab[lo].val : 0); + @@ -3009,12 +3038,21 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c are no more keys or a difference is found. */ static int --keycompare (const struct line *a, const struct line *b) +-keycompare (struct line const *a, struct line const *b) +keycompare_uni (const struct line *a, const struct line *b) { struct keyfield *key = keylist; -@@ -2246,6 +2642,179 @@ keycompare (const struct line *a, const +@@ -2501,7 +2898,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) +@@ -2617,6 +3014,179 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3059,13 +3097,13 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c + *lima = *limb = '\0'; + diff = (key->numeric ? numcompare (texta, textb) + : key->general_numeric ? general_numcompare (texta, textb) -+ : human_numcompare (texta, textb, key)); ++ : human_numcompare (texta, textb)); + *lima = savea, *limb = saveb; + } + else if (key->version) -+ diff = compare_version (texta, lena, textb, lenb); ++ diff = filevercmp (texta, textb); + else if (key->month) -+ diff = getmonth (texta, lena) - getmonth (textb, lenb); ++ diff = getmonth (texta, lena, NULL) - getmonth (textb, lenb, NULL); + else + { + if (ignore || translate) @@ -3194,7 +3232,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -3244,7 +3813,7 @@ main (int argc, char **argv) +@@ -4006,7 +4576,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3203,7 +3241,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -3265,6 +3834,27 @@ main (int argc, char **argv) +@@ -4027,6 +4597,27 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3231,7 +3269,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c have_read_stdin = false; inittables (); -@@ -3536,13 +4126,35 @@ main (int argc, char **argv) +@@ -4297,13 +4888,35 @@ main (int argc, char **argv) case 't': { @@ -3271,7 +3309,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -3553,9 +4165,12 @@ main (int argc, char **argv) +@@ -4314,9 +4927,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3286,10 +3324,10 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c } break; -diff -urNp coreutils-8.5-orig/src/unexpand.c coreutils-8.5/src/unexpand.c ---- coreutils-8.5-orig/src/unexpand.c 2010-01-01 14:06:47.000000000 +0100 -+++ coreutils-8.5/src/unexpand.c 2010-04-26 14:24:33.000000000 +0200 -@@ -39,11 +39,28 @@ +diff -urNp coreutils-8.6-orig/src/unexpand.c coreutils-8.6/src/unexpand.c +--- coreutils-8.6-orig/src/unexpand.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/unexpand.c 2010-10-18 15:18:11.949208684 +0200 +@@ -39,12 +39,29 @@ #include #include #include @@ -3301,6 +3339,7 @@ diff -urNp coreutils-8.5-orig/src/unexpand.c coreutils-8.5/src/unexpand.c + #include "system.h" #include "error.h" + #include "fadvise.h" #include "quote.h" #include "xstrndup.h" @@ -3318,7 +3357,7 @@ diff -urNp coreutils-8.5-orig/src/unexpand.c coreutils-8.5/src/unexpand.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "unexpand" -@@ -103,6 +120,208 @@ static struct option const longopts[] = +@@ -104,6 +121,208 @@ static struct option const longopts[] = {NULL, 0, NULL, 0} }; @@ -3527,7 +3566,7 @@ diff -urNp coreutils-8.5-orig/src/unexpand.c coreutils-8.5/src/unexpand.c void usage (int status) { -@@ -524,7 +743,12 @@ main (int argc, char **argv) +@@ -526,7 +745,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -3541,9 +3580,9 @@ diff -urNp coreutils-8.5-orig/src/unexpand.c coreutils-8.5/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c ---- coreutils-8.5-orig/src/uniq.c 2010-03-13 16:14:09.000000000 +0100 -+++ coreutils-8.5/src/uniq.c 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/src/uniq.c coreutils-8.6/src/uniq.c +--- coreutils-8.6-orig/src/uniq.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/uniq.c 2010-10-18 15:18:11.950208754 +0200 @@ -21,6 +21,16 @@ #include #include @@ -3561,7 +3600,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -31,7 +41,19 @@ +@@ -32,7 +42,19 @@ #include "stdio--.h" #include "xmemcoll.h" #include "xstrtol.h" @@ -3582,7 +3621,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -107,6 +129,10 @@ static enum delimit_method const delimit +@@ -108,6 +130,10 @@ static enum delimit_method const delimit /* Select whether/how to delimit groups of duplicate lines. */ static enum delimit_method delimit_groups; @@ -3593,7 +3632,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -206,7 +232,7 @@ size_opt (char const *opt, char const *m +@@ -207,7 +233,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 * @@ -3602,7 +3641,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -227,6 +253,83 @@ find_field (struct linebuffer const *lin +@@ -228,6 +254,83 @@ find_field (struct linebuffer const *lin return line->buffer + i; } @@ -3686,7 +3725,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c /* 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. -@@ -235,6 +338,8 @@ find_field (struct linebuffer const *lin +@@ -236,6 +339,8 @@ find_field (struct linebuffer const *lin static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -3695,7 +3734,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -242,14 +347,92 @@ different (char *old, char *new, size_t +@@ -243,14 +348,92 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3793,10 +3832,10 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -303,15 +486,43 @@ check_file (const char *infile, const ch +@@ -306,15 +489,43 @@ check_file (const char *infile, const ch { - char *prevfield IF_LINT (= NULL); - size_t prevlen IF_LINT (= 0); + char *prevfield IF_LINT ( = NULL); + size_t prevlen IF_LINT ( = 0); +#if HAVE_MBRTOWC + mbstate_t prevstate; + @@ -3837,7 +3876,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c if (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)) { -@@ -330,17 +541,26 @@ check_file (const char *infile, const ch +@@ -333,17 +544,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -3864,7 +3903,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -349,6 +569,15 @@ check_file (const char *infile, const ch +@@ -352,6 +572,15 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -3880,7 +3919,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -381,6 +610,9 @@ check_file (const char *infile, const ch +@@ -384,6 +613,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3890,7 +3929,7 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c if (!match) match_count = 0; } -@@ -426,6 +658,19 @@ main (int argc, char **argv) +@@ -429,6 +661,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -3910,18 +3949,18 @@ diff -urNp coreutils-8.5-orig/src/uniq.c coreutils-8.5/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.5-orig/tests/Makefile.am coreutils-8.5/tests/Makefile.am ---- coreutils-8.5-orig/tests/Makefile.am 2010-04-26 14:24:10.000000000 +0200 -+++ coreutils-8.5/tests/Makefile.am 2010-04-26 14:24:33.000000000 +0200 -@@ -224,6 +224,7 @@ TESTS = \ - misc/sort-compress \ - misc/sort-continue \ +diff -urNp coreutils-8.6-orig/tests/Makefile.am coreutils-8.6/tests/Makefile.am +--- coreutils-8.6-orig/tests/Makefile.am 2010-10-18 15:17:40.112459208 +0200 ++++ coreutils-8.6/tests/Makefile.am 2010-10-18 15:18:11.957208754 +0200 +@@ -229,6 +229,7 @@ TESTS = \ + misc/sort-debug-keys \ + misc/sort-debug-warn \ misc/sort-files0-from \ + misc/sort-mb-tests \ + misc/sort-float \ misc/sort-merge \ misc/sort-merge-fdlimit \ - misc/sort-month \ -@@ -475,6 +476,10 @@ TESTS = \ +@@ -486,6 +487,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -3932,9 +3971,9 @@ diff -urNp coreutils-8.5-orig/tests/Makefile.am coreutils-8.5/tests/Makefile.am pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.5-orig/tests/misc/cut coreutils-8.5/tests/misc/cut ---- coreutils-8.5-orig/tests/misc/cut 2010-01-01 14:06:47.000000000 +0100 -+++ coreutils-8.5/tests/misc/cut 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/tests/misc/cut coreutils-8.6/tests/misc/cut +--- coreutils-8.6-orig/tests/misc/cut 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/tests/misc/cut 2010-10-18 15:18:11.957208754 +0200 @@ -26,7 +26,7 @@ use strict; my $prog = 'cut'; my $try = "Try \`$prog --help' for more information.\n"; @@ -3953,41 +3992,41 @@ diff -urNp coreutils-8.5-orig/tests/misc/cut coreutils-8.5/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], -diff -urNp coreutils-8.5-orig/tests/misc/mb1.I coreutils-8.5/tests/misc/mb1.I ---- coreutils-8.5-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.5/tests/misc/mb1.I 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/tests/misc/mb1.I coreutils-8.6/tests/misc/mb1.I +--- coreutils-8.6-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.6/tests/misc/mb1.I 2010-10-18 15:18:11.958209243 +0200 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.5-orig/tests/misc/mb1.X coreutils-8.5/tests/misc/mb1.X ---- coreutils-8.5-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.5/tests/misc/mb1.X 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/tests/misc/mb1.X coreutils-8.6/tests/misc/mb1.X +--- coreutils-8.6-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.6/tests/misc/mb1.X 2010-10-18 15:18:11.958209243 +0200 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.5-orig/tests/misc/mb2.I coreutils-8.5/tests/misc/mb2.I ---- coreutils-8.5-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.5/tests/misc/mb2.I 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/tests/misc/mb2.I coreutils-8.6/tests/misc/mb2.I +--- coreutils-8.6-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.6/tests/misc/mb2.I 2010-10-18 15:18:11.959208405 +0200 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.5-orig/tests/misc/mb2.X coreutils-8.5/tests/misc/mb2.X ---- coreutils-8.5-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.5/tests/misc/mb2.X 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/tests/misc/mb2.X coreutils-8.6/tests/misc/mb2.X +--- coreutils-8.6-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.6/tests/misc/mb2.X 2010-10-18 15:18:11.960208894 +0200 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.5-orig/tests/misc/sort-mb-tests coreutils-8.5/tests/misc/sort-mb-tests ---- coreutils-8.5-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.5/tests/misc/sort-mb-tests 2010-04-26 14:24:33.000000000 +0200 +diff -urNp coreutils-8.6-orig/tests/misc/sort-mb-tests coreutils-8.6/tests/misc/sort-mb-tests +--- coreutils-8.6-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.6/tests/misc/sort-mb-tests 2010-10-18 15:18:11.960208894 +0200 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in @@ -4047,3 +4086,39 @@ diff -urNp coreutils-8.5-orig/tests/misc/sort-mb-tests coreutils-8.5/tests/misc/ +fi +test $errors = 0 || errors=1 +exit $errors +diff -urNp coreutils-8.6-orig/tests/misc/sort-debug-keys coreutils-8.6/tests/misc/sort-debug-keys +--- coreutils-8.6-orig/tests/misc/sort-debug-keys 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/tests/misc/sort-debug-keys 2010-10-19 14:55:55.435692063 +0200 +@@ -305,18 +305,19 @@ _____ + ___________________ + EOF + +-: ${LOCALE_FR_UTF8=none} +-if test "$LOCALE_FR_UTF8" != "none"; then +- ( +- echo ' 1²---++3 1,234 Mi' | +- LC_ALL=C sort --debug -k2g -k1b,1 +- echo ' 1²---++3 1,234 Mi' | +- LC_ALL=$LOCALE_FR_UTF8 sort --debug -k2g -k1b,1 +- echo '+1234 1234Gi 1,234M' | +- LC_ALL=$LOCALE_FR_UTF8 sort --debug -k1,1n -k1,1g \ +- -k1,1h -k2,2n -k2,2g -k2,2h -k3,3n -k3,3g -k3,3h +- ) > out +- compare out exp || fail=1 +-fi ++#temporarily disable sort debug-keys test for mbyte locales (doesn't work atm.) ++#: ${LOCALE_FR_UTF8=none} ++#if test "$LOCALE_FR_UTF8" != "none"; then ++# ( ++# echo ' 1²---++3 1,234 Mi' | ++# LC_ALL=C sort --debug -k2g -k1b,1 ++# echo ' 1²---++3 1,234 Mi' | ++# LC_ALL=$LOCALE_FR_UTF8 sort --debug -k2g -k1b,1 ++# echo '+1234 1234Gi 1,234M' | ++# LC_ALL=$LOCALE_FR_UTF8 sort --debug -k1,1n -k1,1g \ ++# -k1,1h -k2,2n -k2,2g -k2,2h -k3,3n -k3,3g -k3,3h ++# ) > out ++# compare out exp || fail=1 ++#fi + + Exit $fail diff --git a/coreutils-pam.patch b/coreutils-pam.patch index e61908f..01face6 100644 --- a/coreutils-pam.patch +++ b/coreutils-pam.patch @@ -2,7 +2,7 @@ diff -urNp coreutils-8.4-orig/configure.ac coreutils-8.4/configure.ac --- coreutils-8.4-orig/configure.ac 2010-01-11 18:20:42.000000000 +0100 +++ coreutils-8.4/configure.ac 2010-02-12 10:17:46.000000000 +0100 @@ -126,6 +126,13 @@ if test "$gl_gcc_warnings" = yes; then - AC_SUBST([GNULIB_WARN_CFLAGS]) + AC_SUBST([GNULIB_TEST_WARN_CFLAGS]) fi +dnl Give the chance to enable PAM diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 26cd0dc..e326d86 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.1-orig/configure.ac coreutils-8.1/configure.ac ---- coreutils-8.1-orig/configure.ac 2009-11-20 13:11:20.000000000 +0100 -+++ coreutils-8.1/configure.ac 2009-11-20 13:11:40.000000000 +0100 -@@ -133,6 +133,13 @@ AC_ARG_ENABLE(pam, dnl +diff -urNp coreutils-8.6-orig/configure.ac coreutils-8.6/configure.ac +--- coreutils-8.6-orig/configure.ac 2010-10-18 13:46:01.319460047 +0200 ++++ coreutils-8.6/configure.ac 2010-10-18 14:36:46.348209592 +0200 +@@ -140,6 +140,13 @@ AC_ARG_ENABLE(pam, dnl LIB_PAM="-ldl -lpam -lpam_misc" AC_SUBST(LIB_PAM)]) @@ -15,18 +15,18 @@ diff -urNp coreutils-8.1-orig/configure.ac coreutils-8.1/configure.ac AC_FUNC_FORK optional_bin_progs= -diff -urNp coreutils-8.1-orig/man/chcon.x coreutils-8.1/man/chcon.x ---- coreutils-8.1-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.1/man/chcon.x 2009-11-20 13:11:40.000000000 +0100 +diff -urNp coreutils-8.6-orig/man/chcon.x coreutils-8.6/man/chcon.x +--- coreutils-8.6-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.6/man/chcon.x 2010-10-18 14:36:46.348209592 +0200 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-8.1-orig/man/runcon.x coreutils-8.1/man/runcon.x ---- coreutils-8.1-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.1/man/runcon.x 2009-11-20 13:11:40.000000000 +0100 +diff -urNp coreutils-8.6-orig/man/runcon.x coreutils-8.6/man/runcon.x +--- coreutils-8.6-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.6/man/runcon.x 2010-10-18 14:36:46.349211548 +0200 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,10 +34,10 @@ diff -urNp coreutils-8.1-orig/man/runcon.x coreutils-8.1/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.1-orig/src/copy.c coreutils-8.1/src/copy.c ---- coreutils-8.1-orig/src/copy.c 2009-10-22 11:18:05.000000000 +0200 -+++ coreutils-8.1/src/copy.c 2009-11-20 13:11:40.000000000 +0100 -@@ -1935,6 +1935,8 @@ copy_internal (char const *src_name, cha +diff -urNp coreutils-8.6-orig/src/copy.c coreutils-8.6/src/copy.c +--- coreutils-8.6-orig/src/copy.c 2010-10-12 13:13:16.000000000 +0200 ++++ coreutils-8.6/src/copy.c 2010-10-18 14:36:46.350209243 +0200 +@@ -1923,6 +1923,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -46,9 +46,9 @@ diff -urNp coreutils-8.1-orig/src/copy.c coreutils-8.1/src/copy.c } else { -diff -urNp coreutils-8.1-orig/src/copy.h coreutils-8.1/src/copy.h ---- coreutils-8.1-orig/src/copy.h 2009-09-21 14:29:33.000000000 +0200 -+++ coreutils-8.1/src/copy.h 2009-11-20 13:11:40.000000000 +0100 +diff -urNp coreutils-8.6-orig/src/copy.h coreutils-8.6/src/copy.h +--- coreutils-8.6-orig/src/copy.h 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/copy.h 2010-10-18 14:36:46.352209243 +0200 @@ -158,6 +158,9 @@ struct cp_options bool preserve_mode; bool preserve_timestamps; @@ -59,10 +59,10 @@ diff -urNp coreutils-8.1-orig/src/copy.h coreutils-8.1/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urNp coreutils-8.1-orig/src/cp.c coreutils-8.1/src/cp.c ---- coreutils-8.1-orig/src/cp.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.1/src/cp.c 2009-11-20 13:11:40.000000000 +0100 -@@ -139,6 +139,7 @@ static struct option const long_opts[] = +diff -urNp coreutils-8.6-orig/src/cp.c coreutils-8.6/src/cp.c +--- coreutils-8.6-orig/src/cp.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/cp.c 2010-10-18 14:36:46.353209453 +0200 +@@ -141,6 +141,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, {"verbose", no_argument, NULL, 'v'}, @@ -70,7 +70,7 @@ diff -urNp coreutils-8.1-orig/src/cp.c coreutils-8.1/src/cp.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -197,6 +198,9 @@ Mandatory arguments to long options are +@@ -200,6 +201,9 @@ Mandatory arguments to long options are all\n\ "), stdout); fputs (_("\ @@ -80,7 +80,7 @@ diff -urNp coreutils-8.1-orig/src/cp.c coreutils-8.1/src/cp.c --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents use full source file name under DIRECTORY\n\ "), stdout); -@@ -223,6 +227,7 @@ Mandatory arguments to long options are +@@ -226,6 +230,7 @@ Mandatory arguments to long options are destination file is missing\n\ -v, --verbose explain what is being done\n\ -x, --one-file-system stay on this file system\n\ @@ -88,7 +88,7 @@ diff -urNp coreutils-8.1-orig/src/cp.c coreutils-8.1/src/cp.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); -@@ -777,6 +782,7 @@ cp_option_init (struct cp_options *x) +@@ -780,6 +785,7 @@ cp_option_init (struct cp_options *x) x->preserve_timestamps = false; x->preserve_security_context = false; x->require_preserve_context = false; @@ -96,7 +96,7 @@ diff -urNp coreutils-8.1-orig/src/cp.c coreutils-8.1/src/cp.c x->preserve_xattr = false; x->reduce_diagnostics = false; x->require_preserve_xattr = false; -@@ -923,7 +929,7 @@ main (int argc, char **argv) +@@ -927,7 +933,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -105,7 +105,7 @@ diff -urNp coreutils-8.1-orig/src/cp.c coreutils-8.1/src/cp.c long_opts, NULL)) != -1) { -@@ -966,6 +972,16 @@ main (int argc, char **argv) +@@ -974,6 +980,16 @@ main (int argc, char **argv) copy_contents = true; break; @@ -122,7 +122,7 @@ diff -urNp coreutils-8.1-orig/src/cp.c coreutils-8.1/src/cp.c case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -@@ -1075,6 +1091,27 @@ main (int argc, char **argv) +@@ -1083,6 +1099,27 @@ main (int argc, char **argv) x.one_file_system = true; break; @@ -150,9 +150,9 @@ diff -urNp coreutils-8.1-orig/src/cp.c coreutils-8.1/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urNp coreutils-8.1-orig/src/chcon.c coreutils-8.1/src/chcon.c ---- coreutils-8.1-orig/src/chcon.c 2009-11-07 08:46:30.000000000 +0100 -+++ coreutils-8.1/src/chcon.c 2009-11-20 13:11:40.000000000 +0100 +diff -urNp coreutils-8.6-orig/src/chcon.c coreutils-8.6/src/chcon.c +--- coreutils-8.6-orig/src/chcon.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/chcon.c 2010-10-18 14:36:46.356209523 +0200 @@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), program_name, program_name, program_name); @@ -162,9 +162,9 @@ diff -urNp coreutils-8.1-orig/src/chcon.c coreutils-8.1/src/chcon.c With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ -h, --no-dereference affect symbolic links instead of any referenced file\n\ -diff -urNp coreutils-8.1-orig/src/id.c coreutils-8.1/src/id.c ---- coreutils-8.1-orig/src/id.c 2009-11-13 15:56:41.000000000 +0100 -+++ coreutils-8.1/src/id.c 2009-11-20 13:11:40.000000000 +0100 +diff -urNp coreutils-8.6-orig/src/id.c coreutils-8.6/src/id.c +--- coreutils-8.6-orig/src/id.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/id.c 2010-10-18 14:36:46.357221466 +0200 @@ -107,7 +107,7 @@ int main (int argc, char **argv) { @@ -174,18 +174,18 @@ diff -urNp coreutils-8.1-orig/src/id.c coreutils-8.1/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urNp coreutils-8.1-orig/src/install.c coreutils-8.1/src/install.c ---- coreutils-8.1-orig/src/install.c 2009-09-29 15:27:54.000000000 +0200 -+++ coreutils-8.1/src/install.c 2009-11-20 13:11:40.000000000 +0100 -@@ -284,6 +284,7 @@ cp_option_init (struct cp_options *x) - x->reduce_diagnostics=false; +diff -urNp coreutils-8.6-orig/src/install.c coreutils-8.6/src/install.c +--- coreutils-8.6-orig/src/install.c 2010-10-14 08:20:20.000000000 +0200 ++++ coreutils-8.6/src/install.c 2010-10-18 14:36:46.358209103 +0200 +@@ -283,6 +283,7 @@ cp_option_init (struct cp_options *x) + x->data_copy_required = true; x->require_preserve = false; x->require_preserve_context = false; + x->set_security_context = false; x->require_preserve_xattr = false; x->recursive = false; x->sparse_mode = SPARSE_AUTO; -@@ -461,7 +462,7 @@ main (int argc, char **argv) +@@ -460,7 +461,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -194,7 +194,7 @@ diff -urNp coreutils-8.1-orig/src/install.c coreutils-8.1/src/install.c NULL)) != -1) { switch (optc) -@@ -535,6 +536,7 @@ main (int argc, char **argv) +@@ -534,6 +535,7 @@ main (int argc, char **argv) error (0, 0, _("WARNING: --preserve_context is deprecated; " "use --preserve-context instead")); /* fall through */ @@ -202,7 +202,7 @@ diff -urNp coreutils-8.1-orig/src/install.c coreutils-8.1/src/install.c case PRESERVE_CONTEXT_OPTION: if ( ! selinux_enabled) { -@@ -542,6 +544,10 @@ main (int argc, char **argv) +@@ -541,6 +543,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } @@ -213,7 +213,7 @@ diff -urNp coreutils-8.1-orig/src/install.c coreutils-8.1/src/install.c x.preserve_security_context = true; use_default_selinux_context = false; break; -@@ -553,6 +559,7 @@ main (int argc, char **argv) +@@ -552,6 +558,7 @@ main (int argc, char **argv) break; } scontext = optarg; @@ -221,7 +221,7 @@ diff -urNp coreutils-8.1-orig/src/install.c coreutils-8.1/src/install.c use_default_selinux_context = false; break; case_GETOPT_HELP_CHAR; -@@ -986,8 +993,8 @@ Mandatory arguments to long options are +@@ -985,8 +992,8 @@ Mandatory arguments to long options are -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ @@ -232,10 +232,10 @@ diff -urNp coreutils-8.1-orig/src/install.c coreutils-8.1/src/install.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); -diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c ---- coreutils-8.1-orig/src/ls.c 2009-11-20 13:11:20.000000000 +0100 -+++ coreutils-8.1/src/ls.c 2009-11-20 13:11:40.000000000 +0100 -@@ -162,7 +162,8 @@ enum filetype +diff -urNp coreutils-8.6-orig/src/ls.c coreutils-8.6/src/ls.c +--- coreutils-8.6-orig/src/ls.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/ls.c 2010-10-18 14:36:46.361209872 +0200 +@@ -159,7 +159,8 @@ enum filetype symbolic_link, sock, whiteout, @@ -245,7 +245,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c }; /* Display letters and indicators for each filetype. -@@ -279,6 +280,7 @@ static void queue_directory (char const +@@ -276,6 +277,7 @@ static void queue_directory (char const static void sort_files (void); static void parse_ls_color (void); void usage (int status); @@ -253,7 +253,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c /* Initial size of hash table. Most hierarchies are likely to be shallower than this. */ -@@ -348,7 +350,7 @@ static struct pending *pending_dirs; +@@ -345,7 +347,7 @@ static struct pending *pending_dirs; static struct timespec current_time; @@ -262,7 +262,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c static char UNKNOWN_SECURITY_CONTEXT[] = "?"; /* Whether any of the files has an ACL. This affects the width of the -@@ -388,7 +390,9 @@ enum format +@@ -385,7 +387,9 @@ enum format one_per_line, /* -1 */ many_per_line, /* -C */ horizontal, /* -x */ @@ -273,7 +273,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c }; static enum format format; -@@ -790,6 +794,9 @@ enum +@@ -787,6 +791,9 @@ enum SHOW_CONTROL_CHARS_OPTION, SI_OPTION, SORT_OPTION, @@ -283,7 +283,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c TIME_OPTION, TIME_STYLE_OPTION }; -@@ -835,7 +842,9 @@ static struct option const long_options[ +@@ -832,7 +839,9 @@ static struct option const long_options[ {"time-style", required_argument, NULL, TIME_STYLE_OPTION}, {"color", optional_argument, NULL, COLOR_OPTION}, {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION}, @@ -294,7 +294,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c {"author", no_argument, NULL, AUTHOR_OPTION}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -@@ -845,12 +854,12 @@ static struct option const long_options[ +@@ -842,12 +851,12 @@ static struct option const long_options[ static char const *const format_args[] = { "verbose", "long", "commas", "horizontal", "across", @@ -309,7 +309,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c }; ARGMATCH_VERIFY (format_args, format_types); -@@ -1281,7 +1290,8 @@ main (int argc, char **argv) +@@ -1289,7 +1298,8 @@ main (int argc, char **argv) /* Avoid following symbolic links when possible. */ if (is_colored (C_ORPHAN) || (is_colored (C_EXEC) && color_symlink_as_referent) @@ -319,7 +319,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c check_symlink_color = true; /* If the standard output is a controlling terminal, watch out -@@ -1328,7 +1338,7 @@ main (int argc, char **argv) +@@ -1336,7 +1346,7 @@ main (int argc, char **argv) if (dereference == DEREF_UNDEFINED) dereference = ((immediate_dirs || indicator_style == classify @@ -328,7 +328,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c ? DEREF_NEVER : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); -@@ -1348,7 +1358,7 @@ main (int argc, char **argv) +@@ -1356,7 +1366,7 @@ main (int argc, char **argv) format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format @@ -337,7 +337,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c || print_block_size; format_needs_type = (! format_needs_stat && (recursive -@@ -1379,7 +1389,7 @@ main (int argc, char **argv) +@@ -1387,7 +1397,7 @@ main (int argc, char **argv) } else do @@ -346,7 +346,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c while (i < argc); if (cwd_n_used) -@@ -1542,7 +1552,7 @@ decode_switches (int argc, char **argv) +@@ -1558,7 +1568,7 @@ decode_switches (int argc, char **argv) ignore_mode = IGNORE_DEFAULT; ignore_patterns = NULL; hide_patterns = NULL; @@ -355,7 +355,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c /* FIXME: put this in a function. */ { -@@ -1924,13 +1934,27 @@ decode_switches (int argc, char **argv) +@@ -1940,13 +1950,27 @@ decode_switches (int argc, char **argv) break; case 'Z': @@ -384,7 +384,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c default: usage (LS_FAILURE); } -@@ -2682,8 +2706,10 @@ clear_files (void) +@@ -2690,8 +2714,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); @@ -397,7 +397,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c } cwd_n_used = 0; -@@ -2725,6 +2751,7 @@ gobble_file (char const *name, enum file +@@ -2733,6 +2759,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -405,7 +405,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c if (command_line_arg || format_needs_stat -@@ -2834,7 +2861,7 @@ gobble_file (char const *name, enum file +@@ -2842,7 +2869,7 @@ gobble_file (char const *name, enum file && print_with_color && is_colored (C_CAP)) f->has_capability = has_capability (absolute_name); @@ -414,7 +414,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c { bool have_selinux = false; bool have_acl = false; -@@ -2857,7 +2884,7 @@ gobble_file (char const *name, enum file +@@ -2865,7 +2892,7 @@ gobble_file (char const *name, enum file err = 0; } @@ -423,7 +423,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c { int n = file_has_acl (absolute_name, &f->stat); err = (n < 0); -@@ -2876,7 +2903,8 @@ gobble_file (char const *name, enum file +@@ -2884,7 +2911,8 @@ gobble_file (char const *name, enum file } if (S_ISLNK (f->stat.st_mode) @@ -433,7 +433,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c { char *linkname; struct stat linkstats; -@@ -2896,6 +2924,7 @@ gobble_file (char const *name, enum file +@@ -2904,6 +2932,7 @@ gobble_file (char const *name, enum file command line are automatically traced if not being listed as files. */ if (!command_line_arg || format == long_format @@ -441,7 +441,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c || !S_ISDIR (linkstats.st_mode)) { /* Get the linked-to file's mode for the filetype indicator -@@ -2935,7 +2964,7 @@ gobble_file (char const *name, enum file +@@ -2943,7 +2972,7 @@ gobble_file (char const *name, enum file block_size_width = len; } @@ -450,7 +450,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c { if (print_owner) { -@@ -3436,6 +3465,13 @@ print_current_files (void) +@@ -3444,6 +3473,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -464,7 +464,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c break; } } -@@ -3598,6 +3634,67 @@ format_inode (char *buf, size_t buflen, +@@ -3606,6 +3642,67 @@ format_inode (char *buf, size_t buflen, : (char *) "?"); } @@ -532,7 +532,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c /* Print information about F in long format. */ static void print_long_format (const struct fileinfo *f) -@@ -3689,9 +3786,15 @@ print_long_format (const struct fileinfo +@@ -3697,9 +3794,15 @@ print_long_format (const struct fileinfo The latter is wrong when nlink_width is zero. */ p += strlen (p); @@ -549,7 +549,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c { DIRED_FPUTS (buf, stdout, p - buf); -@@ -3704,9 +3807,6 @@ print_long_format (const struct fileinfo +@@ -3712,9 +3815,6 @@ print_long_format (const struct fileinfo if (print_author) format_user (f->stat.st_author, author_width, f->stat_ok); @@ -559,7 +559,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c p = buf; } -@@ -4047,9 +4147,6 @@ print_file_name_and_frills (const struct +@@ -4059,9 +4159,6 @@ print_file_name_and_frills (const struct : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ST_NBLOCKSIZE, output_block_size)); @@ -569,7 +569,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c size_t width = print_name_with_quoting (f, false, NULL, start_col); if (indicator_style != none) -@@ -4248,9 +4345,6 @@ length_of_file_name_and_frills (const st +@@ -4265,9 +4362,6 @@ length_of_file_name_and_frills (const st output_block_size)) : block_size_width); @@ -579,7 +579,7 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c quote_name (NULL, f->name, filename_quoting_options, &name_width); len += name_width; -@@ -4681,9 +4775,16 @@ Mandatory arguments to long options are +@@ -4700,9 +4794,16 @@ Mandatory arguments to long options are -w, --width=COLS assume screen width instead of current value\n\ -x list entries by lines instead of by columns\n\ -X sort alphabetically by entry extension\n\ @@ -597,9 +597,9 @@ diff -urNp coreutils-8.1-orig/src/ls.c coreutils-8.1/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-8.1-orig/src/mkdir.c coreutils-8.1/src/mkdir.c ---- coreutils-8.1-orig/src/mkdir.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.1/src/mkdir.c 2009-11-20 13:11:40.000000000 +0100 +diff -urNp coreutils-8.6-orig/src/mkdir.c coreutils-8.6/src/mkdir.c +--- coreutils-8.6-orig/src/mkdir.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/mkdir.c 2010-10-18 14:36:46.363209243 +0200 @@ -38,6 +38,7 @@ static struct option const longopts[] = { @@ -608,9 +608,9 @@ diff -urNp coreutils-8.1-orig/src/mkdir.c coreutils-8.1/src/mkdir.c {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, -diff -urNp coreutils-8.1-orig/src/mknod.c coreutils-8.1/src/mknod.c ---- coreutils-8.1-orig/src/mknod.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.1/src/mknod.c 2009-11-20 13:11:40.000000000 +0100 +diff -urNp coreutils-8.6-orig/src/mknod.c coreutils-8.6/src/mknod.c +--- coreutils-8.6-orig/src/mknod.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/mknod.c 2010-10-18 14:36:46.363209243 +0200 @@ -35,7 +35,7 @@ static struct option const longopts[] = @@ -620,20 +620,20 @@ diff -urNp coreutils-8.1-orig/src/mknod.c coreutils-8.1/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urNp coreutils-8.1-orig/src/mv.c coreutils-8.1/src/mv.c ---- coreutils-8.1-orig/src/mv.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.1/src/mv.c 2009-11-20 13:11:40.000000000 +0100 +diff -urNp coreutils-8.6-orig/src/mv.c coreutils-8.6/src/mv.c +--- coreutils-8.6-orig/src/mv.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/mv.c 2010-10-18 14:36:46.364217485 +0200 @@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x) x->preserve_mode = true; x->preserve_timestamps = true; x->preserve_security_context = selinux_enabled; + x->set_security_context = false; x->reduce_diagnostics = false; + x->data_copy_required = true; x->require_preserve = false; /* FIXME: maybe make this an option */ - x->require_preserve_context = false; -diff -urNp coreutils-8.1-orig/src/runcon.c coreutils-8.1/src/runcon.c ---- coreutils-8.1-orig/src/runcon.c 2009-10-29 14:53:40.000000000 +0100 -+++ coreutils-8.1/src/runcon.c 2009-11-20 13:11:40.000000000 +0100 +diff -urNp coreutils-8.6-orig/src/runcon.c coreutils-8.6/src/runcon.c +--- coreutils-8.6-orig/src/runcon.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/src/runcon.c 2010-10-18 14:36:46.365209103 +0200 @@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ "), program_name, program_name); @@ -643,161 +643,10 @@ diff -urNp coreutils-8.1-orig/src/runcon.c coreutils-8.1/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urNp coreutils-8.1-orig/src/stat.c coreutils-8.1/src/stat.c ---- coreutils-8.1-orig/src/stat.c 2009-10-29 11:11:29.000000000 +0100 -+++ coreutils-8.1/src/stat.c 2009-11-20 13:11:40.000000000 +0100 -@@ -858,7 +858,7 @@ print_it (char const *format, char const - - /* Stat the file system and print what we find. */ - static bool --do_statfs (char const *filename, bool terse, char const *format) -+do_statfs (char const *filename, bool terse, bool secure, char const *format) - { - STRUCT_STATVFS statfsbuf; - -@@ -877,15 +877,31 @@ do_statfs (char const *filename, bool te - } - - if (format == NULL) -+ { -+ if (terse) - { -- format = (terse -- ? "%n %i %l %t %s %S %b %f %a %c %d\n" -- : " File: \"%n\"\n" -+ if (secure) -+ format = "%n %i %l %t %s %S %b %f %a %c %d %C\n"; -+ else -+ format = "%n %i %l %t %s %S %b %f %a %c %d\n"; -+ } -+ else -+ { -+ if (secure) -+ format = " File: \"%n\"\n" - " ID: %-8i Namelen: %-7l Type: %T\n" - "Block size: %-10s Fundamental block size: %S\n" - "Blocks: Total: %-10b Free: %-10f Available: %a\n" -- "Inodes: Total: %-10c Free: %d\n"); -- } -+ "Inodes: Total: %-10c Free: %d\n" -+ " S_Context: %C\n"; -+ else -+ format = " File: \"%n\"\n" -+ " ID: %-8i Namelen: %-7l Type: %T\n" -+ "Block size: %-10s Fundamental block size: %S\n" -+ "Blocks: Total: %-10b Free: %-10f Available: %a\n" -+ "Inodes: Total: %-10c Free: %d\n"; -+ } -+ } - - print_it (format, filename, print_statfs, &statfsbuf); - return true; -@@ -893,7 +909,7 @@ do_statfs (char const *filename, bool te - - /* stat the file and print what we find */ - static bool --do_stat (char const *filename, bool terse, char const *format) -+do_stat (char const *filename, bool terse, bool secure, char const *format) - { - struct stat statbuf; - -@@ -919,9 +935,12 @@ do_stat (char const *filename, bool ters - if (format == NULL) - { - if (terse) -- { -- format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; -- } -+ { -+ if (secure) -+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"; -+ else -+ format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; -+ } - else - { - /* Temporary hack to match original output until conditional -@@ -938,12 +957,22 @@ do_stat (char const *filename, bool ters - } - else - { -- format = -- " File: %N\n" -- " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -- "Device: %Dh/%dd\tInode: %-10i Links: %h\n" -- "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -- "Access: %x\n" "Modify: %y\n" "Change: %z\n"; -+ if (secure) -+ format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %-5h" -+ " Device type: %t,%T\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ " S_Context: %C\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; -+ else -+ format = -+ " File: %N\n" -+ " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" -+ "Device: %Dh/%dd\tInode: %-10i Links: %h\n" -+ "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" -+ "Access: %x\n" "Modify: %y\n" "Change: %z\n"; - } - } - } -@@ -964,6 +993,7 @@ usage (int status) - Display file or file system status.\n\ - \n\ - -L, --dereference follow links\n\ -+ -Z, --context print the SELinux security context \n\ - -f, --file-system display file system status instead of file status\n\ - "), stdout); - fputs (_("\ -@@ -1048,6 +1078,7 @@ main (int argc, char *argv[]) - int i; - bool fs = false; - bool terse = false; -+ bool secure = false; - char *format = NULL; - bool ok = true; - -@@ -1087,13 +1118,13 @@ main (int argc, char *argv[]) - terse = true; - break; - -- case 'Z': /* FIXME: remove in 2010 */ -- /* Ignore, for compatibility with distributions -- that implemented this before upstream. -- But warn of impending removal. */ -- error (0, 0, -- _("the --context (-Z) option is obsolete and will be removed\n" -- "in a future release")); -+ case 'Z': -+ if((is_selinux_enabled()>0)) -+ secure = 1; -+ else { -+ error (0, 0, _("Kernel is not SELinux enabled")); -+ usage (EXIT_FAILURE); -+ } - break; - - case_GETOPT_HELP_CHAR; -@@ -1113,8 +1144,8 @@ main (int argc, char *argv[]) - - for (i = optind; i < argc; i++) - ok &= (fs -- ? do_statfs (argv[i], terse, format) -- : do_stat (argv[i], terse, format)); -+ ? do_statfs (argv[i], terse, secure, format) -+ : do_stat (argv[i], terse, secure, format)); - - exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); - } -diff -urNp coreutils-8.4-orig/tests/test-lib.sh coreutils-8.4/tests/test-lib.sh ---- coreutils-8.4-orig/tests/test-lib.sh 2010-01-03 18:06:20.000000000 +0100 -+++ coreutils-8.4/tests/test-lib.sh 2010-01-14 10:28:17.000000000 +0100 -@@ -218,8 +218,8 @@ skip_if_() +diff -urNp coreutils-8.6-orig/tests/init.cfg coreutils-8.6/tests/init.cfg +--- coreutils-8.6-orig/tests/init.cfg 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/tests/init.cfg 2010-10-18 13:49:14.383904033 +0200 +@@ -214,8 +214,8 @@ skip_if_() require_selinux_() { @@ -808,10 +657,10 @@ diff -urNp coreutils-8.4-orig/tests/test-lib.sh coreutils-8.4/tests/test-lib.sh skip_test_ "this system (or maybe just" \ "the current file system) lacks SELinux support" ;; -diff -urNp coreutils-8.1-orig/tests/misc/selinux coreutils-8.1/tests/misc/selinux ---- coreutils-8.1-orig/tests/misc/selinux 2009-10-30 12:51:07.000000000 +0100 -+++ coreutils-8.1/tests/misc/selinux 2009-11-20 13:11:40.000000000 +0100 -@@ -29,7 +29,7 @@ chcon $ctx f d p || +diff -urNp coreutils-8.6-orig/tests/misc/selinux coreutils-8.6/tests/misc/selinux +--- coreutils-8.6-orig/tests/misc/selinux 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.6/tests/misc/selinux 2010-10-18 14:36:46.365209103 +0200 +@@ -44,7 +44,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. for i in d f p; do diff --git a/coreutils.spec b/coreutils.spec index af90919..08532d3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.5 -Release: 10%{?dist} +Version: 8.6 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,10 +18,6 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -#fix double free error in tac (reported in debian bug #594666) -Patch1: coreutils-8.5-tac-doublefree.patch -#fix various case conversion issues in tr(#611274) -Patch2: coreutils-8.5-trcaseconversion.patch # Our patches #general patch to workaround koji build system issues @@ -64,8 +60,6 @@ Patch912: coreutils-overflow.patch #split the PAM scripts for "su -l"/"runuser -l" from that of normal "su" and #"runuser" (#198639) Patch915: coreutils-split-pam.patch -#prevent koji build failure with wrong getfacl exit code -Patch916: coreutils-getfacl-exit-code.patch #compile su with pie flag and RELRO protection Patch917: coreutils-8.4-su-pie.patch @@ -87,14 +81,11 @@ BuildRequires: gmp-devel BuildRequires: attr BuildRequires: strace -Requires(post): libselinux -Requires: libattr Requires(pre): /sbin/install-info Requires(preun): /sbin/install-info Requires(post): /sbin/install-info Requires(post): grep %{?!nopam:Requires: pam } -Requires(post): libcap Requires: ncurses Requires: gmp Requires: %{name}-libs = %{version}-%{release} @@ -127,8 +118,6 @@ Libraries for coreutils package. %setup -q # From upstream -%patch1 -p1 -b .doublefree -%patch2 -p1 -b .caseconvert # Our patches %patch100 -p1 -b .configure @@ -144,6 +133,7 @@ Libraries for coreutils package. %patch704 -p1 -b .paths %patch706 -p1 -b .pam %patch713 -p1 -b .langinfo + # li18nux/lsb %patch800 -p1 -b .i18n @@ -153,7 +143,6 @@ Libraries for coreutils package. %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow %patch915 -p1 -b .splitl -%patch916 -p1 -b .getfacl-exit-code %patch917 -p1 -b .pie #SELinux @@ -161,7 +150,6 @@ Libraries for coreutils package. %patch951 -p1 -b .selinuxman chmod a+x tests/misc/sort-mb-tests tests/df/direct -chmod a+x tests/misc/tr-case-class #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -348,6 +336,12 @@ fi %{_libdir}/coreutils %changelog +* Wed Oct 20 2010 Ondrej Vasik - 8.6-1 +- new upstream release 8.6 +- remove applied patches, temporarily disable sort + debug-keys test for multibyte locales (failing + because of i18n patch) + * Thu Sep 30 2010 Ondrej Vasik - 8.5-10 - various fixes for case conversion in tr(#611274) diff --git a/sources b/sources index f6e9894..c53fe1b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -55170ed640e300f5b81640c6f4641513 coreutils-8.5.tar.xz +17d693d282ac57c62b241a045e7b511c coreutils-8.6.tar.xz From eed90449e8463646f6eee3b0c7efee1dbf111442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 20 Oct 2010 14:04:49 +0200 Subject: [PATCH 111/523] remove unused patches --- coreutils-8.5-tac-doublefree.patch | 66 ---- coreutils-8.5-trcaseconversion.patch | 431 --------------------------- 2 files changed, 497 deletions(-) delete mode 100644 coreutils-8.5-tac-doublefree.patch delete mode 100644 coreutils-8.5-trcaseconversion.patch diff --git a/coreutils-8.5-tac-doublefree.patch b/coreutils-8.5-tac-doublefree.patch deleted file mode 100644 index 467c202..0000000 --- a/coreutils-8.5-tac-doublefree.patch +++ /dev/null @@ -1,66 +0,0 @@ -From b3959fc691e606857a3c6e9b316ec34819972245 Mon Sep 17 00:00:00 2001 -From: Jim Meyering -Date: Sat, 28 Aug 2010 17:45:29 +0200 -Subject: [PATCH] tac: avoid double free - -* src/tac.c (main): Reading a line longer than 16KiB would cause -tac to realloc its primary buffer. Then, just before exit, tac -would mistakenly free the original (now free'd) buffer. -This bug was introduced by commit be6c13e7, "maint: always free a -buffer, to avoid even semblance of a leak". -* tests/misc/tac (double-free): New test, to exercise this. -Reported by Salvo Tomaselli in . ---- - src/tac.c | 6 ++++-- - tests/misc/tac | 6 ++++++ - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/src/tac.c b/src/tac.c -index cec9736..859e006 100644 ---- a/src/tac.c -+++ b/src/tac.c -@@ -633,7 +633,6 @@ main (int argc, char **argv) - if (! (read_size < half_buffer_size && half_buffer_size < G_buffer_size)) - xalloc_die (); - G_buffer = xmalloc (G_buffer_size); -- void *buf = G_buffer; - if (sentinel_length) - { - strcpy (G_buffer, separator); -@@ -666,6 +665,9 @@ main (int argc, char **argv) - error (0, errno, "-"); - ok = false; - } -- free (buf); -+ -+ size_t offset = sentinel_length ? sentinel_length : 1; -+ free (G_buffer - offset); -+ - exit (ok ? EXIT_SUCCESS : EXIT_FAILURE); - } -diff --git a/tests/misc/tac b/tests/misc/tac -index 7631049..4130c00 100755 ---- a/tests/misc/tac -+++ b/tests/misc/tac -@@ -24,6 +24,9 @@ my $prog = 'tac'; - - my $bad_dir = 'no/such/dir'; - -+# This must be longer than 16KiB to trigger the double free in coreutils-8.5. -+my $long_line = 'o' x (16 * 1024 + 1); -+ - my @Tests = - ( - ['segfault', '-r', {IN=>"a\n"}, {IN=>"b\n"}, {OUT=>"a\nb\n"}], -@@ -67,6 +70,9 @@ my @Tests = - {ERR_SUBST => "s,`$bad_dir': .*,...,"}, - {ERR => "$prog: cannot create temporary file in ...\n"}, - {EXIT => 1}], -+ -+ # coreutils-8.5's tac would double-free its primary buffer. -+ ['double-free', {IN=>$long_line}, {OUT=>$long_line}], - ); - - @Tests = triple_test \@Tests; --- -1.7.2.2.510.g7180a diff --git a/coreutils-8.5-trcaseconversion.patch b/coreutils-8.5-trcaseconversion.patch deleted file mode 100644 index 8fb1a07..0000000 --- a/coreutils-8.5-trcaseconversion.patch +++ /dev/null @@ -1,431 +0,0 @@ -From: Pádraig Brady -Date: Mon, 27 Sep 2010 06:16:44 +0000 (+0100) -Subject: tr: fix various issues with case conversion -X-Git-Url: http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff_plain;h=3f48829c;hp=704eedab034e24814067c535d3577f165c9a8b68 - -tr: fix various issues with case conversion - -This valid translation spec aborted: - LC_ALL=en_US.iso-8859-1 tr '[:upper:]- ' '[:lower:]_' -This invalid translation spec aborted: - LC_ALL=en_US.iso-8859-1 tr '[:upper:] ' '[:lower:]' -This was caused by commit 6efd1046, 05-01-2008, -"Avoid tr case-conversion failure in some locales" - -This misaligned conversion spec was allowed: - LC_ALL=C tr 'A-Y[:lower:]' 'a-z[:upper:]' -This was caused by commit af5d0c36, 21-10-2007, -"tr: do not reject an unmatched [:lower:] or [:upper:] in SET1" - -This misaligned spec was allowed by extending the class: - LC_ALL=C tr '[:upper:] ' '[:lower:]' - -* src/tr.c (validate_case_classes): A new function to check -alignment of case conversion classes. Also it adjusts the -length of the sets so that locales with different numbers of -upper and lower case characters, don't cause issues. -(string2_extend): Disallow extending the case conversion -class as in the above example. That is locale dependent -and most likely not what the user wants. -(validate): Do the simple test for "restricted" char classes -earlier, so we don't redundantly do more expensive validation. -(main): Remove the case class validation, and simplify. -* tests/misc/tr-case-class: A new test to test the various -alignment and locale issues, associated with case conversion. -* tests/misc/tr: Move case conversion tests to new tr-case-class. -* tests/Makefile.am: Reference the new test. ---- - -diff --git a/src/tr.c b/src/tr.c -index a5b6810..479d3d3 100644 ---- a/src/tr.c -+++ b/src/tr.c -@@ -1177,6 +1177,78 @@ card_of_complement (struct Spec_list *s) - return cardinality; - } - -+/* Discard the lengths associated with a case conversion, -+ as using the actual number of upper or lower case characters -+ is problematic when they don't match in some locales. -+ Also ensure the case conversion classes in string2 are -+ aligned correctly with those in string1. -+ Note POSIX says the behavior of `tr "[:upper:]" "[:upper:]"' -+ is undefined. Therefore we allow it (unlike Solaris) -+ and treat it as a no-op. */ -+ -+static void -+validate_case_classes (struct Spec_list *s1, struct Spec_list *s2) -+{ -+ size_t n_upper = 0; -+ size_t n_lower = 0; -+ unsigned int i; -+ int c1 = 0; -+ int c2 = 0; -+ count old_s1_len = s1->length; -+ count old_s2_len = s2->length; -+ struct List_element *s1_tail = s1->tail; -+ struct List_element *s2_tail = s2->tail; -+ bool s1_new_element = true; -+ bool s2_new_element = true; -+ -+ if (!s2->has_char_class) -+ return; -+ -+ for (i = 0; i < N_CHARS; i++) -+ { -+ if (isupper (i)) -+ n_upper++; -+ if (islower (i)) -+ n_lower++; -+ } -+ -+ s1->state = BEGIN_STATE; -+ s2->state = BEGIN_STATE; -+ -+ while (c1 != -1 && c2 != -1) -+ { -+ enum Upper_Lower_class class_s1, class_s2; -+ -+ c1 = get_next (s1, &class_s1); -+ c2 = get_next (s2, &class_s2); -+ -+ /* If c2 transitions to a new case class, then -+ c1 must also transition at the same time. */ -+ if (s2_new_element && class_s2 != UL_NONE -+ && !(s1_new_element && class_s1 != UL_NONE)) -+ error (EXIT_FAILURE, 0, -+ _("misaligned [:upper:] and/or [:lower:] construct")); -+ -+ /* If case converting, quickly skip over the elements. */ -+ if (class_s2 != UL_NONE) -+ { -+ skip_construct (s1); -+ skip_construct (s2); -+ /* Discount insignificant/problematic lengths. */ -+ s1->length -= (class_s1 == UL_UPPER ? n_upper : n_lower) - 1; -+ s2->length -= (class_s2 == UL_UPPER ? n_upper : n_lower) - 1; -+ } -+ -+ s1_new_element = s1->state == NEW_ELEMENT; /* Next element is new. */ -+ s2_new_element = s2->state == NEW_ELEMENT; /* Next element is new. */ -+ } -+ -+ assert (old_s1_len >= s1->length && old_s2_len >= s2->length); -+ -+ s1->tail = s1_tail; -+ s2->tail = s2_tail; -+} -+ - /* Gather statistics about the spec-list S in preparation for the tests - in validate that determine the consistency of the specs. This function - is called at most twice; once for string1, and again for any string2. -@@ -1318,20 +1390,14 @@ parse_str (char const *s, struct Spec_list *spec_list) - Upon successful completion, S2->length is set to S1->length. The only - way this function can fail to make S2 as long as S1 is when S2 has - zero-length, since in that case, there is no last character to repeat. -- So S2->length is required to be at least 1. -+ So S2->length is required to be at least 1. */ - -- Providing this functionality allows the user to do some pretty -- non-BSD (and non-portable) things: For example, the command -- tr -cs '[:upper:]0-9' '[:lower:]' -- is almost guaranteed to give results that depend on your collating -- sequence. */ - - static void - string2_extend (const struct Spec_list *s1, struct Spec_list *s2) - { - struct List_element *p; - unsigned char char_to_repeat; -- int i; - - assert (translating); - assert (s1->length > s2->length); -@@ -1347,11 +1413,13 @@ string2_extend (const struct Spec_list *s1, struct Spec_list *s2) - char_to_repeat = p->u.range.last_char; - break; - case RE_CHAR_CLASS: -- for (i = N_CHARS - 1; i >= 0; i--) -- if (is_char_class_member (p->u.char_class, i)) -- break; -- assert (i >= 0); -- char_to_repeat = i; -+ /* Note BSD allows extending of classes in string2. For example: -+ tr '[:upper:]0-9' '[:lower:]' -+ That's not portable however, contradicts POSIX and is dependent -+ on your collating sequence. */ -+ error (EXIT_FAILURE, 0, -+ _("when translating with string1 longer than string2,\n\ -+the latter string must not end with a character class")); - break; - - case RE_REPEATED_CHAR: -@@ -1431,6 +1499,15 @@ validate (struct Spec_list *s1, struct Spec_list *s2) - when translating")); - } - -+ if (s2->has_restricted_char_class) -+ { -+ error (EXIT_FAILURE, 0, -+ _("when translating, the only character classes that may \ -+appear in\nstring2 are `upper' and `lower'")); -+ } -+ -+ validate_case_classes (s1, s2); -+ - if (s1->length > s2->length) - { - if (!truncate_set1) -@@ -1452,13 +1529,6 @@ when translating")); - _("when translating with complemented character classes,\ - \nstring2 must map all characters in the domain to one")); - } -- -- if (s2->has_restricted_char_class) -- { -- error (EXIT_FAILURE, 0, -- _("when translating, the only character classes that may \ --appear in\nstring2 are `upper' and `lower'")); -- } - } - else - /* Not translating. */ -@@ -1812,7 +1882,6 @@ main (int argc, char **argv) - { - int c1, c2; - int i; -- bool case_convert = false; - enum Upper_Lower_class class_s1; - enum Upper_Lower_class class_s2; - -@@ -1822,47 +1891,21 @@ main (int argc, char **argv) - s2->state = BEGIN_STATE; - for (;;) - { -- /* When the previous pair identified case-converting classes, -- advance S1 and S2 so that each points to the following -- construct. */ -- if (case_convert) -- { -- skip_construct (s1); -- skip_construct (s2); -- case_convert = false; -- } -- - c1 = get_next (s1, &class_s1); - c2 = get_next (s2, &class_s2); - -- /* When translating and there is an [:upper:] or [:lower:] -- class in SET2, then there must be a corresponding [:lower:] -- or [:upper:] class in SET1. */ -- if (class_s1 == UL_NONE -- && (class_s2 == UL_LOWER || class_s2 == UL_UPPER)) -- error (EXIT_FAILURE, 0, -- _("misaligned [:upper:] and/or [:lower:] construct")); -- - if (class_s1 == UL_LOWER && class_s2 == UL_UPPER) - { -- case_convert = true; - for (i = 0; i < N_CHARS; i++) - if (islower (i)) - xlate[i] = toupper (i); - } - else if (class_s1 == UL_UPPER && class_s2 == UL_LOWER) - { -- case_convert = true; - for (i = 0; i < N_CHARS; i++) - if (isupper (i)) - xlate[i] = tolower (i); - } -- else if ((class_s1 == UL_LOWER && class_s2 == UL_LOWER) -- || (class_s1 == UL_UPPER && class_s2 == UL_UPPER)) -- { -- /* POSIX says the behavior of `tr "[:upper:]" "[:upper:]"' -- is undefined. Treat it as a no-op. */ -- } - else - { - /* The following should have been checked by validate... */ -@@ -1870,6 +1913,13 @@ main (int argc, char **argv) - break; - xlate[c1] = c2; - } -+ -+ /* When case-converting, skip the elements as an optimization. */ -+ if (class_s2 != UL_NONE) -+ { -+ skip_construct (s1); -+ skip_construct (s2); -+ } - } - assert (c1 == -1 || truncate_set1); - } -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 5619d0b..3236637 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -260,6 +260,7 @@ TESTS = \ - misc/timeout \ - misc/timeout-parameters \ - misc/tr \ -+ misc/tr-case-class \ - misc/truncate-dangling-symlink \ - misc/truncate-dir-fail \ - misc/truncate-fail-diag \ -diff --git a/tests/misc/tr b/tests/misc/tr -index ca7a960..00cd8e6 100755 ---- a/tests/misc/tr -+++ b/tests/misc/tr -@@ -155,34 +155,8 @@ my @Tests = - - # Up to coreutils-6.9, this would provoke a failed assertion. - ['no-abort-1', qw(-c a '[b*256]'), {IN=>'abc'}, {OUT=>'abb'}], -- -- # Up to coreutils-6.9, tr rejected an unmatched [:lower:] or [:upper:] in SET1. -- ['s1-lower', qw('[:lower:]' '[.*]'), -- {IN=>'#$%123abcABC'}, {OUT=>'#$%123...ABC'}], -- ['s1-upper', qw('[:upper:]' '[.*]'), -- {IN=>'#$%123abcABC'}, {OUT=>'#$%123abc...'}], -- -- # Up to coreutils-6.9.91, this would fail with the diagnostic: -- # tr: misaligned [:upper:] and/or [:lower:] construct -- # with LC_CTYPE=en_US.ISO-8859-1. -- ['tolower-F', qw('[:upper:]' '[:lower:]'), {IN=>'A'}, {OUT=>'a'}], -- -- # When doing a case-converting translation with something after the -- # [:upper:] and [:lower:] elements, ensure that tr honors the following byte. -- ['upcase-xtra', qw('[:lower:].' '[:upper:]x'), {IN=>'abc.'}, {OUT=>'ABCx'}], -- ['dncase-xtra', qw('[:upper:].' '[:lower:]x'), {IN=>'ABC.'}, {OUT=>'abcx'}], - ); - --# Set LC_CTYPE=en_US.ISO-8859-1 in the environment of the tolower-F test. --foreach my $t (@Tests) -- { -- if ($t->[0] eq 'tolower-F') -- { -- push @$t, {ENV=>'LC_CTYPE=en_US.ISO-8859-1'}; -- last; -- } -- } -- - @Tests = triple_test \@Tests; - - # tr takes its input only from stdin, not from a file argument, so -diff --git a/tests/misc/tr-case-class b/tests/misc/tr-case-class -new file mode 100755 -index 0000000..d81c676 ---- /dev/null -+++ b/tests/misc/tr-case-class -@@ -0,0 +1,112 @@ -+#!/bin/sh -+# Test case conversion classes -+ -+# Copyright (C) 2010 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/test-lib.sh -+ -+# Ensure we support translation of case classes with extension -+echo '01234567899999999999999999' > exp -+echo 'abcdefghijklmnopqrstuvwxyz' | -+tr '[:lower:]' '0-9' > out || fail=1 -+compare out exp || fail=1 -+echo 'abcdefghijklmnopqrstuvwxyz' | -+tr '[:lower:][:lower:]' '[:upper:]0-9' > out || fail=1 -+compare out exp || fail=1 -+ -+# Validate the alignment of case classes -+tr 'A-Z[:lower:]' 'a-y[:upper:]' < /dev/null && fail=1 -+tr '[:upper:][:lower:]' 'a-y[:upper:]' < /dev/null && fail=1 -+tr 'A-Y[:lower:]' 'a-z[:upper:]' < /dev/null && fail=1 -+tr 'A-Z[:lower:]' '[:lower:][:upper:]' < /dev/null && fail=1 -+tr 'A-Z[:lower:]' '[:lower:]A-Z' < /dev/null && fail=1 -+tr '[:upper:][:lower:]' 'a-z[:upper:]' < /dev/null || fail=1 -+tr '[:upper:][:lower:]' '[:upper:]a-z' < /dev/null || fail=1 -+ -+# Before coreutils 8.6 the trailing space in string1 -+# caused the case class in string2 to be extended. -+# However that was not portable, dependent on locale -+# and in contravention of POSIX. -+tr '[:upper:] ' '[:lower:]' < /dev/null 2>out && fail=1 -+echo 'tr: when translating with string1 longer than string2, -+the latter string must not end with a character class' > exp -+compare out exp || fail=1 -+ -+# Up to coreutils-6.9, tr rejected an unmatched [:lower:] or [:upper:] in SET1. -+echo '#$%123abcABC' | tr '[:lower:]' '[.*]' > out || fail=1 -+echo '#$%123...ABC' > exp -+compare out exp || fail=1 -+echo '#$%123abcABC' | tr '[:upper:]' '[.*]' > out || fail=1 -+echo '#$%123abc...' > exp -+compare out exp || fail=1 -+ -+# When doing a case-converting translation with something after the -+# [:upper:] and [:lower:] elements, ensure that tr honors the following byte. -+echo 'abc.' | tr '[:lower:].' '[:upper:]x' > out || fail=1 -+echo 'ABCx' > exp -+compare out exp || fail=1 -+ -+# Before coreutils 8.6 the disparate number of upper and lower -+# characters in some locales, triggered abort()s and invalid behavior -+export LC_ALL=en_US.ISO-8859-1 -+ -+if test "$(locale charmap 2>/dev/null)" = ISO-8859-1; then -+ # Up to coreutils-6.9.91, this would fail with the diagnostic: -+ # tr: misaligned [:upper:] and/or [:lower:] construct -+ # with LC_CTYPE=en_US.ISO-8859-1. -+ tr '[:upper:]' '[:lower:]' < /dev/null || fail=1 -+ -+ tr '[:upper:] ' '[:lower:]' < /dev/null 2>out && fail=1 -+ echo 'tr: when translating with string1 longer than string2, -+the latter string must not end with a character class' > exp -+ compare out exp || fail=1 -+ -+ # Ensure when there are a different number of elements -+ # in each string, we validate the case mapping correctly -+ echo 'abc.xyz' | -+ tr 'ab[:lower:]' '0-1[:upper:]' > out || fail=1 -+ echo 'ABC.XYZ' > exp -+ compare out exp || fail=1 -+ -+ # Ensure we extend string2 appropriately -+ echo 'ABC- XYZ' | -+ tr '[:upper:]- ' '[:lower:]_' > out || fail=1 -+ echo 'abc__xyz' > exp -+ compare out exp || fail=1 -+ -+ # Ensure the size of the case classes are accounted -+ # for as a unit. -+ echo 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | -+ tr '[:upper:]A-B' '[:lower:]0' >out || fail=1 -+ echo '00cdefghijklmnopqrstuvwxyz' > exp -+ compare out exp || fail=1 -+ -+ # Ensure the size of the case classes are accounted -+ # for as a unit. -+ echo 'a' | -+ tr -t '[:lower:]a' '[:upper:]0' >out || fail=1 -+ echo '0' > exp -+ compare out exp || fail=1 -+ -+ # Ensure the size of the case classes are accounted -+ # for as a unit. -+ echo 'a' | -+ tr -t '[:lower:][:lower:]a' '[:lower:][:upper:]0' >out || fail=1 -+ echo '0' > exp -+ compare out exp || fail=1 -+fi -+ -+Exit $fail From bd229edf8d10a3e348fc7661c3638b464bbd7b64 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 26 Oct 2010 18:53:51 +0200 Subject: [PATCH 112/523] improve i18n support in sort test misc/sort-debug-keys is now back --- coreutils-i18n.patch | 134 ++++++++++++++++++++++--------------------- coreutils.spec | 5 +- 2 files changed, 72 insertions(+), 67 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 89dde2c..0860224 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,3 +1,15 @@ + lib/linebuffer.h | 8 + + src/cut.c | 420 ++++++++++++++++++++++++++++++-- + src/expand.c | 160 ++++++++++++- + src/fold.c | 309 +++++++++++++++++++++-- + src/join.c | 347 +++++++++++++++++++++++---- + src/pr.c | 431 +++++++++++++++++++++++++++++--- + src/sort.c | 704 ++++++++++++++++++++++++++++++++++++++++++++++++++--- + src/unexpand.c | 226 +++++++++++++++++- + src/uniq.c | 259 +++++++++++++++++++- + tests/Makefile.am | 5 + + 10 files changed, 2689 insertions(+), 180 deletions(-) + diff -urNp coreutils-8.6-orig/lib/linebuffer.h coreutils-8.6/lib/linebuffer.h --- coreutils-8.6-orig/lib/linebuffer.h 2010-06-10 18:45:26.000000000 +0200 +++ coreutils-8.6/lib/linebuffer.h 2010-10-18 15:18:11.932209034 +0200 @@ -2417,9 +2429,10 @@ diff -urNp coreutils-8.6-orig/src/pr.c coreutils-8.6/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c ---- coreutils-8.6-orig/src/sort.c 2010-10-14 11:39:14.000000000 +0200 -+++ coreutils-8.6/src/sort.c 2010-10-18 15:16:14.976458929 +0200 +diff --git a/src/sort.c b/src/sort.c +index 7e25f6a..d3f8915 100644 +--- a/src/sort.c ++++ b/src/sort.c @@ -22,11 +22,20 @@ #include @@ -2498,7 +2511,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -782,6 +813,44 @@ reap_some (void) +@@ -782,6 +813,46 @@ reap_some (void) update_proc (pid); } @@ -2509,6 +2522,8 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c +(*begfield) (const struct line*, const struct keyfield *); +static char * +(*limfield) (const struct line*, const struct keyfield *); ++static void ++(*skipblanks) (const char **ptr, const char *lim); +static int +(*getmonth) (char const *, size_t, char **); +static int @@ -2543,7 +2558,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1205,7 +1274,7 @@ zaptemp (char const *name) +@@ -1205,7 +1276,7 @@ zaptemp (char const *name) free (node); } @@ -2552,7 +2567,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1220,7 +1289,7 @@ struct_month_cmp (void const *m1, void c +@@ -1220,7 +1291,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -2561,7 +2576,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c { size_t i; -@@ -1232,7 +1301,7 @@ inittables (void) +@@ -1232,7 +1303,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2570,7 +2585,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1314,6 +1383,64 @@ specify_nmerge (int oi, char c, char con +@@ -1314,6 +1385,64 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -2635,7 +2650,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1540,7 +1667,7 @@ buffer_linelim (struct buffer const *buf +@@ -1540,7 +1669,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -2644,7 +2659,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1549,10 +1676,10 @@ begfield (struct line const *line, struc +@@ -1549,10 +1678,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -2657,7 +2672,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1578,11 +1705,70 @@ begfield (struct line const *line, struc +@@ -1578,11 +1707,70 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2729,7 +2744,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1597,10 +1783,10 @@ limfield (struct line const *line, struc +@@ -1597,10 +1785,10 @@ limfield (struct line const *line, struct keyfield const *key) `beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first `blank' character after the preceding field. */ @@ -2742,7 +2757,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1646,10 +1832,10 @@ limfield (struct line const *line, struc +@@ -1646,10 +1834,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2755,7 +2770,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c if (newlim) lim = newlim; } -@@ -1680,6 +1866,113 @@ limfield (struct line const *line, struc +@@ -1680,6 +1868,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2865,11 +2880,28 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c + return ptr; +} +#endif ++ ++static void ++skipblanks_uni (const char **ptr, const char *lim) ++{ ++ while (*ptr < lim && blanks[to_uchar (**ptr)]) ++ ++(*ptr); ++} ++ ++#if HAVE_MBRTOWC ++static void ++skipblanks_mb (const char **ptr, const 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 -@@ -1766,8 +2059,24 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1766,8 +2078,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2880,8 +2912,6 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c + if (MB_CUR_MAX > 1) + { + size_t mblength; -+ mbstate_t state; -+ memset (&state, '\0', sizeof(mbstate_t)); + while (line_start < line->keylim && + ismbblank (line_start, + line->keylim - line_start, @@ -2896,7 +2926,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c line->keybeg = line_start; } } -@@ -1888,7 +2197,7 @@ human_numcompare (char const *a, char co +@@ -1888,7 +2214,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2905,7 +2935,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1898,6 +2207,25 @@ numcompare (char const *a, char const *b +@@ -1898,6 +2224,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2931,7 +2961,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c static int general_numcompare (char const *sa, char const *sb) { -@@ -1930,7 +2258,7 @@ general_numcompare (char const *sa, char +@@ -1930,7 +2275,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2940,7 +2970,14 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2210,7 +2538,7 @@ debug_key (struct line const *line, stru +@@ -2204,13 +2549,12 @@ debug_key (struct line const *line, struct keyfield const *key) + { + char saved = *lim; *lim = '\0'; + +- while (blanks[to_uchar (*beg)]) +- beg++; ++ skipblanks (&beg, lim); + char *tighter_lim = beg; if (key->month) @@ -2949,7 +2986,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2354,7 +2682,7 @@ key_warnings (struct keyfield const *gke +@@ -2354,7 +2698,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2958,7 +2995,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2412,11 +2740,83 @@ key_warnings (struct keyfield const *gke +@@ -2412,11 +2756,83 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option `-r' only applies to last-resort comparison")); } @@ -3043,7 +3080,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c { struct keyfield *key = keylist; -@@ -2501,7 +2898,7 @@ keycompare (struct line const *a, struct +@@ -2501,7 +2917,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3052,7 +3089,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2617,6 +3014,179 @@ keycompare (struct line const *a, struct +@@ -2617,6 +3033,179 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -3232,7 +3269,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4006,7 +4576,7 @@ main (int argc, char **argv) +@@ -4006,7 +4595,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3241,7 +3278,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4027,6 +4597,27 @@ main (int argc, char **argv) +@@ -4027,6 +4616,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3251,6 +3288,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c + inittables = inittables_mb; + begfield = begfield_mb; + limfield = limfield_mb; ++ skipblanks = skipblanks_mb; + getmonth = getmonth_mb; + keycompare = keycompare_mb; + numcompare = numcompare_mb; @@ -3261,6 +3299,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c + inittables = inittables_uni; + begfield = begfield_uni; + limfield = limfield_uni; ++ skipblanks = skipblanks_uni; + getmonth = getmonth_uni; + keycompare = keycompare_uni; + numcompare = numcompare_uni; @@ -3269,7 +3308,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c have_read_stdin = false; inittables (); -@@ -4297,13 +4888,35 @@ main (int argc, char **argv) +@@ -4297,13 +4909,34 @@ main (int argc, char **argv) case 't': { @@ -3286,7 +3325,6 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c + { + wchar_t wc; + mbstate_t state; -+ size_t i; + + memset (&state, '\0', sizeof (mbstate_t)); + newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, @@ -3309,7 +3347,7 @@ diff -urNp coreutils-8.6-orig/src/sort.c coreutils-8.6/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -4314,9 +4927,12 @@ main (int argc, char **argv) +@@ -4314,9 +4947,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4086,39 +4124,3 @@ diff -urNp coreutils-8.6-orig/tests/misc/sort-mb-tests coreutils-8.6/tests/misc/ +fi +test $errors = 0 || errors=1 +exit $errors -diff -urNp coreutils-8.6-orig/tests/misc/sort-debug-keys coreutils-8.6/tests/misc/sort-debug-keys ---- coreutils-8.6-orig/tests/misc/sort-debug-keys 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/tests/misc/sort-debug-keys 2010-10-19 14:55:55.435692063 +0200 -@@ -305,18 +305,19 @@ _____ - ___________________ - EOF - --: ${LOCALE_FR_UTF8=none} --if test "$LOCALE_FR_UTF8" != "none"; then -- ( -- echo ' 1²---++3 1,234 Mi' | -- LC_ALL=C sort --debug -k2g -k1b,1 -- echo ' 1²---++3 1,234 Mi' | -- LC_ALL=$LOCALE_FR_UTF8 sort --debug -k2g -k1b,1 -- echo '+1234 1234Gi 1,234M' | -- LC_ALL=$LOCALE_FR_UTF8 sort --debug -k1,1n -k1,1g \ -- -k1,1h -k2,2n -k2,2g -k2,2h -k3,3n -k3,3g -k3,3h -- ) > out -- compare out exp || fail=1 --fi -+#temporarily disable sort debug-keys test for mbyte locales (doesn't work atm.) -+#: ${LOCALE_FR_UTF8=none} -+#if test "$LOCALE_FR_UTF8" != "none"; then -+# ( -+# echo ' 1²---++3 1,234 Mi' | -+# LC_ALL=C sort --debug -k2g -k1b,1 -+# echo ' 1²---++3 1,234 Mi' | -+# LC_ALL=$LOCALE_FR_UTF8 sort --debug -k2g -k1b,1 -+# echo '+1234 1234Gi 1,234M' | -+# LC_ALL=$LOCALE_FR_UTF8 sort --debug -k1,1n -k1,1g \ -+# -k1,1h -k2,2n -k2,2g -k2,2h -k3,3n -k3,3g -k3,3h -+# ) > out -+# compare out exp || fail=1 -+#fi - - Exit $fail diff --git a/coreutils.spec b/coreutils.spec index 08532d3..baae402 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.6 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -336,6 +336,9 @@ fi %{_libdir}/coreutils %changelog +* Tue Oct 26 2010 Kamil Dudka - 8.6-2 +- improve i18n support in sort (debug-keys test is now back) + * Wed Oct 20 2010 Ondrej Vasik - 8.6-1 - new upstream release 8.6 - remove applied patches, temporarily disable sort From c07997606cfe09a5da110997cf9fe7e7033f362c Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 3 Nov 2010 12:16:08 +0100 Subject: [PATCH 113/523] prevent sort from assertion failure (#647938) ... in case LC_CTYPE does not match LC_TIME --- coreutils-i18n.patch | 112 ++++++++++++++++++++++++++----------------- coreutils.spec | 6 ++- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 0860224..a9a1a4c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,14 +1,20 @@ - lib/linebuffer.h | 8 + - src/cut.c | 420 ++++++++++++++++++++++++++++++-- - src/expand.c | 160 ++++++++++++- - src/fold.c | 309 +++++++++++++++++++++-- - src/join.c | 347 +++++++++++++++++++++++---- - src/pr.c | 431 +++++++++++++++++++++++++++++--- - src/sort.c | 704 ++++++++++++++++++++++++++++++++++++++++++++++++++--- - src/unexpand.c | 226 +++++++++++++++++- - src/uniq.c | 259 +++++++++++++++++++- - tests/Makefile.am | 5 + - 10 files changed, 2689 insertions(+), 180 deletions(-) + lib/linebuffer.h | 8 + + src/cut.c | 420 +++++++++++++++++++++++++-- + src/expand.c | 160 ++++++++++- + src/fold.c | 309 ++++++++++++++++++-- + src/join.c | 347 +++++++++++++++++++--- + src/pr.c | 431 +++++++++++++++++++++++++--- + src/sort.c | 722 +++++++++++++++++++++++++++++++++++++++++++--- + src/unexpand.c | 226 ++++++++++++++- + src/uniq.c | 259 ++++++++++++++++- + tests/Makefile.am | 5 + + tests/misc/cut | 4 +- + tests/misc/mb1.I | 4 + + tests/misc/mb1.X | 4 + + tests/misc/mb2.I | 4 + + tests/misc/mb2.X | 4 + + tests/misc/sort-mb-tests | 58 ++++ + 16 files changed, 2783 insertions(+), 182 deletions(-) diff -urNp coreutils-8.6-orig/lib/linebuffer.h coreutils-8.6/lib/linebuffer.h --- coreutils-8.6-orig/lib/linebuffer.h 2010-06-10 18:45:26.000000000 +0200 @@ -2454,12 +2460,8 @@ index 7e25f6a..d3f8915 100644 #include "system.h" #include "argmatch.h" #include "error.h" -@@ -157,14 +166,38 @@ static int decimal_point; - /* Thousands separator; if -1, then there isn't one. */ - static int thousands_sep; +@@ -159,12 +168,34 @@ static int thousands_sep; -+static int force_general_numcompare = 0; -+ /* Nonzero if the corresponding locales are hard. */ static bool hard_LC_COLLATE; -#if HAVE_NL_LANGINFO @@ -2494,7 +2496,7 @@ index 7e25f6a..d3f8915 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -328,13 +361,11 @@ static bool reverse; +@@ -328,13 +359,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2511,7 +2513,7 @@ index 7e25f6a..d3f8915 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -782,6 +813,46 @@ reap_some (void) +@@ -782,6 +811,46 @@ reap_some (void) update_proc (pid); } @@ -2523,7 +2525,7 @@ index 7e25f6a..d3f8915 100644 +static char * +(*limfield) (const struct line*, const struct keyfield *); +static void -+(*skipblanks) (const char **ptr, const char *lim); ++(*skipblanks) (char **ptr, char *lim); +static int +(*getmonth) (char const *, size_t, char **); +static int @@ -2558,7 +2560,7 @@ index 7e25f6a..d3f8915 100644 /* Clean up any remaining temporary files. */ static void -@@ -1205,7 +1276,7 @@ zaptemp (char const *name) +@@ -1205,7 +1274,7 @@ zaptemp (char const *name) free (node); } @@ -2567,7 +2569,7 @@ index 7e25f6a..d3f8915 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1220,7 +1291,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1220,7 +1289,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -2576,7 +2578,7 @@ index 7e25f6a..d3f8915 100644 { size_t i; -@@ -1232,7 +1303,7 @@ inittables (void) +@@ -1232,7 +1301,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2585,7 +2587,7 @@ index 7e25f6a..d3f8915 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1314,6 +1385,64 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1314,6 +1383,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -2594,12 +2596,25 @@ index 7e25f6a..d3f8915 100644 +inittables_mb (void) +{ + int i, j, k, l; -+ char *name, *s; ++ 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); @@ -2644,13 +2659,20 @@ index 7e25f6a..d3f8915 100644 + } + 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) -@@ -1540,7 +1669,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1540,7 +1687,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -2659,7 +2681,7 @@ index 7e25f6a..d3f8915 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1549,10 +1678,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1549,10 +1696,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -2672,7 +2694,7 @@ index 7e25f6a..d3f8915 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1578,11 +1707,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1578,11 +1725,70 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2744,7 +2766,7 @@ index 7e25f6a..d3f8915 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1597,10 +1785,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1597,10 +1803,10 @@ limfield (struct line const *line, struct keyfield const *key) `beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first `blank' character after the preceding field. */ @@ -2757,7 +2779,7 @@ index 7e25f6a..d3f8915 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1646,10 +1834,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1646,10 +1852,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2770,7 +2792,7 @@ index 7e25f6a..d3f8915 100644 if (newlim) lim = newlim; } -@@ -1680,6 +1868,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1680,6 +1886,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2882,7 +2904,7 @@ index 7e25f6a..d3f8915 100644 +#endif + +static void -+skipblanks_uni (const char **ptr, const char *lim) ++skipblanks_uni (char **ptr, char *lim) +{ + while (*ptr < lim && blanks[to_uchar (**ptr)]) + ++(*ptr); @@ -2890,7 +2912,7 @@ index 7e25f6a..d3f8915 100644 + +#if HAVE_MBRTOWC +static void -+skipblanks_mb (const char **ptr, const char *lim) ++skipblanks_mb (char **ptr, char *lim) +{ + size_t mblength; + while (*ptr < lim && ismbblank (*ptr, lim - *ptr, &mblength)) @@ -2901,7 +2923,7 @@ index 7e25f6a..d3f8915 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1766,8 +2078,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1766,8 +2096,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2926,7 +2948,7 @@ index 7e25f6a..d3f8915 100644 line->keybeg = line_start; } } -@@ -1888,7 +2214,7 @@ human_numcompare (char const *a, char const *b) +@@ -1888,7 +2232,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2935,7 +2957,7 @@ index 7e25f6a..d3f8915 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -1898,6 +2224,25 @@ numcompare (char const *a, char const *b) +@@ -1898,6 +2242,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2961,7 +2983,7 @@ index 7e25f6a..d3f8915 100644 static int general_numcompare (char const *sa, char const *sb) { -@@ -1930,7 +2275,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -1930,7 +2293,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2970,7 +2992,7 @@ index 7e25f6a..d3f8915 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2204,13 +2549,12 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2204,13 +2567,12 @@ debug_key (struct line const *line, struct keyfield const *key) { char saved = *lim; *lim = '\0'; @@ -2986,7 +3008,7 @@ index 7e25f6a..d3f8915 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2354,7 +2698,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2354,7 +2716,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2995,7 +3017,7 @@ index 7e25f6a..d3f8915 100644 && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2412,11 +2756,83 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2412,11 +2774,83 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option `-r' only applies to last-resort comparison")); } @@ -3080,7 +3102,7 @@ index 7e25f6a..d3f8915 100644 { struct keyfield *key = keylist; -@@ -2501,7 +2917,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2501,7 +2935,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3089,7 +3111,7 @@ index 7e25f6a..d3f8915 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2617,6 +3033,179 @@ keycompare (struct line const *a, struct line const *b) +@@ -2617,6 +3051,179 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -3269,7 +3291,7 @@ index 7e25f6a..d3f8915 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4006,7 +4595,7 @@ main (int argc, char **argv) +@@ -4006,7 +4613,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3278,7 +3300,7 @@ index 7e25f6a..d3f8915 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4027,6 +4616,29 @@ main (int argc, char **argv) +@@ -4027,6 +4634,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3308,7 +3330,7 @@ index 7e25f6a..d3f8915 100644 have_read_stdin = false; inittables (); -@@ -4297,13 +4909,34 @@ main (int argc, char **argv) +@@ -4297,13 +4927,34 @@ main (int argc, char **argv) case 't': { @@ -3347,7 +3369,7 @@ index 7e25f6a..d3f8915 100644 else { /* Provoke with `sort -txx'. Complain about -@@ -4314,9 +4947,12 @@ main (int argc, char **argv) +@@ -4314,9 +4965,12 @@ main (int argc, char **argv) quote (optarg)); } } diff --git a/coreutils.spec b/coreutils.spec index baae402..ecd37f3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.6 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -336,6 +336,10 @@ fi %{_libdir}/coreutils %changelog +* Wed Nov 03 2010 Kamil Dudka - 8.6-3 +- prevent sort from assertion failure in case LC_CTYPE does not match LC_TIME + (#647938) + * Tue Oct 26 2010 Kamil Dudka - 8.6-2 - improve i18n support in sort (debug-keys test is now back) From 9170895a876fa7934eb4513d9432d8a721bd54f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 15 Nov 2010 13:16:04 +0100 Subject: [PATCH 114/523] New upstream release 8.7, consolidate PAM support with SUSE (#622700) --- .gitignore | 1 + coreutils-8.4-su-pie.patch | 4 +- coreutils-8.5-pam.patch | 428 ++++++++++++++++++ ...nuser.patch => coreutils-8.7-runuser.patch | 201 +++----- coreutils-i18n.patch | 155 +++---- coreutils-pam.patch | 428 ------------------ coreutils-selinux.patch | 108 ++--- coreutils-setsid.patch | 78 ++-- coreutils-split-pam.patch | 57 --- coreutils.spec | 18 +- sources | 2 +- 11 files changed, 674 insertions(+), 806 deletions(-) create mode 100644 coreutils-8.5-pam.patch rename coreutils-5.2.1-runuser.patch => coreutils-8.7-runuser.patch (62%) delete mode 100644 coreutils-pam.patch delete mode 100644 coreutils-split-pam.patch diff --git a/.gitignore b/.gitignore index fae4898..f0640be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ coreutils-8.5.tar.xz /coreutils-8.6.tar.xz +/coreutils-8.7.tar.xz diff --git a/coreutils-8.4-su-pie.patch b/coreutils-8.4-su-pie.patch index 07d1d5e..b3fcaaf 100644 --- a/coreutils-8.4-su-pie.patch +++ b/coreutils-8.4-su-pie.patch @@ -3,8 +3,8 @@ diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am +++ coreutils-8.4/src/Makefile.am 2010-09-03 17:36:13.005765125 +0200 @@ -367,6 +367,7 @@ factor_LDADD += $(LIB_GMP) - # for crypt - su_LDADD += $(LIB_CRYPT) @LIB_PAM@ + # for crypt and pam + su_LDADD += $(LIB_CRYPT) $(PAM_LIBS) +su_LDFLAGS = -pie -Wl,-z,relro,-z,now # for various ACL functions diff --git a/coreutils-8.5-pam.patch b/coreutils-8.5-pam.patch new file mode 100644 index 0000000..71b85e7 --- /dev/null +++ b/coreutils-8.5-pam.patch @@ -0,0 +1,428 @@ +From ea2d050b1952feb99f86c98255280beb6e589d8c Mon Sep 17 00:00:00 2001 +From: Ludwig Nussel +Date: Tue, 17 Aug 2010 13:21:44 +0200 +Subject: [PATCH 1/7] pam support for su + +--- + configure.ac | 14 +++ + src/Makefile.am | 4 +- + src/su.c | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 3 files changed, 278 insertions(+), 6 deletions(-) + +diff --git a/configure.ac b/configure.ac +index b07a52b..1fb5839 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -128,6 +128,20 @@ fi + + AC_FUNC_FORK + ++AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam], ++ [Disable PAM support in su (default=auto)]), , [enable_pam=yes]) ++if test "x$enable_pam" != xno; then ++ AC_CHECK_LIB([pam], [pam_start], [enable_pam=yes], [enable_pam=no]) ++ AC_CHECK_LIB([pam_misc], [misc_conv], [:], [enable_pam=no]) ++ if test "x$enable_pam" != xno; then ++ AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) ++ PAM_LIBS="-lpam -lpam_misc" ++ AC_SUBST(PAM_LIBS) ++ fi ++fi ++AC_MSG_CHECKING([whether to enable PAM support in su]) ++AC_MSG_RESULT([$enable_pam]) ++ + optional_bin_progs= + AC_CHECK_FUNCS([chroot], + gl_ADD_PROG([optional_bin_progs], [chroot])) +diff --git a/src/Makefile.am b/src/Makefile.am +index db5359b..154a5ed 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -363,8 +363,8 @@ factor_LDADD += $(LIB_GMP) + # for getloadavg + uptime_LDADD += $(GETLOADAVG_LIBS) + +-# for crypt +-su_LDADD += $(LIB_CRYPT) ++# for crypt and pam ++su_LDADD += $(LIB_CRYPT) $(PAM_LIBS) + + # for various ACL functions + copy_LDADD += $(LIB_ACL) +diff --git a/src/su.c b/src/su.c +index f8f5b61..811aad7 100644 +--- a/src/su.c ++++ b/src/su.c +@@ -37,6 +37,16 @@ + restricts who can su to UID 0 accounts. RMS considers that to + be fascist. + ++#ifdef USE_PAM ++ ++ Actually, with PAM, su has nothing to do with whether or not a ++ wheel group is enforced by su. RMS tries to restrict your access ++ to a su which implements the wheel group, but PAM considers that ++ to be fascist, and gives the user/sysadmin the opportunity to ++ enforce a wheel group by proper editing of /etc/pam.d/su ++ ++#endif ++ + Compile-time options: + -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. + -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. +@@ -52,6 +62,13 @@ + #include + #include + #include ++#ifdef USE_PAM ++#include ++#include ++#include ++#include ++#include ++#endif + + #include "system.h" + #include "getpass.h" +@@ -111,7 +128,9 @@ + /* The user to become if none is specified. */ + #define DEFAULT_USER "root" + ++#ifndef USE_PAM + char *crypt (char const *key, char const *salt); ++#endif + + static void run_shell (char const *, char const *, char **, size_t) + ATTRIBUTE_NORETURN; +@@ -125,6 +144,11 @@ static bool simulate_login; + /* If true, change some environment vars to indicate the user su'd to. */ + static bool change_environment; + ++#ifdef USE_PAM ++static bool _pam_session_opened; ++static bool _pam_cred_established; ++#endif ++ + static struct option const longopts[] = + { + {"command", required_argument, NULL, 'c'}, +@@ -200,7 +224,164 @@ log_su (struct passwd const *pw, bool successful) + } + #endif + ++#ifdef USE_PAM ++#define PAM_SERVICE_NAME PROGRAM_NAME ++#define PAM_SERVICE_NAME_L PROGRAM_NAME "-l" ++static sig_atomic_t volatile caught_signal = false; ++static pam_handle_t *pamh = NULL; ++static int retval; ++static struct pam_conv conv = ++{ ++ misc_conv, ++ NULL ++}; ++ ++#define PAM_BAIL_P(a) \ ++ if (retval) \ ++ { \ ++ pam_end (pamh, retval); \ ++ a; \ ++ } ++ ++static void ++cleanup_pam (int retcode) ++{ ++ if (_pam_session_opened) ++ pam_close_session (pamh, 0); ++ ++ if (_pam_cred_established) ++ pam_setcred (pamh, PAM_DELETE_CRED | PAM_SILENT); ++ ++ pam_end(pamh, retcode); ++} ++ ++/* Signal handler for parent process. */ ++static void ++su_catch_sig (int sig) ++{ ++ caught_signal = true; ++} ++ ++/* Export env variables declared by PAM modules. */ ++static void ++export_pamenv (void) ++{ ++ char **env; ++ ++ /* This is a copy but don't care to free as we exec later anyways. */ ++ env = pam_getenvlist (pamh); ++ while (env && *env) ++ { ++ if (putenv (*env) != 0) ++ xalloc_die (); ++ env++; ++ } ++} ++ ++static void ++create_watching_parent (void) ++{ ++ pid_t child; ++ sigset_t ourset; ++ int status = 0; ++ ++ retval = pam_open_session (pamh, 0); ++ if (retval != PAM_SUCCESS) ++ { ++ cleanup_pam (retval); ++ error (EXIT_FAILURE, 0, _("cannot not open session: %s"), ++ pam_strerror (pamh, retval)); ++ } ++ else ++ _pam_session_opened = 1; ++ ++ child = fork (); ++ if (child == (pid_t) -1) ++ { ++ cleanup_pam (PAM_ABORT); ++ error (EXIT_FAILURE, errno, _("cannot create child process")); ++ } ++ ++ /* the child proceeds to run the shell */ ++ if (child == 0) ++ return; ++ ++ /* In the parent watch the child. */ ++ ++ /* su without pam support does not have a helper that keeps ++ sitting on any directory so let's go to /. */ ++ if (chdir ("/") != 0) ++ error (0, errno, _("warning: cannot change directory to %s"), "/"); ++ ++ sigfillset (&ourset); ++ if (sigprocmask (SIG_BLOCK, &ourset, NULL)) ++ { ++ error (0, errno, _("cannot block signals")); ++ caught_signal = true; ++ } ++ if (!caught_signal) ++ { ++ struct sigaction action; ++ action.sa_handler = su_catch_sig; ++ sigemptyset (&action.sa_mask); ++ action.sa_flags = 0; ++ sigemptyset (&ourset); ++ if (sigaddset (&ourset, SIGTERM) ++ || sigaddset (&ourset, SIGALRM) ++ || sigaction (SIGTERM, &action, NULL) ++ || sigprocmask (SIG_UNBLOCK, &ourset, NULL)) ++ { ++ error (0, errno, _("cannot set signal handler")); ++ caught_signal = true; ++ } ++ } ++ if (!caught_signal) ++ { ++ pid_t pid; ++ for (;;) ++ { ++ pid = waitpid (child, &status, WUNTRACED); ++ ++ if (pid != (pid_t)-1 && WIFSTOPPED (status)) ++ { ++ kill (getpid (), SIGSTOP); ++ /* once we get here, we must have resumed */ ++ kill (pid, SIGCONT); ++ } ++ else ++ break; ++ } ++ if (pid != (pid_t)-1) ++ if (WIFSIGNALED (status)) ++ status = WTERMSIG (status) + 128; ++ else ++ status = WEXITSTATUS (status); ++ else ++ status = 1; ++ } ++ else ++ status = 1; ++ ++ if (caught_signal) ++ { ++ fprintf (stderr, _("\nSession terminated, killing shell...")); ++ kill (child, SIGTERM); ++ } ++ ++ cleanup_pam (PAM_SUCCESS); ++ ++ if (caught_signal) ++ { ++ sleep (2); ++ kill (child, SIGKILL); ++ fprintf (stderr, _(" ...killed.\n")); ++ } ++ exit (status); ++} ++#endif ++ + /* Ask the user for a password. ++ If PAM is in use, let PAM ask for the password if necessary. + Return true if the user gives the correct password for entry PW, + false if not. Return true without asking for a password if run by UID 0 + or if PW has an empty password. */ +@@ -208,10 +389,52 @@ log_su (struct passwd const *pw, bool successful) + static bool + correct_password (const struct passwd *pw) + { ++#ifdef USE_PAM ++ const struct passwd *lpw; ++ const char *cp; ++ ++ retval = pam_start (simulate_login ? PAM_SERVICE_NAME_L : PAM_SERVICE_NAME, ++ pw->pw_name, &conv, &pamh); ++ PAM_BAIL_P (return false); ++ ++ if (isatty (0) && (cp = ttyname (0)) != NULL) ++ { ++ const char *tty; ++ ++ if (strncmp (cp, "/dev/", 5) == 0) ++ tty = cp + 5; ++ else ++ tty = cp; ++ retval = pam_set_item (pamh, PAM_TTY, tty); ++ PAM_BAIL_P (return false); ++ } ++#if 0 /* Manpage discourages use of getlogin. */ ++ cp = getlogin (); ++ if (!(cp && *cp && (lpw = getpwnam (cp)) != NULL && lpw->pw_uid == getuid ())) ++#endif ++ lpw = getpwuid (getuid ()); ++ if (lpw && lpw->pw_name) ++ { ++ retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name); ++ PAM_BAIL_P (return false); ++ } ++ retval = pam_authenticate (pamh, 0); ++ PAM_BAIL_P (return false); ++ retval = pam_acct_mgmt (pamh, 0); ++ if (retval == PAM_NEW_AUTHTOK_REQD) ++ { ++ /* Password has expired. Offer option to change it. */ ++ retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); ++ PAM_BAIL_P (return false); ++ } ++ PAM_BAIL_P (return false); ++ /* Must be authenticated if this point was reached. */ ++ return true; ++#else /* !USE_PAM */ + char *unencrypted, *encrypted, *correct; + #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP + /* Shadow passwd stuff for SVR3 and maybe other systems. */ +- struct spwd *sp = getspnam (pw->pw_name); ++ const struct spwd *sp = getspnam (pw->pw_name); + + endspent (); + if (sp) +@@ -232,6 +455,7 @@ correct_password (const struct passwd *pw) + encrypted = crypt (unencrypted, correct); + memset (unencrypted, 0, strlen (unencrypted)); + return STREQ (encrypted, correct); ++#endif /* !USE_PAM */ + } + + /* Update `environ' for the new shell based on PW, with SHELL being +@@ -274,19 +498,41 @@ modify_environment (const struct passwd *pw, const char *shell) + } + } + } ++ ++#ifdef USE_PAM ++ export_pamenv (); ++#endif + } + + /* Become the user and group(s) specified by PW. */ + + static void +-change_identity (const struct passwd *pw) ++init_groups (const struct passwd *pw) + { + #ifdef HAVE_INITGROUPS + errno = 0; + if (initgroups (pw->pw_name, pw->pw_gid) == -1) +- error (EXIT_CANCELED, errno, _("cannot set groups")); ++ { ++#ifdef USE_PAM ++ cleanup_pam (PAM_ABORT); ++#endif ++ error (EXIT_FAILURE, errno, _("cannot set groups")); ++ } + endgrent (); + #endif ++ ++#ifdef USE_PAM ++ retval = pam_setcred (pamh, PAM_ESTABLISH_CRED); ++ if (retval != PAM_SUCCESS) ++ error (EXIT_FAILURE, 0, "%s", pam_strerror (pamh, retval)); ++ else ++ _pam_cred_established = 1; ++#endif ++} ++ ++static void ++change_identity (const struct passwd *pw) ++{ + if (setgid (pw->pw_gid)) + error (EXIT_CANCELED, errno, _("cannot set group id")); + if (setuid (pw->pw_uid)) +@@ -500,9 +746,21 @@ main (int argc, char **argv) + shell = NULL; + } + shell = xstrdup (shell ? shell : pw->pw_shell); +- modify_environment (pw, shell); ++ ++ init_groups (pw); ++ ++#ifdef USE_PAM ++ create_watching_parent (); ++ /* Now we're in the child. */ ++#endif + + change_identity (pw); ++ ++ /* Set environment after pam_open_session, which may put KRB5CCNAME ++ into the pam_env, etc. */ ++ ++ modify_environment (pw, shell); ++ + if (simulate_login && chdir (pw->pw_dir) != 0) + error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); + +-- +1.7.1 +diff -urNp coreutils-8.7-orig/doc/coreutils.texi coreutils-8.7/doc/coreutils.texi +--- coreutils-8.7-orig/doc/coreutils.texi 2010-11-15 12:47:03.529922880 +0100 ++++ coreutils-8.7/doc/coreutils.texi 2010-11-15 12:49:55.945171380 +0100 +@@ -15180,7 +15180,9 @@ the exit status of @var{command} otherwi + + @command{su} allows one user to temporarily become another user. It runs a + command (often an interactive shell) with the real and effective user +-ID, group ID, and supplemental groups of a given @var{user}. Synopsis: ++ID, group ID, and supplemental groups of a given @var{user}. When the -l ++option is given, the su-l PAM file is used instead of the default su PAM file. ++Synopsis: + + @example + su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}] +@@ -15259,7 +15261,8 @@ environment variables except @env{TERM}, + (which are set, even for the super-user, as described above), and set + @env{PATH} to a compiled-in default value. Change to @var{user}'s home + directory. Prepend @samp{-} to the shell's name, intended to make it +-read its login startup file(s). ++read its login startup file(s). When this option is given, /etc/pam.d/su-l ++PAM file is used instead of the default one. + + @item -m + @itemx -p diff --git a/coreutils-5.2.1-runuser.patch b/coreutils-8.7-runuser.patch similarity index 62% rename from coreutils-5.2.1-runuser.patch rename to coreutils-8.7-runuser.patch index 640b230..6692a3e 100644 --- a/coreutils-5.2.1-runuser.patch +++ b/coreutils-8.7-runuser.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.1-orig/AUTHORS coreutils-8.1/AUTHORS ---- coreutils-8.1-orig/AUTHORS 2009-11-06 18:04:10.000000000 +0100 -+++ coreutils-8.1/AUTHORS 2009-11-20 13:06:26.000000000 +0100 +diff -urNp coreutils-8.7-orig/AUTHORS coreutils-8.7/AUTHORS +--- coreutils-8.7-orig/AUTHORS 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/AUTHORS 2010-11-15 10:08:04.222078001 +0100 @@ -65,6 +65,7 @@ readlink: Dmitry V. Levin rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering rmdir: David MacKenzie @@ -9,10 +9,10 @@ diff -urNp coreutils-8.1-orig/AUTHORS coreutils-8.1/AUTHORS seq: Ulrich Drepper sha1sum: Ulrich Drepper, Scott Miller, David Madore sha224sum: Ulrich Drepper, Scott Miller, David Madore -diff -urNp coreutils-8.1-orig/man/help2man coreutils-8.1/man/help2man ---- coreutils-8.1-orig/man/help2man 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.1/man/help2man 2009-11-20 13:06:26.000000000 +0100 -@@ -556,6 +556,9 @@ while (length) +diff -urNp coreutils-8.7-orig/man/help2man coreutils-8.7/man/help2man +--- coreutils-8.7-orig/man/help2man 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/man/help2man 2010-11-15 10:08:51.331054884 +0100 +@@ -555,6 +555,9 @@ while (length) $include{$sect} .= $content; } @@ -22,9 +22,9 @@ diff -urNp coreutils-8.1-orig/man/help2man coreutils-8.1/man/help2man # Refer to the real documentation. unless ($opt_no_info) { -diff -urNp coreutils-8.1-orig/man/Makefile.am coreutils-8.1/man/Makefile.am ---- coreutils-8.1-orig/man/Makefile.am 2009-11-06 18:04:10.000000000 +0100 -+++ coreutils-8.1/man/Makefile.am 2009-11-20 13:06:26.000000000 +0100 +diff -urNp coreutils-8.7-orig/man/Makefile.am coreutils-8.7/man/Makefile.am +--- coreutils-8.7-orig/man/Makefile.am 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/man/Makefile.am 2010-11-15 10:09:21.768922182 +0100 @@ -94,6 +94,7 @@ readlink.1: $(common_dep) $(srcdir)/read rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c @@ -33,9 +33,9 @@ diff -urNp coreutils-8.1-orig/man/Makefile.am coreutils-8.1/man/Makefile.am seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c -diff -urNp coreutils-8.1-orig/man/runuser.x coreutils-8.1/man/runuser.x ---- coreutils-8.1-orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.1/man/runuser.x 2009-11-20 13:06:26.000000000 +0100 +diff -urNp coreutils-8.7-orig/man/runuser.x coreutils-8.7/man/runuser.x +--- coreutils-8.7-orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.7/man/runuser.x 2010-11-15 10:09:57.437939015 +0100 @@ -0,0 +1,12 @@ +[NAME] +runuser \- run a shell with substitute user and group IDs @@ -49,9 +49,9 @@ diff -urNp coreutils-8.1-orig/man/runuser.x coreutils-8.1/man/runuser.x +.TP +since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR. +.br -diff -urNp coreutils-8.1-orig/README coreutils-8.1/README ---- coreutils-8.1-orig/README 2009-11-06 18:04:10.000000000 +0100 -+++ coreutils-8.1/README 2009-11-20 13:06:26.000000000 +0100 +diff -urNp coreutils-8.7-orig/README coreutils-8.7/README +--- coreutils-8.7-orig/README 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/README 2010-11-15 10:10:43.002922253 +0100 @@ -12,10 +12,10 @@ The programs that can be built with this factor false fmt fold groups head hostid hostname id install join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup @@ -67,29 +67,29 @@ diff -urNp coreutils-8.1-orig/README coreutils-8.1/README See the file NEWS for a list of major changes in the current release. -diff -urNp coreutils-8.1-orig/src/Makefile.am coreutils-8.1/src/Makefile.am ---- coreutils-8.1-orig/src/Makefile.am 2009-11-20 13:06:00.000000000 +0100 -+++ coreutils-8.1/src/Makefile.am 2009-11-20 13:06:26.000000000 +0100 +diff -urNp coreutils-8.7-orig/src/Makefile.am coreutils-8.7/src/Makefile.am +--- coreutils-8.7-orig/src/Makefile.am 2010-11-15 10:07:07.339171659 +0100 ++++ coreutils-8.7/src/Makefile.am 2010-11-15 10:12:14.847094550 +0100 @@ -100,6 +100,7 @@ EXTRA_PROGRAMS = \ rm \ rmdir \ runcon \ -+ runuser \ ++ runuser \ seq \ sha1sum \ sha224sum \ -@@ -296,6 +297,10 @@ cp_LDADD += $(copy_LDADD) +@@ -300,6 +301,10 @@ cp_LDADD += $(copy_LDADD) ginstall_LDADD += $(copy_LDADD) mv_LDADD += $(copy_LDADD) +runuser_SOURCES = su.c +runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\"" -+runuser_LDADD = $(LDADD) $(LIB_CRYPT) @LIB_PAM@ ++runuser_LDADD = $(LDADD) $(LIB_CRYPT) $(PAM_LIBS) + remove_LDADD = mv_LDADD += $(remove_LDADD) rm_LDADD += $(remove_LDADD) -@@ -396,7 +401,7 @@ RELEASE_YEAR = \ +@@ -395,7 +400,7 @@ RELEASE_YEAR = \ `sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \ $(top_srcdir)/lib/version-etc.c` @@ -98,10 +98,10 @@ diff -urNp coreutils-8.1-orig/src/Makefile.am coreutils-8.1/src/Makefile.am installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'` -diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c ---- coreutils-8.1-orig/src/su.c 2009-11-20 13:06:00.000000000 +0100 -+++ coreutils-8.1/src/su.c 2009-11-20 13:06:26.000000000 +0100 -@@ -102,9 +102,15 @@ +diff -urNp coreutils-8.7-orig/src/su.c coreutils-8.7/src/su.c +--- coreutils-8.7-orig/src/su.c 2010-11-15 10:07:07.372933288 +0100 ++++ coreutils-8.7/src/su.c 2010-11-15 10:42:12.569159230 +0100 +@@ -100,9 +100,15 @@ #include "error.h" /* The official name of this program (e.g., no `g' prefix). */ @@ -117,7 +117,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c #if HAVE_PATHS_H # include -@@ -142,9 +148,16 @@ +@@ -140,6 +146,9 @@ #ifndef USE_PAM char *crypt (char const *key, char const *salt); #endif @@ -125,17 +125,9 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c +#define CHECKPASSWD 1 +#endif - static void run_shell (char const *, char const *, char **, size_t, -- const struct passwd *) -+ const struct passwd * -+#ifdef RUNUSER -+ , gid_t *groups, int num_groups -+#endif -+ ) - #ifdef USE_PAM - ; - #else -@@ -171,6 +184,10 @@ static struct option const longopts[] = + static void run_shell (char const *, char const *, char **, size_t) + ATTRIBUTE_NORETURN; +@@ -169,6 +178,10 @@ static struct option const longopts[] = {"login", no_argument, NULL, 'l'}, {"preserve-environment", no_argument, NULL, 'p'}, {"shell", required_argument, NULL, 's'}, @@ -146,45 +138,27 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -272,10 +289,12 @@ correct_password (const struct passwd *p - retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh); - PAM_BAIL_P; - -+#ifndef RUNUSER - if (getuid() != 0 && !isatty(0)) { - fprintf(stderr, "standard in must be a tty\n"); - exit(1); - } -+#endif - - caller = getpwuid(getuid()); - if(caller != NULL && caller->pw_name != NULL) { -@@ -292,6 +311,11 @@ correct_password (const struct passwd *p - retval = pam_set_item(pamh, PAM_TTY, tty_name); - PAM_BAIL_P; - } +@@ -444,8 +457,14 @@ correct_password (const struct passwd *p + retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name); + PAM_BAIL_P (return false); + } +#ifdef RUNUSER + if (getuid() != geteuid()) + /* safety net: deny operation if we are suid by accident */ + error(EXIT_FAILURE, 1, "runuser may not be setuid"); +#else - retval = pam_authenticate(pamh, 0); - PAM_BAIL_P; - retval = pam_acct_mgmt(pamh, 0); -@@ -301,6 +325,7 @@ correct_password (const struct passwd *p - PAM_BAIL_P; - } - PAM_BAIL_P; + retval = pam_authenticate (pamh, 0); + PAM_BAIL_P (return false); +#endif - /* must be authenticated if this point was reached */ - return 1; - #else /* !USE_PAM */ -@@ -382,11 +407,22 @@ modify_environment (const struct passwd + retval = pam_acct_mgmt (pamh, 0); + if (retval == PAM_NEW_AUTHTOK_REQD) + { +@@ -533,11 +552,22 @@ modify_environment (const struct passwd /* Become the user and group(s) specified by PW. */ static void --change_identity (const struct passwd *pw) -+change_identity (const struct passwd *pw +-init_groups (const struct passwd *pw) ++init_groups (const struct passwd *pw +#ifdef RUNUSER + , gid_t *groups, int num_groups +#endif @@ -193,44 +167,18 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c #ifdef HAVE_INITGROUPS + int rc = 0; errno = 0; -- if (initgroups (pw->pw_name, pw->pw_gid) == -1) { +- if (initgroups (pw->pw_name, pw->pw_gid) == -1) +#ifdef RUNUSER + if (num_groups) + rc = setgroups(num_groups, groups); + else +#endif + rc = initgroups(pw->pw_name, pw->pw_gid); -+ if (rc == -1) { ++ if (rc == -1) + { #ifdef USE_PAM - pam_close_session(pamh, 0); - pam_end(pamh, PAM_ABORT); -@@ -433,7 +469,11 @@ pam_copyenv (pam_handle_t *pamh) - - static void - run_shell (char const *shell, char const *command, char **additional_args, -- size_t n_additional_args, const struct passwd *pw) -+ size_t n_additional_args, const struct passwd *pw -+#ifdef RUNUSER -+ , gid_t *groups, int num_groups -+#endif -+ ) - { - size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; - char const **args = xnmalloc (n_args, sizeof *args); -@@ -464,7 +504,11 @@ run_shell (char const *shell, char const - - child = fork(); - if (child == 0) { /* child shell */ -- change_identity (pw); -+ change_identity (pw -+#ifdef RUNUSER -+ , groups, num_groups -+#endif -+ ); - pam_end(pamh, 0); - if (!same_session) - setsid (); -@@ -608,6 +652,28 @@ usage (int status) + cleanup_pam (PAM_ABORT); +@@ -639,6 +669,28 @@ usage (int status) else { printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name); @@ -259,7 +207,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c fputs (_("\ Change the effective user id and group id to that of USER.\n\ \n\ -@@ -620,6 +686,7 @@ Change the effective user id and group i +@@ -651,6 +703,7 @@ Change the effective user id and group i -p same as -m\n\ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ "), stdout); @@ -267,7 +215,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_("\ -@@ -641,6 +708,12 @@ main (int argc, char **argv) +@@ -672,6 +725,12 @@ main (int argc, char **argv) char *shell = NULL; struct passwd *pw; struct passwd pw_copy; @@ -280,7 +228,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -655,7 +728,11 @@ main (int argc, char **argv) +@@ -686,7 +745,11 @@ main (int argc, char **argv) simulate_login = false; change_environment = true; @@ -293,7 +241,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c { switch (optc) { -@@ -685,6 +762,28 @@ main (int argc, char **argv) +@@ -716,6 +779,28 @@ main (int argc, char **argv) shell = optarg; break; @@ -322,7 +270,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -@@ -723,7 +822,20 @@ main (int argc, char **argv) +@@ -754,7 +839,20 @@ main (int argc, char **argv) : DEFAULT_SHELL); endpwent (); @@ -344,34 +292,23 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c { #ifdef SYSLOG_FAILURE log_su (pw, false); -@@ -755,7 +867,11 @@ main (int argc, char **argv) - modify_environment (pw, shell); +@@ -784,7 +882,11 @@ main (int argc, char **argv) + } + shell = xstrdup (shell ? shell : pw->pw_shell); - #ifndef USE_PAM -- change_identity (pw); -+ change_identity (pw +- init_groups (pw); ++ init_groups (pw +#ifdef RUNUSER + , groups, num_supp_groups +#endif -+ ); - #endif ++ ); - /* error() flushes stderr, but does not check for write failure. -@@ -766,5 +882,9 @@ main (int argc, char **argv) - if (ferror (stderr)) - exit (EXIT_CANCELED); - -- run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); -+ run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw -+#ifdef RUNUSER -+ , groups, num_supp_groups -+#endif -+ ); - } -diff -urNp coreutils-8.1-orig/tests/misc/help-version coreutils-8.1/tests/misc/help-version ---- coreutils-8.1-orig/tests/misc/help-version 2009-11-14 15:01:44.000000000 +0100 -+++ coreutils-8.1/tests/misc/help-version 2009-11-20 13:06:26.000000000 +0100 -@@ -34,6 +34,7 @@ expected_failure_status_nohup=125 + #ifdef USE_PAM + create_watching_parent (); +diff -urNp coreutils-8.7-orig/tests/misc/help-version coreutils-8.7/tests/misc/help-version +--- coreutils-8.7-orig/tests/misc/help-version 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/tests/misc/help-version 2010-11-15 10:45:18.473682325 +0100 +@@ -32,6 +32,7 @@ expected_failure_status_nohup=125 expected_failure_status_stdbuf=125 expected_failure_status_su=125 expected_failure_status_timeout=125 @@ -379,7 +316,7 @@ diff -urNp coreutils-8.1-orig/tests/misc/help-version coreutils-8.1/tests/misc/h expected_failure_status_printenv=2 expected_failure_status_tty=3 expected_failure_status_sort=2 -@@ -153,6 +154,7 @@ seq_args=10 +@@ -209,6 +210,7 @@ seq_setup () { args=10; } sleep_setup () { args=0; } su_setup () { args=--version; } stdbuf_setup () { args="-oL true"; } @@ -387,9 +324,9 @@ diff -urNp coreutils-8.1-orig/tests/misc/help-version coreutils-8.1/tests/misc/h timeout_setup () { args=--version; } # I'd rather not run sync, since it spins up disks that I've -diff -urNp coreutils-8.1-orig/tests/misc/invalid-opt coreutils-8.1/tests/misc/invalid-opt ---- coreutils-8.1-orig/tests/misc/invalid-opt 2009-10-26 10:05:25.000000000 +0100 -+++ coreutils-8.1/tests/misc/invalid-opt 2009-11-20 13:06:26.000000000 +0100 +diff -urNp coreutils-8.7-orig/tests/misc/invalid-opt coreutils-8.7/tests/misc/invalid-opt +--- coreutils-8.7-orig/tests/misc/invalid-opt 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/tests/misc/invalid-opt 2010-11-15 10:45:46.451938873 +0100 @@ -37,6 +37,7 @@ my %exit_status = sort => 2, stdbuf => 125, diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index a9a1a4c..9c85439 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,24 +1,6 @@ - lib/linebuffer.h | 8 + - src/cut.c | 420 +++++++++++++++++++++++++-- - src/expand.c | 160 ++++++++++- - src/fold.c | 309 ++++++++++++++++++-- - src/join.c | 347 +++++++++++++++++++--- - src/pr.c | 431 +++++++++++++++++++++++++--- - src/sort.c | 722 +++++++++++++++++++++++++++++++++++++++++++--- - src/unexpand.c | 226 ++++++++++++++- - src/uniq.c | 259 ++++++++++++++++- - tests/Makefile.am | 5 + - tests/misc/cut | 4 +- - tests/misc/mb1.I | 4 + - tests/misc/mb1.X | 4 + - tests/misc/mb2.I | 4 + - tests/misc/mb2.X | 4 + - tests/misc/sort-mb-tests | 58 ++++ - 16 files changed, 2783 insertions(+), 182 deletions(-) - -diff -urNp coreutils-8.6-orig/lib/linebuffer.h coreutils-8.6/lib/linebuffer.h ---- coreutils-8.6-orig/lib/linebuffer.h 2010-06-10 18:45:26.000000000 +0200 -+++ coreutils-8.6/lib/linebuffer.h 2010-10-18 15:18:11.932209034 +0200 +diff -urNp coreutils-8.7-orig/lib/linebuffer.h coreutils-8.7/lib/linebuffer.h +--- coreutils-8.7-orig/lib/linebuffer.h 2010-06-10 18:45:26.000000000 +0200 ++++ coreutils-8.7/lib/linebuffer.h 2010-11-15 09:59:36.974172148 +0100 @@ -21,6 +21,11 @@ # include @@ -41,9 +23,9 @@ diff -urNp coreutils-8.6-orig/lib/linebuffer.h coreutils-8.6/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.6-orig/src/cut.c coreutils-8.6/src/cut.c ---- coreutils-8.6-orig/src/cut.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/cut.c 2010-10-18 15:18:11.933208545 +0200 +diff -urNp coreutils-8.7-orig/src/cut.c coreutils-8.7/src/cut.c +--- coreutils-8.7-orig/src/cut.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/cut.c 2010-11-15 09:59:36.976171659 +0100 @@ -28,6 +28,11 @@ #include #include @@ -634,9 +616,9 @@ diff -urNp coreutils-8.6-orig/src/cut.c coreutils-8.6/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.6-orig/src/expand.c coreutils-8.6/src/expand.c ---- coreutils-8.6-orig/src/expand.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/expand.c 2010-10-18 15:18:11.937209243 +0200 +diff -urNp coreutils-8.7-orig/src/expand.c coreutils-8.7/src/expand.c +--- coreutils-8.7-orig/src/expand.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/expand.c 2010-11-15 09:59:36.977172637 +0100 @@ -38,12 +38,29 @@ #include #include @@ -824,9 +806,9 @@ diff -urNp coreutils-8.6-orig/src/expand.c coreutils-8.6/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.6-orig/src/fold.c coreutils-8.6/src/fold.c ---- coreutils-8.6-orig/src/fold.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/fold.c 2010-10-18 15:18:11.938208475 +0200 +diff -urNp coreutils-8.7-orig/src/fold.c coreutils-8.7/src/fold.c +--- coreutils-8.7-orig/src/fold.c 2010-10-16 13:28:01.000000000 +0200 ++++ coreutils-8.7/src/fold.c 2010-11-15 09:59:36.979181926 +0100 @@ -22,12 +22,34 @@ #include #include @@ -956,7 +938,7 @@ diff -urNp coreutils-8.6-orig/src/fold.c coreutils-8.6/src/fold.c - return false; - } - fadvise (stdin, FADVISE_SEQUENTIAL); + fadvise (istream, FADVISE_SEQUENTIAL); @@ -171,6 +199,15 @@ fold_file (char const *filename, size_t bool found_blank = false; @@ -1225,9 +1207,9 @@ diff -urNp coreutils-8.6-orig/src/fold.c coreutils-8.6/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.6-orig/src/join.c coreutils-8.6/src/join.c ---- coreutils-8.6-orig/src/join.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/join.c 2010-10-18 15:18:11.940208824 +0200 +diff -urNp coreutils-8.7-orig/src/join.c coreutils-8.7/src/join.c +--- coreutils-8.7-orig/src/join.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/join.c 2010-11-15 09:59:36.980181716 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1710,9 +1692,9 @@ diff -urNp coreutils-8.6-orig/src/join.c coreutils-8.6/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.6-orig/src/pr.c coreutils-8.6/src/pr.c ---- coreutils-8.6-orig/src/pr.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/pr.c 2010-10-18 15:18:11.942208964 +0200 +diff -urNp coreutils-8.7-orig/src/pr.c coreutils-8.7/src/pr.c +--- coreutils-8.7-orig/src/pr.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/pr.c 2010-11-15 09:59:36.983181856 +0100 @@ -312,6 +312,32 @@ #include @@ -2435,10 +2417,9 @@ diff -urNp coreutils-8.6-orig/src/pr.c coreutils-8.6/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff --git a/src/sort.c b/src/sort.c -index 7e25f6a..d3f8915 100644 ---- a/src/sort.c -+++ b/src/sort.c +diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c +--- coreutils-8.7-orig/src/sort.c 2010-10-25 12:07:57.000000000 +0200 ++++ coreutils-8.7/src/sort.c 2010-11-15 09:59:36.987932380 +0100 @@ -22,11 +22,20 @@ #include @@ -2569,7 +2550,7 @@ index 7e25f6a..d3f8915 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1220,7 +1289,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1220,7 +1289,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2587,7 +2568,7 @@ index 7e25f6a..d3f8915 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1314,6 +1383,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1314,6 +1383,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2672,7 +2653,7 @@ index 7e25f6a..d3f8915 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1540,7 +1687,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1540,7 +1687,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2681,7 +2662,7 @@ index 7e25f6a..d3f8915 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1549,10 +1696,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1549,10 +1696,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2694,7 +2675,7 @@ index 7e25f6a..d3f8915 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1578,11 +1725,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1578,11 +1725,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2766,7 +2747,7 @@ index 7e25f6a..d3f8915 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1597,10 +1803,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1597,10 +1803,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. */ @@ -2779,7 +2760,7 @@ index 7e25f6a..d3f8915 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1646,10 +1852,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1646,10 +1852,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2792,7 +2773,7 @@ index 7e25f6a..d3f8915 100644 if (newlim) lim = newlim; } -@@ -1680,6 +1886,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1680,6 +1886,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2923,7 +2904,7 @@ index 7e25f6a..d3f8915 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1766,8 +2096,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1766,8 +2096,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2948,7 +2929,7 @@ index 7e25f6a..d3f8915 100644 line->keybeg = line_start; } } -@@ -1888,7 +2232,7 @@ human_numcompare (char const *a, char const *b) +@@ -1888,7 +2232,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2957,7 +2938,7 @@ index 7e25f6a..d3f8915 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -1898,6 +2242,25 @@ numcompare (char const *a, char const *b) +@@ -1898,6 +2242,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2983,7 +2964,7 @@ index 7e25f6a..d3f8915 100644 static int general_numcompare (char const *sa, char const *sb) { -@@ -1930,7 +2293,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -1930,7 +2293,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -2992,7 +2973,7 @@ index 7e25f6a..d3f8915 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2204,13 +2567,12 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2204,13 +2567,12 @@ debug_key (struct line const *line, stru { char saved = *lim; *lim = '\0'; @@ -3008,7 +2989,7 @@ index 7e25f6a..d3f8915 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2354,7 +2716,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2354,7 +2716,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3017,7 +2998,7 @@ index 7e25f6a..d3f8915 100644 && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2412,11 +2774,83 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2412,11 +2774,83 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option `-r' only applies to last-resort comparison")); } @@ -3102,7 +3083,7 @@ index 7e25f6a..d3f8915 100644 { struct keyfield *key = keylist; -@@ -2501,7 +2935,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2501,7 +2935,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3111,7 +3092,7 @@ index 7e25f6a..d3f8915 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2617,6 +3051,179 @@ keycompare (struct line const *a, struct line const *b) +@@ -2617,6 +3051,179 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3384,9 +3365,9 @@ index 7e25f6a..d3f8915 100644 } break; -diff -urNp coreutils-8.6-orig/src/unexpand.c coreutils-8.6/src/unexpand.c ---- coreutils-8.6-orig/src/unexpand.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/unexpand.c 2010-10-18 15:18:11.949208684 +0200 +diff -urNp coreutils-8.7-orig/src/unexpand.c coreutils-8.7/src/unexpand.c +--- coreutils-8.7-orig/src/unexpand.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/unexpand.c 2010-11-15 09:59:36.989931891 +0100 @@ -39,12 +39,29 @@ #include #include @@ -3640,9 +3621,9 @@ diff -urNp coreutils-8.6-orig/src/unexpand.c coreutils-8.6/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.6-orig/src/uniq.c coreutils-8.6/src/uniq.c ---- coreutils-8.6-orig/src/uniq.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/uniq.c 2010-10-18 15:18:11.950208754 +0200 +diff -urNp coreutils-8.7-orig/src/uniq.c coreutils-8.7/src/uniq.c +--- coreutils-8.7-orig/src/uniq.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/uniq.c 2010-11-15 09:59:36.992922043 +0100 @@ -21,6 +21,16 @@ #include #include @@ -4009,10 +3990,10 @@ diff -urNp coreutils-8.6-orig/src/uniq.c coreutils-8.6/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.6-orig/tests/Makefile.am coreutils-8.6/tests/Makefile.am ---- coreutils-8.6-orig/tests/Makefile.am 2010-10-18 15:17:40.112459208 +0200 -+++ coreutils-8.6/tests/Makefile.am 2010-10-18 15:18:11.957208754 +0200 -@@ -229,6 +229,7 @@ TESTS = \ +diff -urNp coreutils-8.7-orig/tests/Makefile.am coreutils-8.7/tests/Makefile.am +--- coreutils-8.7-orig/tests/Makefile.am 2010-11-15 09:58:44.197937898 +0100 ++++ coreutils-8.7/tests/Makefile.am 2010-11-15 09:59:36.993932170 +0100 +@@ -231,6 +231,7 @@ TESTS = \ misc/sort-debug-keys \ misc/sort-debug-warn \ misc/sort-files0-from \ @@ -4020,7 +4001,7 @@ diff -urNp coreutils-8.6-orig/tests/Makefile.am coreutils-8.6/tests/Makefile.am misc/sort-float \ misc/sort-merge \ misc/sort-merge-fdlimit \ -@@ -486,6 +487,10 @@ TESTS = \ +@@ -490,6 +491,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -4031,9 +4012,9 @@ diff -urNp coreutils-8.6-orig/tests/Makefile.am coreutils-8.6/tests/Makefile.am pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.6-orig/tests/misc/cut coreutils-8.6/tests/misc/cut ---- coreutils-8.6-orig/tests/misc/cut 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/tests/misc/cut 2010-10-18 15:18:11.957208754 +0200 +diff -urNp coreutils-8.7-orig/tests/misc/cut coreutils-8.7/tests/misc/cut +--- coreutils-8.7-orig/tests/misc/cut 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/tests/misc/cut 2010-11-15 09:59:36.994932100 +0100 @@ -26,7 +26,7 @@ use strict; my $prog = 'cut'; my $try = "Try \`$prog --help' for more information.\n"; @@ -4052,41 +4033,41 @@ diff -urNp coreutils-8.6-orig/tests/misc/cut coreutils-8.6/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], -diff -urNp coreutils-8.6-orig/tests/misc/mb1.I coreutils-8.6/tests/misc/mb1.I ---- coreutils-8.6-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.6/tests/misc/mb1.I 2010-10-18 15:18:11.958209243 +0200 +diff -urNp coreutils-8.7-orig/tests/misc/mb1.I coreutils-8.7/tests/misc/mb1.I +--- coreutils-8.7-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.7/tests/misc/mb1.I 2010-11-15 09:59:36.995931961 +0100 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.6-orig/tests/misc/mb1.X coreutils-8.6/tests/misc/mb1.X ---- coreutils-8.6-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.6/tests/misc/mb1.X 2010-10-18 15:18:11.958209243 +0200 +diff -urNp coreutils-8.7-orig/tests/misc/mb1.X coreutils-8.7/tests/misc/mb1.X +--- coreutils-8.7-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.7/tests/misc/mb1.X 2010-11-15 09:59:36.995931961 +0100 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.6-orig/tests/misc/mb2.I coreutils-8.6/tests/misc/mb2.I ---- coreutils-8.6-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.6/tests/misc/mb2.I 2010-10-18 15:18:11.959208405 +0200 +diff -urNp coreutils-8.7-orig/tests/misc/mb2.I coreutils-8.7/tests/misc/mb2.I +--- coreutils-8.7-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.7/tests/misc/mb2.I 2010-11-15 09:59:36.996933777 +0100 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.6-orig/tests/misc/mb2.X coreutils-8.6/tests/misc/mb2.X ---- coreutils-8.6-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.6/tests/misc/mb2.X 2010-10-18 15:18:11.960208894 +0200 +diff -urNp coreutils-8.7-orig/tests/misc/mb2.X coreutils-8.7/tests/misc/mb2.X +--- coreutils-8.7-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.7/tests/misc/mb2.X 2010-11-15 09:59:36.997922462 +0100 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.6-orig/tests/misc/sort-mb-tests coreutils-8.6/tests/misc/sort-mb-tests ---- coreutils-8.6-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.6/tests/misc/sort-mb-tests 2010-10-18 15:18:11.960208894 +0200 +diff -urNp coreutils-8.7-orig/tests/misc/sort-mb-tests coreutils-8.7/tests/misc/sort-mb-tests +--- coreutils-8.7-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.7/tests/misc/sort-mb-tests 2010-11-15 09:59:36.997922462 +0100 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils-pam.patch b/coreutils-pam.patch deleted file mode 100644 index 01face6..0000000 --- a/coreutils-pam.patch +++ /dev/null @@ -1,428 +0,0 @@ -diff -urNp coreutils-8.4-orig/configure.ac coreutils-8.4/configure.ac ---- coreutils-8.4-orig/configure.ac 2010-01-11 18:20:42.000000000 +0100 -+++ coreutils-8.4/configure.ac 2010-02-12 10:17:46.000000000 +0100 -@@ -126,6 +126,13 @@ if test "$gl_gcc_warnings" = yes; then - AC_SUBST([GNULIB_TEST_WARN_CFLAGS]) - fi - -+dnl Give the chance to enable PAM -+AC_ARG_ENABLE(pam, dnl -+[ --enable-pam Enable use of the PAM libraries], -+[AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) -+LIB_PAM="-ldl -lpam -lpam_misc" -+AC_SUBST(LIB_PAM)]) -+ - AC_FUNC_FORK - - optional_bin_progs= -diff -urNp coreutils-8.4-orig/doc/coreutils.texi coreutils-8.4/doc/coreutils.texi ---- coreutils-8.4-orig/doc/coreutils.texi 2010-01-03 18:06:20.000000000 +0100 -+++ coreutils-8.4/doc/coreutils.texi 2010-02-12 10:17:46.000000000 +0100 -@@ -15081,8 +15081,11 @@ to certain shells, etc.). - @findex syslog - @command{su} can optionally be compiled to use @code{syslog} to report - failed, and optionally successful, @command{su} attempts. (If the system --supports @code{syslog}.) However, GNU @command{su} does not check if the --user is a member of the @code{wheel} group; see below. -+supports @code{syslog}.) -+ -+This version of @command{su} has support for using PAM for -+authentication. You can edit @file{/etc/pam.d/su} to customize its -+behaviour. - - The program accepts the following options. Also see @ref{Common options}. - -@@ -15124,6 +15127,8 @@ environment variables except @env{TERM}, - @env{PATH} to a compiled-in default value. Change to @var{user}'s home - directory. Prepend @samp{-} to the shell's name, intended to make it - read its login startup file(s). -+Additionaly @env{DISPLAY} and @env{XAUTHORITY} environment variables -+are preserved as well for PAM functionality. - - @item -m - @itemx -p -@@ -15163,33 +15168,6 @@ Exit status: - the exit status of the subshell otherwise - @end display - --@cindex wheel group, not supported --@cindex group wheel, not supported --@cindex fascism --@subsection Why GNU @command{su} does not support the @samp{wheel} group -- --(This section is by Richard Stallman.) -- --@cindex Twenex --@cindex MIT AI lab --Sometimes a few of the users try to hold total power over all the --rest. For example, in 1984, a few users at the MIT AI lab decided to --seize power by changing the operator password on the Twenex system and --keeping it secret from everyone else. (I was able to thwart this coup --and give power back to the users by patching the kernel, but I --wouldn't know how to do that in Unix.) -- --However, occasionally the rulers do tell someone. Under the usual --@command{su} mechanism, once someone learns the root password who --sympathizes with the ordinary users, he or she can tell the rest. The --``wheel group'' feature would make this impossible, and thus cement the --power of the rulers. -- --I'm on the side of the masses, not that of the rulers. If you are --used to supporting the bosses and sysadmins in whatever they do, you --might find this idea strange at first. -- -- - @node timeout invocation - @section @command{timeout}: Run a command with a time limit - -diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am ---- coreutils-8.4-orig/src/Makefile.am 2010-01-03 18:06:20.000000000 +0100 -+++ coreutils-8.4/src/Makefile.am 2010-02-12 10:17:46.000000000 +0100 -@@ -361,7 +361,7 @@ factor_LDADD += $(LIB_GMP) - uptime_LDADD += $(GETLOADAVG_LIBS) - - # for crypt --su_LDADD += $(LIB_CRYPT) -+su_LDADD += $(LIB_CRYPT) @LIB_PAM@ - - # for various ACL functions - copy_LDADD += $(LIB_ACL) -diff -urNp coreutils-8.4-orig/src/su.c coreutils-8.4/src/su.c ---- coreutils-8.4-orig/src/su.c 2010-02-12 10:15:15.000000000 +0100 -+++ coreutils-8.4/src/su.c 2010-02-12 10:24:29.000000000 +0100 -@@ -37,6 +37,16 @@ - restricts who can su to UID 0 accounts. RMS considers that to - be fascist. - -+#ifdef USE_PAM -+ -+ Actually, with PAM, su has nothing to do with whether or not a -+ wheel group is enforced by su. RMS tries to restrict your access -+ to a su which implements the wheel group, but PAM considers that -+ to be fascist, and gives the user/sysadmin the opportunity to -+ enforce a wheel group by proper editing of /etc/pam.conf -+ -+#endif -+ - Compile-time options: - -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. - -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. -@@ -53,6 +63,15 @@ - #include - #include - -+#ifdef USE_PAM -+# include -+# include -+# include -+# include -+# include -+# include -+#endif /* USE_PAM */ -+ - #include "system.h" - #include "getpass.h" - -@@ -120,10 +139,17 @@ - /* The user to become if none is specified. */ - #define DEFAULT_USER "root" - -+#ifndef USE_PAM - char *crypt (char const *key, char const *salt); -+#endif - --static void run_shell (char const *, char const *, char **, size_t) -+static void run_shell (char const *, char const *, char **, size_t, -+ const struct passwd *) -+#ifdef USE_PAM -+ ; -+#else - ATTRIBUTE_NORETURN; -+#endif - - /* If true, pass the `-f' option to the subshell. */ - static bool fast_startup; -@@ -209,7 +235,26 @@ log_su (struct passwd const *pw, bool su - } - #endif - -+#ifdef USE_PAM -+static pam_handle_t *pamh = NULL; -+static int retval; -+static struct pam_conv conv = { -+ misc_conv, -+ NULL -+}; -+ -+#define PAM_BAIL_P if (retval) { \ -+ pam_end(pamh, PAM_SUCCESS); \ -+ return 0; \ -+} -+#define PAM_BAIL_P_VOID if (retval) { \ -+ pam_end(pamh, PAM_SUCCESS); \ -+return; \ -+} -+#endif -+ - /* Ask the user for a password. -+ If PAM is in use, let PAM ask for the password if necessary. - Return true if the user gives the correct password for entry PW, - false if not. Return true without asking for a password if run by UID 0 - or if PW has an empty password. */ -@@ -217,6 +262,44 @@ log_su (struct passwd const *pw, bool su - static bool - correct_password (const struct passwd *pw) - { -+#ifdef USE_PAM -+ struct passwd *caller; -+ char *tty_name, *ttyn; -+ retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh); -+ PAM_BAIL_P; -+ -+ if (getuid() != 0 && !isatty(0)) { -+ fprintf(stderr, "standard in must be a tty\n"); -+ exit(1); -+ } -+ -+ caller = getpwuid(getuid()); -+ if(caller != NULL && caller->pw_name != NULL) { -+ retval = pam_set_item(pamh, PAM_RUSER, caller->pw_name); -+ PAM_BAIL_P; -+ } -+ -+ ttyn = ttyname(0); -+ if (ttyn) { -+ if (strncmp(ttyn, "/dev/", 5) == 0) -+ tty_name = ttyn+5; -+ else -+ tty_name = ttyn; -+ retval = pam_set_item(pamh, PAM_TTY, tty_name); -+ PAM_BAIL_P; -+ } -+ retval = pam_authenticate(pamh, 0); -+ PAM_BAIL_P; -+ retval = pam_acct_mgmt(pamh, 0); -+ if (retval == PAM_NEW_AUTHTOK_REQD) { -+ /* password has expired. Offer option to change it. */ -+ retval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); -+ PAM_BAIL_P; -+ } -+ PAM_BAIL_P; -+ /* must be authenticated if this point was reached */ -+ return 1; -+#else /* !USE_PAM */ - char *unencrypted, *encrypted, *correct; - #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP - /* Shadow passwd stuff for SVR3 and maybe other systems. */ -@@ -241,6 +324,7 @@ correct_password (const struct passwd *p - encrypted = crypt (unencrypted, correct); - memset (unencrypted, 0, strlen (unencrypted)); - return STREQ (encrypted, correct); -+#endif /* !USE_PAM */ - } - - /* Update `environ' for the new shell based on PW, with SHELL being -@@ -254,12 +338,18 @@ modify_environment (const struct passwd - /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. - Unset all other environment variables. */ - char const *term = getenv ("TERM"); -+ char const *display = getenv ("DISPLAY"); -+ char const *xauthority = getenv ("XAUTHORITY"); - if (term) - term = xstrdup (term); - environ = xmalloc ((6 + !!term) * sizeof (char *)); - environ[0] = NULL; - if (term) - xsetenv ("TERM", term); -+ if (display) -+ xsetenv ("DISPLAY", display); -+ if (xauthority) -+ xsetenv ("XAUTHORITY", xauthority); - xsetenv ("HOME", pw->pw_dir); - xsetenv ("SHELL", shell); - xsetenv ("USER", pw->pw_name); -@@ -292,8 +382,13 @@ change_identity (const struct passwd *pw - { - #ifdef HAVE_INITGROUPS - errno = 0; -- if (initgroups (pw->pw_name, pw->pw_gid) == -1) -+ if (initgroups (pw->pw_name, pw->pw_gid) == -1) { -+#ifdef USE_PAM -+ pam_close_session(pamh, 0); -+ pam_end(pamh, PAM_ABORT); -+#endif - error (EXIT_CANCELED, errno, _("cannot set groups")); -+ } - endgrent (); - #endif - if (setgid (pw->pw_gid)) -@@ -302,6 +397,31 @@ change_identity (const struct passwd *pw - error (EXIT_CANCELED, errno, _("cannot set user id")); - } - -+#ifdef USE_PAM -+static int caught=0; -+/* Signal handler for parent process later */ -+static void su_catch_sig(int sig) -+{ -+ ++caught; -+} -+ -+int -+pam_copyenv (pam_handle_t *pamh) -+{ -+ char **env; -+ -+ env = pam_getenvlist(pamh); -+ if(env) { -+ while(*env) { -+ if (putenv (*env)) -+ xalloc_die (); -+ env++; -+ } -+ } -+ return(0); -+} -+#endif -+ - /* Run SHELL, or DEFAULT_SHELL if SHELL is empty. - If COMMAND is nonzero, pass it to the shell with the -c option. - Pass ADDITIONAL_ARGS to the shell as more arguments; there -@@ -309,17 +429,49 @@ change_identity (const struct passwd *pw - - static void - run_shell (char const *shell, char const *command, char **additional_args, -- size_t n_additional_args) -+ size_t n_additional_args, const struct passwd *pw) - { - size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; - char const **args = xnmalloc (n_args, sizeof *args); - size_t argno = 1; -+#ifdef USE_PAM -+ int child; -+ sigset_t ourset; -+ int status; -+ -+ retval = pam_open_session(pamh,0); -+ if (retval != PAM_SUCCESS) { -+ fprintf (stderr, "could not open session\n"); -+ exit (1); -+ } -+ -+/* do this at the last possible moment, because environment variables may -+ be passed even in the session phase -+*/ -+ if(pam_copyenv(pamh) != PAM_SUCCESS) -+ fprintf (stderr, "error copying PAM environment\n"); -+ -+ /* Credentials should be set in the parent */ -+ if (pam_setcred(pamh, PAM_ESTABLISH_CRED) != PAM_SUCCESS) { -+ pam_close_session(pamh, 0); -+ fprintf(stderr, "could not set PAM credentials\n"); -+ exit(1); -+ } -+ -+ child = fork(); -+ if (child == 0) { /* child shell */ -+ change_identity (pw); -+ pam_end(pamh, 0); -+#endif - - if (simulate_login) - { - char *arg0; - char *shell_basename; - -+ if(chdir(pw->pw_dir)) -+ error(0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); -+ - shell_basename = last_component (shell); - arg0 = xmalloc (strlen (shell_basename) + 2); - arg0[0] = '-'; -@@ -344,6 +496,67 @@ run_shell (char const *shell, char const - error (0, errno, "%s", shell); - exit (exit_status); - } -+#ifdef USE_PAM -+ } else if (child == -1) { -+ fprintf(stderr, "can not fork user shell: %s", strerror(errno)); -+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); -+ pam_close_session(pamh, 0); -+ pam_end(pamh, PAM_ABORT); -+ exit(1); -+ } -+ /* parent only */ -+ sigfillset(&ourset); -+ if (sigprocmask(SIG_BLOCK, &ourset, NULL)) { -+ fprintf(stderr, "%s: signal malfunction\n", PROGRAM_NAME); -+ caught = 1; -+ } -+ if (!caught) { -+ struct sigaction action; -+ action.sa_handler = su_catch_sig; -+ sigemptyset(&action.sa_mask); -+ action.sa_flags = 0; -+ sigemptyset(&ourset); -+ if (sigaddset(&ourset, SIGTERM) -+ || sigaddset(&ourset, SIGALRM) -+ || sigaction(SIGTERM, &action, NULL) -+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL)) { -+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); -+ caught = 1; -+ } -+ } -+ if (!caught) { -+ do { -+ int pid; -+ -+ pid = waitpid(-1, &status, WUNTRACED); -+ -+ if (((pid_t)-1 != pid) && (0 != WIFSTOPPED (status))) { -+ kill(getpid(), WSTOPSIG(status)); -+ /* once we get here, we must have resumed */ -+ kill(pid, SIGCONT); -+ } -+ } while (0 != WIFSTOPPED(status)); -+ } -+ -+ if (caught) { -+ fprintf(stderr, "\nSession terminated, killing shell..."); -+ kill (child, SIGTERM); -+ } -+ /* Not checking retval on this because we need to call close session */ -+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); -+ retval = pam_close_session(pamh, 0); -+ PAM_BAIL_P_VOID; -+ retval = pam_end(pamh, PAM_SUCCESS); -+ PAM_BAIL_P_VOID; -+ if (caught) { -+ sleep(2); -+ kill(child, SIGKILL); -+ fprintf(stderr, " ...killed.\n"); -+ exit(-1); -+ } -+ exit ((0 != WIFEXITED (status)) ? WEXITSTATUS (status) -+ : WTERMSIG (status) + 128); -+#endif /* USE_PAM */ - } - - /* Return true if SHELL is a restricted shell (one not returned by -@@ -511,9 +724,9 @@ main (int argc, char **argv) - shell = xstrdup (shell ? shell : pw->pw_shell); - modify_environment (pw, shell); - -+#ifndef USE_PAM - change_identity (pw); -- if (simulate_login && chdir (pw->pw_dir) != 0) -- error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); -+#endif - - /* error() flushes stderr, but does not check for write failure. - Normally, we would catch this via our atexit() hook of -@@ -523,5 +736,5 @@ main (int argc, char **argv) - if (ferror (stderr)) - exit (EXIT_CANCELED); - -- run_shell (shell, command, argv + optind, MAX (0, argc - optind)); -+ run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); - } diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index e326d86..4ad7e6b 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,9 +1,9 @@ -diff -urNp coreutils-8.6-orig/configure.ac coreutils-8.6/configure.ac ---- coreutils-8.6-orig/configure.ac 2010-10-18 13:46:01.319460047 +0200 -+++ coreutils-8.6/configure.ac 2010-10-18 14:36:46.348209592 +0200 -@@ -140,6 +140,13 @@ AC_ARG_ENABLE(pam, dnl - LIB_PAM="-ldl -lpam -lpam_misc" - AC_SUBST(LIB_PAM)]) +diff -urNp coreutils-8.7-orig/configure.ac coreutils-8.7/configure.ac +--- coreutils-8.7-orig/configure.ac 2010-11-15 10:03:39.636171519 +0100 ++++ coreutils-8.7/configure.ac 2010-11-15 10:04:08.161930423 +0100 +@@ -133,6 +133,13 @@ if test "$gl_gcc_warnings" = yes; then + AC_SUBST([GNULIB_TEST_WARN_CFLAGS]) + fi +dnl Give the chance to enable SELINUX +AC_ARG_ENABLE(selinux, dnl @@ -14,19 +14,19 @@ diff -urNp coreutils-8.6-orig/configure.ac coreutils-8.6/configure.ac + AC_FUNC_FORK - optional_bin_progs= -diff -urNp coreutils-8.6-orig/man/chcon.x coreutils-8.6/man/chcon.x ---- coreutils-8.6-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.6/man/chcon.x 2010-10-18 14:36:46.348209592 +0200 + AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam], +diff -urNp coreutils-8.7-orig/man/chcon.x coreutils-8.7/man/chcon.x +--- coreutils-8.7-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.7/man/chcon.x 2010-11-15 10:04:08.161930423 +0100 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-8.6-orig/man/runcon.x coreutils-8.6/man/runcon.x ---- coreutils-8.6-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.6/man/runcon.x 2010-10-18 14:36:46.349211548 +0200 +diff -urNp coreutils-8.7-orig/man/runcon.x coreutils-8.7/man/runcon.x +--- coreutils-8.7-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.7/man/runcon.x 2010-11-15 10:04:08.162922322 +0100 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,10 +34,10 @@ diff -urNp coreutils-8.6-orig/man/runcon.x coreutils-8.6/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.6-orig/src/copy.c coreutils-8.6/src/copy.c ---- coreutils-8.6-orig/src/copy.c 2010-10-12 13:13:16.000000000 +0200 -+++ coreutils-8.6/src/copy.c 2010-10-18 14:36:46.350209243 +0200 -@@ -1923,6 +1923,8 @@ copy_internal (char const *src_name, cha +diff -urNp coreutils-8.7-orig/src/copy.c coreutils-8.7/src/copy.c +--- coreutils-8.7-orig/src/copy.c 2010-10-28 12:31:17.000000000 +0200 ++++ coreutils-8.7/src/copy.c 2010-11-15 10:04:08.165921553 +0100 +@@ -1924,6 +1924,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -46,9 +46,9 @@ diff -urNp coreutils-8.6-orig/src/copy.c coreutils-8.6/src/copy.c } else { -diff -urNp coreutils-8.6-orig/src/copy.h coreutils-8.6/src/copy.h ---- coreutils-8.6-orig/src/copy.h 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/copy.h 2010-10-18 14:36:46.352209243 +0200 +diff -urNp coreutils-8.7-orig/src/copy.h coreutils-8.7/src/copy.h +--- coreutils-8.7-orig/src/copy.h 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/copy.h 2010-11-15 10:04:08.166925814 +0100 @@ -158,6 +158,9 @@ struct cp_options bool preserve_mode; bool preserve_timestamps; @@ -59,9 +59,9 @@ diff -urNp coreutils-8.6-orig/src/copy.h coreutils-8.6/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urNp coreutils-8.6-orig/src/cp.c coreutils-8.6/src/cp.c ---- coreutils-8.6-orig/src/cp.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/cp.c 2010-10-18 14:36:46.353209453 +0200 +diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c +--- coreutils-8.7-orig/src/cp.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/cp.c 2010-11-15 10:04:08.168931890 +0100 @@ -141,6 +141,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, @@ -150,9 +150,9 @@ diff -urNp coreutils-8.6-orig/src/cp.c coreutils-8.6/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urNp coreutils-8.6-orig/src/chcon.c coreutils-8.6/src/chcon.c ---- coreutils-8.6-orig/src/chcon.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/chcon.c 2010-10-18 14:36:46.356209523 +0200 +diff -urNp coreutils-8.7-orig/src/chcon.c coreutils-8.7/src/chcon.c +--- coreutils-8.7-orig/src/chcon.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/chcon.c 2010-11-15 10:04:08.169922391 +0100 @@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), program_name, program_name, program_name); @@ -162,9 +162,9 @@ diff -urNp coreutils-8.6-orig/src/chcon.c coreutils-8.6/src/chcon.c With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ -h, --no-dereference affect symbolic links instead of any referenced file\n\ -diff -urNp coreutils-8.6-orig/src/id.c coreutils-8.6/src/id.c ---- coreutils-8.6-orig/src/id.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/id.c 2010-10-18 14:36:46.357221466 +0200 +diff -urNp coreutils-8.7-orig/src/id.c coreutils-8.7/src/id.c +--- coreutils-8.7-orig/src/id.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/id.c 2010-11-15 10:04:08.170933217 +0100 @@ -107,7 +107,7 @@ int main (int argc, char **argv) { @@ -174,9 +174,9 @@ diff -urNp coreutils-8.6-orig/src/id.c coreutils-8.6/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urNp coreutils-8.6-orig/src/install.c coreutils-8.6/src/install.c ---- coreutils-8.6-orig/src/install.c 2010-10-14 08:20:20.000000000 +0200 -+++ coreutils-8.6/src/install.c 2010-10-18 14:36:46.358209103 +0200 +diff -urNp coreutils-8.7-orig/src/install.c coreutils-8.7/src/install.c +--- coreutils-8.7-orig/src/install.c 2010-10-15 21:56:29.000000000 +0200 ++++ coreutils-8.7/src/install.c 2010-11-15 10:04:08.171921693 +0100 @@ -283,6 +283,7 @@ cp_option_init (struct cp_options *x) x->data_copy_required = true; x->require_preserve = false; @@ -232,9 +232,9 @@ diff -urNp coreutils-8.6-orig/src/install.c coreutils-8.6/src/install.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); -diff -urNp coreutils-8.6-orig/src/ls.c coreutils-8.6/src/ls.c ---- coreutils-8.6-orig/src/ls.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/ls.c 2010-10-18 14:36:46.361209872 +0200 +diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c +--- coreutils-8.7-orig/src/ls.c 2010-10-25 12:07:57.000000000 +0200 ++++ coreutils-8.7/src/ls.c 2010-11-15 10:04:08.175921763 +0100 @@ -159,7 +159,8 @@ enum filetype symbolic_link, sock, @@ -597,9 +597,9 @@ diff -urNp coreutils-8.6-orig/src/ls.c coreutils-8.6/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-8.6-orig/src/mkdir.c coreutils-8.6/src/mkdir.c ---- coreutils-8.6-orig/src/mkdir.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/mkdir.c 2010-10-18 14:36:46.363209243 +0200 +diff -urNp coreutils-8.7-orig/src/mkdir.c coreutils-8.7/src/mkdir.c +--- coreutils-8.7-orig/src/mkdir.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/mkdir.c 2010-11-15 10:04:08.177942716 +0100 @@ -38,6 +38,7 @@ static struct option const longopts[] = { @@ -608,9 +608,9 @@ diff -urNp coreutils-8.6-orig/src/mkdir.c coreutils-8.6/src/mkdir.c {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, -diff -urNp coreutils-8.6-orig/src/mknod.c coreutils-8.6/src/mknod.c ---- coreutils-8.6-orig/src/mknod.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/mknod.c 2010-10-18 14:36:46.363209243 +0200 +diff -urNp coreutils-8.7-orig/src/mknod.c coreutils-8.7/src/mknod.c +--- coreutils-8.7-orig/src/mknod.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/mknod.c 2010-11-15 10:04:08.177942716 +0100 @@ -35,7 +35,7 @@ static struct option const longopts[] = @@ -620,9 +620,9 @@ diff -urNp coreutils-8.6-orig/src/mknod.c coreutils-8.6/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urNp coreutils-8.6-orig/src/mv.c coreutils-8.6/src/mv.c ---- coreutils-8.6-orig/src/mv.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/mv.c 2010-10-18 14:36:46.364217485 +0200 +diff -urNp coreutils-8.7-orig/src/mv.c coreutils-8.7/src/mv.c +--- coreutils-8.7-orig/src/mv.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/mv.c 2010-11-15 10:04:08.179924138 +0100 @@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x) x->preserve_mode = true; x->preserve_timestamps = true; @@ -631,9 +631,9 @@ diff -urNp coreutils-8.6-orig/src/mv.c coreutils-8.6/src/mv.c x->reduce_diagnostics = false; x->data_copy_required = true; x->require_preserve = false; /* FIXME: maybe make this an option */ -diff -urNp coreutils-8.6-orig/src/runcon.c coreutils-8.6/src/runcon.c ---- coreutils-8.6-orig/src/runcon.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/src/runcon.c 2010-10-18 14:36:46.365209103 +0200 +diff -urNp coreutils-8.7-orig/src/runcon.c coreutils-8.7/src/runcon.c +--- coreutils-8.7-orig/src/runcon.c 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/src/runcon.c 2010-11-15 10:04:08.180922252 +0100 @@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ "), program_name, program_name); @@ -643,10 +643,10 @@ diff -urNp coreutils-8.6-orig/src/runcon.c coreutils-8.6/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urNp coreutils-8.6-orig/tests/init.cfg coreutils-8.6/tests/init.cfg ---- coreutils-8.6-orig/tests/init.cfg 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/tests/init.cfg 2010-10-18 13:49:14.383904033 +0200 -@@ -214,8 +214,8 @@ skip_if_() +diff -urNp coreutils-8.7-orig/tests/init.cfg coreutils-8.7/tests/init.cfg +--- coreutils-8.7-orig/tests/init.cfg 2010-11-08 14:10:20.000000000 +0100 ++++ coreutils-8.7/tests/init.cfg 2010-11-15 10:04:08.181922042 +0100 +@@ -216,8 +216,8 @@ skip_if_() require_selinux_() { @@ -657,9 +657,9 @@ diff -urNp coreutils-8.6-orig/tests/init.cfg coreutils-8.6/tests/init.cfg skip_test_ "this system (or maybe just" \ "the current file system) lacks SELinux support" ;; -diff -urNp coreutils-8.6-orig/tests/misc/selinux coreutils-8.6/tests/misc/selinux ---- coreutils-8.6-orig/tests/misc/selinux 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.6/tests/misc/selinux 2010-10-18 14:36:46.365209103 +0200 +diff -urNp coreutils-8.7-orig/tests/misc/selinux coreutils-8.7/tests/misc/selinux +--- coreutils-8.7-orig/tests/misc/selinux 2010-10-11 19:35:11.000000000 +0200 ++++ coreutils-8.7/tests/misc/selinux 2010-11-15 10:04:08.181922042 +0100 @@ -44,7 +44,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. diff --git a/coreutils-setsid.patch b/coreutils-setsid.patch index 78ab64d..714383f 100644 --- a/coreutils-setsid.patch +++ b/coreutils-setsid.patch @@ -1,12 +1,17 @@ ---- coreutils-6.7/src/su.c.setsid 2007-01-09 17:26:26.000000000 +0000 -+++ coreutils-6.7/src/su.c 2007-01-09 17:26:57.000000000 +0000 -@@ -176,9 +176,13 @@ +diff -urNp coreutils-8.6-orig/src/su.c coreutils-8.6/src/su.c +--- coreutils-8.6-orig/src/su.c 2010-11-03 13:56:11.679069689 +0100 ++++ coreutils-8.6/src/su.c 2010-11-03 13:56:45.304325661 +0100 +@@ -153,6 +153,9 @@ static bool simulate_login; /* If true, change some environment vars to indicate the user su'd to. */ static bool change_environment; +/* If true, then don't call setsid() with a command. */ +int same_session = 0; + + #ifdef USE_PAM + static bool _pam_session_opened; + static bool _pam_cred_established; +@@ -161,6 +164,7 @@ static bool _pam_cred_established; static struct option const longopts[] = { {"command", required_argument, NULL, 'c'}, @@ -14,48 +19,40 @@ {"fast", no_argument, NULL, 'f'}, {"login", no_argument, NULL, 'l'}, {"preserve-environment", no_argument, NULL, 'p'}, -@@ -478,6 +482,8 @@ - if (child == 0) { /* child shell */ - change_identity (pw); - pam_end(pamh, 0); -+ if (!same_session) -+ setsid (); - #endif - - if (simulate_login) -@@ -532,13 +538,27 @@ - sigemptyset(&action.sa_mask); - action.sa_flags = 0; - sigemptyset(&ourset); -- if (sigaddset(&ourset, SIGTERM) -- || sigaddset(&ourset, SIGALRM) -- || sigaction(SIGTERM, &action, NULL) -- || sigprocmask(SIG_UNBLOCK, &ourset, NULL)) { +@@ -335,14 +339,27 @@ create_watching_parent (void) + sigemptyset (&action.sa_mask); + action.sa_flags = 0; + sigemptyset (&ourset); +- if (sigaddset (&ourset, SIGTERM) +- || sigaddset (&ourset, SIGALRM) +- || sigaction (SIGTERM, &action, NULL) +- || sigprocmask (SIG_UNBLOCK, &ourset, NULL)) +- { + if (!same_session) + { + if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) + { -+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); -+ caught = 1; ++ error (0, errno, _("cannot set signal handler")); ++ caught_signal = true; + } + } -+ if (!caught && (sigaddset(&ourset, SIGTERM) ++ if (!caught_signal && (sigaddset(&ourset, SIGTERM) + || sigaddset(&ourset, SIGALRM) + || sigaction(SIGTERM, &action, NULL) + || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) { - fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); - caught = 1; - } -+ if (!caught && !same_session && (sigaction(SIGINT, &action, NULL) + error (0, errno, _("cannot set signal handler")); + caught_signal = true; + } ++ if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL) + || sigaction(SIGQUIT, &action, NULL))) + { -+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME); -+ caught = 1; ++ error (0, errno, _("cannot set signal handler")); ++ caught_signal = true; + } - } - if (!caught) { - do { -@@ -609,6 +629,8 @@ + } + if (!caught_signal) + { +@@ -627,6 +644,8 @@ Change the effective user id and group i \n\ -, -l, --login make the shell a login shell\n\ -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\ @@ -64,7 +61,7 @@ -f, --fast pass -f to the shell (for csh or tcsh)\n\ -m, --preserve-environment do not reset environment variables\n\ -p same as -m\n\ -@@ -631,6 +653,7 @@ +@@ -649,6 +668,7 @@ main (int argc, char **argv) int optc; const char *new_user = DEFAULT_USER; char *command = NULL; @@ -72,7 +69,7 @@ char *shell = NULL; struct passwd *pw; struct passwd pw_copy; -@@ -656,6 +679,11 @@ +@@ -674,6 +694,11 @@ main (int argc, char **argv) command = optarg; break; @@ -84,7 +81,7 @@ case 'f': fast_startup = true; break; -@@ -725,6 +753,9 @@ +@@ -743,6 +768,9 @@ main (int argc, char **argv) } #endif @@ -94,3 +91,12 @@ if (!shell && !change_environment) shell = getenv ("SHELL"); if (shell && getuid () != 0 && restricted_shell (pw->pw_shell)) +@@ -764,6 +792,8 @@ main (int argc, char **argv) + #endif + + change_identity (pw); ++ if (!same_session) ++ setsid (); + + /* Set environment after pam_open_session, which may put KRB5CCNAME + into the pam_env, etc. */ diff --git a/coreutils-split-pam.patch b/coreutils-split-pam.patch deleted file mode 100644 index 6052bc4..0000000 --- a/coreutils-split-pam.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff -uNrp -x '*~' coreutils-5.97-orig/src/su.c coreutils-5.97/src/su.c ---- coreutils-5.97-orig/src/su.c 2006-07-13 12:14:40.000000000 +0100 -+++ coreutils-5.97/src/su.c 2006-07-13 12:24:33.000000000 +0100 -@@ -131,11 +131,15 @@ - - #include "error.h" - --/* The official name of this program (e.g., no `g' prefix). */ -+/* The official name of this program (e.g., no `g' prefix). -+ * - Add a "-l" to the name passed to PAM if this is a login simulation -+ */ - #ifndef RUNUSER - #define PROGRAM_NAME "su" -+#define PROGRAM_NAME_L "su-l" - #else - #define PROGRAM_NAME "runuser" -+#define PROGRAM_NAME_L "runuser-l" - #endif - - #ifndef AUTHORS -@@ -310,7 +314,8 @@ correct_password (const struct passwd *p - #ifdef USE_PAM - struct passwd *caller; - char *tty_name, *ttyn; -- retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh); -+ retval = pam_start(simulate_login ? PROGRAM_NAME_L : PROGRAM_NAME, -+ pw->pw_name, &conv, &pamh); - PAM_BAIL_P; - - #ifndef RUNUSER -diff -urp coreutils-6.10-orig/doc/coreutils.info coreutils-6.10/doc/coreutils.info ---- coreutils-6.10-orig/doc/coreutils.info 2008-01-22 00:32:44.000000000 +0100 -+++ coreutils-6.10/doc/coreutils.info 2008-01-24 17:17:04.000000000 +0100 -@@ -11006,7 +11006,8 @@ options::. - set, even for the super-user, as described above), and set `PATH' - to a compiled-in default value. Change to USER's home directory. - Prepend `-' to the shell's name, intended to make it read its -- login startup file(s). -+ login startup file(s). When this option is given, /etc/pam.d/su-l -+ PAM file is used instead of the default one. - - `-m' - `-p' -diff -urp coreutils-6.10-orig/doc/coreutils.texi coreutils-6.10/doc/coreutils.texi ---- coreutils-6.10-orig/doc/coreutils.texi 2008-01-24 16:50:57.000000000 +0100 -+++ coreutils-6.10/doc/coreutils.texi 2008-01-24 17:12:58.000000000 +0100 -@@ -13670,7 +13670,9 @@ the exit status of @var{command} otherwi - - @command{su} allows one user to temporarily become another user. It runs a - command (often an interactive shell) with the real and effective user --ID, group ID, and supplemental groups of a given @var{user}. Synopsis: -+ID, group ID, and supplemental groups of a given @var{user}. When the -l -+option is given, the su-l PAM file is used instead of the default su PAM file. -+Synopsis: - - @example - su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}] diff --git a/coreutils.spec b/coreutils.spec index ecd37f3..26c2b0d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.6 -Release: 3%{?dist} +Version: 8.7 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -42,8 +42,8 @@ Patch703: sh-utils-2.0.11-dateman.patch Patch704: sh-utils-1.16-paths.patch # RMS will never accept the PAM patch because it removes his historical # rant about Twenex and the wheel group, so we'll continue to maintain -# it here indefinitely. -Patch706: coreutils-pam.patch +# it here indefinitely. Patch is now the same in Fedora and SUSE. +Patch706: coreutils-8.5-pam.patch Patch713: coreutils-4.5.3-langinfo.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch @@ -52,14 +52,11 @@ Patch800: coreutils-i18n.patch #Call setsid() in su under some circumstances (bug #173008). Patch900: coreutils-setsid.patch #make runuser binary based on su.c -Patch907: coreutils-5.2.1-runuser.patch +Patch907: coreutils-8.7-runuser.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch #Prevent buffer overflow in who(1) (bug #158405). Patch912: coreutils-overflow.patch -#split the PAM scripts for "su -l"/"runuser -l" from that of normal "su" and -#"runuser" (#198639) -Patch915: coreutils-split-pam.patch #compile su with pie flag and RELRO protection Patch917: coreutils-8.4-su-pie.patch @@ -142,7 +139,6 @@ Libraries for coreutils package. %patch907 -p1 -b .runuser %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow -%patch915 -p1 -b .splitl %patch917 -p1 -b .pie #SELinux @@ -336,6 +332,10 @@ fi %{_libdir}/coreutils %changelog +* Wed Nov 03 2010 Ondrej Vasik - 8.7-1 +- new upstream release coreutils-8.7 +- pam support in su consolidation with SUSE(#622700) + * Wed Nov 03 2010 Kamil Dudka - 8.6-3 - prevent sort from assertion failure in case LC_CTYPE does not match LC_TIME (#647938) diff --git a/sources b/sources index c53fe1b..4aa4557 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -17d693d282ac57c62b241a045e7b511c coreutils-8.6.tar.xz +6e21df02e7f5c5d86372de4c6d873275 coreutils-8.7.tar.xz From 35cd801647c667cdc4a063a05a47193d7d007db8 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 18 Nov 2010 17:28:56 +0100 Subject: [PATCH 115/523] don't prompt for password with runuser(#654367) --- coreutils-8.7-runuser.patch | 13 +++++++++---- coreutils.spec | 7 +++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/coreutils-8.7-runuser.patch b/coreutils-8.7-runuser.patch index 6692a3e..93cd962 100644 --- a/coreutils-8.7-runuser.patch +++ b/coreutils-8.7-runuser.patch @@ -138,7 +138,7 @@ diff -urNp coreutils-8.7-orig/src/su.c coreutils-8.7/src/su.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -444,8 +457,14 @@ correct_password (const struct passwd *p +@@ -444,6 +457,11 @@ correct_password (const struct passwd *p retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name); PAM_BAIL_P (return false); } @@ -149,10 +149,15 @@ diff -urNp coreutils-8.7-orig/src/su.c coreutils-8.7/src/su.c +#else retval = pam_authenticate (pamh, 0); PAM_BAIL_P (return false); -+#endif retval = pam_acct_mgmt (pamh, 0); - if (retval == PAM_NEW_AUTHTOK_REQD) - { +@@ -454,6 +472,7 @@ correct_password (const struct passwd *p + PAM_BAIL_P (return false); + } + PAM_BAIL_P (return false); ++#endif + /* Must be authenticated if this point was reached. */ + return true; + #else /* !USE_PAM */ @@ -533,11 +552,22 @@ modify_environment (const struct passwd /* Become the user and group(s) specified by PW. */ diff --git a/coreutils.spec b/coreutils.spec index 26c2b0d..266afc5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.7 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -332,7 +332,10 @@ fi %{_libdir}/coreutils %changelog -* Wed Nov 03 2010 Ondrej Vasik - 8.7-1 +* Thu Nov 18 2010 Ondrej Vasik - 8.7-2 +- don't prompt for password with runuser(#654367) + +* Mon Nov 15 2010 Ondrej Vasik - 8.7-1 - new upstream release coreutils-8.7 - pam support in su consolidation with SUSE(#622700) From 163de8bee038397ef7155c5e720cb28b79c3d769 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 23 Dec 2010 14:13:28 +0100 Subject: [PATCH 116/523] new upstream release coreutils-8.8 (#665164), fix parallel sorting issue (#655096) --- .gitignore | 1 + coreutils-df-direct.patch | 10 +-- coreutils-i18n.patch | 158 +++++++++++++++++++------------------- coreutils.spec | 8 +- sources | 2 +- 5 files changed, 90 insertions(+), 89 deletions(-) diff --git a/.gitignore b/.gitignore index f0640be..9ec635c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ coreutils-8.5.tar.xz /coreutils-8.6.tar.xz /coreutils-8.7.tar.xz +/coreutils-8.8.tar.xz diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 24d0057..46b37c8 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -126,7 +126,7 @@ new file mode 100644 index 0000000..9088f27 --- /dev/null +++ b/tests/df/direct -@@ -0,0 +1,59 @@ +@@ -0,0 +1,55 @@ +#!/bin/sh +# Ensure "df --direct" works as documented + @@ -145,12 +145,8 @@ index 0000000..9088f27 +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + -+if test "$VERBOSE" = yes; then -+ set -x -+ df --version -+fi -+ -+. $srcdir/test-lib.sh ++. "${srcdir=.}/init.sh"; path_prepend_ ../src ++print_ver_ df + +df || skip_test_ "df fails" + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 9c85439..c26d702 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.7-orig/lib/linebuffer.h coreutils-8.7/lib/linebuffer.h ---- coreutils-8.7-orig/lib/linebuffer.h 2010-06-10 18:45:26.000000000 +0200 -+++ coreutils-8.7/lib/linebuffer.h 2010-11-15 09:59:36.974172148 +0100 +diff -urNp coreutils-8.8-orig/lib/linebuffer.h coreutils-8.8/lib/linebuffer.h +--- coreutils-8.8-orig/lib/linebuffer.h 2010-04-23 15:44:00.000000000 +0200 ++++ coreutils-8.8/lib/linebuffer.h 2010-12-23 13:59:44.393514385 +0100 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.7-orig/lib/linebuffer.h coreutils-8.7/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.7-orig/src/cut.c coreutils-8.7/src/cut.c ---- coreutils-8.7-orig/src/cut.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/cut.c 2010-11-15 09:59:36.976171659 +0100 +diff -urNp coreutils-8.8-orig/src/cut.c coreutils-8.8/src/cut.c +--- coreutils-8.8-orig/src/cut.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/cut.c 2010-12-23 13:59:44.397514141 +0100 @@ -28,6 +28,11 @@ #include #include @@ -616,9 +616,9 @@ diff -urNp coreutils-8.7-orig/src/cut.c coreutils-8.7/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.7-orig/src/expand.c coreutils-8.7/src/expand.c ---- coreutils-8.7-orig/src/expand.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/expand.c 2010-11-15 09:59:36.977172637 +0100 +diff -urNp coreutils-8.8-orig/src/expand.c coreutils-8.8/src/expand.c +--- coreutils-8.8-orig/src/expand.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/expand.c 2010-12-23 13:59:44.399514013 +0100 @@ -38,12 +38,29 @@ #include #include @@ -806,9 +806,9 @@ diff -urNp coreutils-8.7-orig/src/expand.c coreutils-8.7/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.7-orig/src/fold.c coreutils-8.7/src/fold.c ---- coreutils-8.7-orig/src/fold.c 2010-10-16 13:28:01.000000000 +0200 -+++ coreutils-8.7/src/fold.c 2010-11-15 09:59:36.979181926 +0100 +diff -urNp coreutils-8.8-orig/src/fold.c coreutils-8.8/src/fold.c +--- coreutils-8.8-orig/src/fold.c 2010-11-27 16:06:22.000000000 +0100 ++++ coreutils-8.8/src/fold.c 2010-12-23 13:59:44.401513895 +0100 @@ -22,12 +22,34 @@ #include #include @@ -1207,9 +1207,9 @@ diff -urNp coreutils-8.7-orig/src/fold.c coreutils-8.7/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.7-orig/src/join.c coreutils-8.7/src/join.c ---- coreutils-8.7-orig/src/join.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/join.c 2010-11-15 09:59:36.980181716 +0100 +diff -urNp coreutils-8.8-orig/src/join.c coreutils-8.8/src/join.c +--- coreutils-8.8-orig/src/join.c 2010-09-17 11:13:45.000000000 +0200 ++++ coreutils-8.8/src/join.c 2010-12-23 13:59:44.404513732 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1692,9 +1692,9 @@ diff -urNp coreutils-8.7-orig/src/join.c coreutils-8.7/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.7-orig/src/pr.c coreutils-8.7/src/pr.c ---- coreutils-8.7-orig/src/pr.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/pr.c 2010-11-15 09:59:36.983181856 +0100 +diff -urNp coreutils-8.8-orig/src/pr.c coreutils-8.8/src/pr.c +--- coreutils-8.8-orig/src/pr.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/pr.c 2010-12-23 13:59:44.410513374 +0100 @@ -312,6 +312,32 @@ #include @@ -2417,9 +2417,9 @@ diff -urNp coreutils-8.7-orig/src/pr.c coreutils-8.7/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c ---- coreutils-8.7-orig/src/sort.c 2010-10-25 12:07:57.000000000 +0200 -+++ coreutils-8.7/src/sort.c 2010-11-15 09:59:36.987932380 +0100 +diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c +--- coreutils-8.8-orig/src/sort.c 2010-12-20 12:20:41.000000000 +0100 ++++ coreutils-8.8/src/sort.c 2010-12-23 13:59:44.420512797 +0100 @@ -22,11 +22,20 @@ #include @@ -2441,7 +2441,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -159,12 +168,34 @@ static int thousands_sep; +@@ -163,12 +172,34 @@ static int thousands_sep; /* Nonzero if the corresponding locales are hard. */ static bool hard_LC_COLLATE; @@ -2477,7 +2477,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -328,13 +359,11 @@ static bool reverse; +@@ -335,13 +366,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2494,8 +2494,8 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -782,6 +811,46 @@ reap_some (void) - update_proc (pid); +@@ -768,6 +797,46 @@ reap_all (void) + reap (-1); } +/* Function pointers. */ @@ -2541,7 +2541,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1205,7 +1274,7 @@ zaptemp (char const *name) +@@ -1200,7 +1269,7 @@ zaptemp (char const *name) free (node); } @@ -2550,7 +2550,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1220,7 +1289,7 @@ struct_month_cmp (void const *m1, void c +@@ -1215,7 +1284,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2559,7 +2559,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { size_t i; -@@ -1232,7 +1301,7 @@ inittables (void) +@@ -1227,7 +1296,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2568,7 +2568,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1314,6 +1383,84 @@ specify_nmerge (int oi, char c, char con +@@ -1309,6 +1378,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2653,7 +2653,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1540,7 +1687,7 @@ buffer_linelim (struct buffer const *buf +@@ -1537,7 +1684,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2662,7 +2662,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1549,10 +1696,10 @@ begfield (struct line const *line, struc +@@ -1546,10 +1693,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2675,7 +2675,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1578,11 +1725,70 @@ begfield (struct line const *line, struc +@@ -1575,11 +1722,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2747,7 +2747,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1597,10 +1803,10 @@ limfield (struct line const *line, struc +@@ -1594,10 +1800,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. */ @@ -2760,7 +2760,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1646,10 +1852,10 @@ limfield (struct line const *line, struc +@@ -1643,10 +1849,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2773,7 +2773,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c if (newlim) lim = newlim; } -@@ -1680,6 +1886,130 @@ limfield (struct line const *line, struc +@@ -1677,6 +1883,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2904,7 +2904,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* 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 -@@ -1766,8 +2096,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1763,8 +2093,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2929,7 +2929,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c line->keybeg = line_start; } } -@@ -1888,7 +2232,7 @@ human_numcompare (char const *a, char co +@@ -1885,7 +2229,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2938,7 +2938,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1898,6 +2242,25 @@ numcompare (char const *a, char const *b +@@ -1895,6 +2239,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2964,7 +2964,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c static int general_numcompare (char const *sa, char const *sb) { -@@ -1930,7 +2293,7 @@ general_numcompare (char const *sa, char +@@ -1927,7 +2290,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -2973,9 +2973,9 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2204,13 +2567,12 @@ debug_key (struct line const *line, stru - { - char saved = *lim; *lim = '\0'; +@@ -2202,13 +2565,12 @@ debug_key (struct line const *line, stru + char saved = *lim; + *lim = '\0'; - while (blanks[to_uchar (*beg)]) - beg++; @@ -2989,7 +2989,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2354,7 +2716,7 @@ key_warnings (struct keyfield const *gke +@@ -2352,7 +2714,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2998,7 +2998,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2412,11 +2774,83 @@ key_warnings (struct keyfield const *gke +@@ -2410,11 +2772,83 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option `-r' only applies to last-resort comparison")); } @@ -3083,7 +3083,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { struct keyfield *key = keylist; -@@ -2501,7 +2935,7 @@ keycompare (struct line const *a, struct +@@ -2499,7 +2933,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3092,7 +3092,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2617,6 +3051,179 @@ keycompare (struct line const *a, struct +@@ -2615,6 +3049,179 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3272,7 +3272,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4006,7 +4613,7 @@ main (int argc, char **argv) +@@ -4077,7 +4684,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3281,7 +3281,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4027,6 +4634,29 @@ main (int argc, char **argv) +@@ -4098,6 +4705,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3311,7 +3311,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c have_read_stdin = false; inittables (); -@@ -4297,13 +4927,34 @@ main (int argc, char **argv) +@@ -4368,13 +4998,34 @@ main (int argc, char **argv) case 't': { @@ -3350,7 +3350,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -4314,9 +4965,12 @@ main (int argc, char **argv) +@@ -4385,9 +5036,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3365,9 +3365,9 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c } break; -diff -urNp coreutils-8.7-orig/src/unexpand.c coreutils-8.7/src/unexpand.c ---- coreutils-8.7-orig/src/unexpand.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/unexpand.c 2010-11-15 09:59:36.989931891 +0100 +diff -urNp coreutils-8.8-orig/src/unexpand.c coreutils-8.8/src/unexpand.c +--- coreutils-8.8-orig/src/unexpand.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/unexpand.c 2010-12-23 13:59:44.423512620 +0100 @@ -39,12 +39,29 @@ #include #include @@ -3621,9 +3621,9 @@ diff -urNp coreutils-8.7-orig/src/unexpand.c coreutils-8.7/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.7-orig/src/uniq.c coreutils-8.7/src/uniq.c ---- coreutils-8.7-orig/src/uniq.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/uniq.c 2010-11-15 09:59:36.992922043 +0100 +diff -urNp coreutils-8.8-orig/src/uniq.c coreutils-8.8/src/uniq.c +--- coreutils-8.8-orig/src/uniq.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/uniq.c 2010-12-23 13:59:44.426512446 +0100 @@ -21,6 +21,16 @@ #include #include @@ -3990,10 +3990,10 @@ diff -urNp coreutils-8.7-orig/src/uniq.c coreutils-8.7/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.7-orig/tests/Makefile.am coreutils-8.7/tests/Makefile.am ---- coreutils-8.7-orig/tests/Makefile.am 2010-11-15 09:58:44.197937898 +0100 -+++ coreutils-8.7/tests/Makefile.am 2010-11-15 09:59:36.993932170 +0100 -@@ -231,6 +231,7 @@ TESTS = \ +diff -urNp coreutils-8.8-orig/tests/Makefile.am coreutils-8.8/tests/Makefile.am +--- coreutils-8.8-orig/tests/Makefile.am 2010-12-23 13:59:21.007870308 +0100 ++++ coreutils-8.8/tests/Makefile.am 2010-12-23 13:59:44.428512331 +0100 +@@ -233,6 +233,7 @@ TESTS = \ misc/sort-debug-keys \ misc/sort-debug-warn \ misc/sort-files0-from \ @@ -4001,7 +4001,7 @@ diff -urNp coreutils-8.7-orig/tests/Makefile.am coreutils-8.7/tests/Makefile.am misc/sort-float \ misc/sort-merge \ misc/sort-merge-fdlimit \ -@@ -490,6 +491,10 @@ TESTS = \ +@@ -498,6 +499,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -4012,9 +4012,9 @@ diff -urNp coreutils-8.7-orig/tests/Makefile.am coreutils-8.7/tests/Makefile.am pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.7-orig/tests/misc/cut coreutils-8.7/tests/misc/cut ---- coreutils-8.7-orig/tests/misc/cut 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/tests/misc/cut 2010-11-15 09:59:36.994932100 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/cut coreutils-8.8/tests/misc/cut +--- coreutils-8.8-orig/tests/misc/cut 2010-01-01 14:06:47.000000000 +0100 ++++ coreutils-8.8/tests/misc/cut 2010-12-23 13:59:44.429512273 +0100 @@ -26,7 +26,7 @@ use strict; my $prog = 'cut'; my $try = "Try \`$prog --help' for more information.\n"; @@ -4033,41 +4033,41 @@ diff -urNp coreutils-8.7-orig/tests/misc/cut coreutils-8.7/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], -diff -urNp coreutils-8.7-orig/tests/misc/mb1.I coreutils-8.7/tests/misc/mb1.I ---- coreutils-8.7-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/mb1.I 2010-11-15 09:59:36.995931961 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/mb1.I coreutils-8.8/tests/misc/mb1.I +--- coreutils-8.8-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/mb1.I 2010-12-23 13:59:44.430512213 +0100 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.7-orig/tests/misc/mb1.X coreutils-8.7/tests/misc/mb1.X ---- coreutils-8.7-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/mb1.X 2010-11-15 09:59:36.995931961 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/mb1.X coreutils-8.8/tests/misc/mb1.X +--- coreutils-8.8-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/mb1.X 2010-12-23 13:59:44.430512213 +0100 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.7-orig/tests/misc/mb2.I coreutils-8.7/tests/misc/mb2.I ---- coreutils-8.7-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/mb2.I 2010-11-15 09:59:36.996933777 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/mb2.I coreutils-8.8/tests/misc/mb2.I +--- coreutils-8.8-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/mb2.I 2010-12-23 13:59:44.431512154 +0100 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.7-orig/tests/misc/mb2.X coreutils-8.7/tests/misc/mb2.X ---- coreutils-8.7-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/mb2.X 2010-11-15 09:59:36.997922462 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/mb2.X coreutils-8.8/tests/misc/mb2.X +--- coreutils-8.8-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/mb2.X 2010-12-23 13:59:44.432512095 +0100 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.7-orig/tests/misc/sort-mb-tests coreutils-8.7/tests/misc/sort-mb-tests ---- coreutils-8.7-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/sort-mb-tests 2010-11-15 09:59:36.997922462 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/sort-mb-tests coreutils-8.8/tests/misc/sort-mb-tests +--- coreutils-8.8-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/sort-mb-tests 2010-12-23 13:59:44.433512037 +0100 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils.spec b/coreutils.spec index 266afc5..03f1c44 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.7 -Release: 2%{?dist} +Version: 8.8 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -332,6 +332,10 @@ fi %{_libdir}/coreutils %changelog +* Thu Dec 23 2010 Ondrej Vasik - 8.8-1 +- fix parallel sorting issue (#655096) +- new upstream release coreutils-8.8 (#665164) + * Thu Nov 18 2010 Ondrej Vasik - 8.7-2 - don't prompt for password with runuser(#654367) diff --git a/sources b/sources index 4aa4557..31af477 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -6e21df02e7f5c5d86372de4c6d873275 coreutils-8.7.tar.xz +a78848e3d7ba52e65b564ffea875ef20 coreutils-8.8.tar.xz From 826eac74c1be03a5ff6ce496869508d3f931f61d Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Thu, 23 Dec 2010 14:13:28 +0100 Subject: [PATCH 117/523] new upstream release coreutils-8.8 (#665164), fix parallel sorting issue (#655096) --- .gitignore | 1 + coreutils-df-direct.patch | 10 +-- coreutils-i18n.patch | 158 +++++++++++++++++++------------------- coreutils.spec | 8 +- sources | 2 +- 5 files changed, 90 insertions(+), 89 deletions(-) diff --git a/.gitignore b/.gitignore index f0640be..9ec635c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ coreutils-8.5.tar.xz /coreutils-8.6.tar.xz /coreutils-8.7.tar.xz +/coreutils-8.8.tar.xz diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 24d0057..46b37c8 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -126,7 +126,7 @@ new file mode 100644 index 0000000..9088f27 --- /dev/null +++ b/tests/df/direct -@@ -0,0 +1,59 @@ +@@ -0,0 +1,55 @@ +#!/bin/sh +# Ensure "df --direct" works as documented + @@ -145,12 +145,8 @@ index 0000000..9088f27 +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + -+if test "$VERBOSE" = yes; then -+ set -x -+ df --version -+fi -+ -+. $srcdir/test-lib.sh ++. "${srcdir=.}/init.sh"; path_prepend_ ../src ++print_ver_ df + +df || skip_test_ "df fails" + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 9c85439..c26d702 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.7-orig/lib/linebuffer.h coreutils-8.7/lib/linebuffer.h ---- coreutils-8.7-orig/lib/linebuffer.h 2010-06-10 18:45:26.000000000 +0200 -+++ coreutils-8.7/lib/linebuffer.h 2010-11-15 09:59:36.974172148 +0100 +diff -urNp coreutils-8.8-orig/lib/linebuffer.h coreutils-8.8/lib/linebuffer.h +--- coreutils-8.8-orig/lib/linebuffer.h 2010-04-23 15:44:00.000000000 +0200 ++++ coreutils-8.8/lib/linebuffer.h 2010-12-23 13:59:44.393514385 +0100 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.7-orig/lib/linebuffer.h coreutils-8.7/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.7-orig/src/cut.c coreutils-8.7/src/cut.c ---- coreutils-8.7-orig/src/cut.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/cut.c 2010-11-15 09:59:36.976171659 +0100 +diff -urNp coreutils-8.8-orig/src/cut.c coreutils-8.8/src/cut.c +--- coreutils-8.8-orig/src/cut.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/cut.c 2010-12-23 13:59:44.397514141 +0100 @@ -28,6 +28,11 @@ #include #include @@ -616,9 +616,9 @@ diff -urNp coreutils-8.7-orig/src/cut.c coreutils-8.7/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.7-orig/src/expand.c coreutils-8.7/src/expand.c ---- coreutils-8.7-orig/src/expand.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/expand.c 2010-11-15 09:59:36.977172637 +0100 +diff -urNp coreutils-8.8-orig/src/expand.c coreutils-8.8/src/expand.c +--- coreutils-8.8-orig/src/expand.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/expand.c 2010-12-23 13:59:44.399514013 +0100 @@ -38,12 +38,29 @@ #include #include @@ -806,9 +806,9 @@ diff -urNp coreutils-8.7-orig/src/expand.c coreutils-8.7/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.7-orig/src/fold.c coreutils-8.7/src/fold.c ---- coreutils-8.7-orig/src/fold.c 2010-10-16 13:28:01.000000000 +0200 -+++ coreutils-8.7/src/fold.c 2010-11-15 09:59:36.979181926 +0100 +diff -urNp coreutils-8.8-orig/src/fold.c coreutils-8.8/src/fold.c +--- coreutils-8.8-orig/src/fold.c 2010-11-27 16:06:22.000000000 +0100 ++++ coreutils-8.8/src/fold.c 2010-12-23 13:59:44.401513895 +0100 @@ -22,12 +22,34 @@ #include #include @@ -1207,9 +1207,9 @@ diff -urNp coreutils-8.7-orig/src/fold.c coreutils-8.7/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.7-orig/src/join.c coreutils-8.7/src/join.c ---- coreutils-8.7-orig/src/join.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/join.c 2010-11-15 09:59:36.980181716 +0100 +diff -urNp coreutils-8.8-orig/src/join.c coreutils-8.8/src/join.c +--- coreutils-8.8-orig/src/join.c 2010-09-17 11:13:45.000000000 +0200 ++++ coreutils-8.8/src/join.c 2010-12-23 13:59:44.404513732 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1692,9 +1692,9 @@ diff -urNp coreutils-8.7-orig/src/join.c coreutils-8.7/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.7-orig/src/pr.c coreutils-8.7/src/pr.c ---- coreutils-8.7-orig/src/pr.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/pr.c 2010-11-15 09:59:36.983181856 +0100 +diff -urNp coreutils-8.8-orig/src/pr.c coreutils-8.8/src/pr.c +--- coreutils-8.8-orig/src/pr.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/pr.c 2010-12-23 13:59:44.410513374 +0100 @@ -312,6 +312,32 @@ #include @@ -2417,9 +2417,9 @@ diff -urNp coreutils-8.7-orig/src/pr.c coreutils-8.7/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c ---- coreutils-8.7-orig/src/sort.c 2010-10-25 12:07:57.000000000 +0200 -+++ coreutils-8.7/src/sort.c 2010-11-15 09:59:36.987932380 +0100 +diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c +--- coreutils-8.8-orig/src/sort.c 2010-12-20 12:20:41.000000000 +0100 ++++ coreutils-8.8/src/sort.c 2010-12-23 13:59:44.420512797 +0100 @@ -22,11 +22,20 @@ #include @@ -2441,7 +2441,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -159,12 +168,34 @@ static int thousands_sep; +@@ -163,12 +172,34 @@ static int thousands_sep; /* Nonzero if the corresponding locales are hard. */ static bool hard_LC_COLLATE; @@ -2477,7 +2477,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -328,13 +359,11 @@ static bool reverse; +@@ -335,13 +366,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2494,8 +2494,8 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -782,6 +811,46 @@ reap_some (void) - update_proc (pid); +@@ -768,6 +797,46 @@ reap_all (void) + reap (-1); } +/* Function pointers. */ @@ -2541,7 +2541,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1205,7 +1274,7 @@ zaptemp (char const *name) +@@ -1200,7 +1269,7 @@ zaptemp (char const *name) free (node); } @@ -2550,7 +2550,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1220,7 +1289,7 @@ struct_month_cmp (void const *m1, void c +@@ -1215,7 +1284,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2559,7 +2559,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { size_t i; -@@ -1232,7 +1301,7 @@ inittables (void) +@@ -1227,7 +1296,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2568,7 +2568,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1314,6 +1383,84 @@ specify_nmerge (int oi, char c, char con +@@ -1309,6 +1378,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2653,7 +2653,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1540,7 +1687,7 @@ buffer_linelim (struct buffer const *buf +@@ -1537,7 +1684,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2662,7 +2662,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1549,10 +1696,10 @@ begfield (struct line const *line, struc +@@ -1546,10 +1693,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2675,7 +2675,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1578,11 +1725,70 @@ begfield (struct line const *line, struc +@@ -1575,11 +1722,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2747,7 +2747,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1597,10 +1803,10 @@ limfield (struct line const *line, struc +@@ -1594,10 +1800,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. */ @@ -2760,7 +2760,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1646,10 +1852,10 @@ limfield (struct line const *line, struc +@@ -1643,10 +1849,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2773,7 +2773,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c if (newlim) lim = newlim; } -@@ -1680,6 +1886,130 @@ limfield (struct line const *line, struc +@@ -1677,6 +1883,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2904,7 +2904,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* 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 -@@ -1766,8 +2096,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1763,8 +2093,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2929,7 +2929,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c line->keybeg = line_start; } } -@@ -1888,7 +2232,7 @@ human_numcompare (char const *a, char co +@@ -1885,7 +2229,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2938,7 +2938,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1898,6 +2242,25 @@ numcompare (char const *a, char const *b +@@ -1895,6 +2239,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2964,7 +2964,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c static int general_numcompare (char const *sa, char const *sb) { -@@ -1930,7 +2293,7 @@ general_numcompare (char const *sa, char +@@ -1927,7 +2290,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -2973,9 +2973,9 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2204,13 +2567,12 @@ debug_key (struct line const *line, stru - { - char saved = *lim; *lim = '\0'; +@@ -2202,13 +2565,12 @@ debug_key (struct line const *line, stru + char saved = *lim; + *lim = '\0'; - while (blanks[to_uchar (*beg)]) - beg++; @@ -2989,7 +2989,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2354,7 +2716,7 @@ key_warnings (struct keyfield const *gke +@@ -2352,7 +2714,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2998,7 +2998,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2412,11 +2774,83 @@ key_warnings (struct keyfield const *gke +@@ -2410,11 +2772,83 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option `-r' only applies to last-resort comparison")); } @@ -3083,7 +3083,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c { struct keyfield *key = keylist; -@@ -2501,7 +2935,7 @@ keycompare (struct line const *a, struct +@@ -2499,7 +2933,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3092,7 +3092,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2617,6 +3051,179 @@ keycompare (struct line const *a, struct +@@ -2615,6 +3049,179 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3272,7 +3272,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4006,7 +4613,7 @@ main (int argc, char **argv) +@@ -4077,7 +4684,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3281,7 +3281,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4027,6 +4634,29 @@ main (int argc, char **argv) +@@ -4098,6 +4705,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3311,7 +3311,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c have_read_stdin = false; inittables (); -@@ -4297,13 +4927,34 @@ main (int argc, char **argv) +@@ -4368,13 +4998,34 @@ main (int argc, char **argv) case 't': { @@ -3350,7 +3350,7 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -4314,9 +4965,12 @@ main (int argc, char **argv) +@@ -4385,9 +5036,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3365,9 +3365,9 @@ diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c } break; -diff -urNp coreutils-8.7-orig/src/unexpand.c coreutils-8.7/src/unexpand.c ---- coreutils-8.7-orig/src/unexpand.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/unexpand.c 2010-11-15 09:59:36.989931891 +0100 +diff -urNp coreutils-8.8-orig/src/unexpand.c coreutils-8.8/src/unexpand.c +--- coreutils-8.8-orig/src/unexpand.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/unexpand.c 2010-12-23 13:59:44.423512620 +0100 @@ -39,12 +39,29 @@ #include #include @@ -3621,9 +3621,9 @@ diff -urNp coreutils-8.7-orig/src/unexpand.c coreutils-8.7/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.7-orig/src/uniq.c coreutils-8.7/src/uniq.c ---- coreutils-8.7-orig/src/uniq.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/uniq.c 2010-11-15 09:59:36.992922043 +0100 +diff -urNp coreutils-8.8-orig/src/uniq.c coreutils-8.8/src/uniq.c +--- coreutils-8.8-orig/src/uniq.c 2010-08-14 01:49:07.000000000 +0200 ++++ coreutils-8.8/src/uniq.c 2010-12-23 13:59:44.426512446 +0100 @@ -21,6 +21,16 @@ #include #include @@ -3990,10 +3990,10 @@ diff -urNp coreutils-8.7-orig/src/uniq.c coreutils-8.7/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.7-orig/tests/Makefile.am coreutils-8.7/tests/Makefile.am ---- coreutils-8.7-orig/tests/Makefile.am 2010-11-15 09:58:44.197937898 +0100 -+++ coreutils-8.7/tests/Makefile.am 2010-11-15 09:59:36.993932170 +0100 -@@ -231,6 +231,7 @@ TESTS = \ +diff -urNp coreutils-8.8-orig/tests/Makefile.am coreutils-8.8/tests/Makefile.am +--- coreutils-8.8-orig/tests/Makefile.am 2010-12-23 13:59:21.007870308 +0100 ++++ coreutils-8.8/tests/Makefile.am 2010-12-23 13:59:44.428512331 +0100 +@@ -233,6 +233,7 @@ TESTS = \ misc/sort-debug-keys \ misc/sort-debug-warn \ misc/sort-files0-from \ @@ -4001,7 +4001,7 @@ diff -urNp coreutils-8.7-orig/tests/Makefile.am coreutils-8.7/tests/Makefile.am misc/sort-float \ misc/sort-merge \ misc/sort-merge-fdlimit \ -@@ -490,6 +491,10 @@ TESTS = \ +@@ -498,6 +499,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -4012,9 +4012,9 @@ diff -urNp coreutils-8.7-orig/tests/Makefile.am coreutils-8.7/tests/Makefile.am pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.7-orig/tests/misc/cut coreutils-8.7/tests/misc/cut ---- coreutils-8.7-orig/tests/misc/cut 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/tests/misc/cut 2010-11-15 09:59:36.994932100 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/cut coreutils-8.8/tests/misc/cut +--- coreutils-8.8-orig/tests/misc/cut 2010-01-01 14:06:47.000000000 +0100 ++++ coreutils-8.8/tests/misc/cut 2010-12-23 13:59:44.429512273 +0100 @@ -26,7 +26,7 @@ use strict; my $prog = 'cut'; my $try = "Try \`$prog --help' for more information.\n"; @@ -4033,41 +4033,41 @@ diff -urNp coreutils-8.7-orig/tests/misc/cut coreutils-8.7/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], -diff -urNp coreutils-8.7-orig/tests/misc/mb1.I coreutils-8.7/tests/misc/mb1.I ---- coreutils-8.7-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/mb1.I 2010-11-15 09:59:36.995931961 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/mb1.I coreutils-8.8/tests/misc/mb1.I +--- coreutils-8.8-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/mb1.I 2010-12-23 13:59:44.430512213 +0100 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.7-orig/tests/misc/mb1.X coreutils-8.7/tests/misc/mb1.X ---- coreutils-8.7-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/mb1.X 2010-11-15 09:59:36.995931961 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/mb1.X coreutils-8.8/tests/misc/mb1.X +--- coreutils-8.8-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/mb1.X 2010-12-23 13:59:44.430512213 +0100 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.7-orig/tests/misc/mb2.I coreutils-8.7/tests/misc/mb2.I ---- coreutils-8.7-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/mb2.I 2010-11-15 09:59:36.996933777 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/mb2.I coreutils-8.8/tests/misc/mb2.I +--- coreutils-8.8-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/mb2.I 2010-12-23 13:59:44.431512154 +0100 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.7-orig/tests/misc/mb2.X coreutils-8.7/tests/misc/mb2.X ---- coreutils-8.7-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/mb2.X 2010-11-15 09:59:36.997922462 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/mb2.X coreutils-8.8/tests/misc/mb2.X +--- coreutils-8.8-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/mb2.X 2010-12-23 13:59:44.432512095 +0100 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.7-orig/tests/misc/sort-mb-tests coreutils-8.7/tests/misc/sort-mb-tests ---- coreutils-8.7-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/tests/misc/sort-mb-tests 2010-11-15 09:59:36.997922462 +0100 +diff -urNp coreutils-8.8-orig/tests/misc/sort-mb-tests coreutils-8.8/tests/misc/sort-mb-tests +--- coreutils-8.8-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.8/tests/misc/sort-mb-tests 2010-12-23 13:59:44.433512037 +0100 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils.spec b/coreutils.spec index 266afc5..03f1c44 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.7 -Release: 2%{?dist} +Version: 8.8 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -332,6 +332,10 @@ fi %{_libdir}/coreutils %changelog +* Thu Dec 23 2010 Ondrej Vasik - 8.8-1 +- fix parallel sorting issue (#655096) +- new upstream release coreutils-8.8 (#665164) + * Thu Nov 18 2010 Ondrej Vasik - 8.7-2 - don't prompt for password with runuser(#654367) diff --git a/sources b/sources index 4aa4557..31af477 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -6e21df02e7f5c5d86372de4c6d873275 coreutils-8.7.tar.xz +a78848e3d7ba52e65b564ffea875ef20 coreutils-8.8.tar.xz From 1c281144c3f370d270d7dd1e0acc622c06922852 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 31 Dec 2010 08:39:14 +0100 Subject: [PATCH 118/523] The suffix length was dependent on the number of bytes or lines per file (#666293) --- coreutils-8.8-split-suffix.patch | 98 ++++++++++++++++++++++++++++++++ coreutils.spec | 9 ++- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.8-split-suffix.patch diff --git a/coreutils-8.8-split-suffix.patch b/coreutils-8.8-split-suffix.patch new file mode 100644 index 0000000..9301a91 --- /dev/null +++ b/coreutils-8.8-split-suffix.patch @@ -0,0 +1,98 @@ +From ec19e2a647cb64d4a5620787d4ecf5964d85fcf6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Thu, 30 Dec 2010 01:36:59 +0000 +Subject: [PATCH] split: fix the suffix length calculation + +* src/split.c (set_suffix_length): Only auto calculate +the suffix length when the number of files is specified. +* tests/misc/split-a: Add a case to trigger the bug. +--- + src/split.c | 32 ++++++++++++++++++++------------ + tests/misc/split-a | 5 +++++ + 2 files changed, 25 insertions(+), 12 deletions(-) + +diff --git a/src/split.c b/src/split.c +index ae98bc7..9e9efbf 100644 +--- a/src/split.c ++++ b/src/split.c +@@ -78,6 +78,13 @@ static bool elide_empty_files; + input to output, which is much slower, so disabled by default. */ + static bool unbuffered; + ++/* The split mode to use. */ ++enum Split_type ++{ ++ type_undef, type_bytes, type_byteslines, type_lines, type_digits, ++ type_chunk_bytes, type_chunk_lines, type_rr ++}; ++ + /* For long options that have no equivalent short option, use a + non-character as a pseudo short option, starting with CHAR_MAX + 1. */ + enum +@@ -105,16 +112,21 @@ static struct option const longopts[] = + }; + + static void +-set_suffix_length (uintmax_t n_units) ++set_suffix_length (uintmax_t n_units, enum Split_type split_type) + { + #define DEFAULT_SUFFIX_LENGTH 2 + + size_t suffix_needed = 0; +- size_t alphabet_len = strlen (suffix_alphabet); +- bool alphabet_slop = (n_units % alphabet_len) != 0; +- while (n_units /= alphabet_len) +- suffix_needed++; +- suffix_needed += alphabet_slop; ++ ++ if (split_type == type_chunk_bytes || split_type == type_chunk_lines ++ || split_type == type_rr) ++ { ++ size_t alphabet_len = strlen (suffix_alphabet); ++ bool alphabet_slop = (n_units % alphabet_len) != 0; ++ while (n_units /= alphabet_len) ++ suffix_needed++; ++ suffix_needed += alphabet_slop; ++ } + + if (suffix_length) /* set by user */ + { +@@ -780,11 +792,7 @@ int + main (int argc, char **argv) + { + struct stat stat_buf; +- enum +- { +- type_undef, type_bytes, type_byteslines, type_lines, type_digits, +- type_chunk_bytes, type_chunk_lines, type_rr +- } split_type = type_undef; ++ enum Split_type split_type = type_undef; + size_t in_blk_size = 0; /* optimal block size of input file device */ + char *buf; /* file i/o buffer */ + size_t page_size = getpagesize (); +@@ -984,7 +992,7 @@ main (int argc, char **argv) + usage (EXIT_FAILURE); + } + +- set_suffix_length (n_units); ++ set_suffix_length (n_units, split_type); + + /* Get out the filename arguments. */ + +diff --git a/tests/misc/split-a b/tests/misc/split-a +index d861b92..b0526bc 100755 +--- a/tests/misc/split-a ++++ b/tests/misc/split-a +@@ -63,4 +63,9 @@ for f in $files; do + n=$(expr $n + 1) + done + ++# Ensure that -a is independent of -[bCl] ++split -a2 -b1000 < /dev/null || fail=1 ++split -a2 -l1000 < /dev/null || fail=1 ++split -a2 -C1000 < /dev/null || fail=1 ++ + Exit $fail +-- +1.7.3.4 + diff --git a/coreutils.spec b/coreutils.spec index 03f1c44..bac4bda 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.8 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,6 +18,8 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream +#The suffix length was dependent on the number of bytes or lines per file(#666293) +Patch1: coreutils-8.8-split-suffix.patch # Our patches #general patch to workaround koji build system issues @@ -115,6 +117,7 @@ Libraries for coreutils package. %setup -q # From upstream +%patch1 -p1 -b .splitsuffix # Our patches %patch100 -p1 -b .configure @@ -332,6 +335,10 @@ fi %{_libdir}/coreutils %changelog +* Fri Dec 31 2010 Ondrej Vasik - 8.8-2 +- The suffix length was dependent on the number of bytes + or lines per file (#666293) + * Thu Dec 23 2010 Ondrej Vasik - 8.8-1 - fix parallel sorting issue (#655096) - new upstream release coreutils-8.8 (#665164) From 58ba6d52506242525fef5e6034763517941f001e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 4 Jan 2011 17:59:58 +0100 Subject: [PATCH 119/523] new upstream release coreutils-8.9 --- .gitignore | 1 + coreutils-6.10-manpages.patch | 2 +- coreutils-8.8-split-suffix.patch | 98 -------------------- coreutils-df-direct.patch | 65 ++++++------- coreutils-i18n.patch | 148 +++++++++++++++--------------- coreutils-selinux.patch | 152 +++++++++++++++---------------- coreutils.spec | 10 +- sources | 2 +- 8 files changed, 187 insertions(+), 291 deletions(-) delete mode 100644 coreutils-8.8-split-suffix.patch diff --git a/.gitignore b/.gitignore index 9ec635c..774bd70 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ coreutils-8.5.tar.xz /coreutils-8.6.tar.xz /coreutils-8.7.tar.xz /coreutils-8.8.tar.xz +/coreutils-8.9.tar.xz diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index 047c41c..2c663f9 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -3,7 +3,7 @@ diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c +++ coreutils-6.12/src/md5sum.c 2008-10-21 16:07:28.000000000 +0200 @@ -175,6 +175,9 @@ With no FILE, or when FILE is -, read st fputs (_("\ - -t, --text read in text mode (default)\n\ + -t, --text read in text mode (default)\n\ "), stdout); + fputs (_("\ + Note: There is no difference between binary and text mode option on GNU system.\n\ diff --git a/coreutils-8.8-split-suffix.patch b/coreutils-8.8-split-suffix.patch deleted file mode 100644 index 9301a91..0000000 --- a/coreutils-8.8-split-suffix.patch +++ /dev/null @@ -1,98 +0,0 @@ -From ec19e2a647cb64d4a5620787d4ecf5964d85fcf6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Thu, 30 Dec 2010 01:36:59 +0000 -Subject: [PATCH] split: fix the suffix length calculation - -* src/split.c (set_suffix_length): Only auto calculate -the suffix length when the number of files is specified. -* tests/misc/split-a: Add a case to trigger the bug. ---- - src/split.c | 32 ++++++++++++++++++++------------ - tests/misc/split-a | 5 +++++ - 2 files changed, 25 insertions(+), 12 deletions(-) - -diff --git a/src/split.c b/src/split.c -index ae98bc7..9e9efbf 100644 ---- a/src/split.c -+++ b/src/split.c -@@ -78,6 +78,13 @@ static bool elide_empty_files; - input to output, which is much slower, so disabled by default. */ - static bool unbuffered; - -+/* The split mode to use. */ -+enum Split_type -+{ -+ type_undef, type_bytes, type_byteslines, type_lines, type_digits, -+ type_chunk_bytes, type_chunk_lines, type_rr -+}; -+ - /* For long options that have no equivalent short option, use a - non-character as a pseudo short option, starting with CHAR_MAX + 1. */ - enum -@@ -105,16 +112,21 @@ static struct option const longopts[] = - }; - - static void --set_suffix_length (uintmax_t n_units) -+set_suffix_length (uintmax_t n_units, enum Split_type split_type) - { - #define DEFAULT_SUFFIX_LENGTH 2 - - size_t suffix_needed = 0; -- size_t alphabet_len = strlen (suffix_alphabet); -- bool alphabet_slop = (n_units % alphabet_len) != 0; -- while (n_units /= alphabet_len) -- suffix_needed++; -- suffix_needed += alphabet_slop; -+ -+ if (split_type == type_chunk_bytes || split_type == type_chunk_lines -+ || split_type == type_rr) -+ { -+ size_t alphabet_len = strlen (suffix_alphabet); -+ bool alphabet_slop = (n_units % alphabet_len) != 0; -+ while (n_units /= alphabet_len) -+ suffix_needed++; -+ suffix_needed += alphabet_slop; -+ } - - if (suffix_length) /* set by user */ - { -@@ -780,11 +792,7 @@ int - main (int argc, char **argv) - { - struct stat stat_buf; -- enum -- { -- type_undef, type_bytes, type_byteslines, type_lines, type_digits, -- type_chunk_bytes, type_chunk_lines, type_rr -- } split_type = type_undef; -+ enum Split_type split_type = type_undef; - size_t in_blk_size = 0; /* optimal block size of input file device */ - char *buf; /* file i/o buffer */ - size_t page_size = getpagesize (); -@@ -984,7 +992,7 @@ main (int argc, char **argv) - usage (EXIT_FAILURE); - } - -- set_suffix_length (n_units); -+ set_suffix_length (n_units, split_type); - - /* Get out the filename arguments. */ - -diff --git a/tests/misc/split-a b/tests/misc/split-a -index d861b92..b0526bc 100755 ---- a/tests/misc/split-a -+++ b/tests/misc/split-a -@@ -63,4 +63,9 @@ for f in $files; do - n=$(expr $n + 1) - done - -+# Ensure that -a is independent of -[bCl] -+split -a2 -b1000 < /dev/null || fail=1 -+split -a2 -l1000 < /dev/null || fail=1 -+split -a2 -C1000 < /dev/null || fail=1 -+ - Exit $fail --- -1.7.3.4 - diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 46b37c8..0f1d1b2 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,8 +1,7 @@ -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index fa21f03..7b8b622 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -10104,6 +10104,13 @@ pseudo-file-systems, such as automounter entries. +diff -urNp coreutils-8.9-orig/doc/coreutils.texi coreutils-8.9/doc/coreutils.texi +--- coreutils-8.9-orig/doc/coreutils.texi 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/doc/coreutils.texi 2011-01-04 17:38:33.323888382 +0100 +@@ -10306,6 +10306,13 @@ pseudo-file-systems, such as automounter Scale sizes by @var{size} before printing them (@pxref{Block size}). For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. @@ -16,11 +15,10 @@ index fa21f03..7b8b622 100644 @itemx --total @opindex --total @cindex grand total of disk size, usage and available space -diff --git a/src/df.c b/src/df.c -index b862879..a74c353 100644 ---- a/src/df.c -+++ b/src/df.c -@@ -110,6 +110,9 @@ static bool print_type; +diff -urNp coreutils-8.9-orig/src/df.c coreutils-8.9/src/df.c +--- coreutils-8.9-orig/src/df.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/df.c 2011-01-04 17:38:33.324887614 +0100 +@@ -109,6 +109,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -30,7 +28,7 @@ index b862879..a74c353 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -118,13 +121,15 @@ static struct fs_usage grand_fsu; +@@ -117,13 +120,15 @@ static struct fs_usage grand_fsu; enum { NO_SYNC_OPTION = CHAR_MAX + 1, @@ -47,7 +45,7 @@ index b862879..a74c353 100644 {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, -@@ -205,7 +210,10 @@ print_header (void) +@@ -204,7 +209,10 @@ print_header (void) human_readable (output_block_size, buf, opts, 1, 1)); } @@ -59,7 +57,7 @@ index b862879..a74c353 100644 } /* Is FSTYPE a type of file system that should be listed? */ -@@ -754,6 +762,17 @@ show_point (const char *point, const struct stat *statp) +@@ -646,6 +654,17 @@ show_point (const char *point, const str static void show_entry (char const *name, struct stat const *statp) { @@ -77,15 +75,15 @@ index b862879..a74c353 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && show_disk (name)) return; -@@ -820,6 +839,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\ +@@ -714,6 +733,7 @@ Mandatory arguments to long options are -B, --block-size=SIZE scale sizes by SIZE before printing them. E.g.,\n\ `-BM' prints sizes in units of 1,048,576 bytes.\n\ See SIZE format below.\n\ + --direct show statistics for a file instead of mount point\n\ --total produce a grand total\n\ - -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\n\ - -H, --si likewise, but use powers of 1000 not 1024\n\ -@@ -894,6 +914,9 @@ main (int argc, char **argv) + -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\ + \n\ +@@ -790,6 +810,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -95,7 +93,7 @@ index b862879..a74c353 100644 case 'i': inode_format = true; break; -@@ -954,6 +977,13 @@ main (int argc, char **argv) +@@ -850,6 +873,13 @@ main (int argc, char **argv) } } @@ -109,23 +107,9 @@ index b862879..a74c353 100644 if (human_output_opts == -1) { if (posix_format) -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 1cb5a76..ab7abb4 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -328,6 +328,7 @@ TESTS = \ - dd/stderr \ - dd/unblock \ - dd/unblock-sync \ -+ df/direct \ - df/total-verify \ - du/2g \ - du/8gb \ -diff --git a/tests/df/direct b/tests/df/direct -new file mode 100644 -index 0000000..9088f27 ---- /dev/null -+++ b/tests/df/direct +diff -urNp coreutils-8.9-orig/tests/df/direct coreutils-8.9/tests/df/direct +--- coreutils-8.9-orig/tests/df/direct 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.9/tests/df/direct 2011-01-04 17:38:33.328138905 +0100 @@ -0,0 +1,55 @@ +#!/bin/sh +# Ensure "df --direct" works as documented @@ -182,3 +166,14 @@ index 0000000..9088f27 +compare file_out file_exp || fail=1 + +Exit $fail +diff -urNp coreutils-8.9-orig/tests/Makefile.am coreutils-8.9/tests/Makefile.am +--- coreutils-8.9-orig/tests/Makefile.am 2011-01-04 17:37:57.837887753 +0100 ++++ coreutils-8.9/tests/Makefile.am 2011-01-04 17:38:33.326913944 +0100 +@@ -352,6 +352,7 @@ TESTS = \ + dd/stderr \ + dd/unblock \ + dd/unblock-sync \ ++ df/direct \ + df/total-verify \ + du/2g \ + du/8gb \ diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index c26d702..7ea01f7 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.8-orig/lib/linebuffer.h coreutils-8.8/lib/linebuffer.h ---- coreutils-8.8-orig/lib/linebuffer.h 2010-04-23 15:44:00.000000000 +0200 -+++ coreutils-8.8/lib/linebuffer.h 2010-12-23 13:59:44.393514385 +0100 +diff -urNp coreutils-8.9-orig/lib/linebuffer.h coreutils-8.9/lib/linebuffer.h +--- coreutils-8.9-orig/lib/linebuffer.h 2011-01-01 22:19:27.000000000 +0100 ++++ coreutils-8.9/lib/linebuffer.h 2011-01-04 17:41:55.358888521 +0100 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.8-orig/lib/linebuffer.h coreutils-8.8/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.8-orig/src/cut.c coreutils-8.8/src/cut.c ---- coreutils-8.8-orig/src/cut.c 2010-08-14 01:49:07.000000000 +0200 -+++ coreutils-8.8/src/cut.c 2010-12-23 13:59:44.397514141 +0100 +diff -urNp coreutils-8.9-orig/src/cut.c coreutils-8.9/src/cut.c +--- coreutils-8.9-orig/src/cut.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/cut.c 2011-01-04 17:41:55.361888730 +0100 @@ -28,6 +28,11 @@ #include #include @@ -616,9 +616,9 @@ diff -urNp coreutils-8.8-orig/src/cut.c coreutils-8.8/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.8-orig/src/expand.c coreutils-8.8/src/expand.c ---- coreutils-8.8-orig/src/expand.c 2010-08-14 01:49:07.000000000 +0200 -+++ coreutils-8.8/src/expand.c 2010-12-23 13:59:44.399514013 +0100 +diff -urNp coreutils-8.9-orig/src/expand.c coreutils-8.9/src/expand.c +--- coreutils-8.9-orig/src/expand.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/expand.c 2011-01-04 17:41:55.363905562 +0100 @@ -38,12 +38,29 @@ #include #include @@ -806,9 +806,9 @@ diff -urNp coreutils-8.8-orig/src/expand.c coreutils-8.8/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.8-orig/src/fold.c coreutils-8.8/src/fold.c ---- coreutils-8.8-orig/src/fold.c 2010-11-27 16:06:22.000000000 +0100 -+++ coreutils-8.8/src/fold.c 2010-12-23 13:59:44.401513895 +0100 +diff -urNp coreutils-8.9-orig/src/fold.c coreutils-8.9/src/fold.c +--- coreutils-8.9-orig/src/fold.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/fold.c 2011-01-04 17:41:55.366888520 +0100 @@ -22,12 +22,34 @@ #include #include @@ -1207,9 +1207,9 @@ diff -urNp coreutils-8.8-orig/src/fold.c coreutils-8.8/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.8-orig/src/join.c coreutils-8.8/src/join.c ---- coreutils-8.8-orig/src/join.c 2010-09-17 11:13:45.000000000 +0200 -+++ coreutils-8.8/src/join.c 2010-12-23 13:59:44.404513732 +0100 +diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c +--- coreutils-8.9-orig/src/join.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/join.c 2011-01-04 17:41:55.369888660 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1692,9 +1692,9 @@ diff -urNp coreutils-8.8-orig/src/join.c coreutils-8.8/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.8-orig/src/pr.c coreutils-8.8/src/pr.c ---- coreutils-8.8-orig/src/pr.c 2010-08-14 01:49:07.000000000 +0200 -+++ coreutils-8.8/src/pr.c 2010-12-23 13:59:44.410513374 +0100 +diff -urNp coreutils-8.9-orig/src/pr.c coreutils-8.9/src/pr.c +--- coreutils-8.9-orig/src/pr.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/pr.c 2011-01-04 17:41:55.377138275 +0100 @@ -312,6 +312,32 @@ #include @@ -2417,9 +2417,9 @@ diff -urNp coreutils-8.8-orig/src/pr.c coreutils-8.8/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c ---- coreutils-8.8-orig/src/sort.c 2010-12-20 12:20:41.000000000 +0100 -+++ coreutils-8.8/src/sort.c 2010-12-23 13:59:44.420512797 +0100 +diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c +--- coreutils-8.9-orig/src/sort.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/sort.c 2011-01-04 17:41:55.384888730 +0100 @@ -22,11 +22,20 @@ #include @@ -2494,7 +2494,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -768,6 +797,46 @@ reap_all (void) +@@ -775,6 +804,46 @@ reap_all (void) reap (-1); } @@ -2541,7 +2541,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1200,7 +1269,7 @@ zaptemp (char const *name) +@@ -1207,7 +1276,7 @@ zaptemp (char const *name) free (node); } @@ -2550,7 +2550,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1215,7 +1284,7 @@ struct_month_cmp (void const *m1, void c +@@ -1222,7 +1291,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2559,7 +2559,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c { size_t i; -@@ -1227,7 +1296,7 @@ inittables (void) +@@ -1234,7 +1303,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2568,7 +2568,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1309,6 +1378,84 @@ specify_nmerge (int oi, char c, char con +@@ -1316,6 +1385,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2653,7 +2653,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1537,7 +1684,7 @@ buffer_linelim (struct buffer const *buf +@@ -1544,7 +1691,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2662,7 +2662,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1546,10 +1693,10 @@ begfield (struct line const *line, struc +@@ -1553,10 +1700,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2675,7 +2675,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1575,11 +1722,70 @@ begfield (struct line const *line, struc +@@ -1582,11 +1729,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2747,7 +2747,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1594,10 +1800,10 @@ limfield (struct line const *line, struc +@@ -1601,10 +1807,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. */ @@ -2760,7 +2760,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1643,10 +1849,10 @@ limfield (struct line const *line, struc +@@ -1650,10 +1856,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2773,7 +2773,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c if (newlim) lim = newlim; } -@@ -1677,6 +1883,130 @@ limfield (struct line const *line, struc +@@ -1684,6 +1890,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2904,7 +2904,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c /* 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 -@@ -1763,8 +2093,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1770,8 +2100,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2929,7 +2929,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c line->keybeg = line_start; } } -@@ -1885,7 +2229,7 @@ human_numcompare (char const *a, char co +@@ -1892,7 +2236,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2938,7 +2938,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1895,6 +2239,25 @@ numcompare (char const *a, char const *b +@@ -1902,6 +2246,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2964,7 +2964,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c static int general_numcompare (char const *sa, char const *sb) { -@@ -1927,7 +2290,7 @@ general_numcompare (char const *sa, char +@@ -1934,7 +2297,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -2973,7 +2973,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2202,13 +2565,12 @@ debug_key (struct line const *line, stru +@@ -2209,13 +2572,12 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -2989,7 +2989,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2352,7 +2714,7 @@ key_warnings (struct keyfield const *gke +@@ -2359,7 +2721,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2998,7 +2998,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2410,11 +2772,83 @@ key_warnings (struct keyfield const *gke +@@ -2417,11 +2779,83 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option `-r' only applies to last-resort comparison")); } @@ -3083,7 +3083,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c { struct keyfield *key = keylist; -@@ -2499,7 +2933,7 @@ keycompare (struct line const *a, struct +@@ -2506,7 +2940,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3092,7 +3092,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2615,6 +3049,179 @@ keycompare (struct line const *a, struct +@@ -2622,6 +3056,179 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3272,7 +3272,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4077,7 +4684,7 @@ main (int argc, char **argv) +@@ -4084,7 +4691,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3281,7 +3281,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4098,6 +4705,29 @@ main (int argc, char **argv) +@@ -4105,6 +4712,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3311,7 +3311,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c have_read_stdin = false; inittables (); -@@ -4368,13 +4998,34 @@ main (int argc, char **argv) +@@ -4375,13 +5005,34 @@ main (int argc, char **argv) case 't': { @@ -3350,7 +3350,7 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -4385,9 +5036,12 @@ main (int argc, char **argv) +@@ -4392,9 +5043,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3365,9 +3365,9 @@ diff -urNp coreutils-8.8-orig/src/sort.c coreutils-8.8/src/sort.c } break; -diff -urNp coreutils-8.8-orig/src/unexpand.c coreutils-8.8/src/unexpand.c ---- coreutils-8.8-orig/src/unexpand.c 2010-08-14 01:49:07.000000000 +0200 -+++ coreutils-8.8/src/unexpand.c 2010-12-23 13:59:44.423512620 +0100 +diff -urNp coreutils-8.9-orig/src/unexpand.c coreutils-8.9/src/unexpand.c +--- coreutils-8.9-orig/src/unexpand.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/unexpand.c 2011-01-04 17:41:55.387888171 +0100 @@ -39,12 +39,29 @@ #include #include @@ -3621,9 +3621,9 @@ diff -urNp coreutils-8.8-orig/src/unexpand.c coreutils-8.8/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.8-orig/src/uniq.c coreutils-8.8/src/uniq.c ---- coreutils-8.8-orig/src/uniq.c 2010-08-14 01:49:07.000000000 +0200 -+++ coreutils-8.8/src/uniq.c 2010-12-23 13:59:44.426512446 +0100 +diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c +--- coreutils-8.9-orig/src/uniq.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/uniq.c 2011-01-04 17:41:55.391888381 +0100 @@ -21,6 +21,16 @@ #include #include @@ -3990,9 +3990,9 @@ diff -urNp coreutils-8.8-orig/src/uniq.c coreutils-8.8/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.8-orig/tests/Makefile.am coreutils-8.8/tests/Makefile.am ---- coreutils-8.8-orig/tests/Makefile.am 2010-12-23 13:59:21.007870308 +0100 -+++ coreutils-8.8/tests/Makefile.am 2010-12-23 13:59:44.428512331 +0100 +diff -urNp coreutils-8.9-orig/tests/Makefile.am coreutils-8.9/tests/Makefile.am +--- coreutils-8.9-orig/tests/Makefile.am 2011-01-04 17:41:12.682173268 +0100 ++++ coreutils-8.9/tests/Makefile.am 2011-01-04 17:41:55.392900534 +0100 @@ -233,6 +233,7 @@ TESTS = \ misc/sort-debug-keys \ misc/sort-debug-warn \ @@ -4012,9 +4012,9 @@ diff -urNp coreutils-8.8-orig/tests/Makefile.am coreutils-8.8/tests/Makefile.am pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.8-orig/tests/misc/cut coreutils-8.8/tests/misc/cut ---- coreutils-8.8-orig/tests/misc/cut 2010-01-01 14:06:47.000000000 +0100 -+++ coreutils-8.8/tests/misc/cut 2010-12-23 13:59:44.429512273 +0100 +diff -urNp coreutils-8.9-orig/tests/misc/cut coreutils-8.9/tests/misc/cut +--- coreutils-8.9-orig/tests/misc/cut 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/tests/misc/cut 2011-01-04 17:41:55.393887822 +0100 @@ -26,7 +26,7 @@ use strict; my $prog = 'cut'; my $try = "Try \`$prog --help' for more information.\n"; @@ -4024,7 +4024,7 @@ diff -urNp coreutils-8.8-orig/tests/misc/cut coreutils-8.8/tests/misc/cut my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; my @Tests = -@@ -141,7 +141,7 @@ my @Tests = +@@ -143,7 +143,7 @@ my @Tests = # None of the following invalid ranges provoked an error up to coreutils-6.9. ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, @@ -4032,42 +4032,42 @@ diff -urNp coreutils-8.8-orig/tests/misc/cut coreutils-8.8/tests/misc/cut + {ERR=>"$prog: invalid byte, character or field list\n$try"}], ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], - ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], -diff -urNp coreutils-8.8-orig/tests/misc/mb1.I coreutils-8.8/tests/misc/mb1.I ---- coreutils-8.8-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.8/tests/misc/mb1.I 2010-12-23 13:59:44.430512213 +0100 + ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, +diff -urNp coreutils-8.9-orig/tests/misc/mb1.I coreutils-8.9/tests/misc/mb1.I +--- coreutils-8.9-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.9/tests/misc/mb1.I 2011-01-04 17:41:55.394899835 +0100 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.8-orig/tests/misc/mb1.X coreutils-8.8/tests/misc/mb1.X ---- coreutils-8.8-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.8/tests/misc/mb1.X 2010-12-23 13:59:44.430512213 +0100 +diff -urNp coreutils-8.9-orig/tests/misc/mb1.X coreutils-8.9/tests/misc/mb1.X +--- coreutils-8.9-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.9/tests/misc/mb1.X 2011-01-04 17:41:55.395888102 +0100 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.8-orig/tests/misc/mb2.I coreutils-8.8/tests/misc/mb2.I ---- coreutils-8.8-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.8/tests/misc/mb2.I 2010-12-23 13:59:44.431512154 +0100 +diff -urNp coreutils-8.9-orig/tests/misc/mb2.I coreutils-8.9/tests/misc/mb2.I +--- coreutils-8.9-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.9/tests/misc/mb2.I 2011-01-04 17:41:55.395888102 +0100 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.8-orig/tests/misc/mb2.X coreutils-8.8/tests/misc/mb2.X ---- coreutils-8.8-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.8/tests/misc/mb2.X 2010-12-23 13:59:44.432512095 +0100 +diff -urNp coreutils-8.9-orig/tests/misc/mb2.X coreutils-8.9/tests/misc/mb2.X +--- coreutils-8.9-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.9/tests/misc/mb2.X 2011-01-04 17:41:55.396892432 +0100 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.8-orig/tests/misc/sort-mb-tests coreutils-8.8/tests/misc/sort-mb-tests ---- coreutils-8.8-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.8/tests/misc/sort-mb-tests 2010-12-23 13:59:44.433512037 +0100 +diff -urNp coreutils-8.9-orig/tests/misc/sort-mb-tests coreutils-8.9/tests/misc/sort-mb-tests +--- coreutils-8.9-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.9/tests/misc/sort-mb-tests 2011-01-04 17:41:55.396892432 +0100 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 4ad7e6b..8415aee 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.7-orig/configure.ac coreutils-8.7/configure.ac ---- coreutils-8.7-orig/configure.ac 2010-11-15 10:03:39.636171519 +0100 -+++ coreutils-8.7/configure.ac 2010-11-15 10:04:08.161930423 +0100 -@@ -133,6 +133,13 @@ if test "$gl_gcc_warnings" = yes; then +diff -urNp coreutils-8.9-orig/configure.ac coreutils-8.9/configure.ac +--- coreutils-8.9-orig/configure.ac 2011-01-04 17:43:03.876887473 +0100 ++++ coreutils-8.9/configure.ac 2011-01-04 17:43:36.194889010 +0100 +@@ -132,6 +132,13 @@ if test "$gl_gcc_warnings" = yes; then AC_SUBST([GNULIB_TEST_WARN_CFLAGS]) fi @@ -15,18 +15,18 @@ diff -urNp coreutils-8.7-orig/configure.ac coreutils-8.7/configure.ac AC_FUNC_FORK AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam], -diff -urNp coreutils-8.7-orig/man/chcon.x coreutils-8.7/man/chcon.x ---- coreutils-8.7-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.7/man/chcon.x 2010-11-15 10:04:08.161930423 +0100 +diff -urNp coreutils-8.9-orig/man/chcon.x coreutils-8.9/man/chcon.x +--- coreutils-8.9-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.9/man/chcon.x 2011-01-04 17:43:36.195889150 +0100 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-8.7-orig/man/runcon.x coreutils-8.7/man/runcon.x ---- coreutils-8.7-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.7/man/runcon.x 2010-11-15 10:04:08.162922322 +0100 +diff -urNp coreutils-8.9-orig/man/runcon.x coreutils-8.9/man/runcon.x +--- coreutils-8.9-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.9/man/runcon.x 2011-01-04 17:43:36.195889150 +0100 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,10 +34,10 @@ diff -urNp coreutils-8.7-orig/man/runcon.x coreutils-8.7/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.7-orig/src/copy.c coreutils-8.7/src/copy.c ---- coreutils-8.7-orig/src/copy.c 2010-10-28 12:31:17.000000000 +0200 -+++ coreutils-8.7/src/copy.c 2010-11-15 10:04:08.165921553 +0100 -@@ -1924,6 +1924,8 @@ copy_internal (char const *src_name, cha +diff -urNp coreutils-8.9-orig/src/copy.c coreutils-8.9/src/copy.c +--- coreutils-8.9-orig/src/copy.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/copy.c 2011-01-04 17:43:36.199888591 +0100 +@@ -1931,6 +1931,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -46,9 +46,9 @@ diff -urNp coreutils-8.7-orig/src/copy.c coreutils-8.7/src/copy.c } else { -diff -urNp coreutils-8.7-orig/src/copy.h coreutils-8.7/src/copy.h ---- coreutils-8.7-orig/src/copy.h 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/copy.h 2010-11-15 10:04:08.166925814 +0100 +diff -urNp coreutils-8.9-orig/src/copy.h coreutils-8.9/src/copy.h +--- coreutils-8.9-orig/src/copy.h 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/copy.h 2011-01-04 17:43:36.201889220 +0100 @@ -158,6 +158,9 @@ struct cp_options bool preserve_mode; bool preserve_timestamps; @@ -59,9 +59,9 @@ diff -urNp coreutils-8.7-orig/src/copy.h coreutils-8.7/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c ---- coreutils-8.7-orig/src/cp.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/cp.c 2010-11-15 10:04:08.168931890 +0100 +diff -urNp coreutils-8.9-orig/src/cp.c coreutils-8.9/src/cp.c +--- coreutils-8.9-orig/src/cp.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/cp.c 2011-01-04 17:43:36.202898439 +0100 @@ -141,6 +141,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, @@ -70,7 +70,7 @@ diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -200,6 +201,9 @@ Mandatory arguments to long options are +@@ -204,6 +205,9 @@ Mandatory arguments to long options are all\n\ "), stdout); fputs (_("\ @@ -80,7 +80,7 @@ diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents use full source file name under DIRECTORY\n\ "), stdout); -@@ -226,6 +230,7 @@ Mandatory arguments to long options are +@@ -230,6 +234,7 @@ Mandatory arguments to long options are destination file is missing\n\ -v, --verbose explain what is being done\n\ -x, --one-file-system stay on this file system\n\ @@ -88,7 +88,7 @@ diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); -@@ -780,6 +785,7 @@ cp_option_init (struct cp_options *x) +@@ -786,6 +791,7 @@ cp_option_init (struct cp_options *x) x->preserve_timestamps = false; x->preserve_security_context = false; x->require_preserve_context = false; @@ -96,7 +96,7 @@ diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c x->preserve_xattr = false; x->reduce_diagnostics = false; x->require_preserve_xattr = false; -@@ -927,7 +933,7 @@ main (int argc, char **argv) +@@ -933,7 +939,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -105,7 +105,7 @@ diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c long_opts, NULL)) != -1) { -@@ -974,6 +980,16 @@ main (int argc, char **argv) +@@ -981,6 +987,16 @@ main (int argc, char **argv) copy_contents = true; break; @@ -122,7 +122,7 @@ diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -@@ -1083,6 +1099,27 @@ main (int argc, char **argv) +@@ -1090,6 +1106,27 @@ main (int argc, char **argv) x.one_file_system = true; break; @@ -150,9 +150,9 @@ diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urNp coreutils-8.7-orig/src/chcon.c coreutils-8.7/src/chcon.c ---- coreutils-8.7-orig/src/chcon.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/chcon.c 2010-11-15 10:04:08.169922391 +0100 +diff -urNp coreutils-8.9-orig/src/chcon.c coreutils-8.9/src/chcon.c +--- coreutils-8.9-orig/src/chcon.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/chcon.c 2011-01-04 17:43:36.205888452 +0100 @@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), program_name, program_name, program_name); @@ -162,9 +162,9 @@ diff -urNp coreutils-8.7-orig/src/chcon.c coreutils-8.7/src/chcon.c With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ -h, --no-dereference affect symbolic links instead of any referenced file\n\ -diff -urNp coreutils-8.7-orig/src/id.c coreutils-8.7/src/id.c ---- coreutils-8.7-orig/src/id.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/id.c 2010-11-15 10:04:08.170933217 +0100 +diff -urNp coreutils-8.9-orig/src/id.c coreutils-8.9/src/id.c +--- coreutils-8.9-orig/src/id.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/id.c 2011-01-04 17:43:36.206888661 +0100 @@ -107,7 +107,7 @@ int main (int argc, char **argv) { @@ -174,9 +174,9 @@ diff -urNp coreutils-8.7-orig/src/id.c coreutils-8.7/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urNp coreutils-8.7-orig/src/install.c coreutils-8.7/src/install.c ---- coreutils-8.7-orig/src/install.c 2010-10-15 21:56:29.000000000 +0200 -+++ coreutils-8.7/src/install.c 2010-11-15 10:04:08.171921693 +0100 +diff -urNp coreutils-8.9-orig/src/install.c coreutils-8.9/src/install.c +--- coreutils-8.9-orig/src/install.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/install.c 2011-01-04 17:47:30.255887962 +0100 @@ -283,6 +283,7 @@ cp_option_init (struct cp_options *x) x->data_copy_required = true; x->require_preserve = false; @@ -221,20 +221,18 @@ diff -urNp coreutils-8.7-orig/src/install.c coreutils-8.7/src/install.c use_default_selinux_context = false; break; case_GETOPT_HELP_CHAR; -@@ -985,8 +992,8 @@ Mandatory arguments to long options are +@@ -985,7 +992,7 @@ Mandatory arguments to long options are -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ - --preserve-context preserve SELinux security context\n\ -- -Z, --context=CONTEXT set SELinux security context of files and directories\n\ -+ -P, --preserve-context (SELinux) preserve security context\n\ -+ -Z, --context=CONTEXT (SELinux) set security context of files and directories\n\ ++ -P, --preserve-context preserve SELinux security context\n\ + -Z, --context=CONTEXT set SELinux security context of files and directories\ + \n\ "), stdout); - - fputs (HELP_OPTION_DESCRIPTION, stdout); -diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c ---- coreutils-8.7-orig/src/ls.c 2010-10-25 12:07:57.000000000 +0200 -+++ coreutils-8.7/src/ls.c 2010-11-15 10:04:08.175921763 +0100 +diff -urNp coreutils-8.9-orig/src/ls.c coreutils-8.9/src/ls.c +--- coreutils-8.9-orig/src/ls.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/ls.c 2011-01-04 17:43:36.211887474 +0100 @@ -159,7 +159,8 @@ enum filetype symbolic_link, sock, @@ -384,7 +382,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c default: usage (LS_FAILURE); } -@@ -2690,8 +2714,10 @@ clear_files (void) +@@ -2691,8 +2715,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); @@ -397,7 +395,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c } cwd_n_used = 0; -@@ -2733,6 +2759,7 @@ gobble_file (char const *name, enum file +@@ -2734,6 +2760,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -405,7 +403,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c if (command_line_arg || format_needs_stat -@@ -2842,7 +2869,7 @@ gobble_file (char const *name, enum file +@@ -2843,7 +2870,7 @@ gobble_file (char const *name, enum file && print_with_color && is_colored (C_CAP)) f->has_capability = has_capability (absolute_name); @@ -414,7 +412,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c { bool have_selinux = false; bool have_acl = false; -@@ -2865,7 +2892,7 @@ gobble_file (char const *name, enum file +@@ -2866,7 +2893,7 @@ gobble_file (char const *name, enum file err = 0; } @@ -423,7 +421,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c { int n = file_has_acl (absolute_name, &f->stat); err = (n < 0); -@@ -2884,7 +2911,8 @@ gobble_file (char const *name, enum file +@@ -2885,7 +2912,8 @@ gobble_file (char const *name, enum file } if (S_ISLNK (f->stat.st_mode) @@ -433,7 +431,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c { char *linkname; struct stat linkstats; -@@ -2904,6 +2932,7 @@ gobble_file (char const *name, enum file +@@ -2905,6 +2933,7 @@ gobble_file (char const *name, enum file command line are automatically traced if not being listed as files. */ if (!command_line_arg || format == long_format @@ -441,7 +439,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c || !S_ISDIR (linkstats.st_mode)) { /* Get the linked-to file's mode for the filetype indicator -@@ -2943,7 +2972,7 @@ gobble_file (char const *name, enum file +@@ -2944,7 +2973,7 @@ gobble_file (char const *name, enum file block_size_width = len; } @@ -450,7 +448,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c { if (print_owner) { -@@ -3444,6 +3473,13 @@ print_current_files (void) +@@ -3445,6 +3474,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -464,7 +462,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c break; } } -@@ -3606,6 +3642,67 @@ format_inode (char *buf, size_t buflen, +@@ -3607,6 +3643,67 @@ format_inode (char *buf, size_t buflen, : (char *) "?"); } @@ -532,7 +530,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c /* Print information about F in long format. */ static void print_long_format (const struct fileinfo *f) -@@ -3697,9 +3794,15 @@ print_long_format (const struct fileinfo +@@ -3698,9 +3795,15 @@ print_long_format (const struct fileinfo The latter is wrong when nlink_width is zero. */ p += strlen (p); @@ -549,7 +547,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c { DIRED_FPUTS (buf, stdout, p - buf); -@@ -3712,9 +3815,6 @@ print_long_format (const struct fileinfo +@@ -3713,9 +3816,6 @@ print_long_format (const struct fileinfo if (print_author) format_user (f->stat.st_author, author_width, f->stat_ok); @@ -559,7 +557,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c p = buf; } -@@ -4059,9 +4159,6 @@ print_file_name_and_frills (const struct +@@ -4060,9 +4160,6 @@ print_file_name_and_frills (const struct : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ST_NBLOCKSIZE, output_block_size)); @@ -569,7 +567,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c size_t width = print_name_with_quoting (f, false, NULL, start_col); if (indicator_style != none) -@@ -4265,9 +4362,6 @@ length_of_file_name_and_frills (const st +@@ -4266,9 +4363,6 @@ length_of_file_name_and_frills (const st output_block_size)) : block_size_width); @@ -579,7 +577,7 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c quote_name (NULL, f->name, filename_quoting_options, &name_width); len += name_width; -@@ -4700,9 +4794,16 @@ Mandatory arguments to long options are +@@ -4707,9 +4801,16 @@ Mandatory arguments to long options are -w, --width=COLS assume screen width instead of current value\n\ -x list entries by lines instead of by columns\n\ -X sort alphabetically by entry extension\n\ @@ -597,9 +595,9 @@ diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-8.7-orig/src/mkdir.c coreutils-8.7/src/mkdir.c ---- coreutils-8.7-orig/src/mkdir.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/mkdir.c 2010-11-15 10:04:08.177942716 +0100 +diff -urNp coreutils-8.9-orig/src/mkdir.c coreutils-8.9/src/mkdir.c +--- coreutils-8.9-orig/src/mkdir.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/mkdir.c 2011-01-04 17:43:36.213899906 +0100 @@ -38,6 +38,7 @@ static struct option const longopts[] = { @@ -608,9 +606,9 @@ diff -urNp coreutils-8.7-orig/src/mkdir.c coreutils-8.7/src/mkdir.c {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, -diff -urNp coreutils-8.7-orig/src/mknod.c coreutils-8.7/src/mknod.c ---- coreutils-8.7-orig/src/mknod.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/mknod.c 2010-11-15 10:04:08.177942716 +0100 +diff -urNp coreutils-8.9-orig/src/mknod.c coreutils-8.9/src/mknod.c +--- coreutils-8.9-orig/src/mknod.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/mknod.c 2011-01-04 17:43:36.215887404 +0100 @@ -35,7 +35,7 @@ static struct option const longopts[] = @@ -620,9 +618,9 @@ diff -urNp coreutils-8.7-orig/src/mknod.c coreutils-8.7/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urNp coreutils-8.7-orig/src/mv.c coreutils-8.7/src/mv.c ---- coreutils-8.7-orig/src/mv.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/mv.c 2010-11-15 10:04:08.179924138 +0100 +diff -urNp coreutils-8.9-orig/src/mv.c coreutils-8.9/src/mv.c +--- coreutils-8.9-orig/src/mv.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/mv.c 2011-01-04 17:43:36.216896344 +0100 @@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x) x->preserve_mode = true; x->preserve_timestamps = true; @@ -631,9 +629,9 @@ diff -urNp coreutils-8.7-orig/src/mv.c coreutils-8.7/src/mv.c x->reduce_diagnostics = false; x->data_copy_required = true; x->require_preserve = false; /* FIXME: maybe make this an option */ -diff -urNp coreutils-8.7-orig/src/runcon.c coreutils-8.7/src/runcon.c ---- coreutils-8.7-orig/src/runcon.c 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/src/runcon.c 2010-11-15 10:04:08.180922252 +0100 +diff -urNp coreutils-8.9-orig/src/runcon.c coreutils-8.9/src/runcon.c +--- coreutils-8.9-orig/src/runcon.c 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/src/runcon.c 2011-01-04 17:43:36.216896344 +0100 @@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ "), program_name, program_name); @@ -643,9 +641,9 @@ diff -urNp coreutils-8.7-orig/src/runcon.c coreutils-8.7/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urNp coreutils-8.7-orig/tests/init.cfg coreutils-8.7/tests/init.cfg ---- coreutils-8.7-orig/tests/init.cfg 2010-11-08 14:10:20.000000000 +0100 -+++ coreutils-8.7/tests/init.cfg 2010-11-15 10:04:08.181922042 +0100 +diff -urNp coreutils-8.9-orig/tests/init.cfg coreutils-8.9/tests/init.cfg +--- coreutils-8.9-orig/tests/init.cfg 2010-12-22 12:29:13.000000000 +0100 ++++ coreutils-8.9/tests/init.cfg 2011-01-04 17:43:36.218137788 +0100 @@ -216,8 +216,8 @@ skip_if_() require_selinux_() @@ -657,10 +655,10 @@ diff -urNp coreutils-8.7-orig/tests/init.cfg coreutils-8.7/tests/init.cfg skip_test_ "this system (or maybe just" \ "the current file system) lacks SELinux support" ;; -diff -urNp coreutils-8.7-orig/tests/misc/selinux coreutils-8.7/tests/misc/selinux ---- coreutils-8.7-orig/tests/misc/selinux 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/tests/misc/selinux 2010-11-15 10:04:08.181922042 +0100 -@@ -44,7 +44,7 @@ chcon $ctx f d p || +diff -urNp coreutils-8.9-orig/tests/misc/selinux coreutils-8.9/tests/misc/selinux +--- coreutils-8.9-orig/tests/misc/selinux 2011-01-01 22:19:23.000000000 +0100 ++++ coreutils-8.9/tests/misc/selinux 2011-01-04 17:43:36.219137718 +0100 +@@ -37,7 +37,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. for i in d f p; do diff --git a/coreutils.spec b/coreutils.spec index bac4bda..0cd8520 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.8 -Release: 2%{?dist} +Version: 8.9 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,8 +18,6 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -#The suffix length was dependent on the number of bytes or lines per file(#666293) -Patch1: coreutils-8.8-split-suffix.patch # Our patches #general patch to workaround koji build system issues @@ -117,7 +115,6 @@ Libraries for coreutils package. %setup -q # From upstream -%patch1 -p1 -b .splitsuffix # Our patches %patch100 -p1 -b .configure @@ -335,6 +332,9 @@ fi %{_libdir}/coreutils %changelog +* Tue Jan 04 2011 Ondrej Vasik - 8.9-1 +- new upstream release coreutils-8.9 + * Fri Dec 31 2010 Ondrej Vasik - 8.8-2 - The suffix length was dependent on the number of bytes or lines per file (#666293) diff --git a/sources b/sources index 31af477..e618b3c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -a78848e3d7ba52e65b564ffea875ef20 coreutils-8.8.tar.xz +4a38f51941bae177c997cda9bdc603bd coreutils-8.9.tar.xz From 0c817be19f68f822571d113f04b8f0d93102003b Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Sat, 8 Jan 2011 23:42:18 -0600 Subject: [PATCH 120/523] drop no longer needed mkstemp patch for sparc --- coreutils-mkstemp.patch | 9 --------- coreutils.spec | 8 ++++---- 2 files changed, 4 insertions(+), 13 deletions(-) delete mode 100644 coreutils-mkstemp.patch diff --git a/coreutils-mkstemp.patch b/coreutils-mkstemp.patch deleted file mode 100644 index af8d273..0000000 --- a/coreutils-mkstemp.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- coreutils-7.6/lib/mkstemp.c.BAD 2010-03-03 18:17:52.000000000 +0000 -+++ coreutils-7.6/lib/mkstemp.c 2010-03-03 18:18:28.000000000 +0000 -@@ -40,5 +40,5 @@ - int - mkstemp (char *xtemplate) - { -- return __gen_tempname (xtemplate, 0, 0, __GT_FILE); -+ return __gen_tempname (xtemplate, __GT_FILE); - } diff --git a/coreutils.spec b/coreutils.spec index 0cd8520..0b9abcd 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.9 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -30,8 +30,6 @@ Patch102: coreutils-7.4-sttytcsadrain.patch Patch103: coreutils-8.2-uname-processortype.patch #df --direct Patch104: coreutils-df-direct.patch -#Fix mkstemp on sparc64 -Patch105: coreutils-mkstemp.patch #add jar-like archives to colored ones Patch106: coreutils-8.5-dircolors.patch @@ -122,7 +120,6 @@ Libraries for coreutils package. %patch102 -p1 -b .tcsadrain %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect -%patch105 -p1 -b .sparc %patch106 -p1 -b .java # sh-utils @@ -332,6 +329,9 @@ fi %{_libdir}/coreutils %changelog +* Sat Jan 08 2011 Dennis Gilmore - 8.9-2 +- drop no longer needed mkstemp patch for sparc + * Tue Jan 04 2011 Ondrej Vasik - 8.9-1 - new upstream release coreutils-8.9 From 7165b2fd596d530ae8e74542fe1a477b68031aa9 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 4 Feb 2011 20:09:36 +0100 Subject: [PATCH 121/523] update sources to 8.10 --- .gitignore | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9ec635c..a57ac7a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ coreutils-8.5.tar.xz /coreutils-8.6.tar.xz /coreutils-8.7.tar.xz /coreutils-8.8.tar.xz +/coreutils-8.10.tar.xz diff --git a/sources b/sources index 31af477..44dc9f9 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -a78848e3d7ba52e65b564ffea875ef20 coreutils-8.8.tar.xz +4bb81c051da6e5436fc1ad9a67ae44fe coreutils-8.10.tar.xz From 16cfab74f076e015b751503779d91c69ba4c9767 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 4 Feb 2011 20:34:45 +0100 Subject: [PATCH 122/523] new upstream release coreutils-8.10 --- coreutils-i18n.patch | 210 +++++++++++++++++++++---------------------- coreutils.spec | 7 +- 2 files changed, 107 insertions(+), 110 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 7ea01f7..1e3b028 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.9-orig/lib/linebuffer.h coreutils-8.9/lib/linebuffer.h ---- coreutils-8.9-orig/lib/linebuffer.h 2011-01-01 22:19:27.000000000 +0100 -+++ coreutils-8.9/lib/linebuffer.h 2011-01-04 17:41:55.358888521 +0100 +diff -urNp coreutils-8.10-orig/lib/linebuffer.h coreutils-8.10/lib/linebuffer.h +--- coreutils-8.10-orig/lib/linebuffer.h 2011-01-06 09:47:56.000000000 +0100 ++++ coreutils-8.10/lib/linebuffer.h 2011-02-04 20:13:23.985464731 +0100 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.9-orig/lib/linebuffer.h coreutils-8.9/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.9-orig/src/cut.c coreutils-8.9/src/cut.c ---- coreutils-8.9-orig/src/cut.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/cut.c 2011-01-04 17:41:55.361888730 +0100 +diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c +--- coreutils-8.10-orig/src/cut.c 2011-01-31 13:40:38.000000000 +0100 ++++ coreutils-8.10/src/cut.c 2011-02-04 20:13:23.988464025 +0100 @@ -28,6 +28,11 @@ #include #include @@ -616,9 +616,9 @@ diff -urNp coreutils-8.9-orig/src/cut.c coreutils-8.9/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.9-orig/src/expand.c coreutils-8.9/src/expand.c ---- coreutils-8.9-orig/src/expand.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/expand.c 2011-01-04 17:41:55.363905562 +0100 +diff -urNp coreutils-8.10-orig/src/expand.c coreutils-8.10/src/expand.c +--- coreutils-8.10-orig/src/expand.c 2011-01-31 13:40:38.000000000 +0100 ++++ coreutils-8.10/src/expand.c 2011-02-04 20:13:23.990463571 +0100 @@ -38,12 +38,29 @@ #include #include @@ -806,9 +806,9 @@ diff -urNp coreutils-8.9-orig/src/expand.c coreutils-8.9/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.9-orig/src/fold.c coreutils-8.9/src/fold.c ---- coreutils-8.9-orig/src/fold.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/fold.c 2011-01-04 17:41:55.366888520 +0100 +diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c +--- coreutils-8.10-orig/src/fold.c 2011-01-31 13:40:38.000000000 +0100 ++++ coreutils-8.10/src/fold.c 2011-02-04 20:13:23.992463115 +0100 @@ -22,12 +22,34 @@ #include #include @@ -1207,9 +1207,9 @@ diff -urNp coreutils-8.9-orig/src/fold.c coreutils-8.9/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c ---- coreutils-8.9-orig/src/join.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/join.c 2011-01-04 17:41:55.369888660 +0100 +diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c +--- coreutils-8.10-orig/src/join.c 2011-01-31 13:40:38.000000000 +0100 ++++ coreutils-8.10/src/join.c 2011-02-04 20:20:15.985114387 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1244,7 +1244,7 @@ diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "join" -@@ -122,10 +136,12 @@ static struct outlist outlist_head; +@@ -129,10 +143,12 @@ static struct outlist outlist_head; /* Last element in `outlist', where a new element can be added. */ static struct outlist *outlist_end = &outlist_head; @@ -1261,7 +1261,7 @@ diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -249,13 +265,14 @@ xfields (struct line *line) +@@ -257,13 +273,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1279,7 +1279,7 @@ diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c { /* Skip leading blanks before the first field. */ while (isblank (to_uchar (*ptr))) -@@ -279,6 +296,148 @@ xfields (struct line *line) +@@ -287,6 +304,148 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1428,7 +1428,7 @@ diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c static void freeline (struct line *line) { -@@ -300,56 +459,115 @@ keycmp (struct line const *line1, struct +@@ -308,56 +467,115 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1567,7 +1567,7 @@ diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -430,6 +648,11 @@ get_line (FILE *fp, struct line **linep, +@@ -438,6 +656,11 @@ get_line (FILE *fp, struct line **linep, return false; } @@ -1579,9 +1579,9 @@ diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c xfields (line); if (prevline[which - 1]) -@@ -529,11 +752,18 @@ prfield (size_t n, struct line const *li +@@ -537,21 +760,28 @@ prfield (size_t n, struct line const *li - /* Print the join of LINE1 and LINE2. */ + /* Output all the fields in line, other than the join field. */ +#define PUT_TAB_CHAR \ + do \ @@ -1589,17 +1589,37 @@ diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c + (tab != NULL) ? \ + fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ + } \ -+ while (0) ++ 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); + } + } +@@ -562,7 +792,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; - outlist = outlist_head.next; - if (outlist) -@@ -568,7 +798,7 @@ prjoin (struct line const *line1, struct +@@ -596,7 +825,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1608,35 +1628,7 @@ diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c } putchar ('\n'); } -@@ -586,23 +816,23 @@ prjoin (struct line const *line1, struct - prfield (join_field_1, line1); - for (i = 0; i < join_field_1 && i < line1->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line1); - } - for (i = join_field_1 + 1; i < line1->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line1); - } - - for (i = 0; i < join_field_2 && i < line2->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line2); - } - for (i = join_field_2 + 1; i < line2->nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line2); - } - putchar ('\n'); -@@ -1043,21 +1273,46 @@ main (int argc, char **argv) +@@ -1075,21 +1304,46 @@ main (int argc, char **argv) case 't': { @@ -1692,9 +1684,9 @@ diff -urNp coreutils-8.9-orig/src/join.c coreutils-8.9/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.9-orig/src/pr.c coreutils-8.9/src/pr.c ---- coreutils-8.9-orig/src/pr.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/pr.c 2011-01-04 17:41:55.377138275 +0100 +diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c +--- coreutils-8.10-orig/src/pr.c 2011-01-31 13:40:38.000000000 +0100 ++++ coreutils-8.10/src/pr.c 2011-02-04 20:13:24.002460897 +0100 @@ -312,6 +312,32 @@ #include @@ -2417,9 +2409,9 @@ diff -urNp coreutils-8.9-orig/src/pr.c coreutils-8.9/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c ---- coreutils-8.9-orig/src/sort.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/sort.c 2011-01-04 17:41:55.384888730 +0100 +diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c +--- coreutils-8.10-orig/src/sort.c 2011-02-03 11:24:35.000000000 +0100 ++++ coreutils-8.10/src/sort.c 2011-02-04 20:15:44.160384535 +0100 @@ -22,11 +22,20 @@ #include @@ -2973,7 +2965,7 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2209,13 +2572,12 @@ debug_key (struct line const *line, stru +@@ -2209,15 +2572,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -2983,13 +2975,15 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c char *tighter_lim = beg; - if (key->month) + 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) -@@ -2359,7 +2721,7 @@ key_warnings (struct keyfield const *gke +@@ -2361,7 +2723,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2998,7 +2992,7 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2417,11 +2779,83 @@ key_warnings (struct keyfield const *gke +@@ -2419,11 +2781,83 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option `-r' only applies to last-resort comparison")); } @@ -3083,7 +3077,7 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c { struct keyfield *key = keylist; -@@ -2506,7 +2940,7 @@ keycompare (struct line const *a, struct +@@ -2508,7 +2942,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3092,7 +3086,7 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2622,6 +3056,179 @@ keycompare (struct line const *a, struct +@@ -2624,6 +3058,179 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3272,7 +3266,7 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4084,7 +4691,7 @@ main (int argc, char **argv) +@@ -4087,7 +4694,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3281,7 +3275,7 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4105,6 +4712,29 @@ main (int argc, char **argv) +@@ -4108,6 +4715,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3311,7 +3305,7 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c have_read_stdin = false; inittables (); -@@ -4375,13 +5005,34 @@ main (int argc, char **argv) +@@ -4378,13 +5008,34 @@ main (int argc, char **argv) case 't': { @@ -3350,7 +3344,7 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -4392,9 +5043,12 @@ main (int argc, char **argv) +@@ -4395,9 +5046,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3365,9 +3359,9 @@ diff -urNp coreutils-8.9-orig/src/sort.c coreutils-8.9/src/sort.c } break; -diff -urNp coreutils-8.9-orig/src/unexpand.c coreutils-8.9/src/unexpand.c ---- coreutils-8.9-orig/src/unexpand.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/unexpand.c 2011-01-04 17:41:55.387888171 +0100 +diff -urNp coreutils-8.10-orig/src/unexpand.c coreutils-8.10/src/unexpand.c +--- coreutils-8.10-orig/src/unexpand.c 2011-01-31 13:40:38.000000000 +0100 ++++ coreutils-8.10/src/unexpand.c 2011-02-04 20:13:24.015458014 +0100 @@ -39,12 +39,29 @@ #include #include @@ -3621,9 +3615,9 @@ diff -urNp coreutils-8.9-orig/src/unexpand.c coreutils-8.9/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c ---- coreutils-8.9-orig/src/uniq.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/uniq.c 2011-01-04 17:41:55.391888381 +0100 +diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c +--- coreutils-8.10-orig/src/uniq.c 2011-01-31 13:40:38.000000000 +0100 ++++ coreutils-8.10/src/uniq.c 2011-02-04 20:13:24.018457349 +0100 @@ -21,6 +21,16 @@ #include #include @@ -3682,7 +3676,7 @@ diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -228,6 +254,83 @@ find_field (struct linebuffer const *lin +@@ -227,6 +253,83 @@ find_field (struct linebuffer const *lin return line->buffer + i; } @@ -3766,7 +3760,7 @@ diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c /* 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. -@@ -236,6 +339,8 @@ find_field (struct linebuffer const *lin +@@ -235,6 +338,8 @@ find_field (struct linebuffer const *lin static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -3775,7 +3769,7 @@ diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -243,14 +348,92 @@ different (char *old, char *new, size_t +@@ -242,14 +347,92 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3873,7 +3867,7 @@ diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -306,15 +489,43 @@ check_file (const char *infile, const ch +@@ -305,15 +488,43 @@ check_file (const char *infile, const ch { char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); @@ -3917,7 +3911,7 @@ diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c if (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)) { -@@ -333,17 +544,26 @@ check_file (const char *infile, const ch +@@ -332,17 +543,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -3944,7 +3938,7 @@ diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -352,6 +572,15 @@ check_file (const char *infile, const ch +@@ -351,6 +571,15 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -3960,7 +3954,7 @@ diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -384,6 +613,9 @@ check_file (const char *infile, const ch +@@ -383,6 +612,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3970,7 +3964,7 @@ diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c if (!match) match_count = 0; } -@@ -429,6 +661,19 @@ main (int argc, char **argv) +@@ -428,6 +660,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -3990,10 +3984,10 @@ diff -urNp coreutils-8.9-orig/src/uniq.c coreutils-8.9/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.9-orig/tests/Makefile.am coreutils-8.9/tests/Makefile.am ---- coreutils-8.9-orig/tests/Makefile.am 2011-01-04 17:41:12.682173268 +0100 -+++ coreutils-8.9/tests/Makefile.am 2011-01-04 17:41:55.392900534 +0100 -@@ -233,6 +233,7 @@ TESTS = \ +diff -urNp coreutils-8.10-orig/tests/Makefile.am coreutils-8.10/tests/Makefile.am +--- coreutils-8.10-orig/tests/Makefile.am 2011-02-04 20:12:58.236173903 +0100 ++++ coreutils-8.10/tests/Makefile.am 2011-02-04 20:13:24.020456905 +0100 +@@ -235,6 +235,7 @@ TESTS = \ misc/sort-debug-keys \ misc/sort-debug-warn \ misc/sort-files0-from \ @@ -4001,7 +3995,7 @@ diff -urNp coreutils-8.9-orig/tests/Makefile.am coreutils-8.9/tests/Makefile.am misc/sort-float \ misc/sort-merge \ misc/sort-merge-fdlimit \ -@@ -498,6 +499,10 @@ TESTS = \ +@@ -505,6 +506,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -4012,9 +4006,9 @@ diff -urNp coreutils-8.9-orig/tests/Makefile.am coreutils-8.9/tests/Makefile.am pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.9-orig/tests/misc/cut coreutils-8.9/tests/misc/cut ---- coreutils-8.9-orig/tests/misc/cut 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/tests/misc/cut 2011-01-04 17:41:55.393887822 +0100 +diff -urNp coreutils-8.10-orig/tests/misc/cut coreutils-8.10/tests/misc/cut +--- coreutils-8.10-orig/tests/misc/cut 2011-01-31 13:40:38.000000000 +0100 ++++ coreutils-8.10/tests/misc/cut 2011-02-04 20:13:24.021456684 +0100 @@ -26,7 +26,7 @@ use strict; my $prog = 'cut'; my $try = "Try \`$prog --help' for more information.\n"; @@ -4033,41 +4027,41 @@ diff -urNp coreutils-8.9-orig/tests/misc/cut coreutils-8.9/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, -diff -urNp coreutils-8.9-orig/tests/misc/mb1.I coreutils-8.9/tests/misc/mb1.I ---- coreutils-8.9-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.9/tests/misc/mb1.I 2011-01-04 17:41:55.394899835 +0100 +diff -urNp coreutils-8.10-orig/tests/misc/mb1.I coreutils-8.10/tests/misc/mb1.I +--- coreutils-8.10-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.10/tests/misc/mb1.I 2011-02-04 20:13:24.022456462 +0100 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.9-orig/tests/misc/mb1.X coreutils-8.9/tests/misc/mb1.X ---- coreutils-8.9-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.9/tests/misc/mb1.X 2011-01-04 17:41:55.395888102 +0100 +diff -urNp coreutils-8.10-orig/tests/misc/mb1.X coreutils-8.10/tests/misc/mb1.X +--- coreutils-8.10-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.10/tests/misc/mb1.X 2011-02-04 20:13:24.023456240 +0100 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.9-orig/tests/misc/mb2.I coreutils-8.9/tests/misc/mb2.I ---- coreutils-8.9-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.9/tests/misc/mb2.I 2011-01-04 17:41:55.395888102 +0100 +diff -urNp coreutils-8.10-orig/tests/misc/mb2.I coreutils-8.10/tests/misc/mb2.I +--- coreutils-8.10-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.10/tests/misc/mb2.I 2011-02-04 20:13:24.024456019 +0100 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.9-orig/tests/misc/mb2.X coreutils-8.9/tests/misc/mb2.X ---- coreutils-8.9-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.9/tests/misc/mb2.X 2011-01-04 17:41:55.396892432 +0100 +diff -urNp coreutils-8.10-orig/tests/misc/mb2.X coreutils-8.10/tests/misc/mb2.X +--- coreutils-8.10-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.10/tests/misc/mb2.X 2011-02-04 20:13:24.024456019 +0100 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.9-orig/tests/misc/sort-mb-tests coreutils-8.9/tests/misc/sort-mb-tests ---- coreutils-8.9-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.9/tests/misc/sort-mb-tests 2011-01-04 17:41:55.396892432 +0100 +diff -urNp coreutils-8.10-orig/tests/misc/sort-mb-tests coreutils-8.10/tests/misc/sort-mb-tests +--- coreutils-8.10-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.10/tests/misc/sort-mb-tests 2011-02-04 20:13:24.025455797 +0100 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils.spec b/coreutils.spec index 0b9abcd..04e25f8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.9 -Release: 2%{?dist} +Version: 8.10 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -329,6 +329,9 @@ fi %{_libdir}/coreutils %changelog +* Fri Feb 03 2011 Ondrej Vasik - 8.10-1 +- new upstream release coreutils-8.10 + * Sat Jan 08 2011 Dennis Gilmore - 8.9-2 - drop no longer needed mkstemp patch for sparc From 95b1c6985e3db1040721951bc70195d763c4f6b6 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 4 Feb 2011 20:35:33 +0100 Subject: [PATCH 123/523] fix typo in commit --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 04e25f8..868223a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -329,7 +329,7 @@ fi %{_libdir}/coreutils %changelog -* Fri Feb 03 2011 Ondrej Vasik - 8.10-1 +* Fri Feb 04 2011 Ondrej Vasik - 8.10-1 - new upstream release coreutils-8.10 * Sat Jan 08 2011 Dennis Gilmore - 8.9-2 From f467b43c7c0b9d6b572275c1e0564afaaa2c3011 Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Tue, 8 Feb 2011 05:28:48 -0600 Subject: [PATCH 124/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 868223a..2c0b102 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.10 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -329,6 +329,9 @@ fi %{_libdir}/coreutils %changelog +* Tue Feb 08 2011 Fedora Release Engineering - 8.10-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + * Fri Feb 04 2011 Ondrej Vasik - 8.10-1 - new upstream release coreutils-8.10 From 78e0be209f54de621c94541f2c65ca0d9829b452 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 17 Feb 2011 10:20:33 +0100 Subject: [PATCH 125/523] add several new TERMs to DIR_COLORS files(#678147) --- coreutils-DIR_COLORS | 3 +++ coreutils-DIR_COLORS.256color | 1 + coreutils-DIR_COLORS.lightbgcolor | 1 + coreutils.spec | 5 ++++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 4befd4c..13c74a6 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -49,13 +49,16 @@ TERM rxvt-256color TERM rxvt-cygwin TERM rxvt-cygwin-native TERM rxvt-unicode +TERM rxvt-unicode-256color TERM rxvt-unicode256 TERM screen TERM screen-256color TERM screen-256color-bce TERM screen-bce TERM screen-w +TERM screen.rxvt TERM screen.linux +TERM terminator TERM vt100 TERM xterm TERM xterm-16color diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 1b2d628..549d7b0 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -23,6 +23,7 @@ OPTIONS -F -T 0 # Below, there should be one TERM entry for each termtype that is colorizable TERM putty-256color TERM rxvt-256color +TERM rxvt-unicode-256color TERM rxvt-unicode256 TERM screen-256color TERM xterm-256color diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index a843bff..6812a97 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -36,6 +36,7 @@ TERM xterm-256color TERM rxvt TERM rxvt-256color TERM rxvt-unicode +TERM rxvt-unicode-256color TERM rxvt-unicode256 TERM xterm-color TERM color-xterm diff --git a/coreutils.spec b/coreutils.spec index 2c0b102..fdd5fef 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.10 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -329,6 +329,9 @@ fi %{_libdir}/coreutils %changelog +* Thu Feb 17 2011 Ondrej Vasik - 8.10-3 +- add several new TERMs to DIR_COLORS files(#678147) + * Tue Feb 08 2011 Fedora Release Engineering - 8.10-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild From e734c6455ad184b7ba69c84149751ef9a1218a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 17 Feb 2011 16:16:49 +0100 Subject: [PATCH 126/523] colorize documents by DIR_COLORS files(brown like mc) --- coreutils-DIR_COLORS | 25 +++++++++++++++++++++++++ coreutils-DIR_COLORS.256color | 25 +++++++++++++++++++++++++ coreutils-DIR_COLORS.lightbgcolor | 25 +++++++++++++++++++++++++ coreutils.spec | 5 ++++- 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 13c74a6..5a41e99 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -217,3 +217,28 @@ EXEC 01;32 .oga 01;36 .spx 01;36 .xspf 01;36 + +# colorize basic documents (brown) +.pdf 00;33 +.ps 00;33 +.ps.gz 00;33 +.txt 00;33 +.patch 00;33 +.diff 00;33 +.log 00;33 +.tex 00;33 +.xls 00;33 +.xlsx 00;33 +.ppt 00;33 +.pptx 00;33 +.rtf 00;33 +.doc 00;33 +.docx 00;33 +.odt 00;33 +.ods 00;33 +.odp 00;33 +.xml 00;33 +.epub 00;33 +.abw 00;33 +.html 00;33 +.wpd 00;33 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 549d7b0..ddff4ac 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -190,3 +190,28 @@ EXEC 38;5;34 .oga 38;5;45 .spx 38;5;45 .xspf 38;5;45 + +# colorize basic documents as well (brown) +.pdf 00;33 +.ps 00;33 +.ps.gz 00;33 +.txt 00;33 +.patch 00;33 +.diff 00;33 +.log 00;33 +.tex 00;33 +.xls 00;33 +.xlsx 00;33 +.ppt 00;33 +.pptx 00;33 +.rtf 00;33 +.doc 00;33 +.docx 00;33 +.odt 00;33 +.ods 00;33 +.odp 00;33 +.xml 00;33 +.epub 00;33 +.abw 00;33 +.html 00;33 +.wpd 00;33 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index 6812a97..e2c05da 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -193,3 +193,28 @@ EXEC 00;32 .oga 00;36 .spx 00;36 .xspf 00;36 + +# colorize basic documents (brown) +.pdf 00;33 +.ps 00;33 +.ps.gz 00;33 +.txt 00;33 +.patch 00;33 +.diff 00;33 +.log 00;33 +.tex 00;33 +.xls 00;33 +.xlsx 00;33 +.ppt 00;33 +.pptx 00;33 +.rtf 00;33 +.doc 00;33 +.docx 00;33 +.odt 00;33 +.ods 00;33 +.odp 00;33 +.xml 00;33 +.epub 00;33 +.abw 00;33 +.html 00;33 +.wpd 00;33 diff --git a/coreutils.spec b/coreutils.spec index fdd5fef..a869962 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.10 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -329,6 +329,9 @@ fi %{_libdir}/coreutils %changelog +* Thu Feb 17 2011 Ondrej Vasik - 8.10-4 +- colorize documents by DIR_COLORS files(brown like mc) + * Thu Feb 17 2011 Ondrej Vasik - 8.10-3 - add several new TERMs to DIR_COLORS files(#678147) From 9207a1510e6d621e8d0d73d025ea622804cc1c2b Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Fri, 4 Mar 2011 21:18:53 +0100 Subject: [PATCH 127/523] make coreutils build even without patches (with nopam, norunuser and noselinux variables) --- coreutils.spec | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index a869962..0c6f8e5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.10 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -142,7 +142,7 @@ Libraries for coreutils package. %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -chmod a+x tests/misc/sort-mb-tests tests/df/direct +chmod a+x tests/misc/sort-mb-tests tests/df/direct || : #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -158,7 +158,7 @@ aclocal -I m4 autoconf --force automake --copy --add-missing %configure --enable-largefile %{?!nopam:--enable-pam} \ - --enable-selinux \ + %{?!noselinux:--enable-selinux} \ --enable-install-program=su,hostname,arch \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : @@ -214,9 +214,9 @@ install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.c # su install -m 4755 src/su $RPM_BUILD_ROOT/bin -install -m 755 src/runuser $RPM_BUILD_ROOT/sbin +%{?!norunuser:install -m 755 src/runuser $RPM_BUILD_ROOT/sbin} # do not ship runuser in /usr/bin/runuser -rm -rf $RPM_BUILD_ROOT/usr/bin/runuser +rm -rf $RPM_BUILD_ROOT/usr/bin/runuser || : # These come from util-linux and/or procps. for i in hostname uptime kill ; do @@ -322,13 +322,17 @@ fi %_infodir/coreutils* %_mandir/man*/* %_sbindir/chroot -/sbin/runuser +%{?!norunuser:/sbin/runuser} %files libs %defattr(-, root, root, -) %{_libdir}/coreutils %changelog +* Fri Mar 4 2011 Ondrej Vasik - 8.10-5 +- make coreutils build even without patches (with + nopam, norunuser and noselinux variables) + * Thu Feb 17 2011 Ondrej Vasik - 8.10-4 - colorize documents by DIR_COLORS files(brown like mc) From 7a041cc0d864282808a101e2963b8e47e9618a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 14 Mar 2011 09:43:52 +0100 Subject: [PATCH 128/523] fix possible uninitalized variables usage caused by i18n patch(#683799) --- coreutils-i18n.patch | 20 +++++++++----------- coreutils.spec | 6 +++++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 1e3b028..6e10f37 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -250,7 +250,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c + size_t mblength; /* The byte size of a multibyte character which shows + as same character as WC. */ + mbstate_t state; /* State of the stream. */ -+ int convfail; /* 1, when conversion is failed. Otherwise 0. */ ++ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ + + idx = 0; + buflen = 0; @@ -662,7 +662,7 @@ diff -urNp coreutils-8.10-orig/src/expand.c coreutils-8.10/src/expand.c + mbstate_t i_state_bak; /* Back up the I_STATE. */ + mbstate_t o_state; /* Current shift state of the output stream. */ + char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos; /* Next read position of BUF. */ ++ char *bufpos = buf; /* Next read position of BUF. */ + size_t buflen = 0; /* The length of the byte sequence in buf. */ + wchar_t wc; /* A gotten wide character. */ + size_t mblength; /* The byte size of a multibyte character @@ -956,7 +956,7 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -217,11 +254,222 @@ fold_file (char const *filename, size_t +@@ -217,11 +254,221 @@ fold_file (char const *filename, size_t line_out[offset_out++] = c; } @@ -974,12 +974,12 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c +{ + 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 = NULL; /* Next read position of 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; /* 1, when conversion is failed. Otherwise 0. */ ++ 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. */ @@ -1034,7 +1034,6 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c + break; + + /* Get a wide character. */ -+ convfail = 0; + state_bak = state; + mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); + @@ -3407,7 +3406,7 @@ diff -urNp coreutils-8.10-orig/src/unexpand.c coreutils-8.10/src/unexpand.c + mbstate_t i_state_bak; /* Back up the I_STATE. */ + mbstate_t o_state; /* Current shift state of the output stream. */ + char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos; /* Next read position of BUF. */ ++ char *bufpos = buf; /* Next read position of BUF. */ + size_t buflen = 0; /* 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 @@ -3715,7 +3714,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c + size_t mblength; + wchar_t wc; + mbstate_t *statep; -+ int convfail; ++ int convfail = 0; + + pos = 0; + statep = &(line->state); @@ -3933,19 +3932,18 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c char *thisfield; size_t thislen; +#if HAVE_MBRTOWC -+ mbstate_t thisstate; ++ mbstate_t thisstate = thisline->state; +#endif if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -351,6 +571,15 @@ check_file (const char *infile, const ch +@@ -351,6 +571,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) + { -+ thisstate = thisline->state; + match = !different_multi (thisfield, prevfield, + thislen, prevlen, thisstate, prevstate); + } diff --git a/coreutils.spec b/coreutils.spec index 0c6f8e5..f76bba3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.10 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -329,6 +329,10 @@ fi %{_libdir}/coreutils %changelog +* Mon Mar 14 2011 Ondrej Vasik - 8.10-6 +- fix possible uninitalized variables usage caused by i18n + patch(#683799) + * Fri Mar 4 2011 Ondrej Vasik - 8.10-5 - make coreutils build even without patches (with nopam, norunuser and noselinux variables) From fdeedf2670e4f68813268bebb457e4f1450e0a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 22 Mar 2011 09:54:46 +0100 Subject: [PATCH 129/523] add note about mkdir mode behaviour into info documentation (#610559) --- coreutils-8.4-mkdir-modenote.patch | 12 ++++++++++++ coreutils.spec | 9 ++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.4-mkdir-modenote.patch diff --git a/coreutils-8.4-mkdir-modenote.patch b/coreutils-8.4-mkdir-modenote.patch new file mode 100644 index 0000000..3576ec6 --- /dev/null +++ b/coreutils-8.4-mkdir-modenote.patch @@ -0,0 +1,12 @@ +diff -urNp coreutils-8.4-orig/doc/coreutils.texi coreutils-8.4/doc/coreutils.texi +--- coreutils-8.4-orig/doc/coreutils.texi 2011-01-07 15:01:18.575654333 +0100 ++++ coreutils-8.4/doc/coreutils.texi 2011-01-07 15:05:38.791655243 +0100 +@@ -9058,6 +9058,8 @@ incorrect. @xref{Directory Setuid and S + set-user-ID and set-group-ID bits of directories are inherited unless + overridden in this way. + ++Note: The @option{--mode},@option{-m} option only applies to the right-most directories listed on the command line. When combined with @option{--parents}, @option{-p} option, any parent directories are created with @samp{u+wx} modified by umask. ++ + @item -p + @itemx --parents + @opindex -p diff --git a/coreutils.spec b/coreutils.spec index f76bba3..0779a23 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.10 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -32,6 +32,8 @@ Patch103: coreutils-8.2-uname-processortype.patch Patch104: coreutils-df-direct.patch #add jar-like archives to colored ones Patch106: coreutils-8.5-dircolors.patch +#add note about mkdir --mode behaviour into info documentation(#610559) +Patch107: coreutils-8.4-mkdir-modenote.patch # sh-utils #add info about TZ envvar to date manpage @@ -121,6 +123,7 @@ Libraries for coreutils package. %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect %patch106 -p1 -b .java +%patch107 -p1 -b .mkdirmode # sh-utils %patch703 -p1 -b .dateman @@ -329,6 +332,10 @@ fi %{_libdir}/coreutils %changelog +* Tue Mar 22 2011 Ondrej Vasik - 8.10-7 +- add note about mkdir mode behaviour into info + documentation (#610559) + * Mon Mar 14 2011 Ondrej Vasik - 8.10-6 - fix possible uninitalized variables usage caused by i18n patch(#683799) From 50a3bada88a4319c1e4f84a6c187fff9d84b2159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 14 Apr 2011 12:30:24 +0200 Subject: [PATCH 130/523] new upstream release 8.11, defuzz patches --- coreutils-df-direct.patch | 79 +++++++++---------- coreutils-selinux.patch | 156 +++++++++++++++++++------------------- coreutils.spec | 7 +- 3 files changed, 123 insertions(+), 119 deletions(-) diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 0f1d1b2..66698bd 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.9-orig/doc/coreutils.texi coreutils-8.9/doc/coreutils.texi ---- coreutils-8.9-orig/doc/coreutils.texi 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/doc/coreutils.texi 2011-01-04 17:38:33.323888382 +0100 -@@ -10306,6 +10306,13 @@ pseudo-file-systems, such as automounter +diff -urNp coreutils-8.11-orig/doc/coreutils.texi coreutils-8.11/doc/coreutils.texi +--- coreutils-8.11-orig/doc/coreutils.texi 2011-04-12 12:07:43.000000000 +0200 ++++ coreutils-8.11/doc/coreutils.texi 2011-04-14 09:53:43.764309420 +0200 +@@ -10409,6 +10409,13 @@ pseudo-file-systems, such as automounter Scale sizes by @var{size} before printing them (@pxref{Block size}). For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. @@ -15,10 +15,10 @@ diff -urNp coreutils-8.9-orig/doc/coreutils.texi coreutils-8.9/doc/coreutils.tex @itemx --total @opindex --total @cindex grand total of disk size, usage and available space -diff -urNp coreutils-8.9-orig/src/df.c coreutils-8.9/src/df.c ---- coreutils-8.9-orig/src/df.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/df.c 2011-01-04 17:38:33.324887614 +0100 -@@ -109,6 +109,9 @@ static bool print_type; +diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c +--- coreutils-8.11-orig/src/df.c 2011-04-12 12:07:43.000000000 +0200 ++++ coreutils-8.11/src/df.c 2011-04-14 10:37:44.208308771 +0200 +@@ -112,6 +112,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -28,7 +28,7 @@ diff -urNp coreutils-8.9-orig/src/df.c coreutils-8.9/src/df.c /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -117,13 +120,15 @@ static struct fs_usage grand_fsu; +@@ -166,13 +169,15 @@ static size_t nrows; enum { NO_SYNC_OPTION = CHAR_MAX + 1, @@ -45,37 +45,38 @@ diff -urNp coreutils-8.9-orig/src/df.c coreutils-8.9/src/df.c {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, -@@ -204,7 +209,10 @@ print_header (void) - human_readable (output_block_size, buf, opts, 1, 1)); - } +@@ -259,7 +264,11 @@ get_header (void) + } -- fputs (_(" Mounted on\n"), stdout); -+ if (direct_statfs) -+ fputs (_(" File\n"), stdout); -+ else -+ fputs (_(" Mounted on\n"), stdout); - } + char *cell = NULL; +- char const *header = _(headers[field][header_mode]); ++ ++ char const *header = (field == MNT_FIELD && direct_statfs)? ++ _("File\n") : ++ _(headers[field][header_mode]); ++ + if (!header) + header = _(headers[field][DEFAULT_MODE]); - /* Is FSTYPE a type of file system that should be listed? */ -@@ -646,6 +654,17 @@ show_point (const char *point, const str +@@ -757,6 +766,17 @@ get_point (const char *point, const stru static void - show_entry (char const *name, struct stat const *statp) + get_entry (char const *name, struct stat const *statp) { + if (direct_statfs) + { + char *resolved = canonicalize_file_name (name); + if (resolved) + { -+ show_dev (NULL, resolved, NULL, NULL, false, false, NULL); ++ get_dev (NULL, resolved, NULL, NULL, false, false, NULL); + free (resolved); + return; + } + } + if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) - && show_disk (name)) + && get_disk (name)) return; -@@ -714,6 +733,7 @@ Mandatory arguments to long options are +@@ -825,6 +845,7 @@ Mandatory arguments to long options are -B, --block-size=SIZE scale sizes by SIZE before printing them. E.g.,\n\ `-BM' prints sizes in units of 1,048,576 bytes.\n\ See SIZE format below.\n\ @@ -83,7 +84,7 @@ diff -urNp coreutils-8.9-orig/src/df.c coreutils-8.9/src/df.c --total produce a grand total\n\ -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\ \n\ -@@ -790,6 +810,9 @@ main (int argc, char **argv) +@@ -901,6 +922,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -93,7 +94,7 @@ diff -urNp coreutils-8.9-orig/src/df.c coreutils-8.9/src/df.c case 'i': inode_format = true; break; -@@ -850,6 +873,13 @@ main (int argc, char **argv) +@@ -961,6 +985,13 @@ main (int argc, char **argv) } } @@ -107,9 +108,9 @@ diff -urNp coreutils-8.9-orig/src/df.c coreutils-8.9/src/df.c if (human_output_opts == -1) { if (posix_format) -diff -urNp coreutils-8.9-orig/tests/df/direct coreutils-8.9/tests/df/direct ---- coreutils-8.9-orig/tests/df/direct 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.9/tests/df/direct 2011-01-04 17:38:33.328138905 +0100 +diff -urNp coreutils-8.11-orig/tests/df/direct coreutils-8.11/tests/df/direct +--- coreutils-8.11-orig/tests/df/direct 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.11/tests/df/direct 2011-04-14 09:53:43.767400034 +0200 @@ -0,0 +1,55 @@ +#!/bin/sh +# Ensure "df --direct" works as documented @@ -156,20 +157,20 @@ diff -urNp coreutils-8.9-orig/tests/df/direct coreutils-8.9/tests/df/direct +compare header_file_out header_file_exp || fail=1 + +# check df output (without --direct) -+$AWK '{ if (NR==2) print $6; }' df_out > file_out \ -+ || framework_failure -+compare file_out file_exp && fail=1 ++#$AWK '{ if (NR==2) print $6; }' df_out > file_out \ ++# || framework_failure ++#compare file_out file_exp && fail=1 + +# check df output (with --direct) -+$AWK '{ if (NR==2) print $6; }' df_direct_out > file_out \ -+ || framework_failure -+compare file_out file_exp || fail=1 ++#$AWK '{ if (NR==2) print $6; }' df_direct_out > file_out \ ++# || framework_failure ++#compare file_out file_exp || fail=1 + +Exit $fail -diff -urNp coreutils-8.9-orig/tests/Makefile.am coreutils-8.9/tests/Makefile.am ---- coreutils-8.9-orig/tests/Makefile.am 2011-01-04 17:37:57.837887753 +0100 -+++ coreutils-8.9/tests/Makefile.am 2011-01-04 17:38:33.326913944 +0100 -@@ -352,6 +352,7 @@ TESTS = \ +diff -urNp coreutils-8.11-orig/tests/Makefile.am coreutils-8.11/tests/Makefile.am +--- coreutils-8.11-orig/tests/Makefile.am 2011-04-14 09:53:13.666324768 +0200 ++++ coreutils-8.11/tests/Makefile.am 2011-04-14 09:53:43.768432620 +0200 +@@ -362,6 +362,7 @@ TESTS = \ dd/stderr \ dd/unblock \ dd/unblock-sync \ diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 8415aee..0c6c51e 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.9-orig/configure.ac coreutils-8.9/configure.ac ---- coreutils-8.9-orig/configure.ac 2011-01-04 17:43:03.876887473 +0100 -+++ coreutils-8.9/configure.ac 2011-01-04 17:43:36.194889010 +0100 +diff -urNp coreutils-8.11-orig/configure.ac coreutils-8.11/configure.ac +--- coreutils-8.11-orig/configure.ac 2011-04-14 11:05:27.511308852 +0200 ++++ coreutils-8.11/configure.ac 2011-04-14 11:06:05.481433832 +0200 @@ -132,6 +132,13 @@ if test "$gl_gcc_warnings" = yes; then AC_SUBST([GNULIB_TEST_WARN_CFLAGS]) fi @@ -15,18 +15,18 @@ diff -urNp coreutils-8.9-orig/configure.ac coreutils-8.9/configure.ac AC_FUNC_FORK AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam], -diff -urNp coreutils-8.9-orig/man/chcon.x coreutils-8.9/man/chcon.x ---- coreutils-8.9-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.9/man/chcon.x 2011-01-04 17:43:36.195889150 +0100 +diff -urNp coreutils-8.11-orig/man/chcon.x coreutils-8.11/man/chcon.x +--- coreutils-8.11-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.11/man/chcon.x 2011-04-14 11:06:05.482433878 +0200 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-8.9-orig/man/runcon.x coreutils-8.9/man/runcon.x ---- coreutils-8.9-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.9/man/runcon.x 2011-01-04 17:43:36.195889150 +0100 +diff -urNp coreutils-8.11-orig/man/runcon.x coreutils-8.11/man/runcon.x +--- coreutils-8.11-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.11/man/runcon.x 2011-04-14 11:06:05.483445779 +0200 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,10 +34,22 @@ diff -urNp coreutils-8.9-orig/man/runcon.x coreutils-8.9/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.9-orig/src/copy.c coreutils-8.9/src/copy.c ---- coreutils-8.9-orig/src/copy.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/copy.c 2011-01-04 17:43:36.199888591 +0100 -@@ -1931,6 +1931,8 @@ copy_internal (char const *src_name, cha +diff -urNp coreutils-8.11-orig/src/chcon.c coreutils-8.11/src/chcon.c +--- coreutils-8.11-orig/src/chcon.c 2011-02-19 18:17:03.000000000 +0100 ++++ coreutils-8.11/src/chcon.c 2011-04-14 11:06:05.489434075 +0200 +@@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ + "), + program_name, program_name, program_name); + fputs (_("\ +-Change the security context of each FILE to CONTEXT.\n\ ++Change the SELinux security context of each FILE to CONTEXT.\n\ + With --reference, change the security context of each FILE to that of RFILE.\n\ + \n\ + -h, --no-dereference affect symbolic links instead of any referenced file\n\ +diff -urNp coreutils-8.11-orig/src/copy.c coreutils-8.11/src/copy.c +--- coreutils-8.11-orig/src/copy.c 2011-04-12 12:07:43.000000000 +0200 ++++ coreutils-8.11/src/copy.c 2011-04-14 11:06:05.485433752 +0200 +@@ -2179,6 +2179,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -46,9 +58,9 @@ diff -urNp coreutils-8.9-orig/src/copy.c coreutils-8.9/src/copy.c } else { -diff -urNp coreutils-8.9-orig/src/copy.h coreutils-8.9/src/copy.h ---- coreutils-8.9-orig/src/copy.h 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/copy.h 2011-01-04 17:43:36.201889220 +0100 +diff -urNp coreutils-8.11-orig/src/copy.h coreutils-8.11/src/copy.h +--- coreutils-8.11-orig/src/copy.h 2011-02-19 18:17:03.000000000 +0100 ++++ coreutils-8.11/src/copy.h 2011-04-14 11:06:05.487340225 +0200 @@ -158,6 +158,9 @@ struct cp_options bool preserve_mode; bool preserve_timestamps; @@ -59,9 +71,9 @@ diff -urNp coreutils-8.9-orig/src/copy.h coreutils-8.9/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urNp coreutils-8.9-orig/src/cp.c coreutils-8.9/src/cp.c ---- coreutils-8.9-orig/src/cp.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/cp.c 2011-01-04 17:43:36.202898439 +0100 +diff -urNp coreutils-8.11-orig/src/cp.c coreutils-8.11/src/cp.c +--- coreutils-8.11-orig/src/cp.c 2011-02-19 18:17:03.000000000 +0100 ++++ coreutils-8.11/src/cp.c 2011-04-14 11:06:05.488433894 +0200 @@ -141,6 +141,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, @@ -150,21 +162,9 @@ diff -urNp coreutils-8.9-orig/src/cp.c coreutils-8.9/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urNp coreutils-8.9-orig/src/chcon.c coreutils-8.9/src/chcon.c ---- coreutils-8.9-orig/src/chcon.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/chcon.c 2011-01-04 17:43:36.205888452 +0100 -@@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ - "), - program_name, program_name, program_name); - fputs (_("\ --Change the security context of each FILE to CONTEXT.\n\ -+Change the SELinux security context of each FILE to CONTEXT.\n\ - With --reference, change the security context of each FILE to that of RFILE.\n\ - \n\ - -h, --no-dereference affect symbolic links instead of any referenced file\n\ -diff -urNp coreutils-8.9-orig/src/id.c coreutils-8.9/src/id.c ---- coreutils-8.9-orig/src/id.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/id.c 2011-01-04 17:43:36.206888661 +0100 +diff -urNp coreutils-8.11-orig/src/id.c coreutils-8.11/src/id.c +--- coreutils-8.11-orig/src/id.c 2011-02-19 18:17:03.000000000 +0100 ++++ coreutils-8.11/src/id.c 2011-04-14 11:06:05.490435340 +0200 @@ -107,7 +107,7 @@ int main (int argc, char **argv) { @@ -174,10 +174,10 @@ diff -urNp coreutils-8.9-orig/src/id.c coreutils-8.9/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urNp coreutils-8.9-orig/src/install.c coreutils-8.9/src/install.c ---- coreutils-8.9-orig/src/install.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/install.c 2011-01-04 17:47:30.255887962 +0100 -@@ -283,6 +283,7 @@ cp_option_init (struct cp_options *x) +diff -urNp coreutils-8.11-orig/src/install.c coreutils-8.11/src/install.c +--- coreutils-8.11-orig/src/install.c 2011-04-12 12:07:43.000000000 +0200 ++++ coreutils-8.11/src/install.c 2011-04-14 11:07:58.333433706 +0200 +@@ -261,6 +261,7 @@ cp_option_init (struct cp_options *x) x->data_copy_required = true; x->require_preserve = false; x->require_preserve_context = false; @@ -185,7 +185,16 @@ diff -urNp coreutils-8.9-orig/src/install.c coreutils-8.9/src/install.c x->require_preserve_xattr = false; x->recursive = false; x->sparse_mode = SPARSE_AUTO; -@@ -460,7 +461,7 @@ main (int argc, char **argv) +@@ -622,7 +623,7 @@ Mandatory arguments to long options are + -v, --verbose print the name of each directory as it is created\n\ + "), stdout); + fputs (_("\ +- --preserve-context preserve SELinux security context\n\ ++ -P, --preserve-context preserve SELinux security context\n\ + -Z, --context=CONTEXT set SELinux security context of files and directories\ + \n\ + "), stdout); +@@ -765,7 +766,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -194,15 +203,15 @@ diff -urNp coreutils-8.9-orig/src/install.c coreutils-8.9/src/install.c NULL)) != -1) { switch (optc) -@@ -534,6 +535,7 @@ main (int argc, char **argv) - error (0, 0, _("WARNING: --preserve_context is deprecated; " - "use --preserve-context instead")); - /* fall through */ +@@ -835,6 +836,7 @@ main (int argc, char **argv) + no_target_directory = true; + break; + + case 'P': case PRESERVE_CONTEXT_OPTION: if ( ! selinux_enabled) { -@@ -541,6 +543,10 @@ main (int argc, char **argv) +@@ -842,6 +844,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } @@ -213,7 +222,7 @@ diff -urNp coreutils-8.9-orig/src/install.c coreutils-8.9/src/install.c x.preserve_security_context = true; use_default_selinux_context = false; break; -@@ -552,6 +558,7 @@ main (int argc, char **argv) +@@ -853,6 +859,7 @@ main (int argc, char **argv) break; } scontext = optarg; @@ -221,18 +230,9 @@ diff -urNp coreutils-8.9-orig/src/install.c coreutils-8.9/src/install.c use_default_selinux_context = false; break; case_GETOPT_HELP_CHAR; -@@ -985,7 +992,7 @@ Mandatory arguments to long options are - -v, --verbose print the name of each directory as it is created\n\ - "), stdout); - fputs (_("\ -- --preserve-context preserve SELinux security context\n\ -+ -P, --preserve-context preserve SELinux security context\n\ - -Z, --context=CONTEXT set SELinux security context of files and directories\ - \n\ - "), stdout); -diff -urNp coreutils-8.9-orig/src/ls.c coreutils-8.9/src/ls.c ---- coreutils-8.9-orig/src/ls.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/ls.c 2011-01-04 17:43:36.211887474 +0100 +diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c +--- coreutils-8.11-orig/src/ls.c 2011-04-12 12:07:43.000000000 +0200 ++++ coreutils-8.11/src/ls.c 2011-04-14 11:06:05.498436329 +0200 @@ -159,7 +159,8 @@ enum filetype symbolic_link, sock, @@ -595,9 +595,9 @@ diff -urNp coreutils-8.9-orig/src/ls.c coreutils-8.9/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-8.9-orig/src/mkdir.c coreutils-8.9/src/mkdir.c ---- coreutils-8.9-orig/src/mkdir.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/mkdir.c 2011-01-04 17:43:36.213899906 +0100 +diff -urNp coreutils-8.11-orig/src/mkdir.c coreutils-8.11/src/mkdir.c +--- coreutils-8.11-orig/src/mkdir.c 2011-02-19 18:17:03.000000000 +0100 ++++ coreutils-8.11/src/mkdir.c 2011-04-14 11:06:05.499460276 +0200 @@ -38,6 +38,7 @@ static struct option const longopts[] = { @@ -606,9 +606,9 @@ diff -urNp coreutils-8.9-orig/src/mkdir.c coreutils-8.9/src/mkdir.c {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, -diff -urNp coreutils-8.9-orig/src/mknod.c coreutils-8.9/src/mknod.c ---- coreutils-8.9-orig/src/mknod.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/mknod.c 2011-01-04 17:43:36.215887404 +0100 +diff -urNp coreutils-8.11-orig/src/mknod.c coreutils-8.11/src/mknod.c +--- coreutils-8.11-orig/src/mknod.c 2011-02-19 18:17:03.000000000 +0100 ++++ coreutils-8.11/src/mknod.c 2011-04-14 11:06:05.500309648 +0200 @@ -35,7 +35,7 @@ static struct option const longopts[] = @@ -618,9 +618,9 @@ diff -urNp coreutils-8.9-orig/src/mknod.c coreutils-8.9/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urNp coreutils-8.9-orig/src/mv.c coreutils-8.9/src/mv.c ---- coreutils-8.9-orig/src/mv.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/mv.c 2011-01-04 17:43:36.216896344 +0100 +diff -urNp coreutils-8.11-orig/src/mv.c coreutils-8.11/src/mv.c +--- coreutils-8.11-orig/src/mv.c 2011-02-19 18:17:03.000000000 +0100 ++++ coreutils-8.11/src/mv.c 2011-04-14 11:06:05.501309664 +0200 @@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x) x->preserve_mode = true; x->preserve_timestamps = true; @@ -629,9 +629,9 @@ diff -urNp coreutils-8.9-orig/src/mv.c coreutils-8.9/src/mv.c x->reduce_diagnostics = false; x->data_copy_required = true; x->require_preserve = false; /* FIXME: maybe make this an option */ -diff -urNp coreutils-8.9-orig/src/runcon.c coreutils-8.9/src/runcon.c ---- coreutils-8.9-orig/src/runcon.c 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/src/runcon.c 2011-01-04 17:43:36.216896344 +0100 +diff -urNp coreutils-8.11-orig/src/runcon.c coreutils-8.11/src/runcon.c +--- coreutils-8.11-orig/src/runcon.c 2011-02-19 18:17:03.000000000 +0100 ++++ coreutils-8.11/src/runcon.c 2011-04-14 11:06:05.502310854 +0200 @@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ "), program_name, program_name); @@ -641,13 +641,13 @@ diff -urNp coreutils-8.9-orig/src/runcon.c coreutils-8.9/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urNp coreutils-8.9-orig/tests/init.cfg coreutils-8.9/tests/init.cfg ---- coreutils-8.9-orig/tests/init.cfg 2010-12-22 12:29:13.000000000 +0100 -+++ coreutils-8.9/tests/init.cfg 2011-01-04 17:43:36.218137788 +0100 -@@ -216,8 +216,8 @@ skip_if_() +diff -urNp coreutils-8.11-orig/tests/init.cfg coreutils-8.11/tests/init.cfg +--- coreutils-8.11-orig/tests/init.cfg 2011-04-12 12:07:43.000000000 +0200 ++++ coreutils-8.11/tests/init.cfg 2011-04-14 11:06:05.503308646 +0200 +@@ -231,8 +231,8 @@ require_selinux_() - require_selinux_() - { + # Independent of whether SELinux is enabled system-wide, + # the current file system may lack SELinux support. - case `ls -Zd .` in - '? .'|'unlabeled .') + case `ls -Zd . | cut -f4 -d" "` in @@ -655,9 +655,9 @@ diff -urNp coreutils-8.9-orig/tests/init.cfg coreutils-8.9/tests/init.cfg skip_test_ "this system (or maybe just" \ "the current file system) lacks SELinux support" ;; -diff -urNp coreutils-8.9-orig/tests/misc/selinux coreutils-8.9/tests/misc/selinux ---- coreutils-8.9-orig/tests/misc/selinux 2011-01-01 22:19:23.000000000 +0100 -+++ coreutils-8.9/tests/misc/selinux 2011-01-04 17:43:36.219137718 +0100 +diff -urNp coreutils-8.11-orig/tests/misc/selinux coreutils-8.11/tests/misc/selinux +--- coreutils-8.11-orig/tests/misc/selinux 2011-01-31 13:40:38.000000000 +0100 ++++ coreutils-8.11/tests/misc/selinux 2011-04-14 11:06:05.504353757 +0200 @@ -37,7 +37,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. diff --git a/coreutils.spec b/coreutils.spec index 0779a23..025a772 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.10 -Release: 7%{?dist} +Version: 8.11 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -332,6 +332,9 @@ fi %{_libdir}/coreutils %changelog +* Thu Apr 14 2011 Ondrej Vasik - 8.11-1 +- new upstream release 8.11, defuzz patches + * Tue Mar 22 2011 Ondrej Vasik - 8.10-7 - add note about mkdir mode behaviour into info documentation (#610559) From 575258689bc80b091282163016b22eedd400fe5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 14 Apr 2011 12:31:15 +0200 Subject: [PATCH 131/523] Forgot to update sources --- .gitignore | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8f1eca9..b1fd01d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /coreutils-8.10.tar.xz +/coreutils-8.11.tar.xz diff --git a/sources b/sources index 44dc9f9..a851066 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -4bb81c051da6e5436fc1ad9a67ae44fe coreutils-8.10.tar.xz +b623ee9b1b768a14e40dfd35ff446f4c coreutils-8.11.tar.xz From d79f57cc321e39d466549914ebb6e469f5f7e5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 14 Apr 2011 16:51:54 +0200 Subject: [PATCH 132/523] fix issue with df --direct(extra new line) --- coreutils-df-direct.patch | 14 +++++++------- coreutils.spec | 5 ++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 66698bd..025323d 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -52,7 +52,7 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c - char const *header = _(headers[field][header_mode]); + + char const *header = (field == MNT_FIELD && direct_statfs)? -+ _("File\n") : ++ _("File") : + _(headers[field][header_mode]); + if (!header) @@ -157,14 +157,14 @@ diff -urNp coreutils-8.11-orig/tests/df/direct coreutils-8.11/tests/df/direct +compare header_file_out header_file_exp || fail=1 + +# check df output (without --direct) -+#$AWK '{ if (NR==2) print $6; }' df_out > file_out \ -+# || framework_failure -+#compare file_out file_exp && fail=1 ++$AWK '{ if (NR==2) print $6; }' df_out > file_out \ ++ || framework_failure ++compare file_out file_exp && fail=1 + +# check df output (with --direct) -+#$AWK '{ if (NR==2) print $6; }' df_direct_out > file_out \ -+# || framework_failure -+#compare file_out file_exp || fail=1 ++$AWK '{ if (NR==2) print $6; }' df_direct_out > file_out \ ++ || framework_failure ++compare file_out file_exp || fail=1 + +Exit $fail diff -urNp coreutils-8.11-orig/tests/Makefile.am coreutils-8.11/tests/Makefile.am diff --git a/coreutils.spec b/coreutils.spec index 025a772..056ad3b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.11 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -332,6 +332,9 @@ fi %{_libdir}/coreutils %changelog +* Thu Apr 14 2011 Ondrej Vasik - 8.11-2 +- fix issue with df --direct(extra new line) + * Thu Apr 14 2011 Ondrej Vasik - 8.11-1 - new upstream release 8.11, defuzz patches From 2947a97744261e5bd9870e406e073eb022fb9f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 27 Apr 2011 11:03:02 +0200 Subject: [PATCH 133/523] new upstream release 8.12, drop accepted patch --- .gitignore | 1 + coreutils.spec | 10 +++++----- sources | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index b1fd01d..298ae80 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /coreutils-8.10.tar.xz /coreutils-8.11.tar.xz +/coreutils-8.12.tar.xz diff --git a/coreutils.spec b/coreutils.spec index 056ad3b..729c149 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.11 -Release: 2%{?dist} +Version: 8.12 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -30,8 +30,6 @@ Patch102: coreutils-7.4-sttytcsadrain.patch Patch103: coreutils-8.2-uname-processortype.patch #df --direct Patch104: coreutils-df-direct.patch -#add jar-like archives to colored ones -Patch106: coreutils-8.5-dircolors.patch #add note about mkdir --mode behaviour into info documentation(#610559) Patch107: coreutils-8.4-mkdir-modenote.patch @@ -122,7 +120,6 @@ Libraries for coreutils package. %patch102 -p1 -b .tcsadrain %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect -%patch106 -p1 -b .java %patch107 -p1 -b .mkdirmode # sh-utils @@ -332,6 +329,9 @@ fi %{_libdir}/coreutils %changelog +* Wed Apr 27 2011 Ondrej Vasik - 8.12-1 +- new upstream release 8.12 + * Thu Apr 14 2011 Ondrej Vasik - 8.11-2 - fix issue with df --direct(extra new line) diff --git a/sources b/sources index a851066..6a12672 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -b623ee9b1b768a14e40dfd35ff446f4c coreutils-8.11.tar.xz +0f7d43c2d2e24314b43a6c6267e25b90 coreutils-8.12.tar.xz From 65b57c538de902f6b9c29b41e64d48c1fd96e4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 15 Jul 2011 15:58:40 +0200 Subject: [PATCH 134/523] support ecryptfs mount of Private (postlogin into su.pamd) - (#722323) --- coreutils-su.pamd | 2 ++ coreutils.spec | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/coreutils-su.pamd b/coreutils-su.pamd index 85e67a8..1981f58 100644 --- a/coreutils-su.pamd +++ b/coreutils-su.pamd @@ -5,8 +5,10 @@ auth sufficient pam_rootok.so # Uncomment the following line to require a user to be in the "wheel" group. #auth required pam_wheel.so use_uid auth include system-auth +auth include postlogin account sufficient pam_succeed_if.so uid = 0 use_uid quiet account include system-auth password include system-auth session include system-auth +session include postlogin session optional pam_xauth.so diff --git a/coreutils.spec b/coreutils.spec index 729c149..2784cdc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.12 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -329,6 +329,10 @@ fi %{_libdir}/coreutils %changelog +* Fri Jul 15 2011 Ondrej Vasik - 8.12-2 +- support ecryptfs mount of Private (postlogin into su.pamd) + (#722323) + * Wed Apr 27 2011 Ondrej Vasik - 8.12-1 - new upstream release 8.12 From c9c477adae50a5ede3a4b48b9a39344e7fc0d51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 29 Jul 2011 15:12:18 +0200 Subject: [PATCH 135/523] use acl_extended_file_nofollow() if available (#692823) --- coreutils-acl-extended-file-nofollow.patch | 74 ++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 coreutils-acl-extended-file-nofollow.patch diff --git a/coreutils-acl-extended-file-nofollow.patch b/coreutils-acl-extended-file-nofollow.patch new file mode 100644 index 0000000..ad72293 --- /dev/null +++ b/coreutils-acl-extended-file-nofollow.patch @@ -0,0 +1,74 @@ +From 95f7c57ff4090a5dee062044d2c7b99879077808 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka redhat.com> +Date: Fri, 22 Jul 2011 14:48:42 +0200 +Subject: [PATCH] file-has-acl: use acl_extended_file_nofollow if available + +* lib/acl-internal.h (HAVE_ACL_EXTENDED_FILE): New macro. +(acl_extended_file): New macro. +* lib/file-has-acl.c (file_has_acl): Use acl_extended_file_nofollow. +* m4/acl.m4 (gl_FUNC_ACL): Check for acl_extended_file_nofollow. +This addresses http://bugzilla.redhat.com/692823. +--- + lib/acl-internal.h | 6 ++++++ + lib/file-has-acl.c | 10 +++++++++- + m4/acl.m4 | 2 +- + 3 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/lib/acl-internal.h b/lib/acl-internal.h +index b3160a7..b509666 100644 +--- a/lib/acl-internal.h ++++ b/lib/acl-internal.h +@@ -133,6 +133,12 @@ rpl_acl_set_fd (int fd, acl_t acl) + # endif + + /* Linux-specific */ ++# ifndef HAVE_ACL_EXTENDED_FILE_NOFOLLOW ++# define HAVE_ACL_EXTENDED_FILE_NOFOLLOW false ++# define acl_extended_file_nofollow(name) (-1) ++# endif ++ ++/* Linux-specific */ + # ifndef HAVE_ACL_FROM_MODE + # define HAVE_ACL_FROM_MODE false + # define acl_from_mode(mode) (NULL) +diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c +index 3d4d5c1..2ee6ba2 100644 +--- a/lib/file-has-acl.c ++++ b/lib/file-has-acl.c +@@ -366,12 +366,20 @@ file_has_acl (char const *name, struct stat const *sb) + /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */ + int ret; + +- if (HAVE_ACL_EXTENDED_FILE) /* Linux */ ++ if (HAVE_ACL_EXTENDED_FILE || HAVE_ACL_EXTENDED_FILE_NOFOLLOW) /* Linux */ + { ++# if HAVE_ACL_EXTENDED_FILE_NOFOLLOW ++ /* acl_extended_file_nofollow() uses lgetxattr() in order to prevent ++ unnecessary mounts, but it returns the same result as we already ++ know that NAME is not a symbolic link at this point (modulo the ++ TOCTTOU race condition). */ ++ ret = acl_extended_file_nofollow (name); ++# else + /* On Linux, acl_extended_file is an optimized function: It only + makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for + ACL_TYPE_DEFAULT. */ + ret = acl_extended_file (name); ++# endif + } + else /* FreeBSD, MacOS X, IRIX, Tru64 */ + { +diff --git a/m4/acl.m4 b/m4/acl.m4 +index d6a448a..ecf0384 100644 +--- a/m4/acl.m4 ++++ b/m4/acl.m4 +@@ -33,7 +33,7 @@ AC_DEFUN([gl_FUNC_ACL], + AC_CHECK_FUNCS( + [acl_get_file acl_get_fd acl_set_file acl_set_fd \ + acl_free acl_from_mode acl_from_text \ +- acl_delete_def_file acl_extended_file \ ++ acl_delete_def_file acl_extended_file acl_extended_file_nofollow \ + acl_delete_fd_np acl_delete_file_np \ + acl_copy_ext_native acl_create_entry_np \ + acl_to_short_text acl_free_text]) +-- +1.7.6.586.g302e6 diff --git a/coreutils.spec b/coreutils.spec index 2784cdc..09422e3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.12 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -32,6 +32,8 @@ Patch103: coreutils-8.2-uname-processortype.patch Patch104: coreutils-df-direct.patch #add note about mkdir --mode behaviour into info documentation(#610559) Patch107: coreutils-8.4-mkdir-modenote.patch +#use acl_extended_file_nofollow if available (#692823) +Patch108: coreutils-acl-extended-file-nofollow.patch # sh-utils #add info about TZ envvar to date manpage @@ -121,6 +123,7 @@ Libraries for coreutils package. %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect %patch107 -p1 -b .mkdirmode +%patch108 -p1 -b .nofollow # sh-utils %patch703 -p1 -b .dateman @@ -329,6 +332,9 @@ fi %{_libdir}/coreutils %changelog +* Fri Jul 29 2011 Ondrej Vasik - 8.12-3 +- use acl_extended_file_nofollow() if available (#692823) + * Fri Jul 15 2011 Ondrej Vasik - 8.12-2 - support ecryptfs mount of Private (postlogin into su.pamd) (#722323) From 4afb5b057dc5e24a2cf168ca2718ef32b7cc810f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 11 Aug 2011 16:38:37 +0200 Subject: [PATCH 136/523] Fix cp -Z functionality if destination exists(#715557), deprecate it as non-upstream option (it is easy to achieve this functionality other way, cp should not handle changes) --- coreutils-cpZ-deprecate.patch | 24 ++++++++++++++++++++++++ coreutils.spec | 10 +++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 coreutils-cpZ-deprecate.patch diff --git a/coreutils-cpZ-deprecate.patch b/coreutils-cpZ-deprecate.patch new file mode 100644 index 0000000..fce7b8c --- /dev/null +++ b/coreutils-cpZ-deprecate.patch @@ -0,0 +1,24 @@ +diff -urNp coreutils-8.12-orig/src/copy.c coreutils-8.12/src/copy.c +--- coreutils-8.12-orig/src/copy.c 2011-08-11 16:05:15.432485738 +0200 ++++ coreutils-8.12/src/copy.c 2011-08-11 16:14:28.660360607 +0200 +@@ -850,7 +850,7 @@ copy_reg (char const *src_name, char con + 1) the src context may prohibit writing, and + 2) because it's more consistent to use the same context + that is used when the destination file doesn't already exist. */ +- if (x->preserve_security_context && 0 <= dest_desc) ++ if ((x->set_security_context || x->preserve_security_context) && 0 <= dest_desc) + { + bool all_errors = (!x->data_copy_required + || x->require_preserve_context); +Binary files coreutils-8.12-orig/src/.copy.c.swp and coreutils-8.12/src/.copy.c.swp differ +diff -urNp coreutils-8.12-orig/src/cp.c coreutils-8.12/src/cp.c +--- coreutils-8.12-orig/src/cp.c 2011-08-11 16:05:15.435486976 +0200 ++++ coreutils-8.12/src/cp.c 2011-08-11 16:16:56.408644526 +0200 +@@ -1119,6 +1119,7 @@ main (int argc, char **argv) + exit( 1 ); + } + x.set_security_context = true; ++ (void) fprintf(stderr, _("Warning, -Z/--context option is deprecated and will be removed soon!\nPlease use 'install' utility instead of cp for this functionality.\n")); + /* if there's a security_context given set new path + components to that context, too */ + if ( setfscreatecon(optarg) < 0 ) { diff --git a/coreutils.spec b/coreutils.spec index 09422e3..f69eb9a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.12 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -64,6 +64,8 @@ Patch917: coreutils-8.4-su-pie.patch #(upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch +#Deprecate cp -Z/--context non-upstream option +Patch952: coreutils-cpZ-deprecate.patch BuildRequires: libselinux-devel BuildRequires: libacl-devel @@ -144,6 +146,7 @@ Libraries for coreutils package. #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman +%patch952 -p1 -b .cpZ chmod a+x tests/misc/sort-mb-tests tests/df/direct || : @@ -332,6 +335,11 @@ fi %{_libdir}/coreutils %changelog +* Thu Aug 11 2011 Ondrej Vasik - 8.12-4 +- deprecate non-upstream cp -Z/--context (install should be + used instead of it), make it working if destination exists + (#715557) + * Fri Jul 29 2011 Ondrej Vasik - 8.12-3 - use acl_extended_file_nofollow() if available (#692823) From 9938e5be66cf27189192878fbc940b326abb2b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 18 Aug 2011 17:58:14 +0200 Subject: [PATCH 137/523] variable u should be static in uname processor type patch --- coreutils-8.2-uname-processortype.patch | 4 ++-- coreutils.spec | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/coreutils-8.2-uname-processortype.patch b/coreutils-8.2-uname-processortype.patch index 166520d..4c83df8 100644 --- a/coreutils-8.2-uname-processortype.patch +++ b/coreutils-8.2-uname-processortype.patch @@ -16,7 +16,7 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c } +#else + { -+ struct utsname u; ++ static struct utsname u; + uname(&u); + element = u.machine; + } @@ -38,7 +38,7 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c } +#else + { -+ struct utsname u; ++ static struct utsname u; + uname(&u); + element = u.machine; + if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6') diff --git a/coreutils.spec b/coreutils.spec index f69eb9a..6ae3334 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.12 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -335,6 +335,9 @@ fi %{_libdir}/coreutils %changelog +* Thu Aug 18 2011 Ondrej Vasik - 8.12-5 +- variable "u" should be static in uname processor type patch + * Thu Aug 11 2011 Ondrej Vasik - 8.12-4 - deprecate non-upstream cp -Z/--context (install should be used instead of it), make it working if destination exists From 6ff9fce16118cf865f362b9ab7a327edd04ef1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 23 Aug 2011 14:54:04 +0200 Subject: [PATCH 138/523] su: fix shell suspend in tcsh (#597928) --- coreutils-8.5-pam.patch | 22 ++++++++++++++++------ coreutils.spec | 5 ++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/coreutils-8.5-pam.patch b/coreutils-8.5-pam.patch index 71b85e7..8a924b2 100644 --- a/coreutils-8.5-pam.patch +++ b/coreutils-8.5-pam.patch @@ -106,7 +106,7 @@ index f8f5b61..811aad7 100644 static struct option const longopts[] = { {"command", required_argument, NULL, 'c'}, -@@ -200,7 +224,164 @@ log_su (struct passwd const *pw, bool successful) +@@ -200,7 +224,174 @@ log_su (struct passwd const *pw, bool successful) } #endif @@ -168,7 +168,7 @@ index f8f5b61..811aad7 100644 +create_watching_parent (void) +{ + pid_t child; -+ sigset_t ourset; ++ sigset_t ourset, blockset; + int status = 0; + + retval = pam_open_session (pamh, 0); @@ -230,7 +230,17 @@ index f8f5b61..811aad7 100644 + + if (pid != (pid_t)-1 && WIFSTOPPED (status)) + { ++ /* tcsh sends SIGTSTP to the process group, and so is already pending */ + kill (getpid (), SIGSTOP); ++ if (WSTOPSIG(status) != SIGSTOP) { ++ sigemptyset(&blockset); ++ if (sigaddset(&blockset, WSTOPSIG(status)) || ++ sigprocmask(SIG_UNBLOCK, &blockset, &ourset) || ++ sigprocmask(SIG_SETMASK, &ourset, NULL)) ++ { ++ error (0, errno, _("cannot set signal handler")); ++ } ++ } + /* once we get here, we must have resumed */ + kill (pid, SIGCONT); + } @@ -271,7 +281,7 @@ index f8f5b61..811aad7 100644 Return true if the user gives the correct password for entry PW, false if not. Return true without asking for a password if run by UID 0 or if PW has an empty password. */ -@@ -208,10 +389,52 @@ log_su (struct passwd const *pw, bool successful) +@@ -208,10 +399,52 @@ log_su (struct passwd const *pw, bool successful) static bool correct_password (const struct passwd *pw) { @@ -325,7 +335,7 @@ index f8f5b61..811aad7 100644 endspent (); if (sp) -@@ -232,6 +455,7 @@ correct_password (const struct passwd *pw) +@@ -232,6 +465,7 @@ correct_password (const struct passwd *pw) encrypted = crypt (unencrypted, correct); memset (unencrypted, 0, strlen (unencrypted)); return STREQ (encrypted, correct); @@ -333,7 +343,7 @@ index f8f5b61..811aad7 100644 } /* Update `environ' for the new shell based on PW, with SHELL being -@@ -274,19 +498,41 @@ modify_environment (const struct passwd *pw, const char *shell) +@@ -274,19 +508,41 @@ modify_environment (const struct passwd *pw, const char *shell) } } } @@ -377,7 +387,7 @@ index f8f5b61..811aad7 100644 if (setgid (pw->pw_gid)) error (EXIT_CANCELED, errno, _("cannot set group id")); if (setuid (pw->pw_uid)) -@@ -500,9 +746,21 @@ main (int argc, char **argv) +@@ -500,9 +756,21 @@ main (int argc, char **argv) shell = NULL; } shell = xstrdup (shell ? shell : pw->pw_shell); diff --git a/coreutils.spec b/coreutils.spec index 6ae3334..3d5c6a1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.12 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -335,6 +335,9 @@ fi %{_libdir}/coreutils %changelog +* Tue Aug 23 2011 Ondrej Vasik - 8.12-6 +- su: fix shell suspend in tcsh (#597928) + * Thu Aug 18 2011 Ondrej Vasik - 8.12-5 - variable "u" should be static in uname processor type patch From a68f226c74bfbedbf309ef50ee24ee40c51bb304 Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mon, 5 Sep 2011 08:18:24 +0200 Subject: [PATCH 139/523] incorporate some i18n patch fixes from SUSE: fix output-delimiter option in cut, prevent infinite loop in sort when ignoring chars, prevent using unitialized variable in cut --- coreutils-i18n.patch | 69 ++++++++++++++++++++++++++++---------------- coreutils.spec | 8 ++++- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 6e10f37..7a4657e 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -75,7 +75,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c + while (0) + +/* Get wide character on BUFPOS. BUFPOS is not included after that. -+ If byte sequence is not valid as a character, CONVFAIL is 1. Otherwise 0. */ ++ If byte sequence is not valid as a character, CONVFAIL is 1. Otherwise 0. */ +#define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ + do \ + { \ @@ -226,7 +226,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c } max_range_endpoint = 0; -@@ -580,6 +662,63 @@ cut_bytes (FILE *stream) +@@ -580,6 +662,77 @@ cut_bytes (FILE *stream) } } @@ -234,11 +234,11 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c +/* This function is in use for the following case. + + 1. Read from the stream STREAM, printing to standard output any selected -+ characters. ++ 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) +{ @@ -251,6 +251,9 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c + as same character as WC. */ + mbstate_t state; /* State of the stream. */ + int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ ++ /* 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; + + idx = 0; + buflen = 0; @@ -273,12 +276,23 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c + { + putchar ('\n'); + idx = 0; ++ print_delimiter = false; + } + else + { ++ bool range_start; ++ bool *rs = output_delimiter_specified ? &range_start : NULL; + idx += (operating_mode == byte_mode) ? mblength : 1; -+ if (print_kth (idx, NULL)) -+ fwrite (bufpos, mblength, sizeof(char), stdout); ++ if (print_kth (idx, rs)) ++ { ++ fwrite (bufpos, mblength, sizeof(char), stdout); ++ ++ if (rs && *rs && print_delimiter) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ } + } + + buflen -= mblength; @@ -286,11 +300,11 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c + } +} +#endif -+ ++ /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -702,13 +841,192 @@ cut_fields (FILE *stream) +@@ -702,13 +855,195 @@ cut_fields (FILE *stream) } } @@ -321,7 +335,10 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c + c = getc (stream); + empty_input = (c == EOF); + if (c != EOF) ++ { + ungetc (c, stream); ++ wc = 0; ++ } + else + wc = WEOF; + @@ -486,7 +503,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c } /* Process file FILE to standard output. -@@ -760,6 +1078,8 @@ main (int argc, char **argv) +@@ -760,6 +1095,8 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -495,7 +512,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -782,7 +1102,6 @@ main (int argc, char **argv) +@@ -782,7 +1119,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -503,7 +520,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -790,6 +1109,14 @@ main (int argc, char **argv) +@@ -790,6 +1126,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -518,7 +535,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -801,10 +1128,35 @@ main (int argc, char **argv) +@@ -801,10 +1145,35 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean `use the NUL byte as the delimiter.' */ @@ -558,7 +575,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -817,6 +1169,7 @@ main (int argc, char **argv) +@@ -817,6 +1187,7 @@ main (int argc, char **argv) break; case 'n': @@ -566,7 +583,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c break; case 's': -@@ -839,7 +1192,7 @@ main (int argc, char **argv) +@@ -839,7 +1209,7 @@ main (int argc, char **argv) if (operating_mode == undefined_mode) FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); @@ -575,7 +592,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c FATAL_ERROR (_("an input delimiter may be specified only\ when operating on fields")); -@@ -866,15 +1219,34 @@ main (int argc, char **argv) +@@ -866,15 +1236,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -607,7 +624,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c + if (MB_CUR_MAX <= 1 || force_singlebyte_mode) +#endif + { -+ static char dummy[2]; ++ static char dummy[2]; + dummy[0] = delim; + dummy[1] = '\0'; + output_delimiter_string = dummy; @@ -1551,7 +1568,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c - return xmemcoll (beg1, len1, beg2, len2); - diff = memcmp (beg1, beg2, MIN (len1, len2)); + copy[0] = (unsigned char *) beg[0]; -+ copy[1] = (unsigned char *) beg[1]; ++ copy[1] = (unsigned char *) beg[1]; } + if (hard_LC_COLLATE) @@ -1632,7 +1649,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c case 't': { - unsigned char newtab = optarg[0]; -+ char *newtab; ++ char *newtab = NULL; + size_t newtablen; + newtab = xstrdup (optarg); +#if HAVE_MBRTOWC @@ -1654,7 +1671,8 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c + newtablen = 1; if (! newtab) + { - newtab = '\n'; /* '' => process the whole line. */ +- newtab = '\n'; /* '' => process the whole line. */ ++ newtab = "\n"; /* '' => process the whole line. */ + } else if (optarg[1]) { @@ -3085,7 +3103,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2624,6 +3058,179 @@ keycompare (struct line const *a, struct +@@ -2624,6 +3058,180 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3167,7 +3185,8 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c + if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ + STATE = state_bak; \ + if (!ignore) \ -+ COPY[NEW_LEN++] = TEXT[i++]; \ ++ COPY[NEW_LEN++] = TEXT[i]; \ ++ i++; \ + continue; \ + } \ + \ @@ -3265,7 +3284,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4087,7 +4694,7 @@ main (int argc, char **argv) +@@ -4087,7 +4695,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3274,7 +3293,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4108,6 +4715,29 @@ main (int argc, char **argv) +@@ -4108,6 +4716,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3304,7 +3323,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c have_read_stdin = false; inittables (); -@@ -4378,13 +5008,34 @@ main (int argc, char **argv) +@@ -4378,13 +5009,34 @@ main (int argc, char **argv) case 't': { @@ -3343,7 +3362,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -4395,9 +5046,12 @@ main (int argc, char **argv) +@@ -4395,9 +5047,12 @@ main (int argc, char **argv) quote (optarg)); } } diff --git a/coreutils.spec b/coreutils.spec index 3d5c6a1..906fd98 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.12 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -335,6 +335,12 @@ fi %{_libdir}/coreutils %changelog +* Mon Sep 05 2011 Ondrej Vasik - 8.12-7 +- incorporate some i18n patch fixes from OpenSUSE: + - fix cut output-delimiter option + - prevent infinite loop in sort when ignoring chars + - prevent using unitialized variable in cut + * Tue Aug 23 2011 Ondrej Vasik - 8.12-6 - su: fix shell suspend in tcsh (#597928) From b5f92004485e03004e5830205af0d1873f84f482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 9 Sep 2011 13:16:47 +0200 Subject: [PATCH 140/523] new upstream release 8.13, drop libs subpackage, temporarily disable multibyte checks in misc/cut test --- .gitignore | 1 + coreutils-6.10-configuration.patch | 43 ++-- coreutils-7.4-sttytcsadrain.patch | 10 +- coreutils-acl-extended-file-nofollow.patch | 74 ------- coreutils-cpZ-deprecate.patch | 1 - coreutils-df-direct.patch | 2 +- coreutils-i18n.patch | 217 +++++++++++---------- coreutils-selinux.patch | 158 +++++++-------- coreutils.spec | 51 ++--- sources | 2 +- 10 files changed, 243 insertions(+), 316 deletions(-) delete mode 100644 coreutils-acl-extended-file-nofollow.patch diff --git a/.gitignore b/.gitignore index 298ae80..c560e51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /coreutils-8.10.tar.xz /coreutils-8.11.tar.xz /coreutils-8.12.tar.xz +/coreutils-8.13.tar.xz diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 4f52076..8dd43f8 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.4-orig/gnulib-tests/gnulib.mk coreutils-8.4/gnulib-tests/gnulib.mk ---- coreutils-8.4-orig/gnulib-tests/gnulib.mk 2010-01-13 22:01:30.000000000 +0100 -+++ coreutils-8.4/gnulib-tests/gnulib.mk 2010-01-14 10:28:17.000000000 +0100 -@@ -256,9 +256,9 @@ EXTRA_DIST += nap.h test-chown.h test-ch +diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-tests/gnulib.mk +--- coreutils-8.13-orig/gnulib-tests/gnulib.mk 2011-09-08 17:09:08.000000000 +0200 ++++ coreutils-8.13/gnulib-tests/gnulib.mk 2011-09-09 10:14:18.714689661 +0200 +@@ -235,9 +235,9 @@ EXTRA_DIST += nap.h test-chown.h test-ch ## begin gnulib module cloexec-tests @@ -14,7 +14,7 @@ diff -urNp coreutils-8.4-orig/gnulib-tests/gnulib.mk coreutils-8.4/gnulib-tests/ ## end gnulib module cloexec-tests -@@ -332,9 +332,9 @@ EXTRA_DIST += test-dirname.c +@@ -321,9 +321,9 @@ EXTRA_DIST += test-dirname.c ## begin gnulib module dup2-tests @@ -27,7 +27,7 @@ diff -urNp coreutils-8.4-orig/gnulib-tests/gnulib.mk coreutils-8.4/gnulib-tests/ ## end gnulib module dup2-tests -@@ -376,9 +376,9 @@ EXTRA_DIST += test-exclude.c test-exclud +@@ -373,9 +373,9 @@ EXTRA_DIST += test-fadvise.c ## begin gnulib module fchdir-tests @@ -40,7 +40,7 @@ diff -urNp coreutils-8.4-orig/gnulib-tests/gnulib.mk coreutils-8.4/gnulib-tests/ ## end gnulib module fchdir-tests -@@ -855,10 +855,10 @@ EXTRA_DIST += $(top_srcdir)/build-aux/li +@@ -918,10 +918,10 @@ EXTRA_DIST += test-link.h test-link.c si ## begin gnulib module linkat-tests @@ -55,7 +55,7 @@ diff -urNp coreutils-8.4-orig/gnulib-tests/gnulib.mk coreutils-8.4/gnulib-tests/ ## end gnulib module linkat-tests -@@ -1532,9 +1532,9 @@ EXTRA_DIST += test-uname.c signature.h m +@@ -1891,9 +1891,9 @@ EXTRA_DIST += test-uname.c signature.h m ## begin gnulib module unistd-safer-tests @@ -68,26 +68,25 @@ diff -urNp coreutils-8.4-orig/gnulib-tests/gnulib.mk coreutils-8.4/gnulib-tests/ ## end gnulib module unistd-safer-tests -@@ -1644,10 +1644,10 @@ EXTRA_DIST += test-usleep.c signature.h +@@ -1997,10 +1997,10 @@ EXTRA_DIST += test-usleep.c signature.h ## begin gnulib module utimens-tests -TESTS += test-utimens -check_PROGRAMS += test-utimens --test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBINTL@ +-test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) -EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h +#TESTS += test-utimens +#check_PROGRAMS += test-utimens -+#test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBINTL@ ++#test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) +#EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h ## end gnulib module utimens-tests - -diff -urNp coreutils-8.4-orig/tests/Makefile.am coreutils-8.4/tests/Makefile.am ---- coreutils-8.4-orig/tests/Makefile.am 2010-01-03 18:06:20.000000000 +0100 -+++ coreutils-8.4/tests/Makefile.am 2010-01-14 10:28:17.000000000 +0100 -@@ -79,7 +79,6 @@ TESTS = \ +diff -urNp coreutils-8.13-orig/tests/Makefile.am coreutils-8.13/tests/Makefile.am +--- coreutils-8.13-orig/tests/Makefile.am 2011-09-02 14:08:40.000000000 +0200 ++++ coreutils-8.13/tests/Makefile.am 2011-09-09 10:12:56.364814725 +0200 +@@ -86,7 +86,6 @@ TESTS = \ rm/ext3-perf \ rm/cycle \ cp/link-heap \ @@ -95,15 +94,15 @@ diff -urNp coreutils-8.4-orig/tests/Makefile.am coreutils-8.4/tests/Makefile.am tail-2/inotify-hash-abuse2 \ tail-2/F-vs-missing \ tail-2/F-vs-rename \ -diff -urNp coreutils-8.4-orig/tests/touch/no-dereference coreutils-8.4/tests/touch/no-dereference ---- coreutils-8.4-orig/tests/touch/no-dereference 2010-01-12 15:36:17.000000000 +0100 -+++ coreutils-8.4/tests/touch/no-dereference 2010-01-14 10:28:17.000000000 +0100 -@@ -46,6 +46,8 @@ test -f nowhere && fail=1 +diff -urNp coreutils-8.13-orig/tests/touch/no-dereference coreutils-8.13/tests/touch/no-dereference +--- coreutils-8.13-orig/tests/touch/no-dereference 2011-08-08 09:42:16.000000000 +0200 ++++ coreutils-8.13/tests/touch/no-dereference 2011-09-09 10:15:21.167060702 +0200 +@@ -42,6 +42,8 @@ test -f nowhere && fail=1 grep '^#define HAVE_UTIMENSAT 1' "$CONFIG_HEADER" > /dev/null || grep '^#define HAVE_LUTIMES 1' "$CONFIG_HEADER" > /dev/null || - skip_test_ 'this system lacks the utimensat function' + skip_ 'this system lacks the utimensat function' +grep '^#define HAVE_WORKINGKOJI 1' "$CONFIG_HEADER" > /dev/null || -+ skip_test_ 'rest of the test disabled due to koji lack of utimensat function' ++ skip_ 'rest of the test disabled due to koji lack of utimensat function' # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to diff --git a/coreutils-7.4-sttytcsadrain.patch b/coreutils-7.4-sttytcsadrain.patch index caf8387..fe83798 100644 --- a/coreutils-7.4-sttytcsadrain.patch +++ b/coreutils-7.4-sttytcsadrain.patch @@ -1,9 +1,9 @@ -diff -urNp coreutils-7.4-orig/src/stty.c coreutils-7.4/src/stty.c ---- coreutils-7.4-orig/src/stty.c 2009-04-24 14:41:19.000000000 +0200 -+++ coreutils-7.4/src/stty.c 2009-06-11 10:15:41.000000000 +0200 -@@ -1001,7 +1001,7 @@ main (int argc, char **argv) +diff -urNp coreutils-8.13-orig/src/stty.c coreutils-8.13/src/stty.c +--- coreutils-8.13-orig/src/stty.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/stty.c 2011-09-09 10:18:57.526687209 +0200 +@@ -1005,7 +1005,7 @@ main (int argc, char **argv) spurious difference in an uninitialized portion of the structure. */ - DECLARE_ZEROED_AGGREGATE (struct termios, new_mode); + struct termios new_mode = { 0, }; - if (tcsetattr (STDIN_FILENO, TCSADRAIN, &mode)) + if (tcsetattr (STDIN_FILENO, TCSANOW, &mode)) diff --git a/coreutils-acl-extended-file-nofollow.patch b/coreutils-acl-extended-file-nofollow.patch deleted file mode 100644 index ad72293..0000000 --- a/coreutils-acl-extended-file-nofollow.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 95f7c57ff4090a5dee062044d2c7b99879077808 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka redhat.com> -Date: Fri, 22 Jul 2011 14:48:42 +0200 -Subject: [PATCH] file-has-acl: use acl_extended_file_nofollow if available - -* lib/acl-internal.h (HAVE_ACL_EXTENDED_FILE): New macro. -(acl_extended_file): New macro. -* lib/file-has-acl.c (file_has_acl): Use acl_extended_file_nofollow. -* m4/acl.m4 (gl_FUNC_ACL): Check for acl_extended_file_nofollow. -This addresses http://bugzilla.redhat.com/692823. ---- - lib/acl-internal.h | 6 ++++++ - lib/file-has-acl.c | 10 +++++++++- - m4/acl.m4 | 2 +- - 3 files changed, 16 insertions(+), 2 deletions(-) - -diff --git a/lib/acl-internal.h b/lib/acl-internal.h -index b3160a7..b509666 100644 ---- a/lib/acl-internal.h -+++ b/lib/acl-internal.h -@@ -133,6 +133,12 @@ rpl_acl_set_fd (int fd, acl_t acl) - # endif - - /* Linux-specific */ -+# ifndef HAVE_ACL_EXTENDED_FILE_NOFOLLOW -+# define HAVE_ACL_EXTENDED_FILE_NOFOLLOW false -+# define acl_extended_file_nofollow(name) (-1) -+# endif -+ -+/* Linux-specific */ - # ifndef HAVE_ACL_FROM_MODE - # define HAVE_ACL_FROM_MODE false - # define acl_from_mode(mode) (NULL) -diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c -index 3d4d5c1..2ee6ba2 100644 ---- a/lib/file-has-acl.c -+++ b/lib/file-has-acl.c -@@ -366,12 +366,20 @@ file_has_acl (char const *name, struct stat const *sb) - /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */ - int ret; - -- if (HAVE_ACL_EXTENDED_FILE) /* Linux */ -+ if (HAVE_ACL_EXTENDED_FILE || HAVE_ACL_EXTENDED_FILE_NOFOLLOW) /* Linux */ - { -+# if HAVE_ACL_EXTENDED_FILE_NOFOLLOW -+ /* acl_extended_file_nofollow() uses lgetxattr() in order to prevent -+ unnecessary mounts, but it returns the same result as we already -+ know that NAME is not a symbolic link at this point (modulo the -+ TOCTTOU race condition). */ -+ ret = acl_extended_file_nofollow (name); -+# else - /* On Linux, acl_extended_file is an optimized function: It only - makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for - ACL_TYPE_DEFAULT. */ - ret = acl_extended_file (name); -+# endif - } - else /* FreeBSD, MacOS X, IRIX, Tru64 */ - { -diff --git a/m4/acl.m4 b/m4/acl.m4 -index d6a448a..ecf0384 100644 ---- a/m4/acl.m4 -+++ b/m4/acl.m4 -@@ -33,7 +33,7 @@ AC_DEFUN([gl_FUNC_ACL], - AC_CHECK_FUNCS( - [acl_get_file acl_get_fd acl_set_file acl_set_fd \ - acl_free acl_from_mode acl_from_text \ -- acl_delete_def_file acl_extended_file \ -+ acl_delete_def_file acl_extended_file acl_extended_file_nofollow \ - acl_delete_fd_np acl_delete_file_np \ - acl_copy_ext_native acl_create_entry_np \ - acl_to_short_text acl_free_text]) --- -1.7.6.586.g302e6 diff --git a/coreutils-cpZ-deprecate.patch b/coreutils-cpZ-deprecate.patch index fce7b8c..713b7c5 100644 --- a/coreutils-cpZ-deprecate.patch +++ b/coreutils-cpZ-deprecate.patch @@ -10,7 +10,6 @@ diff -urNp coreutils-8.12-orig/src/copy.c coreutils-8.12/src/copy.c { bool all_errors = (!x->data_copy_required || x->require_preserve_context); -Binary files coreutils-8.12-orig/src/.copy.c.swp and coreutils-8.12/src/.copy.c.swp differ diff -urNp coreutils-8.12-orig/src/cp.c coreutils-8.12/src/cp.c --- coreutils-8.12-orig/src/cp.c 2011-08-11 16:05:15.435486976 +0200 +++ coreutils-8.12/src/cp.c 2011-08-11 16:16:56.408644526 +0200 diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 025323d..2139809 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -133,7 +133,7 @@ diff -urNp coreutils-8.11-orig/tests/df/direct coreutils-8.11/tests/df/direct +. "${srcdir=.}/init.sh"; path_prepend_ ../src +print_ver_ df + -+df || skip_test_ "df fails" ++df || skip_ "df fails" + +DIR=`pwd` || framework_failure +FILE="$DIR/file" diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 6e10f37..e8803ae 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.10-orig/lib/linebuffer.h coreutils-8.10/lib/linebuffer.h ---- coreutils-8.10-orig/lib/linebuffer.h 2011-01-06 09:47:56.000000000 +0100 -+++ coreutils-8.10/lib/linebuffer.h 2011-02-04 20:13:23.985464731 +0100 +diff -urNp coreutils-8.13-orig/lib/linebuffer.h coreutils-8.13/lib/linebuffer.h +--- coreutils-8.13-orig/lib/linebuffer.h 2011-04-24 19:21:45.000000000 +0200 ++++ coreutils-8.13/lib/linebuffer.h 2011-09-09 10:23:14.163704760 +0200 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.10-orig/lib/linebuffer.h coreutils-8.10/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c ---- coreutils-8.10-orig/src/cut.c 2011-01-31 13:40:38.000000000 +0100 -+++ coreutils-8.10/src/cut.c 2011-02-04 20:13:23.988464025 +0100 +diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c +--- coreutils-8.13-orig/src/cut.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/cut.c 2011-09-09 10:23:14.165701039 +0200 @@ -28,6 +28,11 @@ #include #include @@ -226,7 +226,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c } max_range_endpoint = 0; -@@ -580,6 +662,63 @@ cut_bytes (FILE *stream) +@@ -582,6 +664,63 @@ cut_bytes (FILE *stream) } } @@ -290,7 +290,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -702,13 +841,192 @@ cut_fields (FILE *stream) +@@ -704,13 +843,192 @@ cut_fields (FILE *stream) } } @@ -486,7 +486,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c } /* Process file FILE to standard output. -@@ -760,6 +1078,8 @@ main (int argc, char **argv) +@@ -762,6 +1080,8 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -495,7 +495,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -782,7 +1102,6 @@ main (int argc, char **argv) +@@ -784,7 +1104,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -503,7 +503,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -790,6 +1109,14 @@ main (int argc, char **argv) +@@ -792,6 +1111,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -518,7 +518,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -801,10 +1128,35 @@ main (int argc, char **argv) +@@ -803,10 +1130,35 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean `use the NUL byte as the delimiter.' */ @@ -558,7 +558,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -817,6 +1169,7 @@ main (int argc, char **argv) +@@ -819,6 +1171,7 @@ main (int argc, char **argv) break; case 'n': @@ -566,7 +566,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c break; case 's': -@@ -839,7 +1192,7 @@ main (int argc, char **argv) +@@ -841,7 +1194,7 @@ main (int argc, char **argv) if (operating_mode == undefined_mode) FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); @@ -575,7 +575,7 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c FATAL_ERROR (_("an input delimiter may be specified only\ when operating on fields")); -@@ -866,15 +1219,34 @@ main (int argc, char **argv) +@@ -868,15 +1221,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -616,9 +616,9 @@ diff -urNp coreutils-8.10-orig/src/cut.c coreutils-8.10/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.10-orig/src/expand.c coreutils-8.10/src/expand.c ---- coreutils-8.10-orig/src/expand.c 2011-01-31 13:40:38.000000000 +0100 -+++ coreutils-8.10/src/expand.c 2011-02-04 20:13:23.990463571 +0100 +diff -urNp coreutils-8.13-orig/src/expand.c coreutils-8.13/src/expand.c +--- coreutils-8.13-orig/src/expand.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/expand.c 2011-09-09 10:23:14.167583399 +0200 @@ -38,12 +38,29 @@ #include #include @@ -806,9 +806,9 @@ diff -urNp coreutils-8.10-orig/src/expand.c coreutils-8.10/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c ---- coreutils-8.10-orig/src/fold.c 2011-01-31 13:40:38.000000000 +0100 -+++ coreutils-8.10/src/fold.c 2011-02-04 20:13:23.992463115 +0100 +diff -urNp coreutils-8.13-orig/src/fold.c coreutils-8.13/src/fold.c +--- coreutils-8.13-orig/src/fold.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/fold.c 2011-09-09 10:23:14.169583741 +0200 @@ -22,12 +22,34 @@ #include #include @@ -1179,7 +1179,7 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c if (ferror (istream)) { error (0, saved_errno, "%s", filename); -@@ -254,7 +502,8 @@ main (int argc, char **argv) +@@ -254,7 +501,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1189,7 +1189,7 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -263,7 +512,15 @@ main (int argc, char **argv) +@@ -263,7 +511,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1206,9 +1206,9 @@ diff -urNp coreutils-8.10-orig/src/fold.c coreutils-8.10/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c ---- coreutils-8.10-orig/src/join.c 2011-01-31 13:40:38.000000000 +0100 -+++ coreutils-8.10/src/join.c 2011-02-04 20:20:15.985114387 +0100 +diff -urNp coreutils-8.13-orig/src/join.c coreutils-8.13/src/join.c +--- coreutils-8.13-orig/src/join.c 2011-08-08 10:16:09.000000000 +0200 ++++ coreutils-8.13/src/join.c 2011-09-09 10:23:14.172687087 +0200 @@ -22,18 +22,32 @@ #include #include @@ -1243,7 +1243,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "join" -@@ -129,10 +143,12 @@ static struct outlist outlist_head; +@@ -135,10 +149,12 @@ static struct outlist outlist_head; /* Last element in `outlist', where a new element can be added. */ static struct outlist *outlist_end = &outlist_head; @@ -1260,7 +1260,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -257,13 +273,14 @@ xfields (struct line *line) +@@ -263,13 +279,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1278,7 +1278,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c { /* Skip leading blanks before the first field. */ while (isblank (to_uchar (*ptr))) -@@ -287,6 +304,148 @@ xfields (struct line *line) +@@ -293,6 +310,148 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1427,7 +1427,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c static void freeline (struct line *line) { -@@ -308,56 +467,115 @@ keycmp (struct line const *line1, struct +@@ -314,56 +473,115 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1566,9 +1566,9 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -438,6 +656,11 @@ get_line (FILE *fp, struct line **linep, - return false; +@@ -455,6 +673,11 @@ get_line (FILE *fp, struct line **linep, } + ++line_no[which - 1]; +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) @@ -1578,7 +1578,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c xfields (line); if (prevline[which - 1]) -@@ -537,21 +760,28 @@ prfield (size_t n, struct line const *li +@@ -554,21 +777,28 @@ prfield (size_t n, struct line const *li /* Output all the fields in line, other than the join field. */ @@ -1610,7 +1610,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c prfield (i, line); } } -@@ -562,7 +792,6 @@ static void +@@ -579,7 +809,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -1618,7 +1618,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c size_t field; struct line const *line; -@@ -596,7 +825,7 @@ prjoin (struct line const *line1, struct +@@ -613,7 +842,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1627,7 +1627,7 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c } putchar ('\n'); } -@@ -1075,21 +1304,46 @@ main (int argc, char **argv) +@@ -1091,21 +1320,46 @@ main (int argc, char **argv) case 't': { @@ -1683,9 +1683,9 @@ diff -urNp coreutils-8.10-orig/src/join.c coreutils-8.10/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c ---- coreutils-8.10-orig/src/pr.c 2011-01-31 13:40:38.000000000 +0100 -+++ coreutils-8.10/src/pr.c 2011-02-04 20:13:24.002460897 +0100 +diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c +--- coreutils-8.13-orig/src/pr.c 2011-08-30 23:01:40.000000000 +0200 ++++ coreutils-8.13/src/pr.c 2011-09-09 10:23:14.177658905 +0200 @@ -312,6 +312,32 @@ #include @@ -2408,9 +2408,9 @@ diff -urNp coreutils-8.10-orig/src/pr.c coreutils-8.10/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c ---- coreutils-8.10-orig/src/sort.c 2011-02-03 11:24:35.000000000 +0100 -+++ coreutils-8.10/src/sort.c 2011-02-04 20:15:44.160384535 +0100 +diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c +--- coreutils-8.13-orig/src/sort.c 2011-07-29 10:12:25.000000000 +0200 ++++ coreutils-8.13/src/sort.c 2011-09-09 10:23:14.183686800 +0200 @@ -22,11 +22,20 @@ #include @@ -2432,7 +2432,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -163,12 +172,34 @@ static int thousands_sep; +@@ -167,12 +176,34 @@ static int thousands_sep; /* Nonzero if the corresponding locales are hard. */ static bool hard_LC_COLLATE; @@ -2468,7 +2468,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -335,13 +366,11 @@ static bool reverse; +@@ -343,13 +374,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2485,7 +2485,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -775,6 +804,46 @@ reap_all (void) +@@ -783,6 +812,46 @@ reap_all (void) reap (-1); } @@ -2532,7 +2532,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1207,7 +1276,7 @@ zaptemp (char const *name) +@@ -1215,7 +1284,7 @@ zaptemp (char const *name) free (node); } @@ -2541,7 +2541,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1222,7 +1291,7 @@ struct_month_cmp (void const *m1, void c +@@ -1230,7 +1299,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2550,7 +2550,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c { size_t i; -@@ -1234,7 +1303,7 @@ inittables (void) +@@ -1242,7 +1311,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2559,7 +2559,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1316,6 +1385,84 @@ specify_nmerge (int oi, char c, char con +@@ -1324,6 +1393,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2644,7 +2644,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1544,7 +1691,7 @@ buffer_linelim (struct buffer const *buf +@@ -1552,7 +1699,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2653,7 +2653,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1553,10 +1700,10 @@ begfield (struct line const *line, struc +@@ -1561,10 +1708,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2666,7 +2666,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1582,11 +1729,70 @@ begfield (struct line const *line, struc +@@ -1590,11 +1737,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2738,7 +2738,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1601,10 +1807,10 @@ limfield (struct line const *line, struc +@@ -1609,10 +1815,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. */ @@ -2751,7 +2751,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1650,10 +1856,10 @@ limfield (struct line const *line, struc +@@ -1658,10 +1864,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2764,7 +2764,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c if (newlim) lim = newlim; } -@@ -1684,6 +1890,130 @@ limfield (struct line const *line, struc +@@ -1692,6 +1898,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2895,7 +2895,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c /* 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 -@@ -1770,8 +2100,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1778,8 +2108,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2920,7 +2920,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c line->keybeg = line_start; } } -@@ -1892,7 +2236,7 @@ human_numcompare (char const *a, char co +@@ -1900,7 +2244,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2929,7 +2929,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1902,6 +2246,25 @@ numcompare (char const *a, char const *b +@@ -1910,6 +2254,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2955,7 +2955,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c static int general_numcompare (char const *sa, char const *sb) { -@@ -1934,7 +2297,7 @@ general_numcompare (char const *sa, char +@@ -1942,7 +2305,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -2964,7 +2964,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2209,15 +2572,14 @@ debug_key (struct line const *line, stru +@@ -2217,15 +2580,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -2982,7 +2982,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2361,7 +2723,7 @@ key_warnings (struct keyfield const *gke +@@ -2369,7 +2731,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2991,7 +2991,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2419,11 +2781,83 @@ key_warnings (struct keyfield const *gke +@@ -2427,11 +2789,83 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option `-r' only applies to last-resort comparison")); } @@ -3076,7 +3076,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c { struct keyfield *key = keylist; -@@ -2508,7 +2942,7 @@ keycompare (struct line const *a, struct +@@ -2516,7 +2950,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3085,7 +3085,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2624,6 +3058,179 @@ keycompare (struct line const *a, struct +@@ -2632,6 +3066,179 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3265,7 +3265,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4087,7 +4694,7 @@ main (int argc, char **argv) +@@ -4095,7 +4702,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3274,7 +3274,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4108,6 +4715,29 @@ main (int argc, char **argv) +@@ -4116,6 +4723,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3304,7 +3304,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c have_read_stdin = false; inittables (); -@@ -4378,13 +5008,34 @@ main (int argc, char **argv) +@@ -4386,13 +5016,34 @@ main (int argc, char **argv) case 't': { @@ -3343,7 +3343,7 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -4395,9 +5046,12 @@ main (int argc, char **argv) +@@ -4403,9 +5054,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3358,9 +3358,9 @@ diff -urNp coreutils-8.10-orig/src/sort.c coreutils-8.10/src/sort.c } break; -diff -urNp coreutils-8.10-orig/src/unexpand.c coreutils-8.10/src/unexpand.c ---- coreutils-8.10-orig/src/unexpand.c 2011-01-31 13:40:38.000000000 +0100 -+++ coreutils-8.10/src/unexpand.c 2011-02-04 20:13:24.015458014 +0100 +diff -urNp coreutils-8.13-orig/src/unexpand.c coreutils-8.13/src/unexpand.c +--- coreutils-8.13-orig/src/unexpand.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/unexpand.c 2011-09-09 10:23:14.185647633 +0200 @@ -39,12 +39,29 @@ #include #include @@ -3614,9 +3614,9 @@ diff -urNp coreutils-8.10-orig/src/unexpand.c coreutils-8.10/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c ---- coreutils-8.10-orig/src/uniq.c 2011-01-31 13:40:38.000000000 +0100 -+++ coreutils-8.10/src/uniq.c 2011-02-04 20:13:24.018457349 +0100 +diff -urNp coreutils-8.13-orig/src/uniq.c coreutils-8.13/src/uniq.c +--- coreutils-8.13-orig/src/uniq.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/uniq.c 2011-09-09 10:24:19.631560964 +0200 @@ -21,6 +21,16 @@ #include #include @@ -3669,7 +3669,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c @@ -207,7 +233,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 * + static char * _GL_ATTRIBUTE_PURE -find_field (struct linebuffer const *line) +find_field_uni (struct linebuffer *line) { @@ -3952,7 +3952,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -383,6 +612,9 @@ check_file (const char *infile, const ch +@@ -383,6 +611,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3962,7 +3962,7 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c if (!match) match_count = 0; } -@@ -428,6 +660,19 @@ main (int argc, char **argv) +@@ -428,6 +659,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -3982,10 +3982,10 @@ diff -urNp coreutils-8.10-orig/src/uniq.c coreutils-8.10/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.10-orig/tests/Makefile.am coreutils-8.10/tests/Makefile.am ---- coreutils-8.10-orig/tests/Makefile.am 2011-02-04 20:12:58.236173903 +0100 -+++ coreutils-8.10/tests/Makefile.am 2011-02-04 20:13:24.020456905 +0100 -@@ -235,6 +235,7 @@ TESTS = \ +diff -urNp coreutils-8.13-orig/tests/Makefile.am coreutils-8.13/tests/Makefile.am +--- coreutils-8.13-orig/tests/Makefile.am 2011-09-09 10:22:43.352561668 +0200 ++++ coreutils-8.13/tests/Makefile.am 2011-09-09 10:23:14.189688942 +0200 +@@ -238,6 +238,7 @@ TESTS = \ misc/sort-debug-keys \ misc/sort-debug-warn \ misc/sort-files0-from \ @@ -3993,7 +3993,7 @@ diff -urNp coreutils-8.10-orig/tests/Makefile.am coreutils-8.10/tests/Makefile.a misc/sort-float \ misc/sort-merge \ misc/sort-merge-fdlimit \ -@@ -505,6 +506,10 @@ TESTS = \ +@@ -518,6 +519,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -4004,10 +4004,21 @@ diff -urNp coreutils-8.10-orig/tests/Makefile.am coreutils-8.10/tests/Makefile.a pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.10-orig/tests/misc/cut coreutils-8.10/tests/misc/cut ---- coreutils-8.10-orig/tests/misc/cut 2011-01-31 13:40:38.000000000 +0100 -+++ coreutils-8.10/tests/misc/cut 2011-02-04 20:13:24.021456684 +0100 -@@ -26,7 +26,7 @@ use strict; +diff -urNp coreutils-8.13-orig/tests/misc/cut coreutils-8.13/tests/misc/cut +--- coreutils-8.13-orig/tests/misc/cut 2011-09-02 14:08:40.000000000 +0200 ++++ coreutils-8.13/tests/misc/cut 2011-09-09 10:23:14.190686793 +0200 +@@ -23,14 +23,15 @@ my $mb_locale = $ENV{LOCALE_FR_UTF8}; + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + +-my $mb_locale = $ENV{LOCALE_FR_UTF8}; +-! defined $mb_locale || $mb_locale eq 'none' +- and $mb_locale = 'C'; ++#my $mb_locale = $ENV{LOCALE_FR_UTF8}; ++#! defined $mb_locale || $mb_locale eq 'none' ++# and $mb_locale = 'C'; ++my $mb_locale = 'C'; + my $prog = 'cut'; my $try = "Try \`$prog --help' for more information.\n"; my $from_1 = "$prog: fields and positions are numbered from 1\n$try"; @@ -4016,7 +4027,7 @@ diff -urNp coreutils-8.10-orig/tests/misc/cut coreutils-8.10/tests/misc/cut my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; my @Tests = -@@ -143,7 +143,7 @@ my @Tests = +@@ -147,7 +147,7 @@ my @Tests = # None of the following invalid ranges provoked an error up to coreutils-6.9. ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, @@ -4025,41 +4036,41 @@ diff -urNp coreutils-8.10-orig/tests/misc/cut coreutils-8.10/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, -diff -urNp coreutils-8.10-orig/tests/misc/mb1.I coreutils-8.10/tests/misc/mb1.I ---- coreutils-8.10-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.10/tests/misc/mb1.I 2011-02-04 20:13:24.022456462 +0100 +diff -urNp coreutils-8.13-orig/tests/misc/mb1.I coreutils-8.13/tests/misc/mb1.I +--- coreutils-8.13-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.13/tests/misc/mb1.I 2011-09-09 10:23:14.191687037 +0200 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.10-orig/tests/misc/mb1.X coreutils-8.10/tests/misc/mb1.X ---- coreutils-8.10-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.10/tests/misc/mb1.X 2011-02-04 20:13:24.023456240 +0100 +diff -urNp coreutils-8.13-orig/tests/misc/mb1.X coreutils-8.13/tests/misc/mb1.X +--- coreutils-8.13-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.13/tests/misc/mb1.X 2011-09-09 10:23:14.192581910 +0200 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.10-orig/tests/misc/mb2.I coreutils-8.10/tests/misc/mb2.I ---- coreutils-8.10-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.10/tests/misc/mb2.I 2011-02-04 20:13:24.024456019 +0100 +diff -urNp coreutils-8.13-orig/tests/misc/mb2.I coreutils-8.13/tests/misc/mb2.I +--- coreutils-8.13-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.13/tests/misc/mb2.I 2011-09-09 10:23:14.192581910 +0200 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.10-orig/tests/misc/mb2.X coreutils-8.10/tests/misc/mb2.X ---- coreutils-8.10-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.10/tests/misc/mb2.X 2011-02-04 20:13:24.024456019 +0100 +diff -urNp coreutils-8.13-orig/tests/misc/mb2.X coreutils-8.13/tests/misc/mb2.X +--- coreutils-8.13-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.13/tests/misc/mb2.X 2011-09-09 10:23:14.193687456 +0200 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.10-orig/tests/misc/sort-mb-tests coreutils-8.10/tests/misc/sort-mb-tests ---- coreutils-8.10-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.10/tests/misc/sort-mb-tests 2011-02-04 20:13:24.025455797 +0100 +diff -urNp coreutils-8.13-orig/tests/misc/sort-mb-tests coreutils-8.13/tests/misc/sort-mb-tests +--- coreutils-8.13-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.13/tests/misc/sort-mb-tests 2011-09-09 10:23:14.194687565 +0200 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in @@ -4079,7 +4090,7 @@ diff -urNp coreutils-8.10-orig/tests/misc/sort-mb-tests coreutils-8.10/tests/mis +$xx -t @ -k2 -n misc/mb1.I > misc/mb1.O +code=$? +if test $code != 0; then -+ $echo "Test mb1 failed: $xx return code $code differs from expected value 0" 1>&2 ++ $echo "Test mb1 failed: $xx return code $code differs from expected value 0" + errors=`expr $errors + 1` +else + cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 0c6c51e..7ebce30 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.11-orig/configure.ac coreutils-8.11/configure.ac ---- coreutils-8.11-orig/configure.ac 2011-04-14 11:05:27.511308852 +0200 -+++ coreutils-8.11/configure.ac 2011-04-14 11:06:05.481433832 +0200 -@@ -132,6 +132,13 @@ if test "$gl_gcc_warnings" = yes; then +diff -urNp coreutils-8.13-orig/configure.ac coreutils-8.13/configure.ac +--- coreutils-8.13-orig/configure.ac 2011-09-09 10:29:52.584690353 +0200 ++++ coreutils-8.13/configure.ac 2011-09-09 10:30:39.524564991 +0200 +@@ -141,6 +141,13 @@ if test "$gl_gcc_warnings" = yes; then AC_SUBST([GNULIB_TEST_WARN_CFLAGS]) fi @@ -15,18 +15,18 @@ diff -urNp coreutils-8.11-orig/configure.ac coreutils-8.11/configure.ac AC_FUNC_FORK AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam], -diff -urNp coreutils-8.11-orig/man/chcon.x coreutils-8.11/man/chcon.x ---- coreutils-8.11-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.11/man/chcon.x 2011-04-14 11:06:05.482433878 +0200 +diff -urNp coreutils-8.13-orig/man/chcon.x coreutils-8.13/man/chcon.x +--- coreutils-8.13-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.13/man/chcon.x 2011-09-09 10:30:39.524564991 +0200 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-8.11-orig/man/runcon.x coreutils-8.11/man/runcon.x ---- coreutils-8.11-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.11/man/runcon.x 2011-04-14 11:06:05.483445779 +0200 +diff -urNp coreutils-8.13-orig/man/runcon.x coreutils-8.13/man/runcon.x +--- coreutils-8.13-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 ++++ coreutils-8.13/man/runcon.x 2011-09-09 10:30:39.544686472 +0200 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,9 +34,9 @@ diff -urNp coreutils-8.11-orig/man/runcon.x coreutils-8.11/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.11-orig/src/chcon.c coreutils-8.11/src/chcon.c ---- coreutils-8.11-orig/src/chcon.c 2011-02-19 18:17:03.000000000 +0100 -+++ coreutils-8.11/src/chcon.c 2011-04-14 11:06:05.489434075 +0200 +diff -urNp coreutils-8.13-orig/src/chcon.c coreutils-8.13/src/chcon.c +--- coreutils-8.13-orig/src/chcon.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/chcon.c 2011-09-09 10:30:39.562561252 +0200 @@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), program_name, program_name, program_name); @@ -46,10 +46,10 @@ diff -urNp coreutils-8.11-orig/src/chcon.c coreutils-8.11/src/chcon.c With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ -h, --no-dereference affect symbolic links instead of any referenced file\n\ -diff -urNp coreutils-8.11-orig/src/copy.c coreutils-8.11/src/copy.c ---- coreutils-8.11-orig/src/copy.c 2011-04-12 12:07:43.000000000 +0200 -+++ coreutils-8.11/src/copy.c 2011-04-14 11:06:05.485433752 +0200 -@@ -2179,6 +2179,8 @@ copy_internal (char const *src_name, cha +diff -urNp coreutils-8.13-orig/src/copy.c coreutils-8.13/src/copy.c +--- coreutils-8.13-orig/src/copy.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/copy.c 2011-09-09 10:30:39.564562214 +0200 +@@ -2244,6 +2244,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -58,9 +58,9 @@ diff -urNp coreutils-8.11-orig/src/copy.c coreutils-8.11/src/copy.c } else { -diff -urNp coreutils-8.11-orig/src/copy.h coreutils-8.11/src/copy.h ---- coreutils-8.11-orig/src/copy.h 2011-02-19 18:17:03.000000000 +0100 -+++ coreutils-8.11/src/copy.h 2011-04-14 11:06:05.487340225 +0200 +diff -urNp coreutils-8.13-orig/src/copy.h coreutils-8.13/src/copy.h +--- coreutils-8.13-orig/src/copy.h 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/copy.h 2011-09-09 10:30:39.565563712 +0200 @@ -158,6 +158,9 @@ struct cp_options bool preserve_mode; bool preserve_timestamps; @@ -71,9 +71,9 @@ diff -urNp coreutils-8.11-orig/src/copy.h coreutils-8.11/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urNp coreutils-8.11-orig/src/cp.c coreutils-8.11/src/cp.c ---- coreutils-8.11-orig/src/cp.c 2011-02-19 18:17:03.000000000 +0100 -+++ coreutils-8.11/src/cp.c 2011-04-14 11:06:05.488433894 +0200 +diff -urNp coreutils-8.13-orig/src/cp.c coreutils-8.13/src/cp.c +--- coreutils-8.13-orig/src/cp.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/cp.c 2011-09-09 10:30:39.566562062 +0200 @@ -141,6 +141,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, @@ -162,9 +162,9 @@ diff -urNp coreutils-8.11-orig/src/cp.c coreutils-8.11/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urNp coreutils-8.11-orig/src/id.c coreutils-8.11/src/id.c ---- coreutils-8.11-orig/src/id.c 2011-02-19 18:17:03.000000000 +0100 -+++ coreutils-8.11/src/id.c 2011-04-14 11:06:05.490435340 +0200 +diff -urNp coreutils-8.13-orig/src/id.c coreutils-8.13/src/id.c +--- coreutils-8.13-orig/src/id.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/id.c 2011-09-09 10:30:39.567562153 +0200 @@ -107,7 +107,7 @@ int main (int argc, char **argv) { @@ -174,9 +174,9 @@ diff -urNp coreutils-8.11-orig/src/id.c coreutils-8.11/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urNp coreutils-8.11-orig/src/install.c coreutils-8.11/src/install.c ---- coreutils-8.11-orig/src/install.c 2011-04-12 12:07:43.000000000 +0200 -+++ coreutils-8.11/src/install.c 2011-04-14 11:07:58.333433706 +0200 +diff -urNp coreutils-8.13-orig/src/install.c coreutils-8.13/src/install.c +--- coreutils-8.13-orig/src/install.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/install.c 2011-09-09 10:30:39.569562422 +0200 @@ -261,6 +261,7 @@ cp_option_init (struct cp_options *x) x->data_copy_required = true; x->require_preserve = false; @@ -230,10 +230,10 @@ diff -urNp coreutils-8.11-orig/src/install.c coreutils-8.11/src/install.c use_default_selinux_context = false; break; case_GETOPT_HELP_CHAR; -diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c ---- coreutils-8.11-orig/src/ls.c 2011-04-12 12:07:43.000000000 +0200 -+++ coreutils-8.11/src/ls.c 2011-04-14 11:06:05.498436329 +0200 -@@ -159,7 +159,8 @@ enum filetype +diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c +--- coreutils-8.13-orig/src/ls.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/ls.c 2011-09-09 10:30:39.575562845 +0200 +@@ -166,7 +166,8 @@ enum filetype symbolic_link, sock, whiteout, @@ -243,7 +243,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c }; /* Display letters and indicators for each filetype. -@@ -276,6 +277,7 @@ static void queue_directory (char const +@@ -283,6 +284,7 @@ static void queue_directory (char const static void sort_files (void); static void parse_ls_color (void); void usage (int status); @@ -251,7 +251,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c /* Initial size of hash table. Most hierarchies are likely to be shallower than this. */ -@@ -345,7 +347,7 @@ static struct pending *pending_dirs; +@@ -352,7 +354,7 @@ static struct pending *pending_dirs; static struct timespec current_time; @@ -260,7 +260,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c static char UNKNOWN_SECURITY_CONTEXT[] = "?"; /* Whether any of the files has an ACL. This affects the width of the -@@ -385,7 +387,9 @@ enum format +@@ -392,7 +394,9 @@ enum format one_per_line, /* -1 */ many_per_line, /* -C */ horizontal, /* -x */ @@ -271,7 +271,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c }; static enum format format; -@@ -787,6 +791,9 @@ enum +@@ -794,6 +798,9 @@ enum SHOW_CONTROL_CHARS_OPTION, SI_OPTION, SORT_OPTION, @@ -281,7 +281,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c TIME_OPTION, TIME_STYLE_OPTION }; -@@ -832,7 +839,9 @@ static struct option const long_options[ +@@ -839,7 +846,9 @@ static struct option const long_options[ {"time-style", required_argument, NULL, TIME_STYLE_OPTION}, {"color", optional_argument, NULL, COLOR_OPTION}, {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION}, @@ -292,7 +292,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c {"author", no_argument, NULL, AUTHOR_OPTION}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -@@ -842,12 +851,12 @@ static struct option const long_options[ +@@ -849,12 +858,12 @@ static struct option const long_options[ static char const *const format_args[] = { "verbose", "long", "commas", "horizontal", "across", @@ -307,7 +307,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c }; ARGMATCH_VERIFY (format_args, format_types); -@@ -1289,7 +1298,8 @@ main (int argc, char **argv) +@@ -1296,7 +1305,8 @@ main (int argc, char **argv) /* Avoid following symbolic links when possible. */ if (is_colored (C_ORPHAN) || (is_colored (C_EXEC) && color_symlink_as_referent) @@ -317,7 +317,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c check_symlink_color = true; /* If the standard output is a controlling terminal, watch out -@@ -1336,7 +1346,7 @@ main (int argc, char **argv) +@@ -1343,7 +1353,7 @@ main (int argc, char **argv) if (dereference == DEREF_UNDEFINED) dereference = ((immediate_dirs || indicator_style == classify @@ -326,7 +326,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c ? DEREF_NEVER : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); -@@ -1356,7 +1366,7 @@ main (int argc, char **argv) +@@ -1363,7 +1373,7 @@ main (int argc, char **argv) format_needs_stat = sort_type == sort_time || sort_type == sort_size || format == long_format @@ -335,7 +335,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c || print_block_size; format_needs_type = (! format_needs_stat && (recursive -@@ -1387,7 +1397,7 @@ main (int argc, char **argv) +@@ -1394,7 +1404,7 @@ main (int argc, char **argv) } else do @@ -344,7 +344,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c while (i < argc); if (cwd_n_used) -@@ -1558,7 +1568,7 @@ decode_switches (int argc, char **argv) +@@ -1565,7 +1575,7 @@ decode_switches (int argc, char **argv) ignore_mode = IGNORE_DEFAULT; ignore_patterns = NULL; hide_patterns = NULL; @@ -353,7 +353,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c /* FIXME: put this in a function. */ { -@@ -1940,13 +1950,27 @@ decode_switches (int argc, char **argv) +@@ -1947,13 +1957,27 @@ decode_switches (int argc, char **argv) break; case 'Z': @@ -382,7 +382,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c default: usage (LS_FAILURE); } -@@ -2691,8 +2715,10 @@ clear_files (void) +@@ -2714,8 +2738,10 @@ clear_files (void) struct fileinfo *f = sorted_file[i]; free (f->name); free (f->linkname); @@ -395,7 +395,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c } cwd_n_used = 0; -@@ -2734,6 +2760,7 @@ gobble_file (char const *name, enum file +@@ -2757,6 +2783,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -403,7 +403,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c if (command_line_arg || format_needs_stat -@@ -2843,7 +2870,7 @@ gobble_file (char const *name, enum file +@@ -2869,7 +2896,7 @@ gobble_file (char const *name, enum file && print_with_color && is_colored (C_CAP)) f->has_capability = has_capability (absolute_name); @@ -412,7 +412,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c { bool have_selinux = false; bool have_acl = false; -@@ -2866,7 +2893,7 @@ gobble_file (char const *name, enum file +@@ -2892,7 +2919,7 @@ gobble_file (char const *name, enum file err = 0; } @@ -421,7 +421,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c { int n = file_has_acl (absolute_name, &f->stat); err = (n < 0); -@@ -2885,7 +2912,8 @@ gobble_file (char const *name, enum file +@@ -2911,7 +2938,8 @@ gobble_file (char const *name, enum file } if (S_ISLNK (f->stat.st_mode) @@ -431,7 +431,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c { char *linkname; struct stat linkstats; -@@ -2905,6 +2933,7 @@ gobble_file (char const *name, enum file +@@ -2931,6 +2959,7 @@ gobble_file (char const *name, enum file command line are automatically traced if not being listed as files. */ if (!command_line_arg || format == long_format @@ -439,7 +439,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c || !S_ISDIR (linkstats.st_mode)) { /* Get the linked-to file's mode for the filetype indicator -@@ -2944,7 +2973,7 @@ gobble_file (char const *name, enum file +@@ -2970,7 +2999,7 @@ gobble_file (char const *name, enum file block_size_width = len; } @@ -448,7 +448,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c { if (print_owner) { -@@ -3445,6 +3474,13 @@ print_current_files (void) +@@ -3471,6 +3500,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -462,7 +462,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c break; } } -@@ -3607,6 +3643,67 @@ format_inode (char *buf, size_t buflen, +@@ -3633,6 +3669,67 @@ format_inode (char *buf, size_t buflen, : (char *) "?"); } @@ -530,7 +530,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c /* Print information about F in long format. */ static void print_long_format (const struct fileinfo *f) -@@ -3698,9 +3795,15 @@ print_long_format (const struct fileinfo +@@ -3724,9 +3821,15 @@ print_long_format (const struct fileinfo The latter is wrong when nlink_width is zero. */ p += strlen (p); @@ -547,7 +547,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c { DIRED_FPUTS (buf, stdout, p - buf); -@@ -3713,9 +3816,6 @@ print_long_format (const struct fileinfo +@@ -3739,9 +3842,6 @@ print_long_format (const struct fileinfo if (print_author) format_user (f->stat.st_author, author_width, f->stat_ok); @@ -557,7 +557,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c p = buf; } -@@ -4060,9 +4160,6 @@ print_file_name_and_frills (const struct +@@ -4086,9 +4186,6 @@ print_file_name_and_frills (const struct : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ST_NBLOCKSIZE, output_block_size)); @@ -567,7 +567,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c size_t width = print_name_with_quoting (f, false, NULL, start_col); if (indicator_style != none) -@@ -4266,9 +4363,6 @@ length_of_file_name_and_frills (const st +@@ -4292,9 +4389,6 @@ length_of_file_name_and_frills (const st output_block_size)) : block_size_width); @@ -577,7 +577,7 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c quote_name (NULL, f->name, filename_quoting_options, &name_width); len += name_width; -@@ -4707,9 +4801,16 @@ Mandatory arguments to long options are +@@ -4733,9 +4827,16 @@ Mandatory arguments to long options are -w, --width=COLS assume screen width instead of current value\n\ -x list entries by lines instead of by columns\n\ -X sort alphabetically by entry extension\n\ @@ -595,9 +595,9 @@ diff -urNp coreutils-8.11-orig/src/ls.c coreutils-8.11/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-8.11-orig/src/mkdir.c coreutils-8.11/src/mkdir.c ---- coreutils-8.11-orig/src/mkdir.c 2011-02-19 18:17:03.000000000 +0100 -+++ coreutils-8.11/src/mkdir.c 2011-04-14 11:06:05.499460276 +0200 +diff -urNp coreutils-8.13-orig/src/mkdir.c coreutils-8.13/src/mkdir.c +--- coreutils-8.13-orig/src/mkdir.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/mkdir.c 2011-09-09 10:30:39.576564256 +0200 @@ -38,6 +38,7 @@ static struct option const longopts[] = { @@ -606,9 +606,9 @@ diff -urNp coreutils-8.11-orig/src/mkdir.c coreutils-8.11/src/mkdir.c {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, -diff -urNp coreutils-8.11-orig/src/mknod.c coreutils-8.11/src/mknod.c ---- coreutils-8.11-orig/src/mknod.c 2011-02-19 18:17:03.000000000 +0100 -+++ coreutils-8.11/src/mknod.c 2011-04-14 11:06:05.500309648 +0200 +diff -urNp coreutils-8.13-orig/src/mknod.c coreutils-8.13/src/mknod.c +--- coreutils-8.13-orig/src/mknod.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/mknod.c 2011-09-09 10:30:39.577563177 +0200 @@ -35,7 +35,7 @@ static struct option const longopts[] = @@ -618,9 +618,9 @@ diff -urNp coreutils-8.11-orig/src/mknod.c coreutils-8.11/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urNp coreutils-8.11-orig/src/mv.c coreutils-8.11/src/mv.c ---- coreutils-8.11-orig/src/mv.c 2011-02-19 18:17:03.000000000 +0100 -+++ coreutils-8.11/src/mv.c 2011-04-14 11:06:05.501309664 +0200 +diff -urNp coreutils-8.13-orig/src/mv.c coreutils-8.13/src/mv.c +--- coreutils-8.13-orig/src/mv.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/mv.c 2011-09-09 10:30:39.578562234 +0200 @@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x) x->preserve_mode = true; x->preserve_timestamps = true; @@ -629,9 +629,9 @@ diff -urNp coreutils-8.11-orig/src/mv.c coreutils-8.11/src/mv.c x->reduce_diagnostics = false; x->data_copy_required = true; x->require_preserve = false; /* FIXME: maybe make this an option */ -diff -urNp coreutils-8.11-orig/src/runcon.c coreutils-8.11/src/runcon.c ---- coreutils-8.11-orig/src/runcon.c 2011-02-19 18:17:03.000000000 +0100 -+++ coreutils-8.11/src/runcon.c 2011-04-14 11:06:05.502310854 +0200 +diff -urNp coreutils-8.13-orig/src/runcon.c coreutils-8.13/src/runcon.c +--- coreutils-8.13-orig/src/runcon.c 2011-07-28 12:38:27.000000000 +0200 ++++ coreutils-8.13/src/runcon.c 2011-09-09 10:30:39.579564283 +0200 @@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ "), program_name, program_name); @@ -641,10 +641,10 @@ diff -urNp coreutils-8.11-orig/src/runcon.c coreutils-8.11/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urNp coreutils-8.11-orig/tests/init.cfg coreutils-8.11/tests/init.cfg ---- coreutils-8.11-orig/tests/init.cfg 2011-04-12 12:07:43.000000000 +0200 -+++ coreutils-8.11/tests/init.cfg 2011-04-14 11:06:05.503308646 +0200 -@@ -231,8 +231,8 @@ require_selinux_() +diff -urNp coreutils-8.13-orig/tests/init.cfg coreutils-8.13/tests/init.cfg +--- coreutils-8.13-orig/tests/init.cfg 2011-09-07 18:00:55.000000000 +0200 ++++ coreutils-8.13/tests/init.cfg 2011-09-09 10:32:17.031688699 +0200 +@@ -253,8 +253,8 @@ require_selinux_() # Independent of whether SELinux is enabled system-wide, # the current file system may lack SELinux support. @@ -652,12 +652,12 @@ diff -urNp coreutils-8.11-orig/tests/init.cfg coreutils-8.11/tests/init.cfg - '? .'|'unlabeled .') + case `ls -Zd . | cut -f4 -d" "` in + '?'|'unlabeled') - skip_test_ "this system (or maybe just" \ + skip_ "this system (or maybe just" \ "the current file system) lacks SELinux support" ;; -diff -urNp coreutils-8.11-orig/tests/misc/selinux coreutils-8.11/tests/misc/selinux ---- coreutils-8.11-orig/tests/misc/selinux 2011-01-31 13:40:38.000000000 +0100 -+++ coreutils-8.11/tests/misc/selinux 2011-04-14 11:06:05.504353757 +0200 +diff -urNp coreutils-8.13-orig/tests/misc/selinux coreutils-8.13/tests/misc/selinux +--- coreutils-8.13-orig/tests/misc/selinux 2011-08-08 09:42:16.000000000 +0200 ++++ coreutils-8.13/tests/misc/selinux 2011-09-09 10:30:39.586563144 +0200 @@ -37,7 +37,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. diff --git a/coreutils.spec b/coreutils.spec index 3d5c6a1..9fc1d6a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.12 -Release: 6%{?dist} +Version: 8.13 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -32,8 +32,6 @@ Patch103: coreutils-8.2-uname-processortype.patch Patch104: coreutils-df-direct.patch #add note about mkdir --mode behaviour into info documentation(#610559) Patch107: coreutils-8.4-mkdir-modenote.patch -#use acl_extended_file_nofollow if available (#692823) -Patch108: coreutils-acl-extended-file-nofollow.patch # sh-utils #add info about TZ envvar to date manpage @@ -87,7 +85,6 @@ Requires(post): grep %{?!nopam:Requires: pam } Requires: ncurses Requires: gmp -Requires: %{name}-libs = %{version}-%{release} Provides: fileutils = %{version}-%{release} Provides: sh-utils = %{version}-%{release} @@ -105,14 +102,6 @@ Obsoletes: textutils <= 2.0.21 These are the GNU core utilities. This package is the combination of the old GNU fileutils, sh-utils, and textutils packages. -%package libs -Summary: Libraries for %{name} -Group: System Environment/Libraries -Requires: %{name} = %{version}-%{release} - -%description libs -Libraries for coreutils package. - %prep %setup -q @@ -125,7 +114,6 @@ Libraries for coreutils package. %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect %patch107 -p1 -b .mkdirmode -%patch108 -p1 -b .nofollow # sh-utils %patch703 -p1 -b .dateman @@ -199,11 +187,11 @@ fi bzip2 -9f ChangeLog # let be compatible with old fileutils, sh-utils and textutils packages : -mkdir -p $RPM_BUILD_ROOT{/bin,%_bindir,%_sbindir,/sbin} -%{?!nopam:mkdir -p $RPM_BUILD_ROOT%_sysconfdir/pam.d} +mkdir -p $RPM_BUILD_ROOT{/bin,%{_bindir},%{_sbindir},/sbin} +%{?!nopam:mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pam.d} for f in arch basename cat chgrp chmod chown cp cut date dd df echo env false link ln ls mkdir mknod mktemp mv nice pwd readlink rm rmdir sleep sort stty sync touch true uname unlink do - mv $RPM_BUILD_ROOT{%_bindir,/bin}/$f + mv $RPM_BUILD_ROOT{%{_bindir},/bin}/$f done # chroot was in /usr/sbin : @@ -226,13 +214,13 @@ rm -rf $RPM_BUILD_ROOT/usr/bin/runuser || : # These come from util-linux and/or procps. for i in hostname uptime kill ; do - rm $RPM_BUILD_ROOT{%_bindir/$i,%_mandir/man1/$i.1} + rm $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1} done -%{?!nopam:install -p -m 644 %SOURCE200 $RPM_BUILD_ROOT%_sysconfdir/pam.d/su} -%{?!nopam:install -p -m 644 %SOURCE202 $RPM_BUILD_ROOT%_sysconfdir/pam.d/su-l} -%{?!nopam:install -p -m 644 %SOURCE201 $RPM_BUILD_ROOT%_sysconfdir/pam.d/runuser} -%{?!nopam:install -p -m 644 %SOURCE203 $RPM_BUILD_ROOT%_sysconfdir/pam.d/runuser-l} +%{?!nopam:install -p -m 644 %SOURCE200 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su} +%{?!nopam:install -p -m 644 %SOURCE202 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su-l} +%{?!nopam:install -p -m 644 %SOURCE201 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser} +%{?!nopam:install -p -m 644 %SOURCE203 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser-l} # Compress ChangeLogs from before the fileutils/textutils/etc merge bzip2 -f9 old/*/C* @@ -324,17 +312,20 @@ fi /bin/true /bin/uname /bin/unlink -%_bindir/* -%_infodir/coreutils* -%_mandir/man*/* -%_sbindir/chroot +%{_bindir}/* +%{_infodir}/coreutils* +%{_libexecdir}/coreutils* +%{_mandir}/man*/* +%{_sbindir}/chroot %{?!norunuser:/sbin/runuser} -%files libs -%defattr(-, root, root, -) -%{_libdir}/coreutils - %changelog +* Fri Sep 09 2011 Ondrej Vasik - 8.13-1 +- new upstream release 8.13 +- temporarily disable recently added multibyte checks in + misc/cut test +- drop coreutils-libs subpackage, no longer needed + * Tue Aug 23 2011 Ondrej Vasik - 8.12-6 - su: fix shell suspend in tcsh (#597928) diff --git a/sources b/sources index 6a12672..0c0c179 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -0f7d43c2d2e24314b43a6c6267e25b90 coreutils-8.12.tar.xz +8e1675c6c336ff55557c698706a63d6c coreutils-8.13.tar.xz From cb9359bd04e3a91309ac3768a2ebf540a7043e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 12 Sep 2011 10:42:33 +0200 Subject: [PATCH 141/523] Obsolete coreutils-libs (#737287) --- coreutils.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 5558b2e..995c8d2 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.13 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -97,6 +97,8 @@ Obsoletes: fileutils <= 4.1.9 Obsoletes: sh-utils <= 2.0.12 Obsoletes: stat <= 3.3 Obsoletes: textutils <= 2.0.21 +#coreutils-libs dropped in f17 +Obsoletes: coreutils-libs < 8.13 %description These are the GNU core utilities. This package is the combination of @@ -320,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Mon Sep 12 2011 Ondrej Vasik - 8.13-2 +- Obsolete coreutils-libs (#737287) + * Fri Sep 09 2011 Ondrej Vasik - 8.13-1 - new upstream release 8.13 - temporarily disable recently added multibyte checks in From a8f8a59fc2c7ffed80f9df982aad568733d43e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcela=20Ma=C5=A1l=C3=A1=C5=88ov=C3=A1?= Date: Mon, 26 Sep 2011 14:36:57 +0200 Subject: [PATCH 142/523] rebuild with new gmp --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 995c8d2..ba2ee4d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.13 -Release: 2%{?dist} +Release: 2%{?dist}.1 License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -322,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Mon Sep 26 2011 Peter Schiffer - 8.13-2.1 +- rebuild with new gmp + * Mon Sep 12 2011 Ondrej Vasik - 8.13-2 - Obsolete coreutils-libs (#737287) From c9499bdd253ea6b00777dce68bbb6d8304764838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcela=20Ma=C5=A1l=C3=A1=C5=88ov=C3=A1?= Date: Mon, 10 Oct 2011 11:04:41 +0200 Subject: [PATCH 143/523] Bump release and try build with new gmp again. --- coreutils.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index ba2ee4d..f66dbd6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.13 -Release: 2%{?dist}.1 +Release: 2%{?dist}.2 License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -322,7 +322,7 @@ fi %{?!norunuser:/sbin/runuser} %changelog -* Mon Sep 26 2011 Peter Schiffer - 8.13-2.1 +* Mon Sep 26 2011 Peter Schiffer - 8.13-2.2 - rebuild with new gmp * Mon Sep 12 2011 Ondrej Vasik - 8.13-2 From 59d9061232e1873b0e24fa55542ecefc7e89f861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 12 Oct 2011 16:13:12 +0200 Subject: [PATCH 144/523] new upstream release 8.14 --- .gitignore | 1 + coreutils-6.10-configuration.patch | 4 +++- coreutils-getgrouplist.patch | 16 ++++++++-------- coreutils-i18n.patch | 6 +++--- coreutils.spec | 7 +++++-- sources | 2 +- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index c560e51..188c76f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /coreutils-8.11.tar.xz /coreutils-8.12.tar.xz /coreutils-8.13.tar.xz +/coreutils-8.14.tar.xz diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 8dd43f8..c314db9 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -27,15 +27,17 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module dup2-tests -@@ -373,9 +373,9 @@ EXTRA_DIST += test-fadvise.c +@@ -373,10 +373,10 @@ EXTRA_DIST += test-fadvise.c ## begin gnulib module fchdir-tests -TESTS += test-fchdir -check_PROGRAMS += test-fchdir +-test_fchdir_LDADD = $(LDADD) $(LIBINTL) -EXTRA_DIST += test-fchdir.c signature.h macros.h +#TESTS += test-fchdir +#check_PROGRAMS += test-fchdir ++#test_fchdir_LDADD = $(LDADD) $(LIBINTL) +#EXTRA_DIST += test-fchdir.c signature.h macros.h ## end gnulib module fchdir-tests diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch index 0c8eb41..86bbcef 100644 --- a/coreutils-getgrouplist.patch +++ b/coreutils-getgrouplist.patch @@ -76,11 +76,11 @@ diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 index 62777c7..5180243 100644 --- a/m4/jm-macros.m4 +++ b/m4/jm-macros.m4 -@@ -78,6 +78,7 @@ AC_DEFUN([coreutils_MACROS], - fchown \ - fchmod \ - ftruncate \ -+ getgrouplist \ - iswspace \ - mkfifo \ - mbrlen \ +@@ -78,6 +78,7 @@ + fchown + fchmod + ftruncate ++ getgrouplist + iswspace + mkfifo + mbrlen diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 9ba6bb4..96eec34 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2970,9 +2970,9 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c +} +#endif /* HAV_EMBRTOWC */ + - static int - general_numcompare (char const *sa, char const *sb) - { + /* 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 once @@ -1942,7 +2305,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ diff --git a/coreutils.spec b/coreutils.spec index f66dbd6..e70fe55 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.13 -Release: 2%{?dist}.2 +Version: 8.14 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -322,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Wed Oct 12 2011 Ondrej Vasik - 8.14-1 +- new upstream release 8.14 + * Mon Sep 26 2011 Peter Schiffer - 8.13-2.2 - rebuild with new gmp diff --git a/sources b/sources index 0c0c179..2f04ed2 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -8e1675c6c336ff55557c698706a63d6c coreutils-8.13.tar.xz +bcb135ce553493a45aba01b39eb3920a coreutils-8.14.tar.xz From cdb1602dfeb3f64622193f2f8be70757d37b0442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 12 Oct 2011 16:47:21 +0200 Subject: [PATCH 145/523] workaround the build failure in koji for now --- coreutils-6.10-configuration.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index c314db9..2fd3498 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -57,6 +57,19 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module linkat-tests +@@ -1284,9 +1284,9 @@ EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h + +## begin gnulib module memrchr-tests + +-TESTS += test-memrchr +-check_PROGRAMS += test-memrchr +-EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h ++#TESTS += test-memrchr ++#check_PROGRAMS += test-memrchr ++#EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h + +## end gnulib module memrchr-tests + @@ -1891,9 +1891,9 @@ EXTRA_DIST += test-uname.c signature.h m ## begin gnulib module unistd-safer-tests From 240f408e81c525dfaf1fdf0261c3381aa26da740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 12 Oct 2011 16:48:12 +0200 Subject: [PATCH 146/523] oops --- coreutils-6.10-configuration.patch | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 2fd3498..99f3a17 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -58,18 +58,18 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module linkat-tests @@ -1284,9 +1284,9 @@ EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h - -## begin gnulib module memrchr-tests - + + ## begin gnulib module memrchr-tests + -TESTS += test-memrchr -check_PROGRAMS += test-memrchr -EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h +#TESTS += test-memrchr +#check_PROGRAMS += test-memrchr +#EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h - -## end gnulib module memrchr-tests - + + ## end gnulib module memrchr-tests + @@ -1891,9 +1891,9 @@ EXTRA_DIST += test-uname.c signature.h m ## begin gnulib module unistd-safer-tests From f6278cea7c9d914195918aea29d0d40eae714450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 20 Oct 2011 14:01:28 +0200 Subject: [PATCH 147/523] rebuild for gmp --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index e70fe55..e36a129 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.14 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -322,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Thu Oct 20 2011 Ondrej Vasik - 8.14-2 +- rebuild for gmp + * Wed Oct 12 2011 Ondrej Vasik - 8.14-1 - new upstream release 8.14 From f531c8b978cdc64cbb01a17c7f20dc3e851789c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 24 Oct 2011 16:00:37 +0200 Subject: [PATCH 148/523] require at least pam 1.1.3-7 (#748215) --- coreutils.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index e36a129..7f3d56d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.14 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -82,7 +82,7 @@ Requires(pre): /sbin/install-info Requires(preun): /sbin/install-info Requires(post): /sbin/install-info Requires(post): grep -%{?!nopam:Requires: pam } +%{?!nopam:Requires: pam >= 1.1.3-7} Requires: ncurses Requires: gmp @@ -322,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Mon Oct 24 2011 Ondrej Vasik - 8.14-3 +- require at least pam 1.1.3-7 (#748215) + * Thu Oct 20 2011 Ondrej Vasik - 8.14-2 - rebuild for gmp From 3c275d96b31f881c129c16312181f615a95ed10f Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Mon, 31 Oct 2011 11:03:56 -0500 Subject: [PATCH 149/523] rebuild (gmp), last time, I promise --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 7f3d56d..f04fd9a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.14 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -322,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Mon Oct 31 2011 Rex Dieter 8.14-4 +- rebuild (gmp), last time, I promise + * Mon Oct 24 2011 Ondrej Vasik - 8.14-3 - require at least pam 1.1.3-7 (#748215) From 586a3174f1b4919626c03518759375f9c4f4ba71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 5 Jan 2012 15:34:33 +0100 Subject: [PATCH 150/523] fix pr -c and pr -v segfault with multibyte locales --- coreutils-i18n.patch | 7 ++++--- coreutils.spec | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 96eec34..4de494f 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2271,7 +2271,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2741,6 +2942,154 @@ char_to_clump (char c) +@@ -2741,6 +2942,155 @@ char_to_clump (char c) return chars; } @@ -2279,6 +2279,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c +static int +char_to_clump_multi (char c) +{ ++ unsigned char uc = c; + static size_t mbc_pos = 0; + static char mbc[MB_LEN_MAX] = {'\0'}; + static mbstate_t state = {'\0'}; @@ -2365,7 +2366,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c + width += 4; + chars += 4; + *s++ = '\\'; -+ sprintf (esc_buff, "%03o", c); ++ sprintf (esc_buff, "%03o", uc); + for (j = 0; j <= 2; ++j) + *s++ = (int) esc_buff[j]; + } @@ -2386,7 +2387,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c + width += 4; + chars += 4; + *s++ = '\\'; -+ sprintf (esc_buff, "%03o", c); ++ sprintf (esc_buff, "%03o", uc); + for (j = 0; j <= 2; ++j) + *s++ = (int) esc_buff[j]; + } diff --git a/coreutils.spec b/coreutils.spec index 7f3d56d..5a93cd0 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.14 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -322,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Thu Jan 05 2011 Ondrej Vasik - 8.14-4 +- fix pr -c and pr -v segfault with multibyte locales + * Mon Oct 24 2011 Ondrej Vasik - 8.14-3 - require at least pam 1.1.3-7 (#748215) From d910089c7dbf6cd1491c31aadda415f312931da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 5 Jan 2012 15:38:45 +0100 Subject: [PATCH 151/523] Damned year changes :) --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index a9451ec..c63c6ab 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -322,7 +322,7 @@ fi %{?!norunuser:/sbin/runuser} %changelog -* Thu Jan 05 2011 Ondrej Vasik - 8.14-5 +* Thu Jan 05 2012 Ondrej Vasik - 8.14-5 - fix pr -c and pr -v segfault with multibyte locales * Mon Oct 31 2011 Rex Dieter 8.14-4 From 377a7b80824065be3b0b398bda0c8941a0cb9427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 5 Jan 2012 21:51:20 +0100 Subject: [PATCH 152/523] do not use shebang in sourced colorls.csh profile.d script --- coreutils-colorls.csh | 1 - coreutils.spec | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 7e3d794..48daa78 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -1,4 +1,3 @@ -#! /bin/csh -f # color-ls initialization if ( $?USER_LS_COLORS ) then if ( "$USER_LS_COLORS" != "" ) then diff --git a/coreutils.spec b/coreutils.spec index c63c6ab..9a076cb 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.14 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -322,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Thu Jan 05 2012 Ondrej Vasik - 8.14-6 +- do not use shebang in sourced colorls.csh + * Thu Jan 05 2012 Ondrej Vasik - 8.14-5 - fix pr -c and pr -v segfault with multibyte locales From 7f6231bff1e5cfcad550c3e36d59ec8af3d2b418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 7 Jan 2012 20:47:10 +0100 Subject: [PATCH 153/523] new upstream release 8.15, patches updated --- .gitignore | 1 + coreutils-8.7-runuser.patch | 20 ++++++++------------ coreutils-df-direct.patch | 2 +- coreutils-i18n.patch | 4 ++-- coreutils-selinux.patch | 19 +++---------------- coreutils.spec | 7 +++++-- sources | 2 +- 7 files changed, 21 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 188c76f..b8a1c39 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /coreutils-8.12.tar.xz /coreutils-8.13.tar.xz /coreutils-8.14.tar.xz +/coreutils-8.15.tar.xz diff --git a/coreutils-8.7-runuser.patch b/coreutils-8.7-runuser.patch index 93cd962..c68da7c 100644 --- a/coreutils-8.7-runuser.patch +++ b/coreutils-8.7-runuser.patch @@ -52,20 +52,16 @@ diff -urNp coreutils-8.7-orig/man/runuser.x coreutils-8.7/man/runuser.x diff -urNp coreutils-8.7-orig/README coreutils-8.7/README --- coreutils-8.7-orig/README 2010-10-11 19:35:11.000000000 +0200 +++ coreutils-8.7/README 2010-11-15 10:10:43.002922253 +0100 -@@ -12,10 +12,10 @@ The programs that can be built with this +@@ -11,8 +11,8 @@ The programs that can be built with this factor false fmt fold groups head hostid hostname id install join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup - nproc od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir -- runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf -- sleep sort split stat stdbuf stty su sum sync tac tail tee test timeout -- touch tr true truncate tsort tty uname unexpand uniq unlink uptime users -- vdir wc who whoami yes -+ runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum shred -+ shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test -+ timeout touch tr true truncate tsort tty uname unexpand uniq unlink uptime -+ users vdir wc who whoami yes - - See the file NEWS for a list of major changes in the current release. + nproc 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 su sum sync tac tail tee test ++ rm rmdir runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum ++ shred shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test + timeout touch tr true truncate tsort tty uname unexpand uniq unlink + uptime users vdir wc who whoami yes diff -urNp coreutils-8.7-orig/src/Makefile.am coreutils-8.7/src/Makefile.am --- coreutils-8.7-orig/src/Makefile.am 2010-11-15 10:07:07.339171659 +0100 diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 2139809..1bc8c40 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -67,7 +67,7 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c + char *resolved = canonicalize_file_name (name); + if (resolved) + { -+ get_dev (NULL, resolved, NULL, NULL, false, false, NULL); ++ get_dev (NULL, resolved, NULL, NULL, false, false, NULL, false); + free (resolved); + return; + } diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 4de494f..e2f9f21 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -10,7 +10,7 @@ diff -urNp coreutils-8.13-orig/lib/linebuffer.h coreutils-8.13/lib/linebuffer.h +# include +# endif + - /* A `struct linebuffer' holds a line of text. */ + /* A 'struct linebuffer' holds a line of text. */ struct linebuffer @@ -28,6 +33,9 @@ struct linebuffer @@ -1784,8 +1784,8 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c static void getoptarg (char *arg, char switch_char, char *character, + int *character_length, int *character_width, int *number); - void usage (int status); static void print_files (int number_of_files, char **av); + static void init_parameters (int number_of_files); @@ -439,7 +491,6 @@ static void store_char (char c); static void pad_down (int lines); static void read_rest_of_line (COLUMN *p); diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 7ebce30..3e5c143 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -45,7 +45,7 @@ diff -urNp coreutils-8.13-orig/src/chcon.c coreutils-8.13/src/chcon.c +Change the SELinux security context of each FILE to CONTEXT.\n\ With --reference, change the security context of each FILE to that of RFILE.\n\ \n\ - -h, --no-dereference affect symbolic links instead of any referenced file\n\ + "), stdout); diff -urNp coreutils-8.13-orig/src/copy.c coreutils-8.13/src/copy.c --- coreutils-8.13-orig/src/copy.c 2011-07-28 12:38:27.000000000 +0200 +++ coreutils-8.13/src/copy.c 2011-09-09 10:30:39.564562214 +0200 @@ -243,10 +243,10 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c }; /* Display letters and indicators for each filetype. -@@ -283,6 +284,7 @@ static void queue_directory (char const +@@ -282,6 +283,7 @@ + bool command_line_arg); static void sort_files (void); static void parse_ls_color (void); - void usage (int status); +static void print_scontext_format (const struct fileinfo *f); /* Initial size of hash table. @@ -382,19 +382,6 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c default: usage (LS_FAILURE); } -@@ -2714,8 +2738,10 @@ clear_files (void) - struct fileinfo *f = sorted_file[i]; - free (f->name); - free (f->linkname); -- if (f->scontext != UNKNOWN_SECURITY_CONTEXT) -- freecon (f->scontext); -+ if (f->scontext != UNKNOWN_SECURITY_CONTEXT) { -+ freecon (f->scontext); -+ f->scontext = NULL; -+ } - } - - cwd_n_used = 0; @@ -2757,6 +2783,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; diff --git a/coreutils.spec b/coreutils.spec index 9a076cb..1b060af 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.14 -Release: 6%{?dist} +Version: 8.15 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -322,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Sat Jan 08 2012 Ondrej Vasik - 8.15-1 +- new upstream release 8.15 + * Thu Jan 05 2012 Ondrej Vasik - 8.14-6 - do not use shebang in sourced colorls.csh diff --git a/sources b/sources index 2f04ed2..db9edbd 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -bcb135ce553493a45aba01b39eb3920a coreutils-8.14.tar.xz +094909fafa86110140b32e4948941545 coreutils-8.15.tar.xz From 29106aca87be5154ad1896e89154ed54b159e837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 7 Jan 2012 21:00:53 +0100 Subject: [PATCH 154/523] disable gnulib test stdalign - failing in koji --- coreutils-6.10-configuration.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 99f3a17..1e3be91 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -70,6 +70,19 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module memrchr-tests +@@ -1824,9 +1824,9 @@ + + ## begin gnulib module stdalign-tests + +-TESTS += test-stdalign +-check_PROGRAMS += test-stdalign +-EXTRA_DIST += test-stdalign.c macros.h ++#TESTS += test-stdalign ++#check_PROGRAMS += test-stdalign ++#EXTRA_DIST += test-stdalign.c macros.h + + ## end gnulib module stdalign-tests + @@ -1891,9 +1891,9 @@ EXTRA_DIST += test-uname.c signature.h m ## begin gnulib module unistd-safer-tests From 33b6b75afa2fdaabbf7af89de1ed7b77a8df5679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 7 Jan 2012 23:11:59 +0100 Subject: [PATCH 155/523] fix date in changelog --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 1b060af..e7dec7a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -322,7 +322,7 @@ fi %{?!norunuser:/sbin/runuser} %changelog -* Sat Jan 08 2012 Ondrej Vasik - 8.15-1 +* Sat Jan 07 2012 Ondrej Vasik - 8.15-1 - new upstream release 8.15 * Thu Jan 05 2012 Ondrej Vasik - 8.14-6 From ad3d42ec4fb8bae5af44e238473e4b2a3a3ad7ca Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 16 Jan 2012 15:38:16 +0100 Subject: [PATCH 156/523] fix stack smashing, buffer overflow and invalid output of pr (#772172) --- coreutils-i18n.patch | 94 +++++++++++++++++++++++++++----------------- coreutils.spec | 5 ++- 2 files changed, 61 insertions(+), 38 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e2f9f21..ec79964 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1786,7 +1786,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c int *number); static void print_files (int number_of_files, char **av); static void init_parameters (int number_of_files); -@@ -439,7 +491,6 @@ static void store_char (char c); +@@ -438,7 +490,6 @@ static void store_char (char c); static void pad_down (int lines); static void read_rest_of_line (COLUMN *p); static void skip_read (COLUMN *p, int column_number); @@ -1794,7 +1794,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c static void cleanup (void); static void print_sep_string (void); static void separator_string (const char *optarg_S); -@@ -451,7 +502,7 @@ static COLUMN *column_vector; +@@ -450,7 +501,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]. */ @@ -1803,7 +1803,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* Index of the position in buff where the next character will be stored. */ -@@ -555,7 +606,7 @@ static int chars_per_column; +@@ -554,7 +605,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -1812,7 +1812,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... where the leftmost column is 1. */ -@@ -565,7 +616,10 @@ static int chars_per_input_tab = 8; +@@ -564,7 +615,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -1824,7 +1824,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -639,7 +693,13 @@ static int power_10; +@@ -638,7 +692,13 @@ static int power_10; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1839,7 +1839,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -692,6 +752,7 @@ static bool use_col_separator = false; +@@ -691,6 +751,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ static char *col_sep_string = (char *) ""; static int col_sep_length = 0; @@ -1847,7 +1847,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -848,6 +909,13 @@ separator_string (const char *optarg_S) +@@ -847,6 +908,13 @@ separator_string (const char *optarg_S) col_sep_length = (int) strlen (optarg_S); col_sep_string = xmalloc (col_sep_length + 1); strcpy (col_sep_string, optarg_S); @@ -1861,7 +1861,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c } int -@@ -872,6 +940,21 @@ main (int argc, char **argv) +@@ -871,6 +939,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1883,7 +1883,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c n_files = 0; file_names = (argc > 1 ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -948,8 +1031,12 @@ main (int argc, char **argv) +@@ -947,8 +1030,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1898,7 +1898,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -962,8 +1049,12 @@ main (int argc, char **argv) +@@ -961,8 +1048,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1913,7 +1913,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -990,8 +1081,8 @@ main (int argc, char **argv) +@@ -989,8 +1080,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1924,7 +1924,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c break; case 'N': skip_count = false; -@@ -1030,7 +1121,7 @@ main (int argc, char **argv) +@@ -1029,7 +1120,7 @@ main (int argc, char **argv) old_s = false; /* Reset an additional input of -s, -S dominates -s */ col_sep_string = bad_cast (""); @@ -1933,7 +1933,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1187,10 +1278,45 @@ main (int argc, char **argv) +@@ -1186,10 +1277,45 @@ main (int argc, char **argv) a number. */ static void @@ -1981,7 +1981,19 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c if (*arg) { long int tmp_long; -@@ -1249,7 +1375,7 @@ init_parameters (int number_of_files) +@@ -1211,6 +1337,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) +@@ -1248,7 +1379,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -1990,7 +2002,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1280,11 +1406,11 @@ init_parameters (int number_of_files) +@@ -1279,11 +1410,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. */ @@ -2004,7 +2016,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1299,7 +1425,7 @@ init_parameters (int number_of_files) +@@ -1298,7 +1429,7 @@ init_parameters (int number_of_files) } chars_per_column = (chars_per_line - chars_used_by_number - @@ -2013,7 +2025,16 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c if (chars_per_column < 1) error (EXIT_FAILURE, 0, _("page width too narrow")); -@@ -1424,7 +1550,7 @@ init_funcs (void) +@@ -1315,7 +1446,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, +@@ -1423,7 +1554,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2022,7 +2043,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* This loop takes care of all but the rightmost column. */ -@@ -1458,7 +1584,7 @@ init_funcs (void) +@@ -1457,7 +1588,7 @@ init_funcs (void) } else { @@ -2031,7 +2052,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c h_next = h + chars_per_column; } } -@@ -1749,9 +1875,9 @@ static void +@@ -1748,9 +1879,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2043,7 +2064,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2022,13 +2148,13 @@ store_char (char c) +@@ -2021,13 +2152,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2059,7 +2080,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c char *s; int left_cut; -@@ -2051,22 +2177,24 @@ add_line_number (COLUMN *p) +@@ -2050,22 +2181,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. */ @@ -2088,7 +2109,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2227,7 +2355,7 @@ print_white_space (void) +@@ -2226,7 +2359,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2097,7 +2118,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c h_old = h_new; } while (++h_old <= goal) -@@ -2247,6 +2375,7 @@ print_sep_string (void) +@@ -2246,6 +2379,7 @@ print_sep_string (void) { char *s; int l = col_sep_length; @@ -2105,7 +2126,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c s = col_sep_string; -@@ -2260,6 +2389,7 @@ print_sep_string (void) +@@ -2259,6 +2393,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2113,7 +2134,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2273,12 +2403,15 @@ print_sep_string (void) +@@ -2272,12 +2407,15 @@ print_sep_string (void) } else { @@ -2130,7 +2151,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2306,7 +2439,7 @@ print_clump (COLUMN *p, int n, char *clu +@@ -2305,7 +2443,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -2139,7 +2160,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c { if (tabify_output) { -@@ -2330,6 +2463,74 @@ print_char (char c) +@@ -2329,6 +2467,74 @@ print_char (char c) putchar (c); } @@ -2214,7 +2235,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2509,9 +2710,9 @@ read_line (COLUMN *p) +@@ -2508,9 +2714,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2226,7 +2247,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2612,9 +2813,9 @@ print_stored (COLUMN *p) +@@ -2611,9 +2817,9 @@ print_stored (COLUMN *p) } } @@ -2238,7 +2259,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2627,8 +2828,8 @@ print_stored (COLUMN *p) +@@ -2626,8 +2832,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2249,7 +2270,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c } return true; -@@ -2647,7 +2848,7 @@ print_stored (COLUMN *p) +@@ -2646,7 +2852,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2258,7 +2279,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c { unsigned char uc = c; char *s = clump_buff; -@@ -2657,10 +2858,10 @@ char_to_clump (char c) +@@ -2656,10 +2862,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2271,7 +2292,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2741,6 +2942,155 @@ char_to_clump (char c) +@@ -2740,6 +2946,154 @@ char_to_clump (char c) return chars; } @@ -2279,7 +2300,6 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c +static int +char_to_clump_multi (char c) +{ -+ unsigned char uc = c; + static size_t mbc_pos = 0; + static char mbc[MB_LEN_MAX] = {'\0'}; + static mbstate_t state = {'\0'}; @@ -2317,7 +2337,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c + width = +4; + chars = +4; + *s++ = '\\'; -+ sprintf (esc_buff, "%03o", mbc[0]); ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[0]); + for (i = 0; i <= 2; ++i) + *s++ = (int) esc_buff[i]; + } @@ -2366,7 +2386,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c + width += 4; + chars += 4; + *s++ = '\\'; -+ sprintf (esc_buff, "%03o", uc); ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); + for (j = 0; j <= 2; ++j) + *s++ = (int) esc_buff[j]; + } @@ -2387,7 +2407,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c + width += 4; + chars += 4; + *s++ = '\\'; -+ sprintf (esc_buff, "%03o", uc); ++ sprintf (esc_buff, "%03o", (unsigned char) mbc[i]); + for (j = 0; j <= 2; ++j) + *s++ = (int) esc_buff[j]; + } diff --git a/coreutils.spec b/coreutils.spec index e7dec7a..63528e7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.15 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -322,6 +322,9 @@ fi %{?!norunuser:/sbin/runuser} %changelog +* Mon Jan 16 2012 Kamil Dudka - 8.15-2 +- fix stack smashing, buffer overflow, and invalid output of pr (#772172) + * Sat Jan 07 2012 Ondrej Vasik - 8.15-1 - new upstream release 8.15 From 26e34c1ce38b098b539f1a741ff79a3f02476e5e Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 25 Jan 2012 14:28:25 +0100 Subject: [PATCH 157/523] install everything in /usr This patch is needed for the /usr-move feature https://fedoraproject.org/wiki/Features/UsrMove This package requires now 'filesystem' >= 3, which is only installable on a system which has /bin, /sbin, /lib, /lib64 as symlinks to /usr and not regular directories. The 'filesystem' package acts as a guard, to prevent *this* package to be installed on old unconverted systems. New installations will have the 'filesystem' >=3 layout right away, old installations need to be converted with anaconda or dracut first; only after that, the 'filesystem' package, and also *this* package can be installed. Packages *should* not install files in /bin, /sbin, /lib, /lib64, but only in the corresponding directories in /usr. Packages *must* not install conflicting files with the same names in the corresponding directories in / and /usr. Especially compatibilty symlinks must not be installed. Feel free to modify any of the changes to the spec file, but keep the above in mind. --- coreutils.spec | 164 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 114 insertions(+), 50 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 63528e7..f9750ba 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.15 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -169,7 +169,9 @@ make all %{?_smp_mflags} \ sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi %check -make check +# FIXME: check failed!! +# make check +: %install rm -rf $RPM_BUILD_ROOT @@ -189,17 +191,11 @@ fi bzip2 -9f ChangeLog # let be compatible with old fileutils, sh-utils and textutils packages : -mkdir -p $RPM_BUILD_ROOT{/bin,%{_bindir},%{_sbindir},/sbin} +mkdir -p $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}} %{?!nopam:mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pam.d} -for f in arch basename cat chgrp chmod chown cp cut date dd df echo env false link ln ls mkdir mknod mktemp mv nice pwd readlink rm rmdir sleep sort stty sync touch true uname unlink -do - mv $RPM_BUILD_ROOT{%{_bindir},/bin}/$f -done # chroot was in /usr/sbin : mv $RPM_BUILD_ROOT{%_bindir,%_sbindir}/chroot -# {env,cut,readlink} were previously moved from /usr/bin to /bin and linked into -for i in env cut readlink; do ln -sf ../../bin/$i $RPM_BUILD_ROOT/usr/bin; done mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d install -p -c -m644 %SOURCE101 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS @@ -209,10 +205,10 @@ install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.s install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh # su -install -m 4755 src/su $RPM_BUILD_ROOT/bin -%{?!norunuser:install -m 755 src/runuser $RPM_BUILD_ROOT/sbin} +install -m 4755 src/su $RPM_BUILD_ROOT/%{_bindir} +%{?!norunuser:install -m 755 src/runuser $RPM_BUILD_ROOT/%{_sbindir}} # do not ship runuser in /usr/bin/runuser -rm -rf $RPM_BUILD_ROOT/usr/bin/runuser || : +rm -rf $RPM_BUILD_ROOT/%{_bindir}/runuser || : # These come from util-linux and/or procps. for i in hostname uptime kill ; do @@ -262,7 +258,7 @@ if [ $1 = 0 ]; then fi %post -/bin/grep -v '(sh-utils)\|(fileutils)\|(textutils)' %{_infodir}/dir > \ +%{_bindir}/grep -v '(sh-utils)\|(fileutils)\|(textutils)' %{_infodir}/dir > \ %{_infodir}/dir.rpmmodify || exit 0 /bin/mv -f %{_infodir}/dir.rpmmodify %{_infodir}/dir if [ -f %{_infodir}/%{name}.info.gz ]; then @@ -279,49 +275,117 @@ fi %{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser} %{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser-l} %doc COPYING ABOUT-NLS ChangeLog.bz2 NEWS README THANKS TODO old/* -/bin/arch -/bin/basename -/bin/cat -/bin/chgrp -/bin/chmod -/bin/chown -/bin/cp -/bin/cut -/bin/date -/bin/dd -/bin/df -/bin/echo -/bin/env -/bin/false -/bin/link -/bin/ln -/bin/ls -/bin/mkdir -/bin/mknod -/bin/mv -/bin/nice -/bin/pwd -/bin/readlink -/bin/rm -/bin/rmdir -/bin/sleep -/bin/sort -/bin/stty -%attr(4755,root,root) /bin/su -/bin/sync -/bin/mktemp -/bin/touch -/bin/true -/bin/uname -/bin/unlink -%{_bindir}/* +%{_bindir}/arch +%{_bindir}/basename +%{_bindir}/cat +%{_bindir}/chgrp +%{_bindir}/chmod +%{_bindir}/chown +%{_bindir}/cp +%{_bindir}/cut +%{_bindir}/date +%{_bindir}/dd +%{_bindir}/df +%{_bindir}/echo +%{_bindir}/env +%{_bindir}/false +%{_bindir}/link +%{_bindir}/ln +%{_bindir}/ls +%{_bindir}/mkdir +%{_bindir}/mknod +%{_bindir}/mv +%{_bindir}/nice +%{_bindir}/pwd +%{_bindir}/readlink +%{_bindir}/rm +%{_bindir}/rmdir +%{_bindir}/sleep +%{_bindir}/sort +%{_bindir}/stty +%attr(4755,root,root) %{_bindir}/su +%{_bindir}/sync +%{_bindir}/mktemp +%{_bindir}/touch +%{_bindir}/true +%{_bindir}/uname +%{_bindir}/unlink +%{_bindir}/[ +%{_bindir}/base64 +%{_bindir}/chcon +%{_bindir}/cksum +%{_bindir}/comm +%{_bindir}/csplit +%{_bindir}/dir +%{_bindir}/dircolors +%{_bindir}/dirname +%{_bindir}/du +%{_bindir}/expand +%{_bindir}/expr +%{_bindir}/factor +%{_bindir}/fmt +%{_bindir}/fold +%{_bindir}/groups +%{_bindir}/head +%{_bindir}/hostid +%{_bindir}/id +%{_bindir}/install +%{_bindir}/join +%{_bindir}/logname +%{_bindir}/md5sum +%{_bindir}/mkfifo +%{_bindir}/nl +%{_bindir}/nohup +%{_bindir}/nproc +%{_bindir}/od +%{_bindir}/paste +%{_bindir}/pathchk +%{_bindir}/pinky +%{_bindir}/pr +%{_bindir}/printenv +%{_bindir}/printf +%{_bindir}/ptx +%{_bindir}/runcon +%{_bindir}/seq +%{_bindir}/sha1sum +%{_bindir}/sha224sum +%{_bindir}/sha256sum +%{_bindir}/sha384sum +%{_bindir}/sha512sum +%{_bindir}/shred +%{_bindir}/shuf +%{_bindir}/split +%{_bindir}/stat +%{_bindir}/stdbuf +%{_bindir}/sum +%{_bindir}/tac +%{_bindir}/tail +%{_bindir}/tee +%{_bindir}/test +%{_bindir}/timeout +%{_bindir}/tr +%{_bindir}/truncate +%{_bindir}/tsort +%{_bindir}/tty +%{_bindir}/unexpand +%{_bindir}/uniq +%{_bindir}/users +%{_bindir}/vdir +%{_bindir}/wc +%{_bindir}/who +%{_bindir}/whoami +%{_bindir}/yes %{_infodir}/coreutils* %{_libexecdir}/coreutils* %{_mandir}/man*/* %{_sbindir}/chroot -%{?!norunuser:/sbin/runuser} +%{?!norunuser:%{_sbindir}/runuser} %changelog +* Wed Jan 25 2012 Harald Hoyer 8.15-3 +- install everything in /usr + https://fedoraproject.org/wiki/Features/UsrMove + * Mon Jan 16 2012 Kamil Dudka - 8.15-2 - fix stack smashing, buffer overflow, and invalid output of pr (#772172) From 56e501f901811155c955acdc3283b633274702cf Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 25 Jan 2012 14:50:28 +0100 Subject: [PATCH 158/523] coreutils.spec: added realpath --- coreutils.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/coreutils.spec b/coreutils.spec index f9750ba..6840d30 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -345,6 +345,7 @@ fi %{_bindir}/printenv %{_bindir}/printf %{_bindir}/ptx +%{_bindir}/realpath %{_bindir}/runcon %{_bindir}/seq %{_bindir}/sha1sum From 09220fef36dcc2fe06bd858578119872f889c7e2 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 25 Jan 2012 15:48:48 +0100 Subject: [PATCH 159/523] add missing provides for the /usr-move --- coreutils.spec | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 6840d30..b2a0287 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.15 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -65,6 +65,41 @@ Patch951: coreutils-selinuxmanpages.patch #Deprecate cp -Z/--context non-upstream option Patch952: coreutils-cpZ-deprecate.patch +#Conflicts: filesystem < 3 +Provides: /bin/basename +Provides: /bin/cat +Provides: /bin/chgrp +Provides: /bin/chmod +Provides: /bin/chown +Provides: /bin/cp +Provides: /bin/cut +Provides: /bin/date +Provides: /bin/dd +Provides: /bin/df +Provides: /bin/echo +Provides: /bin/env +Provides: /bin/false +Provides: /bin/ln +Provides: /bin/ls +Provides: /bin/mkdir +Provides: /bin/mknod +Provides: /bin/mktemp +Provides: /bin/mv +Provides: /bin/nice +Provides: /bin/pwd +Provides: /bin/readlink +Provides: /bin/rm +Provides: /bin/rmdir +Provides: /bin/sleep +Provides: /bin/sort +Provides: /bin/stty +Provides: /bin/su +Provides: /bin/sync +Provides: /bin/touch +Provides: /bin/true +Provides: /bin/uname +Provides: /sbin/runuser + BuildRequires: libselinux-devel BuildRequires: libacl-devel BuildRequires: gettext bison @@ -383,6 +418,9 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Wed Jan 25 2012 Harald Hoyer 8.15-4 +- add missing provides for the /usr-move + * Wed Jan 25 2012 Harald Hoyer 8.15-3 - install everything in /usr https://fedoraproject.org/wiki/Features/UsrMove From 0af510e40c4310c3753cb5f01f7bce0bbf322cbc Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Wed, 25 Jan 2012 21:10:54 +0100 Subject: [PATCH 160/523] add filesystem guard --- coreutils.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index b2a0287..355647d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.15 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -65,7 +65,7 @@ Patch951: coreutils-selinuxmanpages.patch #Deprecate cp -Z/--context non-upstream option Patch952: coreutils-cpZ-deprecate.patch -#Conflicts: filesystem < 3 +Conflicts: filesystem < 3 Provides: /bin/basename Provides: /bin/cat Provides: /bin/chgrp @@ -418,6 +418,9 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Wed Jan 25 2012 Harald Hoyer 8.15-5 +- add filesystem guard + * Wed Jan 25 2012 Harald Hoyer 8.15-4 - add missing provides for the /usr-move From ec52e39a795b2ff4776ee06d7dd90c720e7606c1 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Fri, 10 Feb 2012 10:19:28 +0100 Subject: [PATCH 161/523] turn on testsuite again --- coreutils.spec | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 355647d..7ef0e35 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.15 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -204,9 +204,7 @@ make all %{?_smp_mflags} \ sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi %check -# FIXME: check failed!! -# make check -: +make check %install rm -rf $RPM_BUILD_ROOT @@ -418,6 +416,9 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Fri Feb 10 2012 Harald Hoyer 8.15-6 +- turn on testsuite again + * Wed Jan 25 2012 Harald Hoyer 8.15-5 - add filesystem guard From 58683bf9af461411e4e75daac2eac0e50922ed68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 7 Mar 2012 21:29:40 +0100 Subject: [PATCH 162/523] fix sort segfault with multibyte locales (by P.Brady) --- coreutils-i18n.patch | 150 +++++++++++++++++++++---------------------- coreutils.spec | 5 +- 2 files changed, 79 insertions(+), 76 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index ec79964..881f039 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.13-orig/lib/linebuffer.h coreutils-8.13/lib/linebuffer.h ---- coreutils-8.13-orig/lib/linebuffer.h 2011-04-24 19:21:45.000000000 +0200 -+++ coreutils-8.13/lib/linebuffer.h 2011-09-09 10:23:14.163704760 +0200 +diff -urNp coreutils-8.15-orig/lib/linebuffer.h coreutils-8.15/lib/linebuffer.h +--- coreutils-8.15-orig/lib/linebuffer.h 2012-01-06 10:14:31.000000000 +0100 ++++ coreutils-8.15/lib/linebuffer.h 2012-03-07 21:25:39.499333158 +0100 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.13-orig/lib/linebuffer.h coreutils-8.13/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c ---- coreutils-8.13-orig/src/cut.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/cut.c 2011-09-09 10:23:14.165701039 +0200 +diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c +--- coreutils-8.15-orig/src/cut.c 2012-01-01 10:04:06.000000000 +0100 ++++ coreutils-8.15/src/cut.c 2012-03-07 21:25:39.501333069 +0100 @@ -28,6 +28,11 @@ #include #include @@ -304,7 +304,7 @@ diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -704,13 +843,195 @@ cut_fields (FILE *stream) +@@ -704,13 +857,195 @@ cut_fields (FILE *stream) } } @@ -503,7 +503,7 @@ diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c } /* Process file FILE to standard output. -@@ -762,6 +1080,8 @@ main (int argc, char **argv) +@@ -762,6 +1097,8 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -512,7 +512,7 @@ diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -784,7 +1104,6 @@ main (int argc, char **argv) +@@ -784,7 +1121,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -520,7 +520,7 @@ diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -792,6 +1111,14 @@ main (int argc, char **argv) +@@ -792,6 +1128,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -535,7 +535,7 @@ diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -803,10 +1130,35 @@ main (int argc, char **argv) +@@ -803,10 +1147,35 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean `use the NUL byte as the delimiter.' */ @@ -575,7 +575,7 @@ diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -819,6 +1171,7 @@ main (int argc, char **argv) +@@ -819,6 +1188,7 @@ main (int argc, char **argv) break; case 'n': @@ -583,7 +583,7 @@ diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c break; case 's': -@@ -841,7 +1194,7 @@ main (int argc, char **argv) +@@ -841,7 +1211,7 @@ main (int argc, char **argv) if (operating_mode == undefined_mode) FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); @@ -592,7 +592,7 @@ diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c FATAL_ERROR (_("an input delimiter may be specified only\ when operating on fields")); -@@ -868,15 +1221,34 @@ main (int argc, char **argv) +@@ -868,15 +1238,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -633,9 +633,9 @@ diff -urNp coreutils-8.13-orig/src/cut.c coreutils-8.13/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.13-orig/src/expand.c coreutils-8.13/src/expand.c ---- coreutils-8.13-orig/src/expand.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/expand.c 2011-09-09 10:23:14.167583399 +0200 +diff -urNp coreutils-8.15-orig/src/expand.c coreutils-8.15/src/expand.c +--- coreutils-8.15-orig/src/expand.c 2012-01-01 10:04:06.000000000 +0100 ++++ coreutils-8.15/src/expand.c 2012-03-07 21:25:39.502358144 +0100 @@ -38,12 +38,29 @@ #include #include @@ -823,9 +823,9 @@ diff -urNp coreutils-8.13-orig/src/expand.c coreutils-8.13/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.13-orig/src/fold.c coreutils-8.13/src/fold.c ---- coreutils-8.13-orig/src/fold.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/fold.c 2011-09-09 10:23:14.169583741 +0200 +diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c +--- coreutils-8.15-orig/src/fold.c 2012-01-01 10:04:06.000000000 +0100 ++++ coreutils-8.15/src/fold.c 2012-03-07 21:25:39.504360585 +0100 @@ -22,12 +22,34 @@ #include #include @@ -1223,9 +1223,9 @@ diff -urNp coreutils-8.13-orig/src/fold.c coreutils-8.13/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.13-orig/src/join.c coreutils-8.13/src/join.c ---- coreutils-8.13-orig/src/join.c 2011-08-08 10:16:09.000000000 +0200 -+++ coreutils-8.13/src/join.c 2011-09-09 10:23:14.172687087 +0200 +diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c +--- coreutils-8.15-orig/src/join.c 2012-01-01 10:04:06.000000000 +0100 ++++ coreutils-8.15/src/join.c 2012-03-07 21:25:39.506358365 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1670,8 +1670,8 @@ diff -urNp coreutils-8.13-orig/src/join.c coreutils-8.13/src/join.c +#endif + newtablen = 1; if (! newtab) -+ { - newtab = '\n'; /* '' => process the whole line. */ ++ { + newtab = "\n"; /* '' => process the whole line. */ + } else if (optarg[1]) @@ -1701,9 +1701,9 @@ diff -urNp coreutils-8.13-orig/src/join.c coreutils-8.13/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c ---- coreutils-8.13-orig/src/pr.c 2011-08-30 23:01:40.000000000 +0200 -+++ coreutils-8.13/src/pr.c 2011-09-09 10:23:14.177658905 +0200 +diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c +--- coreutils-8.15-orig/src/pr.c 2012-01-01 10:04:06.000000000 +0100 ++++ coreutils-8.15/src/pr.c 2012-03-07 21:25:39.509333048 +0100 @@ -312,6 +312,32 @@ #include @@ -2151,7 +2151,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2305,7 +2443,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2305,7 +2443,7 @@ print_clump (COLUMN *p, int n, char *clu required number of tabs and spaces. */ static void @@ -2447,9 +2447,9 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c ---- coreutils-8.13-orig/src/sort.c 2011-07-29 10:12:25.000000000 +0200 -+++ coreutils-8.13/src/sort.c 2011-09-09 10:23:14.183686800 +0200 +diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c +--- coreutils-8.15-orig/src/sort.c 2012-01-01 10:04:06.000000000 +0100 ++++ coreutils-8.15/src/sort.c 2012-03-07 21:28:21.856210178 +0100 @@ -22,11 +22,20 @@ #include @@ -2994,7 +2994,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c /* 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 once -@@ -1942,7 +2305,7 @@ general_numcompare (char const *sa, char +@@ -1960,7 +2323,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -3003,7 +3003,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2217,15 +2580,14 @@ debug_key (struct line const *line, stru +@@ -2235,15 +2598,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -3021,7 +3021,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2369,7 +2731,7 @@ key_warnings (struct keyfield const *gke +@@ -2387,7 +2749,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3030,7 +3030,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2427,11 +2789,83 @@ key_warnings (struct keyfield const *gke +@@ -2445,11 +2807,83 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option `-r' only applies to last-resort comparison")); } @@ -3096,12 +3096,12 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c + } + while (hi - lo > 1); + -+ if (ea) -+ *ea = (char *) month; -+ + result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) + ? monthtab[lo].val : 0); + ++ if (ea && result) ++ *ea = s + strlen (monthtab[lo].name); ++ + return result; +} +#endif @@ -3115,7 +3115,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c { struct keyfield *key = keylist; -@@ -2516,7 +2950,7 @@ keycompare (struct line const *a, struct +@@ -2534,7 +2968,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3124,7 +3124,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2632,6 +3066,180 @@ keycompare (struct line const *a, struct +@@ -2650,6 +3084,180 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3305,7 +3305,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4095,7 +4702,7 @@ main (int argc, char **argv) +@@ -4110,7 +4718,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3314,7 +3314,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4116,6 +4723,29 @@ main (int argc, char **argv) +@@ -4131,6 +4739,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3344,7 +3344,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c have_read_stdin = false; inittables (); -@@ -4386,13 +5016,34 @@ main (int argc, char **argv) +@@ -4401,13 +5032,34 @@ main (int argc, char **argv) case 't': { @@ -3383,7 +3383,7 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c else { /* Provoke with `sort -txx'. Complain about -@@ -4403,9 +5054,12 @@ main (int argc, char **argv) +@@ -4418,9 +5070,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3398,9 +3398,9 @@ diff -urNp coreutils-8.13-orig/src/sort.c coreutils-8.13/src/sort.c } break; -diff -urNp coreutils-8.13-orig/src/unexpand.c coreutils-8.13/src/unexpand.c ---- coreutils-8.13-orig/src/unexpand.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/unexpand.c 2011-09-09 10:23:14.185647633 +0200 +diff -urNp coreutils-8.15-orig/src/unexpand.c coreutils-8.15/src/unexpand.c +--- coreutils-8.15-orig/src/unexpand.c 2012-01-01 10:04:06.000000000 +0100 ++++ coreutils-8.15/src/unexpand.c 2012-03-07 21:25:39.517457874 +0100 @@ -39,12 +39,29 @@ #include #include @@ -3654,9 +3654,9 @@ diff -urNp coreutils-8.13-orig/src/unexpand.c coreutils-8.13/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.13-orig/src/uniq.c coreutils-8.13/src/uniq.c ---- coreutils-8.13-orig/src/uniq.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/uniq.c 2011-09-09 10:24:19.631560964 +0200 +diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c +--- coreutils-8.15-orig/src/uniq.c 2012-01-01 10:04:06.000000000 +0100 ++++ coreutils-8.15/src/uniq.c 2012-03-07 21:25:39.519460555 +0100 @@ -21,6 +21,16 @@ #include #include @@ -4022,10 +4022,10 @@ diff -urNp coreutils-8.13-orig/src/uniq.c coreutils-8.13/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.13-orig/tests/Makefile.am coreutils-8.13/tests/Makefile.am ---- coreutils-8.13-orig/tests/Makefile.am 2011-09-09 10:22:43.352561668 +0200 -+++ coreutils-8.13/tests/Makefile.am 2011-09-09 10:23:14.189688942 +0200 -@@ -238,6 +238,7 @@ TESTS = \ +diff -urNp coreutils-8.15-orig/tests/Makefile.am coreutils-8.15/tests/Makefile.am +--- coreutils-8.15-orig/tests/Makefile.am 2012-03-07 21:25:03.149233957 +0100 ++++ coreutils-8.15/tests/Makefile.am 2012-03-07 21:25:39.520458288 +0100 +@@ -240,6 +240,7 @@ TESTS = \ misc/sort-debug-keys \ misc/sort-debug-warn \ misc/sort-files0-from \ @@ -4033,7 +4033,7 @@ diff -urNp coreutils-8.13-orig/tests/Makefile.am coreutils-8.13/tests/Makefile.a misc/sort-float \ misc/sort-merge \ misc/sort-merge-fdlimit \ -@@ -518,6 +519,10 @@ TESTS = \ +@@ -526,6 +527,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -4044,10 +4044,10 @@ diff -urNp coreutils-8.13-orig/tests/Makefile.am coreutils-8.13/tests/Makefile.a pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.13-orig/tests/misc/cut coreutils-8.13/tests/misc/cut ---- coreutils-8.13-orig/tests/misc/cut 2011-09-02 14:08:40.000000000 +0200 -+++ coreutils-8.13/tests/misc/cut 2011-09-09 10:23:14.190686793 +0200 -@@ -23,14 +23,15 @@ my $mb_locale = $ENV{LOCALE_FR_UTF8}; +diff -urNp coreutils-8.15-orig/tests/misc/cut coreutils-8.15/tests/misc/cut +--- coreutils-8.15-orig/tests/misc/cut 2012-01-01 10:04:06.000000000 +0100 ++++ coreutils-8.15/tests/misc/cut 2012-03-07 21:25:39.521460928 +0100 +@@ -23,14 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4067,7 +4067,7 @@ diff -urNp coreutils-8.13-orig/tests/misc/cut coreutils-8.13/tests/misc/cut my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; my @Tests = -@@ -147,7 +147,7 @@ my @Tests = +@@ -147,7 +148,7 @@ my @Tests = # None of the following invalid ranges provoked an error up to coreutils-6.9. ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, @@ -4076,41 +4076,41 @@ diff -urNp coreutils-8.13-orig/tests/misc/cut coreutils-8.13/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, -diff -urNp coreutils-8.13-orig/tests/misc/mb1.I coreutils-8.13/tests/misc/mb1.I ---- coreutils-8.13-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.13/tests/misc/mb1.I 2011-09-09 10:23:14.191687037 +0200 +diff -urNp coreutils-8.15-orig/tests/misc/mb1.I coreutils-8.15/tests/misc/mb1.I +--- coreutils-8.15-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.15/tests/misc/mb1.I 2012-03-07 21:25:39.521460928 +0100 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.13-orig/tests/misc/mb1.X coreutils-8.13/tests/misc/mb1.X ---- coreutils-8.13-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.13/tests/misc/mb1.X 2011-09-09 10:23:14.192581910 +0200 +diff -urNp coreutils-8.15-orig/tests/misc/mb1.X coreutils-8.15/tests/misc/mb1.X +--- coreutils-8.15-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.15/tests/misc/mb1.X 2012-03-07 21:25:39.522458368 +0100 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.13-orig/tests/misc/mb2.I coreutils-8.13/tests/misc/mb2.I ---- coreutils-8.13-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.13/tests/misc/mb2.I 2011-09-09 10:23:14.192581910 +0200 +diff -urNp coreutils-8.15-orig/tests/misc/mb2.I coreutils-8.15/tests/misc/mb2.I +--- coreutils-8.15-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.15/tests/misc/mb2.I 2012-03-07 21:25:39.523458000 +0100 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.13-orig/tests/misc/mb2.X coreutils-8.13/tests/misc/mb2.X ---- coreutils-8.13-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.13/tests/misc/mb2.X 2011-09-09 10:23:14.193687456 +0200 +diff -urNp coreutils-8.15-orig/tests/misc/mb2.X coreutils-8.15/tests/misc/mb2.X +--- coreutils-8.15-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.15/tests/misc/mb2.X 2012-03-07 21:25:39.523458000 +0100 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.13-orig/tests/misc/sort-mb-tests coreutils-8.13/tests/misc/sort-mb-tests ---- coreutils-8.13-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.13/tests/misc/sort-mb-tests 2011-09-09 10:23:14.194687565 +0200 +diff -urNp coreutils-8.15-orig/tests/misc/sort-mb-tests coreutils-8.15/tests/misc/sort-mb-tests +--- coreutils-8.15-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.15/tests/misc/sort-mb-tests 2012-03-07 21:25:39.524460637 +0100 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils.spec b/coreutils.spec index 7ef0e35..d5ad27a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.15 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -416,6 +416,9 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Wed Mar 07 2012 Ondrej Vasik 8.15-7 +- fix sort segfault with multibyte locales (by P.Brady) + * Fri Feb 10 2012 Harald Hoyer 8.15-6 - turn on testsuite again From 1618770344b123f310e3f13d6201c1f98d7d5948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 8 Mar 2012 14:10:11 +0100 Subject: [PATCH 163/523] fix regression in du -x with nondir argument (thans D.Stavrovski and J.Meyering) --- coreutils-8.15-du-x-nondir.patch | 43 ++++++++++++++++++++++++++++++++ coreutils.spec | 8 +++++- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.15-du-x-nondir.patch diff --git a/coreutils-8.15-du-x-nondir.patch b/coreutils-8.15-du-x-nondir.patch new file mode 100644 index 0000000..02d120e --- /dev/null +++ b/coreutils-8.15-du-x-nondir.patch @@ -0,0 +1,43 @@ +diff --git a/src/du.c b/src/du.c +index e4e36df..41c9535 100644 +--- a/src/du.c ++++ b/src/du.c +@@ -443,7 +443,14 @@ process_file (FTS *fts, FTSENT *ent) + return false; + } + +- if (fts->fts_options & FTS_XDEV && fts->fts_dev != sb->st_dev) ++ /* The --one-file-system (-x) option cannot exclude anything ++ specified on the command-line. By definition, it can exclude ++ a file or directory only when its device number is different ++ from that of its just-processed parent directory, and du does ++ not process the parent of a command-line argument. */ ++ if (fts->fts_options & FTS_XDEV ++ && FTS_ROOTLEVEL < ent->fts_level ++ && fts->fts_dev != sb->st_dev) + excluded = true; + } + +diff --git a/tests/du/one-file-system b/tests/du/one-file-system +index f0d264a..110080f 100755 +--- a/tests/du/one-file-system ++++ b/tests/du/one-file-system +@@ -43,7 +43,15 @@ compare exp out || fail=1 + du -xL d > u || fail=1 + sed 's/^[0-9][0-9]* //' u > out1 + echo d > exp1 || fail=1 +- + compare exp1 out1 || fail=1 + ++# With coreutils-8.15, "du -xs FILE" would print no output. ++touch f ++for opt in -x -xs; do ++ du $opt f > u || fail=1 ++ sed 's/^[0-9][0-9]* //' u > out2 ++ echo f > exp2 || fail=1 ++ compare exp2 out2 || fail=1 ++done ++ + Exit $fail +-- +cgit v0.9.0.2 diff --git a/coreutils.spec b/coreutils.spec index d5ad27a..2028343 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.15 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,6 +18,8 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream +# fix regression in du -x with nondir argument +Patch1: coreutils-8.15-du-x-nondir.patch # Our patches #general patch to workaround koji build system issues @@ -143,6 +145,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream +%patch1 -p1 -b .xnondir # Our patches %patch100 -p1 -b .configure @@ -416,6 +419,9 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Thu Mar 08 2012 Ondrej Vasik 8.15-8 +- fix regression in du -x with nondir argument (by J.Meyering) + * Wed Mar 07 2012 Ondrej Vasik 8.15-7 - fix sort segfault with multibyte locales (by P.Brady) From bb1a465686e6320efd4b9b321cf9c3cd5c0b24a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 26 Mar 2012 18:23:32 +0200 Subject: [PATCH 164/523] new upstream release 8.16, defuzz patches, remove already applied patches --- .gitignore | 1 + coreutils-8.15-du-x-nondir.patch | 43 ----- coreutils-8.5-pam.patch | 102 +++++------- coreutils-8.7-runuser.patch | 2 +- coreutils-df-direct.patch | 44 ++--- coreutils-i18n.patch | 278 +++++++++++++++---------------- coreutils-selinux.patch | 4 +- coreutils.spec | 11 +- sources | 2 +- 9 files changed, 215 insertions(+), 272 deletions(-) delete mode 100644 coreutils-8.15-du-x-nondir.patch diff --git a/.gitignore b/.gitignore index b8a1c39..ab26cd4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /coreutils-8.13.tar.xz /coreutils-8.14.tar.xz /coreutils-8.15.tar.xz +/coreutils-8.16.tar.xz diff --git a/coreutils-8.15-du-x-nondir.patch b/coreutils-8.15-du-x-nondir.patch deleted file mode 100644 index 02d120e..0000000 --- a/coreutils-8.15-du-x-nondir.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff --git a/src/du.c b/src/du.c -index e4e36df..41c9535 100644 ---- a/src/du.c -+++ b/src/du.c -@@ -443,7 +443,14 @@ process_file (FTS *fts, FTSENT *ent) - return false; - } - -- if (fts->fts_options & FTS_XDEV && fts->fts_dev != sb->st_dev) -+ /* The --one-file-system (-x) option cannot exclude anything -+ specified on the command-line. By definition, it can exclude -+ a file or directory only when its device number is different -+ from that of its just-processed parent directory, and du does -+ not process the parent of a command-line argument. */ -+ if (fts->fts_options & FTS_XDEV -+ && FTS_ROOTLEVEL < ent->fts_level -+ && fts->fts_dev != sb->st_dev) - excluded = true; - } - -diff --git a/tests/du/one-file-system b/tests/du/one-file-system -index f0d264a..110080f 100755 ---- a/tests/du/one-file-system -+++ b/tests/du/one-file-system -@@ -43,7 +43,15 @@ compare exp out || fail=1 - du -xL d > u || fail=1 - sed 's/^[0-9][0-9]* //' u > out1 - echo d > exp1 || fail=1 -- - compare exp1 out1 || fail=1 - -+# With coreutils-8.15, "du -xs FILE" would print no output. -+touch f -+for opt in -x -xs; do -+ du $opt f > u || fail=1 -+ sed 's/^[0-9][0-9]* //' u > out2 -+ echo f > exp2 || fail=1 -+ compare exp2 out2 || fail=1 -+done -+ - Exit $fail --- -cgit v0.9.0.2 diff --git a/coreutils-8.5-pam.patch b/coreutils-8.5-pam.patch index 8a924b2..3d0e416 100644 --- a/coreutils-8.5-pam.patch +++ b/coreutils-8.5-pam.patch @@ -1,19 +1,7 @@ -From ea2d050b1952feb99f86c98255280beb6e589d8c Mon Sep 17 00:00:00 2001 -From: Ludwig Nussel -Date: Tue, 17 Aug 2010 13:21:44 +0200 -Subject: [PATCH 1/7] pam support for su - ---- - configure.ac | 14 +++ - src/Makefile.am | 4 +- - src/su.c | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 278 insertions(+), 6 deletions(-) - -diff --git a/configure.ac b/configure.ac -index b07a52b..1fb5839 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -128,6 +128,20 @@ fi +diff -urNp coreutils-8.16-orig/configure.ac coreutils-8.16/configure.ac +--- coreutils-8.16-orig/configure.ac 2012-03-24 19:22:13.000000000 +0100 ++++ coreutils-8.16/configure.ac 2012-03-26 17:59:07.900139497 +0200 +@@ -185,6 +185,20 @@ fi AC_FUNC_FORK @@ -34,11 +22,34 @@ index b07a52b..1fb5839 100644 optional_bin_progs= AC_CHECK_FUNCS([chroot], gl_ADD_PROG([optional_bin_progs], [chroot])) -diff --git a/src/Makefile.am b/src/Makefile.am -index db5359b..154a5ed 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -363,8 +363,8 @@ factor_LDADD += $(LIB_GMP) +diff -urNp coreutils-8.16-orig/doc/coreutils.texi coreutils-8.16/doc/coreutils.texi +--- coreutils-8.16-orig/doc/coreutils.texi 2012-03-26 17:58:27.624763998 +0200 ++++ coreutils-8.16/doc/coreutils.texi 2012-03-26 17:59:07.907138599 +0200 +@@ -15804,7 +15804,9 @@ the exit status of @var{command} otherwi + + @command{su} allows one user to temporarily become another user. It runs a + command (often an interactive shell) with the real and effective user +-ID, group ID, and supplemental groups of a given @var{user}. Synopsis: ++ID, group ID, and supplemental groups of a given @var{user}. When the -l ++option is given, the su-l PAM file is used instead of the default su PAM file. ++Synopsis: + + @example + su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}] +@@ -15883,7 +15885,8 @@ environment variables except @env{TERM}, + (which are set, even for the super-user, as described above), and set + @env{PATH} to a compiled-in default value. Change to @var{user}'s home + directory. Prepend @samp{-} to the shell's name, intended to make it +-read its login startup file(s). ++read its login startup file(s). When this option is given, /etc/pam.d/su-l ++PAM file is used instead of the default one. + + @item -m + @itemx -p +diff -urNp coreutils-8.16-orig/src/Makefile.am coreutils-8.16/src/Makefile.am +--- coreutils-8.16-orig/src/Makefile.am 2012-03-24 19:22:13.000000000 +0100 ++++ coreutils-8.16/src/Makefile.am 2012-03-26 17:59:07.928142551 +0200 +@@ -357,8 +357,8 @@ factor_LDADD += $(LIB_GMP) # for getloadavg uptime_LDADD += $(GETLOADAVG_LIBS) @@ -49,10 +60,9 @@ index db5359b..154a5ed 100644 # for various ACL functions copy_LDADD += $(LIB_ACL) -diff --git a/src/su.c b/src/su.c -index f8f5b61..811aad7 100644 ---- a/src/su.c -+++ b/src/su.c +diff -urNp coreutils-8.16-orig/src/su.c coreutils-8.16/src/su.c +--- coreutils-8.16-orig/src/su.c 2012-03-26 17:58:27.629764055 +0200 ++++ coreutils-8.16/src/su.c 2012-03-26 17:59:07.931138998 +0200 @@ -37,6 +37,16 @@ restricts who can su to UID 0 accounts. RMS considers that to be fascist. @@ -84,7 +94,7 @@ index f8f5b61..811aad7 100644 #include "system.h" #include "getpass.h" -@@ -111,7 +128,9 @@ +@@ -120,7 +137,9 @@ /* The user to become if none is specified. */ #define DEFAULT_USER "root" @@ -94,7 +104,7 @@ index f8f5b61..811aad7 100644 static void run_shell (char const *, char const *, char **, size_t) ATTRIBUTE_NORETURN; -@@ -125,6 +144,11 @@ static bool simulate_login; +@@ -134,6 +153,11 @@ static bool simulate_login; /* If true, change some environment vars to indicate the user su'd to. */ static bool change_environment; @@ -106,7 +116,7 @@ index f8f5b61..811aad7 100644 static struct option const longopts[] = { {"command", required_argument, NULL, 'c'}, -@@ -200,7 +224,174 @@ log_su (struct passwd const *pw, bool successful) +@@ -212,7 +236,174 @@ log_su (struct passwd const *pw, bool su } #endif @@ -281,7 +291,7 @@ index f8f5b61..811aad7 100644 Return true if the user gives the correct password for entry PW, false if not. Return true without asking for a password if run by UID 0 or if PW has an empty password. */ -@@ -208,10 +399,52 @@ log_su (struct passwd const *pw, bool successful) +@@ -220,10 +411,52 @@ log_su (struct passwd const *pw, bool su static bool correct_password (const struct passwd *pw) { @@ -335,15 +345,15 @@ index f8f5b61..811aad7 100644 endspent (); if (sp) -@@ -232,6 +465,7 @@ correct_password (const struct passwd *pw) +@@ -244,6 +477,7 @@ correct_password (const struct passwd *p encrypted = crypt (unencrypted, correct); memset (unencrypted, 0, strlen (unencrypted)); return STREQ (encrypted, correct); +#endif /* !USE_PAM */ } - /* Update `environ' for the new shell based on PW, with SHELL being -@@ -274,19 +508,41 @@ modify_environment (const struct passwd *pw, const char *shell) + /* Update 'environ' for the new shell based on PW, with SHELL being +@@ -286,19 +520,41 @@ modify_environment (const struct passwd } } } @@ -387,7 +397,7 @@ index f8f5b61..811aad7 100644 if (setgid (pw->pw_gid)) error (EXIT_CANCELED, errno, _("cannot set group id")); if (setuid (pw->pw_uid)) -@@ -500,9 +756,21 @@ main (int argc, char **argv) +@@ -511,9 +767,21 @@ main (int argc, char **argv) shell = NULL; } shell = xstrdup (shell ? shell : pw->pw_shell); @@ -410,29 +420,3 @@ index f8f5b61..811aad7 100644 if (simulate_login && chdir (pw->pw_dir) != 0) error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); --- -1.7.1 -diff -urNp coreutils-8.7-orig/doc/coreutils.texi coreutils-8.7/doc/coreutils.texi ---- coreutils-8.7-orig/doc/coreutils.texi 2010-11-15 12:47:03.529922880 +0100 -+++ coreutils-8.7/doc/coreutils.texi 2010-11-15 12:49:55.945171380 +0100 -@@ -15180,7 +15180,9 @@ the exit status of @var{command} otherwi - - @command{su} allows one user to temporarily become another user. It runs a - command (often an interactive shell) with the real and effective user --ID, group ID, and supplemental groups of a given @var{user}. Synopsis: -+ID, group ID, and supplemental groups of a given @var{user}. When the -l -+option is given, the su-l PAM file is used instead of the default su PAM file. -+Synopsis: - - @example - su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}] -@@ -15259,7 +15261,8 @@ environment variables except @env{TERM}, - (which are set, even for the super-user, as described above), and set - @env{PATH} to a compiled-in default value. Change to @var{user}'s home - directory. Prepend @samp{-} to the shell's name, intended to make it --read its login startup file(s). -+read its login startup file(s). When this option is given, /etc/pam.d/su-l -+PAM file is used instead of the default one. - - @item -m - @itemx -p diff --git a/coreutils-8.7-runuser.patch b/coreutils-8.7-runuser.patch index c68da7c..533e15a 100644 --- a/coreutils-8.7-runuser.patch +++ b/coreutils-8.7-runuser.patch @@ -100,7 +100,7 @@ diff -urNp coreutils-8.7-orig/src/su.c coreutils-8.7/src/su.c @@ -100,9 +100,15 @@ #include "error.h" - /* The official name of this program (e.g., no `g' prefix). */ + /* The official name of this program (e.g., no 'g' prefix). */ +#ifndef RUNUSER #define PROGRAM_NAME "su" +#else diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 1bc8c40..14d1c44 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.11-orig/doc/coreutils.texi coreutils-8.11/doc/coreutils.texi ---- coreutils-8.11-orig/doc/coreutils.texi 2011-04-12 12:07:43.000000000 +0200 -+++ coreutils-8.11/doc/coreutils.texi 2011-04-14 09:53:43.764309420 +0200 -@@ -10409,6 +10409,13 @@ pseudo-file-systems, such as automounter +diff -urNp coreutils-8.16-orig/doc/coreutils.texi coreutils-8.16/doc/coreutils.texi +--- coreutils-8.16-orig/doc/coreutils.texi 2012-03-26 07:38:37.000000000 +0200 ++++ coreutils-8.16/doc/coreutils.texi 2012-03-26 17:31:31.101014556 +0200 +@@ -10584,6 +10584,13 @@ pseudo-file-systems, such as automounter Scale sizes by @var{size} before printing them (@pxref{Block size}). For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. @@ -15,10 +15,10 @@ diff -urNp coreutils-8.11-orig/doc/coreutils.texi coreutils-8.11/doc/coreutils.t @itemx --total @opindex --total @cindex grand total of disk size, usage and available space -diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c ---- coreutils-8.11-orig/src/df.c 2011-04-12 12:07:43.000000000 +0200 -+++ coreutils-8.11/src/df.c 2011-04-14 10:37:44.208308771 +0200 -@@ -112,6 +112,9 @@ static bool print_type; +diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c +--- coreutils-8.16-orig/src/df.c 2012-03-24 21:26:51.000000000 +0100 ++++ coreutils-8.16/src/df.c 2012-03-26 17:31:31.102014797 +0200 +@@ -113,6 +113,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -28,7 +28,7 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -166,13 +169,15 @@ static size_t nrows; +@@ -167,13 +170,15 @@ static size_t nrows; enum { NO_SYNC_OPTION = CHAR_MAX + 1, @@ -45,7 +45,7 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, -@@ -259,7 +264,11 @@ get_header (void) +@@ -260,7 +265,11 @@ get_header (void) } char *cell = NULL; @@ -58,7 +58,7 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c if (!header) header = _(headers[field][DEFAULT_MODE]); -@@ -757,6 +766,17 @@ get_point (const char *point, const stru +@@ -790,6 +799,17 @@ get_point (const char *point, const stru static void get_entry (char const *name, struct stat const *statp) { @@ -76,15 +76,15 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_disk (name)) return; -@@ -825,6 +845,7 @@ Mandatory arguments to long options are +@@ -857,6 +877,7 @@ Mandatory arguments to long options are -B, --block-size=SIZE scale sizes by SIZE before printing them. E.g.,\n\ - `-BM' prints sizes in units of 1,048,576 bytes.\n\ + '-BM' prints sizes in units of 1,048,576 bytes.\n\ See SIZE format below.\n\ + --direct show statistics for a file instead of mount point\n\ --total produce a grand total\n\ -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\ \n\ -@@ -901,6 +922,9 @@ main (int argc, char **argv) +@@ -933,6 +954,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -94,7 +94,7 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c case 'i': inode_format = true; break; -@@ -961,6 +985,13 @@ main (int argc, char **argv) +@@ -993,6 +1017,13 @@ main (int argc, char **argv) } } @@ -108,9 +108,9 @@ diff -urNp coreutils-8.11-orig/src/df.c coreutils-8.11/src/df.c if (human_output_opts == -1) { if (posix_format) -diff -urNp coreutils-8.11-orig/tests/df/direct coreutils-8.11/tests/df/direct ---- coreutils-8.11-orig/tests/df/direct 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.11/tests/df/direct 2011-04-14 09:53:43.767400034 +0200 +diff -urNp coreutils-8.16-orig/tests/df/direct coreutils-8.16/tests/df/direct +--- coreutils-8.16-orig/tests/df/direct 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.16/tests/df/direct 2012-03-26 17:31:31.102897406 +0200 @@ -0,0 +1,55 @@ +#!/bin/sh +# Ensure "df --direct" works as documented @@ -167,10 +167,10 @@ diff -urNp coreutils-8.11-orig/tests/df/direct coreutils-8.11/tests/df/direct +compare file_out file_exp || fail=1 + +Exit $fail -diff -urNp coreutils-8.11-orig/tests/Makefile.am coreutils-8.11/tests/Makefile.am ---- coreutils-8.11-orig/tests/Makefile.am 2011-04-14 09:53:13.666324768 +0200 -+++ coreutils-8.11/tests/Makefile.am 2011-04-14 09:53:43.768432620 +0200 -@@ -362,6 +362,7 @@ TESTS = \ +diff -urNp coreutils-8.16-orig/tests/Makefile.am coreutils-8.16/tests/Makefile.am +--- coreutils-8.16-orig/tests/Makefile.am 2012-03-26 17:31:08.642764437 +0200 ++++ coreutils-8.16/tests/Makefile.am 2012-03-26 17:31:31.104015483 +0200 +@@ -379,6 +379,7 @@ TESTS = \ dd/stderr \ dd/unblock \ dd/unblock-sync \ diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 881f039..ee2cf73 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.15-orig/lib/linebuffer.h coreutils-8.15/lib/linebuffer.h ---- coreutils-8.15-orig/lib/linebuffer.h 2012-01-06 10:14:31.000000000 +0100 -+++ coreutils-8.15/lib/linebuffer.h 2012-03-07 21:25:39.499333158 +0100 +diff -urNp coreutils-8.16-orig/lib/linebuffer.h coreutils-8.16/lib/linebuffer.h +--- coreutils-8.16-orig/lib/linebuffer.h 2012-01-06 10:14:31.000000000 +0100 ++++ coreutils-8.16/lib/linebuffer.h 2012-03-26 18:02:00.993889446 +0200 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.15-orig/lib/linebuffer.h coreutils-8.15/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c ---- coreutils-8.15-orig/src/cut.c 2012-01-01 10:04:06.000000000 +0100 -+++ coreutils-8.15/src/cut.c 2012-03-07 21:25:39.501333069 +0100 +diff -urNp coreutils-8.16-orig/src/cut.c coreutils-8.16/src/cut.c +--- coreutils-8.16-orig/src/cut.c 2012-03-24 21:26:51.000000000 +0100 ++++ coreutils-8.16/src/cut.c 2012-03-26 17:46:48.000000000 +0200 @@ -28,6 +28,11 @@ #include #include @@ -54,7 +54,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c +# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) +#endif + - /* The official name of this program (e.g., no `g' prefix). */ + /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "cut" @@ -72,6 +89,52 @@ @@ -118,7 +118,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c +/* The largest byte, character or field index used as an endpoint of a closed or degenerate range specification; this doesn't include the starting index of right-open-ended ranges. For example, with either range spec - `2-5,9-', `2-3,5,9-' this variable would be set to 5. */ + '2-5,9-', '2-3,5,9-' this variable would be set to 5. */ @@ -102,10 +165,11 @@ static size_t eol_range_start; /* This is a bit vector. @@ -170,7 +170,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -207,7 +284,7 @@ Mandatory arguments to long options are +@@ -206,7 +283,7 @@ Mandatory arguments to long options are -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\ @@ -179,7 +179,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -366,7 +443,7 @@ set_fields (const char *fieldstr) +@@ -365,7 +442,7 @@ set_fields (const char *fieldstr) in_digits = false; /* Starting a range. */ if (dash_found) @@ -188,10 +188,10 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c dash_found = true; fieldstr++; -@@ -390,14 +467,16 @@ set_fields (const char *fieldstr) +@@ -389,14 +466,16 @@ set_fields (const char *fieldstr) if (!rhs_specified) { - /* `n-'. From `initial' to end of line. */ + /* 'n-'. From 'initial' to end of line. */ - eol_range_start = initial; + if (eol_range_start == 0 || + (eol_range_start != 0 && eol_range_start > initial)) @@ -200,14 +200,14 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c } else { - /* `m-n' or `-n' (1-n). */ + /* 'm-n' or '-n' (1-n). */ if (value < initial) - FATAL_ERROR (_("invalid decreasing range")); + FATAL_ERROR (_("invalid byte, character or field list")); /* Is there already a range going to end of line? */ if (eol_range_start != 0) -@@ -477,6 +556,9 @@ set_fields (const char *fieldstr) +@@ -476,6 +555,9 @@ set_fields (const char *fieldstr) if (operating_mode == byte_mode) error (0, 0, _("byte offset %s is too large"), quote (bad_num)); @@ -217,7 +217,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c else error (0, 0, _("field number %s is too large"), quote (bad_num)); -@@ -487,7 +569,7 @@ set_fields (const char *fieldstr) +@@ -486,7 +568,7 @@ set_fields (const char *fieldstr) fieldstr++; } else @@ -226,7 +226,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c } max_range_endpoint = 0; -@@ -582,6 +664,77 @@ cut_bytes (FILE *stream) +@@ -581,6 +663,77 @@ cut_bytes (FILE *stream) } } @@ -304,7 +304,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -704,13 +857,195 @@ cut_fields (FILE *stream) +@@ -703,13 +856,195 @@ cut_fields (FILE *stream) } } @@ -503,7 +503,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c } /* Process file FILE to standard output. -@@ -762,6 +1097,8 @@ main (int argc, char **argv) +@@ -761,6 +1096,8 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -512,7 +512,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -784,7 +1121,6 @@ main (int argc, char **argv) +@@ -783,7 +1120,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -520,7 +520,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -792,6 +1128,14 @@ main (int argc, char **argv) +@@ -791,6 +1127,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -535,10 +535,10 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -803,10 +1147,35 @@ main (int argc, char **argv) +@@ -802,10 +1146,35 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ - /* Interpret -d '' to mean `use the NUL byte as the 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]; @@ -575,7 +575,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -819,6 +1188,7 @@ main (int argc, char **argv) +@@ -818,6 +1187,7 @@ main (int argc, char **argv) break; case 'n': @@ -583,7 +583,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c break; case 's': -@@ -841,7 +1211,7 @@ main (int argc, char **argv) +@@ -840,7 +1210,7 @@ main (int argc, char **argv) if (operating_mode == undefined_mode) FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); @@ -592,7 +592,7 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c FATAL_ERROR (_("an input delimiter may be specified only\ when operating on fields")); -@@ -868,15 +1238,34 @@ main (int argc, char **argv) +@@ -867,15 +1237,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -633,10 +633,10 @@ diff -urNp coreutils-8.15-orig/src/cut.c coreutils-8.15/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.15-orig/src/expand.c coreutils-8.15/src/expand.c ---- coreutils-8.15-orig/src/expand.c 2012-01-01 10:04:06.000000000 +0100 -+++ coreutils-8.15/src/expand.c 2012-03-07 21:25:39.502358144 +0100 -@@ -38,12 +38,29 @@ +diff -urNp coreutils-8.16-orig/src/expand.c coreutils-8.16/src/expand.c +--- coreutils-8.16-orig/src/expand.c 2012-03-24 21:26:51.000000000 +0100 ++++ coreutils-8.16/src/expand.c 2012-03-26 17:42:56.000000000 +0200 +@@ -37,12 +37,29 @@ #include #include #include @@ -663,10 +663,10 @@ diff -urNp coreutils-8.15-orig/src/expand.c coreutils-8.15/src/expand.c +# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) +#endif + - /* The official name of this program (e.g., no `g' prefix). */ + /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "expand" -@@ -360,6 +377,142 @@ expand (void) +@@ -358,6 +375,142 @@ expand (void) } } @@ -809,7 +809,7 @@ diff -urNp coreutils-8.15-orig/src/expand.c coreutils-8.15/src/expand.c int main (int argc, char **argv) { -@@ -424,7 +577,12 @@ main (int argc, char **argv) +@@ -422,7 +575,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -823,9 +823,9 @@ diff -urNp coreutils-8.15-orig/src/expand.c coreutils-8.15/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c ---- coreutils-8.15-orig/src/fold.c 2012-01-01 10:04:06.000000000 +0100 -+++ coreutils-8.15/src/fold.c 2012-03-07 21:25:39.504360585 +0100 +diff -urNp coreutils-8.16-orig/src/fold.c coreutils-8.16/src/fold.c +--- coreutils-8.16-orig/src/fold.c 2012-03-24 19:22:13.000000000 +0100 ++++ coreutils-8.16/src/fold.c 2012-03-26 17:48:37.000000000 +0200 @@ -22,12 +22,34 @@ #include #include @@ -860,7 +860,7 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c + #define TAB_WIDTH 8 - /* The official name of this program (e.g., no `g' prefix). */ + /* The official name of this program (e.g., no 'g' prefix). */ @@ -35,20 +57,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -907,7 +907,7 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c {"spaces", no_argument, NULL, 's'}, {"width", required_argument, NULL, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -78,6 +121,7 @@ Mandatory arguments to long options are +@@ -77,6 +120,7 @@ Mandatory arguments to long options are "), stdout); fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -915,7 +915,7 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -95,7 +139,7 @@ Mandatory arguments to long options are +@@ -94,7 +138,7 @@ Mandatory arguments to long options are static size_t adjust_column (size_t column, char c) { @@ -924,7 +924,7 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c { if (c == '\b') { -@@ -118,30 +162,14 @@ adjust_column (size_t column, char c) +@@ -117,30 +161,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -936,7 +936,7 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c - 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. */ + 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; @@ -957,7 +957,7 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c fadvise (istream, FADVISE_SEQUENTIAL); -@@ -171,6 +199,15 @@ fold_file (char const *filename, size_t +@@ -170,6 +198,15 @@ fold_file (char const *filename, size_t bool found_blank = false; size_t logical_end = offset_out; @@ -973,7 +973,7 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -217,11 +254,221 @@ fold_file (char const *filename, size_t +@@ -216,11 +253,221 @@ fold_file (char const *filename, size_t line_out[offset_out++] = c; } @@ -1196,7 +1196,7 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c if (ferror (istream)) { error (0, saved_errno, "%s", filename); -@@ -254,7 +501,8 @@ main (int argc, char **argv) +@@ -253,7 +500,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1206,7 +1206,7 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -263,7 +511,15 @@ main (int argc, char **argv) +@@ -262,7 +510,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1223,9 +1223,9 @@ diff -urNp coreutils-8.15-orig/src/fold.c coreutils-8.15/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c ---- coreutils-8.15-orig/src/join.c 2012-01-01 10:04:06.000000000 +0100 -+++ coreutils-8.15/src/join.c 2012-03-07 21:25:39.506358365 +0100 +diff -urNp coreutils-8.16-orig/src/join.c coreutils-8.16/src/join.c +--- coreutils-8.16-orig/src/join.c 2012-03-24 21:26:51.000000000 +0100 ++++ coreutils-8.16/src/join.c 2012-03-26 17:50:02.000000000 +0200 @@ -22,18 +22,32 @@ #include #include @@ -1257,11 +1257,11 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c +# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) +#endif + - /* The official name of this program (e.g., no `g' prefix). */ + /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "join" @@ -135,10 +149,12 @@ static struct outlist outlist_head; - /* Last element in `outlist', where a new element can be added. */ + /* 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 @@ -1277,7 +1277,7 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -263,13 +279,14 @@ xfields (struct line *line) +@@ -262,13 +278,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1295,7 +1295,7 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c { /* Skip leading blanks before the first field. */ while (isblank (to_uchar (*ptr))) -@@ -293,6 +310,148 @@ xfields (struct line *line) +@@ -292,6 +309,148 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1444,7 +1444,7 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c static void freeline (struct line *line) { -@@ -314,56 +473,115 @@ keycmp (struct line const *line1, struct +@@ -313,56 +472,115 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1583,7 +1583,7 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -455,6 +673,11 @@ get_line (FILE *fp, struct line **linep, +@@ -454,6 +672,11 @@ get_line (FILE *fp, struct line **linep, } ++line_no[which - 1]; @@ -1595,7 +1595,7 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c xfields (line); if (prevline[which - 1]) -@@ -554,21 +777,28 @@ prfield (size_t n, struct line const *li +@@ -553,21 +776,28 @@ prfield (size_t n, struct line const *li /* Output all the fields in line, other than the join field. */ @@ -1627,7 +1627,7 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c prfield (i, line); } } -@@ -579,7 +809,6 @@ static void +@@ -578,7 +808,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -1635,7 +1635,7 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c size_t field; struct line const *line; -@@ -613,7 +842,7 @@ prjoin (struct line const *line1, struct +@@ -612,7 +841,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1644,7 +1644,7 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c } putchar ('\n'); } -@@ -1091,21 +1320,46 @@ main (int argc, char **argv) +@@ -1090,21 +1319,46 @@ main (int argc, char **argv) case 't': { @@ -1701,9 +1701,9 @@ diff -urNp coreutils-8.15-orig/src/join.c coreutils-8.15/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c ---- coreutils-8.15-orig/src/pr.c 2012-01-01 10:04:06.000000000 +0100 -+++ coreutils-8.15/src/pr.c 2012-03-07 21:25:39.509333048 +0100 +diff -urNp coreutils-8.16-orig/src/pr.c coreutils-8.16/src/pr.c +--- coreutils-8.16-orig/src/pr.c 2012-03-24 21:26:51.000000000 +0100 ++++ coreutils-8.16/src/pr.c 2012-03-26 17:50:48.000000000 +0200 @@ -312,6 +312,32 @@ #include @@ -1753,7 +1753,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c +extern int wcwidth (); +#endif + - /* The official name of this program (e.g., no `g' prefix). */ + /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" @@ -415,7 +453,20 @@ struct COLUMN @@ -1840,7 +1840,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ @@ -691,6 +751,7 @@ static bool use_col_separator = false; - -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ + -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ static char *col_sep_string = (char *) ""; static int col_sep_length = 0; +static int col_sep_width = 0; @@ -2082,7 +2082,7 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c @@ -2050,22 +2181,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 + 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') @@ -2447,9 +2447,9 @@ diff -urNp coreutils-8.15-orig/src/pr.c coreutils-8.15/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c ---- coreutils-8.15-orig/src/sort.c 2012-01-01 10:04:06.000000000 +0100 -+++ coreutils-8.15/src/sort.c 2012-03-07 21:28:21.856210178 +0100 +diff -urNp coreutils-8.16-orig/src/sort.c coreutils-8.16/src/sort.c +--- coreutils-8.16-orig/src/sort.c 2012-03-24 21:26:51.000000000 +0100 ++++ coreutils-8.16/src/sort.c 2012-03-26 17:35:09.000000000 +0200 @@ -22,11 +22,20 @@ #include @@ -2524,7 +2524,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -783,6 +812,46 @@ reap_all (void) +@@ -782,6 +811,46 @@ reap_all (void) reap (-1); } @@ -2571,7 +2571,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1215,7 +1284,7 @@ zaptemp (char const *name) +@@ -1214,7 +1283,7 @@ zaptemp (char const *name) free (node); } @@ -2580,7 +2580,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1230,7 +1299,7 @@ struct_month_cmp (void const *m1, void c +@@ -1229,7 +1298,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2589,7 +2589,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c { size_t i; -@@ -1242,7 +1311,7 @@ inittables (void) +@@ -1241,7 +1310,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2598,7 +2598,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1324,6 +1393,84 @@ specify_nmerge (int oi, char c, char con +@@ -1323,6 +1392,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2683,7 +2683,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1552,7 +1699,7 @@ buffer_linelim (struct buffer const *buf +@@ -1551,7 +1698,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2692,7 +2692,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1561,10 +1708,10 @@ begfield (struct line const *line, struc +@@ -1560,10 +1707,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2705,7 +2705,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1590,11 +1737,70 @@ begfield (struct line const *line, struc +@@ -1589,11 +1736,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2777,9 +2777,9 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1609,10 +1815,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 +@@ -1608,10 +1814,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) @@ -2790,7 +2790,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1658,10 +1864,10 @@ limfield (struct line const *line, struc +@@ -1657,10 +1863,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2803,7 +2803,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c if (newlim) lim = newlim; } -@@ -1692,6 +1898,130 @@ limfield (struct line const *line, struc +@@ -1691,6 +1897,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2934,7 +2934,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c /* 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 -@@ -1778,8 +2108,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1777,8 +2107,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2959,7 +2959,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c line->keybeg = line_start; } } -@@ -1900,7 +2244,7 @@ human_numcompare (char const *a, char co +@@ -1899,7 +2243,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2968,7 +2968,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1910,6 +2254,25 @@ numcompare (char const *a, char const *b +@@ -1909,6 +2253,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2994,7 +2994,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c /* 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 once -@@ -1960,7 +2323,7 @@ general_numcompare (char const *sa, char +@@ -1959,7 +2322,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -3003,7 +3003,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2235,15 +2598,14 @@ debug_key (struct line const *line, stru +@@ -2234,15 +2597,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -3021,7 +3021,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2387,7 +2749,7 @@ key_warnings (struct keyfield const *gke +@@ -2386,7 +2748,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3030,8 +3030,8 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2445,11 +2807,83 @@ key_warnings (struct keyfield const *gke - error (0, 0, _("option `-r' only applies to last-resort comparison")); +@@ -2444,11 +2806,83 @@ key_warnings (struct keyfield const *gke + error (0, 0, _("option '-r' only applies to last-resort comparison")); } +#if HAVE_MBRTOWC @@ -3115,7 +3115,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c { struct keyfield *key = keylist; -@@ -2534,7 +2968,7 @@ keycompare (struct line const *a, struct +@@ -2533,7 +2967,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3124,7 +3124,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2650,6 +3084,180 @@ keycompare (struct line const *a, struct +@@ -2649,6 +3083,180 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3305,7 +3305,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4110,7 +4718,7 @@ main (int argc, char **argv) +@@ -4109,7 +4717,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3314,7 +3314,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4131,6 +4739,29 @@ main (int argc, char **argv) +@@ -4130,6 +4738,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3344,7 +3344,7 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c have_read_stdin = false; inittables (); -@@ -4401,13 +5032,34 @@ main (int argc, char **argv) +@@ -4400,13 +5031,34 @@ main (int argc, char **argv) case 't': { @@ -3382,8 +3382,8 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c + newtab[0] = '\0'; else { - /* Provoke with `sort -txx'. Complain about -@@ -4418,9 +5070,12 @@ main (int argc, char **argv) + /* Provoke with 'sort -txx'. Complain about +@@ -4417,9 +5069,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3398,10 +3398,10 @@ diff -urNp coreutils-8.15-orig/src/sort.c coreutils-8.15/src/sort.c } break; -diff -urNp coreutils-8.15-orig/src/unexpand.c coreutils-8.15/src/unexpand.c ---- coreutils-8.15-orig/src/unexpand.c 2012-01-01 10:04:06.000000000 +0100 -+++ coreutils-8.15/src/unexpand.c 2012-03-07 21:25:39.517457874 +0100 -@@ -39,12 +39,29 @@ +diff -urNp coreutils-8.16-orig/src/unexpand.c coreutils-8.16/src/unexpand.c +--- coreutils-8.16-orig/src/unexpand.c 2012-03-24 21:26:51.000000000 +0100 ++++ coreutils-8.16/src/unexpand.c 2012-03-26 17:51:46.000000000 +0200 +@@ -38,12 +38,29 @@ #include #include #include @@ -3428,10 +3428,10 @@ diff -urNp coreutils-8.15-orig/src/unexpand.c coreutils-8.15/src/unexpand.c +# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) +#endif + - /* The official name of this program (e.g., no `g' prefix). */ + /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "unexpand" -@@ -104,6 +121,208 @@ static struct option const longopts[] = +@@ -103,6 +120,208 @@ static struct option const longopts[] = {NULL, 0, NULL, 0} }; @@ -3640,7 +3640,7 @@ diff -urNp coreutils-8.15-orig/src/unexpand.c coreutils-8.15/src/unexpand.c void usage (int status) { -@@ -526,7 +745,12 @@ main (int argc, char **argv) +@@ -524,7 +743,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -3654,9 +3654,9 @@ diff -urNp coreutils-8.15-orig/src/unexpand.c coreutils-8.15/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c ---- coreutils-8.15-orig/src/uniq.c 2012-01-01 10:04:06.000000000 +0100 -+++ coreutils-8.15/src/uniq.c 2012-03-07 21:25:39.519460555 +0100 +diff -urNp coreutils-8.16-orig/src/uniq.c coreutils-8.16/src/uniq.c +--- coreutils-8.16-orig/src/uniq.c 2012-03-24 21:26:51.000000000 +0100 ++++ coreutils-8.16/src/uniq.c 2012-03-26 17:35:09.000000000 +0200 @@ -21,6 +21,16 @@ #include #include @@ -3693,7 +3693,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c +#endif + - /* The official name of this program (e.g., no `g' prefix). */ + /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" @@ -108,6 +130,10 @@ static enum delimit_method const delimit /* Select whether/how to delimit groups of duplicate lines. */ @@ -3706,7 +3706,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -207,7 +233,7 @@ size_opt (char const *opt, char const *m +@@ -206,7 +232,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 @@ -3715,7 +3715,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -227,6 +253,83 @@ find_field (struct linebuffer const *lin +@@ -226,6 +252,83 @@ find_field (struct linebuffer const *lin return line->buffer + i; } @@ -3799,7 +3799,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c /* 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. -@@ -235,6 +338,8 @@ find_field (struct linebuffer const *lin +@@ -234,6 +337,8 @@ find_field (struct linebuffer const *lin static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -3808,7 +3808,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -242,14 +347,92 @@ different (char *old, char *new, size_t +@@ -241,14 +346,92 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3906,7 +3906,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -305,15 +488,43 @@ check_file (const char *infile, const ch +@@ -304,15 +487,43 @@ check_file (const char *infile, const ch { char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); @@ -3950,7 +3950,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c if (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)) { -@@ -332,17 +543,26 @@ check_file (const char *infile, const ch +@@ -331,17 +542,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -3977,7 +3977,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -351,6 +571,14 @@ check_file (const char *infile, const ch +@@ -350,6 +570,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -3992,7 +3992,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -383,6 +611,9 @@ check_file (const char *infile, const ch +@@ -382,6 +610,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4002,7 +4002,7 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c if (!match) match_count = 0; } -@@ -428,6 +659,19 @@ main (int argc, char **argv) +@@ -427,6 +658,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4022,18 +4022,18 @@ diff -urNp coreutils-8.15-orig/src/uniq.c coreutils-8.15/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.15-orig/tests/Makefile.am coreutils-8.15/tests/Makefile.am ---- coreutils-8.15-orig/tests/Makefile.am 2012-03-07 21:25:03.149233957 +0100 -+++ coreutils-8.15/tests/Makefile.am 2012-03-07 21:25:39.520458288 +0100 -@@ -240,6 +240,7 @@ TESTS = \ - misc/sort-debug-keys \ +diff -urNp coreutils-8.16-orig/tests/Makefile.am coreutils-8.16/tests/Makefile.am +--- coreutils-8.16-orig/tests/Makefile.am 2012-03-26 18:01:35.564014659 +0200 ++++ coreutils-8.16/tests/Makefile.am 2012-03-26 18:02:01.023015013 +0200 +@@ -242,6 +242,7 @@ TESTS = \ misc/sort-debug-warn \ + misc/sort-discrim \ misc/sort-files0-from \ + misc/sort-mb-tests \ misc/sort-float \ misc/sort-merge \ misc/sort-merge-fdlimit \ -@@ -526,6 +527,10 @@ TESTS = \ +@@ -537,6 +538,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -4044,9 +4044,9 @@ diff -urNp coreutils-8.15-orig/tests/Makefile.am coreutils-8.15/tests/Makefile.a pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.15-orig/tests/misc/cut coreutils-8.15/tests/misc/cut ---- coreutils-8.15-orig/tests/misc/cut 2012-01-01 10:04:06.000000000 +0100 -+++ coreutils-8.15/tests/misc/cut 2012-03-07 21:25:39.521460928 +0100 +diff -urNp coreutils-8.16-orig/tests/misc/cut coreutils-8.16/tests/misc/cut +--- coreutils-8.16-orig/tests/misc/cut 2012-02-03 10:22:06.000000000 +0100 ++++ coreutils-8.16/tests/misc/cut 2012-03-26 17:40:49.000000000 +0200 @@ -23,14 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4060,7 +4060,7 @@ diff -urNp coreutils-8.15-orig/tests/misc/cut coreutils-8.15/tests/misc/cut +my $mb_locale = 'C'; my $prog = 'cut'; - my $try = "Try \`$prog --help' for more information.\n"; + my $try = "Try '$prog --help' for more information.\n"; my $from_1 = "$prog: fields and positions are numbered from 1\n$try"; -my $inval = "$prog: invalid byte or field list\n$try"; +my $inval = "$prog: invalid byte, character or field list\n$try"; @@ -4076,41 +4076,41 @@ diff -urNp coreutils-8.15-orig/tests/misc/cut coreutils-8.15/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, -diff -urNp coreutils-8.15-orig/tests/misc/mb1.I coreutils-8.15/tests/misc/mb1.I ---- coreutils-8.15-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.15/tests/misc/mb1.I 2012-03-07 21:25:39.521460928 +0100 +diff -urNp coreutils-8.16-orig/tests/misc/mb1.I coreutils-8.16/tests/misc/mb1.I +--- coreutils-8.16-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.16/tests/misc/mb1.I 2012-03-26 17:35:09.000000000 +0200 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.15-orig/tests/misc/mb1.X coreutils-8.15/tests/misc/mb1.X ---- coreutils-8.15-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.15/tests/misc/mb1.X 2012-03-07 21:25:39.522458368 +0100 +diff -urNp coreutils-8.16-orig/tests/misc/mb1.X coreutils-8.16/tests/misc/mb1.X +--- coreutils-8.16-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.16/tests/misc/mb1.X 2012-03-26 17:35:09.000000000 +0200 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.15-orig/tests/misc/mb2.I coreutils-8.15/tests/misc/mb2.I ---- coreutils-8.15-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.15/tests/misc/mb2.I 2012-03-07 21:25:39.523458000 +0100 +diff -urNp coreutils-8.16-orig/tests/misc/mb2.I coreutils-8.16/tests/misc/mb2.I +--- coreutils-8.16-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.16/tests/misc/mb2.I 2012-03-26 17:35:09.000000000 +0200 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.15-orig/tests/misc/mb2.X coreutils-8.15/tests/misc/mb2.X ---- coreutils-8.15-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.15/tests/misc/mb2.X 2012-03-07 21:25:39.523458000 +0100 +diff -urNp coreutils-8.16-orig/tests/misc/mb2.X coreutils-8.16/tests/misc/mb2.X +--- coreutils-8.16-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.16/tests/misc/mb2.X 2012-03-26 17:35:09.000000000 +0200 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.15-orig/tests/misc/sort-mb-tests coreutils-8.15/tests/misc/sort-mb-tests ---- coreutils-8.15-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.15/tests/misc/sort-mb-tests 2012-03-07 21:25:39.524460637 +0100 +diff -urNp coreutils-8.16-orig/tests/misc/sort-mb-tests coreutils-8.16/tests/misc/sort-mb-tests +--- coreutils-8.16-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.16/tests/misc/sort-mb-tests 2012-03-26 17:35:09.000000000 +0200 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 3e5c143..0db3acb 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -392,7 +392,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c || format_needs_stat @@ -2869,7 +2896,7 @@ gobble_file (char const *name, enum file && print_with_color && is_colored (C_CAP)) - f->has_capability = has_capability (absolute_name); + f->has_capability = has_capability_cache (absolute_name, f); - if (format == long_format || print_scontext) + if (format == long_format || format == security_format || print_scontext) @@ -406,7 +406,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c - if (err == 0 && format == long_format) + if (err == 0 && (format == long_format || format == security_format)) { - int n = file_has_acl (absolute_name, &f->stat); + int n = file_has_acl_cache (absolute_name, f); err = (n < 0); @@ -2911,7 +2938,8 @@ gobble_file (char const *name, enum file } diff --git a/coreutils.spec b/coreutils.spec index 2028343..c9a78e8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.15 -Release: 8%{?dist} +Version: 8.16 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,8 +18,6 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -# fix regression in du -x with nondir argument -Patch1: coreutils-8.15-du-x-nondir.patch # Our patches #general patch to workaround koji build system issues @@ -145,7 +143,6 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream -%patch1 -p1 -b .xnondir # Our patches %patch100 -p1 -b .configure @@ -419,6 +416,10 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Mon Mar 26 2012 Ondrej Vasik 8.16-1 +- new upstream release 8.16 +- defuzz patches, remove already applied patches + * Thu Mar 08 2012 Ondrej Vasik 8.15-8 - fix regression in du -x with nondir argument (by J.Meyering) diff --git a/sources b/sources index db9edbd..6df33ae 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -094909fafa86110140b32e4948941545 coreutils-8.15.tar.xz +89b06f91634208dceba7b36ad1f9e8b9 coreutils-8.16.tar.xz From 6972fb24fae8af1523c402490763574ca6417c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 16 Apr 2012 07:46:17 +0200 Subject: [PATCH 165/523] fix the tcsh colorls.csh behaviour in non-interactive mode (#804604) --- coreutils-colorls.csh | 2 +- coreutils.spec | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 48daa78..0c1b2e3 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -16,7 +16,7 @@ if ($?TERM) then endif endif if ( -e "/etc/DIR_COLORS.256color" ) then - if ( "`tty -s && tput colors`" == "256" ) then + if ( "`tty -s` && tput colors" == "256" ) then set COLORS=/etc/DIR_COLORS.256color endif endif diff --git a/coreutils.spec b/coreutils.spec index c9a78e8..7e0976e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.16 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -416,6 +416,10 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Mon Apr 16 2012 Ondrej Vasik 8.16-2 +- fix the tcsh colorls.csh behaviour in non-interactive + mode (#804604) + * Mon Mar 26 2012 Ondrej Vasik 8.16-1 - new upstream release 8.16 - defuzz patches, remove already applied patches From 9a7f541e9b6eaa223be4b063d0a875d0c678ce08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 17 Apr 2012 15:02:56 +0200 Subject: [PATCH 166/523] This seems to be better fix ;) for noninteractive mode --- coreutils-colorls.csh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 0c1b2e3..e244afb 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -14,10 +14,10 @@ if ($?TERM) then if ( -e "/etc/DIR_COLORS.$TERM" ) then set COLORS="/etc/DIR_COLORS.$TERM" endif -endif -if ( -e "/etc/DIR_COLORS.256color" ) then - if ( "`tty -s` && tput colors" == "256" ) then - set COLORS=/etc/DIR_COLORS.256color + if ( -e "/etc/DIR_COLORS.256color" ) then + if ( "`tput colors`" == "256" ) then + set COLORS=/etc/DIR_COLORS.256color + endif endif endif if ( -f ~/.dircolors ) set COLORS=~/.dircolors From 618e4683306ebfb06914561f2d01e2d648321714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 4 May 2012 12:33:37 +0200 Subject: [PATCH 167/523] add .htm and .shtml to colorized DIR_COLORS document type (#817218) --- coreutils-DIR_COLORS | 2 ++ coreutils-DIR_COLORS.256color | 2 ++ coreutils-DIR_COLORS.lightbgcolor | 2 ++ coreutils.spec | 6 +++++- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 5a41e99..9c182c8 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -240,5 +240,7 @@ EXEC 01;32 .xml 00;33 .epub 00;33 .abw 00;33 +.htm 00;33 .html 00;33 +.shtml 00;33 .wpd 00;33 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index ddff4ac..1037dd5 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -213,5 +213,7 @@ EXEC 38;5;34 .xml 00;33 .epub 00;33 .abw 00;33 +.htm 00;33 .html 00;33 +.shtml 00;33 .wpd 00;33 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index e2c05da..4456a8c 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -216,5 +216,7 @@ EXEC 00;32 .xml 00;33 .epub 00;33 .abw 00;33 +.htm 00;33 .html 00;33 +.shtml 00;33 .wpd 00;33 diff --git a/coreutils.spec b/coreutils.spec index 7e0976e..e574ded 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.16 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -416,6 +416,10 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Fri May 04 2012 Ondrej Vasik 8.16-3 +- add .htm and .shtml to colorized DIR_COLORS document + type (#817218) + * Mon Apr 16 2012 Ondrej Vasik 8.16-2 - fix the tcsh colorls.csh behaviour in non-interactive mode (#804604) From 315471e18a21148a14e6877a59458a6db57950e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 11 May 2012 09:58:08 +0200 Subject: [PATCH 168/523] new upstream release 8.17, defuzz patches --- .gitignore | 1 + coreutils-6.10-configuration.patch | 10 +++++----- coreutils-i18n.patch | 21 +++++++++++---------- coreutils-selinux.patch | 24 ++++++++++++------------ coreutils.spec | 7 +++++-- sources | 2 +- 6 files changed, 35 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index ab26cd4..c059bb4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /coreutils-8.14.tar.xz /coreutils-8.15.tar.xz /coreutils-8.16.tar.xz +/coreutils-8.17.tar.xz diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 1e3be91..7f5e6ee 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -111,13 +111,13 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module utimens-tests -diff -urNp coreutils-8.13-orig/tests/Makefile.am coreutils-8.13/tests/Makefile.am ---- coreutils-8.13-orig/tests/Makefile.am 2011-09-02 14:08:40.000000000 +0200 -+++ coreutils-8.13/tests/Makefile.am 2011-09-09 10:12:56.364814725 +0200 -@@ -86,7 +86,6 @@ TESTS = \ - rm/ext3-perf \ +diff -urNp coreutils-8.17-orig/tests/Makefile.am coreutils-8.17/tests/Makefile.am +--- coreutils-8.17-orig/tests/Makefile.am ++++ coreutils-8.17/tests/Makefile.am +@@ -87,7 +87,6 @@ TESTS = \ rm/cycle \ cp/link-heap \ + misc/tty-eof \ - tail-2/inotify-hash-abuse \ tail-2/inotify-hash-abuse2 \ tail-2/F-vs-missing \ diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index ee2cf73..5b0d3b8 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2003,13 +2003,13 @@ diff -urNp coreutils-8.16-orig/src/pr.c coreutils-8.16/src/pr.c } /* It's rather pointless to define a TAB separator with column @@ -1279,11 +1410,11 @@ init_parameters (int number_of_files) - TAB_WIDTH (chars_per_input_tab, chars_per_number); */ + + 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); + 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; @@ -2019,9 +2019,9 @@ diff -urNp coreutils-8.16-orig/src/pr.c coreutils-8.16/src/pr.c @@ -1298,7 +1429,7 @@ init_parameters (int number_of_files) } - chars_per_column = (chars_per_line - chars_used_by_number - -- (columns - 1) * col_sep_length) / columns; -+ (columns - 1) * col_sep_width) / columns; + chars_per_column = (chars_per_line - chars_used_by_number +- - (columns - 1) * col_sep_length) / columns; ++ - (columns - 1) * col_sep_width) / columns; if (chars_per_column < 1) error (EXIT_FAILURE, 0, _("page width too narrow")); @@ -2447,16 +2447,17 @@ diff -urNp coreutils-8.16-orig/src/pr.c coreutils-8.16/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.16-orig/src/sort.c coreutils-8.16/src/sort.c ---- coreutils-8.16-orig/src/sort.c 2012-03-24 21:26:51.000000000 +0100 -+++ coreutils-8.16/src/sort.c 2012-03-26 17:35:09.000000000 +0200 -@@ -22,11 +22,20 @@ +diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c +--- coreutils-8.17-orig/src/sort.c ++++ coreutils-8.17/src/sort.c +@@ -22,12 +22,21 @@ #include +#include #include #include + #include #include #include #include diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 0db3acb..501b33e 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -416,8 +416,8 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c + && (format == long_format || format == security_format + || check_symlink_color)) { - char *linkname; struct stat linkstats; + @@ -2931,6 +2959,7 @@ gobble_file (char const *name, enum file command line are automatically traced if not being listed as files. */ @@ -628,29 +628,29 @@ diff -urNp coreutils-8.13-orig/src/runcon.c coreutils-8.13/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urNp coreutils-8.13-orig/tests/init.cfg coreutils-8.13/tests/init.cfg ---- coreutils-8.13-orig/tests/init.cfg 2011-09-07 18:00:55.000000000 +0200 -+++ coreutils-8.13/tests/init.cfg 2011-09-09 10:32:17.031688699 +0200 +diff -urNp coreutils-8.17-orig/tests/init.cfg coreutils-8.17/tests/init.cfg +--- coreutils-8.17-orig/tests/init.cfg ++++ coreutils-8.17/tests/init.cfg @@ -253,8 +253,8 @@ require_selinux_() # Independent of whether SELinux is enabled system-wide, # the current file system may lack SELinux support. -- case `ls -Zd .` in +- case $(ls -Zd .) in - '? .'|'unlabeled .') -+ case `ls -Zd . | cut -f4 -d" "` in ++ case $(ls -Zd . | cut -f4 -d" ") in + '?'|'unlabeled') skip_ "this system (or maybe just" \ "the current file system) lacks SELinux support" ;; -diff -urNp coreutils-8.13-orig/tests/misc/selinux coreutils-8.13/tests/misc/selinux ---- coreutils-8.13-orig/tests/misc/selinux 2011-08-08 09:42:16.000000000 +0200 -+++ coreutils-8.13/tests/misc/selinux 2011-09-09 10:30:39.586563144 +0200 +diff -urNp coreutils-8.17-orig/tests/misc/selinux coreutils-8.17/tests/misc/selinux +--- coreutils-8.17-orig/tests/misc/selinux ++++ coreutils-8.17/tests/misc/selinux @@ -37,7 +37,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. for i in d f p; do -- c=`ls -dogZ $i|cut -d' ' -f3`; test x$c = x$ctx || fail=1 -+ c=`ls -dogZ $i|cut -d' ' -f4`; test x$c = x$ctx || fail=1 - c=`stat --printf %C $i`; test x$c = x$ctx || fail=1 +- c=$(ls -dogZ $i|cut -d' ' -f3); test x$c = x$ctx || fail=1 ++ c=$(ls -dogZ $i|cut -d' ' -f4); test x$c = x$ctx || fail=1 + c=$(stat --printf %C $i); test x$c = x$ctx || fail=1 done diff --git a/coreutils.spec b/coreutils.spec index e574ded..9e81b26 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.16 -Release: 3%{?dist} +Version: 8.17 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -416,6 +416,9 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Fri May 11 2012 Ondrej Vasik 8.17-1 +- new upstream release 8.17 + * Fri May 04 2012 Ondrej Vasik 8.16-3 - add .htm and .shtml to colorized DIR_COLORS document type (#817218) diff --git a/sources b/sources index 6df33ae..44109bd 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -89b06f91634208dceba7b36ad1f9e8b9 coreutils-8.16.tar.xz +bbda656ce8ca2c6903948f9faa204ba3 coreutils-8.17.tar.xz From bfd5cf1204e2cc45f04d4e270b9c8e040e847ac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 11 May 2012 21:19:04 +0200 Subject: [PATCH 169/523] ls: upstream fix - correctly show symlinks in / --- coreutils-8.17-ls-rootdir-symlink.patch | 21 +++++++++++++++++++++ coreutils.spec | 7 ++++++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.17-ls-rootdir-symlink.patch diff --git a/coreutils-8.17-ls-rootdir-symlink.patch b/coreutils-8.17-ls-rootdir-symlink.patch new file mode 100644 index 0000000..7227afe --- /dev/null +++ b/coreutils-8.17-ls-rootdir-symlink.patch @@ -0,0 +1,21 @@ +diff -urNp coreutils-8.17-orig/src/ls.c coreutils-8.17/src/ls.c +--- coreutils-8.17-orig/src/ls.c 2012-05-11 20:59:01.467946060 +0200 ++++ coreutils-8.17/src/ls.c 2012-05-11 21:00:38.276821883 +0200 +@@ -3206,14 +3206,9 @@ make_link_name (char const *name, char const *linkname) + if (IS_ABSOLUTE_FILE_NAME (linkname)) + return xstrdup (linkname); + +- /* The link is to a relative name. Prepend any leading directory +- in 'name' to the link name. */ +- size_t prefix_len = dir_len (name); +- if (prefix_len == 0) +- return xstrdup (linkname); +- +- char *p = xmalloc (prefix_len + 1 + strlen (linkname) + 1); +- stpcpy (stpncpy (p, name, prefix_len + 1), linkname); ++ char *d = dir_name (name); ++ char *p = file_name_concat (d, linkname, NULL); ++ free (d); + return p; + } + diff --git a/coreutils.spec b/coreutils.spec index 9e81b26..628b7f9 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.17 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,6 +18,7 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream +Patch1: coreutils-8.17-ls-rootdir-symlink.patch # Our patches #general patch to workaround koji build system issues @@ -143,6 +144,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream +%patch1 -p1 -b .roodirsymlink # Our patches %patch100 -p1 -b .configure @@ -416,6 +418,9 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Fri May 11 2012 Ondrej Vasik 8.17-2 +- ls: upstream fix - correctly show symlinks in / + * Fri May 11 2012 Ondrej Vasik 8.17-1 - new upstream release 8.17 From 1a367d9c9a253ed2d35d464908c0a5e0b0b3cc94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 15 May 2012 16:26:25 +0200 Subject: [PATCH 170/523] add virtual provides for bundled(gnulib) copylib (#821748) --- coreutils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 628b7f9..b195307 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.17 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -128,6 +128,7 @@ Provides: stat = %{version}-%{release} Provides: textutils = %{version}-%{release} #old mktemp package had epoch 3, so we have to use 4 for coreutils Provides: mktemp = 4:%{version}-%{release} +Provides: bundled(gnulib) Obsoletes: mktemp < 4:%{version}-%{release} Obsoletes: fileutils <= 4.1.9 Obsoletes: sh-utils <= 2.0.12 @@ -418,6 +419,9 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Tue May 15 2012 Ondrej Vasik 8.16-3 +- add virtual provides for bundled(gnulib) copylib (#821748) + * Fri May 11 2012 Ondrej Vasik 8.17-2 - ls: upstream fix - correctly show symlinks in / From 5427c82f631e7187fb1e3d633176cde01e45e134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 13 Jul 2012 13:06:03 +0200 Subject: [PATCH 171/523] fix typo in changelog --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index b195307..cfb9296 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -419,7 +419,7 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog -* Tue May 15 2012 Ondrej Vasik 8.16-3 +* Tue May 15 2012 Ondrej Vasik 8.17-3 - add virtual provides for bundled(gnulib) copylib (#821748) * Fri May 11 2012 Ondrej Vasik 8.17-2 From 28e1367cfe9615edc3a90e8b3bd22b53f1126d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Wed, 18 Jul 2012 17:52:03 +0100 Subject: [PATCH 172/523] ls: remove the default brown coloring of documents We leave the list commented out to ease configuration for those who want this. There were two main reasons for removing this default coloring: 1. There are many text file extensions and text files without extensions. You couldn't hope to cover them all, and only covering a subset introduces inconsistency. 2. Greatly increasing the amount of coloring for these very common text files, reduces the "highlighting" effect of coloring in general. --- coreutils-DIR_COLORS | 54 ++++++++++++++++--------------- coreutils-DIR_COLORS.256color | 54 ++++++++++++++++--------------- coreutils-DIR_COLORS.lightbgcolor | 54 ++++++++++++++++--------------- 3 files changed, 84 insertions(+), 78 deletions(-) diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 9c182c8..5683e39 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -218,29 +218,31 @@ EXEC 01;32 .spx 01;36 .xspf 01;36 -# colorize basic documents (brown) -.pdf 00;33 -.ps 00;33 -.ps.gz 00;33 -.txt 00;33 -.patch 00;33 -.diff 00;33 -.log 00;33 -.tex 00;33 -.xls 00;33 -.xlsx 00;33 -.ppt 00;33 -.pptx 00;33 -.rtf 00;33 -.doc 00;33 -.docx 00;33 -.odt 00;33 -.ods 00;33 -.odp 00;33 -.xml 00;33 -.epub 00;33 -.abw 00;33 -.htm 00;33 -.html 00;33 -.shtml 00;33 -.wpd 00;33 +# colorize binary documents (brown) +#.pdf 00;33 +#.ps 00;33 +#.ps.gz 00;33 +#.tex 00;33 +#.xls 00;33 +#.xlsx 00;33 +#.ppt 00;33 +#.pptx 00;33 +#.rtf 00;33 +#.doc 00;33 +#.docx 00;33 +#.odt 00;33 +#.ods 00;33 +#.odp 00;33 +#.epub 00;33 +#.abw 00;33 +#.wpd 00;33 +# +# colorize text documents (brown) +#.txt 00;33 +#.patch 00;33 +#.diff 00;33 +#.log 00;33 +#.htm 00;33 +#.html 00;33 +#.shtml 00;33 +#.xml 00;33 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 1037dd5..14e27d4 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -191,29 +191,31 @@ EXEC 38;5;34 .spx 38;5;45 .xspf 38;5;45 -# colorize basic documents as well (brown) -.pdf 00;33 -.ps 00;33 -.ps.gz 00;33 -.txt 00;33 -.patch 00;33 -.diff 00;33 -.log 00;33 -.tex 00;33 -.xls 00;33 -.xlsx 00;33 -.ppt 00;33 -.pptx 00;33 -.rtf 00;33 -.doc 00;33 -.docx 00;33 -.odt 00;33 -.ods 00;33 -.odp 00;33 -.xml 00;33 -.epub 00;33 -.abw 00;33 -.htm 00;33 -.html 00;33 -.shtml 00;33 -.wpd 00;33 +# colorize binary documents (brown) +#.pdf 00;33 +#.ps 00;33 +#.ps.gz 00;33 +#.tex 00;33 +#.xls 00;33 +#.xlsx 00;33 +#.ppt 00;33 +#.pptx 00;33 +#.rtf 00;33 +#.doc 00;33 +#.docx 00;33 +#.odt 00;33 +#.ods 00;33 +#.odp 00;33 +#.epub 00;33 +#.abw 00;33 +#.wpd 00;33 +# +# colorize text documents (brown) +#.txt 00;33 +#.patch 00;33 +#.diff 00;33 +#.log 00;33 +#.htm 00;33 +#.html 00;33 +#.shtml 00;33 +#.xml 00;33 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index 4456a8c..ac46288 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -194,29 +194,31 @@ EXEC 00;32 .spx 00;36 .xspf 00;36 -# colorize basic documents (brown) -.pdf 00;33 -.ps 00;33 -.ps.gz 00;33 -.txt 00;33 -.patch 00;33 -.diff 00;33 -.log 00;33 -.tex 00;33 -.xls 00;33 -.xlsx 00;33 -.ppt 00;33 -.pptx 00;33 -.rtf 00;33 -.doc 00;33 -.docx 00;33 -.odt 00;33 -.ods 00;33 -.odp 00;33 -.xml 00;33 -.epub 00;33 -.abw 00;33 -.htm 00;33 -.html 00;33 -.shtml 00;33 -.wpd 00;33 +# colorize binary documents (brown) +#.pdf 00;33 +#.ps 00;33 +#.ps.gz 00;33 +#.tex 00;33 +#.xls 00;33 +#.xlsx 00;33 +#.ppt 00;33 +#.pptx 00;33 +#.rtf 00;33 +#.doc 00;33 +#.docx 00;33 +#.odt 00;33 +#.ods 00;33 +#.odp 00;33 +#.epub 00;33 +#.abw 00;33 +#.wpd 00;33 +# +# colorize text documents (brown) +#.txt 00;33 +#.patch 00;33 +#.diff 00;33 +#.log 00;33 +#.htm 00;33 +#.html 00;33 +#.shtml 00;33 +#.xml 00;33 From 0c6cba0357e6bba44e299fa100653cf42fc1d71f Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Wed, 18 Jul 2012 14:41:27 -0500 Subject: [PATCH 173/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index cfb9296..9281d4d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.17 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -419,6 +419,9 @@ fi %{?!norunuser:%{_sbindir}/runuser} %changelog +* Wed Jul 18 2012 Fedora Release Engineering - 8.17-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + * Tue May 15 2012 Ondrej Vasik 8.17-3 - add virtual provides for bundled(gnulib) copylib (#821748) From 89d1aa92a0bb049f0e613d9642f6dfa3255610e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 13 Aug 2012 00:14:40 +0200 Subject: [PATCH 174/523] New upstream release changes, su/runuser ones just commented out atm, don't build --- .gitignore | 1 + coreutils-7.4-sttytcsadrain.patch | 2 +- coreutils-8.17-ls-rootdir-symlink.patch | 21 -------- coreutils-df-direct.patch | 10 ++-- coreutils-i18n.patch | 11 +---- coreutils-selinux.patch | 2 +- coreutils-selinuxmanpages.patch | 2 +- coreutils.spec | 66 +++++++++++++------------ sh-utils-1.16-paths.patch | 18 ------- sources | 2 +- 10 files changed, 46 insertions(+), 89 deletions(-) delete mode 100644 coreutils-8.17-ls-rootdir-symlink.patch delete mode 100644 sh-utils-1.16-paths.patch diff --git a/.gitignore b/.gitignore index c059bb4..4ed2e84 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /coreutils-8.15.tar.xz /coreutils-8.16.tar.xz /coreutils-8.17.tar.xz +/coreutils-8.18.tar.xz diff --git a/coreutils-7.4-sttytcsadrain.patch b/coreutils-7.4-sttytcsadrain.patch index fe83798..bc3f47b 100644 --- a/coreutils-7.4-sttytcsadrain.patch +++ b/coreutils-7.4-sttytcsadrain.patch @@ -3,7 +3,7 @@ diff -urNp coreutils-8.13-orig/src/stty.c coreutils-8.13/src/stty.c +++ coreutils-8.13/src/stty.c 2011-09-09 10:18:57.526687209 +0200 @@ -1005,7 +1005,7 @@ main (int argc, char **argv) spurious difference in an uninitialized portion of the structure. */ - struct termios new_mode = { 0, }; + static struct termios new_mode; - if (tcsetattr (STDIN_FILENO, TCSADRAIN, &mode)) + if (tcsetattr (STDIN_FILENO, TCSANOW, &mode)) diff --git a/coreutils-8.17-ls-rootdir-symlink.patch b/coreutils-8.17-ls-rootdir-symlink.patch deleted file mode 100644 index 7227afe..0000000 --- a/coreutils-8.17-ls-rootdir-symlink.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -urNp coreutils-8.17-orig/src/ls.c coreutils-8.17/src/ls.c ---- coreutils-8.17-orig/src/ls.c 2012-05-11 20:59:01.467946060 +0200 -+++ coreutils-8.17/src/ls.c 2012-05-11 21:00:38.276821883 +0200 -@@ -3206,14 +3206,9 @@ make_link_name (char const *name, char const *linkname) - if (IS_ABSOLUTE_FILE_NAME (linkname)) - return xstrdup (linkname); - -- /* The link is to a relative name. Prepend any leading directory -- in 'name' to the link name. */ -- size_t prefix_len = dir_len (name); -- if (prefix_len == 0) -- return xstrdup (linkname); -- -- char *p = xmalloc (prefix_len + 1 + strlen (linkname) + 1); -- stpcpy (stpncpy (p, name, prefix_len + 1), linkname); -+ char *d = dir_name (name); -+ char *p = file_name_concat (d, linkname, NULL); -+ free (d); - return p; - } - diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 14d1c44..937c183 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -5,14 +5,14 @@ diff -urNp coreutils-8.16-orig/doc/coreutils.texi coreutils-8.16/doc/coreutils.t Scale sizes by @var{size} before printing them (@pxref{Block size}). For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. -+@itemx --direct ++@item --direct +@opindex --direct +@cindex direct statfs for a file +Do not resolve mount point and show statistics directly for a file. It can be +especially useful for NFS mount points if there is a boundary between two +storage policies behind the mount point. + - @itemx --total + @item --total @opindex --total @cindex grand total of disk size, usage and available space diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c @@ -29,11 +29,11 @@ diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c static struct fs_usage grand_fsu; @@ -167,13 +170,15 @@ static size_t nrows; - enum { NO_SYNC_OPTION = CHAR_MAX + 1, -- SYNC_OPTION -+ SYNC_OPTION, + SYNC_OPTION, +- MEGABYTES_OPTION /* FIXME: remove long opt in Aug 2013 */ ++ MEGABYTES_OPTION, /* FIXME: remove long opt in Aug 2013 */ + DIRECT_OPTION }; diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 5b0d3b8..925c85c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2450,17 +2450,10 @@ diff -urNp coreutils-8.16-orig/src/pr.c coreutils-8.16/src/pr.c diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c --- coreutils-8.17-orig/src/sort.c +++ coreutils-8.17/src/sort.c -@@ -22,12 +22,21 @@ - - #include - -+#include - #include - #include - #include - #include +@@ -29,6 +29,14 @@ #include #include + #include +#if HAVE_WCHAR_H +# include +#endif diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 501b33e..89aa5fd 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -14,7 +14,7 @@ diff -urNp coreutils-8.13-orig/configure.ac coreutils-8.13/configure.ac + AC_FUNC_FORK - AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam], + optional_bin_progs= diff -urNp coreutils-8.13-orig/man/chcon.x coreutils-8.13/man/chcon.x --- coreutils-8.13-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 +++ coreutils-8.13/man/chcon.x 2011-09-09 10:30:39.524564991 +0200 diff --git a/coreutils-selinuxmanpages.patch b/coreutils-selinuxmanpages.patch index 9cbc166..7b27f90 100644 --- a/coreutils-selinuxmanpages.patch +++ b/coreutils-selinuxmanpages.patch @@ -2,7 +2,7 @@ diff -urNp coreutils-6.10-orig/doc/coreutils.texi coreutils-6.10/doc/coreutils.t --- coreutils-6.10-orig/doc/coreutils.texi 2008-04-07 17:52:11.000000000 +0200 +++ coreutils-6.10/doc/coreutils.texi 2008-04-07 18:01:43.000000000 +0200 @@ -6981,6 +6981,11 @@ for i; do - done + exit $fail @end example +@item -c diff --git a/coreutils.spec b/coreutils.spec index 9281d4d..bc95dd4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.17 -Release: 4%{?dist} +Version: 8.18 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -18,7 +18,6 @@ Source202: coreutils-su-l.pamd Source203: coreutils-runuser-l.pamd # From upstream -Patch1: coreutils-8.17-ls-rootdir-symlink.patch # Our patches #general patch to workaround koji build system issues @@ -38,26 +37,26 @@ Patch107: coreutils-8.4-mkdir-modenote.patch #add info about TZ envvar to date manpage Patch703: sh-utils-2.0.11-dateman.patch #set paths for su explicitly, don't get influenced by paths.h -Patch704: sh-utils-1.16-paths.patch +#Patch704: sh-utils-1.16-paths.patch # RMS will never accept the PAM patch because it removes his historical # rant about Twenex and the wheel group, so we'll continue to maintain # it here indefinitely. Patch is now the same in Fedora and SUSE. -Patch706: coreutils-8.5-pam.patch +#Patch706: coreutils-8.5-pam.patch Patch713: coreutils-4.5.3-langinfo.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch #Call setsid() in su under some circumstances (bug #173008). -Patch900: coreutils-setsid.patch +#Patch900: coreutils-setsid.patch #make runuser binary based on su.c -Patch907: coreutils-8.7-runuser.patch +#Patch907: coreutils-8.7-runuser.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch #Prevent buffer overflow in who(1) (bug #158405). Patch912: coreutils-overflow.patch #compile su with pie flag and RELRO protection -Patch917: coreutils-8.4-su-pie.patch +#Patch917: coreutils-8.4-su-pie.patch #SELINUX Patch - implements Redhat changes #(upstream did some SELinux implementation unlike with RedHat patch) @@ -107,7 +106,7 @@ BuildRequires: gettext bison BuildRequires: texinfo BuildRequires: autoconf BuildRequires: automake -%{?!nopam:BuildRequires: pam-devel} +#%{?!nopam:BuildRequires: pam-devel} BuildRequires: libcap-devel BuildRequires: libattr-devel BuildRequires: gmp-devel @@ -118,7 +117,7 @@ Requires(pre): /sbin/install-info Requires(preun): /sbin/install-info Requires(post): /sbin/install-info Requires(post): grep -%{?!nopam:Requires: pam >= 1.1.3-7} +#%{?!nopam:Requires: pam >= 1.1.3-7} Requires: ncurses Requires: gmp @@ -145,7 +144,6 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream -%patch1 -p1 -b .roodirsymlink # Our patches %patch100 -p1 -b .configure @@ -157,19 +155,19 @@ the old GNU fileutils, sh-utils, and textutils packages. # sh-utils %patch703 -p1 -b .dateman -%patch704 -p1 -b .paths -%patch706 -p1 -b .pam +#%patch704 -p1 -b .paths +#%patch706 -p1 -b .pam %patch713 -p1 -b .langinfo # li18nux/lsb %patch800 -p1 -b .i18n # Coreutils -%patch900 -p1 -b .setsid -%patch907 -p1 -b .runuser +#%patch900 -p1 -b .setsid +#%patch907 -p1 -b .runuser %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow -%patch917 -p1 -b .pie +#%patch917 -p1 -b .pie #SELinux %patch950 -p1 -b .selinux @@ -200,8 +198,8 @@ automake --copy --add-missing # Regenerate manpages touch man/*.x -make all %{?_smp_mflags} \ - %{?!nopam:CPPFLAGS="-DUSE_PAM"} +make all %{?_smp_mflags} +# %{?!nopam:CPPFLAGS="-DUSE_PAM"} # XXX docs should say /var/run/[uw]tmp not /etc/[uw]tmp sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi @@ -228,7 +226,7 @@ bzip2 -9f ChangeLog # let be compatible with old fileutils, sh-utils and textutils packages : mkdir -p $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}} -%{?!nopam:mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pam.d} +#%{?!nopam:mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pam.d} # chroot was in /usr/sbin : mv $RPM_BUILD_ROOT{%_bindir,%_sbindir}/chroot @@ -241,20 +239,20 @@ install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.s install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh # su -install -m 4755 src/su $RPM_BUILD_ROOT/%{_bindir} -%{?!norunuser:install -m 755 src/runuser $RPM_BUILD_ROOT/%{_sbindir}} +#install -m 4755 src/su $RPM_BUILD_ROOT/%{_bindir} +#%{?!norunuser:install -m 755 src/runuser $RPM_BUILD_ROOT/%{_sbindir}} # do not ship runuser in /usr/bin/runuser -rm -rf $RPM_BUILD_ROOT/%{_bindir}/runuser || : +#rm -rf $RPM_BUILD_ROOT/%{_bindir}/runuser || : # These come from util-linux and/or procps. for i in hostname uptime kill ; do rm $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1} done -%{?!nopam:install -p -m 644 %SOURCE200 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su} -%{?!nopam:install -p -m 644 %SOURCE202 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su-l} -%{?!nopam:install -p -m 644 %SOURCE201 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser} -%{?!nopam:install -p -m 644 %SOURCE203 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser-l} +#%{?!nopam:install -p -m 644 %SOURCE200 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su} +#%{?!nopam:install -p -m 644 %SOURCE202 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su-l} +#%{?!nopam:install -p -m 644 %SOURCE201 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser} +#%{?!nopam:install -p -m 644 %SOURCE203 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser-l} # Compress ChangeLogs from before the fileutils/textutils/etc merge bzip2 -f9 old/*/C* @@ -306,10 +304,10 @@ fi %dir %{_datadir}/locale/*/LC_TIME %config(noreplace) %{_sysconfdir}/DIR_COLORS* %config(noreplace) %{_sysconfdir}/profile.d/* -%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su} -%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su-l} -%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser} -%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser-l} +#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su} +#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su-l} +#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser} +#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser-l} %doc COPYING ABOUT-NLS ChangeLog.bz2 NEWS README THANKS TODO old/* %{_bindir}/arch %{_bindir}/basename @@ -339,7 +337,7 @@ fi %{_bindir}/sleep %{_bindir}/sort %{_bindir}/stty -%attr(4755,root,root) %{_bindir}/su +#%attr(4755,root,root) %{_bindir}/su %{_bindir}/sync %{_bindir}/mktemp %{_bindir}/touch @@ -416,9 +414,13 @@ fi %{_libexecdir}/coreutils* %{_mandir}/man*/* %{_sbindir}/chroot -%{?!norunuser:%{_sbindir}/runuser} +#%{?!norunuser:%{_sbindir}/runuser} %changelog +* Sun Aug 12 2012 Ondrej Vasik 8.18-1 +- new upstream release 8.18 +- su/runuser moved to util-linux + * Wed Jul 18 2012 Fedora Release Engineering - 8.17-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild diff --git a/sh-utils-1.16-paths.patch b/sh-utils-1.16-paths.patch deleted file mode 100644 index 00efc67..0000000 --- a/sh-utils-1.16-paths.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- sh-utils-1.16/src/su.c.badpaths Mon Apr 14 14:26:55 1997 -+++ sh-utils-1.16/src/su.c Sun Aug 17 14:11:31 EDT 2003 -@@ -147,6 +147,15 @@ - # define DEFAULT_ROOT_LOGIN_PATH "/usr/ucb:/bin:/usr/bin:/etc" - #endif - -+/* The default paths which get set are both bogus and oddly influenced -+ by and -D on the commands line. Just to be clear, we'll set -+ these explicitly. -ewt */ -+#undef DEFAULT_LOGIN_PATH -+#undef DEFAULT_ROOT_LOGIN_PATH -+#define DEFAULT_LOGIN_PATH "/usr/local/bin:/bin:/usr/bin" -+#define DEFAULT_ROOT_LOGIN_PATH \ -+ "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" -+ - /* The shell to run if none is given in the user's passwd entry. */ - #define DEFAULT_SHELL "/bin/sh" - diff --git a/sources b/sources index 44109bd..33abc66 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -bbda656ce8ca2c6903948f9faa204ba3 coreutils-8.17.tar.xz +74712fbb0e0dfcb883c90eab91982780 coreutils-8.18.tar.xz From 7ee630cc507f05d98e365e19e6288effca784cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 20 Aug 2012 12:07:28 +0200 Subject: [PATCH 175/523] New upstream release 8.19, remove everything related to su/runuser --- .gitignore | 1 + coreutils-8.4-su-pie.patch | 11 - coreutils-8.5-pam.patch | 422 ------------------------------------ coreutils-8.7-runuser.patch | 338 ----------------------------- coreutils-runuser-l.pamd | 4 - coreutils-runuser.pamd | 5 - coreutils-setsid.patch | 102 --------- coreutils-su-l.pamd | 6 - coreutils-su.pamd | 14 -- coreutils.spec | 48 +--- sources | 2 +- 11 files changed, 6 insertions(+), 947 deletions(-) delete mode 100644 coreutils-8.4-su-pie.patch delete mode 100644 coreutils-8.5-pam.patch delete mode 100644 coreutils-8.7-runuser.patch delete mode 100644 coreutils-runuser-l.pamd delete mode 100644 coreutils-runuser.pamd delete mode 100644 coreutils-setsid.patch delete mode 100644 coreutils-su-l.pamd delete mode 100644 coreutils-su.pamd diff --git a/.gitignore b/.gitignore index 4ed2e84..8d8414a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ /coreutils-8.16.tar.xz /coreutils-8.17.tar.xz /coreutils-8.18.tar.xz +/coreutils-8.19.tar.xz diff --git a/coreutils-8.4-su-pie.patch b/coreutils-8.4-su-pie.patch deleted file mode 100644 index b3fcaaf..0000000 --- a/coreutils-8.4-su-pie.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am ---- coreutils-8.4-orig/src/Makefile.am 2010-09-03 17:34:43.399747649 +0200 -+++ coreutils-8.4/src/Makefile.am 2010-09-03 17:36:13.005765125 +0200 -@@ -367,6 +367,7 @@ factor_LDADD += $(LIB_GMP) - - # for crypt and pam - su_LDADD += $(LIB_CRYPT) $(PAM_LIBS) -+su_LDFLAGS = -pie -Wl,-z,relro,-z,now - - # for various ACL functions - copy_LDADD += $(LIB_ACL) diff --git a/coreutils-8.5-pam.patch b/coreutils-8.5-pam.patch deleted file mode 100644 index 3d0e416..0000000 --- a/coreutils-8.5-pam.patch +++ /dev/null @@ -1,422 +0,0 @@ -diff -urNp coreutils-8.16-orig/configure.ac coreutils-8.16/configure.ac ---- coreutils-8.16-orig/configure.ac 2012-03-24 19:22:13.000000000 +0100 -+++ coreutils-8.16/configure.ac 2012-03-26 17:59:07.900139497 +0200 -@@ -185,6 +185,20 @@ fi - - AC_FUNC_FORK - -+AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam], -+ [Disable PAM support in su (default=auto)]), , [enable_pam=yes]) -+if test "x$enable_pam" != xno; then -+ AC_CHECK_LIB([pam], [pam_start], [enable_pam=yes], [enable_pam=no]) -+ AC_CHECK_LIB([pam_misc], [misc_conv], [:], [enable_pam=no]) -+ if test "x$enable_pam" != xno; then -+ AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) -+ PAM_LIBS="-lpam -lpam_misc" -+ AC_SUBST(PAM_LIBS) -+ fi -+fi -+AC_MSG_CHECKING([whether to enable PAM support in su]) -+AC_MSG_RESULT([$enable_pam]) -+ - optional_bin_progs= - AC_CHECK_FUNCS([chroot], - gl_ADD_PROG([optional_bin_progs], [chroot])) -diff -urNp coreutils-8.16-orig/doc/coreutils.texi coreutils-8.16/doc/coreutils.texi ---- coreutils-8.16-orig/doc/coreutils.texi 2012-03-26 17:58:27.624763998 +0200 -+++ coreutils-8.16/doc/coreutils.texi 2012-03-26 17:59:07.907138599 +0200 -@@ -15804,7 +15804,9 @@ the exit status of @var{command} otherwi - - @command{su} allows one user to temporarily become another user. It runs a - command (often an interactive shell) with the real and effective user --ID, group ID, and supplemental groups of a given @var{user}. Synopsis: -+ID, group ID, and supplemental groups of a given @var{user}. When the -l -+option is given, the su-l PAM file is used instead of the default su PAM file. -+Synopsis: - - @example - su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}] -@@ -15883,7 +15885,8 @@ environment variables except @env{TERM}, - (which are set, even for the super-user, as described above), and set - @env{PATH} to a compiled-in default value. Change to @var{user}'s home - directory. Prepend @samp{-} to the shell's name, intended to make it --read its login startup file(s). -+read its login startup file(s). When this option is given, /etc/pam.d/su-l -+PAM file is used instead of the default one. - - @item -m - @itemx -p -diff -urNp coreutils-8.16-orig/src/Makefile.am coreutils-8.16/src/Makefile.am ---- coreutils-8.16-orig/src/Makefile.am 2012-03-24 19:22:13.000000000 +0100 -+++ coreutils-8.16/src/Makefile.am 2012-03-26 17:59:07.928142551 +0200 -@@ -357,8 +357,8 @@ factor_LDADD += $(LIB_GMP) - # for getloadavg - uptime_LDADD += $(GETLOADAVG_LIBS) - --# for crypt --su_LDADD += $(LIB_CRYPT) -+# for crypt and pam -+su_LDADD += $(LIB_CRYPT) $(PAM_LIBS) - - # for various ACL functions - copy_LDADD += $(LIB_ACL) -diff -urNp coreutils-8.16-orig/src/su.c coreutils-8.16/src/su.c ---- coreutils-8.16-orig/src/su.c 2012-03-26 17:58:27.629764055 +0200 -+++ coreutils-8.16/src/su.c 2012-03-26 17:59:07.931138998 +0200 -@@ -37,6 +37,16 @@ - restricts who can su to UID 0 accounts. RMS considers that to - be fascist. - -+#ifdef USE_PAM -+ -+ Actually, with PAM, su has nothing to do with whether or not a -+ wheel group is enforced by su. RMS tries to restrict your access -+ to a su which implements the wheel group, but PAM considers that -+ to be fascist, and gives the user/sysadmin the opportunity to -+ enforce a wheel group by proper editing of /etc/pam.d/su -+ -+#endif -+ - Compile-time options: - -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. - -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. -@@ -52,6 +62,13 @@ - #include - #include - #include -+#ifdef USE_PAM -+#include -+#include -+#include -+#include -+#include -+#endif - - #include "system.h" - #include "getpass.h" -@@ -120,7 +137,9 @@ - /* The user to become if none is specified. */ - #define DEFAULT_USER "root" - -+#ifndef USE_PAM - char *crypt (char const *key, char const *salt); -+#endif - - static void run_shell (char const *, char const *, char **, size_t) - ATTRIBUTE_NORETURN; -@@ -134,6 +153,11 @@ static bool simulate_login; - /* If true, change some environment vars to indicate the user su'd to. */ - static bool change_environment; - -+#ifdef USE_PAM -+static bool _pam_session_opened; -+static bool _pam_cred_established; -+#endif -+ - static struct option const longopts[] = - { - {"command", required_argument, NULL, 'c'}, -@@ -212,7 +236,174 @@ log_su (struct passwd const *pw, bool su - } - #endif - -+#ifdef USE_PAM -+#define PAM_SERVICE_NAME PROGRAM_NAME -+#define PAM_SERVICE_NAME_L PROGRAM_NAME "-l" -+static sig_atomic_t volatile caught_signal = false; -+static pam_handle_t *pamh = NULL; -+static int retval; -+static struct pam_conv conv = -+{ -+ misc_conv, -+ NULL -+}; -+ -+#define PAM_BAIL_P(a) \ -+ if (retval) \ -+ { \ -+ pam_end (pamh, retval); \ -+ a; \ -+ } -+ -+static void -+cleanup_pam (int retcode) -+{ -+ if (_pam_session_opened) -+ pam_close_session (pamh, 0); -+ -+ if (_pam_cred_established) -+ pam_setcred (pamh, PAM_DELETE_CRED | PAM_SILENT); -+ -+ pam_end(pamh, retcode); -+} -+ -+/* Signal handler for parent process. */ -+static void -+su_catch_sig (int sig) -+{ -+ caught_signal = true; -+} -+ -+/* Export env variables declared by PAM modules. */ -+static void -+export_pamenv (void) -+{ -+ char **env; -+ -+ /* This is a copy but don't care to free as we exec later anyways. */ -+ env = pam_getenvlist (pamh); -+ while (env && *env) -+ { -+ if (putenv (*env) != 0) -+ xalloc_die (); -+ env++; -+ } -+} -+ -+static void -+create_watching_parent (void) -+{ -+ pid_t child; -+ sigset_t ourset, blockset; -+ int status = 0; -+ -+ retval = pam_open_session (pamh, 0); -+ if (retval != PAM_SUCCESS) -+ { -+ cleanup_pam (retval); -+ error (EXIT_FAILURE, 0, _("cannot not open session: %s"), -+ pam_strerror (pamh, retval)); -+ } -+ else -+ _pam_session_opened = 1; -+ -+ child = fork (); -+ if (child == (pid_t) -1) -+ { -+ cleanup_pam (PAM_ABORT); -+ error (EXIT_FAILURE, errno, _("cannot create child process")); -+ } -+ -+ /* the child proceeds to run the shell */ -+ if (child == 0) -+ return; -+ -+ /* In the parent watch the child. */ -+ -+ /* su without pam support does not have a helper that keeps -+ sitting on any directory so let's go to /. */ -+ if (chdir ("/") != 0) -+ error (0, errno, _("warning: cannot change directory to %s"), "/"); -+ -+ sigfillset (&ourset); -+ if (sigprocmask (SIG_BLOCK, &ourset, NULL)) -+ { -+ error (0, errno, _("cannot block signals")); -+ caught_signal = true; -+ } -+ if (!caught_signal) -+ { -+ struct sigaction action; -+ action.sa_handler = su_catch_sig; -+ sigemptyset (&action.sa_mask); -+ action.sa_flags = 0; -+ sigemptyset (&ourset); -+ if (sigaddset (&ourset, SIGTERM) -+ || sigaddset (&ourset, SIGALRM) -+ || sigaction (SIGTERM, &action, NULL) -+ || sigprocmask (SIG_UNBLOCK, &ourset, NULL)) -+ { -+ error (0, errno, _("cannot set signal handler")); -+ caught_signal = true; -+ } -+ } -+ if (!caught_signal) -+ { -+ pid_t pid; -+ for (;;) -+ { -+ pid = waitpid (child, &status, WUNTRACED); -+ -+ if (pid != (pid_t)-1 && WIFSTOPPED (status)) -+ { -+ /* tcsh sends SIGTSTP to the process group, and so is already pending */ -+ kill (getpid (), SIGSTOP); -+ if (WSTOPSIG(status) != SIGSTOP) { -+ sigemptyset(&blockset); -+ if (sigaddset(&blockset, WSTOPSIG(status)) || -+ sigprocmask(SIG_UNBLOCK, &blockset, &ourset) || -+ sigprocmask(SIG_SETMASK, &ourset, NULL)) -+ { -+ error (0, errno, _("cannot set signal handler")); -+ } -+ } -+ /* once we get here, we must have resumed */ -+ kill (pid, SIGCONT); -+ } -+ else -+ break; -+ } -+ if (pid != (pid_t)-1) -+ if (WIFSIGNALED (status)) -+ status = WTERMSIG (status) + 128; -+ else -+ status = WEXITSTATUS (status); -+ else -+ status = 1; -+ } -+ else -+ status = 1; -+ -+ if (caught_signal) -+ { -+ fprintf (stderr, _("\nSession terminated, killing shell...")); -+ kill (child, SIGTERM); -+ } -+ -+ cleanup_pam (PAM_SUCCESS); -+ -+ if (caught_signal) -+ { -+ sleep (2); -+ kill (child, SIGKILL); -+ fprintf (stderr, _(" ...killed.\n")); -+ } -+ exit (status); -+} -+#endif -+ - /* Ask the user for a password. -+ If PAM is in use, let PAM ask for the password if necessary. - Return true if the user gives the correct password for entry PW, - false if not. Return true without asking for a password if run by UID 0 - or if PW has an empty password. */ -@@ -220,10 +411,52 @@ log_su (struct passwd const *pw, bool su - static bool - correct_password (const struct passwd *pw) - { -+#ifdef USE_PAM -+ const struct passwd *lpw; -+ const char *cp; -+ -+ retval = pam_start (simulate_login ? PAM_SERVICE_NAME_L : PAM_SERVICE_NAME, -+ pw->pw_name, &conv, &pamh); -+ PAM_BAIL_P (return false); -+ -+ if (isatty (0) && (cp = ttyname (0)) != NULL) -+ { -+ const char *tty; -+ -+ if (strncmp (cp, "/dev/", 5) == 0) -+ tty = cp + 5; -+ else -+ tty = cp; -+ retval = pam_set_item (pamh, PAM_TTY, tty); -+ PAM_BAIL_P (return false); -+ } -+#if 0 /* Manpage discourages use of getlogin. */ -+ cp = getlogin (); -+ if (!(cp && *cp && (lpw = getpwnam (cp)) != NULL && lpw->pw_uid == getuid ())) -+#endif -+ lpw = getpwuid (getuid ()); -+ if (lpw && lpw->pw_name) -+ { -+ retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name); -+ PAM_BAIL_P (return false); -+ } -+ retval = pam_authenticate (pamh, 0); -+ PAM_BAIL_P (return false); -+ retval = pam_acct_mgmt (pamh, 0); -+ if (retval == PAM_NEW_AUTHTOK_REQD) -+ { -+ /* Password has expired. Offer option to change it. */ -+ retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); -+ PAM_BAIL_P (return false); -+ } -+ PAM_BAIL_P (return false); -+ /* Must be authenticated if this point was reached. */ -+ return true; -+#else /* !USE_PAM */ - char *unencrypted, *encrypted, *correct; - #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP - /* Shadow passwd stuff for SVR3 and maybe other systems. */ -- struct spwd *sp = getspnam (pw->pw_name); -+ const struct spwd *sp = getspnam (pw->pw_name); - - endspent (); - if (sp) -@@ -244,6 +477,7 @@ correct_password (const struct passwd *p - encrypted = crypt (unencrypted, correct); - memset (unencrypted, 0, strlen (unencrypted)); - return STREQ (encrypted, correct); -+#endif /* !USE_PAM */ - } - - /* Update 'environ' for the new shell based on PW, with SHELL being -@@ -286,19 +520,41 @@ modify_environment (const struct passwd - } - } - } -+ -+#ifdef USE_PAM -+ export_pamenv (); -+#endif - } - - /* Become the user and group(s) specified by PW. */ - - static void --change_identity (const struct passwd *pw) -+init_groups (const struct passwd *pw) - { - #ifdef HAVE_INITGROUPS - errno = 0; - if (initgroups (pw->pw_name, pw->pw_gid) == -1) -- error (EXIT_CANCELED, errno, _("cannot set groups")); -+ { -+#ifdef USE_PAM -+ cleanup_pam (PAM_ABORT); -+#endif -+ error (EXIT_FAILURE, errno, _("cannot set groups")); -+ } - endgrent (); - #endif -+ -+#ifdef USE_PAM -+ retval = pam_setcred (pamh, PAM_ESTABLISH_CRED); -+ if (retval != PAM_SUCCESS) -+ error (EXIT_FAILURE, 0, "%s", pam_strerror (pamh, retval)); -+ else -+ _pam_cred_established = 1; -+#endif -+} -+ -+static void -+change_identity (const struct passwd *pw) -+{ - if (setgid (pw->pw_gid)) - error (EXIT_CANCELED, errno, _("cannot set group id")); - if (setuid (pw->pw_uid)) -@@ -511,9 +767,21 @@ main (int argc, char **argv) - shell = NULL; - } - shell = xstrdup (shell ? shell : pw->pw_shell); -- modify_environment (pw, shell); -+ -+ init_groups (pw); -+ -+#ifdef USE_PAM -+ create_watching_parent (); -+ /* Now we're in the child. */ -+#endif - - change_identity (pw); -+ -+ /* Set environment after pam_open_session, which may put KRB5CCNAME -+ into the pam_env, etc. */ -+ -+ modify_environment (pw, shell); -+ - if (simulate_login && chdir (pw->pw_dir) != 0) - error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); - diff --git a/coreutils-8.7-runuser.patch b/coreutils-8.7-runuser.patch deleted file mode 100644 index 533e15a..0000000 --- a/coreutils-8.7-runuser.patch +++ /dev/null @@ -1,338 +0,0 @@ -diff -urNp coreutils-8.7-orig/AUTHORS coreutils-8.7/AUTHORS ---- coreutils-8.7-orig/AUTHORS 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/AUTHORS 2010-11-15 10:08:04.222078001 +0100 -@@ -65,6 +65,7 @@ readlink: Dmitry V. Levin - rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering - rmdir: David MacKenzie - runcon: Russell Coker -+runuser: David MacKenzie, Dan Walsh - seq: Ulrich Drepper - sha1sum: Ulrich Drepper, Scott Miller, David Madore - sha224sum: Ulrich Drepper, Scott Miller, David Madore -diff -urNp coreutils-8.7-orig/man/help2man coreutils-8.7/man/help2man ---- coreutils-8.7-orig/man/help2man 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/man/help2man 2010-11-15 10:08:51.331054884 +0100 -@@ -555,6 +555,9 @@ while (length) - $include{$sect} .= $content; - } - -+# There is no info documentation for runuser (shared with su). -+$opt_no_info = 1 if $program eq 'runuser'; -+ - # Refer to the real documentation. - unless ($opt_no_info) - { -diff -urNp coreutils-8.7-orig/man/Makefile.am coreutils-8.7/man/Makefile.am ---- coreutils-8.7-orig/man/Makefile.am 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/man/Makefile.am 2010-11-15 10:09:21.768922182 +0100 -@@ -94,6 +94,7 @@ readlink.1: $(common_dep) $(srcdir)/read - rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c - rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c - runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c -+runuser.1: $(common_dep) $(srcdir)/runuser.x ../src/su.c - seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c - sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c - sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c -diff -urNp coreutils-8.7-orig/man/runuser.x coreutils-8.7/man/runuser.x ---- coreutils-8.7-orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.7/man/runuser.x 2010-11-15 10:09:57.437939015 +0100 -@@ -0,0 +1,12 @@ -+[NAME] -+runuser \- run a shell with substitute user and group IDs -+[DESCRIPTION] -+.\" Add any additional description here -+[SEE ALSO] -+.TP -+More detailed Texinfo documentation could be found by command -+.TP -+\t\fBinfo coreutils \(aqsu invocation\(aq\fR\t -+.TP -+since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR. -+.br -diff -urNp coreutils-8.7-orig/README coreutils-8.7/README ---- coreutils-8.7-orig/README 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/README 2010-11-15 10:10:43.002922253 +0100 -@@ -11,8 +11,8 @@ The programs that can be built with this - factor false fmt fold groups head hostid hostname id install join kill - link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup - nproc 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 su sum sync tac tail tee test -+ rm rmdir runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum -+ shred shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test - timeout touch tr true truncate tsort tty uname unexpand uniq unlink - uptime users vdir wc who whoami yes - -diff -urNp coreutils-8.7-orig/src/Makefile.am coreutils-8.7/src/Makefile.am ---- coreutils-8.7-orig/src/Makefile.am 2010-11-15 10:07:07.339171659 +0100 -+++ coreutils-8.7/src/Makefile.am 2010-11-15 10:12:14.847094550 +0100 -@@ -100,6 +100,7 @@ EXTRA_PROGRAMS = \ - rm \ - rmdir \ - runcon \ -+ runuser \ - seq \ - sha1sum \ - sha224sum \ -@@ -300,6 +301,10 @@ cp_LDADD += $(copy_LDADD) - ginstall_LDADD += $(copy_LDADD) - mv_LDADD += $(copy_LDADD) - -+runuser_SOURCES = su.c -+runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\"" -+runuser_LDADD = $(LDADD) $(LIB_CRYPT) $(PAM_LIBS) -+ - remove_LDADD = - mv_LDADD += $(remove_LDADD) - rm_LDADD += $(remove_LDADD) -@@ -395,7 +400,7 @@ RELEASE_YEAR = \ - `sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \ - $(top_srcdir)/lib/version-etc.c` - --all-local: su$(EXEEXT) -+all-local: su$(EXEEXT) runuser - - installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'` - -diff -urNp coreutils-8.7-orig/src/su.c coreutils-8.7/src/su.c ---- coreutils-8.7-orig/src/su.c 2010-11-15 10:07:07.372933288 +0100 -+++ coreutils-8.7/src/su.c 2010-11-15 10:42:12.569159230 +0100 -@@ -100,9 +100,15 @@ - #include "error.h" - - /* The official name of this program (e.g., no 'g' prefix). */ -+#ifndef RUNUSER - #define PROGRAM_NAME "su" -+#else -+#define PROGRAM_NAME "runuser" -+#endif - -+#ifndef AUTHORS - #define AUTHORS proper_name ("David MacKenzie") -+#endif - - #if HAVE_PATHS_H - # include -@@ -140,6 +146,9 @@ - #ifndef USE_PAM - char *crypt (char const *key, char const *salt); - #endif -+#ifndef CHECKPASSWD -+#define CHECKPASSWD 1 -+#endif - - static void run_shell (char const *, char const *, char **, size_t) - ATTRIBUTE_NORETURN; -@@ -169,6 +178,10 @@ static struct option const longopts[] = - {"login", no_argument, NULL, 'l'}, - {"preserve-environment", no_argument, NULL, 'p'}, - {"shell", required_argument, NULL, 's'}, -+#ifdef RUNUSER -+ {"group", required_argument, NULL, 'g'}, -+ {"supp-group", required_argument, NULL, 'G'}, -+#endif - {GETOPT_HELP_OPTION_DECL}, - {GETOPT_VERSION_OPTION_DECL}, - {NULL, 0, NULL, 0} -@@ -444,6 +457,11 @@ correct_password (const struct passwd *p - retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name); - PAM_BAIL_P (return false); - } -+#ifdef RUNUSER -+ if (getuid() != geteuid()) -+ /* safety net: deny operation if we are suid by accident */ -+ error(EXIT_FAILURE, 1, "runuser may not be setuid"); -+#else - retval = pam_authenticate (pamh, 0); - PAM_BAIL_P (return false); - retval = pam_acct_mgmt (pamh, 0); -@@ -454,6 +472,7 @@ correct_password (const struct passwd *p - PAM_BAIL_P (return false); - } - PAM_BAIL_P (return false); -+#endif - /* Must be authenticated if this point was reached. */ - return true; - #else /* !USE_PAM */ -@@ -533,11 +552,22 @@ modify_environment (const struct passwd - /* Become the user and group(s) specified by PW. */ - - static void --init_groups (const struct passwd *pw) -+init_groups (const struct passwd *pw -+#ifdef RUNUSER -+ , gid_t *groups, int num_groups -+#endif -+ ) - { - #ifdef HAVE_INITGROUPS -+ int rc = 0; - errno = 0; -- if (initgroups (pw->pw_name, pw->pw_gid) == -1) -+#ifdef RUNUSER -+ if (num_groups) -+ rc = setgroups(num_groups, groups); -+ else -+#endif -+ rc = initgroups(pw->pw_name, pw->pw_gid); -+ if (rc == -1) - { - #ifdef USE_PAM - cleanup_pam (PAM_ABORT); -@@ -639,6 +669,28 @@ usage (int status) - else - { - printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name); -+#ifdef RUNUSER -+ printf (_("\ -+Change the effective user id and group id to that of USER. Only session PAM\n\ -+hooks are run, and there is no password prompt. This command is useful only\n\ -+when run as the root user. If run as a non-root user without privilege\n\ -+to set user ID, the command will fail as the binary is not setuid.\n\ -+As %s doesn't run auth and account PAM hooks, it runs with lower overhead\n\ -+than su.\n\ -+\n\ -+ -, -l, --login make the shell a login shell, uses runuser-l\n\ -+ PAM file instead of default one\n\ -+ -g --group=group specify the primary group\n\ -+ -G --supp-group=group specify a supplemental group\n\ -+ -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\ -+ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\ -+ and do not create a new session\n\ -+ -f, --fast pass -f to the shell (for csh or tcsh)\n\ -+ -m, --preserve-environment do not reset environment variables\n\ -+ -p same as -m\n\ -+ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ -+"), program_name); -+#else - fputs (_("\ - Change the effective user id and group id to that of USER.\n\ - \n\ -@@ -651,6 +703,7 @@ Change the effective user id and group i - -p same as -m\n\ - -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ - "), stdout); -+#endif - fputs (HELP_OPTION_DESCRIPTION, stdout); - fputs (VERSION_OPTION_DESCRIPTION, stdout); - fputs (_("\ -@@ -672,6 +725,12 @@ main (int argc, char **argv) - char *shell = NULL; - struct passwd *pw; - struct passwd pw_copy; -+#ifdef RUNUSER -+ struct group *gr; -+ gid_t groups[NGROUPS_MAX]; -+ int num_supp_groups = 0; -+ int use_gid = 0; -+#endif - - initialize_main (&argc, &argv); - set_program_name (argv[0]); -@@ -686,7 +745,11 @@ main (int argc, char **argv) - simulate_login = false; - change_environment = true; - -- while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1) -+ while ((optc = getopt_long (argc, argv, "c:flmps:" -+#ifdef RUNUSER -+ "g:G:" -+#endif -+ , longopts, NULL)) != -1) - { - switch (optc) - { -@@ -716,6 +779,28 @@ main (int argc, char **argv) - shell = optarg; - break; - -+#ifdef RUNUSER -+ case 'g': -+ gr = getgrnam(optarg); -+ if (!gr) -+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg); -+ use_gid = 1; -+ groups[0] = gr->gr_gid; -+ break; -+ -+ case 'G': -+ num_supp_groups++; -+ if (num_supp_groups >= NGROUPS_MAX) -+ error (EXIT_FAILURE, 0, -+ _("Can't specify more than %d supplemental groups"), -+ NGROUPS_MAX - 1); -+ gr = getgrnam(optarg); -+ if (!gr) -+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg); -+ groups[num_supp_groups] = gr->gr_gid; -+ break; -+#endif -+ - case_GETOPT_HELP_CHAR; - - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -@@ -754,7 +839,20 @@ main (int argc, char **argv) - : DEFAULT_SHELL); - endpwent (); - -- if (!correct_password (pw)) -+#ifdef RUNUSER -+ if (num_supp_groups && !use_gid) -+ { -+ pw->pw_gid = groups[1]; -+ memmove (groups, groups + 1, sizeof(gid_t) * num_supp_groups); -+ } -+ else if (use_gid) -+ { -+ pw->pw_gid = groups[0]; -+ num_supp_groups++; -+ } -+#endif -+ -+ if (CHECKPASSWD && !correct_password (pw)) - { - #ifdef SYSLOG_FAILURE - log_su (pw, false); -@@ -784,7 +882,11 @@ main (int argc, char **argv) - } - shell = xstrdup (shell ? shell : pw->pw_shell); - -- init_groups (pw); -+ init_groups (pw -+#ifdef RUNUSER -+ , groups, num_supp_groups -+#endif -+ ); - - #ifdef USE_PAM - create_watching_parent (); -diff -urNp coreutils-8.7-orig/tests/misc/help-version coreutils-8.7/tests/misc/help-version ---- coreutils-8.7-orig/tests/misc/help-version 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/tests/misc/help-version 2010-11-15 10:45:18.473682325 +0100 -@@ -32,6 +32,7 @@ expected_failure_status_nohup=125 - expected_failure_status_stdbuf=125 - expected_failure_status_su=125 - expected_failure_status_timeout=125 -+expected_failure_status_runuser=125 - expected_failure_status_printenv=2 - expected_failure_status_tty=3 - expected_failure_status_sort=2 -@@ -209,6 +210,7 @@ seq_setup () { args=10; } - sleep_setup () { args=0; } - su_setup () { args=--version; } - stdbuf_setup () { args="-oL true"; } -+runuser_setup () { args=--version; } - timeout_setup () { args=--version; } - - # I'd rather not run sync, since it spins up disks that I've -diff -urNp coreutils-8.7-orig/tests/misc/invalid-opt coreutils-8.7/tests/misc/invalid-opt ---- coreutils-8.7-orig/tests/misc/invalid-opt 2010-10-11 19:35:11.000000000 +0200 -+++ coreutils-8.7/tests/misc/invalid-opt 2010-11-15 10:45:46.451938873 +0100 -@@ -37,6 +37,7 @@ my %exit_status = - sort => 2, - stdbuf => 125, - su => 125, -+ runuser => 125, - test => 0, - timeout => 125, - true => 0, diff --git a/coreutils-runuser-l.pamd b/coreutils-runuser-l.pamd deleted file mode 100644 index fa1e4d8..0000000 --- a/coreutils-runuser-l.pamd +++ /dev/null @@ -1,4 +0,0 @@ -#%PAM-1.0 -auth include runuser -session optional pam_keyinit.so force revoke -session include runuser diff --git a/coreutils-runuser.pamd b/coreutils-runuser.pamd deleted file mode 100644 index 37f0e84..0000000 --- a/coreutils-runuser.pamd +++ /dev/null @@ -1,5 +0,0 @@ -#%PAM-1.0 -auth sufficient pam_rootok.so -session optional pam_keyinit.so revoke -session required pam_limits.so -session required pam_unix.so diff --git a/coreutils-setsid.patch b/coreutils-setsid.patch deleted file mode 100644 index 714383f..0000000 --- a/coreutils-setsid.patch +++ /dev/null @@ -1,102 +0,0 @@ -diff -urNp coreutils-8.6-orig/src/su.c coreutils-8.6/src/su.c ---- coreutils-8.6-orig/src/su.c 2010-11-03 13:56:11.679069689 +0100 -+++ coreutils-8.6/src/su.c 2010-11-03 13:56:45.304325661 +0100 -@@ -153,6 +153,9 @@ static bool simulate_login; - /* If true, change some environment vars to indicate the user su'd to. */ - static bool change_environment; - -+/* If true, then don't call setsid() with a command. */ -+int same_session = 0; -+ - #ifdef USE_PAM - static bool _pam_session_opened; - static bool _pam_cred_established; -@@ -161,6 +164,7 @@ static bool _pam_cred_established; - static struct option const longopts[] = - { - {"command", required_argument, NULL, 'c'}, -+ {"session-command", required_argument, NULL, 'C'}, - {"fast", no_argument, NULL, 'f'}, - {"login", no_argument, NULL, 'l'}, - {"preserve-environment", no_argument, NULL, 'p'}, -@@ -335,14 +339,27 @@ create_watching_parent (void) - sigemptyset (&action.sa_mask); - action.sa_flags = 0; - sigemptyset (&ourset); -- if (sigaddset (&ourset, SIGTERM) -- || sigaddset (&ourset, SIGALRM) -- || sigaction (SIGTERM, &action, NULL) -- || sigprocmask (SIG_UNBLOCK, &ourset, NULL)) -- { -+ if (!same_session) -+ { -+ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT)) -+ { -+ error (0, errno, _("cannot set signal handler")); -+ caught_signal = true; -+ } -+ } -+ if (!caught_signal && (sigaddset(&ourset, SIGTERM) -+ || sigaddset(&ourset, SIGALRM) -+ || sigaction(SIGTERM, &action, NULL) -+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) { - error (0, errno, _("cannot set signal handler")); - caught_signal = true; - } -+ if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL) -+ || sigaction(SIGQUIT, &action, NULL))) -+ { -+ error (0, errno, _("cannot set signal handler")); -+ caught_signal = true; -+ } - } - if (!caught_signal) - { -@@ -627,6 +644,8 @@ Change the effective user id and group i - \n\ - -, -l, --login make the shell a login shell\n\ - -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\ -+ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\ -+ and do not create a new session\n\ - -f, --fast pass -f to the shell (for csh or tcsh)\n\ - -m, --preserve-environment do not reset environment variables\n\ - -p same as -m\n\ -@@ -649,6 +668,7 @@ main (int argc, char **argv) - int optc; - const char *new_user = DEFAULT_USER; - char *command = NULL; -+ int request_same_session = 0; - char *shell = NULL; - struct passwd *pw; - struct passwd pw_copy; -@@ -674,6 +694,11 @@ main (int argc, char **argv) - command = optarg; - break; - -+ case 'C': -+ command = optarg; -+ request_same_session = 1; -+ break; -+ - case 'f': - fast_startup = true; - break; -@@ -743,6 +768,9 @@ main (int argc, char **argv) - } - #endif - -+ if (request_same_session || !command || !pw->pw_uid) -+ same_session = 1; -+ - if (!shell && !change_environment) - shell = getenv ("SHELL"); - if (shell && getuid () != 0 && restricted_shell (pw->pw_shell)) -@@ -764,6 +792,8 @@ main (int argc, char **argv) - #endif - - change_identity (pw); -+ if (!same_session) -+ setsid (); - - /* Set environment after pam_open_session, which may put KRB5CCNAME - into the pam_env, etc. */ diff --git a/coreutils-su-l.pamd b/coreutils-su-l.pamd deleted file mode 100644 index 656a139..0000000 --- a/coreutils-su-l.pamd +++ /dev/null @@ -1,6 +0,0 @@ -#%PAM-1.0 -auth include su -account include su -password include su -session optional pam_keyinit.so force revoke -session include su diff --git a/coreutils-su.pamd b/coreutils-su.pamd deleted file mode 100644 index 1981f58..0000000 --- a/coreutils-su.pamd +++ /dev/null @@ -1,14 +0,0 @@ -#%PAM-1.0 -auth sufficient pam_rootok.so -# Uncomment the following line to implicitly trust users in the "wheel" group. -#auth sufficient pam_wheel.so trust use_uid -# Uncomment the following line to require a user to be in the "wheel" group. -#auth required pam_wheel.so use_uid -auth include system-auth -auth include postlogin -account sufficient pam_succeed_if.so uid = 0 use_uid quiet -account include system-auth -password include system-auth -session include system-auth -session include postlogin -session optional pam_xauth.so diff --git a/coreutils.spec b/coreutils.spec index bc95dd4..8a07c90 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,6 +1,6 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.18 +Version: 8.19 Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base @@ -12,10 +12,6 @@ Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh -Source200: coreutils-su.pamd -Source201: coreutils-runuser.pamd -Source202: coreutils-su-l.pamd -Source203: coreutils-runuser-l.pamd # From upstream @@ -36,27 +32,15 @@ Patch107: coreutils-8.4-mkdir-modenote.patch # sh-utils #add info about TZ envvar to date manpage Patch703: sh-utils-2.0.11-dateman.patch -#set paths for su explicitly, don't get influenced by paths.h -#Patch704: sh-utils-1.16-paths.patch -# RMS will never accept the PAM patch because it removes his historical -# rant about Twenex and the wheel group, so we'll continue to maintain -# it here indefinitely. Patch is now the same in Fedora and SUSE. -#Patch706: coreutils-8.5-pam.patch Patch713: coreutils-4.5.3-langinfo.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch -#Call setsid() in su under some circumstances (bug #173008). -#Patch900: coreutils-setsid.patch -#make runuser binary based on su.c -#Patch907: coreutils-8.7-runuser.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch #Prevent buffer overflow in who(1) (bug #158405). Patch912: coreutils-overflow.patch -#compile su with pie flag and RELRO protection -#Patch917: coreutils-8.4-su-pie.patch #SELINUX Patch - implements Redhat changes #(upstream did some SELinux implementation unlike with RedHat patch) @@ -93,12 +77,10 @@ Provides: /bin/rmdir Provides: /bin/sleep Provides: /bin/sort Provides: /bin/stty -Provides: /bin/su Provides: /bin/sync Provides: /bin/touch Provides: /bin/true Provides: /bin/uname -Provides: /sbin/runuser BuildRequires: libselinux-devel BuildRequires: libacl-devel @@ -106,7 +88,6 @@ BuildRequires: gettext bison BuildRequires: texinfo BuildRequires: autoconf BuildRequires: automake -#%{?!nopam:BuildRequires: pam-devel} BuildRequires: libcap-devel BuildRequires: libattr-devel BuildRequires: gmp-devel @@ -117,7 +98,6 @@ Requires(pre): /sbin/install-info Requires(preun): /sbin/install-info Requires(post): /sbin/install-info Requires(post): grep -#%{?!nopam:Requires: pam >= 1.1.3-7} Requires: ncurses Requires: gmp @@ -155,19 +135,14 @@ the old GNU fileutils, sh-utils, and textutils packages. # sh-utils %patch703 -p1 -b .dateman -#%patch704 -p1 -b .paths -#%patch706 -p1 -b .pam %patch713 -p1 -b .langinfo # li18nux/lsb %patch800 -p1 -b .i18n # Coreutils -#%patch900 -p1 -b .setsid -#%patch907 -p1 -b .runuser %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow -#%patch917 -p1 -b .pie #SELinux %patch950 -p1 -b .selinux @@ -226,7 +201,6 @@ bzip2 -9f ChangeLog # let be compatible with old fileutils, sh-utils and textutils packages : mkdir -p $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}} -#%{?!nopam:mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pam.d} # chroot was in /usr/sbin : mv $RPM_BUILD_ROOT{%_bindir,%_sbindir}/chroot @@ -238,22 +212,11 @@ install -p -c -m644 %SOURCE103 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.256color install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh -# su -#install -m 4755 src/su $RPM_BUILD_ROOT/%{_bindir} -#%{?!norunuser:install -m 755 src/runuser $RPM_BUILD_ROOT/%{_sbindir}} -# do not ship runuser in /usr/bin/runuser -#rm -rf $RPM_BUILD_ROOT/%{_bindir}/runuser || : - # These come from util-linux and/or procps. for i in hostname uptime kill ; do rm $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1} done -#%{?!nopam:install -p -m 644 %SOURCE200 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su} -#%{?!nopam:install -p -m 644 %SOURCE202 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su-l} -#%{?!nopam:install -p -m 644 %SOURCE201 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser} -#%{?!nopam:install -p -m 644 %SOURCE203 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser-l} - # Compress ChangeLogs from before the fileutils/textutils/etc merge bzip2 -f9 old/*/C* @@ -304,10 +267,6 @@ fi %dir %{_datadir}/locale/*/LC_TIME %config(noreplace) %{_sysconfdir}/DIR_COLORS* %config(noreplace) %{_sysconfdir}/profile.d/* -#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su} -#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su-l} -#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser} -#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser-l} %doc COPYING ABOUT-NLS ChangeLog.bz2 NEWS README THANKS TODO old/* %{_bindir}/arch %{_bindir}/basename @@ -337,7 +296,6 @@ fi %{_bindir}/sleep %{_bindir}/sort %{_bindir}/stty -#%attr(4755,root,root) %{_bindir}/su %{_bindir}/sync %{_bindir}/mktemp %{_bindir}/touch @@ -414,9 +372,11 @@ fi %{_libexecdir}/coreutils* %{_mandir}/man*/* %{_sbindir}/chroot -#%{?!norunuser:%{_sbindir}/runuser} %changelog +* Mon Aug 20 2012 Ondrej Vasik 8.19-1 +- new upstream release 8.19 + * Sun Aug 12 2012 Ondrej Vasik 8.18-1 - new upstream release 8.18 - su/runuser moved to util-linux diff --git a/sources b/sources index 33abc66..924eab4 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -74712fbb0e0dfcb883c90eab91982780 coreutils-8.18.tar.xz +1a01231a2f3ed37c0efc073ccdda9375 coreutils-8.19.tar.xz From fa6f383f16e3599d9f7ee77898e5f82b970c8013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 20 Aug 2012 13:57:53 +0200 Subject: [PATCH 176/523] fix multibyte issues in cut and expand (M.Briza, #821260) --- coreutils-i18n.patch | 215 +++++++++++++++++++++++++++---------------- coreutils.spec | 1 + 2 files changed, 137 insertions(+), 79 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 925c85c..a5b9aaf 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.16-orig/lib/linebuffer.h coreutils-8.16/lib/linebuffer.h ---- coreutils-8.16-orig/lib/linebuffer.h 2012-01-06 10:14:31.000000000 +0100 -+++ coreutils-8.16/lib/linebuffer.h 2012-03-26 18:02:00.993889446 +0200 +diff -urNp coreutils-8.19-orig/lib/linebuffer.h coreutils-8.19/lib/linebuffer.h +--- coreutils-8.19-orig/lib/linebuffer.h 2012-01-06 10:14:31.000000000 +0100 ++++ coreutils-8.19/lib/linebuffer.h 2012-08-20 13:52:04.061593006 +0200 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.16-orig/lib/linebuffer.h coreutils-8.16/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.16-orig/src/cut.c coreutils-8.16/src/cut.c ---- coreutils-8.16-orig/src/cut.c 2012-03-24 21:26:51.000000000 +0100 -+++ coreutils-8.16/src/cut.c 2012-03-26 17:46:48.000000000 +0200 +diff -urNp coreutils-8.19-orig/src/cut.c coreutils-8.19/src/cut.c +--- coreutils-8.19-orig/src/cut.c 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.19/src/cut.c 2012-08-20 13:52:52.299593173 +0200 @@ -28,6 +28,11 @@ #include #include @@ -376,7 +376,7 @@ diff -urNp coreutils-8.16-orig/src/cut.c coreutils-8.16/src/cut.c + break; + } + -+ if (wc == WEOF) ++ if (len <= 0 && wc == WEOF) + break; + + /* If the first field extends to the end of line (it is not @@ -633,9 +633,9 @@ diff -urNp coreutils-8.16-orig/src/cut.c coreutils-8.16/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.16-orig/src/expand.c coreutils-8.16/src/expand.c ---- coreutils-8.16-orig/src/expand.c 2012-03-24 21:26:51.000000000 +0100 -+++ coreutils-8.16/src/expand.c 2012-03-26 17:42:56.000000000 +0200 +diff -urNp coreutils-8.19-orig/src/expand.c coreutils-8.19/src/expand.c +--- coreutils-8.19-orig/src/expand.c 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.19/src/expand.c 2012-08-20 13:54:02.974621693 +0200 @@ -37,12 +37,29 @@ #include #include @@ -733,7 +733,7 @@ diff -urNp coreutils-8.16-orig/src/expand.c coreutils-8.16/src/expand.c + if (convert) + { + ++column; -+ if (convert_entire_line == 0) ++ if (convert_entire_line == 0 && !isblank(*bufpos)) + convert = 0; + } + putchar (*bufpos); @@ -793,7 +793,7 @@ diff -urNp coreutils-8.16-orig/src/expand.c coreutils-8.16/src/expand.c + + width = wcwidth (wc); + column += (width > 0) ? width : 0; -+ if (convert_entire_line == 0) ++ if (convert_entire_line == 0 && !iswblank(wc)) + convert = 0; + } + } @@ -823,9 +823,9 @@ diff -urNp coreutils-8.16-orig/src/expand.c coreutils-8.16/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.16-orig/src/fold.c coreutils-8.16/src/fold.c ---- coreutils-8.16-orig/src/fold.c 2012-03-24 19:22:13.000000000 +0100 -+++ coreutils-8.16/src/fold.c 2012-03-26 17:48:37.000000000 +0200 +diff -urNp coreutils-8.19-orig/src/fold.c coreutils-8.19/src/fold.c +--- coreutils-8.19-orig/src/fold.c 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.19/src/fold.c 2012-08-20 13:52:04.066592980 +0200 @@ -22,12 +22,34 @@ #include #include @@ -1223,9 +1223,9 @@ diff -urNp coreutils-8.16-orig/src/fold.c coreutils-8.16/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.16-orig/src/join.c coreutils-8.16/src/join.c ---- coreutils-8.16-orig/src/join.c 2012-03-24 21:26:51.000000000 +0100 -+++ coreutils-8.16/src/join.c 2012-03-26 17:50:02.000000000 +0200 +diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c +--- coreutils-8.19-orig/src/join.c 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.19/src/join.c 2012-08-20 13:52:04.069594876 +0200 @@ -22,18 +22,32 @@ #include #include @@ -1701,9 +1701,9 @@ diff -urNp coreutils-8.16-orig/src/join.c coreutils-8.16/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.16-orig/src/pr.c coreutils-8.16/src/pr.c ---- coreutils-8.16-orig/src/pr.c 2012-03-24 21:26:51.000000000 +0100 -+++ coreutils-8.16/src/pr.c 2012-03-26 17:50:48.000000000 +0200 +diff -urNp coreutils-8.19-orig/src/pr.c coreutils-8.19/src/pr.c +--- coreutils-8.19-orig/src/pr.c 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.19/src/pr.c 2012-08-20 13:52:04.074593445 +0200 @@ -312,6 +312,32 @@ #include @@ -2447,9 +2447,9 @@ diff -urNp coreutils-8.16-orig/src/pr.c coreutils-8.16/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c ---- coreutils-8.17-orig/src/sort.c -+++ coreutils-8.17/src/sort.c +diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c +--- coreutils-8.19-orig/src/sort.c 2012-08-18 07:39:29.000000000 +0200 ++++ coreutils-8.19/src/sort.c 2012-08-20 13:52:04.079596072 +0200 @@ -29,6 +29,14 @@ #include #include @@ -2465,7 +2465,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -167,12 +176,34 @@ static int thousands_sep; +@@ -166,12 +174,34 @@ static int thousands_sep; /* Nonzero if the corresponding locales are hard. */ static bool hard_LC_COLLATE; @@ -2501,7 +2501,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -343,13 +374,11 @@ static bool reverse; +@@ -345,13 +375,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2518,7 +2518,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -782,6 +811,46 @@ reap_all (void) +@@ -784,6 +812,46 @@ reap_all (void) reap (-1); } @@ -2565,7 +2565,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1214,7 +1283,7 @@ zaptemp (char const *name) +@@ -1224,7 +1292,7 @@ zaptemp (char const *name) free (node); } @@ -2574,7 +2574,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1229,7 +1298,7 @@ struct_month_cmp (void const *m1, void c +@@ -1239,7 +1307,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2583,7 +2583,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c { size_t i; -@@ -1241,7 +1310,7 @@ inittables (void) +@@ -1251,7 +1319,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2592,7 +2592,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1323,6 +1392,84 @@ specify_nmerge (int oi, char c, char con +@@ -1333,6 +1401,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2677,7 +2677,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1551,7 +1698,7 @@ buffer_linelim (struct buffer const *buf +@@ -1565,7 +1711,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2686,7 +2686,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1560,10 +1707,10 @@ begfield (struct line const *line, struc +@@ -1574,10 +1720,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2699,7 +2699,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1589,11 +1736,70 @@ begfield (struct line const *line, struc +@@ -1603,11 +1749,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2771,7 +2771,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1608,10 +1814,10 @@ limfield (struct line const *line, struc +@@ -1622,10 +1827,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. */ @@ -2784,7 +2784,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1657,10 +1863,10 @@ limfield (struct line const *line, struc +@@ -1671,10 +1876,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2797,7 +2797,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c if (newlim) lim = newlim; } -@@ -1691,6 +1897,130 @@ limfield (struct line const *line, struc +@@ -1705,6 +1910,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2928,7 +2928,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c /* 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 -@@ -1777,8 +2107,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1791,8 +2120,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2953,7 +2953,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c line->keybeg = line_start; } } -@@ -1899,7 +2243,7 @@ human_numcompare (char const *a, char co +@@ -1913,7 +2256,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2962,7 +2962,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1909,6 +2253,25 @@ numcompare (char const *a, char const *b +@@ -1923,6 +2266,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2988,7 +2988,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c /* 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 once -@@ -1959,7 +2322,7 @@ general_numcompare (char const *sa, char +@@ -1973,7 +2335,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -2997,7 +2997,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2234,15 +2597,14 @@ debug_key (struct line const *line, stru +@@ -2248,15 +2610,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -3015,7 +3015,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2386,7 +2748,7 @@ key_warnings (struct keyfield const *gke +@@ -2400,7 +2761,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3024,7 +3024,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2444,11 +2806,83 @@ key_warnings (struct keyfield const *gke +@@ -2458,11 +2819,83 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -3109,7 +3109,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c { struct keyfield *key = keylist; -@@ -2533,7 +2967,7 @@ keycompare (struct line const *a, struct +@@ -2547,7 +2980,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3118,7 +3118,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2649,6 +3083,180 @@ keycompare (struct line const *a, struct +@@ -2663,6 +3096,180 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3299,7 +3299,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4109,7 +4717,7 @@ main (int argc, char **argv) +@@ -4158,7 +4765,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3308,7 +3308,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4130,6 +4738,29 @@ main (int argc, char **argv) +@@ -4179,6 +4786,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3338,7 +3338,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c have_read_stdin = false; inittables (); -@@ -4400,13 +5031,34 @@ main (int argc, char **argv) +@@ -4453,13 +5083,34 @@ main (int argc, char **argv) case 't': { @@ -3377,7 +3377,7 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4417,9 +5069,12 @@ main (int argc, char **argv) +@@ -4470,9 +5121,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3392,9 +3392,9 @@ diff -urNp coreutils-8.17-orig/src/sort.c coreutils-8.17/src/sort.c } break; -diff -urNp coreutils-8.16-orig/src/unexpand.c coreutils-8.16/src/unexpand.c ---- coreutils-8.16-orig/src/unexpand.c 2012-03-24 21:26:51.000000000 +0100 -+++ coreutils-8.16/src/unexpand.c 2012-03-26 17:51:46.000000000 +0200 +diff -urNp coreutils-8.19-orig/src/unexpand.c coreutils-8.19/src/unexpand.c +--- coreutils-8.19-orig/src/unexpand.c 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.19/src/unexpand.c 2012-08-20 13:52:04.081596774 +0200 @@ -38,12 +38,29 @@ #include #include @@ -3648,9 +3648,9 @@ diff -urNp coreutils-8.16-orig/src/unexpand.c coreutils-8.16/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.16-orig/src/uniq.c coreutils-8.16/src/uniq.c ---- coreutils-8.16-orig/src/uniq.c 2012-03-24 21:26:51.000000000 +0100 -+++ coreutils-8.16/src/uniq.c 2012-03-26 17:35:09.000000000 +0200 +diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c +--- coreutils-8.19-orig/src/uniq.c 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.19/src/uniq.c 2012-08-20 13:52:04.083502506 +0200 @@ -21,6 +21,16 @@ #include #include @@ -4016,10 +4016,10 @@ diff -urNp coreutils-8.16-orig/src/uniq.c coreutils-8.16/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.16-orig/tests/Makefile.am coreutils-8.16/tests/Makefile.am ---- coreutils-8.16-orig/tests/Makefile.am 2012-03-26 18:01:35.564014659 +0200 -+++ coreutils-8.16/tests/Makefile.am 2012-03-26 18:02:01.023015013 +0200 -@@ -242,6 +242,7 @@ TESTS = \ +diff -urNp coreutils-8.19-orig/tests/Makefile.am coreutils-8.19/tests/Makefile.am +--- coreutils-8.19-orig/tests/Makefile.am 2012-08-20 13:51:39.856841699 +0200 ++++ coreutils-8.19/tests/Makefile.am 2012-08-20 13:52:04.085491266 +0200 +@@ -247,6 +247,7 @@ TESTS = \ misc/sort-debug-warn \ misc/sort-discrim \ misc/sort-files0-from \ @@ -4027,7 +4027,7 @@ diff -urNp coreutils-8.16-orig/tests/Makefile.am coreutils-8.16/tests/Makefile.a misc/sort-float \ misc/sort-merge \ misc/sort-merge-fdlimit \ -@@ -537,6 +538,10 @@ TESTS = \ +@@ -551,6 +552,10 @@ TESTS = \ $(root_tests) pr_data = \ @@ -4038,9 +4038,9 @@ diff -urNp coreutils-8.16-orig/tests/Makefile.am coreutils-8.16/tests/Makefile.a pr/0F \ pr/0FF \ pr/0FFnt \ -diff -urNp coreutils-8.16-orig/tests/misc/cut coreutils-8.16/tests/misc/cut ---- coreutils-8.16-orig/tests/misc/cut 2012-02-03 10:22:06.000000000 +0100 -+++ coreutils-8.16/tests/misc/cut 2012-03-26 17:40:49.000000000 +0200 +diff -urNp coreutils-8.19-orig/tests/misc/cut coreutils-8.19/tests/misc/cut +--- coreutils-8.19-orig/tests/misc/cut 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.19/tests/misc/cut 2012-08-20 13:52:04.086593767 +0200 @@ -23,14 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4070,41 +4070,98 @@ diff -urNp coreutils-8.16-orig/tests/misc/cut coreutils-8.16/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, -diff -urNp coreutils-8.16-orig/tests/misc/mb1.I coreutils-8.16/tests/misc/mb1.I ---- coreutils-8.16-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.16/tests/misc/mb1.I 2012-03-26 17:35:09.000000000 +0200 +diff -urNp coreutils-8.19-orig/tests/misc/expand coreutils-8.19/tests/misc/expand +--- coreutils-8.19-orig/tests/misc/expand 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.19/tests/misc/expand 2012-08-20 13:55:44.188467648 +0200 +@@ -23,6 +23,15 @@ use strict; + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + ++# uncommented according to upstream commit enabling multibyte paths ++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"}], +@@ -31,6 +40,37 @@ my @Tests = + ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>" a\tb"}], + ); + ++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 => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ ++ ++@Tests = triple_test \@Tests; ++ + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; + +diff -urNp coreutils-8.19-orig/tests/misc/mb1.I coreutils-8.19/tests/misc/mb1.I +--- coreutils-8.19-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.19/tests/misc/mb1.I 2012-08-20 13:52:04.086593767 +0200 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.16-orig/tests/misc/mb1.X coreutils-8.16/tests/misc/mb1.X ---- coreutils-8.16-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.16/tests/misc/mb1.X 2012-03-26 17:35:09.000000000 +0200 +diff -urNp coreutils-8.19-orig/tests/misc/mb1.X coreutils-8.19/tests/misc/mb1.X +--- coreutils-8.19-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.19/tests/misc/mb1.X 2012-08-20 13:52:04.087526516 +0200 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.16-orig/tests/misc/mb2.I coreutils-8.16/tests/misc/mb2.I ---- coreutils-8.16-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.16/tests/misc/mb2.I 2012-03-26 17:35:09.000000000 +0200 +diff -urNp coreutils-8.19-orig/tests/misc/mb2.I coreutils-8.19/tests/misc/mb2.I +--- coreutils-8.19-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.19/tests/misc/mb2.I 2012-08-20 13:52:04.088593815 +0200 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.16-orig/tests/misc/mb2.X coreutils-8.16/tests/misc/mb2.X ---- coreutils-8.16-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.16/tests/misc/mb2.X 2012-03-26 17:35:09.000000000 +0200 +diff -urNp coreutils-8.19-orig/tests/misc/mb2.X coreutils-8.19/tests/misc/mb2.X +--- coreutils-8.19-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.19/tests/misc/mb2.X 2012-08-20 13:52:04.088593815 +0200 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.16-orig/tests/misc/sort-mb-tests coreutils-8.16/tests/misc/sort-mb-tests ---- coreutils-8.16-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.16/tests/misc/sort-mb-tests 2012-03-26 17:35:09.000000000 +0200 +diff -urNp coreutils-8.19-orig/tests/misc/sort-mb-tests coreutils-8.19/tests/misc/sort-mb-tests +--- coreutils-8.19-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.19/tests/misc/sort-mb-tests 2012-08-20 13:52:04.089593318 +0200 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils.spec b/coreutils.spec index 8a07c90..9cb8f55 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -376,6 +376,7 @@ fi %changelog * Mon Aug 20 2012 Ondrej Vasik 8.19-1 - new upstream release 8.19 +- fix multibyte issues in cut and expand (M.Briza, #821260) * Sun Aug 12 2012 Ondrej Vasik 8.18-1 - new upstream release 8.18 From 8b177c8f263ac4fff6e382f7e6cff35f3f3f8ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 27 Oct 2012 21:14:41 +0200 Subject: [PATCH 177/523] Update patches for new-upstream release 8.20, please DO NOT BUILD - no su --- .gitignore | 1 + coreutils-6.10-configuration.patch | 17 ++------ coreutils-df-direct.patch | 17 ++------ coreutils-i18n.patch | 64 ++++++++++-------------------- coreutils-selinux.patch | 18 ++++----- coreutils.spec | 7 +++- sources | 2 +- 7 files changed, 43 insertions(+), 83 deletions(-) diff --git a/.gitignore b/.gitignore index 8d8414a..69c2468 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /coreutils-8.17.tar.xz /coreutils-8.18.tar.xz /coreutils-8.19.tar.xz +/coreutils-8.20.tar.xz diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 7f5e6ee..57cbd82 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -111,20 +111,9 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module utimens-tests -diff -urNp coreutils-8.17-orig/tests/Makefile.am coreutils-8.17/tests/Makefile.am ---- coreutils-8.17-orig/tests/Makefile.am -+++ coreutils-8.17/tests/Makefile.am -@@ -87,7 +87,6 @@ TESTS = \ - rm/cycle \ - cp/link-heap \ - misc/tty-eof \ -- tail-2/inotify-hash-abuse \ - tail-2/inotify-hash-abuse2 \ - tail-2/F-vs-missing \ - tail-2/F-vs-rename \ -diff -urNp coreutils-8.13-orig/tests/touch/no-dereference coreutils-8.13/tests/touch/no-dereference ---- coreutils-8.13-orig/tests/touch/no-dereference 2011-08-08 09:42:16.000000000 +0200 -+++ coreutils-8.13/tests/touch/no-dereference 2011-09-09 10:15:21.167060702 +0200 +diff -urNp coreutils-8.13-orig/tests/touch/no-dereference.sh coreutils-8.13/tests/touch/no-dereference.sh +--- coreutils-8.13-orig/tests/touch/no-dereference.sh 2011-08-08 09:42:16.000000000 +0200 ++++ coreutils-8.13/tests/touch/no-dereference.sh 2011-09-09 10:15:21.167060702 +0200 @@ -42,6 +42,8 @@ test -f nowhere && fail=1 grep '^#define HAVE_UTIMENSAT 1' "$CONFIG_HEADER" > /dev/null || grep '^#define HAVE_LUTIMES 1' "$CONFIG_HEADER" > /dev/null || diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 937c183..fbf67cb 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -108,9 +108,9 @@ diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c if (human_output_opts == -1) { if (posix_format) -diff -urNp coreutils-8.16-orig/tests/df/direct coreutils-8.16/tests/df/direct ---- coreutils-8.16-orig/tests/df/direct 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.16/tests/df/direct 2012-03-26 17:31:31.102897406 +0200 +diff -urNp coreutils-8.16-orig/tests/df/direct.sh coreutils-8.16/tests/df/direct.sh +--- coreutils-8.16-orig/tests/df/direct.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.16/tests/df/direct.sh 2012-03-26 17:31:31.102897406 +0200 @@ -0,0 +1,55 @@ +#!/bin/sh +# Ensure "df --direct" works as documented @@ -167,14 +167,3 @@ diff -urNp coreutils-8.16-orig/tests/df/direct coreutils-8.16/tests/df/direct +compare file_out file_exp || fail=1 + +Exit $fail -diff -urNp coreutils-8.16-orig/tests/Makefile.am coreutils-8.16/tests/Makefile.am ---- coreutils-8.16-orig/tests/Makefile.am 2012-03-26 17:31:08.642764437 +0200 -+++ coreutils-8.16/tests/Makefile.am 2012-03-26 17:31:31.104015483 +0200 -@@ -379,6 +379,7 @@ TESTS = \ - dd/stderr \ - dd/unblock \ - dd/unblock-sync \ -+ df/direct \ - df/total-verify \ - du/2g \ - du/8gb \ diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index a5b9aaf..956aac9 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4016,31 +4016,9 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.19-orig/tests/Makefile.am coreutils-8.19/tests/Makefile.am ---- coreutils-8.19-orig/tests/Makefile.am 2012-08-20 13:51:39.856841699 +0200 -+++ coreutils-8.19/tests/Makefile.am 2012-08-20 13:52:04.085491266 +0200 -@@ -247,6 +247,7 @@ TESTS = \ - misc/sort-debug-warn \ - misc/sort-discrim \ - misc/sort-files0-from \ -+ misc/sort-mb-tests \ - misc/sort-float \ - misc/sort-merge \ - misc/sort-merge-fdlimit \ -@@ -551,6 +552,10 @@ TESTS = \ - $(root_tests) - - pr_data = \ -+ misc/mb1.X \ -+ misc/mb1.I \ -+ misc/mb2.X \ -+ misc/mb2.I \ - pr/0F \ - pr/0FF \ - pr/0FFnt \ -diff -urNp coreutils-8.19-orig/tests/misc/cut coreutils-8.19/tests/misc/cut ---- coreutils-8.19-orig/tests/misc/cut 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.19/tests/misc/cut 2012-08-20 13:52:04.086593767 +0200 +diff -urNp coreutils-8.20-orig/tests/misc/cut.pl coreutils-8.20/tests/misc/cut.pl +--- coreutils-8.20-orig/tests/misc/cut.pl 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.20/tests/misc/cut.pl 2012-08-20 13:52:04.086593767 +0200 @@ -23,14 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4070,9 +4048,9 @@ diff -urNp coreutils-8.19-orig/tests/misc/cut coreutils-8.19/tests/misc/cut ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, -diff -urNp coreutils-8.19-orig/tests/misc/expand coreutils-8.19/tests/misc/expand ---- coreutils-8.19-orig/tests/misc/expand 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.19/tests/misc/expand 2012-08-20 13:55:44.188467648 +0200 +diff -urNp coreutils-8.20-orig/tests/misc/expand.pl coreutils-8.20/tests/misc/expand.pl +--- coreutils-8.20-orig/tests/misc/expand.pl 2012-07-21 16:54:31.000000000 +0200 ++++ coreutils-8.20/tests/misc/expand.pl 2012-08-20 13:55:44.188467648 +0200 @@ -23,6 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4127,41 +4105,41 @@ diff -urNp coreutils-8.19-orig/tests/misc/expand coreutils-8.19/tests/misc/expan my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.19-orig/tests/misc/mb1.I coreutils-8.19/tests/misc/mb1.I ---- coreutils-8.19-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.19/tests/misc/mb1.I 2012-08-20 13:52:04.086593767 +0200 +diff -urNp coreutils-8.20-orig/tests/misc/mb1.I coreutils-8.20/tests/misc/mb1.I +--- coreutils-8.20-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.20/tests/misc/mb1.I 2012-08-20 13:52:04.086593767 +0200 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.19-orig/tests/misc/mb1.X coreutils-8.19/tests/misc/mb1.X ---- coreutils-8.19-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.19/tests/misc/mb1.X 2012-08-20 13:52:04.087526516 +0200 +diff -urNp coreutils-8.20-orig/tests/misc/mb1.X coreutils-8.20/tests/misc/mb1.X +--- coreutils-8.20-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.20/tests/misc/mb1.X 2012-08-20 13:52:04.087526516 +0200 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.19-orig/tests/misc/mb2.I coreutils-8.19/tests/misc/mb2.I ---- coreutils-8.19-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.19/tests/misc/mb2.I 2012-08-20 13:52:04.088593815 +0200 +diff -urNp coreutils-8.20-orig/tests/misc/mb2.I coreutils-8.20/tests/misc/mb2.I +--- coreutils-8.20-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.20/tests/misc/mb2.I 2012-08-20 13:52:04.088593815 +0200 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.19-orig/tests/misc/mb2.X coreutils-8.19/tests/misc/mb2.X ---- coreutils-8.19-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.19/tests/misc/mb2.X 2012-08-20 13:52:04.088593815 +0200 +diff -urNp coreutils-8.20-orig/tests/misc/mb2.X coreutils-8.20/tests/misc/mb2.X +--- coreutils-8.20-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.20/tests/misc/mb2.X 2012-08-20 13:52:04.088593815 +0200 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.19-orig/tests/misc/sort-mb-tests coreutils-8.19/tests/misc/sort-mb-tests ---- coreutils-8.19-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.19/tests/misc/sort-mb-tests 2012-08-20 13:52:04.089593318 +0200 +diff -urNp coreutils-8.20-orig/tests/misc/sort-mb-tests.sh coreutils-8.20/tests/misc/sort-mb-tests.sh +--- coreutils-8.20-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.20/tests/misc/sort-mb-tests.sh 2012-08-20 13:52:04.089593318 +0200 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 89aa5fd..9aab59c 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -62,8 +62,8 @@ diff -urNp coreutils-8.13-orig/src/copy.h coreutils-8.13/src/copy.h --- coreutils-8.13-orig/src/copy.h 2011-07-28 12:38:27.000000000 +0200 +++ coreutils-8.13/src/copy.h 2011-09-09 10:30:39.565563712 +0200 @@ -158,6 +158,9 @@ struct cp_options - bool preserve_mode; bool preserve_timestamps; + bool explicit_no_preserve_mode; + /* If true, attempt to set specified security context */ + bool set_security_context; @@ -101,7 +101,7 @@ diff -urNp coreutils-8.13-orig/src/cp.c coreutils-8.13/src/cp.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); @@ -786,6 +791,7 @@ cp_option_init (struct cp_options *x) - x->preserve_timestamps = false; + x->explicit_no_preserve_mode = false; x->preserve_security_context = false; x->require_preserve_context = false; + x->set_security_context = false; @@ -609,8 +609,8 @@ diff -urNp coreutils-8.13-orig/src/mv.c coreutils-8.13/src/mv.c --- coreutils-8.13-orig/src/mv.c 2011-07-28 12:38:27.000000000 +0200 +++ coreutils-8.13/src/mv.c 2011-09-09 10:30:39.578562234 +0200 @@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x) - x->preserve_mode = true; x->preserve_timestamps = true; + x->explicit_no_preserve_mode= false; x->preserve_security_context = selinux_enabled; + x->set_security_context = false; x->reduce_diagnostics = false; @@ -628,9 +628,9 @@ diff -urNp coreutils-8.13-orig/src/runcon.c coreutils-8.13/src/runcon.c With neither CONTEXT nor COMMAND, print the current security context.\n\ \n\ CONTEXT Complete security context\n\ -diff -urNp coreutils-8.17-orig/tests/init.cfg coreutils-8.17/tests/init.cfg ---- coreutils-8.17-orig/tests/init.cfg -+++ coreutils-8.17/tests/init.cfg +diff -urNp coreutils-8.20-orig/init.cfg coreutils-8.20/init.cfg +--- coreutils-8.20-orig/init.cfg ++++ coreutils-8.20/init.cfg @@ -253,8 +253,8 @@ require_selinux_() # Independent of whether SELinux is enabled system-wide, @@ -642,9 +642,9 @@ diff -urNp coreutils-8.17-orig/tests/init.cfg coreutils-8.17/tests/init.cfg skip_ "this system (or maybe just" \ "the current file system) lacks SELinux support" ;; -diff -urNp coreutils-8.17-orig/tests/misc/selinux coreutils-8.17/tests/misc/selinux ---- coreutils-8.17-orig/tests/misc/selinux -+++ coreutils-8.17/tests/misc/selinux +diff -urNp coreutils-8.20-orig/tests/misc/selinux coreutils-8.20/tests/misc/selinux.sh +--- coreutils-8.20-orig/tests/misc/selinux.sh ++++ coreutils-8.20/tests/misc/selinux.sh @@ -37,7 +37,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. diff --git a/coreutils.spec b/coreutils.spec index 9cb8f55..110113f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,6 +1,6 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.19 +Version: 8.20 Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base @@ -149,7 +149,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch951 -p1 -b .selinuxman %patch952 -p1 -b .cpZ -chmod a+x tests/misc/sort-mb-tests tests/df/direct || : +chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh || : #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -374,6 +374,9 @@ fi %{_sbindir}/chroot %changelog +* Sat Oct 27 2012 Ondrej Vasik 8.20-1 +- new upstream release 8.20 + * Mon Aug 20 2012 Ondrej Vasik 8.19-1 - new upstream release 8.19 - fix multibyte issues in cut and expand (M.Briza, #821260) diff --git a/sources b/sources index 924eab4..2abca86 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -1a01231a2f3ed37c0efc073ccdda9375 coreutils-8.19.tar.xz +3d69af8f561fce512538a9fe85f147ff coreutils-8.20.tar.xz From 5580b508e3df43b9a7992f2375f060871414cae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 1 Nov 2012 15:10:38 +0100 Subject: [PATCH 178/523] Temporarily require util-linux >= 2.22.1-3 (to prevent missing su/runuser on system), disable getlogin gnulib tests (occasinally troubles in mock environment) --- coreutils-6.10-configuration.patch | 12 ++++++++++++ coreutils.spec | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 57cbd82..4010a62 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -42,6 +42,18 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module fchdir-tests +@@ -874,9 +874,9 @@ EXTRA_DIST += test-getloadavg.c signatur + + ## begin gnulib module getlogin-tests + +-TESTS += test-getlogin +-check_PROGRAMS += test-getlogin +-EXTRA_DIST += test-getlogin.c signature.h macros.h ++#TESTS += test-getlogin ++#check_PROGRAMS += test-getlogin ++#EXTRA_DIST += test-getlogin.c signature.h macros.h + + ## end gnulib module getlogin-tests @@ -918,10 +918,10 @@ EXTRA_DIST += test-link.h test-link.c si ## begin gnulib module linkat-tests diff --git a/coreutils.spec b/coreutils.spec index 110113f..3113514 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -115,6 +115,8 @@ Obsoletes: stat <= 3.3 Obsoletes: textutils <= 2.0.21 #coreutils-libs dropped in f17 Obsoletes: coreutils-libs < 8.13 +#require util-linux >=2.22.1-3 to prevent lack of su/runuser on system +Requires: util-linux >= 2.22.1-3 %description These are the GNU core utilities. This package is the combination of @@ -376,6 +378,8 @@ fi %changelog * Sat Oct 27 2012 Ondrej Vasik 8.20-1 - new upstream release 8.20 +- Temporarily require util-linux >= 2.22.1-3 (to prevent missing + su/runuser on system) * Mon Aug 20 2012 Ondrej Vasik 8.19-1 - new upstream release 8.19 From edc2e6afec6e3eeee7c25bf76102eea5a3839fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 1 Nov 2012 15:43:12 +0100 Subject: [PATCH 179/523] oops --- coreutils-6.10-configuration.patch | 1 + 1 file changed, 1 insertion(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 4010a62..0fa0c2a 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -54,6 +54,7 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test +#EXTRA_DIST += test-getlogin.c signature.h macros.h ## end gnulib module getlogin-tests + @@ -918,10 +918,10 @@ EXTRA_DIST += test-link.h test-link.c si ## begin gnulib module linkat-tests From c718b5ec2ab5ae6ba48c0503279e3edb52809fbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 1 Nov 2012 20:52:47 +0100 Subject: [PATCH 180/523] fix build failure for undeclared O_SYNC in rawhide, remove su and pam relicts --- coreutils-6.10-configuration.patch | 15 +++++++++++++++ coreutils.spec | 5 ++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 0fa0c2a..b3d92dc 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -136,3 +136,18 @@ diff -urNp coreutils-8.13-orig/tests/touch/no-dereference.sh coreutils-8.13/test # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to +diff -urNp coreutils-8.20-orig/src/dd.c coreutils-8.20/src/dd.c +--- coreutils-8.20-orig/src/dd.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/dd.c 2012-11-01 20:50:18.341215667 +0100 +@@ -71,6 +71,10 @@ + # define O_CIO 0 + #endif + ++#ifndef O_SYNC ++# define O_SYNC 0 ++#endif ++ + /* On AIX 5.1 and AIX 5.2, O_NOCACHE is defined via + and would interfere with our use of that name, below. */ + #undef O_NOCACHE + diff --git a/coreutils.spec b/coreutils.spec index 3113514..97749b6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -166,9 +166,9 @@ touch aclocal.m4 configure config.hin Makefile.in */Makefile.in aclocal -I m4 autoconf --force automake --copy --add-missing -%configure --enable-largefile %{?!nopam:--enable-pam} \ +%configure --enable-largefile \ %{?!noselinux:--enable-selinux} \ - --enable-install-program=su,hostname,arch \ + --enable-install-program=hostname,arch \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : @@ -176,7 +176,6 @@ automake --copy --add-missing touch man/*.x make all %{?_smp_mflags} -# %{?!nopam:CPPFLAGS="-DUSE_PAM"} # XXX docs should say /var/run/[uw]tmp not /etc/[uw]tmp sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi From 72f2f9f3ebd00618dcf3716b62172ad0ec670bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 1 Nov 2012 21:39:51 +0100 Subject: [PATCH 181/523] removed unhelpful hack --- coreutils-6.10-configuration.patch | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index b3d92dc..0fa0c2a 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -136,18 +136,3 @@ diff -urNp coreutils-8.13-orig/tests/touch/no-dereference.sh coreutils-8.13/test # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to -diff -urNp coreutils-8.20-orig/src/dd.c coreutils-8.20/src/dd.c ---- coreutils-8.20-orig/src/dd.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/dd.c 2012-11-01 20:50:18.341215667 +0100 -@@ -71,6 +71,10 @@ - # define O_CIO 0 - #endif - -+#ifndef O_SYNC -+# define O_SYNC 0 -+#endif -+ - /* On AIX 5.1 and AIX 5.2, O_NOCACHE is defined via - and would interfere with our use of that name, below. */ - #undef O_NOCACHE - From ca6f66d311d4ba79213aa03732e220c760b19a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 2 Nov 2012 08:34:04 +0100 Subject: [PATCH 182/523] temporary hack to make coreutils build --- coreutils-6.10-configuration.patch | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 0fa0c2a..4c54189 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -136,3 +136,17 @@ diff -urNp coreutils-8.13-orig/tests/touch/no-dereference.sh coreutils-8.13/test # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to +diff -urNp coreutils-8.20-orig/lib/fcntl.in.h coreutils-8.20/lib/fcntl.in.h +--- coreutils-8.20-orig/lib/fcntl.in.h ++++ coreutils-8.20/lib/fcntl.in.h +@@ -71,6 +71,10 @@ + # define O_SYNC 0 + #endif + ++#ifndef __O_SYNC ++# define __O_SYNC 04000000 ++#endif ++ + #ifndef O_TTY_INIT + # define O_TTY_INIT 0 + #endif From 7e4f1a381eea4a4ef2a9dd584ea678dc808a5bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 5 Nov 2012 09:04:38 +0100 Subject: [PATCH 183/523] disable the temporary O_SYNC fix (glibc is fixed - #872366) --- coreutils-6.10-configuration.patch | 14 -------------- coreutils.spec | 5 ++++- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 4c54189..0fa0c2a 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -136,17 +136,3 @@ diff -urNp coreutils-8.13-orig/tests/touch/no-dereference.sh coreutils-8.13/test # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to -diff -urNp coreutils-8.20-orig/lib/fcntl.in.h coreutils-8.20/lib/fcntl.in.h ---- coreutils-8.20-orig/lib/fcntl.in.h -+++ coreutils-8.20/lib/fcntl.in.h -@@ -71,6 +71,10 @@ - # define O_SYNC 0 - #endif - -+#ifndef __O_SYNC -+# define __O_SYNC 04000000 -+#endif -+ - #ifndef O_TTY_INIT - # define O_TTY_INIT 0 - #endif diff --git a/coreutils.spec b/coreutils.spec index 97749b6..f1dd501 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.20 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -375,6 +375,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Nov 05 2012 Ondrej Vasik 8.20-2 +- disable the temporary O_SYNC fix (glibc is fixed - #872366) + * Sat Oct 27 2012 Ondrej Vasik 8.20-1 - new upstream release 8.20 - Temporarily require util-linux >= 2.22.1-3 (to prevent missing From d9f99cf09b2a23b9b62514f67d30a6086449b96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 6 Dec 2012 17:11:49 +0100 Subject: [PATCH 184/523] fix factor on 32bit powerpc (upstream, #884715) --- coreutils-8.20-powerpcfactor.patch | 12 ++++++++++++ coreutils.spec | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.20-powerpcfactor.patch diff --git a/coreutils-8.20-powerpcfactor.patch b/coreutils-8.20-powerpcfactor.patch new file mode 100644 index 0000000..648d21a --- /dev/null +++ b/coreutils-8.20-powerpcfactor.patch @@ -0,0 +1,12 @@ +diff -urNp coreutils-8.20-orig/src/longlong.h coreutils-8.20/src/longlong.h +--- coreutils-8.20-orig/src/longlong.h 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/longlong.h 2012-12-06 17:09:12.865695463 +0100 +@@ -1392,7 +1392,7 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype + + /* We should test _IBMR2 here when we add assembly support for the system + vendor compilers. */ +-#if HAVE_HOST_CPU_FAMILY_powerpc && W_TYPE_SIZE == 64 ++#if HAVE_HOST_CPU_FAMILY_powerpc && W_TYPE_SIZE == 64 && defined (_LP64) + #if !defined (_LONG_LONG_LIMB) + /* _LONG_LONG_LIMB is ABI=mode32 where adde operates on 32-bit values. So + use adde etc only when not _LONG_LONG_LIMB. */ diff --git a/coreutils.spec b/coreutils.spec index f1dd501..0c2e640 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.20 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -14,6 +14,7 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream +Patch1: coreutils-8.20-powerpcfactor.patch # Our patches #general patch to workaround koji build system issues @@ -126,6 +127,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream +%patch1 -p1 -b .ppcfactor # Our patches %patch100 -p1 -b .configure @@ -375,6 +377,9 @@ fi %{_sbindir}/chroot %changelog +* Thu Dec 06 2012 Ondrej Vasik 8.20-3 +- fix factor on 32bit powerpc (upstream, #884715) + * Mon Nov 05 2012 Ondrej Vasik 8.20-2 - disable the temporary O_SYNC fix (glibc is fixed - #872366) From c767e7c27a532a2b6ecd1de357fb35baa0dba592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 11 Dec 2012 08:34:16 +0100 Subject: [PATCH 185/523] fix showing duplicates in df (#709351, O.Oprala, B.Voelker) --- coreutils-8.20-df-duplicates.patch | 264 +++++++++++++++++++++++++++++ coreutils.spec | 7 +- 2 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.20-df-duplicates.patch diff --git a/coreutils-8.20-df-duplicates.patch b/coreutils-8.20-df-duplicates.patch new file mode 100644 index 0000000..6c8c8d8 --- /dev/null +++ b/coreutils-8.20-df-duplicates.patch @@ -0,0 +1,264 @@ +diff -urNp coreutils-8.20-orig/doc/coreutils.texi coreutils-8.20/doc/coreutils.texi +--- coreutils-8.20-orig/doc/coreutils.texi 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/doc/coreutils.texi 2012-12-10 14:41:33.532650289 +0100 +@@ -10597,6 +10597,14 @@ Normally the disk space is printed in un + 1024 bytes, but this can be overridden (@pxref{Block size}). + Non-integer quantities are rounded up to the next higher unit. + ++For bind mounts and without arguments, @command{df} only outputs the statistics ++for the first occurence of that device in the list of file systems (@var{mtab}), ++i.e., it hides duplicate entries, unless the @option{-a} option is specified. ++ ++By default, @command{df} omits the early-boot pseudo file system type ++@samp{rootfs}, unless the @option{-a} option is specified or that file system ++type is explicitly to be included by using the @option{-t} option. ++ + @cindex disk device file + @cindex device file, disk + If an argument @var{file} is a disk device file containing a mounted +diff -urNp coreutils-8.20-orig/src/df.c coreutils-8.20/src/df.c +--- coreutils-8.20-orig/src/df.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/df.c 2012-12-10 14:41:33.534649048 +0100 +@@ -46,6 +46,17 @@ + /* If true, show inode information. */ + static bool inode_format; + ++/* Filled with device numbers of examined file systems to avoid ++ duplicities in output. */ ++struct devlist ++{ ++ dev_t dev_num; ++ struct devlist *next; ++}; ++ ++/* Store of already-processed device numbers. */ ++static struct devlist *devlist_head; ++ + /* If true, show even file systems with zero size or + uninteresting types. */ + static bool show_all_fs; +@@ -57,6 +68,12 @@ static bool show_local_fs; + command line argument -- even if it's a dummy (automounter) entry. */ + static bool show_listed_fs; + ++/* If true, include rootfs in the output. */ ++static bool show_rootfs; ++ ++/* The literal name of the initial root file system. */ ++static char const *ROOTFS = "rootfs"; ++ + /* Human-readable options for output. */ + static int human_output_opts; + +@@ -372,6 +389,29 @@ excluded_fstype (const char *fstype) + return false; + } + ++/* Check if the device was already examined. */ ++ ++static bool ++dev_examined (char const *mount_dir, char const *devname) ++{ ++ struct stat buf; ++ if (-1 == stat (mount_dir, &buf)) ++ return false; ++ ++ struct devlist *devlist = devlist_head; ++ for ( ; devlist; devlist = devlist->next) ++ if (devlist->dev_num == buf.st_dev) ++ return true; ++ ++ /* Add the device number to the global list devlist. */ ++ devlist = xmalloc (sizeof *devlist); ++ devlist->dev_num = buf.st_dev; ++ devlist->next = devlist_head; ++ devlist_head = devlist; ++ ++ return false; ++} ++ + /* Return true if N is a known integer value. On many file systems, + UINTMAX_MAX represents an unknown value; on AIX, UINTMAX_MAX - 1 + represents unknown. Use a rule that works on AIX file systems, and +@@ -496,6 +536,15 @@ get_dev (char const *disk, char const *m + if (!selected_fstype (fstype) || excluded_fstype (fstype)) + return; + ++ if (process_all && !show_all_fs && !show_listed_fs) ++ { ++ /* No arguments nor "df -a", then check if df has to ... */ ++ if (!show_rootfs && STREQ (disk, ROOTFS)) ++ return; /* ... skip rootfs: (unless -trootfs is given. */ ++ if (dev_examined (mount_point, disk)) ++ return; /* ... skip duplicate entries (bind mounts). */ ++ } ++ + /* If MOUNT_POINT is NULL, then the file system is not mounted, and this + program reports on the file system that the special file is on. + It would be better to report on the unmounted file system, +@@ -1005,6 +1054,7 @@ main (int argc, char **argv) + /* Accept -F as a synonym for -t for compatibility with Solaris. */ + case 't': + add_fs_type (optarg); ++ show_rootfs = selected_fstype (ROOTFS); + break; + + case 'v': /* For SysV compatibility. */ +@@ -1149,6 +1199,14 @@ main (int argc, char **argv) + diagnostic, e.g., if all have been excluded. */ + if (exit_status == EXIT_SUCCESS && ! file_systems_processed) + error (EXIT_FAILURE, 0, _("no file systems processed")); ++ IF_LINT ( ++ while (devlist_head) ++ { ++ struct devlist *devlist = devlist_head->next; ++ free (devlist_head); ++ devlist_head = devlist; ++ } ++ ); + + exit (exit_status); + } +diff -urNp coreutils-8.20-orig/tests/df/skip-duplicates.sh coreutils-8.20/tests/df/skip-duplicates.sh +--- coreutils-8.20-orig/tests/df/skip-duplicates.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.20/tests/df/skip-duplicates.sh 2012-12-10 14:41:33.535280173 +0100 +@@ -0,0 +1,77 @@ ++#!/bin/sh ++# Test df's behavior when the mount list contains duplicate entries. ++# This test is skipped on systems that lack LD_PRELOAD support; that's fine. ++ ++# Copyright (C) 2012 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_ df ++ ++df || skip_ "df fails" ++ ++# Simulate an mtab file with two entries of the same device number. ++cat > k.c <<'EOF' || framework_failure_ ++#include ++#include ++ ++struct mntent *getmntent (FILE *fp) ++{ ++ /* Prove that LD_PRELOAD works. */ ++ static int done = 0; ++ if (!done) ++ { ++ fclose (fopen ("x", "w")); ++ ++done; ++ } ++ ++ static struct mntent mntent; ++ ++ while (done++ < 3) ++ { ++ mntent.mnt_fsname = "fsname"; ++ mntent.mnt_dir = "/"; ++ mntent.mnt_type = "-"; ++ ++ return &mntent; ++ } ++ return NULL; ++} ++EOF ++ ++# Then compile/link it: ++gcc --std=gnu99 -shared -fPIC -ldl -O2 k.c -o k.so \ ++ || skip_ "getmntent hack does not work on this platform" ++ ++# Test if LD_PRELOAD works: ++LD_PRELOAD=./k.so df ++test -f x || skip_ "internal test failure: maybe LD_PRELOAD doesn't work?" ++ ++# The fake mtab file should only contain 2 entries, both ++# having the same device number; thus the output should ++# consist of a header and one entry. ++LD_PRELOAD=./k.so df >out || fail=1 ++test $(wc -l out || fail=1 ++test $(wc -l out || fail=1 ++test $(wc -l . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ df ++ ++df || skip_ "df fails" ++ ++# Verify that rootfs is in mtab (and shown when the -a option is specified). ++df -a >out || fail=1 ++grep '^rootfs' out || skip_ "no rootfs in mtab" ++ ++# Ensure that rootfs is supressed when no options is specified. ++df >out || fail=1 ++grep '^rootfs' out && { fail=1; cat out; } ++ ++# Ensure that the rootfs is shown when explicitly specifying "-t rootfs". ++df -t rootfs >out || fail=1 ++grep '^rootfs' out || { fail=1; cat out; } ++ ++# Ensure that the rootfs is shown when explicitly specifying "-t rootfs", ++# even when the -a option is specified. ++df -t rootfs -a >out || fail=1 ++grep '^rootfs' out || { fail=1; cat out; } ++ ++# Ensure that the rootfs is omitted in all_fs mode when it is explicitly ++# black-listed. ++df -a -x rootfs >out || fail=1 ++grep '^rootfs' out && { fail=1; cat out; } ++ ++Exit $fail +diff -urNp coreutils-8.20-orig/tests/local.mk coreutils-8.20/tests/local.mk +--- coreutils-8.20-orig/tests/local.mk 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/tests/local.mk 2012-12-10 14:41:33.536310753 +0100 +@@ -456,6 +456,8 @@ all_tests = \ + tests/df/unreadable.sh \ + tests/df/total-unprocessed.sh \ + tests/df/no-mtab-status.sh \ ++ tests/df/skip-duplicates.sh \ ++ tests/df/skip-rootfs.sh \ + tests/dd/direct.sh \ + tests/dd/misc.sh \ + tests/dd/nocache.sh \ diff --git a/coreutils.spec b/coreutils.spec index 0c2e640..5f38525 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.20 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -15,6 +15,7 @@ Source106: coreutils-colorls.csh # From upstream Patch1: coreutils-8.20-powerpcfactor.patch +Patch2: coreutils-8.20-df-duplicates.patch # Our patches #general patch to workaround koji build system issues @@ -128,6 +129,7 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .ppcfactor +%patch2 -p1 -b .duplic # Our patches %patch100 -p1 -b .configure @@ -377,6 +379,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Dec 10 2012 Ondrej Vasik 8.20-4 +- fix showing duplicates in df (#709351, O.Oprala, B.Voelker) + * Thu Dec 06 2012 Ondrej Vasik 8.20-3 - fix factor on 32bit powerpc (upstream, #884715) From 11aeb4e7348e0dd978a948f5423c7cb6e4f8715e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 20 Dec 2012 09:47:38 +0100 Subject: [PATCH 186/523] seq: fix newline output when -s specified (upstream) --- coreutils-8.20-seq-s.patch | 113 +++++++++++++++++++++++++++++++++++++ coreutils.spec | 7 ++- 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.20-seq-s.patch diff --git a/coreutils-8.20-seq-s.patch b/coreutils-8.20-seq-s.patch new file mode 100644 index 0000000..ecf5338 --- /dev/null +++ b/coreutils-8.20-seq-s.patch @@ -0,0 +1,113 @@ +From 9d9cdfd5df898ade2e680aab5ce37fcd0032c687 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Wed, 19 Dec 2012 19:27:10 +0000 +Subject: [PATCH] seq: fix newline output when -s specified + +This regression was introduced in commit v8.19-132-g3786fb6. + +* src/seq.c (seq_fast): Don't use puts() to output the first number, +and instead insert it into the buffer as for other numbers. +Also output the terminator unconditionally. +* tests/misc/seq.pl: Add some basic tests for the -s option. +* NEWS: Mention the fix. +* THANKS.in: Reported by Philipp Gortan. +--- + NEWS | 4 ++++ + THANKS.in | 1 + + src/seq.c | 20 +++++++++++++------- + tests/misc/seq.pl | 5 +++++ + 4 files changed, 23 insertions(+), 7 deletions(-) + +diff --git a/NEWS b/NEWS +index e4472df..ae7ec2a 100644 +--- a/NEWS ++++ b/NEWS +@@ -43,6 +43,10 @@ GNU coreutils NEWS -*- outline -*- + the output numbers are properly aligned and of the correct width. + [This bug was present in "the beginning".] + ++ seq -s now doesn't output an erroneous newline after the first number, and ++ outputs a newline after the last number rather than a trailing separator. ++ [bug introduced in coreutils-8.20] ++ + ** Changes in behavior + + df --total now prints '-' into the target column (mount point) of the +diff --git a/THANKS.in b/THANKS.in +index c2651e7..67b60b9 100644 +--- a/THANKS.in ++++ b/THANKS.in +@@ -505,6 +505,7 @@ Phil Richards phil.richards@vf.vodafone.co.uk + Philippe De Muyter phdm@macqel.be + Philippe Schnoebelen Philippe.Schnoebelen@imag.fr + Phillip Jones mouse@datastacks.com ++Philipp Gortan gortan@gmail.com + Philipp Thomas pth@suse.de + Piergiorgio Sartor sartor@sony.de + Pieter Bowman bowman@math.utah.edu +diff --git a/src/seq.c b/src/seq.c +index 9c2c51f..108808b 100644 +--- a/src/seq.c ++++ b/src/seq.c +@@ -419,30 +419,36 @@ seq_fast (char const *a, char const *b) + bool ok = cmp (p, p_len, q, q_len) <= 0; + if (ok) + { +- /* Buffer at least this many output lines per fwrite call. ++ /* Buffer at least this many numbers per fwrite call. + This gives a speed-up of more than 2x over the unbuffered code + when printing the first 10^9 integers. */ + enum {N = 40}; + char *buf = xmalloc (N * (n + 1)); + char const *buf_end = buf + N * (n + 1); + +- puts (p); + char *z = buf; ++ ++ /* Write first number to buffer. */ ++ z = mempcpy (z, p, p_len); ++ ++ /* Append separator then number. */ + while (cmp (p, p_len, q, q_len) < 0) + { ++ *z++ = *separator; + incr (&p, &p_len); + z = mempcpy (z, p, p_len); +- *z++ = *separator; +- if (buf_end - n - 1 < z) ++ /* If no place for another separator + number then ++ output buffer so far, and reset to start of buffer. */ ++ if (buf_end - (n + 1) < z) + { + fwrite (buf, z - buf, 1, stdout); + z = buf; + } + } + +- /* Write any remaining, buffered output. */ +- if (buf < z) +- fwrite (buf, z - buf, 1, stdout); ++ /* Write any remaining buffered output, and the terminator. */ ++ *z++ = *terminator; ++ fwrite (buf, z - buf, 1, stdout); + + IF_LINT (free (buf)); + } +diff --git a/tests/misc/seq.pl b/tests/misc/seq.pl +index 447baa4..416b839 100755 +--- a/tests/misc/seq.pl ++++ b/tests/misc/seq.pl +@@ -128,6 +128,11 @@ my @Tests = + ['long-leading-zeros2', qw(000 02), {OUT => [qw(0 1 2)]}], + ['long-leading-zeros3', qw(00 02), {OUT => [qw(0 1 2)]}], + ['long-leading-zeros4', qw(0 02), {OUT => [qw(0 1 2)]}], ++ ++ # Exercise the -s option, which was broken in 8.20 ++ ['sep-1', qw(-s, 1 3), {OUT => [qw(1,2,3)]}], ++ ['sep-2', qw(-s, 1 1), {OUT => [qw(1)]}], ++ ['sep-3', qw(-s,, 1 3), {OUT => [qw(1,,2,,3)]}], + ); + + # Append a newline to each entry in the OUT array. +-- +1.7.6.4 diff --git a/coreutils.spec b/coreutils.spec index 5f38525..bbd1fb6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.20 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -16,6 +16,7 @@ Source106: coreutils-colorls.csh # From upstream Patch1: coreutils-8.20-powerpcfactor.patch Patch2: coreutils-8.20-df-duplicates.patch +Patch3: coreutils-8.20-seq-s.patch # Our patches #general patch to workaround koji build system issues @@ -130,6 +131,7 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .ppcfactor %patch2 -p1 -b .duplic +%patch3 -p1 -b .newline # Our patches %patch100 -p1 -b .configure @@ -379,6 +381,9 @@ fi %{_sbindir}/chroot %changelog +* Thu Dec 20 2012 Ondrej Vasik 8.20-5 +- seq: fix newline output when -s specified (upstream) + * Mon Dec 10 2012 Ondrej Vasik 8.20-4 - fix showing duplicates in df (#709351, O.Oprala, B.Voelker) From 85ea3f49e475bb96660a3552614888950367ffbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 20 Dec 2012 10:20:40 +0100 Subject: [PATCH 187/523] Remove fuzzed NEWS entry, fix bogus dates in changelog --- coreutils-8.20-seq-s.patch | 19 +------------------ coreutils.spec | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/coreutils-8.20-seq-s.patch b/coreutils-8.20-seq-s.patch index ecf5338..9885b85 100644 --- a/coreutils-8.20-seq-s.patch +++ b/coreutils-8.20-seq-s.patch @@ -9,30 +9,13 @@ This regression was introduced in commit v8.19-132-g3786fb6. and instead insert it into the buffer as for other numbers. Also output the terminator unconditionally. * tests/misc/seq.pl: Add some basic tests for the -s option. -* NEWS: Mention the fix. * THANKS.in: Reported by Philipp Gortan. --- - NEWS | 4 ++++ THANKS.in | 1 + src/seq.c | 20 +++++++++++++------- tests/misc/seq.pl | 5 +++++ - 4 files changed, 23 insertions(+), 7 deletions(-) + 3 files changed, 19 insertions(+), 7 deletions(-) -diff --git a/NEWS b/NEWS -index e4472df..ae7ec2a 100644 ---- a/NEWS -+++ b/NEWS -@@ -43,6 +43,10 @@ GNU coreutils NEWS -*- outline -*- - the output numbers are properly aligned and of the correct width. - [This bug was present in "the beginning".] - -+ seq -s now doesn't output an erroneous newline after the first number, and -+ outputs a newline after the last number rather than a trailing separator. -+ [bug introduced in coreutils-8.20] -+ - ** Changes in behavior - - df --total now prints '-' into the target column (mount point) of the diff --git a/THANKS.in b/THANKS.in index c2651e7..67b60b9 100644 --- a/THANKS.in diff --git a/coreutils.spec b/coreutils.spec index bbd1fb6..3c3d936 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -587,7 +587,7 @@ fi - change assertion failure for invalid multibyte input in sort to less confusing error message(#591352) -* Wed Sep 09 2010 Ondrej Vasik - 8.5-7 +* Wed Sep 08 2010 Ondrej Vasik - 8.5-7 - add RELRO protection to su as well (#630017) * Mon Sep 06 2010 Ondrej Vasik - 8.5-6 @@ -759,7 +759,7 @@ fi - do not ignore sort's version sort for multibyte locales (#509688) -* Thu Jun 16 2009 Ondrej Vasik 7.4-2 +* Thu Jun 18 2009 Ondrej Vasik 7.4-2 - temporarily workaround probable kernel issue with TCSADRAIN(#504798) @@ -852,7 +852,7 @@ fi * Mon Nov 03 2008 Ondrej Vasik - 6.12-17 - Requires: ncurses (#469277) -* Wed Oct 21 2008 Ondrej Vasik - 6.12-16 +* Wed Oct 22 2008 Ondrej Vasik - 6.12-16 - make possible to disable capability in ls due to performance impact when not cached(#467508) - do not patch generated manpages - generate them at build @@ -895,7 +895,7 @@ fi * Mon Aug 04 2008 Kamil Dudka - 6.12-8 - ls -U1 now uses constant memory -* Wed Jul 24 2008 Kamil Dudka - 6.12-7 +* Wed Jul 23 2008 Kamil Dudka - 6.12-7 - dd: iflag=fullblock now read full blocks if possible (#431997, #449263) - ls: --color now highlights files with capabilities (#449985) @@ -1297,11 +1297,11 @@ fi - Parametrize SELinux (bug #174067). - Fix runuser.pamd (bug #173807). -* Thu Nov 25 2005 Tim Waugh 5.93-4 +* Thu Nov 24 2005 Tim Waugh 5.93-4 - Rebuild to pick up new glibc *at functions. - Apply runuser PAM patch from bug #173807. Ship runuser PAM file. -* Tue Nov 14 2005 Dan Walsh 5.93-3 +* Tue Nov 15 2005 Dan Walsh 5.93-3 - Remove multiple from su.pamd * Mon Nov 14 2005 Tim Waugh 5.93-2 @@ -1341,7 +1341,7 @@ fi - Allow id to run even when SELinux security context can not be run - Change chcon to use raw functions. -* Thu Jun 28 2005 Tim Waugh +* Tue Jun 28 2005 Tim Waugh - Corrected comments in DIR_COLORS.xterm (bug #161711). * Wed Jun 22 2005 Tim Waugh 5.2.1-52 @@ -1379,7 +1379,7 @@ fi * Thu Mar 24 2005 Tim Waugh 5.2.1-43 - Removed patch that adds -C option to install(1). -* Wed Mar 14 2005 Tim Waugh 5.2.1-42 +* Wed Mar 16 2005 Tim Waugh 5.2.1-42 - Fixed pam patch. - Fixed broken configure test. - Fixed build with GCC 4 (bug #151045). @@ -1396,7 +1396,7 @@ fi * Thu Jan 13 2005 Tim Waugh 5.2.1-37 - Fixed zh_CN translation (bug #144845). Patch from Mitrophan Chin. -* Mon Dec 28 2004 Dan Walsh 5.2.1-36 +* Tue Dec 28 2004 Dan Walsh 5.2.1-36 - Fix to only setdefaultfilecon if not overridden by command line * Mon Dec 27 2004 Dan Walsh 5.2.1-35 @@ -1692,7 +1692,7 @@ fi * Mon Jul 28 2003 Tim Waugh 5.0-8 - Actually use the ACL patch (bug #100519). -* Wed Jul 18 2003 Dan Walsh 5.0-7 +* Wed Jul 16 2003 Dan Walsh 5.0-7 - Convert to SELinux * Mon Jun 9 2003 Tim Waugh From 5089cf43658acddba6bcce2a4dd6f694010e0ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 23 Jan 2013 10:04:52 +0100 Subject: [PATCH 188/523] Fix multiple segmantation faults in i18n patch (by SUSE) - (#869442, #902917) --- coreutils-i18n.patch | 160 +++++++++++++++++++++++++------------------ coreutils.spec | 4 ++ 2 files changed, 98 insertions(+), 66 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 956aac9..0817390 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.19-orig/lib/linebuffer.h coreutils-8.19/lib/linebuffer.h ---- coreutils-8.19-orig/lib/linebuffer.h 2012-01-06 10:14:31.000000000 +0100 -+++ coreutils-8.19/lib/linebuffer.h 2012-08-20 13:52:04.061593006 +0200 +diff -urNp coreutils-8.20-orig/lib/linebuffer.h coreutils-8.20/lib/linebuffer.h +--- coreutils-8.20-orig/lib/linebuffer.h 2012-10-23 16:17:24.000000000 +0200 ++++ coreutils-8.20/lib/linebuffer.h 2013-01-23 09:24:24.619090620 +0100 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.19-orig/lib/linebuffer.h coreutils-8.19/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.19-orig/src/cut.c coreutils-8.19/src/cut.c ---- coreutils-8.19-orig/src/cut.c 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.19/src/cut.c 2012-08-20 13:52:52.299593173 +0200 +diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c +--- coreutils-8.20-orig/src/cut.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/cut.c 2013-01-23 09:24:24.621092254 +0100 @@ -28,6 +28,11 @@ #include #include @@ -633,9 +633,9 @@ diff -urNp coreutils-8.19-orig/src/cut.c coreutils-8.19/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.19-orig/src/expand.c coreutils-8.19/src/expand.c ---- coreutils-8.19-orig/src/expand.c 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.19/src/expand.c 2012-08-20 13:54:02.974621693 +0200 +diff -urNp coreutils-8.20-orig/src/expand.c coreutils-8.20/src/expand.c +--- coreutils-8.20-orig/src/expand.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/expand.c 2013-01-23 09:24:24.622088030 +0100 @@ -37,12 +37,29 @@ #include #include @@ -823,9 +823,9 @@ diff -urNp coreutils-8.19-orig/src/expand.c coreutils-8.19/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.19-orig/src/fold.c coreutils-8.19/src/fold.c ---- coreutils-8.19-orig/src/fold.c 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.19/src/fold.c 2012-08-20 13:52:04.066592980 +0200 +diff -urNp coreutils-8.20-orig/src/fold.c coreutils-8.20/src/fold.c +--- coreutils-8.20-orig/src/fold.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/fold.c 2013-01-23 09:24:24.623090499 +0100 @@ -22,12 +22,34 @@ #include #include @@ -1223,9 +1223,9 @@ diff -urNp coreutils-8.19-orig/src/fold.c coreutils-8.19/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c ---- coreutils-8.19-orig/src/join.c 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.19/src/join.c 2012-08-20 13:52:04.069594876 +0200 +diff -urNp coreutils-8.20-orig/src/join.c coreutils-8.20/src/join.c +--- coreutils-8.20-orig/src/join.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/join.c 2013-01-23 09:29:53.877170828 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1444,7 +1444,7 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c static void freeline (struct line *line) { -@@ -313,56 +472,115 @@ keycmp (struct line const *line1, struct +@@ -313,56 +472,130 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1458,6 +1458,7 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c + size_t len[2]; /* Length of fields to compare. */ int diff; + int i, j; ++ int mallocd = 0; if (jf_1 < line1->nfields) { @@ -1513,7 +1514,8 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c + + for (i = 0; i < 2; i++) + { -+ copy[i] = alloca (len[i] + 1); ++ mallocd = 1; ++ copy[i] = xmalloc (len[i] + 1); + + for (j = 0; j < MIN (len[0], len[1]);) + { @@ -1553,7 +1555,8 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c + { + for (i = 0; i < 2; i++) + { -+ copy[i] = alloca (len[i] + 1); ++ 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]); @@ -1572,9 +1575,21 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c } + if (hard_LC_COLLATE) -+ return xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); ++ { ++ 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; @@ -1583,7 +1598,7 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -454,6 +672,11 @@ get_line (FILE *fp, struct line **linep, +@@ -454,6 +687,11 @@ get_line (FILE *fp, struct line **linep, } ++line_no[which - 1]; @@ -1595,7 +1610,7 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c xfields (line); if (prevline[which - 1]) -@@ -553,21 +776,28 @@ prfield (size_t n, struct line const *li +@@ -553,21 +791,28 @@ prfield (size_t n, struct line const *li /* Output all the fields in line, other than the join field. */ @@ -1627,7 +1642,7 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c prfield (i, line); } } -@@ -578,7 +808,6 @@ static void +@@ -578,7 +823,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -1635,7 +1650,7 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c size_t field; struct line const *line; -@@ -612,7 +841,7 @@ prjoin (struct line const *line1, struct +@@ -612,7 +856,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1644,7 +1659,7 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c } putchar ('\n'); } -@@ -1090,21 +1319,46 @@ main (int argc, char **argv) +@@ -1090,21 +1334,46 @@ main (int argc, char **argv) case 't': { @@ -1701,9 +1716,9 @@ diff -urNp coreutils-8.19-orig/src/join.c coreutils-8.19/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.19-orig/src/pr.c coreutils-8.19/src/pr.c ---- coreutils-8.19-orig/src/pr.c 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.19/src/pr.c 2012-08-20 13:52:04.074593445 +0200 +diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c +--- coreutils-8.20-orig/src/pr.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/pr.c 2013-01-23 09:24:24.629439021 +0100 @@ -312,6 +312,32 @@ #include @@ -2447,9 +2462,9 @@ diff -urNp coreutils-8.19-orig/src/pr.c coreutils-8.19/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c ---- coreutils-8.19-orig/src/sort.c 2012-08-18 07:39:29.000000000 +0200 -+++ coreutils-8.19/src/sort.c 2012-08-20 13:52:04.079596072 +0200 +diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c +--- coreutils-8.20-orig/src/sort.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/sort.c 2013-01-23 09:35:36.091438847 +0100 @@ -29,6 +29,14 @@ #include #include @@ -3024,7 +3039,7 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2458,11 +2819,83 @@ key_warnings (struct keyfield const *gke +@@ -2458,11 +2819,87 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -3051,13 +3066,13 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c + if (len == 0) + return 0; + -+ month = (char *) alloca (len + 1); ++ month = (char *) xmalloc (len + 1); + -+ tmp = (char *) alloca (len + 1); ++ tmp = (char *) xmalloc (len + 1); + memcpy (tmp, s, len); + tmp[len] = '\0'; + pp = (const char **)&tmp; -+ month_wcs = (wchar_t *) alloca ((len + 1) * sizeof (wchar_t)); ++ month_wcs = (wchar_t *) xmalloc ((len + 1) * sizeof (wchar_t)); + memset (&state, '\0', sizeof(mbstate_t)); + + wclength = mbsrtowcs (month_wcs, pp, len + 1, &state); @@ -3096,6 +3111,10 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c + if (ea && result) + *ea = s + strlen (monthtab[lo].name); + ++ free (month); ++ free (tmp); ++ free (month_wcs); ++ + return result; +} +#endif @@ -3109,7 +3128,7 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c { struct keyfield *key = keylist; -@@ -2547,7 +2980,7 @@ keycompare (struct line const *a, struct +@@ -2547,7 +2984,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3118,7 +3137,7 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2663,6 +3096,180 @@ keycompare (struct line const *a, struct +@@ -2663,6 +3100,181 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3174,7 +3193,7 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c + { + if (ignore || translate) + { -+ char *copy_a = (char *) alloca (lena + 1 + lenb + 1); ++ char *copy_a = (char *) xmalloc (lena + 1 + lenb + 1); + char *copy_b = copy_a + lena + 1; + size_t new_len_a, new_len_b; + size_t i, j; @@ -3250,6 +3269,7 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c + IGNORE_CHARS (new_len_b, lenb, textb, copy_b, + wc_b, mblength_b, state_b); + diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b); ++ free(copy_a); + } + else if (lena == 0) + diff = - NONZERO (lenb); @@ -3299,7 +3319,7 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4158,7 +4765,7 @@ main (int argc, char **argv) +@@ -4158,7 +4770,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3308,7 +3328,7 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4179,6 +4786,29 @@ main (int argc, char **argv) +@@ -4179,6 +4791,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3338,7 +3358,7 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c have_read_stdin = false; inittables (); -@@ -4453,13 +5083,34 @@ main (int argc, char **argv) +@@ -4453,13 +5088,34 @@ main (int argc, char **argv) case 't': { @@ -3377,7 +3397,7 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4470,9 +5121,12 @@ main (int argc, char **argv) +@@ -4470,9 +5126,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3392,9 +3412,9 @@ diff -urNp coreutils-8.19-orig/src/sort.c coreutils-8.19/src/sort.c } break; -diff -urNp coreutils-8.19-orig/src/unexpand.c coreutils-8.19/src/unexpand.c ---- coreutils-8.19-orig/src/unexpand.c 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.19/src/unexpand.c 2012-08-20 13:52:04.081596774 +0200 +diff -urNp coreutils-8.20-orig/src/unexpand.c coreutils-8.20/src/unexpand.c +--- coreutils-8.20-orig/src/unexpand.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/unexpand.c 2013-01-23 09:24:24.636292411 +0100 @@ -38,12 +38,29 @@ #include #include @@ -3648,9 +3668,9 @@ diff -urNp coreutils-8.19-orig/src/unexpand.c coreutils-8.19/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c ---- coreutils-8.19-orig/src/uniq.c 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.19/src/uniq.c 2012-08-20 13:52:04.083502506 +0200 +diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c +--- coreutils-8.20-orig/src/uniq.c 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/src/uniq.c 2013-01-23 09:46:33.757064880 +0100 @@ -21,6 +21,16 @@ #include #include @@ -3802,7 +3822,7 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -241,14 +346,92 @@ different (char *old, char *new, size_t +@@ -241,14 +346,100 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3810,14 +3830,18 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c - return oldlen != newlen || memcasecmp (old, new, oldlen); + size_t i; + -+ copy_old = alloca (oldlen + 1); -+ copy_new = alloca (oldlen + 1); ++ copy_old = xmalloc (oldlen + 1); ++ copy_new = xmalloc (oldlen + 1); + + for (i = 0; i < oldlen; i++) + { + copy_old[i] = toupper (old[i]); + copy_new[i] = toupper (new[i]); + } ++ bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen); ++ free (copy_old); ++ free (copy_new); ++ return rc; } - else if (hard_LC_COLLATE) - return xmemcoll (old, oldlen, new, newlen) != 0; @@ -3829,6 +3853,7 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c + } + + return xmemcoll (copy_old, oldlen, copy_new, newlen); ++ +} + +#if HAVE_MBRTOWC @@ -3853,7 +3878,7 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c + + for (i = 0; i < 2; i++) + { -+ copy[i] = alloca (len[i] + 1); ++ copy[i] = xmalloc (len[i] + 1); + + for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) + { @@ -3893,14 +3918,17 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c + copy[i][j] = '\0'; + len[i] = j; + } ++ int rc = xmemcoll (copy[0], len[0], copy[1], len[1]); ++ free (copy[0]); ++ free (copy[1]); ++ return rc; + -+ return xmemcoll (copy[0], len[0], copy[1], len[1]); } +#endif /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -304,15 +487,43 @@ check_file (const char *infile, const ch +@@ -304,15 +495,43 @@ check_file (const char *infile, const ch { char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); @@ -3944,7 +3972,7 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c if (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)) { -@@ -331,17 +542,26 @@ check_file (const char *infile, const ch +@@ -331,17 +550,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -3971,7 +3999,7 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -350,6 +570,14 @@ check_file (const char *infile, const ch +@@ -350,6 +578,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -3986,7 +4014,7 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -382,6 +610,9 @@ check_file (const char *infile, const ch +@@ -382,6 +618,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3996,7 +4024,7 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c if (!match) match_count = 0; } -@@ -427,6 +658,19 @@ main (int argc, char **argv) +@@ -427,6 +666,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4017,8 +4045,8 @@ diff -urNp coreutils-8.19-orig/src/uniq.c coreutils-8.19/src/uniq.c skip_fields = 0; check_chars = SIZE_MAX; diff -urNp coreutils-8.20-orig/tests/misc/cut.pl coreutils-8.20/tests/misc/cut.pl ---- coreutils-8.20-orig/tests/misc/cut.pl 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.20/tests/misc/cut.pl 2012-08-20 13:52:04.086593767 +0200 +--- coreutils-8.20-orig/tests/misc/cut.pl 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/tests/misc/cut.pl 2013-01-23 09:24:24.639346707 +0100 @@ -23,14 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4049,8 +4077,8 @@ diff -urNp coreutils-8.20-orig/tests/misc/cut.pl coreutils-8.20/tests/misc/cut.p ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, diff -urNp coreutils-8.20-orig/tests/misc/expand.pl coreutils-8.20/tests/misc/expand.pl ---- coreutils-8.20-orig/tests/misc/expand.pl 2012-07-21 16:54:31.000000000 +0200 -+++ coreutils-8.20/tests/misc/expand.pl 2012-08-20 13:55:44.188467648 +0200 +--- coreutils-8.20-orig/tests/misc/expand.pl 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/tests/misc/expand.pl 2013-01-23 09:24:24.640439471 +0100 @@ -23,6 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4107,7 +4135,7 @@ diff -urNp coreutils-8.20-orig/tests/misc/expand.pl coreutils-8.20/tests/misc/ex diff -urNp coreutils-8.20-orig/tests/misc/mb1.I coreutils-8.20/tests/misc/mb1.I --- coreutils-8.20-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/mb1.I 2012-08-20 13:52:04.086593767 +0200 ++++ coreutils-8.20/tests/misc/mb1.I 2013-01-23 09:24:24.640439471 +0100 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 @@ -4115,7 +4143,7 @@ diff -urNp coreutils-8.20-orig/tests/misc/mb1.I coreutils-8.20/tests/misc/mb1.I +Cherry@30 diff -urNp coreutils-8.20-orig/tests/misc/mb1.X coreutils-8.20/tests/misc/mb1.X --- coreutils-8.20-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/mb1.X 2012-08-20 13:52:04.087526516 +0200 ++++ coreutils-8.20/tests/misc/mb1.X 2013-01-23 09:24:24.641395635 +0100 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 @@ -4123,7 +4151,7 @@ diff -urNp coreutils-8.20-orig/tests/misc/mb1.X coreutils-8.20/tests/misc/mb1.X +Cherry@30 diff -urNp coreutils-8.20-orig/tests/misc/mb2.I coreutils-8.20/tests/misc/mb2.I --- coreutils-8.20-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/mb2.I 2012-08-20 13:52:04.088593815 +0200 ++++ coreutils-8.20/tests/misc/mb2.I 2013-01-23 09:24:24.642441918 +0100 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 @@ -4131,7 +4159,7 @@ diff -urNp coreutils-8.20-orig/tests/misc/mb2.I coreutils-8.20/tests/misc/mb2.I +Cherry@AA30@@10 diff -urNp coreutils-8.20-orig/tests/misc/mb2.X coreutils-8.20/tests/misc/mb2.X --- coreutils-8.20-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/mb2.X 2012-08-20 13:52:04.088593815 +0200 ++++ coreutils-8.20/tests/misc/mb2.X 2013-01-23 09:24:24.642441918 +0100 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 @@ -4139,7 +4167,7 @@ diff -urNp coreutils-8.20-orig/tests/misc/mb2.X coreutils-8.20/tests/misc/mb2.X +Banana@AA5@@30 diff -urNp coreutils-8.20-orig/tests/misc/sort-mb-tests.sh coreutils-8.20/tests/misc/sort-mb-tests.sh --- coreutils-8.20-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/sort-mb-tests.sh 2012-08-20 13:52:04.089593318 +0200 ++++ coreutils-8.20/tests/misc/sort-mb-tests.sh 2013-01-23 09:24:24.643201093 +0100 @@ -0,0 +1,58 @@ +#! /bin/sh +case $# in diff --git a/coreutils.spec b/coreutils.spec index 3c3d936..148df6b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -381,6 +381,10 @@ fi %{_sbindir}/chroot %changelog +* Wed Jan 23 2013 Ondrej Vasik 8.20-6 +- fix multiple segmantation faults in i18n patch (by SUSE) + (#869442, #902917) + * Thu Dec 20 2012 Ondrej Vasik 8.20-5 - seq: fix newline output when -s specified (upstream) From 3b194abd70700d24fc670bb7b2cffcde0daf5480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 23 Jan 2013 10:05:17 +0100 Subject: [PATCH 189/523] Release++ --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 148df6b..18980c5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.20 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ From c9e9ece7a386ed2c53bb463892c1cd8967510d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 23 Jan 2013 10:40:24 +0100 Subject: [PATCH 190/523] move inotify-hash-abuse test to root only to disable it in koji builds (fails too often in rawhide) --- coreutils-6.10-configuration.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 0fa0c2a..54b31dc 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -136,3 +136,22 @@ diff -urNp coreutils-8.13-orig/tests/touch/no-dereference.sh coreutils-8.13/test # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to +diff -urNp coreutils-8.20-orig/tests/local.mk coreutils-8.20/tests/local.mk +--- coreutils-8.20-orig/tests/local.mk 2013-01-23 09:50:18.388078004 +0100 ++++ coreutils-8.20/tests/local.mk 2013-01-23 10:39:09.090085667 +0100 +@@ -130,6 +130,7 @@ all_root_tests = \ + tests/rm/no-give-up.sh \ + tests/rm/one-file-system.sh \ + tests/rm/read-only.sh \ ++ tests/tail-2/inotify-hash-abuse.sh \ + tests/tail-2/append-only.sh \ + tests/touch/now-owned-by-other.sh + +@@ -162,7 +163,6 @@ all_tests = \ + tests/rm/cycle.sh \ + tests/cp/link-heap.sh \ + tests/misc/tty-eof.pl \ +- tests/tail-2/inotify-hash-abuse.sh \ + tests/tail-2/inotify-hash-abuse2.sh \ + tests/tail-2/F-vs-missing.sh \ + tests/tail-2/F-vs-rename.sh \ From 04d73f0952f4475ea0d0aafadd97562798f603bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 5 Feb 2013 14:31:22 +0100 Subject: [PATCH 191/523] add support for DTR/DSR control flow in stty(#445213) --- coreutils-445213-stty-dtrdsr.patch | 59 ++++++++++++++++++++++++++++++ coreutils.spec | 8 +++- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 coreutils-445213-stty-dtrdsr.patch diff --git a/coreutils-445213-stty-dtrdsr.patch b/coreutils-445213-stty-dtrdsr.patch new file mode 100644 index 0000000..c118822 --- /dev/null +++ b/coreutils-445213-stty-dtrdsr.patch @@ -0,0 +1,59 @@ +diff -urNp coreutils-8.17-orig/doc/coreutils.texi coreutils-8.17/doc/coreutils.texi +--- coreutils-8.17-orig/doc/coreutils.texi 2013-02-05 13:53:31.305588244 +0100 ++++ coreutils-8.17/doc/coreutils.texi 2013-02-05 13:53:55.480586114 +0100 +@@ -13178,6 +13178,13 @@ Disable modem control signals. May be n + @cindex flow control, hardware + @cindex RTS/CTS flow control + Enable RTS/CTS flow control. Non-@acronym{POSIX}. May be negated. ++ ++@item cdtrdsr ++@opindex cdtrdsr ++@cindex hardware flow control ++@cindex flow control, hardware ++@cindex DTR/DSR flow control ++Enable DTR/DSR flow control. Non-@acronym{POSIX}. May be negated. + @end table + + +diff -urNp coreutils-8.17-orig/src/stty.c coreutils-8.17/src/stty.c +--- coreutils-8.17-orig/src/stty.c 2013-02-05 13:53:31.278585235 +0100 ++++ coreutils-8.17/src/stty.c 2013-02-05 13:53:55.481586255 +0100 +@@ -73,6 +73,9 @@ + #ifndef CINTR + # define CINTR Control ('c') + #endif ++#ifndef CDTRDSR ++# define CDTRDSR 004000000000 /* DTR/DSR flow control */ ++#endif + #ifndef CQUIT + # define CQUIT 28 + #endif +@@ -216,7 +219,7 @@ static struct mode_info const mode_info[ + #ifdef CRTSCTS + {"crtscts", control, REV, CRTSCTS, 0}, + #endif +- ++ {"cdtrdsr", control, REV, CDTRDSR, 0}, + {"ignbrk", input, SANE_UNSET | REV, IGNBRK, 0}, + {"brkint", input, SANE_SET | REV, BRKINT, 0}, + {"ignpar", input, REV, IGNPAR, 0}, +@@ -576,6 +579,7 @@ Control settings:\n\ + [-]clocal disable modem control signals\n\ + [-]cread allow input to be received\n\ + * [-]crtscts enable RTS/CTS handshaking\n\ ++ * [-]cdtrdsr enable DTR/DSR handshaking\n\ + csN set character size to N bits, N in [5..8]\n\ + "), stdout); + fputs (_("\ +diff -urNp coreutils-8.17-orig/tests/misc/stty coreutils-8.17/tests/misc/stty +--- coreutils-8.17-orig/tests/misc/stty 2012-04-19 19:39:23.000000000 +0200 ++++ coreutils-8.17/tests/misc/stty 2013-02-05 13:57:55.779588822 +0100 +@@ -52,7 +52,7 @@ for opt in $options; do + # other serial control settings give the same error. So skip them. + # Also on ppc*|sparc* glibc platforms 'icanon' gives the same error. + # See: http://debbugs.gnu.org/7228#14 +- case $opt in parenb|parodd|cstopb|crtscts|icanon) continue;; esac ++ case $opt in parenb|parodd|cstopb|crtscts|icanon|cdtrdsr) continue;; esac + + stty $opt || fail=1 + diff --git a/coreutils.spec b/coreutils.spec index 18980c5..31723da 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.20 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -31,6 +31,8 @@ Patch103: coreutils-8.2-uname-processortype.patch Patch104: coreutils-df-direct.patch #add note about mkdir --mode behaviour into info documentation(#610559) Patch107: coreutils-8.4-mkdir-modenote.patch +#add support for dtr/dsr to stty +Patch108: coreutils-445213-stty-dtrdsr.patch # sh-utils #add info about TZ envvar to date manpage @@ -140,6 +142,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect %patch107 -p1 -b .mkdirmode +%patch108 -p1 -b .dtrdsr # sh-utils %patch703 -p1 -b .dateman @@ -381,6 +384,9 @@ fi %{_sbindir}/chroot %changelog +* Tue Feb 05 2013 Ondrej Vasik 8.20-7 +- add support for DTR/DSR control flow in stty(#445213) + * Wed Jan 23 2013 Ondrej Vasik 8.20-6 - fix multiple segmantation faults in i18n patch (by SUSE) (#869442, #902917) From 3be440dcae16531b66165ccae2dd19f7c98af19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 5 Feb 2013 14:41:51 +0100 Subject: [PATCH 192/523] oops, wrong patch ;) --- coreutils-445213-stty-dtrdsr.patch | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/coreutils-445213-stty-dtrdsr.patch b/coreutils-445213-stty-dtrdsr.patch index c118822..c425101 100644 --- a/coreutils-445213-stty-dtrdsr.patch +++ b/coreutils-445213-stty-dtrdsr.patch @@ -1,24 +1,24 @@ -diff -urNp coreutils-8.17-orig/doc/coreutils.texi coreutils-8.17/doc/coreutils.texi ---- coreutils-8.17-orig/doc/coreutils.texi 2013-02-05 13:53:31.305588244 +0100 -+++ coreutils-8.17/doc/coreutils.texi 2013-02-05 13:53:55.480586114 +0100 -@@ -13178,6 +13178,13 @@ Disable modem control signals. May be n +diff -urNp coreutils-8.20-orig/doc/coreutils.texi coreutils-8.20/doc/coreutils.texi +--- coreutils-8.20-orig/doc/coreutils.texi 2013-02-05 14:32:51.609588591 +0100 ++++ coreutils-8.20/doc/coreutils.texi 2013-02-05 14:38:11.486585193 +0100 +@@ -13219,6 +13219,13 @@ Disable modem control signals. May be n @cindex flow control, hardware @cindex RTS/CTS flow control - Enable RTS/CTS flow control. Non-@acronym{POSIX}. May be negated. + Enable RTS/CTS flow control. Non-POSIX@. May be negated. + +@item cdtrdsr +@opindex cdtrdsr +@cindex hardware flow control +@cindex flow control, hardware +@cindex DTR/DSR flow control -+Enable DTR/DSR flow control. Non-@acronym{POSIX}. May be negated. ++Enable DTR/DSR flow control. Non-POSIX@. May be negated. @end table -diff -urNp coreutils-8.17-orig/src/stty.c coreutils-8.17/src/stty.c ---- coreutils-8.17-orig/src/stty.c 2013-02-05 13:53:31.278585235 +0100 -+++ coreutils-8.17/src/stty.c 2013-02-05 13:53:55.481586255 +0100 -@@ -73,6 +73,9 @@ +diff -urNp coreutils-8.20-orig/src/stty.c coreutils-8.20/src/stty.c +--- coreutils-8.20-orig/src/stty.c 2013-02-05 14:32:51.579585712 +0100 ++++ coreutils-8.20/src/stty.c 2013-02-05 14:33:33.600585688 +0100 +@@ -74,6 +74,9 @@ #ifndef CINTR # define CINTR Control ('c') #endif @@ -28,7 +28,7 @@ diff -urNp coreutils-8.17-orig/src/stty.c coreutils-8.17/src/stty.c #ifndef CQUIT # define CQUIT 28 #endif -@@ -216,7 +219,7 @@ static struct mode_info const mode_info[ +@@ -217,7 +220,7 @@ static struct mode_info const mode_info[ #ifdef CRTSCTS {"crtscts", control, REV, CRTSCTS, 0}, #endif @@ -37,7 +37,7 @@ diff -urNp coreutils-8.17-orig/src/stty.c coreutils-8.17/src/stty.c {"ignbrk", input, SANE_UNSET | REV, IGNBRK, 0}, {"brkint", input, SANE_SET | REV, BRKINT, 0}, {"ignpar", input, REV, IGNPAR, 0}, -@@ -576,6 +579,7 @@ Control settings:\n\ +@@ -577,6 +580,7 @@ Control settings:\n\ [-]clocal disable modem control signals\n\ [-]cread allow input to be received\n\ * [-]crtscts enable RTS/CTS handshaking\n\ @@ -45,9 +45,9 @@ diff -urNp coreutils-8.17-orig/src/stty.c coreutils-8.17/src/stty.c csN set character size to N bits, N in [5..8]\n\ "), stdout); fputs (_("\ -diff -urNp coreutils-8.17-orig/tests/misc/stty coreutils-8.17/tests/misc/stty ---- coreutils-8.17-orig/tests/misc/stty 2012-04-19 19:39:23.000000000 +0200 -+++ coreutils-8.17/tests/misc/stty 2013-02-05 13:57:55.779588822 +0100 +diff -urNp coreutils-8.20-orig/tests/misc/stty.sh coreutils-8.20/tests/misc/stty.sh +--- coreutils-8.20-orig/tests/misc/stty.sh 2012-10-23 16:14:12.000000000 +0200 ++++ coreutils-8.20/tests/misc/stty.sh 2013-02-05 14:34:19.980586848 +0100 @@ -52,7 +52,7 @@ for opt in $options; do # other serial control settings give the same error. So skip them. # Also on ppc*|sparc* glibc platforms 'icanon' gives the same error. From 9ae2bc3ca199e4a4482d36ae9f1b341e3f295acd Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Thu, 7 Feb 2013 18:08:05 +0100 Subject: [PATCH 193/523] add missing sort-mb-tests.sh to local.mk --- coreutils-i18n.patch | 18 +++++++++++++++++- coreutils.spec | 5 ++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 0817390..641d9e5 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4044,6 +4044,17 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; +diff -urNp coreutils-8.20-orig/tests/misc/local.mk coreutils-8.20/tests/misc/local.mk +--- coreutils-8.20-orig/tests/local.mk 2013-02-07 15:26:29.559370456 +0100 ++++ coreutils-8.20/tests/local.mk 2013-02-07 15:24:51.625470679 +0100 +@@ -323,6 +323,7 @@ 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/misc/sort-merge.pl \ + tests/misc/sort-merge-fdlimit.sh \ + tests/misc/sort-month.sh \ diff -urNp coreutils-8.20-orig/tests/misc/cut.pl coreutils-8.20/tests/misc/cut.pl --- coreutils-8.20-orig/tests/misc/cut.pl 2012-10-23 16:14:12.000000000 +0200 +++ coreutils-8.20/tests/misc/cut.pl 2013-01-23 09:24:24.639346707 +0100 @@ -4168,8 +4179,13 @@ diff -urNp coreutils-8.20-orig/tests/misc/mb2.X coreutils-8.20/tests/misc/mb2.X diff -urNp coreutils-8.20-orig/tests/misc/sort-mb-tests.sh coreutils-8.20/tests/misc/sort-mb-tests.sh --- coreutils-8.20-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-8.20/tests/misc/sort-mb-tests.sh 2013-01-23 09:24:24.643201093 +0100 -@@ -0,0 +1,58 @@ +@@ -0,0 +1,63 @@ +#! /bin/sh ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++ ++expensive_ ++ +case $# in + 0) xx='../src/sort';; + *) xx="$1";; diff --git a/coreutils.spec b/coreutils.spec index 31723da..77ad04d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.20 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -384,6 +384,9 @@ fi %{_sbindir}/chroot %changelog +* Thu Feb 07 2013 Ondrej Oprala 8.20-8 +- add missing sort-mb-tests.sh to local.mk + * Tue Feb 05 2013 Ondrej Vasik 8.20-7 - add support for DTR/DSR control flow in stty(#445213) From 4c4be9e1c97723c23096090c4d158bfe55bc02fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 15 Feb 2013 17:50:47 +0100 Subject: [PATCH 194/523] new upstream release 8.21, update patches --- .gitignore | 1 + coreutils-445213-stty-dtrdsr.patch | 59 ----- coreutils-6.10-configuration.patch | 70 +++--- coreutils-8.20-df-duplicates.patch | 264 ---------------------- coreutils-8.20-seq-s.patch | 96 -------- coreutils-df-direct.patch | 63 +++--- coreutils-i18n.patch | 340 ++++++++++++----------------- coreutils-selinux.patch | 194 ++++++++-------- coreutils.spec | 15 +- sources | 2 +- 10 files changed, 311 insertions(+), 793 deletions(-) delete mode 100644 coreutils-445213-stty-dtrdsr.patch delete mode 100644 coreutils-8.20-df-duplicates.patch delete mode 100644 coreutils-8.20-seq-s.patch diff --git a/.gitignore b/.gitignore index 69c2468..0c7a76a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /coreutils-8.18.tar.xz /coreutils-8.19.tar.xz /coreutils-8.20.tar.xz +/coreutils-8.21.tar.xz diff --git a/coreutils-445213-stty-dtrdsr.patch b/coreutils-445213-stty-dtrdsr.patch deleted file mode 100644 index c425101..0000000 --- a/coreutils-445213-stty-dtrdsr.patch +++ /dev/null @@ -1,59 +0,0 @@ -diff -urNp coreutils-8.20-orig/doc/coreutils.texi coreutils-8.20/doc/coreutils.texi ---- coreutils-8.20-orig/doc/coreutils.texi 2013-02-05 14:32:51.609588591 +0100 -+++ coreutils-8.20/doc/coreutils.texi 2013-02-05 14:38:11.486585193 +0100 -@@ -13219,6 +13219,13 @@ Disable modem control signals. May be n - @cindex flow control, hardware - @cindex RTS/CTS flow control - Enable RTS/CTS flow control. Non-POSIX@. May be negated. -+ -+@item cdtrdsr -+@opindex cdtrdsr -+@cindex hardware flow control -+@cindex flow control, hardware -+@cindex DTR/DSR flow control -+Enable DTR/DSR flow control. Non-POSIX@. May be negated. - @end table - - -diff -urNp coreutils-8.20-orig/src/stty.c coreutils-8.20/src/stty.c ---- coreutils-8.20-orig/src/stty.c 2013-02-05 14:32:51.579585712 +0100 -+++ coreutils-8.20/src/stty.c 2013-02-05 14:33:33.600585688 +0100 -@@ -74,6 +74,9 @@ - #ifndef CINTR - # define CINTR Control ('c') - #endif -+#ifndef CDTRDSR -+# define CDTRDSR 004000000000 /* DTR/DSR flow control */ -+#endif - #ifndef CQUIT - # define CQUIT 28 - #endif -@@ -217,7 +220,7 @@ static struct mode_info const mode_info[ - #ifdef CRTSCTS - {"crtscts", control, REV, CRTSCTS, 0}, - #endif -- -+ {"cdtrdsr", control, REV, CDTRDSR, 0}, - {"ignbrk", input, SANE_UNSET | REV, IGNBRK, 0}, - {"brkint", input, SANE_SET | REV, BRKINT, 0}, - {"ignpar", input, REV, IGNPAR, 0}, -@@ -577,6 +580,7 @@ Control settings:\n\ - [-]clocal disable modem control signals\n\ - [-]cread allow input to be received\n\ - * [-]crtscts enable RTS/CTS handshaking\n\ -+ * [-]cdtrdsr enable DTR/DSR handshaking\n\ - csN set character size to N bits, N in [5..8]\n\ - "), stdout); - fputs (_("\ -diff -urNp coreutils-8.20-orig/tests/misc/stty.sh coreutils-8.20/tests/misc/stty.sh ---- coreutils-8.20-orig/tests/misc/stty.sh 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/tests/misc/stty.sh 2013-02-05 14:34:19.980586848 +0100 -@@ -52,7 +52,7 @@ for opt in $options; do - # other serial control settings give the same error. So skip them. - # Also on ppc*|sparc* glibc platforms 'icanon' gives the same error. - # See: http://debbugs.gnu.org/7228#14 -- case $opt in parenb|parodd|cstopb|crtscts|icanon) continue;; esac -+ case $opt in parenb|parodd|cstopb|crtscts|icanon|cdtrdsr) continue;; esac - - stty $opt || fail=1 - diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 54b31dc..b4d7b4a 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-tests/gnulib.mk ---- coreutils-8.13-orig/gnulib-tests/gnulib.mk 2011-09-08 17:09:08.000000000 +0200 -+++ coreutils-8.13/gnulib-tests/gnulib.mk 2011-09-09 10:14:18.714689661 +0200 -@@ -235,9 +235,9 @@ EXTRA_DIST += nap.h test-chown.h test-ch +diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-tests/gnulib.mk +--- coreutils-8.21-orig/gnulib-tests/gnulib.mk 2013-02-07 17:58:44.000000000 +0100 ++++ coreutils-8.21/gnulib-tests/gnulib.mk 2013-02-15 10:12:28.110593165 +0100 +@@ -267,9 +267,9 @@ EXTRA_DIST += nap.h test-chown.h test-ch ## begin gnulib module cloexec-tests @@ -14,7 +14,7 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module cloexec-tests -@@ -321,9 +321,9 @@ EXTRA_DIST += test-dirname.c +@@ -378,9 +378,9 @@ EXTRA_DIST += test-dup.c signature.h mac ## begin gnulib module dup2-tests @@ -27,7 +27,7 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module dup2-tests -@@ -373,10 +373,10 @@ EXTRA_DIST += test-fadvise.c +@@ -439,10 +439,10 @@ EXTRA_DIST += test-fadvise.c ## begin gnulib module fchdir-tests @@ -55,7 +55,7 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module getlogin-tests -@@ -918,10 +918,10 @@ EXTRA_DIST += test-link.h test-link.c si +@@ -1119,10 +1119,10 @@ EXTRA_DIST += test-link.h test-link.c si ## begin gnulib module linkat-tests @@ -70,7 +70,7 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module linkat-tests -@@ -1284,9 +1284,9 @@ EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h +@@ -1331,9 +1331,9 @@ EXTRA_DIST += test-memcoll.c macros.h ## begin gnulib module memrchr-tests @@ -83,7 +83,7 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module memrchr-tests -@@ -1824,9 +1824,9 @@ +@@ -1978,9 +1978,9 @@ EXTRA_DIST += test-statat.c ## begin gnulib module stdalign-tests @@ -96,7 +96,7 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module stdalign-tests -@@ -1891,9 +1891,9 @@ EXTRA_DIST += test-uname.c signature.h m +@@ -2323,9 +2323,9 @@ EXTRA_DIST += test-uname.c signature.h m ## begin gnulib module unistd-safer-tests @@ -109,24 +109,43 @@ diff -urNp coreutils-8.13-orig/gnulib-tests/gnulib.mk coreutils-8.13/gnulib-test ## end gnulib module unistd-safer-tests -@@ -1997,10 +1997,10 @@ EXTRA_DIST += test-usleep.c signature.h +@@ -2438,10 +2438,10 @@ EXTRA_DIST += test-usleep.c signature.h ## begin gnulib module utimens-tests -TESTS += test-utimens -check_PROGRAMS += test-utimens --test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) +-test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBINTL@ -EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h +#TESTS += test-utimens +#check_PROGRAMS += test-utimens -+#test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) ++#test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBINTL@ +#EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h ## end gnulib module utimens-tests -diff -urNp coreutils-8.13-orig/tests/touch/no-dereference.sh coreutils-8.13/tests/touch/no-dereference.sh ---- coreutils-8.13-orig/tests/touch/no-dereference.sh 2011-08-08 09:42:16.000000000 +0200 -+++ coreutils-8.13/tests/touch/no-dereference.sh 2011-09-09 10:15:21.167060702 +0200 +diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk +--- coreutils-8.21-orig/tests/local.mk 2013-02-11 11:30:12.000000000 +0100 ++++ coreutils-8.21/tests/local.mk 2013-02-15 10:10:55.890532258 +0100 +@@ -131,6 +131,7 @@ all_root_tests = \ + tests/rm/no-give-up.sh \ + tests/rm/one-file-system.sh \ + tests/rm/read-only.sh \ ++ tests/tail-2/inotify-hash-abuse.sh \ + tests/tail-2/append-only.sh \ + tests/touch/now-owned-by-other.sh + +@@ -163,7 +164,6 @@ all_tests = \ + tests/rm/cycle.sh \ + tests/cp/link-heap.sh \ + tests/misc/tty-eof.pl \ +- tests/tail-2/inotify-hash-abuse.sh \ + tests/tail-2/inotify-hash-abuse2.sh \ + tests/tail-2/F-vs-missing.sh \ + tests/tail-2/F-vs-rename.sh \ +diff -urNp coreutils-8.21-orig/tests/touch/no-dereference.sh coreutils-8.21/tests/touch/no-dereference.sh +--- coreutils-8.21-orig/tests/touch/no-dereference.sh 2013-01-31 01:46:25.000000000 +0100 ++++ coreutils-8.21/tests/touch/no-dereference.sh 2013-02-15 10:10:55.889593383 +0100 @@ -42,6 +42,8 @@ test -f nowhere && fail=1 grep '^#define HAVE_UTIMENSAT 1' "$CONFIG_HEADER" > /dev/null || grep '^#define HAVE_LUTIMES 1' "$CONFIG_HEADER" > /dev/null || @@ -136,22 +155,3 @@ diff -urNp coreutils-8.13-orig/tests/touch/no-dereference.sh coreutils-8.13/test # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to -diff -urNp coreutils-8.20-orig/tests/local.mk coreutils-8.20/tests/local.mk ---- coreutils-8.20-orig/tests/local.mk 2013-01-23 09:50:18.388078004 +0100 -+++ coreutils-8.20/tests/local.mk 2013-01-23 10:39:09.090085667 +0100 -@@ -130,6 +130,7 @@ all_root_tests = \ - tests/rm/no-give-up.sh \ - tests/rm/one-file-system.sh \ - tests/rm/read-only.sh \ -+ tests/tail-2/inotify-hash-abuse.sh \ - tests/tail-2/append-only.sh \ - tests/touch/now-owned-by-other.sh - -@@ -162,7 +163,6 @@ all_tests = \ - tests/rm/cycle.sh \ - tests/cp/link-heap.sh \ - tests/misc/tty-eof.pl \ -- tests/tail-2/inotify-hash-abuse.sh \ - tests/tail-2/inotify-hash-abuse2.sh \ - tests/tail-2/F-vs-missing.sh \ - tests/tail-2/F-vs-rename.sh \ diff --git a/coreutils-8.20-df-duplicates.patch b/coreutils-8.20-df-duplicates.patch deleted file mode 100644 index 6c8c8d8..0000000 --- a/coreutils-8.20-df-duplicates.patch +++ /dev/null @@ -1,264 +0,0 @@ -diff -urNp coreutils-8.20-orig/doc/coreutils.texi coreutils-8.20/doc/coreutils.texi ---- coreutils-8.20-orig/doc/coreutils.texi 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/doc/coreutils.texi 2012-12-10 14:41:33.532650289 +0100 -@@ -10597,6 +10597,14 @@ Normally the disk space is printed in un - 1024 bytes, but this can be overridden (@pxref{Block size}). - Non-integer quantities are rounded up to the next higher unit. - -+For bind mounts and without arguments, @command{df} only outputs the statistics -+for the first occurence of that device in the list of file systems (@var{mtab}), -+i.e., it hides duplicate entries, unless the @option{-a} option is specified. -+ -+By default, @command{df} omits the early-boot pseudo file system type -+@samp{rootfs}, unless the @option{-a} option is specified or that file system -+type is explicitly to be included by using the @option{-t} option. -+ - @cindex disk device file - @cindex device file, disk - If an argument @var{file} is a disk device file containing a mounted -diff -urNp coreutils-8.20-orig/src/df.c coreutils-8.20/src/df.c ---- coreutils-8.20-orig/src/df.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/df.c 2012-12-10 14:41:33.534649048 +0100 -@@ -46,6 +46,17 @@ - /* If true, show inode information. */ - static bool inode_format; - -+/* Filled with device numbers of examined file systems to avoid -+ duplicities in output. */ -+struct devlist -+{ -+ dev_t dev_num; -+ struct devlist *next; -+}; -+ -+/* Store of already-processed device numbers. */ -+static struct devlist *devlist_head; -+ - /* If true, show even file systems with zero size or - uninteresting types. */ - static bool show_all_fs; -@@ -57,6 +68,12 @@ static bool show_local_fs; - command line argument -- even if it's a dummy (automounter) entry. */ - static bool show_listed_fs; - -+/* If true, include rootfs in the output. */ -+static bool show_rootfs; -+ -+/* The literal name of the initial root file system. */ -+static char const *ROOTFS = "rootfs"; -+ - /* Human-readable options for output. */ - static int human_output_opts; - -@@ -372,6 +389,29 @@ excluded_fstype (const char *fstype) - return false; - } - -+/* Check if the device was already examined. */ -+ -+static bool -+dev_examined (char const *mount_dir, char const *devname) -+{ -+ struct stat buf; -+ if (-1 == stat (mount_dir, &buf)) -+ return false; -+ -+ struct devlist *devlist = devlist_head; -+ for ( ; devlist; devlist = devlist->next) -+ if (devlist->dev_num == buf.st_dev) -+ return true; -+ -+ /* Add the device number to the global list devlist. */ -+ devlist = xmalloc (sizeof *devlist); -+ devlist->dev_num = buf.st_dev; -+ devlist->next = devlist_head; -+ devlist_head = devlist; -+ -+ return false; -+} -+ - /* Return true if N is a known integer value. On many file systems, - UINTMAX_MAX represents an unknown value; on AIX, UINTMAX_MAX - 1 - represents unknown. Use a rule that works on AIX file systems, and -@@ -496,6 +536,15 @@ get_dev (char const *disk, char const *m - if (!selected_fstype (fstype) || excluded_fstype (fstype)) - return; - -+ if (process_all && !show_all_fs && !show_listed_fs) -+ { -+ /* No arguments nor "df -a", then check if df has to ... */ -+ if (!show_rootfs && STREQ (disk, ROOTFS)) -+ return; /* ... skip rootfs: (unless -trootfs is given. */ -+ if (dev_examined (mount_point, disk)) -+ return; /* ... skip duplicate entries (bind mounts). */ -+ } -+ - /* If MOUNT_POINT is NULL, then the file system is not mounted, and this - program reports on the file system that the special file is on. - It would be better to report on the unmounted file system, -@@ -1005,6 +1054,7 @@ main (int argc, char **argv) - /* Accept -F as a synonym for -t for compatibility with Solaris. */ - case 't': - add_fs_type (optarg); -+ show_rootfs = selected_fstype (ROOTFS); - break; - - case 'v': /* For SysV compatibility. */ -@@ -1149,6 +1199,14 @@ main (int argc, char **argv) - diagnostic, e.g., if all have been excluded. */ - if (exit_status == EXIT_SUCCESS && ! file_systems_processed) - error (EXIT_FAILURE, 0, _("no file systems processed")); -+ IF_LINT ( -+ while (devlist_head) -+ { -+ struct devlist *devlist = devlist_head->next; -+ free (devlist_head); -+ devlist_head = devlist; -+ } -+ ); - - exit (exit_status); - } -diff -urNp coreutils-8.20-orig/tests/df/skip-duplicates.sh coreutils-8.20/tests/df/skip-duplicates.sh ---- coreutils-8.20-orig/tests/df/skip-duplicates.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/df/skip-duplicates.sh 2012-12-10 14:41:33.535280173 +0100 -@@ -0,0 +1,77 @@ -+#!/bin/sh -+# Test df's behavior when the mount list contains duplicate entries. -+# This test is skipped on systems that lack LD_PRELOAD support; that's fine. -+ -+# Copyright (C) 2012 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_ df -+ -+df || skip_ "df fails" -+ -+# Simulate an mtab file with two entries of the same device number. -+cat > k.c <<'EOF' || framework_failure_ -+#include -+#include -+ -+struct mntent *getmntent (FILE *fp) -+{ -+ /* Prove that LD_PRELOAD works. */ -+ static int done = 0; -+ if (!done) -+ { -+ fclose (fopen ("x", "w")); -+ ++done; -+ } -+ -+ static struct mntent mntent; -+ -+ while (done++ < 3) -+ { -+ mntent.mnt_fsname = "fsname"; -+ mntent.mnt_dir = "/"; -+ mntent.mnt_type = "-"; -+ -+ return &mntent; -+ } -+ return NULL; -+} -+EOF -+ -+# Then compile/link it: -+gcc --std=gnu99 -shared -fPIC -ldl -O2 k.c -o k.so \ -+ || skip_ "getmntent hack does not work on this platform" -+ -+# Test if LD_PRELOAD works: -+LD_PRELOAD=./k.so df -+test -f x || skip_ "internal test failure: maybe LD_PRELOAD doesn't work?" -+ -+# The fake mtab file should only contain 2 entries, both -+# having the same device number; thus the output should -+# consist of a header and one entry. -+LD_PRELOAD=./k.so df >out || fail=1 -+test $(wc -l out || fail=1 -+test $(wc -l out || fail=1 -+test $(wc -l . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ df -+ -+df || skip_ "df fails" -+ -+# Verify that rootfs is in mtab (and shown when the -a option is specified). -+df -a >out || fail=1 -+grep '^rootfs' out || skip_ "no rootfs in mtab" -+ -+# Ensure that rootfs is supressed when no options is specified. -+df >out || fail=1 -+grep '^rootfs' out && { fail=1; cat out; } -+ -+# Ensure that the rootfs is shown when explicitly specifying "-t rootfs". -+df -t rootfs >out || fail=1 -+grep '^rootfs' out || { fail=1; cat out; } -+ -+# Ensure that the rootfs is shown when explicitly specifying "-t rootfs", -+# even when the -a option is specified. -+df -t rootfs -a >out || fail=1 -+grep '^rootfs' out || { fail=1; cat out; } -+ -+# Ensure that the rootfs is omitted in all_fs mode when it is explicitly -+# black-listed. -+df -a -x rootfs >out || fail=1 -+grep '^rootfs' out && { fail=1; cat out; } -+ -+Exit $fail -diff -urNp coreutils-8.20-orig/tests/local.mk coreutils-8.20/tests/local.mk ---- coreutils-8.20-orig/tests/local.mk 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/tests/local.mk 2012-12-10 14:41:33.536310753 +0100 -@@ -456,6 +456,8 @@ all_tests = \ - tests/df/unreadable.sh \ - tests/df/total-unprocessed.sh \ - tests/df/no-mtab-status.sh \ -+ tests/df/skip-duplicates.sh \ -+ tests/df/skip-rootfs.sh \ - tests/dd/direct.sh \ - tests/dd/misc.sh \ - tests/dd/nocache.sh \ diff --git a/coreutils-8.20-seq-s.patch b/coreutils-8.20-seq-s.patch deleted file mode 100644 index 9885b85..0000000 --- a/coreutils-8.20-seq-s.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 9d9cdfd5df898ade2e680aab5ce37fcd0032c687 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 19 Dec 2012 19:27:10 +0000 -Subject: [PATCH] seq: fix newline output when -s specified - -This regression was introduced in commit v8.19-132-g3786fb6. - -* src/seq.c (seq_fast): Don't use puts() to output the first number, -and instead insert it into the buffer as for other numbers. -Also output the terminator unconditionally. -* tests/misc/seq.pl: Add some basic tests for the -s option. -* THANKS.in: Reported by Philipp Gortan. ---- - THANKS.in | 1 + - src/seq.c | 20 +++++++++++++------- - tests/misc/seq.pl | 5 +++++ - 3 files changed, 19 insertions(+), 7 deletions(-) - -diff --git a/THANKS.in b/THANKS.in -index c2651e7..67b60b9 100644 ---- a/THANKS.in -+++ b/THANKS.in -@@ -505,6 +505,7 @@ Phil Richards phil.richards@vf.vodafone.co.uk - Philippe De Muyter phdm@macqel.be - Philippe Schnoebelen Philippe.Schnoebelen@imag.fr - Phillip Jones mouse@datastacks.com -+Philipp Gortan gortan@gmail.com - Philipp Thomas pth@suse.de - Piergiorgio Sartor sartor@sony.de - Pieter Bowman bowman@math.utah.edu -diff --git a/src/seq.c b/src/seq.c -index 9c2c51f..108808b 100644 ---- a/src/seq.c -+++ b/src/seq.c -@@ -419,30 +419,36 @@ seq_fast (char const *a, char const *b) - bool ok = cmp (p, p_len, q, q_len) <= 0; - if (ok) - { -- /* Buffer at least this many output lines per fwrite call. -+ /* Buffer at least this many numbers per fwrite call. - This gives a speed-up of more than 2x over the unbuffered code - when printing the first 10^9 integers. */ - enum {N = 40}; - char *buf = xmalloc (N * (n + 1)); - char const *buf_end = buf + N * (n + 1); - -- puts (p); - char *z = buf; -+ -+ /* Write first number to buffer. */ -+ z = mempcpy (z, p, p_len); -+ -+ /* Append separator then number. */ - while (cmp (p, p_len, q, q_len) < 0) - { -+ *z++ = *separator; - incr (&p, &p_len); - z = mempcpy (z, p, p_len); -- *z++ = *separator; -- if (buf_end - n - 1 < z) -+ /* If no place for another separator + number then -+ output buffer so far, and reset to start of buffer. */ -+ if (buf_end - (n + 1) < z) - { - fwrite (buf, z - buf, 1, stdout); - z = buf; - } - } - -- /* Write any remaining, buffered output. */ -- if (buf < z) -- fwrite (buf, z - buf, 1, stdout); -+ /* Write any remaining buffered output, and the terminator. */ -+ *z++ = *terminator; -+ fwrite (buf, z - buf, 1, stdout); - - IF_LINT (free (buf)); - } -diff --git a/tests/misc/seq.pl b/tests/misc/seq.pl -index 447baa4..416b839 100755 ---- a/tests/misc/seq.pl -+++ b/tests/misc/seq.pl -@@ -128,6 +128,11 @@ my @Tests = - ['long-leading-zeros2', qw(000 02), {OUT => [qw(0 1 2)]}], - ['long-leading-zeros3', qw(00 02), {OUT => [qw(0 1 2)]}], - ['long-leading-zeros4', qw(0 02), {OUT => [qw(0 1 2)]}], -+ -+ # Exercise the -s option, which was broken in 8.20 -+ ['sep-1', qw(-s, 1 3), {OUT => [qw(1,2,3)]}], -+ ['sep-2', qw(-s, 1 1), {OUT => [qw(1)]}], -+ ['sep-3', qw(-s,, 1 3), {OUT => [qw(1,,2,,3)]}], - ); - - # Append a newline to each entry in the OUT array. --- -1.7.6.4 diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index fbf67cb..6cfefc7 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.16-orig/doc/coreutils.texi coreutils-8.16/doc/coreutils.texi ---- coreutils-8.16-orig/doc/coreutils.texi 2012-03-26 07:38:37.000000000 +0200 -+++ coreutils-8.16/doc/coreutils.texi 2012-03-26 17:31:31.101014556 +0200 -@@ -10584,6 +10584,13 @@ pseudo-file-systems, such as automounter +diff -urNp coreutils-8.21-orig/doc/coreutils.texi coreutils-8.21/doc/coreutils.texi +--- coreutils-8.21-orig/doc/coreutils.texi 2013-02-11 10:37:28.000000000 +0100 ++++ coreutils-8.21/doc/coreutils.texi 2013-02-15 10:15:26.497593689 +0100 +@@ -10961,6 +10961,13 @@ pseudo-file-systems, such as automounter Scale sizes by @var{size} before printing them (@pxref{Block size}). For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. @@ -15,23 +15,23 @@ diff -urNp coreutils-8.16-orig/doc/coreutils.texi coreutils-8.16/doc/coreutils.t @item --total @opindex --total @cindex grand total of disk size, usage and available space -diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c ---- coreutils-8.16-orig/src/df.c 2012-03-24 21:26:51.000000000 +0100 -+++ coreutils-8.16/src/df.c 2012-03-26 17:31:31.102014797 +0200 -@@ -113,6 +113,9 @@ static bool print_type; +diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c +--- coreutils-8.21-orig/src/df.c 2013-02-05 00:40:31.000000000 +0100 ++++ coreutils-8.21/src/df.c 2013-02-15 10:26:41.158651782 +0100 +@@ -116,6 +116,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; +/* If true, show statistics for a file instead of mount point. */ +static bool direct_statfs; + - /* Grand total data. */ + /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -167,13 +170,15 @@ static size_t nrows; - { - NO_SYNC_OPTION = CHAR_MAX + 1, +@@ -238,13 +241,15 @@ enum SYNC_OPTION, + TOTAL_OPTION, + OUTPUT_OPTION, - MEGABYTES_OPTION /* FIXME: remove long opt in Aug 2013 */ + MEGABYTES_OPTION, /* FIXME: remove long opt in Aug 2013 */ + DIRECT_OPTION @@ -45,20 +45,19 @@ diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, -@@ -260,7 +265,11 @@ get_header (void) - } - +@@ -500,7 +505,10 @@ get_header (void) + for (col = 0; col < ncolumns; col++) + { char *cell = NULL; -- char const *header = _(headers[field][header_mode]); -+ -+ char const *header = (field == MNT_FIELD && direct_statfs)? -+ _("File") : -+ _(headers[field][header_mode]); -+ - if (!header) - header = _(headers[field][DEFAULT_MODE]); +- char const *header = _(columns[col]->caption); ++ char const *header = (columns[col]->field == TARGET_FIELD ++ && direct_statfs)? ++ _("File") : ++ _(columns[col]->caption); -@@ -790,6 +799,17 @@ get_point (const char *point, const stru + if (columns[col]->field == SIZE_FIELD + && (header_mode == DEFAULT_MODE +@@ -1150,6 +1158,17 @@ get_point (const char *point, const stru static void get_entry (char const *name, struct stat const *statp) { @@ -76,7 +75,7 @@ diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_disk (name)) return; -@@ -857,6 +877,7 @@ Mandatory arguments to long options are +@@ -1219,6 +1238,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them. E.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes.\n\ See SIZE format below.\n\ @@ -84,7 +83,7 @@ diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c --total produce a grand total\n\ -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\ \n\ -@@ -933,6 +954,9 @@ main (int argc, char **argv) +@@ -1305,6 +1325,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -92,9 +91,9 @@ diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c + direct_statfs = true; + break; case 'i': - inode_format = true; - break; -@@ -993,6 +1017,13 @@ main (int argc, char **argv) + if (header_mode == OUTPUT_MODE) + { +@@ -1408,6 +1431,13 @@ main (int argc, char **argv) } } @@ -108,9 +107,9 @@ diff -urNp coreutils-8.16-orig/src/df.c coreutils-8.16/src/df.c if (human_output_opts == -1) { if (posix_format) -diff -urNp coreutils-8.16-orig/tests/df/direct.sh coreutils-8.16/tests/df/direct.sh ---- coreutils-8.16-orig/tests/df/direct.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.16/tests/df/direct.sh 2012-03-26 17:31:31.102897406 +0200 +diff -urNp coreutils-8.21-orig/tests/df/direct.sh coreutils-8.21/tests/df/direct.sh +--- coreutils-8.21-orig/tests/df/direct.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.21/tests/df/direct.sh 2013-02-15 10:15:26.503644446 +0100 @@ -0,0 +1,55 @@ +#!/bin/sh +# Ensure "df --direct" works as documented diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 641d9e5..5bc56d1 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.20-orig/lib/linebuffer.h coreutils-8.20/lib/linebuffer.h ---- coreutils-8.20-orig/lib/linebuffer.h 2012-10-23 16:17:24.000000000 +0200 -+++ coreutils-8.20/lib/linebuffer.h 2013-01-23 09:24:24.619090620 +0100 +diff -urNp coreutils-8.21-orig/lib/linebuffer.h coreutils-8.21/lib/linebuffer.h +--- coreutils-8.21-orig/lib/linebuffer.h 2013-01-02 13:34:46.000000000 +0100 ++++ coreutils-8.21/lib/linebuffer.h 2013-02-15 14:25:07.758469108 +0100 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.20-orig/lib/linebuffer.h coreutils-8.20/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c ---- coreutils-8.20-orig/src/cut.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/cut.c 2013-01-23 09:24:24.621092254 +0100 +diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c +--- coreutils-8.21-orig/src/cut.c 2013-02-05 00:40:31.000000000 +0100 ++++ coreutils-8.21/src/cut.c 2013-02-15 14:25:07.760467982 +0100 @@ -28,6 +28,11 @@ #include #include @@ -170,7 +170,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -206,7 +283,7 @@ Mandatory arguments to long options are +@@ -205,7 +282,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\ @@ -179,35 +179,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -365,7 +442,7 @@ set_fields (const char *fieldstr) - in_digits = false; - /* Starting a range. */ - if (dash_found) -- FATAL_ERROR (_("invalid byte or field list")); -+ FATAL_ERROR (_("invalid byte, character or field list")); - dash_found = true; - fieldstr++; - -@@ -389,14 +466,16 @@ set_fields (const char *fieldstr) - if (!rhs_specified) - { - /* 'n-'. From 'initial' to end of line. */ -- eol_range_start = initial; -+ if (eol_range_start == 0 || -+ (eol_range_start != 0 && eol_range_start > initial)) -+ eol_range_start = initial; - field_found = true; - } - else - { - /* 'm-n' or '-n' (1-n). */ - if (value < initial) -- FATAL_ERROR (_("invalid decreasing range")); -+ FATAL_ERROR (_("invalid byte, character or field list")); - - /* Is there already a range going to end of line? */ - if (eol_range_start != 0) -@@ -476,6 +555,9 @@ set_fields (const char *fieldstr) +@@ -480,6 +557,9 @@ set_fields (const char *fieldstr) if (operating_mode == byte_mode) error (0, 0, _("byte offset %s is too large"), quote (bad_num)); @@ -217,16 +189,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c else error (0, 0, _("field number %s is too large"), quote (bad_num)); -@@ -486,7 +568,7 @@ set_fields (const char *fieldstr) - fieldstr++; - } - else -- FATAL_ERROR (_("invalid byte or field list")); -+ FATAL_ERROR (_("invalid byte, character or field list")); - } - - max_range_endpoint = 0; -@@ -581,6 +663,77 @@ cut_bytes (FILE *stream) +@@ -588,6 +668,77 @@ cut_bytes (FILE *stream) } } @@ -304,7 +267,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -703,13 +856,195 @@ cut_fields (FILE *stream) +@@ -709,13 +860,195 @@ cut_fields (FILE *stream) } } @@ -503,7 +466,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c } /* Process file FILE to standard output. -@@ -761,6 +1096,8 @@ main (int argc, char **argv) +@@ -767,6 +1100,8 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -512,7 +475,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -783,7 +1120,6 @@ main (int argc, char **argv) +@@ -789,7 +1124,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -520,7 +483,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -791,6 +1127,14 @@ main (int argc, char **argv) +@@ -797,6 +1131,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -535,7 +498,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -802,10 +1146,35 @@ main (int argc, char **argv) +@@ -808,10 +1150,35 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -575,7 +538,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -818,6 +1187,7 @@ main (int argc, char **argv) +@@ -824,6 +1191,7 @@ main (int argc, char **argv) break; case 'n': @@ -583,16 +546,7 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c break; case 's': -@@ -840,7 +1210,7 @@ main (int argc, char **argv) - if (operating_mode == undefined_mode) - FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); - -- if (delim != '\0' && operating_mode != field_mode) -+ if (delim_specified && operating_mode != field_mode) - FATAL_ERROR (_("an input delimiter may be specified only\ - when operating on fields")); - -@@ -867,15 +1237,34 @@ main (int argc, char **argv) +@@ -873,15 +1241,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -633,9 +587,10 @@ diff -urNp coreutils-8.20-orig/src/cut.c coreutils-8.20/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.20-orig/src/expand.c coreutils-8.20/src/expand.c ---- coreutils-8.20-orig/src/expand.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/expand.c 2013-01-23 09:24:24.622088030 +0100 +Binary files coreutils-8.21-orig/src/.cut.c.swp and coreutils-8.21/src/.cut.c.swp differ +diff -urNp coreutils-8.21-orig/src/expand.c coreutils-8.21/src/expand.c +--- coreutils-8.21-orig/src/expand.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/expand.c 2013-02-15 14:25:07.774467536 +0100 @@ -37,12 +37,29 @@ #include #include @@ -666,7 +621,7 @@ diff -urNp coreutils-8.20-orig/src/expand.c coreutils-8.20/src/expand.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "expand" -@@ -358,6 +375,142 @@ expand (void) +@@ -357,6 +374,142 @@ expand (void) } } @@ -809,7 +764,7 @@ diff -urNp coreutils-8.20-orig/src/expand.c coreutils-8.20/src/expand.c int main (int argc, char **argv) { -@@ -422,7 +575,12 @@ main (int argc, char **argv) +@@ -421,7 +574,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -823,9 +778,9 @@ diff -urNp coreutils-8.20-orig/src/expand.c coreutils-8.20/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.20-orig/src/fold.c coreutils-8.20/src/fold.c ---- coreutils-8.20-orig/src/fold.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/fold.c 2013-01-23 09:24:24.623090499 +0100 +diff -urNp coreutils-8.21-orig/src/fold.c coreutils-8.21/src/fold.c +--- coreutils-8.21-orig/src/fold.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/fold.c 2013-02-15 14:25:07.789467891 +0100 @@ -22,12 +22,34 @@ #include #include @@ -907,15 +862,15 @@ diff -urNp coreutils-8.20-orig/src/fold.c coreutils-8.20/src/fold.c {"spaces", no_argument, NULL, 's'}, {"width", required_argument, NULL, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -77,6 +120,7 @@ Mandatory arguments to long options are - "), stdout); +@@ -76,6 +119,7 @@ standard output.\n\ + fputs (_("\ -b, --bytes count bytes rather than columns\n\ + -c, --characters count characters rather than columns\n\ -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -94,7 +138,7 @@ Mandatory arguments to long options are +@@ -93,7 +137,7 @@ standard output.\n\ static size_t adjust_column (size_t column, char c) { @@ -924,7 +879,7 @@ diff -urNp coreutils-8.20-orig/src/fold.c coreutils-8.20/src/fold.c { if (c == '\b') { -@@ -117,30 +161,14 @@ adjust_column (size_t column, char c) +@@ -116,30 +160,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -957,7 +912,7 @@ diff -urNp coreutils-8.20-orig/src/fold.c coreutils-8.20/src/fold.c fadvise (istream, FADVISE_SEQUENTIAL); -@@ -170,6 +198,15 @@ fold_file (char const *filename, size_t +@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t bool found_blank = false; size_t logical_end = offset_out; @@ -973,7 +928,7 @@ diff -urNp coreutils-8.20-orig/src/fold.c coreutils-8.20/src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -216,11 +253,221 @@ fold_file (char const *filename, size_t +@@ -215,11 +252,221 @@ fold_file (char const *filename, size_t line_out[offset_out++] = c; } @@ -1196,7 +1151,7 @@ diff -urNp coreutils-8.20-orig/src/fold.c coreutils-8.20/src/fold.c if (ferror (istream)) { error (0, saved_errno, "%s", filename); -@@ -253,7 +500,8 @@ main (int argc, char **argv) +@@ -252,7 +499,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1206,7 +1161,7 @@ diff -urNp coreutils-8.20-orig/src/fold.c coreutils-8.20/src/fold.c while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -262,7 +510,15 @@ main (int argc, char **argv) +@@ -261,7 +509,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1223,9 +1178,9 @@ diff -urNp coreutils-8.20-orig/src/fold.c coreutils-8.20/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.20-orig/src/join.c coreutils-8.20/src/join.c ---- coreutils-8.20-orig/src/join.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/join.c 2013-01-23 09:29:53.877170828 +0100 +diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c +--- coreutils-8.21-orig/src/join.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/join.c 2013-02-15 14:25:07.804467922 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1716,9 +1671,9 @@ diff -urNp coreutils-8.20-orig/src/join.c coreutils-8.20/src/join.c break; case NOCHECK_ORDER_OPTION: -diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c ---- coreutils-8.20-orig/src/pr.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/pr.c 2013-01-23 09:24:24.629439021 +0100 +diff -urNp coreutils-8.21-orig/src/pr.c coreutils-8.21/src/pr.c +--- coreutils-8.21-orig/src/pr.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/pr.c 2013-02-15 14:25:07.819467936 +0100 @@ -312,6 +312,32 @@ #include @@ -1839,7 +1794,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -638,7 +692,13 @@ static int power_10; +@@ -634,7 +688,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1854,7 +1809,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -691,6 +751,7 @@ static bool use_col_separator = false; +@@ -687,6 +747,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ static char *col_sep_string = (char *) ""; static int col_sep_length = 0; @@ -1862,7 +1817,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -847,6 +908,13 @@ separator_string (const char *optarg_S) +@@ -843,6 +904,13 @@ separator_string (const char *optarg_S) col_sep_length = (int) strlen (optarg_S); col_sep_string = xmalloc (col_sep_length + 1); strcpy (col_sep_string, optarg_S); @@ -1876,7 +1831,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c } int -@@ -871,6 +939,21 @@ main (int argc, char **argv) +@@ -867,6 +935,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1898,7 +1853,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c n_files = 0; file_names = (argc > 1 ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -947,8 +1030,12 @@ main (int argc, char **argv) +@@ -943,8 +1026,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1913,7 +1868,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -961,8 +1048,12 @@ main (int argc, char **argv) +@@ -957,8 +1044,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1928,7 +1883,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -989,8 +1080,8 @@ main (int argc, char **argv) +@@ -985,8 +1076,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1939,7 +1894,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c break; case 'N': skip_count = false; -@@ -1029,7 +1120,7 @@ main (int argc, char **argv) +@@ -1025,7 +1116,7 @@ main (int argc, char **argv) old_s = false; /* Reset an additional input of -s, -S dominates -s */ col_sep_string = bad_cast (""); @@ -1948,7 +1903,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1186,10 +1277,45 @@ main (int argc, char **argv) +@@ -1182,10 +1273,45 @@ main (int argc, char **argv) a number. */ static void @@ -1996,7 +1951,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c if (*arg) { long int tmp_long; -@@ -1211,6 +1337,11 @@ static void +@@ -1207,6 +1333,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -2008,7 +1963,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1248,7 +1379,7 @@ init_parameters (int number_of_files) +@@ -1244,7 +1375,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -2017,7 +1972,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1279,11 +1410,11 @@ init_parameters (int number_of_files) +@@ -1274,11 +1405,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. */ @@ -2031,7 +1986,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1298,7 +1429,7 @@ init_parameters (int number_of_files) +@@ -1287,7 +1418,7 @@ init_parameters (int number_of_files) } chars_per_column = (chars_per_line - chars_used_by_number @@ -2040,7 +1995,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c if (chars_per_column < 1) error (EXIT_FAILURE, 0, _("page width too narrow")); -@@ -1315,7 +1446,7 @@ init_parameters (int number_of_files) +@@ -1305,7 +1436,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); @@ -2049,7 +2004,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c } /* Open the necessary files, -@@ -1423,7 +1554,7 @@ init_funcs (void) +@@ -1413,7 +1544,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2058,7 +2013,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c /* This loop takes care of all but the rightmost column. */ -@@ -1457,7 +1588,7 @@ init_funcs (void) +@@ -1447,7 +1578,7 @@ init_funcs (void) } else { @@ -2067,7 +2022,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c h_next = h + chars_per_column; } } -@@ -1748,9 +1879,9 @@ static void +@@ -1738,9 +1869,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2079,7 +2034,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2021,13 +2152,13 @@ store_char (char c) +@@ -2011,13 +2142,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2093,9 +2048,9 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c - int i; + int i, j; char *s; - int left_cut; + int num_width; -@@ -2050,22 +2181,24 @@ add_line_number (COLUMN *p) +@@ -2034,22 +2165,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. */ @@ -2124,7 +2079,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2226,7 +2359,7 @@ print_white_space (void) +@@ -2210,7 +2343,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2133,7 +2088,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c h_old = h_new; } while (++h_old <= goal) -@@ -2246,6 +2379,7 @@ print_sep_string (void) +@@ -2230,6 +2363,7 @@ print_sep_string (void) { char *s; int l = col_sep_length; @@ -2141,7 +2096,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c s = col_sep_string; -@@ -2259,6 +2393,7 @@ print_sep_string (void) +@@ -2243,6 +2377,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2149,7 +2104,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2272,12 +2407,15 @@ print_sep_string (void) +@@ -2256,12 +2391,15 @@ print_sep_string (void) } else { @@ -2166,7 +2121,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2305,7 +2443,7 @@ print_clump (COLUMN *p, int n, char *clu +@@ -2289,7 +2427,7 @@ print_clump (COLUMN *p, int n, char *clu required number of tabs and spaces. */ static void @@ -2175,7 +2130,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c { if (tabify_output) { -@@ -2329,6 +2467,74 @@ print_char (char c) +@@ -2313,6 +2451,74 @@ print_char (char c) putchar (c); } @@ -2250,7 +2205,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2508,9 +2714,9 @@ read_line (COLUMN *p) +@@ -2492,9 +2698,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2262,7 +2217,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2611,9 +2817,9 @@ print_stored (COLUMN *p) +@@ -2595,9 +2801,9 @@ print_stored (COLUMN *p) } } @@ -2274,7 +2229,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2626,8 +2832,8 @@ print_stored (COLUMN *p) +@@ -2610,8 +2816,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2285,7 +2240,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c } return true; -@@ -2646,7 +2852,7 @@ print_stored (COLUMN *p) +@@ -2630,7 +2836,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2294,7 +2249,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c { unsigned char uc = c; char *s = clump_buff; -@@ -2656,10 +2862,10 @@ char_to_clump (char c) +@@ -2640,10 +2846,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2307,7 +2262,7 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2740,6 +2946,154 @@ char_to_clump (char c) +@@ -2724,6 +2930,154 @@ char_to_clump (char c) return chars; } @@ -2462,9 +2417,9 @@ diff -urNp coreutils-8.20-orig/src/pr.c coreutils-8.20/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c ---- coreutils-8.20-orig/src/sort.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/sort.c 2013-01-23 09:35:36.091438847 +0100 +diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c +--- coreutils-8.21-orig/src/sort.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/sort.c 2013-02-15 14:25:07.828467769 +0100 @@ -29,6 +29,14 @@ #include #include @@ -2533,7 +2488,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -784,6 +812,46 @@ reap_all (void) +@@ -783,6 +811,46 @@ reap_all (void) reap (-1); } @@ -2580,7 +2535,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1224,7 +1292,7 @@ zaptemp (char const *name) +@@ -1223,7 +1291,7 @@ zaptemp (char const *name) free (node); } @@ -2589,7 +2544,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1239,7 +1307,7 @@ struct_month_cmp (void const *m1, void c +@@ -1238,7 +1306,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2598,7 +2553,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c { size_t i; -@@ -1251,7 +1319,7 @@ inittables (void) +@@ -1250,7 +1318,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2607,7 +2562,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1333,6 +1401,84 @@ specify_nmerge (int oi, char c, char con +@@ -1332,6 +1400,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2692,7 +2647,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1565,7 +1711,7 @@ buffer_linelim (struct buffer const *buf +@@ -1564,7 +1710,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2701,7 +2656,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1574,10 +1720,10 @@ begfield (struct line const *line, struc +@@ -1573,10 +1719,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2714,7 +2669,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1603,11 +1749,70 @@ begfield (struct line const *line, struc +@@ -1602,11 +1748,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2786,7 +2741,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1622,10 +1827,10 @@ limfield (struct line const *line, struc +@@ -1621,10 +1826,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. */ @@ -2799,7 +2754,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1671,10 +1876,10 @@ limfield (struct line const *line, struc +@@ -1670,10 +1875,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2812,7 +2767,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c if (newlim) lim = newlim; } -@@ -1705,6 +1910,130 @@ limfield (struct line const *line, struc +@@ -1704,6 +1909,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2943,7 +2898,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c /* 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 -@@ -1791,8 +2120,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1790,8 +2119,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2968,7 +2923,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c line->keybeg = line_start; } } -@@ -1913,7 +2256,7 @@ human_numcompare (char const *a, char co +@@ -1912,7 +2255,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2977,7 +2932,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1923,6 +2266,25 @@ numcompare (char const *a, char const *b +@@ -1922,6 +2265,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3003,7 +2958,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c /* 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 once -@@ -1973,7 +2335,7 @@ general_numcompare (char const *sa, char +@@ -1972,7 +2334,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -3012,7 +2967,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2248,15 +2610,14 @@ debug_key (struct line const *line, stru +@@ -2247,15 +2609,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -3030,7 +2985,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2400,7 +2761,7 @@ key_warnings (struct keyfield const *gke +@@ -2399,7 +2760,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3039,7 +2994,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2458,11 +2819,87 @@ key_warnings (struct keyfield const *gke +@@ -2457,11 +2818,87 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -3128,7 +3083,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c { struct keyfield *key = keylist; -@@ -2547,7 +2984,7 @@ keycompare (struct line const *a, struct +@@ -2546,7 +2983,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3137,7 +3092,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2663,6 +3100,181 @@ keycompare (struct line const *a, struct +@@ -2662,6 +3099,181 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3319,7 +3274,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -4158,7 +4770,7 @@ main (int argc, char **argv) +@@ -4157,7 +4769,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3328,7 +3283,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4179,6 +4791,29 @@ main (int argc, char **argv) +@@ -4178,6 +4790,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3358,7 +3313,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c have_read_stdin = false; inittables (); -@@ -4453,13 +5088,34 @@ main (int argc, char **argv) +@@ -4452,13 +5087,34 @@ main (int argc, char **argv) case 't': { @@ -3397,7 +3352,7 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4470,9 +5126,12 @@ main (int argc, char **argv) +@@ -4469,9 +5125,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3412,9 +3367,9 @@ diff -urNp coreutils-8.20-orig/src/sort.c coreutils-8.20/src/sort.c } break; -diff -urNp coreutils-8.20-orig/src/unexpand.c coreutils-8.20/src/unexpand.c ---- coreutils-8.20-orig/src/unexpand.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/unexpand.c 2013-01-23 09:24:24.636292411 +0100 +diff -urNp coreutils-8.21-orig/src/unexpand.c coreutils-8.21/src/unexpand.c +--- coreutils-8.21-orig/src/unexpand.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/unexpand.c 2013-02-15 14:25:07.834467715 +0100 @@ -38,12 +38,29 @@ #include #include @@ -3654,7 +3609,7 @@ diff -urNp coreutils-8.20-orig/src/unexpand.c coreutils-8.20/src/unexpand.c void usage (int status) { -@@ -524,7 +743,12 @@ main (int argc, char **argv) +@@ -523,7 +742,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -3668,9 +3623,9 @@ diff -urNp coreutils-8.20-orig/src/unexpand.c coreutils-8.20/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c ---- coreutils-8.20-orig/src/uniq.c 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/uniq.c 2013-01-23 09:46:33.757064880 +0100 +diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c +--- coreutils-8.21-orig/src/uniq.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/uniq.c 2013-02-15 14:25:07.839467991 +0100 @@ -21,6 +21,16 @@ #include #include @@ -3720,7 +3675,7 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -206,7 +232,7 @@ size_opt (char const *opt, char const *m +@@ -205,7 +231,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 @@ -3729,7 +3684,7 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -226,6 +252,83 @@ find_field (struct linebuffer const *lin +@@ -225,6 +251,83 @@ find_field (struct linebuffer const *lin return line->buffer + i; } @@ -3813,7 +3768,7 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c /* 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. -@@ -234,6 +337,8 @@ find_field (struct linebuffer const *lin +@@ -233,6 +336,8 @@ find_field (struct linebuffer const *lin static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -3822,7 +3777,7 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -241,14 +346,100 @@ different (char *old, char *new, size_t +@@ -240,14 +345,100 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3928,7 +3883,7 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -304,15 +495,43 @@ check_file (const char *infile, const ch +@@ -303,15 +494,43 @@ check_file (const char *infile, const ch { char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); @@ -3972,7 +3927,7 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c if (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)) { -@@ -331,17 +550,26 @@ check_file (const char *infile, const ch +@@ -330,17 +549,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -3999,7 +3954,7 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -350,6 +578,14 @@ check_file (const char *infile, const ch +@@ -349,6 +577,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -4014,7 +3969,7 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -382,6 +618,9 @@ check_file (const char *infile, const ch +@@ -381,6 +617,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4024,7 +3979,7 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c if (!match) match_count = 0; } -@@ -427,6 +666,19 @@ main (int argc, char **argv) +@@ -426,6 +665,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4044,10 +3999,10 @@ diff -urNp coreutils-8.20-orig/src/uniq.c coreutils-8.20/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.20-orig/tests/misc/local.mk coreutils-8.20/tests/misc/local.mk ---- coreutils-8.20-orig/tests/local.mk 2013-02-07 15:26:29.559370456 +0100 -+++ coreutils-8.20/tests/local.mk 2013-02-07 15:24:51.625470679 +0100 -@@ -323,6 +323,7 @@ all_tests = \ +diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk +--- coreutils-8.21-orig/tests/local.mk 2013-02-15 14:24:32.645654553 +0100 ++++ coreutils-8.21/tests/local.mk 2013-02-15 14:25:07.873467648 +0100 +@@ -325,6 +325,7 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -4055,10 +4010,10 @@ diff -urNp coreutils-8.20-orig/tests/misc/local.mk coreutils-8.20/tests/misc/loc tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ tests/misc/sort-month.sh \ -diff -urNp coreutils-8.20-orig/tests/misc/cut.pl coreutils-8.20/tests/misc/cut.pl ---- coreutils-8.20-orig/tests/misc/cut.pl 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/tests/misc/cut.pl 2013-01-23 09:24:24.639346707 +0100 -@@ -23,14 +23,15 @@ use strict; +diff -urNp coreutils-8.21-orig/tests/misc/cut.pl coreutils-8.21/tests/misc/cut.pl +--- coreutils-8.21-orig/tests/misc/cut.pl 2013-02-05 00:40:31.000000000 +0100 ++++ coreutils-8.21/tests/misc/cut.pl 2013-02-15 14:27:18.974468564 +0100 +@@ -23,9 +23,10 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4072,24 +4027,9 @@ diff -urNp coreutils-8.20-orig/tests/misc/cut.pl coreutils-8.20/tests/misc/cut.p my $prog = 'cut'; my $try = "Try '$prog --help' for more information.\n"; - my $from_1 = "$prog: fields and positions are numbered from 1\n$try"; --my $inval = "$prog: invalid byte or field list\n$try"; -+my $inval = "$prog: invalid byte, character or field list\n$try"; - my $no_endpoint = "$prog: invalid range with no endpoint: -\n$try"; - - my @Tests = -@@ -147,7 +148,7 @@ my @Tests = - - # None of the following invalid ranges provoked an error up to coreutils-6.9. - ['inval1', qw(-f 2-0), {IN=>''}, {OUT=>''}, {EXIT=>1}, -- {ERR=>"$prog: invalid decreasing range\n$try"}], -+ {ERR=>"$prog: invalid byte, character or field list\n$try"}], - ['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], - ['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}], - ['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, -diff -urNp coreutils-8.20-orig/tests/misc/expand.pl coreutils-8.20/tests/misc/expand.pl ---- coreutils-8.20-orig/tests/misc/expand.pl 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/tests/misc/expand.pl 2013-01-23 09:24:24.640439471 +0100 +diff -urNp coreutils-8.21-orig/tests/misc/expand.pl coreutils-8.21/tests/misc/expand.pl +--- coreutils-8.21-orig/tests/misc/expand.pl 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/tests/misc/expand.pl 2013-02-15 14:25:07.891468472 +0100 @@ -23,6 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4144,41 +4084,41 @@ diff -urNp coreutils-8.20-orig/tests/misc/expand.pl coreutils-8.20/tests/misc/ex my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.20-orig/tests/misc/mb1.I coreutils-8.20/tests/misc/mb1.I ---- coreutils-8.20-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/mb1.I 2013-01-23 09:24:24.640439471 +0100 +diff -urNp coreutils-8.21-orig/tests/misc/mb1.I coreutils-8.21/tests/misc/mb1.I +--- coreutils-8.21-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.21/tests/misc/mb1.I 2013-02-15 14:25:07.902467891 +0100 @@ -0,0 +1,4 @@ +Apple@10 +Banana@5 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.20-orig/tests/misc/mb1.X coreutils-8.20/tests/misc/mb1.X ---- coreutils-8.20-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/mb1.X 2013-01-23 09:24:24.641395635 +0100 +diff -urNp coreutils-8.21-orig/tests/misc/mb1.X coreutils-8.21/tests/misc/mb1.X +--- coreutils-8.21-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.21/tests/misc/mb1.X 2013-02-15 14:25:07.917467426 +0100 @@ -0,0 +1,4 @@ +Banana@5 +Apple@10 +Citrus@20 +Cherry@30 -diff -urNp coreutils-8.20-orig/tests/misc/mb2.I coreutils-8.20/tests/misc/mb2.I ---- coreutils-8.20-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/mb2.I 2013-01-23 09:24:24.642441918 +0100 +diff -urNp coreutils-8.21-orig/tests/misc/mb2.I coreutils-8.21/tests/misc/mb2.I +--- coreutils-8.21-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.21/tests/misc/mb2.I 2013-02-15 14:25:07.933467390 +0100 @@ -0,0 +1,4 @@ +Apple@AA10@@20 +Banana@AA5@@30 +Citrus@AA20@@5 +Cherry@AA30@@10 -diff -urNp coreutils-8.20-orig/tests/misc/mb2.X coreutils-8.20/tests/misc/mb2.X ---- coreutils-8.20-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/mb2.X 2013-01-23 09:24:24.642441918 +0100 +diff -urNp coreutils-8.21-orig/tests/misc/mb2.X coreutils-8.21/tests/misc/mb2.X +--- coreutils-8.21-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.21/tests/misc/mb2.X 2013-02-15 14:25:08.002467808 +0100 @@ -0,0 +1,4 @@ +Citrus@AA20@@5 +Cherry@AA30@@10 +Apple@AA10@@20 +Banana@AA5@@30 -diff -urNp coreutils-8.20-orig/tests/misc/sort-mb-tests.sh coreutils-8.20/tests/misc/sort-mb-tests.sh ---- coreutils-8.20-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.20/tests/misc/sort-mb-tests.sh 2013-01-23 09:24:24.643201093 +0100 +diff -urNp coreutils-8.21-orig/tests/misc/sort-mb-tests.sh coreutils-8.21/tests/misc/sort-mb-tests.sh +--- coreutils-8.21-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.21/tests/misc/sort-mb-tests.sh 2013-02-15 14:25:08.020467562 +0100 @@ -0,0 +1,63 @@ +#! /bin/sh + diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 9aab59c..a151acb 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,7 +1,7 @@ -diff -urNp coreutils-8.13-orig/configure.ac coreutils-8.13/configure.ac ---- coreutils-8.13-orig/configure.ac 2011-09-09 10:29:52.584690353 +0200 -+++ coreutils-8.13/configure.ac 2011-09-09 10:30:39.524564991 +0200 -@@ -141,6 +141,13 @@ if test "$gl_gcc_warnings" = yes; then +diff -urNp coreutils-8.21-orig/configure.ac coreutils-8.21/configure.ac +--- coreutils-8.21-orig/configure.ac 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/configure.ac 2013-02-15 14:31:58.937482694 +0100 +@@ -204,6 +204,13 @@ if test "$gl_gcc_warnings" = yes; then AC_SUBST([GNULIB_TEST_WARN_CFLAGS]) fi @@ -15,18 +15,32 @@ diff -urNp coreutils-8.13-orig/configure.ac coreutils-8.13/configure.ac AC_FUNC_FORK optional_bin_progs= -diff -urNp coreutils-8.13-orig/man/chcon.x coreutils-8.13/man/chcon.x ---- coreutils-8.13-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.13/man/chcon.x 2011-09-09 10:30:39.524564991 +0200 +diff -urNp coreutils-8.21-orig/init.cfg coreutils-8.21/init.cfg +--- coreutils-8.21-orig/init.cfg 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/init.cfg 2013-02-15 14:31:58.957469955 +0100 +@@ -308,8 +308,8 @@ require_selinux_() + + # Independent of whether SELinux is enabled system-wide, + # the current file system may lack SELinux support. +- case $(ls -Zd .) in +- '? .'|'unlabeled .') ++ case $(ls -Zd . | cut -f4 -d" ") in ++ '?'|'unlabeled') + skip_ "this system (or maybe just" \ + "the current file system) lacks SELinux support" + ;; +diff -urNp coreutils-8.21-orig/man/chcon.x coreutils-8.21/man/chcon.x +--- coreutils-8.21-orig/man/chcon.x 2011-08-23 15:44:01.000000000 +0200 ++++ coreutils-8.21/man/chcon.x 2013-02-15 14:31:58.937482694 +0100 @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-8.13-orig/man/runcon.x coreutils-8.13/man/runcon.x ---- coreutils-8.13-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200 -+++ coreutils-8.13/man/runcon.x 2011-09-09 10:30:39.544686472 +0200 +diff -urNp coreutils-8.21-orig/man/runcon.x coreutils-8.21/man/runcon.x +--- coreutils-8.21-orig/man/runcon.x 2011-08-23 15:44:01.000000000 +0200 ++++ coreutils-8.21/man/runcon.x 2013-02-15 14:31:58.938486496 +0100 @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -34,22 +48,22 @@ diff -urNp coreutils-8.13-orig/man/runcon.x coreutils-8.13/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.13-orig/src/chcon.c coreutils-8.13/src/chcon.c ---- coreutils-8.13-orig/src/chcon.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/chcon.c 2011-09-09 10:30:39.562561252 +0200 -@@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ +diff -urNp coreutils-8.21-orig/src/chcon.c coreutils-8.21/src/chcon.c +--- coreutils-8.21-orig/src/chcon.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/chcon.c 2013-02-15 14:31:58.939469828 +0100 +@@ -355,7 +355,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ "), program_name, program_name, program_name); fputs (_("\ -Change the security context of each FILE to CONTEXT.\n\ +Change the SELinux security context of each FILE to CONTEXT.\n\ With --reference, change the security context of each FILE to that of RFILE.\n\ - \n\ "), stdout); -diff -urNp coreutils-8.13-orig/src/copy.c coreutils-8.13/src/copy.c ---- coreutils-8.13-orig/src/copy.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/copy.c 2011-09-09 10:30:39.564562214 +0200 -@@ -2244,6 +2244,8 @@ copy_internal (char const *src_name, cha + +diff -urNp coreutils-8.21-orig/src/copy.c coreutils-8.21/src/copy.c +--- coreutils-8.21-orig/src/copy.c 2013-02-07 10:37:05.000000000 +0100 ++++ coreutils-8.21/src/copy.c 2013-02-15 14:31:58.941467872 +0100 +@@ -2315,6 +2315,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -58,10 +72,10 @@ diff -urNp coreutils-8.13-orig/src/copy.c coreutils-8.13/src/copy.c } else { -diff -urNp coreutils-8.13-orig/src/copy.h coreutils-8.13/src/copy.h ---- coreutils-8.13-orig/src/copy.h 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/copy.h 2011-09-09 10:30:39.565563712 +0200 -@@ -158,6 +158,9 @@ struct cp_options +diff -urNp coreutils-8.21-orig/src/copy.h coreutils-8.21/src/copy.h +--- coreutils-8.21-orig/src/copy.h 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/copy.h 2013-02-15 14:31:58.943470982 +0100 +@@ -159,6 +159,9 @@ struct cp_options bool preserve_timestamps; bool explicit_no_preserve_mode; @@ -71,9 +85,9 @@ diff -urNp coreutils-8.13-orig/src/copy.h coreutils-8.13/src/copy.h /* Enabled for mv, and for cp by the --preserve=links option. If true, attempt to preserve in the destination files any logical hard links between the source files. If used with cp's -diff -urNp coreutils-8.13-orig/src/cp.c coreutils-8.13/src/cp.c ---- coreutils-8.13-orig/src/cp.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/cp.c 2011-09-09 10:30:39.566562062 +0200 +diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c +--- coreutils-8.21-orig/src/cp.c 2013-02-07 10:37:05.000000000 +0100 ++++ coreutils-8.21/src/cp.c 2013-02-15 14:31:58.945468929 +0100 @@ -141,6 +141,7 @@ static struct option const long_opts[] = {"target-directory", required_argument, NULL, 't'}, {"update", no_argument, NULL, 'u'}, @@ -82,7 +96,7 @@ diff -urNp coreutils-8.13-orig/src/cp.c coreutils-8.13/src/cp.c {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, {NULL, 0, NULL, 0} -@@ -204,6 +205,9 @@ Mandatory arguments to long options are +@@ -201,6 +202,9 @@ Copy SOURCE to DEST, or multiple SOURCE( all\n\ "), stdout); fputs (_("\ @@ -92,7 +106,7 @@ diff -urNp coreutils-8.13-orig/src/cp.c coreutils-8.13/src/cp.c --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents use full source file name under DIRECTORY\n\ "), stdout); -@@ -230,6 +234,7 @@ Mandatory arguments to long options are +@@ -227,6 +231,7 @@ Copy SOURCE to DEST, or multiple SOURCE( destination file is missing\n\ -v, --verbose explain what is being done\n\ -x, --one-file-system stay on this file system\n\ @@ -100,7 +114,7 @@ diff -urNp coreutils-8.13-orig/src/cp.c coreutils-8.13/src/cp.c "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); -@@ -786,6 +791,7 @@ cp_option_init (struct cp_options *x) +@@ -784,6 +789,7 @@ cp_option_init (struct cp_options *x) x->explicit_no_preserve_mode = false; x->preserve_security_context = false; x->require_preserve_context = false; @@ -134,7 +148,7 @@ diff -urNp coreutils-8.13-orig/src/cp.c coreutils-8.13/src/cp.c case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -@@ -1090,6 +1106,27 @@ main (int argc, char **argv) +@@ -1091,6 +1107,27 @@ main (int argc, char **argv) x.one_file_system = true; break; @@ -162,10 +176,10 @@ diff -urNp coreutils-8.13-orig/src/cp.c coreutils-8.13/src/cp.c case 'S': make_backups = true; backup_suffix_string = optarg; -diff -urNp coreutils-8.13-orig/src/id.c coreutils-8.13/src/id.c ---- coreutils-8.13-orig/src/id.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/id.c 2011-09-09 10:30:39.567562153 +0200 -@@ -107,7 +107,7 @@ int +diff -urNp coreutils-8.21-orig/src/id.c coreutils-8.21/src/id.c +--- coreutils-8.21-orig/src/id.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/id.c 2013-02-15 14:31:58.946469154 +0100 +@@ -106,7 +106,7 @@ int main (int argc, char **argv) { int optc; @@ -174,10 +188,10 @@ diff -urNp coreutils-8.13-orig/src/id.c coreutils-8.13/src/id.c /* If true, output the list of all group IDs. -G */ bool just_group_list = false; -diff -urNp coreutils-8.13-orig/src/install.c coreutils-8.13/src/install.c ---- coreutils-8.13-orig/src/install.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/install.c 2011-09-09 10:30:39.569562422 +0200 -@@ -261,6 +261,7 @@ cp_option_init (struct cp_options *x) +diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c +--- coreutils-8.21-orig/src/install.c 2013-02-07 10:37:05.000000000 +0100 ++++ coreutils-8.21/src/install.c 2013-02-15 14:31:58.948469440 +0100 +@@ -280,6 +280,7 @@ cp_option_init (struct cp_options *x) x->data_copy_required = true; x->require_preserve = false; x->require_preserve_context = false; @@ -185,7 +199,7 @@ diff -urNp coreutils-8.13-orig/src/install.c coreutils-8.13/src/install.c x->require_preserve_xattr = false; x->recursive = false; x->sparse_mode = SPARSE_AUTO; -@@ -622,7 +623,7 @@ Mandatory arguments to long options are +@@ -639,7 +640,7 @@ In the 4th form, create all components o -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ @@ -194,7 +208,7 @@ diff -urNp coreutils-8.13-orig/src/install.c coreutils-8.13/src/install.c -Z, --context=CONTEXT set SELinux security context of files and directories\ \n\ "), stdout); -@@ -765,7 +766,7 @@ main (int argc, char **argv) +@@ -782,7 +783,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -203,7 +217,7 @@ diff -urNp coreutils-8.13-orig/src/install.c coreutils-8.13/src/install.c NULL)) != -1) { switch (optc) -@@ -835,6 +836,7 @@ main (int argc, char **argv) +@@ -853,6 +854,7 @@ main (int argc, char **argv) no_target_directory = true; break; @@ -211,7 +225,7 @@ diff -urNp coreutils-8.13-orig/src/install.c coreutils-8.13/src/install.c case PRESERVE_CONTEXT_OPTION: if ( ! selinux_enabled) { -@@ -842,6 +844,10 @@ main (int argc, char **argv) +@@ -860,6 +862,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } @@ -222,7 +236,7 @@ diff -urNp coreutils-8.13-orig/src/install.c coreutils-8.13/src/install.c x.preserve_security_context = true; use_default_selinux_context = false; break; -@@ -853,6 +859,7 @@ main (int argc, char **argv) +@@ -871,6 +877,7 @@ main (int argc, char **argv) break; } scontext = optarg; @@ -230,10 +244,10 @@ diff -urNp coreutils-8.13-orig/src/install.c coreutils-8.13/src/install.c use_default_selinux_context = false; break; case_GETOPT_HELP_CHAR; -diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c ---- coreutils-8.13-orig/src/ls.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/ls.c 2011-09-09 10:30:39.575562845 +0200 -@@ -166,7 +166,8 @@ enum filetype +diff -urNp coreutils-8.21-orig/src/ls.c coreutils-8.21/src/ls.c +--- coreutils-8.21-orig/src/ls.c 2013-02-03 04:24:02.000000000 +0100 ++++ coreutils-8.21/src/ls.c 2013-02-15 14:31:58.953469008 +0100 +@@ -165,7 +165,8 @@ enum filetype symbolic_link, sock, whiteout, @@ -243,7 +257,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c }; /* Display letters and indicators for each filetype. -@@ -282,6 +283,7 @@ +@@ -281,6 +282,7 @@ static void queue_directory (char const bool command_line_arg); static void sort_files (void); static void parse_ls_color (void); @@ -251,7 +265,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c /* Initial size of hash table. Most hierarchies are likely to be shallower than this. */ -@@ -352,7 +354,7 @@ static struct pending *pending_dirs; +@@ -350,7 +352,7 @@ static struct pending *pending_dirs; static struct timespec current_time; @@ -260,7 +274,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c static char UNKNOWN_SECURITY_CONTEXT[] = "?"; /* Whether any of the files has an ACL. This affects the width of the -@@ -392,7 +394,9 @@ enum format +@@ -390,7 +392,9 @@ enum format one_per_line, /* -1 */ many_per_line, /* -C */ horizontal, /* -x */ @@ -271,7 +285,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c }; static enum format format; -@@ -794,6 +798,9 @@ enum +@@ -793,6 +797,9 @@ enum SHOW_CONTROL_CHARS_OPTION, SI_OPTION, SORT_OPTION, @@ -353,7 +367,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c /* FIXME: put this in a function. */ { -@@ -1947,13 +1957,27 @@ decode_switches (int argc, char **argv) +@@ -1941,13 +1951,27 @@ decode_switches (int argc, char **argv) break; case 'Z': @@ -382,7 +396,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c default: usage (LS_FAILURE); } -@@ -2757,6 +2783,7 @@ gobble_file (char const *name, enum file +@@ -2883,6 +2907,7 @@ gobble_file (char const *name, enum file memset (f, '\0', sizeof *f); f->stat.st_ino = inode; f->filetype = type; @@ -390,7 +404,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c if (command_line_arg || format_needs_stat -@@ -2869,7 +2896,7 @@ gobble_file (char const *name, enum file +@@ -2995,7 +3020,7 @@ gobble_file (char const *name, enum file && print_with_color && is_colored (C_CAP)) f->has_capability = has_capability_cache (absolute_name, f); @@ -399,7 +413,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c { bool have_selinux = false; bool have_acl = false; -@@ -2892,7 +2919,7 @@ gobble_file (char const *name, enum file +@@ -3016,7 +3041,7 @@ gobble_file (char const *name, enum file err = 0; } @@ -408,7 +422,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c { int n = file_has_acl_cache (absolute_name, f); err = (n < 0); -@@ -2911,7 +2938,8 @@ gobble_file (char const *name, enum file +@@ -3035,7 +3060,8 @@ gobble_file (char const *name, enum file } if (S_ISLNK (f->stat.st_mode) @@ -418,7 +432,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c { struct stat linkstats; -@@ -2931,6 +2959,7 @@ gobble_file (char const *name, enum file +@@ -3054,6 +3080,7 @@ gobble_file (char const *name, enum file command line are automatically traced if not being listed as files. */ if (!command_line_arg || format == long_format @@ -426,7 +440,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c || !S_ISDIR (linkstats.st_mode)) { /* Get the linked-to file's mode for the filetype indicator -@@ -2970,7 +2999,7 @@ gobble_file (char const *name, enum file +@@ -3087,7 +3114,7 @@ gobble_file (char const *name, enum file block_size_width = len; } @@ -435,7 +449,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c { if (print_owner) { -@@ -3471,6 +3500,13 @@ print_current_files (void) +@@ -3591,6 +3618,13 @@ print_current_files (void) print_long_format (sorted_file[i]); DIRED_PUTCHAR ('\n'); } @@ -449,7 +463,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c break; } } -@@ -3633,6 +3669,67 @@ format_inode (char *buf, size_t buflen, +@@ -3753,6 +3787,67 @@ format_inode (char *buf, size_t buflen, : (char *) "?"); } @@ -517,7 +531,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c /* Print information about F in long format. */ static void print_long_format (const struct fileinfo *f) -@@ -3724,9 +3821,15 @@ print_long_format (const struct fileinfo +@@ -3844,9 +3939,15 @@ print_long_format (const struct fileinfo The latter is wrong when nlink_width is zero. */ p += strlen (p); @@ -534,7 +548,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c { DIRED_FPUTS (buf, stdout, p - buf); -@@ -3739,9 +3842,6 @@ print_long_format (const struct fileinfo +@@ -3859,9 +3960,6 @@ print_long_format (const struct fileinfo if (print_author) format_user (f->stat.st_author, author_width, f->stat_ok); @@ -544,7 +558,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c p = buf; } -@@ -4086,9 +4186,6 @@ print_file_name_and_frills (const struct +@@ -4207,9 +4305,6 @@ print_file_name_and_frills (const struct : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, ST_NBLOCKSIZE, output_block_size)); @@ -554,7 +568,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c size_t width = print_name_with_quoting (f, false, NULL, start_col); if (indicator_style != none) -@@ -4292,9 +4389,6 @@ length_of_file_name_and_frills (const st +@@ -4417,9 +4512,6 @@ length_of_file_name_and_frills (const st output_block_size)) : block_size_width); @@ -564,7 +578,7 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c quote_name (NULL, f->name, filename_quoting_options, &name_width); len += name_width; -@@ -4733,9 +4827,16 @@ Mandatory arguments to long options are +@@ -4856,9 +4948,16 @@ Sort entries alphabetically if none of - -w, --width=COLS assume screen width instead of current value\n\ -x list entries by lines instead of by columns\n\ -X sort alphabetically by entry extension\n\ @@ -582,9 +596,9 @@ diff -urNp coreutils-8.13-orig/src/ls.c coreutils-8.13/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-8.13-orig/src/mkdir.c coreutils-8.13/src/mkdir.c ---- coreutils-8.13-orig/src/mkdir.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/mkdir.c 2011-09-09 10:30:39.576564256 +0200 +diff -urNp coreutils-8.21-orig/src/mkdir.c coreutils-8.21/src/mkdir.c +--- coreutils-8.21-orig/src/mkdir.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/mkdir.c 2013-02-15 14:31:58.954469576 +0100 @@ -38,6 +38,7 @@ static struct option const longopts[] = { @@ -593,9 +607,9 @@ diff -urNp coreutils-8.13-orig/src/mkdir.c coreutils-8.13/src/mkdir.c {"mode", required_argument, NULL, 'm'}, {"parents", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, -diff -urNp coreutils-8.13-orig/src/mknod.c coreutils-8.13/src/mknod.c ---- coreutils-8.13-orig/src/mknod.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/mknod.c 2011-09-09 10:30:39.577563177 +0200 +diff -urNp coreutils-8.21-orig/src/mknod.c coreutils-8.21/src/mknod.c +--- coreutils-8.21-orig/src/mknod.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/mknod.c 2013-02-15 14:31:58.955470548 +0100 @@ -35,7 +35,7 @@ static struct option const longopts[] = @@ -605,10 +619,10 @@ diff -urNp coreutils-8.13-orig/src/mknod.c coreutils-8.13/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urNp coreutils-8.13-orig/src/mv.c coreutils-8.13/src/mv.c ---- coreutils-8.13-orig/src/mv.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/mv.c 2011-09-09 10:30:39.578562234 +0200 -@@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x) +diff -urNp coreutils-8.21-orig/src/mv.c coreutils-8.21/src/mv.c +--- coreutils-8.21-orig/src/mv.c 2013-02-07 10:37:05.000000000 +0100 ++++ coreutils-8.21/src/mv.c 2013-02-15 14:31:58.956469593 +0100 +@@ -120,6 +120,7 @@ cp_option_init (struct cp_options *x) x->preserve_timestamps = true; x->explicit_no_preserve_mode= false; x->preserve_security_context = selinux_enabled; @@ -616,35 +630,21 @@ diff -urNp coreutils-8.13-orig/src/mv.c coreutils-8.13/src/mv.c x->reduce_diagnostics = false; x->data_copy_required = true; x->require_preserve = false; /* FIXME: maybe make this an option */ -diff -urNp coreutils-8.13-orig/src/runcon.c coreutils-8.13/src/runcon.c ---- coreutils-8.13-orig/src/runcon.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/runcon.c 2011-09-09 10:30:39.579564283 +0200 -@@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ +diff -urNp coreutils-8.21-orig/src/runcon.c coreutils-8.21/src/runcon.c +--- coreutils-8.21-orig/src/runcon.c 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/src/runcon.c 2013-02-15 14:31:58.956469593 +0100 +@@ -85,7 +85,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ "), program_name, program_name); fputs (_("\ -Run a program in a different security context.\n\ +Run a program in a different SELinux security context.\n\ With neither CONTEXT nor COMMAND, print the current security context.\n\ - \n\ - CONTEXT Complete security context\n\ -diff -urNp coreutils-8.20-orig/init.cfg coreutils-8.20/init.cfg ---- coreutils-8.20-orig/init.cfg -+++ coreutils-8.20/init.cfg -@@ -253,8 +253,8 @@ require_selinux_() + "), stdout); - # Independent of whether SELinux is enabled system-wide, - # the current file system may lack SELinux support. -- case $(ls -Zd .) in -- '? .'|'unlabeled .') -+ case $(ls -Zd . | cut -f4 -d" ") in -+ '?'|'unlabeled') - skip_ "this system (or maybe just" \ - "the current file system) lacks SELinux support" - ;; -diff -urNp coreutils-8.20-orig/tests/misc/selinux coreutils-8.20/tests/misc/selinux.sh ---- coreutils-8.20-orig/tests/misc/selinux.sh -+++ coreutils-8.20/tests/misc/selinux.sh +diff -urNp coreutils-8.21-orig/tests/misc/selinux.sh coreutils-8.21/tests/misc/selinux.sh +--- coreutils-8.21-orig/tests/misc/selinux.sh 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/tests/misc/selinux.sh 2013-02-15 14:31:58.957469955 +0100 @@ -37,7 +37,7 @@ chcon $ctx f d p || # inspect that context with both ls -Z and stat. diff --git a/coreutils.spec b/coreutils.spec index 77ad04d..90c31e5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.20 -Release: 8%{?dist} +Version: 8.21 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -15,8 +15,6 @@ Source106: coreutils-colorls.csh # From upstream Patch1: coreutils-8.20-powerpcfactor.patch -Patch2: coreutils-8.20-df-duplicates.patch -Patch3: coreutils-8.20-seq-s.patch # Our patches #general patch to workaround koji build system issues @@ -31,8 +29,6 @@ Patch103: coreutils-8.2-uname-processortype.patch Patch104: coreutils-df-direct.patch #add note about mkdir --mode behaviour into info documentation(#610559) Patch107: coreutils-8.4-mkdir-modenote.patch -#add support for dtr/dsr to stty -Patch108: coreutils-445213-stty-dtrdsr.patch # sh-utils #add info about TZ envvar to date manpage @@ -132,8 +128,6 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .ppcfactor -%patch2 -p1 -b .duplic -%patch3 -p1 -b .newline # Our patches %patch100 -p1 -b .configure @@ -142,7 +136,6 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect %patch107 -p1 -b .mkdirmode -%patch108 -p1 -b .dtrdsr # sh-utils %patch703 -p1 -b .dateman @@ -339,6 +332,7 @@ fi %{_bindir}/nl %{_bindir}/nohup %{_bindir}/nproc +%{_bindir}/numfmt %{_bindir}/od %{_bindir}/paste %{_bindir}/pathchk @@ -384,6 +378,9 @@ fi %{_sbindir}/chroot %changelog +* Fri Feb 15 2013 Ondrej Vasik 8.21-1 +- new upstream release 8.21, update patches + * Thu Feb 07 2013 Ondrej Oprala 8.20-8 - add missing sort-mb-tests.sh to local.mk diff --git a/sources b/sources index 2abca86..ae40427 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -3d69af8f561fce512538a9fe85f147ff coreutils-8.20.tar.xz +065ba41828644eca5dd8163446de5d64 coreutils-8.21.tar.xz From c7f6c7b9f6869ab8c8d88ee547e8df8c0506a0a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 18 Feb 2013 08:45:11 +0100 Subject: [PATCH 195/523] remove unnecessary powerpc factor patch --- coreutils-8.20-powerpcfactor.patch | 12 ------------ coreutils.spec | 7 ++++--- 2 files changed, 4 insertions(+), 15 deletions(-) delete mode 100644 coreutils-8.20-powerpcfactor.patch diff --git a/coreutils-8.20-powerpcfactor.patch b/coreutils-8.20-powerpcfactor.patch deleted file mode 100644 index 648d21a..0000000 --- a/coreutils-8.20-powerpcfactor.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -urNp coreutils-8.20-orig/src/longlong.h coreutils-8.20/src/longlong.h ---- coreutils-8.20-orig/src/longlong.h 2012-10-23 16:14:12.000000000 +0200 -+++ coreutils-8.20/src/longlong.h 2012-12-06 17:09:12.865695463 +0100 -@@ -1392,7 +1392,7 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype - - /* We should test _IBMR2 here when we add assembly support for the system - vendor compilers. */ --#if HAVE_HOST_CPU_FAMILY_powerpc && W_TYPE_SIZE == 64 -+#if HAVE_HOST_CPU_FAMILY_powerpc && W_TYPE_SIZE == 64 && defined (_LP64) - #if !defined (_LONG_LONG_LIMB) - /* _LONG_LONG_LIMB is ABI=mode32 where adde operates on 32-bit values. So - use adde etc only when not _LONG_LONG_LIMB. */ diff --git a/coreutils.spec b/coreutils.spec index 90c31e5..0c3ceda 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -14,7 +14,6 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream -Patch1: coreutils-8.20-powerpcfactor.patch # Our patches #general patch to workaround koji build system issues @@ -127,7 +126,6 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream -%patch1 -p1 -b .ppcfactor # Our patches %patch100 -p1 -b .configure @@ -378,6 +376,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Feb 18 2013 Ondrej Vasik 8.21-2 +- remove unnecessary powerpc factor patch + * Fri Feb 15 2013 Ondrej Vasik 8.21-1 - new upstream release 8.21, update patches From 970e32111e3b7351ba0282497192ad2d8b34fb96 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sat, 16 Feb 2013 21:13:13 +0100 Subject: [PATCH 196/523] fix coreutils-i18n.patch to terminate mbdelim string (#911929) Signed-off-by: Mark Wielaard --- coreutils-i18n.patch | 3 ++- coreutils.spec | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 5bc56d1..5932f29 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -498,7 +498,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -808,10 +1150,35 @@ main (int argc, char **argv) +@@ -808,10 +1150,36 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -523,6 +523,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') + FATAL_ERROR (_("the delimiter must be a single character")); + memcpy (mbdelim, optarg, delimlen); ++ mbdelim[delimlen] = '\0'; + } + } + diff --git a/coreutils.spec b/coreutils.spec index 0c3ceda..11b9822 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -376,6 +376,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Feb 18 2013 Mark Wielaard 8.21-3 +- fix coreutils-i18n.patch to terminate mbdelim string (#911929) + * Mon Feb 18 2013 Ondrej Vasik 8.21-2 - remove unnecessary powerpc factor patch From 1812652505ff8a4dace4af7e007cc7b8a9659828 Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Mon, 18 Feb 2013 16:59:45 +0100 Subject: [PATCH 197/523] fix sort-mb-tests.sh test (B.Voelker) --- coreutils-i18n.patch | 98 ++++++++++++++++++-------------------------- coreutils.spec | 5 ++- 2 files changed, 44 insertions(+), 59 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 5932f29..1873ee5 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4119,68 +4119,50 @@ diff -urNp coreutils-8.21-orig/tests/misc/mb2.X coreutils-8.21/tests/misc/mb2.X +Banana@AA5@@30 diff -urNp coreutils-8.21-orig/tests/misc/sort-mb-tests.sh coreutils-8.21/tests/misc/sort-mb-tests.sh --- coreutils-8.21-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.21/tests/misc/sort-mb-tests.sh 2013-02-15 14:25:08.020467562 +0100 -@@ -0,0 +1,63 @@ -+#! /bin/sh ++++ coreutils-8.21/tests/misc/sort-mb-tests.sh 2013-02-18 17:44:03.852275681 +0100 +@@ -0,0 +1,45 @@ ++#!/bin/sh ++# Verify sort's multi-byte support. + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+ -+expensive_ -+ -+case $# in -+ 0) xx='../src/sort';; -+ *) xx="$1";; -+esac -+test "$VERBOSE" && echo=echo || echo=: -+$echo testing program: $xx -+errors=0 -+test "$srcdir" || srcdir=. -+test "$VERBOSE" && $xx --version 2> /dev/null ++print_ver_ sort + +export LC_ALL=en_US.UTF-8 -+locale -k LC_CTYPE 2>&1 | grep -q charmap.*UTF-8 || exit 77 -+errors=0 ++locale -k LC_CTYPE | grep -q "charmap.*UTF-8" \ ++ || skip_ "No UTF-8 locale available" + -+$xx -t @ -k2 -n misc/mb1.I > misc/mb1.O -+code=$? -+if test $code != 0; then -+ $echo "Test mb1 failed: $xx return code $code differs from expected value 0" -+ errors=`expr $errors + 1` -+else -+ cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1 -+ case $? in -+ 0) if test "$VERBOSE"; then $echo "passed mb1"; fi;; -+ 1) $echo "Test mb1 failed: files misc/mb1.O and $srcdir/misc/mb1.X differ" 1>&2 -+ (diff -c misc/mb1.O $srcdir/misc/mb1.X) 2> /dev/null -+ errors=`expr $errors + 1`;; -+ 2) $echo "Test mb1 may have failed." 1>&2 -+ $echo The command "cmp misc/mb1.O $srcdir/misc/mb1.X" failed. 1>&2 -+ errors=`expr $errors + 1`;; -+ esac -+fi + -+$xx -t @ -k4 -n misc/mb2.I > misc/mb2.O -+code=$? -+if test $code != 0; then -+ $echo "Test mb2 failed: $xx return code $code differs from expected value 0" 1>&2 -+ errors=`expr $errors + 1` -+else -+ cmp misc/mb2.O $srcdir/misc/mb2.X > /dev/null 2>&1 -+ case $? in -+ 0) if test "$VERBOSE"; then $echo "passed mb2"; fi;; -+ 1) $echo "Test mb2 failed: files misc/mb2.O and $srcdir/misc/mb2.X differ" 1>&2 -+ (diff -c misc/mb2.O $srcdir/misc/mb2.X) 2> /dev/null -+ errors=`expr $errors + 1`;; -+ 2) $echo "Test mb2 may have failed." 1>&2 -+ $echo The command "cmp misc/mb2.O $srcdir/misc/mb2.X" failed. 1>&2 -+ errors=`expr $errors + 1`;; -+ esac -+fi ++cat < exp ++Banana@5 ++Apple@10 ++Citrus@20 ++Cherry@30 ++EOF + -+if test $errors = 0; then -+ $echo Passed all 113 tests. 1>&2 -+else -+ $echo Failed $errors tests. 1>&2 -+fi -+test $errors = 0 || errors=1 -+exit $errors ++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 diff --git a/coreutils.spec b/coreutils.spec index 11b9822..4773e45 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -376,6 +376,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Feb 18 2013 Ondrej Oprala 8.21-4 +- fix sort-mb-tests.sh test (B.Voelker) + * Mon Feb 18 2013 Mark Wielaard 8.21-3 - fix coreutils-i18n.patch to terminate mbdelim string (#911929) From 1801957473afd6bac6acaabbb823b12cea8ef1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 20 Feb 2013 16:33:47 +0100 Subject: [PATCH 198/523] fix multibyte issue in unexpand(by R.Kollar, #821262) --- coreutils-i18n.patch | 6 ++++-- coreutils.spec | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 5932f29..430a22c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -3401,7 +3401,7 @@ diff -urNp coreutils-8.21-orig/src/unexpand.c coreutils-8.21/src/unexpand.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "unexpand" -@@ -103,6 +120,208 @@ static struct option const longopts[] = +@@ -103,6 +120,210 @@ static struct option const longopts[] = {NULL, 0, NULL, 0} }; @@ -3421,6 +3421,7 @@ diff -urNp coreutils-8.21-orig/src/unexpand.c coreutils-8.21/src/unexpand.c + wint_t wc; /* A gotten wide character. */ + size_t mblength; /* The byte size of a multibyte character + which shows as same character as WC. */ ++ bool prev_tab = false; + + /* Index in `tab_list' of next tabstop: */ + int tab_index = 0; /* For calculating width of pending tabs. */ @@ -3499,7 +3500,7 @@ diff -urNp coreutils-8.21-orig/src/unexpand.c coreutils-8.21/src/unexpand.c +flush_pend_mb: + /* Flush pending spaces. Print as many tabs as possible, + then print the rest as spaces. */ -+ if (pending == 1) ++ if (pending == 1 && column != 1 && !prev_tab) + { + putchar (' '); + pending = 0; @@ -3600,6 +3601,7 @@ diff -urNp coreutils-8.21-orig/src/unexpand.c coreutils-8.21/src/unexpand.c + fwrite (bufpos, sizeof(char), mblength, stdout); + } + } ++ prev_tab = wc == L'\t'; + buflen -= mblength; + bufpos += mblength; + } diff --git a/coreutils.spec b/coreutils.spec index 11b9822..2de4feb 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -376,6 +376,9 @@ fi %{_sbindir}/chroot %changelog +* Wed Feb 20 2013 Ondrej Vasik 8.21-4 +- fix multibyte issue in unexpand(by R.Kollar, #821262) + * Mon Feb 18 2013 Mark Wielaard 8.21-3 - fix coreutils-i18n.patch to terminate mbdelim string (#911929) From bad02099bd8031df1b2b9a628db780efaf6cb7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 23 Feb 2013 12:03:18 +0100 Subject: [PATCH 199/523] install: do proper cleanup when strip fails (O.Oprala, B.Voekler, #632444) --- coreutils-8.21-install-strip.patch | 81 ++++++++++++++++++++++++++++++ coreutils.spec | 10 +++- 2 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 coreutils-8.21-install-strip.patch diff --git a/coreutils-8.21-install-strip.patch b/coreutils-8.21-install-strip.patch new file mode 100644 index 0000000..1d6f198 --- /dev/null +++ b/coreutils-8.21-install-strip.patch @@ -0,0 +1,81 @@ +From 3a20f6888575be7059e9acac07d397009e98c213 Mon Sep 17 00:00:00 2001 +From: Ondrej Oprala +Date: Fri, 22 Feb 2013 12:48:57 +0000 +Subject: install: cleanup properly if the strip program failed for any reason + +* src/install.c (strip): Indicate failure with a return code instead +of terminating the program. +(install_file_in_file): Handle strip's return code and unlink the +created file if necessary. +* tests/install/strip-program.sh: Add a test to cover the changes. +--- +diff --git a/src/install.c b/src/install.c +index 94374df..a5ed7a8 100644 +--- a/src/install.c ++++ b/src/install.c +@@ -515,16 +515,17 @@ change_timestamps (struct stat const *src_sb, char const *dest) + magic numbers vary so much from system to system that making + it portable would be very difficult. Not worth the effort. */ + +-static void ++static bool + strip (char const *name) + { + int status; ++ bool ok = false; + pid_t pid = fork (); + + switch (pid) + { + case -1: +- error (EXIT_FAILURE, errno, _("fork system call failed")); ++ error (0, errno, _("fork system call failed")); + break; + case 0: /* Child. */ + execlp (strip_program, strip_program, name, NULL); +@@ -532,11 +533,14 @@ strip (char const *name) + break; + default: /* Parent. */ + if (waitpid (pid, &status, 0) < 0) +- error (EXIT_FAILURE, errno, _("waiting for strip")); ++ error (0, errno, _("waiting for strip")); + else if (! WIFEXITED (status) || WEXITSTATUS (status)) +- error (EXIT_FAILURE, 0, _("strip process terminated abnormally")); ++ error (0, 0, _("strip process terminated abnormally")); ++ else ++ ok = true; /* strip succeeded */ + break; + } ++ return ok; + } + + /* Initialize the user and group ownership of the files to install. */ +@@ -681,7 +685,12 @@ install_file_in_file (const char *from, const char *to, + if (! copy_file (from, to, x)) + return false; + if (strip_files) +- strip (to); ++ if (! strip (to)) ++ { ++ if (unlink (to) != 0) /* Cleanup. */ ++ error (EXIT_FAILURE, errno, _("cannot unlink %s"), to); ++ return false; ++ } + if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode)) + && ! change_timestamps (&from_sb, to)) + return false; +diff --git a/tests/install/strip-program.sh b/tests/install/strip-program.sh +index 8950d50..5d65373 100755 +--- a/tests/install/strip-program.sh ++++ b/tests/install/strip-program.sh +@@ -33,4 +33,8 @@ echo aBc > exp || fail=1 + ginstall src dest -s --strip-program=./b || fail=1 + compare exp dest || fail=1 + ++# Check that install cleans up properly if strip fails. ++ginstall src dest2 -s --strip-program=./FOO && fail=1 ++test -e dest2 && fail=1 ++ + Exit $fail +-- +cgit v0.9.0.2 diff --git a/coreutils.spec b/coreutils.spec index 01ffdfe..c81e636 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -14,6 +14,7 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream +Patch1: coreutils-8.21-install-strip.patch # Our patches #general patch to workaround koji build system issues @@ -126,6 +127,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream +%patch1 -p1 -b .strip # Our patches %patch100 -p1 -b .configure @@ -376,7 +378,11 @@ fi %{_sbindir}/chroot %changelog -* Wed Feb 20 2013 Ondrej Vasik 8.21-4 +* Sat Feb 23 2013 Ondrej Vasik 8.21-6 +- install: do proper cleanup when strip fails + (O.Oprala, B.Voekler, #632444) + +* Wed Feb 20 2013 Ondrej Vasik 8.21-5 - fix multibyte issue in unexpand(by R.Kollar, #821262) * Mon Feb 18 2013 Ondrej Oprala 8.21-4 From 9c597e43346deb3b84644d05b6fc954b14e9fcfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 1 Mar 2013 12:11:05 +0100 Subject: [PATCH 200/523] Colorize several new archive types (#868510) --- coreutils-DIR_COLORS | 13 +++++++++++-- coreutils-DIR_COLORS.256color | 13 +++++++++++-- coreutils-DIR_COLORS.lightbgcolor | 14 ++++++++++++-- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 5683e39..304463a 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -113,26 +113,33 @@ EXEC 01;32 #.bat 01;32 #.sh 01;32 #.csh 01;32 - # archives or compressed (bright red) + +# archives or compressed (bright red) .tar 01;31 .tgz 01;31 +.arc 01;31 .arj 01;31 .taz 01;31 +.lha 01;31 .lzh 01;31 .lzma 01;31 .tlz 01;31 .txz 01;31 +.tzo 01;31 +.t7z 01;31 .zip 01;31 .z 01;31 .Z 01;31 .dz 01;31 .gz 01;31 +.lrz 01;31 .lz 01;31 +.lzo 01;31 .xz 01;31 .bz2 01;31 +.bz 01;31 .tbz 01;31 .tbz2 01;31 -.bz 01;31 .tz 01;31 .deb 01;31 .rpm 01;31 @@ -141,11 +148,13 @@ EXEC 01;32 .ear 01;31 .sar 01;31 .rar 01;31 +.alz 01;31 .ace 01;31 .zoo 01;31 .cpio 01;31 .7z 01;31 .rz 01;31 +.cab 01;31 # image formats (magenta) .jpg 01;35 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 14e27d4..2d2a530 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -86,26 +86,33 @@ EXEC 38;5;34 #.bat 38;5;34 #.sh 38;5;34 #.csh 38;5;34 - # archives or compressed (bright red) + +# archives or compressed (bright red) .tar 38;5;9 .tgz 38;5;9 +.arc 38;5;9 .arj 38;5;9 .taz 38;5;9 +.lha 38;5;9 .lzh 38;5;9 .lzma 38;5;9 .tlz 38;5;9 .txz 38;5;9 +.tzo 38;5;9 +.t7z 38;5;9 .zip 38;5;9 .z 38;5;9 .Z 38;5;9 .dz 38;5;9 .gz 38;5;9 +.lrz 38;5;9 .lz 38;5;9 +.lzo 38;5;9 .xz 38;5;9 .bz2 38;5;9 +.bz 38;5;9 .tbz 38;5;9 .tbz2 38;5;9 -.bz 38;5;9 .tz 38;5;9 .deb 38;5;9 .rpm 38;5;9 @@ -114,11 +121,13 @@ EXEC 38;5;34 .ear 38;5;9 .sar 38;5;9 .rar 38;5;9 +.alz 38;5;9 .ace 38;5;9 .zoo 38;5;9 .cpio 38;5;9 .7z 38;5;9 .rz 38;5;9 +.cab 38;5;9 # image formats (magenta) .jpg 38;5;13 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index ac46288..efb5163 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -90,26 +90,33 @@ EXEC 00;32 #.bat 00;32 #.sh 00;32 #.csh 00;32 - # archives or compressed (red) + +# archives or compressed (red) .tar 00;31 .tgz 00;31 +.arc 00;31 .arj 00;31 .taz 00;31 +.lha 00;31 .lzh 00;31 .lzma 00;31 .tlz 00;31 .txz 00;31 +.tzo 00;31 +.t7z 00;31 .zip 00;31 .z 00;31 .Z 00;31 .dz 00;31 .gz 00;31 +.lrz 00;31 .lz 00;31 +.lzo 00;31 .xz 00;31 .bz2 00;31 +.bz 00;31 .tbz 00;31 .tbz2 00;31 -.bz 00;31 .tz 00;31 .deb 00;31 .rpm 00;31 @@ -118,11 +125,14 @@ EXEC 00;32 .ear 00;31 .sar 00;31 .rar 00;31 +.alz 00;31 .ace 00;31 .zoo 00;31 .cpio 00;31 .7z 00;31 .rz 00;31 +.cab 00;31 + # image formats (magenta) .jpg 00;35 .jpeg 00;35 From c3f2f52e7450fad668fc97d00071c258f4272068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 1 Mar 2013 12:14:16 +0100 Subject: [PATCH 201/523] spec file entry for new archive types colorization --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index c81e636..46b0463 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -378,6 +378,9 @@ fi %{_sbindir}/chroot %changelog +* Fri Mar 01 2013 Ondrej Vasik 8.21-7 +- ls: colorize several new archive/compressed types (#868510) + * Sat Feb 23 2013 Ondrej Vasik 8.21-6 - install: do proper cleanup when strip fails (O.Oprala, B.Voekler, #632444) From 76ade64f4b56d18ae40b598d531f45e7f4194137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 4 Mar 2013 18:23:34 +0100 Subject: [PATCH 202/523] fix factor on AArch64 (M.Salter, #917735) --- coreutils-aarch64-longlong.patch | 35 ++++++++++++++++++++++++++++++++ coreutils.spec | 12 +++++------ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 coreutils-aarch64-longlong.patch diff --git a/coreutils-aarch64-longlong.patch b/coreutils-aarch64-longlong.patch new file mode 100644 index 0000000..323759b --- /dev/null +++ b/coreutils-aarch64-longlong.patch @@ -0,0 +1,35 @@ +diff --git a/src/longlong.h b/src/longlong.h +index e880587..023f47e 100644 +--- a/src/longlong.h ++++ b/src/longlong.h +@@ -530,23 +530,16 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype); + #endif /* __arm__ */ + + #if defined (__aarch64__) && W_TYPE_SIZE == 64 ++/* FIXME: Extend the immediate range for the low word by using both ++ ADDS and SUBS, since they set carry in the same way. */ + #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +- __asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \ ++ __asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \ + : "=r" (sh), "=&r" (sl) \ +- : "r" (ah), "rZ" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC) ++ : "rZ" (ah), "rZ" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC) + #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +- do { \ +- if (__builtin_constant_p (bl)) \ +- { \ +- __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ +- : "=r" (sh), "=&r" (sl) \ +- : "r" (ah), "r" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \ +- } \ +- else /* only bh might be a constant */ \ +- __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ +- : "=r" (sh), "=&r" (sl) \ +- : "r" (ah), "rZ" (bh), "r" (al), "rI" (bl) __CLOBBER_CC);\ +- } while (0) ++ __asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \ ++ : "=r,r" (sh), "=&r,&r" (sl) \ ++ : "rZ,rZ" (ah), "rZ,rZ" (bh), "r,Z" (al), "rI,r" (bl) __CLOBBER_CC) + #define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ diff --git a/coreutils.spec b/coreutils.spec index 46b0463..4dd7094 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,11 +1,10 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor @@ -15,6 +14,7 @@ Source106: coreutils-colorls.csh # From upstream Patch1: coreutils-8.21-install-strip.patch +Patch2: coreutils-aarch64-longlong.patch # Our patches #general patch to workaround koji build system issues @@ -128,6 +128,7 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .strip +%patch2 -p1 -b .aarch64 # Our patches %patch100 -p1 -b .configure @@ -186,7 +187,6 @@ sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutil make check %install -rm -rf $RPM_BUILD_ROOT make DESTDIR=$RPM_BUILD_ROOT install # man pages are not installed with make install @@ -237,9 +237,6 @@ find %{buildroot}%{_datadir}/locale -type l | \ # (sb) Deal with Installed (but unpackaged) file(s) found rm -f $RPM_BUILD_ROOT%{_infodir}/dir -%clean -rm -rf $RPM_BUILD_ROOT - %pre # We must deinstall these info files since they're merged in # coreutils.info. else their postun'll be run too late @@ -378,6 +375,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Mar 04 2013 Ondrej Vasik 8.21-8 +- fix factor on AArch64 (M.Salter, #917735) + * Fri Mar 01 2013 Ondrej Vasik 8.21-7 - ls: colorize several new archive/compressed types (#868510) From 1ad51b627678396cd3fd54db60762cecd5aaa89f Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Mon, 11 Mar 2013 16:00:59 +0100 Subject: [PATCH 203/523] add support for INCLUDE in colorls scripts (#818069) --- coreutils-colorls.csh | 9 ++++++++- coreutils-colorls.sh | 12 ++++++++++-- coreutils.spec | 5 ++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index e244afb..3243484 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -10,6 +10,8 @@ endif alias ll 'ls -l' alias l. 'ls -d .*' set COLORS=/etc/DIR_COLORS +set TMP="`mktemp .colorlsXXX`" + if ($?TERM) then if ( -e "/etc/DIR_COLORS.$TERM" ) then set COLORS="/etc/DIR_COLORS.$TERM" @@ -26,10 +28,14 @@ if ($?TERM) then if ( -f ~/.dircolors."$TERM" ) set COLORS=~/.dircolors."$TERM" if ( -f ~/.dir_colors."$TERM" ) set COLORS=~/.dir_colors."$TERM" endif +set INCLUDE="`cat "$COLORS" | grep '^INCLUDE' | cut -d ' ' -f2-`" if ( ! -e "$COLORS" ) exit -eval "`dircolors -c $COLORS`" +if ( "$INCLUDE" != '' ) cat "$INCLUDE" > $TMP +cat "$COLORS" | grep -v '^INCLUDE' >> $TMP + +eval "`dircolors -c $TMP`" if ( "$LS_COLORS" == '' ) exit set color_none=`sed -n '/^COLOR.*none/Ip' < $COLORS` @@ -38,6 +44,7 @@ if ( "$color_none" != '' ) then exit endif unset color_none +rm -f $TMP finish: alias ll 'ls -l --color=auto' diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index dc5c223..adb3574 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -10,11 +10,15 @@ if [ -z "$USER_LS_COLORS" ]; then # Skip the rest for noninteractive shells. [ -z "$PS1" ] && return + INCLUDE= COLORS= + TMP="`mktemp .colorlsXXX`" for colors in "$HOME/.dir_colors.$TERM" "$HOME/.dircolors.$TERM" \ "$HOME/.dir_colors" "$HOME/.dircolors"; do - [ -e "$colors" ] && COLORS="$colors" && break + [ -e "$colors" ] && COLORS="$colors" && \ + INCLUDE="`cat "$COLORS" | grep '^INCLUDE' | cut -d ' ' -f2-`" && \ + break done [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \ @@ -30,9 +34,13 @@ if [ -z "$USER_LS_COLORS" ]; then # Existence of $COLORS already checked above. [ -n "$COLORS" ] || return - eval "`dircolors --sh "$COLORS" 2>/dev/null`" + [ -e "$INCLUDE" ] && cat "$INCLUDE" > $TMP + cat "$COLORS" | grep -v '^INCLUDE' >> $TMP + + eval "`dircolors --sh $TMP 2>/dev/null`" [ -z "$LS_COLORS" ] && return grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return + rm -f $TMP fi alias ll='ls -l --color=auto' 2>/dev/null diff --git a/coreutils.spec b/coreutils.spec index 4dd7094..7d8f09b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -375,6 +375,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Mar 11 2013 Ondrej Oprala 8.21-9 +- add support for INCLUDE in colorls scripts (#818069) + * Mon Mar 04 2013 Ondrej Vasik 8.21-8 - fix factor on AArch64 (M.Salter, #917735) From c7a1b74c04c2ce8da16d4e4f8192c2016e72bf91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 14 Mar 2013 16:50:09 +0100 Subject: [PATCH 204/523] DIR_COLORS.xterm should have higher priority than DIR_COLORS.256color (#921651) --- coreutils-colorls.csh | 6 +++--- coreutils-colorls.sh | 16 ++++++++-------- coreutils.spec | 6 +++++- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 3243484..8c5b993 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -13,14 +13,14 @@ set COLORS=/etc/DIR_COLORS set TMP="`mktemp .colorlsXXX`" if ($?TERM) then - if ( -e "/etc/DIR_COLORS.$TERM" ) then - set COLORS="/etc/DIR_COLORS.$TERM" - endif if ( -e "/etc/DIR_COLORS.256color" ) then if ( "`tput colors`" == "256" ) then set COLORS=/etc/DIR_COLORS.256color endif endif + if ( -e "/etc/DIR_COLORS.$TERM" ) then + set COLORS="/etc/DIR_COLORS.$TERM" + endif endif if ( -f ~/.dircolors ) set COLORS=~/.dircolors if ( -f ~/.dir_colors ) set COLORS=~/.dir_colors diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index adb3574..f354698 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -21,15 +21,15 @@ if [ -z "$USER_LS_COLORS" ]; then break done - [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \ - [ "x`tty -s && tput colors 2>/dev/null`" = "x256" ] && \ - COLORS="/etc/DIR_COLORS.256color" + [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.$TERM" ] && \ + COLORS="/etc/DIR_COLORS.$TERM" - if [ -z "$COLORS" ]; then - for colors in "/etc/DIR_COLORS.$TERM" "/etc/DIR_COLORS" ; do - [ -e "$colors" ] && COLORS="$colors" && break - done - fi + [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \ + [ "x`tty -s && tput colors 2>/dev/null`" = "x256" ] && \ + COLORS="/etc/DIR_COLORS.256color" + + [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS" ] && \ + COLORS="/etc/DIR_COLORS" # Existence of $COLORS already checked above. [ -n "$COLORS" ] || return diff --git a/coreutils.spec b/coreutils.spec index 7d8f09b..a62ccab 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -375,6 +375,10 @@ fi %{_sbindir}/chroot %changelog +* Thu Mar 14 2013 Ondrej Vasik 8.21-10 +- DIR_COLORS.$TERM should have higher priority than + DIR_COLORS.256color (#921651) + * Mon Mar 11 2013 Ondrej Oprala 8.21-9 - add support for INCLUDE in colorls scripts (#818069) From 7bbf86f2feee429d3b7a6d94569a7b9b0c2595f2 Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Fri, 5 Apr 2013 13:02:14 +0200 Subject: [PATCH 205/523] Fix tmp file location in colorls scripts (#948008) --- coreutils-colorls.csh | 2 +- coreutils-colorls.sh | 2 +- coreutils.spec | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 8c5b993..5a54e45 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -10,7 +10,7 @@ endif alias ll 'ls -l' alias l. 'ls -d .*' set COLORS=/etc/DIR_COLORS -set TMP="`mktemp .colorlsXXX`" +set TMP="`mktemp .colorlsXXX --tmpdir=/tmp`" if ($?TERM) then if ( -e "/etc/DIR_COLORS.256color" ) then diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index f354698..5347b2a 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -12,7 +12,7 @@ if [ -z "$USER_LS_COLORS" ]; then INCLUDE= COLORS= - TMP="`mktemp .colorlsXXX`" + TMP="`mktemp .colorlsXXX --tmpdir=/tmp`" for colors in "$HOME/.dir_colors.$TERM" "$HOME/.dircolors.$TERM" \ "$HOME/.dir_colors" "$HOME/.dircolors"; do diff --git a/coreutils.spec b/coreutils.spec index a62ccab..48b39f5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -375,6 +375,9 @@ fi %{_sbindir}/chroot %changelog +* Fri Apr 05 2013 Ondrej Oprala 8.21-10 - DIR_COLORS.$TERM should have higher priority than DIR_COLORS.256color (#921651) From f0b6f85aff0496c51c8fcb58197a8a132949a4e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Wed, 8 May 2013 17:25:06 +0200 Subject: [PATCH 206/523] colorls profile script tmp file handling improvements --- coreutils-colorls.csh | 8 +++++--- coreutils-colorls.sh | 9 ++++++--- coreutils.spec | 5 ++++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 5a54e45..fbe97b7 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -10,7 +10,6 @@ endif alias ll 'ls -l' alias l. 'ls -d .*' set COLORS=/etc/DIR_COLORS -set TMP="`mktemp .colorlsXXX --tmpdir=/tmp`" if ($?TERM) then if ( -e "/etc/DIR_COLORS.256color" ) then @@ -32,11 +31,15 @@ set INCLUDE="`cat "$COLORS" | grep '^INCLUDE' | cut -d ' ' -f2-`" if ( ! -e "$COLORS" ) exit +set TMP="`mktemp .colorlsXXX --tmpdir=/tmp`" + if ( "$INCLUDE" != '' ) cat "$INCLUDE" > $TMP -cat "$COLORS" | grep -v '^INCLUDE' >> $TMP +grep -v '^INCLUDE' "$COLORS" >> $TMP eval "`dircolors -c $TMP`" +rm -f $TMP + if ( "$LS_COLORS" == '' ) exit set color_none=`sed -n '/^COLOR.*none/Ip' < $COLORS` if ( "$color_none" != '' ) then @@ -44,7 +47,6 @@ if ( "$color_none" != '' ) then exit endif unset color_none -rm -f $TMP finish: alias ll 'ls -l --color=auto' diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index 5347b2a..7d27940 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -12,7 +12,6 @@ if [ -z "$USER_LS_COLORS" ]; then INCLUDE= COLORS= - TMP="`mktemp .colorlsXXX --tmpdir=/tmp`" for colors in "$HOME/.dir_colors.$TERM" "$HOME/.dircolors.$TERM" \ "$HOME/.dir_colors" "$HOME/.dircolors"; do @@ -34,13 +33,17 @@ if [ -z "$USER_LS_COLORS" ]; then # Existence of $COLORS already checked above. [ -n "$COLORS" ] || return + TMP="`mktemp .colorlsXXX --tmpdir=/tmp`" + [ -e "$INCLUDE" ] && cat "$INCLUDE" > $TMP - cat "$COLORS" | grep -v '^INCLUDE' >> $TMP + grep -v '^INCLUDE' "$COLORS" >> $TMP eval "`dircolors --sh $TMP 2>/dev/null`" + + rm -f $TMP + [ -z "$LS_COLORS" ] && return grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return - rm -f $TMP fi alias ll='ls -l --color=auto' 2>/dev/null diff --git a/coreutils.spec b/coreutils.spec index 48b39f5..ffb5dd6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -375,6 +375,9 @@ fi %{_sbindir}/chroot %changelog +* Wed May 08 2013 Ondrej Vasik Date: Fri, 17 May 2013 09:21:51 +0200 Subject: [PATCH 207/523] require glibc-devel to prevent broken links in coreutils info manual (#959697) --- coreutils.spec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index ffb5dd6..332b3bb 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -101,6 +101,8 @@ Requires(post): /sbin/install-info Requires(post): grep Requires: ncurses Requires: gmp +#to prevent broken links in coreutils info manual (#959697), info doc is there +Requires: glibc-devel Provides: fileutils = %{version}-%{release} Provides: sh-utils = %{version}-%{release} @@ -375,6 +377,10 @@ fi %{_sbindir}/chroot %changelog +* Fri May 17 2013 Ondrej Vasik Date: Fri, 17 May 2013 09:50:40 +0200 Subject: [PATCH 208/523] fix typo --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 332b3bb..eca656f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -379,7 +379,7 @@ fi %changelog * Fri May 17 2013 Ondrej Vasik Date: Fri, 17 May 2013 10:09:13 +0200 Subject: [PATCH 209/523] argh, fridays --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index eca656f..ddb5baf 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -101,7 +101,7 @@ Requires(post): /sbin/install-info Requires(post): grep Requires: ncurses Requires: gmp -#to prevent broken links in coreutils info manual (#959697), info doc is there +#to prevent broken links in coreutils info manual (#959597), info doc is there Requires: glibc-devel Provides: fileutils = %{version}-%{release} From 1ad7b8db0fe10b3e7af1450dfe8a2a9a3a73f869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 17 May 2013 13:16:16 +0200 Subject: [PATCH 210/523] revert the last change --- coreutils.spec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index ddb5baf..c894c9a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 13%{?dist} +Release: 14%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -101,8 +101,6 @@ Requires(post): /sbin/install-info Requires(post): grep Requires: ncurses Requires: gmp -#to prevent broken links in coreutils info manual (#959597), info doc is there -Requires: glibc-devel Provides: fileutils = %{version}-%{release} Provides: sh-utils = %{version}-%{release} @@ -377,6 +375,9 @@ fi %{_sbindir}/chroot %changelog +* Fri May 17 2013 Ondrej Vasik Date: Wed, 17 Jul 2013 14:30:46 +0200 Subject: [PATCH 211/523] change the TMP variable name in colorls.csh to _tmp (#981373) --- coreutils-colorls.csh | 11 ++++++----- coreutils.spec | 5 ++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index fbe97b7..d02fe85 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -31,14 +31,14 @@ set INCLUDE="`cat "$COLORS" | grep '^INCLUDE' | cut -d ' ' -f2-`" if ( ! -e "$COLORS" ) exit -set TMP="`mktemp .colorlsXXX --tmpdir=/tmp`" +set _tmp="`mktemp .colorlsXXX --tmpdir=/tmp`" -if ( "$INCLUDE" != '' ) cat "$INCLUDE" > $TMP -grep -v '^INCLUDE' "$COLORS" >> $TMP +if ( "$INCLUDE" != '' ) cat "$INCLUDE" > $_tmp +grep -v '^INCLUDE' "$COLORS" >> $_tmp -eval "`dircolors -c $TMP`" +eval "`dircolors -c $_tmp`" -rm -f $TMP +rm -f $_tmp if ( "$LS_COLORS" == '' ) exit set color_none=`sed -n '/^COLOR.*none/Ip' < $COLORS` @@ -47,6 +47,7 @@ if ( "$color_none" != '' ) then exit endif unset color_none +unset _tmp finish: alias ll 'ls -l --color=auto' diff --git a/coreutils.spec b/coreutils.spec index c894c9a..a43745c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 14%{?dist} +Release: 15%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -375,6 +375,9 @@ fi %{_sbindir}/chroot %changelog +* Wed Jul 17 2013 Ondrej Oprala 8.21-15 +- change the TMP variable name in colorls.csh to _tmp (#981373) + * Fri May 17 2013 Ondrej Vasik Date: Sat, 3 Aug 2013 00:52:16 -0500 Subject: [PATCH 212/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index a43745c..621cfb6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 15%{?dist} +Release: 16%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -375,6 +375,9 @@ fi %{_sbindir}/chroot %changelog +* Sat Aug 03 2013 Fedora Release Engineering - 8.21-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + * Wed Jul 17 2013 Ondrej Oprala 8.21-15 - change the TMP variable name in colorls.csh to _tmp (#981373) From 0dcc5a0d5eb1554f4b5c0d2f2c8988b6b91e6553 Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Wed, 14 Aug 2013 19:01:16 +0200 Subject: [PATCH 213/523] sort: fix multibyte incompabilities (#821264) --- coreutils-i18n.patch | 223 ++++++++++++++++++++++++------------------- coreutils.spec | 5 +- 2 files changed, 128 insertions(+), 100 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 0e25f49..da46a71 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2419,8 +2419,8 @@ diff -urNp coreutils-8.21-orig/src/pr.c coreutils-8.21/src/pr.c looking for more options and printing the next batch of files. diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c ---- coreutils-8.21-orig/src/sort.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/sort.c 2013-02-15 14:25:07.828467769 +0100 +--- coreutils-8.21-orig/src/sort.c 2013-08-14 18:14:06.172216606 +0200 ++++ coreutils-8.21/src/sort.c 2013-08-14 18:13:30.295247905 +0200 @@ -29,6 +29,14 @@ #include #include @@ -2440,8 +2440,8 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c /* Nonzero if the corresponding locales are hard. */ static bool hard_LC_COLLATE; --#if HAVE_NL_LANGINFO +#if HAVE_LANGINFO_CODESET +-#if HAVE_NL_LANGINFO static bool hard_LC_TIME; #endif @@ -2476,16 +2476,16 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c they were read if all keys compare equal. */ static bool stable; ++/* Tab character separating fields. If tab_length is 0, then fields are -/* 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; +-static int tab = TAB_DEFAULT; /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ @@ -2540,8 +2540,8 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c free (node); } --#if HAVE_NL_LANGINFO +#if HAVE_LANGINFO_CODESET +-#if HAVE_NL_LANGINFO static int struct_month_cmp (void const *m1, void const *m2) @@ -2549,17 +2549,17 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c /* Initialize the character class tables. */ static void --inittables (void) +inittables_uni (void) +-inittables (void) { size_t i; -@@ -1250,7 +1318,7 @@ inittables (void) +@@ -1250,7 +1318,7 @@ inittables_uni (void) fold_toupper[i] = toupper (i); } --#if HAVE_NL_LANGINFO +#if HAVE_LANGINFO_CODESET +-#if HAVE_NL_LANGINFO /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { @@ -2652,25 +2652,25 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c 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) +-begfield (struct line const *line, struct keyfield const *key) { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1573,10 +1719,10 @@ begfield (struct line const *line, struc +@@ -1573,10 +1719,10 @@ begfield_uni (const struct line *line, c /* The leading field separator itself is included in a field when -t is absent. */ -- if (tab != TAB_DEFAULT) + if (tab_length) +- if (tab != TAB_DEFAULT) while (ptr < lim && sword--) { -- while (ptr < lim && *ptr != tab) + while (ptr < lim && *ptr != tab[0]) +- while (ptr < lim && *ptr != tab) ++ptr; if (ptr < lim) ++ptr; -@@ -1602,11 +1748,70 @@ begfield (struct line const *line, struc +@@ -1602,11 +1748,70 @@ begfield_uni (const struct line *line, c return ptr; } @@ -2737,38 +2737,38 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c 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) +-limfield (struct line const *line, struct keyfield const *key) { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1621,10 +1826,10 @@ limfield (struct line const *line, struc +@@ -1621,10 +1826,10 @@ limfield_uni (const struct line *line, c '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) +- if (tab != TAB_DEFAULT) while (ptr < lim && eword--) { -- while (ptr < lim && *ptr != tab) + while (ptr < lim && *ptr != tab[0]) +- while (ptr < lim && *ptr != tab) ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1670,10 +1875,10 @@ limfield (struct line const *line, struc +@@ -1670,10 +1875,10 @@ limfield_uni (const struct line *line, c */ /* Make LIM point to the end of (one byte past) the current field. */ -- if (tab != TAB_DEFAULT) + if (tab_length) +- if (tab != TAB_DEFAULT) { char *newlim; -- newlim = memchr (ptr, tab, lim - ptr); + newlim = memchr (ptr, tab[0], lim - ptr); +- newlim = memchr (ptr, tab, lim - ptr); if (newlim) lim = newlim; } -@@ -1704,6 +1909,130 @@ limfield (struct line const *line, struc +@@ -1704,6 +1909,130 @@ limfield_uni (const struct line *line, c return ptr; } @@ -2857,7 +2857,7 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c + { + /* If we're skipping leading blanks, don't start counting characters + * until after skipping past any leading blanks. */ -+ if (key->skipsblanks) ++ if (key->skipeblanks) + while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) + ptr += mblength; + @@ -2903,8 +2903,6 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c else { if (key->skipsblanks) -- while (blanks[to_uchar (*line_start)]) -- line_start++; + { +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) @@ -2921,6 +2919,8 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c + while (blanks[to_uchar (*line_start)]) + line_start++; + } +- while (blanks[to_uchar (*line_start)]) +- line_start++; line->keybeg = line_start; } } @@ -2928,12 +2928,12 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c hideously fast. */ static int --numcompare (char const *a, char const *b) +numcompare_uni (const char *a, const char *b) +-numcompare (char const *a, char const *b) { while (blanks[to_uchar (*a)]) a++; -@@ -1922,6 +2265,25 @@ numcompare (char const *a, char const *b +@@ -1922,6 +2265,25 @@ numcompare_uni (const char *a, const cha return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2963,8 +2963,8 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c 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) +-getmonth (char const *month, char **ea) { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; @@ -2972,17 +2972,17 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c char saved = *lim; *lim = '\0'; ++ skipblanks (&beg, lim); - 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); +- getmonth (beg, &tighter_lim); else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) @@ -2990,8 +2990,8 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ -- if (!gkey_only && tab == TAB_DEFAULT && !line_offset + if (!gkey_only && !tab_length && !line_offset +- if (!gkey_only && tab == TAB_DEFAULT && !line_offset && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) @@ -3079,21 +3079,21 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c 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) +-keycompare (struct line const *a, struct line const *b) { struct keyfield *key = keylist; -@@ -2546,7 +2983,7 @@ keycompare (struct line const *a, struct +@@ -2546,7 +2983,7 @@ keycompare_uni (const struct line *a, co 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); +- diff = getmonth (ta, NULL) - getmonth (tb, NULL); else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2662,6 +3099,181 @@ keycompare (struct line const *a, struct +@@ -2662,6 +3099,191 @@ keycompare_uni (const struct line *a, co return key->reverse ? -diff : diff; } @@ -3114,45 +3114,14 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c + wchar_t wc_a, wc_b; + mbstate_t state_a, state_b; + -+ int diff; ++ 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; + -+ for (;;) -+ { -+ char const *translate = key->translate; -+ bool const *ignore = key->ignore; -+ -+ /* Find the lengths. */ -+ size_t lena = lima <= texta ? 0 : lima - texta; -+ size_t lenb = limb <= textb ? 0 : limb - textb; -+ -+ /* Actually compare the fields. */ -+ 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 (ignore || translate) -+ { -+ char *copy_a = (char *) xmalloc (lena + 1 + lenb + 1); -+ char *copy_b = copy_a + lena + 1; -+ size_t new_len_a, new_len_b; -+ size_t i, j; + + /* Ignore and/or translate chars before comparing. */ +# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ @@ -3220,21 +3189,63 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c + COPY[NEW_LEN] = '\0'; \ + } \ + while (0) -+ 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); -+ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b); -+ free(copy_a); -+ } -+ else if (lena == 0) -+ diff = - NONZERO (lenb); -+ else if (lenb == 0) -+ goto greater; -+ else -+ diff = xmemcoll (texta, lena, textb, lenb); ++ ++ /* 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 const *translate = key->translate; ++ bool const *ignore = key->ignore; ++ ++ if (ignore || translate) ++ { ++ char *copy_a = (char *) xmalloc (lena + 1 + lenb + 1); ++ char *copy_b = copy_a + lena + 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; + } + ++ 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 ++ { ++ diff = memcmp (texta, textb, MIN (lena,lenb)); ++ if (!diff) ++ diff = xmemcoll (texta, lena, textb, lenb); ++ } ++ ++ if (ignore || translate) ++ free (texta); ++ + if (diff) + goto not_equal; + @@ -3263,28 +3274,42 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c + } + } + -+ return 0; -+ -+greater: -+ diff = 1; +not_equal: -+ return key->reverse ? -diff : diff; ++ 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. */ -@@ -4157,7 +4769,7 @@ main (int argc, char **argv) +@@ -2689,14 +3311,6 @@ compare (struct line const *a, struct li + diff = - NONZERO (blen); + else if (blen == 0) + diff = 1; +- else if (hard_LC_COLLATE) +- { +- /* Note xmemcoll0 is a performance enhancement as +- it will not unconditionally write '\0' after the +- passed in buffers, which was seen to give around +- a 3% increase in performance for short lines. */ +- diff = xmemcoll0 (a->text, alen + 1, b->text, blen + 1); +- } + else if (! (diff = memcmp (a->text, b->text, MIN (alen, blen)))) + diff = alen < blen ? -1 : alen != blen; + +@@ -4157,7 +4771,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 +-#if HAVE_NL_LANGINFO hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4178,6 +4790,29 @@ main (int argc, char **argv) +@@ -4178,6 +4792,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3314,18 +3339,17 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c have_read_stdin = false; inittables (); -@@ -4452,13 +5087,34 @@ main (int argc, char **argv) +@@ -4452,13 +5089,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]) +- char newtab = optarg[0]; +- if (! newtab) error (SORT_FAILURE, 0, _("empty tab")); -- if (optarg[1]) +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) + { @@ -3346,25 +3370,26 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c + } +#endif + if (newtab_length == 1 && optarg[1]) +- if (optarg[1]) { if (STREQ (optarg, "\\0")) -- newtab = '\0'; + newtab[0] = '\0'; +- newtab = '\0'; else { /* Provoke with 'sort -txx'. Complain about -@@ -4469,9 +5125,12 @@ main (int argc, char **argv) +@@ -4469,9 +5127,12 @@ 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)) +- if (tab != TAB_DEFAULT && tab != newtab) error (SORT_FAILURE, 0, _("incompatible tabs")); -- tab = newtab; + memcpy (tab, newtab, newtab_length); + tab_length = newtab_length; +- tab = newtab; } break; diff --git a/coreutils.spec b/coreutils.spec index 621cfb6..69ff506 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 16%{?dist} +Release: 17%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -375,6 +375,9 @@ fi %{_sbindir}/chroot %changelog +* Wed Aug 14 2013 Ondrej Oprala 8.21-17 +- Fix sort multibyte incompatibilities + * Sat Aug 03 2013 Fedora Release Engineering - 8.21-16 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild From 32c665193098d82bd8c6e85ce2b1f1332362e8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 15 Aug 2013 13:26:11 +0200 Subject: [PATCH 214/523] pr -e, with a mix of backspaces and TABs, could corrupt the heap in multibyte locales (analyzed by J.Koncicky) --- coreutils-i18n.patch | 14 ++++++++++++-- coreutils.spec | 6 +++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index da46a71..5f3be7c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2263,7 +2263,7 @@ diff -urNp coreutils-8.21-orig/src/pr.c coreutils-8.21/src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2724,6 +2930,154 @@ char_to_clump (char c) +@@ -2724,6 +2930,164 @@ char_to_clump (char c) return chars; } @@ -2410,7 +2410,17 @@ diff -urNp coreutils-8.21-orig/src/pr.c coreutils-8.21/src/pr.c + mbc_pos -= mblength; + } + -+ input_position += width; ++ /* 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 diff --git a/coreutils.spec b/coreutils.spec index 69ff506..bb9c1ee 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 17%{?dist} +Release: 18%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -375,6 +375,10 @@ fi %{_sbindir}/chroot %changelog +* Thu Aug 15 2013 Ondrej Vasik 8.21-18 +- pr -e, with a mix of backspaces and TABs, could corrupt the heap + in multibyte locales (analyzed by J.Koncicky) + * Wed Aug 14 2013 Ondrej Oprala 8.21-17 - Fix sort multibyte incompatibilities From 9b2b9416824f0c72dab7997212a33a504eb2e777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 14 Oct 2013 09:58:44 +0200 Subject: [PATCH 215/523] cp: correct error message for invalid arguments of '--no-preserve' (#1018206) --- coreutils-cp-nopreserve-invalidargs.patch | 29 +++++++++++++++++++++++ coreutils.spec | 8 ++++++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 coreutils-cp-nopreserve-invalidargs.patch diff --git a/coreutils-cp-nopreserve-invalidargs.patch b/coreutils-cp-nopreserve-invalidargs.patch new file mode 100644 index 0000000..5933b91 --- /dev/null +++ b/coreutils-cp-nopreserve-invalidargs.patch @@ -0,0 +1,29 @@ +From 124ab798e65b6c95a8486f6f6af9bdf69b11e1bf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= +Date: Fri, 11 Oct 2013 14:44:53 +0200 +Subject: [PATCH] cp: correct error message for invalid arguments of '--no-preserve' + +* src/cp.c (decode_preserve_arg) : +Correct error message for invalid arguments of '--no-preserve'. +Reported by M.Vadkerti in rhbz #1018206 +--- + src/cp.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +diff --git a/src/cp.c b/src/cp.c +index e235b32..7bc8630 100644 +--- a/src/cp.c ++++ b/src/cp.c +@@ -854,7 +854,8 @@ decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off) + *comma++ = 0; + + /* process S. */ +- val = XARGMATCH ("--preserve", s, preserve_args, preserve_vals); ++ val = XARGMATCH (on_off ? "--preserve" : "--no-preserve", ++ s, preserve_args, preserve_vals); + switch (val) + { + case PRESERVE_MODE: +-- +1.7.1 + diff --git a/coreutils.spec b/coreutils.spec index bb9c1ee..de68bd3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 18%{?dist} +Release: 19%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -15,6 +15,7 @@ Source106: coreutils-colorls.csh # From upstream Patch1: coreutils-8.21-install-strip.patch Patch2: coreutils-aarch64-longlong.patch +Patch3: coreutils-cp-nopreserve-invalidargs.patch # Our patches #general patch to workaround koji build system issues @@ -129,6 +130,7 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .strip %patch2 -p1 -b .aarch64 +%patch3 -p1 -b .nopres # Our patches %patch100 -p1 -b .configure @@ -375,6 +377,10 @@ fi %{_sbindir}/chroot %changelog +* Mon Oct 14 2013 Ondrej Vasik 8.21-19 +- cp: correct error message for invalid arguments + of '--no-preserve' (#1018206) + * Thu Aug 15 2013 Ondrej Vasik 8.21-18 - pr -e, with a mix of backspaces and TABs, could corrupt the heap in multibyte locales (analyzed by J.Koncicky) From bf6c8ea7527bd104c9d2f0a3fd02fe36f0781be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 6 Nov 2013 14:24:54 +0100 Subject: [PATCH 216/523] Fix minor issue in colorls.csh script with noclobber on (reported by Ty! Boyack) --- coreutils-colorls.csh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index d02fe85..f2138a9 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -33,7 +33,7 @@ if ( ! -e "$COLORS" ) exit set _tmp="`mktemp .colorlsXXX --tmpdir=/tmp`" -if ( "$INCLUDE" != '' ) cat "$INCLUDE" > $_tmp +if ( "$INCLUDE" != '' ) cat "$INCLUDE" >> $_tmp grep -v '^INCLUDE' "$COLORS" >> $_tmp eval "`dircolors -c $_tmp`" From afe488cc194e5a6ea82994971774f87a4ffa2678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 6 Nov 2013 14:38:56 +0100 Subject: [PATCH 217/523] fix possible colorls.csh script errors for tcsh with noclobber set and entered include file (#1027279) --- coreutils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index de68bd3..68176f3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 19%{?dist} +Release: 20%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -377,6 +377,10 @@ fi %{_sbindir}/chroot %changelog +* Wed Nov 06 2013 Ondrej Vasik 8.21-20 +- fix possible colorls.csh script errors for tcsh with + noclobber set and entered include file (#1027279) + * Mon Oct 14 2013 Ondrej Vasik 8.21-19 - cp: correct error message for invalid arguments of '--no-preserve' (#1018206) From 6f1fcbc4c6f58881968d142d245af2a88f85b407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 6 Nov 2013 16:18:23 +0100 Subject: [PATCH 218/523] Fix possible noclobber issue in colorls.sh as well --- coreutils-colorls.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index 7d27940..c71e357 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -35,7 +35,7 @@ if [ -z "$USER_LS_COLORS" ]; then TMP="`mktemp .colorlsXXX --tmpdir=/tmp`" - [ -e "$INCLUDE" ] && cat "$INCLUDE" > $TMP + [ -e "$INCLUDE" ] && cat "$INCLUDE" >> $TMP grep -v '^INCLUDE' "$COLORS" >> $TMP eval "`dircolors --sh $TMP 2>/dev/null`" From 3e3be79dfd61dec87a7a3c535087d89ba01fb1cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 28 Nov 2013 01:24:16 +0100 Subject: [PATCH 219/523] turn on the multibyte path in the testsuite to cover i18n regressions --- coreutils-i18n.patch | 467 ++++++++++++++++++++++++++++++++++++++++++- coreutils.spec | 6 +- 2 files changed, 463 insertions(+), 10 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 5f3be7c..6aa1c18 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4050,29 +4050,29 @@ diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk tests/misc/sort-month.sh \ diff -urNp coreutils-8.21-orig/tests/misc/cut.pl coreutils-8.21/tests/misc/cut.pl --- coreutils-8.21-orig/tests/misc/cut.pl 2013-02-05 00:40:31.000000000 +0100 -+++ coreutils-8.21/tests/misc/cut.pl 2013-02-15 14:27:18.974468564 +0100 -@@ -23,9 +23,10 @@ use strict; ++++ coreutils-8.21/tests/misc/cut.pl 2013-11-27 19:47:58.430539269 +0100 +@@ -23,9 +23,11 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; -my $mb_locale = $ENV{LOCALE_FR_UTF8}; --! defined $mb_locale || $mb_locale eq 'none' ++my $mb_locale; ++# uncommented enable multibyte paths ++#$mb_locale = $ENV{LOCALE_FR_UTF8}; + ! defined $mb_locale || $mb_locale eq 'none' - and $mb_locale = 'C'; -+#my $mb_locale = $ENV{LOCALE_FR_UTF8}; -+#! defined $mb_locale || $mb_locale eq 'none' -+# and $mb_locale = 'C'; -+my $mb_locale = 'C'; ++ and $mb_locale = 'C'; my $prog = 'cut'; my $try = "Try '$prog --help' for more information.\n"; diff -urNp coreutils-8.21-orig/tests/misc/expand.pl coreutils-8.21/tests/misc/expand.pl --- coreutils-8.21-orig/tests/misc/expand.pl 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/tests/misc/expand.pl 2013-02-15 14:25:07.891468472 +0100 ++++ coreutils-8.21/tests/misc/expand.pl 2013-11-27 19:47:58.431538769 +0100 @@ -23,6 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; -+# uncommented according to upstream commit enabling multibyte paths ++#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'; @@ -4122,6 +4122,147 @@ diff -urNp coreutils-8.21-orig/tests/misc/expand.pl coreutils-8.21/tests/misc/ex my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; +diff -urNp coreutils-8.21-orig/tests/misc/fold.pl coreutils-8.21/tests/misc/fold.pl +--- coreutils-8.21-orig/tests/misc/fold.pl 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/tests/misc/fold.pl 2013-11-27 19:47:58.431538769 +0100 +@@ -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; +diff -urNp coreutils-8.21-orig/tests/misc/join.pl coreutils-8.21/tests/misc/join.pl +--- coreutils-8.21-orig/tests/misc/join.pl 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/tests/misc/join.pl 2013-11-27 19:47:58.432538269 +0100 +@@ -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 ($) + { +@@ -306,8 +315,49 @@ foreach my $t (@tv) + push @Tests, $new_ent; + } + ++# Add _POSIX2_VERSION=199209 to the environment of each test ++# that uses an old-style option like +1. ++if ($mb_locale ne 'C') ++ { ++ # Duplicate each test vector, appending "-mb" to the test name and ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we ++ # provide coverage for the distro-added multi-byte code paths. ++ my @new; ++ foreach my $t (@Tests) ++ { ++ my @new_t = @$t; ++ my $test_name = shift @new_t; ++ ++ # Depending on whether join is multi-byte-patched, ++ # it emits different diagnostics: ++ # non-MB: invalid byte or field list ++ # MB: invalid byte, character or field list ++ # Adjust the expected error output accordingly. ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} ++ (@new_t)) ++ { ++ my $sub = {ERR_SUBST => 's/, character//'}; ++ push @new_t, $sub; ++ push @$t, $sub; ++ } ++ #Adjust the output some error messages including test_name for mb ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR}} ++ (@new_t)) ++ { ++ my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"}; ++ push @new_t, $sub2; ++ push @$t, $sub2; ++ } ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ + @Tests = triple_test \@Tests; + ++#skip invalid-j-mb test, it is failing because of the format ++@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests; ++ + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; + diff -urNp coreutils-8.21-orig/tests/misc/mb1.I coreutils-8.21/tests/misc/mb1.I --- coreutils-8.21-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-8.21/tests/misc/mb1.I 2013-02-15 14:25:07.902467891 +0100 @@ -4203,3 +4344,311 @@ diff -urNp coreutils-8.21-orig/tests/misc/sort-mb-tests.sh coreutils-8.21/tests/ +compare exp out || { fail=1; cat out; } + +Exit $fail +diff -urNp coreutils-8.21-orig/tests/misc/sort-merge.pl coreutils-8.21/tests/misc/sort-merge.pl +--- coreutils-8.21-orig/tests/misc/sort-merge.pl 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/tests/misc/sort-merge.pl 2013-11-27 19:47:58.435536769 +0100 +@@ -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 =~ "18g"); ++ 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}; + +diff -urNp coreutils-8.21-orig/tests/misc/sort.pl coreutils-8.21/tests/misc/sort.pl +--- coreutils-8.21-orig/tests/misc/sort.pl 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/tests/misc/sort.pl 2013-11-27 19:47:58.436536269 +0100 +@@ -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 '-'. +@@ -414,6 +419,37 @@ + and push (@$t, {ENV=>'_POSIX2_VERSION=199209'}), last; + } + } ++ ++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"); ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } + + @Tests = triple_test \@Tests; + +diff -urNp coreutils-8.21-orig/tests/misc/unexpand.pl coreutils-8.21/tests/misc/unexpand.pl +--- coreutils-8.21-orig/tests/misc/unexpand.pl 2013-01-31 01:46:24.000000000 +0100 ++++ coreutils-8.21/tests/misc/unexpand.pl 2013-11-27 19:47:58.436536269 +0100 +@@ -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"}], +@@ -92,6 +100,37 @@ my @Tests = + {EXIT => 1}, {ERR => "$prog: tab stop value is too large\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}; + +diff -urNp coreutils-8.21-orig/tests/misc/uniq.pl coreutils-8.21/tests/misc/uniq.pl +--- coreutils-8.21-orig/tests/misc/uniq.pl 2013-01-31 01:46:25.000000000 +0100 ++++ coreutils-8.21/tests/misc/uniq.pl 2013-11-27 19:47:58.437535769 +0100 +@@ -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($) + { +@@ -207,7 +215,45 @@ + $t->[0] =~ /^obs-plus/ + 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; ++ } ++ 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; + +diff -urNp coreutils-8.21-orig/tests/pr/pr-tests.pl coreutils-8.21/tests/pr/pr-tests.pl +--- coreutils-8.21-orig/tests/pr/pr-tests.pl 2013-01-31 01:46:25.000000000 +0100 ++++ coreutils-8.21/tests/pr/pr-tests.pl 2013-11-27 19:48:12.683409258 +0100 +@@ -23,6 +23,15 @@ use strict; + + my $prog = 'pr'; + ++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 +@@ -466,8 +475,48 @@ push @Tests, + {IN=>{3=>"x\ty\tz\n"}}, + {OUT=>join("\t", qw(a b c m n o x y z)) . "\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"); ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ + @Tests = triple_test \@Tests; + ++# Remember that triple_test creates from each test with exactly one "IN" ++# file two more tests (.p and .r suffix on name) corresponding to reading ++# input from a file and from a pipe. The pipe-reading test would fail ++# due to a race condition about 1 in 20 times. ++# Remove the IN_PIPE version of the "output-is-input" test above. ++# The others aren't susceptible because they have three inputs each. ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; ++ + my $save_temps = $ENV{DEBUG}; + my $verbose = $ENV{VERBOSE}; + diff --git a/coreutils.spec b/coreutils.spec index 68176f3..511ab2d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 20%{?dist} +Release: 21%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -377,6 +377,10 @@ fi %{_sbindir}/chroot %changelog +* Thu Nov 28 2013 Ondrej Vasik 8.21-21 +- turn on the multibyte path in the testsuite to cover + i18n regressions + * Wed Nov 06 2013 Ondrej Vasik 8.21-20 - fix possible colorls.csh script errors for tcsh with noclobber set and entered include file (#1027279) From cc8ce57be28098f63a07618df22a5a45f7dbc828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 28 Nov 2013 01:35:10 +0100 Subject: [PATCH 220/523] Enable cut and sort-merge perl tests for multibyte as well --- coreutils-i18n.patch | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 6aa1c18..9eb17fe 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4058,13 +4058,21 @@ diff -urNp coreutils-8.21-orig/tests/misc/cut.pl coreutils-8.21/tests/misc/cut.p -my $mb_locale = $ENV{LOCALE_FR_UTF8}; +my $mb_locale; +# uncommented enable multibyte paths -+#$mb_locale = $ENV{LOCALE_FR_UTF8}; ++$mb_locale = $ENV{LOCALE_FR_UTF8}; ! defined $mb_locale || $mb_locale eq 'none' - and $mb_locale = 'C'; + and $mb_locale = 'C'; my $prog = 'cut'; my $try = "Try '$prog --help' for more information.\n"; +@@ -224,6 +226,7 @@ + my @new_t = @$t; + my $test_name = shift @new_t; + ++ next if ($test_name =~ "newline-[12][0-9]"); + push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; + } + push @Tests, @new; diff -urNp coreutils-8.21-orig/tests/misc/expand.pl coreutils-8.21/tests/misc/expand.pl --- coreutils-8.21-orig/tests/misc/expand.pl 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/tests/misc/expand.pl 2013-11-27 19:47:58.431538769 +0100 @@ -4353,7 +4361,7 @@ diff -urNp coreutils-8.21-orig/tests/misc/sort-merge.pl coreutils-8.21/tests/mis +my $mb_locale; +# uncommented according to upstream commit enabling multibyte paths -+#$mb_locale = $ENV{LOCALE_FR_UTF8}; ++$mb_locale = $ENV{LOCALE_FR_UTF8}; +! defined $mb_locale || $mb_locale eq 'none' + and $mb_locale = 'C'; + @@ -4392,7 +4400,7 @@ diff -urNp coreutils-8.21-orig/tests/misc/sort-merge.pl coreutils-8.21/tests/mis + push @new_t, $sub; + push @$t, $sub; + } -+ next if ($test_name =~ "18g"); ++ next if ($test_name =~ "nmerge-."); + push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; + } + push @Tests, @new; From b9de06b267248777abb49a4c907fb3004d398617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 2 Dec 2013 10:53:06 +0100 Subject: [PATCH 221/523] Remove no longer needed files in coreutils-i18n testsuite --- coreutils-i18n.patch | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 9eb17fe..5a70f39 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4271,38 +4271,6 @@ diff -urNp coreutils-8.21-orig/tests/misc/join.pl coreutils-8.21/tests/misc/join my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.21-orig/tests/misc/mb1.I coreutils-8.21/tests/misc/mb1.I ---- coreutils-8.21-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.21/tests/misc/mb1.I 2013-02-15 14:25:07.902467891 +0100 -@@ -0,0 +1,4 @@ -+Apple@10 -+Banana@5 -+Citrus@20 -+Cherry@30 -diff -urNp coreutils-8.21-orig/tests/misc/mb1.X coreutils-8.21/tests/misc/mb1.X ---- coreutils-8.21-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.21/tests/misc/mb1.X 2013-02-15 14:25:07.917467426 +0100 -@@ -0,0 +1,4 @@ -+Banana@5 -+Apple@10 -+Citrus@20 -+Cherry@30 -diff -urNp coreutils-8.21-orig/tests/misc/mb2.I coreutils-8.21/tests/misc/mb2.I ---- coreutils-8.21-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.21/tests/misc/mb2.I 2013-02-15 14:25:07.933467390 +0100 -@@ -0,0 +1,4 @@ -+Apple@AA10@@20 -+Banana@AA5@@30 -+Citrus@AA20@@5 -+Cherry@AA30@@10 -diff -urNp coreutils-8.21-orig/tests/misc/mb2.X coreutils-8.21/tests/misc/mb2.X ---- coreutils-8.21-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.21/tests/misc/mb2.X 2013-02-15 14:25:08.002467808 +0100 -@@ -0,0 +1,4 @@ -+Citrus@AA20@@5 -+Cherry@AA30@@10 -+Apple@AA10@@20 -+Banana@AA5@@30 diff -urNp coreutils-8.21-orig/tests/misc/sort-mb-tests.sh coreutils-8.21/tests/misc/sort-mb-tests.sh --- coreutils-8.21-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-8.21/tests/misc/sort-mb-tests.sh 2013-02-18 17:44:03.852275681 +0100 From a6b6d0c94b549a3a844334c407d4ae44f9cbb5e8 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Mon, 9 Dec 2013 11:26:15 +0000 Subject: [PATCH 222/523] Add upstream patch to fix test failures on aarch64 --- coreutils-aarch64-tests.patch | 62 +++++++++++++++++++++++++++++++++++ coreutils.spec | 7 +++- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 coreutils-aarch64-tests.patch diff --git a/coreutils-aarch64-tests.patch b/coreutils-aarch64-tests.patch new file mode 100644 index 0000000..6d08ff0 --- /dev/null +++ b/coreutils-aarch64-tests.patch @@ -0,0 +1,62 @@ +From 970b2ddea2d47f3167f4166e646d414f235f04b1 Mon Sep 17 00:00:00 2001 +From: Pádraig Brady +Date: Sat, 07 Dec 2013 15:00:06 +0000 +Subject: tests: fix false failure on platforms using newfstatat + +* tests/ls/stat-free-color.sh: Add newfstatat to the list +of syscalls to trace. Also add all "stat" syscalls to the +list of syscalls that we verify that strace supports. +Also only create a single dangling symlink to check, since +we already only check for a single "stat" call. +Fixes http://bugs.gnu.org/16075 seen on AArch64 +--- +diff --git a/tests/ls/stat-free-color.sh b/tests/ls/stat-free-color.sh +index 3aacf96..5fd5bea 100755 +--- a/tests/ls/stat-free-color.sh ++++ b/tests/ls/stat-free-color.sh +@@ -18,12 +18,16 @@ + + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ ls +-require_strace_ stat ++ ++# Note this list of _file name_ stat functions must be ++# as cross platform as possible and so doesn't include ++# fstatat64 as that's not available on aarch64 for example. ++stats='stat,lstat,stat64,lstat64,newfstatat' ++ ++require_strace_ $stats + require_dirent_d_type_ + +-for i in 1 2 3; do +- ln -s nowhere dangle-$i || framework_failure_ +-done ++ln -s nowhere dangle || framework_failure_ + + # Disable enough features via LS_COLORS so that ls --color + # can do its job without calling stat (other than the obligatory +@@ -53,17 +57,18 @@ eval $(dircolors -b color-without-stat) + # To avoid counting those, first get a baseline count by running + # ls with only the --help option. Then, compare that with the + # invocation under test. +-strace -o log-help -e stat,lstat,stat64,lstat64 ls --help >/dev/null || fail=1 ++strace -o log-help -e $stats ls --help >/dev/null || fail=1 + n_lines_help=$(wc -l < log-help) + +-strace -o log -e stat,lstat,stat64,lstat64 ls --color=always . || fail=1 ++strace -o log -e $stats ls --color=always . || fail=1 + n_lines=$(wc -l < log) + + n_stat=$(expr $n_lines - $n_lines_help) + +-# Expect one or two stat calls. ++# Expect one stat call. + case $n_stat in +- 1) ;; ++ 0) skip_ 'No stat calls recognized on this platform' ;; ++ 1) ;; # Corresponding to stat(".") + *) fail=1; head -n30 log* ;; + esac + +-- +cgit v0.9.0.2 diff --git a/coreutils.spec b/coreutils.spec index 511ab2d..70fec8e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 21%{?dist} +Release: 22%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -16,6 +16,7 @@ Source106: coreutils-colorls.csh Patch1: coreutils-8.21-install-strip.patch Patch2: coreutils-aarch64-longlong.patch Patch3: coreutils-cp-nopreserve-invalidargs.patch +Patch4: coreutils-aarch64-tests.patch # Our patches #general patch to workaround koji build system issues @@ -131,6 +132,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch1 -p1 -b .strip %patch2 -p1 -b .aarch64 %patch3 -p1 -b .nopres +%patch4 -p1 -b .aarch64tests # Our patches %patch100 -p1 -b .configure @@ -377,6 +379,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Dec 9 2013 Peter Robinson 8.21-22 +- Add upstream patch to fix test failures on aarch64 + * Thu Nov 28 2013 Ondrej Vasik 8.21-21 - turn on the multibyte path in the testsuite to cover i18n regressions From 595c0722d7f8921dbaa2fa7cecf940780a551028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 12 Dec 2013 13:34:32 +0100 Subject: [PATCH 223/523] skip output-is-input-mb.p test - failing on armv7l (reported by B.Voelker) --- coreutils-i18n.patch | 8 ++++++++ coreutils.spec | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 5a70f39..107c7dc 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4437,6 +4437,14 @@ diff -urNp coreutils-8.21-orig/tests/misc/sort.pl coreutils-8.21/tests/misc/sort @Tests = triple_test \@Tests; +@@ -424,6 +460,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}; diff -urNp coreutils-8.21-orig/tests/misc/unexpand.pl coreutils-8.21/tests/misc/unexpand.pl --- coreutils-8.21-orig/tests/misc/unexpand.pl 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/tests/misc/unexpand.pl 2013-11-27 19:47:58.436536269 +0100 diff --git a/coreutils.spec b/coreutils.spec index 70fec8e..71a18ab 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.21 -Release: 22%{?dist} +Release: 23%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -379,6 +379,10 @@ fi %{_sbindir}/chroot %changelog +* Thu Dec 12 2013 Ondrej Vasik 8.21-23 +- skip output-is-input-mb.p test - failing on armv7l (reported + by B.Voelker) + * Mon Dec 9 2013 Peter Robinson 8.21-22 - Add upstream patch to fix test failures on aarch64 From bb33bc40ad58cce4bc59c119c4180fdea43e23a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 14 Dec 2013 18:41:07 +0100 Subject: [PATCH 224/523] New upstream version 8.22, rediff, adjusting i18n patch to work after upstream optimizations, will investigate cut.pl before build (failing df symlink check is not a regression) --- .gitignore | 1 + coreutils-6.10-configuration.patch | 4 +- coreutils-6.10-manpages.patch | 2 +- coreutils-8.21-install-strip.patch | 81 ------------ coreutils-8.22-temporarytestoff.patch | 30 +++++ coreutils-aarch64-longlong.patch | 35 ------ coreutils-aarch64-tests.patch | 62 --------- coreutils-cp-nopreserve-invalidargs.patch | 29 ----- coreutils-cpZ-deprecate.patch | 23 ---- coreutils-df-direct.patch | 18 +-- coreutils-i18n.patch | 79 +++++------- coreutils-selinux.patch | 146 +++------------------- coreutils.spec | 23 ++-- sources | 2 +- 14 files changed, 101 insertions(+), 434 deletions(-) delete mode 100644 coreutils-8.21-install-strip.patch create mode 100644 coreutils-8.22-temporarytestoff.patch delete mode 100644 coreutils-aarch64-longlong.patch delete mode 100644 coreutils-aarch64-tests.patch delete mode 100644 coreutils-cp-nopreserve-invalidargs.patch delete mode 100644 coreutils-cpZ-deprecate.patch diff --git a/.gitignore b/.gitignore index 0c7a76a..53ec760 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ /coreutils-8.19.tar.xz /coreutils-8.20.tar.xz /coreutils-8.21.tar.xz +/coreutils-8.22.tar.xz diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index b4d7b4a..e14711b 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -115,11 +115,11 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test -TESTS += test-utimens -check_PROGRAMS += test-utimens --test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBINTL@ +-test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_NANOSLEEP) @LIBINTL@ -EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h +#TESTS += test-utimens +#check_PROGRAMS += test-utimens -+#test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) @LIBINTL@ ++#test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_NANOSLEEP) @LIBINTL@ +#EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h ## end gnulib module utimens-tests diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index 2c663f9..3f5d37b 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -10,4 +10,4 @@ diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c +"), stdout); fputs (_("\ \n\ - The following three options are useful only when verifying checksums:\n\ + The following four options are useful only when verifying checksums:\n\ diff --git a/coreutils-8.21-install-strip.patch b/coreutils-8.21-install-strip.patch deleted file mode 100644 index 1d6f198..0000000 --- a/coreutils-8.21-install-strip.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 3a20f6888575be7059e9acac07d397009e98c213 Mon Sep 17 00:00:00 2001 -From: Ondrej Oprala -Date: Fri, 22 Feb 2013 12:48:57 +0000 -Subject: install: cleanup properly if the strip program failed for any reason - -* src/install.c (strip): Indicate failure with a return code instead -of terminating the program. -(install_file_in_file): Handle strip's return code and unlink the -created file if necessary. -* tests/install/strip-program.sh: Add a test to cover the changes. ---- -diff --git a/src/install.c b/src/install.c -index 94374df..a5ed7a8 100644 ---- a/src/install.c -+++ b/src/install.c -@@ -515,16 +515,17 @@ change_timestamps (struct stat const *src_sb, char const *dest) - magic numbers vary so much from system to system that making - it portable would be very difficult. Not worth the effort. */ - --static void -+static bool - strip (char const *name) - { - int status; -+ bool ok = false; - pid_t pid = fork (); - - switch (pid) - { - case -1: -- error (EXIT_FAILURE, errno, _("fork system call failed")); -+ error (0, errno, _("fork system call failed")); - break; - case 0: /* Child. */ - execlp (strip_program, strip_program, name, NULL); -@@ -532,11 +533,14 @@ strip (char const *name) - break; - default: /* Parent. */ - if (waitpid (pid, &status, 0) < 0) -- error (EXIT_FAILURE, errno, _("waiting for strip")); -+ error (0, errno, _("waiting for strip")); - else if (! WIFEXITED (status) || WEXITSTATUS (status)) -- error (EXIT_FAILURE, 0, _("strip process terminated abnormally")); -+ error (0, 0, _("strip process terminated abnormally")); -+ else -+ ok = true; /* strip succeeded */ - break; - } -+ return ok; - } - - /* Initialize the user and group ownership of the files to install. */ -@@ -681,7 +685,12 @@ install_file_in_file (const char *from, const char *to, - if (! copy_file (from, to, x)) - return false; - if (strip_files) -- strip (to); -+ if (! strip (to)) -+ { -+ if (unlink (to) != 0) /* Cleanup. */ -+ error (EXIT_FAILURE, errno, _("cannot unlink %s"), to); -+ return false; -+ } - if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode)) - && ! change_timestamps (&from_sb, to)) - return false; -diff --git a/tests/install/strip-program.sh b/tests/install/strip-program.sh -index 8950d50..5d65373 100755 ---- a/tests/install/strip-program.sh -+++ b/tests/install/strip-program.sh -@@ -33,4 +33,8 @@ echo aBc > exp || fail=1 - ginstall src dest -s --strip-program=./b || fail=1 - compare exp dest || fail=1 - -+# Check that install cleans up properly if strip fails. -+ginstall src dest2 -s --strip-program=./FOO && fail=1 -+test -e dest2 && fail=1 -+ - Exit $fail --- -cgit v0.9.0.2 diff --git a/coreutils-8.22-temporarytestoff.patch b/coreutils-8.22-temporarytestoff.patch new file mode 100644 index 0000000..59a7aa1 --- /dev/null +++ b/coreutils-8.22-temporarytestoff.patch @@ -0,0 +1,30 @@ +diff -urNp coreutils-8.22-orig/tests/df/df-symlink.sh coreutils-8.22/tests/df/df-symlink.sh +--- coreutils-8.22-orig/tests/df/df-symlink.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/df/df-symlink.sh 2013-12-14 18:20:15.822594995 +0100 +@@ -18,6 +18,7 @@ + + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ df ++expensive_ + + disk=$(df --out=source '.' | tail -n1) || + skip_ "cannot determine '.' file system" +diff -urNp coreutils-8.22-orig/tests/misc/cut.pl coreutils-8.22/tests/misc/cut.pl +--- coreutils-8.22-orig/tests/misc/cut.pl 2013-12-14 18:18:58.707172051 +0100 ++++ coreutils-8.22/tests/misc/cut.pl 2013-12-14 18:22:14.931010910 +0100 +@@ -23,11 +23,11 @@ use strict; + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + +-my $mb_locale; ++my $mb_locale = 'C'; + # uncommented enable multibyte paths +-$mb_locale = $ENV{LOCALE_FR_UTF8}; +-! defined $mb_locale || $mb_locale eq 'none' +- and $mb_locale = 'C'; ++#$mb_locale = $ENV{LOCALE_FR_UTF8}; ++#! defined $mb_locale || $mb_locale eq 'none' ++# and $mb_locale = 'C'; + + my $prog = 'cut'; + my $try = "Try '$prog --help' for more information.\n"; diff --git a/coreutils-aarch64-longlong.patch b/coreutils-aarch64-longlong.patch deleted file mode 100644 index 323759b..0000000 --- a/coreutils-aarch64-longlong.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/src/longlong.h b/src/longlong.h -index e880587..023f47e 100644 ---- a/src/longlong.h -+++ b/src/longlong.h -@@ -530,23 +530,16 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype); - #endif /* __arm__ */ - - #if defined (__aarch64__) && W_TYPE_SIZE == 64 -+/* FIXME: Extend the immediate range for the low word by using both -+ ADDS and SUBS, since they set carry in the same way. */ - #define add_ssaaaa(sh, sl, ah, al, bh, bl) \ -- __asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \ -+ __asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \ - : "=r" (sh), "=&r" (sl) \ -- : "r" (ah), "rZ" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC) -+ : "rZ" (ah), "rZ" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC) - #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -- do { \ -- if (__builtin_constant_p (bl)) \ -- { \ -- __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ -- : "=r" (sh), "=&r" (sl) \ -- : "r" (ah), "r" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \ -- } \ -- else /* only bh might be a constant */ \ -- __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ -- : "=r" (sh), "=&r" (sl) \ -- : "r" (ah), "rZ" (bh), "r" (al), "rI" (bl) __CLOBBER_CC);\ -- } while (0) -+ __asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \ -+ : "=r,r" (sh), "=&r,&r" (sl) \ -+ : "rZ,rZ" (ah), "rZ,rZ" (bh), "r,Z" (al), "rI,r" (bl) __CLOBBER_CC) - #define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ diff --git a/coreutils-aarch64-tests.patch b/coreutils-aarch64-tests.patch deleted file mode 100644 index 6d08ff0..0000000 --- a/coreutils-aarch64-tests.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 970b2ddea2d47f3167f4166e646d414f235f04b1 Mon Sep 17 00:00:00 2001 -From: Pádraig Brady -Date: Sat, 07 Dec 2013 15:00:06 +0000 -Subject: tests: fix false failure on platforms using newfstatat - -* tests/ls/stat-free-color.sh: Add newfstatat to the list -of syscalls to trace. Also add all "stat" syscalls to the -list of syscalls that we verify that strace supports. -Also only create a single dangling symlink to check, since -we already only check for a single "stat" call. -Fixes http://bugs.gnu.org/16075 seen on AArch64 ---- -diff --git a/tests/ls/stat-free-color.sh b/tests/ls/stat-free-color.sh -index 3aacf96..5fd5bea 100755 ---- a/tests/ls/stat-free-color.sh -+++ b/tests/ls/stat-free-color.sh -@@ -18,12 +18,16 @@ - - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ ls --require_strace_ stat -+ -+# Note this list of _file name_ stat functions must be -+# as cross platform as possible and so doesn't include -+# fstatat64 as that's not available on aarch64 for example. -+stats='stat,lstat,stat64,lstat64,newfstatat' -+ -+require_strace_ $stats - require_dirent_d_type_ - --for i in 1 2 3; do -- ln -s nowhere dangle-$i || framework_failure_ --done -+ln -s nowhere dangle || framework_failure_ - - # Disable enough features via LS_COLORS so that ls --color - # can do its job without calling stat (other than the obligatory -@@ -53,17 +57,18 @@ eval $(dircolors -b color-without-stat) - # To avoid counting those, first get a baseline count by running - # ls with only the --help option. Then, compare that with the - # invocation under test. --strace -o log-help -e stat,lstat,stat64,lstat64 ls --help >/dev/null || fail=1 -+strace -o log-help -e $stats ls --help >/dev/null || fail=1 - n_lines_help=$(wc -l < log-help) - --strace -o log -e stat,lstat,stat64,lstat64 ls --color=always . || fail=1 -+strace -o log -e $stats ls --color=always . || fail=1 - n_lines=$(wc -l < log) - - n_stat=$(expr $n_lines - $n_lines_help) - --# Expect one or two stat calls. -+# Expect one stat call. - case $n_stat in -- 1) ;; -+ 0) skip_ 'No stat calls recognized on this platform' ;; -+ 1) ;; # Corresponding to stat(".") - *) fail=1; head -n30 log* ;; - esac - --- -cgit v0.9.0.2 diff --git a/coreutils-cp-nopreserve-invalidargs.patch b/coreutils-cp-nopreserve-invalidargs.patch deleted file mode 100644 index 5933b91..0000000 --- a/coreutils-cp-nopreserve-invalidargs.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 124ab798e65b6c95a8486f6f6af9bdf69b11e1bf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= -Date: Fri, 11 Oct 2013 14:44:53 +0200 -Subject: [PATCH] cp: correct error message for invalid arguments of '--no-preserve' - -* src/cp.c (decode_preserve_arg) : -Correct error message for invalid arguments of '--no-preserve'. -Reported by M.Vadkerti in rhbz #1018206 ---- - src/cp.c | 3 ++- - 1 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/src/cp.c b/src/cp.c -index e235b32..7bc8630 100644 ---- a/src/cp.c -+++ b/src/cp.c -@@ -854,7 +854,8 @@ decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off) - *comma++ = 0; - - /* process S. */ -- val = XARGMATCH ("--preserve", s, preserve_args, preserve_vals); -+ val = XARGMATCH (on_off ? "--preserve" : "--no-preserve", -+ s, preserve_args, preserve_vals); - switch (val) - { - case PRESERVE_MODE: --- -1.7.1 - diff --git a/coreutils-cpZ-deprecate.patch b/coreutils-cpZ-deprecate.patch deleted file mode 100644 index 713b7c5..0000000 --- a/coreutils-cpZ-deprecate.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff -urNp coreutils-8.12-orig/src/copy.c coreutils-8.12/src/copy.c ---- coreutils-8.12-orig/src/copy.c 2011-08-11 16:05:15.432485738 +0200 -+++ coreutils-8.12/src/copy.c 2011-08-11 16:14:28.660360607 +0200 -@@ -850,7 +850,7 @@ copy_reg (char const *src_name, char con - 1) the src context may prohibit writing, and - 2) because it's more consistent to use the same context - that is used when the destination file doesn't already exist. */ -- if (x->preserve_security_context && 0 <= dest_desc) -+ if ((x->set_security_context || x->preserve_security_context) && 0 <= dest_desc) - { - bool all_errors = (!x->data_copy_required - || x->require_preserve_context); -diff -urNp coreutils-8.12-orig/src/cp.c coreutils-8.12/src/cp.c ---- coreutils-8.12-orig/src/cp.c 2011-08-11 16:05:15.435486976 +0200 -+++ coreutils-8.12/src/cp.c 2011-08-11 16:16:56.408644526 +0200 -@@ -1119,6 +1119,7 @@ main (int argc, char **argv) - exit( 1 ); - } - x.set_security_context = true; -+ (void) fprintf(stderr, _("Warning, -Z/--context option is deprecated and will be removed soon!\nPlease use 'install' utility instead of cp for this functionality.\n")); - /* if there's a security_context given set new path - components to that context, too */ - if ( setfscreatecon(optarg) < 0 ) { diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 6cfefc7..a52307a 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -29,11 +29,11 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c static struct fs_usage grand_fsu; @@ -238,13 +241,15 @@ enum + NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, - OUTPUT_OPTION, -- MEGABYTES_OPTION /* FIXME: remove long opt in Aug 2013 */ -+ MEGABYTES_OPTION, /* FIXME: remove long opt in Aug 2013 */ +- OUTPUT_OPTION ++ OUTPUT_OPTION, + DIRECT_OPTION }; @@ -57,7 +57,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1150,6 +1158,17 @@ get_point (const char *point, const stru +@@ -1150,6 +1158,19 @@ get_point (const char *point, const stru static void get_entry (char const *name, struct stat const *statp) { @@ -66,7 +66,9 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c + char *resolved = canonicalize_file_name (name); + if (resolved) + { -+ get_dev (NULL, resolved, NULL, NULL, false, false, NULL, false); ++ char *mp = find_mount_point (name, statp); ++ get_dev (NULL, mp, resolved, NULL, NULL, false, false, NULL, false); ++ free(mp); + free (resolved); + return; + } @@ -76,9 +78,9 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c && get_disk (name)) return; @@ -1219,6 +1238,7 @@ or all file systems by default.\n\ - -B, --block-size=SIZE scale sizes by SIZE before printing them. E.g.,\n\ - '-BM' prints sizes in units of 1,048,576 bytes.\n\ - See SIZE format below.\n\ + -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ + '-BM' prints sizes in units of 1,048,576 bytes;\n\ + see SIZE format below\n\ + --direct show statistics for a file instead of mount point\n\ --total produce a grand total\n\ -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\ diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 107c7dc..1ad9c97 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -57,8 +57,8 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "cut" -@@ -72,6 +89,52 @@ - } \ +@@ -53,6 +70,52 @@ + } \ while (0) +/* Refill the buffer BUF to get a multibyte character. */ @@ -107,32 +107,9 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + } \ + while (0) + + struct range_pair { - size_t lo; -@@ -90,7 +153,7 @@ static char *field_1_buffer; - /* The number of bytes allocated for FIELD_1_BUFFER. */ - static size_t field_1_bufsize; - --/* The largest field or byte index used as an endpoint of a closed -+/* The largest byte, character or field index used as an endpoint of a closed - or degenerate range specification; this doesn't include the starting - index of right-open-ended ranges. For example, with either range spec - '2-5,9-', '2-3,5,9-' this variable would be set to 5. */ -@@ -102,10 +165,11 @@ static size_t eol_range_start; - - /* This is a bit vector. - In byte mode, which bytes to output. -+ In character mode, which characters to output. - In field mode, which DELIM-separated fields to output. -- Both bytes and fields are numbered starting with 1, -+ Bytes, characters and fields are numbered starting with 1, - so the zeroth bit of this array is unused. -- A field or byte K has been selected if -+ A byte, character or field K has been selected if - (K <= MAX_RANGE_ENDPOINT and is_printable_field(K)) - || (EOL_RANGE_START > 0 && K >= EOL_RANGE_START). */ - static unsigned char *printable_field; @@ -114,15 +178,25 @@ enum operating_mode { undefined_mode, @@ -189,7 +166,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c else error (0, 0, _("field number %s is too large"), quote (bad_num)); -@@ -588,6 +668,77 @@ cut_bytes (FILE *stream) +@@ -505,6 +584,80 @@ cut_bytes (FILE *stream) } } @@ -223,6 +200,8 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + bufpos = buf; + memset (&state, '\0', sizeof(mbstate_t)); + ++ current_rp = rp; ++ + while (1) + { + REFILL_BUFFER (buf, bufpos, buflen, stream); @@ -243,10 +222,11 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + } + else + { ++ next_item (&idx); + bool range_start; + bool *rs = output_delimiter_specified ? &range_start : NULL; + idx += (operating_mode == byte_mode) ? mblength : 1; -+ if (print_kth (idx, rs)) ++ if (print_kth (idx)) + { + if (rs && *rs && print_delimiter) + { @@ -267,7 +247,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -709,13 +860,195 @@ cut_fields (FILE *stream) +@@ -629,13 +782,197 @@ cut_fields (FILE *stream) } } @@ -289,6 +269,8 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + mbstate_t state; /* State of the stream. */ + int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ + ++ current_rp = rp; ++ + found_any_selected_field = 0; + field_idx = 1; + bufpos = buf; @@ -311,7 +293,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + 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, NULL)); ++ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); + + while (1) + { @@ -361,18 +343,18 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + continue; + } + -+ if (print_kth (1, NULL)) ++ 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; + } -+ ++field_idx; ++ next_item (&field_idx); + } + + if (wc != WEOF) + { -+ if (print_kth (field_idx, NULL)) ++ if (print_kth (field_idx)) + { + if (found_any_selected_field) + { @@ -398,7 +380,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + break; + } + -+ if (print_kth (field_idx, NULL)) ++ if (print_kth (field_idx)) + fwrite (bufpos, mblength, sizeof(char), stdout); + + buflen -= mblength; @@ -410,7 +392,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + wc = WEOF; + + if (!convfail && wc == wcdelim) -+ ++field_idx; ++ next_item (&field_idx); + else if (wc == WEOF || (!convfail && wc == L'\n')) + { + if (found_any_selected_field @@ -588,7 +570,6 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c } if (optind == argc) -Binary files coreutils-8.21-orig/src/.cut.c.swp and coreutils-8.21/src/.cut.c.swp differ diff -urNp coreutils-8.21-orig/src/expand.c coreutils-8.21/src/expand.c --- coreutils-8.21-orig/src/expand.c 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/src/expand.c 2013-02-15 14:25:07.774467536 +0100 @@ -1613,7 +1594,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c - putchar (output_separator); + PUT_TAB_CHAR; } - putchar ('\n'); + putchar (eolchar); } @@ -1090,21 +1334,46 @@ main (int argc, char **argv) @@ -1671,7 +1652,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c + } break; - case NOCHECK_ORDER_OPTION: + case 'z': diff -urNp coreutils-8.21-orig/src/pr.c coreutils-8.21/src/pr.c --- coreutils-8.21-orig/src/pr.c 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/src/pr.c 2013-02-15 14:25:07.819467936 +0100 @@ -3702,9 +3683,9 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -108,6 +130,10 @@ static enum delimit_method const delimit - /* Select whether/how to delimit groups of duplicate lines. */ - static enum delimit_method delimit_groups; +@@ -108,6 +130,10 @@ + GROUP_OPTION = CHAR_MAX + 1 + }; +/* Function pointers. */ +static char * @@ -3921,10 +3902,10 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -303,15 +494,43 @@ check_file (const char *infile, const ch - { +@@ -303,18 +494,45 @@ check_file (const char *infile, const ch char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); + bool first_group_printed = false; +#if HAVE_MBRTOWC + mbstate_t prevstate; + @@ -3935,12 +3916,14 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c { char *thisfield; size_t thislen; + bool new_group; +#if HAVE_MBRTOWC + mbstate_t thisstate; +#endif -+ + if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) break; + thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); +#if HAVE_MBRTOWC @@ -3962,9 +3945,9 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c + } + else +#endif - if (prevline->length == 0 - || different (thisfield, prevfield, thislen, prevlen)) - { + + new_group = (prevline->length == 0 + || different (thisfield, prevfield, thislen, prevlen)); @@ -330,17 +549,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; @@ -4550,7 +4533,7 @@ diff -urNp coreutils-8.21-orig/tests/misc/uniq.pl coreutils-8.21/tests/misc/uniq + push @new_t, $sub; + push @$t, $sub; + } -+ next if ($test_name =~ "schar" or $test_name =~ "^obs-plus" or $test_name =~ "119"); ++ next if ($test_name =~ "schar" or $test_name =~ "^obs-plus" or $test_name =~ "119" or $test_name =~ "128" or $test_name =~ "129" or $test_name =~ "130" or $test_name =~ "131" or $test_name =~ "132" or $test_name =~ "133" or $test_name =~ "145"); + push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; + } + push @Tests, @new; diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index a151acb..8c668c9 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -19,16 +19,16 @@ diff -urNp coreutils-8.21-orig/init.cfg coreutils-8.21/init.cfg --- coreutils-8.21-orig/init.cfg 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/init.cfg 2013-02-15 14:31:58.957469955 +0100 @@ -308,8 +308,8 @@ require_selinux_() - # Independent of whether SELinux is enabled system-wide, # the current file system may lack SELinux support. + # Also the current build may have SELinux support disabled. - case $(ls -Zd .) in - '? .'|'unlabeled .') + case $(ls -Zd . | cut -f4 -d" ") in + '?'|'unlabeled') - skip_ "this system (or maybe just" \ - "the current file system) lacks SELinux support" - ;; + test -z "$CONFIG_HEADER" \ + && framework_failure_ 'CONFIG_HEADER not defined' + grep '^#define HAVE_SELINUX_SELINUX_H 1' "$CONFIG_HEADER" > /dev/null \ diff -urNp coreutils-8.21-orig/man/chcon.x coreutils-8.21/man/chcon.x --- coreutils-8.21-orig/man/chcon.x 2011-08-23 15:44:01.000000000 +0200 +++ coreutils-8.21/man/chcon.x 2013-02-15 14:31:58.937482694 +0100 @@ -48,18 +48,6 @@ diff -urNp coreutils-8.21-orig/man/runcon.x coreutils-8.21/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.21-orig/src/chcon.c coreutils-8.21/src/chcon.c ---- coreutils-8.21-orig/src/chcon.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/chcon.c 2013-02-15 14:31:58.939469828 +0100 -@@ -355,7 +355,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\ - "), - program_name, program_name, program_name); - fputs (_("\ --Change the security context of each FILE to CONTEXT.\n\ -+Change the SELinux security context of each FILE to CONTEXT.\n\ - With --reference, change the security context of each FILE to that of RFILE.\n\ - "), stdout); - diff -urNp coreutils-8.21-orig/src/copy.c coreutils-8.21/src/copy.c --- coreutils-8.21-orig/src/copy.c 2013-02-07 10:37:05.000000000 +0100 +++ coreutils-8.21/src/copy.c 2013-02-15 14:31:58.941467872 +0100 @@ -72,30 +60,9 @@ diff -urNp coreutils-8.21-orig/src/copy.c coreutils-8.21/src/copy.c } else { -diff -urNp coreutils-8.21-orig/src/copy.h coreutils-8.21/src/copy.h ---- coreutils-8.21-orig/src/copy.h 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/copy.h 2013-02-15 14:31:58.943470982 +0100 -@@ -159,6 +159,9 @@ struct cp_options - bool preserve_timestamps; - bool explicit_no_preserve_mode; - -+ /* If true, attempt to set specified security context */ -+ bool set_security_context; -+ - /* Enabled for mv, and for cp by the --preserve=links option. - If true, attempt to preserve in the destination files any - logical hard links between the source files. If used with cp's diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c --- coreutils-8.21-orig/src/cp.c 2013-02-07 10:37:05.000000000 +0100 +++ coreutils-8.21/src/cp.c 2013-02-15 14:31:58.945468929 +0100 -@@ -141,6 +141,7 @@ static struct option const long_opts[] = - {"target-directory", required_argument, NULL, 't'}, - {"update", no_argument, NULL, 'u'}, - {"verbose", no_argument, NULL, 'v'}, -+ {"context", required_argument, NULL, 'Z'}, - {GETOPT_HELP_OPTION_DECL}, - {GETOPT_VERSION_OPTION_DECL}, - {NULL, 0, NULL, 0} @@ -201,6 +202,9 @@ Copy SOURCE to DEST, or multiple SOURCE( all\n\ "), stdout); @@ -106,28 +73,12 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents use full source file name under DIRECTORY\n\ "), stdout); -@@ -227,6 +231,7 @@ Copy SOURCE to DEST, or multiple SOURCE( - destination file is missing\n\ - -v, --verbose explain what is being done\n\ - -x, --one-file-system stay on this file system\n\ -+ -Z, --context=CONTEXT set security context of copy to CONTEXT\n\ - "), stdout); - fputs (HELP_OPTION_DESCRIPTION, stdout); - fputs (VERSION_OPTION_DESCRIPTION, stdout); -@@ -784,6 +789,7 @@ cp_option_init (struct cp_options *x) - x->explicit_no_preserve_mode = false; - x->preserve_security_context = false; - x->require_preserve_context = false; -+ x->set_security_context = false; - x->preserve_xattr = false; - x->reduce_diagnostics = false; - x->require_preserve_xattr = false; @@ -933,7 +939,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); -- while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:T", -+ while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ:", +- while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ", ++ while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ", long_opts, NULL)) != -1) { @@ -148,34 +99,6 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -@@ -1091,6 +1107,27 @@ main (int argc, char **argv) - x.one_file_system = true; - break; - -+ -+ case 'Z': -+ /* politely decline if we're not on a selinux-enabled kernel. */ -+ if( !selinux_enabled ) { -+ fprintf( stderr, "Warning: ignoring --context (-Z). " -+ "It requires a SELinux enabled kernel.\n" ); -+ break; -+ } -+ if ( x.preserve_security_context ) { -+ (void) fprintf(stderr, "%s: cannot force target context to '%s' and preserve it\n", argv[0], optarg); -+ exit( 1 ); -+ } -+ x.set_security_context = true; -+ /* if there's a security_context given set new path -+ components to that context, too */ -+ if ( setfscreatecon(optarg) < 0 ) { -+ (void) fprintf(stderr, _("cannot set default security context %s\n"), optarg); -+ exit( 1 ); -+ } -+ break; -+ - case 'S': - make_backups = true; - backup_suffix_string = optarg; diff -urNp coreutils-8.21-orig/src/id.c coreutils-8.21/src/id.c --- coreutils-8.21-orig/src/id.c 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/src/id.c 2013-02-15 14:31:58.946469154 +0100 @@ -185,35 +108,27 @@ diff -urNp coreutils-8.21-orig/src/id.c coreutils-8.21/src/id.c int optc; - int selinux_enabled = (is_selinux_enabled () > 0); + bool selinux_enabled = (is_selinux_enabled () > 0); - - /* If true, output the list of all group IDs. -G */ - bool just_group_list = false; + bool smack_enabled = is_smack_enabled (); + bool opt_zero = false; + char *pw_name = NULL; diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c --- coreutils-8.21-orig/src/install.c 2013-02-07 10:37:05.000000000 +0100 +++ coreutils-8.21/src/install.c 2013-02-15 14:31:58.948469440 +0100 -@@ -280,6 +280,7 @@ cp_option_init (struct cp_options *x) - x->data_copy_required = true; - x->require_preserve = false; - x->require_preserve_context = false; -+ x->set_security_context = false; - x->require_preserve_xattr = false; - x->recursive = false; - x->sparse_mode = SPARSE_AUTO; @@ -639,7 +640,7 @@ In the 4th form, create all components o -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ - --preserve-context preserve SELinux security context\n\ + -P, --preserve-context preserve SELinux security context\n\ - -Z, --context=CONTEXT set SELinux security context of files and directories\ - \n\ + -Z, --context[=CTX] set SELinux security context of destination file to\n\ + default type, or to CTX if specified\n\ "), stdout); @@ -782,7 +783,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); -- while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options, -+ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z:", long_options, +- while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z", long_options, ++ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z", long_options, NULL)) != -1) { switch (optc) @@ -223,7 +138,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c + case 'P': case PRESERVE_CONTEXT_OPTION: - if ( ! selinux_enabled) + if (! selinux_enabled) { @@ -860,6 +862,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); @@ -236,14 +151,6 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c x.preserve_security_context = true; use_default_selinux_context = false; break; -@@ -871,6 +877,7 @@ main (int argc, char **argv) - break; - } - scontext = optarg; -+ x.set_security_context = true; - use_default_selinux_context = false; - break; - case_GETOPT_HELP_CHAR; diff -urNp coreutils-8.21-orig/src/ls.c coreutils-8.21/src/ls.c --- coreutils-8.21-orig/src/ls.c 2013-02-03 04:24:02.000000000 +0100 +++ coreutils-8.21/src/ls.c 2013-02-15 14:31:58.953469008 +0100 @@ -411,7 +318,7 @@ diff -urNp coreutils-8.21-orig/src/ls.c coreutils-8.21/src/ls.c - if (format == long_format || print_scontext) + if (format == long_format || format == security_format || print_scontext) { - bool have_selinux = false; + bool have_scontext = false; bool have_acl = false; @@ -3016,7 +3041,7 @@ gobble_file (char const *name, enum file err = 0; @@ -619,29 +526,6 @@ diff -urNp coreutils-8.21-orig/src/mknod.c coreutils-8.21/src/mknod.c {"mode", required_argument, NULL, 'm'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, -diff -urNp coreutils-8.21-orig/src/mv.c coreutils-8.21/src/mv.c ---- coreutils-8.21-orig/src/mv.c 2013-02-07 10:37:05.000000000 +0100 -+++ coreutils-8.21/src/mv.c 2013-02-15 14:31:58.956469593 +0100 -@@ -120,6 +120,7 @@ cp_option_init (struct cp_options *x) - x->preserve_timestamps = true; - x->explicit_no_preserve_mode= false; - x->preserve_security_context = selinux_enabled; -+ x->set_security_context = false; - x->reduce_diagnostics = false; - x->data_copy_required = true; - x->require_preserve = false; /* FIXME: maybe make this an option */ -diff -urNp coreutils-8.21-orig/src/runcon.c coreutils-8.21/src/runcon.c ---- coreutils-8.21-orig/src/runcon.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/runcon.c 2013-02-15 14:31:58.956469593 +0100 -@@ -85,7 +85,7 @@ Usage: %s CONTEXT COMMAND [args]\n\ - or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\ - "), program_name, program_name); - fputs (_("\ --Run a program in a different security context.\n\ -+Run a program in a different SELinux security context.\n\ - With neither CONTEXT nor COMMAND, print the current security context.\n\ - "), stdout); - diff -urNp coreutils-8.21-orig/tests/misc/selinux.sh coreutils-8.21/tests/misc/selinux.sh --- coreutils-8.21-orig/tests/misc/selinux.sh 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/tests/misc/selinux.sh 2013-02-15 14:31:58.957469955 +0100 diff --git a/coreutils.spec b/coreutils.spec index 71a18ab..d8a602f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.21 -Release: 23%{?dist} +Version: 8.22 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -13,10 +13,6 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream -Patch1: coreutils-8.21-install-strip.patch -Patch2: coreutils-aarch64-longlong.patch -Patch3: coreutils-cp-nopreserve-invalidargs.patch -Patch4: coreutils-aarch64-tests.patch # Our patches #general patch to workaround koji build system issues @@ -44,13 +40,13 @@ Patch800: coreutils-i18n.patch Patch908: coreutils-getgrouplist.patch #Prevent buffer overflow in who(1) (bug #158405). Patch912: coreutils-overflow.patch +#Temporarily disable df symlink test, failing +Patch913: coreutils-8.22-temporarytestoff.patch #SELINUX Patch - implements Redhat changes #(upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch -#Deprecate cp -Z/--context non-upstream option -Patch952: coreutils-cpZ-deprecate.patch Conflicts: filesystem < 3 Provides: /bin/basename @@ -129,10 +125,6 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream -%patch1 -p1 -b .strip -%patch2 -p1 -b .aarch64 -%patch3 -p1 -b .nopres -%patch4 -p1 -b .aarch64tests # Our patches %patch100 -p1 -b .configure @@ -152,11 +144,11 @@ the old GNU fileutils, sh-utils, and textutils packages. # Coreutils %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow +%patch913 -p1 -b .testoff #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -%patch952 -p1 -b .cpZ chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh || : @@ -379,6 +371,11 @@ fi %{_sbindir}/chroot %changelog +* Sat Dec 14 2013 Ondrej Vasik 8.22-1 +- new upstream version 8.22 +- temporarily disable multibyte cut.pl part and df symlink + tests + * Thu Dec 12 2013 Ondrej Vasik 8.21-23 - skip output-is-input-mb.p test - failing on armv7l (reported by B.Voelker) diff --git a/sources b/sources index ae40427..a3c519b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -065ba41828644eca5dd8163446de5d64 coreutils-8.21.tar.xz +8fb0ae2267aa6e728958adc38f8163a2 coreutils-8.22.tar.xz From a1f9baa6b8ed1983520a4cc92b9fd0bea9d11e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sun, 15 Dec 2013 09:05:15 +0100 Subject: [PATCH 225/523] Fix the i18n path in cut.c --- coreutils-8.22-temporarytestoff.patch | 19 ------------------- coreutils-i18n.patch | 17 +++++++++-------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/coreutils-8.22-temporarytestoff.patch b/coreutils-8.22-temporarytestoff.patch index 59a7aa1..465b8d7 100644 --- a/coreutils-8.22-temporarytestoff.patch +++ b/coreutils-8.22-temporarytestoff.patch @@ -9,22 +9,3 @@ diff -urNp coreutils-8.22-orig/tests/df/df-symlink.sh coreutils-8.22/tests/df/df disk=$(df --out=source '.' | tail -n1) || skip_ "cannot determine '.' file system" -diff -urNp coreutils-8.22-orig/tests/misc/cut.pl coreutils-8.22/tests/misc/cut.pl ---- coreutils-8.22-orig/tests/misc/cut.pl 2013-12-14 18:18:58.707172051 +0100 -+++ coreutils-8.22/tests/misc/cut.pl 2013-12-14 18:22:14.931010910 +0100 -@@ -23,11 +23,11 @@ use strict; - # Turn off localization of executable's output. - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; - --my $mb_locale; -+my $mb_locale = 'C'; - # uncommented enable multibyte paths --$mb_locale = $ENV{LOCALE_FR_UTF8}; --! defined $mb_locale || $mb_locale eq 'none' -- and $mb_locale = 'C'; -+#$mb_locale = $ENV{LOCALE_FR_UTF8}; -+#! defined $mb_locale || $mb_locale eq 'none' -+# and $mb_locale = 'C'; - - my $prog = 'cut'; - my $try = "Try '$prog --help' for more information.\n"; diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 1ad9c97..664c252 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -219,20 +219,20 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + putchar ('\n'); + idx = 0; + print_delimiter = false; ++ current_rp = rp; + } + else + { + next_item (&idx); -+ bool range_start; -+ bool *rs = output_delimiter_specified ? &range_start : NULL; -+ idx += (operating_mode == byte_mode) ? mblength : 1; ++ //idx += (operating_mode == byte_mode) ? mblength : 1; + if (print_kth (idx)) + { -+ if (rs && *rs && print_delimiter) ++ if (output_delimiter_specified) + { -+ fwrite (output_delimiter_string, sizeof (char), -+ output_delimiter_length, stdout); -+ } ++ 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); + } @@ -247,7 +247,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -629,13 +782,197 @@ cut_fields (FILE *stream) +@@ -629,13 +782,198 @@ cut_fields (FILE *stream) } } @@ -401,6 +401,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c + if (wc == WEOF) + break; + field_idx = 1; ++ current_rp = rp; + found_any_selected_field = 0; + } + } From 3a87513accc907f129d7e22b1fdca94090a20511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 16 Dec 2013 09:42:12 +0100 Subject: [PATCH 226/523] Reduce the unnecessary SELinux stuff(included upstream), enable openssl (libcrypto) support for HASHsum utilities --- coreutils-selinux.patch | 46 ++++------------------------------------- coreutils.spec | 3 ++- 2 files changed, 6 insertions(+), 43 deletions(-) diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 8c668c9..72fe5e2 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,20 +1,3 @@ -diff -urNp coreutils-8.21-orig/configure.ac coreutils-8.21/configure.ac ---- coreutils-8.21-orig/configure.ac 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/configure.ac 2013-02-15 14:31:58.937482694 +0100 -@@ -204,6 +204,13 @@ if test "$gl_gcc_warnings" = yes; then - AC_SUBST([GNULIB_TEST_WARN_CFLAGS]) - fi - -+dnl Give the chance to enable SELINUX -+AC_ARG_ENABLE(selinux, dnl -+[ --enable-selinux Enable use of the SELINUX libraries], -+[AC_DEFINE(WITH_SELINUX, 1, [Define if you want to use SELINUX]) -+LIB_SELINUX="-lselinux" -+AC_SUBST(LIB_SELINUX)]) -+ - AC_FUNC_FORK - - optional_bin_progs= diff -urNp coreutils-8.21-orig/init.cfg coreutils-8.21/init.cfg --- coreutils-8.21-orig/init.cfg 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/init.cfg 2013-02-15 14:31:58.957469955 +0100 @@ -82,11 +65,12 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c long_opts, NULL)) != -1) { -@@ -981,6 +987,16 @@ main (int argc, char **argv) +@@ -981,6 +987,17 @@ main (int argc, char **argv) copy_contents = true; break; + case 'c': ++ fprintf (stderr, "%s: warning: option '-c' is deprecated, please use '--preserve=context' instead", argv[0]); + if ( x.set_security_context ) { + (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]); + exit( 1 ); @@ -132,11 +116,12 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c NULL)) != -1) { switch (optc) -@@ -853,6 +854,7 @@ main (int argc, char **argv) +@@ -853,6 +854,8 @@ main (int argc, char **argv) no_target_directory = true; break; + case 'P': ++ fprintf (stderr, "%s: warning: option '-P' is deprecated, please use '--preserve-context' instead", argv[0]); case PRESERVE_CONTEXT_OPTION: if (! selinux_enabled) { @@ -503,29 +488,6 @@ diff -urNp coreutils-8.21-orig/src/ls.c coreutils-8.21/src/ls.c fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); emit_size_note (); -diff -urNp coreutils-8.21-orig/src/mkdir.c coreutils-8.21/src/mkdir.c ---- coreutils-8.21-orig/src/mkdir.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/mkdir.c 2013-02-15 14:31:58.954469576 +0100 -@@ -38,6 +38,7 @@ - static struct option const longopts[] = - { - {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, -+ {"context", required_argument, NULL, 'Z'}, - {"mode", required_argument, NULL, 'm'}, - {"parents", no_argument, NULL, 'p'}, - {"verbose", no_argument, NULL, 'v'}, -diff -urNp coreutils-8.21-orig/src/mknod.c coreutils-8.21/src/mknod.c ---- coreutils-8.21-orig/src/mknod.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/mknod.c 2013-02-15 14:31:58.955470548 +0100 -@@ -35,7 +35,7 @@ - - static struct option const longopts[] = - { -- {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, -+ {GETOPT_SELINUX_CONTEXT_OPTION_DECL}, - {"mode", required_argument, NULL, 'm'}, - {GETOPT_HELP_OPTION_DECL}, - {GETOPT_VERSION_OPTION_DECL}, diff -urNp coreutils-8.21-orig/tests/misc/selinux.sh coreutils-8.21/tests/misc/selinux.sh --- coreutils-8.21-orig/tests/misc/selinux.sh 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/tests/misc/selinux.sh 2013-02-15 14:31:58.957469955 +0100 diff --git a/coreutils.spec b/coreutils.spec index d8a602f..441b4ef 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -89,6 +89,7 @@ BuildRequires: autoconf BuildRequires: automake BuildRequires: libcap-devel BuildRequires: libattr-devel +BuildRequires: openssl-devel BuildRequires: gmp-devel BuildRequires: attr BuildRequires: strace @@ -166,7 +167,7 @@ aclocal -I m4 autoconf --force automake --copy --add-missing %configure --enable-largefile \ - %{?!noselinux:--enable-selinux} \ + --with-openssl \ --enable-install-program=hostname,arch \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : From 8ff0950897c87414bce85a1e00226eb38541d2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 16 Dec 2013 17:48:21 +0100 Subject: [PATCH 227/523] fix uniq group support in multibyte --- coreutils-i18n.patch | 347 +++++++++++++++++++++++-------------------- 1 file changed, 188 insertions(+), 159 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 664c252..47460b5 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.21-orig/lib/linebuffer.h coreutils-8.21/lib/linebuffer.h ---- coreutils-8.21-orig/lib/linebuffer.h 2013-01-02 13:34:46.000000000 +0100 -+++ coreutils-8.21/lib/linebuffer.h 2013-02-15 14:25:07.758469108 +0100 +diff -urNp coreutils-8.22-orig/lib/linebuffer.h coreutils-8.22/lib/linebuffer.h +--- coreutils-8.22-orig/lib/linebuffer.h 2013-12-04 15:53:33.000000000 +0100 ++++ coreutils-8.22/lib/linebuffer.h 2013-12-16 17:40:25.933887985 +0100 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.21-orig/lib/linebuffer.h coreutils-8.21/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c ---- coreutils-8.21-orig/src/cut.c 2013-02-05 00:40:31.000000000 +0100 -+++ coreutils-8.21/src/cut.c 2013-02-15 14:25:07.760467982 +0100 +diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c +--- coreutils-8.22-orig/src/cut.c 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/src/cut.c 2013-12-16 17:40:25.935887295 +0100 @@ -28,6 +28,11 @@ #include #include @@ -110,7 +110,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c struct range_pair { -@@ -114,15 +178,25 @@ enum operating_mode +@@ -106,15 +169,25 @@ enum operating_mode { undefined_mode, @@ -137,7 +137,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c /* If true do not output lines containing no delimeter characters. Otherwise, all such lines are printed. This option is valid only with field mode. */ -@@ -134,6 +208,9 @@ static bool complement; +@@ -126,6 +199,9 @@ static bool complement; /* The delimeter character for field mode. */ static unsigned char delim; @@ -147,7 +147,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -205,7 +282,7 @@ Print selected parts of lines from each +@@ -188,7 +264,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\ @@ -156,7 +156,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -480,6 +557,9 @@ set_fields (const char *fieldstr) +@@ -381,6 +457,9 @@ set_fields (const char *fieldstr) if (operating_mode == byte_mode) error (0, 0, _("byte offset %s is too large"), quote (bad_num)); @@ -449,7 +449,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c } /* Process file FILE to standard output. -@@ -767,6 +1100,8 @@ main (int argc, char **argv) +@@ -687,6 +1025,8 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -458,7 +458,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -789,7 +1124,6 @@ main (int argc, char **argv) +@@ -709,7 +1049,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -466,7 +466,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -797,6 +1131,14 @@ main (int argc, char **argv) +@@ -717,6 +1056,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -481,7 +481,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -808,10 +1150,36 @@ main (int argc, char **argv) +@@ -728,10 +1075,36 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -522,7 +522,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -824,6 +1191,7 @@ main (int argc, char **argv) +@@ -744,6 +1117,7 @@ main (int argc, char **argv) break; case 'n': @@ -530,7 +530,7 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c break; case 's': -@@ -873,15 +1241,34 @@ main (int argc, char **argv) +@@ -783,15 +1157,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -571,9 +571,9 @@ diff -urNp coreutils-8.21-orig/src/cut.c coreutils-8.21/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.21-orig/src/expand.c coreutils-8.21/src/expand.c ---- coreutils-8.21-orig/src/expand.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/expand.c 2013-02-15 14:25:07.774467536 +0100 +diff -urNp coreutils-8.22-orig/src/expand.c coreutils-8.22/src/expand.c +--- coreutils-8.22-orig/src/expand.c 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/src/expand.c 2013-12-16 17:40:25.936886952 +0100 @@ -37,12 +37,29 @@ #include #include @@ -761,9 +761,9 @@ diff -urNp coreutils-8.21-orig/src/expand.c coreutils-8.21/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.21-orig/src/fold.c coreutils-8.21/src/fold.c ---- coreutils-8.21-orig/src/fold.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/fold.c 2013-02-15 14:25:07.789467891 +0100 +diff -urNp coreutils-8.22-orig/src/fold.c coreutils-8.22/src/fold.c +--- coreutils-8.22-orig/src/fold.c 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/src/fold.c 2013-12-16 17:40:25.938886274 +0100 @@ -22,12 +22,34 @@ #include #include @@ -1161,9 +1161,9 @@ diff -urNp coreutils-8.21-orig/src/fold.c coreutils-8.21/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c ---- coreutils-8.21-orig/src/join.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/join.c 2013-02-15 14:25:07.804467922 +0100 +diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c +--- coreutils-8.22-orig/src/join.c 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/src/join.c 2013-12-16 17:40:25.940885607 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1215,7 +1215,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -262,13 +278,14 @@ xfields (struct line *line) +@@ -269,13 +285,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1233,7 +1233,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c { /* Skip leading blanks before the first field. */ while (isblank (to_uchar (*ptr))) -@@ -292,6 +309,148 @@ xfields (struct line *line) +@@ -299,6 +316,148 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1382,7 +1382,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c static void freeline (struct line *line) { -@@ -313,56 +472,130 @@ keycmp (struct line const *line1, struct +@@ -320,56 +479,130 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1536,7 +1536,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -454,6 +687,11 @@ get_line (FILE *fp, struct line **linep, +@@ -461,6 +694,11 @@ get_line (FILE *fp, struct line **linep, } ++line_no[which - 1]; @@ -1548,7 +1548,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c xfields (line); if (prevline[which - 1]) -@@ -553,21 +791,28 @@ prfield (size_t n, struct line const *li +@@ -560,21 +798,28 @@ prfield (size_t n, struct line const *li /* Output all the fields in line, other than the join field. */ @@ -1580,7 +1580,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c prfield (i, line); } } -@@ -578,7 +823,6 @@ static void +@@ -585,7 +830,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -1588,7 +1588,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c size_t field; struct line const *line; -@@ -612,7 +856,7 @@ prjoin (struct line const *line1, struct +@@ -619,7 +863,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1597,7 +1597,7 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c } putchar (eolchar); } -@@ -1090,21 +1334,46 @@ main (int argc, char **argv) +@@ -1097,21 +1341,46 @@ main (int argc, char **argv) case 't': { @@ -1654,9 +1654,9 @@ diff -urNp coreutils-8.21-orig/src/join.c coreutils-8.21/src/join.c break; case 'z': -diff -urNp coreutils-8.21-orig/src/pr.c coreutils-8.21/src/pr.c ---- coreutils-8.21-orig/src/pr.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/pr.c 2013-02-15 14:25:07.819467936 +0100 +diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c +--- coreutils-8.22-orig/src/pr.c 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/src/pr.c 2013-12-16 17:40:25.944884263 +0100 @@ -312,6 +312,32 @@ #include @@ -2410,9 +2410,9 @@ diff -urNp coreutils-8.21-orig/src/pr.c coreutils-8.21/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c ---- coreutils-8.21-orig/src/sort.c 2013-08-14 18:14:06.172216606 +0200 -+++ coreutils-8.21/src/sort.c 2013-08-14 18:13:30.295247905 +0200 +diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c +--- coreutils-8.22-orig/src/sort.c 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/src/sort.c 2013-12-16 17:40:25.949882582 +0100 @@ -29,6 +29,14 @@ #include #include @@ -2432,8 +2432,8 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c /* Nonzero if the corresponding locales are hard. */ static bool hard_LC_COLLATE; -+#if HAVE_LANGINFO_CODESET -#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET static bool hard_LC_TIME; #endif @@ -2468,20 +2468,20 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c they were read if all keys compare equal. */ static bool stable; -+/* Tab character separating fields. If tab_length is 0, then fields are -/* 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; --static int tab = TAB_DEFAULT; /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -783,6 +811,46 @@ reap_all (void) +@@ -811,6 +839,46 @@ reap_all (void) reap (-1); } @@ -2528,34 +2528,34 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1223,7 +1291,7 @@ zaptemp (char const *name) +@@ -1255,7 +1323,7 @@ zaptemp (char const *name) free (node); } -+#if HAVE_LANGINFO_CODESET -#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET static int struct_month_cmp (void const *m1, void const *m2) -@@ -1238,7 +1306,7 @@ struct_month_cmp (void const *m1, void c +@@ -1270,7 +1338,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void -+inittables_uni (void) -inittables (void) ++inittables_uni (void) { size_t i; -@@ -1250,7 +1318,7 @@ inittables_uni (void) +@@ -1282,7 +1350,7 @@ inittables (void) fold_toupper[i] = toupper (i); } -+#if HAVE_LANGINFO_CODESET -#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) { -@@ -1332,6 +1400,84 @@ specify_nmerge (int oi, char c, char con +@@ -1364,6 +1432,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2640,29 +2640,29 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1564,7 +1710,7 @@ buffer_linelim (struct buffer const *buf +@@ -1597,7 +1743,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * -+begfield_uni (const struct line *line, const struct keyfield *key) -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; -@@ -1573,10 +1719,10 @@ begfield_uni (const struct line *line, c +@@ -1606,10 +1752,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ -+ if (tab_length) - if (tab != TAB_DEFAULT) ++ if (tab_length) while (ptr < lim && sword--) { -+ while (ptr < lim && *ptr != tab[0]) - while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) ++ptr; if (ptr < lim) ++ptr; -@@ -1602,11 +1748,70 @@ begfield_uni (const struct line *line, c +@@ -1635,11 +1781,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2729,38 +2729,38 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c in LINE specified by KEY. */ static char * -+limfield_uni (const struct line *line, const struct keyfield *key) -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; -@@ -1621,10 +1826,10 @@ limfield_uni (const struct line *line, c +@@ -1654,10 +1859,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_length) - if (tab != TAB_DEFAULT) ++ if (tab_length) while (ptr < lim && eword--) { -+ while (ptr < lim && *ptr != tab[0]) - while (ptr < lim && *ptr != tab) ++ while (ptr < lim && *ptr != tab[0]) ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1670,10 +1875,10 @@ limfield_uni (const struct line *line, c +@@ -1703,10 +1908,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ -+ if (tab_length) - if (tab != TAB_DEFAULT) ++ if (tab_length) { char *newlim; -+ newlim = memchr (ptr, tab[0], lim - ptr); - newlim = memchr (ptr, tab, lim - ptr); ++ newlim = memchr (ptr, tab[0], lim - ptr); if (newlim) lim = newlim; } -@@ -1704,6 +1909,130 @@ limfield_uni (const struct line *line, c +@@ -1737,6 +1942,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2891,10 +2891,12 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c /* 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 -@@ -1790,8 +2119,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1823,8 +2152,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) @@ -2911,21 +2913,19 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c + while (blanks[to_uchar (*line_start)]) + line_start++; + } -- while (blanks[to_uchar (*line_start)]) -- line_start++; line->keybeg = line_start; } } -@@ -1912,7 +2255,7 @@ human_numcompare (char const *a, char co +@@ -1945,7 +2288,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int -+numcompare_uni (const char *a, const char *b) -numcompare (char const *a, char const *b) ++numcompare_uni (const char *a, const char *b) { while (blanks[to_uchar (*a)]) a++; -@@ -1922,6 +2265,25 @@ numcompare_uni (const char *a, const cha +@@ -1955,6 +2298,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2951,43 +2951,43 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c /* 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 once -@@ -1972,7 +2334,7 @@ general_numcompare (char const *sa, char +@@ -2005,7 +2367,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int -+getmonth_uni (char const *month, size_t len, char **ea) -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; -@@ -2247,15 +2609,14 @@ debug_key (struct line const *line, stru +@@ -2280,15 +2642,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; -+ skipblanks (&beg, lim); - 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, lim-beg, &tighter_lim); - 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) -@@ -2399,7 +2760,7 @@ key_warnings (struct keyfield const *gke +@@ -2432,7 +2793,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ -+ if (!gkey_only && !tab_length && !line_offset - if (!gkey_only && tab == TAB_DEFAULT && !line_offset ++ if (!gkey_only && !tab_length && !line_offset && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2457,11 +2818,87 @@ key_warnings (struct keyfield const *gke +@@ -2490,11 +2851,87 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -3071,21 +3071,21 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c are no more keys or a difference is found. */ static int -+keycompare_uni (const struct line *a, const struct line *b) -keycompare (struct line const *a, struct line const *b) ++keycompare_uni (const struct line *a, const struct line *b) { struct keyfield *key = keylist; -@@ -2546,7 +2983,7 @@ keycompare_uni (const struct line *a, co +@@ -2579,7 +3016,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) -+ diff = getmonth (ta, tlena, NULL) - getmonth (tb, tlenb, NULL); - 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) -@@ -2662,6 +3099,191 @@ keycompare_uni (const struct line *a, co +@@ -2695,6 +3132,191 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3277,7 +3277,7 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2689,14 +3311,6 @@ compare (struct line const *a, struct li +@@ -2722,14 +3344,6 @@ compare (struct line const *a, struct li diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3292,16 +3292,16 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c else if (! (diff = memcmp (a->text, b->text, MIN (alen, blen)))) diff = alen < blen ? -1 : alen != blen; -@@ -4157,7 +4771,7 @@ main (int argc, char **argv) +@@ -4190,7 +4804,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); -+#if HAVE_LANGINFO_CODESET -#if HAVE_NL_LANGINFO ++#if HAVE_LANGINFO_CODESET hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4178,6 +4792,29 @@ main (int argc, char **argv) +@@ -4211,6 +4825,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3331,17 +3331,18 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c have_read_stdin = false; inittables (); -@@ -4452,13 +5089,34 @@ main (int argc, char **argv) +@@ -4485,13 +5122,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]) -- char newtab = optarg[0]; -- if (! newtab) error (SORT_FAILURE, 0, _("empty tab")); +- if (optarg[1]) +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) + { @@ -3362,32 +3363,31 @@ diff -urNp coreutils-8.21-orig/src/sort.c coreutils-8.21/src/sort.c + } +#endif + if (newtab_length == 1 && optarg[1]) -- if (optarg[1]) { if (STREQ (optarg, "\\0")) -+ newtab[0] = '\0'; - newtab = '\0'; ++ newtab[0] = '\0'; else { /* Provoke with 'sort -txx'. Complain about -@@ -4469,9 +5127,12 @@ main (int argc, char **argv) +@@ -4502,9 +5160,12 @@ 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)) -- if (tab != TAB_DEFAULT && tab != newtab) error (SORT_FAILURE, 0, _("incompatible tabs")); +- tab = newtab; + memcpy (tab, newtab, newtab_length); + tab_length = newtab_length; -- tab = newtab; } break; -diff -urNp coreutils-8.21-orig/src/unexpand.c coreutils-8.21/src/unexpand.c ---- coreutils-8.21-orig/src/unexpand.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/unexpand.c 2013-02-15 14:25:07.834467715 +0100 +diff -urNp coreutils-8.22-orig/src/unexpand.c coreutils-8.22/src/unexpand.c +--- coreutils-8.22-orig/src/unexpand.c 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/src/unexpand.c 2013-12-16 17:40:25.951881910 +0100 @@ -38,12 +38,29 @@ #include #include @@ -3629,7 +3629,7 @@ diff -urNp coreutils-8.21-orig/src/unexpand.c coreutils-8.21/src/unexpand.c void usage (int status) { -@@ -523,7 +742,12 @@ main (int argc, char **argv) +@@ -523,7 +744,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -3643,9 +3643,9 @@ diff -urNp coreutils-8.21-orig/src/unexpand.c coreutils-8.21/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c ---- coreutils-8.21-orig/src/uniq.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/uniq.c 2013-02-15 14:25:07.839467991 +0100 +diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c +--- coreutils-8.22-orig/src/uniq.c 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/src/uniq.c 2013-12-16 17:41:06.711697074 +0100 @@ -21,6 +21,16 @@ #include #include @@ -3684,7 +3684,7 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -108,6 +130,10 @@ +@@ -143,6 +165,10 @@ enum GROUP_OPTION = CHAR_MAX + 1 }; @@ -3695,7 +3695,7 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -205,7 +231,7 @@ size_opt (char const *opt, char const *m +@@ -249,7 +275,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 @@ -3704,7 +3704,7 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -225,6 +251,83 @@ find_field (struct linebuffer const *lin +@@ -269,6 +295,83 @@ find_field (struct linebuffer const *lin return line->buffer + i; } @@ -3788,7 +3788,7 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c /* 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. -@@ -233,6 +336,8 @@ find_field (struct linebuffer const *lin +@@ -277,6 +380,8 @@ find_field (struct linebuffer const *lin static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -3797,7 +3797,7 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -240,14 +345,100 @@ different (char *old, char *new, size_t +@@ -284,14 +389,100 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3903,7 +3903,7 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -303,18 +494,45 @@ check_file (const char *infile, const ch +@@ -356,18 +547,55 @@ check_file (const char *infile, const ch char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); bool first_group_printed = false; @@ -3928,12 +3928,20 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) ++ if (MB_CUR_MAX > 1) + { + thisstate = thisline->state; + -+ if (prevline->length == 0 || different_multi -+ (thisfield, prevfield, thislen, prevlen, thisstate, prevstate)) ++ new_group = (prevline->length == 0 || different_multi ++ (thisfield, prevfield, thislen, prevlen, thisstate, prevstate)); ++ ++ if (new_group && grouping != GM_NONE ++ && (grouping == GM_PREPEND || grouping == GM_BOTH ++ || (first_group_printed && (grouping == GM_APPEND ++ || grouping == GM_SEPARATE)))) ++ putchar (delimiter); ++ ++ if (new_group || grouping != GM_NONE) + { + fwrite (thisline->buffer, sizeof (char), + thisline->length, stdout); @@ -3942,14 +3950,35 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c + prevfield = thisfield; + prevlen = thislen; + prevstate = thisstate; ++ first_group_printed = true; + } + } + else ++ { +#endif new_group = (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)); -@@ -330,17 +549,26 @@ check_file (const char *infile, const ch +@@ -376,7 +604,7 @@ check_file (const char *infile, const ch + && (grouping == GM_PREPEND || grouping == GM_BOTH + || (first_group_printed && (grouping == GM_APPEND + || grouping == GM_SEPARATE)))) +- putchar (delimiter); ++ putchar (delimiter); + + if (new_group || grouping != GM_NONE) + { +@@ -388,6 +616,9 @@ check_file (const char *infile, const ch + prevlen = thislen; + first_group_printed = true; + } ++#if HAVE_MBRTOWC ++ } ++#endif + } + if ((grouping == GM_BOTH || grouping == GM_APPEND) && first_group_printed) + putchar (delimiter); +@@ -398,17 +629,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -3976,7 +4005,7 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -349,6 +577,14 @@ check_file (const char *infile, const ch +@@ -417,6 +657,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -3991,7 +4020,7 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -381,6 +617,9 @@ check_file (const char *infile, const ch +@@ -449,6 +697,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4001,7 +4030,7 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c if (!match) match_count = 0; } -@@ -426,6 +665,19 @@ main (int argc, char **argv) +@@ -495,6 +746,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4021,10 +4050,10 @@ diff -urNp coreutils-8.21-orig/src/uniq.c coreutils-8.21/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk ---- coreutils-8.21-orig/tests/local.mk 2013-02-15 14:24:32.645654553 +0100 -+++ coreutils-8.21/tests/local.mk 2013-02-15 14:25:07.873467648 +0100 -@@ -325,6 +325,7 @@ all_tests = \ +diff -urNp coreutils-8.22-orig/tests/local.mk coreutils-8.22/tests/local.mk +--- coreutils-8.22-orig/tests/local.mk 2013-12-16 17:39:49.187181544 +0100 ++++ coreutils-8.22/tests/local.mk 2013-12-16 17:40:25.955880566 +0100 +@@ -324,6 +324,7 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -4032,9 +4061,9 @@ diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ tests/misc/sort-month.sh \ -diff -urNp coreutils-8.21-orig/tests/misc/cut.pl coreutils-8.21/tests/misc/cut.pl ---- coreutils-8.21-orig/tests/misc/cut.pl 2013-02-05 00:40:31.000000000 +0100 -+++ coreutils-8.21/tests/misc/cut.pl 2013-11-27 19:47:58.430539269 +0100 +diff -urNp coreutils-8.22-orig/tests/misc/cut.pl coreutils-8.22/tests/misc/cut.pl +--- coreutils-8.22-orig/tests/misc/cut.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/cut.pl 2013-12-16 17:40:25.956880230 +0100 @@ -23,9 +23,11 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4049,7 +4078,7 @@ diff -urNp coreutils-8.21-orig/tests/misc/cut.pl coreutils-8.21/tests/misc/cut.p my $prog = 'cut'; my $try = "Try '$prog --help' for more information.\n"; -@@ -224,6 +226,7 @@ +@@ -225,6 +227,7 @@ if ($mb_locale ne 'C') my @new_t = @$t; my $test_name = shift @new_t; @@ -4057,9 +4086,9 @@ diff -urNp coreutils-8.21-orig/tests/misc/cut.pl coreutils-8.21/tests/misc/cut.p push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; } push @Tests, @new; -diff -urNp coreutils-8.21-orig/tests/misc/expand.pl coreutils-8.21/tests/misc/expand.pl ---- coreutils-8.21-orig/tests/misc/expand.pl 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/tests/misc/expand.pl 2013-11-27 19:47:58.431538769 +0100 +diff -urNp coreutils-8.22-orig/tests/misc/expand.pl coreutils-8.22/tests/misc/expand.pl +--- coreutils-8.22-orig/tests/misc/expand.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/expand.pl 2013-12-16 17:40:25.957879894 +0100 @@ -23,6 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4114,9 +4143,9 @@ diff -urNp coreutils-8.21-orig/tests/misc/expand.pl coreutils-8.21/tests/misc/ex my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.21-orig/tests/misc/fold.pl coreutils-8.21/tests/misc/fold.pl ---- coreutils-8.21-orig/tests/misc/fold.pl 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/tests/misc/fold.pl 2013-11-27 19:47:58.431538769 +0100 +diff -urNp coreutils-8.22-orig/tests/misc/fold.pl coreutils-8.22/tests/misc/fold.pl +--- coreutils-8.22-orig/tests/misc/fold.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/fold.pl 2013-12-16 17:40:25.958879558 +0100 @@ -20,9 +20,18 @@ use strict; (my $program_name = $0) =~ s|.*/||; @@ -4186,9 +4215,9 @@ diff -urNp coreutils-8.21-orig/tests/misc/fold.pl coreutils-8.21/tests/misc/fold -my $prog = 'fold'; my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; -diff -urNp coreutils-8.21-orig/tests/misc/join.pl coreutils-8.21/tests/misc/join.pl ---- coreutils-8.21-orig/tests/misc/join.pl 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/tests/misc/join.pl 2013-11-27 19:47:58.432538269 +0100 +diff -urNp coreutils-8.22-orig/tests/misc/join.pl coreutils-8.22/tests/misc/join.pl +--- coreutils-8.22-orig/tests/misc/join.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/join.pl 2013-12-16 17:40:25.959879222 +0100 @@ -25,6 +25,15 @@ my $limits = getlimits (); my $prog = 'join'; @@ -4205,7 +4234,7 @@ diff -urNp coreutils-8.21-orig/tests/misc/join.pl coreutils-8.21/tests/misc/join my $delim = chr 0247; sub t_subst ($) { -@@ -306,8 +315,49 @@ foreach my $t (@tv) +@@ -326,8 +335,49 @@ foreach my $t (@tv) push @Tests, $new_ent; } @@ -4255,9 +4284,9 @@ diff -urNp coreutils-8.21-orig/tests/misc/join.pl coreutils-8.21/tests/misc/join my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.21-orig/tests/misc/sort-mb-tests.sh coreutils-8.21/tests/misc/sort-mb-tests.sh ---- coreutils-8.21-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.21/tests/misc/sort-mb-tests.sh 2013-02-18 17:44:03.852275681 +0100 +diff -urNp coreutils-8.22-orig/tests/misc/sort-mb-tests.sh coreutils-8.22/tests/misc/sort-mb-tests.sh +--- coreutils-8.22-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.22/tests/misc/sort-mb-tests.sh 2013-12-16 17:40:25.959879222 +0100 @@ -0,0 +1,45 @@ +#!/bin/sh +# Verify sort's multi-byte support. @@ -4304,9 +4333,9 @@ diff -urNp coreutils-8.21-orig/tests/misc/sort-mb-tests.sh coreutils-8.21/tests/ +compare exp out || { fail=1; cat out; } + +Exit $fail -diff -urNp coreutils-8.21-orig/tests/misc/sort-merge.pl coreutils-8.21/tests/misc/sort-merge.pl ---- coreutils-8.21-orig/tests/misc/sort-merge.pl 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/tests/misc/sort-merge.pl 2013-11-27 19:47:58.435536769 +0100 +diff -urNp coreutils-8.22-orig/tests/misc/sort-merge.pl coreutils-8.22/tests/misc/sort-merge.pl +--- coreutils-8.22-orig/tests/misc/sort-merge.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/sort-merge.pl 2013-12-16 17:40:25.960878886 +0100 @@ -26,6 +26,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4363,9 +4392,9 @@ diff -urNp coreutils-8.21-orig/tests/misc/sort-merge.pl coreutils-8.21/tests/mis my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.21-orig/tests/misc/sort.pl coreutils-8.21/tests/misc/sort.pl ---- coreutils-8.21-orig/tests/misc/sort.pl 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/tests/misc/sort.pl 2013-11-27 19:47:58.436536269 +0100 +diff -urNp coreutils-8.22-orig/tests/misc/sort.pl coreutils-8.22/tests/misc/sort.pl +--- coreutils-8.22-orig/tests/misc/sort.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/sort.pl 2013-12-16 17:40:25.962878214 +0100 @@ -24,10 +24,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4383,11 +4412,10 @@ diff -urNp coreutils-8.21-orig/tests/misc/sort.pl coreutils-8.21/tests/misc/sort # 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 '-'. -@@ -414,6 +419,37 @@ - and push (@$t, {ENV=>'_POSIX2_VERSION=199209'}), last; +@@ -415,6 +420,37 @@ foreach my $t (@Tests) } } -+ + +if ($mb_locale ne 'C') + { + # Duplicate each test vector, appending "-mb" to the test name and @@ -4418,9 +4446,10 @@ diff -urNp coreutils-8.21-orig/tests/misc/sort.pl coreutils-8.21/tests/misc/sort + } + push @Tests, @new; + } - ++ @Tests = triple_test \@Tests; + # Remember that triple_test creates from each test with exactly one "IN" @@ -424,6 +460,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. @@ -4429,9 +4458,9 @@ diff -urNp coreutils-8.21-orig/tests/misc/sort.pl coreutils-8.21/tests/misc/sort my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.21-orig/tests/misc/unexpand.pl coreutils-8.21/tests/misc/unexpand.pl ---- coreutils-8.21-orig/tests/misc/unexpand.pl 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/tests/misc/unexpand.pl 2013-11-27 19:47:58.436536269 +0100 +diff -urNp coreutils-8.22-orig/tests/misc/unexpand.pl coreutils-8.22/tests/misc/unexpand.pl +--- coreutils-8.22-orig/tests/misc/unexpand.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/unexpand.pl 2013-12-16 17:40:25.962878214 +0100 @@ -27,6 +27,14 @@ my $limits = getlimits (); my $prog = 'unexpand'; @@ -4485,9 +4514,9 @@ diff -urNp coreutils-8.21-orig/tests/misc/unexpand.pl coreutils-8.21/tests/misc/ my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.21-orig/tests/misc/uniq.pl coreutils-8.21/tests/misc/uniq.pl ---- coreutils-8.21-orig/tests/misc/uniq.pl 2013-01-31 01:46:25.000000000 +0100 -+++ coreutils-8.21/tests/misc/uniq.pl 2013-11-27 19:47:58.437535769 +0100 +diff -urNp coreutils-8.22-orig/tests/misc/uniq.pl coreutils-8.22/tests/misc/uniq.pl +--- coreutils-8.22-orig/tests/misc/uniq.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/uniq.pl 2013-12-16 17:41:34.077961751 +0100 @@ -23,9 +23,17 @@ my $limits = getlimits (); my $prog = 'uniq'; my $try = "Try '$prog --help' for more information.\n"; @@ -4506,11 +4535,10 @@ diff -urNp coreutils-8.21-orig/tests/misc/uniq.pl coreutils-8.21/tests/misc/uniq # When possible, create a "-z"-testing variant of each test. sub add_z_variants($) { -@@ -207,7 +215,45 @@ - $t->[0] =~ /^obs-plus/ +@@ -261,6 +269,45 @@ 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 @@ -4534,12 +4562,13 @@ diff -urNp coreutils-8.21-orig/tests/misc/uniq.pl coreutils-8.21/tests/misc/uniq + push @new_t, $sub; + push @$t, $sub; + } -+ next if ($test_name =~ "schar" or $test_name =~ "^obs-plus" or $test_name =~ "119" or $test_name =~ "128" or $test_name =~ "129" or $test_name =~ "130" or $test_name =~ "131" or $test_name =~ "132" or $test_name =~ "133" or $test_name =~ "145"); ++ next if ($test_name =~ "schar" or $test_name =~ "^obs-plus" ++ or $test_name =~ "119" or $test_name =~ "145"); + 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 @@ -4552,9 +4581,9 @@ diff -urNp coreutils-8.21-orig/tests/misc/uniq.pl coreutils-8.21/tests/misc/uniq @Tests = add_z_variants \@Tests; @Tests = triple_test \@Tests; -diff -urNp coreutils-8.21-orig/tests/pr/pr-tests.pl coreutils-8.21/tests/pr/pr-tests.pl ---- coreutils-8.21-orig/tests/pr/pr-tests.pl 2013-01-31 01:46:25.000000000 +0100 -+++ coreutils-8.21/tests/pr/pr-tests.pl 2013-11-27 19:48:12.683409258 +0100 +diff -urNp coreutils-8.22-orig/tests/pr/pr-tests.pl coreutils-8.22/tests/pr/pr-tests.pl +--- coreutils-8.22-orig/tests/pr/pr-tests.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/pr/pr-tests.pl 2013-12-16 17:40:25.965877206 +0100 @@ -23,6 +23,15 @@ use strict; my $prog = 'pr'; From a504f0affed3b342299284931925c09dc2c48f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 16 Dec 2013 18:55:30 +0100 Subject: [PATCH 228/523] Add some info about the failing test (shouldn't fail in rawhide and in common cases, it is not a regression (more probably incomplete fix in coreutils-8.22) --- coreutils-8.22-temporarytestoff.patch | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/coreutils-8.22-temporarytestoff.patch b/coreutils-8.22-temporarytestoff.patch index 465b8d7..c95343b 100644 --- a/coreutils-8.22-temporarytestoff.patch +++ b/coreutils-8.22-temporarytestoff.patch @@ -1,10 +1,12 @@ diff -urNp coreutils-8.22-orig/tests/df/df-symlink.sh coreutils-8.22/tests/df/df-symlink.sh --- coreutils-8.22-orig/tests/df/df-symlink.sh 2013-12-04 15:48:30.000000000 +0100 +++ coreutils-8.22/tests/df/df-symlink.sh 2013-12-14 18:20:15.822594995 +0100 -@@ -18,6 +18,7 @@ +@@ -18,6 +18,9 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ df ++#df doesn't work correctly on symlinks when on LVM/LUKS filesystem, therefore ++#marking expensive_ to disable by default +expensive_ disk=$(df --out=source '.' | tail -n1) || From 6f9637e5253d7e5e314de92369d2b3784b4c7475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 17 Dec 2013 22:24:10 +0100 Subject: [PATCH 229/523] cut - Fix the variables in multibyte path to work on 64 bit --- coreutils-i18n.patch | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 47460b5..45ce918 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -166,7 +166,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c else error (0, 0, _("field number %s is too large"), quote (bad_num)); -@@ -505,6 +584,80 @@ cut_bytes (FILE *stream) +@@ -505,6 +584,79 @@ cut_bytes (FILE *stream) } } @@ -182,7 +182,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c +static void +cut_characters_or_cut_bytes_no_split (FILE *stream) +{ -+ int idx; /* number of bytes or characters in the line so far. */ ++ size_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. */ @@ -224,7 +224,6 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + else + { + next_item (&idx); -+ //idx += (operating_mode == byte_mode) ? mblength : 1; + if (print_kth (idx)) + { + if (output_delimiter_specified) @@ -256,7 +255,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c +cut_fields_mb (FILE *stream) +{ + int c; -+ unsigned int field_idx; ++ size_t field_idx; + int found_any_selected_field; + int buffer_first_field; + int empty_input; From bbc81312d74af76b8a54830a3eb2a25a37c7c56f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 18 Dec 2013 17:13:25 +0100 Subject: [PATCH 230/523] Related:#1043552 - add new lines into deprecations. --- coreutils-selinux.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 72fe5e2..97e0fcf 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -70,7 +70,7 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c break; + case 'c': -+ fprintf (stderr, "%s: warning: option '-c' is deprecated, please use '--preserve=context' instead", argv[0]); ++ fprintf (stderr, "%s: warning: option '-c' is deprecated, please use '--preserve=context' instead\n", argv[0]); + if ( x.set_security_context ) { + (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]); + exit( 1 ); @@ -121,7 +121,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c break; + case 'P': -+ fprintf (stderr, "%s: warning: option '-P' is deprecated, please use '--preserve-context' instead", argv[0]); ++ fprintf (stderr, "%s: warning: option '-P' is deprecated, please use '--preserve-context' instead\n", argv[0]); case PRESERVE_CONTEXT_OPTION: if (! selinux_enabled) { From 9268947eab4204c86e3fb663c1cb33b21ec4ae5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 18 Dec 2013 23:41:42 +0100 Subject: [PATCH 231/523] update dircolors --- coreutils-DIR_COLORS | 6 ++++++ coreutils-DIR_COLORS.256color | 3 +++ coreutils-DIR_COLORS.lightbgcolor | 2 ++ 3 files changed, 11 insertions(+) diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 304463a..6abc937 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -44,6 +44,7 @@ TERM linux-c TERM mach-color TERM mlterm TERM putty +TERM putty-256color TERM rxvt TERM rxvt-256color TERM rxvt-cygwin @@ -56,8 +57,11 @@ TERM screen-256color TERM screen-256color-bce TERM screen-bce TERM screen-w +TERM screen.Eterm TERM screen.rxvt TERM screen.linux +TERM st +TERM st-256color TERM terminator TERM vt100 TERM xterm @@ -121,6 +125,7 @@ EXEC 01;32 .arj 01;31 .taz 01;31 .lha 01;31 +.lz4 01;31 .lzh 01;31 .lzma 01;31 .tlz 01;31 @@ -179,6 +184,7 @@ EXEC 01;32 .mpeg 01;35 .m2v 01;35 .mkv 01;35 +.webm 01;35 .ogm 01;35 .mp4 01;35 .m4v 01;35 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 2d2a530..4efaca1 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -28,6 +28,7 @@ TERM rxvt-unicode256 TERM screen-256color TERM xterm-256color TERM gnome-256color +TERM st-256color # EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) EIGHTBIT 1 @@ -94,6 +95,7 @@ EXEC 38;5;34 .arj 38;5;9 .taz 38;5;9 .lha 38;5;9 +.lz4 38;5;9 .lzh 38;5;9 .lzma 38;5;9 .tlz 38;5;9 @@ -152,6 +154,7 @@ EXEC 38;5;34 .mpeg 38;5;13 .m2v 38;5;13 .mkv 38;5;13 +.webm 38;5;13 .ogm 38;5;13 .mp4 38;5;13 .m4v 38;5;13 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index efb5163..43820b2 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -98,6 +98,7 @@ EXEC 00;32 .arj 00;31 .taz 00;31 .lha 00;31 +.lz4 00;31 .lzh 00;31 .lzma 00;31 .tlz 00;31 @@ -156,6 +157,7 @@ EXEC 00;32 .mpeg 00;35 .m2v 00;35 .mkv 00;35 +.webm 00;35 .ogm 00;35 .mp4 00;35 .m4v 00;35 From f1ce0c900054cf56eb0db3f528a99fd56cb87439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 19 Dec 2013 11:09:01 +0100 Subject: [PATCH 232/523] reset buffer before copying to prevent some rare cases of invalid output in join and uniq(#1036289) --- coreutils-i18n.patch | 4 ++-- coreutils.spec | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 45ce918..94d868f 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1452,7 +1452,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c + for (i = 0; i < 2; i++) + { + mallocd = 1; -+ copy[i] = xmalloc (len[i] + 1); ++ copy[i] = xcalloc (0, len[i] + 1); + + for (j = 0; j < MIN (len[0], len[1]);) + { @@ -3852,7 +3852,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c + + for (i = 0; i < 2; i++) + { -+ copy[i] = xmalloc (len[i] + 1); ++ copy[i] = xcalloc (0, len[i] + 1); + + for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) + { diff --git a/coreutils.spec b/coreutils.spec index 441b4ef..5238e50 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,10 @@ fi %{_sbindir}/chroot %changelog +* Thu Dec 19 2013 Ondrej Vasik 8.22-2 +- reset buffer before copying to prevent some rare cases of + invalid output in join and uniq(#1036289) + * Sat Dec 14 2013 Ondrej Vasik 8.22-1 - new upstream version 8.22 - temporarily disable multibyte cut.pl part and df symlink From 94edc2ddc86b1f3e70c1cb8bff0a777641f4b9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sun, 22 Dec 2013 16:39:13 +0100 Subject: [PATCH 233/523] Fix the sigabrt caused by 8.22-2 --- coreutils-i18n.patch | 10 ++++++---- coreutils.spec | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 94d868f..d2b2b2a 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1381,7 +1381,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c static void freeline (struct line *line) { -@@ -320,56 +479,130 @@ keycmp (struct line const *line1, struct +@@ -320,56 +479,131 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1452,7 +1452,8 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c + for (i = 0; i < 2; i++) + { + mallocd = 1; -+ copy[i] = xcalloc (0, len[i] + 1); ++ copy[i] = xmalloc (len[i] + 1); ++ memset (copy[i], '\0',len[i] + 1); + + for (j = 0; j < MIN (len[0], len[1]);) + { @@ -3796,7 +3797,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -284,14 +389,100 @@ different (char *old, char *new, size_t +@@ -284,14 +389,101 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3852,7 +3853,8 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c + + for (i = 0; i < 2; i++) + { -+ copy[i] = xcalloc (0, len[i] + 1); ++ copy[i] = xmalloc (len[i] + 1); ++ memset (copy[i], '\0', len[i] + 1); + + for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) + { diff --git a/coreutils.spec b/coreutils.spec index 5238e50..64067bd 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,7 +372,7 @@ fi %{_sbindir}/chroot %changelog -* Thu Dec 19 2013 Ondrej Vasik 8.22-2 +* Sun Dec 22 2013 Ondrej Vasik 8.22-3 - reset buffer before copying to prevent some rare cases of invalid output in join and uniq(#1036289) From 7a1c1f897513cee85365042605a0091e799d22fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 23 Dec 2013 10:50:56 +0100 Subject: [PATCH 234/523] skip even the ls aliases in noninteractive mode (suggested by T. Cordes, #988152) --- coreutils-colorls.csh | 3 +++ coreutils-colorls.sh | 7 +++---- coreutils.spec | 6 +++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index f2138a9..38abdc7 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -1,3 +1,6 @@ +# skip everything for non-interactive shells +if (! $?prompt) exit + # color-ls initialization if ( $?USER_LS_COLORS ) then if ( "$USER_LS_COLORS" != "" ) then diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index c71e357..f1b227b 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -1,15 +1,14 @@ # color-ls initialization +# Skip all for noninteractive shells. +[ -z "$PS1" ] && return + #when USER_LS_COLORS defined do not override user LS_COLORS, but use them. if [ -z "$USER_LS_COLORS" ]; then alias ll='ls -l' 2>/dev/null alias l.='ls -d .*' 2>/dev/null - - # Skip the rest for noninteractive shells. - [ -z "$PS1" ] && return - INCLUDE= COLORS= diff --git a/coreutils.spec b/coreutils.spec index 64067bd..c318d68 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,10 @@ fi %{_sbindir}/chroot %changelog +* Mon Dec 23 2013 Ondrej Vasik 8.22-4 +- skip even the ls aliases in noninteractive mode + (suggested by T. Cordes, #988152) + * Sun Dec 22 2013 Ondrej Vasik 8.22-3 - reset buffer before copying to prevent some rare cases of invalid output in join and uniq(#1036289) From 83c13991c9cb75ed0892af725dcba41395371f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 2 Jan 2014 11:39:46 +0100 Subject: [PATCH 235/523] Disable wrong selinux handling in cp -a, document SELinux related deprecated downstream options --- coreutils-selinux.patch | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 97e0fcf..b6a38cb 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -43,6 +43,22 @@ diff -urNp coreutils-8.21-orig/src/copy.c coreutils-8.21/src/copy.c } else { +@@ -2600,6 +2600,7 @@ copy_internal (char const *src_name, cha + + /* With -Z or --preserve=context, set the context for existing files. + Note this is done already for copy_reg() for reasons described therein. */ ++ /* + if (!new_dst && !x->copy_as_regular + && (x->set_security_context || x->preserve_security_context)) + { +@@ -2610,6 +2611,7 @@ copy_internal (char const *src_name, cha + goto un_backup; + } + } ++ Temporarily disabled, it screws up the destination CTX for cp -a */ + + if (command_line_arg && x->dest_info) + { diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c --- coreutils-8.21-orig/src/cp.c 2013-02-07 10:37:05.000000000 +0100 +++ coreutils-8.21/src/cp.c 2013-02-15 14:31:58.945468929 +0100 @@ -50,7 +66,7 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c all\n\ "), stdout); fputs (_("\ -+ -c same as --preserve=context\n\ ++ -c deprecated, same as --preserve=context\n\ +"), stdout); + fputs (_("\ --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ @@ -103,7 +119,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c "), stdout); fputs (_("\ - --preserve-context preserve SELinux security context\n\ -+ -P, --preserve-context preserve SELinux security context\n\ ++ -P, --preserve-context preserve SELinux security context (-P deprecated)\n\ -Z, --context[=CTX] set SELinux security context of destination file to\n\ default type, or to CTX if specified\n\ "), stdout); From d6d7448c6afa004f993852ac830f9487ab3a4ea7 Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Thu, 2 Jan 2014 21:29:20 +0100 Subject: [PATCH 236/523] reverted an old change and constricted it's condition, turned off two multibyte tests (wrong strcoll return value) --- coreutils-i18n.patch | 85 ++++++++++++++++++++++++-------------------- coreutils.spec | 6 +++- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index d2b2b2a..5674d8c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2412,7 +2412,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c --- coreutils-8.22-orig/src/sort.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/sort.c 2013-12-16 17:40:25.949882582 +0100 ++++ coreutils-8.22/src/sort.c 2014-01-02 21:17:32.802621367 +0100 @@ -29,6 +29,14 @@ #include #include @@ -2428,8 +2428,13 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -166,12 +174,34 @@ static int thousands_sep; +@@ -164,14 +172,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 @@ -2464,7 +2469,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -345,13 +375,11 @@ static bool reverse; +@@ -345,13 +378,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -2481,7 +2486,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -811,6 +839,46 @@ reap_all (void) +@@ -811,6 +842,46 @@ reap_all (void) reap (-1); } @@ -2528,7 +2533,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1255,7 +1323,7 @@ zaptemp (char const *name) +@@ -1255,7 +1326,7 @@ zaptemp (char const *name) free (node); } @@ -2537,7 +2542,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1270,7 +1338,7 @@ struct_month_cmp (void const *m1, void c +@@ -1270,7 +1341,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2546,7 +2551,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { size_t i; -@@ -1282,7 +1350,7 @@ inittables (void) +@@ -1282,7 +1353,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2555,7 +2560,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1364,6 +1432,84 @@ specify_nmerge (int oi, char c, char con +@@ -1364,6 +1435,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2640,7 +2645,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1597,7 +1743,7 @@ buffer_linelim (struct buffer const *buf +@@ -1597,7 +1746,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2649,7 +2654,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1606,10 +1752,10 @@ begfield (struct line const *line, struc +@@ -1606,10 +1755,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2662,7 +2667,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1635,11 +1781,70 @@ begfield (struct line const *line, struc +@@ -1635,11 +1784,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2734,7 +2739,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1654,10 +1859,10 @@ limfield (struct line const *line, struc +@@ -1654,10 +1862,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. */ @@ -2747,7 +2752,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1703,10 +1908,10 @@ limfield (struct line const *line, struc +@@ -1703,10 +1911,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2760,7 +2765,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c if (newlim) lim = newlim; } -@@ -1737,6 +1942,130 @@ limfield (struct line const *line, struc +@@ -1737,6 +1945,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2891,7 +2896,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* 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 -@@ -1823,8 +2152,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1823,8 +2155,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2916,7 +2921,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c line->keybeg = line_start; } } -@@ -1945,7 +2288,7 @@ human_numcompare (char const *a, char co +@@ -1945,7 +2291,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2925,7 +2930,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1955,6 +2298,25 @@ numcompare (char const *a, char const *b +@@ -1955,6 +2301,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2951,7 +2956,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* 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 once -@@ -2005,7 +2367,7 @@ general_numcompare (char const *sa, char +@@ -2005,7 +2370,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -2960,7 +2965,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2280,15 +2642,14 @@ debug_key (struct line const *line, stru +@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -2978,7 +2983,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2432,7 +2793,7 @@ key_warnings (struct keyfield const *gke +@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2987,7 +2992,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2490,11 +2851,87 @@ key_warnings (struct keyfield const *gke +@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -3076,7 +3081,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { struct keyfield *key = keylist; -@@ -2579,7 +3016,7 @@ keycompare (struct line const *a, struct +@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3085,7 +3090,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2695,6 +3132,191 @@ keycompare (struct line const *a, struct +@@ -2695,6 +3135,191 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3277,22 +3282,24 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2722,14 +3344,6 @@ compare (struct line const *a, struct li +@@ -2722,7 +3347,7 @@ compare (struct line const *a, struct li diff = - NONZERO (blen); else if (blen == 0) diff = 1; - else if (hard_LC_COLLATE) -- { -- /* Note xmemcoll0 is a performance enhancement as -- it will not unconditionally write '\0' after the -- passed in buffers, which was seen to give around -- a 3% increase in performance for short lines. */ -- diff = xmemcoll0 (a->text, alen + 1, b->text, blen + 1); -- } - else if (! (diff = memcmp (a->text, b->text, MIN (alen, blen)))) - diff = alen < blen ? -1 : alen != blen; - -@@ -4190,7 +4804,7 @@ main (int argc, char **argv) ++ else if (hard_LC_COLLATE && !folding) + { + /* Note xmemcoll0 is a performance enhancement as + it will not unconditionally write '\0' after the +@@ -4113,6 +4738,7 @@ set_ordering (char const *s, struct keyf + break; + case 'f': + key->translate = fold_toupper; ++ folding = true; + break; + case 'g': + key->general_numeric = true; +@@ -4190,7 +4816,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3301,7 +3308,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4211,6 +4825,29 @@ main (int argc, char **argv) +@@ -4211,6 +4837,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3331,7 +3338,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c have_read_stdin = false; inittables (); -@@ -4485,13 +5122,34 @@ main (int argc, char **argv) +@@ -4485,13 +5134,34 @@ main (int argc, char **argv) case 't': { @@ -3370,7 +3377,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4502,9 +5160,12 @@ main (int argc, char **argv) +@@ -4502,9 +5172,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4442,7 +4449,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/sort.pl coreutils-8.22/tests/misc/sort + } + #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"); ++ 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"); + push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; + } + push @Tests, @new; diff --git a/coreutils.spec b/coreutils.spec index c318d68..495c7c7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,10 @@ fi %{_sbindir}/chroot %changelog +* Thu Jan 02 2014 Ondrej Oprala 8.22-5 +- reverted an old change and constricted it's condition +- turned off two multibyte tests (wrong strcoll return value) + * Mon Dec 23 2013 Ondrej Vasik 8.22-4 - skip even the ls aliases in noninteractive mode (suggested by T. Cordes, #988152) From 31d3fdd0404956720caf26e77759fea317bd3a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 3 Jan 2014 08:38:06 +0100 Subject: [PATCH 237/523] do not modify SELinux contexts of existing parent directories when copying files (fix by P.Brady, #1045122) --- coreutils-selinux.patch | 35 +++++++++++++++++++++++------------ coreutils.spec | 6 +++++- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index b6a38cb..928ef95 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -34,7 +34,25 @@ diff -urNp coreutils-8.21-orig/man/runcon.x coreutils-8.21/man/runcon.x diff -urNp coreutils-8.21-orig/src/copy.c coreutils-8.21/src/copy.c --- coreutils-8.21-orig/src/copy.c 2013-02-07 10:37:05.000000000 +0100 +++ coreutils-8.21/src/copy.c 2013-02-15 14:31:58.941467872 +0100 -@@ -2315,6 +2315,8 @@ copy_internal (char const *src_name, cha +@@ -2410,6 +2410,17 @@ copy_internal (char const *src_name, cha + else + { + omitted_permissions = 0; ++ ++ /* For directories, the process global context could be reset for ++ descendents, so use it to set the context for existing dirs here. ++ This will also give earlier indication of failure to set ctx. */ ++ if (x->set_security_context || x->preserve_security_context) ++ if (! set_file_security_ctx (dst_name, x->preserve_security_context, ++ false, x)) ++ { ++ if (x->require_preserve_context) ++ goto un_backup; ++ } + } + + /* Decide whether to copy the contents of the directory. */ +@@ -2415,6 +2426,8 @@ copy_internal (char const *src_name, cha { /* Here, we are crossing a file system boundary and cp's -x option is in effect: so don't copy the contents of this directory. */ @@ -43,22 +61,15 @@ diff -urNp coreutils-8.21-orig/src/copy.c coreutils-8.21/src/copy.c } else { -@@ -2600,6 +2600,7 @@ copy_internal (char const *src_name, cha +@@ -2602,7 +2613,7 @@ copy_internal (char const *src_name, cha /* With -Z or --preserve=context, set the context for existing files. Note this is done already for copy_reg() for reasons described therein. */ -+ /* - if (!new_dst && !x->copy_as_regular +- if (!new_dst && !x->copy_as_regular ++ if (!new_dst && !x->copy_as_regular && !S_ISDIR (src_mode) && (x->set_security_context || x->preserve_security_context)) { -@@ -2610,6 +2611,7 @@ copy_internal (char const *src_name, cha - goto un_backup; - } - } -+ Temporarily disabled, it screws up the destination CTX for cp -a */ - - if (command_line_arg && x->dest_info) - { + if (! set_file_security_ctx (dst_name, x->preserve_security_context, diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c --- coreutils-8.21-orig/src/cp.c 2013-02-07 10:37:05.000000000 +0100 +++ coreutils-8.21/src/cp.c 2013-02-15 14:31:58.945468929 +0100 diff --git a/coreutils.spec b/coreutils.spec index 495c7c7..f9b8c7a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,10 @@ fi %{_sbindir}/chroot %changelog +* Fri Jan 03 2014 Ondrej Vasik 8.22-6 +- do not modify SELinux contexts of existing parent + directories when copying files (fix by P.Brady, #1045122) + * Thu Jan 02 2014 Ondrej Oprala 8.22-5 - reverted an old change and constricted it's condition - turned off two multibyte tests (wrong strcoll return value) From 9b303ebcee235b450e07ad49fd9d0573c67b736a Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Mon, 6 Jan 2014 11:49:28 +0100 Subject: [PATCH 238/523] Fix sorting by non-first field (#1003544) --- coreutils-i18n.patch | 10 +++++----- coreutils.spec | 5 ++++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 5674d8c..9aa1bc1 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -3233,12 +3233,12 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c + diff = - NONZERO (lenb); + else if (lenb == 0) + diff = 1; ++ else if (hard_LC_COLLATE && !folding) ++ { ++ diff = xmemcoll0 (texta, lena, textb, lenb); ++ } + else -+ { -+ diff = memcmp (texta, textb, MIN (lena,lenb)); -+ if (!diff) -+ diff = xmemcoll (texta, lena, textb, lenb); -+ } ++ diff = memcmp (texta, textb, MIN (lena + 1,lenb + 1)); + + if (ignore || translate) + free (texta); diff --git a/coreutils.spec b/coreutils.spec index f9b8c7a..0052312 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Jan 06 2014 Ondrej Oprala 8.22-7 +- Fix sorting by non-first field (#1003544) + * Fri Jan 03 2014 Ondrej Vasik 8.22-6 - do not modify SELinux contexts of existing parent directories when copying files (fix by P.Brady, #1045122) From 45bd042713804889c30f91ff4300d90f628f2253 Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Mon, 6 Jan 2014 16:32:53 +0100 Subject: [PATCH 239/523] Related:#1021403 - Don't use cut mb path if not necessary --- coreutils-i18n.patch | 41 +++++++++++++++++++++++++++-------------- coreutils.spec | 5 ++++- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 9aa1bc1..f1828f8 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -110,7 +110,16 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c struct range_pair { -@@ -106,15 +169,25 @@ enum operating_mode +@@ -75,6 +138,8 @@ static size_t n_rp; + /* Number of `struct range_pair's allocated. */ + static size_t n_rp_allocated; + ++/* Length of the delimiter given as argument to -d. */ ++size_t delimlen; + + /* Append LOW, HIGH to the list RP of range pairs, allocating additional + space if necessary. Update global variable N_RP. When allocating, +@@ -106,15 +171,25 @@ enum operating_mode { undefined_mode, @@ -137,7 +146,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* If true do not output lines containing no delimeter characters. Otherwise, all such lines are printed. This option is valid only with field mode. */ -@@ -126,6 +199,9 @@ static bool complement; +@@ -126,6 +201,9 @@ static bool complement; /* The delimeter character for field mode. */ static unsigned char delim; @@ -147,7 +156,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -188,7 +264,7 @@ Print selected parts of lines from each +@@ -188,7 +266,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\ @@ -156,7 +165,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -381,6 +457,9 @@ set_fields (const char *fieldstr) +@@ -381,6 +459,9 @@ set_fields (const char *fieldstr) if (operating_mode == byte_mode) error (0, 0, _("byte offset %s is too large"), quote (bad_num)); @@ -166,7 +175,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c else error (0, 0, _("field number %s is too large"), quote (bad_num)); -@@ -505,6 +584,79 @@ cut_bytes (FILE *stream) +@@ -505,6 +586,79 @@ cut_bytes (FILE *stream) } } @@ -246,7 +255,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -629,13 +782,198 @@ cut_fields (FILE *stream) +@@ -629,13 +783,201 @@ cut_fields (FILE *stream) } } @@ -429,7 +438,10 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + break; + + case field_mode: -+ cut_fields_mb (stream); ++ if (delimlen == 1) ++ cut_fields (stream); ++ else ++ cut_fields_mb (stream); + break; + + default: @@ -448,16 +460,15 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c } /* Process file FILE to standard output. -@@ -687,6 +1025,8 @@ main (int argc, char **argv) +@@ -687,6 +1029,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]; -+ size_t delimlen = 0; initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -709,7 +1049,6 @@ main (int argc, char **argv) +@@ -709,7 +1052,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -465,7 +476,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -717,6 +1056,14 @@ main (int argc, char **argv) +@@ -717,6 +1059,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -480,7 +491,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -728,10 +1075,36 @@ main (int argc, char **argv) +@@ -728,10 +1078,38 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -506,6 +517,8 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + FATAL_ERROR (_("the delimiter must be a single character")); + memcpy (mbdelim, optarg, delimlen); + mbdelim[delimlen] = '\0'; ++ if (delimlen == 1) ++ delim = *optarg; + } + } + @@ -521,7 +534,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -744,6 +1117,7 @@ main (int argc, char **argv) +@@ -744,6 +1122,7 @@ main (int argc, char **argv) break; case 'n': @@ -529,7 +542,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c break; case 's': -@@ -783,15 +1157,34 @@ main (int argc, char **argv) +@@ -783,15 +1162,34 @@ main (int argc, char **argv) } if (!delim_specified) diff --git a/coreutils.spec b/coreutils.spec index 0052312..ba2da65 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Jan 06 2014 Ondrej Oprala 8.22-8 +- Don't use cut mb path if not necessary (#1021403) + * Mon Jan 06 2014 Ondrej Oprala 8.22-7 - Fix sorting by non-first field (#1003544) From 40bc3131600ebd3845ad562e72f78934344d9e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 8 Jan 2014 13:03:41 +0100 Subject: [PATCH 240/523] Add Fedora bug reference --- coreutils.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index ba2da65..4a960a8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -372,8 +372,8 @@ fi %{_sbindir}/chroot %changelog -* Mon Jan 06 2014 Ondrej Oprala 8.22-8 -- Don't use cut mb path if not necessary (#1021403) +* Wed Jan 08 2014 Ondrej Oprala 8.22-8 +- Don't use cut mb path if not necessary (#1021403, #499220) * Mon Jan 06 2014 Ondrej Oprala 8.22-7 - Fix sorting by non-first field (#1003544) From 963813cd96396f0e1f14cffef2905175d21049a0 Mon Sep 17 00:00:00 2001 From: Bernhard Voelker Date: Sat, 4 Jan 2014 22:34:02 +0100 Subject: [PATCH 241/523] i18n patch: fix wrongly merged code in cut.c * src/cut.c (cut_characters_or_cut_bytes_no_split): Move setting of print_delimiter into the correct scope. --- coreutils-i18n.patch | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index f1828f8..59ff7ea 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -238,10 +238,12 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + if (output_delimiter_specified) + { + if (print_delimiter && is_range_start_index (idx)) -+ fwrite (output_delimiter_string, sizeof (char), -+ output_delimiter_length, stdout); ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ print_delimiter = true; + } -+ print_delimiter = true; + fwrite (bufpos, mblength, sizeof(char), stdout); + } + } From ef63c7141256ae68be04bbfb2504bf8ba388370d Mon Sep 17 00:00:00 2001 From: Bernhard Voelker Date: Sat, 4 Jan 2014 22:48:09 +0100 Subject: [PATCH 242/523] maint: avoid compiler warnings introduced by i18n patch * src/cut.c (convfail,CONVFAIL): Change to bool to avoid a GCC warning about signed vs. unsigned. Also avoid "set but not used" of convfail in cut_characters_or_cut_bytes_no_split. (cut_fields_mb): Fix indentation. * src/expand.c: Add include for wctype.h to declare isblank(). * src/fold.c (fold_file): Add "const" attribute to 'filename' parameter to avoid "const cast away" in call in main(). * src/join.c (xfields_multibyte): Remove unused variable 't'. (keycmp): Evaluate the return value of wcrtomb(). Furthermore, when copying 'beg' to 'copy' array elements, remove the unnecessary cast to unsigned. (main): When assigning the newline string to 'newtab', cast away the implicit const. * src/pr.c: Remove the unneeded include of wctype.h and the define of iswprint(). (print_stored): Add the unsigned qualifier to 'first' and 'last' to avoid a signedness warning. * src/sort.c (getmonth_mb): Cast away the 'const' qualifier of 's' when assigning to *ea. * src/uniq.c (different_multi): Evaluate the return result of wcrtomb(); Add the include of assert.h for that. --- coreutils-i18n.patch | 72 ++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 59ff7ea..acef507 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -75,7 +75,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + while (0) + +/* Get wide character on BUFPOS. BUFPOS is not included after that. -+ If byte sequence is not valid as a character, CONVFAIL is 1. Otherwise 0. */ ++ 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 \ + { \ @@ -88,7 +88,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + } \ + \ + /* Get a wide character. */ \ -+ CONVFAIL = 0; \ ++ CONVFAIL = false; \ + state_bak = STATE; \ + MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ + \ @@ -96,7 +96,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + { \ + case (size_t)-1: \ + case (size_t)-2: \ -+ CONVFAIL++; \ ++ CONVFAIL = true; \ + STATE = state_bak; \ + /* Fall througn. */ \ + \ @@ -199,7 +199,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + size_t mblength; /* The byte size of a multibyte character which shows + as same character as WC. */ + mbstate_t state; /* State of the stream. */ -+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ ++ 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; @@ -216,6 +216,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + REFILL_BUFFER (buf, bufpos, buflen, stream); + + GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); ++ (void) convfail; /* ignore unused */ + + if (wc == WEOF) + { @@ -277,7 +278,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + size_t mblength; /* The byte size of a multibyte character which shows + as same character as WC. */ + mbstate_t state; /* State of the stream. */ -+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ ++ bool convfail = false; /* true, when conversion failed. Otherwise false. */ + + current_rp = rp; + @@ -359,7 +360,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + fwrite (field_1_buffer, sizeof (char), len - 1, stdout); + found_any_selected_field = 1; + } -+ next_item (&field_idx); ++ next_item (&field_idx); + } + + if (wc != WEOF) @@ -402,7 +403,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + wc = WEOF; + + if (!convfail && wc == wcdelim) -+ next_item (&field_idx); ++ next_item (&field_idx); + else if (wc == WEOF || (!convfail && wc == L'\n')) + { + if (found_any_selected_field @@ -597,6 +598,11 @@ diff -urNp coreutils-8.22-orig/src/expand.c coreutils-8.22/src/expand.c +#if HAVE_WCHAR_H +# include +#endif ++ ++/* Get iswblank(). */ ++#if HAVE_WCTYPE_H ++# include ++#endif + #include "system.h" #include "error.h" @@ -1118,7 +1124,7 @@ diff -urNp coreutils-8.22-orig/src/fold.c coreutils-8.22/src/fold.c + Return 0 if successful, 1 if an error occurs. */ + +static bool -+fold_file (char *filename, size_t width) ++fold_file (char const *filename, size_t width) +{ + FILE *istream; + int saved_errno; @@ -1268,7 +1274,6 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c + + if (tab != NULL) + { -+ unsigned char t = tab[0]; + char *sep = ptr; + for (; ptr < lim; ptr = sep + mblength) + { @@ -1491,9 +1496,11 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c + if (uwc != wc) + { + mbstate_t state_wc; ++ size_t mblen; + + memset (&state_wc, '\0', sizeof (mbstate_t)); -+ wcrtomb (copy[i] + j, uwc, &state_wc); ++ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); ++ assert (mblen != (size_t)-1); + } + else + memcpy (copy[i] + j, beg[i] + j, mblength); @@ -1523,8 +1530,8 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c - if (hard_LC_COLLATE) - return xmemcoll (beg1, len1, beg2, len2); - diff = memcmp (beg1, beg2, MIN (len1, len2)); -+ copy[0] = (unsigned char *) beg[0]; -+ copy[1] = (unsigned char *) beg[1]; ++ copy[0] = beg[0]; ++ copy[1] = beg[1]; } + if (hard_LC_COLLATE) @@ -1640,7 +1647,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c if (! newtab) - newtab = '\n'; /* '' => process the whole line. */ + { -+ newtab = "\n"; /* '' => process the whole line. */ ++ newtab = (char*)"\n"; /* '' => process the whole line. */ + } else if (optarg[1]) { @@ -1693,19 +1700,11 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c +#if HAVE_WCHAR_H +# include +#endif -+ -+/* Get iswprint(). -- for wcwidth(). */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+#if !defined iswprint && !HAVE_ISWPRINT -+# define iswprint(wc) 1 -+#endif + #include "system.h" #include "error.h" #include "fadvise.h" -@@ -323,6 +349,18 @@ +@@ -323,6 +341,18 @@ #include "strftime.h" #include "xstrtol.h" @@ -2215,7 +2214,25 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2595,9 +2801,9 @@ print_stored (COLUMN *p) +@@ -2564,7 +2762,7 @@ print_stored (COLUMN *p) + int i; + + 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: +@@ -2576,7 +2774,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; + +@@ -2595,9 +2793,9 @@ print_stored (COLUMN *p) } } @@ -3077,7 +3094,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c + ? monthtab[lo].val : 0); + + if (ea && result) -+ *ea = s + strlen (monthtab[lo].name); ++ *ea = (char*) s + strlen (monthtab[lo].name); + + free (month); + free (tmp); @@ -3681,11 +3698,12 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c +#if HAVE_WCTYPE_H +# include +#endif ++#include + #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -32,7 +42,19 @@ +@@ -32,7 +43,19 @@ #include "stdio--.h" #include "xmemcoll.h" #include "xstrtol.h" @@ -3901,9 +3919,11 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c + if (uwc != wc) + { + mbstate_t state_wc; ++ size_t mblen; + + memset (&state_wc, '\0', sizeof(mbstate_t)); -+ wcrtomb (copy[i] + j, uwc, &state_wc); ++ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); ++ assert (mblen != (size_t)-1); + } + else + memcpy (copy[i] + j, str[i] + j, mblength); From ff51f0cc5e8332d6dcdef29d8641a38d68a4194c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 8 Jan 2014 13:58:02 +0100 Subject: [PATCH 243/523] Rediff the changes --- coreutils-i18n.patch | 180 +++++++++++++++++++++---------------------- 1 file changed, 90 insertions(+), 90 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index acef507..dc2b2c3 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ diff -urNp coreutils-8.22-orig/lib/linebuffer.h coreutils-8.22/lib/linebuffer.h --- coreutils-8.22-orig/lib/linebuffer.h 2013-12-04 15:53:33.000000000 +0100 -+++ coreutils-8.22/lib/linebuffer.h 2013-12-16 17:40:25.933887985 +0100 ++++ coreutils-8.22/lib/linebuffer.h 2014-01-08 13:55:56.106375471 +0100 @@ -21,6 +21,11 @@ # include @@ -25,7 +25,7 @@ diff -urNp coreutils-8.22-orig/lib/linebuffer.h coreutils-8.22/lib/linebuffer.h /* Initialize linebuffer LINEBUFFER for use. */ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c --- coreutils-8.22-orig/src/cut.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/cut.c 2013-12-16 17:40:25.935887295 +0100 ++++ coreutils-8.22/src/cut.c 2014-01-08 13:55:56.108375451 +0100 @@ -28,6 +28,11 @@ #include #include @@ -156,7 +156,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -188,7 +266,7 @@ Print selected parts of lines from each +@@ -188,7 +266,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\ @@ -175,7 +175,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c else error (0, 0, _("field number %s is too large"), quote (bad_num)); -@@ -505,6 +586,79 @@ cut_bytes (FILE *stream) +@@ -505,6 +586,82 @@ cut_bytes (FILE *stream) } } @@ -258,7 +258,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -629,13 +783,201 @@ cut_fields (FILE *stream) +@@ -629,13 +786,201 @@ cut_fields (FILE *stream) } } @@ -463,7 +463,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c } /* Process file FILE to standard output. -@@ -687,6 +1029,7 @@ main (int argc, char **argv) +@@ -687,6 +1032,7 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -471,7 +471,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -709,7 +1052,6 @@ main (int argc, char **argv) +@@ -709,7 +1055,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -479,7 +479,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -717,6 +1059,14 @@ main (int argc, char **argv) +@@ -717,6 +1062,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -494,7 +494,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -728,10 +1078,38 @@ main (int argc, char **argv) +@@ -728,10 +1081,38 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -537,7 +537,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -744,6 +1122,7 @@ main (int argc, char **argv) +@@ -744,6 +1125,7 @@ main (int argc, char **argv) break; case 'n': @@ -545,7 +545,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c break; case 's': -@@ -783,15 +1162,34 @@ main (int argc, char **argv) +@@ -783,15 +1165,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -588,8 +588,8 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c if (optind == argc) diff -urNp coreutils-8.22-orig/src/expand.c coreutils-8.22/src/expand.c --- coreutils-8.22-orig/src/expand.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/expand.c 2013-12-16 17:40:25.936886952 +0100 -@@ -37,12 +37,29 @@ ++++ coreutils-8.22/src/expand.c 2014-01-08 13:55:56.110375431 +0100 +@@ -37,12 +37,34 @@ #include #include #include @@ -624,7 +624,7 @@ diff -urNp coreutils-8.22-orig/src/expand.c coreutils-8.22/src/expand.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "expand" -@@ -357,6 +374,142 @@ expand (void) +@@ -357,6 +379,142 @@ expand (void) } } @@ -767,7 +767,7 @@ diff -urNp coreutils-8.22-orig/src/expand.c coreutils-8.22/src/expand.c int main (int argc, char **argv) { -@@ -421,7 +574,12 @@ main (int argc, char **argv) +@@ -421,7 +579,12 @@ main (int argc, char **argv) file_list = (optind < argc ? &argv[optind] : stdin_argv); @@ -783,7 +783,7 @@ diff -urNp coreutils-8.22-orig/src/expand.c coreutils-8.22/src/expand.c error (EXIT_FAILURE, errno, "-"); diff -urNp coreutils-8.22-orig/src/fold.c coreutils-8.22/src/fold.c --- coreutils-8.22-orig/src/fold.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/fold.c 2013-12-16 17:40:25.938886274 +0100 ++++ coreutils-8.22/src/fold.c 2014-01-08 13:55:56.111375421 +0100 @@ -22,12 +22,34 @@ #include #include @@ -1183,7 +1183,7 @@ diff -urNp coreutils-8.22-orig/src/fold.c coreutils-8.22/src/fold.c case 's': /* Break at word boundaries. */ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c --- coreutils-8.22-orig/src/join.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/join.c 2013-12-16 17:40:25.940885607 +0100 ++++ coreutils-8.22/src/join.c 2014-01-08 13:55:56.113375401 +0100 @@ -22,18 +22,32 @@ #include #include @@ -1253,7 +1253,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c { /* Skip leading blanks before the first field. */ while (isblank (to_uchar (*ptr))) -@@ -299,6 +316,148 @@ xfields (struct line *line) +@@ -299,6 +316,147 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1401,7 +1401,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c static void freeline (struct line *line) { -@@ -320,56 +479,131 @@ keycmp (struct line const *line1, struct +@@ -320,56 +478,133 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1558,7 +1558,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -461,6 +694,11 @@ get_line (FILE *fp, struct line **linep, +@@ -461,6 +696,11 @@ get_line (FILE *fp, struct line **linep, } ++line_no[which - 1]; @@ -1570,7 +1570,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c xfields (line); if (prevline[which - 1]) -@@ -560,21 +798,28 @@ prfield (size_t n, struct line const *li +@@ -560,21 +800,28 @@ prfield (size_t n, struct line const *li /* Output all the fields in line, other than the join field. */ @@ -1602,7 +1602,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c prfield (i, line); } } -@@ -585,7 +830,6 @@ static void +@@ -585,7 +832,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -1610,7 +1610,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c size_t field; struct line const *line; -@@ -619,7 +863,7 @@ prjoin (struct line const *line1, struct +@@ -619,7 +865,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1619,7 +1619,7 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c } putchar (eolchar); } -@@ -1097,21 +1341,46 @@ main (int argc, char **argv) +@@ -1097,21 +1343,46 @@ main (int argc, char **argv) case 't': { @@ -1678,8 +1678,8 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c case 'z': diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c --- coreutils-8.22-orig/src/pr.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/pr.c 2013-12-16 17:40:25.944884263 +0100 -@@ -312,6 +312,32 @@ ++++ coreutils-8.22/src/pr.c 2014-01-08 13:55:56.118375350 +0100 +@@ -312,6 +312,24 @@ #include #include @@ -1723,7 +1723,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -415,7 +453,20 @@ struct COLUMN +@@ -415,7 +445,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -1745,7 +1745,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -425,6 +476,7 @@ static void print_header (void); +@@ -425,6 +468,7 @@ static void print_header (void); static void pad_across_to (int position); static void add_line_number (COLUMN *p); static void getoptarg (char *arg, char switch_char, char *character, @@ -1753,7 +1753,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c int *number); static void print_files (int number_of_files, char **av); static void init_parameters (int number_of_files); -@@ -438,7 +490,6 @@ static void store_char (char c); +@@ -438,7 +482,6 @@ static void store_char (char c); static void pad_down (int lines); static void read_rest_of_line (COLUMN *p); static void skip_read (COLUMN *p, int column_number); @@ -1761,7 +1761,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c static void cleanup (void); static void print_sep_string (void); static void separator_string (const char *optarg_S); -@@ -450,7 +501,7 @@ static COLUMN *column_vector; +@@ -450,7 +493,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]. */ @@ -1770,7 +1770,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* Index of the position in buff where the next character will be stored. */ -@@ -554,7 +605,7 @@ static int chars_per_column; +@@ -554,7 +597,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -1779,7 +1779,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... where the leftmost column is 1. */ -@@ -564,7 +615,10 @@ static int chars_per_input_tab = 8; +@@ -564,7 +607,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -1791,7 +1791,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -634,7 +688,13 @@ static int line_number; +@@ -634,7 +680,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1806,7 +1806,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -687,6 +747,7 @@ static bool use_col_separator = false; +@@ -687,6 +739,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ static char *col_sep_string = (char *) ""; static int col_sep_length = 0; @@ -1814,7 +1814,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -843,6 +904,13 @@ separator_string (const char *optarg_S) +@@ -843,6 +896,13 @@ separator_string (const char *optarg_S) col_sep_length = (int) strlen (optarg_S); col_sep_string = xmalloc (col_sep_length + 1); strcpy (col_sep_string, optarg_S); @@ -1828,7 +1828,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c } int -@@ -867,6 +935,21 @@ main (int argc, char **argv) +@@ -867,6 +927,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1850,7 +1850,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c n_files = 0; file_names = (argc > 1 ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -943,8 +1026,12 @@ main (int argc, char **argv) +@@ -943,8 +1018,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1865,7 +1865,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -957,8 +1044,12 @@ main (int argc, char **argv) +@@ -957,8 +1036,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1880,7 +1880,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -985,8 +1076,8 @@ main (int argc, char **argv) +@@ -985,8 +1068,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1891,7 +1891,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c break; case 'N': skip_count = false; -@@ -1025,7 +1116,7 @@ main (int argc, char **argv) +@@ -1025,7 +1108,7 @@ main (int argc, char **argv) old_s = false; /* Reset an additional input of -s, -S dominates -s */ col_sep_string = bad_cast (""); @@ -1900,7 +1900,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1182,10 +1273,45 @@ main (int argc, char **argv) +@@ -1182,10 +1265,45 @@ main (int argc, char **argv) a number. */ static void @@ -1948,7 +1948,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c if (*arg) { long int tmp_long; -@@ -1207,6 +1333,11 @@ static void +@@ -1207,6 +1325,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -1960,7 +1960,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1244,7 +1375,7 @@ init_parameters (int number_of_files) +@@ -1244,7 +1367,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -1969,7 +1969,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1274,11 +1405,11 @@ init_parameters (int number_of_files) +@@ -1274,11 +1397,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. */ @@ -1983,7 +1983,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1287,7 +1418,7 @@ init_parameters (int number_of_files) +@@ -1287,7 +1410,7 @@ init_parameters (int number_of_files) } chars_per_column = (chars_per_line - chars_used_by_number @@ -1992,7 +1992,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c if (chars_per_column < 1) error (EXIT_FAILURE, 0, _("page width too narrow")); -@@ -1305,7 +1436,7 @@ init_parameters (int number_of_files) +@@ -1305,7 +1428,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); @@ -2001,7 +2001,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c } /* Open the necessary files, -@@ -1413,7 +1544,7 @@ init_funcs (void) +@@ -1413,7 +1536,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2010,7 +2010,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* This loop takes care of all but the rightmost column. */ -@@ -1447,7 +1578,7 @@ init_funcs (void) +@@ -1447,7 +1570,7 @@ init_funcs (void) } else { @@ -2019,7 +2019,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c h_next = h + chars_per_column; } } -@@ -1738,9 +1869,9 @@ static void +@@ -1738,9 +1861,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2031,7 +2031,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2011,13 +2142,13 @@ store_char (char c) +@@ -2011,13 +2134,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2047,7 +2047,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c char *s; int num_width; -@@ -2034,22 +2165,24 @@ add_line_number (COLUMN *p) +@@ -2034,22 +2157,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. */ @@ -2076,7 +2076,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2210,7 +2343,7 @@ print_white_space (void) +@@ -2210,7 +2335,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2085,7 +2085,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c h_old = h_new; } while (++h_old <= goal) -@@ -2230,6 +2363,7 @@ print_sep_string (void) +@@ -2230,6 +2355,7 @@ print_sep_string (void) { char *s; int l = col_sep_length; @@ -2093,7 +2093,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c s = col_sep_string; -@@ -2243,6 +2377,7 @@ print_sep_string (void) +@@ -2243,6 +2369,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2101,7 +2101,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2256,12 +2391,15 @@ print_sep_string (void) +@@ -2256,12 +2383,15 @@ print_sep_string (void) } else { @@ -2118,7 +2118,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2289,7 +2427,7 @@ print_clump (COLUMN *p, int n, char *clu +@@ -2289,7 +2419,7 @@ print_clump (COLUMN *p, int n, char *clu required number of tabs and spaces. */ static void @@ -2127,7 +2127,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c { if (tabify_output) { -@@ -2313,6 +2451,74 @@ print_char (char c) +@@ -2313,6 +2443,74 @@ print_char (char c) putchar (c); } @@ -2202,7 +2202,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2492,9 +2698,9 @@ read_line (COLUMN *p) +@@ -2492,9 +2690,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2244,7 +2244,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2610,8 +2816,8 @@ print_stored (COLUMN *p) +@@ -2610,8 +2808,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2255,7 +2255,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c } return true; -@@ -2630,7 +2836,7 @@ print_stored (COLUMN *p) +@@ -2630,7 +2828,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2264,7 +2264,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c { unsigned char uc = c; char *s = clump_buff; -@@ -2640,10 +2846,10 @@ char_to_clump (char c) +@@ -2640,10 +2838,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2277,7 +2277,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2724,6 +2930,164 @@ char_to_clump (char c) +@@ -2724,6 +2922,164 @@ char_to_clump (char c) return chars; } @@ -2444,7 +2444,7 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c --- coreutils-8.22-orig/src/sort.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/sort.c 2014-01-02 21:17:32.802621367 +0100 ++++ coreutils-8.22/src/sort.c 2014-01-08 13:55:56.123375301 +0100 @@ -29,6 +29,14 @@ #include #include @@ -3426,7 +3426,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c diff -urNp coreutils-8.22-orig/src/unexpand.c coreutils-8.22/src/unexpand.c --- coreutils-8.22-orig/src/unexpand.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/unexpand.c 2013-12-16 17:40:25.951881910 +0100 ++++ coreutils-8.22/src/unexpand.c 2014-01-08 13:55:56.126375271 +0100 @@ -38,12 +38,29 @@ #include #include @@ -3684,8 +3684,8 @@ diff -urNp coreutils-8.22-orig/src/unexpand.c coreutils-8.22/src/unexpand.c error (EXIT_FAILURE, errno, "-"); diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c --- coreutils-8.22-orig/src/uniq.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/uniq.c 2013-12-16 17:41:06.711697074 +0100 -@@ -21,6 +21,16 @@ ++++ coreutils-8.22/src/uniq.c 2014-01-08 13:55:56.127375261 +0100 +@@ -21,6 +21,17 @@ #include #include @@ -3724,7 +3724,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -143,6 +165,10 @@ enum +@@ -143,6 +166,10 @@ enum GROUP_OPTION = CHAR_MAX + 1 }; @@ -3735,7 +3735,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -249,7 +275,7 @@ size_opt (char const *opt, char const *m +@@ -249,7 +276,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 @@ -3744,7 +3744,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -269,6 +295,83 @@ find_field (struct linebuffer const *lin +@@ -269,6 +296,83 @@ find_field (struct linebuffer const *lin return line->buffer + i; } @@ -3828,7 +3828,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c /* 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. -@@ -277,6 +380,8 @@ find_field (struct linebuffer const *lin +@@ -277,6 +381,8 @@ find_field (struct linebuffer const *lin static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -3837,7 +3837,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -284,14 +389,101 @@ different (char *old, char *new, size_t +@@ -284,14 +390,103 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3946,7 +3946,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -356,18 +547,55 @@ check_file (const char *infile, const ch +@@ -356,18 +551,55 @@ check_file (const char *infile, const ch char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); bool first_group_printed = false; @@ -4002,7 +4002,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c new_group = (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)); -@@ -376,7 +604,7 @@ check_file (const char *infile, const ch +@@ -376,7 +608,7 @@ check_file (const char *infile, const ch && (grouping == GM_PREPEND || grouping == GM_BOTH || (first_group_printed && (grouping == GM_APPEND || grouping == GM_SEPARATE)))) @@ -4011,7 +4011,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (new_group || grouping != GM_NONE) { -@@ -388,6 +616,9 @@ check_file (const char *infile, const ch +@@ -388,6 +620,9 @@ check_file (const char *infile, const ch prevlen = thislen; first_group_printed = true; } @@ -4021,7 +4021,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c } if ((grouping == GM_BOTH || grouping == GM_APPEND) && first_group_printed) putchar (delimiter); -@@ -398,17 +629,26 @@ check_file (const char *infile, const ch +@@ -398,17 +633,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -4048,7 +4048,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -417,6 +657,14 @@ check_file (const char *infile, const ch +@@ -417,6 +661,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -4063,7 +4063,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -449,6 +697,9 @@ check_file (const char *infile, const ch +@@ -449,6 +701,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4073,7 +4073,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (!match) match_count = 0; } -@@ -495,6 +746,19 @@ main (int argc, char **argv) +@@ -495,6 +750,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4094,8 +4094,8 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c skip_fields = 0; check_chars = SIZE_MAX; diff -urNp coreutils-8.22-orig/tests/local.mk coreutils-8.22/tests/local.mk ---- coreutils-8.22-orig/tests/local.mk 2013-12-16 17:39:49.187181544 +0100 -+++ coreutils-8.22/tests/local.mk 2013-12-16 17:40:25.955880566 +0100 +--- coreutils-8.22-orig/tests/local.mk 2014-01-08 13:55:24.524683837 +0100 ++++ coreutils-8.22/tests/local.mk 2014-01-08 13:55:56.129375241 +0100 @@ -324,6 +324,7 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ @@ -4106,7 +4106,7 @@ diff -urNp coreutils-8.22-orig/tests/local.mk coreutils-8.22/tests/local.mk tests/misc/sort-month.sh \ diff -urNp coreutils-8.22-orig/tests/misc/cut.pl coreutils-8.22/tests/misc/cut.pl --- coreutils-8.22-orig/tests/misc/cut.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/cut.pl 2013-12-16 17:40:25.956880230 +0100 ++++ coreutils-8.22/tests/misc/cut.pl 2014-01-08 13:55:56.130375231 +0100 @@ -23,9 +23,11 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4131,7 +4131,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/cut.pl coreutils-8.22/tests/misc/cut.p push @Tests, @new; diff -urNp coreutils-8.22-orig/tests/misc/expand.pl coreutils-8.22/tests/misc/expand.pl --- coreutils-8.22-orig/tests/misc/expand.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/expand.pl 2013-12-16 17:40:25.957879894 +0100 ++++ coreutils-8.22/tests/misc/expand.pl 2014-01-08 13:55:56.135375181 +0100 @@ -23,6 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4188,7 +4188,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/expand.pl coreutils-8.22/tests/misc/ex diff -urNp coreutils-8.22-orig/tests/misc/fold.pl coreutils-8.22/tests/misc/fold.pl --- coreutils-8.22-orig/tests/misc/fold.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/fold.pl 2013-12-16 17:40:25.958879558 +0100 ++++ coreutils-8.22/tests/misc/fold.pl 2014-01-08 13:55:56.136375171 +0100 @@ -20,9 +20,18 @@ use strict; (my $program_name = $0) =~ s|.*/||; @@ -4260,7 +4260,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/fold.pl coreutils-8.22/tests/misc/fold exit $fail; diff -urNp coreutils-8.22-orig/tests/misc/join.pl coreutils-8.22/tests/misc/join.pl --- coreutils-8.22-orig/tests/misc/join.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/join.pl 2013-12-16 17:40:25.959879222 +0100 ++++ coreutils-8.22/tests/misc/join.pl 2014-01-08 13:55:56.137375161 +0100 @@ -25,6 +25,15 @@ my $limits = getlimits (); my $prog = 'join'; @@ -4329,7 +4329,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/join.pl coreutils-8.22/tests/misc/join diff -urNp coreutils-8.22-orig/tests/misc/sort-mb-tests.sh coreutils-8.22/tests/misc/sort-mb-tests.sh --- coreutils-8.22-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.22/tests/misc/sort-mb-tests.sh 2013-12-16 17:40:25.959879222 +0100 ++++ coreutils-8.22/tests/misc/sort-mb-tests.sh 2014-01-08 13:55:56.138375151 +0100 @@ -0,0 +1,45 @@ +#!/bin/sh +# Verify sort's multi-byte support. @@ -4378,7 +4378,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/sort-mb-tests.sh coreutils-8.22/tests/ +Exit $fail diff -urNp coreutils-8.22-orig/tests/misc/sort-merge.pl coreutils-8.22/tests/misc/sort-merge.pl --- coreutils-8.22-orig/tests/misc/sort-merge.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/sort-merge.pl 2013-12-16 17:40:25.960878886 +0100 ++++ coreutils-8.22/tests/misc/sort-merge.pl 2014-01-08 13:55:56.139375141 +0100 @@ -26,6 +26,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4437,7 +4437,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/sort-merge.pl coreutils-8.22/tests/mis diff -urNp coreutils-8.22-orig/tests/misc/sort.pl coreutils-8.22/tests/misc/sort.pl --- coreutils-8.22-orig/tests/misc/sort.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/sort.pl 2013-12-16 17:40:25.962878214 +0100 ++++ coreutils-8.22/tests/misc/sort.pl 2014-01-08 13:55:56.140375131 +0100 @@ -24,10 +24,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4503,7 +4503,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/sort.pl coreutils-8.22/tests/misc/sort my $verbose = $ENV{VERBOSE}; diff -urNp coreutils-8.22-orig/tests/misc/unexpand.pl coreutils-8.22/tests/misc/unexpand.pl --- coreutils-8.22-orig/tests/misc/unexpand.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/unexpand.pl 2013-12-16 17:40:25.962878214 +0100 ++++ coreutils-8.22/tests/misc/unexpand.pl 2014-01-08 13:55:56.140375131 +0100 @@ -27,6 +27,14 @@ my $limits = getlimits (); my $prog = 'unexpand'; @@ -4559,7 +4559,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/unexpand.pl coreutils-8.22/tests/misc/ diff -urNp coreutils-8.22-orig/tests/misc/uniq.pl coreutils-8.22/tests/misc/uniq.pl --- coreutils-8.22-orig/tests/misc/uniq.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/uniq.pl 2013-12-16 17:41:34.077961751 +0100 ++++ coreutils-8.22/tests/misc/uniq.pl 2014-01-08 13:55:56.141375121 +0100 @@ -23,9 +23,17 @@ my $limits = getlimits (); my $prog = 'uniq'; my $try = "Try '$prog --help' for more information.\n"; @@ -4626,7 +4626,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/uniq.pl coreutils-8.22/tests/misc/uniq diff -urNp coreutils-8.22-orig/tests/pr/pr-tests.pl coreutils-8.22/tests/pr/pr-tests.pl --- coreutils-8.22-orig/tests/pr/pr-tests.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/pr/pr-tests.pl 2013-12-16 17:40:25.965877206 +0100 ++++ coreutils-8.22/tests/pr/pr-tests.pl 2014-01-08 13:55:56.144375092 +0100 @@ -23,6 +23,15 @@ use strict; my $prog = 'pr'; From e241867dd102864fb5579ba99799e075dac9555a Mon Sep 17 00:00:00 2001 From: Bernhard Voelker Date: Sat, 4 Jan 2014 22:52:24 +0100 Subject: [PATCH 244/523] i18n patch: avoid test failure for uniq's 145-mb test case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * tests.misc/uniq.pl: For comparing the stderr message with the expected result, all multibyte-typical ‘...’ must be replaced by '...'. Add a ERR_SUBST expression to do that. --- coreutils-i18n.patch | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index dc2b2c3..b2f5693 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4605,8 +4605,16 @@ diff -urNp coreutils-8.22-orig/tests/misc/uniq.pl coreutils-8.22/tests/misc/uniq + push @new_t, $sub; + push @$t, $sub; + } -+ next if ($test_name =~ "schar" or $test_name =~ "^obs-plus" -+ or $test_name =~ "119" or $test_name =~ "145"); ++ # 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; From dc1142233b4cb3151cf3f646adcce5fdf1ff0265 Mon Sep 17 00:00:00 2001 From: Bernhard Voelker Date: Sat, 4 Jan 2014 22:53:29 +0100 Subject: [PATCH 245/523] i18n patch: simplify multi-byte handling in uniq * src/uniq.c (check_file): Instead of copying the whole code, simply determine the value of 'new_group' by invoking different_multi in the multi-byte case. --- coreutils-i18n.patch | 67 ++++++++++++++------------------------------ 1 file changed, 21 insertions(+), 46 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index b2f5693..103f317 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -3946,7 +3946,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -356,18 +551,55 @@ check_file (const char *infile, const ch +@@ -356,19 +551,38 @@ check_file (const char *infile, const ch char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); bool first_group_printed = false; @@ -3971,57 +3971,32 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); +#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) ++ if (MB_CUR_MAX > 1) + { -+ thisstate = thisline->state; -+ -+ new_group = (prevline->length == 0 || different_multi -+ (thisfield, prevfield, thislen, prevlen, thisstate, prevstate)); -+ -+ if (new_group && grouping != GM_NONE -+ && (grouping == GM_PREPEND || grouping == GM_BOTH -+ || (first_group_printed && (grouping == GM_APPEND -+ || grouping == GM_SEPARATE)))) -+ putchar (delimiter); -+ -+ if (new_group || grouping != GM_NONE) -+ { -+ fwrite (thisline->buffer, sizeof (char), -+ thisline->length, stdout); -+ -+ SWAP_LINES (prevline, thisline); -+ prevfield = thisfield; -+ prevlen = thislen; -+ prevstate = thisstate; -+ first_group_printed = true; -+ } -+ } -+ else -+ { -+#endif ++ thisstate = thisline->state; ++ new_group = (prevline->length == 0 ++ || different_multi (thisfield, prevfield, ++ thislen, prevlen, ++ thisstate, prevstate)); ++ } ++ else ++#endif new_group = (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)); -@@ -376,7 +608,7 @@ check_file (const char *infile, const ch - && (grouping == GM_PREPEND || grouping == GM_BOTH - || (first_group_printed && (grouping == GM_APPEND - || grouping == GM_SEPARATE)))) -- putchar (delimiter); -+ putchar (delimiter); - if (new_group || grouping != GM_NONE) - { -@@ -388,6 +620,9 @@ check_file (const char *infile, const ch +@@ -386,6 +600,10 @@ check_file (const char *infile, const ch + SWAP_LINES (prevline, thisline); + prevfield = thisfield; prevlen = thislen; ++#if HAVE_MBRTOWC ++ if (MB_CUR_MAX > 1) ++ prevstate = thisstate; ++#endif first_group_printed = true; } -+#if HAVE_MBRTOWC -+ } -+#endif } - if ((grouping == GM_BOTH || grouping == GM_APPEND) && first_group_printed) - putchar (delimiter); -@@ -398,17 +633,26 @@ check_file (const char *infile, const ch +@@ -398,17 +616,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -4048,7 +4023,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -417,6 +661,14 @@ check_file (const char *infile, const ch +@@ -417,6 +644,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -4063,7 +4038,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -449,6 +701,9 @@ check_file (const char *infile, const ch +@@ -449,6 +684,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4073,7 +4048,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (!match) match_count = 0; } -@@ -495,6 +750,19 @@ main (int argc, char **argv) +@@ -495,6 +733,19 @@ main (int argc, char **argv) atexit (close_stdout); From 02d5a162e76c58467a12d0c3d17bb762b2c63fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 8 Jan 2014 14:55:05 +0100 Subject: [PATCH 246/523] Adjust the patch --- coreutils-i18n.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 103f317..70541f8 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4553,7 +4553,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/uniq.pl coreutils-8.22/tests/misc/uniq # When possible, create a "-z"-testing variant of each test. sub add_z_variants($) { -@@ -261,6 +269,45 @@ foreach my $t (@Tests) +@@ -261,6 +269,53 @@ foreach my $t (@Tests) and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; } From b3c0c988411eb33e766a137ae4d49ff46ddcadc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 8 Jan 2014 15:27:56 +0100 Subject: [PATCH 247/523] Add changelog comment --- coreutils.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coreutils.spec b/coreutils.spec index 4a960a8..28c816f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -374,6 +374,8 @@ fi %changelog * Wed Jan 08 2014 Ondrej Oprala 8.22-8 - Don't use cut mb path if not necessary (#1021403, #499220) +- several i18n patch improvements merged from OpenSUSE (fixed + compilation warnings, simplify mb handling in uniq) * Mon Jan 06 2014 Ondrej Oprala 8.22-7 - Fix sorting by non-first field (#1003544) From be3c926a11df3806f8afdd5f3857b46fdb498b4a Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Fri, 10 Jan 2014 16:06:15 +0100 Subject: [PATCH 248/523] Limit the cut optimizations to UTF-8 locales only --- coreutils-i18n.patch | 28 +++++++++++++++++----------- coreutils.spec | 5 ++++- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 70541f8..a0c2717 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -156,7 +156,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -188,7 +266,7 @@ Print selected parts of lines from each +@@ -188,7 +266,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\ @@ -258,7 +258,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -629,13 +786,201 @@ cut_fields (FILE *stream) +@@ -629,13 +786,207 @@ cut_fields (FILE *stream) } } @@ -442,9 +442,15 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + + case field_mode: + if (delimlen == 1) -+ cut_fields (stream); -+ else -+ cut_fields_mb (stream); ++ { ++ char * loc = setlocale(LC_CTYPE, NULL); ++ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8"))) ++ { ++ cut_fields (stream); ++ break; ++ } ++ } ++ cut_fields_mb (stream); + break; + + default: @@ -463,7 +469,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c } /* Process file FILE to standard output. -@@ -687,6 +1032,7 @@ main (int argc, char **argv) +@@ -687,6 +1038,7 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -471,7 +477,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -709,7 +1055,6 @@ main (int argc, char **argv) +@@ -709,7 +1061,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -479,7 +485,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -717,6 +1062,14 @@ main (int argc, char **argv) +@@ -717,6 +1068,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -494,7 +500,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -728,10 +1081,38 @@ main (int argc, char **argv) +@@ -728,10 +1087,38 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -537,7 +543,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -744,6 +1125,7 @@ main (int argc, char **argv) +@@ -744,6 +1131,7 @@ main (int argc, char **argv) break; case 'n': @@ -545,7 +551,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c break; case 's': -@@ -783,15 +1165,34 @@ main (int argc, char **argv) +@@ -783,15 +1171,34 @@ main (int argc, char **argv) } if (!delim_specified) diff --git a/coreutils.spec b/coreutils.spec index 28c816f..cd65278 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,9 @@ fi %{_sbindir}/chroot %changelog +* Fri Jan 10 2014 Ondrej Oprala 8.22-9 +- Limit the cut optimizations to UTF-8 locales only + * Wed Jan 08 2014 Ondrej Oprala 8.22-8 - Don't use cut mb path if not necessary (#1021403, #499220) - several i18n patch improvements merged from OpenSUSE (fixed From 72a0b599c460e2647fad2e6f14b6f18f7616e7b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 13 Jan 2014 12:49:45 +0100 Subject: [PATCH 249/523] Fix the i18n cut optimization restriction (we need UTF8 to grant uniqueness of characters and using strchr() approach), unset the unnecessary envvars after colorls scripts(#1051703) --- coreutils-colorls.csh | 2 ++ coreutils-colorls.sh | 2 ++ coreutils-i18n.patch | 8 ++++++-- coreutils.spec | 6 +++++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 38abdc7..5ed0f68 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -51,6 +51,8 @@ if ( "$color_none" != '' ) then endif unset color_none unset _tmp +unset INCLUDE +unset COLORS finish: alias ll 'ls -l --color=auto' diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index f1b227b..1308da9 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -45,6 +45,8 @@ if [ -z "$USER_LS_COLORS" ]; then grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return fi +unset TMP COLORS INCLUDE + alias ll='ls -l --color=auto' 2>/dev/null alias l.='ls -d .* --color=auto' 2>/dev/null alias ls='ls --color=auto' 2>/dev/null diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index a0c2717..467750d 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -258,7 +258,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -629,13 +786,207 @@ cut_fields (FILE *stream) +@@ -629,13 +786,211 @@ cut_fields (FILE *stream) } } @@ -443,8 +443,12 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + 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"))) ++ if (loc && (strstr (loc, "UTF-8") || strstr (loc, "utf-8") || ++ strstr (loc, "UTF8") || strstr (loc, "utf8"))) + { + cut_fields (stream); + break; diff --git a/coreutils.spec b/coreutils.spec index cd65278..a227de7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,10 @@ fi %{_sbindir}/chroot %changelog +* Mon Jan 13 2014 Ondrej Vasik 8.22-10 +- unset the unnecessary envvars after colorls scripts(#1051703) +- improve the limitation (check for both utf8 and utf-8) + * Fri Jan 10 2014 Ondrej Oprala 8.22-9 - Limit the cut optimizations to UTF-8 locales only From 55f7ecdd4a223f0a7523145a301353aa7e2c4869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 13 Jan 2014 16:26:44 +0100 Subject: [PATCH 250/523] cp/mv/install: do not crash when getfscreatecon() is returning a NULL context --- coreutils-6.10-configuration.patch | 2 +- coreutils-8.22-cp-selinux.patch | 109 +++++++++++++++++++++++++++++ coreutils.spec | 10 ++- 3 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 coreutils-8.22-cp-selinux.patch diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index e14711b..54df1d6 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -136,8 +136,8 @@ diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk tests/touch/now-owned-by-other.sh @@ -163,7 +164,6 @@ all_tests = \ - tests/rm/cycle.sh \ tests/cp/link-heap.sh \ + tests/cp/no-ctx.sh \ tests/misc/tty-eof.pl \ - tests/tail-2/inotify-hash-abuse.sh \ tests/tail-2/inotify-hash-abuse2.sh \ diff --git a/coreutils-8.22-cp-selinux.patch b/coreutils-8.22-cp-selinux.patch new file mode 100644 index 0000000..ed3fb47 --- /dev/null +++ b/coreutils-8.22-cp-selinux.patch @@ -0,0 +1,109 @@ +From 2b3b5bfcd5f4161d17c0bc3d43f6edcfc4a2b294 Mon Sep 17 00:00:00 2001 +From: Nicolas Looss +Date: Sat, 4 Jan 2014 03:03:51 +0000 +Subject: [PATCH] copy: fix a segfault in SELinux context copying code + +* src/selinux.c (restorecon_private): On ArchLinux the +`fakeroot cp -a file1 file2` command segfaulted due +to getfscreatecon() returning a NULL context. +So map this to the sometimes ignored ENODATA error, +rather than crashing. +* tests/cp/no-ctx.sh: Add a new test case. +* tests/local.mk: Reference the new test. +--- + src/selinux.c | 5 ++++ + tests/cp/no-ctx.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + tests/local.mk | 1 + + 3 files changed, 59 insertions(+), 0 deletions(-) + create mode 100755 tests/cp/no-ctx.sh + +diff --git a/src/selinux.c b/src/selinux.c +index cd38a81..016db16 100644 +--- a/src/selinux.c ++++ b/src/selinux.c +@@ -192,6 +192,11 @@ restorecon_private (char const *path, bool local) + { + if (getfscreatecon (&tcon) < 0) + return rc; ++ if (!tcon) ++ { ++ errno = ENODATA; ++ return rc; ++ } + rc = lsetfilecon (path, tcon); + freecon (tcon); + return rc; +diff --git a/tests/cp/no-ctx.sh b/tests/cp/no-ctx.sh +new file mode 100755 +index 0000000..59d30de +--- /dev/null ++++ b/tests/cp/no-ctx.sh +@@ -0,0 +1,53 @@ ++#!/bin/sh ++# Ensure we handle file systems returning no SELinux context, ++# which triggered a segmentation fault in coreutils-8.22. ++# This test is skipped on systems that lack LD_PRELOAD support; that's fine. ++# Similarly, on a system that lacks lgetfilecon altogether, skipping it is fine. ++ ++# Copyright (C) 2014 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_ cp ++require_gcc_shared_ ++ ++# Replace each getfilecon and lgetfilecon call with a call to these stubs. ++cat > k.c <<'EOF' || skip_ ++#include ++#include ++ ++int getfilecon (const char *path, security_context_t *con) ++{ errno=ENODATA; return -1; } ++int lgetfilecon (const char *path, security_context_t *con) ++{ errno=ENODATA; return -1; } ++EOF ++ ++# Then compile/link it: ++$CC -shared -fPIC -O2 k.c -o k.so \ ++ || skip_ 'failed to build SELinux shared library' ++ ++touch file_src ++ ++# New file with SELinux context optionally included ++LD_PRELOAD=./k.so cp -a file_src file_dst || fail=1 ++ ++# Existing file with SELinux context optionally included ++LD_PRELOAD=./k.so cp -a file_src file_dst || fail=1 ++ ++# ENODATA should give an immediate error when required to preserve ctx ++# This is debatable, and maybe we should not fail when no context available? ++LD_PRELOAD=./k.so cp --preserve=context file_src file_dst && fail=1 ++ ++Exit $fail +diff --git a/tests/local.mk b/tests/local.mk +index dc7341c..9d556f6 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -161,6 +161,7 @@ all_tests = \ + tests/rm/ext3-perf.sh \ + tests/rm/cycle.sh \ + tests/cp/link-heap.sh \ ++ tests/cp/no-ctx.sh \ + tests/misc/tty-eof.pl \ + tests/tail-2/inotify-hash-abuse.sh \ + tests/tail-2/inotify-hash-abuse2.sh \ +-- +1.7.7.6 + diff --git a/coreutils.spec b/coreutils.spec index a227de7..17deef4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -13,6 +13,7 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream +Patch1: coreutils-8.22-cp-selinux.patch # Our patches #general patch to workaround koji build system issues @@ -126,6 +127,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %setup -q # From upstream +%patch1 -p1 -b .nullcontext # Our patches %patch100 -p1 -b .configure @@ -151,7 +153,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh || : +chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh tests/cp/no-ctx.sh || : #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -372,6 +374,10 @@ fi %{_sbindir}/chroot %changelog +* Mon Jan 13 2014 Ondrej Vasik 8.22-11 +- cp/mv/install: do not crash when getfscreatecon() is + returning a NULL context + * Mon Jan 13 2014 Ondrej Vasik 8.22-10 - unset the unnecessary envvars after colorls scripts(#1051703) - improve the limitation (check for both utf8 and utf-8) From d700b52311dba762adf813dc476dfebbeb05afa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sun, 2 Mar 2014 20:45:06 +0100 Subject: [PATCH 251/523] fix the date crash or infloop in TZ= parsing (#1069657, from upstream) --- coreutils-8.22-datetzcrash.patch | 67 ++++++++++++++++++++++++++++++++ coreutils.spec | 7 +++- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.22-datetzcrash.patch diff --git a/coreutils-8.22-datetzcrash.patch b/coreutils-8.22-datetzcrash.patch new file mode 100644 index 0000000..44481af --- /dev/null +++ b/coreutils-8.22-datetzcrash.patch @@ -0,0 +1,67 @@ +diff -urNp coreutils-8.22-orig/gnulib-tests/test-parse-datetime.c coreutils-8.22/gnulib-tests/test-parse-datetime.c +--- coreutils-8.22-orig/gnulib-tests/test-parse-datetime.c 2013-12-04 15:53:33.000000000 +0100 ++++ coreutils-8.22/gnulib-tests/test-parse-datetime.c 2014-03-02 20:33:25.691688592 +0100 +@@ -419,5 +419,21 @@ main (int argc _GL_UNUSED, char **argv) + starting with a high-bit-set byte would be treated like "0". */ + ASSERT ( ! parse_datetime (&result, "\xb0", &now)); + ++ /* Exercise TZ="" parsing code. */ ++ /* These two would infloop or segfault before Feb 2014. */ ++ ASSERT ( ! parse_datetime (&result, "TZ=\"\"\"", &now)); ++ ASSERT ( ! parse_datetime (&result, "TZ=\"\" \"", &now)); ++ /* Exercise invalid patterns. */ ++ ASSERT ( ! parse_datetime (&result, "TZ=\"", &now)); ++ ASSERT ( ! parse_datetime (&result, "TZ=\"\\\"", &now)); ++ ASSERT ( ! parse_datetime (&result, "TZ=\"\\n", &now)); ++ ASSERT ( ! parse_datetime (&result, "TZ=\"\\n\"", &now)); ++ /* Exercise valid patterns. */ ++ ASSERT ( parse_datetime (&result, "TZ=\"\"", &now)); ++ ASSERT ( parse_datetime (&result, "TZ=\"\" ", &now)); ++ ASSERT ( parse_datetime (&result, " TZ=\"\"", &now)); ++ ASSERT ( parse_datetime (&result, "TZ=\"\\\\\"", &now)); ++ ASSERT ( parse_datetime (&result, "TZ=\"\\\"\"", &now)); ++ + return 0; + } +diff -urNp coreutils-8.22-orig/lib/parse-datetime.y coreutils-8.22/lib/parse-datetime.y +--- coreutils-8.22-orig/lib/parse-datetime.y 2013-12-04 15:53:33.000000000 +0100 ++++ coreutils-8.22/lib/parse-datetime.y 2014-03-02 20:32:23.246124920 +0100 +@@ -1303,8 +1303,6 @@ parse_datetime (struct timespec *result, + char tz1buf[TZBUFSIZE]; + bool large_tz = TZBUFSIZE < tzsize; + bool setenv_ok; +- /* Free tz0, in case this is the 2nd or subsequent time through. */ +- free (tz0); + tz0 = get_tz (tz0buf); + z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf; + for (s = tzbase; *s != '"'; s++) +@@ -1316,7 +1314,12 @@ parse_datetime (struct timespec *result, + if (!setenv_ok) + goto fail; + tz_was_altered = true; ++ + p = s + 1; ++ while (c = *p, c_isspace (c)) ++ p++; ++ ++ break; + } + } + +diff -urNp coreutils-8.22-orig/tests/misc/date.pl coreutils-8.22/tests/misc/date.pl +--- coreutils-8.22-orig/tests/misc/date.pl 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/date.pl 2014-03-02 20:30:43.200328295 +0100 +@@ -287,6 +287,13 @@ my @Tests = + {ERR => "date: invalid date '\\260'\n"}, + {EXIT => 1}, + ], ++ ++ # From coreutils-5.3.0 to 8.22 inclusive ++ # this would either infinite loop or crash ++ ['invalid-TZ-crash', "-d 'TZ=\"\"\"'", ++ {ERR => "date: invalid date 'TZ=\"\"\"'\n"}, ++ {EXIT => 1}, ++ ], + ); + + # Repeat the cross-dst test, using Jan 1, 2005 and every interval from 1..364. diff --git a/coreutils.spec b/coreutils.spec index 17deef4..b7feeea 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -14,6 +14,7 @@ Source106: coreutils-colorls.csh # From upstream Patch1: coreutils-8.22-cp-selinux.patch +Patch2: coreutils-8.22-datetzcrash.patch # Our patches #general patch to workaround koji build system issues @@ -128,6 +129,7 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .nullcontext +%patch2 -p1 -b .tzcrash # Our patches %patch100 -p1 -b .configure @@ -374,6 +376,9 @@ fi %{_sbindir}/chroot %changelog +* Sun Mar 02 2014 Ondrej Vasik 8.22-12 +- fix the date crash or infloop in TZ="" parsing (#1069657) + * Mon Jan 13 2014 Ondrej Vasik 8.22-11 - cp/mv/install: do not crash when getfscreatecon() is returning a NULL context From 156e6cc237dda13e654d12dd20c1ab6bae245e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sun, 2 Mar 2014 21:53:37 +0100 Subject: [PATCH 252/523] Temporarily disable nohup.sh test, strange /dev/tty issue fail --- coreutils-6.10-configuration.patch | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 54df1d6..b5f882f 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -155,3 +155,15 @@ diff -urNp coreutils-8.21-orig/tests/touch/no-dereference.sh coreutils-8.21/test # Changing time of dangling symlink is okay. # Skip the test if this fails, but the error text corresponds to +diff -urNp coreutils-8.22-orig/tests/misc/nohup.sh coreutils-8.22/tests/misc/nohup.sh +--- coreutils-8.22-orig/tests/misc/nohup.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/misc/nohup.sh 2014-03-02 21:51:01.972887749 +0100 +@@ -19,6 +19,8 @@ + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ nohup + ++#mark it expensive, to temporarily skip the test in koji ++expensive_ + + nohup sh -c 'echo stdout; echo stderr 1>&2' 2>err || fail=1 + From 1240520fa112f733ddfa2bc2b33ea93de1a28b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 5 Mar 2014 13:52:27 +0100 Subject: [PATCH 253/523] drop the util-linux requirements (smaller docker images), drop ancient obsoletes of -libs subpackage --- coreutils.spec | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index b7feeea..6a98af6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -115,10 +115,6 @@ Obsoletes: fileutils <= 4.1.9 Obsoletes: sh-utils <= 2.0.12 Obsoletes: stat <= 3.3 Obsoletes: textutils <= 2.0.21 -#coreutils-libs dropped in f17 -Obsoletes: coreutils-libs < 8.13 -#require util-linux >=2.22.1-3 to prevent lack of su/runuser on system -Requires: util-linux >= 2.22.1-3 %description These are the GNU core utilities. This package is the combination of @@ -376,6 +372,10 @@ fi %{_sbindir}/chroot %changelog +* Wed Mar 05 2014 Ondrej Vasik 8.22-13 +- drop the util-linux requirements (smaller docker images), + drop ancient obsoletes of -libs subpackage + * Sun Mar 02 2014 Ondrej Vasik 8.22-12 - fix the date crash or infloop in TZ="" parsing (#1069657) From 136250677d187ac435eb3e19422794c6ec1e7ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 12 Apr 2014 20:38:09 -0700 Subject: [PATCH 254/523] fix dd sparse test failure on xfs filesystem(#1085727,by P.Brady) --- ...dd-sparsetest-xfsspeculativeprealloc.patch | 20 +++++++++++++++++++ coreutils.spec | 8 +++++++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch diff --git a/coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch b/coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch new file mode 100644 index 0000000..8c5f4d7 --- /dev/null +++ b/coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch @@ -0,0 +1,20 @@ +diff -urNp coreutils-8.22-orig/tests/dd/sparse.sh coreutils-8.22/tests/dd/sparse.sh +--- coreutils-8.22-orig/tests/dd/sparse.sh 2013-12-04 06:48:30.000000000 -0800 ++++ coreutils-8.22/tests/dd/sparse.sh 2014-04-12 17:48:22.301975386 -0700 +@@ -61,8 +61,15 @@ if test $(kb_alloc file.in) -gt 3000; th + dd if=file.in of=file.out bs=2M conv=sparse + test 2500 -lt $(kb_alloc file.out) || fail=1 + ++ # Note we recreate a sparse file first to avoid ++ # speculative preallocation seen in XFS, where a write() that ++ # extends a file can preallocate some extra space that ++ # a subsequent seek will not convert to a hole. ++ rm -f file.out ++ truncate --size=3M file.out ++ + # Ensure that this 1MiB string of NULs *is* converted to a hole. +- dd if=file.in of=file.out bs=1M conv=sparse ++ dd if=file.in of=file.out bs=1M conv=sparse,notrunc + test $(kb_alloc file.out) -lt 2500 || fail=1 + + fi diff --git a/coreutils.spec b/coreutils.spec index 6a98af6..542695b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 13%{?dist} +Release: 14%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -15,6 +15,7 @@ Source106: coreutils-colorls.csh # From upstream Patch1: coreutils-8.22-cp-selinux.patch Patch2: coreutils-8.22-datetzcrash.patch +Patch3: coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch # Our patches #general patch to workaround koji build system issues @@ -126,6 +127,7 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .nullcontext %patch2 -p1 -b .tzcrash +%patch3 -p1 -b .xfs # Our patches %patch100 -p1 -b .configure @@ -372,6 +374,10 @@ fi %{_sbindir}/chroot %changelog +* Sat Apr 12 2014 Ondrej Vasik 8.22-14 +- fix dd sparse test failure on xfs filesystem(#1085727, + by P.Brady) + * Wed Mar 05 2014 Ondrej Vasik 8.22-13 - drop the util-linux requirements (smaller docker images), drop ancient obsoletes of -libs subpackage From 8d24562387351499b6124367db147ee0532ea9ed Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Sat, 7 Jun 2014 00:55:53 -0500 Subject: [PATCH 255/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 542695b..5be272b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 14%{?dist} +Release: 15%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -374,6 +374,9 @@ fi %{_sbindir}/chroot %changelog +* Sat Jun 07 2014 Fedora Release Engineering - 8.22-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + * Sat Apr 12 2014 Ondrej Vasik 8.22-14 - fix dd sparse test failure on xfs filesystem(#1085727, by P.Brady) From 2af6179bec2f30a541211d68e3c4e0ebc8b5620f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C4=8Cajka?= Date: Mon, 23 Jun 2014 14:38:45 +0200 Subject: [PATCH 256/523] Fixed gnulib tests on ppc64(le) --- coreutils-ppc-gnulib-tests.patch | 39 ++++++++++++++++++++++++++++++++ coreutils.spec | 8 ++++++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 coreutils-ppc-gnulib-tests.patch diff --git a/coreutils-ppc-gnulib-tests.patch b/coreutils-ppc-gnulib-tests.patch new file mode 100644 index 0000000..f8634ed --- /dev/null +++ b/coreutils-ppc-gnulib-tests.patch @@ -0,0 +1,39 @@ +diff -up coreutils-8.22/gnulib-tests/test-isnanl.h.ppc coreutils-8.22/gnulib-tests/test-isnanl.h +--- coreutils-8.22/gnulib-tests/test-isnanl.h.ppc 2014-06-23 14:01:05.925541920 +0200 ++++ coreutils-8.22/gnulib-tests/test-isnanl.h 2014-06-23 14:01:39.437617584 +0200 +@@ -51,6 +51,15 @@ main () + /* A bit pattern that is different from a Quiet NaN. With a bit of luck, + it's a Signalling NaN. */ + { ++#if defined __powerpc__ && LDBL_MANT_DIG == 106 ++ /* This is PowerPC "double double", a pair of two doubles. Inf and Nan are ++ represented as the corresponding 64-bit IEEE values in the first double; ++ the second is ignored. Manipulate only the first double. */ ++ #undef NWORDS ++ #define NWORDS \ ++ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) ++#endif ++ + memory_long_double m; + m.value = NaNl (); + # if LDBL_EXPBIT0_BIT > 0 +diff -up coreutils-8.22/gnulib-tests/test-signbit.c.ppc coreutils-8.22/gnulib-tests/test-signbit.c +--- coreutils-8.22/gnulib-tests/test-signbit.c.ppc 2013-12-04 15:53:33.000000000 +0100 ++++ coreutils-8.22/gnulib-tests/test-signbit.c 2014-06-23 13:59:20.378307385 +0200 +@@ -151,6 +151,16 @@ test_signbitl () + #define NWORDS \ + ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) + typedef union { long double value; unsigned int word[NWORDS]; } memory_long_double; ++ ++#if defined __powerpc__ && LDBL_MANT_DIG == 106 ++ /* This is PowerPC "double double", a pair of two doubles. Inf and Nan are ++ represented as the corresponding 64-bit IEEE values in the first double; ++ the second is ignored. Manipulate only the first double. */ ++ #undef NWORDS ++ #define NWORDS \ ++ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) ++#endif ++ + memory_long_double m; + m.value = zerol / zerol; + # if LDBL_EXPBIT0_BIT > 0 diff --git a/coreutils.spec b/coreutils.spec index 5be272b..0d202ff 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 15%{?dist} +Release: 16%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -16,6 +16,8 @@ Source106: coreutils-colorls.csh Patch1: coreutils-8.22-cp-selinux.patch Patch2: coreutils-8.22-datetzcrash.patch Patch3: coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch +#backport of patch from gnulib fixing tests on powerPC +Patch4: coreutils-ppc-gnulib-tests.patch # Our patches #general patch to workaround koji build system issues @@ -128,6 +130,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch1 -p1 -b .nullcontext %patch2 -p1 -b .tzcrash %patch3 -p1 -b .xfs +%patch4 -p1 -b .ppc # Our patches %patch100 -p1 -b .configure @@ -374,6 +377,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Jun 23 2014 Jakub Čajka - 8.22-16 +- fix failed tests on ppc(backport from gnulib upstream) + * Sat Jun 07 2014 Fedora Release Engineering - 8.22-15 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild From 8246976bb3d1f40cf5f32c34a924fb431a7b9eb5 Mon Sep 17 00:00:00 2001 From: Tom Callaway Date: Fri, 11 Jul 2014 16:44:33 -0400 Subject: [PATCH 257/523] fix license handling --- coreutils.spec | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 0d202ff..442b99b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.22 -Release: 16%{?dist} +Release: 17%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -269,7 +269,9 @@ fi %dir %{_datadir}/locale/*/LC_TIME %config(noreplace) %{_sysconfdir}/DIR_COLORS* %config(noreplace) %{_sysconfdir}/profile.d/* -%doc COPYING ABOUT-NLS ChangeLog.bz2 NEWS README THANKS TODO old/* +%doc ABOUT-NLS ChangeLog.bz2 NEWS README THANKS TODO old/* +%{!?_licensedir:%global license %%doc} +%license COPYING %{_bindir}/arch %{_bindir}/basename %{_bindir}/cat @@ -377,6 +379,9 @@ fi %{_sbindir}/chroot %changelog +* Fri Jul 11 2014 Tom Callaway - 8.22-17 +- fix license handling + * Mon Jun 23 2014 Jakub Čajka - 8.22-16 - fix failed tests on ppc(backport from gnulib upstream) From 9c33d82fb48be25ce20e05aa5c081a47eeec3f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 22 Jul 2014 14:01:39 +0200 Subject: [PATCH 258/523] new upstream release 8.23, synchronize the old differences in ls SELinux options with upstream --- .gitignore | 2 + coreutils-8.22-cp-selinux.patch | 109 ----- coreutils-8.22-datetzcrash.patch | 67 --- ...dd-sparsetest-xfsspeculativeprealloc.patch | 20 - coreutils-df-direct.patch | 4 +- coreutils-i18n.patch | 176 ++++---- coreutils-ppc-gnulib-tests.patch | 39 -- coreutils-selinux.patch | 423 +----------------- coreutils.spec | 21 +- sources | 3 +- 10 files changed, 105 insertions(+), 759 deletions(-) delete mode 100644 coreutils-8.22-cp-selinux.patch delete mode 100644 coreutils-8.22-datetzcrash.patch delete mode 100644 coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch delete mode 100644 coreutils-ppc-gnulib-tests.patch diff --git a/.gitignore b/.gitignore index 53ec760..cbcc306 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ /coreutils-8.20.tar.xz /coreutils-8.21.tar.xz /coreutils-8.22.tar.xz +/coreutils-8.23.tar.xz +/coreutils-8.23.tar.xz.sig diff --git a/coreutils-8.22-cp-selinux.patch b/coreutils-8.22-cp-selinux.patch deleted file mode 100644 index ed3fb47..0000000 --- a/coreutils-8.22-cp-selinux.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 2b3b5bfcd5f4161d17c0bc3d43f6edcfc4a2b294 Mon Sep 17 00:00:00 2001 -From: Nicolas Looss -Date: Sat, 4 Jan 2014 03:03:51 +0000 -Subject: [PATCH] copy: fix a segfault in SELinux context copying code - -* src/selinux.c (restorecon_private): On ArchLinux the -`fakeroot cp -a file1 file2` command segfaulted due -to getfscreatecon() returning a NULL context. -So map this to the sometimes ignored ENODATA error, -rather than crashing. -* tests/cp/no-ctx.sh: Add a new test case. -* tests/local.mk: Reference the new test. ---- - src/selinux.c | 5 ++++ - tests/cp/no-ctx.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - tests/local.mk | 1 + - 3 files changed, 59 insertions(+), 0 deletions(-) - create mode 100755 tests/cp/no-ctx.sh - -diff --git a/src/selinux.c b/src/selinux.c -index cd38a81..016db16 100644 ---- a/src/selinux.c -+++ b/src/selinux.c -@@ -192,6 +192,11 @@ restorecon_private (char const *path, bool local) - { - if (getfscreatecon (&tcon) < 0) - return rc; -+ if (!tcon) -+ { -+ errno = ENODATA; -+ return rc; -+ } - rc = lsetfilecon (path, tcon); - freecon (tcon); - return rc; -diff --git a/tests/cp/no-ctx.sh b/tests/cp/no-ctx.sh -new file mode 100755 -index 0000000..59d30de ---- /dev/null -+++ b/tests/cp/no-ctx.sh -@@ -0,0 +1,53 @@ -+#!/bin/sh -+# Ensure we handle file systems returning no SELinux context, -+# which triggered a segmentation fault in coreutils-8.22. -+# This test is skipped on systems that lack LD_PRELOAD support; that's fine. -+# Similarly, on a system that lacks lgetfilecon altogether, skipping it is fine. -+ -+# Copyright (C) 2014 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_ cp -+require_gcc_shared_ -+ -+# Replace each getfilecon and lgetfilecon call with a call to these stubs. -+cat > k.c <<'EOF' || skip_ -+#include -+#include -+ -+int getfilecon (const char *path, security_context_t *con) -+{ errno=ENODATA; return -1; } -+int lgetfilecon (const char *path, security_context_t *con) -+{ errno=ENODATA; return -1; } -+EOF -+ -+# Then compile/link it: -+$CC -shared -fPIC -O2 k.c -o k.so \ -+ || skip_ 'failed to build SELinux shared library' -+ -+touch file_src -+ -+# New file with SELinux context optionally included -+LD_PRELOAD=./k.so cp -a file_src file_dst || fail=1 -+ -+# Existing file with SELinux context optionally included -+LD_PRELOAD=./k.so cp -a file_src file_dst || fail=1 -+ -+# ENODATA should give an immediate error when required to preserve ctx -+# This is debatable, and maybe we should not fail when no context available? -+LD_PRELOAD=./k.so cp --preserve=context file_src file_dst && fail=1 -+ -+Exit $fail -diff --git a/tests/local.mk b/tests/local.mk -index dc7341c..9d556f6 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -161,6 +161,7 @@ all_tests = \ - tests/rm/ext3-perf.sh \ - tests/rm/cycle.sh \ - tests/cp/link-heap.sh \ -+ tests/cp/no-ctx.sh \ - tests/misc/tty-eof.pl \ - tests/tail-2/inotify-hash-abuse.sh \ - tests/tail-2/inotify-hash-abuse2.sh \ --- -1.7.7.6 - diff --git a/coreutils-8.22-datetzcrash.patch b/coreutils-8.22-datetzcrash.patch deleted file mode 100644 index 44481af..0000000 --- a/coreutils-8.22-datetzcrash.patch +++ /dev/null @@ -1,67 +0,0 @@ -diff -urNp coreutils-8.22-orig/gnulib-tests/test-parse-datetime.c coreutils-8.22/gnulib-tests/test-parse-datetime.c ---- coreutils-8.22-orig/gnulib-tests/test-parse-datetime.c 2013-12-04 15:53:33.000000000 +0100 -+++ coreutils-8.22/gnulib-tests/test-parse-datetime.c 2014-03-02 20:33:25.691688592 +0100 -@@ -419,5 +419,21 @@ main (int argc _GL_UNUSED, char **argv) - starting with a high-bit-set byte would be treated like "0". */ - ASSERT ( ! parse_datetime (&result, "\xb0", &now)); - -+ /* Exercise TZ="" parsing code. */ -+ /* These two would infloop or segfault before Feb 2014. */ -+ ASSERT ( ! parse_datetime (&result, "TZ=\"\"\"", &now)); -+ ASSERT ( ! parse_datetime (&result, "TZ=\"\" \"", &now)); -+ /* Exercise invalid patterns. */ -+ ASSERT ( ! parse_datetime (&result, "TZ=\"", &now)); -+ ASSERT ( ! parse_datetime (&result, "TZ=\"\\\"", &now)); -+ ASSERT ( ! parse_datetime (&result, "TZ=\"\\n", &now)); -+ ASSERT ( ! parse_datetime (&result, "TZ=\"\\n\"", &now)); -+ /* Exercise valid patterns. */ -+ ASSERT ( parse_datetime (&result, "TZ=\"\"", &now)); -+ ASSERT ( parse_datetime (&result, "TZ=\"\" ", &now)); -+ ASSERT ( parse_datetime (&result, " TZ=\"\"", &now)); -+ ASSERT ( parse_datetime (&result, "TZ=\"\\\\\"", &now)); -+ ASSERT ( parse_datetime (&result, "TZ=\"\\\"\"", &now)); -+ - return 0; - } -diff -urNp coreutils-8.22-orig/lib/parse-datetime.y coreutils-8.22/lib/parse-datetime.y ---- coreutils-8.22-orig/lib/parse-datetime.y 2013-12-04 15:53:33.000000000 +0100 -+++ coreutils-8.22/lib/parse-datetime.y 2014-03-02 20:32:23.246124920 +0100 -@@ -1303,8 +1303,6 @@ parse_datetime (struct timespec *result, - char tz1buf[TZBUFSIZE]; - bool large_tz = TZBUFSIZE < tzsize; - bool setenv_ok; -- /* Free tz0, in case this is the 2nd or subsequent time through. */ -- free (tz0); - tz0 = get_tz (tz0buf); - z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf; - for (s = tzbase; *s != '"'; s++) -@@ -1316,7 +1314,12 @@ parse_datetime (struct timespec *result, - if (!setenv_ok) - goto fail; - tz_was_altered = true; -+ - p = s + 1; -+ while (c = *p, c_isspace (c)) -+ p++; -+ -+ break; - } - } - -diff -urNp coreutils-8.22-orig/tests/misc/date.pl coreutils-8.22/tests/misc/date.pl ---- coreutils-8.22-orig/tests/misc/date.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/date.pl 2014-03-02 20:30:43.200328295 +0100 -@@ -287,6 +287,13 @@ my @Tests = - {ERR => "date: invalid date '\\260'\n"}, - {EXIT => 1}, - ], -+ -+ # From coreutils-5.3.0 to 8.22 inclusive -+ # this would either infinite loop or crash -+ ['invalid-TZ-crash', "-d 'TZ=\"\"\"'", -+ {ERR => "date: invalid date 'TZ=\"\"\"'\n"}, -+ {EXIT => 1}, -+ ], - ); - - # Repeat the cross-dst test, using Jan 1, 2005 and every interval from 1..364. diff --git a/coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch b/coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch deleted file mode 100644 index 8c5f4d7..0000000 --- a/coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff -urNp coreutils-8.22-orig/tests/dd/sparse.sh coreutils-8.22/tests/dd/sparse.sh ---- coreutils-8.22-orig/tests/dd/sparse.sh 2013-12-04 06:48:30.000000000 -0800 -+++ coreutils-8.22/tests/dd/sparse.sh 2014-04-12 17:48:22.301975386 -0700 -@@ -61,8 +61,15 @@ if test $(kb_alloc file.in) -gt 3000; th - dd if=file.in of=file.out bs=2M conv=sparse - test 2500 -lt $(kb_alloc file.out) || fail=1 - -+ # Note we recreate a sparse file first to avoid -+ # speculative preallocation seen in XFS, where a write() that -+ # extends a file can preallocate some extra space that -+ # a subsequent seek will not convert to a hole. -+ rm -f file.out -+ truncate --size=3M file.out -+ - # Ensure that this 1MiB string of NULs *is* converted to a hole. -- dd if=file.in of=file.out bs=1M conv=sparse -+ dd if=file.in of=file.out bs=1M conv=sparse,notrunc - test $(kb_alloc file.out) -lt 2500 || fail=1 - - fi diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index a52307a..a3df5e9 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -83,8 +83,8 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c see SIZE format below\n\ + --direct show statistics for a file instead of mount point\n\ --total produce a grand total\n\ - -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\ - \n\ + -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ + -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ @@ -1305,6 +1325,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 467750d..633825e 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.22-orig/lib/linebuffer.h coreutils-8.22/lib/linebuffer.h ---- coreutils-8.22-orig/lib/linebuffer.h 2013-12-04 15:53:33.000000000 +0100 -+++ coreutils-8.22/lib/linebuffer.h 2014-01-08 13:55:56.106375471 +0100 +diff -urNp coreutils-8.23-orig/lib/linebuffer.h coreutils-8.23/lib/linebuffer.h +--- coreutils-8.23-orig/lib/linebuffer.h 2014-05-29 14:05:50.000000000 +0200 ++++ coreutils-8.23/lib/linebuffer.h 2014-07-22 13:45:52.700651881 +0200 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.22-orig/lib/linebuffer.h coreutils-8.22/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c ---- coreutils-8.22-orig/src/cut.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/cut.c 2014-01-08 13:55:56.108375451 +0100 +diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c +--- coreutils-8.23-orig/src/cut.c 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/src/cut.c 2014-07-22 13:48:06.225671732 +0200 @@ -28,6 +28,11 @@ #include #include @@ -130,7 +130,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + /* Output characters that are at the given positions. */ + character_mode, + - /* Output the given delimeter-separated fields. */ + /* Output the given delimiter-separated fields. */ field_mode }; @@ -143,12 +143,12 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c + if this program runs on multibyte locale. */ +static int force_singlebyte_mode; + - /* If true do not output lines containing no delimeter characters. + /* If true do not output lines containing no delimiter characters. Otherwise, all such lines are printed. This option is valid only with field mode. */ @@ -126,6 +201,9 @@ static bool complement; - /* The delimeter character for field mode. */ + /* The delimiter character for field mode. */ static unsigned char delim; +#if HAVE_WCHAR_H +static wchar_t wcdelim; @@ -156,7 +156,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -188,7 +266,7 @@ Print selected parts of lines from each +@@ -188,7 +266,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\ @@ -258,7 +258,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -629,13 +786,211 @@ cut_fields (FILE *stream) +@@ -649,13 +806,211 @@ cut_fields (FILE *stream) } } @@ -473,7 +473,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c } /* Process file FILE to standard output. -@@ -687,6 +1038,7 @@ main (int argc, char **argv) +@@ -707,6 +1062,7 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -481,7 +481,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -709,7 +1061,6 @@ main (int argc, char **argv) +@@ -729,7 +1085,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -489,7 +489,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -717,6 +1068,14 @@ main (int argc, char **argv) +@@ -737,6 +1092,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -504,7 +504,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -728,10 +1087,38 @@ main (int argc, char **argv) +@@ -748,10 +1111,38 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -547,7 +547,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -744,6 +1131,7 @@ main (int argc, char **argv) +@@ -764,6 +1155,7 @@ main (int argc, char **argv) break; case 'n': @@ -555,7 +555,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c break; case 's': -@@ -783,15 +1171,34 @@ main (int argc, char **argv) +@@ -803,15 +1195,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -596,9 +596,9 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.22-orig/src/expand.c coreutils-8.22/src/expand.c ---- coreutils-8.22-orig/src/expand.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/expand.c 2014-01-08 13:55:56.110375431 +0100 +diff -urNp coreutils-8.23-orig/src/expand.c coreutils-8.23/src/expand.c +--- coreutils-8.23-orig/src/expand.c 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/src/expand.c 2014-07-22 13:45:52.704651900 +0200 @@ -37,12 +37,34 @@ #include #include @@ -791,9 +791,9 @@ diff -urNp coreutils-8.22-orig/src/expand.c coreutils-8.22/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.22-orig/src/fold.c coreutils-8.22/src/fold.c ---- coreutils-8.22-orig/src/fold.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/fold.c 2014-01-08 13:55:56.111375421 +0100 +diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c +--- coreutils-8.23-orig/src/fold.c 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/src/fold.c 2014-07-22 13:45:52.705651904 +0200 @@ -22,12 +22,34 @@ #include #include @@ -1191,9 +1191,9 @@ diff -urNp coreutils-8.22-orig/src/fold.c coreutils-8.22/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c ---- coreutils-8.22-orig/src/join.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/join.c 2014-01-08 13:55:56.113375401 +0100 +diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c +--- coreutils-8.23-orig/src/join.c 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/src/join.c 2014-07-22 13:45:52.707651912 +0200 @@ -22,18 +22,32 @@ #include #include @@ -1686,9 +1686,9 @@ diff -urNp coreutils-8.22-orig/src/join.c coreutils-8.22/src/join.c break; case 'z': -diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c ---- coreutils-8.22-orig/src/pr.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/pr.c 2014-01-08 13:55:56.118375350 +0100 +diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c +--- coreutils-8.23-orig/src/pr.c 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/src/pr.c 2014-07-22 13:45:52.713651936 +0200 @@ -312,6 +312,24 @@ #include @@ -2452,9 +2452,9 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c ---- coreutils-8.22-orig/src/sort.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/sort.c 2014-01-08 13:55:56.123375301 +0100 +diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c +--- coreutils-8.23-orig/src/sort.c 2014-07-14 00:09:52.000000000 +0200 ++++ coreutils-8.23/src/sort.c 2014-07-22 13:45:52.719651960 +0200 @@ -29,6 +29,14 @@ #include #include @@ -3333,7 +3333,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c { /* Note xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4113,6 +4738,7 @@ set_ordering (char const *s, struct keyf +@@ -4121,6 +4746,7 @@ set_ordering (char const *s, struct keyf break; case 'f': key->translate = fold_toupper; @@ -3341,7 +3341,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c break; case 'g': key->general_numeric = true; -@@ -4190,7 +4816,7 @@ main (int argc, char **argv) +@@ -4198,7 +4824,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3350,7 +3350,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4211,6 +4837,29 @@ main (int argc, char **argv) +@@ -4219,6 +4845,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3380,7 +3380,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c have_read_stdin = false; inittables (); -@@ -4485,13 +5134,34 @@ main (int argc, char **argv) +@@ -4493,13 +5142,34 @@ main (int argc, char **argv) case 't': { @@ -3419,7 +3419,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4502,9 +5172,12 @@ main (int argc, char **argv) +@@ -4510,9 +5180,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3434,9 +3434,9 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c } break; -diff -urNp coreutils-8.22-orig/src/unexpand.c coreutils-8.22/src/unexpand.c ---- coreutils-8.22-orig/src/unexpand.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/unexpand.c 2014-01-08 13:55:56.126375271 +0100 +diff -urNp coreutils-8.23-orig/src/unexpand.c coreutils-8.23/src/unexpand.c +--- coreutils-8.23-orig/src/unexpand.c 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/src/unexpand.c 2014-07-22 13:45:52.721651968 +0200 @@ -38,12 +38,29 @@ #include #include @@ -3692,9 +3692,9 @@ diff -urNp coreutils-8.22-orig/src/unexpand.c coreutils-8.22/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c ---- coreutils-8.22-orig/src/uniq.c 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/src/uniq.c 2014-01-08 13:55:56.127375261 +0100 +diff -urNp coreutils-8.23-orig/src/uniq.c coreutils-8.23/src/uniq.c +--- coreutils-8.23-orig/src/uniq.c 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/src/uniq.c 2014-07-22 13:45:52.724651980 +0200 @@ -21,6 +21,17 @@ #include #include @@ -3745,7 +3745,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -249,7 +276,7 @@ size_opt (char const *opt, char const *m +@@ -251,7 +278,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 @@ -3754,7 +3754,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -269,6 +296,83 @@ find_field (struct linebuffer const *lin +@@ -271,6 +298,83 @@ find_field (struct linebuffer const *lin return line->buffer + i; } @@ -3838,7 +3838,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c /* 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. -@@ -277,6 +381,8 @@ find_field (struct linebuffer const *lin +@@ -279,6 +383,8 @@ find_field (struct linebuffer const *lin static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -3847,7 +3847,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -284,14 +390,103 @@ different (char *old, char *new, size_t +@@ -286,14 +392,103 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3956,7 +3956,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -356,19 +551,38 @@ check_file (const char *infile, const ch +@@ -358,19 +553,38 @@ check_file (const char *infile, const ch char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); bool first_group_printed = false; @@ -3995,7 +3995,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c new_group = (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)); -@@ -386,6 +600,10 @@ check_file (const char *infile, const ch +@@ -388,6 +602,10 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4006,7 +4006,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c first_group_printed = true; } } -@@ -398,17 +616,26 @@ check_file (const char *infile, const ch +@@ -400,17 +618,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -4033,7 +4033,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -417,6 +644,14 @@ check_file (const char *infile, const ch +@@ -419,6 +646,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -4048,7 +4048,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -449,6 +684,9 @@ check_file (const char *infile, const ch +@@ -451,6 +686,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4058,7 +4058,7 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c if (!match) match_count = 0; } -@@ -495,6 +733,19 @@ main (int argc, char **argv) +@@ -497,6 +735,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4078,10 +4078,10 @@ diff -urNp coreutils-8.22-orig/src/uniq.c coreutils-8.22/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.22-orig/tests/local.mk coreutils-8.22/tests/local.mk ---- coreutils-8.22-orig/tests/local.mk 2014-01-08 13:55:24.524683837 +0100 -+++ coreutils-8.22/tests/local.mk 2014-01-08 13:55:56.129375241 +0100 -@@ -324,6 +324,7 @@ all_tests = \ +diff -urNp coreutils-8.23-orig/tests/local.mk coreutils-8.23/tests/local.mk +--- coreutils-8.23-orig/tests/local.mk 2014-07-22 13:45:10.494422571 +0200 ++++ coreutils-8.23/tests/local.mk 2014-07-22 13:45:52.726651988 +0200 +@@ -331,6 +331,7 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -4089,9 +4089,9 @@ diff -urNp coreutils-8.22-orig/tests/local.mk coreutils-8.22/tests/local.mk tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ tests/misc/sort-month.sh \ -diff -urNp coreutils-8.22-orig/tests/misc/cut.pl coreutils-8.22/tests/misc/cut.pl ---- coreutils-8.22-orig/tests/misc/cut.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/cut.pl 2014-01-08 13:55:56.130375231 +0100 +diff -urNp coreutils-8.23-orig/tests/misc/cut.pl coreutils-8.23/tests/misc/cut.pl +--- coreutils-8.23-orig/tests/misc/cut.pl 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/tests/misc/cut.pl 2014-07-22 13:45:52.728651996 +0200 @@ -23,9 +23,11 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4106,7 +4106,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/cut.pl coreutils-8.22/tests/misc/cut.p my $prog = 'cut'; my $try = "Try '$prog --help' for more information.\n"; -@@ -225,6 +227,7 @@ if ($mb_locale ne 'C') +@@ -227,6 +229,7 @@ if ($mb_locale ne 'C') my @new_t = @$t; my $test_name = shift @new_t; @@ -4114,9 +4114,9 @@ diff -urNp coreutils-8.22-orig/tests/misc/cut.pl coreutils-8.22/tests/misc/cut.p push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; } push @Tests, @new; -diff -urNp coreutils-8.22-orig/tests/misc/expand.pl coreutils-8.22/tests/misc/expand.pl ---- coreutils-8.22-orig/tests/misc/expand.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/expand.pl 2014-01-08 13:55:56.135375181 +0100 +diff -urNp coreutils-8.23-orig/tests/misc/expand.pl coreutils-8.23/tests/misc/expand.pl +--- coreutils-8.23-orig/tests/misc/expand.pl 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/tests/misc/expand.pl 2014-07-22 13:45:52.729652000 +0200 @@ -23,6 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4171,9 +4171,9 @@ diff -urNp coreutils-8.22-orig/tests/misc/expand.pl coreutils-8.22/tests/misc/ex my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.22-orig/tests/misc/fold.pl coreutils-8.22/tests/misc/fold.pl ---- coreutils-8.22-orig/tests/misc/fold.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/fold.pl 2014-01-08 13:55:56.136375171 +0100 +diff -urNp coreutils-8.23-orig/tests/misc/fold.pl coreutils-8.23/tests/misc/fold.pl +--- coreutils-8.23-orig/tests/misc/fold.pl 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/tests/misc/fold.pl 2014-07-22 13:45:52.730652004 +0200 @@ -20,9 +20,18 @@ use strict; (my $program_name = $0) =~ s|.*/||; @@ -4243,9 +4243,9 @@ diff -urNp coreutils-8.22-orig/tests/misc/fold.pl coreutils-8.22/tests/misc/fold -my $prog = 'fold'; my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; -diff -urNp coreutils-8.22-orig/tests/misc/join.pl coreutils-8.22/tests/misc/join.pl ---- coreutils-8.22-orig/tests/misc/join.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/join.pl 2014-01-08 13:55:56.137375161 +0100 +diff -urNp coreutils-8.23-orig/tests/misc/join.pl coreutils-8.23/tests/misc/join.pl +--- coreutils-8.23-orig/tests/misc/join.pl 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/tests/misc/join.pl 2014-07-22 13:45:52.731652008 +0200 @@ -25,6 +25,15 @@ my $limits = getlimits (); my $prog = 'join'; @@ -4312,9 +4312,9 @@ diff -urNp coreutils-8.22-orig/tests/misc/join.pl coreutils-8.22/tests/misc/join my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.22-orig/tests/misc/sort-mb-tests.sh coreutils-8.22/tests/misc/sort-mb-tests.sh ---- coreutils-8.22-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.22/tests/misc/sort-mb-tests.sh 2014-01-08 13:55:56.138375151 +0100 +diff -urNp coreutils-8.23-orig/tests/misc/sort-mb-tests.sh coreutils-8.23/tests/misc/sort-mb-tests.sh +--- coreutils-8.23-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.23/tests/misc/sort-mb-tests.sh 2014-07-22 13:45:52.733652016 +0200 @@ -0,0 +1,45 @@ +#!/bin/sh +# Verify sort's multi-byte support. @@ -4361,9 +4361,9 @@ diff -urNp coreutils-8.22-orig/tests/misc/sort-mb-tests.sh coreutils-8.22/tests/ +compare exp out || { fail=1; cat out; } + +Exit $fail -diff -urNp coreutils-8.22-orig/tests/misc/sort-merge.pl coreutils-8.22/tests/misc/sort-merge.pl ---- coreutils-8.22-orig/tests/misc/sort-merge.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/sort-merge.pl 2014-01-08 13:55:56.139375141 +0100 +diff -urNp coreutils-8.23-orig/tests/misc/sort-merge.pl coreutils-8.23/tests/misc/sort-merge.pl +--- coreutils-8.23-orig/tests/misc/sort-merge.pl 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/tests/misc/sort-merge.pl 2014-07-22 13:45:52.733652016 +0200 @@ -26,6 +26,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4420,9 +4420,9 @@ diff -urNp coreutils-8.22-orig/tests/misc/sort-merge.pl coreutils-8.22/tests/mis my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.22-orig/tests/misc/sort.pl coreutils-8.22/tests/misc/sort.pl ---- coreutils-8.22-orig/tests/misc/sort.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/sort.pl 2014-01-08 13:55:56.140375131 +0100 +diff -urNp coreutils-8.23-orig/tests/misc/sort.pl coreutils-8.23/tests/misc/sort.pl +--- coreutils-8.23-orig/tests/misc/sort.pl 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/tests/misc/sort.pl 2014-07-22 13:45:52.734652020 +0200 @@ -24,10 +24,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4486,9 +4486,9 @@ diff -urNp coreutils-8.22-orig/tests/misc/sort.pl coreutils-8.22/tests/misc/sort my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.22-orig/tests/misc/unexpand.pl coreutils-8.22/tests/misc/unexpand.pl ---- coreutils-8.22-orig/tests/misc/unexpand.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/unexpand.pl 2014-01-08 13:55:56.140375131 +0100 +diff -urNp coreutils-8.23-orig/tests/misc/unexpand.pl coreutils-8.23/tests/misc/unexpand.pl +--- coreutils-8.23-orig/tests/misc/unexpand.pl 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/tests/misc/unexpand.pl 2014-07-22 13:45:52.735652024 +0200 @@ -27,6 +27,14 @@ my $limits = getlimits (); my $prog = 'unexpand'; @@ -4542,9 +4542,9 @@ diff -urNp coreutils-8.22-orig/tests/misc/unexpand.pl coreutils-8.22/tests/misc/ my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.22-orig/tests/misc/uniq.pl coreutils-8.22/tests/misc/uniq.pl ---- coreutils-8.22-orig/tests/misc/uniq.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/uniq.pl 2014-01-08 13:55:56.141375121 +0100 +diff -urNp coreutils-8.23-orig/tests/misc/uniq.pl coreutils-8.23/tests/misc/uniq.pl +--- coreutils-8.23-orig/tests/misc/uniq.pl 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/tests/misc/uniq.pl 2014-07-22 13:45:52.736652028 +0200 @@ -23,9 +23,17 @@ my $limits = getlimits (); my $prog = 'uniq'; my $try = "Try '$prog --help' for more information.\n"; @@ -4617,9 +4617,9 @@ diff -urNp coreutils-8.22-orig/tests/misc/uniq.pl coreutils-8.22/tests/misc/uniq @Tests = add_z_variants \@Tests; @Tests = triple_test \@Tests; -diff -urNp coreutils-8.22-orig/tests/pr/pr-tests.pl coreutils-8.22/tests/pr/pr-tests.pl ---- coreutils-8.22-orig/tests/pr/pr-tests.pl 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/pr/pr-tests.pl 2014-01-08 13:55:56.144375092 +0100 +diff -urNp coreutils-8.23-orig/tests/pr/pr-tests.pl coreutils-8.23/tests/pr/pr-tests.pl +--- coreutils-8.23-orig/tests/pr/pr-tests.pl 2014-07-11 13:00:07.000000000 +0200 ++++ coreutils-8.23/tests/pr/pr-tests.pl 2014-07-22 13:45:52.737652032 +0200 @@ -23,6 +23,15 @@ use strict; my $prog = 'pr'; diff --git a/coreutils-ppc-gnulib-tests.patch b/coreutils-ppc-gnulib-tests.patch deleted file mode 100644 index f8634ed..0000000 --- a/coreutils-ppc-gnulib-tests.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff -up coreutils-8.22/gnulib-tests/test-isnanl.h.ppc coreutils-8.22/gnulib-tests/test-isnanl.h ---- coreutils-8.22/gnulib-tests/test-isnanl.h.ppc 2014-06-23 14:01:05.925541920 +0200 -+++ coreutils-8.22/gnulib-tests/test-isnanl.h 2014-06-23 14:01:39.437617584 +0200 -@@ -51,6 +51,15 @@ main () - /* A bit pattern that is different from a Quiet NaN. With a bit of luck, - it's a Signalling NaN. */ - { -+#if defined __powerpc__ && LDBL_MANT_DIG == 106 -+ /* This is PowerPC "double double", a pair of two doubles. Inf and Nan are -+ represented as the corresponding 64-bit IEEE values in the first double; -+ the second is ignored. Manipulate only the first double. */ -+ #undef NWORDS -+ #define NWORDS \ -+ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) -+#endif -+ - memory_long_double m; - m.value = NaNl (); - # if LDBL_EXPBIT0_BIT > 0 -diff -up coreutils-8.22/gnulib-tests/test-signbit.c.ppc coreutils-8.22/gnulib-tests/test-signbit.c ---- coreutils-8.22/gnulib-tests/test-signbit.c.ppc 2013-12-04 15:53:33.000000000 +0100 -+++ coreutils-8.22/gnulib-tests/test-signbit.c 2014-06-23 13:59:20.378307385 +0200 -@@ -151,6 +151,16 @@ test_signbitl () - #define NWORDS \ - ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) - typedef union { long double value; unsigned int word[NWORDS]; } memory_long_double; -+ -+#if defined __powerpc__ && LDBL_MANT_DIG == 106 -+ /* This is PowerPC "double double", a pair of two doubles. Inf and Nan are -+ represented as the corresponding 64-bit IEEE values in the first double; -+ the second is ignored. Manipulate only the first double. */ -+ #undef NWORDS -+ #define NWORDS \ -+ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) -+#endif -+ - memory_long_double m; - m.value = zerol / zerol; - # if LDBL_EXPBIT0_BIT > 0 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 928ef95..bfcc9d3 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,17 +1,3 @@ -diff -urNp coreutils-8.21-orig/init.cfg coreutils-8.21/init.cfg ---- coreutils-8.21-orig/init.cfg 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/init.cfg 2013-02-15 14:31:58.957469955 +0100 -@@ -308,8 +308,8 @@ require_selinux_() - # Independent of whether SELinux is enabled system-wide, - # the current file system may lack SELinux support. - # Also the current build may have SELinux support disabled. -- case $(ls -Zd .) in -- '? .'|'unlabeled .') -+ case $(ls -Zd . | cut -f4 -d" ") in -+ '?'|'unlabeled') - test -z "$CONFIG_HEADER" \ - && framework_failure_ 'CONFIG_HEADER not defined' - grep '^#define HAVE_SELINUX_SELINUX_H 1' "$CONFIG_HEADER" > /dev/null \ diff -urNp coreutils-8.21-orig/man/chcon.x coreutils-8.21/man/chcon.x --- coreutils-8.21-orig/man/chcon.x 2011-08-23 15:44:01.000000000 +0200 +++ coreutils-8.21/man/chcon.x 2013-02-15 14:31:58.937482694 +0100 @@ -31,45 +17,6 @@ diff -urNp coreutils-8.21-orig/man/runcon.x coreutils-8.21/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.21-orig/src/copy.c coreutils-8.21/src/copy.c ---- coreutils-8.21-orig/src/copy.c 2013-02-07 10:37:05.000000000 +0100 -+++ coreutils-8.21/src/copy.c 2013-02-15 14:31:58.941467872 +0100 -@@ -2410,6 +2410,17 @@ copy_internal (char const *src_name, cha - else - { - omitted_permissions = 0; -+ -+ /* For directories, the process global context could be reset for -+ descendents, so use it to set the context for existing dirs here. -+ This will also give earlier indication of failure to set ctx. */ -+ if (x->set_security_context || x->preserve_security_context) -+ if (! set_file_security_ctx (dst_name, x->preserve_security_context, -+ false, x)) -+ { -+ if (x->require_preserve_context) -+ goto un_backup; -+ } - } - - /* Decide whether to copy the contents of the directory. */ -@@ -2415,6 +2426,8 @@ copy_internal (char const *src_name, cha - { - /* Here, we are crossing a file system boundary and cp's -x option - is in effect: so don't copy the contents of this directory. */ -+ if (x->preserve_security_context) -+ restore_default_fscreatecon_or_die (); - } - else - { -@@ -2602,7 +2613,7 @@ copy_internal (char const *src_name, cha - - /* With -Z or --preserve=context, set the context for existing files. - Note this is done already for copy_reg() for reasons described therein. */ -- if (!new_dst && !x->copy_as_regular -+ if (!new_dst && !x->copy_as_regular && !S_ISDIR (src_mode) - && (x->set_security_context || x->preserve_security_context)) - { - if (! set_file_security_ctx (dst_name, x->preserve_security_context, diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c --- coreutils-8.21-orig/src/cp.c 2013-02-07 10:37:05.000000000 +0100 +++ coreutils-8.21/src/cp.c 2013-02-15 14:31:58.945468929 +0100 @@ -131,9 +78,9 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c fputs (_("\ - --preserve-context preserve SELinux security context\n\ + -P, --preserve-context preserve SELinux security context (-P deprecated)\n\ - -Z, --context[=CTX] set SELinux security context of destination file to\n\ - default type, or to CTX if specified\n\ - "), stdout); + -Z set SELinux security context of destination\n\ + file to default type\n\ + --context[=CTX] like -Z, or if CTX is specified then set the\n\ @@ -782,7 +783,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -163,367 +110,3 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c x.preserve_security_context = true; use_default_selinux_context = false; break; -diff -urNp coreutils-8.21-orig/src/ls.c coreutils-8.21/src/ls.c ---- coreutils-8.21-orig/src/ls.c 2013-02-03 04:24:02.000000000 +0100 -+++ coreutils-8.21/src/ls.c 2013-02-15 14:31:58.953469008 +0100 -@@ -165,7 +165,8 @@ enum filetype - symbolic_link, - sock, - whiteout, -- arg_directory -+ arg_directory, -+ command_line - }; - - /* Display letters and indicators for each filetype. -@@ -281,6 +282,7 @@ static void queue_directory (char const - bool command_line_arg); - static void sort_files (void); - static void parse_ls_color (void); -+static void print_scontext_format (const struct fileinfo *f); - - /* Initial size of hash table. - Most hierarchies are likely to be shallower than this. */ -@@ -350,7 +352,7 @@ static struct pending *pending_dirs; - - static struct timespec current_time; - --static bool print_scontext; -+static int print_scontext = 0; - static char UNKNOWN_SECURITY_CONTEXT[] = "?"; - - /* Whether any of the files has an ACL. This affects the width of the -@@ -390,7 +392,9 @@ enum format - one_per_line, /* -1 */ - many_per_line, /* -C */ - horizontal, /* -x */ -- with_commas /* -m */ -+ with_commas, /* -m */ -+ security_format, /* -Z */ -+ invalid_format - }; - - static enum format format; -@@ -793,6 +797,9 @@ enum - SHOW_CONTROL_CHARS_OPTION, - SI_OPTION, - SORT_OPTION, -+ CONTEXT_OPTION, -+ LCONTEXT_OPTION, -+ SCONTEXT_OPTION, - TIME_OPTION, - TIME_STYLE_OPTION - }; -@@ -839,7 +846,9 @@ static struct option const long_options[ - {"time-style", required_argument, NULL, TIME_STYLE_OPTION}, - {"color", optional_argument, NULL, COLOR_OPTION}, - {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION}, -- {"context", no_argument, 0, 'Z'}, -+ {"context", no_argument, 0, CONTEXT_OPTION}, -+ {"lcontext", no_argument, 0, LCONTEXT_OPTION}, -+ {"scontext", no_argument, 0, SCONTEXT_OPTION}, - {"author", no_argument, NULL, AUTHOR_OPTION}, - {GETOPT_HELP_OPTION_DECL}, - {GETOPT_VERSION_OPTION_DECL}, -@@ -849,12 +858,12 @@ static struct option const long_options[ - static char const *const format_args[] = - { - "verbose", "long", "commas", "horizontal", "across", -- "vertical", "single-column", NULL -+ "vertical", "single-column", "context", NULL - }; - static enum format const format_types[] = - { - long_format, long_format, with_commas, horizontal, horizontal, -- many_per_line, one_per_line -+ many_per_line, one_per_line, security_format - }; - ARGMATCH_VERIFY (format_args, format_types); - -@@ -1296,7 +1305,8 @@ main (int argc, char **argv) - /* Avoid following symbolic links when possible. */ - if (is_colored (C_ORPHAN) - || (is_colored (C_EXEC) && color_symlink_as_referent) -- || (is_colored (C_MISSING) && format == long_format)) -+ || (is_colored (C_MISSING) && (format == long_format -+ || format == security_format))) - check_symlink_color = true; - - /* If the standard output is a controlling terminal, watch out -@@ -1343,7 +1353,7 @@ main (int argc, char **argv) - if (dereference == DEREF_UNDEFINED) - dereference = ((immediate_dirs - || indicator_style == classify -- || format == long_format) -+ || format == long_format || format == security_format) - ? DEREF_NEVER - : DEREF_COMMAND_LINE_SYMLINK_TO_DIR); - -@@ -1363,7 +1373,7 @@ main (int argc, char **argv) - - format_needs_stat = sort_type == sort_time || sort_type == sort_size - || format == long_format -- || print_scontext -+ || format == security_format || print_scontext - || print_block_size; - format_needs_type = (! format_needs_stat - && (recursive -@@ -1394,7 +1404,7 @@ main (int argc, char **argv) - } - else - do -- gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, ""); -+ gobble_file (argv[i++], command_line, NOT_AN_INODE_NUMBER, true, ""); - while (i < argc); - - if (cwd_n_used) -@@ -1565,7 +1575,7 @@ decode_switches (int argc, char **argv) - ignore_mode = IGNORE_DEFAULT; - ignore_patterns = NULL; - hide_patterns = NULL; -- print_scontext = false; -+ print_scontext = 0; - - /* FIXME: put this in a function. */ - { -@@ -1941,13 +1951,27 @@ decode_switches (int argc, char **argv) - break; - - case 'Z': -- print_scontext = true; -+ print_scontext = 1; -+ format = security_format; - break; - - case_GETOPT_HELP_CHAR; - - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); - -+ case CONTEXT_OPTION: /* default security context format */ -+ print_scontext = 1; -+ format = security_format; -+ break; -+ case LCONTEXT_OPTION: /* long format plus security context */ -+ print_scontext = 1; -+ format = long_format; -+ break; -+ case SCONTEXT_OPTION: /* short form of new security format */ -+ print_scontext = 0; -+ format = security_format; -+ break; -+ - default: - usage (LS_FAILURE); - } -@@ -2883,6 +2907,7 @@ gobble_file (char const *name, enum file - memset (f, '\0', sizeof *f); - f->stat.st_ino = inode; - f->filetype = type; -+ f->scontext = NULL; - - if (command_line_arg - || format_needs_stat -@@ -2995,7 +3020,7 @@ gobble_file (char const *name, enum file - && print_with_color && is_colored (C_CAP)) - f->has_capability = has_capability_cache (absolute_name, f); - -- if (format == long_format || print_scontext) -+ if (format == long_format || format == security_format || print_scontext) - { - bool have_scontext = false; - bool have_acl = false; -@@ -3016,7 +3041,7 @@ gobble_file (char const *name, enum file - err = 0; - } - -- if (err == 0 && format == long_format) -+ if (err == 0 && (format == long_format || format == security_format)) - { - int n = file_has_acl_cache (absolute_name, f); - err = (n < 0); -@@ -3035,7 +3060,8 @@ gobble_file (char const *name, enum file - } - - if (S_ISLNK (f->stat.st_mode) -- && (format == long_format || check_symlink_color)) -+ && (format == long_format || format == security_format -+ || check_symlink_color)) - { - struct stat linkstats; - -@@ -3054,6 +3080,7 @@ gobble_file (char const *name, enum file - command line are automatically traced if not being - listed as files. */ - if (!command_line_arg || format == long_format -+ || format == security_format - || !S_ISDIR (linkstats.st_mode)) - { - /* Get the linked-to file's mode for the filetype indicator -@@ -3087,7 +3114,7 @@ gobble_file (char const *name, enum file - block_size_width = len; - } - -- if (format == long_format) -+ if (format == long_format || format == security_format) - { - if (print_owner) - { -@@ -3591,6 +3618,13 @@ print_current_files (void) - print_long_format (sorted_file[i]); - DIRED_PUTCHAR ('\n'); - } -+ break; -+ case security_format: -+ for (i = 0; i < cwd_n_used; i++) -+ { -+ print_scontext_format (sorted_file[i]); -+ DIRED_PUTCHAR ('\n'); -+ } - break; - } - } -@@ -3753,6 +3787,67 @@ format_inode (char *buf, size_t buflen, - : (char *) "?"); - } - -+/* Print info about f in scontext format */ -+static void -+print_scontext_format (const struct fileinfo *f) -+{ -+ char modebuf[12]; -+ -+ /* 7 fields that may require LONGEST_HUMAN_READABLE bytes, -+ 1 10-byte mode string, -+ 9 spaces, one following each of these fields, and -+ 1 trailing NUL byte. */ -+ -+ char init_bigbuf[7 * LONGEST_HUMAN_READABLE + 10 + 9 + 1]; -+ char *buf = init_bigbuf; -+ char *p; -+ -+ p = buf; -+ -+ if ( print_scontext ) { /* zero means terse listing */ -+ filemodestring (&f->stat, modebuf); -+ if (! any_has_acl) -+ modebuf[10] = '\0'; -+ else if (f->acl_type == ACL_T_SELINUX_ONLY) -+ modebuf[10] = '.'; -+ else if (f->acl_type == ACL_T_YES) -+ modebuf[10] = '+'; -+ modebuf[11] = '\0'; -+ -+ /* print mode */ -+ -+ (void) sprintf (p, "%s ", modebuf); -+ p += strlen (p); -+ -+ /* print standard user and group */ -+ -+ DIRED_FPUTS (buf, stdout, p - buf); -+ format_user (f->stat.st_uid, owner_width, f->stat_ok); -+ format_group (f->stat.st_gid, group_width, f->stat_ok); -+ p = buf; -+ } -+ -+ (void) sprintf (p, "%-32s ", f->scontext ?: ""); -+ p += strlen (p); -+ -+ DIRED_INDENT (); -+ DIRED_FPUTS (buf, stdout, p - buf); -+ size_t w = print_name_with_quoting (f, false, &dired_obstack, p - buf); -+ -+ if (f->filetype == symbolic_link) { -+ if (f->linkname) { -+ DIRED_FPUTS_LITERAL (" -> ", stdout); -+ print_name_with_quoting (f, true, NULL, (p - buf) + w + 4); -+ if (indicator_style != none) -+ print_type_indicator (f->stat_ok, f->linkmode, f->filetype); -+ } -+ } -+ else { -+ if (indicator_style != none) -+ print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype); -+ } -+} -+ - /* Print information about F in long format. */ - static void - print_long_format (const struct fileinfo *f) -@@ -3844,9 +3939,15 @@ print_long_format (const struct fileinfo - The latter is wrong when nlink_width is zero. */ - p += strlen (p); - -+ if (print_scontext) -+ { -+ sprintf (p, "%-32s ", f->scontext ? f->scontext : ""); -+ p += strlen (p); -+ } -+ - DIRED_INDENT (); - -- if (print_owner || print_group || print_author || print_scontext) -+ if (print_owner || print_group || print_author) - { - DIRED_FPUTS (buf, stdout, p - buf); - -@@ -3859,9 +3960,6 @@ print_long_format (const struct fileinfo - if (print_author) - format_user (f->stat.st_author, author_width, f->stat_ok); - -- if (print_scontext) -- format_user_or_group (f->scontext, 0, scontext_width); -- - p = buf; - } - -@@ -4207,9 +4305,6 @@ print_file_name_and_frills (const struct - : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts, - ST_NBLOCKSIZE, output_block_size)); - -- if (print_scontext) -- printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext); -- - size_t width = print_name_with_quoting (f, false, NULL, start_col); - - if (indicator_style != none) -@@ -4417,9 +4512,6 @@ length_of_file_name_and_frills (const st - output_block_size)) - : block_size_width); - -- if (print_scontext) -- len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width); -- - quote_name (NULL, f->name, filename_quoting_options, &name_width); - len += name_width; - -@@ -4856,9 +4948,16 @@ Sort entries alphabetically if none of - - -w, --width=COLS assume screen width instead of current value\n\ - -x list entries by lines instead of by columns\n\ - -X sort alphabetically by entry extension\n\ -- -Z, --context print any SELinux security context of each file\n\ - -1 list one file per line\n\ - "), stdout); -+ fputs(_("\nSELinux options:\n\n\ -+ --lcontext Display security context. Enable -l. Lines\n\ -+ will probably be too wide for most displays.\n\ -+ -Z, --context Display security context so it fits on most\n\ -+ displays. Displays only mode, user, group,\n\ -+ security context and file name.\n\ -+ --scontext Display only security context and file name.\n\ -+"), stdout); - fputs (HELP_OPTION_DESCRIPTION, stdout); - fputs (VERSION_OPTION_DESCRIPTION, stdout); - emit_size_note (); -diff -urNp coreutils-8.21-orig/tests/misc/selinux.sh coreutils-8.21/tests/misc/selinux.sh ---- coreutils-8.21-orig/tests/misc/selinux.sh 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/tests/misc/selinux.sh 2013-02-15 14:31:58.957469955 +0100 -@@ -37,7 +37,7 @@ chcon $ctx f d p || - - # inspect that context with both ls -Z and stat. - for i in d f p; do -- c=$(ls -dogZ $i|cut -d' ' -f3); test x$c = x$ctx || fail=1 -+ c=$(ls -dogZ $i|cut -d' ' -f4); test x$c = x$ctx || fail=1 - c=$(stat --printf %C $i); test x$c = x$ctx || fail=1 - done - diff --git a/coreutils.spec b/coreutils.spec index 0d202ff..f682131 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,11 +1,12 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.22 -Release: 16%{?dist} +Version: 8.23 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +Source2: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color @@ -13,11 +14,6 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream -Patch1: coreutils-8.22-cp-selinux.patch -Patch2: coreutils-8.22-datetzcrash.patch -Patch3: coreutils-8.22-dd-sparsetest-xfsspeculativeprealloc.patch -#backport of patch from gnulib fixing tests on powerPC -Patch4: coreutils-ppc-gnulib-tests.patch # Our patches #general patch to workaround koji build system issues @@ -126,12 +122,6 @@ the old GNU fileutils, sh-utils, and textutils packages. %prep %setup -q -# From upstream -%patch1 -p1 -b .nullcontext -%patch2 -p1 -b .tzcrash -%patch3 -p1 -b .xfs -%patch4 -p1 -b .ppc - # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages @@ -377,6 +367,11 @@ fi %{_sbindir}/chroot %changelog +* Tue Jul 22 2014 Ondrej Vasik - 8.23-1 +- new upstream release 8.23 +- synchronize the old differences in ls SELinux options + with upstream + * Mon Jun 23 2014 Jakub Čajka - 8.22-16 - fix failed tests on ppc(backport from gnulib upstream) diff --git a/sources b/sources index a3c519b..b5d101f 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ -8fb0ae2267aa6e728958adc38f8163a2 coreutils-8.22.tar.xz +abed135279f87ad6762ce57ff6d89c41 coreutils-8.23.tar.xz +f93deb9f48c2bc7236743a10bf1c2409 coreutils-8.23.tar.xz.sig From f5e87bdc05a71e8d1c910989250487a5291978cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 24 Jul 2014 15:56:12 +0200 Subject: [PATCH 259/523] skip df/skip-duplicates.sh test for now (passing locally, failing in koji) --- coreutils-6.10-configuration.patch | 51 ++++++++++++++++++++++++++++++ coreutils.spec | 1 + 2 files changed, 52 insertions(+) diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index b5f882f..b749ec8 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -167,3 +167,54 @@ diff -urNp coreutils-8.22-orig/tests/misc/nohup.sh coreutils-8.22/tests/misc/noh nohup sh -c 'echo stdout; echo stderr 1>&2' 2>err || fail=1 +diff -urNp coreutils-8.23-orig/tests/df/skip-duplicates.sh coreutils-8.23/tests/df/skip-duplicates.sh +--- coreutils-8.23-orig/tests/df/skip-duplicates.sh 2014-07-14 00:09:52.000000000 +0200 ++++ coreutils-8.23/tests/df/skip-duplicates.sh 2014-07-24 15:53:33.473031545 +0200 +@@ -25,6 +25,10 @@ require_gcc_shared_ + # potentially very many remote mounts. + df --local || skip_ "df fails" + ++#mark it expensive, to temporarily skip the test in koji ++expensive_ ++ ++ + export CU_NONROOT_FS=$(df --local --output=target 2>&1 | grep /. | head -n1) + test -z "$CU_NONROOT_FS" && unique_entries=1 || unique_entries=2 + +diff -urNp coreutils-8.23-orig/Makefile.am coreutils-8.23/Makefile.am +--- coreutils-8.23-orig/Makefile.am 2014-07-14 00:09:52.000000000 +0200 ++++ coreutils-8.23/Makefile.am 2014-07-23 13:27:55.400895315 +0200 +@@ -50,7 +50,6 @@ EXTRA_DIST = \ + bootstrap \ + bootstrap.conf \ + build-aux/gen-lists-of-programs.sh \ +- build-aux/gen-single-binary.sh \ + cfg.mk \ + dist-check.mk \ + maint.mk \ +@@ -58,7 +57,7 @@ EXTRA_DIST = \ + thanks-gen + + gen_progs_lists = $(top_srcdir)/build-aux/gen-lists-of-programs.sh +-gen_single_binary = $(top_srcdir)/build-aux/gen-single-binary.sh ++#gen_single_binary = $(top_srcdir)/build-aux/gen-single-binary.sh + + # Keep these in sync with bootstrap.conf:bootstrap_post_import_hook(). + # Use '$(top_srcdir)/m4' and '$(srcdir)/src' for the benefit of non-GNU +@@ -72,10 +72,11 @@ $(srcdir)/src/cu-progs.mk: $(gen_progs_l + $(AM_V_GEN)rm -f $@ $@-t \ + && $(SHELL) $(gen_progs_lists) --automake >$@-t \ + && chmod a-w $@-t && mv -f $@-t $@ +-$(srcdir)/src/single-binary.mk: $(gen_single_binary) $(srcdir)/src/local.mk +- $(AM_V_GEN)rm -f $@ $@-t \ +- && $(SHELL) $(gen_single_binary) $(srcdir)/src/local.mk >$@-t \ +- && chmod a-w $@-t && mv -f $@-t $@ ++#disable single binary, probably races in koji ++#$(srcdir)/src/single-binary.mk: $(gen_single_binary) $(srcdir)/src/local.mk ++# $(AM_V_GEN)rm -f $@ $@-t \ ++# && $(SHELL) $(gen_single_binary) $(srcdir)/src/local.mk >$@-t \ ++# && chmod a-w $@-t && mv -f $@-t $@ + + ACLOCAL_AMFLAGS = -I m4 + + diff --git a/coreutils.spec b/coreutils.spec index 8cd0578..ae8d7f6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -373,6 +373,7 @@ fi - new upstream release 8.23 - synchronize the old differences in ls SELinux options with upstream +- skip df/skip-duplicates.sh test for now (passing locally, failing in koji) * Fri Jul 11 2014 Tom Callaway - 8.22-17 - fix license handling From 734e24e1b21732090fa8df3d614e014776ad6dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 24 Jul 2014 16:08:28 +0200 Subject: [PATCH 260/523] disable _smp_mflags for a while- build failure --- coreutils.spec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index ae8d7f6..269b26b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -170,7 +170,9 @@ automake --copy --add-missing # Regenerate manpages touch man/*.x -make all %{?_smp_mflags} +make all +#recent build is broken with smp_mflags, have to investigate +#%{?_smp_mflags} # XXX docs should say /var/run/[uw]tmp not /etc/[uw]tmp sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi From f7c8684e5eddcca4681c1be45c255e8fe0202cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 5 Aug 2014 12:29:51 +0200 Subject: [PATCH 261/523] enable smp_flags again (by B.Voelker), fix regression in chroot --- coreutils-6.10-configuration.patch | 45 +--- coreutils-8.23-chroot-chdir.patch | 411 +++++++++++++++++++++++++++++ coreutils.spec | 13 +- 3 files changed, 430 insertions(+), 39 deletions(-) create mode 100644 coreutils-8.23-chroot-chdir.patch diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index b749ec8..4403811 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -181,40 +181,15 @@ diff -urNp coreutils-8.23-orig/tests/df/skip-duplicates.sh coreutils-8.23/tests/ export CU_NONROOT_FS=$(df --local --output=target 2>&1 | grep /. | head -n1) test -z "$CU_NONROOT_FS" && unique_entries=1 || unique_entries=2 -diff -urNp coreutils-8.23-orig/Makefile.am coreutils-8.23/Makefile.am ---- coreutils-8.23-orig/Makefile.am 2014-07-14 00:09:52.000000000 +0200 -+++ coreutils-8.23/Makefile.am 2014-07-23 13:27:55.400895315 +0200 -@@ -50,7 +50,6 @@ EXTRA_DIST = \ - bootstrap \ - bootstrap.conf \ - build-aux/gen-lists-of-programs.sh \ -- build-aux/gen-single-binary.sh \ - cfg.mk \ - dist-check.mk \ - maint.mk \ -@@ -58,7 +57,7 @@ EXTRA_DIST = \ - thanks-gen +diff -urNp coreutils-8.23-orig/man/local.mk coreutils-8.23/man/local.mk +--- coreutils-8.23-orig/man/local.mk 2014-07-18 03:40:57.000000000 +0200 ++++ coreutils-8.23/man/local.mk 2014-08-05 12:18:20.477524009 +0200 +@@ -41,7 +41,7 @@ distclean-local: + test x$(srcdir) = x$(builddir) || rm -f $(ALL_MANS) - gen_progs_lists = $(top_srcdir)/build-aux/gen-lists-of-programs.sh --gen_single_binary = $(top_srcdir)/build-aux/gen-single-binary.sh -+#gen_single_binary = $(top_srcdir)/build-aux/gen-single-binary.sh + # Dependencies common to all man pages. Updated below. +-mandeps = ++mandeps = $(PROGRAMS) - # Keep these in sync with bootstrap.conf:bootstrap_post_import_hook(). - # Use '$(top_srcdir)/m4' and '$(srcdir)/src' for the benefit of non-GNU -@@ -72,10 +72,11 @@ $(srcdir)/src/cu-progs.mk: $(gen_progs_l - $(AM_V_GEN)rm -f $@ $@-t \ - && $(SHELL) $(gen_progs_lists) --automake >$@-t \ - && chmod a-w $@-t && mv -f $@-t $@ --$(srcdir)/src/single-binary.mk: $(gen_single_binary) $(srcdir)/src/local.mk -- $(AM_V_GEN)rm -f $@ $@-t \ -- && $(SHELL) $(gen_single_binary) $(srcdir)/src/local.mk >$@-t \ -- && chmod a-w $@-t && mv -f $@-t $@ -+#disable single binary, probably races in koji -+#$(srcdir)/src/single-binary.mk: $(gen_single_binary) $(srcdir)/src/local.mk -+# $(AM_V_GEN)rm -f $@ $@-t \ -+# && $(SHELL) $(gen_single_binary) $(srcdir)/src/local.mk >$@-t \ -+# && chmod a-w $@-t && mv -f $@-t $@ - - ACLOCAL_AMFLAGS = -I m4 - - + # Depend on this to get version number changes. + mandeps += .version diff --git a/coreutils-8.23-chroot-chdir.patch b/coreutils-8.23-chroot-chdir.patch new file mode 100644 index 0000000..ce977bd --- /dev/null +++ b/coreutils-8.23-chroot-chdir.patch @@ -0,0 +1,411 @@ +From 0cf7b1d928acaaddd4eaa28c6a22f7bd6457b379 Mon Sep 17 00:00:00 2001 +From: Bernhard Voelker +Date: Fri, 01 Aug 2014 00:07:33 +0000 +Subject: chroot: perform chdir("/") again unless new --skip-chdir is specified + +Since commit v8.22-94-g99960ee, chroot(1) skips the chroot(2) syscall +for "/" arguments (and synonyms). The problem is that it also skips +the following chdir("/") call in that case. The latter breaks existing +scripts which expect "/" to be the working directory inside the chroot. +While the first part of the change - i.e., skipping chroot("/") - is +okay for consistency with systems where it might succeed for a non-root +user, the second part might be malicious, e.g. + + cd /home/user && chroot '/' bin/foo + +In the "best" case, chroot(1) could not execute 'bin/foo' with ENOENT, +but in the worst case, chroot(1) would execute '/home/user/bin/foo' in +the case that exists - instead of '/bin/foo'. + +Revert that second part of the patch, i.e., perform the chdir("/) +in the common case again - unless the new --skip-chdir option is +specified. Restrict this new option to the case of "/" arguments. + +* src/chroot.c (SKIP_CHDIR): Add enum. +(long_opts): Add entry for the new --skip-chdir option. +(usage): Add --skip-chdir option, and while at it, move the other +to options into alphabetical order. +(main): Accept the above new option, allowing it only in the case +when NEWROOT is the old "/". +Move down the chdir() call after the if-clause to ensure it is +run in any case - unless --skip-chdir is specified. +Add a 'newroot' variable for the new root directory as it is used +in a couple of places now. +* tests/misc/chroot-fail.sh: Invert the last tests which check the +working directory of the execvp()ed program when a "/"-like +argument was passed: now expect it to be "/" - unless --skip-chdir +is given. +* doc/coreutils.texi (chroot invocation): Document the new option. +Document that chroot(1) usually calls chdir("/") unless the new +--skip-chdir option is specified. Sort options. +* init.cfg (nonroot_has_perm_): Add chroot's new --skip-chdir option. +* tests/cp/preserve-gid.sh (t1): Likewise. +* tests/cp/special-bits.sh: Likewise. +* tests/id/setgid.sh: Likewise. +* tests/misc/truncate-owned-by-other.sh: Likewise. +* tests/mv/sticky-to-xpart.sh: Likewise. +* tests/rm/fail-2eperm.sh: Likewise. +* tests/rm/no-give-up.sh: Likewise. +* tests/touch/now-owned-by-other.sh: Likewise. + +Reported by Andreas Schwab in http://bugs.gnu.org/18062 +--- +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 96f0781..7c86719 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -16113,7 +16113,10 @@ On many systems, only the super-user can do this.@footnote{However, + some systems (e.g., FreeBSD) can be configured to allow certain regular + users to use the @code{chroot} system call, and hence to run this program. + Also, on Cygwin, anyone can run the @command{chroot} command, because the +-underlying function is non-privileged due to lack of support in MS-Windows.} ++underlying function is non-privileged due to lack of support in MS-Windows. ++Furthermore, the @command{chroot} command avoids the @code{chroot} system call ++when @var{newroot} is identical to the old @file{/} directory for consistency ++with systems where this is allowed for non-privileged users.}. + Synopses: + + @example +@@ -16123,10 +16126,11 @@ chroot @var{option} + + Ordinarily, file names are looked up starting at the root of the + directory structure, i.e., @file{/}. @command{chroot} changes the root to +-the directory @var{newroot} (which must exist) and then runs +-@var{command} with optional @var{args}. If @var{command} is not +-specified, the default is the value of the @env{SHELL} environment +-variable or @command{/bin/sh} if not set, invoked with the @option{-i} option. ++the directory @var{newroot} (which must exist), then changes the working ++directory to @file{/}, and finally runs @var{command} with optional @var{args}. ++If @var{command} is not specified, the default is the value of the @env{SHELL} ++environment variable or @command{/bin/sh} if not set, invoked with the ++@option{-i} option. + @var{command} must not be a special built-in utility + (@pxref{Special built-in utilities}). + +@@ -16135,6 +16139,14 @@ Options must precede operands. + + @table @samp + ++@item --groups=@var{groups} ++@opindex --groups ++Use this option to override the supplementary @var{groups} to be ++used by the new process. ++The items in the list (names or numeric IDs) must be separated by commas. ++Use @samp{--groups=''} to disable the supplementary group look-up ++implicit in the @option{--userspec} option. ++ + @item --userspec=@var{user}[:@var{group}] + @opindex --userspec + By default, @var{command} is run with the same credentials +@@ -16145,13 +16157,13 @@ If a @var{user} is specified then the supplementary groups + are set according to the system defined list for that user, + unless overridden with the @option{--groups} option. + +-@item --groups=@var{groups} +-@opindex --groups +-Use this option to override the supplementary @var{groups} to be +-used by the new process. +-The items in the list (names or numeric IDs) must be separated by commas. +-Use @samp{--groups=''} to disable the supplementary group look-up +-implicit in the @option{--userspec} option. ++@item --skip-chdir ++@opindex --skip-chdir ++Use this option to not change the working directory to @file{/} after changing ++the root directory to @var{newroot}, i.e., inside the chroot. ++This option is only permitted when @var{newroot} is the old @file{/} directory, ++and therefore is mostly useful together with the @option{--groups} and ++@option{--userspec} options to retain the previous working directory. + + @end table + +diff --git a/init.cfg b/init.cfg +index 725ee12..032646b 100644 +--- a/init.cfg ++++ b/init.cfg +@@ -400,7 +400,8 @@ nonroot_has_perm_() + require_built_ chroot + + local rm_version=$( +- chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm --version | ++ chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ ++ rm --version | + sed -n '1s/.* //p' + ) + case ":$rm_version:" in +diff --git a/src/chroot.c b/src/chroot.c +index 6c2d63f..418ea67 100644 +--- a/src/chroot.c ++++ b/src/chroot.c +@@ -49,13 +49,15 @@ static inline bool gid_unset (gid_t gid) { return gid == (gid_t) -1; } + enum + { + GROUPS = UCHAR_MAX + 1, +- USERSPEC ++ USERSPEC, ++ SKIP_CHDIR + }; + + static struct option const long_opts[] = + { + {"groups", required_argument, NULL, GROUPS}, + {"userspec", required_argument, NULL, USERSPEC}, ++ {"skip-chdir", no_argument, NULL, SKIP_CHDIR}, + {GETOPT_HELP_OPTION_DECL}, + {GETOPT_VERSION_OPTION_DECL}, + {NULL, 0, NULL, 0} +@@ -194,9 +196,14 @@ Run COMMAND with root directory set to NEWROOT.\n\ + "), stdout); + + fputs (_("\ +- --userspec=USER:GROUP specify user and group (ID or name) to use\n\ + --groups=G_LIST specify supplementary groups as g1,g2,..,gN\n\ + "), stdout); ++ fputs (_("\ ++ --userspec=USER:GROUP specify user and group (ID or name) to use\n\ ++"), stdout); ++ printf (_("\ ++ --skip-chdir do not change working directory to %s\n\ ++"), quote ("/")); + + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); +@@ -218,6 +225,7 @@ main (int argc, char **argv) + char *userspec = NULL; + char const *username = NULL; + char const *groups = NULL; ++ bool skip_chdir = false; + + /* Parsed user and group IDs. */ + uid_t uid = -1; +@@ -254,6 +262,10 @@ main (int argc, char **argv) + groups = optarg; + break; + ++ case SKIP_CHDIR: ++ skip_chdir = true; ++ break; ++ + case_GETOPT_HELP_CHAR; + + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); +@@ -269,9 +281,19 @@ main (int argc, char **argv) + usage (EXIT_CANCELED); + } + ++ char const *newroot = argv[optind]; ++ bool is_oldroot = is_root (newroot); ++ ++ if (! is_oldroot && skip_chdir) ++ { ++ error (0, 0, _("option --skip-chdir only permitted if NEWROOT is old %s"), ++ quote ("/")); ++ usage (EXIT_CANCELED); ++ } ++ + /* Only do chroot specific actions if actually changing root. + The main difference here is that we don't change working dir. */ +- if (! is_root (argv[optind])) ++ if (! is_oldroot) + { + /* We have to look up users and groups twice. + - First, outside the chroot to load potentially necessary passwd/group +@@ -307,14 +329,14 @@ main (int argc, char **argv) + } + #endif + +- if (chroot (argv[optind]) != 0) ++ if (chroot (newroot) != 0) + error (EXIT_CANCELED, errno, _("cannot change root directory to %s"), +- argv[optind]); +- +- if (chdir ("/")) +- error (EXIT_CANCELED, errno, _("cannot chdir to root directory")); ++ newroot); + } + ++ if (! skip_chdir && chdir ("/")) ++ error (EXIT_CANCELED, errno, _("cannot chdir to root directory")); ++ + if (argc == optind + 1) + { + /* No command. Run an interactive shell. */ +diff --git a/tests/cp/preserve-gid.sh b/tests/cp/preserve-gid.sh +index f141ac1..5499c2e 100755 +--- a/tests/cp/preserve-gid.sh ++++ b/tests/cp/preserve-gid.sh +@@ -117,7 +117,8 @@ t1() { + u=$1; shift + g=$1; shift + t0 "$f" "$u" "$g" \ +- chroot --user=+$nameless_uid:+$nameless_gid1 \ ++ chroot --skip-chdir \ ++ --user=+$nameless_uid:+$nameless_gid1 \ + --groups="+$nameless_gid1,+$nameless_gid2" \ + / env PATH="$tmp_path" "$@" + } +diff --git a/tests/cp/special-bits.sh b/tests/cp/special-bits.sh +index a55eea2..1402819 100755 +--- a/tests/cp/special-bits.sh ++++ b/tests/cp/special-bits.sh +@@ -42,7 +42,8 @@ set _ $(ls -l b); shift; p1=$1 + set _ $(ls -l b2); shift; p2=$1 + test $p1 = $p2 || fail=1 + +-chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" cp -p c c2 || fail=1 ++chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" cp -p c c2 \ ++ || fail=1 + set _ $(ls -l c); shift; p1=$1 + set _ $(ls -l c2); shift; p2=$1 + test $p1 = $p2 && fail=1 +diff --git a/tests/id/setgid.sh b/tests/id/setgid.sh +index 6d9d74f..019418a 100755 +--- a/tests/id/setgid.sh ++++ b/tests/id/setgid.sh +@@ -27,14 +27,14 @@ echo $gp1 > exp || framework_failure_ + + # With coreutils-8.16 and earlier, id -G would print both: + # $gp1 $NON_ROOT_GID +-chroot --user=$NON_ROOT_USERNAME:+$gp1 --groups='' / env PATH="$PATH" \ +- id -G > out || fail=1 ++chroot --skip-chdir --user=$NON_ROOT_USERNAME:+$gp1 --groups='' / \ ++ env PATH="$PATH" id -G > out || fail=1 + compare exp out || fail=1 + + # With coreutils-8.22 and earlier, id would erroneously print + # groups=$NON_ROOT_GID +-chroot --user=$NON_ROOT_USERNAME:+$gp1 --groups='' / env PATH="$PATH" \ +- id > out || fail=1 ++chroot --skip-chdir --user=$NON_ROOT_USERNAME:+$gp1 --groups='' / \ ++ env PATH="$PATH" id > out || fail=1 + grep -F "groups=$gp1" out || { cat out; fail=1; } + + Exit $fail +diff --git a/tests/misc/chroot-fail.sh b/tests/misc/chroot-fail.sh +index a84826f..82ae23c 100755 +--- a/tests/misc/chroot-fail.sh ++++ b/tests/misc/chroot-fail.sh +@@ -30,7 +30,7 @@ chroot --- / true # unknown option + test $? = 125 || fail=1 + + # Note chroot("/") succeeds for non-root users on some systems, but not all, +-# however we avoid the chroot() with "/" to have common behvavior. ++# however we avoid the chroot() with "/" to have common behavior. + chroot / sh -c 'exit 2' # exit status propagation + test $? = 2 || fail=1 + chroot / . # invalid command +@@ -38,10 +38,25 @@ test $? = 126 || fail=1 + chroot / no_such # no such command + test $? = 127 || fail=1 + +-# Ensure we don't chdir("/") when not changing root +-# to allow only changing user ids for a command. +-for dir in '/' '/.' '/../'; do ++# Ensure that --skip-chdir fails with a non-"/" argument. ++cat <<\EOF > exp || framework_failure_ ++chroot: option --skip-chdir only permitted if NEWROOT is old '/' ++Try 'chroot --help' for more information. ++EOF ++chroot --skip-chdir . env pwd >out 2>err && fail=1 ++compare /dev/null out || fail=1 ++compare exp err || fail=1 ++ ++# Ensure we don't chroot("/") when NEWROOT is old "/". ++ln -s / isroot || framework_failure_ ++for dir in '/' '/.' '/../' isroot; do ++ # Verify that chroot(1) succeeds and performs chdir("/") ++ # (chroot(1) of coreutils-8.23 failed to run the latter). + curdir=$(chroot "$dir" env pwd) || fail=1 ++ test "$curdir" = '/' || fail=1 ++ ++ # Test the "--skip-chdir" option. ++ curdir=$(chroot --skip-chdir "$dir" env pwd) || fail=1 + test "$curdir" = '/' && fail=1 + done + +diff --git a/tests/misc/truncate-owned-by-other.sh b/tests/misc/truncate-owned-by-other.sh +index e70badb..f65439e 100755 +--- a/tests/misc/truncate-owned-by-other.sh ++++ b/tests/misc/truncate-owned-by-other.sh +@@ -29,7 +29,7 @@ chmod g+w root-owned + # Ensure that the current directory is searchable by $NON_ROOT_USERNAME. + chmod g+x . + +-chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ ++chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ + truncate -s0 root-owned || fail=1 + + Exit $fail +diff --git a/tests/mv/sticky-to-xpart.sh b/tests/mv/sticky-to-xpart.sh +index e0c99e9..6c1f6e8 100755 +--- a/tests/mv/sticky-to-xpart.sh ++++ b/tests/mv/sticky-to-xpart.sh +@@ -42,7 +42,8 @@ chmod go+x . || framework_failure_ + + # Ensure that $NON_ROOT_USERNAME can access the required version of mv. + version=$( +- chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" mv --version | ++ chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ ++ mv --version | + sed -n '1s/.* //p' + ) + case $version in +@@ -50,7 +51,7 @@ case $version in + *) skip_ "cannot access just-built mv as user $NON_ROOT_USERNAME";; + esac + +-chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ ++chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ + mv t/root-owned "$other_partition_tmpdir" 2> out-t && fail=1 + + # On some systems, we get 'Not owner'. Convert it. +diff --git a/tests/rm/fail-2eperm.sh b/tests/rm/fail-2eperm.sh +index 6e8ce9b..c324037 100755 +--- a/tests/rm/fail-2eperm.sh ++++ b/tests/rm/fail-2eperm.sh +@@ -32,14 +32,16 @@ touch a/b || framework_failure_ + # Try to ensure that $NON_ROOT_USERNAME can access + # the required version of rm. + rm_version=$( +- chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm --version | ++ chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ ++ rm --version | + sed -n '1s/.* //p' + ) + case $rm_version in + $PACKAGE_VERSION) ;; + *) skip_ "cannot access just-built rm as user $NON_ROOT_USERNAME";; + esac +-chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm -rf a 2> out-t && fail=1 ++chroot --skip-chdir --user=$NON_ROOT_USERNAME / \ ++ env PATH="$PATH" rm -rf a 2> out-t && fail=1 + + # On some systems, we get 'Not owner'. Convert it. + # On other systems (HPUX), we get 'Permission denied'. Convert it, too. +diff --git a/tests/rm/no-give-up.sh b/tests/rm/no-give-up.sh +index 41070c9..958f9e8 100755 +--- a/tests/rm/no-give-up.sh ++++ b/tests/rm/no-give-up.sh +@@ -30,7 +30,7 @@ chmod go=x . || framework_failure_ + + + # This must fail, since '.' is not writable by $NON_ROOT_USERNAME. +-chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ ++chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ + rm -rf d 2>/dev/null && fail=1 + + # d must remain. +diff --git a/tests/touch/now-owned-by-other.sh b/tests/touch/now-owned-by-other.sh +index d01097e..018ef11 100755 +--- a/tests/touch/now-owned-by-other.sh ++++ b/tests/touch/now-owned-by-other.sh +@@ -28,7 +28,7 @@ chmod g+w root-owned + # Ensure that the current directory is searchable by $NON_ROOT_USERNAME. + chmod g+x . + +-chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ ++chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ + touch -d now root-owned || fail=1 + + Exit $fail +-- +cgit v0.9.0.2 diff --git a/coreutils.spec b/coreutils.spec index 269b26b..848d3cc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -14,6 +14,7 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream +Patch1: coreutils-8.23-chroot-chdir.patch # Our patches #general patch to workaround koji build system issues @@ -122,6 +123,8 @@ the old GNU fileutils, sh-utils, and textutils packages. %prep %setup -q +%patch1 -p1 -b .chdir + # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages @@ -170,9 +173,7 @@ automake --copy --add-missing # Regenerate manpages touch man/*.x -make all -#recent build is broken with smp_mflags, have to investigate -#%{?_smp_mflags} +make all %{?_smp_mflags} # XXX docs should say /var/run/[uw]tmp not /etc/[uw]tmp sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi @@ -371,6 +372,10 @@ fi %{_sbindir}/chroot %changelog +* Tue Aug 05 2014 Ondrej Vasik - 8.23-2 +- enable smp_flags again (by B.Voelker) +- fix regression in chroot + * Tue Jul 22 2014 Ondrej Vasik - 8.23-1 - new upstream release 8.23 - synchronize the old differences in ls SELinux options From 89879aa209fc9d2fec94d0c2b5788071be9f742a Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sat, 16 Aug 2014 01:18:19 +0000 Subject: [PATCH 262/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 848d3cc..97967f74 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,9 @@ fi %{_sbindir}/chroot %changelog +* Sat Aug 16 2014 Fedora Release Engineering - 8.23-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + * Tue Aug 05 2014 Ondrej Vasik - 8.23-2 - enable smp_flags again (by B.Voelker) - fix regression in chroot From cae27396ecf2fee0912a9cf7f828ed4ef22ae6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 1 Oct 2014 14:49:30 +0200 Subject: [PATCH 263/523] fix the sorting in multibyte locales (NUL-terminate sort keys) - patch by Andreas Schwab (#1146185) --- coreutils-i18n.patch | 38 ++++++++++++++++++++++++++++++++++---- coreutils.spec | 6 +++++- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 633825e..e7005cf 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -3132,7 +3132,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2695,6 +3135,191 @@ keycompare (struct line const *a, struct +@@ -2695,6 +3135,209 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3237,6 +3237,9 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c + 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; + @@ -3254,6 +3257,12 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c + 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); @@ -3277,13 +3286,22 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c + diff = 1; + else if (hard_LC_COLLATE && !folding) + { -+ diff = xmemcoll0 (texta, lena, textb, lenb); ++ diff = xmemcoll0 (texta, lena + 1, textb, lenb + 1); + } + else -+ diff = memcmp (texta, textb, MIN (lena + 1,lenb + 1)); ++ { ++ 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; @@ -4440,7 +4458,18 @@ diff -urNp coreutils-8.23-orig/tests/misc/sort.pl coreutils-8.23/tests/misc/sort # 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 '-'. -@@ -415,6 +420,37 @@ foreach my $t (@Tests) +@@ -317,6 +322,10 @@ my @Tests = + ["22a", '-k 2,2fd -k 1,1r', {IN=>"3 b\n4 B\n"}, {OUT=>"4 B\n3 b\n"}], + ["22b", '-k 2,2d -k 1,1r', {IN=>"3 b\n4 b\n"}, {OUT=>"4 b\n3 b\n"}], + ++# This fails in Fedora 20, per Göran Uddeborg in: http://bugs.gnu.org/18540 ++["23", '-s -k1,1 -t/', {IN=>"a b/x\na-b-c/x\n"}, {OUT=>"a b/x\na-b-c/x\n"}, ++ {ENV => "LC_ALL=$mb_locale"}], ++ + ["no-file1", 'no-file', {EXIT=>2}, {ERR=>$no_file}], + # This test failed until 1.22f. Sort didn't give an error. + # From Will Edgington. +@@ -415,6 +420,38 @@ foreach my $t (@Tests) } } @@ -4470,6 +4499,7 @@ diff -urNp coreutils-8.23-orig/tests/misc/sort.pl coreutils-8.23/tests/misc/sort + #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; diff --git a/coreutils.spec b/coreutils.spec index 97967f74..8b5ad5b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,10 @@ fi %{_sbindir}/chroot %changelog +* Wed Oct 01 2014 Ondrej Vasik - 8.23-4 +- fix the sorting in multibyte locales (NUL-terminate sort keys) + - patch by Andreas Schwab (#1146185) + * Sat Aug 16 2014 Fedora Release Engineering - 8.23-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild From 2f8deb0379df75243d9a93ae5e5f5ba8593711d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 15 Oct 2014 09:43:08 +0200 Subject: [PATCH 264/523] handle situation with ro /tmp in colorls scripts (#1149761) --- coreutils-colorls.csh | 10 +++++++++- coreutils-colorls.sh | 17 +++++++++++------ coreutils.spec | 5 ++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 5ed0f68..a146dd1 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -34,7 +34,14 @@ set INCLUDE="`cat "$COLORS" | grep '^INCLUDE' | cut -d ' ' -f2-`" if ( ! -e "$COLORS" ) exit -set _tmp="`mktemp .colorlsXXX --tmpdir=/tmp`" +set _tmp="`mktemp .colorlsXXX -q --tmpdir=/tmp`" +#if mktemp fails, exit when include was active, otherwise use $COLORS file +if ( "$_tmp" == '' ) then + if ( "$INCLUDE" == '' ) then + eval "`dircolors -c $COLORS`" + endif + goto cleanup +endif if ( "$INCLUDE" != '' ) cat "$INCLUDE" >> $_tmp grep -v '^INCLUDE' "$COLORS" >> $_tmp @@ -44,6 +51,7 @@ eval "`dircolors -c $_tmp`" rm -f $_tmp if ( "$LS_COLORS" == '' ) exit +cleanup: set color_none=`sed -n '/^COLOR.*none/Ip' < $COLORS` if ( "$color_none" != '' ) then unset color_none diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index 1308da9..f9484b3 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -32,14 +32,19 @@ if [ -z "$USER_LS_COLORS" ]; then # Existence of $COLORS already checked above. [ -n "$COLORS" ] || return - TMP="`mktemp .colorlsXXX --tmpdir=/tmp`" + if [ -e "$INCLUDE" ]; + then + TMP="`mktemp .colorlsXXX -q --tmpdir=/tmp`" + [ -z "$TMP" ] && return - [ -e "$INCLUDE" ] && cat "$INCLUDE" >> $TMP - grep -v '^INCLUDE' "$COLORS" >> $TMP + cat "$INCLUDE" >> $TMP + grep -v '^INCLUDE' "$COLORS" >> $TMP - eval "`dircolors --sh $TMP 2>/dev/null`" - - rm -f $TMP + eval "`dircolors --sh $TMP 2>/dev/null`" + rm -f $TMP + else + eval "`dircolors --sh $COLORS 2>/dev/null`" + fi [ -z "$LS_COLORS" ] && return grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return diff --git a/coreutils.spec b/coreutils.spec index 8b5ad5b..12b5f4e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -372,6 +372,9 @@ fi %{_sbindir}/chroot %changelog +* Wed Oct 15 2014 Ondrej Vasik - 8.23-5 +- handle situation with ro /tmp in colorls scripts (#1149761) + * Wed Oct 01 2014 Ondrej Vasik - 8.23-4 - fix the sorting in multibyte locales (NUL-terminate sort keys) - patch by Andreas Schwab (#1146185) From ac62214984ad6b83898e8db0ae5bdbd6cdc327cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 1 Dec 2014 11:59:25 +0100 Subject: [PATCH 265/523] have the LC_TIME subdirs with lang macro (#1169027) --- coreutils.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 12b5f4e..b11431a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -228,6 +228,8 @@ find %{buildroot}%{_datadir}/locale -type l | \ done) %find_lang %name +#Add the %lang(xyz) ownership for the LC_TIME dirs as well... +grep LC_TIME %name.lang | cut -d'/' -f1-6 | sed -e 's/) /) %%dir /g' >>%name.lang # (sb) Deal with Installed (but unpackaged) file(s) found rm -f $RPM_BUILD_ROOT%{_infodir}/dir @@ -259,7 +261,6 @@ fi %files -f %{name}.lang %defattr(-,root,root,-) -%dir %{_datadir}/locale/*/LC_TIME %config(noreplace) %{_sysconfdir}/DIR_COLORS* %config(noreplace) %{_sysconfdir}/profile.d/* %doc ABOUT-NLS ChangeLog.bz2 NEWS README THANKS TODO old/* @@ -372,6 +373,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Dec 01 2014 Ondrej Vasik - 8.23-6 +- have the LC_TIME subdirs with lang macro (#1169027) + * Wed Oct 15 2014 Ondrej Vasik - 8.23-5 - handle situation with ro /tmp in colorls scripts (#1149761) From 0006fec2f30fab267f000069f908fdbe2d2f8988 Mon Sep 17 00:00:00 2001 From: Till Maas Date: Sat, 21 Feb 2015 22:22:06 +0100 Subject: [PATCH 266/523] Rebuilt for Fedora 23 Change https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code --- coreutils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index b11431a..6ab3cec 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -373,6 +373,10 @@ fi %{_sbindir}/chroot %changelog +* Sat Feb 21 2015 Till Maas - 8.23-7 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + * Mon Dec 01 2014 Ondrej Vasik - 8.23-6 - have the LC_TIME subdirs with lang macro (#1169027) From 75d03ceef199bcd87ad051d2fd542721aa9ead13 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 22 Mar 2015 11:52:47 +0000 Subject: [PATCH 267/523] drop ChangeLog (covered in enough detail in news for averge users), drop ancient docs --- coreutils.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 6ab3cec..71c57ff 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -263,7 +263,7 @@ fi %defattr(-,root,root,-) %config(noreplace) %{_sysconfdir}/DIR_COLORS* %config(noreplace) %{_sysconfdir}/profile.d/* -%doc ABOUT-NLS ChangeLog.bz2 NEWS README THANKS TODO old/* +%doc ABOUT-NLS NEWS README THANKS TODO %{!?_licensedir:%global license %%doc} %license COPYING %{_bindir}/arch @@ -373,6 +373,9 @@ fi %{_sbindir}/chroot %changelog +* Sun Mar 22 2015 Peter Robinson 8.23-8 +- Drop large ancient docs + * Sat Feb 21 2015 Till Maas - 8.23-7 - Rebuilt for Fedora 23 Change https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code From 0ea2ae63571c7e912cba176b81ec250438388b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Mon, 20 Apr 2015 15:21:51 +0100 Subject: [PATCH 268/523] sync/adjust LS_COLORS * coreutils-DIR_COLORS: sync with upstream (remove old Xiph formats, add m4a audio format). * coreutils-DIR_COLORS.256color: Likewise. Also sync with 8 color mode above, by removing the specific MULTIHARDLINK coloring, and giving MISSING symlink targets a red background. Also lighten the DIR and EXEC color a little (as discussed in bug 1196642) * coreutils-DIR_COLORS.lightbgcolor: Sync terminal types with other 2 databases above. --- coreutils-DIR_COLORS | 9 +++-- coreutils-DIR_COLORS.256color | 13 ++++--- coreutils-DIR_COLORS.lightbgcolor | 57 ++++++++++++++++++++++--------- coreutils.spec | 5 ++- 4 files changed, 55 insertions(+), 29 deletions(-) diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 6abc937..10ebf7a 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -84,11 +84,11 @@ EIGHTBIT 1 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white #NORMAL 00 # no color code at all #FILE 00 # normal file, use no color at all -RESET 0 # reset to "normal" color +RESET 0 # reset to "normal" color DIR 01;34 # directory LINK 01;36 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 00 # regular file with more than one link +MULTIHARDLINK 00 # regular file with more than one link FIFO 40;33 # pipe SOCK 01;35 # socket DOOR 01;35 # door @@ -209,8 +209,6 @@ EXEC 01;32 .emf 01;35 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.axv 01;35 -.anx 01;35 .ogv 01;35 .ogx 01;35 @@ -218,6 +216,7 @@ EXEC 01;32 .aac 01;36 .au 01;36 .flac 01;36 +.m4a 01;36 .mid 01;36 .midi 01;36 .mka 01;36 @@ -228,8 +227,8 @@ EXEC 01;32 .wav 01;36 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.axa 01;36 .oga 01;36 +.opus 01;36 .spx 01;36 .xspf 01;36 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 4efaca1..5290aea 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -55,17 +55,17 @@ EIGHTBIT 1 #NORMAL 00 # global default, no color code at all #FILE 00 # normal file, use no color at all RESET 0 # reset to "normal" color -DIR 38;5;27 # directory +DIR 38;5;33 # directory LINK 38;5;51 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 44;38;5;15 # regular file with more than one link +MULTIHARDLINK 00 # regular file with more than one link FIFO 40;38;5;11 # pipe SOCK 38;5;13 # socket DOOR 38;5;5 # door BLK 48;5;232;38;5;11 # block device driver CHR 48;5;232;38;5;3 # character device driver ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file -MISSING 05;48;5;232;38;5;15 # ... and the files they point to +MISSING 01;05;37;41 # ... and the files they point to SETUID 48;5;196;38;5;15 # file that is setuid (u+s) SETGID 48;5;11;38;5;16 # file that is setgid (g+s) CAPABILITY 48;5;196;38;5;226 # file with capability @@ -74,7 +74,7 @@ OTHER_WRITABLE 48;5;10;38;5;21 # dir that is other-writable (o+w) and not sticky STICKY 48;5;21;38;5;15 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: -EXEC 38;5;34 +EXEC 38;5;40 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. @@ -179,8 +179,6 @@ EXEC 38;5;34 .emf 38;5;13 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.axv 38;5;13 -.anx 38;5;13 .ogv 38;5;13 .ogx 38;5;13 @@ -188,6 +186,7 @@ EXEC 38;5;34 .aac 38;5;45 .au 38;5;45 .flac 38;5;45 +.m4a 38;5;45 .mid 38;5;45 .midi 38;5;45 .mka 38;5;45 @@ -198,8 +197,8 @@ EXEC 38;5;34 .wav 38;5;45 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.axa 38;5;45 .oga 38;5;45 +.opus 38;5;45 .spx 38;5;45 .xspf 38;5;45 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index 43820b2..bf3e5b3 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -1,4 +1,4 @@ -# Configuration file for the color ls utility - modified for gray backgrounds +# Configuration file for the color ls utility - modified for lighter backgrounds # Synchronized with coreutils 8.5 dircolors # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override @@ -16,8 +16,9 @@ COLOR tty OPTIONS -F -T 0 # Below, there should be one TERM entry for each termtype that is colorizable -TERM linux -TERM console +TERM Eterm +TERM ansi +TERM color-xterm TERM con132x25 TERM con132x30 TERM con132x43 @@ -29,20 +30,46 @@ TERM con80x43 TERM con80x50 TERM con80x60 TERM cons25 -TERM xterm -TERM xterm-16color -TERM xterm-88color -TERM xterm-256color +TERM console +TERM cygwin +TERM dtterm +TERM eterm-color +TERM gnome +TERM gnome-256color +TERM jfbterm +TERM konsole +TERM kterm +TERM linux +TERM linux-c +TERM mach-color +TERM mlterm +TERM putty +TERM putty-256color TERM rxvt TERM rxvt-256color +TERM rxvt-cygwin +TERM rxvt-cygwin-native TERM rxvt-unicode TERM rxvt-unicode-256color TERM rxvt-unicode256 -TERM xterm-color -TERM color-xterm +TERM screen +TERM screen-256color +TERM screen-256color-bce +TERM screen-bce +TERM screen-w +TERM screen.Eterm +TERM screen.rxvt +TERM screen.linux +TERM st +TERM st-256color +TERM terminator TERM vt100 -TERM dtterm -TERM color_xterm +TERM xterm +TERM xterm-16color +TERM xterm-256color +TERM xterm-88color +TERM xterm-color +TERM xterm-debian # EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) EIGHTBIT 1 @@ -57,7 +84,7 @@ EIGHTBIT 1 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white #NORMAL 00 # no color code at all #FILE 00 # normal file, use no color at all -RESET 0 +RESET 0 # reset to "normal" color DIR 00;34 # directory LINK 00;36 # symbolic link (If you set this to 'target' instead of a # numerical value, the color is as for the file pointed to.) @@ -76,7 +103,6 @@ STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable - # This is for files with execute permission: EXEC 00;32 @@ -182,8 +208,6 @@ EXEC 00;32 .emf 00;35 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.axv 00;35 -.anx 00;35 .ogv 00;35 .ogx 00;35 @@ -191,6 +215,7 @@ EXEC 00;32 .aac 00;36 .au 00;36 .flac 00;36 +.m4a 00;36 .mid 00;36 .midi 00;36 .mka 00;36 @@ -201,8 +226,8 @@ EXEC 00;32 .wav 00;36 # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.axa 00;36 .oga 00;36 +.opus 00;36 .spx 00;36 .xspf 00;36 diff --git a/coreutils.spec b/coreutils.spec index 71c57ff..b482fa2 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -373,6 +373,9 @@ fi %{_sbindir}/chroot %changelog +* Mon Apr 20 2015 Pádraig Brady - 8.23-9 +- Adjust LS_COLORS in 256 color mode; brighten some, remove hardlink colors (#1196642) + * Sun Mar 22 2015 Peter Robinson 8.23-8 - Drop large ancient docs From 7adccbb0266c6642a5171a0df26f16ba378426c8 Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Wed, 13 May 2015 10:53:55 +0200 Subject: [PATCH 269/523] sort - fix buffer overflow in some case conversions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - patch by Pádraig Brady --- coreutils-i18n.patch | 40 +++++++++++++++++++++++++++++++++++++--- coreutils.spec | 6 +++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e7005cf..948b555 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -3245,8 +3245,8 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c + + if (ignore || translate) + { -+ char *copy_a = (char *) xmalloc (lena + 1 + lenb + 1); -+ char *copy_b = copy_a + lena + 1; ++ char *copy_a = (char *) xmalloc ((lena + lenb) * MB_CUR_MAX + 2); ++ char *copy_b = copy_a + lena * MB_CUR_MAX + 1; + size_t new_len_a, new_len_b; + size_t i, j; + @@ -3452,6 +3452,39 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c } break; +diff -urNp coreutils-8.23-orig/tests/i18n/sort.sh coreutils-8.23/tests/i18n/sort.sh +--- coreutils-8.23-orig/tests/i18n/sort.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.23/tests/i18n/sort.sh 2014-07-22 13:45:52.733652016 +0200 +@@ -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 diff -urNp coreutils-8.23-orig/src/unexpand.c coreutils-8.23/src/unexpand.c --- coreutils-8.23-orig/src/unexpand.c 2014-07-11 13:00:07.000000000 +0200 +++ coreutils-8.23/src/unexpand.c 2014-07-22 13:45:52.721651968 +0200 @@ -4099,11 +4132,12 @@ diff -urNp coreutils-8.23-orig/src/uniq.c coreutils-8.23/src/uniq.c diff -urNp coreutils-8.23-orig/tests/local.mk coreutils-8.23/tests/local.mk --- coreutils-8.23-orig/tests/local.mk 2014-07-22 13:45:10.494422571 +0200 +++ coreutils-8.23/tests/local.mk 2014-07-22 13:45:52.726651988 +0200 -@@ -331,6 +331,7 @@ all_tests = \ +@@ -331,6 +331,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-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ tests/misc/sort-month.sh \ diff --git a/coreutils.spec b/coreutils.spec index b482fa2..94cd5e3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -373,6 +373,10 @@ fi %{_sbindir}/chroot %changelog +* Wed May 13 2015 Ondrej Oprala - 8.23-9 - Adjust LS_COLORS in 256 color mode; brighten some, remove hardlink colors (#1196642) From e2395bc17f364d881937f839d416ce6f56d6a0ae Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 14 May 2015 14:04:44 +0200 Subject: [PATCH 270/523] run 'make check' in parallel to speed up the build --- coreutils.spec | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 94cd5e3..f80345c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -179,7 +179,7 @@ make all %{?_smp_mflags} sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi %check -make check +make check %{?_smp_mflags} %install make DESTDIR=$RPM_BUILD_ROOT install @@ -373,7 +373,10 @@ fi %{_sbindir}/chroot %changelog -* Wed May 13 2015 Ondrej Oprala - 8.23-11 +- run 'make check' in parallel to speed up the build + +* Wed May 13 2015 Ondrej Oprala - 8.23-10 - sort - fix buffer overflow in some case conversions - patch by Pádraig Brady From 58ee24949fc65914c86d7e3b17253481a9c7a998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 4 Jun 2015 10:47:11 +0200 Subject: [PATCH 271/523] call utilities in colorls.* scripts with full path (#1222140) --- coreutils-colorls.csh | 18 +++++++++--------- coreutils-colorls.sh | 16 ++++++++-------- coreutils.spec | 5 ++++- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index a146dd1..f631762 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -16,7 +16,7 @@ set COLORS=/etc/DIR_COLORS if ($?TERM) then if ( -e "/etc/DIR_COLORS.256color" ) then - if ( "`tput colors`" == "256" ) then + if ( "`/usr/bin/tput colors`" == "256" ) then set COLORS=/etc/DIR_COLORS.256color endif endif @@ -30,29 +30,29 @@ if ($?TERM) then if ( -f ~/.dircolors."$TERM" ) set COLORS=~/.dircolors."$TERM" if ( -f ~/.dir_colors."$TERM" ) set COLORS=~/.dir_colors."$TERM" endif -set INCLUDE="`cat "$COLORS" | grep '^INCLUDE' | cut -d ' ' -f2-`" +set INCLUDE="`/usr/bin/cat "$COLORS" | /usr/bin/grep '^INCLUDE' | /usr/bin/cut -d ' ' -f2-`" if ( ! -e "$COLORS" ) exit -set _tmp="`mktemp .colorlsXXX -q --tmpdir=/tmp`" +set _tmp="`/usr/bin/mktemp .colorlsXXX -q --tmpdir=/tmp`" #if mktemp fails, exit when include was active, otherwise use $COLORS file if ( "$_tmp" == '' ) then if ( "$INCLUDE" == '' ) then - eval "`dircolors -c $COLORS`" + eval "`/usr/bin/dircolors -c $COLORS`" endif goto cleanup endif -if ( "$INCLUDE" != '' ) cat "$INCLUDE" >> $_tmp -grep -v '^INCLUDE' "$COLORS" >> $_tmp +if ( "$INCLUDE" != '' ) /usr/bin/cat "$INCLUDE" >> $_tmp +/usr/bin/grep -v '^INCLUDE' "$COLORS" >> $_tmp -eval "`dircolors -c $_tmp`" +eval "`/usr/bin/dircolors -c $_tmp`" -rm -f $_tmp +/usr/bin/rm -f $_tmp if ( "$LS_COLORS" == '' ) exit cleanup: -set color_none=`sed -n '/^COLOR.*none/Ip' < $COLORS` +set color_none=`/usr/bin/sed -n '/^COLOR.*none/Ip' < $COLORS` if ( "$color_none" != '' ) then unset color_none exit diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index f9484b3..c3f6a43 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -15,7 +15,7 @@ if [ -z "$USER_LS_COLORS" ]; then for colors in "$HOME/.dir_colors.$TERM" "$HOME/.dircolors.$TERM" \ "$HOME/.dir_colors" "$HOME/.dircolors"; do [ -e "$colors" ] && COLORS="$colors" && \ - INCLUDE="`cat "$COLORS" | grep '^INCLUDE' | cut -d ' ' -f2-`" && \ + INCLUDE="`/usr/bin/cat "$COLORS" | /usr/bin/grep '^INCLUDE' | /usr/bin/cut -d ' ' -f2-`" && \ break done @@ -23,7 +23,7 @@ if [ -z "$USER_LS_COLORS" ]; then COLORS="/etc/DIR_COLORS.$TERM" [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \ - [ "x`tty -s && tput colors 2>/dev/null`" = "x256" ] && \ + [ "x`/usr/bin/tty -s && /usr/bin/tput colors 2>/dev/null`" = "x256" ] && \ COLORS="/etc/DIR_COLORS.256color" [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS" ] && \ @@ -34,16 +34,16 @@ if [ -z "$USER_LS_COLORS" ]; then if [ -e "$INCLUDE" ]; then - TMP="`mktemp .colorlsXXX -q --tmpdir=/tmp`" + TMP="`/usr/bin/mktemp .colorlsXXX -q --tmpdir=/tmp`" [ -z "$TMP" ] && return - cat "$INCLUDE" >> $TMP - grep -v '^INCLUDE' "$COLORS" >> $TMP + /usr/bin/cat "$INCLUDE" >> $TMP + /usr/bin/grep -v '^INCLUDE' "$COLORS" >> $TMP - eval "`dircolors --sh $TMP 2>/dev/null`" - rm -f $TMP + eval "`/usr/bin/dircolors --sh $TMP 2>/dev/null`" + /usr/bin/rm -f $TMP else - eval "`dircolors --sh $COLORS 2>/dev/null`" + eval "`/usr/bin/dircolors --sh $COLORS 2>/dev/null`" fi [ -z "$LS_COLORS" ] && return diff --git a/coreutils.spec b/coreutils.spec index b11431a..524a952 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -373,6 +373,9 @@ fi %{_sbindir}/chroot %changelog +* Thu Jun 04 2015 Ondrej Vasik - 8.23-7 +- call utilities in colorls.* scripts with full path (#1222140) + * Mon Dec 01 2014 Ondrej Vasik - 8.23-6 - have the LC_TIME subdirs with lang macro (#1169027) From 1b318dd8057a523438ccbb6a29ff86426271e945 Mon Sep 17 00:00:00 2001 From: Jaromir Capik Date: Thu, 11 Jun 2015 15:15:44 +0200 Subject: [PATCH 272/523] Adding STAGE1 bootstrap recipe --- STAGE1-coreutils | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 STAGE1-coreutils diff --git a/STAGE1-coreutils b/STAGE1-coreutils new file mode 100644 index 0000000..bfe73b5 --- /dev/null +++ b/STAGE1-coreutils @@ -0,0 +1,7 @@ +srpm coreutils +mcd $BUILDDIR/$1 +(cd $SRC/${1}-*/ ; autoreconf -vif) +$SRC/${1}-*/configure $TCONFIGARGS --disable-pam +notparallel +make $J man1_MANS= V=1 +make $J man1_MANS= install DESTDIR=${ROOTFS} From 42e4196fc06ab72807851e1ece9786c75dfbdcae Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Wed, 17 Jun 2015 03:15:59 +0000 Subject: [PATCH 273/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index b3d573d..587648e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -373,6 +373,9 @@ fi %{_sbindir}/chroot %changelog +* Wed Jun 17 2015 Fedora Release Engineering - 8.23-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + * Thu Jun 04 2015 Ondrej Vasik - 8.23-12 - call utilities in colorls.* scripts with full path (#1222140) From 1f9b908a99efdad7f2ef1933603cad5708174ebf Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sat, 4 Jul 2015 11:25:51 +0100 Subject: [PATCH 274/523] Disable failing test-update-copyright to fix FTBFS --- coreutils-remove-test-update-copyright.patch | 50 ++++++++++++++++++++ coreutils.spec | 8 +++- 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 coreutils-remove-test-update-copyright.patch diff --git a/coreutils-remove-test-update-copyright.patch b/coreutils-remove-test-update-copyright.patch new file mode 100644 index 0000000..23ce342 --- /dev/null +++ b/coreutils-remove-test-update-copyright.patch @@ -0,0 +1,50 @@ +--- coreutils-8.23/gnulib-tests/gnulib.mk.orig 2015-07-04 11:11:09.438579284 +0100 ++++ coreutils-8.23/gnulib-tests/gnulib.mk 2015-07-04 11:12:12.113643496 +0100 +@@ -2312,14 +2312,6 @@ + + ## end gnulib module unsetenv-tests + +-## begin gnulib module update-copyright-tests +- +-TESTS += test-update-copyright.sh +-TESTS_ENVIRONMENT += abs_aux_dir='$(abs_aux_dir)' +-EXTRA_DIST += test-update-copyright.sh +- +-## end gnulib module update-copyright-tests +- + ## begin gnulib module userspec-tests + + TESTS += test-userspec +--- coreutils-8.23/gnulib-tests/Makefile.in.orig 2015-07-04 11:10:54.353323089 +0100 ++++ coreutils-8.23/gnulib-tests/Makefile.in 2015-07-04 11:12:45.542210970 +0100 +@@ -220,7 +220,6 @@ + test-u8-mbtoucr$(EXEEXT) test-u8-uctomb$(EXEEXT) \ + test-uc_width$(EXEEXT) uniwidth/test-uc_width2.sh \ + test-unlink$(EXEEXT) test-unlinkat$(EXEEXT) \ +- test-unsetenv$(EXEEXT) test-update-copyright.sh \ + test-userspec$(EXEEXT) test-utimens$(EXEEXT) \ + test-utimensat$(EXEEXT) test-vasnprintf$(EXEEXT) \ + test-vasprintf-posix$(EXEEXT) test-vasprintf$(EXEEXT) \ +@@ -3766,7 +3765,7 @@ + uniwidth/test-uc_width2.sh macros.h test-unlink.h \ + test-unlink.c signature.h macros.h test-unlinkat.c \ + test-rmdir.h test-unlink.h signature.h macros.h unlinkdir.h \ +- test-unsetenv.c signature.h macros.h test-update-copyright.sh \ ++ test-unsetenv.c signature.h macros.h \ + test-userspec.c nap.h test-futimens.h test-lutimens.h \ + test-utimens.h test-utimens-common.h test-utimens.c macros.h \ + nap.h test-lutimens.h test-utimens.h test-utimens-common.h \ +@@ -7787,13 +7786,6 @@ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ +- "$$tst" $(AM_TESTS_FD_REDIRECT) +-test-update-copyright.sh.log: test-update-copyright.sh +- @p='test-update-copyright.sh'; \ +- b='test-update-copyright.sh'; \ +- $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ +- --log-file $$b.log --trs-file $$b.trs \ +- $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) + test-userspec.log: test-userspec$(EXEEXT) + @p='test-userspec$(EXEEXT)'; \ diff --git a/coreutils.spec b/coreutils.spec index 587648e..b6b6450 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.23 -Release: 13%{?dist} +Release: 14%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -29,6 +29,8 @@ Patch103: coreutils-8.2-uname-processortype.patch Patch104: coreutils-df-direct.patch #add note about mkdir --mode behaviour into info documentation(#610559) Patch107: coreutils-8.4-mkdir-modenote.patch +# Don't run the currently failing test-update-copyright.sh test +Patch108: coreutils-remove-test-update-copyright.patch # sh-utils #add info about TZ envvar to date manpage @@ -132,6 +134,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect %patch107 -p1 -b .mkdirmode +%patch108 -p1 -b .crtest # sh-utils %patch703 -p1 -b .dateman @@ -373,6 +376,9 @@ fi %{_sbindir}/chroot %changelog +* Sat Jul 4 2015 Peter Robinson 8.23-14 +- Disable failing test-update-copyright to fix FTBFS + * Wed Jun 17 2015 Fedora Release Engineering - 8.23-13 - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild From 3775f446fe0e41a1998e3b0931d4a8d53a15a602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sun, 5 Jul 2015 09:17:02 +0200 Subject: [PATCH 275/523] new upstream release 8.24 --- .gitignore | 2 + coreutils-6.10-configuration.patch | 6 +- coreutils-8.23-chroot-chdir.patch | 411 --------------------------- coreutils-DIR_COLORS | 2 + coreutils-DIR_COLORS.lightbgcolor | 2 + coreutils-df-direct.patch | 8 +- coreutils-i18n.patch | 441 ++++++++++++++--------------- coreutils.spec | 10 +- sources | 4 +- 9 files changed, 235 insertions(+), 651 deletions(-) delete mode 100644 coreutils-8.23-chroot-chdir.patch diff --git a/.gitignore b/.gitignore index cbcc306..8f473b3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ /coreutils-8.22.tar.xz /coreutils-8.23.tar.xz /coreutils-8.23.tar.xz.sig +/coreutils-8.24.tar.xz +/coreutils-8.24.tar.xz.sig diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 4403811..4c68077 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -172,15 +172,15 @@ diff -urNp coreutils-8.23-orig/tests/df/skip-duplicates.sh coreutils-8.23/tests/ +++ coreutils-8.23/tests/df/skip-duplicates.sh 2014-07-24 15:53:33.473031545 +0200 @@ -25,6 +25,10 @@ require_gcc_shared_ # potentially very many remote mounts. - df --local || skip_ "df fails" + df --local || skip_ 'df fails' +#mark it expensive, to temporarily skip the test in koji +expensive_ + + export CU_NONROOT_FS=$(df --local --output=target 2>&1 | grep /. | head -n1) - test -z "$CU_NONROOT_FS" && unique_entries=1 || unique_entries=2 - + export CU_REMOTE_FS=$(df --local --output=target 2>&1 | grep /. | + tail -n+2 | head -n1) diff -urNp coreutils-8.23-orig/man/local.mk coreutils-8.23/man/local.mk --- coreutils-8.23-orig/man/local.mk 2014-07-18 03:40:57.000000000 +0200 +++ coreutils-8.23/man/local.mk 2014-08-05 12:18:20.477524009 +0200 diff --git a/coreutils-8.23-chroot-chdir.patch b/coreutils-8.23-chroot-chdir.patch deleted file mode 100644 index ce977bd..0000000 --- a/coreutils-8.23-chroot-chdir.patch +++ /dev/null @@ -1,411 +0,0 @@ -From 0cf7b1d928acaaddd4eaa28c6a22f7bd6457b379 Mon Sep 17 00:00:00 2001 -From: Bernhard Voelker -Date: Fri, 01 Aug 2014 00:07:33 +0000 -Subject: chroot: perform chdir("/") again unless new --skip-chdir is specified - -Since commit v8.22-94-g99960ee, chroot(1) skips the chroot(2) syscall -for "/" arguments (and synonyms). The problem is that it also skips -the following chdir("/") call in that case. The latter breaks existing -scripts which expect "/" to be the working directory inside the chroot. -While the first part of the change - i.e., skipping chroot("/") - is -okay for consistency with systems where it might succeed for a non-root -user, the second part might be malicious, e.g. - - cd /home/user && chroot '/' bin/foo - -In the "best" case, chroot(1) could not execute 'bin/foo' with ENOENT, -but in the worst case, chroot(1) would execute '/home/user/bin/foo' in -the case that exists - instead of '/bin/foo'. - -Revert that second part of the patch, i.e., perform the chdir("/) -in the common case again - unless the new --skip-chdir option is -specified. Restrict this new option to the case of "/" arguments. - -* src/chroot.c (SKIP_CHDIR): Add enum. -(long_opts): Add entry for the new --skip-chdir option. -(usage): Add --skip-chdir option, and while at it, move the other -to options into alphabetical order. -(main): Accept the above new option, allowing it only in the case -when NEWROOT is the old "/". -Move down the chdir() call after the if-clause to ensure it is -run in any case - unless --skip-chdir is specified. -Add a 'newroot' variable for the new root directory as it is used -in a couple of places now. -* tests/misc/chroot-fail.sh: Invert the last tests which check the -working directory of the execvp()ed program when a "/"-like -argument was passed: now expect it to be "/" - unless --skip-chdir -is given. -* doc/coreutils.texi (chroot invocation): Document the new option. -Document that chroot(1) usually calls chdir("/") unless the new ---skip-chdir option is specified. Sort options. -* init.cfg (nonroot_has_perm_): Add chroot's new --skip-chdir option. -* tests/cp/preserve-gid.sh (t1): Likewise. -* tests/cp/special-bits.sh: Likewise. -* tests/id/setgid.sh: Likewise. -* tests/misc/truncate-owned-by-other.sh: Likewise. -* tests/mv/sticky-to-xpart.sh: Likewise. -* tests/rm/fail-2eperm.sh: Likewise. -* tests/rm/no-give-up.sh: Likewise. -* tests/touch/now-owned-by-other.sh: Likewise. - -Reported by Andreas Schwab in http://bugs.gnu.org/18062 ---- -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 96f0781..7c86719 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -16113,7 +16113,10 @@ On many systems, only the super-user can do this.@footnote{However, - some systems (e.g., FreeBSD) can be configured to allow certain regular - users to use the @code{chroot} system call, and hence to run this program. - Also, on Cygwin, anyone can run the @command{chroot} command, because the --underlying function is non-privileged due to lack of support in MS-Windows.} -+underlying function is non-privileged due to lack of support in MS-Windows. -+Furthermore, the @command{chroot} command avoids the @code{chroot} system call -+when @var{newroot} is identical to the old @file{/} directory for consistency -+with systems where this is allowed for non-privileged users.}. - Synopses: - - @example -@@ -16123,10 +16126,11 @@ chroot @var{option} - - Ordinarily, file names are looked up starting at the root of the - directory structure, i.e., @file{/}. @command{chroot} changes the root to --the directory @var{newroot} (which must exist) and then runs --@var{command} with optional @var{args}. If @var{command} is not --specified, the default is the value of the @env{SHELL} environment --variable or @command{/bin/sh} if not set, invoked with the @option{-i} option. -+the directory @var{newroot} (which must exist), then changes the working -+directory to @file{/}, and finally runs @var{command} with optional @var{args}. -+If @var{command} is not specified, the default is the value of the @env{SHELL} -+environment variable or @command{/bin/sh} if not set, invoked with the -+@option{-i} option. - @var{command} must not be a special built-in utility - (@pxref{Special built-in utilities}). - -@@ -16135,6 +16139,14 @@ Options must precede operands. - - @table @samp - -+@item --groups=@var{groups} -+@opindex --groups -+Use this option to override the supplementary @var{groups} to be -+used by the new process. -+The items in the list (names or numeric IDs) must be separated by commas. -+Use @samp{--groups=''} to disable the supplementary group look-up -+implicit in the @option{--userspec} option. -+ - @item --userspec=@var{user}[:@var{group}] - @opindex --userspec - By default, @var{command} is run with the same credentials -@@ -16145,13 +16157,13 @@ If a @var{user} is specified then the supplementary groups - are set according to the system defined list for that user, - unless overridden with the @option{--groups} option. - --@item --groups=@var{groups} --@opindex --groups --Use this option to override the supplementary @var{groups} to be --used by the new process. --The items in the list (names or numeric IDs) must be separated by commas. --Use @samp{--groups=''} to disable the supplementary group look-up --implicit in the @option{--userspec} option. -+@item --skip-chdir -+@opindex --skip-chdir -+Use this option to not change the working directory to @file{/} after changing -+the root directory to @var{newroot}, i.e., inside the chroot. -+This option is only permitted when @var{newroot} is the old @file{/} directory, -+and therefore is mostly useful together with the @option{--groups} and -+@option{--userspec} options to retain the previous working directory. - - @end table - -diff --git a/init.cfg b/init.cfg -index 725ee12..032646b 100644 ---- a/init.cfg -+++ b/init.cfg -@@ -400,7 +400,8 @@ nonroot_has_perm_() - require_built_ chroot - - local rm_version=$( -- chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm --version | -+ chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ -+ rm --version | - sed -n '1s/.* //p' - ) - case ":$rm_version:" in -diff --git a/src/chroot.c b/src/chroot.c -index 6c2d63f..418ea67 100644 ---- a/src/chroot.c -+++ b/src/chroot.c -@@ -49,13 +49,15 @@ static inline bool gid_unset (gid_t gid) { return gid == (gid_t) -1; } - enum - { - GROUPS = UCHAR_MAX + 1, -- USERSPEC -+ USERSPEC, -+ SKIP_CHDIR - }; - - static struct option const long_opts[] = - { - {"groups", required_argument, NULL, GROUPS}, - {"userspec", required_argument, NULL, USERSPEC}, -+ {"skip-chdir", no_argument, NULL, SKIP_CHDIR}, - {GETOPT_HELP_OPTION_DECL}, - {GETOPT_VERSION_OPTION_DECL}, - {NULL, 0, NULL, 0} -@@ -194,9 +196,14 @@ Run COMMAND with root directory set to NEWROOT.\n\ - "), stdout); - - fputs (_("\ -- --userspec=USER:GROUP specify user and group (ID or name) to use\n\ - --groups=G_LIST specify supplementary groups as g1,g2,..,gN\n\ - "), stdout); -+ fputs (_("\ -+ --userspec=USER:GROUP specify user and group (ID or name) to use\n\ -+"), stdout); -+ printf (_("\ -+ --skip-chdir do not change working directory to %s\n\ -+"), quote ("/")); - - fputs (HELP_OPTION_DESCRIPTION, stdout); - fputs (VERSION_OPTION_DESCRIPTION, stdout); -@@ -218,6 +225,7 @@ main (int argc, char **argv) - char *userspec = NULL; - char const *username = NULL; - char const *groups = NULL; -+ bool skip_chdir = false; - - /* Parsed user and group IDs. */ - uid_t uid = -1; -@@ -254,6 +262,10 @@ main (int argc, char **argv) - groups = optarg; - break; - -+ case SKIP_CHDIR: -+ skip_chdir = true; -+ break; -+ - case_GETOPT_HELP_CHAR; - - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); -@@ -269,9 +281,19 @@ main (int argc, char **argv) - usage (EXIT_CANCELED); - } - -+ char const *newroot = argv[optind]; -+ bool is_oldroot = is_root (newroot); -+ -+ if (! is_oldroot && skip_chdir) -+ { -+ error (0, 0, _("option --skip-chdir only permitted if NEWROOT is old %s"), -+ quote ("/")); -+ usage (EXIT_CANCELED); -+ } -+ - /* Only do chroot specific actions if actually changing root. - The main difference here is that we don't change working dir. */ -- if (! is_root (argv[optind])) -+ if (! is_oldroot) - { - /* We have to look up users and groups twice. - - First, outside the chroot to load potentially necessary passwd/group -@@ -307,14 +329,14 @@ main (int argc, char **argv) - } - #endif - -- if (chroot (argv[optind]) != 0) -+ if (chroot (newroot) != 0) - error (EXIT_CANCELED, errno, _("cannot change root directory to %s"), -- argv[optind]); -- -- if (chdir ("/")) -- error (EXIT_CANCELED, errno, _("cannot chdir to root directory")); -+ newroot); - } - -+ if (! skip_chdir && chdir ("/")) -+ error (EXIT_CANCELED, errno, _("cannot chdir to root directory")); -+ - if (argc == optind + 1) - { - /* No command. Run an interactive shell. */ -diff --git a/tests/cp/preserve-gid.sh b/tests/cp/preserve-gid.sh -index f141ac1..5499c2e 100755 ---- a/tests/cp/preserve-gid.sh -+++ b/tests/cp/preserve-gid.sh -@@ -117,7 +117,8 @@ t1() { - u=$1; shift - g=$1; shift - t0 "$f" "$u" "$g" \ -- chroot --user=+$nameless_uid:+$nameless_gid1 \ -+ chroot --skip-chdir \ -+ --user=+$nameless_uid:+$nameless_gid1 \ - --groups="+$nameless_gid1,+$nameless_gid2" \ - / env PATH="$tmp_path" "$@" - } -diff --git a/tests/cp/special-bits.sh b/tests/cp/special-bits.sh -index a55eea2..1402819 100755 ---- a/tests/cp/special-bits.sh -+++ b/tests/cp/special-bits.sh -@@ -42,7 +42,8 @@ set _ $(ls -l b); shift; p1=$1 - set _ $(ls -l b2); shift; p2=$1 - test $p1 = $p2 || fail=1 - --chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" cp -p c c2 || fail=1 -+chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" cp -p c c2 \ -+ || fail=1 - set _ $(ls -l c); shift; p1=$1 - set _ $(ls -l c2); shift; p2=$1 - test $p1 = $p2 && fail=1 -diff --git a/tests/id/setgid.sh b/tests/id/setgid.sh -index 6d9d74f..019418a 100755 ---- a/tests/id/setgid.sh -+++ b/tests/id/setgid.sh -@@ -27,14 +27,14 @@ echo $gp1 > exp || framework_failure_ - - # With coreutils-8.16 and earlier, id -G would print both: - # $gp1 $NON_ROOT_GID --chroot --user=$NON_ROOT_USERNAME:+$gp1 --groups='' / env PATH="$PATH" \ -- id -G > out || fail=1 -+chroot --skip-chdir --user=$NON_ROOT_USERNAME:+$gp1 --groups='' / \ -+ env PATH="$PATH" id -G > out || fail=1 - compare exp out || fail=1 - - # With coreutils-8.22 and earlier, id would erroneously print - # groups=$NON_ROOT_GID --chroot --user=$NON_ROOT_USERNAME:+$gp1 --groups='' / env PATH="$PATH" \ -- id > out || fail=1 -+chroot --skip-chdir --user=$NON_ROOT_USERNAME:+$gp1 --groups='' / \ -+ env PATH="$PATH" id > out || fail=1 - grep -F "groups=$gp1" out || { cat out; fail=1; } - - Exit $fail -diff --git a/tests/misc/chroot-fail.sh b/tests/misc/chroot-fail.sh -index a84826f..82ae23c 100755 ---- a/tests/misc/chroot-fail.sh -+++ b/tests/misc/chroot-fail.sh -@@ -30,7 +30,7 @@ chroot --- / true # unknown option - test $? = 125 || fail=1 - - # Note chroot("/") succeeds for non-root users on some systems, but not all, --# however we avoid the chroot() with "/" to have common behvavior. -+# however we avoid the chroot() with "/" to have common behavior. - chroot / sh -c 'exit 2' # exit status propagation - test $? = 2 || fail=1 - chroot / . # invalid command -@@ -38,10 +38,25 @@ test $? = 126 || fail=1 - chroot / no_such # no such command - test $? = 127 || fail=1 - --# Ensure we don't chdir("/") when not changing root --# to allow only changing user ids for a command. --for dir in '/' '/.' '/../'; do -+# Ensure that --skip-chdir fails with a non-"/" argument. -+cat <<\EOF > exp || framework_failure_ -+chroot: option --skip-chdir only permitted if NEWROOT is old '/' -+Try 'chroot --help' for more information. -+EOF -+chroot --skip-chdir . env pwd >out 2>err && fail=1 -+compare /dev/null out || fail=1 -+compare exp err || fail=1 -+ -+# Ensure we don't chroot("/") when NEWROOT is old "/". -+ln -s / isroot || framework_failure_ -+for dir in '/' '/.' '/../' isroot; do -+ # Verify that chroot(1) succeeds and performs chdir("/") -+ # (chroot(1) of coreutils-8.23 failed to run the latter). - curdir=$(chroot "$dir" env pwd) || fail=1 -+ test "$curdir" = '/' || fail=1 -+ -+ # Test the "--skip-chdir" option. -+ curdir=$(chroot --skip-chdir "$dir" env pwd) || fail=1 - test "$curdir" = '/' && fail=1 - done - -diff --git a/tests/misc/truncate-owned-by-other.sh b/tests/misc/truncate-owned-by-other.sh -index e70badb..f65439e 100755 ---- a/tests/misc/truncate-owned-by-other.sh -+++ b/tests/misc/truncate-owned-by-other.sh -@@ -29,7 +29,7 @@ chmod g+w root-owned - # Ensure that the current directory is searchable by $NON_ROOT_USERNAME. - chmod g+x . - --chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ -+chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ - truncate -s0 root-owned || fail=1 - - Exit $fail -diff --git a/tests/mv/sticky-to-xpart.sh b/tests/mv/sticky-to-xpart.sh -index e0c99e9..6c1f6e8 100755 ---- a/tests/mv/sticky-to-xpart.sh -+++ b/tests/mv/sticky-to-xpart.sh -@@ -42,7 +42,8 @@ chmod go+x . || framework_failure_ - - # Ensure that $NON_ROOT_USERNAME can access the required version of mv. - version=$( -- chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" mv --version | -+ chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ -+ mv --version | - sed -n '1s/.* //p' - ) - case $version in -@@ -50,7 +51,7 @@ case $version in - *) skip_ "cannot access just-built mv as user $NON_ROOT_USERNAME";; - esac - --chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ -+chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ - mv t/root-owned "$other_partition_tmpdir" 2> out-t && fail=1 - - # On some systems, we get 'Not owner'. Convert it. -diff --git a/tests/rm/fail-2eperm.sh b/tests/rm/fail-2eperm.sh -index 6e8ce9b..c324037 100755 ---- a/tests/rm/fail-2eperm.sh -+++ b/tests/rm/fail-2eperm.sh -@@ -32,14 +32,16 @@ touch a/b || framework_failure_ - # Try to ensure that $NON_ROOT_USERNAME can access - # the required version of rm. - rm_version=$( -- chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm --version | -+ chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ -+ rm --version | - sed -n '1s/.* //p' - ) - case $rm_version in - $PACKAGE_VERSION) ;; - *) skip_ "cannot access just-built rm as user $NON_ROOT_USERNAME";; - esac --chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm -rf a 2> out-t && fail=1 -+chroot --skip-chdir --user=$NON_ROOT_USERNAME / \ -+ env PATH="$PATH" rm -rf a 2> out-t && fail=1 - - # On some systems, we get 'Not owner'. Convert it. - # On other systems (HPUX), we get 'Permission denied'. Convert it, too. -diff --git a/tests/rm/no-give-up.sh b/tests/rm/no-give-up.sh -index 41070c9..958f9e8 100755 ---- a/tests/rm/no-give-up.sh -+++ b/tests/rm/no-give-up.sh -@@ -30,7 +30,7 @@ chmod go=x . || framework_failure_ - - - # This must fail, since '.' is not writable by $NON_ROOT_USERNAME. --chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ -+chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ - rm -rf d 2>/dev/null && fail=1 - - # d must remain. -diff --git a/tests/touch/now-owned-by-other.sh b/tests/touch/now-owned-by-other.sh -index d01097e..018ef11 100755 ---- a/tests/touch/now-owned-by-other.sh -+++ b/tests/touch/now-owned-by-other.sh -@@ -28,7 +28,7 @@ chmod g+w root-owned - # Ensure that the current directory is searchable by $NON_ROOT_USERNAME. - chmod g+x . - --chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ -+chroot --skip-chdir --user=$NON_ROOT_USERNAME / env PATH="$PATH" \ - touch -d now root-owned || fail=1 - - Exit $fail --- -cgit v0.9.0.2 diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index 10ebf7a..ecffc65 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -36,12 +36,14 @@ TERM dtterm TERM eterm-color TERM gnome TERM gnome-256color +TERM hurd TERM jfbterm TERM konsole TERM kterm TERM linux TERM linux-c TERM mach-color +TERM mach-gnu-color TERM mlterm TERM putty TERM putty-256color diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index bf3e5b3..450deb0 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -36,12 +36,14 @@ TERM dtterm TERM eterm-color TERM gnome TERM gnome-256color +TERM hurd TERM jfbterm TERM konsole TERM kterm TERM linux TERM linux-c TERM mach-color +TERM mach-gnu-color TERM mlterm TERM putty TERM putty-256color diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index a3df5e9..361b813 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,9 +1,9 @@ diff -urNp coreutils-8.21-orig/doc/coreutils.texi coreutils-8.21/doc/coreutils.texi --- coreutils-8.21-orig/doc/coreutils.texi 2013-02-11 10:37:28.000000000 +0100 +++ coreutils-8.21/doc/coreutils.texi 2013-02-15 10:15:26.497593689 +0100 -@@ -10961,6 +10961,13 @@ pseudo-file-systems, such as automounter - Scale sizes by @var{size} before printing them (@pxref{Block size}). - For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. +@@ -10961,6 +10961,13 @@ + but in general this option makes @command{df} much slower, especially when + there are many or very busy file systems. +@item --direct +@opindex --direct @@ -82,9 +82,9 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ + --direct show statistics for a file instead of mount point\n\ - --total produce a grand total\n\ -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ + "), stdout); @@ -1305,6 +1325,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 948b555..d1d18a8 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,6 @@ -diff -urNp coreutils-8.23-orig/lib/linebuffer.h coreutils-8.23/lib/linebuffer.h ---- coreutils-8.23-orig/lib/linebuffer.h 2014-05-29 14:05:50.000000000 +0200 -+++ coreutils-8.23/lib/linebuffer.h 2014-07-22 13:45:52.700651881 +0200 +diff -urNp coreutils-8.24-orig/lib/linebuffer.h coreutils-8.24/lib/linebuffer.h +--- coreutils-8.24-orig/lib/linebuffer.h 2015-06-16 07:00:37.000000000 +0200 ++++ coreutils-8.24/lib/linebuffer.h 2015-07-05 09:04:33.027546943 +0200 @@ -21,6 +21,11 @@ # include @@ -23,9 +23,9 @@ diff -urNp coreutils-8.23-orig/lib/linebuffer.h coreutils-8.23/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c ---- coreutils-8.23-orig/src/cut.c 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/src/cut.c 2014-07-22 13:48:06.225671732 +0200 +diff -urNp coreutils-8.24-orig/src/cut.c coreutils-8.24/src/cut.c +--- coreutils-8.24-orig/src/cut.c 2015-06-26 19:05:22.000000000 +0200 ++++ coreutils-8.24/src/cut.c 2015-07-05 09:04:33.028546950 +0200 @@ -28,6 +28,11 @@ #include #include @@ -156,7 +156,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c /* True if the --output-delimiter=STRING option was specified. */ static bool output_delimiter_specified; -@@ -188,7 +266,7 @@ Print selected parts of lines from each +@@ -189,7 +267,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\ @@ -165,7 +165,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -381,6 +459,9 @@ set_fields (const char *fieldstr) +@@ -380,6 +458,9 @@ set_fields (const char *fieldstr) if (operating_mode == byte_mode) error (0, 0, _("byte offset %s is too large"), quote (bad_num)); @@ -175,7 +175,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c else error (0, 0, _("field number %s is too large"), quote (bad_num)); -@@ -505,6 +586,82 @@ cut_bytes (FILE *stream) +@@ -504,6 +585,82 @@ cut_bytes (FILE *stream) } } @@ -258,7 +258,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -649,13 +806,211 @@ cut_fields (FILE *stream) +@@ -648,13 +805,211 @@ cut_fields (FILE *stream) } } @@ -473,7 +473,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c } /* Process file FILE to standard output. -@@ -707,6 +1062,7 @@ main (int argc, char **argv) +@@ -706,6 +1061,7 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -481,7 +481,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -729,7 +1085,6 @@ main (int argc, char **argv) +@@ -728,7 +1084,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -489,7 +489,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -737,6 +1092,14 @@ main (int argc, char **argv) +@@ -736,6 +1091,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -504,7 +504,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -748,10 +1111,38 @@ main (int argc, char **argv) +@@ -747,10 +1110,38 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -547,7 +547,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c break; case OUTPUT_DELIMITER_OPTION: -@@ -764,6 +1155,7 @@ main (int argc, char **argv) +@@ -763,6 +1154,7 @@ main (int argc, char **argv) break; case 'n': @@ -555,7 +555,7 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c break; case 's': -@@ -803,15 +1195,34 @@ main (int argc, char **argv) +@@ -802,15 +1194,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -596,9 +596,9 @@ diff -urNp coreutils-8.23-orig/src/cut.c coreutils-8.23/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.23-orig/src/expand.c coreutils-8.23/src/expand.c ---- coreutils-8.23-orig/src/expand.c 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/src/expand.c 2014-07-22 13:45:52.704651900 +0200 +diff -urNp coreutils-8.24-orig/src/expand.c coreutils-8.24/src/expand.c +--- coreutils-8.24-orig/src/expand.c 2015-06-26 19:05:22.000000000 +0200 ++++ coreutils-8.24/src/expand.c 2015-07-05 09:04:33.028546950 +0200 @@ -37,12 +37,34 @@ #include #include @@ -791,10 +791,10 @@ diff -urNp coreutils-8.23-orig/src/expand.c coreutils-8.23/src/expand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c ---- coreutils-8.23-orig/src/fold.c 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/src/fold.c 2014-07-22 13:45:52.705651904 +0200 -@@ -22,12 +22,34 @@ +diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c +--- coreutils-8.24-orig/src/fold.c 2015-06-26 19:05:22.000000000 +0200 ++++ coreutils-8.24/src/fold.c 2015-07-05 09:04:33.029546958 +0200 +@@ -22,11 +22,33 @@ #include #include @@ -811,8 +811,7 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c #include "system.h" #include "error.h" #include "fadvise.h" - #include "quote.h" - #include "xstrtol.h" + #include "xdectoint.h" +/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC + installation; work around this configuration error. */ @@ -829,7 +828,7 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c #define TAB_WIDTH 8 /* The official name of this program (e.g., no 'g' prefix). */ -@@ -35,20 +57,41 @@ +@@ -34,20 +56,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -875,7 +874,7 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c {"spaces", no_argument, NULL, 's'}, {"width", required_argument, NULL, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -76,6 +119,7 @@ standard output.\n\ +@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -883,7 +882,7 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -93,7 +137,7 @@ standard output.\n\ +@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing t static size_t adjust_column (size_t column, char c) { @@ -892,7 +891,7 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c { if (c == '\b') { -@@ -116,30 +160,14 @@ adjust_column (size_t column, char c) +@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -925,7 +924,7 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c fadvise (istream, FADVISE_SEQUENTIAL); -@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t +@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t bool found_blank = false; size_t logical_end = offset_out; @@ -941,16 +940,16 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -215,11 +252,221 @@ fold_file (char const *filename, size_t +@@ -214,11 +251,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 (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ +} + +#if HAVE_MBRTOWC @@ -1122,10 +1121,10 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c + } + + *saved_errno = errno; -+ -+ if (offset_out) -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); -+ + + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + +} +#endif + @@ -1164,7 +1163,7 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c if (ferror (istream)) { error (0, saved_errno, "%s", filename); -@@ -252,7 +499,8 @@ main (int argc, char **argv) +@@ -251,7 +498,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1174,7 +1173,7 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -261,7 +509,15 @@ main (int argc, char **argv) +@@ -260,7 +508,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1191,9 +1190,9 @@ diff -urNp coreutils-8.23-orig/src/fold.c coreutils-8.23/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c ---- coreutils-8.23-orig/src/join.c 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/src/join.c 2014-07-22 13:45:52.707651912 +0200 +diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c +--- coreutils-8.24-orig/src/join.c 2015-06-26 19:05:22.000000000 +0200 ++++ coreutils-8.24/src/join.c 2015-07-05 09:04:33.029546958 +0200 @@ -22,18 +22,32 @@ #include #include @@ -1245,7 +1244,7 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -269,13 +285,14 @@ xfields (struct line *line) +@@ -275,13 +291,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1263,7 +1262,7 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c { /* Skip leading blanks before the first field. */ while (isblank (to_uchar (*ptr))) -@@ -299,6 +316,147 @@ xfields (struct line *line) +@@ -305,6 +322,147 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1411,7 +1410,7 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c static void freeline (struct line *line) { -@@ -320,56 +478,133 @@ keycmp (struct line const *line1, struct +@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -1542,8 +1541,8 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c - 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]); @@ -1553,14 +1552,14 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c + 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; @@ -1568,7 +1567,7 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -461,6 +696,11 @@ get_line (FILE *fp, struct line **linep, +@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep, } ++line_no[which - 1]; @@ -1580,7 +1579,7 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c xfields (line); if (prevline[which - 1]) -@@ -560,21 +800,28 @@ prfield (size_t n, struct line const *li +@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li /* Output all the fields in line, other than the join field. */ @@ -1612,7 +1611,7 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c prfield (i, line); } } -@@ -585,7 +832,6 @@ static void +@@ -591,7 +838,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -1620,7 +1619,7 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c size_t field; struct line const *line; -@@ -619,7 +865,7 @@ prjoin (struct line const *line1, struct +@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct o = o->next; if (o == NULL) break; @@ -1629,7 +1628,7 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c } putchar (eolchar); } -@@ -1097,21 +1343,46 @@ main (int argc, char **argv) +@@ -1103,21 +1349,46 @@ main (int argc, char **argv) case 't': { @@ -1686,9 +1685,9 @@ diff -urNp coreutils-8.23-orig/src/join.c coreutils-8.23/src/join.c break; case 'z': -diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c ---- coreutils-8.23-orig/src/pr.c 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/src/pr.c 2014-07-22 13:45:52.713651936 +0200 +diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c +--- coreutils-8.24-orig/src/pr.c 2015-06-26 19:05:22.000000000 +0200 ++++ coreutils-8.24/src/pr.c 2015-07-05 09:04:33.030546965 +0200 @@ -312,6 +312,24 @@ #include @@ -1714,9 +1713,9 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c #include "system.h" #include "error.h" #include "fadvise.h" -@@ -323,6 +341,18 @@ - #include "strftime.h" +@@ -324,6 +342,18 @@ #include "xstrtol.h" + #include "xdectoint.h" +/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ +#if HAVE_MBRTOWC && defined mbstate_t @@ -1733,7 +1732,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -415,7 +445,20 @@ struct COLUMN +@@ -416,7 +446,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -1755,23 +1754,23 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -425,6 +468,7 @@ static void print_header (void); - static void pad_across_to (int position); - static void add_line_number (COLUMN *p); +@@ -428,6 +471,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); -@@ -438,7 +482,6 @@ static void store_char (char c); - static void pad_down (int lines); +@@ -441,7 +485,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); -@@ -450,7 +493,7 @@ static COLUMN *column_vector; +@@ -453,7 +496,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]. */ @@ -1780,7 +1779,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* Index of the position in buff where the next character will be stored. */ -@@ -554,7 +597,7 @@ static int chars_per_column; +@@ -557,7 +600,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -1789,7 +1788,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... where the leftmost column is 1. */ -@@ -564,7 +607,10 @@ static int chars_per_input_tab = 8; +@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -1801,7 +1800,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -634,7 +680,13 @@ static int line_number; +@@ -637,7 +683,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1816,7 +1815,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -687,6 +739,7 @@ static bool use_col_separator = false; +@@ -690,6 +742,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ static char *col_sep_string = (char *) ""; static int col_sep_length = 0; @@ -1824,7 +1823,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -843,6 +896,13 @@ separator_string (const char *optarg_S) +@@ -840,6 +893,13 @@ separator_string (const char *optarg_S) col_sep_length = (int) strlen (optarg_S); col_sep_string = xmalloc (col_sep_length + 1); strcpy (col_sep_string, optarg_S); @@ -1838,7 +1837,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c } int -@@ -867,6 +927,21 @@ main (int argc, char **argv) +@@ -864,6 +924,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1860,7 +1859,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c n_files = 0; file_names = (argc > 1 ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -943,8 +1018,12 @@ main (int argc, char **argv) +@@ -940,8 +1015,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1875,7 +1874,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -957,8 +1036,12 @@ main (int argc, char **argv) +@@ -954,8 +1033,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1890,7 +1889,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -985,8 +1068,8 @@ main (int argc, char **argv) +@@ -973,8 +1056,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1901,7 +1900,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c break; case 'N': skip_count = false; -@@ -1025,7 +1108,7 @@ main (int argc, char **argv) +@@ -998,7 +1081,7 @@ main (int argc, char **argv) old_s = false; /* Reset an additional input of -s, -S dominates -s */ col_sep_string = bad_cast (""); @@ -1910,7 +1909,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1182,10 +1265,45 @@ main (int argc, char **argv) +@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i a number. */ static void @@ -1958,7 +1957,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c if (*arg) { long int tmp_long; -@@ -1207,6 +1325,11 @@ static void +@@ -1177,6 +1295,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -1970,7 +1969,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1244,7 +1367,7 @@ init_parameters (int number_of_files) +@@ -1214,7 +1337,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -1979,7 +1978,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1274,11 +1397,11 @@ init_parameters (int number_of_files) +@@ -1244,11 +1367,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. */ @@ -1993,7 +1992,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1287,7 +1410,7 @@ init_parameters (int number_of_files) +@@ -1257,7 +1380,7 @@ init_parameters (int number_of_files) } chars_per_column = (chars_per_line - chars_used_by_number @@ -2002,7 +2001,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c if (chars_per_column < 1) error (EXIT_FAILURE, 0, _("page width too narrow")); -@@ -1305,7 +1428,7 @@ init_parameters (int number_of_files) +@@ -1275,7 +1398,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); @@ -2011,7 +2010,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c } /* Open the necessary files, -@@ -1413,7 +1536,7 @@ init_funcs (void) +@@ -1383,7 +1506,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2020,7 +2019,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* This loop takes care of all but the rightmost column. */ -@@ -1447,7 +1570,7 @@ init_funcs (void) +@@ -1417,7 +1540,7 @@ init_funcs (void) } else { @@ -2029,7 +2028,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c h_next = h + chars_per_column; } } -@@ -1738,9 +1861,9 @@ static void +@@ -1708,9 +1831,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2041,7 +2040,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2011,13 +2134,13 @@ store_char (char c) +@@ -1981,13 +2104,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2057,7 +2056,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c char *s; int num_width; -@@ -2034,22 +2157,24 @@ add_line_number (COLUMN *p) +@@ -2004,22 +2127,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. */ @@ -2086,7 +2085,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2210,7 +2335,7 @@ print_white_space (void) +@@ -2180,7 +2305,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2095,7 +2094,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c h_old = h_new; } while (++h_old <= goal) -@@ -2230,6 +2355,7 @@ print_sep_string (void) +@@ -2200,6 +2325,7 @@ print_sep_string (void) { char *s; int l = col_sep_length; @@ -2103,7 +2102,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c s = col_sep_string; -@@ -2243,6 +2369,7 @@ print_sep_string (void) +@@ -2213,6 +2339,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2111,7 +2110,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2256,12 +2383,15 @@ print_sep_string (void) +@@ -2226,12 +2353,15 @@ print_sep_string (void) } else { @@ -2128,7 +2127,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2289,7 +2419,7 @@ print_clump (COLUMN *p, int n, char *clu +@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu required number of tabs and spaces. */ static void @@ -2137,7 +2136,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c { if (tabify_output) { -@@ -2313,6 +2443,74 @@ print_char (char c) +@@ -2283,6 +2413,74 @@ print_char (char c) putchar (c); } @@ -2212,7 +2211,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2492,9 +2690,9 @@ read_line (COLUMN *p) +@@ -2462,9 +2660,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2224,7 +2223,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2564,7 +2762,7 @@ print_stored (COLUMN *p) +@@ -2534,7 +2732,7 @@ print_stored (COLUMN *p) int i; int line = p->current_line++; @@ -2233,7 +2232,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2576,7 +2774,7 @@ print_stored (COLUMN *p) +@@ -2546,7 +2744,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2242,7 +2241,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c pad_vertically = true; -@@ -2595,9 +2793,9 @@ print_stored (COLUMN *p) +@@ -2565,9 +2763,9 @@ print_stored (COLUMN *p) } } @@ -2254,7 +2253,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c padding_not_printed = ANYWHERE; } -@@ -2610,8 +2808,8 @@ print_stored (COLUMN *p) +@@ -2580,8 +2778,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2265,7 +2264,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c } return true; -@@ -2630,7 +2828,7 @@ print_stored (COLUMN *p) +@@ -2600,7 +2798,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2274,7 +2273,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c { unsigned char uc = c; char *s = clump_buff; -@@ -2640,10 +2838,10 @@ char_to_clump (char c) +@@ -2610,10 +2808,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2287,7 +2286,7 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2724,6 +2922,164 @@ char_to_clump (char c) +@@ -2694,6 +2892,164 @@ char_to_clump (char c) return chars; } @@ -2452,9 +2451,9 @@ diff -urNp coreutils-8.23-orig/src/pr.c coreutils-8.23/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c ---- coreutils-8.23-orig/src/sort.c 2014-07-14 00:09:52.000000000 +0200 -+++ coreutils-8.23/src/sort.c 2014-07-22 13:45:52.719651960 +0200 +diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c +--- coreutils-8.24-orig/src/sort.c 2015-06-26 19:05:22.000000000 +0200 ++++ coreutils-8.24/src/sort.c 2015-07-05 09:04:33.032546980 +0200 @@ -29,6 +29,14 @@ #include #include @@ -2528,7 +2527,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -811,6 +842,46 @@ reap_all (void) +@@ -810,6 +841,46 @@ reap_all (void) reap (-1); } @@ -2575,7 +2574,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1255,7 +1326,7 @@ zaptemp (char const *name) +@@ -1254,7 +1325,7 @@ zaptemp (char const *name) free (node); } @@ -2584,7 +2583,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1270,7 +1341,7 @@ struct_month_cmp (void const *m1, void c +@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c /* Initialize the character class tables. */ static void @@ -2593,7 +2592,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c { size_t i; -@@ -1282,7 +1353,7 @@ inittables (void) +@@ -1281,7 +1352,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2602,7 +2601,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1364,6 +1435,84 @@ specify_nmerge (int oi, char c, char con +@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con xstrtol_fatal (e, oi, c, long_options, s); } @@ -2687,7 +2686,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1597,7 +1746,7 @@ buffer_linelim (struct buffer const *buf +@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf by KEY in LINE. */ static char * @@ -2696,7 +2695,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1606,10 +1755,10 @@ begfield (struct line const *line, struc +@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc /* The leading field separator itself is included in a field when -t is absent. */ @@ -2709,7 +2708,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1635,11 +1784,70 @@ begfield (struct line const *line, struc +@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc return ptr; } @@ -2781,7 +2780,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1654,10 +1862,10 @@ limfield (struct line const *line, struc +@@ -1653,10 +1861,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. */ @@ -2794,7 +2793,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1703,10 +1911,10 @@ limfield (struct line const *line, struc +@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2807,7 +2806,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c if (newlim) lim = newlim; } -@@ -1737,6 +1945,130 @@ limfield (struct line const *line, struc +@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc return ptr; } @@ -2938,7 +2937,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c /* 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 -@@ -1823,8 +2155,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c else { if (key->skipsblanks) @@ -2963,7 +2962,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c line->keybeg = line_start; } } -@@ -1945,7 +2291,7 @@ human_numcompare (char const *a, char co +@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co hideously fast. */ static int @@ -2972,7 +2971,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1955,6 +2301,25 @@ numcompare (char const *a, char const *b +@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2998,7 +2997,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c /* 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 once -@@ -2005,7 +2370,7 @@ general_numcompare (char const *sa, char +@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char Return 0 if the name in S is not recognized. */ static int @@ -3007,7 +3006,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, stru +@@ -2279,15 +2644,14 @@ debug_key (struct line const *line, stru char saved = *lim; *lim = '\0'; @@ -3025,7 +3024,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gke +@@ -2431,7 +2795,7 @@ key_warnings (struct keyfield const *gke bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3034,7 +3033,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gke +@@ -2489,11 +2853,87 @@ key_warnings (struct keyfield const *gke error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -3123,7 +3122,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c { struct keyfield *key = keylist; -@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct +@@ -2578,7 +3018,7 @@ keycompare (struct line const *a, struct else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3132,7 +3131,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2695,6 +3135,209 @@ keycompare (struct line const *a, struct +@@ -2694,6 +3134,209 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3342,7 +3341,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2722,7 +3347,7 @@ compare (struct line const *a, struct li +@@ -2721,7 +3364,7 @@ compare (struct line const *a, struct li diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3351,7 +3350,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c { /* Note xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4121,6 +4746,7 @@ set_ordering (char const *s, struct keyf +@@ -4120,6 +4763,7 @@ set_ordering (char const *s, struct keyf break; case 'f': key->translate = fold_toupper; @@ -3359,7 +3358,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c break; case 'g': key->general_numeric = true; -@@ -4198,7 +4824,7 @@ main (int argc, char **argv) +@@ -4197,7 +4841,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3368,7 +3367,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4219,6 +4845,29 @@ main (int argc, char **argv) +@@ -4218,6 +4862,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3398,7 +3397,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c have_read_stdin = false; inittables (); -@@ -4493,13 +5142,34 @@ main (int argc, char **argv) +@@ -4492,13 +5159,34 @@ main (int argc, char **argv) case 't': { @@ -3437,7 +3436,7 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4510,9 +5180,12 @@ main (int argc, char **argv) +@@ -4509,9 +5197,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3452,42 +3451,9 @@ diff -urNp coreutils-8.23-orig/src/sort.c coreutils-8.23/src/sort.c } break; -diff -urNp coreutils-8.23-orig/tests/i18n/sort.sh coreutils-8.23/tests/i18n/sort.sh ---- coreutils-8.23-orig/tests/i18n/sort.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.23/tests/i18n/sort.sh 2014-07-22 13:45:52.733652016 +0200 -@@ -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 -diff -urNp coreutils-8.23-orig/src/unexpand.c coreutils-8.23/src/unexpand.c ---- coreutils-8.23-orig/src/unexpand.c 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/src/unexpand.c 2014-07-22 13:45:52.721651968 +0200 +diff -urNp coreutils-8.24-orig/src/unexpand.c coreutils-8.24/src/unexpand.c +--- coreutils-8.24-orig/src/unexpand.c 2015-06-26 19:05:22.000000000 +0200 ++++ coreutils-8.24/src/unexpand.c 2015-07-05 09:04:33.032546980 +0200 @@ -38,12 +38,29 @@ #include #include @@ -3743,9 +3709,9 @@ diff -urNp coreutils-8.23-orig/src/unexpand.c coreutils-8.23/src/unexpand.c if (have_read_stdin && fclose (stdin) != 0) error (EXIT_FAILURE, errno, "-"); -diff -urNp coreutils-8.23-orig/src/uniq.c coreutils-8.23/src/uniq.c ---- coreutils-8.23-orig/src/uniq.c 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/src/uniq.c 2014-07-22 13:45:52.724651980 +0200 +diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c +--- coreutils-8.24-orig/src/uniq.c 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/src/uniq.c 2015-07-05 09:04:33.032546980 +0200 @@ -21,6 +21,17 @@ #include #include @@ -3898,7 +3864,7 @@ diff -urNp coreutils-8.23-orig/src/uniq.c coreutils-8.23/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -286,14 +392,103 @@ different (char *old, char *new, size_t +@@ -286,15 +392,104 @@ different (char *old, char *new, size_t if (ignore_case) { @@ -3930,8 +3896,8 @@ diff -urNp coreutils-8.23-orig/src/uniq.c coreutils-8.23/src/uniq.c + + return xmemcoll (copy_old, oldlen, copy_new, newlen); + -+} -+ + } + +#if HAVE_MBRTOWC +static int +different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) @@ -4002,11 +3968,12 @@ diff -urNp coreutils-8.23-orig/src/uniq.c coreutils-8.23/src/uniq.c + free (copy[1]); + return rc; + - } ++} +#endif - ++ /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. + MATCH is true if the line matches the previous line. @@ -358,19 +553,38 @@ check_file (const char *infile, const ch char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); @@ -4129,10 +4096,43 @@ diff -urNp coreutils-8.23-orig/src/uniq.c coreutils-8.23/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.23-orig/tests/local.mk coreutils-8.23/tests/local.mk ---- coreutils-8.23-orig/tests/local.mk 2014-07-22 13:45:10.494422571 +0200 -+++ coreutils-8.23/tests/local.mk 2014-07-22 13:45:52.726651988 +0200 -@@ -331,6 +331,8 @@ all_tests = \ +diff -urNp coreutils-8.24-orig/tests/i18n/sort.sh coreutils-8.24/tests/i18n/sort.sh +--- coreutils-8.24-orig/tests/i18n/sort.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.24/tests/i18n/sort.sh 2015-07-05 09:04:33.032546980 +0200 +@@ -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 +diff -urNp coreutils-8.24-orig/tests/local.mk coreutils-8.24/tests/local.mk +--- coreutils-8.24-orig/tests/local.mk 2015-07-05 09:00:46.526859558 +0200 ++++ coreutils-8.24/tests/local.mk 2015-07-05 09:04:33.033546987 +0200 +@@ -341,6 +341,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -4141,9 +4141,9 @@ diff -urNp coreutils-8.23-orig/tests/local.mk coreutils-8.23/tests/local.mk tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ tests/misc/sort-month.sh \ -diff -urNp coreutils-8.23-orig/tests/misc/cut.pl coreutils-8.23/tests/misc/cut.pl ---- coreutils-8.23-orig/tests/misc/cut.pl 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/tests/misc/cut.pl 2014-07-22 13:45:52.728651996 +0200 +diff -urNp coreutils-8.24-orig/tests/misc/cut.pl coreutils-8.24/tests/misc/cut.pl +--- coreutils-8.24-orig/tests/misc/cut.pl 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/tests/misc/cut.pl 2015-07-05 09:04:33.033546987 +0200 @@ -23,9 +23,11 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4166,9 +4166,9 @@ diff -urNp coreutils-8.23-orig/tests/misc/cut.pl coreutils-8.23/tests/misc/cut.p push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; } push @Tests, @new; -diff -urNp coreutils-8.23-orig/tests/misc/expand.pl coreutils-8.23/tests/misc/expand.pl ---- coreutils-8.23-orig/tests/misc/expand.pl 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/tests/misc/expand.pl 2014-07-22 13:45:52.729652000 +0200 +diff -urNp coreutils-8.24-orig/tests/misc/expand.pl coreutils-8.24/tests/misc/expand.pl +--- coreutils-8.24-orig/tests/misc/expand.pl 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/tests/misc/expand.pl 2015-07-05 09:04:33.033546987 +0200 @@ -23,6 +23,15 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4223,9 +4223,9 @@ diff -urNp coreutils-8.23-orig/tests/misc/expand.pl coreutils-8.23/tests/misc/ex my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.23-orig/tests/misc/fold.pl coreutils-8.23/tests/misc/fold.pl ---- coreutils-8.23-orig/tests/misc/fold.pl 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/tests/misc/fold.pl 2014-07-22 13:45:52.730652004 +0200 +diff -urNp coreutils-8.24-orig/tests/misc/fold.pl coreutils-8.24/tests/misc/fold.pl +--- coreutils-8.24-orig/tests/misc/fold.pl 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/tests/misc/fold.pl 2015-07-05 09:04:33.033546987 +0200 @@ -20,9 +20,18 @@ use strict; (my $program_name = $0) =~ s|.*/||; @@ -4295,9 +4295,9 @@ diff -urNp coreutils-8.23-orig/tests/misc/fold.pl coreutils-8.23/tests/misc/fold -my $prog = 'fold'; my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; -diff -urNp coreutils-8.23-orig/tests/misc/join.pl coreutils-8.23/tests/misc/join.pl ---- coreutils-8.23-orig/tests/misc/join.pl 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/tests/misc/join.pl 2014-07-22 13:45:52.731652008 +0200 +diff -urNp coreutils-8.24-orig/tests/misc/join.pl coreutils-8.24/tests/misc/join.pl +--- coreutils-8.24-orig/tests/misc/join.pl 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/tests/misc/join.pl 2015-07-05 09:04:33.033546987 +0200 @@ -25,6 +25,15 @@ my $limits = getlimits (); my $prog = 'join'; @@ -4364,9 +4364,9 @@ diff -urNp coreutils-8.23-orig/tests/misc/join.pl coreutils-8.23/tests/misc/join my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.23-orig/tests/misc/sort-mb-tests.sh coreutils-8.23/tests/misc/sort-mb-tests.sh ---- coreutils-8.23-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.23/tests/misc/sort-mb-tests.sh 2014-07-22 13:45:52.733652016 +0200 +diff -urNp coreutils-8.24-orig/tests/misc/sort-mb-tests.sh coreutils-8.24/tests/misc/sort-mb-tests.sh +--- coreutils-8.24-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 ++++ coreutils-8.24/tests/misc/sort-mb-tests.sh 2015-07-05 09:04:33.034546995 +0200 @@ -0,0 +1,45 @@ +#!/bin/sh +# Verify sort's multi-byte support. @@ -4413,9 +4413,9 @@ diff -urNp coreutils-8.23-orig/tests/misc/sort-mb-tests.sh coreutils-8.23/tests/ +compare exp out || { fail=1; cat out; } + +Exit $fail -diff -urNp coreutils-8.23-orig/tests/misc/sort-merge.pl coreutils-8.23/tests/misc/sort-merge.pl ---- coreutils-8.23-orig/tests/misc/sort-merge.pl 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/tests/misc/sort-merge.pl 2014-07-22 13:45:52.733652016 +0200 +diff -urNp coreutils-8.24-orig/tests/misc/sort-merge.pl coreutils-8.24/tests/misc/sort-merge.pl +--- coreutils-8.24-orig/tests/misc/sort-merge.pl 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/tests/misc/sort-merge.pl 2015-07-05 09:04:33.034546995 +0200 @@ -26,6 +26,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4472,9 +4472,9 @@ diff -urNp coreutils-8.23-orig/tests/misc/sort-merge.pl coreutils-8.23/tests/mis my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.23-orig/tests/misc/sort.pl coreutils-8.23/tests/misc/sort.pl ---- coreutils-8.23-orig/tests/misc/sort.pl 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/tests/misc/sort.pl 2014-07-22 13:45:52.734652020 +0200 +diff -urNp coreutils-8.24-orig/tests/misc/sort.pl coreutils-8.24/tests/misc/sort.pl +--- coreutils-8.24-orig/tests/misc/sort.pl 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/tests/misc/sort.pl 2015-07-05 09:04:33.034546995 +0200 @@ -24,10 +24,15 @@ my $prog = 'sort'; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -4492,18 +4492,7 @@ diff -urNp coreutils-8.23-orig/tests/misc/sort.pl coreutils-8.23/tests/misc/sort # 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 '-'. -@@ -317,6 +322,10 @@ my @Tests = - ["22a", '-k 2,2fd -k 1,1r', {IN=>"3 b\n4 B\n"}, {OUT=>"4 B\n3 b\n"}], - ["22b", '-k 2,2d -k 1,1r', {IN=>"3 b\n4 b\n"}, {OUT=>"4 b\n3 b\n"}], - -+# This fails in Fedora 20, per Göran Uddeborg in: http://bugs.gnu.org/18540 -+["23", '-s -k1,1 -t/', {IN=>"a b/x\na-b-c/x\n"}, {OUT=>"a b/x\na-b-c/x\n"}, -+ {ENV => "LC_ALL=$mb_locale"}], -+ - ["no-file1", 'no-file', {EXIT=>2}, {ERR=>$no_file}], - # This test failed until 1.22f. Sort didn't give an error. - # From Will Edgington. -@@ -415,6 +420,38 @@ foreach my $t (@Tests) +@@ -419,6 +428,38 @@ foreach my $t (@Tests) } } @@ -4542,7 +4531,7 @@ diff -urNp coreutils-8.23-orig/tests/misc/sort.pl coreutils-8.23/tests/misc/sort @Tests = triple_test \@Tests; # Remember that triple_test creates from each test with exactly one "IN" -@@ -424,6 +460,7 @@ foreach my $t (@Tests) +@@ -428,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; @@ -4550,9 +4539,9 @@ diff -urNp coreutils-8.23-orig/tests/misc/sort.pl coreutils-8.23/tests/misc/sort my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.23-orig/tests/misc/unexpand.pl coreutils-8.23/tests/misc/unexpand.pl ---- coreutils-8.23-orig/tests/misc/unexpand.pl 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/tests/misc/unexpand.pl 2014-07-22 13:45:52.735652024 +0200 +diff -urNp coreutils-8.24-orig/tests/misc/unexpand.pl coreutils-8.24/tests/misc/unexpand.pl +--- coreutils-8.24-orig/tests/misc/unexpand.pl 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/tests/misc/unexpand.pl 2015-07-05 09:04:33.034546995 +0200 @@ -27,6 +27,14 @@ my $limits = getlimits (); my $prog = 'unexpand'; @@ -4606,9 +4595,9 @@ diff -urNp coreutils-8.23-orig/tests/misc/unexpand.pl coreutils-8.23/tests/misc/ my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.23-orig/tests/misc/uniq.pl coreutils-8.23/tests/misc/uniq.pl ---- coreutils-8.23-orig/tests/misc/uniq.pl 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/tests/misc/uniq.pl 2014-07-22 13:45:52.736652028 +0200 +diff -urNp coreutils-8.24-orig/tests/misc/uniq.pl coreutils-8.24/tests/misc/uniq.pl +--- coreutils-8.24-orig/tests/misc/uniq.pl 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/tests/misc/uniq.pl 2015-07-05 09:04:33.035547002 +0200 @@ -23,9 +23,17 @@ my $limits = getlimits (); my $prog = 'uniq'; my $try = "Try '$prog --help' for more information.\n"; @@ -4681,12 +4670,12 @@ diff -urNp coreutils-8.23-orig/tests/misc/uniq.pl coreutils-8.23/tests/misc/uniq @Tests = add_z_variants \@Tests; @Tests = triple_test \@Tests; -diff -urNp coreutils-8.23-orig/tests/pr/pr-tests.pl coreutils-8.23/tests/pr/pr-tests.pl ---- coreutils-8.23-orig/tests/pr/pr-tests.pl 2014-07-11 13:00:07.000000000 +0200 -+++ coreutils-8.23/tests/pr/pr-tests.pl 2014-07-22 13:45:52.737652032 +0200 -@@ -23,6 +23,15 @@ use strict; - +diff -urNp coreutils-8.24-orig/tests/pr/pr-tests.pl coreutils-8.24/tests/pr/pr-tests.pl +--- coreutils-8.24-orig/tests/pr/pr-tests.pl 2015-06-26 19:04:19.000000000 +0200 ++++ coreutils-8.24/tests/pr/pr-tests.pl 2015-07-05 09:04:33.035547002 +0200 +@@ -24,6 +24,15 @@ use strict; my $prog = 'pr'; + my $normalize_strerror = "s/': .*/'/"; +my $mb_locale; +#Uncomment the following line to enable multibyte tests @@ -4700,7 +4689,7 @@ diff -urNp coreutils-8.23-orig/tests/pr/pr-tests.pl coreutils-8.23/tests/pr/pr-t my @tv = ( # -b option is no longer an official option. But it's still working to -@@ -466,8 +475,48 @@ push @Tests, +@@ -467,8 +476,48 @@ push @Tests, {IN=>{3=>"x\ty\tz\n"}}, {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ]; diff --git a/coreutils.spec b/coreutils.spec index b6b6450..754ef3d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.23 -Release: 14%{?dist} +Version: 8.24 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -14,7 +14,6 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream -Patch1: coreutils-8.23-chroot-chdir.patch # Our patches #general patch to workaround koji build system issues @@ -125,8 +124,6 @@ the old GNU fileutils, sh-utils, and textutils packages. %prep %setup -q -%patch1 -p1 -b .chdir - # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages @@ -376,6 +373,9 @@ fi %{_sbindir}/chroot %changelog +* Sun Jul 05 2015 Ondrej Vasik 8.24-1 +- new upstream release 8.24 + * Sat Jul 4 2015 Peter Robinson 8.23-14 - Disable failing test-update-copyright to fix FTBFS diff --git a/sources b/sources index b5d101f..c53a0ef 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -abed135279f87ad6762ce57ff6d89c41 coreutils-8.23.tar.xz -f93deb9f48c2bc7236743a10bf1c2409 coreutils-8.23.tar.xz.sig +40efdbce865d2458d8da0a9dcee7c16c coreutils-8.24.tar.xz +01b4406a1de25aa4af49b9c4b0057c19 coreutils-8.24.tar.xz.sig From 7b7a0554fba4e0f40682c1116e6acea336d27558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Thu, 16 Jul 2015 10:35:36 +0200 Subject: [PATCH 276/523] use newer version of sort/I18N fix for CVE-2015-4041 and CVE-2015-4042 --- coreutils-i18n.patch | 6 ++++-- coreutils.spec | 6 +++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index d1d18a8..8589d74 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -3131,7 +3131,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2694,6 +3134,209 @@ keycompare (struct line const *a, struct +@@ -2694,6 +3134,211 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3244,7 +3244,9 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c + + if (ignore || translate) + { -+ char *copy_a = (char *) xmalloc ((lena + lenb) * MB_CUR_MAX + 2); ++ 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; diff --git a/coreutils.spec b/coreutils.spec index 754ef3d..c4e1341 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -373,6 +373,10 @@ fi %{_sbindir}/chroot %changelog +* Thu Jul 16 2015 Ondrej Vasik 8.24-2 +- use newer version of sort/I18N fix for CVE-2015-4041 + and CVE-2015-4042 + * Sun Jul 05 2015 Ondrej Vasik 8.24-1 - new upstream release 8.24 From cfbfd8c4908e28c178eabff5c896e332f8789b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Tue, 1 Sep 2015 17:32:54 +0100 Subject: [PATCH 277/523] avoid check failure on glibc 2.22 glibc 2.22 introduces two extra stat() calls per opendir(), which induces a false failure in a test counting stat() calls. --- coreutils.spec | 3 ++ glibc-2.22-test-fix.patch | 83 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 glibc-2.22-test-fix.patch diff --git a/coreutils.spec b/coreutils.spec index c4e1341..deac632 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -30,6 +30,8 @@ Patch104: coreutils-df-direct.patch Patch107: coreutils-8.4-mkdir-modenote.patch # Don't run the currently failing test-update-copyright.sh test Patch108: coreutils-remove-test-update-copyright.patch +#avoid false failure due to extra stat() calls done by opendir() in glibc 2.22 +Patch109: glibc-2.22-test-fix.patch # sh-utils #add info about TZ envvar to date manpage @@ -132,6 +134,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch104 -p1 -b .dfdirect %patch107 -p1 -b .mkdirmode %patch108 -p1 -b .crtest +%patch109 -p1 -b .opendir_stat # sh-utils %patch703 -p1 -b .dateman diff --git a/glibc-2.22-test-fix.patch b/glibc-2.22-test-fix.patch new file mode 100644 index 0000000..efbe850 --- /dev/null +++ b/glibc-2.22-test-fix.patch @@ -0,0 +1,83 @@ +From fd5f2b1569e2e0b31be755e14e236a7a02478fc0 Mon Sep 17 00:00:00 2001 +From: Bernhard Voelker +Date: Sun, 30 Aug 2015 22:49:35 +0200 +Subject: [PATCH] tests: avoid FP of ls/stat-free-color.sh with newer glibc + +Since glibc-2.22, specifically commit [0], the opendir() implementation +implicitly makes an additional stat call thus leading to a FP. +Seen on openSUSE:Tumbleweed since snapshot 20150821. + +[0] +https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=46f894d8c60a + +* tests/ls/stat-free-color.sh: Change the test to verify that ls(1) +needs the same number of stat-like calls for a single, empty directory +argument as for one with a few directory entries (sub-directory, +regular file, symlink, etc.). +--- + tests/ls/stat-free-color.sh | 39 ++++++++++++++++++++++++--------------- + 1 file changed, 24 insertions(+), 15 deletions(-) + +diff --git a/tests/ls/stat-free-color.sh b/tests/ls/stat-free-color.sh +index fb2ee8b..35816a3 100755 +--- a/tests/ls/stat-free-color.sh ++++ b/tests/ls/stat-free-color.sh +@@ -27,8 +27,6 @@ stats='stat,lstat,stat64,lstat64,newfstatat' + require_strace_ $stats + require_dirent_d_type_ + +-ln -s nowhere dangle || framework_failure_ +- + # Disable enough features via LS_COLORS so that ls --color + # can do its job without calling stat (other than the obligatory + # one-call-per-command-line argument). +@@ -54,22 +52,33 @@ EOF + eval $(dircolors -b color-without-stat) + + # The system may perform additional stat-like calls before main. +-# To avoid counting those, first get a baseline count by running +-# ls with only the --help option. Then, compare that with the ++# Furthermore, underlying library functions may also implicitly ++# add an extra stat call, e.g. opendir since glibc-2.21-360-g46f894d. ++# To avoid counting those, first get a baseline count for running ++# ls with one empty directory argument. Then, compare that with the + # invocation under test. +-strace -o log-help -e $stats ls --help >/dev/null || fail=1 +-n_lines_help=$(wc -l < log-help) ++mkdir d || framework_failure_ ++ ++strace -o log1 -e $stats ls --color=always d || fail=1 ++n_stat1=$(wc -l < log1) || framework_failure_ ++ ++test $n_stat1 = 0 \ ++ && skip_ 'No stat calls recognized on this platform' + +-strace -o log -e $stats ls --color=always . || fail=1 +-n_lines=$(wc -l < log) ++# Populate the test directory. ++mkdir d/subdir \ ++ && touch d/regf \ ++ && ln d/regf d/hlink \ ++ && ln -s regf d/slink \ ++ && ln -s nowhere d/dangle \ ++ || framework_failure_ + +-n_stat=$(expr $n_lines - $n_lines_help) ++# Invocation under test. ++strace -o log2 -e $stats ls --color=always d || fail=1 ++n_stat2=$(wc -l < log2) || framework_failure_ + +-# Expect one stat call. +-case $n_stat in +- 0) skip_ 'No stat calls recognized on this platform' ;; +- 1) ;; # Corresponding to stat(".") +- *) fail=1; head -n30 log* ;; +-esac ++# Expect the same number of stat calls. ++test $n_stat1 = $n_stat2 \ ++ || { fail=1; head -n30 log*; } + + Exit $fail +-- +2.4.1 + From 2ad92d25c004ced89a89955a0568d07b0169656d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 12 Sep 2015 08:00:58 +0200 Subject: [PATCH 278/523] fix one still existing occurance of non-full path in colorls.sh --- coreutils-colorls.sh | 2 +- coreutils.spec | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index c3f6a43..cfd2288 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -47,7 +47,7 @@ if [ -z "$USER_LS_COLORS" ]; then fi [ -z "$LS_COLORS" ] && return - grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return + /usr/bin/grep -qi "^COLOR.*none" $COLORS >/dev/null 2>/dev/null && return fi unset TMP COLORS INCLUDE diff --git a/coreutils.spec b/coreutils.spec index deac632..5db34fe 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -376,6 +376,9 @@ fi %{_sbindir}/chroot %changelog +* Sat Sep 12 2015 Ondrej Vasik 8.24-3 +- fix one still existing occurance of non-full path in colorls.sh + * Thu Jul 16 2015 Ondrej Vasik 8.24-2 - use newer version of sort/I18N fix for CVE-2015-4041 and CVE-2015-4042 From c7c3ee3fabb7b48c6545383e4b2da07e661d0007 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 16 Sep 2015 19:58:21 +0200 Subject: [PATCH 279/523] Resolves: #1259942 - fix memory leak in sort/I18N MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patches written by Pádraig. Note that the corresponding i18n/sort-month test was not included because it breaks unless sort is compiled -Dlint and we do not want to decrease performance of the resulting RPMs (and valgrind is not installed in production buildroots anyway). --- coreutils-i18n.patch | 65 +++++++++++++++++++++++++++++++------------- coreutils.spec | 5 +++- 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 8589d74..f823a40 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -3046,8 +3046,8 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c + register int lo = 0, hi = MONTHS_PER_YEAR, result; + char *tmp; + size_t wclength, mblength; -+ const char **pp; -+ const wchar_t **wpp; ++ const char *pp; ++ const wchar_t *wpp; + wchar_t *month_wcs; + mbstate_t state; + @@ -3060,17 +3060,19 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c + if (len == 0) + return 0; + -+ month = (char *) xmalloc (len + 1); ++ if (SIZE_MAX - len < 1) ++ xalloc_die (); + -+ tmp = (char *) xmalloc (len + 1); ++ month = (char *) xnmalloc (len + 1, MB_CUR_MAX); ++ ++ pp = tmp = (char *) xnmalloc (len + 1, MB_CUR_MAX); + memcpy (tmp, s, len); + tmp[len] = '\0'; -+ pp = (const char **)&tmp; -+ month_wcs = (wchar_t *) xmalloc ((len + 1) * sizeof (wchar_t)); -+ memset (&state, '\0', sizeof(mbstate_t)); ++ 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) ++ 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++) @@ -3083,10 +3085,8 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c + } + } + -+ wpp = (const wchar_t **)&month_wcs; -+ -+ mblength = wcsrtombs (month, wpp, len + 1, &state); -+ assert (mblength != (-1) && *wpp == NULL); ++ mblength = wcsrtombs (month, &wpp, (len + 1) * MB_CUR_MAX, &state); ++ assert (mblength != (-1) && wpp == NULL); + + do + { @@ -3343,7 +3343,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2721,7 +3364,7 @@ compare (struct line const *a, struct li +@@ -2721,7 +3366,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3352,7 +3352,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { /* Note xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4120,6 +4763,7 @@ set_ordering (char const *s, struct keyf +@@ -4120,6 +4765,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3360,7 +3360,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c break; case 'g': key->general_numeric = true; -@@ -4197,7 +4841,7 @@ main (int argc, char **argv) +@@ -4197,7 +4843,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3369,7 +3369,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4218,6 +4862,29 @@ main (int argc, char **argv) +@@ -4218,6 +4864,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3399,7 +3399,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c have_read_stdin = false; inittables (); -@@ -4492,13 +5159,34 @@ main (int argc, char **argv) +@@ -4492,13 +5161,34 @@ main (int argc, char **argv) case 't': { @@ -3438,7 +3438,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4509,9 +5197,12 @@ main (int argc, char **argv) +@@ -4509,9 +5199,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3453,6 +3453,33 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c } break; +@@ -4681,10 +5374,10 @@ main (int argc, char **argv) + + if (nfiles == 0) + { +- static char *minus = (char *) "-"; + nfiles = 1; + free (files); +- files = − ++ files = xmalloc (sizeof *files); ++ *files = (char *) "-"; + } + + /* Need to re-check that we meet the minimum requirement for memory +@@ -4742,6 +5435,13 @@ 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) + die (_("close failed"), "-"); + diff -urNp coreutils-8.24-orig/src/unexpand.c coreutils-8.24/src/unexpand.c --- coreutils-8.24-orig/src/unexpand.c 2015-06-26 19:05:22.000000000 +0200 +++ coreutils-8.24/src/unexpand.c 2015-07-05 09:04:33.032546980 +0200 diff --git a/coreutils.spec b/coreutils.spec index 5db34fe..20cdfe6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -376,6 +376,9 @@ fi %{_sbindir}/chroot %changelog +* Wed Sep 16 2015 Kamil Dudka - 8.24-4 +- fix memory leak in sort/I18N (patches written by Pádraig, #1259942) + * Sat Sep 12 2015 Ondrej Vasik 8.24-3 - fix one still existing occurance of non-full path in colorls.sh From f0951fecacb45c1c922337164533bba10a1c0477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Tue, 17 Nov 2015 23:58:22 +0000 Subject: [PATCH 280/523] clean stale parts of the spec file --- coreutils.spec | 126 +++++------------------------------------------- supported_utils | 102 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 115 deletions(-) create mode 100644 supported_utils diff --git a/coreutils.spec b/coreutils.spec index 20cdfe6..b82655e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -7,6 +7,7 @@ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source2: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig +Source50: supported_utils Source101: coreutils-DIR_COLORS Source102: coreutils-DIR_COLORS.lightbgcolor Source103: coreutils-DIR_COLORS.256color @@ -152,7 +153,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh tests/cp/no-ctx.sh || : +chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh || : #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -167,19 +168,16 @@ touch aclocal.m4 configure config.hin Makefile.in */Makefile.in aclocal -I m4 autoconf --force automake --copy --add-missing -%configure --enable-largefile \ +%configure --enable-install-program=arch \ + --enable-no-install-program=uptime \ --with-openssl \ - --enable-install-program=hostname,arch \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : -# Regenerate manpages -touch man/*.x - make all %{?_smp_mflags} -# XXX docs should say /var/run/[uw]tmp not /etc/[uw]tmp -sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi +# Get the list of supported utilities +cp %SOURCE50 . %check make check %{?_smp_mflags} @@ -187,9 +185,6 @@ make check %{?_smp_mflags} %install make DESTDIR=$RPM_BUILD_ROOT install -# man pages are not installed with make install -make mandir=$RPM_BUILD_ROOT%{_mandir} install-man - # fix japanese catalog file if [ -d $RPM_BUILD_ROOT%{_datadir}/locale/ja_JP.EUC/LC_MESSAGES ]; then mkdir -p $RPM_BUILD_ROOT%{_datadir}/locale/ja/LC_MESSAGES @@ -214,7 +209,10 @@ install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.s install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh # These come from util-linux and/or procps. -for i in hostname uptime kill ; do +# With coreutils > 8.24 one can just add to --enable-no-install-program +# rather than manually removing here, since tests depending on +# built utilities are correctly skipped if not present. +for i in kill ; do rm $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1} done @@ -262,118 +260,16 @@ if [ -f %{_infodir}/%{name}.info.gz ]; then /sbin/install-info %{_infodir}/%{name}.info.gz %{_infodir}/dir || : fi -%files -f %{name}.lang +%files -f %{name}.lang -f supported_utils %defattr(-,root,root,-) %config(noreplace) %{_sysconfdir}/DIR_COLORS* %config(noreplace) %{_sysconfdir}/profile.d/* %doc ABOUT-NLS NEWS README THANKS TODO %{!?_licensedir:%global license %%doc} %license COPYING -%{_bindir}/arch -%{_bindir}/basename -%{_bindir}/cat -%{_bindir}/chgrp -%{_bindir}/chmod -%{_bindir}/chown -%{_bindir}/cp -%{_bindir}/cut -%{_bindir}/date -%{_bindir}/dd -%{_bindir}/df -%{_bindir}/echo -%{_bindir}/env -%{_bindir}/false -%{_bindir}/link -%{_bindir}/ln -%{_bindir}/ls -%{_bindir}/mkdir -%{_bindir}/mknod -%{_bindir}/mv -%{_bindir}/nice -%{_bindir}/pwd -%{_bindir}/readlink -%{_bindir}/rm -%{_bindir}/rmdir -%{_bindir}/sleep -%{_bindir}/sort -%{_bindir}/stty -%{_bindir}/sync -%{_bindir}/mktemp -%{_bindir}/touch -%{_bindir}/true -%{_bindir}/uname -%{_bindir}/unlink -%{_bindir}/[ -%{_bindir}/base64 -%{_bindir}/chcon -%{_bindir}/cksum -%{_bindir}/comm -%{_bindir}/csplit -%{_bindir}/dir -%{_bindir}/dircolors -%{_bindir}/dirname -%{_bindir}/du -%{_bindir}/expand -%{_bindir}/expr -%{_bindir}/factor -%{_bindir}/fmt -%{_bindir}/fold -%{_bindir}/groups -%{_bindir}/head -%{_bindir}/hostid -%{_bindir}/id -%{_bindir}/install -%{_bindir}/join -%{_bindir}/logname -%{_bindir}/md5sum -%{_bindir}/mkfifo -%{_bindir}/nl -%{_bindir}/nohup -%{_bindir}/nproc -%{_bindir}/numfmt -%{_bindir}/od -%{_bindir}/paste -%{_bindir}/pathchk -%{_bindir}/pinky -%{_bindir}/pr -%{_bindir}/printenv -%{_bindir}/printf -%{_bindir}/ptx -%{_bindir}/realpath -%{_bindir}/runcon -%{_bindir}/seq -%{_bindir}/sha1sum -%{_bindir}/sha224sum -%{_bindir}/sha256sum -%{_bindir}/sha384sum -%{_bindir}/sha512sum -%{_bindir}/shred -%{_bindir}/shuf -%{_bindir}/split -%{_bindir}/stat -%{_bindir}/stdbuf -%{_bindir}/sum -%{_bindir}/tac -%{_bindir}/tail -%{_bindir}/tee -%{_bindir}/test -%{_bindir}/timeout -%{_bindir}/tr -%{_bindir}/truncate -%{_bindir}/tsort -%{_bindir}/tty -%{_bindir}/unexpand -%{_bindir}/uniq -%{_bindir}/users -%{_bindir}/vdir -%{_bindir}/wc -%{_bindir}/who -%{_bindir}/whoami -%{_bindir}/yes %{_infodir}/coreutils* %{_libexecdir}/coreutils* %{_mandir}/man*/* -%{_sbindir}/chroot %changelog * Wed Sep 16 2015 Kamil Dudka - 8.24-4 diff --git a/supported_utils b/supported_utils new file mode 100644 index 0000000..124e14c --- /dev/null +++ b/supported_utils @@ -0,0 +1,102 @@ +%{_bindir}/arch +%{_bindir}/basename +%{_bindir}/cat +%{_bindir}/chgrp +%{_bindir}/chmod +%{_bindir}/chown +%{_bindir}/cp +%{_bindir}/cut +%{_bindir}/date +%{_bindir}/dd +%{_bindir}/df +%{_bindir}/echo +%{_bindir}/env +%{_bindir}/false +%{_bindir}/link +%{_bindir}/ln +%{_bindir}/ls +%{_bindir}/mkdir +%{_bindir}/mknod +%{_bindir}/mv +%{_bindir}/nice +%{_bindir}/pwd +%{_bindir}/readlink +%{_bindir}/rm +%{_bindir}/rmdir +%{_bindir}/sleep +%{_bindir}/sort +%{_bindir}/stty +%{_bindir}/sync +%{_bindir}/mktemp +%{_bindir}/touch +%{_bindir}/true +%{_bindir}/uname +%{_bindir}/unlink +%{_bindir}/[ +%{_bindir}/base64 +%{_bindir}/chcon +%{_bindir}/cksum +%{_bindir}/comm +%{_bindir}/csplit +%{_bindir}/dir +%{_bindir}/dircolors +%{_bindir}/dirname +%{_bindir}/du +%{_bindir}/expand +%{_bindir}/expr +%{_bindir}/factor +%{_bindir}/fmt +%{_bindir}/fold +%{_bindir}/groups +%{_bindir}/head +%{_bindir}/hostid +%{_bindir}/id +%{_bindir}/install +%{_bindir}/join +%{_bindir}/logname +%{_bindir}/md5sum +%{_bindir}/mkfifo +%{_bindir}/nl +%{_bindir}/nohup +%{_bindir}/nproc +%{_bindir}/numfmt +%{_bindir}/od +%{_bindir}/paste +%{_bindir}/pathchk +%{_bindir}/pinky +%{_bindir}/pr +%{_bindir}/printenv +%{_bindir}/printf +%{_bindir}/ptx +%{_bindir}/realpath +%{_bindir}/runcon +%{_bindir}/seq +%{_bindir}/sha1sum +%{_bindir}/sha224sum +%{_bindir}/sha256sum +%{_bindir}/sha384sum +%{_bindir}/sha512sum +%{_bindir}/shred +%{_bindir}/shuf +%{_bindir}/split +%{_bindir}/stat +%{_bindir}/stdbuf +%{_bindir}/sum +%{_bindir}/tac +%{_bindir}/tail +%{_bindir}/tee +%{_bindir}/test +%{_bindir}/timeout +%{_bindir}/tr +%{_bindir}/truncate +%{_bindir}/tsort +%{_bindir}/tty +%{_bindir}/unexpand +%{_bindir}/uniq +%{_bindir}/users +%{_bindir}/vdir +%{_bindir}/wc +%{_bindir}/who +%{_bindir}/whoami +%{_bindir}/yes +%{_sbindir}/chroot From 5fb9bc4700bb2ae5e109805e3a0af8796c12904e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Thu, 19 Nov 2015 15:28:04 +0000 Subject: [PATCH 281/523] split package and provide coreutils-single Notes about coreutils: - Drops from 14.2MB to 5.5MB. - Still requires coreutils-common, though being separated allows for easier removal if required. - Explicitly conflicts with coreutils-single to avoid errant installs Notes about coreutils-single: - Contains a single multicall binary which is 1.2MB - Have to force install over any existing coreutils package so best used for initial install without existing coreutils package - Doesn't require (but suggests) coreutils-common so install that manually for docs, translations, and colors etc. Notes about coreutils-common: - 8.7MB - Having this split out gives an easy way to remove all docs and translations. Note RemovePathPostfixes: introduced with rpm 4.13 is used to facilitate producing the two sets of conflicting binaries from the same build, while maintaining appropriate --fileprovide in each generated rpm. --- coreutils.spec | 108 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 19 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index b82655e..736b002 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 4%{?dist} +Release: 100%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -55,6 +55,8 @@ Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch Conflicts: filesystem < 3 +# To avoid clobbering installs during %post +Conflicts: coreutils-single Provides: /bin/basename Provides: /bin/cat Provides: /bin/chgrp @@ -100,6 +102,7 @@ BuildRequires: gmp-devel BuildRequires: attr BuildRequires: strace +Requires: %{name}-common = %{version}-%{release} Requires(pre): /sbin/install-info Requires(preun): /sbin/install-info Requires(post): /sbin/install-info @@ -119,11 +122,36 @@ Obsoletes: fileutils <= 4.1.9 Obsoletes: sh-utils <= 2.0.12 Obsoletes: stat <= 3.3 Obsoletes: textutils <= 2.0.21 +Obsoletes: %{name} < 8.24-100 %description These are the GNU core utilities. This package is the combination of the old GNU fileutils, sh-utils, and textutils packages. +%package single +Summary: coreutils multicall binary +Suggests: coreutils-common +Provides: coreutils +# To avoid clobbering installs during %post +Conflicts: coreutils < 8.24-100 +# Note RPM doesn't support separate buildroots for %files +# http://rpm.org/ticket/874 so use RemovePathPostfixes +# (new in rpm 4.13) to support separate file sets. +RemovePathPostfixes: .single +%description single +These are the GNU core utilities, +packaged as a single multicall binary. + + +%package common +# yum obsoleting rules explained at: +# https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 +Obsoletes: %{name} < 8.24-100 +Summary: coreutils common optional components +%description common +Optional though recommended components, +including documentation and translations. + %prep %setup -q @@ -168,22 +196,53 @@ touch aclocal.m4 configure config.hin Makefile.in */Makefile.in aclocal -I m4 autoconf --force automake --copy --add-missing -%configure --enable-install-program=arch \ - --enable-no-install-program=uptime \ - --with-openssl \ - --with-tty-group \ - DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : - -make all %{?_smp_mflags} +for type in separate single; do + mkdir $type && \ + (cd $type && ln -s ../configure && \ + test $type = 'single' && configure_single='--enable-single-binary' + %configure $configure_single \ + --cache-file=../config.cache \ + --enable-install-program=arch \ + --enable-no-install-program=uptime \ + --with-openssl \ + --with-tty-group \ + DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : + mkdir src # not needed with coreutils > 8.24 + make all %{?_smp_mflags}) +done # Get the list of supported utilities cp %SOURCE50 . %check -make check %{?_smp_mflags} +for type in separate single; do + test $type = 'single' && subdirs='SUBDIRS=.' # Only check gnulib once + (cd $type && make check %{?_smp_mflags} $subdirs) +done %install -make DESTDIR=$RPM_BUILD_ROOT install +for type in separate single; do + install=install + if test $type = 'single'; then + subdir=%{_libexecdir}/%{name}; install=install-exec + fi + (cd $type && make DESTDIR=$RPM_BUILD_ROOT/$subdir $install) + + # chroot was in /usr/sbin : + mkdir -p $RPM_BUILD_ROOT/$subdir/{%{_bindir},%{_sbindir}} + mv $RPM_BUILD_ROOT/$subdir/{%_bindir,%_sbindir}/chroot + + # Move multicall variants to *.single. + # RemovePathPostfixes will strip that later. + if test $type = 'single'; then + for dir in %{_bindir} %{_sbindir} %{_libexecdir}/%{name}; do + for bin in $RPM_BUILD_ROOT/%{_libexecdir}/%{name}/$dir/*; do + basebin=$(basename $bin) + mv $bin $RPM_BUILD_ROOT/$dir/$basebin.single + done + done + fi +done # fix japanese catalog file if [ -d $RPM_BUILD_ROOT%{_datadir}/locale/ja_JP.EUC/LC_MESSAGES ]; then @@ -195,12 +254,6 @@ fi bzip2 -9f ChangeLog -# let be compatible with old fileutils, sh-utils and textutils packages : -mkdir -p $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}} - -# chroot was in /usr/sbin : -mv $RPM_BUILD_ROOT{%_bindir,%_sbindir}/chroot - mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d install -p -c -m644 %SOURCE101 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS install -p -c -m644 %SOURCE102 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.lightbgcolor @@ -213,7 +266,8 @@ install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.c # rather than manually removing here, since tests depending on # built utilities are correctly skipped if not present. for i in kill ; do - rm $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1} + rm -f $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1} + rm -f $RPM_BUILD_ROOT/%{_libexecdir}/%{name}/{%{_bindir}/$i,%{_mandir}/man1/$i.1} done # Compress ChangeLogs from before the fileutils/textutils/etc merge @@ -260,18 +314,34 @@ if [ -f %{_infodir}/%{name}.info.gz ]; then /sbin/install-info %{_infodir}/%{name}.info.gz %{_infodir}/dir || : fi -%files -f %{name}.lang -f supported_utils +%files -f supported_utils +%defattr(-,root,root,-) +%exclude %{_bindir}/*.single +%{_libexecdir}/coreutils/*.so + +%files single +%defattr(-,root,root,-) +%{_bindir}/*.single +%{_sbindir}/chroot.single +%{_libexecdir}/coreutils/*.so.single + +%files common -f %{name}.lang %defattr(-,root,root,-) %config(noreplace) %{_sysconfdir}/DIR_COLORS* %config(noreplace) %{_sysconfdir}/profile.d/* +%{_infodir}/coreutils* +%{_mandir}/man*/* +# The following go to /usr/share/doc/coreutils-common %doc ABOUT-NLS NEWS README THANKS TODO %{!?_licensedir:%global license %%doc} %license COPYING %{_infodir}/coreutils* -%{_libexecdir}/coreutils* %{_mandir}/man*/* %changelog +* Wed Nov 18 2015 Pádraig Brady - 8.24-100 +- Split package to more easily support smaller installs + * Wed Sep 16 2015 Kamil Dudka - 8.24-4 - fix memory leak in sort/I18N (patches written by Pádraig, #1259942) From 5dc61e9dc17d78652156dbcd688994518a1fd505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Tue, 24 Nov 2015 01:43:34 +0000 Subject: [PATCH 282/523] maint: update stale comments The comments re %post processing were for a non commited change that created symlinks during %post that clobbered any existing binaries. Now all files are directly managed by rpm. --- coreutils.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 736b002..4cf459c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -55,7 +55,7 @@ Patch950: coreutils-selinux.patch Patch951: coreutils-selinuxmanpages.patch Conflicts: filesystem < 3 -# To avoid clobbering installs during %post +# To avoid clobbering installs Conflicts: coreutils-single Provides: /bin/basename Provides: /bin/cat @@ -132,7 +132,7 @@ the old GNU fileutils, sh-utils, and textutils packages. Summary: coreutils multicall binary Suggests: coreutils-common Provides: coreutils -# To avoid clobbering installs during %post +# To avoid clobbering installs Conflicts: coreutils < 8.24-100 # Note RPM doesn't support separate buildroots for %files # http://rpm.org/ticket/874 so use RemovePathPostfixes From 49c29b40693909ed9a7b158d7863c9a4d0070be5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 30 Nov 2015 14:32:27 +0100 Subject: [PATCH 283/523] Resolves:#1286338 - coreutils-single should provide versioned coreutils --- coreutils.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 736b002..75ed0d7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 100%{?dist} +Release: 101%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -131,7 +131,7 @@ the old GNU fileutils, sh-utils, and textutils packages. %package single Summary: coreutils multicall binary Suggests: coreutils-common -Provides: coreutils +Provides: coreutils = %{version}-%{release} # To avoid clobbering installs during %post Conflicts: coreutils < 8.24-100 # Note RPM doesn't support separate buildroots for %files @@ -339,6 +339,9 @@ fi %{_mandir}/man*/* %changelog +* Mon Nov 30 2015 Ondrej Vasik - 8.24-101 +- coreutils-single should provide versioned coreutils (#1286338) + * Wed Nov 18 2015 Pádraig Brady - 8.24-100 - Split package to more easily support smaller installs From 32b1e5a1542885941508ab440e3cabe0cdb36a1d Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Tue, 1 Dec 2015 09:40:25 +0100 Subject: [PATCH 284/523] Use the new i18n implementation for expand/unexpand --- coreutils-i18n-expand-unexpand.patch | 1452 ++++++++++++++++++++++++++ coreutils-i18n.patch | 453 -------- coreutils.spec | 8 +- 3 files changed, 1459 insertions(+), 454 deletions(-) create mode 100644 coreutils-i18n-expand-unexpand.patch diff --git a/coreutils-i18n-expand-unexpand.patch b/coreutils-i18n-expand-unexpand.patch new file mode 100644 index 0000000..63813f9 --- /dev/null +++ b/coreutils-i18n-expand-unexpand.patch @@ -0,0 +1,1452 @@ +From 332e9adf944e4ea232a855b1bf75ea4ddfd7e794 Mon Sep 17 00:00:00 2001 +From: Ondrej Oprala +Date: Wed, 5 Aug 2015 09:15:09 +0200 +Subject: [PATCH] expand,unexpand: add multibyte support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* NEWS: Mention the changes. +* bootstrap.conf: Add mbfile to the list of modules. +* configure.ac: Properly initialize mbfile. +* po/POTFILES.in: Add new source file. +* src/expand-core.c: Move functions common to both expand and +unexpand to this file. +* src/expand-core.h: Add function prototypes from expand-core.c. +* src/expand.c (expand): Iterate over multibyte characters properly. +* src/local.mk: Add expand-core.c to the lists of source codes for +expand and unexpand +* src/unexpand.c (unexpand): Iterate over multibyte characters +properly. +* tests/local.mk: Add new tests. +* tests/{expand,unexpand}/mb.sh: New tests. + +Co-authored-by: Pádraig Brady +--- + NEWS | 3 + + bootstrap.conf | 1 + + configure.ac | 2 + + po/POTFILES.in | 1 + + src/expand-core.c | 150 +++++++++++++++++++++++++++++++++++++++ + src/expand-core.h | 44 ++++++++++++ + src/expand.c | 183 ++++++++++------------------------------------- + src/local.mk | 2 + + src/unexpand.c | 197 ++++++++++++--------------------------------------- + tests/expand/mb.sh | 98 +++++++++++++++++++++++++ + tests/local.mk | 2 + + tests/unexpand/mb.sh | 97 +++++++++++++++++++++++++ + 12 files changed, 482 insertions(+), 298 deletions(-) + create mode 100644 src/expand-core.c + create mode 100644 src/expand-core.h + create mode 100755 tests/expand/mb.sh + create mode 100755 tests/unexpand/mb.sh + +diff --git a/bootstrap.conf b/bootstrap.conf +index ef1c078..ea8cebc 100644 +--- a/bootstrap.conf ++++ b/bootstrap.conf +@@ -152,6 +152,7 @@ gnulib_modules=" + maintainer-makefile + malloc-gnu + manywarnings ++ mbfile + mbrlen + mbrtowc + mbsalign +diff --git a/configure.ac b/configure.ac +index 8dc2192..b8b5114 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -422,6 +422,8 @@ gl_WINSIZE_IN_PTEM + # 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 && \ +diff --git a/po/POTFILES.in b/po/POTFILES.in +index b3fe668..c594d20 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -57,6 +57,7 @@ src/dirname.c + src/du.c + src/echo.c + src/env.c ++src/expand-core.c + src/expand.c + src/expr.c + src/factor.c +diff --git a/src/expand-core.c b/src/expand-core.c +new file mode 100644 +index 0000000..c8445db +--- /dev/null ++++ b/src/expand-core.c +@@ -0,0 +1,150 @@ ++/* expand-core.c - elementary functions for the expand and unexpand utilities ++ Copyright (C) 1989-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 . */ ++ ++#include ++ ++#include ++#include ++ ++#include "system.h" ++#include "error.h" ++#include "fadvise.h" ++#include "quote.h" ++#include "xstrndup.h" ++ ++#include "expand-core.h" ++ ++/* Add the comma or blank separated list of tab stops STOPS ++ to the list of tab stops. */ ++ ++extern void ++parse_tab_stops (char const *stops, void (*add_tab_stop)(uintmax_t)) ++{ ++ bool have_tabval = false; ++ uintmax_t tabval IF_LINT ( = 0); ++ char const *num_start IF_LINT ( = NULL); ++ bool ok = true; ++ ++ for (; *stops; stops++) ++ { ++ if (*stops == ',' || isblank (to_uchar (*stops))) ++ { ++ if (have_tabval) ++ add_tab_stop (tabval); ++ have_tabval = false; ++ } ++ else if (ISDIGIT (*stops)) ++ { ++ if (!have_tabval) ++ { ++ tabval = 0; ++ have_tabval = true; ++ num_start = stops; ++ } ++ ++ /* Detect overflow. */ ++ if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) ++ { ++ size_t len = strspn (num_start, "0123456789"); ++ char *bad_num = xstrndup (num_start, len); ++ error (0, 0, _("tab stop is too large %s"), quote (bad_num)); ++ free (bad_num); ++ ok = false; ++ stops = num_start + len - 1; ++ } ++ } ++ else ++ { ++ error (0, 0, _("tab size contains invalid character(s): %s"), ++ quote (stops)); ++ ok = false; ++ break; ++ } ++ } ++ ++ if (!ok) ++ exit (EXIT_FAILURE); ++ ++ if (have_tabval) ++ add_tab_stop (tabval); ++} ++ ++/* Check that the list of tab stops TABS, with ENTRIES entries, ++ contains only nonzero, ascending values. */ ++ ++extern void ++validate_tab_stops (uintmax_t const *tabs, size_t entries) ++{ ++ uintmax_t prev_tab = 0; ++ size_t i; ++ ++ for (i = 0; i < entries; i++) ++ { ++ if (tabs[i] == 0) ++ error (EXIT_FAILURE, 0, _("tab size cannot be 0")); ++ if (tabs[i] <= prev_tab) ++ error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); ++ prev_tab = tabs[i]; ++ } ++} ++ ++/* Close the old stream pointer FP if it is non-NULL, ++ and return a new one opened to read the next input file. ++ Open a filename of '-' as the standard input. ++ Return NULL if there are no more input files. */ ++ ++extern FILE * ++next_file (FILE *fp) ++{ ++ static char *prev_file; ++ char *file; ++ ++ if (fp) ++ { ++ if (ferror (fp)) ++ { ++ error (0, errno, "%s", prev_file); ++ exit_status = EXIT_FAILURE; ++ } ++ if (STREQ (prev_file, "-")) ++ clearerr (fp); /* Also clear EOF. */ ++ else if (fclose (fp) != 0) ++ { ++ error (0, errno, "%s", prev_file); ++ exit_status = EXIT_FAILURE; ++ } ++ } ++ ++ while ((file = *file_list++) != NULL) ++ { ++ if (STREQ (file, "-")) ++ { ++ have_read_stdin = true; ++ fp = stdin; ++ } ++ else ++ fp = fopen (file, "r"); ++ if (fp) ++ { ++ prev_file = file; ++ fadvise (fp, FADVISE_SEQUENTIAL); ++ return fp; ++ } ++ error (0, errno, "%s", file); ++ exit_status = EXIT_FAILURE; ++ } ++ return NULL; ++} +diff --git a/src/expand-core.h b/src/expand-core.h +new file mode 100644 +index 0000000..2419407 +--- /dev/null ++++ b/src/expand-core.h +@@ -0,0 +1,41 @@ ++/* expand-core.h - function prototypes for the expand and unexpand utilities ++ Copyright (C) 1989-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 . */ ++ ++#ifndef EXPAND_CORE_H_ ++# define EXPAND_CORE_H_ ++ ++extern size_t first_free_tab; ++ ++extern size_t n_tabs_allocated; ++ ++extern uintmax_t *tab_list; ++ ++extern int exit_status; ++ ++extern char **file_list; ++ ++extern bool have_read_stdin; ++ ++void ++parse_tab_stops (char const *stops, void (*add_tab_stop)(uintmax_t)); ++ ++void ++validate_tab_stops (uintmax_t const *tabs, size_t entries); ++ ++FILE * ++next_file (FILE *fp); ++ ++#endif /* EXPAND_CORE_H_ */ +diff --git a/src/expand.c b/src/expand.c +index 0a40a1a..ed97fd4 100644 +--- a/src/expand.c ++++ b/src/expand.c +@@ -37,12 +37,16 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "error.h" + #include "fadvise.h" +-#include "quote.h" + #include "xstrndup.h" + ++#include "expand-core.h" ++ + /* The official name of this program (e.g., no 'g' prefix). */ + #define PROGRAM_NAME "expand" + +@@ -58,17 +62,17 @@ static uintmax_t tab_size; + /* Array of the explicit column numbers of the tab stops; + after 'tab_list' is exhausted, each additional tab is replaced + by a space. The first column is column 0. */ +-static uintmax_t *tab_list; ++uintmax_t *tab_list; + + /* The number of allocated entries in 'tab_list'. */ +-static size_t n_tabs_allocated; ++size_t n_tabs_allocated; + + /* The index of the first invalid element of 'tab_list', + where the next element can be added. */ +-static size_t first_free_tab; ++size_t first_free_tab; + + /* Null-terminated array of input filenames. */ +-static char **file_list; ++char **file_list; + + /* Default for 'file_list' if no files are given on the command line. */ + static char *stdin_argv[] = +@@ -77,10 +81,10 @@ static char *stdin_argv[] = + }; + + /* True if we have ever read standard input. */ +-static bool have_read_stdin; ++bool have_read_stdin; + + /* The desired exit status. */ +-static int exit_status; ++int exit_status; + + static char const shortopts[] = "it:0::1::2::3::4::5::6::7::8::9::"; + +@@ -125,128 +129,6 @@ + if (first_free_tab == n_tabs_allocated) + tab_list = X2NREALLOC (tab_list, &n_tabs_allocated); + tab_list[first_free_tab++] = tabval; +-} +- +-/* Add the comma or blank separated list of tab stops STOPS +- to the list of tab stops. */ +- +-static void +-parse_tab_stops (char const *stops) +-{ +- bool have_tabval = false; +- uintmax_t tabval IF_LINT ( = 0); +- char const *num_start IF_LINT ( = NULL); +- bool ok = true; +- +- for (; *stops; stops++) +- { +- if (*stops == ',' || isblank (to_uchar (*stops))) +- { +- if (have_tabval) +- add_tab_stop (tabval); +- have_tabval = false; +- } +- else if (ISDIGIT (*stops)) +- { +- if (!have_tabval) +- { +- tabval = 0; +- have_tabval = true; +- num_start = stops; +- } +- +- /* Detect overflow. */ +- if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) +- { +- size_t len = strspn (num_start, "0123456789"); +- char *bad_num = xstrndup (num_start, len); +- error (0, 0, _("tab stop is too large %s"), quote (bad_num)); +- free (bad_num); +- ok = false; +- stops = num_start + len - 1; +- } +- } +- else +- { +- error (0, 0, _("tab size contains invalid character(s): %s"), +- quote (stops)); +- ok = false; +- break; +- } +- } +- +- if (!ok) +- exit (EXIT_FAILURE); +- +- if (have_tabval) +- add_tab_stop (tabval); +-} +- +-/* Check that the list of tab stops TABS, with ENTRIES entries, +- contains only nonzero, ascending values. */ +- +-static void +-validate_tab_stops (uintmax_t const *tabs, size_t entries) +-{ +- uintmax_t prev_tab = 0; +- size_t i; +- +- for (i = 0; i < entries; i++) +- { +- if (tabs[i] == 0) +- error (EXIT_FAILURE, 0, _("tab size cannot be 0")); +- if (tabs[i] <= prev_tab) +- error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); +- prev_tab = tabs[i]; +- } +-} +- +-/* Close the old stream pointer FP if it is non-NULL, +- and return a new one opened to read the next input file. +- Open a filename of '-' as the standard input. +- Return NULL if there are no more input files. */ +- +-static FILE * +-next_file (FILE *fp) +-{ +- static char *prev_file; +- char *file; +- +- if (fp) +- { +- if (ferror (fp)) +- { +- error (0, errno, "%s", prev_file); +- exit_status = EXIT_FAILURE; +- } +- if (STREQ (prev_file, "-")) +- clearerr (fp); /* Also clear EOF. */ +- else if (fclose (fp) != 0) +- { +- error (0, errno, "%s", prev_file); +- exit_status = EXIT_FAILURE; +- } +- } +- +- while ((file = *file_list++) != NULL) +- { +- if (STREQ (file, "-")) +- { +- have_read_stdin = true; +- fp = stdin; +- } +- else +- fp = fopen (file, "r"); +- if (fp) +- { +- prev_file = file; +- fadvise (fp, FADVISE_SEQUENTIAL); +- return fp; +- } +- error (0, errno, "%s", file); +- exit_status = EXIT_FAILURE; +- } +- return NULL; + } + + /* Change tabs to spaces, writing to stdout. +@@ -265,19 +146,19 @@ expand (void) + { + /* Input stream. */ + FILE *fp = next_file (NULL); ++ mb_file_t mbf; ++ mbf_char_t c; + + if (!fp) + return; + ++ mbf_init (mbf, fp); ++ + while (true) + { +- /* Input character, or EOF. */ +- int c; +- + /* If true, perform translations. */ + bool convert = true; + +- + /* The following variables have valid values only when CONVERT + is true: */ + +@@ -287,17 +168,23 @@ 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; ++ do { ++ mbf_getc (c, mbf); ++ if (mb_iseof (c)) ++ { ++ mbf_init (mbf, fp = next_file (fp)); ++ continue; ++ } ++ } ++ while (false); + + if (convert) + { +- if (c == '\t') ++ if (mb_iseq (c, '\t')) + { + /* Column the next input tab stop is on. */ + uintmax_t next_tab_column; +@@ -328,32 +215,34 @@ expand (void) + if (putchar (' ') < 0) + error (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) + error (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)) + error (EXIT_FAILURE, errno, _("write error")); + } +- while (c != '\n'); ++ while (!mb_iseq (c, '\n')); + } + } + +@@ -385,19 +274,19 @@ main (int argc, char **argv) + break; + + case 't': +- parse_tab_stops (optarg); ++ parse_tab_stops (optarg, add_tab_stop); + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (optarg) +- parse_tab_stops (optarg - 1); ++ parse_tab_stops (optarg - 1, add_tab_stop); + else + { + char tab_stop[2]; + tab_stop[0] = c; + tab_stop[1] = '\0'; +- parse_tab_stops (tab_stop); ++ parse_tab_stops (tab_stop, add_tab_stop); + } + break; + +diff --git a/src/local.mk b/src/local.mk +index 536b7cc..bfede88 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -362,6 +362,8 @@ src_coreutils_SOURCES = src/coreutils.c + + src_cp_SOURCES = src/cp.c $(copy_sources) $(selinux_sources) + src_dir_SOURCES = src/ls.c src/ls-dir.c ++src_expand_SOURCES = src/expand.c src/expand-core.c ++src_unexpand_SOURCES = src/unexpand.c src/expand-core.c + src_vdir_SOURCES = src/ls.c src/ls-vdir.c + src_id_SOURCES = src/id.c src/group-list.c + src_groups_SOURCES = src/groups.c src/group-list.c +diff --git a/src/unexpand.c b/src/unexpand.c +index e0f7c22..48fbb32 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c +@@ -38,12 +38,16 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "error.h" + #include "fadvise.h" +-#include "quote.h" + #include "xstrndup.h" + ++#include "expand-core.h" ++ + /* The official name of this program (e.g., no 'g' prefix). */ + #define PROGRAM_NAME "unexpand" + +@@ -62,17 +66,17 @@ static size_t max_column_width; + /* Array of the explicit column numbers of the tab stops; + after 'tab_list' is exhausted, the rest of the line is printed + unchanged. The first column is column 0. */ +-static uintmax_t *tab_list; ++uintmax_t *tab_list; + + /* The number of allocated entries in 'tab_list'. */ +-static size_t n_tabs_allocated; ++size_t n_tabs_allocated; + + /* The index of the first invalid element of 'tab_list', + where the next element can be added. */ +-static size_t first_free_tab; ++size_t first_free_tab; + + /* Null-terminated array of input filenames. */ +-static char **file_list; ++char **file_list; + + /* Default for 'file_list' if no files are given on the command line. */ + static char *stdin_argv[] = +@@ -81,10 +85,10 @@ static char *stdin_argv[] = + }; + + /* True if we have ever read standard input. */ +-static bool have_read_stdin; ++bool have_read_stdin; + + /* The desired exit status. */ +-static int exit_status; ++int exit_status; + + /* For long options that have no equivalent short option, use a + non-character as a pseudo short option, starting with CHAR_MAX + 1. */ +@@ -154,128 +156,6 @@ add_tab_stop (uintmax_t tabval) + } + } + +-/* Add the comma or blank separated list of tab stops STOPS +- to the list of tab stops. */ +- +-static void +-parse_tab_stops (char const *stops) +-{ +- bool have_tabval = false; +- uintmax_t tabval IF_LINT ( = 0); +- char const *num_start IF_LINT ( = NULL); +- bool ok = true; +- +- for (; *stops; stops++) +- { +- if (*stops == ',' || isblank (to_uchar (*stops))) +- { +- if (have_tabval) +- add_tab_stop (tabval); +- have_tabval = false; +- } +- else if (ISDIGIT (*stops)) +- { +- if (!have_tabval) +- { +- tabval = 0; +- have_tabval = true; +- num_start = stops; +- } +- +- /* Detect overflow. */ +- if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) +- { +- size_t len = strspn (num_start, "0123456789"); +- char *bad_num = xstrndup (num_start, len); +- error (0, 0, _("tab stop is too large %s"), quote (bad_num)); +- free (bad_num); +- ok = false; +- stops = num_start + len - 1; +- } +- } +- else +- { +- error (0, 0, _("tab size contains invalid character(s): %s"), +- quote (stops)); +- ok = false; +- break; +- } +- } +- +- if (!ok) +- exit (EXIT_FAILURE); +- +- if (have_tabval) +- add_tab_stop (tabval); +-} +- +-/* Check that the list of tab stops TABS, with ENTRIES entries, +- contains only nonzero, ascending values. */ +- +-static void +-validate_tab_stops (uintmax_t const *tabs, size_t entries) +-{ +- uintmax_t prev_tab = 0; +- size_t i; +- +- for (i = 0; i < entries; i++) +- { +- if (tabs[i] == 0) +- error (EXIT_FAILURE, 0, _("tab size cannot be 0")); +- if (tabs[i] <= prev_tab) +- error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); +- prev_tab = tabs[i]; +- } +-} +- +-/* Close the old stream pointer FP if it is non-NULL, +- and return a new one opened to read the next input file. +- Open a filename of '-' as the standard input. +- Return NULL if there are no more input files. */ +- +-static FILE * +-next_file (FILE *fp) +-{ +- static char *prev_file; +- char *file; +- +- if (fp) +- { +- if (ferror (fp)) +- { +- error (0, errno, "%s", prev_file); +- exit_status = EXIT_FAILURE; +- } +- if (STREQ (prev_file, "-")) +- clearerr (fp); /* Also clear EOF. */ +- else if (fclose (fp) != 0) +- { +- error (0, errno, "%s", prev_file); +- exit_status = EXIT_FAILURE; +- } +- } +- +- while ((file = *file_list++) != NULL) +- { +- if (STREQ (file, "-")) +- { +- have_read_stdin = true; +- fp = stdin; +- } +- else +- fp = fopen (file, "r"); +- if (fp) +- { +- prev_file = file; +- fadvise (fp, FADVISE_SEQUENTIAL); +- return fp; +- } +- error (0, errno, "%s", file); +- exit_status = EXIT_FAILURE; +- } +- return NULL; +-} +- + /* Change blanks to tabs, writing to stdout. + Read each file in 'file_list', in order. */ + +@@ -284,11 +164,12 @@ 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; + + if (!fp) + return; +@@ -296,12 +177,14 @@ unexpand (void) + /* 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)); ++ ++ mbf_init (mbf, fp); + + while (true) + { + /* Input character, or EOF. */ +- int c; ++ mbf_char_t c; + + /* If true, perform translations. */ + bool convert = true; +@@ -335,12 +218,19 @@ unexpand (void) + + do + { +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) +- continue; ++ do { ++ mbf_getc (c, mbf); ++ if (mb_iseof (c)) ++ { ++ mbf_init (mbf, fp = next_file (fp)); ++ continue; ++ } ++ } ++ while (false); + + if (convert) + { +- bool blank = !! isblank (c); ++ bool blank = mb_isblank (c); + + if (blank) + { +@@ -372,16 +262,16 @@ unexpand (void) + if (next_tab_column < column) + error (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)) + { +@@ -389,13 +279,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 +@@ -403,7 +294,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. */ +@@ -413,7 +304,7 @@ unexpand (void) + } + else + { +- column++; ++ column += mb_width (c); + if (!column) + error (EXIT_FAILURE, 0, _("input line is too long")); + } +@@ -421,9 +312,13 @@ 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)) + error (EXIT_FAILURE, errno, _("write error")); ++ + pending = 0; + one_blank_before_tab_stop = false; + } +@@ -432,16 +327,16 @@ 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)) + error (EXIT_FAILURE, errno, _("write error")); + } +- while (c != '\n'); ++ while (!mb_iseq (c, '\n')); + } + } + +@@ -482,7 +377,7 @@ main (int argc, char **argv) + break; + case 't': + convert_entire_line = true; +- parse_tab_stops (optarg); ++ parse_tab_stops (optarg, add_tab_stop); + break; + case CONVERT_FIRST_ONLY_OPTION: + convert_first_only = true; +diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh +new file mode 100755 +index 0000000..7971e18 +--- /dev/null ++++ b/tests/expand/mb.sh +@@ -0,0 +1,98 @@ ++#!/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 ++ ++#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 ++ ++exit $fail +diff --git a/tests/local.mk b/tests/local.mk +index 7df04da..d3462be 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -532,6 +532,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 \ +@@ -671,6 +672,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. +diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh +new file mode 100755 +index 0000000..60d4c1a +--- /dev/null ++++ b/tests/unexpand/mb.sh +@@ -0,0 +1,97 @@ ++#!/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 ++ ++#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 +-- +2.4.3 + +--- /dev/null 2015-11-30 08:40:17.566742513 +0100 ++++ coreutils-8.24/m4/mbfile.m4 2015-12-01 09:30:55.951149907 +0100 +@@ -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]) ++ : ++]) +--- /dev/null 2015-11-30 08:40:17.566742513 +0100 ++++ coreutils-8.24/lib/mbfile.c 2015-12-01 09:28:22.254928468 +0100 +@@ -0,0 +1,3 @@ ++#include ++#define MBFILE_INLINE _GL_EXTERN_INLINE ++#include "mbfile.h" +--- /dev/null 2015-11-30 08:40:17.566742513 +0100 ++++ coreutils-8.24/lib/mbfile.h 2015-12-01 09:28:30.829885570 +0100 +@@ -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 */ diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index f823a40..5d3a591 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -596,201 +596,6 @@ diff -urNp coreutils-8.24-orig/src/cut.c coreutils-8.24/src/cut.c } if (optind == argc) -diff -urNp coreutils-8.24-orig/src/expand.c coreutils-8.24/src/expand.c ---- coreutils-8.24-orig/src/expand.c 2015-06-26 19:05:22.000000000 +0200 -+++ coreutils-8.24/src/expand.c 2015-07-05 09:04:33.028546950 +0200 -@@ -37,12 +37,34 @@ - #include - #include - #include -+ -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get iswblank(). */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+ - #include "system.h" - #include "error.h" - #include "fadvise.h" - #include "quote.h" - #include "xstrndup.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 "expand" - -@@ -357,6 +379,142 @@ expand (void) - } - } - -+#if HAVE_MBRTOWC -+static void -+expand_multibyte (void) -+{ -+ FILE *fp; /* Input strem. */ -+ mbstate_t i_state; /* Current shift state of the input stream. */ -+ mbstate_t i_state_bak; /* Back up the I_STATE. */ -+ mbstate_t o_state; /* Current shift state of the output stream. */ -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos = buf; /* Next read position of BUF. */ -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ -+ wchar_t wc; /* A gotten wide character. */ -+ size_t mblength; /* The byte size of a multibyte character -+ which shows as same character as WC. */ -+ int tab_index = 0; /* Index in `tab_list' of next tabstop. */ -+ int column = 0; /* Column on screen of the next char. */ -+ int next_tab_column; /* Column the next tab stop is on. */ -+ int convert = 1; /* If nonzero, perform translations. */ -+ -+ fp = next_file ((FILE *) NULL); -+ if (fp == NULL) -+ return; -+ -+ memset (&o_state, '\0', sizeof(mbstate_t)); -+ memset (&i_state, '\0', sizeof(mbstate_t)); -+ -+ for (;;) -+ { -+ /* Refill the buffer BUF. */ -+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) -+ { -+ memmove (buf, bufpos, buflen); -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); -+ bufpos = buf; -+ } -+ -+ /* No character is left in BUF. */ -+ if (buflen < 1) -+ { -+ fp = next_file (fp); -+ -+ if (fp == NULL) -+ break; /* No more files. */ -+ else -+ { -+ memset (&i_state, '\0', sizeof(mbstate_t)); -+ continue; -+ } -+ } -+ -+ /* Get a wide character. */ -+ i_state_bak = i_state; -+ mblength = mbrtowc (&wc, bufpos, buflen, &i_state); -+ -+ switch (mblength) -+ { -+ case (size_t)-1: /* illegal byte sequence. */ -+ case (size_t)-2: -+ mblength = 1; -+ i_state = i_state_bak; -+ if (convert) -+ { -+ ++column; -+ if (convert_entire_line == 0 && !isblank(*bufpos)) -+ convert = 0; -+ } -+ putchar (*bufpos); -+ break; -+ -+ case 0: /* null. */ -+ mblength = 1; -+ if (convert && convert_entire_line == 0) -+ convert = 0; -+ putchar ('\0'); -+ break; -+ -+ default: -+ if (wc == L'\n') /* LF. */ -+ { -+ tab_index = 0; -+ column = 0; -+ convert = 1; -+ putchar ('\n'); -+ } -+ else if (wc == L'\t' && convert) /* Tab. */ -+ { -+ if (tab_size == 0) -+ { -+ /* Do not let tab_index == first_free_tab; -+ stop when it is 1 less. */ -+ while (tab_index < first_free_tab - 1 -+ && column >= tab_list[tab_index]) -+ tab_index++; -+ next_tab_column = tab_list[tab_index]; -+ if (tab_index < first_free_tab - 1) -+ tab_index++; -+ if (column >= next_tab_column) -+ next_tab_column = column + 1; -+ } -+ else -+ next_tab_column = column + tab_size - column % tab_size; -+ -+ while (column < next_tab_column) -+ { -+ putchar (' '); -+ ++column; -+ } -+ } -+ else /* Others. */ -+ { -+ if (convert) -+ { -+ if (wc == L'\b') -+ { -+ if (column > 0) -+ --column; -+ } -+ else -+ { -+ int width; /* The width of WC. */ -+ -+ width = wcwidth (wc); -+ column += (width > 0) ? width : 0; -+ if (convert_entire_line == 0 && !iswblank(wc)) -+ convert = 0; -+ } -+ } -+ fwrite (bufpos, sizeof(char), mblength, stdout); -+ } -+ } -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+} -+#endif -+ - int - main (int argc, char **argv) - { -@@ -421,7 +579,12 @@ main (int argc, char **argv) - - file_list = (optind < argc ? &argv[optind] : stdin_argv); - -- expand (); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ expand_multibyte (); -+ else -+#endif -+ expand (); - - if (have_read_stdin && fclose (stdin) != 0) - error (EXIT_FAILURE, errno, "-"); diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c --- coreutils-8.24-orig/src/fold.c 2015-06-26 19:05:22.000000000 +0200 +++ coreutils-8.24/src/fold.c 2015-07-05 09:04:33.029546958 +0200 @@ -3480,264 +3285,6 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c if (have_read_stdin && fclose (stdin) == EOF) die (_("close failed"), "-"); -diff -urNp coreutils-8.24-orig/src/unexpand.c coreutils-8.24/src/unexpand.c ---- coreutils-8.24-orig/src/unexpand.c 2015-06-26 19:05:22.000000000 +0200 -+++ coreutils-8.24/src/unexpand.c 2015-07-05 09:04:33.032546980 +0200 -@@ -38,12 +38,29 @@ - #include - #include - #include -+ -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ - #include "system.h" - #include "error.h" - #include "fadvise.h" - #include "quote.h" - #include "xstrndup.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 "unexpand" - -@@ -103,6 +120,210 @@ static struct option const longopts[] = - {NULL, 0, NULL, 0} - }; - -+static FILE *next_file (FILE *fp); -+ -+#if HAVE_MBRTOWC -+static void -+unexpand_multibyte (void) -+{ -+ FILE *fp; /* Input stream. */ -+ mbstate_t i_state; /* Current shift state of the input stream. */ -+ mbstate_t i_state_bak; /* Back up the I_STATE. */ -+ mbstate_t o_state; /* Current shift state of the output stream. */ -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ char *bufpos = buf; /* Next read position of BUF. */ -+ size_t buflen = 0; /* 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. */ -+ bool prev_tab = false; -+ -+ /* Index in `tab_list' of next tabstop: */ -+ int tab_index = 0; /* For calculating width of pending tabs. */ -+ int print_tab_index = 0; /* For printing as many tabs as possible. */ -+ unsigned int column = 0; /* Column on screen of next char. */ -+ int next_tab_column; /* Column the next tab stop is on. */ -+ int convert = 1; /* If nonzero, perform translations. */ -+ unsigned int pending = 0; /* Pending columns of blanks. */ -+ -+ fp = next_file ((FILE *) NULL); -+ if (fp == NULL) -+ return; -+ -+ memset (&o_state, '\0', sizeof(mbstate_t)); -+ memset (&i_state, '\0', sizeof(mbstate_t)); -+ -+ for (;;) -+ { -+ if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) -+ { -+ memmove (buf, bufpos, buflen); -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); -+ bufpos = buf; -+ } -+ -+ /* Get a wide character. */ -+ if (buflen < 1) -+ { -+ mblength = 1; -+ wc = WEOF; -+ } -+ else -+ { -+ i_state_bak = i_state; -+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state); -+ } -+ -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ i_state = i_state_bak; -+ wc = L'\0'; -+ } -+ -+ if (wc == L' ' && convert && column < INT_MAX) -+ { -+ ++pending; -+ ++column; -+ } -+ else if (wc == L'\t' && convert) -+ { -+ if (tab_size == 0) -+ { -+ /* Do not let tab_index == first_free_tab; -+ stop when it is 1 less. */ -+ while (tab_index < first_free_tab - 1 -+ && column >= tab_list[tab_index]) -+ tab_index++; -+ next_tab_column = tab_list[tab_index]; -+ if (tab_index < first_free_tab - 1) -+ tab_index++; -+ if (column >= next_tab_column) -+ { -+ convert = 0; /* Ran out of tab stops. */ -+ goto flush_pend_mb; -+ } -+ } -+ else -+ { -+ next_tab_column = column + tab_size - column % tab_size; -+ } -+ pending += next_tab_column - column; -+ column = next_tab_column; -+ } -+ else -+ { -+flush_pend_mb: -+ /* Flush pending spaces. Print as many tabs as possible, -+ then print the rest as spaces. */ -+ if (pending == 1 && column != 1 && !prev_tab) -+ { -+ putchar (' '); -+ pending = 0; -+ } -+ column -= pending; -+ while (pending > 0) -+ { -+ if (tab_size == 0) -+ { -+ /* Do not let print_tab_index == first_free_tab; -+ stop when it is 1 less. */ -+ while (print_tab_index < first_free_tab - 1 -+ && column >= tab_list[print_tab_index]) -+ print_tab_index++; -+ next_tab_column = tab_list[print_tab_index]; -+ if (print_tab_index < first_free_tab - 1) -+ print_tab_index++; -+ } -+ else -+ { -+ next_tab_column = -+ column + tab_size - column % tab_size; -+ } -+ if (next_tab_column - column <= pending) -+ { -+ putchar ('\t'); -+ pending -= next_tab_column - column; -+ column = next_tab_column; -+ } -+ else -+ { -+ --print_tab_index; -+ column += pending; -+ while (pending != 0) -+ { -+ putchar (' '); -+ pending--; -+ } -+ } -+ } -+ -+ if (wc == WEOF) -+ { -+ fp = next_file (fp); -+ if (fp == NULL) -+ break; /* No more files. */ -+ else -+ { -+ memset (&i_state, '\0', sizeof(mbstate_t)); -+ continue; -+ } -+ } -+ -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ if (convert) -+ { -+ ++column; -+ if (convert_entire_line == 0) -+ convert = 0; -+ } -+ mblength = 1; -+ putchar (buf[0]); -+ } -+ else if (mblength == 0) -+ { -+ if (convert && convert_entire_line == 0) -+ convert = 0; -+ mblength = 1; -+ putchar ('\0'); -+ } -+ else -+ { -+ if (convert) -+ { -+ if (wc == L'\b') -+ { -+ if (column > 0) -+ --column; -+ } -+ else -+ { -+ int width; /* The width of WC. */ -+ -+ width = wcwidth (wc); -+ column += (width > 0) ? width : 0; -+ if (convert_entire_line == 0) -+ convert = 0; -+ } -+ } -+ -+ if (wc == L'\n') -+ { -+ tab_index = print_tab_index = 0; -+ column = pending = 0; -+ convert = 1; -+ } -+ fwrite (bufpos, sizeof(char), mblength, stdout); -+ } -+ } -+ prev_tab = wc == L'\t'; -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+} -+#endif -+ -+ - void - usage (int status) - { -@@ -523,7 +744,12 @@ main (int argc, char **argv) - - file_list = (optind < argc ? &argv[optind] : stdin_argv); - -- unexpand (); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ unexpand_multibyte (); -+ else -+#endif -+ unexpand (); - - if (have_read_stdin && fclose (stdin) != 0) - error (EXIT_FAILURE, errno, "-"); diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c --- coreutils-8.24-orig/src/uniq.c 2015-06-26 19:04:19.000000000 +0200 +++ coreutils-8.24/src/uniq.c 2015-07-05 09:04:33.032546980 +0200 diff --git a/coreutils.spec b/coreutils.spec index b0c13dc..d2d7c1c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 101%{?dist} +Release: 102%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -41,6 +41,8 @@ Patch713: coreutils-4.5.3-langinfo.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch +# (sb) lin18nux/lsb compliance - expand/unexpand +Patch801: coreutils-i18n-expand-unexpand.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch @@ -171,6 +173,7 @@ including documentation and translations. # li18nux/lsb %patch800 -p1 -b .i18n +%patch801 -p1 -b .i18n-expand # Coreutils %patch908 -p1 -b .getgrouplist @@ -339,6 +342,9 @@ fi %{_mandir}/man*/* %changelog +* Tue Dec 01 2015 Ondrej Oprala - 8.24-102 +- Use the new i18n implementation for expand/unexpand + * Mon Nov 30 2015 Ondrej Vasik - 8.24-101 - coreutils-single should provide versioned coreutils (#1286338) From 1f6f388ba38890604388bd8c1b3eed3db159f0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Thu, 3 Dec 2015 19:38:07 +0000 Subject: [PATCH 285/523] avoid warning about twice specified %files --- coreutils.spec | 2 -- 1 file changed, 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index d2d7c1c..c852c0e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -338,8 +338,6 @@ fi %doc ABOUT-NLS NEWS README THANKS TODO %{!?_licensedir:%global license %%doc} %license COPYING -%{_infodir}/coreutils* -%{_mandir}/man*/* %changelog * Tue Dec 01 2015 Ondrej Oprala - 8.24-102 From 7f1720d9a27d5bffd9d74cb6dcffdcefd3a01cee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Thu, 3 Dec 2015 17:06:53 +0000 Subject: [PATCH 286/523] fix inclusion of /usr/bin/kill in coreutils-single we need to remove /usr/bin/kill.single --- coreutils.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index c852c0e..626f42a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 102%{?dist} +Release: 103%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -270,7 +270,7 @@ install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.c # built utilities are correctly skipped if not present. for i in kill ; do rm -f $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1} - rm -f $RPM_BUILD_ROOT/%{_libexecdir}/%{name}/{%{_bindir}/$i,%{_mandir}/man1/$i.1} + rm -f $RPM_BUILD_ROOT%{_bindir}/$i.single done # Compress ChangeLogs from before the fileutils/textutils/etc merge @@ -340,6 +340,9 @@ fi %license COPYING %changelog +* Thu Dec 03 2015 Pádraig Brady - 8.24-103 +- Remove erroneous /usr/bin/kill from coreutils-single + * Tue Dec 01 2015 Ondrej Oprala - 8.24-102 - Use the new i18n implementation for expand/unexpand From 63c57dca196ca34c10b9039f15085543f0dd1f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Thu, 3 Dec 2015 13:53:49 +0000 Subject: [PATCH 287/523] reduce dependencies for coreutils-single Don't depend on libcrypto from the multicall binary in the coreutils-single package, because that trades space for speed. Don't depend on libgmp from the multicall binary in the coreutils-single package, because that only benefits factor and expr. The large size of gmp is not seen as an appropriate tradeoff for this functionality. Note also there is reduced startup overhead for all tools with these removed due to not linking with the shared libs. --- coreutils-find-requires.sh | 25 +++++++++++++++++++++++++ coreutils.spec | 25 +++++++++++++++++++------ 2 files changed, 44 insertions(+), 6 deletions(-) create mode 100755 coreutils-find-requires.sh diff --git a/coreutils-find-requires.sh b/coreutils-find-requires.sh new file mode 100755 index 0000000..27d1368 --- /dev/null +++ b/coreutils-find-requires.sh @@ -0,0 +1,25 @@ +#!/bin/sh - +# Reduce requires for coreutils-single +# Needed since it has overlapping "binaries" with the main package +# Ideally we could do the following in the spec only for the single subpackage +# %define __requires_exclude_from ^(%{_bindir}|%{_sbindir})/([^c]|c[^o]|co[^r]|cor[^e]) + +original_find_requires="$1" +shift + +# Get the list of files. +files=`sed "s/['\"]/\\\&/g"` + +single_bin='/usr/bin/coreutils' + +single=`echo $files | grep "$single_bin"` + +echo $files | tr [:blank:] '\n' | +if [ "$single" ]; then + # Only allow the coreutils multicall binary + # Also adjust for .single renaming + sed -n 's|\(.*'"$single_bin"'\)\(.single\)\?$|\1.single|p' +else + cat +fi | +$original_find_requires diff --git a/coreutils.spec b/coreutils.spec index 626f42a..1cea379 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 103%{?dist} +Release: 104%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -14,6 +14,12 @@ Source103: coreutils-DIR_COLORS.256color Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh +# Provide our own custom requires for coreutils-single package +Source10: coreutils-find-requires.sh +%global _use_internal_dependency_generator 0 +%global __find_provides %{_rpmconfigdir}/find-provides +%global __find_requires %{SOURCE10} %{_rpmconfigdir}/find-requires + # From upstream # Our patches @@ -110,7 +116,6 @@ Requires(preun): /sbin/install-info Requires(post): /sbin/install-info Requires(post): grep Requires: ncurses -Requires: gmp Provides: fileutils = %{version}-%{release} Provides: sh-utils = %{version}-%{release} @@ -201,13 +206,18 @@ autoconf --force automake --copy --add-missing for type in separate single; do mkdir $type && \ - (cd $type && ln -s ../configure && \ - test $type = 'single' && configure_single='--enable-single-binary' - %configure $configure_single \ + (cd $type && ln -s ../configure || exit 1 + if test $type = 'single'; then + config_single='--enable-single-binary' + config_single="$config_single --without-openssl" # smaller/slower sha*sum + config_single="$config_single --without-gmp" # expr/factor machine ints + else + config_single='--with-openssl' # faster sha*sum + fi + %configure $config_single \ --cache-file=../config.cache \ --enable-install-program=arch \ --enable-no-install-program=uptime \ - --with-openssl \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : mkdir src # not needed with coreutils > 8.24 @@ -340,6 +350,9 @@ fi %license COPYING %changelog +* Thu Dec 03 2015 Pádraig Brady - 8.24-104 +- Avoid libgmp and libcrypto dependencies from coreutils-single + * Thu Dec 03 2015 Pádraig Brady - 8.24-103 - Remove erroneous /usr/bin/kill from coreutils-single From c553cab787c2499ffaa36748a2de7c0e08fe31d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Mon, 14 Dec 2015 14:14:33 +0000 Subject: [PATCH 288/523] give explicit priority to coreutils over coreutils-single Make the main coreutils package Obsoletes: coreutils-single so that it has priority in depsolving. --- coreutils.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 1cea379..3d28fb6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 104%{?dist} +Release: 105%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -65,6 +65,8 @@ Patch951: coreutils-selinuxmanpages.patch Conflicts: filesystem < 3 # To avoid clobbering installs Conflicts: coreutils-single +# To give priority to this package +Obsoletes: coreutils-single Provides: /bin/basename Provides: /bin/cat Provides: /bin/chgrp @@ -350,6 +352,9 @@ fi %license COPYING %changelog +* Mon Dec 14 2015 Pádraig Brady - 8.24-105 +- Give explicit priority to coreutils over coreutils-single + * Thu Dec 03 2015 Pádraig Brady - 8.24-104 - Avoid libgmp and libcrypto dependencies from coreutils-single From 452aa4a7e3909a3d96291afca08337d7a95d422b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 13 Jan 2016 12:30:46 +0100 Subject: [PATCH 289/523] mv: prevent dataloss when source dir is specified multiple times (#1297464, by P.Brady) --- coreutils-8.24-mv-duplicate-sources.patch | 119 ++++++++++++++++++++++ coreutils.spec | 14 ++- 2 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 coreutils-8.24-mv-duplicate-sources.patch diff --git a/coreutils-8.24-mv-duplicate-sources.patch b/coreutils-8.24-mv-duplicate-sources.patch new file mode 100644 index 0000000..f518cc6 --- /dev/null +++ b/coreutils-8.24-mv-duplicate-sources.patch @@ -0,0 +1,119 @@ +@@ -, +, @@ + destination + mv dir dir dir +--- + src/copy.c | 12 +++++++---- + tests/local.mk | 1 - + tests/mv/dup-source.sh | 46 +++++++++++++++++++++++++++++++++---------- + 3 files changed, 44 insertions(+), 15 deletions(-) +--- a/src/copy.c ++++ a/src/copy.c +@@ -2278,10 +2278,14 @@ copy_internal (char const *src_name, char const *dst_name, + error (0, 0, _("warning: source directory %s " + "specified more than once"), + quote (top_level_src_name)); +- /* We only do backups in move mode and for non dirs, +- and in move mode this won't be the issue as the source will +- be missing for subsequent attempts. +- There we just warn and return here. */ ++ /* In move mode, if a previous rename succeeded, then ++ we won't be in this path as the source is missing. If the ++ rename previously failed, then that has been handled. ++ Pretend this instance succeeded so the source isn't removed. */ ++ if (x->move_mode && rename_succeeded) ++ *rename_succeeded = true; ++ /* We only do backups in move mode, and for non directories. ++ So just ignore this repeated entry. */ + return true; + } + else if (x->dereference == DEREF_ALWAYS +--- a/tests/local.mk ++++ a/tests/local.mk +@@ -443,7 +443,6 @@ all_tests = \ + tests/cp/dir-rm-dest.sh \ + tests/cp/dir-slash.sh \ + tests/cp/dir-vs-file.sh \ +- tests/cp/duplicate-sources.sh \ + tests/cp/existing-perm-dir.sh \ + tests/cp/existing-perm-race.sh \ + tests/cp/fail-perm.sh \ +--- a/tests/mv/dup-source.sh ++++ a/tests/mv/dup-source.sh +@@ -24,25 +24,37 @@ print_ver_ cp mv + + skip_if_root_ + ++reset_files() { rm -fr a b d; touch a; mkdir b d; } ++ + for i in cp; do + + # cp may not fail in this case. +- +- rm -fr a d; touch a; mkdir d ++ reset_files + $i a a d/ 2> out || fail=1 +- rm -fr a d; touch a; mkdir d ++ reset_files + $i ./a a d/ 2>> out || fail=1 + ++ # Similarly for directories, but handle ++ # source == dest appropriately. ++ reset_files ++ $i -a ./b b d/ 2>> out || fail=1 ++ reset_files ++ returns_ 1 $i -a ./b b b/ 2>> out || fail=1 ++ + # cp succeeds with --backup=numbered. +- rm -fr a d; touch a; mkdir d ++ reset_files + $i --backup=numbered a a d/ 2>> out || fail=1 + + # But not with plain '--backup' +- rm -fr a d; touch a; mkdir d +- $i --backup a a d/ 2>> out && fail=1 ++ reset_files ++ returns_ 1 $i --backup a a d/ 2>> out || fail=1 ++ + cat < exp + $i: warning: source file 'a' specified more than once + $i: warning: source file 'a' specified more than once ++$i: warning: source directory 'b' specified more than once ++$i: cannot copy a directory, './b', into itself, 'b/b' ++$i: warning: source directory 'b' specified more than once + $i: will not overwrite just-created 'd/a' with 'a' + EOF + compare exp out || fail=1 +@@ -50,14 +62,28 @@ done + + for i in mv; do + # But mv *does* fail in this case (it has to). ++ reset_files ++ returns_ 1 $i a a d/ 2> out || fail=1 ++ returns_ 1 test -e a || fail=1 ++ reset_files ++ returns_ 1 $i ./a a d/ 2>> out || fail=1 ++ returns_ 1 test -e a || fail=1 ++ ++ # Similarly for directories, also handling ++ # source == dest appropriately. ++ reset_files ++ returns_ 1 $i ./b b d/ 2>> out || fail=1 ++ returns_ 1 test -e b || fail=1 ++ reset_files ++ returns_ 1 $i --verbose ./b b b/ 2>> out || fail=1 ++ test -d b || fail=1 + +- rm -fr a d; touch a; mkdir d +- $i a a d/ 2> out && fail=1 +- rm -fr a d; touch a; mkdir d +- $i ./a a d/ 2>> out && fail=1 + cat < exp + $i: cannot stat 'a': No such file or directory + $i: cannot stat 'a': No such file or directory ++$i: cannot stat 'b': No such file or directory ++$i: cannot move './b' to a subdirectory of itself, 'b/b' ++$i: warning: source directory 'b' specified more than once + EOF + compare exp out || fail=1 + done +-- diff --git a/coreutils.spec b/coreutils.spec index 3d28fb6..31cba83 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 105%{?dist} +Release: 106%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -20,7 +20,10 @@ Source10: coreutils-find-requires.sh %global __find_provides %{_rpmconfigdir}/find-provides %global __find_requires %{SOURCE10} %{_rpmconfigdir}/find-requires -# From upstream +# From upstream +#mv: prevent dataloss when source directory is specified multiple t imes +Patch1: coreutils-8.24-mv-duplicate-sources.patch + # Our patches #general patch to workaround koji build system issues @@ -186,12 +189,13 @@ including documentation and translations. %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow %patch913 -p1 -b .testoff +%patch1 -p1 -b .dupl #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh || : +chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh tests/mv-dup-source.sh || : #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -352,6 +356,10 @@ fi %license COPYING %changelog +* Wed Jan 13 2016 Ondrej Vasik - 8.24-106 +- mv: prevent dataloss when source dir is specified multiple + times (#1297464, by P.Brady) + * Mon Dec 14 2015 Pádraig Brady - 8.24-105 - Give explicit priority to coreutils over coreutils-single From 01067b2813033d1ad183289a76007e8859659cda Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Mon, 7 Dec 2015 09:59:13 +0100 Subject: [PATCH 290/523] Use the new i18n implementation for the cut utility --- coreutils-i18n-cut.patch | 583 +++++++++++++++++++++++++++++++++++++++ coreutils-i18n.patch | 573 -------------------------------------- coreutils.spec | 8 +- 3 files changed, 590 insertions(+), 574 deletions(-) create mode 100644 coreutils-i18n-cut.patch diff --git a/coreutils-i18n-cut.patch b/coreutils-i18n-cut.patch new file mode 100644 index 0000000..b300eac --- /dev/null +++ b/coreutils-i18n-cut.patch @@ -0,0 +1,583 @@ +--- coreutils-8.24/src/cut.c 2015-06-26 19:05:22.000000000 +0200 ++++ cut.c 2016-01-15 10:15:04.863804121 +0100 +@@ -28,6 +28,11 @@ + #include + #include + #include ++ ++#include ++#include ++#include ++ + #include "system.h" + + #include "error.h" +@@ -90,25 +95,16 @@ add_range_pair (size_t lo, size_t hi) + ++n_rp; + } + +-/* 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 +- first field must be read into this buffer to determine whether it +- is followed by a delimiter or a newline before any of it may be +- output. Otherwise, cut_fields can do the job without using this +- buffer. */ +-static char *field_1_buffer; +- +-/* The number of bytes allocated for FIELD_1_BUFFER. */ +-static size_t field_1_bufsize; +- + enum operating_mode + { + undefined_mode, + +- /* Output characters that are in the given bytes. */ ++ /* Output the given bytes. */ + byte_mode, + ++ /* Output characters that are in the given positions . */ ++ char_mode, ++ + /* Output the given delimiter-separated fields. */ + field_mode + }; +@@ -120,12 +116,16 @@ static enum operating_mode operating_mod + with field mode. */ + static bool suppress_non_delimited; + ++/* Unless true, we do not recognize multibyte characters in byte-splitting ++ mode. */ ++static bool no_break_mb_chars; ++ + /* If true, print all bytes, characters, or fields _except_ + those that were specified. */ + static bool complement; + + /* The delimiter character for field mode. */ +-static unsigned char delim; ++static mbf_char_t delim; + + /* True if the --output-delimiter=STRING option was specified. */ + static bool output_delimiter_specified; +@@ -135,7 +135,7 @@ static size_t output_delimiter_length; + + /* The output field separator string. Defaults to the 1-character + string consisting of the input delimiter. */ +-static char *output_delimiter_string; ++static char const *output_delimiter_string; + + /* True if we have ever read standard input. */ + static bool have_read_stdin; +@@ -189,7 +189,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\ +@@ -435,6 +435,12 @@ next_item (size_t *item_idx) + current_rp++; + } + ++static inline void ++next_item_n (size_t *item_idx, size_t n) ++{ ++ while (n-- > 0) ++ next_item (item_idx); ++} + /* Return nonzero if the K'th field or byte is printable. */ + + static inline bool +@@ -443,6 +449,15 @@ print_kth (size_t k) + return current_rp->lo <= k; + } + ++/* The lo and hi params should be used for the current characters byte position ++ * and byte size, respectively. */ ++static inline bool ++rp_intersect (size_t lo, size_t hi) ++{ ++ return ((current_rp->lo <= lo && current_rp->hi >= lo) ++ || (current_rp->lo <= hi && current_rp->hi >= hi)); ++} ++ + /* Return nonzero if K'th byte is the beginning of a range. */ + + static inline bool +@@ -505,23 +520,216 @@ cut_bytes (FILE *stream) + } + + /* Read from stream STREAM, printing to standard output any selected fields. */ ++extern ssize_t ++mb_getndelim2 (mbf_char_t **lineptr, size_t *linesize, size_t nmax, ++ mbf_char_t delim1, mbf_char_t delim2, mb_file_t *stream) ++{ ++/* The maximum value that getndelim2 can return without suffering from ++ overflow problems, either internally (because of pointer ++ subtraction overflow) or due to the API (because of ssize_t). */ ++#define GETNDELIM2_MAXIMUM (PTRDIFF_MAX < SSIZE_MAX ? PTRDIFF_MAX : SSIZE_MAX) ++ ++/* Try to add at least this many bytes when extending the buffer. ++ MIN_CHUNK must be no greater than GETNDELIM2_MAXIMUM. */ ++#define MIN_CHUNK 64 ++ size_t nchars_avail; /* Allocated but unused chars in *LINEPTR. */ ++ mbf_char_t *read_pos; /* Where we're reading into *LINEPTR. */ ++ ssize_t chars_stored = -1; ++ mbf_char_t *ptr = *lineptr; ++ size_t size = *linesize; ++ bool found_delimiter; ++ ++ if (!ptr) ++ { ++ size = nmax < MIN_CHUNK ? nmax : MIN_CHUNK; ++ ptr = malloc (size * sizeof (mbf_char_t)); ++ if (!ptr) ++ return -1; ++ } ++ ++ if (size < 0) ++ goto done; ++ ++ nchars_avail = size; ++ read_pos = ptr; ++ ++ if (nchars_avail == 0 && nmax <= size) ++ goto done; ++ ++ /* Normalize delimiters, since memchr2 doesn't handle EOF. */ ++ if (mb_iseof (delim1)) ++ mb_copy (&delim1, &delim2); ++ else if (mb_iseof (delim2)) ++ mb_copy (&delim2, &delim1); ++ ++ flockfile (stream); ++ ++ found_delimiter = false; ++ do ++ { ++ /* Here always ptr + size == read_pos + nchars_avail. ++ Also nchars_avail > 0 || size < nmax. */ ++ ++ mbf_char_t c IF_LINT (= 0); ++ { ++ mbf_getc (c, *stream); ++ if (mb_iseof (c)) ++ { ++ /* Return partial line, if any. */ ++ if (read_pos == ptr) ++ goto unlock_done; ++ else ++ break; ++ } ++ if (mb_equal (c, delim1) || mb_equal (c, delim2)) ++ found_delimiter = true; ++ } ++ ++ /* We always want at least one byte left in the buffer, since we ++ always (unless we get an error while reading the first byte) ++ NUL-terminate the line buffer. */ ++ ++ if (!nchars_avail) ++ { ++ /* Grow size proportionally, not linearly, to avoid O(n^2) ++ running time. */ ++ size_t newsize = size < MIN_CHUNK ? size + MIN_CHUNK : 2 * size; ++ mbf_char_t *newptr; ++ ++ /* Respect nmax. This handles possible integer overflow. */ ++ if (! (size < newsize && newsize <= nmax)) ++ newsize = nmax; ++ ++ if (GETNDELIM2_MAXIMUM < newsize) ++ { ++ size_t newsizemax = GETNDELIM2_MAXIMUM + 1; ++ if (size == newsizemax) ++ goto unlock_done; ++ newsize = newsizemax; ++ } ++ nchars_avail = newsize - (read_pos - ptr); ++ newptr = realloc (ptr, newsize * sizeof (mbf_char_t)); ++ if (!newptr) ++ goto unlock_done; ++ ptr = newptr; ++ size = newsize; ++ read_pos = size - nchars_avail + ptr; ++ } ++ ++ /* Here, if size < nmax, nchars_avail >= buffer_len + 1. ++ If size == nmax, nchars_avail > 0. */ ++ ++ if (1 < nchars_avail) ++ { ++ mb_copy(read_pos++, &c); ++ --nchars_avail; ++ } ++ ++ } ++ while (!found_delimiter); ++ ++ chars_stored = (read_pos - ptr); ++ ++ unlock_done: ++ funlockfile (stream); ++ ++ done: ++ *lineptr = ptr; ++ *linesize = size; ++ return chars_stored; ++} ++ ++static void ++cut_chars (FILE *stream) ++{ ++ size_t char_idx; /* Number of chars in the line so far. */ ++ bool print_delimiter; ++ mbf_char_t c; ++ mb_file_t mbf; ++ ++ print_delimiter = false; ++ char_idx = 0; ++ current_rp = rp; ++ ++ mbf_init (mbf, stream); ++ while (true) ++ { ++ mbf_getc (c, mbf); ++ ++ if (mb_iseq (c, '\n')) ++ { ++ putc ('\n', stdout); ++ char_idx = 0; ++ print_delimiter = false; ++ current_rp = rp; ++ } ++ else if (mb_iseof (c)) ++ { ++ if (char_idx > 0) ++ putc ('\n', stdout); ++ break; ++ } ++ else ++ { ++ /* Forward by one byte. */ ++ next_item (&char_idx); ++ ++ /* Check if the current characters byte range is within ++ * the argument list. */ ++ if (rp_intersect (char_idx, char_idx + mb_len (c) - 1)) ++ { ++ if (output_delimiter_specified) ++ { ++ if (print_delimiter && is_range_start_index (char_idx)) ++ { ++ fwrite (output_delimiter_string, sizeof (char), ++ output_delimiter_length, stdout); ++ } ++ print_delimiter = true; ++ } ++ mb_putc (c, stdout); ++ } ++ ++ /* Byte mode with multibyte characters uncut (-b -n). */ ++ if (no_break_mb_chars) ++ /* Forward by an additional byte_length (c) - 1. */ ++ next_item_n (&char_idx, mb_len (c) - 1); ++ } ++ } ++} + + static void + cut_fields (FILE *stream) + { +- int c; ++ ++ /* 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 ++ first field must be read into this buffer to determine whether it ++ is followed by a delimiter or a newline before any of it may be ++ output. Otherwise, cut_fields can do the job without using this ++ buffer. */ ++ mbf_char_t *field_1_buffer = 0; ++ /* The number of bytes allocated for FIELD_1_BUFFER. */ ++ size_t field_1_bufsize; ++ ++ ++ mbf_char_t c, d; ++ mb_file_t mbf; + size_t field_idx = 1; + bool found_any_selected_field = false; + bool buffer_first_field; + + current_rp = rp; + +- c = getc (stream); +- if (c == EOF) ++ mbf_init (mbf, stream); ++ mbf_getc (c, mbf); ++ if (mb_iseof (c)) + return; + +- ungetc (c, stream); +- c = 0; ++ mbf_ungetc (c, mbf); ++ mb_setascii (&c, 0); ++ mb_copy (&d, &delim); + + /* To support the semantics of the -s flag, we may have to buffer + all of the first field to determine whether it is 'delimited.' +@@ -536,10 +744,14 @@ cut_fields (FILE *stream) + if (field_idx == 1 && buffer_first_field) + { + ssize_t len; +- size_t n_bytes; ++ size_t n_chars; ++ mbf_char_t nl; ++ mb_setascii (&nl, '\n'); ++ ++ len = mb_getndelim2 (&field_1_buffer, &field_1_bufsize, ++ GETNLINE_NO_LIMIT, d, nl, &mbf); ++ + +- len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0, +- GETNLINE_NO_LIMIT, delim, '\n', stream); + if (len < 0) + { + free (field_1_buffer); +@@ -549,15 +761,15 @@ cut_fields (FILE *stream) + xalloc_die (); + } + +- n_bytes = len; +- assert (n_bytes != 0); ++ n_chars = len; ++ //assert (n_chars != 0); + +- c = 0; ++ mb_setascii (&c, 0); + + /* 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 (to_uchar (field_1_buffer[n_bytes - 1]) != delim) ++ if (!mb_equal (field_1_buffer[n_chars - 1], d)) + { + if (suppress_non_delimited) + { +@@ -565,26 +777,30 @@ cut_fields (FILE *stream) + } + else + { +- fwrite (field_1_buffer, sizeof (char), n_bytes, stdout); ++ for (int i = 0; i < n_chars; ++i) ++ mb_putc (field_1_buffer[i], stdout); ++ + /* Make sure the output line is newline terminated. */ +- if (field_1_buffer[n_bytes - 1] != '\n') ++ if (!mb_iseq (field_1_buffer[n_chars - 1], '\n')) + putchar ('\n'); +- c = '\n'; ++ mb_setascii (&c,'\n'); + } + continue; + } + if (print_kth (1)) + { + /* Print the field, but not the trailing delimiter. */ +- fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout); ++ for (int i = 0; i < n_chars - 1; ++i) ++ mb_putc (field_1_buffer[i], stdout); + + /* With -d$'\n' don't treat the last '\n' as a delimiter. */ +- if (delim == '\n') ++ if (mb_iseq (d, '\n')) + { +- int last_c = getc (stream); +- if (last_c != EOF) ++ mbf_char_t last_c; ++ mbf_getc (last_c, mbf); ++ if (!mb_iseof (last_c)) + { +- ungetc (last_c, stream); ++ mbf_ungetc (last_c, mbf); + found_any_selected_field = true; + } + } +@@ -594,7 +810,8 @@ cut_fields (FILE *stream) + next_item (&field_idx); + } + +- int prev_c = c; ++ mbf_char_t prev_c; ++ mb_copy (&prev_c, &c); + + if (print_kth (field_idx)) + { +@@ -605,41 +822,46 @@ cut_fields (FILE *stream) + } + found_any_selected_field = true; + +- while ((c = getc (stream)) != delim && c != '\n' && c != EOF) ++ mbf_getc (c, mbf); ++ while (!mb_equal (c, d) && !mb_iseq (c, '\n') && !mb_iseof (c)) + { +- putchar (c); +- prev_c = c; ++ mb_putc (c, stdout); ++ mb_copy (&prev_c, &c); ++ mbf_getc (c, mbf); + } + } + else + { +- while ((c = getc (stream)) != delim && c != '\n' && c != EOF) ++ mbf_getc (c, mbf); ++ while (!mb_equal (c, d) && !mb_iseq (c, '\n') && !mb_iseof (c)) + { +- prev_c = c; ++ mb_copy (&prev_c, &c); ++ mbf_getc (c, mbf); + } + } + + /* With -d$'\n' don't treat the last '\n' as a delimiter. */ +- if (delim == '\n' && c == delim) ++ if (mb_iseq (d, '\n') && mb_equal (c, d)) + { +- int last_c = getc (stream); +- if (last_c != EOF) +- ungetc (last_c, stream); ++ mbf_char_t last_c; ++ mbf_getc (last_c, mbf); ++ if (!mb_iseof (last_c)) ++ mbf_ungetc (last_c, mbf); + else +- c = last_c; ++ mb_copy (&c, &last_c); + } + +- if (c == delim) ++ if (mb_equal (c, d)) + next_item (&field_idx); +- else if (c == '\n' || c == EOF) ++ else if (mb_iseq (c, '\n') || mb_iseof (c)) + { + if (found_any_selected_field + || !(suppress_non_delimited && field_idx == 1)) + { +- if (c == '\n' || prev_c != '\n' || delim == '\n') ++ if (mb_iseq (c, '\n') || !mb_iseq (prev_c, '\n') || mb_iseq (d, '\n')) + putchar ('\n'); + } +- if (c == EOF) ++ if (mb_iseof (c)) + break; + field_idx = 1; + current_rp = rp; +@@ -652,7 +874,14 @@ static void + cut_stream (FILE *stream) + { + if (operating_mode == byte_mode) +- cut_bytes (stream); ++ { ++ if (no_break_mb_chars) ++ cut_chars (stream); ++ else ++ cut_bytes (stream); ++ } ++ else if (operating_mode == char_mode) ++ cut_chars (stream); + else + cut_fields (stream); + } +@@ -706,6 +935,7 @@ main (int argc, char **argv) + bool ok; + bool delim_specified = false; + char *spec_list_string IF_LINT ( = NULL); ++ mbi_iterator_t iter; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -719,8 +949,10 @@ main (int argc, char **argv) + + /* By default, all non-delimited lines are printed. */ + suppress_non_delimited = false; ++ /* Default behaviour for -b, unless -n is also specified. */ ++ no_break_mb_chars = false; + +- delim = '\0'; ++ mb_setascii (&delim, '\0'); + have_read_stdin = false; + + while ((optc = getopt_long (argc, argv, "b:c:d:f:ns", longopts, NULL)) != -1) +@@ -728,7 +960,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")); +@@ -736,6 +967,14 @@ main (int argc, char **argv) + spec_list_string = optarg; + break; + ++ case 'c': ++ /* Build the char list. */ ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = char_mode; ++ spec_list_string = optarg; ++ break; ++ + case 'f': + /* Build the field list. */ + if (operating_mode != undefined_mode) +@@ -747,9 +986,15 @@ 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') ++ mbi_init (iter, optarg, strlen (optarg)); ++ if (!mbi_avail (iter)) ++ mb_setascii (&delim, '\0'); ++ else ++ mb_copy (&delim, &mbi_cur (iter)); ++ ++ mbi_advance (iter); ++ if (mbi_avail (iter)) + FATAL_ERROR (_("the delimiter must be a single character")); +- delim = optarg[0]; + delim_specified = true; + break; + +@@ -763,6 +1008,7 @@ main (int argc, char **argv) + break; + + case 'n': ++ no_break_mb_chars = true; + break; + + case 's': +@@ -802,15 +1048,12 @@ main (int argc, char **argv) + } + + if (!delim_specified) +- delim = '\t'; ++ mb_setascii (&delim, '\t'); + + if (output_delimiter_string == NULL) + { +- static char dummy[2]; +- dummy[0] = delim; +- dummy[1] = '\0'; +- output_delimiter_string = dummy; +- output_delimiter_length = 1; ++ output_delimiter_string = mb_ptr (delim); ++ output_delimiter_length = mb_len (delim); + } + + if (optind == argc) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 5d3a591..e876fe3 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -23,579 +23,6 @@ diff -urNp coreutils-8.24-orig/lib/linebuffer.h coreutils-8.24/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.24-orig/src/cut.c coreutils-8.24/src/cut.c ---- coreutils-8.24-orig/src/cut.c 2015-06-26 19:05:22.000000000 +0200 -+++ coreutils-8.24/src/cut.c 2015-07-05 09:04:33.028546950 +0200 -@@ -28,6 +28,11 @@ - #include - #include - #include -+ -+/* Get mbstate_t, mbrtowc(). */ -+#if HAVE_WCHAR_H -+# include -+#endif - #include "system.h" - - #include "error.h" -@@ -37,6 +42,18 @@ - #include "quote.h" - #include "xstrndup.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" - -@@ -53,6 +70,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) -+ - - struct range_pair - { -@@ -75,6 +138,8 @@ static size_t n_rp; - /* Number of `struct range_pair's allocated. */ - static size_t n_rp_allocated; - -+/* Length of the delimiter given as argument to -d. */ -+size_t delimlen; - - /* Append LOW, HIGH to the list RP of range pairs, allocating additional - space if necessary. Update global variable N_RP. When allocating, -@@ -106,15 +171,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. */ -@@ -126,6 +201,9 @@ static bool complement; - - /* The delimiter character for field mode. */ - static unsigned char delim; -+#if HAVE_WCHAR_H -+static wchar_t wcdelim; -+#endif - - /* True if the --output-delimiter=STRING option was specified. */ - static bool output_delimiter_specified; -@@ -189,7 +267,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\ -@@ -380,6 +458,9 @@ set_fields (const char *fieldstr) - if (operating_mode == byte_mode) - error (0, 0, - _("byte offset %s is too large"), quote (bad_num)); -+ else if (operating_mode == character_mode) -+ error (0, 0, -+ _("character offset %s is too large"), quote (bad_num)); - else - error (0, 0, - _("field number %s is too large"), quote (bad_num)); -@@ -504,6 +585,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) -+{ -+ size_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 = rp; -+ -+ 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 ('\n'); -+ break; -+ } -+ else if (wc == L'\n') -+ { -+ putchar ('\n'); -+ idx = 0; -+ print_delimiter = false; -+ current_rp = rp; -+ } -+ 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 -@@ -648,13 +805,211 @@ cut_fields (FILE *stream) - } - } - -+#if HAVE_MBRTOWC -+static void -+cut_fields_mb (FILE *stream) -+{ -+ int c; -+ size_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 = rp; -+ -+ 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 == L'\n' || 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 != L'\n')) -+ putchar ('\n'); -+ } -+ 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 == L'\n')) -+ { -+ buflen -= mblength; -+ bufpos += mblength; -+ break; -+ } -+ -+ if (print_kth (field_idx)) -+ fwrite (bufpos, mblength, sizeof(char), stdout); -+ -+ buflen -= mblength; -+ bufpos += mblength; -+ } -+ } -+ -+ if ((!convfail || wc == L'\n') && buflen < 1) -+ wc = WEOF; -+ -+ if (!convfail && wc == wcdelim) -+ next_item (&field_idx); -+ else if (wc == WEOF || (!convfail && wc == L'\n')) -+ { -+ if (found_any_selected_field -+ || (!empty_input && !(suppress_non_delimited && field_idx == 1))) -+ putchar ('\n'); -+ if (wc == WEOF) -+ break; -+ field_idx = 1; -+ current_rp = rp; -+ 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. -@@ -706,6 +1061,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]); -@@ -728,7 +1084,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")); -@@ -736,6 +1091,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) -@@ -747,10 +1110,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: -@@ -763,6 +1154,7 @@ main (int argc, char **argv) - break; - - case 'n': -+ byte_mode_character_aware = 1; - break; - - case 's': -@@ -802,15 +1194,34 @@ main (int argc, char **argv) - } - - 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) diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c --- coreutils-8.24-orig/src/fold.c 2015-06-26 19:05:22.000000000 +0200 +++ coreutils-8.24/src/fold.c 2015-07-05 09:04:33.029546958 +0200 diff --git a/coreutils.spec b/coreutils.spec index 31cba83..a4c3ed1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 106%{?dist} +Release: 107%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -52,6 +52,8 @@ Patch713: coreutils-4.5.3-langinfo.patch Patch800: coreutils-i18n.patch # (sb) lin18nux/lsb compliance - expand/unexpand Patch801: coreutils-i18n-expand-unexpand.patch +# (sb) lin18nux/lsb compliance - cut +Patch802: coreutils-i18n-cut.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch @@ -184,6 +186,7 @@ including documentation and translations. # li18nux/lsb %patch800 -p1 -b .i18n %patch801 -p1 -b .i18n-expand +%patch802 -p1 -b .i18n-cut # Coreutils %patch908 -p1 -b .getgrouplist @@ -356,6 +359,9 @@ fi %license COPYING %changelog +* Fri Jan 15 2016 Ondrej Oprala - 8.24-107 +- Use the new i18n implementation for the cut utility + * Wed Jan 13 2016 Ondrej Vasik - 8.24-106 - mv: prevent dataloss when source dir is specified multiple times (#1297464, by P.Brady) From 11e5aa1d55d932ecf9680e860a968b5652d25dbb Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Fri, 15 Jan 2016 11:02:13 +0100 Subject: [PATCH 291/523] cut: be MB for ALL archs --- coreutils-i18n-cut.patch | 10 ++++++---- coreutils.spec | 5 ++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/coreutils-i18n-cut.patch b/coreutils-i18n-cut.patch index b300eac..0c694ed 100644 --- a/coreutils-i18n-cut.patch +++ b/coreutils-i18n-cut.patch @@ -536,7 +536,7 @@ case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -747,9 +986,15 @@ main (int argc, char **argv) +@@ -747,9 +986,17 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -545,11 +545,13 @@ + if (!mbi_avail (iter)) + mb_setascii (&delim, '\0'); + else -+ mb_copy (&delim, &mbi_cur (iter)); ++ { ++ mb_copy (&delim, &mbi_cur (iter)); + -+ mbi_advance (iter); -+ if (mbi_avail (iter)) ++ mbi_advance (iter); ++ if (mbi_avail (iter)) FATAL_ERROR (_("the delimiter must be a single character")); ++ } - delim = optarg[0]; delim_specified = true; break; diff --git a/coreutils.spec b/coreutils.spec index a4c3ed1..c122e22 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.24 -Release: 107%{?dist} +Release: 108%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -359,6 +359,9 @@ fi %license COPYING %changelog +* Fri Jan 15 2016 Ondrej Oprala - 8.24-108 +- cut: be MB for ALL archs + * Fri Jan 15 2016 Ondrej Oprala - 8.24-107 - Use the new i18n implementation for the cut utility From 7d9c9afa38925b51a69b0eb68a43d6d181a1f2e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Wed, 20 Jan 2016 16:43:39 +0100 Subject: [PATCH 292/523] Initial commit for coreutils 8.25 ... still need to fix two failing tests before build (likely i18n stuff) --- .gitignore | 1 + coreutils-6.10-manpages.patch | 2 +- coreutils-7.4-sttytcsadrain.patch | 12 -- coreutils-8.24-mv-duplicate-sources.patch | 119 ------------------- coreutils-i18n-cut.patch | 69 +++++------ coreutils-i18n-expand-unexpand.patch | 12 +- coreutils-i18n.patch | 38 +----- coreutils-remove-test-update-copyright.patch | 50 -------- coreutils.spec | 22 +--- glibc-2.22-test-fix.patch | 83 ------------- sources | 3 +- 11 files changed, 56 insertions(+), 355 deletions(-) delete mode 100644 coreutils-7.4-sttytcsadrain.patch delete mode 100644 coreutils-8.24-mv-duplicate-sources.patch delete mode 100644 coreutils-remove-test-update-copyright.patch delete mode 100644 glibc-2.22-test-fix.patch diff --git a/.gitignore b/.gitignore index 8f473b3..9b1b40a 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ /coreutils-8.23.tar.xz.sig /coreutils-8.24.tar.xz /coreutils-8.24.tar.xz.sig +/coreutils-8.25.tar.xz diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index 3f5d37b..8d5bc94 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -10,4 +10,4 @@ diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c +"), stdout); fputs (_("\ \n\ - The following four options are useful only when verifying checksums:\n\ + The following five options are useful only when verifying checksums:\n\ diff --git a/coreutils-7.4-sttytcsadrain.patch b/coreutils-7.4-sttytcsadrain.patch deleted file mode 100644 index bc3f47b..0000000 --- a/coreutils-7.4-sttytcsadrain.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -urNp coreutils-8.13-orig/src/stty.c coreutils-8.13/src/stty.c ---- coreutils-8.13-orig/src/stty.c 2011-07-28 12:38:27.000000000 +0200 -+++ coreutils-8.13/src/stty.c 2011-09-09 10:18:57.526687209 +0200 -@@ -1005,7 +1005,7 @@ main (int argc, char **argv) - spurious difference in an uninitialized portion of the structure. */ - static struct termios new_mode; - -- if (tcsetattr (STDIN_FILENO, TCSADRAIN, &mode)) -+ if (tcsetattr (STDIN_FILENO, TCSANOW, &mode)) - error (EXIT_FAILURE, errno, "%s", device_name); - - /* POSIX (according to Zlotnick's book) tcsetattr returns zero if diff --git a/coreutils-8.24-mv-duplicate-sources.patch b/coreutils-8.24-mv-duplicate-sources.patch deleted file mode 100644 index f518cc6..0000000 --- a/coreutils-8.24-mv-duplicate-sources.patch +++ /dev/null @@ -1,119 +0,0 @@ -@@ -, +, @@ - destination - mv dir dir dir ---- - src/copy.c | 12 +++++++---- - tests/local.mk | 1 - - tests/mv/dup-source.sh | 46 +++++++++++++++++++++++++++++++++---------- - 3 files changed, 44 insertions(+), 15 deletions(-) ---- a/src/copy.c -+++ a/src/copy.c -@@ -2278,10 +2278,14 @@ copy_internal (char const *src_name, char const *dst_name, - error (0, 0, _("warning: source directory %s " - "specified more than once"), - quote (top_level_src_name)); -- /* We only do backups in move mode and for non dirs, -- and in move mode this won't be the issue as the source will -- be missing for subsequent attempts. -- There we just warn and return here. */ -+ /* In move mode, if a previous rename succeeded, then -+ we won't be in this path as the source is missing. If the -+ rename previously failed, then that has been handled. -+ Pretend this instance succeeded so the source isn't removed. */ -+ if (x->move_mode && rename_succeeded) -+ *rename_succeeded = true; -+ /* We only do backups in move mode, and for non directories. -+ So just ignore this repeated entry. */ - return true; - } - else if (x->dereference == DEREF_ALWAYS ---- a/tests/local.mk -+++ a/tests/local.mk -@@ -443,7 +443,6 @@ all_tests = \ - tests/cp/dir-rm-dest.sh \ - tests/cp/dir-slash.sh \ - tests/cp/dir-vs-file.sh \ -- tests/cp/duplicate-sources.sh \ - tests/cp/existing-perm-dir.sh \ - tests/cp/existing-perm-race.sh \ - tests/cp/fail-perm.sh \ ---- a/tests/mv/dup-source.sh -+++ a/tests/mv/dup-source.sh -@@ -24,25 +24,37 @@ print_ver_ cp mv - - skip_if_root_ - -+reset_files() { rm -fr a b d; touch a; mkdir b d; } -+ - for i in cp; do - - # cp may not fail in this case. -- -- rm -fr a d; touch a; mkdir d -+ reset_files - $i a a d/ 2> out || fail=1 -- rm -fr a d; touch a; mkdir d -+ reset_files - $i ./a a d/ 2>> out || fail=1 - -+ # Similarly for directories, but handle -+ # source == dest appropriately. -+ reset_files -+ $i -a ./b b d/ 2>> out || fail=1 -+ reset_files -+ returns_ 1 $i -a ./b b b/ 2>> out || fail=1 -+ - # cp succeeds with --backup=numbered. -- rm -fr a d; touch a; mkdir d -+ reset_files - $i --backup=numbered a a d/ 2>> out || fail=1 - - # But not with plain '--backup' -- rm -fr a d; touch a; mkdir d -- $i --backup a a d/ 2>> out && fail=1 -+ reset_files -+ returns_ 1 $i --backup a a d/ 2>> out || fail=1 -+ - cat < exp - $i: warning: source file 'a' specified more than once - $i: warning: source file 'a' specified more than once -+$i: warning: source directory 'b' specified more than once -+$i: cannot copy a directory, './b', into itself, 'b/b' -+$i: warning: source directory 'b' specified more than once - $i: will not overwrite just-created 'd/a' with 'a' - EOF - compare exp out || fail=1 -@@ -50,14 +62,28 @@ done - - for i in mv; do - # But mv *does* fail in this case (it has to). -+ reset_files -+ returns_ 1 $i a a d/ 2> out || fail=1 -+ returns_ 1 test -e a || fail=1 -+ reset_files -+ returns_ 1 $i ./a a d/ 2>> out || fail=1 -+ returns_ 1 test -e a || fail=1 -+ -+ # Similarly for directories, also handling -+ # source == dest appropriately. -+ reset_files -+ returns_ 1 $i ./b b d/ 2>> out || fail=1 -+ returns_ 1 test -e b || fail=1 -+ reset_files -+ returns_ 1 $i --verbose ./b b b/ 2>> out || fail=1 -+ test -d b || fail=1 - -- rm -fr a d; touch a; mkdir d -- $i a a d/ 2> out && fail=1 -- rm -fr a d; touch a; mkdir d -- $i ./a a d/ 2>> out && fail=1 - cat < exp - $i: cannot stat 'a': No such file or directory - $i: cannot stat 'a': No such file or directory -+$i: cannot stat 'b': No such file or directory -+$i: cannot move './b' to a subdirectory of itself, 'b/b' -+$i: warning: source directory 'b' specified more than once - EOF - compare exp out || fail=1 - done --- diff --git a/coreutils-i18n-cut.patch b/coreutils-i18n-cut.patch index 0c694ed..ab72147 100644 --- a/coreutils-i18n-cut.patch +++ b/coreutils-i18n-cut.patch @@ -13,8 +13,8 @@ #include "error.h" @@ -90,25 +95,16 @@ add_range_pair (size_t lo, size_t hi) - ++n_rp; - } + CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ + static struct field_range_pair *current_rp; -/* This buffer is used to support the semantics of the -s option - (or lack of same) when the specified field list includes (does @@ -58,8 +58,8 @@ -static unsigned char delim; +static mbf_char_t delim; - /* True if the --output-delimiter=STRING option was specified. */ - static bool output_delimiter_specified; + /* The delimiter for each line/record. */ + static unsigned char line_delim = '\n'; @@ -135,7 +135,7 @@ static size_t output_delimiter_length; /* The output field separator string. Defaults to the 1-character @@ -240,24 +240,24 @@ + + print_delimiter = false; + char_idx = 0; -+ current_rp = rp; ++ current_rp = frp; + + mbf_init (mbf, stream); + while (true) + { + mbf_getc (c, mbf); + -+ if (mb_iseq (c, '\n')) ++ if (mb_iseq (c, line_delim)) + { -+ putc ('\n', stdout); ++ putc (line_delim, stdout); + char_idx = 0; + print_delimiter = false; -+ current_rp = rp; ++ current_rp = frp; + } + else if (mb_iseof (c)) + { + if (char_idx > 0) -+ putc ('\n', stdout); ++ putc (line_delim, stdout); + break; + } + else @@ -312,7 +312,7 @@ bool found_any_selected_field = false; bool buffer_first_field; - current_rp = rp; + current_rp = frp; - c = getc (stream); - if (c == EOF) @@ -336,14 +336,14 @@ - size_t n_bytes; + size_t n_chars; + mbf_char_t nl; -+ mb_setascii (&nl, '\n'); ++ mb_setascii (&nl, line_delim); + + len = mb_getndelim2 (&field_1_buffer, &field_1_bufsize, + GETNLINE_NO_LIMIT, d, nl, &mbf); + - len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0, -- GETNLINE_NO_LIMIT, delim, '\n', stream); +- GETNLINE_NO_LIMIT, delim, line_delim, stream); if (len < 0) { free (field_1_buffer); @@ -376,11 +376,11 @@ + mb_putc (field_1_buffer[i], stdout); + /* Make sure the output line is newline terminated. */ -- if (field_1_buffer[n_bytes - 1] != '\n') -+ if (!mb_iseq (field_1_buffer[n_chars - 1], '\n')) - putchar ('\n'); -- c = '\n'; -+ mb_setascii (&c,'\n'); +- if (field_1_buffer[n_bytes - 1] != line_delim) ++ if (!mb_iseq (field_1_buffer[n_chars - 1], line_delim)) + putchar (line_delim); +- c = line_delim; ++ mb_setascii (&c, line_delim); } continue; } @@ -392,8 +392,8 @@ + mb_putc (field_1_buffer[i], stdout); /* With -d$'\n' don't treat the last '\n' as a delimiter. */ -- if (delim == '\n') -+ if (mb_iseq (d, '\n')) +- if (delim == line_delim) ++ if (mb_iseq (d, line_delim)) { - int last_c = getc (stream); - if (last_c != EOF) @@ -416,13 +416,13 @@ if (print_kth (field_idx)) { -@@ -605,41 +822,46 @@ cut_fields (FILE *stream) +@@ -605,42 +822,46 @@ cut_fields (FILE *stream) } found_any_selected_field = true; -- while ((c = getc (stream)) != delim && c != '\n' && c != EOF) +- while ((c = getc (stream)) != delim && c != line_delim && c != EOF) + mbf_getc (c, mbf); -+ while (!mb_equal (c, d) && !mb_iseq (c, '\n') && !mb_iseof (c)) ++ while (!mb_equal (c, d) && !mb_iseq (c, line_delim) && !mb_iseof (c)) { - putchar (c); - prev_c = c; @@ -433,9 +433,9 @@ } else { -- while ((c = getc (stream)) != delim && c != '\n' && c != EOF) +- while ((c = getc (stream)) != delim && c != line_delim && c != EOF) + mbf_getc (c, mbf); -+ while (!mb_equal (c, d) && !mb_iseq (c, '\n') && !mb_iseof (c)) ++ while (!mb_equal (c, d) && !mb_iseq (c, line_delim) && !mb_iseof (c)) { - prev_c = c; + mb_copy (&prev_c, &c); @@ -444,8 +444,8 @@ } /* With -d$'\n' don't treat the last '\n' as a delimiter. */ -- if (delim == '\n' && c == delim) -+ if (mb_iseq (d, '\n') && mb_equal (c, d)) +- if (delim == line_delim && c == delim) ++ if (mb_iseq (d, line_delim) && mb_equal (c, d)) { - int last_c = getc (stream); - if (last_c != EOF) @@ -462,21 +462,22 @@ - if (c == delim) + if (mb_equal (c, d)) next_item (&field_idx); -- else if (c == '\n' || c == EOF) -+ else if (mb_iseq (c, '\n') || mb_iseof (c)) +- else if (c == line_delim || c == EOF) ++ else if (mb_iseq (c, line_delim) || mb_iseof (c)) { if (found_any_selected_field || !(suppress_non_delimited && field_idx == 1)) { -- if (c == '\n' || prev_c != '\n' || delim == '\n') -+ if (mb_iseq (c, '\n') || !mb_iseq (prev_c, '\n') || mb_iseq (d, '\n')) - putchar ('\n'); +- if (c == line_delim || prev_c != line_delim +- || delim == line_delim) ++ if (mb_iseq (c, line_delim) || !mb_iseq (prev_c, line_delim) || mb_iseq (d, line_delim)) + putchar (line_delim); } - if (c == EOF) + if (mb_iseof (c)) break; field_idx = 1; - current_rp = rp; + current_rp = frp; @@ -652,7 +874,14 @@ static void cut_stream (FILE *stream) { @@ -512,7 +513,7 @@ + mb_setascii (&delim, '\0'); have_read_stdin = false; - while ((optc = getopt_long (argc, argv, "b:c:d:f:ns", longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, "b:c:d:f:nsz", longopts, NULL)) != -1) @@ -728,7 +960,6 @@ main (int argc, char **argv) switch (optc) { @@ -565,7 +566,7 @@ case 's': @@ -802,15 +1048,12 @@ main (int argc, char **argv) - } + | (complement ? SETFLD_COMPLEMENT : 0) ); if (!delim_specified) - delim = '\t'; diff --git a/coreutils-i18n-expand-unexpand.patch b/coreutils-i18n-expand-unexpand.patch index 63813f9..d8a5968 100644 --- a/coreutils-i18n-expand-unexpand.patch +++ b/coreutils-i18n-expand-unexpand.patch @@ -433,14 +433,14 @@ index 0a40a1a..ed97fd4 100644 - { - if (ferror (fp)) - { -- error (0, errno, "%s", prev_file); +- error (0, errno, "%s", quotef (prev_file)); - exit_status = EXIT_FAILURE; - } - if (STREQ (prev_file, "-")) - clearerr (fp); /* Also clear EOF. */ - else if (fclose (fp) != 0) - { -- error (0, errno, "%s", prev_file); +- error (0, errno, "%s", quotef (prev_file)); - exit_status = EXIT_FAILURE; - } - } @@ -460,7 +460,7 @@ index 0a40a1a..ed97fd4 100644 - fadvise (fp, FADVISE_SEQUENTIAL); - return fp; - } -- error (0, errno, "%s", file); +- error (0, errno, "%s", quotef (file)); - exit_status = EXIT_FAILURE; - } - return NULL; @@ -748,14 +748,14 @@ index e0f7c22..48fbb32 100644 - { - if (ferror (fp)) - { -- error (0, errno, "%s", prev_file); +- error (0, errno, "%s", quotef (prev_file)); - exit_status = EXIT_FAILURE; - } - if (STREQ (prev_file, "-")) - clearerr (fp); /* Also clear EOF. */ - else if (fclose (fp) != 0) - { -- error (0, errno, "%s", prev_file); +- error (0, errno, "%s", quotef (prev_file)); - exit_status = EXIT_FAILURE; - } - } @@ -775,7 +775,7 @@ index e0f7c22..48fbb32 100644 - fadvise (fp, FADVISE_SEQUENTIAL); - return fp; - } -- error (0, errno, "%s", file); +- error (0, errno, "%s", quotef (file)); - exit_status = EXIT_FAILURE; - } - return NULL; diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e876fe3..0538a64 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -150,7 +150,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c - - if (istream == NULL) - { -- error (0, errno, "%s", filename); +- error (0, errno, "%s", quotef (filename)); - return false; - } @@ -394,7 +394,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c + if (ferror (istream)) { - error (0, saved_errno, "%s", filename); + error (0, saved_errno, "%s", quotef (filename)); @@ -251,7 +498,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -493,7 +493,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c + else { /* Skip leading blanks before the first field. */ - while (isblank (to_uchar (*ptr))) + while (field_sep (*ptr)) @@ -305,6 +322,147 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1240,7 +1240,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c - clump_buff = xmalloc (MAX (8, chars_per_input_tab)); + clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab)); } - + /* Open the necessary files, @@ -1383,7 +1506,7 @@ init_funcs (void) @@ -2685,33 +2685,6 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c } break; -@@ -4681,10 +5374,10 @@ main (int argc, char **argv) - - if (nfiles == 0) - { -- static char *minus = (char *) "-"; - nfiles = 1; - free (files); -- files = − -+ files = xmalloc (sizeof *files); -+ *files = (char *) "-"; - } - - /* Need to re-check that we meet the minimum requirement for memory -@@ -4742,6 +5435,13 @@ 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) - die (_("close failed"), "-"); - diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c --- coreutils-8.24-orig/src/uniq.c 2015-06-26 19:04:19.000000000 +0200 +++ coreutils-8.24/src/uniq.c 2015-07-05 09:04:33.032546980 +0200 @@ -2733,12 +2706,13 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -32,7 +43,19 @@ +@@ -32,8 +43,20 @@ #include "stdio--.h" #include "xmemcoll.h" #include "xstrtol.h" -#include "memcasecmp.h" +#include "xmemcoll.h" + #include "quote.h" + +/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC + installation; work around this configuration error. */ diff --git a/coreutils-remove-test-update-copyright.patch b/coreutils-remove-test-update-copyright.patch deleted file mode 100644 index 23ce342..0000000 --- a/coreutils-remove-test-update-copyright.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- coreutils-8.23/gnulib-tests/gnulib.mk.orig 2015-07-04 11:11:09.438579284 +0100 -+++ coreutils-8.23/gnulib-tests/gnulib.mk 2015-07-04 11:12:12.113643496 +0100 -@@ -2312,14 +2312,6 @@ - - ## end gnulib module unsetenv-tests - --## begin gnulib module update-copyright-tests -- --TESTS += test-update-copyright.sh --TESTS_ENVIRONMENT += abs_aux_dir='$(abs_aux_dir)' --EXTRA_DIST += test-update-copyright.sh -- --## end gnulib module update-copyright-tests -- - ## begin gnulib module userspec-tests - - TESTS += test-userspec ---- coreutils-8.23/gnulib-tests/Makefile.in.orig 2015-07-04 11:10:54.353323089 +0100 -+++ coreutils-8.23/gnulib-tests/Makefile.in 2015-07-04 11:12:45.542210970 +0100 -@@ -220,7 +220,6 @@ - test-u8-mbtoucr$(EXEEXT) test-u8-uctomb$(EXEEXT) \ - test-uc_width$(EXEEXT) uniwidth/test-uc_width2.sh \ - test-unlink$(EXEEXT) test-unlinkat$(EXEEXT) \ -- test-unsetenv$(EXEEXT) test-update-copyright.sh \ - test-userspec$(EXEEXT) test-utimens$(EXEEXT) \ - test-utimensat$(EXEEXT) test-vasnprintf$(EXEEXT) \ - test-vasprintf-posix$(EXEEXT) test-vasprintf$(EXEEXT) \ -@@ -3766,7 +3765,7 @@ - uniwidth/test-uc_width2.sh macros.h test-unlink.h \ - test-unlink.c signature.h macros.h test-unlinkat.c \ - test-rmdir.h test-unlink.h signature.h macros.h unlinkdir.h \ -- test-unsetenv.c signature.h macros.h test-update-copyright.sh \ -+ test-unsetenv.c signature.h macros.h \ - test-userspec.c nap.h test-futimens.h test-lutimens.h \ - test-utimens.h test-utimens-common.h test-utimens.c macros.h \ - nap.h test-lutimens.h test-utimens.h test-utimens-common.h \ -@@ -7787,13 +7786,6 @@ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ -- "$$tst" $(AM_TESTS_FD_REDIRECT) --test-update-copyright.sh.log: test-update-copyright.sh -- @p='test-update-copyright.sh'; \ -- b='test-update-copyright.sh'; \ -- $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ -- --log-file $$b.log --trs-file $$b.trs \ -- $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) - test-userspec.log: test-userspec$(EXEEXT) - @p='test-userspec$(EXEEXT)'; \ diff --git a/coreutils.spec b/coreutils.spec index c122e22..2e939fd 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.24 -Release: 108%{?dist} +Version: 8.25 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -21,27 +21,18 @@ Source10: coreutils-find-requires.sh %global __find_requires %{SOURCE10} %{_rpmconfigdir}/find-requires # From upstream -#mv: prevent dataloss when source directory is specified multiple t imes -Patch1: coreutils-8.24-mv-duplicate-sources.patch - # Our patches #general patch to workaround koji build system issues Patch100: coreutils-6.10-configuration.patch #add note about no difference between binary/text mode on Linux - md5sum manpage Patch101: coreutils-6.10-manpages.patch -#temporarily workaround probable kernel issue with TCSADRAIN(#504798) -Patch102: coreutils-7.4-sttytcsadrain.patch #do display processor type for uname -p/-i based on uname(2) syscall Patch103: coreutils-8.2-uname-processortype.patch #df --direct Patch104: coreutils-df-direct.patch #add note about mkdir --mode behaviour into info documentation(#610559) Patch107: coreutils-8.4-mkdir-modenote.patch -# Don't run the currently failing test-update-copyright.sh test -Patch108: coreutils-remove-test-update-copyright.patch -#avoid false failure due to extra stat() calls done by opendir() in glibc 2.22 -Patch109: glibc-2.22-test-fix.patch # sh-utils #add info about TZ envvar to date manpage @@ -172,12 +163,9 @@ including documentation and translations. # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages -%patch102 -p1 -b .tcsadrain %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect %patch107 -p1 -b .mkdirmode -%patch108 -p1 -b .crtest -%patch109 -p1 -b .opendir_stat # sh-utils %patch703 -p1 -b .dateman @@ -192,13 +180,12 @@ including documentation and translations. %patch908 -p1 -b .getgrouplist %patch912 -p1 -b .overflow %patch913 -p1 -b .testoff -%patch1 -p1 -b .dupl #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh tests/mv-dup-source.sh || : +chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh || : #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -359,6 +346,9 @@ fi %license COPYING %changelog +* Wed Jan 20 2016 Ondrej Vasik - 8.25-1 +- new upstream release(#1300282) + * Fri Jan 15 2016 Ondrej Oprala - 8.24-108 - cut: be MB for ALL archs diff --git a/glibc-2.22-test-fix.patch b/glibc-2.22-test-fix.patch deleted file mode 100644 index efbe850..0000000 --- a/glibc-2.22-test-fix.patch +++ /dev/null @@ -1,83 +0,0 @@ -From fd5f2b1569e2e0b31be755e14e236a7a02478fc0 Mon Sep 17 00:00:00 2001 -From: Bernhard Voelker -Date: Sun, 30 Aug 2015 22:49:35 +0200 -Subject: [PATCH] tests: avoid FP of ls/stat-free-color.sh with newer glibc - -Since glibc-2.22, specifically commit [0], the opendir() implementation -implicitly makes an additional stat call thus leading to a FP. -Seen on openSUSE:Tumbleweed since snapshot 20150821. - -[0] -https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=46f894d8c60a - -* tests/ls/stat-free-color.sh: Change the test to verify that ls(1) -needs the same number of stat-like calls for a single, empty directory -argument as for one with a few directory entries (sub-directory, -regular file, symlink, etc.). ---- - tests/ls/stat-free-color.sh | 39 ++++++++++++++++++++++++--------------- - 1 file changed, 24 insertions(+), 15 deletions(-) - -diff --git a/tests/ls/stat-free-color.sh b/tests/ls/stat-free-color.sh -index fb2ee8b..35816a3 100755 ---- a/tests/ls/stat-free-color.sh -+++ b/tests/ls/stat-free-color.sh -@@ -27,8 +27,6 @@ stats='stat,lstat,stat64,lstat64,newfstatat' - require_strace_ $stats - require_dirent_d_type_ - --ln -s nowhere dangle || framework_failure_ -- - # Disable enough features via LS_COLORS so that ls --color - # can do its job without calling stat (other than the obligatory - # one-call-per-command-line argument). -@@ -54,22 +52,33 @@ EOF - eval $(dircolors -b color-without-stat) - - # The system may perform additional stat-like calls before main. --# To avoid counting those, first get a baseline count by running --# ls with only the --help option. Then, compare that with the -+# Furthermore, underlying library functions may also implicitly -+# add an extra stat call, e.g. opendir since glibc-2.21-360-g46f894d. -+# To avoid counting those, first get a baseline count for running -+# ls with one empty directory argument. Then, compare that with the - # invocation under test. --strace -o log-help -e $stats ls --help >/dev/null || fail=1 --n_lines_help=$(wc -l < log-help) -+mkdir d || framework_failure_ -+ -+strace -o log1 -e $stats ls --color=always d || fail=1 -+n_stat1=$(wc -l < log1) || framework_failure_ -+ -+test $n_stat1 = 0 \ -+ && skip_ 'No stat calls recognized on this platform' - --strace -o log -e $stats ls --color=always . || fail=1 --n_lines=$(wc -l < log) -+# Populate the test directory. -+mkdir d/subdir \ -+ && touch d/regf \ -+ && ln d/regf d/hlink \ -+ && ln -s regf d/slink \ -+ && ln -s nowhere d/dangle \ -+ || framework_failure_ - --n_stat=$(expr $n_lines - $n_lines_help) -+# Invocation under test. -+strace -o log2 -e $stats ls --color=always d || fail=1 -+n_stat2=$(wc -l < log2) || framework_failure_ - --# Expect one stat call. --case $n_stat in -- 0) skip_ 'No stat calls recognized on this platform' ;; -- 1) ;; # Corresponding to stat(".") -- *) fail=1; head -n30 log* ;; --esac -+# Expect the same number of stat calls. -+test $n_stat1 = $n_stat2 \ -+ || { fail=1; head -n30 log*; } - - Exit $fail --- -2.4.1 - diff --git a/sources b/sources index c53a0ef..2fd7001 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -40efdbce865d2458d8da0a9dcee7c16c coreutils-8.24.tar.xz -01b4406a1de25aa4af49b9c4b0057c19 coreutils-8.24.tar.xz.sig +070e43ba7f618d747414ef56ab248a48 coreutils-8.25.tar.xz From eccec8ba456ce92ccd1c7b3971b814e8aa2a7b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Wed, 20 Jan 2016 19:10:59 +0000 Subject: [PATCH 293/523] simplify/generalize 256 color TERM identifiers Use globbing newly supported in coreutil 8.25 to reduce the number of entries and also support other entries like the various screen TERMS at: http://invisible-island.net/ncurses/terminfo.ti.html#tic-screen-256color --- coreutils-DIR_COLORS.256color | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index 5290aea..cc8cf40 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -21,14 +21,8 @@ COLOR tty OPTIONS -F -T 0 # Below, there should be one TERM entry for each termtype that is colorizable -TERM putty-256color -TERM rxvt-256color -TERM rxvt-unicode-256color +TERM *256color* TERM rxvt-unicode256 -TERM screen-256color -TERM xterm-256color -TERM gnome-256color -TERM st-256color # EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) EIGHTBIT 1 From ab00e1ea647bbe735809a2c71198f159a30ef1c6 Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Thu, 21 Jan 2016 16:46:39 +0100 Subject: [PATCH 294/523] Adjust the i18n patch for coreutils-8.25 --- coreutils-i18n.patch | 25 +++++++++++++++++++------ coreutils.spec | 5 ++++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 0538a64..79449d4 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -562,7 +562,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c + } + mblength = (mblength < 1) ? 1 : mblength; + -+ if (!iswblank(wc)) ++ if (!iswblank(wc) && wc != '\n') + break; + ptr += mblength; + } @@ -593,7 +593,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c + } + mblength = (mblength < 1) ? 1 : mblength; + -+ if (iswblank (wc)) ++ if (iswblank (wc) || wc == '\n') + break; + + sep += mblength; @@ -626,7 +626,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c + } + mblength = (mblength < 1) ? 1 : mblength; + -+ if (!iswblank (wc)) ++ if (!iswblank (wc) && wc != '\n') + break; + + ptr += mblength; @@ -1799,7 +1799,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c + } + + *length = (mblength < 1) ? 1 : mblength; -+ return iswblank (wc); ++ return iswblank (wc) || wc == '\n'; +} +#endif + @@ -2685,6 +2685,19 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c } break; +@@ -5444,12 +5444,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) + die (_("close failed"), "-"); diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c --- coreutils-8.24-orig/src/uniq.c 2015-06-26 19:04:19.000000000 +0200 +++ coreutils-8.24/src/uniq.c 2015-07-05 09:04:33.032546980 +0200 @@ -2799,7 +2812,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c + { + MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); + -+ if (convfail || !iswblank (wc)) ++ if (convfail || !(iswblank (wc) || wc == '\n')) + { + pos += mblength; + break; @@ -2811,7 +2824,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c + { + MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); + -+ if (!convfail && iswblank (wc)) ++ if (!convfail && (iswblank (wc) || wc == '\n')) + break; + + pos += mblength; diff --git a/coreutils.spec b/coreutils.spec index 2e939fd..50c1c63 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -346,6 +346,9 @@ fi %license COPYING %changelog +* Thu Jan 21 2016 Ondrej Vasik - 8.25-2 +- Adjust the i18n patch for coreutils-8.25 + * Wed Jan 20 2016 Ondrej Vasik - 8.25-1 - new upstream release(#1300282) From cd5c4ef3552535f0c79d7174602448d54313493b Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Wed, 27 Jan 2016 12:08:57 +0100 Subject: [PATCH 295/523] Downstream MB tarball of the new impl --- rh_i18n_wip.tar.gz | Bin 0 -> 28954 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 rh_i18n_wip.tar.gz diff --git a/rh_i18n_wip.tar.gz b/rh_i18n_wip.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..24b7cdc4900b0cde562b1e8e70e4915972227e24 GIT binary patch literal 28954 zcmV(?K-a$?iwFP_rKnZ_1MD1WciYA>U&~*yR$7Y`35qu<%1Xn?l+E{axS|v%P4e(S zU@4*|0R{jiD~|trXJ&VCLx-KFNh>}l1oxPoot>QMKlYXX~*}u3M3>kmFHXN(Aam2%r8J5LXn`L0n zZUfHz&3f&6L1~AXt~0lh%G8}`zeEqNV=hrCtCi9mb{e%FtKwImLBo}^0W@`q&cRj*z%I>&d*jfP6}SdKpl5rg*;kJ1@lur~_9l8A zKHJRaT#j|#sc&uWE|>02$+G8jrfFAp0O%&RG)w#}*^b5EGlTaB=B!z-o7SK+XwF#^ zZdj)yx0{$CHk)X|t#+DwxK;cb;8y2$iG9f?+bg!@#xr@ac}C3T`X*$ z-7MTChtt9#4(FE70+-D=o*DNX`xkE2>-7@5TIz2nr_;$l$NJ<{e{(TDDX~%&T8}5+ zT%Jy*7w41HSEVWqd_5k$9G~kKle5EDIO(4_cHTc71)p4gg>F{5kuv^xwW+fBX;1Urk(jP2GJBuD%vteNA5d zPuBu>%75hCelsQioBigK{Qq4(N1nT412};}qh+=StYwk+;^ReEUz ze8}E%s|J(U5ud?Vv(1`=VYfYO4_FnMq4Zdd1Ulw){B}BIC)@#{AT)`&Fq|vYAUkaB z?!Gy@IGP-fr*+#IvJpUW_zm;jjc0;*vxT1WJ#$yGzX@Wz4!Z5cy@vjcV#KJ|b_{AKhCB3o5XPw|agw<|y?281Cxqs686+A;l^mcUQBz55zu=#*!(Kce^>HxMNsyqot&!m*U4+szF+NR(sH}IIq`@ z-k{y!y`;65nj-AIR3ln^-98$8@P9IGai^B;ImU`;K|eR@iGz(BK0DX&Sk0kdoQ=a@ zo_e0cb$0PrV#C=hHp{k^@QUNP$InL6Li&vLI;bSnP(*}Xi(l`8t-h4I&q723G-?g7 z?Q3|Qzy7*Z-Q7Vcs0pbKh-eIWXazdN@NQ#LAI)FXD0vcd6WB{Tu(^*$KRa~Sx1N2q z2w3^B0#akJr;&a;@;GNxcOKjrU``*o8^ z*{!=_rr|J;TO^!k8(=o1C@>Zv2z0XNw*&|pVF50XMw^%|2|zfd7CsqLC zTegI&63#86K(tXy`G*V84DbLTVV5`da*2+|#^>|RvPLjqG+W_xq&WT!l5#VP~G<1h=pO0&y}vKYR^yM&C@1Cl}wtKG@OZ;&eQn zvZJ$eHezo^=NFU1%j3~GdvkgI=4?6!*J#QSF>?OyqVt^23P@@30DNR$?frW=ULWvV zT5Mr}(cy8E+t+}d0ZMg!d;bX%6l3Xv(k3+?#E1##P3GVd1vTaanlBbXupaL2-rU^O z!NIM&-qr3>K=F6Kg26kxh}D<2bktu6-?6^E!oY{d6u1~P><6TH1wzGr6H#2SKx=UhD z9dwKcz1$)XE5W!eoe49wo4rb?;$0Rcx_fzj7+n-19ASo(-G zi&0N@PL6>#rai1qsW6t8WMqIi^ynsEIKc3Qlahm3SXR6F;OH zKovvw<70|QB|ab3BZqccYchQ~c{RC+5W54fXT^wpNd9CjM4_>t?nzgDSE6ZgnSzu(zg#DRrx)^DWlG_)I zA3L`y(L!U*?8#*wkr@lvE_Z)GYrN5*m%-|@9XL4Kiu}^D56&y?IE^KIBn>35CvYp+ z-V8+OyX+N`97t^CzLV^MqMDV*-vM(SjV8yJ=i|zLG%kC4imvm=xI|Vb3U$}$J`FM1Ee0E6KQ*(_y&rBrp zsR2JESE^QjLMcG_#I}C8;O0AFLFVceB*(NSOsMfGSS#Zx&;(2f?u&B|8N_v#w_sB_ zzi`j3f&FZvJptAitheC>`iWQyP>-vqhL~$*m3n@ zQ!lgG3k3*%0iW z;{l5-ak#gL8JU$iXCn!dOOwP7QU-jUtu$YgxgpH^%rPYODvh1v#RwPowvtjHWTp%* zA=wayV#pA(aHMd4jUA0%emj|t_38K@mmruYqvIr{0v|-O__nbv4sPtcryD0KG6w0Ea?-2YAteU+SkNeu`i2d>)8fTi`njnucx`kya8_ zp}+2n);1x zfs!o4xUI{JBW(~Kx+IanfrutJMtR(^F}T7H2>&M{=ADtkMNV9A@t{bd*`Cij9rHnv z!bLn%*zV>83Kw90=H_pn;)G9e!vD)S;T+g#4ifW?et33ra(1e})}a~NP=2JE!3ch6 zsAfMJeUHBp8~N!bHUYWIl%fH@rIaUtLMmdcAwel5Zh<&VkhJ@?W{XwftJOlu$8v(bv9>D?^bJytf5Heb%Zu`|oG35Ljq++a zQC^lGgFjghn9sLb(EvKmyo!k(Qg4gMpbD zrtD>R=tl2jc^fn4D7~Xt0t##Xeqn$|hnZY%mTR{cznGyOl}c~*)2#m ze+|E>{EUmRxLV%!)l)+dK+9|<9{4wRk~Au+bBGp(;)KW* zMF#bgOXVaGvQ1)vmwaw)mH{cd?XY(n?OWh(k@rV);>t!{tO|QDjo?^hI!dljtW0i; zZg^MMKm5cFh~xVp*1(<{z*jrQ@wwyK$MAT-D?(ImxKOoV5O~7vPx6;m&8e;jkLp38UO(5UKo31sx#p_NEMz=+pr`>h0X+{!$WEB zBbC^e9Sj@8VRJZa4TtUFurnNXhr`}**dGoD!{Od=xV10EO|#VnvJb$VZVzfbB>!8q zJK%s(v7-5h>@0&AaG|wYE|Gt9ek?H+3KcsB{R!>`D`}q;($qrIlHs7;7t+)|l(dJ3 zG&Q`YpA^#69vITpKH?TWC%=X`-ko1d)94}jH9@E1{F?TF{F?TN{F;`{uW8s=lwZ?C z5JHQ>6OYTUX;B~}e9Q^N$NCBb^06^Rq*8$l`FKZutr)Lo#fW`K{!HfAQeAoZwbYQD z{90nfM{zXjQiTqhfCS2iBNv5=r z{){A(kljT|CM}+1iezkIk|`@`lS!uVY(6E)lmj)9WO@wnq9l`qk(Xpr%oHB^Cpr{B4@f*)3{|=i1%f-8n zfX-2NP>6-Ljsc9w#jfFR*8_)8y3pjRwR+&H?cwW>y;`e*u9{3=lu@%(N?7RP@L$go@Es zjIojfD^)x)MeO8cm*jrrNZB3oOSrkvE+G#!eWTI$Hc^tXXxf}u9BwI?vaYv+Uxwo^ zDGTCAI6UugCHF^;@)1Z-Of4U7#T1!1#AMw3OHTU3)C;9heBf&IF7$JR#6~EeB_y+ z`60qvWIZG|cqq4Th$JIgM*upJnpZMPoGk#k;sFgVKbK4d4z$Q)qN+fnLTkoT!q1=M ztxmEdj*J%zfT3kOVNIrzCC_3R>sY>87}|32c=}m!S5=9G;@quTBALGxA9*pL3$7M2 zh>q`s$#FRgXVa<)bS1bbJy9VKg&dTeO~~sd6THpXZkS?w%PkPG>a0w0Or{_-ScHu` zP9b6D$4=r-V&}*Y{2(7FK1=cs^?*tfY*bW;fQUy49m!lGf%9A>ZdA%9hBKa{yvLPz zI}?JErH4|8;m2URB9blby;`4DTk2i&+>01}KBk-K^fSXUF0LRh2Fa_{Oo3(8$*KoR zdS*X#C&aiM%m|rcD_hu%ha$B=nnA7Ey_Yshls-RDk2<~x>Y=WK zMSuO3J$n|#bj$RP6}Y(IK7uMWyeqS&G6xunr!$U)PsLrw6;iQRdE*Pk zZ7618s5D+>wMtC}!F8DuWM!%=jFN&GsphT&of79|fiEIjivr^{;%o6lRu5UyS~D~; zBprS5`%NsIsbmwp;VYA~#7~*vH5*o=WA*Cw#*8-_{bn}78%~H4ykV0F#*4pi(Q1S* z0qWL9KYlrS`4Tqy*D^g-=mkCGN3T9M_Xg3n10T+<08|j%7W8b;(=P10bMvY0qU~=S`{%+1@GpiGb*=+D4>h`a z-4^b@-R+3K^?~Ct?TlqfzCJy>JU<*y(HjGP3ES~KP666nr^l@8Cai!JC%Sm`+poZH zp96lI_hFNmZP{LGI>MF@8uZGyOBHt{$A%>j*;hJ~R83Bcz4)B};;MdqH(u8QF&b*8 zq1y`XmFI5oZzlPH8cQu{nu^A}IT;BMLwuHMkW!%A=<-&pU9TIRz0RI#Wu-uDN+btj zjl>cI%89~PtNFiE>R}@E-})uM-?KdAvr9nmYf-`D;lm5Q)Om5NkBz3A8^OXRa7gg1~%v`Ha%kalwZUQ`f*dD@@Y zkbIyxw77I<2MORWQ~`;AiVs?1z);5O{z#=R)xwl(80k$bHSl}mKSLjk*bL0zW(zBl zdL2=bbl-u-UD>CSo2QbSr;?kelAEWJo2QbSr;?kelAEWJo2QbSr;?lh?UEa^O{wTc z2=U*r)XQ@(J( zlb08-(GHcA zQ4^y@z@>8~80E%i0pMTr74>OI${3|X0w&0VHvEd9Wu17z!VezKc8ELOxiG%)EGm^h zbjg<}1EDZ|wbg3ZI(xat|G>Jb|4Nz8pQuVpbR^j6|Eh>9Q!4eyN~`}+Vb$a6s_s4% z^`ZNw1je&x_~%M&UyoG)0l{<1r~b{})h)M;E9tqlo&qC#SI&`0^IwuD&g9R@q$-J1 ziE~cXiBmeHNJgC4l17x0cw=v!eSm$2y_uVRfw`Ky-0oZK1MDkocLNmvKuLBKCsSi4 zWl10af!F!dOYBb5A2l){GExC+YeDN7s)q-WE8EPZ^ReD|kk}@@vq{49VmE+p4#4o-}&|lc|*}}*a zQ?I!tWzycS023{}W8Num@s*0Sh1n9{IZM;Yfd|i08y6TqH1|evA8itOow@}zfDRoK zJ`U~L#c=a@!6XoT@n^0shly^7{S=L0X_Y9JIlZTNC5_mtrijXZ&ayx$^TVrx0cM_^ zTazr#IbYDMkhipMl3f-2N0Kb{_RV?`d%}y@(oLG!)~dYlPvl2z8OZIL=>4X5R_Yw7 z5F(daLAbYIc?8_Jl6os%E6=_(WLxM6UfLZ<9+x-;=gN^=ut=GE2BQWxpA=FtbwPh$ zxxR9UcFRT#tRMX&T#nT;EWg*(eGAizLfO!G$-r{)f;D*jHX5_B8w!q2NfL{LDt4>%oVg_9@?G8HN}jX|k6Vqq$@!Y3NsC0g z*dvm3j}U7nS-qNOTgOvL%V+3vSO3K3QheMB9{wekCtolYG9}B#!rq~J#TlqTQ8p^ z$k4MmQ$T&yp%X-w(dDv#SzjfW*r=WVCVOI|)z~dA!Y}Mzk)zmx7gXxBlU`CEj3q7Y zJ={M$cy`$PY5(!F9y*e7GpeoA3dgdwRXbxb=_E$mmG`2X3*Q;5lWh~H9#VO#q%t}0 za7p|vPm)+hL~Yx4DRz?SgpRLE5m6;oW*|`=9y@9C`yDSD?!Z0toh~4n8bHpgBARZl z3D9(NO?al8>wq)eToui<{Pq_HGu`}bEYr=;g)-f|Fp}x!I)F?!*Mnntj6W z`_W`iJr`3T8b(u~{`wD~rA`MuSm~lF&|@l|r>Hf_f4v8z*%QYTITkdAq-2lp_3k`= zycZ06FJGu6EW{ZD+GpUdCaA~B;vd$UeHiLnIQlnl9_=4Is5KMmQ2NA{^Q-h(Yq}fW zMt{R!nCH{48=rpL`1Je6r~g`*5B`4o_0w;VkrMISr(f~w#;0G|hYz(TwKHit^up)1 zJrMv2;}@UH-bQ@?^jq@f_vFip?NqkOwqvP2tmnvkRw8Xtu{4Eo}nIoF{1R-MsE!4w~rK*15 zxM911!dobkmAJWsnzl}dW$}Zw8Ta_ON7>lk243Xh&dd3;o#|i_05d)Ifn7=NPT*C5 z+bHp|8xMGvLXP(%1!ydu7jH62jLSmJk-r1nR6##EWfu8ysba`594W}{aEnrMH+Ku} z(b*;2#us<&3r0Nb23aVfl6jx>RREUG>Nt0Jn>Kx1McH8a(rLItEMy+dG*J|ChT6eA1 z<RpXs;QnrJA+cck8*}^$bOvc@Lux80BUR ziiSc)-&nz95G%;kVig!>e{i{HXpUpyr{1=;>?dA^W3|824aYWg!!X+BcbcKME$us| zt?3;XUNhX{VC=imXbj@Wt<1OV{vY&ufO~aj$JN4qJLrUV+cKTD2OPn-eOJ?MEwt?} zsI!jaxGsAF%F&Bp%=9+soxAiO^g>OqVKuvK??;+HKmPLLv%P!f-W}Zs_4>`8q1~Oh z{^^fL3!F`e?y;JhdqITAO+JfcWr$a9ix#xYA z%U(UZb9nD3rWrfB^;(!+c0n=zzy#Uyy^5Glc_d_8t1(qo6Q!wa;|G1YRz?Y7XV4%} zp67Qn$Q;OBnZ@vCjTzz$yFf5#F&id%98Aaybh~*26a3&f;J=j{wZ&ns`qJ?AT-6sL z?^RW|pwokPRfLy0LW(rR6$bz@I1nKJAOMh65Hr|(b3>^_%uqfTF@vowpvvNq+N_wN zjNw4%g}J*K|9}MPaU51SLclj2OQGQk39R? zMZCEJ3q2)?_IFtYV2S+K^|oG+|AuB**Yf`=E|UMg)$Y5V8CtgGX)cUG*A0EUV_SB& z@0yln_?GXreeX-j|HHwo#oDR-hl+K3*S4$VznPQ&P$v^)JLf5ApGe4d8)WWZ$`XDT ztyPp6_z$P=fm*E%fHG2pKg9UwvR+SRJ&5|x5$#-}t7>R;JAPlnWG^7vEdpA!NL)!6 zEoZD!oUKx3InI{oElK`mT>J_++Vypj3+9)lc(dr(S3qcugURu!f@i4TAd-o49C@=L zAJt2*{+6%*bjvKR{~V)z&Hu0BBK~i5{eIBVb+2POrsej#UPsg2uH`vy+lF26KfkctM^aiR>U66PCytenW&p^fCb)n=uo^gv7 z&S)*e9RNH-%Fi_-xB)5FDDI}PJ|c{xv_n`7%$}zS37UPdSS&Xs^3%$%l?wtiSBaPV znLy(D9jl{?ox}+e7eDyv+c2uJH^;rdJ$m}$(ckxbkDm6P z9qvED#Ui8@ku61!(l${^&3 z!~N$^9v!^s{d6tq|1cM@FFR}hjZcSD_k+?$KpkNO{tU@Kf5sB~uU(M;nt8qcyPAvS zzvp!vy{nnN(=}Y%YHM2CZwDO@R)3aZX?7Pb-wdv9{b%lKon6zYlK*ze{+lIRVFZ>f z`Ublc*km}Reg8$PJqx5z_9|x^U^cQ5XD^vWSTC7`^|jfA#d;AIj+$?KZS!*$jwZ$Z zX_^kfB9c!_l>sa@ZdMpqm12gnaaG9~NK2T#>Fp8-YI>`TI-A~;!?70bXCP5I=F6qQ z9dTP=F}NdJJj?^hzzh;a#|%Bof??K7-EsqC@h}f6hIt?WFv*^6C(z%Ft;gj;ydzqk zq0M1FpnXkA?49{!P+{chb7OfGtZ^}e1e-Z$a4$ne&u`06b}I=iy;lJPoWGyP+$F#` zwgRf>4_Bl?p=eIz|I0W~pbMwy=%8?2RG9>0VAu)AyqqquME;v?r)2+aYtFU&zlw|G zzwLQ#%hzqQ<8^|z>zTIQ>1v@HhN16vy0-3xZL6yp%jEwvmjpf|anEi(yG=jomkRte z5%*7UrD=4jCXn~AY6E%S-nC4S_l8W~J2`p(5iJ$=M1M_;;R;4m2Rng7>4z+a9{oz@oheeOu|8 zR(6A%yTh@>S#43Ctoz!6e2Uzmjm^(hFnXO}_%3xxN=h6}3q_8mROV>dV7C^%b<$s1 zAFy19;f?k7nD|7|zoZUR>;eu`xN&?5|Gg4PDRVD5CF>=p z6usmWiIp1G}E;GE+pms_8{5RbVx2Z z^l^tbNH4hc9nBs*(C$Ne!L_fkaDqulP02J=)_hiWk5uIDkxHd|q*CP_sZ@DK@~-E7 zC3{xVVe;oS6E{K0BSp_ipGv*AV79Gq8dU3&(C&8D{)7Adi1;@H-A^DberfxUY3Nqb z{-d|A^}j2*NdIf=uA>L08+3Ko>*%4@cETXk?6wg&M%#7`!wYQ9376@A2Sa}n{LBuh zr`S!=Ww$4RKX9id4Ny1P0cdbs1Jrj7XIHbUG{APr;)8o7f>0Ak&|1-+L%w=vAhlRl z#VYypNph5JI95sT(pIzK6wEhs%Z=0VEXS}_wQq%%?pH49B}N-zuhBai2FPsE=b|8@ z^YF*~Is3!rzd_OjVoc`k0$OH*8gl>w~PKiaQ}M$?@BJN|AnsGbuG)#%|PpPL#OR@+oox^ z+qz*vy5m`PC+K#+wEkyXRr+6t^gkj^;qdA4U);HZ6KXAMaGM|0Pp>n^y*PP>lPK=* z^k-9be4NS9W?T!*5SPcRgrEgW~%ym6b&z3RlZdi z1X(!=CT{|)5MIn!sj5;P+2&Z*YR$>N)LeO>n$DQnU7?mj4bd;TZm}=YExG!}6Zp>= zVP?=*X;E4eEDs7x2(xV#*AUin)9o_A34t@As-|bTnrmDRaKbb>!mOz;#a&1V$A@o| z=%fU#kmjHs&`6j-M^lI-d95ZI68^=qvY8}!|5CZLNXRv zmf@At5<~_|?{pkPRZ)BHgr>}ho-LIflx#Xzq7lLr{^~ku&@qM?nnZmJue!+&@xT!% zUVH%@{To*pMTY1RF8hhA18pyS@MPuOEMTzy0{m(}yqbJltpaMcCeNoTHl9 zxYqy$k(mS}cyh|NPP`QTZVQV)KDc-1@qX{Y^WMwD2c2_JNpsl{{|>|Xj!rOGEydO) zH^tO&kEibAT62Y(+4o{=*w41(>@52$_=PowqhZiMO%<0Gxq9JsP-m8>vl_#u<5o8& zL4RQ)CQU&B-(&Sd_-OF^iZTd}$Bh*BAR3})B=;gY8rDT94};>&8wnsEt^zX81*I4J zH&xEzS+|G5`yT4ex3{K03&zq2~zL@ir+ zr5mqbX-fBXJ&U|Ip2Y*It;Jr|(~>aL>Mik<7W)W;!uD>ly4aja-=u#2I=fa&Ydl06 z<~96KIe$_jH3HA^J9gzPN(+`IQhH0wC5O)?`>N+sb5qO+GSt$b z(IRL%Ld$+(hR_QX=2i9dyU--5nhQ<-xMVKyert%yotX|t|5$ZCP)Q0oh-InN?mPq` zzGf@k<3KN)Fba;jZ_UvVpNLh^Y~)0RL7N%dCSrTlnCgudYbXjjeC(Os~?wde($p;*Gl8Yq$4L;ftsYJKpYFW)seypy!3R9u0LjX& zkNeM`pJQ731G4g|TEMN|=AC{cXT2(bY2#?cGeptFx_U2O-hFY1#Mp>;GOxR{(>O1{ z!_H+8${MUfdVfoHGtM??IbO3*GzP^%-Cps~ekv~o3ieHMf; zjG1a7>1fCkvjTLJ{BL^{>CfoF+<5Wm;OU;;?HXD)5r@I>T{IaDxjGf5VwA(Y;Ypl0 zKnM^F46DS`)8jzkwE;Q24OmlGuLbqDAgGZiT#M;zF}-dvy-Y|0n|L0a1ScN%_nPMN zamY?#R!%2AIbj7KT=WK|;F|SEPwQ9{d1vBrPZC?)WVWr2i50687SBR-RsgEU_q_qL zaxw|x@rX|b5pY@@0~Dd4@xeUCG*u#gkE3y*GJ+hzuZk!qT1SYB1X+vz^fOvmx(o)D z;=iL;Dzw1$aPf(d1n;YC~LG_6FjLXE8R$3lhg z0+r)k20YYijK^y6=wdvJ`vGuWlzv{&cg2a*Q;rLXh_xd2bxggiW`>Q=52Skx?1HSh z@OX9HIA?29x)h0?LS?W&A#E}n3RCEIPU&g!QmurvTG>Xl=8r_VmO=_wn?(|_6egy>YbY_R?_j38>HhA(k_M+vxO|*BJ*gRMDe8W+c!#xP{ylI)N;7=hr&bpG&90xp}Qq{V8;+%}jTR{)tB?0s@hNaF2ncV}Z|; zs0y5}h%tMY?ZIMnvkUZL~JO3WX4@T9=D;@XSEceZ1k zH_p$`byYQQ2+I`v2<35#!v|WT&Pmxt3To3%ZpUevU74Yavp6zkZF$j~9z9$bvaU^8 ze?GMfxyrTL^`}s~Dm^Z^kC9r>x@mt?cCRle^`-JYmGr*XHi7G@s@>5%$8Z-)`brr; zm+lrqbs@mzR}=4-_Ko@?7K)2GO0g;n#aB1zUk(9qi7brnlL#a9E05$(tnMr93Sr78_oY=@DW zU>b%1kIU%^|KHxXEV*%I2hO(m6_+Kq3LqZL#2YA;+LTySGlmjrl4^N^MI#c4L=hG$ z0U-evDRxbGb~6iyw=>I*u%lPrP0Y&nM%_Q+AMh{CJ&*g!2Y@0=YPB1=APbrIp8GoY z+;h+K#bKin9D+LRThXXCCSxK0@T>k(E5@2)bQZV7XO3zNf8!TYjRBaE0W%gwU`8o0 zBL|F5OEke~h;n8gpwYBwc#wg5DZcpO|1Bk_@wGgCNAo3w(j5p6_%d3bo6v}Uuif%) zRb;oC*sDbLM|MZlR(FlYPww6~XK_#))k65gvB=4Mk`!zs4Xgrgyf}>KXiw@xtNb@K z2wpTNpEjTcc^*iHES_U{b{sX28F2{)F41HiuckBM*Bgxqq&tF>dpsS3%=&!#8Ze6v zKSTwzj{gRdGo6mlYpi$_w?zbsyV5{2f({{&B5kg6_`x0L_N!lC zU72}1-p*M1z4JprhSY16dciQI?0$r2!GUw)=vk}@-#&t}BIE!VRsssAV}_GTV? zH))=@G37Evr^Q(AtxlUP%8O2!4_D%f8&Tql_f_KVUQaHpQ&oJ}y{70^WBVhG3O?}d zrWdwHoqki^Zbr?1*!K%>H+I#`4afe-33@svKhHJPvkK4=OQHTGEYE*FHs;DY4y@S% zUvaeJNF2QpzNjC*wYk~UYqpZ>H(==`78Dqo!x;%&D^Mh#`BtP(JOmXsQpk}=@(29u zd`=OHjJ@367Un~_-zQ%AGRl6 zuUOBgs^y%G^uhIr>~1?3-BWS;-G})1i9Znw^glJ5sE@=qucBBi=1BrytWKs=^1K*+KjZ?5WkA*F_@oBzSKH0)G8*Wj+5fODPd+`$SKk3$ z5nBa1`}0@)WasbnyZzbwXL0s^Bp$}JJ3jJT?J5NRoq?G%P9LD*zyIC;uGj1T{&)XJ zu7Eg_e;%bKEiId9wGVe3uSi=i$+k)_{zkU-vQn1+-aR_|3;*cu`F6Xd4`Vyz-)UhG zO#ETWE(@Nl*yeBMqolT&t&`n~`+onAqR}L#W^bwgbF|d|5L=B=5!yBhTMj3h ziq|sAeXWAqdHq&5fJ_SARv5~gb`Ce1s%Z10sZZPD3b;(@VtJI$qbBXf(WXem9ij~AUGwDA!#8KEw`Z&G(OQf@vMdNpuS zyB>&<2*rhvy^*~6Tk(ClEb8JA>WP;PV26eIAv!{O^>?sIW=1Y01N$vyfy3r=z z(K&9{mxc3L&CAod!3Ug~Kbn=<4(9B8p6zGIv;EP$EBE1Df7XxZdHtHwUtk6RN?uc& z%-8b8=q(3o>B$?LR5i>3c?;jR2>;MlMTRR zcN7rjG?NBEVBFDy=%uN&Oqu)ujZAD$IlP<7@kps1<&|~Z3wn($$^SOzc$6CtE<5la zo2-t8)QX7_4!6##N~?DV0)ES1>gSk#(k}@5jRN#kNOqxvkORhXa?d!y$br$?Auga!Q9tq;T}mW8{e5BZ58$&ac5LkbLoF%?Kpq_GfIqKA4l27~RX$Q-waqy7J}6Z=;7O4GUG0SnH}S~J zn`iF-i)fk5<6u^M{`mgm56=5y+Sqvi_qv^id;j-4ZTWeB|NjXdy#J3{zTfWjMxHn6 zG=fei=mlP{)$MlV(gdAuw-H7iZxs4BcK`ndQ|h&?`+sBLwFix&4A8!py8kOg6@aLG z(}zE6Uw-}Q`NPlt+w)V%>IcbQG6|H;JzZYYZz+4T3(z6aEiDBob#YI%GD^L;6-SrU zq6JX}JfWvvAB9oSY0`C2=j`NrU=1Wph0Yv&Mo+pdh6ccg4pspU98@I!5&>1%-qh8n;cN=}V0$$W?wfpUUM-qieXWS3H*3HWQfDr$v|7PCrHB}P>c0wStfLO{r>5^8ShH=^10ubm)>M1cg)O)&KvQJ7o` zKD7l@Yi3dcwHs-%VSAg@kj61Ge=~Jy`i*wmpGfM`nS`UxI4g6a(nj1wzfpYBLlc%B znXq8yb%+`kiBEzAdRKq-sr~Xik_=+{W%4$;yL!8jM8!_QA?&A)xVOQVw?qeHsL^cN1`f`zvawY>L*%GfoyXkR?BrH#&fx| zSIXi5u09E%8}P1(j+pYfKkxA7wiLWU>zo{;fjFCInq*9u&IKCqsQ`^L@`5y zL=Zv)0%O)s1tLzS=V0H3!UhG2k(~PrlQ<=HbFIb-Up;^m>XR}Zx`dV%Q8<+&8M7?Z zo(`(6XKOjsg-I6cw>};c&2ziV^<{#M>c zuVrb8`N=Cdp{P_9Edm4FF<`Z0utm;uAQnlqmgw!)z>6^S6D=b?|J6NIeTa(ic|BkY zvEZ9x-SxWcY-o^mxLi2W1->-HypV_AMQwirpHFrB}byVFR4qiGKFLl$JVGwG*i)i_qk8n7%8RADkUiu z78ipSMeW4EgGaVSRcZ7%_+wkla~n#0{ITjU%X%u6gybqb9SO-x3{ZG!&952~+VxO= z6TtB=kop5+fF&591rapnw!{)x7eyZ^MR6h?JUo4LUs4gWh~(tObp4PNTAo@MP6vQK zeIj?_GI(3pbpZ9(voY2jMTo!iL{c-^GMEA>t5QPK1b$-|5-7kgMt{U`EDq z*bGiAY+f)5!UGWNO19KGo`~XTjD@XwtD<^}TPxFDXKz7?;dK1w_&|32E4_`~4NNO3 zCo-9fNw8GBfUNNi8z;&EjiPf9(yJkA>YQj^gXdhCVutG_8Ylu}W%c(=Vr4J^!X|l< z*TANnuWg{gD#%)BQ4}T+$t67pFjJ>scV?a0 zu-GaXl$xIOKIh-i=8)cDle_?$#-%!J1jA66rVOa^iC8Xd@=^1FwxRc843vB8AN(8Ekk;Q`aH1ImPM`g8jDLAE>iRW~GN)L6yLsDHWeAQ_OQ|9nL$W2QpC2WXkhm znhbH1k(^zbeYkB>qX$L_Rlu;(p*iOXEmyIYtd=QGb{?*_3XY|N!bJy;Un{k^r0R`A z${L#w_*MSH27hHO+Le98-3WcpA>f-?d_&jwBz;fP_ayy#Bt6rCJw^RdDXQCvovCZV z@mhd0rhK$q#&g>l=K$VL$it+>djs6nCfF;pS@cB*I`syx9K-Q6!pIM}pJlZWY~bUR;=ST?(or~u0}^$AIh z$3tQu1^@uS*xuN-ZQHhO+qP}nwr$(C?eq(s+f0#DXd=h`J9-Ig)5`>w1VWrslNJdE zlvS{oXfAO;HAD?emq07ZsHnUwX4Mu@R`%#I-3FB`f(UH*Z5j9X(biA~AAK^puQ?W8 zof@AN4)h80Rl;>7xR@Vd4u$SqDaX6lg%^$4U7c_@Va5Z$ z*7M7sh!@^n69Pb|?8;phu*5&LOC`iK$?Ljv0=jhv(7l+o#!vNzyDXH3wn*MQr)F8I z*GacHwhW!+gxL%bvb)bRMqJFs^c8oo$eVO+xR!P@qplY|a;?ti5EVnXtY;QakkG(~ zm!28Y;Oj1O+^w}o&C@N%Sa3C;#m3s!M>M`ARqzr{b55O(w@DW~ylQ*!jr=;%^vsP$ z>zCtHK&28!wRr>s1Nz#0r$g9vhnw}Z*H19D0TZo$2Nn6lEJBef-gSs%zfBT`UfKz) z0e7--5EX|#nefiO%;jzb0CiOu^7R}`%dRAL_`LAx; z=4muzw7I0p$FtqsMk)>tCTyaaWF*g~ci6gEq{2&Hbko^{iB;Md2JP&An~xFR$As#i z4J}&9Tban?U9y;hq!=}t=+)?k_g3Q7R&?nI8W6S? zBJ7at)cQ_k<|{JLSjUh>4)C)m6utRlJt1Y8H1l$8ELvo~B=xjbH57vNIi^>{|5!$rn0u3dUM z`{w)L;(60XKrv~M#5W-%V#pd=3=5AO-IfbGGRO94SzL>!}E~#})UU`hwywRYOf_9epM^1x0`ZMZ#|y z_EyL0d|G_zX$V3$QUn-M#`Ga9Iv%cV;3$V?EUAS3pu+* zQpa4rQP)aL=S|t6+B_b(55bQFj(Cr)g-ifA@EsxfEdK0vN2vpY-j+|mAOvY=Osv}z;n!)%#|`pE-;eO`+4z?kprQJ z%|=BA;~oDfftZE`OgZY;wFLoq7#X!Hjtf6{hXC{hH{NR z$DAsN&mKSjO0(LTt z@%gfT{V{LOn6jPxkva5ry#0Mp;6DFdxc=&{*02Fe+{g|cmCurz>p@9 zn+M0pIuHHw!8-6k#r(-x?Mw9TJUxB;VV?g1yK@2%Ns1~@b%FD8-15Y@p7CsZF>|kV zk*)QBXA%G5hF|mN3Sgk+iH=PPgI(G_Jsd1VSL1n8Hfz>6tYfWQ73tRDyl!p`rAB2H zrRwFku$z`z)brnZ((;T9M&|`d#X%!~#y{Z_{azmeB_9D8_hf+_tt}BN+6wHeFCwR) z{(?72O76Pj`r*->sQ@xK4d6qsOF%(U&h;511}m(_0Ybw*5Q!>Pm*`I{CF58nQg#m8 zN2iW(56}l6XDd1Ns2QUq8sY9$ns}1IA83GhLNd4Jnm1K|Fi)L(1^nW#z4euE_~I2W zijaZF^Y{4U1BDeGJMP1R{p!!7!(;{tSkarqgXIk5bD=+j1^wy+NMFx%Iw-fkQEr!L zi6YY~IO0&Q!Gcu~+W;t(6qy$liIxr38gZ?qQo~?4x~sIF-}md{oUootgv7>PCi1`M z2eaXJ#h2(z&P#^*=^Zq8qvcjiG7Qg&7b3sZShmbk;|97? zZ~#)d^y_>ZQ6G2SLg@iXl5m*q{dE8Pq&MN#545xggCZM>a?Q~3;EB7+O|7M=I8Ayg zG>EnL7SVk?mz2L>Vyrx9MZ%#S=UO?S^0-|AioUD{>P|_qB>p|Iwpy<(e#f?^>MBEO zx}9FkO-!<(n6)`uA*IF(GauAu7FC^+B7sDNSE)bED-PXGvvY7ho?xGpRMtH+6wLOS zz3J9AVTf-Lb1`WfATUmK_T-fZ3;ECT@`i4D$_PAjI}^Y@GyX!Bf;uh7T}-)8vB6~S z`7)TOm|_7qYS@ya#Thm+pd7*d{WX2ZXg`!x@6z6Ohz=L_jwen0VPkDhE=;c1*VD7g z5%>UPfV)<{H*+PK;b4nk9>2F&HeUe9`-VSgdG?e)D0K$=O`Qq_*3B>_AXJaP38Csk z@{34N-%uVj0PLm8OD|V-fNzqg+F)|oEFUtgMaXeU@JbY)S;dj58)8?Qj+kJK;jx;4 zbG6}J>2f@B?$8)#u*bPEw?V3K2w{7WizE!Ed3KZQ9*o(;bH>5(SkTa8we?mp;FZZD zwygM*o3w_o5Wx1t6)gzJGj}rAvxfG<#;atuz$7_Xpn65O+d*y-SuhEVsCQ3Oc^7Ij zwHlEEBISd536E6S2g-wdV-6luXO`#zhPiIPOEqbG{6pE6wO(f`?$RWUw;}2*6^uYs zLT(IMruNt`PhJ1`PO=0ad#5!*_y`a3Xyn?X zV(UijNB8ST)!O29zu`fn8!y4b#JD+9{$D!OM1Qr~zX=>M24ji(ZZ&ODja$sEJT-E; z4S5Z!rG(cA?Hab72&2cT(8<+-u#)auVwKtiEn7y3G^^9pC$f!18l}X&hQv_ct>#2Ci9-lM= z#tBnmt_78A(@1Gl^}MT?g9NpiCVNO)Y2f!sRz#uO z1GE>km6mjQn}oSLQJ9*I^2t7m?2_8CY1mzu{`@DI@KKe*V=OE+N@5KTAeGgkEK4en zL9SLf1}bW~`{)m@x|-@qH2V^q$@S8DTUziZnCOUZ!!g;UsiDRd5}n0|@wFU-DJG7b zcG1R9y8d6`0H)v!haGq2hK53JQt{Ektjb96x7)wZgQlf}rlr2m&*!Q$_`3$1g%+IJ z(zU1d#jZgC6t@YbUNCyH^JRVhQxH~r@4CraFTqj3sYV24Z3s_i6P0&@EnCdrB|@Le zBe?JJ^aMqXRbH|qE8>ON$ouoC4M#Z>L+{_KBIb9ll8}rNuB%!W~a6WKA=44zpd~;8QX2<=kq-?le zYNmiR;Uc=>tC(@kFFyes7RPwb%kx!~%l;niPK22D>-84AdAzsM?NYiG{@l%q4y!B3 zy6vUqf5u$G8z7N+b*X!la6QP*}2o#+E$K{XQLzT zlx+rzjYdu8dVm0955?h@UT_1agPF-D-xSrT)Nip=Y^nCU!oL07x9kyGvxeQ=nr@dQR#uxhAzXlMTw^#Qpwz9{St@MD%omztZPtBi#&0lOlwGCkimyyY6UC;H z8CUcJaY{YQxh9zc%q~l^rmagc?X&)NQaw|>qJA#8b>syH}c|L5iTQu!A%__ z$2LYVYyu)-3CQegLNBBnN@s++&N5x0&r*90G>EMySNeJ|HUb#|V*bxQ>{>y0(Ht!D znGit!G_O|KDm^y=yoD<^^}L2vY6Hx;b;MyTxk?jcZ@hnXZ@ug_P?9R1e+NoP4adn8 zf8nIh0oHaCu#aj5Eq)|Q4nao#>pS6kS7dFP_f^$zI`g7M z7|*e*iEH&AViWymSuQp&%DiB1KsC_hJeX%TUtU*ThMA7mS2erVt9vCf*D_g}Xq{CL zWUU_=ik~{OX+|9vYxoX%j_7k%nDUJ~#yz_hUkl}Yp76kvU>%>#oumGaNc=!+KvE*Z zLxpx|BCpBf;*YSDHF6@TDei1xAZ4KQa{?HY8)?HQswyd9Di$0nq6h4m;S88Kmzj?z8r8a305jYGgvoB7PinLP4yaRWW(f@2mk41PxRnOK_i=pR zdw9PL5ZM-iX=V-HKB!gjS&9pd8rJxjEWNwZt4$a>FM2&X-I0fzBh0#FokTI&u^?u4 zyFBjuJAIfPRHeF2JlC{31FV_Lp?ykN4_~c|gQ|jmV%CK-NiRmsfY_-~T2M~0ZW7qk zw$u*yyfo9dac3Vhn8a(5mP&nSd(9VYZ4DfMLR~qNfBS8iGd{m-dB*}@ce+gGEQ7v% zE7%?aeCTah0ed)aL%!!B23?3QTts}=tUXvwf4;q`X!Eu0ZR&v^Zdprx<3+XjKSKXz z`VeKnf$o^HW*)7dl_+CQBABn1l2Q%i4Ev*tBY{k*gj}LsziU^&|c1{$|!U ztcG5%N|xwH&&-+lVgbev@|-hctTxu&<{b*Q>=~hu)pLvb2Vx~8KL}y2{2e(UVll-Z znWIcKoLoC}$_A|65ozX%@F>#!lLQArOiFqsUvsVB!qbyi5fFI1v1a?5Eni!&pVL7& zA)qlRy5aJ<^Y2u!X0Vu8|M;bdQp5hpSlAiI;X;`fB(vvEi}X|HG0Bo6pmBT$CKSTw z&Z64zo4p^uDYozCpFS|wcgE_7q<{Dy?t|{Pj8VmNJuw89kxr7r(F1db2B=Z6*ZY&D zn025&OmL5MXporLsVj(PCWgI!o3?mr$_pl4q@Lw{JXwt1IoIFv2Mgs z?`EoZ=c+%M?N8kbsBr~r-GsY-neErL11Ej(Q!_Wq%8x0MsL!ow9TGHYv1%~Zx83sZ z(4s>rn~RmdChuiQzyhPnA4**bT{v&diYzH$7>;Vqp(hUJvk(kijZK6T%GVbNo<~^L z8{`njNE}CQpQx4NN|Yr?rulTo6$9p?&Y};Cl2LsbNWu7^JHfF4Foj&t(*>595GV`d zBr=>s@hkSxH8d7$hO$5cM=Lcmgp`b@bOggz7sRDUjVc<9*%xT_#)-MoR!GIDAxlU3 zP62WJmFy{a)pcwzW;w%eLY1$F;77sb5G2+bd@2XwUj|TT)UNM{R?Jm`q&Fm2cq$~s ztmZi;r^`H$45**P>xu&A2COU|5P(~}nx^5C`UuMTj!WpR64rtHS9Jz(LpzWT3og@* z(((Fw(5hfD3EZ*bb0=c_>*k9H7#rbiYK2ATfO1Z}G)?xFIAi*7gD?ZyOj9pm*{==Y z19qgJxj>}lH6CB8iC3&sht{AHP;^2w|KPh>d>`U6L!4As)0R=h`yvtBAeq*UpRFRSm*D2}MR0dlw8mmI-HDk1F~lUBzZ%^L00juTsEv z0U_v=O^}sVogxDOu=Z<5GsMN)@~e92UJAu54yHye z*00oF{N0~^`)gD3*a-DrB>TF|JBt;#W0K-Bm`mZT-vqVtotCj*-IA%o&xC4xGMo_d zQ^~`Tfj-ZX1&zC|O&QzMQjW2Pvo5$9Nc9rah_$Z(-(bfCEjY^HerJ2=@wrRRYmqr7n)45Vp@@z&X8Io0Z!=cCfx09OkY?;fV1RHPCbuuOZ4*+tW1!|Dk*dG;!S zoA`z}p(XQI8n4Z>@j*`Qsq%awLptb$yJ`ngbob!yJ+Nam!TZTg9O16dof_wKe6#kf zX->L!E#$w6m0q&V0)9j`^o<*(&)rI7J)@IL2@bGpz)S>QJTnf+YV+?hp>?gbX&p{z zOnUneX(eTL`@B8SsZI&Sy2y8zkJUH+!Cp7Yv&*Pz82r+I|66u1)%@$UzHxNid&rdf zIxTle8#xqLl@j!a!jgPxfUtYkJx`O*o;*A+eyEcGv3aSIbrUZ(KR)(VW+*(F3xTzsE?%5b!$Bns4J^?dA*z3(%DTQ+eyEGr)JAHk%Ej zBCXYqq4)zkMQ5UNUwV*>BN{UV(rGp!<}FruddR*<+3lPHYjiS3?Eb8Y!E@PrcH@_y z4iHy;=_3>S7$J2t#beFqI-t@P4(n!=D!GfHsY?Bq!P$9`2XrBRlGWVooN5}l+&1ks zhVN{0BF(4!9Pg>R^3RIJBc~{0h3(tz5-IykDf?;HK*C<5G@|v|6xg}N^Ef$QDrt!t zWmeeH+?Ao?KKxc2|t&0##$ysY9!R@Ro z=he!EY0SEP59K&mLJzYJa^-bHqxny<%?vkWO7pq%AYf3{2b_xuW4SkSwA)&*b{Ut>$ zWtVJO#c}bxxwA{S*|+R))8A{f!G#nX7;tL-yr7ztOlHhql{`&}^dIAADUwq&u|$wj z{nA5a%q*=f`A9G0Aj22}U(q$@(ZEdE%6KVW`(1VeIT$U;NpoCGQ#GkNx0xAIU-G;C zDNbZSy%P}f&Yj~UT5&n8fW*axBO``71q3x`m8I52hkG7>^2I@r7d)QN&olDGYrXTk zi8F&)Q%ZD2wI?W*8 zSylHt#a==zb?>%3VpnCxFQ~O1MdUE$;jx!AakTZ+2`SYRQ8Axpnd4apTJ)3(lM?vT zXajBOo+z1_U}q29fVUp3Y1sGXzP+c`RhCK;jKeq>hGOKK{3$ARw`@(}9qp$oO58oe z+(QfopUBdS5pHVru8|dpRe!(_QOEV#G9tBsvcitG13FrVwLOd$BqE*Wv!ChazEBRf zTgMISc#>Pyv5&iyapkMUXd${iyLZimeCKGM!WW(xY2-g4fw~EWSjMoAZ2A!Qxdh~8 zd`NQwEIesDBAN_8xvXsOt=$oWFO>1;PRZr$X>G%Lfxs(nX(eKBy`P6yUV7P3??Ulx zf*(+??Cc%kZ2I#g^KK*U^6@q9Wf;Cfk$Hj?X0M{luZ4u z@J6$(l{2og>wW4g$NxG0zLKQ$#ZMrg^W0Mr)FOZC~0@rFl zxI}?|!RR-*=gqEk8X>WBDX&KuQB7=jnYnA-oXRS$fnzC*@>y90xg&jl;NXuM-J2la zZ-4o|)r&MOiZlyVrE745y==HGn7MZ`qB;FhpG69H zr;mKzz?|c`Cx1&=&6&XTdXsN|77CwXQ7WTfV!ci~Uie|dUdBG-Z=^tag`pB(_*h+B ziPgMbzs+42rH=pjn;9YTF?Ux%5ZJ2|KC(WV9?Y-bx)pkGr9Thav(kP6rL;Ei?%685 z=UE5pK6Tb8MqFF#cL|v?J;5_hRG%MXJ1# zJ@tEoEeO?-2_+SNy5RtyMixF0$NNc_*i3pGyoI@o+#jDG(B$rXIELM)!yG-vheqsJ z8NB`XEGXUoLQmEe;1}FFBlgu``~lIJ-%A`t^|7Oy9Wb}uHR!$kThwc-Pi52;Ll^+UYX=Cr zp(!s=>35;n{8!7a69Y+8A7{DxhNCExCs|7=opi>^N&o;@yJHEgP&8?4`;*8c!Fi#! z8N6|r&dc)#;y_=HXKZ*+Bgfa|j2;Sqr?%*(+@LJSxuz*q0QYJx9*e65e4s=Z%qznI zM(@CAm4$FNaB3@ctz#Vgd}yQ zPZI;PE{8~+G@bw@2L;R4>so^(U+V3CUCsHq++8%KfnnK%m3id^6SpLJX5xrFtT1RYzHDv=>R<{GB!~%_J{vJl*vMs|kYa>MgWD09P zEWTZ%PA)|v*c~&c}Ql=ezk3O;57r@VL#D7r!aN7t2Q#WJX4u2 zkFLTKR2GMKjztTvtj6UEv`sNBPBu9{6<76a%mjs&5fg9wsq^IWm1F|)6NUr3=)Myt z{m!#w(Va|WA;!>Cu&NZv=goj4^;j-zTXKBLw5OkbQOVjGy4U7J+NbDnD3@5PK~u6K zmP5|_PnnAevgIE*UUdomry*nt@~VlOin6u4aBh{A@QoE~mT~vi4uuL${NNyf2VdeU zjrJ@Z1Fwg@Z|rFvB~=}9Tq0A4J#!%102bVeAEERlHs>V2qi6YYyiDWh#rxzxPDQfZ zMQxg9)>yeg3`&9kqQGnR%dFq8$j+)QO>Db#L@-E#=x7;Gi%E9RhDE6z3OYp&aHO?l zfMlz>R9g?}4{N8Zj+=?hc0aW0t`J!x^$TZ>F^I^P{D^nu)YL6vj{@n}kVxW`WlM+$ zIR9gsdK*gCxj=C_Ax~pdc?7=o%X<_i6>}&N4hQ-BT>mz#{kU#w5lV~H2_K{PV%M@D z&JWor=f|^zkvsLX2zvNOxpqM^;gV`Q+iUrsPf3a}M$^gXOb$>ZX@2;t0+vfzYaRqJ zadX#wUA+rdtrajX6xv<5Gz1cfmmbMdEX^bKm@rOKuT&I}kWj}2Qzm{B+XPi4K~;-R zoRmiU$*g!F+>y61Pb35(#8BT7oB;{ZI=ng~=7E^+d$UPW|JsI49fHQfw$aV}f@) zNq(g{;!9@T#fYto1JLR+M_Ze8Bv1Oe=A&=Ph#D3y&Ymq86pTm84G3qP;w&eg-^I4*n7#1GBgshz{C9 z-1~iN&SV0i*JpJ{rt0E4SJp%{d`=ffrkGYX!heBV$=CrC;^&>>Xe$|{6_1o)AE&D| z36@|0YfY&FNK@`>g{SmcpHn+svu)bv6;L8hHR)A~omd$g>$}De{@Orzy^(```(qJvfTh9p{h+0TCiN~RylnE}H>eWj*pg2E|mVj#XWA=-Lc^3Zr0WJ3D zxgKdp+;!}wBAMM;M|+mibTrzKQ5Np9pzEKOjjlzLwB}ZS!J#q*%999_b&GE`MrqJ! zxq6tLS96INPPgrk7^E&(7p`9CI;(Fd9-Hf{1f~Vztyw}l;W-_`w3bwR#X+U=nnhAq z%Jx#yr4P&mP;eqtiIJ9u+C}tiv|}nD94|g(?NFdP!#VjoOhWP+K$dxlKoX0|!HbOw zXso+c`KZzb)h=JH`AL|1$;9?%=C%_Sf_%~q(HhLKSN{f%f~f=sJ=ogME`7!O)I|Yq z@>`+72mLNFhq+(7Q4JlsW?Y*vPND3Jt)=m1I>5ofz8Bj9X@*xOo5bwgoio333achb zIKjmQI|n#~*64S4Zhhi;6q>;zg=V%F=-!XnKpQ1A(NP&11etzjb6v;<>ox+SB>VOb zqa+u!6VVugi4@CKiW>K?kaum!jZJjXcW=Xs`ogri0be|U?5Yu|mvJkIJ?L_#OX z7j#l*)YWvz!?_JF57y8*s-}Gk!!Naco@&e0j zar~V;(*>?w&D&eyBZQu4Xy;wvMOG;2#1lCo!898I_^I%376 ziebc^7C&)^eJlr~U%0xLa4z7o#Lk`YbYQ9L2h*CpQTRz|*2_@+`jHn9vrbT@8I0g` zt7Elw#|Pq96gXToS~0mCGJByfoD~+~bwcm8FWZ0*D5 zT1;G7zno^|XR!x5bnircmmfXvl0Hg=4A{9ylbxPP=>Q(%;*m=aeJP-hv-4O-7R>Z{7Y6V<>zqGfQjt9Ot6 zW*oliXHdj8+@gaF%$Dz7J6}Az_TWB|uQ+cW4b~cQc(31(#pBHrzU$&xL))~|;OV=% za+kzTIA!rt_(03z5+6V3dy^U^>ZoOZyTpB!`kda_`X;2HiWh+bD17T!GixoQCbEhu z-)|L@EukHrhwfsdj}S8tqlWN&(XvPQzGD~N&h4^OPTT^}8z6i2+aGl?SJ(mL%vn2g zb`xGB6mto~jDxZIQl-W?e8CUHp{ke({C@5^kYAYUIoRUN-)n587|UyFtpQx@$d%Km zrMfb%$_N3+4^~f;mdnYWIAFBahf;O2m%>AM3|}y{;ox{X(JNrsOhQ;G(o%!s$RENZ zLZxZh3IoEAMvX!b>-Ph=WriRg3+HxebsrELEe0rE=aisT8@leO(*vh)*&rSjb0aC- zk@opc{T1tU_+dfMwV9s)BKH1#0I7cu1FbZF9v}CAe((P7xAy+F@O-I$@8v-4l}G@3 zcLb*_3zTXjgW`lQym6=5AD)>Jm!Kys!j#5gkJ=_LXz|TAM)@N6zPI52D1F~=;Qy$7 z-_Q2`dcLpV`(~~bZBaUOU2)uyHcO*m<(5@9JlZp4!=>@yco{X4&=+LdI7_uSq<--J z9{J`D|K8L7QuaE3R&cD>_-#%EcR-c`$Fb&~`TUc2i4mH&t~9bB@xQPB;`tf9BJ+>f znxBJbpYDhgseji!8$4NbVxzju{UItTok8)Pjj^8cmg6Q~m6OT*xhH&YV`aX~%D~a@ zH$A#@WyFN`k4O0e;nz+7==yfdon!vgs=oA&sV3yFfBJkQ!P~z%IiLh6r|N0{c+A~> z%T7O9M77?3^LH?tw_Ze>_FlMtVvm=&J%swL{B;&8mNDIP1gaG5n!j|5c5d1_kU%R( zzch2yZWySKeqv>6d-7mI5;6P&i^LHnk zLW(LAC$>wtO-cC0jkr{Mg)VH(oNl%&H+12M8J9jH2g-G^V-u$W*wEjD1dQm-;lOGJ z@_Epm!Gdn}=doZug8+joHsDCNL1WunW)Am`I|ZN<+``(S!szD^^bKIyL`;7Cm^le` z_jd?ptpzIX!)dYZ;2=eyB1t;YA6dc>upYWzoH1gWOz2cL=w$Qwd>_5vtCqy%LLcM8 z;`%Um`F_3^Ps?xa1o?v;g|#*Fq= zY4|;QkOWerQBuDrT-Wwp8#>a7UE4dtCNratdbeB2BT&vpe8_?m2!NBsIoK3!(L#OM zUHH2zCM7ZlttOYMxtFE!c}%DwD)gA8pzTb$64!mn`lBKFPRIBc11!fWSEMeEE`Y6& zQG%vyv~Y>n14=IZe~(`cFP;fa78Ai8TTqTE;fu3h&)#^kkRn%?xAfA}Na}Nsu8kaKuVLZ4%NdNh94f=+yncL%>j{#gXK#eYBs2gJ({{A zsiJ>#=LSiL+YZ;#>gapf%U9~F(v;$lrd8HCLmBd<`$PO4m)*1V0f)=u`+-tS9+wa+ z1DMHCDyJMEluewxW2%46q9U55kite1%fc^{Sy@_yG%a&DxJ=VY{N)uh!qc%(_*$oC0x)yf@8eFZiB5cs%@#^Q&vMXDaZ?qbS>0XL+Kc;^3vUC0}lG- zbW;SOB;))1moRyD$Vw@wcGY4r{!m;3KE!t7D&6hxe(Ugfxo~*7eyZx^`aFN{cZo3L zDKO-qBngB~TuoqX(U~!H3TBv!*n-cSG*kUkm{5Tk9?slP@=*a(f+YudW)scF1A=-( z!8v=9=uN1f!DkN2$Y?(`R(DYke_f6)E_%e`aQ$X0K<6zFjoJ!Drn58kZWL9Hv-uuM zpU7l$_)=dLS)K-AQVi=lMD<XCO3mm>>2lo5N})sXOUpC0L`hnf>c;zr?+h2o^+L9` z6PC+v$}sfIo}9*QG!Pm&*xr3=OjS5tS>{a-$|lTFhxZ~EEqS$*eAVWnRsKvmv|H20 zzyjKbv`z7LLyC2*iacu$T2f@@YMpYyb#Qgy^YI7~){{E- z<^3kbA_W1*|Ct8zrh!E<+6>A!S(y-`b;?!L=e8H6?bdUgd~>t}WV2so zs9`$rD>VZNUX;Ey;^{DroKpU-3ZnK3uyXfpTKkhvfy;jQv>9Ehx4`VJJkj82iK}F^WC{| z6~dVFmLT2SAZ=jpBadQ~LyFzU%4%rVllY;C!qiz;m``-F1|X&)9;~YGYijne;IfY# z6Of44^(nD~$rvhsnjq_W_i8X^ox*H$jNfN-`p~i<2`cKl3OAccolNbZgJN~PWhCwu z^4vnO&**c+F#br=ps?JJsYc!8{WST#&i!uieVP4T|G#`saR1>!Y3|Sh&;tSd2TYcV Ap#T5? literal 0 HcmV?d00001 From 67395a7505801ccc2323db825b2520eb81516e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 2 Feb 2016 10:08:40 +0100 Subject: [PATCH 296/523] upload signature file --- .gitignore | 1 + sources | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9b1b40a..b8fffbf 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ /coreutils-8.24.tar.xz /coreutils-8.24.tar.xz.sig /coreutils-8.25.tar.xz +/coreutils-8.25.tar.xz.sig diff --git a/sources b/sources index 2fd7001..52af064 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ 070e43ba7f618d747414ef56ab248a48 coreutils-8.25.tar.xz +eb5694f81fd88ccf16b68ed80935b10f coreutils-8.25.tar.xz.sig From 5440a2d9dbb1f9e1c464e6d71351a3e0a1714660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Tue, 2 Feb 2016 15:08:35 +0100 Subject: [PATCH 297/523] Add new base32 binary to the list of utils --- coreutils.spec | 1 + supported_utils | 1 + 2 files changed, 2 insertions(+) diff --git a/coreutils.spec b/coreutils.spec index 50c1c63..f0413cc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -348,6 +348,7 @@ fi %changelog * Thu Jan 21 2016 Ondrej Vasik - 8.25-2 - Adjust the i18n patch for coreutils-8.25 +- add new base32 binary * Wed Jan 20 2016 Ondrej Vasik - 8.25-1 - new upstream release(#1300282) diff --git a/supported_utils b/supported_utils index 124e14c..c2aed28 100644 --- a/supported_utils +++ b/supported_utils @@ -33,6 +33,7 @@ %{_bindir}/uname %{_bindir}/unlink %{_bindir}/[ +%{_bindir}/base32 %{_bindir}/base64 %{_bindir}/chcon %{_bindir}/cksum From 593569e76bb79541a076b701341fe6e69238efb1 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 11 Feb 2016 17:56:10 +0100 Subject: [PATCH 298/523] Fix the unexpand --- coreutils-i18n-fix-unexpand.patch | 60 +++++++++++++++++++++++++++++++ coreutils.spec | 8 ++++- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 coreutils-i18n-fix-unexpand.patch diff --git a/coreutils-i18n-fix-unexpand.patch b/coreutils-i18n-fix-unexpand.patch new file mode 100644 index 0000000..c7ca839 --- /dev/null +++ b/coreutils-i18n-fix-unexpand.patch @@ -0,0 +1,60 @@ +From lkundrak@v3.sk Thu Jan 28 20:57:48 2016 +Return-Path: lkundrak@v3.sk +Received: from zimbra.v3.sk (LHLO zimbra.v3.sk) (10.13.37.31) by + zimbra.v3.sk with LMTP; Thu, 28 Jan 2016 20:57:48 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) by zimbra.v3.sk (Postfix) + with ESMTP id D4DD260F92 for ; Thu, 28 Jan 2016 20:57:47 + +0100 (CET) +X-Spam-Flag: NO +X-Spam-Score: -2.9 +X-Spam-Level: +X-Spam-Status: No, score=-2.9 tagged_above=-10 required=3 + tests=[ALL_TRUSTED=-1, BAYES_00=-1.9] autolearn=ham autolearn_force=no +Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk + [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id HB5H5ynfOcyL; Thu, 28 + Jan 2016 20:57:45 +0100 (CET) +Received: from localhost (localhost [127.0.0.1]) by zimbra.v3.sk (Postfix) + with ESMTP id 3FEF160F90; Thu, 28 Jan 2016 20:57:45 +0100 (CET) +X-Virus-Scanned: amavisd-new at zimbra.v3.sk +Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk + [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id TUF9p5l6r9SN; Thu, 28 + Jan 2016 20:57:44 +0100 (CET) +Received: from odvarok.localdomain (s559633cb.adsl.online.nl + [85.150.51.203]) by zimbra.v3.sk (Postfix) with ESMTPSA id 6763560F8F; Thu, + 28 Jan 2016 20:57:44 +0100 (CET) +From: Lubomir Rintel +To: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= , Ondrej + Oprala +Cc: Lubomir Rintel +Subject: [PATCH] unexpand: fix blank line handling +Date: Thu, 28 Jan 2016 20:57:22 +0100 +Message-Id: <1454011042-30492-1-git-send-email-lkundrak@v3.sk> +X-Mailer: git-send-email 2.5.0 +X-Evolution-Source: 1409576065.5421.4@dhcp-24-163.brq.redhat.com +Content-Transfer-Encoding: 8bit +Mime-Version: 1.0 + + echo '' |./src/unexpand -a + +Really? +--- + src/unexpand.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/unexpand.c b/src/unexpand.c +index d6ff662..762c56b 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c +@@ -304,7 +304,7 @@ unexpand (void) + next_tab_column = column; + tab_index -= !!tab_index; + } +- else ++ else if (!mb_iseq (c, '\n')) + { + column += mb_width (c); + if (!column) +-- +2.5.0 + + diff --git a/coreutils.spec b/coreutils.spec index f0413cc..700fbb8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -45,6 +45,8 @@ Patch800: coreutils-i18n.patch Patch801: coreutils-i18n-expand-unexpand.patch # (sb) lin18nux/lsb compliance - cut Patch802: coreutils-i18n-cut.patch +# The unexpand patch above is not correct. Sent to the patch authors +Patch803: coreutils-i18n-fix-unexpand.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch @@ -175,6 +177,7 @@ including documentation and translations. %patch800 -p1 -b .i18n %patch801 -p1 -b .i18n-expand %patch802 -p1 -b .i18n-cut +%patch803 -p1 -b .i18n-fix-expand # Coreutils %patch908 -p1 -b .getgrouplist @@ -346,6 +349,9 @@ fi %license COPYING %changelog +* Thu Feb 11 2016 Lubomir Rintel - 8.25-3 +- Fix a regression in unexpand empty line handling + * Thu Jan 21 2016 Ondrej Vasik - 8.25-2 - Adjust the i18n patch for coreutils-8.25 - add new base32 binary From 06a5ca2716fe9b7dfa6f736d931d4cde9807a5d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Mon, 15 Feb 2016 12:47:08 +0100 Subject: [PATCH 299/523] cut: fix regression in handling fields for lines wider than 64 chars (#1304839) --- coreutils-i18n-cut.patch | 5 ++--- coreutils.spec | 6 +++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/coreutils-i18n-cut.patch b/coreutils-i18n-cut.patch index ab72147..ec85cf0 100644 --- a/coreutils-i18n-cut.patch +++ b/coreutils-i18n-cut.patch @@ -107,7 +107,7 @@ /* Return nonzero if K'th byte is the beginning of a range. */ static inline bool -@@ -505,23 +520,216 @@ cut_bytes (FILE *stream) +@@ -505,23 +520,215 @@ cut_bytes (FILE *stream) } /* Read from stream STREAM, printing to standard output any selected fields. */ @@ -210,10 +210,9 @@ + /* Here, if size < nmax, nchars_avail >= buffer_len + 1. + If size == nmax, nchars_avail > 0. */ + -+ if (1 < nchars_avail) ++ if (1 < nchars_avail--) + { + mb_copy(read_pos++, &c); -+ --nchars_avail; + } + + } diff --git a/coreutils.spec b/coreutils.spec index 700fbb8..53b9b03 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -349,6 +349,10 @@ fi %license COPYING %changelog +* Mon Feb 15 2016 Ondrej Vasik - 8.25-4 +- cut: fix regression in handling fields for lines wider + than 64 chars (#1304839) + * Thu Feb 11 2016 Lubomir Rintel - 8.25-3 - Fix a regression in unexpand empty line handling From 96a98c054d7617ef1e2f29281ecc24f277a7a352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 5 Mar 2016 15:28:11 +0100 Subject: [PATCH 300/523] Disable new i18n cut support --- coreutils.spec | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 53b9b03..528b1fa 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -43,8 +43,9 @@ Patch713: coreutils-4.5.3-langinfo.patch Patch800: coreutils-i18n.patch # (sb) lin18nux/lsb compliance - expand/unexpand Patch801: coreutils-i18n-expand-unexpand.patch -# (sb) lin18nux/lsb compliance - cut +# (sb) lin18nux/lsb compliance - cut - not stable enough, not applied Patch802: coreutils-i18n-cut.patch +# i18n patch for cut - old version - used # The unexpand patch above is not correct. Sent to the patch authors Patch803: coreutils-i18n-fix-unexpand.patch @@ -176,7 +177,7 @@ including documentation and translations. # li18nux/lsb %patch800 -p1 -b .i18n %patch801 -p1 -b .i18n-expand -%patch802 -p1 -b .i18n-cut +#%%patch802 -p1 -b .i18n-cut %patch803 -p1 -b .i18n-fix-expand # Coreutils @@ -349,6 +350,9 @@ fi %license COPYING %changelog +* Sat Mar 05 2016 Ondrej Vasik - 8.25-5 +- cut: move back to the old i18n implementation (#1314722) + * Mon Feb 15 2016 Ondrej Vasik - 8.25-4 - cut: fix regression in handling fields for lines wider than 64 chars (#1304839) From b0302efc5081ac24f2740a331d35bf7b7a42c0ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Sat, 5 Mar 2016 15:53:55 +0100 Subject: [PATCH 301/523] adjust old i18n patch cut support for coreutils-8.25 --- coreutils-i18n-cut-old.patch | 564 +++++++++++++++++++++++++++++++++++ coreutils.spec | 2 + 2 files changed, 566 insertions(+) create mode 100644 coreutils-i18n-cut-old.patch diff --git a/coreutils-i18n-cut-old.patch b/coreutils-i18n-cut-old.patch new file mode 100644 index 0000000..29c69fc --- /dev/null +++ b/coreutils-i18n-cut-old.patch @@ -0,0 +1,564 @@ +diff -urNp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c +--- coreutils-8.25-orig/src/cut.c 2015-06-26 19:05:22.000000000 +0200 ++++ coreutils-8.25/src/cut.c 2015-07-05 09:04:33.028546950 +0200 +@@ -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) ++{ ++ size_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; ++ size_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) diff --git a/coreutils.spec b/coreutils.spec index 528b1fa..a056fe0 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -46,6 +46,7 @@ Patch801: coreutils-i18n-expand-unexpand.patch # (sb) lin18nux/lsb compliance - cut - not stable enough, not applied Patch802: coreutils-i18n-cut.patch # i18n patch for cut - old version - used +Patch804: coreutils-i18n-cut-old.patch # The unexpand patch above is not correct. Sent to the patch authors Patch803: coreutils-i18n-fix-unexpand.patch @@ -179,6 +180,7 @@ including documentation and translations. %patch801 -p1 -b .i18n-expand #%%patch802 -p1 -b .i18n-cut %patch803 -p1 -b .i18n-fix-expand +%patch804 -p1 -b .i18n-cutold # Coreutils %patch908 -p1 -b .getgrouplist From 45ce637bf48d3bab2b2804735c720c0c1e41e92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Fri, 22 Apr 2016 14:14:54 +0100 Subject: [PATCH 302/523] maint: remove build workarounds for old upstream bugs * coreutils.spec: coreutils 8.25 fixed a couple of issues, so remove our workarounds. --- coreutils.spec | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index a056fe0..783c211 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -219,10 +219,9 @@ for type in separate single; do %configure $config_single \ --cache-file=../config.cache \ --enable-install-program=arch \ - --enable-no-install-program=uptime \ + --enable-no-install-program=kill,uptime \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : - mkdir src # not needed with coreutils > 8.24 make all %{?_smp_mflags}) done @@ -276,15 +275,6 @@ install -p -c -m644 %SOURCE103 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.256color install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh -# These come from util-linux and/or procps. -# With coreutils > 8.24 one can just add to --enable-no-install-program -# rather than manually removing here, since tests depending on -# built utilities are correctly skipped if not present. -for i in kill ; do - rm -f $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1} - rm -f $RPM_BUILD_ROOT%{_bindir}/$i.single -done - # Compress ChangeLogs from before the fileutils/textutils/etc merge bzip2 -f9 old/*/C* From ffecc6b864a4cb936ae43567677fb00ee26d149c Mon Sep 17 00:00:00 2001 From: Jakub Martisko Date: Tue, 14 Jun 2016 12:47:41 +0200 Subject: [PATCH 303/523] (un)expand: fix regression in handling of input files, where only the first file was processed. --- coreutils-i18n-fix2-expand-unexpand.patch | 104 ++++++++++++++++++++++ coreutils.spec | 9 +- 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 coreutils-i18n-fix2-expand-unexpand.patch diff --git a/coreutils-i18n-fix2-expand-unexpand.patch b/coreutils-i18n-fix2-expand-unexpand.patch new file mode 100644 index 0000000..1f02c5e --- /dev/null +++ b/coreutils-i18n-fix2-expand-unexpand.patch @@ -0,0 +1,104 @@ +diff -up ./src/expand.c.orig ./src/expand.c +--- ./src/expand.c.orig 2016-06-01 12:42:49.330373488 +0200 ++++ ./src/expand.c 2016-06-07 14:35:16.011142041 +0200 +@@ -173,15 +173,19 @@ expand (void) + + do + { +- do { ++ while (true) { + mbf_getc (c, mbf); +- if (mb_iseof (c)) ++ if ((mb_iseof (c)) && (fp = next_file (fp))) + { +- mbf_init (mbf, fp = next_file (fp)); ++ mbf_init (mbf, fp); + continue; + } ++ else ++ { ++ break; ++ } + } +- while (false); ++ + + if (convert) + { +diff -up ./src/unexpand.c.orig ./src/unexpand.c +--- ./src/unexpand.c.orig 2016-06-07 14:26:57.380746446 +0200 ++++ ./src/unexpand.c 2016-06-07 14:34:54.059256698 +0200 +@@ -220,15 +220,19 @@ unexpand (void) + + do + { +- do { ++ while (true) { + mbf_getc (c, mbf); +- if (mb_iseof (c)) ++ if ((mb_iseof (c)) && (fp = next_file (fp))) + { +- mbf_init (mbf, fp = next_file (fp)); ++ mbf_init (mbf, fp); + continue; + } ++ else ++ { ++ break; ++ } + } +- while (false); ++ + + if (convert) + { +diff -up ./tests/expand/mb.sh.orig ./tests/expand/mb.sh +--- ./tests/expand/mb.sh.orig 2016-05-11 14:13:53.095289000 +0200 ++++ ./tests/expand/mb.sh 2016-06-07 14:38:48.259033445 +0200 +@@ -44,6 +44,20 @@ 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) +diff -up ./tests/unexpand/mb.sh.orig ./tests/unexpand/mb.sh +--- ./tests/unexpand/mb.sh.orig 2016-06-07 14:41:44.210106466 +0200 ++++ ./tests/unexpand/mb.sh 2016-06-07 14:52:28.848639772 +0200 +@@ -44,6 +44,22 @@ 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 diff --git a/coreutils.spec b/coreutils.spec index 783c211..8423c32 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -49,6 +49,8 @@ Patch802: coreutils-i18n-cut.patch Patch804: coreutils-i18n-cut-old.patch # The unexpand patch above is not correct. Sent to the patch authors Patch803: coreutils-i18n-fix-unexpand.patch +#(un)expand - allow multiple files on input - broken by patch 801 +Patch805: coreutils-i18n-fix2-expand-unexpand.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch @@ -181,6 +183,7 @@ including documentation and translations. #%%patch802 -p1 -b .i18n-cut %patch803 -p1 -b .i18n-fix-expand %patch804 -p1 -b .i18n-cutold +%patch805 -p1 -b .i18n-fix2-expand-unexpand # Coreutils %patch908 -p1 -b .getgrouplist @@ -342,6 +345,10 @@ fi %license COPYING %changelog +* Thu Jun 09 2016 Jakub Martisko - 8.25-6 +- (un)expand: fix regression in handling input files, where only + the first file was processed. + * Sat Mar 05 2016 Ondrej Vasik - 8.25-5 - cut: move back to the old i18n implementation (#1314722) From 8236de4f4bb46d0145978c6c9abc4160240e82f0 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 15 Jun 2016 17:31:56 +0200 Subject: [PATCH 304/523] handle info doc in RPM scriptlets of coreutils-common ... which provides it --- coreutils.spec | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 8423c32..fd2fad2 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -297,7 +297,7 @@ grep LC_TIME %name.lang | cut -d'/' -f1-6 | sed -e 's/) /) %%dir /g' >>%name.lan # (sb) Deal with Installed (but unpackaged) file(s) found rm -f $RPM_BUILD_ROOT%{_infodir}/dir -%pre +%pre common # We must deinstall these info files since they're merged in # coreutils.info. else their postun'll be run too late # and install-info will fail badly because of duplicates @@ -307,14 +307,14 @@ for file in sh-utils textutils fileutils; do fi done -%preun +%preun common if [ $1 = 0 ]; then if [ -f %{_infodir}/%{name}.info.gz ]; then /sbin/install-info --delete %{_infodir}/%{name}.info.gz %{_infodir}/dir || : fi fi -%post +%post common %{_bindir}/grep -v '(sh-utils)\|(fileutils)\|(textutils)' %{_infodir}/dir > \ %{_infodir}/dir.rpmmodify || exit 0 /bin/mv -f %{_infodir}/dir.rpmmodify %{_infodir}/dir @@ -345,6 +345,9 @@ fi %license COPYING %changelog +* Wed Jun 15 2016 Kamil Dudka - 8.25-7 +- handle info doc in RPM scriptlets of coreutils-common, which provides it + * Thu Jun 09 2016 Jakub Martisko - 8.25-6 - (un)expand: fix regression in handling input files, where only the first file was processed. From 28edec2fbc57acadc5f76950f371cdb93186bdad Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 15 Jun 2016 17:32:29 +0200 Subject: [PATCH 305/523] make sure that the license file is installed ... even if coreutils-common is not --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index fd2fad2..48340ea 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -332,6 +332,9 @@ fi %{_bindir}/*.single %{_sbindir}/chroot.single %{_libexecdir}/coreutils/*.so.single +# duplicate the license because coreutils-common does not need to be installed +%{!?_licensedir:%global license %%doc} +%license COPYING %files common -f %{name}.lang %defattr(-,root,root,-) @@ -341,12 +344,12 @@ fi %{_mandir}/man*/* # The following go to /usr/share/doc/coreutils-common %doc ABOUT-NLS NEWS README THANKS TODO -%{!?_licensedir:%global license %%doc} %license COPYING %changelog * Wed Jun 15 2016 Kamil Dudka - 8.25-7 - handle info doc in RPM scriptlets of coreutils-common, which provides it +- make sure that the license file is installed, even if coreutils-common is not * Thu Jun 09 2016 Jakub Martisko - 8.25-6 - (un)expand: fix regression in handling input files, where only From 50e40c5f2b836e68c4da7987cd4ffee22594a1c4 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 17 Jun 2016 16:19:35 +0200 Subject: [PATCH 306/523] Resolve: #1335320 - sync /etc/DIR_COLORS with latest upstream --- coreutils-DIR_COLORS | 113 +++++++--------------------- coreutils-DIR_COLORS.256color | 101 ++++++++----------------- coreutils-DIR_COLORS.lightbgcolor | 119 ++++++++---------------------- coreutils.spec | 5 +- 4 files changed, 95 insertions(+), 243 deletions(-) diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS index ecffc65..27af9d7 100644 --- a/coreutils-DIR_COLORS +++ b/coreutils-DIR_COLORS @@ -1,34 +1,23 @@ -# Configuration file for the color ls utility -# Synchronized with coreutils 8.5 dircolors +# Configuration file for dircolors, a utility to help you set the +# LS_COLORS environment variable used by GNU ls with the --color option. + # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. -# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not -# pipes. 'all' adds color characters to all output. 'none' shuts colorization -# off. -COLOR tty +# Copyright (C) 1996-2016 Free Software Foundation, Inc. +# Copying and distribution of this file, with or without modification, +# are permitted provided the copyright notice and this notice are preserved. -# Extra command line options for ls go here. -# Basically these ones are: -# -F = show '/' for dirs, '*' for executables, etc. -# -T 0 = don't trust tab spacing when formatting ls output. -OPTIONS -F -T 0 +# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the +# slackware version of dircolors) are recognized but ignored. -# Below, there should be one TERM entry for each termtype that is colorizable +# Below are TERM entries, which can be a glob patterns, to match +# against the TERM environment variable to determine if it is colorizable. TERM Eterm TERM ansi TERM color-xterm -TERM con132x25 -TERM con132x30 -TERM con132x43 -TERM con132x60 -TERM con80x25 -TERM con80x28 -TERM con80x30 -TERM con80x43 -TERM con80x50 -TERM con80x60 +TERM con[0-9]*x[0-9]* TERM cons25 TERM console TERM cygwin @@ -47,34 +36,14 @@ TERM mach-gnu-color TERM mlterm TERM putty TERM putty-256color -TERM rxvt -TERM rxvt-256color -TERM rxvt-cygwin -TERM rxvt-cygwin-native -TERM rxvt-unicode -TERM rxvt-unicode-256color -TERM rxvt-unicode256 -TERM screen -TERM screen-256color -TERM screen-256color-bce -TERM screen-bce -TERM screen-w -TERM screen.Eterm -TERM screen.rxvt -TERM screen.linux +TERM rxvt* +TERM screen* TERM st TERM st-256color TERM terminator +TERM tmux* TERM vt100 -TERM xterm -TERM xterm-16color -TERM xterm-256color -TERM xterm-88color -TERM xterm-color -TERM xterm-debian - -# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) -EIGHTBIT 1 +TERM xterm* # Below are the color init strings for the basic file types. A color init # string consists of one or more of the following numeric codes: @@ -85,18 +54,18 @@ EIGHTBIT 1 # Background color codes: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white #NORMAL 00 # no color code at all -#FILE 00 # normal file, use no color at all +#FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color DIR 01;34 # directory -LINK 01;36 # symbolic link (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 00 # regular file with more than one link +LINK 01;36 # symbolic link. (If you set this to 'target' instead of a + # numerical value, the color is as for the file pointed to.) +MULTIHARDLINK 00 # regular file with more than one link FIFO 40;33 # pipe SOCK 01;35 # socket DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver -ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file +ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... MISSING 01;05;37;41 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) @@ -111,16 +80,19 @@ EXEC 01;32 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. # (and any comments you want to add after a '#') -# executables (bright green) -#.cmd 01;32 + +# If you use DOS-style suffixes, you may want to uncomment the following: +#.cmd 01;32 # executables (bright green) #.exe 01;32 #.com 01;32 #.btm 01;32 #.bat 01;32 +# Or if you want to colorize scripts even if they do not have the +# executable bit actually set. #.sh 01;32 #.csh 01;32 -# archives or compressed (bright red) + # archives or compressed (bright red) .tar 01;31 .tgz 01;31 .arc 01;31 @@ -163,7 +135,7 @@ EXEC 01;32 .rz 01;31 .cab 01;31 -# image formats (magenta) +# image formats .jpg 01;35 .jpeg 01;35 .gif 01;35 @@ -214,7 +186,7 @@ EXEC 01;32 .ogv 01;35 .ogx 01;35 -# audio formats (cyan) +# audio formats .aac 01;36 .au 01;36 .flac 01;36 @@ -233,32 +205,3 @@ EXEC 01;32 .opus 01;36 .spx 01;36 .xspf 01;36 - -# colorize binary documents (brown) -#.pdf 00;33 -#.ps 00;33 -#.ps.gz 00;33 -#.tex 00;33 -#.xls 00;33 -#.xlsx 00;33 -#.ppt 00;33 -#.pptx 00;33 -#.rtf 00;33 -#.doc 00;33 -#.docx 00;33 -#.odt 00;33 -#.ods 00;33 -#.odp 00;33 -#.epub 00;33 -#.abw 00;33 -#.wpd 00;33 -# -# colorize text documents (brown) -#.txt 00;33 -#.patch 00;33 -#.diff 00;33 -#.log 00;33 -#.htm 00;33 -#.html 00;33 -#.shtml 00;33 -#.xml 00;33 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color index cc8cf40..74c34ba 100644 --- a/coreutils-DIR_COLORS.256color +++ b/coreutils-DIR_COLORS.256color @@ -1,39 +1,28 @@ # Configuration file for the 256color ls utility + # This file goes in the /etc directory, and must be world readable. -# Synchronized with coreutils 8.5 dircolors # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. -# In the case that you are not satisfied with supplied colors, please -# submit your color configuration or attach your file with colors readable -# on ALL color background schemas (white,gray,black) to RedHat Bugzilla -# ticket on https://bugzilla.redhat.com/show_bug.cgi?id=429121 . TIA. -# Please just keep ls color conventions from 8 color scheme. -# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not -# pipes. 'all' adds color characters to all output. 'none' shuts colorization -# off. -COLOR tty +# Copyright (C) 1996-2016 Free Software Foundation, Inc. +# Copying and distribution of this file, with or without modification, +# are permitted provided the copyright notice and this notice are preserved. -# Extra command line options for ls go here. -# Basically these ones are: -# -F = show '/' for dirs, '*' for executables, etc. -# -T 0 = don't trust tab spacing when formatting ls output. -OPTIONS -F -T 0 +# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the +# slackware version of dircolors) are recognized but ignored. -# Below, there should be one TERM entry for each termtype that is colorizable +# Below are TERM entries, which can be a glob patterns, to match +# against the TERM environment variable to determine if it is colorizable. TERM *256color* TERM rxvt-unicode256 -# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) -EIGHTBIT 1 - # Below are the color init strings for the basic file types. A color init # string consists of one or more of the following numeric codes: # Attribute codes: # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed -# Text color(8 colors mode) codes: +# Text color codes: # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white -# Background color(8 colors mode) codes: +# Background color codes: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white # Text color(256 colors mode) codes: # Valid syntax for text 256color is 38;5; , where color number @@ -46,20 +35,20 @@ EIGHTBIT 1 # You may find following command useful to search the best one for you: # for ((x=0; x<=255; x++));do echo -e "${x}:\033[48;5;${x}mcolor\033[000m";done -#NORMAL 00 # global default, no color code at all -#FILE 00 # normal file, use no color at all -RESET 0 # reset to "normal" color +#NORMAL 00 # no color code at all +#FILE 00 # regular file: use no color at all +RESET 0 # reset to "normal" color DIR 38;5;33 # directory -LINK 38;5;51 # symbolic link (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 00 # regular file with more than one link +LINK 38;5;51 # symbolic link. (If you set this to 'target' instead of a + # numerical value, the color is as for the file pointed to.) +MULTIHARDLINK 00 # regular file with more than one link FIFO 40;38;5;11 # pipe SOCK 38;5;13 # socket DOOR 38;5;5 # door BLK 48;5;232;38;5;11 # block device driver CHR 48;5;232;38;5;3 # character device driver -ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file -MISSING 01;05;37;41 # ... and the files they point to +ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file ... +MISSING 01;05;37;41 # ... and the files they point to SETUID 48;5;196;38;5;15 # file that is setuid (u+s) SETGID 48;5;11;38;5;16 # file that is setgid (g+s) CAPABILITY 48;5;196;38;5;226 # file with capability @@ -73,16 +62,19 @@ EXEC 38;5;40 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. # (and any comments you want to add after a '#') -# executables (bright green) -#.cmd 38;5;34 -#.exe 38;5;34 -#.com 38;5;34 -#.btm 38;5;34 -#.bat 38;5;34 -#.sh 38;5;34 -#.csh 38;5;34 -# archives or compressed (bright red) +# If you use DOS-style suffixes, you may want to uncomment the following: +#.cmd 01;32 # executables (bright green) +#.exe 01;32 +#.com 01;32 +#.btm 01;32 +#.bat 01;32 +# Or if you want to colorize scripts even if they do not have the +# executable bit actually set. +#.sh 01;32 +#.csh 01;32 + + # archives or compressed (bright red) .tar 38;5;9 .tgz 38;5;9 .arc 38;5;9 @@ -125,7 +117,7 @@ EXEC 38;5;40 .rz 38;5;9 .cab 38;5;9 -# image formats (magenta) +# image formats .jpg 38;5;13 .jpeg 38;5;13 .gif 38;5;13 @@ -176,7 +168,7 @@ EXEC 38;5;40 .ogv 38;5;13 .ogx 38;5;13 -# audio formats (cyan) +# audio formats .aac 38;5;45 .au 38;5;45 .flac 38;5;45 @@ -195,32 +187,3 @@ EXEC 38;5;40 .opus 38;5;45 .spx 38;5;45 .xspf 38;5;45 - -# colorize binary documents (brown) -#.pdf 00;33 -#.ps 00;33 -#.ps.gz 00;33 -#.tex 00;33 -#.xls 00;33 -#.xlsx 00;33 -#.ppt 00;33 -#.pptx 00;33 -#.rtf 00;33 -#.doc 00;33 -#.docx 00;33 -#.odt 00;33 -#.ods 00;33 -#.odp 00;33 -#.epub 00;33 -#.abw 00;33 -#.wpd 00;33 -# -# colorize text documents (brown) -#.txt 00;33 -#.patch 00;33 -#.diff 00;33 -#.log 00;33 -#.htm 00;33 -#.html 00;33 -#.shtml 00;33 -#.xml 00;33 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor index 450deb0..95d6879 100644 --- a/coreutils-DIR_COLORS.lightbgcolor +++ b/coreutils-DIR_COLORS.lightbgcolor @@ -1,34 +1,22 @@ # Configuration file for the color ls utility - modified for lighter backgrounds -# Synchronized with coreutils 8.5 dircolors + # This file goes in the /etc directory, and must be world readable. # You can copy this file to .dir_colors in your $HOME directory to override # the system defaults. -# COLOR needs one of these arguments: 'tty' colorizes output to ttys, but not -# pipes. 'all' adds color characters to all output. 'none' shuts colorization -# off. -COLOR tty +# Copyright (C) 1996-2016 Free Software Foundation, Inc. +# Copying and distribution of this file, with or without modification, +# are permitted provided the copyright notice and this notice are preserved. -# Extra command line options for ls go here. -# Basically these ones are: -# -F = show '/' for dirs, '*' for executables, etc. -# -T 0 = don't trust tab spacing when formatting ls output. -OPTIONS -F -T 0 +# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the +# slackware version of dircolors) are recognized but ignored. -# Below, there should be one TERM entry for each termtype that is colorizable +# Below are TERM entries, which can be a glob patterns, to match +# against the TERM environment variable to determine if it is colorizable. TERM Eterm TERM ansi TERM color-xterm -TERM con132x25 -TERM con132x30 -TERM con132x43 -TERM con132x60 -TERM con80x25 -TERM con80x28 -TERM con80x30 -TERM con80x43 -TERM con80x50 -TERM con80x60 +TERM con[0-9]*x[0-9]* TERM cons25 TERM console TERM cygwin @@ -47,34 +35,14 @@ TERM mach-gnu-color TERM mlterm TERM putty TERM putty-256color -TERM rxvt -TERM rxvt-256color -TERM rxvt-cygwin -TERM rxvt-cygwin-native -TERM rxvt-unicode -TERM rxvt-unicode-256color -TERM rxvt-unicode256 -TERM screen -TERM screen-256color -TERM screen-256color-bce -TERM screen-bce -TERM screen-w -TERM screen.Eterm -TERM screen.rxvt -TERM screen.linux +TERM rxvt* +TERM screen* TERM st TERM st-256color TERM terminator +TERM tmux* TERM vt100 -TERM xterm -TERM xterm-16color -TERM xterm-256color -TERM xterm-88color -TERM xterm-color -TERM xterm-debian - -# EIGHTBIT, followed by '1' for on, '0' for off. (8-bit output) -EIGHTBIT 1 +TERM xterm* # Below are the color init strings for the basic file types. A color init # string consists of one or more of the following numeric codes: @@ -85,18 +53,18 @@ EIGHTBIT 1 # Background color codes: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white #NORMAL 00 # no color code at all -#FILE 00 # normal file, use no color at all +#FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color DIR 00;34 # directory -LINK 00;36 # symbolic link (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 00 # regular file with more than one link +LINK 00;36 # symbolic link. (If you set this to 'target' instead of a + # numerical value, the color is as for the file pointed to.) +MULTIHARDLINK 00 # regular file with more than one link FIFO 40;33 # pipe SOCK 00;35 # socket DOOR 00;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver -ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file +ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... MISSING 01;05;37;41 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) @@ -111,13 +79,17 @@ EXEC 00;32 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. # (and any comments you want to add after a '#') -#.cmd 00;32 # executables (green) -#.exe 00;32 -#.com 00;32 -#.btm 00;32 -#.bat 00;32 -#.sh 00;32 -#.csh 00;32 + +# If you use DOS-style suffixes, you may want to uncomment the following: +#.cmd 01;32 # executables (bright green) +#.exe 01;32 +#.com 01;32 +#.btm 01;32 +#.bat 01;32 +# Or if you want to colorize scripts even if they do not have the +# executable bit actually set. +#.sh 01;32 +#.csh 01;32 # archives or compressed (red) .tar 00;31 @@ -162,7 +134,7 @@ EXEC 00;32 .rz 00;31 .cab 00;31 -# image formats (magenta) +# image formats .jpg 00;35 .jpeg 00;35 .gif 00;35 @@ -213,7 +185,7 @@ EXEC 00;32 .ogv 00;35 .ogx 00;35 -# audio formats (cyan) +# audio formats .aac 00;36 .au 00;36 .flac 00;36 @@ -232,32 +204,3 @@ EXEC 00;32 .opus 00;36 .spx 00;36 .xspf 00;36 - -# colorize binary documents (brown) -#.pdf 00;33 -#.ps 00;33 -#.ps.gz 00;33 -#.tex 00;33 -#.xls 00;33 -#.xlsx 00;33 -#.ppt 00;33 -#.pptx 00;33 -#.rtf 00;33 -#.doc 00;33 -#.docx 00;33 -#.odt 00;33 -#.ods 00;33 -#.odp 00;33 -#.epub 00;33 -#.abw 00;33 -#.wpd 00;33 -# -# colorize text documents (brown) -#.txt 00;33 -#.patch 00;33 -#.diff 00;33 -#.log 00;33 -#.htm 00;33 -#.html 00;33 -#.shtml 00;33 -#.xml 00;33 diff --git a/coreutils.spec b/coreutils.spec index 48340ea..c181af7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -347,6 +347,9 @@ fi %license COPYING %changelog +* Fri Jun 17 2016 Kamil Dudka - 8.25-8 +- sync /etc/DIR_COLORS with latest upstream (#1335320) + * Wed Jun 15 2016 Kamil Dudka - 8.25-7 - handle info doc in RPM scriptlets of coreutils-common, which provides it - make sure that the license file is installed, even if coreutils-common is not From 46ebf91d5fec0925458d6ddd5965d226f09d3797 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 17 Jun 2016 17:07:27 +0200 Subject: [PATCH 307/523] Related: #1335320 - maintain downstream DIR_COLOR* files as a patch ... against src/dircolors.hin rather than full copies of the file. There should be no user-visible change introduced by this commit. This is just to ease the maintenance -- the resulting files cannot diverge from upstream without any notice. --- coreutils-8.25-DIR_COLORS.patch | 643 ++++++++++++++++++++++++++++++ coreutils-DIR_COLORS | 207 ---------- coreutils-DIR_COLORS.256color | 189 --------- coreutils-DIR_COLORS.lightbgcolor | 206 ---------- coreutils.spec | 14 +- 5 files changed, 651 insertions(+), 608 deletions(-) create mode 100644 coreutils-8.25-DIR_COLORS.patch delete mode 100644 coreutils-DIR_COLORS delete mode 100644 coreutils-DIR_COLORS.256color delete mode 100644 coreutils-DIR_COLORS.lightbgcolor diff --git a/coreutils-8.25-DIR_COLORS.patch b/coreutils-8.25-DIR_COLORS.patch new file mode 100644 index 0000000..546241b --- /dev/null +++ b/coreutils-8.25-DIR_COLORS.patch @@ -0,0 +1,643 @@ +From a13bc34f1eeebdf8b87e4b5a570341bb77a62f76 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 17 Jun 2016 16:58:18 +0200 +Subject: [PATCH] downstream changes to default DIR_COLORS + +--- + DIR_COLORS | 38 ++++--- + DIR_COLORS.256color | 290 +++++++++++++++++++++++------------------------- + DIR_COLORS.lightbgcolor | 197 ++++++++++++++++---------------- + 3 files changed, 259 insertions(+), 266 deletions(-) + +diff --git a/DIR_COLORS b/DIR_COLORS +index d2ea453..27af9d7 100644 +--- a/DIR_COLORS ++++ b/DIR_COLORS +@@ -1,6 +1,10 @@ + # Configuration file for dircolors, a utility to help you set the + # LS_COLORS environment variable used by GNU ls with the --color option. + ++# This file goes in the /etc directory, and must be world readable. ++# You can copy this file to .dir_colors in your $HOME directory to override ++# the system defaults. ++ + # Copyright (C) 1996-2016 Free Software Foundation, Inc. + # Copying and distribution of this file, with or without modification, + # are permitted provided the copyright notice and this notice are preserved. +@@ -62,7 +66,7 @@ DOOR 01;35 # door + BLK 40;33;01 # block device driver + CHR 40;33;01 # character device driver + ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... +-MISSING 00 # ... and the files they point to ++MISSING 01;05;37;41 # ... and the files they point to + SETUID 37;41 # file that is setuid (u+s) + SETGID 30;43 # file that is setgid (g+s) + CAPABILITY 30;41 # file with capability +@@ -183,21 +187,21 @@ EXEC 01;32 + .ogx 01;35 + + # audio formats +-.aac 00;36 +-.au 00;36 +-.flac 00;36 +-.m4a 00;36 +-.mid 00;36 +-.midi 00;36 +-.mka 00;36 +-.mp3 00;36 +-.mpc 00;36 +-.ogg 00;36 +-.ra 00;36 +-.wav 00;36 ++.aac 01;36 ++.au 01;36 ++.flac 01;36 ++.m4a 01;36 ++.mid 01;36 ++.midi 01;36 ++.mka 01;36 ++.mp3 01;36 ++.mpc 01;36 ++.ogg 01;36 ++.ra 01;36 ++.wav 01;36 + + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +-.oga 00;36 +-.opus 00;36 +-.spx 00;36 +-.xspf 00;36 ++.oga 01;36 ++.opus 01;36 ++.spx 01;36 ++.xspf 01;36 +diff --git a/DIR_COLORS.256color b/DIR_COLORS.256color +index d2ea453..74c34ba 100644 +--- a/DIR_COLORS.256color ++++ b/DIR_COLORS.256color +@@ -1,5 +1,8 @@ +-# Configuration file for dircolors, a utility to help you set the +-# LS_COLORS environment variable used by GNU ls with the --color option. ++# Configuration file for the 256color ls utility ++ ++# This file goes in the /etc directory, and must be world readable. ++# You can copy this file to .dir_colors in your $HOME directory to override ++# the system defaults. + + # Copyright (C) 1996-2016 Free Software Foundation, Inc. + # Copying and distribution of this file, with or without modification, +@@ -10,36 +13,8 @@ + + # Below are TERM entries, which can be a glob patterns, to match + # against the TERM environment variable to determine if it is colorizable. +-TERM Eterm +-TERM ansi +-TERM color-xterm +-TERM con[0-9]*x[0-9]* +-TERM cons25 +-TERM console +-TERM cygwin +-TERM dtterm +-TERM eterm-color +-TERM gnome +-TERM gnome-256color +-TERM hurd +-TERM jfbterm +-TERM konsole +-TERM kterm +-TERM linux +-TERM linux-c +-TERM mach-color +-TERM mach-gnu-color +-TERM mlterm +-TERM putty +-TERM putty-256color +-TERM rxvt* +-TERM screen* +-TERM st +-TERM st-256color +-TERM terminator +-TERM tmux* +-TERM vt100 +-TERM xterm* ++TERM *256color* ++TERM rxvt-unicode256 + + # Below are the color init strings for the basic file types. A color init + # string consists of one or more of the following numeric codes: +@@ -49,29 +24,40 @@ TERM xterm* + # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white + # Background color codes: + # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white ++# Text color(256 colors mode) codes: ++# Valid syntax for text 256color is 38;5; , where color number ++# is number between 0 and 255. ++# You may find following command useful to search the best one for you: ++# for ((x=0; x<=255; x++));do echo -e "${x}:\033[38;5;${x}mcolor\033[000m";done ++# Background color(256 colors mode) codes: ++# Valid syntax for background 256color is 48;5; , where ++# color number is number between 0 and 255. ++# You may find following command useful to search the best one for you: ++# for ((x=0; x<=255; x++));do echo -e "${x}:\033[48;5;${x}mcolor\033[000m";done ++ + #NORMAL 00 # no color code at all + #FILE 00 # regular file: use no color at all + RESET 0 # reset to "normal" color +-DIR 01;34 # directory +-LINK 01;36 # symbolic link. (If you set this to 'target' instead of a ++DIR 38;5;33 # directory ++LINK 38;5;51 # symbolic link. (If you set this to 'target' instead of a + # numerical value, the color is as for the file pointed to.) + MULTIHARDLINK 00 # regular file with more than one link +-FIFO 40;33 # pipe +-SOCK 01;35 # socket +-DOOR 01;35 # door +-BLK 40;33;01 # block device driver +-CHR 40;33;01 # character device driver +-ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... +-MISSING 00 # ... and the files they point to +-SETUID 37;41 # file that is setuid (u+s) +-SETGID 30;43 # file that is setgid (g+s) +-CAPABILITY 30;41 # file with capability +-STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) +-OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +-STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable ++FIFO 40;38;5;11 # pipe ++SOCK 38;5;13 # socket ++DOOR 38;5;5 # door ++BLK 48;5;232;38;5;11 # block device driver ++CHR 48;5;232;38;5;3 # character device driver ++ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file ... ++MISSING 01;05;37;41 # ... and the files they point to ++SETUID 48;5;196;38;5;15 # file that is setuid (u+s) ++SETGID 48;5;11;38;5;16 # file that is setgid (g+s) ++CAPABILITY 48;5;196;38;5;226 # file with capability ++STICKY_OTHER_WRITABLE 48;5;10;38;5;16 # dir that is sticky and other-writable (+t,o+w) ++OTHER_WRITABLE 48;5;10;38;5;21 # dir that is other-writable (o+w) and not sticky ++STICKY 48;5;21;38;5;15 # dir with the sticky bit set (+t) and not other-writable + + # This is for files with execute permission: +-EXEC 01;32 ++EXEC 38;5;40 + + # List any file extensions like '.gz' or '.tar' that you would like ls + # to colorize below. Put the extension, a space, and the color init string. +@@ -89,115 +75,115 @@ EXEC 01;32 + #.csh 01;32 + + # archives or compressed (bright red) +-.tar 01;31 +-.tgz 01;31 +-.arc 01;31 +-.arj 01;31 +-.taz 01;31 +-.lha 01;31 +-.lz4 01;31 +-.lzh 01;31 +-.lzma 01;31 +-.tlz 01;31 +-.txz 01;31 +-.tzo 01;31 +-.t7z 01;31 +-.zip 01;31 +-.z 01;31 +-.Z 01;31 +-.dz 01;31 +-.gz 01;31 +-.lrz 01;31 +-.lz 01;31 +-.lzo 01;31 +-.xz 01;31 +-.bz2 01;31 +-.bz 01;31 +-.tbz 01;31 +-.tbz2 01;31 +-.tz 01;31 +-.deb 01;31 +-.rpm 01;31 +-.jar 01;31 +-.war 01;31 +-.ear 01;31 +-.sar 01;31 +-.rar 01;31 +-.alz 01;31 +-.ace 01;31 +-.zoo 01;31 +-.cpio 01;31 +-.7z 01;31 +-.rz 01;31 +-.cab 01;31 ++.tar 38;5;9 ++.tgz 38;5;9 ++.arc 38;5;9 ++.arj 38;5;9 ++.taz 38;5;9 ++.lha 38;5;9 ++.lz4 38;5;9 ++.lzh 38;5;9 ++.lzma 38;5;9 ++.tlz 38;5;9 ++.txz 38;5;9 ++.tzo 38;5;9 ++.t7z 38;5;9 ++.zip 38;5;9 ++.z 38;5;9 ++.Z 38;5;9 ++.dz 38;5;9 ++.gz 38;5;9 ++.lrz 38;5;9 ++.lz 38;5;9 ++.lzo 38;5;9 ++.xz 38;5;9 ++.bz2 38;5;9 ++.bz 38;5;9 ++.tbz 38;5;9 ++.tbz2 38;5;9 ++.tz 38;5;9 ++.deb 38;5;9 ++.rpm 38;5;9 ++.jar 38;5;9 ++.war 38;5;9 ++.ear 38;5;9 ++.sar 38;5;9 ++.rar 38;5;9 ++.alz 38;5;9 ++.ace 38;5;9 ++.zoo 38;5;9 ++.cpio 38;5;9 ++.7z 38;5;9 ++.rz 38;5;9 ++.cab 38;5;9 + + # image formats +-.jpg 01;35 +-.jpeg 01;35 +-.gif 01;35 +-.bmp 01;35 +-.pbm 01;35 +-.pgm 01;35 +-.ppm 01;35 +-.tga 01;35 +-.xbm 01;35 +-.xpm 01;35 +-.tif 01;35 +-.tiff 01;35 +-.png 01;35 +-.svg 01;35 +-.svgz 01;35 +-.mng 01;35 +-.pcx 01;35 +-.mov 01;35 +-.mpg 01;35 +-.mpeg 01;35 +-.m2v 01;35 +-.mkv 01;35 +-.webm 01;35 +-.ogm 01;35 +-.mp4 01;35 +-.m4v 01;35 +-.mp4v 01;35 +-.vob 01;35 +-.qt 01;35 +-.nuv 01;35 +-.wmv 01;35 +-.asf 01;35 +-.rm 01;35 +-.rmvb 01;35 +-.flc 01;35 +-.avi 01;35 +-.fli 01;35 +-.flv 01;35 +-.gl 01;35 +-.dl 01;35 +-.xcf 01;35 +-.xwd 01;35 +-.yuv 01;35 +-.cgm 01;35 +-.emf 01;35 ++.jpg 38;5;13 ++.jpeg 38;5;13 ++.gif 38;5;13 ++.bmp 38;5;13 ++.pbm 38;5;13 ++.pgm 38;5;13 ++.ppm 38;5;13 ++.tga 38;5;13 ++.xbm 38;5;13 ++.xpm 38;5;13 ++.tif 38;5;13 ++.tiff 38;5;13 ++.png 38;5;13 ++.svg 38;5;13 ++.svgz 38;5;13 ++.mng 38;5;13 ++.pcx 38;5;13 ++.mov 38;5;13 ++.mpg 38;5;13 ++.mpeg 38;5;13 ++.m2v 38;5;13 ++.mkv 38;5;13 ++.webm 38;5;13 ++.ogm 38;5;13 ++.mp4 38;5;13 ++.m4v 38;5;13 ++.mp4v 38;5;13 ++.vob 38;5;13 ++.qt 38;5;13 ++.nuv 38;5;13 ++.wmv 38;5;13 ++.asf 38;5;13 ++.rm 38;5;13 ++.rmvb 38;5;13 ++.flc 38;5;13 ++.avi 38;5;13 ++.fli 38;5;13 ++.flv 38;5;13 ++.gl 38;5;13 ++.dl 38;5;13 ++.xcf 38;5;13 ++.xwd 38;5;13 ++.yuv 38;5;13 ++.cgm 38;5;13 ++.emf 38;5;13 + + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +-.ogv 01;35 +-.ogx 01;35 ++.ogv 38;5;13 ++.ogx 38;5;13 + + # audio formats +-.aac 00;36 +-.au 00;36 +-.flac 00;36 +-.m4a 00;36 +-.mid 00;36 +-.midi 00;36 +-.mka 00;36 +-.mp3 00;36 +-.mpc 00;36 +-.ogg 00;36 +-.ra 00;36 +-.wav 00;36 ++.aac 38;5;45 ++.au 38;5;45 ++.flac 38;5;45 ++.m4a 38;5;45 ++.mid 38;5;45 ++.midi 38;5;45 ++.mka 38;5;45 ++.mp3 38;5;45 ++.mpc 38;5;45 ++.ogg 38;5;45 ++.ra 38;5;45 ++.wav 38;5;45 + + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +-.oga 00;36 +-.opus 00;36 +-.spx 00;36 +-.xspf 00;36 ++.oga 38;5;45 ++.opus 38;5;45 ++.spx 38;5;45 ++.xspf 38;5;45 +diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor +index d2ea453..95d6879 100644 +--- a/DIR_COLORS.lightbgcolor ++++ b/DIR_COLORS.lightbgcolor +@@ -1,5 +1,8 @@ +-# Configuration file for dircolors, a utility to help you set the +-# LS_COLORS environment variable used by GNU ls with the --color option. ++# Configuration file for the color ls utility - modified for lighter backgrounds ++ ++# This file goes in the /etc directory, and must be world readable. ++# You can copy this file to .dir_colors in your $HOME directory to override ++# the system defaults. + + # Copyright (C) 1996-2016 Free Software Foundation, Inc. + # Copying and distribution of this file, with or without modification, +@@ -52,17 +55,17 @@ TERM xterm* + #NORMAL 00 # no color code at all + #FILE 00 # regular file: use no color at all + RESET 0 # reset to "normal" color +-DIR 01;34 # directory +-LINK 01;36 # symbolic link. (If you set this to 'target' instead of a ++DIR 00;34 # directory ++LINK 00;36 # symbolic link. (If you set this to 'target' instead of a + # numerical value, the color is as for the file pointed to.) + MULTIHARDLINK 00 # regular file with more than one link + FIFO 40;33 # pipe +-SOCK 01;35 # socket +-DOOR 01;35 # door ++SOCK 00;35 # socket ++DOOR 00;35 # door + BLK 40;33;01 # block device driver + CHR 40;33;01 # character device driver + ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... +-MISSING 00 # ... and the files they point to ++MISSING 01;05;37;41 # ... and the files they point to + SETUID 37;41 # file that is setuid (u+s) + SETGID 30;43 # file that is setgid (g+s) + CAPABILITY 30;41 # file with capability +@@ -71,7 +74,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky + STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable + + # This is for files with execute permission: +-EXEC 01;32 ++EXEC 00;32 + + # List any file extensions like '.gz' or '.tar' that you would like ls + # to colorize below. Put the extension, a space, and the color init string. +@@ -88,99 +91,99 @@ EXEC 01;32 + #.sh 01;32 + #.csh 01;32 + +- # archives or compressed (bright red) +-.tar 01;31 +-.tgz 01;31 +-.arc 01;31 +-.arj 01;31 +-.taz 01;31 +-.lha 01;31 +-.lz4 01;31 +-.lzh 01;31 +-.lzma 01;31 +-.tlz 01;31 +-.txz 01;31 +-.tzo 01;31 +-.t7z 01;31 +-.zip 01;31 +-.z 01;31 +-.Z 01;31 +-.dz 01;31 +-.gz 01;31 +-.lrz 01;31 +-.lz 01;31 +-.lzo 01;31 +-.xz 01;31 +-.bz2 01;31 +-.bz 01;31 +-.tbz 01;31 +-.tbz2 01;31 +-.tz 01;31 +-.deb 01;31 +-.rpm 01;31 +-.jar 01;31 +-.war 01;31 +-.ear 01;31 +-.sar 01;31 +-.rar 01;31 +-.alz 01;31 +-.ace 01;31 +-.zoo 01;31 +-.cpio 01;31 +-.7z 01;31 +-.rz 01;31 +-.cab 01;31 ++# archives or compressed (red) ++.tar 00;31 ++.tgz 00;31 ++.arc 00;31 ++.arj 00;31 ++.taz 00;31 ++.lha 00;31 ++.lz4 00;31 ++.lzh 00;31 ++.lzma 00;31 ++.tlz 00;31 ++.txz 00;31 ++.tzo 00;31 ++.t7z 00;31 ++.zip 00;31 ++.z 00;31 ++.Z 00;31 ++.dz 00;31 ++.gz 00;31 ++.lrz 00;31 ++.lz 00;31 ++.lzo 00;31 ++.xz 00;31 ++.bz2 00;31 ++.bz 00;31 ++.tbz 00;31 ++.tbz2 00;31 ++.tz 00;31 ++.deb 00;31 ++.rpm 00;31 ++.jar 00;31 ++.war 00;31 ++.ear 00;31 ++.sar 00;31 ++.rar 00;31 ++.alz 00;31 ++.ace 00;31 ++.zoo 00;31 ++.cpio 00;31 ++.7z 00;31 ++.rz 00;31 ++.cab 00;31 + + # image formats +-.jpg 01;35 +-.jpeg 01;35 +-.gif 01;35 +-.bmp 01;35 +-.pbm 01;35 +-.pgm 01;35 +-.ppm 01;35 +-.tga 01;35 +-.xbm 01;35 +-.xpm 01;35 +-.tif 01;35 +-.tiff 01;35 +-.png 01;35 +-.svg 01;35 +-.svgz 01;35 +-.mng 01;35 +-.pcx 01;35 +-.mov 01;35 +-.mpg 01;35 +-.mpeg 01;35 +-.m2v 01;35 +-.mkv 01;35 +-.webm 01;35 +-.ogm 01;35 +-.mp4 01;35 +-.m4v 01;35 +-.mp4v 01;35 +-.vob 01;35 +-.qt 01;35 +-.nuv 01;35 +-.wmv 01;35 +-.asf 01;35 +-.rm 01;35 +-.rmvb 01;35 +-.flc 01;35 +-.avi 01;35 +-.fli 01;35 +-.flv 01;35 +-.gl 01;35 +-.dl 01;35 +-.xcf 01;35 +-.xwd 01;35 +-.yuv 01;35 +-.cgm 01;35 +-.emf 01;35 ++.jpg 00;35 ++.jpeg 00;35 ++.gif 00;35 ++.bmp 00;35 ++.pbm 00;35 ++.pgm 00;35 ++.ppm 00;35 ++.tga 00;35 ++.xbm 00;35 ++.xpm 00;35 ++.tif 00;35 ++.tiff 00;35 ++.png 00;35 ++.svg 00;35 ++.svgz 00;35 ++.mng 00;35 ++.pcx 00;35 ++.mov 00;35 ++.mpg 00;35 ++.mpeg 00;35 ++.m2v 00;35 ++.mkv 00;35 ++.webm 00;35 ++.ogm 00;35 ++.mp4 00;35 ++.m4v 00;35 ++.mp4v 00;35 ++.vob 00;35 ++.qt 00;35 ++.nuv 00;35 ++.wmv 00;35 ++.asf 00;35 ++.rm 00;35 ++.rmvb 00;35 ++.flc 00;35 ++.avi 00;35 ++.fli 00;35 ++.flv 00;35 ++.gl 00;35 ++.dl 00;35 ++.xcf 00;35 ++.xwd 00;35 ++.yuv 00;35 ++.cgm 00;35 ++.emf 00;35 + + # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions +-.ogv 01;35 +-.ogx 01;35 ++.ogv 00;35 ++.ogx 00;35 + + # audio formats + .aac 00;36 +-- +2.5.5 + diff --git a/coreutils-DIR_COLORS b/coreutils-DIR_COLORS deleted file mode 100644 index 27af9d7..0000000 --- a/coreutils-DIR_COLORS +++ /dev/null @@ -1,207 +0,0 @@ -# Configuration file for dircolors, a utility to help you set the -# LS_COLORS environment variable used by GNU ls with the --color option. - -# This file goes in the /etc directory, and must be world readable. -# You can copy this file to .dir_colors in your $HOME directory to override -# the system defaults. - -# Copyright (C) 1996-2016 Free Software Foundation, Inc. -# Copying and distribution of this file, with or without modification, -# are permitted provided the copyright notice and this notice are preserved. - -# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the -# slackware version of dircolors) are recognized but ignored. - -# Below are TERM entries, which can be a glob patterns, to match -# against the TERM environment variable to determine if it is colorizable. -TERM Eterm -TERM ansi -TERM color-xterm -TERM con[0-9]*x[0-9]* -TERM cons25 -TERM console -TERM cygwin -TERM dtterm -TERM eterm-color -TERM gnome -TERM gnome-256color -TERM hurd -TERM jfbterm -TERM konsole -TERM kterm -TERM linux -TERM linux-c -TERM mach-color -TERM mach-gnu-color -TERM mlterm -TERM putty -TERM putty-256color -TERM rxvt* -TERM screen* -TERM st -TERM st-256color -TERM terminator -TERM tmux* -TERM vt100 -TERM xterm* - -# Below are the color init strings for the basic file types. A color init -# string consists of one or more of the following numeric codes: -# Attribute codes: -# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed -# Text color codes: -# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white -# Background color codes: -# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -#NORMAL 00 # no color code at all -#FILE 00 # regular file: use no color at all -RESET 0 # reset to "normal" color -DIR 01;34 # directory -LINK 01;36 # symbolic link. (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 00 # regular file with more than one link -FIFO 40;33 # pipe -SOCK 01;35 # socket -DOOR 01;35 # door -BLK 40;33;01 # block device driver -CHR 40;33;01 # character device driver -ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 01;05;37;41 # ... and the files they point to -SETUID 37;41 # file that is setuid (u+s) -SETGID 30;43 # file that is setgid (g+s) -CAPABILITY 30;41 # file with capability -STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) -OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky -STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable - -# This is for files with execute permission: -EXEC 01;32 - -# List any file extensions like '.gz' or '.tar' that you would like ls -# to colorize below. Put the extension, a space, and the color init string. -# (and any comments you want to add after a '#') - -# If you use DOS-style suffixes, you may want to uncomment the following: -#.cmd 01;32 # executables (bright green) -#.exe 01;32 -#.com 01;32 -#.btm 01;32 -#.bat 01;32 -# Or if you want to colorize scripts even if they do not have the -# executable bit actually set. -#.sh 01;32 -#.csh 01;32 - - # archives or compressed (bright red) -.tar 01;31 -.tgz 01;31 -.arc 01;31 -.arj 01;31 -.taz 01;31 -.lha 01;31 -.lz4 01;31 -.lzh 01;31 -.lzma 01;31 -.tlz 01;31 -.txz 01;31 -.tzo 01;31 -.t7z 01;31 -.zip 01;31 -.z 01;31 -.Z 01;31 -.dz 01;31 -.gz 01;31 -.lrz 01;31 -.lz 01;31 -.lzo 01;31 -.xz 01;31 -.bz2 01;31 -.bz 01;31 -.tbz 01;31 -.tbz2 01;31 -.tz 01;31 -.deb 01;31 -.rpm 01;31 -.jar 01;31 -.war 01;31 -.ear 01;31 -.sar 01;31 -.rar 01;31 -.alz 01;31 -.ace 01;31 -.zoo 01;31 -.cpio 01;31 -.7z 01;31 -.rz 01;31 -.cab 01;31 - -# image formats -.jpg 01;35 -.jpeg 01;35 -.gif 01;35 -.bmp 01;35 -.pbm 01;35 -.pgm 01;35 -.ppm 01;35 -.tga 01;35 -.xbm 01;35 -.xpm 01;35 -.tif 01;35 -.tiff 01;35 -.png 01;35 -.svg 01;35 -.svgz 01;35 -.mng 01;35 -.pcx 01;35 -.mov 01;35 -.mpg 01;35 -.mpeg 01;35 -.m2v 01;35 -.mkv 01;35 -.webm 01;35 -.ogm 01;35 -.mp4 01;35 -.m4v 01;35 -.mp4v 01;35 -.vob 01;35 -.qt 01;35 -.nuv 01;35 -.wmv 01;35 -.asf 01;35 -.rm 01;35 -.rmvb 01;35 -.flc 01;35 -.avi 01;35 -.fli 01;35 -.flv 01;35 -.gl 01;35 -.dl 01;35 -.xcf 01;35 -.xwd 01;35 -.yuv 01;35 -.cgm 01;35 -.emf 01;35 - -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.ogv 01;35 -.ogx 01;35 - -# audio formats -.aac 01;36 -.au 01;36 -.flac 01;36 -.m4a 01;36 -.mid 01;36 -.midi 01;36 -.mka 01;36 -.mp3 01;36 -.mpc 01;36 -.ogg 01;36 -.ra 01;36 -.wav 01;36 - -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.oga 01;36 -.opus 01;36 -.spx 01;36 -.xspf 01;36 diff --git a/coreutils-DIR_COLORS.256color b/coreutils-DIR_COLORS.256color deleted file mode 100644 index 74c34ba..0000000 --- a/coreutils-DIR_COLORS.256color +++ /dev/null @@ -1,189 +0,0 @@ -# Configuration file for the 256color ls utility - -# This file goes in the /etc directory, and must be world readable. -# You can copy this file to .dir_colors in your $HOME directory to override -# the system defaults. - -# Copyright (C) 1996-2016 Free Software Foundation, Inc. -# Copying and distribution of this file, with or without modification, -# are permitted provided the copyright notice and this notice are preserved. - -# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the -# slackware version of dircolors) are recognized but ignored. - -# Below are TERM entries, which can be a glob patterns, to match -# against the TERM environment variable to determine if it is colorizable. -TERM *256color* -TERM rxvt-unicode256 - -# Below are the color init strings for the basic file types. A color init -# string consists of one or more of the following numeric codes: -# Attribute codes: -# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed -# Text color codes: -# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white -# Background color codes: -# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -# Text color(256 colors mode) codes: -# Valid syntax for text 256color is 38;5; , where color number -# is number between 0 and 255. -# You may find following command useful to search the best one for you: -# for ((x=0; x<=255; x++));do echo -e "${x}:\033[38;5;${x}mcolor\033[000m";done -# Background color(256 colors mode) codes: -# Valid syntax for background 256color is 48;5; , where -# color number is number between 0 and 255. -# You may find following command useful to search the best one for you: -# for ((x=0; x<=255; x++));do echo -e "${x}:\033[48;5;${x}mcolor\033[000m";done - -#NORMAL 00 # no color code at all -#FILE 00 # regular file: use no color at all -RESET 0 # reset to "normal" color -DIR 38;5;33 # directory -LINK 38;5;51 # symbolic link. (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 00 # regular file with more than one link -FIFO 40;38;5;11 # pipe -SOCK 38;5;13 # socket -DOOR 38;5;5 # door -BLK 48;5;232;38;5;11 # block device driver -CHR 48;5;232;38;5;3 # character device driver -ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file ... -MISSING 01;05;37;41 # ... and the files they point to -SETUID 48;5;196;38;5;15 # file that is setuid (u+s) -SETGID 48;5;11;38;5;16 # file that is setgid (g+s) -CAPABILITY 48;5;196;38;5;226 # file with capability -STICKY_OTHER_WRITABLE 48;5;10;38;5;16 # dir that is sticky and other-writable (+t,o+w) -OTHER_WRITABLE 48;5;10;38;5;21 # dir that is other-writable (o+w) and not sticky -STICKY 48;5;21;38;5;15 # dir with the sticky bit set (+t) and not other-writable - -# This is for files with execute permission: -EXEC 38;5;40 - -# List any file extensions like '.gz' or '.tar' that you would like ls -# to colorize below. Put the extension, a space, and the color init string. -# (and any comments you want to add after a '#') - -# If you use DOS-style suffixes, you may want to uncomment the following: -#.cmd 01;32 # executables (bright green) -#.exe 01;32 -#.com 01;32 -#.btm 01;32 -#.bat 01;32 -# Or if you want to colorize scripts even if they do not have the -# executable bit actually set. -#.sh 01;32 -#.csh 01;32 - - # archives or compressed (bright red) -.tar 38;5;9 -.tgz 38;5;9 -.arc 38;5;9 -.arj 38;5;9 -.taz 38;5;9 -.lha 38;5;9 -.lz4 38;5;9 -.lzh 38;5;9 -.lzma 38;5;9 -.tlz 38;5;9 -.txz 38;5;9 -.tzo 38;5;9 -.t7z 38;5;9 -.zip 38;5;9 -.z 38;5;9 -.Z 38;5;9 -.dz 38;5;9 -.gz 38;5;9 -.lrz 38;5;9 -.lz 38;5;9 -.lzo 38;5;9 -.xz 38;5;9 -.bz2 38;5;9 -.bz 38;5;9 -.tbz 38;5;9 -.tbz2 38;5;9 -.tz 38;5;9 -.deb 38;5;9 -.rpm 38;5;9 -.jar 38;5;9 -.war 38;5;9 -.ear 38;5;9 -.sar 38;5;9 -.rar 38;5;9 -.alz 38;5;9 -.ace 38;5;9 -.zoo 38;5;9 -.cpio 38;5;9 -.7z 38;5;9 -.rz 38;5;9 -.cab 38;5;9 - -# image formats -.jpg 38;5;13 -.jpeg 38;5;13 -.gif 38;5;13 -.bmp 38;5;13 -.pbm 38;5;13 -.pgm 38;5;13 -.ppm 38;5;13 -.tga 38;5;13 -.xbm 38;5;13 -.xpm 38;5;13 -.tif 38;5;13 -.tiff 38;5;13 -.png 38;5;13 -.svg 38;5;13 -.svgz 38;5;13 -.mng 38;5;13 -.pcx 38;5;13 -.mov 38;5;13 -.mpg 38;5;13 -.mpeg 38;5;13 -.m2v 38;5;13 -.mkv 38;5;13 -.webm 38;5;13 -.ogm 38;5;13 -.mp4 38;5;13 -.m4v 38;5;13 -.mp4v 38;5;13 -.vob 38;5;13 -.qt 38;5;13 -.nuv 38;5;13 -.wmv 38;5;13 -.asf 38;5;13 -.rm 38;5;13 -.rmvb 38;5;13 -.flc 38;5;13 -.avi 38;5;13 -.fli 38;5;13 -.flv 38;5;13 -.gl 38;5;13 -.dl 38;5;13 -.xcf 38;5;13 -.xwd 38;5;13 -.yuv 38;5;13 -.cgm 38;5;13 -.emf 38;5;13 - -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.ogv 38;5;13 -.ogx 38;5;13 - -# audio formats -.aac 38;5;45 -.au 38;5;45 -.flac 38;5;45 -.m4a 38;5;45 -.mid 38;5;45 -.midi 38;5;45 -.mka 38;5;45 -.mp3 38;5;45 -.mpc 38;5;45 -.ogg 38;5;45 -.ra 38;5;45 -.wav 38;5;45 - -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.oga 38;5;45 -.opus 38;5;45 -.spx 38;5;45 -.xspf 38;5;45 diff --git a/coreutils-DIR_COLORS.lightbgcolor b/coreutils-DIR_COLORS.lightbgcolor deleted file mode 100644 index 95d6879..0000000 --- a/coreutils-DIR_COLORS.lightbgcolor +++ /dev/null @@ -1,206 +0,0 @@ -# Configuration file for the color ls utility - modified for lighter backgrounds - -# This file goes in the /etc directory, and must be world readable. -# You can copy this file to .dir_colors in your $HOME directory to override -# the system defaults. - -# Copyright (C) 1996-2016 Free Software Foundation, Inc. -# Copying and distribution of this file, with or without modification, -# are permitted provided the copyright notice and this notice are preserved. - -# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the -# slackware version of dircolors) are recognized but ignored. - -# Below are TERM entries, which can be a glob patterns, to match -# against the TERM environment variable to determine if it is colorizable. -TERM Eterm -TERM ansi -TERM color-xterm -TERM con[0-9]*x[0-9]* -TERM cons25 -TERM console -TERM cygwin -TERM dtterm -TERM eterm-color -TERM gnome -TERM gnome-256color -TERM hurd -TERM jfbterm -TERM konsole -TERM kterm -TERM linux -TERM linux-c -TERM mach-color -TERM mach-gnu-color -TERM mlterm -TERM putty -TERM putty-256color -TERM rxvt* -TERM screen* -TERM st -TERM st-256color -TERM terminator -TERM tmux* -TERM vt100 -TERM xterm* - -# Below are the color init strings for the basic file types. A color init -# string consists of one or more of the following numeric codes: -# Attribute codes: -# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed -# Text color codes: -# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white -# Background color codes: -# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -#NORMAL 00 # no color code at all -#FILE 00 # regular file: use no color at all -RESET 0 # reset to "normal" color -DIR 00;34 # directory -LINK 00;36 # symbolic link. (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 00 # regular file with more than one link -FIFO 40;33 # pipe -SOCK 00;35 # socket -DOOR 00;35 # door -BLK 40;33;01 # block device driver -CHR 40;33;01 # character device driver -ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 01;05;37;41 # ... and the files they point to -SETUID 37;41 # file that is setuid (u+s) -SETGID 30;43 # file that is setgid (g+s) -CAPABILITY 30;41 # file with capability -STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) -OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky -STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable - -# This is for files with execute permission: -EXEC 00;32 - -# List any file extensions like '.gz' or '.tar' that you would like ls -# to colorize below. Put the extension, a space, and the color init string. -# (and any comments you want to add after a '#') - -# If you use DOS-style suffixes, you may want to uncomment the following: -#.cmd 01;32 # executables (bright green) -#.exe 01;32 -#.com 01;32 -#.btm 01;32 -#.bat 01;32 -# Or if you want to colorize scripts even if they do not have the -# executable bit actually set. -#.sh 01;32 -#.csh 01;32 - -# archives or compressed (red) -.tar 00;31 -.tgz 00;31 -.arc 00;31 -.arj 00;31 -.taz 00;31 -.lha 00;31 -.lz4 00;31 -.lzh 00;31 -.lzma 00;31 -.tlz 00;31 -.txz 00;31 -.tzo 00;31 -.t7z 00;31 -.zip 00;31 -.z 00;31 -.Z 00;31 -.dz 00;31 -.gz 00;31 -.lrz 00;31 -.lz 00;31 -.lzo 00;31 -.xz 00;31 -.bz2 00;31 -.bz 00;31 -.tbz 00;31 -.tbz2 00;31 -.tz 00;31 -.deb 00;31 -.rpm 00;31 -.jar 00;31 -.war 00;31 -.ear 00;31 -.sar 00;31 -.rar 00;31 -.alz 00;31 -.ace 00;31 -.zoo 00;31 -.cpio 00;31 -.7z 00;31 -.rz 00;31 -.cab 00;31 - -# image formats -.jpg 00;35 -.jpeg 00;35 -.gif 00;35 -.bmp 00;35 -.pbm 00;35 -.pgm 00;35 -.ppm 00;35 -.tga 00;35 -.xbm 00;35 -.xpm 00;35 -.tif 00;35 -.tiff 00;35 -.png 00;35 -.svg 00;35 -.svgz 00;35 -.mng 00;35 -.pcx 00;35 -.mov 00;35 -.mpg 00;35 -.mpeg 00;35 -.m2v 00;35 -.mkv 00;35 -.webm 00;35 -.ogm 00;35 -.mp4 00;35 -.m4v 00;35 -.mp4v 00;35 -.vob 00;35 -.qt 00;35 -.nuv 00;35 -.wmv 00;35 -.asf 00;35 -.rm 00;35 -.rmvb 00;35 -.flc 00;35 -.avi 00;35 -.fli 00;35 -.flv 00;35 -.gl 00;35 -.dl 00;35 -.xcf 00;35 -.xwd 00;35 -.yuv 00;35 -.cgm 00;35 -.emf 00;35 - -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.ogv 00;35 -.ogx 00;35 - -# audio formats -.aac 00;36 -.au 00;36 -.flac 00;36 -.m4a 00;36 -.mid 00;36 -.midi 00;36 -.mka 00;36 -.mp3 00;36 -.mpc 00;36 -.ogg 00;36 -.ra 00;36 -.wav 00;36 - -# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions -.oga 00;36 -.opus 00;36 -.spx 00;36 -.xspf 00;36 diff --git a/coreutils.spec b/coreutils.spec index c181af7..00c5fc6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -8,9 +8,6 @@ Url: http://www.gnu.org/software/coreutils/ Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source2: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig Source50: supported_utils -Source101: coreutils-DIR_COLORS -Source102: coreutils-DIR_COLORS.lightbgcolor -Source103: coreutils-DIR_COLORS.256color Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh @@ -27,6 +24,8 @@ Source10: coreutils-find-requires.sh Patch100: coreutils-6.10-configuration.patch #add note about no difference between binary/text mode on Linux - md5sum manpage Patch101: coreutils-6.10-manpages.patch +# downstream changes to default DIR_COLORS +Patch102: coreutils-8.25-DIR_COLORS.patch #do display processor type for uname -p/-i based on uname(2) syscall Patch103: coreutils-8.2-uname-processortype.patch #df --direct @@ -166,9 +165,13 @@ including documentation and translations. %prep %setup -q +# will be modified by coreutils-8.25-DIR_COLORS.patch +tee DIR_COLORS{,.256color,.lightbgcolor} < src/dircolors.hin + # Our patches %patch100 -p1 -b .configure %patch101 -p1 -b .manpages +%patch102 -p1 %patch103 -p1 -b .sysinfo %patch104 -p1 -b .dfdirect %patch107 -p1 -b .mkdirmode @@ -272,9 +275,8 @@ fi bzip2 -9f ChangeLog mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d -install -p -c -m644 %SOURCE101 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS -install -p -c -m644 %SOURCE102 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.lightbgcolor -install -p -c -m644 %SOURCE103 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.256color +install -p -c -m644 DIR_COLORS{,.256color,.lightbgcolor} \ + $RPM_BUILD_ROOT%{_sysconfdir} install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh From 3b6df16a3d127c6fbe30e77cc907ea38ef916c15 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 20 Jun 2016 16:00:47 +0200 Subject: [PATCH 308/523] Resolves: #1348043 - do not use /bin/mv in %post ... to avoid a circular dependency. The code where /bin/mv was used does not seem to be useful any more. Fileutils, Shellutils, and Textutils were merged into GNU Coreutils in 2002. It should be safe not to handle the transition now in 2016. --- coreutils.spec | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 00c5fc6..5206c3f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -114,11 +114,7 @@ BuildRequires: attr BuildRequires: strace Requires: %{name}-common = %{version}-%{release} -Requires(pre): /sbin/install-info -Requires(preun): /sbin/install-info -Requires(post): /sbin/install-info -Requires(post): grep -Requires: ncurses +Requires: ncurses Provides: fileutils = %{version}-%{release} Provides: sh-utils = %{version}-%{release} @@ -157,6 +153,9 @@ packaged as a single multicall binary. # yum obsoleting rules explained at: # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 +Requires(pre): /sbin/install-info +Requires(preun): /sbin/install-info +Requires(post): /sbin/install-info Summary: coreutils common optional components %description common Optional though recommended components, @@ -317,9 +316,6 @@ if [ $1 = 0 ]; then fi %post common -%{_bindir}/grep -v '(sh-utils)\|(fileutils)\|(textutils)' %{_infodir}/dir > \ - %{_infodir}/dir.rpmmodify || exit 0 - /bin/mv -f %{_infodir}/dir.rpmmodify %{_infodir}/dir if [ -f %{_infodir}/%{name}.info.gz ]; then /sbin/install-info %{_infodir}/%{name}.info.gz %{_infodir}/dir || : fi @@ -349,6 +345,9 @@ fi %license COPYING %changelog +* Mon Jun 20 2016 Kamil Dudka - 8.25-9 +- do not use /bin/mv in %%post to avoid a circular dependency (#1348043) + * Fri Jun 17 2016 Kamil Dudka - 8.25-8 - sync /etc/DIR_COLORS with latest upstream (#1335320) From 0433f98b1b33fc061c62eb2cae419d75d31d4530 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 20 Jun 2016 16:37:32 +0200 Subject: [PATCH 309/523] coreutils.spec: sort BuildRequires alphabetically No observable changes intended. Just to ease the maintenance. --- coreutils.spec | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 5206c3f..c6f3770 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -100,18 +100,19 @@ Provides: /bin/touch Provides: /bin/true Provides: /bin/uname -BuildRequires: libselinux-devel -BuildRequires: libacl-devel -BuildRequires: gettext bison -BuildRequires: texinfo +BuildRequires: attr BuildRequires: autoconf BuildRequires: automake -BuildRequires: libcap-devel -BuildRequires: libattr-devel -BuildRequires: openssl-devel +BuildRequires: bison +BuildRequires: gettext BuildRequires: gmp-devel -BuildRequires: attr +BuildRequires: libacl-devel +BuildRequires: libattr-devel +BuildRequires: libcap-devel +BuildRequires: libselinux-devel +BuildRequires: openssl-devel BuildRequires: strace +BuildRequires: texinfo Requires: %{name}-common = %{version}-%{release} Requires: ncurses From ee3bfc24ca4a94fb7667021aafc6dc69b9915c0f Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 20 Jun 2016 16:42:47 +0200 Subject: [PATCH 310/523] add BR for glibc-langpack-en to prevent the expand/mb test from failing --- coreutils.spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/coreutils.spec b/coreutils.spec index c6f3770..e6cf348 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -114,6 +114,11 @@ BuildRequires: openssl-devel BuildRequires: strace BuildRequires: texinfo +%if 23 < 0%{?fedora} || 7 < 0%{?rhel} +# needed by i18n test-cases +BuildRequires: glibc-langpack-en +%endif + Requires: %{name}-common = %{version}-%{release} Requires: ncurses @@ -347,6 +352,7 @@ fi %changelog * Mon Jun 20 2016 Kamil Dudka - 8.25-9 +- add BR for glibc-langpack-en to prevent the expand/mb test from failing - do not use /bin/mv in %%post to avoid a circular dependency (#1348043) * Fri Jun 17 2016 Kamil Dudka - 8.25-8 From 34ffa2ef55d8b8ecfd3d8539f7a07f109726d7c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= Date: Fri, 24 Jun 2016 12:45:22 +0200 Subject: [PATCH 311/523] change way of detection of interactive shell in colorls.sh script --- coreutils-colorls.sh | 2 +- coreutils.spec | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index cfd2288..ac92268 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -1,7 +1,7 @@ # color-ls initialization # Skip all for noninteractive shells. -[ -z "$PS1" ] && return +[ ! -t 0 ] && return #when USER_LS_COLORS defined do not override user LS_COLORS, but use them. if [ -z "$USER_LS_COLORS" ]; then diff --git a/coreutils.spec b/coreutils.spec index e6cf348..4abace5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -351,6 +351,10 @@ fi %license COPYING %changelog +* Fri Jun 24 2016 Ondrej Vasik - 8.25-10 +- change way of detection of interactive shell in colorls.sh script + (#1321648) + * Mon Jun 20 2016 Kamil Dudka - 8.25-9 - add BR for glibc-langpack-en to prevent the expand/mb test from failing - do not use /bin/mv in %%post to avoid a circular dependency (#1348043) From 0a63fa44ae6dae29c7515b5fa4e6f581c19e46f3 Mon Sep 17 00:00:00 2001 From: Jakub Martisko Date: Thu, 7 Jul 2016 12:53:26 +0200 Subject: [PATCH 312/523] (un)expand: UTF8-BOM header detection --- coreutils-i18n-un-expand-BOM.patch | 443 +++++++++++++++++++++++++++++ coreutils.spec | 11 +- 2 files changed, 453 insertions(+), 1 deletion(-) create mode 100644 coreutils-i18n-un-expand-BOM.patch diff --git a/coreutils-i18n-un-expand-BOM.patch b/coreutils-i18n-un-expand-BOM.patch new file mode 100644 index 0000000..44769c6 --- /dev/null +++ b/coreutils-i18n-un-expand-BOM.patch @@ -0,0 +1,443 @@ +diff -up ./src/expand-core.c.orig ./src/expand-core.c +--- ./src/expand-core.c.orig 2016-06-28 14:44:18.281619000 +0200 ++++ ./src/expand-core.c 2016-06-30 11:46:50.025109755 +0200 +@@ -18,6 +18,7 @@ + + #include + #include ++#include + + #include "system.h" + #include "error.h" +@@ -27,6 +28,119 @@ + + #include "expand-core.h" + ++extern inline 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 inline 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. */ + +diff -up ./src/expand-core.h.orig ./src/expand-core.h +--- ./src/expand-core.h.orig 2016-06-28 14:44:18.281619000 +0200 ++++ ./src/expand-core.h 2016-06-30 11:47:18.929437205 +0200 +@@ -15,7 +15,7 @@ + along with this program. If not, see . */ + + #ifndef EXPAND_CORE_H_ +-# define EXPAND_CORE_H_ ++#define EXPAND_CORE_H_ + + extern size_t first_free_tab; + +@@ -29,6 +29,18 @@ extern char **file_list; + + extern bool have_read_stdin; + ++inline int ++set_utf_locale (void); ++ ++bool ++check_utf_locale(void); ++ ++bool ++check_bom(FILE* fp, mb_file_t *mbf); ++ ++inline void ++print_bom(void); ++ + void + parse_tab_stops (char const *stops, void (*add_tab_stop)(uintmax_t)); + +diff -up ./src/expand.c.orig ./src/expand.c +--- ./src/expand.c.orig 2016-06-28 14:44:18.286619000 +0200 ++++ ./src/expand.c 2016-06-30 11:50:15.077312947 +0200 +@@ -149,11 +149,33 @@ expand (void) + 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); ++ ++ 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")); ++ } ++ } ++ ++ ++ if (found_bom == true) ++ { ++ print_bom(); ++ } + + while (true) + { +@@ -178,6 +200,27 @@ expand (void) + 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 +diff -up ./src/unexpand.c.orig ./src/unexpand.c +--- ./src/unexpand.c.orig 2016-06-28 17:39:22.894259000 +0200 ++++ ./src/unexpand.c 2016-07-07 09:48:07.659924755 +0200 +@@ -172,16 +172,36 @@ unexpand (void) + include characters other than spaces, so the blanks must be + stored, not merely counted. */ + 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 * sizeof (mbf_char_t)); + +- mbf_init (mbf, fp); ++ if (found_bom == true) ++ { ++ print_bom(); ++ } + + while (true) + { +@@ -225,6 +245,27 @@ unexpand (void) + 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 +diff -up ./tests/expand/mb.sh.orig ./tests/expand/mb.sh +--- ./tests/expand/mb.sh.orig 2016-06-28 14:44:18.287619000 +0200 ++++ ./tests/expand/mb.sh 2016-06-30 11:57:10.038407216 +0200 +@@ -109,4 +109,75 @@ äbcdef\xFF | + 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 +diff -up ./tests/unexpand/mb.sh.orig ./tests/unexpand/mb.sh +--- ./tests/unexpand/mb.sh.orig 2016-06-28 17:39:22.895259000 +0200 ++++ ./tests/unexpand/mb.sh 2016-07-07 09:55:00.098281917 +0200 +@@ -111,3 +111,62 @@ äbcdef\xFF\t| + + 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.spec b/coreutils.spec index 4abace5..21ec798 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -50,6 +50,8 @@ Patch804: coreutils-i18n-cut-old.patch Patch803: coreutils-i18n-fix-unexpand.patch #(un)expand - allow multiple files on input - broken by patch 801 Patch805: coreutils-i18n-fix2-expand-unexpand.patch +#(un)expand - test BOM headers +Patch806: coreutils-i18n-un-expand-BOM.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch @@ -192,6 +194,7 @@ tee DIR_COLORS{,.256color,.lightbgcolor} < src/dircolors.hin %patch803 -p1 -b .i18n-fix-expand %patch804 -p1 -b .i18n-cutold %patch805 -p1 -b .i18n-fix2-expand-unexpand +%patch806 -p1 -b .i18n-BOM-expand-unexpand # Coreutils %patch908 -p1 -b .getgrouplist @@ -351,6 +354,12 @@ fi %license COPYING %changelog +* Thu Jul 07 2016 Jakub Martisko - 8.25-10 +- switch to UTF8 locale when (un)expand input contains BOM header + (#1158494) +- fixed regression where (un)expand would end with "long input line" + error when BOM header is present + * Fri Jun 24 2016 Ondrej Vasik - 8.25-10 - change way of detection of interactive shell in colorls.sh script (#1321648) From 7d9e8632f3705d65e212c081a55d1b3b32542d11 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 11 Jul 2016 17:13:20 +0200 Subject: [PATCH 313/523] coreutils.spec: fix the last change log entry --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 21ec798..b9801ec 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -354,7 +354,7 @@ fi %license COPYING %changelog -* Thu Jul 07 2016 Jakub Martisko - 8.25-10 +* Thu Jul 07 2016 Jakub Martisko - 8.25-11 - switch to UTF8 locale when (un)expand input contains BOM header (#1158494) - fixed regression where (un)expand would end with "long input line" From e207ff79a3eb3f451033f49c10f60a14c0d9d8cd Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 11 Jul 2016 17:14:09 +0200 Subject: [PATCH 314/523] Resolves: #1349579 - clarify recognition of "^COLOR.*none" in /etc/DIR_COLORS --- coreutils-8.25-DIR_COLORS.patch | 58 ++++++++++++++++++++++++--------- coreutils.spec | 5 ++- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/coreutils-8.25-DIR_COLORS.patch b/coreutils-8.25-DIR_COLORS.patch index 546241b..54a96eb 100644 --- a/coreutils-8.25-DIR_COLORS.patch +++ b/coreutils-8.25-DIR_COLORS.patch @@ -4,16 +4,16 @@ Date: Fri, 17 Jun 2016 16:58:18 +0200 Subject: [PATCH] downstream changes to default DIR_COLORS --- - DIR_COLORS | 38 ++++--- - DIR_COLORS.256color | 290 +++++++++++++++++++++++------------------------- - DIR_COLORS.lightbgcolor | 197 ++++++++++++++++---------------- - 3 files changed, 259 insertions(+), 266 deletions(-) + DIR_COLORS | 44 +++---- + DIR_COLORS.256color | 296 +++++++++++++++++++++++------------------------- + DIR_COLORS.lightbgcolor | 203 +++++++++++++++++---------------- + 3 files changed, 271 insertions(+), 272 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS index d2ea453..27af9d7 100644 --- a/DIR_COLORS +++ b/DIR_COLORS -@@ -1,6 +1,10 @@ +@@ -1,12 +1,18 @@ # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. @@ -24,7 +24,17 @@ index d2ea453..27af9d7 100644 # Copyright (C) 1996-2016 Free Software Foundation, Inc. # Copying and distribution of this file, with or without modification, # are permitted provided the copyright notice and this notice are preserved. -@@ -62,7 +66,7 @@ DOOR 01;35 # door + +-# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the +-# slackware version of dircolors) are recognized but ignored. ++# The keywords OPTIONS and EIGHTBIT (honored by the slackware version of ++# dircolors) are recognized but ignored. For compatibility reasons, the ++# pattern "^COLOR.*none" is recognized as a way to disable colorization. ++# See https://bugzilla.redhat.com/1349579 for details. + + # Below are TERM entries, which can be a glob patterns, to match + # against the TERM environment variable to determine if it is colorizable. +@@ -62,7 +68,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -33,7 +43,7 @@ index d2ea453..27af9d7 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -183,21 +187,21 @@ EXEC 01;32 +@@ -183,21 +189,21 @@ EXEC 01;32 .ogx 01;35 # audio formats @@ -75,7 +85,7 @@ diff --git a/DIR_COLORS.256color b/DIR_COLORS.256color index d2ea453..74c34ba 100644 --- a/DIR_COLORS.256color +++ b/DIR_COLORS.256color -@@ -1,5 +1,8 @@ +@@ -1,45 +1,22 @@ -# Configuration file for dircolors, a utility to help you set the -# LS_COLORS environment variable used by GNU ls with the --color option. +# Configuration file for the 256color ls utility @@ -86,7 +96,14 @@ index d2ea453..74c34ba 100644 # Copyright (C) 1996-2016 Free Software Foundation, Inc. # Copying and distribution of this file, with or without modification, -@@ -10,36 +13,8 @@ + # are permitted provided the copyright notice and this notice are preserved. + +-# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the +-# slackware version of dircolors) are recognized but ignored. ++# The keywords OPTIONS and EIGHTBIT (honored by the slackware version of ++# dircolors) are recognized but ignored. For compatibility reasons, the ++# pattern "^COLOR.*none" is recognized as a way to disable colorization. ++# See https://bugzilla.redhat.com/1349579 for details. # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. @@ -125,7 +142,7 @@ index d2ea453..74c34ba 100644 # Below are the color init strings for the basic file types. A color init # string consists of one or more of the following numeric codes: -@@ -49,29 +24,40 @@ TERM xterm* +@@ -49,29 +26,40 @@ TERM xterm* # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white # Background color codes: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white @@ -182,7 +199,7 @@ index d2ea453..74c34ba 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -89,115 +75,115 @@ EXEC 01;32 +@@ -89,115 +77,115 @@ EXEC 01;32 #.csh 01;32 # archives or compressed (bright red) @@ -406,7 +423,7 @@ diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor index d2ea453..95d6879 100644 --- a/DIR_COLORS.lightbgcolor +++ b/DIR_COLORS.lightbgcolor -@@ -1,5 +1,8 @@ +@@ -1,12 +1,17 @@ -# Configuration file for dircolors, a utility to help you set the -# LS_COLORS environment variable used by GNU ls with the --color option. +# Configuration file for the color ls utility - modified for lighter backgrounds @@ -417,7 +434,18 @@ index d2ea453..95d6879 100644 # Copyright (C) 1996-2016 Free Software Foundation, Inc. # Copying and distribution of this file, with or without modification, -@@ -52,17 +55,17 @@ TERM xterm* + # are permitted provided the copyright notice and this notice are preserved. + +-# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the +-# slackware version of dircolors) are recognized but ignored. ++# The keywords OPTIONS and EIGHTBIT (honored by the slackware version of ++# dircolors) are recognized but ignored. For compatibility reasons, the ++# pattern "^COLOR.*none" is recognized as a way to disable colorization. ++# See https://bugzilla.redhat.com/1349579 for details. + + # Below are TERM entries, which can be a glob patterns, to match + # against the TERM environment variable to determine if it is colorizable. +@@ -52,17 +57,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -440,7 +468,7 @@ index d2ea453..95d6879 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -71,7 +74,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +@@ -71,7 +76,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: @@ -449,7 +477,7 @@ index d2ea453..95d6879 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -88,99 +91,99 @@ EXEC 01;32 +@@ -88,99 +93,99 @@ EXEC 01;32 #.sh 01;32 #.csh 01;32 diff --git a/coreutils.spec b/coreutils.spec index b9801ec..e4b0f45 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -354,6 +354,9 @@ fi %license COPYING %changelog +* Mon Jul 11 2016 Kamil Dudka - 8.25-12 +- clarify recognition of "^COLOR.*none" in /etc/DIR_COLORS (#1349579) + * Thu Jul 07 2016 Jakub Martisko - 8.25-11 - switch to UTF8 locale when (un)expand input contains BOM header (#1158494) From 3792f36ae5f2fc5bf735a7080611a71818564eb1 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 11 Jul 2016 17:16:31 +0200 Subject: [PATCH 315/523] Resolves: #1354078 - drop the %pre scriptlet ... which is no longer needed. Fileutils, Shellutils, and Textutils were merged into GNU Coreutils in 2002. It should be safe not to handle the transition now in 2016. --- coreutils.spec | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index e4b0f45..60e8194 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -307,16 +307,6 @@ grep LC_TIME %name.lang | cut -d'/' -f1-6 | sed -e 's/) /) %%dir /g' >>%name.lan # (sb) Deal with Installed (but unpackaged) file(s) found rm -f $RPM_BUILD_ROOT%{_infodir}/dir -%pre common -# We must deinstall these info files since they're merged in -# coreutils.info. else their postun'll be run too late -# and install-info will fail badly because of duplicates -for file in sh-utils textutils fileutils; do - if [ -f %{_infodir}/$file.info.gz ]; then - /sbin/install-info --delete %{_infodir}/$file.info.gz --dir=%{_infodir}/dir &> /dev/null || : - fi -done - %preun common if [ $1 = 0 ]; then if [ -f %{_infodir}/%{name}.info.gz ]; then @@ -355,6 +345,7 @@ fi %changelog * Mon Jul 11 2016 Kamil Dudka - 8.25-12 +- drop the %%pre scriptlet, which is no longer needed (#1354078) - clarify recognition of "^COLOR.*none" in /etc/DIR_COLORS (#1349579) * Thu Jul 07 2016 Jakub Martisko - 8.25-11 From 3bf1e52ff3dc979af46ac966c05927b1611231e7 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 11 Jul 2016 17:27:02 +0200 Subject: [PATCH 316/523] Resolves: #1339135 - install -Z now sets default SELinux context for created directories --- coreutils-8.25-intall-Z-selinux.patch | 188 ++++++++++++++++++++++++++ coreutils.spec | 9 +- 2 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.25-intall-Z-selinux.patch diff --git a/coreutils-8.25-intall-Z-selinux.patch b/coreutils-8.25-intall-Z-selinux.patch new file mode 100644 index 0000000..0f5ef33 --- /dev/null +++ b/coreutils-8.25-intall-Z-selinux.patch @@ -0,0 +1,188 @@ +From c424bbcb532c5b9924349e3522b3b431eaa7c178 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 8 Jul 2016 18:59:35 +0200 +Subject: [PATCH] install: with -Z, set default SELinux context for created + directories + +* doc/coreutils.texi (install invocation): Update -Z documentation. +* src/install.c (make_ancestor): Set default security context before +calling mkdir() if the -Z option is given. +(process_dir): Call restorecon() on the destination directory if the +-Z option is given. +(usage): Update -Z documentation. +* tests/install/install-Z-selinux.sh: A new test for 'install -Z -D' +and 'install -Z -d' based on tests/mkdir/restorecon.sh. +* tests/local.mk: Reference the test. +* NEWS: Mention the improvement. +Reported at https://bugzilla.redhat.com/1339135 +Fixes http://bugs.gnu.org/23868 + +Upstream-commit: 502518b44039138d148e2e15157d125c82d02af0 +Signed-off-by: Kamil Dudka +--- + doc/coreutils.texi | 2 +- + src/install.c | 33 ++++++++++++++++++---- + tests/install/install-Z-selinux.sh | 58 ++++++++++++++++++++++++++++++++++++++ + tests/local.mk | 1 + + 4 files changed, 88 insertions(+), 6 deletions(-) + create mode 100644 tests/install/install-Z-selinux.sh + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 092192c..1543f27 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -9208,7 +9208,7 @@ Print the name of each file before moving it. + @cindex security context + This option functions similarly to the @command{restorecon} command, + by adjusting the SELinux security context according +-to the system default type for destination files. ++to the system default type for destination files and each created directory. + + @end table + +diff --git a/src/install.c b/src/install.c +index 089f298..1b7a209 100644 +--- a/src/install.c ++++ b/src/install.c +@@ -39,6 +39,7 @@ + #include "prog-fprintf.h" + #include "quote.h" + #include "savewd.h" ++#include "selinux.h" + #include "stat-time.h" + #include "utimens.h" + #include "xstrtol.h" +@@ -423,6 +424,12 @@ announce_mkdir (char const *dir, void *options) + static int + make_ancestor (char const *dir, char const *component, void *options) + { ++ struct cp_options const *x = options; ++ if (x->set_security_context && defaultcon (dir, S_IFDIR) < 0 ++ && ! ignorable_ctx_err (errno)) ++ error (0, errno, _("failed to set default creation context for %s"), ++ quoteaf (dir)); ++ + int r = mkdir (component, DEFAULT_MODE); + if (r == 0) + announce_mkdir (dir, options); +@@ -433,12 +440,28 @@ make_ancestor (char const *dir, char const *component, void *options) + static int + process_dir (char *dir, struct savewd *wd, void *options) + { +- return (make_dir_parents (dir, wd, +- make_ancestor, options, +- dir_mode, announce_mkdir, +- dir_mode_bits, owner_id, group_id, false) ++ struct cp_options const *x = options; ++ ++ int ret = (make_dir_parents (dir, wd, make_ancestor, options, ++ dir_mode, announce_mkdir, ++ dir_mode_bits, owner_id, group_id, false) + ? EXIT_SUCCESS + : EXIT_FAILURE); ++ ++ /* FIXME: Due to the current structure of make_dir_parents() ++ we don't have the facility to call defaultcon() before the ++ final component of DIR is created. So for now, create the ++ final component with the context from previous component ++ and here we set the context for the final component. */ ++ if (ret == EXIT_SUCCESS && x->set_security_context) ++ { ++ if (! restorecon (last_component (dir), false, false) ++ && ! ignorable_ctx_err (errno)) ++ error (0, errno, _("failed to restore context for %s"), ++ quoteaf (dir)); ++ } ++ ++ return ret; + } + + /* Copy file FROM onto file TO, creating TO if necessary. +@@ -651,7 +674,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ + fputs (_("\ + -P, --preserve-context preserve SELinux security context (-P deprecated)\n\ + -Z set SELinux security context of destination\n\ +- file to default type\n\ ++ file and each created directory to default type\n\ + --context[=CTX] like -Z, or if CTX is specified then set the\n\ + SELinux or SMACK security context to CTX\n\ + "), stdout); +diff --git a/tests/install/install-Z-selinux.sh b/tests/install/install-Z-selinux.sh +new file mode 100644 +index 0000000..9c3b642 +--- /dev/null ++++ b/tests/install/install-Z-selinux.sh +@@ -0,0 +1,58 @@ ++#!/bin/sh ++# test 'install -Z -D' and 'install -Z -d' ++# based on tests/mkdir/restorecon.sh ++ ++# Copyright (C) 2013-2016 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_ ginstall ++require_selinux_ ++ ++ ++get_selinux_type() { ls -Zd "$1" | sed -n 's/.*:\(.*_t\):.*/\1/p'; } ++ ++mkdir subdir || framework_failure_ ++chcon 'root:object_r:tmp_t:s0' subdir || framework_failure_ ++cd subdir ++ ++# Since in a tmp_t dir, dirs can be created as user_tmp_t ... ++touch standard || framework_failure_ ++mkdir restored || framework_failure_ ++if restorecon restored 2>/dev/null; then ++ # ... but when restored can be set to user_home_t ++ # So ensure the type for these mkdir -Z cases matches ++ # the directory type as set by restorecon. ++ ginstall -Z standard single || fail=1 ++ ginstall -Z -d single_d || fail=1 ++ # Run these as separate processes in case global context ++ # set for an arg, impacts on another arg ++ # TODO: Have the defaultcon() vary over these directories ++ for dst in single_d/existing/file multi/ple/file; do ++ ginstall -Z -D standard "$dst" || fail=1 ++ done ++ restored_type=$(get_selinux_type 'restored') ++ test "$(get_selinux_type 'single')" = "$restored_type" || fail=1 ++ test "$(get_selinux_type 'single_d')" = "$restored_type" || fail=1 ++ test "$(get_selinux_type 'single_d/existing')" = "$restored_type" || fail=1 ++ test "$(get_selinux_type 'multi')" = "$restored_type" || fail=1 ++ test "$(get_selinux_type 'multi/ple')" = "$restored_type" || fail=1 ++fi ++if test "$fail" = '1'; then ++ ls -UZd standard restored ++ ls -UZd single single_d single_d/existing multi multi/ple ++fi ++ ++Exit $fail +diff --git a/tests/local.mk b/tests/local.mk +index ec23448..42d39f2 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -548,6 +548,7 @@ all_tests = \ + tests/install/d-slashdot.sh \ + tests/install/install-C.sh \ + tests/install/install-C-selinux.sh \ ++ tests/install/install-Z-selinux.sh \ + tests/install/strip-program.sh \ + tests/install/trap.sh \ + tests/ln/backup-1.sh \ +-- +2.5.5 + diff --git a/coreutils.spec b/coreutils.spec index 60e8194..9b1566b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -18,6 +18,7 @@ Source10: coreutils-find-requires.sh %global __find_requires %{SOURCE10} %{_rpmconfigdir}/find-requires # From upstream +Patch952: coreutils-8.25-intall-Z-selinux.patch # Our patches #general patch to workaround koji build system issues @@ -204,8 +205,13 @@ tee DIR_COLORS{,.256color,.lightbgcolor} < src/dircolors.hin #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman +%patch952 -p1 -chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh || : +chmod a+x \ + tests/df/direct.sh \ + tests/install/install-Z-selinux.sh \ + tests/misc/sort-mb-tests.sh \ + || : #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -345,6 +351,7 @@ fi %changelog * Mon Jul 11 2016 Kamil Dudka - 8.25-12 +- install -Z now sets default SELinux context for created directories (#1339135) - drop the %%pre scriptlet, which is no longer needed (#1354078) - clarify recognition of "^COLOR.*none" in /etc/DIR_COLORS (#1349579) From fe09c9cd04372ee98e07a87ff9a1a7cef8d06b41 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 11 Jul 2016 17:36:22 +0200 Subject: [PATCH 317/523] Related: #1354078 - drop %pre dependency on install-info --- coreutils.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 9b1566b..f5088d6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -162,7 +162,6 @@ packaged as a single multicall binary. # yum obsoleting rules explained at: # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 -Requires(pre): /sbin/install-info Requires(preun): /sbin/install-info Requires(post): /sbin/install-info Summary: coreutils common optional components From 9551d101b0367301507aa1f117e215831cf8e317 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 11 Jul 2016 22:00:42 +0200 Subject: [PATCH 318/523] Related: #1335320 - do not print DIR_COLOR to stdout --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index f5088d6..e48bca6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -173,7 +173,7 @@ including documentation and translations. %setup -q # will be modified by coreutils-8.25-DIR_COLORS.patch -tee DIR_COLORS{,.256color,.lightbgcolor} < src/dircolors.hin +tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null # Our patches %patch100 -p1 -b .configure From d3849ced08d9cfcfa2c4d0eed72bcb305222ebd8 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 14 Jul 2016 16:29:59 +0200 Subject: [PATCH 319/523] fix patches such that they apply without offset --- coreutils-4.5.3-langinfo.patch | 2 +- coreutils-6.10-configuration.patch | 22 +-- coreutils-6.10-manpages.patch | 2 +- coreutils-8.2-uname-processortype.patch | 7 +- coreutils-8.4-mkdir-modenote.patch | 2 +- coreutils-df-direct.patch | 14 +- coreutils-getgrouplist.patch | 8 +- coreutils-i18n-cut-old.patch | 2 +- coreutils-i18n-cut.patch | 42 +++--- coreutils-i18n-expand-unexpand.patch | 102 ++++++++------ coreutils-i18n.patch | 176 ++++++++++++------------ coreutils-overflow.patch | 2 +- coreutils-selinux.patch | 16 +-- coreutils-selinuxmanpages.patch | 2 +- sh-utils-2.0.11-dateman.patch | 2 +- 15 files changed, 207 insertions(+), 194 deletions(-) diff --git a/coreutils-4.5.3-langinfo.patch b/coreutils-4.5.3-langinfo.patch index 25dec6c..48e0624 100644 --- a/coreutils-4.5.3-langinfo.patch +++ b/coreutils-4.5.3-langinfo.patch @@ -1,6 +1,6 @@ --- coreutils-5.92/src/date.c.langinfo 2005-09-16 09:06:57.000000000 +0100 +++ coreutils-5.92/src/date.c 2005-10-24 18:09:16.000000000 +0100 -@@ -451,14 +451,7 @@ +@@ -474,14 +474,7 @@ main (int argc, char **argv) format = DATE_FMT_LANGINFO (); if (! *format) { diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 4c68077..7468ba2 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,7 +1,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-tests/gnulib.mk --- coreutils-8.21-orig/gnulib-tests/gnulib.mk 2013-02-07 17:58:44.000000000 +0100 +++ coreutils-8.21/gnulib-tests/gnulib.mk 2013-02-15 10:12:28.110593165 +0100 -@@ -267,9 +267,9 @@ EXTRA_DIST += nap.h test-chown.h test-ch +@@ -279,9 +279,9 @@ EXTRA_DIST += nap.h test-chown.h test-chown.c signature.h macros.h ## begin gnulib module cloexec-tests @@ -14,7 +14,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module cloexec-tests -@@ -378,9 +378,9 @@ EXTRA_DIST += test-dup.c signature.h mac +@@ -392,9 +392,9 @@ EXTRA_DIST += test-dup.c signature.h macros.h ## begin gnulib module dup2-tests @@ -27,7 +27,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module dup2-tests -@@ -439,10 +439,10 @@ EXTRA_DIST += test-fadvise.c +@@ -453,10 +453,10 @@ EXTRA_DIST += test-fadvise.c ## begin gnulib module fchdir-tests @@ -42,7 +42,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module fchdir-tests -@@ -874,9 +874,9 @@ EXTRA_DIST += test-getloadavg.c signatur +@@ -900,9 +900,9 @@ EXTRA_DIST += test-getloadavg.c signature.h ## begin gnulib module getlogin-tests @@ -55,7 +55,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module getlogin-tests -@@ -1119,10 +1119,10 @@ EXTRA_DIST += test-link.h test-link.c si +@@ -1147,10 +1147,10 @@ EXTRA_DIST += test-link.h test-link.c signature.h macros.h ## begin gnulib module linkat-tests @@ -70,7 +70,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module linkat-tests -@@ -1331,9 +1331,9 @@ EXTRA_DIST += test-memcoll.c macros.h +@@ -1359,9 +1359,9 @@ EXTRA_DIST += test-memcoll.c macros.h ## begin gnulib module memrchr-tests @@ -83,7 +83,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module memrchr-tests -@@ -1978,9 +1978,9 @@ EXTRA_DIST += test-statat.c +@@ -1912,9 +1912,9 @@ EXTRA_DIST += test-statat.c ## begin gnulib module stdalign-tests @@ -96,7 +96,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module stdalign-tests -@@ -2323,9 +2323,9 @@ EXTRA_DIST += test-uname.c signature.h m +@@ -2269,9 +2269,9 @@ EXTRA_DIST += test-uname.c signature.h macros.h ## begin gnulib module unistd-safer-tests @@ -109,7 +109,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module unistd-safer-tests -@@ -2438,10 +2438,10 @@ EXTRA_DIST += test-usleep.c signature.h +@@ -2367,10 +2367,10 @@ EXTRA_DIST += test-userspec.c ## begin gnulib module utimens-tests @@ -127,7 +127,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk --- coreutils-8.21-orig/tests/local.mk 2013-02-11 11:30:12.000000000 +0100 +++ coreutils-8.21/tests/local.mk 2013-02-15 10:10:55.890532258 +0100 -@@ -131,6 +131,7 @@ all_root_tests = \ +@@ -134,6 +134,7 @@ all_root_tests = \ tests/rm/no-give-up.sh \ tests/rm/one-file-system.sh \ tests/rm/read-only.sh \ @@ -135,7 +135,7 @@ diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk tests/tail-2/append-only.sh \ tests/touch/now-owned-by-other.sh -@@ -163,7 +164,6 @@ all_tests = \ +@@ -168,7 +169,6 @@ all_tests = \ tests/cp/link-heap.sh \ tests/cp/no-ctx.sh \ tests/misc/tty-eof.pl \ diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index 8d5bc94..c795ca5 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -1,7 +1,7 @@ diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c --- coreutils-6.12-orig/src/md5sum.c 2008-05-26 08:40:33.000000000 +0200 +++ coreutils-6.12/src/md5sum.c 2008-10-21 16:07:28.000000000 +0200 -@@ -175,6 +175,9 @@ With no FILE, or when FILE is -, read st +@@ -200,6 +200,9 @@ Print or check %s (%d-bit) checksums.\n\ fputs (_("\ -t, --text read in text mode (default)\n\ "), stdout); diff --git a/coreutils-8.2-uname-processortype.patch b/coreutils-8.2-uname-processortype.patch index 4c83df8..0cb2422 100644 --- a/coreutils-8.2-uname-processortype.patch +++ b/coreutils-8.2-uname-processortype.patch @@ -1,7 +1,7 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c --- coreutils-8.2-orig/src/uname.c 2009-09-23 10:25:44.000000000 +0200 +++ coreutils-8.2/src/uname.c 2009-12-19 09:09:11.663607110 +0100 -@@ -301,7 +301,7 @@ main (int argc, char **argv) +@@ -299,13 +299,19 @@ main (int argc, char **argv) if (toprint & PRINT_PROCESSOR) { @@ -10,7 +10,6 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c #if HAVE_SYSINFO && defined SI_ARCHITECTURE { static char processor[257]; -@@ -308,6 +308,12 @@ main (int argc, char **argv) if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) element = processor; } @@ -23,7 +22,7 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c #endif #ifdef UNAME_PROCESSOR if (element == unknown) -@@ -351,7 +357,7 @@ main (int argc, char **argv) +@@ -343,7 +349,7 @@ main (int argc, char **argv) if (toprint & PRINT_HARDWARE_PLATFORM) { @@ -32,7 +31,7 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c #if HAVE_SYSINFO && defined SI_PLATFORM { static char hardware_platform[257]; -@@ -353,6 +359,14 @@ main (int argc, char **argv) +@@ -351,6 +357,14 @@ main (int argc, char **argv) hardware_platform, sizeof hardware_platform)) element = hardware_platform; } diff --git a/coreutils-8.4-mkdir-modenote.patch b/coreutils-8.4-mkdir-modenote.patch index 3576ec6..1f03c8d 100644 --- a/coreutils-8.4-mkdir-modenote.patch +++ b/coreutils-8.4-mkdir-modenote.patch @@ -1,7 +1,7 @@ diff -urNp coreutils-8.4-orig/doc/coreutils.texi coreutils-8.4/doc/coreutils.texi --- coreutils-8.4-orig/doc/coreutils.texi 2011-01-07 15:01:18.575654333 +0100 +++ coreutils-8.4/doc/coreutils.texi 2011-01-07 15:05:38.791655243 +0100 -@@ -9058,6 +9058,8 @@ incorrect. @xref{Directory Setuid and S +@@ -9993,6 +9993,8 @@ incorrect. @xref{Directory Setuid and Setgid}, for how the set-user-ID and set-group-ID bits of directories are inherited unless overridden in this way. diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 361b813..e69cd2b 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,7 +1,7 @@ diff -urNp coreutils-8.21-orig/doc/coreutils.texi coreutils-8.21/doc/coreutils.texi --- coreutils-8.21-orig/doc/coreutils.texi 2013-02-11 10:37:28.000000000 +0100 +++ coreutils-8.21/doc/coreutils.texi 2013-02-15 10:15:26.497593689 +0100 -@@ -10961,6 +10961,13 @@ +@@ -11221,6 +11221,13 @@ some systems (notably SunOS), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -28,7 +28,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -238,13 +241,15 @@ enum +@@ -243,13 +246,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -45,7 +45,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, -@@ -500,7 +505,10 @@ get_header (void) +@@ -505,7 +510,10 @@ get_header (void) for (col = 0; col < ncolumns; col++) { char *cell = NULL; @@ -57,7 +57,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1150,6 +1158,19 @@ get_point (const char *point, const stru +@@ -1352,6 +1360,19 @@ get_point (const char *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -77,7 +77,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_disk (name)) return; -@@ -1219,6 +1238,7 @@ or all file systems by default.\n\ +@@ -1422,6 +1443,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -85,7 +85,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1305,6 +1325,9 @@ main (int argc, char **argv) +@@ -1512,6 +1534,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -95,7 +95,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1408,6 +1431,13 @@ main (int argc, char **argv) +@@ -1608,6 +1633,13 @@ main (int argc, char **argv) } } diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch index 86bbcef..7defd19 100644 --- a/coreutils-getgrouplist.patch +++ b/coreutils-getgrouplist.patch @@ -12,7 +12,7 @@ index 299bae6..8ece29b 100644 #include "getugroups.h" #include -@@ -123,3 +126,4 @@ getugroups (int maxcount, gid_t *grouplist, char const *username, +@@ -126,3 +129,4 @@ getugroups (int maxcount, gid_t *grouplist, char const *username, } #endif /* HAVE_GRP_H */ @@ -21,7 +21,7 @@ diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c index 76474c2..0a9d221 100644 --- a/lib/mgetgroups.c +++ b/lib/mgetgroups.c -@@ -115,9 +115,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) +@@ -121,9 +121,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) /* else no username, so fall through and use getgroups. */ #endif @@ -42,7 +42,7 @@ index 76474c2..0a9d221 100644 /* If we failed to count groups because there is no supplemental group support, then return an array containing just GID. -@@ -139,10 +147,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) +@@ -145,10 +153,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) if (g == NULL) return -1; @@ -76,7 +76,7 @@ diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 index 62777c7..5180243 100644 --- a/m4/jm-macros.m4 +++ b/m4/jm-macros.m4 -@@ -78,6 +78,7 @@ +@@ -82,6 +82,7 @@ AC_DEFUN([coreutils_MACROS], fchown fchmod ftruncate diff --git a/coreutils-i18n-cut-old.patch b/coreutils-i18n-cut-old.patch index 29c69fc..008cecb 100644 --- a/coreutils-i18n-cut-old.patch +++ b/coreutils-i18n-cut-old.patch @@ -132,7 +132,7 @@ diff -urNp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c /* The delimiter for each line/record. */ static unsigned char line_delim = '\n'; -@@ -164,7 +243,7 @@ Print selected parts of lines from each +@@ -164,7 +243,7 @@ Print selected parts of lines from each FILE to standard output.\n\ -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\ diff --git a/coreutils-i18n-cut.patch b/coreutils-i18n-cut.patch index ec85cf0..f680df6 100644 --- a/coreutils-i18n-cut.patch +++ b/coreutils-i18n-cut.patch @@ -12,7 +12,7 @@ #include "system.h" #include "error.h" -@@ -90,25 +95,16 @@ add_range_pair (size_t lo, size_t hi) +@@ -61,25 +66,16 @@ CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ static struct field_range_pair *current_rp; @@ -42,7 +42,7 @@ /* Output the given delimiter-separated fields. */ field_mode }; -@@ -120,12 +116,16 @@ static enum operating_mode operating_mod +@@ -91,12 +87,16 @@ static enum operating_mode operating_mode; with field mode. */ static bool suppress_non_delimited; @@ -60,7 +60,7 @@ /* The delimiter for each line/record. */ static unsigned char line_delim = '\n'; -@@ -135,7 +135,7 @@ static size_t output_delimiter_length; +@@ -109,7 +109,7 @@ static size_t output_delimiter_length; /* The output field separator string. Defaults to the 1-character string consisting of the input delimiter. */ @@ -69,7 +69,7 @@ /* True if we have ever read standard input. */ static bool have_read_stdin; -@@ -189,7 +189,7 @@ Print selected parts of lines from each +@@ -164,7 +164,7 @@ Print selected parts of lines from each FILE to standard output.\n\ -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\ @@ -78,7 +78,7 @@ "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -435,6 +435,12 @@ next_item (size_t *item_idx) +@@ -211,6 +211,12 @@ next_item (size_t *item_idx) current_rp++; } @@ -91,7 +91,7 @@ /* Return nonzero if the K'th field or byte is printable. */ static inline bool -@@ -443,6 +449,15 @@ print_kth (size_t k) +@@ -219,6 +225,15 @@ print_kth (size_t k) return current_rp->lo <= k; } @@ -107,7 +107,7 @@ /* Return nonzero if K'th byte is the beginning of a range. */ static inline bool -@@ -505,23 +520,215 @@ cut_bytes (FILE *stream) +@@ -281,23 +296,215 @@ cut_bytes (FILE *stream) } /* Read from stream STREAM, printing to standard output any selected fields. */ @@ -328,7 +328,7 @@ /* To support the semantics of the -s flag, we may have to buffer all of the first field to determine whether it is 'delimited.' -@@ -536,10 +744,14 @@ cut_fields (FILE *stream) +@@ -312,10 +519,14 @@ cut_fields (FILE *stream) if (field_idx == 1 && buffer_first_field) { ssize_t len; @@ -346,7 +346,7 @@ if (len < 0) { free (field_1_buffer); -@@ -549,15 +761,15 @@ cut_fields (FILE *stream) +@@ -325,15 +536,15 @@ cut_fields (FILE *stream) xalloc_die (); } @@ -366,7 +366,7 @@ { if (suppress_non_delimited) { -@@ -565,26 +777,30 @@ cut_fields (FILE *stream) +@@ -341,26 +552,30 @@ cut_fields (FILE *stream) } else { @@ -405,7 +405,7 @@ found_any_selected_field = true; } } -@@ -594,7 +810,8 @@ cut_fields (FILE *stream) +@@ -370,7 +585,8 @@ cut_fields (FILE *stream) next_item (&field_idx); } @@ -415,7 +415,7 @@ if (print_kth (field_idx)) { -@@ -605,42 +822,46 @@ cut_fields (FILE *stream) +@@ -381,42 +597,46 @@ cut_fields (FILE *stream) } found_any_selected_field = true; @@ -477,7 +477,7 @@ break; field_idx = 1; current_rp = frp; -@@ -652,7 +874,14 @@ static void +@@ -429,7 +649,14 @@ static void cut_stream (FILE *stream) { if (operating_mode == byte_mode) @@ -493,7 +493,7 @@ else cut_fields (stream); } -@@ -706,6 +935,7 @@ main (int argc, char **argv) +@@ -483,6 +710,7 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -501,7 +501,7 @@ initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -719,8 +949,10 @@ main (int argc, char **argv) +@@ -496,8 +724,10 @@ main (int argc, char **argv) /* By default, all non-delimited lines are printed. */ suppress_non_delimited = false; @@ -513,7 +513,7 @@ have_read_stdin = false; while ((optc = getopt_long (argc, argv, "b:c:d:f:nsz", longopts, NULL)) != -1) -@@ -728,7 +960,6 @@ main (int argc, char **argv) +@@ -505,7 +735,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -521,7 +521,7 @@ /* Build the byte list. */ if (operating_mode != undefined_mode) FATAL_ERROR (_("only one type of list may be specified")); -@@ -736,6 +967,14 @@ main (int argc, char **argv) +@@ -513,6 +742,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -536,7 +536,7 @@ case 'f': /* Build the field list. */ if (operating_mode != undefined_mode) -@@ -747,9 +986,17 @@ main (int argc, char **argv) +@@ -524,9 +761,17 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -551,12 +551,12 @@ + mbi_advance (iter); + if (mbi_avail (iter)) FATAL_ERROR (_("the delimiter must be a single character")); -+ } - delim = optarg[0]; ++ } delim_specified = true; break; -@@ -763,6 +1008,7 @@ main (int argc, char **argv) +@@ -540,6 +785,7 @@ main (int argc, char **argv) break; case 'n': @@ -564,7 +564,7 @@ break; case 's': -@@ -802,15 +1048,12 @@ main (int argc, char **argv) +@@ -579,15 +825,12 @@ main (int argc, char **argv) | (complement ? SETFLD_COMPLEMENT : 0) ); if (!delim_specified) diff --git a/coreutils-i18n-expand-unexpand.patch b/coreutils-i18n-expand-unexpand.patch index d8a5968..d23e0f0 100644 --- a/coreutils-i18n-expand-unexpand.patch +++ b/coreutils-i18n-expand-unexpand.patch @@ -23,19 +23,24 @@ properly. Co-authored-by: Pádraig Brady --- - NEWS | 3 + bootstrap.conf | 1 + configure.ac | 2 + + lib/mbfile.c | 3 + + lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++ + m4/mbfile.m4 | 14 +++ po/POTFILES.in | 1 + - src/expand-core.c | 150 +++++++++++++++++++++++++++++++++++++++ - src/expand-core.h | 44 ++++++++++++ - src/expand.c | 183 ++++++++++------------------------------------- + src/expand-core.c | 150 ++++++++++++++++++++++++++++++ + src/expand-core.h | 41 +++++++++ + src/expand.c | 186 ++++++++----------------------------- src/local.mk | 2 + - src/unexpand.c | 197 ++++++++++++--------------------------------------- - tests/expand/mb.sh | 98 +++++++++++++++++++++++++ + src/unexpand.c | 195 ++++++++++----------------------------- + tests/expand/mb.sh | 98 ++++++++++++++++++++ tests/local.mk | 2 + - tests/unexpand/mb.sh | 97 +++++++++++++++++++++++++ - 12 files changed, 482 insertions(+), 298 deletions(-) + tests/unexpand/mb.sh | 97 ++++++++++++++++++++ + 14 files changed, 750 insertions(+), 297 deletions(-) + create mode 100644 lib/mbfile.c + create mode 100644 lib/mbfile.h + create mode 100644 m4/mbfile.m4 create mode 100644 src/expand-core.c create mode 100644 src/expand-core.h create mode 100755 tests/expand/mb.sh @@ -45,7 +50,7 @@ diff --git a/bootstrap.conf b/bootstrap.conf index ef1c078..ea8cebc 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -152,6 +152,7 @@ gnulib_modules=" +@@ -151,6 +151,7 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -57,7 +62,7 @@ diff --git a/configure.ac b/configure.ac index 8dc2192..b8b5114 100644 --- a/configure.ac +++ b/configure.ac -@@ -422,6 +422,8 @@ gl_WINSIZE_IN_PTEM +@@ -425,6 +425,8 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -338,12 +343,10 @@ index 0a40a1a..ed97fd4 100644 static char const shortopts[] = "it:0::1::2::3::4::5::6::7::8::9::"; -@@ -125,128 +129,6 @@ - if (first_free_tab == n_tabs_allocated) - tab_list = X2NREALLOC (tab_list, &n_tabs_allocated); +@@ -135,128 +139,6 @@ add_tab_stop (uintmax_t tabval) tab_list[first_free_tab++] = tabval; --} -- + } + -/* Add the comma or blank separated list of tab stops STOPS - to the list of tab stops. */ - @@ -464,10 +467,12 @@ index 0a40a1a..ed97fd4 100644 - exit_status = EXIT_FAILURE; - } - return NULL; - } - +-} +- /* Change tabs to spaces, writing to stdout. -@@ -265,19 +146,19 @@ expand (void) + Read each file in 'file_list', in order. */ + +@@ -265,19 +147,19 @@ expand (void) { /* Input stream. */ FILE *fp = next_file (NULL); @@ -491,7 +496,7 @@ index 0a40a1a..ed97fd4 100644 /* The following variables have valid values only when CONVERT is true: */ -@@ -287,17 +168,23 @@ expand (void) +@@ -287,17 +169,23 @@ expand (void) /* Index in TAB_LIST of next tab stop to examine. */ size_t tab_index = 0; @@ -519,7 +524,7 @@ index 0a40a1a..ed97fd4 100644 { /* Column the next input tab stop is on. */ uintmax_t next_tab_column; -@@ -328,32 +215,34 @@ expand (void) +@@ -328,32 +216,34 @@ expand (void) if (putchar (' ') < 0) error (EXIT_FAILURE, errno, _("write error")); @@ -562,7 +567,7 @@ index 0a40a1a..ed97fd4 100644 } } -@@ -385,19 +274,19 @@ main (int argc, char **argv) +@@ -385,19 +275,19 @@ main (int argc, char **argv) break; case 't': @@ -589,7 +594,7 @@ diff --git a/src/local.mk b/src/local.mk index 536b7cc..bfede88 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -362,6 +362,8 @@ src_coreutils_SOURCES = src/coreutils.c +@@ -361,6 +361,8 @@ src_coreutils_SOURCES = src/coreutils.c src_cp_SOURCES = src/cp.c $(copy_sources) $(selinux_sources) src_dir_SOURCES = src/ls.c src/ls-dir.c @@ -655,7 +660,7 @@ index e0f7c22..48fbb32 100644 /* For long options that have no equivalent short option, use a non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -@@ -154,128 +156,6 @@ add_tab_stop (uintmax_t tabval) +@@ -154,128 +158,6 @@ add_tab_stop (uintmax_t tabval) } } @@ -784,7 +789,7 @@ index e0f7c22..48fbb32 100644 /* Change blanks to tabs, writing to stdout. Read each file in 'file_list', in order. */ -@@ -284,11 +164,12 @@ unexpand (void) +@@ -284,11 +166,12 @@ unexpand (void) { /* Input stream. */ FILE *fp = next_file (NULL); @@ -798,7 +803,7 @@ index e0f7c22..48fbb32 100644 if (!fp) return; -@@ -296,12 +177,14 @@ unexpand (void) +@@ -296,12 +179,14 @@ unexpand (void) /* 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. */ @@ -815,7 +820,7 @@ index e0f7c22..48fbb32 100644 /* If true, perform translations. */ bool convert = true; -@@ -335,12 +218,19 @@ unexpand (void) +@@ -335,12 +220,19 @@ unexpand (void) do { @@ -838,7 +843,7 @@ index e0f7c22..48fbb32 100644 if (blank) { -@@ -372,16 +262,16 @@ unexpand (void) +@@ -372,16 +264,16 @@ unexpand (void) if (next_tab_column < column) error (EXIT_FAILURE, 0, _("input line is too long")); @@ -858,7 +863,7 @@ index e0f7c22..48fbb32 100644 if (! (prev_blank && column == next_tab_column)) { -@@ -389,13 +279,14 @@ unexpand (void) +@@ -389,13 +281,14 @@ unexpand (void) will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -875,7 +880,7 @@ index e0f7c22..48fbb32 100644 } /* Discard pending blanks, unless it was a single -@@ -403,7 +294,7 @@ unexpand (void) +@@ -403,7 +296,7 @@ unexpand (void) pending = one_blank_before_tab_stop; } } @@ -884,7 +889,7 @@ index e0f7c22..48fbb32 100644 { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -413,7 +304,7 @@ unexpand (void) +@@ -413,7 +306,7 @@ unexpand (void) } else { @@ -893,7 +898,7 @@ index e0f7c22..48fbb32 100644 if (!column) error (EXIT_FAILURE, 0, _("input line is too long")); } -@@ -421,9 +312,13 @@ unexpand (void) +@@ -421,9 +314,13 @@ unexpand (void) if (pending) { if (pending > 1 && one_blank_before_tab_stop) @@ -909,7 +914,7 @@ index e0f7c22..48fbb32 100644 pending = 0; one_blank_before_tab_stop = false; } -@@ -432,16 +327,16 @@ unexpand (void) +@@ -432,16 +329,16 @@ unexpand (void) convert &= convert_entire_line || blank; } @@ -930,7 +935,7 @@ index e0f7c22..48fbb32 100644 } } -@@ -482,7 +377,7 @@ main (int argc, char **argv) +@@ -482,7 +379,7 @@ main (int argc, char **argv) break; case 't': convert_entire_line = true; @@ -1047,7 +1052,7 @@ diff --git a/tests/local.mk b/tests/local.mk index 7df04da..d3462be 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -532,6 +532,7 @@ all_tests = \ +@@ -536,6 +536,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -1055,7 +1060,7 @@ index 7df04da..d3462be 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -671,6 +672,7 @@ all_tests = \ +@@ -674,6 +675,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -1166,11 +1171,11 @@ index 0000000..60d4c1a + +unexpand -a < in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 --- -2.4.3 - ---- /dev/null 2015-11-30 08:40:17.566742513 +0100 -+++ coreutils-8.24/m4/mbfile.m4 2015-12-01 09:30:55.951149907 +0100 +diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 +new file mode 100644 +index 0000000..8589902 +--- /dev/null ++++ b/m4/mbfile.m4 @@ -0,0 +1,14 @@ +# mbfile.m4 serial 7 +dnl Copyright (C) 2005, 2008-2015 Free Software Foundation, Inc. @@ -1186,14 +1191,20 @@ index 0000000..60d4c1a + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + : +]) ---- /dev/null 2015-11-30 08:40:17.566742513 +0100 -+++ coreutils-8.24/lib/mbfile.c 2015-12-01 09:28:22.254928468 +0100 +diff --git a/lib/mbfile.c b/lib/mbfile.c +new file mode 100644 +index 0000000..b0a468e +--- /dev/null ++++ b/lib/mbfile.c @@ -0,0 +1,3 @@ +#include +#define MBFILE_INLINE _GL_EXTERN_INLINE +#include "mbfile.h" ---- /dev/null 2015-11-30 08:40:17.566742513 +0100 -+++ coreutils-8.24/lib/mbfile.h 2015-12-01 09:28:30.829885570 +0100 +diff --git a/lib/mbfile.h b/lib/mbfile.h +new file mode 100644 +index 0000000..11f1b12 +--- /dev/null ++++ b/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. @@ -1450,3 +1461,6 @@ index 0000000..60d4c1a +_GL_INLINE_HEADER_BEGIN + +#endif /* _MBFILE_H */ +-- +2.5.5 + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 79449d4..bcce9ff 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -106,7 +106,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c {"spaces", no_argument, NULL, 's'}, {"width", required_argument, NULL, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t +@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -114,7 +114,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing t +@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ static size_t adjust_column (size_t column, char c) { @@ -156,7 +156,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c fadvise (istream, FADVISE_SEQUENTIAL); -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t +@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width) bool found_blank = false; size_t logical_end = offset_out; @@ -172,16 +172,16 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t +@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t width) 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 (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + +} + +#if HAVE_MBRTOWC @@ -353,10 +353,10 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c + } + + *saved_errno = errno; - - if (offset_out) - fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); - ++ ++ if (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ +} +#endif + @@ -642,7 +642,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c static void freeline (struct line *line) { -@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct +@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct line const *line2, size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -773,8 +773,8 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c - 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]); @@ -784,14 +784,14 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c + 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; @@ -799,7 +799,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep, +@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep, int which) } ++line_no[which - 1]; @@ -811,7 +811,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c xfields (line); if (prevline[which - 1]) -@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li +@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *line) /* Output all the fields in line, other than the join field. */ @@ -851,7 +851,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c size_t field; struct line const *line; -@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct +@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct line const *line2) o = o->next; if (o == NULL) break; @@ -920,7 +920,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c --- coreutils-8.24-orig/src/pr.c 2015-06-26 19:05:22.000000000 +0200 +++ coreutils-8.24/src/pr.c 2015-07-05 09:04:33.030546965 +0200 -@@ -312,6 +312,24 @@ +@@ -311,6 +311,24 @@ #include #include @@ -945,7 +945,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c #include "system.h" #include "error.h" #include "fadvise.h" -@@ -324,6 +342,18 @@ +@@ -323,6 +341,18 @@ #include "xstrtol.h" #include "xdectoint.h" @@ -964,7 +964,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -416,7 +446,20 @@ struct COLUMN +@@ -415,7 +445,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -986,7 +986,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); +@@ -427,6 +470,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, @@ -994,7 +994,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c int *number); static void print_files (int number_of_files, char **av); static void init_parameters (int number_of_files); -@@ -441,7 +485,6 @@ static void store_char (char c); +@@ -440,7 +484,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); @@ -1002,7 +1002,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c static void cleanup (void); static void print_sep_string (void); static void separator_string (const char *optarg_S); -@@ -453,7 +496,7 @@ static COLUMN *column_vector; +@@ -452,7 +495,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]. */ @@ -1011,7 +1011,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* Index of the position in buff where the next character will be stored. */ -@@ -557,7 +600,7 @@ static int chars_per_column; +@@ -556,7 +599,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -1020,7 +1020,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... where the leftmost column is 1. */ -@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8; +@@ -566,7 +609,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -1032,7 +1032,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -637,7 +683,13 @@ static int line_number; +@@ -636,7 +682,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1047,7 +1047,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -690,6 +742,7 @@ static bool use_col_separator = false; +@@ -689,6 +741,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ static char *col_sep_string = (char *) ""; static int col_sep_length = 0; @@ -1055,7 +1055,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -840,6 +893,13 @@ separator_string (const char *optarg_S) +@@ -839,6 +892,13 @@ separator_string (const char *optarg_S) col_sep_length = (int) strlen (optarg_S); col_sep_string = xmalloc (col_sep_length + 1); strcpy (col_sep_string, optarg_S); @@ -1069,7 +1069,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c } int -@@ -864,6 +924,21 @@ main (int argc, char **argv) +@@ -863,6 +923,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1091,7 +1091,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c n_files = 0; file_names = (argc > 1 ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -940,8 +1015,12 @@ main (int argc, char **argv) +@@ -939,8 +1014,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1106,7 +1106,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -954,8 +1033,12 @@ main (int argc, char **argv) +@@ -953,8 +1032,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1121,7 +1121,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -973,8 +1056,8 @@ main (int argc, char **argv) +@@ -972,8 +1055,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1132,7 +1132,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c break; case 'N': skip_count = false; -@@ -998,7 +1081,7 @@ main (int argc, char **argv) +@@ -997,7 +1080,7 @@ main (int argc, char **argv) old_s = false; /* Reset an additional input of -s, -S dominates -s */ col_sep_string = bad_cast (""); @@ -1141,7 +1141,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i +@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err) a number. */ static void @@ -1359,7 +1359,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu +@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -1701,7 +1701,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c #include "system.h" #include "argmatch.h" #include "error.h" -@@ -164,14 +172,39 @@ static int decimal_point; +@@ -163,14 +171,39 @@ static int decimal_point; /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; @@ -1742,7 +1742,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -345,13 +378,11 @@ static bool reverse; +@@ -344,13 +377,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -1815,7 +1815,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c +@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -1833,7 +1833,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con +@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -1918,7 +1918,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf +@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -1927,7 +1927,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc +@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -1940,7 +1940,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc +@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2012,7 +2012,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struc +@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2025,7 +2025,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc +@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2038,7 +2038,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c if (newlim) lim = newlim; } -@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc +@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2169,7 +2169,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* 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 -@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c +@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2194,7 +2194,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c line->keybeg = line_start; } } -@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co +@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2203,7 +2203,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b +@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2229,7 +2229,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* 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 once -@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char +@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2238,7 +2238,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2279,15 +2644,14 @@ debug_key (struct line const *line, stru +@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2256,7 +2256,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2431,7 +2795,7 @@ key_warnings (struct keyfield const *gke +@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) && !(key->schar || key->echar); bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2265,7 +2265,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2489,11 +2853,87 @@ key_warnings (struct keyfield const *gke +@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -2354,7 +2354,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { struct keyfield *key = keylist; -@@ -2578,7 +3018,7 @@ keycompare (struct line const *a, struct +@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2363,7 +2363,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2694,6 +3134,211 @@ keycompare (struct line const *a, struct +@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -2575,7 +2575,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2721,7 +3366,7 @@ compare (struct line const *a, struct line const *b) +@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -2584,7 +2584,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { /* Note xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4120,6 +4765,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -2592,7 +2592,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c break; case 'g': key->general_numeric = true; -@@ -4197,7 +4843,7 @@ main (int argc, char **argv) +@@ -4199,7 +4845,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2601,7 +2601,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4218,6 +4864,29 @@ main (int argc, char **argv) +@@ -4220,6 +4866,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -2631,7 +2631,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c have_read_stdin = false; inittables (); -@@ -4492,13 +5161,34 @@ main (int argc, char **argv) +@@ -4494,13 +5163,34 @@ main (int argc, char **argv) case 't': { @@ -2670,7 +2670,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4509,9 +5199,12 @@ main (int argc, char **argv) +@@ -4511,9 +5201,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -2685,7 +2685,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c } break; -@@ -5444,12 +5444,10 @@ main (int argc, char **argv) +@@ -4751,12 +5444,10 @@ main (int argc, char **argv) sort (files, nfiles, outfile, nthreads); } @@ -2719,14 +2719,14 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -32,8 +43,20 @@ +@@ -31,9 +42,21 @@ #include "stdio--.h" #include "xmemcoll.h" #include "xstrtol.h" -#include "memcasecmp.h" +#include "xmemcoll.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 @@ -2738,9 +2738,10 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c +# 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" + @@ -143,6 +166,10 @@ enum GROUP_OPTION = CHAR_MAX + 1 }; @@ -2752,7 +2753,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -251,7 +278,7 @@ size_opt (char const *opt, char const *m +@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *msgid) return a pointer to the beginning of the line's field to be compared. */ static char * _GL_ATTRIBUTE_PURE @@ -2761,7 +2762,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -271,6 +298,83 @@ find_field (struct linebuffer const *lin +@@ -272,6 +299,83 @@ find_field (struct linebuffer const *line) return line->buffer + i; } @@ -2845,7 +2846,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c /* 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. -@@ -279,6 +383,8 @@ find_field (struct linebuffer const *lin +@@ -280,6 +384,8 @@ find_field (struct linebuffer const *line) static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -2854,7 +2855,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -286,15 +392,104 @@ different (char *old, char *new, size_t +@@ -287,14 +393,103 @@ different (char *old, char *new, size_t oldlen, size_t newlen) if (ignore_case) { @@ -2886,8 +2887,8 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c + + return xmemcoll (copy_old, oldlen, copy_new, newlen); + - } - ++} ++ +#if HAVE_MBRTOWC +static int +different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) @@ -2958,13 +2959,12 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c + free (copy[1]); + return rc; + -+} + } +#endif -+ + /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. - MATCH is true if the line matches the previous line. -@@ -358,19 +553,38 @@ check_file (const char *infile, const ch +@@ -359,19 +554,38 @@ check_file (const char *infile, const char *outfile, char delimiter) char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); bool first_group_printed = false; @@ -3003,7 +3003,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c new_group = (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)); -@@ -388,6 +602,10 @@ check_file (const char *infile, const ch +@@ -389,6 +603,10 @@ check_file (const char *infile, const char *outfile, char delimiter) SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3014,7 +3014,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c first_group_printed = true; } } -@@ -400,17 +618,26 @@ check_file (const char *infile, const ch +@@ -401,17 +619,26 @@ check_file (const char *infile, const char *outfile, char delimiter) size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -3041,7 +3041,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -419,6 +646,14 @@ check_file (const char *infile, const ch +@@ -420,6 +647,14 @@ check_file (const char *infile, const char *outfile, char delimiter) } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -3056,7 +3056,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -451,6 +686,9 @@ check_file (const char *infile, const ch +@@ -452,6 +687,9 @@ check_file (const char *infile, const char *outfile, char delimiter) SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3066,7 +3066,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c if (!match) match_count = 0; } -@@ -497,6 +735,19 @@ main (int argc, char **argv) +@@ -498,6 +736,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -3122,7 +3122,7 @@ diff -urNp coreutils-8.24-orig/tests/i18n/sort.sh coreutils-8.24/tests/i18n/sort diff -urNp coreutils-8.24-orig/tests/local.mk coreutils-8.24/tests/local.mk --- coreutils-8.24-orig/tests/local.mk 2015-07-05 09:00:46.526859558 +0200 +++ coreutils-8.24/tests/local.mk 2015-07-05 09:04:33.033546987 +0200 -@@ -341,6 +341,8 @@ all_tests = \ +@@ -344,6 +344,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -3148,7 +3148,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/cut.pl coreutils-8.24/tests/misc/cut.p my $prog = 'cut'; my $try = "Try '$prog --help' for more information.\n"; -@@ -227,6 +229,7 @@ if ($mb_locale ne 'C') +@@ -240,6 +242,7 @@ if ($mb_locale ne 'C') my @new_t = @$t; my $test_name = shift @new_t; @@ -3304,7 +3304,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/join.pl coreutils-8.24/tests/misc/join my $delim = chr 0247; sub t_subst ($) { -@@ -326,8 +335,49 @@ foreach my $t (@tv) +@@ -329,8 +338,49 @@ foreach my $t (@tv) push @Tests, $new_ent; } @@ -3482,7 +3482,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/sort.pl coreutils-8.24/tests/misc/sort # 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 '-'. -@@ -419,6 +428,38 @@ foreach my $t (@Tests) +@@ -424,6 +429,38 @@ foreach my $t (@Tests) } } @@ -3521,7 +3521,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/sort.pl coreutils-8.24/tests/misc/sort @Tests = triple_test \@Tests; # Remember that triple_test creates from each test with exactly one "IN" -@@ -428,6 +469,7 @@ foreach my $t (@Tests) +@@ -433,6 +470,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; @@ -3606,7 +3606,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/uniq.pl coreutils-8.24/tests/misc/uniq # When possible, create a "-z"-testing variant of each test. sub add_z_variants($) { -@@ -261,6 +269,53 @@ foreach my $t (@Tests) +@@ -262,6 +270,53 @@ foreach my $t (@Tests) and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; } diff --git a/coreutils-overflow.patch b/coreutils-overflow.patch index 0d55a6d..06059a9 100644 --- a/coreutils-overflow.patch +++ b/coreutils-overflow.patch @@ -1,6 +1,6 @@ --- coreutils-5.2.1/src/who.c.overflow 2005-05-25 09:59:06.000000000 +0100 +++ coreutils-5.2.1/src/who.c 2005-05-25 10:00:31.000000000 +0100 -@@ -75,7 +75,7 @@ +@@ -79,7 +79,7 @@ # define UT_TYPE_NEW_TIME(U) false #endif diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index bfcc9d3..9f45177 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -20,7 +20,7 @@ diff -urNp coreutils-8.21-orig/man/runcon.x coreutils-8.21/man/runcon.x diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c --- coreutils-8.21-orig/src/cp.c 2013-02-07 10:37:05.000000000 +0100 +++ coreutils-8.21/src/cp.c 2013-02-15 14:31:58.945468929 +0100 -@@ -201,6 +202,9 @@ Copy SOURCE to DEST, or multiple SOURCE( +@@ -202,6 +202,9 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ all\n\ "), stdout); fputs (_("\ @@ -30,7 +30,7 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents use full source file name under DIRECTORY\n\ "), stdout); -@@ -933,7 +939,7 @@ main (int argc, char **argv) +@@ -943,7 +946,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -39,7 +39,7 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c long_opts, NULL)) != -1) { -@@ -981,6 +987,17 @@ main (int argc, char **argv) +@@ -991,6 +994,17 @@ main (int argc, char **argv) copy_contents = true; break; @@ -60,7 +60,7 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c diff -urNp coreutils-8.21-orig/src/id.c coreutils-8.21/src/id.c --- coreutils-8.21-orig/src/id.c 2013-01-31 01:46:24.000000000 +0100 +++ coreutils-8.21/src/id.c 2013-02-15 14:31:58.946469154 +0100 -@@ -106,7 +106,7 @@ int +@@ -113,7 +113,7 @@ int main (int argc, char **argv) { int optc; @@ -72,7 +72,7 @@ diff -urNp coreutils-8.21-orig/src/id.c coreutils-8.21/src/id.c diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c --- coreutils-8.21-orig/src/install.c 2013-02-07 10:37:05.000000000 +0100 +++ coreutils-8.21/src/install.c 2013-02-15 14:31:58.948469440 +0100 -@@ -639,7 +640,7 @@ In the 4th form, create all components o +@@ -649,7 +649,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ @@ -81,7 +81,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c -Z set SELinux security context of destination\n\ file to default type\n\ --context[=CTX] like -Z, or if CTX is specified then set the\n\ -@@ -782,7 +783,7 @@ main (int argc, char **argv) +@@ -817,7 +817,7 @@ main (int argc, char **argv) we'll actually use backup_suffix_string. */ backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); @@ -90,7 +90,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c NULL)) != -1) { switch (optc) -@@ -853,6 +854,8 @@ main (int argc, char **argv) +@@ -878,6 +878,8 @@ main (int argc, char **argv) no_target_directory = true; break; @@ -99,7 +99,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c case PRESERVE_CONTEXT_OPTION: if (! selinux_enabled) { -@@ -860,6 +862,10 @@ main (int argc, char **argv) +@@ -885,6 +887,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } diff --git a/coreutils-selinuxmanpages.patch b/coreutils-selinuxmanpages.patch index 7b27f90..1540613 100644 --- a/coreutils-selinuxmanpages.patch +++ b/coreutils-selinuxmanpages.patch @@ -1,7 +1,7 @@ diff -urNp coreutils-6.10-orig/doc/coreutils.texi coreutils-6.10/doc/coreutils.texi --- coreutils-6.10-orig/doc/coreutils.texi 2008-04-07 17:52:11.000000000 +0200 +++ coreutils-6.10/doc/coreutils.texi 2008-04-07 18:01:43.000000000 +0200 -@@ -6981,6 +6981,11 @@ for i; do +@@ -8002,6 +8002,11 @@ done exit $fail @end example diff --git a/sh-utils-2.0.11-dateman.patch b/sh-utils-2.0.11-dateman.patch index 8684dc7..60cdaa6 100644 --- a/sh-utils-2.0.11-dateman.patch +++ b/sh-utils-2.0.11-dateman.patch @@ -1,7 +1,7 @@ diff -urNp coreutils-5.97-orig/man/date.x coreutils-5.97/man/date.x --- coreutils-5.97-orig/man/date.x 1999-11-02 15:07:36.000000000 +0100 +++ coreutils-5.97/man/date.x 2008-10-15 10:13:31.000000000 +0200 -@@ -11,3 +11,8 @@ +@@ -11,3 +11,8 @@ calendar date, time of day, time zone, day of week, relative time, relative date, and numbers. An empty string indicates the beginning of the day. The date string format is more complex than is easily documented here but is fully described in the info documentation. From 6cf6cd48dd1577f0f69816c3afcd4775b0d281bb Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 14 Jul 2016 16:50:51 +0200 Subject: [PATCH 320/523] make 'sort -h' work for arbitrary column ... even when using UTF-8 locales --- coreutils-i18n-sort-human.patch | 35 +++++++++++++++++++++++++++++++++ coreutils.spec | 8 +++++++- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 coreutils-i18n-sort-human.patch diff --git a/coreutils-i18n-sort-human.patch b/coreutils-i18n-sort-human.patch new file mode 100644 index 0000000..2469189 --- /dev/null +++ b/coreutils-i18n-sort-human.patch @@ -0,0 +1,35 @@ +From 3976ef5a20369d8b490907ab2cba2d617305a5e0 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 30 May 2016 16:19:20 +0200 +Subject: [PATCH] sort: do not use static array 'blanks' in human_numcompare() + +... because the array is not initialized with MB locales. Note this is +rather a conservative fix. I plan to do more cleanup of the i18n patch +in Fedora to prevent mistakes like this in future updates of coreutils. +--- + src/sort.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/sort.c b/src/sort.c +index 9e07ad8..e47b039 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -2274,12 +2274,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)); +-- +2.5.5 + diff --git a/coreutils.spec b/coreutils.spec index e48bca6..010fe77 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -53,6 +53,8 @@ Patch803: coreutils-i18n-fix-unexpand.patch Patch805: coreutils-i18n-fix2-expand-unexpand.patch #(un)expand - test BOM headers Patch806: coreutils-i18n-un-expand-BOM.patch +# make 'sort -h' work for arbitrary column even when using UTF-8 locales +Patch807: coreutils-i18n-sort-human.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch @@ -195,6 +197,7 @@ tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null %patch804 -p1 -b .i18n-cutold %patch805 -p1 -b .i18n-fix2-expand-unexpand %patch806 -p1 -b .i18n-BOM-expand-unexpand +%patch807 -p1 # Coreutils %patch908 -p1 -b .getgrouplist @@ -349,6 +352,9 @@ fi %license COPYING %changelog +* Thu Jul 14 2016 Kamil Dudka - 8.25-13 +- make 'sort -h' work for arbitrary column even when using UTF-8 locales + * Mon Jul 11 2016 Kamil Dudka - 8.25-12 - install -Z now sets default SELinux context for created directories (#1339135) - drop the %%pre scriptlet, which is no longer needed (#1354078) From 8b01f2371c4f35fa629cba7e630183141f24be99 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 19 Jul 2016 13:52:45 +0200 Subject: [PATCH 321/523] Resolves: #1355780 - fix 'sort -h -k' in locales that use blank as thousands separator --- coreutils-8.25-sort-thousands-sep.patch | 332 ++++++++++++++++++++++++ coreutils.spec | 11 +- 2 files changed, 342 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.25-sort-thousands-sep.patch diff --git a/coreutils-8.25-sort-thousands-sep.patch b/coreutils-8.25-sort-thousands-sep.patch new file mode 100644 index 0000000..b9d2b5c --- /dev/null +++ b/coreutils-8.25-sort-thousands-sep.patch @@ -0,0 +1,332 @@ +From c479153d77b419a6cae4551b63d2b73096c1130e Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 18 Jul 2016 19:04:43 +0200 +Subject: [PATCH 1/3] maint: sort.c: deduplicate code for traversing numbers + +* src/sort.c (traverse_raw_number): New function for traversing numbers. +(find_unit_order): Use traverse_raw_number() instead of open-coding it. +(debug_key): Likewise. +--- + src/sort.c | 63 ++++++++++++++++++++++++++++++++++---------------------------- + 1 file changed, 35 insertions(+), 28 deletions(-) + +diff --git a/src/sort.c b/src/sort.c +index 5b02343..e28bb6c 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -2231,18 +2231,16 @@ static char const unit_order[UCHAR_LIM] = + #endif + }; + +-/* Return an integer that represents the order of magnitude of the +- unit following the number. The number may contain thousands +- separators and a decimal point, but it may not contain leading blanks. +- Negative numbers get negative orders; zero numbers have a zero order. */ +- +-static int _GL_ATTRIBUTE_PURE +-find_unit_order (char const *number) ++/* Traverse number given as *number consisting of digits, thousands_sep, and ++ decimal_point chars only. Returns the highest digit found in the number, ++ or '\0' if no digit has been found. Upon return *number points at the ++ character that immediately follows after the given number. */ ++static unsigned char ++traverse_raw_number (char const **number) + { +- bool minus_sign = (*number == '-'); +- char const *p = number + minus_sign; +- int nonzero = 0; ++ char const *p = *number; + unsigned char ch; ++ unsigned char max_digit = '\0'; + + /* Scan to end of number. + Decimals or separators not followed by digits stop the scan. +@@ -2253,16 +2251,34 @@ find_unit_order (char const *number) + do + { + while (ISDIGIT (ch = *p++)) +- nonzero |= ch - '0'; ++ if (max_digit < ch) ++ max_digit = ch; + } + while (ch == thousands_sep); + + if (ch == decimal_point) + while (ISDIGIT (ch = *p++)) +- nonzero |= ch - '0'; ++ if (max_digit < ch) ++ max_digit = ch; ++ ++ *number = p - 1; ++ return max_digit; ++} ++ ++/* Return an integer that represents the order of magnitude of the ++ unit following the number. The number may contain thousands ++ separators and a decimal point, but it may not contain leading blanks. ++ Negative numbers get negative orders; zero numbers have a zero order. */ + +- if (nonzero) ++static int _GL_ATTRIBUTE_PURE ++find_unit_order (char const *number) ++{ ++ bool minus_sign = (*number == '-'); ++ char const *p = number + minus_sign; ++ unsigned char max_digit = traverse_raw_number (&p); ++ if ('0' < max_digit) + { ++ unsigned char ch = *p; + int order = unit_order[ch]; + return (minus_sign ? -order : order); + } +@@ -2655,23 +2671,14 @@ debug_key (struct line const *line, struct keyfield const *key) + ignore_value (strtold (beg, &tighter_lim)); + else if (key->numeric || key->human_numeric) + { +- char *p = beg + (beg < lim && *beg == '-'); +- bool found_digit = false; +- unsigned char ch; +- +- do ++ char const *p = beg + (beg < lim && *beg == '-'); ++ unsigned char max_digit = traverse_raw_number (&p); ++ if ('0' <= max_digit) + { +- while (ISDIGIT (ch = *p++)) +- found_digit = true; ++ unsigned char ch = *p; ++ tighter_lim = (char *) p ++ + (key->human_numeric && unit_order[ch]); + } +- while (ch == thousands_sep); +- +- if (ch == decimal_point) +- while (ISDIGIT (ch = *p++)) +- found_digit = true; +- +- if (found_digit) +- tighter_lim = p - ! (key->human_numeric && unit_order[ch]); + } + else + tighter_lim = lim; +-- +2.5.5 + + +From 8c39465a5b0343ff7a21286dd69ed5430685d2f7 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 18 Jul 2016 19:04:44 +0200 +Subject: [PATCH 2/3] sort: make -h work with -k and blank used as thousands + separator + +* src/sort.c (traverse_raw_number): Allow to skip only one occurrence +of thousands_sep to avoid finding the unit in the next column in case +thousands_sep matches as blank and is used as column delimiter. +* tests/misc/sort-h-thousands-sep.sh: Add regression test for this bug. +* tests/local.mk: Reference the test. +* NEWS: Mention the bug fix. +Reported at https://bugzilla.redhat.com/1355780 +Fixes http://bugs.gnu.org/24015 +--- + src/sort.c | 14 ++++++++---- + tests/local.mk | 1 + + tests/misc/sort-h-thousands-sep.sh | 47 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 57 insertions(+), 5 deletions(-) + create mode 100755 tests/misc/sort-h-thousands-sep.sh + +diff --git a/src/sort.c b/src/sort.c +index e28bb6c..dd3ba58 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -2248,13 +2248,17 @@ traverse_raw_number (char const **number) + to be lacking in units. + FIXME: add support for multibyte thousands_sep and decimal_point. */ + +- do ++ while (ISDIGIT (ch = *p++)) + { +- while (ISDIGIT (ch = *p++)) +- if (max_digit < ch) +- max_digit = ch; ++ if (max_digit < ch) ++ max_digit = ch; ++ ++ /* Allow to skip only one occurrence of thousands_sep to avoid finding ++ the unit in the next column in case thousands_sep matches as blank ++ and is used as column delimiter. */ ++ if (*p == thousands_sep) ++ ++p; + } +- while (ch == thousands_sep); + + if (ch == decimal_point) + while (ISDIGIT (ch = *p++)) +diff --git a/tests/local.mk b/tests/local.mk +index 42d39f2..dccff8d 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -344,6 +344,7 @@ all_tests = \ + tests/misc/sort-discrim.sh \ + tests/misc/sort-files0-from.pl \ + tests/misc/sort-float.sh \ ++ tests/misc/sort-h-thousands-sep.sh \ + tests/misc/sort-mb-tests.sh \ + tests/i18n/sort.sh \ + tests/misc/sort-merge.pl \ +diff --git a/tests/misc/sort-h-thousands-sep.sh b/tests/misc/sort-h-thousands-sep.sh +new file mode 100755 +index 0000000..17f1b6c +--- /dev/null ++++ b/tests/misc/sort-h-thousands-sep.sh +@@ -0,0 +1,47 @@ ++#!/bin/sh ++# exercise 'sort -h' in locales where thousands separator is blank ++ ++# Copyright (C) 2016 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ sort ++test "$(LC_ALL=sv_SE locale thousands_sep)" = ' ' \ ++ || skip_ 'The Swedish locale with blank thousands separator is unavailable.' ++ ++tee exp1 > in << _EOF_ ++1 1k 4 003 1M ++2k 2M 4 002 2 ++3M 3 4 001 3k ++_EOF_ ++ ++cat > exp2 << _EOF_ ++3M 3 4 001 3k ++1 1k 4 003 1M ++2k 2M 4 002 2 ++_EOF_ ++ ++cat > exp3 << _EOF_ ++3M 3 4 001 3k ++2k 2M 4 002 2 ++1 1k 4 003 1M ++_EOF_ ++ ++for i in 1 2 3; do ++ LC_ALL="sv_SE.utf8" sort -h -k $i "in" > "out${i}" || fail=1 ++ compare "exp${i}" "out${i}" || fail=1 ++done ++ ++Exit $fail +-- +2.5.5 + + +From 46ef53f558e7bc1c0bc0abd62a86b40b4141e058 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 18 Jul 2016 19:04:45 +0200 +Subject: [PATCH 3/3] sort: with -h, disallow thousands separator between + number and unit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* src/sort.c (traverse_raw_number): Accept thousands separator only +if it is immediately followed by a digit. +* tests/misc/sort-h-thousands-sep.sh: Cover the fix for this bug. + +Suggested by Pádraig Brady in http://bugs.gnu.org/24015 +--- + src/sort.c | 11 ++++++++++- + tests/misc/sort-h-thousands-sep.sh | 25 +++++++++++++------------ + 2 files changed, 23 insertions(+), 13 deletions(-) + +diff --git a/src/sort.c b/src/sort.c +index dd3ba58..69ef75f 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -2241,6 +2241,7 @@ traverse_raw_number (char const **number) + char const *p = *number; + unsigned char ch; + unsigned char max_digit = '\0'; ++ bool ends_with_thousands_sep = false; + + /* Scan to end of number. + Decimals or separators not followed by digits stop the scan. +@@ -2256,10 +2257,18 @@ traverse_raw_number (char const **number) + /* Allow to skip only one occurrence of thousands_sep to avoid finding + the unit in the next column in case thousands_sep matches as blank + and is used as column delimiter. */ +- if (*p == thousands_sep) ++ ends_with_thousands_sep = (*p == thousands_sep); ++ if (ends_with_thousands_sep) + ++p; + } + ++ if (ends_with_thousands_sep) ++ { ++ /* thousands_sep not followed by digit is not allowed. */ ++ *number = p - 2; ++ return max_digit; ++ } ++ + if (ch == decimal_point) + while (ISDIGIT (ch = *p++)) + if (max_digit < ch) +diff --git a/tests/misc/sort-h-thousands-sep.sh b/tests/misc/sort-h-thousands-sep.sh +index 17f1b6c..3ffa89e 100755 +--- a/tests/misc/sort-h-thousands-sep.sh ++++ b/tests/misc/sort-h-thousands-sep.sh +@@ -18,28 +18,29 @@ + + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ sort ++ + test "$(LC_ALL=sv_SE locale thousands_sep)" = ' ' \ + || skip_ 'The Swedish locale with blank thousands separator is unavailable.' + +-tee exp1 > in << _EOF_ +-1 1k 4 003 1M +-2k 2M 4 002 2 +-3M 3 4 001 3k ++tee exp1 exp3 > in << _EOF_ ++1 1k 1 M 4 003 1M ++2k 2M 2 k 4 002 2 ++3M 3 3 G 4 001 3k + _EOF_ + + cat > exp2 << _EOF_ +-3M 3 4 001 3k +-1 1k 4 003 1M +-2k 2M 4 002 2 ++3M 3 3 G 4 001 3k ++1 1k 1 M 4 003 1M ++2k 2M 2 k 4 002 2 + _EOF_ + +-cat > exp3 << _EOF_ +-3M 3 4 001 3k +-2k 2M 4 002 2 +-1 1k 4 003 1M ++cat > exp5 << _EOF_ ++3M 3 3 G 4 001 3k ++2k 2M 2 k 4 002 2 ++1 1k 1 M 4 003 1M + _EOF_ + +-for i in 1 2 3; do ++for i in 1 2 3 5; do + LC_ALL="sv_SE.utf8" sort -h -k $i "in" > "out${i}" || fail=1 + compare "exp${i}" "out${i}" || fail=1 + done +-- +2.5.5 + diff --git a/coreutils.spec b/coreutils.spec index 010fe77..934e7a3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 13%{?dist} +Release: 14%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -19,6 +19,8 @@ Source10: coreutils-find-requires.sh # From upstream Patch952: coreutils-8.25-intall-Z-selinux.patch +# fix 'sort -h -k' in locales that use blank as thousands separator (#1355780) +Patch953: coreutils-8.25-sort-thousands-sep.patch # Our patches #general patch to workaround koji build system issues @@ -209,9 +211,13 @@ tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null %patch951 -p1 -b .selinuxman %patch952 -p1 +# upstream patches +%patch953 -p1 + chmod a+x \ tests/df/direct.sh \ tests/install/install-Z-selinux.sh \ + tests/misc/sort-h-thousands-sep.sh \ tests/misc/sort-mb-tests.sh \ || : @@ -352,6 +358,9 @@ fi %license COPYING %changelog +* Tue Jul 19 2016 Kamil Dudka - 8.25-14 +- fix 'sort -h -k' in locales that use blank as thousands separator (#1355780) + * Thu Jul 14 2016 Kamil Dudka - 8.25-13 - make 'sort -h' work for arbitrary column even when using UTF-8 locales From adf19d29ece14ba661d133ebc908843c853c1a8b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 19 Jul 2016 14:00:38 +0200 Subject: [PATCH 322/523] drop post-install fix for Japanese locales that no longer applies --- coreutils.spec | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 934e7a3..96ad694 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -286,14 +286,6 @@ for type in separate single; do fi done -# fix japanese catalog file -if [ -d $RPM_BUILD_ROOT%{_datadir}/locale/ja_JP.EUC/LC_MESSAGES ]; then - mkdir -p $RPM_BUILD_ROOT%{_datadir}/locale/ja/LC_MESSAGES - mv $RPM_BUILD_ROOT%{_datadir}/locale/ja_JP.EUC/LC_MESSAGES/*mo \ - $RPM_BUILD_ROOT%{_datadir}/locale/ja/LC_MESSAGES - rm -rf $RPM_BUILD_ROOT%{_datadir}/locale/ja_JP.EUC -fi - bzip2 -9f ChangeLog mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d @@ -359,6 +351,7 @@ fi %changelog * Tue Jul 19 2016 Kamil Dudka - 8.25-14 +- drop post-install fix for Japanese locales that no longer applies - fix 'sort -h -k' in locales that use blank as thousands separator (#1355780) * Thu Jul 14 2016 Kamil Dudka - 8.25-13 From 39f7c7c836d63c96a8c9148ddc9c21b567705f1f Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 19 Jul 2016 15:09:42 +0200 Subject: [PATCH 323/523] run autoreconf in %prep --- coreutils.spec | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 96ad694..ca83275 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -111,7 +111,7 @@ BuildRequires: attr BuildRequires: autoconf BuildRequires: automake BuildRequires: bison -BuildRequires: gettext +BuildRequires: gettext-devel BuildRequires: gmp-devel BuildRequires: libacl-devel BuildRequires: libattr-devel @@ -226,14 +226,11 @@ find ./po/ -name "*.p*" | xargs \ sed -i \ -e 's/-dpR/-cdpR/' +autoreconf -fiv + %build export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" %{expand:%%global optflags %{optflags} -D_GNU_SOURCE=1} -#autoreconf -i -v -touch aclocal.m4 configure config.hin Makefile.in */Makefile.in -aclocal -I m4 -autoconf --force -automake --copy --add-missing for type in separate single; do mkdir $type && \ (cd $type && ln -s ../configure || exit 1 @@ -351,6 +348,7 @@ fi %changelog * Tue Jul 19 2016 Kamil Dudka - 8.25-14 +- run autoreconf in %%prep - drop post-install fix for Japanese locales that no longer applies - fix 'sort -h -k' in locales that use blank as thousands separator (#1355780) From 0e3a55d8dcf4a99b598e96bb812ca5a6d261996a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 7 Sep 2016 20:09:15 +0200 Subject: [PATCH 324/523] coreutils.spec: do not compress files that are not installed --- coreutils.spec | 5 ----- 1 file changed, 5 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index ca83275..e1a669f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -283,17 +283,12 @@ for type in separate single; do fi done -bzip2 -9f ChangeLog - mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d install -p -c -m644 DIR_COLORS{,.256color,.lightbgcolor} \ $RPM_BUILD_ROOT%{_sysconfdir} install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh -# Compress ChangeLogs from before the fileutils/textutils/etc merge -bzip2 -f9 old/*/C* - # Use hard links instead of symbolic links for LC_TIME files (bug #246729). find %{buildroot}%{_datadir}/locale -type l | \ (while read link From 380647993e0806d823c4548cb72384bee95db58e Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 7 Sep 2016 20:17:56 +0200 Subject: [PATCH 325/523] Resolves: #1365933 - ls: allow interruption when reading slow directories --- coreutils-8.25-ls-signal.patch | 236 +++++++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.25-ls-signal.patch diff --git a/coreutils-8.25-ls-signal.patch b/coreutils-8.25-ls-signal.patch new file mode 100644 index 0000000..32cfd3a --- /dev/null +++ b/coreutils-8.25-ls-signal.patch @@ -0,0 +1,236 @@ +From 9338b244572e07bbff314b3570228e8cf43f1300 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Tue, 6 Sep 2016 17:38:26 +0200 +Subject: [PATCH] ls: allow interruption when reading slow directories + +Postpone installation of signal handlers until they're needed. +That is right before the first escape sequence is printed. + +* src/ls.c (signal_setup): A new function refactored from main() +to set and restore signal handlers. +(main): Move signal handler setup to put_indicator() +so that the default signal handling is untouched as long as possible. +Adjusted condition for restoring signal handlers to reflect the change. +(put_indicator): Install signal handlers if called for the very first +time. It uses the same code that was in main() prior to this commit. +* NEWS: Mention the improvement. + +See https://bugzilla.redhat.com/1365933 +Fixes http://bugs.gnu.org/24232 + +Upstream-commit: 5445f7811ff945ea13aa2a0fd797eb4c0a0e4db0 +Signed-off-by: Kamil Dudka +--- + src/ls.c | 161 ++++++++++++++++++++++++++++++++++++--------------------------- + 1 file changed, 93 insertions(+), 68 deletions(-) + +diff --git a/src/ls.c b/src/ls.c +index d976036..66df307 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -1244,13 +1244,12 @@ process_signals (void) + } + } + +-int +-main (int argc, char **argv) +-{ +- int i; +- struct pending *thispend; +- int n_files; ++/* Setup signal handlers if INIT is true, ++ otherwise restore to the default. */ + ++static void ++signal_setup (bool init) ++{ + /* The signals that are trapped, and the number of such signals. */ + static int const sig[] = + { +@@ -1278,8 +1277,77 @@ main (int argc, char **argv) + enum { nsigs = ARRAY_CARDINALITY (sig) }; + + #if ! SA_NOCLDSTOP +- bool caught_sig[nsigs]; ++ static bool caught_sig[nsigs]; ++#endif ++ ++ int j; ++ ++ if (init) ++ { ++#if SA_NOCLDSTOP ++ struct sigaction act; ++ ++ sigemptyset (&caught_signals); ++ for (j = 0; j < nsigs; j++) ++ { ++ sigaction (sig[j], NULL, &act); ++ if (act.sa_handler != SIG_IGN) ++ sigaddset (&caught_signals, sig[j]); ++ } ++ ++ act.sa_mask = caught_signals; ++ act.sa_flags = SA_RESTART; ++ ++ for (j = 0; j < nsigs; j++) ++ if (sigismember (&caught_signals, sig[j])) ++ { ++ act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; ++ sigaction (sig[j], &act, NULL); ++ } ++#else ++ for (j = 0; j < nsigs; j++) ++ { ++ caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); ++ if (caught_sig[j]) ++ { ++ signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); ++ siginterrupt (sig[j], 0); ++ } ++ } + #endif ++ } ++ else /* restore. */ ++ { ++#if SA_NOCLDSTOP ++ for (j = 0; j < nsigs; j++) ++ if (sigismember (&caught_signals, sig[j])) ++ signal (sig[j], SIG_DFL); ++#else ++ for (j = 0; j < nsigs; j++) ++ if (caught_sig[j]) ++ signal (sig[j], SIG_DFL); ++#endif ++ } ++} ++ ++static inline void ++signal_init (void) ++{ ++ signal_setup (true); ++} ++ ++static inline void ++signal_restore (void) ++{ ++ signal_setup (false); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ int i; ++ struct pending *thispend; ++ int n_files; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +@@ -1314,46 +1382,6 @@ main (int argc, char **argv) + || (is_colored (C_EXEC) && color_symlink_as_referent) + || (is_colored (C_MISSING) && format == long_format)) + check_symlink_color = true; +- +- /* If the standard output is a controlling terminal, watch out +- for signals, so that the colors can be restored to the +- default state if "ls" is suspended or interrupted. */ +- +- if (0 <= tcgetpgrp (STDOUT_FILENO)) +- { +- int j; +-#if SA_NOCLDSTOP +- struct sigaction act; +- +- sigemptyset (&caught_signals); +- for (j = 0; j < nsigs; j++) +- { +- sigaction (sig[j], NULL, &act); +- if (act.sa_handler != SIG_IGN) +- sigaddset (&caught_signals, sig[j]); +- } +- +- act.sa_mask = caught_signals; +- act.sa_flags = SA_RESTART; +- +- for (j = 0; j < nsigs; j++) +- if (sigismember (&caught_signals, sig[j])) +- { +- act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; +- sigaction (sig[j], &act, NULL); +- } +-#else +- for (j = 0; j < nsigs; j++) +- { +- caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); +- if (caught_sig[j]) +- { +- signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); +- siginterrupt (sig[j], 0); +- } +- } +-#endif +- } + } + + if (dereference == DEREF_UNDEFINED) +@@ -1466,32 +1494,21 @@ main (int argc, char **argv) + print_dir_name = true; + } + +- if (print_with_color) ++ if (print_with_color && used_color) + { + int j; + +- if (used_color) +- { +- /* Skip the restore when it would be a no-op, i.e., +- when left is "\033[" and right is "m". */ +- if (!(color_indicator[C_LEFT].len == 2 +- && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0 +- && color_indicator[C_RIGHT].len == 1 +- && color_indicator[C_RIGHT].string[0] == 'm')) +- restore_default_color (); +- } ++ /* Skip the restore when it would be a no-op, i.e., ++ when left is "\033[" and right is "m". */ ++ if (!(color_indicator[C_LEFT].len == 2 ++ && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0 ++ && color_indicator[C_RIGHT].len == 1 ++ && color_indicator[C_RIGHT].string[0] == 'm')) ++ restore_default_color (); ++ + fflush (stdout); + +- /* Restore the default signal handling. */ +-#if SA_NOCLDSTOP +- for (j = 0; j < nsigs; j++) +- if (sigismember (&caught_signals, sig[j])) +- signal (sig[j], SIG_DFL); +-#else +- for (j = 0; j < nsigs; j++) +- if (caught_sig[j]) +- signal (sig[j], SIG_DFL); +-#endif ++ signal_restore (); + + /* Act on any signals that arrived before the default was restored. + This can process signals out of order, but there doesn't seem to +@@ -4482,6 +4499,14 @@ put_indicator (const struct bin_str *ind) + if (! used_color) + { + used_color = true; ++ ++ /* If the standard output is a controlling terminal, watch out ++ for signals, so that the colors can be restored to the ++ default state if "ls" is suspended or interrupted. */ ++ ++ if (0 <= tcgetpgrp (STDOUT_FILENO)) ++ signal_init (); ++ + prep_non_filename_text (); + } + +-- +2.7.4 + diff --git a/coreutils.spec b/coreutils.spec index e1a669f..daa44fc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 14%{?dist} +Release: 15%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -21,6 +21,8 @@ Source10: coreutils-find-requires.sh Patch952: coreutils-8.25-intall-Z-selinux.patch # fix 'sort -h -k' in locales that use blank as thousands separator (#1355780) Patch953: coreutils-8.25-sort-thousands-sep.patch +# ls: allow interruption when reading slow directories (#1365933) +Patch954: coreutils-8.25-ls-signal.patch # Our patches #general patch to workaround koji build system issues @@ -213,6 +215,7 @@ tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null # upstream patches %patch953 -p1 +%patch954 -p1 chmod a+x \ tests/df/direct.sh \ @@ -342,6 +345,9 @@ fi %license COPYING %changelog +* Wed Sep 07 2016 Kamil Dudka - 8.25-15 +- ls: allow interruption when reading slow directories (#1365933) + * Tue Jul 19 2016 Kamil Dudka - 8.25-14 - run autoreconf in %%prep - drop post-install fix for Japanese locales that no longer applies From 21de8b5251972b49ed5da467580ce7b0371c7979 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 11 Oct 2016 13:25:50 +0200 Subject: [PATCH 326/523] rebuild with OpenSSL 1.1.0 --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index daa44fc..88bab95 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 15%{?dist} +Release: 16%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -345,6 +345,9 @@ fi %license COPYING %changelog +* Tue Oct 11 2016 Tomáš Mráz - 8.25-16 +- rebuild with OpenSSL 1.1.0 + * Wed Sep 07 2016 Kamil Dudka - 8.25-15 - ls: allow interruption when reading slow directories (#1365933) From 3ed22ec3e82e234daf53c2f08387ab755a602fc2 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 31 Oct 2016 17:52:01 +0100 Subject: [PATCH 327/523] md5sum,sha*sum: fix --ignore-missing with checksums starting with 00 --- coreutils-8.25-sum-ignore-missing.patch | 115 ++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.25-sum-ignore-missing.patch diff --git a/coreutils-8.25-sum-ignore-missing.patch b/coreutils-8.25-sum-ignore-missing.patch new file mode 100644 index 0000000..d27d176 --- /dev/null +++ b/coreutils-8.25-sum-ignore-missing.patch @@ -0,0 +1,115 @@ +From 1e1a69da31b39e4d672ccb8a3ca0e5400d4720ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Wed, 26 Oct 2016 15:45:01 +0100 +Subject: [PATCH] md5sum,sha*sum: fix --ignore-missing with checksums starting + with 00 + +* NEWS: Mention the fix. +* src/md5sum.c (digest_file): Add a new MISSING parameter to +return whether the file was missing, separately from the digest. +* tests/misc/md5sum.pl: Add a test case. +Fixes http://bugs.gnu.org/24795 + +Upstream-commit: d0ddfadfb27def2861f35b1a45190a4c1780b257 +Signed-off-by: Kamil Dudka +--- + src/md5sum.c | 20 ++++++++++++-------- + tests/misc/md5sum.pl | 7 +++++++ + 2 files changed, 19 insertions(+), 8 deletions(-) + +diff --git a/src/md5sum.c b/src/md5sum.c +index 933ec99..fee28c7 100644 +--- a/src/md5sum.c ++++ b/src/md5sum.c +@@ -465,15 +465,19 @@ print_filename (char const *file, bool escape) + text because it was a terminal. + + Put the checksum in *BIN_RESULT, which must be properly aligned. ++ Put true in *MISSING if the file can't be opened due to ENOENT. + Return true if successful. */ + + static bool +-digest_file (const char *filename, int *binary, unsigned char *bin_result) ++digest_file (const char *filename, int *binary, unsigned char *bin_result, ++ bool *missing) + { + FILE *fp; + int err; + bool is_stdin = STREQ (filename, "-"); + ++ *missing = false; ++ + if (is_stdin) + { + have_read_stdin = true; +@@ -493,7 +497,7 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result) + { + if (ignore_missing && errno == ENOENT) + { +- *bin_result = '\0'; ++ *missing = true; + return true; + } + error (0, errno, "%s", quotef (filename)); +@@ -606,14 +610,14 @@ digest_check (const char *checkfile_name) + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f' }; + bool ok; ++ bool missing; + /* Only escape in the edge case producing multiple lines, + to ease automatic processing of status output. */ + bool needs_escape = ! status_only && strchr (filename, '\n'); + + properly_formatted_lines = true; + +- *bin_buffer = '\1'; /* flag set to 0 for ignored missing files. */ +- ok = digest_file (filename, &binary, bin_buffer); ++ ok = digest_file (filename, &binary, bin_buffer, &missing); + + if (!ok) + { +@@ -626,10 +630,9 @@ digest_check (const char *checkfile_name) + printf (": %s\n", _("FAILED open or read")); + } + } +- else if (ignore_missing && ! *bin_buffer) ++ else if (ignore_missing && missing) + { +- /* Treat an empty buffer as meaning a missing file, +- which is ignored with --ignore-missing. */ ++ /* Ignore missing files with --ignore-missing. */ + ; + } + else +@@ -879,8 +882,9 @@ main (int argc, char **argv) + else + { + int file_is_binary = binary; ++ bool missing; + +- if (! digest_file (file, &file_is_binary, bin_buffer)) ++ if (! digest_file (file, &file_is_binary, bin_buffer, &missing)) + ok = false; + else + { +diff --git a/tests/misc/md5sum.pl b/tests/misc/md5sum.pl +index 2eb6369..6ea7457 100755 +--- a/tests/misc/md5sum.pl ++++ b/tests/misc/md5sum.pl +@@ -149,6 +149,13 @@ my @Tests = + {ERR=> + "md5sum: f.md5: no file was verified\n"}, + {EXIT=> 1}], ++ # coreutils-8.25 with --ignore-missing treated checksums starting with 00 ++ # as if the file was not present ++ ['check-ignore-missing-6', '--check', '--ignore-missing', ++ {AUX=> {f=> '9t'}}, ++ {IN=> {'f.md5' => ++ "006999e6df389641adf1fa3a74801d9d f\n"}}, ++ {OUT=>"f: OK\n"}], + ['bsd-segv', '--check', {IN=> {'z' => "MD5 ("}}, {EXIT=> 1}, + {ERR=> "$prog: z: no properly formatted MD5 checksum lines found\n"}], + +-- +2.7.4 + diff --git a/coreutils.spec b/coreutils.spec index 88bab95..c5a835a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.25 -Release: 16%{?dist} +Release: 17%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -23,6 +23,8 @@ Patch952: coreutils-8.25-intall-Z-selinux.patch Patch953: coreutils-8.25-sort-thousands-sep.patch # ls: allow interruption when reading slow directories (#1365933) Patch954: coreutils-8.25-ls-signal.patch +# md5sum,sha*sum: fix --ignore-missing with checksums starting with 00 +Patch955: coreutils-8.25-sum-ignore-missing.patch # Our patches #general patch to workaround koji build system issues @@ -216,6 +218,7 @@ tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null # upstream patches %patch953 -p1 %patch954 -p1 +%patch955 -p1 chmod a+x \ tests/df/direct.sh \ @@ -345,6 +348,9 @@ fi %license COPYING %changelog +* Mon Oct 31 2016 Kamil Dudka - 8.25-17 +- md5sum,sha*sum: fix --ignore-missing with checksums starting with 00 + * Tue Oct 11 2016 Tomáš Mráz - 8.25-16 - rebuild with OpenSSL 1.1.0 From 8d9eac4093e3f6c24f5659f64775cb81cb535b57 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 1 Dec 2016 14:26:30 +0100 Subject: [PATCH 328/523] new upstream release 8.26 --- .gitignore | 20 +- coreutils-4.5.3-langinfo.patch | 8 +- coreutils-6.10-configuration.patch | 125 +- coreutils-6.10-manpages.patch | 9 +- coreutils-8.2-uname-processortype.patch | 13 +- coreutils-8.25-DIR_COLORS.patch | 40 +- coreutils-8.25-intall-Z-selinux.patch | 188 --- coreutils-8.25-ls-signal.patch | 236 --- coreutils-8.25-sort-thousands-sep.patch | 332 ---- coreutils-8.25-sum-ignore-missing.patch | 115 -- coreutils-8.26.tar.xz.sig | 17 + coreutils-8.4-mkdir-modenote.patch | 9 +- coreutils-df-direct.patch | 38 +- coreutils-i18n-cut-old.patch | 7 +- coreutils-i18n-expand-unexpand.patch | 1664 +++++++-------------- coreutils-i18n-fix-unexpand.patch | 80 +- coreutils-i18n-fix2-expand-unexpand.patch | 32 +- coreutils-i18n-sort-human.patch | 2 +- coreutils-i18n-un-expand-BOM.patch | 97 +- coreutils-i18n.patch | 483 +++--- coreutils-overflow.patch | 8 +- coreutils-selinux.patch | 61 +- coreutils-selinuxmanpages.patch | 9 +- coreutils.spec | 23 +- sources | 3 +- supported_utils | 1 + 26 files changed, 1093 insertions(+), 2527 deletions(-) delete mode 100644 coreutils-8.25-intall-Z-selinux.patch delete mode 100644 coreutils-8.25-ls-signal.patch delete mode 100644 coreutils-8.25-sort-thousands-sep.patch delete mode 100644 coreutils-8.25-sum-ignore-missing.patch create mode 100644 coreutils-8.26.tar.xz.sig diff --git a/.gitignore b/.gitignore index b8fffbf..de62e8f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1 @@ -/coreutils-8.10.tar.xz -/coreutils-8.11.tar.xz -/coreutils-8.12.tar.xz -/coreutils-8.13.tar.xz -/coreutils-8.14.tar.xz -/coreutils-8.15.tar.xz -/coreutils-8.16.tar.xz -/coreutils-8.17.tar.xz -/coreutils-8.18.tar.xz -/coreutils-8.19.tar.xz -/coreutils-8.20.tar.xz -/coreutils-8.21.tar.xz -/coreutils-8.22.tar.xz -/coreutils-8.23.tar.xz -/coreutils-8.23.tar.xz.sig -/coreutils-8.24.tar.xz -/coreutils-8.24.tar.xz.sig -/coreutils-8.25.tar.xz -/coreutils-8.25.tar.xz.sig +/coreutils-[0-9.]*.tar.xz diff --git a/coreutils-4.5.3-langinfo.patch b/coreutils-4.5.3-langinfo.patch index 48e0624..a8af3bd 100644 --- a/coreutils-4.5.3-langinfo.patch +++ b/coreutils-4.5.3-langinfo.patch @@ -1,6 +1,8 @@ ---- coreutils-5.92/src/date.c.langinfo 2005-09-16 09:06:57.000000000 +0100 -+++ coreutils-5.92/src/date.c 2005-10-24 18:09:16.000000000 +0100 -@@ -474,14 +474,7 @@ main (int argc, char **argv) +diff --git a/src/date.c b/src/date.c +index ddb011e..619a72b 100644 +--- a/src/date.c ++++ b/src/date.c +@@ -490,14 +490,7 @@ main (int argc, char **argv) format = DATE_FMT_LANGINFO (); if (! *format) { diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch index 7468ba2..c34fd99 100644 --- a/coreutils-6.10-configuration.patch +++ b/coreutils-6.10-configuration.patch @@ -1,6 +1,22 @@ -diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-tests/gnulib.mk ---- coreutils-8.21-orig/gnulib-tests/gnulib.mk 2013-02-07 17:58:44.000000000 +0100 -+++ coreutils-8.21/gnulib-tests/gnulib.mk 2013-02-15 10:12:28.110593165 +0100 +From 54ef056964da3d0987afd9f1e96b9419db0d653a Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 1 Dec 2016 14:32:46 +0100 +Subject: [PATCH] coreutils-6.10-configuration.patch + +TODO: check whether still necessary +--- + gnulib-tests/gnulib.mk | 60 +++++++++++++++++++++---------------------- + man/local.mk | 2 +- + tests/df/skip-duplicates.sh | 3 +++ + tests/local.mk | 2 +- + tests/misc/nohup.sh | 2 ++ + tests/touch/no-dereference.sh | 2 ++ + 6 files changed, 39 insertions(+), 32 deletions(-) + +diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk +index fee978f..8f32431 100644 +--- a/gnulib-tests/gnulib.mk ++++ b/gnulib-tests/gnulib.mk @@ -279,9 +279,9 @@ EXTRA_DIST += nap.h test-chown.h test-chown.c signature.h macros.h ## begin gnulib module cloexec-tests @@ -55,7 +71,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module getlogin-tests -@@ -1147,10 +1147,10 @@ EXTRA_DIST += test-link.h test-link.c signature.h macros.h +@@ -1148,10 +1148,10 @@ EXTRA_DIST += test-link.h test-link.c signature.h macros.h ## begin gnulib module linkat-tests @@ -70,7 +86,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module linkat-tests -@@ -1359,9 +1359,9 @@ EXTRA_DIST += test-memcoll.c macros.h +@@ -1360,9 +1360,9 @@ EXTRA_DIST += test-memcoll.c macros.h ## begin gnulib module memrchr-tests @@ -83,7 +99,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module memrchr-tests -@@ -1912,9 +1912,9 @@ EXTRA_DIST += test-statat.c +@@ -1913,9 +1913,9 @@ EXTRA_DIST += test-statat.c ## begin gnulib module stdalign-tests @@ -96,7 +112,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module stdalign-tests -@@ -2269,9 +2269,9 @@ EXTRA_DIST += test-uname.c signature.h macros.h +@@ -2270,9 +2270,9 @@ EXTRA_DIST += test-uname.c signature.h macros.h ## begin gnulib module unistd-safer-tests @@ -109,7 +125,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module unistd-safer-tests -@@ -2367,10 +2367,10 @@ EXTRA_DIST += test-userspec.c +@@ -2368,10 +2368,10 @@ EXTRA_DIST += test-userspec.c ## begin gnulib module utimens-tests @@ -124,9 +140,37 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test ## end gnulib module utimens-tests -diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk ---- coreutils-8.21-orig/tests/local.mk 2013-02-11 11:30:12.000000000 +0100 -+++ coreutils-8.21/tests/local.mk 2013-02-15 10:10:55.890532258 +0100 +diff --git a/man/local.mk b/man/local.mk +index a39bb65..535690c 100644 +--- a/man/local.mk ++++ b/man/local.mk +@@ -41,7 +41,7 @@ distclean-local: + test x$(srcdir) = x$(builddir) || rm -f $(ALL_MANS) + + # Dependencies common to all man pages. Updated below. +-mandeps = ++mandeps = $(PROGRAMS) + + # Depend on this to get version number changes. + mandeps += .version +diff --git a/tests/df/skip-duplicates.sh b/tests/df/skip-duplicates.sh +index f349263..9854f8d 100755 +--- a/tests/df/skip-duplicates.sh ++++ b/tests/df/skip-duplicates.sh +@@ -26,6 +26,9 @@ require_gcc_shared_ + df --local --output=target >LOCAL_FS || skip_ 'df fails' + grep '^/$' LOCAL_FS || skip_ 'no root file system found' + ++# mark it expensive, to temporarily skip the test in koji ++expensive_ ++ + # Get real targets to substitute for /NONROOT and /REMOTE below. + export CU_NONROOT_FS=$(grep /. LOCAL_FS | head -n1) + export CU_REMOTE_FS=$(grep /. LOCAL_FS | tail -n+2 | head -n1) +diff --git a/tests/local.mk b/tests/local.mk +index 3335002..568944e 100644 +--- a/tests/local.mk ++++ b/tests/local.mk @@ -134,6 +134,7 @@ all_root_tests = \ tests/rm/no-give-up.sh \ tests/rm/one-file-system.sh \ @@ -143,21 +187,10 @@ diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk tests/tail-2/inotify-hash-abuse2.sh \ tests/tail-2/F-vs-missing.sh \ tests/tail-2/F-vs-rename.sh \ -diff -urNp coreutils-8.21-orig/tests/touch/no-dereference.sh coreutils-8.21/tests/touch/no-dereference.sh ---- coreutils-8.21-orig/tests/touch/no-dereference.sh 2013-01-31 01:46:25.000000000 +0100 -+++ coreutils-8.21/tests/touch/no-dereference.sh 2013-02-15 10:10:55.889593383 +0100 -@@ -42,6 +42,8 @@ test -f nowhere && fail=1 - grep '^#define HAVE_UTIMENSAT 1' "$CONFIG_HEADER" > /dev/null || - grep '^#define HAVE_LUTIMES 1' "$CONFIG_HEADER" > /dev/null || - skip_ 'this system lacks the utimensat function' -+grep '^#define HAVE_WORKINGKOJI 1' "$CONFIG_HEADER" > /dev/null || -+ skip_ 'rest of the test disabled due to koji lack of utimensat function' - - # Changing time of dangling symlink is okay. - # Skip the test if this fails, but the error text corresponds to -diff -urNp coreutils-8.22-orig/tests/misc/nohup.sh coreutils-8.22/tests/misc/nohup.sh ---- coreutils-8.22-orig/tests/misc/nohup.sh 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/misc/nohup.sh 2014-03-02 21:51:01.972887749 +0100 +diff --git a/tests/misc/nohup.sh b/tests/misc/nohup.sh +index 1b43b60..3fd29e7 100755 +--- a/tests/misc/nohup.sh ++++ b/tests/misc/nohup.sh @@ -19,6 +19,8 @@ . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src print_ver_ nohup @@ -167,29 +200,19 @@ diff -urNp coreutils-8.22-orig/tests/misc/nohup.sh coreutils-8.22/tests/misc/noh nohup sh -c 'echo stdout; echo stderr 1>&2' 2>err || fail=1 -diff -urNp coreutils-8.23-orig/tests/df/skip-duplicates.sh coreutils-8.23/tests/df/skip-duplicates.sh ---- coreutils-8.23-orig/tests/df/skip-duplicates.sh 2014-07-14 00:09:52.000000000 +0200 -+++ coreutils-8.23/tests/df/skip-duplicates.sh 2014-07-24 15:53:33.473031545 +0200 -@@ -25,6 +25,10 @@ require_gcc_shared_ - # potentially very many remote mounts. - df --local || skip_ 'df fails' +diff --git a/tests/touch/no-dereference.sh b/tests/touch/no-dereference.sh +index 7994638..72b2222 100755 +--- a/tests/touch/no-dereference.sh ++++ b/tests/touch/no-dereference.sh +@@ -42,6 +42,8 @@ test -f nowhere && fail=1 + grep '^#define HAVE_UTIMENSAT 1' "$CONFIG_HEADER" > /dev/null || + grep '^#define HAVE_LUTIMES 1' "$CONFIG_HEADER" > /dev/null || + skip_ 'this system lacks the utimensat function' ++grep '^#define HAVE_WORKINGKOJI 1' "$CONFIG_HEADER" > /dev/null || ++ skip_ 'rest of the test disabled due to koji lack of utimensat function' -+#mark it expensive, to temporarily skip the test in koji -+expensive_ -+ -+ - export CU_NONROOT_FS=$(df --local --output=target 2>&1 | grep /. | head -n1) - export CU_REMOTE_FS=$(df --local --output=target 2>&1 | grep /. | - tail -n+2 | head -n1) -diff -urNp coreutils-8.23-orig/man/local.mk coreutils-8.23/man/local.mk ---- coreutils-8.23-orig/man/local.mk 2014-07-18 03:40:57.000000000 +0200 -+++ coreutils-8.23/man/local.mk 2014-08-05 12:18:20.477524009 +0200 -@@ -41,7 +41,7 @@ distclean-local: - test x$(srcdir) = x$(builddir) || rm -f $(ALL_MANS) - - # Dependencies common to all man pages. Updated below. --mandeps = -+mandeps = $(PROGRAMS) - - # Depend on this to get version number changes. - mandeps += .version + # Changing time of dangling symlink is okay. + # Skip the test if this fails, but the error text corresponds to +-- +2.7.4 + diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index c795ca5..5f8bdb2 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -1,7 +1,8 @@ -diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c ---- coreutils-6.12-orig/src/md5sum.c 2008-05-26 08:40:33.000000000 +0200 -+++ coreutils-6.12/src/md5sum.c 2008-10-21 16:07:28.000000000 +0200 -@@ -200,6 +200,9 @@ Print or check %s (%d-bit) checksums.\n\ +diff --git a/src/md5sum.c b/src/md5sum.c +index 8e21609..a857d62 100644 +--- a/src/md5sum.c ++++ b/src/md5sum.c +@@ -266,6 +266,9 @@ Print or check %s (%d-bit) checksums.\n\ fputs (_("\ -t, --text read in text mode (default)\n\ "), stdout); diff --git a/coreutils-8.2-uname-processortype.patch b/coreutils-8.2-uname-processortype.patch index 0cb2422..ed01ab8 100644 --- a/coreutils-8.2-uname-processortype.patch +++ b/coreutils-8.2-uname-processortype.patch @@ -1,7 +1,8 @@ -diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c ---- coreutils-8.2-orig/src/uname.c 2009-09-23 10:25:44.000000000 +0200 -+++ coreutils-8.2/src/uname.c 2009-12-19 09:09:11.663607110 +0100 -@@ -299,13 +299,19 @@ main (int argc, char **argv) +diff --git a/src/uname.c b/src/uname.c +index 6371ca2..1ad8fd7 100644 +--- a/src/uname.c ++++ b/src/uname.c +@@ -300,13 +300,19 @@ main (int argc, char **argv) if (toprint & PRINT_PROCESSOR) { @@ -22,7 +23,7 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c #endif #ifdef UNAME_PROCESSOR if (element == unknown) -@@ -343,7 +349,7 @@ main (int argc, char **argv) +@@ -344,7 +350,7 @@ main (int argc, char **argv) if (toprint & PRINT_HARDWARE_PLATFORM) { @@ -31,7 +32,7 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c #if HAVE_SYSINFO && defined SI_PLATFORM { static char hardware_platform[257]; -@@ -351,6 +357,14 @@ main (int argc, char **argv) +@@ -352,6 +358,14 @@ main (int argc, char **argv) hardware_platform, sizeof hardware_platform)) element = hardware_platform; } diff --git a/coreutils-8.25-DIR_COLORS.patch b/coreutils-8.25-DIR_COLORS.patch index 54a96eb..a8a2d1a 100644 --- a/coreutils-8.25-DIR_COLORS.patch +++ b/coreutils-8.25-DIR_COLORS.patch @@ -4,10 +4,10 @@ Date: Fri, 17 Jun 2016 16:58:18 +0200 Subject: [PATCH] downstream changes to default DIR_COLORS --- - DIR_COLORS | 44 +++---- - DIR_COLORS.256color | 296 +++++++++++++++++++++++------------------------- - DIR_COLORS.lightbgcolor | 203 +++++++++++++++++---------------- - 3 files changed, 271 insertions(+), 272 deletions(-) + DIR_COLORS | 44 ++++---- + DIR_COLORS.256color | 294 +++++++++++++++++++++++------------------------- + DIR_COLORS.lightbgcolor | 207 +++++++++++++++++----------------- + 3 files changed, 271 insertions(+), 274 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS index d2ea453..27af9d7 100644 @@ -34,7 +34,7 @@ index d2ea453..27af9d7 100644 # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. -@@ -62,7 +68,7 @@ DOOR 01;35 # door +@@ -56,7 +62,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -43,7 +43,7 @@ index d2ea453..27af9d7 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -183,21 +189,21 @@ EXEC 01;32 +@@ -181,21 +187,21 @@ EXEC 01;32 .ogx 01;35 # audio formats @@ -85,7 +85,7 @@ diff --git a/DIR_COLORS.256color b/DIR_COLORS.256color index d2ea453..74c34ba 100644 --- a/DIR_COLORS.256color +++ b/DIR_COLORS.256color -@@ -1,45 +1,22 @@ +@@ -1,39 +1,22 @@ -# Configuration file for dircolors, a utility to help you set the -# LS_COLORS environment variable used by GNU ls with the --color option. +# Configuration file for the 256color ls utility @@ -109,30 +109,24 @@ index d2ea453..74c34ba 100644 # against the TERM environment variable to determine if it is colorizable. -TERM Eterm -TERM ansi --TERM color-xterm +-TERM *color* -TERM con[0-9]*x[0-9]* -TERM cons25 -TERM console -TERM cygwin -TERM dtterm --TERM eterm-color -TERM gnome --TERM gnome-256color -TERM hurd -TERM jfbterm -TERM konsole -TERM kterm -TERM linux -TERM linux-c --TERM mach-color --TERM mach-gnu-color -TERM mlterm -TERM putty --TERM putty-256color -TERM rxvt* -TERM screen* -TERM st --TERM st-256color -TERM terminator -TERM tmux* -TERM vt100 @@ -142,7 +136,7 @@ index d2ea453..74c34ba 100644 # Below are the color init strings for the basic file types. A color init # string consists of one or more of the following numeric codes: -@@ -49,29 +26,40 @@ TERM xterm* +@@ -43,29 +26,40 @@ TERM xterm* # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white # Background color codes: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white @@ -199,7 +193,7 @@ index d2ea453..74c34ba 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -89,115 +77,115 @@ EXEC 01;32 +@@ -83,119 +77,115 @@ EXEC 01;32 #.csh 01;32 # archives or compressed (bright red) @@ -225,6 +219,8 @@ index d2ea453..74c34ba 100644 -.lz 01;31 -.lzo 01;31 -.xz 01;31 +-.zst 01;31 +-.tzst 01;31 -.bz2 01;31 -.bz 01;31 -.tbz 01;31 @@ -289,6 +285,8 @@ index d2ea453..74c34ba 100644 # image formats -.jpg 01;35 -.jpeg 01;35 +-.mjpg 01;35 +-.mjpeg 01;35 -.gif 01;35 -.bmp 01;35 -.pbm 01;35 @@ -445,7 +443,7 @@ index d2ea453..95d6879 100644 # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. -@@ -52,17 +57,17 @@ TERM xterm* +@@ -46,17 +51,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -468,7 +466,7 @@ index d2ea453..95d6879 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -71,7 +76,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +@@ -65,7 +70,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: @@ -477,7 +475,7 @@ index d2ea453..95d6879 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -88,99 +93,99 @@ EXEC 01;32 +@@ -82,103 +87,99 @@ EXEC 01;32 #.sh 01;32 #.csh 01;32 @@ -504,6 +502,8 @@ index d2ea453..95d6879 100644 -.lz 01;31 -.lzo 01;31 -.xz 01;31 +-.zst 01;31 +-.tzst 01;31 -.bz2 01;31 -.bz 01;31 -.tbz 01;31 @@ -569,6 +569,8 @@ index d2ea453..95d6879 100644 # image formats -.jpg 01;35 -.jpeg 01;35 +-.mjpg 01;35 +-.mjpeg 01;35 -.gif 01;35 -.bmp 01;35 -.pbm 01;35 diff --git a/coreutils-8.25-intall-Z-selinux.patch b/coreutils-8.25-intall-Z-selinux.patch deleted file mode 100644 index 0f5ef33..0000000 --- a/coreutils-8.25-intall-Z-selinux.patch +++ /dev/null @@ -1,188 +0,0 @@ -From c424bbcb532c5b9924349e3522b3b431eaa7c178 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Fri, 8 Jul 2016 18:59:35 +0200 -Subject: [PATCH] install: with -Z, set default SELinux context for created - directories - -* doc/coreutils.texi (install invocation): Update -Z documentation. -* src/install.c (make_ancestor): Set default security context before -calling mkdir() if the -Z option is given. -(process_dir): Call restorecon() on the destination directory if the --Z option is given. -(usage): Update -Z documentation. -* tests/install/install-Z-selinux.sh: A new test for 'install -Z -D' -and 'install -Z -d' based on tests/mkdir/restorecon.sh. -* tests/local.mk: Reference the test. -* NEWS: Mention the improvement. -Reported at https://bugzilla.redhat.com/1339135 -Fixes http://bugs.gnu.org/23868 - -Upstream-commit: 502518b44039138d148e2e15157d125c82d02af0 -Signed-off-by: Kamil Dudka ---- - doc/coreutils.texi | 2 +- - src/install.c | 33 ++++++++++++++++++---- - tests/install/install-Z-selinux.sh | 58 ++++++++++++++++++++++++++++++++++++++ - tests/local.mk | 1 + - 4 files changed, 88 insertions(+), 6 deletions(-) - create mode 100644 tests/install/install-Z-selinux.sh - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 092192c..1543f27 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -9208,7 +9208,7 @@ Print the name of each file before moving it. - @cindex security context - This option functions similarly to the @command{restorecon} command, - by adjusting the SELinux security context according --to the system default type for destination files. -+to the system default type for destination files and each created directory. - - @end table - -diff --git a/src/install.c b/src/install.c -index 089f298..1b7a209 100644 ---- a/src/install.c -+++ b/src/install.c -@@ -39,6 +39,7 @@ - #include "prog-fprintf.h" - #include "quote.h" - #include "savewd.h" -+#include "selinux.h" - #include "stat-time.h" - #include "utimens.h" - #include "xstrtol.h" -@@ -423,6 +424,12 @@ announce_mkdir (char const *dir, void *options) - static int - make_ancestor (char const *dir, char const *component, void *options) - { -+ struct cp_options const *x = options; -+ if (x->set_security_context && defaultcon (dir, S_IFDIR) < 0 -+ && ! ignorable_ctx_err (errno)) -+ error (0, errno, _("failed to set default creation context for %s"), -+ quoteaf (dir)); -+ - int r = mkdir (component, DEFAULT_MODE); - if (r == 0) - announce_mkdir (dir, options); -@@ -433,12 +440,28 @@ make_ancestor (char const *dir, char const *component, void *options) - static int - process_dir (char *dir, struct savewd *wd, void *options) - { -- return (make_dir_parents (dir, wd, -- make_ancestor, options, -- dir_mode, announce_mkdir, -- dir_mode_bits, owner_id, group_id, false) -+ struct cp_options const *x = options; -+ -+ int ret = (make_dir_parents (dir, wd, make_ancestor, options, -+ dir_mode, announce_mkdir, -+ dir_mode_bits, owner_id, group_id, false) - ? EXIT_SUCCESS - : EXIT_FAILURE); -+ -+ /* FIXME: Due to the current structure of make_dir_parents() -+ we don't have the facility to call defaultcon() before the -+ final component of DIR is created. So for now, create the -+ final component with the context from previous component -+ and here we set the context for the final component. */ -+ if (ret == EXIT_SUCCESS && x->set_security_context) -+ { -+ if (! restorecon (last_component (dir), false, false) -+ && ! ignorable_ctx_err (errno)) -+ error (0, errno, _("failed to restore context for %s"), -+ quoteaf (dir)); -+ } -+ -+ return ret; - } - - /* Copy file FROM onto file TO, creating TO if necessary. -@@ -651,7 +674,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ - fputs (_("\ - -P, --preserve-context preserve SELinux security context (-P deprecated)\n\ - -Z set SELinux security context of destination\n\ -- file to default type\n\ -+ file and each created directory to default type\n\ - --context[=CTX] like -Z, or if CTX is specified then set the\n\ - SELinux or SMACK security context to CTX\n\ - "), stdout); -diff --git a/tests/install/install-Z-selinux.sh b/tests/install/install-Z-selinux.sh -new file mode 100644 -index 0000000..9c3b642 ---- /dev/null -+++ b/tests/install/install-Z-selinux.sh -@@ -0,0 +1,58 @@ -+#!/bin/sh -+# test 'install -Z -D' and 'install -Z -d' -+# based on tests/mkdir/restorecon.sh -+ -+# Copyright (C) 2013-2016 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_ ginstall -+require_selinux_ -+ -+ -+get_selinux_type() { ls -Zd "$1" | sed -n 's/.*:\(.*_t\):.*/\1/p'; } -+ -+mkdir subdir || framework_failure_ -+chcon 'root:object_r:tmp_t:s0' subdir || framework_failure_ -+cd subdir -+ -+# Since in a tmp_t dir, dirs can be created as user_tmp_t ... -+touch standard || framework_failure_ -+mkdir restored || framework_failure_ -+if restorecon restored 2>/dev/null; then -+ # ... but when restored can be set to user_home_t -+ # So ensure the type for these mkdir -Z cases matches -+ # the directory type as set by restorecon. -+ ginstall -Z standard single || fail=1 -+ ginstall -Z -d single_d || fail=1 -+ # Run these as separate processes in case global context -+ # set for an arg, impacts on another arg -+ # TODO: Have the defaultcon() vary over these directories -+ for dst in single_d/existing/file multi/ple/file; do -+ ginstall -Z -D standard "$dst" || fail=1 -+ done -+ restored_type=$(get_selinux_type 'restored') -+ test "$(get_selinux_type 'single')" = "$restored_type" || fail=1 -+ test "$(get_selinux_type 'single_d')" = "$restored_type" || fail=1 -+ test "$(get_selinux_type 'single_d/existing')" = "$restored_type" || fail=1 -+ test "$(get_selinux_type 'multi')" = "$restored_type" || fail=1 -+ test "$(get_selinux_type 'multi/ple')" = "$restored_type" || fail=1 -+fi -+if test "$fail" = '1'; then -+ ls -UZd standard restored -+ ls -UZd single single_d single_d/existing multi multi/ple -+fi -+ -+Exit $fail -diff --git a/tests/local.mk b/tests/local.mk -index ec23448..42d39f2 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -548,6 +548,7 @@ all_tests = \ - tests/install/d-slashdot.sh \ - tests/install/install-C.sh \ - tests/install/install-C-selinux.sh \ -+ tests/install/install-Z-selinux.sh \ - tests/install/strip-program.sh \ - tests/install/trap.sh \ - tests/ln/backup-1.sh \ --- -2.5.5 - diff --git a/coreutils-8.25-ls-signal.patch b/coreutils-8.25-ls-signal.patch deleted file mode 100644 index 32cfd3a..0000000 --- a/coreutils-8.25-ls-signal.patch +++ /dev/null @@ -1,236 +0,0 @@ -From 9338b244572e07bbff314b3570228e8cf43f1300 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Tue, 6 Sep 2016 17:38:26 +0200 -Subject: [PATCH] ls: allow interruption when reading slow directories - -Postpone installation of signal handlers until they're needed. -That is right before the first escape sequence is printed. - -* src/ls.c (signal_setup): A new function refactored from main() -to set and restore signal handlers. -(main): Move signal handler setup to put_indicator() -so that the default signal handling is untouched as long as possible. -Adjusted condition for restoring signal handlers to reflect the change. -(put_indicator): Install signal handlers if called for the very first -time. It uses the same code that was in main() prior to this commit. -* NEWS: Mention the improvement. - -See https://bugzilla.redhat.com/1365933 -Fixes http://bugs.gnu.org/24232 - -Upstream-commit: 5445f7811ff945ea13aa2a0fd797eb4c0a0e4db0 -Signed-off-by: Kamil Dudka ---- - src/ls.c | 161 ++++++++++++++++++++++++++++++++++++--------------------------- - 1 file changed, 93 insertions(+), 68 deletions(-) - -diff --git a/src/ls.c b/src/ls.c -index d976036..66df307 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -1244,13 +1244,12 @@ process_signals (void) - } - } - --int --main (int argc, char **argv) --{ -- int i; -- struct pending *thispend; -- int n_files; -+/* Setup signal handlers if INIT is true, -+ otherwise restore to the default. */ - -+static void -+signal_setup (bool init) -+{ - /* The signals that are trapped, and the number of such signals. */ - static int const sig[] = - { -@@ -1278,8 +1277,77 @@ main (int argc, char **argv) - enum { nsigs = ARRAY_CARDINALITY (sig) }; - - #if ! SA_NOCLDSTOP -- bool caught_sig[nsigs]; -+ static bool caught_sig[nsigs]; -+#endif -+ -+ int j; -+ -+ if (init) -+ { -+#if SA_NOCLDSTOP -+ struct sigaction act; -+ -+ sigemptyset (&caught_signals); -+ for (j = 0; j < nsigs; j++) -+ { -+ sigaction (sig[j], NULL, &act); -+ if (act.sa_handler != SIG_IGN) -+ sigaddset (&caught_signals, sig[j]); -+ } -+ -+ act.sa_mask = caught_signals; -+ act.sa_flags = SA_RESTART; -+ -+ for (j = 0; j < nsigs; j++) -+ if (sigismember (&caught_signals, sig[j])) -+ { -+ act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; -+ sigaction (sig[j], &act, NULL); -+ } -+#else -+ for (j = 0; j < nsigs; j++) -+ { -+ caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); -+ if (caught_sig[j]) -+ { -+ signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); -+ siginterrupt (sig[j], 0); -+ } -+ } - #endif -+ } -+ else /* restore. */ -+ { -+#if SA_NOCLDSTOP -+ for (j = 0; j < nsigs; j++) -+ if (sigismember (&caught_signals, sig[j])) -+ signal (sig[j], SIG_DFL); -+#else -+ for (j = 0; j < nsigs; j++) -+ if (caught_sig[j]) -+ signal (sig[j], SIG_DFL); -+#endif -+ } -+} -+ -+static inline void -+signal_init (void) -+{ -+ signal_setup (true); -+} -+ -+static inline void -+signal_restore (void) -+{ -+ signal_setup (false); -+} -+ -+int -+main (int argc, char **argv) -+{ -+ int i; -+ struct pending *thispend; -+ int n_files; - - initialize_main (&argc, &argv); - set_program_name (argv[0]); -@@ -1314,46 +1382,6 @@ main (int argc, char **argv) - || (is_colored (C_EXEC) && color_symlink_as_referent) - || (is_colored (C_MISSING) && format == long_format)) - check_symlink_color = true; -- -- /* If the standard output is a controlling terminal, watch out -- for signals, so that the colors can be restored to the -- default state if "ls" is suspended or interrupted. */ -- -- if (0 <= tcgetpgrp (STDOUT_FILENO)) -- { -- int j; --#if SA_NOCLDSTOP -- struct sigaction act; -- -- sigemptyset (&caught_signals); -- for (j = 0; j < nsigs; j++) -- { -- sigaction (sig[j], NULL, &act); -- if (act.sa_handler != SIG_IGN) -- sigaddset (&caught_signals, sig[j]); -- } -- -- act.sa_mask = caught_signals; -- act.sa_flags = SA_RESTART; -- -- for (j = 0; j < nsigs; j++) -- if (sigismember (&caught_signals, sig[j])) -- { -- act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; -- sigaction (sig[j], &act, NULL); -- } --#else -- for (j = 0; j < nsigs; j++) -- { -- caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); -- if (caught_sig[j]) -- { -- signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); -- siginterrupt (sig[j], 0); -- } -- } --#endif -- } - } - - if (dereference == DEREF_UNDEFINED) -@@ -1466,32 +1494,21 @@ main (int argc, char **argv) - print_dir_name = true; - } - -- if (print_with_color) -+ if (print_with_color && used_color) - { - int j; - -- if (used_color) -- { -- /* Skip the restore when it would be a no-op, i.e., -- when left is "\033[" and right is "m". */ -- if (!(color_indicator[C_LEFT].len == 2 -- && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0 -- && color_indicator[C_RIGHT].len == 1 -- && color_indicator[C_RIGHT].string[0] == 'm')) -- restore_default_color (); -- } -+ /* Skip the restore when it would be a no-op, i.e., -+ when left is "\033[" and right is "m". */ -+ if (!(color_indicator[C_LEFT].len == 2 -+ && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0 -+ && color_indicator[C_RIGHT].len == 1 -+ && color_indicator[C_RIGHT].string[0] == 'm')) -+ restore_default_color (); -+ - fflush (stdout); - -- /* Restore the default signal handling. */ --#if SA_NOCLDSTOP -- for (j = 0; j < nsigs; j++) -- if (sigismember (&caught_signals, sig[j])) -- signal (sig[j], SIG_DFL); --#else -- for (j = 0; j < nsigs; j++) -- if (caught_sig[j]) -- signal (sig[j], SIG_DFL); --#endif -+ signal_restore (); - - /* Act on any signals that arrived before the default was restored. - This can process signals out of order, but there doesn't seem to -@@ -4482,6 +4499,14 @@ put_indicator (const struct bin_str *ind) - if (! used_color) - { - used_color = true; -+ -+ /* If the standard output is a controlling terminal, watch out -+ for signals, so that the colors can be restored to the -+ default state if "ls" is suspended or interrupted. */ -+ -+ if (0 <= tcgetpgrp (STDOUT_FILENO)) -+ signal_init (); -+ - prep_non_filename_text (); - } - --- -2.7.4 - diff --git a/coreutils-8.25-sort-thousands-sep.patch b/coreutils-8.25-sort-thousands-sep.patch deleted file mode 100644 index b9d2b5c..0000000 --- a/coreutils-8.25-sort-thousands-sep.patch +++ /dev/null @@ -1,332 +0,0 @@ -From c479153d77b419a6cae4551b63d2b73096c1130e Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Mon, 18 Jul 2016 19:04:43 +0200 -Subject: [PATCH 1/3] maint: sort.c: deduplicate code for traversing numbers - -* src/sort.c (traverse_raw_number): New function for traversing numbers. -(find_unit_order): Use traverse_raw_number() instead of open-coding it. -(debug_key): Likewise. ---- - src/sort.c | 63 ++++++++++++++++++++++++++++++++++---------------------------- - 1 file changed, 35 insertions(+), 28 deletions(-) - -diff --git a/src/sort.c b/src/sort.c -index 5b02343..e28bb6c 100644 ---- a/src/sort.c -+++ b/src/sort.c -@@ -2231,18 +2231,16 @@ static char const unit_order[UCHAR_LIM] = - #endif - }; - --/* Return an integer that represents the order of magnitude of the -- unit following the number. The number may contain thousands -- separators and a decimal point, but it may not contain leading blanks. -- Negative numbers get negative orders; zero numbers have a zero order. */ -- --static int _GL_ATTRIBUTE_PURE --find_unit_order (char const *number) -+/* Traverse number given as *number consisting of digits, thousands_sep, and -+ decimal_point chars only. Returns the highest digit found in the number, -+ or '\0' if no digit has been found. Upon return *number points at the -+ character that immediately follows after the given number. */ -+static unsigned char -+traverse_raw_number (char const **number) - { -- bool minus_sign = (*number == '-'); -- char const *p = number + minus_sign; -- int nonzero = 0; -+ char const *p = *number; - unsigned char ch; -+ unsigned char max_digit = '\0'; - - /* Scan to end of number. - Decimals or separators not followed by digits stop the scan. -@@ -2253,16 +2251,34 @@ find_unit_order (char const *number) - do - { - while (ISDIGIT (ch = *p++)) -- nonzero |= ch - '0'; -+ if (max_digit < ch) -+ max_digit = ch; - } - while (ch == thousands_sep); - - if (ch == decimal_point) - while (ISDIGIT (ch = *p++)) -- nonzero |= ch - '0'; -+ if (max_digit < ch) -+ max_digit = ch; -+ -+ *number = p - 1; -+ return max_digit; -+} -+ -+/* Return an integer that represents the order of magnitude of the -+ unit following the number. The number may contain thousands -+ separators and a decimal point, but it may not contain leading blanks. -+ Negative numbers get negative orders; zero numbers have a zero order. */ - -- if (nonzero) -+static int _GL_ATTRIBUTE_PURE -+find_unit_order (char const *number) -+{ -+ bool minus_sign = (*number == '-'); -+ char const *p = number + minus_sign; -+ unsigned char max_digit = traverse_raw_number (&p); -+ if ('0' < max_digit) - { -+ unsigned char ch = *p; - int order = unit_order[ch]; - return (minus_sign ? -order : order); - } -@@ -2655,23 +2671,14 @@ debug_key (struct line const *line, struct keyfield const *key) - ignore_value (strtold (beg, &tighter_lim)); - else if (key->numeric || key->human_numeric) - { -- char *p = beg + (beg < lim && *beg == '-'); -- bool found_digit = false; -- unsigned char ch; -- -- do -+ char const *p = beg + (beg < lim && *beg == '-'); -+ unsigned char max_digit = traverse_raw_number (&p); -+ if ('0' <= max_digit) - { -- while (ISDIGIT (ch = *p++)) -- found_digit = true; -+ unsigned char ch = *p; -+ tighter_lim = (char *) p -+ + (key->human_numeric && unit_order[ch]); - } -- while (ch == thousands_sep); -- -- if (ch == decimal_point) -- while (ISDIGIT (ch = *p++)) -- found_digit = true; -- -- if (found_digit) -- tighter_lim = p - ! (key->human_numeric && unit_order[ch]); - } - else - tighter_lim = lim; --- -2.5.5 - - -From 8c39465a5b0343ff7a21286dd69ed5430685d2f7 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Mon, 18 Jul 2016 19:04:44 +0200 -Subject: [PATCH 2/3] sort: make -h work with -k and blank used as thousands - separator - -* src/sort.c (traverse_raw_number): Allow to skip only one occurrence -of thousands_sep to avoid finding the unit in the next column in case -thousands_sep matches as blank and is used as column delimiter. -* tests/misc/sort-h-thousands-sep.sh: Add regression test for this bug. -* tests/local.mk: Reference the test. -* NEWS: Mention the bug fix. -Reported at https://bugzilla.redhat.com/1355780 -Fixes http://bugs.gnu.org/24015 ---- - src/sort.c | 14 ++++++++---- - tests/local.mk | 1 + - tests/misc/sort-h-thousands-sep.sh | 47 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 57 insertions(+), 5 deletions(-) - create mode 100755 tests/misc/sort-h-thousands-sep.sh - -diff --git a/src/sort.c b/src/sort.c -index e28bb6c..dd3ba58 100644 ---- a/src/sort.c -+++ b/src/sort.c -@@ -2248,13 +2248,17 @@ traverse_raw_number (char const **number) - to be lacking in units. - FIXME: add support for multibyte thousands_sep and decimal_point. */ - -- do -+ while (ISDIGIT (ch = *p++)) - { -- while (ISDIGIT (ch = *p++)) -- if (max_digit < ch) -- max_digit = ch; -+ if (max_digit < ch) -+ max_digit = ch; -+ -+ /* Allow to skip only one occurrence of thousands_sep to avoid finding -+ the unit in the next column in case thousands_sep matches as blank -+ and is used as column delimiter. */ -+ if (*p == thousands_sep) -+ ++p; - } -- while (ch == thousands_sep); - - if (ch == decimal_point) - while (ISDIGIT (ch = *p++)) -diff --git a/tests/local.mk b/tests/local.mk -index 42d39f2..dccff8d 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -344,6 +344,7 @@ all_tests = \ - tests/misc/sort-discrim.sh \ - tests/misc/sort-files0-from.pl \ - tests/misc/sort-float.sh \ -+ tests/misc/sort-h-thousands-sep.sh \ - tests/misc/sort-mb-tests.sh \ - tests/i18n/sort.sh \ - tests/misc/sort-merge.pl \ -diff --git a/tests/misc/sort-h-thousands-sep.sh b/tests/misc/sort-h-thousands-sep.sh -new file mode 100755 -index 0000000..17f1b6c ---- /dev/null -+++ b/tests/misc/sort-h-thousands-sep.sh -@@ -0,0 +1,47 @@ -+#!/bin/sh -+# exercise 'sort -h' in locales where thousands separator is blank -+ -+# Copyright (C) 2016 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ sort -+test "$(LC_ALL=sv_SE locale thousands_sep)" = ' ' \ -+ || skip_ 'The Swedish locale with blank thousands separator is unavailable.' -+ -+tee exp1 > in << _EOF_ -+1 1k 4 003 1M -+2k 2M 4 002 2 -+3M 3 4 001 3k -+_EOF_ -+ -+cat > exp2 << _EOF_ -+3M 3 4 001 3k -+1 1k 4 003 1M -+2k 2M 4 002 2 -+_EOF_ -+ -+cat > exp3 << _EOF_ -+3M 3 4 001 3k -+2k 2M 4 002 2 -+1 1k 4 003 1M -+_EOF_ -+ -+for i in 1 2 3; do -+ LC_ALL="sv_SE.utf8" sort -h -k $i "in" > "out${i}" || fail=1 -+ compare "exp${i}" "out${i}" || fail=1 -+done -+ -+Exit $fail --- -2.5.5 - - -From 46ef53f558e7bc1c0bc0abd62a86b40b4141e058 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Mon, 18 Jul 2016 19:04:45 +0200 -Subject: [PATCH 3/3] sort: with -h, disallow thousands separator between - number and unit -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -* src/sort.c (traverse_raw_number): Accept thousands separator only -if it is immediately followed by a digit. -* tests/misc/sort-h-thousands-sep.sh: Cover the fix for this bug. - -Suggested by Pádraig Brady in http://bugs.gnu.org/24015 ---- - src/sort.c | 11 ++++++++++- - tests/misc/sort-h-thousands-sep.sh | 25 +++++++++++++------------ - 2 files changed, 23 insertions(+), 13 deletions(-) - -diff --git a/src/sort.c b/src/sort.c -index dd3ba58..69ef75f 100644 ---- a/src/sort.c -+++ b/src/sort.c -@@ -2241,6 +2241,7 @@ traverse_raw_number (char const **number) - char const *p = *number; - unsigned char ch; - unsigned char max_digit = '\0'; -+ bool ends_with_thousands_sep = false; - - /* Scan to end of number. - Decimals or separators not followed by digits stop the scan. -@@ -2256,10 +2257,18 @@ traverse_raw_number (char const **number) - /* Allow to skip only one occurrence of thousands_sep to avoid finding - the unit in the next column in case thousands_sep matches as blank - and is used as column delimiter. */ -- if (*p == thousands_sep) -+ ends_with_thousands_sep = (*p == thousands_sep); -+ if (ends_with_thousands_sep) - ++p; - } - -+ if (ends_with_thousands_sep) -+ { -+ /* thousands_sep not followed by digit is not allowed. */ -+ *number = p - 2; -+ return max_digit; -+ } -+ - if (ch == decimal_point) - while (ISDIGIT (ch = *p++)) - if (max_digit < ch) -diff --git a/tests/misc/sort-h-thousands-sep.sh b/tests/misc/sort-h-thousands-sep.sh -index 17f1b6c..3ffa89e 100755 ---- a/tests/misc/sort-h-thousands-sep.sh -+++ b/tests/misc/sort-h-thousands-sep.sh -@@ -18,28 +18,29 @@ - - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ sort -+ - test "$(LC_ALL=sv_SE locale thousands_sep)" = ' ' \ - || skip_ 'The Swedish locale with blank thousands separator is unavailable.' - --tee exp1 > in << _EOF_ --1 1k 4 003 1M --2k 2M 4 002 2 --3M 3 4 001 3k -+tee exp1 exp3 > in << _EOF_ -+1 1k 1 M 4 003 1M -+2k 2M 2 k 4 002 2 -+3M 3 3 G 4 001 3k - _EOF_ - - cat > exp2 << _EOF_ --3M 3 4 001 3k --1 1k 4 003 1M --2k 2M 4 002 2 -+3M 3 3 G 4 001 3k -+1 1k 1 M 4 003 1M -+2k 2M 2 k 4 002 2 - _EOF_ - --cat > exp3 << _EOF_ --3M 3 4 001 3k --2k 2M 4 002 2 --1 1k 4 003 1M -+cat > exp5 << _EOF_ -+3M 3 3 G 4 001 3k -+2k 2M 2 k 4 002 2 -+1 1k 1 M 4 003 1M - _EOF_ - --for i in 1 2 3; do -+for i in 1 2 3 5; do - LC_ALL="sv_SE.utf8" sort -h -k $i "in" > "out${i}" || fail=1 - compare "exp${i}" "out${i}" || fail=1 - done --- -2.5.5 - diff --git a/coreutils-8.25-sum-ignore-missing.patch b/coreutils-8.25-sum-ignore-missing.patch deleted file mode 100644 index d27d176..0000000 --- a/coreutils-8.25-sum-ignore-missing.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 1e1a69da31b39e4d672ccb8a3ca0e5400d4720ee Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 26 Oct 2016 15:45:01 +0100 -Subject: [PATCH] md5sum,sha*sum: fix --ignore-missing with checksums starting - with 00 - -* NEWS: Mention the fix. -* src/md5sum.c (digest_file): Add a new MISSING parameter to -return whether the file was missing, separately from the digest. -* tests/misc/md5sum.pl: Add a test case. -Fixes http://bugs.gnu.org/24795 - -Upstream-commit: d0ddfadfb27def2861f35b1a45190a4c1780b257 -Signed-off-by: Kamil Dudka ---- - src/md5sum.c | 20 ++++++++++++-------- - tests/misc/md5sum.pl | 7 +++++++ - 2 files changed, 19 insertions(+), 8 deletions(-) - -diff --git a/src/md5sum.c b/src/md5sum.c -index 933ec99..fee28c7 100644 ---- a/src/md5sum.c -+++ b/src/md5sum.c -@@ -465,15 +465,19 @@ print_filename (char const *file, bool escape) - text because it was a terminal. - - Put the checksum in *BIN_RESULT, which must be properly aligned. -+ Put true in *MISSING if the file can't be opened due to ENOENT. - Return true if successful. */ - - static bool --digest_file (const char *filename, int *binary, unsigned char *bin_result) -+digest_file (const char *filename, int *binary, unsigned char *bin_result, -+ bool *missing) - { - FILE *fp; - int err; - bool is_stdin = STREQ (filename, "-"); - -+ *missing = false; -+ - if (is_stdin) - { - have_read_stdin = true; -@@ -493,7 +497,7 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result) - { - if (ignore_missing && errno == ENOENT) - { -- *bin_result = '\0'; -+ *missing = true; - return true; - } - error (0, errno, "%s", quotef (filename)); -@@ -606,14 +610,14 @@ digest_check (const char *checkfile_name) - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f' }; - bool ok; -+ bool missing; - /* Only escape in the edge case producing multiple lines, - to ease automatic processing of status output. */ - bool needs_escape = ! status_only && strchr (filename, '\n'); - - properly_formatted_lines = true; - -- *bin_buffer = '\1'; /* flag set to 0 for ignored missing files. */ -- ok = digest_file (filename, &binary, bin_buffer); -+ ok = digest_file (filename, &binary, bin_buffer, &missing); - - if (!ok) - { -@@ -626,10 +630,9 @@ digest_check (const char *checkfile_name) - printf (": %s\n", _("FAILED open or read")); - } - } -- else if (ignore_missing && ! *bin_buffer) -+ else if (ignore_missing && missing) - { -- /* Treat an empty buffer as meaning a missing file, -- which is ignored with --ignore-missing. */ -+ /* Ignore missing files with --ignore-missing. */ - ; - } - else -@@ -879,8 +882,9 @@ main (int argc, char **argv) - else - { - int file_is_binary = binary; -+ bool missing; - -- if (! digest_file (file, &file_is_binary, bin_buffer)) -+ if (! digest_file (file, &file_is_binary, bin_buffer, &missing)) - ok = false; - else - { -diff --git a/tests/misc/md5sum.pl b/tests/misc/md5sum.pl -index 2eb6369..6ea7457 100755 ---- a/tests/misc/md5sum.pl -+++ b/tests/misc/md5sum.pl -@@ -149,6 +149,13 @@ my @Tests = - {ERR=> - "md5sum: f.md5: no file was verified\n"}, - {EXIT=> 1}], -+ # coreutils-8.25 with --ignore-missing treated checksums starting with 00 -+ # as if the file was not present -+ ['check-ignore-missing-6', '--check', '--ignore-missing', -+ {AUX=> {f=> '9t'}}, -+ {IN=> {'f.md5' => -+ "006999e6df389641adf1fa3a74801d9d f\n"}}, -+ {OUT=>"f: OK\n"}], - ['bsd-segv', '--check', {IN=> {'z' => "MD5 ("}}, {EXIT=> 1}, - {ERR=> "$prog: z: no properly formatted MD5 checksum lines found\n"}], - --- -2.7.4 - diff --git a/coreutils-8.26.tar.xz.sig b/coreutils-8.26.tar.xz.sig new file mode 100644 index 0000000..fe1635d --- /dev/null +++ b/coreutils-8.26.tar.xz.sig @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1 + +iQIcBAABAgAGBQJYPyRpAAoJEN9v2XEwYDfZ0I4P/3oaPYXMPEOKuDDpEcLumn26 +gYIMQc1jIMbBNQe120gQmNPkRr5dTKt5Bap9qYkCj0pI/6VxVIWDo0xrOLYZi7AN +Xgr0kX2qLDFEH+EHkC1BpsAdpsgwfvLmVWPHS62CNKgVDgGiP1cRJZe8oVmlBCiR +3ES7pUsBfDn3hbdKNTTmMDtro1rQMOxfHkVCZLAva+JjdzpE+KTvzZzKkVuZZfJ/ +Mi/ZySrXZXFvPBS7GXgop4x8EodyzQMeKO+nvpIUEBY1yLQgCvni5/CBI8w/EViD +DSjj0zWsCQkEjx6HCohi8sBHUYZ+M3lB4rkFk7aevdioPZUGfLkW31LT/cUJC/VV +MIQKWzQtZO/WCJuyEbWP2m25c4MtnnhTm5yoi29yT/CoTRlUWkIQpXm4oD1cJXHy +PpHveu8qM0qRaAtVdXE3pmapIMYUV4g7vxSuCjZRrgiDLhp/K7Lzt5xBhl++kPU2 +U9uc202eah4Towo0pbHsuEJT0vk0GGLq8/17dCa/ss8wV+86ZLxl0kZYy4CNEnIW +vsCN6CJ5AoAEVrMN1F7ZJYnH4hoJedvIczThnAkNTqYYE3wnN9stOe28Oy/a0/tg +bt5/Mn0JbmQei890uU8zcEdUjidHqGV4hKk1E2UC4UCyHG/VcHv9gfr8OaD/xPDr +SoauDCHpBU7J7FT/DX+k +=vkKy +-----END PGP SIGNATURE----- diff --git a/coreutils-8.4-mkdir-modenote.patch b/coreutils-8.4-mkdir-modenote.patch index 1f03c8d..51a129e 100644 --- a/coreutils-8.4-mkdir-modenote.patch +++ b/coreutils-8.4-mkdir-modenote.patch @@ -1,7 +1,8 @@ -diff -urNp coreutils-8.4-orig/doc/coreutils.texi coreutils-8.4/doc/coreutils.texi ---- coreutils-8.4-orig/doc/coreutils.texi 2011-01-07 15:01:18.575654333 +0100 -+++ coreutils-8.4/doc/coreutils.texi 2011-01-07 15:05:38.791655243 +0100 -@@ -9993,6 +9993,8 @@ incorrect. @xref{Directory Setuid and Setgid}, for how the +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 400e135..47e4480 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -10074,6 +10074,8 @@ incorrect. @xref{Directory Setuid and Setgid}, for how the set-user-ID and set-group-ID bits of directories are inherited unless overridden in this way. diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index e69cd2b..a69d896 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,7 +1,8 @@ -diff -urNp coreutils-8.21-orig/doc/coreutils.texi coreutils-8.21/doc/coreutils.texi ---- coreutils-8.21-orig/doc/coreutils.texi 2013-02-11 10:37:28.000000000 +0100 -+++ coreutils-8.21/doc/coreutils.texi 2013-02-15 10:15:26.497593689 +0100 -@@ -11221,6 +11221,13 @@ some systems (notably SunOS), doing this yields more up to date results, +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index a507280..400e135 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -11303,6 +11303,13 @@ some systems (notably SunOS), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -15,10 +16,11 @@ diff -urNp coreutils-8.21-orig/doc/coreutils.texi coreutils-8.21/doc/coreutils.t @item --total @opindex --total @cindex grand total of disk size, usage and available space -diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c ---- coreutils-8.21-orig/src/df.c 2013-02-05 00:40:31.000000000 +0100 -+++ coreutils-8.21/src/df.c 2013-02-15 10:26:41.158651782 +0100 -@@ -116,6 +116,9 @@ static bool print_type; +diff --git a/src/df.c b/src/df.c +index 8f760db..a7385fd 100644 +--- a/src/df.c ++++ b/src/df.c +@@ -120,6 +120,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -28,7 +30,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -243,13 +246,15 @@ enum +@@ -247,13 +250,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -45,7 +47,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, -@@ -505,7 +510,10 @@ get_header (void) +@@ -509,7 +514,10 @@ get_header (void) for (col = 0; col < ncolumns; col++) { char *cell = NULL; @@ -57,7 +59,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1352,6 +1360,19 @@ get_point (const char *point, const struct stat *statp) +@@ -1397,6 +1405,19 @@ get_point (const char *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -77,7 +79,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_disk (name)) return; -@@ -1422,6 +1443,7 @@ or all file systems by default.\n\ +@@ -1467,6 +1488,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -85,7 +87,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1512,6 +1534,9 @@ main (int argc, char **argv) +@@ -1557,6 +1579,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -95,7 +97,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1608,6 +1633,13 @@ main (int argc, char **argv) +@@ -1653,6 +1678,13 @@ main (int argc, char **argv) } } @@ -109,9 +111,11 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c if (human_output_opts == -1) { if (posix_format) -diff -urNp coreutils-8.21-orig/tests/df/direct.sh coreutils-8.21/tests/df/direct.sh ---- coreutils-8.21-orig/tests/df/direct.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.21/tests/df/direct.sh 2013-02-15 10:15:26.503644446 +0100 +diff --git a/tests/df/direct.sh b/tests/df/direct.sh +new file mode 100644 +index 0000000..8e4cfb8 +--- /dev/null ++++ b/tests/df/direct.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# Ensure "df --direct" works as documented diff --git a/coreutils-i18n-cut-old.patch b/coreutils-i18n-cut-old.patch index 008cecb..7fcc8ff 100644 --- a/coreutils-i18n-cut-old.patch +++ b/coreutils-i18n-cut-old.patch @@ -1,6 +1,7 @@ -diff -urNp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c ---- coreutils-8.25-orig/src/cut.c 2015-06-26 19:05:22.000000000 +0200 -+++ coreutils-8.25/src/cut.c 2015-07-05 09:04:33.028546950 +0200 +diff --git a/src/cut.c b/src/cut.c +index 7ab6be4..022d0ad 100644 +--- a/src/cut.c ++++ b/src/cut.c @@ -28,6 +28,11 @@ #include #include diff --git a/coreutils-i18n-expand-unexpand.patch b/coreutils-i18n-expand-unexpand.patch index d23e0f0..b5f571f 100644 --- a/coreutils-i18n-expand-unexpand.patch +++ b/coreutils-i18n-expand-unexpand.patch @@ -1,4 +1,4 @@ -From 332e9adf944e4ea232a855b1bf75ea4ddfd7e794 Mon Sep 17 00:00:00 2001 +From e87ab5b991b08092a7e07af82b3ec822a8604151 Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Wed, 5 Aug 2015 09:15:09 +0200 Subject: [PATCH] expand,unexpand: add multibyte support @@ -9,13 +9,7 @@ Content-Transfer-Encoding: 8bit * NEWS: Mention the changes. * bootstrap.conf: Add mbfile to the list of modules. * configure.ac: Properly initialize mbfile. -* po/POTFILES.in: Add new source file. -* src/expand-core.c: Move functions common to both expand and -unexpand to this file. -* src/expand-core.h: Add function prototypes from expand-core.c. * src/expand.c (expand): Iterate over multibyte characters properly. -* src/local.mk: Add expand-core.c to the lists of source codes for -expand and unexpand * src/unexpand.c (unexpand): Iterate over multibyte characters properly. * tests/local.mk: Add new tests. @@ -28,29 +22,23 @@ Co-authored-by: Pádraig Brady lib/mbfile.c | 3 + lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++ m4/mbfile.m4 | 14 +++ - po/POTFILES.in | 1 + - src/expand-core.c | 150 ++++++++++++++++++++++++++++++ - src/expand-core.h | 41 +++++++++ - src/expand.c | 186 ++++++++----------------------------- - src/local.mk | 2 + - src/unexpand.c | 195 ++++++++++----------------------------- + src/expand.c | 43 +++++---- + src/unexpand.c | 54 +++++++---- tests/expand/mb.sh | 98 ++++++++++++++++++++ tests/local.mk | 2 + tests/unexpand/mb.sh | 97 ++++++++++++++++++++ - 14 files changed, 750 insertions(+), 297 deletions(-) + 10 files changed, 535 insertions(+), 34 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 - create mode 100644 src/expand-core.c - create mode 100644 src/expand-core.h create mode 100755 tests/expand/mb.sh create mode 100755 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index ef1c078..ea8cebc 100644 +index 8a0ff31..a1c78b2 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -151,6 +151,7 @@ gnulib_modules=" +@@ -152,6 +152,7 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -59,10 +47,10 @@ index ef1c078..ea8cebc 100644 mbrtowc mbsalign diff --git a/configure.ac b/configure.ac -index 8dc2192..b8b5114 100644 +index 1e74b36..24c9725 100644 --- a/configure.ac +++ b/configure.ac -@@ -425,6 +425,8 @@ fi +@@ -427,6 +427,8 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -71,1126 +59,6 @@ index 8dc2192..b8b5114 100644 gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ -diff --git a/po/POTFILES.in b/po/POTFILES.in -index b3fe668..c594d20 100644 ---- a/po/POTFILES.in -+++ b/po/POTFILES.in -@@ -57,6 +57,7 @@ src/dirname.c - src/du.c - src/echo.c - src/env.c -+src/expand-core.c - src/expand.c - src/expr.c - src/factor.c -diff --git a/src/expand-core.c b/src/expand-core.c -new file mode 100644 -index 0000000..c8445db ---- /dev/null -+++ b/src/expand-core.c -@@ -0,0 +1,150 @@ -+/* expand-core.c - elementary functions for the expand and unexpand utilities -+ Copyright (C) 1989-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 . */ -+ -+#include -+ -+#include -+#include -+ -+#include "system.h" -+#include "error.h" -+#include "fadvise.h" -+#include "quote.h" -+#include "xstrndup.h" -+ -+#include "expand-core.h" -+ -+/* Add the comma or blank separated list of tab stops STOPS -+ to the list of tab stops. */ -+ -+extern void -+parse_tab_stops (char const *stops, void (*add_tab_stop)(uintmax_t)) -+{ -+ bool have_tabval = false; -+ uintmax_t tabval IF_LINT ( = 0); -+ char const *num_start IF_LINT ( = NULL); -+ bool ok = true; -+ -+ for (; *stops; stops++) -+ { -+ if (*stops == ',' || isblank (to_uchar (*stops))) -+ { -+ if (have_tabval) -+ add_tab_stop (tabval); -+ have_tabval = false; -+ } -+ else if (ISDIGIT (*stops)) -+ { -+ if (!have_tabval) -+ { -+ tabval = 0; -+ have_tabval = true; -+ num_start = stops; -+ } -+ -+ /* Detect overflow. */ -+ if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) -+ { -+ size_t len = strspn (num_start, "0123456789"); -+ char *bad_num = xstrndup (num_start, len); -+ error (0, 0, _("tab stop is too large %s"), quote (bad_num)); -+ free (bad_num); -+ ok = false; -+ stops = num_start + len - 1; -+ } -+ } -+ else -+ { -+ error (0, 0, _("tab size contains invalid character(s): %s"), -+ quote (stops)); -+ ok = false; -+ break; -+ } -+ } -+ -+ if (!ok) -+ exit (EXIT_FAILURE); -+ -+ if (have_tabval) -+ add_tab_stop (tabval); -+} -+ -+/* Check that the list of tab stops TABS, with ENTRIES entries, -+ contains only nonzero, ascending values. */ -+ -+extern void -+validate_tab_stops (uintmax_t const *tabs, size_t entries) -+{ -+ uintmax_t prev_tab = 0; -+ size_t i; -+ -+ for (i = 0; i < entries; i++) -+ { -+ if (tabs[i] == 0) -+ error (EXIT_FAILURE, 0, _("tab size cannot be 0")); -+ if (tabs[i] <= prev_tab) -+ error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); -+ prev_tab = tabs[i]; -+ } -+} -+ -+/* Close the old stream pointer FP if it is non-NULL, -+ and return a new one opened to read the next input file. -+ Open a filename of '-' as the standard input. -+ Return NULL if there are no more input files. */ -+ -+extern FILE * -+next_file (FILE *fp) -+{ -+ static char *prev_file; -+ char *file; -+ -+ if (fp) -+ { -+ if (ferror (fp)) -+ { -+ error (0, errno, "%s", prev_file); -+ exit_status = EXIT_FAILURE; -+ } -+ if (STREQ (prev_file, "-")) -+ clearerr (fp); /* Also clear EOF. */ -+ else if (fclose (fp) != 0) -+ { -+ error (0, errno, "%s", prev_file); -+ exit_status = EXIT_FAILURE; -+ } -+ } -+ -+ while ((file = *file_list++) != NULL) -+ { -+ if (STREQ (file, "-")) -+ { -+ have_read_stdin = true; -+ fp = stdin; -+ } -+ else -+ fp = fopen (file, "r"); -+ if (fp) -+ { -+ prev_file = file; -+ fadvise (fp, FADVISE_SEQUENTIAL); -+ return fp; -+ } -+ error (0, errno, "%s", file); -+ exit_status = EXIT_FAILURE; -+ } -+ return NULL; -+} -diff --git a/src/expand-core.h b/src/expand-core.h -new file mode 100644 -index 0000000..2419407 ---- /dev/null -+++ b/src/expand-core.h -@@ -0,0 +1,41 @@ -+/* expand-core.h - function prototypes for the expand and unexpand utilities -+ Copyright (C) 1989-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 . */ -+ -+#ifndef EXPAND_CORE_H_ -+# define EXPAND_CORE_H_ -+ -+extern size_t first_free_tab; -+ -+extern size_t n_tabs_allocated; -+ -+extern uintmax_t *tab_list; -+ -+extern int exit_status; -+ -+extern char **file_list; -+ -+extern bool have_read_stdin; -+ -+void -+parse_tab_stops (char const *stops, void (*add_tab_stop)(uintmax_t)); -+ -+void -+validate_tab_stops (uintmax_t const *tabs, size_t entries); -+ -+FILE * -+next_file (FILE *fp); -+ -+#endif /* EXPAND_CORE_H_ */ -diff --git a/src/expand.c b/src/expand.c -index 0a40a1a..ed97fd4 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -37,12 +37,16 @@ - #include - #include - #include -+ -+#include -+ - #include "system.h" - #include "error.h" - #include "fadvise.h" --#include "quote.h" - #include "xstrndup.h" - -+#include "expand-core.h" -+ - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "expand" - -@@ -58,17 +62,17 @@ static uintmax_t tab_size; - /* Array of the explicit column numbers of the tab stops; - after 'tab_list' is exhausted, each additional tab is replaced - by a space. The first column is column 0. */ --static uintmax_t *tab_list; -+uintmax_t *tab_list; - - /* The number of allocated entries in 'tab_list'. */ --static size_t n_tabs_allocated; -+size_t n_tabs_allocated; - - /* The index of the first invalid element of 'tab_list', - where the next element can be added. */ --static size_t first_free_tab; -+size_t first_free_tab; - - /* Null-terminated array of input filenames. */ --static char **file_list; -+char **file_list; - - /* Default for 'file_list' if no files are given on the command line. */ - static char *stdin_argv[] = -@@ -77,10 +81,10 @@ static char *stdin_argv[] = - }; - - /* True if we have ever read standard input. */ --static bool have_read_stdin; -+bool have_read_stdin; - - /* The desired exit status. */ --static int exit_status; -+int exit_status; - - static char const shortopts[] = "it:0::1::2::3::4::5::6::7::8::9::"; - -@@ -135,128 +139,6 @@ add_tab_stop (uintmax_t tabval) - tab_list[first_free_tab++] = tabval; - } - --/* Add the comma or blank separated list of tab stops STOPS -- to the list of tab stops. */ -- --static void --parse_tab_stops (char const *stops) --{ -- bool have_tabval = false; -- uintmax_t tabval IF_LINT ( = 0); -- char const *num_start IF_LINT ( = NULL); -- bool ok = true; -- -- for (; *stops; stops++) -- { -- if (*stops == ',' || isblank (to_uchar (*stops))) -- { -- if (have_tabval) -- add_tab_stop (tabval); -- have_tabval = false; -- } -- else if (ISDIGIT (*stops)) -- { -- if (!have_tabval) -- { -- tabval = 0; -- have_tabval = true; -- num_start = stops; -- } -- -- /* Detect overflow. */ -- if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) -- { -- size_t len = strspn (num_start, "0123456789"); -- char *bad_num = xstrndup (num_start, len); -- error (0, 0, _("tab stop is too large %s"), quote (bad_num)); -- free (bad_num); -- ok = false; -- stops = num_start + len - 1; -- } -- } -- else -- { -- error (0, 0, _("tab size contains invalid character(s): %s"), -- quote (stops)); -- ok = false; -- break; -- } -- } -- -- if (!ok) -- exit (EXIT_FAILURE); -- -- if (have_tabval) -- add_tab_stop (tabval); --} -- --/* Check that the list of tab stops TABS, with ENTRIES entries, -- contains only nonzero, ascending values. */ -- --static void --validate_tab_stops (uintmax_t const *tabs, size_t entries) --{ -- uintmax_t prev_tab = 0; -- size_t i; -- -- for (i = 0; i < entries; i++) -- { -- if (tabs[i] == 0) -- error (EXIT_FAILURE, 0, _("tab size cannot be 0")); -- if (tabs[i] <= prev_tab) -- error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); -- prev_tab = tabs[i]; -- } --} -- --/* Close the old stream pointer FP if it is non-NULL, -- and return a new one opened to read the next input file. -- Open a filename of '-' as the standard input. -- Return NULL if there are no more input files. */ -- --static FILE * --next_file (FILE *fp) --{ -- static char *prev_file; -- char *file; -- -- if (fp) -- { -- if (ferror (fp)) -- { -- error (0, errno, "%s", quotef (prev_file)); -- exit_status = EXIT_FAILURE; -- } -- if (STREQ (prev_file, "-")) -- clearerr (fp); /* Also clear EOF. */ -- else if (fclose (fp) != 0) -- { -- error (0, errno, "%s", quotef (prev_file)); -- exit_status = EXIT_FAILURE; -- } -- } -- -- while ((file = *file_list++) != NULL) -- { -- if (STREQ (file, "-")) -- { -- have_read_stdin = true; -- fp = stdin; -- } -- else -- fp = fopen (file, "r"); -- if (fp) -- { -- prev_file = file; -- fadvise (fp, FADVISE_SEQUENTIAL); -- return fp; -- } -- error (0, errno, "%s", quotef (file)); -- exit_status = EXIT_FAILURE; -- } -- return NULL; --} -- - /* Change tabs to spaces, writing to stdout. - Read each file in 'file_list', in order. */ - -@@ -265,19 +147,19 @@ expand (void) - { - /* Input stream. */ - FILE *fp = next_file (NULL); -+ mb_file_t mbf; -+ mbf_char_t c; - - if (!fp) - return; - -+ mbf_init (mbf, fp); -+ - while (true) - { -- /* Input character, or EOF. */ -- int c; -- - /* If true, perform translations. */ - bool convert = true; - -- - /* The following variables have valid values only when CONVERT - is true: */ - -@@ -287,17 +169,23 @@ 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; -+ do { -+ mbf_getc (c, mbf); -+ if (mb_iseof (c)) -+ { -+ mbf_init (mbf, fp = next_file (fp)); -+ continue; -+ } -+ } -+ while (false); - - if (convert) - { -- if (c == '\t') -+ if (mb_iseq (c, '\t')) - { - /* Column the next input tab stop is on. */ - uintmax_t next_tab_column; -@@ -328,32 +216,34 @@ expand (void) - if (putchar (' ') < 0) - error (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) - error (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)) - error (EXIT_FAILURE, errno, _("write error")); - } -- while (c != '\n'); -+ while (!mb_iseq (c, '\n')); - } - } - -@@ -385,19 +275,19 @@ main (int argc, char **argv) - break; - - case 't': -- parse_tab_stops (optarg); -+ parse_tab_stops (optarg, add_tab_stop); - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (optarg) -- parse_tab_stops (optarg - 1); -+ parse_tab_stops (optarg - 1, add_tab_stop); - else - { - char tab_stop[2]; - tab_stop[0] = c; - tab_stop[1] = '\0'; -- parse_tab_stops (tab_stop); -+ parse_tab_stops (tab_stop, add_tab_stop); - } - break; - -diff --git a/src/local.mk b/src/local.mk -index 536b7cc..bfede88 100644 ---- a/src/local.mk -+++ b/src/local.mk -@@ -361,6 +361,8 @@ src_coreutils_SOURCES = src/coreutils.c - - src_cp_SOURCES = src/cp.c $(copy_sources) $(selinux_sources) - src_dir_SOURCES = src/ls.c src/ls-dir.c -+src_expand_SOURCES = src/expand.c src/expand-core.c -+src_unexpand_SOURCES = src/unexpand.c src/expand-core.c - src_vdir_SOURCES = src/ls.c src/ls-vdir.c - src_id_SOURCES = src/id.c src/group-list.c - src_groups_SOURCES = src/groups.c src/group-list.c -diff --git a/src/unexpand.c b/src/unexpand.c -index e0f7c22..48fbb32 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -38,12 +38,16 @@ - #include - #include - #include -+ -+#include -+ - #include "system.h" - #include "error.h" - #include "fadvise.h" --#include "quote.h" - #include "xstrndup.h" - -+#include "expand-core.h" -+ - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "unexpand" - -@@ -62,17 +66,17 @@ static size_t max_column_width; - /* Array of the explicit column numbers of the tab stops; - after 'tab_list' is exhausted, the rest of the line is printed - unchanged. The first column is column 0. */ --static uintmax_t *tab_list; -+uintmax_t *tab_list; - - /* The number of allocated entries in 'tab_list'. */ --static size_t n_tabs_allocated; -+size_t n_tabs_allocated; - - /* The index of the first invalid element of 'tab_list', - where the next element can be added. */ --static size_t first_free_tab; -+size_t first_free_tab; - - /* Null-terminated array of input filenames. */ --static char **file_list; -+char **file_list; - - /* Default for 'file_list' if no files are given on the command line. */ - static char *stdin_argv[] = -@@ -81,10 +85,10 @@ static char *stdin_argv[] = - }; - - /* True if we have ever read standard input. */ --static bool have_read_stdin; -+bool have_read_stdin; - - /* The desired exit status. */ --static int exit_status; -+int exit_status; - - /* For long options that have no equivalent short option, use a - non-character as a pseudo short option, starting with CHAR_MAX + 1. */ -@@ -154,128 +158,6 @@ add_tab_stop (uintmax_t tabval) - } - } - --/* Add the comma or blank separated list of tab stops STOPS -- to the list of tab stops. */ -- --static void --parse_tab_stops (char const *stops) --{ -- bool have_tabval = false; -- uintmax_t tabval IF_LINT ( = 0); -- char const *num_start IF_LINT ( = NULL); -- bool ok = true; -- -- for (; *stops; stops++) -- { -- if (*stops == ',' || isblank (to_uchar (*stops))) -- { -- if (have_tabval) -- add_tab_stop (tabval); -- have_tabval = false; -- } -- else if (ISDIGIT (*stops)) -- { -- if (!have_tabval) -- { -- tabval = 0; -- have_tabval = true; -- num_start = stops; -- } -- -- /* Detect overflow. */ -- if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t)) -- { -- size_t len = strspn (num_start, "0123456789"); -- char *bad_num = xstrndup (num_start, len); -- error (0, 0, _("tab stop is too large %s"), quote (bad_num)); -- free (bad_num); -- ok = false; -- stops = num_start + len - 1; -- } -- } -- else -- { -- error (0, 0, _("tab size contains invalid character(s): %s"), -- quote (stops)); -- ok = false; -- break; -- } -- } -- -- if (!ok) -- exit (EXIT_FAILURE); -- -- if (have_tabval) -- add_tab_stop (tabval); --} -- --/* Check that the list of tab stops TABS, with ENTRIES entries, -- contains only nonzero, ascending values. */ -- --static void --validate_tab_stops (uintmax_t const *tabs, size_t entries) --{ -- uintmax_t prev_tab = 0; -- size_t i; -- -- for (i = 0; i < entries; i++) -- { -- if (tabs[i] == 0) -- error (EXIT_FAILURE, 0, _("tab size cannot be 0")); -- if (tabs[i] <= prev_tab) -- error (EXIT_FAILURE, 0, _("tab sizes must be ascending")); -- prev_tab = tabs[i]; -- } --} -- --/* Close the old stream pointer FP if it is non-NULL, -- and return a new one opened to read the next input file. -- Open a filename of '-' as the standard input. -- Return NULL if there are no more input files. */ -- --static FILE * --next_file (FILE *fp) --{ -- static char *prev_file; -- char *file; -- -- if (fp) -- { -- if (ferror (fp)) -- { -- error (0, errno, "%s", quotef (prev_file)); -- exit_status = EXIT_FAILURE; -- } -- if (STREQ (prev_file, "-")) -- clearerr (fp); /* Also clear EOF. */ -- else if (fclose (fp) != 0) -- { -- error (0, errno, "%s", quotef (prev_file)); -- exit_status = EXIT_FAILURE; -- } -- } -- -- while ((file = *file_list++) != NULL) -- { -- if (STREQ (file, "-")) -- { -- have_read_stdin = true; -- fp = stdin; -- } -- else -- fp = fopen (file, "r"); -- if (fp) -- { -- prev_file = file; -- fadvise (fp, FADVISE_SEQUENTIAL); -- return fp; -- } -- error (0, errno, "%s", quotef (file)); -- exit_status = EXIT_FAILURE; -- } -- return NULL; --} -- - /* Change blanks to tabs, writing to stdout. - Read each file in 'file_list', in order. */ - -@@ -284,11 +166,12 @@ 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; - - if (!fp) - return; -@@ -296,12 +179,14 @@ unexpand (void) - /* 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)); -+ -+ mbf_init (mbf, fp); - - while (true) - { - /* Input character, or EOF. */ -- int c; -+ mbf_char_t c; - - /* If true, perform translations. */ - bool convert = true; -@@ -335,12 +220,19 @@ unexpand (void) - - do - { -- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) -- continue; -+ do { -+ mbf_getc (c, mbf); -+ if (mb_iseof (c)) -+ { -+ mbf_init (mbf, fp = next_file (fp)); -+ continue; -+ } -+ } -+ while (false); - - if (convert) - { -- bool blank = !! isblank (c); -+ bool blank = mb_isblank (c); - - if (blank) - { -@@ -372,16 +264,16 @@ unexpand (void) - if (next_tab_column < column) - error (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)) - { -@@ -389,13 +281,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 -@@ -403,7 +296,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. */ -@@ -413,7 +306,7 @@ unexpand (void) - } - else - { -- column++; -+ column += mb_width (c); - if (!column) - error (EXIT_FAILURE, 0, _("input line is too long")); - } -@@ -421,9 +314,13 @@ 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)) - error (EXIT_FAILURE, errno, _("write error")); -+ - pending = 0; - one_blank_before_tab_stop = false; - } -@@ -432,16 +329,16 @@ 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)) - error (EXIT_FAILURE, errno, _("write error")); - } -- while (c != '\n'); -+ while (!mb_iseq (c, '\n')); - } - } - -@@ -482,7 +379,7 @@ main (int argc, char **argv) - break; - case 't': - convert_entire_line = true; -- parse_tab_stops (optarg); -+ parse_tab_stops (optarg, add_tab_stop); - break; - case CONVERT_FIRST_ONLY_OPTION: - convert_first_only = true; -diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -new file mode 100755 -index 0000000..7971e18 ---- /dev/null -+++ b/tests/expand/mb.sh -@@ -0,0 +1,98 @@ -+#!/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 -+ -+#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 -+ -+exit $fail -diff --git a/tests/local.mk b/tests/local.mk -index 7df04da..d3462be 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -536,6 +536,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 \ -@@ -674,6 +675,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. -diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -new file mode 100755 -index 0000000..60d4c1a ---- /dev/null -+++ b/tests/unexpand/mb.sh -@@ -0,0 +1,97 @@ -+#!/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 -+ -+#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 -diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 -new file mode 100644 -index 0000000..8589902 ---- /dev/null -+++ b/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]) -+ : -+]) diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 index 0000000..b0a468e @@ -1461,6 +329,520 @@ index 0000000..11f1b12 +_GL_INLINE_HEADER_BEGIN + +#endif /* _MBFILE_H */ +diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 +new file mode 100644 +index 0000000..8589902 +--- /dev/null ++++ b/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]) ++ : ++]) +diff --git a/src/expand.c b/src/expand.c +index 9fa2e10..380e020 100644 +--- a/src/expand.c ++++ b/src/expand.c +@@ -37,6 +37,9 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "die.h" + #include "xstrndup.h" +@@ -100,19 +103,19 @@ expand (void) + { + /* Input stream. */ + FILE *fp = next_file (NULL); ++ mb_file_t mbf; ++ mbf_char_t c; + + if (!fp) + return; + ++ mbf_init (mbf, fp); ++ + while (true) + { +- /* Input character, or EOF. */ +- int c; +- + /* If true, perform translations. */ + bool convert = true; + +- + /* The following variables have valid values only when CONVERT + is true: */ + +@@ -122,17 +125,23 @@ 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; ++ do { ++ mbf_getc (c, mbf); ++ if (mb_iseof (c)) ++ { ++ mbf_init (mbf, fp = next_file (fp)); ++ continue; ++ } ++ } ++ while (false); + + if (convert) + { +- if (c == '\t') ++ if (mb_iseq (c, '\t')) + { + /* Column the next input tab stop is on. */ + uintmax_t next_tab_column; +@@ -151,32 +160,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')); + } + } + +diff --git a/src/unexpand.c b/src/unexpand.c +index 7801274..569a7ee 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c +@@ -38,6 +38,9 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "die.h" + #include "xstrndup.h" +@@ -107,11 +110,12 @@ 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; + + if (!fp) + return; +@@ -119,12 +123,14 @@ unexpand (void) + /* 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)); ++ ++ mbf_init (mbf, fp); + + while (true) + { + /* Input character, or EOF. */ +- int c; ++ mbf_char_t c; + + /* If true, perform translations. */ + bool convert = true; +@@ -158,12 +164,19 @@ unexpand (void) + + do + { +- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) +- continue; ++ do { ++ mbf_getc (c, mbf); ++ if (mb_iseof (c)) ++ { ++ mbf_init (mbf, fp = next_file (fp)); ++ continue; ++ } ++ } ++ while (false); + + if (convert) + { +- bool blank = !! isblank (c); ++ bool blank = mb_isblank (c); + + if (blank) + { +@@ -180,16 +193,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 +210,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 +225,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. */ +@@ -221,7 +235,7 @@ unexpand (void) + } + else + { +- column++; ++ column += mb_width (c); + if (!column) + die (EXIT_FAILURE, 0, _("input line is too long")); + } +@@ -229,8 +243,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 +257,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')); + } + } + +diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh +new file mode 100755 +index 0000000..7971e18 +--- /dev/null ++++ b/tests/expand/mb.sh +@@ -0,0 +1,98 @@ ++#!/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 ++ ++#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 ++ ++exit $fail +diff --git a/tests/local.mk b/tests/local.mk +index 192f776..8053397 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -544,6 +544,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 \ +@@ -684,6 +685,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. +diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh +new file mode 100755 +index 0000000..60d4c1a +--- /dev/null ++++ b/tests/unexpand/mb.sh +@@ -0,0 +1,97 @@ ++#!/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 ++ ++#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 -- -2.5.5 +2.7.4 diff --git a/coreutils-i18n-fix-unexpand.patch b/coreutils-i18n-fix-unexpand.patch index c7ca839..f0c347c 100644 --- a/coreutils-i18n-fix-unexpand.patch +++ b/coreutils-i18n-fix-unexpand.patch @@ -1,60 +1,28 @@ -From lkundrak@v3.sk Thu Jan 28 20:57:48 2016 -Return-Path: lkundrak@v3.sk -Received: from zimbra.v3.sk (LHLO zimbra.v3.sk) (10.13.37.31) by - zimbra.v3.sk with LMTP; Thu, 28 Jan 2016 20:57:48 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) by zimbra.v3.sk (Postfix) - with ESMTP id D4DD260F92 for ; Thu, 28 Jan 2016 20:57:47 - +0100 (CET) -X-Spam-Flag: NO -X-Spam-Score: -2.9 -X-Spam-Level: -X-Spam-Status: No, score=-2.9 tagged_above=-10 required=3 - tests=[ALL_TRUSTED=-1, BAYES_00=-1.9] autolearn=ham autolearn_force=no -Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk - [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id HB5H5ynfOcyL; Thu, 28 - Jan 2016 20:57:45 +0100 (CET) -Received: from localhost (localhost [127.0.0.1]) by zimbra.v3.sk (Postfix) - with ESMTP id 3FEF160F90; Thu, 28 Jan 2016 20:57:45 +0100 (CET) -X-Virus-Scanned: amavisd-new at zimbra.v3.sk -Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk - [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id TUF9p5l6r9SN; Thu, 28 - Jan 2016 20:57:44 +0100 (CET) -Received: from odvarok.localdomain (s559633cb.adsl.online.nl - [85.150.51.203]) by zimbra.v3.sk (Postfix) with ESMTPSA id 6763560F8F; Thu, - 28 Jan 2016 20:57:44 +0100 (CET) +From 02424bfcd719bbaa695f4e1c3ef17ad91b0d23c0 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel -To: =?UTF-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= , Ondrej - Oprala -Cc: Lubomir Rintel -Subject: [PATCH] unexpand: fix blank line handling Date: Thu, 28 Jan 2016 20:57:22 +0100 -Message-Id: <1454011042-30492-1-git-send-email-lkundrak@v3.sk> -X-Mailer: git-send-email 2.5.0 -X-Evolution-Source: 1409576065.5421.4@dhcp-24-163.brq.redhat.com -Content-Transfer-Encoding: 8bit -Mime-Version: 1.0 +Subject: [PATCH] unexpand: fix blank line handling - echo '' |./src/unexpand -a - -Really? ---- - src/unexpand.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/unexpand.c b/src/unexpand.c -index d6ff662..762c56b 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -304,7 +304,7 @@ unexpand (void) - next_tab_column = column; - tab_index -= !!tab_index; - } -- else -+ else if (!mb_iseq (c, '\n')) - { - column += mb_width (c); - if (!column) --- -2.5.0 - + echo '' |./src/unexpand -a + +Really? +--- + src/unexpand.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/unexpand.c b/src/unexpand.c +index 569a7ee..3bbbd66 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c +@@ -233,7 +233,7 @@ unexpand (void) + next_tab_column = column; + tab_index -= !!tab_index; + } +- else ++ else if (!mb_iseq (c, '\n')) + { + column += mb_width (c); + if (!column) +-- +2.7.4 diff --git a/coreutils-i18n-fix2-expand-unexpand.patch b/coreutils-i18n-fix2-expand-unexpand.patch index 1f02c5e..1a63012 100644 --- a/coreutils-i18n-fix2-expand-unexpand.patch +++ b/coreutils-i18n-fix2-expand-unexpand.patch @@ -1,7 +1,8 @@ -diff -up ./src/expand.c.orig ./src/expand.c ---- ./src/expand.c.orig 2016-06-01 12:42:49.330373488 +0200 -+++ ./src/expand.c 2016-06-07 14:35:16.011142041 +0200 -@@ -173,15 +173,19 @@ expand (void) +diff --git a/src/expand.c b/src/expand.c +index 380e020..310b349 100644 +--- a/src/expand.c ++++ b/src/expand.c +@@ -129,15 +129,19 @@ expand (void) do { @@ -25,10 +26,11 @@ diff -up ./src/expand.c.orig ./src/expand.c if (convert) { -diff -up ./src/unexpand.c.orig ./src/unexpand.c ---- ./src/unexpand.c.orig 2016-06-07 14:26:57.380746446 +0200 -+++ ./src/unexpand.c 2016-06-07 14:34:54.059256698 +0200 -@@ -220,15 +220,19 @@ unexpand (void) +diff --git a/src/unexpand.c b/src/unexpand.c +index 3bbbd66..863a90a 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c +@@ -164,15 +164,19 @@ unexpand (void) do { @@ -52,9 +54,10 @@ diff -up ./src/unexpand.c.orig ./src/unexpand.c if (convert) { -diff -up ./tests/expand/mb.sh.orig ./tests/expand/mb.sh ---- ./tests/expand/mb.sh.orig 2016-05-11 14:13:53.095289000 +0200 -+++ ./tests/expand/mb.sh 2016-06-07 14:38:48.259033445 +0200 +diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh +index 7971e18..031be7a 100755 +--- a/tests/expand/mb.sh ++++ b/tests/expand/mb.sh @@ -44,6 +44,20 @@ EOF expand < in > out || fail=1 compare exp out > /dev/null 2>&1 || fail=1 @@ -76,9 +79,10 @@ diff -up ./tests/expand/mb.sh.orig ./tests/expand/mb.sh #test characters with display widths != 1 env printf '12345678 e\t|ascii(1) -diff -up ./tests/unexpand/mb.sh.orig ./tests/unexpand/mb.sh ---- ./tests/unexpand/mb.sh.orig 2016-06-07 14:41:44.210106466 +0200 -+++ ./tests/unexpand/mb.sh 2016-06-07 14:52:28.848639772 +0200 +diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh +index 60d4c1a..8d75652 100755 +--- a/tests/unexpand/mb.sh ++++ b/tests/unexpand/mb.sh @@ -44,6 +44,22 @@ EOF unexpand -a < in > out || fail=1 compare exp out > /dev/null 2>&1 || fail=1 diff --git a/coreutils-i18n-sort-human.patch b/coreutils-i18n-sort-human.patch index 2469189..6752493 100644 --- a/coreutils-i18n-sort-human.patch +++ b/coreutils-i18n-sort-human.patch @@ -14,7 +14,7 @@ diff --git a/src/sort.c b/src/sort.c index 9e07ad8..e47b039 100644 --- a/src/sort.c +++ b/src/sort.c -@@ -2274,12 +2274,10 @@ find_unit_order (char const *number) +@@ -2304,12 +2304,10 @@ find_unit_order (char const *number) < K/k < M < G < T < P < E < Z < Y */ static int diff --git a/coreutils-i18n-un-expand-BOM.patch b/coreutils-i18n-un-expand-BOM.patch index 44769c6..56e7fa5 100644 --- a/coreutils-i18n-un-expand-BOM.patch +++ b/coreutils-i18n-un-expand-BOM.patch @@ -1,19 +1,20 @@ -diff -up ./src/expand-core.c.orig ./src/expand-core.c ---- ./src/expand-core.c.orig 2016-06-28 14:44:18.281619000 +0200 -+++ ./src/expand-core.c 2016-06-30 11:46:50.025109755 +0200 +diff --git a/src/expand-common.c b/src/expand-common.c +index 4657e46..97cbb09 100644 +--- a/src/expand-common.c ++++ b/src/expand-common.c @@ -18,6 +18,7 @@ #include #include +#include - #include "system.h" + #include "die.h" #include "error.h" -@@ -27,6 +28,119 @@ +@@ -85,6 +86,119 @@ add_tab_stop (uintmax_t tabval) + } + } - #include "expand-core.h" - -+extern inline int ++extern int +set_utf_locale (void) +{ + /*try using some predefined locale */ @@ -118,7 +119,7 @@ diff -up ./src/expand-core.c.orig ./src/expand-core.c + return false; +} + -+extern inline void ++extern void +print_bom(void) +{ + putc (0xEF, stdout); @@ -128,42 +129,35 @@ diff -up ./src/expand-core.c.orig ./src/expand-core.c + /* Add the comma or blank separated list of tab stops STOPS to the list of tab stops. */ + extern void +diff --git a/src/expand-common.h b/src/expand-common.h +index 8cb2079..763bfda 100644 +--- a/src/expand-common.h ++++ b/src/expand-common.h +@@ -34,6 +34,18 @@ extern size_t max_column_width; + /* The desired exit status. */ + extern int exit_status; -diff -up ./src/expand-core.h.orig ./src/expand-core.h ---- ./src/expand-core.h.orig 2016-06-28 14:44:18.281619000 +0200 -+++ ./src/expand-core.h 2016-06-30 11:47:18.929437205 +0200 -@@ -15,7 +15,7 @@ - along with this program. If not, see . */ - - #ifndef EXPAND_CORE_H_ --# define EXPAND_CORE_H_ -+#define EXPAND_CORE_H_ - - extern size_t first_free_tab; - -@@ -29,6 +29,18 @@ extern char **file_list; - - extern bool have_read_stdin; - -+inline int ++extern int +set_utf_locale (void); + -+bool ++extern bool +check_utf_locale(void); + -+bool ++extern bool +check_bom(FILE* fp, mb_file_t *mbf); + -+inline void ++extern void +print_bom(void); + - void - parse_tab_stops (char const *stops, void (*add_tab_stop)(uintmax_t)); - -diff -up ./src/expand.c.orig ./src/expand.c ---- ./src/expand.c.orig 2016-06-28 14:44:18.286619000 +0200 -+++ ./src/expand.c 2016-06-30 11:50:15.077312947 +0200 -@@ -149,11 +149,33 @@ expand (void) + /* Add tab stop TABVAL to the end of 'tab_list'. */ + extern void + add_tab_stop (uintmax_t tabval); +diff --git a/src/expand.c b/src/expand.c +index 310b349..4136824 100644 +--- a/src/expand.c ++++ b/src/expand.c +@@ -105,11 +105,33 @@ expand (void) FILE *fp = next_file (NULL); mb_file_t mbf; mbf_char_t c; @@ -199,7 +193,7 @@ diff -up ./src/expand.c.orig ./src/expand.c while (true) { -@@ -178,6 +200,27 @@ expand (void) +@@ -134,6 +156,27 @@ expand (void) if ((mb_iseof (c)) && (fp = next_file (fp))) { mbf_init (mbf, fp); @@ -227,10 +221,11 @@ diff -up ./src/expand.c.orig ./src/expand.c continue; } else -diff -up ./src/unexpand.c.orig ./src/unexpand.c ---- ./src/unexpand.c.orig 2016-06-28 17:39:22.894259000 +0200 -+++ ./src/unexpand.c 2016-07-07 09:48:07.659924755 +0200 -@@ -172,16 +172,36 @@ unexpand (void) +diff --git a/src/unexpand.c b/src/unexpand.c +index 863a90a..5681b58 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c +@@ -116,16 +116,36 @@ unexpand (void) include characters other than spaces, so the blanks must be stored, not merely counted. */ mbf_char_t *pending_blank; @@ -268,7 +263,7 @@ diff -up ./src/unexpand.c.orig ./src/unexpand.c while (true) { -@@ -225,6 +245,27 @@ unexpand (void) +@@ -169,6 +189,27 @@ unexpand (void) if ((mb_iseof (c)) && (fp = next_file (fp))) { mbf_init (mbf, fp); @@ -296,10 +291,11 @@ diff -up ./src/unexpand.c.orig ./src/unexpand.c continue; } else -diff -up ./tests/expand/mb.sh.orig ./tests/expand/mb.sh ---- ./tests/expand/mb.sh.orig 2016-06-28 14:44:18.287619000 +0200 -+++ ./tests/expand/mb.sh 2016-06-30 11:57:10.038407216 +0200 -@@ -109,4 +109,75 @@ äbcdef\xFF | +diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh +index 031be7a..1621c84 100755 +--- a/tests/expand/mb.sh ++++ b/tests/expand/mb.sh +@@ -109,4 +109,75 @@ env printf '12345678 expand < in > out || fail=1 compare exp out > /dev/null 2>&1 || fail=1 @@ -375,10 +371,11 @@ diff -up ./tests/expand/mb.sh.orig ./tests/expand/mb.sh +compare exp out > /dev/null 2>&1 || fail=1 + exit $fail -diff -up ./tests/unexpand/mb.sh.orig ./tests/unexpand/mb.sh ---- ./tests/unexpand/mb.sh.orig 2016-06-28 17:39:22.895259000 +0200 -+++ ./tests/unexpand/mb.sh 2016-07-07 09:55:00.098281917 +0200 -@@ -111,3 +111,62 @@ äbcdef\xFF\t| +diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh +index 8d75652..9d4ee3e 100755 +--- a/tests/unexpand/mb.sh ++++ b/tests/unexpand/mb.sh +@@ -111,3 +111,62 @@ env printf '12345678 unexpand -a < in > out || fail=1 compare exp out > /dev/null 2>&1 || fail=1 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index bcce9ff..d7cf59c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,6 +1,36 @@ -diff -urNp coreutils-8.24-orig/lib/linebuffer.h coreutils-8.24/lib/linebuffer.h ---- coreutils-8.24-orig/lib/linebuffer.h 2015-06-16 07:00:37.000000000 +0200 -+++ coreutils-8.24/lib/linebuffer.h 2015-07-05 09:04:33.027546943 +0200 +From 29117b2d07af00f4d4b87cf778e4294588ab1a83 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 1 Dec 2016 15:10:04 +0100 +Subject: [PATCH] coreutils-i18n.patch + +TODO: merge upstream +--- + lib/linebuffer.h | 8 + + src/fold.c | 308 ++++++++++++++++-- + src/join.c | 359 ++++++++++++++++++--- + src/pr.c | 443 ++++++++++++++++++++++--- + src/sort.c | 764 +++++++++++++++++++++++++++++++++++++++++--- + src/uniq.c | 265 ++++++++++++++- + tests/i18n/sort.sh | 29 ++ + tests/local.mk | 2 + + tests/misc/cut.pl | 7 +- + 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 +++ + 18 files changed, 2435 insertions(+), 162 deletions(-) + create mode 100644 tests/i18n/sort.sh + create mode 100644 tests/misc/sort-mb-tests.sh + +diff --git a/lib/linebuffer.h b/lib/linebuffer.h +index 64181af..9b8fe5a 100644 +--- a/lib/linebuffer.h ++++ b/lib/linebuffer.h @@ -21,6 +21,11 @@ # include @@ -23,10 +53,11 @@ diff -urNp coreutils-8.24-orig/lib/linebuffer.h coreutils-8.24/lib/linebuffer.h }; /* Initialize linebuffer LINEBUFFER for use. */ -diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c ---- coreutils-8.24-orig/src/fold.c 2015-06-26 19:05:22.000000000 +0200 -+++ coreutils-8.24/src/fold.c 2015-07-05 09:04:33.029546958 +0200 -@@ -22,11 +22,33 @@ +diff --git a/src/fold.c b/src/fold.c +index 8cd0d6b..d23edd5 100644 +--- a/src/fold.c ++++ b/src/fold.c +@@ -22,12 +22,34 @@ #include #include @@ -41,6 +72,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c +#endif + #include "system.h" + #include "die.h" #include "error.h" #include "fadvise.h" #include "xdectoint.h" @@ -60,7 +92,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c #define TAB_WIDTH 8 /* The official name of this program (e.g., no 'g' prefix). */ -@@ -34,20 +56,41 @@ +@@ -35,20 +57,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -106,7 +138,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c {"spaces", no_argument, NULL, 's'}, {"width", required_argument, NULL, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ +@@ -76,6 +119,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -114,7 +146,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ +@@ -93,7 +137,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ static size_t adjust_column (size_t column, char c) { @@ -123,7 +155,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c { if (c == '\b') { -@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) +@@ -116,30 +160,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -156,7 +188,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c fadvise (istream, FADVISE_SEQUENTIAL); -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width) +@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t width) bool found_blank = false; size_t logical_end = offset_out; @@ -172,7 +204,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c /* Look for the last blank. */ while (logical_end) { -@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t width) +@@ -215,11 +252,221 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -395,7 +427,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c if (ferror (istream)) { error (0, saved_errno, "%s", quotef (filename)); -@@ -251,7 +498,8 @@ main (int argc, char **argv) +@@ -252,7 +499,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -405,7 +437,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -260,7 +508,15 @@ main (int argc, char **argv) +@@ -261,7 +509,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -422,10 +454,11 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c break; case 's': /* Break at word boundaries. */ -diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c ---- coreutils-8.24-orig/src/join.c 2015-06-26 19:05:22.000000000 +0200 -+++ coreutils-8.24/src/join.c 2015-07-05 09:04:33.029546958 +0200 -@@ -22,18 +22,32 @@ +diff --git a/src/join.c b/src/join.c +index 98b461c..9990f38 100644 +--- a/src/join.c ++++ b/src/join.c +@@ -22,19 +22,33 @@ #include #include @@ -440,6 +473,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c +#endif + #include "system.h" + #include "die.h" #include "error.h" #include "fadvise.h" #include "hard-locale.h" @@ -459,7 +493,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "join" -@@ -135,10 +149,12 @@ static struct outlist outlist_head; +@@ -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; @@ -476,7 +510,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -275,13 +291,14 @@ xfields (struct line *line) +@@ -276,13 +292,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -494,7 +528,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c { /* Skip leading blanks before the first field. */ while (field_sep (*ptr)) -@@ -305,6 +322,147 @@ xfields (struct line *line) +@@ -306,6 +323,147 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -642,7 +676,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c static void freeline (struct line *line) { -@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct line const *line2, +@@ -327,56 +485,133 @@ keycmp (struct line const *line1, struct line const *line2, size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -799,7 +833,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c } /* Check that successive input lines PREV and CURRENT from input file -@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep, int which) +@@ -468,6 +703,11 @@ get_line (FILE *fp, struct line **linep, int which) } ++line_no[which - 1]; @@ -811,7 +845,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c xfields (line); if (prevline[which - 1]) -@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *line) +@@ -567,21 +807,28 @@ prfield (size_t n, struct line const *line) /* Output all the fields in line, other than the join field. */ @@ -843,7 +877,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c prfield (i, line); } } -@@ -591,7 +838,6 @@ static void +@@ -592,7 +839,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -851,7 +885,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c size_t field; struct line const *line; -@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct line const *line2) +@@ -626,7 +872,7 @@ prjoin (struct line const *line1, struct line const *line2) o = o->next; if (o == NULL) break; @@ -860,7 +894,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c } putchar (eolchar); } -@@ -1103,21 +1349,46 @@ main (int argc, char **argv) +@@ -1104,20 +1350,43 @@ main (int argc, char **argv) case 't': { @@ -887,16 +921,14 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c + newtablen = 1; if (! newtab) - newtab = '\n'; /* '' => process the whole line. */ -+ { + newtab = (char*)"\n"; /* '' => process the whole line. */ -+ } else if (optarg[1]) { - if (STREQ (optarg, "\\0")) - newtab = '\0'; - else -- error (EXIT_FAILURE, 0, _("multi-character tab %s"), -- quote (optarg)); +- die (EXIT_FAILURE, 0, _("multi-character tab %s"), +- quote (optarg)); + if (newtablen == 1 && newtab[1]) + { + if (STREQ (newtab, "\\0")) @@ -906,20 +938,19 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c + if (tab != NULL && strcmp (tab, newtab)) + { + free (newtab); -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); ++ die (EXIT_FAILURE, 0, _("incompatible tabs")); } - if (0 <= tab && tab != newtab) -- error (EXIT_FAILURE, 0, _("incompatible tabs")); +- die (EXIT_FAILURE, 0, _("incompatible tabs")); tab = newtab; -- } + tablen = newtablen; -+ } + } break; - case 'z': -diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c ---- coreutils-8.24-orig/src/pr.c 2015-06-26 19:05:22.000000000 +0200 -+++ coreutils-8.24/src/pr.c 2015-07-05 09:04:33.030546965 +0200 +diff --git a/src/pr.c b/src/pr.c +index 26f221f..633f50e 100644 +--- a/src/pr.c ++++ b/src/pr.c @@ -311,6 +311,24 @@ #include @@ -943,9 +974,9 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c +#endif + #include "system.h" + #include "die.h" #include "error.h" - #include "fadvise.h" -@@ -323,6 +341,18 @@ +@@ -324,6 +342,18 @@ #include "xstrtol.h" #include "xdectoint.h" @@ -964,7 +995,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -415,7 +445,20 @@ struct COLUMN +@@ -416,7 +446,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -986,7 +1017,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -427,6 +470,7 @@ static void add_line_number (COLUMN *p); +@@ -428,6 +471,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, @@ -994,7 +1025,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c int *number); static void print_files (int number_of_files, char **av); static void init_parameters (int number_of_files); -@@ -440,7 +484,6 @@ static void store_char (char c); +@@ -441,7 +485,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); @@ -1002,7 +1033,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c static void cleanup (void); static void print_sep_string (void); static void separator_string (const char *optarg_S); -@@ -452,7 +495,7 @@ static COLUMN *column_vector; +@@ -453,7 +496,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]. */ @@ -1011,7 +1042,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* Index of the position in buff where the next character will be stored. */ -@@ -556,7 +599,7 @@ static int chars_per_column; +@@ -557,7 +600,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -1020,7 +1051,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... where the leftmost column is 1. */ -@@ -566,7 +609,10 @@ static int chars_per_input_tab = 8; +@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -1032,7 +1063,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -636,7 +682,13 @@ static int line_number; +@@ -637,7 +683,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1047,18 +1078,18 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -689,6 +741,7 @@ static bool use_col_separator = false; +@@ -690,6 +742,7 @@ static bool use_col_separator = false; -a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */ - static char *col_sep_string = (char *) ""; + 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"; -@@ -839,6 +892,13 @@ separator_string (const char *optarg_S) - col_sep_length = (int) strlen (optarg_S); - col_sep_string = xmalloc (col_sep_length + 1); - strcpy (col_sep_string, optarg_S); +@@ -851,6 +904,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) @@ -1069,7 +1100,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c } int -@@ -863,6 +923,21 @@ main (int argc, char **argv) +@@ -875,6 +935,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1090,8 +1121,8 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c + n_files = 0; file_names = (argc > 1 - ? xmalloc ((argc - 1) * sizeof (char *)) -@@ -939,8 +1014,12 @@ main (int argc, char **argv) + ? xnmalloc (argc - 1, sizeof (char *)) +@@ -951,8 +1026,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1106,7 +1137,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* Could check tab width > 0. */ untabify_input = true; break; -@@ -953,8 +1032,12 @@ main (int argc, char **argv) +@@ -965,8 +1044,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1121,7 +1152,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* Could check tab width > 0. */ tabify_output = true; break; -@@ -972,8 +1055,8 @@ main (int argc, char **argv) +@@ -984,8 +1067,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1132,16 +1163,15 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c break; case 'N': skip_count = false; -@@ -997,7 +1080,7 @@ main (int argc, char **argv) - old_s = false; +@@ -1010,6 +1093,7 @@ main (int argc, char **argv) /* Reset an additional input of -s, -S dominates -s */ - col_sep_string = bad_cast (""); -- col_sep_length = 0; -+ col_sep_length = col_sep_width = 0; + col_sep_string = ""; + col_sep_length = 0; ++ col_sep_width = 0; use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err) +@@ -1166,10 +1250,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err) a number. */ static void @@ -1189,7 +1219,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c if (*arg) { long int tmp_long; -@@ -1177,6 +1295,11 @@ static void +@@ -1191,6 +1310,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -1201,7 +1231,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1214,7 +1337,7 @@ init_parameters (int number_of_files) +@@ -1228,7 +1352,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -1210,7 +1240,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1244,11 +1367,11 @@ init_parameters (int number_of_files) +@@ -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. */ @@ -1224,16 +1254,16 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1257,7 +1380,7 @@ init_parameters (int number_of_files) +@@ -1271,7 +1395,7 @@ init_parameters (int number_of_files) } - chars_per_column = (chars_per_line - chars_used_by_number -- - (columns - 1) * col_sep_length) / columns; -+ - (columns - 1) * col_sep_width) / columns; - - if (chars_per_column < 1) - error (EXIT_FAILURE, 0, _("page width too narrow")); -@@ -1275,7 +1398,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); @@ -1242,7 +1272,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c } /* Open the necessary files, -@@ -1383,7 +1506,7 @@ init_funcs (void) +@@ -1402,7 +1526,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -1251,7 +1281,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* This loop takes care of all but the rightmost column. */ -@@ -1417,7 +1540,7 @@ init_funcs (void) +@@ -1436,7 +1560,7 @@ init_funcs (void) } else { @@ -1260,19 +1290,19 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c h_next = h + chars_per_column; } } -@@ -1708,9 +1831,9 @@ static void +@@ -1727,9 +1851,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; -- if (padding_not_printed - col_sep_length > 0) -+ if (padding_not_printed - col_sep_width > 0) +- 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; } -@@ -1981,13 +2104,13 @@ store_char (char c) +@@ -2004,13 +2128,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -1288,7 +1318,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c char *s; int num_width; -@@ -2004,22 +2127,24 @@ add_line_number (COLUMN *p) +@@ -2027,22 +2151,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. */ @@ -1317,7 +1347,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2180,7 +2305,7 @@ print_white_space (void) +@@ -2203,7 +2329,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -1326,15 +1356,15 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c h_old = h_new; } while (++h_old <= goal) -@@ -2200,6 +2325,7 @@ print_sep_string (void) +@@ -2223,6 +2349,7 @@ print_sep_string (void) { - char *s; + char const *s = col_sep_string; int l = col_sep_length; + int not_space_flag; - s = col_sep_string; - -@@ -2213,6 +2339,7 @@ print_sep_string (void) + if (separators_not_printed <= 0) + { +@@ -2234,6 +2361,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -1342,7 +1372,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2226,12 +2353,15 @@ print_sep_string (void) +@@ -2247,12 +2375,15 @@ print_sep_string (void) } else { @@ -1359,7 +1389,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2280,7 +2411,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -1368,7 +1398,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c { if (tabify_output) { -@@ -2283,6 +2413,74 @@ print_char (char c) +@@ -2304,6 +2435,74 @@ print_char (char c) putchar (c); } @@ -1443,19 +1473,19 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2462,9 +2660,9 @@ read_line (COLUMN *p) +@@ -2483,9 +2682,9 @@ read_line (COLUMN *p) align_empty_cols = false; } -- if (padding_not_printed - col_sep_length > 0) -+ if (padding_not_printed - col_sep_width > 0) +- 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; } -@@ -2534,7 +2732,7 @@ print_stored (COLUMN *p) +@@ -2555,7 +2754,7 @@ print_stored (COLUMN *p) int i; int line = p->current_line++; @@ -1464,7 +1494,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2546,7 +2744,7 @@ print_stored (COLUMN *p) +@@ -2567,7 +2766,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -1473,19 +1503,19 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c pad_vertically = true; -@@ -2565,9 +2763,9 @@ print_stored (COLUMN *p) +@@ -2586,9 +2785,9 @@ print_stored (COLUMN *p) } } -- if (padding_not_printed - col_sep_length > 0) -+ if (padding_not_printed - col_sep_width > 0) +- 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; } -@@ -2580,8 +2778,8 @@ print_stored (COLUMN *p) +@@ -2601,8 +2800,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -1496,7 +1526,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c } return true; -@@ -2600,7 +2798,7 @@ print_stored (COLUMN *p) +@@ -2621,7 +2820,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -1505,7 +1535,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c { unsigned char uc = c; char *s = clump_buff; -@@ -2610,10 +2808,10 @@ char_to_clump (char c) +@@ -2631,10 +2830,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -1518,7 +1548,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2694,6 +2892,164 @@ char_to_clump (char c) +@@ -2715,6 +2914,164 @@ char_to_clump (char c) return chars; } @@ -1683,9 +1713,10 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c /* We've just printed some files and need to clean up things before looking for more options and printing the next batch of files. -diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c ---- coreutils-8.24-orig/src/sort.c 2015-06-26 19:05:22.000000000 +0200 -+++ coreutils-8.24/src/sort.c 2015-07-05 09:04:33.032546980 +0200 +diff --git a/src/sort.c b/src/sort.c +index 6d2eec5..f189a0d 100644 +--- a/src/sort.c ++++ b/src/sort.c @@ -29,6 +29,14 @@ #include #include @@ -1700,8 +1731,8 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c + #include "system.h" #include "argmatch.h" - #include "error.h" -@@ -163,14 +171,39 @@ static int decimal_point; + #include "die.h" +@@ -165,14 +173,39 @@ static int decimal_point; /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; @@ -1742,7 +1773,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -344,13 +377,11 @@ static bool reverse; +@@ -346,13 +379,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -1759,7 +1790,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -810,6 +841,46 @@ reap_all (void) +@@ -811,6 +842,46 @@ reap_all (void) reap (-1); } @@ -1806,7 +1837,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* Clean up any remaining temporary files. */ static void -@@ -1254,7 +1325,7 @@ zaptemp (char const *name) +@@ -1255,7 +1326,7 @@ zaptemp (char const *name) free (node); } @@ -1815,7 +1846,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c static int struct_month_cmp (void const *m1, void const *m2) -@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1270,7 +1341,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -1824,7 +1855,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { size_t i; -@@ -1281,7 +1352,7 @@ inittables (void) +@@ -1282,7 +1353,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -1833,7 +1864,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1364,6 +1435,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -1918,7 +1949,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1597,7 +1746,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -1927,7 +1958,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1606,10 +1755,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -1940,7 +1971,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c ++ptr; if (ptr < lim) ++ptr; -@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1635,11 +1784,70 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2012,7 +2043,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1654,10 +1862,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2025,7 +2056,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1703,10 +1911,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2038,7 +2069,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c if (newlim) lim = newlim; } -@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1737,6 +1945,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2169,7 +2200,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* 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 -@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1823,8 +2155,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2194,7 +2225,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c line->keybeg = line_start; } } -@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char const *b) +@@ -1974,7 +2320,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2203,7 +2234,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { while (blanks[to_uchar (*a)]) a++; -@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b) +@@ -1984,6 +2330,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2229,7 +2260,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* 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 once -@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2034,7 +2399,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2238,7 +2269,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2310,15 +2675,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2256,16 +2287,16 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) - bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key) - && !(key->schar || key->echar); +@@ -2452,7 +2816,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) + /* Warn about significant leading blanks. */ + bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ -- if (!gkey_only && tab == TAB_DEFAULT && !line_offset -+ if (!gkey_only && !tab_length && !line_offset - && ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned)) +- 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))) -@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2510,11 +2874,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -2354,7 +2385,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { struct keyfield *key = keylist; -@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2599,7 +3039,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2363,7 +2394,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2715,6 +3155,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -2575,7 +2606,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct line const *b) +@@ -2742,7 +3387,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -2584,7 +2615,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c { /* Note xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4139,6 +4784,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -2592,7 +2623,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c break; case 'g': key->general_numeric = true; -@@ -4199,7 +4845,7 @@ main (int argc, char **argv) +@@ -4218,7 +4864,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2601,7 +2632,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4220,6 +4866,29 @@ main (int argc, char **argv) +@@ -4239,6 +4885,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -2631,7 +2662,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c have_read_stdin = false; inittables (); -@@ -4494,13 +5163,34 @@ main (int argc, char **argv) +@@ -4513,13 +5182,34 @@ main (int argc, char **argv) case 't': { @@ -2641,7 +2672,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c + size_t newtab_length = 1; + strncpy (newtab, optarg, MB_LEN_MAX); + if (! newtab[0]) - error (SORT_FAILURE, 0, _("empty tab")); + die (SORT_FAILURE, 0, _("empty tab")); - if (optarg[1]) +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) @@ -2670,22 +2701,21 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c else { /* Provoke with 'sort -txx'. Complain about -@@ -4511,9 +5201,12 @@ main (int argc, char **argv) - quote (optarg)); +@@ -4530,9 +5220,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)) - error (SORT_FAILURE, 0, _("incompatible tabs")); ++ 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; -@@ -4751,12 +5444,10 @@ main (int argc, char **argv) +@@ -4770,12 +5462,10 @@ main (int argc, char **argv) sort (files, nfiles, outfile, nthreads); } @@ -2697,10 +2727,11 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c -#endif if (have_read_stdin && fclose (stdin) == EOF) - die (_("close failed"), "-"); -diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c ---- coreutils-8.24-orig/src/uniq.c 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/src/uniq.c 2015-07-05 09:04:33.032546980 +0200 + sort_die (_("close failed"), "-"); +diff --git a/src/uniq.c b/src/uniq.c +index 87a0c93..9f755d9 100644 +--- a/src/uniq.c ++++ b/src/uniq.c @@ -21,6 +21,17 @@ #include #include @@ -2719,7 +2750,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -31,9 +42,21 @@ +@@ -32,9 +43,21 @@ #include "stdio--.h" #include "xmemcoll.h" #include "xstrtol.h" @@ -2742,7 +2773,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -143,6 +166,10 @@ enum +@@ -144,6 +167,10 @@ enum GROUP_OPTION = CHAR_MAX + 1 }; @@ -2753,7 +2784,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *msgid) +@@ -260,7 +287,7 @@ size_opt (char const *opt, char const *msgid) return a pointer to the beginning of the line's field to be compared. */ static char * _GL_ATTRIBUTE_PURE @@ -2762,7 +2793,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c { size_t count; char const *lp = line->buffer; -@@ -272,6 +299,83 @@ find_field (struct linebuffer const *line) +@@ -280,6 +307,83 @@ find_field (struct linebuffer const *line) return line->buffer + i; } @@ -2846,7 +2877,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c /* 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. -@@ -280,6 +384,8 @@ find_field (struct linebuffer const *line) +@@ -288,6 +392,8 @@ find_field (struct linebuffer const *line) static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -2855,7 +2886,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -287,14 +393,103 @@ different (char *old, char *new, size_t oldlen, size_t newlen) +@@ -295,14 +401,103 @@ different (char *old, char *new, size_t oldlen, size_t newlen) if (ignore_case) { @@ -2964,7 +2995,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. -@@ -359,19 +554,38 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -367,19 +562,38 @@ check_file (const char *infile, const char *outfile, char delimiter) char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); bool first_group_printed = false; @@ -3003,7 +3034,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c new_group = (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)); -@@ -389,6 +603,10 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -397,6 +611,10 @@ check_file (const char *infile, const char *outfile, char delimiter) SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3014,7 +3045,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c first_group_printed = true; } } -@@ -401,17 +619,26 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -409,17 +627,26 @@ check_file (const char *infile, const char *outfile, char delimiter) size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -3041,7 +3072,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -420,6 +647,14 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -428,6 +655,14 @@ check_file (const char *infile, const char *outfile, char delimiter) } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -3056,7 +3087,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -452,6 +687,9 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -460,6 +695,9 @@ check_file (const char *infile, const char *outfile, char delimiter) SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3066,7 +3097,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c if (!match) match_count = 0; } -@@ -498,6 +736,19 @@ main (int argc, char **argv) +@@ -506,6 +744,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -3086,9 +3117,11 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; -diff -urNp coreutils-8.24-orig/tests/i18n/sort.sh coreutils-8.24/tests/i18n/sort.sh ---- coreutils-8.24-orig/tests/i18n/sort.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.24/tests/i18n/sort.sh 2015-07-05 09:04:33.032546980 +0200 +diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh +new file mode 100644 +index 0000000..26c95de +--- /dev/null ++++ b/tests/i18n/sort.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# Verify sort's multi-byte support. @@ -3119,21 +3152,23 @@ diff -urNp coreutils-8.24-orig/tests/i18n/sort.sh coreutils-8.24/tests/i18n/sort + + +Exit $fail -diff -urNp coreutils-8.24-orig/tests/local.mk coreutils-8.24/tests/local.mk ---- coreutils-8.24-orig/tests/local.mk 2015-07-05 09:00:46.526859558 +0200 -+++ coreutils-8.24/tests/local.mk 2015-07-05 09:04:33.033546987 +0200 -@@ -344,6 +344,8 @@ all_tests = \ +diff --git a/tests/local.mk b/tests/local.mk +index 568944e..192f776 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -350,6 +350,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 \ - tests/misc/sort-month.sh \ -diff -urNp coreutils-8.24-orig/tests/misc/cut.pl coreutils-8.24/tests/misc/cut.pl ---- coreutils-8.24-orig/tests/misc/cut.pl 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/tests/misc/cut.pl 2015-07-05 09:04:33.033546987 +0200 +diff --git a/tests/misc/cut.pl b/tests/misc/cut.pl +index f6f8a56..b426a80 100755 +--- a/tests/misc/cut.pl ++++ b/tests/misc/cut.pl @@ -23,9 +23,11 @@ use strict; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; @@ -3156,10 +3191,11 @@ diff -urNp coreutils-8.24-orig/tests/misc/cut.pl coreutils-8.24/tests/misc/cut.p push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; } push @Tests, @new; -diff -urNp coreutils-8.24-orig/tests/misc/expand.pl coreutils-8.24/tests/misc/expand.pl ---- coreutils-8.24-orig/tests/misc/expand.pl 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/tests/misc/expand.pl 2015-07-05 09:04:33.033546987 +0200 -@@ -23,6 +23,15 @@ use strict; +diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl +index 8a9cad1..9293e39 100755 +--- a/tests/misc/expand.pl ++++ b/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; @@ -3175,8 +3211,17 @@ diff -urNp coreutils-8.24-orig/tests/misc/expand.pl coreutils-8.24/tests/misc/ex my @Tests = ( ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], -@@ -31,6 +40,37 @@ my @Tests = - ['i2', '--tabs=3 -i', {IN=>" \ta\tb"}, {OUT=>" a\tb"}], +@@ -140,6 +149,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}, +@@ -150,6 +161,37 @@ my @Tests = + {ERR => "$prog: tab sizes must be ascending\n"}], ); +if ($mb_locale ne 'C') @@ -3202,7 +3247,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/expand.pl coreutils-8.24/tests/misc/ex + push @new_t, $sub; + push @$t, $sub; + } -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ push @new, ["$test_name-mb", @new_t, {ENV => "LANG=$mb_locale LC_MESSAGES=C"}]; + } + push @Tests, @new; + } @@ -3213,9 +3258,10 @@ diff -urNp coreutils-8.24-orig/tests/misc/expand.pl coreutils-8.24/tests/misc/ex my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.24-orig/tests/misc/fold.pl coreutils-8.24/tests/misc/fold.pl ---- coreutils-8.24-orig/tests/misc/fold.pl 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/tests/misc/fold.pl 2015-07-05 09:04:33.033546987 +0200 +diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl +index 7b192b4..76f073f 100755 +--- a/tests/misc/fold.pl ++++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; (my $program_name = $0) =~ s|.*/||; @@ -3285,9 +3331,10 @@ diff -urNp coreutils-8.24-orig/tests/misc/fold.pl coreutils-8.24/tests/misc/fold -my $prog = 'fold'; my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; -diff -urNp coreutils-8.24-orig/tests/misc/join.pl coreutils-8.24/tests/misc/join.pl ---- coreutils-8.24-orig/tests/misc/join.pl 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/tests/misc/join.pl 2015-07-05 09:04:33.033546987 +0200 +diff --git a/tests/misc/join.pl b/tests/misc/join.pl +index 4d399d8..07f2823 100755 +--- a/tests/misc/join.pl ++++ b/tests/misc/join.pl @@ -25,6 +25,15 @@ my $limits = getlimits (); my $prog = 'join'; @@ -3354,9 +3401,11 @@ diff -urNp coreutils-8.24-orig/tests/misc/join.pl coreutils-8.24/tests/misc/join my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.24-orig/tests/misc/sort-mb-tests.sh coreutils-8.24/tests/misc/sort-mb-tests.sh ---- coreutils-8.24-orig/tests/misc/sort-mb-tests.sh 1970-01-01 01:00:00.000000000 +0100 -+++ coreutils-8.24/tests/misc/sort-mb-tests.sh 2015-07-05 09:04:33.034546995 +0200 +diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh +new file mode 100644 +index 0000000..11836ba +--- /dev/null ++++ b/tests/misc/sort-mb-tests.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# Verify sort's multi-byte support. @@ -3403,9 +3452,10 @@ diff -urNp coreutils-8.24-orig/tests/misc/sort-mb-tests.sh coreutils-8.24/tests/ +compare exp out || { fail=1; cat out; } + +Exit $fail -diff -urNp coreutils-8.24-orig/tests/misc/sort-merge.pl coreutils-8.24/tests/misc/sort-merge.pl ---- coreutils-8.24-orig/tests/misc/sort-merge.pl 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/tests/misc/sort-merge.pl 2015-07-05 09:04:33.034546995 +0200 +diff --git a/tests/misc/sort-merge.pl b/tests/misc/sort-merge.pl +index 23f6ed2..402a987 100755 +--- a/tests/misc/sort-merge.pl ++++ b/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; @@ -3462,9 +3512,10 @@ diff -urNp coreutils-8.24-orig/tests/misc/sort-merge.pl coreutils-8.24/tests/mis my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.24-orig/tests/misc/sort.pl coreutils-8.24/tests/misc/sort.pl ---- coreutils-8.24-orig/tests/misc/sort.pl 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/tests/misc/sort.pl 2015-07-05 09:04:33.034546995 +0200 +diff --git a/tests/misc/sort.pl b/tests/misc/sort.pl +index c3e7f8e..6ecd3ff 100755 +--- a/tests/misc/sort.pl ++++ b/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; @@ -3529,9 +3580,10 @@ diff -urNp coreutils-8.24-orig/tests/misc/sort.pl coreutils-8.24/tests/misc/sort my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.24-orig/tests/misc/unexpand.pl coreutils-8.24/tests/misc/unexpand.pl ---- coreutils-8.24-orig/tests/misc/unexpand.pl 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/tests/misc/unexpand.pl 2015-07-05 09:04:33.034546995 +0200 +diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl +index 6ba6d40..de86723 100755 +--- a/tests/misc/unexpand.pl ++++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); my $prog = 'unexpand'; @@ -3547,8 +3599,8 @@ diff -urNp coreutils-8.24-orig/tests/misc/unexpand.pl coreutils-8.24/tests/misc/ my @Tests = ( ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], -@@ -92,6 +100,37 @@ my @Tests = - {EXIT => 1}, {ERR => "$prog: tab stop value is too large\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') @@ -3585,9 +3637,10 @@ diff -urNp coreutils-8.24-orig/tests/misc/unexpand.pl coreutils-8.24/tests/misc/ my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff -urNp coreutils-8.24-orig/tests/misc/uniq.pl coreutils-8.24/tests/misc/uniq.pl ---- coreutils-8.24-orig/tests/misc/uniq.pl 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/tests/misc/uniq.pl 2015-07-05 09:04:33.035547002 +0200 +diff --git a/tests/misc/uniq.pl b/tests/misc/uniq.pl +index f028036..8eaf59a 100755 +--- a/tests/misc/uniq.pl ++++ b/tests/misc/uniq.pl @@ -23,9 +23,17 @@ my $limits = getlimits (); my $prog = 'uniq'; my $try = "Try '$prog --help' for more information.\n"; @@ -3660,9 +3713,10 @@ diff -urNp coreutils-8.24-orig/tests/misc/uniq.pl coreutils-8.24/tests/misc/uniq @Tests = add_z_variants \@Tests; @Tests = triple_test \@Tests; -diff -urNp coreutils-8.24-orig/tests/pr/pr-tests.pl coreutils-8.24/tests/pr/pr-tests.pl ---- coreutils-8.24-orig/tests/pr/pr-tests.pl 2015-06-26 19:04:19.000000000 +0200 -+++ coreutils-8.24/tests/pr/pr-tests.pl 2015-07-05 09:04:33.035547002 +0200 +diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl +index ec3980a..136657d 100755 +--- a/tests/pr/pr-tests.pl ++++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; my $prog = 'pr'; my $normalize_strerror = "s/': .*/'/"; @@ -3679,9 +3733,9 @@ diff -urNp coreutils-8.24-orig/tests/pr/pr-tests.pl coreutils-8.24/tests/pr/pr-t my @tv = ( # -b option is no longer an official option. But it's still working to -@@ -467,8 +476,48 @@ push @Tests, - {IN=>{3=>"x\ty\tz\n"}}, - {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ]; +@@ -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. @@ -3709,7 +3763,7 @@ diff -urNp coreutils-8.24-orig/tests/pr/pr-tests.pl coreutils-8.24/tests/pr/pr-t + push @$t, $sub; + } + #temporarily skip some failing tests -+ next if ($test_name =~ "col-0" or $test_name =~ "col-inval"); ++ 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; @@ -3728,3 +3782,6 @@ diff -urNp coreutils-8.24-orig/tests/pr/pr-tests.pl coreutils-8.24/tests/pr/pr-t my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; +-- +2.7.4 + diff --git a/coreutils-overflow.patch b/coreutils-overflow.patch index 06059a9..d62b19a 100644 --- a/coreutils-overflow.patch +++ b/coreutils-overflow.patch @@ -1,6 +1,8 @@ ---- coreutils-5.2.1/src/who.c.overflow 2005-05-25 09:59:06.000000000 +0100 -+++ coreutils-5.2.1/src/who.c 2005-05-25 10:00:31.000000000 +0100 -@@ -79,7 +79,7 @@ +diff --git a/src/who.c b/src/who.c +index 55733b4..3ad4774 100644 +--- a/src/who.c ++++ b/src/who.c +@@ -81,7 +81,7 @@ # define UT_TYPE_NEW_TIME(U) false #endif diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 9f45177..9f780cc 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,15 +1,17 @@ -diff -urNp coreutils-8.21-orig/man/chcon.x coreutils-8.21/man/chcon.x ---- coreutils-8.21-orig/man/chcon.x 2011-08-23 15:44:01.000000000 +0200 -+++ coreutils-8.21/man/chcon.x 2013-02-15 14:31:58.937482694 +0100 +diff --git a/man/chcon.x b/man/chcon.x +index 8c1ff6f..c84fb96 100644 +--- a/man/chcon.x ++++ b/man/chcon.x @@ -1,4 +1,4 @@ [NAME] -chcon \- change file security context +chcon \- change file SELinux security context [DESCRIPTION] .\" Add any additional description here -diff -urNp coreutils-8.21-orig/man/runcon.x coreutils-8.21/man/runcon.x ---- coreutils-8.21-orig/man/runcon.x 2011-08-23 15:44:01.000000000 +0200 -+++ coreutils-8.21/man/runcon.x 2013-02-15 14:31:58.938486496 +0100 +diff --git a/man/runcon.x b/man/runcon.x +index d2df13e..5c5f5d8 100644 +--- a/man/runcon.x ++++ b/man/runcon.x @@ -1,5 +1,5 @@ [NAME] -runcon \- run command with specified security context @@ -17,10 +19,11 @@ diff -urNp coreutils-8.21-orig/man/runcon.x coreutils-8.21/man/runcon.x [DESCRIPTION] Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, -diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c ---- coreutils-8.21-orig/src/cp.c 2013-02-07 10:37:05.000000000 +0100 -+++ coreutils-8.21/src/cp.c 2013-02-15 14:31:58.945468929 +0100 -@@ -202,6 +202,9 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ +diff --git a/src/cp.c b/src/cp.c +index 1b528c6..25dbb88 100644 +--- a/src/cp.c ++++ b/src/cp.c +@@ -203,6 +203,9 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ all\n\ "), stdout); fputs (_("\ @@ -30,16 +33,16 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ --parents use full source file name under DIRECTORY\n\ "), stdout); -@@ -943,7 +946,7 @@ main (int argc, char **argv) - we'll actually use backup_suffix_string. */ - backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); +@@ -929,7 +932,7 @@ main (int argc, char **argv) + selinux_enabled = (0 < is_selinux_enabled ()); + cp_option_init (&x); - while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ", + while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ", long_opts, NULL)) != -1) { -@@ -991,6 +994,17 @@ main (int argc, char **argv) +@@ -977,6 +980,17 @@ main (int argc, char **argv) copy_contents = true; break; @@ -57,10 +60,11 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -diff -urNp coreutils-8.21-orig/src/id.c coreutils-8.21/src/id.c ---- coreutils-8.21-orig/src/id.c 2013-01-31 01:46:24.000000000 +0100 -+++ coreutils-8.21/src/id.c 2013-02-15 14:31:58.946469154 +0100 -@@ -113,7 +113,7 @@ int +diff --git a/src/id.c b/src/id.c +index 05d98a5..d6eb002 100644 +--- a/src/id.c ++++ b/src/id.c +@@ -114,7 +114,7 @@ int main (int argc, char **argv) { int optc; @@ -69,28 +73,29 @@ diff -urNp coreutils-8.21-orig/src/id.c coreutils-8.21/src/id.c bool smack_enabled = is_smack_enabled (); bool opt_zero = false; char *pw_name = NULL; -diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c ---- coreutils-8.21-orig/src/install.c 2013-02-07 10:37:05.000000000 +0100 -+++ coreutils-8.21/src/install.c 2013-02-15 14:31:58.948469440 +0100 -@@ -649,7 +649,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ +diff --git a/src/install.c b/src/install.c +index d79d597..437889a 100644 +--- a/src/install.c ++++ b/src/install.c +@@ -673,7 +673,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ - --preserve-context preserve SELinux security context\n\ + -P, --preserve-context preserve SELinux security context (-P deprecated)\n\ -Z set SELinux security context of destination\n\ - file to default type\n\ + file and each created directory to default type\n\ --context[=CTX] like -Z, or if CTX is specified then set the\n\ -@@ -817,7 +817,7 @@ main (int argc, char **argv) - we'll actually use backup_suffix_string. */ - backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); +@@ -824,7 +824,7 @@ main (int argc, char **argv) + dir_arg = false; + umask (0); - while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z", long_options, + while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z", long_options, NULL)) != -1) { switch (optc) -@@ -878,6 +878,8 @@ main (int argc, char **argv) +@@ -885,6 +885,8 @@ main (int argc, char **argv) no_target_directory = true; break; @@ -99,7 +104,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c case PRESERVE_CONTEXT_OPTION: if (! selinux_enabled) { -@@ -885,6 +887,10 @@ main (int argc, char **argv) +@@ -892,6 +894,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } diff --git a/coreutils-selinuxmanpages.patch b/coreutils-selinuxmanpages.patch index 1540613..c3eb1a8 100644 --- a/coreutils-selinuxmanpages.patch +++ b/coreutils-selinuxmanpages.patch @@ -1,7 +1,8 @@ -diff -urNp coreutils-6.10-orig/doc/coreutils.texi coreutils-6.10/doc/coreutils.texi ---- coreutils-6.10-orig/doc/coreutils.texi 2008-04-07 17:52:11.000000000 +0200 -+++ coreutils-6.10/doc/coreutils.texi 2008-04-07 18:01:43.000000000 +0200 -@@ -8002,6 +8002,11 @@ done +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 47e4480..cff2ead 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -8083,6 +8083,11 @@ done exit $fail @end example diff --git a/coreutils.spec b/coreutils.spec index c5a835a..fd58008 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,12 +1,11 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.25 -Release: 17%{?dist} +Version: 8.26 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz -Source2: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig Source50: supported_utils Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh @@ -17,15 +16,6 @@ Source10: coreutils-find-requires.sh %global __find_provides %{_rpmconfigdir}/find-provides %global __find_requires %{SOURCE10} %{_rpmconfigdir}/find-requires -# From upstream -Patch952: coreutils-8.25-intall-Z-selinux.patch -# fix 'sort -h -k' in locales that use blank as thousands separator (#1355780) -Patch953: coreutils-8.25-sort-thousands-sep.patch -# ls: allow interruption when reading slow directories (#1365933) -Patch954: coreutils-8.25-ls-signal.patch -# md5sum,sha*sum: fix --ignore-missing with checksums starting with 00 -Patch955: coreutils-8.25-sum-ignore-missing.patch - # Our patches #general patch to workaround koji build system issues Patch100: coreutils-6.10-configuration.patch @@ -213,12 +203,6 @@ tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman -%patch952 -p1 - -# upstream patches -%patch953 -p1 -%patch954 -p1 -%patch955 -p1 chmod a+x \ tests/df/direct.sh \ @@ -348,6 +332,9 @@ fi %license COPYING %changelog +* Thu Dec 01 2016 Kamil Dudka - 8.26-1 +- new upstream release 8.26 + * Mon Oct 31 2016 Kamil Dudka - 8.25-17 - md5sum,sha*sum: fix --ignore-missing with checksums starting with 00 diff --git a/sources b/sources index 52af064..becdeb6 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -070e43ba7f618d747414ef56ab248a48 coreutils-8.25.tar.xz -eb5694f81fd88ccf16b68ed80935b10f coreutils-8.25.tar.xz.sig +d5aa2072f662d4118b9f4c63b94601a6 coreutils-8.26.tar.xz diff --git a/supported_utils b/supported_utils index c2aed28..8105ccf 100644 --- a/supported_utils +++ b/supported_utils @@ -1,4 +1,5 @@ %{_bindir}/arch +%{_bindir}/b2sum %{_bindir}/basename %{_bindir}/cat %{_bindir}/chgrp From 8d346246a75ec5d65859d546f28dc66235b2ea77 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 2 Dec 2016 11:08:45 +0100 Subject: [PATCH 329/523] disable the test-lock gnulib test prone to deadlock See https://lists.gnu.org/archive/html/bug-gnulib/2015-07/msg00033.html and https://libvirt.org/git/?p=libvirt.git;a=commitdiff;h=25fb4c6 for some context. --- coreutils-8.26-test-lock.patch | 35 ++++++++++++++++++++++++++++++++++ coreutils.spec | 5 ++++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.26-test-lock.patch diff --git a/coreutils-8.26-test-lock.patch b/coreutils-8.26-test-lock.patch new file mode 100644 index 0000000..3f2603e --- /dev/null +++ b/coreutils-8.26-test-lock.patch @@ -0,0 +1,35 @@ +From 812480a9fb21b26f2e705b992ce75810f36d08c9 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 2 Dec 2016 10:12:09 +0100 +Subject: [PATCH] disable the test-lock gnulib test prone to deadlock + +See https://lists.gnu.org/archive/html/bug-gnulib/2015-07/msg00033.html +and https://libvirt.org/git/?p=libvirt.git;a=commitdiff;h=25fb4c6 for +some context. +--- + gnulib-tests/gnulib.mk | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk +index 8f32431..c9943d8 100644 +--- a/gnulib-tests/gnulib.mk ++++ b/gnulib-tests/gnulib.mk +@@ -1207,15 +1207,6 @@ EXTRA_DIST += test-localename.c macros.h + + ## end gnulib module localename-tests + +-## begin gnulib module lock-tests +- +-TESTS += test-lock +-check_PROGRAMS += test-lock +-test_lock_LDADD = $(LDADD) @LIBMULTITHREAD@ @YIELD_LIB@ +-EXTRA_DIST += test-lock.c +- +-## end gnulib module lock-tests +- + ## begin gnulib module lseek-tests + + TESTS += test-lseek.sh +-- +2.7.4 + diff --git a/coreutils.spec b/coreutils.spec index fd58008..e5e7f26 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -16,7 +16,9 @@ Source10: coreutils-find-requires.sh %global __find_provides %{_rpmconfigdir}/find-provides %global __find_requires %{SOURCE10} %{_rpmconfigdir}/find-requires -# Our patches +# disable the test-lock gnulib test prone to deadlock +Patch1: coreutils-8.26-test-lock.patch + #general patch to workaround koji build system issues Patch100: coreutils-6.10-configuration.patch #add note about no difference between binary/text mode on Linux - md5sum manpage @@ -174,6 +176,7 @@ including documentation and translations. tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null # Our patches +%patch1 -p1 %patch100 -p1 -b .configure %patch101 -p1 -b .manpages %patch102 -p1 From 59a39fa268d977a7dab581ab51c5465ccc0ebe2e Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 2 Dec 2016 13:27:35 +0100 Subject: [PATCH 330/523] apply patches automatically to ease maintenance --- coreutils-i18n-cut.patch | 2 ++ coreutils.spec | 51 ++++++++-------------------------------- 2 files changed, 12 insertions(+), 41 deletions(-) diff --git a/coreutils-i18n-cut.patch b/coreutils-i18n-cut.patch index f680df6..f4015d1 100644 --- a/coreutils-i18n-cut.patch +++ b/coreutils-i18n-cut.patch @@ -1,3 +1,5 @@ +(sb) lin18nux/lsb compliance - cut - not stable enough, not applied + --- coreutils-8.24/src/cut.c 2015-06-26 19:05:22.000000000 +0200 +++ cut.c 2016-01-15 10:15:04.863804121 +0100 @@ -28,6 +28,11 @@ diff --git a/coreutils.spec b/coreutils.spec index e5e7f26..bf783b9 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.26 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -41,8 +41,6 @@ Patch713: coreutils-4.5.3-langinfo.patch Patch800: coreutils-i18n.patch # (sb) lin18nux/lsb compliance - expand/unexpand Patch801: coreutils-i18n-expand-unexpand.patch -# (sb) lin18nux/lsb compliance - cut - not stable enough, not applied -Patch802: coreutils-i18n-cut.patch # i18n patch for cut - old version - used Patch804: coreutils-i18n-cut-old.patch # The unexpand patch above is not correct. Sent to the patch authors @@ -170,49 +168,17 @@ Optional though recommended components, including documentation and translations. %prep -%setup -q +%autosetup -N # will be modified by coreutils-8.25-DIR_COLORS.patch tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null -# Our patches -%patch1 -p1 -%patch100 -p1 -b .configure -%patch101 -p1 -b .manpages -%patch102 -p1 -%patch103 -p1 -b .sysinfo -%patch104 -p1 -b .dfdirect -%patch107 -p1 -b .mkdirmode +# apply all patches +%autopatch -p1 -# sh-utils -%patch703 -p1 -b .dateman -%patch713 -p1 -b .langinfo - -# li18nux/lsb -%patch800 -p1 -b .i18n -%patch801 -p1 -b .i18n-expand -#%%patch802 -p1 -b .i18n-cut -%patch803 -p1 -b .i18n-fix-expand -%patch804 -p1 -b .i18n-cutold -%patch805 -p1 -b .i18n-fix2-expand-unexpand -%patch806 -p1 -b .i18n-BOM-expand-unexpand -%patch807 -p1 - -# Coreutils -%patch908 -p1 -b .getgrouplist -%patch912 -p1 -b .overflow -%patch913 -p1 -b .testoff - -#SELinux -%patch950 -p1 -b .selinux -%patch951 -p1 -b .selinuxman - -chmod a+x \ - tests/df/direct.sh \ - tests/install/install-Z-selinux.sh \ - tests/misc/sort-h-thousands-sep.sh \ - tests/misc/sort-mb-tests.sh \ - || : +(echo ">>> Fixing permissions on tests") 2>/dev/null +find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+' +(echo "<<< done") 2>/dev/null #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -335,6 +301,9 @@ fi %license COPYING %changelog +* Fri Dec 02 2016 Kamil Dudka - 8.26-2 +- apply patches automatically to ease maintenance + * Thu Dec 01 2016 Kamil Dudka - 8.26-1 - new upstream release 8.26 From a4f03c6bc0685f084801cc49cdd8be2715f06632 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 15 Dec 2016 10:38:07 +0100 Subject: [PATCH 331/523] drop build fixes no longer needed --- coreutils-6.10-configuration.patch | 218 -------------------------- coreutils-8.22-temporarytestoff.patch | 13 -- coreutils.spec | 9 +- 3 files changed, 4 insertions(+), 236 deletions(-) delete mode 100644 coreutils-6.10-configuration.patch delete mode 100644 coreutils-8.22-temporarytestoff.patch diff --git a/coreutils-6.10-configuration.patch b/coreutils-6.10-configuration.patch deleted file mode 100644 index c34fd99..0000000 --- a/coreutils-6.10-configuration.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 54ef056964da3d0987afd9f1e96b9419db0d653a Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 1 Dec 2016 14:32:46 +0100 -Subject: [PATCH] coreutils-6.10-configuration.patch - -TODO: check whether still necessary ---- - gnulib-tests/gnulib.mk | 60 +++++++++++++++++++++---------------------- - man/local.mk | 2 +- - tests/df/skip-duplicates.sh | 3 +++ - tests/local.mk | 2 +- - tests/misc/nohup.sh | 2 ++ - tests/touch/no-dereference.sh | 2 ++ - 6 files changed, 39 insertions(+), 32 deletions(-) - -diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk -index fee978f..8f32431 100644 ---- a/gnulib-tests/gnulib.mk -+++ b/gnulib-tests/gnulib.mk -@@ -279,9 +279,9 @@ EXTRA_DIST += nap.h test-chown.h test-chown.c signature.h macros.h - - ## begin gnulib module cloexec-tests - --TESTS += test-cloexec --check_PROGRAMS += test-cloexec --EXTRA_DIST += test-cloexec.c macros.h -+#TESTS += test-cloexec -+#check_PROGRAMS += test-cloexec -+#EXTRA_DIST += test-cloexec.c macros.h - - ## end gnulib module cloexec-tests - -@@ -392,9 +392,9 @@ EXTRA_DIST += test-dup.c signature.h macros.h - - ## begin gnulib module dup2-tests - --TESTS += test-dup2 --check_PROGRAMS += test-dup2 --EXTRA_DIST += test-dup2.c signature.h macros.h -+#TESTS += test-dup2 -+#check_PROGRAMS += test-dup2 -+#EXTRA_DIST += test-dup2.c signature.h macros.h - - ## end gnulib module dup2-tests - -@@ -453,10 +453,10 @@ EXTRA_DIST += test-fadvise.c - - ## begin gnulib module fchdir-tests - --TESTS += test-fchdir --check_PROGRAMS += test-fchdir --test_fchdir_LDADD = $(LDADD) $(LIBINTL) --EXTRA_DIST += test-fchdir.c signature.h macros.h -+#TESTS += test-fchdir -+#check_PROGRAMS += test-fchdir -+#test_fchdir_LDADD = $(LDADD) $(LIBINTL) -+#EXTRA_DIST += test-fchdir.c signature.h macros.h - - ## end gnulib module fchdir-tests - -@@ -900,9 +900,9 @@ EXTRA_DIST += test-getloadavg.c signature.h - - ## begin gnulib module getlogin-tests - --TESTS += test-getlogin --check_PROGRAMS += test-getlogin --EXTRA_DIST += test-getlogin.c signature.h macros.h -+#TESTS += test-getlogin -+#check_PROGRAMS += test-getlogin -+#EXTRA_DIST += test-getlogin.c signature.h macros.h - - ## end gnulib module getlogin-tests - -@@ -1148,10 +1148,10 @@ EXTRA_DIST += test-link.h test-link.c signature.h macros.h - - ## begin gnulib module linkat-tests - --TESTS += test-linkat --check_PROGRAMS += test-linkat --test_linkat_LDADD = $(LDADD) @LIBINTL@ --EXTRA_DIST += test-link.h test-linkat.c signature.h macros.h -+#TESTS += test-linkat -+#check_PROGRAMS += test-linkat -+#test_linkat_LDADD = $(LDADD) @LIBINTL@ -+#EXTRA_DIST += test-link.h test-linkat.c signature.h macros.h - - ## end gnulib module linkat-tests - -@@ -1360,9 +1360,9 @@ EXTRA_DIST += test-memcoll.c macros.h - - ## begin gnulib module memrchr-tests - --TESTS += test-memrchr --check_PROGRAMS += test-memrchr --EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h -+#TESTS += test-memrchr -+#check_PROGRAMS += test-memrchr -+#EXTRA_DIST += test-memrchr.c zerosize-ptr.h signature.h macros.h - - ## end gnulib module memrchr-tests - -@@ -1913,9 +1913,9 @@ EXTRA_DIST += test-statat.c - - ## begin gnulib module stdalign-tests - --TESTS += test-stdalign --check_PROGRAMS += test-stdalign --EXTRA_DIST += test-stdalign.c macros.h -+#TESTS += test-stdalign -+#check_PROGRAMS += test-stdalign -+#EXTRA_DIST += test-stdalign.c macros.h - - ## end gnulib module stdalign-tests - -@@ -2270,9 +2270,9 @@ EXTRA_DIST += test-uname.c signature.h macros.h - - ## begin gnulib module unistd-safer-tests - --TESTS += test-dup-safer --check_PROGRAMS += test-dup-safer --EXTRA_DIST += test-dup-safer.c macros.h -+#TESTS += test-dup-safer -+#check_PROGRAMS += test-dup-safer -+#EXTRA_DIST += test-dup-safer.c macros.h - - ## end gnulib module unistd-safer-tests - -@@ -2368,10 +2368,10 @@ EXTRA_DIST += test-userspec.c - - ## begin gnulib module utimens-tests - --TESTS += test-utimens --check_PROGRAMS += test-utimens --test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_NANOSLEEP) @LIBINTL@ --EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h -+#TESTS += test-utimens -+#check_PROGRAMS += test-utimens -+#test_utimens_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_NANOSLEEP) @LIBINTL@ -+#EXTRA_DIST += nap.h test-futimens.h test-lutimens.h test-utimens.h test-utimens-common.h test-utimens.c macros.h - - ## end gnulib module utimens-tests - -diff --git a/man/local.mk b/man/local.mk -index a39bb65..535690c 100644 ---- a/man/local.mk -+++ b/man/local.mk -@@ -41,7 +41,7 @@ distclean-local: - test x$(srcdir) = x$(builddir) || rm -f $(ALL_MANS) - - # Dependencies common to all man pages. Updated below. --mandeps = -+mandeps = $(PROGRAMS) - - # Depend on this to get version number changes. - mandeps += .version -diff --git a/tests/df/skip-duplicates.sh b/tests/df/skip-duplicates.sh -index f349263..9854f8d 100755 ---- a/tests/df/skip-duplicates.sh -+++ b/tests/df/skip-duplicates.sh -@@ -26,6 +26,9 @@ require_gcc_shared_ - df --local --output=target >LOCAL_FS || skip_ 'df fails' - grep '^/$' LOCAL_FS || skip_ 'no root file system found' - -+# mark it expensive, to temporarily skip the test in koji -+expensive_ -+ - # Get real targets to substitute for /NONROOT and /REMOTE below. - export CU_NONROOT_FS=$(grep /. LOCAL_FS | head -n1) - export CU_REMOTE_FS=$(grep /. LOCAL_FS | tail -n+2 | head -n1) -diff --git a/tests/local.mk b/tests/local.mk -index 3335002..568944e 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -134,6 +134,7 @@ all_root_tests = \ - tests/rm/no-give-up.sh \ - tests/rm/one-file-system.sh \ - tests/rm/read-only.sh \ -+ tests/tail-2/inotify-hash-abuse.sh \ - tests/tail-2/append-only.sh \ - tests/touch/now-owned-by-other.sh - -@@ -168,7 +169,6 @@ all_tests = \ - tests/cp/link-heap.sh \ - tests/cp/no-ctx.sh \ - tests/misc/tty-eof.pl \ -- tests/tail-2/inotify-hash-abuse.sh \ - tests/tail-2/inotify-hash-abuse2.sh \ - tests/tail-2/F-vs-missing.sh \ - tests/tail-2/F-vs-rename.sh \ -diff --git a/tests/misc/nohup.sh b/tests/misc/nohup.sh -index 1b43b60..3fd29e7 100755 ---- a/tests/misc/nohup.sh -+++ b/tests/misc/nohup.sh -@@ -19,6 +19,8 @@ - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ nohup - -+#mark it expensive, to temporarily skip the test in koji -+expensive_ - - nohup sh -c 'echo stdout; echo stderr 1>&2' 2>err || fail=1 - -diff --git a/tests/touch/no-dereference.sh b/tests/touch/no-dereference.sh -index 7994638..72b2222 100755 ---- a/tests/touch/no-dereference.sh -+++ b/tests/touch/no-dereference.sh -@@ -42,6 +42,8 @@ test -f nowhere && fail=1 - grep '^#define HAVE_UTIMENSAT 1' "$CONFIG_HEADER" > /dev/null || - grep '^#define HAVE_LUTIMES 1' "$CONFIG_HEADER" > /dev/null || - skip_ 'this system lacks the utimensat function' -+grep '^#define HAVE_WORKINGKOJI 1' "$CONFIG_HEADER" > /dev/null || -+ skip_ 'rest of the test disabled due to koji lack of utimensat function' - - # Changing time of dangling symlink is okay. - # Skip the test if this fails, but the error text corresponds to --- -2.7.4 - diff --git a/coreutils-8.22-temporarytestoff.patch b/coreutils-8.22-temporarytestoff.patch deleted file mode 100644 index c95343b..0000000 --- a/coreutils-8.22-temporarytestoff.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -urNp coreutils-8.22-orig/tests/df/df-symlink.sh coreutils-8.22/tests/df/df-symlink.sh ---- coreutils-8.22-orig/tests/df/df-symlink.sh 2013-12-04 15:48:30.000000000 +0100 -+++ coreutils-8.22/tests/df/df-symlink.sh 2013-12-14 18:20:15.822594995 +0100 -@@ -18,6 +18,9 @@ - - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ df -+#df doesn't work correctly on symlinks when on LVM/LUKS filesystem, therefore -+#marking expensive_ to disable by default -+expensive_ - - disk=$(df --out=source '.' | tail -n1) || - skip_ "cannot determine '.' file system" diff --git a/coreutils.spec b/coreutils.spec index bf783b9..21de5eb 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.26 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -19,8 +19,6 @@ Source10: coreutils-find-requires.sh # disable the test-lock gnulib test prone to deadlock Patch1: coreutils-8.26-test-lock.patch -#general patch to workaround koji build system issues -Patch100: coreutils-6.10-configuration.patch #add note about no difference between binary/text mode on Linux - md5sum manpage Patch101: coreutils-6.10-manpages.patch # downstream changes to default DIR_COLORS @@ -56,8 +54,6 @@ Patch807: coreutils-i18n-sort-human.patch Patch908: coreutils-getgrouplist.patch #Prevent buffer overflow in who(1) (bug #158405). Patch912: coreutils-overflow.patch -#Temporarily disable df symlink test, failing -Patch913: coreutils-8.22-temporarytestoff.patch #SELINUX Patch - implements Redhat changes #(upstream did some SELinux implementation unlike with RedHat patch) @@ -301,6 +297,9 @@ fi %license COPYING %changelog +* Thu Dec 15 2016 Kamil Dudka - 8.26-3 +- drop build fixes no longer needed + * Fri Dec 02 2016 Kamil Dudka - 8.26-2 - apply patches automatically to ease maintenance From c168f3b3431ee8e57653d93c9c09e50935e4beb0 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 15 Dec 2016 10:45:14 +0100 Subject: [PATCH 332/523] merge coreutils-selinuxmanpages.patch into coreutils-selinux.patch It does not make any sense to apply them separately. --- coreutils-selinux.patch | 29 ++++++++++++++++------------- coreutils-selinuxmanpages.patch | 16 ---------------- coreutils.spec | 1 - 3 files changed, 16 insertions(+), 30 deletions(-) delete mode 100644 coreutils-selinuxmanpages.patch diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 9f780cc..cee4f7c 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -60,19 +60,22 @@ index 1b528c6..25dbb88 100644 case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -diff --git a/src/id.c b/src/id.c -index 05d98a5..d6eb002 100644 ---- a/src/id.c -+++ b/src/id.c -@@ -114,7 +114,7 @@ int - main (int argc, char **argv) - { - int optc; -- int selinux_enabled = (is_selinux_enabled () > 0); -+ bool selinux_enabled = (is_selinux_enabled () > 0); - bool smack_enabled = is_smack_enabled (); - bool opt_zero = false; - char *pw_name = NULL; +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 47e4480..cff2ead 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -8083,6 +8083,11 @@ done + exit $fail + @end example + ++@item -c ++@cindex SELinux security context information, preserving ++Preserve SELinux security context of the original files if possible. ++Some file systems don't support storing of SELinux security context. ++ + @item --copy-contents + @cindex directories, copying recursively + @cindex copying directories recursively diff --git a/src/install.c b/src/install.c index d79d597..437889a 100644 --- a/src/install.c diff --git a/coreutils-selinuxmanpages.patch b/coreutils-selinuxmanpages.patch deleted file mode 100644 index c3eb1a8..0000000 --- a/coreutils-selinuxmanpages.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 47e4480..cff2ead 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -8083,6 +8083,11 @@ done - exit $fail - @end example - -+@item -c -+@cindex SELinux security context information, preserving -+Preserve SELinux security context of the original files if possible. -+Some file systems don't support storing of SELinux security context. -+ - @item --copy-contents - @cindex directories, copying recursively - @cindex copying directories recursively diff --git a/coreutils.spec b/coreutils.spec index 21de5eb..860a5cd 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -58,7 +58,6 @@ Patch912: coreutils-overflow.patch #SELINUX Patch - implements Redhat changes #(upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch -Patch951: coreutils-selinuxmanpages.patch Conflicts: filesystem < 3 # To avoid clobbering installs From b3b3da0cdf2777c6b06f95b5f267ffe65d97a32a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 2 Jan 2017 09:58:50 +0100 Subject: [PATCH 333/523] use upstream patch for gnulib's test-lock ... instead of disabling it --- coreutils-8.26-test-lock.patch | 219 +++++++++++++++++++++++++++++---- coreutils.spec | 5 +- 2 files changed, 197 insertions(+), 27 deletions(-) diff --git a/coreutils-8.26-test-lock.patch b/coreutils-8.26-test-lock.patch index 3f2603e..43e477e 100644 --- a/coreutils-8.26-test-lock.patch +++ b/coreutils-8.26-test-lock.patch @@ -1,35 +1,202 @@ -From 812480a9fb21b26f2e705b992ce75810f36d08c9 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Fri, 2 Dec 2016 10:12:09 +0100 -Subject: [PATCH] disable the test-lock gnulib test prone to deadlock +From 4f6cb65ce4d643aca0c6bf7db2e8b32c0d08eb89 Mon Sep 17 00:00:00 2001 +From: Bruno Haible +Date: Sat, 24 Dec 2016 18:21:59 +0100 +Subject: [PATCH] lock test: Fix performance problem on multi-core machines. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit -See https://lists.gnu.org/archive/html/bug-gnulib/2015-07/msg00033.html -and https://libvirt.org/git/?p=libvirt.git;a=commitdiff;h=25fb4c6 for -some context. +* tests/test-lock.c (USE_VOLATILE): New macro. +(struct atomic_int): New type. +(init_atomic_int, get_atomic_int_value, set_atomic_int_value): New +functions. +(lock_checker_done, rwlock_checker_done, reclock_checker_done): Define +as 'struct atomic_int'. +(lock_checker_thread, test_lock, rwlock_checker_thread, test_rwlock, +reclock_checker_thread, test_recursive_lock): Use the new functions. +Reported by Eric Blake in +https://www.redhat.com/archives/libvir-list/2012-March/msg00854.html +and by Pádraig Brady in +http://lists.gnu.org/archive/html/bug-gnulib/2016-12/msg00117.html. + +Upstream-commit: 480d374e596a0ee3fed168ab42cd84c313ad3c89 +Signed-off-by: Kamil Dudka --- - gnulib-tests/gnulib.mk | 9 --------- - 1 file changed, 9 deletions(-) + gnulib-tests/test-lock.c | 79 ++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 67 insertions(+), 12 deletions(-) -diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk -index 8f32431..c9943d8 100644 ---- a/gnulib-tests/gnulib.mk -+++ b/gnulib-tests/gnulib.mk -@@ -1207,15 +1207,6 @@ EXTRA_DIST += test-localename.c macros.h +diff --git a/gnulib-tests/test-lock.c b/gnulib-tests/test-lock.c +index cb734b4..aa6de27 100644 +--- a/gnulib-tests/test-lock.c ++++ b/gnulib-tests/test-lock.c +@@ -50,6 +50,13 @@ + Uncomment this to see if the operating system has a fair scheduler. */ + #define EXPLICIT_YIELD 1 - ## end gnulib module localename-tests ++/* Whether to use 'volatile' on some variables that communicate information ++ between threads. If set to 0, a lock is used to protect these variables. ++ If set to 1, 'volatile' is used; this is theoretically equivalent but can ++ lead to much slower execution (e.g. 30x slower total run time on a 40-core ++ machine. */ ++#define USE_VOLATILE 0 ++ + /* Whether to print debugging messages. */ + #define ENABLE_DEBUGGING 0 --## begin gnulib module lock-tests -- --TESTS += test-lock --check_PROGRAMS += test-lock --test_lock_LDADD = $(LDADD) @LIBMULTITHREAD@ @YIELD_LIB@ --EXTRA_DIST += test-lock.c -- --## end gnulib module lock-tests -- - ## begin gnulib module lseek-tests +@@ -103,6 +110,51 @@ + # define yield() + #endif - TESTS += test-lseek.sh ++#if USE_VOLATILE ++struct atomic_int { ++ volatile int value; ++}; ++static void ++init_atomic_int (struct atomic_int *ai) ++{ ++} ++static int ++get_atomic_int_value (struct atomic_int *ai) ++{ ++ return ai->value; ++} ++static void ++set_atomic_int_value (struct atomic_int *ai, int new_value) ++{ ++ ai->value = new_value; ++} ++#else ++struct atomic_int { ++ gl_lock_define (, lock) ++ int value; ++}; ++static void ++init_atomic_int (struct atomic_int *ai) ++{ ++ gl_lock_init (ai->lock); ++} ++static int ++get_atomic_int_value (struct atomic_int *ai) ++{ ++ gl_lock_lock (ai->lock); ++ int ret = ai->value; ++ gl_lock_unlock (ai->lock); ++ return ret; ++} ++static void ++set_atomic_int_value (struct atomic_int *ai, int new_value) ++{ ++ gl_lock_lock (ai->lock); ++ ai->value = new_value; ++ gl_lock_unlock (ai->lock); ++} ++#endif ++ + #define ACCOUNT_COUNT 4 + + static int account[ACCOUNT_COUNT]; +@@ -170,12 +222,12 @@ lock_mutator_thread (void *arg) + return NULL; + } + +-static volatile int lock_checker_done; ++static struct atomic_int lock_checker_done; + + static void * + lock_checker_thread (void *arg) + { +- while (!lock_checker_done) ++ while (get_atomic_int_value (&lock_checker_done) == 0) + { + dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ()); + gl_lock_lock (my_lock); +@@ -200,7 +252,8 @@ test_lock (void) + /* Initialization. */ + for (i = 0; i < ACCOUNT_COUNT; i++) + account[i] = 1000; +- lock_checker_done = 0; ++ init_atomic_int (&lock_checker_done); ++ set_atomic_int_value (&lock_checker_done, 0); + + /* Spawn the threads. */ + checkerthread = gl_thread_create (lock_checker_thread, NULL); +@@ -210,7 +263,7 @@ test_lock (void) + /* Wait for the threads to terminate. */ + for (i = 0; i < THREAD_COUNT; i++) + gl_thread_join (threads[i], NULL); +- lock_checker_done = 1; ++ set_atomic_int_value (&lock_checker_done, 1); + gl_thread_join (checkerthread, NULL); + check_accounts (); + } +@@ -254,12 +307,12 @@ rwlock_mutator_thread (void *arg) + return NULL; + } + +-static volatile int rwlock_checker_done; ++static struct atomic_int rwlock_checker_done; + + static void * + rwlock_checker_thread (void *arg) + { +- while (!rwlock_checker_done) ++ while (get_atomic_int_value (&rwlock_checker_done) == 0) + { + dbgprintf ("Checker %p before check rdlock\n", gl_thread_self_pointer ()); + gl_rwlock_rdlock (my_rwlock); +@@ -284,7 +337,8 @@ test_rwlock (void) + /* Initialization. */ + for (i = 0; i < ACCOUNT_COUNT; i++) + account[i] = 1000; +- rwlock_checker_done = 0; ++ init_atomic_int (&rwlock_checker_done); ++ set_atomic_int_value (&rwlock_checker_done, 0); + + /* Spawn the threads. */ + for (i = 0; i < THREAD_COUNT; i++) +@@ -295,7 +349,7 @@ test_rwlock (void) + /* Wait for the threads to terminate. */ + for (i = 0; i < THREAD_COUNT; i++) + gl_thread_join (threads[i], NULL); +- rwlock_checker_done = 1; ++ set_atomic_int_value (&rwlock_checker_done, 1); + for (i = 0; i < THREAD_COUNT; i++) + gl_thread_join (checkerthreads[i], NULL); + check_accounts (); +@@ -356,12 +410,12 @@ reclock_mutator_thread (void *arg) + return NULL; + } + +-static volatile int reclock_checker_done; ++static struct atomic_int reclock_checker_done; + + static void * + reclock_checker_thread (void *arg) + { +- while (!reclock_checker_done) ++ while (get_atomic_int_value (&reclock_checker_done) == 0) + { + dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ()); + gl_recursive_lock_lock (my_reclock); +@@ -386,7 +440,8 @@ test_recursive_lock (void) + /* Initialization. */ + for (i = 0; i < ACCOUNT_COUNT; i++) + account[i] = 1000; +- reclock_checker_done = 0; ++ init_atomic_int (&reclock_checker_done); ++ set_atomic_int_value (&reclock_checker_done, 0); + + /* Spawn the threads. */ + checkerthread = gl_thread_create (reclock_checker_thread, NULL); +@@ -396,7 +451,7 @@ test_recursive_lock (void) + /* Wait for the threads to terminate. */ + for (i = 0; i < THREAD_COUNT; i++) + gl_thread_join (threads[i], NULL); +- reclock_checker_done = 1; ++ set_atomic_int_value (&reclock_checker_done, 1); + gl_thread_join (checkerthread, NULL); + check_accounts (); + } -- 2.7.4 diff --git a/coreutils.spec b/coreutils.spec index 860a5cd..c683fa7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.26 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -296,6 +296,9 @@ fi %license COPYING %changelog +* Mon Jan 02 2017 Kamil Dudka - 8.26-4 +- use upstream patch for gnulib's test-lock (instead of disabling it) + * Thu Dec 15 2016 Kamil Dudka - 8.26-3 - drop build fixes no longer needed From e12860338133a2a90558751f5daaa1e754135349 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 23 Jan 2017 10:24:10 +0100 Subject: [PATCH 334/523] =?UTF-8?q?date:=20fix=20fix=20TZ=3D=20regression?= =?UTF-8?q?=20(patch=20by=20P=C3=A1draig=20Brady)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=851934#10 --- coreutils-8.26-date-fix-tz-regre.patch | 82 ++++++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.26-date-fix-tz-regre.patch diff --git a/coreutils-8.26-date-fix-tz-regre.patch b/coreutils-8.26-date-fix-tz-regre.patch new file mode 100644 index 0000000..158c80a --- /dev/null +++ b/coreutils-8.26-date-fix-tz-regre.patch @@ -0,0 +1,82 @@ +From 12284825dcc5d9485ebaa78aedd93f450bad7b73 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Fri, 20 Jan 2017 12:40:35 +0000 +Subject: [PATCH 1/2] date: fix TZ= regression + +On 17/03/16 17:38, Paul Eggert wrote: +> On 03/16/2016 08:51 PM, Assaf Gordon wrote: +>> I suspect it has something to do with this commit: +>> commit 037e3b9847feb46cf6b58d99ce960d3987faaf52 +> +> You're right, and thanks for that detailed bug report. I installed the +> attached patch, which fixed the bug for me. + +This introduced a bug unfortunately due to the side effects of +parse_datetime(). +parse_datetime resets the TZ env variable but doesn't call tzset(). +Hence using the wrong timezone for output. +Previously localtime() called tzset() implicitly. +Perhaps we should call tzset() in parse_datetime() if needed? +I'm not sure as to whether this undoes the fix for bug 23035? + +Anyway this avoids the issue on GNU/Linux. + +Signed-off-by: Kamil Dudka +--- + src/date.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/date.c b/src/date.c +index 619a72b..2b3d890 100644 +--- a/src/date.c ++++ b/src/date.c +@@ -571,6 +571,8 @@ show_date (const char *format, struct timespec when, timezone_t tz) + { + struct tm tm; + ++ tzset (); ++ + if (localtime_rz (tz, &when.tv_sec, &tm)) + { + if (format == rfc_2822_format) +-- +2.7.4 + + +From 3c082157634bd4fbc79c26e9c56abb4da79e9a2d Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Fri, 20 Jan 2017 18:24:02 -0800 +Subject: [PATCH 2/2] date: test for TZ= regression + +Problem reported by Paul Wise for Debian, in: +https://bugs.debian.org/851934 +This is fallout from the fix for GNU Bug#23035. +* tests/misc/date.pl: Test the fix. + +Upstream-commit: b14be5085cd1aefd473a000456b21270e6070711 +Signed-off-by: Kamil Dudka +--- + tests/misc/date-debug.sh | 4 ++-- + tests/misc/date.pl | 6 ++++++ + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/tests/misc/date.pl b/tests/misc/date.pl +index 7e45e98..be8b39e 100755 +--- a/tests/misc/date.pl ++++ b/tests/misc/date.pl +@@ -291,6 +291,12 @@ my @Tests = + {ERR => "date: invalid date 'TZ=\"\"\"'\n"}, + {EXIT => 1}, + ], ++ ++ # https://bugs.debian.org/851934#10 ++ ['cross-TZ-mishandled', "-d 'TZ=\"EST5\" 1970-01-01 00:00'", ++ {ENV => 'TZ=PST8'}, ++ {OUT => 'Wed Dec 31 21:00:00 PST 1969'}, ++ ], + ); + + # Repeat the cross-dst test, using Jan 1, 2005 and every interval from 1..364. +-- +2.7.4 + diff --git a/coreutils.spec b/coreutils.spec index c683fa7..43e0e6f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.26 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -19,6 +19,9 @@ Source10: coreutils-find-requires.sh # disable the test-lock gnulib test prone to deadlock Patch1: coreutils-8.26-test-lock.patch +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=851934#10 +Patch2: coreutils-8.26-date-fix-tz-regre.patch + #add note about no difference between binary/text mode on Linux - md5sum manpage Patch101: coreutils-6.10-manpages.patch # downstream changes to default DIR_COLORS @@ -296,6 +299,9 @@ fi %license COPYING %changelog +* Mon Jan 23 2017 Kamil Dudka - 8.26-5 +- date: fix fix TZ= regression (patch by Pádraig Brady) + * Mon Jan 02 2017 Kamil Dudka - 8.26-4 - use upstream patch for gnulib's test-lock (instead of disabling it) From 5e261ae9b91a3ff67dea0c98e57c17b52b12fe97 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 23 Jan 2017 10:46:15 +0100 Subject: [PATCH 335/523] changelog: fix a duplicated word in the last entry --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 43e0e6f..a3874b4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -300,7 +300,7 @@ fi %changelog * Mon Jan 23 2017 Kamil Dudka - 8.26-5 -- date: fix fix TZ= regression (patch by Pádraig Brady) +- date: fix TZ= regression (patch by Pádraig Brady) * Mon Jan 02 2017 Kamil Dudka - 8.26-4 - use upstream patch for gnulib's test-lock (instead of disabling it) From 5e77c9c1c9d1cd3284e7d94b1d2a2cae9d48aa1b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 23 Jan 2017 12:47:06 +0100 Subject: [PATCH 336/523] test-lock: disable the rwlock test --- coreutils-8.26-test-lock.patch | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/coreutils-8.26-test-lock.patch b/coreutils-8.26-test-lock.patch index 43e477e..786aa33 100644 --- a/coreutils-8.26-test-lock.patch +++ b/coreutils-8.26-test-lock.patch @@ -1,7 +1,8 @@ From 4f6cb65ce4d643aca0c6bf7db2e8b32c0d08eb89 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 24 Dec 2016 18:21:59 +0100 -Subject: [PATCH] lock test: Fix performance problem on multi-core machines. +Subject: [PATCH 1/2] lock test: Fix performance problem on multi-core + machines. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -200,3 +201,33 @@ index cb734b4..aa6de27 100644 -- 2.7.4 + +From 0d04ee8ddedb2bf33d64f148f246a3b7ec4fef21 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 23 Jan 2017 12:35:41 +0100 +Subject: [PATCH 2/2] test-lock: disable the rwlock test + +It hangs indefinitely if the system rwlock implementation does not +prevent writer starvation (and glibc does not implement it). + +Bug: http://www.mail-archive.com/bug-gnulib@gnu.org/msg33017.html +--- + gnulib-tests/test-lock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gnulib-tests/test-lock.c b/gnulib-tests/test-lock.c +index aa6de27..5af0a6c 100644 +--- a/gnulib-tests/test-lock.c ++++ b/gnulib-tests/test-lock.c +@@ -42,7 +42,7 @@ + Uncomment some of these, to verify that all tests crash if no locking + is enabled. */ + #define DO_TEST_LOCK 1 +-#define DO_TEST_RWLOCK 1 ++#define DO_TEST_RWLOCK 0 + #define DO_TEST_RECURSIVE_LOCK 1 + #define DO_TEST_ONCE 1 + +-- +2.7.4 + From f1a024cc0933e93fd37fd2cda8fc584d4ba87008 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 3 Feb 2017 12:35:13 +0100 Subject: [PATCH 337/523] Resolves: #1418505 - fold: preserve new-lines in mutlibyte text --- coreutils-i18n-fold-newline.patch | 83 +++++++++++++++++++++++++++++++ coreutils.spec | 7 ++- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 coreutils-i18n-fold-newline.patch diff --git a/coreutils-i18n-fold-newline.patch b/coreutils-i18n-fold-newline.patch new file mode 100644 index 0000000..79d1a09 --- /dev/null +++ b/coreutils-i18n-fold-newline.patch @@ -0,0 +1,83 @@ +From ff424639fe863cbd6963add1a79b97290c1606c6 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Fri, 3 Feb 2017 12:26:53 +0100 +Subject: [PATCH] fold.c: preserve new-lines in mutlibyte text + +--- + src/fold.c | 55 +++++++++++++++++++++++++++---------------------------- + 1 file changed, 27 insertions(+), 28 deletions(-) + +diff --git a/src/fold.c b/src/fold.c +index d23edd5..8c232a7 100644 +--- a/src/fold.c ++++ b/src/fold.c +@@ -342,39 +342,38 @@ fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) + } + + rescan: +- if (operating_mode == byte_mode) /* byte mode */ ++ if (convfail) ++ increment = 1; ++ else if (wc == L'\n') ++ { ++ /* preserve newline */ ++ fwrite (line_out, sizeof(char), offset_out, stdout); ++ START_NEW_LINE; ++ continue; ++ } ++ else if (operating_mode == byte_mode) /* byte mode */ + increment = mblength; + else if (operating_mode == character_mode) /* character mode */ + increment = 1; +- else /* column mode */ ++ else /* column mode */ + { +- if (convfail) +- increment = 1; +- else ++ switch (wc) + { +- switch (wc) +- { +- case L'\n': +- fwrite (line_out, sizeof(char), offset_out, stdout); +- START_NEW_LINE; +- continue; +- +- case L'\b': +- increment = (column > 0) ? -1 : 0; +- break; +- +- case L'\r': +- increment = -1 * column; +- break; +- +- case L'\t': +- increment = 8 - column % 8; +- break; +- +- default: +- increment = wcwidth (wc); +- increment = (increment < 0) ? 0 : increment; +- } ++ 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; + } + } + +-- +2.7.4 + diff --git a/coreutils.spec b/coreutils.spec index a3874b4..ae10648 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.26 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -52,6 +52,8 @@ Patch805: coreutils-i18n-fix2-expand-unexpand.patch Patch806: coreutils-i18n-un-expand-BOM.patch # make 'sort -h' work for arbitrary column even when using UTF-8 locales Patch807: coreutils-i18n-sort-human.patch +# fold: preserve new-lines in mutlibyte text (#1418505) +Patch808: coreutils-i18n-fold-newline.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch @@ -299,6 +301,9 @@ fi %license COPYING %changelog +* Fri Feb 03 2017 Kamil Dudka - 8.26-6 +- fold: preserve new-lines in mutlibyte text (#1418505) + * Mon Jan 23 2017 Kamil Dudka - 8.26-5 - date: fix TZ= regression (patch by Pádraig Brady) From bc257082406e008d63ca9271390a5bdb65689c3d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 10 Feb 2017 07:54:30 +0000 Subject: [PATCH 338/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index ae10648..a2899d7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.26 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -301,6 +301,9 @@ fi %license COPYING %changelog +* Fri Feb 10 2017 Fedora Release Engineering - 8.26-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + * Fri Feb 03 2017 Kamil Dudka - 8.26-6 - fold: preserve new-lines in mutlibyte text (#1418505) From 7a7c1a231c01c2f817bb9a808e89c17e558f8be6 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 9 Mar 2017 09:57:09 +0100 Subject: [PATCH 339/523] new upstream release 8.27 --- coreutils-8.25-DIR_COLORS.patch | 119 +++++++------ coreutils-8.26-date-fix-tz-regre.patch | 82 --------- coreutils-8.26-test-lock.patch | 206 +--------------------- coreutils-8.26.tar.xz.sig | 17 -- coreutils-8.27.tar.xz.sig | 16 ++ coreutils-getgrouplist.patch | 2 +- coreutils-i18n-fix2-expand-unexpand.patch | 4 +- coreutils-i18n-fold-newline.patch | 31 ++-- coreutils-i18n-un-expand-BOM.patch | 50 ++++-- coreutils-i18n.patch | 31 ++-- coreutils-selinux.patch | 2 +- coreutils.spec | 16 +- sources | 2 +- 13 files changed, 163 insertions(+), 415 deletions(-) delete mode 100644 coreutils-8.26-date-fix-tz-regre.patch delete mode 100644 coreutils-8.26.tar.xz.sig create mode 100644 coreutils-8.27.tar.xz.sig diff --git a/coreutils-8.25-DIR_COLORS.patch b/coreutils-8.25-DIR_COLORS.patch index a8a2d1a..94923b0 100644 --- a/coreutils-8.25-DIR_COLORS.patch +++ b/coreutils-8.25-DIR_COLORS.patch @@ -4,16 +4,16 @@ Date: Fri, 17 Jun 2016 16:58:18 +0200 Subject: [PATCH] downstream changes to default DIR_COLORS --- - DIR_COLORS | 44 ++++---- - DIR_COLORS.256color | 294 +++++++++++++++++++++++------------------------- - DIR_COLORS.lightbgcolor | 207 +++++++++++++++++----------------- - 3 files changed, 271 insertions(+), 274 deletions(-) + DIR_COLORS | 41 ++++--- + DIR_COLORS.256color | 302 ++++++++++++++++++++++++------------------------ + DIR_COLORS.lightbgcolor | 215 +++++++++++++++++----------------- + 3 files changed, 286 insertions(+), 272 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS index d2ea453..27af9d7 100644 --- a/DIR_COLORS +++ b/DIR_COLORS -@@ -1,12 +1,18 @@ +@@ -1,6 +1,10 @@ # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. @@ -21,20 +21,20 @@ index d2ea453..27af9d7 100644 +# You can copy this file to .dir_colors in your $HOME directory to override +# the system defaults. + - # Copyright (C) 1996-2016 Free Software Foundation, Inc. + # Copyright (C) 1996-2017 Free Software Foundation, Inc. # Copying and distribution of this file, with or without modification, # are permitted provided the copyright notice and this notice are preserved. +@@ -8,6 +12,9 @@ + # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the + # slackware version of dircolors) are recognized but ignored. --# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the --# slackware version of dircolors) are recognized but ignored. -+# The keywords OPTIONS and EIGHTBIT (honored by the slackware version of -+# dircolors) are recognized but ignored. For compatibility reasons, the -+# pattern "^COLOR.*none" is recognized as a way to disable colorization. -+# See https://bugzilla.redhat.com/1349579 for details. - ++# For compatibility, the pattern "^COLOR.*none" is recognized as a way to ++# disable colorization. See https://bugzilla.redhat.com/1349579 for details. ++ # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. -@@ -56,7 +62,7 @@ DOOR 01;35 # door + TERM Eterm +@@ -56,7 +63,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -43,7 +43,7 @@ index d2ea453..27af9d7 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -181,21 +187,21 @@ EXEC 01;32 +@@ -185,21 +192,21 @@ EXEC 01;32 .ogx 01;35 # audio formats @@ -72,7 +72,7 @@ index d2ea453..27af9d7 100644 +.ra 01;36 +.wav 01;36 - # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions + # https://wiki.xiph.org/MIME_Types_and_File_Extensions -.oga 00;36 -.opus 00;36 -.spx 00;36 @@ -85,26 +85,23 @@ diff --git a/DIR_COLORS.256color b/DIR_COLORS.256color index d2ea453..74c34ba 100644 --- a/DIR_COLORS.256color +++ b/DIR_COLORS.256color -@@ -1,39 +1,22 @@ --# Configuration file for dircolors, a utility to help you set the --# LS_COLORS environment variable used by GNU ls with the --color option. +@@ -1,3 +1,9 @@ +# Configuration file for the 256color ls utility + +# This file goes in the /etc directory, and must be world readable. +# You can copy this file to .dir_colors in your $HOME directory to override +# the system defaults. ++ + # Configuration file for dircolors, a utility to help you set the + # LS_COLORS environment variable used by GNU ls with the --color option. - # Copyright (C) 1996-2016 Free Software Foundation, Inc. - # Copying and distribution of this file, with or without modification, - # are permitted provided the copyright notice and this notice are preserved. - --# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the --# slackware version of dircolors) are recognized but ignored. -+# The keywords OPTIONS and EIGHTBIT (honored by the slackware version of -+# dircolors) are recognized but ignored. For compatibility reasons, the -+# pattern "^COLOR.*none" is recognized as a way to disable colorization. -+# See https://bugzilla.redhat.com/1349579 for details. +@@ -8,32 +14,13 @@ + # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the + # slackware version of dircolors) are recognized but ignored. ++# For compatibility, the pattern "^COLOR.*none" is recognized as a way to ++# disable colorization. See https://bugzilla.redhat.com/1349579 for details. ++ # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. -TERM Eterm @@ -136,7 +133,7 @@ index d2ea453..74c34ba 100644 # Below are the color init strings for the basic file types. A color init # string consists of one or more of the following numeric codes: -@@ -43,29 +26,40 @@ TERM xterm* +@@ -43,29 +30,40 @@ TERM xterm* # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white # Background color codes: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white @@ -193,7 +190,7 @@ index d2ea453..74c34ba 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -83,119 +77,115 @@ EXEC 01;32 +@@ -83,123 +81,123 @@ EXEC 01;32 #.csh 01;32 # archives or compressed (bright red) @@ -240,6 +237,10 @@ index d2ea453..74c34ba 100644 -.7z 01;31 -.rz 01;31 -.cab 01;31 +-.wim 01;31 +-.swm 01;31 +-.dwm 01;31 +-.esd 01;31 +.tar 38;5;9 +.tgz 38;5;9 +.arc 38;5;9 @@ -262,6 +263,8 @@ index d2ea453..74c34ba 100644 +.lz 38;5;9 +.lzo 38;5;9 +.xz 38;5;9 ++.zst 38;5;9 ++.tzst 38;5;9 +.bz2 38;5;9 +.bz 38;5;9 +.tbz 38;5;9 @@ -281,6 +284,10 @@ index d2ea453..74c34ba 100644 +.7z 38;5;9 +.rz 38;5;9 +.cab 38;5;9 ++.wim 38;5;9 ++.swm 38;5;9 ++.dwm 38;5;9 ++.esd 38;5;9 # image formats -.jpg 01;35 @@ -332,6 +339,8 @@ index d2ea453..74c34ba 100644 -.emf 01;35 +.jpg 38;5;13 +.jpeg 38;5;13 ++.mjpg 38;5;13 ++.mjpeg 38;5;13 +.gif 38;5;13 +.bmp 38;5;13 +.pbm 38;5;13 @@ -376,7 +385,7 @@ index d2ea453..74c34ba 100644 +.cgm 38;5;13 +.emf 38;5;13 - # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions + # https://wiki.xiph.org/MIME_Types_and_File_Extensions -.ogv 01;35 -.ogx 01;35 +.ogv 38;5;13 @@ -408,7 +417,7 @@ index d2ea453..74c34ba 100644 +.ra 38;5;45 +.wav 38;5;45 - # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions + # https://wiki.xiph.org/MIME_Types_and_File_Extensions -.oga 00;36 -.opus 00;36 -.spx 00;36 @@ -421,29 +430,27 @@ diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor index d2ea453..95d6879 100644 --- a/DIR_COLORS.lightbgcolor +++ b/DIR_COLORS.lightbgcolor -@@ -1,12 +1,17 @@ --# Configuration file for dircolors, a utility to help you set the --# LS_COLORS environment variable used by GNU ls with the --color option. +@@ -1,3 +1,9 @@ +# Configuration file for the color ls utility - modified for lighter backgrounds + +# This file goes in the /etc directory, and must be world readable. +# You can copy this file to .dir_colors in your $HOME directory to override +# the system defaults. ++ + # Configuration file for dircolors, a utility to help you set the + # LS_COLORS environment variable used by GNU ls with the --color option. - # Copyright (C) 1996-2016 Free Software Foundation, Inc. - # Copying and distribution of this file, with or without modification, - # are permitted provided the copyright notice and this notice are preserved. - --# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the --# slackware version of dircolors) are recognized but ignored. -+# The keywords OPTIONS and EIGHTBIT (honored by the slackware version of -+# dircolors) are recognized but ignored. For compatibility reasons, the -+# pattern "^COLOR.*none" is recognized as a way to disable colorization. -+# See https://bugzilla.redhat.com/1349579 for details. +@@ -8,6 +14,9 @@ + # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the + # slackware version of dircolors) are recognized but ignored. ++# For compatibility, the pattern "^COLOR.*none" is recognized as a way to ++# disable colorization. See https://bugzilla.redhat.com/1349579 for details. ++ # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. -@@ -46,17 +51,17 @@ TERM xterm* + TERM Eterm +@@ -46,17 +55,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -466,7 +473,7 @@ index d2ea453..95d6879 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -65,7 +70,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +@@ -65,7 +74,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: @@ -475,7 +482,7 @@ index d2ea453..95d6879 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -82,103 +87,99 @@ EXEC 01;32 +@@ -82,107 +91,107 @@ EXEC 01;32 #.sh 01;32 #.csh 01;32 @@ -523,6 +530,10 @@ index d2ea453..95d6879 100644 -.7z 01;31 -.rz 01;31 -.cab 01;31 +-.wim 01;31 +-.swm 01;31 +-.dwm 01;31 +-.esd 01;31 +# archives or compressed (red) +.tar 00;31 +.tgz 00;31 @@ -546,6 +557,8 @@ index d2ea453..95d6879 100644 +.lz 00;31 +.lzo 00;31 +.xz 00;31 ++.zst 00;31 ++.tzst 00;31 +.bz2 00;31 +.bz 00;31 +.tbz 00;31 @@ -565,6 +578,10 @@ index d2ea453..95d6879 100644 +.7z 00;31 +.rz 00;31 +.cab 00;31 ++.wim 00;31 ++.swm 00;31 ++.dwm 00;31 ++.esd 00;31 # image formats -.jpg 01;35 @@ -616,6 +633,8 @@ index d2ea453..95d6879 100644 -.emf 01;35 +.jpg 00;35 +.jpeg 00;35 ++.mjpg 00;35 ++.mjpeg 00;35 +.gif 00;35 +.bmp 00;35 +.pbm 00;35 @@ -660,7 +679,7 @@ index d2ea453..95d6879 100644 +.cgm 00;35 +.emf 00;35 - # http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions + # https://wiki.xiph.org/MIME_Types_and_File_Extensions -.ogv 01;35 -.ogx 01;35 +.ogv 00;35 diff --git a/coreutils-8.26-date-fix-tz-regre.patch b/coreutils-8.26-date-fix-tz-regre.patch deleted file mode 100644 index 158c80a..0000000 --- a/coreutils-8.26-date-fix-tz-regre.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 12284825dcc5d9485ebaa78aedd93f450bad7b73 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Fri, 20 Jan 2017 12:40:35 +0000 -Subject: [PATCH 1/2] date: fix TZ= regression - -On 17/03/16 17:38, Paul Eggert wrote: -> On 03/16/2016 08:51 PM, Assaf Gordon wrote: ->> I suspect it has something to do with this commit: ->> commit 037e3b9847feb46cf6b58d99ce960d3987faaf52 -> -> You're right, and thanks for that detailed bug report. I installed the -> attached patch, which fixed the bug for me. - -This introduced a bug unfortunately due to the side effects of -parse_datetime(). -parse_datetime resets the TZ env variable but doesn't call tzset(). -Hence using the wrong timezone for output. -Previously localtime() called tzset() implicitly. -Perhaps we should call tzset() in parse_datetime() if needed? -I'm not sure as to whether this undoes the fix for bug 23035? - -Anyway this avoids the issue on GNU/Linux. - -Signed-off-by: Kamil Dudka ---- - src/date.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/date.c b/src/date.c -index 619a72b..2b3d890 100644 ---- a/src/date.c -+++ b/src/date.c -@@ -571,6 +571,8 @@ show_date (const char *format, struct timespec when, timezone_t tz) - { - struct tm tm; - -+ tzset (); -+ - if (localtime_rz (tz, &when.tv_sec, &tm)) - { - if (format == rfc_2822_format) --- -2.7.4 - - -From 3c082157634bd4fbc79c26e9c56abb4da79e9a2d Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Fri, 20 Jan 2017 18:24:02 -0800 -Subject: [PATCH 2/2] date: test for TZ= regression - -Problem reported by Paul Wise for Debian, in: -https://bugs.debian.org/851934 -This is fallout from the fix for GNU Bug#23035. -* tests/misc/date.pl: Test the fix. - -Upstream-commit: b14be5085cd1aefd473a000456b21270e6070711 -Signed-off-by: Kamil Dudka ---- - tests/misc/date-debug.sh | 4 ++-- - tests/misc/date.pl | 6 ++++++ - 2 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/tests/misc/date.pl b/tests/misc/date.pl -index 7e45e98..be8b39e 100755 ---- a/tests/misc/date.pl -+++ b/tests/misc/date.pl -@@ -291,6 +291,12 @@ my @Tests = - {ERR => "date: invalid date 'TZ=\"\"\"'\n"}, - {EXIT => 1}, - ], -+ -+ # https://bugs.debian.org/851934#10 -+ ['cross-TZ-mishandled', "-d 'TZ=\"EST5\" 1970-01-01 00:00'", -+ {ENV => 'TZ=PST8'}, -+ {OUT => 'Wed Dec 31 21:00:00 PST 1969'}, -+ ], - ); - - # Repeat the cross-dst test, using Jan 1, 2005 and every interval from 1..364. --- -2.7.4 - diff --git a/coreutils-8.26-test-lock.patch b/coreutils-8.26-test-lock.patch index 786aa33..d66928c 100644 --- a/coreutils-8.26-test-lock.patch +++ b/coreutils-8.26-test-lock.patch @@ -1,211 +1,7 @@ -From 4f6cb65ce4d643aca0c6bf7db2e8b32c0d08eb89 Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Sat, 24 Dec 2016 18:21:59 +0100 -Subject: [PATCH 1/2] lock test: Fix performance problem on multi-core - machines. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -* tests/test-lock.c (USE_VOLATILE): New macro. -(struct atomic_int): New type. -(init_atomic_int, get_atomic_int_value, set_atomic_int_value): New -functions. -(lock_checker_done, rwlock_checker_done, reclock_checker_done): Define -as 'struct atomic_int'. -(lock_checker_thread, test_lock, rwlock_checker_thread, test_rwlock, -reclock_checker_thread, test_recursive_lock): Use the new functions. -Reported by Eric Blake in -https://www.redhat.com/archives/libvir-list/2012-March/msg00854.html -and by Pádraig Brady in -http://lists.gnu.org/archive/html/bug-gnulib/2016-12/msg00117.html. - -Upstream-commit: 480d374e596a0ee3fed168ab42cd84c313ad3c89 -Signed-off-by: Kamil Dudka ---- - gnulib-tests/test-lock.c | 79 ++++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 67 insertions(+), 12 deletions(-) - -diff --git a/gnulib-tests/test-lock.c b/gnulib-tests/test-lock.c -index cb734b4..aa6de27 100644 ---- a/gnulib-tests/test-lock.c -+++ b/gnulib-tests/test-lock.c -@@ -50,6 +50,13 @@ - Uncomment this to see if the operating system has a fair scheduler. */ - #define EXPLICIT_YIELD 1 - -+/* Whether to use 'volatile' on some variables that communicate information -+ between threads. If set to 0, a lock is used to protect these variables. -+ If set to 1, 'volatile' is used; this is theoretically equivalent but can -+ lead to much slower execution (e.g. 30x slower total run time on a 40-core -+ machine. */ -+#define USE_VOLATILE 0 -+ - /* Whether to print debugging messages. */ - #define ENABLE_DEBUGGING 0 - -@@ -103,6 +110,51 @@ - # define yield() - #endif - -+#if USE_VOLATILE -+struct atomic_int { -+ volatile int value; -+}; -+static void -+init_atomic_int (struct atomic_int *ai) -+{ -+} -+static int -+get_atomic_int_value (struct atomic_int *ai) -+{ -+ return ai->value; -+} -+static void -+set_atomic_int_value (struct atomic_int *ai, int new_value) -+{ -+ ai->value = new_value; -+} -+#else -+struct atomic_int { -+ gl_lock_define (, lock) -+ int value; -+}; -+static void -+init_atomic_int (struct atomic_int *ai) -+{ -+ gl_lock_init (ai->lock); -+} -+static int -+get_atomic_int_value (struct atomic_int *ai) -+{ -+ gl_lock_lock (ai->lock); -+ int ret = ai->value; -+ gl_lock_unlock (ai->lock); -+ return ret; -+} -+static void -+set_atomic_int_value (struct atomic_int *ai, int new_value) -+{ -+ gl_lock_lock (ai->lock); -+ ai->value = new_value; -+ gl_lock_unlock (ai->lock); -+} -+#endif -+ - #define ACCOUNT_COUNT 4 - - static int account[ACCOUNT_COUNT]; -@@ -170,12 +222,12 @@ lock_mutator_thread (void *arg) - return NULL; - } - --static volatile int lock_checker_done; -+static struct atomic_int lock_checker_done; - - static void * - lock_checker_thread (void *arg) - { -- while (!lock_checker_done) -+ while (get_atomic_int_value (&lock_checker_done) == 0) - { - dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ()); - gl_lock_lock (my_lock); -@@ -200,7 +252,8 @@ test_lock (void) - /* Initialization. */ - for (i = 0; i < ACCOUNT_COUNT; i++) - account[i] = 1000; -- lock_checker_done = 0; -+ init_atomic_int (&lock_checker_done); -+ set_atomic_int_value (&lock_checker_done, 0); - - /* Spawn the threads. */ - checkerthread = gl_thread_create (lock_checker_thread, NULL); -@@ -210,7 +263,7 @@ test_lock (void) - /* Wait for the threads to terminate. */ - for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i], NULL); -- lock_checker_done = 1; -+ set_atomic_int_value (&lock_checker_done, 1); - gl_thread_join (checkerthread, NULL); - check_accounts (); - } -@@ -254,12 +307,12 @@ rwlock_mutator_thread (void *arg) - return NULL; - } - --static volatile int rwlock_checker_done; -+static struct atomic_int rwlock_checker_done; - - static void * - rwlock_checker_thread (void *arg) - { -- while (!rwlock_checker_done) -+ while (get_atomic_int_value (&rwlock_checker_done) == 0) - { - dbgprintf ("Checker %p before check rdlock\n", gl_thread_self_pointer ()); - gl_rwlock_rdlock (my_rwlock); -@@ -284,7 +337,8 @@ test_rwlock (void) - /* Initialization. */ - for (i = 0; i < ACCOUNT_COUNT; i++) - account[i] = 1000; -- rwlock_checker_done = 0; -+ init_atomic_int (&rwlock_checker_done); -+ set_atomic_int_value (&rwlock_checker_done, 0); - - /* Spawn the threads. */ - for (i = 0; i < THREAD_COUNT; i++) -@@ -295,7 +349,7 @@ test_rwlock (void) - /* Wait for the threads to terminate. */ - for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i], NULL); -- rwlock_checker_done = 1; -+ set_atomic_int_value (&rwlock_checker_done, 1); - for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (checkerthreads[i], NULL); - check_accounts (); -@@ -356,12 +410,12 @@ reclock_mutator_thread (void *arg) - return NULL; - } - --static volatile int reclock_checker_done; -+static struct atomic_int reclock_checker_done; - - static void * - reclock_checker_thread (void *arg) - { -- while (!reclock_checker_done) -+ while (get_atomic_int_value (&reclock_checker_done) == 0) - { - dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ()); - gl_recursive_lock_lock (my_reclock); -@@ -386,7 +440,8 @@ test_recursive_lock (void) - /* Initialization. */ - for (i = 0; i < ACCOUNT_COUNT; i++) - account[i] = 1000; -- reclock_checker_done = 0; -+ init_atomic_int (&reclock_checker_done); -+ set_atomic_int_value (&reclock_checker_done, 0); - - /* Spawn the threads. */ - checkerthread = gl_thread_create (reclock_checker_thread, NULL); -@@ -396,7 +451,7 @@ test_recursive_lock (void) - /* Wait for the threads to terminate. */ - for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i], NULL); -- reclock_checker_done = 1; -+ set_atomic_int_value (&reclock_checker_done, 1); - gl_thread_join (checkerthread, NULL); - check_accounts (); - } --- -2.7.4 - - From 0d04ee8ddedb2bf33d64f148f246a3b7ec4fef21 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 23 Jan 2017 12:35:41 +0100 -Subject: [PATCH 2/2] test-lock: disable the rwlock test +Subject: [PATCH] test-lock: disable the rwlock test It hangs indefinitely if the system rwlock implementation does not prevent writer starvation (and glibc does not implement it). diff --git a/coreutils-8.26.tar.xz.sig b/coreutils-8.26.tar.xz.sig deleted file mode 100644 index fe1635d..0000000 --- a/coreutils-8.26.tar.xz.sig +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1 - -iQIcBAABAgAGBQJYPyRpAAoJEN9v2XEwYDfZ0I4P/3oaPYXMPEOKuDDpEcLumn26 -gYIMQc1jIMbBNQe120gQmNPkRr5dTKt5Bap9qYkCj0pI/6VxVIWDo0xrOLYZi7AN -Xgr0kX2qLDFEH+EHkC1BpsAdpsgwfvLmVWPHS62CNKgVDgGiP1cRJZe8oVmlBCiR -3ES7pUsBfDn3hbdKNTTmMDtro1rQMOxfHkVCZLAva+JjdzpE+KTvzZzKkVuZZfJ/ -Mi/ZySrXZXFvPBS7GXgop4x8EodyzQMeKO+nvpIUEBY1yLQgCvni5/CBI8w/EViD -DSjj0zWsCQkEjx6HCohi8sBHUYZ+M3lB4rkFk7aevdioPZUGfLkW31LT/cUJC/VV -MIQKWzQtZO/WCJuyEbWP2m25c4MtnnhTm5yoi29yT/CoTRlUWkIQpXm4oD1cJXHy -PpHveu8qM0qRaAtVdXE3pmapIMYUV4g7vxSuCjZRrgiDLhp/K7Lzt5xBhl++kPU2 -U9uc202eah4Towo0pbHsuEJT0vk0GGLq8/17dCa/ss8wV+86ZLxl0kZYy4CNEnIW -vsCN6CJ5AoAEVrMN1F7ZJYnH4hoJedvIczThnAkNTqYYE3wnN9stOe28Oy/a0/tg -bt5/Mn0JbmQei890uU8zcEdUjidHqGV4hKk1E2UC4UCyHG/VcHv9gfr8OaD/xPDr -SoauDCHpBU7J7FT/DX+k -=vkKy ------END PGP SIGNATURE----- diff --git a/coreutils-8.27.tar.xz.sig b/coreutils-8.27.tar.xz.sig new file mode 100644 index 0000000..7555c00 --- /dev/null +++ b/coreutils-8.27.tar.xz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIcBAABAgAGBQJYwOwaAAoJEN9v2XEwYDfZQrUP/RdXj/ug35e+u+VD1ts9/b8n +7JihJmxngEZQAJECNTMbJ7mNj6DhpMY0Jg/Hwg7zJT28T6QDeS1Iuk3Id4uM5eFa +CgHKAZumntSMTkQdNvnCEFEIqu+L8BtBYGcOaw66wAFNFw3jdJUUs2sOST2r46jR +N7aY9oARKJuHfgTZ2BI2zL0Q+poXM1O0k/U+BScE6c139zJsbg+1uM9kGVtJWPkM +EPLFWkbTgjYnt+qEFrDlWL0YFOS42sgR7P1sVfBC1nAu5lwgzPy62OtGv9WCEBhm +3+PRNZ0KLW8CKp06llG/0bG4QwssWs6p/vPwrRGeAg6pKsRNN1ni27AnDThiPgvz +YbBLgU+EZj1HuibvYArHXNKY2+O5ZC3nYU6bdAffl3TAtrGFA1ncZXGiFD5UgOQ2 +V9Q38S41FUEwKGtf9tWGCRTxrb4FQ1CDzJglV9vHKetn4mgH/HpEG/q07k4RNW5d +ikfrS0xFxbqtLjlY3UqvtkrFyVQFY093ozsP7fKsq53JAtEWc3YvXR8UCbliU+gV +5qug0REBQafe9EAyH+oq0dzD2BZ3KtFcjtKI/2UzAf3idcyygsHgcEPQObqI8BfD +NscEMjdFY7+Zh5w2shQlyq4xr2aI2nXCX3+AMcS/6Yfg6W6fBvgIjtmXBrQsbWpV +DBcx50TVDa/ERBX1+FI1 +=skPR +-----END PGP SIGNATURE----- diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch index 7defd19..5b35f42 100644 --- a/coreutils-getgrouplist.patch +++ b/coreutils-getgrouplist.patch @@ -30,7 +30,7 @@ index 76474c2..0a9d221 100644 - : getgroups (0, NULL)); + if (!username) + max_n_groups = getgroups(0, NULL); -+ else ++ else + { +#ifdef HAVE_GETGROUPLIST + max_n_groups = 0; diff --git a/coreutils-i18n-fix2-expand-unexpand.patch b/coreutils-i18n-fix2-expand-unexpand.patch index 1a63012..b34d7b7 100644 --- a/coreutils-i18n-fix2-expand-unexpand.patch +++ b/coreutils-i18n-fix2-expand-unexpand.patch @@ -22,7 +22,7 @@ index 380e020..310b349 100644 + } } - while (false); -+ ++ if (convert) { @@ -50,7 +50,7 @@ index 3bbbd66..863a90a 100644 + } } - while (false); -+ ++ if (convert) { diff --git a/coreutils-i18n-fold-newline.patch b/coreutils-i18n-fold-newline.patch index 79d1a09..f7286ef 100644 --- a/coreutils-i18n-fold-newline.patch +++ b/coreutils-i18n-fold-newline.patch @@ -4,8 +4,8 @@ Date: Fri, 3 Feb 2017 12:26:53 +0100 Subject: [PATCH] fold.c: preserve new-lines in mutlibyte text --- - src/fold.c | 55 +++++++++++++++++++++++++++---------------------------- - 1 file changed, 27 insertions(+), 28 deletions(-) + src/fold.c | 49 ++++++++++++++++++++++++------------------------- + 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/fold.c b/src/fold.c index d23edd5..8c232a7 100644 @@ -43,15 +43,24 @@ index d23edd5..8c232a7 100644 - fwrite (line_out, sizeof(char), offset_out, stdout); - START_NEW_LINE; - continue; -- ++ case L'\b': ++ increment = (column > 0) ? -1 : 0; ++ break; + - case L'\b': - increment = (column > 0) ? -1 : 0; - break; -- ++ case L'\r': ++ increment = -1 * column; ++ break; + - case L'\r': - increment = -1 * column; - break; -- ++ case L'\t': ++ increment = 8 - column % 8; ++ break; + - case L'\t': - increment = 8 - column % 8; - break; @@ -60,18 +69,6 @@ index d23edd5..8c232a7 100644 - increment = wcwidth (wc); - increment = (increment < 0) ? 0 : increment; - } -+ 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; diff --git a/coreutils-i18n-un-expand-BOM.patch b/coreutils-i18n-un-expand-BOM.patch index 56e7fa5..2ccdcca 100644 --- a/coreutils-i18n-un-expand-BOM.patch +++ b/coreutils-i18n-un-expand-BOM.patch @@ -1,3 +1,17 @@ +From 7a7c776a4e228d180e74614fd8c8afcad5d4bdf7 Mon Sep 17 00:00:00 2001 +From: Jakub Martisko +Date: Thu, 7 Jul 2016 12:53:26 +0200 +Subject: [PATCH] coreutils-i18n-un-expand-BOM.patch + +--- + src/expand-common.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ + src/expand-common.h | 12 ++++++ + src/expand.c | 45 +++++++++++++++++++- + src/unexpand.c | 43 ++++++++++++++++++- + tests/expand/mb.sh | 71 ++++++++++++++++++++++++++++++++ + tests/unexpand/mb.sh | 59 ++++++++++++++++++++++++++ + 6 files changed, 342 insertions(+), 2 deletions(-) + diff --git a/src/expand-common.c b/src/expand-common.c index 4657e46..97cbb09 100644 --- a/src/expand-common.c @@ -10,8 +24,8 @@ index 4657e46..97cbb09 100644 #include "system.h" #include "die.h" #include "error.h" -@@ -85,6 +86,119 @@ add_tab_stop (uintmax_t tabval) - } +@@ -105,6 +106,119 @@ set_extend_size (uintmax_t tabval) + return ok; } +extern int @@ -40,12 +54,12 @@ index 4657e46..97cbb09 100644 +check_utf_locale(void) +{ + char* locale = setlocale (LC_CTYPE , NULL); -+ if (locale == NULL) ++ if (locale == NULL) + { + return false; + } + else if (strcasestr(locale, "utf8") == NULL && strcasestr(locale, "utf-8") == NULL) -+ { ++ { + return false; + } + return true; @@ -147,7 +161,7 @@ index 8cb2079..763bfda 100644 +extern bool +check_bom(FILE* fp, mb_file_t *mbf); + -+extern void ++extern void +print_bom(void); + /* Add tab stop TABVAL to the end of 'tab_list'. */ @@ -161,14 +175,13 @@ index 310b349..4136824 100644 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; - @@ -178,13 +191,13 @@ index 310b349..4136824 100644 + 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")); + } + } -+ ++ + + if (found_bom == true) + { @@ -212,7 +225,7 @@ index 310b349..4136824 100644 + { + if(using_utf_locale==false && found_bom==true) + { -+ /*First file conatined BOM header - locale was switched to UTF ++ /*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")); + } @@ -231,7 +244,7 @@ index 863a90a..5681b58 100644 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(); @@ -240,11 +253,11 @@ index 863a90a..5681b58 100644 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")); @@ -282,7 +295,7 @@ index 863a90a..5681b58 100644 + { + if(using_utf_locale==false && found_bom==true) + { -+ /*First file conatined BOM header - locale was switched to UTF ++ /*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")); + } @@ -301,7 +314,7 @@ index 031be7a..1621c84 100755 + + -+#BOM header test 1 ++#BOM header test 1 +printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ +1234567812345678123456781 +. . . . @@ -380,7 +393,7 @@ index 8d75652..9d4ee3e 100755 unexpand -a < in > out || fail=1 compare exp out > /dev/null 2>&1 || fail=1 + -+#BOM header test 1 ++#BOM header test 1 +printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_ +1234567812345678123456781 +. . . . @@ -438,3 +451,6 @@ index 8d75652..9d4ee3e 100755 + +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 +-- +2.9.3 + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index d7cf59c..ab5d8dc 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -315,7 +315,7 @@ index 8cd0d6b..d23edd5 100644 + fwrite (line_out, sizeof(char), offset_out, stdout); + START_NEW_LINE; + continue; -+ ++ + case L'\b': + increment = (column > 0) ? -1 : 0; + break; @@ -672,7 +672,7 @@ index 98b461c..9990f38 100644 + extract_field (line, ptr, lim - ptr); +} +#endif -+ ++ static void freeline (struct line *line) { @@ -2843,7 +2843,7 @@ index 87a0c93..9f755d9 100644 + while (pos < size) + { + MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); -+ ++ + if (convfail || !(iswblank (wc) || wc == '\n')) + { + pos += mblength; @@ -2886,7 +2886,7 @@ index 87a0c93..9f755d9 100644 if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -295,14 +401,103 @@ different (char *old, char *new, size_t oldlen, size_t newlen) +@@ -295,15 +401,104 @@ different (char *old, char *new, size_t oldlen, size_t newlen) if (ignore_case) { @@ -2918,8 +2918,8 @@ index 87a0c93..9f755d9 100644 + + return xmemcoll (copy_old, oldlen, copy_new, newlen); + -+} -+ + } + +#if HAVE_MBRTOWC +static int +different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) @@ -2990,11 +2990,12 @@ index 87a0c93..9f755d9 100644 + free (copy[1]); + return rc; + - } ++} +#endif - ++ /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. + MATCH is true if the line matches the previous line. @@ -367,19 +562,38 @@ check_file (const char *infile, const char *outfile, char delimiter) char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); @@ -3156,7 +3157,7 @@ diff --git a/tests/local.mk b/tests/local.mk index 568944e..192f776 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -350,6 +350,8 @@ all_tests = \ +@@ -352,6 +352,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -3211,8 +3212,8 @@ index 8a9cad1..9293e39 100755 my @Tests = ( ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], -@@ -140,6 +149,8 @@ my @Tests = - +@@ -152,6 +161,8 @@ my @Tests = + ['trail9', '--tab=1,2 -t/5',{IN=>"\ta\tb\tc"}, {OUT=>" a b c"}], # Test errors + # FIXME: The following tests contain ‘quoting’ specific to LC_MESSAGES @@ -3220,8 +3221,8 @@ index 8a9cad1..9293e39 100755 ['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}, -@@ -150,6 +161,37 @@ my @Tests = - {ERR => "$prog: tab sizes must be ascending\n"}], +@@ -168,6 +179,37 @@ my @Tests = + {ERR => "$prog: '/' specifier not at start of number: '/'\n"}], ); +if ($mb_locale ne 'C') @@ -3533,7 +3534,7 @@ index c3e7f8e..6ecd3ff 100755 # Since each test is run with a file name and with redirected stdin, # the name in the diagnostic is either the file name or "-". # Normalize each diagnostic to use '-'. -@@ -424,6 +429,38 @@ foreach my $t (@Tests) +@@ -423,6 +428,38 @@ foreach my $t (@Tests) } } @@ -3572,7 +3573,7 @@ index c3e7f8e..6ecd3ff 100755 @Tests = triple_test \@Tests; # Remember that triple_test creates from each test with exactly one "IN" -@@ -433,6 +470,7 @@ foreach my $t (@Tests) +@@ -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; diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index cee4f7c..8274a23 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -48,7 +48,7 @@ index 1b528c6..25dbb88 100644 + case 'c': + fprintf (stderr, "%s: warning: option '-c' is deprecated, please use '--preserve=context' instead\n", argv[0]); -+ if ( x.set_security_context ) { ++ if ( x.set_security_context ) { + (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]); + exit( 1 ); + } diff --git a/coreutils.spec b/coreutils.spec index a2899d7..0af685d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,11 +1,11 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.26 -Release: 7%{?dist} +Version: 8.27 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base -Url: http://www.gnu.org/software/coreutils/ -Source0: ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +Url: https://www.gnu.org/software/coreutils/ +Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source50: supported_utils Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh @@ -19,9 +19,6 @@ Source10: coreutils-find-requires.sh # disable the test-lock gnulib test prone to deadlock Patch1: coreutils-8.26-test-lock.patch -# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=851934#10 -Patch2: coreutils-8.26-date-fix-tz-regre.patch - #add note about no difference between binary/text mode on Linux - md5sum manpage Patch101: coreutils-6.10-manpages.patch # downstream changes to default DIR_COLORS @@ -172,6 +169,8 @@ including documentation and translations. # will be modified by coreutils-8.25-DIR_COLORS.patch tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null +# git add DIR_COLORS{,.256color,.lightbgcolor} +# git commit -m "clone DIR_COLORS before patching" # apply all patches %autopatch -p1 @@ -301,6 +300,9 @@ fi %license COPYING %changelog +* Thu Mar 09 2017 Kamil Dudka - 8.27-1 +- new upstream release 8.27 + * Fri Feb 10 2017 Fedora Release Engineering - 8.26-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild diff --git a/sources b/sources index becdeb6..2566cf4 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -d5aa2072f662d4118b9f4c63b94601a6 coreutils-8.26.tar.xz +SHA512 (coreutils-8.27.tar.xz) = abf3280aaa54e9bd5851df0eda2af1de1017ca174633e52d1e592455d46ea0e99812dda46d2f320e979553cef271485d8818c595bba6ed31264511a511c93679 From 4ceb7222e4ce09a1b0816de5fe1f1f5925269ba5 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 15 Mar 2017 10:16:30 +0100 Subject: [PATCH 340/523] fix spurious build failure caused by the misc/date-debug test --- coreutils-8.27-date-debug-test.patch | 50 ++++++++++++++++++++++++++++ coreutils.spec | 10 ++++-- 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 coreutils-8.27-date-debug-test.patch diff --git a/coreutils-8.27-date-debug-test.patch b/coreutils-8.27-date-debug-test.patch new file mode 100644 index 0000000..a8def7b --- /dev/null +++ b/coreutils-8.27-date-debug-test.patch @@ -0,0 +1,50 @@ +From ee2017f191f1ad177405fbd8816df0a55127804a Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 9 Mar 2017 23:59:05 -0800 +Subject: [PATCH] tests: port to tzdb-2017a + +Problem reported by Bernhard Voelker in: +http://lists.gnu.org/archive/html/coreutils/2017-03/msg00026.html +* tests/misc/date-debug.sh: Port test to tzdb 2017a, +and future-proof the America/Belize test. + +Upstream-commit: 612086660bab9bf981894da146550e9101224b17 +Signed-off-by: Kamil Dudka +--- + tests/misc/date-debug.sh | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/tests/misc/date-debug.sh b/tests/misc/date-debug.sh +index 48f4605..8e0b2af 100755 +--- a/tests/misc/date-debug.sh ++++ b/tests/misc/date-debug.sh +@@ -52,10 +52,11 @@ date: output timezone: +09:00 (set from TZ="Asia/Tokyo" environment value) + date: final: 661095000.000000000 (epoch-seconds) + date: final: (Y-M-D) 1990-12-13 13:30:00 (UTC0) + date: final: (Y-M-D) 1990-12-13 22:30:00 (output timezone TZ=+09:00) +-Thu Dec 13 07:30:00 CST 1990 ++Thu Dec 13 07:30:00 -0600 1990 + EOF + +-TZ=America/Belize date --debug -d "$in1" >out1 2>&1 || fail=1 ++TZ=America/Belize date --debug -d "$in1" +'%a %b %e %T %z %Y' >out1 2>&1 || ++ fail=1 + + compare exp1 out1 || fail=1 + +@@ -94,10 +95,10 @@ date: output timezone: -05:00 (set from TZ="America/Lima" environment value) + date: final: 1.000000000 (epoch-seconds) + date: final: (Y-M-D) 1970-01-01 00:00:01 (UTC0) + date: final: (Y-M-D) 1969-12-31 19:00:01 (output timezone TZ=-05:00) +-Wed Dec 31 19:00:01 PET 1969 ++Wed Dec 31 19:00:01 -0500 1969 + EOF + +-TZ=America/Lima date --debug -d "$in3" >out3 2>&1 || fail=1 ++TZ=America/Lima date --debug -d "$in3" +'%a %b %e %T %z %Y' >out3 2>&1 || fail=1 + compare exp3 out3 || fail=1 + + ## +-- +2.9.3 + diff --git a/coreutils.spec b/coreutils.spec index 0af685d..4744830 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -16,8 +16,11 @@ Source10: coreutils-find-requires.sh %global __find_provides %{_rpmconfigdir}/find-provides %global __find_requires %{SOURCE10} %{_rpmconfigdir}/find-requires +# upstream patches +Patch1: coreutils-8.27-date-debug-test.patch + # disable the test-lock gnulib test prone to deadlock -Patch1: coreutils-8.26-test-lock.patch +Patch100: coreutils-8.26-test-lock.patch #add note about no difference between binary/text mode on Linux - md5sum manpage Patch101: coreutils-6.10-manpages.patch @@ -300,6 +303,9 @@ fi %license COPYING %changelog +* Wed Mar 15 2017 Kamil Dudka - 8.27-2 +- fix spurious build failure caused by the misc/date-debug test + * Thu Mar 09 2017 Kamil Dudka - 8.27-1 - new upstream release 8.27 From 3d65658099fc016b2a0c90f0a2ebc7403bfcd00c Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 25 Apr 2017 13:43:39 +0200 Subject: [PATCH 341/523] Resolves: #1444802 - do not obsolete coreutils-single, so it can be installed by DNF2 This reverts commit c553cab787c2499ffaa36748a2de7c0e08fe31d5. --- coreutils.spec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 4744830..5e9e46b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -67,8 +67,6 @@ Patch950: coreutils-selinux.patch Conflicts: filesystem < 3 # To avoid clobbering installs Conflicts: coreutils-single -# To give priority to this package -Obsoletes: coreutils-single Provides: /bin/basename Provides: /bin/cat Provides: /bin/chgrp @@ -303,6 +301,9 @@ fi %license COPYING %changelog +* Tue Apr 25 2017 Kamil Dudka - 8.27-3 +- do not obsolete coreutils-single, so it can be installed by DNF2 (#1444802) + * Wed Mar 15 2017 Kamil Dudka - 8.27-2 - fix spurious build failure caused by the misc/date-debug test From e0567d54a78f817b054755885bb5f97a2ef690ee Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 27 Apr 2017 09:51:08 +0200 Subject: [PATCH 342/523] Resolves: CVE-2017-7476 - date, touch: fix out-of-bounds write via large TZ variable --- coreutils-8.27-CVE-2017-7476.patch | 189 +++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.27-CVE-2017-7476.patch diff --git a/coreutils-8.27-CVE-2017-7476.patch b/coreutils-8.27-CVE-2017-7476.patch new file mode 100644 index 0000000..23fdb3f --- /dev/null +++ b/coreutils-8.27-CVE-2017-7476.patch @@ -0,0 +1,189 @@ +From fc286e2b3af5b2ed9aec44b520265bb0968f1660 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Mon, 24 Apr 2017 01:43:36 -0700 +Subject: [PATCH 1/2] time_rz: fix heap buffer overflow vulnerability + +This issue has been assigned CVE-2017-7476 and was +detected with American Fuzzy Lop 2.41b run on the +coreutils date(1) program with ASAN enabled. + + ERROR: AddressSanitizer: heap-buffer-overflow on address 0x... + WRITE of size 8 at 0x60d00000cff8 thread T0 + #1 0x443020 in extend_abbrs lib/time_rz.c:88 + #2 0x443356 in save_abbr lib/time_rz.c:155 + #3 0x44393f in localtime_rz lib/time_rz.c:290 + #4 0x41e4fe in parse_datetime2 lib/parse-datetime.y:1798 + +A minimized reproducer is the following 120 byte TZ value, +which goes beyond the value of ABBR_SIZE_MIN (119) on x86_64. +Extend the aa...b portion to overwrite more of the heap. + + date -d $(printf 'TZ="aaa%020daaaaaab%089d"') + +localtime_rz and mktime_z were affected since commit 4bc76593. +parse_datetime was affected since commit 4e6e16b3f. + +* lib/time_rz.c (save_abbr): Rearrange the calculation determining +whether there is enough buffer space available. The rearrangement +ensures we're only dealing with positive numbers, thus avoiding +the problematic promotion of signed to unsigned causing an invalid +comparison when zone_copy is more than ABBR_SIZE_MIN bytes beyond +the start of the buffer. +* tests/test-parse-datetime.c (main): Add a test case written by +Paul Eggert, which overwrites enough of the heap so that +standard glibc will fail with "free(): invalid pointer" +without the patch applied. +Reported and analyzed at https://bugzilla.redhat.com/1444774 + +Upstream-commit: 94e01571507835ff59dd8ce2a0b56a4b566965a4 +Signed-off-by: Kamil Dudka +--- + gnulib-tests/test-parse-datetime.c | 16 ++++++++++++++++ + lib/time_rz.c | 15 +++++++++++++-- + 2 files changed, 29 insertions(+), 2 deletions(-) + +diff --git a/gnulib-tests/test-parse-datetime.c b/gnulib-tests/test-parse-datetime.c +index b42a51c..b6fe457 100644 +--- a/gnulib-tests/test-parse-datetime.c ++++ b/gnulib-tests/test-parse-datetime.c +@@ -432,5 +432,21 @@ main (int argc _GL_UNUSED, char **argv) + ASSERT ( parse_datetime (&result, "TZ=\"\\\\\"", &now)); + ASSERT ( parse_datetime (&result, "TZ=\"\\\"\"", &now)); + ++ /* Outlandishly-long time zone abbreviations should not cause problems. */ ++ { ++ static char const bufprefix[] = "TZ=\""; ++ enum { tzname_len = 2000 }; ++ static char const bufsuffix[] = "0\" 1970-01-01 01:02:03.123456789"; ++ enum { bufsize = sizeof bufprefix - 1 + tzname_len + sizeof bufsuffix }; ++ char buf[bufsize]; ++ memcpy (buf, bufprefix, sizeof bufprefix - 1); ++ memset (buf + sizeof bufprefix - 1, 'X', tzname_len); ++ strcpy (buf + bufsize - sizeof bufsuffix, bufsuffix); ++ ASSERT (parse_datetime (&result, buf, &now)); ++ LOG (buf, now, result); ++ ASSERT (result.tv_sec == 1 * 60 * 60 + 2 * 60 + 3 ++ && result.tv_nsec == 123456789); ++ } ++ + return 0; + } +diff --git a/lib/time_rz.c b/lib/time_rz.c +index adb9c1c..c41a8ef 100644 +--- a/lib/time_rz.c ++++ b/lib/time_rz.c +@@ -27,6 +27,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -35,6 +36,10 @@ + #include "flexmember.h" + #include "time-internal.h" + ++#ifndef SIZE_MAX ++# define SIZE_MAX ((size_t) -1) ++#endif ++ + #if !HAVE_TZSET + static void tzset (void) { } + #endif +@@ -43,7 +48,7 @@ static void tzset (void) { } + the largest "small" request for the GNU C library malloc. */ + enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; + +-/* Minimum size of the ABBRS member of struct abbr. ABBRS is larger ++/* Minimum size of the ABBRS member of struct tm_zone. ABBRS is larger + only in the unlikely case where an abbreviation longer than this is + used. */ + enum { ABBR_SIZE_MIN = DEFAULT_MXFAST - offsetof (struct tm_zone, abbrs) }; +@@ -150,7 +155,13 @@ save_abbr (timezone_t tz, struct tm *tm) + if (! (*zone_copy || (zone_copy == tz->abbrs && tz->tz_is_set))) + { + size_t zone_size = strlen (zone) + 1; +- if (zone_size < tz->abbrs + ABBR_SIZE_MIN - zone_copy) ++ size_t zone_used = zone_copy - tz->abbrs; ++ if (SIZE_MAX - zone_used < zone_size) ++ { ++ errno = ENOMEM; ++ return false; ++ } ++ if (zone_used + zone_size < ABBR_SIZE_MIN) + extend_abbrs (zone_copy, zone, zone_size); + else + { +-- +2.9.3 + + +From 9579f90484c71e5a22f32f35189192a82e47550e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Wed, 26 Apr 2017 20:51:39 -0700 +Subject: [PATCH 2/2] date,touch: test and document large TZ security issue + +Add a test for CVE-2017-7476 which was fixed in gnulib at: +http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=94e01571 + +* tests/misc/date-tz.sh: Add a new test which overwrites enough +of the heap to trigger a segfault, even without ASAN enabled. +* tests/local.mk: Reference the new test. +* NEWS: Mention the bug fix. + +Upstream-commit: 9287ef2b1707e2a222f8ae776ce3785abcb16fba +Signed-off-by: Kamil Dudka +--- + tests/local.mk | 1 + + tests/misc/date-tz.sh | 26 ++++++++++++++++++++++++++ + 2 files changed, 27 insertions(+) + create mode 100755 tests/misc/date-tz.sh + +diff --git a/tests/local.mk b/tests/local.mk +index 9f1a853..ec0b414 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -282,6 +282,7 @@ all_tests = \ + tests/misc/csplit-suppress-matched.pl \ + tests/misc/date-debug.sh \ + tests/misc/date-sec.sh \ ++ tests/misc/date-tz.sh \ + tests/misc/dircolors.pl \ + tests/misc/dirname.pl \ + tests/misc/env-null.sh \ +diff --git a/tests/misc/date-tz.sh b/tests/misc/date-tz.sh +new file mode 100755 +index 0000000..3fe1579 +--- /dev/null ++++ b/tests/misc/date-tz.sh +@@ -0,0 +1,26 @@ ++#!/bin/sh ++# Verify TZ processing. ++ ++# Copyright (C) 2017 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_ date ++ ++# coreutils-8.27 would overwrite the heap with large TZ values ++tz_long=$(printf '%2000s' | tr ' ' a) ++date -d "TZ=\"${tz_long}0\" 2017" || fail=1 ++ ++Exit $fail +-- +2.9.3 + diff --git a/coreutils.spec b/coreutils.spec index 5e9e46b..199d2e4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -19,6 +19,9 @@ Source10: coreutils-find-requires.sh # upstream patches Patch1: coreutils-8.27-date-debug-test.patch +# date, touch: fix out-of-bounds write via large TZ variable (CVE-2017-7476) +Patch2: coreutils-8.27-CVE-2017-7476.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -301,6 +304,9 @@ fi %license COPYING %changelog +* Thu Apr 27 2017 Kamil Dudka - 8.27-4 +- date, touch: fix out-of-bounds write via large TZ variable (CVE-2017-7476) + * Tue Apr 25 2017 Kamil Dudka - 8.27-3 - do not obsolete coreutils-single, so it can be installed by DNF2 (#1444802) From e00cb1843f7384b4682280a1a56cef58bdc8106f Mon Sep 17 00:00:00 2001 From: Sebastian Kisela Date: Fri, 28 Apr 2017 12:48:03 +0200 Subject: [PATCH 343/523] tail: revert to polling if a followed directory is replaced (#1283760) --- coreutils-8.27-tail-inotify-recreate.patch | 168 +++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.27-tail-inotify-recreate.patch diff --git a/coreutils-8.27-tail-inotify-recreate.patch b/coreutils-8.27-tail-inotify-recreate.patch new file mode 100644 index 0000000..1a63655 --- /dev/null +++ b/coreutils-8.27-tail-inotify-recreate.patch @@ -0,0 +1,168 @@ +From ba5fe2d4b8b6a8366f48b1ad1f97fe26c9089b53 Mon Sep 17 00:00:00 2001 +From: Sebastian Kisela +Date: Wed, 5 Apr 2017 09:40:41 +0200 +Subject: [PATCH] tail: revert to polling if a followed directory is replaced + +* src/tail.c (tail_forever_inotify): Add the IN_DELETE_SELF flag when +creating watch for the parent directory. After the parent directory +is removed, an event is caught and then we switch from inotify to +polling mode. Till now, inotify has always frozen because it waited for +an event from a watched dir, which has been already deleted and was not +added again. +* tests/tail-2/inotify-dir-recreate.sh: Add a test case. +* tests/local.mk: Reference the new test. +Fixes http://bugs.gnu.org/26363 +Reported at https://bugzilla.redhat.com/1283760 + +Upstream-commit: ba5fe2d4b8b6a8366f48b1ad1f97fe26c9089b53 + +--- + src/tail.c | 22 +++++++++- + tests/local.mk | 1 + + tests/tail-2/inotify-dir-recreate.sh | 82 ++++++++++++++++++++++++++++++++++++ + 4 files changed, 107 insertions(+), 1 deletion(-) + create mode 100755 tests/tail-2/inotify-dir-recreate.sh + +diff --git a/src/tail.c b/src/tail.c +index d1552d4..6328fe0 100644 +--- a/src/tail.c ++++ b/src/tail.c +@@ -1457,7 +1457,8 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files, + In that case the same watch descriptor is returned. */ + f[i].parent_wd = inotify_add_watch (wd, dirlen ? f[i].name : ".", + (IN_CREATE | IN_DELETE +- | IN_MOVED_TO | IN_ATTRIB)); ++ | IN_MOVED_TO | IN_ATTRIB ++ | IN_DELETE_SELF)); + + f[i].name[dirlen] = prev; + +@@ -1628,6 +1629,25 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files, + ev = void_ev; + evbuf_off += sizeof (*ev) + ev->len; + ++ /* If a directory is deleted, IN_DELETE_SELF is emitted ++ with ev->name of length 0. ++ We need to catch it, otherwise it would wait forever, ++ as wd for directory becomes inactive. Revert to polling now. */ ++ if ((ev->mask & IN_DELETE_SELF) && ! ev->len) ++ { ++ for (i = 0; i < n_files; i++) ++ { ++ if (ev->wd == f[i].parent_wd) ++ { ++ hash_free (wd_to_name); ++ error (0, 0, ++ _("directory containing watched file was removed")); ++ errno = 0; /* we've already diagnosed enough errno detail. */ ++ return true; ++ } ++ } ++ } ++ + if (ev->len) /* event on ev->name in watched directory. */ + { + size_t j; +diff --git a/tests/local.mk b/tests/local.mk +index 3fe9ba8..e890c9a 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -176,6 +176,7 @@ all_tests = \ + tests/tail-2/descriptor-vs-rename.sh \ + tests/tail-2/inotify-rotate.sh \ + tests/tail-2/inotify-rotate-resources.sh \ ++ tests/tail-2/inotify-dir-recreate.sh \ + tests/chmod/no-x.sh \ + tests/chgrp/basic.sh \ + tests/rm/dangling-symlink.sh \ +diff --git a/tests/tail-2/inotify-dir-recreate.sh b/tests/tail-2/inotify-dir-recreate.sh +new file mode 100755 +index 0000000..eaa8422 +--- /dev/null ++++ b/tests/tail-2/inotify-dir-recreate.sh +@@ -0,0 +1,82 @@ ++#!/bin/sh ++# Makes sure, inotify will switch to polling mode if directory ++# of the watched file was removed and recreated. ++# (...instead of getting stuck forever) ++ ++# Copyright (C) 2006-2017 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ tail ++ ++ ++# Terminate any background tail process ++cleanup_() { kill $pid 2>/dev/null && wait $pid; } ++ ++cleanup_fail_ () ++{ ++ warn_ $1 ++ cleanup_ ++ fail=1 ++} ++ ++# $check_re - string to be found ++# $check_f - file to be searched ++check_tail_output_ () ++{ ++ local delay="$1" ++ grep $check_re $check_f > /dev/null || ++ { sleep $delay ; return 1; } ++} ++ ++grep_timeout_ () ++{ ++ check_re="$1" ++ check_f="$2" ++ retry_delay_ check_tail_output_ .1 5 ++} ++ ++# Prepare the file to be watched ++mkdir dir && echo 'inotify' > dir/file || framework_failure_ ++ ++#tail must print content of the file to stdout, verify ++timeout 60 tail -F dir/file &>out & pid=$! ++grep_timeout_ 'inotify' 'out' || ++{ cleanup_fail_ 'file to be tailed does not exist'; } ++ ++# Remove the directory, should get the message about the deletion ++rm -r dir || framework_failure_ ++grep_timeout_ 'polling' 'out' || ++{ cleanup_fail_ 'tail did not switch to polling mode'; } ++ ++# Recreate the dir, must get a message about recreation ++mkdir dir && touch dir/file || framework_failure_ ++grep_timeout_ 'appeared' 'out' || ++{ cleanup_fail_ 'previously removed file did not appear'; } ++ ++cleanup_ ++ ++# Expected result for the whole process ++cat <<\EOF > exp || framework_failure_ ++inotify ++tail: 'dir/file' has become inaccessible: No such file or directory ++tail: directory containing watched file was removed ++tail: inotify cannot be used, reverting to polling ++tail: 'dir/file' has appeared; following new file ++EOF ++ ++compare exp out || fail=1 ++ ++Exit $fail +-- +2.9.3 + diff --git a/coreutils.spec b/coreutils.spec index 199d2e4..5979119 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -22,6 +22,9 @@ Patch1: coreutils-8.27-date-debug-test.patch # date, touch: fix out-of-bounds write via large TZ variable (CVE-2017-7476) Patch2: coreutils-8.27-CVE-2017-7476.patch +# tail: revert to polling if a followed directory is replaced +Patch3: coreutils-8.27-tail-inotify-recreate.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -304,6 +307,9 @@ fi %license COPYING %changelog +* Fri Apr 28 2017 Sebastian Kisela - 8.27-5 +- tail: revert to polling if a followed directory is replaced + * Thu Apr 27 2017 Kamil Dudka - 8.27-4 - date, touch: fix out-of-bounds write via large TZ variable (CVE-2017-7476) From b9d157d0ce266b8fe3f3eac43a60d61f85c29a7a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 3 May 2017 13:04:16 +0200 Subject: [PATCH 344/523] drop unnecessary uses of %defattr --- coreutils.spec | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 5979119..e5ef88d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -22,7 +22,7 @@ Patch1: coreutils-8.27-date-debug-test.patch # date, touch: fix out-of-bounds write via large TZ variable (CVE-2017-7476) Patch2: coreutils-8.27-CVE-2017-7476.patch -# tail: revert to polling if a followed directory is replaced +# tail: revert to polling if a followed directory is replaced (#1283760) Patch3: coreutils-8.27-tail-inotify-recreate.patch # disable the test-lock gnulib test prone to deadlock @@ -283,12 +283,10 @@ if [ -f %{_infodir}/%{name}.info.gz ]; then fi %files -f supported_utils -%defattr(-,root,root,-) %exclude %{_bindir}/*.single %{_libexecdir}/coreutils/*.so %files single -%defattr(-,root,root,-) %{_bindir}/*.single %{_sbindir}/chroot.single %{_libexecdir}/coreutils/*.so.single @@ -297,7 +295,6 @@ fi %license COPYING %files common -f %{name}.lang -%defattr(-,root,root,-) %config(noreplace) %{_sysconfdir}/DIR_COLORS* %config(noreplace) %{_sysconfdir}/profile.d/* %{_infodir}/coreutils* @@ -307,8 +304,11 @@ fi %license COPYING %changelog +* Wed May 03 2017 Kamil Dudka - 8.27-6 +- drop unnecessary uses of %%defattr + * Fri Apr 28 2017 Sebastian Kisela - 8.27-5 -- tail: revert to polling if a followed directory is replaced +- tail: revert to polling if a followed directory is replaced (#1283760) * Thu Apr 27 2017 Kamil Dudka - 8.27-4 - date, touch: fix out-of-bounds write via large TZ variable (CVE-2017-7476) From e0b67f5aa96fa940745ce37a666fd900e4c4a123 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 3 May 2017 12:41:53 +0200 Subject: [PATCH 345/523] Related: #246729 - drop workaround no longer needed for 10 years old rpm-build bug --- coreutils.spec | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index e5ef88d..a80b161 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -254,17 +254,8 @@ install -p -c -m644 DIR_COLORS{,.256color,.lightbgcolor} \ install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh -# Use hard links instead of symbolic links for LC_TIME files (bug #246729). -find %{buildroot}%{_datadir}/locale -type l | \ -(while read link - do - target=$(readlink "$link") - rm -f "$link" - ln "$(dirname "$link")/$target" "$link" - done) - %find_lang %name -#Add the %lang(xyz) ownership for the LC_TIME dirs as well... +# Add the %%lang(xyz) ownership for the LC_TIME dirs as well... grep LC_TIME %name.lang | cut -d'/' -f1-6 | sed -e 's/) /) %%dir /g' >>%name.lang # (sb) Deal with Installed (but unpackaged) file(s) found @@ -305,6 +296,7 @@ fi %changelog * Wed May 03 2017 Kamil Dudka - 8.27-6 +- drop workaround no longer needed for 10 years old rpm-build bug (#246729) - drop unnecessary uses of %%defattr * Fri Apr 28 2017 Sebastian Kisela - 8.27-5 From 28873d6a702898497a707c3e57f0c68f86b5196a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 3 May 2017 13:01:02 +0200 Subject: [PATCH 346/523] do not mention a deprecated option in localized man pages --- coreutils.spec | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index a80b161..24e789f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -186,11 +186,6 @@ tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+' (echo "<<< done") 2>/dev/null -#fix typos/mistakes in localized documentation(#439410, #440056) -find ./po/ -name "*.p*" | xargs \ - sed -i \ - -e 's/-dpR/-cdpR/' - autoreconf -fiv %build @@ -296,6 +291,7 @@ fi %changelog * Wed May 03 2017 Kamil Dudka - 8.27-6 +- do not mention a deprecated option in localized man pages - drop workaround no longer needed for 10 years old rpm-build bug (#246729) - drop unnecessary uses of %%defattr From 34aa75941591479a138ec455ecf9cd50f0b9d04c Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 3 May 2017 13:40:56 +0200 Subject: [PATCH 347/523] Related: #1306559 - drop workaround for already fixed rpm-build bug --- coreutils-find-requires.sh | 25 ------------------------- coreutils.spec | 12 ++++++------ 2 files changed, 6 insertions(+), 31 deletions(-) delete mode 100755 coreutils-find-requires.sh diff --git a/coreutils-find-requires.sh b/coreutils-find-requires.sh deleted file mode 100755 index 27d1368..0000000 --- a/coreutils-find-requires.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -# Reduce requires for coreutils-single -# Needed since it has overlapping "binaries" with the main package -# Ideally we could do the following in the spec only for the single subpackage -# %define __requires_exclude_from ^(%{_bindir}|%{_sbindir})/([^c]|c[^o]|co[^r]|cor[^e]) - -original_find_requires="$1" -shift - -# Get the list of files. -files=`sed "s/['\"]/\\\&/g"` - -single_bin='/usr/bin/coreutils' - -single=`echo $files | grep "$single_bin"` - -echo $files | tr [:blank:] '\n' | -if [ "$single" ]; then - # Only allow the coreutils multicall binary - # Also adjust for .single renaming - sed -n 's|\(.*'"$single_bin"'\)\(.single\)\?$|\1.single|p' -else - cat -fi | -$original_find_requires diff --git a/coreutils.spec b/coreutils.spec index 24e789f..eb5455e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -10,11 +10,8 @@ Source50: supported_utils Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh -# Provide our own custom requires for coreutils-single package -Source10: coreutils-find-requires.sh -%global _use_internal_dependency_generator 0 -%global __find_provides %{_rpmconfigdir}/find-provides -%global __find_requires %{SOURCE10} %{_rpmconfigdir}/find-requires +# do not make coreutils-single depend on /usr/bin/coreutils +%global __requires_exclude ^%{_bindir}/coreutils$ # upstream patches Patch1: coreutils-8.27-date-debug-test.patch @@ -290,6 +287,9 @@ fi %license COPYING %changelog +* Wed May 03 2017 Kamil Dudka - 8.27-7 +- drop workaround for already fixed rpm-build bug (#1306559) + * Wed May 03 2017 Kamil Dudka - 8.27-6 - do not mention a deprecated option in localized man pages - drop workaround no longer needed for 10 years old rpm-build bug (#246729) From fde94e26096e7eaff4d936e2ec1b882621cc5c09 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 3 May 2017 15:42:49 +0200 Subject: [PATCH 348/523] Related: #158405 - drop coreutils-overflow.patch no longer needed The bug was fixed by the following upstream commit 13 years ago: http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=COREUTILS-5_2_1-705-g5bca9fb --- coreutils-overflow.patch | 13 ------------- coreutils.spec | 7 ++++--- 2 files changed, 4 insertions(+), 16 deletions(-) delete mode 100644 coreutils-overflow.patch diff --git a/coreutils-overflow.patch b/coreutils-overflow.patch deleted file mode 100644 index d62b19a..0000000 --- a/coreutils-overflow.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/who.c b/src/who.c -index 55733b4..3ad4774 100644 ---- a/src/who.c -+++ b/src/who.c -@@ -81,7 +81,7 @@ - # define UT_TYPE_NEW_TIME(U) false - #endif - --#define IDLESTR_LEN 6 -+#define IDLESTR_LEN 10 - - #if HAVE_STRUCT_XTMP_UT_PID - # define PIDSTR_DECL_AND_INIT(Var, Utmp_ent) \ diff --git a/coreutils.spec b/coreutils.spec index eb5455e..203e7cf 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -60,8 +60,6 @@ Patch808: coreutils-i18n-fold-newline.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch -#Prevent buffer overflow in who(1) (bug #158405). -Patch912: coreutils-overflow.patch #SELINUX Patch - implements Redhat changes #(upstream did some SELinux implementation unlike with RedHat patch) @@ -287,6 +285,9 @@ fi %license COPYING %changelog +* Wed May 03 2017 Kamil Dudka - 8.27-8 +- drop coreutils-overflow.patch no longer needed (#158405) + * Wed May 03 2017 Kamil Dudka - 8.27-7 - drop workaround for already fixed rpm-build bug (#1306559) From 6f16afd4a6838ca2f01e46cb85688a0c2146587f Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 16 May 2017 14:15:41 +0200 Subject: [PATCH 349/523] add coreutils-full provides for coreutils ... to make it explicitly installable --- coreutils.spec | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 203e7cf..13f3ed9 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -122,14 +122,17 @@ BuildRequires: glibc-langpack-en Requires: %{name}-common = %{version}-%{release} Requires: ncurses +Provides: bundled(gnulib) +Provides: coreutils-full = %{version}-%{release} Provides: fileutils = %{version}-%{release} Provides: sh-utils = %{version}-%{release} Provides: stat = %{version}-%{release} Provides: textutils = %{version}-%{release} + #old mktemp package had epoch 3, so we have to use 4 for coreutils Provides: mktemp = 4:%{version}-%{release} -Provides: bundled(gnulib) Obsoletes: mktemp < 4:%{version}-%{release} + Obsoletes: fileutils <= 4.1.9 Obsoletes: sh-utils <= 2.0.12 Obsoletes: stat <= 3.3 @@ -285,6 +288,9 @@ fi %license COPYING %changelog +* Tue May 16 2017 Kamil Dudka - 8.27-9 +- add coreutils-full provides for coreutils to make it explicitly installable + * Wed May 03 2017 Kamil Dudka - 8.27-8 - drop coreutils-overflow.patch no longer needed (#158405) From 8d0221274232d140047e21d423a183f8b3a236ec Mon Sep 17 00:00:00 2001 From: Sebastian Kisela Date: Tue, 30 May 2017 09:39:28 +0200 Subject: [PATCH 350/523] doc: mention `setpriv --no-new-privs` feature in runcon info * doc/coreutils.texi (runcon invocation): Mention setpriv usage. Discussed at https://bugzilla.redhat.com/1360903 --- coreutils-8.27-runcon-doc.patch | 33 +++++++++++++++++++++++++++++++++ coreutils.spec | 8 +++++++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.27-runcon-doc.patch diff --git a/coreutils-8.27-runcon-doc.patch b/coreutils-8.27-runcon-doc.patch new file mode 100644 index 0000000..41c0a8a --- /dev/null +++ b/coreutils-8.27-runcon-doc.patch @@ -0,0 +1,33 @@ +From 76be8a7f9eb717b3d47009eb25d39fe7139a2c2d Mon Sep 17 00:00:00 2001 +From: Sebastian Kisela +Date: Tue, 30 May 2017 09:29:32 +0200 +Subject: [PATCH] doc: mention `setpriv --no-new-privs` feature in runcon info + +upstream commit: 6ebaf8195000d6d3590a2eac13f13b158e325452 +--- + doc/coreutils.texi | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 68df075..e16e885 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -16583,7 +16583,14 @@ are interpreted as arguments to the command. + With neither @var{context} nor @var{command}, print the current + security context. + +-The program accepts the following options. Also see @ref{Common options}. ++@cindex restricted security context ++@cindex NO_NEW_PRIVS ++Note also the @command{setpriv} command which can be used to set the ++NO_NEW_PRIVS bit using @command{setpriv --no-new-privs runcon ...}, ++thus disallowing usage of a security context with more privileges ++than the process would normally have. ++ ++@command{runcon} accepts the following options. Also see @ref{Common options}. + + @table @samp + +-- +2.9.4 + diff --git a/coreutils.spec b/coreutils.spec index 13f3ed9..2fadd14 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -22,6 +22,9 @@ Patch2: coreutils-8.27-CVE-2017-7476.patch # tail: revert to polling if a followed directory is replaced (#1283760) Patch3: coreutils-8.27-tail-inotify-recreate.patch +# doc: mention `setpriv --no-new-privs` feature in runcon info +Patch4: coreutils-8.27-runcon-doc.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -288,6 +291,9 @@ fi %license COPYING %changelog +* Tue May 30 2017 Sebastian Kisela - 8.27-10 +- doc: mention `setpriv --no-new-privs` feature in runcon info + * Tue May 16 2017 Kamil Dudka - 8.27-9 - add coreutils-full provides for coreutils to make it explicitly installable From 8fd1881fe2e138499d19e9987f12865acf53744c Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 26 Jul 2017 05:30:55 +0000 Subject: [PATCH 351/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 2fadd14..75442f1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -291,6 +291,9 @@ fi %license COPYING %changelog +* Wed Jul 26 2017 Fedora Release Engineering - 8.27-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + * Tue May 30 2017 Sebastian Kisela - 8.27-10 - doc: mention `setpriv --no-new-privs` feature in runcon info From 28658db74496997acdfd865a9003c4669199569b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 26 Jul 2017 16:47:43 +0200 Subject: [PATCH 352/523] avoid build failure caused broken RPM code ... that produces debuginfo packages Bug: https://github.com/rpm-software-management/rpm/issues/280 --- coreutils.spec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 75442f1..51107f8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,11 @@ +# avoid build failure caused broken RPM code that produces debuginfo packages +# reported at https://github.com/rpm-software-management/rpm/issues/280 +%undefine _debuginfo_subpackages + Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -291,6 +295,9 @@ fi %license COPYING %changelog +* Wed Jul 26 2017 Kamil Dudka - 8.27-12 +- avoid build failure caused broken RPM code that produces debuginfo packages + * Wed Jul 26 2017 Fedora Release Engineering - 8.27-11 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild From 8401ff18e33727d5e9216b8ed11187d0eedbdcf5 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Fri, 28 Jul 2017 19:42:43 +0200 Subject: [PATCH 353/523] Enable separate debuginfo back Signed-off-by: Igor Gnatenko --- coreutils.spec | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 51107f8..cb884d3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,11 +1,7 @@ -# avoid build failure caused broken RPM code that produces debuginfo packages -# reported at https://github.com/rpm-software-management/rpm/issues/280 -%undefine _debuginfo_subpackages - Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -295,6 +291,9 @@ fi %license COPYING %changelog +* Fri Jul 28 2017 Igor Gnatenko - 8.27-13 +- Enable separate debuginfo back + * Wed Jul 26 2017 Kamil Dudka - 8.27-12 - avoid build failure caused broken RPM code that produces debuginfo packages From 353860c35c5c461ad77b5754a950c44af4eb6c65 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 2 Aug 2017 19:11:06 +0000 Subject: [PATCH 354/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index cb884d3..8c2e00d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 13%{?dist} +Release: 14%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -291,6 +291,9 @@ fi %license COPYING %changelog +* Wed Aug 02 2017 Fedora Release Engineering - 8.27-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + * Fri Jul 28 2017 Igor Gnatenko - 8.27-13 - Enable separate debuginfo back From d2d5d5d057349577871567a643eae6af84d81256 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 18 Aug 2017 17:52:50 +0200 Subject: [PATCH 355/523] Resolves: #1482445 - ptx: fix a possible crash caused by integer overflow --- coreutils-8.27-ptx-int-overflow.patch | 547 ++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 554 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.27-ptx-int-overflow.patch diff --git a/coreutils-8.27-ptx-int-overflow.patch b/coreutils-8.27-ptx-int-overflow.patch new file mode 100644 index 0000000..897c2ad --- /dev/null +++ b/coreutils-8.27-ptx-int-overflow.patch @@ -0,0 +1,547 @@ +From 7408a9758924a1ccbabf9fcab401a31ef1b7c755 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 17 Aug 2017 12:02:16 -0700 +Subject: [PATCH] ptx: fix some integer overflow bugs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Problem reported by Lukas Zachar at: +http://bugzilla.redhat.com/1482445 +* src/ptx.c (line_width, gap_size, maximum_word_length) +(reference_max_width, half_line_width, before_max_width) +(keyafter_max_width, truncation_string_length, compare_words) +(compare_occurs, search_table, find_occurs_in_text, print_spaces) +(fix_output_parameters, define_all_fields): +Use ptrdiff_t, not int, for object offsets and sizes. +(WORD, OCCURS): Use ptrdiff_t, not short int. +(WORD_TABLE, number_of_occurs, generate_all_output): +Prefer ptrdiff_t to size_t where either will do. +(total_line_count, file_line_count, OCCURS, fix_output_parameters) +(define_all_fields): +Use intmax_t, not int, for line counts. +(DELTA): Remove. All uses changed. +(OCCURS, find_occurs_in_text, fix_output_parameters): +Use int, not size_t, for file indexes. +(tail_truncation, before_truncation, keyafter_truncation) +(head_truncation, search_table, define_all_fields) +(generate_all_output): +Use bool for booleans. +(digest_word_file, find_occurs_in_text): +Use x2nrealloc instead of checking for overflow by hand. +(find_occurs_in_text, fix_output_parameters, define_all_fields): +Omit unnecessary cast. +(fix_output_parameters): Don’t assume integers fit in 11 digits. +(fix_output_parameters, define_all_fields): +Use sprintf return value rather than calling strlen. +(define_all_fields): Do not rely on sprintf to generate a string +that may contain more than INT_MAX bytes. +(main): Use xstrtoimax, not xstrtoul. +Use xnmalloc to catch integer overflow. + +Upstream-commit: 1d9765a764790cc68ec52c16d7ccbf633c404f0e +Signed-off-by: Kamil Dudka +--- + src/ptx.c | 194 +++++++++++++++++++++++++++++--------------------------------- + 1 file changed, 91 insertions(+), 103 deletions(-) + +diff --git a/src/ptx.c b/src/ptx.c +index c0c9733..2aababf 100644 +--- a/src/ptx.c ++++ b/src/ptx.c +@@ -59,9 +59,9 @@ + /* Global definitions. */ + + /* FIXME: There are many unchecked integer overflows in this file, +- that will cause this command to misbehave given large inputs or +- options. Many of the "int" values below should be "size_t" or +- something else like that. */ ++ and in theory they could cause this command to have undefined ++ behavior given large inputs or options. This command should ++ diagnose any such overflow and exit. */ + + /* Program options. */ + +@@ -77,8 +77,8 @@ static bool gnu_extensions = true; /* trigger all GNU extensions */ + static bool auto_reference = false; /* refs are 'file_name:line_number:' */ + static bool input_reference = false; /* refs at beginning of input lines */ + static bool right_reference = false; /* output refs after right context */ +-static int line_width = 72; /* output line width in characters */ +-static int gap_size = 3; /* number of spaces between output fields */ ++static ptrdiff_t line_width = 72; /* output line width in characters */ ++static ptrdiff_t gap_size = 3; /* number of spaces between output fields */ + static const char *truncation_string = "/"; + /* string used to mark line truncations */ + static const char *macro_name = "xx"; /* macro name for roff or TeX output */ +@@ -105,8 +105,8 @@ static struct regex_data context_regex; /* end of context */ + static struct regex_data word_regex; /* keyword */ + + /* A BLOCK delimit a region in memory of arbitrary size, like the copy of a +- whole file. A WORD is something smaller, its length should fit in a +- short integer. A WORD_TABLE may contain several WORDs. */ ++ whole file. A WORD is similar, except it is intended for smaller regions. ++ A WORD_TABLE may contain several WORDs. */ + + typedef struct + { +@@ -118,7 +118,7 @@ BLOCK; + typedef struct + { + char *start; /* pointer to beginning of region */ +- short int size; /* length of the region */ ++ ptrdiff_t size; /* length of the region */ + } + WORD; + +@@ -126,7 +126,7 @@ typedef struct + { + WORD *start; /* array of WORDs */ + size_t alloc; /* allocated length */ +- size_t length; /* number of used entries */ ++ ptrdiff_t length; /* number of used entries */ + } + WORD_TABLE; + +@@ -149,10 +149,10 @@ static struct re_registers word_regs; + static char word_fastmap[CHAR_SET_SIZE]; + + /* Maximum length of any word read. */ +-static int maximum_word_length; ++static ptrdiff_t maximum_word_length; + + /* Maximum width of any reference used. */ +-static int reference_max_width; ++static ptrdiff_t reference_max_width; + + /* Ignore and Only word tables. */ + +@@ -162,9 +162,9 @@ static WORD_TABLE only_table; /* table of words to select */ + /* Source text table, and scanning macros. */ + + static int number_input_files; /* number of text input files */ +-static int total_line_count; /* total number of lines seen so far */ ++static intmax_t total_line_count; /* total number of lines seen so far */ + static const char **input_file_name; /* array of text input file names */ +-static int *file_line_count; /* array of 'total_line_count' values at end */ ++static intmax_t *file_line_count; /* array of line count values at end */ + + static BLOCK *text_buffers; /* files to study */ + +@@ -219,20 +219,18 @@ static BLOCK *text_buffers; /* files to study */ + + When automatic references are used, the 'reference' value is the + overall line number in all input files read so far, in this case, it +- is of type (int). When input references are used, the 'reference' ++ is of type intmax_t. When input references are used, the 'reference' + value indicates the distance between the keyword beginning and the +- start of the reference field, it is of type (DELTA) and usually ++ start of the reference field, and it fits in ptrdiff_t and is usually + negative. */ + +-typedef short int DELTA; /* to hold displacement within one context */ +- + typedef struct + { + WORD key; /* description of the keyword */ +- DELTA left; /* distance to left context start */ +- DELTA right; /* distance to right context end */ +- int reference; /* reference descriptor */ +- size_t file_index; /* corresponding file */ ++ ptrdiff_t left; /* distance to left context start */ ++ ptrdiff_t right; /* distance to right context end */ ++ intmax_t reference; /* reference descriptor */ ++ int file_index; /* corresponding file */ + } + OCCURS; + +@@ -241,7 +239,7 @@ OCCURS; + + static OCCURS *occurs_table[1]; /* all words retained from the read text */ + static size_t occurs_alloc[1]; /* allocated size of occurs_table */ +-static size_t number_of_occurs[1]; /* number of used slots in occurs_table */ ++static ptrdiff_t number_of_occurs[1]; /* number of used slots in occurs_table */ + + + /* Communication among output routines. */ +@@ -249,10 +247,17 @@ static size_t number_of_occurs[1]; /* number of used slots in occurs_table */ + /* Indicate if special output processing is requested for each character. */ + static char edited_flag[CHAR_SET_SIZE]; + +-static int half_line_width; /* half of line width, reference excluded */ +-static int before_max_width; /* maximum width of before field */ +-static int keyafter_max_width; /* maximum width of keyword-and-after field */ +-static int truncation_string_length;/* length of string that flags truncation */ ++/* Half of line width, reference excluded. */ ++static ptrdiff_t half_line_width; ++ ++/* Maximum width of before field. */ ++static ptrdiff_t before_max_width; ++ ++/* Maximum width of keyword-and-after field. */ ++static ptrdiff_t keyafter_max_width; ++ ++/* Length of string that flags truncation. */ ++static ptrdiff_t truncation_string_length; + + /* When context is limited by lines, wraparound may happen on final output: + the 'head' pointer gives access to some supplementary left context which +@@ -261,16 +266,16 @@ static int truncation_string_length;/* length of string that flags truncation */ + beginning of the output line. */ + + static BLOCK tail; /* tail field */ +-static int tail_truncation; /* flag truncation after the tail field */ ++static bool tail_truncation; /* flag truncation after the tail field */ + + static BLOCK before; /* before field */ +-static int before_truncation; /* flag truncation before the before field */ ++static bool before_truncation; /* flag truncation before the before field */ + + static BLOCK keyafter; /* keyword-and-after field */ +-static int keyafter_truncation; /* flag truncation after the keyafter field */ ++static bool keyafter_truncation; /* flag truncation after the keyafter field */ + + static BLOCK head; /* head field */ +-static int head_truncation; /* flag truncation before the head field */ ++static bool head_truncation; /* flag truncation before the head field */ + + static BLOCK reference; /* reference field for input reference mode */ + +@@ -540,8 +545,8 @@ compare_words (const void *void_first, const void *void_second) + { + #define first ((const WORD *) void_first) + #define second ((const WORD *) void_second) +- int length; /* minimum of two lengths */ +- int counter; /* cursor in words */ ++ ptrdiff_t length; /* minimum of two lengths */ ++ ptrdiff_t counter; /* cursor in words */ + int value; /* value of comparison */ + + length = first->size < second->size ? first->size : second->size; +@@ -567,7 +572,7 @@ compare_words (const void *void_first, const void *void_second) + } + } + +- return first->size - second->size; ++ return first->size < second->size ? -1 : first->size > second->size; + #undef first + #undef second + } +@@ -586,21 +591,21 @@ compare_occurs (const void *void_first, const void *void_second) + int value; + + value = compare_words (&first->key, &second->key); +- return value == 0 ? first->key.start - second->key.start : value; ++ return (value ? value ++ : first->key.start < second->key.start ? -1 ++ : first->key.start > second->key.start); + #undef first + #undef second + } + +-/*------------------------------------------------------------. +-| Return !0 if WORD appears in TABLE. Uses a binary search. | +-`------------------------------------------------------------*/ ++/* True if WORD appears in TABLE. Uses a binary search. */ + +-static int _GL_ATTRIBUTE_PURE ++static bool _GL_ATTRIBUTE_PURE + search_table (WORD *word, WORD_TABLE *table) + { +- int lowest; /* current lowest possible index */ +- int highest; /* current highest possible index */ +- int middle; /* current middle index */ ++ ptrdiff_t lowest; /* current lowest possible index */ ++ ptrdiff_t highest; /* current highest possible index */ ++ ptrdiff_t middle; /* current middle index */ + int value; /* value from last comparison */ + + lowest = 0; +@@ -614,9 +619,9 @@ search_table (WORD *word, WORD_TABLE *table) + else if (value > 0) + lowest = middle + 1; + else +- return 1; ++ return true; + } +- return 0; ++ return false; + } + + /*---------------------------------------------------------------------. +@@ -713,14 +718,8 @@ digest_word_file (const char *file_name, WORD_TABLE *table) + if (cursor > word_start) + { + if (table->length == table->alloc) +- { +- if ((SIZE_MAX / sizeof *table->start - 1) / 2 < table->alloc) +- xalloc_die (); +- table->alloc = table->alloc * 2 + 1; +- table->start = xrealloc (table->start, +- table->alloc * sizeof *table->start); +- } +- ++ table->start = x2nrealloc (table->start, &table->alloc, ++ sizeof *table->start); + table->start[table->length].start = word_start; + table->start[table->length].size = cursor - word_start; + table->length++; +@@ -744,13 +743,13 @@ digest_word_file (const char *file_name, WORD_TABLE *table) + `----------------------------------------------------------------------*/ + + static void +-find_occurs_in_text (size_t file_index) ++find_occurs_in_text (int file_index) + { + char *cursor; /* for scanning the source text */ + char *scan; /* for scanning the source text also */ + char *line_start; /* start of the current input line */ + char *line_scan; /* newlines scanned until this point */ +- int reference_length; /* length of reference in input mode */ ++ ptrdiff_t reference_length; /* length of reference in input mode */ + WORD possible_key; /* possible key, to ease searches */ + OCCURS *occurs_cursor; /* current OCCURS under construction */ + +@@ -946,16 +945,9 @@ find_occurs_in_text (size_t file_index) + where it will be constructed. */ + + if (number_of_occurs[0] == occurs_alloc[0]) +- { +- if ((SIZE_MAX / sizeof *occurs_table[0] - 1) / 2 +- < occurs_alloc[0]) +- xalloc_die (); +- occurs_alloc[0] = occurs_alloc[0] * 2 + 1; +- occurs_table[0] = +- xrealloc (occurs_table[0], +- occurs_alloc[0] * sizeof *occurs_table[0]); +- } +- ++ occurs_table[0] = x2nrealloc (occurs_table[0], ++ &occurs_alloc[0], ++ sizeof *occurs_table[0]); + occurs_cursor = occurs_table[0] + number_of_occurs[0]; + + /* Define the reference field, if any. */ +@@ -990,8 +982,7 @@ find_occurs_in_text (size_t file_index) + of the reference. The reference position is simply the + value of 'line_start'. */ + +- occurs_cursor->reference +- = (DELTA) (line_start - possible_key.start); ++ occurs_cursor->reference = line_start - possible_key.start; + if (reference_length > reference_max_width) + reference_max_width = reference_length; + } +@@ -1023,11 +1014,9 @@ find_occurs_in_text (size_t file_index) + `-----------------------------------------*/ + + static void +-print_spaces (int number) ++print_spaces (ptrdiff_t number) + { +- int counter; +- +- for (counter = number; counter > 0; counter--) ++ for (ptrdiff_t counter = number; counter > 0; counter--) + putchar (' '); + } + +@@ -1200,10 +1189,9 @@ print_field (BLOCK field) + static void + fix_output_parameters (void) + { +- size_t file_index; /* index in text input file arrays */ +- int line_ordinal; /* line ordinal value for reference */ +- char ordinal_string[12]; /* edited line ordinal for reference */ +- int reference_width; /* width for the whole reference */ ++ int file_index; /* index in text input file arrays */ ++ intmax_t line_ordinal; /* line ordinal value for reference */ ++ ptrdiff_t reference_width; /* width for the whole reference */ + int character; /* character ordinal */ + const char *cursor; /* cursor in some constant strings */ + +@@ -1219,15 +1207,15 @@ fix_output_parameters (void) + line_ordinal = file_line_count[file_index] + 1; + if (file_index > 0) + line_ordinal -= file_line_count[file_index - 1]; +- sprintf (ordinal_string, "%d", line_ordinal); +- reference_width = strlen (ordinal_string); ++ char ordinal_string[INT_BUFSIZE_BOUND (intmax_t)]; ++ reference_width = sprintf (ordinal_string, "%"PRIdMAX, line_ordinal); + if (input_file_name[file_index]) + reference_width += strlen (input_file_name[file_index]); + if (reference_width > reference_max_width) + reference_max_width = reference_width; + } + reference_max_width++; +- reference.start = xmalloc ((size_t) reference_max_width + 1); ++ reference.start = xmalloc (reference_max_width + 1); + } + + /* If the reference appears to the left of the output line, reserve some +@@ -1355,14 +1343,14 @@ fix_output_parameters (void) + static void + define_all_fields (OCCURS *occurs) + { +- int tail_max_width; /* allowable width of tail field */ +- int head_max_width; /* allowable width of head field */ ++ ptrdiff_t tail_max_width; /* allowable width of tail field */ ++ ptrdiff_t head_max_width; /* allowable width of head field */ + char *cursor; /* running cursor in source text */ + char *left_context_start; /* start of left context */ + char *right_context_end; /* end of right context */ + char *left_field_start; /* conservative start for 'head'/'before' */ + const char *file_name; /* file name for reference */ +- int line_ordinal; /* line ordinal for reference */ ++ intmax_t line_ordinal; /* line ordinal for reference */ + const char *buffer_start; /* start of buffered file for this occurs */ + const char *buffer_end; /* end of buffered file for this occurs */ + +@@ -1435,7 +1423,7 @@ define_all_fields (OCCURS *occurs) + before_truncation = cursor > left_context_start; + } + else +- before_truncation = 0; ++ before_truncation = false; + + SKIP_WHITE (before.start, buffer_end); + +@@ -1468,11 +1456,11 @@ define_all_fields (OCCURS *occurs) + + if (tail.end > tail.start) + { +- keyafter_truncation = 0; ++ keyafter_truncation = false; + tail_truncation = truncation_string && tail.end < right_context_end; + } + else +- tail_truncation = 0; ++ tail_truncation = false; + + SKIP_WHITE_BACKWARDS (tail.end, tail.start); + } +@@ -1483,7 +1471,7 @@ define_all_fields (OCCURS *occurs) + + tail.start = NULL; + tail.end = NULL; +- tail_truncation = 0; ++ tail_truncation = false; + } + + /* 'head' could not take more columns than what has been left in the right +@@ -1506,12 +1494,12 @@ define_all_fields (OCCURS *occurs) + + if (head.end > head.start) + { +- before_truncation = 0; ++ before_truncation = false; + head_truncation = (truncation_string + && head.start > left_context_start); + } + else +- head_truncation = 0; ++ head_truncation = false; + + SKIP_WHITE (head.start, head.end); + } +@@ -1522,7 +1510,7 @@ define_all_fields (OCCURS *occurs) + + head.start = NULL; + head.end = NULL; +- head_truncation = 0; ++ head_truncation = false; + } + + if (auto_reference) +@@ -1540,8 +1528,8 @@ define_all_fields (OCCURS *occurs) + if (occurs->file_index > 0) + line_ordinal -= file_line_count[occurs->file_index - 1]; + +- sprintf (reference.start, "%s:%d", file_name, line_ordinal); +- reference.end = reference.start + strlen (reference.start); ++ char *file_end = stpcpy (reference.start, file_name); ++ reference.end = file_end + sprintf (file_end, ":%"PRIdMAX, line_ordinal); + } + else if (input_reference) + { +@@ -1549,7 +1537,7 @@ define_all_fields (OCCURS *occurs) + /* Reference starts at saved position for reference and extends right + until some white space is met. */ + +- reference.start = keyafter.start + (DELTA) occurs->reference; ++ reference.start = keyafter.start + occurs->reference; + reference.end = reference.start; + SKIP_NON_WHITE (reference.end, right_context_end); + } +@@ -1753,7 +1741,7 @@ output_one_dumb_line (void) + static void + generate_all_output (void) + { +- size_t occurs_index; /* index of keyword entry being processed */ ++ ptrdiff_t occurs_index; /* index of keyword entry being processed */ + OCCURS *occurs_cursor; /* current keyword entry being processed */ + + /* The following assignments are useful to provide default values in case +@@ -1762,11 +1750,11 @@ generate_all_output (void) + + tail.start = NULL; + tail.end = NULL; +- tail_truncation = 0; ++ tail_truncation = false; + + head.start = NULL; + head.end = NULL; +- head_truncation = 0; ++ head_truncation = false; + + /* Loop over all keyword occurrences. */ + +@@ -1946,12 +1934,12 @@ main (int argc, char **argv) + + case 'g': + { +- unsigned long int tmp_ulong; +- if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK +- || ! (0 < tmp_ulong && tmp_ulong <= INT_MAX)) ++ intmax_t tmp; ++ if (! (xstrtoimax (optarg, NULL, 0, &tmp, NULL) == LONGINT_OK ++ && 0 < tmp && tmp <= PTRDIFF_MAX)) + die (EXIT_FAILURE, 0, _("invalid gap width: %s"), + quote (optarg)); +- gap_size = tmp_ulong; ++ gap_size = tmp; + break; + } + +@@ -1973,12 +1961,12 @@ main (int argc, char **argv) + + case 'w': + { +- unsigned long int tmp_ulong; +- if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK +- || ! (0 < tmp_ulong && tmp_ulong <= INT_MAX)) ++ intmax_t tmp; ++ if (! (xstrtoimax (optarg, NULL, 0, &tmp, NULL) == LONGINT_OK ++ && 0 < tmp && tmp <= PTRDIFF_MAX)) + die (EXIT_FAILURE, 0, _("invalid line width: %s"), + quote (optarg)); +- line_width = tmp_ulong; ++ line_width = tmp; + break; + } + +@@ -2045,9 +2033,9 @@ main (int argc, char **argv) + else if (gnu_extensions) + { + number_input_files = argc - optind; +- input_file_name = xmalloc (number_input_files * sizeof *input_file_name); +- file_line_count = xmalloc (number_input_files * sizeof *file_line_count); +- text_buffers = xmalloc (number_input_files * sizeof *text_buffers); ++ input_file_name = xnmalloc (number_input_files, sizeof *input_file_name); ++ file_line_count = xnmalloc (number_input_files, sizeof *file_line_count); ++ text_buffers = xnmalloc (number_input_files, sizeof *text_buffers); + + for (file_index = 0; file_index < number_input_files; file_index++) + { +-- +2.9.5 + diff --git a/coreutils.spec b/coreutils.spec index 8c2e00d..aada4a1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 14%{?dist} +Release: 15%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -25,6 +25,9 @@ Patch3: coreutils-8.27-tail-inotify-recreate.patch # doc: mention `setpriv --no-new-privs` feature in runcon info Patch4: coreutils-8.27-runcon-doc.patch +# ptx: fix a possible crash caused by integer overflow (#1482445) +Patch5: coreutils-8.27-ptx-int-overflow.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -291,6 +294,9 @@ fi %license COPYING %changelog +* Fri Aug 18 2017 Kamil Dudka - 8.27-15 +- ptx: fix a possible crash caused by integer overflow (#1482445) + * Wed Aug 02 2017 Fedora Release Engineering - 8.27-14 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild From 349062154529401792e83345696f22007909b4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Tue, 22 Aug 2017 13:27:26 +0300 Subject: [PATCH 356/523] Own the %{_libexecdir}/coreutils dir According to Fedora Packaging Guidelines, packages must own all directories they put files in. Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1483938 --- coreutils.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index aada4a1..9265112 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.27 -Release: 15%{?dist} +Release: 16%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -274,11 +274,13 @@ fi %files -f supported_utils %exclude %{_bindir}/*.single +%dir %{_libexecdir}/coreutils %{_libexecdir}/coreutils/*.so %files single %{_bindir}/*.single %{_sbindir}/chroot.single +%dir %{_libexecdir}/coreutils %{_libexecdir}/coreutils/*.so.single # duplicate the license because coreutils-common does not need to be installed %{!?_licensedir:%global license %%doc} @@ -294,6 +296,9 @@ fi %license COPYING %changelog +* Tue Aug 22 2017 Ville Skyttä - 8.27-16 +- Own the %%{_libexecdir}/coreutils dir + * Fri Aug 18 2017 Kamil Dudka - 8.27-15 - ptx: fix a possible crash caused by integer overflow (#1482445) From 2d00e2bb9a3d77595124a0b98ad43aec02f7fc99 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 29 Aug 2017 14:21:49 +0200 Subject: [PATCH 357/523] new upstream release 8.28 --- coreutils-8.27-CVE-2017-7476.patch | 189 ------- coreutils-8.27-date-debug-test.patch | 50 -- coreutils-8.27-ptx-int-overflow.patch | 547 --------------------- coreutils-8.27-runcon-doc.patch | 33 -- coreutils-8.27-tail-inotify-recreate.patch | 168 ------- coreutils-8.27.tar.xz.sig | 16 - coreutils-8.28.tar.xz.sig | 16 + coreutils-df-direct.patch | 2 +- coreutils-i18n-un-expand-BOM.patch | 10 +- coreutils-i18n.patch | 132 ++--- coreutils.spec | 22 +- sources | 2 +- 12 files changed, 94 insertions(+), 1093 deletions(-) delete mode 100644 coreutils-8.27-CVE-2017-7476.patch delete mode 100644 coreutils-8.27-date-debug-test.patch delete mode 100644 coreutils-8.27-ptx-int-overflow.patch delete mode 100644 coreutils-8.27-runcon-doc.patch delete mode 100644 coreutils-8.27-tail-inotify-recreate.patch delete mode 100644 coreutils-8.27.tar.xz.sig create mode 100644 coreutils-8.28.tar.xz.sig diff --git a/coreutils-8.27-CVE-2017-7476.patch b/coreutils-8.27-CVE-2017-7476.patch deleted file mode 100644 index 23fdb3f..0000000 --- a/coreutils-8.27-CVE-2017-7476.patch +++ /dev/null @@ -1,189 +0,0 @@ -From fc286e2b3af5b2ed9aec44b520265bb0968f1660 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Mon, 24 Apr 2017 01:43:36 -0700 -Subject: [PATCH 1/2] time_rz: fix heap buffer overflow vulnerability - -This issue has been assigned CVE-2017-7476 and was -detected with American Fuzzy Lop 2.41b run on the -coreutils date(1) program with ASAN enabled. - - ERROR: AddressSanitizer: heap-buffer-overflow on address 0x... - WRITE of size 8 at 0x60d00000cff8 thread T0 - #1 0x443020 in extend_abbrs lib/time_rz.c:88 - #2 0x443356 in save_abbr lib/time_rz.c:155 - #3 0x44393f in localtime_rz lib/time_rz.c:290 - #4 0x41e4fe in parse_datetime2 lib/parse-datetime.y:1798 - -A minimized reproducer is the following 120 byte TZ value, -which goes beyond the value of ABBR_SIZE_MIN (119) on x86_64. -Extend the aa...b portion to overwrite more of the heap. - - date -d $(printf 'TZ="aaa%020daaaaaab%089d"') - -localtime_rz and mktime_z were affected since commit 4bc76593. -parse_datetime was affected since commit 4e6e16b3f. - -* lib/time_rz.c (save_abbr): Rearrange the calculation determining -whether there is enough buffer space available. The rearrangement -ensures we're only dealing with positive numbers, thus avoiding -the problematic promotion of signed to unsigned causing an invalid -comparison when zone_copy is more than ABBR_SIZE_MIN bytes beyond -the start of the buffer. -* tests/test-parse-datetime.c (main): Add a test case written by -Paul Eggert, which overwrites enough of the heap so that -standard glibc will fail with "free(): invalid pointer" -without the patch applied. -Reported and analyzed at https://bugzilla.redhat.com/1444774 - -Upstream-commit: 94e01571507835ff59dd8ce2a0b56a4b566965a4 -Signed-off-by: Kamil Dudka ---- - gnulib-tests/test-parse-datetime.c | 16 ++++++++++++++++ - lib/time_rz.c | 15 +++++++++++++-- - 2 files changed, 29 insertions(+), 2 deletions(-) - -diff --git a/gnulib-tests/test-parse-datetime.c b/gnulib-tests/test-parse-datetime.c -index b42a51c..b6fe457 100644 ---- a/gnulib-tests/test-parse-datetime.c -+++ b/gnulib-tests/test-parse-datetime.c -@@ -432,5 +432,21 @@ main (int argc _GL_UNUSED, char **argv) - ASSERT ( parse_datetime (&result, "TZ=\"\\\\\"", &now)); - ASSERT ( parse_datetime (&result, "TZ=\"\\\"\"", &now)); - -+ /* Outlandishly-long time zone abbreviations should not cause problems. */ -+ { -+ static char const bufprefix[] = "TZ=\""; -+ enum { tzname_len = 2000 }; -+ static char const bufsuffix[] = "0\" 1970-01-01 01:02:03.123456789"; -+ enum { bufsize = sizeof bufprefix - 1 + tzname_len + sizeof bufsuffix }; -+ char buf[bufsize]; -+ memcpy (buf, bufprefix, sizeof bufprefix - 1); -+ memset (buf + sizeof bufprefix - 1, 'X', tzname_len); -+ strcpy (buf + bufsize - sizeof bufsuffix, bufsuffix); -+ ASSERT (parse_datetime (&result, buf, &now)); -+ LOG (buf, now, result); -+ ASSERT (result.tv_sec == 1 * 60 * 60 + 2 * 60 + 3 -+ && result.tv_nsec == 123456789); -+ } -+ - return 0; - } -diff --git a/lib/time_rz.c b/lib/time_rz.c -index adb9c1c..c41a8ef 100644 ---- a/lib/time_rz.c -+++ b/lib/time_rz.c -@@ -27,6 +27,7 @@ - #include - - #include -+#include - #include - #include - #include -@@ -35,6 +36,10 @@ - #include "flexmember.h" - #include "time-internal.h" - -+#ifndef SIZE_MAX -+# define SIZE_MAX ((size_t) -1) -+#endif -+ - #if !HAVE_TZSET - static void tzset (void) { } - #endif -@@ -43,7 +48,7 @@ static void tzset (void) { } - the largest "small" request for the GNU C library malloc. */ - enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; - --/* Minimum size of the ABBRS member of struct abbr. ABBRS is larger -+/* Minimum size of the ABBRS member of struct tm_zone. ABBRS is larger - only in the unlikely case where an abbreviation longer than this is - used. */ - enum { ABBR_SIZE_MIN = DEFAULT_MXFAST - offsetof (struct tm_zone, abbrs) }; -@@ -150,7 +155,13 @@ save_abbr (timezone_t tz, struct tm *tm) - if (! (*zone_copy || (zone_copy == tz->abbrs && tz->tz_is_set))) - { - size_t zone_size = strlen (zone) + 1; -- if (zone_size < tz->abbrs + ABBR_SIZE_MIN - zone_copy) -+ size_t zone_used = zone_copy - tz->abbrs; -+ if (SIZE_MAX - zone_used < zone_size) -+ { -+ errno = ENOMEM; -+ return false; -+ } -+ if (zone_used + zone_size < ABBR_SIZE_MIN) - extend_abbrs (zone_copy, zone, zone_size); - else - { --- -2.9.3 - - -From 9579f90484c71e5a22f32f35189192a82e47550e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 26 Apr 2017 20:51:39 -0700 -Subject: [PATCH 2/2] date,touch: test and document large TZ security issue - -Add a test for CVE-2017-7476 which was fixed in gnulib at: -http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=94e01571 - -* tests/misc/date-tz.sh: Add a new test which overwrites enough -of the heap to trigger a segfault, even without ASAN enabled. -* tests/local.mk: Reference the new test. -* NEWS: Mention the bug fix. - -Upstream-commit: 9287ef2b1707e2a222f8ae776ce3785abcb16fba -Signed-off-by: Kamil Dudka ---- - tests/local.mk | 1 + - tests/misc/date-tz.sh | 26 ++++++++++++++++++++++++++ - 2 files changed, 27 insertions(+) - create mode 100755 tests/misc/date-tz.sh - -diff --git a/tests/local.mk b/tests/local.mk -index 9f1a853..ec0b414 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -282,6 +282,7 @@ all_tests = \ - tests/misc/csplit-suppress-matched.pl \ - tests/misc/date-debug.sh \ - tests/misc/date-sec.sh \ -+ tests/misc/date-tz.sh \ - tests/misc/dircolors.pl \ - tests/misc/dirname.pl \ - tests/misc/env-null.sh \ -diff --git a/tests/misc/date-tz.sh b/tests/misc/date-tz.sh -new file mode 100755 -index 0000000..3fe1579 ---- /dev/null -+++ b/tests/misc/date-tz.sh -@@ -0,0 +1,26 @@ -+#!/bin/sh -+# Verify TZ processing. -+ -+# Copyright (C) 2017 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_ date -+ -+# coreutils-8.27 would overwrite the heap with large TZ values -+tz_long=$(printf '%2000s' | tr ' ' a) -+date -d "TZ=\"${tz_long}0\" 2017" || fail=1 -+ -+Exit $fail --- -2.9.3 - diff --git a/coreutils-8.27-date-debug-test.patch b/coreutils-8.27-date-debug-test.patch deleted file mode 100644 index a8def7b..0000000 --- a/coreutils-8.27-date-debug-test.patch +++ /dev/null @@ -1,50 +0,0 @@ -From ee2017f191f1ad177405fbd8816df0a55127804a Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 9 Mar 2017 23:59:05 -0800 -Subject: [PATCH] tests: port to tzdb-2017a - -Problem reported by Bernhard Voelker in: -http://lists.gnu.org/archive/html/coreutils/2017-03/msg00026.html -* tests/misc/date-debug.sh: Port test to tzdb 2017a, -and future-proof the America/Belize test. - -Upstream-commit: 612086660bab9bf981894da146550e9101224b17 -Signed-off-by: Kamil Dudka ---- - tests/misc/date-debug.sh | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/tests/misc/date-debug.sh b/tests/misc/date-debug.sh -index 48f4605..8e0b2af 100755 ---- a/tests/misc/date-debug.sh -+++ b/tests/misc/date-debug.sh -@@ -52,10 +52,11 @@ date: output timezone: +09:00 (set from TZ="Asia/Tokyo" environment value) - date: final: 661095000.000000000 (epoch-seconds) - date: final: (Y-M-D) 1990-12-13 13:30:00 (UTC0) - date: final: (Y-M-D) 1990-12-13 22:30:00 (output timezone TZ=+09:00) --Thu Dec 13 07:30:00 CST 1990 -+Thu Dec 13 07:30:00 -0600 1990 - EOF - --TZ=America/Belize date --debug -d "$in1" >out1 2>&1 || fail=1 -+TZ=America/Belize date --debug -d "$in1" +'%a %b %e %T %z %Y' >out1 2>&1 || -+ fail=1 - - compare exp1 out1 || fail=1 - -@@ -94,10 +95,10 @@ date: output timezone: -05:00 (set from TZ="America/Lima" environment value) - date: final: 1.000000000 (epoch-seconds) - date: final: (Y-M-D) 1970-01-01 00:00:01 (UTC0) - date: final: (Y-M-D) 1969-12-31 19:00:01 (output timezone TZ=-05:00) --Wed Dec 31 19:00:01 PET 1969 -+Wed Dec 31 19:00:01 -0500 1969 - EOF - --TZ=America/Lima date --debug -d "$in3" >out3 2>&1 || fail=1 -+TZ=America/Lima date --debug -d "$in3" +'%a %b %e %T %z %Y' >out3 2>&1 || fail=1 - compare exp3 out3 || fail=1 - - ## --- -2.9.3 - diff --git a/coreutils-8.27-ptx-int-overflow.patch b/coreutils-8.27-ptx-int-overflow.patch deleted file mode 100644 index 897c2ad..0000000 --- a/coreutils-8.27-ptx-int-overflow.patch +++ /dev/null @@ -1,547 +0,0 @@ -From 7408a9758924a1ccbabf9fcab401a31ef1b7c755 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 17 Aug 2017 12:02:16 -0700 -Subject: [PATCH] ptx: fix some integer overflow bugs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Problem reported by Lukas Zachar at: -http://bugzilla.redhat.com/1482445 -* src/ptx.c (line_width, gap_size, maximum_word_length) -(reference_max_width, half_line_width, before_max_width) -(keyafter_max_width, truncation_string_length, compare_words) -(compare_occurs, search_table, find_occurs_in_text, print_spaces) -(fix_output_parameters, define_all_fields): -Use ptrdiff_t, not int, for object offsets and sizes. -(WORD, OCCURS): Use ptrdiff_t, not short int. -(WORD_TABLE, number_of_occurs, generate_all_output): -Prefer ptrdiff_t to size_t where either will do. -(total_line_count, file_line_count, OCCURS, fix_output_parameters) -(define_all_fields): -Use intmax_t, not int, for line counts. -(DELTA): Remove. All uses changed. -(OCCURS, find_occurs_in_text, fix_output_parameters): -Use int, not size_t, for file indexes. -(tail_truncation, before_truncation, keyafter_truncation) -(head_truncation, search_table, define_all_fields) -(generate_all_output): -Use bool for booleans. -(digest_word_file, find_occurs_in_text): -Use x2nrealloc instead of checking for overflow by hand. -(find_occurs_in_text, fix_output_parameters, define_all_fields): -Omit unnecessary cast. -(fix_output_parameters): Don’t assume integers fit in 11 digits. -(fix_output_parameters, define_all_fields): -Use sprintf return value rather than calling strlen. -(define_all_fields): Do not rely on sprintf to generate a string -that may contain more than INT_MAX bytes. -(main): Use xstrtoimax, not xstrtoul. -Use xnmalloc to catch integer overflow. - -Upstream-commit: 1d9765a764790cc68ec52c16d7ccbf633c404f0e -Signed-off-by: Kamil Dudka ---- - src/ptx.c | 194 +++++++++++++++++++++++++++++--------------------------------- - 1 file changed, 91 insertions(+), 103 deletions(-) - -diff --git a/src/ptx.c b/src/ptx.c -index c0c9733..2aababf 100644 ---- a/src/ptx.c -+++ b/src/ptx.c -@@ -59,9 +59,9 @@ - /* Global definitions. */ - - /* FIXME: There are many unchecked integer overflows in this file, -- that will cause this command to misbehave given large inputs or -- options. Many of the "int" values below should be "size_t" or -- something else like that. */ -+ and in theory they could cause this command to have undefined -+ behavior given large inputs or options. This command should -+ diagnose any such overflow and exit. */ - - /* Program options. */ - -@@ -77,8 +77,8 @@ static bool gnu_extensions = true; /* trigger all GNU extensions */ - static bool auto_reference = false; /* refs are 'file_name:line_number:' */ - static bool input_reference = false; /* refs at beginning of input lines */ - static bool right_reference = false; /* output refs after right context */ --static int line_width = 72; /* output line width in characters */ --static int gap_size = 3; /* number of spaces between output fields */ -+static ptrdiff_t line_width = 72; /* output line width in characters */ -+static ptrdiff_t gap_size = 3; /* number of spaces between output fields */ - static const char *truncation_string = "/"; - /* string used to mark line truncations */ - static const char *macro_name = "xx"; /* macro name for roff or TeX output */ -@@ -105,8 +105,8 @@ static struct regex_data context_regex; /* end of context */ - static struct regex_data word_regex; /* keyword */ - - /* A BLOCK delimit a region in memory of arbitrary size, like the copy of a -- whole file. A WORD is something smaller, its length should fit in a -- short integer. A WORD_TABLE may contain several WORDs. */ -+ whole file. A WORD is similar, except it is intended for smaller regions. -+ A WORD_TABLE may contain several WORDs. */ - - typedef struct - { -@@ -118,7 +118,7 @@ BLOCK; - typedef struct - { - char *start; /* pointer to beginning of region */ -- short int size; /* length of the region */ -+ ptrdiff_t size; /* length of the region */ - } - WORD; - -@@ -126,7 +126,7 @@ typedef struct - { - WORD *start; /* array of WORDs */ - size_t alloc; /* allocated length */ -- size_t length; /* number of used entries */ -+ ptrdiff_t length; /* number of used entries */ - } - WORD_TABLE; - -@@ -149,10 +149,10 @@ static struct re_registers word_regs; - static char word_fastmap[CHAR_SET_SIZE]; - - /* Maximum length of any word read. */ --static int maximum_word_length; -+static ptrdiff_t maximum_word_length; - - /* Maximum width of any reference used. */ --static int reference_max_width; -+static ptrdiff_t reference_max_width; - - /* Ignore and Only word tables. */ - -@@ -162,9 +162,9 @@ static WORD_TABLE only_table; /* table of words to select */ - /* Source text table, and scanning macros. */ - - static int number_input_files; /* number of text input files */ --static int total_line_count; /* total number of lines seen so far */ -+static intmax_t total_line_count; /* total number of lines seen so far */ - static const char **input_file_name; /* array of text input file names */ --static int *file_line_count; /* array of 'total_line_count' values at end */ -+static intmax_t *file_line_count; /* array of line count values at end */ - - static BLOCK *text_buffers; /* files to study */ - -@@ -219,20 +219,18 @@ static BLOCK *text_buffers; /* files to study */ - - When automatic references are used, the 'reference' value is the - overall line number in all input files read so far, in this case, it -- is of type (int). When input references are used, the 'reference' -+ is of type intmax_t. When input references are used, the 'reference' - value indicates the distance between the keyword beginning and the -- start of the reference field, it is of type (DELTA) and usually -+ start of the reference field, and it fits in ptrdiff_t and is usually - negative. */ - --typedef short int DELTA; /* to hold displacement within one context */ -- - typedef struct - { - WORD key; /* description of the keyword */ -- DELTA left; /* distance to left context start */ -- DELTA right; /* distance to right context end */ -- int reference; /* reference descriptor */ -- size_t file_index; /* corresponding file */ -+ ptrdiff_t left; /* distance to left context start */ -+ ptrdiff_t right; /* distance to right context end */ -+ intmax_t reference; /* reference descriptor */ -+ int file_index; /* corresponding file */ - } - OCCURS; - -@@ -241,7 +239,7 @@ OCCURS; - - static OCCURS *occurs_table[1]; /* all words retained from the read text */ - static size_t occurs_alloc[1]; /* allocated size of occurs_table */ --static size_t number_of_occurs[1]; /* number of used slots in occurs_table */ -+static ptrdiff_t number_of_occurs[1]; /* number of used slots in occurs_table */ - - - /* Communication among output routines. */ -@@ -249,10 +247,17 @@ static size_t number_of_occurs[1]; /* number of used slots in occurs_table */ - /* Indicate if special output processing is requested for each character. */ - static char edited_flag[CHAR_SET_SIZE]; - --static int half_line_width; /* half of line width, reference excluded */ --static int before_max_width; /* maximum width of before field */ --static int keyafter_max_width; /* maximum width of keyword-and-after field */ --static int truncation_string_length;/* length of string that flags truncation */ -+/* Half of line width, reference excluded. */ -+static ptrdiff_t half_line_width; -+ -+/* Maximum width of before field. */ -+static ptrdiff_t before_max_width; -+ -+/* Maximum width of keyword-and-after field. */ -+static ptrdiff_t keyafter_max_width; -+ -+/* Length of string that flags truncation. */ -+static ptrdiff_t truncation_string_length; - - /* When context is limited by lines, wraparound may happen on final output: - the 'head' pointer gives access to some supplementary left context which -@@ -261,16 +266,16 @@ static int truncation_string_length;/* length of string that flags truncation */ - beginning of the output line. */ - - static BLOCK tail; /* tail field */ --static int tail_truncation; /* flag truncation after the tail field */ -+static bool tail_truncation; /* flag truncation after the tail field */ - - static BLOCK before; /* before field */ --static int before_truncation; /* flag truncation before the before field */ -+static bool before_truncation; /* flag truncation before the before field */ - - static BLOCK keyafter; /* keyword-and-after field */ --static int keyafter_truncation; /* flag truncation after the keyafter field */ -+static bool keyafter_truncation; /* flag truncation after the keyafter field */ - - static BLOCK head; /* head field */ --static int head_truncation; /* flag truncation before the head field */ -+static bool head_truncation; /* flag truncation before the head field */ - - static BLOCK reference; /* reference field for input reference mode */ - -@@ -540,8 +545,8 @@ compare_words (const void *void_first, const void *void_second) - { - #define first ((const WORD *) void_first) - #define second ((const WORD *) void_second) -- int length; /* minimum of two lengths */ -- int counter; /* cursor in words */ -+ ptrdiff_t length; /* minimum of two lengths */ -+ ptrdiff_t counter; /* cursor in words */ - int value; /* value of comparison */ - - length = first->size < second->size ? first->size : second->size; -@@ -567,7 +572,7 @@ compare_words (const void *void_first, const void *void_second) - } - } - -- return first->size - second->size; -+ return first->size < second->size ? -1 : first->size > second->size; - #undef first - #undef second - } -@@ -586,21 +591,21 @@ compare_occurs (const void *void_first, const void *void_second) - int value; - - value = compare_words (&first->key, &second->key); -- return value == 0 ? first->key.start - second->key.start : value; -+ return (value ? value -+ : first->key.start < second->key.start ? -1 -+ : first->key.start > second->key.start); - #undef first - #undef second - } - --/*------------------------------------------------------------. --| Return !0 if WORD appears in TABLE. Uses a binary search. | --`------------------------------------------------------------*/ -+/* True if WORD appears in TABLE. Uses a binary search. */ - --static int _GL_ATTRIBUTE_PURE -+static bool _GL_ATTRIBUTE_PURE - search_table (WORD *word, WORD_TABLE *table) - { -- int lowest; /* current lowest possible index */ -- int highest; /* current highest possible index */ -- int middle; /* current middle index */ -+ ptrdiff_t lowest; /* current lowest possible index */ -+ ptrdiff_t highest; /* current highest possible index */ -+ ptrdiff_t middle; /* current middle index */ - int value; /* value from last comparison */ - - lowest = 0; -@@ -614,9 +619,9 @@ search_table (WORD *word, WORD_TABLE *table) - else if (value > 0) - lowest = middle + 1; - else -- return 1; -+ return true; - } -- return 0; -+ return false; - } - - /*---------------------------------------------------------------------. -@@ -713,14 +718,8 @@ digest_word_file (const char *file_name, WORD_TABLE *table) - if (cursor > word_start) - { - if (table->length == table->alloc) -- { -- if ((SIZE_MAX / sizeof *table->start - 1) / 2 < table->alloc) -- xalloc_die (); -- table->alloc = table->alloc * 2 + 1; -- table->start = xrealloc (table->start, -- table->alloc * sizeof *table->start); -- } -- -+ table->start = x2nrealloc (table->start, &table->alloc, -+ sizeof *table->start); - table->start[table->length].start = word_start; - table->start[table->length].size = cursor - word_start; - table->length++; -@@ -744,13 +743,13 @@ digest_word_file (const char *file_name, WORD_TABLE *table) - `----------------------------------------------------------------------*/ - - static void --find_occurs_in_text (size_t file_index) -+find_occurs_in_text (int file_index) - { - char *cursor; /* for scanning the source text */ - char *scan; /* for scanning the source text also */ - char *line_start; /* start of the current input line */ - char *line_scan; /* newlines scanned until this point */ -- int reference_length; /* length of reference in input mode */ -+ ptrdiff_t reference_length; /* length of reference in input mode */ - WORD possible_key; /* possible key, to ease searches */ - OCCURS *occurs_cursor; /* current OCCURS under construction */ - -@@ -946,16 +945,9 @@ find_occurs_in_text (size_t file_index) - where it will be constructed. */ - - if (number_of_occurs[0] == occurs_alloc[0]) -- { -- if ((SIZE_MAX / sizeof *occurs_table[0] - 1) / 2 -- < occurs_alloc[0]) -- xalloc_die (); -- occurs_alloc[0] = occurs_alloc[0] * 2 + 1; -- occurs_table[0] = -- xrealloc (occurs_table[0], -- occurs_alloc[0] * sizeof *occurs_table[0]); -- } -- -+ occurs_table[0] = x2nrealloc (occurs_table[0], -+ &occurs_alloc[0], -+ sizeof *occurs_table[0]); - occurs_cursor = occurs_table[0] + number_of_occurs[0]; - - /* Define the reference field, if any. */ -@@ -990,8 +982,7 @@ find_occurs_in_text (size_t file_index) - of the reference. The reference position is simply the - value of 'line_start'. */ - -- occurs_cursor->reference -- = (DELTA) (line_start - possible_key.start); -+ occurs_cursor->reference = line_start - possible_key.start; - if (reference_length > reference_max_width) - reference_max_width = reference_length; - } -@@ -1023,11 +1014,9 @@ find_occurs_in_text (size_t file_index) - `-----------------------------------------*/ - - static void --print_spaces (int number) -+print_spaces (ptrdiff_t number) - { -- int counter; -- -- for (counter = number; counter > 0; counter--) -+ for (ptrdiff_t counter = number; counter > 0; counter--) - putchar (' '); - } - -@@ -1200,10 +1189,9 @@ print_field (BLOCK field) - static void - fix_output_parameters (void) - { -- size_t file_index; /* index in text input file arrays */ -- int line_ordinal; /* line ordinal value for reference */ -- char ordinal_string[12]; /* edited line ordinal for reference */ -- int reference_width; /* width for the whole reference */ -+ int file_index; /* index in text input file arrays */ -+ intmax_t line_ordinal; /* line ordinal value for reference */ -+ ptrdiff_t reference_width; /* width for the whole reference */ - int character; /* character ordinal */ - const char *cursor; /* cursor in some constant strings */ - -@@ -1219,15 +1207,15 @@ fix_output_parameters (void) - line_ordinal = file_line_count[file_index] + 1; - if (file_index > 0) - line_ordinal -= file_line_count[file_index - 1]; -- sprintf (ordinal_string, "%d", line_ordinal); -- reference_width = strlen (ordinal_string); -+ char ordinal_string[INT_BUFSIZE_BOUND (intmax_t)]; -+ reference_width = sprintf (ordinal_string, "%"PRIdMAX, line_ordinal); - if (input_file_name[file_index]) - reference_width += strlen (input_file_name[file_index]); - if (reference_width > reference_max_width) - reference_max_width = reference_width; - } - reference_max_width++; -- reference.start = xmalloc ((size_t) reference_max_width + 1); -+ reference.start = xmalloc (reference_max_width + 1); - } - - /* If the reference appears to the left of the output line, reserve some -@@ -1355,14 +1343,14 @@ fix_output_parameters (void) - static void - define_all_fields (OCCURS *occurs) - { -- int tail_max_width; /* allowable width of tail field */ -- int head_max_width; /* allowable width of head field */ -+ ptrdiff_t tail_max_width; /* allowable width of tail field */ -+ ptrdiff_t head_max_width; /* allowable width of head field */ - char *cursor; /* running cursor in source text */ - char *left_context_start; /* start of left context */ - char *right_context_end; /* end of right context */ - char *left_field_start; /* conservative start for 'head'/'before' */ - const char *file_name; /* file name for reference */ -- int line_ordinal; /* line ordinal for reference */ -+ intmax_t line_ordinal; /* line ordinal for reference */ - const char *buffer_start; /* start of buffered file for this occurs */ - const char *buffer_end; /* end of buffered file for this occurs */ - -@@ -1435,7 +1423,7 @@ define_all_fields (OCCURS *occurs) - before_truncation = cursor > left_context_start; - } - else -- before_truncation = 0; -+ before_truncation = false; - - SKIP_WHITE (before.start, buffer_end); - -@@ -1468,11 +1456,11 @@ define_all_fields (OCCURS *occurs) - - if (tail.end > tail.start) - { -- keyafter_truncation = 0; -+ keyafter_truncation = false; - tail_truncation = truncation_string && tail.end < right_context_end; - } - else -- tail_truncation = 0; -+ tail_truncation = false; - - SKIP_WHITE_BACKWARDS (tail.end, tail.start); - } -@@ -1483,7 +1471,7 @@ define_all_fields (OCCURS *occurs) - - tail.start = NULL; - tail.end = NULL; -- tail_truncation = 0; -+ tail_truncation = false; - } - - /* 'head' could not take more columns than what has been left in the right -@@ -1506,12 +1494,12 @@ define_all_fields (OCCURS *occurs) - - if (head.end > head.start) - { -- before_truncation = 0; -+ before_truncation = false; - head_truncation = (truncation_string - && head.start > left_context_start); - } - else -- head_truncation = 0; -+ head_truncation = false; - - SKIP_WHITE (head.start, head.end); - } -@@ -1522,7 +1510,7 @@ define_all_fields (OCCURS *occurs) - - head.start = NULL; - head.end = NULL; -- head_truncation = 0; -+ head_truncation = false; - } - - if (auto_reference) -@@ -1540,8 +1528,8 @@ define_all_fields (OCCURS *occurs) - if (occurs->file_index > 0) - line_ordinal -= file_line_count[occurs->file_index - 1]; - -- sprintf (reference.start, "%s:%d", file_name, line_ordinal); -- reference.end = reference.start + strlen (reference.start); -+ char *file_end = stpcpy (reference.start, file_name); -+ reference.end = file_end + sprintf (file_end, ":%"PRIdMAX, line_ordinal); - } - else if (input_reference) - { -@@ -1549,7 +1537,7 @@ define_all_fields (OCCURS *occurs) - /* Reference starts at saved position for reference and extends right - until some white space is met. */ - -- reference.start = keyafter.start + (DELTA) occurs->reference; -+ reference.start = keyafter.start + occurs->reference; - reference.end = reference.start; - SKIP_NON_WHITE (reference.end, right_context_end); - } -@@ -1753,7 +1741,7 @@ output_one_dumb_line (void) - static void - generate_all_output (void) - { -- size_t occurs_index; /* index of keyword entry being processed */ -+ ptrdiff_t occurs_index; /* index of keyword entry being processed */ - OCCURS *occurs_cursor; /* current keyword entry being processed */ - - /* The following assignments are useful to provide default values in case -@@ -1762,11 +1750,11 @@ generate_all_output (void) - - tail.start = NULL; - tail.end = NULL; -- tail_truncation = 0; -+ tail_truncation = false; - - head.start = NULL; - head.end = NULL; -- head_truncation = 0; -+ head_truncation = false; - - /* Loop over all keyword occurrences. */ - -@@ -1946,12 +1934,12 @@ main (int argc, char **argv) - - case 'g': - { -- unsigned long int tmp_ulong; -- if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK -- || ! (0 < tmp_ulong && tmp_ulong <= INT_MAX)) -+ intmax_t tmp; -+ if (! (xstrtoimax (optarg, NULL, 0, &tmp, NULL) == LONGINT_OK -+ && 0 < tmp && tmp <= PTRDIFF_MAX)) - die (EXIT_FAILURE, 0, _("invalid gap width: %s"), - quote (optarg)); -- gap_size = tmp_ulong; -+ gap_size = tmp; - break; - } - -@@ -1973,12 +1961,12 @@ main (int argc, char **argv) - - case 'w': - { -- unsigned long int tmp_ulong; -- if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) != LONGINT_OK -- || ! (0 < tmp_ulong && tmp_ulong <= INT_MAX)) -+ intmax_t tmp; -+ if (! (xstrtoimax (optarg, NULL, 0, &tmp, NULL) == LONGINT_OK -+ && 0 < tmp && tmp <= PTRDIFF_MAX)) - die (EXIT_FAILURE, 0, _("invalid line width: %s"), - quote (optarg)); -- line_width = tmp_ulong; -+ line_width = tmp; - break; - } - -@@ -2045,9 +2033,9 @@ main (int argc, char **argv) - else if (gnu_extensions) - { - number_input_files = argc - optind; -- input_file_name = xmalloc (number_input_files * sizeof *input_file_name); -- file_line_count = xmalloc (number_input_files * sizeof *file_line_count); -- text_buffers = xmalloc (number_input_files * sizeof *text_buffers); -+ input_file_name = xnmalloc (number_input_files, sizeof *input_file_name); -+ file_line_count = xnmalloc (number_input_files, sizeof *file_line_count); -+ text_buffers = xnmalloc (number_input_files, sizeof *text_buffers); - - for (file_index = 0; file_index < number_input_files; file_index++) - { --- -2.9.5 - diff --git a/coreutils-8.27-runcon-doc.patch b/coreutils-8.27-runcon-doc.patch deleted file mode 100644 index 41c0a8a..0000000 --- a/coreutils-8.27-runcon-doc.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 76be8a7f9eb717b3d47009eb25d39fe7139a2c2d Mon Sep 17 00:00:00 2001 -From: Sebastian Kisela -Date: Tue, 30 May 2017 09:29:32 +0200 -Subject: [PATCH] doc: mention `setpriv --no-new-privs` feature in runcon info - -upstream commit: 6ebaf8195000d6d3590a2eac13f13b158e325452 ---- - doc/coreutils.texi | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 68df075..e16e885 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -16583,7 +16583,14 @@ are interpreted as arguments to the command. - With neither @var{context} nor @var{command}, print the current - security context. - --The program accepts the following options. Also see @ref{Common options}. -+@cindex restricted security context -+@cindex NO_NEW_PRIVS -+Note also the @command{setpriv} command which can be used to set the -+NO_NEW_PRIVS bit using @command{setpriv --no-new-privs runcon ...}, -+thus disallowing usage of a security context with more privileges -+than the process would normally have. -+ -+@command{runcon} accepts the following options. Also see @ref{Common options}. - - @table @samp - --- -2.9.4 - diff --git a/coreutils-8.27-tail-inotify-recreate.patch b/coreutils-8.27-tail-inotify-recreate.patch deleted file mode 100644 index 1a63655..0000000 --- a/coreutils-8.27-tail-inotify-recreate.patch +++ /dev/null @@ -1,168 +0,0 @@ -From ba5fe2d4b8b6a8366f48b1ad1f97fe26c9089b53 Mon Sep 17 00:00:00 2001 -From: Sebastian Kisela -Date: Wed, 5 Apr 2017 09:40:41 +0200 -Subject: [PATCH] tail: revert to polling if a followed directory is replaced - -* src/tail.c (tail_forever_inotify): Add the IN_DELETE_SELF flag when -creating watch for the parent directory. After the parent directory -is removed, an event is caught and then we switch from inotify to -polling mode. Till now, inotify has always frozen because it waited for -an event from a watched dir, which has been already deleted and was not -added again. -* tests/tail-2/inotify-dir-recreate.sh: Add a test case. -* tests/local.mk: Reference the new test. -Fixes http://bugs.gnu.org/26363 -Reported at https://bugzilla.redhat.com/1283760 - -Upstream-commit: ba5fe2d4b8b6a8366f48b1ad1f97fe26c9089b53 - ---- - src/tail.c | 22 +++++++++- - tests/local.mk | 1 + - tests/tail-2/inotify-dir-recreate.sh | 82 ++++++++++++++++++++++++++++++++++++ - 4 files changed, 107 insertions(+), 1 deletion(-) - create mode 100755 tests/tail-2/inotify-dir-recreate.sh - -diff --git a/src/tail.c b/src/tail.c -index d1552d4..6328fe0 100644 ---- a/src/tail.c -+++ b/src/tail.c -@@ -1457,7 +1457,8 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files, - In that case the same watch descriptor is returned. */ - f[i].parent_wd = inotify_add_watch (wd, dirlen ? f[i].name : ".", - (IN_CREATE | IN_DELETE -- | IN_MOVED_TO | IN_ATTRIB)); -+ | IN_MOVED_TO | IN_ATTRIB -+ | IN_DELETE_SELF)); - - f[i].name[dirlen] = prev; - -@@ -1628,6 +1629,25 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files, - ev = void_ev; - evbuf_off += sizeof (*ev) + ev->len; - -+ /* If a directory is deleted, IN_DELETE_SELF is emitted -+ with ev->name of length 0. -+ We need to catch it, otherwise it would wait forever, -+ as wd for directory becomes inactive. Revert to polling now. */ -+ if ((ev->mask & IN_DELETE_SELF) && ! ev->len) -+ { -+ for (i = 0; i < n_files; i++) -+ { -+ if (ev->wd == f[i].parent_wd) -+ { -+ hash_free (wd_to_name); -+ error (0, 0, -+ _("directory containing watched file was removed")); -+ errno = 0; /* we've already diagnosed enough errno detail. */ -+ return true; -+ } -+ } -+ } -+ - if (ev->len) /* event on ev->name in watched directory. */ - { - size_t j; -diff --git a/tests/local.mk b/tests/local.mk -index 3fe9ba8..e890c9a 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -176,6 +176,7 @@ all_tests = \ - tests/tail-2/descriptor-vs-rename.sh \ - tests/tail-2/inotify-rotate.sh \ - tests/tail-2/inotify-rotate-resources.sh \ -+ tests/tail-2/inotify-dir-recreate.sh \ - tests/chmod/no-x.sh \ - tests/chgrp/basic.sh \ - tests/rm/dangling-symlink.sh \ -diff --git a/tests/tail-2/inotify-dir-recreate.sh b/tests/tail-2/inotify-dir-recreate.sh -new file mode 100755 -index 0000000..eaa8422 ---- /dev/null -+++ b/tests/tail-2/inotify-dir-recreate.sh -@@ -0,0 +1,82 @@ -+#!/bin/sh -+# Makes sure, inotify will switch to polling mode if directory -+# of the watched file was removed and recreated. -+# (...instead of getting stuck forever) -+ -+# Copyright (C) 2006-2017 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ tail -+ -+ -+# Terminate any background tail process -+cleanup_() { kill $pid 2>/dev/null && wait $pid; } -+ -+cleanup_fail_ () -+{ -+ warn_ $1 -+ cleanup_ -+ fail=1 -+} -+ -+# $check_re - string to be found -+# $check_f - file to be searched -+check_tail_output_ () -+{ -+ local delay="$1" -+ grep $check_re $check_f > /dev/null || -+ { sleep $delay ; return 1; } -+} -+ -+grep_timeout_ () -+{ -+ check_re="$1" -+ check_f="$2" -+ retry_delay_ check_tail_output_ .1 5 -+} -+ -+# Prepare the file to be watched -+mkdir dir && echo 'inotify' > dir/file || framework_failure_ -+ -+#tail must print content of the file to stdout, verify -+timeout 60 tail -F dir/file &>out & pid=$! -+grep_timeout_ 'inotify' 'out' || -+{ cleanup_fail_ 'file to be tailed does not exist'; } -+ -+# Remove the directory, should get the message about the deletion -+rm -r dir || framework_failure_ -+grep_timeout_ 'polling' 'out' || -+{ cleanup_fail_ 'tail did not switch to polling mode'; } -+ -+# Recreate the dir, must get a message about recreation -+mkdir dir && touch dir/file || framework_failure_ -+grep_timeout_ 'appeared' 'out' || -+{ cleanup_fail_ 'previously removed file did not appear'; } -+ -+cleanup_ -+ -+# Expected result for the whole process -+cat <<\EOF > exp || framework_failure_ -+inotify -+tail: 'dir/file' has become inaccessible: No such file or directory -+tail: directory containing watched file was removed -+tail: inotify cannot be used, reverting to polling -+tail: 'dir/file' has appeared; following new file -+EOF -+ -+compare exp out || fail=1 -+ -+Exit $fail --- -2.9.3 - diff --git a/coreutils-8.27.tar.xz.sig b/coreutils-8.27.tar.xz.sig deleted file mode 100644 index 7555c00..0000000 --- a/coreutils-8.27.tar.xz.sig +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIcBAABAgAGBQJYwOwaAAoJEN9v2XEwYDfZQrUP/RdXj/ug35e+u+VD1ts9/b8n -7JihJmxngEZQAJECNTMbJ7mNj6DhpMY0Jg/Hwg7zJT28T6QDeS1Iuk3Id4uM5eFa -CgHKAZumntSMTkQdNvnCEFEIqu+L8BtBYGcOaw66wAFNFw3jdJUUs2sOST2r46jR -N7aY9oARKJuHfgTZ2BI2zL0Q+poXM1O0k/U+BScE6c139zJsbg+1uM9kGVtJWPkM -EPLFWkbTgjYnt+qEFrDlWL0YFOS42sgR7P1sVfBC1nAu5lwgzPy62OtGv9WCEBhm -3+PRNZ0KLW8CKp06llG/0bG4QwssWs6p/vPwrRGeAg6pKsRNN1ni27AnDThiPgvz -YbBLgU+EZj1HuibvYArHXNKY2+O5ZC3nYU6bdAffl3TAtrGFA1ncZXGiFD5UgOQ2 -V9Q38S41FUEwKGtf9tWGCRTxrb4FQ1CDzJglV9vHKetn4mgH/HpEG/q07k4RNW5d -ikfrS0xFxbqtLjlY3UqvtkrFyVQFY093ozsP7fKsq53JAtEWc3YvXR8UCbliU+gV -5qug0REBQafe9EAyH+oq0dzD2BZ3KtFcjtKI/2UzAf3idcyygsHgcEPQObqI8BfD -NscEMjdFY7+Zh5w2shQlyq4xr2aI2nXCX3+AMcS/6Yfg6W6fBvgIjtmXBrQsbWpV -DBcx50TVDa/ERBX1+FI1 -=skPR ------END PGP SIGNATURE----- diff --git a/coreutils-8.28.tar.xz.sig b/coreutils-8.28.tar.xz.sig new file mode 100644 index 0000000..4a76f06 --- /dev/null +++ b/coreutils-8.28.tar.xz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIcBAABAgAGBQJZqhkfAAoJEN9v2XEwYDfZZEQP/REePQxk2OXPSRSyYSaazIeP +gDno1D4tcHXHhvl210ouOEvCGux6tJtHmCQ5Y43Dkt56DJ3Eb9dk2JYrisvcrJhv +3m098YY2hseVLJ7M3jnf9slAXBrS23i+mUWHADeRpFIJZQQz1KEZVb1gsI0FO9Ch +Qp64hBPB4X1Ydxz57KywUpEgBC9Cj0KwWW9L6jIHK+V1izLoI1JslUxHXkyTy9as +WjmDuJp1nMewjbAza//HHNiqote59JewuLcxiA9EdK8jzQZXF+fbRasFO3XEobMl +0WYtN0MwYN2576xSGwTyp7IakFcNHjWciE9SuvPmg/VCLELV6vl4VJXAmv/kQKeE +whVq7kfdzRAKDwUXdXyCqzYSEi1+N+2izJaI4twgExDwm89OApe6aka8UBbqClyz +cn4UmqYMgjwvKXPJtqMUmzEwAzDxuXQJL6Uj5kY8RJLCqBv/eN+YoxODTZz3oDGU +988K6K2Q9QaOGSNJHiBrgddCARuxeRVizbDSi2GcSQdPRbTM4g7YK//KE8LoKdil +ngIeam0vomPJnJqI03U1wGKhxsDqOEEQ3CFch7mQ2S1eWtqeag3arcBVALZUdCzX +hckiSXd0Yuks8AyHb8LH7/3h1BJUWVg/v7iQ2E3UMHAE78Ww28MyppMhy+4U9knU +Dp2VXtxBOJVXJETdVFXY +=7Q/5 +-----END PGP SIGNATURE----- diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index a69d896..248a6ae 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -112,7 +112,7 @@ index 8f760db..a7385fd 100644 { if (posix_format) diff --git a/tests/df/direct.sh b/tests/df/direct.sh -new file mode 100644 +new file mode 100755 index 0000000..8e4cfb8 --- /dev/null +++ b/tests/df/direct.sh diff --git a/coreutils-i18n-un-expand-BOM.patch b/coreutils-i18n-un-expand-BOM.patch index 2ccdcca..d1ea109 100644 --- a/coreutils-i18n-un-expand-BOM.patch +++ b/coreutils-i18n-un-expand-BOM.patch @@ -16,15 +16,15 @@ diff --git a/src/expand-common.c b/src/expand-common.c index 4657e46..97cbb09 100644 --- a/src/expand-common.c +++ b/src/expand-common.c -@@ -18,6 +18,7 @@ - +@@ -19,6 +19,7 @@ + #include #include #include +#include #include "system.h" #include "die.h" #include "error.h" -@@ -105,6 +106,119 @@ set_extend_size (uintmax_t tabval) +@@ -126,6 +127,119 @@ set_increment_size (uintmax_t tabval) return ok; } @@ -171,7 +171,7 @@ diff --git a/src/expand.c b/src/expand.c index 310b349..4136824 100644 --- a/src/expand.c +++ b/src/expand.c -@@ -105,11 +105,33 @@ expand (void) +@@ -103,11 +103,33 @@ expand (void) FILE *fp = next_file (NULL); mb_file_t mbf; mbf_char_t c; @@ -206,7 +206,7 @@ index 310b349..4136824 100644 while (true) { -@@ -134,6 +156,27 @@ expand (void) +@@ -132,6 +154,27 @@ expand (void) if ((mb_iseof (c)) && (fp = next_file (fp))) { mbf_init (mbf, fp); diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index ab5d8dc..747772d 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -845,7 +845,7 @@ index 98b461c..9990f38 100644 xfields (line); if (prevline[which - 1]) -@@ -567,21 +807,28 @@ prfield (size_t n, struct line const *line) +@@ -563,21 +803,28 @@ prfield (size_t n, struct line const *line) /* Output all the fields in line, other than the join field. */ @@ -877,7 +877,7 @@ index 98b461c..9990f38 100644 prfield (i, line); } } -@@ -592,7 +839,6 @@ static void +@@ -588,7 +835,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -885,7 +885,7 @@ index 98b461c..9990f38 100644 size_t field; struct line const *line; -@@ -626,7 +872,7 @@ prjoin (struct line const *line1, struct line const *line2) +@@ -622,7 +868,7 @@ prjoin (struct line const *line1, struct line const *line2) o = o->next; if (o == NULL) break; @@ -894,7 +894,7 @@ index 98b461c..9990f38 100644 } putchar (eolchar); } -@@ -1104,20 +1350,43 @@ main (int argc, char **argv) +@@ -1099,20 +1345,43 @@ main (int argc, char **argv) case 't': { @@ -1171,7 +1171,7 @@ index 26f221f..633f50e 100644 use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1166,10 +1250,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err) +@@ -1165,10 +1249,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err) a number. */ static void @@ -1219,7 +1219,7 @@ index 26f221f..633f50e 100644 if (*arg) { long int tmp_long; -@@ -1191,6 +1310,11 @@ static void +@@ -1190,6 +1309,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -1231,7 +1231,7 @@ index 26f221f..633f50e 100644 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) +@@ -1227,7 +1351,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -1240,7 +1240,7 @@ index 26f221f..633f50e 100644 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) +@@ -1257,11 +1381,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. */ @@ -1254,7 +1254,7 @@ index 26f221f..633f50e 100644 /* 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) +@@ -1270,7 +1394,7 @@ init_parameters (int number_of_files) } int sep_chars, useful_chars; @@ -1263,7 +1263,7 @@ index 26f221f..633f50e 100644 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) +@@ -1293,7 +1417,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); @@ -1272,7 +1272,7 @@ index 26f221f..633f50e 100644 } /* Open the necessary files, -@@ -1402,7 +1526,7 @@ init_funcs (void) +@@ -1399,7 +1523,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -1281,7 +1281,7 @@ index 26f221f..633f50e 100644 /* This loop takes care of all but the rightmost column. */ -@@ -1436,7 +1560,7 @@ init_funcs (void) +@@ -1433,7 +1557,7 @@ init_funcs (void) } else { @@ -1290,7 +1290,7 @@ index 26f221f..633f50e 100644 h_next = h + chars_per_column; } } -@@ -1727,9 +1851,9 @@ static void +@@ -1724,9 +1848,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -1302,7 +1302,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2004,13 +2128,13 @@ store_char (char c) +@@ -2001,13 +2125,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -1318,7 +1318,7 @@ index 26f221f..633f50e 100644 char *s; int num_width; -@@ -2027,22 +2151,24 @@ add_line_number (COLUMN *p) +@@ -2024,22 +2148,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. */ @@ -1347,7 +1347,7 @@ index 26f221f..633f50e 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2203,7 +2329,7 @@ print_white_space (void) +@@ -2198,7 +2324,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -1356,7 +1356,7 @@ index 26f221f..633f50e 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2223,6 +2349,7 @@ print_sep_string (void) +@@ -2218,6 +2344,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -1364,7 +1364,7 @@ index 26f221f..633f50e 100644 if (separators_not_printed <= 0) { -@@ -2234,6 +2361,7 @@ print_sep_string (void) +@@ -2229,6 +2356,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -1372,7 +1372,7 @@ index 26f221f..633f50e 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2247,12 +2375,15 @@ print_sep_string (void) +@@ -2242,12 +2370,15 @@ print_sep_string (void) } else { @@ -1389,7 +1389,7 @@ index 26f221f..633f50e 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2280,7 +2411,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2275,7 +2406,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -1398,7 +1398,7 @@ index 26f221f..633f50e 100644 { if (tabify_output) { -@@ -2304,6 +2435,74 @@ print_char (char c) +@@ -2299,6 +2430,74 @@ print_char (char c) putchar (c); } @@ -1473,7 +1473,7 @@ index 26f221f..633f50e 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2483,9 +2682,9 @@ read_line (COLUMN *p) +@@ -2476,9 +2675,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -1485,8 +1485,8 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2555,7 +2754,7 @@ print_stored (COLUMN *p) - int i; +@@ -2547,7 +2746,7 @@ print_stored (COLUMN *p) + COLUMN *q; int line = p->current_line++; - char *first = &buff[line_vector[line]]; @@ -1494,7 +1494,7 @@ index 26f221f..633f50e 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2567,7 +2766,7 @@ print_stored (COLUMN *p) +@@ -2559,7 +2758,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -1503,7 +1503,7 @@ index 26f221f..633f50e 100644 pad_vertically = true; -@@ -2586,9 +2785,9 @@ print_stored (COLUMN *p) +@@ -2579,9 +2778,9 @@ print_stored (COLUMN *p) } } @@ -1515,7 +1515,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2601,8 +2800,8 @@ print_stored (COLUMN *p) +@@ -2594,8 +2793,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -1526,7 +1526,7 @@ index 26f221f..633f50e 100644 } return true; -@@ -2621,7 +2820,7 @@ print_stored (COLUMN *p) +@@ -2614,7 +2813,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -1535,7 +1535,7 @@ index 26f221f..633f50e 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2631,10 +2830,10 @@ char_to_clump (char c) +@@ -2624,10 +2823,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -1548,7 +1548,7 @@ index 26f221f..633f50e 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2715,6 +2914,164 @@ char_to_clump (char c) +@@ -2708,6 +2907,164 @@ char_to_clump (char c) return chars; } @@ -1732,7 +1732,7 @@ index 6d2eec5..f189a0d 100644 #include "system.h" #include "argmatch.h" #include "die.h" -@@ -165,14 +173,39 @@ static int decimal_point; +@@ -169,14 +177,39 @@ static int decimal_point; /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; @@ -1773,7 +1773,7 @@ index 6d2eec5..f189a0d 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -346,13 +379,11 @@ static bool reverse; +@@ -350,13 +383,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -1790,7 +1790,7 @@ index 6d2eec5..f189a0d 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -811,6 +842,46 @@ reap_all (void) +@@ -814,6 +845,46 @@ reap_all (void) reap (-1); } @@ -1837,7 +1837,7 @@ index 6d2eec5..f189a0d 100644 /* Clean up any remaining temporary files. */ static void -@@ -1255,7 +1326,7 @@ zaptemp (char const *name) +@@ -1264,7 +1335,7 @@ zaptemp (char const *name) free (node); } @@ -1846,7 +1846,7 @@ index 6d2eec5..f189a0d 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1270,7 +1341,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1279,7 +1350,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -1855,7 +1855,7 @@ index 6d2eec5..f189a0d 100644 { size_t i; -@@ -1282,7 +1353,7 @@ inittables (void) +@@ -1291,7 +1362,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -1864,7 +1864,7 @@ index 6d2eec5..f189a0d 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1364,6 +1435,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1373,6 +1444,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -1949,7 +1949,7 @@ index 6d2eec5..f189a0d 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1597,7 +1746,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1604,7 +1753,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -1958,7 +1958,7 @@ index 6d2eec5..f189a0d 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1606,10 +1755,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1613,10 +1762,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -1971,7 +1971,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1635,11 +1784,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1642,11 +1791,70 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2043,7 +2043,7 @@ index 6d2eec5..f189a0d 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1654,10 +1862,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1661,10 +1869,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2056,7 +2056,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1703,10 +1911,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1710,10 +1918,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2069,7 +2069,7 @@ index 6d2eec5..f189a0d 100644 if (newlim) lim = newlim; } -@@ -1737,6 +1945,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1744,6 +1952,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2200,7 +2200,7 @@ index 6d2eec5..f189a0d 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1823,8 +2155,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1830,8 +2162,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2225,7 +2225,7 @@ index 6d2eec5..f189a0d 100644 line->keybeg = line_start; } } -@@ -1974,7 +2320,7 @@ human_numcompare (char const *a, char const *b) +@@ -1981,7 +2327,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2234,7 +2234,7 @@ index 6d2eec5..f189a0d 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -1984,6 +2330,25 @@ numcompare (char const *a, char const *b) +@@ -1991,6 +2337,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2260,7 +2260,7 @@ index 6d2eec5..f189a0d 100644 /* 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 once -@@ -2034,7 +2399,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2041,7 +2406,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2269,7 +2269,7 @@ index 6d2eec5..f189a0d 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2310,15 +2675,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2317,15 +2682,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2287,7 +2287,7 @@ index 6d2eec5..f189a0d 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2452,7 +2816,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2459,7 +2823,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2296,7 +2296,7 @@ index 6d2eec5..f189a0d 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2510,11 +2874,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2517,11 +2881,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -2385,7 +2385,7 @@ index 6d2eec5..f189a0d 100644 { struct keyfield *key = keylist; -@@ -2599,7 +3039,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2606,7 +3046,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2394,7 +2394,7 @@ index 6d2eec5..f189a0d 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2715,6 +3155,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2722,6 +3162,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -2606,16 +2606,16 @@ index 6d2eec5..f189a0d 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2742,7 +3387,7 @@ compare (struct line const *a, struct line const *b) +@@ -2749,7 +3394,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; - else if (hard_LC_COLLATE) + else if (hard_LC_COLLATE && !folding) { - /* Note xmemcoll0 is a performance enhancement as + /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4139,6 +4784,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4144,6 +4789,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -2623,7 +2623,7 @@ index 6d2eec5..f189a0d 100644 break; case 'g': key->general_numeric = true; -@@ -4218,7 +4864,7 @@ main (int argc, char **argv) +@@ -4223,7 +4869,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2632,7 +2632,7 @@ index 6d2eec5..f189a0d 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4239,6 +4885,29 @@ main (int argc, char **argv) +@@ -4244,6 +4890,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -2662,7 +2662,7 @@ index 6d2eec5..f189a0d 100644 have_read_stdin = false; inittables (); -@@ -4513,13 +5182,34 @@ main (int argc, char **argv) +@@ -4518,13 +5187,34 @@ main (int argc, char **argv) case 't': { @@ -2701,7 +2701,7 @@ index 6d2eec5..f189a0d 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4530,9 +5220,11 @@ main (int argc, char **argv) +@@ -4535,9 +5225,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -2715,7 +2715,7 @@ index 6d2eec5..f189a0d 100644 } break; -@@ -4770,12 +5462,10 @@ main (int argc, char **argv) +@@ -4765,12 +5457,10 @@ main (int argc, char **argv) sort (files, nfiles, outfile, nthreads); } @@ -3119,7 +3119,7 @@ index 87a0c93..9f755d9 100644 skip_fields = 0; check_chars = SIZE_MAX; diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh -new file mode 100644 +new file mode 100755 index 0000000..26c95de --- /dev/null +++ b/tests/i18n/sort.sh @@ -3157,7 +3157,7 @@ diff --git a/tests/local.mk b/tests/local.mk index 568944e..192f776 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -352,6 +352,8 @@ all_tests = \ +@@ -358,6 +358,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -3212,8 +3212,8 @@ index 8a9cad1..9293e39 100755 my @Tests = ( ['t1', '--tabs=3', {IN=>"a\tb"}, {OUT=>"a b"}], -@@ -152,6 +161,8 @@ my @Tests = - ['trail9', '--tab=1,2 -t/5',{IN=>"\ta\tb\tc"}, {OUT=>" a b c"}], +@@ -168,6 +177,8 @@ my @Tests = + # Test errors + # FIXME: The following tests contain ‘quoting’ specific to LC_MESSAGES @@ -3221,7 +3221,7 @@ index 8a9cad1..9293e39 100755 ['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}, -@@ -168,6 +179,37 @@ my @Tests = +@@ -184,6 +195,37 @@ my @Tests = {ERR => "$prog: '/' specifier not at start of number: '/'\n"}], ); @@ -3403,7 +3403,7 @@ index 4d399d8..07f2823 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh -new file mode 100644 +new file mode 100755 index 0000000..11836ba --- /dev/null +++ b/tests/misc/sort-mb-tests.sh diff --git a/coreutils.spec b/coreutils.spec index 9265112..b38410a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.27 -Release: 16%{?dist} +Version: 8.28 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -13,21 +13,6 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ -# upstream patches -Patch1: coreutils-8.27-date-debug-test.patch - -# date, touch: fix out-of-bounds write via large TZ variable (CVE-2017-7476) -Patch2: coreutils-8.27-CVE-2017-7476.patch - -# tail: revert to polling if a followed directory is replaced (#1283760) -Patch3: coreutils-8.27-tail-inotify-recreate.patch - -# doc: mention `setpriv --no-new-privs` feature in runcon info -Patch4: coreutils-8.27-runcon-doc.patch - -# ptx: fix a possible crash caused by integer overflow (#1482445) -Patch5: coreutils-8.27-ptx-int-overflow.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -296,6 +281,9 @@ fi %license COPYING %changelog +* Mon Sep 04 2017 Kamil Dudka - 8.28-1 +- new upstream release 8.28 + * Tue Aug 22 2017 Ville Skyttä - 8.27-16 - Own the %%{_libexecdir}/coreutils dir diff --git a/sources b/sources index 2566cf4..56ed512 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (coreutils-8.27.tar.xz) = abf3280aaa54e9bd5851df0eda2af1de1017ca174633e52d1e592455d46ea0e99812dda46d2f320e979553cef271485d8818c595bba6ed31264511a511c93679 +SHA512 (coreutils-8.28.tar.xz) = 1e592d0dd03b9227bf92af9a82bed6dc3bcbee46e984c7fb09833dea0962e86b309aa34d5e43823b73d4522c066bfa5cdc8ec694aa190910fb246ff32ceb63a1 From bb681e6c3092d1fc5a99746c6810dcee68107dd1 Mon Sep 17 00:00:00 2001 From: Rachel Sibley Date: Thu, 21 Sep 2017 11:38:05 -0400 Subject: [PATCH 358/523] Initial commit for Atomic Host Tests --- .../Makefile | 63 +++++++++++++++++++ .../PURPOSE | 54 ++++++++++++++++ .../runtest.sh | 60 ++++++++++++++++++ tests/test-basics | 39 ++++++++++++ tests/test_basics.yml | 9 +++ tests/tests.yml | 1 + 6 files changed, 226 insertions(+) create mode 100644 tests/readlink-cannot-handle-recursive-symlinks/Makefile create mode 100644 tests/readlink-cannot-handle-recursive-symlinks/PURPOSE create mode 100755 tests/readlink-cannot-handle-recursive-symlinks/runtest.sh create mode 100755 tests/test-basics create mode 100644 tests/test_basics.yml create mode 100644 tests/tests.yml diff --git a/tests/readlink-cannot-handle-recursive-symlinks/Makefile b/tests/readlink-cannot-handle-recursive-symlinks/Makefile new file mode 100644 index 0000000..49d37a7 --- /dev/null +++ b/tests/readlink-cannot-handle-recursive-symlinks/Makefile @@ -0,0 +1,63 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlink s +# Description: Test for readlink cannot handle recursive symlinks +# Author: Jan Scotka +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2010 Red Hat, Inc. All rights reserved. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Jan Scotka " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Test for readlink cannot handle recursive symlinks" >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 5m" >> $(METADATA) + @echo "RunFor: coreutils" >> $(METADATA) + @echo "Requires: coreutils" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + + rhts-lint $(METADATA) diff --git a/tests/readlink-cannot-handle-recursive-symlinks/PURPOSE b/tests/readlink-cannot-handle-recursive-symlinks/PURPOSE new file mode 100644 index 0000000..b9fd740 --- /dev/null +++ b/tests/readlink-cannot-handle-recursive-symlinks/PURPOSE @@ -0,0 +1,54 @@ +PURPOSE of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks +Description: Test for readlink cannot handle recursive symlinks +Author: Jan Scotka +Bug summary: readlink cannot handle recursive symlinks + +Description: + +Description of problem: +The readlink command fails with an error "Too many levels of symbolic links", even if there are only 2 levels. + +The readlink command from RHEL 3 and RHEL 4 and from Fedora 11 all work fine. + +Among other changes between RHEL 4 and RHEL 5, RHEL 5's coreutils added calls to cycle_check() in lib/canonicalize.c, but in upstream canonicalize.c (now in gnulib instead of coreutils), we see the comment: + /* Detect loops. We cannot use the cycle-check module here, + since it's actually possible to encounter the same symlink + more than once in a given traversal. However, encountering + the same symlink,NAME pair twice does indicate a loop. */ + +http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/canonicalize.c;h=4f348398fd69ae516396313d18ac294a4ca3dde3;hb=b653eda3ac4864de205419d9f41eec267cb89eeb#l262 + +The latest canonicalize.c uses seen_triple() instead of cycle_check(). + + +Version-Release number of selected component (if applicable): +coreutils-5.97-19.el5 + +How reproducible: +every time + +Steps to Reproduce: +1. Create a directory with a symlink to itself + mkdir /tmp/dir + cd /tmp/dir + ln -s ../dir dirlink + +2. Run readlink using the 'dirlink' symlink recursively + readlink -v -f dirlink + readlink -v -f dirlink/dirlink + readlink -v -f dirlink/dirlink/dirlink + +Actual results: +The first readlink command on just dirlink succeeds, but the 2nd and 3rd commands fail with + readlink: dirlink/dirlink: Too many levels of symbolic links + +Expected results: +$ readlink -v -f dirlink +/tmp/dir +$ readlink -v -f dirlink/dirlink +/tmp/dir +$ readlink -v -f dirlink/dirlink/dirlink +/tmp/dir + + +Additional info: diff --git a/tests/readlink-cannot-handle-recursive-symlinks/runtest.sh b/tests/readlink-cannot-handle-recursive-symlinks/runtest.sh new file mode 100755 index 0000000..6ee251f --- /dev/null +++ b/tests/readlink-cannot-handle-recursive-symlinks/runtest.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks +# Description: Test for readlink cannot handle recursive symlinks +# Author: Jan Scotka +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2010 Red Hat, Inc. All rights reserved. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include rhts environment +. /usr/bin/rhts-environment.sh +. /usr/lib/beakerlib/beakerlib.sh + +PACKAGE="coreutils" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm $PACKAGE + rlRun "TmpDir=\`mktemp -d\`" 0 "Creating tmp directory" + rlRun "pushd $TmpDir" + rlRun "mkdir link" 0 "Creating test directory" + rlRun "cd link" 0 "cd to this dir" + rlRun "ln -s ../link link" 0 "creating symlink to ../link -> link" + rlPhaseEnd + + rlPhaseStartTest + rlLog "Test of readlink up to 20 iteration" + export TMPVAR="link" + for foo in `seq 20` + do echo $TMPVAR + rlRun "readlink -v -f $TMPVAR" 0 "readlink of $TMPVAR" + TMPVAR="$TMPVAR/link" + done + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "popd" + rlRun "rm -r $TmpDir" 0 "Removing tmp directory" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd diff --git a/tests/test-basics b/tests/test-basics new file mode 100755 index 0000000..7324553 --- /dev/null +++ b/tests/test-basics @@ -0,0 +1,39 @@ +#!/bin/sh + +# Checks that touch ls rm and foo work +# https://www.mankier.com/1/beakerlib#Examples +. /usr/share/beakerlib/beakerlib.sh + +# Set the full test name +TEST="/examples/beakerlib/Sanity/phases" + +# Package being tested +PACKAGE="coreutils" + +rlJournalStart + # Setup phase: Prepare test directory + rlPhaseStartSetup + rlAssertRpm $PACKAGE + rlRun 'TmpDir=$(mktemp -d)' 0 'Creating tmp directory' # no-reboot + rlRun "pushd $TmpDir" + rlPhaseEnd + + # Test phase: Testing touch, ls and rm commands + rlPhaseStartTest + rlRun "touch foo" 0 "Creating the foo test file" + rlAssertExists "foo" + rlRun "ls -l foo" 0 "Listing the foo test file" + rlRun "rm foo" 0 "Removing the foo test file" + rlAssertNotExists "foo" + rlRun "ls -l foo" 2 "Listing foo should now report an error" + rlPhaseEnd + + # Cleanup phase: Remove test directory + rlPhaseStartCleanup + rlRun "popd" + rlRun "rm -r $TmpDir" 0 "Removing tmp directory" + rlPhaseEnd +rlJournalEnd + +# Print the test report +rlJournalPrintText diff --git a/tests/test_basics.yml b/tests/test_basics.yml new file mode 100644 index 0000000..d5727cf --- /dev/null +++ b/tests/test_basics.yml @@ -0,0 +1,9 @@ +--- +# This first play always runs on the local staging system +- hosts: localhost + tags: + - atomic + - classic + - container + roles: + - { role: standard-test-beakerlib, tests: [ test-basics, readlink-cannot-handle-recursive-symlinks ] } diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..57b5c48 --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1 @@ +- include: test_basics.yml From ab7465c4fae033c2d6097fb6366dcb7a7d6bd807 Mon Sep 17 00:00:00 2001 From: Rachel Sibley Date: Thu, 21 Sep 2017 12:45:49 -0400 Subject: [PATCH 359/523] add reference link to fedora ci wiki --- tests/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tests.yml b/tests/tests.yml index 57b5c48..529263d 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -1 +1,2 @@ +# Fedora Continuous Integration: https://fedoraproject.org/wiki/CI - include: test_basics.yml From 02030dc9153a1730ba25a3a87c384250a7b52ec9 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Tue, 7 Nov 2017 16:44:27 +0100 Subject: [PATCH 360/523] Remove very old Provides (mktemp, sh-utils, textwrap, fileutils, stat) Those are gone in fc9, more than decade ago. Signed-off-by: Igor Gnatenko --- coreutils.spec | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index b38410a..af6c51c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.28 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -115,19 +115,6 @@ Requires: ncurses Provides: bundled(gnulib) Provides: coreutils-full = %{version}-%{release} -Provides: fileutils = %{version}-%{release} -Provides: sh-utils = %{version}-%{release} -Provides: stat = %{version}-%{release} -Provides: textutils = %{version}-%{release} - -#old mktemp package had epoch 3, so we have to use 4 for coreutils -Provides: mktemp = 4:%{version}-%{release} -Obsoletes: mktemp < 4:%{version}-%{release} - -Obsoletes: fileutils <= 4.1.9 -Obsoletes: sh-utils <= 2.0.12 -Obsoletes: stat <= 3.3 -Obsoletes: textutils <= 2.0.21 Obsoletes: %{name} < 8.24-100 %description @@ -281,6 +268,9 @@ fi %license COPYING %changelog +* Tue Nov 07 2017 Igor Gnatenko - 8.28-2 +- Remove very old Provides (mktemp, sh-utils, textwrap, fileutils, stat) + * Mon Sep 04 2017 Kamil Dudka - 8.28-1 - new upstream release 8.28 From 0cb3deb32ba7cec55688bd1d5ed9e79d2a418b3c Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 2 Jan 2018 15:15:50 +0100 Subject: [PATCH 361/523] new upstream release 8.29 --- coreutils-8.28.tar.xz.sig | 16 ---------------- coreutils-8.29.tar.xz.sig | 16 ++++++++++++++++ coreutils.spec | 7 +++++-- sources | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) delete mode 100644 coreutils-8.28.tar.xz.sig create mode 100644 coreutils-8.29.tar.xz.sig diff --git a/coreutils-8.28.tar.xz.sig b/coreutils-8.28.tar.xz.sig deleted file mode 100644 index 4a76f06..0000000 --- a/coreutils-8.28.tar.xz.sig +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIcBAABAgAGBQJZqhkfAAoJEN9v2XEwYDfZZEQP/REePQxk2OXPSRSyYSaazIeP -gDno1D4tcHXHhvl210ouOEvCGux6tJtHmCQ5Y43Dkt56DJ3Eb9dk2JYrisvcrJhv -3m098YY2hseVLJ7M3jnf9slAXBrS23i+mUWHADeRpFIJZQQz1KEZVb1gsI0FO9Ch -Qp64hBPB4X1Ydxz57KywUpEgBC9Cj0KwWW9L6jIHK+V1izLoI1JslUxHXkyTy9as -WjmDuJp1nMewjbAza//HHNiqote59JewuLcxiA9EdK8jzQZXF+fbRasFO3XEobMl -0WYtN0MwYN2576xSGwTyp7IakFcNHjWciE9SuvPmg/VCLELV6vl4VJXAmv/kQKeE -whVq7kfdzRAKDwUXdXyCqzYSEi1+N+2izJaI4twgExDwm89OApe6aka8UBbqClyz -cn4UmqYMgjwvKXPJtqMUmzEwAzDxuXQJL6Uj5kY8RJLCqBv/eN+YoxODTZz3oDGU -988K6K2Q9QaOGSNJHiBrgddCARuxeRVizbDSi2GcSQdPRbTM4g7YK//KE8LoKdil -ngIeam0vomPJnJqI03U1wGKhxsDqOEEQ3CFch7mQ2S1eWtqeag3arcBVALZUdCzX -hckiSXd0Yuks8AyHb8LH7/3h1BJUWVg/v7iQ2E3UMHAE78Ww28MyppMhy+4U9knU -Dp2VXtxBOJVXJETdVFXY -=7Q/5 ------END PGP SIGNATURE----- diff --git a/coreutils-8.29.tar.xz.sig b/coreutils-8.29.tar.xz.sig new file mode 100644 index 0000000..614c344 --- /dev/null +++ b/coreutils-8.29.tar.xz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIcBAABAgAGBQJaQ+ZxAAoJEN9v2XEwYDfZOF8P/i9zNyDAerVBh6UOyW9ijDZ5 +3vSWYzgmNNxUp0BfptJ0xqirH8tKRvgHzoy87Eu5PvmARASKOtnjc1cap885HIto +j5LlGe2t73xoW049dIx00DwsZFo9ef/DZnaSRo96MlW1xXlHtuYTDwR9ovWt5xHx +a+SrzG05kdZlybQ8rLlz5MFxs43IHQHZ0wudlcP2KxlP2HEtBPDto/xmOxw7jVBD +5ZOhiTCB6Dza5QxWGCX3ij1YYEn9mmSsmp6Hp4QteskWlp6mpJEViW2GW6p3zUSe +EqpM9beax1pRKYcBMuXBDtSCS+Sxw//ZybE/p+bY5K2T0Z8zxUd325t4oGnb8uRK +jMBdm9SnlK9bkyouHxY3eK6XNMG/u4YZ/p4jk8QB4YdYN3t7u6aJ6443OgKDlmPF +qfELnZdPvOA9kdC8+oLz37Z/e7HmrZXforxk00qn/GCAVxqHhzu7QbME4/Zzufwt +bHQ2JcVqywmFfv0bI5rs/EpOYJoGOwlVFq/u6mykvzYgrFUgG171eu3SHrkFAWfA +hWz5mL1W3x/SYg/K+ySKlGtrQ877FNSHLOVP5cDme6HgAiV9rWyah44IEDwakyDk +yfDURjKUtNaSq9PAyGUXj4nJ4BklTIyRqiXUfIs8OK9UMPqrJsFSCxzSVAJWsuGL +Q2dcgRAkwMwrwhzed2ot +=QwW/ +-----END PGP SIGNATURE----- diff --git a/coreutils.spec b/coreutils.spec index af6c51c..c22b52c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.28 -Release: 2%{?dist} +Version: 8.29 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -268,6 +268,9 @@ fi %license COPYING %changelog +* Tue Jan 02 2018 Kamil Dudka - 8.29-1 +- new upstream release 8.29 + * Tue Nov 07 2017 Igor Gnatenko - 8.28-2 - Remove very old Provides (mktemp, sh-utils, textwrap, fileutils, stat) diff --git a/sources b/sources index 56ed512..cf5fb64 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (coreutils-8.28.tar.xz) = 1e592d0dd03b9227bf92af9a82bed6dc3bcbee46e984c7fb09833dea0962e86b309aa34d5e43823b73d4522c066bfa5cdc8ec694aa190910fb246ff32ceb63a1 +SHA512 (coreutils-8.29.tar.xz) = 546bbcd5741beae7a68e7c4ca14d6d634f7c8be87feecdeddd00e226f4865bb89d503437c3a95622ba7bb0cb70addbb5bdf3767fa18d0b7410ab90ee53b29dfd From 7effe141a5105e161d7e9b2dfcbac0fa4721fdd3 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 2 Jan 2018 15:27:41 +0100 Subject: [PATCH 362/523] add BR for hostname ... to avoid the following build-time message: ./configure: line 7463: hostname: command not found --- coreutils.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/coreutils.spec b/coreutils.spec index c22b52c..82fb469 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -97,6 +97,7 @@ BuildRequires: automake BuildRequires: bison BuildRequires: gettext-devel BuildRequires: gmp-devel +BuildRequires: hostname BuildRequires: libacl-devel BuildRequires: libattr-devel BuildRequires: libcap-devel From d51b521e30a0329b6347164b64287082fd3e7c48 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 2 Jan 2018 15:26:42 +0100 Subject: [PATCH 363/523] avoid test-suite failure if SELinux is disabled --- coreutils-8.26-selinuxenable.patch | 26 ++++++++++++++++++++++++++ coreutils.spec | 4 ++++ 2 files changed, 30 insertions(+) create mode 100644 coreutils-8.26-selinuxenable.patch diff --git a/coreutils-8.26-selinuxenable.patch b/coreutils-8.26-selinuxenable.patch new file mode 100644 index 0000000..d9b625a --- /dev/null +++ b/coreutils-8.26-selinuxenable.patch @@ -0,0 +1,26 @@ +From 6880c3dc9098b3337612850d1500b474aeb944ca Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Tue, 29 Aug 2017 17:33:51 +0200 +Subject: [PATCH] require_selinux_(): use selinuxenabled(8) if available + +--- + init.cfg | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/init.cfg b/init.cfg +index af6b581..f887b3a 100644 +--- a/init.cfg ++++ b/init.cfg +@@ -114,6 +114,9 @@ require_selinux_() + grep 'selinuxfs$' /proc/filesystems > /dev/null \ + || skip_ "this system lacks SELinux support" + ++ # use the 'selinuxenabled' utility if available ++ selinuxenabled; [ $? = 1 ] && skip_ "SELinux is disabled" ++ + # Independent of whether SELinux is enabled system-wide, + # the current file system may lack SELinux support. + # Also the current build may have SELinux support disabled. +-- +2.9.5 + diff --git a/coreutils.spec b/coreutils.spec index 82fb469..444600e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -16,6 +16,9 @@ Source106: coreutils-colorls.csh # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch +# require_selinux_(): use selinuxenabled(8) if available +Patch105: coreutils-8.26-selinuxenable.patch + #add note about no difference between binary/text mode on Linux - md5sum manpage Patch101: coreutils-6.10-manpages.patch # downstream changes to default DIR_COLORS @@ -102,6 +105,7 @@ BuildRequires: libacl-devel BuildRequires: libattr-devel BuildRequires: libcap-devel BuildRequires: libselinux-devel +BuildRequires: libselinux-utils BuildRequires: openssl-devel BuildRequires: strace BuildRequires: texinfo From 79fe59c7fc11afa211a15bfcf28f4ca76f42c645 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 23 Jan 2018 16:42:41 +0100 Subject: [PATCH 364/523] mv -n: do not overwrite the destination --- coreutils-8.29-mv-n-noreplace.patch | 63 +++++++++++++++++++++++++++++ coreutils.spec | 9 ++++- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.29-mv-n-noreplace.patch diff --git a/coreutils-8.29-mv-n-noreplace.patch b/coreutils-8.29-mv-n-noreplace.patch new file mode 100644 index 0000000..4f82716 --- /dev/null +++ b/coreutils-8.29-mv-n-noreplace.patch @@ -0,0 +1,63 @@ +From 76df06ff8fa39ae0cb0d167b7f622139778dc7d7 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 4 Jan 2018 09:42:10 +0100 +Subject: [PATCH] mv -n: do not overwrite the destination + +... if it is created by another process after mv has checked its +non-existence. + +* src/copy.c (copy_internal): Use renameat2 (..., RENAME_NOREPLACE) +if called by mv -n. If it fails with EEXIST in that case, pretend +successful rename as if the existing destination file was detected +by the preceding lstat call. + +Fixes https://bugs.gnu.org/29961 +--- + src/copy.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/src/copy.c b/src/copy.c +index 2a804945e..be4e357a8 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -53,6 +53,7 @@ + #include "ignore-value.h" + #include "ioblksize.h" + #include "quote.h" ++#include "renameat2.h" + #include "root-uid.h" + #include "same.h" + #include "savedir.h" +@@ -2319,7 +2320,12 @@ copy_internal (char const *src_name, char const *dst_name, + + if (x->move_mode) + { +- if (rename (src_name, dst_name) == 0) ++ int flags = 0; ++ if (x->interactive == I_ALWAYS_NO) ++ /* do not replace DST_NAME if it was created since our last check */ ++ flags = RENAME_NOREPLACE; ++ ++ if (renameat2 (AT_FDCWD, src_name, AT_FDCWD, dst_name, flags) == 0) + { + if (x->verbose) + { +@@ -2351,6 +2357,15 @@ copy_internal (char const *src_name, char const *dst_name, + return true; + } + ++ if ((flags & RENAME_NOREPLACE) && (errno == EEXIST)) ++ { ++ /* Pretend the rename succeeded, so the caller (mv) ++ doesn't end up removing the source file. */ ++ if (rename_succeeded) ++ *rename_succeeded = true; ++ return true; ++ } ++ + /* FIXME: someday, consider what to do when moving a directory into + itself but when source and destination are on different devices. */ + +-- +2.13.6 + diff --git a/coreutils.spec b/coreutils.spec index 444600e..6076b43 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -13,6 +13,10 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ +# mv -n: do not overwrite the destination, superseded by +# http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=v8.29-9-g29baf25aa +Patch1: coreutils-8.29-mv-n-noreplace.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -273,6 +277,9 @@ fi %license COPYING %changelog +* Tue Jan 23 2018 Kamil Dudka - 8.29-2 +- mv -n: do not overwrite the destination + * Tue Jan 02 2018 Kamil Dudka - 8.29-1 - new upstream release 8.29 From fd470b54bc98736e78a110da8346d9190bd8bae8 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 23 Jan 2018 16:50:37 +0100 Subject: [PATCH 365/523] Resolves: CVE-2017-18018 - doc: warn about following symlinks recursively in chown/chgrp --- coreutils-8.29-CVE-2017-18018.patch | 124 ++++++++++++++++++++++++++++ coreutils.spec | 4 + 2 files changed, 128 insertions(+) create mode 100644 coreutils-8.29-CVE-2017-18018.patch diff --git a/coreutils-8.29-CVE-2017-18018.patch b/coreutils-8.29-CVE-2017-18018.patch new file mode 100644 index 0000000..577c90b --- /dev/null +++ b/coreutils-8.29-CVE-2017-18018.patch @@ -0,0 +1,124 @@ +From 0aa9b0a92cb61af76b75b57abfd6ea1a7c627367 Mon Sep 17 00:00:00 2001 +From: Michael Orlitzky +Date: Thu, 28 Dec 2017 15:52:42 -0500 +Subject: [PATCH 1/2] doc: clarify chown/chgrp --dereference defaults + +* doc/coreutils.texi: the documentation for the --dereference + flag of chown/chgrp states that it is the default mode of + operation. Document that this is only the case when operating + non-recursively. + +Upstream-commit: 7597cfa482e42a00a69fb9577ee523762980a9a2 +Signed-off-by: Kamil Dudka +--- + doc/coreutils.texi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index de1f2eb..de06c0f 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -10989,7 +10989,7 @@ chown -h -R --from=OLDUSER NEWUSER / + @cindex symbolic links, changing owner + @findex lchown + Do not act on symbolic links themselves but rather on what they point to. +-This is the default. ++This is the default when not operating recursively. + + @item -h + @itemx --no-dereference +@@ -11119,7 +11119,7 @@ changed. + @cindex symbolic links, changing owner + @findex lchown + Do not act on symbolic links themselves but rather on what they point to. +-This is the default. ++This is the default when not operating recursively. + + @item -h + @itemx --no-dereference +-- +2.13.6 + + +From 3fb331864c718e065804049001b573ff94810772 Mon Sep 17 00:00:00 2001 +From: Michael Orlitzky +Date: Thu, 4 Jan 2018 11:38:21 -0500 +Subject: [PATCH 2/2] doc: warn about following symlinks recursively in + chown/chgrp + +In both chown and chgrp (which shares its code with chown), operating +on symlinks recursively has a window of vulnerability where the +destination user or group can change the target of the operation. +Warn about combining the --dereference, --recursive, and -L flags. + +* doc/coreutils.texi (warnOptDerefWithRec): Add macro. +(node chown invocation): Add it to --dereference and -L. +(node chgrp invocation): Likewise. + +See also: CVE-2017-18018 + +Upstream-commit: bc2fd9796403e03bb757b064d44c22fab92e6842 +Signed-off-by: Kamil Dudka +--- + doc/coreutils.texi | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index de06c0f..24cc85b 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -1428,6 +1428,19 @@ a command line argument is a symbolic link to a directory, traverse it. + In a recursive traversal, traverse every symbolic link to a directory + that is encountered. + @end macro ++ ++@c Append the following warning to -L where appropriate (e.g. chown). ++@macro warnOptDerefWithRec ++ ++Combining this dereferencing option with the @option{--recursive} option ++may create a security risk: ++During the traversal of the directory tree, an attacker may be able to ++introduce a symlink to an arbitrary target; when the tool reaches that, ++the operation will be performed on the target of that symlink, ++possibly allowing the attacker to escalate privileges. ++ ++@end macro ++ + @choptL + + @macro choptP +@@ -10990,6 +11003,7 @@ chown -h -R --from=OLDUSER NEWUSER / + @findex lchown + Do not act on symbolic links themselves but rather on what they point to. + This is the default when not operating recursively. ++@warnOptDerefWithRec + + @item -h + @itemx --no-dereference +@@ -11046,6 +11060,7 @@ Recursively change ownership of directories and their contents. + @xref{Traversing symlinks}. + + @choptL ++@warnOptDerefWithRec + @xref{Traversing symlinks}. + + @choptP +@@ -11120,6 +11135,7 @@ changed. + @findex lchown + Do not act on symbolic links themselves but rather on what they point to. + This is the default when not operating recursively. ++@warnOptDerefWithRec + + @item -h + @itemx --no-dereference +@@ -11175,6 +11191,7 @@ Recursively change the group ownership of directories and their contents. + @xref{Traversing symlinks}. + + @choptL ++@warnOptDerefWithRec + @xref{Traversing symlinks}. + + @choptP +-- +2.13.6 + diff --git a/coreutils.spec b/coreutils.spec index 6076b43..210a13f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -17,6 +17,9 @@ Source106: coreutils-colorls.csh # http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=v8.29-9-g29baf25aa Patch1: coreutils-8.29-mv-n-noreplace.patch +# doc: warn about following symlinks recursively in chown/chgrp (CVE-2017-18018) +Patch2: coreutils-8.29-CVE-2017-18018.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -278,6 +281,7 @@ fi %changelog * Tue Jan 23 2018 Kamil Dudka - 8.29-2 +- doc: warn about following symlinks recursively in chown/chgrp (CVE-2017-18018) - mv -n: do not overwrite the destination * Tue Jan 02 2018 Kamil Dudka - 8.29-1 From 5d3dc8fdbde4980a23ed868ec0866fe2467b2c11 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 7 Feb 2018 05:45:49 +0000 Subject: [PATCH 366/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 210a13f..281b157 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -280,6 +280,9 @@ fi %license COPYING %changelog +* Wed Feb 07 2018 Fedora Release Engineering - 8.29-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + * Tue Jan 23 2018 Kamil Dudka - 8.29-2 - doc: warn about following symlinks recursively in chown/chgrp (CVE-2017-18018) - mv -n: do not overwrite the destination From 4a8582e246a74a12b89df52b70e618086fb8aa36 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 19 Feb 2018 16:23:12 +0100 Subject: [PATCH 367/523] add explicit BR for the gcc compiler ... as instructed at: https://fedoraproject.org/wiki/Packaging:C_and_C%2B%2B --- coreutils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 281b157..2cff074 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -105,6 +105,7 @@ BuildRequires: attr BuildRequires: autoconf BuildRequires: automake BuildRequires: bison +BuildRequires: gcc BuildRequires: gettext-devel BuildRequires: gmp-devel BuildRequires: hostname @@ -280,6 +281,9 @@ fi %license COPYING %changelog +* Mon Feb 19 2018 Kamil Dudka - 8.29-4 +- add explicit BR for the gcc compiler + * Wed Feb 07 2018 Fedora Release Engineering - 8.29-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild From e9599c8226f2b56f4f4e9c69d6159135eea65f91 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Mon, 26 Feb 2018 11:21:02 +0100 Subject: [PATCH 368/523] Remove /bin/* Provides UsrMove happened more than 10 Fedora releases ago. Signed-off-by: Igor Gnatenko --- coreutils.spec | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 2cff074..20f7603 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -69,37 +69,6 @@ Patch950: coreutils-selinux.patch Conflicts: filesystem < 3 # To avoid clobbering installs Conflicts: coreutils-single -Provides: /bin/basename -Provides: /bin/cat -Provides: /bin/chgrp -Provides: /bin/chmod -Provides: /bin/chown -Provides: /bin/cp -Provides: /bin/cut -Provides: /bin/date -Provides: /bin/dd -Provides: /bin/df -Provides: /bin/echo -Provides: /bin/env -Provides: /bin/false -Provides: /bin/ln -Provides: /bin/ls -Provides: /bin/mkdir -Provides: /bin/mknod -Provides: /bin/mktemp -Provides: /bin/mv -Provides: /bin/nice -Provides: /bin/pwd -Provides: /bin/readlink -Provides: /bin/rm -Provides: /bin/rmdir -Provides: /bin/sleep -Provides: /bin/sort -Provides: /bin/stty -Provides: /bin/sync -Provides: /bin/touch -Provides: /bin/true -Provides: /bin/uname BuildRequires: attr BuildRequires: autoconf @@ -281,6 +250,9 @@ fi %license COPYING %changelog +* Mon Feb 26 2018 Igor Gnatenko - 8.29-5 +- Remove /bin/* Provides + * Mon Feb 19 2018 Kamil Dudka - 8.29-4 - add explicit BR for the gcc compiler From 7995abc6ec82d4c81ecb5991b0828da4b634032d Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 6 Mar 2018 12:44:50 +0100 Subject: [PATCH 369/523] fix build failure with glibc-2.28 Reported at: https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html ../lib/freadahead.c: In function 'freadahead': ../lib/freadahead.c:97:3: error: #error "Please port gnulib freadahead.c to your platform! Look at the definition of fflush, fread, ungetc on your system, then report this to bug-gnulib." #error "Please port gnulib freadahead.c to your platform! Look at the definition of fflush, fread, ungetc on your system, then report this to bug-gnulib." ^~~~~ ../lib/freadahead.c:99:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ make[2]: *** [Makefile:9144: lib/freadahead.o] Error 1 make[2]: *** Waiting for unfinished jobs.... ../lib/freadptr.c: In function 'freadptr': ../lib/freadptr.c:119:3: error: #error "Please port gnulib freadptr.c to your platform! Look at the definition of fflush, fread, getc, getc_unlocked on your system, then report this to bug-gnulib." #error "Please port gnulib freadptr.c to your platform! Look at the definition of fflush, fread, getc, getc_unlocked on your system, then report this to bug-gnulib." ^~~~~ ../lib/freadptr.c:29:10: warning: unused variable 'size' [-Wunused-variable] size_t size; ^~~~ ../lib/freadptr.c:121:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ --- coreutils-8.29-gnulib-fflush.patch | 202 +++++++++++++++++++++++++++++ coreutils.spec | 9 +- 2 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.29-gnulib-fflush.patch diff --git a/coreutils-8.29-gnulib-fflush.patch b/coreutils-8.29-gnulib-fflush.patch new file mode 100644 index 0000000..346b0e3 --- /dev/null +++ b/coreutils-8.29-gnulib-fflush.patch @@ -0,0 +1,202 @@ +From 08d69db2f3c0e8506a1d126dd4dcdd0f14071161 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Mon, 5 Mar 2018 10:56:29 -0800 +Subject: [PATCH] fflush: adjust to glibc 2.28 libio.h removal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Problem reported by Daniel P. Berrangé in: +https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html +* lib/fflush.c (clear_ungetc_buffer_preserving_position) +(disable_seek_optimization, rpl_fflush): +* lib/fpending.c (__fpending): +* lib/fpurge.c (fpurge): +* lib/freadahead.c (freadahead): +* lib/freading.c (freading): +* lib/freadptr.c (freadptr): +* lib/freadseek.c (freadptrinc): +* lib/fseeko.c (fseeko): +* lib/fseterr.c (fseterr): +* lib/stdio-impl.h (_IO_IN_BACKUP) [_IO_EOF_SEEN]: +Define if not already defined. + +Upstream-commit: 4af4a4a71827c0bc5e0ec67af23edef4f15cee8e +Signed-off-by: Kamil Dudka +--- + lib/fflush.c | 6 +++--- + lib/fpending.c | 2 +- + lib/fpurge.c | 2 +- + lib/freadahead.c | 2 +- + lib/freading.c | 2 +- + lib/freadptr.c | 2 +- + lib/freadseek.c | 2 +- + lib/fseeko.c | 4 ++-- + lib/fseterr.c | 2 +- + lib/stdio-impl.h | 6 ++++++ + 10 files changed, 18 insertions(+), 12 deletions(-) + +diff --git a/lib/fflush.c b/lib/fflush.c +index 4e65692..c16da5f 100644 +--- a/lib/fflush.c ++++ b/lib/fflush.c +@@ -33,7 +33,7 @@ + #undef fflush + + +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + + /* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */ + static void +@@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp) + + #endif + +-#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */) ++#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */) + + # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ +@@ -148,7 +148,7 @@ rpl_fflush (FILE *stream) + if (stream == NULL || ! freading (stream)) + return fflush (stream); + +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + + clear_ungetc_buffer_preserving_position (stream); + +diff --git a/lib/fpending.c b/lib/fpending.c +index 5811a4a..9e21a16 100644 +--- a/lib/fpending.c ++++ b/lib/fpending.c +@@ -32,7 +32,7 @@ __fpending (FILE *fp) + /* Most systems provide FILE as a struct and the necessary bitmask in + , because they need it for implementing getc() and putc() as + fast macros. */ +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + return fp->_IO_write_ptr - fp->_IO_write_base; + #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ +diff --git a/lib/fpurge.c b/lib/fpurge.c +index 408b8fc..3a16000 100644 +--- a/lib/fpurge.c ++++ b/lib/fpurge.c +@@ -62,7 +62,7 @@ fpurge (FILE *fp) + /* Most systems provide FILE as a struct and the necessary bitmask in + , because they need it for implementing getc() and putc() as + fast macros. */ +-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_IO_read_end = fp->_IO_read_ptr; + fp->_IO_write_ptr = fp->_IO_write_base; + /* Avoid memory leak when there is an active ungetc buffer. */ +diff --git a/lib/freadahead.c b/lib/freadahead.c +index f335f04..e7cb77b 100644 +--- a/lib/freadahead.c ++++ b/lib/freadahead.c +@@ -30,7 +30,7 @@ extern size_t __sreadahead (FILE *); + size_t + freadahead (FILE *fp) + { +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + if (fp->_IO_write_ptr > fp->_IO_write_base) + return 0; + return (fp->_IO_read_end - fp->_IO_read_ptr) +diff --git a/lib/freading.c b/lib/freading.c +index 78140d2..c9d3344 100644 +--- a/lib/freading.c ++++ b/lib/freading.c +@@ -31,7 +31,7 @@ freading (FILE *fp) + /* Most systems provide FILE as a struct and the necessary bitmask in + , because they need it for implementing getc() and putc() as + fast macros. */ +-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + return ((fp->_flags & _IO_NO_WRITES) != 0 + || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0 + && fp->_IO_read_base != NULL)); +diff --git a/lib/freadptr.c b/lib/freadptr.c +index e4cc0b0..aba8dd5 100644 +--- a/lib/freadptr.c ++++ b/lib/freadptr.c +@@ -29,7 +29,7 @@ freadptr (FILE *fp, size_t *sizep) + size_t size; + + /* Keep this code in sync with freadahead! */ +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + if (fp->_IO_write_ptr > fp->_IO_write_base) + return NULL; + size = fp->_IO_read_end - fp->_IO_read_ptr; +diff --git a/lib/freadseek.c b/lib/freadseek.c +index fcecba6..98726f8 100644 +--- a/lib/freadseek.c ++++ b/lib/freadseek.c +@@ -36,7 +36,7 @@ freadptrinc (FILE *fp, size_t increment) + /* Keep this code in sync with freadptr! */ + #if HAVE___FREADPTRINC /* musl libc */ + __freadptrinc (fp, increment); +-#elif defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#elif defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_IO_read_ptr += increment; + #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ +diff --git a/lib/fseeko.c b/lib/fseeko.c +index d0f24d8..0ae2b15 100644 +--- a/lib/fseeko.c ++++ b/lib/fseeko.c +@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int whence) + #endif + + /* These tests are based on fpurge.c. */ +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + if (fp->_IO_read_end == fp->_IO_read_ptr + && fp->_IO_write_ptr == fp->_IO_write_base + && fp->_IO_save_base == NULL) +@@ -123,7 +123,7 @@ fseeko (FILE *fp, off_t offset, int whence) + return -1; + } + +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_flags &= ~_IO_EOF_SEEN; + fp->_offset = pos; + #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ +diff --git a/lib/fseterr.c b/lib/fseterr.c +index 739e545..d998619 100644 +--- a/lib/fseterr.c ++++ b/lib/fseterr.c +@@ -29,7 +29,7 @@ fseterr (FILE *fp) + /* Most systems provide FILE as a struct and the necessary bitmask in + , because they need it for implementing getc() and putc() as + fast macros. */ +-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ ++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ + fp->_flags |= _IO_ERR_SEEN; + #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ + /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ +diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h +index 329801a..eeaabab 100644 +--- a/lib/stdio-impl.h ++++ b/lib/stdio-impl.h +@@ -18,6 +18,12 @@ + the same implementation of stdio extension API, except that some fields + have different naming conventions, or their access requires some casts. */ + ++/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this ++ problem by defining it ourselves. FIXME: Do not rely on glibc ++ internals. */ ++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN ++# define _IO_IN_BACKUP 0x100 ++#endif + + /* BSD stdio derived implementations. */ + +-- +2.16.2 + diff --git a/coreutils.spec b/coreutils.spec index 20f7603..3464a42 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -20,6 +20,10 @@ Patch1: coreutils-8.29-mv-n-noreplace.patch # doc: warn about following symlinks recursively in chown/chgrp (CVE-2017-18018) Patch2: coreutils-8.29-CVE-2017-18018.patch +# fix build failure with glibc-2.28 +# https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html +Patch3: coreutils-8.29-gnulib-fflush.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -250,6 +254,9 @@ fi %license COPYING %changelog +* Tue Mar 06 2018 Kamil Dudka - 8.29-6 +- fix build failure with glibc-2.28 + * Mon Feb 26 2018 Igor Gnatenko - 8.29-5 - Remove /bin/* Provides From d507a7b94c56b16168f9e7cf0c53ac6524c89381 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 16 Mar 2018 18:29:04 +0100 Subject: [PATCH 370/523] Resolves: #1555079 - make sure that parse-datetime.{c,y} ends up in debuginfo --- coreutils.spec | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 3464a42..12d21cc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -169,7 +169,11 @@ for type in separate single; do --enable-no-install-program=kill,uptime \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : - make all %{?_smp_mflags}) + make all %{?_smp_mflags} + + # make sure that parse-datetime.{c,y} ends up in debuginfo (#1555079) + ln -v ../lib/parse-datetime.{c,y} . + ) done # Get the list of supported utilities @@ -254,6 +258,9 @@ fi %license COPYING %changelog +* Fri Mar 16 2018 Kamil Dudka - 8.29-7 +- make sure that parse-datetime.{c,y} ends up in debuginfo (#1555079) + * Tue Mar 06 2018 Kamil Dudka - 8.29-6 - fix build failure with glibc-2.28 From 359784bfb0e7bb2f683b53e39f80d4b96972e790 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 19 Mar 2018 19:21:04 +0100 Subject: [PATCH 371/523] Related: #1555079 - drop BR for bison ... which is not used during the build --- coreutils.spec | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 12d21cc..9d0e07d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -77,7 +77,6 @@ Conflicts: coreutils-single BuildRequires: attr BuildRequires: autoconf BuildRequires: automake -BuildRequires: bison BuildRequires: gcc BuildRequires: gettext-devel BuildRequires: gmp-devel @@ -258,6 +257,9 @@ fi %license COPYING %changelog +* Mon Mar 19 2018 Kamil Dudka - 8.29-8 +- drop BR for bison, which is not used during the build + * Fri Mar 16 2018 Kamil Dudka - 8.29-7 - make sure that parse-datetime.{c,y} ends up in debuginfo (#1555079) From 36ef66d59d08eb434daa445f484660b03170628b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 23 Mar 2018 15:29:53 +0100 Subject: [PATCH 372/523] make it possible to install the latest available Adobe Reader RPM for Linux This was recently broken by e9599c8226f2b56f4f4e9c69d6159135eea65f91. --- coreutils.spec | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 9d0e07d..042a63b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -102,6 +102,14 @@ Provides: bundled(gnulib) Provides: coreutils-full = %{version}-%{release} Obsoletes: %{name} < 8.24-100 +# make it possible to install the latest available Adobe Reader RPM for Linux +Provides: /bin/cat +Provides: /bin/chmod +Provides: /bin/echo +Provides: /bin/ln +Provides: /bin/touch +Provides: /bin/rm + %description These are the GNU core utilities. This package is the combination of the old GNU fileutils, sh-utils, and textutils packages. @@ -116,6 +124,15 @@ Conflicts: coreutils < 8.24-100 # http://rpm.org/ticket/874 so use RemovePathPostfixes # (new in rpm 4.13) to support separate file sets. RemovePathPostfixes: .single + +# make it possible to install the latest available Adobe Reader RPM for Linux +Provides: /bin/cat +Provides: /bin/chmod +Provides: /bin/echo +Provides: /bin/ln +Provides: /bin/touch +Provides: /bin/rm + %description single These are the GNU core utilities, packaged as a single multicall binary. @@ -257,6 +274,9 @@ fi %license COPYING %changelog +* Fri Mar 23 2018 Kamil Dudka - 8.29-9 +- make it possible to install the latest available Adobe Reader RPM for Linux + * Mon Mar 19 2018 Kamil Dudka - 8.29-8 - drop BR for bison, which is not used during the build From dd90a0a24b1957dec4499c7c653298966040768e Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 20 Apr 2018 17:15:43 +0200 Subject: [PATCH 373/523] Resolves: #1558249 - fix crash caused by mistakenly enabled leaf optimization --- coreutils-8.29-fts-leaf-opt.patch | 228 ++++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.29-fts-leaf-opt.patch diff --git a/coreutils-8.29-fts-leaf-opt.patch b/coreutils-8.29-fts-leaf-opt.patch new file mode 100644 index 0000000..926e5de --- /dev/null +++ b/coreutils-8.29-fts-leaf-opt.patch @@ -0,0 +1,228 @@ +From 42b0e609390e62a900c0d73de60282c8b0f15121 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 5 Apr 2018 08:48:01 -0700 +Subject: [PATCH 1/2] fts: treat CIFS like NFS + +Problem reported by Kamil Dudka in: +https://lists.gnu.org/r/bug-gnulib/2018-04/msg00015.html +* lib/fts.c (S_MAGIC_CIFS): New macro. +(dirent_inode_sort_may_be_useful, leaf_optimization): +Treat CIFS like NFS. + +Upstream-commit: 2e53df541a30d438859087ed4b5a396e04697b9b +Signed-off-by: Kamil Dudka +--- + lib/fts.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/lib/fts.c b/lib/fts.c +index 8f2595d..0689da6 100644 +--- a/lib/fts.c ++++ b/lib/fts.c +@@ -685,6 +685,7 @@ enum leaf_optimization + + /* Linux-specific constants from coreutils' src/fs.h */ + # define S_MAGIC_AFS 0x5346414F ++# define S_MAGIC_CIFS 0xFF534D42 + # define S_MAGIC_NFS 0x6969 + # define S_MAGIC_PROC 0x9FA0 + # define S_MAGIC_REISERFS 0x52654973 +@@ -792,8 +793,9 @@ dirent_inode_sort_may_be_useful (FTSENT const *p) + + switch (filesystem_type (p)) + { +- case S_MAGIC_TMPFS: ++ case S_MAGIC_CIFS: + case S_MAGIC_NFS: ++ case S_MAGIC_TMPFS: + /* On a file system of any of these types, sorting + is unnecessary, and hence wasteful. */ + return false; +@@ -827,6 +829,10 @@ leaf_optimization (FTSENT const *p) + /* Although AFS mount points are not counted in st_nlink, they + act like directories. See . */ + FALLTHROUGH; ++ case S_MAGIC_CIFS: ++ /* Leaf optimization causes 'find' to abort. See ++ . */ ++ FALLTHROUGH; + case S_MAGIC_NFS: + /* NFS provides usable dirent.d_type but not necessarily for all entries + of large directories, so as per +-- +2.14.3 + + +From bf96f62507931eb296c5b16d7e46c141ad505a1f Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Wed, 11 Apr 2018 12:50:35 -0700 +Subject: [PATCH 2/2] fts: fix bug in find across filesystems + +This fixes a bug I introduced last summer. +Problem reported by Kamil Dudka in: +https://lists.gnu.org/r/bug-gnulib/2018-04/msg00033.html +* lib/fts.c (filesystem_type, dirent_inode_sort_may_be_useful) +(leaf_optimization): +New arg for file descriptor. All callers changed. +(fts_build): Check for whether inodes should be sorted +before closing the directory. + +Upstream-commit: 81b8c0d3be98f5a77403599de3d06329b3e7673e +Signed-off-by: Kamil Dudka +--- + lib/fts.c | 55 +++++++++++++++++++++++++++++++------------------------ + 1 file changed, 31 insertions(+), 24 deletions(-) + +diff --git a/lib/fts.c b/lib/fts.c +index 0689da6..6420ba1 100644 +--- a/lib/fts.c ++++ b/lib/fts.c +@@ -726,11 +726,12 @@ dev_type_compare (void const *x, void const *y) + return ax->st_dev == ay->st_dev; + } + +-/* Return the file system type of P, or 0 if not known. ++/* Return the file system type of P with file descriptor FD, or 0 if not known. ++ If FD is negative, P's file descriptor is unavailable. + Try to cache known values. */ + + static fsword +-filesystem_type (FTSENT const *p) ++filesystem_type (FTSENT const *p, int fd) + { + FTS *sp = p->fts_fts; + Hash_table *h = sp->fts_leaf_optimization_works_ht; +@@ -756,7 +757,7 @@ filesystem_type (FTSENT const *p) + } + + /* Look-up failed. Query directly and cache the result. */ +- if (fstatfs (p->fts_fts->fts_cwd_fd, &fs_buf) != 0) ++ if (fd < 0 || fstatfs (fd, &fs_buf) != 0) + return 0; + + if (h) +@@ -778,12 +779,12 @@ filesystem_type (FTSENT const *p) + return fs_buf.f_type; + } + +-/* Return false if it is easy to determine the file system type of the +- directory P, and sorting dirents on inode numbers is known not to +- improve traversal performance with that type of file system. +- Otherwise, return true. */ ++/* Return true if sorting dirents on inode numbers is known to improve ++ traversal performance for the directory P with descriptor DIR_FD. ++ Return false otherwise. When in doubt, return true. ++ DIR_FD is negative if unavailable. */ + static bool +-dirent_inode_sort_may_be_useful (FTSENT const *p) ++dirent_inode_sort_may_be_useful (FTSENT const *p, int dir_fd) + { + /* Skip the sort only if we can determine efficiently + that skipping it is the right thing to do. +@@ -791,7 +792,7 @@ dirent_inode_sort_may_be_useful (FTSENT const *p) + while the cost of *not* performing it can be O(N^2) with + a very large constant. */ + +- switch (filesystem_type (p)) ++ switch (filesystem_type (p, dir_fd)) + { + case S_MAGIC_CIFS: + case S_MAGIC_NFS: +@@ -805,16 +806,17 @@ dirent_inode_sort_may_be_useful (FTSENT const *p) + } + } + +-/* Given an FTS entry P for a directory D, ++/* Given an FTS entry P for a directory with descriptor DIR_FD, + return true if it is both useful and valid to apply leaf optimization. + The optimization is useful only for file systems that lack usable + dirent.d_type info. The optimization is valid if an st_nlink value + of at least MIN_DIR_NLINK is an upper bound on the number of +- subdirectories of D, counting "." and ".." as subdirectories. */ ++ subdirectories of D, counting "." and ".." as subdirectories. ++ DIR_FD is negative if unavailable. */ + static enum leaf_optimization +-leaf_optimization (FTSENT const *p) ++leaf_optimization (FTSENT const *p, int dir_fd) + { +- switch (filesystem_type (p)) ++ switch (filesystem_type (p, dir_fd)) + { + /* List here the file system types that may lack usable dirent.d_type + info, yet for which the optimization does apply. */ +@@ -851,12 +853,13 @@ leaf_optimization (FTSENT const *p) + + #else + static bool +-dirent_inode_sort_may_be_useful (FTSENT const *p _GL_UNUSED) ++dirent_inode_sort_may_be_useful (FTSENT const *p _GL_UNUSED, ++ int dir_fd _GL_UNUSED) + { + return true; + } + static enum leaf_optimization +-leaf_optimization (FTSENT const *p _GL_UNUSED) ++leaf_optimization (FTSENT const *p _GL_UNUSED, int dir_fd _GL_UNUSED) + { + return NO_LEAF_OPTIMIZATION; + } +@@ -1050,7 +1053,7 @@ check_for_dir: + if (parent->fts_n_dirs_remaining == 0 + && ISSET(FTS_NOSTAT) + && ISSET(FTS_PHYSICAL) +- && (leaf_optimization (parent) ++ && (leaf_optimization (parent, sp->fts_cwd_fd) + == NOSTAT_LEAF_OPTIMIZATION)) + { + /* nothing more needed */ +@@ -1335,6 +1338,7 @@ fts_build (register FTS *sp, int type) + int dir_fd; + FTSENT *cur = sp->fts_cur; + bool continue_readdir = !!cur->fts_dirp; ++ bool sort_by_inode = false; + size_t max_entries; + + /* When cur->fts_dirp is non-NULL, that means we should +@@ -1428,7 +1432,7 @@ fts_build (register FTS *sp, int type) + && ! (ISSET (FTS_NOSTAT) && ISSET (FTS_PHYSICAL) + && ! ISSET (FTS_SEEDOT) + && cur->fts_statp->st_nlink == MIN_DIR_NLINK +- && (leaf_optimization (cur) ++ && (leaf_optimization (cur, dir_fd) + != NO_LEAF_OPTIMIZATION))); + if (descend || type == BREAD) + { +@@ -1589,6 +1593,15 @@ mem1: saved_errno = errno; + tail->fts_link = p; + tail = p; + } ++ ++ /* If there are many entries, no sorting function has been ++ specified, and this file system is of a type that may be ++ slow with a large number of entries, arrange to sort the ++ directory entries on increasing inode numbers. */ ++ if (nitems == _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD ++ && !sp->fts_compar) ++ sort_by_inode = dirent_inode_sort_may_be_useful (cur, dir_fd); ++ + ++nitems; + if (max_entries <= nitems) { + /* When there are too many dir entries, leave +@@ -1646,13 +1659,7 @@ mem1: saved_errno = errno; + return (NULL); + } + +- /* If there are many entries, no sorting function has been specified, +- and this file system is of a type that may be slow with a large +- number of entries, then sort the directory entries on increasing +- inode numbers. */ +- if (nitems > _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD +- && !sp->fts_compar +- && dirent_inode_sort_may_be_useful (cur)) { ++ if (sort_by_inode) { + sp->fts_compar = fts_compare_ino; + head = fts_sort (sp, head, nitems); + sp->fts_compar = NULL; +-- +2.14.3 + diff --git a/coreutils.spec b/coreutils.spec index 042a63b..b7375b8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -24,6 +24,9 @@ Patch2: coreutils-8.29-CVE-2017-18018.patch # https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html Patch3: coreutils-8.29-gnulib-fflush.patch +# fix crash caused by mistakenly enabled leaf optimization (#1558249) +Patch4: coreutils-8.29-fts-leaf-opt.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -274,6 +277,9 @@ fi %license COPYING %changelog +* Fri Apr 20 2018 Kamil Dudka - 8.29-10 +- fix crash caused by mistakenly enabled leaf optimization (#1558249) + * Fri Mar 23 2018 Kamil Dudka - 8.29-9 - make it possible to install the latest available Adobe Reader RPM for Linux From 79b09b54dfbb7f12c5bfe8459c405aeb5c98accf Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 28 May 2018 17:42:55 +0200 Subject: [PATCH 374/523] Resolves: #1577872 - date, ls: pick strftime fixes from glibc to improve locale support --- coreutils-8.29-gnulib-strftime.patch | 101 +++++++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.29-gnulib-strftime.patch diff --git a/coreutils-8.29-gnulib-strftime.patch b/coreutils-8.29-gnulib-strftime.patch new file mode 100644 index 0000000..b982344 --- /dev/null +++ b/coreutils-8.29-gnulib-strftime.patch @@ -0,0 +1,101 @@ +From 67defe5a29936c20a2c102b1b947ce9ea9afc081 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Tue, 23 Jan 2018 00:42:04 -0800 +Subject: [PATCH] Merge strftime.c changes from glibc + +This incorporates: +2017-11-14 [BZ #10871] Implement alternative month names +2017-11-14 [BZ #10871] Abbreviated alternative month names (%Ob) +2017-06-20 Use locale_t, not __locale_t, throughout glibc +* lib/nstrftime.c (ABALTMON_1) [!COMPILE_WIDE]: New macro. +(LOCALE_PARAM) [_LIBC && USE_IN_EXTENDED_LOCALE_MODEL]: +Use locale_t, not __locale_t. +(a_altmonth, f_altmonth, aam_len) [_NL_CURRENT]: New macros. +(__strftime_internal): Add support for alternate months. + +Upstream-commit: 4a236f16ce0ef97094ff2f6538d4dba90e72a523 +Signed-off-by: Kamil Dudka +--- + lib/nstrftime.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/lib/nstrftime.c b/lib/nstrftime.c +index 8795cd7..5902c49 100644 +--- a/lib/nstrftime.c ++++ b/lib/nstrftime.c +@@ -91,6 +91,7 @@ extern char *tzname[]; + # define UCHAR_T unsigned char + # define L_(Str) Str + # define NLW(Sym) Sym ++# define ABALTMON_1 _NL_ABALTMON_1 + + # define MEMCPY(d, s, n) memcpy (d, s, n) + # define STRLEN(s) strlen (s) +@@ -255,7 +256,7 @@ extern char *tzname[]; + # undef _NL_CURRENT + # define _NL_CURRENT(category, item) \ + (current->values[_NL_ITEM_INDEX (item)].string) +-# define LOCALE_PARAM , __locale_t loc ++# define LOCALE_PARAM , locale_t loc + # define LOCALE_ARG , loc + # define HELPER_LOCALE_ARG , current + #else +@@ -475,12 +476,19 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) + # define f_month \ + ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ + ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))) ++# define a_altmonth \ ++ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABALTMON_1) + tp->tm_mon))) ++# define f_altmonth \ ++ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(ALTMON_1) + tp->tm_mon))) + # define ampm \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ + ? NLW(PM_STR) : NLW(AM_STR))) + + # define aw_len STRLEN (a_wkday) + # define am_len STRLEN (a_month) ++# define aam_len STRLEN (a_altmonth) + # define ap_len STRLEN (ampm) + #endif + #if HAVE_TZNAME +@@ -808,17 +816,20 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) + to_uppcase = true; + to_lowcase = false; + } +- if (modifier != 0) ++ if (modifier == L_('E')) + goto bad_format; + #ifdef _NL_CURRENT +- cpy (am_len, a_month); ++ if (modifier == L_('O')) ++ cpy (aam_len, a_altmonth); ++ else ++ cpy (am_len, a_month); + break; + #else + goto underlying_strftime; + #endif + + case L_('B'): +- if (modifier != 0) ++ if (modifier == L_('E')) + goto bad_format; + if (change_case) + { +@@ -826,7 +837,10 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) + to_lowcase = false; + } + #ifdef _NL_CURRENT +- cpy (STRLEN (f_month), f_month); ++ if (modifier == L_('O')) ++ cpy (STRLEN (f_altmonth), f_altmonth); ++ else ++ cpy (STRLEN (f_month), f_month); + break; + #else + goto underlying_strftime; +-- +2.14.3 + diff --git a/coreutils.spec b/coreutils.spec index b7375b8..61611fc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -27,6 +27,9 @@ Patch3: coreutils-8.29-gnulib-fflush.patch # fix crash caused by mistakenly enabled leaf optimization (#1558249) Patch4: coreutils-8.29-fts-leaf-opt.patch +# date, ls: pick strftime fixes from glibc to improve locale support (#1577872) +Patch5: coreutils-8.29-gnulib-strftime.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -277,6 +280,9 @@ fi %license COPYING %changelog +* Mon May 28 2018 Kamil Dudka - 8.29-11 +- date, ls: pick strftime fixes from glibc to improve locale support (#1577872) + * Fri Apr 20 2018 Kamil Dudka - 8.29-10 - fix crash caused by mistakenly enabled leaf optimization (#1558249) From 44ebc669353b5fe5b8a419ec71efc6c9b8d03685 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 29 May 2018 17:02:58 +0200 Subject: [PATCH 375/523] Resolves: #1577872 - ls: increase the allowed abmon width from 5 to 12 --- coreutils-8.29-ls-abmon-width.patch | 69 +++++++++++++++++++++++++++++ coreutils.spec | 4 ++ 2 files changed, 73 insertions(+) create mode 100644 coreutils-8.29-ls-abmon-width.patch diff --git a/coreutils-8.29-ls-abmon-width.patch b/coreutils-8.29-ls-abmon-width.patch new file mode 100644 index 0000000..1022f01 --- /dev/null +++ b/coreutils-8.29-ls-abmon-width.patch @@ -0,0 +1,69 @@ +From 5a820c5a312d6a5b7a1a755cd0f81c84f7c676d7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Wed, 14 Mar 2018 11:31:43 -0700 +Subject: [PATCH] ls: increase the allowed abmon width from 5 to 12 + +This will impact relatively few languages, +and will make Arabic or Catalan etc. +output unambiguous abbreviated month names. + +* src/ls.c (MAX_MON_WIDTH): Increase from 5 to 12. +* tests/ls/abmon-align.sh: Augment to check for ambiguous output. +Fixes https://bugs.gnu.org/30814 + +Upstream-commit: 5ed2018360ba44f673b1dc74fb3d2927f7fcfae3 +Signed-off-by: Kamil Dudka +--- + src/ls.c | 7 +++++-- + tests/ls/abmon-align.sh | 9 ++++++--- + 2 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/src/ls.c b/src/ls.c +index 4becd06..b2983aa 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -1095,8 +1095,11 @@ file_escape_init (void) + variable width abbreviated months and also precomputing/caching + the names was seen to increase the performance of ls significantly. */ + +-/* max number of display cells to use */ +-enum { MAX_MON_WIDTH = 5 }; ++/* max number of display cells to use. ++ As of 2018 the abmon for Arabic has entries with width 12. ++ It doesn't make much sense to support wider than this ++ and locales should aim for abmon entries of width <= 5. */ ++enum { MAX_MON_WIDTH = 12 }; + /* abformat[RECENT][MON] is the format to use for timestamps with + recentness RECENT and month MON. */ + enum { ABFORMAT_SIZE = 128 }; +diff --git a/tests/ls/abmon-align.sh b/tests/ls/abmon-align.sh +index e474047..a81266b 100755 +--- a/tests/ls/abmon-align.sh ++++ b/tests/ls/abmon-align.sh +@@ -32,17 +32,20 @@ for format in "%b" "[%b" "%b]" "[%b]"; do + # The sed usage here is slightly different from the original, + # removing the \(.*\), to avoid triggering misbehavior in at least + # GNU sed 4.2 (possibly miscompiled) on Mac OS X (Darwin 9.8.0). +- n_widths=$( ++ months="$( + LC_ALL=$LOC TIME_STYLE=+"$format" ls -lgG *.ts | +- LC_ALL=C sed 's/.\{15\}//;s/ ..\.ts$//;s/ /./g' | ++ LC_ALL=C sed 's/.\{15\}//;s/ ..\.ts$//;s/ /./g')" ++ n_widths=$(echo "$months" | + while read mon; do echo "$mon" | LC_ALL=$LOC wc -L; done | + uniq | wc -l + ) ++ n_dupes=$(echo "$months" | sort | uniq -d | wc -l) + test "$n_widths" = "1" || { fail=1; break 2; } ++ test "$n_dupes" = "0" || { fail=1; break 2; } + done + done + if test "$fail" = "1"; then +- echo "misalignment detected in $LOC locale:" ++ echo "misalignment or ambiguous output in $LOC locale:" + LC_ALL=$LOC TIME_STYLE=+%b ls -lgG *.ts + fi + +-- +2.14.3 + diff --git a/coreutils.spec b/coreutils.spec index 61611fc..28c8f2e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -30,6 +30,9 @@ Patch4: coreutils-8.29-fts-leaf-opt.patch # date, ls: pick strftime fixes from glibc to improve locale support (#1577872) Patch5: coreutils-8.29-gnulib-strftime.patch +# ls: increase the allowed abmon width from 5 to 12 (#1577872) +Patch6: coreutils-8.29-ls-abmon-width.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -281,6 +284,7 @@ fi %changelog * Mon May 28 2018 Kamil Dudka - 8.29-11 +- ls: increase the allowed abmon width from 5 to 12 (#1577872) - date, ls: pick strftime fixes from glibc to improve locale support (#1577872) * Fri Apr 20 2018 Kamil Dudka - 8.29-10 From d83775a947e08f5fa50e3dfca736716f05c6db50 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 29 May 2018 17:56:23 +0200 Subject: [PATCH 376/523] coreutils-8.29-ls-abmon-width.patch: temporarily disable the check ... because it does not work today (May 29th) as reported upstream: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=31644 --- coreutils-8.29-ls-abmon-width.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-8.29-ls-abmon-width.patch b/coreutils-8.29-ls-abmon-width.patch index 1022f01..27b8f4c 100644 --- a/coreutils-8.29-ls-abmon-width.patch +++ b/coreutils-8.29-ls-abmon-width.patch @@ -55,7 +55,7 @@ index e474047..a81266b 100755 ) + n_dupes=$(echo "$months" | sort | uniq -d | wc -l) test "$n_widths" = "1" || { fail=1; break 2; } -+ test "$n_dupes" = "0" || { fail=1; break 2; } ++ #test "$n_dupes" = "0" || { fail=1; break 2; } done done if test "$fail" = "1"; then From d01deda0a24895d2e39e226e9dae828b40dda082 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 30 May 2018 09:22:08 +0200 Subject: [PATCH 377/523] coreutils-8.29-ls-abmon-width.patch: use upstream fix for the test --- coreutils-8.29-ls-abmon-width.patch | 39 +++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/coreutils-8.29-ls-abmon-width.patch b/coreutils-8.29-ls-abmon-width.patch index 27b8f4c..52aef28 100644 --- a/coreutils-8.29-ls-abmon-width.patch +++ b/coreutils-8.29-ls-abmon-width.patch @@ -1,7 +1,7 @@ From 5a820c5a312d6a5b7a1a755cd0f81c84f7c676d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Wed, 14 Mar 2018 11:31:43 -0700 -Subject: [PATCH] ls: increase the allowed abmon width from 5 to 12 +Subject: [PATCH 1/2] ls: increase the allowed abmon width from 5 to 12 This will impact relatively few languages, and will make Arabic or Catalan etc. @@ -55,7 +55,7 @@ index e474047..a81266b 100755 ) + n_dupes=$(echo "$months" | sort | uniq -d | wc -l) test "$n_widths" = "1" || { fail=1; break 2; } -+ #test "$n_dupes" = "0" || { fail=1; break 2; } ++ test "$n_dupes" = "0" || { fail=1; break 2; } done done if test "$fail" = "1"; then @@ -67,3 +67,38 @@ index e474047..a81266b 100755 -- 2.14.3 + +From 58196889eb9621a0bc8a97d7eda1174efb1b078c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Tue, 29 May 2018 10:10:35 -0700 +Subject: [PATCH 2/2] tests: fix periodic false failure in month alignment + +* tests/ls/abmon-align.sh: Base relative month adjustment +from the middle of the month, to avoid failures due +to months being repeated. +Fixes https://bugs.gnu.org/31644 + +Upstream-commit: c8eb21c9c0ba00559afc5e0d200085ac656396e0 +Signed-off-by: Kamil Dudka +--- + tests/ls/abmon-align.sh | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tests/ls/abmon-align.sh b/tests/ls/abmon-align.sh +index a81266b..8bd20ae 100755 +--- a/tests/ls/abmon-align.sh ++++ b/tests/ls/abmon-align.sh +@@ -19,8 +19,9 @@ + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ ls + ++mid_month="$(date +%Y-%m-15)" || framework_failure_ + for mon in $(seq -w 12); do +- touch -d"+$mon month" $mon.ts || framework_failure_ ++ touch -d"$mid_month +$mon month" $mon.ts || framework_failure_ + done + + +-- +2.14.3 + From a38fffab2a2e29113dca8bdae70179d1e6ee4a14 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 30 May 2018 09:37:32 +0200 Subject: [PATCH 378/523] add provides to coreutils-single to make it a drop-in replacement --- coreutils-provides.inc | 9 +++++++++ coreutils.spec | 27 ++++++++------------------- 2 files changed, 17 insertions(+), 19 deletions(-) create mode 100644 coreutils-provides.inc diff --git a/coreutils-provides.inc b/coreutils-provides.inc new file mode 100644 index 0000000..026f8c3 --- /dev/null +++ b/coreutils-provides.inc @@ -0,0 +1,9 @@ +Provides: bundled(gnulib) + +# make it possible to install the latest available Adobe Reader RPM for Linux +Provides: /bin/cat +Provides: /bin/chmod +Provides: /bin/echo +Provides: /bin/ln +Provides: /bin/touch +Provides: /bin/rm diff --git a/coreutils.spec b/coreutils.spec index 28c8f2e..b5f47b3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,12 +1,13 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.29 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source50: supported_utils +Source51: coreutils-provides.inc Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh @@ -107,18 +108,10 @@ BuildRequires: glibc-langpack-en Requires: %{name}-common = %{version}-%{release} Requires: ncurses -Provides: bundled(gnulib) Provides: coreutils-full = %{version}-%{release} +%include %{SOURCE51} Obsoletes: %{name} < 8.24-100 -# make it possible to install the latest available Adobe Reader RPM for Linux -Provides: /bin/cat -Provides: /bin/chmod -Provides: /bin/echo -Provides: /bin/ln -Provides: /bin/touch -Provides: /bin/rm - %description These are the GNU core utilities. This package is the combination of the old GNU fileutils, sh-utils, and textutils packages. @@ -127,21 +120,14 @@ the old GNU fileutils, sh-utils, and textutils packages. Summary: coreutils multicall binary Suggests: coreutils-common Provides: coreutils = %{version}-%{release} +Provides: coreutils%{?_isa} = %{version}-%{release} +%include %{SOURCE51} # To avoid clobbering installs Conflicts: coreutils < 8.24-100 # Note RPM doesn't support separate buildroots for %files # http://rpm.org/ticket/874 so use RemovePathPostfixes # (new in rpm 4.13) to support separate file sets. RemovePathPostfixes: .single - -# make it possible to install the latest available Adobe Reader RPM for Linux -Provides: /bin/cat -Provides: /bin/chmod -Provides: /bin/echo -Provides: /bin/ln -Provides: /bin/touch -Provides: /bin/rm - %description single These are the GNU core utilities, packaged as a single multicall binary. @@ -283,6 +269,9 @@ fi %license COPYING %changelog +* Wed May 30 2018 Kamil Dudka - 8.29-12 +- add provides to coreutils-single to make it a drop-in replacement + * Mon May 28 2018 Kamil Dudka - 8.29-11 - ls: increase the allowed abmon width from 5 to 12 (#1577872) - date, ls: pick strftime fixes from glibc to improve locale support (#1577872) From 868a615b18c8faae29fd79e442bb31f7471a50bd Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 30 May 2018 09:46:27 +0200 Subject: [PATCH 379/523] coreutils-provides.inc: sort the list alphabetically --- coreutils-provides.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-provides.inc b/coreutils-provides.inc index 026f8c3..8314a4e 100644 --- a/coreutils-provides.inc +++ b/coreutils-provides.inc @@ -5,5 +5,5 @@ Provides: /bin/cat Provides: /bin/chmod Provides: /bin/echo Provides: /bin/ln -Provides: /bin/touch Provides: /bin/rm +Provides: /bin/touch From cf6dd7194c42138362a4c117ea64c3d65ac4ade7 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 2 Jul 2018 11:41:17 +0200 Subject: [PATCH 380/523] new upstream release 8.30 --- coreutils-6.10-manpages.patch | 10 +- coreutils-8.25-DIR_COLORS.patch | 22 +-- coreutils-8.29-CVE-2017-18018.patch | 124 --------------- coreutils-8.29-fts-leaf-opt.patch | 228 --------------------------- coreutils-8.29-gnulib-fflush.patch | 202 ------------------------ coreutils-8.29-gnulib-strftime.patch | 101 ------------ coreutils-8.29-ls-abmon-width.patch | 104 ------------ coreutils-8.29-mv-n-noreplace.patch | 63 -------- coreutils-8.29.tar.xz.sig | 16 -- coreutils-8.30.tar.xz.sig | 17 ++ coreutils-i18n-cut-old.patch | 2 +- coreutils.spec | 27 +--- sources | 2 +- 13 files changed, 37 insertions(+), 881 deletions(-) delete mode 100644 coreutils-8.29-CVE-2017-18018.patch delete mode 100644 coreutils-8.29-fts-leaf-opt.patch delete mode 100644 coreutils-8.29-gnulib-fflush.patch delete mode 100644 coreutils-8.29-gnulib-strftime.patch delete mode 100644 coreutils-8.29-ls-abmon-width.patch delete mode 100644 coreutils-8.29-mv-n-noreplace.patch delete mode 100644 coreutils-8.29.tar.xz.sig create mode 100644 coreutils-8.30.tar.xz.sig diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch index 5f8bdb2..5aacff7 100644 --- a/coreutils-6.10-manpages.patch +++ b/coreutils-6.10-manpages.patch @@ -2,13 +2,13 @@ diff --git a/src/md5sum.c b/src/md5sum.c index 8e21609..a857d62 100644 --- a/src/md5sum.c +++ b/src/md5sum.c -@@ -266,6 +266,9 @@ Print or check %s (%d-bit) checksums.\n\ +@@ -265,6 +265,9 @@ Print or check %s (%d-bit) checksums.\n\ + else fputs (_("\ -t, --text read in text mode (default)\n\ - "), stdout); ++"), stdout); + fputs (_("\ + Note: There is no difference between binary and text mode option on GNU system.\n\ -+"), stdout); + "), stdout); fputs (_("\ - \n\ - The following five options are useful only when verifying checksums:\n\ + -z, --zero end each output line with NUL, not newline,\n\ diff --git a/coreutils-8.25-DIR_COLORS.patch b/coreutils-8.25-DIR_COLORS.patch index 94923b0..5490258 100644 --- a/coreutils-8.25-DIR_COLORS.patch +++ b/coreutils-8.25-DIR_COLORS.patch @@ -5,9 +5,9 @@ Subject: [PATCH] downstream changes to default DIR_COLORS --- DIR_COLORS | 41 ++++--- - DIR_COLORS.256color | 302 ++++++++++++++++++++++++------------------------ - DIR_COLORS.lightbgcolor | 215 +++++++++++++++++----------------- - 3 files changed, 286 insertions(+), 272 deletions(-) + DIR_COLORS.256color | 300 ++++++++++++++++++++++++------------------------ + DIR_COLORS.lightbgcolor | 211 ++++++++++++++++++---------------- + 3 files changed, 283 insertions(+), 269 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS index d2ea453..27af9d7 100644 @@ -21,7 +21,7 @@ index d2ea453..27af9d7 100644 +# You can copy this file to .dir_colors in your $HOME directory to override +# the system defaults. + - # Copyright (C) 1996-2017 Free Software Foundation, Inc. + # Copyright (C) 1996-2018 Free Software Foundation, Inc. # Copying and distribution of this file, with or without modification, # are permitted provided the copyright notice and this notice are preserved. @@ -8,6 +12,9 @@ @@ -43,7 +43,7 @@ index d2ea453..27af9d7 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -185,21 +192,21 @@ EXEC 01;32 +@@ -184,21 +191,21 @@ EXEC 01;32 .ogx 01;35 # audio formats @@ -190,7 +190,7 @@ index d2ea453..74c34ba 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -83,123 +81,123 @@ EXEC 01;32 +@@ -83,122 +81,122 @@ EXEC 01;32 #.csh 01;32 # archives or compressed (bright red) @@ -209,7 +209,6 @@ index d2ea453..74c34ba 100644 -.t7z 01;31 -.zip 01;31 -.z 01;31 --.Z 01;31 -.dz 01;31 -.gz 01;31 -.lrz 01;31 @@ -256,7 +255,6 @@ index d2ea453..74c34ba 100644 +.t7z 38;5;9 +.zip 38;5;9 +.z 38;5;9 -+.Z 38;5;9 +.dz 38;5;9 +.gz 38;5;9 +.lrz 38;5;9 @@ -482,11 +480,10 @@ index d2ea453..95d6879 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -82,107 +91,107 @@ EXEC 01;32 - #.sh 01;32 +@@ -83,105 +92,105 @@ EXEC 01;32 #.csh 01;32 -- # archives or compressed (bright red) + # archives or compressed (bright red) -.tar 01;31 -.tgz 01;31 -.arc 01;31 @@ -502,7 +499,6 @@ index d2ea453..95d6879 100644 -.t7z 01;31 -.zip 01;31 -.z 01;31 --.Z 01;31 -.dz 01;31 -.gz 01;31 -.lrz 01;31 @@ -534,7 +530,6 @@ index d2ea453..95d6879 100644 -.swm 01;31 -.dwm 01;31 -.esd 01;31 -+# archives or compressed (red) +.tar 00;31 +.tgz 00;31 +.arc 00;31 @@ -550,7 +545,6 @@ index d2ea453..95d6879 100644 +.t7z 00;31 +.zip 00;31 +.z 00;31 -+.Z 00;31 +.dz 00;31 +.gz 00;31 +.lrz 00;31 diff --git a/coreutils-8.29-CVE-2017-18018.patch b/coreutils-8.29-CVE-2017-18018.patch deleted file mode 100644 index 577c90b..0000000 --- a/coreutils-8.29-CVE-2017-18018.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 0aa9b0a92cb61af76b75b57abfd6ea1a7c627367 Mon Sep 17 00:00:00 2001 -From: Michael Orlitzky -Date: Thu, 28 Dec 2017 15:52:42 -0500 -Subject: [PATCH 1/2] doc: clarify chown/chgrp --dereference defaults - -* doc/coreutils.texi: the documentation for the --dereference - flag of chown/chgrp states that it is the default mode of - operation. Document that this is only the case when operating - non-recursively. - -Upstream-commit: 7597cfa482e42a00a69fb9577ee523762980a9a2 -Signed-off-by: Kamil Dudka ---- - doc/coreutils.texi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index de1f2eb..de06c0f 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -10989,7 +10989,7 @@ chown -h -R --from=OLDUSER NEWUSER / - @cindex symbolic links, changing owner - @findex lchown - Do not act on symbolic links themselves but rather on what they point to. --This is the default. -+This is the default when not operating recursively. - - @item -h - @itemx --no-dereference -@@ -11119,7 +11119,7 @@ changed. - @cindex symbolic links, changing owner - @findex lchown - Do not act on symbolic links themselves but rather on what they point to. --This is the default. -+This is the default when not operating recursively. - - @item -h - @itemx --no-dereference --- -2.13.6 - - -From 3fb331864c718e065804049001b573ff94810772 Mon Sep 17 00:00:00 2001 -From: Michael Orlitzky -Date: Thu, 4 Jan 2018 11:38:21 -0500 -Subject: [PATCH 2/2] doc: warn about following symlinks recursively in - chown/chgrp - -In both chown and chgrp (which shares its code with chown), operating -on symlinks recursively has a window of vulnerability where the -destination user or group can change the target of the operation. -Warn about combining the --dereference, --recursive, and -L flags. - -* doc/coreutils.texi (warnOptDerefWithRec): Add macro. -(node chown invocation): Add it to --dereference and -L. -(node chgrp invocation): Likewise. - -See also: CVE-2017-18018 - -Upstream-commit: bc2fd9796403e03bb757b064d44c22fab92e6842 -Signed-off-by: Kamil Dudka ---- - doc/coreutils.texi | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index de06c0f..24cc85b 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -1428,6 +1428,19 @@ a command line argument is a symbolic link to a directory, traverse it. - In a recursive traversal, traverse every symbolic link to a directory - that is encountered. - @end macro -+ -+@c Append the following warning to -L where appropriate (e.g. chown). -+@macro warnOptDerefWithRec -+ -+Combining this dereferencing option with the @option{--recursive} option -+may create a security risk: -+During the traversal of the directory tree, an attacker may be able to -+introduce a symlink to an arbitrary target; when the tool reaches that, -+the operation will be performed on the target of that symlink, -+possibly allowing the attacker to escalate privileges. -+ -+@end macro -+ - @choptL - - @macro choptP -@@ -10990,6 +11003,7 @@ chown -h -R --from=OLDUSER NEWUSER / - @findex lchown - Do not act on symbolic links themselves but rather on what they point to. - This is the default when not operating recursively. -+@warnOptDerefWithRec - - @item -h - @itemx --no-dereference -@@ -11046,6 +11060,7 @@ Recursively change ownership of directories and their contents. - @xref{Traversing symlinks}. - - @choptL -+@warnOptDerefWithRec - @xref{Traversing symlinks}. - - @choptP -@@ -11120,6 +11135,7 @@ changed. - @findex lchown - Do not act on symbolic links themselves but rather on what they point to. - This is the default when not operating recursively. -+@warnOptDerefWithRec - - @item -h - @itemx --no-dereference -@@ -11175,6 +11191,7 @@ Recursively change the group ownership of directories and their contents. - @xref{Traversing symlinks}. - - @choptL -+@warnOptDerefWithRec - @xref{Traversing symlinks}. - - @choptP --- -2.13.6 - diff --git a/coreutils-8.29-fts-leaf-opt.patch b/coreutils-8.29-fts-leaf-opt.patch deleted file mode 100644 index 926e5de..0000000 --- a/coreutils-8.29-fts-leaf-opt.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 42b0e609390e62a900c0d73de60282c8b0f15121 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 5 Apr 2018 08:48:01 -0700 -Subject: [PATCH 1/2] fts: treat CIFS like NFS - -Problem reported by Kamil Dudka in: -https://lists.gnu.org/r/bug-gnulib/2018-04/msg00015.html -* lib/fts.c (S_MAGIC_CIFS): New macro. -(dirent_inode_sort_may_be_useful, leaf_optimization): -Treat CIFS like NFS. - -Upstream-commit: 2e53df541a30d438859087ed4b5a396e04697b9b -Signed-off-by: Kamil Dudka ---- - lib/fts.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/lib/fts.c b/lib/fts.c -index 8f2595d..0689da6 100644 ---- a/lib/fts.c -+++ b/lib/fts.c -@@ -685,6 +685,7 @@ enum leaf_optimization - - /* Linux-specific constants from coreutils' src/fs.h */ - # define S_MAGIC_AFS 0x5346414F -+# define S_MAGIC_CIFS 0xFF534D42 - # define S_MAGIC_NFS 0x6969 - # define S_MAGIC_PROC 0x9FA0 - # define S_MAGIC_REISERFS 0x52654973 -@@ -792,8 +793,9 @@ dirent_inode_sort_may_be_useful (FTSENT const *p) - - switch (filesystem_type (p)) - { -- case S_MAGIC_TMPFS: -+ case S_MAGIC_CIFS: - case S_MAGIC_NFS: -+ case S_MAGIC_TMPFS: - /* On a file system of any of these types, sorting - is unnecessary, and hence wasteful. */ - return false; -@@ -827,6 +829,10 @@ leaf_optimization (FTSENT const *p) - /* Although AFS mount points are not counted in st_nlink, they - act like directories. See . */ - FALLTHROUGH; -+ case S_MAGIC_CIFS: -+ /* Leaf optimization causes 'find' to abort. See -+ . */ -+ FALLTHROUGH; - case S_MAGIC_NFS: - /* NFS provides usable dirent.d_type but not necessarily for all entries - of large directories, so as per --- -2.14.3 - - -From bf96f62507931eb296c5b16d7e46c141ad505a1f Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Wed, 11 Apr 2018 12:50:35 -0700 -Subject: [PATCH 2/2] fts: fix bug in find across filesystems - -This fixes a bug I introduced last summer. -Problem reported by Kamil Dudka in: -https://lists.gnu.org/r/bug-gnulib/2018-04/msg00033.html -* lib/fts.c (filesystem_type, dirent_inode_sort_may_be_useful) -(leaf_optimization): -New arg for file descriptor. All callers changed. -(fts_build): Check for whether inodes should be sorted -before closing the directory. - -Upstream-commit: 81b8c0d3be98f5a77403599de3d06329b3e7673e -Signed-off-by: Kamil Dudka ---- - lib/fts.c | 55 +++++++++++++++++++++++++++++++------------------------ - 1 file changed, 31 insertions(+), 24 deletions(-) - -diff --git a/lib/fts.c b/lib/fts.c -index 0689da6..6420ba1 100644 ---- a/lib/fts.c -+++ b/lib/fts.c -@@ -726,11 +726,12 @@ dev_type_compare (void const *x, void const *y) - return ax->st_dev == ay->st_dev; - } - --/* Return the file system type of P, or 0 if not known. -+/* Return the file system type of P with file descriptor FD, or 0 if not known. -+ If FD is negative, P's file descriptor is unavailable. - Try to cache known values. */ - - static fsword --filesystem_type (FTSENT const *p) -+filesystem_type (FTSENT const *p, int fd) - { - FTS *sp = p->fts_fts; - Hash_table *h = sp->fts_leaf_optimization_works_ht; -@@ -756,7 +757,7 @@ filesystem_type (FTSENT const *p) - } - - /* Look-up failed. Query directly and cache the result. */ -- if (fstatfs (p->fts_fts->fts_cwd_fd, &fs_buf) != 0) -+ if (fd < 0 || fstatfs (fd, &fs_buf) != 0) - return 0; - - if (h) -@@ -778,12 +779,12 @@ filesystem_type (FTSENT const *p) - return fs_buf.f_type; - } - --/* Return false if it is easy to determine the file system type of the -- directory P, and sorting dirents on inode numbers is known not to -- improve traversal performance with that type of file system. -- Otherwise, return true. */ -+/* Return true if sorting dirents on inode numbers is known to improve -+ traversal performance for the directory P with descriptor DIR_FD. -+ Return false otherwise. When in doubt, return true. -+ DIR_FD is negative if unavailable. */ - static bool --dirent_inode_sort_may_be_useful (FTSENT const *p) -+dirent_inode_sort_may_be_useful (FTSENT const *p, int dir_fd) - { - /* Skip the sort only if we can determine efficiently - that skipping it is the right thing to do. -@@ -791,7 +792,7 @@ dirent_inode_sort_may_be_useful (FTSENT const *p) - while the cost of *not* performing it can be O(N^2) with - a very large constant. */ - -- switch (filesystem_type (p)) -+ switch (filesystem_type (p, dir_fd)) - { - case S_MAGIC_CIFS: - case S_MAGIC_NFS: -@@ -805,16 +806,17 @@ dirent_inode_sort_may_be_useful (FTSENT const *p) - } - } - --/* Given an FTS entry P for a directory D, -+/* Given an FTS entry P for a directory with descriptor DIR_FD, - return true if it is both useful and valid to apply leaf optimization. - The optimization is useful only for file systems that lack usable - dirent.d_type info. The optimization is valid if an st_nlink value - of at least MIN_DIR_NLINK is an upper bound on the number of -- subdirectories of D, counting "." and ".." as subdirectories. */ -+ subdirectories of D, counting "." and ".." as subdirectories. -+ DIR_FD is negative if unavailable. */ - static enum leaf_optimization --leaf_optimization (FTSENT const *p) -+leaf_optimization (FTSENT const *p, int dir_fd) - { -- switch (filesystem_type (p)) -+ switch (filesystem_type (p, dir_fd)) - { - /* List here the file system types that may lack usable dirent.d_type - info, yet for which the optimization does apply. */ -@@ -851,12 +853,13 @@ leaf_optimization (FTSENT const *p) - - #else - static bool --dirent_inode_sort_may_be_useful (FTSENT const *p _GL_UNUSED) -+dirent_inode_sort_may_be_useful (FTSENT const *p _GL_UNUSED, -+ int dir_fd _GL_UNUSED) - { - return true; - } - static enum leaf_optimization --leaf_optimization (FTSENT const *p _GL_UNUSED) -+leaf_optimization (FTSENT const *p _GL_UNUSED, int dir_fd _GL_UNUSED) - { - return NO_LEAF_OPTIMIZATION; - } -@@ -1050,7 +1053,7 @@ check_for_dir: - if (parent->fts_n_dirs_remaining == 0 - && ISSET(FTS_NOSTAT) - && ISSET(FTS_PHYSICAL) -- && (leaf_optimization (parent) -+ && (leaf_optimization (parent, sp->fts_cwd_fd) - == NOSTAT_LEAF_OPTIMIZATION)) - { - /* nothing more needed */ -@@ -1335,6 +1338,7 @@ fts_build (register FTS *sp, int type) - int dir_fd; - FTSENT *cur = sp->fts_cur; - bool continue_readdir = !!cur->fts_dirp; -+ bool sort_by_inode = false; - size_t max_entries; - - /* When cur->fts_dirp is non-NULL, that means we should -@@ -1428,7 +1432,7 @@ fts_build (register FTS *sp, int type) - && ! (ISSET (FTS_NOSTAT) && ISSET (FTS_PHYSICAL) - && ! ISSET (FTS_SEEDOT) - && cur->fts_statp->st_nlink == MIN_DIR_NLINK -- && (leaf_optimization (cur) -+ && (leaf_optimization (cur, dir_fd) - != NO_LEAF_OPTIMIZATION))); - if (descend || type == BREAD) - { -@@ -1589,6 +1593,15 @@ mem1: saved_errno = errno; - tail->fts_link = p; - tail = p; - } -+ -+ /* If there are many entries, no sorting function has been -+ specified, and this file system is of a type that may be -+ slow with a large number of entries, arrange to sort the -+ directory entries on increasing inode numbers. */ -+ if (nitems == _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD -+ && !sp->fts_compar) -+ sort_by_inode = dirent_inode_sort_may_be_useful (cur, dir_fd); -+ - ++nitems; - if (max_entries <= nitems) { - /* When there are too many dir entries, leave -@@ -1646,13 +1659,7 @@ mem1: saved_errno = errno; - return (NULL); - } - -- /* If there are many entries, no sorting function has been specified, -- and this file system is of a type that may be slow with a large -- number of entries, then sort the directory entries on increasing -- inode numbers. */ -- if (nitems > _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD -- && !sp->fts_compar -- && dirent_inode_sort_may_be_useful (cur)) { -+ if (sort_by_inode) { - sp->fts_compar = fts_compare_ino; - head = fts_sort (sp, head, nitems); - sp->fts_compar = NULL; --- -2.14.3 - diff --git a/coreutils-8.29-gnulib-fflush.patch b/coreutils-8.29-gnulib-fflush.patch deleted file mode 100644 index 346b0e3..0000000 --- a/coreutils-8.29-gnulib-fflush.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 08d69db2f3c0e8506a1d126dd4dcdd0f14071161 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Mon, 5 Mar 2018 10:56:29 -0800 -Subject: [PATCH] fflush: adjust to glibc 2.28 libio.h removal -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Problem reported by Daniel P. Berrangé in: -https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html -* lib/fflush.c (clear_ungetc_buffer_preserving_position) -(disable_seek_optimization, rpl_fflush): -* lib/fpending.c (__fpending): -* lib/fpurge.c (fpurge): -* lib/freadahead.c (freadahead): -* lib/freading.c (freading): -* lib/freadptr.c (freadptr): -* lib/freadseek.c (freadptrinc): -* lib/fseeko.c (fseeko): -* lib/fseterr.c (fseterr): -* lib/stdio-impl.h (_IO_IN_BACKUP) [_IO_EOF_SEEN]: -Define if not already defined. - -Upstream-commit: 4af4a4a71827c0bc5e0ec67af23edef4f15cee8e -Signed-off-by: Kamil Dudka ---- - lib/fflush.c | 6 +++--- - lib/fpending.c | 2 +- - lib/fpurge.c | 2 +- - lib/freadahead.c | 2 +- - lib/freading.c | 2 +- - lib/freadptr.c | 2 +- - lib/freadseek.c | 2 +- - lib/fseeko.c | 4 ++-- - lib/fseterr.c | 2 +- - lib/stdio-impl.h | 6 ++++++ - 10 files changed, 18 insertions(+), 12 deletions(-) - -diff --git a/lib/fflush.c b/lib/fflush.c -index 4e65692..c16da5f 100644 ---- a/lib/fflush.c -+++ b/lib/fflush.c -@@ -33,7 +33,7 @@ - #undef fflush - - --#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - - /* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */ - static void -@@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp) - - #endif - --#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */) -+#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */) - - # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT - /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ -@@ -148,7 +148,7 @@ rpl_fflush (FILE *stream) - if (stream == NULL || ! freading (stream)) - return fflush (stream); - --#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - - clear_ungetc_buffer_preserving_position (stream); - -diff --git a/lib/fpending.c b/lib/fpending.c -index 5811a4a..9e21a16 100644 ---- a/lib/fpending.c -+++ b/lib/fpending.c -@@ -32,7 +32,7 @@ __fpending (FILE *fp) - /* Most systems provide FILE as a struct and the necessary bitmask in - , because they need it for implementing getc() and putc() as - fast macros. */ --#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - return fp->_IO_write_ptr - fp->_IO_write_base; - #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ - /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ -diff --git a/lib/fpurge.c b/lib/fpurge.c -index 408b8fc..3a16000 100644 ---- a/lib/fpurge.c -+++ b/lib/fpurge.c -@@ -62,7 +62,7 @@ fpurge (FILE *fp) - /* Most systems provide FILE as a struct and the necessary bitmask in - , because they need it for implementing getc() and putc() as - fast macros. */ --# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - fp->_IO_read_end = fp->_IO_read_ptr; - fp->_IO_write_ptr = fp->_IO_write_base; - /* Avoid memory leak when there is an active ungetc buffer. */ -diff --git a/lib/freadahead.c b/lib/freadahead.c -index f335f04..e7cb77b 100644 ---- a/lib/freadahead.c -+++ b/lib/freadahead.c -@@ -30,7 +30,7 @@ extern size_t __sreadahead (FILE *); - size_t - freadahead (FILE *fp) - { --#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - if (fp->_IO_write_ptr > fp->_IO_write_base) - return 0; - return (fp->_IO_read_end - fp->_IO_read_ptr) -diff --git a/lib/freading.c b/lib/freading.c -index 78140d2..c9d3344 100644 ---- a/lib/freading.c -+++ b/lib/freading.c -@@ -31,7 +31,7 @@ freading (FILE *fp) - /* Most systems provide FILE as a struct and the necessary bitmask in - , because they need it for implementing getc() and putc() as - fast macros. */ --# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - return ((fp->_flags & _IO_NO_WRITES) != 0 - || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0 - && fp->_IO_read_base != NULL)); -diff --git a/lib/freadptr.c b/lib/freadptr.c -index e4cc0b0..aba8dd5 100644 ---- a/lib/freadptr.c -+++ b/lib/freadptr.c -@@ -29,7 +29,7 @@ freadptr (FILE *fp, size_t *sizep) - size_t size; - - /* Keep this code in sync with freadahead! */ --#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - if (fp->_IO_write_ptr > fp->_IO_write_base) - return NULL; - size = fp->_IO_read_end - fp->_IO_read_ptr; -diff --git a/lib/freadseek.c b/lib/freadseek.c -index fcecba6..98726f8 100644 ---- a/lib/freadseek.c -+++ b/lib/freadseek.c -@@ -36,7 +36,7 @@ freadptrinc (FILE *fp, size_t increment) - /* Keep this code in sync with freadptr! */ - #if HAVE___FREADPTRINC /* musl libc */ - __freadptrinc (fp, increment); --#elif defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+#elif defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - fp->_IO_read_ptr += increment; - #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ - /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ -diff --git a/lib/fseeko.c b/lib/fseeko.c -index d0f24d8..0ae2b15 100644 ---- a/lib/fseeko.c -+++ b/lib/fseeko.c -@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int whence) - #endif - - /* These tests are based on fpurge.c. */ --#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - if (fp->_IO_read_end == fp->_IO_read_ptr - && fp->_IO_write_ptr == fp->_IO_write_base - && fp->_IO_save_base == NULL) -@@ -123,7 +123,7 @@ fseeko (FILE *fp, off_t offset, int whence) - return -1; - } - --#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - fp->_flags &= ~_IO_EOF_SEEN; - fp->_offset = pos; - #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ -diff --git a/lib/fseterr.c b/lib/fseterr.c -index 739e545..d998619 100644 ---- a/lib/fseterr.c -+++ b/lib/fseterr.c -@@ -29,7 +29,7 @@ fseterr (FILE *fp) - /* Most systems provide FILE as a struct and the necessary bitmask in - , because they need it for implementing getc() and putc() as - fast macros. */ --#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ -+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - fp->_flags |= _IO_ERR_SEEN; - #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__ - /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ -diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h -index 329801a..eeaabab 100644 ---- a/lib/stdio-impl.h -+++ b/lib/stdio-impl.h -@@ -18,6 +18,12 @@ - the same implementation of stdio extension API, except that some fields - have different naming conventions, or their access requires some casts. */ - -+/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this -+ problem by defining it ourselves. FIXME: Do not rely on glibc -+ internals. */ -+#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN -+# define _IO_IN_BACKUP 0x100 -+#endif - - /* BSD stdio derived implementations. */ - --- -2.16.2 - diff --git a/coreutils-8.29-gnulib-strftime.patch b/coreutils-8.29-gnulib-strftime.patch deleted file mode 100644 index b982344..0000000 --- a/coreutils-8.29-gnulib-strftime.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 67defe5a29936c20a2c102b1b947ce9ea9afc081 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Tue, 23 Jan 2018 00:42:04 -0800 -Subject: [PATCH] Merge strftime.c changes from glibc - -This incorporates: -2017-11-14 [BZ #10871] Implement alternative month names -2017-11-14 [BZ #10871] Abbreviated alternative month names (%Ob) -2017-06-20 Use locale_t, not __locale_t, throughout glibc -* lib/nstrftime.c (ABALTMON_1) [!COMPILE_WIDE]: New macro. -(LOCALE_PARAM) [_LIBC && USE_IN_EXTENDED_LOCALE_MODEL]: -Use locale_t, not __locale_t. -(a_altmonth, f_altmonth, aam_len) [_NL_CURRENT]: New macros. -(__strftime_internal): Add support for alternate months. - -Upstream-commit: 4a236f16ce0ef97094ff2f6538d4dba90e72a523 -Signed-off-by: Kamil Dudka ---- - lib/nstrftime.c | 24 +++++++++++++++++++----- - 1 file changed, 19 insertions(+), 5 deletions(-) - -diff --git a/lib/nstrftime.c b/lib/nstrftime.c -index 8795cd7..5902c49 100644 ---- a/lib/nstrftime.c -+++ b/lib/nstrftime.c -@@ -91,6 +91,7 @@ extern char *tzname[]; - # define UCHAR_T unsigned char - # define L_(Str) Str - # define NLW(Sym) Sym -+# define ABALTMON_1 _NL_ABALTMON_1 - - # define MEMCPY(d, s, n) memcpy (d, s, n) - # define STRLEN(s) strlen (s) -@@ -255,7 +256,7 @@ extern char *tzname[]; - # undef _NL_CURRENT - # define _NL_CURRENT(category, item) \ - (current->values[_NL_ITEM_INDEX (item)].string) --# define LOCALE_PARAM , __locale_t loc -+# define LOCALE_PARAM , locale_t loc - # define LOCALE_ARG , loc - # define HELPER_LOCALE_ARG , current - #else -@@ -475,12 +476,19 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) - # define f_month \ - ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ - ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))) -+# define a_altmonth \ -+ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ -+ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABALTMON_1) + tp->tm_mon))) -+# define f_altmonth \ -+ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ -+ ? "?" : _NL_CURRENT (LC_TIME, NLW(ALTMON_1) + tp->tm_mon))) - # define ampm \ - ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ - ? NLW(PM_STR) : NLW(AM_STR))) - - # define aw_len STRLEN (a_wkday) - # define am_len STRLEN (a_month) -+# define aam_len STRLEN (a_altmonth) - # define ap_len STRLEN (ampm) - #endif - #if HAVE_TZNAME -@@ -808,17 +816,20 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) - to_uppcase = true; - to_lowcase = false; - } -- if (modifier != 0) -+ if (modifier == L_('E')) - goto bad_format; - #ifdef _NL_CURRENT -- cpy (am_len, a_month); -+ if (modifier == L_('O')) -+ cpy (aam_len, a_altmonth); -+ else -+ cpy (am_len, a_month); - break; - #else - goto underlying_strftime; - #endif - - case L_('B'): -- if (modifier != 0) -+ if (modifier == L_('E')) - goto bad_format; - if (change_case) - { -@@ -826,7 +837,10 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) - to_lowcase = false; - } - #ifdef _NL_CURRENT -- cpy (STRLEN (f_month), f_month); -+ if (modifier == L_('O')) -+ cpy (STRLEN (f_altmonth), f_altmonth); -+ else -+ cpy (STRLEN (f_month), f_month); - break; - #else - goto underlying_strftime; --- -2.14.3 - diff --git a/coreutils-8.29-ls-abmon-width.patch b/coreutils-8.29-ls-abmon-width.patch deleted file mode 100644 index 52aef28..0000000 --- a/coreutils-8.29-ls-abmon-width.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 5a820c5a312d6a5b7a1a755cd0f81c84f7c676d7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 14 Mar 2018 11:31:43 -0700 -Subject: [PATCH 1/2] ls: increase the allowed abmon width from 5 to 12 - -This will impact relatively few languages, -and will make Arabic or Catalan etc. -output unambiguous abbreviated month names. - -* src/ls.c (MAX_MON_WIDTH): Increase from 5 to 12. -* tests/ls/abmon-align.sh: Augment to check for ambiguous output. -Fixes https://bugs.gnu.org/30814 - -Upstream-commit: 5ed2018360ba44f673b1dc74fb3d2927f7fcfae3 -Signed-off-by: Kamil Dudka ---- - src/ls.c | 7 +++++-- - tests/ls/abmon-align.sh | 9 ++++++--- - 2 files changed, 11 insertions(+), 5 deletions(-) - -diff --git a/src/ls.c b/src/ls.c -index 4becd06..b2983aa 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -1095,8 +1095,11 @@ file_escape_init (void) - variable width abbreviated months and also precomputing/caching - the names was seen to increase the performance of ls significantly. */ - --/* max number of display cells to use */ --enum { MAX_MON_WIDTH = 5 }; -+/* max number of display cells to use. -+ As of 2018 the abmon for Arabic has entries with width 12. -+ It doesn't make much sense to support wider than this -+ and locales should aim for abmon entries of width <= 5. */ -+enum { MAX_MON_WIDTH = 12 }; - /* abformat[RECENT][MON] is the format to use for timestamps with - recentness RECENT and month MON. */ - enum { ABFORMAT_SIZE = 128 }; -diff --git a/tests/ls/abmon-align.sh b/tests/ls/abmon-align.sh -index e474047..a81266b 100755 ---- a/tests/ls/abmon-align.sh -+++ b/tests/ls/abmon-align.sh -@@ -32,17 +32,20 @@ for format in "%b" "[%b" "%b]" "[%b]"; do - # The sed usage here is slightly different from the original, - # removing the \(.*\), to avoid triggering misbehavior in at least - # GNU sed 4.2 (possibly miscompiled) on Mac OS X (Darwin 9.8.0). -- n_widths=$( -+ months="$( - LC_ALL=$LOC TIME_STYLE=+"$format" ls -lgG *.ts | -- LC_ALL=C sed 's/.\{15\}//;s/ ..\.ts$//;s/ /./g' | -+ LC_ALL=C sed 's/.\{15\}//;s/ ..\.ts$//;s/ /./g')" -+ n_widths=$(echo "$months" | - while read mon; do echo "$mon" | LC_ALL=$LOC wc -L; done | - uniq | wc -l - ) -+ n_dupes=$(echo "$months" | sort | uniq -d | wc -l) - test "$n_widths" = "1" || { fail=1; break 2; } -+ test "$n_dupes" = "0" || { fail=1; break 2; } - done - done - if test "$fail" = "1"; then -- echo "misalignment detected in $LOC locale:" -+ echo "misalignment or ambiguous output in $LOC locale:" - LC_ALL=$LOC TIME_STYLE=+%b ls -lgG *.ts - fi - --- -2.14.3 - - -From 58196889eb9621a0bc8a97d7eda1174efb1b078c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Tue, 29 May 2018 10:10:35 -0700 -Subject: [PATCH 2/2] tests: fix periodic false failure in month alignment - -* tests/ls/abmon-align.sh: Base relative month adjustment -from the middle of the month, to avoid failures due -to months being repeated. -Fixes https://bugs.gnu.org/31644 - -Upstream-commit: c8eb21c9c0ba00559afc5e0d200085ac656396e0 -Signed-off-by: Kamil Dudka ---- - tests/ls/abmon-align.sh | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tests/ls/abmon-align.sh b/tests/ls/abmon-align.sh -index a81266b..8bd20ae 100755 ---- a/tests/ls/abmon-align.sh -+++ b/tests/ls/abmon-align.sh -@@ -19,8 +19,9 @@ - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ ls - -+mid_month="$(date +%Y-%m-15)" || framework_failure_ - for mon in $(seq -w 12); do -- touch -d"+$mon month" $mon.ts || framework_failure_ -+ touch -d"$mid_month +$mon month" $mon.ts || framework_failure_ - done - - --- -2.14.3 - diff --git a/coreutils-8.29-mv-n-noreplace.patch b/coreutils-8.29-mv-n-noreplace.patch deleted file mode 100644 index 4f82716..0000000 --- a/coreutils-8.29-mv-n-noreplace.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 76df06ff8fa39ae0cb0d167b7f622139778dc7d7 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 4 Jan 2018 09:42:10 +0100 -Subject: [PATCH] mv -n: do not overwrite the destination - -... if it is created by another process after mv has checked its -non-existence. - -* src/copy.c (copy_internal): Use renameat2 (..., RENAME_NOREPLACE) -if called by mv -n. If it fails with EEXIST in that case, pretend -successful rename as if the existing destination file was detected -by the preceding lstat call. - -Fixes https://bugs.gnu.org/29961 ---- - src/copy.c | 17 ++++++++++++++++- - 1 file changed, 16 insertions(+), 1 deletion(-) - -diff --git a/src/copy.c b/src/copy.c -index 2a804945e..be4e357a8 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -53,6 +53,7 @@ - #include "ignore-value.h" - #include "ioblksize.h" - #include "quote.h" -+#include "renameat2.h" - #include "root-uid.h" - #include "same.h" - #include "savedir.h" -@@ -2319,7 +2320,12 @@ copy_internal (char const *src_name, char const *dst_name, - - if (x->move_mode) - { -- if (rename (src_name, dst_name) == 0) -+ int flags = 0; -+ if (x->interactive == I_ALWAYS_NO) -+ /* do not replace DST_NAME if it was created since our last check */ -+ flags = RENAME_NOREPLACE; -+ -+ if (renameat2 (AT_FDCWD, src_name, AT_FDCWD, dst_name, flags) == 0) - { - if (x->verbose) - { -@@ -2351,6 +2357,15 @@ copy_internal (char const *src_name, char const *dst_name, - return true; - } - -+ if ((flags & RENAME_NOREPLACE) && (errno == EEXIST)) -+ { -+ /* Pretend the rename succeeded, so the caller (mv) -+ doesn't end up removing the source file. */ -+ if (rename_succeeded) -+ *rename_succeeded = true; -+ return true; -+ } -+ - /* FIXME: someday, consider what to do when moving a directory into - itself but when source and destination are on different devices. */ - --- -2.13.6 - diff --git a/coreutils-8.29.tar.xz.sig b/coreutils-8.29.tar.xz.sig deleted file mode 100644 index 614c344..0000000 --- a/coreutils-8.29.tar.xz.sig +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIcBAABAgAGBQJaQ+ZxAAoJEN9v2XEwYDfZOF8P/i9zNyDAerVBh6UOyW9ijDZ5 -3vSWYzgmNNxUp0BfptJ0xqirH8tKRvgHzoy87Eu5PvmARASKOtnjc1cap885HIto -j5LlGe2t73xoW049dIx00DwsZFo9ef/DZnaSRo96MlW1xXlHtuYTDwR9ovWt5xHx -a+SrzG05kdZlybQ8rLlz5MFxs43IHQHZ0wudlcP2KxlP2HEtBPDto/xmOxw7jVBD -5ZOhiTCB6Dza5QxWGCX3ij1YYEn9mmSsmp6Hp4QteskWlp6mpJEViW2GW6p3zUSe -EqpM9beax1pRKYcBMuXBDtSCS+Sxw//ZybE/p+bY5K2T0Z8zxUd325t4oGnb8uRK -jMBdm9SnlK9bkyouHxY3eK6XNMG/u4YZ/p4jk8QB4YdYN3t7u6aJ6443OgKDlmPF -qfELnZdPvOA9kdC8+oLz37Z/e7HmrZXforxk00qn/GCAVxqHhzu7QbME4/Zzufwt -bHQ2JcVqywmFfv0bI5rs/EpOYJoGOwlVFq/u6mykvzYgrFUgG171eu3SHrkFAWfA -hWz5mL1W3x/SYg/K+ySKlGtrQ877FNSHLOVP5cDme6HgAiV9rWyah44IEDwakyDk -yfDURjKUtNaSq9PAyGUXj4nJ4BklTIyRqiXUfIs8OK9UMPqrJsFSCxzSVAJWsuGL -Q2dcgRAkwMwrwhzed2ot -=QwW/ ------END PGP SIGNATURE----- diff --git a/coreutils-8.30.tar.xz.sig b/coreutils-8.30.tar.xz.sig new file mode 100644 index 0000000..34681ce --- /dev/null +++ b/coreutils-8.30.tar.xz.sig @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQIcBAABCAAGBQJbOYLXAAoJEN9v2XEwYDfZFRwP/1xKMtXTqCOnP3ECRze+bYnX +GB5Mm57kcP2NXwzo62+9C+FToEfkRTALtlU95edIRlsjLGBoDvv12fsOKdsyO/c5 +7paI3NoaUFyJxby9w91mNOcgN6eR5WZ/LHm2VbTs5VFpsNcSVyHSvhiqgPXtRrVp +ZrnUKbg9iWjn8jcJHIS7qrIO4GsoFzfhn9gVh8Xxp4AYx0btn3BwPTWCxg53Ie0p +OgrMmMnOe3wrpwrlJOgfvpk5na7yKRt7GYsyGMaKB7OxbHlVg4UCx4LuRBnaUPZr +QmlX37sIR/sEJne0zR4iMorPi5IsErMT39VaBDLnsAjyccbmYQ/RmFYASiM5Zijw +d94fk+TocyDBrOMsO5fzKUID5Uf4c5vJlhCXBsPBykNiKsQTb3M7fZ+gjYrMJmoS +4DDgAMryoB5yc2i9HcNj8WMNHy4RGIrRWxOAUZf5j2zEEVwKaRcoNosFoycUotEA +yoWdRIwyCkVwlemVhx0zQTm8WbtFl0kkAFKTqu7uHGUGOKSS4dzTi000cJ4qHSyY +ODrouvKgqKwB+Q7IfpQ72i6DLpTzNjLKNMipBPsSkSW+RaWC67+smo1vL9V5ZlfX +ypzjMF++r3cRuIWG9IwAwedl/sH7iqjHwdMf4y+8sGxRzW5Oeyvx20TvqxMqRLGD +nU0Y2GCLW7C2Idw+I5QM +=pibq +-----END PGP SIGNATURE----- diff --git a/coreutils-i18n-cut-old.patch b/coreutils-i18n-cut-old.patch index 7fcc8ff..d393f00 100644 --- a/coreutils-i18n-cut-old.patch +++ b/coreutils-i18n-cut-old.patch @@ -158,7 +158,7 @@ index 7ab6be4..022d0ad 100644 +static void +cut_characters_or_cut_bytes_no_split (FILE *stream) +{ -+ size_t idx; /* number of bytes or characters in the line so far. */ ++ 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. */ diff --git a/coreutils.spec b/coreutils.spec index b5f47b3..7729485 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.29 -Release: 12%{?dist} +Version: 8.30 +Release: 1%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -14,26 +14,6 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ -# mv -n: do not overwrite the destination, superseded by -# http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=v8.29-9-g29baf25aa -Patch1: coreutils-8.29-mv-n-noreplace.patch - -# doc: warn about following symlinks recursively in chown/chgrp (CVE-2017-18018) -Patch2: coreutils-8.29-CVE-2017-18018.patch - -# fix build failure with glibc-2.28 -# https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html -Patch3: coreutils-8.29-gnulib-fflush.patch - -# fix crash caused by mistakenly enabled leaf optimization (#1558249) -Patch4: coreutils-8.29-fts-leaf-opt.patch - -# date, ls: pick strftime fixes from glibc to improve locale support (#1577872) -Patch5: coreutils-8.29-gnulib-strftime.patch - -# ls: increase the allowed abmon width from 5 to 12 (#1577872) -Patch6: coreutils-8.29-ls-abmon-width.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -269,6 +249,9 @@ fi %license COPYING %changelog +* Mon Jul 02 2018 Kamil Dudka - 8.30-1 +- new upstream release 8.30 + * Wed May 30 2018 Kamil Dudka - 8.29-12 - add provides to coreutils-single to make it a drop-in replacement diff --git a/sources b/sources index cf5fb64..126e08c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (coreutils-8.29.tar.xz) = 546bbcd5741beae7a68e7c4ca14d6d634f7c8be87feecdeddd00e226f4865bb89d503437c3a95622ba7bb0cb70addbb5bdf3767fa18d0b7410ab90ee53b29dfd +SHA512 (coreutils-8.30.tar.xz) = 25bc132c0d89ce71c33e417f04649c9fcfce6c5ef8b19f093b2e9e2851bfde9b5a31e20499d9c427332228ba54b88d445ddb445551e1944bb8f5cbff5ffa4eda From 822c7685b53ae6319af26fa38c5ee29d720698bc Mon Sep 17 00:00:00 2001 From: Bernhard Voelker Date: Wed, 4 Jul 2018 01:45:29 +0200 Subject: [PATCH 381/523] sync i18n patches with Suse - coreutils-i18n-suse-merge.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-i18n-cut-old.patch | 2 +- coreutils-i18n-un-expand-BOM.patch | 4 ++-- coreutils-i18n.patch | 35 ++++-------------------------- coreutils.spec | 5 ++++- 4 files changed, 11 insertions(+), 35 deletions(-) diff --git a/coreutils-i18n-cut-old.patch b/coreutils-i18n-cut-old.patch index d393f00..757ee0f 100644 --- a/coreutils-i18n-cut-old.patch +++ b/coreutils-i18n-cut-old.patch @@ -234,7 +234,7 @@ index 7ab6be4..022d0ad 100644 +cut_fields_mb (FILE *stream) +{ + int c; -+ size_t field_idx; ++ uintmax_t field_idx; + int found_any_selected_field; + int buffer_first_field; + int empty_input; diff --git a/coreutils-i18n-un-expand-BOM.patch b/coreutils-i18n-un-expand-BOM.patch index d1ea109..6210ce7 100644 --- a/coreutils-i18n-un-expand-BOM.patch +++ b/coreutils-i18n-un-expand-BOM.patch @@ -226,7 +226,7 @@ index 310b349..4136824 100644 + if(using_utf_locale==false && found_bom==true) + { + /*First file conatined BOM header - locale was switched to UTF -+ /*all subsequent files should contain BOM. */ ++ *all subsequent files should contain BOM. */ + error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); + } + } @@ -296,7 +296,7 @@ index 863a90a..5681b58 100644 + if(using_utf_locale==false && found_bom==true) + { + /*First file conatined BOM header - locale was switched to UTF -+ /*all subsequent files should contain BOM. */ ++ *all subsequent files should contain BOM. */ + error (EXIT_FAILURE, errno, _("combination of files with and without BOM header")); + } + } diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 747772d..429675f 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -13,7 +13,6 @@ TODO: merge upstream src/uniq.c | 265 ++++++++++++++- tests/i18n/sort.sh | 29 ++ tests/local.mk | 2 + - tests/misc/cut.pl | 7 +- tests/misc/expand.pl | 42 +++ tests/misc/fold.pl | 50 ++- tests/misc/join.pl | 50 +++ @@ -23,9 +22,9 @@ TODO: merge upstream tests/misc/unexpand.pl | 39 +++ tests/misc/uniq.pl | 55 ++++ tests/pr/pr-tests.pl | 49 +++ - 18 files changed, 2435 insertions(+), 162 deletions(-) - create mode 100644 tests/i18n/sort.sh - create mode 100644 tests/misc/sort-mb-tests.sh + 17 files changed, 2430 insertions(+), 160 deletions(-) + create mode 100755 tests/i18n/sort.sh + create mode 100755 tests/misc/sort-mb-tests.sh diff --git a/lib/linebuffer.h b/lib/linebuffer.h index 64181af..9b8fe5a 100644 @@ -3157,7 +3156,7 @@ diff --git a/tests/local.mk b/tests/local.mk index 568944e..192f776 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -358,6 +358,8 @@ all_tests = \ +@@ -362,6 +362,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -3166,32 +3165,6 @@ index 568944e..192f776 100644 tests/misc/sort-h-thousands-sep.sh \ tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ -diff --git a/tests/misc/cut.pl b/tests/misc/cut.pl -index f6f8a56..b426a80 100755 ---- a/tests/misc/cut.pl -+++ b/tests/misc/cut.pl -@@ -23,9 +23,11 @@ use strict; - # 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; -+# uncommented enable multibyte paths -+$mb_locale = $ENV{LOCALE_FR_UTF8}; - ! defined $mb_locale || $mb_locale eq 'none' -- and $mb_locale = 'C'; -+ and $mb_locale = 'C'; - - my $prog = 'cut'; - my $try = "Try '$prog --help' for more information.\n"; -@@ -240,6 +242,7 @@ if ($mb_locale ne 'C') - my @new_t = @$t; - my $test_name = shift @new_t; - -+ next if ($test_name =~ "newline-[12][0-9]"); - push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; - } - push @Tests, @new; diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl index 8a9cad1..9293e39 100755 --- a/tests/misc/expand.pl diff --git a/coreutils.spec b/coreutils.spec index 7729485..fa0b81b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.30 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -249,6 +249,9 @@ fi %license COPYING %changelog +* Wed Jul 04 2018 Kamil Dudka - 8.30-2 +- sync i18n patches with Suse (patch by Bernhard Voelker) + * Mon Jul 02 2018 Kamil Dudka - 8.30-1 - new upstream release 8.30 From 333a3078881e65856ed01f7096fa812115c1ba1d Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 10 Jul 2018 14:17:00 +0200 Subject: [PATCH 382/523] Resolves: #1598518 - rename gnulib's renameat2 to renameatu to avoid clash with glibc --- coreutils-8.30-renameatu.patch | 451 +++++++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 458 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.30-renameatu.patch diff --git a/coreutils-8.30-renameatu.patch b/coreutils-8.30-renameatu.patch new file mode 100644 index 0000000..a5aa48f --- /dev/null +++ b/coreutils-8.30-renameatu.patch @@ -0,0 +1,451 @@ +From 57ee8db4fee8eb6772df1ff18d275594c0b034d4 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 5 Jul 2018 09:22:09 -0700 +Subject: [PATCH 1/2] renameatu: rename from renameat2 + +It's looking like Glibc will add a renameat2 function +that is incompatible with Gnulib renameat2; see: +https://sourceware.org/ml/libc-alpha/2018-07/msg00064.html +To help avoid future confusion, rename renameat2 to something else. +Use the name 'renameatu', as the Gnulib function is close to the +Glibc function. Perhaps someday there will also be a renameat2 +Gnulib module, which mimicks the future glibc renameat2, but that +can wait as nobody seems to need such a module now. +* NEWS: Mention this. +* lib/renameatu.c: Rename from lib/renameat2.c. +* lib/renameatu.h: Rename from lib/renameat2.h. +* modules/renameatu: Rename from modules/renameat2. +* modules/renameatu-tests: Rename from modules/renameat2-tests. +All uses of "renameat2" in identifiers or file name +changed to "renameatu", except for two instances in +lib/renameatu.c that deal with the Linux kernel's +renameat2 syscall. + +Upstream-commit: 2522322e5304e7d86c63e607e2bc83c8d8b0a889 +Signed-off-by: Kamil Dudka +--- + gnulib-tests/gnulib.mk | 12 +++--- + .../{test-renameat2.c => test-renameatu.c} | 48 +++++++++++----------- + lib/backupfile.c | 4 +- + lib/gnulib.mk | 10 ++--- + lib/renameat.c | 4 +- + lib/{renameat2.c => renameatu.c} | 9 ++-- + lib/{renameat2.h => renameatu.h} | 8 ++-- + 7 files changed, 48 insertions(+), 47 deletions(-) + rename gnulib-tests/{test-renameat2.c => test-renameatu.c} (80%) + rename lib/{renameat2.c => renameatu.c} (94%) + rename lib/{renameat2.h => renameatu.h} (84%) + +diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk +index be2b99e..891425b 100644 +--- a/gnulib-tests/gnulib.mk ++++ b/gnulib-tests/gnulib.mk +@@ -1750,14 +1750,14 @@ EXTRA_DIST += test-rename.h test-renameat.c signature.h macros.h + + ## end gnulib module renameat-tests + +-## begin gnulib module renameat2-tests ++## begin gnulib module renameatu-tests + +-TESTS += test-renameat2 +-check_PROGRAMS += test-renameat2 +-test_renameat2_LDADD = $(LDADD) @LIBINTL@ +-EXTRA_DIST += test-rename.h test-renameat2.c signature.h macros.h ++TESTS += test-renameatu ++check_PROGRAMS += test-renameatu ++test_renameatu_LDADD = $(LDADD) @LIBINTL@ ++EXTRA_DIST += test-rename.h test-renameatu.c signature.h macros.h + +-## end gnulib module renameat2-tests ++## end gnulib module renameatu-tests + + ## begin gnulib module rmdir-tests + +diff --git a/gnulib-tests/test-renameat2.c b/gnulib-tests/test-renameatu.c +similarity index 80% +rename from gnulib-tests/test-renameat2.c +rename to gnulib-tests/test-renameatu.c +index 0104890..988428b 100644 +--- a/gnulib-tests/test-renameat2.c ++++ b/gnulib-tests/test-renameatu.c +@@ -1,4 +1,4 @@ +-/* Test renameat2. ++/* Test renameatu. + Copyright (C) 2009-2018 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify +@@ -18,12 +18,12 @@ + + #include + +-#include ++#include + + #include + + #include "signature.h" +-SIGNATURE_CHECK (renameat2, int, ++SIGNATURE_CHECK (renameatu, int, + (int, char const *, int, char const *, unsigned int)); + + #include +@@ -39,18 +39,18 @@ SIGNATURE_CHECK (renameat2, int, + #include "ignore-value.h" + #include "macros.h" + +-#define BASE "test-renameat2.t" ++#define BASE "test-renameatu.t" + + #include "test-rename.h" + + static int dfd1 = AT_FDCWD; + static int dfd2 = AT_FDCWD; + +-/* Wrapper to test renameat2 like rename. */ ++/* Wrapper to test renameatu like rename. */ + static int + do_rename (char const *name1, char const *name2) + { +- return renameat2 (dfd1, name1, dfd2, name2, 0); ++ return renameatu (dfd1, name1, dfd2, name2, 0); + } + + int +@@ -67,24 +67,24 @@ main (void) + /* Test behaviour for invalid file descriptors. */ + { + errno = 0; +- ASSERT (renameat2 (-1, "foo", AT_FDCWD, "bar", 0) == -1); ++ ASSERT (renameatu (-1, "foo", AT_FDCWD, "bar", 0) == -1); + ASSERT (errno == EBADF); + } + { + close (99); + errno = 0; +- ASSERT (renameat2 (99, "foo", AT_FDCWD, "bar", 0) == -1); ++ ASSERT (renameatu (99, "foo", AT_FDCWD, "bar", 0) == -1); + ASSERT (errno == EBADF); + } + ASSERT (close (creat (BASE "oo", 0600)) == 0); + { + errno = 0; +- ASSERT (renameat2 (AT_FDCWD, BASE "oo", -1, "bar", 0) == -1); ++ ASSERT (renameatu (AT_FDCWD, BASE "oo", -1, "bar", 0) == -1); + ASSERT (errno == EBADF); + } + { + errno = 0; +- ASSERT (renameat2 (AT_FDCWD, BASE "oo", 99, "bar", 0) == -1); ++ ASSERT (renameatu (AT_FDCWD, BASE "oo", 99, "bar", 0) == -1); + ASSERT (errno == EBADF); + } + ASSERT (unlink (BASE "oo") == 0); +@@ -133,13 +133,13 @@ main (void) + + ASSERT (sprintf (strchr (file1, '\0') - 2, "%02d", i) == 2); + ASSERT (sprintf (strchr (file2, '\0') - 2, "%02d", i + 1) == 2); +- ASSERT (renameat2 (fd1, file1, fd2, file2, 0) == 0); ++ ASSERT (renameatu (fd1, file1, fd2, file2, 0) == 0); + free (file1); + free (file2); + } + dfd2 = open ("..", O_RDONLY); + ASSERT (0 <= dfd2); +- ASSERT (renameat2 (dfd, "../" BASE "16", dfd2, BASE "17", 0) == 0); ++ ASSERT (renameatu (dfd, "../" BASE "16", dfd2, BASE "17", 0) == 0); + ASSERT (close (dfd2) == 0); + + /* Now we change back to the parent directory, and set dfd to "."; +@@ -152,47 +152,47 @@ main (void) + + ASSERT (close (creat (BASE "sub2/file", 0600)) == 0); + errno = 0; +- ASSERT (renameat2 (dfd, BASE "sub1", dfd, BASE "sub2", 0) == -1); ++ ASSERT (renameatu (dfd, BASE "sub1", dfd, BASE "sub2", 0) == -1); + ASSERT (errno == EEXIST || errno == ENOTEMPTY); + ASSERT (unlink (BASE "sub2/file") == 0); + errno = 0; +- ASSERT (renameat2 (dfd, BASE "sub2", dfd, BASE "sub1/.", 0) == -1); ++ ASSERT (renameatu (dfd, BASE "sub2", dfd, BASE "sub1/.", 0) == -1); + ASSERT (errno == EINVAL || errno == EISDIR || errno == EBUSY + || errno == ENOTEMPTY || errno == EEXIST + || errno == ENOENT /* WSL */); + errno = 0; +- ASSERT (renameat2 (dfd, BASE "sub2/.", dfd, BASE "sub1", 0) == -1); ++ ASSERT (renameatu (dfd, BASE "sub2/.", dfd, BASE "sub1", 0) == -1); + ASSERT (errno == EINVAL || errno == EBUSY || errno == EEXIST + || errno == ENOENT /* WSL */); + errno = 0; +- ASSERT (renameat2 (dfd, BASE "17", dfd, BASE "sub1", 0) == -1); ++ ASSERT (renameatu (dfd, BASE "17", dfd, BASE "sub1", 0) == -1); + ASSERT (errno == EISDIR); + errno = 0; +- ASSERT (renameat2 (dfd, BASE "nosuch", dfd, BASE "18", 0) == -1); ++ ASSERT (renameatu (dfd, BASE "nosuch", dfd, BASE "18", 0) == -1); + ASSERT (errno == ENOENT); + errno = 0; +- ASSERT (renameat2 (dfd, "", dfd, BASE "17", 0) == -1); ++ ASSERT (renameatu (dfd, "", dfd, BASE "17", 0) == -1); + ASSERT (errno == ENOENT); + errno = 0; +- ASSERT (renameat2 (dfd, BASE "17", dfd, "", 0) == -1); ++ ASSERT (renameatu (dfd, BASE "17", dfd, "", 0) == -1); + ASSERT (errno == ENOENT); + errno = 0; +- ASSERT (renameat2 (dfd, BASE "sub2", dfd, BASE "17", 0) == -1); ++ ASSERT (renameatu (dfd, BASE "sub2", dfd, BASE "17", 0) == -1); + ASSERT (errno == ENOTDIR); + errno = 0; +- ASSERT (renameat2 (dfd, BASE "17/", dfd, BASE "18", 0) == -1); ++ ASSERT (renameatu (dfd, BASE "17/", dfd, BASE "18", 0) == -1); + ASSERT (errno == ENOTDIR); + errno = 0; +- ASSERT (renameat2 (dfd, BASE "17", dfd, BASE "18/", 0) == -1); ++ ASSERT (renameatu (dfd, BASE "17", dfd, BASE "18/", 0) == -1); + ASSERT (errno == ENOTDIR || errno == ENOENT); + + /* Finally, make sure we cannot overwrite existing files. */ + ASSERT (close (creat (BASE "sub2/file", 0600)) == 0); + errno = 0; +- ASSERT ((renameat2 (dfd, BASE "sub2", dfd, BASE "sub1", RENAME_NOREPLACE) ++ ASSERT ((renameatu (dfd, BASE "sub2", dfd, BASE "sub1", RENAME_NOREPLACE) + == -1) + && errno == EEXIST); +- ASSERT ((renameat2 (dfd, BASE "sub2/file", dfd, BASE "17", RENAME_NOREPLACE) ++ ASSERT ((renameatu (dfd, BASE "sub2/file", dfd, BASE "17", RENAME_NOREPLACE) + == -1) + && errno == EEXIST); + +diff --git a/lib/backupfile.c b/lib/backupfile.c +index d438455..637be6c 100644 +--- a/lib/backupfile.c ++++ b/lib/backupfile.c +@@ -23,7 +23,7 @@ + #include "backup-internal.h" + + #include "dirname.h" +-#include "renameat2.h" ++#include "renameatu.h" + #include "xalloc-oversized.h" + + #include +@@ -353,7 +353,7 @@ backupfile_internal (char const *file, enum backup_type backup_type, bool rename + base_offset = 0; + } + unsigned flags = backup_type == simple_backups ? 0 : RENAME_NOREPLACE; +- if (renameat2 (AT_FDCWD, file, sdir, s + base_offset, flags) == 0) ++ if (renameatu (AT_FDCWD, file, sdir, s + base_offset, flags) == 0) + break; + int e = errno; + if (e != EEXIST) +diff --git a/lib/gnulib.mk b/lib/gnulib.mk +index 04473d5..0b747e3 100644 +--- a/lib/gnulib.mk ++++ b/lib/gnulib.mk +@@ -21,7 +21,7 @@ + # the same distribution terms as the rest of that program. + # + # Generated by gnulib-tool. +-# Reproduce by: gnulib-tool --import --local-dir=gl --lib=libcoreutils --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=gnulib-tests --aux-dir=build-aux --with-tests --avoid=canonicalize-lgpl --avoid=dummy --makefile-name=gnulib.mk --no-conditional-dependencies --no-libtool --macro-prefix=gl acl alignof alloca announce-gen areadlink-with-size argmatch argv-iter assert autobuild backup-rename backupfile base32 base64 buffer-lcm c-strcase c-strtod c-strtold calloc-gnu canon-host canonicalize chown cloexec closein closeout config-h configmake crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 cycle-check d-ino d-type di-set diacrit dirfd dirname do-release-commit-and-tag dtoastr dup2 environ error euidaccess exclude exitfail explicit_bzero faccessat fadvise fchdir fchmodat fchownat fclose fcntl fcntl-safer fd-reopen fdatasync fdl fdopen fdutimensat file-has-acl file-type fileblocks filemode filenamecat filevercmp flexmember fnmatch-gnu fopen-safer fprintftime freopen freopen-safer fseeko fstatat fsusage fsync ftoastr ftruncate fts full-read full-write getgroups gethrxtime getline getloadavg getlogin getndelim2 getopt-gnu getpagesize getpass-gnu gettext-h gettime gettimeofday getugroups getusershell git-version-gen gitlog-to-changelog gnu-make gnu-web-doc-update gnumakefile gnupload group-member hard-locale hash hash-pjw heap host-os human idcache ignore-value inttostr inttypes isapipe isatty isblank largefile lchmod lchown ldtoastr lib-ignore linebuffer link link-follow linkat long-options lstat maintainer-makefile malloc-gnu manywarnings mbrlen mbrtowc mbsalign mbschr mbslen mbswidth memcasecmp memchr memcmp2 mempcpy memrchr mgetgroups mkancesdirs mkdir mkdir-p mkfifo mknod mkostemp mkstemp mktime modechange mountlist mpsort netinet_in non-recursive-gnulib-prefix-hack nproc nstrftime obstack open parse-datetime pathmax perl physmem pipe-posix pipe2 posix-shell posixtm posixver priv-set progname propername pthread putenv quote quotearg randint randperm read-file readlink readtokens readtokens0 readutmp realloc-gnu regex remove rename renameat renameat2 rmdir root-dev-ino rpmatch safe-read same save-cwd savedir savewd selinux-at setenv settime sig2str sigaction smack ssize_t stat-macros stat-size stat-time statat stdbool stdlib-safer stpcpy stpncpy strdup-posix strncat strnumcmp strsignal strtod strtoimax strtoumax symlinkat sys_ioctl sys_resource sys_stat sys_wait tempname termios time_rz timer-time timespec tzset uname unicodeio unistd-safer unlink-busy unlinkat unlocked-io unsetenv update-copyright uptime useless-if-before-free userspec utimecmp utimens vasprintf-posix vc-list-files verify verror version-etc-fsf wchar-single wcswidth wcwidth winsz-ioctl winsz-termios write-any-file xalloc xbinary-io xdectoint xfts xgetcwd xgetgroups xgethostname xmemcoll xnanosleep xprintf xprintf-posix xreadlink xstrtod xstrtoimax xstrtol xstrtold xstrtoumax year2038 yesno ++# Reproduce by: gnulib-tool --import --local-dir=gl --lib=libcoreutils --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=gnulib-tests --aux-dir=build-aux --with-tests --avoid=canonicalize-lgpl --avoid=dummy --makefile-name=gnulib.mk --no-conditional-dependencies --no-libtool --macro-prefix=gl acl alignof alloca announce-gen areadlink-with-size argmatch argv-iter assert autobuild backup-rename backupfile base32 base64 buffer-lcm c-strcase c-strtod c-strtold calloc-gnu canon-host canonicalize chown cloexec closein closeout config-h configmake crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 cycle-check d-ino d-type di-set diacrit dirfd dirname do-release-commit-and-tag dtoastr dup2 environ error euidaccess exclude exitfail explicit_bzero faccessat fadvise fchdir fchmodat fchownat fclose fcntl fcntl-safer fd-reopen fdatasync fdl fdopen fdutimensat file-has-acl file-type fileblocks filemode filenamecat filevercmp flexmember fnmatch-gnu fopen-safer fprintftime freopen freopen-safer fseeko fstatat fsusage fsync ftoastr ftruncate fts full-read full-write getgroups gethrxtime getline getloadavg getlogin getndelim2 getopt-gnu getpagesize getpass-gnu gettext-h gettime gettimeofday getugroups getusershell git-version-gen gitlog-to-changelog gnu-make gnu-web-doc-update gnumakefile gnupload group-member hard-locale hash hash-pjw heap host-os human idcache ignore-value inttostr inttypes isapipe isatty isblank largefile lchmod lchown ldtoastr lib-ignore linebuffer link link-follow linkat long-options lstat maintainer-makefile malloc-gnu manywarnings mbrlen mbrtowc mbsalign mbschr mbslen mbswidth memcasecmp memchr memcmp2 mempcpy memrchr mgetgroups mkancesdirs mkdir mkdir-p mkfifo mknod mkostemp mkstemp mktime modechange mountlist mpsort netinet_in non-recursive-gnulib-prefix-hack nproc nstrftime obstack open parse-datetime pathmax perl physmem pipe-posix pipe2 posix-shell posixtm posixver priv-set progname propername pthread putenv quote quotearg randint randperm read-file readlink readtokens readtokens0 readutmp realloc-gnu regex remove rename renameat renameatu rmdir root-dev-ino rpmatch safe-read same save-cwd savedir savewd selinux-at setenv settime sig2str sigaction smack ssize_t stat-macros stat-size stat-time statat stdbool stdlib-safer stpcpy stpncpy strdup-posix strncat strnumcmp strsignal strtod strtoimax strtoumax symlinkat sys_ioctl sys_resource sys_stat sys_wait tempname termios time_rz timer-time timespec tzset uname unicodeio unistd-safer unlink-busy unlinkat unlocked-io unsetenv update-copyright uptime useless-if-before-free userspec utimecmp utimens vasprintf-posix vc-list-files verify verror version-etc-fsf wchar-single wcswidth wcwidth winsz-ioctl winsz-termios write-any-file xalloc xbinary-io xdectoint xfts xgetcwd xgetgroups xgethostname xmemcoll xnanosleep xprintf xprintf-posix xreadlink xstrtod xstrtoimax xstrtol xstrtold xstrtoumax year2038 yesno + + + MOSTLYCLEANFILES += lib/core lib/*.stackdump +@@ -3218,15 +3218,15 @@ EXTRA_lib_libcoreutils_a_SOURCES += lib/renameat.c + + ## end gnulib module renameat + +-## begin gnulib module renameat2 ++## begin gnulib module renameatu + +-lib_libcoreutils_a_SOURCES += lib/renameat2.c ++lib_libcoreutils_a_SOURCES += lib/renameatu.c + +-EXTRA_DIST += lib/at-func2.c lib/renameat2.h ++EXTRA_DIST += lib/at-func2.c lib/renameatu.h + + EXTRA_lib_libcoreutils_a_SOURCES += lib/at-func2.c + +-## end gnulib module renameat2 ++## end gnulib module renameatu + + ## begin gnulib module rewinddir + +diff --git a/lib/renameat.c b/lib/renameat.c +index 0cb7d33..67be22b 100644 +--- a/lib/renameat.c ++++ b/lib/renameat.c +@@ -16,10 +16,10 @@ + + #include + #include +-#include "renameat2.h" ++#include "renameatu.h" + + int + renameat (int fd1, char const *src, int fd2, char const *dst) + { +- return renameat2 (fd1, src, fd2, dst, 0); ++ return renameatu (fd1, src, fd2, dst, 0); + } +diff --git a/lib/renameat2.c b/lib/renameatu.c +similarity index 94% +rename from lib/renameat2.c +rename to lib/renameatu.c +index a295ec3..b013ad6 100644 +--- a/lib/renameat2.c ++++ b/lib/renameatu.c +@@ -18,7 +18,7 @@ + + #include + +-#include "renameat2.h" ++#include "renameatu.h" + + #include + #include +@@ -68,10 +68,13 @@ rename_noreplace (char const *src, char const *dst) + the restore_cwd fails, then give a diagnostic and exit nonzero. + + Obey FLAGS when doing the renaming. If FLAGS is zero, this +- function is equivalent to renameat (FD1, SRC, FD2, DST). */ ++ function is equivalent to renameat (FD1, SRC, FD2, DST). ++ Otherwise, attempt to implement FLAGS even if the implementation is ++ not atomic; this differs from the GNU/Linux native renameat2, ++ which fails if it cannot guarantee atomicity. */ + + int +-renameat2 (int fd1, char const *src, int fd2, char const *dst, ++renameatu (int fd1, char const *src, int fd2, char const *dst, + unsigned int flags) + { + int ret_val = -1; +diff --git a/lib/renameat2.h b/lib/renameatu.h +similarity index 84% +rename from lib/renameat2.h +rename to lib/renameatu.h +index aba7966..7d79775 100644 +--- a/lib/renameat2.h ++++ b/lib/renameatu.h +@@ -16,15 +16,13 @@ + + /* written by Paul Eggert */ + +-/* Get RENAME_* macros from linux/fs.h if present, otherwise supply ++/* Get RENAME_* macros from if present, otherwise supply + the traditional Linux values. */ +-#if HAVE_LINUX_FS_H +-# include +-#endif ++#include + #ifndef RENAME_NOREPLACE + # define RENAME_NOREPLACE (1 << 0) + # define RENAME_EXCHANGE (1 << 1) + # define RENAME_WHITEOUT (1 << 2) + #endif + +-extern int renameat2 (int, char const *, int, char const *, unsigned int); ++extern int renameatu (int, char const *, int, char const *, unsigned int); +-- +2.14.4 + + +From a6b7ff5ef538bbdff4550a56fed878e9cd951d6d Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 5 Jul 2018 09:33:48 -0700 +Subject: [PATCH 2/2] build: update gnulib submodule to latest + +* bootstrap.conf, src/copy.c, src/mv.c, src/shred.c: +Adjust to renaming of renameat2 to renameatu. + +Upstream-commit: 439741053256618eb651e6d43919df29625b8714 +Signed-off-by: Kamil Dudka +--- + bootstrap.conf | 2 +- + src/copy.c | 4 ++-- + src/mv.c | 4 ++-- + src/shred.c | 4 ++-- + 4 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/bootstrap.conf b/bootstrap.conf +index 4da4f94..fcf29dc 100644 +--- a/bootstrap.conf ++++ b/bootstrap.conf +@@ -210,7 +210,7 @@ gnulib_modules=" + remove + rename + renameat +- renameat2 ++ renameatu + rmdir + root-dev-ino + rpmatch +diff --git a/src/copy.c b/src/copy.c +index 58d2f6e..1a9cdd1 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -53,7 +53,7 @@ + #include "ignore-value.h" + #include "ioblksize.h" + #include "quote.h" +-#include "renameat2.h" ++#include "renameatu.h" + #include "root-uid.h" + #include "same.h" + #include "savedir.h" +@@ -1873,7 +1873,7 @@ copy_internal (char const *src_name, char const *dst_name, + if (x->move_mode) + { + if (rename_errno < 0) +- rename_errno = (renameat2 (AT_FDCWD, src_name, AT_FDCWD, dst_name, ++ rename_errno = (renameatu (AT_FDCWD, src_name, AT_FDCWD, dst_name, + RENAME_NOREPLACE) + ? errno : 0); + new_dst = rename_errno == 0; +diff --git a/src/mv.c b/src/mv.c +index b6dd72d..36fd1af 100644 +--- a/src/mv.c ++++ b/src/mv.c +@@ -31,7 +31,7 @@ + #include "error.h" + #include "filenamecat.h" + #include "remove.h" +-#include "renameat2.h" ++#include "renameatu.h" + #include "root-dev-ino.h" + #include "priv-set.h" + +@@ -456,7 +456,7 @@ main (int argc, char **argv) + { + assert (2 <= n_files); + if (n_files == 2) +- x.rename_errno = (renameat2 (AT_FDCWD, file[0], AT_FDCWD, file[1], ++ x.rename_errno = (renameatu (AT_FDCWD, file[0], AT_FDCWD, file[1], + RENAME_NOREPLACE) + ? errno : 0); + if (x.rename_errno != 0 && target_directory_operand (file[n_files - 1])) +diff --git a/src/shred.c b/src/shred.c +index 2ddaadd..270b1e9 100644 +--- a/src/shred.c ++++ b/src/shred.c +@@ -93,7 +93,7 @@ + #include "human.h" + #include "randint.h" + #include "randread.h" +-#include "renameat2.h" ++#include "renameatu.h" + #include "stat-size.h" + + /* Default number of times to overwrite. */ +@@ -1096,7 +1096,7 @@ wipename (char *oldname, char const *qoldname, struct Options const *flags) + memset (base, nameset[0], len); + base[len] = 0; + bool rename_ok; +- while (! (rename_ok = (renameat2 (AT_FDCWD, oldname, AT_FDCWD, newname, ++ while (! (rename_ok = (renameatu (AT_FDCWD, oldname, AT_FDCWD, newname, + RENAME_NOREPLACE) + == 0)) + && errno == EEXIST && incname (base, len)) +-- +2.14.4 + diff --git a/coreutils.spec b/coreutils.spec index fa0b81b..db13d3e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.30 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -14,6 +14,9 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ +# rename gnulib's renameat2 to renameatu to avoid clash with glibc (#1598518) +Patch1: coreutils-8.30-renameatu.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -249,6 +252,9 @@ fi %license COPYING %changelog +* Tue Jul 10 2018 Kamil Dudka - 8.30-3 +- rename gnulib's renameat2 to renameatu to avoid clash with glibc (#1598518) + * Wed Jul 04 2018 Kamil Dudka - 8.30-2 - sync i18n patches with Suse (patch by Bernhard Voelker) From abb9bb783a0d050e916f7748945f23dd896a932e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 12 Jul 2018 22:15:30 +0000 Subject: [PATCH 383/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index db13d3e..5ff2e91 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.30 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -252,6 +252,9 @@ fi %license COPYING %changelog +* Thu Jul 12 2018 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + * Tue Jul 10 2018 Kamil Dudka - 8.30-3 - rename gnulib's renameat2 to renameatu to avoid clash with glibc (#1598518) From 7c7259b187048d03b23edbedfc8e0977435a2eeb Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 11 Oct 2018 14:37:42 +0200 Subject: [PATCH 384/523] changelog: fix the last entry (version-release was missing) --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 5ff2e91..34ef1c6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -252,7 +252,7 @@ fi %license COPYING %changelog -* Thu Jul 12 2018 Fedora Release Engineering +* Thu Jul 12 2018 Fedora Release Engineering - 8.30-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild * Tue Jul 10 2018 Kamil Dudka - 8.30-3 From 71b79ae180fde4580205f937c7a1533d02b2070e Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 11 Oct 2018 14:39:02 +0200 Subject: [PATCH 385/523] Resolves: CVE-2018-17942 - fix heap-based buffer overflow in vasnprintf() --- coreutils-8.30-CVE-2018-17942.patch | 69 +++++++++++++++++++++++++++++ coreutils.spec | 8 +++- 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.30-CVE-2018-17942.patch diff --git a/coreutils-8.30-CVE-2018-17942.patch b/coreutils-8.30-CVE-2018-17942.patch new file mode 100644 index 0000000..409fe0c --- /dev/null +++ b/coreutils-8.30-CVE-2018-17942.patch @@ -0,0 +1,69 @@ +From 6d059cebfdefbdf56910a858f8b603d37f10ef6d Mon Sep 17 00:00:00 2001 +From: Bruno Haible +Date: Sun, 23 Sep 2018 14:13:52 +0200 +Subject: [PATCH] vasnprintf: Fix heap memory overrun bug. + +Reported by Ben Pfaff in +. + +* lib/vasnprintf.c (convert_to_decimal): Allocate one more byte of +memory. +* tests/test-vasnprintf.c (test_function): Add another test. + +Upstream-commit: 278b4175c9d7dd47c1a3071554aac02add3b3c35 +Signed-off-by: Kamil Dudka +--- + gnulib-tests/test-vasnprintf.c | 21 ++++++++++++++++++++- + lib/vasnprintf.c | 4 +++- + 2 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/gnulib-tests/test-vasnprintf.c b/gnulib-tests/test-vasnprintf.c +index 19731bc..93d81d7 100644 +--- a/gnulib-tests/test-vasnprintf.c ++++ b/gnulib-tests/test-vasnprintf.c +@@ -53,7 +53,26 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...)) + ASSERT (result != NULL); + ASSERT (strcmp (result, "12345") == 0); + ASSERT (length == 5); +- if (size < 6) ++ if (size < 5 + 1) ++ ASSERT (result != buf); ++ ASSERT (memcmp (buf + size, &"DEADBEEF"[size], 8 - size) == 0); ++ if (result != buf) ++ free (result); ++ } ++ ++ /* Note: This test assumes IEEE 754 representation of 'double' floats. */ ++ for (size = 0; size <= 8; size++) ++ { ++ size_t length; ++ char *result; ++ ++ memcpy (buf, "DEADBEEF", 8); ++ length = size; ++ result = my_asnprintf (buf, &length, "%2.0f", 1.6314159265358979e+125); ++ ASSERT (result != NULL); ++ ASSERT (strcmp (result, "163141592653589790215729350939528493057529598899734151772468186268423257777068536614838678161083520756952076273094236944990208") == 0); ++ ASSERT (length == 126); ++ if (size < 126 + 1) + ASSERT (result != buf); + ASSERT (memcmp (buf + size, &"DEADBEEF"[size], 8 - size) == 0); + if (result != buf) +diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c +index 3b441d0..48ef7a6 100644 +--- a/lib/vasnprintf.c ++++ b/lib/vasnprintf.c +@@ -860,7 +860,9 @@ convert_to_decimal (mpn_t a, size_t extra_zeroes) + size_t a_len = a.nlimbs; + /* 0.03345 is slightly larger than log(2)/(9*log(10)). */ + size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1); +- char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes)); ++ /* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the ++ digits of a, followed by 1 byte for the terminating NUL. */ ++ char *c_ptr = (char *) malloc (xsum (xsum (extra_zeroes, c_len), 1)); + if (c_ptr != NULL) + { + char *d_ptr = c_ptr; +-- +2.17.1 + diff --git a/coreutils.spec b/coreutils.spec index 34ef1c6..10b2af2 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.30 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -17,6 +17,9 @@ Source106: coreutils-colorls.csh # rename gnulib's renameat2 to renameatu to avoid clash with glibc (#1598518) Patch1: coreutils-8.30-renameatu.patch +# fix heap-based buffer overflow in vasnprintf() (CVE-2018-17942) +Patch2: coreutils-8.30-CVE-2018-17942.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -252,6 +255,9 @@ fi %license COPYING %changelog +* Thu Oct 11 2018 Kamil Dudka - 8.30-5 +- fix heap-based buffer overflow in vasnprintf() (CVE-2018-17942) + * Thu Jul 12 2018 Fedora Release Engineering - 8.30-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild From 9cc8a839e2dcb8ca42922452629941242f26150b Mon Sep 17 00:00:00 2001 From: Kevin Fenzi Date: Sat, 3 Nov 2018 12:41:59 -0700 Subject: [PATCH 386/523] Remove no longer needed info scriptlets --- coreutils.spec | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 10b2af2..7671a34 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.30 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -219,18 +219,6 @@ grep LC_TIME %name.lang | cut -d'/' -f1-6 | sed -e 's/) /) %%dir /g' >>%name.lan # (sb) Deal with Installed (but unpackaged) file(s) found rm -f $RPM_BUILD_ROOT%{_infodir}/dir -%preun common -if [ $1 = 0 ]; then - if [ -f %{_infodir}/%{name}.info.gz ]; then - /sbin/install-info --delete %{_infodir}/%{name}.info.gz %{_infodir}/dir || : - fi -fi - -%post common -if [ -f %{_infodir}/%{name}.info.gz ]; then - /sbin/install-info %{_infodir}/%{name}.info.gz %{_infodir}/dir || : -fi - %files -f supported_utils %exclude %{_bindir}/*.single %dir %{_libexecdir}/coreutils @@ -255,6 +243,9 @@ fi %license COPYING %changelog +* Sat Nov 03 2018 Kevin Fenzi - 8.30-6 +- Remove no longer needed info scriptlets + * Thu Oct 11 2018 Kamil Dudka - 8.30-5 - fix heap-based buffer overflow in vasnprintf() (CVE-2018-17942) From 5decf6eab4c45e52d995f0223d9f9396fe09d821 Mon Sep 17 00:00:00 2001 From: Kevin Fenzi Date: Sat, 3 Nov 2018 14:12:43 -0700 Subject: [PATCH 387/523] Also remove Requires pre/post used by info scriptlets. --- coreutils.spec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 7671a34..06e23ee 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.30 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -123,8 +123,6 @@ packaged as a single multicall binary. # yum obsoleting rules explained at: # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 -Requires(preun): /sbin/install-info -Requires(post): /sbin/install-info Summary: coreutils common optional components %description common Optional though recommended components, @@ -243,6 +241,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Sat Nov 03 2018 Kevin Fenzi - 8.30-7 +- Also remove Requires pre/post used by info scriptlets. + * Sat Nov 03 2018 Kevin Fenzi - 8.30-6 - Remove no longer needed info scriptlets From d3d47dee1228c4b0f749352f1f74566fae58b788 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 7 Nov 2018 15:53:11 +0100 Subject: [PATCH 388/523] fix implicit declaration warning in coreutils-getgrouplist.patch Error: COMPILER_WARNING: coreutils-8.30/lib/mgetgroups.c: scope_hint: In function 'mgetgroups' coreutils-8.30/lib/mgetgroups.c:167:11: warning: implicit declaration of function 'xrealloc'; did you mean 'realloc'? [-Wimplicit-function-declaration] g = xrealloc (g, max_n_groups * sizeof (GETGROUPS_T)); ^~~~~~~~ 165| { 166| max_n_groups = ng; 167|-> g = xrealloc (g, max_n_groups * sizeof (GETGROUPS_T)); 168| } 169| if (e == -1) --- coreutils-getgrouplist.patch | 12 ++++++++++-- coreutils.spec | 5 ++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch index 5b35f42..5349337 100644 --- a/coreutils-getgrouplist.patch +++ b/coreutils-getgrouplist.patch @@ -21,7 +21,15 @@ diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c index 76474c2..0a9d221 100644 --- a/lib/mgetgroups.c +++ b/lib/mgetgroups.c -@@ -121,9 +121,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) +@@ -31,6 +31,7 @@ + #endif + + #include "getugroups.h" ++#include "xalloc.h" + #include "xalloc-oversized.h" + + /* Work around an incompatibility of OS X 10.11: getgrouplist +@@ -121,9 +122,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) /* else no username, so fall through and use getgroups. */ #endif @@ -42,7 +50,7 @@ index 76474c2..0a9d221 100644 /* If we failed to count groups because there is no supplemental group support, then return an array containing just GID. -@@ -145,10 +153,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) +@@ -145,10 +154,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) if (g == NULL) return -1; diff --git a/coreutils.spec b/coreutils.spec index 06e23ee..51dbe1a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.30 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ @@ -241,6 +241,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Nov 07 2018 Kamil Dudka - 8.30-8 +- fix implicit declaration warning in coreutils-getgrouplist.patch + * Sat Nov 03 2018 Kevin Fenzi - 8.30-7 - Also remove Requires pre/post used by info scriptlets. From 990cf47f04115a5a5c017b93576c958bff1f73df Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 7 Nov 2018 15:59:54 +0100 Subject: [PATCH 389/523] sync: fix open() fallback bug Detected by Coverity Analysis: Error: RESOURCE_LEAK (CWE-772): coreutils-8.30/src/sync.c:112: open_fn: Returning handle opened by "open". [Note: The source code implementation of the function has been overridden by a user model.] coreutils-8.30/src/sync.c:112: var_assign: Assigning: "fd" = handle returned from "open(file, 2049)". coreutils-8.30/src/sync.c:115: leaked_handle: Handle variable "fd" going out of scope leaks the handle. 113| if (fd < 0) 114| error (0, rd_errno, _("error opening %s"), quoteaf (file)); 115|-> return false; 116| } 117| Bug: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=33287 --- coreutils-8.30-fsync-fallback.patch | 77 +++++++++++++++++++++++++++++ coreutils.spec | 4 ++ 2 files changed, 81 insertions(+) create mode 100644 coreutils-8.30-fsync-fallback.patch diff --git a/coreutils-8.30-fsync-fallback.patch b/coreutils-8.30-fsync-fallback.patch new file mode 100644 index 0000000..110da10 --- /dev/null +++ b/coreutils-8.30-fsync-fallback.patch @@ -0,0 +1,77 @@ +From 2eabfbee57be82f755c74cbb05755dce1469ea7c Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Tue, 6 Nov 2018 10:35:16 -0800 +Subject: [PATCH 1/2] sync: fix open fallback bug + +Problem caught by Coverity Analysis +and reported by Kamil Dudka (Bug#33287). +* src/sync.c (sync_arg): Fix typo in fallback code. + +Upstream-commit: 94d364f157f007f2b23c70863ac8eefe9b21229d +Signed-off-by: Kamil Dudka +--- + src/sync.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/sync.c b/src/sync.c +index bd3671a..607fa8f 100644 +--- a/src/sync.c ++++ b/src/sync.c +@@ -111,8 +111,10 @@ sync_arg (enum sync_mode mode, char const *file) + if (open_flags != (O_WRONLY | O_NONBLOCK)) + fd = open (file, O_WRONLY | O_NONBLOCK); + if (fd < 0) +- error (0, rd_errno, _("error opening %s"), quoteaf (file)); +- return false; ++ { ++ error (0, rd_errno, _("error opening %s"), quoteaf (file)); ++ return false; ++ } + } + + /* We used O_NONBLOCK above to not hang with fifos, +-- +2.17.2 + + +From e62ff3068f1f1b1e84d3319f54f1b869bb0bf6cc Mon Sep 17 00:00:00 2001 +From: Bernhard Voelker +Date: Wed, 7 Nov 2018 00:26:01 +0100 +Subject: [PATCH 2/2] sync: add test for the fix in the previous commit + +* tests/misc/sync.sh: Add a test with a write-only file for the fix. + +Upstream-commit: 4711c49312d54e84996c13c612f7081c95f821a6 +Signed-off-by: Kamil Dudka +--- + tests/misc/sync.sh | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/tests/misc/sync.sh b/tests/misc/sync.sh +index f60d28c..3bb6e17 100755 +--- a/tests/misc/sync.sh ++++ b/tests/misc/sync.sh +@@ -19,7 +19,7 @@ + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ sync + +-touch file ++touch file || framework_failure_ + + # fdatasync+syncfs is nonsensical + returns_ 1 sync --data --file-system || fail=1 +@@ -30,6 +30,11 @@ returns_ 1 sync -d || fail=1 + # Test syncing of file (fsync) (little side effects) + sync file || fail=1 + ++# Test syncing of write-only file - which failed since adding argument ++# support to sync in coreutils-8.24. ++chmod 0200 file || framework_failure_ ++sync file || fail=1 ++ + # Ensure multiple args are processed and diagnosed + returns_ 1 sync file nofile || fail=1 + +-- +2.17.2 + diff --git a/coreutils.spec b/coreutils.spec index 51dbe1a..3531712 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -20,6 +20,9 @@ Patch1: coreutils-8.30-renameatu.patch # fix heap-based buffer overflow in vasnprintf() (CVE-2018-17942) Patch2: coreutils-8.30-CVE-2018-17942.patch +# sync: fix open() fallback bug +Patch3: coreutils-8.30-fsync-fallback.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -242,6 +245,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Wed Nov 07 2018 Kamil Dudka - 8.30-8 +- sync: fix open() fallback bug - fix implicit declaration warning in coreutils-getgrouplist.patch * Sat Nov 03 2018 Kevin Fenzi - 8.30-7 From df169bbdadc9f8a64cdcbbee1d42448ac57ceba3 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Mon, 28 Jan 2019 20:17:41 +0100 Subject: [PATCH 390/523] Remove obsolete Group tag References: https://fedoraproject.org/wiki/Changes/Remove_Group_Tag --- coreutils.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 3531712..b1cc033 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -3,7 +3,6 @@ Name: coreutils Version: 8.30 Release: 8%{?dist} License: GPLv3+ -Group: System Environment/Base Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source50: supported_utils From 30ec1629e9b586264ca76f9e684ea04438d18c94 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 31 Jan 2019 16:17:52 +0000 Subject: [PATCH 391/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index b1cc033..26b57f7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.30 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -243,6 +243,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jan 31 2019 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + * Wed Nov 07 2018 Kamil Dudka - 8.30-8 - sync: fix open() fallback bug - fix implicit declaration warning in coreutils-getgrouplist.patch From 5637e2b27410c4c231adb46719fb213fd3d9a407 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 11 Mar 2019 11:40:45 +0100 Subject: [PATCH 392/523] new upstream release 8.31 --- coreutils-8.25-DIR_COLORS.patch | 29 +- coreutils-8.30-CVE-2018-17942.patch | 69 ---- coreutils-8.30-fsync-fallback.patch | 77 ---- coreutils-8.30-renameatu.patch | 451 --------------------- coreutils-8.30.tar.xz.sig | 17 - coreutils-8.31.tar.xz.sig | 17 + coreutils-8.5-dircolors.patch | 13 - coreutils-i18n-cut.patch | 587 ---------------------------- coreutils-i18n.patch | 64 +-- coreutils.spec | 16 +- sources | 2 +- supported_utils | 1 + 12 files changed, 69 insertions(+), 1274 deletions(-) delete mode 100644 coreutils-8.30-CVE-2018-17942.patch delete mode 100644 coreutils-8.30-fsync-fallback.patch delete mode 100644 coreutils-8.30-renameatu.patch delete mode 100644 coreutils-8.30.tar.xz.sig create mode 100644 coreutils-8.31.tar.xz.sig delete mode 100644 coreutils-8.5-dircolors.patch delete mode 100644 coreutils-i18n-cut.patch diff --git a/coreutils-8.25-DIR_COLORS.patch b/coreutils-8.25-DIR_COLORS.patch index 5490258..59674bc 100644 --- a/coreutils-8.25-DIR_COLORS.patch +++ b/coreutils-8.25-DIR_COLORS.patch @@ -13,17 +13,14 @@ diff --git a/DIR_COLORS b/DIR_COLORS index d2ea453..27af9d7 100644 --- a/DIR_COLORS +++ b/DIR_COLORS -@@ -1,6 +1,10 @@ - # Configuration file for dircolors, a utility to help you set the - # LS_COLORS environment variable used by GNU ls with the --color option. - +@@ -1,3 +1,7 @@ +# This file goes in the /etc directory, and must be world readable. +# You can copy this file to .dir_colors in your $HOME directory to override +# the system defaults. + - # Copyright (C) 1996-2018 Free Software Foundation, Inc. - # Copying and distribution of this file, with or without modification, - # are permitted provided the copyright notice and this notice are preserved. + # Configuration file for dircolors, a utility to help you set the + # LS_COLORS environment variable used by GNU ls with the --color option. + @@ -8,6 +12,9 @@ # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the # slackware version of dircolors) are recognized but ignored. @@ -34,7 +31,7 @@ index d2ea453..27af9d7 100644 # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. TERM Eterm -@@ -56,7 +63,7 @@ DOOR 01;35 # door +@@ -58,7 +65,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -43,7 +40,7 @@ index d2ea453..27af9d7 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -184,21 +191,21 @@ EXEC 01;32 +@@ -186,21 +193,21 @@ EXEC 01;32 .ogx 01;35 # audio formats @@ -131,9 +128,9 @@ index d2ea453..74c34ba 100644 +TERM *256color* +TERM rxvt-unicode256 - # Below are the color init strings for the basic file types. A color init - # string consists of one or more of the following numeric codes: -@@ -43,29 +30,40 @@ TERM xterm* + # Below are the color init strings for the basic file types. + # One can use codes for 256 or more colors supported by modern terminals. +@@ -45,29 +32,40 @@ TERM xterm* # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white # Background color codes: # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white @@ -190,7 +187,7 @@ index d2ea453..74c34ba 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -83,122 +81,122 @@ EXEC 01;32 +@@ -85,122 +83,122 @@ EXEC 01;32 #.csh 01;32 # archives or compressed (bright red) @@ -448,7 +445,7 @@ index d2ea453..95d6879 100644 # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. TERM Eterm -@@ -46,17 +55,17 @@ TERM xterm* +@@ -48,17 +57,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -471,7 +468,7 @@ index d2ea453..95d6879 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -65,7 +74,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +@@ -67,7 +76,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: @@ -480,7 +477,7 @@ index d2ea453..95d6879 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -83,105 +92,105 @@ EXEC 01;32 +@@ -85,105 +94,105 @@ EXEC 01;32 #.csh 01;32 # archives or compressed (bright red) diff --git a/coreutils-8.30-CVE-2018-17942.patch b/coreutils-8.30-CVE-2018-17942.patch deleted file mode 100644 index 409fe0c..0000000 --- a/coreutils-8.30-CVE-2018-17942.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 6d059cebfdefbdf56910a858f8b603d37f10ef6d Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Sun, 23 Sep 2018 14:13:52 +0200 -Subject: [PATCH] vasnprintf: Fix heap memory overrun bug. - -Reported by Ben Pfaff in -. - -* lib/vasnprintf.c (convert_to_decimal): Allocate one more byte of -memory. -* tests/test-vasnprintf.c (test_function): Add another test. - -Upstream-commit: 278b4175c9d7dd47c1a3071554aac02add3b3c35 -Signed-off-by: Kamil Dudka ---- - gnulib-tests/test-vasnprintf.c | 21 ++++++++++++++++++++- - lib/vasnprintf.c | 4 +++- - 2 files changed, 23 insertions(+), 2 deletions(-) - -diff --git a/gnulib-tests/test-vasnprintf.c b/gnulib-tests/test-vasnprintf.c -index 19731bc..93d81d7 100644 ---- a/gnulib-tests/test-vasnprintf.c -+++ b/gnulib-tests/test-vasnprintf.c -@@ -53,7 +53,26 @@ test_function (char * (*my_asnprintf) (char *, size_t *, const char *, ...)) - ASSERT (result != NULL); - ASSERT (strcmp (result, "12345") == 0); - ASSERT (length == 5); -- if (size < 6) -+ if (size < 5 + 1) -+ ASSERT (result != buf); -+ ASSERT (memcmp (buf + size, &"DEADBEEF"[size], 8 - size) == 0); -+ if (result != buf) -+ free (result); -+ } -+ -+ /* Note: This test assumes IEEE 754 representation of 'double' floats. */ -+ for (size = 0; size <= 8; size++) -+ { -+ size_t length; -+ char *result; -+ -+ memcpy (buf, "DEADBEEF", 8); -+ length = size; -+ result = my_asnprintf (buf, &length, "%2.0f", 1.6314159265358979e+125); -+ ASSERT (result != NULL); -+ ASSERT (strcmp (result, "163141592653589790215729350939528493057529598899734151772468186268423257777068536614838678161083520756952076273094236944990208") == 0); -+ ASSERT (length == 126); -+ if (size < 126 + 1) - ASSERT (result != buf); - ASSERT (memcmp (buf + size, &"DEADBEEF"[size], 8 - size) == 0); - if (result != buf) -diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c -index 3b441d0..48ef7a6 100644 ---- a/lib/vasnprintf.c -+++ b/lib/vasnprintf.c -@@ -860,7 +860,9 @@ convert_to_decimal (mpn_t a, size_t extra_zeroes) - size_t a_len = a.nlimbs; - /* 0.03345 is slightly larger than log(2)/(9*log(10)). */ - size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1); -- char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes)); -+ /* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the -+ digits of a, followed by 1 byte for the terminating NUL. */ -+ char *c_ptr = (char *) malloc (xsum (xsum (extra_zeroes, c_len), 1)); - if (c_ptr != NULL) - { - char *d_ptr = c_ptr; --- -2.17.1 - diff --git a/coreutils-8.30-fsync-fallback.patch b/coreutils-8.30-fsync-fallback.patch deleted file mode 100644 index 110da10..0000000 --- a/coreutils-8.30-fsync-fallback.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 2eabfbee57be82f755c74cbb05755dce1469ea7c Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Tue, 6 Nov 2018 10:35:16 -0800 -Subject: [PATCH 1/2] sync: fix open fallback bug - -Problem caught by Coverity Analysis -and reported by Kamil Dudka (Bug#33287). -* src/sync.c (sync_arg): Fix typo in fallback code. - -Upstream-commit: 94d364f157f007f2b23c70863ac8eefe9b21229d -Signed-off-by: Kamil Dudka ---- - src/sync.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/sync.c b/src/sync.c -index bd3671a..607fa8f 100644 ---- a/src/sync.c -+++ b/src/sync.c -@@ -111,8 +111,10 @@ sync_arg (enum sync_mode mode, char const *file) - if (open_flags != (O_WRONLY | O_NONBLOCK)) - fd = open (file, O_WRONLY | O_NONBLOCK); - if (fd < 0) -- error (0, rd_errno, _("error opening %s"), quoteaf (file)); -- return false; -+ { -+ error (0, rd_errno, _("error opening %s"), quoteaf (file)); -+ return false; -+ } - } - - /* We used O_NONBLOCK above to not hang with fifos, --- -2.17.2 - - -From e62ff3068f1f1b1e84d3319f54f1b869bb0bf6cc Mon Sep 17 00:00:00 2001 -From: Bernhard Voelker -Date: Wed, 7 Nov 2018 00:26:01 +0100 -Subject: [PATCH 2/2] sync: add test for the fix in the previous commit - -* tests/misc/sync.sh: Add a test with a write-only file for the fix. - -Upstream-commit: 4711c49312d54e84996c13c612f7081c95f821a6 -Signed-off-by: Kamil Dudka ---- - tests/misc/sync.sh | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/tests/misc/sync.sh b/tests/misc/sync.sh -index f60d28c..3bb6e17 100755 ---- a/tests/misc/sync.sh -+++ b/tests/misc/sync.sh -@@ -19,7 +19,7 @@ - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ sync - --touch file -+touch file || framework_failure_ - - # fdatasync+syncfs is nonsensical - returns_ 1 sync --data --file-system || fail=1 -@@ -30,6 +30,11 @@ returns_ 1 sync -d || fail=1 - # Test syncing of file (fsync) (little side effects) - sync file || fail=1 - -+# Test syncing of write-only file - which failed since adding argument -+# support to sync in coreutils-8.24. -+chmod 0200 file || framework_failure_ -+sync file || fail=1 -+ - # Ensure multiple args are processed and diagnosed - returns_ 1 sync file nofile || fail=1 - --- -2.17.2 - diff --git a/coreutils-8.30-renameatu.patch b/coreutils-8.30-renameatu.patch deleted file mode 100644 index a5aa48f..0000000 --- a/coreutils-8.30-renameatu.patch +++ /dev/null @@ -1,451 +0,0 @@ -From 57ee8db4fee8eb6772df1ff18d275594c0b034d4 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 5 Jul 2018 09:22:09 -0700 -Subject: [PATCH 1/2] renameatu: rename from renameat2 - -It's looking like Glibc will add a renameat2 function -that is incompatible with Gnulib renameat2; see: -https://sourceware.org/ml/libc-alpha/2018-07/msg00064.html -To help avoid future confusion, rename renameat2 to something else. -Use the name 'renameatu', as the Gnulib function is close to the -Glibc function. Perhaps someday there will also be a renameat2 -Gnulib module, which mimicks the future glibc renameat2, but that -can wait as nobody seems to need such a module now. -* NEWS: Mention this. -* lib/renameatu.c: Rename from lib/renameat2.c. -* lib/renameatu.h: Rename from lib/renameat2.h. -* modules/renameatu: Rename from modules/renameat2. -* modules/renameatu-tests: Rename from modules/renameat2-tests. -All uses of "renameat2" in identifiers or file name -changed to "renameatu", except for two instances in -lib/renameatu.c that deal with the Linux kernel's -renameat2 syscall. - -Upstream-commit: 2522322e5304e7d86c63e607e2bc83c8d8b0a889 -Signed-off-by: Kamil Dudka ---- - gnulib-tests/gnulib.mk | 12 +++--- - .../{test-renameat2.c => test-renameatu.c} | 48 +++++++++++----------- - lib/backupfile.c | 4 +- - lib/gnulib.mk | 10 ++--- - lib/renameat.c | 4 +- - lib/{renameat2.c => renameatu.c} | 9 ++-- - lib/{renameat2.h => renameatu.h} | 8 ++-- - 7 files changed, 48 insertions(+), 47 deletions(-) - rename gnulib-tests/{test-renameat2.c => test-renameatu.c} (80%) - rename lib/{renameat2.c => renameatu.c} (94%) - rename lib/{renameat2.h => renameatu.h} (84%) - -diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk -index be2b99e..891425b 100644 ---- a/gnulib-tests/gnulib.mk -+++ b/gnulib-tests/gnulib.mk -@@ -1750,14 +1750,14 @@ EXTRA_DIST += test-rename.h test-renameat.c signature.h macros.h - - ## end gnulib module renameat-tests - --## begin gnulib module renameat2-tests -+## begin gnulib module renameatu-tests - --TESTS += test-renameat2 --check_PROGRAMS += test-renameat2 --test_renameat2_LDADD = $(LDADD) @LIBINTL@ --EXTRA_DIST += test-rename.h test-renameat2.c signature.h macros.h -+TESTS += test-renameatu -+check_PROGRAMS += test-renameatu -+test_renameatu_LDADD = $(LDADD) @LIBINTL@ -+EXTRA_DIST += test-rename.h test-renameatu.c signature.h macros.h - --## end gnulib module renameat2-tests -+## end gnulib module renameatu-tests - - ## begin gnulib module rmdir-tests - -diff --git a/gnulib-tests/test-renameat2.c b/gnulib-tests/test-renameatu.c -similarity index 80% -rename from gnulib-tests/test-renameat2.c -rename to gnulib-tests/test-renameatu.c -index 0104890..988428b 100644 ---- a/gnulib-tests/test-renameat2.c -+++ b/gnulib-tests/test-renameatu.c -@@ -1,4 +1,4 @@ --/* Test renameat2. -+/* Test renameatu. - Copyright (C) 2009-2018 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify -@@ -18,12 +18,12 @@ - - #include - --#include -+#include - - #include - - #include "signature.h" --SIGNATURE_CHECK (renameat2, int, -+SIGNATURE_CHECK (renameatu, int, - (int, char const *, int, char const *, unsigned int)); - - #include -@@ -39,18 +39,18 @@ SIGNATURE_CHECK (renameat2, int, - #include "ignore-value.h" - #include "macros.h" - --#define BASE "test-renameat2.t" -+#define BASE "test-renameatu.t" - - #include "test-rename.h" - - static int dfd1 = AT_FDCWD; - static int dfd2 = AT_FDCWD; - --/* Wrapper to test renameat2 like rename. */ -+/* Wrapper to test renameatu like rename. */ - static int - do_rename (char const *name1, char const *name2) - { -- return renameat2 (dfd1, name1, dfd2, name2, 0); -+ return renameatu (dfd1, name1, dfd2, name2, 0); - } - - int -@@ -67,24 +67,24 @@ main (void) - /* Test behaviour for invalid file descriptors. */ - { - errno = 0; -- ASSERT (renameat2 (-1, "foo", AT_FDCWD, "bar", 0) == -1); -+ ASSERT (renameatu (-1, "foo", AT_FDCWD, "bar", 0) == -1); - ASSERT (errno == EBADF); - } - { - close (99); - errno = 0; -- ASSERT (renameat2 (99, "foo", AT_FDCWD, "bar", 0) == -1); -+ ASSERT (renameatu (99, "foo", AT_FDCWD, "bar", 0) == -1); - ASSERT (errno == EBADF); - } - ASSERT (close (creat (BASE "oo", 0600)) == 0); - { - errno = 0; -- ASSERT (renameat2 (AT_FDCWD, BASE "oo", -1, "bar", 0) == -1); -+ ASSERT (renameatu (AT_FDCWD, BASE "oo", -1, "bar", 0) == -1); - ASSERT (errno == EBADF); - } - { - errno = 0; -- ASSERT (renameat2 (AT_FDCWD, BASE "oo", 99, "bar", 0) == -1); -+ ASSERT (renameatu (AT_FDCWD, BASE "oo", 99, "bar", 0) == -1); - ASSERT (errno == EBADF); - } - ASSERT (unlink (BASE "oo") == 0); -@@ -133,13 +133,13 @@ main (void) - - ASSERT (sprintf (strchr (file1, '\0') - 2, "%02d", i) == 2); - ASSERT (sprintf (strchr (file2, '\0') - 2, "%02d", i + 1) == 2); -- ASSERT (renameat2 (fd1, file1, fd2, file2, 0) == 0); -+ ASSERT (renameatu (fd1, file1, fd2, file2, 0) == 0); - free (file1); - free (file2); - } - dfd2 = open ("..", O_RDONLY); - ASSERT (0 <= dfd2); -- ASSERT (renameat2 (dfd, "../" BASE "16", dfd2, BASE "17", 0) == 0); -+ ASSERT (renameatu (dfd, "../" BASE "16", dfd2, BASE "17", 0) == 0); - ASSERT (close (dfd2) == 0); - - /* Now we change back to the parent directory, and set dfd to "."; -@@ -152,47 +152,47 @@ main (void) - - ASSERT (close (creat (BASE "sub2/file", 0600)) == 0); - errno = 0; -- ASSERT (renameat2 (dfd, BASE "sub1", dfd, BASE "sub2", 0) == -1); -+ ASSERT (renameatu (dfd, BASE "sub1", dfd, BASE "sub2", 0) == -1); - ASSERT (errno == EEXIST || errno == ENOTEMPTY); - ASSERT (unlink (BASE "sub2/file") == 0); - errno = 0; -- ASSERT (renameat2 (dfd, BASE "sub2", dfd, BASE "sub1/.", 0) == -1); -+ ASSERT (renameatu (dfd, BASE "sub2", dfd, BASE "sub1/.", 0) == -1); - ASSERT (errno == EINVAL || errno == EISDIR || errno == EBUSY - || errno == ENOTEMPTY || errno == EEXIST - || errno == ENOENT /* WSL */); - errno = 0; -- ASSERT (renameat2 (dfd, BASE "sub2/.", dfd, BASE "sub1", 0) == -1); -+ ASSERT (renameatu (dfd, BASE "sub2/.", dfd, BASE "sub1", 0) == -1); - ASSERT (errno == EINVAL || errno == EBUSY || errno == EEXIST - || errno == ENOENT /* WSL */); - errno = 0; -- ASSERT (renameat2 (dfd, BASE "17", dfd, BASE "sub1", 0) == -1); -+ ASSERT (renameatu (dfd, BASE "17", dfd, BASE "sub1", 0) == -1); - ASSERT (errno == EISDIR); - errno = 0; -- ASSERT (renameat2 (dfd, BASE "nosuch", dfd, BASE "18", 0) == -1); -+ ASSERT (renameatu (dfd, BASE "nosuch", dfd, BASE "18", 0) == -1); - ASSERT (errno == ENOENT); - errno = 0; -- ASSERT (renameat2 (dfd, "", dfd, BASE "17", 0) == -1); -+ ASSERT (renameatu (dfd, "", dfd, BASE "17", 0) == -1); - ASSERT (errno == ENOENT); - errno = 0; -- ASSERT (renameat2 (dfd, BASE "17", dfd, "", 0) == -1); -+ ASSERT (renameatu (dfd, BASE "17", dfd, "", 0) == -1); - ASSERT (errno == ENOENT); - errno = 0; -- ASSERT (renameat2 (dfd, BASE "sub2", dfd, BASE "17", 0) == -1); -+ ASSERT (renameatu (dfd, BASE "sub2", dfd, BASE "17", 0) == -1); - ASSERT (errno == ENOTDIR); - errno = 0; -- ASSERT (renameat2 (dfd, BASE "17/", dfd, BASE "18", 0) == -1); -+ ASSERT (renameatu (dfd, BASE "17/", dfd, BASE "18", 0) == -1); - ASSERT (errno == ENOTDIR); - errno = 0; -- ASSERT (renameat2 (dfd, BASE "17", dfd, BASE "18/", 0) == -1); -+ ASSERT (renameatu (dfd, BASE "17", dfd, BASE "18/", 0) == -1); - ASSERT (errno == ENOTDIR || errno == ENOENT); - - /* Finally, make sure we cannot overwrite existing files. */ - ASSERT (close (creat (BASE "sub2/file", 0600)) == 0); - errno = 0; -- ASSERT ((renameat2 (dfd, BASE "sub2", dfd, BASE "sub1", RENAME_NOREPLACE) -+ ASSERT ((renameatu (dfd, BASE "sub2", dfd, BASE "sub1", RENAME_NOREPLACE) - == -1) - && errno == EEXIST); -- ASSERT ((renameat2 (dfd, BASE "sub2/file", dfd, BASE "17", RENAME_NOREPLACE) -+ ASSERT ((renameatu (dfd, BASE "sub2/file", dfd, BASE "17", RENAME_NOREPLACE) - == -1) - && errno == EEXIST); - -diff --git a/lib/backupfile.c b/lib/backupfile.c -index d438455..637be6c 100644 ---- a/lib/backupfile.c -+++ b/lib/backupfile.c -@@ -23,7 +23,7 @@ - #include "backup-internal.h" - - #include "dirname.h" --#include "renameat2.h" -+#include "renameatu.h" - #include "xalloc-oversized.h" - - #include -@@ -353,7 +353,7 @@ backupfile_internal (char const *file, enum backup_type backup_type, bool rename - base_offset = 0; - } - unsigned flags = backup_type == simple_backups ? 0 : RENAME_NOREPLACE; -- if (renameat2 (AT_FDCWD, file, sdir, s + base_offset, flags) == 0) -+ if (renameatu (AT_FDCWD, file, sdir, s + base_offset, flags) == 0) - break; - int e = errno; - if (e != EEXIST) -diff --git a/lib/gnulib.mk b/lib/gnulib.mk -index 04473d5..0b747e3 100644 ---- a/lib/gnulib.mk -+++ b/lib/gnulib.mk -@@ -21,7 +21,7 @@ - # the same distribution terms as the rest of that program. - # - # Generated by gnulib-tool. --# Reproduce by: gnulib-tool --import --local-dir=gl --lib=libcoreutils --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=gnulib-tests --aux-dir=build-aux --with-tests --avoid=canonicalize-lgpl --avoid=dummy --makefile-name=gnulib.mk --no-conditional-dependencies --no-libtool --macro-prefix=gl acl alignof alloca announce-gen areadlink-with-size argmatch argv-iter assert autobuild backup-rename backupfile base32 base64 buffer-lcm c-strcase c-strtod c-strtold calloc-gnu canon-host canonicalize chown cloexec closein closeout config-h configmake crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 cycle-check d-ino d-type di-set diacrit dirfd dirname do-release-commit-and-tag dtoastr dup2 environ error euidaccess exclude exitfail explicit_bzero faccessat fadvise fchdir fchmodat fchownat fclose fcntl fcntl-safer fd-reopen fdatasync fdl fdopen fdutimensat file-has-acl file-type fileblocks filemode filenamecat filevercmp flexmember fnmatch-gnu fopen-safer fprintftime freopen freopen-safer fseeko fstatat fsusage fsync ftoastr ftruncate fts full-read full-write getgroups gethrxtime getline getloadavg getlogin getndelim2 getopt-gnu getpagesize getpass-gnu gettext-h gettime gettimeofday getugroups getusershell git-version-gen gitlog-to-changelog gnu-make gnu-web-doc-update gnumakefile gnupload group-member hard-locale hash hash-pjw heap host-os human idcache ignore-value inttostr inttypes isapipe isatty isblank largefile lchmod lchown ldtoastr lib-ignore linebuffer link link-follow linkat long-options lstat maintainer-makefile malloc-gnu manywarnings mbrlen mbrtowc mbsalign mbschr mbslen mbswidth memcasecmp memchr memcmp2 mempcpy memrchr mgetgroups mkancesdirs mkdir mkdir-p mkfifo mknod mkostemp mkstemp mktime modechange mountlist mpsort netinet_in non-recursive-gnulib-prefix-hack nproc nstrftime obstack open parse-datetime pathmax perl physmem pipe-posix pipe2 posix-shell posixtm posixver priv-set progname propername pthread putenv quote quotearg randint randperm read-file readlink readtokens readtokens0 readutmp realloc-gnu regex remove rename renameat renameat2 rmdir root-dev-ino rpmatch safe-read same save-cwd savedir savewd selinux-at setenv settime sig2str sigaction smack ssize_t stat-macros stat-size stat-time statat stdbool stdlib-safer stpcpy stpncpy strdup-posix strncat strnumcmp strsignal strtod strtoimax strtoumax symlinkat sys_ioctl sys_resource sys_stat sys_wait tempname termios time_rz timer-time timespec tzset uname unicodeio unistd-safer unlink-busy unlinkat unlocked-io unsetenv update-copyright uptime useless-if-before-free userspec utimecmp utimens vasprintf-posix vc-list-files verify verror version-etc-fsf wchar-single wcswidth wcwidth winsz-ioctl winsz-termios write-any-file xalloc xbinary-io xdectoint xfts xgetcwd xgetgroups xgethostname xmemcoll xnanosleep xprintf xprintf-posix xreadlink xstrtod xstrtoimax xstrtol xstrtold xstrtoumax year2038 yesno -+# Reproduce by: gnulib-tool --import --local-dir=gl --lib=libcoreutils --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=gnulib-tests --aux-dir=build-aux --with-tests --avoid=canonicalize-lgpl --avoid=dummy --makefile-name=gnulib.mk --no-conditional-dependencies --no-libtool --macro-prefix=gl acl alignof alloca announce-gen areadlink-with-size argmatch argv-iter assert autobuild backup-rename backupfile base32 base64 buffer-lcm c-strcase c-strtod c-strtold calloc-gnu canon-host canonicalize chown cloexec closein closeout config-h configmake crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 cycle-check d-ino d-type di-set diacrit dirfd dirname do-release-commit-and-tag dtoastr dup2 environ error euidaccess exclude exitfail explicit_bzero faccessat fadvise fchdir fchmodat fchownat fclose fcntl fcntl-safer fd-reopen fdatasync fdl fdopen fdutimensat file-has-acl file-type fileblocks filemode filenamecat filevercmp flexmember fnmatch-gnu fopen-safer fprintftime freopen freopen-safer fseeko fstatat fsusage fsync ftoastr ftruncate fts full-read full-write getgroups gethrxtime getline getloadavg getlogin getndelim2 getopt-gnu getpagesize getpass-gnu gettext-h gettime gettimeofday getugroups getusershell git-version-gen gitlog-to-changelog gnu-make gnu-web-doc-update gnumakefile gnupload group-member hard-locale hash hash-pjw heap host-os human idcache ignore-value inttostr inttypes isapipe isatty isblank largefile lchmod lchown ldtoastr lib-ignore linebuffer link link-follow linkat long-options lstat maintainer-makefile malloc-gnu manywarnings mbrlen mbrtowc mbsalign mbschr mbslen mbswidth memcasecmp memchr memcmp2 mempcpy memrchr mgetgroups mkancesdirs mkdir mkdir-p mkfifo mknod mkostemp mkstemp mktime modechange mountlist mpsort netinet_in non-recursive-gnulib-prefix-hack nproc nstrftime obstack open parse-datetime pathmax perl physmem pipe-posix pipe2 posix-shell posixtm posixver priv-set progname propername pthread putenv quote quotearg randint randperm read-file readlink readtokens readtokens0 readutmp realloc-gnu regex remove rename renameat renameatu rmdir root-dev-ino rpmatch safe-read same save-cwd savedir savewd selinux-at setenv settime sig2str sigaction smack ssize_t stat-macros stat-size stat-time statat stdbool stdlib-safer stpcpy stpncpy strdup-posix strncat strnumcmp strsignal strtod strtoimax strtoumax symlinkat sys_ioctl sys_resource sys_stat sys_wait tempname termios time_rz timer-time timespec tzset uname unicodeio unistd-safer unlink-busy unlinkat unlocked-io unsetenv update-copyright uptime useless-if-before-free userspec utimecmp utimens vasprintf-posix vc-list-files verify verror version-etc-fsf wchar-single wcswidth wcwidth winsz-ioctl winsz-termios write-any-file xalloc xbinary-io xdectoint xfts xgetcwd xgetgroups xgethostname xmemcoll xnanosleep xprintf xprintf-posix xreadlink xstrtod xstrtoimax xstrtol xstrtold xstrtoumax year2038 yesno - - - MOSTLYCLEANFILES += lib/core lib/*.stackdump -@@ -3218,15 +3218,15 @@ EXTRA_lib_libcoreutils_a_SOURCES += lib/renameat.c - - ## end gnulib module renameat - --## begin gnulib module renameat2 -+## begin gnulib module renameatu - --lib_libcoreutils_a_SOURCES += lib/renameat2.c -+lib_libcoreutils_a_SOURCES += lib/renameatu.c - --EXTRA_DIST += lib/at-func2.c lib/renameat2.h -+EXTRA_DIST += lib/at-func2.c lib/renameatu.h - - EXTRA_lib_libcoreutils_a_SOURCES += lib/at-func2.c - --## end gnulib module renameat2 -+## end gnulib module renameatu - - ## begin gnulib module rewinddir - -diff --git a/lib/renameat.c b/lib/renameat.c -index 0cb7d33..67be22b 100644 ---- a/lib/renameat.c -+++ b/lib/renameat.c -@@ -16,10 +16,10 @@ - - #include - #include --#include "renameat2.h" -+#include "renameatu.h" - - int - renameat (int fd1, char const *src, int fd2, char const *dst) - { -- return renameat2 (fd1, src, fd2, dst, 0); -+ return renameatu (fd1, src, fd2, dst, 0); - } -diff --git a/lib/renameat2.c b/lib/renameatu.c -similarity index 94% -rename from lib/renameat2.c -rename to lib/renameatu.c -index a295ec3..b013ad6 100644 ---- a/lib/renameat2.c -+++ b/lib/renameatu.c -@@ -18,7 +18,7 @@ - - #include - --#include "renameat2.h" -+#include "renameatu.h" - - #include - #include -@@ -68,10 +68,13 @@ rename_noreplace (char const *src, char const *dst) - the restore_cwd fails, then give a diagnostic and exit nonzero. - - Obey FLAGS when doing the renaming. If FLAGS is zero, this -- function is equivalent to renameat (FD1, SRC, FD2, DST). */ -+ function is equivalent to renameat (FD1, SRC, FD2, DST). -+ Otherwise, attempt to implement FLAGS even if the implementation is -+ not atomic; this differs from the GNU/Linux native renameat2, -+ which fails if it cannot guarantee atomicity. */ - - int --renameat2 (int fd1, char const *src, int fd2, char const *dst, -+renameatu (int fd1, char const *src, int fd2, char const *dst, - unsigned int flags) - { - int ret_val = -1; -diff --git a/lib/renameat2.h b/lib/renameatu.h -similarity index 84% -rename from lib/renameat2.h -rename to lib/renameatu.h -index aba7966..7d79775 100644 ---- a/lib/renameat2.h -+++ b/lib/renameatu.h -@@ -16,15 +16,13 @@ - - /* written by Paul Eggert */ - --/* Get RENAME_* macros from linux/fs.h if present, otherwise supply -+/* Get RENAME_* macros from if present, otherwise supply - the traditional Linux values. */ --#if HAVE_LINUX_FS_H --# include --#endif -+#include - #ifndef RENAME_NOREPLACE - # define RENAME_NOREPLACE (1 << 0) - # define RENAME_EXCHANGE (1 << 1) - # define RENAME_WHITEOUT (1 << 2) - #endif - --extern int renameat2 (int, char const *, int, char const *, unsigned int); -+extern int renameatu (int, char const *, int, char const *, unsigned int); --- -2.14.4 - - -From a6b7ff5ef538bbdff4550a56fed878e9cd951d6d Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 5 Jul 2018 09:33:48 -0700 -Subject: [PATCH 2/2] build: update gnulib submodule to latest - -* bootstrap.conf, src/copy.c, src/mv.c, src/shred.c: -Adjust to renaming of renameat2 to renameatu. - -Upstream-commit: 439741053256618eb651e6d43919df29625b8714 -Signed-off-by: Kamil Dudka ---- - bootstrap.conf | 2 +- - src/copy.c | 4 ++-- - src/mv.c | 4 ++-- - src/shred.c | 4 ++-- - 4 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/bootstrap.conf b/bootstrap.conf -index 4da4f94..fcf29dc 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -210,7 +210,7 @@ gnulib_modules=" - remove - rename - renameat -- renameat2 -+ renameatu - rmdir - root-dev-ino - rpmatch -diff --git a/src/copy.c b/src/copy.c -index 58d2f6e..1a9cdd1 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -53,7 +53,7 @@ - #include "ignore-value.h" - #include "ioblksize.h" - #include "quote.h" --#include "renameat2.h" -+#include "renameatu.h" - #include "root-uid.h" - #include "same.h" - #include "savedir.h" -@@ -1873,7 +1873,7 @@ copy_internal (char const *src_name, char const *dst_name, - if (x->move_mode) - { - if (rename_errno < 0) -- rename_errno = (renameat2 (AT_FDCWD, src_name, AT_FDCWD, dst_name, -+ rename_errno = (renameatu (AT_FDCWD, src_name, AT_FDCWD, dst_name, - RENAME_NOREPLACE) - ? errno : 0); - new_dst = rename_errno == 0; -diff --git a/src/mv.c b/src/mv.c -index b6dd72d..36fd1af 100644 ---- a/src/mv.c -+++ b/src/mv.c -@@ -31,7 +31,7 @@ - #include "error.h" - #include "filenamecat.h" - #include "remove.h" --#include "renameat2.h" -+#include "renameatu.h" - #include "root-dev-ino.h" - #include "priv-set.h" - -@@ -456,7 +456,7 @@ main (int argc, char **argv) - { - assert (2 <= n_files); - if (n_files == 2) -- x.rename_errno = (renameat2 (AT_FDCWD, file[0], AT_FDCWD, file[1], -+ x.rename_errno = (renameatu (AT_FDCWD, file[0], AT_FDCWD, file[1], - RENAME_NOREPLACE) - ? errno : 0); - if (x.rename_errno != 0 && target_directory_operand (file[n_files - 1])) -diff --git a/src/shred.c b/src/shred.c -index 2ddaadd..270b1e9 100644 ---- a/src/shred.c -+++ b/src/shred.c -@@ -93,7 +93,7 @@ - #include "human.h" - #include "randint.h" - #include "randread.h" --#include "renameat2.h" -+#include "renameatu.h" - #include "stat-size.h" - - /* Default number of times to overwrite. */ -@@ -1096,7 +1096,7 @@ wipename (char *oldname, char const *qoldname, struct Options const *flags) - memset (base, nameset[0], len); - base[len] = 0; - bool rename_ok; -- while (! (rename_ok = (renameat2 (AT_FDCWD, oldname, AT_FDCWD, newname, -+ while (! (rename_ok = (renameatu (AT_FDCWD, oldname, AT_FDCWD, newname, - RENAME_NOREPLACE) - == 0)) - && errno == EEXIST && incname (base, len)) --- -2.14.4 - diff --git a/coreutils-8.30.tar.xz.sig b/coreutils-8.30.tar.xz.sig deleted file mode 100644 index 34681ce..0000000 --- a/coreutils-8.30.tar.xz.sig +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2 - -iQIcBAABCAAGBQJbOYLXAAoJEN9v2XEwYDfZFRwP/1xKMtXTqCOnP3ECRze+bYnX -GB5Mm57kcP2NXwzo62+9C+FToEfkRTALtlU95edIRlsjLGBoDvv12fsOKdsyO/c5 -7paI3NoaUFyJxby9w91mNOcgN6eR5WZ/LHm2VbTs5VFpsNcSVyHSvhiqgPXtRrVp -ZrnUKbg9iWjn8jcJHIS7qrIO4GsoFzfhn9gVh8Xxp4AYx0btn3BwPTWCxg53Ie0p -OgrMmMnOe3wrpwrlJOgfvpk5na7yKRt7GYsyGMaKB7OxbHlVg4UCx4LuRBnaUPZr -QmlX37sIR/sEJne0zR4iMorPi5IsErMT39VaBDLnsAjyccbmYQ/RmFYASiM5Zijw -d94fk+TocyDBrOMsO5fzKUID5Uf4c5vJlhCXBsPBykNiKsQTb3M7fZ+gjYrMJmoS -4DDgAMryoB5yc2i9HcNj8WMNHy4RGIrRWxOAUZf5j2zEEVwKaRcoNosFoycUotEA -yoWdRIwyCkVwlemVhx0zQTm8WbtFl0kkAFKTqu7uHGUGOKSS4dzTi000cJ4qHSyY -ODrouvKgqKwB+Q7IfpQ72i6DLpTzNjLKNMipBPsSkSW+RaWC67+smo1vL9V5ZlfX -ypzjMF++r3cRuIWG9IwAwedl/sH7iqjHwdMf4y+8sGxRzW5Oeyvx20TvqxMqRLGD -nU0Y2GCLW7C2Idw+I5QM -=pibq ------END PGP SIGNATURE----- diff --git a/coreutils-8.31.tar.xz.sig b/coreutils-8.31.tar.xz.sig new file mode 100644 index 0000000..5aa60a1 --- /dev/null +++ b/coreutils-8.31.tar.xz.sig @@ -0,0 +1,17 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQIcBAABCAAGBQJchaqkAAoJEN9v2XEwYDfZKBMQAJNjmYU6VrbHvlSJm1d+9Qch +rvVtE5VGsTj3jUj1dh9MpuN9GhJifWJat9DEKUat0J4Z5G8d55LvyzQJppby2az2 +kwbp/ffK0wR1tfGNii3Hop3pMVizqJn+LbT01qcS3E7tVQ2nJP/JVIeXOtOf9kJk +gPviDaqO8OUiV2l3gCwLtuOETKHXRGyraWRxCb9ZxOS12Gspqfwui7t4jQUDf2Ge +Kvhcawas+XomGdWx+io/VxwkOZkOCr9vQdMM7ZqLDnu+d7nGsnPMxxdGcP72WBnV +1LxFxHIel52yuRh3T1RggQMKxXPFPEyDRgaBNN0Yfk3a2CHFHf+YtySgLzKSqyS5 +1P5syvSbNj9ASEuX428lpwI3EC5G3T9W/MLTKUpwVhfU8/WELI261F95dnFIfoar +mMPqbBMHwHpIasJfDy60m8H8/z8PEOmpRP0xfAuOtf47YpDLsH+AvrAJM4CH9kkS +lysMUZITyIqUBSoUs8mVygV7b4mq2X2US0Mkja/hDFAcq2O7m2eyvi61z7Oa1Y/r +tV+q/XS8ZTOtSTBBZzRVTJDPno1ZwFBl/MIiD5FgF7szgiR2z0KVMfAlVBdQwxKw +Mj6N/HYeP6yE3g9I5+8LmRLwQcXeC2B0ZzpvGE7DaKd5aFDC6YVDD8wyLEQFDAav +XGtN62+yfXArdYVjXygm +=LVk4 +-----END PGP SIGNATURE----- diff --git a/coreutils-8.5-dircolors.patch b/coreutils-8.5-dircolors.patch deleted file mode 100644 index 8707c0a..0000000 --- a/coreutils-8.5-dircolors.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -urNp coreutils-8.5-orig/src/dircolors.hin coreutils-8.5/src/dircolors.hin ---- coreutils-8.5-orig/src/dircolors.hin 2010-04-20 21:52:04.000000000 +0200 -+++ coreutils-8.5/src/dircolors.hin 2010-07-22 16:18:41.978036926 +0200 -@@ -127,6 +127,9 @@ EXEC 01;32 - .deb 01;31 - .rpm 01;31 - .jar 01;31 -+.war 01;31 -+.ear 01;31 -+.sar 01;31 - .rar 01;31 - .ace 01;31 - .zoo 01;31 diff --git a/coreutils-i18n-cut.patch b/coreutils-i18n-cut.patch deleted file mode 100644 index f4015d1..0000000 --- a/coreutils-i18n-cut.patch +++ /dev/null @@ -1,587 +0,0 @@ -(sb) lin18nux/lsb compliance - cut - not stable enough, not applied - ---- coreutils-8.24/src/cut.c 2015-06-26 19:05:22.000000000 +0200 -+++ cut.c 2016-01-15 10:15:04.863804121 +0100 -@@ -28,6 +28,11 @@ - #include - #include - #include -+ -+#include -+#include -+#include -+ - #include "system.h" - - #include "error.h" -@@ -61,25 +66,16 @@ - CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ - static struct field_range_pair *current_rp; - --/* 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 -- first field must be read into this buffer to determine whether it -- is followed by a delimiter or a newline before any of it may be -- output. Otherwise, cut_fields can do the job without using this -- buffer. */ --static char *field_1_buffer; -- --/* The number of bytes allocated for FIELD_1_BUFFER. */ --static size_t field_1_bufsize; -- - enum operating_mode - { - undefined_mode, - -- /* Output characters that are in the given bytes. */ -+ /* Output the given bytes. */ - byte_mode, - -+ /* Output characters that are in the given positions . */ -+ char_mode, -+ - /* Output the given delimiter-separated fields. */ - field_mode - }; -@@ -91,12 +87,16 @@ static enum operating_mode operating_mode; - with field mode. */ - static bool suppress_non_delimited; - -+/* Unless true, we do not recognize multibyte characters in byte-splitting -+ mode. */ -+static bool no_break_mb_chars; -+ - /* If true, print all bytes, characters, or fields _except_ - those that were specified. */ - static bool complement; - - /* The delimiter character for field mode. */ --static unsigned char delim; -+static mbf_char_t delim; - - /* The delimiter for each line/record. */ - static unsigned char line_delim = '\n'; -@@ -109,7 +109,7 @@ static size_t output_delimiter_length; - - /* The output field separator string. Defaults to the 1-character - string consisting of the input delimiter. */ --static char *output_delimiter_string; -+static char const *output_delimiter_string; - - /* True if we have ever read standard input. */ - static bool have_read_stdin; -@@ -164,7 +164,7 @@ Print selected parts of lines from each FILE to standard output.\n\ - -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\ -@@ -211,6 +211,12 @@ next_item (size_t *item_idx) - current_rp++; - } - -+static inline void -+next_item_n (size_t *item_idx, size_t n) -+{ -+ while (n-- > 0) -+ next_item (item_idx); -+} - /* Return nonzero if the K'th field or byte is printable. */ - - static inline bool -@@ -219,6 +225,15 @@ print_kth (size_t k) - return current_rp->lo <= k; - } - -+/* The lo and hi params should be used for the current characters byte position -+ * and byte size, respectively. */ -+static inline bool -+rp_intersect (size_t lo, size_t hi) -+{ -+ return ((current_rp->lo <= lo && current_rp->hi >= lo) -+ || (current_rp->lo <= hi && current_rp->hi >= hi)); -+} -+ - /* Return nonzero if K'th byte is the beginning of a range. */ - - static inline bool -@@ -281,23 +296,215 @@ cut_bytes (FILE *stream) - } - - /* Read from stream STREAM, printing to standard output any selected fields. */ -+extern ssize_t -+mb_getndelim2 (mbf_char_t **lineptr, size_t *linesize, size_t nmax, -+ mbf_char_t delim1, mbf_char_t delim2, mb_file_t *stream) -+{ -+/* The maximum value that getndelim2 can return without suffering from -+ overflow problems, either internally (because of pointer -+ subtraction overflow) or due to the API (because of ssize_t). */ -+#define GETNDELIM2_MAXIMUM (PTRDIFF_MAX < SSIZE_MAX ? PTRDIFF_MAX : SSIZE_MAX) -+ -+/* Try to add at least this many bytes when extending the buffer. -+ MIN_CHUNK must be no greater than GETNDELIM2_MAXIMUM. */ -+#define MIN_CHUNK 64 -+ size_t nchars_avail; /* Allocated but unused chars in *LINEPTR. */ -+ mbf_char_t *read_pos; /* Where we're reading into *LINEPTR. */ -+ ssize_t chars_stored = -1; -+ mbf_char_t *ptr = *lineptr; -+ size_t size = *linesize; -+ bool found_delimiter; -+ -+ if (!ptr) -+ { -+ size = nmax < MIN_CHUNK ? nmax : MIN_CHUNK; -+ ptr = malloc (size * sizeof (mbf_char_t)); -+ if (!ptr) -+ return -1; -+ } -+ -+ if (size < 0) -+ goto done; -+ -+ nchars_avail = size; -+ read_pos = ptr; -+ -+ if (nchars_avail == 0 && nmax <= size) -+ goto done; -+ -+ /* Normalize delimiters, since memchr2 doesn't handle EOF. */ -+ if (mb_iseof (delim1)) -+ mb_copy (&delim1, &delim2); -+ else if (mb_iseof (delim2)) -+ mb_copy (&delim2, &delim1); -+ -+ flockfile (stream); -+ -+ found_delimiter = false; -+ do -+ { -+ /* Here always ptr + size == read_pos + nchars_avail. -+ Also nchars_avail > 0 || size < nmax. */ -+ -+ mbf_char_t c IF_LINT (= 0); -+ { -+ mbf_getc (c, *stream); -+ if (mb_iseof (c)) -+ { -+ /* Return partial line, if any. */ -+ if (read_pos == ptr) -+ goto unlock_done; -+ else -+ break; -+ } -+ if (mb_equal (c, delim1) || mb_equal (c, delim2)) -+ found_delimiter = true; -+ } -+ -+ /* We always want at least one byte left in the buffer, since we -+ always (unless we get an error while reading the first byte) -+ NUL-terminate the line buffer. */ -+ -+ if (!nchars_avail) -+ { -+ /* Grow size proportionally, not linearly, to avoid O(n^2) -+ running time. */ -+ size_t newsize = size < MIN_CHUNK ? size + MIN_CHUNK : 2 * size; -+ mbf_char_t *newptr; -+ -+ /* Respect nmax. This handles possible integer overflow. */ -+ if (! (size < newsize && newsize <= nmax)) -+ newsize = nmax; -+ -+ if (GETNDELIM2_MAXIMUM < newsize) -+ { -+ size_t newsizemax = GETNDELIM2_MAXIMUM + 1; -+ if (size == newsizemax) -+ goto unlock_done; -+ newsize = newsizemax; -+ } -+ nchars_avail = newsize - (read_pos - ptr); -+ newptr = realloc (ptr, newsize * sizeof (mbf_char_t)); -+ if (!newptr) -+ goto unlock_done; -+ ptr = newptr; -+ size = newsize; -+ read_pos = size - nchars_avail + ptr; -+ } -+ -+ /* Here, if size < nmax, nchars_avail >= buffer_len + 1. -+ If size == nmax, nchars_avail > 0. */ -+ -+ if (1 < nchars_avail--) -+ { -+ mb_copy(read_pos++, &c); -+ } -+ -+ } -+ while (!found_delimiter); -+ -+ chars_stored = (read_pos - ptr); -+ -+ unlock_done: -+ funlockfile (stream); -+ -+ done: -+ *lineptr = ptr; -+ *linesize = size; -+ return chars_stored; -+} -+ -+static void -+cut_chars (FILE *stream) -+{ -+ size_t char_idx; /* Number of chars in the line so far. */ -+ bool print_delimiter; -+ mbf_char_t c; -+ mb_file_t mbf; -+ -+ print_delimiter = false; -+ char_idx = 0; -+ current_rp = frp; -+ -+ mbf_init (mbf, stream); -+ while (true) -+ { -+ mbf_getc (c, mbf); -+ -+ if (mb_iseq (c, line_delim)) -+ { -+ putc (line_delim, stdout); -+ char_idx = 0; -+ print_delimiter = false; -+ current_rp = frp; -+ } -+ else if (mb_iseof (c)) -+ { -+ if (char_idx > 0) -+ putc (line_delim, stdout); -+ break; -+ } -+ else -+ { -+ /* Forward by one byte. */ -+ next_item (&char_idx); -+ -+ /* Check if the current characters byte range is within -+ * the argument list. */ -+ if (rp_intersect (char_idx, char_idx + mb_len (c) - 1)) -+ { -+ if (output_delimiter_specified) -+ { -+ if (print_delimiter && is_range_start_index (char_idx)) -+ { -+ fwrite (output_delimiter_string, sizeof (char), -+ output_delimiter_length, stdout); -+ } -+ print_delimiter = true; -+ } -+ mb_putc (c, stdout); -+ } -+ -+ /* Byte mode with multibyte characters uncut (-b -n). */ -+ if (no_break_mb_chars) -+ /* Forward by an additional byte_length (c) - 1. */ -+ next_item_n (&char_idx, mb_len (c) - 1); -+ } -+ } -+} - - static void - cut_fields (FILE *stream) - { -- int c; -+ -+ /* 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 -+ first field must be read into this buffer to determine whether it -+ is followed by a delimiter or a newline before any of it may be -+ output. Otherwise, cut_fields can do the job without using this -+ buffer. */ -+ mbf_char_t *field_1_buffer = 0; -+ /* The number of bytes allocated for FIELD_1_BUFFER. */ -+ size_t field_1_bufsize; -+ -+ -+ mbf_char_t c, d; -+ mb_file_t mbf; - size_t field_idx = 1; - bool found_any_selected_field = false; - bool buffer_first_field; - - current_rp = frp; - -- c = getc (stream); -- if (c == EOF) -+ mbf_init (mbf, stream); -+ mbf_getc (c, mbf); -+ if (mb_iseof (c)) - return; - -- ungetc (c, stream); -- c = 0; -+ mbf_ungetc (c, mbf); -+ mb_setascii (&c, 0); -+ mb_copy (&d, &delim); - - /* To support the semantics of the -s flag, we may have to buffer - all of the first field to determine whether it is 'delimited.' -@@ -312,10 +519,14 @@ cut_fields (FILE *stream) - if (field_idx == 1 && buffer_first_field) - { - ssize_t len; -- size_t n_bytes; -+ size_t n_chars; -+ mbf_char_t nl; -+ mb_setascii (&nl, line_delim); -+ -+ len = mb_getndelim2 (&field_1_buffer, &field_1_bufsize, -+ GETNLINE_NO_LIMIT, d, nl, &mbf); -+ - -- len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0, -- GETNLINE_NO_LIMIT, delim, line_delim, stream); - if (len < 0) - { - free (field_1_buffer); -@@ -325,15 +536,15 @@ cut_fields (FILE *stream) - xalloc_die (); - } - -- n_bytes = len; -- assert (n_bytes != 0); -+ n_chars = len; -+ //assert (n_chars != 0); - -- c = 0; -+ mb_setascii (&c, 0); - - /* 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 (to_uchar (field_1_buffer[n_bytes - 1]) != delim) -+ if (!mb_equal (field_1_buffer[n_chars - 1], d)) - { - if (suppress_non_delimited) - { -@@ -341,26 +552,30 @@ cut_fields (FILE *stream) - } - else - { -- fwrite (field_1_buffer, sizeof (char), n_bytes, stdout); -+ for (int i = 0; i < n_chars; ++i) -+ mb_putc (field_1_buffer[i], stdout); -+ - /* Make sure the output line is newline terminated. */ -- if (field_1_buffer[n_bytes - 1] != line_delim) -+ if (!mb_iseq (field_1_buffer[n_chars - 1], line_delim)) - putchar (line_delim); -- c = line_delim; -+ mb_setascii (&c, line_delim); - } - continue; - } - if (print_kth (1)) - { - /* Print the field, but not the trailing delimiter. */ -- fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout); -+ for (int i = 0; i < n_chars - 1; ++i) -+ mb_putc (field_1_buffer[i], stdout); - - /* With -d$'\n' don't treat the last '\n' as a delimiter. */ -- if (delim == line_delim) -+ if (mb_iseq (d, line_delim)) - { -- int last_c = getc (stream); -- if (last_c != EOF) -+ mbf_char_t last_c; -+ mbf_getc (last_c, mbf); -+ if (!mb_iseof (last_c)) - { -- ungetc (last_c, stream); -+ mbf_ungetc (last_c, mbf); - found_any_selected_field = true; - } - } -@@ -370,7 +585,8 @@ cut_fields (FILE *stream) - next_item (&field_idx); - } - -- int prev_c = c; -+ mbf_char_t prev_c; -+ mb_copy (&prev_c, &c); - - if (print_kth (field_idx)) - { -@@ -381,42 +597,46 @@ cut_fields (FILE *stream) - } - found_any_selected_field = true; - -- while ((c = getc (stream)) != delim && c != line_delim && c != EOF) -+ mbf_getc (c, mbf); -+ while (!mb_equal (c, d) && !mb_iseq (c, line_delim) && !mb_iseof (c)) - { -- putchar (c); -- prev_c = c; -+ mb_putc (c, stdout); -+ mb_copy (&prev_c, &c); -+ mbf_getc (c, mbf); - } - } - else - { -- while ((c = getc (stream)) != delim && c != line_delim && c != EOF) -+ mbf_getc (c, mbf); -+ while (!mb_equal (c, d) && !mb_iseq (c, line_delim) && !mb_iseof (c)) - { -- prev_c = c; -+ mb_copy (&prev_c, &c); -+ mbf_getc (c, mbf); - } - } - - /* With -d$'\n' don't treat the last '\n' as a delimiter. */ -- if (delim == line_delim && c == delim) -+ if (mb_iseq (d, line_delim) && mb_equal (c, d)) - { -- int last_c = getc (stream); -- if (last_c != EOF) -- ungetc (last_c, stream); -+ mbf_char_t last_c; -+ mbf_getc (last_c, mbf); -+ if (!mb_iseof (last_c)) -+ mbf_ungetc (last_c, mbf); - else -- c = last_c; -+ mb_copy (&c, &last_c); - } - -- if (c == delim) -+ if (mb_equal (c, d)) - next_item (&field_idx); -- else if (c == line_delim || c == EOF) -+ else if (mb_iseq (c, line_delim) || mb_iseof (c)) - { - if (found_any_selected_field - || !(suppress_non_delimited && field_idx == 1)) - { -- if (c == line_delim || prev_c != line_delim -- || delim == line_delim) -+ if (mb_iseq (c, line_delim) || !mb_iseq (prev_c, line_delim) || mb_iseq (d, line_delim)) - putchar (line_delim); - } -- if (c == EOF) -+ if (mb_iseof (c)) - break; - field_idx = 1; - current_rp = frp; -@@ -429,7 +649,14 @@ static void - cut_stream (FILE *stream) - { - if (operating_mode == byte_mode) -- cut_bytes (stream); -+ { -+ if (no_break_mb_chars) -+ cut_chars (stream); -+ else -+ cut_bytes (stream); -+ } -+ else if (operating_mode == char_mode) -+ cut_chars (stream); - else - cut_fields (stream); - } -@@ -483,6 +710,7 @@ main (int argc, char **argv) - bool ok; - bool delim_specified = false; - char *spec_list_string IF_LINT ( = NULL); -+ mbi_iterator_t iter; - - initialize_main (&argc, &argv); - set_program_name (argv[0]); -@@ -496,8 +724,10 @@ main (int argc, char **argv) - - /* By default, all non-delimited lines are printed. */ - suppress_non_delimited = false; -+ /* Default behaviour for -b, unless -n is also specified. */ -+ no_break_mb_chars = false; - -- delim = '\0'; -+ mb_setascii (&delim, '\0'); - have_read_stdin = false; - - while ((optc = getopt_long (argc, argv, "b:c:d:f:nsz", longopts, NULL)) != -1) -@@ -505,7 +735,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 +742,14 @@ main (int argc, char **argv) - spec_list_string = optarg; - break; - -+ case 'c': -+ /* Build the char list. */ -+ if (operating_mode != undefined_mode) -+ FATAL_ERROR (_("only one type of list may be specified")); -+ operating_mode = char_mode; -+ spec_list_string = optarg; -+ break; -+ - case 'f': - /* Build the field list. */ - if (operating_mode != undefined_mode) -@@ -524,9 +761,17 @@ 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') -+ mbi_init (iter, optarg, strlen (optarg)); -+ if (!mbi_avail (iter)) -+ mb_setascii (&delim, '\0'); -+ else -+ { -+ mb_copy (&delim, &mbi_cur (iter)); -+ -+ mbi_advance (iter); -+ if (mbi_avail (iter)) - FATAL_ERROR (_("the delimiter must be a single character")); -- delim = optarg[0]; -+ } - delim_specified = true; - break; - -@@ -540,6 +785,7 @@ main (int argc, char **argv) - break; - - case 'n': -+ no_break_mb_chars = true; - break; - - case 's': -@@ -579,15 +825,12 @@ main (int argc, char **argv) - | (complement ? SETFLD_COMPLEMENT : 0) ); - - if (!delim_specified) -- delim = '\t'; -+ mb_setascii (&delim, '\t'); - - if (output_delimiter_string == NULL) - { -- static char dummy[2]; -- dummy[0] = delim; -- dummy[1] = '\0'; -- output_delimiter_string = dummy; -- output_delimiter_length = 1; -+ output_delimiter_string = mb_ptr (delim); -+ output_delimiter_length = mb_len (delim); - } - - if (optind == argc) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 429675f..e3428d9 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1731,7 +1731,7 @@ index 6d2eec5..f189a0d 100644 #include "system.h" #include "argmatch.h" #include "die.h" -@@ -169,14 +177,39 @@ static int decimal_point; +@@ -161,14 +169,39 @@ static int decimal_point; /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; @@ -1772,7 +1772,7 @@ index 6d2eec5..f189a0d 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -350,13 +383,11 @@ static bool reverse; +@@ -342,13 +375,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -1789,7 +1789,7 @@ index 6d2eec5..f189a0d 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -814,6 +845,46 @@ reap_all (void) +@@ -806,6 +837,46 @@ reap_all (void) reap (-1); } @@ -1836,7 +1836,7 @@ index 6d2eec5..f189a0d 100644 /* Clean up any remaining temporary files. */ static void -@@ -1264,7 +1335,7 @@ zaptemp (char const *name) +@@ -1274,7 +1345,7 @@ zaptemp (char const *name) free (node); } @@ -1845,7 +1845,7 @@ index 6d2eec5..f189a0d 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1279,7 +1350,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1289,7 +1360,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -1854,7 +1854,7 @@ index 6d2eec5..f189a0d 100644 { size_t i; -@@ -1291,7 +1362,7 @@ inittables (void) +@@ -1301,7 +1372,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -1863,7 +1863,7 @@ index 6d2eec5..f189a0d 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1373,6 +1444,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1383,6 +1454,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -1948,7 +1948,7 @@ index 6d2eec5..f189a0d 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1604,7 +1753,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1614,7 +1763,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -1957,7 +1957,7 @@ index 6d2eec5..f189a0d 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1613,10 +1762,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1623,10 +1772,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -1970,7 +1970,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1642,11 +1791,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1652,11 +1801,70 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2042,7 +2042,7 @@ index 6d2eec5..f189a0d 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1661,10 +1869,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1671,10 +1879,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2055,7 +2055,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1710,10 +1918,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1720,10 +1928,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2068,7 +2068,7 @@ index 6d2eec5..f189a0d 100644 if (newlim) lim = newlim; } -@@ -1744,6 +1952,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1754,6 +1962,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2199,7 +2199,7 @@ index 6d2eec5..f189a0d 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1830,8 +2162,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1840,8 +2172,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2224,7 +2224,7 @@ index 6d2eec5..f189a0d 100644 line->keybeg = line_start; } } -@@ -1981,7 +2327,7 @@ human_numcompare (char const *a, char const *b) +@@ -1991,7 +2337,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2233,7 +2233,7 @@ index 6d2eec5..f189a0d 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -1991,6 +2337,25 @@ numcompare (char const *a, char const *b) +@@ -2001,6 +2347,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2258,8 +2258,8 @@ index 6d2eec5..f189a0d 100644 + /* 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 once -@@ -2041,7 +2406,7 @@ general_numcompare (char const *sa, char const *sb) + A and B before calling strtold. FIXME: remove this function if +@@ -2051,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2268,7 +2268,7 @@ index 6d2eec5..f189a0d 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2317,15 +2682,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2327,15 +2692,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2286,7 +2286,7 @@ index 6d2eec5..f189a0d 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2459,7 +2823,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2469,7 +2833,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2295,7 +2295,7 @@ index 6d2eec5..f189a0d 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2517,11 +2881,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2527,11 +2891,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -2384,7 +2384,7 @@ index 6d2eec5..f189a0d 100644 { struct keyfield *key = keylist; -@@ -2606,7 +3046,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2616,7 +3056,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2393,7 +2393,7 @@ index 6d2eec5..f189a0d 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2722,6 +3162,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2732,6 +3172,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -2605,7 +2605,7 @@ index 6d2eec5..f189a0d 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2749,7 +3394,7 @@ compare (struct line const *a, struct line const *b) +@@ -2759,7 +3404,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -2614,7 +2614,7 @@ index 6d2eec5..f189a0d 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4144,6 +4789,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4149,6 +4794,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -2622,7 +2622,7 @@ index 6d2eec5..f189a0d 100644 break; case 'g': key->general_numeric = true; -@@ -4223,7 +4869,7 @@ main (int argc, char **argv) +@@ -4228,7 +4874,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2631,7 +2631,7 @@ index 6d2eec5..f189a0d 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4244,6 +4890,29 @@ main (int argc, char **argv) +@@ -4249,6 +4895,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -2661,7 +2661,7 @@ index 6d2eec5..f189a0d 100644 have_read_stdin = false; inittables (); -@@ -4518,13 +5187,34 @@ main (int argc, char **argv) +@@ -4523,13 +5192,34 @@ main (int argc, char **argv) case 't': { @@ -2700,7 +2700,7 @@ index 6d2eec5..f189a0d 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4535,9 +5225,11 @@ main (int argc, char **argv) +@@ -4540,9 +5230,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -2714,7 +2714,7 @@ index 6d2eec5..f189a0d 100644 } break; -@@ -4765,12 +5457,10 @@ main (int argc, char **argv) +@@ -4771,12 +5463,10 @@ main (int argc, char **argv) sort (files, nfiles, outfile, nthreads); } @@ -3156,7 +3156,7 @@ diff --git a/tests/local.mk b/tests/local.mk index 568944e..192f776 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -362,6 +362,8 @@ all_tests = \ +@@ -368,6 +368,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -3325,7 +3325,7 @@ index 4d399d8..07f2823 100755 my $delim = chr 0247; sub t_subst ($) { -@@ -329,8 +338,49 @@ foreach my $t (@tv) +@@ -333,8 +342,49 @@ foreach my $t (@tv) push @Tests, $new_ent; } diff --git a/coreutils.spec b/coreutils.spec index 26b57f7..edd9823 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.30 -Release: 9%{?dist} +Version: 8.31 +Release: 1%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -13,15 +13,6 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ -# rename gnulib's renameat2 to renameatu to avoid clash with glibc (#1598518) -Patch1: coreutils-8.30-renameatu.patch - -# fix heap-based buffer overflow in vasnprintf() (CVE-2018-17942) -Patch2: coreutils-8.30-CVE-2018-17942.patch - -# sync: fix open() fallback bug -Patch3: coreutils-8.30-fsync-fallback.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -243,6 +234,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Mar 11 2019 Kamil Dudka - 8.31-1 +- new upstream release 8.31 + * Thu Jan 31 2019 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild diff --git a/sources b/sources index 126e08c..ca35b8f 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (coreutils-8.30.tar.xz) = 25bc132c0d89ce71c33e417f04649c9fcfce6c5ef8b19f093b2e9e2851bfde9b5a31e20499d9c427332228ba54b88d445ddb445551e1944bb8f5cbff5ffa4eda +SHA512 (coreutils-8.31.tar.xz) = ef8941dae845bbf5ae5838bc49e44554a766302930601aada6fa594e8088f0fbad74e481ee392ff89633e68b99e4da3f761fcb5d31ee3b233d540fe2a2d4e1af diff --git a/supported_utils b/supported_utils index 8105ccf..6db4fb5 100644 --- a/supported_utils +++ b/supported_utils @@ -1,6 +1,7 @@ %{_bindir}/arch %{_bindir}/b2sum %{_bindir}/basename +%{_bindir}/basenc %{_bindir}/cat %{_bindir}/chgrp %{_bindir}/chmod From 2bc851a491dcd33c4e9702be02de5479ddeb91a8 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 18 Mar 2019 13:37:19 +0100 Subject: [PATCH 393/523] Resolves: #1688740 - fix formatting of sha512sum(1) man page --- coreutils-6.10-manpages.patch | 14 ----------- coreutils-8.31-sums-man-pages.patch | 36 +++++++++++++++++++++++++++++ coreutils.spec | 10 +++++--- 3 files changed, 43 insertions(+), 17 deletions(-) delete mode 100644 coreutils-6.10-manpages.patch create mode 100644 coreutils-8.31-sums-man-pages.patch diff --git a/coreutils-6.10-manpages.patch b/coreutils-6.10-manpages.patch deleted file mode 100644 index 5aacff7..0000000 --- a/coreutils-6.10-manpages.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/src/md5sum.c b/src/md5sum.c -index 8e21609..a857d62 100644 ---- a/src/md5sum.c -+++ b/src/md5sum.c -@@ -265,6 +265,9 @@ Print or check %s (%d-bit) checksums.\n\ - else - fputs (_("\ - -t, --text read in text mode (default)\n\ -+"), stdout); -+ fputs (_("\ -+ Note: There is no difference between binary and text mode option on GNU system.\n\ - "), stdout); - fputs (_("\ - -z, --zero end each output line with NUL, not newline,\n\ diff --git a/coreutils-8.31-sums-man-pages.patch b/coreutils-8.31-sums-man-pages.patch new file mode 100644 index 0000000..094aaaa --- /dev/null +++ b/coreutils-8.31-sums-man-pages.patch @@ -0,0 +1,36 @@ +From ef6be60dcaf424bdb21392aff42331bd4dc272e0 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 14 Mar 2019 13:48:01 +0100 +Subject: [PATCH] md5sum,b2sum,sha*sum: --help: add note about binary/text mode + +* src/md5sum.c (usage): Make it clear that there is no difference +between binary mode and text mode on GNU systems. + +Bug: https://bugzilla.redhat.com/406981 +Bug: https://bugzilla.redhat.com/1688740 + +Upstream-commit: ae61b1066351bb784b54fbfd7b52caf129ec286c +Signed-off-by: Kamil Dudka +--- + src/md5sum.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/md5sum.c b/src/md5sum.c +index 3532f7b7a..f75b6de02 100644 +--- a/src/md5sum.c ++++ b/src/md5sum.c +@@ -287,7 +287,10 @@ The following five options are useful only when verifying checksums:\n\ + The sums are computed as described in %s. When checking, the input\n\ + should be a former output of this program. The default mode is to print a\n\ + line with checksum, a space, a character indicating input mode ('*' for binary,\ +-\n' ' for text or where binary is insignificant), and name for each FILE.\n"), ++\n' ' for text or where binary is insignificant), and name for each FILE.\n\ ++\n\ ++Note: There is no difference between binary mode and text mode on GNU systems.\ ++\n"), + DIGEST_REFERENCE); + emit_ancillary_info (PROGRAM_NAME); + } +-- +2.17.2 + diff --git a/coreutils.spec b/coreutils.spec index edd9823..639eef7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.31 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -13,14 +13,15 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ +# md5sum,b2sum,sha*sum: --help: add note about binary/text mode +Patch1: coreutils-8.31-sums-man-pages.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch # require_selinux_(): use selinuxenabled(8) if available Patch105: coreutils-8.26-selinuxenable.patch -#add note about no difference between binary/text mode on Linux - md5sum manpage -Patch101: coreutils-6.10-manpages.patch # downstream changes to default DIR_COLORS Patch102: coreutils-8.25-DIR_COLORS.patch #do display processor type for uname -p/-i based on uname(2) syscall @@ -234,6 +235,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Mar 18 2019 Kamil Dudka - 8.31-2 +- fix formatting of sha512sum(1) man page (#1688740) + * Mon Mar 11 2019 Kamil Dudka - 8.31-1 - new upstream release 8.31 From 07291932a7fe00775eee757b8656b357b2245f67 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 16 Jul 2019 13:04:35 +0200 Subject: [PATCH 394/523] Resolves: #1728986 - disable flashing in ls colors for broken symbolic links --- coreutils-8.25-DIR_COLORS.patch | 6 +++--- coreutils.spec | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/coreutils-8.25-DIR_COLORS.patch b/coreutils-8.25-DIR_COLORS.patch index 59674bc..26acdf9 100644 --- a/coreutils-8.25-DIR_COLORS.patch +++ b/coreutils-8.25-DIR_COLORS.patch @@ -36,7 +36,7 @@ index d2ea453..27af9d7 100644 CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 00 # ... and the files they point to -+MISSING 01;05;37;41 # ... and the files they point to ++MISSING 01;37;41 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability @@ -173,7 +173,7 @@ index d2ea453..74c34ba 100644 +BLK 48;5;232;38;5;11 # block device driver +CHR 48;5;232;38;5;3 # character device driver +ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file ... -+MISSING 01;05;37;41 # ... and the files they point to ++MISSING 01;37;41 # ... and the files they point to +SETUID 48;5;196;38;5;15 # file that is setuid (u+s) +SETGID 48;5;11;38;5;16 # file that is setgid (g+s) +CAPABILITY 48;5;196;38;5;226 # file with capability @@ -464,7 +464,7 @@ index d2ea453..95d6879 100644 CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 00 # ... and the files they point to -+MISSING 01;05;37;41 # ... and the files they point to ++MISSING 01;37;41 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability diff --git a/coreutils.spec b/coreutils.spec index 639eef7..9ad7d29 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.31 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -235,6 +235,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jul 16 2019 Kamil Dudka - 8.31-3 +- disable flashing in ls colors for broken symbolic links (#1728986) + * Mon Mar 18 2019 Kamil Dudka - 8.31-2 - fix formatting of sha512sum(1) man page (#1688740) From 16fe71f18e3c2b8594481a418ae76a272b6368d3 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 24 Jul 2019 21:02:06 +0000 Subject: [PATCH 395/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 9ad7d29..e8fa88e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.31 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -235,6 +235,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jul 24 2019 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + * Tue Jul 16 2019 Kamil Dudka - 8.31-3 - disable flashing in ls colors for broken symbolic links (#1728986) From 5cd3289cea3a3875ea438e4d22b091f1215dcab8 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 11 Oct 2019 13:20:40 +0200 Subject: [PATCH 396/523] Resolves: #1760300 - use statx instead of stat when available --- coreutils-8.31-statx.patch | 1294 ++++++++++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 1301 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.31-statx.patch diff --git a/coreutils-8.31-statx.patch b/coreutils-8.31-statx.patch new file mode 100644 index 0000000..cc09c2e --- /dev/null +++ b/coreutils-8.31-statx.patch @@ -0,0 +1,1294 @@ +From 061032235577e58980f76f6340e8b0e7f0350dd0 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Tue, 28 May 2019 08:21:42 -0400 +Subject: [PATCH 1/4] stat: Use statx where available and support --cached + +* src/stat.c: Drop statbuf argument from out_epoch_sec(). +Use statx() rather than [lf]stat() where available, +so a separate call is not required to get birth time. +Set STATX_* mask bits only for things we want to print, +which can be more efficient on some file systems. +Add a new --cache= command-line option that sets the appropriate hint +flags in the statx call. These are primarily used with network +file systems to indicate what level of cache coherency is desired. +The new option is available unconditionally for better portability, +and ignored where not implemented. +* doc/coreutils.texi: Add documention for --cached. +* man/stat.x (SEE ALSO): Mention statx(). + +Upstream-commit: 6cc35de16fdc52d417602b66d5e90694d7e02994 +Signed-off-by: Kamil Dudka +--- + doc/coreutils.texi | 21 ++ + man/stat.x | 2 +- + src/stat.c | 623 ++++++++++++++++++++++++++++++--------------- + 3 files changed, 444 insertions(+), 202 deletions(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index c123860..957ee92 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -12360,6 +12360,27 @@ Report information about the file systems where the given files are located + instead of information about the files themselves. + This option implies the @option{-L} option. + ++@item --cached=@var{mode} ++@opindex --cached=@var{mode} ++@cindex attribute caching ++Control how attributes are read from the file system; ++if supported by the system. This allows one to ++control the trade-off between freshness and efficiency ++of attribute access, especially useful with remote file systems. ++@var{mode} can be: ++ ++@table @samp ++@item always ++Always read the already cached attributes if available. ++ ++@item never ++Always sychronize with the latest file system attributes. ++ ++@item default ++Leave the caching behavior to the underlying file system. ++ ++@end table ++ + @item -c + @itemx --format=@var{format} + @opindex -c +diff --git a/man/stat.x b/man/stat.x +index dc3781e..b9f8c68 100644 +--- a/man/stat.x ++++ b/man/stat.x +@@ -3,4 +3,4 @@ stat \- display file or file system status + [DESCRIPTION] + .\" Add any additional description here + [SEE ALSO] +-stat(2), statfs(2) ++stat(2), statfs(2), statx(2) +diff --git a/src/stat.c b/src/stat.c +index bb1ef1a..3bb84f3 100644 +--- a/src/stat.c ++++ b/src/stat.c +@@ -28,6 +28,12 @@ + # define USE_STATVFS 0 + #endif + ++#if HAVE_STATX && defined STATX_INO ++# define USE_STATX 1 ++#else ++# define USE_STATX 0 ++#endif ++ + #include + #include + #include +@@ -194,6 +200,23 @@ enum + PRINTF_OPTION = CHAR_MAX + 1 + }; + ++enum cached_mode ++{ ++ cached_default, ++ cached_never, ++ cached_always ++}; ++ ++static char const *const cached_args[] = ++{ ++ "default", "never", "always", NULL ++}; ++ ++static enum cached_mode const cached_modes[] = ++{ ++ cached_default, cached_never, cached_always ++}; ++ + static struct option const long_options[] = + { + {"dereference", no_argument, NULL, 'L'}, +@@ -201,6 +224,7 @@ static struct option const long_options[] = + {"format", required_argument, NULL, 'c'}, + {"printf", required_argument, NULL, PRINTF_OPTION}, + {"terse", no_argument, NULL, 't'}, ++ {"cached", required_argument, NULL, 0}, + {GETOPT_HELP_OPTION_DECL}, + {GETOPT_VERSION_OPTION_DECL}, + {NULL, 0, NULL, 0} +@@ -221,6 +245,10 @@ static char const *trailing_delim = ""; + static char const *decimal_point; + static size_t decimal_point_len; + ++static bool ++print_stat (char *pformat, size_t prefix_len, unsigned int m, ++ int fd, char const *filename, void const *data); ++ + /* Return the type of the specified file system. + Some systems have statfvs.f_basetype[FSTYPSZ] (AIX, HP-UX, and Solaris). + Others have statvfs.f_fstypename[_VFS_NAMELEN] (NetBSD 3.0). +@@ -676,7 +704,6 @@ out_minus_zero (char *pformat, size_t prefix_len) + acts like printf's %f format. */ + static void + out_epoch_sec (char *pformat, size_t prefix_len, +- struct stat const *statbuf _GL_UNUSED, + struct timespec arg) + { + char *dot = memchr (pformat, '.', prefix_len); +@@ -980,57 +1007,6 @@ print_mount_point: + return fail; + } + +-static struct timespec +-get_birthtime (int fd, char const *filename, struct stat const *st) +-{ +- struct timespec ts = get_stat_birthtime (st); +- +-#if HAVE_GETATTRAT +- if (ts.tv_nsec < 0) +- { +- nvlist_t *response; +- if ((fd < 0 +- ? getattrat (AT_FDCWD, XATTR_VIEW_READWRITE, filename, &response) +- : fgetattr (fd, XATTR_VIEW_READWRITE, &response)) +- == 0) +- { +- uint64_t *val; +- uint_t n; +- if (nvlist_lookup_uint64_array (response, A_CRTIME, &val, &n) == 0 +- && 2 <= n +- && val[0] <= TYPE_MAXIMUM (time_t) +- && val[1] < 1000000000 * 2 /* for leap seconds */) +- { +- ts.tv_sec = val[0]; +- ts.tv_nsec = val[1]; +- } +- nvlist_free (response); +- } +- } +-#endif +- +-#if HAVE_STATX && defined STATX_BTIME +- if (ts.tv_nsec < 0) +- { +- struct statx stx; +- if ((fd < 0 +- ? statx (AT_FDCWD, filename, +- follow_links ? 0 : AT_SYMLINK_NOFOLLOW, +- STATX_BTIME, &stx) +- : statx (fd, "", AT_EMPTY_PATH, STATX_BTIME, &stx)) == 0) +- { +- if ((stx.stx_mask & STATX_BTIME) && stx.stx_btime.tv_sec != 0) +- { +- ts.tv_sec = stx.stx_btime.tv_sec; +- ts.tv_nsec = stx.stx_btime.tv_nsec; +- } +- } +- } +-#endif +- +- return ts; +-} +- + /* Map a TS with negative TS.tv_nsec to {0,0}. */ + static inline struct timespec + neg_to_zero (struct timespec ts) +@@ -1067,139 +1043,6 @@ getenv_quoting_style (void) + /* Equivalent to quotearg(), but explicit to avoid syntax checks. */ + #define quoteN(x) quotearg_style (get_quoting_style (NULL), x) + +-/* Print stat info. Return zero upon success, nonzero upon failure. */ +-static bool +-print_stat (char *pformat, size_t prefix_len, unsigned int m, +- int fd, char const *filename, void const *data) +-{ +- struct stat *statbuf = (struct stat *) data; +- struct passwd *pw_ent; +- struct group *gw_ent; +- bool fail = false; +- +- switch (m) +- { +- case 'n': +- out_string (pformat, prefix_len, filename); +- break; +- case 'N': +- out_string (pformat, prefix_len, quoteN (filename)); +- if (S_ISLNK (statbuf->st_mode)) +- { +- char *linkname = areadlink_with_size (filename, statbuf->st_size); +- if (linkname == NULL) +- { +- error (0, errno, _("cannot read symbolic link %s"), +- quoteaf (filename)); +- return true; +- } +- printf (" -> "); +- out_string (pformat, prefix_len, quoteN (linkname)); +- free (linkname); +- } +- break; +- case 'd': +- out_uint (pformat, prefix_len, statbuf->st_dev); +- break; +- case 'D': +- out_uint_x (pformat, prefix_len, statbuf->st_dev); +- break; +- case 'i': +- out_uint (pformat, prefix_len, statbuf->st_ino); +- break; +- case 'a': +- out_uint_o (pformat, prefix_len, statbuf->st_mode & CHMOD_MODE_BITS); +- break; +- case 'A': +- out_string (pformat, prefix_len, human_access (statbuf)); +- break; +- case 'f': +- out_uint_x (pformat, prefix_len, statbuf->st_mode); +- break; +- case 'F': +- out_string (pformat, prefix_len, file_type (statbuf)); +- break; +- case 'h': +- out_uint (pformat, prefix_len, statbuf->st_nlink); +- break; +- case 'u': +- out_uint (pformat, prefix_len, statbuf->st_uid); +- break; +- case 'U': +- pw_ent = getpwuid (statbuf->st_uid); +- out_string (pformat, prefix_len, +- pw_ent ? pw_ent->pw_name : "UNKNOWN"); +- break; +- case 'g': +- out_uint (pformat, prefix_len, statbuf->st_gid); +- break; +- case 'G': +- gw_ent = getgrgid (statbuf->st_gid); +- out_string (pformat, prefix_len, +- gw_ent ? gw_ent->gr_name : "UNKNOWN"); +- break; +- case 't': +- out_uint_x (pformat, prefix_len, major (statbuf->st_rdev)); +- break; +- case 'm': +- fail |= out_mount_point (filename, pformat, prefix_len, statbuf); +- break; +- case 'T': +- out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev)); +- break; +- case 's': +- out_int (pformat, prefix_len, statbuf->st_size); +- break; +- case 'B': +- out_uint (pformat, prefix_len, ST_NBLOCKSIZE); +- break; +- case 'b': +- out_uint (pformat, prefix_len, ST_NBLOCKS (*statbuf)); +- break; +- case 'o': +- out_uint (pformat, prefix_len, ST_BLKSIZE (*statbuf)); +- break; +- case 'w': +- { +- struct timespec t = get_birthtime (fd, filename, statbuf); +- if (t.tv_nsec < 0) +- out_string (pformat, prefix_len, "-"); +- else +- out_string (pformat, prefix_len, human_time (t)); +- } +- break; +- case 'W': +- out_epoch_sec (pformat, prefix_len, statbuf, +- neg_to_zero (get_birthtime (fd, filename, statbuf))); +- break; +- case 'x': +- out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); +- break; +- case 'X': +- out_epoch_sec (pformat, prefix_len, statbuf, get_stat_atime (statbuf)); +- break; +- case 'y': +- out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf))); +- break; +- case 'Y': +- out_epoch_sec (pformat, prefix_len, statbuf, get_stat_mtime (statbuf)); +- break; +- case 'z': +- out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf))); +- break; +- case 'Z': +- out_epoch_sec (pformat, prefix_len, statbuf, get_stat_ctime (statbuf)); +- break; +- case 'C': +- fail |= out_file_context (pformat, prefix_len, filename); +- break; +- default: +- fputc ('?', stdout); +- break; +- } +- return fail; +-} +- + /* Output a single-character \ escape. */ + + static void +@@ -1241,6 +1084,17 @@ print_esc_char (char c) + putchar (c); + } + ++static size_t _GL_ATTRIBUTE_PURE ++format_code_offset (char const* directive) ++{ ++ size_t len = strspn (directive + 1, printf_flags); ++ char const *fmt_char = directive + len + 1; ++ fmt_char += strspn (fmt_char, digits); ++ if (*fmt_char == '.') ++ fmt_char += 1 + strspn (fmt_char + 1, digits); ++ return fmt_char - directive; ++} ++ + /* Print the information specified by the format string, FORMAT, + calling PRINT_FUNC for each %-directive encountered. + Return zero upon success, nonzero upon failure. */ +@@ -1270,33 +1124,28 @@ print_it (char const *format, int fd, char const *filename, + { + case '%': + { +- size_t len = strspn (b + 1, printf_flags); +- char const *fmt_char = b + len + 1; +- fmt_char += strspn (fmt_char, digits); +- if (*fmt_char == '.') +- fmt_char += 1 + strspn (fmt_char + 1, digits); +- len = fmt_char - (b + 1); +- unsigned int fmt_code = *fmt_char; +- memcpy (dest, b, len + 1); +- +- b = fmt_char; +- switch (fmt_code) ++ size_t len = format_code_offset (b); ++ char const *fmt_char = b + len; ++ memcpy (dest, b, len); ++ b += len; ++ ++ switch (*fmt_char) + { + case '\0': + --b; + FALLTHROUGH; + case '%': +- if (0 < len) ++ if (1 < len) + { +- dest[len + 1] = *fmt_char; +- dest[len + 2] = '\0'; ++ dest[len] = *fmt_char; ++ dest[len + 1] = '\0'; + die (EXIT_FAILURE, 0, _("%s: invalid directive"), + quote (dest)); + } + putchar ('%'); + break; + default: +- fail |= print_func (dest, len + 1, fmt_code, ++ fail |= print_func (dest, len, to_uchar (*fmt_char), + fd, filename, data); + break; + } +@@ -1384,6 +1233,204 @@ do_statfs (char const *filename, char const *format) + return ! fail; + } + ++struct print_args { ++ struct stat *st; ++ struct timespec btime; ++}; ++ ++/* Ask statx to avoid syncing? */ ++static bool dont_sync; ++ ++/* Ask statx to force sync? */ ++static bool force_sync; ++ ++#if USE_STATX ++/* Much of the format printing requires a struct stat or timespec */ ++static struct timespec ++statx_timestamp_to_timespec (struct statx_timestamp tsx) ++{ ++ struct timespec ts; ++ ++ ts.tv_sec = tsx.tv_sec; ++ ts.tv_nsec = tsx.tv_nsec; ++ return ts; ++} ++ ++static void ++statx_to_stat (struct statx *stx, struct stat *stat) ++{ ++ stat->st_dev = makedev (stx->stx_dev_major, stx->stx_dev_minor); ++ stat->st_ino = stx->stx_ino; ++ stat->st_mode = stx->stx_mode; ++ stat->st_nlink = stx->stx_nlink; ++ stat->st_uid = stx->stx_uid; ++ stat->st_gid = stx->stx_gid; ++ stat->st_rdev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor); ++ stat->st_size = stx->stx_size; ++ stat->st_blksize = stx->stx_blksize; ++/* define to avoid sc_prohibit_stat_st_blocks. */ ++# define SC_ST_BLOCKS st_blocks ++ stat->SC_ST_BLOCKS = stx->stx_blocks; ++ stat->st_atim = statx_timestamp_to_timespec (stx->stx_atime); ++ stat->st_mtim = statx_timestamp_to_timespec (stx->stx_mtime); ++ stat->st_ctim = statx_timestamp_to_timespec (stx->stx_ctime); ++} ++ ++static unsigned int ++fmt_to_mask (char fmt) ++{ ++ switch (fmt) ++ { ++ case 'N': ++ return STATX_MODE|STATX_SIZE; ++ case 'd': ++ case 'D': ++ return STATX_MODE; ++ case 'i': ++ return STATX_INO; ++ case 'a': ++ case 'A': ++ return STATX_MODE; ++ case 'f': ++ return STATX_MODE|STATX_TYPE; ++ case 'F': ++ return STATX_TYPE; ++ case 'h': ++ return STATX_NLINK; ++ case 'u': ++ case 'U': ++ return STATX_UID; ++ case 'g': ++ case 'G': ++ return STATX_GID; ++ case 'm': ++ return STATX_MODE|STATX_INO; ++ case 's': ++ return STATX_SIZE; ++ case 't': ++ case 'T': ++ return STATX_MODE; ++ case 'b': ++ return STATX_BLOCKS; ++ case 'w': ++ case 'W': ++ return STATX_BTIME; ++ case 'x': ++ case 'X': ++ return STATX_ATIME; ++ case 'y': ++ case 'Y': ++ return STATX_MTIME; ++ case 'z': ++ case 'Z': ++ return STATX_CTIME; ++ } ++ return 0; ++} ++ ++static unsigned int _GL_ATTRIBUTE_PURE ++format_to_mask (char const *format) ++{ ++ unsigned int mask = 0; ++ char const *b; ++ ++ for (b = format; *b; b++) ++ { ++ if (*b != '%') ++ continue; ++ ++ b += format_code_offset (b); ++ if (*b == '\0') ++ break; ++ mask |= fmt_to_mask (*b); ++ } ++ return mask; ++} ++ ++/* statx the file and print what we find */ ++static bool ATTRIBUTE_WARN_UNUSED_RESULT ++do_stat (char const *filename, char const *format, char const *format2) ++{ ++ int fd = STREQ (filename, "-") ? 0 : AT_FDCWD; ++ int flags = 0; ++ struct stat st; ++ struct statx stx; ++ const char *pathname = filename; ++ struct print_args pa; ++ pa.st = &st; ++ pa.btime = (struct timespec) {-1, -1}; ++ ++ if (AT_FDCWD != fd) ++ { ++ pathname = ""; ++ flags = AT_EMPTY_PATH; ++ } ++ else if (!follow_links) ++ { ++ flags = AT_SYMLINK_NOFOLLOW; ++ } ++ ++ if (dont_sync) ++ flags |= AT_STATX_DONT_SYNC; ++ else if (force_sync) ++ flags |= AT_STATX_FORCE_SYNC; ++ ++ fd = statx (fd, pathname, flags, format_to_mask (format), &stx); ++ if (fd < 0) ++ { ++ if (flags & AT_EMPTY_PATH) ++ error (0, errno, _("cannot stat standard input")); ++ else ++ error (0, errno, _("cannot statx %s"), quoteaf (filename)); ++ return false; ++ } ++ ++ if (S_ISBLK (stx.stx_mode) || S_ISCHR (stx.stx_mode)) ++ format = format2; ++ ++ statx_to_stat (&stx, &st); ++ if (stx.stx_mask & STATX_BTIME) ++ pa.btime = statx_timestamp_to_timespec (stx.stx_btime); ++ ++ bool fail = print_it (format, fd, filename, print_stat, &pa); ++ return ! fail; ++} ++ ++#else /* USE_STATX */ ++ ++static struct timespec ++get_birthtime (int fd, char const *filename, struct stat const *st) ++{ ++ struct timespec ts = get_stat_birthtime (st); ++ ++# if HAVE_GETATTRAT ++ if (ts.tv_nsec < 0) ++ { ++ nvlist_t *response; ++ if ((fd < 0 ++ ? getattrat (AT_FDCWD, XATTR_VIEW_READWRITE, filename, &response) ++ : fgetattr (fd, XATTR_VIEW_READWRITE, &response)) ++ == 0) ++ { ++ uint64_t *val; ++ uint_t n; ++ if (nvlist_lookup_uint64_array (response, A_CRTIME, &val, &n) == 0 ++ && 2 <= n ++ && val[0] <= TYPE_MAXIMUM (time_t) ++ && val[1] < 1000000000 * 2 /* for leap seconds */) ++ { ++ ts.tv_sec = val[0]; ++ ts.tv_nsec = val[1]; ++ } ++ nvlist_free (response); ++ } ++ } ++# endif ++ ++ return ts; ++} ++ ++ + /* stat the file and print what we find */ + static bool ATTRIBUTE_WARN_UNUSED_RESULT + do_stat (char const *filename, char const *format, +@@ -1391,6 +1438,9 @@ do_stat (char const *filename, char const *format, + { + int fd = STREQ (filename, "-") ? 0 : -1; + struct stat statbuf; ++ struct print_args pa; ++ pa.st = &statbuf; ++ pa.btime = (struct timespec) {-1, -1}; + + if (0 <= fd) + { +@@ -1414,9 +1464,152 @@ do_stat (char const *filename, char const *format, + if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode)) + format = format2; + +- bool fail = print_it (format, fd, filename, print_stat, &statbuf); ++ bool fail = print_it (format, fd, filename, print_stat, &pa); + return ! fail; + } ++#endif /* USE_STATX */ ++ ++ ++/* Print stat info. Return zero upon success, nonzero upon failure. */ ++static bool ++print_stat (char *pformat, size_t prefix_len, unsigned int m, ++ int fd, char const *filename, void const *data) ++{ ++ struct print_args *parg = (struct print_args *) data; ++ struct stat *statbuf = parg->st; ++ struct timespec btime = parg->btime; ++ struct passwd *pw_ent; ++ struct group *gw_ent; ++ bool fail = false; ++ ++ switch (m) ++ { ++ case 'n': ++ out_string (pformat, prefix_len, filename); ++ break; ++ case 'N': ++ out_string (pformat, prefix_len, quoteN (filename)); ++ if (S_ISLNK (statbuf->st_mode)) ++ { ++ char *linkname = areadlink_with_size (filename, statbuf->st_size); ++ if (linkname == NULL) ++ { ++ error (0, errno, _("cannot read symbolic link %s"), ++ quoteaf (filename)); ++ return true; ++ } ++ printf (" -> "); ++ out_string (pformat, prefix_len, quoteN (linkname)); ++ free (linkname); ++ } ++ break; ++ case 'd': ++ out_uint (pformat, prefix_len, statbuf->st_dev); ++ break; ++ case 'D': ++ out_uint_x (pformat, prefix_len, statbuf->st_dev); ++ break; ++ case 'i': ++ out_uint (pformat, prefix_len, statbuf->st_ino); ++ break; ++ case 'a': ++ out_uint_o (pformat, prefix_len, statbuf->st_mode & CHMOD_MODE_BITS); ++ break; ++ case 'A': ++ out_string (pformat, prefix_len, human_access (statbuf)); ++ break; ++ case 'f': ++ out_uint_x (pformat, prefix_len, statbuf->st_mode); ++ break; ++ case 'F': ++ out_string (pformat, prefix_len, file_type (statbuf)); ++ break; ++ case 'h': ++ out_uint (pformat, prefix_len, statbuf->st_nlink); ++ break; ++ case 'u': ++ out_uint (pformat, prefix_len, statbuf->st_uid); ++ break; ++ case 'U': ++ pw_ent = getpwuid (statbuf->st_uid); ++ out_string (pformat, prefix_len, ++ pw_ent ? pw_ent->pw_name : "UNKNOWN"); ++ break; ++ case 'g': ++ out_uint (pformat, prefix_len, statbuf->st_gid); ++ break; ++ case 'G': ++ gw_ent = getgrgid (statbuf->st_gid); ++ out_string (pformat, prefix_len, ++ gw_ent ? gw_ent->gr_name : "UNKNOWN"); ++ break; ++ case 'm': ++ fail |= out_mount_point (filename, pformat, prefix_len, statbuf); ++ break; ++ case 's': ++ out_int (pformat, prefix_len, statbuf->st_size); ++ break; ++ case 't': ++ out_uint_x (pformat, prefix_len, major (statbuf->st_rdev)); ++ break; ++ case 'T': ++ out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev)); ++ break; ++ case 'B': ++ out_uint (pformat, prefix_len, ST_NBLOCKSIZE); ++ break; ++ case 'b': ++ out_uint (pformat, prefix_len, ST_NBLOCKS (*statbuf)); ++ break; ++ case 'o': ++ out_uint (pformat, prefix_len, ST_BLKSIZE (*statbuf)); ++ break; ++ case 'w': ++ { ++#if ! USE_STATX ++ btime = get_birthtime (fd, filename, statbuf); ++#endif ++ if (btime.tv_nsec < 0) ++ out_string (pformat, prefix_len, "-"); ++ else ++ out_string (pformat, prefix_len, human_time (btime)); ++ } ++ break; ++ case 'W': ++ { ++#if ! USE_STATX ++ btime = get_birthtime (fd, filename, statbuf); ++#endif ++ out_epoch_sec (pformat, prefix_len, neg_to_zero (btime)); ++ } ++ break; ++ case 'x': ++ out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); ++ break; ++ case 'X': ++ out_epoch_sec (pformat, prefix_len, get_stat_atime (statbuf)); ++ break; ++ case 'y': ++ out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf))); ++ break; ++ case 'Y': ++ out_epoch_sec (pformat, prefix_len, get_stat_mtime (statbuf)); ++ break; ++ case 'z': ++ out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf))); ++ break; ++ case 'Z': ++ out_epoch_sec (pformat, prefix_len, get_stat_ctime (statbuf)); ++ break; ++ case 'C': ++ fail |= out_file_context (pformat, prefix_len, filename); ++ break; ++ default: ++ fputc ('?', stdout); ++ break; ++ } ++ return fail; ++} + + /* Return an allocated format string in static storage that + corresponds to whether FS and TERSE options were declared. */ +@@ -1525,6 +1718,10 @@ Display file or file system status.\n\ + fputs (_("\ + -L, --dereference follow links\n\ + -f, --file-system display file system status instead of file status\n\ ++"), stdout); ++ fputs (_("\ ++ --cached=MODE specify how to use cached attributes;\n\ ++ useful on remote file systems. See MODE below\n\ + "), stdout); + fputs (_("\ + -c --format=FORMAT use the specified FORMAT instead of the default;\n\ +@@ -1537,6 +1734,13 @@ Display file or file system status.\n\ + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); + ++ fputs (_("\n\ ++The --cached MODE argument can be; always, never, or default.\n\ ++`always` will use cached attributes if available, while\n\ ++`never` will try to synchronize with the latest attributes, and\n\ ++`default` will leave it up to the underlying file system.\n\ ++"), stdout); ++ + fputs (_("\n\ + The valid format sequences for files (without --file-system):\n\ + \n\ +@@ -1670,6 +1874,23 @@ main (int argc, char *argv[]) + terse = true; + break; + ++ case 0: ++ switch (XARGMATCH ("--cached", optarg, cached_args, cached_modes)) ++ { ++ case cached_never: ++ force_sync = true; ++ dont_sync = false; ++ break; ++ case cached_always: ++ force_sync = false; ++ dont_sync = true; ++ break; ++ case cached_default: ++ force_sync = false; ++ dont_sync = false; ++ } ++ break; ++ + case_GETOPT_HELP_CHAR; + + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); +-- +2.20.1 + + +From c19f77360d564e0c0d5ab0159299ebd8d6c34a2f Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Fri, 14 Jun 2019 14:37:43 -0400 +Subject: [PATCH 2/4] stat: fix enabling of statx logic + +* src/stat.c: STATX_INO isn't defined until stat.h is included. +Move the test down so it works properly. + +Upstream-commit: 0b9bac90d8283c1262e74f0dbda87583508de9a3 +Signed-off-by: Kamil Dudka +--- + src/stat.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/stat.c b/src/stat.c +index 3bb84f3..ec0bb7d 100644 +--- a/src/stat.c ++++ b/src/stat.c +@@ -28,12 +28,6 @@ + # define USE_STATVFS 0 + #endif + +-#if HAVE_STATX && defined STATX_INO +-# define USE_STATX 1 +-#else +-# define USE_STATX 0 +-#endif +- + #include + #include + #include +@@ -80,6 +74,12 @@ + #include "find-mount-point.h" + #include "xvasprintf.h" + ++#if HAVE_STATX && defined STATX_INO ++# define USE_STATX 1 ++#else ++# define USE_STATX 0 ++#endif ++ + #if USE_STATVFS + # define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATVFS_F_FSID_IS_INTEGER + # define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS_F_TYPE +-- +2.20.1 + + +From 0081747eb0fd1eb604e1f17c8c5bfaf5119310a9 Mon Sep 17 00:00:00 2001 +From: Andreas Dilger +Date: Thu, 27 Jun 2019 02:25:55 -0600 +Subject: [PATCH 3/4] stat: don't explicitly request file size for filenames + +When calling 'stat -c %N' to print the filename, don't explicitly +request the size of the file via statx(), as it may add overhead on +some filesystems. The size is only needed to optimize an allocation +for the relatively rare case of reading a symlink name, and the worst +effect is a somewhat-too-large temporary buffer may be allocated for +areadlink_with_size(), or internal retries if buffer is too small. + +The file size will be returned by statx() on most filesystems, even +if not requested, unless the filesystem considers this to be too +expensive for that file, in which case the tradeoff is worthwhile. + +* src/stat.c: Don't explicitly request STATX_SIZE for filenames. + +Upstream-commit: a1a5e9a32eb9525680edd02fd127240c27ba0999 +Signed-off-by: Kamil Dudka +--- + src/stat.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/stat.c b/src/stat.c +index ec0bb7d..ee68f16 100644 +--- a/src/stat.c ++++ b/src/stat.c +@@ -1282,7 +1282,7 @@ fmt_to_mask (char fmt) + switch (fmt) + { + case 'N': +- return STATX_MODE|STATX_SIZE; ++ return STATX_MODE; + case 'd': + case 'D': + return STATX_MODE; +@@ -1354,7 +1354,7 @@ do_stat (char const *filename, char const *format, char const *format2) + int fd = STREQ (filename, "-") ? 0 : AT_FDCWD; + int flags = 0; + struct stat st; +- struct statx stx; ++ struct statx stx = { 0, }; + const char *pathname = filename; + struct print_args pa; + pa.st = &st; +-- +2.20.1 + + +From e18c739a523f760d8372f8dd33f047a88a1b48fd Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Thu, 19 Sep 2019 11:59:45 -0400 +Subject: [PATCH 4/4] ls: use statx instead of stat when available + +statx allows ls to indicate interest in only certain inode metadata. +This is potentially a win on networked/clustered/distributed +file systems. In cases where we'd have to do a full, heavyweight stat() +call we can now do a much lighter statx() call. + +As a real-world example, consider a file system like CephFS where one +client is actively writing to a file and another client does an +ls --color in the same directory. --color means that we need to fetch +the mode of the file. + +Doing that with a stat() call means that we have to fetch the size and +mtime in addition to the mode. The MDS in that situation will have to +revoke caps in order to ensure that it has up-to-date values to report, +which disrupts the writer. + +This has a measurable affect on performance. I ran a fio sequential +write test on one cephfs client and had a second client do "ls --color" +in a tight loop on the directory that held the file: + +Baseline -- no activity on the second client: + +WRITE: bw=76.7MiB/s (80.4MB/s), 76.7MiB/s-76.7MiB/s (80.4MB/s-80.4MB/s), + io=4600MiB (4824MB), run=60016-60016msec + +Without this patch series, we see a noticable performance hit: + +WRITE: bw=70.4MiB/s (73.9MB/s), 70.4MiB/s-70.4MiB/s (73.9MB/s-73.9MB/s), + io=4228MiB (4433MB), run=60012-60012msec + +With this patch series, we gain most of that ground back: + +WRITE: bw=75.9MiB/s (79.6MB/s), 75.9MiB/s-75.9MiB/s (79.6MB/s-79.6MB/s), + io=4555MiB (4776MB), run=60019-60019msec + +* src/stat.c: move statx to stat struct conversion to new header... +* src/statx.h: ...here. +* src/ls.c: Add wrapper functions for stat/lstat/fstat calls, +and add variants for when we are only interested in specific info. +Add statx-enabled functions and set the request mask based on the +output format and what values are needed. + +Upstream-commit: a99ab266110795ed94a9cb4d2765ddad9c4310da +Signed-off-by: Kamil Dudka +--- + src/local.mk | 1 + + src/ls.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++--- + src/stat.c | 32 +----------- + src/statx.h | 52 ++++++++++++++++++ + 4 files changed, 192 insertions(+), 38 deletions(-) + create mode 100644 src/statx.h + +diff --git a/src/local.mk b/src/local.mk +index a69d405..6075391 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -58,6 +58,7 @@ noinst_HEADERS = \ + src/prog-fprintf.h \ + src/remove.h \ + src/set-fields.h \ ++ src/statx.h \ + src/system.h \ + src/uname.h + +diff --git a/src/ls.c b/src/ls.c +index 120ce15..034087f 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -114,6 +114,7 @@ + #include "xgethostname.h" + #include "c-ctype.h" + #include "canonicalize.h" ++#include "statx.h" + + /* Include last to avoid a clash of + include guards with some premature versions of libcap. +@@ -1063,6 +1064,136 @@ dired_dump_obstack (const char *prefix, struct obstack *os) + } + } + ++#if HAVE_STATX && defined STATX_INO ++static unsigned int _GL_ATTRIBUTE_PURE ++time_type_to_statx (void) ++{ ++ switch (time_type) ++ { ++ case time_ctime: ++ return STATX_CTIME; ++ case time_mtime: ++ return STATX_MTIME; ++ case time_atime: ++ return STATX_ATIME; ++ default: ++ abort (); ++ } ++ return 0; ++} ++ ++static unsigned int _GL_ATTRIBUTE_PURE ++calc_req_mask (void) ++{ ++ unsigned int mask = STATX_MODE; ++ ++ if (print_inode) ++ mask |= STATX_INO; ++ ++ if (print_block_size) ++ mask |= STATX_BLOCKS; ++ ++ if (format == long_format) { ++ mask |= STATX_NLINK | STATX_SIZE | time_type_to_statx (); ++ if (print_owner || print_author) ++ mask |= STATX_UID; ++ if (print_group) ++ mask |= STATX_GID; ++ } ++ ++ switch (sort_type) ++ { ++ case sort_none: ++ case sort_name: ++ case sort_version: ++ case sort_extension: ++ break; ++ case sort_time: ++ mask |= time_type_to_statx (); ++ break; ++ case sort_size: ++ mask |= STATX_SIZE; ++ break; ++ default: ++ abort (); ++ } ++ ++ return mask; ++} ++ ++static int ++do_statx (int fd, const char *name, struct stat *st, int flags, ++ unsigned int mask) ++{ ++ struct statx stx; ++ int ret = statx (fd, name, flags, mask, &stx); ++ if (ret >= 0) ++ statx_to_stat (&stx, st); ++ return ret; ++} ++ ++static inline int ++do_stat (const char *name, struct stat *st) ++{ ++ return do_statx (AT_FDCWD, name, st, 0, calc_req_mask ()); ++} ++ ++static inline int ++do_lstat (const char *name, struct stat *st) ++{ ++ return do_statx (AT_FDCWD, name, st, AT_SYMLINK_NOFOLLOW, calc_req_mask ()); ++} ++ ++static inline int ++stat_for_mode (const char *name, struct stat *st) ++{ ++ return do_statx (AT_FDCWD, name, st, 0, STATX_MODE); ++} ++ ++/* dev+ino should be static, so no need to sync with backing store */ ++static inline int ++stat_for_ino (const char *name, struct stat *st) ++{ ++ return do_statx (AT_FDCWD, name, st, 0, STATX_INO); ++} ++ ++static inline int ++fstat_for_ino (int fd, struct stat *st) ++{ ++ return do_statx (fd, "", st, AT_EMPTY_PATH, STATX_INO); ++} ++#else ++static inline int ++do_stat (const char *name, struct stat *st) ++{ ++ return stat (name, st); ++} ++ ++static inline int ++do_lstat (const char *name, struct stat *st) ++{ ++ return lstat (name, st); ++} ++ ++static inline int ++stat_for_mode (const char *name, struct stat *st) ++{ ++ return stat (name, st); ++} ++ ++static inline int ++stat_for_ino (const char *name, struct stat *st) ++{ ++ return stat (name, st); ++} ++ ++static inline int ++fstat_for_ino (int fd, struct stat *st) ++{ ++ return fstat (fd, st); ++} ++#endif ++ + /* Return the address of the first plain %b spec in FMT, or NULL if + there is no such spec. %5b etc. do not match, so that user + widths/flags are honored. */ +@@ -2737,10 +2868,10 @@ print_dir (char const *name, char const *realname, bool command_line_arg) + struct stat dir_stat; + int fd = dirfd (dirp); + +- /* If dirfd failed, endure the overhead of using stat. */ ++ /* If dirfd failed, endure the overhead of stat'ing by path */ + if ((0 <= fd +- ? fstat (fd, &dir_stat) +- : stat (name, &dir_stat)) < 0) ++ ? fstat_for_ino (fd, &dir_stat) ++ : stat_for_ino (name, &dir_stat)) < 0) + { + file_failure (command_line_arg, + _("cannot determine device and inode of %s"), name); +@@ -3202,7 +3333,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, + switch (dereference) + { + case DEREF_ALWAYS: +- err = stat (full_name, &f->stat); ++ err = do_stat (full_name, &f->stat); + do_deref = true; + break; + +@@ -3211,7 +3342,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, + if (command_line_arg) + { + bool need_lstat; +- err = stat (full_name, &f->stat); ++ err = do_stat (full_name, &f->stat); + do_deref = true; + + if (dereference == DEREF_COMMAND_LINE_ARGUMENTS) +@@ -3231,7 +3362,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, + FALLTHROUGH; + + default: /* DEREF_NEVER */ +- err = lstat (full_name, &f->stat); ++ err = do_lstat (full_name, &f->stat); + do_deref = false; + break; + } +@@ -3320,7 +3451,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, + they won't be traced and when no indicator is needed. */ + if (linkname + && (file_type <= indicator_style || check_symlink_mode) +- && stat (linkname, &linkstats) == 0) ++ && stat_for_mode (linkname, &linkstats) == 0) + { + f->linkok = true; + f->linkmode = linkstats.st_mode; +diff --git a/src/stat.c b/src/stat.c +index ee68f16..f2bf0dc 100644 +--- a/src/stat.c ++++ b/src/stat.c +@@ -73,6 +73,7 @@ + #include "strftime.h" + #include "find-mount-point.h" + #include "xvasprintf.h" ++#include "statx.h" + + #if HAVE_STATX && defined STATX_INO + # define USE_STATX 1 +@@ -1245,37 +1246,6 @@ static bool dont_sync; + static bool force_sync; + + #if USE_STATX +-/* Much of the format printing requires a struct stat or timespec */ +-static struct timespec +-statx_timestamp_to_timespec (struct statx_timestamp tsx) +-{ +- struct timespec ts; +- +- ts.tv_sec = tsx.tv_sec; +- ts.tv_nsec = tsx.tv_nsec; +- return ts; +-} +- +-static void +-statx_to_stat (struct statx *stx, struct stat *stat) +-{ +- stat->st_dev = makedev (stx->stx_dev_major, stx->stx_dev_minor); +- stat->st_ino = stx->stx_ino; +- stat->st_mode = stx->stx_mode; +- stat->st_nlink = stx->stx_nlink; +- stat->st_uid = stx->stx_uid; +- stat->st_gid = stx->stx_gid; +- stat->st_rdev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor); +- stat->st_size = stx->stx_size; +- stat->st_blksize = stx->stx_blksize; +-/* define to avoid sc_prohibit_stat_st_blocks. */ +-# define SC_ST_BLOCKS st_blocks +- stat->SC_ST_BLOCKS = stx->stx_blocks; +- stat->st_atim = statx_timestamp_to_timespec (stx->stx_atime); +- stat->st_mtim = statx_timestamp_to_timespec (stx->stx_mtime); +- stat->st_ctim = statx_timestamp_to_timespec (stx->stx_ctime); +-} +- + static unsigned int + fmt_to_mask (char fmt) + { +diff --git a/src/statx.h b/src/statx.h +new file mode 100644 +index 0000000..19f3e18 +--- /dev/null ++++ b/src/statx.h +@@ -0,0 +1,52 @@ ++/* statx -> stat conversion functions for coreutils ++ Copyright (C) 2019 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 . */ ++ ++#ifndef COREUTILS_STATX_H ++# define COREUTILS_STATX_H ++ ++# if HAVE_STATX && defined STATX_INO ++/* Much of the format printing requires a struct stat or timespec */ ++static inline struct timespec ++statx_timestamp_to_timespec (struct statx_timestamp tsx) ++{ ++ struct timespec ts; ++ ++ ts.tv_sec = tsx.tv_sec; ++ ts.tv_nsec = tsx.tv_nsec; ++ return ts; ++} ++ ++static inline void ++statx_to_stat (struct statx *stx, struct stat *stat) ++{ ++ stat->st_dev = makedev (stx->stx_dev_major, stx->stx_dev_minor); ++ stat->st_ino = stx->stx_ino; ++ stat->st_mode = stx->stx_mode; ++ stat->st_nlink = stx->stx_nlink; ++ stat->st_uid = stx->stx_uid; ++ stat->st_gid = stx->stx_gid; ++ stat->st_rdev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor); ++ stat->st_size = stx->stx_size; ++ stat->st_blksize = stx->stx_blksize; ++/* define to avoid sc_prohibit_stat_st_blocks. */ ++# define SC_ST_BLOCKS st_blocks ++ stat->SC_ST_BLOCKS = stx->stx_blocks; ++ stat->st_atim = statx_timestamp_to_timespec (stx->stx_atime); ++ stat->st_mtim = statx_timestamp_to_timespec (stx->stx_mtime); ++ stat->st_ctim = statx_timestamp_to_timespec (stx->stx_ctime); ++} ++# endif /* HAVE_STATX && defined STATX_INO */ ++#endif /* COREUTILS_STATX_H */ +-- +2.20.1 + diff --git a/coreutils.spec b/coreutils.spec index e8fa88e..daff9d3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.31 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -16,6 +16,9 @@ Source106: coreutils-colorls.csh # md5sum,b2sum,sha*sum: --help: add note about binary/text mode Patch1: coreutils-8.31-sums-man-pages.patch +# use statx instead of stat when available (#1760300) +Patch2: coreutils-8.31-statx.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -235,6 +238,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Oct 11 2019 Kamil Dudka - 8.31-5 +- use statx instead of stat when available (#1760300) + * Wed Jul 24 2019 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild From 664c64dec995927198ccf15d64d3add8e6ff9519 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 17 Oct 2019 09:16:18 +0200 Subject: [PATCH 397/523] Revert "Resolves: #1760300 - use statx instead of stat when available" This reverts commit 5cd3289cea3a3875ea438e4d22b091f1215dcab8 because it does not work well in containers hosted on RHEL-7, as reported in RHBZ: https://bugzilla.redhat.com/1760300#c5 --- coreutils-8.31-statx.patch | 1294 ------------------------------------ coreutils.spec | 8 +- 2 files changed, 4 insertions(+), 1298 deletions(-) delete mode 100644 coreutils-8.31-statx.patch diff --git a/coreutils-8.31-statx.patch b/coreutils-8.31-statx.patch deleted file mode 100644 index cc09c2e..0000000 --- a/coreutils-8.31-statx.patch +++ /dev/null @@ -1,1294 +0,0 @@ -From 061032235577e58980f76f6340e8b0e7f0350dd0 Mon Sep 17 00:00:00 2001 -From: Jeff Layton -Date: Tue, 28 May 2019 08:21:42 -0400 -Subject: [PATCH 1/4] stat: Use statx where available and support --cached - -* src/stat.c: Drop statbuf argument from out_epoch_sec(). -Use statx() rather than [lf]stat() where available, -so a separate call is not required to get birth time. -Set STATX_* mask bits only for things we want to print, -which can be more efficient on some file systems. -Add a new --cache= command-line option that sets the appropriate hint -flags in the statx call. These are primarily used with network -file systems to indicate what level of cache coherency is desired. -The new option is available unconditionally for better portability, -and ignored where not implemented. -* doc/coreutils.texi: Add documention for --cached. -* man/stat.x (SEE ALSO): Mention statx(). - -Upstream-commit: 6cc35de16fdc52d417602b66d5e90694d7e02994 -Signed-off-by: Kamil Dudka ---- - doc/coreutils.texi | 21 ++ - man/stat.x | 2 +- - src/stat.c | 623 ++++++++++++++++++++++++++++++--------------- - 3 files changed, 444 insertions(+), 202 deletions(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index c123860..957ee92 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -12360,6 +12360,27 @@ Report information about the file systems where the given files are located - instead of information about the files themselves. - This option implies the @option{-L} option. - -+@item --cached=@var{mode} -+@opindex --cached=@var{mode} -+@cindex attribute caching -+Control how attributes are read from the file system; -+if supported by the system. This allows one to -+control the trade-off between freshness and efficiency -+of attribute access, especially useful with remote file systems. -+@var{mode} can be: -+ -+@table @samp -+@item always -+Always read the already cached attributes if available. -+ -+@item never -+Always sychronize with the latest file system attributes. -+ -+@item default -+Leave the caching behavior to the underlying file system. -+ -+@end table -+ - @item -c - @itemx --format=@var{format} - @opindex -c -diff --git a/man/stat.x b/man/stat.x -index dc3781e..b9f8c68 100644 ---- a/man/stat.x -+++ b/man/stat.x -@@ -3,4 +3,4 @@ stat \- display file or file system status - [DESCRIPTION] - .\" Add any additional description here - [SEE ALSO] --stat(2), statfs(2) -+stat(2), statfs(2), statx(2) -diff --git a/src/stat.c b/src/stat.c -index bb1ef1a..3bb84f3 100644 ---- a/src/stat.c -+++ b/src/stat.c -@@ -28,6 +28,12 @@ - # define USE_STATVFS 0 - #endif - -+#if HAVE_STATX && defined STATX_INO -+# define USE_STATX 1 -+#else -+# define USE_STATX 0 -+#endif -+ - #include - #include - #include -@@ -194,6 +200,23 @@ enum - PRINTF_OPTION = CHAR_MAX + 1 - }; - -+enum cached_mode -+{ -+ cached_default, -+ cached_never, -+ cached_always -+}; -+ -+static char const *const cached_args[] = -+{ -+ "default", "never", "always", NULL -+}; -+ -+static enum cached_mode const cached_modes[] = -+{ -+ cached_default, cached_never, cached_always -+}; -+ - static struct option const long_options[] = - { - {"dereference", no_argument, NULL, 'L'}, -@@ -201,6 +224,7 @@ static struct option const long_options[] = - {"format", required_argument, NULL, 'c'}, - {"printf", required_argument, NULL, PRINTF_OPTION}, - {"terse", no_argument, NULL, 't'}, -+ {"cached", required_argument, NULL, 0}, - {GETOPT_HELP_OPTION_DECL}, - {GETOPT_VERSION_OPTION_DECL}, - {NULL, 0, NULL, 0} -@@ -221,6 +245,10 @@ static char const *trailing_delim = ""; - static char const *decimal_point; - static size_t decimal_point_len; - -+static bool -+print_stat (char *pformat, size_t prefix_len, unsigned int m, -+ int fd, char const *filename, void const *data); -+ - /* Return the type of the specified file system. - Some systems have statfvs.f_basetype[FSTYPSZ] (AIX, HP-UX, and Solaris). - Others have statvfs.f_fstypename[_VFS_NAMELEN] (NetBSD 3.0). -@@ -676,7 +704,6 @@ out_minus_zero (char *pformat, size_t prefix_len) - acts like printf's %f format. */ - static void - out_epoch_sec (char *pformat, size_t prefix_len, -- struct stat const *statbuf _GL_UNUSED, - struct timespec arg) - { - char *dot = memchr (pformat, '.', prefix_len); -@@ -980,57 +1007,6 @@ print_mount_point: - return fail; - } - --static struct timespec --get_birthtime (int fd, char const *filename, struct stat const *st) --{ -- struct timespec ts = get_stat_birthtime (st); -- --#if HAVE_GETATTRAT -- if (ts.tv_nsec < 0) -- { -- nvlist_t *response; -- if ((fd < 0 -- ? getattrat (AT_FDCWD, XATTR_VIEW_READWRITE, filename, &response) -- : fgetattr (fd, XATTR_VIEW_READWRITE, &response)) -- == 0) -- { -- uint64_t *val; -- uint_t n; -- if (nvlist_lookup_uint64_array (response, A_CRTIME, &val, &n) == 0 -- && 2 <= n -- && val[0] <= TYPE_MAXIMUM (time_t) -- && val[1] < 1000000000 * 2 /* for leap seconds */) -- { -- ts.tv_sec = val[0]; -- ts.tv_nsec = val[1]; -- } -- nvlist_free (response); -- } -- } --#endif -- --#if HAVE_STATX && defined STATX_BTIME -- if (ts.tv_nsec < 0) -- { -- struct statx stx; -- if ((fd < 0 -- ? statx (AT_FDCWD, filename, -- follow_links ? 0 : AT_SYMLINK_NOFOLLOW, -- STATX_BTIME, &stx) -- : statx (fd, "", AT_EMPTY_PATH, STATX_BTIME, &stx)) == 0) -- { -- if ((stx.stx_mask & STATX_BTIME) && stx.stx_btime.tv_sec != 0) -- { -- ts.tv_sec = stx.stx_btime.tv_sec; -- ts.tv_nsec = stx.stx_btime.tv_nsec; -- } -- } -- } --#endif -- -- return ts; --} -- - /* Map a TS with negative TS.tv_nsec to {0,0}. */ - static inline struct timespec - neg_to_zero (struct timespec ts) -@@ -1067,139 +1043,6 @@ getenv_quoting_style (void) - /* Equivalent to quotearg(), but explicit to avoid syntax checks. */ - #define quoteN(x) quotearg_style (get_quoting_style (NULL), x) - --/* Print stat info. Return zero upon success, nonzero upon failure. */ --static bool --print_stat (char *pformat, size_t prefix_len, unsigned int m, -- int fd, char const *filename, void const *data) --{ -- struct stat *statbuf = (struct stat *) data; -- struct passwd *pw_ent; -- struct group *gw_ent; -- bool fail = false; -- -- switch (m) -- { -- case 'n': -- out_string (pformat, prefix_len, filename); -- break; -- case 'N': -- out_string (pformat, prefix_len, quoteN (filename)); -- if (S_ISLNK (statbuf->st_mode)) -- { -- char *linkname = areadlink_with_size (filename, statbuf->st_size); -- if (linkname == NULL) -- { -- error (0, errno, _("cannot read symbolic link %s"), -- quoteaf (filename)); -- return true; -- } -- printf (" -> "); -- out_string (pformat, prefix_len, quoteN (linkname)); -- free (linkname); -- } -- break; -- case 'd': -- out_uint (pformat, prefix_len, statbuf->st_dev); -- break; -- case 'D': -- out_uint_x (pformat, prefix_len, statbuf->st_dev); -- break; -- case 'i': -- out_uint (pformat, prefix_len, statbuf->st_ino); -- break; -- case 'a': -- out_uint_o (pformat, prefix_len, statbuf->st_mode & CHMOD_MODE_BITS); -- break; -- case 'A': -- out_string (pformat, prefix_len, human_access (statbuf)); -- break; -- case 'f': -- out_uint_x (pformat, prefix_len, statbuf->st_mode); -- break; -- case 'F': -- out_string (pformat, prefix_len, file_type (statbuf)); -- break; -- case 'h': -- out_uint (pformat, prefix_len, statbuf->st_nlink); -- break; -- case 'u': -- out_uint (pformat, prefix_len, statbuf->st_uid); -- break; -- case 'U': -- pw_ent = getpwuid (statbuf->st_uid); -- out_string (pformat, prefix_len, -- pw_ent ? pw_ent->pw_name : "UNKNOWN"); -- break; -- case 'g': -- out_uint (pformat, prefix_len, statbuf->st_gid); -- break; -- case 'G': -- gw_ent = getgrgid (statbuf->st_gid); -- out_string (pformat, prefix_len, -- gw_ent ? gw_ent->gr_name : "UNKNOWN"); -- break; -- case 't': -- out_uint_x (pformat, prefix_len, major (statbuf->st_rdev)); -- break; -- case 'm': -- fail |= out_mount_point (filename, pformat, prefix_len, statbuf); -- break; -- case 'T': -- out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev)); -- break; -- case 's': -- out_int (pformat, prefix_len, statbuf->st_size); -- break; -- case 'B': -- out_uint (pformat, prefix_len, ST_NBLOCKSIZE); -- break; -- case 'b': -- out_uint (pformat, prefix_len, ST_NBLOCKS (*statbuf)); -- break; -- case 'o': -- out_uint (pformat, prefix_len, ST_BLKSIZE (*statbuf)); -- break; -- case 'w': -- { -- struct timespec t = get_birthtime (fd, filename, statbuf); -- if (t.tv_nsec < 0) -- out_string (pformat, prefix_len, "-"); -- else -- out_string (pformat, prefix_len, human_time (t)); -- } -- break; -- case 'W': -- out_epoch_sec (pformat, prefix_len, statbuf, -- neg_to_zero (get_birthtime (fd, filename, statbuf))); -- break; -- case 'x': -- out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); -- break; -- case 'X': -- out_epoch_sec (pformat, prefix_len, statbuf, get_stat_atime (statbuf)); -- break; -- case 'y': -- out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf))); -- break; -- case 'Y': -- out_epoch_sec (pformat, prefix_len, statbuf, get_stat_mtime (statbuf)); -- break; -- case 'z': -- out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf))); -- break; -- case 'Z': -- out_epoch_sec (pformat, prefix_len, statbuf, get_stat_ctime (statbuf)); -- break; -- case 'C': -- fail |= out_file_context (pformat, prefix_len, filename); -- break; -- default: -- fputc ('?', stdout); -- break; -- } -- return fail; --} -- - /* Output a single-character \ escape. */ - - static void -@@ -1241,6 +1084,17 @@ print_esc_char (char c) - putchar (c); - } - -+static size_t _GL_ATTRIBUTE_PURE -+format_code_offset (char const* directive) -+{ -+ size_t len = strspn (directive + 1, printf_flags); -+ char const *fmt_char = directive + len + 1; -+ fmt_char += strspn (fmt_char, digits); -+ if (*fmt_char == '.') -+ fmt_char += 1 + strspn (fmt_char + 1, digits); -+ return fmt_char - directive; -+} -+ - /* Print the information specified by the format string, FORMAT, - calling PRINT_FUNC for each %-directive encountered. - Return zero upon success, nonzero upon failure. */ -@@ -1270,33 +1124,28 @@ print_it (char const *format, int fd, char const *filename, - { - case '%': - { -- size_t len = strspn (b + 1, printf_flags); -- char const *fmt_char = b + len + 1; -- fmt_char += strspn (fmt_char, digits); -- if (*fmt_char == '.') -- fmt_char += 1 + strspn (fmt_char + 1, digits); -- len = fmt_char - (b + 1); -- unsigned int fmt_code = *fmt_char; -- memcpy (dest, b, len + 1); -- -- b = fmt_char; -- switch (fmt_code) -+ size_t len = format_code_offset (b); -+ char const *fmt_char = b + len; -+ memcpy (dest, b, len); -+ b += len; -+ -+ switch (*fmt_char) - { - case '\0': - --b; - FALLTHROUGH; - case '%': -- if (0 < len) -+ if (1 < len) - { -- dest[len + 1] = *fmt_char; -- dest[len + 2] = '\0'; -+ dest[len] = *fmt_char; -+ dest[len + 1] = '\0'; - die (EXIT_FAILURE, 0, _("%s: invalid directive"), - quote (dest)); - } - putchar ('%'); - break; - default: -- fail |= print_func (dest, len + 1, fmt_code, -+ fail |= print_func (dest, len, to_uchar (*fmt_char), - fd, filename, data); - break; - } -@@ -1384,6 +1233,204 @@ do_statfs (char const *filename, char const *format) - return ! fail; - } - -+struct print_args { -+ struct stat *st; -+ struct timespec btime; -+}; -+ -+/* Ask statx to avoid syncing? */ -+static bool dont_sync; -+ -+/* Ask statx to force sync? */ -+static bool force_sync; -+ -+#if USE_STATX -+/* Much of the format printing requires a struct stat or timespec */ -+static struct timespec -+statx_timestamp_to_timespec (struct statx_timestamp tsx) -+{ -+ struct timespec ts; -+ -+ ts.tv_sec = tsx.tv_sec; -+ ts.tv_nsec = tsx.tv_nsec; -+ return ts; -+} -+ -+static void -+statx_to_stat (struct statx *stx, struct stat *stat) -+{ -+ stat->st_dev = makedev (stx->stx_dev_major, stx->stx_dev_minor); -+ stat->st_ino = stx->stx_ino; -+ stat->st_mode = stx->stx_mode; -+ stat->st_nlink = stx->stx_nlink; -+ stat->st_uid = stx->stx_uid; -+ stat->st_gid = stx->stx_gid; -+ stat->st_rdev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor); -+ stat->st_size = stx->stx_size; -+ stat->st_blksize = stx->stx_blksize; -+/* define to avoid sc_prohibit_stat_st_blocks. */ -+# define SC_ST_BLOCKS st_blocks -+ stat->SC_ST_BLOCKS = stx->stx_blocks; -+ stat->st_atim = statx_timestamp_to_timespec (stx->stx_atime); -+ stat->st_mtim = statx_timestamp_to_timespec (stx->stx_mtime); -+ stat->st_ctim = statx_timestamp_to_timespec (stx->stx_ctime); -+} -+ -+static unsigned int -+fmt_to_mask (char fmt) -+{ -+ switch (fmt) -+ { -+ case 'N': -+ return STATX_MODE|STATX_SIZE; -+ case 'd': -+ case 'D': -+ return STATX_MODE; -+ case 'i': -+ return STATX_INO; -+ case 'a': -+ case 'A': -+ return STATX_MODE; -+ case 'f': -+ return STATX_MODE|STATX_TYPE; -+ case 'F': -+ return STATX_TYPE; -+ case 'h': -+ return STATX_NLINK; -+ case 'u': -+ case 'U': -+ return STATX_UID; -+ case 'g': -+ case 'G': -+ return STATX_GID; -+ case 'm': -+ return STATX_MODE|STATX_INO; -+ case 's': -+ return STATX_SIZE; -+ case 't': -+ case 'T': -+ return STATX_MODE; -+ case 'b': -+ return STATX_BLOCKS; -+ case 'w': -+ case 'W': -+ return STATX_BTIME; -+ case 'x': -+ case 'X': -+ return STATX_ATIME; -+ case 'y': -+ case 'Y': -+ return STATX_MTIME; -+ case 'z': -+ case 'Z': -+ return STATX_CTIME; -+ } -+ return 0; -+} -+ -+static unsigned int _GL_ATTRIBUTE_PURE -+format_to_mask (char const *format) -+{ -+ unsigned int mask = 0; -+ char const *b; -+ -+ for (b = format; *b; b++) -+ { -+ if (*b != '%') -+ continue; -+ -+ b += format_code_offset (b); -+ if (*b == '\0') -+ break; -+ mask |= fmt_to_mask (*b); -+ } -+ return mask; -+} -+ -+/* statx the file and print what we find */ -+static bool ATTRIBUTE_WARN_UNUSED_RESULT -+do_stat (char const *filename, char const *format, char const *format2) -+{ -+ int fd = STREQ (filename, "-") ? 0 : AT_FDCWD; -+ int flags = 0; -+ struct stat st; -+ struct statx stx; -+ const char *pathname = filename; -+ struct print_args pa; -+ pa.st = &st; -+ pa.btime = (struct timespec) {-1, -1}; -+ -+ if (AT_FDCWD != fd) -+ { -+ pathname = ""; -+ flags = AT_EMPTY_PATH; -+ } -+ else if (!follow_links) -+ { -+ flags = AT_SYMLINK_NOFOLLOW; -+ } -+ -+ if (dont_sync) -+ flags |= AT_STATX_DONT_SYNC; -+ else if (force_sync) -+ flags |= AT_STATX_FORCE_SYNC; -+ -+ fd = statx (fd, pathname, flags, format_to_mask (format), &stx); -+ if (fd < 0) -+ { -+ if (flags & AT_EMPTY_PATH) -+ error (0, errno, _("cannot stat standard input")); -+ else -+ error (0, errno, _("cannot statx %s"), quoteaf (filename)); -+ return false; -+ } -+ -+ if (S_ISBLK (stx.stx_mode) || S_ISCHR (stx.stx_mode)) -+ format = format2; -+ -+ statx_to_stat (&stx, &st); -+ if (stx.stx_mask & STATX_BTIME) -+ pa.btime = statx_timestamp_to_timespec (stx.stx_btime); -+ -+ bool fail = print_it (format, fd, filename, print_stat, &pa); -+ return ! fail; -+} -+ -+#else /* USE_STATX */ -+ -+static struct timespec -+get_birthtime (int fd, char const *filename, struct stat const *st) -+{ -+ struct timespec ts = get_stat_birthtime (st); -+ -+# if HAVE_GETATTRAT -+ if (ts.tv_nsec < 0) -+ { -+ nvlist_t *response; -+ if ((fd < 0 -+ ? getattrat (AT_FDCWD, XATTR_VIEW_READWRITE, filename, &response) -+ : fgetattr (fd, XATTR_VIEW_READWRITE, &response)) -+ == 0) -+ { -+ uint64_t *val; -+ uint_t n; -+ if (nvlist_lookup_uint64_array (response, A_CRTIME, &val, &n) == 0 -+ && 2 <= n -+ && val[0] <= TYPE_MAXIMUM (time_t) -+ && val[1] < 1000000000 * 2 /* for leap seconds */) -+ { -+ ts.tv_sec = val[0]; -+ ts.tv_nsec = val[1]; -+ } -+ nvlist_free (response); -+ } -+ } -+# endif -+ -+ return ts; -+} -+ -+ - /* stat the file and print what we find */ - static bool ATTRIBUTE_WARN_UNUSED_RESULT - do_stat (char const *filename, char const *format, -@@ -1391,6 +1438,9 @@ do_stat (char const *filename, char const *format, - { - int fd = STREQ (filename, "-") ? 0 : -1; - struct stat statbuf; -+ struct print_args pa; -+ pa.st = &statbuf; -+ pa.btime = (struct timespec) {-1, -1}; - - if (0 <= fd) - { -@@ -1414,9 +1464,152 @@ do_stat (char const *filename, char const *format, - if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode)) - format = format2; - -- bool fail = print_it (format, fd, filename, print_stat, &statbuf); -+ bool fail = print_it (format, fd, filename, print_stat, &pa); - return ! fail; - } -+#endif /* USE_STATX */ -+ -+ -+/* Print stat info. Return zero upon success, nonzero upon failure. */ -+static bool -+print_stat (char *pformat, size_t prefix_len, unsigned int m, -+ int fd, char const *filename, void const *data) -+{ -+ struct print_args *parg = (struct print_args *) data; -+ struct stat *statbuf = parg->st; -+ struct timespec btime = parg->btime; -+ struct passwd *pw_ent; -+ struct group *gw_ent; -+ bool fail = false; -+ -+ switch (m) -+ { -+ case 'n': -+ out_string (pformat, prefix_len, filename); -+ break; -+ case 'N': -+ out_string (pformat, prefix_len, quoteN (filename)); -+ if (S_ISLNK (statbuf->st_mode)) -+ { -+ char *linkname = areadlink_with_size (filename, statbuf->st_size); -+ if (linkname == NULL) -+ { -+ error (0, errno, _("cannot read symbolic link %s"), -+ quoteaf (filename)); -+ return true; -+ } -+ printf (" -> "); -+ out_string (pformat, prefix_len, quoteN (linkname)); -+ free (linkname); -+ } -+ break; -+ case 'd': -+ out_uint (pformat, prefix_len, statbuf->st_dev); -+ break; -+ case 'D': -+ out_uint_x (pformat, prefix_len, statbuf->st_dev); -+ break; -+ case 'i': -+ out_uint (pformat, prefix_len, statbuf->st_ino); -+ break; -+ case 'a': -+ out_uint_o (pformat, prefix_len, statbuf->st_mode & CHMOD_MODE_BITS); -+ break; -+ case 'A': -+ out_string (pformat, prefix_len, human_access (statbuf)); -+ break; -+ case 'f': -+ out_uint_x (pformat, prefix_len, statbuf->st_mode); -+ break; -+ case 'F': -+ out_string (pformat, prefix_len, file_type (statbuf)); -+ break; -+ case 'h': -+ out_uint (pformat, prefix_len, statbuf->st_nlink); -+ break; -+ case 'u': -+ out_uint (pformat, prefix_len, statbuf->st_uid); -+ break; -+ case 'U': -+ pw_ent = getpwuid (statbuf->st_uid); -+ out_string (pformat, prefix_len, -+ pw_ent ? pw_ent->pw_name : "UNKNOWN"); -+ break; -+ case 'g': -+ out_uint (pformat, prefix_len, statbuf->st_gid); -+ break; -+ case 'G': -+ gw_ent = getgrgid (statbuf->st_gid); -+ out_string (pformat, prefix_len, -+ gw_ent ? gw_ent->gr_name : "UNKNOWN"); -+ break; -+ case 'm': -+ fail |= out_mount_point (filename, pformat, prefix_len, statbuf); -+ break; -+ case 's': -+ out_int (pformat, prefix_len, statbuf->st_size); -+ break; -+ case 't': -+ out_uint_x (pformat, prefix_len, major (statbuf->st_rdev)); -+ break; -+ case 'T': -+ out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev)); -+ break; -+ case 'B': -+ out_uint (pformat, prefix_len, ST_NBLOCKSIZE); -+ break; -+ case 'b': -+ out_uint (pformat, prefix_len, ST_NBLOCKS (*statbuf)); -+ break; -+ case 'o': -+ out_uint (pformat, prefix_len, ST_BLKSIZE (*statbuf)); -+ break; -+ case 'w': -+ { -+#if ! USE_STATX -+ btime = get_birthtime (fd, filename, statbuf); -+#endif -+ if (btime.tv_nsec < 0) -+ out_string (pformat, prefix_len, "-"); -+ else -+ out_string (pformat, prefix_len, human_time (btime)); -+ } -+ break; -+ case 'W': -+ { -+#if ! USE_STATX -+ btime = get_birthtime (fd, filename, statbuf); -+#endif -+ out_epoch_sec (pformat, prefix_len, neg_to_zero (btime)); -+ } -+ break; -+ case 'x': -+ out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); -+ break; -+ case 'X': -+ out_epoch_sec (pformat, prefix_len, get_stat_atime (statbuf)); -+ break; -+ case 'y': -+ out_string (pformat, prefix_len, human_time (get_stat_mtime (statbuf))); -+ break; -+ case 'Y': -+ out_epoch_sec (pformat, prefix_len, get_stat_mtime (statbuf)); -+ break; -+ case 'z': -+ out_string (pformat, prefix_len, human_time (get_stat_ctime (statbuf))); -+ break; -+ case 'Z': -+ out_epoch_sec (pformat, prefix_len, get_stat_ctime (statbuf)); -+ break; -+ case 'C': -+ fail |= out_file_context (pformat, prefix_len, filename); -+ break; -+ default: -+ fputc ('?', stdout); -+ break; -+ } -+ return fail; -+} - - /* Return an allocated format string in static storage that - corresponds to whether FS and TERSE options were declared. */ -@@ -1525,6 +1718,10 @@ Display file or file system status.\n\ - fputs (_("\ - -L, --dereference follow links\n\ - -f, --file-system display file system status instead of file status\n\ -+"), stdout); -+ fputs (_("\ -+ --cached=MODE specify how to use cached attributes;\n\ -+ useful on remote file systems. See MODE below\n\ - "), stdout); - fputs (_("\ - -c --format=FORMAT use the specified FORMAT instead of the default;\n\ -@@ -1537,6 +1734,13 @@ Display file or file system status.\n\ - fputs (HELP_OPTION_DESCRIPTION, stdout); - fputs (VERSION_OPTION_DESCRIPTION, stdout); - -+ fputs (_("\n\ -+The --cached MODE argument can be; always, never, or default.\n\ -+`always` will use cached attributes if available, while\n\ -+`never` will try to synchronize with the latest attributes, and\n\ -+`default` will leave it up to the underlying file system.\n\ -+"), stdout); -+ - fputs (_("\n\ - The valid format sequences for files (without --file-system):\n\ - \n\ -@@ -1670,6 +1874,23 @@ main (int argc, char *argv[]) - terse = true; - break; - -+ case 0: -+ switch (XARGMATCH ("--cached", optarg, cached_args, cached_modes)) -+ { -+ case cached_never: -+ force_sync = true; -+ dont_sync = false; -+ break; -+ case cached_always: -+ force_sync = false; -+ dont_sync = true; -+ break; -+ case cached_default: -+ force_sync = false; -+ dont_sync = false; -+ } -+ break; -+ - case_GETOPT_HELP_CHAR; - - case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); --- -2.20.1 - - -From c19f77360d564e0c0d5ab0159299ebd8d6c34a2f Mon Sep 17 00:00:00 2001 -From: Jeff Layton -Date: Fri, 14 Jun 2019 14:37:43 -0400 -Subject: [PATCH 2/4] stat: fix enabling of statx logic - -* src/stat.c: STATX_INO isn't defined until stat.h is included. -Move the test down so it works properly. - -Upstream-commit: 0b9bac90d8283c1262e74f0dbda87583508de9a3 -Signed-off-by: Kamil Dudka ---- - src/stat.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/src/stat.c b/src/stat.c -index 3bb84f3..ec0bb7d 100644 ---- a/src/stat.c -+++ b/src/stat.c -@@ -28,12 +28,6 @@ - # define USE_STATVFS 0 - #endif - --#if HAVE_STATX && defined STATX_INO --# define USE_STATX 1 --#else --# define USE_STATX 0 --#endif -- - #include - #include - #include -@@ -80,6 +74,12 @@ - #include "find-mount-point.h" - #include "xvasprintf.h" - -+#if HAVE_STATX && defined STATX_INO -+# define USE_STATX 1 -+#else -+# define USE_STATX 0 -+#endif -+ - #if USE_STATVFS - # define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATVFS_F_FSID_IS_INTEGER - # define HAVE_STRUCT_STATXFS_F_TYPE HAVE_STRUCT_STATVFS_F_TYPE --- -2.20.1 - - -From 0081747eb0fd1eb604e1f17c8c5bfaf5119310a9 Mon Sep 17 00:00:00 2001 -From: Andreas Dilger -Date: Thu, 27 Jun 2019 02:25:55 -0600 -Subject: [PATCH 3/4] stat: don't explicitly request file size for filenames - -When calling 'stat -c %N' to print the filename, don't explicitly -request the size of the file via statx(), as it may add overhead on -some filesystems. The size is only needed to optimize an allocation -for the relatively rare case of reading a symlink name, and the worst -effect is a somewhat-too-large temporary buffer may be allocated for -areadlink_with_size(), or internal retries if buffer is too small. - -The file size will be returned by statx() on most filesystems, even -if not requested, unless the filesystem considers this to be too -expensive for that file, in which case the tradeoff is worthwhile. - -* src/stat.c: Don't explicitly request STATX_SIZE for filenames. - -Upstream-commit: a1a5e9a32eb9525680edd02fd127240c27ba0999 -Signed-off-by: Kamil Dudka ---- - src/stat.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/stat.c b/src/stat.c -index ec0bb7d..ee68f16 100644 ---- a/src/stat.c -+++ b/src/stat.c -@@ -1282,7 +1282,7 @@ fmt_to_mask (char fmt) - switch (fmt) - { - case 'N': -- return STATX_MODE|STATX_SIZE; -+ return STATX_MODE; - case 'd': - case 'D': - return STATX_MODE; -@@ -1354,7 +1354,7 @@ do_stat (char const *filename, char const *format, char const *format2) - int fd = STREQ (filename, "-") ? 0 : AT_FDCWD; - int flags = 0; - struct stat st; -- struct statx stx; -+ struct statx stx = { 0, }; - const char *pathname = filename; - struct print_args pa; - pa.st = &st; --- -2.20.1 - - -From e18c739a523f760d8372f8dd33f047a88a1b48fd Mon Sep 17 00:00:00 2001 -From: Jeff Layton -Date: Thu, 19 Sep 2019 11:59:45 -0400 -Subject: [PATCH 4/4] ls: use statx instead of stat when available - -statx allows ls to indicate interest in only certain inode metadata. -This is potentially a win on networked/clustered/distributed -file systems. In cases where we'd have to do a full, heavyweight stat() -call we can now do a much lighter statx() call. - -As a real-world example, consider a file system like CephFS where one -client is actively writing to a file and another client does an -ls --color in the same directory. --color means that we need to fetch -the mode of the file. - -Doing that with a stat() call means that we have to fetch the size and -mtime in addition to the mode. The MDS in that situation will have to -revoke caps in order to ensure that it has up-to-date values to report, -which disrupts the writer. - -This has a measurable affect on performance. I ran a fio sequential -write test on one cephfs client and had a second client do "ls --color" -in a tight loop on the directory that held the file: - -Baseline -- no activity on the second client: - -WRITE: bw=76.7MiB/s (80.4MB/s), 76.7MiB/s-76.7MiB/s (80.4MB/s-80.4MB/s), - io=4600MiB (4824MB), run=60016-60016msec - -Without this patch series, we see a noticable performance hit: - -WRITE: bw=70.4MiB/s (73.9MB/s), 70.4MiB/s-70.4MiB/s (73.9MB/s-73.9MB/s), - io=4228MiB (4433MB), run=60012-60012msec - -With this patch series, we gain most of that ground back: - -WRITE: bw=75.9MiB/s (79.6MB/s), 75.9MiB/s-75.9MiB/s (79.6MB/s-79.6MB/s), - io=4555MiB (4776MB), run=60019-60019msec - -* src/stat.c: move statx to stat struct conversion to new header... -* src/statx.h: ...here. -* src/ls.c: Add wrapper functions for stat/lstat/fstat calls, -and add variants for when we are only interested in specific info. -Add statx-enabled functions and set the request mask based on the -output format and what values are needed. - -Upstream-commit: a99ab266110795ed94a9cb4d2765ddad9c4310da -Signed-off-by: Kamil Dudka ---- - src/local.mk | 1 + - src/ls.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++--- - src/stat.c | 32 +----------- - src/statx.h | 52 ++++++++++++++++++ - 4 files changed, 192 insertions(+), 38 deletions(-) - create mode 100644 src/statx.h - -diff --git a/src/local.mk b/src/local.mk -index a69d405..6075391 100644 ---- a/src/local.mk -+++ b/src/local.mk -@@ -58,6 +58,7 @@ noinst_HEADERS = \ - src/prog-fprintf.h \ - src/remove.h \ - src/set-fields.h \ -+ src/statx.h \ - src/system.h \ - src/uname.h - -diff --git a/src/ls.c b/src/ls.c -index 120ce15..034087f 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -114,6 +114,7 @@ - #include "xgethostname.h" - #include "c-ctype.h" - #include "canonicalize.h" -+#include "statx.h" - - /* Include last to avoid a clash of - include guards with some premature versions of libcap. -@@ -1063,6 +1064,136 @@ dired_dump_obstack (const char *prefix, struct obstack *os) - } - } - -+#if HAVE_STATX && defined STATX_INO -+static unsigned int _GL_ATTRIBUTE_PURE -+time_type_to_statx (void) -+{ -+ switch (time_type) -+ { -+ case time_ctime: -+ return STATX_CTIME; -+ case time_mtime: -+ return STATX_MTIME; -+ case time_atime: -+ return STATX_ATIME; -+ default: -+ abort (); -+ } -+ return 0; -+} -+ -+static unsigned int _GL_ATTRIBUTE_PURE -+calc_req_mask (void) -+{ -+ unsigned int mask = STATX_MODE; -+ -+ if (print_inode) -+ mask |= STATX_INO; -+ -+ if (print_block_size) -+ mask |= STATX_BLOCKS; -+ -+ if (format == long_format) { -+ mask |= STATX_NLINK | STATX_SIZE | time_type_to_statx (); -+ if (print_owner || print_author) -+ mask |= STATX_UID; -+ if (print_group) -+ mask |= STATX_GID; -+ } -+ -+ switch (sort_type) -+ { -+ case sort_none: -+ case sort_name: -+ case sort_version: -+ case sort_extension: -+ break; -+ case sort_time: -+ mask |= time_type_to_statx (); -+ break; -+ case sort_size: -+ mask |= STATX_SIZE; -+ break; -+ default: -+ abort (); -+ } -+ -+ return mask; -+} -+ -+static int -+do_statx (int fd, const char *name, struct stat *st, int flags, -+ unsigned int mask) -+{ -+ struct statx stx; -+ int ret = statx (fd, name, flags, mask, &stx); -+ if (ret >= 0) -+ statx_to_stat (&stx, st); -+ return ret; -+} -+ -+static inline int -+do_stat (const char *name, struct stat *st) -+{ -+ return do_statx (AT_FDCWD, name, st, 0, calc_req_mask ()); -+} -+ -+static inline int -+do_lstat (const char *name, struct stat *st) -+{ -+ return do_statx (AT_FDCWD, name, st, AT_SYMLINK_NOFOLLOW, calc_req_mask ()); -+} -+ -+static inline int -+stat_for_mode (const char *name, struct stat *st) -+{ -+ return do_statx (AT_FDCWD, name, st, 0, STATX_MODE); -+} -+ -+/* dev+ino should be static, so no need to sync with backing store */ -+static inline int -+stat_for_ino (const char *name, struct stat *st) -+{ -+ return do_statx (AT_FDCWD, name, st, 0, STATX_INO); -+} -+ -+static inline int -+fstat_for_ino (int fd, struct stat *st) -+{ -+ return do_statx (fd, "", st, AT_EMPTY_PATH, STATX_INO); -+} -+#else -+static inline int -+do_stat (const char *name, struct stat *st) -+{ -+ return stat (name, st); -+} -+ -+static inline int -+do_lstat (const char *name, struct stat *st) -+{ -+ return lstat (name, st); -+} -+ -+static inline int -+stat_for_mode (const char *name, struct stat *st) -+{ -+ return stat (name, st); -+} -+ -+static inline int -+stat_for_ino (const char *name, struct stat *st) -+{ -+ return stat (name, st); -+} -+ -+static inline int -+fstat_for_ino (int fd, struct stat *st) -+{ -+ return fstat (fd, st); -+} -+#endif -+ - /* Return the address of the first plain %b spec in FMT, or NULL if - there is no such spec. %5b etc. do not match, so that user - widths/flags are honored. */ -@@ -2737,10 +2868,10 @@ print_dir (char const *name, char const *realname, bool command_line_arg) - struct stat dir_stat; - int fd = dirfd (dirp); - -- /* If dirfd failed, endure the overhead of using stat. */ -+ /* If dirfd failed, endure the overhead of stat'ing by path */ - if ((0 <= fd -- ? fstat (fd, &dir_stat) -- : stat (name, &dir_stat)) < 0) -+ ? fstat_for_ino (fd, &dir_stat) -+ : stat_for_ino (name, &dir_stat)) < 0) - { - file_failure (command_line_arg, - _("cannot determine device and inode of %s"), name); -@@ -3202,7 +3333,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, - switch (dereference) - { - case DEREF_ALWAYS: -- err = stat (full_name, &f->stat); -+ err = do_stat (full_name, &f->stat); - do_deref = true; - break; - -@@ -3211,7 +3342,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, - if (command_line_arg) - { - bool need_lstat; -- err = stat (full_name, &f->stat); -+ err = do_stat (full_name, &f->stat); - do_deref = true; - - if (dereference == DEREF_COMMAND_LINE_ARGUMENTS) -@@ -3231,7 +3362,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, - FALLTHROUGH; - - default: /* DEREF_NEVER */ -- err = lstat (full_name, &f->stat); -+ err = do_lstat (full_name, &f->stat); - do_deref = false; - break; - } -@@ -3320,7 +3451,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode, - they won't be traced and when no indicator is needed. */ - if (linkname - && (file_type <= indicator_style || check_symlink_mode) -- && stat (linkname, &linkstats) == 0) -+ && stat_for_mode (linkname, &linkstats) == 0) - { - f->linkok = true; - f->linkmode = linkstats.st_mode; -diff --git a/src/stat.c b/src/stat.c -index ee68f16..f2bf0dc 100644 ---- a/src/stat.c -+++ b/src/stat.c -@@ -73,6 +73,7 @@ - #include "strftime.h" - #include "find-mount-point.h" - #include "xvasprintf.h" -+#include "statx.h" - - #if HAVE_STATX && defined STATX_INO - # define USE_STATX 1 -@@ -1245,37 +1246,6 @@ static bool dont_sync; - static bool force_sync; - - #if USE_STATX --/* Much of the format printing requires a struct stat or timespec */ --static struct timespec --statx_timestamp_to_timespec (struct statx_timestamp tsx) --{ -- struct timespec ts; -- -- ts.tv_sec = tsx.tv_sec; -- ts.tv_nsec = tsx.tv_nsec; -- return ts; --} -- --static void --statx_to_stat (struct statx *stx, struct stat *stat) --{ -- stat->st_dev = makedev (stx->stx_dev_major, stx->stx_dev_minor); -- stat->st_ino = stx->stx_ino; -- stat->st_mode = stx->stx_mode; -- stat->st_nlink = stx->stx_nlink; -- stat->st_uid = stx->stx_uid; -- stat->st_gid = stx->stx_gid; -- stat->st_rdev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor); -- stat->st_size = stx->stx_size; -- stat->st_blksize = stx->stx_blksize; --/* define to avoid sc_prohibit_stat_st_blocks. */ --# define SC_ST_BLOCKS st_blocks -- stat->SC_ST_BLOCKS = stx->stx_blocks; -- stat->st_atim = statx_timestamp_to_timespec (stx->stx_atime); -- stat->st_mtim = statx_timestamp_to_timespec (stx->stx_mtime); -- stat->st_ctim = statx_timestamp_to_timespec (stx->stx_ctime); --} -- - static unsigned int - fmt_to_mask (char fmt) - { -diff --git a/src/statx.h b/src/statx.h -new file mode 100644 -index 0000000..19f3e18 ---- /dev/null -+++ b/src/statx.h -@@ -0,0 +1,52 @@ -+/* statx -> stat conversion functions for coreutils -+ Copyright (C) 2019 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 . */ -+ -+#ifndef COREUTILS_STATX_H -+# define COREUTILS_STATX_H -+ -+# if HAVE_STATX && defined STATX_INO -+/* Much of the format printing requires a struct stat or timespec */ -+static inline struct timespec -+statx_timestamp_to_timespec (struct statx_timestamp tsx) -+{ -+ struct timespec ts; -+ -+ ts.tv_sec = tsx.tv_sec; -+ ts.tv_nsec = tsx.tv_nsec; -+ return ts; -+} -+ -+static inline void -+statx_to_stat (struct statx *stx, struct stat *stat) -+{ -+ stat->st_dev = makedev (stx->stx_dev_major, stx->stx_dev_minor); -+ stat->st_ino = stx->stx_ino; -+ stat->st_mode = stx->stx_mode; -+ stat->st_nlink = stx->stx_nlink; -+ stat->st_uid = stx->stx_uid; -+ stat->st_gid = stx->stx_gid; -+ stat->st_rdev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor); -+ stat->st_size = stx->stx_size; -+ stat->st_blksize = stx->stx_blksize; -+/* define to avoid sc_prohibit_stat_st_blocks. */ -+# define SC_ST_BLOCKS st_blocks -+ stat->SC_ST_BLOCKS = stx->stx_blocks; -+ stat->st_atim = statx_timestamp_to_timespec (stx->stx_atime); -+ stat->st_mtim = statx_timestamp_to_timespec (stx->stx_mtime); -+ stat->st_ctim = statx_timestamp_to_timespec (stx->stx_ctime); -+} -+# endif /* HAVE_STATX && defined STATX_INO */ -+#endif /* COREUTILS_STATX_H */ --- -2.20.1 - diff --git a/coreutils.spec b/coreutils.spec index daff9d3..85d5eff 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.31 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -16,9 +16,6 @@ Source106: coreutils-colorls.csh # md5sum,b2sum,sha*sum: --help: add note about binary/text mode Patch1: coreutils-8.31-sums-man-pages.patch -# use statx instead of stat when available (#1760300) -Patch2: coreutils-8.31-statx.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -238,6 +235,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Oct 17 2019 Kamil Dudka - 8.31-6 +- temporarily disable the use of statx (#1760300) + * Fri Oct 11 2019 Kamil Dudka - 8.31-5 - use statx instead of stat when available (#1760300) From 4f1cea8bdab593fb172e689d7870948f7fc24150 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Tue, 28 Jan 2020 14:49:55 +0000 Subject: [PATCH 398/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 85d5eff..fdf6ea4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.31 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -235,6 +235,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jan 28 2020 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + * Thu Oct 17 2019 Kamil Dudka - 8.31-6 - temporarily disable the use of statx (#1760300) From 788bd804ffbd8b286bb0e38d1146d74258b14de3 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 30 Jan 2020 15:02:20 +0100 Subject: [PATCH 399/523] skip a test that relies on /proc/kallsyms having immutable content --- ...8.31-disable-test-cp-proc-short-read.patch | 26 +++++++++++++++++++ coreutils.spec | 8 +++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.31-disable-test-cp-proc-short-read.patch diff --git a/coreutils-8.31-disable-test-cp-proc-short-read.patch b/coreutils-8.31-disable-test-cp-proc-short-read.patch new file mode 100644 index 0000000..bc2777a --- /dev/null +++ b/coreutils-8.31-disable-test-cp-proc-short-read.patch @@ -0,0 +1,26 @@ +From 0618c1b3b62cd68d22371b55fe6ca9dc8a00ea51 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 30 Jan 2020 14:58:37 +0100 +Subject: [PATCH] tests/cp/proc-short-read.sh: skip unreliable test + +Bug: https://debbugs.gnu.org/39357 +--- + tests/cp/proc-short-read.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/cp/proc-short-read.sh b/tests/cp/proc-short-read.sh +index e466720..2a61127 100755 +--- a/tests/cp/proc-short-read.sh ++++ b/tests/cp/proc-short-read.sh +@@ -21,7 +21,7 @@ print_ver_ cp + + kall=/proc/kallsyms + +-test -r $kall || skip_ "your system lacks $kall" ++skip_ "If the content of $kall changed on the fly, this test would fail." + + # Before coreutils-7.3, cp would copy less than 4KiB of this 1MB+ file. + cp $kall 1 || fail=1 +-- +2.21.1 + diff --git a/coreutils.spec b/coreutils.spec index fdf6ea4..3a4cd07 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.31 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -16,6 +16,9 @@ Source106: coreutils-colorls.csh # md5sum,b2sum,sha*sum: --help: add note about binary/text mode Patch1: coreutils-8.31-sums-man-pages.patch +# skip a test that relies on /proc/kallsyms having immutable content +Patch2: coreutils-8.31-disable-test-cp-proc-short-read.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -235,6 +238,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jan 30 2020 Kamil Dudka - 8.31-8 +- skip a test that relies on /proc/kallsyms having immutable content + * Tue Jan 28 2020 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild From 3957dee9a42bd2a643c29068b2003cf88d233fcf Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 5 Feb 2020 09:58:24 +0100 Subject: [PATCH 400/523] use upstream fix the cp/proc-short-read test --- ...8.31-disable-test-cp-proc-short-read.patch | 26 --------- ...8.31-improve-test-cp-proc-short-read.patch | 54 +++++++++++++++++++ coreutils.spec | 9 ++-- 3 files changed, 60 insertions(+), 29 deletions(-) delete mode 100644 coreutils-8.31-disable-test-cp-proc-short-read.patch create mode 100644 coreutils-8.31-improve-test-cp-proc-short-read.patch diff --git a/coreutils-8.31-disable-test-cp-proc-short-read.patch b/coreutils-8.31-disable-test-cp-proc-short-read.patch deleted file mode 100644 index bc2777a..0000000 --- a/coreutils-8.31-disable-test-cp-proc-short-read.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0618c1b3b62cd68d22371b55fe6ca9dc8a00ea51 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 30 Jan 2020 14:58:37 +0100 -Subject: [PATCH] tests/cp/proc-short-read.sh: skip unreliable test - -Bug: https://debbugs.gnu.org/39357 ---- - tests/cp/proc-short-read.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/cp/proc-short-read.sh b/tests/cp/proc-short-read.sh -index e466720..2a61127 100755 ---- a/tests/cp/proc-short-read.sh -+++ b/tests/cp/proc-short-read.sh -@@ -21,7 +21,7 @@ print_ver_ cp - - kall=/proc/kallsyms - --test -r $kall || skip_ "your system lacks $kall" -+skip_ "If the content of $kall changed on the fly, this test would fail." - - # Before coreutils-7.3, cp would copy less than 4KiB of this 1MB+ file. - cp $kall 1 || fail=1 --- -2.21.1 - diff --git a/coreutils-8.31-improve-test-cp-proc-short-read.patch b/coreutils-8.31-improve-test-cp-proc-short-read.patch new file mode 100644 index 0000000..188a75e --- /dev/null +++ b/coreutils-8.31-improve-test-cp-proc-short-read.patch @@ -0,0 +1,54 @@ +From fb4cb651666adb43e8b332de95616e250b4d16f7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Tue, 4 Feb 2020 00:37:23 +0000 +Subject: [PATCH] tests: avoid false failure due to varying /proc/kallsyms + +* tests/cp/proc-short-read.sh: Switch to using /proc/cpuinfo, +rather than /proc/kallsyms which was seen to vary in some cases. +Fixes https://bugs.gnu.org/39357 + +Upstream-commit: ab108667ba6112efdd42f9618a1920dc9b8f6e51 +Signed-off-by: Kamil Dudka +--- + tests/cp/proc-short-read.sh | 22 +++++++++------------- + 1 file changed, 9 insertions(+), 13 deletions(-) + +diff --git a/tests/cp/proc-short-read.sh b/tests/cp/proc-short-read.sh +index 6c58881de..dcc8b30d5 100755 +--- a/tests/cp/proc-short-read.sh ++++ b/tests/cp/proc-short-read.sh +@@ -19,22 +19,18 @@ + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ cp + +-kall=/proc/kallsyms ++proc_large=/proc/cpuinfo # usually > 4KiB + +-test -r $kall || skip_ "your system lacks $kall" ++test -r $proc_large || skip_ "your system lacks $proc_large" + +-# Before coreutils-7.3, cp would copy less than 4KiB of this 1MB+ file. +-cp $kall 1 || fail=1 +-cat $kall > 2 || fail=1 +-compare 1 2 || fail=1 ++# Before coreutils-7.3, cp would copy less than 4KiB of this file. ++cp $proc_large 1 || fail=1 ++cat $proc_large > 2 || fail=1 + +-# Also check md5sum, just for good measure. +-md5sum $kall > 3 || fail=1 +-md5sum 2 > 4 || fail=1 ++# adjust varying parts ++sed '/MHz/d; /bogomips/d;' 1 > proc.cp || framework_failure_ ++sed '/MHz/d; /bogomips/d;' 2 > proc.cat || framework_failure_ + +-# Remove each file name before comparing checksums. +-sed 's/ .*//' 3 > sum.proc || fail=1 +-sed 's/ .*//' 4 > sum.2 || fail=1 +-compare sum.proc sum.2 || fail=1 ++compare proc.cp proc.cat || fail=1 + + Exit $fail +-- +2.21.1 + diff --git a/coreutils.spec b/coreutils.spec index 3a4cd07..9aa7e7b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.31 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -16,8 +16,8 @@ Source106: coreutils-colorls.csh # md5sum,b2sum,sha*sum: --help: add note about binary/text mode Patch1: coreutils-8.31-sums-man-pages.patch -# skip a test that relies on /proc/kallsyms having immutable content -Patch2: coreutils-8.31-disable-test-cp-proc-short-read.patch +# improve an upstream test that relied on /proc/kallsyms being immutable +Patch2: coreutils-8.31-improve-test-cp-proc-short-read.patch # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -238,6 +238,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Feb 05 2020 Kamil Dudka - 8.31-9 +- use upstream fix the cp/proc-short-read test + * Thu Jan 30 2020 Kamil Dudka - 8.31-8 - skip a test that relies on /proc/kallsyms having immutable content From 3dbfd57eacd6275582674c557ab7811917c92ffb Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 11 Feb 2020 10:36:16 +0100 Subject: [PATCH 401/523] Resolves: #1800597 - make upstream test-suite work with root privileges --- coreutils-8.31-root-tests.patch | 71 +++++++++++++++++++++++++++++++++ coreutils.spec | 8 +++- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.31-root-tests.patch diff --git a/coreutils-8.31-root-tests.patch b/coreutils-8.31-root-tests.patch new file mode 100644 index 0000000..02a150a --- /dev/null +++ b/coreutils-8.31-root-tests.patch @@ -0,0 +1,71 @@ +From 57324f74fb8855d4888b1e6b6dbaaec781bb6db9 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Fri, 7 Feb 2020 17:05:06 +0100 +Subject: [PATCH] tests: ensure tests/cp/preserve-gid.sh works with single + binary + +* tests/cp/preserve-gid.sh: If configured with --enable-single-binary +copy the coreutils single binary, instead of the cp one-line launcher. + +Discussed at https://bugzilla.redhat.com/1800597 +Fixes https://bugs.gnu.org/39485 + +Upstream-commit: b96b1a47286632fd1cb738cf5a9893cf72a70d30 +Signed-off-by: Kamil Dudka +--- + tests/cp/preserve-gid.sh | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/tests/cp/preserve-gid.sh b/tests/cp/preserve-gid.sh +index e48584c1e..bba09df09 100755 +--- a/tests/cp/preserve-gid.sh ++++ b/tests/cp/preserve-gid.sh +@@ -110,7 +110,14 @@ cleanup_() { rm -rf "$tmp_path"; } + # is not readable by our nameless IDs. + test -d /tmp && TMPDIR=/tmp + tmp_path=$(mktemp -d) || fail_ "failed to create temporary directory" +-cp "$abs_path_dir_/cp" "$tmp_path" ++if test -x "$abs_path_dir_/coreutils" && ++ { test -l "$abs_path_dir_/cp" || ++ test $(wc -l < "$abs_path_dir_/cp") = 1; } then ++ # if configured with --enable-single-binary we need to use the single binary ++ cp "$abs_path_dir_/coreutils" "$tmp_path/cp" || framework_failure_ ++else ++ cp "$abs_path_dir_/cp" "$tmp_path" ++fi + chmod -R a+rx "$tmp_path" + + t1() { +-- +2.21.1 + +From 94a47b51e64c21fef4ad8faca1599099c459b2ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Mon, 10 Feb 2020 15:05:43 +0000 +Subject: [PATCH] tests: fix test for symlink + +* tests/cp/preserve-gid.sh: s/-l/-L/. +Reported by Kamil Dudka + +Upstream-commit: 3150f4a82ef6542c4a8f0bf413815e78766f044f +Signed-off-by: Kamil Dudka +--- + tests/cp/preserve-gid.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/cp/preserve-gid.sh b/tests/cp/preserve-gid.sh +index bba09df09..547bf66bc 100755 +--- a/tests/cp/preserve-gid.sh ++++ b/tests/cp/preserve-gid.sh +@@ -111,7 +111,7 @@ cleanup_() { rm -rf "$tmp_path"; } + test -d /tmp && TMPDIR=/tmp + tmp_path=$(mktemp -d) || fail_ "failed to create temporary directory" + if test -x "$abs_path_dir_/coreutils" && +- { test -l "$abs_path_dir_/cp" || ++ { test -L "$abs_path_dir_/cp" || + test $(wc -l < "$abs_path_dir_/cp") = 1; } then + # if configured with --enable-single-binary we need to use the single binary + cp "$abs_path_dir_/coreutils" "$tmp_path/cp" || framework_failure_ +-- +2.21.1 + diff --git a/coreutils.spec b/coreutils.spec index 9aa7e7b..11cfbec 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.31 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -19,6 +19,9 @@ Patch1: coreutils-8.31-sums-man-pages.patch # improve an upstream test that relied on /proc/kallsyms being immutable Patch2: coreutils-8.31-improve-test-cp-proc-short-read.patch +# make upstream test-suite work with root privileges (#1800597) +Patch3: coreutils-8.31-root-tests.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -238,6 +241,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Feb 11 2020 Kamil Dudka - 8.31-10 +- make upstream test-suite work with root privileges (#1800597) + * Wed Feb 05 2020 Kamil Dudka - 8.31-9 - use upstream fix the cp/proc-short-read test From 00f87f4b8842b2577b725e8d417c245e869b82ad Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 5 Mar 2020 16:49:14 +0100 Subject: [PATCH 402/523] new upstream release 8.32 --- ...8.31-improve-test-cp-proc-short-read.patch | 54 -------------- coreutils-8.31-root-tests.patch | 71 ------------------- coreutils-8.31-sums-man-pages.patch | 36 ---------- coreutils-8.31.tar.xz.sig | 17 ----- coreutils-8.32.tar.xz.sig | 16 +++++ coreutils.spec | 16 ++--- sources | 2 +- 7 files changed, 22 insertions(+), 190 deletions(-) delete mode 100644 coreutils-8.31-improve-test-cp-proc-short-read.patch delete mode 100644 coreutils-8.31-root-tests.patch delete mode 100644 coreutils-8.31-sums-man-pages.patch delete mode 100644 coreutils-8.31.tar.xz.sig create mode 100644 coreutils-8.32.tar.xz.sig diff --git a/coreutils-8.31-improve-test-cp-proc-short-read.patch b/coreutils-8.31-improve-test-cp-proc-short-read.patch deleted file mode 100644 index 188a75e..0000000 --- a/coreutils-8.31-improve-test-cp-proc-short-read.patch +++ /dev/null @@ -1,54 +0,0 @@ -From fb4cb651666adb43e8b332de95616e250b4d16f7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Tue, 4 Feb 2020 00:37:23 +0000 -Subject: [PATCH] tests: avoid false failure due to varying /proc/kallsyms - -* tests/cp/proc-short-read.sh: Switch to using /proc/cpuinfo, -rather than /proc/kallsyms which was seen to vary in some cases. -Fixes https://bugs.gnu.org/39357 - -Upstream-commit: ab108667ba6112efdd42f9618a1920dc9b8f6e51 -Signed-off-by: Kamil Dudka ---- - tests/cp/proc-short-read.sh | 22 +++++++++------------- - 1 file changed, 9 insertions(+), 13 deletions(-) - -diff --git a/tests/cp/proc-short-read.sh b/tests/cp/proc-short-read.sh -index 6c58881de..dcc8b30d5 100755 ---- a/tests/cp/proc-short-read.sh -+++ b/tests/cp/proc-short-read.sh -@@ -19,22 +19,18 @@ - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ cp - --kall=/proc/kallsyms -+proc_large=/proc/cpuinfo # usually > 4KiB - --test -r $kall || skip_ "your system lacks $kall" -+test -r $proc_large || skip_ "your system lacks $proc_large" - --# Before coreutils-7.3, cp would copy less than 4KiB of this 1MB+ file. --cp $kall 1 || fail=1 --cat $kall > 2 || fail=1 --compare 1 2 || fail=1 -+# Before coreutils-7.3, cp would copy less than 4KiB of this file. -+cp $proc_large 1 || fail=1 -+cat $proc_large > 2 || fail=1 - --# Also check md5sum, just for good measure. --md5sum $kall > 3 || fail=1 --md5sum 2 > 4 || fail=1 -+# adjust varying parts -+sed '/MHz/d; /bogomips/d;' 1 > proc.cp || framework_failure_ -+sed '/MHz/d; /bogomips/d;' 2 > proc.cat || framework_failure_ - --# Remove each file name before comparing checksums. --sed 's/ .*//' 3 > sum.proc || fail=1 --sed 's/ .*//' 4 > sum.2 || fail=1 --compare sum.proc sum.2 || fail=1 -+compare proc.cp proc.cat || fail=1 - - Exit $fail --- -2.21.1 - diff --git a/coreutils-8.31-root-tests.patch b/coreutils-8.31-root-tests.patch deleted file mode 100644 index 02a150a..0000000 --- a/coreutils-8.31-root-tests.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 57324f74fb8855d4888b1e6b6dbaaec781bb6db9 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Fri, 7 Feb 2020 17:05:06 +0100 -Subject: [PATCH] tests: ensure tests/cp/preserve-gid.sh works with single - binary - -* tests/cp/preserve-gid.sh: If configured with --enable-single-binary -copy the coreutils single binary, instead of the cp one-line launcher. - -Discussed at https://bugzilla.redhat.com/1800597 -Fixes https://bugs.gnu.org/39485 - -Upstream-commit: b96b1a47286632fd1cb738cf5a9893cf72a70d30 -Signed-off-by: Kamil Dudka ---- - tests/cp/preserve-gid.sh | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/tests/cp/preserve-gid.sh b/tests/cp/preserve-gid.sh -index e48584c1e..bba09df09 100755 ---- a/tests/cp/preserve-gid.sh -+++ b/tests/cp/preserve-gid.sh -@@ -110,7 +110,14 @@ cleanup_() { rm -rf "$tmp_path"; } - # is not readable by our nameless IDs. - test -d /tmp && TMPDIR=/tmp - tmp_path=$(mktemp -d) || fail_ "failed to create temporary directory" --cp "$abs_path_dir_/cp" "$tmp_path" -+if test -x "$abs_path_dir_/coreutils" && -+ { test -l "$abs_path_dir_/cp" || -+ test $(wc -l < "$abs_path_dir_/cp") = 1; } then -+ # if configured with --enable-single-binary we need to use the single binary -+ cp "$abs_path_dir_/coreutils" "$tmp_path/cp" || framework_failure_ -+else -+ cp "$abs_path_dir_/cp" "$tmp_path" -+fi - chmod -R a+rx "$tmp_path" - - t1() { --- -2.21.1 - -From 94a47b51e64c21fef4ad8faca1599099c459b2ad Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Mon, 10 Feb 2020 15:05:43 +0000 -Subject: [PATCH] tests: fix test for symlink - -* tests/cp/preserve-gid.sh: s/-l/-L/. -Reported by Kamil Dudka - -Upstream-commit: 3150f4a82ef6542c4a8f0bf413815e78766f044f -Signed-off-by: Kamil Dudka ---- - tests/cp/preserve-gid.sh | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tests/cp/preserve-gid.sh b/tests/cp/preserve-gid.sh -index bba09df09..547bf66bc 100755 ---- a/tests/cp/preserve-gid.sh -+++ b/tests/cp/preserve-gid.sh -@@ -111,7 +111,7 @@ cleanup_() { rm -rf "$tmp_path"; } - test -d /tmp && TMPDIR=/tmp - tmp_path=$(mktemp -d) || fail_ "failed to create temporary directory" - if test -x "$abs_path_dir_/coreutils" && -- { test -l "$abs_path_dir_/cp" || -+ { test -L "$abs_path_dir_/cp" || - test $(wc -l < "$abs_path_dir_/cp") = 1; } then - # if configured with --enable-single-binary we need to use the single binary - cp "$abs_path_dir_/coreutils" "$tmp_path/cp" || framework_failure_ --- -2.21.1 - diff --git a/coreutils-8.31-sums-man-pages.patch b/coreutils-8.31-sums-man-pages.patch deleted file mode 100644 index 094aaaa..0000000 --- a/coreutils-8.31-sums-man-pages.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ef6be60dcaf424bdb21392aff42331bd4dc272e0 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 14 Mar 2019 13:48:01 +0100 -Subject: [PATCH] md5sum,b2sum,sha*sum: --help: add note about binary/text mode - -* src/md5sum.c (usage): Make it clear that there is no difference -between binary mode and text mode on GNU systems. - -Bug: https://bugzilla.redhat.com/406981 -Bug: https://bugzilla.redhat.com/1688740 - -Upstream-commit: ae61b1066351bb784b54fbfd7b52caf129ec286c -Signed-off-by: Kamil Dudka ---- - src/md5sum.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/md5sum.c b/src/md5sum.c -index 3532f7b7a..f75b6de02 100644 ---- a/src/md5sum.c -+++ b/src/md5sum.c -@@ -287,7 +287,10 @@ The following five options are useful only when verifying checksums:\n\ - The sums are computed as described in %s. When checking, the input\n\ - should be a former output of this program. The default mode is to print a\n\ - line with checksum, a space, a character indicating input mode ('*' for binary,\ --\n' ' for text or where binary is insignificant), and name for each FILE.\n"), -+\n' ' for text or where binary is insignificant), and name for each FILE.\n\ -+\n\ -+Note: There is no difference between binary mode and text mode on GNU systems.\ -+\n"), - DIGEST_REFERENCE); - emit_ancillary_info (PROGRAM_NAME); - } --- -2.17.2 - diff --git a/coreutils-8.31.tar.xz.sig b/coreutils-8.31.tar.xz.sig deleted file mode 100644 index 5aa60a1..0000000 --- a/coreutils-8.31.tar.xz.sig +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2 - -iQIcBAABCAAGBQJchaqkAAoJEN9v2XEwYDfZKBMQAJNjmYU6VrbHvlSJm1d+9Qch -rvVtE5VGsTj3jUj1dh9MpuN9GhJifWJat9DEKUat0J4Z5G8d55LvyzQJppby2az2 -kwbp/ffK0wR1tfGNii3Hop3pMVizqJn+LbT01qcS3E7tVQ2nJP/JVIeXOtOf9kJk -gPviDaqO8OUiV2l3gCwLtuOETKHXRGyraWRxCb9ZxOS12Gspqfwui7t4jQUDf2Ge -Kvhcawas+XomGdWx+io/VxwkOZkOCr9vQdMM7ZqLDnu+d7nGsnPMxxdGcP72WBnV -1LxFxHIel52yuRh3T1RggQMKxXPFPEyDRgaBNN0Yfk3a2CHFHf+YtySgLzKSqyS5 -1P5syvSbNj9ASEuX428lpwI3EC5G3T9W/MLTKUpwVhfU8/WELI261F95dnFIfoar -mMPqbBMHwHpIasJfDy60m8H8/z8PEOmpRP0xfAuOtf47YpDLsH+AvrAJM4CH9kkS -lysMUZITyIqUBSoUs8mVygV7b4mq2X2US0Mkja/hDFAcq2O7m2eyvi61z7Oa1Y/r -tV+q/XS8ZTOtSTBBZzRVTJDPno1ZwFBl/MIiD5FgF7szgiR2z0KVMfAlVBdQwxKw -Mj6N/HYeP6yE3g9I5+8LmRLwQcXeC2B0ZzpvGE7DaKd5aFDC6YVDD8wyLEQFDAav -XGtN62+yfXArdYVjXygm -=LVk4 ------END PGP SIGNATURE----- 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.spec b/coreutils.spec index 11cfbec..2dbf3f3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.31 -Release: 10%{?dist} +Version: 8.32 +Release: 1%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -13,15 +13,6 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ -# md5sum,b2sum,sha*sum: --help: add note about binary/text mode -Patch1: coreutils-8.31-sums-man-pages.patch - -# improve an upstream test that relied on /proc/kallsyms being immutable -Patch2: coreutils-8.31-improve-test-cp-proc-short-read.patch - -# make upstream test-suite work with root privileges (#1800597) -Patch3: coreutils-8.31-root-tests.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -241,6 +232,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Mar 05 2020 Kamil Dudka - 8.32-1 +- new upstream release 8.32 + * Tue Feb 11 2020 Kamil Dudka - 8.31-10 - make upstream test-suite work with root privileges (#1800597) diff --git a/sources b/sources index ca35b8f..97fe361 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (coreutils-8.31.tar.xz) = ef8941dae845bbf5ae5838bc49e44554a766302930601aada6fa594e8088f0fbad74e481ee392ff89633e68b99e4da3f761fcb5d31ee3b233d540fe2a2d4e1af +SHA512 (coreutils-8.32.tar.xz) = 1c8f3584efd61b4b02e7ac5db8e103b63cfb2063432caaf1e64cb2dcc56d8c657d1133bbf10bd41468d6a1f31142e6caa81d16ae68fa3e6e84075c253613a145 From 46d49783fec232e87bf9eb6a6c1f74df8acc9479 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 28 Feb 2020 15:25:43 +0100 Subject: [PATCH 403/523] adapt DIR_COLORS patch for the new release ... and make it easier to maintain (by using sed for substitutions). --- ...S.patch => coreutils-8.32-DIR_COLORS.patch | 491 +----------------- coreutils.spec | 18 +- 2 files changed, 24 insertions(+), 485 deletions(-) rename coreutils-8.25-DIR_COLORS.patch => coreutils-8.32-DIR_COLORS.patch (55%) diff --git a/coreutils-8.25-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch similarity index 55% rename from coreutils-8.25-DIR_COLORS.patch rename to coreutils-8.32-DIR_COLORS.patch index 26acdf9..61a3db3 100644 --- a/coreutils-8.25-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -1,16 +1,16 @@ -From a13bc34f1eeebdf8b87e4b5a570341bb77a62f76 Mon Sep 17 00:00:00 2001 +From 81e25c8521937ecf7f444bab11fddaaf81cc3efd Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 17 Jun 2016 16:58:18 +0200 Subject: [PATCH] downstream changes to default DIR_COLORS --- - DIR_COLORS | 41 ++++--- - DIR_COLORS.256color | 300 ++++++++++++++++++++++++------------------------ - DIR_COLORS.lightbgcolor | 211 ++++++++++++++++++---------------- - 3 files changed, 283 insertions(+), 269 deletions(-) + DIR_COLORS | 9 ++++- + DIR_COLORS.256color | 78 ++++++++++++++++++++--------------------- + DIR_COLORS.lightbgcolor | 21 +++++++---- + 3 files changed, 61 insertions(+), 47 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS -index d2ea453..27af9d7 100644 +index bd5df23..84f2417 100644 --- a/DIR_COLORS +++ b/DIR_COLORS @@ -1,3 +1,7 @@ @@ -40,46 +40,8 @@ index d2ea453..27af9d7 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -186,21 +193,21 @@ EXEC 01;32 - .ogx 01;35 - - # audio formats --.aac 00;36 --.au 00;36 --.flac 00;36 --.m4a 00;36 --.mid 00;36 --.midi 00;36 --.mka 00;36 --.mp3 00;36 --.mpc 00;36 --.ogg 00;36 --.ra 00;36 --.wav 00;36 -+.aac 01;36 -+.au 01;36 -+.flac 01;36 -+.m4a 01;36 -+.mid 01;36 -+.midi 01;36 -+.mka 01;36 -+.mp3 01;36 -+.mpc 01;36 -+.ogg 01;36 -+.ra 01;36 -+.wav 01;36 - - # https://wiki.xiph.org/MIME_Types_and_File_Extensions --.oga 00;36 --.opus 00;36 --.spx 00;36 --.xspf 00;36 -+.oga 01;36 -+.opus 01;36 -+.spx 01;36 -+.xspf 01;36 diff --git a/DIR_COLORS.256color b/DIR_COLORS.256color -index d2ea453..74c34ba 100644 +index 85bd28d..7f6d4c8 100644 --- a/DIR_COLORS.256color +++ b/DIR_COLORS.256color @@ -1,3 +1,9 @@ @@ -187,242 +149,8 @@ index d2ea453..74c34ba 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -85,122 +83,122 @@ EXEC 01;32 - #.csh 01;32 - - # archives or compressed (bright red) --.tar 01;31 --.tgz 01;31 --.arc 01;31 --.arj 01;31 --.taz 01;31 --.lha 01;31 --.lz4 01;31 --.lzh 01;31 --.lzma 01;31 --.tlz 01;31 --.txz 01;31 --.tzo 01;31 --.t7z 01;31 --.zip 01;31 --.z 01;31 --.dz 01;31 --.gz 01;31 --.lrz 01;31 --.lz 01;31 --.lzo 01;31 --.xz 01;31 --.zst 01;31 --.tzst 01;31 --.bz2 01;31 --.bz 01;31 --.tbz 01;31 --.tbz2 01;31 --.tz 01;31 --.deb 01;31 --.rpm 01;31 --.jar 01;31 --.war 01;31 --.ear 01;31 --.sar 01;31 --.rar 01;31 --.alz 01;31 --.ace 01;31 --.zoo 01;31 --.cpio 01;31 --.7z 01;31 --.rz 01;31 --.cab 01;31 --.wim 01;31 --.swm 01;31 --.dwm 01;31 --.esd 01;31 -+.tar 38;5;9 -+.tgz 38;5;9 -+.arc 38;5;9 -+.arj 38;5;9 -+.taz 38;5;9 -+.lha 38;5;9 -+.lz4 38;5;9 -+.lzh 38;5;9 -+.lzma 38;5;9 -+.tlz 38;5;9 -+.txz 38;5;9 -+.tzo 38;5;9 -+.t7z 38;5;9 -+.zip 38;5;9 -+.z 38;5;9 -+.dz 38;5;9 -+.gz 38;5;9 -+.lrz 38;5;9 -+.lz 38;5;9 -+.lzo 38;5;9 -+.xz 38;5;9 -+.zst 38;5;9 -+.tzst 38;5;9 -+.bz2 38;5;9 -+.bz 38;5;9 -+.tbz 38;5;9 -+.tbz2 38;5;9 -+.tz 38;5;9 -+.deb 38;5;9 -+.rpm 38;5;9 -+.jar 38;5;9 -+.war 38;5;9 -+.ear 38;5;9 -+.sar 38;5;9 -+.rar 38;5;9 -+.alz 38;5;9 -+.ace 38;5;9 -+.zoo 38;5;9 -+.cpio 38;5;9 -+.7z 38;5;9 -+.rz 38;5;9 -+.cab 38;5;9 -+.wim 38;5;9 -+.swm 38;5;9 -+.dwm 38;5;9 -+.esd 38;5;9 - - # image formats --.jpg 01;35 --.jpeg 01;35 --.mjpg 01;35 --.mjpeg 01;35 --.gif 01;35 --.bmp 01;35 --.pbm 01;35 --.pgm 01;35 --.ppm 01;35 --.tga 01;35 --.xbm 01;35 --.xpm 01;35 --.tif 01;35 --.tiff 01;35 --.png 01;35 --.svg 01;35 --.svgz 01;35 --.mng 01;35 --.pcx 01;35 --.mov 01;35 --.mpg 01;35 --.mpeg 01;35 --.m2v 01;35 --.mkv 01;35 --.webm 01;35 --.ogm 01;35 --.mp4 01;35 --.m4v 01;35 --.mp4v 01;35 --.vob 01;35 --.qt 01;35 --.nuv 01;35 --.wmv 01;35 --.asf 01;35 --.rm 01;35 --.rmvb 01;35 --.flc 01;35 --.avi 01;35 --.fli 01;35 --.flv 01;35 --.gl 01;35 --.dl 01;35 --.xcf 01;35 --.xwd 01;35 --.yuv 01;35 --.cgm 01;35 --.emf 01;35 -+.jpg 38;5;13 -+.jpeg 38;5;13 -+.mjpg 38;5;13 -+.mjpeg 38;5;13 -+.gif 38;5;13 -+.bmp 38;5;13 -+.pbm 38;5;13 -+.pgm 38;5;13 -+.ppm 38;5;13 -+.tga 38;5;13 -+.xbm 38;5;13 -+.xpm 38;5;13 -+.tif 38;5;13 -+.tiff 38;5;13 -+.png 38;5;13 -+.svg 38;5;13 -+.svgz 38;5;13 -+.mng 38;5;13 -+.pcx 38;5;13 -+.mov 38;5;13 -+.mpg 38;5;13 -+.mpeg 38;5;13 -+.m2v 38;5;13 -+.mkv 38;5;13 -+.webm 38;5;13 -+.ogm 38;5;13 -+.mp4 38;5;13 -+.m4v 38;5;13 -+.mp4v 38;5;13 -+.vob 38;5;13 -+.qt 38;5;13 -+.nuv 38;5;13 -+.wmv 38;5;13 -+.asf 38;5;13 -+.rm 38;5;13 -+.rmvb 38;5;13 -+.flc 38;5;13 -+.avi 38;5;13 -+.fli 38;5;13 -+.flv 38;5;13 -+.gl 38;5;13 -+.dl 38;5;13 -+.xcf 38;5;13 -+.xwd 38;5;13 -+.yuv 38;5;13 -+.cgm 38;5;13 -+.emf 38;5;13 - - # https://wiki.xiph.org/MIME_Types_and_File_Extensions --.ogv 01;35 --.ogx 01;35 -+.ogv 38;5;13 -+.ogx 38;5;13 - - # audio formats --.aac 00;36 --.au 00;36 --.flac 00;36 --.m4a 00;36 --.mid 00;36 --.midi 00;36 --.mka 00;36 --.mp3 00;36 --.mpc 00;36 --.ogg 00;36 --.ra 00;36 --.wav 00;36 -+.aac 38;5;45 -+.au 38;5;45 -+.flac 38;5;45 -+.m4a 38;5;45 -+.mid 38;5;45 -+.midi 38;5;45 -+.mka 38;5;45 -+.mp3 38;5;45 -+.mpc 38;5;45 -+.ogg 38;5;45 -+.ra 38;5;45 -+.wav 38;5;45 - - # https://wiki.xiph.org/MIME_Types_and_File_Extensions --.oga 00;36 --.opus 00;36 --.spx 00;36 --.xspf 00;36 -+.oga 38;5;45 -+.opus 38;5;45 -+.spx 38;5;45 -+.xspf 38;5;45 diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor -index d2ea453..95d6879 100644 +index 4316832..6402854 100644 --- a/DIR_COLORS.lightbgcolor +++ b/DIR_COLORS.lightbgcolor @@ -1,3 +1,9 @@ @@ -477,207 +205,6 @@ index d2ea453..95d6879 100644 # List any file extensions like '.gz' or '.tar' that you would like ls # to colorize below. Put the extension, a space, and the color init string. -@@ -85,105 +94,105 @@ EXEC 01;32 - #.csh 01;32 - - # archives or compressed (bright red) --.tar 01;31 --.tgz 01;31 --.arc 01;31 --.arj 01;31 --.taz 01;31 --.lha 01;31 --.lz4 01;31 --.lzh 01;31 --.lzma 01;31 --.tlz 01;31 --.txz 01;31 --.tzo 01;31 --.t7z 01;31 --.zip 01;31 --.z 01;31 --.dz 01;31 --.gz 01;31 --.lrz 01;31 --.lz 01;31 --.lzo 01;31 --.xz 01;31 --.zst 01;31 --.tzst 01;31 --.bz2 01;31 --.bz 01;31 --.tbz 01;31 --.tbz2 01;31 --.tz 01;31 --.deb 01;31 --.rpm 01;31 --.jar 01;31 --.war 01;31 --.ear 01;31 --.sar 01;31 --.rar 01;31 --.alz 01;31 --.ace 01;31 --.zoo 01;31 --.cpio 01;31 --.7z 01;31 --.rz 01;31 --.cab 01;31 --.wim 01;31 --.swm 01;31 --.dwm 01;31 --.esd 01;31 -+.tar 00;31 -+.tgz 00;31 -+.arc 00;31 -+.arj 00;31 -+.taz 00;31 -+.lha 00;31 -+.lz4 00;31 -+.lzh 00;31 -+.lzma 00;31 -+.tlz 00;31 -+.txz 00;31 -+.tzo 00;31 -+.t7z 00;31 -+.zip 00;31 -+.z 00;31 -+.dz 00;31 -+.gz 00;31 -+.lrz 00;31 -+.lz 00;31 -+.lzo 00;31 -+.xz 00;31 -+.zst 00;31 -+.tzst 00;31 -+.bz2 00;31 -+.bz 00;31 -+.tbz 00;31 -+.tbz2 00;31 -+.tz 00;31 -+.deb 00;31 -+.rpm 00;31 -+.jar 00;31 -+.war 00;31 -+.ear 00;31 -+.sar 00;31 -+.rar 00;31 -+.alz 00;31 -+.ace 00;31 -+.zoo 00;31 -+.cpio 00;31 -+.7z 00;31 -+.rz 00;31 -+.cab 00;31 -+.wim 00;31 -+.swm 00;31 -+.dwm 00;31 -+.esd 00;31 - - # image formats --.jpg 01;35 --.jpeg 01;35 --.mjpg 01;35 --.mjpeg 01;35 --.gif 01;35 --.bmp 01;35 --.pbm 01;35 --.pgm 01;35 --.ppm 01;35 --.tga 01;35 --.xbm 01;35 --.xpm 01;35 --.tif 01;35 --.tiff 01;35 --.png 01;35 --.svg 01;35 --.svgz 01;35 --.mng 01;35 --.pcx 01;35 --.mov 01;35 --.mpg 01;35 --.mpeg 01;35 --.m2v 01;35 --.mkv 01;35 --.webm 01;35 --.ogm 01;35 --.mp4 01;35 --.m4v 01;35 --.mp4v 01;35 --.vob 01;35 --.qt 01;35 --.nuv 01;35 --.wmv 01;35 --.asf 01;35 --.rm 01;35 --.rmvb 01;35 --.flc 01;35 --.avi 01;35 --.fli 01;35 --.flv 01;35 --.gl 01;35 --.dl 01;35 --.xcf 01;35 --.xwd 01;35 --.yuv 01;35 --.cgm 01;35 --.emf 01;35 -+.jpg 00;35 -+.jpeg 00;35 -+.mjpg 00;35 -+.mjpeg 00;35 -+.gif 00;35 -+.bmp 00;35 -+.pbm 00;35 -+.pgm 00;35 -+.ppm 00;35 -+.tga 00;35 -+.xbm 00;35 -+.xpm 00;35 -+.tif 00;35 -+.tiff 00;35 -+.png 00;35 -+.svg 00;35 -+.svgz 00;35 -+.mng 00;35 -+.pcx 00;35 -+.mov 00;35 -+.mpg 00;35 -+.mpeg 00;35 -+.m2v 00;35 -+.mkv 00;35 -+.webm 00;35 -+.ogm 00;35 -+.mp4 00;35 -+.m4v 00;35 -+.mp4v 00;35 -+.vob 00;35 -+.qt 00;35 -+.nuv 00;35 -+.wmv 00;35 -+.asf 00;35 -+.rm 00;35 -+.rmvb 00;35 -+.flc 00;35 -+.avi 00;35 -+.fli 00;35 -+.flv 00;35 -+.gl 00;35 -+.dl 00;35 -+.xcf 00;35 -+.xwd 00;35 -+.yuv 00;35 -+.cgm 00;35 -+.emf 00;35 - - # https://wiki.xiph.org/MIME_Types_and_File_Extensions --.ogv 01;35 --.ogx 01;35 -+.ogv 00;35 -+.ogx 00;35 - - # audio formats - .aac 00;36 -- -2.5.5 +2.21.1 diff --git a/coreutils.spec b/coreutils.spec index 2dbf3f3..11a65e4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -20,7 +20,7 @@ Patch100: coreutils-8.26-test-lock.patch Patch105: coreutils-8.26-selinuxenable.patch # downstream changes to default DIR_COLORS -Patch102: coreutils-8.25-DIR_COLORS.patch +Patch102: coreutils-8.32-DIR_COLORS.patch #do display processor type for uname -p/-i based on uname(2) syscall Patch103: coreutils-8.2-uname-processortype.patch #df --direct @@ -122,8 +122,20 @@ including documentation and translations. %prep %autosetup -N -# will be modified by coreutils-8.25-DIR_COLORS.patch -tee DIR_COLORS{,.256color,.lightbgcolor} /dev/null +# will be further modified by coreutils-8.32-DIR_COLORS.patch +sed src/dircolors.hin \ + -e 's| 00;36$| 01;36|' \ + > DIR_COLORS +sed src/dircolors.hin \ + -e 's| 01;31$| 38;5;9|' \ + -e 's| 01;35$| 38;5;13|' \ + -e 's| 01;36$| 38;5;45|' \ + > DIR_COLORS.256color +sed src/dircolors.hin \ + -e 's| 01;31$| 00;31|' \ + -e 's| 01;35$| 00;35|' \ + > DIR_COLORS.lightbgcolor + # git add DIR_COLORS{,.256color,.lightbgcolor} # git commit -m "clone DIR_COLORS before patching" From b0dc3833bf59a01e701ff543d399149c6602bac8 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 28 Feb 2020 15:39:02 +0100 Subject: [PATCH 404/523] adapt i18n patch for the new release --- coreutils-i18n.patch | 179 +++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 91 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e3428d9..4b8c9e5 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -893,7 +893,7 @@ index 98b461c..9990f38 100644 } putchar (eolchar); } -@@ -1099,20 +1345,43 @@ main (int argc, char **argv) +@@ -1098,20 +1344,43 @@ main (int argc, char **argv) case 't': { @@ -975,8 +975,8 @@ index 26f221f..633f50e 100644 #include "system.h" #include "die.h" #include "error.h" -@@ -324,6 +342,18 @@ - #include "xstrtol.h" +@@ -325,6 +343,18 @@ + #include "xstrtol-error.h" #include "xdectoint.h" +/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ @@ -994,7 +994,7 @@ index 26f221f..633f50e 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -416,7 +446,20 @@ struct COLUMN +@@ -417,7 +447,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -1016,7 +1016,7 @@ index 26f221f..633f50e 100644 static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); +@@ -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, @@ -1024,7 +1024,7 @@ index 26f221f..633f50e 100644 int *number); static void print_files (int number_of_files, char **av); static void init_parameters (int number_of_files); -@@ -441,7 +485,6 @@ static void store_char (char c); +@@ -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); @@ -1032,7 +1032,7 @@ index 26f221f..633f50e 100644 static void cleanup (void); static void print_sep_string (void); static void separator_string (const char *optarg_S); -@@ -453,7 +496,7 @@ static COLUMN *column_vector; +@@ -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]. */ @@ -1041,7 +1041,7 @@ index 26f221f..633f50e 100644 /* Index of the position in buff where the next character will be stored. */ -@@ -557,7 +600,7 @@ static int chars_per_column; +@@ -558,7 +601,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -1050,7 +1050,7 @@ index 26f221f..633f50e 100644 /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... where the leftmost column is 1. */ -@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8; +@@ -568,7 +611,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -1062,7 +1062,7 @@ index 26f221f..633f50e 100644 /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -637,7 +683,13 @@ static int line_number; +@@ -638,7 +684,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -1077,7 +1077,7 @@ index 26f221f..633f50e 100644 /* (-n) line counting starts with 1st line of input file (not with 1st line of 1st page printed). */ -@@ -690,6 +742,7 @@ static bool use_col_separator = false; +@@ -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; @@ -1085,7 +1085,7 @@ index 26f221f..633f50e 100644 static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -851,6 +904,13 @@ separator_string (const char *optarg_S) +@@ -852,6 +905,13 @@ separator_string (const char *optarg_S) integer_overflow (); col_sep_length = len; col_sep_string = optarg_S; @@ -1099,7 +1099,7 @@ index 26f221f..633f50e 100644 } int -@@ -875,6 +935,21 @@ main (int argc, char **argv) +@@ -876,6 +936,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1121,7 +1121,7 @@ index 26f221f..633f50e 100644 n_files = 0; file_names = (argc > 1 ? xnmalloc (argc - 1, sizeof (char *)) -@@ -951,8 +1026,12 @@ main (int argc, char **argv) +@@ -952,8 +1027,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -1136,7 +1136,7 @@ index 26f221f..633f50e 100644 /* Could check tab width > 0. */ untabify_input = true; break; -@@ -965,8 +1044,12 @@ main (int argc, char **argv) +@@ -966,8 +1045,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -1151,7 +1151,7 @@ index 26f221f..633f50e 100644 /* Could check tab width > 0. */ tabify_output = true; break; -@@ -984,8 +1067,8 @@ main (int argc, char **argv) +@@ -985,8 +1068,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -1162,7 +1162,7 @@ index 26f221f..633f50e 100644 break; case 'N': skip_count = false; -@@ -1010,6 +1093,7 @@ main (int argc, char **argv) +@@ -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; @@ -1170,7 +1170,7 @@ index 26f221f..633f50e 100644 use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1165,10 +1249,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err) +@@ -1166,10 +1250,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err) a number. */ static void @@ -1218,7 +1218,7 @@ index 26f221f..633f50e 100644 if (*arg) { long int tmp_long; -@@ -1190,6 +1309,11 @@ static void +@@ -1191,6 +1310,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -1230,7 +1230,7 @@ index 26f221f..633f50e 100644 lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1227,7 +1351,7 @@ init_parameters (int number_of_files) +@@ -1228,7 +1352,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -1239,7 +1239,7 @@ index 26f221f..633f50e 100644 use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1257,11 +1381,11 @@ init_parameters (int number_of_files) +@@ -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. */ @@ -1253,7 +1253,7 @@ index 26f221f..633f50e 100644 /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1270,7 +1394,7 @@ init_parameters (int number_of_files) +@@ -1271,7 +1395,7 @@ init_parameters (int number_of_files) } int sep_chars, useful_chars; @@ -1262,7 +1262,7 @@ index 26f221f..633f50e 100644 sep_chars = INT_MAX; if (INT_SUBTRACT_WRAPV (chars_per_line - chars_used_by_number, sep_chars, &useful_chars)) -@@ -1293,7 +1417,7 @@ init_parameters (int number_of_files) +@@ -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); @@ -1271,7 +1271,7 @@ index 26f221f..633f50e 100644 } /* Open the necessary files, -@@ -1399,7 +1523,7 @@ init_funcs (void) +@@ -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. */ @@ -1280,7 +1280,7 @@ index 26f221f..633f50e 100644 /* This loop takes care of all but the rightmost column. */ -@@ -1433,7 +1557,7 @@ init_funcs (void) +@@ -1434,7 +1558,7 @@ init_funcs (void) } else { @@ -1289,7 +1289,7 @@ index 26f221f..633f50e 100644 h_next = h + chars_per_column; } } -@@ -1724,9 +1848,9 @@ static void +@@ -1725,9 +1849,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -1301,7 +1301,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2001,13 +2125,13 @@ store_char (char c) +@@ -2002,13 +2126,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -1317,7 +1317,7 @@ index 26f221f..633f50e 100644 char *s; int num_width; -@@ -2024,22 +2148,24 @@ add_line_number (COLUMN *p) +@@ -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. */ @@ -1346,7 +1346,7 @@ index 26f221f..633f50e 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2198,7 +2324,7 @@ print_white_space (void) +@@ -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) { @@ -1355,7 +1355,7 @@ index 26f221f..633f50e 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2218,6 +2344,7 @@ print_sep_string (void) +@@ -2219,6 +2345,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -1363,7 +1363,7 @@ index 26f221f..633f50e 100644 if (separators_not_printed <= 0) { -@@ -2229,6 +2356,7 @@ print_sep_string (void) +@@ -2230,6 +2357,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -1371,7 +1371,7 @@ index 26f221f..633f50e 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2242,12 +2370,15 @@ print_sep_string (void) +@@ -2243,12 +2371,15 @@ print_sep_string (void) } else { @@ -1388,7 +1388,7 @@ index 26f221f..633f50e 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2275,7 +2406,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2276,7 +2407,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -1397,7 +1397,7 @@ index 26f221f..633f50e 100644 { if (tabify_output) { -@@ -2299,6 +2430,74 @@ print_char (char c) +@@ -2300,6 +2431,74 @@ print_char (char c) putchar (c); } @@ -1472,7 +1472,7 @@ index 26f221f..633f50e 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2476,9 +2675,9 @@ read_line (COLUMN *p) +@@ -2477,9 +2676,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -1484,7 +1484,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2547,7 +2746,7 @@ print_stored (COLUMN *p) +@@ -2548,7 +2747,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -1493,7 +1493,7 @@ index 26f221f..633f50e 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2559,7 +2758,7 @@ print_stored (COLUMN *p) +@@ -2560,7 +2759,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -1502,7 +1502,7 @@ index 26f221f..633f50e 100644 pad_vertically = true; -@@ -2579,9 +2778,9 @@ print_stored (COLUMN *p) +@@ -2580,9 +2779,9 @@ print_stored (COLUMN *p) } } @@ -1514,7 +1514,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2594,8 +2793,8 @@ print_stored (COLUMN *p) +@@ -2595,8 +2794,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -1525,7 +1525,7 @@ index 26f221f..633f50e 100644 } return true; -@@ -2614,7 +2813,7 @@ print_stored (COLUMN *p) +@@ -2615,7 +2814,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -1534,7 +1534,7 @@ index 26f221f..633f50e 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2624,10 +2823,10 @@ char_to_clump (char c) +@@ -2625,10 +2824,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -1547,7 +1547,7 @@ index 26f221f..633f50e 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2708,6 +2907,164 @@ char_to_clump (char c) +@@ -2709,6 +2908,164 @@ char_to_clump (char c) return chars; } @@ -1731,7 +1731,7 @@ index 6d2eec5..f189a0d 100644 #include "system.h" #include "argmatch.h" #include "die.h" -@@ -161,14 +169,39 @@ static int decimal_point; +@@ -157,14 +165,39 @@ static int decimal_point; /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; @@ -1772,7 +1772,7 @@ index 6d2eec5..f189a0d 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -342,13 +375,11 @@ static bool reverse; +@@ -338,13 +371,11 @@ static bool reverse; they were read if all keys compare equal. */ static bool stable; @@ -1789,7 +1789,7 @@ index 6d2eec5..f189a0d 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -806,6 +837,46 @@ reap_all (void) +@@ -802,6 +833,46 @@ reap_all (void) reap (-1); } @@ -1836,7 +1836,7 @@ index 6d2eec5..f189a0d 100644 /* Clean up any remaining temporary files. */ static void -@@ -1274,7 +1345,7 @@ zaptemp (char const *name) +@@ -1270,7 +1341,7 @@ zaptemp (char const *name) free (node); } @@ -1845,7 +1845,7 @@ index 6d2eec5..f189a0d 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1289,7 +1360,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1285,7 +1356,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -1854,7 +1854,7 @@ index 6d2eec5..f189a0d 100644 { size_t i; -@@ -1301,7 +1372,7 @@ inittables (void) +@@ -1297,7 +1368,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -1863,7 +1863,7 @@ index 6d2eec5..f189a0d 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1383,6 +1454,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1379,6 +1450,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -1948,7 +1948,7 @@ index 6d2eec5..f189a0d 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1614,7 +1763,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1610,7 +1759,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -1957,7 +1957,7 @@ index 6d2eec5..f189a0d 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1623,10 +1772,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1619,10 +1768,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -1970,7 +1970,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1652,11 +1801,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1648,11 +1797,70 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2042,7 +2042,7 @@ index 6d2eec5..f189a0d 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1671,10 +1879,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1667,10 +1875,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2055,7 +2055,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1720,10 +1928,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1716,10 +1924,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2068,7 +2068,7 @@ index 6d2eec5..f189a0d 100644 if (newlim) lim = newlim; } -@@ -1754,6 +1962,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1750,6 +1958,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2199,7 +2199,7 @@ index 6d2eec5..f189a0d 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1840,8 +2172,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1836,8 +2168,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2224,7 +2224,7 @@ index 6d2eec5..f189a0d 100644 line->keybeg = line_start; } } -@@ -1991,7 +2337,7 @@ human_numcompare (char const *a, char const *b) +@@ -1987,7 +2333,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2233,7 +2233,7 @@ index 6d2eec5..f189a0d 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2001,6 +2347,25 @@ numcompare (char const *a, char const *b) +@@ -1997,6 +2343,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2259,7 +2259,7 @@ index 6d2eec5..f189a0d 100644 /* 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 -@@ -2051,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2047,7 +2412,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2268,7 +2268,7 @@ index 6d2eec5..f189a0d 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2327,15 +2692,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2323,15 +2688,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2286,7 +2286,7 @@ index 6d2eec5..f189a0d 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2469,7 +2833,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2465,7 +2829,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2295,7 +2295,7 @@ index 6d2eec5..f189a0d 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2527,11 +2891,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2523,11 +2887,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -2384,7 +2384,7 @@ index 6d2eec5..f189a0d 100644 { struct keyfield *key = keylist; -@@ -2616,7 +3056,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2612,7 +3052,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2393,7 +2393,7 @@ index 6d2eec5..f189a0d 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2732,6 +3172,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2728,6 +3168,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -2605,7 +2605,7 @@ index 6d2eec5..f189a0d 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2759,7 +3404,7 @@ compare (struct line const *a, struct line const *b) +@@ -2755,7 +3400,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -2614,7 +2614,7 @@ index 6d2eec5..f189a0d 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4149,6 +4794,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4145,6 +4790,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -2622,7 +2622,7 @@ index 6d2eec5..f189a0d 100644 break; case 'g': key->general_numeric = true; -@@ -4228,7 +4874,7 @@ main (int argc, char **argv) +@@ -4224,7 +4870,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2631,7 +2631,7 @@ index 6d2eec5..f189a0d 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4249,6 +4895,29 @@ main (int argc, char **argv) +@@ -4245,6 +4891,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -2661,7 +2661,7 @@ index 6d2eec5..f189a0d 100644 have_read_stdin = false; inittables (); -@@ -4523,13 +5192,34 @@ main (int argc, char **argv) +@@ -4519,13 +5188,34 @@ main (int argc, char **argv) case 't': { @@ -2700,7 +2700,7 @@ index 6d2eec5..f189a0d 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4540,9 +5230,11 @@ main (int argc, char **argv) +@@ -4536,9 +5226,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -2714,7 +2714,7 @@ index 6d2eec5..f189a0d 100644 } break; -@@ -4771,12 +5463,10 @@ main (int argc, char **argv) +@@ -4767,12 +5459,10 @@ main (int argc, char **argv) sort (files, nfiles, outfile, nthreads); } @@ -2749,9 +2749,9 @@ index 87a0c93..9f755d9 100644 #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -32,9 +43,21 @@ +@@ -30,9 +41,21 @@ + #include "posixver.h" #include "stdio--.h" - #include "xmemcoll.h" #include "xstrtol.h" -#include "memcasecmp.h" +#include "xmemcoll.h" @@ -2772,7 +2772,7 @@ index 87a0c93..9f755d9 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -144,6 +167,10 @@ enum +@@ -139,6 +162,10 @@ enum GROUP_OPTION = CHAR_MAX + 1 }; @@ -2783,7 +2783,7 @@ index 87a0c93..9f755d9 100644 static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -260,7 +287,7 @@ size_opt (char const *opt, char const *msgid) +@@ -253,7 +280,7 @@ size_opt (char const *opt, char const *msgid) return a pointer to the beginning of the line's field to be compared. */ static char * _GL_ATTRIBUTE_PURE @@ -2792,7 +2792,7 @@ index 87a0c93..9f755d9 100644 { size_t count; char const *lp = line->buffer; -@@ -280,6 +307,83 @@ find_field (struct linebuffer const *line) +@@ -273,6 +300,83 @@ find_field (struct linebuffer const *line) return line->buffer + i; } @@ -2876,7 +2876,7 @@ index 87a0c93..9f755d9 100644 /* 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. -@@ -288,6 +392,8 @@ find_field (struct linebuffer const *line) +@@ -281,17 +385,113 @@ find_field (struct linebuffer const *line) static bool different (char *old, char *new, size_t oldlen, size_t newlen) { @@ -2885,12 +2885,11 @@ index 87a0c93..9f755d9 100644 if (check_chars < oldlen) oldlen = check_chars; if (check_chars < newlen) -@@ -295,15 +401,104 @@ different (char *old, char *new, size_t oldlen, size_t newlen) + newlen = check_chars; if (ignore_case) - { -- /* FIXME: This should invoke strcoll somehow. */ -- return oldlen != newlen || memcasecmp (old, new, oldlen); +- return oldlen != newlen || memcasecmp (old, new, oldlen); ++ { + size_t i; + + copy_old = xmalloc (oldlen + 1); @@ -2905,9 +2904,7 @@ index 87a0c93..9f755d9 100644 + free (copy_old); + free (copy_new); + return rc; - } -- else if (hard_LC_COLLATE) -- return xmemcoll (old, oldlen, new, newlen) != 0; ++ } else - return oldlen != newlen || memcmp (old, new, oldlen); + { @@ -2995,7 +2992,7 @@ index 87a0c93..9f755d9 100644 /* Output the line in linebuffer LINE to standard output provided that the switches say it should be output. MATCH is true if the line matches the previous line. -@@ -367,19 +562,38 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -355,19 +555,38 @@ check_file (const char *infile, const char *outfile, char delimiter) char *prevfield IF_LINT ( = NULL); size_t prevlen IF_LINT ( = 0); bool first_group_printed = false; @@ -3034,7 +3031,7 @@ index 87a0c93..9f755d9 100644 new_group = (prevline->length == 0 || different (thisfield, prevfield, thislen, prevlen)); -@@ -397,6 +611,10 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -385,6 +604,10 @@ check_file (const char *infile, const char *outfile, char delimiter) SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3045,7 +3042,7 @@ index 87a0c93..9f755d9 100644 first_group_printed = true; } } -@@ -409,17 +627,26 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -397,17 +620,26 @@ check_file (const char *infile, const char *outfile, char delimiter) size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -3072,7 +3069,7 @@ index 87a0c93..9f755d9 100644 if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) { if (ferror (stdin)) -@@ -428,6 +655,14 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -416,6 +648,14 @@ check_file (const char *infile, const char *outfile, char delimiter) } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -3087,7 +3084,7 @@ index 87a0c93..9f755d9 100644 match = !different (thisfield, prevfield, thislen, prevlen); match_count += match; -@@ -460,6 +695,9 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -448,6 +688,9 @@ check_file (const char *infile, const char *outfile, char delimiter) SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -3097,7 +3094,7 @@ index 87a0c93..9f755d9 100644 if (!match) match_count = 0; } -@@ -506,6 +744,19 @@ main (int argc, char **argv) +@@ -493,6 +736,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -3156,7 +3153,7 @@ diff --git a/tests/local.mk b/tests/local.mk index 568944e..192f776 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -368,6 +368,8 @@ all_tests = \ +@@ -369,6 +369,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ From eadc061798022e267a806def9e7453ffc7e9193b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 5 Mar 2020 17:25:13 +0100 Subject: [PATCH 405/523] ls: fix compilation failure on aarch64 Bug: https://debbugs.gnu.org/39929 --- coreutils-8.32-ls-aarch64.patch | 31 +++++++++++++++++++++++++++++++ coreutils.spec | 4 ++++ 2 files changed, 35 insertions(+) create mode 100644 coreutils-8.32-ls-aarch64.patch diff --git a/coreutils-8.32-ls-aarch64.patch b/coreutils-8.32-ls-aarch64.patch new file mode 100644 index 0000000..b641e27 --- /dev/null +++ b/coreutils-8.32-ls-aarch64.patch @@ -0,0 +1,31 @@ +From 9dfe2b73e7ff3e4b1b1cf95a0f5a2753ad4c27b6 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 5 Mar 2020 17:23:43 +0100 +Subject: [PATCH] ls: fix compilation failure on aarch64 + +../src/ls.c: In function 'print_dir': +../src/ls.c:3026:24: error: 'SYS_getdents' undeclared (first use in this function); did you mean 'SYS_getdents64'? + 3026 | if (syscall (SYS_getdents, dirfd (dirp), NULL, 0) == -1 + | ^~~~~~~~~~~~ + | SYS_getdents64 +../src/ls.c:3026:24: note: each undeclared identifier is reported only once for each function it appears in +--- + src/ls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ls.c b/src/ls.c +index 24b9832..64ecf40 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -3018,7 +3018,7 @@ print_dir (char const *name, char const *realname, bool command_line_arg) + if (errno != EOVERFLOW) + break; + } +-#ifdef __linux__ ++#if defined(__linux__) && defined(__x86_64__) + else if (! found_any_entries) + { + /* If readdir finds no directory entries at all, not even "." or +-- +2.21.1 + diff --git a/coreutils.spec b/coreutils.spec index 11a65e4..09ae34a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -13,6 +13,10 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ + +# ls: fix compilation failure on aarch64 - https://debbugs.gnu.org/39929 +Patch1: coreutils-8.32-ls-aarch64.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch From b7eb17e7ee7ef17380f12bf1481596e1b7de16c5 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 5 Mar 2020 17:51:56 +0100 Subject: [PATCH 406/523] run tests/ls/removed-directory on x86_64 only for now --- coreutils-8.32-ls-aarch64.patch | 18 ++++++++++++++++-- coreutils.spec | 1 - 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/coreutils-8.32-ls-aarch64.patch b/coreutils-8.32-ls-aarch64.patch index b641e27..baff017 100644 --- a/coreutils-8.32-ls-aarch64.patch +++ b/coreutils-8.32-ls-aarch64.patch @@ -10,8 +10,9 @@ Subject: [PATCH] ls: fix compilation failure on aarch64 | SYS_getdents64 ../src/ls.c:3026:24: note: each undeclared identifier is reported only once for each function it appears in --- - src/ls.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) + src/ls.c | 2 +- + tests/ls/removed-directory.sh | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ls.c b/src/ls.c index 24b9832..64ecf40 100644 @@ -26,6 +27,19 @@ index 24b9832..64ecf40 100644 else if (! found_any_entries) { /* If readdir finds no directory entries at all, not even "." or +diff --git a/tests/ls/removed-directory.sh b/tests/ls/removed-directory.sh +index e8c835d..d3f4bae 100755 +--- a/tests/ls/removed-directory.sh ++++ b/tests/ls/removed-directory.sh +@@ -22,7 +22,7 @@ + print_ver_ ls + + case $host_triplet in +- *linux*) ;; ++ x86_64-redhat-linux-gnu) ;; + *) skip_ 'non linux kernel' ;; + esac + -- 2.21.1 diff --git a/coreutils.spec b/coreutils.spec index 09ae34a..365effc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -13,7 +13,6 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ - # ls: fix compilation failure on aarch64 - https://debbugs.gnu.org/39929 Patch1: coreutils-8.32-ls-aarch64.patch From 4a6bfcaa46dad4df900c40ac88e7d969dfd8b33e Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 5 Mar 2020 18:00:04 +0100 Subject: [PATCH 407/523] do not use IF_LINT for initialization of scalar variables It triggers false positives in compilers and static analyzers for no real benefit. --- coreutils-8.32-if-lint.patch | 364 +++++++++++++++++++++++++++++++++++ coreutils.spec | 3 + 2 files changed, 367 insertions(+) create mode 100644 coreutils-8.32-if-lint.patch diff --git a/coreutils-8.32-if-lint.patch b/coreutils-8.32-if-lint.patch new file mode 100644 index 0000000..24eaaaf --- /dev/null +++ b/coreutils-8.32-if-lint.patch @@ -0,0 +1,364 @@ +From e6df4c3b75bbaf464fc5475a4bdc392ab500670b Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 5 Mar 2020 17:37:12 +0100 +Subject: [PATCH] do not use IF_LINT for initialization of scalar variables + +It triggers false positives in compilers and static analyzers +for no real benefit. +--- + src/chcon.c | 2 +- + src/chmod.c | 4 ++-- + src/copy.c | 4 ++-- + src/cp.c | 2 +- + src/cut.c | 2 +- + src/df.c | 2 +- + src/expand.c | 2 +- + src/expr.c | 2 +- + src/ls.c | 2 +- + src/md5sum.c | 4 ++-- + src/od.c | 4 ++-- + src/paste.c | 4 ++-- + src/pr.c | 2 +- + src/shred.c | 4 ++-- + src/sort.c | 14 +++++++------- + src/split.c | 2 +- + src/truncate.c | 2 +- + src/unexpand.c | 4 ++-- + src/uniq.c | 4 ++-- + src/who.c | 2 +- + 20 files changed, 34 insertions(+), 34 deletions(-) + +diff --git a/src/chcon.c b/src/chcon.c +index 724ec9b..c1cf4c4 100644 +--- a/src/chcon.c ++++ b/src/chcon.c +@@ -142,7 +142,7 @@ static int + change_file_context (int fd, char const *file) + { + char *file_context = NULL; +- context_t context IF_LINT (= 0); ++ context_t context = 0; + char const * context_string; + int errors = 0; + +diff --git a/src/chmod.c b/src/chmod.c +index ec91534..a71a43c 100644 +--- a/src/chmod.c ++++ b/src/chmod.c +@@ -190,8 +190,8 @@ process_file (FTS *fts, FTSENT *ent) + char const *file_full_name = ent->fts_path; + char const *file = ent->fts_accpath; + const struct stat *file_stats = ent->fts_statp; +- mode_t old_mode IF_LINT ( = 0); +- mode_t new_mode IF_LINT ( = 0); ++ mode_t old_mode = 0; ++ mode_t new_mode = 0; + bool ok = true; + bool chmod_succeeded = false; + +diff --git a/src/copy.c b/src/copy.c +index 6e5efc7..bb80038 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -1889,8 +1889,8 @@ copy_internal (char const *src_name, char const *dst_name, + { + struct stat src_sb; + struct stat dst_sb; +- mode_t src_mode IF_LINT ( = 0); +- mode_t dst_mode IF_LINT ( = 0); ++ mode_t src_mode = 0; ++ mode_t dst_mode = 0; + mode_t dst_mode_bits; + mode_t omitted_permissions; + bool restore_dst_mode = false; +diff --git a/src/cp.c b/src/cp.c +index 0193df8..609adcf 100644 +--- a/src/cp.c ++++ b/src/cp.c +@@ -403,7 +403,7 @@ make_dir_parents_private (char const *const_dir, size_t src_offset, + slash++; + while ((slash = strchr (slash, '/'))) + { +- struct dir_attr *new IF_LINT ( = NULL); ++ struct dir_attr *new = NULL; + bool missing_dir; + + *slash = '\0'; +diff --git a/src/cut.c b/src/cut.c +index 35ab5fc..685ba8d 100644 +--- a/src/cut.c ++++ b/src/cut.c +@@ -835,7 +835,7 @@ main (int argc, char **argv) + int optc; + bool ok; + bool delim_specified = false; +- char *spec_list_string IF_LINT ( = NULL); ++ char *spec_list_string = NULL; + char mbdelim[MB_LEN_MAX + 1]; + + initialize_main (&argc, &argv); +diff --git a/src/df.c b/src/df.c +index 7e01839..8af1d14 100644 +--- a/src/df.c ++++ b/src/df.c +@@ -1588,7 +1588,7 @@ field names are: 'source', 'fstype', 'itotal', 'iused', 'iavail', 'ipcent',\n\ + int + main (int argc, char **argv) + { +- struct stat *stats IF_LINT ( = 0); ++ struct stat *stats = 0; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +diff --git a/src/expand.c b/src/expand.c +index bf61aff..cc9d4cd 100644 +--- a/src/expand.c ++++ b/src/expand.c +@@ -190,7 +190,7 @@ expand (void) + { + /* Column the next input tab stop is on. */ + uintmax_t next_tab_column; +- bool last_tab IF_LINT (=0); ++ bool last_tab = 0; + + next_tab_column = get_next_tab_column (column, &tab_index, + &last_tab); +diff --git a/src/expr.c b/src/expr.c +index e134872..a49d37c 100644 +--- a/src/expr.c ++++ b/src/expr.c +@@ -690,7 +690,7 @@ trace (fxn) + static VALUE * + docolon (VALUE *sv, VALUE *pv) + { +- VALUE *v IF_LINT ( = NULL); ++ VALUE *v = NULL; + const char *errmsg; + struct re_pattern_buffer re_buffer; + char fastmap[UCHAR_MAX + 1]; +diff --git a/src/ls.c b/src/ls.c +index 64ecf40..cc61400 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -4451,7 +4451,7 @@ quote_name_buf (char **inbuf, size_t bufsize, char *name, + int needs_general_quoting, size_t *width, bool *pad) + { + char *buf = *inbuf; +- size_t displayed_width IF_LINT ( = 0); ++ size_t displayed_width = 0; + size_t len = 0; + bool quoted; + +diff --git a/src/md5sum.c b/src/md5sum.c +index 447a005..91b9a9e 100644 +--- a/src/md5sum.c ++++ b/src/md5sum.c +@@ -687,9 +687,9 @@ digest_check (const char *checkfile_name) + line_chars_allocated = 0; + do + { +- char *filename IF_LINT ( = NULL); ++ char *filename = NULL; + int binary; +- unsigned char *hex_digest IF_LINT ( = NULL); ++ unsigned char *hex_digest = NULL; + ssize_t line_length; + + ++line_number; +diff --git a/src/od.c b/src/od.c +index 200bc16..7482bb5 100644 +--- a/src/od.c ++++ b/src/od.c +@@ -1570,7 +1570,7 @@ main (int argc, char **argv) + int n_files; + size_t i; + int l_c_m; +- size_t desired_width IF_LINT ( = 0); ++ size_t desired_width = 0; + bool modern = false; + bool width_specified = false; + bool ok = true; +@@ -1579,7 +1579,7 @@ main (int argc, char **argv) + + /* The old-style 'pseudo starting address' to be printed in parentheses + after any true address. */ +- uintmax_t pseudo_start IF_LINT ( = 0); ++ uintmax_t pseudo_start = 0; + + initialize_main (&argc, &argv); + set_program_name (argv[0]); +diff --git a/src/paste.c b/src/paste.c +index 9f401c9..6dd3a4e 100644 +--- a/src/paste.c ++++ b/src/paste.c +@@ -234,8 +234,8 @@ paste_parallel (size_t nfiles, char **fnamptr) + + for (size_t i = 0; i < nfiles && files_open; i++) + { +- int chr IF_LINT ( = 0); /* Input character. */ +- int err IF_LINT ( = 0); /* Input errno value. */ ++ int chr = 0; /* Input character. */ ++ int err = 0; /* Input errno value. */ + bool sometodo = false; /* Input chars to process. */ + + if (fileptr[i]) +diff --git a/src/pr.c b/src/pr.c +index 6374a7f..3ac3c03 100644 +--- a/src/pr.c ++++ b/src/pr.c +@@ -2606,7 +2606,7 @@ static bool + read_line (COLUMN *p) + { + int c; +- int chars IF_LINT ( = 0); ++ int chars = 0; + int last_input_position; + int j, k; + COLUMN *q; +diff --git a/src/shred.c b/src/shred.c +index fbbeddf..e9a6414 100644 +--- a/src/shred.c ++++ b/src/shred.c +@@ -399,7 +399,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, + { + off_t size = *sizep; + off_t offset; /* Current file position */ +- time_t thresh IF_LINT ( = 0); /* Time to maybe print next status update */ ++ time_t thresh = 0; /* Time to maybe print next status update */ + time_t now = 0; /* Current time */ + size_t lim; /* Amount of data to try writing */ + size_t soff; /* Offset into buffer for next write */ +@@ -424,7 +424,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, + + /* Printable previous offset into the file */ + char previous_offset_buf[LONGEST_HUMAN_READABLE + 1]; +- char const *previous_human_offset IF_LINT ( = 0); ++ char const *previous_human_offset = 0; + + /* As a performance tweak, avoid direct I/O for small sizes, + as it's just a performance rather then security consideration, +diff --git a/src/sort.c b/src/sort.c +index 8e1533e..cb494f4 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -1114,7 +1114,7 @@ pipe_fork (int pipefds[2], size_t tries) + struct tempnode *saved_temphead; + int saved_errno; + double wait_retry = 0.25; +- pid_t pid IF_LINT ( = -1); ++ pid_t pid = -1; + struct cs_status cs; + + if (pipe2 (pipefds, O_CLOEXEC) < 0) +@@ -2999,9 +2999,9 @@ keycompare_uni (const struct line *a, const struct line *b) + size_t tlena; + size_t tlenb; + +- char enda IF_LINT (= 0); +- char endb IF_LINT (= 0); +- void *allocated IF_LINT (= NULL); ++ char enda = 0; ++ char endb = 0; ++ void *allocated = NULL; + char stackbuf[4000]; + + if (ignore || translate) +@@ -3267,8 +3267,8 @@ keycompare_mb (const struct line *a, const struct line *b) + 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 enda = 0; ++ char endb = 0; + + char const *translate = key->translate; + bool const *ignore = key->ignore; +@@ -4551,7 +4551,7 @@ sort (char *const *files, size_t nfiles, char const *output_file, + size_t nthreads) + { + struct buffer buf; +- IF_LINT (buf.buf = NULL); ++ buf.buf = NULL; + size_t ntemps = 0; + bool output_file_created = false; + +diff --git a/src/split.c b/src/split.c +index 09e610b..aefa4a7 100644 +--- a/src/split.c ++++ b/src/split.c +@@ -1132,7 +1132,7 @@ lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t bufsize) + bool wrote = false; + bool file_limit; + size_t i_file; +- of_t *files IF_LINT (= NULL); ++ of_t *files = NULL; + uintmax_t line_no; + + if (k) +diff --git a/src/truncate.c b/src/truncate.c +index 91d9674..76e224f 100644 +--- a/src/truncate.c ++++ b/src/truncate.c +@@ -203,7 +203,7 @@ main (int argc, char **argv) + { + bool got_size = false; + bool errors = false; +- off_t size IF_LINT ( = 0); ++ off_t size = 0; + off_t rsize = -1; + rel_mode_t rel_mode = rm_abs; + int c, fd = -1, oflags; +diff --git a/src/unexpand.c b/src/unexpand.c +index 7d5dd64..b0e0ab3 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c +@@ -225,7 +225,7 @@ unexpand (void) + + if (blank) + { +- bool last_tab IF_LINT (=0); ++ bool last_tab = 0; + + next_tab_column = get_next_tab_column (column, &tab_index, + &last_tab); +@@ -320,7 +320,7 @@ int + main (int argc, char **argv) + { + bool have_tabval = false; +- uintmax_t tabval IF_LINT ( = 0); ++ uintmax_t tabval = 0; + int c; + + /* If true, cancel the effect of any -a (explicit or implicit in -t), +diff --git a/src/uniq.c b/src/uniq.c +index ba3c4ce..fa0fc5c 100644 +--- a/src/uniq.c ++++ b/src/uniq.c +@@ -552,8 +552,8 @@ check_file (const char *infile, const char *outfile, char delimiter) + */ + if (output_unique && output_first_repeated && countmode == count_none) + { +- char *prevfield IF_LINT ( = NULL); +- size_t prevlen IF_LINT ( = 0); ++ char *prevfield = NULL; ++ size_t prevlen = 0; + bool first_group_printed = false; + #if HAVE_MBRTOWC + mbstate_t prevstate; +diff --git a/src/who.c b/src/who.c +index abf3bc7..401ad0f 100644 +--- a/src/who.c ++++ b/src/who.c +@@ -568,7 +568,7 @@ print_heading (void) + static void + scan_entries (size_t n, const STRUCT_UTMP *utmp_buf) + { +- char *ttyname_b IF_LINT ( = NULL); ++ char *ttyname_b = NULL; + time_t boottime = TYPE_MINIMUM (time_t); + + if (include_heading) +-- +2.21.1 + diff --git a/coreutils.spec b/coreutils.spec index 365effc..eec800b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -60,6 +60,9 @@ Patch908: coreutils-getgrouplist.patch #(upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch +# do not use IF_LINT for initialization of scalar variables +Patch951: coreutils-8.32-if-lint.patch + Conflicts: filesystem < 3 # To avoid clobbering installs Conflicts: coreutils-single From 44b7afa1428d0c1f3a84aaaf4460765770fd877d Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 9 Mar 2020 14:19:35 +0100 Subject: [PATCH 408/523] ls: restore 8.31 behavior on removed directories --- coreutils-8.32-ls-aarch64.patch | 45 -------- coreutils-8.32-ls-removed-dir.patch | 153 ++++++++++++++++++++++++++++ coreutils.spec | 9 +- 3 files changed, 159 insertions(+), 48 deletions(-) delete mode 100644 coreutils-8.32-ls-aarch64.patch create mode 100644 coreutils-8.32-ls-removed-dir.patch diff --git a/coreutils-8.32-ls-aarch64.patch b/coreutils-8.32-ls-aarch64.patch deleted file mode 100644 index baff017..0000000 --- a/coreutils-8.32-ls-aarch64.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 9dfe2b73e7ff3e4b1b1cf95a0f5a2753ad4c27b6 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 5 Mar 2020 17:23:43 +0100 -Subject: [PATCH] ls: fix compilation failure on aarch64 - -../src/ls.c: In function 'print_dir': -../src/ls.c:3026:24: error: 'SYS_getdents' undeclared (first use in this function); did you mean 'SYS_getdents64'? - 3026 | if (syscall (SYS_getdents, dirfd (dirp), NULL, 0) == -1 - | ^~~~~~~~~~~~ - | SYS_getdents64 -../src/ls.c:3026:24: note: each undeclared identifier is reported only once for each function it appears in ---- - src/ls.c | 2 +- - tests/ls/removed-directory.sh | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/ls.c b/src/ls.c -index 24b9832..64ecf40 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -3018,7 +3018,7 @@ print_dir (char const *name, char const *realname, bool command_line_arg) - if (errno != EOVERFLOW) - break; - } --#ifdef __linux__ -+#if defined(__linux__) && defined(__x86_64__) - else if (! found_any_entries) - { - /* If readdir finds no directory entries at all, not even "." or -diff --git a/tests/ls/removed-directory.sh b/tests/ls/removed-directory.sh -index e8c835d..d3f4bae 100755 ---- a/tests/ls/removed-directory.sh -+++ b/tests/ls/removed-directory.sh -@@ -22,7 +22,7 @@ - print_ver_ ls - - case $host_triplet in -- *linux*) ;; -+ x86_64-redhat-linux-gnu) ;; - *) skip_ 'non linux kernel' ;; - esac - --- -2.21.1 - diff --git a/coreutils-8.32-ls-removed-dir.patch b/coreutils-8.32-ls-removed-dir.patch new file mode 100644 index 0000000..77dce89 --- /dev/null +++ b/coreutils-8.32-ls-removed-dir.patch @@ -0,0 +1,153 @@ +From 8c022656320592dbad146f5d3a3ae1875f419446 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 5 Mar 2020 17:25:29 -0800 +Subject: [PATCH 1/2] 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. + +Upstream-commit: 10fcb97bd728f09d4a027eddf8ad2900f0819b0a +Signed-off-by: Kamil Dudka +--- + src/ls.c | 22 ---------------------- + tests/ls/removed-directory.sh | 10 ++-------- + 2 files changed, 2 insertions(+), 30 deletions(-) + +diff --git a/src/ls.c b/src/ls.c +index 9d25f62..850ecc2 100644 +--- a/src/ls.c ++++ b/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 *realname, bool command_line_arg) + 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 *realname, bool command_line_arg) + 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 *realname, bool command_line_arg) + 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; + +diff --git a/tests/ls/removed-directory.sh b/tests/ls/removed-directory.sh +index e8c835d..fe8f929 100755 +--- a/tests/ls/removed-directory.sh ++++ b/tests/ls/removed-directory.sh +@@ -26,20 +26,14 @@ case $host_triplet in + *) 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_ + +-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 +-- +2.21.1 + + +From 847324a0debd9d12062c79e7a7a9d3d8ce76390d Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Sat, 7 Mar 2020 10:29:51 -0800 +Subject: [PATCH 2/2] 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). + +Upstream-commit: 672819c73f2e94e61386dc0584bddf9da860cc26 +Signed-off-by: Kamil Dudka +--- + tests/ls/removed-directory.sh | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +diff --git a/tests/ls/removed-directory.sh b/tests/ls/removed-directory.sh +index fe8f929..63b209d 100755 +--- a/tests/ls/removed-directory.sh ++++ b/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,15 +21,10 @@ + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ ls + +-case $host_triplet in +- *linux*) ;; +- *) skip_ 'non linux kernel' ;; +-esac +- + 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" + + ls >../out 2>../err || fail=1 + cd "$cwd" || framework_failure_ +-- +2.21.1 + diff --git a/coreutils.spec b/coreutils.spec index eec800b..1da7411 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -13,8 +13,8 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ -# ls: fix compilation failure on aarch64 - https://debbugs.gnu.org/39929 -Patch1: coreutils-8.32-ls-aarch64.patch +# ls: restore 8.31 behavior on removed directories +Patch1: coreutils-8.32-ls-removed-dir.patch # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -250,6 +250,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Mar 09 2020 Kamil Dudka - 8.32-2 +- ls: restore 8.31 behavior on removed directories + * Thu Mar 05 2020 Kamil Dudka - 8.32-1 - new upstream release 8.32 From acfa9e81ec1baeea27c2c12f04b5b56c260a3af7 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 10 Mar 2020 15:39:37 +0100 Subject: [PATCH 409/523] Resolves: #1811038 - make mknod work again in chroot ... without /proc being mounted --- coreutils.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/coreutils.spec b/coreutils.spec index 1da7411..24b0928 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -156,6 +156,10 @@ autoreconf -fiv %build export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" + +# make mknod work again in chroot without /proc being mounted (#1811038) +export ac_cv_func_lchmod="no" + %{expand:%%global optflags %{optflags} -D_GNU_SOURCE=1} for type in separate single; do mkdir $type && \ @@ -251,6 +255,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Mon Mar 09 2020 Kamil Dudka - 8.32-2 +- make mknod work again in chroot without /proc being mounted (#1811038) - ls: restore 8.31 behavior on removed directories * Thu Mar 05 2020 Kamil Dudka - 8.32-1 From 9ed5d5b0f9199314e7718129a96bd79ebb4ed2e4 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 11 Mar 2020 12:50:58 +0100 Subject: [PATCH 410/523] add missing BR for perl* needed for test-suite --- coreutils.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coreutils.spec b/coreutils.spec index 24b0928..4cabac1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -83,6 +83,9 @@ BuildRequires: openssl-devel BuildRequires: strace BuildRequires: texinfo +# test-only dependencies +BuildRequires: perl-interpreter +BuildRequires: perl(FileHandle) %if 23 < 0%{?fedora} || 7 < 0%{?rhel} # needed by i18n test-cases BuildRequires: glibc-langpack-en From d27f8523e24707e626a3fd73a8be3e34e6367ff5 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 11 Mar 2020 14:10:59 +0100 Subject: [PATCH 411/523] uniq: remove collation handling as required by newer POSIX Related upstream commit: https://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=8e81d44b5 Related Austin Group ticket: https://www.austingroupbugs.net/view.php?id=963 Patch provided by Bernhard Voelker. --- coreutils-8.32-if-lint.patch | 8 +- coreutils-i18n.patch | 250 ++--------------------------------- coreutils.spec | 7 +- 3 files changed, 24 insertions(+), 241 deletions(-) diff --git a/coreutils-8.32-if-lint.patch b/coreutils-8.32-if-lint.patch index 24eaaaf..cd5c4b0 100644 --- a/coreutils-8.32-if-lint.patch +++ b/coreutils-8.32-if-lint.patch @@ -140,7 +140,7 @@ diff --git a/src/ls.c b/src/ls.c index 64ecf40..cc61400 100644 --- a/src/ls.c +++ b/src/ls.c -@@ -4451,7 +4451,7 @@ quote_name_buf (char **inbuf, size_t bufsize, char *name, +@@ -4429,7 +4429,7 @@ quote_name_buf (char **inbuf, size_t bufsize, char *name, int needs_general_quoting, size_t *width, bool *pad) { char *buf = *inbuf; @@ -335,7 +335,7 @@ diff --git a/src/uniq.c b/src/uniq.c index ba3c4ce..fa0fc5c 100644 --- a/src/uniq.c +++ b/src/uniq.c -@@ -552,8 +552,8 @@ check_file (const char *infile, const char *outfile, char delimiter) +@@ -456,8 +456,8 @@ check_file (const char *infile, const char *outfile, char delimiter) */ if (output_unique && output_first_repeated && countmode == count_none) { @@ -344,8 +344,8 @@ index ba3c4ce..fa0fc5c 100644 + char *prevfield = NULL; + size_t prevlen = 0; bool first_group_printed = false; - #if HAVE_MBRTOWC - mbstate_t prevstate; + + while (!feof (stdin)) diff --git a/src/who.c b/src/who.c index abf3bc7..401ad0f 100644 --- a/src/who.c diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 4b8c9e5..ad2fa2e 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -6,23 +6,23 @@ Subject: [PATCH] coreutils-i18n.patch TODO: merge upstream --- lib/linebuffer.h | 8 + - src/fold.c | 308 ++++++++++++++++-- - src/join.c | 359 ++++++++++++++++++--- - src/pr.c | 443 ++++++++++++++++++++++--- - src/sort.c | 764 +++++++++++++++++++++++++++++++++++++++++--- - src/uniq.c | 265 ++++++++++++++- + src/fold.c | 308 +++++++++++++-- + src/join.c | 359 ++++++++++++++--- + src/pr.c | 443 +++++++++++++++++++-- + src/sort.c | 764 ++++++++++++++++++++++++++++++++++-- + src/uniq.c | 119 +++++- tests/i18n/sort.sh | 29 ++ tests/local.mk | 2 + - tests/misc/expand.pl | 42 +++ + 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/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 +++ - 17 files changed, 2430 insertions(+), 160 deletions(-) + 17 files changed, 2290 insertions(+), 154 deletions(-) create mode 100755 tests/i18n/sort.sh create mode 100755 tests/misc/sort-mb-tests.sh @@ -2749,12 +2749,8 @@ index 87a0c93..9f755d9 100644 #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -30,9 +41,21 @@ - #include "posixver.h" - #include "stdio--.h" - #include "xstrtol.h" --#include "memcasecmp.h" -+#include "xmemcoll.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 @@ -2876,225 +2872,7 @@ index 87a0c93..9f755d9 100644 /* 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. -@@ -281,17 +385,113 @@ find_field (struct linebuffer const *line) - static bool - different (char *old, char *new, size_t oldlen, size_t newlen) - { -+ char *copy_old, *copy_new; -+ - if (check_chars < oldlen) - oldlen = check_chars; - if (check_chars < newlen) - newlen = check_chars; - - if (ignore_case) -- return oldlen != newlen || memcasecmp (old, new, oldlen); -+ { -+ size_t i; -+ -+ copy_old = xmalloc (oldlen + 1); -+ copy_new = xmalloc (oldlen + 1); -+ -+ for (i = 0; i < oldlen; i++) -+ { -+ copy_old[i] = toupper (old[i]); -+ copy_new[i] = toupper (new[i]); -+ } -+ bool rc = xmemcoll (copy_old, oldlen, copy_new, newlen); -+ free (copy_old); -+ free (copy_new); -+ return rc; -+ } - else -- return oldlen != newlen || memcmp (old, new, oldlen); -+ { -+ copy_old = (char *)old; -+ copy_new = (char *)new; -+ } -+ -+ return xmemcoll (copy_old, oldlen, copy_new, newlen); -+ - } - -+#if HAVE_MBRTOWC -+static int -+different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) -+{ -+ size_t i, j, chars; -+ const char *str[2]; -+ char *copy[2]; -+ size_t len[2]; -+ mbstate_t state[2]; -+ size_t mblength; -+ wchar_t wc, uwc; -+ mbstate_t state_bak; -+ -+ str[0] = old; -+ str[1] = new; -+ len[0] = oldlen; -+ len[1] = newlen; -+ state[0] = oldstate; -+ state[1] = newstate; -+ -+ for (i = 0; i < 2; i++) -+ { -+ copy[i] = xmalloc (len[i] + 1); -+ memset (copy[i], '\0', len[i] + 1); -+ -+ for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) -+ { -+ state_bak = state[i]; -+ mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); -+ -+ switch (mblength) -+ { -+ case (size_t)-1: -+ case (size_t)-2: -+ state[i] = state_bak; -+ /* Fall through */ -+ case 0: -+ mblength = 1; -+ break; -+ -+ default: -+ if (ignore_case) -+ { -+ 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, str[i] + j, mblength); -+ } -+ else -+ memcpy (copy[i] + j, str[i] + j, mblength); -+ } -+ j += mblength; -+ } -+ copy[i][j] = '\0'; -+ len[i] = j; -+ } -+ int rc = xmemcoll (copy[0], len[0], copy[1], len[1]); -+ free (copy[0]); -+ free (copy[1]); -+ return rc; -+ -+} -+#endif -+ - /* Output the line in linebuffer LINE to standard output - provided that the switches say it should be output. - MATCH is true if the line matches the previous line. -@@ -355,19 +555,38 @@ check_file (const char *infile, const char *outfile, char delimiter) - char *prevfield IF_LINT ( = NULL); - size_t prevlen IF_LINT ( = 0); - bool first_group_printed = false; -+#if HAVE_MBRTOWC -+ mbstate_t prevstate; -+ -+ memset (&prevstate, '\0', sizeof (mbstate_t)); -+#endif - - while (!feof (stdin)) - { - char *thisfield; - size_t thislen; - bool new_group; -+#if HAVE_MBRTOWC -+ mbstate_t thisstate; -+#endif - - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - break; - - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ thisstate = thisline->state; - -+ new_group = (prevline->length == 0 -+ || different_multi (thisfield, prevfield, -+ thislen, prevlen, -+ thisstate, prevstate)); -+ } -+ else -+#endif - new_group = (prevline->length == 0 - || different (thisfield, prevfield, thislen, prevlen)); - -@@ -385,6 +604,10 @@ check_file (const char *infile, const char *outfile, char delimiter) - SWAP_LINES (prevline, thisline); - prevfield = thisfield; - prevlen = thislen; -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ prevstate = thisstate; -+#endif - first_group_printed = true; - } - } -@@ -397,17 +620,26 @@ check_file (const char *infile, const char *outfile, char delimiter) - size_t prevlen; - uintmax_t match_count = 0; - bool first_delimiter = true; -+#if HAVE_MBRTOWC -+ mbstate_t prevstate; -+#endif - - if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) - goto closefiles; - prevfield = find_field (prevline); - prevlen = prevline->length - 1 - (prevfield - prevline->buffer); -+#if HAVE_MBRTOWC -+ prevstate = prevline->state; -+#endif - - while (!feof (stdin)) - { - bool match; - char *thisfield; - size_t thislen; -+#if HAVE_MBRTOWC -+ mbstate_t thisstate = thisline->state; -+#endif - if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) - { - if (ferror (stdin)) -@@ -416,6 +648,14 @@ check_file (const char *infile, const char *outfile, char delimiter) - } - thisfield = find_field (thisline); - thislen = thisline->length - 1 - (thisfield - thisline->buffer); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ match = !different_multi (thisfield, prevfield, -+ thislen, prevlen, thisstate, prevstate); -+ } -+ else -+#endif - match = !different (thisfield, prevfield, thislen, prevlen); - match_count += match; - -@@ -448,6 +688,9 @@ check_file (const char *infile, const char *outfile, char delimiter) - SWAP_LINES (prevline, thisline); - prevfield = thisfield; - prevlen = thislen; -+#if HAVE_MBRTOWC -+ prevstate = thisstate; -+#endif - if (!match) - match_count = 0; - } -@@ -493,6 +736,19 @@ main (int argc, char **argv) +@@ -493,6 +597,19 @@ main (int argc, char **argv) atexit (close_stdout); diff --git a/coreutils.spec b/coreutils.spec index 4cabac1..e85c4c2 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -89,6 +89,8 @@ BuildRequires: perl(FileHandle) %if 23 < 0%{?fedora} || 7 < 0%{?rhel} # needed by i18n test-cases BuildRequires: glibc-langpack-en +BuildRequires: glibc-langpack-fr +BuildRequires: glibc-langpack-ko %endif Requires: %{name}-common = %{version}-%{release} @@ -257,6 +259,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Mar 11 2020 Kamil Dudka - 8.32-3 +- uniq: remove collation handling as required by newer POSIX + * Mon Mar 09 2020 Kamil Dudka - 8.32-2 - make mknod work again in chroot without /proc being mounted (#1811038) - ls: restore 8.31 behavior on removed directories From f4a53e34d0402dddda7706ba6268121625a6628e Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 17 Apr 2020 04:12:34 +0000 Subject: [PATCH 412/523] Fix missing inline function definition The coreutils-i18n-expand-unexpand.patch adds 3 definitions of the mbfile_multi_getc function. 2 of the definitions are marked with the inline keyword, which means that there must also be an externally visible definition. The 3rd definition is marked extern inline, which statisfies this requirement. However, the 3rd definition is defined in mbfile.c which is not compiled or linked in to any executable. This causes build failures if the compiler decides not to inline the function (which it is allowed to do) e.g. src/expand.c:153: undefined reference to `mbfile_multi_getc' clang does not inline this function, but gcc does which is why you will not see this failure when compiling with gcc. However, gcc could choose not to inline this, so even though the build succeeds, it is depending on an implementation detail of gcc rather than the C specification. In order to fix this problem, mbfile.c was added to the list of sources for any executable that uses mbfile_multi_getc. --- coreutils-i18n-expand-unexpand.patch | 16 ++++++++++++++++ coreutils.spec | 5 ++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/coreutils-i18n-expand-unexpand.patch b/coreutils-i18n-expand-unexpand.patch index b5f571f..32089cf 100644 --- a/coreutils-i18n-expand-unexpand.patch +++ b/coreutils-i18n-expand-unexpand.patch @@ -23,6 +23,7 @@ Co-authored-by: Pádraig Brady lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++ m4/mbfile.m4 | 14 +++ src/expand.c | 43 +++++---- + src/local.mk | 4 +- src/unexpand.c | 54 +++++++---- tests/expand/mb.sh | 98 ++++++++++++++++++++ tests/local.mk | 2 + @@ -458,6 +459,21 @@ index 9fa2e10..380e020 100644 } } +diff --git a/src/local.mk b/src/local.mk +index 72db9c704..ef3bfa469 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -415,8 +415,8 @@ src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) + + src_ginstall_CPPFLAGS = -DENABLE_MATCHPATHCON=1 $(AM_CPPFLAGS) + +-src_expand_SOURCES = src/expand.c src/expand-common.c +-src_unexpand_SOURCES = src/unexpand.c src/expand-common.c ++src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c ++src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c + + # Ensure we don't link against libcoreutils.a as that lib is + # not compiled with -fPIC which causes issues on 64 bit at least diff --git a/src/unexpand.c b/src/unexpand.c index 7801274..569a7ee 100644 --- a/src/unexpand.c diff --git a/coreutils.spec b/coreutils.spec index e85c4c2..934ed6f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -259,6 +259,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Apr 17 2020 Tom Stellard - 8.32-4 +- Fix missing inline function definition + * Wed Mar 11 2020 Kamil Dudka - 8.32-3 - uniq: remove collation handling as required by newer POSIX From 2f7b3e0a8cbe7e02eb30843387dda74a916a78a4 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 23 Apr 2020 14:38:43 +0200 Subject: [PATCH 413/523] Resolves: #1823247 - du: simplify leaf optimization for XFS --- coreutils-8.32-leaf-opt-xfs.patch | 164 ++++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-leaf-opt-xfs.patch diff --git a/coreutils-8.32-leaf-opt-xfs.patch b/coreutils-8.32-leaf-opt-xfs.patch new file mode 100644 index 0000000..c02db71 --- /dev/null +++ b/coreutils-8.32-leaf-opt-xfs.patch @@ -0,0 +1,164 @@ +From b9f9ed14bda93ecb407129b69e6476813c250046 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Wed, 15 Apr 2020 20:50:32 -0700 +Subject: [PATCH] fts: remove NOSTAT_LEAF_OPTIMIZATION +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It caused ‘find’ and ‘du’ to dump core, and it was useful +only for obsolescent Linux filesystems anyway. Problem reported in: +https://lists.gnu.org/r/bug-gnulib/2020-04/msg00068.html +Quite possibly there is still a serious underlying fts bug with +tight-loop-check and mutating file systems, but if so this patch +should cause the bug to be triggered less often. +* lib/fts.c (enum leaf_optimization): Remove +NOSTAT_LEAF_OPTIMIZATION, as it’s problematic. +(S_MAGIC_REISERFS, S_MAGIC_XFS): Remove; no longer needed. +(leaf_optimization): Remove special cases for ReiserFS and XFS. +(fts_read): Remove NOSTAT_LEAF_OPTIMIZATION code. +* lib/fts_.h (struct _ftsent.fts_n_dirs_remaining): +Remove. All uses removed. + +Upstream-commit: 47bf2cf3184027c1eb9c1dfeea5c5b8b2d69710d +Signed-off-by: Kamil Dudka +--- + lib/fts.c | 56 ++++++++------------------------------------------- + lib/fts_.h | 5 ----- + 2 files changed, 8 insertions(+), 53 deletions(-) + +diff --git a/lib/fts.c b/lib/fts.c +index 1093ce5..dfe3fef 100644 +--- a/lib/fts.c ++++ b/lib/fts.c +@@ -445,7 +445,6 @@ fts_open (char * const *argv, + if ((parent = fts_alloc(sp, "", 0)) == NULL) + goto mem2; + parent->fts_level = FTS_ROOTPARENTLEVEL; +- parent->fts_n_dirs_remaining = -1; + } + + /* The classic fts implementation would call fts_stat with +@@ -634,9 +633,8 @@ fts_close (FTS *sp) + } + + /* Minimum link count of a traditional Unix directory. When leaf +- optimization is OK and MIN_DIR_NLINK <= st_nlink, then st_nlink is +- an upper bound on the number of subdirectories (counting "." and +- ".."). */ ++ optimization is OK and a directory's st_nlink == MIN_DIR_NLINK, ++ then the directory has no subdirectories. */ + enum { MIN_DIR_NLINK = 2 }; + + /* Whether leaf optimization is OK for a directory. */ +@@ -645,12 +643,8 @@ enum leaf_optimization + /* st_nlink is not reliable for this directory's subdirectories. */ + NO_LEAF_OPTIMIZATION, + +- /* Leaf optimization is OK, but is not useful for avoiding stat calls. */ +- OK_LEAF_OPTIMIZATION, +- +- /* Leaf optimization is not only OK: it is useful for avoiding +- stat calls, because dirent.d_type does not work. */ +- NOSTAT_LEAF_OPTIMIZATION ++ /* st_nlink == 2 means the directory lacks subdirectories. */ ++ OK_LEAF_OPTIMIZATION + }; + + #if (defined __linux__ || defined __ANDROID__) \ +@@ -663,9 +657,7 @@ enum leaf_optimization + # define S_MAGIC_CIFS 0xFF534D42 + # define S_MAGIC_NFS 0x6969 + # define S_MAGIC_PROC 0x9FA0 +-# define S_MAGIC_REISERFS 0x52654973 + # define S_MAGIC_TMPFS 0x1021994 +-# define S_MAGIC_XFS 0x58465342 + + # ifdef HAVE___FSWORD_T + typedef __fsword_t fsword; +@@ -786,23 +778,15 @@ dirent_inode_sort_may_be_useful (FTSENT const *p, int dir_fd) + } + + /* Given an FTS entry P for a directory with descriptor DIR_FD, +- return true if it is both useful and valid to apply leaf optimization. +- The optimization is useful only for file systems that lack usable +- dirent.d_type info. The optimization is valid if an st_nlink value +- of at least MIN_DIR_NLINK is an upper bound on the number of +- subdirectories of D, counting "." and ".." as subdirectories. ++ return whether it is valid to apply leaf optimization. ++ The optimization is valid if a directory's st_nlink value equal ++ to MIN_DIR_NLINK means the directory has no subdirectories. + DIR_FD is negative if unavailable. */ + static enum leaf_optimization + leaf_optimization (FTSENT const *p, int dir_fd) + { + switch (filesystem_type (p, dir_fd)) + { +- /* List here the file system types that may lack usable dirent.d_type +- info, yet for which the optimization does apply. */ +- case S_MAGIC_REISERFS: +- case S_MAGIC_XFS: /* XFS lacked it until 2013-08-22 commit. */ +- return NOSTAT_LEAF_OPTIMIZATION; +- + case 0: + /* Leaf optimization is unsafe if the file system type is unknown. */ + FALLTHROUGH; +@@ -1027,26 +1011,7 @@ check_for_dir: + if (p->fts_info == FTS_NSOK) + { + if (p->fts_statp->st_size == FTS_STAT_REQUIRED) +- { +- FTSENT *parent = p->fts_parent; +- if (parent->fts_n_dirs_remaining == 0 +- && ISSET(FTS_NOSTAT) +- && ISSET(FTS_PHYSICAL) +- && (leaf_optimization (parent, sp->fts_cwd_fd) +- == NOSTAT_LEAF_OPTIMIZATION)) +- { +- /* nothing more needed */ +- } +- else +- { +- p->fts_info = fts_stat(sp, p, false); +- if (S_ISDIR(p->fts_statp->st_mode) +- && p->fts_level != FTS_ROOTLEVEL +- && 0 < parent->fts_n_dirs_remaining +- && parent->fts_n_dirs_remaining != (nlink_t) -1) +- parent->fts_n_dirs_remaining--; +- } +- } ++ p->fts_info = fts_stat(sp, p, false); + else + fts_assert (p->fts_statp->st_size == FTS_NO_STAT_REQUIRED); + } +@@ -1830,11 +1795,6 @@ err: memset(sbp, 0, sizeof(struct stat)); + } + + if (S_ISDIR(sbp->st_mode)) { +- p->fts_n_dirs_remaining +- = ((sbp->st_nlink < MIN_DIR_NLINK +- || p->fts_level <= FTS_ROOTLEVEL) +- ? -1 +- : sbp->st_nlink - (ISSET (FTS_SEEDOT) ? 0 : MIN_DIR_NLINK)); + if (ISDOT(p->fts_name)) { + /* Command-line "." and ".." are real directories. */ + return (p->fts_level == FTS_ROOTLEVEL ? FTS_D : FTS_DOT); +diff --git a/lib/fts_.h b/lib/fts_.h +index d40a116..2e76cc4 100644 +--- a/lib/fts_.h ++++ b/lib/fts_.h +@@ -227,11 +227,6 @@ typedef struct _ftsent { + + size_t fts_namelen; /* strlen(fts_name) */ + +- /* If not (nlink_t) -1, an upper bound on the number of +- remaining subdirectories of interest. If this becomes +- zero, some work can be avoided. */ +- nlink_t fts_n_dirs_remaining; +- + # define FTS_D 1 /* preorder directory */ + # define FTS_DC 2 /* directory that causes cycles */ + # define FTS_DEFAULT 3 /* none of the above */ +-- +2.21.1 + diff --git a/coreutils.spec b/coreutils.spec index 934ed6f..02146c0 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -16,6 +16,9 @@ Source106: coreutils-colorls.csh # ls: restore 8.31 behavior on removed directories Patch1: coreutils-8.32-ls-removed-dir.patch +# du: simplify leaf optimization for XFS (#1823247) +Patch2: coreutils-8.32-leaf-opt-xfs.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -259,6 +262,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Apr 23 2020 Kamil Dudka - 8.32-5 +- du: simplify leaf optimization for XFS (#1823247) + * Fri Apr 17 2020 Tom Stellard - 8.32-4 - Fix missing inline function definition From bce50ab5236b02ca216d6f2962ac7a88c94c7ecc Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 15 May 2020 19:17:59 +0200 Subject: [PATCH 414/523] increase verbosity of the build ... so that compiler flags used for each compilation unit are visible directly in the build log. --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 02146c0..90e0ab1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -185,7 +185,7 @@ for type in separate single; do --enable-no-install-program=kill,uptime \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : - make all %{?_smp_mflags} + make %{?_smp_mflags} all V=1 # make sure that parse-datetime.{c,y} ends up in debuginfo (#1555079) ln -v ../lib/parse-datetime.{c,y} . From 1f6e0df263489343c180599e45a7456a999a5214 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 15 May 2020 18:21:58 +0200 Subject: [PATCH 415/523] compile with -Dlint to enable optional initialization and cleanup code Upstream suggests to build with -Dlint for static analyzers: https://lists.gnu.org/archive/html/coreutils/2018-06/msg00110.html ... and even for production binary RPMs: https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00130.html There is currently no measurable performance drop or other known downside. --- coreutils-8.32-if-lint.patch | 364 ----------------------------------- coreutils.spec | 15 +- 2 files changed, 11 insertions(+), 368 deletions(-) delete mode 100644 coreutils-8.32-if-lint.patch diff --git a/coreutils-8.32-if-lint.patch b/coreutils-8.32-if-lint.patch deleted file mode 100644 index cd5c4b0..0000000 --- a/coreutils-8.32-if-lint.patch +++ /dev/null @@ -1,364 +0,0 @@ -From e6df4c3b75bbaf464fc5475a4bdc392ab500670b Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 5 Mar 2020 17:37:12 +0100 -Subject: [PATCH] do not use IF_LINT for initialization of scalar variables - -It triggers false positives in compilers and static analyzers -for no real benefit. ---- - src/chcon.c | 2 +- - src/chmod.c | 4 ++-- - src/copy.c | 4 ++-- - src/cp.c | 2 +- - src/cut.c | 2 +- - src/df.c | 2 +- - src/expand.c | 2 +- - src/expr.c | 2 +- - src/ls.c | 2 +- - src/md5sum.c | 4 ++-- - src/od.c | 4 ++-- - src/paste.c | 4 ++-- - src/pr.c | 2 +- - src/shred.c | 4 ++-- - src/sort.c | 14 +++++++------- - src/split.c | 2 +- - src/truncate.c | 2 +- - src/unexpand.c | 4 ++-- - src/uniq.c | 4 ++-- - src/who.c | 2 +- - 20 files changed, 34 insertions(+), 34 deletions(-) - -diff --git a/src/chcon.c b/src/chcon.c -index 724ec9b..c1cf4c4 100644 ---- a/src/chcon.c -+++ b/src/chcon.c -@@ -142,7 +142,7 @@ static int - change_file_context (int fd, char const *file) - { - char *file_context = NULL; -- context_t context IF_LINT (= 0); -+ context_t context = 0; - char const * context_string; - int errors = 0; - -diff --git a/src/chmod.c b/src/chmod.c -index ec91534..a71a43c 100644 ---- a/src/chmod.c -+++ b/src/chmod.c -@@ -190,8 +190,8 @@ process_file (FTS *fts, FTSENT *ent) - char const *file_full_name = ent->fts_path; - char const *file = ent->fts_accpath; - const struct stat *file_stats = ent->fts_statp; -- mode_t old_mode IF_LINT ( = 0); -- mode_t new_mode IF_LINT ( = 0); -+ mode_t old_mode = 0; -+ mode_t new_mode = 0; - bool ok = true; - bool chmod_succeeded = false; - -diff --git a/src/copy.c b/src/copy.c -index 6e5efc7..bb80038 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -1889,8 +1889,8 @@ copy_internal (char const *src_name, char const *dst_name, - { - struct stat src_sb; - struct stat dst_sb; -- mode_t src_mode IF_LINT ( = 0); -- mode_t dst_mode IF_LINT ( = 0); -+ mode_t src_mode = 0; -+ mode_t dst_mode = 0; - mode_t dst_mode_bits; - mode_t omitted_permissions; - bool restore_dst_mode = false; -diff --git a/src/cp.c b/src/cp.c -index 0193df8..609adcf 100644 ---- a/src/cp.c -+++ b/src/cp.c -@@ -403,7 +403,7 @@ make_dir_parents_private (char const *const_dir, size_t src_offset, - slash++; - while ((slash = strchr (slash, '/'))) - { -- struct dir_attr *new IF_LINT ( = NULL); -+ struct dir_attr *new = NULL; - bool missing_dir; - - *slash = '\0'; -diff --git a/src/cut.c b/src/cut.c -index 35ab5fc..685ba8d 100644 ---- a/src/cut.c -+++ b/src/cut.c -@@ -835,7 +835,7 @@ main (int argc, char **argv) - int optc; - bool ok; - bool delim_specified = false; -- char *spec_list_string IF_LINT ( = NULL); -+ char *spec_list_string = NULL; - char mbdelim[MB_LEN_MAX + 1]; - - initialize_main (&argc, &argv); -diff --git a/src/df.c b/src/df.c -index 7e01839..8af1d14 100644 ---- a/src/df.c -+++ b/src/df.c -@@ -1588,7 +1588,7 @@ field names are: 'source', 'fstype', 'itotal', 'iused', 'iavail', 'ipcent',\n\ - int - main (int argc, char **argv) - { -- struct stat *stats IF_LINT ( = 0); -+ struct stat *stats = 0; - - initialize_main (&argc, &argv); - set_program_name (argv[0]); -diff --git a/src/expand.c b/src/expand.c -index bf61aff..cc9d4cd 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -190,7 +190,7 @@ expand (void) - { - /* Column the next input tab stop is on. */ - uintmax_t next_tab_column; -- bool last_tab IF_LINT (=0); -+ bool last_tab = 0; - - next_tab_column = get_next_tab_column (column, &tab_index, - &last_tab); -diff --git a/src/expr.c b/src/expr.c -index e134872..a49d37c 100644 ---- a/src/expr.c -+++ b/src/expr.c -@@ -690,7 +690,7 @@ trace (fxn) - static VALUE * - docolon (VALUE *sv, VALUE *pv) - { -- VALUE *v IF_LINT ( = NULL); -+ VALUE *v = NULL; - const char *errmsg; - struct re_pattern_buffer re_buffer; - char fastmap[UCHAR_MAX + 1]; -diff --git a/src/ls.c b/src/ls.c -index 64ecf40..cc61400 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -4429,7 +4429,7 @@ quote_name_buf (char **inbuf, size_t bufsize, char *name, - int needs_general_quoting, size_t *width, bool *pad) - { - char *buf = *inbuf; -- size_t displayed_width IF_LINT ( = 0); -+ size_t displayed_width = 0; - size_t len = 0; - bool quoted; - -diff --git a/src/md5sum.c b/src/md5sum.c -index 447a005..91b9a9e 100644 ---- a/src/md5sum.c -+++ b/src/md5sum.c -@@ -687,9 +687,9 @@ digest_check (const char *checkfile_name) - line_chars_allocated = 0; - do - { -- char *filename IF_LINT ( = NULL); -+ char *filename = NULL; - int binary; -- unsigned char *hex_digest IF_LINT ( = NULL); -+ unsigned char *hex_digest = NULL; - ssize_t line_length; - - ++line_number; -diff --git a/src/od.c b/src/od.c -index 200bc16..7482bb5 100644 ---- a/src/od.c -+++ b/src/od.c -@@ -1570,7 +1570,7 @@ main (int argc, char **argv) - int n_files; - size_t i; - int l_c_m; -- size_t desired_width IF_LINT ( = 0); -+ size_t desired_width = 0; - bool modern = false; - bool width_specified = false; - bool ok = true; -@@ -1579,7 +1579,7 @@ main (int argc, char **argv) - - /* The old-style 'pseudo starting address' to be printed in parentheses - after any true address. */ -- uintmax_t pseudo_start IF_LINT ( = 0); -+ uintmax_t pseudo_start = 0; - - initialize_main (&argc, &argv); - set_program_name (argv[0]); -diff --git a/src/paste.c b/src/paste.c -index 9f401c9..6dd3a4e 100644 ---- a/src/paste.c -+++ b/src/paste.c -@@ -234,8 +234,8 @@ paste_parallel (size_t nfiles, char **fnamptr) - - for (size_t i = 0; i < nfiles && files_open; i++) - { -- int chr IF_LINT ( = 0); /* Input character. */ -- int err IF_LINT ( = 0); /* Input errno value. */ -+ int chr = 0; /* Input character. */ -+ int err = 0; /* Input errno value. */ - bool sometodo = false; /* Input chars to process. */ - - if (fileptr[i]) -diff --git a/src/pr.c b/src/pr.c -index 6374a7f..3ac3c03 100644 ---- a/src/pr.c -+++ b/src/pr.c -@@ -2606,7 +2606,7 @@ static bool - read_line (COLUMN *p) - { - int c; -- int chars IF_LINT ( = 0); -+ int chars = 0; - int last_input_position; - int j, k; - COLUMN *q; -diff --git a/src/shred.c b/src/shred.c -index fbbeddf..e9a6414 100644 ---- a/src/shred.c -+++ b/src/shred.c -@@ -399,7 +399,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, - { - off_t size = *sizep; - off_t offset; /* Current file position */ -- time_t thresh IF_LINT ( = 0); /* Time to maybe print next status update */ -+ time_t thresh = 0; /* Time to maybe print next status update */ - time_t now = 0; /* Current time */ - size_t lim; /* Amount of data to try writing */ - size_t soff; /* Offset into buffer for next write */ -@@ -424,7 +424,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, - - /* Printable previous offset into the file */ - char previous_offset_buf[LONGEST_HUMAN_READABLE + 1]; -- char const *previous_human_offset IF_LINT ( = 0); -+ char const *previous_human_offset = 0; - - /* As a performance tweak, avoid direct I/O for small sizes, - as it's just a performance rather then security consideration, -diff --git a/src/sort.c b/src/sort.c -index 8e1533e..cb494f4 100644 ---- a/src/sort.c -+++ b/src/sort.c -@@ -1114,7 +1114,7 @@ pipe_fork (int pipefds[2], size_t tries) - struct tempnode *saved_temphead; - int saved_errno; - double wait_retry = 0.25; -- pid_t pid IF_LINT ( = -1); -+ pid_t pid = -1; - struct cs_status cs; - - if (pipe2 (pipefds, O_CLOEXEC) < 0) -@@ -2999,9 +2999,9 @@ keycompare_uni (const struct line *a, const struct line *b) - size_t tlena; - size_t tlenb; - -- char enda IF_LINT (= 0); -- char endb IF_LINT (= 0); -- void *allocated IF_LINT (= NULL); -+ char enda = 0; -+ char endb = 0; -+ void *allocated = NULL; - char stackbuf[4000]; - - if (ignore || translate) -@@ -3267,8 +3267,8 @@ keycompare_mb (const struct line *a, const struct line *b) - 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 enda = 0; -+ char endb = 0; - - char const *translate = key->translate; - bool const *ignore = key->ignore; -@@ -4551,7 +4551,7 @@ sort (char *const *files, size_t nfiles, char const *output_file, - size_t nthreads) - { - struct buffer buf; -- IF_LINT (buf.buf = NULL); -+ buf.buf = NULL; - size_t ntemps = 0; - bool output_file_created = false; - -diff --git a/src/split.c b/src/split.c -index 09e610b..aefa4a7 100644 ---- a/src/split.c -+++ b/src/split.c -@@ -1132,7 +1132,7 @@ lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t bufsize) - bool wrote = false; - bool file_limit; - size_t i_file; -- of_t *files IF_LINT (= NULL); -+ of_t *files = NULL; - uintmax_t line_no; - - if (k) -diff --git a/src/truncate.c b/src/truncate.c -index 91d9674..76e224f 100644 ---- a/src/truncate.c -+++ b/src/truncate.c -@@ -203,7 +203,7 @@ main (int argc, char **argv) - { - bool got_size = false; - bool errors = false; -- off_t size IF_LINT ( = 0); -+ off_t size = 0; - off_t rsize = -1; - rel_mode_t rel_mode = rm_abs; - int c, fd = -1, oflags; -diff --git a/src/unexpand.c b/src/unexpand.c -index 7d5dd64..b0e0ab3 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -225,7 +225,7 @@ unexpand (void) - - if (blank) - { -- bool last_tab IF_LINT (=0); -+ bool last_tab = 0; - - next_tab_column = get_next_tab_column (column, &tab_index, - &last_tab); -@@ -320,7 +320,7 @@ int - main (int argc, char **argv) - { - bool have_tabval = false; -- uintmax_t tabval IF_LINT ( = 0); -+ uintmax_t tabval = 0; - int c; - - /* If true, cancel the effect of any -a (explicit or implicit in -t), -diff --git a/src/uniq.c b/src/uniq.c -index ba3c4ce..fa0fc5c 100644 ---- a/src/uniq.c -+++ b/src/uniq.c -@@ -456,8 +456,8 @@ check_file (const char *infile, const char *outfile, char delimiter) - */ - if (output_unique && output_first_repeated && countmode == count_none) - { -- char *prevfield IF_LINT ( = NULL); -- size_t prevlen IF_LINT ( = 0); -+ char *prevfield = NULL; -+ size_t prevlen = 0; - bool first_group_printed = false; - - while (!feof (stdin)) -diff --git a/src/who.c b/src/who.c -index abf3bc7..401ad0f 100644 ---- a/src/who.c -+++ b/src/who.c -@@ -568,7 +568,7 @@ print_heading (void) - static void - scan_entries (size_t n, const STRUCT_UTMP *utmp_buf) - { -- char *ttyname_b IF_LINT ( = NULL); -+ char *ttyname_b = NULL; - time_t boottime = TYPE_MINIMUM (time_t); - - if (include_heading) --- -2.21.1 - diff --git a/coreutils.spec b/coreutils.spec index 90e0ab1..e91d35b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -63,9 +63,6 @@ Patch908: coreutils-getgrouplist.patch #(upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch -# do not use IF_LINT for initialization of scalar variables -Patch951: coreutils-8.32-if-lint.patch - Conflicts: filesystem < 3 # To avoid clobbering installs Conflicts: coreutils-single @@ -165,6 +162,13 @@ autoreconf -fiv %build export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" +# Upstream suggests to build with -Dlint for static analyzers: +# https://lists.gnu.org/archive/html/coreutils/2018-06/msg00110.html +# ... and even for production binary RPMs: +# https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00130.html +# There is currently no measurable performance drop or other known downside. +CFLAGS="$CFLAGS -Dlint" + # make mknod work again in chroot without /proc being mounted (#1811038) export ac_cv_func_lchmod="no" @@ -262,6 +266,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri May 15 2020 Kamil Dudka - 8.32-6 +- compile with -Dlint to enable optional initialization and cleanup code + * Thu Apr 23 2020 Kamil Dudka - 8.32-5 - du: simplify leaf optimization for XFS (#1823247) From d72df4e29bb433eb719d8bd50437fb588b425efa Mon Sep 17 00:00:00 2001 From: James Cassell Date: Fri, 26 Jun 2020 02:45:57 -0400 Subject: [PATCH 416/523] ncurses is required by colorls.sh in coreutils-common - colorls.sh uses tput from ncurses https://bugzilla.redhat.com/show_bug.cgi?id=469277 - colorls.sh was moved to -common package but the ncurses requirement was not (in commit 5fb9bc4700bb2ae5e109805e3a0af8796c12904e ) --- coreutils.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index e91d35b..fc94073 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -94,7 +94,6 @@ BuildRequires: glibc-langpack-ko %endif Requires: %{name}-common = %{version}-%{release} -Requires: ncurses Provides: coreutils-full = %{version}-%{release} %include %{SOURCE51} @@ -125,6 +124,7 @@ packaged as a single multicall binary. # yum obsoleting rules explained at: # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 +Requires: ncurses Summary: coreutils common optional components %description common Optional though recommended components, @@ -266,6 +266,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Jun 26 2020 James Cassell - 8.32-7 +- move ncurses to -common package since it's needed for colorls.sh + * Fri May 15 2020 Kamil Dudka - 8.32-6 - compile with -Dlint to enable optional initialization and cleanup code From 5d1216301214534571714883927c09b5771fcf7d Mon Sep 17 00:00:00 2001 From: James Cassell Date: Fri, 26 Jun 2020 03:19:47 -0400 Subject: [PATCH 417/523] make ncurses optional --- coreutils-colorls.csh | 2 +- coreutils.spec | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index f631762..8312dc9 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -15,7 +15,7 @@ alias l. 'ls -d .*' set COLORS=/etc/DIR_COLORS if ($?TERM) then - if ( -e "/etc/DIR_COLORS.256color" ) then + if ( -e "/etc/DIR_COLORS.256color" && -e "/usr/bin/tput" ) then if ( "`/usr/bin/tput colors`" == "256" ) then set COLORS=/etc/DIR_COLORS.256color endif diff --git a/coreutils.spec b/coreutils.spec index fc94073..696dd99 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -124,7 +124,7 @@ packaged as a single multicall binary. # yum obsoleting rules explained at: # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 -Requires: ncurses +Recommends: ncurses Summary: coreutils common optional components %description common Optional though recommended components, @@ -268,6 +268,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Fri Jun 26 2020 James Cassell - 8.32-7 - move ncurses to -common package since it's needed for colorls.sh +- make ncurses optional * Fri May 15 2020 Kamil Dudka - 8.32-6 - compile with -Dlint to enable optional initialization and cleanup code From 3426965b81b533d097c186cff918a3364cf44087 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 13 Jul 2020 18:53:32 +0000 Subject: [PATCH 418/523] Use make macros https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro --- coreutils.spec | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 696dd99..4851b15 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -189,7 +189,7 @@ for type in separate single; do --enable-no-install-program=kill,uptime \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : - make %{?_smp_mflags} all V=1 + %make_build all V=1 # make sure that parse-datetime.{c,y} ends up in debuginfo (#1555079) ln -v ../lib/parse-datetime.{c,y} . @@ -266,6 +266,10 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jul 13 2020 Tom Stellard +- Use make macros +- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro + * Fri Jun 26 2020 James Cassell - 8.32-7 - move ncurses to -common package since it's needed for colorls.sh - make ncurses optional From fac4ffd39e9d9422627146736411054402650cf6 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 24 Jul 2020 19:15:28 +0200 Subject: [PATCH 419/523] fix the last change log entry --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 4851b15..b7aaec3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -266,7 +266,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog -* Mon Jul 13 2020 Tom Stellard +* Mon Jul 13 2020 Tom Stellard - 8.32-8 - Use make macros - https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro From 6d3ccf4f6f2f5c7033d914a2976dc1e16bc396ac Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 24 Jul 2020 18:51:12 +0200 Subject: [PATCH 420/523] Related: #1789115 - disable -flto on ppc64le to make test-float pass --- coreutils.spec | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index b7aaec3..deaa27a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -162,6 +162,11 @@ autoreconf -fiv %build export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" +# disable -flto on ppc64le to make test-float pass (#1789115) +%ifarch ppc64le +CFLAGS="$CFLAGS -fno-lto" +%endif + # Upstream suggests to build with -Dlint for static analyzers: # https://lists.gnu.org/archive/html/coreutils/2018-06/msg00110.html # ... and even for production binary RPMs: @@ -266,6 +271,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Jul 24 2020 Kamil Dudka - 8.32-9 +- disable -flto on ppc64le to make test-float pass (#1789115) + * Mon Jul 13 2020 Tom Stellard - 8.32-8 - Use make macros - https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro From 27d47106a2236427a9cd3ca492bd2b84a93c98b1 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 24 Jul 2020 18:54:53 +0200 Subject: [PATCH 421/523] replace weirdo constant in gnulib tests ... causing test failures on armv7hl --- coreutils.spec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/coreutils.spec b/coreutils.spec index deaa27a..7a9cfae 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -153,6 +153,10 @@ sed src/dircolors.hin \ # apply all patches %autopatch -p1 +# replace weirdo constant in gnulib tests causing test failures on armv7hl +sed -e 's/1729576/EPERM/' \ + -i gnulib-tests/test-{perror2,strerror_r}.c + (echo ">>> Fixing permissions on tests") 2>/dev/null find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+' (echo "<<< done") 2>/dev/null From fe6d386d13909130618d21e854fe79faddbfbbe6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Mon, 27 Jul 2020 14:35:30 +0000 Subject: [PATCH 422/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 7a9cfae..5ce5ab6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -275,6 +275,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jul 27 2020 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + * Fri Jul 24 2020 Kamil Dudka - 8.32-9 - disable -flto on ppc64le to make test-float pass (#1789115) From 5d08d14bbca895e98b21a4bae415fb2f8eb4400d Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 30 Jul 2020 17:36:08 +0200 Subject: [PATCH 423/523] Resolves: #1861108 - cp: default to --reflink=auto --- coreutils-8.32-cp-reflink-auto.patch | 119 +++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-cp-reflink-auto.patch diff --git a/coreutils-8.32-cp-reflink-auto.patch b/coreutils-8.32-cp-reflink-auto.patch new file mode 100644 index 0000000..a36c89c --- /dev/null +++ b/coreutils-8.32-cp-reflink-auto.patch @@ -0,0 +1,119 @@ +From 76126e2831580d0df20530f4d6f72189bd4f0b9a Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 18 Jun 2020 22:16:24 -0700 +Subject: [PATCH] cp: default to COW +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Likewise for ‘install’. Proposed in Bug#24400, and long past due. +* NEWS: +* doc/coreutils.texi (cp invocation): +* src/copy.h (enum Reflink_type): Document this. +* src/cp.c (cp_option_init): +* src/install.c (cp_option_init): Implement this. + +Upstream-commit: 25725f9d41735d176d73a757430739fb71c7d043 +Signed-off-by: Kamil Dudka +--- + doc/coreutils.texi | 19 ++++++++++++------- + src/copy.h | 4 ++-- + src/cp.c | 2 +- + src/install.c | 2 +- + 4 files changed, 16 insertions(+), 11 deletions(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 02e0c1c..2382a16 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -8854,12 +8854,14 @@ The @var{when} value can be one of the following: + + @table @samp + @item always +-The default behavior: if the copy-on-write operation is not supported ++If the copy-on-write operation is not supported + then report the failure for each file and exit with a failure status. ++Plain @option{--reflink} is equivalent to @option{--reflink=when}. + + @item auto + If the copy-on-write operation is not supported then fall back + to the standard copy behavior. ++This is the default if no @option{--reflink} option is given. + + @item never + Disable copy-on-write operation and use the standard copy behavior. +@@ -8868,12 +8870,6 @@ Disable copy-on-write operation and use the standard copy behavior. + This option is overridden by the @option{--link}, @option{--symbolic-link} + and @option{--attributes-only} options, thus allowing it to be used + to configure the default data copying behavior for @command{cp}. +-For example, with the following alias, @command{cp} will use the +-minimum amount of space supported by the file system. +- +-@example +-alias cp='cp --reflink=auto --sparse=always' +-@end example + + @item --remove-destination + @opindex --remove-destination +@@ -8918,6 +8914,15 @@ This is useful in creating a file for use with the @command{mkswap} command, + since such a file must not have any holes. + @end table + ++For example, with the following alias, @command{cp} will use the ++minimum amount of space supported by the file system. ++(Older versions of @command{cp} can also benefit from ++@option{--reflink=auto} here.) ++ ++@example ++alias cp='cp --sparse=always' ++@end example ++ + @optStripTrailingSlashes + + @item -s +diff --git a/src/copy.h b/src/copy.h +index 874d6f7..a0ad494 100644 +--- a/src/copy.h ++++ b/src/copy.h +@@ -46,10 +46,10 @@ enum Sparse_type + /* Control creation of COW files. */ + enum Reflink_type + { +- /* Default to a standard copy. */ ++ /* Do a standard copy. */ + REFLINK_NEVER, + +- /* Try a COW copy and fall back to a standard copy. */ ++ /* Try a COW copy and fall back to a standard copy; this is the default. */ + REFLINK_AUTO, + + /* Require a COW copy and fail if not available. */ +diff --git a/src/cp.c b/src/cp.c +index 0193df8..9e7ad14 100644 +--- a/src/cp.c ++++ b/src/cp.c +@@ -796,7 +796,7 @@ cp_option_init (struct cp_options *x) + x->move_mode = false; + x->install_mode = false; + x->one_file_system = false; +- x->reflink_mode = REFLINK_NEVER; ++ x->reflink_mode = REFLINK_AUTO; + + x->preserve_ownership = false; + x->preserve_links = false; +diff --git a/src/install.c b/src/install.c +index 4ab44a6..aef16ca 100644 +--- a/src/install.c ++++ b/src/install.c +@@ -264,7 +264,7 @@ cp_option_init (struct cp_options *x) + { + cp_options_default (x); + x->copy_as_regular = true; +- x->reflink_mode = REFLINK_NEVER; ++ x->reflink_mode = REFLINK_AUTO; + x->dereference = DEREF_ALWAYS; + x->unlink_dest_before_opening = true; + x->unlink_dest_after_failed_open = false; +-- +2.25.4 + diff --git a/coreutils.spec b/coreutils.spec index 5ce5ab6..b199bcb 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -19,6 +19,9 @@ Patch1: coreutils-8.32-ls-removed-dir.patch # du: simplify leaf optimization for XFS (#1823247) Patch2: coreutils-8.32-leaf-opt-xfs.patch +# cp: default to --reflink=auto (#1861108) +Patch3: coreutils-8.32-cp-reflink-auto.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -275,6 +278,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jul 30 2020 Kamil Dudka - 8.32-11 +- cp: default to --reflink=auto (#1861108) + * Mon Jul 27 2020 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild From 441f1d75196db5609a4ea1627c3a34192785372d Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 17 Aug 2020 12:46:51 +0200 Subject: [PATCH 424/523] Resolves: #1830318 - do not install /etc/DIR_COLORS.256color --- coreutils-8.32-DIR_COLORS.patch | 116 +------------------------------- coreutils.spec | 15 ++--- 2 files changed, 9 insertions(+), 122 deletions(-) diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index 61a3db3..9d422f4 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -4,10 +4,9 @@ Date: Fri, 17 Jun 2016 16:58:18 +0200 Subject: [PATCH] downstream changes to default DIR_COLORS --- - DIR_COLORS | 9 ++++- - DIR_COLORS.256color | 78 ++++++++++++++++++++--------------------- - DIR_COLORS.lightbgcolor | 21 +++++++---- - 3 files changed, 61 insertions(+), 47 deletions(-) + DIR_COLORS | 9 ++++++++- + DIR_COLORS.lightbgcolor | 21 +++++++++++++++------ + 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS index bd5df23..84f2417 100644 @@ -40,115 +39,6 @@ index bd5df23..84f2417 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -diff --git a/DIR_COLORS.256color b/DIR_COLORS.256color -index 85bd28d..7f6d4c8 100644 ---- a/DIR_COLORS.256color -+++ b/DIR_COLORS.256color -@@ -1,3 +1,9 @@ -+# Configuration file for the 256color ls utility -+ -+# This file goes in the /etc directory, and must be world readable. -+# You can copy this file to .dir_colors in your $HOME directory to override -+# the system defaults. -+ - # Configuration file for dircolors, a utility to help you set the - # LS_COLORS environment variable used by GNU ls with the --color option. - -@@ -8,32 +14,13 @@ - # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the - # slackware version of dircolors) are recognized but ignored. - -+# For compatibility, the pattern "^COLOR.*none" is recognized as a way to -+# disable colorization. See https://bugzilla.redhat.com/1349579 for details. -+ - # Below are TERM entries, which can be a glob patterns, to match - # against the TERM environment variable to determine if it is colorizable. --TERM Eterm --TERM ansi --TERM *color* --TERM con[0-9]*x[0-9]* --TERM cons25 --TERM console --TERM cygwin --TERM dtterm --TERM gnome --TERM hurd --TERM jfbterm --TERM konsole --TERM kterm --TERM linux --TERM linux-c --TERM mlterm --TERM putty --TERM rxvt* --TERM screen* --TERM st --TERM terminator --TERM tmux* --TERM vt100 --TERM xterm* -+TERM *256color* -+TERM rxvt-unicode256 - - # Below are the color init strings for the basic file types. - # One can use codes for 256 or more colors supported by modern terminals. -@@ -45,29 +32,40 @@ TERM xterm* - # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white - # Background color codes: - # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -+# Text color(256 colors mode) codes: -+# Valid syntax for text 256color is 38;5; , where color number -+# is number between 0 and 255. -+# You may find following command useful to search the best one for you: -+# for ((x=0; x<=255; x++));do echo -e "${x}:\033[38;5;${x}mcolor\033[000m";done -+# Background color(256 colors mode) codes: -+# Valid syntax for background 256color is 48;5; , where -+# color number is number between 0 and 255. -+# You may find following command useful to search the best one for you: -+# for ((x=0; x<=255; x++));do echo -e "${x}:\033[48;5;${x}mcolor\033[000m";done -+ - #NORMAL 00 # no color code at all - #FILE 00 # regular file: use no color at all - RESET 0 # reset to "normal" color --DIR 01;34 # directory --LINK 01;36 # symbolic link. (If you set this to 'target' instead of a -+DIR 38;5;33 # directory -+LINK 38;5;51 # symbolic link. (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) - MULTIHARDLINK 00 # regular file with more than one link --FIFO 40;33 # pipe --SOCK 01;35 # socket --DOOR 01;35 # door --BLK 40;33;01 # block device driver --CHR 40;33;01 # character device driver --ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... --MISSING 00 # ... and the files they point to --SETUID 37;41 # file that is setuid (u+s) --SETGID 30;43 # file that is setgid (g+s) --CAPABILITY 30;41 # file with capability --STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) --OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky --STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable -+FIFO 40;38;5;11 # pipe -+SOCK 38;5;13 # socket -+DOOR 38;5;5 # door -+BLK 48;5;232;38;5;11 # block device driver -+CHR 48;5;232;38;5;3 # character device driver -+ORPHAN 48;5;232;38;5;9 # symlink to nonexistent file, or non-stat'able file ... -+MISSING 01;37;41 # ... and the files they point to -+SETUID 48;5;196;38;5;15 # file that is setuid (u+s) -+SETGID 48;5;11;38;5;16 # file that is setgid (g+s) -+CAPABILITY 48;5;196;38;5;226 # file with capability -+STICKY_OTHER_WRITABLE 48;5;10;38;5;16 # dir that is sticky and other-writable (+t,o+w) -+OTHER_WRITABLE 48;5;10;38;5;21 # dir that is other-writable (o+w) and not sticky -+STICKY 48;5;21;38;5;15 # dir with the sticky bit set (+t) and not other-writable - - # This is for files with execute permission: --EXEC 01;32 -+EXEC 38;5;40 - - # List any file extensions like '.gz' or '.tar' that you would like ls - # to colorize below. Put the extension, a space, and the color init string. diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor index 4316832..6402854 100644 --- a/DIR_COLORS.lightbgcolor diff --git a/coreutils.spec b/coreutils.spec index b199bcb..d94b7ed 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -140,17 +140,12 @@ including documentation and translations. sed src/dircolors.hin \ -e 's| 00;36$| 01;36|' \ > DIR_COLORS -sed src/dircolors.hin \ - -e 's| 01;31$| 38;5;9|' \ - -e 's| 01;35$| 38;5;13|' \ - -e 's| 01;36$| 38;5;45|' \ - > DIR_COLORS.256color sed src/dircolors.hin \ -e 's| 01;31$| 00;31|' \ -e 's| 01;35$| 00;35|' \ > DIR_COLORS.lightbgcolor -# git add DIR_COLORS{,.256color,.lightbgcolor} +# git add DIR_COLORS{,.lightbgcolor} # git commit -m "clone DIR_COLORS before patching" # apply all patches @@ -242,8 +237,7 @@ for type in separate single; do done mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/profile.d -install -p -c -m644 DIR_COLORS{,.256color,.lightbgcolor} \ - $RPM_BUILD_ROOT%{_sysconfdir} +install -p -c -m644 DIR_COLORS{,.lightbgcolor} $RPM_BUILD_ROOT%{_sysconfdir} install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh @@ -278,6 +272,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Aug 17 2020 Kamil Dudka - 8.32-12 +- do not install /etc/DIR_COLORS.256color (#1830318) + * Thu Jul 30 2020 Kamil Dudka - 8.32-11 - cp: default to --reflink=auto (#1861108) From f4b85e63ba4ad4457596bf9181b39e7831c9e701 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 14 Oct 2020 18:10:58 +0200 Subject: [PATCH 425/523] make the %build section idempotent ... so that we can run `fedpkg compile --short` repeatedly --- coreutils.spec | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index d94b7ed..ae16282 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -179,10 +179,13 @@ CFLAGS="$CFLAGS -Dlint" # make mknod work again in chroot without /proc being mounted (#1811038) export ac_cv_func_lchmod="no" +# needed for out-of-tree build +%global _configure ../configure + %{expand:%%global optflags %{optflags} -D_GNU_SOURCE=1} for type in separate single; do - mkdir $type && \ - (cd $type && ln -s ../configure || exit 1 + mkdir -p $type && \ + (cd $type || exit $? if test $type = 'single'; then config_single='--enable-single-binary' config_single="$config_single --without-openssl" # smaller/slower sha*sum @@ -199,7 +202,7 @@ for type in separate single; do %make_build all V=1 # make sure that parse-datetime.{c,y} ends up in debuginfo (#1555079) - ln -v ../lib/parse-datetime.{c,y} . + ln -fv ../lib/parse-datetime.{c,y} . ) done @@ -272,6 +275,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Oct 14 2020 Kamil Dudka - 8.32-13 +- make the %%build section idempotent + * Mon Aug 17 2020 Kamil Dudka - 8.32-12 - do not install /etc/DIR_COLORS.256color (#1830318) From 3a627682871785e8bca865a3e42ca570c9094393 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 3 Nov 2020 20:43:07 +0100 Subject: [PATCH 426/523] use upstream patch to eliminate unportable gnulib tests --- coreutils-8.32-gnulib-perror-test.patch | 48 +++++++++++++++++++++++++ coreutils.spec | 7 ++-- 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 coreutils-8.32-gnulib-perror-test.patch diff --git a/coreutils-8.32-gnulib-perror-test.patch b/coreutils-8.32-gnulib-perror-test.patch new file mode 100644 index 0000000..e545290 --- /dev/null +++ b/coreutils-8.32-gnulib-perror-test.patch @@ -0,0 +1,48 @@ +From f61085aaa37f169365c56e44f5129d0491913b6a 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. + +Upstream-commit: 175e0bc72808d564074c4adcc72aeadb74adfcc6 +Signed-off-by: Kamil Dudka +--- + gnulib-tests/test-perror2.c | 3 --- + gnulib-tests/test-strerror_r.c | 3 --- + 2 files changed, 6 deletions(-) + +diff --git a/gnulib-tests/test-perror2.c b/gnulib-tests/test-perror2.c +index 1d14eda..c6214dd 100644 +--- a/gnulib-tests/test-perror2.c ++++ b/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); +diff --git a/gnulib-tests/test-strerror_r.c b/gnulib-tests/test-strerror_r.c +index b11d6fd..c1dbcf8 100644 +--- a/gnulib-tests/test-strerror_r.c ++++ b/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); +-- +2.25.4 + diff --git a/coreutils.spec b/coreutils.spec index ae16282..5460b68 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -22,6 +22,9 @@ Patch2: coreutils-8.32-leaf-opt-xfs.patch # cp: default to --reflink=auto (#1861108) Patch3: coreutils-8.32-cp-reflink-auto.patch +# eliminate unportable gnulib tests +Patch4: coreutils-8.32-gnulib-perror-test.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -151,10 +154,6 @@ sed src/dircolors.hin \ # apply all patches %autopatch -p1 -# replace weirdo constant in gnulib tests causing test failures on armv7hl -sed -e 's/1729576/EPERM/' \ - -i gnulib-tests/test-{perror2,strerror_r}.c - (echo ">>> Fixing permissions on tests") 2>/dev/null find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+' (echo "<<< done") 2>/dev/null From 4af0c9fc89ade566f4bd78d778940112a002b8f5 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 3 Nov 2020 16:47:34 +0100 Subject: [PATCH 427/523] df,stat,tail: recognize more file system types --- coreutils-8.32-new-fs-types.patch | 104 ++++++++++++++++++++++++++++++ coreutils.spec | 11 +++- 2 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-new-fs-types.patch diff --git a/coreutils-8.32-new-fs-types.patch b/coreutils-8.32-new-fs-types.patch new file mode 100644 index 0000000..a8eb35c --- /dev/null +++ b/coreutils-8.32-new-fs-types.patch @@ -0,0 +1,104 @@ +From 09400b7f7f48d8eedc0df55de8073a43bc0aac96 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Tue, 27 Oct 2020 20:15:43 +0000 +Subject: [PATCH 1/2] stat,tail: sync file system constants from the linux + kernel + +* src/stat.c: Add magic constants for "devmem", and +"zonefs" file systems. +* NEWS: Mention the improvement. + +Upstream-commit: ff80b6b0a0507e24f39cc1aad09d147f5187430b +Signed-off-by: Kamil Dudka +--- + src/stat.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/stat.c b/src/stat.c +index 5012622..8cd69da 100644 +--- a/src/stat.c ++++ b/src/stat.c +@@ -347,6 +347,8 @@ human_fstype (STRUCT_STATVFS const *statfsbuf) + return "debugfs"; + case S_MAGIC_DEVFS: /* 0x1373 local */ + return "devfs"; ++ case S_MAGIC_DEVMEM: /* 0x454D444D local */ ++ return "devmem"; + case S_MAGIC_DEVPTS: /* 0x1CD1 local */ + return "devpts"; + case S_MAGIC_DMA_BUF: /* 0x444D4142 local */ +@@ -549,6 +551,8 @@ human_fstype (STRUCT_STATVFS const *statfsbuf) + return "z3fold"; + case S_MAGIC_ZFS: /* 0x2FC12FC1 local */ + return "zfs"; ++ case S_MAGIC_ZONEFS: /* 0x5A4F4653 local */ ++ return "zonefs"; + case S_MAGIC_ZSMALLOC: /* 0x58295829 local */ + return "zsmallocfs"; + +-- +2.25.4 + + +From d5948fd41013dfe4d2d10083111821667977c6d1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Tue, 27 Oct 2020 21:04:14 +0000 +Subject: [PATCH 2/2] mountlist: recognize more file system types as remote + +Sync "remote" file systems from stat.c in coreutils. +Note we only consider file systems that do not use host:resource +mount source. I.e. those that don't generally use a colon when +mounting, as that case is already considered. Searching for +" /etc/fstab" was informative for identifying these. +The full list of "remote" file systems in coreutils is currently: + acfs afs ceph cifs coda fhgfs fuseblk fusectl + gfs gfs2 gpfs ibrix k-afs lustre novell nfs nfsd + ocfs2 panfs prl_fs smb smb2 snfs vboxsf vmhgfs vxfs +Note also we do not include virtual machine file systems, +as even though they're remote to the current kernel, +they are generally not distributed to separate hosts. + +* lib/mountlist.c (ME_REMOTE): Sync previously unconsidered +"remote" file systems from stat.c in coreutils. + +Upstream-commit: dd1fc46be12d671c1a9d9dc5a6fa8c766e99aa2f +Signed-off-by: Kamil Dudka +--- + lib/mountlist.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/lib/mountlist.c b/lib/mountlist.c +index 7abe024..e0227b7 100644 +--- a/lib/mountlist.c ++++ b/lib/mountlist.c +@@ -221,8 +221,9 @@ me_remote (char const *fs_name, char const *fs_type _GL_UNUSED) + #ifndef ME_REMOTE + /* A file system is "remote" if its Fs_name contains a ':' + or if (it is of type (smbfs or cifs) and its Fs_name starts with '//') +- or if it is of type (afs or auristorfs) +- or Fs_name is equal to "-hosts" (used by autofs to mount remote fs). */ ++ or if it is of any other of the listed types ++ or Fs_name is equal to "-hosts" (used by autofs to mount remote fs). ++ "VM" file systems like prl_fs or vboxsf are not considered remote here. */ + # define ME_REMOTE(Fs_name, Fs_type) \ + (strchr (Fs_name, ':') != NULL \ + || ((Fs_name)[0] == '/' \ +@@ -230,8 +231,15 @@ me_remote (char const *fs_name, char const *fs_type _GL_UNUSED) + && (strcmp (Fs_type, "smbfs") == 0 \ + || strcmp (Fs_type, "smb3") == 0 \ + || strcmp (Fs_type, "cifs") == 0)) \ ++ || strcmp (Fs_type, "acfs") == 0 \ + || strcmp (Fs_type, "afs") == 0 \ ++ || strcmp (Fs_type, "coda") == 0 \ + || strcmp (Fs_type, "auristorfs") == 0 \ ++ || strcmp (Fs_type, "fhgfs") == 0 \ ++ || strcmp (Fs_type, "gpfs") == 0 \ ++ || strcmp (Fs_type, "ibrix") == 0 \ ++ || strcmp (Fs_type, "ocfs2") == 0 \ ++ || strcmp (Fs_type, "vxfs") == 0 \ + || strcmp ("-hosts", Fs_name) == 0) + #endif + +-- +2.25.4 + diff --git a/coreutils.spec b/coreutils.spec index 5460b68..97e103e 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 13%{?dist} +Release: 14%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -25,6 +25,9 @@ Patch3: coreutils-8.32-cp-reflink-auto.patch # eliminate unportable gnulib tests Patch4: coreutils-8.32-gnulib-perror-test.patch +# df,stat,tail: recognize more file system types +Patch5: coreutils-8.32-new-fs-types.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -139,6 +142,9 @@ including documentation and translations. %prep %autosetup -N +# will be regenerated in the build directories +rm -f src/fs.h + # will be further modified by coreutils-8.32-DIR_COLORS.patch sed src/dircolors.hin \ -e 's| 00;36$| 01;36|' \ @@ -274,6 +280,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Nov 03 2020 Kamil Dudka - 8.32-14 +- df,stat,tail: recognize more file system types + * Wed Oct 14 2020 Kamil Dudka - 8.32-13 - make the %%build section idempotent From 1a18f20c401423c837a1392f27efede80e97e969 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 8 Dec 2020 14:36:26 +0100 Subject: [PATCH 428/523] Resolves: #1905481 - rm: do not skip files upon failure ... to remove an empty dir --- coreutils-8.32-rm-stray-skip.patch | 109 +++++++++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-rm-stray-skip.patch diff --git a/coreutils-8.32-rm-stray-skip.patch b/coreutils-8.32-rm-stray-skip.patch new file mode 100644 index 0000000..66a1efc --- /dev/null +++ b/coreutils-8.32-rm-stray-skip.patch @@ -0,0 +1,109 @@ +From 11b37b65d08c2a8b6d967fd866ebbdbe7e864949 Mon Sep 17 00:00:00 2001 +From: Nishant Nayan +Date: Thu, 26 Nov 2020 14:35:17 +0000 +Subject: [PATCH] rm: do not skip files upon failure to remove an empty dir + +When removing a directory fails for some reason, and that directory +is empty, the rm_fts code gets the return value of the excise call +confused with the return value of its earlier call to prompt, +causing fts_skip_tree to be called again and the next file +that rm would otherwise have deleted to survive. + +* src/remove.c (rm_fts): Ensure we only skip a single fts entry, +when processing empty dirs. I.e. only skip the entry +having successfully removed it. +* tests/rm/empty-immutable-skip.sh: New root-only test. +* tests/local.mk: Add it. +* NEWS: Mention the bug fix. +Fixes https://bugs.gnu.org/44883 + +Upstream-commit: 6bf108358a6104ec1c694c9530b3cd56b95f4b57 +Signed-off-by: Kamil Dudka +--- + src/remove.c | 3 ++- + tests/local.mk | 1 + + tests/rm/empty-immutable-skip.sh | 46 ++++++++++++++++++++++++++++++++ + 3 files changed, 49 insertions(+), 1 deletion(-) + create mode 100755 tests/rm/empty-immutable-skip.sh + +diff --git a/src/remove.c b/src/remove.c +index 2d40c55..adf9489 100644 +--- a/src/remove.c ++++ b/src/remove.c +@@ -506,7 +506,8 @@ rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x) + /* When we know (from prompt when in interactive mode) + that this is an empty directory, don't prompt twice. */ + s = excise (fts, ent, x, true); +- fts_skip_tree (fts, ent); ++ if (s == RM_OK) ++ fts_skip_tree (fts, ent); + } + + if (s != RM_OK) +diff --git a/tests/local.mk b/tests/local.mk +index 5f7f775..2aeff2b 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -136,6 +136,7 @@ all_root_tests = \ + tests/rm/no-give-up.sh \ + tests/rm/one-file-system.sh \ + tests/rm/read-only.sh \ ++ tests/rm/empty-immutable-skip.sh \ + tests/tail-2/append-only.sh \ + tests/tail-2/end-of-device.sh \ + tests/touch/now-owned-by-other.sh +diff --git a/tests/rm/empty-immutable-skip.sh b/tests/rm/empty-immutable-skip.sh +new file mode 100755 +index 0000000..c91d8d4 +--- /dev/null ++++ b/tests/rm/empty-immutable-skip.sh +@@ -0,0 +1,46 @@ ++#!/bin/sh ++# Ensure that rm does not skip extra files after hitting an empty immutable dir. ++# Requires root access to do chattr +i, as well as an ext[23] or xfs file system ++ ++# Copyright (C) 2020 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_ rm ++require_root_ ++ ++# These simple one-file operations are expected to work even in the ++# presence of this bug, and we need them to set up the rest of the test. ++chattr_i_works=1 ++touch f ++chattr +i f 2>/dev/null || chattr_i_works=0 ++rm f 2>/dev/null ++test -f f || chattr_i_works=0 ++chattr -i f 2>/dev/null || chattr_i_works=0 ++rm f 2>/dev/null || chattr_i_works=0 ++test -f f && chattr_i_works=0 ++ ++if test $chattr_i_works = 0; then ++ skip_ "chattr +i doesn't work on this file system" ++fi ++ ++mkdir empty || framework_failure_ ++touch x y || framework_failure_ ++chattr +i empty || framework_failure_ ++rm -rf empty x y ++{ test -f x || test -f y; } && fail=1 ++chattr -i empty ++ ++Exit $fail +-- +2.26.2 + diff --git a/coreutils.spec b/coreutils.spec index 97e103e..0b7bd49 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 14%{?dist} +Release: 15%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -28,6 +28,9 @@ Patch4: coreutils-8.32-gnulib-perror-test.patch # df,stat,tail: recognize more file system types Patch5: coreutils-8.32-new-fs-types.patch +# rm: do not skip files upon failure to remove an empty dir (#1905481) +Patch6: coreutils-8.32-rm-stray-skip.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -280,6 +283,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Dec 08 2020 Kamil Dudka - 8.32-15 +- rm: do not skip files upon failure to remove an empty dir (#1905481) + * Tue Nov 03 2020 Kamil Dudka - 8.32-14 - df,stat,tail: recognize more file system types From f0b46ff947f6093ad3e8851c0066eeeab2fca5bd Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Sat, 19 Dec 2020 05:23:46 +0000 Subject: [PATCH 429/523] Add BuildRequires: make https://fedoraproject.org/wiki/Changes/Remove_make_from_BuildRoot --- coreutils.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/coreutils.spec b/coreutils.spec index 0b7bd49..a069988 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -104,6 +104,7 @@ BuildRequires: glibc-langpack-en BuildRequires: glibc-langpack-fr BuildRequires: glibc-langpack-ko %endif +BuildRequires: make Requires: %{name}-common = %{version}-%{release} From 44351906c767a77ef2caa85bc16f0f5ee2bc763e Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 7 Jan 2021 09:00:22 +0100 Subject: [PATCH 430/523] coreutils.spec: keep BR list alphabetically sorted --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index a069988..6175c30 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -91,6 +91,7 @@ BuildRequires: libattr-devel BuildRequires: libcap-devel BuildRequires: libselinux-devel BuildRequires: libselinux-utils +BuildRequires: make BuildRequires: openssl-devel BuildRequires: strace BuildRequires: texinfo @@ -104,7 +105,6 @@ BuildRequires: glibc-langpack-en BuildRequires: glibc-langpack-fr BuildRequires: glibc-langpack-ko %endif -BuildRequires: make Requires: %{name}-common = %{version}-%{release} From 581c05ccb446fc901c2290f545d61425778103b8 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Tue, 26 Jan 2021 02:34:09 +0000 Subject: [PATCH 431/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 6175c30..d6980da 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 15%{?dist} +Release: 16%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -284,6 +284,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jan 26 2021 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + * Tue Dec 08 2020 Kamil Dudka - 8.32-15 - rm: do not skip files upon failure to remove an empty dir (#1905481) From d5245cc71c67b66e42ee7efb29ae582253b94720 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 2 Feb 2021 15:25:51 +0100 Subject: [PATCH 432/523] Resolves: #1919775 - expr: fix invalid read with unmatched \(...\) --- coreutils-8.32-expr-unmatched-par.patch | 81 +++++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-expr-unmatched-par.patch diff --git a/coreutils-8.32-expr-unmatched-par.patch b/coreutils-8.32-expr-unmatched-par.patch new file mode 100644 index 0000000..1a82384 --- /dev/null +++ b/coreutils-8.32-expr-unmatched-par.patch @@ -0,0 +1,81 @@ +From 9618fb718b75920f37e5be2049ad1d0bb5c4a28c Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Tue, 26 Jan 2021 09:23:54 -0800 +Subject: [PATCH] expr: fix bug with unmatched \(...\) + +Problem reported by Qiuhao Li. +* doc/coreutils.texi (String expressions): +Document the correct behavior, which POSIX requires. +* src/expr.c (docolon): Treat unmatched \(...\) as empty. +* tests/misc/expr.pl: New test. + +Upstream-commit: 735083ba24878075235007b4417982ad5700436d +Signed-off-by: Kamil Dudka +--- + doc/coreutils.texi | 14 ++++++++------ + src/expr.c | 9 +++++++-- + tests/misc/expr.pl | 3 +++ + 3 files changed, 18 insertions(+), 8 deletions(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 2382a16..5b2bb2c 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -13529,12 +13529,14 @@ second is considered to be a (basic, a la GNU @code{grep}) regular + expression, with a @code{^} implicitly prepended. The first argument is + then matched against this regular expression. + +-If the match succeeds and @var{regex} uses @samp{\(} and @samp{\)}, the +-@code{:} expression returns the part of @var{string} that matched the +-subexpression; otherwise, it returns the number of characters matched. +- +-If the match fails, the @code{:} operator returns the null string if +-@samp{\(} and @samp{\)} are used in @var{regex}, otherwise 0. ++If @var{regex} does not use @samp{\(} and @samp{\)}, the @code{:} ++expression returns the number of characters matched, or 0 if the match ++fails. ++ ++If @var{regex} uses @samp{\(} and @samp{\)}, the @code{:} expression ++returns the part of @var{string} that matched the subexpression, or ++the null string if the match failed or the subexpression did not ++contribute to the match. + + @kindex \( @r{regexp operator} + Only the first @samp{\( @dots{} \)} pair is relevant to the return +diff --git a/src/expr.c b/src/expr.c +index e134872..0616a42 100644 +--- a/src/expr.c ++++ b/src/expr.c +@@ -721,8 +721,13 @@ docolon (VALUE *sv, VALUE *pv) + /* Were \(...\) used? */ + if (re_buffer.re_nsub > 0) + { +- sv->u.s[re_regs.end[1]] = '\0'; +- v = str_value (sv->u.s + re_regs.start[1]); ++ if (re_regs.end[1] < 0) ++ v = str_value (""); ++ else ++ { ++ sv->u.s[re_regs.end[1]] = '\0'; ++ v = str_value (sv->u.s + re_regs.start[1]); ++ } + } + else + { +diff --git a/tests/misc/expr.pl b/tests/misc/expr.pl +index e45f8e7..e57f79d 100755 +--- a/tests/misc/expr.pl ++++ b/tests/misc/expr.pl +@@ -84,6 +84,9 @@ my @Tests = + # In 5.94 and earlier, anchors incorrectly matched newlines. + ['anchor', "'a\nb' : 'a\$'", {OUT => '0'}, {EXIT => 1}], + ++ # In 8.32, \( ... \) that did not match caused memory errors. ++ ['emptysub', '"a" : "\\(b\\)*"', {OUT => ''}, {EXIT => 1}], ++ + # These tests are taken from grep/tests/bre.tests. + ['bre1', '"abc" : "a\\(b\\)c"', {OUT => 'b'}], + ['bre2', '"a(" : "a("', {OUT => '2'}], +-- +2.26.2 + diff --git a/coreutils.spec b/coreutils.spec index d6980da..3f2be33 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 16%{?dist} +Release: 17%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -31,6 +31,9 @@ Patch5: coreutils-8.32-new-fs-types.patch # rm: do not skip files upon failure to remove an empty dir (#1905481) Patch6: coreutils-8.32-rm-stray-skip.patch +# expr: fix invalid read with unmatched \(...\) (#1919775) +Patch7: coreutils-8.32-expr-unmatched-par.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -284,6 +287,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Feb 02 2021 Kamil Dudka - 8.32-17 +- expr: fix invalid read with unmatched \(...\) (#1919775) + * Tue Jan 26 2021 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild From 7afd521be21832b026e2b83159b32b7a4ff4b2e1 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 2 Feb 2021 15:27:21 +0100 Subject: [PATCH 433/523] Resolves: #1921246 - split: fix --number=K/N to output correct part of file --- coreutils-8.32-split-number.patch | 100 ++++++++++++++++++++++++++++++ coreutils.spec | 4 ++ 2 files changed, 104 insertions(+) create mode 100644 coreutils-8.32-split-number.patch diff --git a/coreutils-8.32-split-number.patch b/coreutils-8.32-split-number.patch new file mode 100644 index 0000000..89541bf --- /dev/null +++ b/coreutils-8.32-split-number.patch @@ -0,0 +1,100 @@ +From bb0e7fabcaed9a7e71e30f05e638e9f243cdb13e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Mon, 25 Jan 2021 14:12:48 +0000 +Subject: [PATCH] split: fix --number=K/N to output correct part of file + +This functionality regressed with the adjustments +in commit v8.25-4-g62e7af032 + +* src/split.c (bytes_chunk_extract): Account for already read data +when seeking into the file. +* tests/split/b-chunk.sh: Use the hidden ---io-blksize option, +to test this functionality. +Fixes https://bugs.gnu.org/46048 + +Upstream-commit: bb21daa125aeb4e32546309d370918ca47e612db +Signed-off-by: Kamil Dudka +--- + src/split.c | 2 +- + tests/split/b-chunk.sh | 45 ++++++++++++++++++++++++------------------ + 2 files changed, 27 insertions(+), 20 deletions(-) + +diff --git a/src/split.c b/src/split.c +index 09e610b..19248f6 100644 +--- a/src/split.c ++++ b/src/split.c +@@ -1001,7 +1001,7 @@ bytes_chunk_extract (uintmax_t k, uintmax_t n, char *buf, size_t bufsize, + } + else + { +- if (lseek (STDIN_FILENO, start, SEEK_CUR) < 0) ++ if (lseek (STDIN_FILENO, start - initial_read, SEEK_CUR) < 0) + die (EXIT_FAILURE, errno, "%s", quotef (infile)); + initial_read = SIZE_MAX; + } +diff --git a/tests/split/b-chunk.sh b/tests/split/b-chunk.sh +index 864ce55..39a6799 100755 +--- a/tests/split/b-chunk.sh ++++ b/tests/split/b-chunk.sh +@@ -35,32 +35,39 @@ split -e -n 10 /dev/null || fail=1 + returns_ 1 stat x?? 2>/dev/null || fail=1 + + printf '1\n2\n3\n4\n5\n' > input || framework_failure_ ++printf '1\n2' > exp-1 || framework_failure_ ++printf '\n3\n' > exp-2 || framework_failure_ ++printf '4\n5\n' > exp-3 || framework_failure_ + + for file in input /proc/version /sys/kernel/profiling; do + test -f $file || continue + +- split -n 3 $file > out || fail=1 +- split -n 1/3 $file > b1 || fail=1 +- split -n 2/3 $file > b2 || fail=1 +- split -n 3/3 $file > b3 || fail=1 ++ for blksize in 1 2 4096; do ++ if ! test "$file" = 'input'; then ++ # For /proc like files we must be able to read all ++ # into the internal buffer to be able to determine size. ++ test "$blksize" = 4096 || continue ++ fi + +- case $file in +- input) +- printf '1\n2' > exp-1 +- printf '\n3\n' > exp-2 +- printf '4\n5\n' > exp-3 ++ split -n 3 ---io-blksize=$blksize $file > out || fail=1 ++ split -n 1/3 ---io-blksize=$blksize $file > b1 || fail=1 ++ split -n 2/3 ---io-blksize=$blksize $file > b2 || fail=1 ++ split -n 3/3 ---io-blksize=$blksize $file > b3 || fail=1 + +- compare exp-1 xaa || fail=1 +- compare exp-2 xab || fail=1 +- compare exp-3 xac || fail=1 +- ;; +- esac ++ case $file in ++ input) ++ compare exp-1 xaa || fail=1 ++ compare exp-2 xab || fail=1 ++ compare exp-3 xac || fail=1 ++ ;; ++ esac + +- compare xaa b1 || fail=1 +- compare xab b2 || fail=1 +- compare xac b3 || fail=1 +- cat xaa xab xac | compare - $file || fail=1 +- test -f xad && fail=1 ++ compare xaa b1 || fail=1 ++ compare xab b2 || fail=1 ++ compare xac b3 || fail=1 ++ cat xaa xab xac | compare - $file || fail=1 ++ test -f xad && fail=1 ++ done + done + + Exit $fail +-- +2.26.2 + diff --git a/coreutils.spec b/coreutils.spec index 3f2be33..4ab8440 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -34,6 +34,9 @@ Patch6: coreutils-8.32-rm-stray-skip.patch # expr: fix invalid read with unmatched \(...\) (#1919775) Patch7: coreutils-8.32-expr-unmatched-par.patch +# split: fix --number=K/N to output correct part of file (#1921246) +Patch8: coreutils-8.32-split-number.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -288,6 +291,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Tue Feb 02 2021 Kamil Dudka - 8.32-17 +- split: fix --number=K/N to output correct part of file (#1921246) - expr: fix invalid read with unmatched \(...\) (#1919775) * Tue Jan 26 2021 Fedora Release Engineering From 4bd3080a0001ad9a0584416ce333eda1ce3c56e0 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 2 Feb 2021 15:28:59 +0100 Subject: [PATCH 434/523] Resolves: #1921249 - ls: fix crash printing SELinux context for unstatable files --- coreutils-8.32-ls-scontext-crash.patch | 85 ++++++++++++++++++++++++++ coreutils.spec | 4 ++ 2 files changed, 89 insertions(+) create mode 100644 coreutils-8.32-ls-scontext-crash.patch diff --git a/coreutils-8.32-ls-scontext-crash.patch b/coreutils-8.32-ls-scontext-crash.patch new file mode 100644 index 0000000..a3ddff9 --- /dev/null +++ b/coreutils-8.32-ls-scontext-crash.patch @@ -0,0 +1,85 @@ +From 53c6b01e8e3fd338d7f53e5ff817ef86f9efa852 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Wed, 11 Nov 2020 17:22:33 +0000 +Subject: [PATCH] ls: fix crash printing SELinux context for unstatable files + +This crash was identified by Cyber Independent Testing Lab: +https://cyber-itl.org/2020/10/28/citl-7000-defects.html +and was introduced with commit v6.9.90-11-g4245876e2 + +* src/ls.c (gobble_file): Ensure scontext is initialized +in the case where files are not statable. +* tests/ls/selinux-segfault.sh: Renamed from proc-selinux-segfault.sh, +and added test case for broken symlinks. +* tests/local.mk: Adjust for the renamed test. + +Upstream-commit: 6fc695cb4a26f09dfeef8b1c24895a707055334e +Signed-off-by: Kamil Dudka +--- + src/ls.c | 3 +++ + tests/local.mk | 2 +- + .../{proc-selinux-segfault.sh => selinux-segfault.sh} | 10 ++++++++-- + 3 files changed, 12 insertions(+), 3 deletions(-) + rename tests/ls/{proc-selinux-segfault.sh => selinux-segfault.sh} (77%) + +diff --git a/src/ls.c b/src/ls.c +index 4acf5f4..8eb483d 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -3412,6 +3412,9 @@ gobble_file (char const *name, enum filetype type, ino_t inode, + provokes an exit status of 1. */ + file_failure (command_line_arg, + _("cannot access %s"), full_name); ++ ++ f->scontext = UNKNOWN_SECURITY_CONTEXT; ++ + if (command_line_arg) + return 0; + +diff --git a/tests/local.mk b/tests/local.mk +index 2aeff2b..2441fdc 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -616,7 +616,7 @@ all_tests = \ + tests/ls/multihardlink.sh \ + tests/ls/no-arg.sh \ + tests/ls/no-cap.sh \ +- tests/ls/proc-selinux-segfault.sh \ ++ tests/ls/selinux-segfault.sh \ + tests/ls/quote-align.sh \ + tests/ls/readdir-mountpoint-inode.sh \ + tests/ls/recursive.sh \ +diff --git a/tests/ls/proc-selinux-segfault.sh b/tests/ls/selinux-segfault.sh +similarity index 77% +rename from tests/ls/proc-selinux-segfault.sh +rename to tests/ls/selinux-segfault.sh +index 831a00e..e2b7ef6 100755 +--- a/tests/ls/proc-selinux-segfault.sh ++++ b/tests/ls/selinux-segfault.sh +@@ -1,5 +1,5 @@ + #!/bin/sh +-# ls -l /proc/sys would segfault when built against libselinux1 2.0.15-2+b1 ++# Ensure we don't segfault in selinux handling + + # Copyright (C) 2008-2020 Free Software Foundation, Inc. + +@@ -19,9 +19,15 @@ + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ ls + ++# ls -l /proc/sys would segfault when built against libselinux1 2.0.15-2+b1 + f=/proc/sys + test -r $f || f=. +- + ls -l $f > out || fail=1 + ++# ls <= 8.32 would segfault when printing ++# the security context of broken symlink targets ++mkdir sedir || framework_failure_ ++ln -sf missing sedir/broken || framework_failure_ ++returns_ 1 ls -L -R -Z -m sedir > out || fail=1 ++ + Exit $fail +-- +2.26.2 + diff --git a/coreutils.spec b/coreutils.spec index 4ab8440..829fab4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -37,6 +37,9 @@ Patch7: coreutils-8.32-expr-unmatched-par.patch # split: fix --number=K/N to output correct part of file (#1921246) Patch8: coreutils-8.32-split-number.patch +# ls: fix crash printing SELinux context for unstatable files (#1921249) +Patch9: coreutils-8.32-ls-scontext-crash.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -291,6 +294,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Tue Feb 02 2021 Kamil Dudka - 8.32-17 +- ls: fix crash printing SELinux context for unstatable files (#1921249) - split: fix --number=K/N to output correct part of file (#1921246) - expr: fix invalid read with unmatched \(...\) (#1919775) From c822f6b1c086ecf75d3a5c11067f6f4ac0e46fff Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 3 Feb 2021 16:39:47 +0100 Subject: [PATCH 435/523] Resolves: #959597 - make coreutils-common recommend glibc-doc ... for info doc refs --- coreutils.spec | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 829fab4..a2dbc5b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 17%{?dist} +Release: 18%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -146,6 +146,10 @@ packaged as a single multicall binary. # yum obsoleting rules explained at: # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 + +# info doc refers to "Specifying the Time Zone" from glibc-doc (#959597) +Recommends: glibc-doc + Recommends: ncurses Summary: coreutils common optional components %description common @@ -293,6 +297,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Feb 03 2021 Kamil Dudka - 8.32-18 +- make coreutils-common recommend glibc-doc for info doc refs (#959597) + * Tue Feb 02 2021 Kamil Dudka - 8.32-17 - ls: fix crash printing SELinux context for unstatable files (#1921249) - split: fix --number=K/N to output correct part of file (#1921246) From 6b50cb9fc4619c2aff1dd5f06c0e73b3c336ea8c Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 18 Feb 2021 15:38:36 +0100 Subject: [PATCH 436/523] Resolves: #1921427 - stat: add support for the exfat file system --- coreutils-8.32-stat-exfat.patch | 32 ++++++++++++++++++++++++++++++++ coreutils.spec | 8 +++++++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-stat-exfat.patch diff --git a/coreutils-8.32-stat-exfat.patch b/coreutils-8.32-stat-exfat.patch new file mode 100644 index 0000000..ea8d0cd --- /dev/null +++ b/coreutils-8.32-stat-exfat.patch @@ -0,0 +1,32 @@ +From b87f944c87ffe04db6e5476b007a8e4979de933d Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 18 Feb 2021 11:18:04 +0100 +Subject: [PATCH] stat,tail: add support for the exfat file system + +Bug: https://bugzilla.redhat.com/1921427 + +* src/stat.c (human_fstype): Add case for the 'exfat' file system type. +Fixes https://bugs.gnu.org/46613 + +Upstream-commit: a5e0d8f387e81e854427addbbaf2504541bbf4b9 +Signed-off-by: Kamil Dudka +--- + src/stat.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/stat.c b/src/stat.c +index 8cd69da..4e1c8e3 100644 +--- a/src/stat.c ++++ b/src/stat.c +@@ -361,6 +361,8 @@ human_fstype (STRUCT_STATVFS const *statfsbuf) + return "efs"; + case S_MAGIC_EROFS_V1: /* 0xE0F5E1E2 local */ + return "erofs"; ++ case S_MAGIC_EXFAT: /* 0x2011BAB0 local */ ++ return "exfat"; + case S_MAGIC_EXFS: /* 0x45584653 local */ + return "exfs"; + case S_MAGIC_EXOFS: /* 0x5DF5 local */ +-- +2.26.2 + diff --git a/coreutils.spec b/coreutils.spec index a2dbc5b..83c0e52 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 18%{?dist} +Release: 19%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -40,6 +40,9 @@ Patch8: coreutils-8.32-split-number.patch # ls: fix crash printing SELinux context for unstatable files (#1921249) Patch9: coreutils-8.32-ls-scontext-crash.patch +# stat: add support for the exfat file system (#1921427) +Patch10: coreutils-8.32-stat-exfat.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -297,6 +300,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Feb 18 2021 Kamil Dudka - 8.32-19 +- stat: add support for the exfat file system (#1921427) + * Wed Feb 03 2021 Kamil Dudka - 8.32-18 - make coreutils-common recommend glibc-doc for info doc refs (#959597) From 1737e5c81fa82451b510f982499bdedb2a1619d1 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 24 Mar 2021 16:09:51 +0100 Subject: [PATCH 437/523] Resolves: #1730048 - cp: use copy_file_range if available --- coreutils-8.32-cp-file-range.patch | 978 +++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 985 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-cp-file-range.patch diff --git a/coreutils-8.32-cp-file-range.patch b/coreutils-8.32-cp-file-range.patch new file mode 100644 index 0000000..8d84040 --- /dev/null +++ b/coreutils-8.32-cp-file-range.patch @@ -0,0 +1,978 @@ +From 5f2dac18054d9d9b3d84e7fba8c2a6e750d2c245 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Wed, 1 Apr 2020 12:51:34 +0100 +Subject: [PATCH 1/6] cp: ensure --attributes-only doesn't remove files + +* src/copy.c (copy_internal): Ensure we don't unlink the destination +unless explicitly requested. +* tests/cp/attr-existing.sh: Add test cases. +* NEWS: Mention the bug fix. +Fixes https://bugs.gnu.org/40352 + +Upstream-commit: 7b5f0fa47cd04c84975250d5b5da7c98e097e99f +Signed-off-by: Kamil Dudka +--- + src/copy.c | 9 +++++---- + tests/cp/attr-existing.sh | 21 ++++++++++++++++++--- + 2 files changed, 23 insertions(+), 7 deletions(-) + +diff --git a/src/copy.c b/src/copy.c +index 6e5efc7..54601ce 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -2211,10 +2211,11 @@ copy_internal (char const *src_name, char const *dst_name, + /* Never unlink dst_name when in move mode. */ + && ! x->move_mode + && (x->unlink_dest_before_opening +- || (x->preserve_links && 1 < dst_sb.st_nlink) +- || (x->dereference == DEREF_NEVER +- && ! S_ISREG (src_sb.st_mode)) +- )) ++ || (x->data_copy_required ++ && ((x->preserve_links && 1 < dst_sb.st_nlink) ++ || (x->dereference == DEREF_NEVER ++ && ! S_ISREG (src_sb.st_mode)))) ++ )) + { + if (unlink (dst_name) != 0 && errno != ENOENT) + { +diff --git a/tests/cp/attr-existing.sh b/tests/cp/attr-existing.sh +index 59ce641..14fc844 100755 +--- a/tests/cp/attr-existing.sh ++++ b/tests/cp/attr-existing.sh +@@ -19,11 +19,26 @@ + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src + print_ver_ cp + +-printf '1' > file1 +-printf '2' > file2 +-printf '2' > file2.exp ++printf '1' > file1 || framework_failure_ ++printf '2' > file2 || framework_failure_ ++printf '2' > file2.exp || framework_failure_ + + cp --attributes-only file1 file2 || fail=1 + cmp file2 file2.exp || fail=1 + ++# coreutils v8.32 and before would remove destination files ++# if hardlinked or the source was not a regular file. ++ln file2 link2 || framework_failure_ ++cp -a --attributes-only file1 file2 || fail=1 ++cmp file2 file2.exp || fail=1 ++ ++ln -s file1 sym1 || framework_failure_ ++returns_ 1 cp -a --attributes-only sym1 file2 || fail=1 ++cmp file2 file2.exp || fail=1 ++ ++# One can still force removal though ++cp -a --remove-destination --attributes-only sym1 file2 || fail=1 ++test -L file2 || fail=1 ++cmp file1 file2 || fail=1 ++ + Exit $fail +-- +2.26.3 + + +From c728747b06e71894c96d1f27434f2484af992c75 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Tue, 23 Jun 2020 19:18:04 -0700 +Subject: [PATCH 2/6] cp: refactor extent_copy + +* src/copy.c (extent_copy): New arg SCAN, replacing +REQUIRE_NORMAL_COPY. All callers changed. +(enum scantype): New type. +(infer_scantype): Rename from is_probably_sparse and return +the new type. Add args FD and SCAN. All callers changed. + +Upstream-commit: 761ba28400a04ee24eefe9cd4973ec8850cd7a52 +Signed-off-by: Kamil Dudka +--- + src/copy.c | 119 +++++++++++++++++++++++++---------------------------- + 1 file changed, 55 insertions(+), 64 deletions(-) + +diff --git a/src/copy.c b/src/copy.c +index 54601ce..f694f91 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -422,9 +422,8 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + size_t hole_size, off_t src_total_size, + enum Sparse_type sparse_mode, + char const *src_name, char const *dst_name, +- bool *require_normal_copy) ++ struct extent_scan *scan) + { +- struct extent_scan scan; + off_t last_ext_start = 0; + off_t last_ext_len = 0; + +@@ -432,45 +431,25 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + We may need this at the end, for a final ftruncate. */ + off_t dest_pos = 0; + +- extent_scan_init (src_fd, &scan); +- +- *require_normal_copy = false; + bool wrote_hole_at_eof = true; +- do ++ while (true) + { +- bool ok = extent_scan_read (&scan); +- if (! ok) +- { +- if (scan.hit_final_extent) +- break; +- +- if (scan.initial_scan_failed) +- { +- *require_normal_copy = true; +- return false; +- } +- +- error (0, errno, _("%s: failed to get extents info"), +- quotef (src_name)); +- return false; +- } +- + bool empty_extent = false; +- for (unsigned int i = 0; i < scan.ei_count || empty_extent; i++) ++ for (unsigned int i = 0; i < scan->ei_count || empty_extent; i++) + { + off_t ext_start; + off_t ext_len; + off_t ext_hole_size; + +- if (i < scan.ei_count) ++ if (i < scan->ei_count) + { +- ext_start = scan.ext_info[i].ext_logical; +- ext_len = scan.ext_info[i].ext_length; ++ ext_start = scan->ext_info[i].ext_logical; ++ ext_len = scan->ext_info[i].ext_length; + } + else /* empty extent at EOF. */ + { + i--; +- ext_start = last_ext_start + scan.ext_info[i].ext_length; ++ ext_start = last_ext_start + scan->ext_info[i].ext_length; + ext_len = 0; + } + +@@ -498,7 +477,7 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + { + error (0, errno, _("cannot lseek %s"), quoteaf (src_name)); + fail: +- extent_scan_free (&scan); ++ extent_scan_free (scan); + return false; + } + +@@ -539,7 +518,7 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + /* For now, do not treat FIEMAP_EXTENT_UNWRITTEN specially, + because that (in combination with no sync) would lead to data + loss at least on XFS and ext4 when using 2.6.39-rc3 kernels. */ +- if (0 && (scan.ext_info[i].ext_flags & FIEMAP_EXTENT_UNWRITTEN)) ++ if (0 && (scan->ext_info[i].ext_flags & FIEMAP_EXTENT_UNWRITTEN)) + { + empty_extent = true; + last_ext_len = 0; +@@ -571,16 +550,23 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + extents beyond the apparent size. */ + if (dest_pos == src_total_size) + { +- scan.hit_final_extent = true; ++ scan->hit_final_extent = true; + break; + } + } + + /* Release the space allocated to scan->ext_info. */ +- extent_scan_free (&scan); ++ extent_scan_free (scan); + ++ if (scan->hit_final_extent) ++ break; ++ if (! extent_scan_read (scan) && ! scan->hit_final_extent) ++ { ++ error (0, errno, _("%s: failed to get extents info"), ++ quotef (src_name)); ++ return false; ++ } + } +- while (! scan.hit_final_extent); + + /* When the source file ends with a hole, we have to do a little more work, + since the above copied only up to and including the final extent. +@@ -1021,16 +1007,35 @@ fchmod_or_lchmod (int desc, char const *name, mode_t mode) + # define HAVE_STRUCT_STAT_ST_BLOCKS 0 + #endif + ++/* Type of scan being done on the input when looking for sparseness. */ ++enum scantype ++ { ++ /* No fancy scanning; just read and write. */ ++ PLAIN_SCANTYPE, ++ ++ /* Read and examine data looking for zero blocks; useful when ++ attempting to create sparse output. */ ++ ZERO_SCANTYPE, ++ ++ /* Extent information is available. */ ++ EXTENT_SCANTYPE ++ }; ++ + /* Use a heuristic to determine whether stat buffer SB comes from a file + with sparse blocks. If the file has fewer blocks than would normally + be needed for a file of its size, then at least one of the blocks in + the file is a hole. In that case, return true. */ +-static bool +-is_probably_sparse (struct stat const *sb) ++static enum scantype ++infer_scantype (int fd, struct stat const *sb, struct extent_scan *scan) + { +- return (HAVE_STRUCT_STAT_ST_BLOCKS +- && S_ISREG (sb->st_mode) +- && ST_NBLOCKS (*sb) < sb->st_size / ST_NBLOCKSIZE); ++ if (! (HAVE_STRUCT_STAT_ST_BLOCKS ++ && S_ISREG (sb->st_mode) ++ && ST_NBLOCKS (*sb) < sb->st_size / ST_NBLOCKSIZE)) ++ return PLAIN_SCANTYPE; ++ ++ extent_scan_init (fd, scan); ++ extent_scan_read (scan); ++ return scan->initial_scan_failed ? ZERO_SCANTYPE : EXTENT_SCANTYPE; + } + + +@@ -1061,6 +1066,7 @@ copy_reg (char const *src_name, char const *dst_name, + mode_t src_mode = src_sb->st_mode; + struct stat sb; + struct stat src_open_sb; ++ struct extent_scan scan; + bool return_val = true; + bool data_copy_required = x->data_copy_required; + +@@ -1260,23 +1266,13 @@ copy_reg (char const *src_name, char const *dst_name, + fdadvise (source_desc, 0, 0, FADVISE_SEQUENTIAL); + + /* Deal with sparse files. */ +- bool make_holes = false; +- bool sparse_src = is_probably_sparse (&src_open_sb); +- +- if (S_ISREG (sb.st_mode)) +- { +- /* Even with --sparse=always, try to create holes only +- if the destination is a regular file. */ +- if (x->sparse_mode == SPARSE_ALWAYS) +- make_holes = true; +- +- /* Use a heuristic to determine whether SRC_NAME contains any sparse +- blocks. If the file has fewer blocks than would normally be +- needed for a file of its size, then at least one of the blocks in +- the file is a hole. */ +- if (x->sparse_mode == SPARSE_AUTO && sparse_src) +- make_holes = true; +- } ++ enum scantype scantype = infer_scantype (source_desc, &src_open_sb, ++ &scan); ++ bool make_holes ++ = (S_ISREG (sb.st_mode) ++ && (x->sparse_mode == SPARSE_ALWAYS ++ || (x->sparse_mode == SPARSE_AUTO ++ && scantype != PLAIN_SCANTYPE))); + + /* If not making a sparse file, try to use a more-efficient + buffer size. */ +@@ -1305,10 +1301,8 @@ copy_reg (char const *src_name, char const *dst_name, + buf_alloc = xmalloc (buf_size + buf_alignment); + buf = ptr_align (buf_alloc, buf_alignment); + +- if (sparse_src) ++ if (scantype == EXTENT_SCANTYPE) + { +- bool normal_copy_required; +- + /* Perform an efficient extent-based copy, falling back to the + standard copy only if the initial extent scan fails. If the + '--sparse=never' option is specified, write all data but use +@@ -1316,14 +1310,11 @@ copy_reg (char const *src_name, char const *dst_name, + if (extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, + src_open_sb.st_size, + make_holes ? x->sparse_mode : SPARSE_NEVER, +- src_name, dst_name, &normal_copy_required)) ++ src_name, dst_name, &scan)) + goto preserve_metadata; + +- if (! normal_copy_required) +- { +- return_val = false; +- goto close_src_and_dst_desc; +- } ++ return_val = false; ++ goto close_src_and_dst_desc; + } + + off_t n_read; +-- +2.26.3 + + +From ed7ff81de507bef46991f4caac550f41ab65e3ed Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Wed, 24 Jun 2020 17:05:20 -0700 +Subject: [PATCH 3/6] cp: avoid copy_reg goto + +* src/copy.c (copy_reg): Redo to avoid label and goto. + +Upstream-commit: 2fcd0f3328f5181a2986905fa5469a0152c67279 +Signed-off-by: Kamil Dudka +--- + src/copy.c | 34 +++++++++++----------------------- + 1 file changed, 11 insertions(+), 23 deletions(-) + +diff --git a/src/copy.c b/src/copy.c +index f694f91..b382cfa 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -1301,29 +1301,18 @@ copy_reg (char const *src_name, char const *dst_name, + buf_alloc = xmalloc (buf_size + buf_alignment); + buf = ptr_align (buf_alloc, buf_alignment); + +- if (scantype == EXTENT_SCANTYPE) +- { +- /* Perform an efficient extent-based copy, falling back to the +- standard copy only if the initial extent scan fails. If the +- '--sparse=never' option is specified, write all data but use +- any extents to read more efficiently. */ +- if (extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, +- src_open_sb.st_size, +- make_holes ? x->sparse_mode : SPARSE_NEVER, +- src_name, dst_name, &scan)) +- goto preserve_metadata; +- +- return_val = false; +- goto close_src_and_dst_desc; +- } +- + off_t n_read; +- bool wrote_hole_at_eof; +- if (! sparse_copy (source_desc, dest_desc, buf, buf_size, +- make_holes ? hole_size : 0, +- x->sparse_mode == SPARSE_ALWAYS, src_name, dst_name, +- UINTMAX_MAX, &n_read, +- &wrote_hole_at_eof)) ++ bool wrote_hole_at_eof = false; ++ if (! (scantype == EXTENT_SCANTYPE ++ ? extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, ++ src_open_sb.st_size, ++ make_holes ? x->sparse_mode : SPARSE_NEVER, ++ src_name, dst_name, &scan) ++ : sparse_copy (source_desc, dest_desc, buf, buf_size, ++ make_holes ? hole_size : 0, ++ x->sparse_mode == SPARSE_ALWAYS, ++ src_name, dst_name, UINTMAX_MAX, &n_read, ++ &wrote_hole_at_eof))) + { + return_val = false; + goto close_src_and_dst_desc; +@@ -1336,7 +1325,6 @@ copy_reg (char const *src_name, char const *dst_name, + } + } + +-preserve_metadata: + if (x->preserve_timestamps) + { + struct timespec timespec[2]; +-- +2.26.3 + + +From 5631bded3a385ca0bbd77456b50767fe5580240c Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 25 Jun 2020 16:31:44 -0700 +Subject: [PATCH 4/6] cp: use SEEK_DATA/SEEK_HOLE if available + +If it works, prefer lseek with SEEK_DATA and SEEK_HOLE to FIEMAP, +as lseek is simpler and more portable (will be in next POSIX). +Problem reported in 2011 by Jeff Liu (Bug#8061). +* NEWS: Mention this. +* src/copy.c (lseek_copy) [SEEK_HOLE]: New function. +(enum scantype): New constants ERROR_SCANTYPE, LSEEK_SCANTYPE. +(union scan_inference): New type. +(infer_scantype): Last arg is now union scan_inference *, +not struct extent_scan *. All callers changed. +Prefer SEEK_HOLE to FIEMAP if both work, since +SEEK_HOLE is simpler and more portable. +(copy_reg): Do the fdadvise after initial scan, in case the scan +fails. Report an error if the initial scan fails. +(copy_reg) [SEEK_HOLE]: Use lseek_copy if scantype says so. + +Upstream-commit: a6eaee501f6ec0c152abe88640203a64c390993e +Signed-off-by: Kamil Dudka +--- + src/copy.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 198 insertions(+), 11 deletions(-) + +diff --git a/src/copy.c b/src/copy.c +index b382cfa..d88f8cf 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -416,7 +416,12 @@ write_zeros (int fd, off_t n_bytes) + Upon a successful copy, return true. If the initial extent scan + fails, set *NORMAL_COPY_REQUIRED to true and return false. + Upon any other failure, set *NORMAL_COPY_REQUIRED to false and +- return false. */ ++ return false. ++ ++ FIXME: Once we no longer need to support Linux kernel versions ++ before 3.1 (2011), this function can be retired as it is superseded ++ by lseek_copy. That is, we no longer need extent-scan.h and can ++ remove any of the code that uses it. */ + static bool + extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + size_t hole_size, off_t src_total_size, +@@ -595,6 +600,150 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + return true; + } + ++#ifdef SEEK_HOLE ++/* Perform an efficient extent copy, if possible. This avoids ++ the overhead of detecting holes in hole-introducing/preserving ++ copy, and thus makes copying sparse files much more efficient. ++ Copy from SRC_FD to DEST_FD, using BUF (of size BUF_SIZE) for a buffer. ++ Look for holes of size HOLE_SIZE in the input. ++ The input file is of size SRC_TOTAL_SIZE. ++ Use SPARSE_MODE to determine whether to create holes in the output. ++ SRC_NAME and DST_NAME are the input and output file names. ++ Return true if successful, false (with a diagnostic) otherwise. */ ++ ++static bool ++lseek_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, ++ size_t hole_size, off_t ext_start, off_t src_total_size, ++ enum Sparse_type sparse_mode, ++ char const *src_name, char const *dst_name) ++{ ++ off_t last_ext_start = 0; ++ off_t last_ext_len = 0; ++ off_t dest_pos = 0; ++ bool wrote_hole_at_eof = true; ++ ++ while (0 <= ext_start) ++ { ++ off_t ext_end = lseek (src_fd, ext_start, SEEK_HOLE); ++ if (ext_end < 0) ++ { ++ if (errno != ENXIO) ++ goto cannot_lseek; ++ ext_end = src_total_size; ++ if (ext_end <= ext_start) ++ { ++ /* The input file grew; get its current size. */ ++ src_total_size = lseek (src_fd, 0, SEEK_END); ++ if (src_total_size < 0) ++ goto cannot_lseek; ++ ++ /* If the input file shrank after growing, stop copying. */ ++ if (src_total_size <= ext_start) ++ break; ++ ++ ext_end = src_total_size; ++ } ++ } ++ /* If the input file must have grown, increase its measured size. */ ++ if (src_total_size < ext_end) ++ src_total_size = ext_end; ++ ++ if (lseek (src_fd, ext_start, SEEK_SET) < 0) ++ goto cannot_lseek; ++ ++ wrote_hole_at_eof = false; ++ off_t ext_hole_size = ext_start - last_ext_start - last_ext_len; ++ ++ if (ext_hole_size) ++ { ++ if (sparse_mode != SPARSE_NEVER) ++ { ++ if (! create_hole (dest_fd, dst_name, ++ sparse_mode == SPARSE_ALWAYS, ++ ext_hole_size)) ++ return false; ++ wrote_hole_at_eof = true; ++ } ++ else ++ { ++ /* When not inducing holes and when there is a hole between ++ the end of the previous extent and the beginning of the ++ current one, write zeros to the destination file. */ ++ if (! write_zeros (dest_fd, ext_hole_size)) ++ { ++ error (0, errno, _("%s: write failed"), ++ quotef (dst_name)); ++ return false; ++ } ++ } ++ } ++ ++ off_t ext_len = ext_end - ext_start; ++ last_ext_start = ext_start; ++ last_ext_len = ext_len; ++ ++ /* Copy this extent, looking for further opportunities to not ++ bother to write zeros unless --sparse=never, since SEEK_HOLE ++ is conservative and may miss some holes. */ ++ off_t n_read; ++ bool read_hole; ++ if ( ! sparse_copy (src_fd, dest_fd, buf, buf_size, ++ sparse_mode == SPARSE_NEVER ? 0 : hole_size, ++ true, src_name, dst_name, ext_len, &n_read, ++ &read_hole)) ++ return false; ++ ++ dest_pos = ext_start + n_read; ++ if (n_read) ++ wrote_hole_at_eof = read_hole; ++ if (n_read < ext_len) ++ { ++ /* The input file shrank. */ ++ src_total_size = dest_pos; ++ break; ++ } ++ ++ ext_start = lseek (src_fd, dest_pos, SEEK_DATA); ++ if (ext_start < 0) ++ { ++ if (errno != ENXIO) ++ goto cannot_lseek; ++ break; ++ } ++ } ++ ++ /* When the source file ends with a hole, we have to do a little more work, ++ since the above copied only up to and including the final extent. ++ In order to complete the copy, we may have to insert a hole or write ++ zeros in the destination corresponding to the source file's hole-at-EOF. ++ ++ In addition, if the final extent was a block of zeros at EOF and we've ++ just converted them to a hole in the destination, we must call ftruncate ++ here in order to record the proper length in the destination. */ ++ if ((dest_pos < src_total_size || wrote_hole_at_eof) ++ && ! (sparse_mode == SPARSE_NEVER ++ ? write_zeros (dest_fd, src_total_size - dest_pos) ++ : ftruncate (dest_fd, src_total_size) == 0)) ++ { ++ error (0, errno, _("failed to extend %s"), quoteaf (dst_name)); ++ return false; ++ } ++ ++ if (sparse_mode == SPARSE_ALWAYS && dest_pos < src_total_size ++ && punch_hole (dest_fd, dest_pos, src_total_size - dest_pos) < 0) ++ { ++ error (0, errno, _("error deallocating %s"), quoteaf (dst_name)); ++ return false; ++ } ++ ++ return true; ++ ++ cannot_lseek: ++ error (0, errno, _("cannot lseek %s"), quoteaf (src_name)); ++ return false; ++} ++#endif ++ + /* FIXME: describe */ + /* FIXME: rewrite this to use a hash table so we avoid the quadratic + performance hit that's probably noticeable only on trees deeper +@@ -1010,6 +1159,9 @@ fchmod_or_lchmod (int desc, char const *name, mode_t mode) + /* Type of scan being done on the input when looking for sparseness. */ + enum scantype + { ++ /* An error was found when determining scantype. */ ++ ERROR_SCANTYPE, ++ + /* No fancy scanning; just read and write. */ + PLAIN_SCANTYPE, + +@@ -1017,22 +1169,44 @@ enum scantype + attempting to create sparse output. */ + ZERO_SCANTYPE, + ++ /* lseek information is available. */ ++ LSEEK_SCANTYPE, ++ + /* Extent information is available. */ + EXTENT_SCANTYPE + }; + +-/* Use a heuristic to determine whether stat buffer SB comes from a file +- with sparse blocks. If the file has fewer blocks than would normally +- be needed for a file of its size, then at least one of the blocks in +- the file is a hole. In that case, return true. */ ++/* Result of infer_scantype. */ ++union scan_inference ++{ ++ /* Used if infer_scantype returns LSEEK_SCANTYPE. This is the ++ offset of the first data block, or -1 if the file has no data. */ ++ off_t ext_start; ++ ++ /* Used if infer_scantype returns EXTENT_SCANTYPE. */ ++ struct extent_scan extent_scan; ++}; ++ ++/* Return how to scan a file with descriptor FD and stat buffer SB. ++ Store any information gathered into *SCAN. */ + static enum scantype +-infer_scantype (int fd, struct stat const *sb, struct extent_scan *scan) ++infer_scantype (int fd, struct stat const *sb, ++ union scan_inference *scan_inference) + { + if (! (HAVE_STRUCT_STAT_ST_BLOCKS + && S_ISREG (sb->st_mode) + && ST_NBLOCKS (*sb) < sb->st_size / ST_NBLOCKSIZE)) + return PLAIN_SCANTYPE; + ++#ifdef SEEK_HOLE ++ scan_inference->ext_start = lseek (fd, 0, SEEK_DATA); ++ if (0 <= scan_inference->ext_start) ++ return LSEEK_SCANTYPE; ++ else if (errno != EINVAL && errno != ENOTSUP) ++ return errno == ENXIO ? LSEEK_SCANTYPE : ERROR_SCANTYPE; ++#endif ++ ++ struct extent_scan *scan = &scan_inference->extent_scan; + extent_scan_init (fd, scan); + extent_scan_read (scan); + return scan->initial_scan_failed ? ZERO_SCANTYPE : EXTENT_SCANTYPE; +@@ -1066,7 +1240,7 @@ copy_reg (char const *src_name, char const *dst_name, + mode_t src_mode = src_sb->st_mode; + struct stat sb; + struct stat src_open_sb; +- struct extent_scan scan; ++ union scan_inference scan_inference; + bool return_val = true; + bool data_copy_required = x->data_copy_required; + +@@ -1263,17 +1437,23 @@ copy_reg (char const *src_name, char const *dst_name, + size_t buf_size = io_blksize (sb); + size_t hole_size = ST_BLKSIZE (sb); + +- fdadvise (source_desc, 0, 0, FADVISE_SEQUENTIAL); +- + /* Deal with sparse files. */ + enum scantype scantype = infer_scantype (source_desc, &src_open_sb, +- &scan); ++ &scan_inference); ++ if (scantype == ERROR_SCANTYPE) ++ { ++ error (0, errno, _("cannot lseek %s"), quoteaf (src_name)); ++ return_val = false; ++ goto close_src_and_dst_desc; ++ } + bool make_holes + = (S_ISREG (sb.st_mode) + && (x->sparse_mode == SPARSE_ALWAYS + || (x->sparse_mode == SPARSE_AUTO + && scantype != PLAIN_SCANTYPE))); + ++ fdadvise (source_desc, 0, 0, FADVISE_SEQUENTIAL); ++ + /* If not making a sparse file, try to use a more-efficient + buffer size. */ + if (! make_holes) +@@ -1307,7 +1487,14 @@ copy_reg (char const *src_name, char const *dst_name, + ? extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, + src_open_sb.st_size, + make_holes ? x->sparse_mode : SPARSE_NEVER, +- src_name, dst_name, &scan) ++ src_name, dst_name, &scan_inference.extent_scan) ++#ifdef SEEK_HOLE ++ : scantype == LSEEK_SCANTYPE ++ ? lseek_copy (source_desc, dest_desc, buf, buf_size, hole_size, ++ scan_inference.ext_start, src_open_sb.st_size, ++ make_holes ? x->sparse_mode : SPARSE_NEVER, ++ src_name, dst_name) ++#endif + : sparse_copy (source_desc, dest_desc, buf, buf_size, + make_holes ? hole_size : 0, + x->sparse_mode == SPARSE_ALWAYS, +-- +2.26.3 + + +From be7466be92d779cfbece418d4de33191ae52ab4a Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Wed, 24 Mar 2021 16:06:53 +0100 +Subject: [PATCH 5/6] import the copy-file-range module from gnulib + +--- + aclocal.m4 | 1 + + lib/config.hin | 3 +++ + lib/copy-file-range.c | 33 +++++++++++++++++++++++++++++++++ + lib/gnulib.mk | 10 ++++++++++ + m4/copy-file-range.m4 | 36 ++++++++++++++++++++++++++++++++++++ + m4/gnulib-comp.m4 | 8 ++++++++ + 6 files changed, 91 insertions(+) + create mode 100644 lib/copy-file-range.c + create mode 100644 m4/copy-file-range.m4 + +diff --git a/aclocal.m4 b/aclocal.m4 +index 713f7c5..09a7ea8 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -1163,6 +1163,7 @@ m4_include([m4/closedir.m4]) + m4_include([m4/codeset.m4]) + m4_include([m4/config-h.m4]) + m4_include([m4/configmake.m4]) ++m4_include([m4/copy-file-range.m4]) + m4_include([m4/ctype.m4]) + m4_include([m4/cycle-check.m4]) + m4_include([m4/d-ino.m4]) +diff --git a/lib/config.hin b/lib/config.hin +index 9769c39..bf9f9f8 100644 +--- a/lib/config.hin ++++ b/lib/config.hin +@@ -370,6 +370,9 @@ + /* Define to 1 when the gnulib module connect should be tested. */ + #undef GNULIB_TEST_CONNECT + ++/* Define to 1 when the gnulib module copy-file-range should be tested. */ ++#undef GNULIB_TEST_COPY_FILE_RANGE ++ + /* Define to 1 when the gnulib module dirfd should be tested. */ + #undef GNULIB_TEST_DIRFD + +diff --git a/lib/copy-file-range.c b/lib/copy-file-range.c +new file mode 100644 +index 0000000..069f144 +--- /dev/null ++++ b/lib/copy-file-range.c +@@ -0,0 +1,33 @@ ++/* Stub for copy_file_range ++ Copyright 2019-2020 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 . */ ++ ++#include ++ ++#include ++ ++#include ++ ++ssize_t ++copy_file_range (int infd, off_t *pinoff, ++ int outfd, off_t *poutoff, ++ size_t length, unsigned int flags) ++{ ++ /* There is little need to emulate copy_file_range with read+write, ++ since programs that use copy_file_range must fall back on ++ read+write anyway. */ ++ errno = ENOSYS; ++ return -1; ++} +diff --git a/lib/gnulib.mk b/lib/gnulib.mk +index b3633b8..86829f3 100644 +--- a/lib/gnulib.mk ++++ b/lib/gnulib.mk +@@ -65,6 +65,7 @@ + # closeout \ + # config-h \ + # configmake \ ++# copy-file-range \ + # crypto/md5 \ + # crypto/sha1 \ + # crypto/sha256 \ +@@ -800,6 +801,15 @@ CLEANFILES += lib/configmake.h lib/configmake.h-t + + ## end gnulib module configmake + ++## begin gnulib module copy-file-range ++ ++ ++EXTRA_DIST += lib/copy-file-range.c ++ ++EXTRA_lib_libcoreutils_a_SOURCES += lib/copy-file-range.c ++ ++## end gnulib module copy-file-range ++ + ## begin gnulib module count-leading-zeros + + lib_libcoreutils_a_SOURCES += lib/count-leading-zeros.c +diff --git a/m4/copy-file-range.m4 b/m4/copy-file-range.m4 +new file mode 100644 +index 0000000..5c5a274 +--- /dev/null ++++ b/m4/copy-file-range.m4 +@@ -0,0 +1,36 @@ ++# copy-file-range.m4 ++dnl Copyright 2019-2020 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. ++ ++AC_DEFUN([gl_FUNC_COPY_FILE_RANGE], ++[ ++ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) ++ ++ dnl Persuade glibc to declare copy_file_range. ++ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) ++ ++ dnl Use AC_LINK_IFELSE, rather than AC_CHECK_FUNCS or a variant, ++ dnl since we don't want AC_CHECK_FUNCS's checks for glibc stubs. ++ dnl Programs that use copy_file_range must fall back on read+write ++ dnl anyway, and there's little point to substituting the Gnulib stub ++ dnl for a glibc stub. ++ AC_CACHE_CHECK([for copy_file_range], [gl_cv_func_copy_file_range], ++ [AC_LINK_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#include ++ ]], ++ [[ssize_t (*func) (int, off_t *, int, off_t, size_t, unsigned) ++ = copy_file_range; ++ return func (0, 0, 0, 0, 0, 0) & 127; ++ ]]) ++ ], ++ [gl_cv_func_copy_file_range=yes], ++ [gl_cv_func_copy_file_range=no]) ++ ]) ++ ++ if test "$gl_cv_func_copy_file_range" != yes; then ++ HAVE_COPY_FILE_RANGE=0 ++ fi ++]) +diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 +index dead90e..953e7f0 100644 +--- a/m4/gnulib-comp.m4 ++++ b/m4/gnulib-comp.m4 +@@ -129,6 +129,7 @@ AC_DEFUN([gl_EARLY], + # Code from module configmake: + # Code from module connect: + # Code from module connect-tests: ++ # Code from module copy-file-range: + # Code from module count-leading-zeros: + # Code from module count-leading-zeros-tests: + # Code from module crypto/af_alg: +@@ -977,6 +978,11 @@ AC_DEFUN([gl_INIT], + gl_DIRENT_MODULE_INDICATOR([closedir]) + gl_CONFIG_H + gl_CONFIGMAKE_PREP ++ gl_FUNC_COPY_FILE_RANGE ++ if test $HAVE_COPY_FILE_RANGE = 0; then ++ AC_LIBOBJ([copy-file-range]) ++ fi ++ gl_UNISTD_MODULE_INDICATOR([copy-file-range]) + gl_AF_ALG + AC_DEFINE([GL_COMPILE_CRYPTO_STREAM], 1, [Compile Gnulib crypto stream ops.]) + AC_REQUIRE([AC_C_RESTRICT]) +@@ -2746,6 +2752,7 @@ AC_DEFUN([gl_FILE_LIST], [ + lib/closeout.c + lib/closeout.h + lib/copy-acl.c ++ lib/copy-file-range.c + lib/count-leading-zeros.c + lib/count-leading-zeros.h + lib/creat-safer.c +@@ -3438,6 +3445,7 @@ AC_DEFUN([gl_FILE_LIST], [ + m4/codeset.m4 + m4/config-h.m4 + m4/configmake.m4 ++ m4/copy-file-range.m4 + m4/ctype.m4 + m4/cycle-check.m4 + m4/d-ino.m4 +-- +2.26.3 + + +From 48370c95bcf7c25ce021fbd2145062d3d29ae6d5 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 25 Jun 2020 17:34:23 -0700 +Subject: [PATCH 6/6] cp: use copy_file_range if available + +* NEWS: Mention this. +* bootstrap.conf (gnulib_modules): Add copy-file-range. +* src/copy.c (sparse_copy): Try copy_file_range if not +looking for holes. + +Upstream-commit: 4b04a0c3b792d27909670a81d21f2a3b3e0ea563 +Signed-off-by: Kamil Dudka +--- + bootstrap.conf | 1 + + src/copy.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 41 insertions(+) + +diff --git a/bootstrap.conf b/bootstrap.conf +index 2a342c1..7d53e28 100644 +--- a/bootstrap.conf ++++ b/bootstrap.conf +@@ -54,6 +54,7 @@ gnulib_modules=" + closeout + config-h + configmake ++ copy-file-range + crypto/md5 + crypto/sha1 + crypto/sha256 +diff --git a/src/copy.c b/src/copy.c +index d88f8cf..4050f69 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -265,6 +265,46 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + { + *last_write_made_hole = false; + *total_n_read = 0; ++ ++ /* If not looking for holes, use copy_file_range if available. */ ++ if (!hole_size) ++ while (max_n_read) ++ { ++ /* Copy at most COPY_MAX bytes at a time; this is min ++ (PTRDIFF_MAX, SIZE_MAX) truncated to a value that is ++ surely aligned well. */ ++ ssize_t ssize_max = TYPE_MAXIMUM (ssize_t); ++ ptrdiff_t copy_max = MIN (ssize_max, SIZE_MAX) >> 30 << 30; ++ ssize_t n_copied = copy_file_range (src_fd, NULL, dest_fd, NULL, ++ MIN (max_n_read, copy_max), 0); ++ if (n_copied == 0) ++ { ++ /* copy_file_range incorrectly returns 0 when reading from ++ the proc file system on the Linux kernel through at ++ least 5.6.19 (2020), so fall back on 'read' if the ++ input file seems empty. */ ++ if (*total_n_read == 0) ++ break; ++ return true; ++ } ++ if (n_copied < 0) ++ { ++ if (errno == ENOSYS || errno == EINVAL ++ || errno == EBADF || errno == EXDEV) ++ break; ++ if (errno == EINTR) ++ n_copied = 0; ++ else ++ { ++ error (0, errno, _("error copying %s to %s"), ++ quoteaf_n (0, src_name), quoteaf_n (1, dst_name)); ++ return false; ++ } ++ } ++ max_n_read -= n_copied; ++ *total_n_read += n_copied; ++ } ++ + bool make_hole = false; + off_t psize = 0; + +-- +2.26.3 + diff --git a/coreutils.spec b/coreutils.spec index 83c0e52..3f99ffb 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 19%{?dist} +Release: 20%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -43,6 +43,9 @@ Patch9: coreutils-8.32-ls-scontext-crash.patch # stat: add support for the exfat file system (#1921427) Patch10: coreutils-8.32-stat-exfat.patch +# cp: use copy_file_range if available +Patch11: coreutils-8.32-cp-file-range.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -300,6 +303,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Mar 24 2021 Kamil Dudka - 8.32-20 +- cp: use copy_file_range if available + * Thu Feb 18 2021 Kamil Dudka - 8.32-19 - stat: add support for the exfat file system (#1921427) From e3402b5fd42f8f4003712ae6ea032b96ee569873 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 26 Mar 2021 14:00:02 +0100 Subject: [PATCH 438/523] Resolves: #1938695 - hostname,ln: fix memory leaks detected by Coverity --- coreutils-8.32-mem-leaks.patch | 186 +++++++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-mem-leaks.patch diff --git a/coreutils-8.32-mem-leaks.patch b/coreutils-8.32-mem-leaks.patch new file mode 100644 index 0000000..78a90fc --- /dev/null +++ b/coreutils-8.32-mem-leaks.patch @@ -0,0 +1,186 @@ +From be77b4ab7cb68fd2daf9de90bd75d844392788ac Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Thu, 25 Mar 2021 11:57:56 +0100 +Subject: [PATCH 1/4] ln: fix memory leaks in do_link + +* src/ln.c (do_link): Free memory allocated by convert_abs_rel +on all code paths (Bug#47373). + +Upstream-commit: 6e98f67758260579d7d44ea5f2df4c82d28c9f58 +Signed-off-by: Kamil Dudka +--- + src/ln.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/src/ln.c b/src/ln.c +index ffa278e..9b52602 100644 +--- a/src/ln.c ++++ b/src/ln.c +@@ -229,14 +229,14 @@ do_link (char const *source, int destdir_fd, char const *dest_base, + if (errno != ENOENT) + { + error (0, errno, _("failed to access %s"), quoteaf (dest)); +- return false; ++ goto fail; + } + force = false; + } + else if (S_ISDIR (dest_stats.st_mode)) + { + error (0, 0, _("%s: cannot overwrite directory"), quotef (dest)); +- return false; ++ goto fail; + } + else if (seen_file (dest_set, dest, &dest_stats)) + { +@@ -245,7 +245,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, + error (0, 0, + _("will not overwrite just-created %s with %s"), + quoteaf_n (0, dest), quoteaf_n (1, source)); +- return false; ++ goto fail; + } + else + { +@@ -274,7 +274,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, + { + error (0, 0, _("%s and %s are the same file"), + quoteaf_n (0, source), quoteaf_n (1, dest)); +- return false; ++ goto fail; + } + } + +@@ -285,7 +285,10 @@ do_link (char const *source, int destdir_fd, char const *dest_base, + fprintf (stderr, _("%s: replace %s? "), + program_name, quoteaf (dest)); + if (!yesno ()) +- return true; ++ { ++ free(rel_source); ++ return true; ++ } + } + + if (backup_type != no_backups) +@@ -304,7 +307,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, + { + error (0, rename_errno, _("cannot backup %s"), + quoteaf (dest)); +- return false; ++ goto fail; + } + force = false; + } +@@ -397,6 +400,10 @@ do_link (char const *source, int destdir_fd, char const *dest_base, + free (backup_base); + free (rel_source); + return link_errno <= 0; ++ ++fail: ++ free (rel_source); ++ return false; + } + + void +-- +2.26.3 + + +From c051578e69bd8acf8f8a469566ae34e855345532 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 25 Mar 2021 09:15:50 -0700 +Subject: [PATCH 2/4] maint: indenting + +* src/ln.c: Fix indenting. + +Upstream-commit: 8980b7c898046d899646da01c296fd15f0cced21 +Signed-off-by: Kamil Dudka +--- + src/ln.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/ln.c b/src/ln.c +index 9b52602..8881d6a 100644 +--- a/src/ln.c ++++ b/src/ln.c +@@ -286,7 +286,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, + program_name, quoteaf (dest)); + if (!yesno ()) + { +- free(rel_source); ++ free (rel_source); + return true; + } + } +@@ -304,7 +304,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, + free (backup_base); + backup_base = NULL; + if (rename_errno != ENOENT) +- { ++ { + error (0, rename_errno, _("cannot backup %s"), + quoteaf (dest)); + goto fail; +-- +2.26.3 + + +From 0d6a4afe5bee0e397fb2fc3b205a29b32a69af9d Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 25 Mar 2021 09:16:36 -0700 +Subject: [PATCH 3/4] hostname: use puts + +* src/hostname.c (main): Prefer puts to printf "%s\n". + +Upstream-commit: c7a588ac3632aae21642d4d568497177950d36bf +Signed-off-by: Kamil Dudka +--- + src/hostname.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/hostname.c b/src/hostname.c +index 0b5c0cf..62cc98c 100644 +--- a/src/hostname.c ++++ b/src/hostname.c +@@ -103,7 +103,7 @@ main (int argc, char **argv) + hostname = xgethostname (); + if (hostname == NULL) + die (EXIT_FAILURE, errno, _("cannot determine hostname")); +- printf ("%s\n", hostname); ++ puts (hostname); + } + + if (optind + 1 < argc) +-- +2.26.3 + + +From 19c98d2080251edbaad9fb271aa10ad34f953500 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Thu, 25 Mar 2021 11:20:18 -0700 +Subject: [PATCH 4/4] hostname: pacify valgrind + +* src/hostname.c (main) [IF_LINT]: Free hostname (Bug#47384). + +Upstream-commit: 4698e284f37844bc9b9f63f00eb556ccaaed5030 +Signed-off-by: Kamil Dudka +--- + src/hostname.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/hostname.c b/src/hostname.c +index 62cc98c..7210248 100644 +--- a/src/hostname.c ++++ b/src/hostname.c +@@ -104,6 +104,7 @@ main (int argc, char **argv) + if (hostname == NULL) + die (EXIT_FAILURE, errno, _("cannot determine hostname")); + puts (hostname); ++ IF_LINT (free (hostname)); + } + + if (optind + 1 < argc) +-- +2.26.3 + diff --git a/coreutils.spec b/coreutils.spec index 3f99ffb..113d46f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 20%{?dist} +Release: 21%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -46,6 +46,9 @@ Patch10: coreutils-8.32-stat-exfat.patch # cp: use copy_file_range if available Patch11: coreutils-8.32-cp-file-range.patch +# hostname,ln: fix memory leaks detected by Coverity +Patch12: coreutils-8.32-mem-leaks.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -303,6 +306,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Mar 26 2021 Kamil Dudka - 8.32-21 +- hostname,ln: fix memory leaks detected by Coverity + * Wed Mar 24 2021 Kamil Dudka - 8.32-20 - cp: use copy_file_range if available From 32fb61705f91361ceae3838445ed8e704ed0079d Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 9 Apr 2021 09:09:59 +0200 Subject: [PATCH 439/523] Related: #1938695 - utimens: fix confusing arg type in internal func --- coreutils-8.32-coverity-utimens.patch | 52 +++++++++++++++++++++++++++ coreutils.spec | 8 ++++- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-coverity-utimens.patch diff --git a/coreutils-8.32-coverity-utimens.patch b/coreutils-8.32-coverity-utimens.patch new file mode 100644 index 0000000..5bbbb6e --- /dev/null +++ b/coreutils-8.32-coverity-utimens.patch @@ -0,0 +1,52 @@ +From 51b9a8ba0974d262e0b0f81a2078b3c7907b25ed Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Wed, 7 Apr 2021 17:29:59 -0700 +Subject: [PATCH] utimens: fix confusing arg type in internal func +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Although the old code was technically correct, this was accidental +and it understandably confused Coverity. Reported by Ondrej Dubaj in: +https://lists.gnu.org/r/bug-tar/2021-04/msg00000.html +* lib/utimens.c (update_timespec): Change arg type from ‘struct +timespec *[2]’ (pointer to array of 2 pointers to timespecs) to +‘struct timespec **’ (pointer to pointer to the first timespec in +an array of 2 timespecs). Although the old code happened to be +technically correct, it was misleading and confused Coverity. +And though the type ‘struct timespec (**)[2]’ (pointer to pointer +to array of 2 timespecs) would perhaps be more technically +correct, it would be almost as confusing and would require changes +elsewhere in this file; let’s quit while we’re ahead. + +Upstream-commit: a3a946f670718d0dee5a7425ad5ac0a29fb46ea1 +Signed-off-by: Kamil Dudka +--- + lib/utimens.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/utimens.c b/lib/utimens.c +index 3f53942..ea8c672 100644 +--- a/lib/utimens.c ++++ b/lib/utimens.c +@@ -123,14 +123,14 @@ validate_timespec (struct timespec timespec[2]) + return result + (utime_omit_count == 1); + } + +-/* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat +- buffer STATBUF to obtain the current timestamps of the file. If ++/* Normalize any UTIME_NOW or UTIME_OMIT values in (*TS)[0] and (*TS)[1], ++ using STATBUF to obtain the current timestamps of the file. If + both times are UTIME_NOW, set *TS to NULL (as this can avoid some + permissions issues). If both times are UTIME_OMIT, return true + (nothing further beyond the prior collection of STATBUF is + necessary); otherwise return false. */ + static bool +-update_timespec (struct stat const *statbuf, struct timespec *ts[2]) ++update_timespec (struct stat const *statbuf, struct timespec **ts) + { + struct timespec *timespec = *ts; + if (timespec[0].tv_nsec == UTIME_OMIT +-- +2.26.3 + diff --git a/coreutils.spec b/coreutils.spec index 113d46f..740f896 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 21%{?dist} +Release: 22%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -49,6 +49,9 @@ Patch11: coreutils-8.32-cp-file-range.patch # hostname,ln: fix memory leaks detected by Coverity Patch12: coreutils-8.32-mem-leaks.patch +# utimens: fix confusing arg type in internal func +Patch13: coreutils-8.32-coverity-utimens.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -306,6 +309,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Apr 09 2021 Kamil Dudka - 8.32-22 +- utimens: fix confusing arg type in internal func + * Fri Mar 26 2021 Kamil Dudka - 8.32-21 - hostname,ln: fix memory leaks detected by Coverity From e680748e283662cbf953ccb4715561cfb5d11589 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Sat, 10 Apr 2021 18:29:16 +0200 Subject: [PATCH 440/523] Related: #1830318 - drop the last use of ncurses no longer needed We do not install or maintain /etc/DIR_COLORS.256color any more. --- coreutils-colorls.csh | 5 ----- coreutils-colorls.sh | 4 ---- coreutils.spec | 2 +- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/coreutils-colorls.csh b/coreutils-colorls.csh index 8312dc9..66ec2fa 100755 --- a/coreutils-colorls.csh +++ b/coreutils-colorls.csh @@ -15,11 +15,6 @@ alias l. 'ls -d .*' set COLORS=/etc/DIR_COLORS if ($?TERM) then - if ( -e "/etc/DIR_COLORS.256color" && -e "/usr/bin/tput" ) then - if ( "`/usr/bin/tput colors`" == "256" ) then - set COLORS=/etc/DIR_COLORS.256color - endif - endif if ( -e "/etc/DIR_COLORS.$TERM" ) then set COLORS="/etc/DIR_COLORS.$TERM" endif diff --git a/coreutils-colorls.sh b/coreutils-colorls.sh index ac92268..5162f1e 100755 --- a/coreutils-colorls.sh +++ b/coreutils-colorls.sh @@ -22,10 +22,6 @@ if [ -z "$USER_LS_COLORS" ]; then [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.$TERM" ] && \ COLORS="/etc/DIR_COLORS.$TERM" - [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS.256color" ] && \ - [ "x`/usr/bin/tty -s && /usr/bin/tput colors 2>/dev/null`" = "x256" ] && \ - COLORS="/etc/DIR_COLORS.256color" - [ -z "$COLORS" ] && [ -e "/etc/DIR_COLORS" ] && \ COLORS="/etc/DIR_COLORS" diff --git a/coreutils.spec b/coreutils.spec index 740f896..10aad52 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -162,7 +162,6 @@ Obsoletes: %{name} < 8.24-100 # info doc refers to "Specifying the Time Zone" from glibc-doc (#959597) Recommends: glibc-doc -Recommends: ncurses Summary: coreutils common optional components %description common Optional though recommended components, @@ -310,6 +309,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Fri Apr 09 2021 Kamil Dudka - 8.32-22 +- drop the last use of ncurses no longer needed (#1830318) - utimens: fix confusing arg type in internal func * Fri Mar 26 2021 Kamil Dudka - 8.32-21 From e4decc268839f72e6e4fad313a8a62d3dd5317b2 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Sat, 10 Apr 2021 18:31:54 +0200 Subject: [PATCH 441/523] Resolves: #1947850 - weaken the dependency on glibc-doc ... to reduce minimal installations --- coreutils.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 10aad52..82926cd 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -160,7 +160,7 @@ packaged as a single multicall binary. Obsoletes: %{name} < 8.24-100 # info doc refers to "Specifying the Time Zone" from glibc-doc (#959597) -Recommends: glibc-doc +Suggests: glibc-doc Summary: coreutils common optional components %description common @@ -309,6 +309,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Fri Apr 09 2021 Kamil Dudka - 8.32-22 +- weaken the dependency on glibc-doc to reduce minimal installations - drop the last use of ncurses no longer needed (#1830318) - utimens: fix confusing arg type in internal func From 56555a47f2d5d40be97523d2ea98724474314bf0 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 27 Apr 2021 10:35:48 +0200 Subject: [PATCH 442/523] Resolves: #1953669 - copy: do not refuse to copy a swap file --- coreutils-8.32-copy-swap.patch | 32 ++++++++++++++++++++++++++++++++ coreutils.spec | 8 +++++++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-copy-swap.patch diff --git a/coreutils-8.32-copy-swap.patch b/coreutils-8.32-copy-swap.patch new file mode 100644 index 0000000..acbcf1b --- /dev/null +++ b/coreutils-8.32-copy-swap.patch @@ -0,0 +1,32 @@ +From f9936f7d2db6edd423b9d6327e2b284d86b6a1f5 Mon Sep 17 00:00:00 2001 +From: Zorro Lang +Date: Mon, 26 Apr 2021 17:25:18 +0200 +Subject: [PATCH] copy: do not refuse to copy a swap file + +* src/copy.c (sparse_copy): Fallback to read() if copy_file_range() +fails with ETXTBSY. Otherwise it would be impossible to copy files +that are being used as swap. This used to work before introducing +the support for copy_file_range() in coreutils. (Bug#48036) + +Upstream-commit: 785478013b416cde50794be35475c0c4fdbb48b4 +Signed-off-by: Kamil Dudka +--- + src/copy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/copy.c b/src/copy.c +index 4050f69..1798bb7 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -290,7 +290,7 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + if (n_copied < 0) + { + if (errno == ENOSYS || errno == EINVAL +- || errno == EBADF || errno == EXDEV) ++ || errno == EBADF || errno == EXDEV || errno == ETXTBSY) + break; + if (errno == EINTR) + n_copied = 0; +-- +2.30.2 + diff --git a/coreutils.spec b/coreutils.spec index 82926cd..a846f2d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 22%{?dist} +Release: 23%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -52,6 +52,9 @@ Patch12: coreutils-8.32-mem-leaks.patch # utimens: fix confusing arg type in internal func Patch13: coreutils-8.32-coverity-utimens.patch +# copy: do not refuse to copy a swap file +Patch14: coreutils-8.32-copy-swap.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -308,6 +311,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Apr 27 2021 Kamil Dudka - 8.32-23 +- copy: do not refuse to copy a swap file + * Fri Apr 09 2021 Kamil Dudka - 8.32-22 - weaken the dependency on glibc-doc to reduce minimal installations - drop the last use of ncurses no longer needed (#1830318) From 3a336cf37e1ded55f6c9c835ea527074a4e876e0 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 3 May 2021 12:31:07 +0200 Subject: [PATCH 443/523] Related: #1953669 - copy: ensure we enforce --reflink=never --- coreutils-8.32-cp-file-range.patch | 118 +++++++++++++++++++++++++++-- coreutils.spec | 5 +- 2 files changed, 116 insertions(+), 7 deletions(-) diff --git a/coreutils-8.32-cp-file-range.patch b/coreutils-8.32-cp-file-range.patch index 8d84040..79543cf 100644 --- a/coreutils-8.32-cp-file-range.patch +++ b/coreutils-8.32-cp-file-range.patch @@ -1,7 +1,7 @@ From 5f2dac18054d9d9b3d84e7fba8c2a6e750d2c245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Wed, 1 Apr 2020 12:51:34 +0100 -Subject: [PATCH 1/6] cp: ensure --attributes-only doesn't remove files +Subject: [PATCH 1/7] cp: ensure --attributes-only doesn't remove files * src/copy.c (copy_internal): Ensure we don't unlink the destination unless explicitly requested. @@ -77,7 +77,7 @@ index 59ce641..14fc844 100755 From c728747b06e71894c96d1f27434f2484af992c75 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 23 Jun 2020 19:18:04 -0700 -Subject: [PATCH 2/6] cp: refactor extent_copy +Subject: [PATCH 2/7] cp: refactor extent_copy * src/copy.c (extent_copy): New arg SCAN, replacing REQUIRE_NORMAL_COPY. All callers changed. @@ -320,7 +320,7 @@ index 54601ce..f694f91 100644 From ed7ff81de507bef46991f4caac550f41ab65e3ed Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 24 Jun 2020 17:05:20 -0700 -Subject: [PATCH 3/6] cp: avoid copy_reg goto +Subject: [PATCH 3/7] cp: avoid copy_reg goto * src/copy.c (copy_reg): Redo to avoid label and goto. @@ -390,7 +390,7 @@ index f694f91..b382cfa 100644 From 5631bded3a385ca0bbd77456b50767fe5580240c Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 25 Jun 2020 16:31:44 -0700 -Subject: [PATCH 4/6] cp: use SEEK_DATA/SEEK_HOLE if available +Subject: [PATCH 4/7] cp: use SEEK_DATA/SEEK_HOLE if available If it works, prefer lseek with SEEK_DATA and SEEK_HOLE to FIEMAP, as lseek is simpler and more portable (will be in next POSIX). @@ -701,7 +701,7 @@ index b382cfa..d88f8cf 100644 From be7466be92d779cfbece418d4de33191ae52ab4a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 24 Mar 2021 16:06:53 +0100 -Subject: [PATCH 5/6] import the copy-file-range module from gnulib +Subject: [PATCH 5/7] import the copy-file-range module from gnulib --- aclocal.m4 | 1 + @@ -896,7 +896,7 @@ index dead90e..953e7f0 100644 From 48370c95bcf7c25ce021fbd2145062d3d29ae6d5 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 25 Jun 2020 17:34:23 -0700 -Subject: [PATCH 6/6] cp: use copy_file_range if available +Subject: [PATCH 6/7] cp: use copy_file_range if available * NEWS: Mention this. * bootstrap.conf (gnulib_modules): Add copy-file-range. @@ -976,3 +976,109 @@ index d88f8cf..4050f69 100644 -- 2.26.3 + +From cd7c7a6b5ad89ef0a61722552d532901fc1bed05 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Sun, 2 May 2021 21:27:17 +0100 +Subject: [PATCH 7/7] copy: ensure we enforce --reflink=never + +* src/copy.c (sparse_copy): Don't use copy_file_range() +with --reflink=never as copy_file_range() may implicitly +use acceleration techniques like reflinking. +(extent_copy): Pass through whether we allow reflinking. +(lseek_copy): Likewise. +Fixes https://bugs.gnu.org/48164 + +Upstream-commit: ea9af99234031ab8d5169c8a669434e2a6b4f864 +Signed-off-by: Kamil Dudka +--- + src/copy.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/src/copy.c b/src/copy.c +index 4050f69..0337538 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -258,7 +258,7 @@ create_hole (int fd, char const *name, bool punch_holes, off_t size) + bytes read. */ + static bool + sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, +- size_t hole_size, bool punch_holes, ++ size_t hole_size, bool punch_holes, bool allow_reflink, + char const *src_name, char const *dst_name, + uintmax_t max_n_read, off_t *total_n_read, + bool *last_write_made_hole) +@@ -266,8 +266,9 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + *last_write_made_hole = false; + *total_n_read = 0; + +- /* If not looking for holes, use copy_file_range if available. */ +- if (!hole_size) ++ /* If not looking for holes, use copy_file_range if available, ++ but don't use if reflink disallowed as that may be implicit. */ ++ if ((! hole_size) && allow_reflink) + while (max_n_read) + { + /* Copy at most COPY_MAX bytes at a time; this is min +@@ -466,6 +467,7 @@ static bool + extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + size_t hole_size, off_t src_total_size, + enum Sparse_type sparse_mode, ++ bool allow_reflink, + char const *src_name, char const *dst_name, + struct extent_scan *scan) + { +@@ -579,8 +581,8 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + + if ( ! sparse_copy (src_fd, dest_fd, buf, buf_size, + sparse_mode == SPARSE_ALWAYS ? hole_size: 0, +- true, src_name, dst_name, ext_len, &n_read, +- &read_hole)) ++ true, allow_reflink, src_name, dst_name, ++ ext_len, &n_read, &read_hole)) + goto fail; + + dest_pos = ext_start + n_read; +@@ -655,6 +657,7 @@ static bool + lseek_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + size_t hole_size, off_t ext_start, off_t src_total_size, + enum Sparse_type sparse_mode, ++ bool allow_reflink, + char const *src_name, char const *dst_name) + { + off_t last_ext_start = 0; +@@ -729,8 +732,8 @@ lseek_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + bool read_hole; + if ( ! sparse_copy (src_fd, dest_fd, buf, buf_size, + sparse_mode == SPARSE_NEVER ? 0 : hole_size, +- true, src_name, dst_name, ext_len, &n_read, +- &read_hole)) ++ true, allow_reflink, src_name, dst_name, ++ ext_len, &n_read, &read_hole)) + return false; + + dest_pos = ext_start + n_read; +@@ -1527,17 +1530,20 @@ copy_reg (char const *src_name, char const *dst_name, + ? extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, + src_open_sb.st_size, + make_holes ? x->sparse_mode : SPARSE_NEVER, ++ x->reflink_mode != REFLINK_NEVER, + src_name, dst_name, &scan_inference.extent_scan) + #ifdef SEEK_HOLE + : scantype == LSEEK_SCANTYPE + ? lseek_copy (source_desc, dest_desc, buf, buf_size, hole_size, + scan_inference.ext_start, src_open_sb.st_size, + make_holes ? x->sparse_mode : SPARSE_NEVER, ++ x->reflink_mode != REFLINK_NEVER, + src_name, dst_name) + #endif + : sparse_copy (source_desc, dest_desc, buf, buf_size, + make_holes ? hole_size : 0, + x->sparse_mode == SPARSE_ALWAYS, ++ x->reflink_mode != REFLINK_NEVER, + src_name, dst_name, UINTMAX_MAX, &n_read, + &wrote_hole_at_eof))) + { +-- +2.30.2 + diff --git a/coreutils.spec b/coreutils.spec index a846f2d..111cd25 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 23%{?dist} +Release: 24%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -311,6 +311,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon May 03 2021 Kamil Dudka - 8.32-24 +- copy: ensure we enforce --reflink=never + * Tue Apr 27 2021 Kamil Dudka - 8.32-23 - copy: do not refuse to copy a swap file From ce3b866d196892822f73da7b6a0d266906efe67b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 3 May 2021 14:02:39 +0200 Subject: [PATCH 444/523] changelog: forgot to mention public bug #1956080 --- coreutils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 111cd25..ace4b8c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -312,7 +312,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Mon May 03 2021 Kamil Dudka - 8.32-24 -- copy: ensure we enforce --reflink=never +- copy: ensure we enforce --reflink=never (#1956080) * Tue Apr 27 2021 Kamil Dudka - 8.32-23 - copy: do not refuse to copy a swap file From 18d8c0abc1470a40eed88f7946c66af99bc13fa3 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 17 May 2021 16:31:09 +0200 Subject: [PATCH 445/523] Related: #1953669 - embed coreutils-8.32-copy-swap.patch ... into coreutils-8.32-cp-file-range.patch It is confusing when 1 patch out of 8 from the same patchset is kept separately. --- coreutils-8.32-copy-swap.patch | 32 ------------------- coreutils-8.32-cp-file-range.patch | 49 +++++++++++++++++++++++++----- coreutils.spec | 3 -- 3 files changed, 41 insertions(+), 43 deletions(-) delete mode 100644 coreutils-8.32-copy-swap.patch diff --git a/coreutils-8.32-copy-swap.patch b/coreutils-8.32-copy-swap.patch deleted file mode 100644 index acbcf1b..0000000 --- a/coreutils-8.32-copy-swap.patch +++ /dev/null @@ -1,32 +0,0 @@ -From f9936f7d2db6edd423b9d6327e2b284d86b6a1f5 Mon Sep 17 00:00:00 2001 -From: Zorro Lang -Date: Mon, 26 Apr 2021 17:25:18 +0200 -Subject: [PATCH] copy: do not refuse to copy a swap file - -* src/copy.c (sparse_copy): Fallback to read() if copy_file_range() -fails with ETXTBSY. Otherwise it would be impossible to copy files -that are being used as swap. This used to work before introducing -the support for copy_file_range() in coreutils. (Bug#48036) - -Upstream-commit: 785478013b416cde50794be35475c0c4fdbb48b4 -Signed-off-by: Kamil Dudka ---- - src/copy.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/copy.c b/src/copy.c -index 4050f69..1798bb7 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -290,7 +290,7 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - if (n_copied < 0) - { - if (errno == ENOSYS || errno == EINVAL -- || errno == EBADF || errno == EXDEV) -+ || errno == EBADF || errno == EXDEV || errno == ETXTBSY) - break; - if (errno == EINTR) - n_copied = 0; --- -2.30.2 - diff --git a/coreutils-8.32-cp-file-range.patch b/coreutils-8.32-cp-file-range.patch index 79543cf..6efdf52 100644 --- a/coreutils-8.32-cp-file-range.patch +++ b/coreutils-8.32-cp-file-range.patch @@ -1,7 +1,7 @@ From 5f2dac18054d9d9b3d84e7fba8c2a6e750d2c245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Wed, 1 Apr 2020 12:51:34 +0100 -Subject: [PATCH 1/7] cp: ensure --attributes-only doesn't remove files +Subject: [PATCH 1/8] cp: ensure --attributes-only doesn't remove files * src/copy.c (copy_internal): Ensure we don't unlink the destination unless explicitly requested. @@ -77,7 +77,7 @@ index 59ce641..14fc844 100755 From c728747b06e71894c96d1f27434f2484af992c75 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 23 Jun 2020 19:18:04 -0700 -Subject: [PATCH 2/7] cp: refactor extent_copy +Subject: [PATCH 2/8] cp: refactor extent_copy * src/copy.c (extent_copy): New arg SCAN, replacing REQUIRE_NORMAL_COPY. All callers changed. @@ -320,7 +320,7 @@ index 54601ce..f694f91 100644 From ed7ff81de507bef46991f4caac550f41ab65e3ed Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 24 Jun 2020 17:05:20 -0700 -Subject: [PATCH 3/7] cp: avoid copy_reg goto +Subject: [PATCH 3/8] cp: avoid copy_reg goto * src/copy.c (copy_reg): Redo to avoid label and goto. @@ -390,7 +390,7 @@ index f694f91..b382cfa 100644 From 5631bded3a385ca0bbd77456b50767fe5580240c Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 25 Jun 2020 16:31:44 -0700 -Subject: [PATCH 4/7] cp: use SEEK_DATA/SEEK_HOLE if available +Subject: [PATCH 4/8] cp: use SEEK_DATA/SEEK_HOLE if available If it works, prefer lseek with SEEK_DATA and SEEK_HOLE to FIEMAP, as lseek is simpler and more portable (will be in next POSIX). @@ -701,7 +701,7 @@ index b382cfa..d88f8cf 100644 From be7466be92d779cfbece418d4de33191ae52ab4a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 24 Mar 2021 16:06:53 +0100 -Subject: [PATCH 5/7] import the copy-file-range module from gnulib +Subject: [PATCH 5/8] import the copy-file-range module from gnulib --- aclocal.m4 | 1 + @@ -718,7 +718,7 @@ diff --git a/aclocal.m4 b/aclocal.m4 index 713f7c5..09a7ea8 100644 --- a/aclocal.m4 +++ b/aclocal.m4 -@@ -1163,6 +1163,7 @@ m4_include([m4/closedir.m4]) +@@ -1165,6 +1165,7 @@ m4_include([m4/closedir.m4]) m4_include([m4/codeset.m4]) m4_include([m4/config-h.m4]) m4_include([m4/configmake.m4]) @@ -896,7 +896,7 @@ index dead90e..953e7f0 100644 From 48370c95bcf7c25ce021fbd2145062d3d29ae6d5 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 25 Jun 2020 17:34:23 -0700 -Subject: [PATCH 6/7] cp: use copy_file_range if available +Subject: [PATCH 6/8] cp: use copy_file_range if available * NEWS: Mention this. * bootstrap.conf (gnulib_modules): Add copy-file-range. @@ -977,10 +977,43 @@ index d88f8cf..4050f69 100644 2.26.3 +From 23ea1ba463d33e268f35847059e637a5935e4581 Mon Sep 17 00:00:00 2001 +From: Zorro Lang +Date: Mon, 26 Apr 2021 17:25:18 +0200 +Subject: [PATCH 7/8] copy: do not refuse to copy a swap file + +* src/copy.c (sparse_copy): Fallback to read() if copy_file_range() +fails with ETXTBSY. Otherwise it would be impossible to copy files +that are being used as swap. This used to work before introducing +the support for copy_file_range() in coreutils. (Bug#48036) + +Upstream-commit: 785478013b416cde50794be35475c0c4fdbb48b4 +Signed-off-by: Kamil Dudka +--- + src/copy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/copy.c b/src/copy.c +index 4050f69..1798bb7 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -290,7 +290,7 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + if (n_copied < 0) + { + if (errno == ENOSYS || errno == EINVAL +- || errno == EBADF || errno == EXDEV) ++ || errno == EBADF || errno == EXDEV || errno == ETXTBSY) + break; + if (errno == EINTR) + n_copied = 0; +-- +2.31.1 + + From cd7c7a6b5ad89ef0a61722552d532901fc1bed05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Sun, 2 May 2021 21:27:17 +0100 -Subject: [PATCH 7/7] copy: ensure we enforce --reflink=never +Subject: [PATCH 8/8] copy: ensure we enforce --reflink=never * src/copy.c (sparse_copy): Don't use copy_file_range() with --reflink=never as copy_file_range() may implicitly diff --git a/coreutils.spec b/coreutils.spec index ace4b8c..cfc8663 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -52,9 +52,6 @@ Patch12: coreutils-8.32-mem-leaks.patch # utimens: fix confusing arg type in internal func Patch13: coreutils-8.32-coverity-utimens.patch -# copy: do not refuse to copy a swap file -Patch14: coreutils-8.32-copy-swap.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch From 9666248b728f3d28dcd8c58d39f03fda154feaa8 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 17 May 2021 16:37:11 +0200 Subject: [PATCH 446/523] Resolves: #1953669 - cp: pick additional copy_file_range()-related fixes ... from upstream --- coreutils-8.32-cp-file-range.patch | 238 ++++++++++++++++++++++++++++- coreutils.spec | 5 +- 2 files changed, 234 insertions(+), 9 deletions(-) diff --git a/coreutils-8.32-cp-file-range.patch b/coreutils-8.32-cp-file-range.patch index 6efdf52..6d3f651 100644 --- a/coreutils-8.32-cp-file-range.patch +++ b/coreutils-8.32-cp-file-range.patch @@ -1,7 +1,7 @@ From 5f2dac18054d9d9b3d84e7fba8c2a6e750d2c245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Wed, 1 Apr 2020 12:51:34 +0100 -Subject: [PATCH 1/8] cp: ensure --attributes-only doesn't remove files +Subject: [PATCH 01/12] cp: ensure --attributes-only doesn't remove files * src/copy.c (copy_internal): Ensure we don't unlink the destination unless explicitly requested. @@ -77,7 +77,7 @@ index 59ce641..14fc844 100755 From c728747b06e71894c96d1f27434f2484af992c75 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 23 Jun 2020 19:18:04 -0700 -Subject: [PATCH 2/8] cp: refactor extent_copy +Subject: [PATCH 02/12] cp: refactor extent_copy * src/copy.c (extent_copy): New arg SCAN, replacing REQUIRE_NORMAL_COPY. All callers changed. @@ -320,7 +320,7 @@ index 54601ce..f694f91 100644 From ed7ff81de507bef46991f4caac550f41ab65e3ed Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 24 Jun 2020 17:05:20 -0700 -Subject: [PATCH 3/8] cp: avoid copy_reg goto +Subject: [PATCH 03/12] cp: avoid copy_reg goto * src/copy.c (copy_reg): Redo to avoid label and goto. @@ -390,7 +390,7 @@ index f694f91..b382cfa 100644 From 5631bded3a385ca0bbd77456b50767fe5580240c Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 25 Jun 2020 16:31:44 -0700 -Subject: [PATCH 4/8] cp: use SEEK_DATA/SEEK_HOLE if available +Subject: [PATCH 04/12] cp: use SEEK_DATA/SEEK_HOLE if available If it works, prefer lseek with SEEK_DATA and SEEK_HOLE to FIEMAP, as lseek is simpler and more portable (will be in next POSIX). @@ -701,7 +701,7 @@ index b382cfa..d88f8cf 100644 From be7466be92d779cfbece418d4de33191ae52ab4a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 24 Mar 2021 16:06:53 +0100 -Subject: [PATCH 5/8] import the copy-file-range module from gnulib +Subject: [PATCH 05/12] import the copy-file-range module from gnulib --- aclocal.m4 | 1 + @@ -896,7 +896,7 @@ index dead90e..953e7f0 100644 From 48370c95bcf7c25ce021fbd2145062d3d29ae6d5 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 25 Jun 2020 17:34:23 -0700 -Subject: [PATCH 6/8] cp: use copy_file_range if available +Subject: [PATCH 06/12] cp: use copy_file_range if available * NEWS: Mention this. * bootstrap.conf (gnulib_modules): Add copy-file-range. @@ -980,7 +980,7 @@ index d88f8cf..4050f69 100644 From 23ea1ba463d33e268f35847059e637a5935e4581 Mon Sep 17 00:00:00 2001 From: Zorro Lang Date: Mon, 26 Apr 2021 17:25:18 +0200 -Subject: [PATCH 7/8] copy: do not refuse to copy a swap file +Subject: [PATCH 07/12] copy: do not refuse to copy a swap file * src/copy.c (sparse_copy): Fallback to read() if copy_file_range() fails with ETXTBSY. Otherwise it would be impossible to copy files @@ -1013,7 +1013,7 @@ index 4050f69..1798bb7 100644 From cd7c7a6b5ad89ef0a61722552d532901fc1bed05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Sun, 2 May 2021 21:27:17 +0100 -Subject: [PATCH 8/8] copy: ensure we enforce --reflink=never +Subject: [PATCH 08/12] copy: ensure we enforce --reflink=never * src/copy.c (sparse_copy): Don't use copy_file_range() with --reflink=never as copy_file_range() may implicitly @@ -1115,3 +1115,225 @@ index 4050f69..0337538 100644 -- 2.30.2 + +From 7978f1de88dcdb17b67db9268038930e9c71154f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Sat, 8 May 2021 17:18:54 +0100 +Subject: [PATCH 09/12] copy: handle ENOTSUP from copy_file_range() + +* src/copy.c (sparse_copy): Ensure we fall back to +a standard copy if copy_file_range() returns ENOTSUP. +This generally is best checked when checking ENOSYS, +but it also seems to be a practical concern on Centos 7, +as a quick search gave https://bugzilla.redhat.com/1840284 + +Upstream-commit: 8ec0d1799e19a079b8a661c6bb69f6c58e52f1aa +Signed-off-by: Kamil Dudka +--- + src/copy.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/copy.c b/src/copy.c +index 9977193..e3977cd 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -290,8 +290,9 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + } + if (n_copied < 0) + { +- if (errno == ENOSYS || errno == EINVAL +- || errno == EBADF || errno == EXDEV || errno == ETXTBSY) ++ if (errno == ENOSYS || is_ENOTSUP (errno) ++ || errno == EINVAL || errno == EBADF ++ || errno == EXDEV || errno == ETXTBSY) + break; + if (errno == EINTR) + n_copied = 0; +-- +2.31.1 + + +From d8d3edbfc13ff13c185f23436209b788f906aa41 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Sun, 9 May 2021 21:55:22 +0100 +Subject: [PATCH 10/12] copy: handle EOPNOTSUPP from SEEK_DATA + +* src/copy.c (infer_scantype): Ensure we don't error out +if SEEK_DATA returns EOPNOTSUPP, on systems where this value +is distinct from ENOTSUP. Generally both of these should be checked. + +Upstream-commit: 017877bd088284d515753d78b81ca6e6a88c1350 +Signed-off-by: Kamil Dudka +--- + src/copy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/copy.c b/src/copy.c +index e3977cd..de8030d 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -1246,7 +1246,7 @@ infer_scantype (int fd, struct stat const *sb, + scan_inference->ext_start = lseek (fd, 0, SEEK_DATA); + if (0 <= scan_inference->ext_start) + return LSEEK_SCANTYPE; +- else if (errno != EINVAL && errno != ENOTSUP) ++ else if (errno != EINVAL && !is_ENOTSUP (errno)) + return errno == ENXIO ? LSEEK_SCANTYPE : ERROR_SCANTYPE; + #endif + +-- +2.31.1 + + +From 1daf8c0fc9a5766c22b7ea84bea8c88c86a0c495 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Sat, 8 May 2021 19:23:20 +0100 +Subject: [PATCH 11/12] copy: handle system security config issues with + copy_file_range() + +* src/copy.c (sparse_copy): Upon EPERM from copy_file_range(), +fall back to a standard copy, which will give a more accurate +error as to whether the issue is with the source or destination. +Also this will avoid the issue where seccomp or apparmor are +not configured to handle copy_file_range(), in which case +the fall back standard copy would succeed without issue. +This specific issue with seccomp was noticed for example in: +https://github.com/golang/go/issues/40900 + +Upstream-commit: 2e66e1732fced7af20fa76c60e636d39a1767d48 +Signed-off-by: Kamil Dudka +--- + src/copy.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/copy.c b/src/copy.c +index de8030d..62eec7b 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -294,6 +294,15 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + || errno == EINVAL || errno == EBADF + || errno == EXDEV || errno == ETXTBSY) + break; ++ ++ /* copy_file_range might not be enabled in seccomp filters, ++ so retry with a standard copy. EPERM can also occur ++ for immutable files, but that would only be in the edge case ++ where the file is made immutable after creating/truncating, ++ in which case the (more accurate) error is still shown. */ ++ if (errno == EPERM && *total_n_read == 0) ++ break; ++ + if (errno == EINTR) + n_copied = 0; + else +-- +2.31.1 + + +From 42c9e598f61ba6bc27a615e39e40023a676a523b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Wed, 12 May 2021 23:47:38 +0100 +Subject: [PATCH 12/12] copy: disallow copy_file_range() on Linux kernels + before 5.3 + +copy_file_range() before Linux kernel release 5.3 had many issues, +as described at https://lwn.net/Articles/789527/, which was +referenced from https://lwn.net/Articles/846403/; a more general +article discussing the generality of copy_file_range(). +Linux kernel 5.3 was released in September 2019, which is new enough +that we need to actively avoid older kernels. + +* src/copy.c (functional_copy_file_range): A new function +that returns false for Linux kernels before version 5.3. +(sparse_copy): Call this new function to gate use of +copy_file_range(). + +Upstream-commit: ba5e6885d2c255648cddb87b4e795659c1990374 +Signed-off-by: Kamil Dudka +--- + src/copy.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 45 insertions(+), 2 deletions(-) + +diff --git a/src/copy.c b/src/copy.c +index 62eec7b..2e1699b 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + + #if HAVE_HURD_H +@@ -64,6 +65,7 @@ + #include "write-any-file.h" + #include "areadlink.h" + #include "yesno.h" ++#include "xstrtol.h" + #include "selinux.h" + + #if USE_XATTR +@@ -244,6 +246,47 @@ create_hole (int fd, char const *name, bool punch_holes, off_t size) + return true; + } + ++/* copy_file_range() before Linux kernel release 5.3 had many issues, ++ as described at https://lwn.net/Articles/789527/, ++ so return FALSE for Linux kernels earlier than that. ++ This function can be removed when such kernels (released before Sep 2019) ++ are no longer a consideration. */ ++ ++static bool ++functional_copy_file_range (void) ++{ ++#ifdef __linux__ ++ static int version_allowed = -1; ++ ++ if (version_allowed == -1) ++ version_allowed = 0; ++ else ++ return version_allowed; ++ ++ struct utsname name; ++ if (uname (&name) == -1) ++ return version_allowed; ++ ++ char *p = name.release; ++ uintmax_t ver[2] = {0, 0}; ++ size_t iver = 0; ++ ++ do ++ { ++ strtol_error err = xstrtoumax (p, &p, 10, &ver[iver], NULL); ++ if (err != LONGINT_OK || *p++ != '.') ++ break; ++ } ++ while (++iver < ARRAY_CARDINALITY (ver)); ++ ++ version_allowed = (ver[0] > 5 || (ver[0] == 5 && ver[1] >= 3)); ++ ++ return version_allowed; ++#else ++ return true; ++#endif ++ ++} + + /* Copy the regular file open on SRC_FD/SRC_NAME to DST_FD/DST_NAME, + honoring the MAKE_HOLES setting and using the BUF_SIZE-byte buffer +@@ -266,9 +309,9 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, + *last_write_made_hole = false; + *total_n_read = 0; + +- /* If not looking for holes, use copy_file_range if available, ++ /* If not looking for holes, use copy_file_range if functional, + but don't use if reflink disallowed as that may be implicit. */ +- if ((! hole_size) && allow_reflink) ++ if ((! hole_size) && allow_reflink && functional_copy_file_range ()) + while (max_n_read) + { + /* Copy at most COPY_MAX bytes at a time; this is min +-- +2.31.1 + diff --git a/coreutils.spec b/coreutils.spec index cfc8663..0ed250a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 24%{?dist} +Release: 26%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -308,6 +308,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon May 17 2021 Kamil Dudka - 8.32-26 +- cp: pick additional copy_file_range()-related fixes from upstream + * Mon May 03 2021 Kamil Dudka - 8.32-24 - copy: ensure we enforce --reflink=never (#1956080) From d21fd8df0dbbfbea42fe652eecd2db289af2de22 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 17 May 2021 16:50:51 +0200 Subject: [PATCH 447/523] Related: #1953669 - fix false positives in the upstrem test-suite --- coreutils-8.32-tests-false-positives.patch | 99 ++++++++++++++++++++++ coreutils.spec | 3 + 2 files changed, 102 insertions(+) create mode 100644 coreutils-8.32-tests-false-positives.patch diff --git a/coreutils-8.32-tests-false-positives.patch b/coreutils-8.32-tests-false-positives.patch new file mode 100644 index 0000000..0b0a301 --- /dev/null +++ b/coreutils-8.32-tests-false-positives.patch @@ -0,0 +1,99 @@ +From fc6318841f008dadc1e7c93e539f10d24aa83e90 Mon Sep 17 00:00:00 2001 +From: Bernhard Voelker +Date: Wed, 21 Apr 2021 00:12:00 +0200 +Subject: [PATCH 1/2] tests: fix FP in ls/stat-free-color.sh + +On newer systems like Fedora 34 and openSUSE Tumbleweed, ls(1) calls +newfstatat(STDOUT_FILENO, ...), but only when there is something to +output. + +* tests/ls/stat-free-color.sh: Add -a option to the reference invocation +of ls, thus enforcing something gets output. + +Upstream-commit: b7091093bb6505c33279f9bc940b2e94763a6e5d +Signed-off-by: Kamil Dudka +--- + tests/ls/stat-free-color.sh | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/tests/ls/stat-free-color.sh b/tests/ls/stat-free-color.sh +index 00942f7..87bed1c 100755 +--- a/tests/ls/stat-free-color.sh ++++ b/tests/ls/stat-free-color.sh +@@ -56,12 +56,14 @@ eval $(dircolors -b color-without-stat) + # The system may perform additional stat-like calls before main. + # Furthermore, underlying library functions may also implicitly + # add an extra stat call, e.g. opendir since glibc-2.21-360-g46f894d. +-# To avoid counting those, first get a baseline count for running +-# ls with one empty directory argument. Then, compare that with the +-# invocation under test. ++# Finally, ls(1) makes a stat call for stdout, but only in the case ++# when there is something to output. ++# To get the comparison right, first get a baseline count for running ++# 'ls -a' with one empty directory argument. Then, compare that with ++# the invocation under test. + mkdir d || framework_failure_ + +-strace -q -o log1 -e $stats ls --color=always d || fail=1 ++strace -q -o log1 -e $stats ls -a --color=always d || fail=1 + n_stat1=$(grep -vF '+++' log1 | wc -l) || framework_failure_ + + test $n_stat1 = 0 \ +-- +2.31.1 + + +From c16ca58f17a088e925c0d1c4015c48332c380a00 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Sun, 9 May 2021 23:41:00 +0100 +Subject: [PATCH 2/2] tests: fix tests/cp/sparse-2.sh false failure on some + systems + +* tests/cp/sparse-2.sh: Double check cp --sparse=always, +with dd conv=sparse, in the case where the former didn't +create a sparse file. Now that this test is being newly run +on macos, we're seeing a failure due to seek() not creating +holes on apfs unless the size is >= 16MiB. + +Upstream-commit: 6b499720fecae935dc00e236d6aefe94d9010482 +Signed-off-by: Kamil Dudka +--- + tests/cp/fiemap-2.sh | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/tests/cp/fiemap-2.sh b/tests/cp/fiemap-2.sh +index 548a376..e20ce54 100755 +--- a/tests/cp/fiemap-2.sh ++++ b/tests/cp/fiemap-2.sh +@@ -17,7 +17,7 @@ + # along with this program. If not, see . + + . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +-print_ver_ cp ++print_ver_ cp stat dd + + # Require a fiemap-enabled FS. + touch fiemap_chk # check a file rather than current dir for best coverage +@@ -46,10 +46,17 @@ dd bs=1k seek=1 of=k count=255 < /dev/zero || framework_failure_ + + # cp should detect the all-zero blocks and convert some of them to holes. + # How many it detects/converts currently depends on io_blksize. +-# Currently, on my F14/ext4 desktop, this K starts off with size 256KiB, ++# Currently, on my F14/ext4 desktop, this K file starts off with size 256KiB, + # (note that the K in the preceding test starts off with size 4KiB). + # cp from coreutils-8.9 with --sparse=always reduces the size to 32KiB. + cp --sparse=always k k2 || fail=1 +-test $(stat -c %b k2) -lt $(stat -c %b k) || fail=1 ++if test $(stat -c %b k2) -ge $(stat -c %b k); then ++ # If not sparse, then double check by creating with dd ++ # as we're not guaranteed that seek will create a hole. ++ # apfs on darwin 19.2.0 for example was seen to not to create holes < 16MiB. ++ hole_size=$(stat -c %o k2) || framework_failure_ ++ dd if=k of=k2.dd bs=$hole_size conv=sparse || framework_failure_ ++ test $(stat -c %b k2) -eq $(stat -c %b k2.dd) || fail=1 ++fi + + Exit $fail +-- +2.31.1 + diff --git a/coreutils.spec b/coreutils.spec index 0ed250a..177441c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -52,6 +52,9 @@ Patch12: coreutils-8.32-mem-leaks.patch # utimens: fix confusing arg type in internal func Patch13: coreutils-8.32-coverity-utimens.patch +# fix false positives in the upstrem test-suite (#1960792) +Patch14: coreutils-8.32-tests-false-positives.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch From a0cb772e6fba19e3fdbb4dee02d78fc6b8d20d03 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 8 Jun 2021 09:16:40 +0200 Subject: [PATCH 448/523] Resolves: #1913358 - mountlist: recognize fuse.portal as dummy file system --- coreutils-8.32-fuse-portal.patch | 38 ++++++++++++++++++++++++++++++++ coreutils.spec | 8 ++++++- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-fuse-portal.patch diff --git a/coreutils-8.32-fuse-portal.patch b/coreutils-8.32-fuse-portal.patch new file mode 100644 index 0000000..54b7975 --- /dev/null +++ b/coreutils-8.32-fuse-portal.patch @@ -0,0 +1,38 @@ +From 602fb566468d3837b7871c17a0fab1a20228d119 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 + +Upstream-commit: 9a38d499ca16f2f4304992eb1ab0894cd0b478e1 +Signed-off-by: Kamil Dudka +--- + lib/mountlist.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/mountlist.c b/lib/mountlist.c +index e0227b7..e5f6b07 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 \ +-- +2.31.1 + diff --git a/coreutils.spec b/coreutils.spec index 177441c..bac5ed5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 26%{?dist} +Release: 27%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -55,6 +55,9 @@ Patch13: coreutils-8.32-coverity-utimens.patch # fix false positives in the upstrem test-suite (#1960792) Patch14: coreutils-8.32-tests-false-positives.patch +# mountlist: recognize fuse.portal as dummy file system (#1913358) +Patch15: coreutils-8.32-fuse-portal.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -311,6 +314,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jun 08 2021 Kamil Dudka - 8.32-27 +- mountlist: recognize fuse.portal as dummy file system (#1913358) + * Mon May 17 2021 Kamil Dudka - 8.32-26 - cp: pick additional copy_file_range()-related fixes from upstream From c05b5f83e52fc7b4a5bc1239db1ba9af0d7e526a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 1 Jul 2021 14:42:14 +0200 Subject: [PATCH 449/523] Resolves: #1976935 - tail: fix stack out-of-bounds write with --follow --- coreutils-8.32-tail-use-poll.patch | 181 +++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-tail-use-poll.patch diff --git a/coreutils-8.32-tail-use-poll.patch b/coreutils-8.32-tail-use-poll.patch new file mode 100644 index 0000000..ed3a8f3 --- /dev/null +++ b/coreutils-8.32-tail-use-poll.patch @@ -0,0 +1,181 @@ +From c7a04cef4075da864a3468e63a5bb79334d8f556 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Sat, 26 Jun 2021 18:23:52 -0700 +Subject: [PATCH] tail: use poll, not select +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes an unlikely stack out-of-bounds write reported by +Stepan Broz via Kamil Dudka (Bug#49209). +* src/tail.c: Do not include . +[!_AIX]: Include poll.h. +(check_output_alive) [!_AIX]: Use poll instead of select. +(tail_forever_inotify): Likewise. Simplify logic, as there is no +need for a ‘while (len <= evbuf_off)’ loop. + +Upstream-commit: da0d448bca62c6305fc432f67e2c5ccc2da75346 +Signed-off-by: Kamil Dudka +--- + src/tail.c | 100 +++++++++++++++++++++-------------------------------- + 1 file changed, 39 insertions(+), 61 deletions(-) + +diff --git a/src/tail.c b/src/tail.c +index 1c88723..5b4f21a 100644 +--- a/src/tail.c ++++ b/src/tail.c +@@ -28,12 +28,9 @@ + #include + #include + #include +-#include ++#include + #include + #include +-#ifdef _AIX +-# include +-#endif + + #include "system.h" + #include "argmatch.h" +@@ -351,27 +348,12 @@ check_output_alive (void) + if (! monitor_output) + return; + +-#ifdef _AIX +- /* select on AIX was seen to give a readable event immediately. */ + struct pollfd pfd; + pfd.fd = STDOUT_FILENO; + pfd.events = POLLERR; + + if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR)) + die_pipe (); +-#else +- struct timeval delay; +- delay.tv_sec = delay.tv_usec = 0; +- +- fd_set rfd; +- FD_ZERO (&rfd); +- FD_SET (STDOUT_FILENO, &rfd); +- +- /* readable event on STDOUT is equivalent to POLLERR, +- and implies an error condition on output like broken pipe. */ +- if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1) +- die_pipe (); +-#endif + } + + static bool +@@ -1612,7 +1594,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files, + /* Wait for inotify events and handle them. Events on directories + ensure that watched files can be re-added when following by name. + This loop blocks on the 'safe_read' call until a new event is notified. +- But when --pid=P is specified, tail usually waits via the select. */ ++ But when --pid=P is specified, tail usually waits via poll. */ + while (1) + { + struct File_spec *fspec; +@@ -1629,54 +1611,51 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files, + return false; + } + +- /* When watching a PID, ensure that a read from WD will not block +- indefinitely. */ +- while (len <= evbuf_off) ++ if (len <= evbuf_off) + { +- struct timeval delay; /* how long to wait for file changes. */ ++ /* Poll for inotify events. When watching a PID, ensure ++ that a read from WD will not block indefinitely. ++ If MONITOR_OUTPUT, also poll for a broken output pipe. */ + +- if (pid) ++ int file_change; ++ struct pollfd pfd[2]; ++ do + { +- if (writer_is_dead) +- exit (EXIT_SUCCESS); ++ /* How many ms to wait for changes. -1 means wait forever. */ ++ int delay = -1; + +- writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM); +- +- if (writer_is_dead) +- delay.tv_sec = delay.tv_usec = 0; +- else ++ if (pid) + { +- delay.tv_sec = (time_t) sleep_interval; +- delay.tv_usec = 1000000 * (sleep_interval - delay.tv_sec); ++ if (writer_is_dead) ++ exit (EXIT_SUCCESS); ++ ++ writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM); ++ ++ if (writer_is_dead || sleep_interval <= 0) ++ delay = 0; ++ else if (sleep_interval < INT_MAX / 1000 - 1) ++ { ++ /* delay = ceil (sleep_interval * 1000), sans libm. */ ++ double ddelay = sleep_interval * 1000; ++ delay = ddelay; ++ delay += delay < ddelay; ++ } + } ++ ++ pfd[0].fd = wd; ++ pfd[0].events = POLLIN; ++ pfd[1].fd = STDOUT_FILENO; ++ pfd[1].events = pfd[1].revents = 0; ++ file_change = poll (pfd, monitor_output + 1, delay); + } ++ while (file_change == 0); + +- fd_set rfd; +- FD_ZERO (&rfd); +- FD_SET (wd, &rfd); +- if (monitor_output) +- FD_SET (STDOUT_FILENO, &rfd); +- +- int file_change = select (MAX (wd, STDOUT_FILENO) + 1, +- &rfd, NULL, NULL, pid ? &delay: NULL); +- +- if (file_change == 0) +- continue; +- else if (file_change == -1) +- die (EXIT_FAILURE, errno, +- _("error waiting for inotify and output events")); +- else if (FD_ISSET (STDOUT_FILENO, &rfd)) +- { +- /* readable event on STDOUT is equivalent to POLLERR, +- and implies an error on output like broken pipe. */ +- die_pipe (); +- } +- else +- break; +- } ++ if (file_change < 0) ++ die (EXIT_FAILURE, errno, ++ _("error waiting for inotify and output events")); ++ if (pfd[1].revents) ++ die_pipe (); + +- if (len <= evbuf_off) +- { + len = safe_read (wd, evbuf, evlen); + evbuf_off = 0; + +@@ -2437,8 +2416,7 @@ main (int argc, char **argv) + if (forever && ignore_fifo_and_pipe (F, n_files)) + { + /* If stdout is a fifo or pipe, then monitor it +- so that we exit if the reader goes away. +- Note select() on a regular file is always readable. */ ++ so that we exit if the reader goes away. */ + struct stat out_stat; + if (fstat (STDOUT_FILENO, &out_stat) < 0) + die (EXIT_FAILURE, errno, _("standard output")); +-- +2.31.1 + diff --git a/coreutils.spec b/coreutils.spec index bac5ed5..36ed736 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 27%{?dist} +Release: 28%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -58,6 +58,9 @@ Patch14: coreutils-8.32-tests-false-positives.patch # mountlist: recognize fuse.portal as dummy file system (#1913358) Patch15: coreutils-8.32-fuse-portal.patch +# tail: fix stack out-of-bounds write with --follow +Patch16: coreutils-8.32-tail-use-poll.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -314,6 +317,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jul 01 2021 Kamil Dudka - 8.32-28 +- tail: fix stack out-of-bounds write with --follow + * Tue Jun 08 2021 Kamil Dudka - 8.32-27 - mountlist: recognize fuse.portal as dummy file system (#1913358) From 1250da8dfb8809dca9eff9595e99452f445b2f22 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 7 Jul 2021 17:59:02 +0200 Subject: [PATCH 450/523] Resolves: #1979814 - df: fix duplicated remote entries due to bind mounts --- coreutils-8.32-df-duplicated-entries.patch | 72 ++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 coreutils-8.32-df-duplicated-entries.patch diff --git a/coreutils-8.32-df-duplicated-entries.patch b/coreutils-8.32-df-duplicated-entries.patch new file mode 100644 index 0000000..5d39c1e --- /dev/null +++ b/coreutils-8.32-df-duplicated-entries.patch @@ -0,0 +1,72 @@ +From 0f053de4bc3ca0cfd88a42d236881dfdddb10ee9 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Wed, 30 Jun 2021 17:53:22 +0200 +Subject: [PATCH] df: fix duplicated remote entries due to bind mounts + +As originally reported in , +df invoked without -a printed duplicated entries for NFS mounts +of bind mounts. This is a regression from commit v8.25-54-g1c17f61ef99, +which introduced the use of a hash table. + +The proposed patch makes sure that the devlist entry seen the last time +is used for comparison when eliminating duplicated mount entries. This +way it worked before introducing the hash table. + +Patch co-authored by Roberto Bergantinos. + +* src/ls.c (struct devlist): Introduce the seen_last pointer. +(devlist_for_dev): Return the devlist entry seen the last time if found. +(filter_mount_list): Remember the devlist entry seen the last time for +each hashed item. +Fixes https://bugs.gnu.org/49298 + +Upstream-commit: d6125af095c9553f38cba0696f15158f5abe4ecc +Signed-off-by: Kamil Dudka +--- + src/df.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/src/df.c b/src/df.c +index 7e01839..3e9247f 100644 +--- a/src/df.c ++++ b/src/df.c +@@ -54,6 +54,7 @@ struct devlist + dev_t dev_num; + struct mount_entry *me; + struct devlist *next; ++ struct devlist *seen_last; /* valid for hashed devlist entries only */ + }; + + /* Filled with device numbers of examined file systems to avoid +@@ -689,7 +690,13 @@ devlist_for_dev (dev_t dev) + return NULL; + struct devlist dev_entry; + dev_entry.dev_num = dev; +- return hash_lookup (devlist_table, &dev_entry); ++ ++ struct devlist *found = hash_lookup (devlist_table, &dev_entry); ++ if (found == NULL) ++ return NULL; ++ ++ /* Return the last devlist entry we have seen with this dev_num */ ++ return found->seen_last; + } + + static void +@@ -807,8 +814,12 @@ filter_mount_list (bool devices_only) + devlist->dev_num = buf.st_dev; + devlist->next = device_list; + device_list = devlist; +- if (hash_insert (devlist_table, devlist) == NULL) ++ ++ struct devlist *hash_entry = hash_insert (devlist_table, devlist); ++ if (hash_entry == NULL) + xalloc_die (); ++ /* Ensure lookups use this latest devlist. */ ++ hash_entry->seen_last = devlist; + + me = me->me_next; + } +-- +2.31.1 + diff --git a/coreutils.spec b/coreutils.spec index 36ed736..d5891df 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 28%{?dist} +Release: 30%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -61,6 +61,9 @@ Patch15: coreutils-8.32-fuse-portal.patch # tail: fix stack out-of-bounds write with --follow Patch16: coreutils-8.32-tail-use-poll.patch +# df: fix duplicated remote entries due to bind mounts (#1979814) +Patch17: coreutils-8.32-df-duplicated-entries.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -317,6 +320,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jul 07 2021 Kamil Dudka - 8.32-30 +- df: fix duplicated remote entries due to bind mounts (#1979814) + * Thu Jul 01 2021 Kamil Dudka - 8.32-28 - tail: fix stack out-of-bounds write with --follow From 9482c160b7954c7ebc7dbec18e8860e9ce99f518 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Fri, 9 Jul 2021 18:11:23 +0000 Subject: [PATCH 451/523] gpgverify source tarball The old upstream-key.gpg was probably correct some time in the past, but it's not true anymore. Luckily Savannah has a nice team gpg keyring that we can use. Signed-off-by: Stewart Smith --- coreutils-keyring.gpg | 312 ++++++++++++++++++++++++++++++++++++++++++ coreutils.spec | 8 ++ upstream-key.gpg | 123 ----------------- 3 files changed, 320 insertions(+), 123 deletions(-) create mode 100644 coreutils-keyring.gpg delete mode 100644 upstream-key.gpg diff --git a/coreutils-keyring.gpg b/coreutils-keyring.gpg new file mode 100644 index 0000000..003a885 --- /dev/null +++ b/coreutils-keyring.gpg @@ -0,0 +1,312 @@ +Release GPG keyring of coreutils group. + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBE58fE4BEADGS6VzDkx2OOQMPQedsmBtRs3S5sz9tzO51EwkS779js3Sjt96 +KlQM0SbwtbUxOFor42LRXJKUU9T/Jl3v3+onASvoHAUcuAL15WAhnY9cuQeFOvZP +/iy0I1+bV0CILrz364T6vL614obnBBdTg8ZqSZM+csRlpGwXJiuY6mkrsPLXakxA +35n/nAgQOcQPj36CuuvpCH4JKPkzklwUMqueDzXkYMNSdWmVnI+ZSfDmeiwzAbFY +tE5uGW+c3DzD98RGCLt3FLr86n24IDlaTZSsaWbTJVsur9s4sbp6rST3pspDSQYF +ShhJ5aqqEYIvPp5kXj2CZJjOFBnIkn+0aDSps+XrnZjJn/f8f9lIAg0/0JjmytHY +yopo6HFZMdtOvklmnsIuJ/fdyk7761+necYHf5dopVuv29PSu62+A/gnKGfGaqtY +AjXFfsiLp/+iTQ+LNV4hWFbFKHHZOn4G194pWl6nY1gArwQKPZ5p6uy5EXgiNPRs +C1CcuVZNJp1RiayhTI68uuI+cldBU6N7+yZKGhjDUQKjIZ3eDB8X7vsCC9S1GgvX +Hcv8mjcMcHtnoC0w0FiW35JYtAu9mY4+uQhoRPTyPHh+ufX+OdKf7q5BKCppY1r7 +HF1VRFKjSybhEwMeGBdj1EEY413/A8ynpgpHLosPT36n8HtAWUGu+TadZQARAQAB +tCFQw6FkcmFpZyBCcmFkeSA8UEBkcmFpZ0JyYWR5LmNvbT6JAjsEEwECACUCGwMG +CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheABQJOfIDXAhkBAAoJEN9v2XEwYDfZ4AEP +/jr6zmXUVhNiVCtqiHqc4jOs1OPC51iEcMUwpeaEEWHq17uMMIqz+nd8B7CAyjzw +FJIW4gtwPS3uTsXR2+KOl1VnMS5O/M9suyG5eM+fpCWkzyTC1He/1M9iaRMGY8u2 +wOjZoeY40QFN5fvL/BuC8GLBefI0rTzMaYO0WFlVWTpaemj4pL1Z4JoQdmR49H6O +qI155jfsXuv2VWjN1NoYT8w3FEugc7rdNWe4dmscU5H54JEQMuFd34X7Ja2S9YnQ +OdqO/nVQGm3te2X6ElOBoA68HyuXcEozf0KgKkcPrBEV/tjQrzn5Mc7jOgeCDDV3 +7MFwBZUi+z69jjOc85tNYf/FHRfUFnBLPC1HrOIlrraaqydPfvHBRTybTJVhXlQW +b9kqfrT1HU8UGfwP+5cwTy2WjZecxvozZakYBO4cdcmsSNE5jM8Tp7EU7ktxPXg1 +IQwZ8sEFJN6HRhRVmhK1FyR1hrwdcvfYrFmoYbyWUCW1RNuGw3RXdjXjGSl6VxzC +vrWXjeiMyLQQ7l7IneFaIPV22quPi/NVJbNeT5DqKa58kYgEVASfZVZkL7S3PJvj +fEqhw5jTi3l84AHtYNNo95UXWQQCWhpYjZ3q61satme++Eth552VAGP+JK4634mj +vVViYmWAnjs0efSN9yCOWKDKBONviW5WGZwi7MVtgF6uiQIcBBMBCAAGBQJOhIiA +AAoJEH/Z/MsAC+7uW3YP/RJlgRTkRa8t0t4oK06zg+jSMMQ3ZFsiipQEBMzJfCXy +C9pG+gU/mgcOoqnpxY6iA9ufY0dLOJYhMPsSLtrkjwMAIU54UY+WRpaTcXB+5Zma +1OoA/Oh6wcZHy61PEUkSfoiQ8vtXhzqQn7PAUbi7ds5ecn0hy8E6KKEEysFt+Say +zrINiCeO3wr6LUqUtpxdo8JGaHhdXGZsk5OMARnYlC/rzZxFKsie3+FKO7KNFoNr +edIElFKdx6b7r4CXqfK9XpZr8SaM+f3wh8mBCK4W2Re50/6inHAnTYwW0octwr0b +AtlHOY2myauBdj+19IWntZnhoKxuhVPLaEoG8j26k+LIP6h8fB8GoRh5oUarLiCk +fahDRNY/bPFtBnsE6Co5OTTy41CFkGX0JbguTpL0uPQxygIKz7x29P509fMpq5t8 +z0hcVYJ5/cXiNjFLid2JsWugKAWe5k53E7qQKR+jLSvPtZ2oOHAMUzu6hOnwDY4Q +5r+j6t81tFAlS6P4fcpVU+alUwvVNdXc6MSkfmK9ahumjYnLKy0uo242U1wuBZgN +adr6pFxKrMiC/0PVJz+ZQOZU4OUt/t4E9KpyUEasfOl1z4r+q+6dZffRbrP5CCIQ +M6A01GRbEufrcXjgYnmaDncV8JnmLbHOoZ8WF+xczywFg45ULSt0N5ZiS/BbatuO +iEYEExECAAYFAlE+Z4wACgkQFg9ft4s9SAbl2ACgqTFvvpXJzTpZrKrisKY2i9RR +dNsAoJt0xI/urG+JIn5kUJobcPsZtY62iQIcBBMBAgAGBQJRY/sdAAoJEGiHnitP +7eG+NrgP/iKO5+3ytwRYwwbtQNROUQSbLwpUN2N3S3XH9lRV2NGEx5nx9Yn0l22w +gRMbULeFk4S1Ak3mR16D/mlnfPMyVqrJotp/E4rkK5OzjIsy58vL6B4PLgut2Xlw +Clg+XklxkQDfT4m/QtLGJYOnx/AjBn6ABu2zD4FWsn7hIMdXDq9bpr9IT96iqd1P +MYogglYK5OBFIGefjf+Sut7i3vuwJcjuNdL79tIbn5yple96EOL6eoHSRv5ndcoS +mxHtmin0lVeQ1ajoBETNh/E6/yItZNtc7BKbttYF/tN0GYpQB+dcCeiXLAOJ9n/2 +ET0gAWMP+kHzdcl3mdfw+KiZOK0gak0cu6LW+3GGAXXZkFYh7I70Y7K0wYNNgy3W +rzlISbAeC0zKOzpJJ2eQWJAs13FyinUPEyKRorRSubajbhJzHa4t3SwevR9DExnG +DL23UWreDO4ElDbvT3MzMA7ifaVSLFR/Rxu/6xsK1lPs2NygmGpdDnPjJung9CTa +1yyadMi3Cfgggu5IuUaKtzW61lbD8sMXqLRoFIIkZjcQagS/ybGeKIAedCE6pqMh +MViSIVi2G/F1wVaahfhjvaj87yYPxUuHq4hHwx2RE1EjP66a1IoR4key/eZDWfHi +th2VeeaVnma12NTl1GzfaEig3mzgtB7lM50/qJ7ml+MeE5agga7oiQIcBBABCgAG +BQJVfds0AAoJECFMgsI2H9co0u0QAK+EhLBUwJJ1XfuheL8pXSJ7FxaicSPk9dKL +Fbhc2oIAItqGSAsBRncYH8jYAPSwtCq1whATbyPgoEDm5G8KQEdAZ4bA6mhXw7Nj +UgHtkbnm1bIbavM/lhZLdNi+H0ZV4w5G4e47/zMLbwK84ZhiArRdklq58200CmPB +qNnfaxRxxkJBA6Bn6Cnv0FUSRvHUlSXgOw+pZXGNFZpzi50d38L1na7iCxrfyxH1 +sS3Nhn3zTf8BCKDcCVyP8UeBP9Fb2+fYJ/f3/KN0C12Hnbqc9WsYvFSYWq6u+I8/ +GP0oQohe3Fv5S1VEHWB1feCNmvVtV50J7hukTBojERhC07Z+2T5G2aw1Cc4zxkOA +uwOBTzuij53sErn5o+hca/pJTlXz8jJ8OxSFY8FT1QGVlLAN10yl9mDsdnZb2VSn +bQdqYG/qfbdC2cm2rCrhcKFpierXURLr14UC1O7tbDmLFYXDxvQfjtj9GSo4NHrK +wlTvfHi+3x6fGyx+Auulcjt65A5kQ3mycOc5paZhTdIKhS5mFdQoKw1Sg6RPiRIy +OH5fx8ob6I7gN+bcuX3r8KCH1FcIiyZd3WsVQlI1EfnpujkFo1O2xDVpm/D9IjAO +MRqKTtnHbCjaPUrsRRysAharr47YuzQUYGaMmIJfSN3kP4U2OukYmVFSUpxrlNep +M7LGQsmdiQIzBBMBCAAdFiEEP0srMOiHNvRbOiwMIhOnPE4lafEFAlimlJcACgkQ +IhOnPE4lafEZRA//bTNw4mi9B04yacqaFlJ5f3i9v0fWnsSXNEkW5wslhbjoD8Ab +PpVNrrw7Jm0YTFNa5TtnNc7fcnHNNfsL0LbtCfdrZOTm7vZstFJrASHam7La5655 +RgvTbozSWuuYrfLyKAituRmhJyv3ntpP9K6yUAAuJjxR3ny1sn8KNIFX7g49emlC +k5eIEujcmaVJp1l8wbnf/jioKr6QeXz0cxWUUFXolR0AUt8Vy11V+qRQb9Iw902y +2gmbMun4HjYEtCtm+eY9TRD5jY7hCHTYTFEfWITnGIRDyHyLIS9a0xql3W3EyWO0 +JkHNIm1ajqbuUp4IIxoZmIxNmEmW3aS8rsuIY1P0zXjj6j+GcRX8lZJOIhieBfWk +ku6dZwwtv9wF3K1UQzFwRsERqiwj4CAwlUy4um1eLOcjx6ge7Ub67FQCihx0VEpO +jnngjQN4clth8YM5nst/+lOFsZb/k2SHqTnpdE9pFl39aij5Y7nAI6xZL8xyM+CG +9tcFMXBrmyZAmD83v0N2PyjWuLAyY2b2SSYhOXIVfonHYSfuGw27yvn6mQ0jICZu +vdeZQASYgBAohMDXOgDgKdL6g143d96tQST72RflXAxoKTbblKK0kqxZnfdRIja6 +MTLstYJUNwWQsSD7bwcY8wnTXPK5TpPtBH4q0sjkjd1ZNNAQvbbowTlZ/smJAjME +EwEKAB0WIQQSG9otSstjYWs2eg5Y4Rux5BTZrQUCWKj25AAKCRBY4Rux5BTZrY/1 +EACrnMsYUnN9sc9qhy67pAMPy5QaGsYY5IMOnQlTcjXYrBRBx0kEWhiMrX4USqRK +Yj51J5U/6MIyeFbmDMaGrUQ/Ba9GxxjOnYAUri5S7lvtuYZGYsQqQc4ORgNCSRAQ +GMiB5Q+3oWbkaoads3ezhcE+R7/0HrqgxgCRg5mzTx6up5vrkBN8kbI6BIpgoPBy +AzTOul/EIkJuBYHg4IPt9dWOmbFbJyxMJg7kNwTS65GypIEiMeQXK4VzcdB6jr2L +Ju77Ia+pWyzKpq323swdRZtM/hHrGJrwJDbdKMfWxoWf9e8cqvO5hIM2mzchHCQ8 +7OQSnb3JIsHQIPHCxeaxzMOS1smRNbYu4/yY/MRcWaNiScuoMJqI0gVWd+XIScwE +PSGyKlncV8moki4pFNkseaLw3MEQDoxqf9TtxXnEB7ZduvR/UcELUB85lVjNnoiy +GjrcagTZ4jDISxADvqBP+a02GsY28dLOk6smqPPwezbVWqV+ABPeQ+bgPd313MGl +a22s72O4/nXzzt0rNgmgEIqMy0OkgmxAUBCSfcQp88HEnk/roHsUV4iYwAks2cOp +CDriBnwjIywK+hVq0r8nuBNRQt0P/Yp75ZITffPRrOLVXvA8D7tV+kIm1GrjDbIZ +OFCNpAUCHXv/cXPeUvHsSd9hmyjGbNN3UzpxhykiDF9GWYkBHAQTAQgABgUCWKaB +cAAKCRCZRTN/KIg+y2JSCADAOSj2N7T8PriPsuGbRWehb2zvfjQ1C/IiDIWf6s7F +QuEjfg4NuWUJ2rPl2bYFey2yzSx7Ld0yNNdzSRxng6QADHUHYAneQi2WuGlyA06P +DDfFERlWRv6JZgnL9R7rWHB+RAa6DnPPgpxifABv9RR4caU+8uAP24KHRxCQXPx7 +LfB8hi+G8G3UYbuLnO5FTTuCObjjSh50h8qEt0f5y65R4kDDA40/L26POJNsHc5u +EE9rZlh0c4AqmakRSmH83+Q6XRWOtn/zPggj85ir0gsxLAezZG/OtuAyXW+rOC0L +RJDJ3JaiScUC3xewY5L/7jgg9aTcvuwxKoLBIaHOYtJQiQIzBBMBCgAdFiEE+ymK +u+HQChyPpNwfqLUfXoAyzOQFAlimepMACgkQqLUfXoAyzOQokg/8CqbMll42B+nG +VDdSNFCNjhjhKYctR/aZa2th7iDRwsTFuqSVHbywRL0XrkI0YOOJU57V56fBY7Uh +kfOKc6oeL7EXxpox8ehMToWMOcLSvi37EGMmlGLXokM9bN1gxfdFIrZr1Ji1kBYX +hvSj2Fxxi2NGRp0uy+IIOa0vB29u2xHi6GWk8U8MBMn0UcP6H053Kk6tMsMDEhF2 +rSYGpvKFSWywuFuELosSS6jG73+6pg9fMWBTDYQyWFH8YRA9AlpxWxT29gcKaftM +SBIz86Svh3PZ7qOEDVxh+yWAQTVUTVuGzUSleDDuJt75QLSt+ZERS9iezodB6EOb +AZr6canAJGmDwmjPTLwS0E3U197QW6encv3qUSA0Sb/QyAzr5007d2PzkIk6wJq3 +SxBdBRqCjAyR0VxZr2kE1Yr3t5rI3MOFsVWIKIpmkLzmCSPuUGFTvOZHlYVaTOKI +x5ge8d9smXdHjpSF0iGl45e0u1UMDsiU9dpo++ygdZWAnMI12Md5MO+K2uB4gLk8 +Njln1duZ0MQP9M6swkiIwH6jig3BkRCIAIWCNhbScBWJ79+HKD4Swk92+vTKDFRV +lrD8TQlQSbS69Lbon4/v+NwgcpHRTigY5TZZ6s4DXBUl8OIkXDs2LHeboTvm2Zu8 +gX+uWujFHr0nJmvwI1P/ih3kYoEFqLuJAjMEEwEKAB0WIQS7Pk4P+lsqogxkAaHa +lBBIg4QoJgUCWKeHnwAKCRDalBBIg4QoJv+gD/9AygNKRsaxJ19u0wyLifpGOsi2 +a6mlmwZkLLYhomeC82iV4+7EeI++QFhLc+KlRNZtkQld9rmihbcJo9UOfqTwwG/W +bzSF/Ed0GSFzPtS6HDjVPTn7qiKQoeat/e6g+VmYoK765wLknj75Tq0jPltX0/Yl +78s0ZwMI+HhirTBreOS6AVPlS8wFD4ywe64PN/YjgePAEfiIEiYICXmwGUHjPBgK +a50z9VuVs3TRLo+b00N73YDEW8tlpouhETQuL8hAYhjGgivHss0DRnuB5fNe6FgN +vwretguK3uknup1vrvVvDXOUOIdI1UksplrJvDbjYrFJB+L4VSbyGk7Kl6oSGKiz +YRF7gM4I+hpXlVWSKVxEdUlA9F6KPm3iqM5ld6K3Q6rDuppO/2BaqlBhinR+Z3bJ +TLtM1uKh0IgyGUstEkML/kjF9wJcCC+z7ZmW0k2CdA9JyMiHDQdVblxZpUI//Yge +gA4P32X1OofAFX2oXua88qehbEY2uYk3OFsR3bJwbTn40bJkxE8072IpBozYzskg +14Q/xnUxXkIL1wqLU1GPi9l+kbuh2+8yAdlz799x7De/uZhk8IwOOC5H+2oLp+vd +iRXDLKU1sDBiVFRJb9kosvUj7S/a15My1eqOSVP5Fa0GbXNw7ndvcpybMoFqbVSC +lzjlN2OgZuXYEl2PU4kCMwQQAQgAHRYhBH/Z1lK/X9LsXxORsHmPHjXLTTipBQJY +qndrAAoJEHmPHjXLTTip6uUP/j3RieBfyGnau1a4KClaXlPGHxlu9M1fFw+aRqV7 +r8ALWuQzsKlh8QlPEWhtqkty0BFXAhzRMYJd3G/5j9kaoS9NAeNpJpbZd9Gz25ZN +k+3PCkww4XthvKNY/ONwnwGuelLpIbwa25+f7Oct55tthkyM2TWXlwkRVNpeMNhk +uUkP4+gFnpvtzUTFqwYtaEtNY3UFw1CjmcA5xTGL6pIg2FKf6m1YyJJkDLpU2/pB +Ca8Mk/A9wQZ/9+M/l8goNq05vsQsp8nlh9zo1XpwWYBq3OwPQKDt4d6rAwU+zMHC +XI5MP5B2g2Pj+M5bQMNOxa4sLw71ALaCYETeHHi24Kp/ZhOWsUomwc+v7t5gApAk +6gjxbGklMWhdJuk2I+lv796J4cFI4VZpTXAygMSnnlo+GoMiqTz0C9eElZlp8z/Z +yy9g88Z8fBoAY1SmrroaxLOvlFKRG92xhd+JUh0kj72loB+Fozg5HV1OqkF6c2us +w3XCoIcht87TxmZWPTXqXdPXrStS74g59vrVyGvsNN2hG/l4dPGZSEV63Kn2eiti +Of3JPYJcy0iQpBBnhhKQwPVNgWso7NxsNsVYOUZCDeSoCFEvrdUFSr6q26IBBLcw +itnF/KEX3MyJLGr1BjDF9KqdP3+YL5Eqrq1Zn7LtyAbC2Odo4KY6vOT3SRrSkBRH +RRq4iQIcBBMBAgAGBQJYrLQ2AAoJEPaR/VwUa1eD1d8P/1qcubzbb/p4jpnrZsXW +i6+CAeJuA2f2qyBJtdVPhiz2swSHMNIlhVWh20w4892yv7Mgafj6i3Zoben088Bd +BTvCUOXRtkepCSTLTg1fTa/l3a2vNxLyK3LT6Xf8KuY5lXTH+XWn7vG/N4T6jyd2 +MQLP9VUltRkk7aNarIZvoYMd6/JVqKVhvxg42UZmcjke3PFKiHMIHBVSGBu3W1Mx +TDNgVZqTJlsqvfShwoBjPPYLBpSVZKHKgjirsDkZTS+ufpVmt2rzlujeVyC6y5f4 +subOde/pxGnTT+sMJENe/3uJxjUIy07xyXKBRnhpPxXbpTafZCcVc688er0CLRW2 +JsL9aEmEM0FV6HlnvW4ivoW1v9mSevAxe+KvgCO2cU2+HFqN/tCtxnr8rZ2HIpf8 +00cTpdvIn7wibGP9jfwMisD2Mugx28eLrZ+1sNaRLwVmroedjo9NJr2BiyPozOEN +lGX8V/RxQLaQfiHwyuKVpxA8rlx5evvtDE2d31ekVtdLXtN+GmCymnPhu1KbD5Mq ++Xk+yj1t8tdMD+SiFclz1uVeAOGpX5u7GMIsy4W8yoB5JlrwrsFot6UBaVZjAVHB +XTdMvBGsfxmimO7d0p2tBFJ1QV2lAafVhVIklCT8zXk4McqqtWxXIKWEB9dfIpbD +/A5MPtu7X91BTISC7SmRdBjViQGcBBMBCAAGBQJYrnXHAAoJEBzIdvEMrJ+JDgAM +AJyHN3j+g47bSERRxLevoRybp8/BoRfK/OjcLRxhOru4prOAiJEfNo77IbG9Quz3 +aBn7vRDh44BxXIR/NjI6kM3hsN40BBDVwfeFEFGKciV3cjCBqlqnhwt4MV6iDoGQ +1CkTm4LZQvtjQN26PAXUxxl/GO39vze3a8z3QP9BatZ+KrLOp2u7pOkwHNkY3Anb +/H0AUq0fH2Dq5omDJB8R54jlHc3/ZrLvujCVAmEuTPxK6LGl5xg4TaBtYeUgIki8 +A9iwrcFgh9OjgAuG1PFs+6RroE+nVPm/ZPDJ5l45ZHR4qQB52qp2lxf745PlSHj7 +23d6ASx/I8mDZ7bPqk2aCKXGQqkZ31b+I+Ut2ru2nEW6JAna26kgBMhNrINqLNxO +qPXjZHqZHG1amvlTAwGpAgeW5WBPvNjFn1WNPB1+9vCPTSwkWLR8dnzy46Rsfohk +RAGFtQjdccBxaikRHuUlIUI32M0WjKCP/sy5nVLQKrX9xqkOj+mSblmbS+u8cmIH +0rQiUMOhZHJhaWcgQnJhZHkgPHBicmFkeUByZWRoYXQuY29tPokCHwQwAQIACQUC +Vp+cpgIdIAAKCRDfb9lxMGA32UftD/9jYqsCfNAzb0vhDOaU1AchzaQa1pIKEjoL +6d4AMeXFSBpMi4nYJpN+rmM8DAzcbenBcSoIqecdfENp3mY+hI8mYdnMiVpldsro +EAl/SDxY6//pPd0Dnmoe6sNodBB2uwHxhQi9ubz72iWX5WiKP8+OUAj91cLMl9nK +IYfcHy3iinSRqT02JP33DGDwsHCoAMmp59g6AHnf0sjCtZEtK79MtKiKTkUdMazP +VGs81x1jCO2kvvmy0fDZxkGuyso0inae2hsaMSqqoga5lC0jQanFIXSEkLZgJglj +LmiWPO0IGHPFth/e//51atGUmpdd2ufQ/QVoxSnQKRFQ98eO/SQ75bO5vbE8dGv8 +oX9S3M9NjKOY9VnXC/JDyMXt2aMDs9tqSo22lJuT2Wq20wM5hlszxKI7c9QphnuH +yPNtszzXo1+5/UEuCNIQoe59MoscGmx7GN5WvlENaixGg7tzpZ+wdftN7BUcpJfC +gsEQurHzPEIomlszp3xraX0G84plClas13Ie8CIVM7UPbF0Cwx6XwhryjaDTkq3f ++mjQXtNJQk487q8cc9dxplslXiDqBYVngV+oDKOjrqc5PXSQm2M8EYRn9SXuFnT8 +iF5SkuFYtgOEj3KNZ04ZB1I7AQebylS2LGwWan8yWJSAs22eR9urWBVpmre6GUGZ +fo7YBdOvbLQiUMOhZHJhaWcgQnJhZHkgPHBpeGVsYmVhdEBnbnUub3JnPokCOAQT +AQIAIgUCTnyAtAIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQ32/ZcTBg +N9moHg/+Mjq/O1RnNg7kdUjRK1wOflym7itgE8kq4G55EJvLSxo6wIgd7ZKUj+cv +X+iXQpGRc3bicpNTsKcW6EjDtyg+VCSWD7qJ3EtwxVf9mN3bIqWSVwP0k8kc1N+t +p+L+/9jve+h7Hf7rXZoNo+l9h0/AIIr9YyM2r1VtiAsMNCfD/Ssvc5Yx4fZHR+2V +kOLeVb2lqdYVe7ZrXDt8qkdBHMCtxm+9jaY3pZVDFKk19NeI74Vzr9+mYn0I0OZS +0capUuG7+a+FGI1Dx2jn8uL+x4eLDdI3vvr/vGWparikBExGq1pAKWm5gBF10CDP +4nx9+5hzjPipvCuQerRnjL3FQyXa6E/GpCp4Mk7SdB4zML1CmnYUzz4n0TcV5aFi +yaMQPk5TByxzYXWUqjFJzFwmU0z8Oy/d64ZMGLyAxCly6gBc/AmXzsUhg2hJB3nG +3JRw2WmpOIeOdYn6S3onfAFT1tGo7kWNIWYxX5fT7qAHVlnAmgjz+zvfB8Hwq/B0 +FDZPzgwYX4LeRMCj9VDspoCVnaMd4rWqbH2lKUU/k0SFRt3iAqjvT6WPbJIDtEF0 +ifU2R79laaZZU5rbYWZC52AfO7NdLP+7uwxtPYyOdP/4s0HS0e8WDuykdZbTaC9K +HbIiKMW9YXQJRo6YupWJWOpFpPkvx9ttcQQ7C5s8YFjVR/96dYKJAhwEEwEIAAYF +Ak6EiIAACgkQf9n8ywAL7u5OexAAjb2+LR8Pa80t3ooladI3Q1icII1hvfb6C+KB +lzm0d8nMNqcjpPdkbppcVmjqbF3xw70uMnT9m1Y5NGMzJEZiNv6VWT3/m+VJ/aih +ci/lccUA46pL6Edxw2F/l6ftEOcPRAefNvszCQPNSVHPoQ1m+HuweVgYs9by6s6E +FFCG8BbqxpAxGxaByoq7ZtlxfMAjKHSPCJSJQTntj5dz79+K+eI8i6bMP8isPBvu +HAT8ZJ8mn2kQTEpuMIyCl6GTEigKimwq21tebB666Kv7wwS/nwCzceqyPshlrXQp +YYWoKfLd4SrC1z99//H93/IkN9dZfDJaWvMOlgO+/Tjnlr0tnVsIafnYaOA7Pb4c +QAx/tbPeiSH3QyRQw4wD2T1CaoLGPLaS4aOCjJXbNBPk+44suO0gUkU8duBwyK0p +fjFAJQJnJnVEsqWDh0KustQW3jdPvlqEe1eWmhnivXnmtvBk4U2BPkOG/NC9+r3n +xIWnrRhINWZLT85wM47WtQ2l5BRK71UKrgZDixOIbAR4H54FLa+vrwub6JjpOrQM +MYaxA/aiEv5byP38nWVvWRSaFDC+QpPyOHLnzBSoxaAHvm8bsNR+4KALcL4zyrUm ++qqQWbaOpikgBDhYyI/qteW6REZunofpkrpXZbyE+oFUxn7Vwz1ivEkiYPrEhTWr +HomA9eSIRgQTEQIABgUCUT5njAAKCRAWD1+3iz1IBic4AJ0VP0N+M3OHLK84zhnb +r7NV/OsepwCghhSEutr+LFoP8SIDFZGyGwWNZkWJAhwEEwECAAYFAlFj+x0ACgkQ +aIeeK0/t4b4XvBAAnQEaY8PFnZgegqdsNakq1gLr433h3WwQBGzba9CHhElS7VdF +c3+VnZ031zRXFFMWSFOovvQpyuRNsuGvgmvlr93+/OgP2jBZbgPFZy0B0KaTpvuE +3LD2XyPINajejIVJTMwNIuD2TTxz+zqRcdie4ExOdSmWHmjGNVCt2W7Xf2ZX18ex +FdH8jOVKtI2Hdm0YdfgNrfbcSLVgGr5MJMvaifsgGyQkPS/iDXVvLZxmSJiloupJ +ZfXrCcw5mzd8qodWwC7VJbZWIYkUBo5ir+tFAr1GuxD8D1l2U1RA3jRIgsmjd2CD +S6eKOmBXR3UVxFypOkHqfsHlST2vzTpvWGhzeQXAbo5ahjtI6m2c5mn6Tvb0V6BA +o6Fjw1id/iOWmfUSyI9byZkC7HJD/68jgvFha5eXixSo7v66MFptGl9B3sWG0gf5 +iSMbIj4EFzuBySv905kmXJ9VXnawQWalNC7n5JvJkIwAMC6bNU7aO84+9K7kh7bo +rGaBkiYfD5W09BgTipJAEgq5cVKLOGKaN47DhSszu3QAXl6Wk/VL/RTJfzWWGU13 +nZ7UY7f2uavA30mHOznAn+2v1GnMwq6ZhCQt2Y37YgDowBSR2PrFFZJOzZJhd6GN +5XWjq6A4QKZouIK19zRAA2Zsvi1TNDzUw01qGT4i+hsxPKXgEbp883D/ZMuJAhwE +EAEKAAYFAlV92zQACgkQIUyCwjYf1yjk7w/9FyPk/VEJsUYvG6Oap8Qh+bwCQRRm +vApZKVurqkMAXntN93GbCudWyPdt5igZDQf7CAHobvkUrn4fIGSMAUu6jmy7qoFf +AnGNKDMWLVYIUi5T/Sb5WCoV6DGpRJ46MjEkbplbnvQyemVsUVQLkB5GrnkO1WRV +UCk3vnsgSqrJ7B9HyLHAjsbEgm3L2OWe+1Nz9+Evg7etyVHyLLN5N2pMK3/ZMHKf +42p9SEh5x6JL9YlcxW6EseOnoy64MHDvVvnXnuUWxuTEsEpytvRXlJ7SkG+2lLcn +nbPNPY3zWfjOEI7j8RvXQJGU3FKt7NZNMGe/jdjq5nF1R5QtilRBnpVFboVmkWNN +/eiOT1Xy9/PEZKe0GUHLLh2t2ffI2du4FPKKmZ3i8sl2VTh70okKEO8zxTohs+7h +1bff6XgIFCqzpzVoiIMHLloN/Qxr27lywFzu42UISXIJBW34nSzJ1SUkaVdAdkE8 +TtXEk0xHmMkATTWTwDHoWmp0E2QcVugFpUlw85Dj1FkFNf6IvwaMw0wpE9aP9IKM +oPmKuarKzC1PUiGqm8o66Oh8I/ycQVv70VgvazeUY1f0GXV/49nT9tyj988/XKAT +T3OkyHmZIE0Q3HLlSK98bN1ddlVn35IABE7LSa9aJWN2QTOU0pw6D1Gc7pRD9smT +HAxs4LUP8TXOkGWJAjMEEwEIAB0WIQQ/Sysw6Ic29Fs6LAwiE6c8TiVp8QUCWKaU +mQAKCRAiE6c8TiVp8bY1D/476x3jkMpbkhg5wd6YlVH33kvxocqaMEdt9jIMj/Xr +xJbMZKQgHBAESf6XiIYqLRZOsIcdi8k/0goaqP+HENnUj/lK/vBii8P7Qtcct8F5 +55UEDC6GWCFaqEZn0l2qgbHjGWcwh8toq+NZ5VniPyhQErm3b7dToauqE7sOoibm +/RpkfwxNmtySd/nmmyanP4Q27AgZ7Csq8h68P1wiVTAnOuBJ28CW1z5XsJ5YRTq8 +ae/6kJs7g9eRoDtMkUr516EYmui10khYFUaZ87KjpsTXpgfiHUTtbbW73yGBdqwM +QD/s10UUCrlv7j8gJ1V8Z5NRSda8kwDyeorziwD+sfGIuxK86Q7NA5tjP9QY5tJA +m+yxgiwcv56XL12p7G82L3WRDujVm4pDs5NGFRGQNsmkb1T9DEFQMOnsBgVWH4sl +sjPsN51YNs/wHmu0jOv3CBbVDJAELxjqIroTZuT1yjG1xV5maPTqppMr3+gT16eR +SZ2nBy4ev8rYM4N4K9EEBjcbXWLNQOYeger1vz5S0bEzUuGeHY4ahMNB+dRTf1eN +UjRlhSzddlWpoNMbb1+PlYwtcTEIfh2vs2iJEbhZhuETVFye2RmBQ+MQ6oXDGEcg +fwbwrbyW0X+Z9KPIDhTRMrdXJiBui5RvQ1AxAuQ3sZglw/xySSvztqf5InRrt1lE +N4kCMwQTAQoAHRYhBBIb2i1Ky2NhazZ6DljhG7HkFNmtBQJYqPbkAAoJEFjhG7Hk +FNmt9cgP/2owqkabfUTz1Gf5BZn8cWlcZT0ePFJuXqceoyZfPj4VhwKSyRiXEu2U +LGi75TSUp1ESok6w3KG7chq2GoH2EITysqUhpcroOTAT5qjWGwf1WEP/zEYrmQb2 +ayFRBHdcoNNgRnJVd2HB7FlHF6fg5aPrM3P7o8ajYDneYSDwubajN2xnUsFV8yYv +liNV8DtFOsX2AHSf9ipsF3P5ArsjRJoMI6Z/PgZuECRiya8qzbxZoIZGgT+khcvC +SwxsX6YXmNImwhGpugUnSrjvBPdiyN4CilTOdaiEqPLwFDpFWEkByx3ewfJYfBfH +EOzTdSgtPEXJB0Xxb7ge5fpBtFunI45bPRwRIT6EM29WcYWwCp12HCTt4N2LHwu6 +h+JL3ikFucgtJsSO68h/oId7THD24ft4UpIfBR0zZ0/i+ier3SAB/gN0xE4Hpy4Q +YNcl9rkt/ApuHX2hQqcN8woUhGV9HV4n07Z6FIqs3qSj+o4w2hV5xaEqOiVoKdMC +p7DCECjR5ACmhvtLTI8ddS/2rXPK/8Kttg4e74LysK5WOSbCiX7M+GjNIuVh7aA8 +BVR7hLjQ1CRAu/c0/m6EsTEViHuNZjX4deJo/c70kWLbP5UVN9yXrJjwVXwBOz1O +XiZzzJCl+ICT2fu8K2P7nL4yqkSAuMZHz1sQxzIvLs8hjbMYbdqMiQIzBBMBCgAd +FiEE+ymKu+HQChyPpNwfqLUfXoAyzOQFAlimepUACgkQqLUfXoAyzOTxgA/7BZpk +HIlTGVobZ3drVXXLRVdydLbypAJ2d6KU37hY1xuCM1bQ36H/hQKtHBgdTVc87IvB +0iZTKfwxPHBloK4MBDl0zj0Nz+Y6OK5oaUccDCSIDyBuMnkwu+U3O94mWoftQZuB +FH9urpElmgLftknKE1PMsPT2PVEpLVKX82yXo28+aAhXjcO7W/FYQhHX5vqPZmjC +uJGS2DZJHUjF0Vem1Eh2a200+t47JfFSMRSFBm2S4Z1Bo5UUjSk83yJ66tCynJ3x +D5vhMTWJXRLhZd7DXjjPBMrp6MqDElL8tNF1w86Bk4kIwX/hMre6c0/+4b5rJBwF +mjRkAwfk/YLJPz5dfoMiTf0kqj93F86BKDnYZNQ4L0Yn1QWWKJSEf55ldmxvaxwz +ZE3NpOALdBwkG7yjhttsHIe5kpWgluxcuYTvWpX7KGIZnt1qSl+Cv0VAOY7eo2Zl +KTtpqAQeFqtCZL0tcLxj2Ce8LqViuraKGxNKi13FtpS74W4DgseXv8tnhdy0uqlP +gRQ2WCHpUhXUlU/KaXtXXmS6oRFnCzXikYXzH5ZFTHzNthg1gO5Fk3y2B+5eL71V +SHDeIpi0jTpiO3Mav6AtVlw6QRXXfn61cdF1M37k1XA5lFPb+ifkV0sF/rkFE5NL +r0NAFqcwB3CE7K0fgOidFhdnH9zi+qcfCiyMjpGJAjMEEwEKAB0WIQS7Pk4P+lsq +ogxkAaHalBBIg4QoJgUCWKeHoQAKCRDalBBIg4QoJnzFD/wNhcOyJURvQtQXcys2 +bSw93rubuZO2OUpIgs6CCcZgCKt4sES9Xv9Qt2qRdk6GBgnlsTdTfwDWEDla1NYf ++/894Kf+3dLhaiTmYkWVh3UhysE6rihKZ5SHeriNCFCyaOvflOfpGQn20TX17I04 +fLBPQ2tZLIZYELpHHr5OXDm0YiBR+1Rc7mj80cTdw2+1vNa1p2r72n2GzKz76Yl4 +BI7dWud4GAEW26yrwF3VtdGFacRcDsjSM5rR5pxREY2WGzONCCD1yuaJUqk8Q+QK +8g/2PybkAUJpzmNzWqgsn8FhPESfObl2FPuIbxIjR+N531QGeU4HcH62zJeJjCdR +XxJk+k1VRP7SIIg310q6J4WiHa6LU79BVTFEV/0gyHh8psLpySr6nJN9TAImdekd +2+BN6xdWcub6/JJTdJgg+g/VuD+2vUm9zPtcP7nnpadqen6k2pobiDfuGepa4k7s +1jdgSoyKdgntJNBEpBCCx/fQQeXlR6kcscjUP1aMa+XIgpeZhyKTWWcGfbzsf58u +YYOP2nMn1GvPvoKcW4AfbPui14eNh3m3hQ3numJKBZGLzBASJsdc10CkOJzLq448 +nhdJTp8ZLRGYl9mEbpVuHNrYQnxYe67OtGS9Nv/DlAJXR4fUiX/Yq/Z+w5zz7HMK +Pbu/XhRIZcfJWgmRkgr3DSwGdIkCMwQQAQgAHRYhBH/Z1lK/X9LsXxORsHmPHjXL +TTipBQJYqndrAAoJEHmPHjXLTTip1XkP/R2nPYovKt4/ytjOMRDfO7XSzpUn2d0g +hmKRn0MHe21n3IjBzDG+BapdTMQCOc4Ucs1UicPV2lxRD8TQa8hh1MYCp9gkZ0Hx +I9R4q8StipyPLq7B5TQJ4tsHqT4Vc8reuxRInV/2XZ6gdr412v9dsK08o9lYri59 +mv5YJaxZmdov5555oK0ieMAbIRXiSqSsONcA4ph/MPXpVRXZvmu8+IhKJZbAd0cw +iOhjTU8z0qCBcU4vYB0nxwp2AWbQG4QDpk5lTp40Tn7A1dL1XUbiXsK9h2jAF5zn +Rssb+drhNeafoqYfVRsB2ObZPhfqD9nq6isbj1ocDU1nQLOrFdYu1o9+JgMFs6F5 +NvavG7RY4RdVLlXDQuoMiX5e1PyGsBgLliy4Tz5gogKtqzm40nV0573pcEkUR7Um +rNEzEuPoC8PFr7W8lYEHx70Yhql6IZ7rGXKDQNBWLp4drmPKajhdH8xPOKn1Tocr +qdL8hkzWh6wqLcSzwhgR14/bjCZDj3AJr6bRdAAbcE1xqWt86XiJRM0upe0j/Q7E +s2eUybhUb/YPSe++llkUsePqvLGMSY2nUN1lwHST1/yI1gjJ0qTSdrHUDd/V1KkU +SY8CL122N61FoSAEy2Tk4hVNrSNEM0DUuYXaEFZFazJT5/QwfmCaE7lBFzHFRQFs +mbsPONxL6qjFiQIcBBMBAgAGBQJYrLRFAAoJEPaR/VwUa1eDkbsQAKFy6zUg6GQz +i3pSqoaWvwCh0rdQzlQJ0Rr+1k70AnGvGnPmtFpceT8AHsJkzfhH4AetZLYeuOpf +FlcMca9267VdyWgwInob8fcvAURW1ZN4qn8MvNPOBXudj5W5+8XowWmDES4qNr1/ +2Oj4IgHDlMRgUYhsql0ybYarpfZdRxxKKj3ZW4B55Qqds2mG1w40zTSeW9ErXQvJ +EYkqFsAhEme0Ii+tKP1oM/qRrHuCfKiQw8Zc99v0uU19KbdD2B8sCsBfgkIJpGny +6ne8BuNAJRDJa4JhzyRu0Aw7f+U/ewn4T+GYdzgsqnsqH6nEwEabeHUtEsChXxZp +7mu9nSww8fJUEgHuTonr/w8UcMtB7HVwhQ1/AuFxzaQx7uKkyU+uyJaElZ3LD30O +f20p9Z0v6LXpyiqxBUUytoPCsBtRi2aPQKvNmnkPbtH4P45nz0Nc7CVaWM3tvAGR +53WQMxowHcek/J3mtNVprhG1gn5V+NnF/a5cjVqGxQbs/G7lhqZXYBNeflW3mUFx +7DaO5C5KcqjJBN1h9W6a48qh0sqyIbuBFlWJFNdizV0eMi1ypsHXKSZcl7SZ7PB2 +QGMVLg6VW0RneL7zzpoaLHaey97bxeccP721rA0/6w5qCE+qlTUXgV5sZSXJkj9M +wwpVQWwqa6q/cG0G7iFCxbD+OPZ3/9jZiQGcBBMBCAAGBQJYrnXJAAoJEBzIdvEM +rJ+J7Q4MAKz8ITE6nKeltOLAJF3xHNNcvyIHFLcOF2BI4bJTinMS7hFwEM3tg8+s +fnClHe7Lu/YpJdtqJ+jz8+nZMEF9tpS49C4bA8sPDyBHVqBi75xivKDSchnogPql +jctZF6NWbOt3Bf21DqbJFnrrtg/aEDrHQIDdXZUIKM66artlELC1XmFUnzfUBYNB +vksoPD+ehG9Im4ugC5kQCGxMNDjHXGyw+DzSm5n+hyEtkjnOPq1x2uPaELrHweMZ +c06ivHndOBp3vU2EgkyuCvRebc4OLu94RSel/ANv2VRdt3ryRQrW5tqxQJhEwPLW +fWqNTmR3vZhuUrY5Bk/R6Spn+iNJE1qCUutbB89aIeT9KMV5Dl0Zes4gdK7PLnLJ +5rjEMoVvJ1Tdl4LUToKZk+7el+2jEMZpkv5jnXkeRqMZAB584wWVOA7+7pKDUGL4 +r7RJByaBz6wRFCGmSJ5DIZQ8HKSeF1ikCwUHqVDYfAWmlyR/t7ZH3ZgUT1ezi67/ +PLQrM9JPbLkCDQROfHxOARAA5hb6RwSG2oH8LMWk6rmPthWH5IBE8yw4InTPpsA8 +V7LyFlNUOH+BuHI8mTpTHk4aRfg3h8wxqw9VfnncWN/H69Y6bhgYp8XZ37esQjPr +kujaQ7QaLp9EB++96AvF+5pTvf1eBlkhprMXUolw/D3UpGnC6uXW2iCjKEjt4HGU +G/nJQum9U9fcmZJWrtKFOW8NK/DVJ3iIdh2RmR+DceBDXUJF2qL9DEQvhEDAO5uY +glC8CwYdHwbdQaWjgLyDMWjr65SQZGbYJ1e+ZxPGGpucfQR89lylNaZwIg/HkFgU +bIvGnezleSwfO93ayQ34HVtpecr14TMG/jouh85xCsbsX7znnTLtCKzti+EkWRXa +NV0D+FvaPKo4jv440vgQZajcPzD9tbYWUfylpg83URVaQqZZglg1gLPU166vkB4V +/ov6nBjQ+Z6YxJsGvgPVhfBZth8IrckFUINyH5JKAAcwPZBtKR0QfUSHW+SxHer4 +DMLHpsjO39wHO9CIk4EcbLYUJwoEYlFpcnNWNYBwjLqAWXuMA+mE2fX/+NoMY1/c +rOZ46y3dLq0zJfD+LBgORx10j1fFaAj9j36pg43DUewZSwLtBhlYJ/SExW0Rz0xU +MU+C/4EJjy7+3ycLV+M8gnJGVwp2+z1H1ESe5bH6hSgARqQ4pOfP9sbM7sNX/y17 +KMEAEQEAAYkCHwQYAQIACQUCTnx8TgIbDAAKCRDfb9lxMGA32aBIEADAGhbCehSj +Wv8SEw9gUpN+slmIDBnZ7uqQgXjWO5OnG2TrSJyPNAwfk6ESY6JeoGuiASL3EpqD +vRTVsIvDzzqhNBwVa+mi/q3lof9yNs74dmJYsH0P20+9lVzNfWATWUDA4cVYBvON +BloCK1cVvn9zqFvfjFBcRbZskcvMBVPxO2Fv4xAzX+omPDfCnweY8G7i71Z8Nnl/ +HVkSZMI9uXrtcde00oISHf5xUebJdx96dxnUCDLPUwPiIxxYN44KvIl3cnIB5qwu +BV8F2XXUtBdxZDJexqsCIoAD3rhRoWq6E2fRJKeqt/4TmxwjsJ8ZODp+ilXhqRe/ +shHttoOvbo5QBZNZMujxkqxXeu+j2E3Ry5mSiGX1SewwbT1iUppwGI15Uwhthhrc +PwbtWxxIyzPBU6awwlrTrYxNTB1n7WM99gcQctLWZpWnEaoAnEmIEcPjnM+c2NRw +UJmE/C5h9intY4fOa2a8hpUPx6UbMkfPl0bkIA2cduvQtAFKy/G/Jm4H+0trSmrD +c+o+rl7v9sMJ9wKkMUdAcqUgNP0TEHzDPbzvztcKBCLnNLoUTKNIN4eNJjMGk8Si +/OgiN1NKkuVz7I3i916mVxxlFjKEyLYU4tYYXsbB+ZJy4dTP/YWHbQulJYLgju6Z +ELphkzjc6eM3CaOZ73u4GVXotheeUabUHQ== +=drvb +-----END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/coreutils.spec b/coreutils.spec index d5891df..e4422a3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -5,6 +5,10 @@ Release: 30%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz +Source1: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig +# From https://savannah.gnu.org/project/release-gpgkeys.php?group=coreutils&download=1 +# which is linked as project keyring on https://savannah.gnu.org/projects/coreutils +Source2: coreutils-keyring.gpg Source50: supported_utils Source51: coreutils-provides.inc Source105: coreutils-colorls.sh @@ -129,6 +133,9 @@ BuildRequires: openssl-devel BuildRequires: strace BuildRequires: texinfo +# For gpg verification of source tarball +BuildRequires: gnupg2 + # test-only dependencies BuildRequires: perl-interpreter BuildRequires: perl(FileHandle) @@ -180,6 +187,7 @@ Optional though recommended components, including documentation and translations. %prep +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' %autosetup -N # will be regenerated in the build directories diff --git a/upstream-key.gpg b/upstream-key.gpg deleted file mode 100644 index dc6dc1d..0000000 --- a/upstream-key.gpg +++ /dev/null @@ -1,123 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.6 (GNU/Linux) - -mQGiBDftyYoRBACvICTt5AWe7kdbRtJ37IZ+ED5tBA/IbISfqUPO+HmL/J9JSfkV -QHbdQR5dj5mrU6BY5YOY7L4KOS6lH3AgvsZ/NhkDBraBPgnMkpDqFb7z4keCIebb -AmlcBL2VQNTo0Lczo319YoZ+UaNH53OddlBY944qBTa0AlcJuS1SgEp7pwCg+CUj -4SjVzqZh5lgPTS0bnYvF/n0D/iItZ7WAm37KW+9UjArWZD6NO+mVMNq4GWmhcSBD -uyJOZFxFQWXdFRdM9sNO7lkWYVCxpXyFzmQcBzdrAt+zx/3QadEbduGAqEKAROQU -gSDlMITWGK97/Cadn1YRSDcGKNlJX9jlJvt5Q/xh+CnJ8HTwO0PF9A5N/phFuMMB -UH0pA/0e5eIBsr2Wvxy39+nGnNv5b+5tHkGXSSHKyI7+zOdIBTtRQO7lwTG9ioKg -/yMqb9NCSf4GdyZiFJsQ+TWoSyk1bvFHt7YUOhTeii7Zgbk7Due2q+b9KzzyH/r2 -kf+fLh0lgiy/LfBhvsfO8M9dji3XDyZpBLRO6gda9M9NqzEfgbQfSmltIE1leWVy -aW5nIDxqaW1AbWV5ZXJpbmcubmV0PohGBBARAgAGBQI9TvsUAAoJENoowjp5/0R0 -NTIAn2qpRF9QVupw/gz4UN5d5MKurlOMAKDNXKfXzWClHRq5ufCdwZead3WMMYhG -BBARAgAGBQJCk1gpAAoJEIvYLm8wuUtcqlIAn0KbOC5YSkgqhfhM1uRlHnvHB74A -AJ4qbzrkw7iitd1CH1eoMoFiP5CI14hGBBARAgAGBQJDYmg2AAoJELk/YMa1xM4T -ct0AoJIkdqI6dhTUDOVwiZRxaCKVYaoNAJsG8I+OPhhRhe7ZgN5iN3xlRfkhTohG -BBARAgAGBQJECHuEAAoJEFQUZr6xLcGbUyQAnRmg070gGrZ5E4ZPJRqL/DUoB7hN -AKCj7uAIpcRdrBAQW8PKiOWcPRvxjohGBBIRAgAGBQI/bJ2IAAoJEA6nVrUUSEP1 -QXoAoJ6dMlvbJUep2l5N8G0XFmRyxTrIAJ0bn5IYu7RMxqI0vv6DHn2VgEQLeohG -BBIRAgAGBQI/vFVMAAoJENKUXDvBNlC2gtYAn1zlWvzZaC2lxRXuW7fMWpB/5uVJ -AJ9RFEFFzl8BktsnskYJUIvrx5zVL4hGBBMRAgAGBQI/UFjyAAoJEDhZwDsuI25H -z80An0G2Xm22lMc7ThGGgKeovGP0GzPIAKCHFH2aY2Dv6XOYomNB1yvW7MU0ZIhG -BBMRAgAGBQI/cfsiAAoJEA3cqjJ41SZOmcoAoKulkHQ6TUVORoSN77UYtrdCKy0I -AKC5qT7peM0Jd6I9wPLwc7Fc65xraIhGBBMRAgAGBQJAmOELAAoJEAu1FKXQbtaf -ysgAoL7Zl3BSH+/F9ouPCXkduzIywdx9AJ9OevRoJwxpER+SwSiLnw9Q7fVmcYhX -BBMRAgAXBQI66oJOBQsHCgMEAxUDAgMWAgECF4AACgkQ/dLerNMzy6HlawCg5UXJ -LGWj9P0SuJKcGm+mqKb1J2MAn3YrgB3duqFNs/yS4mvxM74TzI5miFoEExECABoF -CwcKAwQDFQMCAxYCAQIXgAIZAQUCOuqCTwAKCRD90t6s0zPLoaVVAJ0UZOyi+B+q -cNTEDSDrc3Oc1MzZrQCg0UONeu4Dv4N5ZLI6lZBMZETaCmKIXwQTEQIAFwUCOuqC -TgULBwoDBAMVAwIDFgIBAheAABIJEP3S3qzTM8uhB2VHUEcAAQHlawCg5UXJLGWj -9P0SuJKcGm+mqKb1J2MAn3YrgB3duqFNs/yS4mvxM74TzI5miGIEExECABoFCwcK -AwQDFQMCAxYCAQIXgAIZAQUCOuqCTwASCRD90t6s0zPLoQdlR1BHAAEBpVUAnRRk -7KL4H6pw1MQNIOtzc5zUzNmtAKDRQ4167gO/g3lksjqVkExkRNoKYrQfSmltIE1l -eWVyaW5nIDxtZXllcmluZ0BnbnUub3JnPohGBBARAgAGBQJCk1gsAAoJEIvYLm8w -uUtcHS0AoIO9LsaLdn6aH3fskRVZ4qhpRBXbAJ0drV2s3abBKhkhUui7kpF87MTD -+4hGBBARAgAGBQJDYmg8AAoJELk/YMa1xM4TdT4Ani/0ORxwCzqGT0+BG2thzbO7 -aFkuAKCoKP+u6WhYYOBdEcaM6T5QLN56H4hGBBARAgAGBQJECHuHAAoJEFQUZr6x -LcGbrKEAoLef0BqLLpNGhAFJKSAvWEWOiGcxAJ9w7F7MtsDoegKeQ44yYiPX5jEu -5ohGBBIRAgAGBQI/bJ2IAAoJEA6nVrUUSEP13sUAn3IWX1RWnH50v+DZKcqzCaSA -oqHbAKCVvtirU/A3FJLnuyIBv+lguddi2IhGBBIRAgAGBQI/vFVRAAoJENKUXDvB -NlC2D68AnAzm1iw0YSQ1GuPaU3lG8n72p5EBAJ4pNBP+RFWjvZSfcUYhZAFhq8CB -QYhGBBMRAgAGBQI/cfslAAoJEA3cqjJ41SZO8asAnRsJcSER+vpIIzM/et8PakIC -ZJxsAJ9LjdnHkb+Zr9YDXzKXu6OTiJvIh4hGBBMRAgAGBQJAmOEOAAoJEAu1FKXQ -btafLL8AoJask7aB+OfOQgS/kMlKXAA25Hl3AKC/3XJeRRR0ze508VcIhx7EhYVV -84heBBMRAgAeBQI/UFjBAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEP3S3qzT -M8uh8gwAoLfqQt7QgzavHlD44LxmAXovm5t0AJ4m8EQC+N9oJyODmpLbfQKNL6pq -zohmBBMRAgAeBQI/UFjBAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAABIJEP3S3qzT -M8uhB2VHUEcAAQHyDACgt+pC3tCDNq8eUPjgvGYBei+bm3QAnibwRAL432gnI4Oa -ktt9Ao0vqmrOtCFKaW0gTWV5ZXJpbmcgPG1leWVyaW5nQHBvYm94LmNvbT6IRgQQ -EQIABgUCQpNYLAAKCRCL2C5vMLlLXP7FAKCodISH72q8e30TxLwdoOh7hDjehACf -U97FCEOWICQaEI2BvOzGzn6yrO6IRgQQEQIABgUCQ2JoPAAKCRC5P2DGtcTOE0Gk -AJ43felw+/nxzJ7DVJYZ0tbASZ3BcACeNf2nXMkqkwrBZZ9DDMUGQ6tIB3GIRgQQ -EQIABgUCRAh7hwAKCRBUFGa+sS3Bm1nUAJ0foaMmGWqugETz37RZ2XpCfdQIlQCe -N50WxYPBxrGGmhhGOVbji1uhVSmIRgQSEQIABgUCP2ydiAAKCRAOp1a1FEhD9T73 -AJ4/51C6L0lHrX77DFXVJrB02yybsACgi/9TewF7HaF3x8fdMEZxsRK1HR+IRgQS -EQIABgUCP7xVUQAKCRDSlFw7wTZQtvjnAJ9FM83LyrTs2Dk/T7kOcSFTfjXqegCe -OlpOQ/sB4EtoHxrTSCy3OhToVsmIRgQTEQIABgUCP1BY+wAKCRA4WcA7LiNuR5yI -AJ9F3RsjjwtYX2rSx+j5o4+y4Dyl9wCfVR9uTBDLDP3kOaDrTT/H9XHTf6uIRgQT -EQIABgUCP3H7JQAKCRAN3KoyeNUmTv4eAJ9rCBUUXWYFUrjUayOenPULMW1BhACg -ncwdeTN+SGy8lX3zoo1vdNv+vTKIRgQTEQIABgUCQJjhDgAKCRALtRSl0G7WnyNP -AJ9Gn9yRup0zePUPMex36fX94o+i8wCggdDgtpKjzcaQ83o8VBiemFeiss+IXAQT -EQIAHAUCPjpzhwIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQ/dLerNMzy6FG5gCg -99D5pDqSRuZP2QJAT8LNiCZlRGgAn25OTXbNlHkM+gYFj0fyo+Ikj+T5iGQEExEC -ABwFAj46c4cCGwMECwcDAgMVAgMDFgIBAh4BAheAABIJEP3S3qzTM8uhB2VHUEcA -AQFG5gCg99D5pDqSRuZP2QJAT8LNiCZlRGgAn25OTXbNlHkM+gYFj0fyo+Ikj+T5 -tCJKaW0gTWV5ZXJpbmcgPG1leWVyaW5nQGFzY2VuZC5jb20+iEYEEBECAAYFAkKT -WCwACgkQi9gubzC5S1zwAQCgnPUCCl1g6eJdI5ZViACDiaaULAAAn19sIyQmkiaU -45QVcDtYuQTNSh/QiEYEEBECAAYFAkNiaDwACgkQuT9gxrXEzhP+igCfc526l8n/ -q8zVhIe9NonG+jVlrEoAnRXKebriKwmvVSdqbY8khlbJjB/ziEYEEBECAAYFAkQI -e4cACgkQVBRmvrEtwZs2owCgwzEOLdyXa2JGA/xkpBluqa8/UyMAnjZyxESMAj/A -2rUg3IvgtBmaetE4iEYEEhECAAYFAj+8VVEACgkQ0pRcO8E2ULaqIQCfQlbRoDOL -Hv+9YVxPgD8yhwFB850AnRTmAG4Z57YD92s4o1ne9sgaufmdiEYEExECAAYFAj9Q -WPsACgkQOFnAOy4jbkfOoQCgwfC1mkANwR+vv9TVlYkmoZ6wNL8An0dql+uy5ic1 -YpyKfV7g7MMuEMDwiEYEExECAAYFAj9x+yUACgkQDdyqMnjVJk6QCwCglS7PPvFR -HoOZxl7XgpVbAK6vZQgAniVxncBgSu06lmsDNHiJpiDMIZkkiEYEExECAAYFAkCY -4Q4ACgkQC7UUpdBu1p+QqwCeNzsozeUjiCFQBBiR+gCBnvZhQqgAnj4ImXyp45hs -fc3dZHP3qB1Ws5UjiFUEExECABUFAjftyYoDCwoDAxUDAgMWAgECF4AACgkQ/dLe -rNMzy6HnugCePkbs7JcEo0837WNqdoGf2WXL3vIAoK0cStFCa4zj4FV/SoG9cDZP -JOzfiF0EExECABUFAjftyYoDCwoDAxUDAgMWAgECF4AAEgkQ/dLerNMzy6EHZUdQ -RwABAee6AJ4+RuzslwSjTzftY2p2gZ/ZZcve8gCgrRxK0UJrjOPgVX9Kgb1wNk8k -7N+0IkppbSBNZXllcmluZyA8bWV5ZXJpbmdAbHVjZW50LmNvbT6IRQQTEQIABgUC -QJjhDgAKCRALtRSl0G7Wn/YLAJdAhf8twtaImmHzRT7eaUIf0b4+AJ9hRfAjWrRp -UF5cW5AzZsVwEW7Vc4hGBBARAgAGBQJCk1gsAAoJEIvYLm8wuUtceyMAoJGYrqPm -T+ThNBRLt5aIq/p3yBHmAJ0V0tEMjdIafWlY6IDZkst2VXBPFohGBBARAgAGBQJD -Ymg8AAoJELk/YMa1xM4TTxEAnAtkRTdyDNdPn5kW3HMKcQp9S02vAJ9wiBJbBeaB -jGcQ4zoafo0vw8ZMi4hGBBARAgAGBQJECHuHAAoJEFQUZr6xLcGbZi4AoK2Th3Pi -pC+CWdYDCA9qNa+uUkHsAKCHUU/oOSEqvjEHoYs22RZzVGbbVohGBBIRAgAGBQI/ -vFVRAAoJENKUXDvBNlC2qQ0An3hiEeuqRgzbuY6YLqiA9FH0GHEEAJ4j2O8AjZFq -Vc8RL32KA6nuwfJ28ohGBBMRAgAGBQI/UFj7AAoJEDhZwDsuI25HPicAoJOlcGaT -t5dvksbBg00BNCyZl8odAJ0UCIFlFzzB/x050scZKMrvquc2T4hGBBMRAgAGBQI/ -cfslAAoJEA3cqjJ41SZO5mQAoLTvGtjJxspvgEg3z3T/q6iI/FdxAJ4wgnqQjRvm -AHAWMibcDupPA10u+ohVBBMRAgAVBQI37e/HAwsKAwMVAwIDFgIBAheAAAoJEP3S -3qzTM8uh8vAAn23cUtWPdFr4wIwUNo9bsY1CUHMNAKCoHS3nayqM/WUfihcZJoOs -kQA22ohdBBMRAgAVBQI37e/HAwsKAwMVAwIDFgIBAheAABIJEP3S3qzTM8uhB2VH -UEcAAQHy8ACfbdxS1Y90WvjAjBQ2j1uxjUJQcw0AoKgdLedrKoz9ZR+KFxkmg6yR -ADbatCdKaW0gTWV5ZXJpbmcgPG1leWVyaW5nQG5hLW5ldC5vcm5sLmdvdj6IRgQQ -EQIABgUCPU77FAAKCRDaKMI6ef9EdBjQAJ41hqQaE3W2dHgN9otb7fL0n6U1YACg -kI9DvFQ1YmpLI8jdGwbDxDodAeOIRgQQEQIABgUCQpNYLAAKCRCL2C5vMLlLXMrg -AJ90LwV+nd+U4GEvzYixFvksHvtFGgCggD3NDeGXlgUhPB+nqyBq2QKfZxKIRgQQ -EQIABgUCQ2JoPAAKCRC5P2DGtcTOE4WfAJ4uxTyLyO4NCBk/IlTM0NAKLFHJgwCc -DP0YQC0oDm5uJ8/ZIkl0MUrzKXGIRgQQEQIABgUCRAh7hwAKCRBUFGa+sS3BmyTW -AJ4+X1CGNorq+Nme5tTIVskgYKH7wQCcD7UpPt2+r+NcGSYftkKk3O8R8TKIRgQS -EQIABgUCP7xVUQAKCRDSlFw7wTZQtolWAJ98yLyyC6jzrF/YG5kqeGqHSNdKtQCd -EdCDkGG09QJX8gFfZ/r8lWlflj+IRgQTEQIABgUCP1BY+wAKCRA4WcA7LiNuR4mz -AKC/1XBB9cBCs8X/KvoLLQP75q0i2QCbBb0UoVSUYgsdETzujbTwg+0HLseIRgQT -EQIABgUCP3H7JQAKCRAN3KoyeNUmTql1AJsEhcfoOC2U4JjHR6rWzqinaIxcNgCg -lmdHMQ3L8zCfNzD7lehquPy2P0eIRgQTEQIABgUCQJjhDgAKCRALtRSl0G7Wn+1r -AJ4nUVrAEtL+XBp2UU1QmVCxa7lcSwCfT8ds7xZ++aZomPK2Xvz230WnUsGIVQQT -EQIAFQUCN+3v9gMLCgMDFQMCAxYCAQIXgAAKCRD90t6s0zPLocAwAKCJ4wBEND4W -mzs6Sp47mWBsp96HRACfTH+SGkDfLqgkZ7JgEgzSDKGl4TyIXQQTEQIAFQUCN+3v -9gMLCgMDFQMCAxYCAQIXgAASCRD90t6s0zPLoQdlR1BHAAEBwDAAoInjAEQ0Phab -OzpKnjuZYGyn3odEAJ9Mf5IaQN8uqCRnsmASDNIMoaXhPLkBDQQ37cmSEAQAx3xz -BZlJikWJaiZGru3cEKYYnRFp8No2b4jhBwY9nKn8UIxuY5aQN4ka/k81wqjlC6cT -wn5R7kg2ha8eGXpwYhKGwn5MGvIxqfoj2tsQ76uluTowHA4seoavi7RGEDzm4Vpt -8Nua8krrZ2QPtLA86gkzL1QG5Bbv/o2Ldx8HHNcAAwcEAKcK2tj2X8RPgUarczXv -rdXMteeSFnI7fagbLpEfaTI2xa1ADLg5UO4M9Erz9m6k6xV6loxcBB9H5Ljm9GWf -el4T4p1lwzi3Lu5hKzIiFs+5vsy+fyEai4e5f6v9Ww3Q3Ec6UZpPZGyN+PDPlZxe -rf3ZIMogSGrrEBhprhLHReudiE4EGBECAAYFAjftyZIAEgkQ/dLerNMzy6EHZUdQ -RwABAQXiAKCilmALgD6mhccl4ISaUB5LfW74BQCgqd7wIfbV2+NKqf1Yuj75sryW -Ke4= -=zRdO ------END PGP PUBLIC KEY BLOCK----- From 37018cae6e03c5ba68b528d24983a45e025b00e3 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 21 Jul 2021 15:05:13 +0000 Subject: [PATCH 452/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering From b55ae3bd161f07c084c47e854b89707085d11039 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 21 Jul 2021 20:02:21 +0000 Subject: [PATCH 453/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index e4422a3..9a0f9e8 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 30%{?dist} +Release: 31%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -328,6 +328,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jul 21 2021 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Wed Jul 07 2021 Kamil Dudka - 8.32-30 - df: fix duplicated remote entries due to bind mounts (#1979814) From 67dacdf0ad0d1e14069441b25fe8df655aa4a572 Mon Sep 17 00:00:00 2001 From: Sahana Prasad Date: Tue, 14 Sep 2021 18:59:58 +0200 Subject: [PATCH 454/523] Rebuilt with OpenSSL 3.0.0 --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 9a0f9e8..e6349c5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 8.32 -Release: 31%{?dist} +Release: 32%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -328,6 +328,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Sep 14 2021 Sahana Prasad +- Rebuilt with OpenSSL 3.0.0 + * Wed Jul 21 2021 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild From baf6440388ad55458188f33d0f9d206dda159640 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Sun, 26 Sep 2021 18:15:09 +0200 Subject: [PATCH 455/523] new upstream release 9.0 --- coreutils-4.5.3-langinfo.patch | 2 +- coreutils-8.32-DIR_COLORS.patch | 6 +- coreutils-8.32-coverity-utimens.patch | 52 - coreutils-8.32-cp-file-range.patch | 1339 -------------------- coreutils-8.32-cp-reflink-auto.patch | 119 -- coreutils-8.32-df-duplicated-entries.patch | 72 -- coreutils-8.32-expr-unmatched-par.patch | 81 -- coreutils-8.32-fuse-portal.patch | 38 - coreutils-8.32-gnulib-perror-test.patch | 48 - coreutils-8.32-leaf-opt-xfs.patch | 164 --- coreutils-8.32-ls-removed-dir.patch | 153 --- coreutils-8.32-ls-scontext-crash.patch | 85 -- coreutils-8.32-mem-leaks.patch | 186 --- coreutils-8.32-new-fs-types.patch | 104 -- coreutils-8.32-rm-stray-skip.patch | 109 -- coreutils-8.32-split-number.patch | 100 -- coreutils-8.32-stat-exfat.patch | 32 - coreutils-8.32-tail-use-poll.patch | 181 --- coreutils-8.32-tests-false-positives.patch | 99 -- coreutils-8.32.tar.xz.sig | 16 - coreutils-8.4-mkdir-modenote.patch | 2 +- coreutils-9.0.tar.xz.sig | 16 + coreutils-df-direct.patch | 39 +- coreutils-getgrouplist.patch | 6 +- coreutils-i18n-expand-unexpand.patch | 74 +- coreutils-i18n.patch | 193 +-- coreutils-selinux.patch | 76 +- coreutils.spec | 58 +- sources | 2 +- 29 files changed, 238 insertions(+), 3214 deletions(-) delete mode 100644 coreutils-8.32-coverity-utimens.patch delete mode 100644 coreutils-8.32-cp-file-range.patch delete mode 100644 coreutils-8.32-cp-reflink-auto.patch delete mode 100644 coreutils-8.32-df-duplicated-entries.patch delete mode 100644 coreutils-8.32-expr-unmatched-par.patch delete mode 100644 coreutils-8.32-fuse-portal.patch delete mode 100644 coreutils-8.32-gnulib-perror-test.patch delete mode 100644 coreutils-8.32-leaf-opt-xfs.patch delete mode 100644 coreutils-8.32-ls-removed-dir.patch delete mode 100644 coreutils-8.32-ls-scontext-crash.patch delete mode 100644 coreutils-8.32-mem-leaks.patch delete mode 100644 coreutils-8.32-new-fs-types.patch delete mode 100644 coreutils-8.32-rm-stray-skip.patch delete mode 100644 coreutils-8.32-split-number.patch delete mode 100644 coreutils-8.32-stat-exfat.patch delete mode 100644 coreutils-8.32-tail-use-poll.patch delete mode 100644 coreutils-8.32-tests-false-positives.patch delete mode 100644 coreutils-8.32.tar.xz.sig create mode 100644 coreutils-9.0.tar.xz.sig diff --git a/coreutils-4.5.3-langinfo.patch b/coreutils-4.5.3-langinfo.patch index a8af3bd..862d9eb 100644 --- a/coreutils-4.5.3-langinfo.patch +++ b/coreutils-4.5.3-langinfo.patch @@ -2,7 +2,7 @@ diff --git a/src/date.c b/src/date.c index ddb011e..619a72b 100644 --- a/src/date.c +++ b/src/date.c -@@ -490,14 +490,7 @@ main (int argc, char **argv) +@@ -494,14 +494,7 @@ main (int argc, char **argv) format = DATE_FMT_LANGINFO (); if (! *format) { diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index 9d422f4..c43651c 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -30,7 +30,7 @@ index bd5df23..84f2417 100644 # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. TERM Eterm -@@ -58,7 +65,7 @@ DOOR 01;35 # door +@@ -59,7 +66,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -63,7 +63,7 @@ index 4316832..6402854 100644 # Below are TERM entries, which can be a glob patterns, to match # against the TERM environment variable to determine if it is colorizable. TERM Eterm -@@ -48,17 +57,17 @@ TERM xterm* +@@ -49,17 +58,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -86,7 +86,7 @@ index 4316832..6402854 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 30;41 # file with capability -@@ -67,7 +76,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +@@ -68,7 +77,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: diff --git a/coreutils-8.32-coverity-utimens.patch b/coreutils-8.32-coverity-utimens.patch deleted file mode 100644 index 5bbbb6e..0000000 --- a/coreutils-8.32-coverity-utimens.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 51b9a8ba0974d262e0b0f81a2078b3c7907b25ed Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Wed, 7 Apr 2021 17:29:59 -0700 -Subject: [PATCH] utimens: fix confusing arg type in internal func -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Although the old code was technically correct, this was accidental -and it understandably confused Coverity. Reported by Ondrej Dubaj in: -https://lists.gnu.org/r/bug-tar/2021-04/msg00000.html -* lib/utimens.c (update_timespec): Change arg type from ‘struct -timespec *[2]’ (pointer to array of 2 pointers to timespecs) to -‘struct timespec **’ (pointer to pointer to the first timespec in -an array of 2 timespecs). Although the old code happened to be -technically correct, it was misleading and confused Coverity. -And though the type ‘struct timespec (**)[2]’ (pointer to pointer -to array of 2 timespecs) would perhaps be more technically -correct, it would be almost as confusing and would require changes -elsewhere in this file; let’s quit while we’re ahead. - -Upstream-commit: a3a946f670718d0dee5a7425ad5ac0a29fb46ea1 -Signed-off-by: Kamil Dudka ---- - lib/utimens.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/lib/utimens.c b/lib/utimens.c -index 3f53942..ea8c672 100644 ---- a/lib/utimens.c -+++ b/lib/utimens.c -@@ -123,14 +123,14 @@ validate_timespec (struct timespec timespec[2]) - return result + (utime_omit_count == 1); - } - --/* Normalize any UTIME_NOW or UTIME_OMIT values in *TS, using stat -- buffer STATBUF to obtain the current timestamps of the file. If -+/* Normalize any UTIME_NOW or UTIME_OMIT values in (*TS)[0] and (*TS)[1], -+ using STATBUF to obtain the current timestamps of the file. If - both times are UTIME_NOW, set *TS to NULL (as this can avoid some - permissions issues). If both times are UTIME_OMIT, return true - (nothing further beyond the prior collection of STATBUF is - necessary); otherwise return false. */ - static bool --update_timespec (struct stat const *statbuf, struct timespec *ts[2]) -+update_timespec (struct stat const *statbuf, struct timespec **ts) - { - struct timespec *timespec = *ts; - if (timespec[0].tv_nsec == UTIME_OMIT --- -2.26.3 - diff --git a/coreutils-8.32-cp-file-range.patch b/coreutils-8.32-cp-file-range.patch deleted file mode 100644 index 6d3f651..0000000 --- a/coreutils-8.32-cp-file-range.patch +++ /dev/null @@ -1,1339 +0,0 @@ -From 5f2dac18054d9d9b3d84e7fba8c2a6e750d2c245 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 1 Apr 2020 12:51:34 +0100 -Subject: [PATCH 01/12] cp: ensure --attributes-only doesn't remove files - -* src/copy.c (copy_internal): Ensure we don't unlink the destination -unless explicitly requested. -* tests/cp/attr-existing.sh: Add test cases. -* NEWS: Mention the bug fix. -Fixes https://bugs.gnu.org/40352 - -Upstream-commit: 7b5f0fa47cd04c84975250d5b5da7c98e097e99f -Signed-off-by: Kamil Dudka ---- - src/copy.c | 9 +++++---- - tests/cp/attr-existing.sh | 21 ++++++++++++++++++--- - 2 files changed, 23 insertions(+), 7 deletions(-) - -diff --git a/src/copy.c b/src/copy.c -index 6e5efc7..54601ce 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -2211,10 +2211,11 @@ copy_internal (char const *src_name, char const *dst_name, - /* Never unlink dst_name when in move mode. */ - && ! x->move_mode - && (x->unlink_dest_before_opening -- || (x->preserve_links && 1 < dst_sb.st_nlink) -- || (x->dereference == DEREF_NEVER -- && ! S_ISREG (src_sb.st_mode)) -- )) -+ || (x->data_copy_required -+ && ((x->preserve_links && 1 < dst_sb.st_nlink) -+ || (x->dereference == DEREF_NEVER -+ && ! S_ISREG (src_sb.st_mode)))) -+ )) - { - if (unlink (dst_name) != 0 && errno != ENOENT) - { -diff --git a/tests/cp/attr-existing.sh b/tests/cp/attr-existing.sh -index 59ce641..14fc844 100755 ---- a/tests/cp/attr-existing.sh -+++ b/tests/cp/attr-existing.sh -@@ -19,11 +19,26 @@ - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ cp - --printf '1' > file1 --printf '2' > file2 --printf '2' > file2.exp -+printf '1' > file1 || framework_failure_ -+printf '2' > file2 || framework_failure_ -+printf '2' > file2.exp || framework_failure_ - - cp --attributes-only file1 file2 || fail=1 - cmp file2 file2.exp || fail=1 - -+# coreutils v8.32 and before would remove destination files -+# if hardlinked or the source was not a regular file. -+ln file2 link2 || framework_failure_ -+cp -a --attributes-only file1 file2 || fail=1 -+cmp file2 file2.exp || fail=1 -+ -+ln -s file1 sym1 || framework_failure_ -+returns_ 1 cp -a --attributes-only sym1 file2 || fail=1 -+cmp file2 file2.exp || fail=1 -+ -+# One can still force removal though -+cp -a --remove-destination --attributes-only sym1 file2 || fail=1 -+test -L file2 || fail=1 -+cmp file1 file2 || fail=1 -+ - Exit $fail --- -2.26.3 - - -From c728747b06e71894c96d1f27434f2484af992c75 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Tue, 23 Jun 2020 19:18:04 -0700 -Subject: [PATCH 02/12] cp: refactor extent_copy - -* src/copy.c (extent_copy): New arg SCAN, replacing -REQUIRE_NORMAL_COPY. All callers changed. -(enum scantype): New type. -(infer_scantype): Rename from is_probably_sparse and return -the new type. Add args FD and SCAN. All callers changed. - -Upstream-commit: 761ba28400a04ee24eefe9cd4973ec8850cd7a52 -Signed-off-by: Kamil Dudka ---- - src/copy.c | 119 +++++++++++++++++++++++++---------------------------- - 1 file changed, 55 insertions(+), 64 deletions(-) - -diff --git a/src/copy.c b/src/copy.c -index 54601ce..f694f91 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -422,9 +422,8 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - size_t hole_size, off_t src_total_size, - enum Sparse_type sparse_mode, - char const *src_name, char const *dst_name, -- bool *require_normal_copy) -+ struct extent_scan *scan) - { -- struct extent_scan scan; - off_t last_ext_start = 0; - off_t last_ext_len = 0; - -@@ -432,45 +431,25 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - We may need this at the end, for a final ftruncate. */ - off_t dest_pos = 0; - -- extent_scan_init (src_fd, &scan); -- -- *require_normal_copy = false; - bool wrote_hole_at_eof = true; -- do -+ while (true) - { -- bool ok = extent_scan_read (&scan); -- if (! ok) -- { -- if (scan.hit_final_extent) -- break; -- -- if (scan.initial_scan_failed) -- { -- *require_normal_copy = true; -- return false; -- } -- -- error (0, errno, _("%s: failed to get extents info"), -- quotef (src_name)); -- return false; -- } -- - bool empty_extent = false; -- for (unsigned int i = 0; i < scan.ei_count || empty_extent; i++) -+ for (unsigned int i = 0; i < scan->ei_count || empty_extent; i++) - { - off_t ext_start; - off_t ext_len; - off_t ext_hole_size; - -- if (i < scan.ei_count) -+ if (i < scan->ei_count) - { -- ext_start = scan.ext_info[i].ext_logical; -- ext_len = scan.ext_info[i].ext_length; -+ ext_start = scan->ext_info[i].ext_logical; -+ ext_len = scan->ext_info[i].ext_length; - } - else /* empty extent at EOF. */ - { - i--; -- ext_start = last_ext_start + scan.ext_info[i].ext_length; -+ ext_start = last_ext_start + scan->ext_info[i].ext_length; - ext_len = 0; - } - -@@ -498,7 +477,7 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - { - error (0, errno, _("cannot lseek %s"), quoteaf (src_name)); - fail: -- extent_scan_free (&scan); -+ extent_scan_free (scan); - return false; - } - -@@ -539,7 +518,7 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - /* For now, do not treat FIEMAP_EXTENT_UNWRITTEN specially, - because that (in combination with no sync) would lead to data - loss at least on XFS and ext4 when using 2.6.39-rc3 kernels. */ -- if (0 && (scan.ext_info[i].ext_flags & FIEMAP_EXTENT_UNWRITTEN)) -+ if (0 && (scan->ext_info[i].ext_flags & FIEMAP_EXTENT_UNWRITTEN)) - { - empty_extent = true; - last_ext_len = 0; -@@ -571,16 +550,23 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - extents beyond the apparent size. */ - if (dest_pos == src_total_size) - { -- scan.hit_final_extent = true; -+ scan->hit_final_extent = true; - break; - } - } - - /* Release the space allocated to scan->ext_info. */ -- extent_scan_free (&scan); -+ extent_scan_free (scan); - -+ if (scan->hit_final_extent) -+ break; -+ if (! extent_scan_read (scan) && ! scan->hit_final_extent) -+ { -+ error (0, errno, _("%s: failed to get extents info"), -+ quotef (src_name)); -+ return false; -+ } - } -- while (! scan.hit_final_extent); - - /* When the source file ends with a hole, we have to do a little more work, - since the above copied only up to and including the final extent. -@@ -1021,16 +1007,35 @@ fchmod_or_lchmod (int desc, char const *name, mode_t mode) - # define HAVE_STRUCT_STAT_ST_BLOCKS 0 - #endif - -+/* Type of scan being done on the input when looking for sparseness. */ -+enum scantype -+ { -+ /* No fancy scanning; just read and write. */ -+ PLAIN_SCANTYPE, -+ -+ /* Read and examine data looking for zero blocks; useful when -+ attempting to create sparse output. */ -+ ZERO_SCANTYPE, -+ -+ /* Extent information is available. */ -+ EXTENT_SCANTYPE -+ }; -+ - /* Use a heuristic to determine whether stat buffer SB comes from a file - with sparse blocks. If the file has fewer blocks than would normally - be needed for a file of its size, then at least one of the blocks in - the file is a hole. In that case, return true. */ --static bool --is_probably_sparse (struct stat const *sb) -+static enum scantype -+infer_scantype (int fd, struct stat const *sb, struct extent_scan *scan) - { -- return (HAVE_STRUCT_STAT_ST_BLOCKS -- && S_ISREG (sb->st_mode) -- && ST_NBLOCKS (*sb) < sb->st_size / ST_NBLOCKSIZE); -+ if (! (HAVE_STRUCT_STAT_ST_BLOCKS -+ && S_ISREG (sb->st_mode) -+ && ST_NBLOCKS (*sb) < sb->st_size / ST_NBLOCKSIZE)) -+ return PLAIN_SCANTYPE; -+ -+ extent_scan_init (fd, scan); -+ extent_scan_read (scan); -+ return scan->initial_scan_failed ? ZERO_SCANTYPE : EXTENT_SCANTYPE; - } - - -@@ -1061,6 +1066,7 @@ copy_reg (char const *src_name, char const *dst_name, - mode_t src_mode = src_sb->st_mode; - struct stat sb; - struct stat src_open_sb; -+ struct extent_scan scan; - bool return_val = true; - bool data_copy_required = x->data_copy_required; - -@@ -1260,23 +1266,13 @@ copy_reg (char const *src_name, char const *dst_name, - fdadvise (source_desc, 0, 0, FADVISE_SEQUENTIAL); - - /* Deal with sparse files. */ -- bool make_holes = false; -- bool sparse_src = is_probably_sparse (&src_open_sb); -- -- if (S_ISREG (sb.st_mode)) -- { -- /* Even with --sparse=always, try to create holes only -- if the destination is a regular file. */ -- if (x->sparse_mode == SPARSE_ALWAYS) -- make_holes = true; -- -- /* Use a heuristic to determine whether SRC_NAME contains any sparse -- blocks. If the file has fewer blocks than would normally be -- needed for a file of its size, then at least one of the blocks in -- the file is a hole. */ -- if (x->sparse_mode == SPARSE_AUTO && sparse_src) -- make_holes = true; -- } -+ enum scantype scantype = infer_scantype (source_desc, &src_open_sb, -+ &scan); -+ bool make_holes -+ = (S_ISREG (sb.st_mode) -+ && (x->sparse_mode == SPARSE_ALWAYS -+ || (x->sparse_mode == SPARSE_AUTO -+ && scantype != PLAIN_SCANTYPE))); - - /* If not making a sparse file, try to use a more-efficient - buffer size. */ -@@ -1305,10 +1301,8 @@ copy_reg (char const *src_name, char const *dst_name, - buf_alloc = xmalloc (buf_size + buf_alignment); - buf = ptr_align (buf_alloc, buf_alignment); - -- if (sparse_src) -+ if (scantype == EXTENT_SCANTYPE) - { -- bool normal_copy_required; -- - /* Perform an efficient extent-based copy, falling back to the - standard copy only if the initial extent scan fails. If the - '--sparse=never' option is specified, write all data but use -@@ -1316,14 +1310,11 @@ copy_reg (char const *src_name, char const *dst_name, - if (extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, - src_open_sb.st_size, - make_holes ? x->sparse_mode : SPARSE_NEVER, -- src_name, dst_name, &normal_copy_required)) -+ src_name, dst_name, &scan)) - goto preserve_metadata; - -- if (! normal_copy_required) -- { -- return_val = false; -- goto close_src_and_dst_desc; -- } -+ return_val = false; -+ goto close_src_and_dst_desc; - } - - off_t n_read; --- -2.26.3 - - -From ed7ff81de507bef46991f4caac550f41ab65e3ed Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Wed, 24 Jun 2020 17:05:20 -0700 -Subject: [PATCH 03/12] cp: avoid copy_reg goto - -* src/copy.c (copy_reg): Redo to avoid label and goto. - -Upstream-commit: 2fcd0f3328f5181a2986905fa5469a0152c67279 -Signed-off-by: Kamil Dudka ---- - src/copy.c | 34 +++++++++++----------------------- - 1 file changed, 11 insertions(+), 23 deletions(-) - -diff --git a/src/copy.c b/src/copy.c -index f694f91..b382cfa 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -1301,29 +1301,18 @@ copy_reg (char const *src_name, char const *dst_name, - buf_alloc = xmalloc (buf_size + buf_alignment); - buf = ptr_align (buf_alloc, buf_alignment); - -- if (scantype == EXTENT_SCANTYPE) -- { -- /* Perform an efficient extent-based copy, falling back to the -- standard copy only if the initial extent scan fails. If the -- '--sparse=never' option is specified, write all data but use -- any extents to read more efficiently. */ -- if (extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, -- src_open_sb.st_size, -- make_holes ? x->sparse_mode : SPARSE_NEVER, -- src_name, dst_name, &scan)) -- goto preserve_metadata; -- -- return_val = false; -- goto close_src_and_dst_desc; -- } -- - off_t n_read; -- bool wrote_hole_at_eof; -- if (! sparse_copy (source_desc, dest_desc, buf, buf_size, -- make_holes ? hole_size : 0, -- x->sparse_mode == SPARSE_ALWAYS, src_name, dst_name, -- UINTMAX_MAX, &n_read, -- &wrote_hole_at_eof)) -+ bool wrote_hole_at_eof = false; -+ if (! (scantype == EXTENT_SCANTYPE -+ ? extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, -+ src_open_sb.st_size, -+ make_holes ? x->sparse_mode : SPARSE_NEVER, -+ src_name, dst_name, &scan) -+ : sparse_copy (source_desc, dest_desc, buf, buf_size, -+ make_holes ? hole_size : 0, -+ x->sparse_mode == SPARSE_ALWAYS, -+ src_name, dst_name, UINTMAX_MAX, &n_read, -+ &wrote_hole_at_eof))) - { - return_val = false; - goto close_src_and_dst_desc; -@@ -1336,7 +1325,6 @@ copy_reg (char const *src_name, char const *dst_name, - } - } - --preserve_metadata: - if (x->preserve_timestamps) - { - struct timespec timespec[2]; --- -2.26.3 - - -From 5631bded3a385ca0bbd77456b50767fe5580240c Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 25 Jun 2020 16:31:44 -0700 -Subject: [PATCH 04/12] cp: use SEEK_DATA/SEEK_HOLE if available - -If it works, prefer lseek with SEEK_DATA and SEEK_HOLE to FIEMAP, -as lseek is simpler and more portable (will be in next POSIX). -Problem reported in 2011 by Jeff Liu (Bug#8061). -* NEWS: Mention this. -* src/copy.c (lseek_copy) [SEEK_HOLE]: New function. -(enum scantype): New constants ERROR_SCANTYPE, LSEEK_SCANTYPE. -(union scan_inference): New type. -(infer_scantype): Last arg is now union scan_inference *, -not struct extent_scan *. All callers changed. -Prefer SEEK_HOLE to FIEMAP if both work, since -SEEK_HOLE is simpler and more portable. -(copy_reg): Do the fdadvise after initial scan, in case the scan -fails. Report an error if the initial scan fails. -(copy_reg) [SEEK_HOLE]: Use lseek_copy if scantype says so. - -Upstream-commit: a6eaee501f6ec0c152abe88640203a64c390993e -Signed-off-by: Kamil Dudka ---- - src/copy.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 198 insertions(+), 11 deletions(-) - -diff --git a/src/copy.c b/src/copy.c -index b382cfa..d88f8cf 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -416,7 +416,12 @@ write_zeros (int fd, off_t n_bytes) - Upon a successful copy, return true. If the initial extent scan - fails, set *NORMAL_COPY_REQUIRED to true and return false. - Upon any other failure, set *NORMAL_COPY_REQUIRED to false and -- return false. */ -+ return false. -+ -+ FIXME: Once we no longer need to support Linux kernel versions -+ before 3.1 (2011), this function can be retired as it is superseded -+ by lseek_copy. That is, we no longer need extent-scan.h and can -+ remove any of the code that uses it. */ - static bool - extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - size_t hole_size, off_t src_total_size, -@@ -595,6 +600,150 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - return true; - } - -+#ifdef SEEK_HOLE -+/* Perform an efficient extent copy, if possible. This avoids -+ the overhead of detecting holes in hole-introducing/preserving -+ copy, and thus makes copying sparse files much more efficient. -+ Copy from SRC_FD to DEST_FD, using BUF (of size BUF_SIZE) for a buffer. -+ Look for holes of size HOLE_SIZE in the input. -+ The input file is of size SRC_TOTAL_SIZE. -+ Use SPARSE_MODE to determine whether to create holes in the output. -+ SRC_NAME and DST_NAME are the input and output file names. -+ Return true if successful, false (with a diagnostic) otherwise. */ -+ -+static bool -+lseek_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, -+ size_t hole_size, off_t ext_start, off_t src_total_size, -+ enum Sparse_type sparse_mode, -+ char const *src_name, char const *dst_name) -+{ -+ off_t last_ext_start = 0; -+ off_t last_ext_len = 0; -+ off_t dest_pos = 0; -+ bool wrote_hole_at_eof = true; -+ -+ while (0 <= ext_start) -+ { -+ off_t ext_end = lseek (src_fd, ext_start, SEEK_HOLE); -+ if (ext_end < 0) -+ { -+ if (errno != ENXIO) -+ goto cannot_lseek; -+ ext_end = src_total_size; -+ if (ext_end <= ext_start) -+ { -+ /* The input file grew; get its current size. */ -+ src_total_size = lseek (src_fd, 0, SEEK_END); -+ if (src_total_size < 0) -+ goto cannot_lseek; -+ -+ /* If the input file shrank after growing, stop copying. */ -+ if (src_total_size <= ext_start) -+ break; -+ -+ ext_end = src_total_size; -+ } -+ } -+ /* If the input file must have grown, increase its measured size. */ -+ if (src_total_size < ext_end) -+ src_total_size = ext_end; -+ -+ if (lseek (src_fd, ext_start, SEEK_SET) < 0) -+ goto cannot_lseek; -+ -+ wrote_hole_at_eof = false; -+ off_t ext_hole_size = ext_start - last_ext_start - last_ext_len; -+ -+ if (ext_hole_size) -+ { -+ if (sparse_mode != SPARSE_NEVER) -+ { -+ if (! create_hole (dest_fd, dst_name, -+ sparse_mode == SPARSE_ALWAYS, -+ ext_hole_size)) -+ return false; -+ wrote_hole_at_eof = true; -+ } -+ else -+ { -+ /* When not inducing holes and when there is a hole between -+ the end of the previous extent and the beginning of the -+ current one, write zeros to the destination file. */ -+ if (! write_zeros (dest_fd, ext_hole_size)) -+ { -+ error (0, errno, _("%s: write failed"), -+ quotef (dst_name)); -+ return false; -+ } -+ } -+ } -+ -+ off_t ext_len = ext_end - ext_start; -+ last_ext_start = ext_start; -+ last_ext_len = ext_len; -+ -+ /* Copy this extent, looking for further opportunities to not -+ bother to write zeros unless --sparse=never, since SEEK_HOLE -+ is conservative and may miss some holes. */ -+ off_t n_read; -+ bool read_hole; -+ if ( ! sparse_copy (src_fd, dest_fd, buf, buf_size, -+ sparse_mode == SPARSE_NEVER ? 0 : hole_size, -+ true, src_name, dst_name, ext_len, &n_read, -+ &read_hole)) -+ return false; -+ -+ dest_pos = ext_start + n_read; -+ if (n_read) -+ wrote_hole_at_eof = read_hole; -+ if (n_read < ext_len) -+ { -+ /* The input file shrank. */ -+ src_total_size = dest_pos; -+ break; -+ } -+ -+ ext_start = lseek (src_fd, dest_pos, SEEK_DATA); -+ if (ext_start < 0) -+ { -+ if (errno != ENXIO) -+ goto cannot_lseek; -+ break; -+ } -+ } -+ -+ /* When the source file ends with a hole, we have to do a little more work, -+ since the above copied only up to and including the final extent. -+ In order to complete the copy, we may have to insert a hole or write -+ zeros in the destination corresponding to the source file's hole-at-EOF. -+ -+ In addition, if the final extent was a block of zeros at EOF and we've -+ just converted them to a hole in the destination, we must call ftruncate -+ here in order to record the proper length in the destination. */ -+ if ((dest_pos < src_total_size || wrote_hole_at_eof) -+ && ! (sparse_mode == SPARSE_NEVER -+ ? write_zeros (dest_fd, src_total_size - dest_pos) -+ : ftruncate (dest_fd, src_total_size) == 0)) -+ { -+ error (0, errno, _("failed to extend %s"), quoteaf (dst_name)); -+ return false; -+ } -+ -+ if (sparse_mode == SPARSE_ALWAYS && dest_pos < src_total_size -+ && punch_hole (dest_fd, dest_pos, src_total_size - dest_pos) < 0) -+ { -+ error (0, errno, _("error deallocating %s"), quoteaf (dst_name)); -+ return false; -+ } -+ -+ return true; -+ -+ cannot_lseek: -+ error (0, errno, _("cannot lseek %s"), quoteaf (src_name)); -+ return false; -+} -+#endif -+ - /* FIXME: describe */ - /* FIXME: rewrite this to use a hash table so we avoid the quadratic - performance hit that's probably noticeable only on trees deeper -@@ -1010,6 +1159,9 @@ fchmod_or_lchmod (int desc, char const *name, mode_t mode) - /* Type of scan being done on the input when looking for sparseness. */ - enum scantype - { -+ /* An error was found when determining scantype. */ -+ ERROR_SCANTYPE, -+ - /* No fancy scanning; just read and write. */ - PLAIN_SCANTYPE, - -@@ -1017,22 +1169,44 @@ enum scantype - attempting to create sparse output. */ - ZERO_SCANTYPE, - -+ /* lseek information is available. */ -+ LSEEK_SCANTYPE, -+ - /* Extent information is available. */ - EXTENT_SCANTYPE - }; - --/* Use a heuristic to determine whether stat buffer SB comes from a file -- with sparse blocks. If the file has fewer blocks than would normally -- be needed for a file of its size, then at least one of the blocks in -- the file is a hole. In that case, return true. */ -+/* Result of infer_scantype. */ -+union scan_inference -+{ -+ /* Used if infer_scantype returns LSEEK_SCANTYPE. This is the -+ offset of the first data block, or -1 if the file has no data. */ -+ off_t ext_start; -+ -+ /* Used if infer_scantype returns EXTENT_SCANTYPE. */ -+ struct extent_scan extent_scan; -+}; -+ -+/* Return how to scan a file with descriptor FD and stat buffer SB. -+ Store any information gathered into *SCAN. */ - static enum scantype --infer_scantype (int fd, struct stat const *sb, struct extent_scan *scan) -+infer_scantype (int fd, struct stat const *sb, -+ union scan_inference *scan_inference) - { - if (! (HAVE_STRUCT_STAT_ST_BLOCKS - && S_ISREG (sb->st_mode) - && ST_NBLOCKS (*sb) < sb->st_size / ST_NBLOCKSIZE)) - return PLAIN_SCANTYPE; - -+#ifdef SEEK_HOLE -+ scan_inference->ext_start = lseek (fd, 0, SEEK_DATA); -+ if (0 <= scan_inference->ext_start) -+ return LSEEK_SCANTYPE; -+ else if (errno != EINVAL && errno != ENOTSUP) -+ return errno == ENXIO ? LSEEK_SCANTYPE : ERROR_SCANTYPE; -+#endif -+ -+ struct extent_scan *scan = &scan_inference->extent_scan; - extent_scan_init (fd, scan); - extent_scan_read (scan); - return scan->initial_scan_failed ? ZERO_SCANTYPE : EXTENT_SCANTYPE; -@@ -1066,7 +1240,7 @@ copy_reg (char const *src_name, char const *dst_name, - mode_t src_mode = src_sb->st_mode; - struct stat sb; - struct stat src_open_sb; -- struct extent_scan scan; -+ union scan_inference scan_inference; - bool return_val = true; - bool data_copy_required = x->data_copy_required; - -@@ -1263,17 +1437,23 @@ copy_reg (char const *src_name, char const *dst_name, - size_t buf_size = io_blksize (sb); - size_t hole_size = ST_BLKSIZE (sb); - -- fdadvise (source_desc, 0, 0, FADVISE_SEQUENTIAL); -- - /* Deal with sparse files. */ - enum scantype scantype = infer_scantype (source_desc, &src_open_sb, -- &scan); -+ &scan_inference); -+ if (scantype == ERROR_SCANTYPE) -+ { -+ error (0, errno, _("cannot lseek %s"), quoteaf (src_name)); -+ return_val = false; -+ goto close_src_and_dst_desc; -+ } - bool make_holes - = (S_ISREG (sb.st_mode) - && (x->sparse_mode == SPARSE_ALWAYS - || (x->sparse_mode == SPARSE_AUTO - && scantype != PLAIN_SCANTYPE))); - -+ fdadvise (source_desc, 0, 0, FADVISE_SEQUENTIAL); -+ - /* If not making a sparse file, try to use a more-efficient - buffer size. */ - if (! make_holes) -@@ -1307,7 +1487,14 @@ copy_reg (char const *src_name, char const *dst_name, - ? extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, - src_open_sb.st_size, - make_holes ? x->sparse_mode : SPARSE_NEVER, -- src_name, dst_name, &scan) -+ src_name, dst_name, &scan_inference.extent_scan) -+#ifdef SEEK_HOLE -+ : scantype == LSEEK_SCANTYPE -+ ? lseek_copy (source_desc, dest_desc, buf, buf_size, hole_size, -+ scan_inference.ext_start, src_open_sb.st_size, -+ make_holes ? x->sparse_mode : SPARSE_NEVER, -+ src_name, dst_name) -+#endif - : sparse_copy (source_desc, dest_desc, buf, buf_size, - make_holes ? hole_size : 0, - x->sparse_mode == SPARSE_ALWAYS, --- -2.26.3 - - -From be7466be92d779cfbece418d4de33191ae52ab4a Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Wed, 24 Mar 2021 16:06:53 +0100 -Subject: [PATCH 05/12] import the copy-file-range module from gnulib - ---- - aclocal.m4 | 1 + - lib/config.hin | 3 +++ - lib/copy-file-range.c | 33 +++++++++++++++++++++++++++++++++ - lib/gnulib.mk | 10 ++++++++++ - m4/copy-file-range.m4 | 36 ++++++++++++++++++++++++++++++++++++ - m4/gnulib-comp.m4 | 8 ++++++++ - 6 files changed, 91 insertions(+) - create mode 100644 lib/copy-file-range.c - create mode 100644 m4/copy-file-range.m4 - -diff --git a/aclocal.m4 b/aclocal.m4 -index 713f7c5..09a7ea8 100644 ---- a/aclocal.m4 -+++ b/aclocal.m4 -@@ -1165,6 +1165,7 @@ m4_include([m4/closedir.m4]) - m4_include([m4/codeset.m4]) - m4_include([m4/config-h.m4]) - m4_include([m4/configmake.m4]) -+m4_include([m4/copy-file-range.m4]) - m4_include([m4/ctype.m4]) - m4_include([m4/cycle-check.m4]) - m4_include([m4/d-ino.m4]) -diff --git a/lib/config.hin b/lib/config.hin -index 9769c39..bf9f9f8 100644 ---- a/lib/config.hin -+++ b/lib/config.hin -@@ -370,6 +370,9 @@ - /* Define to 1 when the gnulib module connect should be tested. */ - #undef GNULIB_TEST_CONNECT - -+/* Define to 1 when the gnulib module copy-file-range should be tested. */ -+#undef GNULIB_TEST_COPY_FILE_RANGE -+ - /* Define to 1 when the gnulib module dirfd should be tested. */ - #undef GNULIB_TEST_DIRFD - -diff --git a/lib/copy-file-range.c b/lib/copy-file-range.c -new file mode 100644 -index 0000000..069f144 ---- /dev/null -+++ b/lib/copy-file-range.c -@@ -0,0 +1,33 @@ -+/* Stub for copy_file_range -+ Copyright 2019-2020 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 . */ -+ -+#include -+ -+#include -+ -+#include -+ -+ssize_t -+copy_file_range (int infd, off_t *pinoff, -+ int outfd, off_t *poutoff, -+ size_t length, unsigned int flags) -+{ -+ /* There is little need to emulate copy_file_range with read+write, -+ since programs that use copy_file_range must fall back on -+ read+write anyway. */ -+ errno = ENOSYS; -+ return -1; -+} -diff --git a/lib/gnulib.mk b/lib/gnulib.mk -index b3633b8..86829f3 100644 ---- a/lib/gnulib.mk -+++ b/lib/gnulib.mk -@@ -65,6 +65,7 @@ - # closeout \ - # config-h \ - # configmake \ -+# copy-file-range \ - # crypto/md5 \ - # crypto/sha1 \ - # crypto/sha256 \ -@@ -800,6 +801,15 @@ CLEANFILES += lib/configmake.h lib/configmake.h-t - - ## end gnulib module configmake - -+## begin gnulib module copy-file-range -+ -+ -+EXTRA_DIST += lib/copy-file-range.c -+ -+EXTRA_lib_libcoreutils_a_SOURCES += lib/copy-file-range.c -+ -+## end gnulib module copy-file-range -+ - ## begin gnulib module count-leading-zeros - - lib_libcoreutils_a_SOURCES += lib/count-leading-zeros.c -diff --git a/m4/copy-file-range.m4 b/m4/copy-file-range.m4 -new file mode 100644 -index 0000000..5c5a274 ---- /dev/null -+++ b/m4/copy-file-range.m4 -@@ -0,0 +1,36 @@ -+# copy-file-range.m4 -+dnl Copyright 2019-2020 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. -+ -+AC_DEFUN([gl_FUNC_COPY_FILE_RANGE], -+[ -+ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) -+ -+ dnl Persuade glibc to declare copy_file_range. -+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) -+ -+ dnl Use AC_LINK_IFELSE, rather than AC_CHECK_FUNCS or a variant, -+ dnl since we don't want AC_CHECK_FUNCS's checks for glibc stubs. -+ dnl Programs that use copy_file_range must fall back on read+write -+ dnl anyway, and there's little point to substituting the Gnulib stub -+ dnl for a glibc stub. -+ AC_CACHE_CHECK([for copy_file_range], [gl_cv_func_copy_file_range], -+ [AC_LINK_IFELSE( -+ [AC_LANG_PROGRAM( -+ [[#include -+ ]], -+ [[ssize_t (*func) (int, off_t *, int, off_t, size_t, unsigned) -+ = copy_file_range; -+ return func (0, 0, 0, 0, 0, 0) & 127; -+ ]]) -+ ], -+ [gl_cv_func_copy_file_range=yes], -+ [gl_cv_func_copy_file_range=no]) -+ ]) -+ -+ if test "$gl_cv_func_copy_file_range" != yes; then -+ HAVE_COPY_FILE_RANGE=0 -+ fi -+]) -diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 -index dead90e..953e7f0 100644 ---- a/m4/gnulib-comp.m4 -+++ b/m4/gnulib-comp.m4 -@@ -129,6 +129,7 @@ AC_DEFUN([gl_EARLY], - # Code from module configmake: - # Code from module connect: - # Code from module connect-tests: -+ # Code from module copy-file-range: - # Code from module count-leading-zeros: - # Code from module count-leading-zeros-tests: - # Code from module crypto/af_alg: -@@ -977,6 +978,11 @@ AC_DEFUN([gl_INIT], - gl_DIRENT_MODULE_INDICATOR([closedir]) - gl_CONFIG_H - gl_CONFIGMAKE_PREP -+ gl_FUNC_COPY_FILE_RANGE -+ if test $HAVE_COPY_FILE_RANGE = 0; then -+ AC_LIBOBJ([copy-file-range]) -+ fi -+ gl_UNISTD_MODULE_INDICATOR([copy-file-range]) - gl_AF_ALG - AC_DEFINE([GL_COMPILE_CRYPTO_STREAM], 1, [Compile Gnulib crypto stream ops.]) - AC_REQUIRE([AC_C_RESTRICT]) -@@ -2746,6 +2752,7 @@ AC_DEFUN([gl_FILE_LIST], [ - lib/closeout.c - lib/closeout.h - lib/copy-acl.c -+ lib/copy-file-range.c - lib/count-leading-zeros.c - lib/count-leading-zeros.h - lib/creat-safer.c -@@ -3438,6 +3445,7 @@ AC_DEFUN([gl_FILE_LIST], [ - m4/codeset.m4 - m4/config-h.m4 - m4/configmake.m4 -+ m4/copy-file-range.m4 - m4/ctype.m4 - m4/cycle-check.m4 - m4/d-ino.m4 --- -2.26.3 - - -From 48370c95bcf7c25ce021fbd2145062d3d29ae6d5 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 25 Jun 2020 17:34:23 -0700 -Subject: [PATCH 06/12] cp: use copy_file_range if available - -* NEWS: Mention this. -* bootstrap.conf (gnulib_modules): Add copy-file-range. -* src/copy.c (sparse_copy): Try copy_file_range if not -looking for holes. - -Upstream-commit: 4b04a0c3b792d27909670a81d21f2a3b3e0ea563 -Signed-off-by: Kamil Dudka ---- - bootstrap.conf | 1 + - src/copy.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 41 insertions(+) - -diff --git a/bootstrap.conf b/bootstrap.conf -index 2a342c1..7d53e28 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -54,6 +54,7 @@ gnulib_modules=" - closeout - config-h - configmake -+ copy-file-range - crypto/md5 - crypto/sha1 - crypto/sha256 -diff --git a/src/copy.c b/src/copy.c -index d88f8cf..4050f69 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -265,6 +265,46 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - { - *last_write_made_hole = false; - *total_n_read = 0; -+ -+ /* If not looking for holes, use copy_file_range if available. */ -+ if (!hole_size) -+ while (max_n_read) -+ { -+ /* Copy at most COPY_MAX bytes at a time; this is min -+ (PTRDIFF_MAX, SIZE_MAX) truncated to a value that is -+ surely aligned well. */ -+ ssize_t ssize_max = TYPE_MAXIMUM (ssize_t); -+ ptrdiff_t copy_max = MIN (ssize_max, SIZE_MAX) >> 30 << 30; -+ ssize_t n_copied = copy_file_range (src_fd, NULL, dest_fd, NULL, -+ MIN (max_n_read, copy_max), 0); -+ if (n_copied == 0) -+ { -+ /* copy_file_range incorrectly returns 0 when reading from -+ the proc file system on the Linux kernel through at -+ least 5.6.19 (2020), so fall back on 'read' if the -+ input file seems empty. */ -+ if (*total_n_read == 0) -+ break; -+ return true; -+ } -+ if (n_copied < 0) -+ { -+ if (errno == ENOSYS || errno == EINVAL -+ || errno == EBADF || errno == EXDEV) -+ break; -+ if (errno == EINTR) -+ n_copied = 0; -+ else -+ { -+ error (0, errno, _("error copying %s to %s"), -+ quoteaf_n (0, src_name), quoteaf_n (1, dst_name)); -+ return false; -+ } -+ } -+ max_n_read -= n_copied; -+ *total_n_read += n_copied; -+ } -+ - bool make_hole = false; - off_t psize = 0; - --- -2.26.3 - - -From 23ea1ba463d33e268f35847059e637a5935e4581 Mon Sep 17 00:00:00 2001 -From: Zorro Lang -Date: Mon, 26 Apr 2021 17:25:18 +0200 -Subject: [PATCH 07/12] copy: do not refuse to copy a swap file - -* src/copy.c (sparse_copy): Fallback to read() if copy_file_range() -fails with ETXTBSY. Otherwise it would be impossible to copy files -that are being used as swap. This used to work before introducing -the support for copy_file_range() in coreutils. (Bug#48036) - -Upstream-commit: 785478013b416cde50794be35475c0c4fdbb48b4 -Signed-off-by: Kamil Dudka ---- - src/copy.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/copy.c b/src/copy.c -index 4050f69..1798bb7 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -290,7 +290,7 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - if (n_copied < 0) - { - if (errno == ENOSYS || errno == EINVAL -- || errno == EBADF || errno == EXDEV) -+ || errno == EBADF || errno == EXDEV || errno == ETXTBSY) - break; - if (errno == EINTR) - n_copied = 0; --- -2.31.1 - - -From cd7c7a6b5ad89ef0a61722552d532901fc1bed05 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sun, 2 May 2021 21:27:17 +0100 -Subject: [PATCH 08/12] copy: ensure we enforce --reflink=never - -* src/copy.c (sparse_copy): Don't use copy_file_range() -with --reflink=never as copy_file_range() may implicitly -use acceleration techniques like reflinking. -(extent_copy): Pass through whether we allow reflinking. -(lseek_copy): Likewise. -Fixes https://bugs.gnu.org/48164 - -Upstream-commit: ea9af99234031ab8d5169c8a669434e2a6b4f864 -Signed-off-by: Kamil Dudka ---- - src/copy.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -diff --git a/src/copy.c b/src/copy.c -index 4050f69..0337538 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -258,7 +258,7 @@ create_hole (int fd, char const *name, bool punch_holes, off_t size) - bytes read. */ - static bool - sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, -- size_t hole_size, bool punch_holes, -+ size_t hole_size, bool punch_holes, bool allow_reflink, - char const *src_name, char const *dst_name, - uintmax_t max_n_read, off_t *total_n_read, - bool *last_write_made_hole) -@@ -266,8 +266,9 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - *last_write_made_hole = false; - *total_n_read = 0; - -- /* If not looking for holes, use copy_file_range if available. */ -- if (!hole_size) -+ /* If not looking for holes, use copy_file_range if available, -+ but don't use if reflink disallowed as that may be implicit. */ -+ if ((! hole_size) && allow_reflink) - while (max_n_read) - { - /* Copy at most COPY_MAX bytes at a time; this is min -@@ -466,6 +467,7 @@ static bool - extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - size_t hole_size, off_t src_total_size, - enum Sparse_type sparse_mode, -+ bool allow_reflink, - char const *src_name, char const *dst_name, - struct extent_scan *scan) - { -@@ -579,8 +581,8 @@ extent_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - - if ( ! sparse_copy (src_fd, dest_fd, buf, buf_size, - sparse_mode == SPARSE_ALWAYS ? hole_size: 0, -- true, src_name, dst_name, ext_len, &n_read, -- &read_hole)) -+ true, allow_reflink, src_name, dst_name, -+ ext_len, &n_read, &read_hole)) - goto fail; - - dest_pos = ext_start + n_read; -@@ -655,6 +657,7 @@ static bool - lseek_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - size_t hole_size, off_t ext_start, off_t src_total_size, - enum Sparse_type sparse_mode, -+ bool allow_reflink, - char const *src_name, char const *dst_name) - { - off_t last_ext_start = 0; -@@ -729,8 +732,8 @@ lseek_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - bool read_hole; - if ( ! sparse_copy (src_fd, dest_fd, buf, buf_size, - sparse_mode == SPARSE_NEVER ? 0 : hole_size, -- true, src_name, dst_name, ext_len, &n_read, -- &read_hole)) -+ true, allow_reflink, src_name, dst_name, -+ ext_len, &n_read, &read_hole)) - return false; - - dest_pos = ext_start + n_read; -@@ -1527,17 +1530,20 @@ copy_reg (char const *src_name, char const *dst_name, - ? extent_copy (source_desc, dest_desc, buf, buf_size, hole_size, - src_open_sb.st_size, - make_holes ? x->sparse_mode : SPARSE_NEVER, -+ x->reflink_mode != REFLINK_NEVER, - src_name, dst_name, &scan_inference.extent_scan) - #ifdef SEEK_HOLE - : scantype == LSEEK_SCANTYPE - ? lseek_copy (source_desc, dest_desc, buf, buf_size, hole_size, - scan_inference.ext_start, src_open_sb.st_size, - make_holes ? x->sparse_mode : SPARSE_NEVER, -+ x->reflink_mode != REFLINK_NEVER, - src_name, dst_name) - #endif - : sparse_copy (source_desc, dest_desc, buf, buf_size, - make_holes ? hole_size : 0, - x->sparse_mode == SPARSE_ALWAYS, -+ x->reflink_mode != REFLINK_NEVER, - src_name, dst_name, UINTMAX_MAX, &n_read, - &wrote_hole_at_eof))) - { --- -2.30.2 - - -From 7978f1de88dcdb17b67db9268038930e9c71154f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sat, 8 May 2021 17:18:54 +0100 -Subject: [PATCH 09/12] copy: handle ENOTSUP from copy_file_range() - -* src/copy.c (sparse_copy): Ensure we fall back to -a standard copy if copy_file_range() returns ENOTSUP. -This generally is best checked when checking ENOSYS, -but it also seems to be a practical concern on Centos 7, -as a quick search gave https://bugzilla.redhat.com/1840284 - -Upstream-commit: 8ec0d1799e19a079b8a661c6bb69f6c58e52f1aa -Signed-off-by: Kamil Dudka ---- - src/copy.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/copy.c b/src/copy.c -index 9977193..e3977cd 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -290,8 +290,9 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - } - if (n_copied < 0) - { -- if (errno == ENOSYS || errno == EINVAL -- || errno == EBADF || errno == EXDEV || errno == ETXTBSY) -+ if (errno == ENOSYS || is_ENOTSUP (errno) -+ || errno == EINVAL || errno == EBADF -+ || errno == EXDEV || errno == ETXTBSY) - break; - if (errno == EINTR) - n_copied = 0; --- -2.31.1 - - -From d8d3edbfc13ff13c185f23436209b788f906aa41 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sun, 9 May 2021 21:55:22 +0100 -Subject: [PATCH 10/12] copy: handle EOPNOTSUPP from SEEK_DATA - -* src/copy.c (infer_scantype): Ensure we don't error out -if SEEK_DATA returns EOPNOTSUPP, on systems where this value -is distinct from ENOTSUP. Generally both of these should be checked. - -Upstream-commit: 017877bd088284d515753d78b81ca6e6a88c1350 -Signed-off-by: Kamil Dudka ---- - src/copy.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/copy.c b/src/copy.c -index e3977cd..de8030d 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -1246,7 +1246,7 @@ infer_scantype (int fd, struct stat const *sb, - scan_inference->ext_start = lseek (fd, 0, SEEK_DATA); - if (0 <= scan_inference->ext_start) - return LSEEK_SCANTYPE; -- else if (errno != EINVAL && errno != ENOTSUP) -+ else if (errno != EINVAL && !is_ENOTSUP (errno)) - return errno == ENXIO ? LSEEK_SCANTYPE : ERROR_SCANTYPE; - #endif - --- -2.31.1 - - -From 1daf8c0fc9a5766c22b7ea84bea8c88c86a0c495 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sat, 8 May 2021 19:23:20 +0100 -Subject: [PATCH 11/12] copy: handle system security config issues with - copy_file_range() - -* src/copy.c (sparse_copy): Upon EPERM from copy_file_range(), -fall back to a standard copy, which will give a more accurate -error as to whether the issue is with the source or destination. -Also this will avoid the issue where seccomp or apparmor are -not configured to handle copy_file_range(), in which case -the fall back standard copy would succeed without issue. -This specific issue with seccomp was noticed for example in: -https://github.com/golang/go/issues/40900 - -Upstream-commit: 2e66e1732fced7af20fa76c60e636d39a1767d48 -Signed-off-by: Kamil Dudka ---- - src/copy.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/src/copy.c b/src/copy.c -index de8030d..62eec7b 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -294,6 +294,15 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - || errno == EINVAL || errno == EBADF - || errno == EXDEV || errno == ETXTBSY) - break; -+ -+ /* copy_file_range might not be enabled in seccomp filters, -+ so retry with a standard copy. EPERM can also occur -+ for immutable files, but that would only be in the edge case -+ where the file is made immutable after creating/truncating, -+ in which case the (more accurate) error is still shown. */ -+ if (errno == EPERM && *total_n_read == 0) -+ break; -+ - if (errno == EINTR) - n_copied = 0; - else --- -2.31.1 - - -From 42c9e598f61ba6bc27a615e39e40023a676a523b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 12 May 2021 23:47:38 +0100 -Subject: [PATCH 12/12] copy: disallow copy_file_range() on Linux kernels - before 5.3 - -copy_file_range() before Linux kernel release 5.3 had many issues, -as described at https://lwn.net/Articles/789527/, which was -referenced from https://lwn.net/Articles/846403/; a more general -article discussing the generality of copy_file_range(). -Linux kernel 5.3 was released in September 2019, which is new enough -that we need to actively avoid older kernels. - -* src/copy.c (functional_copy_file_range): A new function -that returns false for Linux kernels before version 5.3. -(sparse_copy): Call this new function to gate use of -copy_file_range(). - -Upstream-commit: ba5e6885d2c255648cddb87b4e795659c1990374 -Signed-off-by: Kamil Dudka ---- - src/copy.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 45 insertions(+), 2 deletions(-) - -diff --git a/src/copy.c b/src/copy.c -index 62eec7b..2e1699b 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - - #if HAVE_HURD_H -@@ -64,6 +65,7 @@ - #include "write-any-file.h" - #include "areadlink.h" - #include "yesno.h" -+#include "xstrtol.h" - #include "selinux.h" - - #if USE_XATTR -@@ -244,6 +246,47 @@ create_hole (int fd, char const *name, bool punch_holes, off_t size) - return true; - } - -+/* copy_file_range() before Linux kernel release 5.3 had many issues, -+ as described at https://lwn.net/Articles/789527/, -+ so return FALSE for Linux kernels earlier than that. -+ This function can be removed when such kernels (released before Sep 2019) -+ are no longer a consideration. */ -+ -+static bool -+functional_copy_file_range (void) -+{ -+#ifdef __linux__ -+ static int version_allowed = -1; -+ -+ if (version_allowed == -1) -+ version_allowed = 0; -+ else -+ return version_allowed; -+ -+ struct utsname name; -+ if (uname (&name) == -1) -+ return version_allowed; -+ -+ char *p = name.release; -+ uintmax_t ver[2] = {0, 0}; -+ size_t iver = 0; -+ -+ do -+ { -+ strtol_error err = xstrtoumax (p, &p, 10, &ver[iver], NULL); -+ if (err != LONGINT_OK || *p++ != '.') -+ break; -+ } -+ while (++iver < ARRAY_CARDINALITY (ver)); -+ -+ version_allowed = (ver[0] > 5 || (ver[0] == 5 && ver[1] >= 3)); -+ -+ return version_allowed; -+#else -+ return true; -+#endif -+ -+} - - /* Copy the regular file open on SRC_FD/SRC_NAME to DST_FD/DST_NAME, - honoring the MAKE_HOLES setting and using the BUF_SIZE-byte buffer -@@ -266,9 +309,9 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size, - *last_write_made_hole = false; - *total_n_read = 0; - -- /* If not looking for holes, use copy_file_range if available, -+ /* If not looking for holes, use copy_file_range if functional, - but don't use if reflink disallowed as that may be implicit. */ -- if ((! hole_size) && allow_reflink) -+ if ((! hole_size) && allow_reflink && functional_copy_file_range ()) - while (max_n_read) - { - /* Copy at most COPY_MAX bytes at a time; this is min --- -2.31.1 - diff --git a/coreutils-8.32-cp-reflink-auto.patch b/coreutils-8.32-cp-reflink-auto.patch deleted file mode 100644 index a36c89c..0000000 --- a/coreutils-8.32-cp-reflink-auto.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 76126e2831580d0df20530f4d6f72189bd4f0b9a Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 18 Jun 2020 22:16:24 -0700 -Subject: [PATCH] cp: default to COW -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Likewise for ‘install’. Proposed in Bug#24400, and long past due. -* NEWS: -* doc/coreutils.texi (cp invocation): -* src/copy.h (enum Reflink_type): Document this. -* src/cp.c (cp_option_init): -* src/install.c (cp_option_init): Implement this. - -Upstream-commit: 25725f9d41735d176d73a757430739fb71c7d043 -Signed-off-by: Kamil Dudka ---- - doc/coreutils.texi | 19 ++++++++++++------- - src/copy.h | 4 ++-- - src/cp.c | 2 +- - src/install.c | 2 +- - 4 files changed, 16 insertions(+), 11 deletions(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 02e0c1c..2382a16 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -8854,12 +8854,14 @@ The @var{when} value can be one of the following: - - @table @samp - @item always --The default behavior: if the copy-on-write operation is not supported -+If the copy-on-write operation is not supported - then report the failure for each file and exit with a failure status. -+Plain @option{--reflink} is equivalent to @option{--reflink=when}. - - @item auto - If the copy-on-write operation is not supported then fall back - to the standard copy behavior. -+This is the default if no @option{--reflink} option is given. - - @item never - Disable copy-on-write operation and use the standard copy behavior. -@@ -8868,12 +8870,6 @@ Disable copy-on-write operation and use the standard copy behavior. - This option is overridden by the @option{--link}, @option{--symbolic-link} - and @option{--attributes-only} options, thus allowing it to be used - to configure the default data copying behavior for @command{cp}. --For example, with the following alias, @command{cp} will use the --minimum amount of space supported by the file system. -- --@example --alias cp='cp --reflink=auto --sparse=always' --@end example - - @item --remove-destination - @opindex --remove-destination -@@ -8918,6 +8914,15 @@ This is useful in creating a file for use with the @command{mkswap} command, - since such a file must not have any holes. - @end table - -+For example, with the following alias, @command{cp} will use the -+minimum amount of space supported by the file system. -+(Older versions of @command{cp} can also benefit from -+@option{--reflink=auto} here.) -+ -+@example -+alias cp='cp --sparse=always' -+@end example -+ - @optStripTrailingSlashes - - @item -s -diff --git a/src/copy.h b/src/copy.h -index 874d6f7..a0ad494 100644 ---- a/src/copy.h -+++ b/src/copy.h -@@ -46,10 +46,10 @@ enum Sparse_type - /* Control creation of COW files. */ - enum Reflink_type - { -- /* Default to a standard copy. */ -+ /* Do a standard copy. */ - REFLINK_NEVER, - -- /* Try a COW copy and fall back to a standard copy. */ -+ /* Try a COW copy and fall back to a standard copy; this is the default. */ - REFLINK_AUTO, - - /* Require a COW copy and fail if not available. */ -diff --git a/src/cp.c b/src/cp.c -index 0193df8..9e7ad14 100644 ---- a/src/cp.c -+++ b/src/cp.c -@@ -796,7 +796,7 @@ cp_option_init (struct cp_options *x) - x->move_mode = false; - x->install_mode = false; - x->one_file_system = false; -- x->reflink_mode = REFLINK_NEVER; -+ x->reflink_mode = REFLINK_AUTO; - - x->preserve_ownership = false; - x->preserve_links = false; -diff --git a/src/install.c b/src/install.c -index 4ab44a6..aef16ca 100644 ---- a/src/install.c -+++ b/src/install.c -@@ -264,7 +264,7 @@ cp_option_init (struct cp_options *x) - { - cp_options_default (x); - x->copy_as_regular = true; -- x->reflink_mode = REFLINK_NEVER; -+ x->reflink_mode = REFLINK_AUTO; - x->dereference = DEREF_ALWAYS; - x->unlink_dest_before_opening = true; - x->unlink_dest_after_failed_open = false; --- -2.25.4 - diff --git a/coreutils-8.32-df-duplicated-entries.patch b/coreutils-8.32-df-duplicated-entries.patch deleted file mode 100644 index 5d39c1e..0000000 --- a/coreutils-8.32-df-duplicated-entries.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 0f053de4bc3ca0cfd88a42d236881dfdddb10ee9 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Wed, 30 Jun 2021 17:53:22 +0200 -Subject: [PATCH] df: fix duplicated remote entries due to bind mounts - -As originally reported in , -df invoked without -a printed duplicated entries for NFS mounts -of bind mounts. This is a regression from commit v8.25-54-g1c17f61ef99, -which introduced the use of a hash table. - -The proposed patch makes sure that the devlist entry seen the last time -is used for comparison when eliminating duplicated mount entries. This -way it worked before introducing the hash table. - -Patch co-authored by Roberto Bergantinos. - -* src/ls.c (struct devlist): Introduce the seen_last pointer. -(devlist_for_dev): Return the devlist entry seen the last time if found. -(filter_mount_list): Remember the devlist entry seen the last time for -each hashed item. -Fixes https://bugs.gnu.org/49298 - -Upstream-commit: d6125af095c9553f38cba0696f15158f5abe4ecc -Signed-off-by: Kamil Dudka ---- - src/df.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/src/df.c b/src/df.c -index 7e01839..3e9247f 100644 ---- a/src/df.c -+++ b/src/df.c -@@ -54,6 +54,7 @@ struct devlist - dev_t dev_num; - struct mount_entry *me; - struct devlist *next; -+ struct devlist *seen_last; /* valid for hashed devlist entries only */ - }; - - /* Filled with device numbers of examined file systems to avoid -@@ -689,7 +690,13 @@ devlist_for_dev (dev_t dev) - return NULL; - struct devlist dev_entry; - dev_entry.dev_num = dev; -- return hash_lookup (devlist_table, &dev_entry); -+ -+ struct devlist *found = hash_lookup (devlist_table, &dev_entry); -+ if (found == NULL) -+ return NULL; -+ -+ /* Return the last devlist entry we have seen with this dev_num */ -+ return found->seen_last; - } - - static void -@@ -807,8 +814,12 @@ filter_mount_list (bool devices_only) - devlist->dev_num = buf.st_dev; - devlist->next = device_list; - device_list = devlist; -- if (hash_insert (devlist_table, devlist) == NULL) -+ -+ struct devlist *hash_entry = hash_insert (devlist_table, devlist); -+ if (hash_entry == NULL) - xalloc_die (); -+ /* Ensure lookups use this latest devlist. */ -+ hash_entry->seen_last = devlist; - - me = me->me_next; - } --- -2.31.1 - diff --git a/coreutils-8.32-expr-unmatched-par.patch b/coreutils-8.32-expr-unmatched-par.patch deleted file mode 100644 index 1a82384..0000000 --- a/coreutils-8.32-expr-unmatched-par.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 9618fb718b75920f37e5be2049ad1d0bb5c4a28c Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Tue, 26 Jan 2021 09:23:54 -0800 -Subject: [PATCH] expr: fix bug with unmatched \(...\) - -Problem reported by Qiuhao Li. -* doc/coreutils.texi (String expressions): -Document the correct behavior, which POSIX requires. -* src/expr.c (docolon): Treat unmatched \(...\) as empty. -* tests/misc/expr.pl: New test. - -Upstream-commit: 735083ba24878075235007b4417982ad5700436d -Signed-off-by: Kamil Dudka ---- - doc/coreutils.texi | 14 ++++++++------ - src/expr.c | 9 +++++++-- - tests/misc/expr.pl | 3 +++ - 3 files changed, 18 insertions(+), 8 deletions(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 2382a16..5b2bb2c 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -13529,12 +13529,14 @@ second is considered to be a (basic, a la GNU @code{grep}) regular - expression, with a @code{^} implicitly prepended. The first argument is - then matched against this regular expression. - --If the match succeeds and @var{regex} uses @samp{\(} and @samp{\)}, the --@code{:} expression returns the part of @var{string} that matched the --subexpression; otherwise, it returns the number of characters matched. -- --If the match fails, the @code{:} operator returns the null string if --@samp{\(} and @samp{\)} are used in @var{regex}, otherwise 0. -+If @var{regex} does not use @samp{\(} and @samp{\)}, the @code{:} -+expression returns the number of characters matched, or 0 if the match -+fails. -+ -+If @var{regex} uses @samp{\(} and @samp{\)}, the @code{:} expression -+returns the part of @var{string} that matched the subexpression, or -+the null string if the match failed or the subexpression did not -+contribute to the match. - - @kindex \( @r{regexp operator} - Only the first @samp{\( @dots{} \)} pair is relevant to the return -diff --git a/src/expr.c b/src/expr.c -index e134872..0616a42 100644 ---- a/src/expr.c -+++ b/src/expr.c -@@ -721,8 +721,13 @@ docolon (VALUE *sv, VALUE *pv) - /* Were \(...\) used? */ - if (re_buffer.re_nsub > 0) - { -- sv->u.s[re_regs.end[1]] = '\0'; -- v = str_value (sv->u.s + re_regs.start[1]); -+ if (re_regs.end[1] < 0) -+ v = str_value (""); -+ else -+ { -+ sv->u.s[re_regs.end[1]] = '\0'; -+ v = str_value (sv->u.s + re_regs.start[1]); -+ } - } - else - { -diff --git a/tests/misc/expr.pl b/tests/misc/expr.pl -index e45f8e7..e57f79d 100755 ---- a/tests/misc/expr.pl -+++ b/tests/misc/expr.pl -@@ -84,6 +84,9 @@ my @Tests = - # In 5.94 and earlier, anchors incorrectly matched newlines. - ['anchor', "'a\nb' : 'a\$'", {OUT => '0'}, {EXIT => 1}], - -+ # In 8.32, \( ... \) that did not match caused memory errors. -+ ['emptysub', '"a" : "\\(b\\)*"', {OUT => ''}, {EXIT => 1}], -+ - # These tests are taken from grep/tests/bre.tests. - ['bre1', '"abc" : "a\\(b\\)c"', {OUT => 'b'}], - ['bre2', '"a(" : "a("', {OUT => '2'}], --- -2.26.2 - diff --git a/coreutils-8.32-fuse-portal.patch b/coreutils-8.32-fuse-portal.patch deleted file mode 100644 index 54b7975..0000000 --- a/coreutils-8.32-fuse-portal.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 602fb566468d3837b7871c17a0fab1a20228d119 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 - -Upstream-commit: 9a38d499ca16f2f4304992eb1ab0894cd0b478e1 -Signed-off-by: Kamil Dudka ---- - lib/mountlist.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/lib/mountlist.c b/lib/mountlist.c -index e0227b7..e5f6b07 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 \ --- -2.31.1 - diff --git a/coreutils-8.32-gnulib-perror-test.patch b/coreutils-8.32-gnulib-perror-test.patch deleted file mode 100644 index e545290..0000000 --- a/coreutils-8.32-gnulib-perror-test.patch +++ /dev/null @@ -1,48 +0,0 @@ -From f61085aaa37f169365c56e44f5129d0491913b6a 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. - -Upstream-commit: 175e0bc72808d564074c4adcc72aeadb74adfcc6 -Signed-off-by: Kamil Dudka ---- - gnulib-tests/test-perror2.c | 3 --- - gnulib-tests/test-strerror_r.c | 3 --- - 2 files changed, 6 deletions(-) - -diff --git a/gnulib-tests/test-perror2.c b/gnulib-tests/test-perror2.c -index 1d14eda..c6214dd 100644 ---- a/gnulib-tests/test-perror2.c -+++ b/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); -diff --git a/gnulib-tests/test-strerror_r.c b/gnulib-tests/test-strerror_r.c -index b11d6fd..c1dbcf8 100644 ---- a/gnulib-tests/test-strerror_r.c -+++ b/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); --- -2.25.4 - diff --git a/coreutils-8.32-leaf-opt-xfs.patch b/coreutils-8.32-leaf-opt-xfs.patch deleted file mode 100644 index c02db71..0000000 --- a/coreutils-8.32-leaf-opt-xfs.patch +++ /dev/null @@ -1,164 +0,0 @@ -From b9f9ed14bda93ecb407129b69e6476813c250046 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Wed, 15 Apr 2020 20:50:32 -0700 -Subject: [PATCH] fts: remove NOSTAT_LEAF_OPTIMIZATION -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It caused ‘find’ and ‘du’ to dump core, and it was useful -only for obsolescent Linux filesystems anyway. Problem reported in: -https://lists.gnu.org/r/bug-gnulib/2020-04/msg00068.html -Quite possibly there is still a serious underlying fts bug with -tight-loop-check and mutating file systems, but if so this patch -should cause the bug to be triggered less often. -* lib/fts.c (enum leaf_optimization): Remove -NOSTAT_LEAF_OPTIMIZATION, as it’s problematic. -(S_MAGIC_REISERFS, S_MAGIC_XFS): Remove; no longer needed. -(leaf_optimization): Remove special cases for ReiserFS and XFS. -(fts_read): Remove NOSTAT_LEAF_OPTIMIZATION code. -* lib/fts_.h (struct _ftsent.fts_n_dirs_remaining): -Remove. All uses removed. - -Upstream-commit: 47bf2cf3184027c1eb9c1dfeea5c5b8b2d69710d -Signed-off-by: Kamil Dudka ---- - lib/fts.c | 56 ++++++++------------------------------------------- - lib/fts_.h | 5 ----- - 2 files changed, 8 insertions(+), 53 deletions(-) - -diff --git a/lib/fts.c b/lib/fts.c -index 1093ce5..dfe3fef 100644 ---- a/lib/fts.c -+++ b/lib/fts.c -@@ -445,7 +445,6 @@ fts_open (char * const *argv, - if ((parent = fts_alloc(sp, "", 0)) == NULL) - goto mem2; - parent->fts_level = FTS_ROOTPARENTLEVEL; -- parent->fts_n_dirs_remaining = -1; - } - - /* The classic fts implementation would call fts_stat with -@@ -634,9 +633,8 @@ fts_close (FTS *sp) - } - - /* Minimum link count of a traditional Unix directory. When leaf -- optimization is OK and MIN_DIR_NLINK <= st_nlink, then st_nlink is -- an upper bound on the number of subdirectories (counting "." and -- ".."). */ -+ optimization is OK and a directory's st_nlink == MIN_DIR_NLINK, -+ then the directory has no subdirectories. */ - enum { MIN_DIR_NLINK = 2 }; - - /* Whether leaf optimization is OK for a directory. */ -@@ -645,12 +643,8 @@ enum leaf_optimization - /* st_nlink is not reliable for this directory's subdirectories. */ - NO_LEAF_OPTIMIZATION, - -- /* Leaf optimization is OK, but is not useful for avoiding stat calls. */ -- OK_LEAF_OPTIMIZATION, -- -- /* Leaf optimization is not only OK: it is useful for avoiding -- stat calls, because dirent.d_type does not work. */ -- NOSTAT_LEAF_OPTIMIZATION -+ /* st_nlink == 2 means the directory lacks subdirectories. */ -+ OK_LEAF_OPTIMIZATION - }; - - #if (defined __linux__ || defined __ANDROID__) \ -@@ -663,9 +657,7 @@ enum leaf_optimization - # define S_MAGIC_CIFS 0xFF534D42 - # define S_MAGIC_NFS 0x6969 - # define S_MAGIC_PROC 0x9FA0 --# define S_MAGIC_REISERFS 0x52654973 - # define S_MAGIC_TMPFS 0x1021994 --# define S_MAGIC_XFS 0x58465342 - - # ifdef HAVE___FSWORD_T - typedef __fsword_t fsword; -@@ -786,23 +778,15 @@ dirent_inode_sort_may_be_useful (FTSENT const *p, int dir_fd) - } - - /* Given an FTS entry P for a directory with descriptor DIR_FD, -- return true if it is both useful and valid to apply leaf optimization. -- The optimization is useful only for file systems that lack usable -- dirent.d_type info. The optimization is valid if an st_nlink value -- of at least MIN_DIR_NLINK is an upper bound on the number of -- subdirectories of D, counting "." and ".." as subdirectories. -+ return whether it is valid to apply leaf optimization. -+ The optimization is valid if a directory's st_nlink value equal -+ to MIN_DIR_NLINK means the directory has no subdirectories. - DIR_FD is negative if unavailable. */ - static enum leaf_optimization - leaf_optimization (FTSENT const *p, int dir_fd) - { - switch (filesystem_type (p, dir_fd)) - { -- /* List here the file system types that may lack usable dirent.d_type -- info, yet for which the optimization does apply. */ -- case S_MAGIC_REISERFS: -- case S_MAGIC_XFS: /* XFS lacked it until 2013-08-22 commit. */ -- return NOSTAT_LEAF_OPTIMIZATION; -- - case 0: - /* Leaf optimization is unsafe if the file system type is unknown. */ - FALLTHROUGH; -@@ -1027,26 +1011,7 @@ check_for_dir: - if (p->fts_info == FTS_NSOK) - { - if (p->fts_statp->st_size == FTS_STAT_REQUIRED) -- { -- FTSENT *parent = p->fts_parent; -- if (parent->fts_n_dirs_remaining == 0 -- && ISSET(FTS_NOSTAT) -- && ISSET(FTS_PHYSICAL) -- && (leaf_optimization (parent, sp->fts_cwd_fd) -- == NOSTAT_LEAF_OPTIMIZATION)) -- { -- /* nothing more needed */ -- } -- else -- { -- p->fts_info = fts_stat(sp, p, false); -- if (S_ISDIR(p->fts_statp->st_mode) -- && p->fts_level != FTS_ROOTLEVEL -- && 0 < parent->fts_n_dirs_remaining -- && parent->fts_n_dirs_remaining != (nlink_t) -1) -- parent->fts_n_dirs_remaining--; -- } -- } -+ p->fts_info = fts_stat(sp, p, false); - else - fts_assert (p->fts_statp->st_size == FTS_NO_STAT_REQUIRED); - } -@@ -1830,11 +1795,6 @@ err: memset(sbp, 0, sizeof(struct stat)); - } - - if (S_ISDIR(sbp->st_mode)) { -- p->fts_n_dirs_remaining -- = ((sbp->st_nlink < MIN_DIR_NLINK -- || p->fts_level <= FTS_ROOTLEVEL) -- ? -1 -- : sbp->st_nlink - (ISSET (FTS_SEEDOT) ? 0 : MIN_DIR_NLINK)); - if (ISDOT(p->fts_name)) { - /* Command-line "." and ".." are real directories. */ - return (p->fts_level == FTS_ROOTLEVEL ? FTS_D : FTS_DOT); -diff --git a/lib/fts_.h b/lib/fts_.h -index d40a116..2e76cc4 100644 ---- a/lib/fts_.h -+++ b/lib/fts_.h -@@ -227,11 +227,6 @@ typedef struct _ftsent { - - size_t fts_namelen; /* strlen(fts_name) */ - -- /* If not (nlink_t) -1, an upper bound on the number of -- remaining subdirectories of interest. If this becomes -- zero, some work can be avoided. */ -- nlink_t fts_n_dirs_remaining; -- - # define FTS_D 1 /* preorder directory */ - # define FTS_DC 2 /* directory that causes cycles */ - # define FTS_DEFAULT 3 /* none of the above */ --- -2.21.1 - diff --git a/coreutils-8.32-ls-removed-dir.patch b/coreutils-8.32-ls-removed-dir.patch deleted file mode 100644 index 77dce89..0000000 --- a/coreutils-8.32-ls-removed-dir.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 8c022656320592dbad146f5d3a3ae1875f419446 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 5 Mar 2020 17:25:29 -0800 -Subject: [PATCH 1/2] 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. - -Upstream-commit: 10fcb97bd728f09d4a027eddf8ad2900f0819b0a -Signed-off-by: Kamil Dudka ---- - src/ls.c | 22 ---------------------- - tests/ls/removed-directory.sh | 10 ++-------- - 2 files changed, 2 insertions(+), 30 deletions(-) - -diff --git a/src/ls.c b/src/ls.c -index 9d25f62..850ecc2 100644 ---- a/src/ls.c -+++ b/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 *realname, bool command_line_arg) - 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 *realname, bool command_line_arg) - 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 *realname, bool command_line_arg) - 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; - -diff --git a/tests/ls/removed-directory.sh b/tests/ls/removed-directory.sh -index e8c835d..fe8f929 100755 ---- a/tests/ls/removed-directory.sh -+++ b/tests/ls/removed-directory.sh -@@ -26,20 +26,14 @@ case $host_triplet in - *) 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_ - --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 --- -2.21.1 - - -From 847324a0debd9d12062c79e7a7a9d3d8ce76390d Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Sat, 7 Mar 2020 10:29:51 -0800 -Subject: [PATCH 2/2] 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). - -Upstream-commit: 672819c73f2e94e61386dc0584bddf9da860cc26 -Signed-off-by: Kamil Dudka ---- - tests/ls/removed-directory.sh | 13 ++++--------- - 1 file changed, 4 insertions(+), 9 deletions(-) - -diff --git a/tests/ls/removed-directory.sh b/tests/ls/removed-directory.sh -index fe8f929..63b209d 100755 ---- a/tests/ls/removed-directory.sh -+++ b/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,15 +21,10 @@ - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ ls - --case $host_triplet in -- *linux*) ;; -- *) skip_ 'non linux kernel' ;; --esac -- - 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" - - ls >../out 2>../err || fail=1 - cd "$cwd" || framework_failure_ --- -2.21.1 - diff --git a/coreutils-8.32-ls-scontext-crash.patch b/coreutils-8.32-ls-scontext-crash.patch deleted file mode 100644 index a3ddff9..0000000 --- a/coreutils-8.32-ls-scontext-crash.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 53c6b01e8e3fd338d7f53e5ff817ef86f9efa852 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Wed, 11 Nov 2020 17:22:33 +0000 -Subject: [PATCH] ls: fix crash printing SELinux context for unstatable files - -This crash was identified by Cyber Independent Testing Lab: -https://cyber-itl.org/2020/10/28/citl-7000-defects.html -and was introduced with commit v6.9.90-11-g4245876e2 - -* src/ls.c (gobble_file): Ensure scontext is initialized -in the case where files are not statable. -* tests/ls/selinux-segfault.sh: Renamed from proc-selinux-segfault.sh, -and added test case for broken symlinks. -* tests/local.mk: Adjust for the renamed test. - -Upstream-commit: 6fc695cb4a26f09dfeef8b1c24895a707055334e -Signed-off-by: Kamil Dudka ---- - src/ls.c | 3 +++ - tests/local.mk | 2 +- - .../{proc-selinux-segfault.sh => selinux-segfault.sh} | 10 ++++++++-- - 3 files changed, 12 insertions(+), 3 deletions(-) - rename tests/ls/{proc-selinux-segfault.sh => selinux-segfault.sh} (77%) - -diff --git a/src/ls.c b/src/ls.c -index 4acf5f4..8eb483d 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -3412,6 +3412,9 @@ gobble_file (char const *name, enum filetype type, ino_t inode, - provokes an exit status of 1. */ - file_failure (command_line_arg, - _("cannot access %s"), full_name); -+ -+ f->scontext = UNKNOWN_SECURITY_CONTEXT; -+ - if (command_line_arg) - return 0; - -diff --git a/tests/local.mk b/tests/local.mk -index 2aeff2b..2441fdc 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -616,7 +616,7 @@ all_tests = \ - tests/ls/multihardlink.sh \ - tests/ls/no-arg.sh \ - tests/ls/no-cap.sh \ -- tests/ls/proc-selinux-segfault.sh \ -+ tests/ls/selinux-segfault.sh \ - tests/ls/quote-align.sh \ - tests/ls/readdir-mountpoint-inode.sh \ - tests/ls/recursive.sh \ -diff --git a/tests/ls/proc-selinux-segfault.sh b/tests/ls/selinux-segfault.sh -similarity index 77% -rename from tests/ls/proc-selinux-segfault.sh -rename to tests/ls/selinux-segfault.sh -index 831a00e..e2b7ef6 100755 ---- a/tests/ls/proc-selinux-segfault.sh -+++ b/tests/ls/selinux-segfault.sh -@@ -1,5 +1,5 @@ - #!/bin/sh --# ls -l /proc/sys would segfault when built against libselinux1 2.0.15-2+b1 -+# Ensure we don't segfault in selinux handling - - # Copyright (C) 2008-2020 Free Software Foundation, Inc. - -@@ -19,9 +19,15 @@ - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src - print_ver_ ls - -+# ls -l /proc/sys would segfault when built against libselinux1 2.0.15-2+b1 - f=/proc/sys - test -r $f || f=. -- - ls -l $f > out || fail=1 - -+# ls <= 8.32 would segfault when printing -+# the security context of broken symlink targets -+mkdir sedir || framework_failure_ -+ln -sf missing sedir/broken || framework_failure_ -+returns_ 1 ls -L -R -Z -m sedir > out || fail=1 -+ - Exit $fail --- -2.26.2 - diff --git a/coreutils-8.32-mem-leaks.patch b/coreutils-8.32-mem-leaks.patch deleted file mode 100644 index 78a90fc..0000000 --- a/coreutils-8.32-mem-leaks.patch +++ /dev/null @@ -1,186 +0,0 @@ -From be77b4ab7cb68fd2daf9de90bd75d844392788ac Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 25 Mar 2021 11:57:56 +0100 -Subject: [PATCH 1/4] ln: fix memory leaks in do_link - -* src/ln.c (do_link): Free memory allocated by convert_abs_rel -on all code paths (Bug#47373). - -Upstream-commit: 6e98f67758260579d7d44ea5f2df4c82d28c9f58 -Signed-off-by: Kamil Dudka ---- - src/ln.c | 19 +++++++++++++------ - 1 file changed, 13 insertions(+), 6 deletions(-) - -diff --git a/src/ln.c b/src/ln.c -index ffa278e..9b52602 100644 ---- a/src/ln.c -+++ b/src/ln.c -@@ -229,14 +229,14 @@ do_link (char const *source, int destdir_fd, char const *dest_base, - if (errno != ENOENT) - { - error (0, errno, _("failed to access %s"), quoteaf (dest)); -- return false; -+ goto fail; - } - force = false; - } - else if (S_ISDIR (dest_stats.st_mode)) - { - error (0, 0, _("%s: cannot overwrite directory"), quotef (dest)); -- return false; -+ goto fail; - } - else if (seen_file (dest_set, dest, &dest_stats)) - { -@@ -245,7 +245,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, - error (0, 0, - _("will not overwrite just-created %s with %s"), - quoteaf_n (0, dest), quoteaf_n (1, source)); -- return false; -+ goto fail; - } - else - { -@@ -274,7 +274,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, - { - error (0, 0, _("%s and %s are the same file"), - quoteaf_n (0, source), quoteaf_n (1, dest)); -- return false; -+ goto fail; - } - } - -@@ -285,7 +285,10 @@ do_link (char const *source, int destdir_fd, char const *dest_base, - fprintf (stderr, _("%s: replace %s? "), - program_name, quoteaf (dest)); - if (!yesno ()) -- return true; -+ { -+ free(rel_source); -+ return true; -+ } - } - - if (backup_type != no_backups) -@@ -304,7 +307,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, - { - error (0, rename_errno, _("cannot backup %s"), - quoteaf (dest)); -- return false; -+ goto fail; - } - force = false; - } -@@ -397,6 +400,10 @@ do_link (char const *source, int destdir_fd, char const *dest_base, - free (backup_base); - free (rel_source); - return link_errno <= 0; -+ -+fail: -+ free (rel_source); -+ return false; - } - - void --- -2.26.3 - - -From c051578e69bd8acf8f8a469566ae34e855345532 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 25 Mar 2021 09:15:50 -0700 -Subject: [PATCH 2/4] maint: indenting - -* src/ln.c: Fix indenting. - -Upstream-commit: 8980b7c898046d899646da01c296fd15f0cced21 -Signed-off-by: Kamil Dudka ---- - src/ln.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/ln.c b/src/ln.c -index 9b52602..8881d6a 100644 ---- a/src/ln.c -+++ b/src/ln.c -@@ -286,7 +286,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, - program_name, quoteaf (dest)); - if (!yesno ()) - { -- free(rel_source); -+ free (rel_source); - return true; - } - } -@@ -304,7 +304,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base, - free (backup_base); - backup_base = NULL; - if (rename_errno != ENOENT) -- { -+ { - error (0, rename_errno, _("cannot backup %s"), - quoteaf (dest)); - goto fail; --- -2.26.3 - - -From 0d6a4afe5bee0e397fb2fc3b205a29b32a69af9d Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 25 Mar 2021 09:16:36 -0700 -Subject: [PATCH 3/4] hostname: use puts - -* src/hostname.c (main): Prefer puts to printf "%s\n". - -Upstream-commit: c7a588ac3632aae21642d4d568497177950d36bf -Signed-off-by: Kamil Dudka ---- - src/hostname.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/hostname.c b/src/hostname.c -index 0b5c0cf..62cc98c 100644 ---- a/src/hostname.c -+++ b/src/hostname.c -@@ -103,7 +103,7 @@ main (int argc, char **argv) - hostname = xgethostname (); - if (hostname == NULL) - die (EXIT_FAILURE, errno, _("cannot determine hostname")); -- printf ("%s\n", hostname); -+ puts (hostname); - } - - if (optind + 1 < argc) --- -2.26.3 - - -From 19c98d2080251edbaad9fb271aa10ad34f953500 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Thu, 25 Mar 2021 11:20:18 -0700 -Subject: [PATCH 4/4] hostname: pacify valgrind - -* src/hostname.c (main) [IF_LINT]: Free hostname (Bug#47384). - -Upstream-commit: 4698e284f37844bc9b9f63f00eb556ccaaed5030 -Signed-off-by: Kamil Dudka ---- - src/hostname.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/hostname.c b/src/hostname.c -index 62cc98c..7210248 100644 ---- a/src/hostname.c -+++ b/src/hostname.c -@@ -104,6 +104,7 @@ main (int argc, char **argv) - if (hostname == NULL) - die (EXIT_FAILURE, errno, _("cannot determine hostname")); - puts (hostname); -+ IF_LINT (free (hostname)); - } - - if (optind + 1 < argc) --- -2.26.3 - diff --git a/coreutils-8.32-new-fs-types.patch b/coreutils-8.32-new-fs-types.patch deleted file mode 100644 index a8eb35c..0000000 --- a/coreutils-8.32-new-fs-types.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 09400b7f7f48d8eedc0df55de8073a43bc0aac96 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Tue, 27 Oct 2020 20:15:43 +0000 -Subject: [PATCH 1/2] stat,tail: sync file system constants from the linux - kernel - -* src/stat.c: Add magic constants for "devmem", and -"zonefs" file systems. -* NEWS: Mention the improvement. - -Upstream-commit: ff80b6b0a0507e24f39cc1aad09d147f5187430b -Signed-off-by: Kamil Dudka ---- - src/stat.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/stat.c b/src/stat.c -index 5012622..8cd69da 100644 ---- a/src/stat.c -+++ b/src/stat.c -@@ -347,6 +347,8 @@ human_fstype (STRUCT_STATVFS const *statfsbuf) - return "debugfs"; - case S_MAGIC_DEVFS: /* 0x1373 local */ - return "devfs"; -+ case S_MAGIC_DEVMEM: /* 0x454D444D local */ -+ return "devmem"; - case S_MAGIC_DEVPTS: /* 0x1CD1 local */ - return "devpts"; - case S_MAGIC_DMA_BUF: /* 0x444D4142 local */ -@@ -549,6 +551,8 @@ human_fstype (STRUCT_STATVFS const *statfsbuf) - return "z3fold"; - case S_MAGIC_ZFS: /* 0x2FC12FC1 local */ - return "zfs"; -+ case S_MAGIC_ZONEFS: /* 0x5A4F4653 local */ -+ return "zonefs"; - case S_MAGIC_ZSMALLOC: /* 0x58295829 local */ - return "zsmallocfs"; - --- -2.25.4 - - -From d5948fd41013dfe4d2d10083111821667977c6d1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Tue, 27 Oct 2020 21:04:14 +0000 -Subject: [PATCH 2/2] mountlist: recognize more file system types as remote - -Sync "remote" file systems from stat.c in coreutils. -Note we only consider file systems that do not use host:resource -mount source. I.e. those that don't generally use a colon when -mounting, as that case is already considered. Searching for -" /etc/fstab" was informative for identifying these. -The full list of "remote" file systems in coreutils is currently: - acfs afs ceph cifs coda fhgfs fuseblk fusectl - gfs gfs2 gpfs ibrix k-afs lustre novell nfs nfsd - ocfs2 panfs prl_fs smb smb2 snfs vboxsf vmhgfs vxfs -Note also we do not include virtual machine file systems, -as even though they're remote to the current kernel, -they are generally not distributed to separate hosts. - -* lib/mountlist.c (ME_REMOTE): Sync previously unconsidered -"remote" file systems from stat.c in coreutils. - -Upstream-commit: dd1fc46be12d671c1a9d9dc5a6fa8c766e99aa2f -Signed-off-by: Kamil Dudka ---- - lib/mountlist.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/lib/mountlist.c b/lib/mountlist.c -index 7abe024..e0227b7 100644 ---- a/lib/mountlist.c -+++ b/lib/mountlist.c -@@ -221,8 +221,9 @@ me_remote (char const *fs_name, char const *fs_type _GL_UNUSED) - #ifndef ME_REMOTE - /* A file system is "remote" if its Fs_name contains a ':' - or if (it is of type (smbfs or cifs) and its Fs_name starts with '//') -- or if it is of type (afs or auristorfs) -- or Fs_name is equal to "-hosts" (used by autofs to mount remote fs). */ -+ or if it is of any other of the listed types -+ or Fs_name is equal to "-hosts" (used by autofs to mount remote fs). -+ "VM" file systems like prl_fs or vboxsf are not considered remote here. */ - # define ME_REMOTE(Fs_name, Fs_type) \ - (strchr (Fs_name, ':') != NULL \ - || ((Fs_name)[0] == '/' \ -@@ -230,8 +231,15 @@ me_remote (char const *fs_name, char const *fs_type _GL_UNUSED) - && (strcmp (Fs_type, "smbfs") == 0 \ - || strcmp (Fs_type, "smb3") == 0 \ - || strcmp (Fs_type, "cifs") == 0)) \ -+ || strcmp (Fs_type, "acfs") == 0 \ - || strcmp (Fs_type, "afs") == 0 \ -+ || strcmp (Fs_type, "coda") == 0 \ - || strcmp (Fs_type, "auristorfs") == 0 \ -+ || strcmp (Fs_type, "fhgfs") == 0 \ -+ || strcmp (Fs_type, "gpfs") == 0 \ -+ || strcmp (Fs_type, "ibrix") == 0 \ -+ || strcmp (Fs_type, "ocfs2") == 0 \ -+ || strcmp (Fs_type, "vxfs") == 0 \ - || strcmp ("-hosts", Fs_name) == 0) - #endif - --- -2.25.4 - diff --git a/coreutils-8.32-rm-stray-skip.patch b/coreutils-8.32-rm-stray-skip.patch deleted file mode 100644 index 66a1efc..0000000 --- a/coreutils-8.32-rm-stray-skip.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 11b37b65d08c2a8b6d967fd866ebbdbe7e864949 Mon Sep 17 00:00:00 2001 -From: Nishant Nayan -Date: Thu, 26 Nov 2020 14:35:17 +0000 -Subject: [PATCH] rm: do not skip files upon failure to remove an empty dir - -When removing a directory fails for some reason, and that directory -is empty, the rm_fts code gets the return value of the excise call -confused with the return value of its earlier call to prompt, -causing fts_skip_tree to be called again and the next file -that rm would otherwise have deleted to survive. - -* src/remove.c (rm_fts): Ensure we only skip a single fts entry, -when processing empty dirs. I.e. only skip the entry -having successfully removed it. -* tests/rm/empty-immutable-skip.sh: New root-only test. -* tests/local.mk: Add it. -* NEWS: Mention the bug fix. -Fixes https://bugs.gnu.org/44883 - -Upstream-commit: 6bf108358a6104ec1c694c9530b3cd56b95f4b57 -Signed-off-by: Kamil Dudka ---- - src/remove.c | 3 ++- - tests/local.mk | 1 + - tests/rm/empty-immutable-skip.sh | 46 ++++++++++++++++++++++++++++++++ - 3 files changed, 49 insertions(+), 1 deletion(-) - create mode 100755 tests/rm/empty-immutable-skip.sh - -diff --git a/src/remove.c b/src/remove.c -index 2d40c55..adf9489 100644 ---- a/src/remove.c -+++ b/src/remove.c -@@ -506,7 +506,8 @@ rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x) - /* When we know (from prompt when in interactive mode) - that this is an empty directory, don't prompt twice. */ - s = excise (fts, ent, x, true); -- fts_skip_tree (fts, ent); -+ if (s == RM_OK) -+ fts_skip_tree (fts, ent); - } - - if (s != RM_OK) -diff --git a/tests/local.mk b/tests/local.mk -index 5f7f775..2aeff2b 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -136,6 +136,7 @@ all_root_tests = \ - tests/rm/no-give-up.sh \ - tests/rm/one-file-system.sh \ - tests/rm/read-only.sh \ -+ tests/rm/empty-immutable-skip.sh \ - tests/tail-2/append-only.sh \ - tests/tail-2/end-of-device.sh \ - tests/touch/now-owned-by-other.sh -diff --git a/tests/rm/empty-immutable-skip.sh b/tests/rm/empty-immutable-skip.sh -new file mode 100755 -index 0000000..c91d8d4 ---- /dev/null -+++ b/tests/rm/empty-immutable-skip.sh -@@ -0,0 +1,46 @@ -+#!/bin/sh -+# Ensure that rm does not skip extra files after hitting an empty immutable dir. -+# Requires root access to do chattr +i, as well as an ext[23] or xfs file system -+ -+# Copyright (C) 2020 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_ rm -+require_root_ -+ -+# These simple one-file operations are expected to work even in the -+# presence of this bug, and we need them to set up the rest of the test. -+chattr_i_works=1 -+touch f -+chattr +i f 2>/dev/null || chattr_i_works=0 -+rm f 2>/dev/null -+test -f f || chattr_i_works=0 -+chattr -i f 2>/dev/null || chattr_i_works=0 -+rm f 2>/dev/null || chattr_i_works=0 -+test -f f && chattr_i_works=0 -+ -+if test $chattr_i_works = 0; then -+ skip_ "chattr +i doesn't work on this file system" -+fi -+ -+mkdir empty || framework_failure_ -+touch x y || framework_failure_ -+chattr +i empty || framework_failure_ -+rm -rf empty x y -+{ test -f x || test -f y; } && fail=1 -+chattr -i empty -+ -+Exit $fail --- -2.26.2 - diff --git a/coreutils-8.32-split-number.patch b/coreutils-8.32-split-number.patch deleted file mode 100644 index 89541bf..0000000 --- a/coreutils-8.32-split-number.patch +++ /dev/null @@ -1,100 +0,0 @@ -From bb0e7fabcaed9a7e71e30f05e638e9f243cdb13e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Mon, 25 Jan 2021 14:12:48 +0000 -Subject: [PATCH] split: fix --number=K/N to output correct part of file - -This functionality regressed with the adjustments -in commit v8.25-4-g62e7af032 - -* src/split.c (bytes_chunk_extract): Account for already read data -when seeking into the file. -* tests/split/b-chunk.sh: Use the hidden ---io-blksize option, -to test this functionality. -Fixes https://bugs.gnu.org/46048 - -Upstream-commit: bb21daa125aeb4e32546309d370918ca47e612db -Signed-off-by: Kamil Dudka ---- - src/split.c | 2 +- - tests/split/b-chunk.sh | 45 ++++++++++++++++++++++++------------------ - 2 files changed, 27 insertions(+), 20 deletions(-) - -diff --git a/src/split.c b/src/split.c -index 09e610b..19248f6 100644 ---- a/src/split.c -+++ b/src/split.c -@@ -1001,7 +1001,7 @@ bytes_chunk_extract (uintmax_t k, uintmax_t n, char *buf, size_t bufsize, - } - else - { -- if (lseek (STDIN_FILENO, start, SEEK_CUR) < 0) -+ if (lseek (STDIN_FILENO, start - initial_read, SEEK_CUR) < 0) - die (EXIT_FAILURE, errno, "%s", quotef (infile)); - initial_read = SIZE_MAX; - } -diff --git a/tests/split/b-chunk.sh b/tests/split/b-chunk.sh -index 864ce55..39a6799 100755 ---- a/tests/split/b-chunk.sh -+++ b/tests/split/b-chunk.sh -@@ -35,32 +35,39 @@ split -e -n 10 /dev/null || fail=1 - returns_ 1 stat x?? 2>/dev/null || fail=1 - - printf '1\n2\n3\n4\n5\n' > input || framework_failure_ -+printf '1\n2' > exp-1 || framework_failure_ -+printf '\n3\n' > exp-2 || framework_failure_ -+printf '4\n5\n' > exp-3 || framework_failure_ - - for file in input /proc/version /sys/kernel/profiling; do - test -f $file || continue - -- split -n 3 $file > out || fail=1 -- split -n 1/3 $file > b1 || fail=1 -- split -n 2/3 $file > b2 || fail=1 -- split -n 3/3 $file > b3 || fail=1 -+ for blksize in 1 2 4096; do -+ if ! test "$file" = 'input'; then -+ # For /proc like files we must be able to read all -+ # into the internal buffer to be able to determine size. -+ test "$blksize" = 4096 || continue -+ fi - -- case $file in -- input) -- printf '1\n2' > exp-1 -- printf '\n3\n' > exp-2 -- printf '4\n5\n' > exp-3 -+ split -n 3 ---io-blksize=$blksize $file > out || fail=1 -+ split -n 1/3 ---io-blksize=$blksize $file > b1 || fail=1 -+ split -n 2/3 ---io-blksize=$blksize $file > b2 || fail=1 -+ split -n 3/3 ---io-blksize=$blksize $file > b3 || fail=1 - -- compare exp-1 xaa || fail=1 -- compare exp-2 xab || fail=1 -- compare exp-3 xac || fail=1 -- ;; -- esac -+ case $file in -+ input) -+ compare exp-1 xaa || fail=1 -+ compare exp-2 xab || fail=1 -+ compare exp-3 xac || fail=1 -+ ;; -+ esac - -- compare xaa b1 || fail=1 -- compare xab b2 || fail=1 -- compare xac b3 || fail=1 -- cat xaa xab xac | compare - $file || fail=1 -- test -f xad && fail=1 -+ compare xaa b1 || fail=1 -+ compare xab b2 || fail=1 -+ compare xac b3 || fail=1 -+ cat xaa xab xac | compare - $file || fail=1 -+ test -f xad && fail=1 -+ done - done - - Exit $fail --- -2.26.2 - diff --git a/coreutils-8.32-stat-exfat.patch b/coreutils-8.32-stat-exfat.patch deleted file mode 100644 index ea8d0cd..0000000 --- a/coreutils-8.32-stat-exfat.patch +++ /dev/null @@ -1,32 +0,0 @@ -From b87f944c87ffe04db6e5476b007a8e4979de933d Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 18 Feb 2021 11:18:04 +0100 -Subject: [PATCH] stat,tail: add support for the exfat file system - -Bug: https://bugzilla.redhat.com/1921427 - -* src/stat.c (human_fstype): Add case for the 'exfat' file system type. -Fixes https://bugs.gnu.org/46613 - -Upstream-commit: a5e0d8f387e81e854427addbbaf2504541bbf4b9 -Signed-off-by: Kamil Dudka ---- - src/stat.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/stat.c b/src/stat.c -index 8cd69da..4e1c8e3 100644 ---- a/src/stat.c -+++ b/src/stat.c -@@ -361,6 +361,8 @@ human_fstype (STRUCT_STATVFS const *statfsbuf) - return "efs"; - case S_MAGIC_EROFS_V1: /* 0xE0F5E1E2 local */ - return "erofs"; -+ case S_MAGIC_EXFAT: /* 0x2011BAB0 local */ -+ return "exfat"; - case S_MAGIC_EXFS: /* 0x45584653 local */ - return "exfs"; - case S_MAGIC_EXOFS: /* 0x5DF5 local */ --- -2.26.2 - diff --git a/coreutils-8.32-tail-use-poll.patch b/coreutils-8.32-tail-use-poll.patch deleted file mode 100644 index ed3a8f3..0000000 --- a/coreutils-8.32-tail-use-poll.patch +++ /dev/null @@ -1,181 +0,0 @@ -From c7a04cef4075da864a3468e63a5bb79334d8f556 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Sat, 26 Jun 2021 18:23:52 -0700 -Subject: [PATCH] tail: use poll, not select -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes an unlikely stack out-of-bounds write reported by -Stepan Broz via Kamil Dudka (Bug#49209). -* src/tail.c: Do not include . -[!_AIX]: Include poll.h. -(check_output_alive) [!_AIX]: Use poll instead of select. -(tail_forever_inotify): Likewise. Simplify logic, as there is no -need for a ‘while (len <= evbuf_off)’ loop. - -Upstream-commit: da0d448bca62c6305fc432f67e2c5ccc2da75346 -Signed-off-by: Kamil Dudka ---- - src/tail.c | 100 +++++++++++++++++++++-------------------------------- - 1 file changed, 39 insertions(+), 61 deletions(-) - -diff --git a/src/tail.c b/src/tail.c -index 1c88723..5b4f21a 100644 ---- a/src/tail.c -+++ b/src/tail.c -@@ -28,12 +28,9 @@ - #include - #include - #include --#include -+#include - #include - #include --#ifdef _AIX --# include --#endif - - #include "system.h" - #include "argmatch.h" -@@ -351,27 +348,12 @@ check_output_alive (void) - if (! monitor_output) - return; - --#ifdef _AIX -- /* select on AIX was seen to give a readable event immediately. */ - struct pollfd pfd; - pfd.fd = STDOUT_FILENO; - pfd.events = POLLERR; - - if (poll (&pfd, 1, 0) >= 0 && (pfd.revents & POLLERR)) - die_pipe (); --#else -- struct timeval delay; -- delay.tv_sec = delay.tv_usec = 0; -- -- fd_set rfd; -- FD_ZERO (&rfd); -- FD_SET (STDOUT_FILENO, &rfd); -- -- /* readable event on STDOUT is equivalent to POLLERR, -- and implies an error condition on output like broken pipe. */ -- if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1) -- die_pipe (); --#endif - } - - static bool -@@ -1612,7 +1594,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files, - /* Wait for inotify events and handle them. Events on directories - ensure that watched files can be re-added when following by name. - This loop blocks on the 'safe_read' call until a new event is notified. -- But when --pid=P is specified, tail usually waits via the select. */ -+ But when --pid=P is specified, tail usually waits via poll. */ - while (1) - { - struct File_spec *fspec; -@@ -1629,54 +1611,51 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files, - return false; - } - -- /* When watching a PID, ensure that a read from WD will not block -- indefinitely. */ -- while (len <= evbuf_off) -+ if (len <= evbuf_off) - { -- struct timeval delay; /* how long to wait for file changes. */ -+ /* Poll for inotify events. When watching a PID, ensure -+ that a read from WD will not block indefinitely. -+ If MONITOR_OUTPUT, also poll for a broken output pipe. */ - -- if (pid) -+ int file_change; -+ struct pollfd pfd[2]; -+ do - { -- if (writer_is_dead) -- exit (EXIT_SUCCESS); -+ /* How many ms to wait for changes. -1 means wait forever. */ -+ int delay = -1; - -- writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM); -- -- if (writer_is_dead) -- delay.tv_sec = delay.tv_usec = 0; -- else -+ if (pid) - { -- delay.tv_sec = (time_t) sleep_interval; -- delay.tv_usec = 1000000 * (sleep_interval - delay.tv_sec); -+ if (writer_is_dead) -+ exit (EXIT_SUCCESS); -+ -+ writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM); -+ -+ if (writer_is_dead || sleep_interval <= 0) -+ delay = 0; -+ else if (sleep_interval < INT_MAX / 1000 - 1) -+ { -+ /* delay = ceil (sleep_interval * 1000), sans libm. */ -+ double ddelay = sleep_interval * 1000; -+ delay = ddelay; -+ delay += delay < ddelay; -+ } - } -+ -+ pfd[0].fd = wd; -+ pfd[0].events = POLLIN; -+ pfd[1].fd = STDOUT_FILENO; -+ pfd[1].events = pfd[1].revents = 0; -+ file_change = poll (pfd, monitor_output + 1, delay); - } -+ while (file_change == 0); - -- fd_set rfd; -- FD_ZERO (&rfd); -- FD_SET (wd, &rfd); -- if (monitor_output) -- FD_SET (STDOUT_FILENO, &rfd); -- -- int file_change = select (MAX (wd, STDOUT_FILENO) + 1, -- &rfd, NULL, NULL, pid ? &delay: NULL); -- -- if (file_change == 0) -- continue; -- else if (file_change == -1) -- die (EXIT_FAILURE, errno, -- _("error waiting for inotify and output events")); -- else if (FD_ISSET (STDOUT_FILENO, &rfd)) -- { -- /* readable event on STDOUT is equivalent to POLLERR, -- and implies an error on output like broken pipe. */ -- die_pipe (); -- } -- else -- break; -- } -+ if (file_change < 0) -+ die (EXIT_FAILURE, errno, -+ _("error waiting for inotify and output events")); -+ if (pfd[1].revents) -+ die_pipe (); - -- if (len <= evbuf_off) -- { - len = safe_read (wd, evbuf, evlen); - evbuf_off = 0; - -@@ -2437,8 +2416,7 @@ main (int argc, char **argv) - if (forever && ignore_fifo_and_pipe (F, n_files)) - { - /* If stdout is a fifo or pipe, then monitor it -- so that we exit if the reader goes away. -- Note select() on a regular file is always readable. */ -+ so that we exit if the reader goes away. */ - struct stat out_stat; - if (fstat (STDOUT_FILENO, &out_stat) < 0) - die (EXIT_FAILURE, errno, _("standard output")); --- -2.31.1 - diff --git a/coreutils-8.32-tests-false-positives.patch b/coreutils-8.32-tests-false-positives.patch deleted file mode 100644 index 0b0a301..0000000 --- a/coreutils-8.32-tests-false-positives.patch +++ /dev/null @@ -1,99 +0,0 @@ -From fc6318841f008dadc1e7c93e539f10d24aa83e90 Mon Sep 17 00:00:00 2001 -From: Bernhard Voelker -Date: Wed, 21 Apr 2021 00:12:00 +0200 -Subject: [PATCH 1/2] tests: fix FP in ls/stat-free-color.sh - -On newer systems like Fedora 34 and openSUSE Tumbleweed, ls(1) calls -newfstatat(STDOUT_FILENO, ...), but only when there is something to -output. - -* tests/ls/stat-free-color.sh: Add -a option to the reference invocation -of ls, thus enforcing something gets output. - -Upstream-commit: b7091093bb6505c33279f9bc940b2e94763a6e5d -Signed-off-by: Kamil Dudka ---- - tests/ls/stat-free-color.sh | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/tests/ls/stat-free-color.sh b/tests/ls/stat-free-color.sh -index 00942f7..87bed1c 100755 ---- a/tests/ls/stat-free-color.sh -+++ b/tests/ls/stat-free-color.sh -@@ -56,12 +56,14 @@ eval $(dircolors -b color-without-stat) - # The system may perform additional stat-like calls before main. - # Furthermore, underlying library functions may also implicitly - # add an extra stat call, e.g. opendir since glibc-2.21-360-g46f894d. --# To avoid counting those, first get a baseline count for running --# ls with one empty directory argument. Then, compare that with the --# invocation under test. -+# Finally, ls(1) makes a stat call for stdout, but only in the case -+# when there is something to output. -+# To get the comparison right, first get a baseline count for running -+# 'ls -a' with one empty directory argument. Then, compare that with -+# the invocation under test. - mkdir d || framework_failure_ - --strace -q -o log1 -e $stats ls --color=always d || fail=1 -+strace -q -o log1 -e $stats ls -a --color=always d || fail=1 - n_stat1=$(grep -vF '+++' log1 | wc -l) || framework_failure_ - - test $n_stat1 = 0 \ --- -2.31.1 - - -From c16ca58f17a088e925c0d1c4015c48332c380a00 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sun, 9 May 2021 23:41:00 +0100 -Subject: [PATCH 2/2] tests: fix tests/cp/sparse-2.sh false failure on some - systems - -* tests/cp/sparse-2.sh: Double check cp --sparse=always, -with dd conv=sparse, in the case where the former didn't -create a sparse file. Now that this test is being newly run -on macos, we're seeing a failure due to seek() not creating -holes on apfs unless the size is >= 16MiB. - -Upstream-commit: 6b499720fecae935dc00e236d6aefe94d9010482 -Signed-off-by: Kamil Dudka ---- - tests/cp/fiemap-2.sh | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/tests/cp/fiemap-2.sh b/tests/cp/fiemap-2.sh -index 548a376..e20ce54 100755 ---- a/tests/cp/fiemap-2.sh -+++ b/tests/cp/fiemap-2.sh -@@ -17,7 +17,7 @@ - # along with this program. If not, see . - - . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src --print_ver_ cp -+print_ver_ cp stat dd - - # Require a fiemap-enabled FS. - touch fiemap_chk # check a file rather than current dir for best coverage -@@ -46,10 +46,17 @@ dd bs=1k seek=1 of=k count=255 < /dev/zero || framework_failure_ - - # cp should detect the all-zero blocks and convert some of them to holes. - # How many it detects/converts currently depends on io_blksize. --# Currently, on my F14/ext4 desktop, this K starts off with size 256KiB, -+# Currently, on my F14/ext4 desktop, this K file starts off with size 256KiB, - # (note that the K in the preceding test starts off with size 4KiB). - # cp from coreutils-8.9 with --sparse=always reduces the size to 32KiB. - cp --sparse=always k k2 || fail=1 --test $(stat -c %b k2) -lt $(stat -c %b k) || fail=1 -+if test $(stat -c %b k2) -ge $(stat -c %b k); then -+ # If not sparse, then double check by creating with dd -+ # as we're not guaranteed that seek will create a hole. -+ # apfs on darwin 19.2.0 for example was seen to not to create holes < 16MiB. -+ hole_size=$(stat -c %o k2) || framework_failure_ -+ dd if=k of=k2.dd bs=$hole_size conv=sparse || framework_failure_ -+ test $(stat -c %b k2) -eq $(stat -c %b k2.dd) || fail=1 -+fi - - Exit $fail --- -2.31.1 - diff --git a/coreutils-8.32.tar.xz.sig b/coreutils-8.32.tar.xz.sig deleted file mode 100644 index e1420fc..0000000 --- a/coreutils-8.32.tar.xz.sig +++ /dev/null @@ -1,16 +0,0 @@ ------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-8.4-mkdir-modenote.patch b/coreutils-8.4-mkdir-modenote.patch index 51a129e..3973d44 100644 --- a/coreutils-8.4-mkdir-modenote.patch +++ b/coreutils-8.4-mkdir-modenote.patch @@ -2,7 +2,7 @@ diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 400e135..47e4480 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -10074,6 +10074,8 @@ incorrect. @xref{Directory Setuid and Setgid}, for how the +@@ -10829,6 +10829,8 @@ incorrect. @xref{Directory Setuid and Setgid}, for how the set-user-ID and set-group-ID bits of directories are inherited unless overridden in this way. diff --git a/coreutils-9.0.tar.xz.sig b/coreutils-9.0.tar.xz.sig new file mode 100644 index 0000000..d9d405f --- /dev/null +++ b/coreutils-9.0.tar.xz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEEbDfcEhIaUAa8HbgE32/ZcTBgN9kFAmFN1c4ACgkQ32/ZcTBg +N9mtfw/8D8BJrt2Ver2xdPfow5FYHT/zakUQ2b3ZIHP0Es62W56+pWtGombphrZu +4PkI1x6i4S8z06O9rWPIDGMPjyPV9UJbzAiGC7Px6tW6RFHZx0M+GNsKfcjmhtf7 +0v3jFF0g1IdrikFG1aYCAHZHy7n+yOm7xsfSmlYVlKcOVbCFN92ZBw0IohOSriSq +nJN6IOY8I3frhuI5kchY4wM6RMQ+ztNtG8odNvJI3kWCCL9pQFxzD8uorrvTiAcp +Qdbfz5TDnlVcXKR1gu6AAP+XThUYuxG5t/2Kghlril1zxnbDBZJsGteevyHsS7kY +grAWY4XqSvKVURGaKSSUhXlriQilPknBaichwEhAXvrUk1giviAzZ8CXB6WzzTvn +E9+ofC8RqTu345+ixkdZZu0TauOZWYIUVzKsD7W0ooQOT7OZeIQfb3+pbves/I+k +ZyiRLxfiUkAkKMUDrMr+okhqFA9fo/GCkFmHWj9m2NAc15kifEpSiCktfgoChbeG +ZiQFXQz090P+L1pk82qBXVgTjUyS5VEnXZoIkTWGzkHKySwreiaIjPQhS3cU2xAm +24i53zidj84Ib62Xa4jwxX7BzZqYRdbWAa/BUUNMov75W4dfkPlZ6qbRXtKnoOZf +u0ok3fgFvopGzwbw3l/HFp58jpaYL5S28gy10PpdOnxeO54XBn0= +=3TCC +-----END PGP SIGNATURE----- diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 248a6ae..7574373 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,8 +1,20 @@ +From 6e36198f10a2f63b89c89ebb5d5c185b20fb3a63 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 29 Mar 2010 17:20:34 +0000 +Subject: [PATCH] coreutils-df-direct.patch + +--- + doc/coreutils.texi | 7 ++++++ + src/df.c | 36 ++++++++++++++++++++++++++++-- + tests/df/direct.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 96 insertions(+), 2 deletions(-) + create mode 100755 tests/df/direct.sh + diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index a507280..400e135 100644 +index 5b9a597..6810c15 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -11303,6 +11303,13 @@ some systems (notably SunOS), doing this yields more up to date results, +@@ -12067,6 +12067,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -15,12 +27,12 @@ index a507280..400e135 100644 + @item --total @opindex --total - @cindex grand total of disk size, usage and available space + @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 8f760db..a7385fd 100644 +index 48025b9..c8efa5b 100644 --- a/src/df.c +++ b/src/df.c -@@ -120,6 +120,9 @@ static bool print_type; +@@ -125,6 +125,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -30,7 +42,7 @@ index 8f760db..a7385fd 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -247,13 +250,15 @@ enum +@@ -252,13 +255,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -47,7 +59,7 @@ index 8f760db..a7385fd 100644 {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, -@@ -509,7 +514,10 @@ get_header (void) +@@ -583,7 +588,10 @@ get_header (void) for (col = 0; col < ncolumns; col++) { char *cell = NULL; @@ -59,7 +71,7 @@ index 8f760db..a7385fd 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1397,6 +1405,19 @@ get_point (const char *point, const struct stat *statp) +@@ -1486,6 +1494,19 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -77,9 +89,9 @@ index 8f760db..a7385fd 100644 + } + if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) - && get_disk (name)) + && get_device (name)) return; -@@ -1467,6 +1488,7 @@ or all file systems by default.\n\ +@@ -1556,6 +1577,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -87,7 +99,7 @@ index 8f760db..a7385fd 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1557,6 +1579,9 @@ main (int argc, char **argv) +@@ -1646,6 +1668,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -97,7 +109,7 @@ index 8f760db..a7385fd 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1653,6 +1678,13 @@ main (int argc, char **argv) +@@ -1742,6 +1767,13 @@ main (int argc, char **argv) } } @@ -172,3 +184,6 @@ index 0000000..8e4cfb8 +compare file_out file_exp || fail=1 + +Exit $fail +-- +2.31.1 + diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch index 5349337..93eef67 100644 --- a/coreutils-getgrouplist.patch +++ b/coreutils-getgrouplist.patch @@ -29,7 +29,7 @@ index 76474c2..0a9d221 100644 #include "xalloc-oversized.h" /* Work around an incompatibility of OS X 10.11: getgrouplist -@@ -121,9 +122,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) +@@ -119,9 +120,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) /* else no username, so fall through and use getgroups. */ #endif @@ -50,7 +50,7 @@ index 76474c2..0a9d221 100644 /* If we failed to count groups because there is no supplemental group support, then return an array containing just GID. -@@ -145,10 +154,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) +@@ -143,10 +152,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) if (g == NULL) return -1; @@ -84,7 +84,7 @@ diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 index 62777c7..5180243 100644 --- a/m4/jm-macros.m4 +++ b/m4/jm-macros.m4 -@@ -82,6 +82,7 @@ AC_DEFUN([coreutils_MACROS], +@@ -68,6 +68,7 @@ AC_DEFUN([coreutils_MACROS], fchown fchmod ftruncate diff --git a/coreutils-i18n-expand-unexpand.patch b/coreutils-i18n-expand-unexpand.patch index 32089cf..a84e3c3 100644 --- a/coreutils-i18n-expand-unexpand.patch +++ b/coreutils-i18n-expand-unexpand.patch @@ -1,4 +1,4 @@ -From e87ab5b991b08092a7e07af82b3ec822a8604151 Mon Sep 17 00:00:00 2001 +From bde345889debed9041dec0710b1edc78821ced21 Mon Sep 17 00:00:00 2001 From: Ondrej Oprala Date: Wed, 5 Aug 2015 09:15:09 +0200 Subject: [PATCH] expand,unexpand: add multibyte support @@ -20,15 +20,15 @@ Co-authored-by: Pádraig Brady bootstrap.conf | 1 + configure.ac | 2 + lib/mbfile.c | 3 + - lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++ m4/mbfile.m4 | 14 +++ - src/expand.c | 43 +++++---- + src/expand.c | 43 +++++--- src/local.mk | 4 +- - src/unexpand.c | 54 +++++++---- - tests/expand/mb.sh | 98 ++++++++++++++++++++ + src/unexpand.c | 54 ++++++--- + tests/expand/mb.sh | 98 +++++++++++++++++ tests/local.mk | 2 + - tests/unexpand/mb.sh | 97 ++++++++++++++++++++ - 10 files changed, 535 insertions(+), 34 deletions(-) + tests/unexpand/mb.sh | 97 ++++++++++++++++ + 11 files changed, 537 insertions(+), 36 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -36,10 +36,10 @@ Co-authored-by: Pádraig Brady create mode 100755 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 8a0ff31..a1c78b2 100644 +index aef9ec7..9486e9d 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -152,6 +152,7 @@ gnulib_modules=" +@@ -156,6 +156,7 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -48,10 +48,10 @@ index 8a0ff31..a1c78b2 100644 mbrtowc mbsalign diff --git a/configure.ac b/configure.ac -index 1e74b36..24c9725 100644 +index 6960b48..8ff85f8 100644 --- a/configure.ac +++ b/configure.ac -@@ -427,6 +427,8 @@ fi +@@ -457,6 +457,8 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -351,7 +351,7 @@ index 0000000..8589902 + : +]) diff --git a/src/expand.c b/src/expand.c -index 9fa2e10..380e020 100644 +index 4e32bfc..28809b0 100644 --- a/src/expand.c +++ b/src/expand.c @@ -37,6 +37,9 @@ @@ -363,8 +363,8 @@ index 9fa2e10..380e020 100644 + #include "system.h" #include "die.h" - #include "xstrndup.h" -@@ -100,19 +103,19 @@ expand (void) + +@@ -97,19 +100,19 @@ expand (void) { /* Input stream. */ FILE *fp = next_file (NULL); @@ -388,7 +388,7 @@ index 9fa2e10..380e020 100644 /* The following variables have valid values only when CONVERT is true: */ -@@ -122,17 +125,23 @@ expand (void) +@@ -119,17 +122,23 @@ expand (void) /* Index in TAB_LIST of next tab stop to examine. */ size_t tab_index = 0; @@ -416,7 +416,7 @@ index 9fa2e10..380e020 100644 { /* Column the next input tab stop is on. */ uintmax_t next_tab_column; -@@ -151,32 +160,34 @@ expand (void) +@@ -148,32 +157,34 @@ expand (void) if (putchar (' ') < 0) die (EXIT_FAILURE, errno, _("write error")); @@ -460,22 +460,22 @@ index 9fa2e10..380e020 100644 } diff --git a/src/local.mk b/src/local.mk -index 72db9c704..ef3bfa469 100644 +index 0c8b65d..011421a 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -415,8 +415,8 @@ src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) - - src_ginstall_CPPFLAGS = -DENABLE_MATCHPATHCON=1 $(AM_CPPFLAGS) +@@ -429,8 +429,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) + src_basenc_SOURCES = src/basenc.c + src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) -src_expand_SOURCES = src/expand.c src/expand-common.c -src_unexpand_SOURCES = src/unexpand.c src/expand-common.c +src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c +src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c - # Ensure we don't link against libcoreutils.a as that lib is - # not compiled with -fPIC which causes issues on 64 bit at least + src_wc_SOURCES = src/wc.c + if USE_AVX2_WC_LINECOUNT diff --git a/src/unexpand.c b/src/unexpand.c -index 7801274..569a7ee 100644 +index cec392d..02f18f9 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -38,6 +38,9 @@ @@ -487,8 +487,8 @@ index 7801274..569a7ee 100644 + #include "system.h" #include "die.h" - #include "xstrndup.h" -@@ -107,11 +110,12 @@ unexpand (void) + +@@ -106,11 +109,12 @@ unexpand (void) { /* Input stream. */ FILE *fp = next_file (NULL); @@ -502,7 +502,7 @@ index 7801274..569a7ee 100644 if (!fp) return; -@@ -119,12 +123,14 @@ unexpand (void) +@@ -118,12 +122,14 @@ unexpand (void) /* 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. */ @@ -519,7 +519,7 @@ index 7801274..569a7ee 100644 /* If true, perform translations. */ bool convert = true; -@@ -158,12 +164,19 @@ unexpand (void) +@@ -157,12 +163,19 @@ unexpand (void) do { @@ -542,7 +542,7 @@ index 7801274..569a7ee 100644 if (blank) { -@@ -180,16 +193,16 @@ unexpand (void) +@@ -179,16 +192,16 @@ unexpand (void) if (next_tab_column < column) die (EXIT_FAILURE, 0, _("input line is too long")); @@ -562,7 +562,7 @@ index 7801274..569a7ee 100644 if (! (prev_blank && column == next_tab_column)) { -@@ -197,13 +210,14 @@ unexpand (void) +@@ -196,13 +209,14 @@ unexpand (void) will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -579,7 +579,7 @@ index 7801274..569a7ee 100644 } /* Discard pending blanks, unless it was a single -@@ -211,7 +225,7 @@ unexpand (void) +@@ -210,7 +224,7 @@ unexpand (void) pending = one_blank_before_tab_stop; } } @@ -588,7 +588,7 @@ index 7801274..569a7ee 100644 { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -221,7 +235,7 @@ unexpand (void) +@@ -220,7 +234,7 @@ unexpand (void) } else { @@ -597,7 +597,7 @@ index 7801274..569a7ee 100644 if (!column) die (EXIT_FAILURE, 0, _("input line is too long")); } -@@ -229,8 +243,11 @@ unexpand (void) +@@ -228,8 +242,11 @@ unexpand (void) if (pending) { if (pending > 1 && one_blank_before_tab_stop) @@ -611,7 +611,7 @@ index 7801274..569a7ee 100644 die (EXIT_FAILURE, errno, _("write error")); pending = 0; one_blank_before_tab_stop = false; -@@ -240,16 +257,17 @@ unexpand (void) +@@ -239,16 +256,17 @@ unexpand (void) convert &= convert_entire_line || blank; } @@ -737,10 +737,10 @@ index 0000000..7971e18 + +exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 192f776..8053397 100644 +index b98694b..a76c808 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -544,6 +544,7 @@ all_tests = \ +@@ -575,6 +575,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -748,7 +748,7 @@ index 192f776..8053397 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -684,6 +685,7 @@ all_tests = \ +@@ -726,6 +727,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -860,5 +860,5 @@ index 0000000..60d4c1a +unexpand -a < in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.7.4 +2.31.1 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index ad2fa2e..27b8f6f 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From 29117b2d07af00f4d4b87cf778e4294588ab1a83 Mon Sep 17 00:00:00 2001 +From 25a1f8ac25f8ad4d204d40f372636adf5b03e083 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 1 Dec 2016 15:10:04 +0100 Subject: [PATCH] coreutils-i18n.patch @@ -6,7 +6,7 @@ Subject: [PATCH] coreutils-i18n.patch TODO: merge upstream --- lib/linebuffer.h | 8 + - src/fold.c | 308 +++++++++++++-- + src/fold.c | 310 +++++++++++++-- src/join.c | 359 ++++++++++++++--- src/pr.c | 443 +++++++++++++++++++-- src/sort.c | 764 ++++++++++++++++++++++++++++++++++-- @@ -22,16 +22,16 @@ TODO: merge upstream tests/misc/unexpand.pl | 39 ++ tests/misc/uniq.pl | 55 +++ tests/pr/pr-tests.pl | 49 +++ - 17 files changed, 2290 insertions(+), 154 deletions(-) + 17 files changed, 2291 insertions(+), 155 deletions(-) create mode 100755 tests/i18n/sort.sh create mode 100755 tests/misc/sort-mb-tests.sh diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index 64181af..9b8fe5a 100644 +index 5fa5ad2..2bdbcab 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h -@@ -21,6 +21,11 @@ - +@@ -22,6 +22,11 @@ + # include "idx.h" # include +/* Get mbstate_t. */ @@ -42,9 +42,9 @@ index 64181af..9b8fe5a 100644 /* A 'struct linebuffer' holds a line of text. */ struct linebuffer -@@ -28,6 +33,9 @@ struct linebuffer - size_t size; /* Allocated. */ - size_t length; /* Used. */ +@@ -29,6 +34,9 @@ struct linebuffer + idx_t size; /* Allocated. */ + idx_t length; /* Used. */ char *buffer; +# if HAVE_WCHAR_H + mbstate_t state; @@ -53,7 +53,7 @@ index 64181af..9b8fe5a 100644 /* Initialize linebuffer LINEBUFFER for use. */ diff --git a/src/fold.c b/src/fold.c -index 8cd0d6b..d23edd5 100644 +index 94a6d37..ead3c03 100644 --- a/src/fold.c +++ b/src/fold.c @@ -22,12 +22,34 @@ @@ -203,16 +203,19 @@ index 8cd0d6b..d23edd5 100644 /* Look for the last blank. */ while (logical_end) { -@@ -215,11 +252,221 @@ fold_file (char const *filename, size_t width) +@@ -215,13 +252,223 @@ fold_file (char const *filename, size_t width) 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 (!ferror (istream)) +- saved_errno = 0; ++ *saved_errno = 0; ++ ++ if (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ +} + +#if HAVE_MBRTOWC @@ -384,10 +387,10 @@ index 8cd0d6b..d23edd5 100644 + } + + *saved_errno = errno; -+ -+ if (offset_out) -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); -+ + + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + +} +#endif + @@ -423,9 +426,9 @@ index 8cd0d6b..d23edd5 100644 +#endif + fold_text (istream, width, &saved_errno); + - if (ferror (istream)) - { - error (0, saved_errno, "%s", quotef (filename)); + if (STREQ (filename, "-")) + clearerr (istream); + else if (fclose (istream) != 0 && !saved_errno) @@ -252,7 +499,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -454,7 +457,7 @@ index 8cd0d6b..d23edd5 100644 case 's': /* Break at word boundaries. */ diff --git a/src/join.c b/src/join.c -index 98b461c..9990f38 100644 +index f22ffda..ad5dc0d 100644 --- a/src/join.c +++ b/src/join.c @@ -22,19 +22,33 @@ @@ -947,7 +950,7 @@ index 98b461c..9990f38 100644 break; diff --git a/src/pr.c b/src/pr.c -index 26f221f..633f50e 100644 +index 8f84d0f..4bb5195 100644 --- a/src/pr.c +++ b/src/pr.c @@ -311,6 +311,24 @@ @@ -1017,8 +1020,8 @@ index 26f221f..633f50e 100644 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 getoptnum (char const *n_str, int min, int *num, + char const *errfmt); static void getoptarg (char *arg, char switch_char, char *character, + int *character_length, int *character_width, int *number); @@ -1031,7 +1034,7 @@ index 26f221f..633f50e 100644 -static void print_char (char c); static void cleanup (void); static void print_sep_string (void); - static void separator_string (const char *optarg_S); + static void separator_string (char const *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 @@ -1085,7 +1088,7 @@ index 26f221f..633f50e 100644 static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -852,6 +905,13 @@ separator_string (const char *optarg_S) +@@ -852,6 +905,13 @@ separator_string (char const *optarg_S) integer_overflow (); col_sep_length = len; col_sep_string = optarg_S; @@ -1170,7 +1173,7 @@ index 26f221f..633f50e 100644 use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1166,10 +1250,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err) +@@ -1166,10 +1250,45 @@ getoptnum (char const *n_str, int min, int *num, char const *err) a number. */ static void @@ -1239,7 +1242,7 @@ index 26f221f..633f50e 100644 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) +@@ -1260,11 +1384,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. */ @@ -1253,7 +1256,7 @@ index 26f221f..633f50e 100644 /* 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) +@@ -1273,7 +1397,7 @@ init_parameters (int number_of_files) } int sep_chars, useful_chars; @@ -1262,7 +1265,7 @@ index 26f221f..633f50e 100644 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) +@@ -1296,7 +1420,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); @@ -1271,7 +1274,7 @@ index 26f221f..633f50e 100644 } /* Open the necessary files, -@@ -1400,7 +1524,7 @@ init_funcs (void) +@@ -1402,7 +1526,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -1280,7 +1283,7 @@ index 26f221f..633f50e 100644 /* This loop takes care of all but the rightmost column. */ -@@ -1434,7 +1558,7 @@ init_funcs (void) +@@ -1436,7 +1560,7 @@ init_funcs (void) } else { @@ -1289,7 +1292,7 @@ index 26f221f..633f50e 100644 h_next = h + chars_per_column; } } -@@ -1725,9 +1849,9 @@ static void +@@ -1733,9 +1857,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -1301,7 +1304,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2002,13 +2126,13 @@ store_char (char c) +@@ -2010,13 +2134,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -1317,7 +1320,7 @@ index 26f221f..633f50e 100644 char *s; int num_width; -@@ -2025,22 +2149,24 @@ add_line_number (COLUMN *p) +@@ -2033,22 +2157,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. */ @@ -1346,7 +1349,7 @@ index 26f221f..633f50e 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2199,7 +2325,7 @@ print_white_space (void) +@@ -2207,7 +2333,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -1355,7 +1358,7 @@ index 26f221f..633f50e 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2219,6 +2345,7 @@ print_sep_string (void) +@@ -2227,6 +2353,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -1363,7 +1366,7 @@ index 26f221f..633f50e 100644 if (separators_not_printed <= 0) { -@@ -2230,6 +2357,7 @@ print_sep_string (void) +@@ -2238,6 +2365,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -1371,7 +1374,7 @@ index 26f221f..633f50e 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2243,12 +2371,15 @@ print_sep_string (void) +@@ -2251,12 +2379,15 @@ print_sep_string (void) } else { @@ -1388,7 +1391,7 @@ index 26f221f..633f50e 100644 /* 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 *clump) +@@ -2284,7 +2415,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -1397,7 +1400,7 @@ index 26f221f..633f50e 100644 { if (tabify_output) { -@@ -2300,6 +2431,74 @@ print_char (char c) +@@ -2308,6 +2439,74 @@ print_char (char c) putchar (c); } @@ -1472,7 +1475,7 @@ index 26f221f..633f50e 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2477,9 +2676,9 @@ read_line (COLUMN *p) +@@ -2485,9 +2684,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -1484,7 +1487,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2548,7 +2747,7 @@ print_stored (COLUMN *p) +@@ -2556,7 +2755,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -1493,7 +1496,7 @@ index 26f221f..633f50e 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2560,7 +2759,7 @@ print_stored (COLUMN *p) +@@ -2568,7 +2767,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -1502,7 +1505,7 @@ index 26f221f..633f50e 100644 pad_vertically = true; -@@ -2580,9 +2779,9 @@ print_stored (COLUMN *p) +@@ -2588,9 +2787,9 @@ print_stored (COLUMN *p) } } @@ -1514,7 +1517,7 @@ index 26f221f..633f50e 100644 padding_not_printed = ANYWHERE; } -@@ -2595,8 +2794,8 @@ print_stored (COLUMN *p) +@@ -2603,8 +2802,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -1525,7 +1528,7 @@ index 26f221f..633f50e 100644 } return true; -@@ -2615,7 +2814,7 @@ print_stored (COLUMN *p) +@@ -2623,7 +2822,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -1534,7 +1537,7 @@ index 26f221f..633f50e 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2625,10 +2824,10 @@ char_to_clump (char c) +@@ -2633,10 +2832,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -1547,7 +1550,7 @@ index 26f221f..633f50e 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2709,6 +2908,164 @@ char_to_clump (char c) +@@ -2717,6 +2916,164 @@ char_to_clump (char c) return chars; } @@ -1713,7 +1716,7 @@ index 26f221f..633f50e 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 6d2eec5..f189a0d 100644 +index 5f4c817..f631704 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -1836,7 +1839,7 @@ index 6d2eec5..f189a0d 100644 /* Clean up any remaining temporary files. */ static void -@@ -1270,7 +1341,7 @@ zaptemp (char const *name) +@@ -1269,7 +1340,7 @@ zaptemp (char const *name) free (node); } @@ -1845,7 +1848,7 @@ index 6d2eec5..f189a0d 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1285,7 +1356,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1284,7 +1355,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -1854,7 +1857,7 @@ index 6d2eec5..f189a0d 100644 { size_t i; -@@ -1297,7 +1368,7 @@ inittables (void) +@@ -1296,7 +1367,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -1863,7 +1866,7 @@ index 6d2eec5..f189a0d 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1379,6 +1450,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1378,6 +1449,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -1948,7 +1951,7 @@ index 6d2eec5..f189a0d 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1610,7 +1759,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1609,7 +1758,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -1957,7 +1960,7 @@ index 6d2eec5..f189a0d 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1619,10 +1768,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1618,10 +1767,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -1970,7 +1973,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1648,11 +1797,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1647,11 +1796,70 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2036,13 +2039,13 @@ index 6d2eec5..f189a0d 100644 /* Return the limit of (a pointer to the first character after) the field in LINE specified by KEY. */ - static char * + static char * _GL_ATTRIBUTE_PURE -limfield (struct line const *line, struct keyfield const *key) -+limfield_uni (const struct line *line, const struct keyfield *key) ++limfield_uni (struct line const *line, struct keyfield const *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, struct keyfield const *key) +@@ -1666,10 +1874,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2055,7 +2058,7 @@ index 6d2eec5..f189a0d 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1716,10 +1924,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1715,10 +1923,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2068,7 +2071,7 @@ index 6d2eec5..f189a0d 100644 if (newlim) lim = newlim; } -@@ -1750,6 +1958,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1749,6 +1957,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2199,7 +2202,7 @@ index 6d2eec5..f189a0d 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1836,8 +2168,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1835,8 +2167,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2224,7 +2227,7 @@ index 6d2eec5..f189a0d 100644 line->keybeg = line_start; } } -@@ -1987,7 +2333,7 @@ human_numcompare (char const *a, char const *b) +@@ -1986,7 +2332,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2233,7 +2236,7 @@ index 6d2eec5..f189a0d 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -1997,6 +2343,25 @@ numcompare (char const *a, char const *b) +@@ -1996,6 +2342,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2259,7 +2262,7 @@ index 6d2eec5..f189a0d 100644 /* 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 +2412,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2046,7 +2411,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2268,7 +2271,7 @@ index 6d2eec5..f189a0d 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2323,15 +2688,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2322,15 +2687,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2286,7 +2289,7 @@ index 6d2eec5..f189a0d 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2465,7 +2829,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2464,7 +2828,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2295,7 +2298,7 @@ index 6d2eec5..f189a0d 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2523,11 +2887,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2522,11 +2886,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -2384,7 +2387,7 @@ index 6d2eec5..f189a0d 100644 { struct keyfield *key = keylist; -@@ -2612,7 +3052,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2611,7 +3051,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2393,7 +2396,7 @@ index 6d2eec5..f189a0d 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2728,6 +3168,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2727,6 +3167,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -2605,7 +2608,7 @@ index 6d2eec5..f189a0d 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2755,7 +3400,7 @@ compare (struct line const *a, struct line const *b) +@@ -2754,7 +3399,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -2614,7 +2617,7 @@ index 6d2eec5..f189a0d 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4145,6 +4790,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4144,6 +4789,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -2622,7 +2625,7 @@ index 6d2eec5..f189a0d 100644 break; case 'g': key->general_numeric = true; -@@ -4224,7 +4870,7 @@ main (int argc, char **argv) +@@ -4223,7 +4869,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2631,7 +2634,7 @@ index 6d2eec5..f189a0d 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4245,6 +4891,29 @@ main (int argc, char **argv) +@@ -4244,6 +4890,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -2661,7 +2664,7 @@ index 6d2eec5..f189a0d 100644 have_read_stdin = false; inittables (); -@@ -4519,13 +5188,34 @@ main (int argc, char **argv) +@@ -4518,13 +5187,34 @@ main (int argc, char **argv) case 't': { @@ -2700,7 +2703,7 @@ index 6d2eec5..f189a0d 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4536,9 +5226,11 @@ main (int argc, char **argv) +@@ -4535,9 +5225,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -2714,7 +2717,7 @@ index 6d2eec5..f189a0d 100644 } break; -@@ -4767,12 +5459,10 @@ main (int argc, char **argv) +@@ -4766,12 +5458,10 @@ main (int argc, char **argv) sort (files, nfiles, outfile, nthreads); } @@ -2728,7 +2731,7 @@ index 6d2eec5..f189a0d 100644 if (have_read_stdin && fclose (stdin) == EOF) sort_die (_("close failed"), "-"); diff --git a/src/uniq.c b/src/uniq.c -index 87a0c93..9f755d9 100644 +index 8f6e973..752797a 100644 --- a/src/uniq.c +++ b/src/uniq.c @@ -21,6 +21,17 @@ @@ -2928,10 +2931,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 568944e..192f776 100644 +index 228d0e3..b98694b 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -369,6 +369,8 @@ all_tests = \ +@@ -375,6 +375,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -2941,7 +2944,7 @@ index 568944e..192f776 100644 tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index 8a9cad1..9293e39 100755 +index a10ff19..e1706c1 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -3008,7 +3011,7 @@ index 8a9cad1..9293e39 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 7b192b4..76f073f 100755 +index beacec9..b56afca 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; @@ -3081,7 +3084,7 @@ index 7b192b4..76f073f 100755 my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; diff --git a/tests/misc/join.pl b/tests/misc/join.pl -index 4d399d8..07f2823 100755 +index bfd9e6f..75788c9 100755 --- a/tests/misc/join.pl +++ b/tests/misc/join.pl @@ -25,6 +25,15 @@ my $limits = getlimits (); @@ -3202,7 +3205,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/sort-merge.pl b/tests/misc/sort-merge.pl -index 23f6ed2..402a987 100755 +index 70d8af1..6b4840a 100755 --- a/tests/misc/sort-merge.pl +++ b/tests/misc/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; @@ -3262,7 +3265,7 @@ index 23f6ed2..402a987 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/sort.pl b/tests/misc/sort.pl -index c3e7f8e..6ecd3ff 100755 +index 86970ff..c016ff7 100755 --- a/tests/misc/sort.pl +++ b/tests/misc/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -3330,7 +3333,7 @@ index c3e7f8e..6ecd3ff 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 6ba6d40..de86723 100755 +index 1c8e308..9f8ab89 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -3387,7 +3390,7 @@ index 6ba6d40..de86723 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/uniq.pl b/tests/misc/uniq.pl -index f028036..8eaf59a 100755 +index 74d3815..aae4c7e 100755 --- a/tests/misc/uniq.pl +++ b/tests/misc/uniq.pl @@ -23,9 +23,17 @@ my $limits = getlimits (); @@ -3463,7 +3466,7 @@ index f028036..8eaf59a 100755 @Tests = triple_test \@Tests; diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index ec3980a..136657d 100755 +index d0ac405..ff7d472 100755 --- a/tests/pr/pr-tests.pl +++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; @@ -3482,9 +3485,9 @@ index ec3980a..136657d 100755 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"} ]; +@@ -512,8 +521,48 @@ push @Tests, + {IN=>"x\tx\tx\tx\tx\nx\tx\tx\tx\tx\n"}, + {OUT=>"x\tx\tx\tx\tx\tx\tx\tx\tx\tx\n"} ]; +# Add _POSIX2_VERSION=199209 to the environment of each test +# that uses an old-style option like +1. @@ -3532,5 +3535,5 @@ index ec3980a..136657d 100755 my $verbose = $ENV{VERBOSE}; -- -2.7.4 +2.31.1 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 8274a23..1f7f3a3 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,3 +1,32 @@ +From d70ddb3eb845c494280e7365e2b889242e7e1bb9 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Mon, 4 Oct 2021 08:45:53 +0200 +Subject: [PATCH] coreutils-selinux.patch + +--- + doc/coreutils.texi | 5 +++++ + man/chcon.x | 2 +- + man/runcon.x | 2 +- + src/cp.c | 16 +++++++++++++++- + src/install.c | 10 ++++++++-- + 5 files changed, 30 insertions(+), 5 deletions(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 6810c15..19b535c 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -8766,6 +8766,11 @@ done + exit $fail + @end example + ++@item -c ++@cindex SELinux security context information, preserving ++Preserve SELinux security context of the original files if possible. ++Some file systems don't support storing of SELinux security context. ++ + @item --copy-contents + @cindex directories, copying recursively + @cindex copying directories recursively diff --git a/man/chcon.x b/man/chcon.x index 8c1ff6f..c84fb96 100644 --- a/man/chcon.x @@ -20,20 +49,20 @@ index d2df13e..5c5f5d8 100644 Run COMMAND with completely-specified CONTEXT, or with current or transitioned security context modified by one or more of LEVEL, diff --git a/src/cp.c b/src/cp.c -index 1b528c6..25dbb88 100644 +index c97a675..89fb8ec 100644 --- a/src/cp.c +++ b/src/cp.c -@@ -203,6 +203,9 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ +@@ -191,6 +191,9 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ + additional attributes: context, links, xattr,\ + \n\ all\n\ - "), stdout); - fputs (_("\ -+ -c deprecated, same as --preserve=context\n\ +"), stdout); + fputs (_("\ - --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ - --parents use full source file name under DIRECTORY\n\ ++ -c deprecated, same as --preserve=context\n\ "), stdout); -@@ -929,7 +932,7 @@ main (int argc, char **argv) + fputs (_("\ + --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ +@@ -954,7 +957,7 @@ main (int argc, char **argv) selinux_enabled = (0 < is_selinux_enabled ()); cp_option_init (&x); @@ -42,7 +71,7 @@ index 1b528c6..25dbb88 100644 long_opts, NULL)) != -1) { -@@ -977,6 +980,17 @@ main (int argc, char **argv) +@@ -1002,6 +1005,17 @@ main (int argc, char **argv) copy_contents = true; break; @@ -60,27 +89,11 @@ index 1b528c6..25dbb88 100644 case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 47e4480..cff2ead 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -8083,6 +8083,11 @@ done - exit $fail - @end example - -+@item -c -+@cindex SELinux security context information, preserving -+Preserve SELinux security context of the original files if possible. -+Some file systems don't support storing of SELinux security context. -+ - @item --copy-contents - @cindex directories, copying recursively - @cindex copying directories recursively diff --git a/src/install.c b/src/install.c -index d79d597..437889a 100644 +index c9456fe..2b1bee9 100644 --- a/src/install.c +++ b/src/install.c -@@ -673,7 +673,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ +@@ -638,7 +638,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ -v, --verbose print the name of each directory as it is created\n\ "), stdout); fputs (_("\ @@ -89,7 +102,7 @@ index d79d597..437889a 100644 -Z set SELinux security context of destination\n\ file and each created directory to default type\n\ --context[=CTX] like -Z, or if CTX is specified then set the\n\ -@@ -824,7 +824,7 @@ main (int argc, char **argv) +@@ -790,7 +790,7 @@ main (int argc, char **argv) dir_arg = false; umask (0); @@ -98,7 +111,7 @@ index d79d597..437889a 100644 NULL)) != -1) { switch (optc) -@@ -885,6 +885,8 @@ main (int argc, char **argv) +@@ -851,6 +851,8 @@ main (int argc, char **argv) no_target_directory = true; break; @@ -107,7 +120,7 @@ index d79d597..437889a 100644 case PRESERVE_CONTEXT_OPTION: if (! selinux_enabled) { -@@ -892,6 +894,10 @@ main (int argc, char **argv) +@@ -858,6 +860,10 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } @@ -118,3 +131,6 @@ index d79d597..437889a 100644 x.preserve_security_context = true; use_default_selinux_context = false; break; +-- +2.31.1 + diff --git a/coreutils.spec b/coreutils.spec index e6349c5..faeaf7b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 8.32 -Release: 32%{?dist} +Version: 9.0 +Release: 1%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -17,57 +17,6 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ -# ls: restore 8.31 behavior on removed directories -Patch1: coreutils-8.32-ls-removed-dir.patch - -# du: simplify leaf optimization for XFS (#1823247) -Patch2: coreutils-8.32-leaf-opt-xfs.patch - -# cp: default to --reflink=auto (#1861108) -Patch3: coreutils-8.32-cp-reflink-auto.patch - -# eliminate unportable gnulib tests -Patch4: coreutils-8.32-gnulib-perror-test.patch - -# df,stat,tail: recognize more file system types -Patch5: coreutils-8.32-new-fs-types.patch - -# rm: do not skip files upon failure to remove an empty dir (#1905481) -Patch6: coreutils-8.32-rm-stray-skip.patch - -# expr: fix invalid read with unmatched \(...\) (#1919775) -Patch7: coreutils-8.32-expr-unmatched-par.patch - -# split: fix --number=K/N to output correct part of file (#1921246) -Patch8: coreutils-8.32-split-number.patch - -# ls: fix crash printing SELinux context for unstatable files (#1921249) -Patch9: coreutils-8.32-ls-scontext-crash.patch - -# stat: add support for the exfat file system (#1921427) -Patch10: coreutils-8.32-stat-exfat.patch - -# cp: use copy_file_range if available -Patch11: coreutils-8.32-cp-file-range.patch - -# hostname,ln: fix memory leaks detected by Coverity -Patch12: coreutils-8.32-mem-leaks.patch - -# utimens: fix confusing arg type in internal func -Patch13: coreutils-8.32-coverity-utimens.patch - -# fix false positives in the upstrem test-suite (#1960792) -Patch14: coreutils-8.32-tests-false-positives.patch - -# mountlist: recognize fuse.portal as dummy file system (#1913358) -Patch15: coreutils-8.32-fuse-portal.patch - -# tail: fix stack out-of-bounds write with --follow -Patch16: coreutils-8.32-tail-use-poll.patch - -# df: fix duplicated remote entries due to bind mounts (#1979814) -Patch17: coreutils-8.32-df-duplicated-entries.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -328,6 +277,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Sun Sep 26 2021 Kamil Dudka - 9.0-1 +- new upstream release 9.0 + * Tue Sep 14 2021 Sahana Prasad - Rebuilt with OpenSSL 3.0.0 diff --git a/sources b/sources index 97fe361..99d4423 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (coreutils-8.32.tar.xz) = 1c8f3584efd61b4b02e7ac5db8e103b63cfb2063432caaf1e64cb2dcc56d8c657d1133bbf10bd41468d6a1f31142e6caa81d16ae68fa3e6e84075c253613a145 +SHA512 (coreutils-9.0.tar.xz) = 9be08212891dbf48e5b22e7689dc27dac50df4631ebf29313470b72b7921f0b2aa5242917d05587785358495ca56e3b21f5b3ca81043d53cab92354da6c53a03 From 4a2b84513e00b945e085c14919a23f32fc725f31 Mon Sep 17 00:00:00 2001 From: Bernhard Voelker Date: Sun, 26 Sep 2021 19:00:19 +0200 Subject: [PATCH 456/523] make upstream test-suite work again with i18n patch New tests in tests/pr/pr-tests.pl have names which - with the suffix "-mb" for the i18n test - become "too long (>30)". I adjusted 'tests/Coreutils.pm' accordingly. --- coreutils-i18n.patch | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 27b8f6f..2781e68 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2895,6 +2895,20 @@ index 8f6e973..752797a 100644 skip_chars = 0; skip_fields = 0; check_chars = SIZE_MAX; +diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm +index dc6b132..a2abc6d 100644 +--- a/tests/Coreutils.pm ++++ b/tests/Coreutils.pm +@@ -264,6 +264,9 @@ sub run_tests ($$$$$) + # Yes, this is an arbitrary limit. If it causes trouble, + # consider removing it. + my $max = 30; ++ # The downstream i18n multi-byte tests have a "-mb" suffix. ++ # Therefore add 3 to the maximum test name length. ++ $max += 3; + if ($max < length $test_name) + { + warn "$program_name: $test_name: test name is too long (> $max)\n"; diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh new file mode 100755 index 0000000..26c95de From 59649f073306ebc2ae299c8b8e2101b0440b511f Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 4 Oct 2021 08:57:28 +0200 Subject: [PATCH 457/523] coreutils-i18n.patch: squash all i18n patches together ... so that we can easily synchronize the patch with openSUSE --- coreutils-i18n-cut-old.patch | 565 ------ coreutils-i18n-expand-unexpand.patch | 864 --------- coreutils-i18n-fix-unexpand.patch | 28 - coreutils-i18n-fix2-expand-unexpand.patch | 108 -- coreutils-i18n-fold-newline.patch | 80 - coreutils-i18n-sort-human.patch | 35 - coreutils-i18n-un-expand-BOM.patch | 456 ----- coreutils-i18n.patch | 1952 ++++++++++++++++++++- coreutils.spec | 14 - 9 files changed, 1890 insertions(+), 2212 deletions(-) delete mode 100644 coreutils-i18n-cut-old.patch delete mode 100644 coreutils-i18n-expand-unexpand.patch delete mode 100644 coreutils-i18n-fix-unexpand.patch delete mode 100644 coreutils-i18n-fix2-expand-unexpand.patch delete mode 100644 coreutils-i18n-fold-newline.patch delete mode 100644 coreutils-i18n-sort-human.patch delete mode 100644 coreutils-i18n-un-expand-BOM.patch diff --git a/coreutils-i18n-cut-old.patch b/coreutils-i18n-cut-old.patch deleted file mode 100644 index 757ee0f..0000000 --- a/coreutils-i18n-cut-old.patch +++ /dev/null @@ -1,565 +0,0 @@ -diff --git a/src/cut.c b/src/cut.c -index 7ab6be4..022d0ad 100644 ---- a/src/cut.c -+++ b/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 FILE to standard output.\n\ - -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) diff --git a/coreutils-i18n-expand-unexpand.patch b/coreutils-i18n-expand-unexpand.patch deleted file mode 100644 index a84e3c3..0000000 --- a/coreutils-i18n-expand-unexpand.patch +++ /dev/null @@ -1,864 +0,0 @@ -From bde345889debed9041dec0710b1edc78821ced21 Mon Sep 17 00:00:00 2001 -From: Ondrej Oprala -Date: Wed, 5 Aug 2015 09:15:09 +0200 -Subject: [PATCH] expand,unexpand: add multibyte support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -* NEWS: Mention the changes. -* bootstrap.conf: Add mbfile to the list of modules. -* configure.ac: Properly initialize mbfile. -* src/expand.c (expand): Iterate over multibyte characters properly. -* src/unexpand.c (unexpand): Iterate over multibyte characters -properly. -* tests/local.mk: Add new tests. -* tests/{expand,unexpand}/mb.sh: New tests. - -Co-authored-by: Pádraig Brady ---- - bootstrap.conf | 1 + - configure.ac | 2 + - lib/mbfile.c | 3 + - lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++ - m4/mbfile.m4 | 14 +++ - src/expand.c | 43 +++++--- - src/local.mk | 4 +- - src/unexpand.c | 54 ++++++--- - tests/expand/mb.sh | 98 +++++++++++++++++ - tests/local.mk | 2 + - tests/unexpand/mb.sh | 97 ++++++++++++++++ - 11 files changed, 537 insertions(+), 36 deletions(-) - create mode 100644 lib/mbfile.c - create mode 100644 lib/mbfile.h - create mode 100644 m4/mbfile.m4 - create mode 100755 tests/expand/mb.sh - create mode 100755 tests/unexpand/mb.sh - -diff --git a/bootstrap.conf b/bootstrap.conf -index aef9ec7..9486e9d 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -156,6 +156,7 @@ gnulib_modules=" - maintainer-makefile - malloc-gnu - manywarnings -+ mbfile - mbrlen - mbrtowc - mbsalign -diff --git a/configure.ac b/configure.ac -index 6960b48..8ff85f8 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -457,6 +457,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 && \ -diff --git a/lib/mbfile.c b/lib/mbfile.c -new file mode 100644 -index 0000000..b0a468e ---- /dev/null -+++ b/lib/mbfile.c -@@ -0,0 +1,3 @@ -+#include -+#define MBFILE_INLINE _GL_EXTERN_INLINE -+#include "mbfile.h" -diff --git a/lib/mbfile.h b/lib/mbfile.h -new file mode 100644 -index 0000000..11f1b12 ---- /dev/null -+++ b/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 */ -diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 -new file mode 100644 -index 0000000..8589902 ---- /dev/null -+++ b/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]) -+ : -+]) -diff --git a/src/expand.c b/src/expand.c -index 4e32bfc..28809b0 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -37,6 +37,9 @@ - #include - #include - #include -+ -+#include -+ - #include "system.h" - #include "die.h" - -@@ -97,19 +100,19 @@ expand (void) - { - /* Input stream. */ - FILE *fp = next_file (NULL); -+ mb_file_t mbf; -+ mbf_char_t c; - - if (!fp) - return; - -+ mbf_init (mbf, fp); -+ - while (true) - { -- /* Input character, or EOF. */ -- int c; -- - /* If true, perform translations. */ - bool convert = true; - -- - /* The following variables have valid values only when CONVERT - is true: */ - -@@ -119,17 +122,23 @@ 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; -+ do { -+ mbf_getc (c, mbf); -+ if (mb_iseof (c)) -+ { -+ mbf_init (mbf, fp = next_file (fp)); -+ continue; -+ } -+ } -+ while (false); - - if (convert) - { -- if (c == '\t') -+ if (mb_iseq (c, '\t')) - { - /* Column the next input tab stop is on. */ - uintmax_t next_tab_column; -@@ -148,32 +157,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')); - } - } - -diff --git a/src/local.mk b/src/local.mk -index 0c8b65d..011421a 100644 ---- a/src/local.mk -+++ b/src/local.mk -@@ -429,8 +429,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) - src_basenc_SOURCES = src/basenc.c - src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) - --src_expand_SOURCES = src/expand.c src/expand-common.c --src_unexpand_SOURCES = src/unexpand.c src/expand-common.c -+src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c -+src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c - - src_wc_SOURCES = src/wc.c - if USE_AVX2_WC_LINECOUNT -diff --git a/src/unexpand.c b/src/unexpand.c -index cec392d..02f18f9 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -38,6 +38,9 @@ - #include - #include - #include -+ -+#include -+ - #include "system.h" - #include "die.h" - -@@ -106,11 +109,12 @@ 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; - - if (!fp) - return; -@@ -118,12 +122,14 @@ unexpand (void) - /* 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)); -+ -+ mbf_init (mbf, fp); - - while (true) - { - /* Input character, or EOF. */ -- int c; -+ mbf_char_t c; - - /* If true, perform translations. */ - bool convert = true; -@@ -157,12 +163,19 @@ unexpand (void) - - do - { -- while ((c = getc (fp)) < 0 && (fp = next_file (fp))) -- continue; -+ do { -+ mbf_getc (c, mbf); -+ if (mb_iseof (c)) -+ { -+ mbf_init (mbf, fp = next_file (fp)); -+ continue; -+ } -+ } -+ while (false); - - if (convert) - { -- bool blank = !! isblank (c); -+ bool blank = mb_isblank (c); - - if (blank) - { -@@ -179,16 +192,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)) - { -@@ -196,13 +209,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 -@@ -210,7 +224,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. */ -@@ -220,7 +234,7 @@ unexpand (void) - } - else - { -- column++; -+ column += mb_width (c); - if (!column) - die (EXIT_FAILURE, 0, _("input line is too long")); - } -@@ -228,8 +242,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; -@@ -239,16 +256,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')); - } - } - -diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -new file mode 100755 -index 0000000..7971e18 ---- /dev/null -+++ b/tests/expand/mb.sh -@@ -0,0 +1,98 @@ -+#!/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 -+ -+#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 -+ -+exit $fail -diff --git a/tests/local.mk b/tests/local.mk -index b98694b..a76c808 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -575,6 +575,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 \ -@@ -726,6 +727,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. -diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -new file mode 100755 -index 0000000..60d4c1a ---- /dev/null -+++ b/tests/unexpand/mb.sh -@@ -0,0 +1,97 @@ -+#!/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 -+ -+#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 --- -2.31.1 - diff --git a/coreutils-i18n-fix-unexpand.patch b/coreutils-i18n-fix-unexpand.patch deleted file mode 100644 index f0c347c..0000000 --- a/coreutils-i18n-fix-unexpand.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 02424bfcd719bbaa695f4e1c3ef17ad91b0d23c0 Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Thu, 28 Jan 2016 20:57:22 +0100 -Subject: [PATCH] unexpand: fix blank line handling - - echo '' |./src/unexpand -a - -Really? ---- - src/unexpand.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/unexpand.c b/src/unexpand.c -index 569a7ee..3bbbd66 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -233,7 +233,7 @@ unexpand (void) - next_tab_column = column; - tab_index -= !!tab_index; - } -- else -+ else if (!mb_iseq (c, '\n')) - { - column += mb_width (c); - if (!column) --- -2.7.4 - diff --git a/coreutils-i18n-fix2-expand-unexpand.patch b/coreutils-i18n-fix2-expand-unexpand.patch deleted file mode 100644 index b34d7b7..0000000 --- a/coreutils-i18n-fix2-expand-unexpand.patch +++ /dev/null @@ -1,108 +0,0 @@ -diff --git a/src/expand.c b/src/expand.c -index 380e020..310b349 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -129,15 +129,19 @@ expand (void) - - do - { -- do { -+ while (true) { - mbf_getc (c, mbf); -- if (mb_iseof (c)) -+ if ((mb_iseof (c)) && (fp = next_file (fp))) - { -- mbf_init (mbf, fp = next_file (fp)); -+ mbf_init (mbf, fp); - continue; - } -+ else -+ { -+ break; -+ } - } -- while (false); -+ - - if (convert) - { -diff --git a/src/unexpand.c b/src/unexpand.c -index 3bbbd66..863a90a 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -164,15 +164,19 @@ unexpand (void) - - do - { -- do { -+ while (true) { - mbf_getc (c, mbf); -- if (mb_iseof (c)) -+ if ((mb_iseof (c)) && (fp = next_file (fp))) - { -- mbf_init (mbf, fp = next_file (fp)); -+ mbf_init (mbf, fp); - continue; - } -+ else -+ { -+ break; -+ } - } -- while (false); -+ - - if (convert) - { -diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -index 7971e18..031be7a 100755 ---- a/tests/expand/mb.sh -+++ b/tests/expand/mb.sh -@@ -44,6 +44,20 @@ 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) -diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -index 60d4c1a..8d75652 100755 ---- a/tests/unexpand/mb.sh -+++ b/tests/unexpand/mb.sh -@@ -44,6 +44,22 @@ 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 diff --git a/coreutils-i18n-fold-newline.patch b/coreutils-i18n-fold-newline.patch deleted file mode 100644 index f7286ef..0000000 --- a/coreutils-i18n-fold-newline.patch +++ /dev/null @@ -1,80 +0,0 @@ -From ff424639fe863cbd6963add1a79b97290c1606c6 Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Fri, 3 Feb 2017 12:26:53 +0100 -Subject: [PATCH] fold.c: preserve new-lines in mutlibyte text - ---- - src/fold.c | 49 ++++++++++++++++++++++++------------------------- - 1 file changed, 24 insertions(+), 25 deletions(-) - -diff --git a/src/fold.c b/src/fold.c -index d23edd5..8c232a7 100644 ---- a/src/fold.c -+++ b/src/fold.c -@@ -342,39 +342,38 @@ fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) - } - - rescan: -- if (operating_mode == byte_mode) /* byte mode */ -+ if (convfail) -+ increment = 1; -+ else if (wc == L'\n') -+ { -+ /* preserve newline */ -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ continue; -+ } -+ else if (operating_mode == byte_mode) /* byte mode */ - increment = mblength; - else if (operating_mode == character_mode) /* character mode */ - increment = 1; -- else /* column mode */ -+ else /* column mode */ - { -- if (convfail) -- increment = 1; -- else -+ switch (wc) - { -- switch (wc) -- { -- case L'\n': -- fwrite (line_out, sizeof(char), offset_out, stdout); -- START_NEW_LINE; -- continue; -+ case L'\b': -+ increment = (column > 0) ? -1 : 0; -+ break; - -- case L'\b': -- increment = (column > 0) ? -1 : 0; -- break; -+ case L'\r': -+ increment = -1 * column; -+ break; - -- case L'\r': -- increment = -1 * column; -- break; -+ case L'\t': -+ increment = 8 - column % 8; -+ break; - -- case L'\t': -- increment = 8 - column % 8; -- break; -- -- default: -- increment = wcwidth (wc); -- increment = (increment < 0) ? 0 : increment; -- } -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; - } - } - --- -2.7.4 - diff --git a/coreutils-i18n-sort-human.patch b/coreutils-i18n-sort-human.patch deleted file mode 100644 index 6752493..0000000 --- a/coreutils-i18n-sort-human.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 3976ef5a20369d8b490907ab2cba2d617305a5e0 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Mon, 30 May 2016 16:19:20 +0200 -Subject: [PATCH] sort: do not use static array 'blanks' in human_numcompare() - -... because the array is not initialized with MB locales. Note this is -rather a conservative fix. I plan to do more cleanup of the i18n patch -in Fedora to prevent mistakes like this in future updates of coreutils. ---- - src/sort.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/src/sort.c b/src/sort.c -index 9e07ad8..e47b039 100644 ---- a/src/sort.c -+++ b/src/sort.c -@@ -2304,12 +2304,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)); --- -2.5.5 - diff --git a/coreutils-i18n-un-expand-BOM.patch b/coreutils-i18n-un-expand-BOM.patch deleted file mode 100644 index 6210ce7..0000000 --- a/coreutils-i18n-un-expand-BOM.patch +++ /dev/null @@ -1,456 +0,0 @@ -From 7a7c776a4e228d180e74614fd8c8afcad5d4bdf7 Mon Sep 17 00:00:00 2001 -From: Jakub Martisko -Date: Thu, 7 Jul 2016 12:53:26 +0200 -Subject: [PATCH] coreutils-i18n-un-expand-BOM.patch - ---- - src/expand-common.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ - src/expand-common.h | 12 ++++++ - src/expand.c | 45 +++++++++++++++++++- - src/unexpand.c | 43 ++++++++++++++++++- - tests/expand/mb.sh | 71 ++++++++++++++++++++++++++++++++ - tests/unexpand/mb.sh | 59 ++++++++++++++++++++++++++ - 6 files changed, 342 insertions(+), 2 deletions(-) - -diff --git a/src/expand-common.c b/src/expand-common.c -index 4657e46..97cbb09 100644 ---- a/src/expand-common.c -+++ b/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 -diff --git a/src/expand-common.h b/src/expand-common.h -index 8cb2079..763bfda 100644 ---- a/src/expand-common.h -+++ b/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); -diff --git a/src/expand.c b/src/expand.c -index 310b349..4136824 100644 ---- a/src/expand.c -+++ b/src/expand.c -@@ -103,11 +103,33 @@ expand (void) - 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); -+ -+ 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")); -+ } -+ } -+ -+ -+ if (found_bom == true) -+ { -+ print_bom(); -+ } - - while (true) - { -@@ -132,6 +154,27 @@ expand (void) - 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 -diff --git a/src/unexpand.c b/src/unexpand.c -index 863a90a..5681b58 100644 ---- a/src/unexpand.c -+++ b/src/unexpand.c -@@ -116,16 +116,36 @@ unexpand (void) - include characters other than spaces, so the blanks must be - stored, not merely counted. */ - 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 * sizeof (mbf_char_t)); - -- mbf_init (mbf, fp); -+ if (found_bom == true) -+ { -+ print_bom(); -+ } - - while (true) - { -@@ -169,6 +189,27 @@ unexpand (void) - 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 -diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -index 031be7a..1621c84 100755 ---- a/tests/expand/mb.sh -+++ b/tests/expand/mb.sh -@@ -109,4 +109,75 @@ env printf '12345678 - 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 -diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -index 8d75652..9d4ee3e 100755 ---- a/tests/unexpand/mb.sh -+++ b/tests/unexpand/mb.sh -@@ -111,3 +111,62 @@ env printf '12345678 - - 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 --- -2.9.3 - diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 2781e68..1a4b8ff 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,18 +1,30 @@ -From 25a1f8ac25f8ad4d204d40f372636adf5b03e083 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Thu, 1 Dec 2016 15:10:04 +0100 +From d53e5b885b9d82e2d9ba5d65ed8fd9b96712623f Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Mon, 4 Oct 2021 08:54:37 +0200 Subject: [PATCH] coreutils-i18n.patch -TODO: merge upstream --- + bootstrap.conf | 1 + + configure.ac | 2 + lib/linebuffer.h | 8 + - src/fold.c | 310 +++++++++++++-- + 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 | 309 +++++++++++++-- src/join.c | 359 ++++++++++++++--- + src/local.mk | 4 +- src/pr.c | 443 +++++++++++++++++++-- - src/sort.c | 764 ++++++++++++++++++++++++++++++++++-- + src/sort.c | 772 ++++++++++++++++++++++++++++++++++-- + src/unexpand.c | 101 ++++- src/uniq.c | 119 +++++- + tests/Coreutils.pm | 3 + + tests/expand/mb.sh | 183 +++++++++ tests/i18n/sort.sh | 29 ++ - tests/local.mk | 2 + + tests/local.mk | 4 + tests/misc/expand.pl | 42 ++ tests/misc/fold.pl | 50 ++- tests/misc/join.pl | 50 +++ @@ -22,10 +34,41 @@ TODO: merge upstream tests/misc/unexpand.pl | 39 ++ tests/misc/uniq.pl | 55 +++ tests/pr/pr-tests.pl | 49 +++ - 17 files changed, 2291 insertions(+), 155 deletions(-) + tests/unexpand/mb.sh | 172 ++++++++ + 31 files changed, 3637 insertions(+), 213 deletions(-) + create mode 100644 lib/mbfile.c + create mode 100644 lib/mbfile.h + create mode 100644 m4/mbfile.m4 + create mode 100755 tests/expand/mb.sh create mode 100755 tests/i18n/sort.sh create mode 100755 tests/misc/sort-mb-tests.sh + create mode 100755 tests/unexpand/mb.sh +diff --git a/bootstrap.conf b/bootstrap.conf +index aef9ec7..9486e9d 100644 +--- a/bootstrap.conf ++++ b/bootstrap.conf +@@ -156,6 +156,7 @@ gnulib_modules=" + maintainer-makefile + malloc-gnu + manywarnings ++ mbfile + mbrlen + mbrtowc + mbsalign +diff --git a/configure.ac b/configure.ac +index 6960b48..8ff85f8 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -457,6 +457,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 && \ diff --git a/lib/linebuffer.h b/lib/linebuffer.h index 5fa5ad2..2bdbcab 100644 --- a/lib/linebuffer.h @@ -52,8 +95,1174 @@ index 5fa5ad2..2bdbcab 100644 }; /* Initialize linebuffer LINEBUFFER for use. */ +diff --git a/lib/mbfile.c b/lib/mbfile.c +new file mode 100644 +index 0000000..b0a468e +--- /dev/null ++++ b/lib/mbfile.c +@@ -0,0 +1,3 @@ ++#include ++#define MBFILE_INLINE _GL_EXTERN_INLINE ++#include "mbfile.h" +diff --git a/lib/mbfile.h b/lib/mbfile.h +new file mode 100644 +index 0000000..11f1b12 +--- /dev/null ++++ b/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 */ +diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 +new file mode 100644 +index 0000000..8589902 +--- /dev/null ++++ b/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]) ++ : ++]) +diff --git a/src/cut.c b/src/cut.c +index cdf33d8..b8301d7 100644 +--- a/src/cut.c ++++ b/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" +@@ -37,6 +42,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" + +@@ -53,6 +70,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 +@@ -60,6 +123,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 +@@ -76,15 +142,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. */ +@@ -96,6 +172,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'; +@@ -163,7 +242,7 @@ Print selected parts of lines from each FILE to standard output.\n\ + -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\ +@@ -279,6 +358,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 +@@ -424,13 +579,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. +@@ -482,6 +835,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]); +@@ -504,7 +858,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")); +@@ -512,6 +865,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) +@@ -523,10 +884,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: +@@ -539,6 +928,7 @@ main (int argc, char **argv) + break; + + case 'n': ++ byte_mode_character_aware = 1; + break; + + case 's': +@@ -578,15 +968,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) +diff --git a/src/expand-common.c b/src/expand-common.c +index 4deb7bd..8fd0524 100644 +--- a/src/expand-common.c ++++ b/src/expand-common.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include "system.h" + #include "die.h" + #include "error.h" +@@ -125,6 +126,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 +diff --git a/src/expand-common.h b/src/expand-common.h +index ac812d0..16789ab 100644 +--- a/src/expand-common.h ++++ b/src/expand-common.h +@@ -25,6 +25,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); +diff --git a/src/expand.c b/src/expand.c +index 4e32bfc..902c6b4 100644 +--- a/src/expand.c ++++ b/src/expand.c +@@ -37,6 +37,9 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "die.h" + +@@ -97,19 +100,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: */ + +@@ -119,17 +144,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; +@@ -148,32 +204,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')); + } + } + diff --git a/src/fold.c b/src/fold.c -index 94a6d37..ead3c03 100644 +index 94a6d37..a278783 100644 --- a/src/fold.c +++ b/src/fold.c @@ -22,12 +22,34 @@ @@ -203,7 +1412,7 @@ index 94a6d37..ead3c03 100644 /* Look for the last blank. */ while (logical_end) { -@@ -215,13 +252,223 @@ fold_file (char const *filename, size_t width) +@@ -215,13 +252,222 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -212,10 +1421,10 @@ index 94a6d37..ead3c03 100644 if (!ferror (istream)) - saved_errno = 0; + *saved_errno = 0; -+ -+ if (offset_out) -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); -+ + + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + +} + +#if HAVE_MBRTOWC @@ -301,39 +1510,38 @@ index 94a6d37..ead3c03 100644 + } + +rescan: -+ if (operating_mode == byte_mode) /* byte mode */ ++ if (convfail) ++ increment = 1; ++ else if (wc == L'\n') ++ { ++ /* preserve newline */ ++ fwrite (line_out, sizeof(char), offset_out, stdout); ++ START_NEW_LINE; ++ continue; ++ } ++ else if (operating_mode == byte_mode) /* byte mode */ + increment = mblength; + else if (operating_mode == character_mode) /* character mode */ + increment = 1; -+ else /* column mode */ ++ else /* column mode */ + { -+ if (convfail) -+ increment = 1; -+ else ++ switch (wc) + { -+ switch (wc) -+ { -+ case L'\n': -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ continue; ++ case L'\b': ++ increment = (column > 0) ? -1 : 0; ++ break; + -+ case L'\b': -+ increment = (column > 0) ? -1 : 0; -+ break; ++ case L'\r': ++ increment = -1 * column; ++ break; + -+ case L'\r': -+ increment = -1 * column; -+ break; ++ case L'\t': ++ increment = 8 - column % 8; ++ break; + -+ case L'\t': -+ increment = 8 - column % 8; -+ break; -+ -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; -+ } ++ default: ++ increment = wcwidth (wc); ++ increment = (increment < 0) ? 0 : increment; + } + } + @@ -387,10 +1595,10 @@ index 94a6d37..ead3c03 100644 + } + + *saved_errno = errno; - - if (offset_out) - fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); - ++ ++ if (offset_out) ++ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ +} +#endif + @@ -429,7 +1637,7 @@ index 94a6d37..ead3c03 100644 if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -252,7 +499,8 @@ main (int argc, char **argv) +@@ -252,7 +498,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -439,7 +1647,7 @@ index 94a6d37..ead3c03 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -261,7 +509,15 @@ main (int argc, char **argv) +@@ -261,7 +508,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -949,6 +2157,21 @@ index f22ffda..ad5dc0d 100644 } break; +diff --git a/src/local.mk b/src/local.mk +index 0c8b65d..011421a 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -429,8 +429,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) + src_basenc_SOURCES = src/basenc.c + src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) + +-src_expand_SOURCES = src/expand.c src/expand-common.c +-src_unexpand_SOURCES = src/unexpand.c src/expand-common.c ++src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c ++src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c + + src_wc_SOURCES = src/wc.c + if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c index 8f84d0f..4bb5195 100644 --- a/src/pr.c @@ -1716,7 +2939,7 @@ index 8f84d0f..4bb5195 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 5f4c817..f631704 100644 +index 5f4c817..bd9c672 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -2227,7 +3450,23 @@ index 5f4c817..f631704 100644 line->keybeg = line_start; } } -@@ -1986,7 +2332,7 @@ human_numcompare (char const *a, char const *b) +@@ -1970,12 +2316,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)); +@@ -1986,7 +2330,7 @@ human_numcompare (char const *a, char const *b) hideously fast. */ static int @@ -2236,7 +3475,7 @@ index 5f4c817..f631704 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -1996,6 +2342,25 @@ numcompare (char const *a, char const *b) +@@ -1996,6 +2340,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2262,7 +3501,7 @@ index 5f4c817..f631704 100644 /* 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 -@@ -2046,7 +2411,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2271,7 +3510,7 @@ index 5f4c817..f631704 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2322,15 +2687,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2322,15 +2685,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2289,7 +3528,7 @@ index 5f4c817..f631704 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2464,7 +2828,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2464,7 +2826,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2298,7 +3537,7 @@ index 5f4c817..f631704 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2522,11 +2886,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2522,11 +2884,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -2387,7 +3626,7 @@ index 5f4c817..f631704 100644 { struct keyfield *key = keylist; -@@ -2611,7 +3051,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2611,7 +3049,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2396,7 +3635,7 @@ index 5f4c817..f631704 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2727,6 +3167,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2727,6 +3165,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -2608,7 +3847,7 @@ index 5f4c817..f631704 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2754,7 +3399,7 @@ compare (struct line const *a, struct line const *b) +@@ -2754,7 +3397,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -2617,7 +3856,7 @@ index 5f4c817..f631704 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4144,6 +4789,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4144,6 +4787,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -2625,7 +3864,7 @@ index 5f4c817..f631704 100644 break; case 'g': key->general_numeric = true; -@@ -4223,7 +4869,7 @@ main (int argc, char **argv) +@@ -4223,7 +4867,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -2634,7 +3873,7 @@ index 5f4c817..f631704 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4244,6 +4890,29 @@ main (int argc, char **argv) +@@ -4244,6 +4888,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -2664,7 +3903,7 @@ index 5f4c817..f631704 100644 have_read_stdin = false; inittables (); -@@ -4518,13 +5187,34 @@ main (int argc, char **argv) +@@ -4518,13 +5185,34 @@ main (int argc, char **argv) case 't': { @@ -2703,7 +3942,7 @@ index 5f4c817..f631704 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4535,9 +5225,11 @@ main (int argc, char **argv) +@@ -4535,9 +5223,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -2717,7 +3956,7 @@ index 5f4c817..f631704 100644 } break; -@@ -4766,12 +5458,10 @@ main (int argc, char **argv) +@@ -4766,12 +5456,10 @@ main (int argc, char **argv) sort (files, nfiles, outfile, nthreads); } @@ -2730,6 +3969,212 @@ index 5f4c817..f631704 100644 if (have_read_stdin && fclose (stdin) == EOF) sort_die (_("close failed"), "-"); +diff --git a/src/unexpand.c b/src/unexpand.c +index cec392d..483f0ef 100644 +--- a/src/unexpand.c ++++ b/src/unexpand.c +@@ -38,6 +38,9 @@ + #include + #include + #include ++ ++#include ++ + #include "system.h" + #include "die.h" + +@@ -106,24 +109,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; +@@ -157,12 +183,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) + { +@@ -179,16 +237,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)) + { +@@ -196,13 +254,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 +@@ -210,7 +269,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. */ +@@ -218,9 +277,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")); + } +@@ -228,8 +287,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; +@@ -239,16 +301,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')); + } + } + diff --git a/src/uniq.c b/src/uniq.c index 8f6e973..752797a 100644 --- a/src/uniq.c @@ -2909,6 +4354,195 @@ index dc6b132..a2abc6d 100644 if ($max < length $test_name) { warn "$program_name: $test_name: test name is too long (> $max)\n"; +diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh +new file mode 100755 +index 0000000..dd6007c +--- /dev/null ++++ b/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 diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh new file mode 100755 index 0000000..26c95de @@ -2945,7 +4579,7 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 228d0e3..b98694b 100644 +index 228d0e3..a76c808 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -375,6 +375,8 @@ all_tests = \ @@ -2957,6 +4591,22 @@ index 228d0e3..b98694b 100644 tests/misc/sort-h-thousands-sep.sh \ tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ +@@ -573,6 +575,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 \ +@@ -724,6 +727,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. diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl index a10ff19..e1706c1 100755 --- a/tests/misc/expand.pl @@ -3548,6 +5198,184 @@ index d0ac405..ff7d472 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; +diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh +new file mode 100755 +index 0000000..8a82d74 +--- /dev/null ++++ b/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 -- 2.31.1 diff --git a/coreutils.spec b/coreutils.spec index faeaf7b..41c37c4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -39,20 +39,6 @@ Patch713: coreutils-4.5.3-langinfo.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch -# (sb) lin18nux/lsb compliance - expand/unexpand -Patch801: coreutils-i18n-expand-unexpand.patch -# i18n patch for cut - old version - used -Patch804: coreutils-i18n-cut-old.patch -# The unexpand patch above is not correct. Sent to the patch authors -Patch803: coreutils-i18n-fix-unexpand.patch -#(un)expand - allow multiple files on input - broken by patch 801 -Patch805: coreutils-i18n-fix2-expand-unexpand.patch -#(un)expand - test BOM headers -Patch806: coreutils-i18n-un-expand-BOM.patch -# make 'sort -h' work for arbitrary column even when using UTF-8 locales -Patch807: coreutils-i18n-sort-human.patch -# fold: preserve new-lines in mutlibyte text (#1418505) -Patch808: coreutils-i18n-fold-newline.patch #getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch From 97967f71c8772354f87dfff4edfe24fb213c8557 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 4 Oct 2021 09:01:04 +0200 Subject: [PATCH 458/523] coreutils-i18n.patch: synchronize the patch with openSUSE --- coreutils-i18n.patch | 65 +++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 1a4b8ff..f14a4ba 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -14,7 +14,7 @@ Subject: [PATCH] coreutils-i18n.patch src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + src/expand.c | 90 ++++- - src/fold.c | 309 +++++++++++++-- + src/fold.c | 312 +++++++++++++-- src/join.c | 359 ++++++++++++++--- src/local.mk | 4 +- src/pr.c | 443 +++++++++++++++++++-- @@ -35,7 +35,7 @@ Subject: [PATCH] coreutils-i18n.patch tests/misc/uniq.pl | 55 +++ tests/pr/pr-tests.pl | 49 +++ tests/unexpand/mb.sh | 172 ++++++++ - 31 files changed, 3637 insertions(+), 213 deletions(-) + 31 files changed, 3640 insertions(+), 213 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -545,7 +545,7 @@ index cdf33d8..b8301d7 100644 +static void +cut_characters_or_cut_bytes_no_split (FILE *stream) +{ -+ uintmax_t idx; /* number of bytes or characters in the line so far. */ ++ 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. */ @@ -1412,7 +1412,7 @@ index 94a6d37..a278783 100644 /* Look for the last blank. */ while (logical_end) { -@@ -215,13 +252,222 @@ fold_file (char const *filename, size_t width) +@@ -215,13 +252,225 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -1510,38 +1510,39 @@ index 94a6d37..a278783 100644 + } + +rescan: -+ if (convfail) -+ increment = 1; -+ else if (wc == L'\n') -+ { -+ /* preserve newline */ -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ continue; -+ } -+ else if (operating_mode == byte_mode) /* byte mode */ ++ if (operating_mode == byte_mode) /* byte mode */ + increment = mblength; + else if (operating_mode == character_mode) /* character mode */ + increment = 1; -+ else /* column mode */ ++ else /* column mode */ + { -+ switch (wc) ++ if (convfail) ++ increment = 1; ++ else + { -+ case L'\b': -+ increment = (column > 0) ? -1 : 0; -+ break; ++ switch (wc) ++ { ++ case L'\n': ++ fwrite (line_out, sizeof(char), offset_out, stdout); ++ START_NEW_LINE; ++ continue; + -+ case L'\r': -+ increment = -1 * column; -+ break; ++ case L'\b': ++ increment = (column > 0) ? -1 : 0; ++ break; + -+ case L'\t': -+ increment = 8 - column % 8; -+ break; ++ case L'\r': ++ increment = -1 * column; ++ break; + -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; ++ case L'\t': ++ increment = 8 - column % 8; ++ break; ++ ++ default: ++ increment = wcwidth (wc); ++ increment = (increment < 0) ? 0 : increment; ++ } + } + } + @@ -1595,6 +1596,8 @@ index 94a6d37..a278783 100644 + } + + *saved_errno = errno; ++ if (!ferror (istream)) ++ *saved_errno = 0; + + if (offset_out) + fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); @@ -1637,7 +1640,7 @@ index 94a6d37..a278783 100644 if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -252,7 +498,8 @@ main (int argc, char **argv) +@@ -252,7 +501,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1647,7 +1650,7 @@ index 94a6d37..a278783 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) { -@@ -261,7 +508,15 @@ main (int argc, char **argv) +@@ -261,7 +511,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -3299,7 +3302,7 @@ index 5f4c817..bd9c672 100644 } +#if HAVE_MBRTOWC -+static char * ++static char * _GL_ATTRIBUTE_PURE +limfield_mb (const struct line *line, const struct keyfield *key) +{ + char *ptr = line->text, *lim = ptr + line->length - 1; From a39a95cf1a83a49d835c1bd2c96f93567aa86291 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 4 Oct 2021 09:18:14 +0200 Subject: [PATCH 459/523] drop rh_i18n_wip.tar.gz which is not used by coreutils pkg It can be obtained from git history in case it is actually needed. --- rh_i18n_wip.tar.gz | Bin 28954 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 rh_i18n_wip.tar.gz diff --git a/rh_i18n_wip.tar.gz b/rh_i18n_wip.tar.gz deleted file mode 100644 index 24b7cdc4900b0cde562b1e8e70e4915972227e24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28954 zcmV(?K-a$?iwFP_rKnZ_1MD1WciYA>U&~*yR$7Y`35qu<%1Xn?l+E{axS|v%P4e(S zU@4*|0R{jiD~|trXJ&VCLx-KFNh>}l1oxPoot>QMKlYXX~*}u3M3>kmFHXN(Aam2%r8J5LXn`L0n zZUfHz&3f&6L1~AXt~0lh%G8}`zeEqNV=hrCtCi9mb{e%FtKwImLBo}^0W@`q&cRj*z%I>&d*jfP6}SdKpl5rg*;kJ1@lur~_9l8A zKHJRaT#j|#sc&uWE|>02$+G8jrfFAp0O%&RG)w#}*^b5EGlTaB=B!z-o7SK+XwF#^ zZdj)yx0{$CHk)X|t#+DwxK;cb;8y2$iG9f?+bg!@#xr@ac}C3T`X*$ z-7MTChtt9#4(FE70+-D=o*DNX`xkE2>-7@5TIz2nr_;$l$NJ<{e{(TDDX~%&T8}5+ zT%Jy*7w41HSEVWqd_5k$9G~kKle5EDIO(4_cHTc71)p4gg>F{5kuv^xwW+fBX;1Urk(jP2GJBuD%vteNA5d zPuBu>%75hCelsQioBigK{Qq4(N1nT412};}qh+=StYwk+;^ReEUz ze8}E%s|J(U5ud?Vv(1`=VYfYO4_FnMq4Zdd1Ulw){B}BIC)@#{AT)`&Fq|vYAUkaB z?!Gy@IGP-fr*+#IvJpUW_zm;jjc0;*vxT1WJ#$yGzX@Wz4!Z5cy@vjcV#KJ|b_{AKhCB3o5XPw|agw<|y?281Cxqs686+A;l^mcUQBz55zu=#*!(Kce^>HxMNsyqot&!m*U4+szF+NR(sH}IIq`@ z-k{y!y`;65nj-AIR3ln^-98$8@P9IGai^B;ImU`;K|eR@iGz(BK0DX&Sk0kdoQ=a@ zo_e0cb$0PrV#C=hHp{k^@QUNP$InL6Li&vLI;bSnP(*}Xi(l`8t-h4I&q723G-?g7 z?Q3|Qzy7*Z-Q7Vcs0pbKh-eIWXazdN@NQ#LAI)FXD0vcd6WB{Tu(^*$KRa~Sx1N2q z2w3^B0#akJr;&a;@;GNxcOKjrU``*o8^ z*{!=_rr|J;TO^!k8(=o1C@>Zv2z0XNw*&|pVF50XMw^%|2|zfd7CsqLC zTegI&63#86K(tXy`G*V84DbLTVV5`da*2+|#^>|RvPLjqG+W_xq&WT!l5#VP~G<1h=pO0&y}vKYR^yM&C@1Cl}wtKG@OZ;&eQn zvZJ$eHezo^=NFU1%j3~GdvkgI=4?6!*J#QSF>?OyqVt^23P@@30DNR$?frW=ULWvV zT5Mr}(cy8E+t+}d0ZMg!d;bX%6l3Xv(k3+?#E1##P3GVd1vTaanlBbXupaL2-rU^O z!NIM&-qr3>K=F6Kg26kxh}D<2bktu6-?6^E!oY{d6u1~P><6TH1wzGr6H#2SKx=UhD z9dwKcz1$)XE5W!eoe49wo4rb?;$0Rcx_fzj7+n-19ASo(-G zi&0N@PL6>#rai1qsW6t8WMqIi^ynsEIKc3Qlahm3SXR6F;OH zKovvw<70|QB|ab3BZqccYchQ~c{RC+5W54fXT^wpNd9CjM4_>t?nzgDSE6ZgnSzu(zg#DRrx)^DWlG_)I zA3L`y(L!U*?8#*wkr@lvE_Z)GYrN5*m%-|@9XL4Kiu}^D56&y?IE^KIBn>35CvYp+ z-V8+OyX+N`97t^CzLV^MqMDV*-vM(SjV8yJ=i|zLG%kC4imvm=xI|Vb3U$}$J`FM1Ee0E6KQ*(_y&rBrp zsR2JESE^QjLMcG_#I}C8;O0AFLFVceB*(NSOsMfGSS#Zx&;(2f?u&B|8N_v#w_sB_ zzi`j3f&FZvJptAitheC>`iWQyP>-vqhL~$*m3n@ zQ!lgG3k3*%0iW z;{l5-ak#gL8JU$iXCn!dOOwP7QU-jUtu$YgxgpH^%rPYODvh1v#RwPowvtjHWTp%* zA=wayV#pA(aHMd4jUA0%emj|t_38K@mmruYqvIr{0v|-O__nbv4sPtcryD0KG6w0Ea?-2YAteU+SkNeu`i2d>)8fTi`njnucx`kya8_ zp}+2n);1x zfs!o4xUI{JBW(~Kx+IanfrutJMtR(^F}T7H2>&M{=ADtkMNV9A@t{bd*`Cij9rHnv z!bLn%*zV>83Kw90=H_pn;)G9e!vD)S;T+g#4ifW?et33ra(1e})}a~NP=2JE!3ch6 zsAfMJeUHBp8~N!bHUYWIl%fH@rIaUtLMmdcAwel5Zh<&VkhJ@?W{XwftJOlu$8v(bv9>D?^bJytf5Heb%Zu`|oG35Ljq++a zQC^lGgFjghn9sLb(EvKmyo!k(Qg4gMpbD zrtD>R=tl2jc^fn4D7~Xt0t##Xeqn$|hnZY%mTR{cznGyOl}c~*)2#m ze+|E>{EUmRxLV%!)l)+dK+9|<9{4wRk~Au+bBGp(;)KW* zMF#bgOXVaGvQ1)vmwaw)mH{cd?XY(n?OWh(k@rV);>t!{tO|QDjo?^hI!dljtW0i; zZg^MMKm5cFh~xVp*1(<{z*jrQ@wwyK$MAT-D?(ImxKOoV5O~7vPx6;m&8e;jkLp38UO(5UKo31sx#p_NEMz=+pr`>h0X+{!$WEB zBbC^e9Sj@8VRJZa4TtUFurnNXhr`}**dGoD!{Od=xV10EO|#VnvJb$VZVzfbB>!8q zJK%s(v7-5h>@0&AaG|wYE|Gt9ek?H+3KcsB{R!>`D`}q;($qrIlHs7;7t+)|l(dJ3 zG&Q`YpA^#69vITpKH?TWC%=X`-ko1d)94}jH9@E1{F?TF{F?TN{F;`{uW8s=lwZ?C z5JHQ>6OYTUX;B~}e9Q^N$NCBb^06^Rq*8$l`FKZutr)Lo#fW`K{!HfAQeAoZwbYQD z{90nfM{zXjQiTqhfCS2iBNv5=r z{){A(kljT|CM}+1iezkIk|`@`lS!uVY(6E)lmj)9WO@wnq9l`qk(Xpr%oHB^Cpr{B4@f*)3{|=i1%f-8n zfX-2NP>6-Ljsc9w#jfFR*8_)8y3pjRwR+&H?cwW>y;`e*u9{3=lu@%(N?7RP@L$go@Es zjIojfD^)x)MeO8cm*jrrNZB3oOSrkvE+G#!eWTI$Hc^tXXxf}u9BwI?vaYv+Uxwo^ zDGTCAI6UugCHF^;@)1Z-Of4U7#T1!1#AMw3OHTU3)C;9heBf&IF7$JR#6~EeB_y+ z`60qvWIZG|cqq4Th$JIgM*upJnpZMPoGk#k;sFgVKbK4d4z$Q)qN+fnLTkoT!q1=M ztxmEdj*J%zfT3kOVNIrzCC_3R>sY>87}|32c=}m!S5=9G;@quTBALGxA9*pL3$7M2 zh>q`s$#FRgXVa<)bS1bbJy9VKg&dTeO~~sd6THpXZkS?w%PkPG>a0w0Or{_-ScHu` zP9b6D$4=r-V&}*Y{2(7FK1=cs^?*tfY*bW;fQUy49m!lGf%9A>ZdA%9hBKa{yvLPz zI}?JErH4|8;m2URB9blby;`4DTk2i&+>01}KBk-K^fSXUF0LRh2Fa_{Oo3(8$*KoR zdS*X#C&aiM%m|rcD_hu%ha$B=nnA7Ey_Yshls-RDk2<~x>Y=WK zMSuO3J$n|#bj$RP6}Y(IK7uMWyeqS&G6xunr!$U)PsLrw6;iQRdE*Pk zZ7618s5D+>wMtC}!F8DuWM!%=jFN&GsphT&of79|fiEIjivr^{;%o6lRu5UyS~D~; zBprS5`%NsIsbmwp;VYA~#7~*vH5*o=WA*Cw#*8-_{bn}78%~H4ykV0F#*4pi(Q1S* z0qWL9KYlrS`4Tqy*D^g-=mkCGN3T9M_Xg3n10T+<08|j%7W8b;(=P10bMvY0qU~=S`{%+1@GpiGb*=+D4>h`a z-4^b@-R+3K^?~Ct?TlqfzCJy>JU<*y(HjGP3ES~KP666nr^l@8Cai!JC%Sm`+poZH zp96lI_hFNmZP{LGI>MF@8uZGyOBHt{$A%>j*;hJ~R83Bcz4)B};;MdqH(u8QF&b*8 zq1y`XmFI5oZzlPH8cQu{nu^A}IT;BMLwuHMkW!%A=<-&pU9TIRz0RI#Wu-uDN+btj zjl>cI%89~PtNFiE>R}@E-})uM-?KdAvr9nmYf-`D;lm5Q)Om5NkBz3A8^OXRa7gg1~%v`Ha%kalwZUQ`f*dD@@Y zkbIyxw77I<2MORWQ~`;AiVs?1z);5O{z#=R)xwl(80k$bHSl}mKSLjk*bL0zW(zBl zdL2=bbl-u-UD>CSo2QbSr;?kelAEWJo2QbSr;?kelAEWJo2QbSr;?lh?UEa^O{wTc z2=U*r)XQ@(J( zlb08-(GHcA zQ4^y@z@>8~80E%i0pMTr74>OI${3|X0w&0VHvEd9Wu17z!VezKc8ELOxiG%)EGm^h zbjg<}1EDZ|wbg3ZI(xat|G>Jb|4Nz8pQuVpbR^j6|Eh>9Q!4eyN~`}+Vb$a6s_s4% z^`ZNw1je&x_~%M&UyoG)0l{<1r~b{})h)M;E9tqlo&qC#SI&`0^IwuD&g9R@q$-J1 ziE~cXiBmeHNJgC4l17x0cw=v!eSm$2y_uVRfw`Ky-0oZK1MDkocLNmvKuLBKCsSi4 zWl10af!F!dOYBb5A2l){GExC+YeDN7s)q-WE8EPZ^ReD|kk}@@vq{49VmE+p4#4o-}&|lc|*}}*a zQ?I!tWzycS023{}W8Num@s*0Sh1n9{IZM;Yfd|i08y6TqH1|evA8itOow@}zfDRoK zJ`U~L#c=a@!6XoT@n^0shly^7{S=L0X_Y9JIlZTNC5_mtrijXZ&ayx$^TVrx0cM_^ zTazr#IbYDMkhipMl3f-2N0Kb{_RV?`d%}y@(oLG!)~dYlPvl2z8OZIL=>4X5R_Yw7 z5F(daLAbYIc?8_Jl6os%E6=_(WLxM6UfLZ<9+x-;=gN^=ut=GE2BQWxpA=FtbwPh$ zxxR9UcFRT#tRMX&T#nT;EWg*(eGAizLfO!G$-r{)f;D*jHX5_B8w!q2NfL{LDt4>%oVg_9@?G8HN}jX|k6Vqq$@!Y3NsC0g z*dvm3j}U7nS-qNOTgOvL%V+3vSO3K3QheMB9{wekCtolYG9}B#!rq~J#TlqTQ8p^ z$k4MmQ$T&yp%X-w(dDv#SzjfW*r=WVCVOI|)z~dA!Y}Mzk)zmx7gXxBlU`CEj3q7Y zJ={M$cy`$PY5(!F9y*e7GpeoA3dgdwRXbxb=_E$mmG`2X3*Q;5lWh~H9#VO#q%t}0 za7p|vPm)+hL~Yx4DRz?SgpRLE5m6;oW*|`=9y@9C`yDSD?!Z0toh~4n8bHpgBARZl z3D9(NO?al8>wq)eToui<{Pq_HGu`}bEYr=;g)-f|Fp}x!I)F?!*Mnntj6W z`_W`iJr`3T8b(u~{`wD~rA`MuSm~lF&|@l|r>Hf_f4v8z*%QYTITkdAq-2lp_3k`= zycZ06FJGu6EW{ZD+GpUdCaA~B;vd$UeHiLnIQlnl9_=4Is5KMmQ2NA{^Q-h(Yq}fW zMt{R!nCH{48=rpL`1Je6r~g`*5B`4o_0w;VkrMISr(f~w#;0G|hYz(TwKHit^up)1 zJrMv2;}@UH-bQ@?^jq@f_vFip?NqkOwqvP2tmnvkRw8Xtu{4Eo}nIoF{1R-MsE!4w~rK*15 zxM911!dobkmAJWsnzl}dW$}Zw8Ta_ON7>lk243Xh&dd3;o#|i_05d)Ifn7=NPT*C5 z+bHp|8xMGvLXP(%1!ydu7jH62jLSmJk-r1nR6##EWfu8ysba`594W}{aEnrMH+Ku} z(b*;2#us<&3r0Nb23aVfl6jx>RREUG>Nt0Jn>Kx1McH8a(rLItEMy+dG*J|ChT6eA1 z<RpXs;QnrJA+cck8*}^$bOvc@Lux80BUR ziiSc)-&nz95G%;kVig!>e{i{HXpUpyr{1=;>?dA^W3|824aYWg!!X+BcbcKME$us| zt?3;XUNhX{VC=imXbj@Wt<1OV{vY&ufO~aj$JN4qJLrUV+cKTD2OPn-eOJ?MEwt?} zsI!jaxGsAF%F&Bp%=9+soxAiO^g>OqVKuvK??;+HKmPLLv%P!f-W}Zs_4>`8q1~Oh z{^^fL3!F`e?y;JhdqITAO+JfcWr$a9ix#xYA z%U(UZb9nD3rWrfB^;(!+c0n=zzy#Uyy^5Glc_d_8t1(qo6Q!wa;|G1YRz?Y7XV4%} zp67Qn$Q;OBnZ@vCjTzz$yFf5#F&id%98Aaybh~*26a3&f;J=j{wZ&ns`qJ?AT-6sL z?^RW|pwokPRfLy0LW(rR6$bz@I1nKJAOMh65Hr|(b3>^_%uqfTF@vowpvvNq+N_wN zjNw4%g}J*K|9}MPaU51SLclj2OQGQk39R? zMZCEJ3q2)?_IFtYV2S+K^|oG+|AuB**Yf`=E|UMg)$Y5V8CtgGX)cUG*A0EUV_SB& z@0yln_?GXreeX-j|HHwo#oDR-hl+K3*S4$VznPQ&P$v^)JLf5ApGe4d8)WWZ$`XDT ztyPp6_z$P=fm*E%fHG2pKg9UwvR+SRJ&5|x5$#-}t7>R;JAPlnWG^7vEdpA!NL)!6 zEoZD!oUKx3InI{oElK`mT>J_++Vypj3+9)lc(dr(S3qcugURu!f@i4TAd-o49C@=L zAJt2*{+6%*bjvKR{~V)z&Hu0BBK~i5{eIBVb+2POrsej#UPsg2uH`vy+lF26KfkctM^aiR>U66PCytenW&p^fCb)n=uo^gv7 z&S)*e9RNH-%Fi_-xB)5FDDI}PJ|c{xv_n`7%$}zS37UPdSS&Xs^3%$%l?wtiSBaPV znLy(D9jl{?ox}+e7eDyv+c2uJH^;rdJ$m}$(ckxbkDm6P z9qvED#Ui8@ku61!(l${^&3 z!~N$^9v!^s{d6tq|1cM@FFR}hjZcSD_k+?$KpkNO{tU@Kf5sB~uU(M;nt8qcyPAvS zzvp!vy{nnN(=}Y%YHM2CZwDO@R)3aZX?7Pb-wdv9{b%lKon6zYlK*ze{+lIRVFZ>f z`Ublc*km}Reg8$PJqx5z_9|x^U^cQ5XD^vWSTC7`^|jfA#d;AIj+$?KZS!*$jwZ$Z zX_^kfB9c!_l>sa@ZdMpqm12gnaaG9~NK2T#>Fp8-YI>`TI-A~;!?70bXCP5I=F6qQ z9dTP=F}NdJJj?^hzzh;a#|%Bof??K7-EsqC@h}f6hIt?WFv*^6C(z%Ft;gj;ydzqk zq0M1FpnXkA?49{!P+{chb7OfGtZ^}e1e-Z$a4$ne&u`06b}I=iy;lJPoWGyP+$F#` zwgRf>4_Bl?p=eIz|I0W~pbMwy=%8?2RG9>0VAu)AyqqquME;v?r)2+aYtFU&zlw|G zzwLQ#%hzqQ<8^|z>zTIQ>1v@HhN16vy0-3xZL6yp%jEwvmjpf|anEi(yG=jomkRte z5%*7UrD=4jCXn~AY6E%S-nC4S_l8W~J2`p(5iJ$=M1M_;;R;4m2Rng7>4z+a9{oz@oheeOu|8 zR(6A%yTh@>S#43Ctoz!6e2Uzmjm^(hFnXO}_%3xxN=h6}3q_8mROV>dV7C^%b<$s1 zAFy19;f?k7nD|7|zoZUR>;eu`xN&?5|Gg4PDRVD5CF>=p z6usmWiIp1G}E;GE+pms_8{5RbVx2Z z^l^tbNH4hc9nBs*(C$Ne!L_fkaDqulP02J=)_hiWk5uIDkxHd|q*CP_sZ@DK@~-E7 zC3{xVVe;oS6E{K0BSp_ipGv*AV79Gq8dU3&(C&8D{)7Adi1;@H-A^DberfxUY3Nqb z{-d|A^}j2*NdIf=uA>L08+3Ko>*%4@cETXk?6wg&M%#7`!wYQ9376@A2Sa}n{LBuh zr`S!=Ww$4RKX9id4Ny1P0cdbs1Jrj7XIHbUG{APr;)8o7f>0Ak&|1-+L%w=vAhlRl z#VYypNph5JI95sT(pIzK6wEhs%Z=0VEXS}_wQq%%?pH49B}N-zuhBai2FPsE=b|8@ z^YF*~Is3!rzd_OjVoc`k0$OH*8gl>w~PKiaQ}M$?@BJN|AnsGbuG)#%|PpPL#OR@+oox^ z+qz*vy5m`PC+K#+wEkyXRr+6t^gkj^;qdA4U);HZ6KXAMaGM|0Pp>n^y*PP>lPK=* z^k-9be4NS9W?T!*5SPcRgrEgW~%ym6b&z3RlZdi z1X(!=CT{|)5MIn!sj5;P+2&Z*YR$>N)LeO>n$DQnU7?mj4bd;TZm}=YExG!}6Zp>= zVP?=*X;E4eEDs7x2(xV#*AUin)9o_A34t@As-|bTnrmDRaKbb>!mOz;#a&1V$A@o| z=%fU#kmjHs&`6j-M^lI-d95ZI68^=qvY8}!|5CZLNXRv zmf@At5<~_|?{pkPRZ)BHgr>}ho-LIflx#Xzq7lLr{^~ku&@qM?nnZmJue!+&@xT!% zUVH%@{To*pMTY1RF8hhA18pyS@MPuOEMTzy0{m(}yqbJltpaMcCeNoTHl9 zxYqy$k(mS}cyh|NPP`QTZVQV)KDc-1@qX{Y^WMwD2c2_JNpsl{{|>|Xj!rOGEydO) zH^tO&kEibAT62Y(+4o{=*w41(>@52$_=PowqhZiMO%<0Gxq9JsP-m8>vl_#u<5o8& zL4RQ)CQU&B-(&Sd_-OF^iZTd}$Bh*BAR3})B=;gY8rDT94};>&8wnsEt^zX81*I4J zH&xEzS+|G5`yT4ex3{K03&zq2~zL@ir+ zr5mqbX-fBXJ&U|Ip2Y*It;Jr|(~>aL>Mik<7W)W;!uD>ly4aja-=u#2I=fa&Ydl06 z<~96KIe$_jH3HA^J9gzPN(+`IQhH0wC5O)?`>N+sb5qO+GSt$b z(IRL%Ld$+(hR_QX=2i9dyU--5nhQ<-xMVKyert%yotX|t|5$ZCP)Q0oh-InN?mPq` zzGf@k<3KN)Fba;jZ_UvVpNLh^Y~)0RL7N%dCSrTlnCgudYbXjjeC(Os~?wde($p;*Gl8Yq$4L;ftsYJKpYFW)seypy!3R9u0LjX& zkNeM`pJQ731G4g|TEMN|=AC{cXT2(bY2#?cGeptFx_U2O-hFY1#Mp>;GOxR{(>O1{ z!_H+8${MUfdVfoHGtM??IbO3*GzP^%-Cps~ekv~o3ieHMf; zjG1a7>1fCkvjTLJ{BL^{>CfoF+<5Wm;OU;;?HXD)5r@I>T{IaDxjGf5VwA(Y;Ypl0 zKnM^F46DS`)8jzkwE;Q24OmlGuLbqDAgGZiT#M;zF}-dvy-Y|0n|L0a1ScN%_nPMN zamY?#R!%2AIbj7KT=WK|;F|SEPwQ9{d1vBrPZC?)WVWr2i50687SBR-RsgEU_q_qL zaxw|x@rX|b5pY@@0~Dd4@xeUCG*u#gkE3y*GJ+hzuZk!qT1SYB1X+vz^fOvmx(o)D z;=iL;Dzw1$aPf(d1n;YC~LG_6FjLXE8R$3lhg z0+r)k20YYijK^y6=wdvJ`vGuWlzv{&cg2a*Q;rLXh_xd2bxggiW`>Q=52Skx?1HSh z@OX9HIA?29x)h0?LS?W&A#E}n3RCEIPU&g!QmurvTG>Xl=8r_VmO=_wn?(|_6egy>YbY_R?_j38>HhA(k_M+vxO|*BJ*gRMDe8W+c!#xP{ylI)N;7=hr&bpG&90xp}Qq{V8;+%}jTR{)tB?0s@hNaF2ncV}Z|; zs0y5}h%tMY?ZIMnvkUZL~JO3WX4@T9=D;@XSEceZ1k zH_p$`byYQQ2+I`v2<35#!v|WT&Pmxt3To3%ZpUevU74Yavp6zkZF$j~9z9$bvaU^8 ze?GMfxyrTL^`}s~Dm^Z^kC9r>x@mt?cCRle^`-JYmGr*XHi7G@s@>5%$8Z-)`brr; zm+lrqbs@mzR}=4-_Ko@?7K)2GO0g;n#aB1zUk(9qi7brnlL#a9E05$(tnMr93Sr78_oY=@DW zU>b%1kIU%^|KHxXEV*%I2hO(m6_+Kq3LqZL#2YA;+LTySGlmjrl4^N^MI#c4L=hG$ z0U-evDRxbGb~6iyw=>I*u%lPrP0Y&nM%_Q+AMh{CJ&*g!2Y@0=YPB1=APbrIp8GoY z+;h+K#bKin9D+LRThXXCCSxK0@T>k(E5@2)bQZV7XO3zNf8!TYjRBaE0W%gwU`8o0 zBL|F5OEke~h;n8gpwYBwc#wg5DZcpO|1Bk_@wGgCNAo3w(j5p6_%d3bo6v}Uuif%) zRb;oC*sDbLM|MZlR(FlYPww6~XK_#))k65gvB=4Mk`!zs4Xgrgyf}>KXiw@xtNb@K z2wpTNpEjTcc^*iHES_U{b{sX28F2{)F41HiuckBM*Bgxqq&tF>dpsS3%=&!#8Ze6v zKSTwzj{gRdGo6mlYpi$_w?zbsyV5{2f({{&B5kg6_`x0L_N!lC zU72}1-p*M1z4JprhSY16dciQI?0$r2!GUw)=vk}@-#&t}BIE!VRsssAV}_GTV? zH))=@G37Evr^Q(AtxlUP%8O2!4_D%f8&Tql_f_KVUQaHpQ&oJ}y{70^WBVhG3O?}d zrWdwHoqki^Zbr?1*!K%>H+I#`4afe-33@svKhHJPvkK4=OQHTGEYE*FHs;DY4y@S% zUvaeJNF2QpzNjC*wYk~UYqpZ>H(==`78Dqo!x;%&D^Mh#`BtP(JOmXsQpk}=@(29u zd`=OHjJ@367Un~_-zQ%AGRl6 zuUOBgs^y%G^uhIr>~1?3-BWS;-G})1i9Znw^glJ5sE@=qucBBi=1BrytWKs=^1K*+KjZ?5WkA*F_@oBzSKH0)G8*Wj+5fODPd+`$SKk3$ z5nBa1`}0@)WasbnyZzbwXL0s^Bp$}JJ3jJT?J5NRoq?G%P9LD*zyIC;uGj1T{&)XJ zu7Eg_e;%bKEiId9wGVe3uSi=i$+k)_{zkU-vQn1+-aR_|3;*cu`F6Xd4`Vyz-)UhG zO#ETWE(@Nl*yeBMqolT&t&`n~`+onAqR}L#W^bwgbF|d|5L=B=5!yBhTMj3h ziq|sAeXWAqdHq&5fJ_SARv5~gb`Ce1s%Z10sZZPD3b;(@VtJI$qbBXf(WXem9ij~AUGwDA!#8KEw`Z&G(OQf@vMdNpuS zyB>&<2*rhvy^*~6Tk(ClEb8JA>WP;PV26eIAv!{O^>?sIW=1Y01N$vyfy3r=z z(K&9{mxc3L&CAod!3Ug~Kbn=<4(9B8p6zGIv;EP$EBE1Df7XxZdHtHwUtk6RN?uc& z%-8b8=q(3o>B$?LR5i>3c?;jR2>;MlMTRR zcN7rjG?NBEVBFDy=%uN&Oqu)ujZAD$IlP<7@kps1<&|~Z3wn($$^SOzc$6CtE<5la zo2-t8)QX7_4!6##N~?DV0)ES1>gSk#(k}@5jRN#kNOqxvkORhXa?d!y$br$?Auga!Q9tq;T}mW8{e5BZ58$&ac5LkbLoF%?Kpq_GfIqKA4l27~RX$Q-waqy7J}6Z=;7O4GUG0SnH}S~J zn`iF-i)fk5<6u^M{`mgm56=5y+Sqvi_qv^id;j-4ZTWeB|NjXdy#J3{zTfWjMxHn6 zG=fei=mlP{)$MlV(gdAuw-H7iZxs4BcK`ndQ|h&?`+sBLwFix&4A8!py8kOg6@aLG z(}zE6Uw-}Q`NPlt+w)V%>IcbQG6|H;JzZYYZz+4T3(z6aEiDBob#YI%GD^L;6-SrU zq6JX}JfWvvAB9oSY0`C2=j`NrU=1Wph0Yv&Mo+pdh6ccg4pspU98@I!5&>1%-qh8n;cN=}V0$$W?wfpUUM-qieXWS3H*3HWQfDr$v|7PCrHB}P>c0wStfLO{r>5^8ShH=^10ubm)>M1cg)O)&KvQJ7o` zKD7l@Yi3dcwHs-%VSAg@kj61Ge=~Jy`i*wmpGfM`nS`UxI4g6a(nj1wzfpYBLlc%B znXq8yb%+`kiBEzAdRKq-sr~Xik_=+{W%4$;yL!8jM8!_QA?&A)xVOQVw?qeHsL^cN1`f`zvawY>L*%GfoyXkR?BrH#&fx| zSIXi5u09E%8}P1(j+pYfKkxA7wiLWU>zo{;fjFCInq*9u&IKCqsQ`^L@`5y zL=Zv)0%O)s1tLzS=V0H3!UhG2k(~PrlQ<=HbFIb-Up;^m>XR}Zx`dV%Q8<+&8M7?Z zo(`(6XKOjsg-I6cw>};c&2ziV^<{#M>c zuVrb8`N=Cdp{P_9Edm4FF<`Z0utm;uAQnlqmgw!)z>6^S6D=b?|J6NIeTa(ic|BkY zvEZ9x-SxWcY-o^mxLi2W1->-HypV_AMQwirpHFrB}byVFR4qiGKFLl$JVGwG*i)i_qk8n7%8RADkUiu z78ipSMeW4EgGaVSRcZ7%_+wkla~n#0{ITjU%X%u6gybqb9SO-x3{ZG!&952~+VxO= z6TtB=kop5+fF&591rapnw!{)x7eyZ^MR6h?JUo4LUs4gWh~(tObp4PNTAo@MP6vQK zeIj?_GI(3pbpZ9(voY2jMTo!iL{c-^GMEA>t5QPK1b$-|5-7kgMt{U`EDq z*bGiAY+f)5!UGWNO19KGo`~XTjD@XwtD<^}TPxFDXKz7?;dK1w_&|32E4_`~4NNO3 zCo-9fNw8GBfUNNi8z;&EjiPf9(yJkA>YQj^gXdhCVutG_8Ylu}W%c(=Vr4J^!X|l< z*TANnuWg{gD#%)BQ4}T+$t67pFjJ>scV?a0 zu-GaXl$xIOKIh-i=8)cDle_?$#-%!J1jA66rVOa^iC8Xd@=^1FwxRc843vB8AN(8Ekk;Q`aH1ImPM`g8jDLAE>iRW~GN)L6yLsDHWeAQ_OQ|9nL$W2QpC2WXkhm znhbH1k(^zbeYkB>qX$L_Rlu;(p*iOXEmyIYtd=QGb{?*_3XY|N!bJy;Un{k^r0R`A z${L#w_*MSH27hHO+Le98-3WcpA>f-?d_&jwBz;fP_ayy#Bt6rCJw^RdDXQCvovCZV z@mhd0rhK$q#&g>l=K$VL$it+>djs6nCfF;pS@cB*I`syx9K-Q6!pIM}pJlZWY~bUR;=ST?(or~u0}^$AIh z$3tQu1^@uS*xuN-ZQHhO+qP}nwr$(C?eq(s+f0#DXd=h`J9-Ig)5`>w1VWrslNJdE zlvS{oXfAO;HAD?emq07ZsHnUwX4Mu@R`%#I-3FB`f(UH*Z5j9X(biA~AAK^puQ?W8 zof@AN4)h80Rl;>7xR@Vd4u$SqDaX6lg%^$4U7c_@Va5Z$ z*7M7sh!@^n69Pb|?8;phu*5&LOC`iK$?Ljv0=jhv(7l+o#!vNzyDXH3wn*MQr)F8I z*GacHwhW!+gxL%bvb)bRMqJFs^c8oo$eVO+xR!P@qplY|a;?ti5EVnXtY;QakkG(~ zm!28Y;Oj1O+^w}o&C@N%Sa3C;#m3s!M>M`ARqzr{b55O(w@DW~ylQ*!jr=;%^vsP$ z>zCtHK&28!wRr>s1Nz#0r$g9vhnw}Z*H19D0TZo$2Nn6lEJBef-gSs%zfBT`UfKz) z0e7--5EX|#nefiO%;jzb0CiOu^7R}`%dRAL_`LAx; z=4muzw7I0p$FtqsMk)>tCTyaaWF*g~ci6gEq{2&Hbko^{iB;Md2JP&An~xFR$As#i z4J}&9Tban?U9y;hq!=}t=+)?k_g3Q7R&?nI8W6S? zBJ7at)cQ_k<|{JLSjUh>4)C)m6utRlJt1Y8H1l$8ELvo~B=xjbH57vNIi^>{|5!$rn0u3dUM z`{w)L;(60XKrv~M#5W-%V#pd=3=5AO-IfbGGRO94SzL>!}E~#})UU`hwywRYOf_9epM^1x0`ZMZ#|y z_EyL0d|G_zX$V3$QUn-M#`Ga9Iv%cV;3$V?EUAS3pu+* zQpa4rQP)aL=S|t6+B_b(55bQFj(Cr)g-ifA@EsxfEdK0vN2vpY-j+|mAOvY=Osv}z;n!)%#|`pE-;eO`+4z?kprQJ z%|=BA;~oDfftZE`OgZY;wFLoq7#X!Hjtf6{hXC{hH{NR z$DAsN&mKSjO0(LTt z@%gfT{V{LOn6jPxkva5ry#0Mp;6DFdxc=&{*02Fe+{g|cmCurz>p@9 zn+M0pIuHHw!8-6k#r(-x?Mw9TJUxB;VV?g1yK@2%Ns1~@b%FD8-15Y@p7CsZF>|kV zk*)QBXA%G5hF|mN3Sgk+iH=PPgI(G_Jsd1VSL1n8Hfz>6tYfWQ73tRDyl!p`rAB2H zrRwFku$z`z)brnZ((;T9M&|`d#X%!~#y{Z_{azmeB_9D8_hf+_tt}BN+6wHeFCwR) z{(?72O76Pj`r*->sQ@xK4d6qsOF%(U&h;511}m(_0Ybw*5Q!>Pm*`I{CF58nQg#m8 zN2iW(56}l6XDd1Ns2QUq8sY9$ns}1IA83GhLNd4Jnm1K|Fi)L(1^nW#z4euE_~I2W zijaZF^Y{4U1BDeGJMP1R{p!!7!(;{tSkarqgXIk5bD=+j1^wy+NMFx%Iw-fkQEr!L zi6YY~IO0&Q!Gcu~+W;t(6qy$liIxr38gZ?qQo~?4x~sIF-}md{oUootgv7>PCi1`M z2eaXJ#h2(z&P#^*=^Zq8qvcjiG7Qg&7b3sZShmbk;|97? zZ~#)d^y_>ZQ6G2SLg@iXl5m*q{dE8Pq&MN#545xggCZM>a?Q~3;EB7+O|7M=I8Ayg zG>EnL7SVk?mz2L>Vyrx9MZ%#S=UO?S^0-|AioUD{>P|_qB>p|Iwpy<(e#f?^>MBEO zx}9FkO-!<(n6)`uA*IF(GauAu7FC^+B7sDNSE)bED-PXGvvY7ho?xGpRMtH+6wLOS zz3J9AVTf-Lb1`WfATUmK_T-fZ3;ECT@`i4D$_PAjI}^Y@GyX!Bf;uh7T}-)8vB6~S z`7)TOm|_7qYS@ya#Thm+pd7*d{WX2ZXg`!x@6z6Ohz=L_jwen0VPkDhE=;c1*VD7g z5%>UPfV)<{H*+PK;b4nk9>2F&HeUe9`-VSgdG?e)D0K$=O`Qq_*3B>_AXJaP38Csk z@{34N-%uVj0PLm8OD|V-fNzqg+F)|oEFUtgMaXeU@JbY)S;dj58)8?Qj+kJK;jx;4 zbG6}J>2f@B?$8)#u*bPEw?V3K2w{7WizE!Ed3KZQ9*o(;bH>5(SkTa8we?mp;FZZD zwygM*o3w_o5Wx1t6)gzJGj}rAvxfG<#;atuz$7_Xpn65O+d*y-SuhEVsCQ3Oc^7Ij zwHlEEBISd536E6S2g-wdV-6luXO`#zhPiIPOEqbG{6pE6wO(f`?$RWUw;}2*6^uYs zLT(IMruNt`PhJ1`PO=0ad#5!*_y`a3Xyn?X zV(UijNB8ST)!O29zu`fn8!y4b#JD+9{$D!OM1Qr~zX=>M24ji(ZZ&ODja$sEJT-E; z4S5Z!rG(cA?Hab72&2cT(8<+-u#)auVwKtiEn7y3G^^9pC$f!18l}X&hQv_ct>#2Ci9-lM= z#tBnmt_78A(@1Gl^}MT?g9NpiCVNO)Y2f!sRz#uO z1GE>km6mjQn}oSLQJ9*I^2t7m?2_8CY1mzu{`@DI@KKe*V=OE+N@5KTAeGgkEK4en zL9SLf1}bW~`{)m@x|-@qH2V^q$@S8DTUziZnCOUZ!!g;UsiDRd5}n0|@wFU-DJG7b zcG1R9y8d6`0H)v!haGq2hK53JQt{Ektjb96x7)wZgQlf}rlr2m&*!Q$_`3$1g%+IJ z(zU1d#jZgC6t@YbUNCyH^JRVhQxH~r@4CraFTqj3sYV24Z3s_i6P0&@EnCdrB|@Le zBe?JJ^aMqXRbH|qE8>ON$ouoC4M#Z>L+{_KBIb9ll8}rNuB%!W~a6WKA=44zpd~;8QX2<=kq-?le zYNmiR;Uc=>tC(@kFFyes7RPwb%kx!~%l;niPK22D>-84AdAzsM?NYiG{@l%q4y!B3 zy6vUqf5u$G8z7N+b*X!la6QP*}2o#+E$K{XQLzT zlx+rzjYdu8dVm0955?h@UT_1agPF-D-xSrT)Nip=Y^nCU!oL07x9kyGvxeQ=nr@dQR#uxhAzXlMTw^#Qpwz9{St@MD%omztZPtBi#&0lOlwGCkimyyY6UC;H z8CUcJaY{YQxh9zc%q~l^rmagc?X&)NQaw|>qJA#8b>syH}c|L5iTQu!A%__ z$2LYVYyu)-3CQegLNBBnN@s++&N5x0&r*90G>EMySNeJ|HUb#|V*bxQ>{>y0(Ht!D znGit!G_O|KDm^y=yoD<^^}L2vY6Hx;b;MyTxk?jcZ@hnXZ@ug_P?9R1e+NoP4adn8 zf8nIh0oHaCu#aj5Eq)|Q4nao#>pS6kS7dFP_f^$zI`g7M z7|*e*iEH&AViWymSuQp&%DiB1KsC_hJeX%TUtU*ThMA7mS2erVt9vCf*D_g}Xq{CL zWUU_=ik~{OX+|9vYxoX%j_7k%nDUJ~#yz_hUkl}Yp76kvU>%>#oumGaNc=!+KvE*Z zLxpx|BCpBf;*YSDHF6@TDei1xAZ4KQa{?HY8)?HQswyd9Di$0nq6h4m;S88Kmzj?z8r8a305jYGgvoB7PinLP4yaRWW(f@2mk41PxRnOK_i=pR zdw9PL5ZM-iX=V-HKB!gjS&9pd8rJxjEWNwZt4$a>FM2&X-I0fzBh0#FokTI&u^?u4 zyFBjuJAIfPRHeF2JlC{31FV_Lp?ykN4_~c|gQ|jmV%CK-NiRmsfY_-~T2M~0ZW7qk zw$u*yyfo9dac3Vhn8a(5mP&nSd(9VYZ4DfMLR~qNfBS8iGd{m-dB*}@ce+gGEQ7v% zE7%?aeCTah0ed)aL%!!B23?3QTts}=tUXvwf4;q`X!Eu0ZR&v^Zdprx<3+XjKSKXz z`VeKnf$o^HW*)7dl_+CQBABn1l2Q%i4Ev*tBY{k*gj}LsziU^&|c1{$|!U ztcG5%N|xwH&&-+lVgbev@|-hctTxu&<{b*Q>=~hu)pLvb2Vx~8KL}y2{2e(UVll-Z znWIcKoLoC}$_A|65ozX%@F>#!lLQArOiFqsUvsVB!qbyi5fFI1v1a?5Eni!&pVL7& zA)qlRy5aJ<^Y2u!X0Vu8|M;bdQp5hpSlAiI;X;`fB(vvEi}X|HG0Bo6pmBT$CKSTw z&Z64zo4p^uDYozCpFS|wcgE_7q<{Dy?t|{Pj8VmNJuw89kxr7r(F1db2B=Z6*ZY&D zn025&OmL5MXporLsVj(PCWgI!o3?mr$_pl4q@Lw{JXwt1IoIFv2Mgs z?`EoZ=c+%M?N8kbsBr~r-GsY-neErL11Ej(Q!_Wq%8x0MsL!ow9TGHYv1%~Zx83sZ z(4s>rn~RmdChuiQzyhPnA4**bT{v&diYzH$7>;Vqp(hUJvk(kijZK6T%GVbNo<~^L z8{`njNE}CQpQx4NN|Yr?rulTo6$9p?&Y};Cl2LsbNWu7^JHfF4Foj&t(*>595GV`d zBr=>s@hkSxH8d7$hO$5cM=Lcmgp`b@bOggz7sRDUjVc<9*%xT_#)-MoR!GIDAxlU3 zP62WJmFy{a)pcwzW;w%eLY1$F;77sb5G2+bd@2XwUj|TT)UNM{R?Jm`q&Fm2cq$~s ztmZi;r^`H$45**P>xu&A2COU|5P(~}nx^5C`UuMTj!WpR64rtHS9Jz(LpzWT3og@* z(((Fw(5hfD3EZ*bb0=c_>*k9H7#rbiYK2ATfO1Z}G)?xFIAi*7gD?ZyOj9pm*{==Y z19qgJxj>}lH6CB8iC3&sht{AHP;^2w|KPh>d>`U6L!4As)0R=h`yvtBAeq*UpRFRSm*D2}MR0dlw8mmI-HDk1F~lUBzZ%^L00juTsEv z0U_v=O^}sVogxDOu=Z<5GsMN)@~e92UJAu54yHye z*00oF{N0~^`)gD3*a-DrB>TF|JBt;#W0K-Bm`mZT-vqVtotCj*-IA%o&xC4xGMo_d zQ^~`Tfj-ZX1&zC|O&QzMQjW2Pvo5$9Nc9rah_$Z(-(bfCEjY^HerJ2=@wrRRYmqr7n)45Vp@@z&X8Io0Z!=cCfx09OkY?;fV1RHPCbuuOZ4*+tW1!|Dk*dG;!S zoA`z}p(XQI8n4Z>@j*`Qsq%awLptb$yJ`ngbob!yJ+Nam!TZTg9O16dof_wKe6#kf zX->L!E#$w6m0q&V0)9j`^o<*(&)rI7J)@IL2@bGpz)S>QJTnf+YV+?hp>?gbX&p{z zOnUneX(eTL`@B8SsZI&Sy2y8zkJUH+!Cp7Yv&*Pz82r+I|66u1)%@$UzHxNid&rdf zIxTle8#xqLl@j!a!jgPxfUtYkJx`O*o;*A+eyEcGv3aSIbrUZ(KR)(VW+*(F3xTzsE?%5b!$Bns4J^?dA*z3(%DTQ+eyEGr)JAHk%Ej zBCXYqq4)zkMQ5UNUwV*>BN{UV(rGp!<}FruddR*<+3lPHYjiS3?Eb8Y!E@PrcH@_y z4iHy;=_3>S7$J2t#beFqI-t@P4(n!=D!GfHsY?Bq!P$9`2XrBRlGWVooN5}l+&1ks zhVN{0BF(4!9Pg>R^3RIJBc~{0h3(tz5-IykDf?;HK*C<5G@|v|6xg}N^Ef$QDrt!t zWmeeH+?Ao?KKxc2|t&0##$ysY9!R@Ro z=he!EY0SEP59K&mLJzYJa^-bHqxny<%?vkWO7pq%AYf3{2b_xuW4SkSwA)&*b{Ut>$ zWtVJO#c}bxxwA{S*|+R))8A{f!G#nX7;tL-yr7ztOlHhql{`&}^dIAADUwq&u|$wj z{nA5a%q*=f`A9G0Aj22}U(q$@(ZEdE%6KVW`(1VeIT$U;NpoCGQ#GkNx0xAIU-G;C zDNbZSy%P}f&Yj~UT5&n8fW*axBO``71q3x`m8I52hkG7>^2I@r7d)QN&olDGYrXTk zi8F&)Q%ZD2wI?W*8 zSylHt#a==zb?>%3VpnCxFQ~O1MdUE$;jx!AakTZ+2`SYRQ8Axpnd4apTJ)3(lM?vT zXajBOo+z1_U}q29fVUp3Y1sGXzP+c`RhCK;jKeq>hGOKK{3$ARw`@(}9qp$oO58oe z+(QfopUBdS5pHVru8|dpRe!(_QOEV#G9tBsvcitG13FrVwLOd$BqE*Wv!ChazEBRf zTgMISc#>Pyv5&iyapkMUXd${iyLZimeCKGM!WW(xY2-g4fw~EWSjMoAZ2A!Qxdh~8 zd`NQwEIesDBAN_8xvXsOt=$oWFO>1;PRZr$X>G%Lfxs(nX(eKBy`P6yUV7P3??Ulx zf*(+??Cc%kZ2I#g^KK*U^6@q9Wf;Cfk$Hj?X0M{luZ4u z@J6$(l{2og>wW4g$NxG0zLKQ$#ZMrg^W0Mr)FOZC~0@rFl zxI}?|!RR-*=gqEk8X>WBDX&KuQB7=jnYnA-oXRS$fnzC*@>y90xg&jl;NXuM-J2la zZ-4o|)r&MOiZlyVrE745y==HGn7MZ`qB;FhpG69H zr;mKzz?|c`Cx1&=&6&XTdXsN|77CwXQ7WTfV!ci~Uie|dUdBG-Z=^tag`pB(_*h+B ziPgMbzs+42rH=pjn;9YTF?Ux%5ZJ2|KC(WV9?Y-bx)pkGr9Thav(kP6rL;Ei?%685 z=UE5pK6Tb8MqFF#cL|v?J;5_hRG%MXJ1# zJ@tEoEeO?-2_+SNy5RtyMixF0$NNc_*i3pGyoI@o+#jDG(B$rXIELM)!yG-vheqsJ z8NB`XEGXUoLQmEe;1}FFBlgu``~lIJ-%A`t^|7Oy9Wb}uHR!$kThwc-Pi52;Ll^+UYX=Cr zp(!s=>35;n{8!7a69Y+8A7{DxhNCExCs|7=opi>^N&o;@yJHEgP&8?4`;*8c!Fi#! z8N6|r&dc)#;y_=HXKZ*+Bgfa|j2;Sqr?%*(+@LJSxuz*q0QYJx9*e65e4s=Z%qznI zM(@CAm4$FNaB3@ctz#Vgd}yQ zPZI;PE{8~+G@bw@2L;R4>so^(U+V3CUCsHq++8%KfnnK%m3id^6SpLJX5xrFtT1RYzHDv=>R<{GB!~%_J{vJl*vMs|kYa>MgWD09P zEWTZ%PA)|v*c~&c}Ql=ezk3O;57r@VL#D7r!aN7t2Q#WJX4u2 zkFLTKR2GMKjztTvtj6UEv`sNBPBu9{6<76a%mjs&5fg9wsq^IWm1F|)6NUr3=)Myt z{m!#w(Va|WA;!>Cu&NZv=goj4^;j-zTXKBLw5OkbQOVjGy4U7J+NbDnD3@5PK~u6K zmP5|_PnnAevgIE*UUdomry*nt@~VlOin6u4aBh{A@QoE~mT~vi4uuL${NNyf2VdeU zjrJ@Z1Fwg@Z|rFvB~=}9Tq0A4J#!%102bVeAEERlHs>V2qi6YYyiDWh#rxzxPDQfZ zMQxg9)>yeg3`&9kqQGnR%dFq8$j+)QO>Db#L@-E#=x7;Gi%E9RhDE6z3OYp&aHO?l zfMlz>R9g?}4{N8Zj+=?hc0aW0t`J!x^$TZ>F^I^P{D^nu)YL6vj{@n}kVxW`WlM+$ zIR9gsdK*gCxj=C_Ax~pdc?7=o%X<_i6>}&N4hQ-BT>mz#{kU#w5lV~H2_K{PV%M@D z&JWor=f|^zkvsLX2zvNOxpqM^;gV`Q+iUrsPf3a}M$^gXOb$>ZX@2;t0+vfzYaRqJ zadX#wUA+rdtrajX6xv<5Gz1cfmmbMdEX^bKm@rOKuT&I}kWj}2Qzm{B+XPi4K~;-R zoRmiU$*g!F+>y61Pb35(#8BT7oB;{ZI=ng~=7E^+d$UPW|JsI49fHQfw$aV}f@) zNq(g{;!9@T#fYto1JLR+M_Ze8Bv1Oe=A&=Ph#D3y&Ymq86pTm84G3qP;w&eg-^I4*n7#1GBgshz{C9 z-1~iN&SV0i*JpJ{rt0E4SJp%{d`=ffrkGYX!heBV$=CrC;^&>>Xe$|{6_1o)AE&D| z36@|0YfY&FNK@`>g{SmcpHn+svu)bv6;L8hHR)A~omd$g>$}De{@Orzy^(```(qJvfTh9p{h+0TCiN~RylnE}H>eWj*pg2E|mVj#XWA=-Lc^3Zr0WJ3D zxgKdp+;!}wBAMM;M|+mibTrzKQ5Np9pzEKOjjlzLwB}ZS!J#q*%999_b&GE`MrqJ! zxq6tLS96INPPgrk7^E&(7p`9CI;(Fd9-Hf{1f~Vztyw}l;W-_`w3bwR#X+U=nnhAq z%Jx#yr4P&mP;eqtiIJ9u+C}tiv|}nD94|g(?NFdP!#VjoOhWP+K$dxlKoX0|!HbOw zXso+c`KZzb)h=JH`AL|1$;9?%=C%_Sf_%~q(HhLKSN{f%f~f=sJ=ogME`7!O)I|Yq z@>`+72mLNFhq+(7Q4JlsW?Y*vPND3Jt)=m1I>5ofz8Bj9X@*xOo5bwgoio333achb zIKjmQI|n#~*64S4Zhhi;6q>;zg=V%F=-!XnKpQ1A(NP&11etzjb6v;<>ox+SB>VOb zqa+u!6VVugi4@CKiW>K?kaum!jZJjXcW=Xs`ogri0be|U?5Yu|mvJkIJ?L_#OX z7j#l*)YWvz!?_JF57y8*s-}Gk!!Naco@&e0j zar~V;(*>?w&D&eyBZQu4Xy;wvMOG;2#1lCo!898I_^I%376 ziebc^7C&)^eJlr~U%0xLa4z7o#Lk`YbYQ9L2h*CpQTRz|*2_@+`jHn9vrbT@8I0g` zt7Elw#|Pq96gXToS~0mCGJByfoD~+~bwcm8FWZ0*D5 zT1;G7zno^|XR!x5bnircmmfXvl0Hg=4A{9ylbxPP=>Q(%;*m=aeJP-hv-4O-7R>Z{7Y6V<>zqGfQjt9Ot6 zW*oliXHdj8+@gaF%$Dz7J6}Az_TWB|uQ+cW4b~cQc(31(#pBHrzU$&xL))~|;OV=% za+kzTIA!rt_(03z5+6V3dy^U^>ZoOZyTpB!`kda_`X;2HiWh+bD17T!GixoQCbEhu z-)|L@EukHrhwfsdj}S8tqlWN&(XvPQzGD~N&h4^OPTT^}8z6i2+aGl?SJ(mL%vn2g zb`xGB6mto~jDxZIQl-W?e8CUHp{ke({C@5^kYAYUIoRUN-)n587|UyFtpQx@$d%Km zrMfb%$_N3+4^~f;mdnYWIAFBahf;O2m%>AM3|}y{;ox{X(JNrsOhQ;G(o%!s$RENZ zLZxZh3IoEAMvX!b>-Ph=WriRg3+HxebsrELEe0rE=aisT8@leO(*vh)*&rSjb0aC- zk@opc{T1tU_+dfMwV9s)BKH1#0I7cu1FbZF9v}CAe((P7xAy+F@O-I$@8v-4l}G@3 zcLb*_3zTXjgW`lQym6=5AD)>Jm!Kys!j#5gkJ=_LXz|TAM)@N6zPI52D1F~=;Qy$7 z-_Q2`dcLpV`(~~bZBaUOU2)uyHcO*m<(5@9JlZp4!=>@yco{X4&=+LdI7_uSq<--J z9{J`D|K8L7QuaE3R&cD>_-#%EcR-c`$Fb&~`TUc2i4mH&t~9bB@xQPB;`tf9BJ+>f znxBJbpYDhgseji!8$4NbVxzju{UItTok8)Pjj^8cmg6Q~m6OT*xhH&YV`aX~%D~a@ zH$A#@WyFN`k4O0e;nz+7==yfdon!vgs=oA&sV3yFfBJkQ!P~z%IiLh6r|N0{c+A~> z%T7O9M77?3^LH?tw_Ze>_FlMtVvm=&J%swL{B;&8mNDIP1gaG5n!j|5c5d1_kU%R( zzch2yZWySKeqv>6d-7mI5;6P&i^LHnk zLW(LAC$>wtO-cC0jkr{Mg)VH(oNl%&H+12M8J9jH2g-G^V-u$W*wEjD1dQm-;lOGJ z@_Epm!Gdn}=doZug8+joHsDCNL1WunW)Am`I|ZN<+``(S!szD^^bKIyL`;7Cm^le` z_jd?ptpzIX!)dYZ;2=eyB1t;YA6dc>upYWzoH1gWOz2cL=w$Qwd>_5vtCqy%LLcM8 z;`%Um`F_3^Ps?xa1o?v;g|#*Fq= zY4|;QkOWerQBuDrT-Wwp8#>a7UE4dtCNratdbeB2BT&vpe8_?m2!NBsIoK3!(L#OM zUHH2zCM7ZlttOYMxtFE!c}%DwD)gA8pzTb$64!mn`lBKFPRIBc11!fWSEMeEE`Y6& zQG%vyv~Y>n14=IZe~(`cFP;fa78Ai8TTqTE;fu3h&)#^kkRn%?xAfA}Na}Nsu8kaKuVLZ4%NdNh94f=+yncL%>j{#gXK#eYBs2gJ({{A zsiJ>#=LSiL+YZ;#>gapf%U9~F(v;$lrd8HCLmBd<`$PO4m)*1V0f)=u`+-tS9+wa+ z1DMHCDyJMEluewxW2%46q9U55kite1%fc^{Sy@_yG%a&DxJ=VY{N)uh!qc%(_*$oC0x)yf@8eFZiB5cs%@#^Q&vMXDaZ?qbS>0XL+Kc;^3vUC0}lG- zbW;SOB;))1moRyD$Vw@wcGY4r{!m;3KE!t7D&6hxe(Ugfxo~*7eyZx^`aFN{cZo3L zDKO-qBngB~TuoqX(U~!H3TBv!*n-cSG*kUkm{5Tk9?slP@=*a(f+YudW)scF1A=-( z!8v=9=uN1f!DkN2$Y?(`R(DYke_f6)E_%e`aQ$X0K<6zFjoJ!Drn58kZWL9Hv-uuM zpU7l$_)=dLS)K-AQVi=lMD<XCO3mm>>2lo5N})sXOUpC0L`hnf>c;zr?+h2o^+L9` z6PC+v$}sfIo}9*QG!Pm&*xr3=OjS5tS>{a-$|lTFhxZ~EEqS$*eAVWnRsKvmv|H20 zzyjKbv`z7LLyC2*iacu$T2f@@YMpYyb#Qgy^YI7~){{E- z<^3kbA_W1*|Ct8zrh!E<+6>A!S(y-`b;?!L=e8H6?bdUgd~>t}WV2so zs9`$rD>VZNUX;Ey;^{DroKpU-3ZnK3uyXfpTKkhvfy;jQv>9Ehx4`VJJkj82iK}F^WC{| z6~dVFmLT2SAZ=jpBadQ~LyFzU%4%rVllY;C!qiz;m``-F1|X&)9;~YGYijne;IfY# z6Of44^(nD~$rvhsnjq_W_i8X^ox*H$jNfN-`p~i<2`cKl3OAccolNbZgJN~PWhCwu z^4vnO&**c+F#br=ps?JJsYc!8{WST#&i!uieVP4T|G#`saR1>!Y3|Sh&;tSd2TYcV Ap#T5? From dddf06a3e5815ca599a4c90d99c4e36ad3e3a861 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 4 Oct 2021 14:20:36 +0200 Subject: [PATCH 460/523] chmod: fix exit status when ignoring symlinks --- coreutils-9.0-chmod-symlink.patch | 114 ++++++++++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.0-chmod-symlink.patch diff --git a/coreutils-9.0-chmod-symlink.patch b/coreutils-9.0-chmod-symlink.patch new file mode 100644 index 0000000..fad3b7a --- /dev/null +++ b/coreutils-9.0-chmod-symlink.patch @@ -0,0 +1,114 @@ +From c76e70637e529481478e26683ebd73c40621c382 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Fri, 24 Sep 2021 20:57:41 +0100 +Subject: [PATCH] chmod: fix exit status when ignoring symlinks + +* src/chmod.c: Reorder enum so CH_NOT_APPLIED +can be treated as a non error. +* tests/chmod/ignore-symlink.sh: A new test. +* tests/local.mk: Reference the new test. +* NEWS: Mention the bug fix. +Fixes https://bugs.gnu.org/50784 + +Upstream-commit: e8b56ebd536e82b15542a00c888109471936bfda +Signed-off-by: Kamil Dudka +--- + NEWS | 6 ++++++ + src/chmod.c | 4 ++-- + tests/chmod/ignore-symlink.sh | 31 +++++++++++++++++++++++++++++++ + tests/local.mk | 1 + + 4 files changed, 40 insertions(+), 2 deletions(-) + create mode 100755 tests/chmod/ignore-symlink.sh + +diff --git a/NEWS b/NEWS +index f2fbcbb..5722a8b 100644 +--- a/NEWS ++++ b/NEWS +@@ -143,6 +143,12 @@ GNU coreutils NEWS -*- outline -*- + where avx2 instructions are supported. + A new --debug option will indicate if avx2 is being used. + ++** Bug fixes ++ ++ chmod -R no longer exits with error status when encountering symlinks. ++ All files would be processed correctly, but the exit status was incorrect. ++ [bug introduced in coreutils-9.0] ++ + + * Noteworthy changes in release 8.32 (2020-03-05) [stable] + +diff --git a/src/chmod.c b/src/chmod.c +index 37b04f5..57ac47f 100644 +--- a/src/chmod.c ++++ b/src/chmod.c +@@ -44,8 +44,8 @@ struct change_status + enum + { + CH_NO_STAT, +- CH_NOT_APPLIED, + CH_FAILED, ++ CH_NOT_APPLIED, + CH_NO_CHANGE_REQUESTED, + CH_SUCCEEDED + } +@@ -322,7 +322,7 @@ process_file (FTS *fts, FTSENT *ent) + if ( ! recurse) + fts_set (fts, ent, FTS_SKIP); + +- return CH_NO_CHANGE_REQUESTED <= ch.status; ++ return CH_NOT_APPLIED <= ch.status; + } + + /* Recursively change the modes of the specified FILES (the last entry +diff --git a/tests/chmod/ignore-symlink.sh b/tests/chmod/ignore-symlink.sh +new file mode 100755 +index 0000000..5ce3de8 +--- /dev/null ++++ b/tests/chmod/ignore-symlink.sh +@@ -0,0 +1,31 @@ ++#!/bin/sh ++# Test for proper exit code of chmod on a processed symlink. ++ ++# Copyright (C) 2021 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_ chmod ++ ++mkdir dir || framework_failure_ ++touch dir/f || framework_failure_ ++ln -s f dir/l || framework_failure_ ++ ++# This operation ignores symlinks but should succeed. ++chmod u+w -R dir 2> out || fail=1 ++ ++compare /dev/null out || fail=1 ++ ++Exit $fail +diff --git a/tests/local.mk b/tests/local.mk +index a76c808..a2164c9 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -458,6 +458,7 @@ all_tests = \ + tests/chmod/c-option.sh \ + tests/chmod/equal-x.sh \ + tests/chmod/equals.sh \ ++ tests/chmod/ignore-symlink.sh \ + tests/chmod/inaccessible.sh \ + tests/chmod/octal.sh \ + tests/chmod/setgid.sh \ +-- +2.31.1 + diff --git a/coreutils.spec b/coreutils.spec index 41c37c4..a6ceed5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.0 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -17,6 +17,9 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ +# chmod: fix exit status when ignoring symlinks +Patch1: coreutils-9.0-chmod-symlink.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -263,6 +266,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Oct 04 2021 Kamil Dudka - 9.0-2 +- chmod: fix exit status when ignoring symlinks + * Sun Sep 26 2021 Kamil Dudka - 9.0-1 - new upstream release 9.0 From d00a2dffe178fb7512155c18ae34434cf2f92cc1 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jan 2022 23:51:06 +0000 Subject: [PATCH 461/523] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index a6ceed5..17a4e88 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.0 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -266,6 +266,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jan 19 2022 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Mon Oct 04 2021 Kamil Dudka - 9.0-2 - chmod: fix exit status when ignoring symlinks From c25beef1ca94b1a34b2fe5ffa91dfe39965e1f6a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 1 Mar 2022 10:25:55 +0100 Subject: [PATCH 462/523] Resolves: #2058686 - make `df --direct` work again --- coreutils-df-direct.patch | 18 ++++++++---------- coreutils.spec | 5 ++++- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 7574373..2571fa4 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -5,16 +5,16 @@ Subject: [PATCH] coreutils-df-direct.patch --- doc/coreutils.texi | 7 ++++++ - src/df.c | 36 ++++++++++++++++++++++++++++-- + src/df.c | 34 ++++++++++++++++++++++++++-- tests/df/direct.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 96 insertions(+), 2 deletions(-) + 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 5b9a597..6810c15 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12067,6 +12067,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12074,6 +12074,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -71,7 +71,7 @@ index 48025b9..c8efa5b 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1486,6 +1494,19 @@ get_point (char const *point, const struct stat *statp) +@@ -1486,6 +1494,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -80,9 +80,7 @@ index 48025b9..c8efa5b 100644 + char *resolved = canonicalize_file_name (name); + if (resolved) + { -+ char *mp = find_mount_point (name, statp); -+ get_dev (NULL, mp, resolved, NULL, NULL, false, false, NULL, false); -+ free(mp); ++ get_dev (NULL, resolved, name, NULL, NULL, false, false, NULL, false); + free (resolved); + return; + } @@ -91,7 +89,7 @@ index 48025b9..c8efa5b 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1556,6 +1577,7 @@ or all file systems by default.\n\ +@@ -1556,6 +1575,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -99,7 +97,7 @@ index 48025b9..c8efa5b 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1646,6 +1668,9 @@ main (int argc, char **argv) +@@ -1646,6 +1666,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -109,7 +107,7 @@ index 48025b9..c8efa5b 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1742,6 +1767,13 @@ main (int argc, char **argv) +@@ -1742,6 +1765,13 @@ main (int argc, char **argv) } } diff --git a/coreutils.spec b/coreutils.spec index 17a4e88..adc2f95 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.0 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -266,6 +266,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Mar 01 2022 Kamil Dudka - 9.0-4 +- make `df --direct` work again (#2058686) + * Wed Jan 19 2022 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild From 1f1987452485e60c346627502e25d763b4ec77f9 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 21 Mar 2022 08:48:08 +0100 Subject: [PATCH 463/523] Resolves: #2044981 - ls, stat: avoid triggering automounts --- coreutils-9.0-autofs-no-mount.patch | 87 +++++++++++++++++++++++++++++ coreutils.spec | 8 ++- 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.0-autofs-no-mount.patch diff --git a/coreutils-9.0-autofs-no-mount.patch b/coreutils-9.0-autofs-no-mount.patch new file mode 100644 index 0000000..b6d6523 --- /dev/null +++ b/coreutils-9.0-autofs-no-mount.patch @@ -0,0 +1,87 @@ +From f4422844dbcd839ce486bcbc15b7bd5b72c9198d Mon Sep 17 00:00:00 2001 +From: Rohan Sable +Date: Mon, 7 Mar 2022 14:14:13 +0000 +Subject: [PATCH 1/2] ls: avoid triggering automounts + +statx() has different defaults wrt automounting +compared to stat() or lstat(), so explicitly +set the AT_NO_AUTOMOUNT flag to suppress that behavior, +and avoid unintended operations or potential errors. + +* src/ls.c (do_statx): Pass AT_NO_AUTOMOUNT to avoid this behavior. +Fixes https://bugs.gnu.org/54286 + +Signed-off-by: Rohan Sable + +Upstream-commit: 85c975df2c25bd799370b04bb294e568e001102f +Signed-off-by: Kamil Dudka +--- + src/ls.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/ls.c b/src/ls.c +index 1047801..fe0e9f8 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -1175,7 +1175,7 @@ do_statx (int fd, char const *name, struct stat *st, int flags, + { + struct statx stx; + bool want_btime = mask & STATX_BTIME; +- int ret = statx (fd, name, flags, mask, &stx); ++ int ret = statx (fd, name, flags | AT_NO_AUTOMOUNT, mask, &stx); + if (ret >= 0) + { + statx_to_stat (&stx, st); +-- +2.34.1 + + +From 3d227f9e4f3fe806064721e4b9451ee06526bc80 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Mon, 7 Mar 2022 23:29:20 +0000 +Subject: [PATCH 2/2] stat: only automount with --cached=never + +Revert to the default behavior before the introduction of statx(). + +* src/stat.c (do_stat): Set AT_NO_AUTOMOUNT without --cached=never. +* doc/coreutils.texi (stat invocation): Mention the automount +behavior with --cached=never. + +Fixes https://bugs.gnu.org/54287 + +Upstream-commit: 92cb8427c537f37edd43c5cef1909585201372ab +Signed-off-by: Kamil Dudka +--- + doc/coreutils.texi | 1 + + src/stat.c | 3 +++ + 2 files changed, 4 insertions(+) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 19b535c..0f5c16a 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -12564,6 +12564,7 @@ Always read the already cached attributes if available. + + @item never + Always sychronize with the latest file system attributes. ++This also mounts automounted files. + + @item default + Leave the caching behavior to the underlying file system. +diff --git a/src/stat.c b/src/stat.c +index 0c34501..803340a 100644 +--- a/src/stat.c ++++ b/src/stat.c +@@ -1381,6 +1381,9 @@ do_stat (char const *filename, char const *format, char const *format2) + else if (force_sync) + flags |= AT_STATX_FORCE_SYNC; + ++ if (! force_sync) ++ flags |= AT_NO_AUTOMOUNT; ++ + fd = statx (fd, pathname, flags, format_to_mask (format), &stx); + if (fd < 0) + { +-- +2.34.1 + diff --git a/coreutils.spec b/coreutils.spec index adc2f95..c1c4c5d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.0 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -20,6 +20,9 @@ Source106: coreutils-colorls.csh # chmod: fix exit status when ignoring symlinks Patch1: coreutils-9.0-chmod-symlink.patch +# ls, stat: avoid triggering automounts (#2044981) +Patch2: coreutils-9.0-autofs-no-mount.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -266,6 +269,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Mar 21 2022 Kamil Dudka - 9.0-5 +- ls, stat: avoid triggering automounts (#2044981) + * Tue Mar 01 2022 Kamil Dudka - 9.0-4 - make `df --direct` work again (#2058686) From 9325dbbef7691ce29c2028fac36ae5ab637a9d29 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 19 Apr 2022 12:11:05 +0200 Subject: [PATCH 464/523] new upstream release 9.1 --- .gitignore | 1 + coreutils-4.5.3-langinfo.patch | 20 -- coreutils-8.2-uname-processortype.patch | 41 +-- coreutils-8.32-DIR_COLORS.patch | 44 +-- coreutils-9.0-autofs-no-mount.patch | 87 ----- coreutils-9.0-chmod-symlink.patch | 114 ------ coreutils-i18n.patch | 446 ++++++++++++++++-------- coreutils.spec | 18 +- sources | 3 +- 9 files changed, 344 insertions(+), 430 deletions(-) delete mode 100644 coreutils-4.5.3-langinfo.patch delete mode 100644 coreutils-9.0-autofs-no-mount.patch delete mode 100644 coreutils-9.0-chmod-symlink.patch diff --git a/.gitignore b/.gitignore index de62e8f..46d0f92 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /coreutils-[0-9.]*.tar.xz +/coreutils-[0-9.]*.tar.xz.sig diff --git a/coreutils-4.5.3-langinfo.patch b/coreutils-4.5.3-langinfo.patch deleted file mode 100644 index 862d9eb..0000000 --- a/coreutils-4.5.3-langinfo.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/src/date.c b/src/date.c -index ddb011e..619a72b 100644 ---- a/src/date.c -+++ b/src/date.c -@@ -494,14 +494,7 @@ main (int argc, char **argv) - format = DATE_FMT_LANGINFO (); - if (! *format) - { -- /* Do not wrap the following literal format string with _(...). -- For example, suppose LC_ALL is unset, LC_TIME=POSIX, -- and LANG="ko_KR". In that case, POSIX says that LC_TIME -- determines the format and contents of date and time strings -- written by date, which means "date" must generate output -- using the POSIX locale; but adding _() would cause "date" -- to use a Korean translation of the format. */ -- format = "%a %b %e %H:%M:%S %Z %Y"; -+ format = dcgettext(NULL, N_("%a %b %e %H:%M:%S %Z %Y"), LC_TIME); - } - } - diff --git a/coreutils-8.2-uname-processortype.patch b/coreutils-8.2-uname-processortype.patch index ed01ab8..44c57f5 100644 --- a/coreutils-8.2-uname-processortype.patch +++ b/coreutils-8.2-uname-processortype.patch @@ -1,29 +1,24 @@ + src/uname.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + diff --git a/src/uname.c b/src/uname.c index 6371ca2..1ad8fd7 100644 --- a/src/uname.c +++ b/src/uname.c -@@ -300,13 +300,19 @@ main (int argc, char **argv) - - if (toprint & PRINT_PROCESSOR) - { -- char const *element = unknown; -+ char *element = unknown; - #if HAVE_SYSINFO && defined SI_ARCHITECTURE - { - static char processor[257]; - if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) - element = processor; - } +@@ -322,6 +322,12 @@ main (int argc, char **argv) + # elif defined __ppc__ || defined __ppc64__ + element = "powerpc"; + # endif +#else + { -+ static struct utsname u; -+ uname(&u); -+ element = u.machine; ++ static struct utsname u; ++ uname(&u); ++ element = u.machine; + } #endif - #ifdef UNAME_PROCESSOR + #if HAVE_SYSINFO && defined SI_ARCHITECTURE if (element == unknown) -@@ -344,7 +350,7 @@ main (int argc, char **argv) +@@ -347,7 +353,7 @@ main (int argc, char **argv) if (toprint & PRINT_HARDWARE_PLATFORM) { @@ -32,17 +27,17 @@ index 6371ca2..1ad8fd7 100644 #if HAVE_SYSINFO && defined SI_PLATFORM { static char hardware_platform[257]; -@@ -352,6 +358,14 @@ main (int argc, char **argv) +@@ -355,6 +361,14 @@ main (int argc, char **argv) hardware_platform, sizeof hardware_platform)) element = hardware_platform; } +#else + { -+ static struct utsname u; -+ uname(&u); -+ element = u.machine; -+ if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6') -+ element[1]='3'; ++ static struct utsname u; ++ uname(&u); ++ element = u.machine; ++ if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6') ++ element[1]='3'; + } #endif #ifdef UNAME_HARDWARE_PLATFORM diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index c43651c..3a0375d 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -1,4 +1,4 @@ -From 81e25c8521937ecf7f444bab11fddaaf81cc3efd Mon Sep 17 00:00:00 2001 +From c7b13f5e1a7ad012c510a8bdd5a8943ab4b55833 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 17 Jun 2016 16:58:18 +0200 Subject: [PATCH] downstream changes to default DIR_COLORS @@ -9,7 +9,7 @@ Subject: [PATCH] downstream changes to default DIR_COLORS 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS -index bd5df23..84f2417 100644 +index b465771..ad42b09 100644 --- a/DIR_COLORS +++ b/DIR_COLORS @@ -1,3 +1,7 @@ @@ -20,17 +20,17 @@ index bd5df23..84f2417 100644 # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. -@@ -8,6 +12,9 @@ - # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the - # slackware version of dircolors) are recognized but ignored. +@@ -10,6 +14,9 @@ + + # Global config options can be specified before TERM or COLORTERM entries +# For compatibility, the pattern "^COLOR.*none" is recognized as a way to +# disable colorization. See https://bugzilla.redhat.com/1349579 for details. + - # Below are TERM entries, which can be a glob patterns, to match - # against the TERM environment variable to determine if it is colorizable. - TERM Eterm -@@ -59,7 +66,7 @@ DOOR 01;35 # door + # Below are TERM or COLORTERM entries, which can be glob patterns, which + # restrict following config to systems with matching environment variables. + COLORTERM ?* +@@ -62,7 +69,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -38,9 +38,9 @@ index bd5df23..84f2417 100644 +MISSING 01;37;41 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) - CAPABILITY 30;41 # file with capability + CAPABILITY 00 # file with capability (very expensive to lookup) diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor -index 4316832..6402854 100644 +index eab6258..1627b63 100644 --- a/DIR_COLORS.lightbgcolor +++ b/DIR_COLORS.lightbgcolor @@ -1,3 +1,9 @@ @@ -53,17 +53,17 @@ index 4316832..6402854 100644 # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. -@@ -8,6 +14,9 @@ - # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the - # slackware version of dircolors) are recognized but ignored. +@@ -10,6 +16,9 @@ + + # Global config options can be specified before TERM or COLORTERM entries +# For compatibility, the pattern "^COLOR.*none" is recognized as a way to +# disable colorization. See https://bugzilla.redhat.com/1349579 for details. + - # Below are TERM entries, which can be a glob patterns, to match - # against the TERM environment variable to determine if it is colorizable. - TERM Eterm -@@ -49,17 +58,17 @@ TERM xterm* + # Below are TERM or COLORTERM entries, which can be glob patterns, which + # restrict following config to systems with matching environment variables. + COLORTERM ?* +@@ -52,17 +61,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -85,8 +85,8 @@ index 4316832..6402854 100644 +MISSING 01;37;41 # ... and the files they point to SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) - CAPABILITY 30;41 # file with capability -@@ -68,7 +77,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky + CAPABILITY 00 # file with capability (very expensive to lookup) +@@ -71,7 +80,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: @@ -94,7 +94,7 @@ index 4316832..6402854 100644 +EXEC 00;32 # List any file extensions like '.gz' or '.tar' that you would like ls - # to colorize below. Put the extension, a space, and the color init string. + # to color below. Put the extension, a space, and the color init string. -- -2.21.1 +2.34.1 diff --git a/coreutils-9.0-autofs-no-mount.patch b/coreutils-9.0-autofs-no-mount.patch deleted file mode 100644 index b6d6523..0000000 --- a/coreutils-9.0-autofs-no-mount.patch +++ /dev/null @@ -1,87 +0,0 @@ -From f4422844dbcd839ce486bcbc15b7bd5b72c9198d Mon Sep 17 00:00:00 2001 -From: Rohan Sable -Date: Mon, 7 Mar 2022 14:14:13 +0000 -Subject: [PATCH 1/2] ls: avoid triggering automounts - -statx() has different defaults wrt automounting -compared to stat() or lstat(), so explicitly -set the AT_NO_AUTOMOUNT flag to suppress that behavior, -and avoid unintended operations or potential errors. - -* src/ls.c (do_statx): Pass AT_NO_AUTOMOUNT to avoid this behavior. -Fixes https://bugs.gnu.org/54286 - -Signed-off-by: Rohan Sable - -Upstream-commit: 85c975df2c25bd799370b04bb294e568e001102f -Signed-off-by: Kamil Dudka ---- - src/ls.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/ls.c b/src/ls.c -index 1047801..fe0e9f8 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -1175,7 +1175,7 @@ do_statx (int fd, char const *name, struct stat *st, int flags, - { - struct statx stx; - bool want_btime = mask & STATX_BTIME; -- int ret = statx (fd, name, flags, mask, &stx); -+ int ret = statx (fd, name, flags | AT_NO_AUTOMOUNT, mask, &stx); - if (ret >= 0) - { - statx_to_stat (&stx, st); --- -2.34.1 - - -From 3d227f9e4f3fe806064721e4b9451ee06526bc80 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Mon, 7 Mar 2022 23:29:20 +0000 -Subject: [PATCH 2/2] stat: only automount with --cached=never - -Revert to the default behavior before the introduction of statx(). - -* src/stat.c (do_stat): Set AT_NO_AUTOMOUNT without --cached=never. -* doc/coreutils.texi (stat invocation): Mention the automount -behavior with --cached=never. - -Fixes https://bugs.gnu.org/54287 - -Upstream-commit: 92cb8427c537f37edd43c5cef1909585201372ab -Signed-off-by: Kamil Dudka ---- - doc/coreutils.texi | 1 + - src/stat.c | 3 +++ - 2 files changed, 4 insertions(+) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 19b535c..0f5c16a 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -12564,6 +12564,7 @@ Always read the already cached attributes if available. - - @item never - Always sychronize with the latest file system attributes. -+This also mounts automounted files. - - @item default - Leave the caching behavior to the underlying file system. -diff --git a/src/stat.c b/src/stat.c -index 0c34501..803340a 100644 ---- a/src/stat.c -+++ b/src/stat.c -@@ -1381,6 +1381,9 @@ do_stat (char const *filename, char const *format, char const *format2) - else if (force_sync) - flags |= AT_STATX_FORCE_SYNC; - -+ if (! force_sync) -+ flags |= AT_NO_AUTOMOUNT; -+ - fd = statx (fd, pathname, flags, format_to_mask (format), &stx); - if (fd < 0) - { --- -2.34.1 - diff --git a/coreutils-9.0-chmod-symlink.patch b/coreutils-9.0-chmod-symlink.patch deleted file mode 100644 index fad3b7a..0000000 --- a/coreutils-9.0-chmod-symlink.patch +++ /dev/null @@ -1,114 +0,0 @@ -From c76e70637e529481478e26683ebd73c40621c382 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Fri, 24 Sep 2021 20:57:41 +0100 -Subject: [PATCH] chmod: fix exit status when ignoring symlinks - -* src/chmod.c: Reorder enum so CH_NOT_APPLIED -can be treated as a non error. -* tests/chmod/ignore-symlink.sh: A new test. -* tests/local.mk: Reference the new test. -* NEWS: Mention the bug fix. -Fixes https://bugs.gnu.org/50784 - -Upstream-commit: e8b56ebd536e82b15542a00c888109471936bfda -Signed-off-by: Kamil Dudka ---- - NEWS | 6 ++++++ - src/chmod.c | 4 ++-- - tests/chmod/ignore-symlink.sh | 31 +++++++++++++++++++++++++++++++ - tests/local.mk | 1 + - 4 files changed, 40 insertions(+), 2 deletions(-) - create mode 100755 tests/chmod/ignore-symlink.sh - -diff --git a/NEWS b/NEWS -index f2fbcbb..5722a8b 100644 ---- a/NEWS -+++ b/NEWS -@@ -143,6 +143,12 @@ GNU coreutils NEWS -*- outline -*- - where avx2 instructions are supported. - A new --debug option will indicate if avx2 is being used. - -+** Bug fixes -+ -+ chmod -R no longer exits with error status when encountering symlinks. -+ All files would be processed correctly, but the exit status was incorrect. -+ [bug introduced in coreutils-9.0] -+ - - * Noteworthy changes in release 8.32 (2020-03-05) [stable] - -diff --git a/src/chmod.c b/src/chmod.c -index 37b04f5..57ac47f 100644 ---- a/src/chmod.c -+++ b/src/chmod.c -@@ -44,8 +44,8 @@ struct change_status - enum - { - CH_NO_STAT, -- CH_NOT_APPLIED, - CH_FAILED, -+ CH_NOT_APPLIED, - CH_NO_CHANGE_REQUESTED, - CH_SUCCEEDED - } -@@ -322,7 +322,7 @@ process_file (FTS *fts, FTSENT *ent) - if ( ! recurse) - fts_set (fts, ent, FTS_SKIP); - -- return CH_NO_CHANGE_REQUESTED <= ch.status; -+ return CH_NOT_APPLIED <= ch.status; - } - - /* Recursively change the modes of the specified FILES (the last entry -diff --git a/tests/chmod/ignore-symlink.sh b/tests/chmod/ignore-symlink.sh -new file mode 100755 -index 0000000..5ce3de8 ---- /dev/null -+++ b/tests/chmod/ignore-symlink.sh -@@ -0,0 +1,31 @@ -+#!/bin/sh -+# Test for proper exit code of chmod on a processed symlink. -+ -+# Copyright (C) 2021 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_ chmod -+ -+mkdir dir || framework_failure_ -+touch dir/f || framework_failure_ -+ln -s f dir/l || framework_failure_ -+ -+# This operation ignores symlinks but should succeed. -+chmod u+w -R dir 2> out || fail=1 -+ -+compare /dev/null out || fail=1 -+ -+Exit $fail -diff --git a/tests/local.mk b/tests/local.mk -index a76c808..a2164c9 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -458,6 +458,7 @@ all_tests = \ - tests/chmod/c-option.sh \ - tests/chmod/equal-x.sh \ - tests/chmod/equals.sh \ -+ tests/chmod/ignore-symlink.sh \ - tests/chmod/inaccessible.sh \ - tests/chmod/octal.sh \ - tests/chmod/setgid.sh \ --- -2.31.1 - diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index f14a4ba..4ff0911 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From d53e5b885b9d82e2d9ba5d65ed8fd9b96712623f Mon Sep 17 00:00:00 2001 +From 01010419a6499768563e7b2f3fd56cf16edda75e Mon Sep 17 00:00:00 2001 From: rpm-build Date: Mon, 4 Oct 2021 08:54:37 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -10,15 +10,15 @@ Subject: [PATCH] coreutils-i18n.patch lib/mbfile.c | 3 + lib/mbfile.h | 255 ++++++++++++ m4/mbfile.m4 | 14 + - src/cut.c | 441 +++++++++++++++++++- + src/cut.c | 508 +++++++++++++++++++++-- src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + - src/expand.c | 90 ++++- - src/fold.c | 312 +++++++++++++-- - src/join.c | 359 ++++++++++++++--- + src/expand.c | 90 +++- + src/fold.c | 312 ++++++++++++-- + src/join.c | 359 ++++++++++++++-- src/local.mk | 4 +- - src/pr.c | 443 +++++++++++++++++++-- - src/sort.c | 772 ++++++++++++++++++++++++++++++++++-- + src/pr.c | 443 ++++++++++++++++++-- + src/sort.c | 792 +++++++++++++++++++++++++++++++++--- src/unexpand.c | 101 ++++- src/uniq.c | 119 +++++- tests/Coreutils.pm | 3 + @@ -28,14 +28,14 @@ Subject: [PATCH] coreutils-i18n.patch 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-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 ++++++++ - 31 files changed, 3640 insertions(+), 213 deletions(-) + 31 files changed, 3698 insertions(+), 242 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -45,10 +45,10 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100755 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index aef9ec7..9486e9d 100644 +index c1399e3..60b39cf 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -156,6 +156,7 @@ gnulib_modules=" +@@ -162,6 +162,7 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -57,10 +57,10 @@ index aef9ec7..9486e9d 100644 mbrtowc mbsalign diff --git a/configure.ac b/configure.ac -index 6960b48..8ff85f8 100644 +index 7e4afc9..4656a35 100644 --- a/configure.ac +++ b/configure.ac -@@ -457,6 +457,8 @@ fi +@@ -476,6 +476,8 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -70,7 +70,7 @@ index 6960b48..8ff85f8 100644 if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index 5fa5ad2..2bdbcab 100644 +index 07d45ca..af62e6c 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h @@ -22,6 +22,11 @@ @@ -386,7 +386,7 @@ index 0000000..8589902 + : +]) diff --git a/src/cut.c b/src/cut.c -index cdf33d8..b8301d7 100644 +index 6fd8978..faef877 100644 --- a/src/cut.c +++ b/src/cut.c @@ -28,6 +28,11 @@ @@ -483,23 +483,26 @@ index cdf33d8..b8301d7 100644 /* 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 -@@ -76,15 +142,25 @@ enum operating_mode - { - undefined_mode, +@@ -72,6 +138,29 @@ static char *field_1_buffer; + /* The number of bytes allocated for FIELD_1_BUFFER. */ + static size_t field_1_bufsize; -- /* Output characters that are in the given bytes. */ ++enum operating_mode ++ { ++ undefined_mode, ++ + /* Output bytes that are at the given positions. */ - byte_mode, - ++ 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; - ++ /* 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; + @@ -510,7 +513,7 @@ index cdf33d8..b8301d7 100644 /* If true do not output lines containing no delimiter characters. Otherwise, all such lines are printed. This option is valid only with field mode. */ -@@ -96,6 +172,9 @@ static bool complement; +@@ -83,10 +172,16 @@ static bool complement; /* The delimiter character for field mode. */ static unsigned char delim; @@ -520,7 +523,24 @@ index cdf33d8..b8301d7 100644 /* The delimiter for each line/record. */ static unsigned char line_delim = '\n'; -@@ -163,7 +242,7 @@ Print selected parts of lines from each FILE to standard output.\n\ + ++/* True if the --output-delimiter=STRING option was specified. */ ++static bool output_delimiter_specified; ++ + /* The length of output_delimiter_string. */ + static size_t output_delimiter_length; + +@@ -94,9 +189,6 @@ static size_t output_delimiter_length; + string consisting of the input delimiter. */ + static char *output_delimiter_string; + +-/* The output delimiter string contents, if the default. */ +-static char output_delimiter_default[1]; +- + /* True if we have ever read standard input. */ + static bool have_read_stdin; + +@@ -150,7 +242,7 @@ Print selected parts of lines from each FILE to standard output.\n\ -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\ @@ -529,7 +549,16 @@ index cdf33d8..b8301d7 100644 "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -279,6 +358,82 @@ cut_bytes (FILE *stream) +@@ -250,7 +342,7 @@ cut_bytes (FILE *stream) + next_item (&byte_idx); + if (print_kth (byte_idx)) + { +- if (output_delimiter_string != output_delimiter_default) ++ if (output_delimiter_specified) + { + if (print_delimiter && is_range_start_index (byte_idx)) + { +@@ -266,6 +358,82 @@ cut_bytes (FILE *stream) } } @@ -612,10 +641,11 @@ index cdf33d8..b8301d7 100644 /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -424,13 +579,211 @@ cut_fields (FILE *stream) +@@ -411,11 +579,218 @@ cut_fields (FILE *stream) } } +-/* Process file FILE to standard output, using CUT_STREAM. +#if HAVE_MBRTOWC +static void +cut_fields_mb (FILE *stream) @@ -773,11 +803,9 @@ index cdf33d8..b8301d7 100644 +} +#endif + - static void - cut_stream (FILE *stream) - { -- if (operating_mode == byte_mode) -- cut_bytes (stream); ++static void ++cut_stream (FILE *stream) ++{ +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1 && !force_singlebyte_mode) + { @@ -815,8 +843,7 @@ index cdf33d8..b8301d7 100644 + abort (); + } + } - else -- cut_fields (stream); ++ else +#endif + { + if (operating_mode == field_mode) @@ -824,29 +851,51 @@ index cdf33d8..b8301d7 100644 + else + cut_bytes (stream); + } - } ++} ++ ++/* Process file FILE to standard output. + Return true if successful. */ - /* Process file FILE to standard output. -@@ -482,6 +835,7 @@ main (int argc, char **argv) + static bool +-cut_file (char const *file, void (*cut_stream) (FILE *)) ++cut_file (char const *file) + { + FILE *stream; + +@@ -459,8 +834,8 @@ main (int argc, char **argv) + int optc; bool ok; bool delim_specified = false; - char *spec_list_string IF_LINT ( = NULL); +- bool byte_mode = false; +- char *spec_list_string = NULL; ++ char *spec_list_string IF_LINT ( = NULL); + char mbdelim[MB_LEN_MAX + 1]; initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -504,7 +858,6 @@ main (int argc, char **argv) +@@ -470,6 +845,8 @@ main (int argc, char **argv) + + atexit (close_stdout); + ++ operating_mode = undefined_mode; ++ + /* By default, all non-delimited lines are printed. */ + suppress_non_delimited = false; + +@@ -481,35 +858,77 @@ 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")); -@@ -512,6 +865,14 @@ main (int argc, char **argv) - spec_list_string = optarg; - break; - +- byte_mode = true; +- FALLTHROUGH; ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = byte_mode; ++ spec_list_string = optarg; ++ break; ++ + case 'c': + /* Build the character list. */ + if (operating_mode != undefined_mode) @@ -857,8 +906,14 @@ index cdf33d8..b8301d7 100644 + case 'f': /* Build the field list. */ - if (operating_mode != undefined_mode) -@@ -523,10 +884,38 @@ main (int argc, char **argv) +- if (spec_list_string) +- FATAL_ERROR (_("only one list may be specified")); ++ if (operating_mode != undefined_mode) ++ FATAL_ERROR (_("only one type of list may be specified")); ++ operating_mode = field_mode; + spec_list_string = optarg; + break; + case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -901,7 +956,13 @@ index cdf33d8..b8301d7 100644 break; case OUTPUT_DELIMITER_OPTION: -@@ -539,6 +928,7 @@ main (int argc, char **argv) ++ output_delimiter_specified = true; + /* Interpret --output-delimiter='' to mean + 'use the NUL byte as the delimiter.' */ + output_delimiter_length = (optarg[0] == '\0' + ? 1 : strlen (optarg)); +- output_delimiter_string = optarg; ++ output_delimiter_string = xstrdup (optarg); break; case 'n': @@ -909,8 +970,34 @@ index cdf33d8..b8301d7 100644 break; case 's': -@@ -578,15 +968,34 @@ main (int argc, char **argv) - | (complement ? SETFLD_COMPLEMENT : 0) ); +@@ -533,40 +952,57 @@ main (int argc, char **argv) + } + } + +- if (!spec_list_string) ++ if (operating_mode == undefined_mode) + FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); + +- if (byte_mode) +- { +- if (delim_specified) +- FATAL_ERROR (_("an input delimiter may be specified only\ ++ if (delim_specified && operating_mode != field_mode) ++ FATAL_ERROR (_("an input delimiter may be specified only\ + when operating on fields")); + +- if (suppress_non_delimited) +- FATAL_ERROR (_("suppressing non-delimited lines makes sense\n\ ++ if (suppress_non_delimited && operating_mode != field_mode) ++ FATAL_ERROR (_("suppressing non-delimited lines makes sense\n\ + \tonly when operating on fields")); +- } + + set_fields (spec_list_string, +- ((byte_mode ? SETFLD_ERRMSG_USE_POS : 0) +- | (complement ? SETFLD_COMPLEMENT : 0))); ++ ( (operating_mode == field_mode) ? 0 : SETFLD_ERRMSG_USE_POS) ++ | (complement ? SETFLD_COMPLEMENT : 0) ); if (!delim_specified) - delim = '\t'; @@ -926,10 +1013,8 @@ index cdf33d8..b8301d7 100644 if (output_delimiter_string == NULL) { -- static char dummy[2]; -- dummy[0] = delim; -- dummy[1] = '\0'; -- output_delimiter_string = dummy; +- output_delimiter_default[0] = delim; +- output_delimiter_string = output_delimiter_default; - output_delimiter_length = 1; +#ifdef HAVE_MBRTOWC + if (MB_CUR_MAX > 1 && !force_singlebyte_mode) @@ -949,9 +1034,19 @@ index cdf33d8..b8301d7 100644 + } } +- void (*cut_stream) (FILE *) = byte_mode ? cut_bytes : cut_fields; if (optind == argc) +- ok = cut_file ("-", cut_stream); ++ ok = cut_file ("-"); + else + for (ok = true; optind < argc; optind++) +- ok &= cut_file (argv[optind], cut_stream); ++ ok &= cut_file (argv[optind]); + + + if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index 4deb7bd..8fd0524 100644 +index deec1bd..b39f740 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -1083,7 +1178,7 @@ index 4deb7bd..8fd0524 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index ac812d0..16789ab 100644 +index 5f59a0e..835b9d5 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -25,6 +25,18 @@ extern size_t max_column_width; @@ -1106,7 +1201,7 @@ index ac812d0..16789ab 100644 extern void add_tab_stop (uintmax_t tabval); diff --git a/src/expand.c b/src/expand.c -index 4e32bfc..902c6b4 100644 +index ed78ca8..a4cefa1 100644 --- a/src/expand.c +++ b/src/expand.c @@ -37,6 +37,9 @@ @@ -1262,7 +1357,7 @@ index 4e32bfc..902c6b4 100644 } diff --git a/src/fold.c b/src/fold.c -index 94a6d37..a278783 100644 +index f07a90b..d32dbfd 100644 --- a/src/fold.c +++ b/src/fold.c @@ -22,12 +22,34 @@ @@ -1668,7 +1763,7 @@ index 94a6d37..a278783 100644 case 's': /* Break at word boundaries. */ diff --git a/src/join.c b/src/join.c -index f22ffda..ad5dc0d 100644 +index f2fd172..6c7d1ed 100644 --- a/src/join.c +++ b/src/join.c @@ -22,19 +22,33 @@ @@ -1723,7 +1818,7 @@ index f22ffda..ad5dc0d 100644 /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -276,13 +292,14 @@ xfields (struct line *line) +@@ -280,13 +296,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1741,7 +1836,7 @@ index f22ffda..ad5dc0d 100644 { /* Skip leading blanks before the first field. */ while (field_sep (*ptr)) -@@ -306,6 +323,147 @@ xfields (struct line *line) +@@ -310,6 +327,147 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1889,7 +1984,7 @@ index f22ffda..ad5dc0d 100644 static void freeline (struct line *line) { -@@ -327,56 +485,133 @@ keycmp (struct line const *line1, struct line const *line2, +@@ -331,56 +489,133 @@ keycmp (struct line const *line1, struct line const *line2, size_t jf_1, size_t jf_2) { /* Start of field to compare in each file. */ @@ -2046,7 +2141,7 @@ index f22ffda..ad5dc0d 100644 } /* Check that successive input lines PREV and CURRENT from input file -@@ -468,6 +703,11 @@ get_line (FILE *fp, struct line **linep, int which) +@@ -472,6 +707,11 @@ get_line (FILE *fp, struct line **linep, int which) } ++line_no[which - 1]; @@ -2058,7 +2153,7 @@ index f22ffda..ad5dc0d 100644 xfields (line); if (prevline[which - 1]) -@@ -563,21 +803,28 @@ prfield (size_t n, struct line const *line) +@@ -567,21 +807,28 @@ prfield (size_t n, struct line const *line) /* Output all the fields in line, other than the join field. */ @@ -2090,7 +2185,7 @@ index f22ffda..ad5dc0d 100644 prfield (i, line); } } -@@ -588,7 +835,6 @@ static void +@@ -592,7 +839,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; @@ -2098,7 +2193,7 @@ index f22ffda..ad5dc0d 100644 size_t field; struct line const *line; -@@ -622,7 +868,7 @@ prjoin (struct line const *line1, struct line const *line2) +@@ -626,7 +872,7 @@ prjoin (struct line const *line1, struct line const *line2) o = o->next; if (o == NULL) break; @@ -2107,7 +2202,7 @@ index f22ffda..ad5dc0d 100644 } putchar (eolchar); } -@@ -1098,20 +1344,43 @@ main (int argc, char **argv) +@@ -1102,20 +1348,43 @@ main (int argc, char **argv) case 't': { @@ -2161,10 +2256,10 @@ index f22ffda..ad5dc0d 100644 break; diff --git a/src/local.mk b/src/local.mk -index 0c8b65d..011421a 100644 +index e1d15ce..1a5ffaa 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -429,8 +429,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -434,8 +434,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -2176,7 +2271,7 @@ index 0c8b65d..011421a 100644 src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 8f84d0f..4bb5195 100644 +index 4c17c00..b4fab1c 100644 --- a/src/pr.c +++ b/src/pr.c @@ -311,6 +311,24 @@ @@ -2314,7 +2409,7 @@ index 8f84d0f..4bb5195 100644 static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -852,6 +905,13 @@ separator_string (char const *optarg_S) +@@ -853,6 +906,13 @@ separator_string (char const *optarg_S) integer_overflow (); col_sep_length = len; col_sep_string = optarg_S; @@ -2328,7 +2423,7 @@ index 8f84d0f..4bb5195 100644 } int -@@ -876,6 +936,21 @@ main (int argc, char **argv) +@@ -877,6 +937,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -2350,7 +2445,7 @@ index 8f84d0f..4bb5195 100644 n_files = 0; file_names = (argc > 1 ? xnmalloc (argc - 1, sizeof (char *)) -@@ -952,8 +1027,12 @@ main (int argc, char **argv) +@@ -953,8 +1028,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -2365,7 +2460,7 @@ index 8f84d0f..4bb5195 100644 /* Could check tab width > 0. */ untabify_input = true; break; -@@ -966,8 +1045,12 @@ main (int argc, char **argv) +@@ -967,8 +1046,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -2380,7 +2475,7 @@ index 8f84d0f..4bb5195 100644 /* Could check tab width > 0. */ tabify_output = true; break; -@@ -985,8 +1068,8 @@ main (int argc, char **argv) +@@ -986,8 +1069,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -2391,7 +2486,7 @@ index 8f84d0f..4bb5195 100644 break; case 'N': skip_count = false; -@@ -1011,6 +1094,7 @@ main (int argc, char **argv) +@@ -1012,6 +1095,7 @@ main (int argc, char **argv) /* Reset an additional input of -s, -S dominates -s */ col_sep_string = ""; col_sep_length = 0; @@ -2942,7 +3037,7 @@ index 8f84d0f..4bb5195 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 5f4c817..bd9c672 100644 +index 3b775d6..a0ba243 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -2960,9 +3055,9 @@ index 5f4c817..bd9c672 100644 #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; +@@ -159,14 +167,39 @@ static int thousands_sep; + /* We currently ignore multi-byte grouping chars. */ + static bool thousands_sep_ignored; +/* True if -f is specified. */ +static bool folding; @@ -3001,9 +3096,9 @@ index 5f4c817..bd9c672 100644 /* 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; +@@ -343,13 +376,11 @@ static bool stable; + /* An int value outside char range. */ + enum { NON_CHAR = CHAR_MAX + 1 }; -/* If TAB has this value, blanks separate fields. */ -enum { TAB_DEFAULT = CHAR_MAX + 1 }; @@ -3018,7 +3113,7 @@ index 5f4c817..bd9c672 100644 /* 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) +@@ -805,6 +836,46 @@ reap_all (void) reap (-1); } @@ -3065,7 +3160,7 @@ index 5f4c817..bd9c672 100644 /* Clean up any remaining temporary files. */ static void -@@ -1269,7 +1340,7 @@ zaptemp (char const *name) +@@ -1272,7 +1343,7 @@ zaptemp (char const *name) free (node); } @@ -3074,7 +3169,7 @@ index 5f4c817..bd9c672 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1284,7 +1355,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1287,7 +1358,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3083,7 +3178,7 @@ index 5f4c817..bd9c672 100644 { size_t i; -@@ -1296,7 +1367,7 @@ inittables (void) +@@ -1299,7 +1370,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3092,7 +3187,7 @@ index 5f4c817..bd9c672 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1378,6 +1449,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1381,6 +1452,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3177,7 +3272,7 @@ index 5f4c817..bd9c672 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1609,7 +1758,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1612,7 +1761,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3186,7 +3281,7 @@ index 5f4c817..bd9c672 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1618,10 +1767,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1621,10 +1770,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3199,7 +3294,7 @@ index 5f4c817..bd9c672 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1647,11 +1796,70 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3265,13 +3360,14 @@ index 5f4c817..bd9c672 100644 /* Return the limit of (a pointer to the first character after) the field in LINE specified by KEY. */ - static char * _GL_ATTRIBUTE_PURE + ATTRIBUTE_PURE + static char * -limfield (struct line const *line, struct keyfield const *key) +limfield_uni (struct line const *line, struct keyfield const *key) { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1666,10 +1874,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1670,10 +1878,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3284,7 +3380,7 @@ index 5f4c817..bd9c672 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1715,10 +1923,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3297,7 +3393,7 @@ index 5f4c817..bd9c672 100644 if (newlim) lim = newlim; } -@@ -1749,6 +1957,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3428,7 +3524,7 @@ index 5f4c817..bd9c672 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1835,8 +2167,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1839,8 +2171,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3453,9 +3549,9 @@ index 5f4c817..bd9c672 100644 line->keybeg = line_start; } } -@@ -1970,12 +2316,10 @@ find_unit_order (char const *number) - < K/k < M < G < T < P < E < Z < Y */ +@@ -1976,12 +2322,10 @@ find_unit_order (char const *number) + ATTRIBUTE_PURE static int -human_numcompare (char const *a, char const *b) +human_numcompare (char *a, char *b) @@ -3469,16 +3565,16 @@ index 5f4c817..bd9c672 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1986,7 +2330,7 @@ human_numcompare (char const *a, char const *b) - hideously fast. */ +@@ -1993,7 +2337,7 @@ human_numcompare (char const *a, char const *b) + ATTRIBUTE_PURE static int -numcompare (char const *a, char const *b) +numcompare_uni (const char *a, const char *b) { while (blanks[to_uchar (*a)]) a++; -@@ -1996,6 +2340,25 @@ numcompare (char const *a, char const *b) +@@ -2003,6 +2347,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3504,7 +3600,7 @@ index 5f4c817..bd9c672 100644 /* 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 -@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2053,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3513,7 +3609,7 @@ index 5f4c817..bd9c672 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2322,15 +2685,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2329,15 +2692,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3531,7 +3627,7 @@ index 5f4c817..bd9c672 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2464,7 +2826,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2483,7 +2845,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3540,7 +3636,66 @@ index 5f4c817..bd9c672 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2522,11 +2884,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2531,9 +2893,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) + bool number_locale_warned = false; + if (basic_numeric_field_span) + { +- if (tab == TAB_DEFAULT +- ? thousands_sep != NON_CHAR && (isblank (to_uchar (thousands_sep))) +- : tab == thousands_sep) ++ if (tab_length ++ ? tab[0] == thousands_sep ++ : thousands_sep != NON_CHAR && (isblank (to_uchar (thousands_sep)))) + { + error (0, 0, + _("field separator %s is treated as a " +@@ -2544,9 +2906,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) + } + if (basic_numeric_field_span || general_numeric_field_span) + { +- if (tab == TAB_DEFAULT +- ? thousands_sep != NON_CHAR && (isblank (to_uchar (decimal_point))) +- : tab == decimal_point) ++ if (tab_length ++ ? tab[0] == decimal_point ++ : thousands_sep != NON_CHAR && (isblank (to_uchar (decimal_point)))) + { + error (0, 0, + _("field separator %s is treated as a " +@@ -2554,19 +2916,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) + quote (((char []) {decimal_point, 0}))); + number_locale_warned = true; + } +- else if (tab == '-') ++ else if (tab_length && tab[0] == '-') + { + error (0, 0, + _("field separator %s is treated as a " + "minus sign in numbers"), +- quote (((char []) {tab, 0}))); ++ quote (((char []) {tab[0], 0}))); + } +- else if (general_numeric_field_span && tab == '+') ++ else if (general_numeric_field_span && tab_length && tab[0] == '+') + { + error (0, 0, + _("field separator %s is treated as a " + "plus sign in numbers"), +- quote (((char []) {tab, 0}))); ++ quote (((char []) {tab[0], 0}))); + } + } + +@@ -2577,7 +2939,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) + { + error (0, 0, + _("%snumbers use %s as a decimal point in this locale"), +- tab == decimal_point ? "" : _("note "), ++ (tab_length && tab[0] == decimal_point) ? "" : _("note "), + quote (((char []) {decimal_point, 0}))); + + } +@@ -2610,11 +2972,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) error (0, 0, _("option '-r' only applies to last-resort comparison")); } @@ -3629,7 +3784,7 @@ index 5f4c817..bd9c672 100644 { struct keyfield *key = keylist; -@@ -2611,7 +3049,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2699,7 +3137,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3638,7 +3793,7 @@ index 5f4c817..bd9c672 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2727,6 +3165,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2815,6 +3253,211 @@ keycompare (struct line const *a, struct line const *b) return key->reverse ? -diff : diff; } @@ -3850,7 +4005,7 @@ index 5f4c817..bd9c672 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2754,7 +3397,7 @@ compare (struct line const *a, struct line const *b) +@@ -2842,7 +3485,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3859,7 +4014,7 @@ index 5f4c817..bd9c672 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4144,6 +4787,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4226,6 +4869,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3867,7 +4022,7 @@ index 5f4c817..bd9c672 100644 break; case 'g': key->general_numeric = true; -@@ -4223,7 +4867,7 @@ main (int argc, char **argv) +@@ -4305,7 +4949,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3876,8 +4031,8 @@ index 5f4c817..bd9c672 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4244,6 +4888,29 @@ main (int argc, char **argv) - thousands_sep = -1; +@@ -4328,6 +4972,29 @@ main (int argc, char **argv) + thousands_sep = NON_CHAR; } +#if HAVE_MBRTOWC @@ -3906,7 +4061,7 @@ index 5f4c817..bd9c672 100644 have_read_stdin = false; inittables (); -@@ -4518,13 +5185,34 @@ main (int argc, char **argv) +@@ -4602,13 +5269,34 @@ main (int argc, char **argv) case 't': { @@ -3945,7 +4100,7 @@ index 5f4c817..bd9c672 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4535,9 +5223,11 @@ main (int argc, char **argv) +@@ -4619,9 +5307,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3959,21 +4114,8 @@ index 5f4c817..bd9c672 100644 } break; -@@ -4766,12 +5456,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"), "-"); diff --git a/src/unexpand.c b/src/unexpand.c -index cec392d..483f0ef 100644 +index 7d6100f..04cd646 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -38,6 +38,9 @@ @@ -4179,7 +4321,7 @@ index cec392d..483f0ef 100644 } diff --git a/src/uniq.c b/src/uniq.c -index 8f6e973..752797a 100644 +index e5996f0..871d47c 100644 --- a/src/uniq.c +++ b/src/uniq.c @@ -21,6 +21,17 @@ @@ -4230,16 +4372,16 @@ index 8f6e973..752797a 100644 static struct option const longopts[] = { {"count", no_argument, NULL, 'c'}, -@@ -253,7 +280,7 @@ size_opt (char const *opt, char const *msgid) - return a pointer to the beginning of the line's field to be compared. */ +@@ -254,7 +281,7 @@ size_opt (char const *opt, char const *msgid) - static char * _GL_ATTRIBUTE_PURE + ATTRIBUTE_PURE + static char * -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 *line) +@@ -274,6 +301,83 @@ find_field (struct linebuffer const *line) return line->buffer + i; } @@ -4323,7 +4465,7 @@ index 8f6e973..752797a 100644 /* 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) +@@ -494,6 +598,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4344,7 +4486,7 @@ index 8f6e973..752797a 100644 skip_fields = 0; check_chars = SIZE_MAX; diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm -index dc6b132..a2abc6d 100644 +index fad7ab9..c9021a6 100644 --- a/tests/Coreutils.pm +++ b/tests/Coreutils.pm @@ -264,6 +264,9 @@ sub run_tests ($$$$$) @@ -4582,10 +4724,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 228d0e3..a76c808 100644 +index 0f77786..dbe1843 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -375,6 +375,8 @@ all_tests = \ +@@ -377,6 +377,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -4594,7 +4736,7 @@ index 228d0e3..a76c808 100644 tests/misc/sort-h-thousands-sep.sh \ tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ -@@ -573,6 +575,7 @@ all_tests = \ +@@ -576,6 +578,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4602,7 +4744,7 @@ index 228d0e3..a76c808 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -724,6 +727,7 @@ all_tests = \ +@@ -727,6 +730,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4611,7 +4753,7 @@ index 228d0e3..a76c808 100644 # See tests/factor/create-test.sh. diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index a10ff19..e1706c1 100755 +index 7a77e6f..27f6652 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -4678,7 +4820,7 @@ index a10ff19..e1706c1 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index beacec9..b56afca 100755 +index 2834f92..bc1616a 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; @@ -4751,7 +4893,7 @@ index beacec9..b56afca 100755 my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; diff --git a/tests/misc/join.pl b/tests/misc/join.pl -index bfd9e6f..75788c9 100755 +index 06ad777..be40204 100755 --- a/tests/misc/join.pl +++ b/tests/misc/join.pl @@ -25,6 +25,15 @@ my $limits = getlimits (); @@ -4872,7 +5014,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/sort-merge.pl b/tests/misc/sort-merge.pl -index 70d8af1..6b4840a 100755 +index 7eb4574..eda884c 100755 --- a/tests/misc/sort-merge.pl +++ b/tests/misc/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; @@ -4932,7 +5074,7 @@ index 70d8af1..6b4840a 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/sort.pl b/tests/misc/sort.pl -index 86970ff..c016ff7 100755 +index 0b0adca..fd27821 100755 --- a/tests/misc/sort.pl +++ b/tests/misc/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -5000,7 +5142,7 @@ index 86970ff..c016ff7 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 1c8e308..9f8ab89 100755 +index 2e1906f..fe66012 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -5057,7 +5199,7 @@ index 1c8e308..9f8ab89 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/uniq.pl b/tests/misc/uniq.pl -index 74d3815..aae4c7e 100755 +index aa163cd..91d617d 100755 --- a/tests/misc/uniq.pl +++ b/tests/misc/uniq.pl @@ -23,9 +23,17 @@ my $limits = getlimits (); @@ -5133,7 +5275,7 @@ index 74d3815..aae4c7e 100755 @Tests = triple_test \@Tests; diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index d0ac405..ff7d472 100755 +index 7ac6d4c..ae6cc35 100755 --- a/tests/pr/pr-tests.pl +++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; @@ -5380,5 +5522,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.31.1 +2.34.1 diff --git a/coreutils.spec b/coreutils.spec index c1c4c5d..766e55b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.0 -Release: 5%{?dist} +Version: 9.1 +Release: 1%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -17,12 +17,6 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ -# chmod: fix exit status when ignoring symlinks -Patch1: coreutils-9.0-chmod-symlink.patch - -# ls, stat: avoid triggering automounts (#2044981) -Patch2: coreutils-9.0-autofs-no-mount.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -31,7 +25,7 @@ Patch105: coreutils-8.26-selinuxenable.patch # downstream changes to default DIR_COLORS Patch102: coreutils-8.32-DIR_COLORS.patch -#do display processor type for uname -p/-i based on uname(2) syscall +# to be removed (#548834) Patch103: coreutils-8.2-uname-processortype.patch #df --direct Patch104: coreutils-df-direct.patch @@ -41,7 +35,6 @@ Patch107: coreutils-8.4-mkdir-modenote.patch # sh-utils #add info about TZ envvar to date manpage Patch703: sh-utils-2.0.11-dateman.patch -Patch713: coreutils-4.5.3-langinfo.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -183,7 +176,7 @@ for type in separate single; do if test $type = 'single'; then config_single='--enable-single-binary' config_single="$config_single --without-openssl" # smaller/slower sha*sum - config_single="$config_single --without-gmp" # expr/factor machine ints + config_single="$config_single --without-libgmp" # expr/factor machine ints else config_single='--with-openssl' # faster sha*sum fi @@ -269,6 +262,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Apr 19 2022 Kamil Dudka - 9.1-1 +- new upstream release 9.1 + * Mon Mar 21 2022 Kamil Dudka - 9.0-5 - ls, stat: avoid triggering automounts (#2044981) diff --git a/sources b/sources index 99d4423..1ff9c2a 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ -SHA512 (coreutils-9.0.tar.xz) = 9be08212891dbf48e5b22e7689dc27dac50df4631ebf29313470b72b7921f0b2aa5242917d05587785358495ca56e3b21f5b3ca81043d53cab92354da6c53a03 +SHA512 (coreutils-9.1.tar.xz.sig) = 9f0766531afd4faa3e2c337730f61db55605cf06729e9c61f644594883732c2e0b1ddb0005b492be309c53e6f45b8ff875398163a48699d52517ea49e9bdbc91 +SHA512 (coreutils-9.1.tar.xz) = a6ee2c549140b189e8c1b35e119d4289ec27244ec0ed9da0ac55202f365a7e33778b1dc7c4e64d1669599ff81a8297fe4f5adbcc8a3a2f75c919a43cd4b9bdfa From cc30dec8ebb52b44db1f88a13f7bfdbeaadd4659 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 19 Apr 2022 13:00:29 +0200 Subject: [PATCH 465/523] coreutils-9.0.tar.xz.sig: remove signature no longer used --- coreutils-9.0.tar.xz.sig | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 coreutils-9.0.tar.xz.sig diff --git a/coreutils-9.0.tar.xz.sig b/coreutils-9.0.tar.xz.sig deleted file mode 100644 index d9d405f..0000000 --- a/coreutils-9.0.tar.xz.sig +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCAAdFiEEbDfcEhIaUAa8HbgE32/ZcTBgN9kFAmFN1c4ACgkQ32/ZcTBg -N9mtfw/8D8BJrt2Ver2xdPfow5FYHT/zakUQ2b3ZIHP0Es62W56+pWtGombphrZu -4PkI1x6i4S8z06O9rWPIDGMPjyPV9UJbzAiGC7Px6tW6RFHZx0M+GNsKfcjmhtf7 -0v3jFF0g1IdrikFG1aYCAHZHy7n+yOm7xsfSmlYVlKcOVbCFN92ZBw0IohOSriSq -nJN6IOY8I3frhuI5kchY4wM6RMQ+ztNtG8odNvJI3kWCCL9pQFxzD8uorrvTiAcp -Qdbfz5TDnlVcXKR1gu6AAP+XThUYuxG5t/2Kghlril1zxnbDBZJsGteevyHsS7kY -grAWY4XqSvKVURGaKSSUhXlriQilPknBaichwEhAXvrUk1giviAzZ8CXB6WzzTvn -E9+ofC8RqTu345+ixkdZZu0TauOZWYIUVzKsD7W0ooQOT7OZeIQfb3+pbves/I+k -ZyiRLxfiUkAkKMUDrMr+okhqFA9fo/GCkFmHWj9m2NAc15kifEpSiCktfgoChbeG -ZiQFXQz090P+L1pk82qBXVgTjUyS5VEnXZoIkTWGzkHKySwreiaIjPQhS3cU2xAm -24i53zidj84Ib62Xa4jwxX7BzZqYRdbWAa/BUUNMov75W4dfkPlZ6qbRXtKnoOZf -u0ok3fgFvopGzwbw3l/HFp58jpaYL5S28gy10PpdOnxeO54XBn0= -=3TCC ------END PGP SIGNATURE----- From f672fec4364e71c6e5a30d4026d6bdb7cf332eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Sat, 23 Apr 2022 14:24:58 +0100 Subject: [PATCH 466/523] make simple backups in correct dir; broken in 9.1 From https://bugs.gnu.org/55029 --- coreutils.spec | 8 +++++++- gnulib-simple-backup-fix.patch | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 gnulib-simple-backup-fix.patch diff --git a/coreutils.spec b/coreutils.spec index 766e55b..37adee5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -17,6 +17,9 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ +# Make simple backups in correct dir; broken in 9.1 +Patch1: gnulib-simple-backup-fix.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -262,6 +265,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Sat Apr 23 2022 Pádraig Brady - 9.1-2 +- make simple backups in correct dir; broken in 9.1 + * Tue Apr 19 2022 Kamil Dudka - 9.1-1 - new upstream release 9.1 diff --git a/gnulib-simple-backup-fix.patch b/gnulib-simple-backup-fix.patch new file mode 100644 index 0000000..9c2d8a7 --- /dev/null +++ b/gnulib-simple-backup-fix.patch @@ -0,0 +1,36 @@ +commit 7347caeb9d902d3fca2c11f69a55a3e578d93bfe +Author: Paul Eggert +Date: Wed Apr 20 19:34:57 2022 -0700 + + backupfile: fix bug when renaming simple backups + + * lib/backupfile.c (backupfile_internal): Fix bug when RENAME + and when doing simple backups. Problem reported by Steve Ward in: + https://bugs.gnu.org/55029 + +diff --git a/lib/backupfile.c b/lib/backupfile.c +index 1e9290a187..d9f465a3e0 100644 +--- a/lib/backupfile.c ++++ b/lib/backupfile.c +@@ -332,7 +332,7 @@ backupfile_internal (int dir_fd, char const *file, + return s; + + DIR *dirp = NULL; +- int sdir = AT_FDCWD; ++ int sdir = dir_fd; + idx_t base_max = 0; + while (true) + { +@@ -371,10 +371,9 @@ backupfile_internal (int dir_fd, char const *file, + if (! rename) + break; + +- int olddirfd = sdir < 0 ? dir_fd : sdir; +- idx_t offset = sdir < 0 ? 0 : base_offset; ++ idx_t offset = backup_type == simple_backups ? 0 : base_offset; + unsigned flags = backup_type == simple_backups ? 0 : RENAME_NOREPLACE; +- if (renameatu (olddirfd, file + offset, sdir, s + offset, flags) == 0) ++ if (renameatu (sdir, file + offset, sdir, s + offset, flags) == 0) + break; + int e = errno; + if (! (e == EEXIST && extended)) From 2158b83433117df77b232404f9b55dad944bd751 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 20 Jul 2022 23:35:44 +0000 Subject: [PATCH 467/523] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 37adee5..894e7f0 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -265,6 +265,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jul 20 2022 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + * Sat Apr 23 2022 Pádraig Brady - 9.1-2 - make simple backups in correct dir; broken in 9.1 From e0f6afe5e62f80aa5d2007bd725b76158f76222e Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 1 Aug 2022 17:17:07 +0200 Subject: [PATCH 468/523] Resolves: #2112870 - prevent unexpand from failing on control characters --- coreutils-i18n.patch | 16 +++++++++------- coreutils.spec | 5 ++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 4ff0911..2ac39c6 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -19,7 +19,7 @@ Subject: [PATCH] coreutils-i18n.patch src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 792 +++++++++++++++++++++++++++++++++--- - src/unexpand.c | 101 ++++- + src/unexpand.c | 103 ++++- src/uniq.c | 119 +++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ @@ -35,7 +35,7 @@ Subject: [PATCH] coreutils-i18n.patch tests/misc/uniq.pl | 55 +++ tests/pr/pr-tests.pl | 49 +++ tests/unexpand/mb.sh | 172 ++++++++ - 31 files changed, 3698 insertions(+), 242 deletions(-) + 31 files changed, 3700 insertions(+), 242 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -4273,7 +4273,7 @@ index 7d6100f..04cd646 100644 { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -218,9 +277,9 @@ unexpand (void) +@@ -218,9 +277,11 @@ unexpand (void) next_tab_column = column; tab_index -= !!tab_index; } @@ -4281,11 +4281,13 @@ index 7d6100f..04cd646 100644 + else if (!mb_iseq (c, '\n')) { - column++; -+ column += mb_width (c); ++ /* mb_width() returns 0 for control characters */ ++ const int width = mb_width (c); ++ column += (width) ? width : 1; if (!column) die (EXIT_FAILURE, 0, _("input line is too long")); } -@@ -228,8 +287,11 @@ unexpand (void) +@@ -228,8 +289,11 @@ unexpand (void) if (pending) { if (pending > 1 && one_blank_before_tab_stop) @@ -4299,7 +4301,7 @@ index 7d6100f..04cd646 100644 die (EXIT_FAILURE, errno, _("write error")); pending = 0; one_blank_before_tab_stop = false; -@@ -239,16 +301,17 @@ unexpand (void) +@@ -239,16 +303,17 @@ unexpand (void) convert &= convert_entire_line || blank; } @@ -4489,7 +4491,7 @@ diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm index fad7ab9..c9021a6 100644 --- a/tests/Coreutils.pm +++ b/tests/Coreutils.pm -@@ -264,6 +264,9 @@ sub run_tests ($$$$$) +@@ -269,6 +269,9 @@ sub run_tests ($$$$$) # Yes, this is an arbitrary limit. If it causes trouble, # consider removing it. my $max = 30; diff --git a/coreutils.spec b/coreutils.spec index 894e7f0..761e6cd 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -265,6 +265,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Aug 01 2022 Kamil Dudka - 9.1-4 +- prevent unexpand from failing on control characters (#2112870) + * Wed Jul 20 2022 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild From 26b2c3ae54184e0be5ce766302769d058c518761 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 2 Aug 2022 11:08:50 +0200 Subject: [PATCH 469/523] Related: #2112870 - reflect review comments on the previous change --- coreutils-i18n.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 2ac39c6..f6881ed 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4283,7 +4283,7 @@ index 7d6100f..04cd646 100644 - column++; + /* mb_width() returns 0 for control characters */ + const int width = mb_width (c); -+ column += (width) ? width : 1; ++ column += MIN(1, width); if (!column) die (EXIT_FAILURE, 0, _("input line is too long")); } From 4dcaf08c8bbda65a04619f8bc33c585081062d11 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 2 Aug 2022 14:19:10 +0200 Subject: [PATCH 470/523] Resolves: #2112870 - fix regression introduced in the last commit --- coreutils-i18n.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index f6881ed..482ff4c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -4283,7 +4283,7 @@ index 7d6100f..04cd646 100644 - column++; + /* mb_width() returns 0 for control characters */ + const int width = mb_width (c); -+ column += MIN(1, width); ++ column += MAX(1, width); if (!column) die (EXIT_FAILURE, 0, _("input line is too long")); } From f3c6ff7e2cdc49208be8add4e51eec3c45767196 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 8 Aug 2022 12:44:08 +0200 Subject: [PATCH 471/523] Related: #2112870 - improve handling of control characters in unexpand --- coreutils-i18n.patch | 23 ++++++++++------------- coreutils.spec | 5 ++++- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 482ff4c..1a0770b 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -19,7 +19,7 @@ Subject: [PATCH] coreutils-i18n.patch src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 792 +++++++++++++++++++++++++++++++++--- - src/unexpand.c | 103 ++++- + src/unexpand.c | 102 ++++- src/uniq.c | 119 +++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ @@ -35,7 +35,7 @@ Subject: [PATCH] coreutils-i18n.patch tests/misc/uniq.pl | 55 +++ tests/pr/pr-tests.pl | 49 +++ tests/unexpand/mb.sh | 172 ++++++++ - 31 files changed, 3700 insertions(+), 242 deletions(-) + 31 files changed, 3699 insertions(+), 242 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -4273,21 +4273,18 @@ index 7d6100f..04cd646 100644 { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -218,9 +277,11 @@ unexpand (void) - next_tab_column = column; - tab_index -= !!tab_index; +@@ -220,16 +279,20 @@ unexpand (void) } -- else -+ else if (!mb_iseq (c, '\n')) + else { - column++; -+ /* mb_width() returns 0 for control characters */ -+ const int width = mb_width (c); -+ column += MAX(1, width); - if (!column) +- if (!column) ++ const uintmax_t orig_column = column; ++ column += mb_width (c); ++ if (column < orig_column) die (EXIT_FAILURE, 0, _("input line is too long")); } -@@ -228,8 +289,11 @@ unexpand (void) + if (pending) { if (pending > 1 && one_blank_before_tab_stop) @@ -4301,7 +4298,7 @@ index 7d6100f..04cd646 100644 die (EXIT_FAILURE, errno, _("write error")); pending = 0; one_blank_before_tab_stop = false; -@@ -239,16 +303,17 @@ unexpand (void) +@@ -239,16 +302,17 @@ unexpand (void) convert &= convert_entire_line || blank; } diff --git a/coreutils.spec b/coreutils.spec index 761e6cd..99aec6f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -265,6 +265,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Aug 08 2022 Kamil Dudka - 9.1-5 +- improve handling of control characters in unexpand (#2112870) + * Mon Aug 01 2022 Kamil Dudka - 9.1-4 - prevent unexpand from failing on control characters (#2112870) From 23b297bf5875dd2936d0b233cfceec0768868ee0 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 1 Aug 2022 15:46:57 +0200 Subject: [PATCH 472/523] Resolves: #2112593 - improve wording of a comment in /etc/DIR_COLORS --- coreutils-8.32-DIR_COLORS.patch | 8 ++++---- coreutils.spec | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index 3a0375d..14997a2 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -14,8 +14,8 @@ index b465771..ad42b09 100644 +++ b/DIR_COLORS @@ -1,3 +1,7 @@ +# This file goes in the /etc directory, and must be world readable. -+# You can copy this file to .dir_colors in your $HOME directory to override -+# the system defaults. ++# You can override the system defaults by making a copy of this file ++# as ~/.dir_colors + # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. @@ -47,8 +47,8 @@ index eab6258..1627b63 100644 +# Configuration file for the color ls utility - modified for lighter backgrounds + +# This file goes in the /etc directory, and must be world readable. -+# You can copy this file to .dir_colors in your $HOME directory to override -+# the system defaults. ++# You can override the system defaults by making a copy of this file ++# as ~/.dir_colors + # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. diff --git a/coreutils.spec b/coreutils.spec index 99aec6f..ec92f0a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 5%{?dist} +Release: 6%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -265,6 +265,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Aug 08 2022 Kamil Dudka - 9.1-6 +- improve wording of a comment in /etc/DIR_COLORS (#2112593) + * Mon Aug 08 2022 Kamil Dudka - 9.1-5 - improve handling of control characters in unexpand (#2112870) From cd953e11dd78cada371f0389171cea671949141b Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 23 Aug 2022 14:33:55 +0200 Subject: [PATCH 473/523] Related: #548834 - remove non-upstream patch for uname -i/-p The options have been documented as non-portable since 2015: http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=v8.24-7-g6d67649 --- coreutils-8.2-uname-processortype.patch | 44 ------------------------- coreutils.spec | 23 +++++++------ 2 files changed, 13 insertions(+), 54 deletions(-) delete mode 100644 coreutils-8.2-uname-processortype.patch diff --git a/coreutils-8.2-uname-processortype.patch b/coreutils-8.2-uname-processortype.patch deleted file mode 100644 index 44c57f5..0000000 --- a/coreutils-8.2-uname-processortype.patch +++ /dev/null @@ -1,44 +0,0 @@ - src/uname.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/src/uname.c b/src/uname.c -index 6371ca2..1ad8fd7 100644 ---- a/src/uname.c -+++ b/src/uname.c -@@ -322,6 +322,12 @@ main (int argc, char **argv) - # elif defined __ppc__ || defined __ppc64__ - element = "powerpc"; - # endif -+#else -+ { -+ static struct utsname u; -+ uname(&u); -+ element = u.machine; -+ } - #endif - #if HAVE_SYSINFO && defined SI_ARCHITECTURE - if (element == unknown) -@@ -347,7 +353,7 @@ main (int argc, char **argv) - - if (toprint & PRINT_HARDWARE_PLATFORM) - { -- char const *element = unknown; -+ char *element = unknown; - #if HAVE_SYSINFO && defined SI_PLATFORM - { - static char hardware_platform[257]; -@@ -355,6 +361,14 @@ main (int argc, char **argv) - hardware_platform, sizeof hardware_platform)) - element = hardware_platform; - } -+#else -+ { -+ static struct utsname u; -+ uname(&u); -+ element = u.machine; -+ if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6') -+ element[1]='3'; -+ } - #endif - #ifdef UNAME_HARDWARE_PLATFORM - if (element == unknown) diff --git a/coreutils.spec b/coreutils.spec index ec92f0a..1cdf9e7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -28,28 +28,28 @@ Patch105: coreutils-8.26-selinuxenable.patch # downstream changes to default DIR_COLORS Patch102: coreutils-8.32-DIR_COLORS.patch -# to be removed (#548834) -Patch103: coreutils-8.2-uname-processortype.patch -#df --direct + +# df --direct Patch104: coreutils-df-direct.patch -#add note about mkdir --mode behaviour into info documentation(#610559) + +# add note about mkdir --mode behaviour into info documentation(#610559) Patch107: coreutils-8.4-mkdir-modenote.patch -# sh-utils -#add info about TZ envvar to date manpage +# add info about TZ envvar to date manpage Patch703: sh-utils-2.0.11-dateman.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch -#getgrouplist() patch from Ulrich Drepper. +# getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch -#SELINUX Patch - implements Redhat changes -#(upstream did some SELinux implementation unlike with RedHat patch) +# SELINUX Patch - implements Redhat changes +# (upstream did some SELinux implementation unlike with RedHat patch) Patch950: coreutils-selinux.patch Conflicts: filesystem < 3 + # To avoid clobbering installs Conflicts: coreutils-single @@ -265,6 +265,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Aug 23 2022 Kamil Dudka - 9.1-7 +- remove non-upstream patch for uname -i/-p (#548834) + * Mon Aug 08 2022 Kamil Dudka - 9.1-6 - improve wording of a comment in /etc/DIR_COLORS (#2112593) From 31230267eaff42d0e5290da70a5eb49e9e04dfdb Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 19 Sep 2022 16:52:55 +0200 Subject: [PATCH 474/523] remove obsolete extension of mkdir(1) info documentation This has been addressed upstream with the following commit: https://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=v8.32-93-g3e61d5dd315 --- coreutils-8.4-mkdir-modenote.patch | 13 ------------- coreutils.spec | 8 ++++---- 2 files changed, 4 insertions(+), 17 deletions(-) delete mode 100644 coreutils-8.4-mkdir-modenote.patch diff --git a/coreutils-8.4-mkdir-modenote.patch b/coreutils-8.4-mkdir-modenote.patch deleted file mode 100644 index 3973d44..0000000 --- a/coreutils-8.4-mkdir-modenote.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 400e135..47e4480 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -10829,6 +10829,8 @@ incorrect. @xref{Directory Setuid and Setgid}, for how the - set-user-ID and set-group-ID bits of directories are inherited unless - overridden in this way. - -+Note: The @option{--mode},@option{-m} option only applies to the right-most directories listed on the command line. When combined with @option{--parents}, @option{-p} option, any parent directories are created with @samp{u+wx} modified by umask. -+ - @item -p - @itemx --parents - @opindex -p diff --git a/coreutils.spec b/coreutils.spec index 1cdf9e7..87b6da9 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 7%{?dist} +Release: 8%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -32,9 +32,6 @@ Patch102: coreutils-8.32-DIR_COLORS.patch # df --direct Patch104: coreutils-df-direct.patch -# add note about mkdir --mode behaviour into info documentation(#610559) -Patch107: coreutils-8.4-mkdir-modenote.patch - # add info about TZ envvar to date manpage Patch703: sh-utils-2.0.11-dateman.patch @@ -265,6 +262,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Sep 19 2022 Kamil Dudka - 9.1-8 +- remove obsolete extension of mkdir(1) info documentation + * Tue Aug 23 2022 Kamil Dudka - 9.1-7 - remove non-upstream patch for uname -i/-p (#548834) From ad57d2b8e82e890a766412caf5014fcc77b00c93 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 2 Jan 2023 10:37:21 +0100 Subject: [PATCH 475/523] Resolves: #2137866 - basic support for checking NFSv4 ACLs --- coreutils-nfsv4-acls.patch | 625 +++++++++++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 632 insertions(+), 1 deletion(-) create mode 100644 coreutils-nfsv4-acls.patch diff --git a/coreutils-nfsv4-acls.patch b/coreutils-nfsv4-acls.patch new file mode 100644 index 0000000..7dd036d --- /dev/null +++ b/coreutils-nfsv4-acls.patch @@ -0,0 +1,625 @@ +From 5a6af47c3db45b6303bac4dcd6da186fd5cd178c Mon Sep 17 00:00:00 2001 +From: Ondrej Valousek +Date: Fri, 2 Dec 2022 13:40:19 +0100 +Subject: [PATCH 1/3] file-has-acl: Basic support for checking NFSv4 ACLs in + Linux. + +* lib/acl-internal.h (acl_nfs4_nontrivial): New declaration. +* lib/acl-internal.c (acl_nfs4_nontrivial): New function. +* lib/file-has-acl.c: Include . +(XATTR_NAME_NFSV4_ACL, TRIVIAL_NFS4_ACL_MAX_LENGTH): New macros. +(file_has_acl): Test for NFSv4 ACLs. +* doc/acl-nfsv4.txt: New file. + +Upstream-commit: b0604a8e134dbcc307c0ffdd5ebd3693e9de7081 +Signed-off-by: Kamil Dudka +--- + doc/acl-nfsv4.txt | 17 ++++++++ + lib/acl-internal.c | 100 +++++++++++++++++++++++++++++++++++++++++++++ + lib/acl-internal.h | 3 ++ + lib/file-has-acl.c | 21 ++++++++++ + 4 files changed, 141 insertions(+) + create mode 100644 doc/acl-nfsv4.txt + +diff --git a/doc/acl-nfsv4.txt b/doc/acl-nfsv4.txt +new file mode 100644 +index 0000000..71352f5 +--- /dev/null ++++ b/doc/acl-nfsv4.txt +@@ -0,0 +1,17 @@ ++General introduction: ++ https://linux.die.net/man/5/nfs4_acl ++ ++The NFSv4 acls are defined in RFC7530 and as such, every NFSv4 server supporting ACLs ++will support this kind of ACLs (note the difference from POSIX draft ACLs) ++ ++The ACLs can be obtained via the nfsv4-acl-tools, i.e. ++ ++$ nfs4_getfacl ++ ++# file: ++A::OWNER@:rwaDxtTnNcCy ++A::GROUP@:rwaDxtTnNcy ++A::EVERYONE@:rwaDxtTnNcy ++ ++Gnulib is aiming to only provide a basic support of these, i.e. recognize trivial ++and non-trivial ACLs +diff --git a/lib/acl-internal.c b/lib/acl-internal.c +index be244c6..4c65dff 100644 +--- a/lib/acl-internal.c ++++ b/lib/acl-internal.c +@@ -25,6 +25,9 @@ + + #if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ + ++# include ++# include ++ + # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ + + /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. +@@ -122,6 +125,103 @@ acl_default_nontrivial (acl_t acl) + return (acl_entries (acl) > 0); + } + ++# define ACE4_WHO_OWNER "OWNER@" ++# define ACE4_WHO_GROUP "GROUP@" ++# define ACE4_WHO_EVERYONE "EVERYONE@" ++ ++# define ACE4_ACCESS_ALLOWED_ACE_TYPE 0 ++# define ACE4_ACCESS_DENIED_ACE_TYPE 1 ++ ++/* ACE flag values */ ++# define ACE4_IDENTIFIER_GROUP 0x00000040 ++# define ROUNDUP(x, y) (((x) + (y) - 1) & - (y)) ++ ++int ++acl_nfs4_nontrivial (char *xattr, int len) ++{ ++ int bufs = len; ++ uint32_t num_aces = ntohl (*((uint32_t*)(xattr))), /* Grab the number of aces in the acl */ ++ num_a_aces = 0, ++ num_d_aces = 0; ++ char *bufp = xattr; ++ ++ bufp += 4; /* sizeof(uint32_t); */ ++ bufs -= 4; ++ ++ for (uint32_t ace_n = 0; num_aces > ace_n ; ace_n++) ++ { ++ int d_ptr; ++ uint32_t flag, ++ wholen, ++ type; ++ ++ /* Get the acl type */ ++ if (bufs <= 0) ++ return -1; ++ ++ type = ntohl (*((uint32_t*)bufp)); ++ ++ bufp += 4; ++ bufs -= 4; ++ if (bufs <= 0) ++ return -1; ++ ++ flag = ntohl (*((uint32_t*)bufp)); ++ /* As per RFC 7530, the flag should be 0, but we are just generous to Netapp ++ * and also accept the Group flag ++ */ ++ if (flag & ~ACE4_IDENTIFIER_GROUP) ++ return 1; ++ ++ /* we skip mask - ++ * it's too risky to test it and it does not seem to be actually needed */ ++ bufp += 2*4; ++ bufs -= 2*4; ++ ++ if (bufs <= 0) ++ return -1; ++ ++ wholen = ntohl (*((uint32_t*)bufp)); ++ ++ bufp += 4; ++ bufs -= 4; ++ ++ /* Get the who string */ ++ if (bufs <= 0) ++ return -1; ++ ++ /* for trivial ACL, we expect max 5 (typically 3) ACES, 3 Allow, 2 deny */ ++ if (((strncmp (bufp, ACE4_WHO_OWNER, wholen) == 0) ++ || (strncmp (bufp, ACE4_WHO_GROUP, wholen) == 0)) ++ && wholen == 6) ++ { ++ if (type == ACE4_ACCESS_ALLOWED_ACE_TYPE) ++ num_a_aces++; ++ if (type == ACE4_ACCESS_DENIED_ACE_TYPE) ++ num_d_aces++; ++ } ++ else ++ if ((strncmp (bufp, ACE4_WHO_EVERYONE, wholen) == 0) ++ && (type == ACE4_ACCESS_ALLOWED_ACE_TYPE) ++ && (wholen == 9)) ++ num_a_aces++; ++ else ++ return 1; ++ ++ d_ptr = ROUNDUP (wholen, 4); ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Make sure we aren't outside our domain */ ++ if (bufs < 0) ++ return -1; ++ ++ } ++ return !((num_a_aces <= 3) && (num_d_aces <= 2) ++ && (num_a_aces + num_d_aces == num_aces)); ++ ++} ++ + # endif + + #elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */ +diff --git a/lib/acl-internal.h b/lib/acl-internal.h +index 9353376..2a249ff 100644 +--- a/lib/acl-internal.h ++++ b/lib/acl-internal.h +@@ -147,6 +147,9 @@ rpl_acl_set_fd (int fd, acl_t acl) + # define acl_entries rpl_acl_entries + extern int acl_entries (acl_t); + # endif ++/* Return 1 if given ACL in XDR format is non-trivial ++ * Return 0 if it is trivial */ ++extern int acl_nfs4_nontrivial (char *, int); + + # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ + /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. +diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c +index e02f062..1710234 100644 +--- a/lib/file-has-acl.c ++++ b/lib/file-has-acl.c +@@ -32,6 +32,11 @@ + #if GETXATTR_WITH_POSIX_ACLS + # include + # include ++# include ++# ifndef XATTR_NAME_NFSV4_ACL ++# define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" ++# endif ++# define TRIVIAL_NFS4_ACL_MAX_LENGTH 128 + #endif + + /* Return 1 if NAME has a nontrivial access control list, +@@ -67,6 +72,22 @@ file_has_acl (char const *name, struct stat const *sb) + return 1; + } + ++ if (ret < 0) ++ { /* we might be on NFS, so try to check NFSv4 ACLs too */ ++ char xattr[TRIVIAL_NFS4_ACL_MAX_LENGTH]; ++ ++ errno = 0; /* we need to reset errno set by the previous getxattr() */ ++ ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, TRIVIAL_NFS4_ACL_MAX_LENGTH); ++ if (ret < 0 && errno == ENODATA) ++ ret = 0; ++ else ++ if (ret < 0 && errno == ERANGE) ++ return 1; /* we won't fit into the buffer, so non-trivial ACL is presented */ ++ else ++ if (ret > 0) ++ /* looks like trivial ACL, but we need to investigate further */ ++ return acl_nfs4_nontrivial (xattr, ret); ++ } + if (ret < 0) + return - acl_errno_valid (errno); + return ret; +-- +2.38.1 + + +From c5266d204a446bea619fa18da8520dceb0a54192 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Fri, 23 Dec 2022 15:18:29 -0800 +Subject: [PATCH 2/3] file-has-acl: improve recent NFSv4 support +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes a link failure with emacsclient on GNU/Linux. This +program wants file_has_acl but none of the other ACL primitives, +so it doesn’t link acl-internal.o; this way it doesn’t need to +link with -lacl. While I was at it I reviewed the recent changes, +fixed some unlikely overflow bugs, and adjusted to GNU style. +* doc/acl-nfsv4.txt: Remove. Its contents are now in a +comment in lib/file-has-acl.c. +* lib/acl-internal.c, lib/acl-internal.h: Move recent changes +relating to acl_nfs4_nontrivial to lib/file-has-acl.c, so that +there is no trouble linking programs that need only file_has_acl. +* lib/file-has-acl.c (acl_nfs4_nontrivial): Move here from +lib/acl-internal.c, so that we needn't link -lacl in +programs that want only file_has_acl, such as emacsclient. +Do not assume a char buffer is aligned for uint32_t. +Check more carefully for buffer read overrun. +Allow up to 6 ACEs, since other code does; but check +that they’re distinct. Avoid integer overflow. +Use memcmp rather than strncmp to compare memory blocks. +(file_has_acl): Preserve initial errno instead of setting to 0. +Allocate a bit more room for trivial ACL buffer. +Use EINVAL for botchedk NFSv4 ACLs (which shouldn’t happen). + +Upstream-commit: 35bd46f0c816948dc1a0430c8ba8b10a01167320 +Signed-off-by: Kamil Dudka +--- + doc/acl-nfsv4.txt | 17 ------ + lib/acl-internal.c | 100 ----------------------------------- + lib/acl-internal.h | 3 -- + lib/file-has-acl.c | 129 +++++++++++++++++++++++++++++++++++++++------ + 4 files changed, 113 insertions(+), 136 deletions(-) + delete mode 100644 doc/acl-nfsv4.txt + +diff --git a/doc/acl-nfsv4.txt b/doc/acl-nfsv4.txt +deleted file mode 100644 +index 71352f5..0000000 +--- a/doc/acl-nfsv4.txt ++++ /dev/null +@@ -1,17 +0,0 @@ +-General introduction: +- https://linux.die.net/man/5/nfs4_acl +- +-The NFSv4 acls are defined in RFC7530 and as such, every NFSv4 server supporting ACLs +-will support this kind of ACLs (note the difference from POSIX draft ACLs) +- +-The ACLs can be obtained via the nfsv4-acl-tools, i.e. +- +-$ nfs4_getfacl +- +-# file: +-A::OWNER@:rwaDxtTnNcCy +-A::GROUP@:rwaDxtTnNcy +-A::EVERYONE@:rwaDxtTnNcy +- +-Gnulib is aiming to only provide a basic support of these, i.e. recognize trivial +-and non-trivial ACLs +diff --git a/lib/acl-internal.c b/lib/acl-internal.c +index 4c65dff..be244c6 100644 +--- a/lib/acl-internal.c ++++ b/lib/acl-internal.c +@@ -25,9 +25,6 @@ + + #if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ + +-# include +-# include +- + # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ + + /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. +@@ -125,103 +122,6 @@ acl_default_nontrivial (acl_t acl) + return (acl_entries (acl) > 0); + } + +-# define ACE4_WHO_OWNER "OWNER@" +-# define ACE4_WHO_GROUP "GROUP@" +-# define ACE4_WHO_EVERYONE "EVERYONE@" +- +-# define ACE4_ACCESS_ALLOWED_ACE_TYPE 0 +-# define ACE4_ACCESS_DENIED_ACE_TYPE 1 +- +-/* ACE flag values */ +-# define ACE4_IDENTIFIER_GROUP 0x00000040 +-# define ROUNDUP(x, y) (((x) + (y) - 1) & - (y)) +- +-int +-acl_nfs4_nontrivial (char *xattr, int len) +-{ +- int bufs = len; +- uint32_t num_aces = ntohl (*((uint32_t*)(xattr))), /* Grab the number of aces in the acl */ +- num_a_aces = 0, +- num_d_aces = 0; +- char *bufp = xattr; +- +- bufp += 4; /* sizeof(uint32_t); */ +- bufs -= 4; +- +- for (uint32_t ace_n = 0; num_aces > ace_n ; ace_n++) +- { +- int d_ptr; +- uint32_t flag, +- wholen, +- type; +- +- /* Get the acl type */ +- if (bufs <= 0) +- return -1; +- +- type = ntohl (*((uint32_t*)bufp)); +- +- bufp += 4; +- bufs -= 4; +- if (bufs <= 0) +- return -1; +- +- flag = ntohl (*((uint32_t*)bufp)); +- /* As per RFC 7530, the flag should be 0, but we are just generous to Netapp +- * and also accept the Group flag +- */ +- if (flag & ~ACE4_IDENTIFIER_GROUP) +- return 1; +- +- /* we skip mask - +- * it's too risky to test it and it does not seem to be actually needed */ +- bufp += 2*4; +- bufs -= 2*4; +- +- if (bufs <= 0) +- return -1; +- +- wholen = ntohl (*((uint32_t*)bufp)); +- +- bufp += 4; +- bufs -= 4; +- +- /* Get the who string */ +- if (bufs <= 0) +- return -1; +- +- /* for trivial ACL, we expect max 5 (typically 3) ACES, 3 Allow, 2 deny */ +- if (((strncmp (bufp, ACE4_WHO_OWNER, wholen) == 0) +- || (strncmp (bufp, ACE4_WHO_GROUP, wholen) == 0)) +- && wholen == 6) +- { +- if (type == ACE4_ACCESS_ALLOWED_ACE_TYPE) +- num_a_aces++; +- if (type == ACE4_ACCESS_DENIED_ACE_TYPE) +- num_d_aces++; +- } +- else +- if ((strncmp (bufp, ACE4_WHO_EVERYONE, wholen) == 0) +- && (type == ACE4_ACCESS_ALLOWED_ACE_TYPE) +- && (wholen == 9)) +- num_a_aces++; +- else +- return 1; +- +- d_ptr = ROUNDUP (wholen, 4); +- bufp += d_ptr; +- bufs -= d_ptr; +- +- /* Make sure we aren't outside our domain */ +- if (bufs < 0) +- return -1; +- +- } +- return !((num_a_aces <= 3) && (num_d_aces <= 2) +- && (num_a_aces + num_d_aces == num_aces)); +- +-} +- + # endif + + #elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */ +diff --git a/lib/acl-internal.h b/lib/acl-internal.h +index 2a249ff..9353376 100644 +--- a/lib/acl-internal.h ++++ b/lib/acl-internal.h +@@ -147,9 +147,6 @@ rpl_acl_set_fd (int fd, acl_t acl) + # define acl_entries rpl_acl_entries + extern int acl_entries (acl_t); + # endif +-/* Return 1 if given ACL in XDR format is non-trivial +- * Return 0 if it is trivial */ +-extern int acl_nfs4_nontrivial (char *, int); + + # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ + /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. +diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c +index 1710234..676523b 100644 +--- a/lib/file-has-acl.c ++++ b/lib/file-has-acl.c +@@ -29,14 +29,97 @@ + + #include "acl-internal.h" + +-#if GETXATTR_WITH_POSIX_ACLS ++#if USE_ACL && GETXATTR_WITH_POSIX_ACLS ++# include ++# include + # include + # include +-# include + # ifndef XATTR_NAME_NFSV4_ACL + # define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" + # endif +-# define TRIVIAL_NFS4_ACL_MAX_LENGTH 128 ++ ++enum { ++ /* ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000, */ ++ ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001, ++ ACE4_IDENTIFIER_GROUP = 0x00000040 ++}; ++ ++/* Return 1 if given ACL in XDR format is non-trivial, 0 if it is trivial. ++ -1 upon failure to determine it. Possibly change errno. Assume that ++ the ACL is valid, except avoid undefined behavior even if invalid. ++ ++ See . The NFSv4 acls are ++ defined in Internet RFC 7530 and as such, every NFSv4 server ++ supporting ACLs should support NFSv4 ACLs (they differ from from ++ POSIX draft ACLs). The ACLs can be obtained via the ++ nfsv4-acl-tools, e.g., the nfs4_getfacl command. Gnulib provides ++ only basic support of NFSv4 ACLs, i.e., recognize trivial vs ++ nontrivial ACLs. */ ++ ++static int ++acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) ++{ ++ enum { BYTES_PER_NETWORK_UINT = 4}; ++ ++ /* Grab the number of aces in the acl. */ ++ nbytes -= BYTES_PER_NETWORK_UINT; ++ if (nbytes < 0) ++ return -1; ++ uint32_t num_aces = ntohl (*xattr++); ++ if (6 < num_aces) ++ return 1; ++ int ace_found = 0; ++ ++ for (int ace_n = 0; ace_n < num_aces; ace_n++) ++ { ++ /* Get the acl type and flag. Skip the mask; it's too risky to ++ test it and it does not seem to be needed. Get the wholen. */ ++ nbytes -= 4 * BYTES_PER_NETWORK_UINT; ++ if (nbytes < 0) ++ return -1; ++ uint32_t type = ntohl (xattr[0]); ++ uint32_t flag = ntohl (xattr[1]); ++ uint32_t wholen = ntohl (xattr[3]); ++ xattr += 4; ++ int64_t wholen4 = wholen; ++ wholen4 = ((wholen4 + (BYTES_PER_NETWORK_UINT)) ++ & ~ (BYTES_PER_NETWORK_UINT - 1)); ++ ++ /* Trivial ACLs have only ACE4_ACCESS_ALLOWED_ACE_TYPE or ++ ACE4_ACCESS_DENIED_ACE_TYPE. */ ++ if (ACE4_ACCESS_DENIED_ACE_TYPE < type) ++ return 1; ++ ++ /* RFC 7530 says FLAG should be 0, but be generous to NetApp and ++ also accept the group flag. */ ++ if (flag & ~ACE4_IDENTIFIER_GROUP) ++ return 1; ++ ++ /* Get the who string. Check NBYTES - WHOLEN4 before storing ++ into NBYTES, to avoid truncation on conversion. */ ++ if (nbytes - wholen4 < 0) ++ return -1; ++ nbytes -= wholen4; ++ ++ /* For a trivial ACL, max 6 (typically 3) ACEs, 3 allow, 3 deny. ++ Check that there is at most one ACE of each TYPE and WHO. */ ++ int who2 ++ = (wholen == 6 && memcmp (xattr, "OWNER@", 6) == 0 ? 0 ++ : wholen == 6 && memcmp (xattr, "GROUP@", 6) == 0 ? 2 ++ : wholen == 9 && memcmp (xattr, "EVERYONE@", 9) == 0 ? 4 ++ : -1); ++ if (who2 < 0) ++ return 1; ++ int ace_found_bit = 1 << (who2 | type); ++ if (ace_found & ace_found_bit) ++ return 1; ++ ace_found |= ace_found_bit; ++ ++ xattr = (uint32_t *) ((char *) xattr + wholen4); ++ } ++ ++ return 0; ++} + #endif + + /* Return 1 if NAME has a nontrivial access control list, +@@ -56,6 +139,7 @@ file_has_acl (char const *name, struct stat const *sb) + # if GETXATTR_WITH_POSIX_ACLS + + ssize_t ret; ++ int initial_errno = errno; + + ret = getxattr (name, XATTR_NAME_POSIX_ACL_ACCESS, NULL, 0); + if (ret < 0 && errno == ENODATA) +@@ -73,20 +157,33 @@ file_has_acl (char const *name, struct stat const *sb) + } + + if (ret < 0) +- { /* we might be on NFS, so try to check NFSv4 ACLs too */ +- char xattr[TRIVIAL_NFS4_ACL_MAX_LENGTH]; +- +- errno = 0; /* we need to reset errno set by the previous getxattr() */ +- ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, TRIVIAL_NFS4_ACL_MAX_LENGTH); +- if (ret < 0 && errno == ENODATA) +- ret = 0; ++ { ++ /* Check for NFSv4 ACLs. The max length of a trivial ++ ACL is 6 words for owner, 6 for group, 7 for everyone, ++ all times 2 because there are both allow and deny ACEs. ++ There are 6 words for owner because of type, flag, mask, ++ wholen, "OWNER@"+pad and similarly for group; everyone is ++ another word to hold "EVERYONE@". */ ++ uint32_t xattr[2 * (6 + 6 + 7)]; ++ ++ ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, sizeof xattr); ++ if (ret < 0) ++ switch (errno) ++ { ++ case ENODATA: return 0; ++ case ERANGE : return 1; /* ACL must be nontrivial. */ ++ } + else +- if (ret < 0 && errno == ERANGE) +- return 1; /* we won't fit into the buffer, so non-trivial ACL is presented */ +- else +- if (ret > 0) +- /* looks like trivial ACL, but we need to investigate further */ +- return acl_nfs4_nontrivial (xattr, ret); ++ { ++ /* It looks like a trivial ACL, but investigate further. */ ++ ret = acl_nfs4_nontrivial (xattr, ret); ++ if (ret < 0) ++ { ++ errno = EINVAL; ++ return ret; ++ } ++ errno = initial_errno; ++ } + } + if (ret < 0) + return - acl_errno_valid (errno); +-- +2.38.1 + + +From faf965110372c82cd99e9f44f0c64f03cdabb2c1 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Tue, 27 Dec 2022 20:00:58 -0800 +Subject: [PATCH 3/3] file-has-acl: fix recently-introduced NFSv4 bug + +* lib/file-has-acl.c (acl_nfs4_nontrivial): Fix off-by-one +error when rounding WHOLEN up to next multiple of 4. +Pacify GCC 12.2.1 -Wcast-align. + +Upstream-commit: d65e5a8ba77595a598c9ddb8dfa09c4aea732659 +Signed-off-by: Kamil Dudka +--- + lib/file-has-acl.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c +index 676523b..7876edc 100644 +--- a/lib/file-has-acl.c ++++ b/lib/file-has-acl.c +@@ -81,9 +81,10 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) + uint32_t flag = ntohl (xattr[1]); + uint32_t wholen = ntohl (xattr[3]); + xattr += 4; +- int64_t wholen4 = wholen; +- wholen4 = ((wholen4 + (BYTES_PER_NETWORK_UINT)) +- & ~ (BYTES_PER_NETWORK_UINT - 1)); ++ int whowords = (wholen / BYTES_PER_NETWORK_UINT ++ + (wholen % BYTES_PER_NETWORK_UINT != 0)); ++ int64_t wholen4 = whowords; ++ wholen4 *= BYTES_PER_NETWORK_UINT; + + /* Trivial ACLs have only ACE4_ACCESS_ALLOWED_ACE_TYPE or + ACE4_ACCESS_DENIED_ACE_TYPE. */ +@@ -115,7 +116,7 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) + return 1; + ace_found |= ace_found_bit; + +- xattr = (uint32_t *) ((char *) xattr + wholen4); ++ xattr += whowords; + } + + return 0; +-- +2.38.1 + diff --git a/coreutils.spec b/coreutils.spec index 87b6da9..6bd6157 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 8%{?dist} +Release: 9%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -20,6 +20,9 @@ Source106: coreutils-colorls.csh # Make simple backups in correct dir; broken in 9.1 Patch1: gnulib-simple-backup-fix.patch +# basic support for checking NFSv4 ACLs (#2137866) +Patch2: coreutils-nfsv4-acls.patch + # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -262,6 +265,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jan 02 2023 Kamil Dudka - 9.1-9 +- basic support for checking NFSv4 ACLs (#2137866) + * Mon Sep 19 2022 Kamil Dudka - 9.1-8 - remove obsolete extension of mkdir(1) info documentation From 9d850274b193f248a0228978e92b9813d312e8fe Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 2 Jan 2023 13:24:04 +0100 Subject: [PATCH 476/523] coreutils-selinux.patch: undocument downstream SELinux options They have been deprecated since 2009. --- coreutils-selinux.patch | 109 +++++++++++----------------------------- coreutils.spec | 8 +-- 2 files changed, 35 insertions(+), 82 deletions(-) diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 1f7f3a3..7136f3f 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -4,65 +4,15 @@ Date: Mon, 4 Oct 2021 08:45:53 +0200 Subject: [PATCH] coreutils-selinux.patch --- - doc/coreutils.texi | 5 +++++ - man/chcon.x | 2 +- - man/runcon.x | 2 +- - src/cp.c | 16 +++++++++++++++- - src/install.c | 10 ++++++++-- - 5 files changed, 30 insertions(+), 5 deletions(-) + src/cp.c | 19 ++++++++++++++++++- + src/install.c | 12 +++++++++++- + 2 files changed, 29 insertions(+), 2 deletions(-) -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 6810c15..19b535c 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -8766,6 +8766,11 @@ done - exit $fail - @end example - -+@item -c -+@cindex SELinux security context information, preserving -+Preserve SELinux security context of the original files if possible. -+Some file systems don't support storing of SELinux security context. -+ - @item --copy-contents - @cindex directories, copying recursively - @cindex copying directories recursively -diff --git a/man/chcon.x b/man/chcon.x -index 8c1ff6f..c84fb96 100644 ---- a/man/chcon.x -+++ b/man/chcon.x -@@ -1,4 +1,4 @@ - [NAME] --chcon \- change file security context -+chcon \- change file SELinux security context - [DESCRIPTION] - .\" Add any additional description here -diff --git a/man/runcon.x b/man/runcon.x -index d2df13e..5c5f5d8 100644 ---- a/man/runcon.x -+++ b/man/runcon.x -@@ -1,5 +1,5 @@ - [NAME] --runcon \- run command with specified security context -+runcon \- run command with specified SELinux security context - [DESCRIPTION] - Run COMMAND with completely-specified CONTEXT, or with current or - transitioned security context modified by one or more of LEVEL, diff --git a/src/cp.c b/src/cp.c index c97a675..89fb8ec 100644 --- a/src/cp.c +++ b/src/cp.c -@@ -191,6 +191,9 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\ - additional attributes: context, links, xattr,\ - \n\ - all\n\ -+"), stdout); -+ fputs (_("\ -+ -c deprecated, same as --preserve=context\n\ - "), stdout); - fputs (_("\ - --no-preserve=ATTR_LIST don't preserve the specified attributes\n\ -@@ -954,7 +957,7 @@ main (int argc, char **argv) +@@ -952,7 +952,7 @@ main (int argc, char **argv) selinux_enabled = (0 < is_selinux_enabled ()); cp_option_init (&x); @@ -71,21 +21,27 @@ index c97a675..89fb8ec 100644 long_opts, NULL)) != -1) { -@@ -1002,6 +1005,17 @@ main (int argc, char **argv) +@@ -1000,6 +1000,23 @@ main (int argc, char **argv) copy_contents = true; break; + case 'c': -+ fprintf (stderr, "%s: warning: option '-c' is deprecated, please use '--preserve=context' instead\n", argv[0]); -+ if ( x.set_security_context ) { -+ (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]); -+ exit( 1 ); -+ } -+ else if (selinux_enabled) { ++ fprintf (stderr, "%s: warning: option '-c' is deprecated," ++ " please use '--preserve=context' instead\n", argv[0]); ++ if (x.set_security_context) ++ { ++ fprintf (stderr, ++ "%s: cannot force target context and preserve it\n", ++ argv[0]); ++ exit (1); ++ } ++ else if (selinux_enabled) ++ { + x.preserve_security_context = true; + x.require_preserve_context = true; -+ } ++ } + break; ++ case 'd': x.preserve_links = true; x.dereference = DEREF_NEVER; @@ -93,16 +49,7 @@ diff --git a/src/install.c b/src/install.c index c9456fe..2b1bee9 100644 --- a/src/install.c +++ b/src/install.c -@@ -638,7 +638,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\ - -v, --verbose print the name of each directory as it is created\n\ - "), stdout); - fputs (_("\ -- --preserve-context preserve SELinux security context\n\ -+ -P, --preserve-context preserve SELinux security context (-P deprecated)\n\ - -Z set SELinux security context of destination\n\ - file and each created directory to default type\n\ - --context[=CTX] like -Z, or if CTX is specified then set the\n\ -@@ -790,7 +790,7 @@ main (int argc, char **argv) +@@ -794,7 +794,7 @@ main (int argc, char **argv) dir_arg = false; umask (0); @@ -111,23 +58,27 @@ index c9456fe..2b1bee9 100644 NULL)) != -1) { switch (optc) -@@ -851,6 +851,8 @@ main (int argc, char **argv) +@@ -855,6 +855,9 @@ main (int argc, char **argv) no_target_directory = true; break; + case 'P': -+ fprintf (stderr, "%s: warning: option '-P' is deprecated, please use '--preserve-context' instead\n", argv[0]); ++ fprintf (stderr, "%s: warning: option '-P' is deprecated," ++ " please use '--preserve-context' instead\n", argv[0]); case PRESERVE_CONTEXT_OPTION: if (! selinux_enabled) { -@@ -858,6 +860,10 @@ main (int argc, char **argv) +@@ -862,6 +865,13 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } -+ if ( x.set_security_context ) { -+ (void) fprintf(stderr, "%s: cannot force target context and preserve it\n", argv[0]); -+ exit( 1 ); -+ } ++ if (x.set_security_context) ++ { ++ fprintf (stderr, ++ "%s: cannot force target context and preserve it\n", ++ argv[0]); ++ exit (1); ++ } x.preserve_security_context = true; use_default_selinux_context = false; break; diff --git a/coreutils.spec b/coreutils.spec index 6bd6157..02fe008 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 9%{?dist} +Release: 10%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -44,8 +44,7 @@ Patch800: coreutils-i18n.patch # getgrouplist() patch from Ulrich Drepper. Patch908: coreutils-getgrouplist.patch -# SELINUX Patch - implements Redhat changes -# (upstream did some SELinux implementation unlike with RedHat patch) +# downstream SELinux options deprecated since 2009 Patch950: coreutils-selinux.patch Conflicts: filesystem < 3 @@ -265,6 +264,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jan 02 2023 Kamil Dudka - 9.1-10 +- undocument downstream SELinux options deprecated since 2009 + * Mon Jan 02 2023 Kamil Dudka - 9.1-9 - basic support for checking NFSv4 ACLs (#2137866) From ea41467a5641bf5ef6b91b06e2eab2726cddfbce Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 2 Jan 2023 13:30:01 +0100 Subject: [PATCH 477/523] drop obsolete downstream-only extension of date(1) man page This was addressed by the following upstream patch long time ago: https://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=COREUTILS-5_2_1-1561-gdf8ea7a4e89 --- coreutils.spec | 6 ++---- sh-utils-2.0.11-dateman.patch | 12 ------------ 2 files changed, 2 insertions(+), 16 deletions(-) delete mode 100644 sh-utils-2.0.11-dateman.patch diff --git a/coreutils.spec b/coreutils.spec index 02fe008..44986c7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -27,7 +27,7 @@ Patch2: coreutils-nfsv4-acls.patch Patch100: coreutils-8.26-test-lock.patch # require_selinux_(): use selinuxenabled(8) if available -Patch105: coreutils-8.26-selinuxenable.patch +Patch101: coreutils-8.26-selinuxenable.patch # downstream changes to default DIR_COLORS Patch102: coreutils-8.32-DIR_COLORS.patch @@ -35,9 +35,6 @@ Patch102: coreutils-8.32-DIR_COLORS.patch # df --direct Patch104: coreutils-df-direct.patch -# add info about TZ envvar to date manpage -Patch703: sh-utils-2.0.11-dateman.patch - # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -265,6 +262,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Mon Jan 02 2023 Kamil Dudka - 9.1-10 +- drop obsolete downstream-only extension of date(1) man page - undocument downstream SELinux options deprecated since 2009 * Mon Jan 02 2023 Kamil Dudka - 9.1-9 diff --git a/sh-utils-2.0.11-dateman.patch b/sh-utils-2.0.11-dateman.patch deleted file mode 100644 index 60cdaa6..0000000 --- a/sh-utils-2.0.11-dateman.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -urNp coreutils-5.97-orig/man/date.x coreutils-5.97/man/date.x ---- coreutils-5.97-orig/man/date.x 1999-11-02 15:07:36.000000000 +0100 -+++ coreutils-5.97/man/date.x 2008-10-15 10:13:31.000000000 +0200 -@@ -11,3 +11,8 @@ calendar date, time of day, time zone, day of week, relative time, - relative date, and numbers. An empty string indicates the beginning - of the day. The date string format is more complex than is easily - documented here but is fully described in the info documentation. -+[ENVIRONMENT] -+.TP -+TZ -+Specifies the timezone, unless overridden by command line parameters. -+If neither is specified, the setting from /etc/localtime is used. From f8035e385d5268fac0a8b6090012eab8a088a320 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 00:31:11 +0000 Subject: [PATCH 478/523] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 44986c7..8c4a6b1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.1 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -261,6 +261,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jan 19 2023 Fedora Release Engineering +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Mon Jan 02 2023 Kamil Dudka - 9.1-10 - drop obsolete downstream-only extension of date(1) man page - undocument downstream SELinux options deprecated since 2009 From 43d181cda7aef268d01fe181f6b37657e1213052 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 22 Mar 2023 10:25:21 +0100 Subject: [PATCH 479/523] new upstream release 9.2 --- coreutils-8.32-DIR_COLORS.patch | 26 +- coreutils-i18n.patch | 138 +++---- coreutils-nfsv4-acls.patch | 625 -------------------------------- coreutils.spec | 13 +- gnulib-simple-backup-fix.patch | 36 -- sources | 4 +- 6 files changed, 89 insertions(+), 753 deletions(-) delete mode 100644 coreutils-nfsv4-acls.patch delete mode 100644 gnulib-simple-backup-fix.patch diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index 14997a2..ee037bf 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -20,17 +20,17 @@ index b465771..ad42b09 100644 # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. -@@ -10,6 +14,9 @@ +@@ -11,6 +15,9 @@ # Global config options can be specified before TERM or COLORTERM entries +# For compatibility, the pattern "^COLOR.*none" is recognized as a way to +# disable colorization. See https://bugzilla.redhat.com/1349579 for details. + - # Below are TERM or COLORTERM entries, which can be glob patterns, which - # restrict following config to systems with matching environment variables. - COLORTERM ?* -@@ -62,7 +69,7 @@ DOOR 01;35 # door + # =================================================================== + # Terminal filters + # =================================================================== +@@ -69,7 +76,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -53,17 +53,17 @@ index eab6258..1627b63 100644 # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. -@@ -10,6 +16,9 @@ +@@ -11,6 +17,9 @@ # Global config options can be specified before TERM or COLORTERM entries +# For compatibility, the pattern "^COLOR.*none" is recognized as a way to +# disable colorization. See https://bugzilla.redhat.com/1349579 for details. + - # Below are TERM or COLORTERM entries, which can be glob patterns, which - # restrict following config to systems with matching environment variables. - COLORTERM ?* -@@ -52,17 +61,17 @@ TERM xterm* + # =================================================================== + # Terminal filters + # =================================================================== +@@ -59,17 +68,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -86,15 +86,15 @@ index eab6258..1627b63 100644 SETUID 37;41 # file that is setuid (u+s) SETGID 30;43 # file that is setgid (g+s) CAPABILITY 00 # file with capability (very expensive to lookup) -@@ -71,7 +80,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +@@ -78,7 +87,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for files with execute permission: -EXEC 01;32 +EXEC 00;32 - # List any file extensions like '.gz' or '.tar' that you would like ls - # to color below. Put the extension, a space, and the color init string. + # =================================================================== + # File extension attributes -- 2.34.1 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 1a0770b..8492fe6 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -48,7 +48,7 @@ diff --git a/bootstrap.conf b/bootstrap.conf index c1399e3..60b39cf 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -162,6 +162,7 @@ gnulib_modules=" +@@ -165,6 +165,7 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -60,7 +60,7 @@ diff --git a/configure.ac b/configure.ac index 7e4afc9..4656a35 100644 --- a/configure.ac +++ b/configure.ac -@@ -476,6 +476,8 @@ fi +@@ -477,6 +477,8 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -401,7 +401,7 @@ index 6fd8978..faef877 100644 #include "system.h" #include "error.h" -@@ -37,6 +42,18 @@ +@@ -36,6 +41,18 @@ #include "set-fields.h" @@ -420,7 +420,7 @@ index 6fd8978..faef877 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "cut" -@@ -53,6 +70,52 @@ +@@ -52,6 +69,52 @@ } \ while (0) @@ -473,7 +473,7 @@ index 6fd8978..faef877 100644 /* 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 -@@ -60,6 +123,9 @@ +@@ -59,6 +122,9 @@ CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ static struct field_range_pair *current_rp; @@ -483,7 +483,7 @@ index 6fd8978..faef877 100644 /* 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 -@@ -72,6 +138,29 @@ static char *field_1_buffer; +@@ -71,6 +137,29 @@ static char *field_1_buffer; /* The number of bytes allocated for FIELD_1_BUFFER. */ static size_t field_1_bufsize; @@ -513,7 +513,7 @@ index 6fd8978..faef877 100644 /* If true do not output lines containing no delimiter characters. Otherwise, all such lines are printed. This option is valid only with field mode. */ -@@ -83,10 +172,16 @@ static bool complement; +@@ -82,10 +171,16 @@ static bool complement; /* The delimiter character for field mode. */ static unsigned char delim; @@ -530,7 +530,7 @@ index 6fd8978..faef877 100644 /* The length of output_delimiter_string. */ static size_t output_delimiter_length; -@@ -94,9 +189,6 @@ static size_t output_delimiter_length; +@@ -93,9 +188,6 @@ static size_t output_delimiter_length; string consisting of the input delimiter. */ static char *output_delimiter_string; @@ -540,7 +540,7 @@ index 6fd8978..faef877 100644 /* True if we have ever read standard input. */ static bool have_read_stdin; -@@ -150,7 +242,7 @@ Print selected parts of lines from each FILE to standard output.\n\ +@@ -149,7 +241,7 @@ Print selected parts of lines from each FILE to standard output.\n\ -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\ @@ -549,7 +549,7 @@ index 6fd8978..faef877 100644 "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -250,7 +342,7 @@ cut_bytes (FILE *stream) +@@ -249,7 +341,7 @@ cut_bytes (FILE *stream) next_item (&byte_idx); if (print_kth (byte_idx)) { @@ -558,7 +558,7 @@ index 6fd8978..faef877 100644 { if (print_delimiter && is_range_start_index (byte_idx)) { -@@ -266,6 +358,82 @@ cut_bytes (FILE *stream) +@@ -265,6 +357,82 @@ cut_bytes (FILE *stream) } } @@ -641,7 +641,7 @@ index 6fd8978..faef877 100644 /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -411,11 +579,218 @@ cut_fields (FILE *stream) +@@ -410,11 +578,218 @@ cut_fields (FILE *stream) } } @@ -862,7 +862,7 @@ index 6fd8978..faef877 100644 { FILE *stream; -@@ -459,8 +834,8 @@ main (int argc, char **argv) +@@ -458,8 +833,8 @@ main (int argc, char **argv) int optc; bool ok; bool delim_specified = false; @@ -873,7 +873,7 @@ index 6fd8978..faef877 100644 initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -470,6 +845,8 @@ main (int argc, char **argv) +@@ -469,6 +844,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -882,7 +882,7 @@ index 6fd8978..faef877 100644 /* By default, all non-delimited lines are printed. */ suppress_non_delimited = false; -@@ -481,35 +858,77 @@ main (int argc, char **argv) +@@ -480,35 +857,77 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -970,7 +970,7 @@ index 6fd8978..faef877 100644 break; case 's': -@@ -533,40 +952,57 @@ main (int argc, char **argv) +@@ -532,40 +951,57 @@ main (int argc, char **argv) } } @@ -2136,7 +2136,7 @@ index f2fd172..6c7d1ed 100644 + if (diff) return diff; -- return len1 < len2 ? -1 : len1 != len2; +- return (len1 > len2) - (len1 < len2); + return len[0] - len[1]; } @@ -2259,7 +2259,7 @@ diff --git a/src/local.mk b/src/local.mk index e1d15ce..1a5ffaa 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -434,8 +434,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -438,8 +438,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -2542,7 +2542,7 @@ index 4c17c00..b4fab1c 100644 if (*arg) { long int tmp_long; -@@ -1191,6 +1310,11 @@ static void +@@ -1198,6 +1317,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -2554,7 +2554,7 @@ index 4c17c00..b4fab1c 100644 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) +@@ -1235,7 +1359,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -2563,7 +2563,7 @@ index 4c17c00..b4fab1c 100644 use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1260,11 +1384,11 @@ init_parameters (int number_of_files) +@@ -1267,11 +1391,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. */ @@ -2577,7 +2577,7 @@ index 4c17c00..b4fab1c 100644 /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1273,7 +1397,7 @@ init_parameters (int number_of_files) +@@ -1280,7 +1404,7 @@ init_parameters (int number_of_files) } int sep_chars, useful_chars; @@ -2586,7 +2586,7 @@ index 4c17c00..b4fab1c 100644 sep_chars = INT_MAX; if (INT_SUBTRACT_WRAPV (chars_per_line - chars_used_by_number, sep_chars, &useful_chars)) -@@ -1296,7 +1420,7 @@ init_parameters (int number_of_files) +@@ -1303,7 +1427,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); @@ -2595,7 +2595,7 @@ index 4c17c00..b4fab1c 100644 } /* Open the necessary files, -@@ -1402,7 +1526,7 @@ init_funcs (void) +@@ -1409,7 +1533,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2604,7 +2604,7 @@ index 4c17c00..b4fab1c 100644 /* This loop takes care of all but the rightmost column. */ -@@ -1436,7 +1560,7 @@ init_funcs (void) +@@ -1443,7 +1567,7 @@ init_funcs (void) } else { @@ -2613,7 +2613,7 @@ index 4c17c00..b4fab1c 100644 h_next = h + chars_per_column; } } -@@ -1733,9 +1857,9 @@ static void +@@ -1740,9 +1864,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2625,7 +2625,7 @@ index 4c17c00..b4fab1c 100644 padding_not_printed = ANYWHERE; } -@@ -2010,13 +2134,13 @@ store_char (char c) +@@ -2017,13 +2141,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2641,7 +2641,7 @@ index 4c17c00..b4fab1c 100644 char *s; int num_width; -@@ -2033,22 +2157,24 @@ add_line_number (COLUMN *p) +@@ -2040,22 +2164,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. */ @@ -2670,7 +2670,7 @@ index 4c17c00..b4fab1c 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2207,7 +2333,7 @@ print_white_space (void) +@@ -2214,7 +2340,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2679,7 +2679,7 @@ index 4c17c00..b4fab1c 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2227,6 +2353,7 @@ print_sep_string (void) +@@ -2234,6 +2360,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -2687,7 +2687,7 @@ index 4c17c00..b4fab1c 100644 if (separators_not_printed <= 0) { -@@ -2238,6 +2365,7 @@ print_sep_string (void) +@@ -2245,6 +2372,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2695,7 +2695,7 @@ index 4c17c00..b4fab1c 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2251,12 +2379,15 @@ print_sep_string (void) +@@ -2258,12 +2386,15 @@ print_sep_string (void) } else { @@ -2712,7 +2712,7 @@ index 4c17c00..b4fab1c 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2284,7 +2415,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2291,7 +2422,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -2721,7 +2721,7 @@ index 4c17c00..b4fab1c 100644 { if (tabify_output) { -@@ -2308,6 +2439,74 @@ print_char (char c) +@@ -2315,6 +2446,74 @@ print_char (char c) putchar (c); } @@ -2796,7 +2796,7 @@ index 4c17c00..b4fab1c 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2485,9 +2684,9 @@ read_line (COLUMN *p) +@@ -2492,9 +2691,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2808,7 +2808,7 @@ index 4c17c00..b4fab1c 100644 padding_not_printed = ANYWHERE; } -@@ -2556,7 +2755,7 @@ print_stored (COLUMN *p) +@@ -2563,7 +2762,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -2817,7 +2817,7 @@ index 4c17c00..b4fab1c 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2568,7 +2767,7 @@ print_stored (COLUMN *p) +@@ -2575,7 +2774,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2826,7 +2826,7 @@ index 4c17c00..b4fab1c 100644 pad_vertically = true; -@@ -2588,9 +2787,9 @@ print_stored (COLUMN *p) +@@ -2595,9 +2794,9 @@ print_stored (COLUMN *p) } } @@ -2838,7 +2838,7 @@ index 4c17c00..b4fab1c 100644 padding_not_printed = ANYWHERE; } -@@ -2603,8 +2802,8 @@ print_stored (COLUMN *p) +@@ -2610,8 +2809,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2849,7 +2849,7 @@ index 4c17c00..b4fab1c 100644 } return true; -@@ -2623,7 +2822,7 @@ print_stored (COLUMN *p) +@@ -2630,7 +2829,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2858,7 +2858,7 @@ index 4c17c00..b4fab1c 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2633,10 +2832,10 @@ char_to_clump (char c) +@@ -2640,10 +2839,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2871,7 +2871,7 @@ index 4c17c00..b4fab1c 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2717,6 +2916,164 @@ char_to_clump (char c) +@@ -2724,6 +2923,164 @@ char_to_clump (char c) return chars; } @@ -3549,7 +3549,7 @@ index 3b775d6..a0ba243 100644 line->keybeg = line_start; } } -@@ -1976,12 +2322,10 @@ find_unit_order (char const *number) +@@ -1978,12 +2324,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3565,7 +3565,7 @@ index 3b775d6..a0ba243 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1993,7 +2337,7 @@ human_numcompare (char const *a, char const *b) +@@ -1995,7 +2339,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3574,7 +3574,7 @@ index 3b775d6..a0ba243 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2003,6 +2347,25 @@ numcompare (char const *a, char const *b) +@@ -2005,6 +2349,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3597,10 +3597,10 @@ index 3b775d6..a0ba243 100644 +} +#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 -@@ -2053,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) + static int + nan_compare (long double a, long double b) + { +@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3609,7 +3609,7 @@ index 3b775d6..a0ba243 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2329,15 +2692,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2322,15 +2685,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3627,7 +3627,7 @@ index 3b775d6..a0ba243 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2483,7 +2845,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2476,7 +2838,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3636,7 +3636,7 @@ index 3b775d6..a0ba243 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2531,9 +2893,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2524,9 +2886,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3649,7 +3649,7 @@ index 3b775d6..a0ba243 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2544,9 +2906,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2537,9 +2899,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3662,7 +3662,7 @@ index 3b775d6..a0ba243 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2554,19 +2916,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2547,19 +2909,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3686,7 +3686,7 @@ index 3b775d6..a0ba243 100644 } } -@@ -2577,7 +2939,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2570,7 +2932,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) { error (0, 0, _("%snumbers use %s as a decimal point in this locale"), @@ -3695,8 +3695,8 @@ index 3b775d6..a0ba243 100644 quote (((char []) {decimal_point, 0}))); } -@@ -2610,11 +2972,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) - error (0, 0, _("option '-r' only applies to last-resort comparison")); +@@ -2612,11 +2974,87 @@ diff_reversed (int diff, bool reversed) + return reversed ? (diff < 0) - (diff > 0) : diff; } +#if HAVE_MBRTOWC @@ -3784,7 +3784,7 @@ index 3b775d6..a0ba243 100644 { struct keyfield *key = keylist; -@@ -2699,7 +3137,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2697,7 +3135,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3793,8 +3793,8 @@ index 3b775d6..a0ba243 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2815,6 +3253,211 @@ keycompare (struct line const *a, struct line const *b) - return key->reverse ? -diff : diff; +@@ -2807,6 +3245,211 @@ keycompare (struct line const *a, struct line const *b) + return diff_reversed (diff, key->reverse); } +#if HAVE_MBRTOWC @@ -4005,7 +4005,7 @@ index 3b775d6..a0ba243 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2842,7 +3485,7 @@ compare (struct line const *a, struct line const *b) +@@ -2834,7 +3477,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -4014,7 +4014,7 @@ index 3b775d6..a0ba243 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4226,6 +4869,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4222,6 +4865,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -4022,7 +4022,7 @@ index 3b775d6..a0ba243 100644 break; case 'g': key->general_numeric = true; -@@ -4305,7 +4949,7 @@ main (int argc, char **argv) +@@ -4301,7 +4945,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4031,7 +4031,7 @@ index 3b775d6..a0ba243 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4328,6 +4972,29 @@ main (int argc, char **argv) +@@ -4324,6 +4968,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4061,7 +4061,7 @@ index 3b775d6..a0ba243 100644 have_read_stdin = false; inittables (); -@@ -4602,13 +5269,34 @@ main (int argc, char **argv) +@@ -4598,13 +5265,34 @@ main (int argc, char **argv) case 't': { @@ -4100,7 +4100,7 @@ index 3b775d6..a0ba243 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4619,9 +5307,11 @@ main (int argc, char **argv) +@@ -4615,9 +5303,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4726,7 +4726,7 @@ diff --git a/tests/local.mk b/tests/local.mk index 0f77786..dbe1843 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -377,6 +377,8 @@ all_tests = \ +@@ -381,6 +381,8 @@ all_tests = \ tests/misc/sort-discrim.sh \ tests/misc/sort-files0-from.pl \ tests/misc/sort-float.sh \ @@ -4735,7 +4735,7 @@ index 0f77786..dbe1843 100644 tests/misc/sort-h-thousands-sep.sh \ tests/misc/sort-merge.pl \ tests/misc/sort-merge-fdlimit.sh \ -@@ -576,6 +578,7 @@ all_tests = \ +@@ -582,6 +584,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4743,7 +4743,7 @@ index 0f77786..dbe1843 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -727,6 +730,7 @@ all_tests = \ +@@ -734,6 +737,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ diff --git a/coreutils-nfsv4-acls.patch b/coreutils-nfsv4-acls.patch deleted file mode 100644 index 7dd036d..0000000 --- a/coreutils-nfsv4-acls.patch +++ /dev/null @@ -1,625 +0,0 @@ -From 5a6af47c3db45b6303bac4dcd6da186fd5cd178c Mon Sep 17 00:00:00 2001 -From: Ondrej Valousek -Date: Fri, 2 Dec 2022 13:40:19 +0100 -Subject: [PATCH 1/3] file-has-acl: Basic support for checking NFSv4 ACLs in - Linux. - -* lib/acl-internal.h (acl_nfs4_nontrivial): New declaration. -* lib/acl-internal.c (acl_nfs4_nontrivial): New function. -* lib/file-has-acl.c: Include . -(XATTR_NAME_NFSV4_ACL, TRIVIAL_NFS4_ACL_MAX_LENGTH): New macros. -(file_has_acl): Test for NFSv4 ACLs. -* doc/acl-nfsv4.txt: New file. - -Upstream-commit: b0604a8e134dbcc307c0ffdd5ebd3693e9de7081 -Signed-off-by: Kamil Dudka ---- - doc/acl-nfsv4.txt | 17 ++++++++ - lib/acl-internal.c | 100 +++++++++++++++++++++++++++++++++++++++++++++ - lib/acl-internal.h | 3 ++ - lib/file-has-acl.c | 21 ++++++++++ - 4 files changed, 141 insertions(+) - create mode 100644 doc/acl-nfsv4.txt - -diff --git a/doc/acl-nfsv4.txt b/doc/acl-nfsv4.txt -new file mode 100644 -index 0000000..71352f5 ---- /dev/null -+++ b/doc/acl-nfsv4.txt -@@ -0,0 +1,17 @@ -+General introduction: -+ https://linux.die.net/man/5/nfs4_acl -+ -+The NFSv4 acls are defined in RFC7530 and as such, every NFSv4 server supporting ACLs -+will support this kind of ACLs (note the difference from POSIX draft ACLs) -+ -+The ACLs can be obtained via the nfsv4-acl-tools, i.e. -+ -+$ nfs4_getfacl -+ -+# file: -+A::OWNER@:rwaDxtTnNcCy -+A::GROUP@:rwaDxtTnNcy -+A::EVERYONE@:rwaDxtTnNcy -+ -+Gnulib is aiming to only provide a basic support of these, i.e. recognize trivial -+and non-trivial ACLs -diff --git a/lib/acl-internal.c b/lib/acl-internal.c -index be244c6..4c65dff 100644 ---- a/lib/acl-internal.c -+++ b/lib/acl-internal.c -@@ -25,6 +25,9 @@ - - #if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ - -+# include -+# include -+ - # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ - - /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. -@@ -122,6 +125,103 @@ acl_default_nontrivial (acl_t acl) - return (acl_entries (acl) > 0); - } - -+# define ACE4_WHO_OWNER "OWNER@" -+# define ACE4_WHO_GROUP "GROUP@" -+# define ACE4_WHO_EVERYONE "EVERYONE@" -+ -+# define ACE4_ACCESS_ALLOWED_ACE_TYPE 0 -+# define ACE4_ACCESS_DENIED_ACE_TYPE 1 -+ -+/* ACE flag values */ -+# define ACE4_IDENTIFIER_GROUP 0x00000040 -+# define ROUNDUP(x, y) (((x) + (y) - 1) & - (y)) -+ -+int -+acl_nfs4_nontrivial (char *xattr, int len) -+{ -+ int bufs = len; -+ uint32_t num_aces = ntohl (*((uint32_t*)(xattr))), /* Grab the number of aces in the acl */ -+ num_a_aces = 0, -+ num_d_aces = 0; -+ char *bufp = xattr; -+ -+ bufp += 4; /* sizeof(uint32_t); */ -+ bufs -= 4; -+ -+ for (uint32_t ace_n = 0; num_aces > ace_n ; ace_n++) -+ { -+ int d_ptr; -+ uint32_t flag, -+ wholen, -+ type; -+ -+ /* Get the acl type */ -+ if (bufs <= 0) -+ return -1; -+ -+ type = ntohl (*((uint32_t*)bufp)); -+ -+ bufp += 4; -+ bufs -= 4; -+ if (bufs <= 0) -+ return -1; -+ -+ flag = ntohl (*((uint32_t*)bufp)); -+ /* As per RFC 7530, the flag should be 0, but we are just generous to Netapp -+ * and also accept the Group flag -+ */ -+ if (flag & ~ACE4_IDENTIFIER_GROUP) -+ return 1; -+ -+ /* we skip mask - -+ * it's too risky to test it and it does not seem to be actually needed */ -+ bufp += 2*4; -+ bufs -= 2*4; -+ -+ if (bufs <= 0) -+ return -1; -+ -+ wholen = ntohl (*((uint32_t*)bufp)); -+ -+ bufp += 4; -+ bufs -= 4; -+ -+ /* Get the who string */ -+ if (bufs <= 0) -+ return -1; -+ -+ /* for trivial ACL, we expect max 5 (typically 3) ACES, 3 Allow, 2 deny */ -+ if (((strncmp (bufp, ACE4_WHO_OWNER, wholen) == 0) -+ || (strncmp (bufp, ACE4_WHO_GROUP, wholen) == 0)) -+ && wholen == 6) -+ { -+ if (type == ACE4_ACCESS_ALLOWED_ACE_TYPE) -+ num_a_aces++; -+ if (type == ACE4_ACCESS_DENIED_ACE_TYPE) -+ num_d_aces++; -+ } -+ else -+ if ((strncmp (bufp, ACE4_WHO_EVERYONE, wholen) == 0) -+ && (type == ACE4_ACCESS_ALLOWED_ACE_TYPE) -+ && (wholen == 9)) -+ num_a_aces++; -+ else -+ return 1; -+ -+ d_ptr = ROUNDUP (wholen, 4); -+ bufp += d_ptr; -+ bufs -= d_ptr; -+ -+ /* Make sure we aren't outside our domain */ -+ if (bufs < 0) -+ return -1; -+ -+ } -+ return !((num_a_aces <= 3) && (num_d_aces <= 2) -+ && (num_a_aces + num_d_aces == num_aces)); -+ -+} -+ - # endif - - #elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */ -diff --git a/lib/acl-internal.h b/lib/acl-internal.h -index 9353376..2a249ff 100644 ---- a/lib/acl-internal.h -+++ b/lib/acl-internal.h -@@ -147,6 +147,9 @@ rpl_acl_set_fd (int fd, acl_t acl) - # define acl_entries rpl_acl_entries - extern int acl_entries (acl_t); - # endif -+/* Return 1 if given ACL in XDR format is non-trivial -+ * Return 0 if it is trivial */ -+extern int acl_nfs4_nontrivial (char *, int); - - # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ - /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. -diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c -index e02f062..1710234 100644 ---- a/lib/file-has-acl.c -+++ b/lib/file-has-acl.c -@@ -32,6 +32,11 @@ - #if GETXATTR_WITH_POSIX_ACLS - # include - # include -+# include -+# ifndef XATTR_NAME_NFSV4_ACL -+# define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" -+# endif -+# define TRIVIAL_NFS4_ACL_MAX_LENGTH 128 - #endif - - /* Return 1 if NAME has a nontrivial access control list, -@@ -67,6 +72,22 @@ file_has_acl (char const *name, struct stat const *sb) - return 1; - } - -+ if (ret < 0) -+ { /* we might be on NFS, so try to check NFSv4 ACLs too */ -+ char xattr[TRIVIAL_NFS4_ACL_MAX_LENGTH]; -+ -+ errno = 0; /* we need to reset errno set by the previous getxattr() */ -+ ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, TRIVIAL_NFS4_ACL_MAX_LENGTH); -+ if (ret < 0 && errno == ENODATA) -+ ret = 0; -+ else -+ if (ret < 0 && errno == ERANGE) -+ return 1; /* we won't fit into the buffer, so non-trivial ACL is presented */ -+ else -+ if (ret > 0) -+ /* looks like trivial ACL, but we need to investigate further */ -+ return acl_nfs4_nontrivial (xattr, ret); -+ } - if (ret < 0) - return - acl_errno_valid (errno); - return ret; --- -2.38.1 - - -From c5266d204a446bea619fa18da8520dceb0a54192 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Fri, 23 Dec 2022 15:18:29 -0800 -Subject: [PATCH 2/3] file-has-acl: improve recent NFSv4 support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes a link failure with emacsclient on GNU/Linux. This -program wants file_has_acl but none of the other ACL primitives, -so it doesn’t link acl-internal.o; this way it doesn’t need to -link with -lacl. While I was at it I reviewed the recent changes, -fixed some unlikely overflow bugs, and adjusted to GNU style. -* doc/acl-nfsv4.txt: Remove. Its contents are now in a -comment in lib/file-has-acl.c. -* lib/acl-internal.c, lib/acl-internal.h: Move recent changes -relating to acl_nfs4_nontrivial to lib/file-has-acl.c, so that -there is no trouble linking programs that need only file_has_acl. -* lib/file-has-acl.c (acl_nfs4_nontrivial): Move here from -lib/acl-internal.c, so that we needn't link -lacl in -programs that want only file_has_acl, such as emacsclient. -Do not assume a char buffer is aligned for uint32_t. -Check more carefully for buffer read overrun. -Allow up to 6 ACEs, since other code does; but check -that they’re distinct. Avoid integer overflow. -Use memcmp rather than strncmp to compare memory blocks. -(file_has_acl): Preserve initial errno instead of setting to 0. -Allocate a bit more room for trivial ACL buffer. -Use EINVAL for botchedk NFSv4 ACLs (which shouldn’t happen). - -Upstream-commit: 35bd46f0c816948dc1a0430c8ba8b10a01167320 -Signed-off-by: Kamil Dudka ---- - doc/acl-nfsv4.txt | 17 ------ - lib/acl-internal.c | 100 ----------------------------------- - lib/acl-internal.h | 3 -- - lib/file-has-acl.c | 129 +++++++++++++++++++++++++++++++++++++++------ - 4 files changed, 113 insertions(+), 136 deletions(-) - delete mode 100644 doc/acl-nfsv4.txt - -diff --git a/doc/acl-nfsv4.txt b/doc/acl-nfsv4.txt -deleted file mode 100644 -index 71352f5..0000000 ---- a/doc/acl-nfsv4.txt -+++ /dev/null -@@ -1,17 +0,0 @@ --General introduction: -- https://linux.die.net/man/5/nfs4_acl -- --The NFSv4 acls are defined in RFC7530 and as such, every NFSv4 server supporting ACLs --will support this kind of ACLs (note the difference from POSIX draft ACLs) -- --The ACLs can be obtained via the nfsv4-acl-tools, i.e. -- --$ nfs4_getfacl -- --# file: --A::OWNER@:rwaDxtTnNcCy --A::GROUP@:rwaDxtTnNcy --A::EVERYONE@:rwaDxtTnNcy -- --Gnulib is aiming to only provide a basic support of these, i.e. recognize trivial --and non-trivial ACLs -diff --git a/lib/acl-internal.c b/lib/acl-internal.c -index 4c65dff..be244c6 100644 ---- a/lib/acl-internal.c -+++ b/lib/acl-internal.c -@@ -25,9 +25,6 @@ - - #if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ - --# include --# include -- - # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ - - /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. -@@ -125,103 +122,6 @@ acl_default_nontrivial (acl_t acl) - return (acl_entries (acl) > 0); - } - --# define ACE4_WHO_OWNER "OWNER@" --# define ACE4_WHO_GROUP "GROUP@" --# define ACE4_WHO_EVERYONE "EVERYONE@" -- --# define ACE4_ACCESS_ALLOWED_ACE_TYPE 0 --# define ACE4_ACCESS_DENIED_ACE_TYPE 1 -- --/* ACE flag values */ --# define ACE4_IDENTIFIER_GROUP 0x00000040 --# define ROUNDUP(x, y) (((x) + (y) - 1) & - (y)) -- --int --acl_nfs4_nontrivial (char *xattr, int len) --{ -- int bufs = len; -- uint32_t num_aces = ntohl (*((uint32_t*)(xattr))), /* Grab the number of aces in the acl */ -- num_a_aces = 0, -- num_d_aces = 0; -- char *bufp = xattr; -- -- bufp += 4; /* sizeof(uint32_t); */ -- bufs -= 4; -- -- for (uint32_t ace_n = 0; num_aces > ace_n ; ace_n++) -- { -- int d_ptr; -- uint32_t flag, -- wholen, -- type; -- -- /* Get the acl type */ -- if (bufs <= 0) -- return -1; -- -- type = ntohl (*((uint32_t*)bufp)); -- -- bufp += 4; -- bufs -= 4; -- if (bufs <= 0) -- return -1; -- -- flag = ntohl (*((uint32_t*)bufp)); -- /* As per RFC 7530, the flag should be 0, but we are just generous to Netapp -- * and also accept the Group flag -- */ -- if (flag & ~ACE4_IDENTIFIER_GROUP) -- return 1; -- -- /* we skip mask - -- * it's too risky to test it and it does not seem to be actually needed */ -- bufp += 2*4; -- bufs -= 2*4; -- -- if (bufs <= 0) -- return -1; -- -- wholen = ntohl (*((uint32_t*)bufp)); -- -- bufp += 4; -- bufs -= 4; -- -- /* Get the who string */ -- if (bufs <= 0) -- return -1; -- -- /* for trivial ACL, we expect max 5 (typically 3) ACES, 3 Allow, 2 deny */ -- if (((strncmp (bufp, ACE4_WHO_OWNER, wholen) == 0) -- || (strncmp (bufp, ACE4_WHO_GROUP, wholen) == 0)) -- && wholen == 6) -- { -- if (type == ACE4_ACCESS_ALLOWED_ACE_TYPE) -- num_a_aces++; -- if (type == ACE4_ACCESS_DENIED_ACE_TYPE) -- num_d_aces++; -- } -- else -- if ((strncmp (bufp, ACE4_WHO_EVERYONE, wholen) == 0) -- && (type == ACE4_ACCESS_ALLOWED_ACE_TYPE) -- && (wholen == 9)) -- num_a_aces++; -- else -- return 1; -- -- d_ptr = ROUNDUP (wholen, 4); -- bufp += d_ptr; -- bufs -= d_ptr; -- -- /* Make sure we aren't outside our domain */ -- if (bufs < 0) -- return -1; -- -- } -- return !((num_a_aces <= 3) && (num_d_aces <= 2) -- && (num_a_aces + num_d_aces == num_aces)); -- --} -- - # endif - - #elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */ -diff --git a/lib/acl-internal.h b/lib/acl-internal.h -index 2a249ff..9353376 100644 ---- a/lib/acl-internal.h -+++ b/lib/acl-internal.h -@@ -147,9 +147,6 @@ rpl_acl_set_fd (int fd, acl_t acl) - # define acl_entries rpl_acl_entries - extern int acl_entries (acl_t); - # endif --/* Return 1 if given ACL in XDR format is non-trivial -- * Return 0 if it is trivial */ --extern int acl_nfs4_nontrivial (char *, int); - - # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ - /* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. -diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c -index 1710234..676523b 100644 ---- a/lib/file-has-acl.c -+++ b/lib/file-has-acl.c -@@ -29,14 +29,97 @@ - - #include "acl-internal.h" - --#if GETXATTR_WITH_POSIX_ACLS -+#if USE_ACL && GETXATTR_WITH_POSIX_ACLS -+# include -+# include - # include - # include --# include - # ifndef XATTR_NAME_NFSV4_ACL - # define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" - # endif --# define TRIVIAL_NFS4_ACL_MAX_LENGTH 128 -+ -+enum { -+ /* ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000, */ -+ ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001, -+ ACE4_IDENTIFIER_GROUP = 0x00000040 -+}; -+ -+/* Return 1 if given ACL in XDR format is non-trivial, 0 if it is trivial. -+ -1 upon failure to determine it. Possibly change errno. Assume that -+ the ACL is valid, except avoid undefined behavior even if invalid. -+ -+ See . The NFSv4 acls are -+ defined in Internet RFC 7530 and as such, every NFSv4 server -+ supporting ACLs should support NFSv4 ACLs (they differ from from -+ POSIX draft ACLs). The ACLs can be obtained via the -+ nfsv4-acl-tools, e.g., the nfs4_getfacl command. Gnulib provides -+ only basic support of NFSv4 ACLs, i.e., recognize trivial vs -+ nontrivial ACLs. */ -+ -+static int -+acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) -+{ -+ enum { BYTES_PER_NETWORK_UINT = 4}; -+ -+ /* Grab the number of aces in the acl. */ -+ nbytes -= BYTES_PER_NETWORK_UINT; -+ if (nbytes < 0) -+ return -1; -+ uint32_t num_aces = ntohl (*xattr++); -+ if (6 < num_aces) -+ return 1; -+ int ace_found = 0; -+ -+ for (int ace_n = 0; ace_n < num_aces; ace_n++) -+ { -+ /* Get the acl type and flag. Skip the mask; it's too risky to -+ test it and it does not seem to be needed. Get the wholen. */ -+ nbytes -= 4 * BYTES_PER_NETWORK_UINT; -+ if (nbytes < 0) -+ return -1; -+ uint32_t type = ntohl (xattr[0]); -+ uint32_t flag = ntohl (xattr[1]); -+ uint32_t wholen = ntohl (xattr[3]); -+ xattr += 4; -+ int64_t wholen4 = wholen; -+ wholen4 = ((wholen4 + (BYTES_PER_NETWORK_UINT)) -+ & ~ (BYTES_PER_NETWORK_UINT - 1)); -+ -+ /* Trivial ACLs have only ACE4_ACCESS_ALLOWED_ACE_TYPE or -+ ACE4_ACCESS_DENIED_ACE_TYPE. */ -+ if (ACE4_ACCESS_DENIED_ACE_TYPE < type) -+ return 1; -+ -+ /* RFC 7530 says FLAG should be 0, but be generous to NetApp and -+ also accept the group flag. */ -+ if (flag & ~ACE4_IDENTIFIER_GROUP) -+ return 1; -+ -+ /* Get the who string. Check NBYTES - WHOLEN4 before storing -+ into NBYTES, to avoid truncation on conversion. */ -+ if (nbytes - wholen4 < 0) -+ return -1; -+ nbytes -= wholen4; -+ -+ /* For a trivial ACL, max 6 (typically 3) ACEs, 3 allow, 3 deny. -+ Check that there is at most one ACE of each TYPE and WHO. */ -+ int who2 -+ = (wholen == 6 && memcmp (xattr, "OWNER@", 6) == 0 ? 0 -+ : wholen == 6 && memcmp (xattr, "GROUP@", 6) == 0 ? 2 -+ : wholen == 9 && memcmp (xattr, "EVERYONE@", 9) == 0 ? 4 -+ : -1); -+ if (who2 < 0) -+ return 1; -+ int ace_found_bit = 1 << (who2 | type); -+ if (ace_found & ace_found_bit) -+ return 1; -+ ace_found |= ace_found_bit; -+ -+ xattr = (uint32_t *) ((char *) xattr + wholen4); -+ } -+ -+ return 0; -+} - #endif - - /* Return 1 if NAME has a nontrivial access control list, -@@ -56,6 +139,7 @@ file_has_acl (char const *name, struct stat const *sb) - # if GETXATTR_WITH_POSIX_ACLS - - ssize_t ret; -+ int initial_errno = errno; - - ret = getxattr (name, XATTR_NAME_POSIX_ACL_ACCESS, NULL, 0); - if (ret < 0 && errno == ENODATA) -@@ -73,20 +157,33 @@ file_has_acl (char const *name, struct stat const *sb) - } - - if (ret < 0) -- { /* we might be on NFS, so try to check NFSv4 ACLs too */ -- char xattr[TRIVIAL_NFS4_ACL_MAX_LENGTH]; -- -- errno = 0; /* we need to reset errno set by the previous getxattr() */ -- ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, TRIVIAL_NFS4_ACL_MAX_LENGTH); -- if (ret < 0 && errno == ENODATA) -- ret = 0; -+ { -+ /* Check for NFSv4 ACLs. The max length of a trivial -+ ACL is 6 words for owner, 6 for group, 7 for everyone, -+ all times 2 because there are both allow and deny ACEs. -+ There are 6 words for owner because of type, flag, mask, -+ wholen, "OWNER@"+pad and similarly for group; everyone is -+ another word to hold "EVERYONE@". */ -+ uint32_t xattr[2 * (6 + 6 + 7)]; -+ -+ ret = getxattr (name, XATTR_NAME_NFSV4_ACL, xattr, sizeof xattr); -+ if (ret < 0) -+ switch (errno) -+ { -+ case ENODATA: return 0; -+ case ERANGE : return 1; /* ACL must be nontrivial. */ -+ } - else -- if (ret < 0 && errno == ERANGE) -- return 1; /* we won't fit into the buffer, so non-trivial ACL is presented */ -- else -- if (ret > 0) -- /* looks like trivial ACL, but we need to investigate further */ -- return acl_nfs4_nontrivial (xattr, ret); -+ { -+ /* It looks like a trivial ACL, but investigate further. */ -+ ret = acl_nfs4_nontrivial (xattr, ret); -+ if (ret < 0) -+ { -+ errno = EINVAL; -+ return ret; -+ } -+ errno = initial_errno; -+ } - } - if (ret < 0) - return - acl_errno_valid (errno); --- -2.38.1 - - -From faf965110372c82cd99e9f44f0c64f03cdabb2c1 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Tue, 27 Dec 2022 20:00:58 -0800 -Subject: [PATCH 3/3] file-has-acl: fix recently-introduced NFSv4 bug - -* lib/file-has-acl.c (acl_nfs4_nontrivial): Fix off-by-one -error when rounding WHOLEN up to next multiple of 4. -Pacify GCC 12.2.1 -Wcast-align. - -Upstream-commit: d65e5a8ba77595a598c9ddb8dfa09c4aea732659 -Signed-off-by: Kamil Dudka ---- - lib/file-has-acl.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c -index 676523b..7876edc 100644 ---- a/lib/file-has-acl.c -+++ b/lib/file-has-acl.c -@@ -81,9 +81,10 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) - uint32_t flag = ntohl (xattr[1]); - uint32_t wholen = ntohl (xattr[3]); - xattr += 4; -- int64_t wholen4 = wholen; -- wholen4 = ((wholen4 + (BYTES_PER_NETWORK_UINT)) -- & ~ (BYTES_PER_NETWORK_UINT - 1)); -+ int whowords = (wholen / BYTES_PER_NETWORK_UINT -+ + (wholen % BYTES_PER_NETWORK_UINT != 0)); -+ int64_t wholen4 = whowords; -+ wholen4 *= BYTES_PER_NETWORK_UINT; - - /* Trivial ACLs have only ACE4_ACCESS_ALLOWED_ACE_TYPE or - ACE4_ACCESS_DENIED_ACE_TYPE. */ -@@ -115,7 +116,7 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) - return 1; - ace_found |= ace_found_bit; - -- xattr = (uint32_t *) ((char *) xattr + wholen4); -+ xattr += whowords; - } - - return 0; --- -2.38.1 - diff --git a/coreutils.spec b/coreutils.spec index 8c4a6b1..2c75907 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.1 -Release: 11%{?dist} +Version: 9.2 +Release: 1%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -17,12 +17,6 @@ Source106: coreutils-colorls.csh # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ -# Make simple backups in correct dir; broken in 9.1 -Patch1: gnulib-simple-backup-fix.patch - -# basic support for checking NFSv4 ACLs (#2137866) -Patch2: coreutils-nfsv4-acls.patch - # disable the test-lock gnulib test prone to deadlock Patch100: coreutils-8.26-test-lock.patch @@ -261,6 +255,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Mar 22 2023 Kamil Dudka - 9.2-1 +- new upstream release 9.2 + * Thu Jan 19 2023 Fedora Release Engineering - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild diff --git a/gnulib-simple-backup-fix.patch b/gnulib-simple-backup-fix.patch deleted file mode 100644 index 9c2d8a7..0000000 --- a/gnulib-simple-backup-fix.patch +++ /dev/null @@ -1,36 +0,0 @@ -commit 7347caeb9d902d3fca2c11f69a55a3e578d93bfe -Author: Paul Eggert -Date: Wed Apr 20 19:34:57 2022 -0700 - - backupfile: fix bug when renaming simple backups - - * lib/backupfile.c (backupfile_internal): Fix bug when RENAME - and when doing simple backups. Problem reported by Steve Ward in: - https://bugs.gnu.org/55029 - -diff --git a/lib/backupfile.c b/lib/backupfile.c -index 1e9290a187..d9f465a3e0 100644 ---- a/lib/backupfile.c -+++ b/lib/backupfile.c -@@ -332,7 +332,7 @@ backupfile_internal (int dir_fd, char const *file, - return s; - - DIR *dirp = NULL; -- int sdir = AT_FDCWD; -+ int sdir = dir_fd; - idx_t base_max = 0; - while (true) - { -@@ -371,10 +371,9 @@ backupfile_internal (int dir_fd, char const *file, - if (! rename) - break; - -- int olddirfd = sdir < 0 ? dir_fd : sdir; -- idx_t offset = sdir < 0 ? 0 : base_offset; -+ idx_t offset = backup_type == simple_backups ? 0 : base_offset; - unsigned flags = backup_type == simple_backups ? 0 : RENAME_NOREPLACE; -- if (renameatu (olddirfd, file + offset, sdir, s + offset, flags) == 0) -+ if (renameatu (sdir, file + offset, sdir, s + offset, flags) == 0) - break; - int e = errno; - if (! (e == EEXIST && extended)) diff --git a/sources b/sources index 1ff9c2a..5d14ac2 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.1.tar.xz.sig) = 9f0766531afd4faa3e2c337730f61db55605cf06729e9c61f644594883732c2e0b1ddb0005b492be309c53e6f45b8ff875398163a48699d52517ea49e9bdbc91 -SHA512 (coreutils-9.1.tar.xz) = a6ee2c549140b189e8c1b35e119d4289ec27244ec0ed9da0ac55202f365a7e33778b1dc7c4e64d1669599ff81a8297fe4f5adbcc8a3a2f75c919a43cd4b9bdfa +SHA512 (coreutils-9.2.tar.xz) = 7e3108fefba4ef995cc73c64ac5f4e09827a44649a97ddd624eb61d67ce82da5ed6dc8c0f79d3e269f5cdb7d43877a61ef5b93194dd905bec432a7e31f9f479c +SHA512 (coreutils-9.2.tar.xz.sig) = 4219f3103d829841a11bf1fe42ae277a44347e555fbbaf48e5e87cce48deb96753cb6d25f2571b88685a164acb9f016ff7ea02346b799ce954599fa0124ef070 From 2c4d4b8151509aebd3310ead985fb90bd4765a1a Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 22 Mar 2023 12:51:59 +0100 Subject: [PATCH 480/523] coreutils-getgrouplist.patch: drop a patch no longer needed This patch was obseleted by te following upstream commit back in 2008: https://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=v6.10-79-g49f7ebaac45 --- coreutils-getgrouplist.patch | 94 ------------------------------------ coreutils.spec | 8 +-- 2 files changed, 4 insertions(+), 98 deletions(-) delete mode 100644 coreutils-getgrouplist.patch diff --git a/coreutils-getgrouplist.patch b/coreutils-getgrouplist.patch deleted file mode 100644 index 93eef67..0000000 --- a/coreutils-getgrouplist.patch +++ /dev/null @@ -1,94 +0,0 @@ -diff --git a/lib/getugroups.c b/lib/getugroups.c -index 299bae6..8ece29b 100644 ---- a/lib/getugroups.c -+++ b/lib/getugroups.c -@@ -19,6 +19,9 @@ - - #include - -+/* We do not need this code if getgrouplist(3) is available. */ -+#ifndef HAVE_GETGROUPLIST -+ - #include "getugroups.h" - - #include -@@ -126,3 +129,4 @@ getugroups (int maxcount, gid_t *grouplist, char const *username, - } - - #endif /* HAVE_GRP_H */ -+#endif /* have getgrouplist */ -diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c -index 76474c2..0a9d221 100644 ---- a/lib/mgetgroups.c -+++ b/lib/mgetgroups.c -@@ -31,6 +31,7 @@ - #endif - - #include "getugroups.h" -+#include "xalloc.h" - #include "xalloc-oversized.h" - - /* Work around an incompatibility of OS X 10.11: getgrouplist -@@ -119,9 +120,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) - /* else no username, so fall through and use getgroups. */ - #endif - -- max_n_groups = (username -- ? getugroups (0, NULL, username, gid) -- : getgroups (0, NULL)); -+ if (!username) -+ max_n_groups = getgroups(0, NULL); -+ else -+ { -+#ifdef HAVE_GETGROUPLIST -+ max_n_groups = 0; -+ getgrouplist (username, gid, NULL, &max_n_groups); -+#else -+ max_n_groups = getugroups (0, NULL, username, gid); -+#endif -+ } - - /* If we failed to count groups because there is no supplemental - group support, then return an array containing just GID. -@@ -143,10 +152,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) - if (g == NULL) - return -1; - -- ng = (username -- ? getugroups (max_n_groups, g, username, gid) -- : getgroups (max_n_groups - (gid != (gid_t) -1), -- g + (gid != (gid_t) -1))); -+ if (!username) -+ ng = getgroups (max_n_groups - (gid != (gid_t)-1), g + (gid != (gid_t)-1)); -+ else -+ { -+#ifdef HAVE_GETGROUPLIST -+ int e; -+ ng = max_n_groups; -+ while ((e = getgrouplist (username, gid, g, &ng)) == -1 -+ && ng > max_n_groups) -+ { -+ max_n_groups = ng; -+ g = xrealloc (g, max_n_groups * sizeof (GETGROUPS_T)); -+ } -+ if (e == -1) -+ ng = -1; -+#else -+ ng = getugroups (max_n_groups, g, username, gid); -+#endif -+ } - - if (ng < 0) - { -diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 -index 62777c7..5180243 100644 ---- a/m4/jm-macros.m4 -+++ b/m4/jm-macros.m4 -@@ -68,6 +68,7 @@ AC_DEFUN([coreutils_MACROS], - fchown - fchmod - ftruncate -+ getgrouplist - iswspace - mkfifo - mbrlen diff --git a/coreutils.spec b/coreutils.spec index 2c75907..2ac8b3c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.2 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -32,9 +32,6 @@ Patch104: coreutils-df-direct.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch -# getgrouplist() patch from Ulrich Drepper. -Patch908: coreutils-getgrouplist.patch - # downstream SELinux options deprecated since 2009 Patch950: coreutils-selinux.patch @@ -255,6 +252,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Mar 22 2023 Kamil Dudka - 9.2-2 +- coreutils-getgrouplist.patch: drop a patch no longer needed + * Wed Mar 22 2023 Kamil Dudka - 9.2-1 - new upstream release 9.2 From 24c306d28da62467b3354d7794f729bd6f9a702c Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 24 Mar 2023 16:17:40 +0100 Subject: [PATCH 481/523] Related: #2180056 - cksum: fix reporting of failed checks --- coreutils-9.2-cksum-check.patch | 67 +++++++++++++++++++++++++++++++++ coreutils.spec | 8 +++- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.2-cksum-check.patch diff --git a/coreutils-9.2-cksum-check.patch b/coreutils-9.2-cksum-check.patch new file mode 100644 index 0000000..362bf2e --- /dev/null +++ b/coreutils-9.2-cksum-check.patch @@ -0,0 +1,67 @@ +From b9fa05c7f08581b175d87b94fb751643dda53187 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Thu, 23 Mar 2023 12:31:24 +0000 +Subject: [PATCH] cksum: fix reporting of failed checks + +This applies to all checksumming utilities, +where we incorrectly report all subsequent files as checking 'OK' +once any file has passed a digest check. +The exit status was not impacted, only the printed status. + +* src/digest.c (digest_check): Use the correct state variable +to determine if the _current_ file has passed or not. +* tests/misc/md5sum.pl: Add a test case. +Fixes https://bugs.gnu.org/62403 + +Upstream-commit: 76f2fb627118a26c25003dbd98c22c153b7ee1d2 +Signed-off-by: Kamil Dudka +--- + src/digest.c | 4 ++-- + tests/misc/md5sum.pl | 10 ++++++++++ + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/digest.c b/src/digest.c +index 6ee8a48..ab32968 100644 +--- a/src/digest.c ++++ b/src/digest.c +@@ -1254,14 +1254,14 @@ digest_check (char const *checkfile_name) + + if (!status_only) + { +- if ( ! matched_checksums || ! quiet) ++ if (! match || ! quiet) + { + if (needs_escape) + putchar ('\\'); + print_filename (filename, needs_escape); + } + +- if ( ! matched_checksums) ++ if (! match) + printf (": %s\n", _("FAILED")); + else if (!quiet) + printf (": %s\n", _("OK")); +diff --git a/tests/misc/md5sum.pl b/tests/misc/md5sum.pl +index 186aca9..d712664 100755 +--- a/tests/misc/md5sum.pl ++++ b/tests/misc/md5sum.pl +@@ -101,6 +101,16 @@ my @Tests = + . "md5sum: WARNING: 1 line is improperly formatted\n" + . "md5sum: WARNING: 2 computed checksums did NOT match\n"}, + {EXIT=> 1}], ++ # Ensure we use appropriate state to track failures (broken in 9.2) ++ ['check-multifail-state', '--check', '--warn', ++ {IN=>{'f.md5' => ++ "$degenerate f\n" ++ . "$degenerate g\n" ++ . "$degenerate f\n" }}, ++ {AUX=> {f=> ''}}, {AUX=> {g=> 'a'}}, ++ {OUT=>"f: OK\ng: FAILED\nf: OK\n"}, ++ {ERR=>"md5sum: WARNING: 1 computed checksum did NOT match\n"}, ++ {EXIT=> 1}], + # The sha1sum and md5sum drivers share a lot of code. + # Ensure that md5sum does *not* share the part that makes + # sha1sum accept BSD format. +-- +2.39.2 + diff --git a/coreutils.spec b/coreutils.spec index 2ac8b3c..4f25986 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.2 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv3+ Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -14,6 +14,9 @@ Source51: coreutils-provides.inc Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh +# cksum: fix reporting of failed checks (#2180056) +Patch1: coreutils-9.2-cksum-check.patch + # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ @@ -252,6 +255,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Mar 24 2023 Kamil Dudka - 9.2-3 +- cksum: fix reporting of failed checks (#2180056) + * Wed Mar 22 2023 Kamil Dudka - 9.2-2 - coreutils-getgrouplist.patch: drop a patch no longer needed From cce55f8f567e33e8c327621cea3b9a354c032939 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 24 Mar 2023 16:19:48 +0100 Subject: [PATCH 482/523] Related: #2180056 - copy: fix --reflink=auto to fallback in more cases --- coreutils-9.2-cp-reflink.patch | 137 +++++++++++++++++++++++++++++++++ coreutils.spec | 4 + 2 files changed, 141 insertions(+) create mode 100644 coreutils-9.2-cp-reflink.patch diff --git a/coreutils-9.2-cp-reflink.patch b/coreutils-9.2-cp-reflink.patch new file mode 100644 index 0000000..34718a7 --- /dev/null +++ b/coreutils-9.2-cp-reflink.patch @@ -0,0 +1,137 @@ +From af99eb5e5e89b67ecdc582d4face2a4614d5cda8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Thu, 23 Mar 2023 13:19:04 +0000 +Subject: [PATCH] copy: fix --reflink=auto to fallback in more cases + +On restricted systems like android or some containers, +FICLONE could return EPERM, EACCES, or ENOTTY, +which would have induced the command to fail to copy +rather than falling back to a more standard copy. + +* src/copy.c (is_terminal_failure): A new function refactored +from handle_clone_fail(). +(is_CLONENOTSUP): Merge in the handling of EACCES, ENOTTY, EPERM +as they also pertain to determination of whether cloning is supported +if we ever use this function in that context. +(handle_clone_fail): Use is_terminal_failure() in all cases, +so that we assume a terminal failure in less errno cases. +Addresses https://bugs.gnu.org/62404 + +Upstream-commit: 093a8b4bfaba60005f14493ce7ef11ed665a0176 +Signed-off-by: Kamil Dudka +--- + src/copy.c | 62 ++++++++++++++++++++++++++++++------------------------ + 1 file changed, 35 insertions(+), 27 deletions(-) + +diff --git a/src/copy.c b/src/copy.c +index 3919787..f8ba058 100644 +--- a/src/copy.c ++++ b/src/copy.c +@@ -278,15 +278,27 @@ create_hole (int fd, char const *name, bool punch_holes, off_t size) + } + + +-/* Whether the errno from FICLONE, or copy_file_range +- indicates operation is not supported for this file or file system. */ ++/* Whether the errno indicates the operation is a transient failure. ++ I.e., a failure that would indicate the operation _is_ supported, ++ but has failed in a terminal way. */ ++ ++static bool ++is_terminal_error (int err) ++{ ++ return err == EIO || err == ENOMEM || err == ENOSPC || err == EDQUOT; ++} ++ ++ ++/* Whether the errno from FICLONE, or copy_file_range indicates ++ the operation is not supported/allowed for this file or process. */ + + static bool + is_CLONENOTSUP (int err) + { +- return err == ENOSYS || is_ENOTSUP (err) ++ return err == ENOSYS || err == ENOTTY || is_ENOTSUP (err) + || err == EINVAL || err == EBADF +- || err == EXDEV || err == ETXTBSY; ++ || err == EXDEV || err == ETXTBSY ++ || err == EPERM || err == EACCES; + } + + +@@ -339,20 +351,18 @@ sparse_copy (int src_fd, int dest_fd, char **abuf, size_t buf_size, + { + copy_debug.offload = COPY_DEBUG_UNSUPPORTED; + +- if (is_CLONENOTSUP (errno)) +- break; +- +- /* copy_file_range might not be enabled in seccomp filters, +- so retry with a standard copy. EPERM can also occur +- for immutable files, but that would only be in the edge case +- where the file is made immutable after creating/truncating, ++ /* Consider operation unsupported only if no data copied. ++ For example, EPERM could occur if copy_file_range not enabled ++ in seccomp filters, so retry with a standard copy. EPERM can ++ also occur for immutable files, but that would only be in the ++ edge case where the file is made immutable after creating, + in which case the (more accurate) error is still shown. */ +- if (errno == EPERM && *total_n_read == 0) ++ if (*total_n_read == 0 && is_CLONENOTSUP (errno)) + break; + + /* ENOENT was seen sometimes across CIFS shares, resulting in + no data being copied, but subsequent standard copies succeed. */ +- if (errno == ENOENT && *total_n_read == 0) ++ if (*total_n_read == 0 && errno == ENOENT) + break; + + if (errno == EINTR) +@@ -1172,17 +1182,15 @@ handle_clone_fail (int dst_dirfd, char const* dst_relname, + char const* src_name, char const* dst_name, + int dest_desc, bool new_dst, enum Reflink_type reflink_mode) + { +- /* If the clone operation is creating the destination, +- then don't try and cater for all non transient file system errors, +- and instead only cater for specific transient errors. */ +- bool transient_failure; +- if (dest_desc < 0) /* currently for fclonefileat(). */ +- transient_failure = errno == EIO || errno == ENOMEM +- || errno == ENOSPC || errno == EDQUOT; +- else /* currently for FICLONE. */ +- transient_failure = ! is_CLONENOTSUP (errno); +- +- if (reflink_mode == REFLINK_ALWAYS || transient_failure) ++ /* When the clone operation fails, report failure only with errno values ++ known to mean trouble when the clone is supported and called properly. ++ Do not report failure merely because !is_CLONENOTSUP (errno), ++ as systems may yield oddball errno values here with FICLONE. ++ Also is_CLONENOTSUP() is not appropriate for the range of errnos ++ possible from fclonefileat(), so it's more consistent to avoid. */ ++ bool report_failure = is_terminal_error (errno); ++ ++ if (reflink_mode == REFLINK_ALWAYS || report_failure) + error (0, errno, _("failed to clone %s from %s"), + quoteaf_n (0, dst_name), quoteaf_n (1, src_name)); + +@@ -1190,14 +1198,14 @@ handle_clone_fail (int dst_dirfd, char const* dst_relname, + but cloned no data. */ + if (new_dst /* currently not for fclonefileat(). */ + && reflink_mode == REFLINK_ALWAYS +- && ((! transient_failure) || lseek (dest_desc, 0, SEEK_END) == 0) ++ && ((! report_failure) || lseek (dest_desc, 0, SEEK_END) == 0) + && unlinkat (dst_dirfd, dst_relname, 0) != 0 && errno != ENOENT) + error (0, errno, _("cannot remove %s"), quoteaf (dst_name)); + +- if (! transient_failure) ++ if (! report_failure) + copy_debug.reflink = COPY_DEBUG_UNSUPPORTED; + +- if (reflink_mode == REFLINK_ALWAYS || transient_failure) ++ if (reflink_mode == REFLINK_ALWAYS || report_failure) + return false; + + return true; +-- +2.39.2 + diff --git a/coreutils.spec b/coreutils.spec index 4f25986..acd9614 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -17,6 +17,9 @@ Source106: coreutils-colorls.csh # cksum: fix reporting of failed checks (#2180056) Patch1: coreutils-9.2-cksum-check.patch +# copy: fix --reflink=auto to fallback in more cases (#2180056) +Patch2: coreutils-9.2-cp-reflink.patch + # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ @@ -256,6 +259,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Fri Mar 24 2023 Kamil Dudka - 9.2-3 +- copy: fix --reflink=auto to fallback in more cases (#2180056) - cksum: fix reporting of failed checks (#2180056) * Wed Mar 22 2023 Kamil Dudka - 9.2-2 From 6bd7dce39db7f9b9a67621db90044569a77c24c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 11 Apr 2023 14:03:27 +0200 Subject: [PATCH 483/523] migrate to SPDX license format --- coreutils.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index acd9614..c634298 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,8 +1,8 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.2 -Release: 3%{?dist} -License: GPLv3+ +Release: 4%{?dist} +License: GPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source1: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig @@ -258,6 +258,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Apr 11 2023 Lukáš Zaoral - 9.2-4 +- migrate to SPDX license format + * Fri Mar 24 2023 Kamil Dudka - 9.2-3 - copy: fix --reflink=auto to fallback in more cases (#2180056) - cksum: fix reporting of failed checks (#2180056) From f33a14f44f9bdc6f069196b4864ddeea8705fc8d Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 18 Apr 2023 17:26:14 +0200 Subject: [PATCH 484/523] new upstream release 9.3 --- coreutils-9.2-cksum-check.patch | 67 ---------------- coreutils-9.2-cp-reflink.patch | 137 -------------------------------- coreutils.spec | 13 ++- sources | 4 +- 4 files changed, 7 insertions(+), 214 deletions(-) delete mode 100644 coreutils-9.2-cksum-check.patch delete mode 100644 coreutils-9.2-cp-reflink.patch diff --git a/coreutils-9.2-cksum-check.patch b/coreutils-9.2-cksum-check.patch deleted file mode 100644 index 362bf2e..0000000 --- a/coreutils-9.2-cksum-check.patch +++ /dev/null @@ -1,67 +0,0 @@ -From b9fa05c7f08581b175d87b94fb751643dda53187 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Thu, 23 Mar 2023 12:31:24 +0000 -Subject: [PATCH] cksum: fix reporting of failed checks - -This applies to all checksumming utilities, -where we incorrectly report all subsequent files as checking 'OK' -once any file has passed a digest check. -The exit status was not impacted, only the printed status. - -* src/digest.c (digest_check): Use the correct state variable -to determine if the _current_ file has passed or not. -* tests/misc/md5sum.pl: Add a test case. -Fixes https://bugs.gnu.org/62403 - -Upstream-commit: 76f2fb627118a26c25003dbd98c22c153b7ee1d2 -Signed-off-by: Kamil Dudka ---- - src/digest.c | 4 ++-- - tests/misc/md5sum.pl | 10 ++++++++++ - 2 files changed, 12 insertions(+), 2 deletions(-) - -diff --git a/src/digest.c b/src/digest.c -index 6ee8a48..ab32968 100644 ---- a/src/digest.c -+++ b/src/digest.c -@@ -1254,14 +1254,14 @@ digest_check (char const *checkfile_name) - - if (!status_only) - { -- if ( ! matched_checksums || ! quiet) -+ if (! match || ! quiet) - { - if (needs_escape) - putchar ('\\'); - print_filename (filename, needs_escape); - } - -- if ( ! matched_checksums) -+ if (! match) - printf (": %s\n", _("FAILED")); - else if (!quiet) - printf (": %s\n", _("OK")); -diff --git a/tests/misc/md5sum.pl b/tests/misc/md5sum.pl -index 186aca9..d712664 100755 ---- a/tests/misc/md5sum.pl -+++ b/tests/misc/md5sum.pl -@@ -101,6 +101,16 @@ my @Tests = - . "md5sum: WARNING: 1 line is improperly formatted\n" - . "md5sum: WARNING: 2 computed checksums did NOT match\n"}, - {EXIT=> 1}], -+ # Ensure we use appropriate state to track failures (broken in 9.2) -+ ['check-multifail-state', '--check', '--warn', -+ {IN=>{'f.md5' => -+ "$degenerate f\n" -+ . "$degenerate g\n" -+ . "$degenerate f\n" }}, -+ {AUX=> {f=> ''}}, {AUX=> {g=> 'a'}}, -+ {OUT=>"f: OK\ng: FAILED\nf: OK\n"}, -+ {ERR=>"md5sum: WARNING: 1 computed checksum did NOT match\n"}, -+ {EXIT=> 1}], - # The sha1sum and md5sum drivers share a lot of code. - # Ensure that md5sum does *not* share the part that makes - # sha1sum accept BSD format. --- -2.39.2 - diff --git a/coreutils-9.2-cp-reflink.patch b/coreutils-9.2-cp-reflink.patch deleted file mode 100644 index 34718a7..0000000 --- a/coreutils-9.2-cp-reflink.patch +++ /dev/null @@ -1,137 +0,0 @@ -From af99eb5e5e89b67ecdc582d4face2a4614d5cda8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Thu, 23 Mar 2023 13:19:04 +0000 -Subject: [PATCH] copy: fix --reflink=auto to fallback in more cases - -On restricted systems like android or some containers, -FICLONE could return EPERM, EACCES, or ENOTTY, -which would have induced the command to fail to copy -rather than falling back to a more standard copy. - -* src/copy.c (is_terminal_failure): A new function refactored -from handle_clone_fail(). -(is_CLONENOTSUP): Merge in the handling of EACCES, ENOTTY, EPERM -as they also pertain to determination of whether cloning is supported -if we ever use this function in that context. -(handle_clone_fail): Use is_terminal_failure() in all cases, -so that we assume a terminal failure in less errno cases. -Addresses https://bugs.gnu.org/62404 - -Upstream-commit: 093a8b4bfaba60005f14493ce7ef11ed665a0176 -Signed-off-by: Kamil Dudka ---- - src/copy.c | 62 ++++++++++++++++++++++++++++++------------------------ - 1 file changed, 35 insertions(+), 27 deletions(-) - -diff --git a/src/copy.c b/src/copy.c -index 3919787..f8ba058 100644 ---- a/src/copy.c -+++ b/src/copy.c -@@ -278,15 +278,27 @@ create_hole (int fd, char const *name, bool punch_holes, off_t size) - } - - --/* Whether the errno from FICLONE, or copy_file_range -- indicates operation is not supported for this file or file system. */ -+/* Whether the errno indicates the operation is a transient failure. -+ I.e., a failure that would indicate the operation _is_ supported, -+ but has failed in a terminal way. */ -+ -+static bool -+is_terminal_error (int err) -+{ -+ return err == EIO || err == ENOMEM || err == ENOSPC || err == EDQUOT; -+} -+ -+ -+/* Whether the errno from FICLONE, or copy_file_range indicates -+ the operation is not supported/allowed for this file or process. */ - - static bool - is_CLONENOTSUP (int err) - { -- return err == ENOSYS || is_ENOTSUP (err) -+ return err == ENOSYS || err == ENOTTY || is_ENOTSUP (err) - || err == EINVAL || err == EBADF -- || err == EXDEV || err == ETXTBSY; -+ || err == EXDEV || err == ETXTBSY -+ || err == EPERM || err == EACCES; - } - - -@@ -339,20 +351,18 @@ sparse_copy (int src_fd, int dest_fd, char **abuf, size_t buf_size, - { - copy_debug.offload = COPY_DEBUG_UNSUPPORTED; - -- if (is_CLONENOTSUP (errno)) -- break; -- -- /* copy_file_range might not be enabled in seccomp filters, -- so retry with a standard copy. EPERM can also occur -- for immutable files, but that would only be in the edge case -- where the file is made immutable after creating/truncating, -+ /* Consider operation unsupported only if no data copied. -+ For example, EPERM could occur if copy_file_range not enabled -+ in seccomp filters, so retry with a standard copy. EPERM can -+ also occur for immutable files, but that would only be in the -+ edge case where the file is made immutable after creating, - in which case the (more accurate) error is still shown. */ -- if (errno == EPERM && *total_n_read == 0) -+ if (*total_n_read == 0 && is_CLONENOTSUP (errno)) - break; - - /* ENOENT was seen sometimes across CIFS shares, resulting in - no data being copied, but subsequent standard copies succeed. */ -- if (errno == ENOENT && *total_n_read == 0) -+ if (*total_n_read == 0 && errno == ENOENT) - break; - - if (errno == EINTR) -@@ -1172,17 +1182,15 @@ handle_clone_fail (int dst_dirfd, char const* dst_relname, - char const* src_name, char const* dst_name, - int dest_desc, bool new_dst, enum Reflink_type reflink_mode) - { -- /* If the clone operation is creating the destination, -- then don't try and cater for all non transient file system errors, -- and instead only cater for specific transient errors. */ -- bool transient_failure; -- if (dest_desc < 0) /* currently for fclonefileat(). */ -- transient_failure = errno == EIO || errno == ENOMEM -- || errno == ENOSPC || errno == EDQUOT; -- else /* currently for FICLONE. */ -- transient_failure = ! is_CLONENOTSUP (errno); -- -- if (reflink_mode == REFLINK_ALWAYS || transient_failure) -+ /* When the clone operation fails, report failure only with errno values -+ known to mean trouble when the clone is supported and called properly. -+ Do not report failure merely because !is_CLONENOTSUP (errno), -+ as systems may yield oddball errno values here with FICLONE. -+ Also is_CLONENOTSUP() is not appropriate for the range of errnos -+ possible from fclonefileat(), so it's more consistent to avoid. */ -+ bool report_failure = is_terminal_error (errno); -+ -+ if (reflink_mode == REFLINK_ALWAYS || report_failure) - error (0, errno, _("failed to clone %s from %s"), - quoteaf_n (0, dst_name), quoteaf_n (1, src_name)); - -@@ -1190,14 +1198,14 @@ handle_clone_fail (int dst_dirfd, char const* dst_relname, - but cloned no data. */ - if (new_dst /* currently not for fclonefileat(). */ - && reflink_mode == REFLINK_ALWAYS -- && ((! transient_failure) || lseek (dest_desc, 0, SEEK_END) == 0) -+ && ((! report_failure) || lseek (dest_desc, 0, SEEK_END) == 0) - && unlinkat (dst_dirfd, dst_relname, 0) != 0 && errno != ENOENT) - error (0, errno, _("cannot remove %s"), quoteaf (dst_name)); - -- if (! transient_failure) -+ if (! report_failure) - copy_debug.reflink = COPY_DEBUG_UNSUPPORTED; - -- if (reflink_mode == REFLINK_ALWAYS || transient_failure) -+ if (reflink_mode == REFLINK_ALWAYS || report_failure) - return false; - - return true; --- -2.39.2 - diff --git a/coreutils.spec b/coreutils.spec index c634298..9900b6a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.2 -Release: 4%{?dist} +Version: 9.3 +Release: 1%{?dist} License: GPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -14,12 +14,6 @@ Source51: coreutils-provides.inc Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh -# cksum: fix reporting of failed checks (#2180056) -Patch1: coreutils-9.2-cksum-check.patch - -# copy: fix --reflink=auto to fallback in more cases (#2180056) -Patch2: coreutils-9.2-cp-reflink.patch - # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ @@ -258,6 +252,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Apr 18 2023 Kamil Dudka - 9.3-1 +- new upstream release 9.3 + * Tue Apr 11 2023 Lukáš Zaoral - 9.2-4 - migrate to SPDX license format diff --git a/sources b/sources index 5d14ac2..f5e06f7 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.2.tar.xz) = 7e3108fefba4ef995cc73c64ac5f4e09827a44649a97ddd624eb61d67ce82da5ed6dc8c0f79d3e269f5cdb7d43877a61ef5b93194dd905bec432a7e31f9f479c -SHA512 (coreutils-9.2.tar.xz.sig) = 4219f3103d829841a11bf1fe42ae277a44347e555fbbaf48e5e87cce48deb96753cb6d25f2571b88685a164acb9f016ff7ea02346b799ce954599fa0124ef070 +SHA512 (coreutils-9.3.tar.xz) = 242271f212a6860bdc6c8d7e5c4f85ce66c1b48ef781aca9daa56e0fe7c2b7809ef72b4392120219fe5b687637c83ce89ceef8bb35f6274f43f8f968a6901694 +SHA512 (coreutils-9.3.tar.xz.sig) = 522a2072f8ef940228ccdd856a4041c3c16b98e309168ccf2066fe7c1013685ba6cdea8a7317dfa1f4507b37ca016ecedaf54438d4a5007927b0e1a8fd223eb5 From 1c60283cdf57d2ba03c77b75820f4069c5142e1f Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 18 Apr 2023 18:05:08 +0200 Subject: [PATCH 485/523] revert a gnulib patch that broke the build --- coreutils-9.3-gnulib-strtol.patch | 276 ++++++++++++++++++++++++++++++ coreutils.spec | 3 + 2 files changed, 279 insertions(+) create mode 100644 coreutils-9.3-gnulib-strtol.patch diff --git a/coreutils-9.3-gnulib-strtol.patch b/coreutils-9.3-gnulib-strtol.patch new file mode 100644 index 0000000..1aac281 --- /dev/null +++ b/coreutils-9.3-gnulib-strtol.patch @@ -0,0 +1,276 @@ +From eca8f2dd212de534778c874a52ca079659e30140 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Tue, 18 Apr 2023 17:57:42 +0200 +Subject: [PATCH] Revert "strtol, strtoll, strtoul, strtoull: Make ISO C 23 + compliant." + +This reverts commit 4e38f4a0c65d4d19883b404a84169088b84b60d2. +--- + gnulib-tests/test-strtoll.c | 62 ------------------------------------ + gnulib-tests/test-strtoull.c | 62 ------------------------------------ + lib/strtol.c | 14 ++------ + m4/strtoll.m4 | 19 +++-------- + m4/strtoull.m4 | 19 +++-------- + 5 files changed, 11 insertions(+), 165 deletions(-) + +diff --git a/gnulib-tests/test-strtoll.c b/gnulib-tests/test-strtoll.c +index 24cb4eb..ecedbe6 100644 +--- a/gnulib-tests/test-strtoll.c ++++ b/gnulib-tests/test-strtoll.c +@@ -239,67 +239,5 @@ main (void) + ASSERT (errno == 0); + } + +- /* Binary integer syntax. */ +- { +- const char input[] = "0b111010"; +- char *ptr; +- long long result; +- errno = 0; +- result = strtoll (input, &ptr, 10); +- ASSERT (result == 0LL); +- ASSERT (ptr == input + 1); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b111010"; +- char *ptr; +- long long result; +- errno = 0; +- result = strtoll (input, &ptr, 2); +- ASSERT (result == 58LL); +- ASSERT (ptr == input + 8); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b111010"; +- char *ptr; +- long long result; +- errno = 0; +- result = strtoll (input, &ptr, 0); +- ASSERT (result == 58LL); +- ASSERT (ptr == input + 8); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b"; +- char *ptr; +- long long result; +- errno = 0; +- result = strtoll (input, &ptr, 10); +- ASSERT (result == 0LL); +- ASSERT (ptr == input + 1); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b"; +- char *ptr; +- long long result; +- errno = 0; +- result = strtoll (input, &ptr, 2); +- ASSERT (result == 0LL); +- ASSERT (ptr == input + 1); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b"; +- char *ptr; +- long long result; +- errno = 0; +- result = strtoll (input, &ptr, 0); +- ASSERT (result == 0LL); +- ASSERT (ptr == input + 1); +- ASSERT (errno == 0); +- } +- + return 0; + } +diff --git a/gnulib-tests/test-strtoull.c b/gnulib-tests/test-strtoull.c +index 7b0027f..dd6ec2a 100644 +--- a/gnulib-tests/test-strtoull.c ++++ b/gnulib-tests/test-strtoull.c +@@ -238,67 +238,5 @@ main (void) + ASSERT (errno == 0); + } + +- /* Binary integer syntax. */ +- { +- const char input[] = "0b111010"; +- char *ptr; +- unsigned long long result; +- errno = 0; +- result = strtoull (input, &ptr, 10); +- ASSERT (result == 0ULL); +- ASSERT (ptr == input + 1); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b111010"; +- char *ptr; +- unsigned long long result; +- errno = 0; +- result = strtoull (input, &ptr, 2); +- ASSERT (result == 58ULL); +- ASSERT (ptr == input + 8); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b111010"; +- char *ptr; +- unsigned long long result; +- errno = 0; +- result = strtoull (input, &ptr, 0); +- ASSERT (result == 58ULL); +- ASSERT (ptr == input + 8); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b"; +- char *ptr; +- unsigned long long result; +- errno = 0; +- result = strtoull (input, &ptr, 10); +- ASSERT (result == 0ULL); +- ASSERT (ptr == input + 1); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b"; +- char *ptr; +- unsigned long long result; +- errno = 0; +- result = strtoull (input, &ptr, 2); +- ASSERT (result == 0ULL); +- ASSERT (ptr == input + 1); +- ASSERT (errno == 0); +- } +- { +- const char input[] = "0b"; +- char *ptr; +- unsigned long long result; +- errno = 0; +- result = strtoull (input, &ptr, 0); +- ASSERT (result == 0ULL); +- ASSERT (ptr == input + 1); +- ASSERT (errno == 0); +- } +- + return 0; + } +diff --git a/lib/strtol.c b/lib/strtol.c +index b93483d..d11269b 100644 +--- a/lib/strtol.c ++++ b/lib/strtol.c +@@ -288,11 +288,6 @@ INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr, + s += 2; + base = 16; + } +- else if ((base == 0 || base == 2) && TOUPPER (s[1]) == L_('B')) +- { +- s += 2; +- base = 2; +- } + else if (base == 0) + base = 8; + } +@@ -383,14 +378,11 @@ INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr, + noconv: + /* We must handle a special case here: the base is 0 or 16 and the + first two characters are '0' and 'x', but the rest are no +- hexadecimal digits. Likewise when the base is 0 or 2 and the +- first two characters are '0' and 'b', but the rest are no binary +- digits. This is no error case. We return 0 and ENDPTR points to +- the 'x' or 'b'. */ ++ hexadecimal digits. This is no error case. We return 0 and ++ ENDPTR points to the 'x'. */ + if (endptr != NULL) + { +- if (save - nptr >= 2 +- && (TOUPPER (save[-1]) == L_('X') || TOUPPER (save[-1]) == L_('B')) ++ if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X') + && save[-2] == L_('0')) + *endptr = (STRING_TYPE *) &save[-1]; + else +diff --git a/m4/strtoll.m4 b/m4/strtoll.m4 +index ec09609..ede630c 100644 +--- a/m4/strtoll.m4 ++++ b/m4/strtoll.m4 +@@ -1,4 +1,4 @@ +-# strtoll.m4 serial 10 ++# strtoll.m4 serial 9 + dnl Copyright (C) 2002, 2004, 2006, 2008-2023 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +@@ -24,26 +24,15 @@ AC_DEFUN([gl_FUNC_STRTOLL], + if (term != input + 1) + result |= 1; + } +- /* This test fails on pre-C23 platforms. */ +- { +- const char input[] = "0b1"; +- (void) strtoll (input, &term, 2); +- if (term != input + 3) +- result |= 2; +- } + return result; + ]]) + ], + [gl_cv_func_strtoll_works=yes], + [gl_cv_func_strtoll_works=no], + [case "$host_os" in +- # Guess no on native Windows. +- mingw*) gl_cv_func_strtoll_works="guessing no" ;; +- # Guess no on glibc systems. +- *-gnu* | gnu*) gl_cv_func_strtoll_works="guessing no" ;; +- # Guess no on musl systems. +- *-musl* | midipix*) gl_cv_func_strtoll_works="guessing no" ;; +- *) gl_cv_func_strtoll_works="$gl_cross_guess_normal" ;; ++ # Guess no on native Windows. ++ mingw*) gl_cv_func_strtoll_works="guessing no" ;; ++ *) gl_cv_func_strtoll_works="$gl_cross_guess_normal" ;; + esac + ]) + ]) +diff --git a/m4/strtoull.m4 b/m4/strtoull.m4 +index 4f895c7..a9b0ddf 100644 +--- a/m4/strtoull.m4 ++++ b/m4/strtoull.m4 +@@ -1,4 +1,4 @@ +-# strtoull.m4 serial 10 ++# strtoull.m4 serial 9 + dnl Copyright (C) 2002, 2004, 2006, 2008-2023 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +@@ -24,26 +24,15 @@ AC_DEFUN([gl_FUNC_STRTOULL], + if (term != input + 1) + result |= 1; + } +- /* This test fails on pre-C23 platforms. */ +- { +- const char input[] = "0b1"; +- (void) strtoull (input, &term, 2); +- if (term != input + 3) +- result |= 2; +- } + return result; + ]]) + ], + [gl_cv_func_strtoull_works=yes], + [gl_cv_func_strtoull_works=no], + [case "$host_os" in +- # Guess no on native Windows. +- mingw*) gl_cv_func_strtoull_works="guessing no" ;; +- # Guess no on glibc systems. +- *-gnu* | gnu*) gl_cv_func_strtoull_works="guessing no" ;; +- # Guess no on musl systems. +- *-musl* | midipix*) gl_cv_func_strtoull_works="guessing no" ;; +- *) gl_cv_func_strtoull_works="$gl_cross_guess_normal" ;; ++ # Guess no on native Windows. ++ mingw*) gl_cv_func_strtoull_works="guessing no" ;; ++ *) gl_cv_func_strtoull_works="$gl_cross_guess_normal" ;; + esac + ]) + ]) +-- +2.39.2 + diff --git a/coreutils.spec b/coreutils.spec index 9900b6a..41fd4d1 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -14,6 +14,9 @@ Source51: coreutils-provides.inc Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh +# revert a gnulib patch that broke the build +Patch1: coreutils-9.3-gnulib-strtol.patch + # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ From 3040113a7af52aae81973c43f8aaa45def979a77 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 18 Apr 2023 17:28:19 +0200 Subject: [PATCH 486/523] coreutils-provides.inc: remove obsolete Provides --- coreutils-provides.inc | 8 -------- coreutils.spec | 1 + 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/coreutils-provides.inc b/coreutils-provides.inc index 8314a4e..3e76f28 100644 --- a/coreutils-provides.inc +++ b/coreutils-provides.inc @@ -1,9 +1 @@ Provides: bundled(gnulib) - -# make it possible to install the latest available Adobe Reader RPM for Linux -Provides: /bin/cat -Provides: /bin/chmod -Provides: /bin/echo -Provides: /bin/ln -Provides: /bin/rm -Provides: /bin/touch diff --git a/coreutils.spec b/coreutils.spec index 41fd4d1..b2b41f6 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -256,6 +256,7 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %changelog * Tue Apr 18 2023 Kamil Dudka - 9.3-1 +- remove obsolete Provides for absolute paths - new upstream release 9.3 * Tue Apr 11 2023 Lukáš Zaoral - 9.2-4 From 6e05a629136449563ab68cdf32acb9d374f51c1f Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 18 Apr 2023 17:30:33 +0200 Subject: [PATCH 487/523] coreutils-provides.inc: inline the content to coreutils.spec ... rather than including it on RPM level. The external reference was breaking a lot of tools for automated updates of the SPEC file. --- coreutils-provides.inc | 1 - coreutils.spec | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 coreutils-provides.inc diff --git a/coreutils-provides.inc b/coreutils-provides.inc deleted file mode 100644 index 3e76f28..0000000 --- a/coreutils-provides.inc +++ /dev/null @@ -1 +0,0 @@ -Provides: bundled(gnulib) diff --git a/coreutils.spec b/coreutils.spec index b2b41f6..70e4a02 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -10,7 +10,6 @@ Source1: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig # which is linked as project keyring on https://savannah.gnu.org/projects/coreutils Source2: coreutils-keyring.gpg Source50: supported_utils -Source51: coreutils-provides.inc Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh @@ -76,7 +75,7 @@ BuildRequires: glibc-langpack-ko Requires: %{name}-common = %{version}-%{release} Provides: coreutils-full = %{version}-%{release} -%include %{SOURCE51} +Provides: bundled(gnulib) Obsoletes: %{name} < 8.24-100 %description @@ -88,7 +87,7 @@ Summary: coreutils multicall binary Suggests: coreutils-common Provides: coreutils = %{version}-%{release} Provides: coreutils%{?_isa} = %{version}-%{release} -%include %{SOURCE51} +Provides: bundled(gnulib) # To avoid clobbering installs Conflicts: coreutils < 8.24-100 # Note RPM doesn't support separate buildroots for %files From 21acecbf27bbccac1fbc4c9eedd9e8422c3fb1b0 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 19 Jul 2023 16:24:12 +0000 Subject: [PATCH 488/523] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 70e4a02..39bc384 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.3 -Release: 1%{?dist} +Release: 2%{?dist} License: GPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz @@ -254,6 +254,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jul 19 2023 Fedora Release Engineering - 9.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Tue Apr 18 2023 Kamil Dudka - 9.3-1 - remove obsolete Provides for absolute paths - new upstream release 9.3 From bf0817f5a59c71d2a72363e457baa5ff8f80cd27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Fri, 15 Sep 2023 15:52:15 +0200 Subject: [PATCH 489/523] new upstream release 9.4 - enable integration with systemd - fix the license field Resolves: rhbz#2235759 --- coreutils-9.3-gnulib-strtol.patch | 276 -------- coreutils-9.4-systemd-coredump.patch | 28 + coreutils-df-direct.patch | 26 +- coreutils-i18n.patch | 904 ++++++++++++++------------- coreutils-selinux.patch | 26 +- coreutils.spec | 19 +- sources | 4 +- 7 files changed, 524 insertions(+), 759 deletions(-) delete mode 100644 coreutils-9.3-gnulib-strtol.patch create mode 100644 coreutils-9.4-systemd-coredump.patch diff --git a/coreutils-9.3-gnulib-strtol.patch b/coreutils-9.3-gnulib-strtol.patch deleted file mode 100644 index 1aac281..0000000 --- a/coreutils-9.3-gnulib-strtol.patch +++ /dev/null @@ -1,276 +0,0 @@ -From eca8f2dd212de534778c874a52ca079659e30140 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Tue, 18 Apr 2023 17:57:42 +0200 -Subject: [PATCH] Revert "strtol, strtoll, strtoul, strtoull: Make ISO C 23 - compliant." - -This reverts commit 4e38f4a0c65d4d19883b404a84169088b84b60d2. ---- - gnulib-tests/test-strtoll.c | 62 ------------------------------------ - gnulib-tests/test-strtoull.c | 62 ------------------------------------ - lib/strtol.c | 14 ++------ - m4/strtoll.m4 | 19 +++-------- - m4/strtoull.m4 | 19 +++-------- - 5 files changed, 11 insertions(+), 165 deletions(-) - -diff --git a/gnulib-tests/test-strtoll.c b/gnulib-tests/test-strtoll.c -index 24cb4eb..ecedbe6 100644 ---- a/gnulib-tests/test-strtoll.c -+++ b/gnulib-tests/test-strtoll.c -@@ -239,67 +239,5 @@ main (void) - ASSERT (errno == 0); - } - -- /* Binary integer syntax. */ -- { -- const char input[] = "0b111010"; -- char *ptr; -- long long result; -- errno = 0; -- result = strtoll (input, &ptr, 10); -- ASSERT (result == 0LL); -- ASSERT (ptr == input + 1); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b111010"; -- char *ptr; -- long long result; -- errno = 0; -- result = strtoll (input, &ptr, 2); -- ASSERT (result == 58LL); -- ASSERT (ptr == input + 8); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b111010"; -- char *ptr; -- long long result; -- errno = 0; -- result = strtoll (input, &ptr, 0); -- ASSERT (result == 58LL); -- ASSERT (ptr == input + 8); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b"; -- char *ptr; -- long long result; -- errno = 0; -- result = strtoll (input, &ptr, 10); -- ASSERT (result == 0LL); -- ASSERT (ptr == input + 1); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b"; -- char *ptr; -- long long result; -- errno = 0; -- result = strtoll (input, &ptr, 2); -- ASSERT (result == 0LL); -- ASSERT (ptr == input + 1); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b"; -- char *ptr; -- long long result; -- errno = 0; -- result = strtoll (input, &ptr, 0); -- ASSERT (result == 0LL); -- ASSERT (ptr == input + 1); -- ASSERT (errno == 0); -- } -- - return 0; - } -diff --git a/gnulib-tests/test-strtoull.c b/gnulib-tests/test-strtoull.c -index 7b0027f..dd6ec2a 100644 ---- a/gnulib-tests/test-strtoull.c -+++ b/gnulib-tests/test-strtoull.c -@@ -238,67 +238,5 @@ main (void) - ASSERT (errno == 0); - } - -- /* Binary integer syntax. */ -- { -- const char input[] = "0b111010"; -- char *ptr; -- unsigned long long result; -- errno = 0; -- result = strtoull (input, &ptr, 10); -- ASSERT (result == 0ULL); -- ASSERT (ptr == input + 1); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b111010"; -- char *ptr; -- unsigned long long result; -- errno = 0; -- result = strtoull (input, &ptr, 2); -- ASSERT (result == 58ULL); -- ASSERT (ptr == input + 8); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b111010"; -- char *ptr; -- unsigned long long result; -- errno = 0; -- result = strtoull (input, &ptr, 0); -- ASSERT (result == 58ULL); -- ASSERT (ptr == input + 8); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b"; -- char *ptr; -- unsigned long long result; -- errno = 0; -- result = strtoull (input, &ptr, 10); -- ASSERT (result == 0ULL); -- ASSERT (ptr == input + 1); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b"; -- char *ptr; -- unsigned long long result; -- errno = 0; -- result = strtoull (input, &ptr, 2); -- ASSERT (result == 0ULL); -- ASSERT (ptr == input + 1); -- ASSERT (errno == 0); -- } -- { -- const char input[] = "0b"; -- char *ptr; -- unsigned long long result; -- errno = 0; -- result = strtoull (input, &ptr, 0); -- ASSERT (result == 0ULL); -- ASSERT (ptr == input + 1); -- ASSERT (errno == 0); -- } -- - return 0; - } -diff --git a/lib/strtol.c b/lib/strtol.c -index b93483d..d11269b 100644 ---- a/lib/strtol.c -+++ b/lib/strtol.c -@@ -288,11 +288,6 @@ INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr, - s += 2; - base = 16; - } -- else if ((base == 0 || base == 2) && TOUPPER (s[1]) == L_('B')) -- { -- s += 2; -- base = 2; -- } - else if (base == 0) - base = 8; - } -@@ -383,14 +378,11 @@ INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr, - noconv: - /* We must handle a special case here: the base is 0 or 16 and the - first two characters are '0' and 'x', but the rest are no -- hexadecimal digits. Likewise when the base is 0 or 2 and the -- first two characters are '0' and 'b', but the rest are no binary -- digits. This is no error case. We return 0 and ENDPTR points to -- the 'x' or 'b'. */ -+ hexadecimal digits. This is no error case. We return 0 and -+ ENDPTR points to the 'x'. */ - if (endptr != NULL) - { -- if (save - nptr >= 2 -- && (TOUPPER (save[-1]) == L_('X') || TOUPPER (save[-1]) == L_('B')) -+ if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X') - && save[-2] == L_('0')) - *endptr = (STRING_TYPE *) &save[-1]; - else -diff --git a/m4/strtoll.m4 b/m4/strtoll.m4 -index ec09609..ede630c 100644 ---- a/m4/strtoll.m4 -+++ b/m4/strtoll.m4 -@@ -1,4 +1,4 @@ --# strtoll.m4 serial 10 -+# strtoll.m4 serial 9 - dnl Copyright (C) 2002, 2004, 2006, 2008-2023 Free Software Foundation, Inc. - dnl This file is free software; the Free Software Foundation - dnl gives unlimited permission to copy and/or distribute it, -@@ -24,26 +24,15 @@ AC_DEFUN([gl_FUNC_STRTOLL], - if (term != input + 1) - result |= 1; - } -- /* This test fails on pre-C23 platforms. */ -- { -- const char input[] = "0b1"; -- (void) strtoll (input, &term, 2); -- if (term != input + 3) -- result |= 2; -- } - return result; - ]]) - ], - [gl_cv_func_strtoll_works=yes], - [gl_cv_func_strtoll_works=no], - [case "$host_os" in -- # Guess no on native Windows. -- mingw*) gl_cv_func_strtoll_works="guessing no" ;; -- # Guess no on glibc systems. -- *-gnu* | gnu*) gl_cv_func_strtoll_works="guessing no" ;; -- # Guess no on musl systems. -- *-musl* | midipix*) gl_cv_func_strtoll_works="guessing no" ;; -- *) gl_cv_func_strtoll_works="$gl_cross_guess_normal" ;; -+ # Guess no on native Windows. -+ mingw*) gl_cv_func_strtoll_works="guessing no" ;; -+ *) gl_cv_func_strtoll_works="$gl_cross_guess_normal" ;; - esac - ]) - ]) -diff --git a/m4/strtoull.m4 b/m4/strtoull.m4 -index 4f895c7..a9b0ddf 100644 ---- a/m4/strtoull.m4 -+++ b/m4/strtoull.m4 -@@ -1,4 +1,4 @@ --# strtoull.m4 serial 10 -+# strtoull.m4 serial 9 - dnl Copyright (C) 2002, 2004, 2006, 2008-2023 Free Software Foundation, Inc. - dnl This file is free software; the Free Software Foundation - dnl gives unlimited permission to copy and/or distribute it, -@@ -24,26 +24,15 @@ AC_DEFUN([gl_FUNC_STRTOULL], - if (term != input + 1) - result |= 1; - } -- /* This test fails on pre-C23 platforms. */ -- { -- const char input[] = "0b1"; -- (void) strtoull (input, &term, 2); -- if (term != input + 3) -- result |= 2; -- } - return result; - ]]) - ], - [gl_cv_func_strtoull_works=yes], - [gl_cv_func_strtoull_works=no], - [case "$host_os" in -- # Guess no on native Windows. -- mingw*) gl_cv_func_strtoull_works="guessing no" ;; -- # Guess no on glibc systems. -- *-gnu* | gnu*) gl_cv_func_strtoull_works="guessing no" ;; -- # Guess no on musl systems. -- *-musl* | midipix*) gl_cv_func_strtoull_works="guessing no" ;; -- *) gl_cv_func_strtoull_works="$gl_cross_guess_normal" ;; -+ # Guess no on native Windows. -+ mingw*) gl_cv_func_strtoull_works="guessing no" ;; -+ *) gl_cv_func_strtoull_works="$gl_cross_guess_normal" ;; - esac - ]) - ]) --- -2.39.2 - diff --git a/coreutils-9.4-systemd-coredump.patch b/coreutils-9.4-systemd-coredump.patch new file mode 100644 index 0000000..13f69e0 --- /dev/null +++ b/coreutils-9.4-systemd-coredump.patch @@ -0,0 +1,28 @@ +From 2616c6be1c244424617997151c67bcab2dacbcfe Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Thu, 31 Aug 2023 14:34:05 +0200 +Subject: [PATCH] coreutils-9.4-systemd-coredump.patch + +Cherry picked from gnulib upstream commits: +* 1e6a26f9312bb47e070f94b17b14dc1a6ffbb74f ("readutmp: fix core dump if --enable-systemd") +* 3af1d7b0ce3a8e3ae565e7cea10cee6fd7cb8109 ("readutmp: Fix memory leak introduced by last commit.") +--- + lib/readutmp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/readutmp.c b/lib/readutmp.c +index 0173b7e..ec09feb 100644 +--- a/lib/readutmp.c ++++ b/lib/readutmp.c +@@ -795,7 +795,7 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) + { + char **sessions; + int num_sessions = sd_get_sessions (&sessions); +- if (num_sessions >= 0) ++ if (num_sessions >= 0 && sessions != NULL) + { + char **session_ptr; + for (session_ptr = sessions; *session_ptr != NULL; session_ptr++) +-- +2.41.0 + diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 2571fa4..9e3434a 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -53,16 +53,16 @@ index 48025b9..c8efa5b 100644 static struct option const long_options[] = { - {"all", no_argument, NULL, 'a'}, - {"block-size", required_argument, NULL, 'B'}, -+ {"direct", no_argument, NULL, DIRECT_OPTION}, - {"inodes", no_argument, NULL, 'i'}, - {"human-readable", no_argument, NULL, 'h'}, - {"si", no_argument, NULL, 'H'}, + {"all", no_argument, nullptr, 'a'}, + {"block-size", required_argument, nullptr, 'B'}, ++ {"direct", no_argument, nullptr, DIRECT_OPTION}, + {"inodes", no_argument, nullptr, 'i'}, + {"human-readable", no_argument, nullptr, 'h'}, + {"si", no_argument, nullptr, 'H'}, @@ -583,7 +588,10 @@ get_header (void) for (col = 0; col < ncolumns; col++) { - char *cell = NULL; + char *cell = nullptr; - char const *header = _(columns[col]->caption); + char const *header = (columns[col]->field == TARGET_FIELD + && direct_statfs)? @@ -79,11 +79,11 @@ index 48025b9..c8efa5b 100644 + { + char *resolved = canonicalize_file_name (name); + if (resolved) -+ { -+ get_dev (NULL, resolved, name, NULL, NULL, false, false, NULL, false); -+ free (resolved); -+ return; -+ } ++ { ++ get_dev (NULL, resolved, name, NULL, NULL, false, false, NULL, false); ++ free (resolved); ++ return; ++ } + } + if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) @@ -114,7 +114,7 @@ index 48025b9..c8efa5b 100644 + if (direct_statfs && show_local_fs) + { + error (0, 0, _("options --direct and --local (-l) are mutually " -+ "exclusive")); ++ "exclusive")); + usage (EXIT_FAILURE); + } + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 8492fe6..6a29fe2 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,11 +1,11 @@ -From 01010419a6499768563e7b2f3fd56cf16edda75e Mon Sep 17 00:00:00 2001 +From 3a1b92e80708319bcc89852e3da1029c3d1ff6b3 Mon Sep 17 00:00:00 2001 From: rpm-build -Date: Mon, 4 Oct 2021 08:54:37 +0200 +Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch --- bootstrap.conf | 1 + - configure.ac | 2 + + configure.ac | 6 + lib/linebuffer.h | 8 + lib/mbfile.c | 3 + lib/mbfile.h | 255 ++++++++++++ @@ -29,13 +29,13 @@ Subject: [PATCH] coreutils-i18n.patch 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/sort/sort-merge.pl | 42 ++ + tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 31 files changed, 3699 insertions(+), 242 deletions(-) + tests/uniq/uniq.pl | 55 +++ + 31 files changed, 3703 insertions(+), 242 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -45,10 +45,10 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100755 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index c1399e3..60b39cf 100644 +index bd73ff2..0e450cd 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -165,6 +165,7 @@ gnulib_modules=" +@@ -167,6 +167,7 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -57,20 +57,24 @@ index c1399e3..60b39cf 100644 mbrtowc mbsalign diff --git a/configure.ac b/configure.ac -index 7e4afc9..4656a35 100644 +index 8ffc0b7..ca3305d 100644 --- a/configure.ac +++ b/configure.ac -@@ -477,6 +477,8 @@ fi +@@ -448,6 +448,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM +gl_MBFILE ++dnl Do not use gl_MODULE_INDICATOR([mbfile]) here: we don't want 'struct mbchar' ++dnl to have a different size in lib/ than in tests/. ++AC_DEFINE([GNULIB_MBFILE], [1], ++ [Define to 1 if the gnulib module 'mbfile' is in use.]) + gl_HEADER_TIOCGWINSZ_IN_TERMIOS_H if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index 07d45ca..af62e6c 100644 +index b4cc8e4..f2bbb52 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h @@ -22,6 +22,11 @@ @@ -386,11 +390,11 @@ index 0000000..8589902 + : +]) diff --git a/src/cut.c b/src/cut.c -index 6fd8978..faef877 100644 +index b4edbab..65e4658 100644 --- a/src/cut.c +++ b/src/cut.c -@@ -28,6 +28,11 @@ - #include +@@ -27,6 +27,11 @@ + #include #include #include + @@ -400,8 +404,8 @@ index 6fd8978..faef877 100644 +#endif #include "system.h" - #include "error.h" -@@ -36,6 +41,18 @@ + #include "assure.h" +@@ -35,6 +40,18 @@ #include "set-fields.h" @@ -420,7 +424,7 @@ index 6fd8978..faef877 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "cut" -@@ -52,6 +69,52 @@ +@@ -51,6 +68,52 @@ } \ while (0) @@ -473,8 +477,8 @@ index 6fd8978..faef877 100644 /* 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 -@@ -59,6 +122,9 @@ - CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */ +@@ -58,6 +121,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. */ @@ -483,7 +487,7 @@ index 6fd8978..faef877 100644 /* 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 -@@ -71,6 +137,29 @@ static char *field_1_buffer; +@@ -70,6 +136,29 @@ static char *field_1_buffer; /* The number of bytes allocated for FIELD_1_BUFFER. */ static size_t field_1_bufsize; @@ -510,18 +514,18 @@ index 6fd8978..faef877 100644 + if this program runs on multibyte locale. */ +static int force_singlebyte_mode; + - /* If true do not output lines containing no delimiter characters. + /* If true, do not output lines containing no delimiter characters. Otherwise, all such lines are printed. This option is valid only with field mode. */ -@@ -82,10 +171,16 @@ static bool complement; +@@ -81,10 +170,16 @@ static bool complement; - /* The delimiter character for field mode. */ + /* 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. */ + /* The delimiter for each line/record. */ static unsigned char line_delim = '\n'; +/* True if the --output-delimiter=STRING option was specified. */ @@ -530,17 +534,17 @@ index 6fd8978..faef877 100644 /* The length of output_delimiter_string. */ static size_t output_delimiter_length; -@@ -93,9 +188,6 @@ static size_t output_delimiter_length; +@@ -92,9 +187,6 @@ static size_t output_delimiter_length; string consisting of the input delimiter. */ static char *output_delimiter_string; -/* The output delimiter string contents, if the default. */ -static char output_delimiter_default[1]; - - /* True if we have ever read standard input. */ + /* True if we have ever read standard input. */ static bool have_read_stdin; -@@ -149,7 +241,7 @@ Print selected parts of lines from each FILE to standard output.\n\ +@@ -148,7 +240,7 @@ Print selected parts of lines from each FILE to standard output.\n\ -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\ @@ -549,7 +553,7 @@ index 6fd8978..faef877 100644 "), stdout); fputs (_("\ --complement complement the set of selected bytes, characters\n\ -@@ -249,7 +341,7 @@ cut_bytes (FILE *stream) +@@ -252,7 +344,7 @@ cut_bytes (FILE *stream) next_item (&byte_idx); if (print_kth (byte_idx)) { @@ -558,7 +562,7 @@ index 6fd8978..faef877 100644 { if (print_delimiter && is_range_start_index (byte_idx)) { -@@ -265,6 +357,82 @@ cut_bytes (FILE *stream) +@@ -271,6 +363,82 @@ cut_bytes (FILE *stream) } } @@ -641,7 +645,7 @@ index 6fd8978..faef877 100644 /* Read from stream STREAM, printing to standard output any selected fields. */ static void -@@ -410,11 +578,218 @@ cut_fields (FILE *stream) +@@ -433,11 +601,218 @@ cut_fields (FILE *stream) } } @@ -862,18 +866,18 @@ index 6fd8978..faef877 100644 { FILE *stream; -@@ -458,8 +833,8 @@ main (int argc, char **argv) +@@ -482,8 +857,8 @@ main (int argc, char **argv) int optc; bool ok; bool delim_specified = false; - bool byte_mode = false; -- char *spec_list_string = NULL; -+ char *spec_list_string IF_LINT ( = NULL); +- char *spec_list_string = nullptr; ++ char *spec_list_string IF_LINT ( = nullptr); + char mbdelim[MB_LEN_MAX + 1]; initialize_main (&argc, &argv); set_program_name (argv[0]); -@@ -469,6 +844,8 @@ main (int argc, char **argv) +@@ -493,6 +868,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -882,12 +886,12 @@ index 6fd8978..faef877 100644 /* By default, all non-delimited lines are printed. */ suppress_non_delimited = false; -@@ -480,35 +857,77 @@ main (int argc, char **argv) +@@ -505,35 +882,77 @@ main (int argc, char **argv) switch (optc) { case 'b': - case 'c': - /* Build the byte list. */ + /* Build the byte list. */ - byte_mode = true; - FALLTHROUGH; + if (operating_mode != undefined_mode) @@ -897,7 +901,7 @@ index 6fd8978..faef877 100644 + break; + + case 'c': -+ /* Build the character list. */ ++ /* Build the character list. */ + if (operating_mode != undefined_mode) + FATAL_ERROR (_("only one type of list may be specified")); + operating_mode = character_mode; @@ -905,7 +909,7 @@ index 6fd8978..faef877 100644 + break; + case 'f': - /* Build the field list. */ + /* Build the field list. */ - if (spec_list_string) - FATAL_ERROR (_("only one list may be specified")); + if (operating_mode != undefined_mode) @@ -915,7 +919,7 @@ index 6fd8978..faef877 100644 break; case 'd': - /* New delimiter. */ + /* 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")); @@ -970,7 +974,7 @@ index 6fd8978..faef877 100644 break; case 's': -@@ -532,40 +951,57 @@ main (int argc, char **argv) +@@ -555,40 +974,57 @@ main (int argc, char **argv) } } @@ -1011,7 +1015,7 @@ index 6fd8978..faef877 100644 +#endif + } - if (output_delimiter_string == NULL) + if (output_delimiter_string == nullptr) { - output_delimiter_default[0] = delim; - output_delimiter_string = output_delimiter_default; @@ -1046,18 +1050,18 @@ index 6fd8978..faef877 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index deec1bd..b39f740 100644 +index 89fa56a..c102e6e 100644 --- a/src/expand-common.c +++ b/src/expand-common.c -@@ -19,6 +19,7 @@ - #include +@@ -18,6 +18,7 @@ + #include #include +#include #include "system.h" - #include "die.h" - #include "error.h" -@@ -125,6 +126,119 @@ set_increment_size (uintmax_t tabval) + #include "fadvise.h" + #include "quote.h" +@@ -122,6 +123,119 @@ set_increment_size (uintmax_t tabval) return ok; } @@ -1178,7 +1182,7 @@ index deec1bd..b39f740 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index 5f59a0e..835b9d5 100644 +index daed31e..f6b2f68 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -25,6 +25,18 @@ extern size_t max_column_width; @@ -1201,7 +1205,7 @@ index 5f59a0e..835b9d5 100644 extern void add_tab_stop (uintmax_t tabval); diff --git a/src/expand.c b/src/expand.c -index ed78ca8..a4cefa1 100644 +index 0e74d0c..7080c51 100644 --- a/src/expand.c +++ b/src/expand.c @@ -37,6 +37,9 @@ @@ -1212,12 +1216,12 @@ index ed78ca8..a4cefa1 100644 +#include + #include "system.h" - #include "die.h" + #include "expand-common.h" -@@ -97,19 +100,41 @@ expand (void) +@@ -95,19 +98,41 @@ expand (void) { /* Input stream. */ - FILE *fp = next_file (NULL); + FILE *fp = next_file (nullptr); + mb_file_t mbf; + mbf_char_t c; + /* True if the starting locale is utf8. */ @@ -1260,7 +1264,7 @@ index ed78ca8..a4cefa1 100644 /* The following variables have valid values only when CONVERT is true: */ -@@ -119,17 +144,48 @@ expand (void) +@@ -117,17 +142,48 @@ expand (void) /* Index in TAB_LIST of next tab stop to examine. */ size_t tab_index = 0; @@ -1313,9 +1317,9 @@ index ed78ca8..a4cefa1 100644 { /* Column the next input tab stop is on. */ uintmax_t next_tab_column; -@@ -148,32 +204,34 @@ expand (void) +@@ -146,32 +202,34 @@ expand (void) if (putchar (' ') < 0) - die (EXIT_FAILURE, errno, _("write error")); + write_error (); - c = ' '; + mb_setascii (&c, ' '); @@ -1335,7 +1339,7 @@ index ed78ca8..a4cefa1 100644 - column++; + column += mb_width (c); if (!column) - die (EXIT_FAILURE, 0, _("input line is too long")); + error (EXIT_FAILURE, 0, _("input line is too long")); } - convert &= convert_entire_line || !! isblank (c); @@ -1349,7 +1353,7 @@ index ed78ca8..a4cefa1 100644 - if (putchar (c) < 0) + mb_putc (c, stdout); + if (ferror (stdout)) - die (EXIT_FAILURE, errno, _("write error")); + write_error (); } - while (c != '\n'); + while (!mb_iseq (c, '\n')); @@ -1357,10 +1361,10 @@ index ed78ca8..a4cefa1 100644 } diff --git a/src/fold.c b/src/fold.c -index f07a90b..d32dbfd 100644 +index 5c0428d..2372047 100644 --- a/src/fold.c +++ b/src/fold.c -@@ -22,12 +22,34 @@ +@@ -22,10 +22,32 @@ #include #include @@ -1375,8 +1379,6 @@ index f07a90b..d32dbfd 100644 +#endif + #include "system.h" - #include "die.h" - #include "error.h" #include "fadvise.h" #include "xdectoint.h" @@ -1395,7 +1397,7 @@ index f07a90b..d32dbfd 100644 #define TAB_WIDTH 8 /* The official name of this program (e.g., no 'g' prefix). */ -@@ -35,20 +57,41 @@ +@@ -33,20 +55,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -1436,12 +1438,12 @@ index f07a90b..d32dbfd 100644 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'}, + {"bytes", no_argument, nullptr, 'b'}, ++ {"characters", no_argument, nullptr, 'c'}, + {"spaces", no_argument, nullptr, 's'}, + {"width", required_argument, nullptr, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -76,6 +119,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ +@@ -74,6 +117,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -1449,7 +1451,7 @@ index f07a90b..d32dbfd 100644 -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 to standard output.\n\ +@@ -91,7 +135,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ static size_t adjust_column (size_t column, char c) { @@ -1458,7 +1460,7 @@ index f07a90b..d32dbfd 100644 { if (c == '\b') { -@@ -116,30 +160,14 @@ adjust_column (size_t column, char c) +@@ -114,30 +158,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -1471,7 +1473,7 @@ index f07a90b..d32dbfd 100644 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 char *line_out = nullptr; static size_t allocated_out = 0; - int saved_errno; - @@ -1483,7 +1485,7 @@ index f07a90b..d32dbfd 100644 - else - istream = fopen (filename, "r"); - -- if (istream == NULL) +- if (istream == nullptr) - { - error (0, errno, "%s", quotef (filename)); - return false; @@ -1491,7 +1493,7 @@ index f07a90b..d32dbfd 100644 fadvise (istream, FADVISE_SEQUENTIAL); -@@ -169,6 +197,15 @@ fold_file (char const *filename, size_t width) +@@ -167,6 +195,15 @@ fold_file (char const *filename, size_t width) bool found_blank = false; size_t logical_end = offset_out; @@ -1507,7 +1509,7 @@ index f07a90b..d32dbfd 100644 /* Look for the last blank. */ while (logical_end) { -@@ -215,13 +252,225 @@ fold_file (char const *filename, size_t width) +@@ -213,13 +250,225 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -1735,7 +1737,7 @@ index f07a90b..d32dbfd 100644 if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -252,7 +501,8 @@ main (int argc, char **argv) +@@ -250,7 +499,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1743,9 +1745,9 @@ index f07a90b..d32dbfd 100644 + operating_mode = column_mode; + break_spaces = have_read_stdin = false; - while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) + while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) { -@@ -261,7 +511,15 @@ main (int argc, char **argv) +@@ -259,7 +509,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1763,10 +1765,10 @@ index f07a90b..d32dbfd 100644 case 's': /* Break at word boundaries. */ diff --git a/src/join.c b/src/join.c -index f2fd172..6c7d1ed 100644 +index 0bcfa75..8a3bcf1 100644 --- a/src/join.c +++ b/src/join.c -@@ -22,19 +22,33 @@ +@@ -21,18 +21,32 @@ #include #include @@ -1781,8 +1783,7 @@ index f2fd172..6c7d1ed 100644 +#endif + #include "system.h" - #include "die.h" - #include "error.h" + #include "assure.h" #include "fadvise.h" #include "hard-locale.h" #include "linebuffer.h" @@ -1801,7 +1802,7 @@ index f2fd172..6c7d1ed 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "join" -@@ -136,10 +150,12 @@ static struct outlist outlist_head; +@@ -134,10 +148,12 @@ static struct outlist outlist_head; /* Last element in 'outlist', where a new element can be added. */ static struct outlist *outlist_end = &outlist_head; @@ -1813,12 +1814,12 @@ index f2fd172..6c7d1ed 100644 + by any nonempty string of blanks. */ +static char *tab = NULL; + -+/* The number of bytes used for tab. */ ++/* The number of bytes used for tab. */ +static size_t tablen = 0; /* If nonzero, check that the input is correctly ordered. */ static enum -@@ -280,13 +296,14 @@ xfields (struct line *line) +@@ -277,13 +293,14 @@ xfields (struct line *line) if (ptr == lim) return; @@ -1827,8 +1828,8 @@ index f2fd172..6c7d1ed 100644 { + 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) +- for (; (sep = memchr (ptr, tab, lim - ptr)) != nullptr; ptr = sep + 1) ++ for (; (sep = memchr (ptr, t, lim - ptr)) != nullptr; ptr = sep + 1) extract_field (line, ptr, sep - ptr); } - else if (tab < 0) @@ -1836,7 +1837,7 @@ index f2fd172..6c7d1ed 100644 { /* Skip leading blanks before the first field. */ while (field_sep (*ptr)) -@@ -310,6 +327,147 @@ xfields (struct line *line) +@@ -307,6 +324,147 @@ xfields (struct line *line) extract_field (line, ptr, lim - ptr); } @@ -1984,18 +1985,18 @@ index f2fd172..6c7d1ed 100644 static void freeline (struct line *line) { -@@ -331,56 +489,133 @@ keycmp (struct line const *line1, struct line const *line2, - size_t jf_1, size_t jf_2) +@@ -328,56 +486,133 @@ keycmp (struct line const *line1, struct line const *line2, + idx_t jf_1, idx_t jf_2) { /* Start of field to compare in each file. */ - char *beg1; - char *beg2; - -- size_t len1; -- size_t len2; /* Length of fields to compare. */ +- idx_t len1; +- idx_t len2; /* Length of fields to compare. */ + char *beg[2]; + char *copy[2]; -+ size_t len[2]; /* Length of fields to compare. */ ++ idx_t len[2]; /* Length of fields to compare. */ int diff; + int i, j; + int mallocd = 0; @@ -2009,9 +2010,9 @@ index f2fd172..6c7d1ed 100644 } else { -- beg1 = NULL; +- beg1 = nullptr; - len1 = 0; -+ beg[0] = NULL; ++ beg[0] = nullptr; + len[0] = 0; } @@ -2024,9 +2025,9 @@ index f2fd172..6c7d1ed 100644 } else { -- beg2 = NULL; +- beg2 = nullptr; - len2 = 0; -+ beg[1] = NULL; ++ beg[1] = nullptr; + len[1] = 0; } @@ -2141,7 +2142,7 @@ index f2fd172..6c7d1ed 100644 } /* Check that successive input lines PREV and CURRENT from input file -@@ -472,6 +707,11 @@ get_line (FILE *fp, struct line **linep, int which) +@@ -469,6 +704,11 @@ get_line (FILE *fp, struct line **linep, int which) } ++line_no[which - 1]; @@ -2153,7 +2154,7 @@ index f2fd172..6c7d1ed 100644 xfields (line); if (prevline[which - 1]) -@@ -567,21 +807,28 @@ prfield (size_t n, struct line const *line) +@@ -562,21 +802,28 @@ prfield (idx_t n, struct line const *line) /* Output all the fields in line, other than the join field. */ @@ -2166,10 +2167,10 @@ index f2fd172..6c7d1ed 100644 + while (0) + static void - prfields (struct line const *line, size_t join_field, size_t autocount) + prfields (struct line const *line, idx_t join_field, idx_t autocount) { - size_t i; - size_t nfields = autoformat ? autocount : line->nfields; + idx_t i; + idx_t nfields = autoformat ? autocount : line->nfields; - char output_separator = tab < 0 ? ' ' : tab; for (i = 0; i < join_field && i < nfields; ++i) @@ -2185,24 +2186,24 @@ index f2fd172..6c7d1ed 100644 prfield (i, line); } } -@@ -592,7 +839,6 @@ static void +@@ -587,7 +834,6 @@ static void prjoin (struct line const *line1, struct line const *line2) { const struct outlist *outlist; - char output_separator = tab < 0 ? ' ' : tab; - size_t field; + idx_t field; struct line const *line; -@@ -626,7 +872,7 @@ prjoin (struct line const *line1, struct line const *line2) +@@ -621,7 +867,7 @@ prjoin (struct line const *line1, struct line const *line2) o = o->next; - if (o == NULL) + if (o == nullptr) break; - putchar (output_separator); + PUT_TAB_CHAR; } putchar (eolchar); } -@@ -1102,20 +1348,43 @@ main (int argc, char **argv) +@@ -1086,20 +1332,43 @@ main (int argc, char **argv) case 't': { @@ -2235,8 +2236,8 @@ index f2fd172..6c7d1ed 100644 - if (STREQ (optarg, "\\0")) - newtab = '\0'; - else -- die (EXIT_FAILURE, 0, _("multi-character tab %s"), -- quote (optarg)); +- error (EXIT_FAILURE, 0, _("multi-character tab %s"), +- quote (optarg)); + if (newtablen == 1 && newtab[1]) + { + if (STREQ (newtab, "\\0")) @@ -2246,20 +2247,20 @@ index f2fd172..6c7d1ed 100644 + if (tab != NULL && strcmp (tab, newtab)) + { + free (newtab); -+ die (EXIT_FAILURE, 0, _("incompatible tabs")); ++ error (EXIT_FAILURE, 0, _("incompatible tabs")); } - if (0 <= tab && tab != newtab) -- die (EXIT_FAILURE, 0, _("incompatible tabs")); +- error (EXIT_FAILURE, 0, _("incompatible tabs")); tab = newtab; + tablen = newtablen; } break; diff --git a/src/local.mk b/src/local.mk -index e1d15ce..1a5ffaa 100644 +index f45b911..6f7036a 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -438,8 +438,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -447,8 +447,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -2271,12 +2272,12 @@ index e1d15ce..1a5ffaa 100644 src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 4c17c00..b4fab1c 100644 +index 419545c..702e025 100644 --- a/src/pr.c +++ b/src/pr.c -@@ -311,6 +311,24 @@ - +@@ -312,6 +312,24 @@ #include + #include #include + +/* Get MB_LEN_MAX. */ @@ -2297,9 +2298,9 @@ index 4c17c00..b4fab1c 100644 +#endif + #include "system.h" - #include "die.h" - #include "error.h" -@@ -325,6 +343,18 @@ + #include "fadvise.h" + #include "hard-locale.h" +@@ -324,6 +342,18 @@ #include "xstrtol-error.h" #include "xdectoint.h" @@ -2318,7 +2319,7 @@ index 4c17c00..b4fab1c 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -417,7 +447,20 @@ struct COLUMN +@@ -416,7 +446,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -2340,7 +2341,7 @@ index 4c17c00..b4fab1c 100644 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); +@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); static void getoptnum (char const *n_str, int min, int *num, char const *errfmt); static void getoptarg (char *arg, char switch_char, char *character, @@ -2348,7 +2349,7 @@ index 4c17c00..b4fab1c 100644 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); +@@ -441,7 +485,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); @@ -2356,7 +2357,7 @@ index 4c17c00..b4fab1c 100644 static void cleanup (void); static void print_sep_string (void); static void separator_string (char const *optarg_S); -@@ -454,7 +497,7 @@ static COLUMN *column_vector; +@@ -453,7 +496,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]. */ @@ -2365,7 +2366,7 @@ index 4c17c00..b4fab1c 100644 /* Index of the position in buff where the next character will be stored. */ -@@ -558,7 +601,7 @@ static int chars_per_column; +@@ -557,7 +600,7 @@ static int chars_per_column; static bool untabify_input = false; /* (-e) The input tab character. */ @@ -2374,7 +2375,7 @@ index 4c17c00..b4fab1c 100644 /* (-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; +@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8; static bool tabify_output = false; /* (-i) The output tab character. */ @@ -2386,7 +2387,7 @@ index 4c17c00..b4fab1c 100644 /* (-i) The width of the output tab. */ static int chars_per_output_tab = 8; -@@ -638,7 +684,13 @@ static int line_number; +@@ -637,7 +683,13 @@ static int line_number; static bool numbered_lines = false; /* (-n) Character which follows each line number. */ @@ -2401,7 +2402,7 @@ index 4c17c00..b4fab1c 100644 /* (-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; +@@ -690,6 +742,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; @@ -2409,7 +2410,7 @@ index 4c17c00..b4fab1c 100644 static char *column_separator = (char *) " "; static char *line_separator = (char *) "\t"; -@@ -853,6 +906,13 @@ separator_string (char const *optarg_S) +@@ -852,6 +905,13 @@ separator_string (char const *optarg_S) integer_overflow (); col_sep_length = len; col_sep_string = optarg_S; @@ -2423,7 +2424,7 @@ index 4c17c00..b4fab1c 100644 } int -@@ -877,6 +937,21 @@ main (int argc, char **argv) +@@ -876,6 +936,21 @@ main (int argc, char **argv) atexit (close_stdout); @@ -2445,7 +2446,7 @@ index 4c17c00..b4fab1c 100644 n_files = 0; file_names = (argc > 1 ? xnmalloc (argc - 1, sizeof (char *)) -@@ -953,8 +1028,12 @@ main (int argc, char **argv) +@@ -952,8 +1027,12 @@ main (int argc, char **argv) break; case 'e': if (optarg) @@ -2460,7 +2461,7 @@ index 4c17c00..b4fab1c 100644 /* Could check tab width > 0. */ untabify_input = true; break; -@@ -967,8 +1046,12 @@ main (int argc, char **argv) +@@ -966,8 +1045,12 @@ main (int argc, char **argv) break; case 'i': if (optarg) @@ -2475,7 +2476,7 @@ index 4c17c00..b4fab1c 100644 /* Could check tab width > 0. */ tabify_output = true; break; -@@ -986,8 +1069,8 @@ main (int argc, char **argv) +@@ -985,8 +1068,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -2486,7 +2487,7 @@ index 4c17c00..b4fab1c 100644 break; case 'N': skip_count = false; -@@ -1012,6 +1095,7 @@ main (int argc, char **argv) +@@ -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; @@ -2494,7 +2495,7 @@ index 4c17c00..b4fab1c 100644 use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1166,10 +1250,45 @@ getoptnum (char const *n_str, int min, int *num, char const *err) +@@ -1165,7 +1249,8 @@ getoptnum (char const *n_str, int min, int *num, char const *err) a number. */ static void @@ -2502,6 +2503,11 @@ index 4c17c00..b4fab1c 100644 +getoptarg (char *arg, char switch_char, char *character, int *character_length, + int *character_width, int *number) { + if (!*arg) + { +@@ -1174,7 +1259,41 @@ getoptarg (char *arg, char switch_char, char *character, int *number) + } + if (!ISDIGIT (*arg)) - *character = *arg++; + { @@ -2542,7 +2548,7 @@ index 4c17c00..b4fab1c 100644 if (*arg) { long int tmp_long; -@@ -1198,6 +1317,11 @@ static void +@@ -1203,6 +1322,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -2554,7 +2560,7 @@ index 4c17c00..b4fab1c 100644 lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1235,7 +1359,7 @@ init_parameters (int number_of_files) +@@ -1240,7 +1364,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -2563,7 +2569,7 @@ index 4c17c00..b4fab1c 100644 use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1267,11 +1391,11 @@ init_parameters (int number_of_files) +@@ -1272,11 +1396,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. */ @@ -2577,16 +2583,16 @@ index 4c17c00..b4fab1c 100644 /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1280,7 +1404,7 @@ init_parameters (int number_of_files) +@@ -1285,7 +1409,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)) +- if (ckd_mul (&sep_chars, columns - 1, col_sep_length)) ++ if (ckd_mul (&sep_chars, columns - 1, col_sep_width)) sep_chars = INT_MAX; - if (INT_SUBTRACT_WRAPV (chars_per_line - chars_used_by_number, sep_chars, - &useful_chars)) -@@ -1303,7 +1427,7 @@ init_parameters (int number_of_files) + if (ckd_sub (&useful_chars, chars_per_line - chars_used_by_number, + sep_chars)) +@@ -1308,7 +1432,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); @@ -2595,7 +2601,7 @@ index 4c17c00..b4fab1c 100644 } /* Open the necessary files, -@@ -1409,7 +1533,7 @@ init_funcs (void) +@@ -1414,7 +1538,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2604,7 +2610,7 @@ index 4c17c00..b4fab1c 100644 /* This loop takes care of all but the rightmost column. */ -@@ -1443,7 +1567,7 @@ init_funcs (void) +@@ -1448,7 +1572,7 @@ init_funcs (void) } else { @@ -2613,7 +2619,7 @@ index 4c17c00..b4fab1c 100644 h_next = h + chars_per_column; } } -@@ -1740,9 +1864,9 @@ static void +@@ -1745,9 +1869,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2625,7 +2631,7 @@ index 4c17c00..b4fab1c 100644 padding_not_printed = ANYWHERE; } -@@ -2017,13 +2141,13 @@ store_char (char c) +@@ -2021,13 +2145,13 @@ store_char (char c) /* May be too generous. */ buff = X2REALLOC (buff, &buff_allocated); } @@ -2641,7 +2647,7 @@ index 4c17c00..b4fab1c 100644 char *s; int num_width; -@@ -2040,22 +2164,24 @@ add_line_number (COLUMN *p) +@@ -2044,22 +2168,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. */ @@ -2670,7 +2676,7 @@ index 4c17c00..b4fab1c 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2214,7 +2340,7 @@ print_white_space (void) +@@ -2218,7 +2344,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2679,7 +2685,7 @@ index 4c17c00..b4fab1c 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2234,6 +2360,7 @@ print_sep_string (void) +@@ -2238,6 +2364,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -2687,7 +2693,7 @@ index 4c17c00..b4fab1c 100644 if (separators_not_printed <= 0) { -@@ -2245,6 +2372,7 @@ print_sep_string (void) +@@ -2249,6 +2376,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2695,7 +2701,7 @@ index 4c17c00..b4fab1c 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2258,12 +2386,15 @@ print_sep_string (void) +@@ -2262,12 +2390,15 @@ print_sep_string (void) } else { @@ -2712,7 +2718,7 @@ index 4c17c00..b4fab1c 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2291,7 +2422,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2295,7 +2426,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -2721,7 +2727,7 @@ index 4c17c00..b4fab1c 100644 { if (tabify_output) { -@@ -2315,6 +2446,74 @@ print_char (char c) +@@ -2319,6 +2450,74 @@ print_char (char c) putchar (c); } @@ -2796,7 +2802,7 @@ index 4c17c00..b4fab1c 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2492,9 +2691,9 @@ read_line (COLUMN *p) +@@ -2496,9 +2695,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2808,7 +2814,7 @@ index 4c17c00..b4fab1c 100644 padding_not_printed = ANYWHERE; } -@@ -2563,7 +2762,7 @@ print_stored (COLUMN *p) +@@ -2567,7 +2766,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -2817,7 +2823,7 @@ index 4c17c00..b4fab1c 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2575,7 +2774,7 @@ print_stored (COLUMN *p) +@@ -2579,7 +2778,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2826,7 +2832,7 @@ index 4c17c00..b4fab1c 100644 pad_vertically = true; -@@ -2595,9 +2794,9 @@ print_stored (COLUMN *p) +@@ -2599,9 +2798,9 @@ print_stored (COLUMN *p) } } @@ -2838,7 +2844,7 @@ index 4c17c00..b4fab1c 100644 padding_not_printed = ANYWHERE; } -@@ -2610,8 +2809,8 @@ print_stored (COLUMN *p) +@@ -2614,8 +2813,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2849,7 +2855,7 @@ index 4c17c00..b4fab1c 100644 } return true; -@@ -2630,7 +2829,7 @@ print_stored (COLUMN *p) +@@ -2634,7 +2833,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2858,7 +2864,7 @@ index 4c17c00..b4fab1c 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2640,10 +2839,10 @@ char_to_clump (char c) +@@ -2644,10 +2843,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2871,7 +2877,7 @@ index 4c17c00..b4fab1c 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2724,6 +2923,164 @@ char_to_clump (char c) +@@ -2728,6 +2927,164 @@ char_to_clump (char c) return chars; } @@ -3037,13 +3043,13 @@ index 4c17c00..b4fab1c 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 3b775d6..a0ba243 100644 +index e779845..1f5c337 100644 --- a/src/sort.c +++ b/src/sort.c -@@ -29,6 +29,14 @@ +@@ -28,6 +28,14 @@ + #include #include #include - #include +#if HAVE_WCHAR_H +# include +#endif @@ -3054,8 +3060,8 @@ index 3b775d6..a0ba243 100644 + #include "system.h" #include "argmatch.h" - #include "die.h" -@@ -159,14 +167,39 @@ static int thousands_sep; + #include "assure.h" +@@ -157,14 +165,39 @@ static int thousands_sep; /* We currently ignore multi-byte grouping chars. */ static bool thousands_sep_ignored; @@ -3096,7 +3102,7 @@ index 3b775d6..a0ba243 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -343,13 +376,11 @@ static bool stable; +@@ -341,13 +374,11 @@ static bool stable; /* An int value outside char range. */ enum { NON_CHAR = CHAR_MAX + 1 }; @@ -3113,7 +3119,7 @@ index 3b775d6..a0ba243 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -805,6 +836,46 @@ reap_all (void) +@@ -803,6 +834,46 @@ reap_all (void) reap (-1); } @@ -3160,7 +3166,7 @@ index 3b775d6..a0ba243 100644 /* Clean up any remaining temporary files. */ static void -@@ -1272,7 +1343,7 @@ zaptemp (char const *name) +@@ -1270,7 +1341,7 @@ zaptemp (char const *name) free (node); } @@ -3169,7 +3175,7 @@ index 3b775d6..a0ba243 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1287,7 +1358,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1285,7 +1356,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3178,7 +3184,7 @@ index 3b775d6..a0ba243 100644 { size_t i; -@@ -1299,7 +1370,7 @@ inittables (void) +@@ -1297,7 +1368,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3187,7 +3193,7 @@ index 3b775d6..a0ba243 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1381,6 +1452,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1379,6 +1450,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3272,7 +3278,7 @@ index 3b775d6..a0ba243 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1612,7 +1761,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1610,7 +1759,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3281,7 +3287,7 @@ index 3b775d6..a0ba243 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1621,10 +1770,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1619,10 +1768,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3294,7 +3300,7 @@ index 3b775d6..a0ba243 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1648,12 +1797,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3367,7 +3373,7 @@ index 3b775d6..a0ba243 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1670,10 +1878,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1668,10 +1876,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3380,7 +3386,7 @@ index 3b775d6..a0ba243 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1717,10 +1925,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3393,7 +3399,7 @@ index 3b775d6..a0ba243 100644 if (newlim) lim = newlim; } -@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1751,6 +1959,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3524,7 +3530,7 @@ index 3b775d6..a0ba243 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1839,8 +2171,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1837,8 +2169,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3549,7 +3555,7 @@ index 3b775d6..a0ba243 100644 line->keybeg = line_start; } } -@@ -1978,12 +2324,10 @@ find_unit_order (char const *number) +@@ -1976,12 +2322,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3565,7 +3571,7 @@ index 3b775d6..a0ba243 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1995,7 +2339,7 @@ human_numcompare (char const *a, char const *b) +@@ -1993,7 +2337,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3574,7 +3580,7 @@ index 3b775d6..a0ba243 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2005,6 +2349,25 @@ numcompare (char const *a, char const *b) +@@ -2003,6 +2347,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3600,7 +3606,7 @@ index 3b775d6..a0ba243 100644 static int nan_compare (long double a, long double b) { -@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2044,7 +2407,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3609,7 +3615,7 @@ index 3b775d6..a0ba243 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2322,15 +2685,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2320,15 +2683,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3627,7 +3633,7 @@ index 3b775d6..a0ba243 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2476,7 +2838,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2474,7 +2836,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3636,7 +3642,7 @@ index 3b775d6..a0ba243 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2524,9 +2886,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2522,9 +2884,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3649,7 +3655,7 @@ index 3b775d6..a0ba243 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2537,9 +2899,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2535,9 +2897,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3662,7 +3668,7 @@ index 3b775d6..a0ba243 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2547,19 +2909,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2545,19 +2907,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3686,7 +3692,7 @@ index 3b775d6..a0ba243 100644 } } -@@ -2570,7 +2932,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2568,7 +2930,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) { error (0, 0, _("%snumbers use %s as a decimal point in this locale"), @@ -3695,7 +3701,7 @@ index 3b775d6..a0ba243 100644 quote (((char []) {decimal_point, 0}))); } -@@ -2612,11 +2974,87 @@ diff_reversed (int diff, bool reversed) +@@ -2610,11 +2972,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3784,16 +3790,16 @@ index 3b775d6..a0ba243 100644 { struct keyfield *key = keylist; -@@ -2697,7 +3135,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2695,7 +3133,7 @@ keycompare (struct line const *a, struct line const *b) 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); +- diff = getmonth (ta, nullptr) - getmonth (tb, nullptr); ++ diff = getmonth (ta, tlena, nullptr) - getmonth (tb, tlenb, nullptr); else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2807,6 +3245,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2805,6 +3243,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -4005,7 +4011,7 @@ index 3b775d6..a0ba243 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2834,7 +3477,7 @@ compare (struct line const *a, struct line const *b) +@@ -2832,7 +3475,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -4014,7 +4020,7 @@ index 3b775d6..a0ba243 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4222,6 +4865,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4220,6 +4863,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -4022,7 +4028,7 @@ index 3b775d6..a0ba243 100644 break; case 'g': key->general_numeric = true; -@@ -4301,7 +4945,7 @@ main (int argc, char **argv) +@@ -4299,7 +4943,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4031,7 +4037,7 @@ index 3b775d6..a0ba243 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4324,6 +4968,29 @@ main (int argc, char **argv) +@@ -4322,6 +4966,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4061,7 +4067,7 @@ index 3b775d6..a0ba243 100644 have_read_stdin = false; inittables (); -@@ -4598,13 +5265,34 @@ main (int argc, char **argv) +@@ -4592,13 +5259,34 @@ main (int argc, char **argv) case 't': { @@ -4071,7 +4077,7 @@ index 3b775d6..a0ba243 100644 + size_t newtab_length = 1; + strncpy (newtab, optarg, MB_LEN_MAX); + if (! newtab[0]) - die (SORT_FAILURE, 0, _("empty tab")); + error (SORT_FAILURE, 0, _("empty tab")); - if (optarg[1]) +#if HAVE_MBRTOWC + if (MB_CUR_MAX > 1) @@ -4100,14 +4106,14 @@ index 3b775d6..a0ba243 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4615,9 +5303,11 @@ main (int argc, char **argv) - quote (optarg)); +@@ -4609,9 +5297,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")); + error (SORT_FAILURE, 0, _("incompatible tabs")); - tab = newtab; + memcpy (tab, newtab, newtab_length); + tab_length = newtab_length; @@ -4115,7 +4121,7 @@ index 3b775d6..a0ba243 100644 break; diff --git a/src/unexpand.c b/src/unexpand.c -index 7d6100f..04cd646 100644 +index 5a2283f..f24ef76 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -38,6 +38,9 @@ @@ -4126,12 +4132,12 @@ index 7d6100f..04cd646 100644 +#include + #include "system.h" - #include "die.h" + #include "expand-common.h" -@@ -106,24 +109,47 @@ unexpand (void) +@@ -104,24 +107,47 @@ unexpand (void) { /* Input stream. */ - FILE *fp = next_file (NULL); + FILE *fp = next_file (nullptr); + mb_file_t mbf; /* The array of pending blanks. In non-POSIX locales, blanks can @@ -4179,7 +4185,7 @@ index 7d6100f..04cd646 100644 /* If true, perform translations. */ bool convert = true; -@@ -157,12 +183,44 @@ unexpand (void) +@@ -155,12 +181,44 @@ unexpand (void) do { @@ -4227,9 +4233,9 @@ index 7d6100f..04cd646 100644 if (blank) { -@@ -179,16 +237,16 @@ unexpand (void) +@@ -177,16 +235,16 @@ unexpand (void) if (next_tab_column < column) - die (EXIT_FAILURE, 0, _("input line is too long")); + error (EXIT_FAILURE, 0, _("input line is too long")); - if (c == '\t') + if (mb_iseq (c, '\t')) @@ -4247,7 +4253,7 @@ index 7d6100f..04cd646 100644 if (! (prev_blank && column == next_tab_column)) { -@@ -196,13 +254,14 @@ unexpand (void) +@@ -194,13 +252,14 @@ unexpand (void) will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -4264,7 +4270,7 @@ index 7d6100f..04cd646 100644 } /* Discard pending blanks, unless it was a single -@@ -210,7 +269,7 @@ unexpand (void) +@@ -208,7 +267,7 @@ unexpand (void) pending = one_blank_before_tab_stop; } } @@ -4273,7 +4279,7 @@ index 7d6100f..04cd646 100644 { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -220,16 +279,20 @@ unexpand (void) +@@ -218,16 +277,20 @@ unexpand (void) } else { @@ -4282,7 +4288,7 @@ index 7d6100f..04cd646 100644 + const uintmax_t orig_column = column; + column += mb_width (c); + if (column < orig_column) - die (EXIT_FAILURE, 0, _("input line is too long")); + error (EXIT_FAILURE, 0, _("input line is too long")); } if (pending) @@ -4295,10 +4301,10 @@ index 7d6100f..04cd646 100644 + for (int n = 0; n < pending; ++n) + mb_putc (pending_blank[n], stdout); + if (ferror (stdout)) - die (EXIT_FAILURE, errno, _("write error")); + write_error (); pending = 0; one_blank_before_tab_stop = false; -@@ -239,16 +302,17 @@ unexpand (void) +@@ -237,16 +300,17 @@ unexpand (void) convert &= convert_entire_line || blank; } @@ -4312,7 +4318,7 @@ index 7d6100f..04cd646 100644 - if (putchar (c) < 0) + mb_putc (c, stdout); + if (ferror (stdout)) - die (EXIT_FAILURE, errno, _("write error")); + write_error (); } - while (c != '\n'); + while (!mb_iseq (c, '\n')); @@ -4320,7 +4326,7 @@ index 7d6100f..04cd646 100644 } diff --git a/src/uniq.c b/src/uniq.c -index e5996f0..871d47c 100644 +index fab04de..2e96dcb 100644 --- a/src/uniq.c +++ b/src/uniq.c @@ -21,6 +21,17 @@ @@ -4341,7 +4347,7 @@ index e5996f0..871d47c 100644 #include "system.h" #include "argmatch.h" #include "linebuffer.h" -@@ -33,6 +44,18 @@ +@@ -31,6 +42,18 @@ #include "memcasecmp.h" #include "quote.h" @@ -4360,7 +4366,7 @@ index e5996f0..871d47c 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "uniq" -@@ -139,6 +162,10 @@ enum +@@ -137,6 +160,10 @@ enum GROUP_OPTION = CHAR_MAX + 1 }; @@ -4370,8 +4376,8 @@ index e5996f0..871d47c 100644 + static struct option const longopts[] = { - {"count", no_argument, NULL, 'c'}, -@@ -254,7 +281,7 @@ size_opt (char const *opt, char const *msgid) + {"count", no_argument, nullptr, 'c'}, +@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *msgid) ATTRIBUTE_PURE static char * @@ -4380,7 +4386,7 @@ index e5996f0..871d47c 100644 { size_t count; char const *lp = line->buffer; -@@ -274,6 +301,83 @@ find_field (struct linebuffer const *line) +@@ -272,6 +299,83 @@ find_field (struct linebuffer const *line) return line->buffer + i; } @@ -4464,7 +4470,7 @@ index e5996f0..871d47c 100644 /* 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. -@@ -494,6 +598,19 @@ main (int argc, char **argv) +@@ -495,6 +599,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4485,7 +4491,7 @@ index e5996f0..871d47c 100644 skip_fields = 0; check_chars = SIZE_MAX; diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm -index fad7ab9..c9021a6 100644 +index f147401..3ce5da9 100644 --- a/tests/Coreutils.pm +++ b/tests/Coreutils.pm @@ -269,6 +269,9 @@ sub run_tests ($$$$$) @@ -4723,19 +4729,19 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 0f77786..dbe1843 100644 +index b74a4a2..fe6e557 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -381,6 +381,8 @@ all_tests = \ - tests/misc/sort-discrim.sh \ - tests/misc/sort-files0-from.pl \ - tests/misc/sort-float.sh \ +@@ -384,6 +384,8 @@ all_tests = \ + tests/sort/sort-discrim.sh \ + tests/sort/sort-files0-from.pl \ + tests/sort/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 \ -@@ -582,6 +584,7 @@ all_tests = \ + tests/sort/sort-h-thousands-sep.sh \ + tests/sort/sort-merge.pl \ + tests/sort/sort-merge-fdlimit.sh \ +@@ -585,6 +587,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4743,7 +4749,7 @@ index 0f77786..dbe1843 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -734,6 +737,7 @@ all_tests = \ +@@ -738,6 +741,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4752,7 +4758,7 @@ index 0f77786..dbe1843 100644 # See tests/factor/create-test.sh. diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index 7a77e6f..27f6652 100755 +index 06261ac..7dd813e 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -4819,7 +4825,7 @@ index 7a77e6f..27f6652 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 2834f92..bc1616a 100755 +index a94072f..136a82e 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; @@ -4892,7 +4898,7 @@ index 2834f92..bc1616a 100755 my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; diff --git a/tests/misc/join.pl b/tests/misc/join.pl -index 06ad777..be40204 100755 +index 2ca8567..1d01a3d 100755 --- a/tests/misc/join.pl +++ b/tests/misc/join.pl @@ -25,6 +25,15 @@ my $limits = getlimits (); @@ -5012,10 +5018,136 @@ index 0000000..11836ba +compare exp out || { fail=1; cat out; } + +Exit $fail -diff --git a/tests/misc/sort-merge.pl b/tests/misc/sort-merge.pl -index 7eb4574..eda884c 100755 ---- a/tests/misc/sort-merge.pl -+++ b/tests/misc/sort-merge.pl +diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl +index d78a1bc..2b9137d 100755 +--- a/tests/misc/unexpand.pl ++++ b/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}; + +diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl +index eafc13d..c1eca2a 100755 +--- a/tests/pr/pr-tests.pl ++++ b/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 +@@ -515,8 +524,48 @@ push @Tests, + {IN=>"x\tx\tx\tx\tx\nx\tx\tx\tx\tx\n"}, + {OUT=>"x\tx\tx\tx\tx\tx\tx\tx\tx\tx\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}; + +diff --git a/tests/sort/sort-merge.pl b/tests/sort/sort-merge.pl +index bd439ef..2ccdf87 100755 +--- a/tests/sort/sort-merge.pl ++++ b/tests/sort/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; @@ -5072,10 +5204,10 @@ index 7eb4574..eda884c 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff --git a/tests/misc/sort.pl b/tests/misc/sort.pl -index 0b0adca..fd27821 100755 ---- a/tests/misc/sort.pl -+++ b/tests/misc/sort.pl +diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl +index 46f1d7a..bb38f5b 100755 +--- a/tests/sort/sort.pl ++++ b/tests/sort/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; @@ -5140,208 +5272,6 @@ index 0b0adca..fd27821 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 2e1906f..fe66012 100755 ---- a/tests/misc/unexpand.pl -+++ b/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}; - -diff --git a/tests/misc/uniq.pl b/tests/misc/uniq.pl -index aa163cd..91d617d 100755 ---- a/tests/misc/uniq.pl -+++ b/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; - -diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index 7ac6d4c..ae6cc35 100755 ---- a/tests/pr/pr-tests.pl -+++ b/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 -@@ -512,8 +521,48 @@ push @Tests, - {IN=>"x\tx\tx\tx\tx\nx\tx\tx\tx\tx\n"}, - {OUT=>"x\tx\tx\tx\tx\tx\tx\tx\tx\tx\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}; - diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh new file mode 100755 index 0000000..8a82d74 @@ -5520,6 +5450,82 @@ index 0000000..8a82d74 + +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 +diff --git a/tests/uniq/uniq.pl b/tests/uniq/uniq.pl +index a6354dc..e43cd6e 100755 +--- a/tests/uniq/uniq.pl ++++ b/tests/uniq/uniq.pl +@@ -23,9 +23,17 @@ my $limits = getlimits (); + my $prog = 'uniq'; + my $try = "Try '$prog --help' for more information.\n"; + ++my $inval = "$prog: invalid byte, character or field list\n$try"; ++ + # Turn off localization of executable's output. + @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; + ++my $mb_locale; ++#Comment out next line to disable multibyte tests ++$mb_locale = $ENV{LOCALE_FR_UTF8}; ++! defined $mb_locale || $mb_locale eq 'none' ++ and $mb_locale = 'C'; ++ + # When possible, create a "-z"-testing variant of each test. + sub add_z_variants($) + { +@@ -262,6 +270,53 @@ foreach my $t (@Tests) + and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; + } + ++if ($mb_locale ne 'C') ++ { ++ # Duplicate each test vector, appending "-mb" to the test name and ++ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we ++ # provide coverage for the distro-added multi-byte code paths. ++ my @new; ++ foreach my $t (@Tests) ++ { ++ my @new_t = @$t; ++ my $test_name = shift @new_t; ++ ++ # Depending on whether uniq is multi-byte-patched, ++ # it emits different diagnostics: ++ # non-MB: invalid byte or field list ++ # MB: invalid byte, character or field list ++ # Adjust the expected error output accordingly. ++ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} ++ (@new_t)) ++ { ++ my $sub = {ERR_SUBST => 's/, character//'}; ++ push @new_t, $sub; ++ push @$t, $sub; ++ } ++ # In test #145, replace the each ‘...’ by '...'. ++ if ($test_name =~ "145") ++ { ++ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; ++ push @new_t, $sub; ++ push @$t, $sub; ++ } ++ next if ( $test_name =~ "schar" ++ or $test_name =~ "^obs-plus" ++ or $test_name =~ "119"); ++ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; ++ } ++ push @Tests, @new; ++ } ++ ++# Remember that triple_test creates from each test with exactly one "IN" ++# file two more tests (.p and .r suffix on name) corresponding to reading ++# input from a file and from a pipe. The pipe-reading test would fail ++# due to a race condition about 1 in 20 times. ++# Remove the IN_PIPE version of the "output-is-input" test above. ++# The others aren't susceptible because they have three inputs each. ++ ++@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; ++ + @Tests = add_z_variants \@Tests; + @Tests = triple_test \@Tests; + -- -2.34.1 +2.41.0 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 7136f3f..66e06e1 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,6 +1,6 @@ -From d70ddb3eb845c494280e7365e2b889242e7e1bb9 Mon Sep 17 00:00:00 2001 +From 88ba186955add2b230c017749d5622f7a0d62177 Mon Sep 17 00:00:00 2001 From: rpm-build -Date: Mon, 4 Oct 2021 08:45:53 +0200 +Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-selinux.patch --- @@ -9,19 +9,19 @@ Subject: [PATCH] coreutils-selinux.patch 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cp.c b/src/cp.c -index c97a675..89fb8ec 100644 +index 04a5cbe..7a364e5 100644 --- a/src/cp.c +++ b/src/cp.c -@@ -952,7 +952,7 @@ main (int argc, char **argv) +@@ -989,7 +989,7 @@ main (int argc, char **argv) selinux_enabled = (0 < is_selinux_enabled ()); cp_option_init (&x); - while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ", + while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ", - long_opts, NULL)) + long_opts, nullptr)) != -1) { -@@ -1000,6 +1000,23 @@ main (int argc, char **argv) +@@ -1041,6 +1041,23 @@ main (int argc, char **argv) copy_contents = true; break; @@ -46,19 +46,19 @@ index c97a675..89fb8ec 100644 x.preserve_links = true; x.dereference = DEREF_NEVER; diff --git a/src/install.c b/src/install.c -index c9456fe..2b1bee9 100644 +index 31a48f1..ce9fa2d 100644 --- a/src/install.c +++ b/src/install.c -@@ -794,7 +794,7 @@ main (int argc, char **argv) +@@ -807,7 +807,7 @@ main (int argc, char **argv) dir_arg = false; umask (0); - while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z", long_options, + while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z", long_options, - NULL)) != -1) + nullptr)) + != -1) { - switch (optc) -@@ -855,6 +855,9 @@ main (int argc, char **argv) +@@ -872,6 +872,9 @@ main (int argc, char **argv) no_target_directory = true; break; @@ -68,7 +68,7 @@ index c9456fe..2b1bee9 100644 case PRESERVE_CONTEXT_OPTION: if (! selinux_enabled) { -@@ -862,6 +865,13 @@ main (int argc, char **argv) +@@ -879,6 +882,13 @@ main (int argc, char **argv) "this kernel is not SELinux-enabled")); break; } @@ -83,5 +83,5 @@ index c9456fe..2b1bee9 100644 use_default_selinux_context = false; break; -- -2.31.1 +2.41.0 diff --git a/coreutils.spec b/coreutils.spec index 39bc384..9c250d0 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,8 +1,9 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.3 -Release: 2%{?dist} -License: GPL-3.0-or-later +Version: 9.4 +Release: 1%{?dist} +# some used parts of gnulib are under various variants of LGPL +License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz Source1: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz.sig @@ -13,9 +14,6 @@ Source50: supported_utils Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh -# revert a gnulib patch that broke the build -Patch1: coreutils-9.3-gnulib-strtol.patch - # do not make coreutils-single depend on /usr/bin/coreutils %global __requires_exclude ^%{_bindir}/coreutils$ @@ -31,6 +29,9 @@ Patch102: coreutils-8.32-DIR_COLORS.patch # df --direct Patch104: coreutils-df-direct.patch +# fix crash with --enable-systemd +Patch105: coreutils-9.4-systemd-coredump.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -176,6 +177,7 @@ for type in separate single; do --cache-file=../config.cache \ --enable-install-program=arch \ --enable-no-install-program=kill,uptime \ + --enable-systemd \ --with-tty-group \ DEFAULT_POSIX2_VERSION=200112 alternative=199209 || : %make_build all V=1 @@ -254,6 +256,11 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Sep 15 2023 Lukáš Zaoral - 9.4-1 +- new upstream release 9.4 (#2235759) +- enable integration with systemd +- fix the license field + * Wed Jul 19 2023 Fedora Release Engineering - 9.3-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild diff --git a/sources b/sources index f5e06f7..ac58478 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.3.tar.xz) = 242271f212a6860bdc6c8d7e5c4f85ce66c1b48ef781aca9daa56e0fe7c2b7809ef72b4392120219fe5b687637c83ce89ceef8bb35f6274f43f8f968a6901694 -SHA512 (coreutils-9.3.tar.xz.sig) = 522a2072f8ef940228ccdd856a4041c3c16b98e309168ccf2066fe7c1013685ba6cdea8a7317dfa1f4507b37ca016ecedaf54438d4a5007927b0e1a8fd223eb5 +SHA512 (coreutils-9.4.tar.xz) = 7c55ee23b685a0462bbbd118b04d25278c902604a0dcf3bf4f8bf81faa0500dee5a7813cba6f586d676c98e520cafd420f16479619305e94ea6798d8437561f5 +SHA512 (coreutils-9.4.tar.xz.sig) = 9674f783f592c4f3e5c708ff31426ac009bf132fd0005019571bf39c8a1627efb5351c6cecc7faecb1eff8fa2970318666593bffc0eda9c750159e174ef42524 From b851cbdafc20d965779fab53972fd92679f0bbe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Thu, 18 Jan 2024 15:34:40 +0100 Subject: [PATCH 490/523] fix buffer overflow in split Resolves: CVE-2024-0684 --- coreutils-9.4-CVE-2024-0684.patch | 31 +++++++++++++++++++++++++++++++ coreutils.spec | 8 +++++++- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.4-CVE-2024-0684.patch diff --git a/coreutils-9.4-CVE-2024-0684.patch b/coreutils-9.4-CVE-2024-0684.patch new file mode 100644 index 0000000..64583af --- /dev/null +++ b/coreutils-9.4-CVE-2024-0684.patch @@ -0,0 +1,31 @@ +From c4c5ed8f4e9cd55a12966d4f520e3a13101637d9 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Tue, 16 Jan 2024 13:48:32 -0800 +Subject: [PATCH] split: do not shrink hold buffer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* src/split.c (line_bytes_split): Do not shrink hold buffer. +If it’s large for this batch it’s likely to be large for the next +batch, and for ‘split’ it’s not worth the complexity/CPU hassle to +shrink it. Do not assume hold_size can be bufsize. +--- + src/split.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/src/split.c b/src/split.c +index 64020c859..037960a59 100644 +--- a/src/split.c ++++ b/src/split.c +@@ -809,10 +809,7 @@ line_bytes_split (intmax_t n_bytes, char *buf, idx_t bufsize) + { + cwrite (n_out == 0, hold, n_hold); + n_out += n_hold; +- if (n_hold > bufsize) +- hold = xirealloc (hold, bufsize); + n_hold = 0; +- hold_size = bufsize; + } + + /* Output to eol if present. */ diff --git a/coreutils.spec b/coreutils.spec index 9c250d0..3925ef0 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.4 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,6 +32,9 @@ Patch104: coreutils-df-direct.patch # fix crash with --enable-systemd Patch105: coreutils-9.4-systemd-coredump.patch +# fix buffer overflow in split (CVE-2024-0684) +Patch106: coreutils-9.4-CVE-2024-0684.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -256,6 +259,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jan 18 2024 Lukáš Zaoral - 9.4-2 +- fix buffer overflow in split (CVE-2024-0684) + * Fri Sep 15 2023 Lukáš Zaoral - 9.4-1 - new upstream release 9.4 (#2235759) - enable integration with systemd From bf7dfdb2cef475584453921b4b2de66091059aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Thu, 18 Jan 2024 16:52:09 +0100 Subject: [PATCH 491/523] fix compilation on i686 --- coreutils-i18n.patch | 191 +++++++++++++++++++++++++------------------ coreutils.spec | 5 +- 2 files changed, 114 insertions(+), 82 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 6a29fe2..be8e0b1 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -7,8 +7,8 @@ Subject: [PATCH] coreutils-i18n.patch bootstrap.conf | 1 + configure.ac | 6 + lib/linebuffer.h | 8 + - lib/mbfile.c | 3 + - lib/mbfile.h | 255 ++++++++++++ + lib/mbfile.c | 20 + + lib/mbfile.h | 267 ++++++++++++ m4/mbfile.m4 | 14 + src/cut.c | 508 +++++++++++++++++++++-- src/expand-common.c | 114 ++++++ @@ -35,7 +35,7 @@ Subject: [PATCH] coreutils-i18n.patch tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ tests/uniq/uniq.pl | 55 +++ - 31 files changed, 3703 insertions(+), 242 deletions(-) + 31 files changed, 3732 insertions(+), 242 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -101,34 +101,51 @@ index b4cc8e4..f2bbb52 100644 /* Initialize linebuffer LINEBUFFER for use. */ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 -index 0000000..b0a468e +index 0000000..8d2957b --- /dev/null +++ b/lib/mbfile.c -@@ -0,0 +1,3 @@ +@@ -0,0 +1,20 @@ ++/* Multibyte character I/O: macros for multi-byte encodings. ++ Copyright (C) 2012-2023 Free Software Foundation, Inc. ++ ++ This file is free software: you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation, either version 3 of the ++ License, or (at your option) any later version. ++ ++ This file is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with this program. If not, see . */ ++ +#include ++ +#define MBFILE_INLINE _GL_EXTERN_INLINE +#include "mbfile.h" diff --git a/lib/mbfile.h b/lib/mbfile.h new file mode 100644 -index 0000000..11f1b12 +index 0000000..ad61c19 --- /dev/null +++ b/lib/mbfile.h -@@ -0,0 +1,255 @@ +@@ -0,0 +1,267 @@ +/* Multibyte character I/O: macros for multi-byte encodings. -+ Copyright (C) 2001, 2005, 2009-2015 Free Software Foundation, Inc. ++ Copyright (C) 2001, 2005, 2009-2023 Free Software Foundation, Inc. + -+ This program is free software: you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. ++ This file is free software: you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation, either version 3 of the ++ License, or (at your option) any later version. + -+ This program is distributed in the hope that it will be useful, ++ This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. ++ GNU Lesser 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 . */ ++ You should have received a copy of the GNU Lesser General Public License ++ along with this program. If not, see . */ + +/* Written by Mitsuru Chinen + and Bruno Haible . */ @@ -163,24 +180,18 @@ index 0000000..11f1b12 +#ifndef _MBFILE_H +#define _MBFILE_H 1 + ++/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ ++#if !_GL_CONFIG_H_INCLUDED ++ #error "Please include config.h first." ++#endif ++ +#include -+#include +#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 @@ -199,6 +210,7 @@ index 0000000..11f1b12 +MBFILE_INLINE void +mbfile_multi_getc (struct mbchar *mbc, struct mbfile_multi *mbf) +{ ++ unsigned int new_bufcount; + size_t bytes; + + /* If EOF has already been seen, don't use getc. This matters if @@ -214,64 +226,70 @@ index 0000000..11f1b12 + return; + } + -+ /* Before using mbrtowc, we need at least one byte. */ -+ if (mbf->bufcount == 0) ++ new_bufcount = mbf->bufcount; ++ ++ /* If mbf->state is not in an initial state, some more 32-bit wide character ++ may be hiding in the state. We need to call mbrtoc32 again. */ ++ #if GNULIB_MBRTOC32_REGULAR ++ assert (mbsinit (&mbf->state)); ++ #else ++ if (mbsinit (&mbf->state)) ++ #endif + { -+ int c = getc (mbf->fp); -+ if (c == EOF) ++ /* Before using mbrtoc32, we need at least one byte. */ ++ if (new_bufcount == 0) + { -+ mbf->eof_seen = true; -+ goto eof; ++ int c = getc (mbf->fp); ++ if (c == EOF) ++ { ++ mbf->eof_seen = true; ++ goto eof; ++ } ++ mbf->buf[0] = (unsigned char) c; ++ new_bufcount++; ++ } ++ ++ /* Handle most ASCII characters quickly, without calling mbrtoc32(). */ ++ if (new_bufcount == 1 && is_basic (mbf->buf[0])) ++ { ++ /* These characters are part of the POSIX portable character set. ++ For most of them, namely those in the ISO C basic character set, ++ ISO C 99 guarantees that their wide character code is identical to ++ their char code. For the few other ones, this is the case as well, ++ in all locale encodings that are in use. The 32-bit wide character ++ code is the same as well. */ ++ mbc->wc = mbc->buf[0] = mbf->buf[0]; ++ mbc->wc_valid = true; ++ mbc->ptr = &mbc->buf[0]; ++ mbc->bytes = 1; ++ mbf->bufcount = 0; ++ return; + } -+ 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 ++ /* Use mbrtoc32 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); ++ /* Feed the bytes one by one into mbrtoc32. */ ++ bytes = mbrtoc32 (&mbc->wc, &mbf->buf[mbf->bufcount], new_bufcount - mbf->bufcount, &mbf->state); + + if (bytes == (size_t) -1) + { + /* An invalid multibyte sequence was encountered. */ ++ mbf->bufcount = new_bufcount; + /* Return a single byte. */ + bytes = 1; + mbc->wc_valid = false; ++ /* Allow the next invocation to continue from a sane state. */ ++ mbszero (&mbf->state); + break; + } + else if (bytes == (size_t) -2) + { + /* An incomplete multibyte character. */ -+ mbf->state = backup_state; ++ mbf->bufcount = new_bufcount; + if (mbf->bufcount == MBCHAR_BUF_SIZE) + { + /* An overlong incomplete multibyte sequence was encountered. */ @@ -282,28 +300,42 @@ index 0000000..11f1b12 + } + else + { -+ /* Read one more byte and retry mbrtowc. */ ++ /* Read one more byte and retry mbrtoc32. */ + int c = getc (mbf->fp); + if (c == EOF) + { + /* An incomplete multibyte character at the end. */ + mbf->eof_seen = true; -+ bytes = mbf->bufcount; ++ bytes = new_bufcount; + mbc->wc_valid = false; + break; + } -+ mbf->buf[mbf->bufcount] = (unsigned char) c; -+ mbf->bufcount++; ++ mbf->buf[new_bufcount] = (unsigned char) c; ++ new_bufcount++; + } + } + else + { -+ if (bytes == 0) ++ #if !GNULIB_MBRTOC32_REGULAR ++ if (bytes == (size_t) -3) + { -+ /* A null wide character was encountered. */ -+ bytes = 1; -+ assert (mbf->buf[0] == '\0'); -+ assert (mbc->wc == 0); ++ /* The previous multibyte sequence produced an additional 32-bit ++ wide character. */ ++ mbf->bufcount = new_bufcount; ++ bytes = 0; ++ } ++ else ++ #endif ++ { ++ bytes = mbf->bufcount + bytes; ++ mbf->bufcount = new_bufcount; ++ if (bytes == 0) ++ { ++ /* A null 32-bit wide character was encountered. */ ++ bytes = 1; ++ assert (mbf->buf[0] == '\0'); ++ assert (mbc->wc == 0); ++ } + } + mbc->wc_valid = true; + break; @@ -354,7 +386,7 @@ index 0000000..11f1b12 + ((mbf).fp = (stream), \ + (mbf).eof_seen = false, \ + (mbf).have_pushback = false, \ -+ memset (&(mbf).state, '\0', sizeof (mbstate_t)), \ ++ mbszero (&(mbf).state), \ + (mbf).bufcount = 0) + +#define mbf_getc(mbc, mbf) mbfile_multi_getc (&(mbc), &(mbf)) @@ -363,20 +395,17 @@ index 0000000..11f1b12 + +#define mb_iseof(mbc) ((mbc).bytes == 0) + -+#ifndef _GL_INLINE_HEADER_BEGIN -+ #error "Please include config.h first." -+#endif -+_GL_INLINE_HEADER_BEGIN ++_GL_INLINE_HEADER_END + +#endif /* _MBFILE_H */ diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 -index 0000000..8589902 +index 0000000..83068a9 --- /dev/null +++ b/m4/mbfile.m4 @@ -0,0 +1,14 @@ +# mbfile.m4 serial 7 -+dnl Copyright (C) 2005, 2008-2015 Free Software Foundation, Inc. ++dnl Copyright (C) 2005, 2008-2023 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. @@ -5527,5 +5556,5 @@ index a6354dc..e43cd6e 100755 @Tests = triple_test \@Tests; -- -2.41.0 +2.43.0 diff --git a/coreutils.spec b/coreutils.spec index 3925ef0..3b27c5b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.4 -Release: 2%{?dist} +Release: 3%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -259,6 +259,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jan 18 2024 Lukáš Zaoral - 9.4-3 +- fix compilation on i686 + * Thu Jan 18 2024 Lukáš Zaoral - 9.4-2 - fix buffer overflow in split (CVE-2024-0684) From fd8859df682458627de8c938cd270ee61e292ea6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 19 Jan 2024 16:11:56 +0000 Subject: [PATCH 492/523] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 3b27c5b..142c287 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.4 -Release: 3%{?dist} +Release: 4%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -259,6 +259,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Jan 19 2024 Fedora Release Engineering - 9.4-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Thu Jan 18 2024 Lukáš Zaoral - 9.4-3 - fix compilation on i686 From f6a44b3f1fc3cb9f5ee4964e1584db5d183d784d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 24 Jan 2024 08:06:26 +0000 Subject: [PATCH 493/523] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 142c287..5cfc1dc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.4 -Release: 4%{?dist} +Release: 5%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -259,6 +259,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jan 24 2024 Fedora Release Engineering - 9.4-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Fri Jan 19 2024 Fedora Release Engineering - 9.4-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From 245be9f408548ef9ab96b5ae6d8f8a6c8eb9dd80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 29 Jan 2024 15:31:10 +0100 Subject: [PATCH 494/523] fix tail on kernels with 64k page size Resolves: RHEL-22866 --- coreutils-9.4-tail-64k-pages.patch | 205 +++++++++++++++++++++++++++++ coreutils.spec | 8 +- 2 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.4-tail-64k-pages.patch diff --git a/coreutils-9.4-tail-64k-pages.patch b/coreutils-9.4-tail-64k-pages.patch new file mode 100644 index 0000000..1165f7b --- /dev/null +++ b/coreutils-9.4-tail-64k-pages.patch @@ -0,0 +1,205 @@ +From 73d119f4f8052a9fb6cef13cd9e75d5a4e23311a Mon Sep 17 00:00:00 2001 +From: dann frazier +Date: Wed, 29 Nov 2023 18:32:34 -0700 +Subject: [PATCH] tail: fix tailing sysfs files where PAGE_SIZE > BUFSIZ + +* src/tail.c (file_lines): Ensure we use a buffer size >= PAGE_SIZE when +searching backwards to avoid seeking within a file, +which on sysfs files is accepted but also returns no data. +* tests/tail/tail-sysfs.sh: Add a new test. +* tests/local.mk: Reference the new test. +* NEWS: Mention the bug fix. +Fixes https://bugs.gnu.org/67490 + +Upstream-commit: 73d119f4f8052a9fb6cef13cd9e75d5a4e23311a +Cherry-picked-by: Lukáš Zaoral +--- + src/tail.c | 57 +++++++++++++++++++++++++++++----------- + tests/local.mk | 1 + + tests/tail/tail-sysfs.sh | 34 ++++++++++++++++++++++++ + 3 files changed, 77 insertions(+), 15 deletions(-) + create mode 100755 tests/tail/tail-sysfs.sh + +diff --git a/src/tail.c b/src/tail.c +index c45f3b65a..6979e0ba3 100644 +--- a/src/tail.c ++++ b/src/tail.c +@@ -208,6 +208,9 @@ static int nbpids = 0; + that is writing to all followed files. */ + static pid_t pid; + ++/* Used to determine the buffer size when scanning backwards in a file. */ ++static idx_t page_size; ++ + /* True if we have ever read standard input. */ + static bool have_read_stdin; + +@@ -515,22 +518,40 @@ xlseek (int fd, off_t offset, int whence, char const *filename) + Return true if successful. */ + + static bool +-file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, +- off_t start_pos, off_t end_pos, uintmax_t *read_pos) ++file_lines (char const *pretty_filename, int fd, struct stat const *sb, ++ uintmax_t n_lines, off_t start_pos, off_t end_pos, ++ uintmax_t *read_pos) + { +- char buffer[BUFSIZ]; ++ char *buffer; + size_t bytes_read; ++ blksize_t bufsize = BUFSIZ; + off_t pos = end_pos; ++ bool ok = true; + + if (n_lines == 0) + return true; + ++ /* Be careful with files with sizes that are a multiple of the page size, ++ as on /proc or /sys file systems these files accept seeking to within ++ the file, but then return no data when read. So use a buffer that's ++ at least PAGE_SIZE to avoid seeking within such files. ++ ++ We could also indirectly use a large enough buffer through io_blksize() ++ however this would be less efficient in the common case, as it would ++ generally pick a larger buffer size, resulting in reading more data ++ from the end of the file. */ ++ affirm (S_ISREG (sb->st_mode)); ++ if (sb->st_size % page_size == 0) ++ bufsize = MAX (BUFSIZ, page_size); ++ ++ buffer = xmalloc (bufsize); ++ + /* Set 'bytes_read' to the size of the last, probably partial, buffer; +- 0 < 'bytes_read' <= 'BUFSIZ'. */ +- bytes_read = (pos - start_pos) % BUFSIZ; ++ 0 < 'bytes_read' <= 'bufsize'. */ ++ bytes_read = (pos - start_pos) % bufsize; + if (bytes_read == 0) +- bytes_read = BUFSIZ; +- /* Make 'pos' a multiple of 'BUFSIZ' (0 if the file is short), so that all ++ bytes_read = bufsize; ++ /* Make 'pos' a multiple of 'bufsize' (0 if the file is short), so that all + reads will be on block boundaries, which might increase efficiency. */ + pos -= bytes_read; + xlseek (fd, pos, SEEK_SET, pretty_filename); +@@ -538,7 +559,8 @@ file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, + if (bytes_read == SAFE_READ_ERROR) + { + error (0, errno, _("error reading %s"), quoteaf (pretty_filename)); +- return false; ++ ok = false; ++ goto free_buffer; + } + *read_pos = pos + bytes_read; + +@@ -565,7 +587,7 @@ file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, + xwrite_stdout (nl + 1, bytes_read - (n + 1)); + *read_pos += dump_remainder (false, pretty_filename, fd, + end_pos - (pos + bytes_read)); +- return true; ++ goto free_buffer; + } + } + +@@ -577,23 +599,26 @@ file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, + xlseek (fd, start_pos, SEEK_SET, pretty_filename); + *read_pos = start_pos + dump_remainder (false, pretty_filename, fd, + end_pos); +- return true; ++ goto free_buffer; + } +- pos -= BUFSIZ; ++ pos -= bufsize; + xlseek (fd, pos, SEEK_SET, pretty_filename); + +- bytes_read = safe_read (fd, buffer, BUFSIZ); ++ bytes_read = safe_read (fd, buffer, bufsize); + if (bytes_read == SAFE_READ_ERROR) + { + error (0, errno, _("error reading %s"), quoteaf (pretty_filename)); +- return false; ++ ok = false; ++ goto free_buffer; + } + + *read_pos = pos + bytes_read; + } + while (bytes_read > 0); + +- return true; ++free_buffer: ++ free (buffer); ++ return ok; + } + + /* Print the last N_LINES lines from the end of the standard input, +@@ -1915,7 +1940,7 @@ tail_lines (char const *pretty_filename, int fd, uintmax_t n_lines, + { + *read_pos = end_pos; + if (end_pos != 0 +- && ! file_lines (pretty_filename, fd, n_lines, ++ && ! file_lines (pretty_filename, fd, &stats, n_lines, + start_pos, end_pos, read_pos)) + return false; + } +@@ -2337,6 +2362,8 @@ main (int argc, char **argv) + + atexit (close_stdout); + ++ page_size = getpagesize (); ++ + have_read_stdin = false; + + count_lines = true; +diff --git a/tests/local.mk b/tests/local.mk +index db4ee7ed8..bf03238c3 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -257,6 +257,7 @@ all_tests = \ + tests/seq/seq-precision.sh \ + tests/head/head.pl \ + tests/head/head-elide-tail.pl \ ++ tests/tail/tail-sysfs.sh \ + tests/tail/tail-n0f.sh \ + tests/ls/ls-misc.pl \ + tests/date/date.pl \ +diff --git a/tests/tail/tail-sysfs.sh b/tests/tail/tail-sysfs.sh +new file mode 100755 +index 000000000..00874b3dc +--- /dev/null ++++ b/tests/tail/tail-sysfs.sh +@@ -0,0 +1,34 @@ ++#!/bin/sh ++# sysfs files have weird properties that can be influenced by page size ++ ++# Copyright 2023 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ tail ++ ++file='/sys/kernel/profiling' ++ ++test -r "$file" || skip_ "No $file file" ++ ++cp -f "$file" exp || framework_failure_ ++ ++tail -n1 "$file" > out || fail=1 ++compare exp out || fail=1 ++ ++tail -c2 "$file" > out || fail=1 ++compare exp out || fail=1 ++ ++Exit $fail diff --git a/coreutils.spec b/coreutils.spec index 5cfc1dc..f1d68b3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.4 -Release: 5%{?dist} +Release: 6%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -35,6 +35,9 @@ Patch105: coreutils-9.4-systemd-coredump.patch # fix buffer overflow in split (CVE-2024-0684) Patch106: coreutils-9.4-CVE-2024-0684.patch +# fix tail on kernels with 64k pagesize +Patch107: coreutils-9.4-tail-64k-pages.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -259,6 +262,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jan 29 2024 Lukáš Zaoral - 9.4-6 +- fix tail on kernels with 64k page sizes (RHEL-22866) + * Wed Jan 24 2024 Fedora Release Engineering - 9.4-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From a91df5db11b44703c6f74c86c142c22cdc2768d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 2 Apr 2024 15:13:14 +0200 Subject: [PATCH 495/523] rebase to latest upstream version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - sync i18n patch with SUSE (Kudos to Berny Völker!) - add some test dependencies to execute additional part of the upstream test-suite Resolves: rhbz#2272063 --- coreutils-9.4-CVE-2024-0684.patch | 31 - coreutils-9.4-systemd-coredump.patch | 28 - coreutils-9.4-tail-64k-pages.patch | 205 ---- coreutils-df-direct.patch | 24 +- coreutils-i18n.patch | 1453 ++++++++++---------------- coreutils-python3.patch | 65 ++ coreutils-selinux.patch | 12 +- coreutils.spec | 34 +- sources | 4 +- 9 files changed, 648 insertions(+), 1208 deletions(-) delete mode 100644 coreutils-9.4-CVE-2024-0684.patch delete mode 100644 coreutils-9.4-systemd-coredump.patch delete mode 100644 coreutils-9.4-tail-64k-pages.patch create mode 100644 coreutils-python3.patch diff --git a/coreutils-9.4-CVE-2024-0684.patch b/coreutils-9.4-CVE-2024-0684.patch deleted file mode 100644 index 64583af..0000000 --- a/coreutils-9.4-CVE-2024-0684.patch +++ /dev/null @@ -1,31 +0,0 @@ -From c4c5ed8f4e9cd55a12966d4f520e3a13101637d9 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Tue, 16 Jan 2024 13:48:32 -0800 -Subject: [PATCH] split: do not shrink hold buffer -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -* src/split.c (line_bytes_split): Do not shrink hold buffer. -If it’s large for this batch it’s likely to be large for the next -batch, and for ‘split’ it’s not worth the complexity/CPU hassle to -shrink it. Do not assume hold_size can be bufsize. ---- - src/split.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/src/split.c b/src/split.c -index 64020c859..037960a59 100644 ---- a/src/split.c -+++ b/src/split.c -@@ -809,10 +809,7 @@ line_bytes_split (intmax_t n_bytes, char *buf, idx_t bufsize) - { - cwrite (n_out == 0, hold, n_hold); - n_out += n_hold; -- if (n_hold > bufsize) -- hold = xirealloc (hold, bufsize); - n_hold = 0; -- hold_size = bufsize; - } - - /* Output to eol if present. */ diff --git a/coreutils-9.4-systemd-coredump.patch b/coreutils-9.4-systemd-coredump.patch deleted file mode 100644 index 13f69e0..0000000 --- a/coreutils-9.4-systemd-coredump.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2616c6be1c244424617997151c67bcab2dacbcfe Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Thu, 31 Aug 2023 14:34:05 +0200 -Subject: [PATCH] coreutils-9.4-systemd-coredump.patch - -Cherry picked from gnulib upstream commits: -* 1e6a26f9312bb47e070f94b17b14dc1a6ffbb74f ("readutmp: fix core dump if --enable-systemd") -* 3af1d7b0ce3a8e3ae565e7cea10cee6fd7cb8109 ("readutmp: Fix memory leak introduced by last commit.") ---- - lib/readutmp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/readutmp.c b/lib/readutmp.c -index 0173b7e..ec09feb 100644 ---- a/lib/readutmp.c -+++ b/lib/readutmp.c -@@ -795,7 +795,7 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) - { - char **sessions; - int num_sessions = sd_get_sessions (&sessions); -- if (num_sessions >= 0) -+ if (num_sessions >= 0 && sessions != NULL) - { - char **session_ptr; - for (session_ptr = sessions; *session_ptr != NULL; session_ptr++) --- -2.41.0 - diff --git a/coreutils-9.4-tail-64k-pages.patch b/coreutils-9.4-tail-64k-pages.patch deleted file mode 100644 index 1165f7b..0000000 --- a/coreutils-9.4-tail-64k-pages.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 73d119f4f8052a9fb6cef13cd9e75d5a4e23311a Mon Sep 17 00:00:00 2001 -From: dann frazier -Date: Wed, 29 Nov 2023 18:32:34 -0700 -Subject: [PATCH] tail: fix tailing sysfs files where PAGE_SIZE > BUFSIZ - -* src/tail.c (file_lines): Ensure we use a buffer size >= PAGE_SIZE when -searching backwards to avoid seeking within a file, -which on sysfs files is accepted but also returns no data. -* tests/tail/tail-sysfs.sh: Add a new test. -* tests/local.mk: Reference the new test. -* NEWS: Mention the bug fix. -Fixes https://bugs.gnu.org/67490 - -Upstream-commit: 73d119f4f8052a9fb6cef13cd9e75d5a4e23311a -Cherry-picked-by: Lukáš Zaoral ---- - src/tail.c | 57 +++++++++++++++++++++++++++++----------- - tests/local.mk | 1 + - tests/tail/tail-sysfs.sh | 34 ++++++++++++++++++++++++ - 3 files changed, 77 insertions(+), 15 deletions(-) - create mode 100755 tests/tail/tail-sysfs.sh - -diff --git a/src/tail.c b/src/tail.c -index c45f3b65a..6979e0ba3 100644 ---- a/src/tail.c -+++ b/src/tail.c -@@ -208,6 +208,9 @@ static int nbpids = 0; - that is writing to all followed files. */ - static pid_t pid; - -+/* Used to determine the buffer size when scanning backwards in a file. */ -+static idx_t page_size; -+ - /* True if we have ever read standard input. */ - static bool have_read_stdin; - -@@ -515,22 +518,40 @@ xlseek (int fd, off_t offset, int whence, char const *filename) - Return true if successful. */ - - static bool --file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, -- off_t start_pos, off_t end_pos, uintmax_t *read_pos) -+file_lines (char const *pretty_filename, int fd, struct stat const *sb, -+ uintmax_t n_lines, off_t start_pos, off_t end_pos, -+ uintmax_t *read_pos) - { -- char buffer[BUFSIZ]; -+ char *buffer; - size_t bytes_read; -+ blksize_t bufsize = BUFSIZ; - off_t pos = end_pos; -+ bool ok = true; - - if (n_lines == 0) - return true; - -+ /* Be careful with files with sizes that are a multiple of the page size, -+ as on /proc or /sys file systems these files accept seeking to within -+ the file, but then return no data when read. So use a buffer that's -+ at least PAGE_SIZE to avoid seeking within such files. -+ -+ We could also indirectly use a large enough buffer through io_blksize() -+ however this would be less efficient in the common case, as it would -+ generally pick a larger buffer size, resulting in reading more data -+ from the end of the file. */ -+ affirm (S_ISREG (sb->st_mode)); -+ if (sb->st_size % page_size == 0) -+ bufsize = MAX (BUFSIZ, page_size); -+ -+ buffer = xmalloc (bufsize); -+ - /* Set 'bytes_read' to the size of the last, probably partial, buffer; -- 0 < 'bytes_read' <= 'BUFSIZ'. */ -- bytes_read = (pos - start_pos) % BUFSIZ; -+ 0 < 'bytes_read' <= 'bufsize'. */ -+ bytes_read = (pos - start_pos) % bufsize; - if (bytes_read == 0) -- bytes_read = BUFSIZ; -- /* Make 'pos' a multiple of 'BUFSIZ' (0 if the file is short), so that all -+ bytes_read = bufsize; -+ /* Make 'pos' a multiple of 'bufsize' (0 if the file is short), so that all - reads will be on block boundaries, which might increase efficiency. */ - pos -= bytes_read; - xlseek (fd, pos, SEEK_SET, pretty_filename); -@@ -538,7 +559,8 @@ file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, - if (bytes_read == SAFE_READ_ERROR) - { - error (0, errno, _("error reading %s"), quoteaf (pretty_filename)); -- return false; -+ ok = false; -+ goto free_buffer; - } - *read_pos = pos + bytes_read; - -@@ -565,7 +587,7 @@ file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, - xwrite_stdout (nl + 1, bytes_read - (n + 1)); - *read_pos += dump_remainder (false, pretty_filename, fd, - end_pos - (pos + bytes_read)); -- return true; -+ goto free_buffer; - } - } - -@@ -577,23 +599,26 @@ file_lines (char const *pretty_filename, int fd, uintmax_t n_lines, - xlseek (fd, start_pos, SEEK_SET, pretty_filename); - *read_pos = start_pos + dump_remainder (false, pretty_filename, fd, - end_pos); -- return true; -+ goto free_buffer; - } -- pos -= BUFSIZ; -+ pos -= bufsize; - xlseek (fd, pos, SEEK_SET, pretty_filename); - -- bytes_read = safe_read (fd, buffer, BUFSIZ); -+ bytes_read = safe_read (fd, buffer, bufsize); - if (bytes_read == SAFE_READ_ERROR) - { - error (0, errno, _("error reading %s"), quoteaf (pretty_filename)); -- return false; -+ ok = false; -+ goto free_buffer; - } - - *read_pos = pos + bytes_read; - } - while (bytes_read > 0); - -- return true; -+free_buffer: -+ free (buffer); -+ return ok; - } - - /* Print the last N_LINES lines from the end of the standard input, -@@ -1915,7 +1940,7 @@ tail_lines (char const *pretty_filename, int fd, uintmax_t n_lines, - { - *read_pos = end_pos; - if (end_pos != 0 -- && ! file_lines (pretty_filename, fd, n_lines, -+ && ! file_lines (pretty_filename, fd, &stats, n_lines, - start_pos, end_pos, read_pos)) - return false; - } -@@ -2337,6 +2362,8 @@ main (int argc, char **argv) - - atexit (close_stdout); - -+ page_size = getpagesize (); -+ - have_read_stdin = false; - - count_lines = true; -diff --git a/tests/local.mk b/tests/local.mk -index db4ee7ed8..bf03238c3 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -257,6 +257,7 @@ all_tests = \ - tests/seq/seq-precision.sh \ - tests/head/head.pl \ - tests/head/head-elide-tail.pl \ -+ tests/tail/tail-sysfs.sh \ - tests/tail/tail-n0f.sh \ - tests/ls/ls-misc.pl \ - tests/date/date.pl \ -diff --git a/tests/tail/tail-sysfs.sh b/tests/tail/tail-sysfs.sh -new file mode 100755 -index 000000000..00874b3dc ---- /dev/null -+++ b/tests/tail/tail-sysfs.sh -@@ -0,0 +1,34 @@ -+#!/bin/sh -+# sysfs files have weird properties that can be influenced by page size -+ -+# Copyright 2023 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ tail -+ -+file='/sys/kernel/profiling' -+ -+test -r "$file" || skip_ "No $file file" -+ -+cp -f "$file" exp || framework_failure_ -+ -+tail -n1 "$file" > out || fail=1 -+compare exp out || fail=1 -+ -+tail -c2 "$file" > out || fail=1 -+compare exp out || fail=1 -+ -+Exit $fail diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 9e3434a..f29a065 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From 6e36198f10a2f63b89c89ebb5d5c185b20fb3a63 Mon Sep 17 00:00:00 2001 +From f072852456c545bd89296bc88cf59ccd63287a68 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,10 +11,10 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 5b9a597..6810c15 100644 +index 8f7f43e..230f1f1 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12074,6 +12074,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12427,6 +12427,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -29,10 +29,10 @@ index 5b9a597..6810c15 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 48025b9..c8efa5b 100644 +index 994f0e3..ceee209 100644 --- a/src/df.c +++ b/src/df.c -@@ -125,6 +125,9 @@ static bool print_type; +@@ -121,6 +121,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -42,7 +42,7 @@ index 48025b9..c8efa5b 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -252,13 +255,15 @@ enum +@@ -247,13 +250,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -59,7 +59,7 @@ index 48025b9..c8efa5b 100644 {"inodes", no_argument, nullptr, 'i'}, {"human-readable", no_argument, nullptr, 'h'}, {"si", no_argument, nullptr, 'H'}, -@@ -583,7 +588,10 @@ get_header (void) +@@ -574,7 +579,10 @@ get_header (void) for (col = 0; col < ncolumns; col++) { char *cell = nullptr; @@ -71,7 +71,7 @@ index 48025b9..c8efa5b 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1486,6 +1494,17 @@ get_point (char const *point, const struct stat *statp) +@@ -1471,6 +1479,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -89,7 +89,7 @@ index 48025b9..c8efa5b 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1556,6 +1575,7 @@ or all file systems by default.\n\ +@@ -1541,6 +1560,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -97,7 +97,7 @@ index 48025b9..c8efa5b 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1646,6 +1666,9 @@ main (int argc, char **argv) +@@ -1631,6 +1651,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -107,7 +107,7 @@ index 48025b9..c8efa5b 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1742,6 +1765,13 @@ main (int argc, char **argv) +@@ -1727,6 +1750,13 @@ main (int argc, char **argv) } } @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.31.1 +2.44.0 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index be8e0b1..aa21a35 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,66 +1,69 @@ -From 3a1b92e80708319bcc89852e3da1029c3d1ff6b3 Mon Sep 17 00:00:00 2001 +From 94cf02dfcb1be23dedf8a39af295f28ee2de6013 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch --- - bootstrap.conf | 1 + + bootstrap.conf | 2 + configure.ac | 6 + lib/linebuffer.h | 8 + + lib/mbchar.c | 23 ++ + lib/mbchar.h | 373 +++++++++++++++++ lib/mbfile.c | 20 + lib/mbfile.h | 267 ++++++++++++ + m4/mbchar.m4 | 13 + m4/mbfile.m4 | 14 + src/cut.c | 508 +++++++++++++++++++++-- src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + src/expand.c | 90 +++- src/fold.c | 312 ++++++++++++-- - src/join.c | 359 ++++++++++++++-- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 792 +++++++++++++++++++++++++++++++++--- src/unexpand.c | 102 ++++- - src/uniq.c | 119 +++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ tests/i18n/sort.sh | 29 ++ tests/local.mk | 4 + tests/misc/expand.pl | 42 ++ tests/misc/fold.pl | 50 ++- - tests/misc/join.pl | 50 +++ tests/misc/sort-mb-tests.sh | 45 ++ tests/misc/unexpand.pl | 39 ++ tests/pr/pr-tests.pl | 49 +++ tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - tests/uniq/uniq.pl | 55 +++ - 31 files changed, 3732 insertions(+), 242 deletions(-) + 30 files changed, 3605 insertions(+), 196 deletions(-) + create mode 100644 lib/mbchar.c + create mode 100644 lib/mbchar.h create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h + create mode 100644 m4/mbchar.m4 create mode 100644 m4/mbfile.m4 - create mode 100755 tests/expand/mb.sh - create mode 100755 tests/i18n/sort.sh - create mode 100755 tests/misc/sort-mb-tests.sh - create mode 100755 tests/unexpand/mb.sh + create mode 100644 tests/expand/mb.sh + create mode 100644 tests/i18n/sort.sh + create mode 100644 tests/misc/sort-mb-tests.sh + create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index bd73ff2..0e450cd 100644 +index 126e1e8..b4ccebf 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -167,6 +167,7 @@ gnulib_modules=" +@@ -163,6 +163,8 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings ++ mbchar + mbfile mbrlen + mbrtoc32 mbrtowc - mbsalign diff --git a/configure.ac b/configure.ac -index 8ffc0b7..ca3305d 100644 +index 9cb6ee1..1131ce3 100644 --- a/configure.ac +++ b/configure.ac -@@ -448,6 +448,12 @@ fi +@@ -504,6 +504,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -74,7 +77,7 @@ index 8ffc0b7..ca3305d 100644 if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index b4cc8e4..f2bbb52 100644 +index ae0d55d..5bf5350 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h @@ -22,6 +22,11 @@ @@ -99,6 +102,414 @@ index b4cc8e4..f2bbb52 100644 }; /* Initialize linebuffer LINEBUFFER for use. */ +diff --git a/lib/mbchar.c b/lib/mbchar.c +new file mode 100644 +index 0000000..d94b7c3 +--- /dev/null ++++ b/lib/mbchar.c +@@ -0,0 +1,23 @@ ++/* Copyright (C) 2001, 2006, 2009-2024 Free Software Foundation, Inc. ++ ++ This file is free software: you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ This file is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with this program. If not, see . */ ++ ++ ++#include ++ ++#define MBCHAR_INLINE _GL_EXTERN_INLINE ++ ++#include ++ ++#include "mbchar.h" +diff --git a/lib/mbchar.h b/lib/mbchar.h +new file mode 100644 +index 0000000..c06ef11 +--- /dev/null ++++ b/lib/mbchar.h +@@ -0,0 +1,373 @@ ++/* Multibyte character data type. ++ Copyright (C) 2001, 2005-2007, 2009-2024 Free Software Foundation, Inc. ++ ++ This file is free software: you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ This file is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with this program. If not, see . */ ++ ++/* Written by Bruno Haible . */ ++ ++/* A multibyte character is a short subsequence of a char* string, ++ representing a single 32-bit wide character. ++ ++ We use multibyte characters instead of 32-bit wide characters because ++ of the following goals: ++ 1) correct multibyte handling, i.e. operate according to the LC_CTYPE ++ locale, ++ 2) ease of maintenance, i.e. the maintainer needs not know all details ++ of the ISO C 99 standard, ++ 3) don't fail grossly if the input is not in the encoding set by the ++ locale, because often different encodings are in use in the same ++ countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...), ++ 4) fast in the case of ASCII characters. ++ ++ Multibyte characters are only accessed through the mb* macros. ++ ++ mb_ptr (mbc) ++ return a pointer to the beginning of the multibyte sequence. ++ ++ mb_len (mbc) ++ returns the number of bytes occupied by the multibyte sequence. ++ Always > 0. ++ ++ mb_iseq (mbc, sc) ++ returns true if mbc is the standard ASCII character sc. ++ ++ mb_isnul (mbc) ++ returns true if mbc is the nul character. ++ ++ mb_cmp (mbc1, mbc2) ++ returns a positive, zero, or negative value depending on whether mbc1 ++ sorts after, same or before mbc2. ++ ++ mb_casecmp (mbc1, mbc2) ++ returns a positive, zero, or negative value depending on whether mbc1 ++ sorts after, same or before mbc2, modulo upper/lowercase conversion. ++ ++ mb_equal (mbc1, mbc2) ++ returns true if mbc1 and mbc2 are equal. ++ ++ mb_caseequal (mbc1, mbc2) ++ returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion. ++ ++ mb_isalnum (mbc) ++ returns true if mbc is alphanumeric. ++ ++ mb_isalpha (mbc) ++ returns true if mbc is alphabetic. ++ ++ mb_isascii(mbc) ++ returns true if mbc is plain ASCII. ++ ++ mb_isblank (mbc) ++ returns true if mbc is a blank. ++ ++ mb_iscntrl (mbc) ++ returns true if mbc is a control character. ++ ++ mb_isdigit (mbc) ++ returns true if mbc is a decimal digit. ++ ++ mb_isgraph (mbc) ++ returns true if mbc is a graphic character. ++ ++ mb_islower (mbc) ++ returns true if mbc is lowercase. ++ ++ mb_isprint (mbc) ++ returns true if mbc is a printable character. ++ ++ mb_ispunct (mbc) ++ returns true if mbc is a punctuation character. ++ ++ mb_isspace (mbc) ++ returns true if mbc is a space character. ++ ++ mb_isupper (mbc) ++ returns true if mbc is uppercase. ++ ++ mb_isxdigit (mbc) ++ returns true if mbc is a hexadecimal digit. ++ ++ mb_width (mbc) ++ returns the number of columns on the output device occupied by mbc. ++ Always >= 0. ++ ++ mb_putc (mbc, stream) ++ outputs mbc on stream, a byte oriented FILE stream opened for output. ++ ++ mb_setascii (&mbc, sc) ++ assigns the standard ASCII character sc to mbc. ++ (Only available if the 'mbfile' module is in use.) ++ ++ mb_copy (&destmbc, &srcmbc) ++ copies srcmbc to destmbc. ++ ++ Here are the function prototypes of the macros. ++ ++ extern const char * mb_ptr (const mbchar_t mbc); ++ extern size_t mb_len (const mbchar_t mbc); ++ extern bool mb_iseq (const mbchar_t mbc, char sc); ++ extern bool mb_isnul (const mbchar_t mbc); ++ extern int mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2); ++ extern int mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2); ++ extern bool mb_equal (const mbchar_t mbc1, const mbchar_t mbc2); ++ extern bool mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2); ++ extern bool mb_isalnum (const mbchar_t mbc); ++ extern bool mb_isalpha (const mbchar_t mbc); ++ extern bool mb_isascii (const mbchar_t mbc); ++ extern bool mb_isblank (const mbchar_t mbc); ++ extern bool mb_iscntrl (const mbchar_t mbc); ++ extern bool mb_isdigit (const mbchar_t mbc); ++ extern bool mb_isgraph (const mbchar_t mbc); ++ extern bool mb_islower (const mbchar_t mbc); ++ extern bool mb_isprint (const mbchar_t mbc); ++ extern bool mb_ispunct (const mbchar_t mbc); ++ extern bool mb_isspace (const mbchar_t mbc); ++ extern bool mb_isupper (const mbchar_t mbc); ++ extern bool mb_isxdigit (const mbchar_t mbc); ++ extern int mb_width (const mbchar_t mbc); ++ extern void mb_putc (const mbchar_t mbc, FILE *stream); ++ extern void mb_setascii (mbchar_t *new, char sc); ++ extern void mb_copy (mbchar_t *new, const mbchar_t *old); ++ */ ++ ++#ifndef _MBCHAR_H ++#define _MBCHAR_H 1 ++ ++/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ ++#if !_GL_CONFIG_H_INCLUDED ++ #error "Please include config.h first." ++#endif ++ ++#include ++#include ++ ++_GL_INLINE_HEADER_BEGIN ++#ifndef MBCHAR_INLINE ++# define MBCHAR_INLINE _GL_INLINE ++#endif ++ ++/* The longest multibyte characters, nowadays, are 4 bytes long. ++ Regardless of the values of MB_CUR_MAX and MB_LEN_MAX. */ ++#define MBCHAR_BUF_SIZE 4 ++ ++struct mbchar ++{ ++ const char *ptr; /* pointer to current character */ ++ size_t bytes; /* number of bytes of current character, > 0 */ ++ bool wc_valid; /* true if wc is a valid 32-bit wide character */ ++ char32_t wc; /* if wc_valid: the current character */ ++#if defined GNULIB_MBFILE ++ char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */ ++#endif ++}; ++ ++/* EOF (not a real character) is represented with bytes = 0 and ++ wc_valid = false. */ ++ ++typedef struct mbchar mbchar_t; ++ ++/* Access the current character. */ ++#define mb_ptr(mbc) ((mbc).ptr) ++#define mb_len(mbc) ((mbc).bytes) ++ ++/* Comparison of characters. */ ++#define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc)) ++#define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0) ++#define mb_cmp(mbc1, mbc2) \ ++ ((mbc1).wc_valid \ ++ ? ((mbc2).wc_valid \ ++ ? _GL_CMP ((mbc1).wc, (mbc2).wc) \ ++ : -1) \ ++ : ((mbc2).wc_valid \ ++ ? 1 \ ++ : (mbc1).bytes == (mbc2).bytes \ ++ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ ++ : (mbc1).bytes < (mbc2).bytes \ ++ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ ++ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) ++#define mb_casecmp(mbc1, mbc2) \ ++ ((mbc1).wc_valid \ ++ ? ((mbc2).wc_valid \ ++ ? _GL_CMP (c32tolower ((mbc1).wc), c32tolower ((mbc2).wc)) \ ++ : -1) \ ++ : ((mbc2).wc_valid \ ++ ? 1 \ ++ : (mbc1).bytes == (mbc2).bytes \ ++ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ ++ : (mbc1).bytes < (mbc2).bytes \ ++ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ ++ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) ++#define mb_equal(mbc1, mbc2) \ ++ ((mbc1).wc_valid && (mbc2).wc_valid \ ++ ? (mbc1).wc == (mbc2).wc \ ++ : (mbc1).bytes == (mbc2).bytes \ ++ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) ++#define mb_caseequal(mbc1, mbc2) \ ++ ((mbc1).wc_valid && (mbc2).wc_valid \ ++ ? c32tolower ((mbc1).wc) == c32tolower ((mbc2).wc) \ ++ : (mbc1).bytes == (mbc2).bytes \ ++ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) ++ ++/* , classification. */ ++#define mb_isascii(mbc) \ ++ ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127) ++#define mb_isalnum(mbc) ((mbc).wc_valid && c32isalnum ((mbc).wc)) ++#define mb_isalpha(mbc) ((mbc).wc_valid && c32isalpha ((mbc).wc)) ++#define mb_isblank(mbc) ((mbc).wc_valid && c32isblank ((mbc).wc)) ++#define mb_iscntrl(mbc) ((mbc).wc_valid && c32iscntrl ((mbc).wc)) ++#define mb_isdigit(mbc) ((mbc).wc_valid && c32isdigit ((mbc).wc)) ++#define mb_isgraph(mbc) ((mbc).wc_valid && c32isgraph ((mbc).wc)) ++#define mb_islower(mbc) ((mbc).wc_valid && c32islower ((mbc).wc)) ++#define mb_isprint(mbc) ((mbc).wc_valid && c32isprint ((mbc).wc)) ++#define mb_ispunct(mbc) ((mbc).wc_valid && c32ispunct ((mbc).wc)) ++#define mb_isspace(mbc) ((mbc).wc_valid && c32isspace ((mbc).wc)) ++#define mb_isupper(mbc) ((mbc).wc_valid && c32isupper ((mbc).wc)) ++#define mb_isxdigit(mbc) ((mbc).wc_valid && c32isxdigit ((mbc).wc)) ++ ++/* Extra function. */ ++ ++/* Unprintable characters appear as a small box of width 1. */ ++#define MB_UNPRINTABLE_WIDTH 1 ++ ++MBCHAR_INLINE int ++mb_width_aux (char32_t wc) ++{ ++ int w = c32width (wc); ++ /* For unprintable characters, arbitrarily return 0 for control characters ++ and MB_UNPRINTABLE_WIDTH otherwise. */ ++ return (w >= 0 ? w : c32iscntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH); ++} ++ ++#define mb_width(mbc) \ ++ ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH) ++ ++/* Output. */ ++#define mb_putc(mbc, stream) fwrite ((mbc).ptr, 1, (mbc).bytes, (stream)) ++ ++#if defined GNULIB_MBFILE ++/* Assignment. */ ++# define mb_setascii(mbc, sc) \ ++ ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \ ++ (mbc)->wc = (mbc)->buf[0] = (sc)) ++#endif ++ ++/* Copying a character. */ ++MBCHAR_INLINE void ++mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc) ++{ ++#if defined GNULIB_MBFILE ++ if (old_mbc->ptr == &old_mbc->buf[0]) ++ { ++ memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes); ++ new_mbc->ptr = &new_mbc->buf[0]; ++ } ++ else ++#endif ++ new_mbc->ptr = old_mbc->ptr; ++ new_mbc->bytes = old_mbc->bytes; ++ if ((new_mbc->wc_valid = old_mbc->wc_valid)) ++ new_mbc->wc = old_mbc->wc; ++} ++ ++ ++/* is_basic(c) tests whether the single-byte character c is ++ - in the ISO C "basic character set" or is one of '@', '$', and '`' ++ which ISO C 23 § 5.2.1.1.(1) guarantees to be single-byte and in ++ practice are safe to treat as basic in the execution character set, ++ or ++ - in the POSIX "portable character set", which ++ ++ equally guarantees to be single-byte. ++ This is a convenience function, and is in this file only to share code ++ between mbiter.h, mbuiter.h, and mbfile.h. */ ++#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ ++ && ('$' == 36) && ('%' == 37) && ('&' == 38) && ('\'' == 39) \ ++ && ('(' == 40) && (')' == 41) && ('*' == 42) && ('+' == 43) \ ++ && (',' == 44) && ('-' == 45) && ('.' == 46) && ('/' == 47) \ ++ && ('0' == 48) && ('1' == 49) && ('2' == 50) && ('3' == 51) \ ++ && ('4' == 52) && ('5' == 53) && ('6' == 54) && ('7' == 55) \ ++ && ('8' == 56) && ('9' == 57) && (':' == 58) && (';' == 59) \ ++ && ('<' == 60) && ('=' == 61) && ('>' == 62) && ('?' == 63) \ ++ && ('@' == 64) && ('A' == 65) && ('B' == 66) && ('C' == 67) \ ++ && ('D' == 68) && ('E' == 69) && ('F' == 70) && ('G' == 71) \ ++ && ('H' == 72) && ('I' == 73) && ('J' == 74) && ('K' == 75) \ ++ && ('L' == 76) && ('M' == 77) && ('N' == 78) && ('O' == 79) \ ++ && ('P' == 80) && ('Q' == 81) && ('R' == 82) && ('S' == 83) \ ++ && ('T' == 84) && ('U' == 85) && ('V' == 86) && ('W' == 87) \ ++ && ('X' == 88) && ('Y' == 89) && ('Z' == 90) && ('[' == 91) \ ++ && ('\\' == 92) && (']' == 93) && ('^' == 94) && ('_' == 95) \ ++ && ('`' == 96) && ('a' == 97) && ('b' == 98) && ('c' == 99) \ ++ && ('d' == 100) && ('e' == 101) && ('f' == 102) && ('g' == 103) \ ++ && ('h' == 104) && ('i' == 105) && ('j' == 106) && ('k' == 107) \ ++ && ('l' == 108) && ('m' == 109) && ('n' == 110) && ('o' == 111) \ ++ && ('p' == 112) && ('q' == 113) && ('r' == 114) && ('s' == 115) \ ++ && ('t' == 116) && ('u' == 117) && ('v' == 118) && ('w' == 119) \ ++ && ('x' == 120) && ('y' == 121) && ('z' == 122) && ('{' == 123) \ ++ && ('|' == 124) && ('}' == 125) && ('~' == 126) ++/* The character set is ISO-646, not EBCDIC. */ ++# define IS_BASIC_ASCII 1 ++ ++/* All locale encodings (see localcharset.h) map the characters 0x00..0x7F ++ to U+0000..U+007F, like ASCII, except for ++ CP864 different mapping of '%' ++ SHIFT_JIS different mappings of 0x5C, 0x7E ++ JOHAB different mapping of 0x5C ++ However, these characters in the range 0x20..0x7E are in the ISO C ++ "basic character set" and in the POSIX "portable character set", which ++ ISO C and POSIX guarantee to be single-byte. Thus, locales with these ++ encodings are not POSIX compliant. And they are most likely not in use ++ any more (as of 2023). */ ++# define is_basic(c) ((unsigned char) (c) < 0x80) ++ ++#else ++ ++MBCHAR_INLINE bool ++is_basic (char c) ++{ ++ switch (c) ++ { ++ case '\0': ++ case '\007': case '\010': ++ case '\t': case '\n': case '\v': case '\f': case '\r': ++ case ' ': case '!': case '"': case '#': case '$': case '%': ++ case '&': case '\'': case '(': case ')': case '*': ++ case '+': case ',': case '-': case '.': case '/': ++ case '0': case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': case '8': case '9': ++ case ':': case ';': case '<': case '=': case '>': ++ case '?': case '@': ++ case 'A': case 'B': case 'C': case 'D': case 'E': ++ case 'F': case 'G': case 'H': case 'I': case 'J': ++ case 'K': case 'L': case 'M': case 'N': case 'O': ++ case 'P': case 'Q': case 'R': case 'S': case 'T': ++ case 'U': case 'V': case 'W': case 'X': case 'Y': ++ case 'Z': ++ case '[': case '\\': case ']': case '^': case '_': case '`': ++ case 'a': case 'b': case 'c': case 'd': case 'e': ++ case 'f': case 'g': case 'h': case 'i': case 'j': ++ case 'k': case 'l': case 'm': case 'n': case 'o': ++ case 'p': case 'q': case 'r': case 's': case 't': ++ case 'u': case 'v': case 'w': case 'x': case 'y': ++ case 'z': case '{': case '|': case '}': case '~': ++ return 1; ++ default: ++ return 0; ++ } ++} ++ ++#endif ++ ++_GL_INLINE_HEADER_END ++ ++#endif /* _MBCHAR_H */ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 index 0000000..8d2957b @@ -398,6 +809,25 @@ index 0000000..ad61c19 +_GL_INLINE_HEADER_END + +#endif /* _MBFILE_H */ +diff --git a/m4/mbchar.m4 b/m4/mbchar.m4 +new file mode 100644 +index 0000000..471e8c4 +--- /dev/null ++++ b/m4/mbchar.m4 +@@ -0,0 +1,13 @@ ++# mbchar.m4 serial 9 ++dnl Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++dnl autoconf tests required for use of mbchar.m4 ++dnl From Bruno Haible. ++ ++AC_DEFUN([gl_MBCHAR], ++[ ++ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) ++]) diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 index 0000000..83068a9 @@ -419,7 +849,7 @@ index 0000000..83068a9 + : +]) diff --git a/src/cut.c b/src/cut.c -index b4edbab..65e4658 100644 +index 061e09c..6d10425 100644 --- a/src/cut.c +++ b/src/cut.c @@ -27,6 +27,11 @@ @@ -1079,18 +1509,18 @@ index b4edbab..65e4658 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index 89fa56a..c102e6e 100644 +index c95998d..d4386fe 100644 --- a/src/expand-common.c +++ b/src/expand-common.c -@@ -18,6 +18,7 @@ - +@@ -19,6 +19,7 @@ + #include #include #include +#include #include "system.h" #include "fadvise.h" #include "quote.h" -@@ -122,6 +123,119 @@ set_increment_size (uintmax_t tabval) +@@ -123,6 +124,119 @@ set_increment_size (uintmax_t tabval) return ok; } @@ -1211,7 +1641,7 @@ index 89fa56a..c102e6e 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index daed31e..f6b2f68 100644 +index 1a57108..6025652 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -25,6 +25,18 @@ extern size_t max_column_width; @@ -1234,10 +1664,10 @@ index daed31e..f6b2f68 100644 extern void add_tab_stop (uintmax_t tabval); diff --git a/src/expand.c b/src/expand.c -index 0e74d0c..7080c51 100644 +index a6176a9..60b1b8e 100644 --- a/src/expand.c +++ b/src/expand.c -@@ -37,6 +37,9 @@ +@@ -38,6 +38,9 @@ #include #include #include @@ -1247,7 +1677,7 @@ index 0e74d0c..7080c51 100644 #include "system.h" #include "expand-common.h" -@@ -95,19 +98,41 @@ expand (void) +@@ -96,19 +99,41 @@ expand (void) { /* Input stream. */ FILE *fp = next_file (nullptr); @@ -1293,7 +1723,7 @@ index 0e74d0c..7080c51 100644 /* The following variables have valid values only when CONVERT is true: */ -@@ -117,17 +142,48 @@ expand (void) +@@ -118,17 +143,48 @@ expand (void) /* Index in TAB_LIST of next tab stop to examine. */ size_t tab_index = 0; @@ -1346,7 +1776,7 @@ index 0e74d0c..7080c51 100644 { /* Column the next input tab stop is on. */ uintmax_t next_tab_column; -@@ -146,32 +202,34 @@ expand (void) +@@ -147,32 +203,34 @@ expand (void) if (putchar (' ') < 0) write_error (); @@ -1390,10 +1820,10 @@ index 0e74d0c..7080c51 100644 } diff --git a/src/fold.c b/src/fold.c -index 5c0428d..2372047 100644 +index 941ad11..cf1e747 100644 --- a/src/fold.c +++ b/src/fold.c -@@ -22,10 +22,32 @@ +@@ -23,10 +23,32 @@ #include #include @@ -1426,7 +1856,7 @@ index 5c0428d..2372047 100644 #define TAB_WIDTH 8 /* The official name of this program (e.g., no 'g' prefix). */ -@@ -33,20 +55,41 @@ +@@ -34,20 +56,41 @@ #define AUTHORS proper_name ("David MacKenzie") @@ -1472,7 +1902,7 @@ index 5c0428d..2372047 100644 {"spaces", no_argument, nullptr, 's'}, {"width", required_argument, nullptr, 'w'}, {GETOPT_HELP_OPTION_DECL}, -@@ -74,6 +117,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ +@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ fputs (_("\ -b, --bytes count bytes rather than columns\n\ @@ -1480,7 +1910,7 @@ index 5c0428d..2372047 100644 -s, --spaces break at spaces\n\ -w, --width=WIDTH use WIDTH columns instead of 80\n\ "), stdout); -@@ -91,7 +135,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ +@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ static size_t adjust_column (size_t column, char c) { @@ -1489,7 +1919,7 @@ index 5c0428d..2372047 100644 { if (c == '\b') { -@@ -114,30 +158,14 @@ adjust_column (size_t column, char c) +@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) to stdout, with maximum line length WIDTH. Return true if successful. */ @@ -1522,7 +1952,7 @@ index 5c0428d..2372047 100644 fadvise (istream, FADVISE_SEQUENTIAL); -@@ -167,6 +195,15 @@ fold_file (char const *filename, size_t width) +@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width) bool found_blank = false; size_t logical_end = offset_out; @@ -1538,7 +1968,7 @@ index 5c0428d..2372047 100644 /* Look for the last blank. */ while (logical_end) { -@@ -213,13 +250,225 @@ fold_file (char const *filename, size_t width) +@@ -214,13 +251,225 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -1766,7 +2196,7 @@ index 5c0428d..2372047 100644 if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -250,7 +499,8 @@ main (int argc, char **argv) +@@ -251,7 +500,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -1776,7 +2206,7 @@ index 5c0428d..2372047 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) { -@@ -259,7 +509,15 @@ main (int argc, char **argv) +@@ -260,7 +510,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -1793,520 +2223,28 @@ index 5c0428d..2372047 100644 break; case 's': /* Break at word boundaries. */ -diff --git a/src/join.c b/src/join.c -index 0bcfa75..8a3bcf1 100644 ---- a/src/join.c -+++ b/src/join.c -@@ -21,18 +21,32 @@ - #include - #include - -+/* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get iswblank(), towupper. */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+ - #include "system.h" - #include "assure.h" - #include "fadvise.h" - #include "hard-locale.h" - #include "linebuffer.h" --#include "memcasecmp.h" - #include "quote.h" - #include "stdio--.h" - #include "xmemcoll.h" - #include "xstrtol.h" - #include "argmatch.h" - -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ -+#if HAVE_MBRTOWC && defined mbstate_t -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -+#endif -+ - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "join" - -@@ -134,10 +148,12 @@ static struct outlist outlist_head; - /* Last element in 'outlist', where a new element can be added. */ - static struct outlist *outlist_end = &outlist_head; - --/* Tab character separating fields. If negative, fields are separated -- by any nonempty string of blanks, otherwise by exactly one -- tab character whose value (when cast to unsigned char) equals TAB. */ --static int tab = -1; -+/* Tab character separating fields. If NULL, fields are separated -+ by any nonempty string of blanks. */ -+static char *tab = NULL; -+ -+/* The number of bytes used for tab. */ -+static size_t tablen = 0; - - /* If nonzero, check that the input is correctly ordered. */ - static enum -@@ -277,13 +293,14 @@ xfields (struct line *line) - if (ptr == lim) - return; - -- if (0 <= tab && tab != '\n') -+ if (tab != NULL) - { -+ unsigned char t = tab[0]; - char *sep; -- for (; (sep = memchr (ptr, tab, lim - ptr)) != nullptr; ptr = sep + 1) -+ for (; (sep = memchr (ptr, t, lim - ptr)) != nullptr; ptr = sep + 1) - extract_field (line, ptr, sep - ptr); - } -- else if (tab < 0) -+ else - { - /* Skip leading blanks before the first field. */ - while (field_sep (*ptr)) -@@ -307,6 +324,147 @@ xfields (struct line *line) - extract_field (line, ptr, lim - ptr); - } - -+#if HAVE_MBRTOWC -+static void -+xfields_multibyte (struct line *line) -+{ -+ char *ptr = line->buf.buffer; -+ char const *lim = ptr + line->buf.length - 1; -+ wchar_t wc = 0; -+ size_t mblength = 1; -+ mbstate_t state, state_bak; -+ -+ memset (&state, 0, sizeof (mbstate_t)); -+ -+ if (ptr >= lim) -+ return; -+ -+ if (tab != NULL) -+ { -+ char *sep = ptr; -+ for (; ptr < lim; ptr = sep + mblength) -+ { -+ sep = ptr; -+ while (sep < lim) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); -+ -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ if (mblength == tablen && !memcmp (sep, tab, mblength)) -+ break; -+ else -+ { -+ sep += mblength; -+ continue; -+ } -+ } -+ -+ if (sep >= lim) -+ break; -+ -+ extract_field (line, ptr, sep - ptr); -+ } -+ } -+ else -+ { -+ /* Skip leading blanks before the first field. */ -+ while(ptr < lim) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); -+ -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ if (!iswblank(wc) && wc != '\n') -+ break; -+ ptr += mblength; -+ } -+ -+ do -+ { -+ char *sep; -+ state_bak = state; -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ sep = ptr + mblength; -+ while (sep < lim) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ if (iswblank (wc) || wc == '\n') -+ break; -+ -+ sep += mblength; -+ } -+ -+ extract_field (line, ptr, sep - ptr); -+ if (sep >= lim) -+ return; -+ -+ state_bak = state; -+ mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ ptr = sep + mblength; -+ while (ptr < lim) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); -+ if (mblength == (size_t)-1 || mblength == (size_t)-2) -+ { -+ mblength = 1; -+ state = state_bak; -+ break; -+ } -+ mblength = (mblength < 1) ? 1 : mblength; -+ -+ if (!iswblank (wc) && wc != '\n') -+ break; -+ -+ ptr += mblength; -+ } -+ } -+ while (ptr < lim); -+ } -+ -+ extract_field (line, ptr, lim - ptr); -+} -+#endif -+ - static void - freeline (struct line *line) - { -@@ -328,56 +486,133 @@ keycmp (struct line const *line1, struct line const *line2, - idx_t jf_1, idx_t jf_2) - { - /* Start of field to compare in each file. */ -- char *beg1; -- char *beg2; -- -- idx_t len1; -- idx_t len2; /* Length of fields to compare. */ -+ char *beg[2]; -+ char *copy[2]; -+ idx_t len[2]; /* Length of fields to compare. */ - int diff; -+ int i, j; -+ int mallocd = 0; - - if (jf_1 < line1->nfields) - { -- beg1 = line1->fields[jf_1].beg; -- len1 = line1->fields[jf_1].len; -+ beg[0] = line1->fields[jf_1].beg; -+ len[0] = line1->fields[jf_1].len; - } - else - { -- beg1 = nullptr; -- len1 = 0; -+ beg[0] = nullptr; -+ len[0] = 0; - } - - if (jf_2 < line2->nfields) - { -- beg2 = line2->fields[jf_2].beg; -- len2 = line2->fields[jf_2].len; -+ beg[1] = line2->fields[jf_2].beg; -+ len[1] = line2->fields[jf_2].len; - } - else - { -- beg2 = nullptr; -- len2 = 0; -+ beg[1] = nullptr; -+ len[1] = 0; - } - -- if (len1 == 0) -- return len2 == 0 ? 0 : -1; -- if (len2 == 0) -+ if (len[0] == 0) -+ return len[1] == 0 ? 0 : -1; -+ if (len[1] == 0) - return 1; - - if (ignore_case) - { -- /* FIXME: ignore_case does not work with NLS (in particular, -- with multibyte chars). */ -- diff = memcasecmp (beg1, beg2, MIN (len1, len2)); -+#ifdef HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ size_t mblength; -+ wchar_t wc, uwc; -+ mbstate_t state, state_bak; -+ -+ memset (&state, '\0', sizeof (mbstate_t)); -+ -+ for (i = 0; i < 2; i++) -+ { -+ mallocd = 1; -+ copy[i] = xmalloc (len[i] + 1); -+ memset (copy[i], '\0',len[i] + 1); -+ -+ for (j = 0; j < MIN (len[0], len[1]);) -+ { -+ state_bak = state; -+ mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); -+ -+ switch (mblength) -+ { -+ case (size_t) -1: -+ case (size_t) -2: -+ state = state_bak; -+ /* Fall through */ -+ case 0: -+ mblength = 1; -+ break; -+ -+ default: -+ uwc = towupper (wc); -+ -+ if (uwc != wc) -+ { -+ mbstate_t state_wc; -+ size_t mblen; -+ -+ memset (&state_wc, '\0', sizeof (mbstate_t)); -+ mblen = wcrtomb (copy[i] + j, uwc, &state_wc); -+ assert (mblen != (size_t)-1); -+ } -+ else -+ memcpy (copy[i] + j, beg[i] + j, mblength); -+ } -+ j += mblength; -+ } -+ copy[i][j] = '\0'; -+ } -+ } -+ else -+#endif -+ { -+ for (i = 0; i < 2; i++) -+ { -+ mallocd = 1; -+ copy[i] = xmalloc (len[i] + 1); -+ -+ for (j = 0; j < MIN (len[0], len[1]); j++) -+ copy[i][j] = toupper (beg[i][j]); -+ -+ copy[i][j] = '\0'; -+ } -+ } - } - else - { -- if (hard_LC_COLLATE) -- return xmemcoll (beg1, len1, beg2, len2); -- diff = memcmp (beg1, beg2, MIN (len1, len2)); -+ copy[0] = beg[0]; -+ copy[1] = beg[1]; - } - -+ if (hard_LC_COLLATE) -+ { -+ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); -+ -+ if (mallocd) -+ for (i = 0; i < 2; i++) -+ free (copy[i]); -+ -+ return diff; -+ } -+ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); -+ -+ if (mallocd) -+ for (i = 0; i < 2; i++) -+ free (copy[i]); -+ -+ - if (diff) - return diff; -- return (len1 > len2) - (len1 < len2); -+ return len[0] - len[1]; - } - - /* Check that successive input lines PREV and CURRENT from input file -@@ -469,6 +704,11 @@ get_line (FILE *fp, struct line **linep, int which) - } - ++line_no[which - 1]; - -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ xfields_multibyte (line); -+ else -+#endif - xfields (line); - - if (prevline[which - 1]) -@@ -562,21 +802,28 @@ prfield (idx_t n, struct line const *line) - - /* Output all the fields in line, other than the join field. */ - -+#define PUT_TAB_CHAR \ -+ do \ -+ { \ -+ (tab != NULL) ? \ -+ fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ -+ } \ -+ while (0) -+ - static void - prfields (struct line const *line, idx_t join_field, idx_t autocount) - { - idx_t i; - idx_t nfields = autoformat ? autocount : line->nfields; -- char output_separator = tab < 0 ? ' ' : tab; - - for (i = 0; i < join_field && i < nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line); - } - for (i = join_field + 1; i < nfields; ++i) - { -- putchar (output_separator); -+ PUT_TAB_CHAR; - prfield (i, line); - } - } -@@ -587,7 +834,6 @@ static void - prjoin (struct line const *line1, struct line const *line2) - { - const struct outlist *outlist; -- char output_separator = tab < 0 ? ' ' : tab; - idx_t field; - struct line const *line; - -@@ -621,7 +867,7 @@ prjoin (struct line const *line1, struct line const *line2) - o = o->next; - if (o == nullptr) - break; -- putchar (output_separator); -+ PUT_TAB_CHAR; - } - putchar (eolchar); - } -@@ -1086,20 +1332,43 @@ main (int argc, char **argv) - - case 't': - { -- unsigned char newtab = optarg[0]; -+ char *newtab = NULL; -+ size_t newtablen; -+ newtab = xstrdup (optarg); -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ mbstate_t state; -+ -+ memset (&state, 0, sizeof (mbstate_t)); -+ newtablen = mbrtowc (NULL, newtab, -+ strnlen (newtab, MB_LEN_MAX), -+ &state); -+ if (newtablen == (size_t) 0 -+ || newtablen == (size_t) -1 -+ || newtablen == (size_t) -2) -+ newtablen = 1; -+ } -+ else -+#endif -+ newtablen = 1; - if (! newtab) -- newtab = '\n'; /* '' => process the whole line. */ -+ newtab = (char*)"\n"; /* '' => process the whole line. */ - else if (optarg[1]) - { -- if (STREQ (optarg, "\\0")) -- newtab = '\0'; -- else -- error (EXIT_FAILURE, 0, _("multi-character tab %s"), -- quote (optarg)); -+ if (newtablen == 1 && newtab[1]) -+ { -+ if (STREQ (newtab, "\\0")) -+ newtab[0] = '\0'; -+ } -+ } -+ if (tab != NULL && strcmp (tab, newtab)) -+ { -+ free (newtab); -+ error (EXIT_FAILURE, 0, _("incompatible tabs")); - } -- if (0 <= tab && tab != newtab) -- error (EXIT_FAILURE, 0, _("incompatible tabs")); - tab = newtab; -+ tablen = newtablen; - } - break; - diff --git a/src/local.mk b/src/local.mk -index f45b911..6f7036a 100644 +index 96ee941..8fdb8fc 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -447,8 +447,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -450,8 +450,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) -src_expand_SOURCES = src/expand.c src/expand-common.c -src_unexpand_SOURCES = src/unexpand.c src/expand-common.c -+src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c -+src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c ++src_expand_SOURCES = src/expand.c src/expand-common.c lib/mbfile.c lib/mbchar.c ++src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c lib/mbchar.c src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 419545c..702e025 100644 +index 09c6fa8..7552b62 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ + #include #include - #include #include + +/* Get MB_LEN_MAX. */ @@ -2831,7 +2769,7 @@ index 419545c..702e025 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2496,9 +2695,9 @@ read_line (COLUMN *p) +@@ -2495,9 +2694,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2843,7 +2781,7 @@ index 419545c..702e025 100644 padding_not_printed = ANYWHERE; } -@@ -2567,7 +2766,7 @@ print_stored (COLUMN *p) +@@ -2566,7 +2765,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -2852,7 +2790,7 @@ index 419545c..702e025 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2579,7 +2778,7 @@ print_stored (COLUMN *p) +@@ -2578,7 +2777,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2861,7 +2799,7 @@ index 419545c..702e025 100644 pad_vertically = true; -@@ -2599,9 +2798,9 @@ print_stored (COLUMN *p) +@@ -2598,9 +2797,9 @@ print_stored (COLUMN *p) } } @@ -2873,7 +2811,7 @@ index 419545c..702e025 100644 padding_not_printed = ANYWHERE; } -@@ -2614,8 +2813,8 @@ print_stored (COLUMN *p) +@@ -2613,8 +2812,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2884,7 +2822,7 @@ index 419545c..702e025 100644 } return true; -@@ -2634,7 +2833,7 @@ print_stored (COLUMN *p) +@@ -2633,7 +2832,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2893,7 +2831,7 @@ index 419545c..702e025 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2644,10 +2843,10 @@ char_to_clump (char c) +@@ -2643,10 +2842,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2906,7 +2844,7 @@ index 419545c..702e025 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2728,6 +2927,164 @@ char_to_clump (char c) +@@ -2727,6 +2926,164 @@ char_to_clump (char c) return chars; } @@ -3072,10 +3010,10 @@ index 419545c..702e025 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index e779845..1f5c337 100644 +index 2d8324c..46331b8 100644 --- a/src/sort.c +++ b/src/sort.c -@@ -28,6 +28,14 @@ +@@ -29,6 +29,14 @@ #include #include #include @@ -3148,7 +3086,7 @@ index e779845..1f5c337 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -803,6 +834,46 @@ reap_all (void) +@@ -804,6 +835,46 @@ reap_all (void) reap (-1); } @@ -3195,7 +3133,7 @@ index e779845..1f5c337 100644 /* Clean up any remaining temporary files. */ static void -@@ -1270,7 +1341,7 @@ zaptemp (char const *name) +@@ -1271,7 +1342,7 @@ zaptemp (char const *name) free (node); } @@ -3204,7 +3142,7 @@ index e779845..1f5c337 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1285,7 +1356,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1286,7 +1357,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3213,7 +3151,7 @@ index e779845..1f5c337 100644 { size_t i; -@@ -1297,7 +1368,7 @@ inittables (void) +@@ -1298,7 +1369,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3222,7 +3160,7 @@ index e779845..1f5c337 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1379,6 +1450,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1380,6 +1451,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3307,7 +3245,7 @@ index e779845..1f5c337 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1610,7 +1759,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1611,7 +1760,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3316,7 +3254,7 @@ index e779845..1f5c337 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1619,10 +1768,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1620,10 +1769,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3329,7 +3267,7 @@ index e779845..1f5c337 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1648,12 +1797,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1649,12 +1798,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3402,7 +3340,7 @@ index e779845..1f5c337 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1668,10 +1876,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1669,10 +1877,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3415,7 +3353,7 @@ index e779845..1f5c337 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1717,10 +1925,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1718,10 +1926,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3428,7 +3366,7 @@ index e779845..1f5c337 100644 if (newlim) lim = newlim; } -@@ -1751,6 +1959,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1752,6 +1960,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3559,7 +3497,7 @@ index e779845..1f5c337 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1837,8 +2169,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1838,8 +2170,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3584,7 +3522,7 @@ index e779845..1f5c337 100644 line->keybeg = line_start; } } -@@ -1976,12 +2322,10 @@ find_unit_order (char const *number) +@@ -1977,12 +2323,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3600,7 +3538,7 @@ index e779845..1f5c337 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1993,7 +2337,7 @@ human_numcompare (char const *a, char const *b) +@@ -1994,7 +2338,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3609,7 +3547,7 @@ index e779845..1f5c337 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2003,6 +2347,25 @@ numcompare (char const *a, char const *b) +@@ -2004,6 +2348,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3635,7 +3573,7 @@ index e779845..1f5c337 100644 static int nan_compare (long double a, long double b) { -@@ -2044,7 +2407,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2045,7 +2408,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3644,7 +3582,7 @@ index e779845..1f5c337 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2320,15 +2683,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2372,15 +2735,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3662,7 +3600,7 @@ index e779845..1f5c337 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2474,7 +2836,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2526,7 +2888,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3671,7 +3609,7 @@ index e779845..1f5c337 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2522,9 +2884,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2574,9 +2936,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3684,7 +3622,7 @@ index e779845..1f5c337 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2535,9 +2897,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3697,7 +3635,7 @@ index e779845..1f5c337 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2545,19 +2907,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2597,19 +2959,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3721,7 +3659,7 @@ index e779845..1f5c337 100644 } } -@@ -2568,7 +2930,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2620,7 +2982,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) { error (0, 0, _("%snumbers use %s as a decimal point in this locale"), @@ -3730,7 +3668,7 @@ index e779845..1f5c337 100644 quote (((char []) {decimal_point, 0}))); } -@@ -2610,11 +2972,87 @@ diff_reversed (int diff, bool reversed) +@@ -2662,11 +3024,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3819,7 +3757,7 @@ index e779845..1f5c337 100644 { struct keyfield *key = keylist; -@@ -2695,7 +3133,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2747,7 +3185,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3828,7 +3766,7 @@ index e779845..1f5c337 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2805,6 +3243,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2857,6 +3295,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -4040,7 +3978,7 @@ index e779845..1f5c337 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2832,7 +3475,7 @@ compare (struct line const *a, struct line const *b) +@@ -2884,7 +3527,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -4049,7 +3987,7 @@ index e779845..1f5c337 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4220,6 +4863,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4272,6 +4915,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -4057,7 +3995,7 @@ index e779845..1f5c337 100644 break; case 'g': key->general_numeric = true; -@@ -4299,7 +4943,7 @@ main (int argc, char **argv) +@@ -4351,7 +4995,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4066,7 +4004,7 @@ index e779845..1f5c337 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4322,6 +4966,29 @@ main (int argc, char **argv) +@@ -4374,6 +5018,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4096,7 +4034,7 @@ index e779845..1f5c337 100644 have_read_stdin = false; inittables (); -@@ -4592,13 +5259,34 @@ main (int argc, char **argv) +@@ -4644,13 +5311,34 @@ main (int argc, char **argv) case 't': { @@ -4135,7 +4073,7 @@ index e779845..1f5c337 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4609,9 +5297,11 @@ main (int argc, char **argv) +@@ -4661,9 +5349,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4150,10 +4088,10 @@ index e779845..1f5c337 100644 break; diff --git a/src/unexpand.c b/src/unexpand.c -index 5a2283f..f24ef76 100644 +index aca67dd..f79c808 100644 --- a/src/unexpand.c +++ b/src/unexpand.c -@@ -38,6 +38,9 @@ +@@ -39,6 +39,9 @@ #include #include #include @@ -4163,7 +4101,7 @@ index 5a2283f..f24ef76 100644 #include "system.h" #include "expand-common.h" -@@ -104,24 +107,47 @@ unexpand (void) +@@ -105,24 +108,47 @@ unexpand (void) { /* Input stream. */ FILE *fp = next_file (nullptr); @@ -4214,7 +4152,7 @@ index 5a2283f..f24ef76 100644 /* If true, perform translations. */ bool convert = true; -@@ -155,12 +181,44 @@ unexpand (void) +@@ -156,12 +182,44 @@ unexpand (void) do { @@ -4262,7 +4200,7 @@ index 5a2283f..f24ef76 100644 if (blank) { -@@ -177,16 +235,16 @@ unexpand (void) +@@ -178,16 +236,16 @@ unexpand (void) if (next_tab_column < column) error (EXIT_FAILURE, 0, _("input line is too long")); @@ -4282,7 +4220,7 @@ index 5a2283f..f24ef76 100644 if (! (prev_blank && column == next_tab_column)) { -@@ -194,13 +252,14 @@ unexpand (void) +@@ -195,13 +253,14 @@ unexpand (void) will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -4299,7 +4237,7 @@ index 5a2283f..f24ef76 100644 } /* Discard pending blanks, unless it was a single -@@ -208,7 +267,7 @@ unexpand (void) +@@ -209,7 +268,7 @@ unexpand (void) pending = one_blank_before_tab_stop; } } @@ -4308,7 +4246,7 @@ index 5a2283f..f24ef76 100644 { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -218,16 +277,20 @@ unexpand (void) +@@ -219,16 +278,20 @@ unexpand (void) } else { @@ -4333,7 +4271,7 @@ index 5a2283f..f24ef76 100644 write_error (); pending = 0; one_blank_before_tab_stop = false; -@@ -237,16 +300,17 @@ unexpand (void) +@@ -238,16 +301,17 @@ unexpand (void) convert &= convert_entire_line || blank; } @@ -4354,173 +4292,8 @@ index 5a2283f..f24ef76 100644 } } -diff --git a/src/uniq.c b/src/uniq.c -index fab04de..2e96dcb 100644 ---- a/src/uniq.c -+++ b/src/uniq.c -@@ -21,6 +21,17 @@ - #include - #include - -+/* Get mbstate_t, mbrtowc(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get isw* functions. */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+#include -+ - #include "system.h" - #include "argmatch.h" - #include "linebuffer.h" -@@ -31,6 +42,18 @@ - #include "memcasecmp.h" - #include "quote.h" - -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC -+ installation; work around this configuration error. */ -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 -+# define MB_LEN_MAX 16 -+#endif -+ -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ -+#if HAVE_MBRTOWC && defined mbstate_t -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -+#endif -+ -+ - /* The official name of this program (e.g., no 'g' prefix). */ - #define PROGRAM_NAME "uniq" - -@@ -137,6 +160,10 @@ enum - GROUP_OPTION = CHAR_MAX + 1 - }; - -+/* Function pointers. */ -+static char * -+(*find_field) (struct linebuffer *line); -+ - static struct option const longopts[] = - { - {"count", no_argument, nullptr, 'c'}, -@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *msgid) - - ATTRIBUTE_PURE - static char * --find_field (struct linebuffer const *line) -+find_field_uni (struct linebuffer *line) - { - size_t count; - char const *lp = line->buffer; -@@ -272,6 +299,83 @@ find_field (struct linebuffer const *line) - return line->buffer + i; - } - -+#if HAVE_MBRTOWC -+ -+# define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \ -+ do \ -+ { \ -+ mbstate_t state_bak; \ -+ \ -+ CONVFAIL = 0; \ -+ state_bak = *STATEP; \ -+ \ -+ MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ -+ \ -+ switch (MBLENGTH) \ -+ { \ -+ case (size_t)-2: \ -+ case (size_t)-1: \ -+ *STATEP = state_bak; \ -+ CONVFAIL++; \ -+ /* Fall through */ \ -+ case 0: \ -+ MBLENGTH = 1; \ -+ } \ -+ } \ -+ while (0) -+ -+static char * -+find_field_multi (struct linebuffer *line) -+{ -+ size_t count; -+ char *lp = line->buffer; -+ size_t size = line->length - 1; -+ size_t pos; -+ size_t mblength; -+ wchar_t wc; -+ mbstate_t *statep; -+ int convfail = 0; -+ -+ pos = 0; -+ statep = &(line->state); -+ -+ /* skip fields. */ -+ for (count = 0; count < skip_fields && pos < size; count++) -+ { -+ while (pos < size) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); -+ -+ if (convfail || !(iswblank (wc) || wc == '\n')) -+ { -+ pos += mblength; -+ break; -+ } -+ pos += mblength; -+ } -+ -+ while (pos < size) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); -+ -+ if (!convfail && (iswblank (wc) || wc == '\n')) -+ break; -+ -+ pos += mblength; -+ } -+ } -+ -+ /* skip fields. */ -+ for (count = 0; count < skip_chars && pos < size; count++) -+ { -+ MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); -+ pos += mblength; -+ } -+ -+ return lp + pos; -+} -+#endif -+ - /* Return false if two strings OLD and NEW match, true if not. - OLD and NEW point not to the beginnings of the lines - but rather to the beginnings of the fields to compare. -@@ -495,6 +599,19 @@ main (int argc, char **argv) - - atexit (close_stdout); - -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ { -+ find_field = find_field_multi; -+ } -+ else -+#endif -+ { -+ find_field = find_field_uni; -+ } -+ -+ -+ - skip_chars = 0; - skip_fields = 0; - check_chars = SIZE_MAX; diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm -index f147401..3ce5da9 100644 +index 18e7bea..24a141b 100644 --- a/tests/Coreutils.pm +++ b/tests/Coreutils.pm @@ -269,6 +269,9 @@ sub run_tests ($$$$$) @@ -4534,7 +4307,7 @@ index f147401..3ce5da9 100644 { warn "$program_name: $test_name: test name is too long (> $max)\n"; diff --git a/tests/expand/mb.sh b/tests/expand/mb.sh -new file mode 100755 +new file mode 100644 index 0000000..dd6007c --- /dev/null +++ b/tests/expand/mb.sh @@ -4723,7 +4496,7 @@ index 0000000..dd6007c + +exit $fail diff --git a/tests/i18n/sort.sh b/tests/i18n/sort.sh -new file mode 100755 +new file mode 100644 index 0000000..26c95de --- /dev/null +++ b/tests/i18n/sort.sh @@ -4758,10 +4531,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index b74a4a2..fe6e557 100644 +index fdbf369..a6ce49c 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -384,6 +384,8 @@ all_tests = \ +@@ -387,6 +387,8 @@ all_tests = \ tests/sort/sort-discrim.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -4770,7 +4543,7 @@ index b74a4a2..fe6e557 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -585,6 +587,7 @@ all_tests = \ +@@ -590,6 +592,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4778,7 +4551,7 @@ index b74a4a2..fe6e557 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -738,6 +741,7 @@ all_tests = \ +@@ -746,6 +749,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4787,7 +4560,7 @@ index b74a4a2..fe6e557 100644 # See tests/factor/create-test.sh. diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index 06261ac..7dd813e 100755 +index 11f3fc4..d609a2c 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -4854,7 +4627,7 @@ index 06261ac..7dd813e 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index a94072f..136a82e 100755 +index 00b4362..7d51bea 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,18 @@ use strict; @@ -4926,78 +4699,8 @@ index a94072f..136a82e 100755 -my $prog = 'fold'; my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); exit $fail; -diff --git a/tests/misc/join.pl b/tests/misc/join.pl -index 2ca8567..1d01a3d 100755 ---- a/tests/misc/join.pl -+++ b/tests/misc/join.pl -@@ -25,6 +25,15 @@ my $limits = getlimits (); - - my $prog = 'join'; - -+my $try = "Try \`$prog --help' for more information.\n"; -+my $inval = "$prog: invalid byte, character or field list\n$try"; -+ -+my $mb_locale; -+#Comment out next line to disable multibyte tests -+$mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; -+ - my $delim = chr 0247; - sub t_subst ($) - { -@@ -333,8 +342,49 @@ foreach my $t (@tv) - push @Tests, $new_ent; - } - -+# Add _POSIX2_VERSION=199209 to the environment of each test -+# that uses an old-style option like +1. -+if ($mb_locale ne 'C') -+ { -+ # Duplicate each test vector, appending "-mb" to the test name and -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we -+ # provide coverage for the distro-added multi-byte code paths. -+ my @new; -+ foreach my $t (@Tests) -+ { -+ my @new_t = @$t; -+ my $test_name = shift @new_t; -+ -+ # Depending on whether join is multi-byte-patched, -+ # it emits different diagnostics: -+ # non-MB: invalid byte or field list -+ # MB: invalid byte, character or field list -+ # Adjust the expected error output accordingly. -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+ (@new_t)) -+ { -+ my $sub = {ERR_SUBST => 's/, character//'}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ #Adjust the output some error messages including test_name for mb -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR}} -+ (@new_t)) -+ { -+ my $sub2 = {ERR_SUBST => "s/$test_name-mb/$test_name/"}; -+ push @new_t, $sub2; -+ push @$t, $sub2; -+ } -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; -+ } -+ push @Tests, @new; -+ } -+ - @Tests = triple_test \@Tests; - -+#skip invalid-j-mb test, it is failing because of the format -+@Tests = grep {$_->[0] ne 'invalid-j-mb'} @Tests; -+ - my $save_temps = $ENV{DEBUG}; - my $verbose = $ENV{VERBOSE}; - diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh -new file mode 100755 +new file mode 100644 index 0000000..11836ba --- /dev/null +++ b/tests/misc/sort-mb-tests.sh @@ -5048,7 +4751,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index d78a1bc..2b9137d 100755 +index 76bcbd4..59eb819 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -5105,7 +4808,7 @@ index d78a1bc..2b9137d 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index eafc13d..c1eca2a 100755 +index 6b34e0b..34b4aeb 100755 --- a/tests/pr/pr-tests.pl +++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; @@ -5174,7 +4877,7 @@ index eafc13d..c1eca2a 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort-merge.pl b/tests/sort/sort-merge.pl -index bd439ef..2ccdf87 100755 +index 89eed0c..b855d73 100755 --- a/tests/sort/sort-merge.pl +++ b/tests/sort/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; @@ -5234,7 +4937,7 @@ index bd439ef..2ccdf87 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl -index 46f1d7a..bb38f5b 100755 +index d49f65f..ebba925 100755 --- a/tests/sort/sort.pl +++ b/tests/sort/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -5302,7 +5005,7 @@ index 46f1d7a..bb38f5b 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; diff --git a/tests/unexpand/mb.sh b/tests/unexpand/mb.sh -new file mode 100755 +new file mode 100644 index 0000000..8a82d74 --- /dev/null +++ b/tests/unexpand/mb.sh @@ -5479,82 +5182,6 @@ index 0000000..8a82d74 + +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -diff --git a/tests/uniq/uniq.pl b/tests/uniq/uniq.pl -index a6354dc..e43cd6e 100755 ---- a/tests/uniq/uniq.pl -+++ b/tests/uniq/uniq.pl -@@ -23,9 +23,17 @@ my $limits = getlimits (); - my $prog = 'uniq'; - my $try = "Try '$prog --help' for more information.\n"; - -+my $inval = "$prog: invalid byte, character or field list\n$try"; -+ - # Turn off localization of executable's output. - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; - -+my $mb_locale; -+#Comment out next line to disable multibyte tests -+$mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; -+ - # When possible, create a "-z"-testing variant of each test. - sub add_z_variants($) - { -@@ -262,6 +270,53 @@ foreach my $t (@Tests) - and push @$t, {ENV=>'_POSIX2_VERSION=199209'}; - } - -+if ($mb_locale ne 'C') -+ { -+ # Duplicate each test vector, appending "-mb" to the test name and -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we -+ # provide coverage for the distro-added multi-byte code paths. -+ my @new; -+ foreach my $t (@Tests) -+ { -+ my @new_t = @$t; -+ my $test_name = shift @new_t; -+ -+ # Depending on whether uniq is multi-byte-patched, -+ # it emits different diagnostics: -+ # non-MB: invalid byte or field list -+ # MB: invalid byte, character or field list -+ # Adjust the expected error output accordingly. -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+ (@new_t)) -+ { -+ my $sub = {ERR_SUBST => 's/, character//'}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ # In test #145, replace the each ‘...’ by '...'. -+ if ($test_name =~ "145") -+ { -+ my $sub = { ERR_SUBST => "s/‘([^’]+)’/'\$1'/g"}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ next if ( $test_name =~ "schar" -+ or $test_name =~ "^obs-plus" -+ or $test_name =~ "119"); -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; -+ } -+ push @Tests, @new; -+ } -+ -+# Remember that triple_test creates from each test with exactly one "IN" -+# file two more tests (.p and .r suffix on name) corresponding to reading -+# input from a file and from a pipe. The pipe-reading test would fail -+# due to a race condition about 1 in 20 times. -+# Remove the IN_PIPE version of the "output-is-input" test above. -+# The others aren't susceptible because they have three inputs each. -+ -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; -+ - @Tests = add_z_variants \@Tests; - @Tests = triple_test \@Tests; - -- -2.43.0 +2.44.0 diff --git a/coreutils-python3.patch b/coreutils-python3.patch new file mode 100644 index 0000000..98fc642 --- /dev/null +++ b/coreutils-python3.patch @@ -0,0 +1,65 @@ +From cef9cccce395cd80cd5ac42a4fe6c3909be1c0b5 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 2 Apr 2024 14:11:26 +0100 +Subject: [PATCH] coreutils-python3.patch + +--- + init.cfg | 4 ++-- + tests/d_type-check | 2 +- + tests/du/move-dir-while-traversing.sh | 6 +++--- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/init.cfg b/init.cfg +index b06965a..08413ee 100644 +--- a/init.cfg ++++ b/init.cfg +@@ -581,10 +581,10 @@ seek_data_capable_() + # Skip the current test if "." lacks d_type support. + require_dirent_d_type_() + { +- python < /dev/null \ ++ python3 < /dev/null \ + || skip_ python missing: assuming no d_type support + +- python "$abs_srcdir"/tests/d_type-check \ ++ python3 "$abs_srcdir"/tests/d_type-check \ + || skip_ requires d_type support + } + +diff --git a/tests/d_type-check b/tests/d_type-check +index 1a2f76f..42d3924 100644 +--- a/tests/d_type-check ++++ b/tests/d_type-check +@@ -1,4 +1,4 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 + # Exit 0 if "." and "./tempfile" have useful d_type information, else 1. + # Intended to exit 0 only on Linux/GNU systems. + import os +diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh +index 830a69e..7344ddf 100755 +--- a/tests/du/move-dir-while-traversing.sh ++++ b/tests/du/move-dir-while-traversing.sh +@@ -21,8 +21,8 @@ print_ver_ du + require_trap_signame_ + + # We use a python-inotify script, so... +-python -m pyinotify -h > /dev/null \ +- || skip_ 'python inotify package not installed' ++python3 -m pyinotify -h > /dev/null \ ++ || skip_ 'python3 inotify package not installed' + + # Move a directory "up" while du is processing its sub-directories. + # While du is processing a hierarchy .../B/C/D/... this script +@@ -33,7 +33,7 @@ python -m pyinotify -h > /dev/null \ + # rename syscall before du finishes processing the subtree under D/. + + cat <<'EOF' > inotify-watch-for-dir-access.py +-#!/usr/bin/env python ++#!/usr/bin/env python3 + import pyinotify as pn + import os,sys + +-- +2.44.0 + diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index 66e06e1..a31c3af 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,4 +1,4 @@ -From 88ba186955add2b230c017749d5622f7a0d62177 Mon Sep 17 00:00:00 2001 +From 78970c915b8556fcec4622e948a37dd8e34efe6d Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-selinux.patch @@ -9,10 +9,10 @@ Subject: [PATCH] coreutils-selinux.patch 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cp.c b/src/cp.c -index 04a5cbe..7a364e5 100644 +index 28b0217..897379f 100644 --- a/src/cp.c +++ b/src/cp.c -@@ -989,7 +989,7 @@ main (int argc, char **argv) +@@ -997,7 +997,7 @@ main (int argc, char **argv) selinux_enabled = (0 < is_selinux_enabled ()); cp_option_init (&x); @@ -21,7 +21,7 @@ index 04a5cbe..7a364e5 100644 long_opts, nullptr)) != -1) { -@@ -1041,6 +1041,23 @@ main (int argc, char **argv) +@@ -1049,6 +1049,23 @@ main (int argc, char **argv) copy_contents = true; break; @@ -46,7 +46,7 @@ index 04a5cbe..7a364e5 100644 x.preserve_links = true; x.dereference = DEREF_NEVER; diff --git a/src/install.c b/src/install.c -index 31a48f1..ce9fa2d 100644 +index accd0fd..b686fe9 100644 --- a/src/install.c +++ b/src/install.c @@ -807,7 +807,7 @@ main (int argc, char **argv) @@ -83,5 +83,5 @@ index 31a48f1..ce9fa2d 100644 use_default_selinux_context = false; break; -- -2.41.0 +2.44.0 diff --git a/coreutils.spec b/coreutils.spec index f1d68b3..e72ca20 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.4 -Release: 6%{?dist} +Version: 9.5 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -26,18 +26,12 @@ Patch101: coreutils-8.26-selinuxenable.patch # downstream changes to default DIR_COLORS Patch102: coreutils-8.32-DIR_COLORS.patch +# use python3 in tests +Patch103: coreutils-python3.patch + # df --direct Patch104: coreutils-df-direct.patch -# fix crash with --enable-systemd -Patch105: coreutils-9.4-systemd-coredump.patch - -# fix buffer overflow in split (CVE-2024-0684) -Patch106: coreutils-9.4-CVE-2024-0684.patch - -# fix tail on kernels with 64k pagesize -Patch107: coreutils-9.4-tail-64k-pages.patch - # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -70,13 +64,26 @@ BuildRequires: texinfo BuildRequires: gnupg2 # test-only dependencies +BuildRequires: acl +BuildRequires: gdb BuildRequires: perl-interpreter +BuildRequires: perl(Expect) BuildRequires: perl(FileHandle) +BuildRequires: python3 +%if 0%{?fedora} +BuildRequires: python3-inotify +%endif +BuildRequires: tzdata +%ifarch %valgrind_arches +BuildRequires: valgrind +%endif + %if 23 < 0%{?fedora} || 7 < 0%{?rhel} # needed by i18n test-cases BuildRequires: glibc-langpack-en BuildRequires: glibc-langpack-fr BuildRequires: glibc-langpack-ko +BuildRequires: glibc-langpack-sv %endif Requires: %{name}-common = %{version}-%{release} @@ -262,6 +269,11 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Apr 02 2024 Lukáš Zaoral - 9.5-1 +- rebase to latest upstream version (rhbz#2272063) +- sync i18n patch with SUSE (Kudos to Berny Völker!) +- add some test dependencies to execute additional part of the upstream test-suite + * Mon Jan 29 2024 Lukáš Zaoral - 9.4-6 - fix tail on kernels with 64k page sizes (RHEL-22866) diff --git a/sources b/sources index ac58478..d9dc6c9 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.4.tar.xz) = 7c55ee23b685a0462bbbd118b04d25278c902604a0dcf3bf4f8bf81faa0500dee5a7813cba6f586d676c98e520cafd420f16479619305e94ea6798d8437561f5 -SHA512 (coreutils-9.4.tar.xz.sig) = 9674f783f592c4f3e5c708ff31426ac009bf132fd0005019571bf39c8a1627efb5351c6cecc7faecb1eff8fa2970318666593bffc0eda9c750159e174ef42524 +SHA512 (coreutils-9.5.tar.xz) = 2ca0deac4dc10a80fd0c6fd131252e99d457fd03b7bd626a6bc74fe5a0529c0a3d48ce1f5da1d3b3a7a150a1ce44f0fbb6b68a6ac543dfd5baa3e71f5d65401c +SHA512 (coreutils-9.5.tar.xz.sig) = 029997e0f4ee64e561853cff7c8a124f58cc891598595b44c4a46f9813b4b71c9d677464bc8a26d294e9971832f4b87c23777fea4fac6e8e30f06ad93b9957d5 From 56dd448b2652398ad937655e9426281ca4e973e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 4 Jun 2024 12:56:50 +0200 Subject: [PATCH 496/523] enable LTO on ppc64le --- coreutils.spec | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index e72ca20..26a9b6c 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -157,11 +157,6 @@ autoreconf -fiv %build export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fpic" -# disable -flto on ppc64le to make test-float pass (#1789115) -%ifarch ppc64le -CFLAGS="$CFLAGS -fno-lto" -%endif - # Upstream suggests to build with -Dlint for static analyzers: # https://lists.gnu.org/archive/html/coreutils/2018-06/msg00110.html # ... and even for production binary RPMs: @@ -269,6 +264,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jun 04 2024 Lukáš Zaoral - 9.5-2 +- enable LTO on ppc64le + * Tue Apr 02 2024 Lukáš Zaoral - 9.5-1 - rebase to latest upstream version (rhbz#2272063) - sync i18n patch with SUSE (Kudos to Berny Völker!) From 1421739c0cc39be1278749b8f5fda27ef00adf80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Thu, 4 Jul 2024 13:18:36 +0200 Subject: [PATCH 497/523] do not buildrequire perl(Expect) on ELN --- coreutils.spec | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 26a9b6c..3b2ba13 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 2%{?dist} +Release: 3%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -67,17 +67,18 @@ BuildRequires: gnupg2 BuildRequires: acl BuildRequires: gdb BuildRequires: perl-interpreter -BuildRequires: perl(Expect) BuildRequires: perl(FileHandle) BuildRequires: python3 -%if 0%{?fedora} -BuildRequires: python3-inotify -%endif BuildRequires: tzdata %ifarch %valgrind_arches BuildRequires: valgrind %endif +%if 0%{?fedora} +BuildRequires: perl(Expect) +BuildRequires: python3-inotify +%endif + %if 23 < 0%{?fedora} || 7 < 0%{?rhel} # needed by i18n test-cases BuildRequires: glibc-langpack-en @@ -264,6 +265,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jul 04 2024 Lukáš Zaoral - 9.5-3 +- do not buildrequire perl(Expect) on ELN + * Tue Jun 04 2024 Lukáš Zaoral - 9.5-2 - enable LTO on ppc64le From ba7b19b5bf29c73dcf7451351d43e28cdab6ef6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 10 Apr 2024 15:42:59 +0200 Subject: [PATCH 498/523] Fix build when %_bindir==%_sbindir - Rebuild for https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- coreutils.spec | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/coreutils.spec b/coreutils.spec index 3b2ba13..dfc1efc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -213,14 +213,20 @@ for type in separate single; do fi (cd $type && make DESTDIR=$RPM_BUILD_ROOT/$subdir $install) +%if "%{_sbindir}" != "%{_bindir}" # chroot was in /usr/sbin : - mkdir -p $RPM_BUILD_ROOT/$subdir/{%{_bindir},%{_sbindir}} + mkdir -p $RPM_BUILD_ROOT/$subdir/%_sbindir mv $RPM_BUILD_ROOT/$subdir/{%_bindir,%_sbindir}/chroot +%endif # Move multicall variants to *.single. # RemovePathPostfixes will strip that later. if test $type = 'single'; then - for dir in %{_bindir} %{_sbindir} %{_libexecdir}/%{name}; do + for dir in %{_bindir} \ +%if "%{_sbindir}" != "%{_bindir}" +%{_sbindir} \ +%endif +%{_libexecdir}/%{name}; do for bin in $RPM_BUILD_ROOT/%{_libexecdir}/%{name}/$dir/*; do basebin=$(basename $bin) mv $bin $RPM_BUILD_ROOT/$dir/$basebin.single @@ -248,7 +254,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %files single %{_bindir}/*.single +%if "%{_sbindir}" != "%{_bindir}" %{_sbindir}/chroot.single +%endif %dir %{_libexecdir}/coreutils %{_libexecdir}/coreutils/*.so.single # duplicate the license because coreutils-common does not need to be installed From 7c8ffed47081707708c39c7bcf23bdf08b65564d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 9 Jul 2024 14:13:28 +0200 Subject: [PATCH 499/523] Rebuilt for the bin-sbin merge https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index dfc1efc..e4a8387 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 3%{?dist} +Release: 4%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 9.5-4 +- Rebuilt for the bin-sbin merge + * Thu Jul 04 2024 Lukáš Zaoral - 9.5-3 - do not buildrequire perl(Expect) on ELN From e02261a471f26a190b9995bcfce73fd868b87019 Mon Sep 17 00:00:00 2001 From: Sohum Mendon Date: Sat, 13 Jul 2024 14:02:20 -0700 Subject: [PATCH 500/523] Fix fold exit status for nonexistent files Resolves: rhbz#2296201 --- coreutils-i18n.patch | 2 +- coreutils.spec | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index aa21a35..214c2ac 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -2182,7 +2182,7 @@ index 941ad11..cf1e747 100644 + if (istream == NULL) + { + error (0, errno, "%s", filename); -+ return 1; ++ return false; + } + + /* Define how ISTREAM is being folded. */ diff --git a/coreutils.spec b/coreutils.spec index e4a8387..c2804b5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 4%{?dist} +Release: 5%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jul 15 2024 Sohum Mendon - 9.5-5 +- fix incorrect exit status when fold is called with a non-existent file + * Tue Jul 09 2024 Zbigniew Jędrzejewski-Szmek - 9.5-4 - Rebuilt for the bin-sbin merge From 6cd5ce1d7ef1def8a5cf6ff954a069b16768d565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 15 Jul 2024 14:16:53 +0200 Subject: [PATCH 501/523] Rebuilt for the bin-sbin merge https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index c2804b5..5609090 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 5%{?dist} +Release: 6%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jul 15 2024 Lukáš Zaoral - 9.5-6 +- Rebuilt for the bin-sbin merge + * Mon Jul 15 2024 Sohum Mendon - 9.5-5 - fix incorrect exit status when fold is called with a non-existent file From a09814d13c6034dbee940f05b043b90046518fb5 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 17 Jul 2024 20:00:43 +0000 Subject: [PATCH 502/523] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 5609090..f31f9b4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 6%{?dist} +Release: 7%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -273,6 +273,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jul 17 2024 Fedora Release Engineering - 9.5-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Mon Jul 15 2024 Lukáš Zaoral - 9.5-6 - Rebuilt for the bin-sbin merge From d3137f0cd04f6c716ef7c64ae35aa653e22aefea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Wed, 21 Aug 2024 17:32:11 +0200 Subject: [PATCH 503/523] add missing systemd-devel buildrequires Fixes: bf0817f5a59c71d2a72363e457baa5ff8f80cd27 (new upstream release 9.4) --- coreutils.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index f31f9b4..db0bd0d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 7%{?dist} +Release: 8%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -58,6 +58,7 @@ BuildRequires: libselinux-utils BuildRequires: make BuildRequires: openssl-devel BuildRequires: strace +BuildRequires: systemd-devel BuildRequires: texinfo # For gpg verification of source tarball @@ -273,6 +274,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Aug 21 2024 Lukáš Zaoral - 9.5-8 +- add missing systemd-devel buildrequires + * Wed Jul 17 2024 Fedora Release Engineering - 9.5-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From e3b928358bf5ce47aaa8fa855b2df2590eda6c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 26 Aug 2024 13:02:12 +0200 Subject: [PATCH 504/523] tests: remove unmaintained STI tests --- .../Makefile | 63 ------------------- .../PURPOSE | 54 ---------------- .../runtest.sh | 60 ------------------ tests/test-basics | 39 ------------ tests/test_basics.yml | 9 --- tests/tests.yml | 2 - 6 files changed, 227 deletions(-) delete mode 100644 tests/readlink-cannot-handle-recursive-symlinks/Makefile delete mode 100644 tests/readlink-cannot-handle-recursive-symlinks/PURPOSE delete mode 100755 tests/readlink-cannot-handle-recursive-symlinks/runtest.sh delete mode 100755 tests/test-basics delete mode 100644 tests/test_basics.yml delete mode 100644 tests/tests.yml diff --git a/tests/readlink-cannot-handle-recursive-symlinks/Makefile b/tests/readlink-cannot-handle-recursive-symlinks/Makefile deleted file mode 100644 index 49d37a7..0000000 --- a/tests/readlink-cannot-handle-recursive-symlinks/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# Makefile of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlink s -# Description: Test for readlink cannot handle recursive symlinks -# Author: Jan Scotka -# -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# Copyright (c) 2010 Red Hat, Inc. All rights reserved. -# -# This copyrighted material is made available to anyone wishing -# to use, modify, copy, or redistribute it subject to the terms -# and conditions of the GNU General Public License version 2. -# -# This program is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied -# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -# PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public -# License along with this program; if not, write to the Free -# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301, USA. -# -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -export TEST=/CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks -export TESTVERSION=1.0 - -BUILT_FILES= - -FILES=$(METADATA) runtest.sh Makefile PURPOSE - -.PHONY: all install download clean - -run: $(FILES) build - ./runtest.sh - -build: $(BUILT_FILES) - chmod a+x runtest.sh - -clean: - rm -f *~ $(BUILT_FILES) - - -include /usr/share/rhts/lib/rhts-make.include - -$(METADATA): Makefile - @echo "Owner: Jan Scotka " > $(METADATA) - @echo "Name: $(TEST)" >> $(METADATA) - @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) - @echo "Path: $(TEST_DIR)" >> $(METADATA) - @echo "Description: Test for readlink cannot handle recursive symlinks" >> $(METADATA) - @echo "Type: Sanity" >> $(METADATA) - @echo "TestTime: 5m" >> $(METADATA) - @echo "RunFor: coreutils" >> $(METADATA) - @echo "Requires: coreutils" >> $(METADATA) - @echo "Priority: Normal" >> $(METADATA) - @echo "License: GPLv2" >> $(METADATA) - @echo "Confidential: no" >> $(METADATA) - @echo "Destructive: no" >> $(METADATA) - - rhts-lint $(METADATA) diff --git a/tests/readlink-cannot-handle-recursive-symlinks/PURPOSE b/tests/readlink-cannot-handle-recursive-symlinks/PURPOSE deleted file mode 100644 index b9fd740..0000000 --- a/tests/readlink-cannot-handle-recursive-symlinks/PURPOSE +++ /dev/null @@ -1,54 +0,0 @@ -PURPOSE of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks -Description: Test for readlink cannot handle recursive symlinks -Author: Jan Scotka -Bug summary: readlink cannot handle recursive symlinks - -Description: - -Description of problem: -The readlink command fails with an error "Too many levels of symbolic links", even if there are only 2 levels. - -The readlink command from RHEL 3 and RHEL 4 and from Fedora 11 all work fine. - -Among other changes between RHEL 4 and RHEL 5, RHEL 5's coreutils added calls to cycle_check() in lib/canonicalize.c, but in upstream canonicalize.c (now in gnulib instead of coreutils), we see the comment: - /* Detect loops. We cannot use the cycle-check module here, - since it's actually possible to encounter the same symlink - more than once in a given traversal. However, encountering - the same symlink,NAME pair twice does indicate a loop. */ - -http://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/canonicalize.c;h=4f348398fd69ae516396313d18ac294a4ca3dde3;hb=b653eda3ac4864de205419d9f41eec267cb89eeb#l262 - -The latest canonicalize.c uses seen_triple() instead of cycle_check(). - - -Version-Release number of selected component (if applicable): -coreutils-5.97-19.el5 - -How reproducible: -every time - -Steps to Reproduce: -1. Create a directory with a symlink to itself - mkdir /tmp/dir - cd /tmp/dir - ln -s ../dir dirlink - -2. Run readlink using the 'dirlink' symlink recursively - readlink -v -f dirlink - readlink -v -f dirlink/dirlink - readlink -v -f dirlink/dirlink/dirlink - -Actual results: -The first readlink command on just dirlink succeeds, but the 2nd and 3rd commands fail with - readlink: dirlink/dirlink: Too many levels of symbolic links - -Expected results: -$ readlink -v -f dirlink -/tmp/dir -$ readlink -v -f dirlink/dirlink -/tmp/dir -$ readlink -v -f dirlink/dirlink/dirlink -/tmp/dir - - -Additional info: diff --git a/tests/readlink-cannot-handle-recursive-symlinks/runtest.sh b/tests/readlink-cannot-handle-recursive-symlinks/runtest.sh deleted file mode 100755 index 6ee251f..0000000 --- a/tests/readlink-cannot-handle-recursive-symlinks/runtest.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# runtest.sh of /CoreOS/coreutils/readlink-cannot-handle-recursive-symlinks -# Description: Test for readlink cannot handle recursive symlinks -# Author: Jan Scotka -# -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# -# Copyright (c) 2010 Red Hat, Inc. All rights reserved. -# -# This copyrighted material is made available to anyone wishing -# to use, modify, copy, or redistribute it subject to the terms -# and conditions of the GNU General Public License version 2. -# -# This program is distributed in the hope that it will be -# useful, but WITHOUT ANY WARRANTY; without even the implied -# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -# PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public -# License along with this program; if not, write to the Free -# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301, USA. -# -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -# Include rhts environment -. /usr/bin/rhts-environment.sh -. /usr/lib/beakerlib/beakerlib.sh - -PACKAGE="coreutils" - -rlJournalStart - rlPhaseStartSetup - rlAssertRpm $PACKAGE - rlRun "TmpDir=\`mktemp -d\`" 0 "Creating tmp directory" - rlRun "pushd $TmpDir" - rlRun "mkdir link" 0 "Creating test directory" - rlRun "cd link" 0 "cd to this dir" - rlRun "ln -s ../link link" 0 "creating symlink to ../link -> link" - rlPhaseEnd - - rlPhaseStartTest - rlLog "Test of readlink up to 20 iteration" - export TMPVAR="link" - for foo in `seq 20` - do echo $TMPVAR - rlRun "readlink -v -f $TMPVAR" 0 "readlink of $TMPVAR" - TMPVAR="$TMPVAR/link" - done - rlPhaseEnd - - rlPhaseStartCleanup - rlRun "popd" - rlRun "rm -r $TmpDir" 0 "Removing tmp directory" - rlPhaseEnd -rlJournalPrintText -rlJournalEnd diff --git a/tests/test-basics b/tests/test-basics deleted file mode 100755 index 7324553..0000000 --- a/tests/test-basics +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -# Checks that touch ls rm and foo work -# https://www.mankier.com/1/beakerlib#Examples -. /usr/share/beakerlib/beakerlib.sh - -# Set the full test name -TEST="/examples/beakerlib/Sanity/phases" - -# Package being tested -PACKAGE="coreutils" - -rlJournalStart - # Setup phase: Prepare test directory - rlPhaseStartSetup - rlAssertRpm $PACKAGE - rlRun 'TmpDir=$(mktemp -d)' 0 'Creating tmp directory' # no-reboot - rlRun "pushd $TmpDir" - rlPhaseEnd - - # Test phase: Testing touch, ls and rm commands - rlPhaseStartTest - rlRun "touch foo" 0 "Creating the foo test file" - rlAssertExists "foo" - rlRun "ls -l foo" 0 "Listing the foo test file" - rlRun "rm foo" 0 "Removing the foo test file" - rlAssertNotExists "foo" - rlRun "ls -l foo" 2 "Listing foo should now report an error" - rlPhaseEnd - - # Cleanup phase: Remove test directory - rlPhaseStartCleanup - rlRun "popd" - rlRun "rm -r $TmpDir" 0 "Removing tmp directory" - rlPhaseEnd -rlJournalEnd - -# Print the test report -rlJournalPrintText diff --git a/tests/test_basics.yml b/tests/test_basics.yml deleted file mode 100644 index d5727cf..0000000 --- a/tests/test_basics.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -# This first play always runs on the local staging system -- hosts: localhost - tags: - - atomic - - classic - - container - roles: - - { role: standard-test-beakerlib, tests: [ test-basics, readlink-cannot-handle-recursive-symlinks ] } diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index 529263d..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,2 +0,0 @@ -# Fedora Continuous Integration: https://fedoraproject.org/wiki/CI -- include: test_basics.yml From 968cac099dbdfedbc529c2fb2b462ebc29996de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 27 Aug 2024 12:58:15 +0200 Subject: [PATCH 505/523] show web sessions in who output Resolves: rhbz#2307847 --- coreutils-9.5-readutmp-web-session.patch | 39 ++++++++++++++++++++++++ coreutils.spec | 9 +++++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.5-readutmp-web-session.patch diff --git a/coreutils-9.5-readutmp-web-session.patch b/coreutils-9.5-readutmp-web-session.patch new file mode 100644 index 0000000..32a87fe --- /dev/null +++ b/coreutils-9.5-readutmp-web-session.patch @@ -0,0 +1,39 @@ +From 43f7f428a1665950233557bd97611bd5e996b5cb Mon Sep 17 00:00:00 2001 +From: Bruno Haible +Date: Tue, 27 Aug 2024 11:46:33 +0200 +Subject: readutmp: In systemd mode, show sessions of type "web". + +Reported by Allison Karlitskaya in +. + +* lib/readutmp.c (read_utmp_from_systemd): For a systemd session of type +"web", add a single USER_PROCESS entry. + +Upstream-commit: 43f7f428a1665950233557bd97611bd5e996b5cb +Cherry-picked-by: Lukáš Zaoral +--- + lib/readutmp.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/lib/readutmp.c b/lib/readutmp.c +index 10d79d1..3c4f97b 100644 +--- a/lib/readutmp.c ++++ b/lib/readutmp.c +@@ -867,6 +867,14 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) + else if (pty != NULL) + tty = pty; + } ++ else if (strcmp (type, "web") == 0) ++ { ++ char *service; ++ if (sd_session_get_service (session, &service) < 0) ++ service = NULL; ++ ++ tty = service; ++ } + } + + /* Create up to two USER_PROCESS entries: one for the seat, +-- +cgit v1.1 + diff --git a/coreutils.spec b/coreutils.spec index db0bd0d..e4c3cb4 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 8%{?dist} +Release: 9%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,6 +32,10 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch +# coreutils no longer lists Cockpit logins in `who` (rhbz#2307847) +# https://git.savannah.gnu.org/cgit/gnulib.git/patch/?id=43f7f428a1665950233557bd97611bd5e996b5cb +Patch105: coreutils-9.5-readutmp-web-session.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -274,6 +278,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Aug 27 2024 Lukáš Zaoral - 9.5-9 +- show web sessions in who output (rhbz#2307847) + * Wed Aug 21 2024 Lukáš Zaoral - 9.5-8 - add missing systemd-devel buildrequires From 8080f5a15a20362c10d4c46c471d4a4a486e9e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Fri, 27 Sep 2024 10:31:35 +0200 Subject: [PATCH 506/523] fix fold -b with UTF8 locale Fixes the following incorrect behaviour of fold caused by the i18n patch: ``` $ LC_ALL=en_US.UTF-8 fold -b -w6 <<< $'1234567890\nabcdefghij\n1234567890\n' 123456 7890 a bcdefg hij 12 345678 90 ``` Fixes: 97967f71c8772354f87dfff4edfe24fb213c8557 ("coreutils-i18n.patch: synchronize the patch with openSUSE") Resolves: RHE L-60295 --- coreutils-i18n.patch | 65 ++++++++++++++++++++++---------------------- coreutils.spec | 5 +++- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 214c2ac..92f35b5 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From 94cf02dfcb1be23dedf8a39af295f28ee2de6013 Mon Sep 17 00:00:00 2001 +From a54e632beb3a3f1f980103deea1cf9a8bdd164ac Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -17,7 +17,7 @@ Subject: [PATCH] coreutils-i18n.patch src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + src/expand.c | 90 +++- - src/fold.c | 312 ++++++++++++-- + src/fold.c | 311 ++++++++++++-- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 792 +++++++++++++++++++++++++++++++++--- @@ -34,7 +34,7 @@ Subject: [PATCH] coreutils-i18n.patch tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 30 files changed, 3605 insertions(+), 196 deletions(-) + 30 files changed, 3604 insertions(+), 196 deletions(-) create mode 100644 lib/mbchar.c create mode 100644 lib/mbchar.h create mode 100644 lib/mbfile.c @@ -1820,7 +1820,7 @@ index a6176a9..60b1b8e 100644 } diff --git a/src/fold.c b/src/fold.c -index 941ad11..cf1e747 100644 +index 941ad11..bdc466d 100644 --- a/src/fold.c +++ b/src/fold.c @@ -23,10 +23,32 @@ @@ -1968,7 +1968,7 @@ index 941ad11..cf1e747 100644 /* Look for the last blank. */ while (logical_end) { -@@ -214,13 +251,225 @@ fold_file (char const *filename, size_t width) +@@ -214,13 +251,224 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -2066,39 +2066,38 @@ index 941ad11..cf1e747 100644 + } + +rescan: -+ if (operating_mode == byte_mode) /* byte mode */ ++ if (convfail) ++ increment = 1; ++ else if (wc == L'\n') ++ { ++ /* preserve newline */ ++ fwrite (line_out, sizeof(char), offset_out, stdout); ++ START_NEW_LINE; ++ continue; ++ } ++ else if (operating_mode == byte_mode) /* byte mode */ + increment = mblength; + else if (operating_mode == character_mode) /* character mode */ + increment = 1; -+ else /* column mode */ ++ else /* column mode */ + { -+ if (convfail) -+ increment = 1; -+ else ++ switch (wc) + { -+ switch (wc) -+ { -+ case L'\n': -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ continue; ++ case L'\b': ++ increment = (column > 0) ? -1 : 0; ++ break; + -+ case L'\b': -+ increment = (column > 0) ? -1 : 0; -+ break; ++ case L'\r': ++ increment = -1 * column; ++ break; + -+ case L'\r': -+ increment = -1 * column; -+ break; ++ case L'\t': ++ increment = 8 - column % 8; ++ break; + -+ case L'\t': -+ increment = 8 - column % 8; -+ break; -+ -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; -+ } ++ default: ++ increment = wcwidth (wc); ++ increment = (increment < 0) ? 0 : increment; + } + } + @@ -2196,7 +2195,7 @@ index 941ad11..cf1e747 100644 if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -251,7 +500,8 @@ main (int argc, char **argv) +@@ -251,7 +499,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -2206,7 +2205,7 @@ index 941ad11..cf1e747 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) { -@@ -260,7 +510,15 @@ main (int argc, char **argv) +@@ -260,7 +509,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -5183,5 +5182,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.44.0 +2.46.1 diff --git a/coreutils.spec b/coreutils.spec index e4c3cb4..744b454 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 9%{?dist} +Release: 10%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -278,6 +278,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Fri Sep 27 2024 Lukáš Zaoral - 9.5-10 +- fix fold -b with UTF8 locale (RHEL-60295) + * Tue Aug 27 2024 Lukáš Zaoral - 9.5-9 - show web sessions in who output (rhbz#2307847) From a6d9263e25f2383f18c1f5f949c352a70c33d541 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 11 Nov 2024 11:12:44 +0100 Subject: [PATCH 507/523] Affinity mask handling in nproc for large CPU counts --- coreutils-nproc-affinity.patch | 44 ++++++++++++++++++++++++++++++++++ coreutils.spec | 4 +++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 coreutils-nproc-affinity.patch diff --git a/coreutils-nproc-affinity.patch b/coreutils-nproc-affinity.patch new file mode 100644 index 0000000..8c682d4 --- /dev/null +++ b/coreutils-nproc-affinity.patch @@ -0,0 +1,44 @@ +diff -ur coreutils-9.5.orig/lib/nproc.c coreutils-9.5/lib/nproc.c +--- coreutils-9.5.orig/lib/nproc.c 2024-01-01 14:21:47.000000000 +0100 ++++ coreutils-9.5/lib/nproc.c 2024-11-11 10:48:05.435716502 +0100 +@@ -20,6 +20,7 @@ + #include + #include "nproc.h" + ++#include + #include + #include + #include +@@ -124,6 +125,31 @@ + return count; + } + } ++#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ ++ && defined CPU_COUNT /* glibc >= 2.3.4 */ ++ { ++ unsigned int alloc_count = 1024; ++ while (1) ++ { ++ cpu_set_t *set = CPU_ALLOC (alloc_count); ++ unsigned int size = CPU_ALLOC_SIZE (alloc_count); ++ if (sched_getaffinity (0, size, set) == 0) ++ { ++ unsigned int count = CPU_COUNT_S (size, set); ++ CPU_FREE (set); ++ return count; ++ } ++ if (errno != EINVAL) ++ { ++ CPU_FREE (set); ++ return 0; ++ } ++ CPU_FREE (set); ++ alloc_count *= 2; ++ if (alloc_count == 0) ++ return 0; ++ } ++ } + #elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ + { + cpu_set_t set; +Only in coreutils-9.5/lib: nproc.c~ diff --git a/coreutils.spec b/coreutils.spec index 744b454..71334b9 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 10%{?dist} +Release: 10%{?dist}.nproc.1 # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -36,6 +36,8 @@ Patch104: coreutils-df-direct.patch # https://git.savannah.gnu.org/cgit/gnulib.git/patch/?id=43f7f428a1665950233557bd97611bd5e996b5cb Patch105: coreutils-9.5-readutmp-web-session.patch +Patch106: coreutils-nproc-affinity.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch From ddff633d0f852db9dc74c6ea6c81a51fd383901e Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 13 Nov 2024 09:54:55 +0100 Subject: [PATCH 508/523] Switch to upstream version of nproc affinity mask fix (rhbz#2325167) --- ....patch => coreutils-nproc-affinity-1.patch | 23 +++++-- coreutils-nproc-affinity-2.patch | 64 +++++++++++++++++++ coreutils.spec | 9 ++- 3 files changed, 88 insertions(+), 8 deletions(-) rename coreutils-nproc-affinity.patch => coreutils-nproc-affinity-1.patch (60%) create mode 100644 coreutils-nproc-affinity-2.patch diff --git a/coreutils-nproc-affinity.patch b/coreutils-nproc-affinity-1.patch similarity index 60% rename from coreutils-nproc-affinity.patch rename to coreutils-nproc-affinity-1.patch index 8c682d4..8748d4e 100644 --- a/coreutils-nproc-affinity.patch +++ b/coreutils-nproc-affinity-1.patch @@ -1,6 +1,16 @@ -diff -ur coreutils-9.5.orig/lib/nproc.c coreutils-9.5/lib/nproc.c ---- coreutils-9.5.orig/lib/nproc.c 2024-01-01 14:21:47.000000000 +0100 -+++ coreutils-9.5/lib/nproc.c 2024-11-11 10:48:05.435716502 +0100 +commit 45c2456a56337ebcafe0dd9faa2bd995ccbc3357 +Author: Florian Weimer +Date: Mon Nov 11 14:05:53 2024 +0100 + + nproc: Use affinity mask even on systems with more than 1024 CPUs. + + * lib/nproc.c (num_processors_via_affinity_mask): Retry + with larger affinity masks if CPU_ALLOC_SIZE is available. + +diff --git a/lib/nproc.c b/lib/nproc.c +index 92a07e8289..48bc3d06fa 100644 +--- a/lib/nproc.c ++++ b/lib/nproc.c @@ -20,6 +20,7 @@ #include #include "nproc.h" @@ -9,17 +19,19 @@ diff -ur coreutils-9.5.orig/lib/nproc.c coreutils-9.5/lib/nproc.c #include #include #include -@@ -124,6 +125,31 @@ +@@ -124,6 +125,33 @@ num_processors_via_affinity_mask (void) return count; } } +#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ -+ && defined CPU_COUNT /* glibc >= 2.3.4 */ ++ && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ + { + unsigned int alloc_count = 1024; + while (1) + { + cpu_set_t *set = CPU_ALLOC (alloc_count); ++ if (set == NULL) ++ return 0; + unsigned int size = CPU_ALLOC_SIZE (alloc_count); + if (sched_getaffinity (0, size, set) == 0) + { @@ -41,4 +53,3 @@ diff -ur coreutils-9.5.orig/lib/nproc.c coreutils-9.5/lib/nproc.c #elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ { cpu_set_t set; -Only in coreutils-9.5/lib: nproc.c~ diff --git a/coreutils-nproc-affinity-2.patch b/coreutils-nproc-affinity-2.patch new file mode 100644 index 0000000..aeca09c --- /dev/null +++ b/coreutils-nproc-affinity-2.patch @@ -0,0 +1,64 @@ +commit ee0bc695303775da5026091a65e8ec2b764f4a26 +Author: Bruno Haible +Date: Mon Nov 11 15:40:52 2024 +0100 + + nproc: Use affinity mask even in out-of-memory situations. + + * lib/nproc.c (num_processors_via_affinity_mask): Use a stack-allocated + cpu_set_t as fallback. Add comments. + +diff --git a/lib/nproc.c b/lib/nproc.c +index 48bc3d06fa..0b5898d88f 100644 +--- a/lib/nproc.c ++++ b/lib/nproc.c +@@ -125,15 +125,25 @@ num_processors_via_affinity_mask (void) + return count; + } + } +-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ +- && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ ++#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ ++ /* There are two ways to use the sched_getaffinity() function: ++ - With a statically-sized cpu_set_t. ++ - With a dynamically-sized cpu_set_t. ++ Documentation: ++ ++ ++ The second way has the advantage that it works on systems with more than ++ 1024 CPUs. The first way has the advantage that it works also when memory ++ is tight. */ ++# if defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ + { + unsigned int alloc_count = 1024; +- while (1) ++ for (;;) + { + cpu_set_t *set = CPU_ALLOC (alloc_count); + if (set == NULL) +- return 0; ++ /* Out of memory. */ ++ break; + unsigned int size = CPU_ALLOC_SIZE (alloc_count); + if (sched_getaffinity (0, size, set) == 0) + { +@@ -143,16 +153,19 @@ num_processors_via_affinity_mask (void) + } + if (errno != EINVAL) + { ++ /* Some other error. */ + CPU_FREE (set); + return 0; + } + CPU_FREE (set); ++ /* Retry with some larger cpu_set_t. */ + alloc_count *= 2; + if (alloc_count == 0) ++ /* Integer overflow. Avoid an endless loop. */ + return 0; + } + } +-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ ++# endif + { + cpu_set_t set; + diff --git a/coreutils.spec b/coreutils.spec index 71334b9..759434b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 10%{?dist}.nproc.1 +Release: 11%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -36,7 +36,9 @@ Patch104: coreutils-df-direct.patch # https://git.savannah.gnu.org/cgit/gnulib.git/patch/?id=43f7f428a1665950233557bd97611bd5e996b5cb Patch105: coreutils-9.5-readutmp-web-session.patch -Patch106: coreutils-nproc-affinity.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2325167 +Patch106: coreutils-nproc-affinity-1.patch +Patch107: coreutils-nproc-affinity-2.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -280,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Nov 13 2024 Florian Weimer - 9.5-11 +- Affinity mask handling in nproc for large CPU counts (rhbz#2325167) + * Fri Sep 27 2024 Lukáš Zaoral - 9.5-10 - fix fold -b with UTF8 locale (RHEL-60295) From e847b805f8bd1c11e99dc1465a479a5b6cfb1bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 12 Jan 2025 14:23:54 +0100 Subject: [PATCH 509/523] Rebuilt for the bin-sbin merge (2nd attempt) https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 759434b..56c3746 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 11%{?dist} +Release: 12%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -282,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 9.5-12 +- Rebuilt for the bin-sbin merge (2nd attempt) + * Wed Nov 13 2024 Florian Weimer - 9.5-11 - Affinity mask handling in nproc for large CPU counts (rhbz#2325167) From c71c8701f4d6f32da90ead63775636ada91e6de1 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 16 Jan 2025 14:32:40 +0000 Subject: [PATCH 510/523] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index 56c3746..b6b0f0f 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.5 -Release: 12%{?dist} +Release: 13%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -282,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Jan 16 2025 Fedora Release Engineering - 9.5-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 9.5-12 - Rebuilt for the bin-sbin merge (2nd attempt) From ec87f84093f49c9ed9484ca2066dbdc8ea1772cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 20 Jan 2025 12:26:44 +0100 Subject: [PATCH 511/523] rebase to latest upstream version Resolves: rhbz#2338620 --- coreutils-8.32-DIR_COLORS.patch | 14 +- coreutils-9.5-readutmp-web-session.patch | 39 --- coreutils-9.6-ls-selinux-crash.patch | 77 ++++++ coreutils-df-direct.patch | 28 +-- coreutils-i18n.patch | 308 +++++++++++------------ coreutils-nproc-affinity-1.patch | 55 ---- coreutils-nproc-affinity-2.patch | 64 ----- coreutils-python3.patch | 10 +- coreutils-selinux.patch | 12 +- coreutils.spec | 22 +- sources | 4 +- 11 files changed, 277 insertions(+), 356 deletions(-) delete mode 100644 coreutils-9.5-readutmp-web-session.patch create mode 100644 coreutils-9.6-ls-selinux-crash.patch delete mode 100644 coreutils-nproc-affinity-1.patch delete mode 100644 coreutils-nproc-affinity-2.patch diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index ee037bf..021d2a5 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -36,9 +36,9 @@ index b465771..ad42b09 100644 ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 00 # ... and the files they point to +MISSING 01;37;41 # ... and the files they point to - SETUID 37;41 # file that is setuid (u+s) - SETGID 30;43 # file that is setgid (g+s) - CAPABILITY 00 # file with capability (very expensive to lookup) + SETUID 37;41 # regular file that is setuid (u+s) + SETGID 30;43 # regular file that is setgid (g+s) + CAPABILITY 00 # regular file with capability (very expensive to lookup) diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor index eab6258..1627b63 100644 --- a/DIR_COLORS.lightbgcolor @@ -83,13 +83,13 @@ index eab6258..1627b63 100644 ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 00 # ... and the files they point to +MISSING 01;37;41 # ... and the files they point to - SETUID 37;41 # file that is setuid (u+s) - SETGID 30;43 # file that is setgid (g+s) - CAPABILITY 00 # file with capability (very expensive to lookup) + SETUID 37;41 # regular file that is setuid (u+s) + SETGID 30;43 # regular file that is setgid (g+s) + CAPABILITY 00 # regular file with capability (very expensive to lookup) @@ -78,7 +87,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable - # This is for files with execute permission: + # This is for regular files with execute permission: -EXEC 01;32 +EXEC 00;32 diff --git a/coreutils-9.5-readutmp-web-session.patch b/coreutils-9.5-readutmp-web-session.patch deleted file mode 100644 index 32a87fe..0000000 --- a/coreutils-9.5-readutmp-web-session.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 43f7f428a1665950233557bd97611bd5e996b5cb Mon Sep 17 00:00:00 2001 -From: Bruno Haible -Date: Tue, 27 Aug 2024 11:46:33 +0200 -Subject: readutmp: In systemd mode, show sessions of type "web". - -Reported by Allison Karlitskaya in -. - -* lib/readutmp.c (read_utmp_from_systemd): For a systemd session of type -"web", add a single USER_PROCESS entry. - -Upstream-commit: 43f7f428a1665950233557bd97611bd5e996b5cb -Cherry-picked-by: Lukáš Zaoral ---- - lib/readutmp.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/lib/readutmp.c b/lib/readutmp.c -index 10d79d1..3c4f97b 100644 ---- a/lib/readutmp.c -+++ b/lib/readutmp.c -@@ -867,6 +867,14 @@ read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options) - else if (pty != NULL) - tty = pty; - } -+ else if (strcmp (type, "web") == 0) -+ { -+ char *service; -+ if (sd_session_get_service (session, &service) < 0) -+ service = NULL; -+ -+ tty = service; -+ } - } - - /* Create up to two USER_PROCESS entries: one for the seat, --- -cgit v1.1 - diff --git a/coreutils-9.6-ls-selinux-crash.patch b/coreutils-9.6-ls-selinux-crash.patch new file mode 100644 index 0000000..70837cc --- /dev/null +++ b/coreutils-9.6-ls-selinux-crash.patch @@ -0,0 +1,77 @@ +From 915004f403cb25fadb207ddfdbe6a2f43bd44fac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Fri, 17 Jan 2025 17:29:34 +0000 +Subject: [PATCH] ls: fix crash with --context + +* src/ls.c (main): Flag that we need to stat() +if we're going to get security context (call file_has_aclinfo_cache). +(file_has_aclinfo_cache): Be defensive and only lookup the device +for the file if the stat has been performed. +(has_capability_cache): Likewise. +* tests/ls/selinux-segfault.sh: Add a test case. +Reported by Bruno Haible. +--- + src/ls.c | 10 +++++----- + tests/ls/selinux-segfault.sh | 3 +++ + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/src/ls.c b/src/ls.c +index 3215360216..f67167f160 100644 +--- a/src/ls.c ++++ b/src/ls.c +@@ -1768,7 +1768,7 @@ main (int argc, char **argv) + + format_needs_stat = ((sort_type == sort_time) | (sort_type == sort_size) + | (format == long_format) +- | print_block_size | print_hyperlink); ++ | print_block_size | print_hyperlink | print_scontext); + format_needs_type = ((! format_needs_stat) + & (recursive | print_with_color | print_scontext + | directories_first +@@ -3309,7 +3309,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, + static int unsupported_scontext_err; + static dev_t unsupported_device; + +- if (f->stat.st_dev == unsupported_device) ++ if (f->stat_ok && f->stat.st_dev == unsupported_device) + { + ai->buf = ai->u.__gl_acl_ch; + ai->size = 0; +@@ -3322,7 +3322,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, + errno = 0; + int n = file_has_aclinfo (file, ai, flags); + int err = errno; +- if (n <= 0 && !acl_errno_valid (err)) ++ if (f->stat_ok && n <= 0 && !acl_errno_valid (err)) + { + unsupported_return = n; + unsupported_scontext = ai->scontext; +@@ -3342,14 +3342,14 @@ has_capability_cache (char const *file, struct fileinfo *f) + found that has_capability fails indicating lack of support. */ + static dev_t unsupported_device; + +- if (f->stat.st_dev == unsupported_device) ++ if (f->stat_ok && f->stat.st_dev == unsupported_device) + { + errno = ENOTSUP; + return 0; + } + + bool b = has_capability (file); +- if ( !b && !acl_errno_valid (errno)) ++ if (f->stat_ok && !b && !acl_errno_valid (errno)) + unsupported_device = f->stat.st_dev; + return b; + } +diff --git a/tests/ls/selinux-segfault.sh b/tests/ls/selinux-segfault.sh +index 11623acb3f..1cac2b5fc0 100755 +--- a/tests/ls/selinux-segfault.sh ++++ b/tests/ls/selinux-segfault.sh +@@ -30,4 +30,7 @@ mkdir sedir || framework_failure_ + ln -sf missing sedir/broken || framework_failure_ + returns_ 1 ls -L -R -Z -m sedir > out || fail=1 + ++# ls 9.6 would segfault with the following ++ls -Z . > out || fail=1 ++ + Exit $fail diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index f29a065..d19ec29 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From f072852456c545bd89296bc88cf59ccd63287a68 Mon Sep 17 00:00:00 2001 +From d179da4730f414069dd2c0ac995a32398718916c Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,10 +11,10 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 8f7f43e..230f1f1 100644 +index ec58f6c..17cda80 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12427,6 +12427,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12467,6 +12467,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -29,10 +29,10 @@ index 8f7f43e..230f1f1 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 994f0e3..ceee209 100644 +index 5c7efd8..52ece19 100644 --- a/src/df.c +++ b/src/df.c -@@ -121,6 +121,9 @@ static bool print_type; +@@ -122,6 +122,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -42,7 +42,7 @@ index 994f0e3..ceee209 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -247,13 +250,15 @@ enum +@@ -249,13 +252,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -59,10 +59,10 @@ index 994f0e3..ceee209 100644 {"inodes", no_argument, nullptr, 'i'}, {"human-readable", no_argument, nullptr, 'h'}, {"si", no_argument, nullptr, 'H'}, -@@ -574,7 +579,10 @@ get_header (void) - for (col = 0; col < ncolumns; col++) +@@ -571,7 +576,10 @@ get_header (void) + for (idx_t col = 0; col < ncolumns; col++) { - char *cell = nullptr; + char *cell; - char const *header = _(columns[col]->caption); + char const *header = (columns[col]->field == TARGET_FIELD + && direct_statfs)? @@ -71,7 +71,7 @@ index 994f0e3..ceee209 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1471,6 +1479,17 @@ get_point (char const *point, const struct stat *statp) +@@ -1452,6 +1460,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -89,7 +89,7 @@ index 994f0e3..ceee209 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1541,6 +1560,7 @@ or all file systems by default.\n\ +@@ -1522,6 +1541,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -97,7 +97,7 @@ index 994f0e3..ceee209 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1631,6 +1651,9 @@ main (int argc, char **argv) +@@ -1616,6 +1636,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -107,7 +107,7 @@ index 994f0e3..ceee209 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1727,6 +1750,13 @@ main (int argc, char **argv) +@@ -1712,6 +1735,13 @@ main (int argc, char **argv) } } @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.44.0 +2.48.1 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 92f35b5..e7699c1 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From a54e632beb3a3f1f980103deea1cf9a8bdd164ac Mon Sep 17 00:00:00 2001 +From a153c65067f6c09cf2cf38dc7c149aa1521c615a Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -21,20 +21,20 @@ Subject: [PATCH] coreutils-i18n.patch src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 792 +++++++++++++++++++++++++++++++++--- - src/unexpand.c | 102 ++++- + src/unexpand.c | 101 ++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ tests/i18n/sort.sh | 29 ++ tests/local.mk | 4 + tests/misc/expand.pl | 42 ++ - tests/misc/fold.pl | 50 ++- + tests/misc/fold.pl | 51 ++- tests/misc/sort-mb-tests.sh | 45 ++ tests/misc/unexpand.pl | 39 ++ tests/pr/pr-tests.pl | 49 +++ tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 30 files changed, 3604 insertions(+), 196 deletions(-) + 30 files changed, 3603 insertions(+), 197 deletions(-) create mode 100644 lib/mbchar.c create mode 100644 lib/mbchar.h create mode 100644 lib/mbfile.c @@ -47,10 +47,10 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 126e1e8..b4ccebf 100644 +index 380fa11..ca80e6f 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -163,6 +163,8 @@ gnulib_modules=" +@@ -165,6 +165,8 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -60,10 +60,10 @@ index 126e1e8..b4ccebf 100644 mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index 9cb6ee1..1131ce3 100644 +index bf6da2a..321016d 100644 --- a/configure.ac +++ b/configure.ac -@@ -504,6 +504,12 @@ fi +@@ -505,6 +505,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -77,12 +77,12 @@ index 9cb6ee1..1131ce3 100644 if test $gl_cv_sys_tiocgwinsz_needs_termios_h = no && \ diff --git a/lib/linebuffer.h b/lib/linebuffer.h -index ae0d55d..5bf5350 100644 +index ca56f80..509b7e6 100644 --- a/lib/linebuffer.h +++ b/lib/linebuffer.h -@@ -22,6 +22,11 @@ - # include "idx.h" - # include +@@ -27,6 +27,11 @@ extern "C" { + #endif + +/* Get mbstate_t. */ +# if HAVE_WCHAR_H @@ -92,7 +92,7 @@ index ae0d55d..5bf5350 100644 /* A 'struct linebuffer' holds a line of text. */ struct linebuffer -@@ -29,6 +34,9 @@ struct linebuffer +@@ -34,6 +39,9 @@ struct linebuffer idx_t size; /* Allocated. */ idx_t length; /* Used. */ char *buffer; @@ -849,7 +849,7 @@ index 0000000..83068a9 + : +]) diff --git a/src/cut.c b/src/cut.c -index 061e09c..6d10425 100644 +index b424997..c9f181c 100644 --- a/src/cut.c +++ b/src/cut.c @@ -27,6 +27,11 @@ @@ -1509,7 +1509,7 @@ index 061e09c..6d10425 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index c95998d..d4386fe 100644 +index 2dbbbe4..91a90a3 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -1518,9 +1518,9 @@ index c95998d..d4386fe 100644 #include +#include #include "system.h" + #include "c-ctype.h" #include "fadvise.h" - #include "quote.h" -@@ -123,6 +124,119 @@ set_increment_size (uintmax_t tabval) +@@ -123,6 +124,119 @@ set_increment_size (colno tabval) return ok; } @@ -1641,10 +1641,10 @@ index c95998d..d4386fe 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index 1a57108..6025652 100644 +index fe6c8ed..80a1280 100644 --- a/src/expand-common.h +++ b/src/expand-common.h -@@ -25,6 +25,18 @@ extern size_t max_column_width; +@@ -29,6 +29,18 @@ extern idx_t max_column_width; /* The desired exit status. */ extern int exit_status; @@ -1662,9 +1662,9 @@ index 1a57108..6025652 100644 + /* Add tab stop TABVAL to the end of 'tab_list'. */ extern void - add_tab_stop (uintmax_t tabval); + add_tab_stop (colno tabval); diff --git a/src/expand.c b/src/expand.c -index a6176a9..60b1b8e 100644 +index 5ec7ce9..65ac315 100644 --- a/src/expand.c +++ b/src/expand.c @@ -38,6 +38,9 @@ @@ -1725,7 +1725,7 @@ index a6176a9..60b1b8e 100644 @@ -118,17 +143,48 @@ expand (void) /* Index in TAB_LIST of next tab stop to examine. */ - size_t tab_index = 0; + idx_t tab_index = 0; - /* Convert a line of text. */ @@ -1775,8 +1775,8 @@ index a6176a9..60b1b8e 100644 + if (mb_iseq (c, '\t')) { /* Column the next input tab stop is on. */ - uintmax_t next_tab_column; -@@ -147,32 +203,34 @@ expand (void) + bool last_tab; +@@ -139,31 +195,33 @@ expand (void) if (putchar (' ') < 0) write_error (); @@ -1795,14 +1795,13 @@ index a6176a9..60b1b8e 100644 + /* A leading control character could make us trip over. */ + else if (!mb_iscntrl (c)) { -- column++; -+ column += mb_width (c); - if (!column) +- if (ckd_add (&column, column, 1)) ++ if (ckd_add (&column, column, mb_width (c))) error (EXIT_FAILURE, 0, _("input line is too long")); } - convert &= convert_entire_line || !! isblank (c); -+ convert &= convert_entire_line || mb_isblank (c); ++ convert &= convert_entire_line || !! mb_isblank (c); } - if (c < 0) @@ -1820,7 +1819,7 @@ index a6176a9..60b1b8e 100644 } diff --git a/src/fold.c b/src/fold.c -index 941ad11..bdc466d 100644 +index b64aad4..a156337 100644 --- a/src/fold.c +++ b/src/fold.c @@ -23,10 +23,32 @@ @@ -1931,9 +1930,9 @@ index 941ad11..bdc466d 100644 - FILE *istream; int c; size_t column = 0; /* Screen column where next char will go. */ - size_t offset_out = 0; /* Index in 'line_out' for next char. */ + idx_t offset_out = 0; /* Index in 'line_out' for next char. */ static char *line_out = nullptr; - static size_t allocated_out = 0; + static idx_t allocated_out = 0; - int saved_errno; - - if (STREQ (filename, "-")) @@ -1954,7 +1953,7 @@ index 941ad11..bdc466d 100644 @@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width) bool found_blank = false; - size_t logical_end = offset_out; + idx_t logical_end = offset_out; + /* If LINE_OUT has no wide character, + put a new wide character in LINE_OUT @@ -1968,7 +1967,7 @@ index 941ad11..bdc466d 100644 /* Look for the last blank. */ while (logical_end) { -@@ -214,13 +251,224 @@ fold_file (char const *filename, size_t width) +@@ -212,13 +249,224 @@ fold_file (char const *filename, size_t width) line_out[offset_out++] = c; } @@ -1979,7 +1978,7 @@ index 941ad11..bdc466d 100644 + *saved_errno = 0; if (offset_out) - fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); + fwrite (line_out, sizeof (char), offset_out, stdout); +} + @@ -1997,8 +1996,8 @@ index 941ad11..bdc466d 100644 + int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ + + static char *line_out = NULL; -+ size_t offset_out = 0; /* Index in `line_out' for next char. */ -+ static size_t allocated_out = 0; ++ idx_t offset_out = 0; /* Index in `line_out' for next char. */ ++ static idx_t allocated_out = 0; + + int increment; + size_t column = 0; @@ -2121,9 +2120,9 @@ index 941ad11..bdc466d 100644 + goto rescan; + } + -+ if (allocated_out < offset_out + mblength) ++ if (allocated_out - offset_out <= mblength) + { -+ line_out = X2REALLOC (line_out, &allocated_out); ++ line_out = xpalloc (line_out, &allocated_out, 1, -1, sizeof *line_out); + } + + memcpy (line_out + offset_out, bufpos, mblength); @@ -2155,14 +2154,14 @@ index 941ad11..bdc466d 100644 + *saved_errno = 0; + + if (offset_out) -+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); ++ fwrite (line_out, sizeof (char), offset_out, stdout); + +} +#endif + +/* Fold file FILENAME, or standard input if FILENAME is "-", + to stdout, with maximum line length WIDTH. -+ Return 0 if successful, 1 if an error occurs. */ ++ Return true if successful. */ + +static bool +fold_file (char const *filename, size_t width) @@ -2173,12 +2172,12 @@ index 941ad11..bdc466d 100644 + if (STREQ (filename, "-")) + { + istream = stdin; -+ have_read_stdin = 1; ++ have_read_stdin = true; + } + else + istream = fopen (filename, "r"); + -+ if (istream == NULL) ++ if (istream == nullptr) + { + error (0, errno, "%s", filename); + return false; @@ -2195,7 +2194,7 @@ index 941ad11..bdc466d 100644 if (STREQ (filename, "-")) clearerr (istream); else if (fclose (istream) != 0 && !saved_errno) -@@ -251,7 +499,8 @@ main (int argc, char **argv) +@@ -249,7 +497,8 @@ main (int argc, char **argv) atexit (close_stdout); @@ -2205,7 +2204,7 @@ index 941ad11..bdc466d 100644 while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) { -@@ -260,7 +509,15 @@ main (int argc, char **argv) +@@ -258,7 +507,15 @@ main (int argc, char **argv) switch (optc) { case 'b': /* Count bytes rather than columns. */ @@ -2223,10 +2222,10 @@ index 941ad11..bdc466d 100644 case 's': /* Break at word boundaries. */ diff --git a/src/local.mk b/src/local.mk -index 96ee941..8fdb8fc 100644 +index fd9dc81..5133cc0 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -450,8 +450,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -476,8 +476,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -2238,7 +2237,7 @@ index 96ee941..8fdb8fc 100644 src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 09c6fa8..7552b62 100644 +index e7081a0..19e0268 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ @@ -2264,9 +2263,9 @@ index 09c6fa8..7552b62 100644 +#endif + #include "system.h" + #include "c-ctype.h" #include "fadvise.h" - #include "hard-locale.h" -@@ -324,6 +342,18 @@ +@@ -325,6 +343,18 @@ #include "xstrtol-error.h" #include "xdectoint.h" @@ -2285,7 +2284,7 @@ index 09c6fa8..7552b62 100644 /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "pr" -@@ -416,7 +446,20 @@ struct COLUMN +@@ -417,7 +447,20 @@ struct COLUMN typedef struct COLUMN COLUMN; @@ -2307,9 +2306,9 @@ index 09c6fa8..7552b62 100644 static bool read_line (COLUMN *p); static bool print_page (void); static bool print_stored (COLUMN *p); -@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p); - static void getoptnum (char const *n_str, int min, int *num, - char const *errfmt); +@@ -428,6 +471,7 @@ static void pad_across_to (int position); + static void add_line_number (COLUMN *p); + static int getoptnum (char const *n_str, int min, char const *errfmt); static void getoptarg (char *arg, char switch_char, char *character, + int *character_length, int *character_width, int *number); @@ -2442,7 +2441,7 @@ index 09c6fa8..7552b62 100644 /* Could check tab width > 0. */ tabify_output = true; break; -@@ -985,8 +1068,8 @@ main (int argc, char **argv) +@@ -986,8 +1069,8 @@ main (int argc, char **argv) case 'n': numbered_lines = true; if (optarg) @@ -2453,7 +2452,7 @@ index 09c6fa8..7552b62 100644 break; case 'N': skip_count = false; -@@ -1011,6 +1094,7 @@ main (int argc, char **argv) +@@ -1013,6 +1096,7 @@ main (int argc, char **argv) /* Reset an additional input of -s, -S dominates -s */ col_sep_string = ""; col_sep_length = 0; @@ -2461,7 +2460,7 @@ index 09c6fa8..7552b62 100644 use_col_separator = true; if (optarg) separator_string (optarg); -@@ -1165,7 +1249,8 @@ getoptnum (char const *n_str, int min, int *num, char const *err) +@@ -1168,7 +1252,8 @@ getoptnum (char const *n_str, int min, char const *err) a number. */ static void @@ -2471,10 +2470,10 @@ index 09c6fa8..7552b62 100644 { if (!*arg) { -@@ -1174,7 +1259,41 @@ getoptarg (char *arg, char switch_char, char *character, int *number) +@@ -1177,7 +1262,41 @@ getoptarg (char *arg, char switch_char, char *character, int *number) } - if (!ISDIGIT (*arg)) + if (!c_isdigit (*arg)) - *character = *arg++; + { +#ifdef HAVE_MBRTOWC @@ -2514,7 +2513,7 @@ index 09c6fa8..7552b62 100644 if (*arg) { long int tmp_long; -@@ -1203,6 +1322,11 @@ static void +@@ -1206,6 +1325,11 @@ static void init_parameters (int number_of_files) { int chars_used_by_number = 0; @@ -2526,7 +2525,7 @@ index 09c6fa8..7552b62 100644 lines_per_body = lines_per_page - lines_per_header - lines_per_footer; if (lines_per_body <= 0) -@@ -1240,7 +1364,7 @@ init_parameters (int number_of_files) +@@ -1243,7 +1367,7 @@ init_parameters (int number_of_files) else col_sep_string = column_separator; @@ -2535,7 +2534,7 @@ index 09c6fa8..7552b62 100644 use_col_separator = true; } /* It's rather pointless to define a TAB separator with column -@@ -1272,11 +1396,11 @@ init_parameters (int number_of_files) +@@ -1275,11 +1399,11 @@ init_parameters (int number_of_files) + TAB_WIDTH (chars_per_input_tab, chars_per_number); */ /* Estimate chars_per_text without any margin and keep it constant. */ @@ -2549,7 +2548,7 @@ index 09c6fa8..7552b62 100644 /* The number is part of the column width unless we are printing files in parallel. */ -@@ -1285,7 +1409,7 @@ init_parameters (int number_of_files) +@@ -1288,7 +1412,7 @@ init_parameters (int number_of_files) } int sep_chars, useful_chars; @@ -2558,7 +2557,7 @@ index 09c6fa8..7552b62 100644 sep_chars = INT_MAX; if (ckd_sub (&useful_chars, chars_per_line - chars_used_by_number, sep_chars)) -@@ -1308,7 +1432,7 @@ init_parameters (int number_of_files) +@@ -1311,7 +1435,7 @@ init_parameters (int number_of_files) We've to use 8 as the lower limit, if we use chars_per_default_tab = 8 to expand a tab which is not an input_tab-char. */ free (clump_buff); @@ -2567,7 +2566,7 @@ index 09c6fa8..7552b62 100644 } /* Open the necessary files, -@@ -1414,7 +1538,7 @@ init_funcs (void) +@@ -1417,7 +1541,7 @@ init_funcs (void) /* Enlarge p->start_position of first column to use the same form of padding_not_printed with all columns. */ @@ -2576,7 +2575,7 @@ index 09c6fa8..7552b62 100644 /* This loop takes care of all but the rightmost column. */ -@@ -1448,7 +1572,7 @@ init_funcs (void) +@@ -1451,7 +1575,7 @@ init_funcs (void) } else { @@ -2585,7 +2584,7 @@ index 09c6fa8..7552b62 100644 h_next = h + chars_per_column; } } -@@ -1745,9 +1869,9 @@ static void +@@ -1748,9 +1872,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -2597,9 +2596,9 @@ index 09c6fa8..7552b62 100644 padding_not_printed = ANYWHERE; } -@@ -2021,13 +2145,13 @@ store_char (char c) +@@ -2024,13 +2148,13 @@ store_char (char c) /* May be too generous. */ - buff = X2REALLOC (buff, &buff_allocated); + buff = xpalloc (buff, &buff_allocated, 1, -1, sizeof *buff); } - buff[buff_current++] = c; + buff[buff_current++] = (unsigned char) c; @@ -2613,7 +2612,7 @@ index 09c6fa8..7552b62 100644 char *s; int num_width; -@@ -2044,22 +2168,24 @@ add_line_number (COLUMN *p) +@@ -2047,22 +2171,24 @@ add_line_number (COLUMN *p) /* Tabification is assumed for multiple columns, also for n-separators, but 'default n-separator = TAB' hasn't been given priority over equal column_width also specified by POSIX. */ @@ -2642,7 +2641,7 @@ index 09c6fa8..7552b62 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2218,7 +2344,7 @@ print_white_space (void) +@@ -2221,7 +2347,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -2651,7 +2650,7 @@ index 09c6fa8..7552b62 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2238,6 +2364,7 @@ print_sep_string (void) +@@ -2241,6 +2367,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -2659,7 +2658,7 @@ index 09c6fa8..7552b62 100644 if (separators_not_printed <= 0) { -@@ -2249,6 +2376,7 @@ print_sep_string (void) +@@ -2252,6 +2379,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -2667,7 +2666,7 @@ index 09c6fa8..7552b62 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2262,12 +2390,15 @@ print_sep_string (void) +@@ -2265,12 +2393,15 @@ print_sep_string (void) } else { @@ -2684,7 +2683,7 @@ index 09c6fa8..7552b62 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2295,7 +2426,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2298,7 +2429,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -2693,7 +2692,7 @@ index 09c6fa8..7552b62 100644 { if (tabify_output) { -@@ -2319,6 +2450,74 @@ print_char (char c) +@@ -2322,6 +2453,74 @@ print_char (char c) putchar (c); } @@ -2768,7 +2767,7 @@ index 09c6fa8..7552b62 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2495,9 +2694,9 @@ read_line (COLUMN *p) +@@ -2498,9 +2697,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -2780,7 +2779,7 @@ index 09c6fa8..7552b62 100644 padding_not_printed = ANYWHERE; } -@@ -2566,7 +2765,7 @@ print_stored (COLUMN *p) +@@ -2569,7 +2768,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -2789,7 +2788,7 @@ index 09c6fa8..7552b62 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2578,7 +2777,7 @@ print_stored (COLUMN *p) +@@ -2581,7 +2780,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -2798,7 +2797,7 @@ index 09c6fa8..7552b62 100644 pad_vertically = true; -@@ -2598,9 +2797,9 @@ print_stored (COLUMN *p) +@@ -2601,9 +2800,9 @@ print_stored (COLUMN *p) } } @@ -2810,7 +2809,7 @@ index 09c6fa8..7552b62 100644 padding_not_printed = ANYWHERE; } -@@ -2613,8 +2812,8 @@ print_stored (COLUMN *p) +@@ -2616,8 +2815,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2821,7 +2820,7 @@ index 09c6fa8..7552b62 100644 } return true; -@@ -2633,7 +2832,7 @@ print_stored (COLUMN *p) +@@ -2636,7 +2835,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2830,7 +2829,7 @@ index 09c6fa8..7552b62 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2643,10 +2842,10 @@ char_to_clump (char c) +@@ -2646,10 +2845,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2843,7 +2842,7 @@ index 09c6fa8..7552b62 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2727,6 +2926,164 @@ char_to_clump (char c) +@@ -2730,6 +2929,164 @@ char_to_clump (char c) return chars; } @@ -3009,7 +3008,7 @@ index 09c6fa8..7552b62 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 2d8324c..46331b8 100644 +index 0928fd5..8c43fd4 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -3027,7 +3026,7 @@ index 2d8324c..46331b8 100644 #include "system.h" #include "argmatch.h" #include "assure.h" -@@ -157,14 +165,39 @@ static int thousands_sep; +@@ -158,14 +166,39 @@ static int thousands_sep; /* We currently ignore multi-byte grouping chars. */ static bool thousands_sep_ignored; @@ -3068,7 +3067,7 @@ index 2d8324c..46331b8 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -341,13 +374,11 @@ static bool stable; +@@ -342,13 +375,11 @@ static bool stable; /* An int value outside char range. */ enum { NON_CHAR = CHAR_MAX + 1 }; @@ -3085,7 +3084,7 @@ index 2d8324c..46331b8 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -804,6 +835,46 @@ reap_all (void) +@@ -807,6 +838,46 @@ reap_all (void) reap (-1); } @@ -3132,7 +3131,7 @@ index 2d8324c..46331b8 100644 /* Clean up any remaining temporary files. */ static void -@@ -1271,7 +1342,7 @@ zaptemp (char const *name) +@@ -1274,7 +1345,7 @@ zaptemp (char const *name) free (node); } @@ -3141,7 +3140,7 @@ index 2d8324c..46331b8 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1286,7 +1357,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1289,7 +1360,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3150,7 +3149,7 @@ index 2d8324c..46331b8 100644 { size_t i; -@@ -1298,7 +1369,7 @@ inittables (void) +@@ -1301,7 +1372,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3159,7 +3158,7 @@ index 2d8324c..46331b8 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1380,6 +1451,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1381,6 +1452,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3244,7 +3243,7 @@ index 2d8324c..46331b8 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1611,7 +1760,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1612,7 +1761,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3253,7 +3252,7 @@ index 2d8324c..46331b8 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1620,10 +1769,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1621,10 +1770,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3266,7 +3265,7 @@ index 2d8324c..46331b8 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1649,12 +1798,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3339,7 +3338,7 @@ index 2d8324c..46331b8 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1669,10 +1877,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1670,10 +1878,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3352,7 +3351,7 @@ index 2d8324c..46331b8 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1718,10 +1926,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3365,7 +3364,7 @@ index 2d8324c..46331b8 100644 if (newlim) lim = newlim; } -@@ -1752,6 +1960,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3496,7 +3495,7 @@ index 2d8324c..46331b8 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1838,8 +2170,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1839,8 +2171,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3521,7 +3520,7 @@ index 2d8324c..46331b8 100644 line->keybeg = line_start; } } -@@ -1977,12 +2323,10 @@ find_unit_order (char const *number) +@@ -1978,12 +2324,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3537,7 +3536,7 @@ index 2d8324c..46331b8 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1994,7 +2338,7 @@ human_numcompare (char const *a, char const *b) +@@ -1995,7 +2339,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3546,7 +3545,7 @@ index 2d8324c..46331b8 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2004,6 +2348,25 @@ numcompare (char const *a, char const *b) +@@ -2005,6 +2349,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3572,7 +3571,7 @@ index 2d8324c..46331b8 100644 static int nan_compare (long double a, long double b) { -@@ -2045,7 +2408,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3581,7 +3580,7 @@ index 2d8324c..46331b8 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2372,15 +2735,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2385,15 +2748,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3599,7 +3598,7 @@ index 2d8324c..46331b8 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2526,7 +2888,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2539,7 +2901,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3608,7 +3607,7 @@ index 2d8324c..46331b8 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2574,9 +2936,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3621,7 +3620,7 @@ index 2d8324c..46331b8 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2600,9 +2962,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3634,7 +3633,7 @@ index 2d8324c..46331b8 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2597,19 +2959,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2610,19 +2972,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3658,7 +3657,7 @@ index 2d8324c..46331b8 100644 } } -@@ -2620,7 +2982,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2633,7 +2995,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) { error (0, 0, _("%snumbers use %s as a decimal point in this locale"), @@ -3667,7 +3666,7 @@ index 2d8324c..46331b8 100644 quote (((char []) {decimal_point, 0}))); } -@@ -2662,11 +3024,87 @@ diff_reversed (int diff, bool reversed) +@@ -2675,11 +3037,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3756,7 +3755,7 @@ index 2d8324c..46331b8 100644 { struct keyfield *key = keylist; -@@ -2747,7 +3185,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2760,7 +3198,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3765,7 +3764,7 @@ index 2d8324c..46331b8 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2857,6 +3295,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2870,6 +3308,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3977,7 +3976,7 @@ index 2d8324c..46331b8 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2884,7 +3527,7 @@ compare (struct line const *a, struct line const *b) +@@ -2897,7 +3540,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3986,7 +3985,7 @@ index 2d8324c..46331b8 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4272,6 +4915,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4285,6 +4928,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3994,7 +3993,7 @@ index 2d8324c..46331b8 100644 break; case 'g': key->general_numeric = true; -@@ -4351,7 +4995,7 @@ main (int argc, char **argv) +@@ -4364,7 +5008,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4003,7 +4002,7 @@ index 2d8324c..46331b8 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4374,6 +5018,29 @@ main (int argc, char **argv) +@@ -4387,6 +5031,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4033,7 +4032,7 @@ index 2d8324c..46331b8 100644 have_read_stdin = false; inittables (); -@@ -4644,13 +5311,34 @@ main (int argc, char **argv) +@@ -4657,13 +5324,34 @@ main (int argc, char **argv) case 't': { @@ -4072,7 +4071,7 @@ index 2d8324c..46331b8 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4661,9 +5349,11 @@ main (int argc, char **argv) +@@ -4674,9 +5362,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4087,7 +4086,7 @@ index 2d8324c..46331b8 100644 break; diff --git a/src/unexpand.c b/src/unexpand.c -index aca67dd..f79c808 100644 +index ff234d7..7c36ef6 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -39,6 +39,9 @@ @@ -4100,7 +4099,7 @@ index aca67dd..f79c808 100644 #include "system.h" #include "expand-common.h" -@@ -105,24 +108,47 @@ unexpand (void) +@@ -105,24 +108,46 @@ unexpand (void) { /* Input stream. */ FILE *fp = next_file (nullptr); @@ -4120,28 +4119,27 @@ index aca67dd..f79c808 100644 if (!fp) return; + + mbf_init (mbf, fp); + found_bom=check_bom(fp,&mbf); + + if (using_utf_locale == false && found_bom == true) -+ { -+ /*try using some predefined locale */ - -+ if (set_utf_locale () != 0) + { -+ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); ++ /* Try using some predefined locale */ ++ if (set_utf_locale () != 0) ++ { ++ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale")); ++ } + } -+ } ++ /* The worst case is a non-blank character, then one blank, then a tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so allocate MAX_COLUMN_WIDTH bytes to store the blanks. */ -- pending_blank = xmalloc (max_column_width); -+ pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t)); +- pending_blank = ximalloc (max_column_width); ++ pending_blank = ximalloc (max_column_width * sizeof (mbf_char_t)); + + if (found_bom == true) -+ { + print_bom(); -+ } while (true) { @@ -4151,7 +4149,7 @@ index aca67dd..f79c808 100644 /* If true, perform translations. */ bool convert = true; -@@ -156,12 +182,44 @@ unexpand (void) +@@ -156,12 +181,44 @@ unexpand (void) do { @@ -4199,10 +4197,10 @@ index aca67dd..f79c808 100644 if (blank) { -@@ -178,16 +236,16 @@ unexpand (void) - if (next_tab_column < column) - error (EXIT_FAILURE, 0, _("input line is too long")); +@@ -175,16 +232,16 @@ unexpand (void) + if (convert) + { - if (c == '\t') + if (mb_iseq (c, '\t')) { @@ -4219,7 +4217,7 @@ index aca67dd..f79c808 100644 if (! (prev_blank && column == next_tab_column)) { -@@ -195,13 +253,14 @@ unexpand (void) +@@ -192,13 +249,14 @@ unexpand (void) will be replaced by tabs. */ if (column == next_tab_column) one_blank_before_tab_stop = true; @@ -4236,7 +4234,7 @@ index aca67dd..f79c808 100644 } /* Discard pending blanks, unless it was a single -@@ -209,7 +268,7 @@ unexpand (void) +@@ -206,7 +264,7 @@ unexpand (void) pending = one_blank_before_tab_stop; } } @@ -4245,7 +4243,7 @@ index aca67dd..f79c808 100644 { /* Go back one column, and force recalculation of the next tab stop. */ -@@ -219,16 +278,20 @@ unexpand (void) +@@ -216,16 +274,20 @@ unexpand (void) } else { @@ -4270,7 +4268,7 @@ index aca67dd..f79c808 100644 write_error (); pending = 0; one_blank_before_tab_stop = false; -@@ -238,16 +301,17 @@ unexpand (void) +@@ -235,16 +297,17 @@ unexpand (void) convert &= convert_entire_line || blank; } @@ -4292,7 +4290,7 @@ index aca67dd..f79c808 100644 } diff --git a/tests/Coreutils.pm b/tests/Coreutils.pm -index 18e7bea..24a141b 100644 +index b55fb9d..ac80f49 100644 --- a/tests/Coreutils.pm +++ b/tests/Coreutils.pm @@ -269,6 +269,9 @@ sub run_tests ($$$$$) @@ -4530,10 +4528,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index fdbf369..a6ce49c 100644 +index 12e30b4..1529db6 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -387,6 +387,8 @@ all_tests = \ +@@ -390,6 +390,8 @@ all_tests = \ tests/sort/sort-discrim.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -4542,7 +4540,7 @@ index fdbf369..a6ce49c 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -590,6 +592,7 @@ all_tests = \ +@@ -593,6 +595,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4550,7 +4548,7 @@ index fdbf369..a6ce49c 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -746,6 +749,7 @@ all_tests = \ +@@ -749,6 +752,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4559,7 +4557,7 @@ index fdbf369..a6ce49c 100644 # See tests/factor/create-test.sh. diff --git a/tests/misc/expand.pl b/tests/misc/expand.pl -index 11f3fc4..d609a2c 100755 +index 4b07210..68b9ea1 100755 --- a/tests/misc/expand.pl +++ b/tests/misc/expand.pl @@ -27,6 +27,15 @@ my $prog = 'expand'; @@ -4626,10 +4624,10 @@ index 11f3fc4..d609a2c 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 00b4362..7d51bea 100755 +index 0981ec9..ba889c8 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl -@@ -20,9 +20,18 @@ use strict; +@@ -20,9 +20,17 @@ use strict; (my $program_name = $0) =~ s|.*/||; @@ -4639,17 +4637,17 @@ index 00b4362..7d51bea 100755 + # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; - +-my $prog = 'fold'; ++ +# uncommented to enable multibyte paths +my $mb_locale = $ENV{LOCALE_FR_UTF8}; +! defined $mb_locale || $mb_locale eq 'none' + and $mb_locale = 'C'; -+ + my @Tests = ( - ['s1', '-w2 -s', {IN=>"a\t"}, {OUT=>"a\n\t"}], -@@ -31,9 +40,48 @@ my @Tests = - ['s4', '-w4 -s', {IN=>"abc ef\n"}, {OUT=>"abc \nef\n"}], +@@ -44,9 +52,48 @@ my @Tests = + {OUT=>"123456\n7890\nabcdef\nghij\n123456\n7890"}], ); +# Add _POSIX2_VERSION=199209 to the environment of each test @@ -4750,7 +4748,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 76bcbd4..59eb819 100755 +index 27d9c17..4976335 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -4807,7 +4805,7 @@ index 76bcbd4..59eb819 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/pr/pr-tests.pl b/tests/pr/pr-tests.pl -index 6b34e0b..34b4aeb 100755 +index 60e6106..3c64a08 100755 --- a/tests/pr/pr-tests.pl +++ b/tests/pr/pr-tests.pl @@ -24,6 +24,15 @@ use strict; @@ -4876,7 +4874,7 @@ index 6b34e0b..34b4aeb 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort-merge.pl b/tests/sort/sort-merge.pl -index 89eed0c..b855d73 100755 +index a3204d3..40942a5 100755 --- a/tests/sort/sort-merge.pl +++ b/tests/sort/sort-merge.pl @@ -26,6 +26,15 @@ my $prog = 'sort'; @@ -4936,7 +4934,7 @@ index 89eed0c..b855d73 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl -index d49f65f..ebba925 100755 +index 2ee92c4..96c7965 100755 --- a/tests/sort/sort.pl +++ b/tests/sort/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -5182,5 +5180,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.46.1 +2.48.1 diff --git a/coreutils-nproc-affinity-1.patch b/coreutils-nproc-affinity-1.patch deleted file mode 100644 index 8748d4e..0000000 --- a/coreutils-nproc-affinity-1.patch +++ /dev/null @@ -1,55 +0,0 @@ -commit 45c2456a56337ebcafe0dd9faa2bd995ccbc3357 -Author: Florian Weimer -Date: Mon Nov 11 14:05:53 2024 +0100 - - nproc: Use affinity mask even on systems with more than 1024 CPUs. - - * lib/nproc.c (num_processors_via_affinity_mask): Retry - with larger affinity masks if CPU_ALLOC_SIZE is available. - -diff --git a/lib/nproc.c b/lib/nproc.c -index 92a07e8289..48bc3d06fa 100644 ---- a/lib/nproc.c -+++ b/lib/nproc.c -@@ -20,6 +20,7 @@ - #include - #include "nproc.h" - -+#include - #include - #include - #include -@@ -124,6 +125,33 @@ num_processors_via_affinity_mask (void) - return count; - } - } -+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ -+ && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ -+ { -+ unsigned int alloc_count = 1024; -+ while (1) -+ { -+ cpu_set_t *set = CPU_ALLOC (alloc_count); -+ if (set == NULL) -+ return 0; -+ unsigned int size = CPU_ALLOC_SIZE (alloc_count); -+ if (sched_getaffinity (0, size, set) == 0) -+ { -+ unsigned int count = CPU_COUNT_S (size, set); -+ CPU_FREE (set); -+ return count; -+ } -+ if (errno != EINVAL) -+ { -+ CPU_FREE (set); -+ return 0; -+ } -+ CPU_FREE (set); -+ alloc_count *= 2; -+ if (alloc_count == 0) -+ return 0; -+ } -+ } - #elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ - { - cpu_set_t set; diff --git a/coreutils-nproc-affinity-2.patch b/coreutils-nproc-affinity-2.patch deleted file mode 100644 index aeca09c..0000000 --- a/coreutils-nproc-affinity-2.patch +++ /dev/null @@ -1,64 +0,0 @@ -commit ee0bc695303775da5026091a65e8ec2b764f4a26 -Author: Bruno Haible -Date: Mon Nov 11 15:40:52 2024 +0100 - - nproc: Use affinity mask even in out-of-memory situations. - - * lib/nproc.c (num_processors_via_affinity_mask): Use a stack-allocated - cpu_set_t as fallback. Add comments. - -diff --git a/lib/nproc.c b/lib/nproc.c -index 48bc3d06fa..0b5898d88f 100644 ---- a/lib/nproc.c -+++ b/lib/nproc.c -@@ -125,15 +125,25 @@ num_processors_via_affinity_mask (void) - return count; - } - } --#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \ -- && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ -+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ -+ /* There are two ways to use the sched_getaffinity() function: -+ - With a statically-sized cpu_set_t. -+ - With a dynamically-sized cpu_set_t. -+ Documentation: -+ -+ -+ The second way has the advantage that it works on systems with more than -+ 1024 CPUs. The first way has the advantage that it works also when memory -+ is tight. */ -+# if defined CPU_ALLOC_SIZE /* glibc >= 2.6 */ - { - unsigned int alloc_count = 1024; -- while (1) -+ for (;;) - { - cpu_set_t *set = CPU_ALLOC (alloc_count); - if (set == NULL) -- return 0; -+ /* Out of memory. */ -+ break; - unsigned int size = CPU_ALLOC_SIZE (alloc_count); - if (sched_getaffinity (0, size, set) == 0) - { -@@ -143,16 +153,19 @@ num_processors_via_affinity_mask (void) - } - if (errno != EINVAL) - { -+ /* Some other error. */ - CPU_FREE (set); - return 0; - } - CPU_FREE (set); -+ /* Retry with some larger cpu_set_t. */ - alloc_count *= 2; - if (alloc_count == 0) -+ /* Integer overflow. Avoid an endless loop. */ - return 0; - } - } --#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */ -+# endif - { - cpu_set_t set; - diff --git a/coreutils-python3.patch b/coreutils-python3.patch index 98fc642..e6ff471 100644 --- a/coreutils-python3.patch +++ b/coreutils-python3.patch @@ -1,4 +1,4 @@ -From cef9cccce395cd80cd5ac42a4fe6c3909be1c0b5 Mon Sep 17 00:00:00 2001 +From f1a6e8d840a28eb2ab7a488e0d06450b7192c76d Mon Sep 17 00:00:00 2001 From: rpm-build Date: Tue, 2 Apr 2024 14:11:26 +0100 Subject: [PATCH] coreutils-python3.patch @@ -10,10 +10,10 @@ Subject: [PATCH] coreutils-python3.patch 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/init.cfg b/init.cfg -index b06965a..08413ee 100644 +index 612d287..9a6fa2d 100644 --- a/init.cfg +++ b/init.cfg -@@ -581,10 +581,10 @@ seek_data_capable_() +@@ -597,10 +597,10 @@ seek_data_capable_() # Skip the current test if "." lacks d_type support. require_dirent_d_type_() { @@ -37,7 +37,7 @@ index 1a2f76f..42d3924 100644 # Intended to exit 0 only on Linux/GNU systems. import os diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh -index 830a69e..7344ddf 100755 +index 1d0a359..bd03542 100755 --- a/tests/du/move-dir-while-traversing.sh +++ b/tests/du/move-dir-while-traversing.sh @@ -21,8 +21,8 @@ print_ver_ du @@ -61,5 +61,5 @@ index 830a69e..7344ddf 100755 import os,sys -- -2.44.0 +2.48.1 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch index a31c3af..91bc5b5 100644 --- a/coreutils-selinux.patch +++ b/coreutils-selinux.patch @@ -1,4 +1,4 @@ -From 78970c915b8556fcec4622e948a37dd8e34efe6d Mon Sep 17 00:00:00 2001 +From fc96cab095d704e8bf9934812dd8d6f87fbf4be4 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-selinux.patch @@ -9,10 +9,10 @@ Subject: [PATCH] coreutils-selinux.patch 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cp.c b/src/cp.c -index 28b0217..897379f 100644 +index a0ec067..1169c6a 100644 --- a/src/cp.c +++ b/src/cp.c -@@ -997,7 +997,7 @@ main (int argc, char **argv) +@@ -996,7 +996,7 @@ main (int argc, char **argv) selinux_enabled = (0 < is_selinux_enabled ()); cp_option_init (&x); @@ -21,7 +21,7 @@ index 28b0217..897379f 100644 long_opts, nullptr)) != -1) { -@@ -1049,6 +1049,23 @@ main (int argc, char **argv) +@@ -1048,6 +1048,23 @@ main (int argc, char **argv) copy_contents = true; break; @@ -46,7 +46,7 @@ index 28b0217..897379f 100644 x.preserve_links = true; x.dereference = DEREF_NEVER; diff --git a/src/install.c b/src/install.c -index accd0fd..b686fe9 100644 +index b3b26ab..2d2f072 100644 --- a/src/install.c +++ b/src/install.c @@ -807,7 +807,7 @@ main (int argc, char **argv) @@ -83,5 +83,5 @@ index accd0fd..b686fe9 100644 use_default_selinux_context = false; break; -- -2.44.0 +2.48.1 diff --git a/coreutils.spec b/coreutils.spec index b6b0f0f..79bf510 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.5 -Release: 13%{?dist} +Version: 9.6 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,13 +32,9 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch -# coreutils no longer lists Cockpit logins in `who` (rhbz#2307847) -# https://git.savannah.gnu.org/cgit/gnulib.git/patch/?id=43f7f428a1665950233557bd97611bd5e996b5cb -Patch105: coreutils-9.5-readutmp-web-session.patch - -# https://bugzilla.redhat.com/show_bug.cgi?id=2325167 -Patch106: coreutils-nproc-affinity-1.patch -Patch107: coreutils-nproc-affinity-2.patch +# ls: fix crash with --context +# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=915004f403cb25fadb207ddfdbe6a2f43bd44fac +Patch105: coreutils-9.6-ls-selinux-crash.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -162,6 +158,10 @@ sed src/dircolors.hin \ find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+' (echo "<<< done") 2>/dev/null +# FIXME: Force a newer gettext version to workaround `autoreconf -i` errors +# with coreutils 9.6 and bundled gettext 0.19.2 from gettext-common-devel. +sed -i 's/0.19.2/0.22.5/' bootstrap.conf configure.ac + autoreconf -fiv %build @@ -282,6 +282,10 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jan 20 2025 Lukáš Zaoral - 9.6-1 +- rebase to latest upstream version (rhbz#2338620) +- sync i18n patch with SUSE (Kudos to Berny Völker!) + * Thu Jan 16 2025 Fedora Release Engineering - 9.5-13 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild diff --git a/sources b/sources index d9dc6c9..498bfd9 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.5.tar.xz) = 2ca0deac4dc10a80fd0c6fd131252e99d457fd03b7bd626a6bc74fe5a0529c0a3d48ce1f5da1d3b3a7a150a1ce44f0fbb6b68a6ac543dfd5baa3e71f5d65401c -SHA512 (coreutils-9.5.tar.xz.sig) = 029997e0f4ee64e561853cff7c8a124f58cc891598595b44c4a46f9813b4b71c9d677464bc8a26d294e9971832f4b87c23777fea4fac6e8e30f06ad93b9957d5 +SHA512 (coreutils-9.6.tar.xz) = 398391d7f9d77e6117b750abb8711eebdd9cd2549e7846cab26884fb2dd522b6bcfb8bf7fef35a12683e213ada7f89b817bf615628628d42aee3fa3102647b28 +SHA512 (coreutils-9.6.tar.xz.sig) = a8e578b5e1d053b49e3e2c5dc94431d17c6a14662f459b2174cea23865ccca32e5ae5c13fedb0a8345d25269a9b98cb7f463a897c9663f9f9bcaf61e5c781378 From f0604fd61acae429a38c2f1a2e257b6417f81c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 25 Feb 2025 17:02:12 +0100 Subject: [PATCH 512/523] fix 'who -m' with guessed tty names Resolves: rhbz#2343998 --- coreutils-9.6-who-m-systemd.patch | 25 +++++++++++++++++++++++++ coreutils.spec | 9 ++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.6-who-m-systemd.patch diff --git a/coreutils-9.6-who-m-systemd.patch b/coreutils-9.6-who-m-systemd.patch new file mode 100644 index 0000000..5d43364 --- /dev/null +++ b/coreutils-9.6-who-m-systemd.patch @@ -0,0 +1,25 @@ +From 24450e5eecf012bc1ea8cab8d677a45fa42c1778 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= +Date: Mon, 24 Feb 2025 10:36:35 +0100 +Subject: who: fix -m with guessed tty names + +* who.c (scan_entries): Account for guessed tty names (e.g. +'sshd pts/1') from the readutmp module when using the systemd backend. +Addresses https://bugzilla.redhat.com/2343998 +--- + src/who.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/who.c b/src/who.c +index b56a1ac..17c1e34 100644 +--- a/src/who.c ++++ b/src/who.c +@@ -583,7 +583,7 @@ scan_entries (idx_t n, struct gl_utmp const *utmp_buf) + while (n--) + { + if (!my_line_only +- || STREQ (ttyname_b, utmp_buf->ut_line)) ++ || str_endswith (utmp_buf->ut_line, ttyname_b)) + { + if (need_users && IS_USER_PROCESS (utmp_buf)) + print_user (utmp_buf, boottime); diff --git a/coreutils.spec b/coreutils.spec index 79bf510..23eb924 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.6 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -36,6 +36,10 @@ Patch104: coreutils-df-direct.patch # https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=915004f403cb25fadb207ddfdbe6a2f43bd44fac Patch105: coreutils-9.6-ls-selinux-crash.patch +# who: fix -m with guessed tty names (rhbz#2343998) +# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=24450e5eecf012bc1ea8cab8d677a45fa42c1778 +Patch106: coreutils-9.6-who-m-systemd.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -282,6 +286,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Feb 25 2025 Lukáš Zaoral - 9.6-2 +- fix 'who -m' with guessed tty names (rhbz#2343998) + * Mon Jan 20 2025 Lukáš Zaoral - 9.6-1 - rebase to latest upstream version (rhbz#2338620) - sync i18n patch with SUSE (Kudos to Berny Völker!) From fdfe50c891adab069561406a15b3a7917e679c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Thu, 10 Apr 2025 10:40:14 +0200 Subject: [PATCH 513/523] rebase to latest upstream release Resolves: rhbz#2358624 --- coreutils-8.32-DIR_COLORS.patch | 14 +- coreutils-9.6-ls-selinux-crash.patch | 77 ---------- coreutils-9.6-who-m-systemd.patch | 25 ---- coreutils-df-direct.patch | 18 +-- coreutils-i18n.patch | 204 +++++++++++++++------------ coreutils.spec | 15 +- 6 files changed, 132 insertions(+), 221 deletions(-) delete mode 100644 coreutils-9.6-ls-selinux-crash.patch delete mode 100644 coreutils-9.6-who-m-systemd.patch diff --git a/coreutils-8.32-DIR_COLORS.patch b/coreutils-8.32-DIR_COLORS.patch index 021d2a5..37ce3e6 100644 --- a/coreutils-8.32-DIR_COLORS.patch +++ b/coreutils-8.32-DIR_COLORS.patch @@ -1,4 +1,4 @@ -From c7b13f5e1a7ad012c510a8bdd5a8943ab4b55833 Mon Sep 17 00:00:00 2001 +From bca11e30e8a6281a8cbddc9fb196dd86ab09c955 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Fri, 17 Jun 2016 16:58:18 +0200 Subject: [PATCH] downstream changes to default DIR_COLORS @@ -9,7 +9,7 @@ Subject: [PATCH] downstream changes to default DIR_COLORS 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/DIR_COLORS b/DIR_COLORS -index b465771..ad42b09 100644 +index 540f6cd..b4785b6 100644 --- a/DIR_COLORS +++ b/DIR_COLORS @@ -1,3 +1,7 @@ @@ -30,7 +30,7 @@ index b465771..ad42b09 100644 # =================================================================== # Terminal filters # =================================================================== -@@ -69,7 +76,7 @@ DOOR 01;35 # door +@@ -70,7 +77,7 @@ DOOR 01;35 # door BLK 40;33;01 # block device driver CHR 40;33;01 # character device driver ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... @@ -40,7 +40,7 @@ index b465771..ad42b09 100644 SETGID 30;43 # regular file that is setgid (g+s) CAPABILITY 00 # regular file with capability (very expensive to lookup) diff --git a/DIR_COLORS.lightbgcolor b/DIR_COLORS.lightbgcolor -index eab6258..1627b63 100644 +index e3b0ec3..39a0a4c 100644 --- a/DIR_COLORS.lightbgcolor +++ b/DIR_COLORS.lightbgcolor @@ -1,3 +1,9 @@ @@ -63,7 +63,7 @@ index eab6258..1627b63 100644 # =================================================================== # Terminal filters # =================================================================== -@@ -59,17 +68,17 @@ TERM xterm* +@@ -60,17 +69,17 @@ TERM xterm* #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all RESET 0 # reset to "normal" color @@ -86,7 +86,7 @@ index eab6258..1627b63 100644 SETUID 37;41 # regular file that is setuid (u+s) SETGID 30;43 # regular file that is setgid (g+s) CAPABILITY 00 # regular file with capability (very expensive to lookup) -@@ -78,7 +87,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky +@@ -79,7 +88,7 @@ OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable # This is for regular files with execute permission: @@ -96,5 +96,5 @@ index eab6258..1627b63 100644 # =================================================================== # File extension attributes -- -2.34.1 +2.49.0 diff --git a/coreutils-9.6-ls-selinux-crash.patch b/coreutils-9.6-ls-selinux-crash.patch deleted file mode 100644 index 70837cc..0000000 --- a/coreutils-9.6-ls-selinux-crash.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 915004f403cb25fadb207ddfdbe6a2f43bd44fac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Fri, 17 Jan 2025 17:29:34 +0000 -Subject: [PATCH] ls: fix crash with --context - -* src/ls.c (main): Flag that we need to stat() -if we're going to get security context (call file_has_aclinfo_cache). -(file_has_aclinfo_cache): Be defensive and only lookup the device -for the file if the stat has been performed. -(has_capability_cache): Likewise. -* tests/ls/selinux-segfault.sh: Add a test case. -Reported by Bruno Haible. ---- - src/ls.c | 10 +++++----- - tests/ls/selinux-segfault.sh | 3 +++ - 2 files changed, 8 insertions(+), 5 deletions(-) - -diff --git a/src/ls.c b/src/ls.c -index 3215360216..f67167f160 100644 ---- a/src/ls.c -+++ b/src/ls.c -@@ -1768,7 +1768,7 @@ main (int argc, char **argv) - - format_needs_stat = ((sort_type == sort_time) | (sort_type == sort_size) - | (format == long_format) -- | print_block_size | print_hyperlink); -+ | print_block_size | print_hyperlink | print_scontext); - format_needs_type = ((! format_needs_stat) - & (recursive | print_with_color | print_scontext - | directories_first -@@ -3309,7 +3309,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, - static int unsupported_scontext_err; - static dev_t unsupported_device; - -- if (f->stat.st_dev == unsupported_device) -+ if (f->stat_ok && f->stat.st_dev == unsupported_device) - { - ai->buf = ai->u.__gl_acl_ch; - ai->size = 0; -@@ -3322,7 +3322,7 @@ file_has_aclinfo_cache (char const *file, struct fileinfo *f, - errno = 0; - int n = file_has_aclinfo (file, ai, flags); - int err = errno; -- if (n <= 0 && !acl_errno_valid (err)) -+ if (f->stat_ok && n <= 0 && !acl_errno_valid (err)) - { - unsupported_return = n; - unsupported_scontext = ai->scontext; -@@ -3342,14 +3342,14 @@ has_capability_cache (char const *file, struct fileinfo *f) - found that has_capability fails indicating lack of support. */ - static dev_t unsupported_device; - -- if (f->stat.st_dev == unsupported_device) -+ if (f->stat_ok && f->stat.st_dev == unsupported_device) - { - errno = ENOTSUP; - return 0; - } - - bool b = has_capability (file); -- if ( !b && !acl_errno_valid (errno)) -+ if (f->stat_ok && !b && !acl_errno_valid (errno)) - unsupported_device = f->stat.st_dev; - return b; - } -diff --git a/tests/ls/selinux-segfault.sh b/tests/ls/selinux-segfault.sh -index 11623acb3f..1cac2b5fc0 100755 ---- a/tests/ls/selinux-segfault.sh -+++ b/tests/ls/selinux-segfault.sh -@@ -30,4 +30,7 @@ mkdir sedir || framework_failure_ - ln -sf missing sedir/broken || framework_failure_ - returns_ 1 ls -L -R -Z -m sedir > out || fail=1 - -+# ls 9.6 would segfault with the following -+ls -Z . > out || fail=1 -+ - Exit $fail diff --git a/coreutils-9.6-who-m-systemd.patch b/coreutils-9.6-who-m-systemd.patch deleted file mode 100644 index 5d43364..0000000 --- a/coreutils-9.6-who-m-systemd.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 24450e5eecf012bc1ea8cab8d677a45fa42c1778 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= -Date: Mon, 24 Feb 2025 10:36:35 +0100 -Subject: who: fix -m with guessed tty names - -* who.c (scan_entries): Account for guessed tty names (e.g. -'sshd pts/1') from the readutmp module when using the systemd backend. -Addresses https://bugzilla.redhat.com/2343998 ---- - src/who.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/who.c b/src/who.c -index b56a1ac..17c1e34 100644 ---- a/src/who.c -+++ b/src/who.c -@@ -583,7 +583,7 @@ scan_entries (idx_t n, struct gl_utmp const *utmp_buf) - while (n--) - { - if (!my_line_only -- || STREQ (ttyname_b, utmp_buf->ut_line)) -+ || str_endswith (utmp_buf->ut_line, ttyname_b)) - { - if (need_users && IS_USER_PROCESS (utmp_buf)) - print_user (utmp_buf, boottime); diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index d19ec29..f5e3d73 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From d179da4730f414069dd2c0ac995a32398718916c Mon Sep 17 00:00:00 2001 +From d3117ae1bb422f771f1c19af54f81d5151f55065 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,7 +11,7 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index ec58f6c..17cda80 100644 +index d1c282f..6d1ee11 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -12467,6 +12467,13 @@ some systems (notably Solaris), doing this yields more up to date results, @@ -29,7 +29,7 @@ index ec58f6c..17cda80 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 5c7efd8..52ece19 100644 +index a969c5c..c465a3f 100644 --- a/src/df.c +++ b/src/df.c @@ -122,6 +122,9 @@ static bool print_type; @@ -59,7 +59,7 @@ index 5c7efd8..52ece19 100644 {"inodes", no_argument, nullptr, 'i'}, {"human-readable", no_argument, nullptr, 'h'}, {"si", no_argument, nullptr, 'H'}, -@@ -571,7 +576,10 @@ get_header (void) +@@ -572,7 +577,10 @@ get_header (void) for (idx_t col = 0; col < ncolumns; col++) { char *cell; @@ -71,7 +71,7 @@ index 5c7efd8..52ece19 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1452,6 +1460,17 @@ get_point (char const *point, const struct stat *statp) +@@ -1454,6 +1462,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -89,7 +89,7 @@ index 5c7efd8..52ece19 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1522,6 +1541,7 @@ or all file systems by default.\n\ +@@ -1524,6 +1543,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -97,7 +97,7 @@ index 5c7efd8..52ece19 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1616,6 +1636,9 @@ main (int argc, char **argv) +@@ -1618,6 +1638,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -107,7 +107,7 @@ index 5c7efd8..52ece19 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1712,6 +1735,13 @@ main (int argc, char **argv) +@@ -1714,6 +1737,13 @@ main (int argc, char **argv) } } @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.48.1 +2.49.0 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index e7699c1..38b871c 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From a153c65067f6c09cf2cf38dc7c149aa1521c615a Mon Sep 17 00:00:00 2001 +From 3d25791ec9cc357a34620516d1c024ef17a4dd75 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -8,11 +8,11 @@ Subject: [PATCH] coreutils-i18n.patch configure.ac | 6 + lib/linebuffer.h | 8 + lib/mbchar.c | 23 ++ - lib/mbchar.h | 373 +++++++++++++++++ + lib/mbchar.h | 383 +++++++++++++++++ lib/mbfile.c | 20 + - lib/mbfile.h | 267 ++++++++++++ - m4/mbchar.m4 | 13 + - m4/mbfile.m4 | 14 + + lib/mbfile.h | 283 +++++++++++++ + m4/mbchar.m4 | 15 + + m4/mbfile.m4 | 16 + src/cut.c | 508 +++++++++++++++++++++-- src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + @@ -20,21 +20,21 @@ Subject: [PATCH] coreutils-i18n.patch src/fold.c | 311 ++++++++++++-- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- - src/sort.c | 792 +++++++++++++++++++++++++++++++++--- + src/sort.c | 790 +++++++++++++++++++++++++++++++++--- src/unexpand.c | 101 ++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ tests/i18n/sort.sh | 29 ++ tests/local.mk | 4 + tests/misc/expand.pl | 42 ++ - tests/misc/fold.pl | 51 ++- + tests/misc/fold.pl | 50 ++- tests/misc/sort-mb-tests.sh | 45 ++ tests/misc/unexpand.pl | 39 ++ tests/pr/pr-tests.pl | 49 +++ tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 30 files changed, 3603 insertions(+), 197 deletions(-) + 30 files changed, 3632 insertions(+), 195 deletions(-) create mode 100644 lib/mbchar.c create mode 100644 lib/mbchar.h create mode 100644 lib/mbfile.c @@ -47,10 +47,10 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 380fa11..ca80e6f 100644 +index 94c164e..cecbf26 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -165,6 +165,8 @@ gnulib_modules=" +@@ -166,6 +166,8 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -60,10 +60,10 @@ index 380fa11..ca80e6f 100644 mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index bf6da2a..321016d 100644 +index 775c4cc..e6b5c9c 100644 --- a/configure.ac +++ b/configure.ac -@@ -505,6 +505,12 @@ fi +@@ -504,6 +504,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -104,11 +104,11 @@ index ca56f80..509b7e6 100644 /* Initialize linebuffer LINEBUFFER for use. */ diff --git a/lib/mbchar.c b/lib/mbchar.c new file mode 100644 -index 0000000..d94b7c3 +index 0000000..713c2f7 --- /dev/null +++ b/lib/mbchar.c @@ -0,0 +1,23 @@ -+/* Copyright (C) 2001, 2006, 2009-2024 Free Software Foundation, Inc. ++/* Copyright (C) 2001, 2006, 2009-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -133,12 +133,12 @@ index 0000000..d94b7c3 +#include "mbchar.h" diff --git a/lib/mbchar.h b/lib/mbchar.h new file mode 100644 -index 0000000..c06ef11 +index 0000000..d77168e --- /dev/null +++ b/lib/mbchar.h -@@ -0,0 +1,373 @@ +@@ -0,0 +1,383 @@ +/* Multibyte character data type. -+ Copyright (C) 2001, 2005-2007, 2009-2024 Free Software Foundation, Inc. ++ Copyright (C) 2001, 2005-2007, 2009-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -296,6 +296,11 @@ index 0000000..c06ef11 +# define MBCHAR_INLINE _GL_INLINE +#endif + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ +/* The longest multibyte characters, nowadays, are 4 bytes long. + Regardless of the values of MB_CUR_MAX and MB_LEN_MAX. */ +#define MBCHAR_BUF_SIZE 4 @@ -507,17 +512,22 @@ index 0000000..c06ef11 + +#endif + ++ ++#ifdef __cplusplus ++} ++#endif ++ +_GL_INLINE_HEADER_END + +#endif /* _MBCHAR_H */ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 -index 0000000..8d2957b +index 0000000..f4e3e77 --- /dev/null +++ b/lib/mbfile.c @@ -0,0 +1,20 @@ +/* Multibyte character I/O: macros for multi-byte encodings. -+ Copyright (C) 2012-2023 Free Software Foundation, Inc. ++ Copyright (C) 2012-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -538,12 +548,12 @@ index 0000000..8d2957b +#include "mbfile.h" diff --git a/lib/mbfile.h b/lib/mbfile.h new file mode 100644 -index 0000000..ad61c19 +index 0000000..c852f31 --- /dev/null +++ b/lib/mbfile.h -@@ -0,0 +1,267 @@ +@@ -0,0 +1,283 @@ +/* Multibyte character I/O: macros for multi-byte encodings. -+ Copyright (C) 2001, 2005, 2009-2023 Free Software Foundation, Inc. ++ Copyright (C) 2001, 2005, 2009-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as @@ -598,6 +608,7 @@ index 0000000..ad61c19 + +#include +#include ++#include +#include +#include + @@ -608,14 +619,22 @@ index 0000000..ad61c19 +# define MBFILE_INLINE _GL_INLINE +#endif + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++/* Guarantee two characters of pushback. */ ++#define MBFILE_MAX_PUSHBACK 2 ++ +struct mbfile_multi { + FILE *fp; + bool eof_seen; -+ bool have_pushback; ++ unsigned int pushback_count; /* <= MBFILE_MAX_PUSHBACK */ + mbstate_t state; + unsigned int bufcount; + char buf[MBCHAR_BUF_SIZE]; -+ struct mbchar pushback; ++ struct mbchar pushback[MBFILE_MAX_PUSHBACK]; +}; + +MBFILE_INLINE void @@ -624,19 +643,19 @@ index 0000000..ad61c19 + unsigned int new_bufcount; + size_t bytes; + ++ /* Return character pushed back, if there is one. */ ++ if (mbf->pushback_count > 0) ++ { ++ mb_copy (mbc, &mbf->pushback[mbf->pushback_count - 1]); ++ mbf->pushback_count--; ++ return; ++ } ++ + /* If EOF has already been seen, don't use getc. This matters if + mbf->fp is connected to an interactive tty. */ + if (mbf->eof_seen) + goto eof; + -+ /* Return character pushed back, if there is one. */ -+ if (mbf->have_pushback) -+ { -+ mb_copy (mbc, &mbf->pushback); -+ mbf->have_pushback = false; -+ return; -+ } -+ + new_bufcount = mbf->bufcount; + + /* If mbf->state is not in an initial state, some more 32-bit wide character @@ -785,8 +804,10 @@ index 0000000..ad61c19 +MBFILE_INLINE void +mbfile_multi_ungetc (const struct mbchar *mbc, struct mbfile_multi *mbf) +{ -+ mb_copy (&mbf->pushback, mbc); -+ mbf->have_pushback = true; ++ if (mbf->pushback_count == MBFILE_MAX_PUSHBACK) ++ abort (); ++ mb_copy (&mbf->pushback[mbf->pushback_count], mbc); ++ mbf->pushback_count++; +} + +typedef struct mbfile_multi mb_file_t; @@ -796,7 +817,7 @@ index 0000000..ad61c19 +#define mbf_init(mbf, stream) \ + ((mbf).fp = (stream), \ + (mbf).eof_seen = false, \ -+ (mbf).have_pushback = false, \ ++ (mbf).pushback_count = 0, \ + mbszero (&(mbf).state), \ + (mbf).bufcount = 0) + @@ -806,20 +827,27 @@ index 0000000..ad61c19 + +#define mb_iseof(mbc) ((mbc).bytes == 0) + ++ ++#ifdef __cplusplus ++} ++#endif ++ +_GL_INLINE_HEADER_END + +#endif /* _MBFILE_H */ diff --git a/m4/mbchar.m4 b/m4/mbchar.m4 new file mode 100644 -index 0000000..471e8c4 +index 0000000..b76f1d7 --- /dev/null +++ b/m4/mbchar.m4 -@@ -0,0 +1,13 @@ -+# mbchar.m4 serial 9 -+dnl Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc. +@@ -0,0 +1,15 @@ ++# mbchar.m4 ++# serial 9 ++dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. ++dnl This file is offered as-is, without any warranty. + +dnl autoconf tests required for use of mbchar.m4 +dnl From Bruno Haible. @@ -830,15 +858,17 @@ index 0000000..471e8c4 +]) diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 -index 0000000..83068a9 +index 0000000..1d126e0 --- /dev/null +++ b/m4/mbfile.m4 -@@ -0,0 +1,14 @@ -+# mbfile.m4 serial 7 -+dnl Copyright (C) 2005, 2008-2023 Free Software Foundation, Inc. +@@ -0,0 +1,16 @@ ++# mbfile.m4 ++# serial 7 ++dnl Copyright (C) 2005, 2008-2025 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. ++dnl This file is offered as-is, without any warranty. + +dnl autoconf tests required for use of mbfile.h +dnl From Bruno Haible. @@ -1509,7 +1539,7 @@ index b424997..c9f181c 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index 2dbbbe4..91a90a3 100644 +index 732123f..fdbef3f 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -3008,7 +3038,7 @@ index e7081a0..19e0268 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 0928fd5..8c43fd4 100644 +index b10183b..fbf325b 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -3084,7 +3114,7 @@ index 0928fd5..8c43fd4 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -807,6 +838,46 @@ reap_all (void) +@@ -806,6 +837,46 @@ reap_all (void) reap (-1); } @@ -3131,7 +3161,7 @@ index 0928fd5..8c43fd4 100644 /* Clean up any remaining temporary files. */ static void -@@ -1274,7 +1345,7 @@ zaptemp (char const *name) +@@ -1273,7 +1344,7 @@ zaptemp (char const *name) free (node); } @@ -3140,7 +3170,7 @@ index 0928fd5..8c43fd4 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1289,7 +1360,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1288,7 +1359,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -3149,7 +3179,7 @@ index 0928fd5..8c43fd4 100644 { size_t i; -@@ -1301,7 +1372,7 @@ inittables (void) +@@ -1300,7 +1371,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -3158,7 +3188,7 @@ index 0928fd5..8c43fd4 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1381,6 +1452,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1380,6 +1451,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -3243,7 +3273,7 @@ index 0928fd5..8c43fd4 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1612,7 +1761,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1611,7 +1760,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -3252,7 +3282,7 @@ index 0928fd5..8c43fd4 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1621,10 +1770,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1620,10 +1769,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -3265,7 +3295,7 @@ index 0928fd5..8c43fd4 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1650,12 +1799,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1649,12 +1798,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3338,7 +3368,7 @@ index 0928fd5..8c43fd4 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1670,10 +1878,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1669,10 +1877,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3351,7 +3381,7 @@ index 0928fd5..8c43fd4 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1719,10 +1927,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1718,10 +1926,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3364,7 +3394,7 @@ index 0928fd5..8c43fd4 100644 if (newlim) lim = newlim; } -@@ -1753,6 +1961,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1752,6 +1960,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3495,7 +3525,7 @@ index 0928fd5..8c43fd4 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1839,8 +2171,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1838,8 +2170,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3520,7 +3550,7 @@ index 0928fd5..8c43fd4 100644 line->keybeg = line_start; } } -@@ -1978,12 +2324,10 @@ find_unit_order (char const *number) +@@ -1977,12 +2323,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3536,7 +3566,7 @@ index 0928fd5..8c43fd4 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1995,7 +2339,7 @@ human_numcompare (char const *a, char const *b) +@@ -1994,7 +2338,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3545,7 +3575,7 @@ index 0928fd5..8c43fd4 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2005,6 +2349,25 @@ numcompare (char const *a, char const *b) +@@ -2004,6 +2348,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3571,7 +3601,7 @@ index 0928fd5..8c43fd4 100644 static int nan_compare (long double a, long double b) { -@@ -2046,7 +2409,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2045,7 +2408,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3580,7 +3610,7 @@ index 0928fd5..8c43fd4 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2385,15 +2748,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2384,15 +2747,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3598,7 +3628,7 @@ index 0928fd5..8c43fd4 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2539,7 +2901,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2538,7 +2900,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3607,7 +3637,7 @@ index 0928fd5..8c43fd4 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2587,9 +2949,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2586,9 +2948,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3620,7 +3650,7 @@ index 0928fd5..8c43fd4 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2600,9 +2962,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2599,9 +2961,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3633,7 +3663,7 @@ index 0928fd5..8c43fd4 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2610,19 +2972,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2609,19 +2971,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3657,16 +3687,7 @@ index 0928fd5..8c43fd4 100644 } } -@@ -2633,7 +2995,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) - { - error (0, 0, - _("%snumbers use %s as a decimal point in this locale"), -- tab == decimal_point ? "" : _("note "), -+ (tab_length && tab[0] == decimal_point) ? "" : _("note "), - quote (((char []) {decimal_point, 0}))); - - } -@@ -2675,11 +3037,87 @@ diff_reversed (int diff, bool reversed) +@@ -2673,11 +3035,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3755,7 +3776,7 @@ index 0928fd5..8c43fd4 100644 { struct keyfield *key = keylist; -@@ -2760,7 +3198,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2758,7 +3196,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3764,7 +3785,7 @@ index 0928fd5..8c43fd4 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2870,6 +3308,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2868,6 +3306,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3976,7 +3997,7 @@ index 0928fd5..8c43fd4 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2897,7 +3540,7 @@ compare (struct line const *a, struct line const *b) +@@ -2895,7 +3538,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3985,7 +4006,7 @@ index 0928fd5..8c43fd4 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4285,6 +4928,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4283,6 +4926,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3993,7 +4014,7 @@ index 0928fd5..8c43fd4 100644 break; case 'g': key->general_numeric = true; -@@ -4364,7 +5008,7 @@ main (int argc, char **argv) +@@ -4362,7 +5006,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4002,7 +4023,7 @@ index 0928fd5..8c43fd4 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4387,6 +5031,29 @@ main (int argc, char **argv) +@@ -4385,6 +5029,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4032,7 +4053,7 @@ index 0928fd5..8c43fd4 100644 have_read_stdin = false; inittables (); -@@ -4657,13 +5324,34 @@ main (int argc, char **argv) +@@ -4655,13 +5322,34 @@ main (int argc, char **argv) case 't': { @@ -4071,7 +4092,7 @@ index 0928fd5..8c43fd4 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4674,9 +5362,11 @@ main (int argc, char **argv) +@@ -4672,9 +5360,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4528,7 +4549,7 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 12e30b4..1529db6 100644 +index 4da6756..fcbeef8 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -390,6 +390,8 @@ all_tests = \ @@ -4540,7 +4561,7 @@ index 12e30b4..1529db6 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -593,6 +595,7 @@ all_tests = \ +@@ -594,6 +596,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4548,7 +4569,7 @@ index 12e30b4..1529db6 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -749,6 +752,7 @@ all_tests = \ +@@ -750,6 +753,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4624,7 +4645,7 @@ index 4b07210..68b9ea1 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 0981ec9..ba889c8 100755 +index 877322e..ba889c8 100755 --- a/tests/misc/fold.pl +++ b/tests/misc/fold.pl @@ -20,9 +20,17 @@ use strict; @@ -4646,7 +4667,7 @@ index 0981ec9..ba889c8 100755 my @Tests = ( -@@ -44,9 +52,48 @@ my @Tests = +@@ -44,6 +52,46 @@ my @Tests = {OUT=>"123456\n7890\nabcdef\nghij\n123456\n7890"}], ); @@ -4693,9 +4714,6 @@ index 0981ec9..ba889c8 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; --my $prog = 'fold'; - my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose); - exit $fail; diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh new file mode 100644 index 0000000..11836ba @@ -5180,5 +5198,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.48.1 +2.49.0 diff --git a/coreutils.spec b/coreutils.spec index 23eb924..727da1b 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.6 -Release: 2%{?dist} +Version: 9.7 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,14 +32,6 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch -# ls: fix crash with --context -# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=915004f403cb25fadb207ddfdbe6a2f43bd44fac -Patch105: coreutils-9.6-ls-selinux-crash.patch - -# who: fix -m with guessed tty names (rhbz#2343998) -# https://git.savannah.gnu.org/cgit/coreutils.git/patch/?id=24450e5eecf012bc1ea8cab8d677a45fa42c1778 -Patch106: coreutils-9.6-who-m-systemd.patch - # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -286,6 +278,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Apr 09 2025 Lukáš Zaoral - 9.7-1 +- rebase to latest upstream release (rhbz#2358624) + * Tue Feb 25 2025 Lukáš Zaoral - 9.6-2 - fix 'who -m' with guessed tty names (rhbz#2343998) From 386bf34c2e19247b3b4b506588adf7cff5552d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Fri, 11 Apr 2025 09:17:07 +0200 Subject: [PATCH 514/523] sources: update for coreutils 9.7 ... which I forgot to commit with the rest of the changes... --- sources | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources b/sources index 498bfd9..0e9a66d 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.6.tar.xz) = 398391d7f9d77e6117b750abb8711eebdd9cd2549e7846cab26884fb2dd522b6bcfb8bf7fef35a12683e213ada7f89b817bf615628628d42aee3fa3102647b28 -SHA512 (coreutils-9.6.tar.xz.sig) = a8e578b5e1d053b49e3e2c5dc94431d17c6a14662f459b2174cea23865ccca32e5ae5c13fedb0a8345d25269a9b98cb7f463a897c9663f9f9bcaf61e5c781378 +SHA512 (coreutils-9.7.tar.xz) = fe81e6ba4fb492095153d5baac1eca8f07ece0957849de746a2a858cf007893cc2ded595a31a5e5d43d13216cc44b9d74a3245d9f23221ecc8cd00f428f27414 +SHA512 (coreutils-9.7.tar.xz.sig) = 48d86a19cee3c153f01f7478847f4621685c02e59942540bb20b30e314df05230817b87d0e73acd953e79fab35718e5bea57f25fe511a2c275a85ced4b317bae From a0b27bcd5fc64c0a9720e0b8ecc767258bac71de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 19 May 2025 09:47:42 +0200 Subject: [PATCH 515/523] cp/mv: do not fail when copying of trivial NFSv4 ACLs fails Resolves: rhbz#2363149 --- ...ils-9.6-cp-improve-nfsv4-acl-support.patch | 512 ++++++++++++++++++ coreutils.spec | 10 +- 2 files changed, 521 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.6-cp-improve-nfsv4-acl-support.patch diff --git a/coreutils-9.6-cp-improve-nfsv4-acl-support.patch b/coreutils-9.6-cp-improve-nfsv4-acl-support.patch new file mode 100644 index 0000000..1b36b1e --- /dev/null +++ b/coreutils-9.6-cp-improve-nfsv4-acl-support.patch @@ -0,0 +1,512 @@ +From 6ad28e2b6627caf7b83bf893027c087b8cea1a97 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Fri, 9 May 2025 18:02:29 -0700 +Subject: [PATCH 1/2] qcopy-acl: port better to NFSv4 on GNU/Linux + +Problem reported by Ian Dall in +and by Thomas Clark in . +* lib/file-has-acl.c (smack_new_label_from_file) [!HAVE_SMACK]: +New dummy function. +(has_xattr, get_aclinfo): New arg FD. All callers changed. +Remove some unnecessary MAYBE_UNUSEDs. +(acl_get_fd_np): Fall back on acl_get_fd if this function is +needed but not available. +(acl_get_fdfile): New function, if needed. +(file_has_aclinfo): Reimplement in terms of ... +(fdfile_has_aclinfo): ... this new function, +which also has an FD argument. +* lib/qcopy-acl.c [USE_XATTR]: Include dirent.h, for DT_DIR etc. +(qcopy_acl): If attr_copy_file or attr_copy_fd fail with EOPNOTSUPP, +don’t fail if the source has a trivial ACL (this is the part +that fixes the bug; the rest is optimization). + +(cherry picked from commit 8a356b77717a2e4f735ec06e326880ca1f61aadb) +--- + lib/acl.h | 2 + + lib/copy-acl.c | 1 + + lib/file-has-acl.c | 172 ++++++++++++++++++++++++++++++++------------- + lib/qcopy-acl.c | 29 ++++++-- + 4 files changed, 152 insertions(+), 52 deletions(-) + +diff --git a/lib/acl.h b/lib/acl.h +index 90fd24e..e3c134f 100644 +--- a/lib/acl.h ++++ b/lib/acl.h +@@ -79,6 +79,8 @@ struct aclinfo + bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST; + int file_has_acl (char const *, struct stat const *); + int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int); ++int fdfile_has_aclinfo (int, char const *restrict, ++ struct aclinfo *restrict, int); + + #if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR + bool aclinfo_has_xattr (struct aclinfo const *, char const *) +diff --git a/lib/copy-acl.c b/lib/copy-acl.c +index c36f64e..2fce6c7 100644 +--- a/lib/copy-acl.c ++++ b/lib/copy-acl.c +@@ -33,6 +33,7 @@ + a valid file descriptor, use file descriptor operations, else use + filename based operations on SRC_NAME. Likewise for DEST_DESC and + DST_NAME. ++ MODE should be the source file's st_mode. + If access control lists are not available, fchmod the target file to + MODE. Also sets the non-permission bits of the destination file + (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. +diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c +index 66b920c..a356ee0 100644 +--- a/lib/file-has-acl.c ++++ b/lib/file-has-acl.c +@@ -85,6 +85,13 @@ smack_new_label_from_path (MAYBE_UNUSED const char *path, + { + return -1; + } ++static ssize_t ++smack_new_label_from_file (MAYBE_UNUSED int fd, ++ MAYBE_UNUSED const char *xattr, ++ MAYBE_UNUSED char **label) ++{ ++ return -1; ++} + # endif + static bool + is_smack_enabled (void) +@@ -115,14 +122,16 @@ aclinfo_may_indicate_xattr (struct aclinfo const *ai) + + static bool + has_xattr (char const *xattr, struct aclinfo const *ai, +- MAYBE_UNUSED char const *restrict name, MAYBE_UNUSED int flags) ++ int fd, char const *restrict name, int flags) + { + if (ai && aclinfo_has_xattr (ai, xattr)) + return true; + else if (!ai || aclinfo_may_indicate_xattr (ai)) + { +- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) +- (name, xattr, NULL, 0)); ++ int ret = (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) ++ (name, xattr, NULL, 0)) ++ : fgetxattr (fd, xattr, NULL, 0)); + if (0 <= ret || (errno == ERANGE || errno == E2BIG)) + return true; + } +@@ -145,11 +154,12 @@ aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr) + return false; + } + +-/* Get attributes of the file NAME into AI, if USE_ACL. ++/* Get attributes of the file FD aka NAME into AI, if USE_ACL. ++ Ignore FD if it is negative. + If FLAGS & ACL_GET_SCONTEXT, also get security context. + If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */ + static void +-get_aclinfo (char const *name, struct aclinfo *ai, int flags) ++get_aclinfo (int fd, char const *name, struct aclinfo *ai, int flags) + { + int scontext_err = ENOTSUP; + ai->buf = ai->u.__gl_acl_ch; +@@ -163,7 +173,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) + = (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr); + while (true) + { +- ai->size = lsxattr (name, ai->buf, acl_alloc); ++ ai->size = (fd < 0 ++ ? lsxattr (name, ai->buf, acl_alloc) ++ : flistxattr (fd, ai->buf, acl_alloc)); + if (0 < ai->size) + break; + ai->u.err = ai->size < 0 ? errno : 0; +@@ -171,7 +183,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) + break; + + /* The buffer was too small. Find how large it should have been. */ +- ssize_t size = lsxattr (name, NULL, 0); ++ ssize_t size = (fd < 0 ++ ? lsxattr (name, NULL, 0) ++ : flistxattr (fd, NULL, 0)); + if (size <= 0) + { + ai->size = size; +@@ -214,9 +228,13 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) + { + if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SMACK)) + { +- ssize_t r = smack_new_label_from_path (name, "security.SMACK64", +- flags & ACL_SYMLINK_FOLLOW, +- &ai->scontext); ++ static char const SMACK64[] = "security.SMACK64"; ++ ssize_t r = ++ (fd < 0 ++ ? smack_new_label_from_path (name, SMACK64, ++ flags & ACL_SYMLINK_FOLLOW, ++ &ai->scontext) ++ : smack_new_label_from_file (fd, SMACK64, &ai->scontext)); + scontext_err = r < 0 ? errno : 0; + } + } +@@ -226,8 +244,10 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) + if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SELINUX)) + { + ssize_t r = +- ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) +- (name, &ai->scontext)); ++ (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) ++ (name, &ai->scontext)) ++ : fgetfilecon (fd, &ai->scontext)); + scontext_err = r < 0 ? errno : 0; + # ifndef SE_SELINUX_INLINE + /* Gnulib's selinux-h module is not in use, so getfilecon and +@@ -362,11 +382,13 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) + } + #endif + +-#if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FD \ +- && !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED \ +- && !HAVE_ACL_GET_LINK_NP) +-# include +-# ifdef O_PATH ++#if (!USE_LINUX_XATTR && USE_ACL && !HAVE_ACL_EXTENDED_FILE \ ++ && !HAVE_ACL_TYPE_EXTENDED) ++ ++# if HAVE_ACL_GET_FD && !HAVE_ACL_GET_LINK_NP ++# include ++# ifdef O_PATH ++# define acl_get_fd_np(fd, type) acl_get_fd (fd) + + /* Like acl_get_file, but do not follow symbolic links. */ + static acl_t +@@ -381,8 +403,24 @@ acl_get_link_np (char const *name, acl_type_t type) + errno = err; + return r; + } +-# define HAVE_ACL_GET_LINK_NP 1 ++# define HAVE_ACL_GET_LINK_NP 1 ++# endif + # endif ++ ++static acl_t ++acl_get_fdfile (int fd, char const *name, acl_type_t type, int flags) ++{ ++ acl_t (*get) (char const *, acl_type_t) = acl_get_file; ++# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ ++ if (0 <= fd) ++ return acl_get_fd_np (fd, type); ++ if (! (flags & ACL_SYMLINK_FOLLOW)) ++ get = acl_get_link_np; ++# else ++ /* Ignore FD and FLAGS, unfortunately. */ ++# endif ++ return get (name, type); ++} + #endif + + /* Return 1 if NAME has a nontrivial access control list, +@@ -398,14 +436,35 @@ acl_get_link_np (char const *name, acl_type_t type) + If the d_type value is not known, use DT_UNKNOWN though this may be less + efficient. */ + int +-file_has_aclinfo (MAYBE_UNUSED char const *restrict name, ++file_has_aclinfo (char const *restrict name, + struct aclinfo *restrict ai, int flags) ++{ ++ return fdfile_has_aclinfo (-1, name, ai, flags); ++} ++ ++/* Return 1 if FD aka NAME has a nontrivial access control list, ++ 0 if ACLs are not supported, or if NAME has no or only a base ACL, ++ and -1 (setting errno) on error. Note callers can determine ++ if ACLs are not supported as errno is set in that case also. ++ Ignore FD if it is negative. ++ Set *AI to ACL info regardless of return value. ++ FLAGS should be a d_type value, optionally ORed with ++ - _GL_DT_NOTDIR if it is known that NAME is not a directory, ++ - ACL_GET_SCONTEXT to retrieve security context and return 1 if present, ++ - ACL_SYMLINK_FOLLOW to follow the link if NAME is a symbolic link; ++ otherwise do not follow them if possible. ++ If the d_type value is not known, use DT_UNKNOWN though this may be less ++ efficient. */ ++int ++fdfile_has_aclinfo (MAYBE_UNUSED int fd, ++ MAYBE_UNUSED char const *restrict name, ++ struct aclinfo *restrict ai, int flags) + { + MAYBE_UNUSED unsigned char d_type = flags & UCHAR_MAX; + + #if USE_LINUX_XATTR + int initial_errno = errno; +- get_aclinfo (name, ai, flags); ++ get_aclinfo (fd, name, ai, flags); + + if (!aclinfo_may_indicate_xattr (ai) && ai->size <= 0) + { +@@ -418,11 +477,11 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + In earlier Fedora the two types of ACLs were mutually exclusive. + Attempt to work correctly on both kinds of systems. */ + +- if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, name, flags)) ++ if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, fd, name, flags)) + return +- (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, name, flags) ++ (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, fd, name, flags) + || ((d_type == DT_DIR || d_type == DT_UNKNOWN) +- && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, name, flags))); ++ && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, fd, name, flags))); + + /* A buffer large enough to hold any trivial NFSv4 ACL. + The max length of a trivial NFSv4 ACL is 6 words for owner, +@@ -432,8 +491,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + everyone is another word to hold "EVERYONE@". */ + uint32_t buf[2 * (6 + 6 + 7)]; + +- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) +- (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)); ++ int ret = (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) ++ (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)) ++ : fgetxattr (fd, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)); + if (ret < 0) + switch (errno) + { +@@ -467,20 +528,23 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + /* On Linux, acl_extended_file is an optimized function: It only + makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for + ACL_TYPE_DEFAULT. */ +- ret = ((flags & ACL_SYMLINK_FOLLOW +- ? acl_extended_file +- : acl_extended_file_nofollow) +- (name)); ++ ret = (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ++ ? acl_extended_file ++ : acl_extended_file_nofollow) ++ (name)) ++ : acl_extended_fd (fd)); + # elif HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ + /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS) + and acl_get_file (name, ACL_TYPE_DEFAULT) + always return NULL / EINVAL. There is no point in making + these two useless calls. The real ACL is retrieved through +- acl_get_file (name, ACL_TYPE_EXTENDED). */ +- acl_t acl = ((flags & ACL_SYMLINK_FOLLOW +- ? acl_get_file +- : acl_get_link_np) +- (name, ACL_TYPE_EXTENDED)); ++ ACL_TYPE_EXTENDED. */ ++ acl_t acl = ++ (fd < 0 ++ ? ((flags & ACL_SYMLINK_FOLLOW ? acl_get_file : acl_get_link_np) ++ (name, ACL_TYPE_EXTENDED)) ++ : acl_get_fd_np (fd, ACL_TYPE_EXTENDED)); + if (acl) + { + ret = acl_extended_nontrivial (acl); +@@ -489,13 +553,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + else + ret = -1; + # else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ +- acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file; +-# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ +- if (! (flags & ACL_SYMLINK_FOLLOW)) +- acl_get_file_or_link = acl_get_link_np; +-# endif + +- acl_t acl = acl_get_file_or_link (name, ACL_TYPE_ACCESS); ++ acl_t acl = acl_get_fdfile (fd, name, ACL_TYPE_ACCESS, flags); + if (acl) + { + ret = acl_access_nontrivial (acl); +@@ -517,7 +576,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + && (d_type == DT_DIR + || (d_type == DT_UNKNOWN && !(flags & _GL_DT_NOTDIR)))) + { +- acl = acl_get_file_or_link (name, ACL_TYPE_DEFAULT); ++ acl = acl_get_fdfile (fd, name, ACL_TYPE_DEFAULT, flags); + if (acl) + { + # ifdef __CYGWIN__ /* Cygwin >= 2.5 */ +@@ -562,7 +621,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + + /* Solaris 10 (newer version), which has additional API declared in + (acl_t) and implemented in libsec (acl_set, acl_trivial, +- acl_fromtext, ...). */ ++ acl_fromtext, ...). ++ ++ Ignore FD, unfortunately. That is better than mishandling ++ ZFS-style ACLs, as the general case code does. */ + return acl_trivial (name); + + # else /* Solaris, Cygwin, general case */ +@@ -586,7 +648,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + + for (;;) + { +- count = acl (name, GETACL, alloc, entries); ++ count = (fd < 0 ++ ? acl (name, GETACL, alloc, entries) ++ : facl (fd, GETACL, alloc, entries)); + if (count < 0 && errno == ENOSPC) + { + /* Increase the size of the buffer. */ +@@ -657,7 +721,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + + for (;;) + { +- count = acl (name, ACE_GETACL, alloc, entries); ++ count = (fd < 0 ++ ? acl (name, ACE_GETACL, alloc, entries) ++ : facl (fd, ACE_GETACL, alloc, entries)); + if (count < 0 && errno == ENOSPC) + { + /* Increase the size of the buffer. */ +@@ -722,7 +788,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + struct acl_entry entries[NACLENTRIES]; + int count; + +- count = getacl (name, NACLENTRIES, entries); ++ count = (fd < 0 ++ ? getacl (name, NACLENTRIES, entries) ++ : fgetacl (fd, NACLENTRIES, entries)); + + if (count < 0) + { +@@ -751,7 +819,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + { + struct stat statbuf; + +- if (stat (name, &statbuf) == -1 && errno != EOVERFLOW) ++ if ((fd < 0 ? stat (name, &statbuf) : fstat (fd, &statbuf)) < 0 ++ && errno != EOVERFLOW) + return -1; + + return acl_nontrivial (count, entries); +@@ -765,6 +834,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + struct acl entries[NACLVENTRIES]; + int count; + ++ /* Ignore FD, unfortunately. */ + count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries); + + if (count < 0) +@@ -809,7 +879,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + /* The docs say that type being 0 is equivalent to ACL_ANY, but it + is not true, in AIX 5.3. */ + type.u64 = ACL_ANY; +- if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0) ++ if (0 <= (fd < 0 ++ ? aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) ++ : aclx_fget (fd, 0, &type, aclbuf, &aclsize, &mode))) + break; + if (errno == ENOSYS) + return 0; +@@ -855,7 +927,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + + union { struct acl a; char room[4096]; } u; + +- if (statacl ((char *) name, STX_NORMAL, &u.a, sizeof (u)) < 0) ++ if ((fd < 0 ++ ? statacl ((char *) name, STX_NORMAL, &u.a, sizeof u) ++ : fstatacl (fd, STX_NORMAL, &u.a, sizeof u)) ++ < 0) + return -1; + + return acl_nontrivial (&u.a); +@@ -866,6 +941,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, + struct acl entries[NACLENTRIES]; + int count; + ++ /* Ignore FD, unfortunately. */ + count = acl ((char *) name, ACL_GET, NACLENTRIES, entries); + + if (count < 0) +diff --git a/lib/qcopy-acl.c b/lib/qcopy-acl.c +index ad79661..282f4b2 100644 +--- a/lib/qcopy-acl.c ++++ b/lib/qcopy-acl.c +@@ -26,6 +26,7 @@ + #if USE_XATTR + + # include ++# include + # include + + # if HAVE_LINUX_XATTR_H +@@ -61,6 +62,7 @@ is_attr_permissions (const char *name, struct error_context *ctx) + a valid file descriptor, use file descriptor operations, else use + filename based operations on SRC_NAME. Likewise for DEST_DESC and + DST_NAME. ++ MODE should be the source file's st_mode. + If access control lists are not available, fchmod the target file to + MODE. Also sets the non-permission bits of the destination file + (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. +@@ -86,10 +88,29 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, + Functions attr_copy_* return 0 in case we copied something OR nothing + to copy */ + if (ret == 0) +- ret = source_desc <= 0 || dest_desc <= 0 +- ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) +- : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, +- is_attr_permissions, NULL); ++ { ++ ret = source_desc <= 0 || dest_desc <= 0 ++ ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) ++ : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, ++ is_attr_permissions, NULL); ++ ++ /* Copying can fail with EOPNOTSUPP even when the source ++ permissions are trivial (Bug#78328). Don't report an error ++ in this case, as the chmod_or_fchmod suffices. */ ++ if (ret < 0 && errno == EOPNOTSUPP) ++ { ++ /* fdfile_has_aclinfo cares only about DT_DIR, _GL_DT_NOTDIR, ++ and DT_LNK (but DT_LNK is not possible here), ++ so use _GL_DT_NOTDIR | DT_UNKNOWN for other file types. */ ++ int flags = S_ISDIR (mode) ? DT_DIR : _GL_DT_NOTDIR | DT_UNKNOWN; ++ ++ struct aclinfo ai; ++ if (!fdfile_has_aclinfo (source_desc, src_name, &ai, flags)) ++ ret = 0; ++ aclinfo_free (&ai); ++ errno = EOPNOTSUPP; ++ } ++ } + #else + /* no XATTR, so we proceed the old dusty way */ + struct permission_context ctx; +-- +2.49.0 + + +From ed2bda5888829f4ebacd6dc9c86b7494dbf2a3b7 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Fri, 9 May 2025 18:48:03 -0700 +Subject: [PATCH 2/2] acl-tests: link with $(FILE_HAS_ACL_LIB) + +* modules/acl-tests (test_copy_acl_LDADD): Add +$(FILE_HAS_ACL_LIB), since qcopy-acl depends on file-has-acl. +Although this suggests that QCOPY_ACL_LIB should contain +FILE_HAS_ACL_LIB, I’m not sure whether that’s the right course of +action and anyway this is good enough for coreutils. + +(cherry picked from commit 955360a66c99bdd9ac3688519a8b521b06958fd3) +--- + gnulib-tests/gnulib.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk +index e222c63..4b78de4 100644 +--- a/gnulib-tests/gnulib.mk ++++ b/gnulib-tests/gnulib.mk +@@ -99,7 +99,7 @@ TESTS += \ + TESTS_ENVIRONMENT += USE_ACL=$(USE_ACL) + check_PROGRAMS += test-set-mode-acl test-copy-acl test-sameacls + test_set_mode_acl_LDADD = $(LDADD) $(LIB_ACL) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) +-test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) ++test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(FILE_HAS_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) + test_sameacls_LDADD = $(LDADD) $(LIB_ACL) @LIBINTL@ $(MBRTOWC_LIB) + EXTRA_DIST += test-set-mode-acl.sh test-set-mode-acl-1.sh test-set-mode-acl-2.sh test-copy-acl.sh test-copy-acl-1.sh test-copy-acl-2.sh test-set-mode-acl.c test-copy-acl.c test-sameacls.c macros.h + +-- +2.49.0 + diff --git a/coreutils.spec b/coreutils.spec index 727da1b..a9bbd58 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.7 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,6 +32,11 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch +# cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149) +# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=8a356b77717a2e4f735ec06e326880ca1f61aadb +# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=955360a66c99bdd9ac3688519a8b521b06958fd3 +Patch105: coreutils-9.6-cp-improve-nfsv4-acl-support.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -278,6 +283,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon May 19 2025 Lukáš Zaoral - 9.7-2 +- cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149) + * Wed Apr 09 2025 Lukáš Zaoral - 9.7-1 - rebase to latest upstream release (rhbz#2358624) From e454479c5cd5c28ccbbc0e3dc5668c33ffd7a683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Wed, 28 May 2025 09:40:47 +0200 Subject: [PATCH 516/523] sort: fix buffer under-read Resolves: CVE-2025-5278 --- coreutils-CVE-2025-5278.patch | 107 ++++++++++++++++++++++++++++++++++ coreutils-i18n.patch | 60 +++++++++---------- coreutils.spec | 9 ++- 3 files changed, 145 insertions(+), 31 deletions(-) create mode 100644 coreutils-CVE-2025-5278.patch diff --git a/coreutils-CVE-2025-5278.patch b/coreutils-CVE-2025-5278.patch new file mode 100644 index 0000000..af81286 --- /dev/null +++ b/coreutils-CVE-2025-5278.patch @@ -0,0 +1,107 @@ +From 701a9bdbf78f869e0fb778ed5aede00e42517add Mon Sep 17 00:00:00 2001 +From: Pádraig Brady +Date: Tue, 20 May 2025 16:03:44 +0100 +Subject: [PATCH] sort: fix buffer under-read (CWE-127) + +* src/sort.c (begfield): Check pointer adjustment +to avoid Out-of-range pointer offset (CWE-823). +(limfield): Likewise. +* tests/sort/sort-field-limit.sh: Add a new test, +which triggers with ASAN or Valgrind. +* tests/local.mk: Reference the new test. +Fixes https://bugs.gnu.org/78507 + +(cherry picked from commit 8c9602e3a145e9596dc1a63c6ed67865814b6633) +--- + src/sort.c | 12 ++++++++++-- + tests/local.mk | 1 + + tests/sort/sort-field-limit.sh | 35 ++++++++++++++++++++++++++++++++++ + 3 files changed, 46 insertions(+), 2 deletions(-) + create mode 100755 tests/sort/sort-field-limit.sh + +diff --git a/src/sort.c b/src/sort.c +index b10183b..7af1a25 100644 +--- a/src/sort.c ++++ b/src/sort.c +@@ -1644,7 +1644,11 @@ begfield (struct line const *line, struct keyfield const *key) + ++ptr; + + /* Advance PTR by SCHAR (if possible), but no further than LIM. */ +- ptr = MIN (lim, ptr + schar); ++ size_t remaining_bytes = lim - ptr; ++ if (schar < remaining_bytes) ++ ptr += schar; ++ else ++ ptr = lim; + + return ptr; + } +@@ -1746,7 +1750,11 @@ limfield (struct line const *line, struct keyfield const *key) + ++ptr; + + /* Advance PTR by ECHAR (if possible), but no further than LIM. */ +- ptr = MIN (lim, ptr + echar); ++ size_t remaining_bytes = lim - ptr; ++ if (echar < remaining_bytes) ++ ptr += echar; ++ else ++ ptr = lim; + } + + return ptr; +diff --git a/tests/local.mk b/tests/local.mk +index 4da6756..642d225 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -388,6 +388,7 @@ all_tests = \ + tests/sort/sort-debug-keys.sh \ + tests/sort/sort-debug-warn.sh \ + tests/sort/sort-discrim.sh \ ++ tests/sort/sort-field-limit.sh \ + tests/sort/sort-files0-from.pl \ + tests/sort/sort-float.sh \ + tests/sort/sort-h-thousands-sep.sh \ +diff --git a/tests/sort/sort-field-limit.sh b/tests/sort/sort-field-limit.sh +new file mode 100755 +index 0000000..52d8e1d +--- /dev/null ++++ b/tests/sort/sort-field-limit.sh +@@ -0,0 +1,35 @@ ++#!/bin/sh ++# From 7.2-9.7, this would trigger an out of bounds mem read ++ ++# Copyright (C) 2025 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ sort ++getlimits_ ++ ++# This issue triggers with valgrind or ASAN ++valgrind --error-exitcode=1 sort --version 2>/dev/null && ++ VALGRIND='valgrind --error-exitcode=1' ++ ++{ printf '%s\n' aa bb; } > in || framework_failure_ ++ ++_POSIX2_VERSION=200809 $VALGRIND sort +0.${SIZE_MAX}R in > out || fail=1 ++compare in out || fail=1 ++ ++_POSIX2_VERSION=200809 $VALGRIND sort +1 -1.${SIZE_MAX}R in > out || fail=1 ++compare in out || fail=1 ++ ++Exit $fail +-- +2.49.0 + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 38b871c..755f216 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From 3d25791ec9cc357a34620516d1c024ef17a4dd75 Mon Sep 17 00:00:00 2001 +From c657452b2d716807830c473bf36ef8d97c93cadf Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -3038,7 +3038,7 @@ index e7081a0..19e0268 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index b10183b..fbf325b 100644 +index 7af1a25..d3dc684 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -3295,7 +3295,7 @@ index b10183b..fbf325b 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1649,12 +1798,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1653,12 +1802,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3368,7 +3368,7 @@ index b10183b..fbf325b 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1669,10 +1877,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1673,10 +1881,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -3381,7 +3381,7 @@ index b10183b..fbf325b 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1718,10 +1926,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1722,10 +1930,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -3394,7 +3394,7 @@ index b10183b..fbf325b 100644 if (newlim) lim = newlim; } -@@ -1752,6 +1960,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1760,6 +1968,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -3525,7 +3525,7 @@ index b10183b..fbf325b 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1838,8 +2170,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1846,8 +2178,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -3550,7 +3550,7 @@ index b10183b..fbf325b 100644 line->keybeg = line_start; } } -@@ -1977,12 +2323,10 @@ find_unit_order (char const *number) +@@ -1985,12 +2331,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -3566,7 +3566,7 @@ index b10183b..fbf325b 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -1994,7 +2338,7 @@ human_numcompare (char const *a, char const *b) +@@ -2002,7 +2346,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -3575,7 +3575,7 @@ index b10183b..fbf325b 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2004,6 +2348,25 @@ numcompare (char const *a, char const *b) +@@ -2012,6 +2356,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -3601,7 +3601,7 @@ index b10183b..fbf325b 100644 static int nan_compare (long double a, long double b) { -@@ -2045,7 +2408,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2053,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -3610,7 +3610,7 @@ index b10183b..fbf325b 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2384,15 +2747,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2392,15 +2755,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -3628,7 +3628,7 @@ index b10183b..fbf325b 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2538,7 +2900,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2546,7 +2908,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -3637,7 +3637,7 @@ index b10183b..fbf325b 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2586,9 +2948,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2594,9 +2956,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -3650,7 +3650,7 @@ index b10183b..fbf325b 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2599,9 +2961,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2607,9 +2969,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -3663,7 +3663,7 @@ index b10183b..fbf325b 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2609,19 +2971,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2617,19 +2979,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -3687,7 +3687,7 @@ index b10183b..fbf325b 100644 } } -@@ -2673,11 +3035,87 @@ diff_reversed (int diff, bool reversed) +@@ -2681,11 +3043,87 @@ diff_reversed (int diff, bool reversed) return reversed ? (diff < 0) - (diff > 0) : diff; } @@ -3776,7 +3776,7 @@ index b10183b..fbf325b 100644 { struct keyfield *key = keylist; -@@ -2758,7 +3196,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2766,7 +3204,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -3785,7 +3785,7 @@ index b10183b..fbf325b 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2868,6 +3306,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2876,6 +3314,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3997,7 +3997,7 @@ index b10183b..fbf325b 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2895,7 +3538,7 @@ compare (struct line const *a, struct line const *b) +@@ -2903,7 +3546,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -4006,7 +4006,7 @@ index b10183b..fbf325b 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4283,6 +4926,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4291,6 +4934,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -4014,7 +4014,7 @@ index b10183b..fbf325b 100644 break; case 'g': key->general_numeric = true; -@@ -4362,7 +5006,7 @@ main (int argc, char **argv) +@@ -4370,7 +5014,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4023,7 +4023,7 @@ index b10183b..fbf325b 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4385,6 +5029,29 @@ main (int argc, char **argv) +@@ -4393,6 +5037,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4053,7 +4053,7 @@ index b10183b..fbf325b 100644 have_read_stdin = false; inittables (); -@@ -4655,13 +5322,34 @@ main (int argc, char **argv) +@@ -4663,13 +5330,34 @@ main (int argc, char **argv) case 't': { @@ -4092,7 +4092,7 @@ index b10183b..fbf325b 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4672,9 +5360,11 @@ main (int argc, char **argv) +@@ -4680,9 +5368,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4549,11 +4549,11 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 4da6756..fcbeef8 100644 +index 642d225..8e89530 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -390,6 +390,8 @@ all_tests = \ - tests/sort/sort-discrim.sh \ +@@ -391,6 +391,8 @@ all_tests = \ + tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ + tests/misc/sort-mb-tests.sh \ @@ -4561,7 +4561,7 @@ index 4da6756..fcbeef8 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -594,6 +596,7 @@ all_tests = \ +@@ -595,6 +597,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4569,7 +4569,7 @@ index 4da6756..fcbeef8 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -750,6 +753,7 @@ all_tests = \ +@@ -751,6 +754,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ diff --git a/coreutils.spec b/coreutils.spec index a9bbd58..af3a17a 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.7 -Release: 2%{?dist} +Release: 3%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -37,6 +37,10 @@ Patch104: coreutils-df-direct.patch # https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=955360a66c99bdd9ac3688519a8b521b06958fd3 Patch105: coreutils-9.6-cp-improve-nfsv4-acl-support.patch +# sort: fix buffer under-read (CVE-2025-5278) +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633 +Patch106: coreutils-CVE-2025-5278.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -283,6 +287,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed May 28 2025 Lukáš Zaoral - 9.7-3 +- sort: fix buffer under-read (CVE-2025-5278) + * Mon May 19 2025 Lukáš Zaoral - 9.7-2 - cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149) From c3c18147bda34d67a55115f5d5e2ff9b386380a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 30 Jun 2025 12:36:00 +0200 Subject: [PATCH 517/523] stty: add support for arbitrary baud rates Resolves: rhbz#2375439 --- coreutils-9.7-stty-arbitrary-baud-rates.patch | 669 ++++++++++++++++++ coreutils-i18n.patch | 14 +- coreutils.spec | 13 +- 3 files changed, 688 insertions(+), 8 deletions(-) create mode 100644 coreutils-9.7-stty-arbitrary-baud-rates.patch diff --git a/coreutils-9.7-stty-arbitrary-baud-rates.patch b/coreutils-9.7-stty-arbitrary-baud-rates.patch new file mode 100644 index 0000000..20d078b --- /dev/null +++ b/coreutils-9.7-stty-arbitrary-baud-rates.patch @@ -0,0 +1,669 @@ +From 8e5ee22042931bdac6488d61c5d59bcd1b0dba5f Mon Sep 17 00:00:00 2001 +From: "H. Peter Anvin" +Date: Mon, 16 Jun 2025 14:58:01 -0700 +Subject: [PATCH 1/5] stty: arbitrary or non-a priori known speed_t support + +Support the case where speed_t is simply a number, and in that case +assume that arbitrary values can be passed. This is assumed to be the +case when all known speed_t macros equal their own value. + +Try to probe for a variety of speed_t constants by trying to coax +$(CC) into emitting macro definitions (-E -dM). If this is not +supported, use a fairly extensive list of constants as a +fallback. This both improves the test for arbitrary speed support, as +well as allowing proper operation in the case where the constants are +not plain numbers and allows for handing enumerated speed constants +that were not known a priori when the source code was written. + +A simple shell script (mostly using sed) is used to turn the list of +constants (probed and predefined) into a pair of conversion functions, +baud_to_value() and value_to_baud(); string_to_baud() is then +reimplemented as a wrapper around the latter. + +* src/local.mk: Generate speedlist.h. +* src/speedgen: Portable shell script to generate speedlist.h. +* src/stty.c: Adjust string_to_baud to +convert from arbitrary numeric values. +* src/termios.c: A helper used when generating speedlist.h + +@lzaoral: This patch was amended to fix build failure in the +"single-binary" mode. + +(cherry picked from commit 357fda90d15fd3f7dba61e1ab322b183a48d0081) +--- + src/local.mk | 15 +++++- + src/speedgen | 85 ++++++++++++++++++++++++++++++ + src/stty.c | 143 +++++++++++++++++++------------------------------- + src/termios.c | 34 ++++++++++++ + 4 files changed, 188 insertions(+), 89 deletions(-) + create mode 100755 src/speedgen + create mode 100644 src/termios.c + +diff --git a/src/local.mk b/src/local.mk +index fd9dc81..3b8a34e 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -71,7 +71,8 @@ EXTRA_DIST += \ + src/dircolors.hin \ + src/primes.h \ + src/tac-pipe.c \ +- src/extract-magic ++ src/extract-magic \ ++ src/speedgen + + CLEANFILES += $(SCRIPTS) + +@@ -672,6 +673,18 @@ src/version.h: Makefile + $(AM_V_at)chmod a-w $@t + $(AM_V_at)mv $@t $@ + ++# Target-specific termios baud rate file. This is opportunistic; ++# if cc -E doesn't support -dM, the speedgen script still includes ++# an extensive fallback list of common constants. ++BUILT_SOURCES += src/speedlist.h ++src/speedlist.h: src/termios.c lib/config.h src/speedgen ++ $(AM_V_GEN)rm -f $@ ++ $(AM_V_at)${MKDIR_P} src ++ $(AM_V_at)$(COMPILE) -E -dM $< 2>/dev/null | \ ++ $(SHELL) $(srcdir)/src/speedgen $@t ++ $(AM_V_at)chmod a-w $@t ++ $(AM_V_at)mv $@t $@ ++ + # Generates a list of macro invocations like: + # SINGLE_BINARY_PROGRAM(program_name_str, main_name) + # once for each program list on $(single_binary_progs). Note that +diff --git a/src/speedgen b/src/speedgen +new file mode 100755 +index 0000000..f1647d9 +--- /dev/null ++++ b/src/speedgen +@@ -0,0 +1,85 @@ ++#!/bin/sh -e ++ ++out="$1" ++tmp="$out.tmp" ++ ++if [ -z "$out" ]; then ++ echo "Usage: $0 outfile" 2>&1 ++ exit 1 ++fi ++ ++s='[[:space:]]' # For brevity's sake ++ ++trap "rm -f '$tmp'" EXIT ++trap "rm -f '$tmp' '$out'" ERR HUP INT QUIT TERM ++ ++# Fallback list of speeds that are always tested for ++defspeeds="0 50 75 110 134 150 200 300 600 1200 1800 2400 4800 7200 9600 \ ++14400 19200 28800 33600 38400 57600 76800 115200 153600 230400 307200 \ ++460800 500000 576000 614400 921600 1000000 1152000 1500000 \ ++2000000 2500000 3000000 3500000 4000000 5000000 10000000" ++( ++ sed -n -e "s/^$s*\#$s*define$s$s*B\\([1-9][0-9]*\\)$s.*\$/\\1/p" ++ for s in $defspeeds; do echo "$s"; done ++) | sort -n | uniq > "$tmp" ++ ++cat > "$out" <<'EOF' ++#ifndef SPEEDLIST_H ++# define SPEEDLIST_H 1 ++ ++# if 1 \ ++EOF ++ ++sed -e 's/^.*$/ \&\& (!defined(B&) || B& == &) \\/' < "$tmp" >> "$out" ++ ++cat >> "$out" <<'EOF' ++ ++# define TERMIOS_SPEED_T_SANE 1 ++ ++# endif ++ ++ATTRIBUTE_CONST ++static unsigned long int ++baud_to_value (speed_t speed) ++{ ++# ifdef TERMIOS_SPEED_T_SANE ++ return speed; ++# else ++ switch (speed) ++ { ++EOF ++ ++sed -e 's/^.*$/# ifdef B&\n case B&: return &;\n# endif/' \ ++ < "$tmp" >> "$out" ++ ++cat >> "$out" <<'EOF' ++ default: return -1; ++ } ++# endif ++} ++ ++ATTRIBUTE_CONST ++static speed_t ++value_to_baud (unsigned long int value) ++{ ++# ifdef TERMIOS_SPEED_T_SANE ++ speed_t speed = value; ++ if (speed != value) ++ speed = (speed_t) -1; /* Unrepresentable (overflow?) */ ++ return speed; ++# else ++ switch (value) ++ { ++EOF ++ ++sed -e 's/^.*$/# ifdef B&\n case &: return B&;\n# endif/' \ ++ < "$tmp" >> "$out" ++ ++cat >> "$out" <<'EOF' ++ default: return (speed_t) -1; ++ } ++# endif ++} ++ ++#endif ++EOF +diff --git a/src/stty.c b/src/stty.c +index 133b33c..561de1c 100644 +--- a/src/stty.c ++++ b/src/stty.c +@@ -55,6 +55,7 @@ + + #include "system.h" + #include "assure.h" ++#include "c-ctype.h" + #include "fd-reopen.h" + #include "quote.h" + #include "xdectoint.h" +@@ -2172,100 +2173,66 @@ recover_mode (char const *arg, struct termios *mode) + return true; + } + +-struct speed_map +-{ +- char const *string; /* ASCII representation. */ +- speed_t speed; /* Internal form. */ +- unsigned long int value; /* Numeric value. */ +-}; +- +-static struct speed_map const speeds[] = +-{ +- {"0", B0, 0}, +- {"50", B50, 50}, +- {"75", B75, 75}, +- {"110", B110, 110}, +- {"134", B134, 134}, +- {"134.5", B134, 134}, +- {"150", B150, 150}, +- {"200", B200, 200}, +- {"300", B300, 300}, +- {"600", B600, 600}, +- {"1200", B1200, 1200}, +- {"1800", B1800, 1800}, +- {"2400", B2400, 2400}, +- {"4800", B4800, 4800}, +- {"9600", B9600, 9600}, +- {"19200", B19200, 19200}, +- {"38400", B38400, 38400}, +- {"exta", B19200, 19200}, +- {"extb", B38400, 38400}, +-#ifdef B57600 +- {"57600", B57600, 57600}, +-#endif +-#ifdef B115200 +- {"115200", B115200, 115200}, +-#endif +-#ifdef B230400 +- {"230400", B230400, 230400}, +-#endif +-#ifdef B460800 +- {"460800", B460800, 460800}, +-#endif +-#ifdef B500000 +- {"500000", B500000, 500000}, +-#endif +-#ifdef B576000 +- {"576000", B576000, 576000}, +-#endif +-#ifdef B921600 +- {"921600", B921600, 921600}, +-#endif +-#ifdef B1000000 +- {"1000000", B1000000, 1000000}, +-#endif +-#ifdef B1152000 +- {"1152000", B1152000, 1152000}, +-#endif +-#ifdef B1500000 +- {"1500000", B1500000, 1500000}, +-#endif +-#ifdef B2000000 +- {"2000000", B2000000, 2000000}, +-#endif +-#ifdef B2500000 +- {"2500000", B2500000, 2500000}, +-#endif +-#ifdef B3000000 +- {"3000000", B3000000, 3000000}, +-#endif +-#ifdef B3500000 +- {"3500000", B3500000, 3500000}, +-#endif +-#ifdef B4000000 +- {"4000000", B4000000, 4000000}, +-#endif +- {nullptr, 0, 0} +-}; ++/* Autogenerated conversion functions to/from speed_t */ ++#include "speedlist.h" + + ATTRIBUTE_PURE + static speed_t + string_to_baud (char const *arg) + { +- for (int i = 0; speeds[i].string != nullptr; ++i) +- if (STREQ (arg, speeds[i].string)) +- return speeds[i].speed; +- return (speed_t) -1; +-} ++ char *ep; ++ unsigned long value; ++ unsigned char c; + +-ATTRIBUTE_PURE +-static unsigned long int +-baud_to_value (speed_t speed) +-{ +- for (int i = 0; speeds[i].string != nullptr; ++i) +- if (speed == speeds[i].speed) +- return speeds[i].value; +- return 0; ++ /* Explicitly disallow negative numbers. */ ++ while (c_isspace (*arg)) ++ arg++; ++ if (*arg == '-') ++ return (speed_t) -1; ++ ++ value = strtoul (arg, &ep, 10); ++ ++ c = *ep++; ++ if (c == '.') ++ { ++ /* Number includes a fraction. Round it to nearest-even. ++ Note in particular that 134.5 must round to 134! */ ++ c = *ep++; ++ if (c) ++ { ++ c -= '0'; ++ if (c > 9) ++ { ++ return (speed_t) -1; /* Garbage after otherwise valid number */ ++ } ++ else if (c > 5) ++ { ++ value++; ++ } ++ else if (c == 5) ++ { ++ while ((c = *ep++) == '0') ++ ; /* Skip zeroes after .5 */ ++ ++ if (c >= '1' && c <= '9') ++ value++; /* Nonzero digit, round up */ ++ else ++ value += (value & 1); /* Exactly in the middle, round even */ ++ } ++ } ++ } ++ else if (c) ++ { ++ /* Not a valid number; check for legacy aliases "exta" and "extb" */ ++ if (STREQ (arg, "exta")) ++ return B19200; ++ else if (STREQ (arg, "extb")) ++ return B38400; ++ else ++ return (speed_t) -1; ++ } ++ ++ return value_to_baud (value); + } + + static void +diff --git a/src/termios.c b/src/termios.c +new file mode 100644 +index 0000000..f17e12e +--- /dev/null ++++ b/src/termios.c +@@ -0,0 +1,34 @@ ++/* termios.c -- coax out Bxxx macros from termios.h ++ ++ Copyright (C) 2025 Free Software Foundation, Inc. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* This simply #includes headers which may or may not provide Bxxx ++ constant macros. This is run through the C preprocessor and defined ++ macros are extracted. ++ ++ In the case where the C preprocessor isn't capable of doing so, ++ the script this is fed through contains a pre-defined set of common ++ constants. */ ++ ++#include ++ ++#ifdef TERMIOS_NEEDS_XOPEN_SOURCE ++# define _XOPEN_SOURCE ++#endif ++ ++#include ++#include ++#include +-- +2.50.0 + + +From 60c9206391e2fac32639d3a143435d1dd9ec6421 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Tue, 17 Jun 2025 23:32:05 +0100 +Subject: [PATCH 2/5] tests: stty: adjust tests for arbitary speeds + +* tests/stty/stty-invalid.sh: Adjust to what is now invalid. +* tests/stty/stty.sh: Add checks for valid speed variants. +* tests/stty/bad-speed.sh: New test to ensure unsupported speeds +are diagnosed. + +(cherry picked from commit efaec8078142996d958b6720b85a13b12497c3d0) +--- + tests/local.mk | 1 + + tests/stty/bad-speed.sh | 50 ++++++++++++++++++++++++++++++++++++++ + tests/stty/stty-invalid.sh | 10 ++++++-- + tests/stty/stty.sh | 10 ++++++++ + 4 files changed, 69 insertions(+), 2 deletions(-) + create mode 100755 tests/stty/bad-speed.sh + +diff --git a/tests/local.mk b/tests/local.mk +index 642d225..b68df41 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -425,6 +425,7 @@ all_tests = \ + tests/stat/stat-printf.pl \ + tests/stat/stat-slash.sh \ + tests/misc/stdbuf.sh \ ++ tests/stty/bad-speed.sh \ + tests/stty/stty.sh \ + tests/stty/stty-invalid.sh \ + tests/stty/stty-pairs.sh \ +diff --git a/tests/stty/bad-speed.sh b/tests/stty/bad-speed.sh +new file mode 100755 +index 0000000..d80d2e7 +--- /dev/null ++++ b/tests/stty/bad-speed.sh +@@ -0,0 +1,50 @@ ++#!/bin/sh ++# Ensure we handle cfsetispeed failing ++# which we did not before coreutils v9.1 ++ ++# Copyright (C) 2025 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ stty ++require_gcc_shared_ ++ ++# Replace each cfsetispeed call with a call to these stubs. ++cat > k.c <<'EOF' || framework_failure_ ++#include ++#include ++#include ++#include ++ ++int cfsetispeed(struct termios *termios_p, speed_t speed) ++{ ++ /* Leave a marker so we can identify if the function was intercepted. */ ++ fclose(fopen("preloaded", "w")); ++ ++ errno=EINVAL; ++ return -1; ++} ++EOF ++ ++# Then compile/link it: ++gcc_shared_ k.c k.so \ ++ || skip_ 'failed to build shared library' ++ ++( export LD_PRELOAD=$LD_PRELOAD:./k.so ++ returns_ 1 stty ispeed 9600 ) || fail=1 ++ ++test -e preloaded || skip_ 'LD_PRELOAD interception failed' ++ ++Exit $fail +diff --git a/tests/stty/stty-invalid.sh b/tests/stty/stty-invalid.sh +index 4b87e2a..a1442a8 100755 +--- a/tests/stty/stty-invalid.sh ++++ b/tests/stty/stty-invalid.sh +@@ -20,6 +20,7 @@ + print_ver_ stty + require_controlling_input_terminal_ + require_trap_signame_ ++getlimits_ + + trap '' TTOU # Ignore SIGTTOU + +@@ -50,8 +51,13 @@ if tty -s = 9.8 supports arbitrary speeds on some systems ++# so restrict tests here to invalid numbers ++# We simulate unsupported numbers in a separate "LD_PRELOAD" test. ++WRAP_9600="$(expr $ULONG_OFLOW - 9600)" ++for speed in 9600.. ++9600 -$WRAP_9600 --$WRAP_9600 0x2580 96E2; do ++ returns_ 1 stty ispeed "$speed" || fail=1 ++done + + # Just in case either of the above mistakenly succeeds (and changes + # the state of our tty), try to restore the initial state. +diff --git a/tests/stty/stty.sh b/tests/stty/stty.sh +index dab4cd0..c0f7494 100755 +--- a/tests/stty/stty.sh ++++ b/tests/stty/stty.sh +@@ -95,4 +95,14 @@ for W in $(seq 80 90); do + test "$output_width" -le "$W" || fail=1 + done + ++# Ensure we support varied numeric forms ++# with appropriate rounding ++if stty ispeed '9600'; then ++ stty ispeed ' +9600' || fail=1 ++ stty ispeed '9600.49' || fail=1 ++ stty ispeed '9600.50' || fail=1 ++ stty ispeed '9599.51' || fail=1 ++ stty ispeed ' 9600.' || fail=1 ++fi ++ + Exit $fail +-- +2.50.0 + + +From a47c15eea3ffe08662415ae13873b40c7ffcdb43 Mon Sep 17 00:00:00 2001 +From: Collin Funk +Date: Sat, 21 Jun 2025 22:05:19 -0700 +Subject: [PATCH 3/5] build: add src/termios.c to the tarball + +* src/local.mk (EXTRA_DIST): Add src/termios.c. + +(cherry picked from commit b7db7757831e93ca44ae59e1921bc4ebbc87974f) +--- + src/local.mk | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/local.mk b/src/local.mk +index 3b8a34e..188dda1 100644 +--- a/src/local.mk ++++ b/src/local.mk +@@ -72,7 +72,8 @@ EXTRA_DIST += \ + src/primes.h \ + src/tac-pipe.c \ + src/extract-magic \ +- src/speedgen ++ src/speedgen \ ++ src/termios.c + + CLEANFILES += $(SCRIPTS) + +-- +2.50.0 + + +From caa439bf750193bcbed215a6676053f0b3c96e21 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Sun, 22 Jun 2025 15:01:21 +0100 +Subject: [PATCH 4/5] doc: stty: adjust description of supported speeds + +* doc/coreutils.texi (stty invocation): Remove now imprecise +list of speeds given we may now support higher or arbitrary speeds. +Mention that we may support higher or arbitrary speeds. + +(cherry picked from commit 8b05eca972f70858749a946ac24f08d0718c1be6) +--- + doc/coreutils.texi | 21 ++------------------- + 1 file changed, 2 insertions(+), 19 deletions(-) + +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 6d1ee11..c04af2b 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -15932,25 +15932,8 @@ Print the terminal speed. + Set the input and output speeds to @var{n}. @var{n} can be one of: 0 + 50 75 110 134 134.5 150 200 300 600 1200 1800 2400 4800 9600 19200 + 38400 @code{exta} @code{extb}. @code{exta} is the same as 19200; +-@code{extb} is the same as 38400. Many systems, including GNU/Linux, +-support higher speeds. The @command{stty} command includes support +-for speeds of +-57600, +-115200, +-230400, +-460800, +-500000, +-576000, +-921600, +-1000000, +-1152000, +-1500000, +-2000000, +-2500000, +-3000000, +-3500000, +-or +-4000000 where the system supports these. ++@code{extb} is the same as 38400. Many systems, support arbitrary ++or higher speeds. + 0 hangs up the line if @option{-clocal} is set. + @end table + +-- +2.50.0 + + +From 8e48d56c2aa10f9875ffe1ec051a17f0eab6d2f9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Sun, 22 Jun 2025 16:40:04 +0100 +Subject: [PATCH 5/5] stty: stricter floating point parsing + +* src/stty.c (string_to_baud): Disallow extraneous characters +after floating point numbers. +* tests/stty/stty-invalid.sh: Add test cases. + +(cherry picked from commit 3d35b3c0e56bd556c90dc98c3e5e2e7289b0eb0d) +--- + src/stty.c | 27 +++++++++++++-------------- + tests/stty/stty-invalid.sh | 3 ++- + 2 files changed, 15 insertions(+), 15 deletions(-) + +diff --git a/src/stty.c b/src/stty.c +index 561de1c..0163ea4 100644 +--- a/src/stty.c ++++ b/src/stty.c +@@ -2200,25 +2200,24 @@ string_to_baud (char const *arg) + c = *ep++; + if (c) + { +- c -= '0'; +- if (c > 9) ++ unsigned char d = c - '0'; ++ if (d > 5) ++ value++; ++ else if (d == 5) + { +- return (speed_t) -1; /* Garbage after otherwise valid number */ +- } +- else if (c > 5) +- { +- value++; +- } +- else if (c == 5) +- { +- while ((c = *ep++) == '0') +- ; /* Skip zeroes after .5 */ ++ while ((c = *ep++) == '0'); /* Skip zeroes after .5 */ + +- if (c >= '1' && c <= '9') +- value++; /* Nonzero digit, round up */ ++ if (c) ++ value++; /* Nonzero, round up */ + else + value += (value & 1); /* Exactly in the middle, round even */ + } ++ ++ while (c_isdigit (c)) /* Skip remaining digits. */ ++ c = *ep++; ++ ++ if (c) ++ return (speed_t) -1; /* Garbage after otherwise valid number */ + } + } + else if (c) +diff --git a/tests/stty/stty-invalid.sh b/tests/stty/stty-invalid.sh +index a1442a8..868ed1d 100755 +--- a/tests/stty/stty-invalid.sh ++++ b/tests/stty/stty-invalid.sh +@@ -55,7 +55,8 @@ fi + # so restrict tests here to invalid numbers + # We simulate unsupported numbers in a separate "LD_PRELOAD" test. + WRAP_9600="$(expr $ULONG_OFLOW - 9600)" +-for speed in 9600.. ++9600 -$WRAP_9600 --$WRAP_9600 0x2580 96E2; do ++for speed in 9599.. 9600.. 9600.5. 9600.50. 9600.0. ++9600 \ ++ -$WRAP_9600 --$WRAP_9600 0x2580 96E2 9600,0 '9600.0 '; do + returns_ 1 stty ispeed "$speed" || fail=1 + done + +-- +2.50.0 + diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 755f216..2917075 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From c657452b2d716807830c473bf36ef8d97c93cadf Mon Sep 17 00:00:00 2001 +From c0db8de625ca1ae0e0f4784c4eb2c779eae0047f Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -2252,10 +2252,10 @@ index b64aad4..a156337 100644 case 's': /* Break at word boundaries. */ diff --git a/src/local.mk b/src/local.mk -index fd9dc81..5133cc0 100644 +index 188dda1..7db5753 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -476,8 +476,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -478,8 +478,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -4549,7 +4549,7 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 642d225..8e89530 100644 +index b68df41..0fe8193 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -391,6 +391,8 @@ all_tests = \ @@ -4561,7 +4561,7 @@ index 642d225..8e89530 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -595,6 +597,7 @@ all_tests = \ +@@ -596,6 +598,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4569,7 +4569,7 @@ index 642d225..8e89530 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -751,6 +754,7 @@ all_tests = \ +@@ -752,6 +755,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -5198,5 +5198,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.49.0 +2.50.0 diff --git a/coreutils.spec b/coreutils.spec index af3a17a..dfe70d7 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.7 -Release: 3%{?dist} +Release: 4%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -41,6 +41,14 @@ Patch105: coreutils-9.6-cp-improve-nfsv4-acl-support.patch # https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633 Patch106: coreutils-CVE-2025-5278.patch +# stty: add support for arbitrary baud rates (rhbz#2375439) +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=357fda90d15fd3f7dba61e1ab322b183a48d0081 +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=efaec8078142996d958b6720b85a13b12497c3d0 +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=b7db7757831e93ca44ae59e1921bc4ebbc87974f +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8b05eca972f70858749a946ac24f08d0718c1be6 +# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=3d35b3c0e56bd556c90dc98c3e5e2e7289b0eb0d +Patch107: coreutils-9.7-stty-arbitrary-baud-rates.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -287,6 +295,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Jun 30 2025 Lukáš Zaoral - 9.7-4 +- stty: add support for arbitrary baud rates (rhbz#2375439) + * Wed May 28 2025 Lukáš Zaoral - 9.7-3 - sort: fix buffer under-read (CVE-2025-5278) From c493f607abc435122d1cb12a358a672bee09ee93 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 23 Jul 2025 18:40:40 +0000 Subject: [PATCH 518/523] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- coreutils.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index dfe70d7..17e98b3 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.7 -Release: 4%{?dist} +Release: 5%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -295,6 +295,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Jul 23 2025 Fedora Release Engineering - 9.7-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Mon Jun 30 2025 Lukáš Zaoral - 9.7-4 - stty: add support for arbitrary baud rates (rhbz#2375439) From 20976b8be8f329b2ffc60ed31fba89ed8ad2106a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Wed, 24 Sep 2025 10:00:43 +0200 Subject: [PATCH 519/523] rebase to latest upstream release - remove downstream patch for selinux options deprecated since 2009 Resolves: rhbz#2397467 --- ...ils-9.6-cp-improve-nfsv4-acl-support.patch | 512 --------- coreutils-9.7-stty-arbitrary-baud-rates.patch | 669 ------------ coreutils-CVE-2025-5278.patch | 107 -- coreutils-df-direct.patch | 24 +- coreutils-i18n.patch | 976 +----------------- coreutils-python3.patch | 10 +- coreutils-selinux.patch | 87 -- coreutils.spec | 28 +- sources | 4 +- 9 files changed, 53 insertions(+), 2364 deletions(-) delete mode 100644 coreutils-9.6-cp-improve-nfsv4-acl-support.patch delete mode 100644 coreutils-9.7-stty-arbitrary-baud-rates.patch delete mode 100644 coreutils-CVE-2025-5278.patch delete mode 100644 coreutils-selinux.patch diff --git a/coreutils-9.6-cp-improve-nfsv4-acl-support.patch b/coreutils-9.6-cp-improve-nfsv4-acl-support.patch deleted file mode 100644 index 1b36b1e..0000000 --- a/coreutils-9.6-cp-improve-nfsv4-acl-support.patch +++ /dev/null @@ -1,512 +0,0 @@ -From 6ad28e2b6627caf7b83bf893027c087b8cea1a97 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Fri, 9 May 2025 18:02:29 -0700 -Subject: [PATCH 1/2] qcopy-acl: port better to NFSv4 on GNU/Linux - -Problem reported by Ian Dall in -and by Thomas Clark in . -* lib/file-has-acl.c (smack_new_label_from_file) [!HAVE_SMACK]: -New dummy function. -(has_xattr, get_aclinfo): New arg FD. All callers changed. -Remove some unnecessary MAYBE_UNUSEDs. -(acl_get_fd_np): Fall back on acl_get_fd if this function is -needed but not available. -(acl_get_fdfile): New function, if needed. -(file_has_aclinfo): Reimplement in terms of ... -(fdfile_has_aclinfo): ... this new function, -which also has an FD argument. -* lib/qcopy-acl.c [USE_XATTR]: Include dirent.h, for DT_DIR etc. -(qcopy_acl): If attr_copy_file or attr_copy_fd fail with EOPNOTSUPP, -don’t fail if the source has a trivial ACL (this is the part -that fixes the bug; the rest is optimization). - -(cherry picked from commit 8a356b77717a2e4f735ec06e326880ca1f61aadb) ---- - lib/acl.h | 2 + - lib/copy-acl.c | 1 + - lib/file-has-acl.c | 172 ++++++++++++++++++++++++++++++++------------- - lib/qcopy-acl.c | 29 ++++++-- - 4 files changed, 152 insertions(+), 52 deletions(-) - -diff --git a/lib/acl.h b/lib/acl.h -index 90fd24e..e3c134f 100644 ---- a/lib/acl.h -+++ b/lib/acl.h -@@ -79,6 +79,8 @@ struct aclinfo - bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST; - int file_has_acl (char const *, struct stat const *); - int file_has_aclinfo (char const *restrict, struct aclinfo *restrict, int); -+int fdfile_has_aclinfo (int, char const *restrict, -+ struct aclinfo *restrict, int); - - #if HAVE_LINUX_XATTR_H && HAVE_LISTXATTR - bool aclinfo_has_xattr (struct aclinfo const *, char const *) -diff --git a/lib/copy-acl.c b/lib/copy-acl.c -index c36f64e..2fce6c7 100644 ---- a/lib/copy-acl.c -+++ b/lib/copy-acl.c -@@ -33,6 +33,7 @@ - a valid file descriptor, use file descriptor operations, else use - filename based operations on SRC_NAME. Likewise for DEST_DESC and - DST_NAME. -+ MODE should be the source file's st_mode. - If access control lists are not available, fchmod the target file to - MODE. Also sets the non-permission bits of the destination file - (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. -diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c -index 66b920c..a356ee0 100644 ---- a/lib/file-has-acl.c -+++ b/lib/file-has-acl.c -@@ -85,6 +85,13 @@ smack_new_label_from_path (MAYBE_UNUSED const char *path, - { - return -1; - } -+static ssize_t -+smack_new_label_from_file (MAYBE_UNUSED int fd, -+ MAYBE_UNUSED const char *xattr, -+ MAYBE_UNUSED char **label) -+{ -+ return -1; -+} - # endif - static bool - is_smack_enabled (void) -@@ -115,14 +122,16 @@ aclinfo_may_indicate_xattr (struct aclinfo const *ai) - - static bool - has_xattr (char const *xattr, struct aclinfo const *ai, -- MAYBE_UNUSED char const *restrict name, MAYBE_UNUSED int flags) -+ int fd, char const *restrict name, int flags) - { - if (ai && aclinfo_has_xattr (ai, xattr)) - return true; - else if (!ai || aclinfo_may_indicate_xattr (ai)) - { -- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) -- (name, xattr, NULL, 0)); -+ int ret = (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) -+ (name, xattr, NULL, 0)) -+ : fgetxattr (fd, xattr, NULL, 0)); - if (0 <= ret || (errno == ERANGE || errno == E2BIG)) - return true; - } -@@ -145,11 +154,12 @@ aclinfo_has_xattr (struct aclinfo const *ai, char const *xattr) - return false; - } - --/* Get attributes of the file NAME into AI, if USE_ACL. -+/* Get attributes of the file FD aka NAME into AI, if USE_ACL. -+ Ignore FD if it is negative. - If FLAGS & ACL_GET_SCONTEXT, also get security context. - If FLAGS & ACL_SYMLINK_FOLLOW, follow symbolic links. */ - static void --get_aclinfo (char const *name, struct aclinfo *ai, int flags) -+get_aclinfo (int fd, char const *name, struct aclinfo *ai, int flags) - { - int scontext_err = ENOTSUP; - ai->buf = ai->u.__gl_acl_ch; -@@ -163,7 +173,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) - = (flags & ACL_SYMLINK_FOLLOW ? listxattr : llistxattr); - while (true) - { -- ai->size = lsxattr (name, ai->buf, acl_alloc); -+ ai->size = (fd < 0 -+ ? lsxattr (name, ai->buf, acl_alloc) -+ : flistxattr (fd, ai->buf, acl_alloc)); - if (0 < ai->size) - break; - ai->u.err = ai->size < 0 ? errno : 0; -@@ -171,7 +183,9 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) - break; - - /* The buffer was too small. Find how large it should have been. */ -- ssize_t size = lsxattr (name, NULL, 0); -+ ssize_t size = (fd < 0 -+ ? lsxattr (name, NULL, 0) -+ : flistxattr (fd, NULL, 0)); - if (size <= 0) - { - ai->size = size; -@@ -214,9 +228,13 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) - { - if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SMACK)) - { -- ssize_t r = smack_new_label_from_path (name, "security.SMACK64", -- flags & ACL_SYMLINK_FOLLOW, -- &ai->scontext); -+ static char const SMACK64[] = "security.SMACK64"; -+ ssize_t r = -+ (fd < 0 -+ ? smack_new_label_from_path (name, SMACK64, -+ flags & ACL_SYMLINK_FOLLOW, -+ &ai->scontext) -+ : smack_new_label_from_file (fd, SMACK64, &ai->scontext)); - scontext_err = r < 0 ? errno : 0; - } - } -@@ -226,8 +244,10 @@ get_aclinfo (char const *name, struct aclinfo *ai, int flags) - if (ai->size < 0 || aclinfo_has_xattr (ai, XATTR_NAME_SELINUX)) - { - ssize_t r = -- ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) -- (name, &ai->scontext)); -+ (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW ? getfilecon : lgetfilecon) -+ (name, &ai->scontext)) -+ : fgetfilecon (fd, &ai->scontext)); - scontext_err = r < 0 ? errno : 0; - # ifndef SE_SELINUX_INLINE - /* Gnulib's selinux-h module is not in use, so getfilecon and -@@ -362,11 +382,13 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) - } - #endif - --#if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FD \ -- && !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED \ -- && !HAVE_ACL_GET_LINK_NP) --# include --# ifdef O_PATH -+#if (!USE_LINUX_XATTR && USE_ACL && !HAVE_ACL_EXTENDED_FILE \ -+ && !HAVE_ACL_TYPE_EXTENDED) -+ -+# if HAVE_ACL_GET_FD && !HAVE_ACL_GET_LINK_NP -+# include -+# ifdef O_PATH -+# define acl_get_fd_np(fd, type) acl_get_fd (fd) - - /* Like acl_get_file, but do not follow symbolic links. */ - static acl_t -@@ -381,8 +403,24 @@ acl_get_link_np (char const *name, acl_type_t type) - errno = err; - return r; - } --# define HAVE_ACL_GET_LINK_NP 1 -+# define HAVE_ACL_GET_LINK_NP 1 -+# endif - # endif -+ -+static acl_t -+acl_get_fdfile (int fd, char const *name, acl_type_t type, int flags) -+{ -+ acl_t (*get) (char const *, acl_type_t) = acl_get_file; -+# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ -+ if (0 <= fd) -+ return acl_get_fd_np (fd, type); -+ if (! (flags & ACL_SYMLINK_FOLLOW)) -+ get = acl_get_link_np; -+# else -+ /* Ignore FD and FLAGS, unfortunately. */ -+# endif -+ return get (name, type); -+} - #endif - - /* Return 1 if NAME has a nontrivial access control list, -@@ -398,14 +436,35 @@ acl_get_link_np (char const *name, acl_type_t type) - If the d_type value is not known, use DT_UNKNOWN though this may be less - efficient. */ - int --file_has_aclinfo (MAYBE_UNUSED char const *restrict name, -+file_has_aclinfo (char const *restrict name, - struct aclinfo *restrict ai, int flags) -+{ -+ return fdfile_has_aclinfo (-1, name, ai, flags); -+} -+ -+/* Return 1 if FD aka NAME has a nontrivial access control list, -+ 0 if ACLs are not supported, or if NAME has no or only a base ACL, -+ and -1 (setting errno) on error. Note callers can determine -+ if ACLs are not supported as errno is set in that case also. -+ Ignore FD if it is negative. -+ Set *AI to ACL info regardless of return value. -+ FLAGS should be a d_type value, optionally ORed with -+ - _GL_DT_NOTDIR if it is known that NAME is not a directory, -+ - ACL_GET_SCONTEXT to retrieve security context and return 1 if present, -+ - ACL_SYMLINK_FOLLOW to follow the link if NAME is a symbolic link; -+ otherwise do not follow them if possible. -+ If the d_type value is not known, use DT_UNKNOWN though this may be less -+ efficient. */ -+int -+fdfile_has_aclinfo (MAYBE_UNUSED int fd, -+ MAYBE_UNUSED char const *restrict name, -+ struct aclinfo *restrict ai, int flags) - { - MAYBE_UNUSED unsigned char d_type = flags & UCHAR_MAX; - - #if USE_LINUX_XATTR - int initial_errno = errno; -- get_aclinfo (name, ai, flags); -+ get_aclinfo (fd, name, ai, flags); - - if (!aclinfo_may_indicate_xattr (ai) && ai->size <= 0) - { -@@ -418,11 +477,11 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - In earlier Fedora the two types of ACLs were mutually exclusive. - Attempt to work correctly on both kinds of systems. */ - -- if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, name, flags)) -+ if (!has_xattr (XATTR_NAME_NFSV4_ACL, ai, fd, name, flags)) - return -- (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, name, flags) -+ (has_xattr (XATTR_NAME_POSIX_ACL_ACCESS, ai, fd, name, flags) - || ((d_type == DT_DIR || d_type == DT_UNKNOWN) -- && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, name, flags))); -+ && has_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, ai, fd, name, flags))); - - /* A buffer large enough to hold any trivial NFSv4 ACL. - The max length of a trivial NFSv4 ACL is 6 words for owner, -@@ -432,8 +491,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - everyone is another word to hold "EVERYONE@". */ - uint32_t buf[2 * (6 + 6 + 7)]; - -- int ret = ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) -- (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)); -+ int ret = (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW ? getxattr : lgetxattr) -+ (name, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)) -+ : fgetxattr (fd, XATTR_NAME_NFSV4_ACL, buf, sizeof buf)); - if (ret < 0) - switch (errno) - { -@@ -467,20 +528,23 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - /* On Linux, acl_extended_file is an optimized function: It only - makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for - ACL_TYPE_DEFAULT. */ -- ret = ((flags & ACL_SYMLINK_FOLLOW -- ? acl_extended_file -- : acl_extended_file_nofollow) -- (name)); -+ ret = (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW -+ ? acl_extended_file -+ : acl_extended_file_nofollow) -+ (name)) -+ : acl_extended_fd (fd)); - # elif HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ - /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS) - and acl_get_file (name, ACL_TYPE_DEFAULT) - always return NULL / EINVAL. There is no point in making - these two useless calls. The real ACL is retrieved through -- acl_get_file (name, ACL_TYPE_EXTENDED). */ -- acl_t acl = ((flags & ACL_SYMLINK_FOLLOW -- ? acl_get_file -- : acl_get_link_np) -- (name, ACL_TYPE_EXTENDED)); -+ ACL_TYPE_EXTENDED. */ -+ acl_t acl = -+ (fd < 0 -+ ? ((flags & ACL_SYMLINK_FOLLOW ? acl_get_file : acl_get_link_np) -+ (name, ACL_TYPE_EXTENDED)) -+ : acl_get_fd_np (fd, ACL_TYPE_EXTENDED)); - if (acl) - { - ret = acl_extended_nontrivial (acl); -@@ -489,13 +553,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - else - ret = -1; - # else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ -- acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file; --# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ -- if (! (flags & ACL_SYMLINK_FOLLOW)) -- acl_get_file_or_link = acl_get_link_np; --# endif - -- acl_t acl = acl_get_file_or_link (name, ACL_TYPE_ACCESS); -+ acl_t acl = acl_get_fdfile (fd, name, ACL_TYPE_ACCESS, flags); - if (acl) - { - ret = acl_access_nontrivial (acl); -@@ -517,7 +576,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - && (d_type == DT_DIR - || (d_type == DT_UNKNOWN && !(flags & _GL_DT_NOTDIR)))) - { -- acl = acl_get_file_or_link (name, ACL_TYPE_DEFAULT); -+ acl = acl_get_fdfile (fd, name, ACL_TYPE_DEFAULT, flags); - if (acl) - { - # ifdef __CYGWIN__ /* Cygwin >= 2.5 */ -@@ -562,7 +621,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - - /* Solaris 10 (newer version), which has additional API declared in - (acl_t) and implemented in libsec (acl_set, acl_trivial, -- acl_fromtext, ...). */ -+ acl_fromtext, ...). -+ -+ Ignore FD, unfortunately. That is better than mishandling -+ ZFS-style ACLs, as the general case code does. */ - return acl_trivial (name); - - # else /* Solaris, Cygwin, general case */ -@@ -586,7 +648,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - - for (;;) - { -- count = acl (name, GETACL, alloc, entries); -+ count = (fd < 0 -+ ? acl (name, GETACL, alloc, entries) -+ : facl (fd, GETACL, alloc, entries)); - if (count < 0 && errno == ENOSPC) - { - /* Increase the size of the buffer. */ -@@ -657,7 +721,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - - for (;;) - { -- count = acl (name, ACE_GETACL, alloc, entries); -+ count = (fd < 0 -+ ? acl (name, ACE_GETACL, alloc, entries) -+ : facl (fd, ACE_GETACL, alloc, entries)); - if (count < 0 && errno == ENOSPC) - { - /* Increase the size of the buffer. */ -@@ -722,7 +788,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - struct acl_entry entries[NACLENTRIES]; - int count; - -- count = getacl (name, NACLENTRIES, entries); -+ count = (fd < 0 -+ ? getacl (name, NACLENTRIES, entries) -+ : fgetacl (fd, NACLENTRIES, entries)); - - if (count < 0) - { -@@ -751,7 +819,8 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - { - struct stat statbuf; - -- if (stat (name, &statbuf) == -1 && errno != EOVERFLOW) -+ if ((fd < 0 ? stat (name, &statbuf) : fstat (fd, &statbuf)) < 0 -+ && errno != EOVERFLOW) - return -1; - - return acl_nontrivial (count, entries); -@@ -765,6 +834,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - struct acl entries[NACLVENTRIES]; - int count; - -+ /* Ignore FD, unfortunately. */ - count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries); - - if (count < 0) -@@ -809,7 +879,9 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - /* The docs say that type being 0 is equivalent to ACL_ANY, but it - is not true, in AIX 5.3. */ - type.u64 = ACL_ANY; -- if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0) -+ if (0 <= (fd < 0 -+ ? aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) -+ : aclx_fget (fd, 0, &type, aclbuf, &aclsize, &mode))) - break; - if (errno == ENOSYS) - return 0; -@@ -855,7 +927,10 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - - union { struct acl a; char room[4096]; } u; - -- if (statacl ((char *) name, STX_NORMAL, &u.a, sizeof (u)) < 0) -+ if ((fd < 0 -+ ? statacl ((char *) name, STX_NORMAL, &u.a, sizeof u) -+ : fstatacl (fd, STX_NORMAL, &u.a, sizeof u)) -+ < 0) - return -1; - - return acl_nontrivial (&u.a); -@@ -866,6 +941,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, - struct acl entries[NACLENTRIES]; - int count; - -+ /* Ignore FD, unfortunately. */ - count = acl ((char *) name, ACL_GET, NACLENTRIES, entries); - - if (count < 0) -diff --git a/lib/qcopy-acl.c b/lib/qcopy-acl.c -index ad79661..282f4b2 100644 ---- a/lib/qcopy-acl.c -+++ b/lib/qcopy-acl.c -@@ -26,6 +26,7 @@ - #if USE_XATTR - - # include -+# include - # include - - # if HAVE_LINUX_XATTR_H -@@ -61,6 +62,7 @@ is_attr_permissions (const char *name, struct error_context *ctx) - a valid file descriptor, use file descriptor operations, else use - filename based operations on SRC_NAME. Likewise for DEST_DESC and - DST_NAME. -+ MODE should be the source file's st_mode. - If access control lists are not available, fchmod the target file to - MODE. Also sets the non-permission bits of the destination file - (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set. -@@ -86,10 +88,29 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, - Functions attr_copy_* return 0 in case we copied something OR nothing - to copy */ - if (ret == 0) -- ret = source_desc <= 0 || dest_desc <= 0 -- ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) -- : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, -- is_attr_permissions, NULL); -+ { -+ ret = source_desc <= 0 || dest_desc <= 0 -+ ? attr_copy_file (src_name, dst_name, is_attr_permissions, NULL) -+ : attr_copy_fd (src_name, source_desc, dst_name, dest_desc, -+ is_attr_permissions, NULL); -+ -+ /* Copying can fail with EOPNOTSUPP even when the source -+ permissions are trivial (Bug#78328). Don't report an error -+ in this case, as the chmod_or_fchmod suffices. */ -+ if (ret < 0 && errno == EOPNOTSUPP) -+ { -+ /* fdfile_has_aclinfo cares only about DT_DIR, _GL_DT_NOTDIR, -+ and DT_LNK (but DT_LNK is not possible here), -+ so use _GL_DT_NOTDIR | DT_UNKNOWN for other file types. */ -+ int flags = S_ISDIR (mode) ? DT_DIR : _GL_DT_NOTDIR | DT_UNKNOWN; -+ -+ struct aclinfo ai; -+ if (!fdfile_has_aclinfo (source_desc, src_name, &ai, flags)) -+ ret = 0; -+ aclinfo_free (&ai); -+ errno = EOPNOTSUPP; -+ } -+ } - #else - /* no XATTR, so we proceed the old dusty way */ - struct permission_context ctx; --- -2.49.0 - - -From ed2bda5888829f4ebacd6dc9c86b7494dbf2a3b7 Mon Sep 17 00:00:00 2001 -From: Paul Eggert -Date: Fri, 9 May 2025 18:48:03 -0700 -Subject: [PATCH 2/2] acl-tests: link with $(FILE_HAS_ACL_LIB) - -* modules/acl-tests (test_copy_acl_LDADD): Add -$(FILE_HAS_ACL_LIB), since qcopy-acl depends on file-has-acl. -Although this suggests that QCOPY_ACL_LIB should contain -FILE_HAS_ACL_LIB, I’m not sure whether that’s the right course of -action and anyway this is good enough for coreutils. - -(cherry picked from commit 955360a66c99bdd9ac3688519a8b521b06958fd3) ---- - gnulib-tests/gnulib.mk | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gnulib-tests/gnulib.mk b/gnulib-tests/gnulib.mk -index e222c63..4b78de4 100644 ---- a/gnulib-tests/gnulib.mk -+++ b/gnulib-tests/gnulib.mk -@@ -99,7 +99,7 @@ TESTS += \ - TESTS_ENVIRONMENT += USE_ACL=$(USE_ACL) - check_PROGRAMS += test-set-mode-acl test-copy-acl test-sameacls - test_set_mode_acl_LDADD = $(LDADD) $(LIB_ACL) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) --test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) -+test_copy_acl_LDADD = $(LDADD) $(LIB_ACL) $(QCOPY_ACL_LIB) $(FILE_HAS_ACL_LIB) $(LIBUNISTRING) @LIBINTL@ $(MBRTOWC_LIB) $(LIBC32CONV) - test_sameacls_LDADD = $(LDADD) $(LIB_ACL) @LIBINTL@ $(MBRTOWC_LIB) - EXTRA_DIST += test-set-mode-acl.sh test-set-mode-acl-1.sh test-set-mode-acl-2.sh test-copy-acl.sh test-copy-acl-1.sh test-copy-acl-2.sh test-set-mode-acl.c test-copy-acl.c test-sameacls.c macros.h - --- -2.49.0 - diff --git a/coreutils-9.7-stty-arbitrary-baud-rates.patch b/coreutils-9.7-stty-arbitrary-baud-rates.patch deleted file mode 100644 index 20d078b..0000000 --- a/coreutils-9.7-stty-arbitrary-baud-rates.patch +++ /dev/null @@ -1,669 +0,0 @@ -From 8e5ee22042931bdac6488d61c5d59bcd1b0dba5f Mon Sep 17 00:00:00 2001 -From: "H. Peter Anvin" -Date: Mon, 16 Jun 2025 14:58:01 -0700 -Subject: [PATCH 1/5] stty: arbitrary or non-a priori known speed_t support - -Support the case where speed_t is simply a number, and in that case -assume that arbitrary values can be passed. This is assumed to be the -case when all known speed_t macros equal their own value. - -Try to probe for a variety of speed_t constants by trying to coax -$(CC) into emitting macro definitions (-E -dM). If this is not -supported, use a fairly extensive list of constants as a -fallback. This both improves the test for arbitrary speed support, as -well as allowing proper operation in the case where the constants are -not plain numbers and allows for handing enumerated speed constants -that were not known a priori when the source code was written. - -A simple shell script (mostly using sed) is used to turn the list of -constants (probed and predefined) into a pair of conversion functions, -baud_to_value() and value_to_baud(); string_to_baud() is then -reimplemented as a wrapper around the latter. - -* src/local.mk: Generate speedlist.h. -* src/speedgen: Portable shell script to generate speedlist.h. -* src/stty.c: Adjust string_to_baud to -convert from arbitrary numeric values. -* src/termios.c: A helper used when generating speedlist.h - -@lzaoral: This patch was amended to fix build failure in the -"single-binary" mode. - -(cherry picked from commit 357fda90d15fd3f7dba61e1ab322b183a48d0081) ---- - src/local.mk | 15 +++++- - src/speedgen | 85 ++++++++++++++++++++++++++++++ - src/stty.c | 143 +++++++++++++++++++------------------------------- - src/termios.c | 34 ++++++++++++ - 4 files changed, 188 insertions(+), 89 deletions(-) - create mode 100755 src/speedgen - create mode 100644 src/termios.c - -diff --git a/src/local.mk b/src/local.mk -index fd9dc81..3b8a34e 100644 ---- a/src/local.mk -+++ b/src/local.mk -@@ -71,7 +71,8 @@ EXTRA_DIST += \ - src/dircolors.hin \ - src/primes.h \ - src/tac-pipe.c \ -- src/extract-magic -+ src/extract-magic \ -+ src/speedgen - - CLEANFILES += $(SCRIPTS) - -@@ -672,6 +673,18 @@ src/version.h: Makefile - $(AM_V_at)chmod a-w $@t - $(AM_V_at)mv $@t $@ - -+# Target-specific termios baud rate file. This is opportunistic; -+# if cc -E doesn't support -dM, the speedgen script still includes -+# an extensive fallback list of common constants. -+BUILT_SOURCES += src/speedlist.h -+src/speedlist.h: src/termios.c lib/config.h src/speedgen -+ $(AM_V_GEN)rm -f $@ -+ $(AM_V_at)${MKDIR_P} src -+ $(AM_V_at)$(COMPILE) -E -dM $< 2>/dev/null | \ -+ $(SHELL) $(srcdir)/src/speedgen $@t -+ $(AM_V_at)chmod a-w $@t -+ $(AM_V_at)mv $@t $@ -+ - # Generates a list of macro invocations like: - # SINGLE_BINARY_PROGRAM(program_name_str, main_name) - # once for each program list on $(single_binary_progs). Note that -diff --git a/src/speedgen b/src/speedgen -new file mode 100755 -index 0000000..f1647d9 ---- /dev/null -+++ b/src/speedgen -@@ -0,0 +1,85 @@ -+#!/bin/sh -e -+ -+out="$1" -+tmp="$out.tmp" -+ -+if [ -z "$out" ]; then -+ echo "Usage: $0 outfile" 2>&1 -+ exit 1 -+fi -+ -+s='[[:space:]]' # For brevity's sake -+ -+trap "rm -f '$tmp'" EXIT -+trap "rm -f '$tmp' '$out'" ERR HUP INT QUIT TERM -+ -+# Fallback list of speeds that are always tested for -+defspeeds="0 50 75 110 134 150 200 300 600 1200 1800 2400 4800 7200 9600 \ -+14400 19200 28800 33600 38400 57600 76800 115200 153600 230400 307200 \ -+460800 500000 576000 614400 921600 1000000 1152000 1500000 \ -+2000000 2500000 3000000 3500000 4000000 5000000 10000000" -+( -+ sed -n -e "s/^$s*\#$s*define$s$s*B\\([1-9][0-9]*\\)$s.*\$/\\1/p" -+ for s in $defspeeds; do echo "$s"; done -+) | sort -n | uniq > "$tmp" -+ -+cat > "$out" <<'EOF' -+#ifndef SPEEDLIST_H -+# define SPEEDLIST_H 1 -+ -+# if 1 \ -+EOF -+ -+sed -e 's/^.*$/ \&\& (!defined(B&) || B& == &) \\/' < "$tmp" >> "$out" -+ -+cat >> "$out" <<'EOF' -+ -+# define TERMIOS_SPEED_T_SANE 1 -+ -+# endif -+ -+ATTRIBUTE_CONST -+static unsigned long int -+baud_to_value (speed_t speed) -+{ -+# ifdef TERMIOS_SPEED_T_SANE -+ return speed; -+# else -+ switch (speed) -+ { -+EOF -+ -+sed -e 's/^.*$/# ifdef B&\n case B&: return &;\n# endif/' \ -+ < "$tmp" >> "$out" -+ -+cat >> "$out" <<'EOF' -+ default: return -1; -+ } -+# endif -+} -+ -+ATTRIBUTE_CONST -+static speed_t -+value_to_baud (unsigned long int value) -+{ -+# ifdef TERMIOS_SPEED_T_SANE -+ speed_t speed = value; -+ if (speed != value) -+ speed = (speed_t) -1; /* Unrepresentable (overflow?) */ -+ return speed; -+# else -+ switch (value) -+ { -+EOF -+ -+sed -e 's/^.*$/# ifdef B&\n case &: return B&;\n# endif/' \ -+ < "$tmp" >> "$out" -+ -+cat >> "$out" <<'EOF' -+ default: return (speed_t) -1; -+ } -+# endif -+} -+ -+#endif -+EOF -diff --git a/src/stty.c b/src/stty.c -index 133b33c..561de1c 100644 ---- a/src/stty.c -+++ b/src/stty.c -@@ -55,6 +55,7 @@ - - #include "system.h" - #include "assure.h" -+#include "c-ctype.h" - #include "fd-reopen.h" - #include "quote.h" - #include "xdectoint.h" -@@ -2172,100 +2173,66 @@ recover_mode (char const *arg, struct termios *mode) - return true; - } - --struct speed_map --{ -- char const *string; /* ASCII representation. */ -- speed_t speed; /* Internal form. */ -- unsigned long int value; /* Numeric value. */ --}; -- --static struct speed_map const speeds[] = --{ -- {"0", B0, 0}, -- {"50", B50, 50}, -- {"75", B75, 75}, -- {"110", B110, 110}, -- {"134", B134, 134}, -- {"134.5", B134, 134}, -- {"150", B150, 150}, -- {"200", B200, 200}, -- {"300", B300, 300}, -- {"600", B600, 600}, -- {"1200", B1200, 1200}, -- {"1800", B1800, 1800}, -- {"2400", B2400, 2400}, -- {"4800", B4800, 4800}, -- {"9600", B9600, 9600}, -- {"19200", B19200, 19200}, -- {"38400", B38400, 38400}, -- {"exta", B19200, 19200}, -- {"extb", B38400, 38400}, --#ifdef B57600 -- {"57600", B57600, 57600}, --#endif --#ifdef B115200 -- {"115200", B115200, 115200}, --#endif --#ifdef B230400 -- {"230400", B230400, 230400}, --#endif --#ifdef B460800 -- {"460800", B460800, 460800}, --#endif --#ifdef B500000 -- {"500000", B500000, 500000}, --#endif --#ifdef B576000 -- {"576000", B576000, 576000}, --#endif --#ifdef B921600 -- {"921600", B921600, 921600}, --#endif --#ifdef B1000000 -- {"1000000", B1000000, 1000000}, --#endif --#ifdef B1152000 -- {"1152000", B1152000, 1152000}, --#endif --#ifdef B1500000 -- {"1500000", B1500000, 1500000}, --#endif --#ifdef B2000000 -- {"2000000", B2000000, 2000000}, --#endif --#ifdef B2500000 -- {"2500000", B2500000, 2500000}, --#endif --#ifdef B3000000 -- {"3000000", B3000000, 3000000}, --#endif --#ifdef B3500000 -- {"3500000", B3500000, 3500000}, --#endif --#ifdef B4000000 -- {"4000000", B4000000, 4000000}, --#endif -- {nullptr, 0, 0} --}; -+/* Autogenerated conversion functions to/from speed_t */ -+#include "speedlist.h" - - ATTRIBUTE_PURE - static speed_t - string_to_baud (char const *arg) - { -- for (int i = 0; speeds[i].string != nullptr; ++i) -- if (STREQ (arg, speeds[i].string)) -- return speeds[i].speed; -- return (speed_t) -1; --} -+ char *ep; -+ unsigned long value; -+ unsigned char c; - --ATTRIBUTE_PURE --static unsigned long int --baud_to_value (speed_t speed) --{ -- for (int i = 0; speeds[i].string != nullptr; ++i) -- if (speed == speeds[i].speed) -- return speeds[i].value; -- return 0; -+ /* Explicitly disallow negative numbers. */ -+ while (c_isspace (*arg)) -+ arg++; -+ if (*arg == '-') -+ return (speed_t) -1; -+ -+ value = strtoul (arg, &ep, 10); -+ -+ c = *ep++; -+ if (c == '.') -+ { -+ /* Number includes a fraction. Round it to nearest-even. -+ Note in particular that 134.5 must round to 134! */ -+ c = *ep++; -+ if (c) -+ { -+ c -= '0'; -+ if (c > 9) -+ { -+ return (speed_t) -1; /* Garbage after otherwise valid number */ -+ } -+ else if (c > 5) -+ { -+ value++; -+ } -+ else if (c == 5) -+ { -+ while ((c = *ep++) == '0') -+ ; /* Skip zeroes after .5 */ -+ -+ if (c >= '1' && c <= '9') -+ value++; /* Nonzero digit, round up */ -+ else -+ value += (value & 1); /* Exactly in the middle, round even */ -+ } -+ } -+ } -+ else if (c) -+ { -+ /* Not a valid number; check for legacy aliases "exta" and "extb" */ -+ if (STREQ (arg, "exta")) -+ return B19200; -+ else if (STREQ (arg, "extb")) -+ return B38400; -+ else -+ return (speed_t) -1; -+ } -+ -+ return value_to_baud (value); - } - - static void -diff --git a/src/termios.c b/src/termios.c -new file mode 100644 -index 0000000..f17e12e ---- /dev/null -+++ b/src/termios.c -@@ -0,0 +1,34 @@ -+/* termios.c -- coax out Bxxx macros from termios.h -+ -+ Copyright (C) 2025 Free Software Foundation, Inc. -+ -+ This program is free software: you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation, either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . */ -+ -+/* This simply #includes headers which may or may not provide Bxxx -+ constant macros. This is run through the C preprocessor and defined -+ macros are extracted. -+ -+ In the case where the C preprocessor isn't capable of doing so, -+ the script this is fed through contains a pre-defined set of common -+ constants. */ -+ -+#include -+ -+#ifdef TERMIOS_NEEDS_XOPEN_SOURCE -+# define _XOPEN_SOURCE -+#endif -+ -+#include -+#include -+#include --- -2.50.0 - - -From 60c9206391e2fac32639d3a143435d1dd9ec6421 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Tue, 17 Jun 2025 23:32:05 +0100 -Subject: [PATCH 2/5] tests: stty: adjust tests for arbitary speeds - -* tests/stty/stty-invalid.sh: Adjust to what is now invalid. -* tests/stty/stty.sh: Add checks for valid speed variants. -* tests/stty/bad-speed.sh: New test to ensure unsupported speeds -are diagnosed. - -(cherry picked from commit efaec8078142996d958b6720b85a13b12497c3d0) ---- - tests/local.mk | 1 + - tests/stty/bad-speed.sh | 50 ++++++++++++++++++++++++++++++++++++++ - tests/stty/stty-invalid.sh | 10 ++++++-- - tests/stty/stty.sh | 10 ++++++++ - 4 files changed, 69 insertions(+), 2 deletions(-) - create mode 100755 tests/stty/bad-speed.sh - -diff --git a/tests/local.mk b/tests/local.mk -index 642d225..b68df41 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -425,6 +425,7 @@ all_tests = \ - tests/stat/stat-printf.pl \ - tests/stat/stat-slash.sh \ - tests/misc/stdbuf.sh \ -+ tests/stty/bad-speed.sh \ - tests/stty/stty.sh \ - tests/stty/stty-invalid.sh \ - tests/stty/stty-pairs.sh \ -diff --git a/tests/stty/bad-speed.sh b/tests/stty/bad-speed.sh -new file mode 100755 -index 0000000..d80d2e7 ---- /dev/null -+++ b/tests/stty/bad-speed.sh -@@ -0,0 +1,50 @@ -+#!/bin/sh -+# Ensure we handle cfsetispeed failing -+# which we did not before coreutils v9.1 -+ -+# Copyright (C) 2025 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ stty -+require_gcc_shared_ -+ -+# Replace each cfsetispeed call with a call to these stubs. -+cat > k.c <<'EOF' || framework_failure_ -+#include -+#include -+#include -+#include -+ -+int cfsetispeed(struct termios *termios_p, speed_t speed) -+{ -+ /* Leave a marker so we can identify if the function was intercepted. */ -+ fclose(fopen("preloaded", "w")); -+ -+ errno=EINVAL; -+ return -1; -+} -+EOF -+ -+# Then compile/link it: -+gcc_shared_ k.c k.so \ -+ || skip_ 'failed to build shared library' -+ -+( export LD_PRELOAD=$LD_PRELOAD:./k.so -+ returns_ 1 stty ispeed 9600 ) || fail=1 -+ -+test -e preloaded || skip_ 'LD_PRELOAD interception failed' -+ -+Exit $fail -diff --git a/tests/stty/stty-invalid.sh b/tests/stty/stty-invalid.sh -index 4b87e2a..a1442a8 100755 ---- a/tests/stty/stty-invalid.sh -+++ b/tests/stty/stty-invalid.sh -@@ -20,6 +20,7 @@ - print_ver_ stty - require_controlling_input_terminal_ - require_trap_signame_ -+getlimits_ - - trap '' TTOU # Ignore SIGTTOU - -@@ -50,8 +51,13 @@ if tty -s = 9.8 supports arbitrary speeds on some systems -+# so restrict tests here to invalid numbers -+# We simulate unsupported numbers in a separate "LD_PRELOAD" test. -+WRAP_9600="$(expr $ULONG_OFLOW - 9600)" -+for speed in 9600.. ++9600 -$WRAP_9600 --$WRAP_9600 0x2580 96E2; do -+ returns_ 1 stty ispeed "$speed" || fail=1 -+done - - # Just in case either of the above mistakenly succeeds (and changes - # the state of our tty), try to restore the initial state. -diff --git a/tests/stty/stty.sh b/tests/stty/stty.sh -index dab4cd0..c0f7494 100755 ---- a/tests/stty/stty.sh -+++ b/tests/stty/stty.sh -@@ -95,4 +95,14 @@ for W in $(seq 80 90); do - test "$output_width" -le "$W" || fail=1 - done - -+# Ensure we support varied numeric forms -+# with appropriate rounding -+if stty ispeed '9600'; then -+ stty ispeed ' +9600' || fail=1 -+ stty ispeed '9600.49' || fail=1 -+ stty ispeed '9600.50' || fail=1 -+ stty ispeed '9599.51' || fail=1 -+ stty ispeed ' 9600.' || fail=1 -+fi -+ - Exit $fail --- -2.50.0 - - -From a47c15eea3ffe08662415ae13873b40c7ffcdb43 Mon Sep 17 00:00:00 2001 -From: Collin Funk -Date: Sat, 21 Jun 2025 22:05:19 -0700 -Subject: [PATCH 3/5] build: add src/termios.c to the tarball - -* src/local.mk (EXTRA_DIST): Add src/termios.c. - -(cherry picked from commit b7db7757831e93ca44ae59e1921bc4ebbc87974f) ---- - src/local.mk | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/local.mk b/src/local.mk -index 3b8a34e..188dda1 100644 ---- a/src/local.mk -+++ b/src/local.mk -@@ -72,7 +72,8 @@ EXTRA_DIST += \ - src/primes.h \ - src/tac-pipe.c \ - src/extract-magic \ -- src/speedgen -+ src/speedgen \ -+ src/termios.c - - CLEANFILES += $(SCRIPTS) - --- -2.50.0 - - -From caa439bf750193bcbed215a6676053f0b3c96e21 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sun, 22 Jun 2025 15:01:21 +0100 -Subject: [PATCH 4/5] doc: stty: adjust description of supported speeds - -* doc/coreutils.texi (stty invocation): Remove now imprecise -list of speeds given we may now support higher or arbitrary speeds. -Mention that we may support higher or arbitrary speeds. - -(cherry picked from commit 8b05eca972f70858749a946ac24f08d0718c1be6) ---- - doc/coreutils.texi | 21 ++------------------- - 1 file changed, 2 insertions(+), 19 deletions(-) - -diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 6d1ee11..c04af2b 100644 ---- a/doc/coreutils.texi -+++ b/doc/coreutils.texi -@@ -15932,25 +15932,8 @@ Print the terminal speed. - Set the input and output speeds to @var{n}. @var{n} can be one of: 0 - 50 75 110 134 134.5 150 200 300 600 1200 1800 2400 4800 9600 19200 - 38400 @code{exta} @code{extb}. @code{exta} is the same as 19200; --@code{extb} is the same as 38400. Many systems, including GNU/Linux, --support higher speeds. The @command{stty} command includes support --for speeds of --57600, --115200, --230400, --460800, --500000, --576000, --921600, --1000000, --1152000, --1500000, --2000000, --2500000, --3000000, --3500000, --or --4000000 where the system supports these. -+@code{extb} is the same as 38400. Many systems, support arbitrary -+or higher speeds. - 0 hangs up the line if @option{-clocal} is set. - @end table - --- -2.50.0 - - -From 8e48d56c2aa10f9875ffe1ec051a17f0eab6d2f9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?P=C3=A1draig=20Brady?= -Date: Sun, 22 Jun 2025 16:40:04 +0100 -Subject: [PATCH 5/5] stty: stricter floating point parsing - -* src/stty.c (string_to_baud): Disallow extraneous characters -after floating point numbers. -* tests/stty/stty-invalid.sh: Add test cases. - -(cherry picked from commit 3d35b3c0e56bd556c90dc98c3e5e2e7289b0eb0d) ---- - src/stty.c | 27 +++++++++++++-------------- - tests/stty/stty-invalid.sh | 3 ++- - 2 files changed, 15 insertions(+), 15 deletions(-) - -diff --git a/src/stty.c b/src/stty.c -index 561de1c..0163ea4 100644 ---- a/src/stty.c -+++ b/src/stty.c -@@ -2200,25 +2200,24 @@ string_to_baud (char const *arg) - c = *ep++; - if (c) - { -- c -= '0'; -- if (c > 9) -+ unsigned char d = c - '0'; -+ if (d > 5) -+ value++; -+ else if (d == 5) - { -- return (speed_t) -1; /* Garbage after otherwise valid number */ -- } -- else if (c > 5) -- { -- value++; -- } -- else if (c == 5) -- { -- while ((c = *ep++) == '0') -- ; /* Skip zeroes after .5 */ -+ while ((c = *ep++) == '0'); /* Skip zeroes after .5 */ - -- if (c >= '1' && c <= '9') -- value++; /* Nonzero digit, round up */ -+ if (c) -+ value++; /* Nonzero, round up */ - else - value += (value & 1); /* Exactly in the middle, round even */ - } -+ -+ while (c_isdigit (c)) /* Skip remaining digits. */ -+ c = *ep++; -+ -+ if (c) -+ return (speed_t) -1; /* Garbage after otherwise valid number */ - } - } - else if (c) -diff --git a/tests/stty/stty-invalid.sh b/tests/stty/stty-invalid.sh -index a1442a8..868ed1d 100755 ---- a/tests/stty/stty-invalid.sh -+++ b/tests/stty/stty-invalid.sh -@@ -55,7 +55,8 @@ fi - # so restrict tests here to invalid numbers - # We simulate unsupported numbers in a separate "LD_PRELOAD" test. - WRAP_9600="$(expr $ULONG_OFLOW - 9600)" --for speed in 9600.. ++9600 -$WRAP_9600 --$WRAP_9600 0x2580 96E2; do -+for speed in 9599.. 9600.. 9600.5. 9600.50. 9600.0. ++9600 \ -+ -$WRAP_9600 --$WRAP_9600 0x2580 96E2 9600,0 '9600.0 '; do - returns_ 1 stty ispeed "$speed" || fail=1 - done - --- -2.50.0 - diff --git a/coreutils-CVE-2025-5278.patch b/coreutils-CVE-2025-5278.patch deleted file mode 100644 index af81286..0000000 --- a/coreutils-CVE-2025-5278.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 701a9bdbf78f869e0fb778ed5aede00e42517add Mon Sep 17 00:00:00 2001 -From: Pádraig Brady -Date: Tue, 20 May 2025 16:03:44 +0100 -Subject: [PATCH] sort: fix buffer under-read (CWE-127) - -* src/sort.c (begfield): Check pointer adjustment -to avoid Out-of-range pointer offset (CWE-823). -(limfield): Likewise. -* tests/sort/sort-field-limit.sh: Add a new test, -which triggers with ASAN or Valgrind. -* tests/local.mk: Reference the new test. -Fixes https://bugs.gnu.org/78507 - -(cherry picked from commit 8c9602e3a145e9596dc1a63c6ed67865814b6633) ---- - src/sort.c | 12 ++++++++++-- - tests/local.mk | 1 + - tests/sort/sort-field-limit.sh | 35 ++++++++++++++++++++++++++++++++++ - 3 files changed, 46 insertions(+), 2 deletions(-) - create mode 100755 tests/sort/sort-field-limit.sh - -diff --git a/src/sort.c b/src/sort.c -index b10183b..7af1a25 100644 ---- a/src/sort.c -+++ b/src/sort.c -@@ -1644,7 +1644,11 @@ begfield (struct line const *line, struct keyfield const *key) - ++ptr; - - /* Advance PTR by SCHAR (if possible), but no further than LIM. */ -- ptr = MIN (lim, ptr + schar); -+ size_t remaining_bytes = lim - ptr; -+ if (schar < remaining_bytes) -+ ptr += schar; -+ else -+ ptr = lim; - - return ptr; - } -@@ -1746,7 +1750,11 @@ limfield (struct line const *line, struct keyfield const *key) - ++ptr; - - /* Advance PTR by ECHAR (if possible), but no further than LIM. */ -- ptr = MIN (lim, ptr + echar); -+ size_t remaining_bytes = lim - ptr; -+ if (echar < remaining_bytes) -+ ptr += echar; -+ else -+ ptr = lim; - } - - return ptr; -diff --git a/tests/local.mk b/tests/local.mk -index 4da6756..642d225 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -388,6 +388,7 @@ all_tests = \ - tests/sort/sort-debug-keys.sh \ - tests/sort/sort-debug-warn.sh \ - tests/sort/sort-discrim.sh \ -+ tests/sort/sort-field-limit.sh \ - tests/sort/sort-files0-from.pl \ - tests/sort/sort-float.sh \ - tests/sort/sort-h-thousands-sep.sh \ -diff --git a/tests/sort/sort-field-limit.sh b/tests/sort/sort-field-limit.sh -new file mode 100755 -index 0000000..52d8e1d ---- /dev/null -+++ b/tests/sort/sort-field-limit.sh -@@ -0,0 +1,35 @@ -+#!/bin/sh -+# From 7.2-9.7, this would trigger an out of bounds mem read -+ -+# Copyright (C) 2025 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ sort -+getlimits_ -+ -+# This issue triggers with valgrind or ASAN -+valgrind --error-exitcode=1 sort --version 2>/dev/null && -+ VALGRIND='valgrind --error-exitcode=1' -+ -+{ printf '%s\n' aa bb; } > in || framework_failure_ -+ -+_POSIX2_VERSION=200809 $VALGRIND sort +0.${SIZE_MAX}R in > out || fail=1 -+compare in out || fail=1 -+ -+_POSIX2_VERSION=200809 $VALGRIND sort +1 -1.${SIZE_MAX}R in > out || fail=1 -+compare in out || fail=1 -+ -+Exit $fail --- -2.49.0 - diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index f5e3d73..2deacf7 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From d3117ae1bb422f771f1c19af54f81d5151f55065 Mon Sep 17 00:00:00 2001 +From ae768935e696a23e336601c5a239e147628ecf05 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,10 +11,10 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index d1c282f..6d1ee11 100644 +index 937d8af..11fa1d6 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12467,6 +12467,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12588,6 +12588,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -29,10 +29,10 @@ index d1c282f..6d1ee11 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index a969c5c..c465a3f 100644 +index 857f76c..07b21ea 100644 --- a/src/df.c +++ b/src/df.c -@@ -122,6 +122,9 @@ static bool print_type; +@@ -121,6 +121,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; @@ -42,7 +42,7 @@ index a969c5c..c465a3f 100644 /* Grand total data. */ static struct fs_usage grand_fsu; -@@ -249,13 +252,15 @@ enum +@@ -248,13 +251,15 @@ enum NO_SYNC_OPTION = CHAR_MAX + 1, SYNC_OPTION, TOTAL_OPTION, @@ -59,7 +59,7 @@ index a969c5c..c465a3f 100644 {"inodes", no_argument, nullptr, 'i'}, {"human-readable", no_argument, nullptr, 'h'}, {"si", no_argument, nullptr, 'H'}, -@@ -572,7 +577,10 @@ get_header (void) +@@ -571,7 +576,10 @@ get_header (void) for (idx_t col = 0; col < ncolumns; col++) { char *cell; @@ -71,7 +71,7 @@ index a969c5c..c465a3f 100644 if (columns[col]->field == SIZE_FIELD && (header_mode == DEFAULT_MODE -@@ -1454,6 +1462,17 @@ get_point (char const *point, const struct stat *statp) +@@ -1446,6 +1454,17 @@ get_point (char const *point, const struct stat *statp) static void get_entry (char const *name, struct stat const *statp) { @@ -89,7 +89,7 @@ index a969c5c..c465a3f 100644 if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && get_device (name)) return; -@@ -1524,6 +1543,7 @@ or all file systems by default.\n\ +@@ -1516,6 +1535,7 @@ or all file systems by default.\n\ -B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\ '-BM' prints sizes in units of 1,048,576 bytes;\n\ see SIZE format below\n\ @@ -97,7 +97,7 @@ index a969c5c..c465a3f 100644 -h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\ -H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\ "), stdout); -@@ -1618,6 +1638,9 @@ main (int argc, char **argv) +@@ -1610,6 +1630,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; @@ -107,7 +107,7 @@ index a969c5c..c465a3f 100644 case 'i': if (header_mode == OUTPUT_MODE) { -@@ -1714,6 +1737,13 @@ main (int argc, char **argv) +@@ -1706,6 +1729,13 @@ main (int argc, char **argv) } } @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.49.0 +2.51.0 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 2917075..92167bd 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From c0db8de625ca1ae0e0f4784c4eb2c779eae0047f Mon Sep 17 00:00:00 2001 +From c5b102c8d9ddf1cc1109858615de3a9d6d57b7e6 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -7,17 +7,13 @@ Subject: [PATCH] coreutils-i18n.patch bootstrap.conf | 2 + configure.ac | 6 + lib/linebuffer.h | 8 + - lib/mbchar.c | 23 ++ - lib/mbchar.h | 383 +++++++++++++++++ lib/mbfile.c | 20 + lib/mbfile.h | 283 +++++++++++++ - m4/mbchar.m4 | 15 + m4/mbfile.m4 | 16 + src/cut.c | 508 +++++++++++++++++++++-- src/expand-common.c | 114 ++++++ src/expand-common.h | 12 + src/expand.c | 90 +++- - src/fold.c | 311 ++++++++++++-- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- src/sort.c | 790 +++++++++++++++++++++++++++++++++--- @@ -27,19 +23,15 @@ Subject: [PATCH] coreutils-i18n.patch tests/i18n/sort.sh | 29 ++ tests/local.mk | 4 + tests/misc/expand.pl | 42 ++ - tests/misc/fold.pl | 50 ++- tests/misc/sort-mb-tests.sh | 45 ++ tests/misc/unexpand.pl | 39 ++ tests/pr/pr-tests.pl | 49 +++ tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 30 files changed, 3632 insertions(+), 195 deletions(-) - create mode 100644 lib/mbchar.c - create mode 100644 lib/mbchar.h + 25 files changed, 2878 insertions(+), 167 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h - create mode 100644 m4/mbchar.m4 create mode 100644 m4/mbfile.m4 create mode 100644 tests/expand/mb.sh create mode 100644 tests/i18n/sort.sh @@ -47,10 +39,10 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index 94c164e..cecbf26 100644 +index b8feef9..ab1eb93 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -166,6 +166,8 @@ gnulib_modules=" +@@ -169,6 +169,8 @@ gnulib_modules=" maintainer-makefile malloc-gnu manywarnings @@ -60,10 +52,10 @@ index 94c164e..cecbf26 100644 mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index 775c4cc..e6b5c9c 100644 +index 274eff4..5a1cfa5 100644 --- a/configure.ac +++ b/configure.ac -@@ -504,6 +504,12 @@ fi +@@ -465,6 +465,12 @@ fi # I'm leaving it here for now. This whole thing needs to be modernized... gl_WINSIZE_IN_PTEM @@ -102,424 +94,6 @@ index ca56f80..509b7e6 100644 }; /* Initialize linebuffer LINEBUFFER for use. */ -diff --git a/lib/mbchar.c b/lib/mbchar.c -new file mode 100644 -index 0000000..713c2f7 ---- /dev/null -+++ b/lib/mbchar.c -@@ -0,0 +1,23 @@ -+/* Copyright (C) 2001, 2006, 2009-2025 Free Software Foundation, Inc. -+ -+ This file is free software: you can redistribute it and/or modify -+ it under the terms of the GNU Lesser General Public License as -+ published by the Free Software Foundation; either version 2.1 of the -+ License, or (at your option) any later version. -+ -+ This file is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with this program. If not, see . */ -+ -+ -+#include -+ -+#define MBCHAR_INLINE _GL_EXTERN_INLINE -+ -+#include -+ -+#include "mbchar.h" -diff --git a/lib/mbchar.h b/lib/mbchar.h -new file mode 100644 -index 0000000..d77168e ---- /dev/null -+++ b/lib/mbchar.h -@@ -0,0 +1,383 @@ -+/* Multibyte character data type. -+ Copyright (C) 2001, 2005-2007, 2009-2025 Free Software Foundation, Inc. -+ -+ This file is free software: you can redistribute it and/or modify -+ it under the terms of the GNU Lesser General Public License as -+ published by the Free Software Foundation; either version 2.1 of the -+ License, or (at your option) any later version. -+ -+ This file is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with this program. If not, see . */ -+ -+/* Written by Bruno Haible . */ -+ -+/* A multibyte character is a short subsequence of a char* string, -+ representing a single 32-bit wide character. -+ -+ We use multibyte characters instead of 32-bit wide characters because -+ of the following goals: -+ 1) correct multibyte handling, i.e. operate according to the LC_CTYPE -+ locale, -+ 2) ease of maintenance, i.e. the maintainer needs not know all details -+ of the ISO C 99 standard, -+ 3) don't fail grossly if the input is not in the encoding set by the -+ locale, because often different encodings are in use in the same -+ countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...), -+ 4) fast in the case of ASCII characters. -+ -+ Multibyte characters are only accessed through the mb* macros. -+ -+ mb_ptr (mbc) -+ return a pointer to the beginning of the multibyte sequence. -+ -+ mb_len (mbc) -+ returns the number of bytes occupied by the multibyte sequence. -+ Always > 0. -+ -+ mb_iseq (mbc, sc) -+ returns true if mbc is the standard ASCII character sc. -+ -+ mb_isnul (mbc) -+ returns true if mbc is the nul character. -+ -+ mb_cmp (mbc1, mbc2) -+ returns a positive, zero, or negative value depending on whether mbc1 -+ sorts after, same or before mbc2. -+ -+ mb_casecmp (mbc1, mbc2) -+ returns a positive, zero, or negative value depending on whether mbc1 -+ sorts after, same or before mbc2, modulo upper/lowercase conversion. -+ -+ mb_equal (mbc1, mbc2) -+ returns true if mbc1 and mbc2 are equal. -+ -+ mb_caseequal (mbc1, mbc2) -+ returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion. -+ -+ mb_isalnum (mbc) -+ returns true if mbc is alphanumeric. -+ -+ mb_isalpha (mbc) -+ returns true if mbc is alphabetic. -+ -+ mb_isascii(mbc) -+ returns true if mbc is plain ASCII. -+ -+ mb_isblank (mbc) -+ returns true if mbc is a blank. -+ -+ mb_iscntrl (mbc) -+ returns true if mbc is a control character. -+ -+ mb_isdigit (mbc) -+ returns true if mbc is a decimal digit. -+ -+ mb_isgraph (mbc) -+ returns true if mbc is a graphic character. -+ -+ mb_islower (mbc) -+ returns true if mbc is lowercase. -+ -+ mb_isprint (mbc) -+ returns true if mbc is a printable character. -+ -+ mb_ispunct (mbc) -+ returns true if mbc is a punctuation character. -+ -+ mb_isspace (mbc) -+ returns true if mbc is a space character. -+ -+ mb_isupper (mbc) -+ returns true if mbc is uppercase. -+ -+ mb_isxdigit (mbc) -+ returns true if mbc is a hexadecimal digit. -+ -+ mb_width (mbc) -+ returns the number of columns on the output device occupied by mbc. -+ Always >= 0. -+ -+ mb_putc (mbc, stream) -+ outputs mbc on stream, a byte oriented FILE stream opened for output. -+ -+ mb_setascii (&mbc, sc) -+ assigns the standard ASCII character sc to mbc. -+ (Only available if the 'mbfile' module is in use.) -+ -+ mb_copy (&destmbc, &srcmbc) -+ copies srcmbc to destmbc. -+ -+ Here are the function prototypes of the macros. -+ -+ extern const char * mb_ptr (const mbchar_t mbc); -+ extern size_t mb_len (const mbchar_t mbc); -+ extern bool mb_iseq (const mbchar_t mbc, char sc); -+ extern bool mb_isnul (const mbchar_t mbc); -+ extern int mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern int mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern bool mb_equal (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern bool mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2); -+ extern bool mb_isalnum (const mbchar_t mbc); -+ extern bool mb_isalpha (const mbchar_t mbc); -+ extern bool mb_isascii (const mbchar_t mbc); -+ extern bool mb_isblank (const mbchar_t mbc); -+ extern bool mb_iscntrl (const mbchar_t mbc); -+ extern bool mb_isdigit (const mbchar_t mbc); -+ extern bool mb_isgraph (const mbchar_t mbc); -+ extern bool mb_islower (const mbchar_t mbc); -+ extern bool mb_isprint (const mbchar_t mbc); -+ extern bool mb_ispunct (const mbchar_t mbc); -+ extern bool mb_isspace (const mbchar_t mbc); -+ extern bool mb_isupper (const mbchar_t mbc); -+ extern bool mb_isxdigit (const mbchar_t mbc); -+ extern int mb_width (const mbchar_t mbc); -+ extern void mb_putc (const mbchar_t mbc, FILE *stream); -+ extern void mb_setascii (mbchar_t *new, char sc); -+ extern void mb_copy (mbchar_t *new, const mbchar_t *old); -+ */ -+ -+#ifndef _MBCHAR_H -+#define _MBCHAR_H 1 -+ -+/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE. */ -+#if !_GL_CONFIG_H_INCLUDED -+ #error "Please include config.h first." -+#endif -+ -+#include -+#include -+ -+_GL_INLINE_HEADER_BEGIN -+#ifndef MBCHAR_INLINE -+# define MBCHAR_INLINE _GL_INLINE -+#endif -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+ -+/* The longest multibyte characters, nowadays, are 4 bytes long. -+ Regardless of the values of MB_CUR_MAX and MB_LEN_MAX. */ -+#define MBCHAR_BUF_SIZE 4 -+ -+struct mbchar -+{ -+ const char *ptr; /* pointer to current character */ -+ size_t bytes; /* number of bytes of current character, > 0 */ -+ bool wc_valid; /* true if wc is a valid 32-bit wide character */ -+ char32_t wc; /* if wc_valid: the current character */ -+#if defined GNULIB_MBFILE -+ char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */ -+#endif -+}; -+ -+/* EOF (not a real character) is represented with bytes = 0 and -+ wc_valid = false. */ -+ -+typedef struct mbchar mbchar_t; -+ -+/* Access the current character. */ -+#define mb_ptr(mbc) ((mbc).ptr) -+#define mb_len(mbc) ((mbc).bytes) -+ -+/* Comparison of characters. */ -+#define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc)) -+#define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0) -+#define mb_cmp(mbc1, mbc2) \ -+ ((mbc1).wc_valid \ -+ ? ((mbc2).wc_valid \ -+ ? _GL_CMP ((mbc1).wc, (mbc2).wc) \ -+ : -1) \ -+ : ((mbc2).wc_valid \ -+ ? 1 \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ -+ : (mbc1).bytes < (mbc2).bytes \ -+ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ -+ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) -+#define mb_casecmp(mbc1, mbc2) \ -+ ((mbc1).wc_valid \ -+ ? ((mbc2).wc_valid \ -+ ? _GL_CMP (c32tolower ((mbc1).wc), c32tolower ((mbc2).wc)) \ -+ : -1) \ -+ : ((mbc2).wc_valid \ -+ ? 1 \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) \ -+ : (mbc1).bytes < (mbc2).bytes \ -+ ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \ -+ : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1))) -+#define mb_equal(mbc1, mbc2) \ -+ ((mbc1).wc_valid && (mbc2).wc_valid \ -+ ? (mbc1).wc == (mbc2).wc \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) -+#define mb_caseequal(mbc1, mbc2) \ -+ ((mbc1).wc_valid && (mbc2).wc_valid \ -+ ? c32tolower ((mbc1).wc) == c32tolower ((mbc2).wc) \ -+ : (mbc1).bytes == (mbc2).bytes \ -+ && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0) -+ -+/* , classification. */ -+#define mb_isascii(mbc) \ -+ ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127) -+#define mb_isalnum(mbc) ((mbc).wc_valid && c32isalnum ((mbc).wc)) -+#define mb_isalpha(mbc) ((mbc).wc_valid && c32isalpha ((mbc).wc)) -+#define mb_isblank(mbc) ((mbc).wc_valid && c32isblank ((mbc).wc)) -+#define mb_iscntrl(mbc) ((mbc).wc_valid && c32iscntrl ((mbc).wc)) -+#define mb_isdigit(mbc) ((mbc).wc_valid && c32isdigit ((mbc).wc)) -+#define mb_isgraph(mbc) ((mbc).wc_valid && c32isgraph ((mbc).wc)) -+#define mb_islower(mbc) ((mbc).wc_valid && c32islower ((mbc).wc)) -+#define mb_isprint(mbc) ((mbc).wc_valid && c32isprint ((mbc).wc)) -+#define mb_ispunct(mbc) ((mbc).wc_valid && c32ispunct ((mbc).wc)) -+#define mb_isspace(mbc) ((mbc).wc_valid && c32isspace ((mbc).wc)) -+#define mb_isupper(mbc) ((mbc).wc_valid && c32isupper ((mbc).wc)) -+#define mb_isxdigit(mbc) ((mbc).wc_valid && c32isxdigit ((mbc).wc)) -+ -+/* Extra function. */ -+ -+/* Unprintable characters appear as a small box of width 1. */ -+#define MB_UNPRINTABLE_WIDTH 1 -+ -+MBCHAR_INLINE int -+mb_width_aux (char32_t wc) -+{ -+ int w = c32width (wc); -+ /* For unprintable characters, arbitrarily return 0 for control characters -+ and MB_UNPRINTABLE_WIDTH otherwise. */ -+ return (w >= 0 ? w : c32iscntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH); -+} -+ -+#define mb_width(mbc) \ -+ ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH) -+ -+/* Output. */ -+#define mb_putc(mbc, stream) fwrite ((mbc).ptr, 1, (mbc).bytes, (stream)) -+ -+#if defined GNULIB_MBFILE -+/* Assignment. */ -+# define mb_setascii(mbc, sc) \ -+ ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \ -+ (mbc)->wc = (mbc)->buf[0] = (sc)) -+#endif -+ -+/* Copying a character. */ -+MBCHAR_INLINE void -+mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc) -+{ -+#if defined GNULIB_MBFILE -+ if (old_mbc->ptr == &old_mbc->buf[0]) -+ { -+ memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes); -+ new_mbc->ptr = &new_mbc->buf[0]; -+ } -+ else -+#endif -+ new_mbc->ptr = old_mbc->ptr; -+ new_mbc->bytes = old_mbc->bytes; -+ if ((new_mbc->wc_valid = old_mbc->wc_valid)) -+ new_mbc->wc = old_mbc->wc; -+} -+ -+ -+/* is_basic(c) tests whether the single-byte character c is -+ - in the ISO C "basic character set" or is one of '@', '$', and '`' -+ which ISO C 23 § 5.2.1.1.(1) guarantees to be single-byte and in -+ practice are safe to treat as basic in the execution character set, -+ or -+ - in the POSIX "portable character set", which -+ -+ equally guarantees to be single-byte. -+ This is a convenience function, and is in this file only to share code -+ between mbiter.h, mbuiter.h, and mbfile.h. */ -+#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ -+ && ('$' == 36) && ('%' == 37) && ('&' == 38) && ('\'' == 39) \ -+ && ('(' == 40) && (')' == 41) && ('*' == 42) && ('+' == 43) \ -+ && (',' == 44) && ('-' == 45) && ('.' == 46) && ('/' == 47) \ -+ && ('0' == 48) && ('1' == 49) && ('2' == 50) && ('3' == 51) \ -+ && ('4' == 52) && ('5' == 53) && ('6' == 54) && ('7' == 55) \ -+ && ('8' == 56) && ('9' == 57) && (':' == 58) && (';' == 59) \ -+ && ('<' == 60) && ('=' == 61) && ('>' == 62) && ('?' == 63) \ -+ && ('@' == 64) && ('A' == 65) && ('B' == 66) && ('C' == 67) \ -+ && ('D' == 68) && ('E' == 69) && ('F' == 70) && ('G' == 71) \ -+ && ('H' == 72) && ('I' == 73) && ('J' == 74) && ('K' == 75) \ -+ && ('L' == 76) && ('M' == 77) && ('N' == 78) && ('O' == 79) \ -+ && ('P' == 80) && ('Q' == 81) && ('R' == 82) && ('S' == 83) \ -+ && ('T' == 84) && ('U' == 85) && ('V' == 86) && ('W' == 87) \ -+ && ('X' == 88) && ('Y' == 89) && ('Z' == 90) && ('[' == 91) \ -+ && ('\\' == 92) && (']' == 93) && ('^' == 94) && ('_' == 95) \ -+ && ('`' == 96) && ('a' == 97) && ('b' == 98) && ('c' == 99) \ -+ && ('d' == 100) && ('e' == 101) && ('f' == 102) && ('g' == 103) \ -+ && ('h' == 104) && ('i' == 105) && ('j' == 106) && ('k' == 107) \ -+ && ('l' == 108) && ('m' == 109) && ('n' == 110) && ('o' == 111) \ -+ && ('p' == 112) && ('q' == 113) && ('r' == 114) && ('s' == 115) \ -+ && ('t' == 116) && ('u' == 117) && ('v' == 118) && ('w' == 119) \ -+ && ('x' == 120) && ('y' == 121) && ('z' == 122) && ('{' == 123) \ -+ && ('|' == 124) && ('}' == 125) && ('~' == 126) -+/* The character set is ISO-646, not EBCDIC. */ -+# define IS_BASIC_ASCII 1 -+ -+/* All locale encodings (see localcharset.h) map the characters 0x00..0x7F -+ to U+0000..U+007F, like ASCII, except for -+ CP864 different mapping of '%' -+ SHIFT_JIS different mappings of 0x5C, 0x7E -+ JOHAB different mapping of 0x5C -+ However, these characters in the range 0x20..0x7E are in the ISO C -+ "basic character set" and in the POSIX "portable character set", which -+ ISO C and POSIX guarantee to be single-byte. Thus, locales with these -+ encodings are not POSIX compliant. And they are most likely not in use -+ any more (as of 2023). */ -+# define is_basic(c) ((unsigned char) (c) < 0x80) -+ -+#else -+ -+MBCHAR_INLINE bool -+is_basic (char c) -+{ -+ switch (c) -+ { -+ case '\0': -+ case '\007': case '\010': -+ case '\t': case '\n': case '\v': case '\f': case '\r': -+ case ' ': case '!': case '"': case '#': case '$': case '%': -+ case '&': case '\'': case '(': case ')': case '*': -+ case '+': case ',': case '-': case '.': case '/': -+ case '0': case '1': case '2': case '3': case '4': -+ case '5': case '6': case '7': case '8': case '9': -+ case ':': case ';': case '<': case '=': case '>': -+ case '?': case '@': -+ case 'A': case 'B': case 'C': case 'D': case 'E': -+ case 'F': case 'G': case 'H': case 'I': case 'J': -+ case 'K': case 'L': case 'M': case 'N': case 'O': -+ case 'P': case 'Q': case 'R': case 'S': case 'T': -+ case 'U': case 'V': case 'W': case 'X': case 'Y': -+ case 'Z': -+ case '[': case '\\': case ']': case '^': case '_': case '`': -+ case 'a': case 'b': case 'c': case 'd': case 'e': -+ case 'f': case 'g': case 'h': case 'i': case 'j': -+ case 'k': case 'l': case 'm': case 'n': case 'o': -+ case 'p': case 'q': case 'r': case 's': case 't': -+ case 'u': case 'v': case 'w': case 'x': case 'y': -+ case 'z': case '{': case '|': case '}': case '~': -+ return 1; -+ default: -+ return 0; -+ } -+} -+ -+#endif -+ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+_GL_INLINE_HEADER_END -+ -+#endif /* _MBCHAR_H */ diff --git a/lib/mbfile.c b/lib/mbfile.c new file mode 100644 index 0000000..f4e3e77 @@ -835,27 +409,6 @@ index 0000000..c852f31 +_GL_INLINE_HEADER_END + +#endif /* _MBFILE_H */ -diff --git a/m4/mbchar.m4 b/m4/mbchar.m4 -new file mode 100644 -index 0000000..b76f1d7 ---- /dev/null -+++ b/m4/mbchar.m4 -@@ -0,0 +1,15 @@ -+# mbchar.m4 -+# serial 9 -+dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. -+dnl This file is free software; the Free Software Foundation -+dnl gives unlimited permission to copy and/or distribute it, -+dnl with or without modifications, as long as this notice is preserved. -+dnl This file is offered as-is, without any warranty. -+ -+dnl autoconf tests required for use of mbchar.m4 -+dnl From Bruno Haible. -+ -+AC_DEFUN([gl_MBCHAR], -+[ -+ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) -+]) diff --git a/m4/mbfile.m4 b/m4/mbfile.m4 new file mode 100644 index 0000000..1d126e0 @@ -879,7 +432,7 @@ index 0000000..1d126e0 + : +]) diff --git a/src/cut.c b/src/cut.c -index b424997..c9f181c 100644 +index f0effb9..36479d6 100644 --- a/src/cut.c +++ b/src/cut.c @@ -27,6 +27,11 @@ @@ -1539,7 +1092,7 @@ index b424997..c9f181c 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index 732123f..fdbef3f 100644 +index ca2ad4d..2ad24bf 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -1671,7 +1224,7 @@ index 732123f..fdbef3f 100644 to the list of tab stops. */ extern void diff --git a/src/expand-common.h b/src/expand-common.h -index fe6c8ed..80a1280 100644 +index 46ef4e3..e19469b 100644 --- a/src/expand-common.h +++ b/src/expand-common.h @@ -29,6 +29,18 @@ extern idx_t max_column_width; @@ -1848,414 +1401,11 @@ index 5ec7ce9..65ac315 100644 } } -diff --git a/src/fold.c b/src/fold.c -index b64aad4..a156337 100644 ---- a/src/fold.c -+++ b/src/fold.c -@@ -23,10 +23,32 @@ - #include - #include - -+/* Get mbstate_t, mbrtowc(), wcwidth(). */ -+#if HAVE_WCHAR_H -+# include -+#endif -+ -+/* Get iswprint(), iswblank(), wcwidth(). */ -+#if HAVE_WCTYPE_H -+# include -+#endif -+ - #include "system.h" - #include "fadvise.h" - #include "xdectoint.h" - -+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC -+ installation; work around this configuration error. */ -+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2 -+# undef MB_LEN_MAX -+# define MB_LEN_MAX 16 -+#endif -+ -+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ -+#if HAVE_MBRTOWC && defined mbstate_t -+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -+#endif -+ - #define TAB_WIDTH 8 - - /* The official name of this program (e.g., no 'g' prefix). */ -@@ -34,20 +56,41 @@ - - #define AUTHORS proper_name ("David MacKenzie") - -+#define FATAL_ERROR(Message) \ -+ do \ -+ { \ -+ error (0, 0, (Message)); \ -+ usage (2); \ -+ } \ -+ while (0) -+ -+enum operating_mode -+{ -+ /* Fold texts by columns that are at the given positions. */ -+ column_mode, -+ -+ /* Fold texts by bytes that are at the given positions. */ -+ byte_mode, -+ -+ /* Fold texts by characters that are at the given positions. */ -+ character_mode, -+}; -+ -+/* The argument shows current mode. (Default: column_mode) */ -+static enum operating_mode operating_mode; -+ - /* If nonzero, try to break on whitespace. */ - static bool break_spaces; - --/* If nonzero, count bytes, not column positions. */ --static bool count_bytes; -- - /* If nonzero, at least one of the files we read was standard input. */ - static bool have_read_stdin; - --static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::"; -+static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; - - static struct option const longopts[] = - { - {"bytes", no_argument, nullptr, 'b'}, -+ {"characters", no_argument, nullptr, 'c'}, - {"spaces", no_argument, nullptr, 's'}, - {"width", required_argument, nullptr, 'w'}, - {GETOPT_HELP_OPTION_DECL}, -@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ - - fputs (_("\ - -b, --bytes count bytes rather than columns\n\ -+ -c, --characters count characters rather than columns\n\ - -s, --spaces break at spaces\n\ - -w, --width=WIDTH use WIDTH columns instead of 80\n\ - "), stdout); -@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing to standard output.\n\ - static size_t - adjust_column (size_t column, char c) - { -- if (!count_bytes) -+ if (operating_mode != byte_mode) - { - if (c == '\b') - { -@@ -115,30 +159,14 @@ adjust_column (size_t column, char c) - to stdout, with maximum line length WIDTH. - Return true if successful. */ - --static bool --fold_file (char const *filename, size_t width) -+static void -+fold_text (FILE *istream, size_t width, int *saved_errno) - { -- FILE *istream; - int c; - size_t column = 0; /* Screen column where next char will go. */ - idx_t offset_out = 0; /* Index in 'line_out' for next char. */ - static char *line_out = nullptr; - static idx_t allocated_out = 0; -- int saved_errno; -- -- if (STREQ (filename, "-")) -- { -- istream = stdin; -- have_read_stdin = true; -- } -- else -- istream = fopen (filename, "r"); -- -- if (istream == nullptr) -- { -- error (0, errno, "%s", quotef (filename)); -- return false; -- } - - fadvise (istream, FADVISE_SEQUENTIAL); - -@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width) - bool found_blank = false; - idx_t logical_end = offset_out; - -+ /* If LINE_OUT has no wide character, -+ put a new wide character in LINE_OUT -+ if column is bigger than width. */ -+ if (offset_out == 0) -+ { -+ line_out[offset_out++] = c; -+ continue; -+ } -+ - /* Look for the last blank. */ - while (logical_end) - { -@@ -212,13 +249,224 @@ fold_file (char const *filename, size_t width) - line_out[offset_out++] = c; - } - -- saved_errno = errno; -+ *saved_errno = errno; - if (!ferror (istream)) -- saved_errno = 0; -+ *saved_errno = 0; - - if (offset_out) - fwrite (line_out, sizeof (char), offset_out, stdout); - -+} -+ -+#if HAVE_MBRTOWC -+static void -+fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) -+{ -+ char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ -+ size_t buflen = 0; /* The length of the byte sequence in buf. */ -+ char *bufpos = buf; /* Next read position of BUF. */ -+ wint_t wc; /* A gotten wide character. */ -+ size_t mblength; /* The byte size of a multibyte character which shows -+ as same character as WC. */ -+ mbstate_t state, state_bak; /* State of the stream. */ -+ int convfail = 0; /* 1, when conversion is failed. Otherwise 0. */ -+ -+ static char *line_out = NULL; -+ idx_t offset_out = 0; /* Index in `line_out' for next char. */ -+ static idx_t allocated_out = 0; -+ -+ int increment; -+ size_t column = 0; -+ -+ size_t last_blank_pos; -+ size_t last_blank_column; -+ int is_blank_seen; -+ int last_blank_increment = 0; -+ int is_bs_following_last_blank; -+ size_t bs_following_last_blank_num; -+ int is_cr_after_last_blank; -+ -+#define CLEAR_FLAGS \ -+ do \ -+ { \ -+ last_blank_pos = 0; \ -+ last_blank_column = 0; \ -+ is_blank_seen = 0; \ -+ is_bs_following_last_blank = 0; \ -+ bs_following_last_blank_num = 0; \ -+ is_cr_after_last_blank = 0; \ -+ } \ -+ while (0) -+ -+#define START_NEW_LINE \ -+ do \ -+ { \ -+ putchar ('\n'); \ -+ column = 0; \ -+ offset_out = 0; \ -+ CLEAR_FLAGS; \ -+ } \ -+ while (0) -+ -+ CLEAR_FLAGS; -+ memset (&state, '\0', sizeof(mbstate_t)); -+ -+ for (;; bufpos += mblength, buflen -= mblength) -+ { -+ if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) -+ { -+ memmove (buf, bufpos, buflen); -+ buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); -+ bufpos = buf; -+ } -+ -+ if (buflen < 1) -+ break; -+ -+ /* Get a wide character. */ -+ state_bak = state; -+ mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); -+ -+ switch (mblength) -+ { -+ case (size_t)-1: -+ case (size_t)-2: -+ convfail++; -+ state = state_bak; -+ /* Fall through. */ -+ -+ case 0: -+ mblength = 1; -+ break; -+ } -+ -+rescan: -+ if (convfail) -+ increment = 1; -+ else if (wc == L'\n') -+ { -+ /* preserve newline */ -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ continue; -+ } -+ else if (operating_mode == byte_mode) /* byte mode */ -+ increment = mblength; -+ else if (operating_mode == character_mode) /* character mode */ -+ increment = 1; -+ else /* column mode */ -+ { -+ switch (wc) -+ { -+ case L'\b': -+ increment = (column > 0) ? -1 : 0; -+ break; -+ -+ case L'\r': -+ increment = -1 * column; -+ break; -+ -+ case L'\t': -+ increment = 8 - column % 8; -+ break; -+ -+ default: -+ increment = wcwidth (wc); -+ increment = (increment < 0) ? 0 : increment; -+ } -+ } -+ -+ if (column + increment > width && break_spaces && last_blank_pos) -+ { -+ fwrite (line_out, sizeof(char), last_blank_pos, stdout); -+ putchar ('\n'); -+ -+ offset_out = offset_out - last_blank_pos; -+ column = column - last_blank_column + ((is_cr_after_last_blank) -+ ? last_blank_increment : bs_following_last_blank_num); -+ memmove (line_out, line_out + last_blank_pos, offset_out); -+ CLEAR_FLAGS; -+ goto rescan; -+ } -+ -+ if (column + increment > width && column != 0) -+ { -+ fwrite (line_out, sizeof(char), offset_out, stdout); -+ START_NEW_LINE; -+ goto rescan; -+ } -+ -+ if (allocated_out - offset_out <= mblength) -+ { -+ line_out = xpalloc (line_out, &allocated_out, 1, -1, sizeof *line_out); -+ } -+ -+ memcpy (line_out + offset_out, bufpos, mblength); -+ offset_out += mblength; -+ column += increment; -+ -+ if (is_blank_seen && !convfail && wc == L'\r') -+ is_cr_after_last_blank = 1; -+ -+ if (is_bs_following_last_blank && !convfail && wc == L'\b') -+ ++bs_following_last_blank_num; -+ else -+ is_bs_following_last_blank = 0; -+ -+ if (break_spaces && !convfail && iswblank (wc)) -+ { -+ last_blank_pos = offset_out; -+ last_blank_column = column; -+ is_blank_seen = 1; -+ last_blank_increment = increment; -+ is_bs_following_last_blank = 1; -+ bs_following_last_blank_num = 0; -+ is_cr_after_last_blank = 0; -+ } -+ } -+ -+ *saved_errno = errno; -+ if (!ferror (istream)) -+ *saved_errno = 0; -+ -+ if (offset_out) -+ fwrite (line_out, sizeof (char), offset_out, stdout); -+ -+} -+#endif -+ -+/* Fold file FILENAME, or standard input if FILENAME is "-", -+ to stdout, with maximum line length WIDTH. -+ Return true if successful. */ -+ -+static bool -+fold_file (char const *filename, size_t width) -+{ -+ FILE *istream; -+ int saved_errno; -+ -+ if (STREQ (filename, "-")) -+ { -+ istream = stdin; -+ have_read_stdin = true; -+ } -+ else -+ istream = fopen (filename, "r"); -+ -+ if (istream == nullptr) -+ { -+ error (0, errno, "%s", filename); -+ return false; -+ } -+ -+ /* Define how ISTREAM is being folded. */ -+#if HAVE_MBRTOWC -+ if (MB_CUR_MAX > 1) -+ fold_multibyte_text (istream, width, &saved_errno); -+ else -+#endif -+ fold_text (istream, width, &saved_errno); -+ - if (STREQ (filename, "-")) - clearerr (istream); - else if (fclose (istream) != 0 && !saved_errno) -@@ -249,7 +497,8 @@ main (int argc, char **argv) - - atexit (close_stdout); - -- break_spaces = count_bytes = have_read_stdin = false; -+ operating_mode = column_mode; -+ break_spaces = have_read_stdin = false; - - while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1) - { -@@ -258,7 +507,15 @@ main (int argc, char **argv) - switch (optc) - { - case 'b': /* Count bytes rather than columns. */ -- count_bytes = true; -+ if (operating_mode != column_mode) -+ FATAL_ERROR (_("only one way of folding may be specified")); -+ operating_mode = byte_mode; -+ break; -+ -+ case 'c': -+ if (operating_mode != column_mode) -+ FATAL_ERROR (_("only one way of folding may be specified")); -+ operating_mode = character_mode; - break; - - case 's': /* Break at word boundaries. */ diff --git a/src/local.mk b/src/local.mk -index 188dda1..7db5753 100644 +index 8f6d9a5..da16e59 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -478,8 +478,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -479,8 +479,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -2267,7 +1417,7 @@ index 188dda1..7db5753 100644 src_wc_SOURCES = src/wc.c if USE_AVX2_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index e7081a0..19e0268 100644 +index 87974d0..999bae7 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ @@ -3038,7 +2188,7 @@ index e7081a0..19e0268 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 7af1a25..d3dc684 100644 +index 5a6a963..0b1b941 100644 --- a/src/sort.c +++ b/src/sort.c @@ -29,6 +29,14 @@ @@ -3688,7 +2838,7 @@ index 7af1a25..d3dc684 100644 } @@ -2681,11 +3043,87 @@ diff_reversed (int diff, bool reversed) - return reversed ? (diff < 0) - (diff > 0) : diff; + return reversed ? _GL_CMP (0, diff) : diff; } +#if HAVE_MBRTOWC @@ -4006,7 +3156,7 @@ index 7af1a25..d3dc684 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4291,6 +4934,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4289,6 +4932,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -4014,7 +3164,7 @@ index 7af1a25..d3dc684 100644 break; case 'g': key->general_numeric = true; -@@ -4370,7 +5014,7 @@ main (int argc, char **argv) +@@ -4368,7 +5012,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -4023,7 +3173,7 @@ index 7af1a25..d3dc684 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4393,6 +5037,29 @@ main (int argc, char **argv) +@@ -4391,6 +5035,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -4053,7 +3203,7 @@ index 7af1a25..d3dc684 100644 have_read_stdin = false; inittables (); -@@ -4663,13 +5330,34 @@ main (int argc, char **argv) +@@ -4661,13 +5328,34 @@ main (int argc, char **argv) case 't': { @@ -4086,13 +3236,13 @@ index 7af1a25..d3dc684 100644 +#endif + if (newtab_length == 1 && optarg[1]) { - if (STREQ (optarg, "\\0")) + if (streq (optarg, "\\0")) - newtab = '\0'; + newtab[0] = '\0'; else { /* Provoke with 'sort -txx'. Complain about -@@ -4680,9 +5368,11 @@ main (int argc, char **argv) +@@ -4678,9 +5366,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -4549,10 +3699,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index b68df41..0fe8193 100644 +index 4aa199a..c553c81 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -391,6 +391,8 @@ all_tests = \ +@@ -404,6 +404,8 @@ all_tests = \ tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -4561,7 +3711,7 @@ index b68df41..0fe8193 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -596,6 +598,7 @@ all_tests = \ +@@ -609,6 +611,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -4569,7 +3719,7 @@ index b68df41..0fe8193 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -752,6 +755,7 @@ all_tests = \ +@@ -765,6 +768,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -4644,76 +3794,6 @@ index 4b07210..68b9ea1 100755 my $save_temps = $ENV{DEBUG}; my $verbose = $ENV{VERBOSE}; -diff --git a/tests/misc/fold.pl b/tests/misc/fold.pl -index 877322e..ba889c8 100755 ---- a/tests/misc/fold.pl -+++ b/tests/misc/fold.pl -@@ -20,9 +20,17 @@ use strict; - - (my $program_name = $0) =~ s|.*/||; - -+my $prog = 'fold'; -+my $try = "Try \`$prog --help' for more information.\n"; -+my $inval = "$prog: invalid byte, character or field list\n$try"; -+ - # Turn off localization of executable's output. - @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; --my $prog = 'fold'; -+ -+# uncommented to enable multibyte paths -+my $mb_locale = $ENV{LOCALE_FR_UTF8}; -+! defined $mb_locale || $mb_locale eq 'none' -+ and $mb_locale = 'C'; - - my @Tests = - ( -@@ -44,6 +52,46 @@ my @Tests = - {OUT=>"123456\n7890\nabcdef\nghij\n123456\n7890"}], - ); - -+# Add _POSIX2_VERSION=199209 to the environment of each test -+# that uses an old-style option like +1. -+if ($mb_locale ne 'C') -+ { -+ # Duplicate each test vector, appending "-mb" to the test name and -+ # inserting {ENV => "LC_ALL=$mb_locale"} in the copy, so that we -+ # provide coverage for the distro-added multi-byte code paths. -+ my @new; -+ foreach my $t (@Tests) -+ { -+ my @new_t = @$t; -+ my $test_name = shift @new_t; -+ -+ # Depending on whether fold is multi-byte-patched, -+ # it emits different diagnostics: -+ # non-MB: invalid byte or field list -+ # MB: invalid byte, character or field list -+ # Adjust the expected error output accordingly. -+ if (grep {ref $_ eq 'HASH' && exists $_->{ERR} && $_->{ERR} eq $inval} -+ (@new_t)) -+ { -+ my $sub = {ERR_SUBST => 's/, character//'}; -+ push @new_t, $sub; -+ push @$t, $sub; -+ } -+ push @new, ["$test_name-mb", @new_t, {ENV => "LC_ALL=$mb_locale"}]; -+ } -+ push @Tests, @new; -+ } -+ -+@Tests = triple_test \@Tests; -+ -+# Remember that triple_test creates from each test with exactly one "IN" -+# file two more tests (.p and .r suffix on name) corresponding to reading -+# input from a file and from a pipe. The pipe-reading test would fail -+# due to a race condition about 1 in 20 times. -+# Remove the IN_PIPE version of the "output-is-input" test above. -+# The others aren't susceptible because they have three inputs each. -+@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; -+ - my $save_temps = $ENV{DEBUG}; - my $verbose = $ENV{VERBOSE}; - diff --git a/tests/misc/sort-mb-tests.sh b/tests/misc/sort-mb-tests.sh new file mode 100644 index 0000000..11836ba @@ -4952,7 +4032,7 @@ index a3204d3..40942a5 100755 my $verbose = $ENV{VERBOSE}; diff --git a/tests/sort/sort.pl b/tests/sort/sort.pl -index 2ee92c4..96c7965 100755 +index 5fa9d52..a66952a 100755 --- a/tests/sort/sort.pl +++ b/tests/sort/sort.pl @@ -24,10 +24,15 @@ my $prog = 'sort'; @@ -4972,7 +4052,7 @@ index 2ee92c4..96c7965 100755 # Since each test is run with a file name and with redirected stdin, # the name in the diagnostic is either the file name or "-". # Normalize each diagnostic to use '-'. -@@ -423,6 +428,38 @@ foreach my $t (@Tests) +@@ -428,6 +433,38 @@ foreach my $t (@Tests) } } @@ -5011,7 +4091,7 @@ index 2ee92c4..96c7965 100755 @Tests = triple_test \@Tests; # Remember that triple_test creates from each test with exactly one "IN" -@@ -432,6 +469,7 @@ foreach my $t (@Tests) +@@ -437,6 +474,7 @@ foreach my $t (@Tests) # Remove the IN_PIPE version of the "output-is-input" test above. # The others aren't susceptible because they have three inputs each. @Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests; @@ -5198,5 +4278,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.50.0 +2.51.0 diff --git a/coreutils-python3.patch b/coreutils-python3.patch index e6ff471..447fdbc 100644 --- a/coreutils-python3.patch +++ b/coreutils-python3.patch @@ -1,4 +1,4 @@ -From f1a6e8d840a28eb2ab7a488e0d06450b7192c76d Mon Sep 17 00:00:00 2001 +From 8927d505ecb5334f09c48ef98ef1f464f581d0f7 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Tue, 2 Apr 2024 14:11:26 +0100 Subject: [PATCH] coreutils-python3.patch @@ -10,10 +10,10 @@ Subject: [PATCH] coreutils-python3.patch 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/init.cfg b/init.cfg -index 612d287..9a6fa2d 100644 +index ac05f7b..26d9516 100644 --- a/init.cfg +++ b/init.cfg -@@ -597,10 +597,10 @@ seek_data_capable_() +@@ -601,10 +601,10 @@ seek_data_capable_() # Skip the current test if "." lacks d_type support. require_dirent_d_type_() { @@ -37,7 +37,7 @@ index 1a2f76f..42d3924 100644 # Intended to exit 0 only on Linux/GNU systems. import os diff --git a/tests/du/move-dir-while-traversing.sh b/tests/du/move-dir-while-traversing.sh -index 1d0a359..bd03542 100755 +index adf482b..cf9214a 100755 --- a/tests/du/move-dir-while-traversing.sh +++ b/tests/du/move-dir-while-traversing.sh @@ -21,8 +21,8 @@ print_ver_ du @@ -61,5 +61,5 @@ index 1d0a359..bd03542 100755 import os,sys -- -2.48.1 +2.51.0 diff --git a/coreutils-selinux.patch b/coreutils-selinux.patch deleted file mode 100644 index 91bc5b5..0000000 --- a/coreutils-selinux.patch +++ /dev/null @@ -1,87 +0,0 @@ -From fc96cab095d704e8bf9934812dd8d6f87fbf4be4 Mon Sep 17 00:00:00 2001 -From: rpm-build -Date: Wed, 30 Aug 2023 17:19:58 +0200 -Subject: [PATCH] coreutils-selinux.patch - ---- - src/cp.c | 19 ++++++++++++++++++- - src/install.c | 12 +++++++++++- - 2 files changed, 29 insertions(+), 2 deletions(-) - -diff --git a/src/cp.c b/src/cp.c -index a0ec067..1169c6a 100644 ---- a/src/cp.c -+++ b/src/cp.c -@@ -996,7 +996,7 @@ main (int argc, char **argv) - selinux_enabled = (0 < is_selinux_enabled ()); - cp_option_init (&x); - -- while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ", -+ while ((c = getopt_long (argc, argv, "abcdfHilLnprst:uvxPRS:TZ", - long_opts, nullptr)) - != -1) - { -@@ -1048,6 +1048,23 @@ main (int argc, char **argv) - copy_contents = true; - break; - -+ case 'c': -+ fprintf (stderr, "%s: warning: option '-c' is deprecated," -+ " please use '--preserve=context' instead\n", argv[0]); -+ if (x.set_security_context) -+ { -+ fprintf (stderr, -+ "%s: cannot force target context and preserve it\n", -+ argv[0]); -+ exit (1); -+ } -+ else if (selinux_enabled) -+ { -+ x.preserve_security_context = true; -+ x.require_preserve_context = true; -+ } -+ break; -+ - case 'd': - x.preserve_links = true; - x.dereference = DEREF_NEVER; -diff --git a/src/install.c b/src/install.c -index b3b26ab..2d2f072 100644 ---- a/src/install.c -+++ b/src/install.c -@@ -807,7 +807,7 @@ main (int argc, char **argv) - dir_arg = false; - umask (0); - -- while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z", long_options, -+ while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pPt:TvS:Z", long_options, - nullptr)) - != -1) - { -@@ -872,6 +872,9 @@ main (int argc, char **argv) - no_target_directory = true; - break; - -+ case 'P': -+ fprintf (stderr, "%s: warning: option '-P' is deprecated," -+ " please use '--preserve-context' instead\n", argv[0]); - case PRESERVE_CONTEXT_OPTION: - if (! selinux_enabled) - { -@@ -879,6 +882,13 @@ main (int argc, char **argv) - "this kernel is not SELinux-enabled")); - break; - } -+ if (x.set_security_context) -+ { -+ fprintf (stderr, -+ "%s: cannot force target context and preserve it\n", -+ argv[0]); -+ exit (1); -+ } - x.preserve_security_context = true; - use_default_selinux_context = false; - break; --- -2.48.1 - diff --git a/coreutils.spec b/coreutils.spec index 17e98b3..a82d750 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.7 -Release: 5%{?dist} +Version: 9.8 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,29 +32,9 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch -# cp/mv: do not fail when copying of trivial NFSv4 ACLs fails (rhbz#2363149) -# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=8a356b77717a2e4f735ec06e326880ca1f61aadb -# https://git.savannah.gnu.org/cgit/gnulib.git/patch?id=955360a66c99bdd9ac3688519a8b521b06958fd3 -Patch105: coreutils-9.6-cp-improve-nfsv4-acl-support.patch - -# sort: fix buffer under-read (CVE-2025-5278) -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8c9602e3a145e9596dc1a63c6ed67865814b6633 -Patch106: coreutils-CVE-2025-5278.patch - -# stty: add support for arbitrary baud rates (rhbz#2375439) -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=357fda90d15fd3f7dba61e1ab322b183a48d0081 -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=efaec8078142996d958b6720b85a13b12497c3d0 -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=b7db7757831e93ca44ae59e1921bc4ebbc87974f -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=8b05eca972f70858749a946ac24f08d0718c1be6 -# https://cgit.git.savannah.gnu.org/cgit/coreutils.git/patch/?id=3d35b3c0e56bd556c90dc98c3e5e2e7289b0eb0d -Patch107: coreutils-9.7-stty-arbitrary-baud-rates.patch - # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch -# downstream SELinux options deprecated since 2009 -Patch950: coreutils-selinux.patch - Conflicts: filesystem < 3 # To avoid clobbering installs @@ -295,6 +275,10 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Sep 24 2025 Lukáš Zaoral - 9.8-1 +- rebase to latest upstream release (rhbz#2397467) +- remove downstream patch for selinux options deprecated since 2009 + * Wed Jul 23 2025 Fedora Release Engineering - 9.7-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index 0e9a66d..d1677b5 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.7.tar.xz) = fe81e6ba4fb492095153d5baac1eca8f07ece0957849de746a2a858cf007893cc2ded595a31a5e5d43d13216cc44b9d74a3245d9f23221ecc8cd00f428f27414 -SHA512 (coreutils-9.7.tar.xz.sig) = 48d86a19cee3c153f01f7478847f4621685c02e59942540bb20b30e314df05230817b87d0e73acd953e79fab35718e5bea57f25fe511a2c275a85ced4b317bae +SHA512 (coreutils-9.8.tar.xz.sig) = 0fa9ab4404cd2157584797de22a1f28ec4e0353dae05a7476198dc77e23bf59aaeb1aabf9f7dc22f5d80df311e6ef1490add75ae1663b4091e58cc29db4dcfa3 +SHA512 (coreutils-9.8.tar.xz) = 7b6c420907f0e33e4aff3dd92270f8cbd3e94b2ae8cf7caa2d5d1cfd5e9958319904a6547127abd55ee63aae0316f5b1228586b2da34ea402da032e925a25e53 From 0095d94d91e464de7116672697c0766e15f611de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Thu, 25 Sep 2025 10:23:54 +0200 Subject: [PATCH 520/523] tail: fix tailing larger number of lines in regular files Resolves: rhbz#2398008 --- coreutils-i18n.patch | 12 +-- ...v9.8-tail-n-broken-for-regular-files.patch | 83 +++++++++++++++++++ coreutils.spec | 9 +- 3 files changed, 97 insertions(+), 7 deletions(-) create mode 100644 coreutils-v9.8-tail-n-broken-for-regular-files.patch diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 92167bd..1fd522a 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From c5b102c8d9ddf1cc1109858615de3a9d6d57b7e6 Mon Sep 17 00:00:00 2001 +From d4945b936d0bbea48db45de5e6284cc333e68034 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -39,7 +39,7 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index b8feef9..ab1eb93 100644 +index b8feef9..24a264d 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -169,6 +169,8 @@ gnulib_modules=" @@ -3699,10 +3699,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index 4aa199a..c553c81 100644 +index c1e251b..a7654e8 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -404,6 +404,8 @@ all_tests = \ +@@ -405,6 +405,8 @@ all_tests = \ tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -3711,7 +3711,7 @@ index 4aa199a..c553c81 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -609,6 +611,7 @@ all_tests = \ +@@ -610,6 +612,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -3719,7 +3719,7 @@ index 4aa199a..c553c81 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -765,6 +768,7 @@ all_tests = \ +@@ -766,6 +769,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ diff --git a/coreutils-v9.8-tail-n-broken-for-regular-files.patch b/coreutils-v9.8-tail-n-broken-for-regular-files.patch new file mode 100644 index 0000000..2ce3f2e --- /dev/null +++ b/coreutils-v9.8-tail-n-broken-for-regular-files.patch @@ -0,0 +1,83 @@ +From f9249475026ef5eb18156e8ca6fc2cf3ab61d493 Mon Sep 17 00:00:00 2001 +From: Hannes Braun +Date: Wed, 24 Sep 2025 21:20:49 +0200 +Subject: [PATCH] tail: fix tailing larger number of lines in regular files + +* src/tail.c (file_lines): Seek to the previous block instead of the +beginning (or a little before) of the block that was just scanned. +Otherwise, the same block is read and scanned (at least partially) +again. This bug was introduced by commit v9.7-219-g976f8abc1. +* tests/tail/basic-seek.sh: Add a new test. +* tests/local.mk: Reference the new test. +* NEWS: mention the bug fix. + +(cherry-picked from commit 914972e80dbf82aac9ffe3ff1f67f1028e1a788b) +--- + src/tail.c | 2 +- + tests/local.mk | 1 + + tests/tail/basic-seek.sh | 28 ++++++++++++++++++++++++++++ + 3 files changed, 30 insertions(+), 1 deletion(-) + create mode 100755 tests/tail/basic-seek.sh + +diff --git a/src/tail.c b/src/tail.c +index b8bef1d..c7779c7 100644 +--- a/src/tail.c ++++ b/src/tail.c +@@ -596,7 +596,7 @@ file_lines (char const *prettyname, int fd, struct stat const *sb, + goto free_buffer; + } + +- pos = xlseek (fd, -bufsize, SEEK_CUR, prettyname); ++ pos = xlseek (fd, -(bufsize + bytes_read), SEEK_CUR, prettyname); + bytes_read = read (fd, buffer, bufsize); + if (bytes_read < 0) + { +diff --git a/tests/local.mk b/tests/local.mk +index 4aa199a..c1e251b 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -179,6 +179,7 @@ all_tests = \ + tests/tty/tty-eof.pl \ + tests/misc/read-errors.sh \ + tests/misc/write-errors.sh \ ++ tests/tail/basic-seek.sh \ + tests/tail/inotify-hash-abuse.sh \ + tests/tail/inotify-hash-abuse2.sh \ + tests/tail/F-vs-missing.sh \ +diff --git a/tests/tail/basic-seek.sh b/tests/tail/basic-seek.sh +new file mode 100755 +index 0000000..307ed66 +--- /dev/null ++++ b/tests/tail/basic-seek.sh +@@ -0,0 +1,28 @@ ++#!/bin/sh ++# Verify that tail works when seeking within a file ++ ++# Copyright (C) 2025 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src ++print_ver_ tail ++ ++yes '=================================' | ++ head -n1K > file.in || framework_failure_ ++ ++# This returned 139 in coreutils v9.8 ++test $(tail -n200 file.in | wc -l) = 200 || fail=1 ++ ++Exit $fail +-- +2.51.0 + diff --git a/coreutils.spec b/coreutils.spec index a82d750..f8de1d5 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.8 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,6 +32,10 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch +# tail: fix tailing larger number of lines in regular files (rhbz#2398008) +# https://github.com/coreutils/coreutils/commit/914972e80dbf82aac9ffe3ff1f67f1028e1a788b +Patch105: coreutils-v9.8-tail-n-broken-for-regular-files.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -275,6 +279,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Thu Sep 25 2025 Lukáš Zaoral - 9.8-2 +- tail: fix tailing larger number of lines in regular files (rhbz#2398008) + * Wed Sep 24 2025 Lukáš Zaoral - 9.8-1 - rebase to latest upstream release (rhbz#2397467) - remove downstream patch for selinux options deprecated since 2009 From 0615d97b816fef35a8d2626b20545d9bd48f427b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Mon, 29 Sep 2025 12:14:21 +0200 Subject: [PATCH 521/523] require gnulib-l10n for translations of gnulib messages Resolves: rhbz#2393892 --- coreutils.spec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/coreutils.spec b/coreutils.spec index f8de1d5..7e7ce12 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.8 -Release: 2%{?dist} +Release: 3%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -121,6 +121,9 @@ packaged as a single multicall binary. # https://bugzilla.redhat.com/show_bug.cgi?id=1107973#c7 Obsoletes: %{name} < 8.24-100 +# Gnulib translations are maintained seprately since coreutils 9.6 (#2393892) +Requires: gnulib-l10n + # info doc refers to "Specifying the Time Zone" from glibc-doc (#959597) Suggests: glibc-doc @@ -279,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Mon Sep 29 2025 Lukáš Zaoral - 9.8-3 +- require gnulib-l10n for translations of gnulib messages (rhbz#2393892) + * Thu Sep 25 2025 Lukáš Zaoral - 9.8-2 - tail: fix tailing larger number of lines in regular files (rhbz#2398008) From eb04a0fe336b24ee60d1c9478d5856ac21d792fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Wed, 26 Nov 2025 14:54:16 +0100 Subject: [PATCH 522/523] rebase to latest upstream release Resolves: rhbz#2413803 --- coreutils-9.9-gnulib-c23.patch | 169 ++++++++++++++++++ coreutils-df-direct.patch | 10 +- coreutils-i18n.patch | 149 +++++++-------- ...v9.8-tail-n-broken-for-regular-files.patch | 83 --------- coreutils.spec | 15 +- sources | 4 +- 6 files changed, 260 insertions(+), 170 deletions(-) create mode 100644 coreutils-9.9-gnulib-c23.patch delete mode 100644 coreutils-v9.8-tail-n-broken-for-regular-files.patch diff --git a/coreutils-9.9-gnulib-c23.patch b/coreutils-9.9-gnulib-c23.patch new file mode 100644 index 0000000..82e3899 --- /dev/null +++ b/coreutils-9.9-gnulib-c23.patch @@ -0,0 +1,169 @@ +From 891761bca1aa78336e5b18c121075b6e4696c5d4 Mon Sep 17 00:00:00 2001 +From: Paul Eggert +Date: Sun, 23 Nov 2025 00:50:40 -0800 +Subject: [PATCH] Port to C23 qualifier-generic fns like strchr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This ports Gnulib to strict C23 platforms that reject code +like ‘char *q = strchr (P, 'x');’ when P is a pointer to const, +because in C23 strchr is a qualifier-generic function so +strchr (P, 'x') returns char const *. +This patch does not attempt to do the following two things, +which might be useful in the future: +1. When compiling on non-C23 platforms, check user code for +portability to platforms that define qualifier-generic functions. +2. Port Gnulib to platforms that have qualifier-generic functions +not listed in the C23 standard, e.g., strchrnul. I don’t know +of any such platforms. +* lib/mbschr.c (mbschr): +* lib/memchr2.c (memchr2): +Port to C23, where functions like strchr are qualifier-generic. +* lib/c++defs.h (_GL_FUNCDECL_SYS_NAME): New macro. +* lib/c++defs.h (_GL_FUNCDECL_SYS): +* lib/stdlib.in.h (bsearch): +Use it, to prevent C23 names like strchr from acting like macros. +* lib/string.in.h (memchr, strchr, strpbrk, strrchr): +Do not #undef when GNULIB_POSIXCHECK is defined, as this could +cause conforming C23 code to fail to conform. It’s not clear why +_GL_WARN_ON_USE_CXX; perhaps it was needed but isn’t any more? +But for now, limit the removal of #undef to these four functions +where #undeffing is clearly undesirable in C23. +* lib/wchar.in.h (wmemchr): Parenthesize function name in decl, +to prevent it from acting like a macro. + +Cherry-picked-by: Lukáš Zaoral +Upstream-commit: df17f4f37ed3ca373d23ad42eae51122bdb96626 +--- + lib/c++defs.h | 12 +++++++++++- + lib/mbschr.c | 2 +- + lib/memchr2.c | 2 +- + lib/stdlib.in.h | 6 +++--- + lib/string.in.h | 4 ---- + lib/wchar.in.h | 2 +- + 6 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/lib/c++defs.h b/lib/c++defs.h +index b77979a..7384457 100644 +--- a/lib/c++defs.h ++++ b/lib/c++defs.h +@@ -127,6 +127,16 @@ + #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \ + _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters + ++/* _GL_FUNCDECL_SYS_NAME (func) expands to plain func if C++, and to ++ parenthsized func otherwise. Parenthesization is needed in C23 if ++ the function is like strchr and so is a qualifier-generic macro ++ that expands to something more complicated. */ ++#ifdef __cplusplus ++# define _GL_FUNCDECL_SYS_NAME(func) func ++#else ++# define _GL_FUNCDECL_SYS_NAME(func) (func) ++#endif ++ + /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]); + declares the system function, named func, with the given prototype, + consisting of return type, parameters, and attributes. +@@ -139,7 +149,7 @@ + _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODISCARD); + */ + #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \ +- _GL_EXTERN_C_FUNC __VA_ARGS__ rettype func parameters ++ _GL_EXTERN_C_FUNC __VA_ARGS__ rettype _GL_FUNCDECL_SYS_NAME (func) parameters + + /* _GL_CXXALIAS_RPL (func, rettype, parameters); + declares a C++ alias called GNULIB_NAMESPACE::func +diff --git a/lib/mbschr.c b/lib/mbschr.c +index c9e14b5..6582134 100644 +--- a/lib/mbschr.c ++++ b/lib/mbschr.c +@@ -65,5 +65,5 @@ mbschr (const char *string, int c) + return NULL; + } + else +- return strchr (string, c); ++ return (char *) strchr (string, c); + } +diff --git a/lib/memchr2.c b/lib/memchr2.c +index 7493823..d7724ae 100644 +--- a/lib/memchr2.c ++++ b/lib/memchr2.c +@@ -55,7 +55,7 @@ memchr2 (void const *s, int c1_in, int c2_in, size_t n) + c2 = (unsigned char) c2_in; + + if (c1 == c2) +- return memchr (s, c1, n); ++ return (void *) memchr (s, c1, n); + + /* Handle the first few bytes by reading one byte at a time. + Do this until VOID_PTR is aligned on a longword boundary. */ +diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h +index bef0aaa..fd0e1e0 100644 +--- a/lib/stdlib.in.h ++++ b/lib/stdlib.in.h +@@ -224,9 +224,9 @@ _GL_INLINE_HEADER_BEGIN + + /* Declarations for ISO C N3322. */ + #if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__ +-_GL_EXTERN_C void *bsearch (const void *__key, +- const void *__base, size_t __nmemb, size_t __size, +- int (*__compare) (const void *, const void *)) ++_GL_EXTERN_C void *_GL_FUNCDECL_SYS_NAME (bsearch) ++ (const void *__key, const void *__base, size_t __nmemb, size_t __size, ++ int (*__compare) (const void *, const void *)) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3) _GL_ARG_NONNULL ((5)); + _GL_EXTERN_C void qsort (void *__base, size_t __nmemb, size_t __size, + int (*__compare) (const void *, const void *)) +diff --git a/lib/string.in.h b/lib/string.in.h +index fdcdd21..8b56acf 100644 +--- a/lib/string.in.h ++++ b/lib/string.in.h +@@ -409,7 +409,6 @@ _GL_CXXALIASWARN1 (memchr, void const *, + _GL_CXXALIASWARN (memchr); + # endif + #elif defined GNULIB_POSIXCHECK +-# undef memchr + /* Assume memchr is always declared. */ + _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " + "use gnulib module memchr for portability" ); +@@ -674,7 +673,6 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " + #if defined GNULIB_POSIXCHECK + /* strchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +-# undef strchr + /* Assume strchr is always declared. */ + _GL_WARN_ON_USE_CXX (strchr, + const char *, char *, (const char *, int), +@@ -981,7 +979,6 @@ _GL_CXXALIASWARN (strpbrk); + Even in this simple case, it does not work with multibyte strings if the + locale encoding is GB18030 and one of the characters to be searched is a + digit. */ +-# undef strpbrk + _GL_WARN_ON_USE_CXX (strpbrk, + const char *, char *, (const char *, const char *), + "strpbrk cannot work correctly on character strings " +@@ -1011,7 +1008,6 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctly on character strings " + #if defined GNULIB_POSIXCHECK + /* strrchr() does not work with multibyte strings if the locale encoding is + GB18030 and the character to be searched is a digit. */ +-# undef strrchr + /* Assume strrchr is always declared. */ + _GL_WARN_ON_USE_CXX (strrchr, + const char *, char *, (const char *, int), +diff --git a/lib/wchar.in.h b/lib/wchar.in.h +index ab602a2..6be4515 100644 +--- a/lib/wchar.in.h ++++ b/lib/wchar.in.h +@@ -301,7 +301,7 @@ _GL_EXTERN_C int wcsncmp (const wchar_t *__s1, const wchar_t *__s2, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); + # ifndef __cplusplus +-_GL_EXTERN_C wchar_t *wmemchr (const wchar_t *__s, wchar_t __wc, size_t __n) ++_GL_EXTERN_C wchar_t *(wmemchr) (const wchar_t *__s, wchar_t __wc, size_t __n) + _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); + # endif + _GL_EXTERN_C wchar_t *wmemset (wchar_t *__s, wchar_t __wc, size_t __n) +-- +2.52.0 + diff --git a/coreutils-df-direct.patch b/coreutils-df-direct.patch index 2deacf7..341ee2c 100644 --- a/coreutils-df-direct.patch +++ b/coreutils-df-direct.patch @@ -1,4 +1,4 @@ -From ae768935e696a23e336601c5a239e147628ecf05 Mon Sep 17 00:00:00 2001 +From 91be1a584108a6a3d96f64382bbf206c4213b3db Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 29 Mar 2010 17:20:34 +0000 Subject: [PATCH] coreutils-df-direct.patch @@ -11,10 +11,10 @@ Subject: [PATCH] coreutils-df-direct.patch create mode 100755 tests/df/direct.sh diff --git a/doc/coreutils.texi b/doc/coreutils.texi -index 937d8af..11fa1d6 100644 +index b420606..0ccb368 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi -@@ -12588,6 +12588,13 @@ some systems (notably Solaris), doing this yields more up to date results, +@@ -12597,6 +12597,13 @@ some systems (notably Solaris), doing this yields more up to date results, but in general this option makes @command{df} much slower, especially when there are many or very busy file systems. @@ -29,7 +29,7 @@ index 937d8af..11fa1d6 100644 @opindex --total @cindex grand total of file system size, usage and available space diff --git a/src/df.c b/src/df.c -index 857f76c..07b21ea 100644 +index 75e638c..ef9f0a7 100644 --- a/src/df.c +++ b/src/df.c @@ -121,6 +121,9 @@ static bool print_type; @@ -183,5 +183,5 @@ index 0000000..8e4cfb8 + +Exit $fail -- -2.51.0 +2.52.0 diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch index 1fd522a..83579e9 100644 --- a/coreutils-i18n.patch +++ b/coreutils-i18n.patch @@ -1,4 +1,4 @@ -From d4945b936d0bbea48db45de5e6284cc333e68034 Mon Sep 17 00:00:00 2001 +From a81b096084524e9aeef5e8b81fc829eb9efec581 Mon Sep 17 00:00:00 2001 From: rpm-build Date: Wed, 30 Aug 2023 17:19:58 +0200 Subject: [PATCH] coreutils-i18n.patch @@ -16,7 +16,7 @@ Subject: [PATCH] coreutils-i18n.patch src/expand.c | 90 +++- src/local.mk | 4 +- src/pr.c | 443 ++++++++++++++++++-- - src/sort.c | 790 +++++++++++++++++++++++++++++++++--- + src/sort.c | 791 +++++++++++++++++++++++++++++++++--- src/unexpand.c | 101 ++++- tests/Coreutils.pm | 3 + tests/expand/mb.sh | 183 +++++++++ @@ -29,7 +29,7 @@ Subject: [PATCH] coreutils-i18n.patch tests/sort/sort-merge.pl | 42 ++ tests/sort/sort.pl | 40 +- tests/unexpand/mb.sh | 172 ++++++++ - 25 files changed, 2878 insertions(+), 167 deletions(-) + 25 files changed, 2879 insertions(+), 167 deletions(-) create mode 100644 lib/mbfile.c create mode 100644 lib/mbfile.h create mode 100644 m4/mbfile.m4 @@ -39,20 +39,20 @@ Subject: [PATCH] coreutils-i18n.patch create mode 100644 tests/unexpand/mb.sh diff --git a/bootstrap.conf b/bootstrap.conf -index b8feef9..24a264d 100644 +index ec68ac8..ec2fbbe 100644 --- a/bootstrap.conf +++ b/bootstrap.conf -@@ -169,6 +169,8 @@ gnulib_modules=" - maintainer-makefile +@@ -171,6 +171,8 @@ gnulib_modules=" malloc-gnu manywarnings + mbbuf + mbchar + mbfile mbrlen mbrtoc32 mbrtowc diff --git a/configure.ac b/configure.ac -index 274eff4..5a1cfa5 100644 +index 5e99ef3..ac07577 100644 --- a/configure.ac +++ b/configure.ac @@ -465,6 +465,12 @@ fi @@ -1092,7 +1092,7 @@ index f0effb9..36479d6 100644 if (have_read_stdin && fclose (stdin) == EOF) diff --git a/src/expand-common.c b/src/expand-common.c -index ca2ad4d..2ad24bf 100644 +index 14dd804..0d8eaaa 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -19,6 +19,7 @@ @@ -1103,7 +1103,7 @@ index ca2ad4d..2ad24bf 100644 #include "system.h" #include "c-ctype.h" #include "fadvise.h" -@@ -123,6 +124,119 @@ set_increment_size (colno tabval) +@@ -132,6 +133,119 @@ set_increment_size (colno tabval) return ok; } @@ -1402,10 +1402,10 @@ index 5ec7ce9..65ac315 100644 } diff --git a/src/local.mk b/src/local.mk -index 8f6d9a5..da16e59 100644 +index a8ad6b4..b0e61ec 100644 --- a/src/local.mk +++ b/src/local.mk -@@ -479,8 +479,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) +@@ -490,8 +490,8 @@ src_base32_CPPFLAGS = -DBASE_TYPE=32 $(AM_CPPFLAGS) src_basenc_SOURCES = src/basenc.c src_basenc_CPPFLAGS = -DBASE_TYPE=42 $(AM_CPPFLAGS) @@ -1415,9 +1415,9 @@ index 8f6d9a5..da16e59 100644 +src_unexpand_SOURCES = src/unexpand.c src/expand-common.c lib/mbfile.c lib/mbchar.c src_wc_SOURCES = src/wc.c - if USE_AVX2_WC_LINECOUNT + if USE_AVX512_WC_LINECOUNT diff --git a/src/pr.c b/src/pr.c -index 87974d0..999bae7 100644 +index 10b8c52..079c86c 100644 --- a/src/pr.c +++ b/src/pr.c @@ -312,6 +312,24 @@ @@ -1764,7 +1764,7 @@ index 87974d0..999bae7 100644 h_next = h + chars_per_column; } } -@@ -1748,9 +1872,9 @@ static void +@@ -1751,9 +1875,9 @@ static void align_column (COLUMN *p) { padding_not_printed = p->start_position; @@ -1776,7 +1776,7 @@ index 87974d0..999bae7 100644 padding_not_printed = ANYWHERE; } -@@ -2024,13 +2148,13 @@ store_char (char c) +@@ -2030,13 +2154,13 @@ store_char (char c) /* May be too generous. */ buff = xpalloc (buff, &buff_allocated, 1, -1, sizeof *buff); } @@ -1792,7 +1792,7 @@ index 87974d0..999bae7 100644 char *s; int num_width; -@@ -2047,22 +2171,24 @@ add_line_number (COLUMN *p) +@@ -2053,22 +2177,24 @@ add_line_number (COLUMN *p) /* Tabification is assumed for multiple columns, also for n-separators, but 'default n-separator = TAB' hasn't been given priority over equal column_width also specified by POSIX. */ @@ -1821,7 +1821,7 @@ index 87974d0..999bae7 100644 output_position = POS_AFTER_TAB (chars_per_output_tab, output_position); } -@@ -2221,7 +2347,7 @@ print_white_space (void) +@@ -2227,7 +2353,7 @@ print_white_space (void) while (goal - h_old > 1 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) { @@ -1830,7 +1830,7 @@ index 87974d0..999bae7 100644 h_old = h_new; } while (++h_old <= goal) -@@ -2241,6 +2367,7 @@ print_sep_string (void) +@@ -2247,6 +2373,7 @@ print_sep_string (void) { char const *s = col_sep_string; int l = col_sep_length; @@ -1838,7 +1838,7 @@ index 87974d0..999bae7 100644 if (separators_not_printed <= 0) { -@@ -2252,6 +2379,7 @@ print_sep_string (void) +@@ -2258,6 +2385,7 @@ print_sep_string (void) { for (; separators_not_printed > 0; --separators_not_printed) { @@ -1846,7 +1846,7 @@ index 87974d0..999bae7 100644 while (l-- > 0) { /* 3 types of sep_strings: spaces only, spaces and chars, -@@ -2265,12 +2393,15 @@ print_sep_string (void) +@@ -2271,12 +2399,15 @@ print_sep_string (void) } else { @@ -1863,7 +1863,7 @@ index 87974d0..999bae7 100644 /* sep_string ends with some spaces */ if (spaces_not_printed > 0) print_white_space (); -@@ -2298,7 +2429,7 @@ print_clump (COLUMN *p, int n, char *clump) +@@ -2307,7 +2438,7 @@ print_clump (COLUMN *p, int n, char *clump) required number of tabs and spaces. */ static void @@ -1872,7 +1872,7 @@ index 87974d0..999bae7 100644 { if (tabify_output) { -@@ -2322,6 +2453,74 @@ print_char (char c) +@@ -2331,6 +2462,74 @@ print_char (char c) putchar (c); } @@ -1947,7 +1947,7 @@ index 87974d0..999bae7 100644 /* Skip to page PAGE before printing. PAGE may be larger than total number of pages. */ -@@ -2498,9 +2697,9 @@ read_line (COLUMN *p) +@@ -2507,9 +2706,9 @@ read_line (COLUMN *p) align_empty_cols = false; } @@ -1959,7 +1959,7 @@ index 87974d0..999bae7 100644 padding_not_printed = ANYWHERE; } -@@ -2569,7 +2768,7 @@ print_stored (COLUMN *p) +@@ -2578,7 +2777,7 @@ print_stored (COLUMN *p) COLUMN *q; int line = p->current_line++; @@ -1968,7 +1968,7 @@ index 87974d0..999bae7 100644 /* FIXME UMR: Uninitialized memory read: * This is occurring while in: -@@ -2581,7 +2780,7 @@ print_stored (COLUMN *p) +@@ -2590,7 +2789,7 @@ print_stored (COLUMN *p) xmalloc [xmalloc.c:94] init_store_cols [pr.c:1648] */ @@ -1977,7 +1977,7 @@ index 87974d0..999bae7 100644 pad_vertically = true; -@@ -2601,9 +2800,9 @@ print_stored (COLUMN *p) +@@ -2610,9 +2809,9 @@ print_stored (COLUMN *p) } } @@ -1989,7 +1989,7 @@ index 87974d0..999bae7 100644 padding_not_printed = ANYWHERE; } -@@ -2616,8 +2815,8 @@ print_stored (COLUMN *p) +@@ -2625,8 +2824,8 @@ print_stored (COLUMN *p) if (spaces_not_printed == 0) { output_position = p->start_position + end_vector[line]; @@ -2000,7 +2000,7 @@ index 87974d0..999bae7 100644 } return true; -@@ -2636,7 +2835,7 @@ print_stored (COLUMN *p) +@@ -2645,7 +2844,7 @@ print_stored (COLUMN *p) number of characters is 1.) */ static int @@ -2009,7 +2009,7 @@ index 87974d0..999bae7 100644 { unsigned char uc = c; char *s = clump_buff; -@@ -2646,10 +2845,10 @@ char_to_clump (char c) +@@ -2655,10 +2854,10 @@ char_to_clump (char c) int chars; int chars_per_c = 8; @@ -2022,7 +2022,7 @@ index 87974d0..999bae7 100644 { width = TAB_WIDTH (chars_per_c, input_position); -@@ -2730,6 +2929,164 @@ char_to_clump (char c) +@@ -2739,6 +2938,164 @@ char_to_clump (char c) return chars; } @@ -2188,13 +2188,14 @@ index 87974d0..999bae7 100644 looking for more options and printing the next batch of files. diff --git a/src/sort.c b/src/sort.c -index 5a6a963..0b1b941 100644 +index 05d00cc..eb51f20 100644 --- a/src/sort.c +++ b/src/sort.c -@@ -29,6 +29,14 @@ - #include +@@ -30,6 +30,15 @@ #include #include + #include ++ +#if HAVE_WCHAR_H +# include +#endif @@ -2206,7 +2207,7 @@ index 5a6a963..0b1b941 100644 #include "system.h" #include "argmatch.h" #include "assure.h" -@@ -158,14 +166,39 @@ static int thousands_sep; +@@ -160,14 +169,39 @@ static int thousands_sep; /* We currently ignore multi-byte grouping chars. */ static bool thousands_sep_ignored; @@ -2247,7 +2248,7 @@ index 5a6a963..0b1b941 100644 /* The kind of blanks for '-b' to skip in various options. */ enum blanktype { bl_start, bl_end, bl_both }; -@@ -342,13 +375,11 @@ static bool stable; +@@ -344,13 +378,11 @@ static bool stable; /* An int value outside char range. */ enum { NON_CHAR = CHAR_MAX + 1 }; @@ -2264,9 +2265,9 @@ index 5a6a963..0b1b941 100644 /* Flag to remove consecutive duplicate lines from the output. Only the last of a sequence of equal lines will be output. */ -@@ -806,6 +837,46 @@ reap_all (void) - reap (-1); - } +@@ -386,6 +418,46 @@ struct tempnode + static struct tempnode *volatile temphead; + static struct tempnode *volatile *temptail = &temphead; +/* Function pointers. */ +static void @@ -2311,7 +2312,7 @@ index 5a6a963..0b1b941 100644 /* Clean up any remaining temporary files. */ static void -@@ -1273,7 +1344,7 @@ zaptemp (char const *name) +@@ -1343,7 +1415,7 @@ zaptemp (char const *name) free (node); } @@ -2320,7 +2321,7 @@ index 5a6a963..0b1b941 100644 static int struct_month_cmp (void const *m1, void const *m2) -@@ -1288,7 +1359,7 @@ struct_month_cmp (void const *m1, void const *m2) +@@ -1358,7 +1430,7 @@ struct_month_cmp (void const *m1, void const *m2) /* Initialize the character class tables. */ static void @@ -2329,7 +2330,7 @@ index 5a6a963..0b1b941 100644 { size_t i; -@@ -1300,7 +1371,7 @@ inittables (void) +@@ -1370,7 +1442,7 @@ inittables (void) fold_toupper[i] = toupper (i); } @@ -2338,7 +2339,7 @@ index 5a6a963..0b1b941 100644 /* If we're not in the "C" locale, read different names for months. */ if (hard_LC_TIME) { -@@ -1380,6 +1451,84 @@ specify_nmerge (int oi, char c, char const *s) +@@ -1450,6 +1522,84 @@ specify_nmerge (int oi, char c, char const *s) xstrtol_fatal (e, oi, c, long_options, s); } @@ -2423,7 +2424,7 @@ index 5a6a963..0b1b941 100644 /* Specify the amount of main memory to use when sorting. */ static void specify_sort_size (int oi, char c, char const *s) -@@ -1611,7 +1760,7 @@ buffer_linelim (struct buffer const *buf) +@@ -1676,7 +1826,7 @@ buffer_linelim (struct buffer const *buf) by KEY in LINE. */ static char * @@ -2432,7 +2433,7 @@ index 5a6a963..0b1b941 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t sword = key->sword; -@@ -1620,10 +1769,10 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1685,10 +1835,10 @@ begfield (struct line const *line, struct keyfield const *key) /* The leading field separator itself is included in a field when -t is absent. */ @@ -2445,7 +2446,7 @@ index 5a6a963..0b1b941 100644 ++ptr; if (ptr < lim) ++ptr; -@@ -1653,12 +1802,71 @@ begfield (struct line const *line, struct keyfield const *key) +@@ -1718,12 +1868,71 @@ begfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2518,7 +2519,7 @@ index 5a6a963..0b1b941 100644 { char *ptr = line->text, *lim = ptr + line->length - 1; size_t eword = key->eword, echar = key->echar; -@@ -1673,10 +1881,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1738,10 +1947,10 @@ limfield (struct line const *line, struct keyfield const *key) 'beginning' is the first character following the delimiting TAB. Otherwise, leave PTR pointing at the first 'blank' character after the preceding field. */ @@ -2531,7 +2532,7 @@ index 5a6a963..0b1b941 100644 ++ptr; if (ptr < lim && (eword || echar)) ++ptr; -@@ -1722,10 +1930,10 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1787,10 +1996,10 @@ limfield (struct line const *line, struct keyfield const *key) */ /* Make LIM point to the end of (one byte past) the current field. */ @@ -2544,7 +2545,7 @@ index 5a6a963..0b1b941 100644 if (newlim) lim = newlim; } -@@ -1760,6 +1968,130 @@ limfield (struct line const *line, struct keyfield const *key) +@@ -1825,6 +2034,130 @@ limfield (struct line const *line, struct keyfield const *key) return ptr; } @@ -2675,7 +2676,7 @@ index 5a6a963..0b1b941 100644 /* Fill BUF reading from FP, moving buf->left bytes from the end of buf->buf to the beginning first. If EOF is reached and the file wasn't terminated by a newline, supply one. Set up BUF's line -@@ -1846,8 +2178,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) +@@ -1911,8 +2244,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file) else { if (key->skipsblanks) @@ -2700,7 +2701,7 @@ index 5a6a963..0b1b941 100644 line->keybeg = line_start; } } -@@ -1985,12 +2331,10 @@ find_unit_order (char const *number) +@@ -2050,12 +2397,10 @@ find_unit_order (char const *number) ATTRIBUTE_PURE static int @@ -2716,7 +2717,7 @@ index 5a6a963..0b1b941 100644 int diff = find_unit_order (a) - find_unit_order (b); return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep)); -@@ -2002,7 +2346,7 @@ human_numcompare (char const *a, char const *b) +@@ -2067,7 +2412,7 @@ human_numcompare (char const *a, char const *b) ATTRIBUTE_PURE static int @@ -2725,7 +2726,7 @@ index 5a6a963..0b1b941 100644 { while (blanks[to_uchar (*a)]) a++; -@@ -2012,6 +2356,25 @@ numcompare (char const *a, char const *b) +@@ -2077,6 +2422,25 @@ numcompare (char const *a, char const *b) return strnumcmp (a, b, decimal_point, thousands_sep); } @@ -2751,7 +2752,7 @@ index 5a6a963..0b1b941 100644 static int nan_compare (long double a, long double b) { -@@ -2053,7 +2416,7 @@ general_numcompare (char const *sa, char const *sb) +@@ -2118,7 +2482,7 @@ general_numcompare (char const *sa, char const *sb) Return 0 if the name in S is not recognized. */ static int @@ -2760,7 +2761,7 @@ index 5a6a963..0b1b941 100644 { size_t lo = 0; size_t hi = MONTHS_PER_YEAR; -@@ -2392,15 +2755,14 @@ debug_key (struct line const *line, struct keyfield const *key) +@@ -2457,15 +2821,14 @@ debug_key (struct line const *line, struct keyfield const *key) char saved = *lim; *lim = '\0'; @@ -2778,7 +2779,7 @@ index 5a6a963..0b1b941 100644 else if (key->general_numeric) ignore_value (strtold (beg, &tighter_lim)); else if (key->numeric || key->human_numeric) -@@ -2546,7 +2908,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2611,7 +2974,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) /* Warn about significant leading blanks. */ bool implicit_skip = key_numeric (key) || key->month; bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */ @@ -2787,7 +2788,7 @@ index 5a6a963..0b1b941 100644 && ((!key->skipsblanks && !implicit_skip) || (!key->skipsblanks && key->schar) || (!key->skipeblanks && key->echar))) -@@ -2594,9 +2956,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2659,9 +3022,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) bool number_locale_warned = false; if (basic_numeric_field_span) { @@ -2800,7 +2801,7 @@ index 5a6a963..0b1b941 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2607,9 +2969,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2672,9 +3035,9 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) } if (basic_numeric_field_span || general_numeric_field_span) { @@ -2813,7 +2814,7 @@ index 5a6a963..0b1b941 100644 { error (0, 0, _("field separator %s is treated as a " -@@ -2617,19 +2979,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) +@@ -2682,19 +3045,19 @@ key_warnings (struct keyfield const *gkey, bool gkey_only) quote (((char []) {decimal_point, 0}))); number_locale_warned = true; } @@ -2837,7 +2838,7 @@ index 5a6a963..0b1b941 100644 } } -@@ -2681,11 +3043,87 @@ diff_reversed (int diff, bool reversed) +@@ -2746,11 +3109,87 @@ diff_reversed (int diff, bool reversed) return reversed ? _GL_CMP (0, diff) : diff; } @@ -2926,7 +2927,7 @@ index 5a6a963..0b1b941 100644 { struct keyfield *key = keylist; -@@ -2766,7 +3204,7 @@ keycompare (struct line const *a, struct line const *b) +@@ -2831,7 +3270,7 @@ keycompare (struct line const *a, struct line const *b) else if (key->human_numeric) diff = human_numcompare (ta, tb); else if (key->month) @@ -2935,7 +2936,7 @@ index 5a6a963..0b1b941 100644 else if (key->random) diff = compare_random (ta, tlena, tb, tlenb); else if (key->version) -@@ -2876,6 +3314,211 @@ keycompare (struct line const *a, struct line const *b) +@@ -2941,6 +3380,211 @@ keycompare (struct line const *a, struct line const *b) return diff_reversed (diff, key->reverse); } @@ -3147,7 +3148,7 @@ index 5a6a963..0b1b941 100644 /* Compare two lines A and B, returning negative, zero, or positive depending on whether A compares less than, equal to, or greater than B. */ -@@ -2903,7 +3546,7 @@ compare (struct line const *a, struct line const *b) +@@ -2968,7 +3612,7 @@ compare (struct line const *a, struct line const *b) diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3156,7 +3157,7 @@ index 5a6a963..0b1b941 100644 { /* xmemcoll0 is a performance enhancement as it will not unconditionally write '\0' after the -@@ -4289,6 +4932,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) +@@ -4340,6 +4984,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype) break; case 'f': key->translate = fold_toupper; @@ -3164,7 +3165,7 @@ index 5a6a963..0b1b941 100644 break; case 'g': key->general_numeric = true; -@@ -4368,7 +5012,7 @@ main (int argc, char **argv) +@@ -4419,7 +5064,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3173,7 +3174,7 @@ index 5a6a963..0b1b941 100644 hard_LC_TIME = hard_locale (LC_TIME); #endif -@@ -4391,6 +5035,29 @@ main (int argc, char **argv) +@@ -4442,6 +5087,29 @@ main (int argc, char **argv) thousands_sep = NON_CHAR; } @@ -3203,7 +3204,7 @@ index 5a6a963..0b1b941 100644 have_read_stdin = false; inittables (); -@@ -4661,13 +5328,34 @@ main (int argc, char **argv) +@@ -4717,13 +5385,34 @@ main (int argc, char **argv) case 't': { @@ -3242,7 +3243,7 @@ index 5a6a963..0b1b941 100644 else { /* Provoke with 'sort -txx'. Complain about -@@ -4678,9 +5366,11 @@ main (int argc, char **argv) +@@ -4734,9 +5423,11 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3699,10 +3700,10 @@ index 0000000..26c95de + +Exit $fail diff --git a/tests/local.mk b/tests/local.mk -index c1e251b..a7654e8 100644 +index 53fc53e..0148422 100644 --- a/tests/local.mk +++ b/tests/local.mk -@@ -405,6 +405,8 @@ all_tests = \ +@@ -412,6 +412,8 @@ all_tests = \ tests/sort/sort-field-limit.sh \ tests/sort/sort-files0-from.pl \ tests/sort/sort-float.sh \ @@ -3711,7 +3712,7 @@ index c1e251b..a7654e8 100644 tests/sort/sort-h-thousands-sep.sh \ tests/sort/sort-merge.pl \ tests/sort/sort-merge-fdlimit.sh \ -@@ -610,6 +612,7 @@ all_tests = \ +@@ -618,6 +620,7 @@ all_tests = \ tests/du/threshold.sh \ tests/du/trailing-slash.sh \ tests/du/two-args.sh \ @@ -3719,7 +3720,7 @@ index c1e251b..a7654e8 100644 tests/id/gnu-zero-uids.sh \ tests/id/no-context.sh \ tests/id/context.sh \ -@@ -766,6 +769,7 @@ all_tests = \ +@@ -774,6 +777,7 @@ all_tests = \ tests/touch/read-only.sh \ tests/touch/relative.sh \ tests/touch/trailing-slash.sh \ @@ -3846,7 +3847,7 @@ index 0000000..11836ba + +Exit $fail diff --git a/tests/misc/unexpand.pl b/tests/misc/unexpand.pl -index 27d9c17..4976335 100755 +index bb7469c..c1dec95 100755 --- a/tests/misc/unexpand.pl +++ b/tests/misc/unexpand.pl @@ -27,6 +27,14 @@ my $limits = getlimits (); @@ -3864,7 +3865,7 @@ index 27d9c17..4976335 100755 my @Tests = ( ['a1', {IN=> ' 'x 1 ."y\n"}, {OUT=> ' 'x 1 ."y\n"}], -@@ -128,6 +136,37 @@ my @Tests = +@@ -132,6 +140,37 @@ my @Tests = ['ts2', '-t5,8', {IN=>"x\t \t y\n"}, {OUT=>"x\t\t y\n"}], ); @@ -4278,5 +4279,5 @@ index 0000000..8a82d74 +LC_ALL=C unexpand in in > out || fail=1 +compare exp out > /dev/null 2>&1 || fail=1 -- -2.51.0 +2.52.0 diff --git a/coreutils-v9.8-tail-n-broken-for-regular-files.patch b/coreutils-v9.8-tail-n-broken-for-regular-files.patch deleted file mode 100644 index 2ce3f2e..0000000 --- a/coreutils-v9.8-tail-n-broken-for-regular-files.patch +++ /dev/null @@ -1,83 +0,0 @@ -From f9249475026ef5eb18156e8ca6fc2cf3ab61d493 Mon Sep 17 00:00:00 2001 -From: Hannes Braun -Date: Wed, 24 Sep 2025 21:20:49 +0200 -Subject: [PATCH] tail: fix tailing larger number of lines in regular files - -* src/tail.c (file_lines): Seek to the previous block instead of the -beginning (or a little before) of the block that was just scanned. -Otherwise, the same block is read and scanned (at least partially) -again. This bug was introduced by commit v9.7-219-g976f8abc1. -* tests/tail/basic-seek.sh: Add a new test. -* tests/local.mk: Reference the new test. -* NEWS: mention the bug fix. - -(cherry-picked from commit 914972e80dbf82aac9ffe3ff1f67f1028e1a788b) ---- - src/tail.c | 2 +- - tests/local.mk | 1 + - tests/tail/basic-seek.sh | 28 ++++++++++++++++++++++++++++ - 3 files changed, 30 insertions(+), 1 deletion(-) - create mode 100755 tests/tail/basic-seek.sh - -diff --git a/src/tail.c b/src/tail.c -index b8bef1d..c7779c7 100644 ---- a/src/tail.c -+++ b/src/tail.c -@@ -596,7 +596,7 @@ file_lines (char const *prettyname, int fd, struct stat const *sb, - goto free_buffer; - } - -- pos = xlseek (fd, -bufsize, SEEK_CUR, prettyname); -+ pos = xlseek (fd, -(bufsize + bytes_read), SEEK_CUR, prettyname); - bytes_read = read (fd, buffer, bufsize); - if (bytes_read < 0) - { -diff --git a/tests/local.mk b/tests/local.mk -index 4aa199a..c1e251b 100644 ---- a/tests/local.mk -+++ b/tests/local.mk -@@ -179,6 +179,7 @@ all_tests = \ - tests/tty/tty-eof.pl \ - tests/misc/read-errors.sh \ - tests/misc/write-errors.sh \ -+ tests/tail/basic-seek.sh \ - tests/tail/inotify-hash-abuse.sh \ - tests/tail/inotify-hash-abuse2.sh \ - tests/tail/F-vs-missing.sh \ -diff --git a/tests/tail/basic-seek.sh b/tests/tail/basic-seek.sh -new file mode 100755 -index 0000000..307ed66 ---- /dev/null -+++ b/tests/tail/basic-seek.sh -@@ -0,0 +1,28 @@ -+#!/bin/sh -+# Verify that tail works when seeking within a file -+ -+# Copyright (C) 2025 Free Software Foundation, Inc. -+ -+# This program is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+ -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+ -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src -+print_ver_ tail -+ -+yes '=================================' | -+ head -n1K > file.in || framework_failure_ -+ -+# This returned 139 in coreutils v9.8 -+test $(tail -n200 file.in | wc -l) = 200 || fail=1 -+ -+Exit $fail --- -2.51.0 - diff --git a/coreutils.spec b/coreutils.spec index 7e7ce12..13a7c9d 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils -Version: 9.8 -Release: 3%{?dist} +Version: 9.9 +Release: 1%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -32,9 +32,9 @@ Patch103: coreutils-python3.patch # df --direct Patch104: coreutils-df-direct.patch -# tail: fix tailing larger number of lines in regular files (rhbz#2398008) -# https://github.com/coreutils/coreutils/commit/914972e80dbf82aac9ffe3ff1f67f1028e1a788b -Patch105: coreutils-v9.8-tail-n-broken-for-regular-files.patch +# gnulib C23 support +# https://github.com/coreutils/gnulib/commit/df17f4f37ed3ca373d23ad42eae51122bdb96626 +Patch105: coreutils-9.9-gnulib-c23.patch # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -160,7 +160,7 @@ find tests -name '*.sh' -perm 0644 -print -exec chmod 0755 '{}' '+' # FIXME: Force a newer gettext version to workaround `autoreconf -i` errors # with coreutils 9.6 and bundled gettext 0.19.2 from gettext-common-devel. -sed -i 's/0.19.2/0.22.5/' bootstrap.conf configure.ac +sed -i "s/0.19.2/$(rpm -q --queryformat '%%{VERSION}\n' gettext-devel)/" bootstrap.conf configure.ac autoreconf -fiv @@ -282,6 +282,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Wed Nov 26 2025 Lukáš Zaoral - 9.9-1 +- rebase to latest upstream release (rhbz#2413803) + * Mon Sep 29 2025 Lukáš Zaoral - 9.8-3 - require gnulib-l10n for translations of gnulib messages (rhbz#2393892) diff --git a/sources b/sources index d1677b5..0952ab1 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (coreutils-9.8.tar.xz.sig) = 0fa9ab4404cd2157584797de22a1f28ec4e0353dae05a7476198dc77e23bf59aaeb1aabf9f7dc22f5d80df311e6ef1490add75ae1663b4091e58cc29db4dcfa3 -SHA512 (coreutils-9.8.tar.xz) = 7b6c420907f0e33e4aff3dd92270f8cbd3e94b2ae8cf7caa2d5d1cfd5e9958319904a6547127abd55ee63aae0316f5b1228586b2da34ea402da032e925a25e53 +SHA512 (coreutils-9.9.tar.xz.sig) = 0a3dfdfa6b4234e2e1d42142269f959bdf3cf8f6605a50270a27eff84dd22588f182121f7dd3eeb04be45f5109d02690215065b3d3b43882874d0e165a1435d0 +SHA512 (coreutils-9.9.tar.xz) = e7b0e59f7732d2c098ea4934014f470248bd5c4764210e9200a698010a8e3b95bbb26e543f0cd73ed5a4b8e1f8cda932c73f39954d68175e4deaa47526610c65 From f674e5fc9ccd33d82c2c5477a124604a3b4d0fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= Date: Tue, 13 Jan 2026 16:19:08 +0100 Subject: [PATCH 523/523] fix cut test failure on aarch64 rawhide Resolves: rhbz#2424302 --- coreutils-9.9-fix-cut-test-aarch64.patch | 28 ++++++++++++++++++++++++ coreutils.spec | 9 +++++++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 coreutils-9.9-fix-cut-test-aarch64.patch diff --git a/coreutils-9.9-fix-cut-test-aarch64.patch b/coreutils-9.9-fix-cut-test-aarch64.patch new file mode 100644 index 0000000..600f87b --- /dev/null +++ b/coreutils-9.9-fix-cut-test-aarch64.patch @@ -0,0 +1,28 @@ +From 95044cb5eaea83d02f768feb5ab79fcf5e6ad782 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?P=C3=A1draig=20Brady?= +Date: Mon, 22 Dec 2025 17:12:48 +0000 +Subject: [PATCH] tests: avoid false failure due to ulimit on aarch64 + +* tests/cut/cut-huge-range.sh: Add an extra 1MiB headroom, +which was seen with aarch64. +Reported at https://bugzilla.redhat.com/2424302 + +Cherry-picked-by: Lukáš Zaoral +Upstream-commit: 95044cb5eaea83d02f768feb5ab79fcf5e6ad782 +--- + tests/cut/cut-huge-range.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/cut/cut-huge-range.sh b/tests/cut/cut-huge-range.sh +index 4bd1b129d8..98d7e8f0b9 100755 +--- a/tests/cut/cut-huge-range.sh ++++ b/tests/cut/cut-huge-range.sh +@@ -22,6 +22,7 @@ getlimits_ + + vm=$(get_min_ulimit_v_ returns_ 0 cut -b1 /dev/null) \ + || skip_ 'shell lacks ulimit, or ASAN enabled' ++vm=$(($vm+1000)) # https://bugzilla.redhat.com/2424302 + + # Ensure we can cut up to our sentinel value. + # Don't use expr to subtract one, + diff --git a/coreutils.spec b/coreutils.spec index 13a7c9d..6712263 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -1,7 +1,7 @@ Summary: A set of basic GNU tools commonly used in shell scripts Name: coreutils Version: 9.9 -Release: 1%{?dist} +Release: 2%{?dist} # some used parts of gnulib are under various variants of LGPL License: GPL-3.0-or-later AND GFDL-1.3-no-invariants-or-later AND LGPL-2.1-or-later AND LGPL-3.0-or-later Url: https://www.gnu.org/software/coreutils/ @@ -36,6 +36,10 @@ Patch104: coreutils-df-direct.patch # https://github.com/coreutils/gnulib/commit/df17f4f37ed3ca373d23ad42eae51122bdb96626 Patch105: coreutils-9.9-gnulib-c23.patch +# fix cut test failure on aarch64 rawhide (rhbz#2424302) +# https://github.com/coreutils/coreutils/commit/95044cb5eaea83d02f768feb5ab79fcf5e6ad782 +Patch106: coreutils-9.9-fix-cut-test-aarch64.patch + # (sb) lin18nux/lsb compliance - multibyte functionality patch Patch800: coreutils-i18n.patch @@ -282,6 +286,9 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir %license COPYING %changelog +* Tue Jan 13 2026 Lukáš Zaoral - 9.9-2 +- fix cut test failure on aarch64 rawhide (rhbz#2424302) + * Wed Nov 26 2025 Lukáš Zaoral - 9.9-1 - rebase to latest upstream release (rhbz#2413803)