From fc4c3cf0af447b686901eb546a154752f45a1485 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 19 2015 16:09:18 +0000 Subject: import coreutils-8.22-15.el7 --- diff --git a/SOURCES/coreutils-8.22-dd-progress.patch b/SOURCES/coreutils-8.22-dd-progress.patch new file mode 100644 index 0000000..264a432 --- /dev/null +++ b/SOURCES/coreutils-8.22-dd-progress.patch @@ -0,0 +1,479 @@ +From af2a4ed22594badd2719c0123441d69b17bd8328 Mon Sep 17 00:00:00 2001 +From: Federico Simoncelli +Date: Fri, 26 Sep 2014 17:12:32 +0000 +Subject: dd: new status=progress level to print stats periodically + +* src/dd.c: Report the transfer progress every second when the +new status=progress level is used. Adjust the handling and +description of the status= option so that they're treated as +mutually exclusive levels, rather than flags with implicit precedence. +* doc/coreutils.texi (dd invocation): Document the new progress +status level. Reference the new level in the description of SIGUSR1. +* tests/dd/stats.sh: Add new test for status=progress. +* tests/dd/misc.sh: Change so status=none only takes precedence +if it's the last level specified. +--- +diff --git a/doc/coreutils.texi b/doc/coreutils.texi +index 7d32af5..03bb710 100644 +--- a/doc/coreutils.texi ++++ b/doc/coreutils.texi +@@ -8631,24 +8631,32 @@ will ensure that @samp{count=} corresponds to complete input blocks + rather than the traditional POSIX specified behavior of counting + input read operations. + +-@item status=@var{which} ++@item status=@var{level} + @opindex status + Transfer information is normally output to stderr upon + receipt of the @samp{INFO} signal or when @command{dd} exits. +-Specifying @var{which} will identify which information to suppress. ++Specifying @var{level} will adjust the amount of information printed, ++with the last @var{level} specified taking precedence. + + @table @samp + +-@item noxfer +-@opindex noxfer @r{dd status=} +-Do not print the transfer rate and volume statistics +-that normally make up the last status line. +- + @item none + @opindex none @r{dd status=} + Do not print any informational or warning messages to stderr. + Error messages are output as normal. + ++@item noxfer ++@opindex noxfer @r{dd status=} ++Do not print the final transfer rate and volume statistics ++that normally make up the last status line. ++ ++@item progress ++@opindex progress @r{dd status=} ++Print the transfer rate and volume statistics on stderr, ++when processing each input block. Statistics are output ++on a single line at most once every second, but updates ++can be delayed when waiting on I/O. ++ + @end table + + @item conv=@var{conversion}[,@var{conversion}]@dots{} +@@ -9033,6 +9041,9 @@ The above script will output in the following format + 5120000000 bytes (5.1 GB) copied, 18.913 seconds, 271 MB/s + @end example + ++Note also the @samp{status=progress} option which periodically updates ++the last line of the transfer statistics above. ++ + @vindex POSIXLY_CORRECT + On systems lacking the @samp{INFO} signal @command{dd} responds to the + @samp{USR1} signal instead, unless the @env{POSIXLY_CORRECT} +diff --git a/src/dd.c b/src/dd.c +index d22ec59..4018190 100644 +--- a/src/dd.c ++++ b/src/dd.c +@@ -34,6 +34,7 @@ + #include "long-options.h" + #include "quote.h" + #include "quotearg.h" ++#include "verror.h" + #include "xstrtol.h" + #include "xtime.h" + +@@ -132,11 +133,13 @@ enum + C_SPARSE = 0200000 + }; + +-/* Status bit masks. */ ++/* Status levels. */ + enum + { +- STATUS_NOXFER = 01, +- STATUS_NONE = 02 ++ STATUS_NONE = 1, ++ STATUS_NOXFER = 2, ++ STATUS_DEFAULT = 3, ++ STATUS_PROGRESS = 4 + }; + + /* The name of the input file, or NULL for the standard input. */ +@@ -188,7 +191,7 @@ static int input_flags = 0; + static int output_flags = 0; + + /* Status flags for what is printed to stderr. */ +-static int status_flags = 0; ++static int status_level = STATUS_DEFAULT; + + /* If nonzero, filter characters through the translation table. */ + static bool translation_needed = false; +@@ -211,6 +214,12 @@ static uintmax_t w_bytes = 0; + /* Time that dd started. */ + static xtime_t start_time; + ++/* Previous time for periodic progress. */ ++static xtime_t previous_time; ++ ++/* Whether a '\n' is pending after writing progress. */ ++static bool newline_pending; ++ + /* True if input is seekable. */ + static bool input_seekable; + +@@ -373,8 +382,9 @@ static struct symbol_value const flags[] = + /* Status, for status="...". */ + static struct symbol_value const statuses[] = + { +- {"noxfer", STATUS_NOXFER}, + {"none", STATUS_NONE}, ++ {"noxfer", STATUS_NOXFER}, ++ {"progress", STATUS_PROGRESS}, + {"", 0} + }; + +@@ -517,6 +527,25 @@ maybe_close_stdout (void) + _exit (EXIT_FAILURE); + } + ++/* Like error() but handle any pending newline. */ ++ ++static void _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)) ++nl_error (int status, int errnum, const char *fmt, ...) ++{ ++ if (newline_pending) ++ { ++ fputc ('\n', stderr); ++ newline_pending = false; ++ } ++ ++ va_list ap; ++ va_start (ap, fmt); ++ verror (status, errnum, fmt, ap); ++ va_end (ap); ++} ++ ++#define error nl_error ++ + void + usage (int status) + { +@@ -546,8 +575,10 @@ Copy a file, converting and formatting according to the operands.\n\ + oflag=FLAGS write as per the comma separated symbol list\n\ + seek=N skip N obs-sized blocks at start of output\n\ + skip=N skip N ibs-sized blocks at start of input\n\ +- status=WHICH WHICH info to suppress outputting to stderr;\n\ +- 'noxfer' suppresses transfer stats, 'none' suppresses all\n\ ++ status=LEVEL The LEVEL of information to print to stderr;\n\ ++ 'none' suppresses everything but error messages,\n\ ++ 'noxfer' suppresses the final transfer statistics,\n\ ++ 'progress' shows periodic transfer statistics\n\ + "), stdout); + fputs (_("\ + \n\ +@@ -724,8 +755,7 @@ multiple_bits_set (int i) + /* Print transfer statistics. */ + + static void +-print_stats (void) +-{ ++print_xfer_stats (xtime_t progress_time) { + char hbuf[LONGEST_HUMAN_READABLE + 1]; + int human_opts = + (human_autoscale | human_round_to_nearest +@@ -733,23 +763,8 @@ print_stats (void) + double delta_s; + char const *bytes_per_second; + +- if (status_flags & STATUS_NONE) +- return; +- +- fprintf (stderr, +- _("%"PRIuMAX"+%"PRIuMAX" records in\n" +- "%"PRIuMAX"+%"PRIuMAX" records out\n"), +- r_full, r_partial, w_full, w_partial); +- +- if (r_truncate != 0) +- fprintf (stderr, +- ngettext ("%"PRIuMAX" truncated record\n", +- "%"PRIuMAX" truncated records\n", +- select_plural (r_truncate)), +- r_truncate); +- +- if (status_flags & STATUS_NOXFER) +- return; ++ if (progress_time) ++ fputc ('\r', stderr); + + /* Use integer arithmetic to compute the transfer rate, + since that makes it easy to use SI abbreviations. */ +@@ -761,7 +776,8 @@ print_stats (void) + w_bytes, + human_readable (w_bytes, hbuf, human_opts, 1, 1)); + +- xtime_t now = gethrxtime (); ++ xtime_t now = progress_time ? progress_time : gethrxtime (); ++ + if (start_time < now) + { + double XTIME_PRECISIONe0 = XTIME_PRECISION; +@@ -787,7 +803,42 @@ print_stats (void) + but that was incorrect for languages like Polish. To fix this + bug we now use SI symbols even though they're a bit more + confusing in English. */ +- fprintf (stderr, _(", %g s, %s/s\n"), delta_s, bytes_per_second); ++ char const *time_fmt = _(", %g s, %s/s\n");; ++ if (progress_time) ++ time_fmt = _(", %.6f s, %s/s"); /* OK with '\r' as increasing width. */ ++ fprintf (stderr, time_fmt, delta_s, bytes_per_second); ++ ++ newline_pending = !!progress_time; ++} ++ ++static void ++print_stats (void) ++{ ++ if (status_level == STATUS_NONE) ++ return; ++ ++ if (newline_pending) ++ { ++ fputc ('\n', stderr); ++ newline_pending = false; ++ } ++ ++ fprintf (stderr, ++ _("%"PRIuMAX"+%"PRIuMAX" records in\n" ++ "%"PRIuMAX"+%"PRIuMAX" records out\n"), ++ r_full, r_partial, w_full, w_partial); ++ ++ if (r_truncate != 0) ++ fprintf (stderr, ++ ngettext ("%"PRIuMAX" truncated record\n", ++ "%"PRIuMAX" truncated records\n", ++ select_plural (r_truncate)), ++ r_truncate); ++ ++ if (status_level == STATUS_NOXFER) ++ return; ++ ++ print_xfer_stats (0); + } + + /* An ordinary signal was received; arrange for the program to exit. */ +@@ -1035,7 +1086,7 @@ iread (int fd, char *buf, size_t size) + if (0 < prev_nread && prev_nread < size) + { + uintmax_t prev = prev_nread; +- if (!(status_flags & STATUS_NONE)) ++ if (status_level != STATUS_NONE) + error (0, 0, ngettext (("warning: partial read (%"PRIuMAX" byte); " + "suggest iflag=fullblock"), + ("warning: partial read (%"PRIuMAX" bytes); " +@@ -1086,7 +1137,7 @@ iwrite (int fd, char const *buf, size_t size) + { + int old_flags = fcntl (STDOUT_FILENO, F_GETFL); + if (fcntl (STDOUT_FILENO, F_SETFL, old_flags & ~O_DIRECT) != 0 +- && !(status_flags & STATUS_NONE)) ++ && status_level != STATUS_NONE) + error (0, errno, _("failed to turn off O_DIRECT: %s"), + quote (output_file)); + +@@ -1219,7 +1270,7 @@ operand_matches (char const *str, char const *pattern, char delim) + + static int + parse_symbols (char const *str, struct symbol_value const *table, +- char const *error_msgid) ++ bool exclusive, char const *error_msgid) + { + int value = 0; + +@@ -1241,7 +1292,10 @@ parse_symbols (char const *str, struct symbol_value const *table, + } + } + +- value |= entry->value; ++ if (exclusive) ++ value = entry->value; ++ else ++ value |= entry->value; + if (!strcomma) + break; + str = strcomma + 1; +@@ -1316,17 +1370,17 @@ scanargs (int argc, char *const *argv) + else if (operand_is (name, "of")) + output_file = val; + else if (operand_is (name, "conv")) +- conversions_mask |= parse_symbols (val, conversions, ++ conversions_mask |= parse_symbols (val, conversions, false, + N_("invalid conversion")); + else if (operand_is (name, "iflag")) +- input_flags |= parse_symbols (val, flags, ++ input_flags |= parse_symbols (val, flags, false, + N_("invalid input flag")); + else if (operand_is (name, "oflag")) +- output_flags |= parse_symbols (val, flags, ++ output_flags |= parse_symbols (val, flags, false, + N_("invalid output flag")); + else if (operand_is (name, "status")) +- status_flags |= parse_symbols (val, statuses, +- N_("invalid status flag")); ++ status_level = parse_symbols (val, statuses, true, ++ N_("invalid status level")); + else + { + bool invalid = false; +@@ -1613,7 +1667,7 @@ skip_via_lseek (char const *filename, int fdesc, off_t offset, int whence) + && ioctl (fdesc, MTIOCGET, &s2) == 0 + && MT_SAME_POSITION (s1, s2)) + { +- if (!(status_flags & STATUS_NONE)) ++ if (status_level != STATUS_NONE) + error (0, 0, _("warning: working around lseek kernel bug for file " + "(%s)\n of mt_type=0x%0lx -- " + "see for the list of types"), +@@ -1787,7 +1841,7 @@ advance_input_after_read_error (size_t nbytes) + if (offset == input_offset) + return true; + diff = input_offset - offset; +- if (! (0 <= diff && diff <= nbytes) && !(status_flags & STATUS_NONE)) ++ if (! (0 <= diff && diff <= nbytes) && status_level != STATUS_NONE) + error (0, 0, _("warning: invalid file offset after failed read")); + if (0 <= skip_via_lseek (input_file, STDIN_FILENO, diff, SEEK_CUR)) + return true; +@@ -1986,7 +2040,7 @@ dd_copy (void) + 2. pipe has not enough data + 3. partial reads */ + if ((us_blocks || (!input_offset_overflow && us_bytes)) +- && !(status_flags & STATUS_NONE)) ++ && status_level != STATUS_NONE) + { + error (0, 0, + _("%s: cannot skip to specified offset"), quote (input_file)); +@@ -2029,6 +2083,19 @@ dd_copy (void) + + while (1) + { ++ if (status_level == STATUS_PROGRESS) ++ { ++ xtime_t progress_time = gethrxtime (); ++ uintmax_t delta_xtime = progress_time; ++ delta_xtime -= previous_time; ++ double XTIME_PRECISIONe0 = XTIME_PRECISION; ++ if (delta_xtime / XTIME_PRECISIONe0 > 1) ++ { ++ print_xfer_stats (progress_time); ++ previous_time = progress_time; ++ } ++ } ++ + if (r_partial + r_full >= max_records + !!max_bytes) + break; + +@@ -2053,7 +2120,7 @@ dd_copy (void) + + if (nread < 0) + { +- if (!(conversions_mask & C_NOERROR) || !(status_flags & STATUS_NONE)) ++ if (!(conversions_mask & C_NOERROR) || status_level != STATUS_NONE) + error (0, errno, _("error reading %s"), quote (input_file)); + + if (conversions_mask & C_NOERROR) +@@ -2345,7 +2412,7 @@ main (int argc, char **argv) + } + } + +- start_time = gethrxtime (); ++ start_time = previous_time = gethrxtime (); + + exit_status = dd_copy (); + +diff --git a/tests/dd/misc.sh b/tests/dd/misc.sh +index f877fdd..34dfba7 100755 +--- a/tests/dd/misc.sh ++++ b/tests/dd/misc.sh +@@ -35,9 +35,12 @@ dd status=none if=$tmp_in of=/dev/null 2> err || fail=1 + test -s err && { cat err; fail=1; } + dd status=none if=$tmp_in skip=2 of=/dev/null 2> err || fail=1 + test -s err && { cat err; fail=1; } +-# check status=none is cumulative with status=noxfer +-dd status=none status=noxfer if=$tmp_in of=/dev/null 2> err || fail=1 ++# check later status=none overrides earlier status=noxfer ++dd status=noxfer status=none if=$tmp_in of=/dev/null 2> err || fail=1 + test -s err && { cat err; fail=1; } ++# check later status=noxfer overrides earlier status=none ++dd status=none status=noxfer if=$tmp_in of=/dev/null 2> err || fail=1 ++compare /dev/null err && fail=1 + + dd if=$tmp_in of=$tmp_out 2> /dev/null || fail=1 + compare $tmp_in $tmp_out || fail=1 +diff --git a/tests/dd/stats.sh b/tests/dd/stats.sh +new file mode 100755 +index 0000000..24b8c49` +--- a/dev/null ++++ b/tests/dd/stats.sh +@@ -0,0 +1,65 @@ ++#!/bin/sh ++# Check stats output for SIG{INFO,USR1} and status=progress ++ ++# 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_ dd ++ ++env kill -l | grep '^INFO$' && SIGINFO='INFO' || SIGINFO='USR1' ++ ++# This to avoid races in the USR1 case ++# as the dd process will terminate by default until ++# it has its handler enabled. ++trap '' $SIGINFO ++ ++mkfifo_or_skip_ fifo ++ ++for open in '' '1'; do ++ # Run dd with the fullblock iflag to avoid short reads ++ # which can be triggered by reception of signals ++ dd iflag=fullblock if=/dev/zero of=fifo count=100 bs=5000000 2>err & pid=$! ++ ++ # Note if we sleep here we give dd a chance to exec and block on open. ++ # Otherwise we're probably testing SIG_IGN in the forked shell or early dd. ++ test "$open" && sleep .1 ++ ++ # dd will block on open until fifo is opened for reading. ++ # Timeout in case dd goes away erroneously which we check for below. ++ timeout 10 sh -c 'wc -c < fifo > nwritten' & ++ ++ # Send lots of signals immediately to ensure dd not killed due ++ # to race setting handler, or blocking on open of fifo. ++ # Many signals also check that short reads are handled. ++ until ! kill -s $SIGINFO $pid 2>/dev/null; do ++ sleep .01 ++ done ++ ++ wait ++ ++ # Ensure all data processed and at least last status written ++ grep '500000000 bytes .* copied' err || { cat err; fail=1; } ++done ++ ++progress_output() ++{ ++ { sleep "$1"; echo 1; } | dd bs=1 status=progress of=/dev/null 2>err ++ # Progress output should be for "byte ... copied", while final is "bytes ..." ++ grep 'byte .* copied' err ++} ++retry_delay_ progress_output 1 4 || { cat err; fail=1; } ++ ++Exit $fail +-- +cgit v0.9.0.2 diff --git a/SOURCES/coreutils-8.22-du-bindmountcycles.patch b/SOURCES/coreutils-8.22-du-bindmountcycles.patch new file mode 100644 index 0000000..8c38057 --- /dev/null +++ b/SOURCES/coreutils-8.22-du-bindmountcycles.patch @@ -0,0 +1,157 @@ +From dc1c0523a61932fb0c26a795b7e7391eadf2171a Mon Sep 17 00:00:00 2001 +From: Boris Ranto +Date: Mon, 1 Dec 2014 09:24:14 +0100 +Subject: [PATCH 1/1] du: handle sub-bind-mount cycles gracefully + +This patch fixes the handling of sub-bind-mount cycles which are +incorrectly detected as the file system errors. If you bind mount the +directory 'a' to its subdirectory 'a/b/c' and then run 'du a/b' you +will get the circular dependency warning even though nothing is wrong +with the file system. This happens because the first directory that is +traversed twice in this case is not a bind mount but a child of bind +mount. The solution is to traverse all the directories in the cycle +that fts detected and check whether they are not a (bind) mount. + +* src/du.c (mount_point_in_fts_cycle): New function that checks whether +any of the directories in the cycle that fts detected is a mount point. +* src/du.c (process_file): Update the function to use the new function +that looks up all the directories in the fts cycle instead of only the +last one. +* tests/du/bind-mount-dir-cycle-v2.sh: New test case that exhibits the +described behavior. +* tests/local.mk: Reference the new root test. +--- + src/du.c | 23 ++++++++++++++++++++- + tests/du/bind-mount-dir-cycle-v2.sh | 38 +++++++++++++++++++++++++++++++++++ + tests/local.mk | 1 + + 3 files changed, 61 insertions(+), 1 deletions(-) + create mode 100755 tests/du/bind-mount-dir-cycle-v2.sh + +diff --git a/src/du.c b/src/du.c +index ba20120..f5726c7 100644 +--- a/src/du.c ++++ b/src/du.c +@@ -419,6 +419,27 @@ print_size (const struct duinfo *pdui, const char *string) + fflush (stdout); + } + ++/* This function checks whether any of the directories in the cycle that ++ fts detected is a mount point. */ ++ ++static bool ++mount_point_in_fts_cycle (FTSENT const *ent) ++{ ++ FTSENT const *cycle_ent = ent->fts_cycle; ++ ++ while (ent && ent != cycle_ent) ++ { ++ if (di_set_lookup (di_mnt, ent->fts_statp->st_dev, ++ ent->fts_statp->st_ino) > 0) ++ { ++ return true; ++ } ++ ent = ent->fts_parent; ++ } ++ ++ return false; ++} ++ + /* This function is called once for every file system object that fts + encounters. fts does a depth-first traversal. This function knows + that and accumulates per-directory totals based on changes in +@@ -514,15 +514,11 @@ process_file (FTS *fts, FTSENT *ent) + break; + + case FTS_DC: +- if (cycle_warning_required (fts, ent)) ++ /* If not following symlinks and not a (bind) mount point. */ ++ if (cycle_warning_required (fts, ent) ++ && ! mount_point_in_fts_cycle (ent)) + { +- /* If this is a mount point, then diagnose it and avoid +- the cycle. */ +- if (di_set_lookup (di_mnt, sb->st_dev, sb->st_ino)) +- error (0, 0, _("mount point %s already traversed"), +- quote (file)); +- else +- emit_cycle_warning (file); ++ emit_cycle_warning (file); + return false; + } + return true; +diff --git a/tests/du/bind-mount-dir-cycle-v2.sh b/tests/du/bind-mount-dir-cycle-v2.sh +new file mode 100755 +index 0000000..08bfae2 +--- /dev/null ++++ b/tests/du/bind-mount-dir-cycle-v2.sh +@@ -0,0 +1,38 @@ ++#!/bin/sh ++# Check that du can handle sub-bind-mounts cycles as well. ++ ++# 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_ du ++require_root_ ++ ++cleanup_() { umount a/b/c; } ++ ++mkdir -p a/b/c || framework_failure_ ++mount --bind a a/b/c \ ++ || skip_ 'This test requires mount with a working --bind option.' ++ ++echo a/b/c > exp || framework_failure_ ++echo a/b >> exp || framework_failure_ ++ ++du a/b > out 2> err || fail=1 ++sed 's/^[0-9][0-9]* //' out > k && mv k out ++ ++compare /dev/null err || fail=1 ++compare exp out || fail=1 ++ ++Exit $fail +diff --git a/tests/local.mk b/tests/local.mk +index 653c984..349e322 100644 +--- a/tests/local.mk ++++ b/tests/local.mk +@@ -117,6 +117,7 @@ all_root_tests = \ + tests/dd/skip-seek-past-dev.sh \ + tests/df/problematic-chars.sh \ + tests/du/bind-mount-dir-cycle.sh \ ++ tests/du/bind-mount-dir-cycle-v2.sh \ + tests/id/setgid.sh \ + tests/install/install-C-root.sh \ + tests/ls/capability.sh \ +-- +1.7.2.5 +diff -urNp coreutils-8.22-orig/tests/du/bind-mount-dir-cycle.sh coreutils-8.22/tests/du/bind-mount-dir-cycle.sh +--- coreutils-8.22-orig/tests/du/bind-mount-dir-cycle.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/du/bind-mount-dir-cycle.sh 2015-07-02 15:58:49.230632316 +0200 +@@ -27,12 +27,11 @@ mount --bind a a/b \ + || skip_ "This test requires mount with a working --bind option." + + echo a > exp || framework_failure_ +-echo "du: mount point 'a/b' already traversed" > exp-err || framework_failure_ + +-du a > out 2> err && fail=1 ++du a > out 2> err || fail=1 + sed 's/^[0-9][0-9]* //' out > k && mv k out + +-compare exp-err err || fail=1 ++compare /dev/null err || fail=1 + compare exp out || fail=1 + + Exit $fail diff --git a/SOURCES/coreutils-8.22-id-groups.patch b/SOURCES/coreutils-8.22-id-groups.patch new file mode 100644 index 0000000..76ed9a9 --- /dev/null +++ b/SOURCES/coreutils-8.22-id-groups.patch @@ -0,0 +1,39 @@ +diff -urNp coreutils-8.4-orig/src/id.c coreutils-8.4/src/id.c +--- coreutils-8.4-orig/src/id.c 2014-06-26 08:47:28.435047859 +0200 ++++ coreutils-8.4/src/id.c 2014-06-26 08:55:28.352788022 +0200 +@@ -296,8 +296,12 @@ print_full_info (const char *username) + gid_t *groups; + int i; + +- int n_groups = xgetgroups (username, (pwd ? pwd->pw_gid : -1), +- &groups); ++ gid_t primary_group; ++ if (username) ++ primary_group = pwd ? pwd->pw_gid : -1; ++ else ++ primary_group = egid; ++ int n_groups = xgetgroups (username, primary_group, &groups); + if (n_groups < 0) + { + if (username) + +diff -urNp coreutils-8.22-orig/tests/id/setgid.sh coreutils-8.22/tests/id/setgid.sh +--- coreutils-8.22-orig/tests/id/setgid.sh 2014-06-26 08:47:28.750053213 +0200 ++++ coreutils-8.22/tests/id/setgid.sh 2014-06-26 08:51:02.536624404 +0200 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# Verify that id -G prints the right group when run set-GID. ++# Verify that id [-G] prints the right group when run set-GID. + + # Copyright (C) 2012-2013 Free Software Foundation, Inc. + +@@ -35,4 +35,9 @@ setuidgid -g $gp1 $NON_ROOT_USERNAME env + compare exp out || fail=1 + # With coreutils-8.16 and earlier, id -G would print both: $gp1 $g + ++# With coreutils-8.22 and earlier, id would erroneously print groups=$g ++chroot --user=$NON_ROOT_USERNAME:$gp1 --groups='' / env PATH="$PATH" \ ++ id > out || fail=1 ++grep -F "groups=$gp1" out || fail=1 ++ + Exit $fail diff --git a/SOURCES/coreutils-8.22-mv-hardlinksrace.patch b/SOURCES/coreutils-8.22-mv-hardlinksrace.patch new file mode 100644 index 0000000..4e463a8 --- /dev/null +++ b/SOURCES/coreutils-8.22-mv-hardlinksrace.patch @@ -0,0 +1,365 @@ +diff -urNp coreutils-8.22-orig/src/copy.c coreutils-8.22/src/copy.c +--- coreutils-8.22-orig/src/copy.c 2015-07-03 14:42:56.829772551 +0200 ++++ coreutils-8.22/src/copy.c 2015-07-03 14:51:05.371383675 +0200 +@@ -1292,20 +1292,12 @@ close_src_desc: + 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. */ ++ work to do and should return successfully, right away. */ + + 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 cp_options *x, bool *return_now) + { + const struct stat *src_sb_link; + const struct stat *dst_sb_link; +@@ -1316,7 +1308,6 @@ same_file_ok (char const *src_name, stru + 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 +@@ -1348,14 +1339,11 @@ same_file_ok (char const *src_name, stru + /* Here we have two symlinks that are hard-linked together, + and we're not making backups. In this unusual case, simply + returning true would lead to mv calling "rename(A,B)", +- which would do nothing and return 0. I.e., A would +- not be removed. Hence, the solution is to tell the +- caller that all it must do is unlink A and return. */ ++ which would do nothing and return 0. */ + if (same_link) + { +- *unlink_src = true; + *return_now = true; +- return true; ++ return ! x->move_mode; + } + } + +@@ -1443,26 +1431,22 @@ same_file_ok (char const *src_name, stru + 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) + { ++ /* 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. */ + if (S_ISLNK (dst_sb_link->st_mode)) + return true; + ++ /* It's not ok if they're distinct hard links to the same file as ++ this causes a race condition and we may lose data in this case. */ + 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; ++ return ! x->move_mode; + } + } + +@@ -1820,11 +1804,10 @@ copy_internal (char const *src_name, cha + { /* 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)) ++ x, &return_now)) + { + error (0, 0, _("%s and %s are the same file"), + quote_n (0, src_name), quote_n (1, dst_name)); +@@ -1883,22 +1866,14 @@ copy_internal (char const *src_name, cha + 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)) ++ if (abandon_move (x, dst_name, &dst_sb)) + { + /* 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 + { +diff -urNp coreutils-8.22-orig/tests/cp/same-file.sh coreutils-8.22/tests/cp/same-file.sh +--- coreutils-8.22-orig/tests/cp/same-file.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/cp/same-file.sh 2015-07-03 14:54:12.539772880 +0200 +@@ -36,7 +36,7 @@ ln dangling-slink hard-link > /dev/null 2>&1 \ + rm -f no-such dangling-slink hard-link + + test $hard_link_to_symlink_does_the_deref = yes \ +- && remove_these_sed='/^0 -[bf]*l .*sl1 ->/d' \ ++ && remove_these_sed='/^0 -[bf]*l .*sl1 ->/d; /hlsl/d' \ + || remove_these_sed='/^ELIDE NO TEST OUTPUT/d' + + exec 3>&1 1> actual +@@ -44,7 +44,8 @@ exec 3>&1 1> actual + # FIXME: This should be bigger: like more than 8k + contents=XYZ + +-for args in 'foo symlink' 'symlink foo' 'foo foo' 'sl1 sl2' 'foo hardlink'; do ++for args in 'foo symlink' 'symlink foo' 'foo foo' 'sl1 sl2' \ ++ 'foo hardlink' 'hlsl sl2'; do + for options in '' -d -f -df --rem -b -bd -bf -bdf \ + -l -dl -fl -dfl -bl -bdl -bfl -bdfl; do + case $args$options in +@@ -76,6 +77,8 @@ for args in 'foo symlink' 'symlink foo' + continue ;; + 'yes:sl1 sl2:-bfl') + continue ;; ++ yes:hlsl*) ++ continue ;; + esac + + rm -rf dir +@@ -86,6 +87,7 @@ for args in 'foo symlink' 'symlink foo' + case "$args" in *hardlink*) ln foo hardlink ;; esac + case "$args" in *sl1*) ln -s foo sl1;; esac + case "$args" in *sl2*) ln -s foo sl2;; esac ++ case "$args" in *hlsl*) ln sl2 hlsl;;esac + ( + ( + # echo 1>&2 cp $options $args +@@ -211,6 +213,24 @@ cat <<\EOF | sed "$remove_these_sed" > e + 0 -bfl (foo hardlink) + 0 -bdfl (foo hardlink) + ++1 [cp: 'hlsl' and 'sl2' are the same file] (foo hlsl -> foo sl2 -> foo) ++0 -d (foo hlsl -> foo sl2 -> foo) ++1 -f [cp: 'hlsl' and 'sl2' are the same file] (foo hlsl -> foo sl2 -> foo) ++0 -df (foo hlsl -> foo sl2 -> foo) ++0 --rem (foo hlsl -> foo sl2) ++0 -b (foo hlsl -> foo sl2 sl2.~1~ -> foo) ++0 -bd (foo hlsl -> foo sl2 -> foo sl2.~1~ -> foo) ++0 -bf (foo hlsl -> foo sl2 sl2.~1~ -> foo) ++0 -bdf (foo hlsl -> foo sl2 -> foo sl2.~1~ -> foo) ++1 -l [cp: cannot create hard link 'sl2' to 'hlsl'] (foo hlsl -> foo sl2 -> foo) ++0 -dl (foo hlsl -> foo sl2 -> foo) ++0 -fl (foo hlsl -> foo sl2) ++0 -dfl (foo hlsl -> foo sl2 -> foo) ++0 -bl (foo hlsl -> foo sl2 sl2.~1~ -> foo) ++0 -bdl (foo hlsl -> foo sl2 -> foo) ++0 -bfl (foo hlsl -> foo sl2 sl2.~1~ -> foo) ++0 -bdfl (foo hlsl -> foo sl2 -> foo) ++ + EOF + + exec 1>&3 3>&- +diff -urNp coreutils-8.22-orig/tests/local.mk coreutils-8.22/tests/local.mk +--- coreutils-8.22-orig/tests/local.mk 2015-07-03 14:42:56.820772485 +0200 ++++ coreutils-8.22/tests/local.mk 2015-07-03 14:55:07.060176869 +0200 +@@ -591,7 +591,6 @@ all_tests = \ + tests/mv/hard-3.sh \ + tests/mv/hard-4.sh \ + tests/mv/hard-link-1.sh \ +- tests/mv/hard-verbose.sh \ + tests/mv/i-1.pl \ + tests/mv/i-2.sh \ + tests/mv/i-3.sh \ +diff -urNp coreutils-8.22-orig/tests/mv/force.sh coreutils-8.22/tests/mv/force.sh +--- coreutils-8.22-orig/tests/mv/force.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/mv/force.sh 2015-07-03 14:56:42.840885931 +0200 +@@ -25,18 +25,19 @@ ff2=mvforce2 + echo force-contents > $ff || framework_failure_ + ln $ff $ff2 || framework_failure_ + +-# This mv command should exit nonzero. +-mv $ff $ff > out 2>&1 && fail=1 ++# mv should fail for the same name, or separate hardlinks as in ++# both cases rename() will do nothing and return success. ++# One could unlink(src) in the hardlink case, but that would ++# introduce races with overlapping mv instances removing both hardlinks. + +-cat > exp < out 2>&1 && fail=1 + +-compare exp out || fail=1 +-test $(cat $ff) = force-contents || fail=1 ++ printf "mv: '$ff' and '$dest' are the same file\n" > exp ++ compare exp out || fail=1 + +-# This should succeed, even though the source and destination +-# device and inodes are the same. +-mv $ff $ff2 || fail=1 ++ test $(cat $ff) = force-contents || fail=1 ++done + + Exit $fail +diff -urNp coreutils-8.22-orig/tests/mv/hard-4.sh coreutils-8.22/tests/mv/hard-4.sh +--- coreutils-8.22-orig/tests/mv/hard-4.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/mv/hard-4.sh 2015-07-03 14:58:31.179687188 +0200 +@@ -1,5 +1,5 @@ + #!/bin/sh +-# ensure that mv removes a in this case: touch a; ln a b; mv a b ++# ensure that mv maintains a in this case: touch a; ln a b; mv a b + + # Copyright (C) 2003-2013 Free Software Foundation, Inc. + +@@ -21,15 +21,19 @@ print_ver_ mv + touch a || framework_failure_ + ln a b || framework_failure_ + ++# Between coreutils-5.0 and coreutils-8.24, 'a' would be removed. ++# Before coreutils-5.0.1 the issue would not have been diagnosed. ++# We don't emulate the rename(a,b) with unlink(a) as that would ++# introduce races with overlapping mv instances removing both links. ++mv a b 2>err && fail=1 ++printf "mv: 'a' and 'b' are the same file\n" > exp ++compare exp err || fail=1 + +-mv a b || fail=1 + +-# In coreutils-5.0 and earlier, a would not be removed. +-test -r a && fail=1 ++test -r a || fail=1 + test -r b || fail=1 + +-# Make sure it works also with --backup. +-ln b a ++# Make sure it works with --backup. + mv --backup=simple a b || fail=1 + test -r a && fail=1 + test -r b || fail=1 +diff -urNp coreutils-8.22-orig/tests/mv/i-4.sh coreutils-8.22/tests/mv/i-4.sh +--- coreutils-8.22-orig/tests/mv/i-4.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/mv/i-4.sh 2015-07-03 15:00:39.533718254 +0200 +@@ -23,6 +23,7 @@ for i in a b; do + echo $i > $i || framework_failure_ + done + echo y > y || framework_failure_ ++echo n > n || framework_failure_ + + mv -i a b < y >/dev/null 2>&1 || fail=1 + +@@ -32,18 +33,15 @@ case "$(cat b)" in + *) fail=1 ;; + esac + +-# Ensure that mv -i a b works properly with 'n' and 'y' +-# responses, even when a and b are hard links to the same file. +-# This 'n' test would fail (no prompt) for coreutils-5.0.1 through 5.3.0. +-echo n > n ++# Ensure that mv -i a b works properly with 'n' and 'y' responses, ++# when a and b are hard links to the same file. + rm -f a b + echo a > a + ln a b +-mv -i a b < n >/dev/null 2>&1 || fail=1 ++mv -i a b < y 2>err && fail=1 + test -r a || fail=1 + test -r b || fail=1 +-mv -i a b < y >/dev/null 2>&1 || fail=1 +-test -r a && fail=1 +-test -r b || fail=1 ++printf "mv: 'a' and 'b' are the same file\n" > exp ++compare exp err || fail=1 + + Exit $fail +diff -urNp coreutils-8.22-orig/tests/mv/symlink-onto-hardlink-to-self.sh coreutils-8.22/tests/mv/symlink-onto-hardlink-to-self.sh +--- coreutils-8.22-orig/tests/mv/symlink-onto-hardlink-to-self.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/mv/symlink-onto-hardlink-to-self.sh 2015-07-03 15:01:39.209190741 +0200 +@@ -1,10 +1,10 @@ + #!/bin/sh +-# Demonstrate that when moving a symlink onto a hardlink-to-that-symlink, the +-# source symlink is removed. Depending on your kernel (e.g., Linux, Solaris, ++# Demonstrate that when moving a symlink onto a hardlink-to-that-symlink, ++# an error is presented. Depending on your kernel (e.g., Linux, Solaris, + # but not NetBSD), prior to coreutils-8.16, the mv would successfully perform + # a no-op. I.e., surprisingly, mv s1 s2 would succeed, yet fail to remove s1. + +-# Copyright (C) 2012-2013 Free Software Foundation, Inc. ++# Copyright (C) 2012-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 +@@ -26,27 +26,34 @@ print_ver_ mv + touch f || framework_failure_ + ln -s f s2 || framework_failure_ + +-for opt in '' --backup; do ++# Attempt to create a hard link to that symlink. ++# On some systems, it's not possible: they create a hard link to the referent. ++ln s2 s1 || framework_failure_ ++ ++# If s1 is not a symlink, skip this test. ++test -h s1 \ ++ || skip_ your kernel or file system cannot create a hard link to a symlink + +- # Attempt to create a hard link to that symlink. +- # On some systems, it's not possible: they create a hard link to the referent. +- ln s2 s1 || framework_failure_ +- +- # If s1 is not a symlink, skip this test. +- test -h s1 \ +- || skip_ your kernel or file system cannot create a hard link to a symlink ++for opt in '' --backup; do + +- mv $opt s1 s2 > out 2>&1 || fail=1 +- compare /dev/null out || fail=1 ++ if test "$opt" = --backup; then ++ mv $opt s1 s2 > out 2>&1 || fail=1 ++ compare /dev/null out || fail=1 + +- # Ensure that s1 is gone. +- test -e s1 && fail=1 ++ # Ensure that s1 is gone. ++ test -e s1 && fail=1 + +- if test "$opt" = --backup; then + # With --backup, ensure that the backup file was created. + ref=$(readlink s2~) || fail=1 + test "$ref" = f || fail=1 + else ++ echo "mv: 's1' and 's2' are the same file" > exp ++ mv $opt s1 s2 2>err && fail=1 ++ compare exp err || fail=1 ++ ++ # Ensure that s1 is still present. ++ test -e s1 || fail=1 ++ + # Without --backup, ensure there is no backup file. + test -e s2~ && fail=1 + fi diff --git a/SOURCES/coreutils-8.22-non-defaulttests.patch b/SOURCES/coreutils-8.22-non-defaulttests.patch new file mode 100644 index 0000000..95a6dee --- /dev/null +++ b/SOURCES/coreutils-8.22-non-defaulttests.patch @@ -0,0 +1,267 @@ +diff -urNp coreutils-8.22-orig/tests/cp/cp-a-selinux.sh coreutils-8.22/tests/cp/cp-a-selinux.sh +--- coreutils-8.22-orig/tests/cp/cp-a-selinux.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/cp/cp-a-selinux.sh 2015-08-17 13:59:27.837012142 +0200 +@@ -4,7 +4,7 @@ + # Check also locally if --preserve=context, -a and --preserve=all + # does work + +-# Copyright (C) 2007-2013 Free Software Foundation, Inc. ++# Copyright (C) 2007-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 +@@ -37,16 +37,36 @@ cp -a c d 2>err || framework_failure_ + cp --preserve=context c e || framework_failure_ + cp --preserve=all c f || framework_failure_ + ls -Z d | grep $ctx || fail=1 +-test -s err && fail=1 #there must be no stderr output for -a ++# there must be no stderr output for -a ++compare /dev/null err || fail=1 + ls -Z e | grep $ctx || fail=1 + ls -Z f | grep $ctx || fail=1 ++rm -f f ++ ++# Check handling of existing dirs which requires specific handling ++# due to recursion, and was handled incorrectly in coreutils-8.22 ++# Note standard permissions are updated for existing directories ++# in the destination, so SELinux contexts should be updated too. ++chmod o+rw restore/existing_dir ++mkdir -p backup/existing_dir/ || framework_failure_ ++ls -Zd backup/existing_dir > ed_ctx || fail=1 ++grep $ctx ed_ctx && framework_failure_ ++touch backup/existing_dir/file || framework_failure_ ++chcon $ctx backup/existing_dir/file || framework_failure_ ++# Set the dir context to ensure it is reset ++mkdir -p --context="$ctx" restore/existing_dir || framework_failure_ ++# Copy and ensure existing directories updated ++cp -a backup/. restore/ ++ls -Zd restore/existing_dir > ed_ctx || fail=1 ++grep $ctx ed_ctx && ++ { ls -lZd restore/existing_dir; fail=1; } + + # Check restorecon (-Z) functionality for file and directory + get_selinux_type() { ls -Zd "$1" | sed -n 's/.*:\(.*_t\):.*/\1/p'; } + # Also make a dir with our known context + mkdir c_d || framework_failure_ + chcon $ctx c_d || framework_failure_ +-# Get the type of this known context for file and dir ++# Get the type of this known context for file and dir for tracing + old_type_f=$(get_selinux_type c) + old_type_d=$(get_selinux_type c_d) + # Setup copies for manipulation with restorecon +@@ -62,7 +82,7 @@ if restorecon Z1 Z1_d 2>/dev/null; then + cpZ_type_f=$(get_selinux_type Z2) + test "$cpZ_type_f" = "$new_type_f" || fail=1 + +- # Ensuze -Z overrides -a and that dirs are handled too ++ # Ensure -Z overrides -a and that dirs are handled too + cp -aZ c Z3 || fail=1 + cp -aZ c_d Z3_d || fail=1 + cpaZ_type_f=$(get_selinux_type Z3) +@@ -93,27 +113,30 @@ test $skip = 1 \ + + cd mnt || framework_failure_ + +-echo > f || framework_failure_ +- ++# Create files with hopefully different contexts ++echo > ../f || framework_failure_ + echo > g || framework_failure_ ++test "$(stat -c%C ../f)" = "$(stat -c%C g)" && ++ skip_ "files on separate file systems have the same security context" ++ + # /bin/cp from coreutils-6.7-3.fc7 would fail this test by letting cp + # succeed (giving no diagnostics), yet leaving the destination file empty. +-cp -a f g 2>err || fail=1 ++cp -a ../f g 2>err || fail=1 + test -s g || fail=1 # The destination file must not be empty. +-test -s err && fail=1 # There must be no stderr output. ++compare /dev/null err || fail=1 + + # ===================================================== + # Here, we expect cp to succeed and not warn with "Operation not supported" + rm -f g + echo > g +-cp --preserve=all f g 2>err || fail=1 ++cp --preserve=all ../f g 2>err || fail=1 + test -s g || fail=1 + grep "Operation not supported" err && fail=1 + + # ===================================================== + # The same as above except destination does not exist + rm -f g +-cp --preserve=all f g 2>err || fail=1 ++cp --preserve=all ../f g 2>err || fail=1 + test -s g || fail=1 + grep "Operation not supported" err && fail=1 + +@@ -133,9 +156,9 @@ echo > g + # ===================================================== + # Here, we expect cp to fail, because it cannot set the SELinux + # security context through NFS or a mount with fixed context. +-cp --preserve=context f g 2> out && fail=1 ++cp --preserve=context ../f g 2> out && fail=1 + # Here, we *do* expect the destination to be empty. +-test -s g && fail=1 ++compare /dev/null g || fail=1 + sed "s/ .g'.*//" out > k + mv k out + compare exp out || fail=1 +@@ -143,9 +166,9 @@ compare exp out || fail=1 + rm -f g + echo > g + # Check if -a option doesn't silence --preserve=context option diagnostics +-cp -a --preserve=context f g 2> out2 && fail=1 ++cp -a --preserve=context ../f g 2> out2 && fail=1 + # Here, we *do* expect the destination to be empty. +-test -s g && fail=1 ++compare /dev/null g || fail=1 + sed "s/ .g'.*//" out2 > k + mv k out2 + compare exp out2 || fail=1 +@@ -154,31 +177,33 @@ for no_g_cmd in '' 'rm -f g'; do + # restorecon equivalent. Note even though the context + # returned from matchpathcon() will not match $ctx + # the resulting ENOTSUP warning will be suppressed. ++ + # With absolute path + $no_g_cmd +- cp -Z f $(realpath g) || fail=1 ++ cp -Z ../f $(realpath g) || fail=1 + # With relative path + $no_g_cmd +- cp -Z f g || fail=1 ++ cp -Z ../f g || fail=1 + # -Z overrides -a + $no_g_cmd +- cp -Z -a f g || fail=1 ++ cp -Z -a ../f g || fail=1 + # -Z doesn't take an arg + $no_g_cmd +- cp -Z "$ctx" f g && fail=1 ++ returns_ 1 cp -Z "$ctx" ../f g || fail=1 + + # Explicit context + $no_g_cmd + # Explicitly defaulting to the global $ctx should work +- cp --context="$ctx" f g || fail=1 ++ cp --context="$ctx" ../f g || fail=1 + # --context overrides -a + $no_g_cmd +- cp -a --context="$ctx" f g || fail=1 ++ cp -a --context="$ctx" ../f g || fail=1 + done + +-# Mutually exlusive options +-cp -Z --preserve=context f g && fail=1 +-cp --preserve=context -Z f g && fail=1 +-cp --preserve=context --context="$ctx" f g && fail=1 ++# Mutually exclusive options ++returns_ 1 cp -Z --preserve=context ../f g || fail=1 ++returns_ 1 cp --preserve=context -Z ../f g || fail=1 ++returns_ 1 cp --preserve=context --context="$ctx" ../f g || fail=1 + + Exit $fail ++ +diff -urNp coreutils-8.22-orig/tests/du/2g.sh coreutils-8.22/tests/du/2g.sh +--- coreutils-8.22-orig/tests/du/2g.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/du/2g.sh 2015-08-17 13:59:37.349088611 +0200 +@@ -3,7 +3,7 @@ + # Before coreutils-5.93, on systems with a signed, 32-bit stat.st_blocks + # one of du's computations would overflow. + +-# Copyright (C) 2005-2013 Free Software Foundation, Inc. ++# Copyright (C) 2005-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 +@@ -24,13 +24,9 @@ print_ver_ du + # Creating a 2GB file counts as 'very expensive'. + very_expensive_ + +- + # Get number of free kilobytes on current partition, so we can + # skip this test if there is insufficient free space. +- +-# This technique relies on the fact that the 'Available' kilobyte +-# count is the number just before the one with a trailing '%'. +-free_kb=$(df -kP .|tail -1|sed 's/ [0-9][0-9]*%.*//;s/ *$//;s/.* //') ++free_kb=$(df -k --output=avail . | tail -n1) + case "$free_kb" in + [0-9]*) ;; + *) skip_ "invalid size from df: $free_kb";; +@@ -45,16 +41,22 @@ test $min_kb -lt $free_kb || + } + + big=big +-rm -f $big +-test -t 1 || printf 'creating a 2GB file...\n' +-for i in $(seq 100); do +- # Note: 2147483648 == 2^31. Print floor(2^31/100) per iteration. +- printf %21474836s x >> $big || fail=1 +- # On the final iteration, append the remaining 48 bytes. +- test $i = 100 && { printf %48s x >> $big || fail=1; } +- test -t 1 && printf 'creating a 2GB file: %d%% complete\r' $i +-done +-echo ++ ++if ! fallocate -l2G $big; then ++ rm -f $big ++ { ++ is_local_dir_ . || skip 'Not writing 2GB data to remote' ++ for i in $(seq 100); do ++ # Note: 2147483648 == 2^31. Print floor(2^31/100) per iteration. ++ printf %21474836s x || fail=1 ++ done ++ # After the final iteration, append the remaining 48 bytes. ++ printf %48s x || fail=1 ++ } > $big || fail=1 ++fi ++ ++# The allocation may be done asynchronously (BTRFS for example) ++sync $big || framework_failure_ + + du -k $big > out1 || fail=1 + rm -f $big +diff -urNp coreutils-8.22-orig/tests/init.sh coreutils-8.22/tests/init.sh +--- coreutils-8.22-orig/tests/init.sh 2013-12-04 15:48:30.000000000 +0100 ++++ coreutils-8.22/tests/init.sh 2015-08-17 13:59:19.900948318 +0200 +@@ -93,6 +93,27 @@ skip_ () { warn_ "$ME_: skipped test: $@ + fatal_ () { warn_ "$ME_: hard error: $@"; Exit 99; } + framework_failure_ () { warn_ "$ME_: set-up failure: $@"; Exit 99; } + ++# This is used to simplify checking of the return value ++# which is useful when ensuring a command fails as desired. ++# I.e., just doing `command ... &&fail=1` will not catch ++# a segfault in command for example. With this helper you ++# instead check an explicit exit code like ++# returns_ 1 command ... || fail ++returns_ () { ++ # Disable tracing so it doesn't interfere with stderr of the wrapped command ++ { set +x; } 2>/dev/null ++ ++ local exp_exit="$1" ++ shift ++ "$@" ++ test $? -eq $exp_exit && ret_=0 || ret_=1 ++ ++ if test "$VERBOSE" = yes && test "$gl_set_x_corrupts_stderr_" = false; then ++ set -x ++ fi ++ { return $ret_; } 2>/dev/null ++} ++ + # Sanitize this shell to POSIX mode, if possible. + DUALCASE=1; export DUALCASE + if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then +diff -urNp coreutils-8.22-orig/tests/local.mk coreutils-8.22/tests/local.mk +--- coreutils-8.22-orig/tests/local.mk 2015-08-17 12:44:49.343344148 +0200 ++++ coreutils-8.22/tests/local.mk 2015-08-17 13:59:12.124885835 +0200 +@@ -121,7 +121,6 @@ all_root_tests = \ + tests/install/install-C-root.sh \ + tests/ls/capability.sh \ + tests/ls/nameless-uid.sh \ +- tests/misc/chcon.sh \ + tests/misc/chroot-credentials.sh \ + tests/misc/selinux.sh \ + tests/misc/truncate-owned-by-other.sh \ diff --git a/SOURCES/coreutils-8.22-selinux-optionsseparate.patch b/SOURCES/coreutils-8.22-selinux-optionsseparate.patch new file mode 100644 index 0000000..10743c0 --- /dev/null +++ b/SOURCES/coreutils-8.22-selinux-optionsseparate.patch @@ -0,0 +1,80 @@ +diff -urNp coreutils-8.22-orig/src/cp.c coreutils-8.22/src/cp.c +--- coreutils-8.22-orig/src/cp.c 2015-06-11 15:58:04.230858212 +0200 ++++ coreutils-8.22/src/cp.c 2015-06-11 15:59:13.191396755 +0200 +@@ -233,8 +233,10 @@ Copy SOURCE to DEST, or multiple SOURCE( + -x, --one-file-system stay on this file system\n\ + "), stdout); + fputs (_("\ +- -Z, --context[=CTX] set SELinux security context of destination\n\ +- file to default type, or to CTX if specified\n\ ++ -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\ ++ SELinux or SMACK security context to CTX\n\ + "), stdout); + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); +diff -urNp coreutils-8.22-orig/src/install.c coreutils-8.22/src/install.c +--- coreutils-8.22-orig/src/install.c 2015-06-11 15:58:04.230858212 +0200 ++++ coreutils-8.22/src/install.c 2015-06-11 16:00:16.754893027 +0200 +@@ -647,8 +647,10 @@ In the 4th form, create all components o + "), stdout); + fputs (_("\ + -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\ ++ -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\ ++ SELinux or SMACK security context to CTX\n\ + "), stdout); + + fputs (HELP_OPTION_DESCRIPTION, stdout); +diff -urNp coreutils-8.22-orig/src/mkdir.c coreutils-8.22/src/mkdir.c +--- coreutils-8.22-orig/src/mkdir.c 2013-12-05 01:59:36.000000000 +0100 ++++ coreutils-8.22/src/mkdir.c 2015-06-11 16:01:17.209364915 +0200 +@@ -66,8 +66,12 @@ Create the DIRECTORY(ies), if they do no + -m, --mode=MODE set file mode (as in chmod), not a=rwx - umask\n\ + -p, --parents no error if existing, make parent directories as needed\n\ + -v, --verbose print a message for each created directory\n\ +- -Z, --context[=CTX] set the SELinux security context of each created\n\ +- directory to default type or to CTX if specified\n\ ++"), stdout); ++ fputs (_("\ ++ -Z set SELinux security context of each created directory\n\ ++ to the default type\n\ ++ --context[=CTX] like -Z, or if CTX is specified then set the SELinux\n\ ++ or SMACK security context to CTX\n\ + "), stdout); + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); +diff -urNp coreutils-8.22-orig/src/mkfifo.c coreutils-8.22/src/mkfifo.c +--- coreutils-8.22-orig/src/mkfifo.c 2013-12-05 00:43:05.000000000 +0100 ++++ coreutils-8.22/src/mkfifo.c 2015-06-11 16:02:03.389725315 +0200 +@@ -61,8 +61,9 @@ Create named pipes (FIFOs) with the give + -m, --mode=MODE set file permission bits to MODE, not a=rw - umask\n\ + "), stdout); + fputs (_("\ +- -Z, --context[=CTX] set the SELinux security context of each NAME to\n\ +- default type, or CTX if specified\n\ ++ -Z set the SELinux security context to default type\n\ ++ --context[=CTX] like -Z, or if CTX is specified then set the SELinux\n\ ++ or SMACK security context to CTX\n\ + "), stdout); + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); +diff -urNp coreutils-8.22-orig/src/mknod.c coreutils-8.22/src/mknod.c +--- coreutils-8.22-orig/src/mknod.c 2013-12-05 00:43:05.000000000 +0100 ++++ coreutils-8.22/src/mknod.c 2015-06-11 16:02:36.300982160 +0200 +@@ -63,8 +63,9 @@ Create the special file NAME of the give + -m, --mode=MODE set file permission bits to MODE, not a=rw - umask\n\ + "), stdout); + fputs (_("\ +- -Z, --context[=CTX] set the SELinux security context of NAME to\n\ +- default type, or to CTX if specified\n\ ++ -Z set the SELinux security context to default type\n\ ++ --context[=CTX] like -Z, or if CTX is specified then set the SELinux\n\ ++ or SMACK security context to CTX\n\ + "), stdout); + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); diff --git a/SOURCES/coreutils-8.22-vxfs-noinotify.patch b/SOURCES/coreutils-8.22-vxfs-noinotify.patch new file mode 100644 index 0000000..359331c --- /dev/null +++ b/SOURCES/coreutils-8.22-vxfs-noinotify.patch @@ -0,0 +1,12 @@ +diff -urNp coreutils-8.22-orig/src/fs-is-local.h coreutils-8.22/src/fs-is-local.h +--- coreutils-8.22-orig/src/fs-is-local.h 2013-12-13 15:17:10.000000000 +0100 ++++ coreutils-8.22/src/fs-is-local.h 2015-06-04 11:06:34.161072669 +0200 +@@ -98,7 +98,7 @@ is_local_fs_type (unsigned long int magi + case S_MAGIC_USBDEVFS: return 1; + case S_MAGIC_V9FS: return 1; + case S_MAGIC_VMHGFS: return 0; +- case S_MAGIC_VXFS: return 1; ++ case S_MAGIC_VXFS: return 0; + case S_MAGIC_VZFS: return 1; + case S_MAGIC_XENFS: return 1; + case S_MAGIC_XENIX: return 1; diff --git a/SOURCES/coreutils-colorls.csh b/SOURCES/coreutils-colorls.csh index 5ed0f68..f631762 100755 --- a/SOURCES/coreutils-colorls.csh +++ b/SOURCES/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,21 +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 --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 "`/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 -set color_none=`sed -n '/^COLOR.*none/Ip' < $COLORS` +cleanup: +set color_none=`/usr/bin/sed -n '/^COLOR.*none/Ip' < $COLORS` if ( "$color_none" != '' ) then unset color_none exit diff --git a/SOURCES/coreutils-colorls.sh b/SOURCES/coreutils-colorls.sh index 1308da9..cfd2288 100755 --- a/SOURCES/coreutils-colorls.sh +++ b/SOURCES/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" ] && \ @@ -32,17 +32,22 @@ 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="`/usr/bin/mktemp .colorlsXXX -q --tmpdir=/tmp`" + [ -z "$TMP" ] && return - [ -e "$INCLUDE" ] && 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 "`/usr/bin/dircolors --sh $COLORS 2>/dev/null`" + 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/SOURCES/coreutils-i18n.patch b/SOURCES/coreutils-i18n.patch index 20af4da..a3c7b33 100644 --- a/SOURCES/coreutils-i18n.patch +++ b/SOURCES/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 @@ -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. */ \ + \ @@ -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) } } @@ -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) + { @@ -238,10 +239,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); + } + } @@ -255,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,211 @@ cut_fields (FILE *stream) +@@ -629,13 +786,211 @@ cut_fields (FILE *stream) } } @@ -275,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; + @@ -357,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) @@ -400,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 @@ -439,7 +442,7 @@ 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 */ @@ -470,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 +1035,7 @@ main (int argc, char **argv) +@@ -687,6 +1042,7 @@ main (int argc, char **argv) bool ok; bool delim_specified = false; char *spec_list_string IF_LINT ( = NULL); @@ -478,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 +1058,6 @@ main (int argc, char **argv) +@@ -709,7 +1065,6 @@ main (int argc, char **argv) switch (optc) { case 'b': @@ -486,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 +1065,14 @@ main (int argc, char **argv) +@@ -717,6 +1072,14 @@ main (int argc, char **argv) spec_list_string = optarg; break; @@ -501,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 +1084,38 @@ main (int argc, char **argv) +@@ -728,10 +1091,38 @@ main (int argc, char **argv) case 'd': /* New delimiter. */ /* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */ @@ -544,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 +1128,7 @@ main (int argc, char **argv) +@@ -744,6 +1135,7 @@ main (int argc, char **argv) break; case 'n': @@ -552,7 +555,7 @@ diff -urNp coreutils-8.22-orig/src/cut.c coreutils-8.22/src/cut.c break; case 's': -@@ -783,15 +1168,34 @@ main (int argc, char **argv) +@@ -783,15 +1175,34 @@ main (int argc, char **argv) } if (!delim_specified) @@ -595,8 +598,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 @@ -606,6 +609,11 @@ diff -urNp coreutils-8.22-orig/src/expand.c coreutils-8.22/src/expand.c +# include +#endif + ++/* Get iswblank(). */ ++#if HAVE_WCTYPE_H ++# include ++#endif ++ #include "system.h" #include "error.h" #include "fadvise.h" @@ -626,7 +634,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) } } @@ -769,7 +777,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); @@ -785,7 +793,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 @@ -1126,7 +1134,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; @@ -1185,7 +1193,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 @@ -1255,7 +1263,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); } @@ -1276,7 +1284,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) + { @@ -1404,7 +1411,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. */ @@ -1499,9 +1506,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); @@ -1531,8 +1540,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) @@ -1559,7 +1568,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]; @@ -1571,7 +1580,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. */ @@ -1603,7 +1612,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; @@ -1611,7 +1620,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; @@ -1620,7 +1629,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': { @@ -1648,7 +1657,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]) { @@ -1679,8 +1688,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 @@ -1702,18 +1711,10 @@ diff -urNp coreutils-8.22-orig/src/pr.c coreutils-8.22/src/pr.c +# 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" @@ -1732,7 +1733,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; @@ -1754,7 +1755,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, @@ -1762,7 +1763,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); @@ -1770,7 +1771,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]. */ @@ -1779,7 +1780,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. */ @@ -1788,7 +1789,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. */ @@ -1800,7 +1801,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. */ @@ -1815,7 +1816,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; @@ -1823,7 +1824,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); @@ -1837,7 +1838,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); @@ -1859,7 +1860,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) @@ -1874,7 +1875,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) @@ -1889,7 +1890,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) @@ -1900,7 +1901,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 (""); @@ -1909,7 +1910,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 @@ -1957,7 +1958,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; @@ -1969,7 +1970,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; @@ -1978,7 +1979,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. */ @@ -1992,7 +1993,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 @@ -2001,7 +2002,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); @@ -2010,7 +2011,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. */ @@ -2019,7 +2020,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 { @@ -2028,7 +2029,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; @@ -2040,7 +2041,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); } @@ -2056,7 +2057,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. */ @@ -2085,7 +2086,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) { @@ -2094,7 +2095,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; @@ -2102,7 +2103,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) { @@ -2110,7 +2111,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 { @@ -2127,7 +2128,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 @@ -2136,7 +2137,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); } @@ -2211,7 +2212,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; } @@ -2223,7 +2224,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) } } @@ -2235,7 +2254,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]; @@ -2246,7 +2265,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 @@ -2255,7 +2274,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; @@ -2268,7 +2287,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; } @@ -2435,7 +2454,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-03 07:52:26.905202526 +0100 ++++ coreutils-8.22/src/sort.c 2014-01-08 13:55:56.123375301 +0100 @@ -29,6 +29,14 @@ #include #include @@ -2455,7 +2474,7 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/src/sort.c /* Thousands separator; if -1, then there isn't one. */ static int thousands_sep; -+/* True if -f was specified. */ ++/* True if -f is specified. */ +static bool folding; + /* Nonzero if the corresponding locales are hard. */ @@ -3085,7 +3104,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); @@ -3113,7 +3132,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 +3135,191 @@ keycompare (struct line const *a, struct +@@ -2695,6 +3135,209 @@ keycompare (struct line const *a, struct return key->reverse ? -diff : diff; } @@ -3218,13 +3237,16 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/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; + + 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; + @@ -3235,6 +3257,12 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/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); @@ -3258,13 +3286,22 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/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; @@ -3305,7 +3342,7 @@ 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,7 +3347,7 @@ compare (struct line const *a, struct li +@@ -2722,7 +3365,7 @@ compare (struct line const *a, struct li diff = - NONZERO (blen); else if (blen == 0) diff = 1; @@ -3314,15 +3351,15 @@ 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 -@@ -4112,6 +4737,7 @@ set_ordering (char const *s, struct keyf - key->ignore = nondictionary; +@@ -4113,6 +4756,7 @@ set_ordering (char const *s, struct keyf break; case 'f': -+ folding = true; key->translate = fold_toupper; ++ folding = true; break; case 'g': -@@ -4190,7 +4816,7 @@ main (int argc, char **argv) + key->general_numeric = true; +@@ -4190,7 +4834,7 @@ main (int argc, char **argv) initialize_exit_failure (SORT_FAILURE); hard_LC_COLLATE = hard_locale (LC_COLLATE); @@ -3331,7 +3368,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) +@@ -4211,6 +4855,29 @@ main (int argc, char **argv) thousands_sep = -1; } @@ -3361,7 +3398,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) +@@ -4485,13 +5152,34 @@ main (int argc, char **argv) case 't': { @@ -3400,7 +3437,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) +@@ -4502,9 +5190,12 @@ main (int argc, char **argv) quote (optarg)); } } @@ -3415,9 +3452,42 @@ diff -urNp coreutils-8.22-orig/src/sort.c coreutils-8.22/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.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 @@ -3675,8 +3745,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 @@ -3689,11 +3759,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" @@ -3714,7 +3785,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 }; @@ -3725,7 +3796,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 @@ -3734,7 +3805,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; } @@ -3818,7 +3889,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) { @@ -3827,7 +3898,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) { @@ -3909,9 +3980,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); @@ -3934,7 +4007,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,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; @@ -3959,57 +4032,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 +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 + +@@ -386,6 +600,10 @@ check_file (const char *infile, const ch + SWAP_LINES (prevline, thisline); + prevfield = thisfield; prevlen = thislen; - first_group_printed = true; - } +#if HAVE_MBRTOWC -+ } ++ if (MB_CUR_MAX > 1) ++ prevstate = thisstate; +#endif + first_group_printed = true; + } } - 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 +616,26 @@ check_file (const char *infile, const ch size_t prevlen; uintmax_t match_count = 0; bool first_delimiter = true; @@ -4036,7 +4084,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 +644,14 @@ check_file (const char *infile, const ch } thisfield = find_field (thisline); thislen = thisline->length - 1 - (thisfield - thisline->buffer); @@ -4051,7 +4099,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 +684,9 @@ check_file (const char *infile, const ch SWAP_LINES (prevline, thisline); prevfield = thisfield; prevlen = thislen; @@ -4061,7 +4109,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 +733,19 @@ main (int argc, char **argv) atexit (close_stdout); @@ -4082,19 +4130,20 @@ 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 -@@ -324,6 +324,7 @@ all_tests = \ +--- 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 +@@ -325,6 +325,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 -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; @@ -4119,7 +4168,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; @@ -4176,7 +4225,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|.*/||; @@ -4248,7 +4297,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'; @@ -4317,7 +4366,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. @@ -4366,7 +4415,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; @@ -4425,7 +4474,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; @@ -4443,7 +4492,18 @@ diff -urNp coreutils-8.22-orig/tests/misc/sort.pl coreutils-8.22/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 +424,38 @@ foreach my $t (@Tests) } } @@ -4473,6 +4533,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" 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; @@ -4481,7 +4542,7 @@ diff -urNp coreutils-8.22-orig/tests/misc/sort.pl coreutils-8.22/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) +@@ -424,6 +465,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; @@ -4491,7 +4552,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'; @@ -4547,7 +4608,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"; @@ -4566,7 +4627,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'}; } @@ -4593,8 +4654,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; @@ -4614,7 +4683,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'; diff --git a/SOURCES/coreutils-selinuxmanpages.patch b/SOURCES/coreutils-selinuxmanpages.patch index 7b27f90..6bd7aaa 100644 --- a/SOURCES/coreutils-selinuxmanpages.patch +++ b/SOURCES/coreutils-selinuxmanpages.patch @@ -13,3 +13,41 @@ diff -urNp coreutils-6.10-orig/doc/coreutils.texi coreutils-6.10/doc/coreutils.t @item --copy-contents @cindex directories, copying recursively @cindex copying directories recursively +diff -urNp coreutils-8.22-orig/doc/coreutils.texi coreutils-8.22/doc/coreutils.texi +--- coreutils-8.22-orig/doc/coreutils.texi 2015-06-12 14:16:22.672832509 +0200 ++++ coreutils-8.22/doc/coreutils.texi 2015-06-12 14:43:02.646303224 +0200 +@@ -7311,13 +7311,32 @@ it also affects the HP-UX @command{ls} p + + @item -Z + @itemx --context ++@itemx --scontext ++@itemx --lcontext ++@itemx --format=context + @opindex -Z + @opindex --context ++@opindex --format=security ++@opindex --scontext ++@opindex --lcontext + @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. ++@option{-Z} counts as format option and enables displaying of SELinux ++context. ++@option{--scontext} prints SELinux context left to the file name. ++@option{--lcontext} prints long format with SELinux context in the middle. ++@option{--context} prints permissions, user/group, context and file name (in comparison to @option{--lcontext}, omits size, modification time and number of hardlinks). ++ ++Note: When multiple format options are used in @command{ls}, ++the last one is used. Therefore @samp{ls -lZ} (security format ++is last - same as @samp{ls --context}) differs from @samp{ls -Zl} ++(long format with selinux context is shown, same as @samp{ls --lcontext}) ++ ++Do not rely on @option{--scontext} and @option{--lcontext} ++options in your scripts. They will be removed in next major ++version of Red Hat Enterprise Linux. @option{--context} behaviour ++will change (just enabling displaying SELinux context). + + @end table + diff --git a/SPECS/coreutils.spec b/SPECS/coreutils.spec index 71d280d..56c20eb 100644 --- a/SPECS/coreutils.spec +++ b/SPECS/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}.2 +Release: 15%{?dist} License: GPLv3+ Group: System Environment/Base Url: http://www.gnu.org/software/coreutils/ @@ -13,14 +13,24 @@ Source105: coreutils-colorls.sh Source106: coreutils-colorls.csh # From upstream +#Fix segfault in cp (in selinux context code) Patch1: coreutils-8.22-cp-selinux.patch +#Mark veritas filesystem as remote (use polling) +Patch2: coreutils-8.22-vxfs-noinotify.patch +#Fix sparse test on xfs and btrfs filesystems +Patch3: coreutils-8.22-xfs-tests.patch +#Add dd option for progress reporting +Patch4: coreutils-8.22-dd-progress.patch +#Separate -Z and --context options where necessary in --help and manpage +Patch5: coreutils-8.22-selinux-optionsseparate.patch +#Handle du bindmount cycles more gracefully +Patch6: coreutils-8.22-du-bindmountcycles.patch +#Prevent possible race condition for hardlinks in mv +Patch7: coreutils-8.22-mv-hardlinksrace.patch #Use new version of getdisk function in df (better results) -Patch2: coreutils-8.22-df-getdisk.patch +Patch8: coreutils-8.22-df-getdisk.patch #Use new version of find_mount_list function -Patch3: coreutils-8.22-df-filtermountlistupdate.patch -#fix dd sparse test false test failure on xfs and btrfs -Patch4: coreutils-8.22-xfs-tests.patch - +Patch9: coreutils-8.22-df-filtermountlistupdate.patch # Our patches #general patch to workaround koji build system issues @@ -37,6 +47,10 @@ Patch104: coreutils-df-direct.patch Patch107: coreutils-8.4-mkdir-modenote.patch #fix gnulib tests on ppc64le Patch108: coreutils-8.22-ppc64le.patch +#fix groups for session in id +Patch109: coreutils-8.22-id-groups.patch +#fix some non-default tests failing in beaker environment(#1247641) +Patch110: coreutils-8.22-non-defaulttests.patch # sh-utils #add info about TZ envvar to date manpage @@ -125,8 +139,6 @@ 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 @@ -137,9 +149,13 @@ the old GNU fileutils, sh-utils, and textutils packages. # From upstream %patch1 -p1 -b .nullcontext -%patch2 -p1 -b .getdisk -%patch3 -p1 -b .filtermnt -%patch4 -p1 -b .xfsfail +%patch2 -p1 -b .vxfs +%patch3 -p1 -b .xfs +%patch4 -p1 -b .progress +%patch6 -p1 -b .bindmount +%patch7 -p1 -b .race +%patch8 -p1 -b .getdisk +%patch9 -p1 -b .findmnt # Our patches %patch100 -p1 -b .configure @@ -149,6 +165,8 @@ the old GNU fileutils, sh-utils, and textutils packages. %patch104 -p1 -b .dfdirect %patch107 -p1 -b .mkdirmode %patch108 -p1 -b .ppc64le +%patch109 -p1 -b .groups +%patch110 -p1 -b .nondefault # sh-utils %patch703 -p1 -b .dateman @@ -165,8 +183,9 @@ the old GNU fileutils, sh-utils, and textutils packages. #SELinux %patch950 -p1 -b .selinux %patch951 -p1 -b .selinuxman +%patch5 -p1 -b .separate -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 tests/cp/no-ctx.sh tests/dd/stats.sh || : #fix typos/mistakes in localized documentation(#439410, #440056) find ./po/ -name "*.p*" | xargs \ @@ -387,9 +406,29 @@ fi %{_sbindir}/chroot %changelog -* Mon Jul 27 2015 Ondrej Vasik - 8.22-12.2 +* Sat Sep 12 2015 Ondrej Vasik - 8.22-15 +- fix one more occurance of non-full path in colorls.sh (#1222223) + +* Mon Aug 17 2015 Ondrej Vasik - 8.22-14 +- fix several failing non-default(root,expensive) tests (#1247641) + +* Mon Jul 06 2015 Ondrej Vasik - 8.22-13 +- call utilities in colorls.* scripts with full path (#1222223) +- tail: disable inotify in --follow for vxfs (#1109083) +- remove circular dependency for util-linux (not relevant for RHEL 7 - #1155963) +- sort: do not look at more than specified keys for mb locales (#1148347) +- i18n patch: fix buffer overruns and compiler warnings (#1148347) +- xfs: fix dd sparse false test failure on btrfs and xfs (#1223041) +- dd: new status=progress level to print stats periodically (#1147701) +- id/groups - print correct group for session (#1115430) +- cp,install,mknod,mkfifo,mkdir: separate -Z and --context options + in --help and manpage (#1084471) +- ls: clarify --scontext/--context/--lcontext options behaviour + in info documentation, mention deprecation (#1099508) +- du: handle bindmount cycles more gracefully (#1238191) +- mv: prevent possible race condition for hardlinks (#1166570) - df: improve filtering of NFS mounts and bind mounts - (#1247128) + (#1197463, #1100026, #1129661) * Tue Aug 05 2014 Ondrej Vasik - 8.22-12 - fix test failure on ppc64le (#1112687)