summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.x-sc_prohibit_atoi_atof3
-rw-r--r--ChangeLog66
-rw-r--r--Makefile.maint6
-rw-r--r--NEWS4
-rw-r--r--THANKS1
-rw-r--r--TODO3
-rwxr-xr-xbootstrap79
-rw-r--r--doc/ChangeLog15
-rw-r--r--doc/coreutils.texi41
-rw-r--r--gl/lib/acl.c426
-rw-r--r--src/copy.c9
-rw-r--r--src/install.c9
-rw-r--r--src/pr.c3
-rwxr-xr-xtests/cp/sparse2
-rwxr-xr-xtests/du/basic38
-rw-r--r--tests/misc/Makefile.am1
-rwxr-xr-xtests/misc/pr61
-rwxr-xr-xtests/misc/tty-eof1
-rwxr-xr-xtests/mv/i-24
19 files changed, 691 insertions, 81 deletions
diff --git a/.x-sc_prohibit_atoi_atof b/.x-sc_prohibit_atoi_atof
index 3aaffb2b5..d995223a1 100644
--- a/.x-sc_prohibit_atoi_atof
+++ b/.x-sc_prohibit_atoi_atof
@@ -1,8 +1,11 @@
^configure$
ChangeLog
+^TODO$
^lib/mktime\.c$
^lib/getloadavg\.c$
^lib/euidaccess\.c$
^lib/euidaccess-stat\.c$
^lib/group-member\.c$
^Makefile\.maint$
+^doc/coreutils.texi$
+^src/stty.c$
diff --git a/ChangeLog b/ChangeLog
index 4a806612c..2b8a75395 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,69 @@
+2007-03-18 Jim Meyering <jim@meyering.net>
+
+ Fix a bug in how pr -m -s works.
+ * NEWS: Describe how the fix affects pr.
+ * src/pr.c (init_parameters): The --merge (-m) option does
+ not imply --expand-tabs (-e), so don't set "untabify_input".
+ Reported by Wis Macomson.
+ * tests/misc/pr: New file. Test for the above fix.
+ * tests/misc/Makefile.am (TESTS): Add pr.
+ * THANKS: Update.
+
+2007-03-17 Jim Meyering <jim@meyering.net>
+
+ Detect use of AC_CONFIG_AUX_DIR also when its argument is quoted.
+ * bootstrap: Put ""s around use of $build_aux, in case
+ someone uses a name containing shell meta-characters.
+ Reported by Alfred M. Szmidt.
+ * tests/misc/tty-eof: Add shuf to the list of tested commands.
+
+ Avoid test failure on NFS-mounted Solaris ZFS file system.
+ * tests/du/basic: Skip a test if "." is on a non-local file system.
+
+ Avoid an obscure build failure, prefer waitpid over wait.
+ * src/install.c (strip): Use waitpid, not wait. It's equivalent,
+ but feels less obsolescent.
+
+ * bootstrap: Don't use \> in grep regexp. For HP-UX.
+
+2007-03-16 Jim Meyering <jim@meyering.net>
+
+ Begin adding support for Solaris ZFS (4 entries per trivial ACL)
+ * gl/lib/acl.c (ACL_NOT_WELL_SUPPORTED): New macro.
+ (file_has_acl, copy_acl): Use it, rather than enumerating errno values.
+ (is_trivial_acl): New function. Incomplete, for now.
+ (file_has_acl, copy_acl): Use the new function, rather than
+ counting the number of entries in an ACL.
+
+ * bootstrap: Update from gnulib.
+
+ * .x-sc_prohibit_atoi_atof: Add TODO here, too.
+
+2007-03-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/copy.c: Include filemode.h.
+ (overwrite_prompt): Say "try to overwrite", not "overwrite", to
+ make it clearer that the attempt may fail. Problem reported by
+ Dan Jacobson in:
+ http://lists.gnu.org/archive/html/bug-coreutils/2007-03/msg00130.html
+ Output symbolic mode as well as numeric.
+ * tests/mv/i-2 (fail): Adjust to new prompt format.
+
+2007-03-15 Jim Meyering <jim@meyering.net>
+
+ Enforce policy: don't use *scanf functions.
+ * Makefile.maint (sc_prohibit_atoi_atof): Add to regexp and diagnostic.
+ * .x-sc_prohibit_atoi_atof: Give stty a temporary pass.
+ * TODO: note that stty.c needs this small clean-up.
+
+2007-03-13 Jim Meyering <jim@meyering.net>
+
+ Prepare to work on ACL-related failure when using Solaris ZFS.
+ * gl/lib/acl.c: New file, copied from gnulib.
+
+ Work around a failing test due to an NFS-based race condition.
+ * tests/cp/sparse: Accept a report that the copy is *smaller*.
+
2007-03-12 Jim Meyering <jim@meyering.net>
Make bootstrap.conf a tiny bit more generic.
diff --git a/Makefile.maint b/Makefile.maint
index c1da0d559..1c9d69712 100644
--- a/Makefile.maint
+++ b/Makefile.maint
@@ -117,12 +117,12 @@ sc_space_tab:
{ echo '$(ME): found SPACE-TAB sequence; remove the SPACE' \
1>&2; exit 1; } || :
-# Don't use the old ato* functions in `real' code.
+# Don't use *scanf or the old ato* functions in `real' code.
# They provide no error checking mechanism.
# Instead, use strto* functions.
sc_prohibit_atoi_atof:
- @grep -nE '\<ato([filq]|ll)\>' $$($(CVS_LIST_EXCEPT)) && \
- { echo '$(ME): do not use ato''f, ato''i, ato''l, ato''ll, or ato''q' \
+ @grep -nE '\<([fs]?scanf|ato([filq]|ll))\>' $$($(CVS_LIST_EXCEPT)) && \
+ { echo '$(ME): do not use *scan''f, ato''f, ato''i, ato''l, ato''ll, or ato''q' \
1>&2; exit 1; } || :
# Using EXIT_SUCCESS as the first argument to error is misleading,
diff --git a/NEWS b/NEWS
index 57c51e128..4efb18f21 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,10 @@ GNU coreutils NEWS -*- outline -*-
the DF_BLOCK_SIZE, BLOCK_SIZE, and BLOCKSIZE environment variables. It
is still affected by POSIXLY_CORRECT, though.
+ Using pr -m -s (i.e. merging files, with TAB as the output separator)
+ no longer inserts extraneous spaces between output columns.
+
+
* Noteworthy changes in release 6.8 (2007-02-24) [not-unstable]
** Bug fixes
diff --git a/THANKS b/THANKS
index 1d7aae341..ad05b1350 100644
--- a/THANKS
+++ b/THANKS
@@ -519,6 +519,7 @@ William Bader william@nscs.fast.net
William Dowling will@franklin.com
William Lewis wiml@omnigroup.com
wiregauze wiregauze@yahoo.com
+Wis Macomson wis.macomson@intel.com
Wojciech Purczynski cliph@isec.pl
Wolfram Kleff kleff@cs.uni-bonn.de
Won-kyu Park wkpark@chem.skku.ac.kr
diff --git a/TODO b/TODO
index 61fe29c36..0e626306a 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,6 @@
+stty.c:
+ use xstrtoul, not sscanf
+
printf:
Now that gnulib supports *printf("%a"), import one of the
*printf-posix modules so that printf(1) will support %a even on
diff --git a/bootstrap b/bootstrap
index 7d214d3bf..329408505 100755
--- a/bootstrap
+++ b/bootstrap
@@ -89,6 +89,7 @@ extract_package_name='
}
'
package=`sed -n "$extract_package_name" configure.ac` || exit
+gnulib_name=lib$package
build_aux=build-aux
# Extra files from gnulib, which override files from other sources.
@@ -168,11 +169,15 @@ insert_sorted_if_absent() {
}
# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
-grep '^[ ]*AC_CONFIG_AUX_DIR('$build_aux')' configure.ac >/dev/null ||
- {
- echo "$0: expected line not found in configure.ac. Add the following:" >&2
- echo " AC_CONFIG_AUX_DIR($build_aux)" >&2.
- }
+found_aux_dir=no
+grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
+ >/dev/null && found_aux_dir=yes
+grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
+ >/dev/null && found_aux_dir=yes
+if test $found_aux_dir = no; then
+ echo "$0: expected line not found in configure.ac. Add the following:" >&2
+ echo " AC_CONFIG_AUX_DIR([$build_aux])" >&2.
+fi
# If $build_aux doesn't exist, create it now, otherwise some bits
# below will malfunction. If creating it, also mark it as ignored.
@@ -450,7 +455,7 @@ gnulib_tool_options="\
--no-changelog\
--aux-dir $bt/$build_aux\
--doc-base $bt/doc\
- --lib lib$package\
+ --lib $gnulib_name\
--m4-base $bt/m4/\
--source-base $bt/lib/\
--tests-base $bt/tests\
@@ -466,13 +471,18 @@ done
# Import from gettext.
+with_gettext=yes
+grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
+ with_gettext=no
-echo "$0: (cd $bt2; autopoint) ..."
-cp configure.ac $bt2 &&
-(cd $bt2 && autopoint && rm configure.ac) &&
-slurp $bt2 $bt || exit
+if test $with_gettext = yes; then
+ echo "$0: (cd $bt2; autopoint) ..."
+ cp configure.ac $bt2 &&
+ (cd $bt2 && autopoint && rm configure.ac) &&
+ slurp $bt2 $bt || exit
-rm -fr $bt $bt2 || exit
+ rm -fr $bt $bt2 || exit
+fi
# Reconfigure, getting other files.
@@ -504,36 +514,37 @@ for file in $gnulib_extra_files; do
symlink_to_gnulib $file $dst || exit
done
-
-# Create gettext configuration.
-echo "$0: Creating po/Makevars from po/Makevars.template ..."
-rm -f po/Makevars
-sed '
- /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
- /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
- /^XGETTEXT_OPTIONS *=/{
- s/$/ \\/
- a\
- '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
- }
-' po/Makevars.template >po/Makevars
-
-if test -d runtime-po; then
- # Similarly for runtime-po/Makevars, but not quite the same.
- rm -f runtime-po/Makevars
+if test $with_gettext = yes; then
+ # Create gettext configuration.
+ echo "$0: Creating po/Makevars from po/Makevars.template ..."
+ rm -f po/Makevars
sed '
- /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
- /^subdir *=.*/s/=.*/= runtime-po/
+ /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
/^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
/^XGETTEXT_OPTIONS *=/{
s/$/ \\/
a\
- '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
+ '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
}
- ' <po/Makevars.template >runtime-po/Makevars
+ ' po/Makevars.template >po/Makevars
- # Copy identical files from po to runtime-po.
- (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
+ if test -d runtime-po; then
+ # Similarly for runtime-po/Makevars, but not quite the same.
+ rm -f runtime-po/Makevars
+ sed '
+ /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
+ /^subdir *=.*/s/=.*/= runtime-po/
+ /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
+ /^XGETTEXT_OPTIONS *=/{
+ s/$/ \\/
+ a\
+ '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
+ }
+ ' <po/Makevars.template >runtime-po/Makevars
+
+ # Copy identical files from po to runtime-po.
+ (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
+ fi
fi
echo "$0: done. Now you can run './configure'."
diff --git a/doc/ChangeLog b/doc/ChangeLog
index f296614f0..c4171b8f4 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,18 @@
+2007-03-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix manual in response to bug reports by Dan Jacobson.
+ * coreutils.texi (sort invocation): Explain numeric sorts better.
+ Compress self-congratulation into a simple "comparison is exact"
+ notice; the --general-numeric-sort option already explains the
+ tradeoffs.
+ (seq invocation): Add example of -f.
+
+2007-03-12 Jim Meyering <jim@meyering.net>
+
+ * coreutils.texi (cp invocation): Mention that --preserve=timestamps
+ doesn't preserve time stamps on symbolic links.
+ Reported by Polo Talnir in <https://bugzilla.redhat.com/230866>.
+
2007-02-27 Paul Eggert <eggert@cs.ucla.edu>
* coreutils.texi (df invocation): With -P, the default block size
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 23451fe73..7a4cc2db0 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -3575,26 +3575,16 @@ can change this.
@opindex --numeric-sort
@cindex numeric sort
@vindex LC_NUMERIC
-Sort numerically: the number begins each line; specifically, it consists
+Sort numerically. The number begins each line and consists
of optional blanks, an optional @samp{-} sign, and zero or more
digits possibly separated by thousands separators, optionally followed
-by a decimal-point character and zero or more digits. A string of
-no digits is interpreted as @samp{0}. The @env{LC_NUMERIC}
+by a decimal-point character and zero or more digits. An empty
+number is treated as @samp{0}. The @env{LC_NUMERIC}
locale specifies the decimal-point character and thousands separator.
By default a blank is a space or a tab, but the @env{LC_CTYPE} locale
can change this.
-Numeric sort uses what might be considered an unconventional method to
-compare strings representing floating point numbers. Rather than first
-converting each string to the C @code{double} type and then comparing
-those values, @command{sort} aligns the decimal-point characters in the
-two strings and compares the strings a character at a time. One benefit
-of using this approach is its speed. In practice this is much more
-efficient than performing the two corresponding string-to-double (or
-even string-to-integer) conversions and then comparing doubles. In
-addition, there is no corresponding loss of precision. Converting each
-string to @code{double} before comparison would limit precision to about
-16 digits on most systems.
+Comparison is exact; there is no rounding error.
Neither a leading @samp{+} nor exponential notation is recognized.
To compare such strings numerically, use the
@@ -7030,7 +7020,13 @@ and ordinary users
may preserve the group ownership of a file only if they happen to be
a member of the desired group.
@itemx timestamps
-Preserve the times of last access and last modification.
+Preserve the times of last access and last modification, when possible.
+In general, it is not possible to preserve these attributes
+when the affected file is a symbolic link.
+However, FreeBSD now provides the @code{lutimes} function, which makes
+it possibile even for symbolic links. However, this implementation does
+not yet take advantage of that.
+@c FIXME: once we provide lutimes support, update the above.
@itemx links
Preserve in the destination files
any links between corresponding source files.
@@ -13933,6 +13929,12 @@ Print all numbers using @var{format}.
@var{format} must contain exactly one of the @samp{printf}-style
floating point conversion specifications @samp{%a}, @samp{%e},
@samp{%f}, @samp{%g}, @samp{%A}, @samp{%E}, @samp{%F}, @samp{%G}.
+The @samp{%} may be followed by zero or more flags taken from the set
+@samp{-+#0 '}, then an optional width containing one or more digits,
+then an optional precision consisting of a @samp{.} followed by zero
+or more digits. @var{format} may also contain any number of @samp{%%}
+conversion specifications. All conversion specifications have the
+same meaning as with @samp{printf}.
The default format is derived from @var{first}, @var{step}, and
@var{last}. If these all use a fixed point decimal representation,
@@ -13955,6 +13957,15 @@ decimal representation.
@end table
+You can get finer-grained control over output with @option{-f}:
+
+@example
+$ seq -f '(%9.2E)' -9e5 1.1e6 1.3e6
+(-9.00E+05)
+( 2.00E+05)
+( 1.30E+06)
+@end example
+
If you want hexadecimal integer output, you can use @command{printf}
to perform the conversion:
diff --git a/gl/lib/acl.c b/gl/lib/acl.c
new file mode 100644
index 000000000..96153d41c
--- /dev/null
+++ b/gl/lib/acl.c
@@ -0,0 +1,426 @@
+/* acl.c - access control lists
+
+ Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, 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, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Paul Eggert and Andreas Gruenbacher. */
+
+#include <config.h>
+
+#include "acl.h"
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef S_ISLNK
+# define S_ISLNK(Mode) 0
+#endif
+
+#ifdef HAVE_ACL_LIBACL_H
+# include <acl/libacl.h>
+#endif
+
+#include "error.h"
+#include "quote.h"
+
+#include <errno.h>
+#ifndef ENOSYS
+# define ENOSYS (-1)
+#endif
+#ifndef ENOTSUP
+# define ENOTSUP (-1)
+#endif
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(Text) gettext (Text)
+#else
+# define _(Text) Text
+#endif
+
+#ifndef HAVE_FCHMOD
+# define HAVE_FCHMOD false
+# define fchmod(fd, mode) (-1)
+#endif
+
+/* POSIX 1003.1e (draft 17) */
+#ifndef HAVE_ACL_GET_FD
+# define HAVE_ACL_GET_FD false
+# define acl_get_fd(fd) (NULL)
+#endif
+
+/* POSIX 1003.1e (draft 17) */
+#ifndef HAVE_ACL_SET_FD
+# define HAVE_ACL_SET_FD false
+# define acl_set_fd(fd, acl) (-1)
+#endif
+
+/* Linux-specific */
+#ifndef HAVE_ACL_EXTENDED_FILE
+# define HAVE_ACL_EXTENDED_FILE false
+# define acl_extended_file(name) (-1)
+#endif
+
+/* Linux-specific */
+#ifndef HAVE_ACL_FROM_MODE
+# define HAVE_ACL_FROM_MODE false
+# define acl_from_mode(mode) (NULL)
+#endif
+
+#define ACL_NOT_WELL_SUPPORTED(Errno) \
+ (Errno == ENOTSUP || Errno == ENOSYS || Errno == EINVAL)
+
+/* We detect the presence of POSIX 1003.1e (draft 17 -- abandoned) support
+ by checking for HAVE_ACL_GET_FILE, HAVE_ACL_SET_FILE, and HAVE_ACL_FREE.
+ Systems that have acl_get_file, acl_set_file, and acl_free must also
+ have acl_to_text, acl_from_text, and acl_delete_def_file (all defined
+ in the draft); systems that don't would hit #error statements here. */
+
+#if USE_ACL && HAVE_ACL_GET_FILE && !HAVE_ACL_ENTRIES
+# ifndef HAVE_ACL_TO_TEXT
+# error Must have acl_to_text (see POSIX 1003.1e draft 17).
+# endif
+
+/* Return the number of entries in ACL. Linux implements acl_entries
+ as a more efficient extension than using this workaround. */
+
+static int
+acl_entries (acl_t acl)
+{
+ char *text = acl_to_text (acl, NULL), *t;
+ int entries;
+ if (text == NULL)
+ return -1;
+ for (entries = 0, t = text; ; t++, entries++) {
+ t = strchr (t, '\n');
+ if (t == NULL)
+ break;
+ }
+ acl_free (text);
+ return entries;
+}
+#endif
+
+/* If DESC is a valid file descriptor use fchmod to change the
+ file's mode to MODE on systems that have fchown. On systems
+ that don't have fchown and if DESC is invalid, use chown on
+ NAME instead. */
+
+int
+chmod_or_fchmod (const char *name, int desc, mode_t mode)
+{
+ if (HAVE_FCHMOD && desc != -1)
+ return fchmod (desc, mode);
+ else
+ return chmod (name, mode);
+}
+
+#if USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_SET_FILE && HAVE_ACL_FREE
+/* FIXME: use acl_trivial instead, once we have a replacement function */
+static bool
+is_trivial_acl (acl_t acl)
+{
+ int n = acl_entries (acl);
+ if (n <= 3)
+ return true;
+ if (5 <= n)
+ return false;
+
+ /* Here, we know there are exactly 4 entries.
+ If they are for user, group, mask, and other, then return true; */
+ /* FIXME */
+ return false;
+}
+#endif
+
+/* Return 1 if NAME has a nontrivial access control list, 0 if
+ NAME only has no or a base access control list, and -1 on
+ error. SB must be set to the stat buffer of FILE. */
+
+int
+file_has_acl (char const *name, struct stat const *sb)
+{
+#if USE_ACL && HAVE_ACL && defined GETACLCNT
+ /* This implementation should work on recent-enough versions of HP-UX,
+ Solaris, and Unixware. */
+
+# ifndef MIN_ACL_ENTRIES
+# define MIN_ACL_ENTRIES 4
+# endif
+
+ if (! S_ISLNK (sb->st_mode))
+ {
+ int n = acl (name, GETACLCNT, 0, NULL);
+ return n < 0 ? (errno == ENOSYS ? 0 : -1) : (MIN_ACL_ENTRIES < n);
+ }
+#elif USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_FREE
+ /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
+
+ if (! S_ISLNK (sb->st_mode))
+ {
+ int ret;
+
+ if (HAVE_ACL_EXTENDED_FILE)
+ ret = acl_extended_file (name);
+ else
+ {
+ acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS);
+ if (acl)
+ {
+ ret = !is_trivial_acl (acl);
+ acl_free (acl);
+ if (ret == 0 && S_ISDIR (sb->st_mode))
+ {
+ acl = acl_get_file (name, ACL_TYPE_DEFAULT);
+ if (acl)
+ {
+ ret = (0 < acl_entries (acl));
+ acl_free (acl);
+ }
+ else
+ ret = -1;
+ }
+ }
+ else
+ ret = -1;
+ }
+ if (ret < 0)
+ return ACL_NOT_WELL_SUPPORTED (errno) ? 0 : -1;
+ return ret;
+ }
+#endif
+
+ /* FIXME: Add support for AIX, Irix, and Tru64. Please see Samba's
+ source/lib/sysacls.c file for fix-related ideas. */
+
+ return 0;
+}
+
+/* Copy access control lists from one file to another. If SOURCE_DESC is
+ a valid file descriptor, use file descriptor operations, else use
+ filename based operations on SRC_NAME. Likewise for DEST_DESC and
+ DEST_NAME.
+ If access control lists are not available, fchmod the target file to
+ MODE. Also sets the non-permission bits of the destination file
+ (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
+ System call return value semantics. */
+
+int
+copy_acl (const char *src_name, int source_desc, const char *dst_name,
+ int dest_desc, mode_t mode)
+{
+ int ret;
+
+#if USE_ACL && HAVE_ACL_GET_FILE && HAVE_ACL_SET_FILE && HAVE_ACL_FREE
+ /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
+
+ acl_t acl;
+ if (HAVE_ACL_GET_FD && source_desc != -1)
+ acl = acl_get_fd (source_desc);
+ else
+ acl = acl_get_file (src_name, ACL_TYPE_ACCESS);
+ if (acl == NULL)
+ {
+ if (ACL_NOT_WELL_SUPPORTED (errno))
+ return set_acl (dst_name, dest_desc, mode);
+ else
+ {
+ error (0, errno, "%s", quote (src_name));
+ return -1;
+ }
+ }
+
+ if (HAVE_ACL_SET_FD && dest_desc != -1)
+ ret = acl_set_fd (dest_desc, acl);
+ else
+ ret = acl_set_file (dst_name, ACL_TYPE_ACCESS, acl);
+ if (ret != 0)
+ {
+ int saved_errno = errno;
+
+ if (ACL_NOT_WELL_SUPPORTED (errno))
+ {
+ bool trivial = is_trivial_acl (acl);
+ acl_free (acl);
+ if (trivial)
+ {
+ if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
+ saved_errno = errno;
+ else
+ return 0;
+ }
+ else
+ chmod_or_fchmod (dst_name, dest_desc, mode);
+ }
+ else
+ {
+ acl_free (acl);
+ chmod_or_fchmod (dst_name, dest_desc, mode);
+ }
+ error (0, saved_errno, _("preserving permissions for %s"),
+ quote (dst_name));
+ return -1;
+ }
+ else
+ acl_free (acl);
+
+ if (mode & (S_ISUID | S_ISGID | S_ISVTX))
+ {
+ /* We did not call chmod so far, so the special bits have not yet
+ been set. */
+
+ if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
+ {
+ error (0, errno, _("preserving permissions for %s"),
+ quote (dst_name));
+ return -1;
+ }
+ }
+
+ if (S_ISDIR (mode))
+ {
+ acl = acl_get_file (src_name, ACL_TYPE_DEFAULT);
+ if (acl == NULL)
+ {
+ error (0, errno, "%s", quote (src_name));
+ return -1;
+ }
+
+ if (acl_set_file (dst_name, ACL_TYPE_DEFAULT, acl))
+ {
+ error (0, errno, _("preserving permissions for %s"),
+ quote (dst_name));
+ acl_free (acl);
+ return -1;
+ }
+ else
+ acl_free (acl);
+ }
+ return 0;
+#else
+ ret = chmod_or_fchmod (dst_name, dest_desc, mode);
+ if (ret != 0)
+ error (0, errno, _("preserving permissions for %s"), quote (dst_name));
+ return ret;
+#endif
+}
+
+/* Set the access control lists of a file. If DESC is a valid file
+ descriptor, use file descriptor operations where available, else use
+ filename based operations on NAME. If access control lists are not
+ available, fchmod the target file to MODE. Also sets the
+ non-permission bits of the destination file (S_ISUID, S_ISGID, S_ISVTX)
+ to those from MODE if any are set. System call return value
+ semantics. */
+
+int
+set_acl (char const *name, int desc, mode_t mode)
+{
+#if USE_ACL && HAVE_ACL_SET_FILE && HAVE_ACL_FREE
+ /* POSIX 1003.1e draft 17 (abandoned) specific version. */
+
+ /* We must also have have_acl_from_text and acl_delete_def_file.
+ (acl_delete_def_file could be emulated with acl_init followed
+ by acl_set_file, but acl_set_file with an empty acl is
+ unspecified.) */
+
+# ifndef HAVE_ACL_FROM_TEXT
+# error Must have acl_from_text (see POSIX 1003.1e draft 17).
+# endif
+# ifndef HAVE_ACL_DELETE_DEF_FILE
+# error Must have acl_delete_def_file (see POSIX 1003.1e draft 17).
+# endif
+
+ acl_t acl;
+ int ret;
+
+ if (HAVE_ACL_FROM_MODE)
+ {
+ acl = acl_from_mode (mode);
+ if (!acl)
+ {
+ error (0, errno, "%s", quote (name));
+ return -1;
+ }
+ }
+ else
+ {
+ char acl_text[] = "u::---,g::---,o::---";
+
+ if (mode & S_IRUSR) acl_text[ 3] = 'r';
+ if (mode & S_IWUSR) acl_text[ 4] = 'w';
+ if (mode & S_IXUSR) acl_text[ 5] = 'x';
+ if (mode & S_IRGRP) acl_text[10] = 'r';
+ if (mode & S_IWGRP) acl_text[11] = 'w';
+ if (mode & S_IXGRP) acl_text[12] = 'x';
+ if (mode & S_IROTH) acl_text[17] = 'r';
+ if (mode & S_IWOTH) acl_text[18] = 'w';
+ if (mode & S_IXOTH) acl_text[19] = 'x';
+
+ acl = acl_from_text (acl_text);
+ if (!acl)
+ {
+ error (0, errno, "%s", quote (name));
+ return -1;
+ }
+ }
+ if (HAVE_ACL_SET_FD && desc != -1)
+ ret = acl_set_fd (desc, acl);
+ else
+ ret = acl_set_file (name, ACL_TYPE_ACCESS, acl);
+ if (ret != 0)
+ {
+ int saved_errno = errno;
+ acl_free (acl);
+
+ if (ACL_NOT_WELL_SUPPORTED (errno))
+ {
+ if (chmod_or_fchmod (name, desc, mode) != 0)
+ saved_errno = errno;
+ else
+ return 0;
+ }
+ error (0, saved_errno, _("setting permissions for %s"), quote (name));
+ return -1;
+ }
+ else
+ acl_free (acl);
+
+ if (S_ISDIR (mode) && acl_delete_def_file (name))
+ {
+ error (0, errno, _("setting permissions for %s"), quote (name));
+ return -1;
+ }
+
+ if (mode & (S_ISUID | S_ISGID | S_ISVTX))
+ {
+ /* We did not call chmod so far, so the special bits have not yet
+ been set. */
+
+ if (chmod_or_fchmod (name, desc, mode))
+ {
+ error (0, errno, _("preserving permissions for %s"), quote (name));
+ return -1;
+ }
+ }
+ return 0;
+#else
+ int ret = chmod_or_fchmod (name, desc, mode);
+ if (ret)
+ error (0, errno, _("setting permissions for %s"), quote (name));
+ return ret;
+#endif
+}
diff --git a/src/copy.c b/src/copy.c
index 49bbb8ce4..4bdb75cbb 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -38,6 +38,7 @@
#include "euidaccess.h"
#include "error.h"
#include "fcntl--.h"
+#include "filemode.h"
#include "filenamecat.h"
#include "full-write.h"
#include "getpagesize.h"
@@ -797,10 +798,14 @@ overwrite_prompt (char const *dst_name, struct stat const *dst_sb)
{
if (euidaccess (dst_name, W_OK) != 0)
{
+ char perms[12]; /* "-rwxrwxrwx " ls-style modes. */
+ strmode (dst_sb->st_mode, perms);
+ perms[10] = '\0';
fprintf (stderr,
- _("%s: overwrite %s, overriding mode %04lo? "),
+ _("%s: try to overwrite %s, overriding mode %04lo (%s)? "),
program_name, quote (dst_name),
- (unsigned long int) (dst_sb->st_mode & CHMOD_MODE_BITS));
+ (unsigned long int) (dst_sb->st_mode & CHMOD_MODE_BITS),
+ &perms[1]);
}
else
{
diff --git a/src/install.c b/src/install.c
index 8fc6a8a58..04577518c 100644
--- a/src/install.c
+++ b/src/install.c
@@ -566,11 +566,10 @@ strip (char const *name)
error (EXIT_FAILURE, errno, _("cannot run strip"));
break;
default: /* Parent. */
- /* Parent process. */
- while (pid != wait (&status)) /* Wait for kid to finish. */
- /* Do nothing. */ ;
- if (status)
- error (EXIT_FAILURE, 0, _("strip failed"));
+ if (waitpid (pid, &status, 0) < 0)
+ error (EXIT_FAILURE, errno, _("waiting for strip"));
+ else if (! WIFEXITED (status) || WEXITSTATUS (status))
+ error (EXIT_FAILURE, 0, _("strip process terminated abnormally"));
break;
}
}
diff --git a/src/pr.c b/src/pr.c
index bd694f49f..e0aea224e 100644
--- a/src/pr.c
+++ b/src/pr.c
@@ -1,5 +1,5 @@
/* pr -- convert text files for printing.
- Copyright (C) 88, 91, 1995-2006 Free Software Foundation, Inc.
+ Copyright (C) 88, 91, 1995-2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1265,7 +1265,6 @@ init_parameters (int number_of_files)
col_sep_string = column_separator;
truncate_lines = true;
- untabify_input = true;
tabify_output = true;
}
else
diff --git a/tests/cp/sparse b/tests/cp/sparse
index 98d580d21..b2e940e45 100755
--- a/tests/cp/sparse
+++ b/tests/cp/sparse
@@ -52,6 +52,6 @@ fail=0
cp --sparse=always sparse copy || fail=1
# Ensure that the copy has the same block count as the original.
-test `stat --printf %b sparse` = `stat --printf %b copy` || fail=1
+test `stat --printf %b copy` -le `stat --printf %b sparse` || fail=1
(exit $fail); exit $fail
diff --git a/tests/du/basic b/tests/du/basic
index d03ce0c16..665a416c8 100755
--- a/tests/du/basic
+++ b/tests/du/basic
@@ -1,7 +1,7 @@
#!/bin/sh
# Compare actual numbers from du, assuming block size matches mine.
-# Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2006-2007 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -80,20 +80,23 @@ EOF
cmp out exp || fail=1
test $fail = 1 && diff -u out exp 2> /dev/null
-rm -f out exp
-du --block-size=$B -a d | sort -r -k2,2 > out || fail=1
-echo === >> out
-du --block-size=$B -S d | sort -r -k2,2 >> out || fail=1
-
-t2=`stat --format=%b d/sub/2`
-ts=`stat --format=%b d/sub`
-t1=`stat --format=%b d/1`
-td=`stat --format=%b d`
-tot=`expr $t1 + $t2 + $ts + $td`
-d1=`expr $td + $t1`
-s2=`expr $ts + $t2`
-
-cat <<EOF | sed 's/ *#.*//' > exp
+# Perform this test only if "." is on a local file system.
+# Otherwise, it would fail e.g., on an NFS-mounted Solaris ZFS file system.
+if df --local . >/dev/null 2>&1; then
+ rm -f out exp
+ du --block-size=$B -a d | sort -r -k2,2 > out || fail=1
+ echo === >> out
+ du --block-size=$B -S d | sort -r -k2,2 >> out || fail=1
+
+ t2=`stat --format=%b d/sub/2`
+ ts=`stat --format=%b d/sub`
+ t1=`stat --format=%b d/1`
+ td=`stat --format=%b d`
+ tot=`expr $t1 + $t2 + $ts + $td`
+ d1=`expr $td + $t1`
+ s2=`expr $ts + $t2`
+
+ cat <<EOF | sed 's/ *#.*//' > exp
$t2 d/sub/2
$s2 d/sub
$t1 d/1
@@ -103,7 +106,8 @@ $s2 d/sub
$d1 d # d + d/1; don't count the dir. entry for d/sub
EOF
-cmp out exp || fail=1
-test $fail = 1 && diff out exp 2> /dev/null
+ cmp out exp || fail=1
+ test $fail = 1 && diff out exp 2> /dev/null
+fi
(exit $fail); exit $fail
diff --git a/tests/misc/Makefile.am b/tests/misc/Makefile.am
index 1aa3516f8..4d6a754a8 100644
--- a/tests/misc/Makefile.am
+++ b/tests/misc/Makefile.am
@@ -40,6 +40,7 @@ TESTS_ENVIRONMENT = \
# will execute the test script rather than the standard utility.
TESTS = \
+ pr \
df-P \
pwd-unreadable-parent \
cut \
diff --git a/tests/misc/pr b/tests/misc/pr
new file mode 100755
index 000000000..a40ea31c1
--- /dev/null
+++ b/tests/misc/pr
@@ -0,0 +1,61 @@
+#!/bin/sh
+# -*- perl -*-
+# Exercise a bug with pr -m -s
+
+# Copyright (C) 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+: ${PERL=perl}
+: ${srcdir=.}
+
+. $srcdir/../envvar-check
+
+$PERL -e 1 > /dev/null 2>&1 || {
+ echo 1>&2 "$0: configure didn't find a usable version of Perl," \
+ "so can't run this test"
+ exit 77
+}
+
+exec $PERL -w -I$srcdir/.. -MCoreutils -- - <<\EOF
+#/
+require 5.003;
+use strict;
+
+(my $program_name = $0) =~ s|.*/||;
+
+$ENV{PROG} = 'pr';
+my $ME = $ENV{PROG};
+
+# Turn off localization of executable's ouput.
+@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
+
+my @Tests =
+ (
+ ['merge-w-tabs', '-m -s -t',
+ {IN=>{1=>"a\tb\tc\n"}},
+ {IN=>{2=>"m\tn\to\n"}},
+ {IN=>{3=>"x\ty\tz\n"}},
+ {OUT=>join("\t", qw(a b c m n o x y z)) . "\n"} ],
+ );
+
+my $save_temps = $ENV{DEBUG};
+my $verbose = $ENV{VERBOSE};
+
+my $prog = $ENV{PROG} || die "$0: \$PROG not specified in environment\n";
+my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose);
+exit $fail;
+EOF
diff --git a/tests/misc/tty-eof b/tests/misc/tty-eof
index ef60fda0a..dca154e29 100755
--- a/tests/misc/tty-eof
+++ b/tests/misc/tty-eof
@@ -67,6 +67,7 @@ $@ and (warn "$ME: this script requires Perl's Expect package >=1.11\n"),
sha256sum
sha384sum
sha512sum
+ shuf
sort
sum
tac
diff --git a/tests/mv/i-2 b/tests/mv/i-2
index ae7c5a135..36d1ce474 100755
--- a/tests/mv/i-2
+++ b/tests/mv/i-2
@@ -2,7 +2,7 @@
# Test both cp and mv for their behavior with -if and -fi
# The standards (POSIX and SuS) dictate annoyingly inconsistent behavior.
-# Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2006, 2007 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -61,7 +61,7 @@ cp -if e f < y > out 2>&1 || fail=1
# Make sure out contains the prompt.
case "`cat out`" in
- "cp: overwrite \`f', overriding mode 0000?"*) ;;
+ "cp: try to overwrite \`f', overriding mode 0000 (---------)?"*) ;;
*) fail=1 ;;
esac