diff options
-rw-r--r-- | .x-sc_prohibit_atoi_atof | 3 | ||||
-rw-r--r-- | ChangeLog | 66 | ||||
-rw-r--r-- | Makefile.maint | 6 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | THANKS | 1 | ||||
-rw-r--r-- | TODO | 3 | ||||
-rwxr-xr-x | bootstrap | 79 | ||||
-rw-r--r-- | doc/ChangeLog | 15 | ||||
-rw-r--r-- | doc/coreutils.texi | 41 | ||||
-rw-r--r-- | gl/lib/acl.c | 426 | ||||
-rw-r--r-- | src/copy.c | 9 | ||||
-rw-r--r-- | src/install.c | 9 | ||||
-rw-r--r-- | src/pr.c | 3 | ||||
-rwxr-xr-x | tests/cp/sparse | 2 | ||||
-rwxr-xr-x | tests/du/basic | 38 | ||||
-rw-r--r-- | tests/misc/Makefile.am | 1 | ||||
-rwxr-xr-x | tests/misc/pr | 61 | ||||
-rwxr-xr-x | tests/misc/tty-eof | 1 | ||||
-rwxr-xr-x | tests/mv/i-2 | 4 |
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$ @@ -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, @@ -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 @@ -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 @@ -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 @@ -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; } } @@ -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 |