Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
Sebastian Kisela | b1830c7601 | |
Kamil Dudka | fbd3619072 | |
Kamil Dudka | ff7a1bf5b1 | |
Kamil Dudka | 1e1a10a04a | |
Kamil Dudka | 1ce862f0bb | |
Kamil Dudka | cd51eb58a5 | |
Kamil Dudka | fdd7dd0f39 | |
Kamil Dudka | f90bb3d8a4 | |
Jakub Martisko | fd67498083 | |
Jakub Martisko | fa93a02304 |
|
@ -1,6 +1,6 @@
|
|||
--- coreutils-5.92/src/date.c.langinfo 2005-09-16 09:06:57.000000000 +0100
|
||||
+++ coreutils-5.92/src/date.c 2005-10-24 18:09:16.000000000 +0100
|
||||
@@ -451,14 +451,7 @@
|
||||
@@ -474,14 +474,7 @@ main (int argc, char **argv)
|
||||
format = DATE_FMT_LANGINFO ();
|
||||
if (! *format)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-tests/gnulib.mk
|
||||
--- coreutils-8.21-orig/gnulib-tests/gnulib.mk 2013-02-07 17:58:44.000000000 +0100
|
||||
+++ coreutils-8.21/gnulib-tests/gnulib.mk 2013-02-15 10:12:28.110593165 +0100
|
||||
@@ -267,9 +267,9 @@ EXTRA_DIST += nap.h test-chown.h test-ch
|
||||
@@ -279,9 +279,9 @@ EXTRA_DIST += nap.h test-chown.h test-chown.c signature.h macros.h
|
||||
|
||||
## begin gnulib module cloexec-tests
|
||||
|
||||
|
@ -14,7 +14,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test
|
|||
|
||||
## end gnulib module cloexec-tests
|
||||
|
||||
@@ -378,9 +378,9 @@ EXTRA_DIST += test-dup.c signature.h mac
|
||||
@@ -392,9 +392,9 @@ EXTRA_DIST += test-dup.c signature.h macros.h
|
||||
|
||||
## begin gnulib module dup2-tests
|
||||
|
||||
|
@ -27,7 +27,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test
|
|||
|
||||
## end gnulib module dup2-tests
|
||||
|
||||
@@ -439,10 +439,10 @@ EXTRA_DIST += test-fadvise.c
|
||||
@@ -453,10 +453,10 @@ EXTRA_DIST += test-fadvise.c
|
||||
|
||||
## begin gnulib module fchdir-tests
|
||||
|
||||
|
@ -42,7 +42,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test
|
|||
|
||||
## end gnulib module fchdir-tests
|
||||
|
||||
@@ -874,9 +874,9 @@ EXTRA_DIST += test-getloadavg.c signatur
|
||||
@@ -900,9 +900,9 @@ EXTRA_DIST += test-getloadavg.c signature.h
|
||||
|
||||
## begin gnulib module getlogin-tests
|
||||
|
||||
|
@ -55,7 +55,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test
|
|||
|
||||
## end gnulib module getlogin-tests
|
||||
|
||||
@@ -1119,10 +1119,10 @@ EXTRA_DIST += test-link.h test-link.c si
|
||||
@@ -1147,10 +1147,10 @@ EXTRA_DIST += test-link.h test-link.c signature.h macros.h
|
||||
|
||||
## begin gnulib module linkat-tests
|
||||
|
||||
|
@ -70,7 +70,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test
|
|||
|
||||
## end gnulib module linkat-tests
|
||||
|
||||
@@ -1331,9 +1331,9 @@ EXTRA_DIST += test-memcoll.c macros.h
|
||||
@@ -1359,9 +1359,9 @@ EXTRA_DIST += test-memcoll.c macros.h
|
||||
|
||||
## begin gnulib module memrchr-tests
|
||||
|
||||
|
@ -83,7 +83,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test
|
|||
|
||||
## end gnulib module memrchr-tests
|
||||
|
||||
@@ -1978,9 +1978,9 @@ EXTRA_DIST += test-statat.c
|
||||
@@ -1912,9 +1912,9 @@ EXTRA_DIST += test-statat.c
|
||||
|
||||
## begin gnulib module stdalign-tests
|
||||
|
||||
|
@ -96,7 +96,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test
|
|||
|
||||
## end gnulib module stdalign-tests
|
||||
|
||||
@@ -2323,9 +2323,9 @@ EXTRA_DIST += test-uname.c signature.h m
|
||||
@@ -2269,9 +2269,9 @@ EXTRA_DIST += test-uname.c signature.h macros.h
|
||||
|
||||
## begin gnulib module unistd-safer-tests
|
||||
|
||||
|
@ -109,7 +109,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test
|
|||
|
||||
## end gnulib module unistd-safer-tests
|
||||
|
||||
@@ -2438,10 +2438,10 @@ EXTRA_DIST += test-usleep.c signature.h
|
||||
@@ -2367,10 +2367,10 @@ EXTRA_DIST += test-userspec.c
|
||||
|
||||
## begin gnulib module utimens-tests
|
||||
|
||||
|
@ -127,7 +127,7 @@ diff -urNp coreutils-8.21-orig/gnulib-tests/gnulib.mk coreutils-8.21/gnulib-test
|
|||
diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk
|
||||
--- coreutils-8.21-orig/tests/local.mk 2013-02-11 11:30:12.000000000 +0100
|
||||
+++ coreutils-8.21/tests/local.mk 2013-02-15 10:10:55.890532258 +0100
|
||||
@@ -131,6 +131,7 @@ all_root_tests = \
|
||||
@@ -134,6 +134,7 @@ all_root_tests = \
|
||||
tests/rm/no-give-up.sh \
|
||||
tests/rm/one-file-system.sh \
|
||||
tests/rm/read-only.sh \
|
||||
|
@ -135,7 +135,7 @@ diff -urNp coreutils-8.21-orig/tests/local.mk coreutils-8.21/tests/local.mk
|
|||
tests/tail-2/append-only.sh \
|
||||
tests/touch/now-owned-by-other.sh
|
||||
|
||||
@@ -163,7 +164,6 @@ all_tests = \
|
||||
@@ -168,7 +169,6 @@ all_tests = \
|
||||
tests/cp/link-heap.sh \
|
||||
tests/cp/no-ctx.sh \
|
||||
tests/misc/tty-eof.pl \
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
diff -urNp coreutils-6.12-orig/src/md5sum.c coreutils-6.12/src/md5sum.c
|
||||
--- coreutils-6.12-orig/src/md5sum.c 2008-05-26 08:40:33.000000000 +0200
|
||||
+++ coreutils-6.12/src/md5sum.c 2008-10-21 16:07:28.000000000 +0200
|
||||
@@ -175,6 +175,9 @@ With no FILE, or when FILE is -, read st
|
||||
@@ -200,6 +200,9 @@ Print or check %s (%d-bit) checksums.\n\
|
||||
fputs (_("\
|
||||
-t, --text read in text mode (default)\n\
|
||||
"), stdout);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c
|
||||
--- coreutils-8.2-orig/src/uname.c 2009-09-23 10:25:44.000000000 +0200
|
||||
+++ coreutils-8.2/src/uname.c 2009-12-19 09:09:11.663607110 +0100
|
||||
@@ -301,7 +301,7 @@ main (int argc, char **argv)
|
||||
@@ -299,13 +299,19 @@ main (int argc, char **argv)
|
||||
|
||||
if (toprint & PRINT_PROCESSOR)
|
||||
{
|
||||
|
@ -10,7 +10,6 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c
|
|||
#if HAVE_SYSINFO && defined SI_ARCHITECTURE
|
||||
{
|
||||
static char processor[257];
|
||||
@@ -308,6 +308,12 @@ main (int argc, char **argv)
|
||||
if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
|
||||
element = processor;
|
||||
}
|
||||
|
@ -23,7 +22,7 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c
|
|||
#endif
|
||||
#ifdef UNAME_PROCESSOR
|
||||
if (element == unknown)
|
||||
@@ -351,7 +357,7 @@ main (int argc, char **argv)
|
||||
@@ -343,7 +349,7 @@ main (int argc, char **argv)
|
||||
|
||||
if (toprint & PRINT_HARDWARE_PLATFORM)
|
||||
{
|
||||
|
@ -32,7 +31,7 @@ diff -urNp coreutils-8.2-orig/src/uname.c coreutils-8.2/src/uname.c
|
|||
#if HAVE_SYSINFO && defined SI_PLATFORM
|
||||
{
|
||||
static char hardware_platform[257];
|
||||
@@ -353,6 +359,14 @@ main (int argc, char **argv)
|
||||
@@ -351,6 +357,14 @@ main (int argc, char **argv)
|
||||
hardware_platform, sizeof hardware_platform))
|
||||
element = hardware_platform;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
From c424bbcb532c5b9924349e3522b3b431eaa7c178 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Fri, 8 Jul 2016 18:59:35 +0200
|
||||
Subject: [PATCH] install: with -Z, set default SELinux context for created
|
||||
directories
|
||||
|
||||
* doc/coreutils.texi (install invocation): Update -Z documentation.
|
||||
* src/install.c (make_ancestor): Set default security context before
|
||||
calling mkdir() if the -Z option is given.
|
||||
(process_dir): Call restorecon() on the destination directory if the
|
||||
-Z option is given.
|
||||
(usage): Update -Z documentation.
|
||||
* tests/install/install-Z-selinux.sh: A new test for 'install -Z -D'
|
||||
and 'install -Z -d' based on tests/mkdir/restorecon.sh.
|
||||
* tests/local.mk: Reference the test.
|
||||
* NEWS: Mention the improvement.
|
||||
Reported at https://bugzilla.redhat.com/1339135
|
||||
Fixes http://bugs.gnu.org/23868
|
||||
|
||||
Upstream-commit: 502518b44039138d148e2e15157d125c82d02af0
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
doc/coreutils.texi | 2 +-
|
||||
src/install.c | 33 ++++++++++++++++++----
|
||||
tests/install/install-Z-selinux.sh | 58 ++++++++++++++++++++++++++++++++++++++
|
||||
tests/local.mk | 1 +
|
||||
4 files changed, 88 insertions(+), 6 deletions(-)
|
||||
create mode 100644 tests/install/install-Z-selinux.sh
|
||||
|
||||
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
|
||||
index 092192c..1543f27 100644
|
||||
--- a/doc/coreutils.texi
|
||||
+++ b/doc/coreutils.texi
|
||||
@@ -9208,7 +9208,7 @@ Print the name of each file before moving it.
|
||||
@cindex security context
|
||||
This option functions similarly to the @command{restorecon} command,
|
||||
by adjusting the SELinux security context according
|
||||
-to the system default type for destination files.
|
||||
+to the system default type for destination files and each created directory.
|
||||
|
||||
@end table
|
||||
|
||||
diff --git a/src/install.c b/src/install.c
|
||||
index 089f298..1b7a209 100644
|
||||
--- a/src/install.c
|
||||
+++ b/src/install.c
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "prog-fprintf.h"
|
||||
#include "quote.h"
|
||||
#include "savewd.h"
|
||||
+#include "selinux.h"
|
||||
#include "stat-time.h"
|
||||
#include "utimens.h"
|
||||
#include "xstrtol.h"
|
||||
@@ -423,6 +424,12 @@ announce_mkdir (char const *dir, void *options)
|
||||
static int
|
||||
make_ancestor (char const *dir, char const *component, void *options)
|
||||
{
|
||||
+ struct cp_options const *x = options;
|
||||
+ if (x->set_security_context && defaultcon (dir, S_IFDIR) < 0
|
||||
+ && ! ignorable_ctx_err (errno))
|
||||
+ error (0, errno, _("failed to set default creation context for %s"),
|
||||
+ quoteaf (dir));
|
||||
+
|
||||
int r = mkdir (component, DEFAULT_MODE);
|
||||
if (r == 0)
|
||||
announce_mkdir (dir, options);
|
||||
@@ -433,12 +440,28 @@ make_ancestor (char const *dir, char const *component, void *options)
|
||||
static int
|
||||
process_dir (char *dir, struct savewd *wd, void *options)
|
||||
{
|
||||
- return (make_dir_parents (dir, wd,
|
||||
- make_ancestor, options,
|
||||
- dir_mode, announce_mkdir,
|
||||
- dir_mode_bits, owner_id, group_id, false)
|
||||
+ struct cp_options const *x = options;
|
||||
+
|
||||
+ int ret = (make_dir_parents (dir, wd, make_ancestor, options,
|
||||
+ dir_mode, announce_mkdir,
|
||||
+ dir_mode_bits, owner_id, group_id, false)
|
||||
? EXIT_SUCCESS
|
||||
: EXIT_FAILURE);
|
||||
+
|
||||
+ /* FIXME: Due to the current structure of make_dir_parents()
|
||||
+ we don't have the facility to call defaultcon() before the
|
||||
+ final component of DIR is created. So for now, create the
|
||||
+ final component with the context from previous component
|
||||
+ and here we set the context for the final component. */
|
||||
+ if (ret == EXIT_SUCCESS && x->set_security_context)
|
||||
+ {
|
||||
+ if (! restorecon (last_component (dir), false, false)
|
||||
+ && ! ignorable_ctx_err (errno))
|
||||
+ error (0, errno, _("failed to restore context for %s"),
|
||||
+ quoteaf (dir));
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/* Copy file FROM onto file TO, creating TO if necessary.
|
||||
@@ -651,7 +674,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\
|
||||
fputs (_("\
|
||||
-P, --preserve-context preserve SELinux security context (-P deprecated)\n\
|
||||
-Z set SELinux security context of destination\n\
|
||||
- file to default type\n\
|
||||
+ file and each created directory to default type\n\
|
||||
--context[=CTX] like -Z, or if CTX is specified then set the\n\
|
||||
SELinux or SMACK security context to CTX\n\
|
||||
"), stdout);
|
||||
diff --git a/tests/install/install-Z-selinux.sh b/tests/install/install-Z-selinux.sh
|
||||
new file mode 100644
|
||||
index 0000000..9c3b642
|
||||
--- /dev/null
|
||||
+++ b/tests/install/install-Z-selinux.sh
|
||||
@@ -0,0 +1,58 @@
|
||||
+#!/bin/sh
|
||||
+# test 'install -Z -D' and 'install -Z -d'
|
||||
+# based on tests/mkdir/restorecon.sh
|
||||
+
|
||||
+# Copyright (C) 2013-2016 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software: you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation, either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
|
||||
+print_ver_ ginstall
|
||||
+require_selinux_
|
||||
+
|
||||
+
|
||||
+get_selinux_type() { ls -Zd "$1" | sed -n 's/.*:\(.*_t\):.*/\1/p'; }
|
||||
+
|
||||
+mkdir subdir || framework_failure_
|
||||
+chcon 'root:object_r:tmp_t:s0' subdir || framework_failure_
|
||||
+cd subdir
|
||||
+
|
||||
+# Since in a tmp_t dir, dirs can be created as user_tmp_t ...
|
||||
+touch standard || framework_failure_
|
||||
+mkdir restored || framework_failure_
|
||||
+if restorecon restored 2>/dev/null; then
|
||||
+ # ... but when restored can be set to user_home_t
|
||||
+ # So ensure the type for these mkdir -Z cases matches
|
||||
+ # the directory type as set by restorecon.
|
||||
+ ginstall -Z standard single || fail=1
|
||||
+ ginstall -Z -d single_d || fail=1
|
||||
+ # Run these as separate processes in case global context
|
||||
+ # set for an arg, impacts on another arg
|
||||
+ # TODO: Have the defaultcon() vary over these directories
|
||||
+ for dst in single_d/existing/file multi/ple/file; do
|
||||
+ ginstall -Z -D standard "$dst" || fail=1
|
||||
+ done
|
||||
+ restored_type=$(get_selinux_type 'restored')
|
||||
+ test "$(get_selinux_type 'single')" = "$restored_type" || fail=1
|
||||
+ test "$(get_selinux_type 'single_d')" = "$restored_type" || fail=1
|
||||
+ test "$(get_selinux_type 'single_d/existing')" = "$restored_type" || fail=1
|
||||
+ test "$(get_selinux_type 'multi')" = "$restored_type" || fail=1
|
||||
+ test "$(get_selinux_type 'multi/ple')" = "$restored_type" || fail=1
|
||||
+fi
|
||||
+if test "$fail" = '1'; then
|
||||
+ ls -UZd standard restored
|
||||
+ ls -UZd single single_d single_d/existing multi multi/ple
|
||||
+fi
|
||||
+
|
||||
+Exit $fail
|
||||
diff --git a/tests/local.mk b/tests/local.mk
|
||||
index ec23448..42d39f2 100644
|
||||
--- a/tests/local.mk
|
||||
+++ b/tests/local.mk
|
||||
@@ -548,6 +548,7 @@ all_tests = \
|
||||
tests/install/d-slashdot.sh \
|
||||
tests/install/install-C.sh \
|
||||
tests/install/install-C-selinux.sh \
|
||||
+ tests/install/install-Z-selinux.sh \
|
||||
tests/install/strip-program.sh \
|
||||
tests/install/trap.sh \
|
||||
tests/ln/backup-1.sh \
|
||||
--
|
||||
2.5.5
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
From 9338b244572e07bbff314b3570228e8cf43f1300 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Tue, 6 Sep 2016 17:38:26 +0200
|
||||
Subject: [PATCH] ls: allow interruption when reading slow directories
|
||||
|
||||
Postpone installation of signal handlers until they're needed.
|
||||
That is right before the first escape sequence is printed.
|
||||
|
||||
* src/ls.c (signal_setup): A new function refactored from main()
|
||||
to set and restore signal handlers.
|
||||
(main): Move signal handler setup to put_indicator()
|
||||
so that the default signal handling is untouched as long as possible.
|
||||
Adjusted condition for restoring signal handlers to reflect the change.
|
||||
(put_indicator): Install signal handlers if called for the very first
|
||||
time. It uses the same code that was in main() prior to this commit.
|
||||
* NEWS: Mention the improvement.
|
||||
|
||||
See https://bugzilla.redhat.com/1365933
|
||||
Fixes http://bugs.gnu.org/24232
|
||||
|
||||
Upstream-commit: 5445f7811ff945ea13aa2a0fd797eb4c0a0e4db0
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
src/ls.c | 161 ++++++++++++++++++++++++++++++++++++---------------------------
|
||||
1 file changed, 93 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/src/ls.c b/src/ls.c
|
||||
index d976036..66df307 100644
|
||||
--- a/src/ls.c
|
||||
+++ b/src/ls.c
|
||||
@@ -1244,13 +1244,12 @@ process_signals (void)
|
||||
}
|
||||
}
|
||||
|
||||
-int
|
||||
-main (int argc, char **argv)
|
||||
-{
|
||||
- int i;
|
||||
- struct pending *thispend;
|
||||
- int n_files;
|
||||
+/* Setup signal handlers if INIT is true,
|
||||
+ otherwise restore to the default. */
|
||||
|
||||
+static void
|
||||
+signal_setup (bool init)
|
||||
+{
|
||||
/* The signals that are trapped, and the number of such signals. */
|
||||
static int const sig[] =
|
||||
{
|
||||
@@ -1278,8 +1277,77 @@ main (int argc, char **argv)
|
||||
enum { nsigs = ARRAY_CARDINALITY (sig) };
|
||||
|
||||
#if ! SA_NOCLDSTOP
|
||||
- bool caught_sig[nsigs];
|
||||
+ static bool caught_sig[nsigs];
|
||||
+#endif
|
||||
+
|
||||
+ int j;
|
||||
+
|
||||
+ if (init)
|
||||
+ {
|
||||
+#if SA_NOCLDSTOP
|
||||
+ struct sigaction act;
|
||||
+
|
||||
+ sigemptyset (&caught_signals);
|
||||
+ for (j = 0; j < nsigs; j++)
|
||||
+ {
|
||||
+ sigaction (sig[j], NULL, &act);
|
||||
+ if (act.sa_handler != SIG_IGN)
|
||||
+ sigaddset (&caught_signals, sig[j]);
|
||||
+ }
|
||||
+
|
||||
+ act.sa_mask = caught_signals;
|
||||
+ act.sa_flags = SA_RESTART;
|
||||
+
|
||||
+ for (j = 0; j < nsigs; j++)
|
||||
+ if (sigismember (&caught_signals, sig[j]))
|
||||
+ {
|
||||
+ act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler;
|
||||
+ sigaction (sig[j], &act, NULL);
|
||||
+ }
|
||||
+#else
|
||||
+ for (j = 0; j < nsigs; j++)
|
||||
+ {
|
||||
+ caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN);
|
||||
+ if (caught_sig[j])
|
||||
+ {
|
||||
+ signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler);
|
||||
+ siginterrupt (sig[j], 0);
|
||||
+ }
|
||||
+ }
|
||||
#endif
|
||||
+ }
|
||||
+ else /* restore. */
|
||||
+ {
|
||||
+#if SA_NOCLDSTOP
|
||||
+ for (j = 0; j < nsigs; j++)
|
||||
+ if (sigismember (&caught_signals, sig[j]))
|
||||
+ signal (sig[j], SIG_DFL);
|
||||
+#else
|
||||
+ for (j = 0; j < nsigs; j++)
|
||||
+ if (caught_sig[j])
|
||||
+ signal (sig[j], SIG_DFL);
|
||||
+#endif
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+signal_init (void)
|
||||
+{
|
||||
+ signal_setup (true);
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+signal_restore (void)
|
||||
+{
|
||||
+ signal_setup (false);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main (int argc, char **argv)
|
||||
+{
|
||||
+ int i;
|
||||
+ struct pending *thispend;
|
||||
+ int n_files;
|
||||
|
||||
initialize_main (&argc, &argv);
|
||||
set_program_name (argv[0]);
|
||||
@@ -1314,46 +1382,6 @@ main (int argc, char **argv)
|
||||
|| (is_colored (C_EXEC) && color_symlink_as_referent)
|
||||
|| (is_colored (C_MISSING) && format == long_format))
|
||||
check_symlink_color = true;
|
||||
-
|
||||
- /* If the standard output is a controlling terminal, watch out
|
||||
- for signals, so that the colors can be restored to the
|
||||
- default state if "ls" is suspended or interrupted. */
|
||||
-
|
||||
- if (0 <= tcgetpgrp (STDOUT_FILENO))
|
||||
- {
|
||||
- int j;
|
||||
-#if SA_NOCLDSTOP
|
||||
- struct sigaction act;
|
||||
-
|
||||
- sigemptyset (&caught_signals);
|
||||
- for (j = 0; j < nsigs; j++)
|
||||
- {
|
||||
- sigaction (sig[j], NULL, &act);
|
||||
- if (act.sa_handler != SIG_IGN)
|
||||
- sigaddset (&caught_signals, sig[j]);
|
||||
- }
|
||||
-
|
||||
- act.sa_mask = caught_signals;
|
||||
- act.sa_flags = SA_RESTART;
|
||||
-
|
||||
- for (j = 0; j < nsigs; j++)
|
||||
- if (sigismember (&caught_signals, sig[j]))
|
||||
- {
|
||||
- act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler;
|
||||
- sigaction (sig[j], &act, NULL);
|
||||
- }
|
||||
-#else
|
||||
- for (j = 0; j < nsigs; j++)
|
||||
- {
|
||||
- caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN);
|
||||
- if (caught_sig[j])
|
||||
- {
|
||||
- signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler);
|
||||
- siginterrupt (sig[j], 0);
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
- }
|
||||
}
|
||||
|
||||
if (dereference == DEREF_UNDEFINED)
|
||||
@@ -1466,32 +1494,21 @@ main (int argc, char **argv)
|
||||
print_dir_name = true;
|
||||
}
|
||||
|
||||
- if (print_with_color)
|
||||
+ if (print_with_color && used_color)
|
||||
{
|
||||
int j;
|
||||
|
||||
- if (used_color)
|
||||
- {
|
||||
- /* Skip the restore when it would be a no-op, i.e.,
|
||||
- when left is "\033[" and right is "m". */
|
||||
- if (!(color_indicator[C_LEFT].len == 2
|
||||
- && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0
|
||||
- && color_indicator[C_RIGHT].len == 1
|
||||
- && color_indicator[C_RIGHT].string[0] == 'm'))
|
||||
- restore_default_color ();
|
||||
- }
|
||||
+ /* Skip the restore when it would be a no-op, i.e.,
|
||||
+ when left is "\033[" and right is "m". */
|
||||
+ if (!(color_indicator[C_LEFT].len == 2
|
||||
+ && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0
|
||||
+ && color_indicator[C_RIGHT].len == 1
|
||||
+ && color_indicator[C_RIGHT].string[0] == 'm'))
|
||||
+ restore_default_color ();
|
||||
+
|
||||
fflush (stdout);
|
||||
|
||||
- /* Restore the default signal handling. */
|
||||
-#if SA_NOCLDSTOP
|
||||
- for (j = 0; j < nsigs; j++)
|
||||
- if (sigismember (&caught_signals, sig[j]))
|
||||
- signal (sig[j], SIG_DFL);
|
||||
-#else
|
||||
- for (j = 0; j < nsigs; j++)
|
||||
- if (caught_sig[j])
|
||||
- signal (sig[j], SIG_DFL);
|
||||
-#endif
|
||||
+ signal_restore ();
|
||||
|
||||
/* Act on any signals that arrived before the default was restored.
|
||||
This can process signals out of order, but there doesn't seem to
|
||||
@@ -4482,6 +4499,14 @@ put_indicator (const struct bin_str *ind)
|
||||
if (! used_color)
|
||||
{
|
||||
used_color = true;
|
||||
+
|
||||
+ /* If the standard output is a controlling terminal, watch out
|
||||
+ for signals, so that the colors can be restored to the
|
||||
+ default state if "ls" is suspended or interrupted. */
|
||||
+
|
||||
+ if (0 <= tcgetpgrp (STDOUT_FILENO))
|
||||
+ signal_init ();
|
||||
+
|
||||
prep_non_filename_text ();
|
||||
}
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
From 8b89985a3904e0267750c430e01684edf008051b Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Mon, 28 Nov 2016 16:21:42 +0100
|
||||
Subject: [PATCH] install,mkdir: fix handling of -DZ and -pZ, respectively
|
||||
|
||||
... in the case where two or more directories nested in each other are
|
||||
created and each of them defaults to a different SELinux context.
|
||||
|
||||
* src/install.c (make_ancestor): When calling defaultcon(), give it the
|
||||
same path that is given to mkdir(). The other path is not always valid
|
||||
wrt. current working directory.
|
||||
* src/mkdir.c (make_ancestor): Likewise.
|
||||
* NEWS: Mention the bug fix.
|
||||
|
||||
Reported at https://bugzilla.redhat.com/1398913
|
||||
|
||||
Upstream-commit: d8104265f229ababd5a68a46eeccbccc07e72cdc
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
src/install.c | 2 +-
|
||||
src/mkdir.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/install.c b/src/install.c
|
||||
index 1b7a209..cae0a53 100644
|
||||
--- a/src/install.c
|
||||
+++ b/src/install.c
|
||||
@@ -425,7 +425,7 @@ static int
|
||||
make_ancestor (char const *dir, char const *component, void *options)
|
||||
{
|
||||
struct cp_options const *x = options;
|
||||
- if (x->set_security_context && defaultcon (dir, S_IFDIR) < 0
|
||||
+ if (x->set_security_context && defaultcon (component, S_IFDIR) < 0
|
||||
&& ! ignorable_ctx_err (errno))
|
||||
error (0, errno, _("failed to set default creation context for %s"),
|
||||
quoteaf (dir));
|
||||
diff --git a/src/mkdir.c b/src/mkdir.c
|
||||
index 60fc08a..77af857 100644
|
||||
--- a/src/mkdir.c
|
||||
+++ b/src/mkdir.c
|
||||
@@ -122,7 +122,7 @@ make_ancestor (char const *dir, char const *component, void *options)
|
||||
{
|
||||
struct mkdir_options const *o = options;
|
||||
|
||||
- if (o->set_security_context && defaultcon (dir, S_IFDIR) < 0
|
||||
+ if (o->set_security_context && defaultcon (component, S_IFDIR) < 0
|
||||
&& ! ignorable_ctx_err (errno))
|
||||
error (0, errno, _("failed to set default creation context for %s"),
|
||||
quoteaf (dir));
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -0,0 +1,332 @@
|
|||
From c479153d77b419a6cae4551b63d2b73096c1130e Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Mon, 18 Jul 2016 19:04:43 +0200
|
||||
Subject: [PATCH 1/3] maint: sort.c: deduplicate code for traversing numbers
|
||||
|
||||
* src/sort.c (traverse_raw_number): New function for traversing numbers.
|
||||
(find_unit_order): Use traverse_raw_number() instead of open-coding it.
|
||||
(debug_key): Likewise.
|
||||
---
|
||||
src/sort.c | 63 ++++++++++++++++++++++++++++++++++----------------------------
|
||||
1 file changed, 35 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/src/sort.c b/src/sort.c
|
||||
index 5b02343..e28bb6c 100644
|
||||
--- a/src/sort.c
|
||||
+++ b/src/sort.c
|
||||
@@ -2231,18 +2231,16 @@ static char const unit_order[UCHAR_LIM] =
|
||||
#endif
|
||||
};
|
||||
|
||||
-/* Return an integer that represents the order of magnitude of the
|
||||
- unit following the number. The number may contain thousands
|
||||
- separators and a decimal point, but it may not contain leading blanks.
|
||||
- Negative numbers get negative orders; zero numbers have a zero order. */
|
||||
-
|
||||
-static int _GL_ATTRIBUTE_PURE
|
||||
-find_unit_order (char const *number)
|
||||
+/* Traverse number given as *number consisting of digits, thousands_sep, and
|
||||
+ decimal_point chars only. Returns the highest digit found in the number,
|
||||
+ or '\0' if no digit has been found. Upon return *number points at the
|
||||
+ character that immediately follows after the given number. */
|
||||
+static unsigned char
|
||||
+traverse_raw_number (char const **number)
|
||||
{
|
||||
- bool minus_sign = (*number == '-');
|
||||
- char const *p = number + minus_sign;
|
||||
- int nonzero = 0;
|
||||
+ char const *p = *number;
|
||||
unsigned char ch;
|
||||
+ unsigned char max_digit = '\0';
|
||||
|
||||
/* Scan to end of number.
|
||||
Decimals or separators not followed by digits stop the scan.
|
||||
@@ -2253,16 +2251,34 @@ find_unit_order (char const *number)
|
||||
do
|
||||
{
|
||||
while (ISDIGIT (ch = *p++))
|
||||
- nonzero |= ch - '0';
|
||||
+ if (max_digit < ch)
|
||||
+ max_digit = ch;
|
||||
}
|
||||
while (ch == thousands_sep);
|
||||
|
||||
if (ch == decimal_point)
|
||||
while (ISDIGIT (ch = *p++))
|
||||
- nonzero |= ch - '0';
|
||||
+ if (max_digit < ch)
|
||||
+ max_digit = ch;
|
||||
+
|
||||
+ *number = p - 1;
|
||||
+ return max_digit;
|
||||
+}
|
||||
+
|
||||
+/* Return an integer that represents the order of magnitude of the
|
||||
+ unit following the number. The number may contain thousands
|
||||
+ separators and a decimal point, but it may not contain leading blanks.
|
||||
+ Negative numbers get negative orders; zero numbers have a zero order. */
|
||||
|
||||
- if (nonzero)
|
||||
+static int _GL_ATTRIBUTE_PURE
|
||||
+find_unit_order (char const *number)
|
||||
+{
|
||||
+ bool minus_sign = (*number == '-');
|
||||
+ char const *p = number + minus_sign;
|
||||
+ unsigned char max_digit = traverse_raw_number (&p);
|
||||
+ if ('0' < max_digit)
|
||||
{
|
||||
+ unsigned char ch = *p;
|
||||
int order = unit_order[ch];
|
||||
return (minus_sign ? -order : order);
|
||||
}
|
||||
@@ -2655,23 +2671,14 @@ debug_key (struct line const *line, struct keyfield const *key)
|
||||
ignore_value (strtold (beg, &tighter_lim));
|
||||
else if (key->numeric || key->human_numeric)
|
||||
{
|
||||
- char *p = beg + (beg < lim && *beg == '-');
|
||||
- bool found_digit = false;
|
||||
- unsigned char ch;
|
||||
-
|
||||
- do
|
||||
+ char const *p = beg + (beg < lim && *beg == '-');
|
||||
+ unsigned char max_digit = traverse_raw_number (&p);
|
||||
+ if ('0' <= max_digit)
|
||||
{
|
||||
- while (ISDIGIT (ch = *p++))
|
||||
- found_digit = true;
|
||||
+ unsigned char ch = *p;
|
||||
+ tighter_lim = (char *) p
|
||||
+ + (key->human_numeric && unit_order[ch]);
|
||||
}
|
||||
- while (ch == thousands_sep);
|
||||
-
|
||||
- if (ch == decimal_point)
|
||||
- while (ISDIGIT (ch = *p++))
|
||||
- found_digit = true;
|
||||
-
|
||||
- if (found_digit)
|
||||
- tighter_lim = p - ! (key->human_numeric && unit_order[ch]);
|
||||
}
|
||||
else
|
||||
tighter_lim = lim;
|
||||
--
|
||||
2.5.5
|
||||
|
||||
|
||||
From 8c39465a5b0343ff7a21286dd69ed5430685d2f7 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Mon, 18 Jul 2016 19:04:44 +0200
|
||||
Subject: [PATCH 2/3] sort: make -h work with -k and blank used as thousands
|
||||
separator
|
||||
|
||||
* src/sort.c (traverse_raw_number): Allow to skip only one occurrence
|
||||
of thousands_sep to avoid finding the unit in the next column in case
|
||||
thousands_sep matches as blank and is used as column delimiter.
|
||||
* tests/misc/sort-h-thousands-sep.sh: Add regression test for this bug.
|
||||
* tests/local.mk: Reference the test.
|
||||
* NEWS: Mention the bug fix.
|
||||
Reported at https://bugzilla.redhat.com/1355780
|
||||
Fixes http://bugs.gnu.org/24015
|
||||
---
|
||||
src/sort.c | 14 ++++++++----
|
||||
tests/local.mk | 1 +
|
||||
tests/misc/sort-h-thousands-sep.sh | 47 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 57 insertions(+), 5 deletions(-)
|
||||
create mode 100755 tests/misc/sort-h-thousands-sep.sh
|
||||
|
||||
diff --git a/src/sort.c b/src/sort.c
|
||||
index e28bb6c..dd3ba58 100644
|
||||
--- a/src/sort.c
|
||||
+++ b/src/sort.c
|
||||
@@ -2248,13 +2248,17 @@ traverse_raw_number (char const **number)
|
||||
to be lacking in units.
|
||||
FIXME: add support for multibyte thousands_sep and decimal_point. */
|
||||
|
||||
- do
|
||||
+ while (ISDIGIT (ch = *p++))
|
||||
{
|
||||
- while (ISDIGIT (ch = *p++))
|
||||
- if (max_digit < ch)
|
||||
- max_digit = ch;
|
||||
+ if (max_digit < ch)
|
||||
+ max_digit = ch;
|
||||
+
|
||||
+ /* Allow to skip only one occurrence of thousands_sep to avoid finding
|
||||
+ the unit in the next column in case thousands_sep matches as blank
|
||||
+ and is used as column delimiter. */
|
||||
+ if (*p == thousands_sep)
|
||||
+ ++p;
|
||||
}
|
||||
- while (ch == thousands_sep);
|
||||
|
||||
if (ch == decimal_point)
|
||||
while (ISDIGIT (ch = *p++))
|
||||
diff --git a/tests/local.mk b/tests/local.mk
|
||||
index 42d39f2..dccff8d 100644
|
||||
--- a/tests/local.mk
|
||||
+++ b/tests/local.mk
|
||||
@@ -344,6 +344,7 @@ all_tests = \
|
||||
tests/misc/sort-discrim.sh \
|
||||
tests/misc/sort-files0-from.pl \
|
||||
tests/misc/sort-float.sh \
|
||||
+ tests/misc/sort-h-thousands-sep.sh \
|
||||
tests/misc/sort-mb-tests.sh \
|
||||
tests/i18n/sort.sh \
|
||||
tests/misc/sort-merge.pl \
|
||||
diff --git a/tests/misc/sort-h-thousands-sep.sh b/tests/misc/sort-h-thousands-sep.sh
|
||||
new file mode 100755
|
||||
index 0000000..17f1b6c
|
||||
--- /dev/null
|
||||
+++ b/tests/misc/sort-h-thousands-sep.sh
|
||||
@@ -0,0 +1,47 @@
|
||||
+#!/bin/sh
|
||||
+# exercise 'sort -h' in locales where thousands separator is blank
|
||||
+
|
||||
+# Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software: you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation, either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
|
||||
+print_ver_ sort
|
||||
+test "$(LC_ALL=sv_SE locale thousands_sep)" = ' ' \
|
||||
+ || skip_ 'The Swedish locale with blank thousands separator is unavailable.'
|
||||
+
|
||||
+tee exp1 > in << _EOF_
|
||||
+1 1k 4 003 1M
|
||||
+2k 2M 4 002 2
|
||||
+3M 3 4 001 3k
|
||||
+_EOF_
|
||||
+
|
||||
+cat > exp2 << _EOF_
|
||||
+3M 3 4 001 3k
|
||||
+1 1k 4 003 1M
|
||||
+2k 2M 4 002 2
|
||||
+_EOF_
|
||||
+
|
||||
+cat > exp3 << _EOF_
|
||||
+3M 3 4 001 3k
|
||||
+2k 2M 4 002 2
|
||||
+1 1k 4 003 1M
|
||||
+_EOF_
|
||||
+
|
||||
+for i in 1 2 3; do
|
||||
+ LC_ALL="sv_SE.utf8" sort -h -k $i "in" > "out${i}" || fail=1
|
||||
+ compare "exp${i}" "out${i}" || fail=1
|
||||
+done
|
||||
+
|
||||
+Exit $fail
|
||||
--
|
||||
2.5.5
|
||||
|
||||
|
||||
From 46ef53f558e7bc1c0bc0abd62a86b40b4141e058 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Mon, 18 Jul 2016 19:04:45 +0200
|
||||
Subject: [PATCH 3/3] sort: with -h, disallow thousands separator between
|
||||
number and unit
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
* src/sort.c (traverse_raw_number): Accept thousands separator only
|
||||
if it is immediately followed by a digit.
|
||||
* tests/misc/sort-h-thousands-sep.sh: Cover the fix for this bug.
|
||||
|
||||
Suggested by Pádraig Brady in http://bugs.gnu.org/24015
|
||||
---
|
||||
src/sort.c | 11 ++++++++++-
|
||||
tests/misc/sort-h-thousands-sep.sh | 25 +++++++++++++------------
|
||||
2 files changed, 23 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/sort.c b/src/sort.c
|
||||
index dd3ba58..69ef75f 100644
|
||||
--- a/src/sort.c
|
||||
+++ b/src/sort.c
|
||||
@@ -2241,6 +2241,7 @@ traverse_raw_number (char const **number)
|
||||
char const *p = *number;
|
||||
unsigned char ch;
|
||||
unsigned char max_digit = '\0';
|
||||
+ bool ends_with_thousands_sep = false;
|
||||
|
||||
/* Scan to end of number.
|
||||
Decimals or separators not followed by digits stop the scan.
|
||||
@@ -2256,10 +2257,18 @@ traverse_raw_number (char const **number)
|
||||
/* Allow to skip only one occurrence of thousands_sep to avoid finding
|
||||
the unit in the next column in case thousands_sep matches as blank
|
||||
and is used as column delimiter. */
|
||||
- if (*p == thousands_sep)
|
||||
+ ends_with_thousands_sep = (*p == thousands_sep);
|
||||
+ if (ends_with_thousands_sep)
|
||||
++p;
|
||||
}
|
||||
|
||||
+ if (ends_with_thousands_sep)
|
||||
+ {
|
||||
+ /* thousands_sep not followed by digit is not allowed. */
|
||||
+ *number = p - 2;
|
||||
+ return max_digit;
|
||||
+ }
|
||||
+
|
||||
if (ch == decimal_point)
|
||||
while (ISDIGIT (ch = *p++))
|
||||
if (max_digit < ch)
|
||||
diff --git a/tests/misc/sort-h-thousands-sep.sh b/tests/misc/sort-h-thousands-sep.sh
|
||||
index 17f1b6c..3ffa89e 100755
|
||||
--- a/tests/misc/sort-h-thousands-sep.sh
|
||||
+++ b/tests/misc/sort-h-thousands-sep.sh
|
||||
@@ -18,28 +18,29 @@
|
||||
|
||||
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
|
||||
print_ver_ sort
|
||||
+
|
||||
test "$(LC_ALL=sv_SE locale thousands_sep)" = ' ' \
|
||||
|| skip_ 'The Swedish locale with blank thousands separator is unavailable.'
|
||||
|
||||
-tee exp1 > in << _EOF_
|
||||
-1 1k 4 003 1M
|
||||
-2k 2M 4 002 2
|
||||
-3M 3 4 001 3k
|
||||
+tee exp1 exp3 > in << _EOF_
|
||||
+1 1k 1 M 4 003 1M
|
||||
+2k 2M 2 k 4 002 2
|
||||
+3M 3 3 G 4 001 3k
|
||||
_EOF_
|
||||
|
||||
cat > exp2 << _EOF_
|
||||
-3M 3 4 001 3k
|
||||
-1 1k 4 003 1M
|
||||
-2k 2M 4 002 2
|
||||
+3M 3 3 G 4 001 3k
|
||||
+1 1k 1 M 4 003 1M
|
||||
+2k 2M 2 k 4 002 2
|
||||
_EOF_
|
||||
|
||||
-cat > exp3 << _EOF_
|
||||
-3M 3 4 001 3k
|
||||
-2k 2M 4 002 2
|
||||
-1 1k 4 003 1M
|
||||
+cat > exp5 << _EOF_
|
||||
+3M 3 3 G 4 001 3k
|
||||
+2k 2M 2 k 4 002 2
|
||||
+1 1k 1 M 4 003 1M
|
||||
_EOF_
|
||||
|
||||
-for i in 1 2 3; do
|
||||
+for i in 1 2 3 5; do
|
||||
LC_ALL="sv_SE.utf8" sort -h -k $i "in" > "out${i}" || fail=1
|
||||
compare "exp${i}" "out${i}" || fail=1
|
||||
done
|
||||
--
|
||||
2.5.5
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
From 1e1a69da31b39e4d672ccb8a3ca0e5400d4720ee Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <P@draigBrady.com>
|
||||
Date: Wed, 26 Oct 2016 15:45:01 +0100
|
||||
Subject: [PATCH] md5sum,sha*sum: fix --ignore-missing with checksums starting
|
||||
with 00
|
||||
|
||||
* NEWS: Mention the fix.
|
||||
* src/md5sum.c (digest_file): Add a new MISSING parameter to
|
||||
return whether the file was missing, separately from the digest.
|
||||
* tests/misc/md5sum.pl: Add a test case.
|
||||
Fixes http://bugs.gnu.org/24795
|
||||
|
||||
Upstream-commit: d0ddfadfb27def2861f35b1a45190a4c1780b257
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
src/md5sum.c | 20 ++++++++++++--------
|
||||
tests/misc/md5sum.pl | 7 +++++++
|
||||
2 files changed, 19 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/md5sum.c b/src/md5sum.c
|
||||
index 933ec99..fee28c7 100644
|
||||
--- a/src/md5sum.c
|
||||
+++ b/src/md5sum.c
|
||||
@@ -465,15 +465,19 @@ print_filename (char const *file, bool escape)
|
||||
text because it was a terminal.
|
||||
|
||||
Put the checksum in *BIN_RESULT, which must be properly aligned.
|
||||
+ Put true in *MISSING if the file can't be opened due to ENOENT.
|
||||
Return true if successful. */
|
||||
|
||||
static bool
|
||||
-digest_file (const char *filename, int *binary, unsigned char *bin_result)
|
||||
+digest_file (const char *filename, int *binary, unsigned char *bin_result,
|
||||
+ bool *missing)
|
||||
{
|
||||
FILE *fp;
|
||||
int err;
|
||||
bool is_stdin = STREQ (filename, "-");
|
||||
|
||||
+ *missing = false;
|
||||
+
|
||||
if (is_stdin)
|
||||
{
|
||||
have_read_stdin = true;
|
||||
@@ -493,7 +497,7 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result)
|
||||
{
|
||||
if (ignore_missing && errno == ENOENT)
|
||||
{
|
||||
- *bin_result = '\0';
|
||||
+ *missing = true;
|
||||
return true;
|
||||
}
|
||||
error (0, errno, "%s", quotef (filename));
|
||||
@@ -606,14 +610,14 @@ digest_check (const char *checkfile_name)
|
||||
'8', '9', 'a', 'b',
|
||||
'c', 'd', 'e', 'f' };
|
||||
bool ok;
|
||||
+ bool missing;
|
||||
/* Only escape in the edge case producing multiple lines,
|
||||
to ease automatic processing of status output. */
|
||||
bool needs_escape = ! status_only && strchr (filename, '\n');
|
||||
|
||||
properly_formatted_lines = true;
|
||||
|
||||
- *bin_buffer = '\1'; /* flag set to 0 for ignored missing files. */
|
||||
- ok = digest_file (filename, &binary, bin_buffer);
|
||||
+ ok = digest_file (filename, &binary, bin_buffer, &missing);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
@@ -626,10 +630,9 @@ digest_check (const char *checkfile_name)
|
||||
printf (": %s\n", _("FAILED open or read"));
|
||||
}
|
||||
}
|
||||
- else if (ignore_missing && ! *bin_buffer)
|
||||
+ else if (ignore_missing && missing)
|
||||
{
|
||||
- /* Treat an empty buffer as meaning a missing file,
|
||||
- which is ignored with --ignore-missing. */
|
||||
+ /* Ignore missing files with --ignore-missing. */
|
||||
;
|
||||
}
|
||||
else
|
||||
@@ -879,8 +882,9 @@ main (int argc, char **argv)
|
||||
else
|
||||
{
|
||||
int file_is_binary = binary;
|
||||
+ bool missing;
|
||||
|
||||
- if (! digest_file (file, &file_is_binary, bin_buffer))
|
||||
+ if (! digest_file (file, &file_is_binary, bin_buffer, &missing))
|
||||
ok = false;
|
||||
else
|
||||
{
|
||||
diff --git a/tests/misc/md5sum.pl b/tests/misc/md5sum.pl
|
||||
index 2eb6369..6ea7457 100755
|
||||
--- a/tests/misc/md5sum.pl
|
||||
+++ b/tests/misc/md5sum.pl
|
||||
@@ -149,6 +149,13 @@ my @Tests =
|
||||
{ERR=>
|
||||
"md5sum: f.md5: no file was verified\n"},
|
||||
{EXIT=> 1}],
|
||||
+ # coreutils-8.25 with --ignore-missing treated checksums starting with 00
|
||||
+ # as if the file was not present
|
||||
+ ['check-ignore-missing-6', '--check', '--ignore-missing',
|
||||
+ {AUX=> {f=> '9t'}},
|
||||
+ {IN=> {'f.md5' =>
|
||||
+ "006999e6df389641adf1fa3a74801d9d f\n"}},
|
||||
+ {OUT=>"f: OK\n"}],
|
||||
['bsd-segv', '--check', {IN=> {'z' => "MD5 ("}}, {EXIT=> 1},
|
||||
{ERR=> "$prog: z: no properly formatted MD5 checksum lines found\n"}],
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
diff -urNp coreutils-8.4-orig/doc/coreutils.texi coreutils-8.4/doc/coreutils.texi
|
||||
--- coreutils-8.4-orig/doc/coreutils.texi 2011-01-07 15:01:18.575654333 +0100
|
||||
+++ coreutils-8.4/doc/coreutils.texi 2011-01-07 15:05:38.791655243 +0100
|
||||
@@ -9058,6 +9058,8 @@ incorrect. @xref{Directory Setuid and S
|
||||
@@ -9993,6 +9993,8 @@ incorrect. @xref{Directory Setuid and Setgid}, for how the
|
||||
set-user-ID and set-group-ID bits of directories are inherited unless
|
||||
overridden in this way.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
diff -urNp coreutils-8.21-orig/doc/coreutils.texi coreutils-8.21/doc/coreutils.texi
|
||||
--- coreutils-8.21-orig/doc/coreutils.texi 2013-02-11 10:37:28.000000000 +0100
|
||||
+++ coreutils-8.21/doc/coreutils.texi 2013-02-15 10:15:26.497593689 +0100
|
||||
@@ -10961,6 +10961,13 @@
|
||||
@@ -11221,6 +11221,13 @@ some systems (notably SunOS), doing this yields more up to date results,
|
||||
but in general this option makes @command{df} much slower, especially when
|
||||
there are many or very busy file systems.
|
||||
|
||||
|
@ -28,7 +28,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c
|
|||
/* Grand total data. */
|
||||
static struct fs_usage grand_fsu;
|
||||
|
||||
@@ -238,13 +241,15 @@ enum
|
||||
@@ -243,13 +246,15 @@ enum
|
||||
NO_SYNC_OPTION = CHAR_MAX + 1,
|
||||
SYNC_OPTION,
|
||||
TOTAL_OPTION,
|
||||
|
@ -45,7 +45,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c
|
|||
{"inodes", no_argument, NULL, 'i'},
|
||||
{"human-readable", no_argument, NULL, 'h'},
|
||||
{"si", no_argument, NULL, 'H'},
|
||||
@@ -500,7 +505,10 @@ get_header (void)
|
||||
@@ -505,7 +510,10 @@ get_header (void)
|
||||
for (col = 0; col < ncolumns; col++)
|
||||
{
|
||||
char *cell = NULL;
|
||||
|
@ -57,7 +57,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c
|
|||
|
||||
if (columns[col]->field == SIZE_FIELD
|
||||
&& (header_mode == DEFAULT_MODE
|
||||
@@ -1150,6 +1158,19 @@ get_point (const char *point, const stru
|
||||
@@ -1352,6 +1360,19 @@ get_point (const char *point, const struct stat *statp)
|
||||
static void
|
||||
get_entry (char const *name, struct stat const *statp)
|
||||
{
|
||||
|
@ -77,7 +77,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c
|
|||
if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode))
|
||||
&& get_disk (name))
|
||||
return;
|
||||
@@ -1219,6 +1238,7 @@ or all file systems by default.\n\
|
||||
@@ -1422,6 +1443,7 @@ or all file systems by default.\n\
|
||||
-B, --block-size=SIZE scale sizes by SIZE before printing them; e.g.,\n\
|
||||
'-BM' prints sizes in units of 1,048,576 bytes;\n\
|
||||
see SIZE format below\n\
|
||||
|
@ -85,7 +85,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c
|
|||
-h, --human-readable print sizes in powers of 1024 (e.g., 1023M)\n\
|
||||
-H, --si print sizes in powers of 1000 (e.g., 1.1G)\n\
|
||||
"), stdout);
|
||||
@@ -1305,6 +1325,9 @@ main (int argc, char **argv)
|
||||
@@ -1512,6 +1534,9 @@ main (int argc, char **argv)
|
||||
xstrtol_fatal (e, oi, c, long_options, optarg);
|
||||
}
|
||||
break;
|
||||
|
@ -95,7 +95,7 @@ diff -urNp coreutils-8.21-orig/src/df.c coreutils-8.21/src/df.c
|
|||
case 'i':
|
||||
if (header_mode == OUTPUT_MODE)
|
||||
{
|
||||
@@ -1408,6 +1431,13 @@ main (int argc, char **argv)
|
||||
@@ -1608,6 +1633,13 @@ main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ index 299bae6..8ece29b 100644
|
|||
#include "getugroups.h"
|
||||
|
||||
#include <errno.h>
|
||||
@@ -123,3 +126,4 @@ getugroups (int maxcount, gid_t *grouplist, char const *username,
|
||||
@@ -126,3 +129,4 @@ getugroups (int maxcount, gid_t *grouplist, char const *username,
|
||||
}
|
||||
|
||||
#endif /* HAVE_GRP_H */
|
||||
|
@ -21,7 +21,7 @@ diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c
|
|||
index 76474c2..0a9d221 100644
|
||||
--- a/lib/mgetgroups.c
|
||||
+++ b/lib/mgetgroups.c
|
||||
@@ -115,9 +115,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups)
|
||||
@@ -121,9 +121,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups)
|
||||
/* else no username, so fall through and use getgroups. */
|
||||
#endif
|
||||
|
||||
|
@ -42,7 +42,7 @@ index 76474c2..0a9d221 100644
|
|||
|
||||
/* If we failed to count groups because there is no supplemental
|
||||
group support, then return an array containing just GID.
|
||||
@@ -139,10 +147,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups)
|
||||
@@ -145,10 +153,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups)
|
||||
if (g == NULL)
|
||||
return -1;
|
||||
|
||||
|
@ -76,7 +76,7 @@ diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4
|
|||
index 62777c7..5180243 100644
|
||||
--- a/m4/jm-macros.m4
|
||||
+++ b/m4/jm-macros.m4
|
||||
@@ -78,6 +78,7 @@
|
||||
@@ -82,6 +82,7 @@ AC_DEFUN([coreutils_MACROS],
|
||||
fchown
|
||||
fchmod
|
||||
ftruncate
|
||||
|
|
|
@ -132,7 +132,7 @@ diff -urNp coreutils-8.25-orig/src/cut.c coreutils-8.25/src/cut.c
|
|||
|
||||
/* The delimiter for each line/record. */
|
||||
static unsigned char line_delim = '\n';
|
||||
@@ -164,7 +243,7 @@ Print selected parts of lines from each
|
||||
@@ -164,7 +243,7 @@ Print selected parts of lines from each FILE to standard output.\n\
|
||||
-f, --fields=LIST select only these fields; also print any line\n\
|
||||
that contains no delimiter character, unless\n\
|
||||
the -s option is specified\n\
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "system.h"
|
||||
|
||||
#include "error.h"
|
||||
@@ -90,25 +95,16 @@ add_range_pair (size_t lo, size_t hi)
|
||||
@@ -61,25 +66,16 @@
|
||||
CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */
|
||||
static struct field_range_pair *current_rp;
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
|||
/* Output the given delimiter-separated fields. */
|
||||
field_mode
|
||||
};
|
||||
@@ -120,12 +116,16 @@ static enum operating_mode operating_mod
|
||||
@@ -91,12 +87,16 @@ static enum operating_mode operating_mode;
|
||||
with field mode. */
|
||||
static bool suppress_non_delimited;
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
|
||||
/* The delimiter for each line/record. */
|
||||
static unsigned char line_delim = '\n';
|
||||
@@ -135,7 +135,7 @@ static size_t output_delimiter_length;
|
||||
@@ -109,7 +109,7 @@ static size_t output_delimiter_length;
|
||||
|
||||
/* The output field separator string. Defaults to the 1-character
|
||||
string consisting of the input delimiter. */
|
||||
|
@ -69,7 +69,7 @@
|
|||
|
||||
/* True if we have ever read standard input. */
|
||||
static bool have_read_stdin;
|
||||
@@ -189,7 +189,7 @@ Print selected parts of lines from each
|
||||
@@ -164,7 +164,7 @@ Print selected parts of lines from each FILE to standard output.\n\
|
||||
-f, --fields=LIST select only these fields; also print any line\n\
|
||||
that contains no delimiter character, unless\n\
|
||||
the -s option is specified\n\
|
||||
|
@ -78,7 +78,7 @@
|
|||
"), stdout);
|
||||
fputs (_("\
|
||||
--complement complement the set of selected bytes, characters\n\
|
||||
@@ -435,6 +435,12 @@ next_item (size_t *item_idx)
|
||||
@@ -211,6 +211,12 @@ next_item (size_t *item_idx)
|
||||
current_rp++;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@
|
|||
/* Return nonzero if the K'th field or byte is printable. */
|
||||
|
||||
static inline bool
|
||||
@@ -443,6 +449,15 @@ print_kth (size_t k)
|
||||
@@ -219,6 +225,15 @@ print_kth (size_t k)
|
||||
return current_rp->lo <= k;
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@
|
|||
/* Return nonzero if K'th byte is the beginning of a range. */
|
||||
|
||||
static inline bool
|
||||
@@ -505,23 +520,215 @@ cut_bytes (FILE *stream)
|
||||
@@ -281,23 +296,215 @@ cut_bytes (FILE *stream)
|
||||
}
|
||||
|
||||
/* Read from stream STREAM, printing to standard output any selected fields. */
|
||||
|
@ -328,7 +328,7 @@
|
|||
|
||||
/* To support the semantics of the -s flag, we may have to buffer
|
||||
all of the first field to determine whether it is 'delimited.'
|
||||
@@ -536,10 +744,14 @@ cut_fields (FILE *stream)
|
||||
@@ -312,10 +519,14 @@ cut_fields (FILE *stream)
|
||||
if (field_idx == 1 && buffer_first_field)
|
||||
{
|
||||
ssize_t len;
|
||||
|
@ -346,7 +346,7 @@
|
|||
if (len < 0)
|
||||
{
|
||||
free (field_1_buffer);
|
||||
@@ -549,15 +761,15 @@ cut_fields (FILE *stream)
|
||||
@@ -325,15 +536,15 @@ cut_fields (FILE *stream)
|
||||
xalloc_die ();
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,7 @@
|
|||
{
|
||||
if (suppress_non_delimited)
|
||||
{
|
||||
@@ -565,26 +777,30 @@ cut_fields (FILE *stream)
|
||||
@@ -341,26 +552,30 @@ cut_fields (FILE *stream)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -405,7 +405,7 @@
|
|||
found_any_selected_field = true;
|
||||
}
|
||||
}
|
||||
@@ -594,7 +810,8 @@ cut_fields (FILE *stream)
|
||||
@@ -370,7 +585,8 @@ cut_fields (FILE *stream)
|
||||
next_item (&field_idx);
|
||||
}
|
||||
|
||||
|
@ -415,7 +415,7 @@
|
|||
|
||||
if (print_kth (field_idx))
|
||||
{
|
||||
@@ -605,42 +822,46 @@ cut_fields (FILE *stream)
|
||||
@@ -381,42 +597,46 @@ cut_fields (FILE *stream)
|
||||
}
|
||||
found_any_selected_field = true;
|
||||
|
||||
|
@ -477,7 +477,7 @@
|
|||
break;
|
||||
field_idx = 1;
|
||||
current_rp = frp;
|
||||
@@ -652,7 +874,14 @@ static void
|
||||
@@ -429,7 +649,14 @@ static void
|
||||
cut_stream (FILE *stream)
|
||||
{
|
||||
if (operating_mode == byte_mode)
|
||||
|
@ -493,7 +493,7 @@
|
|||
else
|
||||
cut_fields (stream);
|
||||
}
|
||||
@@ -706,6 +935,7 @@ main (int argc, char **argv)
|
||||
@@ -483,6 +710,7 @@ main (int argc, char **argv)
|
||||
bool ok;
|
||||
bool delim_specified = false;
|
||||
char *spec_list_string IF_LINT ( = NULL);
|
||||
|
@ -501,7 +501,7 @@
|
|||
|
||||
initialize_main (&argc, &argv);
|
||||
set_program_name (argv[0]);
|
||||
@@ -719,8 +949,10 @@ main (int argc, char **argv)
|
||||
@@ -496,8 +724,10 @@ main (int argc, char **argv)
|
||||
|
||||
/* By default, all non-delimited lines are printed. */
|
||||
suppress_non_delimited = false;
|
||||
|
@ -513,7 +513,7 @@
|
|||
have_read_stdin = false;
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "b:c:d:f:nsz", longopts, NULL)) != -1)
|
||||
@@ -728,7 +960,6 @@ main (int argc, char **argv)
|
||||
@@ -505,7 +735,6 @@ main (int argc, char **argv)
|
||||
switch (optc)
|
||||
{
|
||||
case 'b':
|
||||
|
@ -521,7 +521,7 @@
|
|||
/* Build the byte list. */
|
||||
if (operating_mode != undefined_mode)
|
||||
FATAL_ERROR (_("only one type of list may be specified"));
|
||||
@@ -736,6 +967,14 @@ main (int argc, char **argv)
|
||||
@@ -513,6 +742,14 @@ main (int argc, char **argv)
|
||||
spec_list_string = optarg;
|
||||
break;
|
||||
|
||||
|
@ -536,7 +536,7 @@
|
|||
case 'f':
|
||||
/* Build the field list. */
|
||||
if (operating_mode != undefined_mode)
|
||||
@@ -747,9 +986,17 @@ main (int argc, char **argv)
|
||||
@@ -524,9 +761,17 @@ main (int argc, char **argv)
|
||||
case 'd':
|
||||
/* New delimiter. */
|
||||
/* Interpret -d '' to mean 'use the NUL byte as the delimiter.' */
|
||||
|
@ -551,12 +551,12 @@
|
|||
+ mbi_advance (iter);
|
||||
+ if (mbi_avail (iter))
|
||||
FATAL_ERROR (_("the delimiter must be a single character"));
|
||||
+ }
|
||||
- delim = optarg[0];
|
||||
+ }
|
||||
delim_specified = true;
|
||||
break;
|
||||
|
||||
@@ -763,6 +1008,7 @@ main (int argc, char **argv)
|
||||
@@ -540,6 +785,7 @@ main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
|
@ -564,7 +564,7 @@
|
|||
break;
|
||||
|
||||
case 's':
|
||||
@@ -802,15 +1048,12 @@ main (int argc, char **argv)
|
||||
@@ -579,15 +825,12 @@ main (int argc, char **argv)
|
||||
| (complement ? SETFLD_COMPLEMENT : 0) );
|
||||
|
||||
if (!delim_specified)
|
||||
|
|
|
@ -23,19 +23,24 @@ properly.
|
|||
|
||||
Co-authored-by: Pádraig Brady <pbrady@redhat.com>
|
||||
---
|
||||
NEWS | 3 +
|
||||
bootstrap.conf | 1 +
|
||||
configure.ac | 2 +
|
||||
lib/mbfile.c | 3 +
|
||||
lib/mbfile.h | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
m4/mbfile.m4 | 14 +++
|
||||
po/POTFILES.in | 1 +
|
||||
src/expand-core.c | 150 +++++++++++++++++++++++++++++++++++++++
|
||||
src/expand-core.h | 44 ++++++++++++
|
||||
src/expand.c | 183 ++++++++++-------------------------------------
|
||||
src/expand-core.c | 150 ++++++++++++++++++++++++++++++
|
||||
src/expand-core.h | 41 +++++++++
|
||||
src/expand.c | 186 ++++++++-----------------------------
|
||||
src/local.mk | 2 +
|
||||
src/unexpand.c | 197 ++++++++++++---------------------------------------
|
||||
tests/expand/mb.sh | 98 +++++++++++++++++++++++++
|
||||
src/unexpand.c | 195 ++++++++++-----------------------------
|
||||
tests/expand/mb.sh | 98 ++++++++++++++++++++
|
||||
tests/local.mk | 2 +
|
||||
tests/unexpand/mb.sh | 97 +++++++++++++++++++++++++
|
||||
12 files changed, 482 insertions(+), 298 deletions(-)
|
||||
tests/unexpand/mb.sh | 97 ++++++++++++++++++++
|
||||
14 files changed, 750 insertions(+), 297 deletions(-)
|
||||
create mode 100644 lib/mbfile.c
|
||||
create mode 100644 lib/mbfile.h
|
||||
create mode 100644 m4/mbfile.m4
|
||||
create mode 100644 src/expand-core.c
|
||||
create mode 100644 src/expand-core.h
|
||||
create mode 100755 tests/expand/mb.sh
|
||||
|
@ -45,7 +50,7 @@ diff --git a/bootstrap.conf b/bootstrap.conf
|
|||
index ef1c078..ea8cebc 100644
|
||||
--- a/bootstrap.conf
|
||||
+++ b/bootstrap.conf
|
||||
@@ -152,6 +152,7 @@ gnulib_modules="
|
||||
@@ -151,6 +151,7 @@ gnulib_modules="
|
||||
maintainer-makefile
|
||||
malloc-gnu
|
||||
manywarnings
|
||||
|
@ -57,7 +62,7 @@ diff --git a/configure.ac b/configure.ac
|
|||
index 8dc2192..b8b5114 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -422,6 +422,8 @@ gl_WINSIZE_IN_PTEM
|
||||
@@ -425,6 +425,8 @@ fi
|
||||
# I'm leaving it here for now. This whole thing needs to be modernized...
|
||||
gl_WINSIZE_IN_PTEM
|
||||
|
||||
|
@ -338,12 +343,10 @@ index 0a40a1a..ed97fd4 100644
|
|||
|
||||
static char const shortopts[] = "it:0::1::2::3::4::5::6::7::8::9::";
|
||||
|
||||
@@ -125,128 +129,6 @@
|
||||
if (first_free_tab == n_tabs_allocated)
|
||||
tab_list = X2NREALLOC (tab_list, &n_tabs_allocated);
|
||||
@@ -135,128 +139,6 @@ add_tab_stop (uintmax_t tabval)
|
||||
tab_list[first_free_tab++] = tabval;
|
||||
-}
|
||||
-
|
||||
}
|
||||
|
||||
-/* Add the comma or blank separated list of tab stops STOPS
|
||||
- to the list of tab stops. */
|
||||
-
|
||||
|
@ -464,10 +467,12 @@ index 0a40a1a..ed97fd4 100644
|
|||
- exit_status = EXIT_FAILURE;
|
||||
- }
|
||||
- return NULL;
|
||||
}
|
||||
|
||||
-}
|
||||
-
|
||||
/* Change tabs to spaces, writing to stdout.
|
||||
@@ -265,19 +146,19 @@ expand (void)
|
||||
Read each file in 'file_list', in order. */
|
||||
|
||||
@@ -265,19 +147,19 @@ expand (void)
|
||||
{
|
||||
/* Input stream. */
|
||||
FILE *fp = next_file (NULL);
|
||||
|
@ -491,7 +496,7 @@ index 0a40a1a..ed97fd4 100644
|
|||
/* The following variables have valid values only when CONVERT
|
||||
is true: */
|
||||
|
||||
@@ -287,17 +168,23 @@ expand (void)
|
||||
@@ -287,17 +169,23 @@ expand (void)
|
||||
/* Index in TAB_LIST of next tab stop to examine. */
|
||||
size_t tab_index = 0;
|
||||
|
||||
|
@ -519,7 +524,7 @@ index 0a40a1a..ed97fd4 100644
|
|||
{
|
||||
/* Column the next input tab stop is on. */
|
||||
uintmax_t next_tab_column;
|
||||
@@ -328,32 +215,34 @@ expand (void)
|
||||
@@ -328,32 +216,34 @@ expand (void)
|
||||
if (putchar (' ') < 0)
|
||||
error (EXIT_FAILURE, errno, _("write error"));
|
||||
|
||||
|
@ -562,7 +567,7 @@ index 0a40a1a..ed97fd4 100644
|
|||
}
|
||||
}
|
||||
|
||||
@@ -385,19 +274,19 @@ main (int argc, char **argv)
|
||||
@@ -385,19 +275,19 @@ main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 't':
|
||||
|
@ -589,7 +594,7 @@ diff --git a/src/local.mk b/src/local.mk
|
|||
index 536b7cc..bfede88 100644
|
||||
--- a/src/local.mk
|
||||
+++ b/src/local.mk
|
||||
@@ -362,6 +362,8 @@ src_coreutils_SOURCES = src/coreutils.c
|
||||
@@ -361,6 +361,8 @@ src_coreutils_SOURCES = src/coreutils.c
|
||||
|
||||
src_cp_SOURCES = src/cp.c $(copy_sources) $(selinux_sources)
|
||||
src_dir_SOURCES = src/ls.c src/ls-dir.c
|
||||
|
@ -655,7 +660,7 @@ index e0f7c22..48fbb32 100644
|
|||
|
||||
/* For long options that have no equivalent short option, use a
|
||||
non-character as a pseudo short option, starting with CHAR_MAX + 1. */
|
||||
@@ -154,128 +156,6 @@ add_tab_stop (uintmax_t tabval)
|
||||
@@ -154,128 +158,6 @@ add_tab_stop (uintmax_t tabval)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -784,7 +789,7 @@ index e0f7c22..48fbb32 100644
|
|||
/* Change blanks to tabs, writing to stdout.
|
||||
Read each file in 'file_list', in order. */
|
||||
|
||||
@@ -284,11 +164,12 @@ unexpand (void)
|
||||
@@ -284,11 +166,12 @@ unexpand (void)
|
||||
{
|
||||
/* Input stream. */
|
||||
FILE *fp = next_file (NULL);
|
||||
|
@ -798,7 +803,7 @@ index e0f7c22..48fbb32 100644
|
|||
|
||||
if (!fp)
|
||||
return;
|
||||
@@ -296,12 +177,14 @@ unexpand (void)
|
||||
@@ -296,12 +179,14 @@ unexpand (void)
|
||||
/* The worst case is a non-blank character, then one blank, then a
|
||||
tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so
|
||||
allocate MAX_COLUMN_WIDTH bytes to store the blanks. */
|
||||
|
@ -815,7 +820,7 @@ index e0f7c22..48fbb32 100644
|
|||
|
||||
/* If true, perform translations. */
|
||||
bool convert = true;
|
||||
@@ -335,12 +218,19 @@ unexpand (void)
|
||||
@@ -335,12 +220,19 @@ unexpand (void)
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -838,7 +843,7 @@ index e0f7c22..48fbb32 100644
|
|||
|
||||
if (blank)
|
||||
{
|
||||
@@ -372,16 +262,16 @@ unexpand (void)
|
||||
@@ -372,16 +264,16 @@ unexpand (void)
|
||||
if (next_tab_column < column)
|
||||
error (EXIT_FAILURE, 0, _("input line is too long"));
|
||||
|
||||
|
@ -858,7 +863,7 @@ index e0f7c22..48fbb32 100644
|
|||
|
||||
if (! (prev_blank && column == next_tab_column))
|
||||
{
|
||||
@@ -389,13 +279,14 @@ unexpand (void)
|
||||
@@ -389,13 +281,14 @@ unexpand (void)
|
||||
will be replaced by tabs. */
|
||||
if (column == next_tab_column)
|
||||
one_blank_before_tab_stop = true;
|
||||
|
@ -875,7 +880,7 @@ index e0f7c22..48fbb32 100644
|
|||
}
|
||||
|
||||
/* Discard pending blanks, unless it was a single
|
||||
@@ -403,7 +294,7 @@ unexpand (void)
|
||||
@@ -403,7 +296,7 @@ unexpand (void)
|
||||
pending = one_blank_before_tab_stop;
|
||||
}
|
||||
}
|
||||
|
@ -884,7 +889,7 @@ index e0f7c22..48fbb32 100644
|
|||
{
|
||||
/* Go back one column, and force recalculation of the
|
||||
next tab stop. */
|
||||
@@ -413,7 +304,7 @@ unexpand (void)
|
||||
@@ -413,7 +306,7 @@ unexpand (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -893,7 +898,7 @@ index e0f7c22..48fbb32 100644
|
|||
if (!column)
|
||||
error (EXIT_FAILURE, 0, _("input line is too long"));
|
||||
}
|
||||
@@ -421,9 +312,13 @@ unexpand (void)
|
||||
@@ -421,9 +314,13 @@ unexpand (void)
|
||||
if (pending)
|
||||
{
|
||||
if (pending > 1 && one_blank_before_tab_stop)
|
||||
|
@ -909,7 +914,7 @@ index e0f7c22..48fbb32 100644
|
|||
pending = 0;
|
||||
one_blank_before_tab_stop = false;
|
||||
}
|
||||
@@ -432,16 +327,16 @@ unexpand (void)
|
||||
@@ -432,16 +329,16 @@ unexpand (void)
|
||||
convert &= convert_entire_line || blank;
|
||||
}
|
||||
|
||||
|
@ -930,7 +935,7 @@ index e0f7c22..48fbb32 100644
|
|||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +377,7 @@ main (int argc, char **argv)
|
||||
@@ -482,7 +379,7 @@ main (int argc, char **argv)
|
||||
break;
|
||||
case 't':
|
||||
convert_entire_line = true;
|
||||
|
@ -1047,7 +1052,7 @@ diff --git a/tests/local.mk b/tests/local.mk
|
|||
index 7df04da..d3462be 100644
|
||||
--- a/tests/local.mk
|
||||
+++ b/tests/local.mk
|
||||
@@ -532,6 +532,7 @@ all_tests = \
|
||||
@@ -536,6 +536,7 @@ all_tests = \
|
||||
tests/du/threshold.sh \
|
||||
tests/du/trailing-slash.sh \
|
||||
tests/du/two-args.sh \
|
||||
|
@ -1055,7 +1060,7 @@ index 7df04da..d3462be 100644
|
|||
tests/id/gnu-zero-uids.sh \
|
||||
tests/id/no-context.sh \
|
||||
tests/id/context.sh \
|
||||
@@ -671,6 +672,7 @@ all_tests = \
|
||||
@@ -674,6 +675,7 @@ all_tests = \
|
||||
tests/touch/read-only.sh \
|
||||
tests/touch/relative.sh \
|
||||
tests/touch/trailing-slash.sh \
|
||||
|
@ -1166,11 +1171,11 @@ index 0000000..60d4c1a
|
|||
+
|
||||
+unexpand -a < in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
--
|
||||
2.4.3
|
||||
|
||||
--- /dev/null 2015-11-30 08:40:17.566742513 +0100
|
||||
+++ coreutils-8.24/m4/mbfile.m4 2015-12-01 09:30:55.951149907 +0100
|
||||
diff --git a/m4/mbfile.m4 b/m4/mbfile.m4
|
||||
new file mode 100644
|
||||
index 0000000..8589902
|
||||
--- /dev/null
|
||||
+++ b/m4/mbfile.m4
|
||||
@@ -0,0 +1,14 @@
|
||||
+# mbfile.m4 serial 7
|
||||
+dnl Copyright (C) 2005, 2008-2015 Free Software Foundation, Inc.
|
||||
|
@ -1186,14 +1191,20 @@ index 0000000..60d4c1a
|
|||
+ AC_REQUIRE([AC_TYPE_MBSTATE_T])
|
||||
+ :
|
||||
+])
|
||||
--- /dev/null 2015-11-30 08:40:17.566742513 +0100
|
||||
+++ coreutils-8.24/lib/mbfile.c 2015-12-01 09:28:22.254928468 +0100
|
||||
diff --git a/lib/mbfile.c b/lib/mbfile.c
|
||||
new file mode 100644
|
||||
index 0000000..b0a468e
|
||||
--- /dev/null
|
||||
+++ b/lib/mbfile.c
|
||||
@@ -0,0 +1,3 @@
|
||||
+#include <config.h>
|
||||
+#define MBFILE_INLINE _GL_EXTERN_INLINE
|
||||
+#include "mbfile.h"
|
||||
--- /dev/null 2015-11-30 08:40:17.566742513 +0100
|
||||
+++ coreutils-8.24/lib/mbfile.h 2015-12-01 09:28:30.829885570 +0100
|
||||
diff --git a/lib/mbfile.h b/lib/mbfile.h
|
||||
new file mode 100644
|
||||
index 0000000..11f1b12
|
||||
--- /dev/null
|
||||
+++ b/lib/mbfile.h
|
||||
@@ -0,0 +1,255 @@
|
||||
+/* Multibyte character I/O: macros for multi-byte encodings.
|
||||
+ Copyright (C) 2001, 2005, 2009-2015 Free Software Foundation, Inc.
|
||||
|
@ -1450,3 +1461,6 @@ index 0000000..60d4c1a
|
|||
+_GL_INLINE_HEADER_BEGIN
|
||||
+
|
||||
+#endif /* _MBFILE_H */
|
||||
--
|
||||
2.5.5
|
||||
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
diff -up ./src/expand.c.orig ./src/expand.c
|
||||
--- ./src/expand.c.orig 2016-06-01 12:42:49.330373488 +0200
|
||||
+++ ./src/expand.c 2016-06-07 14:35:16.011142041 +0200
|
||||
@@ -173,15 +173,19 @@ expand (void)
|
||||
|
||||
do
|
||||
{
|
||||
- do {
|
||||
+ while (true) {
|
||||
mbf_getc (c, mbf);
|
||||
- if (mb_iseof (c))
|
||||
+ if ((mb_iseof (c)) && (fp = next_file (fp)))
|
||||
{
|
||||
- mbf_init (mbf, fp = next_file (fp));
|
||||
+ mbf_init (mbf, fp);
|
||||
continue;
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
- while (false);
|
||||
+
|
||||
|
||||
if (convert)
|
||||
{
|
||||
diff -up ./src/unexpand.c.orig ./src/unexpand.c
|
||||
--- ./src/unexpand.c.orig 2016-06-07 14:26:57.380746446 +0200
|
||||
+++ ./src/unexpand.c 2016-06-07 14:34:54.059256698 +0200
|
||||
@@ -220,15 +220,19 @@ unexpand (void)
|
||||
|
||||
do
|
||||
{
|
||||
- do {
|
||||
+ while (true) {
|
||||
mbf_getc (c, mbf);
|
||||
- if (mb_iseof (c))
|
||||
+ if ((mb_iseof (c)) && (fp = next_file (fp)))
|
||||
{
|
||||
- mbf_init (mbf, fp = next_file (fp));
|
||||
+ mbf_init (mbf, fp);
|
||||
continue;
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
- while (false);
|
||||
+
|
||||
|
||||
if (convert)
|
||||
{
|
||||
diff -up ./tests/expand/mb.sh.orig ./tests/expand/mb.sh
|
||||
--- ./tests/expand/mb.sh.orig 2016-05-11 14:13:53.095289000 +0200
|
||||
+++ ./tests/expand/mb.sh 2016-06-07 14:38:48.259033445 +0200
|
||||
@@ -44,6 +44,20 @@ EOF
|
||||
expand < in > out || fail=1
|
||||
compare exp out > /dev/null 2>&1 || fail=1
|
||||
|
||||
+#multiple files as an input
|
||||
+cat <<\EOF >> exp || framework_failure_
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+ äöü . öüä. ä xx
|
||||
+EOF
|
||||
+
|
||||
+expand ./in ./in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
#test characters with display widths != 1
|
||||
env printf '12345678
|
||||
e\t|ascii(1)
|
||||
diff -up ./tests/unexpand/mb.sh.orig ./tests/unexpand/mb.sh
|
||||
--- ./tests/unexpand/mb.sh.orig 2016-06-07 14:41:44.210106466 +0200
|
||||
+++ ./tests/unexpand/mb.sh 2016-06-07 14:52:28.848639772 +0200
|
||||
@@ -44,6 +44,22 @@ EOF
|
||||
unexpand -a < in > out || fail=1
|
||||
compare exp out > /dev/null 2>&1 || fail=1
|
||||
|
||||
+
|
||||
+#multiple files as an input
|
||||
+cat >> exp <<\EOF
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+ äöü . öüä. ä xx
|
||||
+EOF
|
||||
+
|
||||
+
|
||||
+unexpand -a ./in ./in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
#test characters with a display width larger than 1
|
||||
|
||||
env printf '12345678
|
|
@ -0,0 +1,35 @@
|
|||
From 3976ef5a20369d8b490907ab2cba2d617305a5e0 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Mon, 30 May 2016 16:19:20 +0200
|
||||
Subject: [PATCH] sort: do not use static array 'blanks' in human_numcompare()
|
||||
|
||||
... because the array is not initialized with MB locales. Note this is
|
||||
rather a conservative fix. I plan to do more cleanup of the i18n patch
|
||||
in Fedora to prevent mistakes like this in future updates of coreutils.
|
||||
---
|
||||
src/sort.c | 8 +++-----
|
||||
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/sort.c b/src/sort.c
|
||||
index 9e07ad8..e47b039 100644
|
||||
--- a/src/sort.c
|
||||
+++ b/src/sort.c
|
||||
@@ -2274,12 +2274,10 @@ find_unit_order (char const *number)
|
||||
<none/unknown> < K/k < M < G < T < P < E < Z < Y */
|
||||
|
||||
static int
|
||||
-human_numcompare (char const *a, char const *b)
|
||||
+human_numcompare (char *a, char *b)
|
||||
{
|
||||
- while (blanks[to_uchar (*a)])
|
||||
- a++;
|
||||
- while (blanks[to_uchar (*b)])
|
||||
- b++;
|
||||
+ skipblanks(&a, a + strlen(a));
|
||||
+ skipblanks(&b, b + strlen(b));
|
||||
|
||||
int diff = find_unit_order (a) - find_unit_order (b);
|
||||
return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep));
|
||||
--
|
||||
2.5.5
|
||||
|
|
@ -0,0 +1,443 @@
|
|||
diff -up ./src/expand-core.c.orig ./src/expand-core.c
|
||||
--- ./src/expand-core.c.orig 2016-06-28 14:44:18.281619000 +0200
|
||||
+++ ./src/expand-core.c 2016-06-30 11:46:50.025109755 +0200
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
+#include <mbfile.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "error.h"
|
||||
@@ -27,6 +28,119 @@
|
||||
|
||||
#include "expand-core.h"
|
||||
|
||||
+extern inline int
|
||||
+set_utf_locale (void)
|
||||
+{
|
||||
+ /*try using some predefined locale */
|
||||
+ const char* predef_locales[] = {"C.UTF8","en_US.UTF8","en_GB.UTF8"};
|
||||
+
|
||||
+ const int predef_locales_count=3;
|
||||
+ for (int i=0;i<predef_locales_count;i++)
|
||||
+ {
|
||||
+ if (setlocale(LC_ALL,predef_locales[i])!=NULL)
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (i==predef_locales_count-1)
|
||||
+ {
|
||||
+ return 1;
|
||||
+ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale"));
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+extern bool
|
||||
+check_utf_locale(void)
|
||||
+{
|
||||
+ char* locale = setlocale (LC_CTYPE , NULL);
|
||||
+ if (locale == NULL)
|
||||
+ {
|
||||
+ return false;
|
||||
+ }
|
||||
+ else if (strcasestr(locale, "utf8") == NULL && strcasestr(locale, "utf-8") == NULL)
|
||||
+ {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+extern bool
|
||||
+check_bom(FILE* fp, mb_file_t *mbf)
|
||||
+{
|
||||
+ int c;
|
||||
+
|
||||
+
|
||||
+ c=fgetc(fp);
|
||||
+
|
||||
+ /*test BOM header of the first file */
|
||||
+ mbf->bufcount=0;
|
||||
+ if (c == 0xEF)
|
||||
+ {
|
||||
+ c=fgetc(fp);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (c != EOF)
|
||||
+ {
|
||||
+ ungetc(c,fp);
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (c == 0xBB)
|
||||
+ {
|
||||
+ c=fgetc(fp);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if ( c!= EOF )
|
||||
+ {
|
||||
+ mbf->buf[0]=(unsigned char) 0xEF;
|
||||
+ mbf->bufcount=1;
|
||||
+ ungetc(c,fp);
|
||||
+ return false;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ungetc(0xEF,fp);
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ if (c == 0xBF)
|
||||
+ {
|
||||
+ mbf->bufcount=0;
|
||||
+ return true;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (c != EOF)
|
||||
+ {
|
||||
+ mbf->buf[0]=(unsigned char) 0xEF;
|
||||
+ mbf->buf[1]=(unsigned char) 0xBB;
|
||||
+ mbf->bufcount=2;
|
||||
+ ungetc(c,fp);
|
||||
+ return false;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ mbf->buf[0]=(unsigned char) 0xEF;
|
||||
+ mbf->bufcount=1;
|
||||
+ ungetc(0xBB,fp);
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+extern inline void
|
||||
+print_bom(void)
|
||||
+{
|
||||
+ putc (0xEF, stdout);
|
||||
+ putc (0xBB, stdout);
|
||||
+ putc (0xBF, stdout);
|
||||
+}
|
||||
+
|
||||
/* Add the comma or blank separated list of tab stops STOPS
|
||||
to the list of tab stops. */
|
||||
|
||||
diff -up ./src/expand-core.h.orig ./src/expand-core.h
|
||||
--- ./src/expand-core.h.orig 2016-06-28 14:44:18.281619000 +0200
|
||||
+++ ./src/expand-core.h 2016-06-30 11:47:18.929437205 +0200
|
||||
@@ -15,7 +15,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef EXPAND_CORE_H_
|
||||
-# define EXPAND_CORE_H_
|
||||
+#define EXPAND_CORE_H_
|
||||
|
||||
extern size_t first_free_tab;
|
||||
|
||||
@@ -29,6 +29,18 @@ extern char **file_list;
|
||||
|
||||
extern bool have_read_stdin;
|
||||
|
||||
+inline int
|
||||
+set_utf_locale (void);
|
||||
+
|
||||
+bool
|
||||
+check_utf_locale(void);
|
||||
+
|
||||
+bool
|
||||
+check_bom(FILE* fp, mb_file_t *mbf);
|
||||
+
|
||||
+inline void
|
||||
+print_bom(void);
|
||||
+
|
||||
void
|
||||
parse_tab_stops (char const *stops, void (*add_tab_stop)(uintmax_t));
|
||||
|
||||
diff -up ./src/expand.c.orig ./src/expand.c
|
||||
--- ./src/expand.c.orig 2016-06-28 14:44:18.286619000 +0200
|
||||
+++ ./src/expand.c 2016-06-30 11:50:15.077312947 +0200
|
||||
@@ -149,11 +149,33 @@ expand (void)
|
||||
FILE *fp = next_file (NULL);
|
||||
mb_file_t mbf;
|
||||
mbf_char_t c;
|
||||
-
|
||||
+ /* True if the starting locale is utf8. */
|
||||
+ bool using_utf_locale;
|
||||
+
|
||||
+ /* True if the first file contains BOM header. */
|
||||
+ bool found_bom;
|
||||
+ using_utf_locale=check_utf_locale();
|
||||
+
|
||||
if (!fp)
|
||||
return;
|
||||
-
|
||||
mbf_init (mbf, fp);
|
||||
+ found_bom=check_bom(fp,&mbf);
|
||||
+
|
||||
+ if (using_utf_locale == false && found_bom == true)
|
||||
+ {
|
||||
+ /*try using some predefined locale */
|
||||
+
|
||||
+ if (set_utf_locale () != 0)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale"));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if (found_bom == true)
|
||||
+ {
|
||||
+ print_bom();
|
||||
+ }
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -178,6 +200,27 @@ expand (void)
|
||||
if ((mb_iseof (c)) && (fp = next_file (fp)))
|
||||
{
|
||||
mbf_init (mbf, fp);
|
||||
+ if (fp!=NULL)
|
||||
+ {
|
||||
+ if (check_bom(fp,&mbf)==true)
|
||||
+ {
|
||||
+ /*Not the first file - check BOM header*/
|
||||
+ if (using_utf_locale==false && found_bom==false)
|
||||
+ {
|
||||
+ /*BOM header in subsequent file but not in the first one. */
|
||||
+ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if(using_utf_locale==false && found_bom==true)
|
||||
+ {
|
||||
+ /*First file conatined BOM header - locale was switched to UTF
|
||||
+ /*all subsequent files should contain BOM. */
|
||||
+ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
continue;
|
||||
}
|
||||
else
|
||||
diff -up ./src/unexpand.c.orig ./src/unexpand.c
|
||||
--- ./src/unexpand.c.orig 2016-06-28 17:39:22.894259000 +0200
|
||||
+++ ./src/unexpand.c 2016-07-07 09:48:07.659924755 +0200
|
||||
@@ -172,16 +172,36 @@ unexpand (void)
|
||||
include characters other than spaces, so the blanks must be
|
||||
stored, not merely counted. */
|
||||
mbf_char_t *pending_blank;
|
||||
+ /* True if the starting locale is utf8. */
|
||||
+ bool using_utf_locale;
|
||||
+
|
||||
+ /* True if the first file contains BOM header. */
|
||||
+ bool found_bom;
|
||||
+ using_utf_locale=check_utf_locale();
|
||||
|
||||
if (!fp)
|
||||
return;
|
||||
+ mbf_init (mbf, fp);
|
||||
+ found_bom=check_bom(fp,&mbf);
|
||||
|
||||
+ if (using_utf_locale == false && found_bom == true)
|
||||
+ {
|
||||
+ /*try using some predefined locale */
|
||||
+
|
||||
+ if (set_utf_locale () != 0)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, _("cannot set UTF-8 locale"));
|
||||
+ }
|
||||
+ }
|
||||
/* The worst case is a non-blank character, then one blank, then a
|
||||
tab stop, then MAX_COLUMN_WIDTH - 1 blanks, then a non-blank; so
|
||||
allocate MAX_COLUMN_WIDTH bytes to store the blanks. */
|
||||
pending_blank = xmalloc (max_column_width * sizeof (mbf_char_t));
|
||||
|
||||
- mbf_init (mbf, fp);
|
||||
+ if (found_bom == true)
|
||||
+ {
|
||||
+ print_bom();
|
||||
+ }
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -225,6 +245,27 @@ unexpand (void)
|
||||
if ((mb_iseof (c)) && (fp = next_file (fp)))
|
||||
{
|
||||
mbf_init (mbf, fp);
|
||||
+ if (fp!=NULL)
|
||||
+ {
|
||||
+ if (check_bom(fp,&mbf)==true)
|
||||
+ {
|
||||
+ /*Not the first file - check BOM header*/
|
||||
+ if (using_utf_locale==false && found_bom==false)
|
||||
+ {
|
||||
+ /*BOM header in subsequent file but not in the first one. */
|
||||
+ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if(using_utf_locale==false && found_bom==true)
|
||||
+ {
|
||||
+ /*First file conatined BOM header - locale was switched to UTF
|
||||
+ /*all subsequent files should contain BOM. */
|
||||
+ error (EXIT_FAILURE, errno, _("combination of files with and without BOM header"));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
continue;
|
||||
}
|
||||
else
|
||||
diff -up ./tests/expand/mb.sh.orig ./tests/expand/mb.sh
|
||||
--- ./tests/expand/mb.sh.orig 2016-06-28 14:44:18.287619000 +0200
|
||||
+++ ./tests/expand/mb.sh 2016-06-30 11:57:10.038407216 +0200
|
||||
@@ -109,4 +109,75 @@ äbcdef\xFF |
|
||||
expand < in > out || fail=1
|
||||
compare exp out > /dev/null 2>&1 || fail=1
|
||||
|
||||
+
|
||||
+
|
||||
+#BOM header test 1
|
||||
+printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+EOF
|
||||
+env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_
|
||||
+
|
||||
+printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+ äöü . öüä. ä xx
|
||||
+EOF
|
||||
+
|
||||
+
|
||||
+expand < in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+LANG=C expand < in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+LC_ALL=C expand < in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+
|
||||
+printf '\xEF\xBB\xBF' > in1; cat <<\EOF >> in1 || framework_failure_
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+EOF
|
||||
+env printf ' äöü\t. öüä. \tä xx\n' >> in1 || framework_failure_
|
||||
+
|
||||
+
|
||||
+printf '\xEF\xBB\xBF' > exp; cat <<\EOF >> exp || framework_failure_
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+ äöü . öüä. ä xx
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+ äöü . öüä. ä xx
|
||||
+EOF
|
||||
+
|
||||
+expand in1 in1 > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+LANG=C expand in1 in1 > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+LC_ALL=C expand in1 in1 > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
exit $fail
|
||||
diff -up ./tests/unexpand/mb.sh.orig ./tests/unexpand/mb.sh
|
||||
--- ./tests/unexpand/mb.sh.orig 2016-06-28 17:39:22.895259000 +0200
|
||||
+++ ./tests/unexpand/mb.sh 2016-07-07 09:55:00.098281917 +0200
|
||||
@@ -111,3 +111,62 @@ äbcdef\xFF\t|
|
||||
|
||||
unexpand -a < in > out || fail=1
|
||||
compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+#BOM header test 1
|
||||
+printf "\xEF\xBB\xBF" > in; cat <<\EOF >> in || framework_failure_
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+ äöü . öüä. ä xx
|
||||
+EOF
|
||||
+env printf ' äöü\t. öüä. \tä xx\n' >> in || framework_failure_
|
||||
+
|
||||
+printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+ äöü . öüä. ä xx
|
||||
+EOF
|
||||
+
|
||||
+unexpand < in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+LANG=C unexpand < in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+LC_ALL=C unexpand < in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+
|
||||
+printf "\xEF\xBB\xBF" > exp; cat <<\EOF >> exp || framework_failure_
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+ äöü . öüä. ä xx
|
||||
+1234567812345678123456781
|
||||
+. . . .
|
||||
+a b c d
|
||||
+. . . .
|
||||
+ä ö ü ß
|
||||
+. . . .
|
||||
+ äöü . öüä. ä xx
|
||||
+EOF
|
||||
+
|
||||
+
|
||||
+unexpand in in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+LANG=C unexpand in in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
||||
+
|
||||
+LC_ALL=C unexpand in in > out || fail=1
|
||||
+compare exp out > /dev/null 2>&1 || fail=1
|
|
@ -106,7 +106,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c
|
|||
{"spaces", no_argument, NULL, 's'},
|
||||
{"width", required_argument, NULL, 'w'},
|
||||
{GETOPT_HELP_OPTION_DECL},
|
||||
@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing t
|
||||
@@ -75,6 +118,7 @@ Wrap input lines in each FILE, writing to standard output.\n\
|
||||
|
||||
fputs (_("\
|
||||
-b, --bytes count bytes rather than columns\n\
|
||||
|
@ -114,7 +114,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c
|
|||
-s, --spaces break at spaces\n\
|
||||
-w, --width=WIDTH use WIDTH columns instead of 80\n\
|
||||
"), stdout);
|
||||
@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing t
|
||||
@@ -92,7 +136,7 @@ Wrap input lines in each FILE, writing to standard output.\n\
|
||||
static size_t
|
||||
adjust_column (size_t column, char c)
|
||||
{
|
||||
|
@ -156,7 +156,7 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c
|
|||
|
||||
fadvise (istream, FADVISE_SEQUENTIAL);
|
||||
|
||||
@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t
|
||||
@@ -168,6 +196,15 @@ fold_file (char const *filename, size_t width)
|
||||
bool found_blank = false;
|
||||
size_t logical_end = offset_out;
|
||||
|
||||
|
@ -172,16 +172,16 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c
|
|||
/* Look for the last blank. */
|
||||
while (logical_end)
|
||||
{
|
||||
@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t
|
||||
@@ -214,11 +251,221 @@ fold_file (char const *filename, size_t width)
|
||||
line_out[offset_out++] = c;
|
||||
}
|
||||
|
||||
- saved_errno = errno;
|
||||
+ *saved_errno = errno;
|
||||
+
|
||||
+ if (offset_out)
|
||||
+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
|
||||
+
|
||||
|
||||
if (offset_out)
|
||||
fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
|
||||
|
||||
+}
|
||||
+
|
||||
+#if HAVE_MBRTOWC
|
||||
|
@ -353,10 +353,10 @@ diff -urNp coreutils-8.24-orig/src/fold.c coreutils-8.24/src/fold.c
|
|||
+ }
|
||||
+
|
||||
+ *saved_errno = errno;
|
||||
|
||||
if (offset_out)
|
||||
fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
|
||||
|
||||
+
|
||||
+ if (offset_out)
|
||||
+ fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
|
||||
+
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
|
@ -642,7 +642,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c
|
|||
static void
|
||||
freeline (struct line *line)
|
||||
{
|
||||
@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct
|
||||
@@ -326,56 +484,133 @@ keycmp (struct line const *line1, struct line const *line2,
|
||||
size_t jf_1, size_t jf_2)
|
||||
{
|
||||
/* Start of field to compare in each file. */
|
||||
|
@ -773,8 +773,8 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c
|
|||
- diff = memcmp (beg1, beg2, MIN (len1, len2));
|
||||
+ copy[0] = beg[0];
|
||||
+ copy[1] = beg[1];
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ if (hard_LC_COLLATE)
|
||||
+ {
|
||||
+ diff = xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]);
|
||||
|
@ -784,14 +784,14 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c
|
|||
+ free (copy[i]);
|
||||
+
|
||||
+ return diff;
|
||||
}
|
||||
+ }
|
||||
+ diff = memcmp (copy[0], copy[1], MIN (len[0], len[1]));
|
||||
+
|
||||
+ if (mallocd)
|
||||
+ for (i = 0; i < 2; i++)
|
||||
+ free (copy[i]);
|
||||
+
|
||||
|
||||
+
|
||||
if (diff)
|
||||
return diff;
|
||||
- return len1 < len2 ? -1 : len1 != len2;
|
||||
|
@ -799,7 +799,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c
|
|||
}
|
||||
|
||||
/* Check that successive input lines PREV and CURRENT from input file
|
||||
@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep,
|
||||
@@ -467,6 +702,11 @@ get_line (FILE *fp, struct line **linep, int which)
|
||||
}
|
||||
++line_no[which - 1];
|
||||
|
||||
|
@ -811,7 +811,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c
|
|||
xfields (line);
|
||||
|
||||
if (prevline[which - 1])
|
||||
@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *li
|
||||
@@ -566,21 +806,28 @@ prfield (size_t n, struct line const *line)
|
||||
|
||||
/* Output all the fields in line, other than the join field. */
|
||||
|
||||
|
@ -851,7 +851,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c
|
|||
size_t field;
|
||||
struct line const *line;
|
||||
|
||||
@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct
|
||||
@@ -625,7 +871,7 @@ prjoin (struct line const *line1, struct line const *line2)
|
||||
o = o->next;
|
||||
if (o == NULL)
|
||||
break;
|
||||
|
@ -920,7 +920,7 @@ diff -urNp coreutils-8.24-orig/src/join.c coreutils-8.24/src/join.c
|
|||
diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
||||
--- coreutils-8.24-orig/src/pr.c 2015-06-26 19:05:22.000000000 +0200
|
||||
+++ coreutils-8.24/src/pr.c 2015-07-05 09:04:33.030546965 +0200
|
||||
@@ -312,6 +312,24 @@
|
||||
@@ -311,6 +311,24 @@
|
||||
|
||||
#include <getopt.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -945,7 +945,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
#include "system.h"
|
||||
#include "error.h"
|
||||
#include "fadvise.h"
|
||||
@@ -324,6 +342,18 @@
|
||||
@@ -323,6 +341,18 @@
|
||||
#include "xstrtol.h"
|
||||
#include "xdectoint.h"
|
||||
|
||||
|
@ -964,7 +964,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
/* The official name of this program (e.g., no 'g' prefix). */
|
||||
#define PROGRAM_NAME "pr"
|
||||
|
||||
@@ -416,7 +446,20 @@ struct COLUMN
|
||||
@@ -415,7 +445,20 @@ struct COLUMN
|
||||
|
||||
typedef struct COLUMN COLUMN;
|
||||
|
||||
|
@ -986,7 +986,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
static bool read_line (COLUMN *p);
|
||||
static bool print_page (void);
|
||||
static bool print_stored (COLUMN *p);
|
||||
@@ -428,6 +471,7 @@ static void add_line_number (COLUMN *p);
|
||||
@@ -427,6 +470,7 @@ static void add_line_number (COLUMN *p);
|
||||
static void getoptnum (const char *n_str, int min, int *num,
|
||||
const char *errfmt);
|
||||
static void getoptarg (char *arg, char switch_char, char *character,
|
||||
|
@ -994,7 +994,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
int *number);
|
||||
static void print_files (int number_of_files, char **av);
|
||||
static void init_parameters (int number_of_files);
|
||||
@@ -441,7 +485,6 @@ static void store_char (char c);
|
||||
@@ -440,7 +484,6 @@ static void store_char (char c);
|
||||
static void pad_down (unsigned int lines);
|
||||
static void read_rest_of_line (COLUMN *p);
|
||||
static void skip_read (COLUMN *p, int column_number);
|
||||
|
@ -1002,7 +1002,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
static void cleanup (void);
|
||||
static void print_sep_string (void);
|
||||
static void separator_string (const char *optarg_S);
|
||||
@@ -453,7 +496,7 @@ static COLUMN *column_vector;
|
||||
@@ -452,7 +495,7 @@ static COLUMN *column_vector;
|
||||
we store the leftmost columns contiguously in buff.
|
||||
To print a line from buff, get the index of the first character
|
||||
from line_vector[i], and print up to line_vector[i + 1]. */
|
||||
|
@ -1011,7 +1011,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
|
||||
/* Index of the position in buff where the next character
|
||||
will be stored. */
|
||||
@@ -557,7 +600,7 @@ static int chars_per_column;
|
||||
@@ -556,7 +599,7 @@ static int chars_per_column;
|
||||
static bool untabify_input = false;
|
||||
|
||||
/* (-e) The input tab character. */
|
||||
|
@ -1020,7 +1020,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
|
||||
/* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
|
||||
where the leftmost column is 1. */
|
||||
@@ -567,7 +610,10 @@ static int chars_per_input_tab = 8;
|
||||
@@ -566,7 +609,10 @@ static int chars_per_input_tab = 8;
|
||||
static bool tabify_output = false;
|
||||
|
||||
/* (-i) The output tab character. */
|
||||
|
@ -1032,7 +1032,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
|
||||
/* (-i) The width of the output tab. */
|
||||
static int chars_per_output_tab = 8;
|
||||
@@ -637,7 +683,13 @@ static int line_number;
|
||||
@@ -636,7 +682,13 @@ static int line_number;
|
||||
static bool numbered_lines = false;
|
||||
|
||||
/* (-n) Character which follows each line number. */
|
||||
|
@ -1047,7 +1047,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
|
||||
/* (-n) line counting starts with 1st line of input file (not with 1st
|
||||
line of 1st page printed). */
|
||||
@@ -690,6 +742,7 @@ static bool use_col_separator = false;
|
||||
@@ -689,6 +741,7 @@ static bool use_col_separator = false;
|
||||
-a|COLUMN|-m is a 'space' and with the -J option a 'tab'. */
|
||||
static char *col_sep_string = (char *) "";
|
||||
static int col_sep_length = 0;
|
||||
|
@ -1055,7 +1055,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
static char *column_separator = (char *) " ";
|
||||
static char *line_separator = (char *) "\t";
|
||||
|
||||
@@ -840,6 +893,13 @@ separator_string (const char *optarg_S)
|
||||
@@ -839,6 +892,13 @@ separator_string (const char *optarg_S)
|
||||
col_sep_length = (int) strlen (optarg_S);
|
||||
col_sep_string = xmalloc (col_sep_length + 1);
|
||||
strcpy (col_sep_string, optarg_S);
|
||||
|
@ -1069,7 +1069,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
}
|
||||
|
||||
int
|
||||
@@ -864,6 +924,21 @@ main (int argc, char **argv)
|
||||
@@ -863,6 +923,21 @@ main (int argc, char **argv)
|
||||
|
||||
atexit (close_stdout);
|
||||
|
||||
|
@ -1091,7 +1091,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
n_files = 0;
|
||||
file_names = (argc > 1
|
||||
? xmalloc ((argc - 1) * sizeof (char *))
|
||||
@@ -940,8 +1015,12 @@ main (int argc, char **argv)
|
||||
@@ -939,8 +1014,12 @@ main (int argc, char **argv)
|
||||
break;
|
||||
case 'e':
|
||||
if (optarg)
|
||||
|
@ -1106,7 +1106,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
/* Could check tab width > 0. */
|
||||
untabify_input = true;
|
||||
break;
|
||||
@@ -954,8 +1033,12 @@ main (int argc, char **argv)
|
||||
@@ -953,8 +1032,12 @@ main (int argc, char **argv)
|
||||
break;
|
||||
case 'i':
|
||||
if (optarg)
|
||||
|
@ -1121,7 +1121,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
/* Could check tab width > 0. */
|
||||
tabify_output = true;
|
||||
break;
|
||||
@@ -973,8 +1056,8 @@ main (int argc, char **argv)
|
||||
@@ -972,8 +1055,8 @@ main (int argc, char **argv)
|
||||
case 'n':
|
||||
numbered_lines = true;
|
||||
if (optarg)
|
||||
|
@ -1132,7 +1132,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
break;
|
||||
case 'N':
|
||||
skip_count = false;
|
||||
@@ -998,7 +1081,7 @@ main (int argc, char **argv)
|
||||
@@ -997,7 +1080,7 @@ main (int argc, char **argv)
|
||||
old_s = false;
|
||||
/* Reset an additional input of -s, -S dominates -s */
|
||||
col_sep_string = bad_cast ("");
|
||||
|
@ -1141,7 +1141,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
use_col_separator = true;
|
||||
if (optarg)
|
||||
separator_string (optarg);
|
||||
@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, i
|
||||
@@ -1152,10 +1235,45 @@ getoptnum (const char *n_str, int min, int *num, const char *err)
|
||||
a number. */
|
||||
|
||||
static void
|
||||
|
@ -1359,7 +1359,7 @@ diff -urNp coreutils-8.24-orig/src/pr.c coreutils-8.24/src/pr.c
|
|||
/* sep_string ends with some spaces */
|
||||
if (spaces_not_printed > 0)
|
||||
print_white_space ();
|
||||
@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clu
|
||||
@@ -2259,7 +2389,7 @@ print_clump (COLUMN *p, int n, char *clump)
|
||||
required number of tabs and spaces. */
|
||||
|
||||
static void
|
||||
|
@ -1701,7 +1701,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
#include "system.h"
|
||||
#include "argmatch.h"
|
||||
#include "error.h"
|
||||
@@ -164,14 +172,39 @@ static int decimal_point;
|
||||
@@ -163,14 +171,39 @@ static int decimal_point;
|
||||
/* Thousands separator; if -1, then there isn't one. */
|
||||
static int thousands_sep;
|
||||
|
||||
|
@ -1742,7 +1742,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
/* The kind of blanks for '-b' to skip in various options. */
|
||||
enum blanktype { bl_start, bl_end, bl_both };
|
||||
|
||||
@@ -345,13 +378,11 @@ static bool reverse;
|
||||
@@ -344,13 +377,11 @@ static bool reverse;
|
||||
they were read if all keys compare equal. */
|
||||
static bool stable;
|
||||
|
||||
|
@ -1815,7 +1815,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
|
||||
static int
|
||||
struct_month_cmp (void const *m1, void const *m2)
|
||||
@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void c
|
||||
@@ -1269,7 +1340,7 @@ struct_month_cmp (void const *m1, void const *m2)
|
||||
/* Initialize the character class tables. */
|
||||
|
||||
static void
|
||||
|
@ -1833,7 +1833,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
/* If we're not in the "C" locale, read different names for months. */
|
||||
if (hard_LC_TIME)
|
||||
{
|
||||
@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char con
|
||||
@@ -1363,6 +1434,84 @@ specify_nmerge (int oi, char c, char const *s)
|
||||
xstrtol_fatal (e, oi, c, long_options, s);
|
||||
}
|
||||
|
||||
|
@ -1918,7 +1918,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
/* Specify the amount of main memory to use when sorting. */
|
||||
static void
|
||||
specify_sort_size (int oi, char c, char const *s)
|
||||
@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf
|
||||
@@ -1596,7 +1745,7 @@ buffer_linelim (struct buffer const *buf)
|
||||
by KEY in LINE. */
|
||||
|
||||
static char *
|
||||
|
@ -1927,7 +1927,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
{
|
||||
char *ptr = line->text, *lim = ptr + line->length - 1;
|
||||
size_t sword = key->sword;
|
||||
@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struc
|
||||
@@ -1605,10 +1754,10 @@ begfield (struct line const *line, struct keyfield const *key)
|
||||
/* The leading field separator itself is included in a field when -t
|
||||
is absent. */
|
||||
|
||||
|
@ -1940,7 +1940,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
++ptr;
|
||||
if (ptr < lim)
|
||||
++ptr;
|
||||
@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struc
|
||||
@@ -1634,11 +1783,70 @@ begfield (struct line const *line, struct keyfield const *key)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -2012,7 +2012,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
{
|
||||
char *ptr = line->text, *lim = ptr + line->length - 1;
|
||||
size_t eword = key->eword, echar = key->echar;
|
||||
@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struc
|
||||
@@ -1653,10 +1861,10 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
'beginning' is the first character following the delimiting TAB.
|
||||
Otherwise, leave PTR pointing at the first 'blank' character after
|
||||
the preceding field. */
|
||||
|
@ -2025,7 +2025,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
++ptr;
|
||||
if (ptr < lim && (eword || echar))
|
||||
++ptr;
|
||||
@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struc
|
||||
@@ -1702,10 +1910,10 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
*/
|
||||
|
||||
/* Make LIM point to the end of (one byte past) the current field. */
|
||||
|
@ -2038,7 +2038,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
if (newlim)
|
||||
lim = newlim;
|
||||
}
|
||||
@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struc
|
||||
@@ -1736,6 +1944,130 @@ limfield (struct line const *line, struct keyfield const *key)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -2169,7 +2169,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
/* Fill BUF reading from FP, moving buf->left bytes from the end
|
||||
of buf->buf to the beginning first. If EOF is reached and the
|
||||
file wasn't terminated by a newline, supply one. Set up BUF's line
|
||||
@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, c
|
||||
@@ -1822,8 +2154,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file)
|
||||
else
|
||||
{
|
||||
if (key->skipsblanks)
|
||||
|
@ -2194,7 +2194,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
line->keybeg = line_start;
|
||||
}
|
||||
}
|
||||
@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char co
|
||||
@@ -1944,7 +2290,7 @@ human_numcompare (char const *a, char const *b)
|
||||
hideously fast. */
|
||||
|
||||
static int
|
||||
|
@ -2203,7 +2203,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
{
|
||||
while (blanks[to_uchar (*a)])
|
||||
a++;
|
||||
@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b
|
||||
@@ -1954,6 +2300,25 @@ numcompare (char const *a, char const *b)
|
||||
return strnumcmp (a, b, decimal_point, thousands_sep);
|
||||
}
|
||||
|
||||
|
@ -2229,7 +2229,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
/* Work around a problem whereby the long double value returned by glibc's
|
||||
strtold ("NaN", ...) contains uninitialized bits: clear all bytes of
|
||||
A and B before calling strtold. FIXME: remove this function once
|
||||
@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char
|
||||
@@ -2004,7 +2369,7 @@ general_numcompare (char const *sa, char const *sb)
|
||||
Return 0 if the name in S is not recognized. */
|
||||
|
||||
static int
|
||||
|
@ -2238,7 +2238,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
{
|
||||
size_t lo = 0;
|
||||
size_t hi = MONTHS_PER_YEAR;
|
||||
@@ -2279,15 +2644,14 @@ debug_key (struct line const *line, stru
|
||||
@@ -2280,15 +2645,14 @@ debug_key (struct line const *line, struct keyfield const *key)
|
||||
char saved = *lim;
|
||||
*lim = '\0';
|
||||
|
||||
|
@ -2256,7 +2256,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
else if (key->general_numeric)
|
||||
ignore_value (strtold (beg, &tighter_lim));
|
||||
else if (key->numeric || key->human_numeric)
|
||||
@@ -2431,7 +2795,7 @@ key_warnings (struct keyfield const *gke
|
||||
@@ -2432,7 +2796,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key)
|
||||
&& !(key->schar || key->echar);
|
||||
bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */
|
||||
|
@ -2265,7 +2265,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
&& ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned))
|
||||
|| (!key->skipsblanks && key->schar)
|
||||
|| (!key->skipeblanks && key->echar)))
|
||||
@@ -2489,11 +2853,87 @@ key_warnings (struct keyfield const *gke
|
||||
@@ -2490,11 +2854,87 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
|
||||
error (0, 0, _("option '-r' only applies to last-resort comparison"));
|
||||
}
|
||||
|
||||
|
@ -2354,7 +2354,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
{
|
||||
struct keyfield *key = keylist;
|
||||
|
||||
@@ -2578,7 +3018,7 @@ keycompare (struct line const *a, struct
|
||||
@@ -2579,7 +3019,7 @@ keycompare (struct line const *a, struct line const *b)
|
||||
else if (key->human_numeric)
|
||||
diff = human_numcompare (ta, tb);
|
||||
else if (key->month)
|
||||
|
@ -2363,7 +2363,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
else if (key->random)
|
||||
diff = compare_random (ta, tlena, tb, tlenb);
|
||||
else if (key->version)
|
||||
@@ -2694,6 +3134,211 @@ keycompare (struct line const *a, struct
|
||||
@@ -2695,6 +3135,211 @@ keycompare (struct line const *a, struct line const *b)
|
||||
return key->reverse ? -diff : diff;
|
||||
}
|
||||
|
||||
|
@ -2575,7 +2575,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
/* Compare two lines A and B, returning negative, zero, or positive
|
||||
depending on whether A compares less than, equal to, or greater than B. */
|
||||
|
||||
@@ -2721,7 +3366,7 @@ compare (struct line const *a, struct line const *b)
|
||||
@@ -2722,7 +3367,7 @@ compare (struct line const *a, struct line const *b)
|
||||
diff = - NONZERO (blen);
|
||||
else if (blen == 0)
|
||||
diff = 1;
|
||||
|
@ -2584,7 +2584,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
{
|
||||
/* Note xmemcoll0 is a performance enhancement as
|
||||
it will not unconditionally write '\0' after the
|
||||
@@ -4120,6 +4765,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype)
|
||||
@@ -4121,6 +4766,7 @@ set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype)
|
||||
break;
|
||||
case 'f':
|
||||
key->translate = fold_toupper;
|
||||
|
@ -2592,7 +2592,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
break;
|
||||
case 'g':
|
||||
key->general_numeric = true;
|
||||
@@ -4197,7 +4843,7 @@ main (int argc, char **argv)
|
||||
@@ -4199,7 +4845,7 @@ main (int argc, char **argv)
|
||||
initialize_exit_failure (SORT_FAILURE);
|
||||
|
||||
hard_LC_COLLATE = hard_locale (LC_COLLATE);
|
||||
|
@ -2601,7 +2601,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
hard_LC_TIME = hard_locale (LC_TIME);
|
||||
#endif
|
||||
|
||||
@@ -4218,6 +4864,29 @@ main (int argc, char **argv)
|
||||
@@ -4220,6 +4866,29 @@ main (int argc, char **argv)
|
||||
thousands_sep = -1;
|
||||
}
|
||||
|
||||
|
@ -2631,7 +2631,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
have_read_stdin = false;
|
||||
inittables ();
|
||||
|
||||
@@ -4492,13 +5161,34 @@ main (int argc, char **argv)
|
||||
@@ -4494,13 +5163,34 @@ main (int argc, char **argv)
|
||||
|
||||
case 't':
|
||||
{
|
||||
|
@ -2670,7 +2670,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
else
|
||||
{
|
||||
/* Provoke with 'sort -txx'. Complain about
|
||||
@@ -4509,9 +5199,12 @@ main (int argc, char **argv)
|
||||
@@ -4511,9 +5201,12 @@ main (int argc, char **argv)
|
||||
quote (optarg));
|
||||
}
|
||||
}
|
||||
|
@ -2685,7 +2685,7 @@ diff -urNp coreutils-8.24-orig/src/sort.c coreutils-8.24/src/sort.c
|
|||
}
|
||||
break;
|
||||
|
||||
@@ -5444,12 +5444,10 @@ main (int argc, char **argv)
|
||||
@@ -4751,12 +5444,10 @@ main (int argc, char **argv)
|
||||
sort (files, nfiles, outfile, nthreads);
|
||||
}
|
||||
|
||||
|
@ -2719,14 +2719,14 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
#include "system.h"
|
||||
#include "argmatch.h"
|
||||
#include "linebuffer.h"
|
||||
@@ -32,8 +43,20 @@
|
||||
@@ -31,9 +42,21 @@
|
||||
#include "stdio--.h"
|
||||
#include "xmemcoll.h"
|
||||
#include "xstrtol.h"
|
||||
-#include "memcasecmp.h"
|
||||
+#include "xmemcoll.h"
|
||||
#include "quote.h"
|
||||
+
|
||||
|
||||
+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
|
||||
+ installation; work around this configuration error. */
|
||||
+#if !defined MB_LEN_MAX || MB_LEN_MAX < 2
|
||||
|
@ -2738,9 +2738,10 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
|
||||
+#endif
|
||||
+
|
||||
|
||||
+
|
||||
/* The official name of this program (e.g., no 'g' prefix). */
|
||||
#define PROGRAM_NAME "uniq"
|
||||
|
||||
@@ -143,6 +166,10 @@ enum
|
||||
GROUP_OPTION = CHAR_MAX + 1
|
||||
};
|
||||
|
@ -2752,7 +2753,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
static struct option const longopts[] =
|
||||
{
|
||||
{"count", no_argument, NULL, 'c'},
|
||||
@@ -251,7 +278,7 @@ size_opt (char const *opt, char const *m
|
||||
@@ -252,7 +279,7 @@ size_opt (char const *opt, char const *msgid)
|
||||
return a pointer to the beginning of the line's field to be compared. */
|
||||
|
||||
static char * _GL_ATTRIBUTE_PURE
|
||||
|
@ -2761,7 +2762,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
{
|
||||
size_t count;
|
||||
char const *lp = line->buffer;
|
||||
@@ -271,6 +298,83 @@ find_field (struct linebuffer const *lin
|
||||
@@ -272,6 +299,83 @@ find_field (struct linebuffer const *line)
|
||||
return line->buffer + i;
|
||||
}
|
||||
|
||||
|
@ -2845,7 +2846,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
/* Return false if two strings OLD and NEW match, true if not.
|
||||
OLD and NEW point not to the beginnings of the lines
|
||||
but rather to the beginnings of the fields to compare.
|
||||
@@ -279,6 +383,8 @@ find_field (struct linebuffer const *lin
|
||||
@@ -280,6 +384,8 @@ find_field (struct linebuffer const *line)
|
||||
static bool
|
||||
different (char *old, char *new, size_t oldlen, size_t newlen)
|
||||
{
|
||||
|
@ -2854,7 +2855,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
if (check_chars < oldlen)
|
||||
oldlen = check_chars;
|
||||
if (check_chars < newlen)
|
||||
@@ -286,15 +392,104 @@ different (char *old, char *new, size_t
|
||||
@@ -287,14 +393,103 @@ different (char *old, char *new, size_t oldlen, size_t newlen)
|
||||
|
||||
if (ignore_case)
|
||||
{
|
||||
|
@ -2886,8 +2887,8 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
+
|
||||
+ return xmemcoll (copy_old, oldlen, copy_new, newlen);
|
||||
+
|
||||
}
|
||||
|
||||
+}
|
||||
+
|
||||
+#if HAVE_MBRTOWC
|
||||
+static int
|
||||
+different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate)
|
||||
|
@ -2958,13 +2959,12 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
+ free (copy[1]);
|
||||
+ return rc;
|
||||
+
|
||||
+}
|
||||
}
|
||||
+#endif
|
||||
+
|
||||
|
||||
/* Output the line in linebuffer LINE to standard output
|
||||
provided that the switches say it should be output.
|
||||
MATCH is true if the line matches the previous line.
|
||||
@@ -358,19 +553,38 @@ check_file (const char *infile, const ch
|
||||
@@ -359,19 +554,38 @@ check_file (const char *infile, const char *outfile, char delimiter)
|
||||
char *prevfield IF_LINT ( = NULL);
|
||||
size_t prevlen IF_LINT ( = 0);
|
||||
bool first_group_printed = false;
|
||||
|
@ -3003,7 +3003,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
new_group = (prevline->length == 0
|
||||
|| different (thisfield, prevfield, thislen, prevlen));
|
||||
|
||||
@@ -388,6 +602,10 @@ check_file (const char *infile, const ch
|
||||
@@ -389,6 +603,10 @@ check_file (const char *infile, const char *outfile, char delimiter)
|
||||
SWAP_LINES (prevline, thisline);
|
||||
prevfield = thisfield;
|
||||
prevlen = thislen;
|
||||
|
@ -3014,7 +3014,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
first_group_printed = true;
|
||||
}
|
||||
}
|
||||
@@ -400,17 +618,26 @@ check_file (const char *infile, const ch
|
||||
@@ -401,17 +619,26 @@ check_file (const char *infile, const char *outfile, char delimiter)
|
||||
size_t prevlen;
|
||||
uintmax_t match_count = 0;
|
||||
bool first_delimiter = true;
|
||||
|
@ -3041,7 +3041,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
|
||||
{
|
||||
if (ferror (stdin))
|
||||
@@ -419,6 +646,14 @@ check_file (const char *infile, const ch
|
||||
@@ -420,6 +647,14 @@ check_file (const char *infile, const char *outfile, char delimiter)
|
||||
}
|
||||
thisfield = find_field (thisline);
|
||||
thislen = thisline->length - 1 - (thisfield - thisline->buffer);
|
||||
|
@ -3056,7 +3056,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
match = !different (thisfield, prevfield, thislen, prevlen);
|
||||
match_count += match;
|
||||
|
||||
@@ -451,6 +686,9 @@ check_file (const char *infile, const ch
|
||||
@@ -452,6 +687,9 @@ check_file (const char *infile, const char *outfile, char delimiter)
|
||||
SWAP_LINES (prevline, thisline);
|
||||
prevfield = thisfield;
|
||||
prevlen = thislen;
|
||||
|
@ -3066,7 +3066,7 @@ diff -urNp coreutils-8.24-orig/src/uniq.c coreutils-8.24/src/uniq.c
|
|||
if (!match)
|
||||
match_count = 0;
|
||||
}
|
||||
@@ -497,6 +735,19 @@ main (int argc, char **argv)
|
||||
@@ -498,6 +736,19 @@ main (int argc, char **argv)
|
||||
|
||||
atexit (close_stdout);
|
||||
|
||||
|
@ -3122,7 +3122,7 @@ diff -urNp coreutils-8.24-orig/tests/i18n/sort.sh coreutils-8.24/tests/i18n/sort
|
|||
diff -urNp coreutils-8.24-orig/tests/local.mk coreutils-8.24/tests/local.mk
|
||||
--- coreutils-8.24-orig/tests/local.mk 2015-07-05 09:00:46.526859558 +0200
|
||||
+++ coreutils-8.24/tests/local.mk 2015-07-05 09:04:33.033546987 +0200
|
||||
@@ -341,6 +341,8 @@ all_tests = \
|
||||
@@ -344,6 +344,8 @@ all_tests = \
|
||||
tests/misc/sort-discrim.sh \
|
||||
tests/misc/sort-files0-from.pl \
|
||||
tests/misc/sort-float.sh \
|
||||
|
@ -3148,7 +3148,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/cut.pl coreutils-8.24/tests/misc/cut.p
|
|||
|
||||
my $prog = 'cut';
|
||||
my $try = "Try '$prog --help' for more information.\n";
|
||||
@@ -227,6 +229,7 @@ if ($mb_locale ne 'C')
|
||||
@@ -240,6 +242,7 @@ if ($mb_locale ne 'C')
|
||||
my @new_t = @$t;
|
||||
my $test_name = shift @new_t;
|
||||
|
||||
|
@ -3304,7 +3304,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/join.pl coreutils-8.24/tests/misc/join
|
|||
my $delim = chr 0247;
|
||||
sub t_subst ($)
|
||||
{
|
||||
@@ -326,8 +335,49 @@ foreach my $t (@tv)
|
||||
@@ -329,8 +338,49 @@ foreach my $t (@tv)
|
||||
push @Tests, $new_ent;
|
||||
}
|
||||
|
||||
|
@ -3482,7 +3482,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/sort.pl coreutils-8.24/tests/misc/sort
|
|||
# Since each test is run with a file name and with redirected stdin,
|
||||
# the name in the diagnostic is either the file name or "-".
|
||||
# Normalize each diagnostic to use '-'.
|
||||
@@ -419,6 +428,38 @@ foreach my $t (@Tests)
|
||||
@@ -424,6 +429,38 @@ foreach my $t (@Tests)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3521,7 +3521,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/sort.pl coreutils-8.24/tests/misc/sort
|
|||
@Tests = triple_test \@Tests;
|
||||
|
||||
# Remember that triple_test creates from each test with exactly one "IN"
|
||||
@@ -428,6 +469,7 @@ foreach my $t (@Tests)
|
||||
@@ -433,6 +470,7 @@ foreach my $t (@Tests)
|
||||
# Remove the IN_PIPE version of the "output-is-input" test above.
|
||||
# The others aren't susceptible because they have three inputs each.
|
||||
@Tests = grep {$_->[0] ne 'output-is-input.p'} @Tests;
|
||||
|
@ -3606,7 +3606,7 @@ diff -urNp coreutils-8.24-orig/tests/misc/uniq.pl coreutils-8.24/tests/misc/uniq
|
|||
# When possible, create a "-z"-testing variant of each test.
|
||||
sub add_z_variants($)
|
||||
{
|
||||
@@ -261,6 +269,53 @@ foreach my $t (@Tests)
|
||||
@@ -262,6 +270,53 @@ foreach my $t (@Tests)
|
||||
and push @$t, {ENV=>'_POSIX2_VERSION=199209'};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- coreutils-5.2.1/src/who.c.overflow 2005-05-25 09:59:06.000000000 +0100
|
||||
+++ coreutils-5.2.1/src/who.c 2005-05-25 10:00:31.000000000 +0100
|
||||
@@ -75,7 +75,7 @@
|
||||
@@ -79,7 +79,7 @@
|
||||
# define UT_TYPE_NEW_TIME(U) false
|
||||
#endif
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ diff -urNp coreutils-8.21-orig/man/runcon.x coreutils-8.21/man/runcon.x
|
|||
diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c
|
||||
--- coreutils-8.21-orig/src/cp.c 2013-02-07 10:37:05.000000000 +0100
|
||||
+++ coreutils-8.21/src/cp.c 2013-02-15 14:31:58.945468929 +0100
|
||||
@@ -201,6 +202,9 @@ Copy SOURCE to DEST, or multiple SOURCE(
|
||||
@@ -202,6 +202,9 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
|
||||
all\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
|
@ -30,7 +30,7 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c
|
|||
--no-preserve=ATTR_LIST don't preserve the specified attributes\n\
|
||||
--parents use full source file name under DIRECTORY\n\
|
||||
"), stdout);
|
||||
@@ -933,7 +939,7 @@ main (int argc, char **argv)
|
||||
@@ -943,7 +946,7 @@ main (int argc, char **argv)
|
||||
we'll actually use backup_suffix_string. */
|
||||
backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
|
||||
|
||||
|
@ -39,7 +39,7 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c
|
|||
long_opts, NULL))
|
||||
!= -1)
|
||||
{
|
||||
@@ -981,6 +987,17 @@ main (int argc, char **argv)
|
||||
@@ -991,6 +994,17 @@ main (int argc, char **argv)
|
||||
copy_contents = true;
|
||||
break;
|
||||
|
||||
|
@ -60,7 +60,7 @@ diff -urNp coreutils-8.21-orig/src/cp.c coreutils-8.21/src/cp.c
|
|||
diff -urNp coreutils-8.21-orig/src/id.c coreutils-8.21/src/id.c
|
||||
--- coreutils-8.21-orig/src/id.c 2013-01-31 01:46:24.000000000 +0100
|
||||
+++ coreutils-8.21/src/id.c 2013-02-15 14:31:58.946469154 +0100
|
||||
@@ -106,7 +106,7 @@ int
|
||||
@@ -113,7 +113,7 @@ int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int optc;
|
||||
|
@ -72,7 +72,7 @@ diff -urNp coreutils-8.21-orig/src/id.c coreutils-8.21/src/id.c
|
|||
diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c
|
||||
--- coreutils-8.21-orig/src/install.c 2013-02-07 10:37:05.000000000 +0100
|
||||
+++ coreutils-8.21/src/install.c 2013-02-15 14:31:58.948469440 +0100
|
||||
@@ -639,7 +640,7 @@ In the 4th form, create all components o
|
||||
@@ -649,7 +649,7 @@ In the 4th form, create all components of the given DIRECTORY(ies).\n\
|
||||
-v, --verbose print the name of each directory as it is created\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
|
@ -81,7 +81,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c
|
|||
-Z set SELinux security context of destination\n\
|
||||
file to default type\n\
|
||||
--context[=CTX] like -Z, or if CTX is specified then set the\n\
|
||||
@@ -782,7 +783,7 @@ main (int argc, char **argv)
|
||||
@@ -817,7 +817,7 @@ main (int argc, char **argv)
|
||||
we'll actually use backup_suffix_string. */
|
||||
backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
|
||||
|
||||
|
@ -90,7 +90,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c
|
|||
NULL)) != -1)
|
||||
{
|
||||
switch (optc)
|
||||
@@ -853,6 +854,8 @@ main (int argc, char **argv)
|
||||
@@ -878,6 +878,8 @@ main (int argc, char **argv)
|
||||
no_target_directory = true;
|
||||
break;
|
||||
|
||||
|
@ -99,7 +99,7 @@ diff -urNp coreutils-8.21-orig/src/install.c coreutils-8.21/src/install.c
|
|||
case PRESERVE_CONTEXT_OPTION:
|
||||
if (! selinux_enabled)
|
||||
{
|
||||
@@ -860,6 +862,10 @@ main (int argc, char **argv)
|
||||
@@ -885,6 +887,10 @@ main (int argc, char **argv)
|
||||
"this kernel is not SELinux-enabled"));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
diff -urNp coreutils-6.10-orig/doc/coreutils.texi coreutils-6.10/doc/coreutils.texi
|
||||
--- coreutils-6.10-orig/doc/coreutils.texi 2008-04-07 17:52:11.000000000 +0200
|
||||
+++ coreutils-6.10/doc/coreutils.texi 2008-04-07 18:01:43.000000000 +0200
|
||||
@@ -6981,6 +6981,11 @@ for i; do
|
||||
@@ -8002,6 +8002,11 @@ done
|
||||
exit $fail
|
||||
@end example
|
||||
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
From ba5fe2d4b8b6a8366f48b1ad1f97fe26c9089b53 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Kisela <skisela@redhat.com>
|
||||
Date: Wed, 5 Apr 2017 09:40:41 +0200
|
||||
Subject: [PATCH] tail: revert to polling if a followed directory is replaced
|
||||
|
||||
* src/tail.c (tail_forever_inotify): Add the IN_DELETE_SELF flag when
|
||||
creating watch for the parent directory. After the parent directory
|
||||
is removed, an event is caught and then we switch from inotify to
|
||||
polling mode. Till now, inotify has always frozen because it waited for
|
||||
an event from a watched dir, which has been already deleted and was not
|
||||
added again.
|
||||
* tests/tail-2/inotify-dir-recreate.sh: Add a test case.
|
||||
* tests/local.mk: Reference the new test.
|
||||
Fixes http://bugs.gnu.org/26363
|
||||
Reported at https://bugzilla.redhat.com/1283760
|
||||
---
|
||||
src/tail.c | 22 +++++++++-
|
||||
tests/local.mk | 1 +
|
||||
tests/tail-2/inotify-dir-recreate.sh | 82 ++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 107 insertions(+), 1 deletion(-)
|
||||
create mode 100755 tests/tail-2/inotify-dir-recreate.sh
|
||||
|
||||
diff --git a/src/tail.c b/src/tail.c
|
||||
index d1552d4..6328fe0 100644
|
||||
--- a/src/tail.c
|
||||
+++ b/src/tail.c
|
||||
@@ -1457,7 +1457,8 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
|
||||
In that case the same watch descriptor is returned. */
|
||||
f[i].parent_wd = inotify_add_watch (wd, dirlen ? f[i].name : ".",
|
||||
(IN_CREATE | IN_DELETE
|
||||
- | IN_MOVED_TO | IN_ATTRIB));
|
||||
+ | IN_MOVED_TO | IN_ATTRIB
|
||||
+ | IN_DELETE_SELF));
|
||||
|
||||
f[i].name[dirlen] = prev;
|
||||
|
||||
@@ -1628,6 +1629,25 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
|
||||
ev = void_ev;
|
||||
evbuf_off += sizeof (*ev) + ev->len;
|
||||
|
||||
+ /* If a directory is deleted, IN_DELETE_SELF is emitted
|
||||
+ with ev->name of length 0.
|
||||
+ We need to catch it, otherwise it would wait forever,
|
||||
+ as wd for directory becomes inactive. Revert to polling now. */
|
||||
+ if ((ev->mask & IN_DELETE_SELF) && ! ev->len)
|
||||
+ {
|
||||
+ for (i = 0; i < n_files; i++)
|
||||
+ {
|
||||
+ if (ev->wd == f[i].parent_wd)
|
||||
+ {
|
||||
+ hash_free (wd_to_name);
|
||||
+ error (0, 0,
|
||||
+ _("directory containing watched file was removed"));
|
||||
+ errno = 0; /* we've already diagnosed enough errno detail. */
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (ev->len) /* event on ev->name in watched directory. */
|
||||
{
|
||||
size_t j;
|
||||
diff --git a/tests/local.mk b/tests/local.mk
|
||||
index 3fe9ba8..e890c9a 100644
|
||||
--- a/tests/local.mk
|
||||
+++ b/tests/local.mk
|
||||
@@ -176,6 +176,7 @@ all_tests = \
|
||||
tests/tail-2/descriptor-vs-rename.sh \
|
||||
tests/tail-2/inotify-rotate.sh \
|
||||
tests/tail-2/inotify-rotate-resources.sh \
|
||||
+ tests/tail-2/inotify-dir-recreate.sh \
|
||||
tests/chmod/no-x.sh \
|
||||
tests/chgrp/basic.sh \
|
||||
tests/rm/dangling-symlink.sh \
|
||||
diff --git a/tests/tail-2/inotify-dir-recreate.sh b/tests/tail-2/inotify-dir-recreate.sh
|
||||
new file mode 100755
|
||||
index 0000000..eaa8422
|
||||
--- /dev/null
|
||||
+++ b/tests/tail-2/inotify-dir-recreate.sh
|
||||
@@ -0,0 +1,82 @@
|
||||
+#!/bin/sh
|
||||
+# Makes sure, inotify will switch to polling mode if directory
|
||||
+# of the watched file was removed and recreated.
|
||||
+# (...instead of getting stuck forever)
|
||||
+
|
||||
+# Copyright (C) 2006-2017 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software: you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation, either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
|
||||
+print_ver_ tail
|
||||
+
|
||||
+
|
||||
+# Terminate any background tail process
|
||||
+cleanup_() { kill $pid 2>/dev/null && wait $pid; }
|
||||
+
|
||||
+cleanup_fail_ ()
|
||||
+{
|
||||
+ warn_ $1
|
||||
+ cleanup_
|
||||
+ fail=1
|
||||
+}
|
||||
+
|
||||
+# $check_re - string to be found
|
||||
+# $check_f - file to be searched
|
||||
+check_tail_output_ ()
|
||||
+{
|
||||
+ local delay="$1"
|
||||
+ grep $check_re $check_f > /dev/null ||
|
||||
+ { sleep $delay ; return 1; }
|
||||
+}
|
||||
+
|
||||
+grep_timeout_ ()
|
||||
+{
|
||||
+ check_re="$1"
|
||||
+ check_f="$2"
|
||||
+ retry_delay_ check_tail_output_ .1 5
|
||||
+}
|
||||
+
|
||||
+# Prepare the file to be watched
|
||||
+mkdir dir && echo 'inotify' > dir/file || framework_failure_
|
||||
+
|
||||
+#tail must print content of the file to stdout, verify
|
||||
+timeout 60 tail -F dir/file &>out & pid=$!
|
||||
+grep_timeout_ 'inotify' 'out' ||
|
||||
+{ cleanup_fail_ 'file to be tailed does not exist'; }
|
||||
+
|
||||
+# Remove the directory, should get the message about the deletion
|
||||
+rm -r dir || framework_failure_
|
||||
+grep_timeout_ 'polling' 'out' ||
|
||||
+{ cleanup_fail_ 'tail did not switch to polling mode'; }
|
||||
+
|
||||
+# Recreate the dir, must get a message about recreation
|
||||
+mkdir dir && touch dir/file || framework_failure_
|
||||
+grep_timeout_ 'appeared' 'out' ||
|
||||
+{ cleanup_fail_ 'previously removed file did not appear'; }
|
||||
+
|
||||
+cleanup_
|
||||
+
|
||||
+# Expected result for the whole process
|
||||
+cat <<\EOF > exp || framework_failure_
|
||||
+inotify
|
||||
+tail: 'dir/file' has become inaccessible: No such file or directory
|
||||
+tail: directory containing watched file was removed
|
||||
+tail: inotify cannot be used, reverting to polling
|
||||
+tail: 'dir/file' has appeared; following new file
|
||||
+EOF
|
||||
+
|
||||
+compare exp out || fail=1
|
||||
+
|
||||
+Exit $fail
|
||||
--
|
||||
2.9.3
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
Summary: A set of basic GNU tools commonly used in shell scripts
|
||||
Name: coreutils
|
||||
Version: 8.25
|
||||
Release: 5%{?dist}
|
||||
Release: 9%{?dist}
|
||||
License: GPLv3+
|
||||
Group: System Environment/Base
|
||||
Url: http://www.gnu.org/software/coreutils/
|
||||
|
@ -21,6 +21,17 @@ Source10: coreutils-find-requires.sh
|
|||
%global __find_requires %{SOURCE10} %{_rpmconfigdir}/find-requires
|
||||
|
||||
# From upstream
|
||||
Patch952: coreutils-8.25-intall-Z-selinux.patch
|
||||
# fix 'sort -h -k' in locales that use blank as thousands separator (#1355780)
|
||||
Patch953: coreutils-8.25-sort-thousands-sep.patch
|
||||
# ls: allow interruption when reading slow directories (#1365933)
|
||||
Patch954: coreutils-8.25-ls-signal.patch
|
||||
# md5sum,sha*sum: fix --ignore-missing with checksums starting with 00
|
||||
Patch955: coreutils-8.25-sum-ignore-missing.patch
|
||||
# install,mkdir: fix handling of -DZ and -pZ, respectively (#1398913)
|
||||
Patch956: coreutils-8.25-mkdir-p-selinux.patch
|
||||
# tail: revert to polling if a followed directory is replaced(#1283760)
|
||||
Patch957: coreutils-tail-inotify-recreate.patch
|
||||
|
||||
# Our patches
|
||||
#general patch to workaround koji build system issues
|
||||
|
@ -49,6 +60,12 @@ Patch802: coreutils-i18n-cut.patch
|
|||
Patch804: coreutils-i18n-cut-old.patch
|
||||
# The unexpand patch above is not correct. Sent to the patch authors
|
||||
Patch803: coreutils-i18n-fix-unexpand.patch
|
||||
#(un)expand - allow multiple files on input - broken by patch 801
|
||||
Patch805: coreutils-i18n-fix2-expand-unexpand.patch
|
||||
#(un)expand - test BOM headers
|
||||
Patch806: coreutils-i18n-un-expand-BOM.patch
|
||||
# make 'sort -h' work for arbitrary column even when using UTF-8 locales
|
||||
Patch807: coreutils-i18n-sort-human.patch
|
||||
|
||||
#getgrouplist() patch from Ulrich Drepper.
|
||||
Patch908: coreutils-getgrouplist.patch
|
||||
|
@ -181,6 +198,9 @@ including documentation and translations.
|
|||
#%%patch802 -p1 -b .i18n-cut
|
||||
%patch803 -p1 -b .i18n-fix-expand
|
||||
%patch804 -p1 -b .i18n-cutold
|
||||
%patch805 -p1 -b .i18n-fix2-expand-unexpand
|
||||
%patch806 -p1 -b .i18n-BOM-expand-unexpand
|
||||
%patch807 -p1
|
||||
|
||||
# Coreutils
|
||||
%patch908 -p1 -b .getgrouplist
|
||||
|
@ -190,8 +210,21 @@ including documentation and translations.
|
|||
#SELinux
|
||||
%patch950 -p1 -b .selinux
|
||||
%patch951 -p1 -b .selinuxman
|
||||
%patch952 -p1
|
||||
|
||||
chmod a+x tests/misc/sort-mb-tests.sh tests/df/direct.sh || :
|
||||
# upstream patches
|
||||
%patch953 -p1
|
||||
%patch954 -p1
|
||||
%patch955 -p1
|
||||
%patch956 -p1
|
||||
%patch957 -p1
|
||||
|
||||
chmod a+x \
|
||||
tests/df/direct.sh \
|
||||
tests/install/install-Z-selinux.sh \
|
||||
tests/misc/sort-h-thousands-sep.sh \
|
||||
tests/misc/sort-mb-tests.sh \
|
||||
|| :
|
||||
|
||||
#fix typos/mistakes in localized documentation(#439410, #440056)
|
||||
find ./po/ -name "*.p*" | xargs \
|
||||
|
@ -352,6 +385,27 @@ fi
|
|||
%license COPYING
|
||||
|
||||
%changelog
|
||||
* Fri Apr 28 2017 Sebastian Kisela <skisela@redhat.com> - 8.25-9
|
||||
- tail: revert to polling if a followed directory is replaced(#1283760)
|
||||
|
||||
* Thu Mar 02 2017 Kamil Dudka <kdudka@redhat.com> - 8.25-8
|
||||
- install,mkdir: fix handling of -DZ and -pZ, respectively (#1398913)
|
||||
|
||||
* Mon Oct 31 2016 Kamil Dudka <kdudka@redhat.com> - 8.25-7
|
||||
- md5sum,sha*sum: fix --ignore-missing with checksums starting with 00
|
||||
- ls: allow interruption when reading slow directories (#1365933)
|
||||
- fix 'sort -h -k' in locales that use blank as thousands separator (#1355780)
|
||||
- make 'sort -h' work for arbitrary column even when using UTF-8 locales
|
||||
- install -Z now sets default SELinux context for created directories (#1339135)
|
||||
- switch to UTF8 locale when (un)expand input contains BOM header
|
||||
(#1158494)
|
||||
- fixed regression where (un)expand would end with "long input line"
|
||||
error when BOM header is present
|
||||
|
||||
* Tue Jul 12 2016 Jakub Martisko <jamartis@redhat.com> - 8.25-6
|
||||
- (un)expand fix a regression in handling of input files, where only
|
||||
the first file was procesed.
|
||||
|
||||
* Sat Mar 05 2016 Ondrej Vasik <ovasik@redhat.com> - 8.25-5
|
||||
- cut: move back to the old i18n implementation (#1314722)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
diff -urNp coreutils-5.97-orig/man/date.x coreutils-5.97/man/date.x
|
||||
--- coreutils-5.97-orig/man/date.x 1999-11-02 15:07:36.000000000 +0100
|
||||
+++ coreutils-5.97/man/date.x 2008-10-15 10:13:31.000000000 +0200
|
||||
@@ -11,3 +11,8 @@
|
||||
@@ -11,3 +11,8 @@ calendar date, time of day, time zone, day of week, relative time,
|
||||
relative date, and numbers. An empty string indicates the beginning
|
||||
of the day. The date string format is more complex than is easily
|
||||
documented here but is fully described in the info documentation.
|
||||
|
|
Loading…
Reference in New Issue