aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.prev-version2
-rw-r--r--NEWS134
-rw-r--r--README-release45
-rw-r--r--THANKS11
-rwxr-xr-xbootstrap29
-rw-r--r--bootstrap.conf23
-rw-r--r--cfg.mk6
-rw-r--r--configure.ac2
-rw-r--r--doc/coreutils.texi415
-rw-r--r--gl/lib/tempname.c23
-rw-r--r--gl/lib/tempname.h5
m---------gnulib0
-rw-r--r--lib/fdopendir-glibc.c136
-rw-r--r--m4/check-decl.m48
-rw-r--r--m4/jm-macros.m43
-rwxr-xr-xman/help2man6
-rw-r--r--po/POTFILES.in2
-rw-r--r--src/Makefile.am445
-rw-r--r--src/base64.c2
-rw-r--r--src/basename.c2
-rw-r--r--src/cat.c10
-rw-r--r--src/chcon.c4
-rw-r--r--src/chgrp.c4
-rw-r--r--src/chmod.c6
-rw-r--r--src/chown-core.c2
-rw-r--r--src/chown.c4
-rw-r--r--src/chroot.c4
-rw-r--r--src/cksum.c2
-rw-r--r--src/comm.c3
-rw-r--r--src/copy.c65
-rw-r--r--src/cp.c6
-rw-r--r--src/csplit.c2
-rw-r--r--src/cut.c2
-rw-r--r--src/date.c2
-rw-r--r--src/dd.c13
-rw-r--r--src/df.c15
-rw-r--r--src/dircolors.c2
-rw-r--r--src/dircolors.hin3
-rw-r--r--src/dirname.c2
-rw-r--r--src/du.c10
-rw-r--r--src/echo.c2
-rw-r--r--src/env.c2
-rw-r--r--src/expand.c4
-rw-r--r--src/expr.c10
-rw-r--r--src/factor.c6
-rw-r--r--src/fmt.c2
-rw-r--r--src/fold.c2
-rw-r--r--src/getlimits.c2
-rw-r--r--src/groups.c2
-rw-r--r--src/head.c2
-rw-r--r--src/hostid.c2
-rw-r--r--src/hostname.c2
-rw-r--r--src/id.c9
-rw-r--r--src/install.c4
-rw-r--r--src/join.c3
-rw-r--r--src/kill.c2
-rw-r--r--src/link.c2
-rw-r--r--src/ln.c65
-rw-r--r--src/logname.c2
-rw-r--r--src/ls.c99
-rw-r--r--src/md5sum.c19
-rw-r--r--src/mkdir.c2
-rw-r--r--src/mkfifo.c2
-rw-r--r--src/mknod.c2
-rw-r--r--src/mktemp.c6
-rw-r--r--src/mv.c2
-rw-r--r--src/nice.c2
-rw-r--r--src/nl.c2
-rw-r--r--src/nohup.c2
-rw-r--r--src/od.c6
-rw-r--r--src/paste.c2
-rw-r--r--src/pathchk.c4
-rw-r--r--src/pinky.c3
-rw-r--r--src/pr.c29
-rw-r--r--src/printenv.c2
-rw-r--r--src/printf.c2
-rw-r--r--src/ptx.c14
-rw-r--r--src/pwd.c2
-rw-r--r--src/readlink.c2
-rw-r--r--src/rm.c4
-rw-r--r--src/rmdir.c4
-rw-r--r--src/runcon.c4
-rw-r--r--src/seq.c2
-rw-r--r--src/setuidgid.c4
-rw-r--r--src/shred.c2
-rw-r--r--src/shuf.c2
-rw-r--r--src/sleep.c2
-rw-r--r--src/sort.c45
-rw-r--r--src/split.c9
-rw-r--r--src/stat.c70
-rw-r--r--src/stdbuf.c33
-rw-r--r--src/stty.c26
-rw-r--r--src/su.c12
-rw-r--r--src/sum.c2
-rw-r--r--src/sync.c2
-rw-r--r--src/system.h95
-rw-r--r--src/tac.c2
-rw-r--r--src/tail.c146
-rw-r--r--src/tee.c2
-rw-r--r--src/test.c8
-rw-r--r--src/timeout.c19
-rw-r--r--src/touch.c48
-rw-r--r--src/tr.c2
-rw-r--r--src/true.c2
-rw-r--r--src/truncate.c7
-rw-r--r--src/tsort.c2
-rw-r--r--src/tty.c2
-rw-r--r--src/uname.c2
-rw-r--r--src/unexpand.c4
-rw-r--r--src/uniq.c3
-rw-r--r--src/unlink.c2
-rw-r--r--src/uptime.c6
-rw-r--r--src/users.c2
-rw-r--r--src/wc.c12
-rw-r--r--src/who.c3
-rw-r--r--src/whoami.c2
-rw-r--r--src/yes.c2
-rw-r--r--tests/Makefile.am11
-rwxr-xr-xtests/cp/preserve-slink-time2
-rwxr-xr-xtests/dd/skip-seek-past-file3
-rwxr-xr-xtests/dd/unblock59
-rwxr-xr-xtests/id/no-context40
-rwxr-xr-xtests/ln/hard-to-sym82
-rwxr-xr-xtests/ln/misc23
-rwxr-xr-xtests/ln/slash-decorated-nonexistent-dest34
-rwxr-xr-xtests/ls/color-clear-to-eol6
-rwxr-xr-xtests/ls/color-dtype-dir20
-rwxr-xr-xtests/ls/dangle14
-rwxr-xr-xtests/ls/infloop25
-rwxr-xr-xtests/ls/stat-vs-dirent5
-rwxr-xr-xtests/misc/cat-buf15
-rwxr-xr-xtests/misc/ls-misc2
-rwxr-xr-xtests/misc/md5sum10
-rwxr-xr-xtests/misc/sha1sum11
-rwxr-xr-xtests/misc/sort-continue2
-rwxr-xr-xtests/misc/stat-hyphen35
-rwxr-xr-xtests/misc/stat-slash49
-rwxr-xr-xtests/misc/xattr42
-rwxr-xr-xtests/readlink/can-f36
-rwxr-xr-xtests/tail-2/append-only9
-rwxr-xr-xtests/tail-2/assert8
-rwxr-xr-xtests/tail-2/flush-initial44
-rwxr-xr-xtests/tail-2/follow-stdin41
-rwxr-xr-xtests/tail-2/infloop-112
-rwxr-xr-xtests/tail-2/pid47
-rwxr-xr-xtests/tail-2/pipe-f32
-rwxr-xr-xtests/tail-2/pipe-f237
-rwxr-xr-xtests/tail-2/tail-n0f24
-rwxr-xr-xtests/tail-2/wait67
-rwxr-xr-xtests/touch/60-seconds38
150 files changed, 2094 insertions, 1176 deletions
diff --git a/.prev-version b/.prev-version
index c382960e3..cc40bca69 100644
--- a/.prev-version
+++ b/.prev-version
@@ -1 +1 @@
-7.5
+8.0
diff --git a/NEWS b/NEWS
index c0d751782..f8269fccd 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,98 @@ GNU coreutils NEWS -*- outline -*-
** Bug fixes
+ chcon no longer exits immediately just because SELinux is disabled.
+ Even then, chcon may still be useful.
+ [bug introduced in coreutils-8.0]
+
+ stat -f recognizes more file system types: afs, cifs, anon-inode FS,
+ btrfs, cgroupfs, cramfs-wend, debugfs, futexfs, hfs, inotifyfs, minux3,
+ nilfs, securityfs, selinux, xenfs
+
+** New features
+
+ md5sum --check now also accepts openssl-style checksums.
+ So do sha1sum, sha224sum, sha384sum and sha512sum.
+
+
+* Noteworthy changes in release 8.0 (2009-10-06) [beta]
+
+** Bug fixes
+
+ cp --preserve=xattr and --archive now preserve extended attributes even
+ when the source file doesn't have write access.
+ [bug introduced in coreutils-7.1]
+
+ touch -t [[CC]YY]MMDDhhmm[.ss] now accepts a timestamp string ending in .60,
+ to accommodate leap seconds.
+ [the bug dates back to the initial implementation]
+
+ ls --color now reverts to the color of a base file type consistently
+ when the color of a more specific type is disabled.
+ [bug introduced in coreutils-5.90]
+
+ ls -LR exits with status 2, not 0, when it encounters a cycle
+
+ ls -is is now consistent with ls -lis in ignoring values returned
+ from a failed stat/lstat. For example ls -Lis now prints "?", not "0",
+ for the inode number and allocated size of a dereferenced dangling symlink.
+
+ tail --follow --pid now avoids a race condition where data written
+ just before the process dies might not have been output by tail.
+ Also, tail no longer delays at all when the specified pid is not live.
+ [The race was introduced in coreutils-7.5,
+ and the unnecessary delay was present since textutils-1.22o]
+
+** Portability
+
+ On Solaris 9, many commands would mistakenly treat file/ the same as
+ file. Now, even on such a system, path resolution obeys the POSIX
+ rules that a trailing slash ensures that the preceeding name is a
+ directory or a symlink to a directory.
+
+** Changes in behavior
+
+ id no longer prints SELinux " context=..." when the POSIXLY_CORRECT
+ environment variable is set.
+
+ readlink -f now ignores a trailing slash when deciding if the
+ last component (possibly via a dangling symlink) can be created,
+ since mkdir will succeed in that case.
+
+** New features
+
+ ln now accepts the options --logical (-L) and --physical (-P),
+ added by POSIX 2008. The default behavior is -P on systems like
+ GNU/Linux where link(2) creates hard links to symlinks, and -L on
+ BSD systems where link(2) follows symlinks.
+
+ stat: without -f, a command-line argument of "-" now means standard input.
+ With --file-system (-f), an argument of "-" is now rejected.
+ If you really must operate on a file named "-", specify it as
+ "./-" or use "--" to separate options from arguments.
+
+** Improvements
+
+ rm: rewrite to use gnulib's fts
+ This makes rm -rf significantly faster (400-500%) in some pathological
+ cases, and slightly slower (20%) in at least one pathological case.
+
+ rm -r deletes deep hierarchies more efficiently. Before, execution time
+ was quadratic in the depth of the hierarchy, now it is merely linear.
+ However, this improvement is not as pronounced as might be expected for
+ very deep trees, because prior to this change, for any relative name
+ length longer than 8KiB, rm -r would sacrifice official conformance to
+ avoid the disproportionate quadratic performance penalty. Leading to
+ another improvement:
+
+ rm -r is now slightly more standards-conformant when operating on
+ write-protected files with relative names longer than 8KiB.
+
+
+* Noteworthy changes in release 7.6 (2009-09-11) [stable]
+
+** Bug fixes
+
cp, mv now ignore failure to preserve a symlink time stamp, when it is
due to their running on a kernel older than what was implied by headers
and libraries tested at configure time.
@@ -15,10 +107,14 @@ GNU coreutils NEWS -*- outline -*-
cp --preserve=xattr no longer leaks resources on each preservation failure.
[bug introduced in coreutils-7.1]
- dd now returns non-zero status if it encountered a write error while
+ dd now exits with non-zero status when it encounters a write error while
printing a summary to stderr.
[bug introduced in coreutils-6.11]
+ dd cbs=N conv=unblock would fail to print a final newline when the size
+ of the input was not a multiple of N bytes.
+ [the non-conforming behavior dates back to the initial implementation]
+
df no longer requires that each command-line argument be readable
[bug introduced in coreutils-7.3]
@@ -27,20 +123,42 @@ GNU coreutils NEWS -*- outline -*-
because ls must stat every file in order to obtain a guaranteed-valid
inode number. [bug introduced in coreutils-6.0]
-** Improved robustness
+ tail -f (inotify-enabled) now flushes any initial output before blocking.
+ Before, this would print nothing and wait: stdbuf -o 4K tail -f /etc/passwd
+ Note that this bug affects tail -f only when its standard output is buffered,
+ which is relatively unusual.
+ [bug introduced in coreutils-7.5]
- rm has been rewritten to use gnulib's fts
- This makes it significantly faster (400-500%) in some pathological
- cases, and slightly slower (20%) in at least one pathological case.
- Unrelated to its use of fts, rm -r is now slightly more standards-
- conformant when operating on write-protected relative file names
- longer than 8KiB.
+ tail -f once again works with standard input. inotify-enabled tail -f
+ would fail when operating on a nameless stdin. I.e., tail -f < /etc/passwd
+ would say "tail: cannot watch `-': No such file or directory", yet the
+ relatively baroque tail -f /dev/stdin < /etc/passwd would work. Now, the
+ offending usage causes tail to revert to its conventional sleep-based
+ (i.e., not inotify-based) implementation.
+ [bug introduced in coreutils-7.5]
+
+** Portability
+
+ ln, link: link f z/ would mistakenly succeed on Solaris 10, given an
+ existing file, f, and nothing named "z". ln -T f z/ has the same problem.
+ Each would mistakenly create "z" as a link to "f". Now, even on such a
+ system, each command reports the error, e.g.,
+ link: cannot create link `z/' to `f': Not a directory
** New features
cp --reflink accepts a new "auto" parameter which falls back to
a standard copy if creating a copy-on-write clone is not possible.
+** Changes in behavior
+
+ tail -f now ignores "-" when stdin is a pipe or FIFO.
+ tail-with-no-args now ignores -f unconditionally when stdin is a pipe or FIFO.
+ Before, it would ignore -f only when no file argument was specified,
+ and then only when POSIXLY_CORRECT was set. Now, :|tail -f - terminates
+ immediately. Before, it would block indefinitely.
+
+
* Noteworthy changes in release 7.5 (2009-08-20) [stable]
** Bug fixes
diff --git a/README-release b/README-release
index f3241d8d6..4bf481552 100644
--- a/README-release
+++ b/README-release
@@ -7,19 +7,18 @@ Here are most of the steps we (maintainers) follow when making a release.
* Run ./configure && make maintainer-clean
* Ensure that the desired versions of autoconf, automake, bison, etc.
- are in your PATH. See HACKING for the complete list.
+ are in your PATH. See the buildreq list in bootstrap.conf for
+ the complete list.
* Ensure that you're on "master" with no uncommitted diffs.
This should produce no output: git checkout master; git diff
-* Make sure your local gnulib directory is up to date.
-
-* Run bootstrap, (assuming your local copy of gnulib is in /gnulib):
- ./bootstrap --gnulib-srcdir=/gnulib
+* Run bootstrap: ./bootstrap
FIXME: enable excluded programs like arch? to get their manual pages?
* Pre-release testing:
+ Ensure that make check syntax-check succeeds.
On at least one SELinux-enabled (enforcing) and one non-SELinux system,
run all tests, both root-only and regular.
Run *all* non-root tests, including expensive and very expensive ones i.e.,
@@ -33,16 +32,17 @@ FIXME: enable excluded programs like arch? to get their manual pages?
* Manually set the date, version number, and [stable/alpha/beta] on
line 3 of NEWS, then do e.g.,:
- v=7.3
+ v=8.0
+ pkg=$(sed -n 's/^PACKAGE = \(.*\)/\1/p' Makefile)
git commit -F <(printf 'version '$v'\n\n* NEWS: Record release date.\n') -a
- git tag -s -m "coreutils $v" v$v HEAD
+ git tag -s -m "$pkg $v" v$v HEAD
* Run the following to create release tarballs. Your choice selects the
corresponding upload-to destination in the emitted gnupload command.
The different destinations are specified in cfg.mk. See the definitions
- of gnu_ftp_host-{alpha,beta,major}.
+ of gnu_ftp_host-{alpha,beta,stable}.
- # "TYPE" must be major, beta or alpha
+ # "TYPE" must be stable, beta or alpha
make TYPE
* Test the tarball. copy it to a few odd-ball systems and ensure that
@@ -60,12 +60,15 @@ Once all the builds and tests have passed,
that they're all valid.
* Push the new tag:
- git push origin tag v<JUST_RELEASED_VERSION_NUMBER>
+
+ v=$(cat .prev-version)
+ git push origin tag v$v
* Send the gpg-signed announcement mail, e.g.,
+
To: info-gnu@gnu.org, coreutils-announce@gnu.org
Cc: coordinator@translationproject.org, bug-coreutils@gnu.org
- Subject: coreutils-7.1 released [stable]
+ Subject: coreutils-8.0 released [beta]
* Approve the announcement here:
http://lists.gnu.org/mailman/admindb/coreutils-announce
@@ -74,25 +77,21 @@ Once all the builds and tests have passed,
From here:
https://savannah.gnu.org/projects/coreutils/
click on the "submit news", then write something like the following:
+ (If there is no such button, then enable "News" for the project via
+ the Main -> "Select Features" menu item, or via this link:
+ https://savannah.gnu.org/project/admin/editgroupfeatures.php?group=gzip)
- Subject: coreutils-7.2 released [stable]
+ Subject: coreutils-0.0 released [beta]
The announcement is here:
- http://article.gmane.org/gmane.comp.gnu.core-utils.announce/49
+ http://article.gmane.org/gmane.comp.gnu.core-utils.announce/54
Then go here to approve it:
https://savannah.gnu.org/news/approve.php?group=coreutils
-* For non-alpha releases, update the on-line manual at
+* After each non-alpha release, update the on-line manual accessible via
http://www.gnu.org/software/coreutils/manual/
- Run `make web-manual', then copy the contents of doc/manual
- into a CVS checkout of the coreutils manual repository.
- Also edit coreutils.html (FIXME? why?) before doing a CVS commit.
-
- CVS_RSH=ssh \
- cvs -d:ext:$USER@cvs.savannah.gnu.org:/web/coreutils co coreutils
+ by running this:
- Be sure to "cvs add -ko" any files that "cvs status" marks with "?".
- That is necessary whenever a new texinfo node is added. Each becomes
- a new file in html_node that must then be "cvs add"ed.
+ build-aux/gnu-web-doc-update
diff --git a/THANKS b/THANKS
index 961785e0c..65ac1bb4f 100644
--- a/THANKS
+++ b/THANKS
@@ -66,8 +66,9 @@ Barry Kelly http://barrkel.blogspot.com/
Bauke Jan Douma bjdouma@xs4all.nl
Ben Elliston bje@air.net.au
Ben Harris bjh21@netbsd.org
-Benjamin Cutler cutlerbc@simla.colostate.edu
Bengt Martensson bengt@mathematik.uni-Bremen.de
+Benjamin Cutler cutlerbc@simla.colostate.edu
+Benno Schulenberg bensberg@justemail.net
Bernard Giroud bernard.giroud@creditlyonnais.ch
Bernd Eckenfels ecki@debian.org
Bernd Leibing bernd.leibing@rz.uni-ulm.de
@@ -78,6 +79,7 @@ Bernhard Rosenkraenzer bero@redhat.de
Bernhard Voelker bernhard.voelker@siemens-enterprise.com
Bert Deknuydt Bert.Deknuydt@esat.kuleuven.ac.be
Bert Wesarg bert.wesarg@googlemail.com
+Bill Brelsford wb@k2di.net
Bill Peters peters@gaffel.as.arizona.edu
Bjorn Helgaas helgaas@rsn.hp.com
Bob McCracken kerouac@ravenet.com
@@ -250,6 +252,7 @@ James Antill jmanti%essex.ac.uk@seralph21.essex.ac.uk
James Lemley James.Lemley@acxiom.com
James Hunt jamesodhunt@hotmail.com
James Ralston ralston@pobox.com
+James R. Van Zandt jrvz@comcast.net
James Sneeringer jvs@ocslink.com
James Tanis jtt@soscorp.com
James Youngman jay@gnu.org
@@ -333,6 +336,7 @@ Leah Q eequor@earthlink.net
Lehti Rami rammer@cs.tut.fi
Leonard N. Zubkoff lnz@dandelion.com
Leonardo Milano lmilano@udel.edu
+Lluís Batlle viriketo@gmail.com
Lorne Baker lbaker@nitro.avint.net
Luke Hassell lukehassell@yahoo.com
Luke Kendall lukekendall@optushome.com.au
@@ -371,6 +375,7 @@ Marty Leisner leisner@sdsp.mc.xerox.com
Masami Takikawa takikawm@CS.ORST.EDU
Mate Wierdl mw@moni.msci.memphis.edu
Matej Vela mvela@public.srce.hr
+Matias A. Fonzo selk@dragora.org
Matt Kraai kraai@ftbfs.org
Matt Perry matt@primefactor.com
Matt Pham mattvpham@gmail.com
@@ -386,6 +391,7 @@ Matthew Swift swift@alum.mit.edu
Matthew Woehlke mw_triad@users.sourceforge.net
Matthias Urlichs smurf@noris.de
Matti Aarnio matti.aarnio@zmailer.org
+Mathias Brodala info@noctus.net
Mattias Wadenstein maswan@acc.umu.se
Max Chang maxchang@ucla.edu
Meelis Roos mroos@tartu.cyber.ee
@@ -488,6 +494,7 @@ Ralph Loader loader@maths.ox.ac.uk
Raul Miller moth@magenta.com
Raúl Núñez de Arenas Coronado raul@pleyades.net
Reuben Thomas rrt@sc3d.org
+Yang Ren ryang@redhat.com
Richard A Downing richard.downing@bcs.org.uk
Richard Braakman dark@xs4all.nl
Richard Dawe rich@phekda.freeserve.co.uk
@@ -562,6 +569,7 @@ Tim Waugh twaugh@redhat
Tobias Stoeckmann tobias@bugol.de
Toby Peterson toby@opendarwin.org
Todd A. Jacobs tjacobs@codegnome.org
+Tom Fitzhenry tom@tom-fitzhenry.me.uk
Tom Haynes thomas@netapp.com
Tom Quinn trq@dionysos.thphys.ox.ac.uk
Tomas Pospisek tpo@sourcepole.ch
@@ -604,6 +612,7 @@ 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
+Yanko Kaneti yaneti@declera.com
Yann Dirson dirson@debian.org
Zvi Har'El rl@math.technion.ac.il
diff --git a/bootstrap b/bootstrap
index 4be24b6aa..6957ea3b6 100755
--- a/bootstrap
+++ b/bootstrap
@@ -70,6 +70,9 @@ gnulib_modules=
# Any gnulib files needed that are not in modules.
gnulib_files=
+# A function to be called after everything else in this script.
+bootstrap_epilogue() { :; }
+
# The command to download all .po files for a specified domain into
# a specified directory. Fill in the first %s is the domain name, and
# the second with the destination directory. Use rsync's -L and -r
@@ -150,12 +153,18 @@ vc_ignore=auto
# find_tool ENVVAR NAMES...
# -------------------------
+# Search for a required program. Use the value of ENVVAR, if set,
+# otherwise find the first of the NAMES that can be run (i.e.,
+# supports --version). If found, set ENVVAR to the program name,
+# die otherwise.
find_tool ()
{
# Find sha1sum, named gsha1sum on MacPorts.
find_tool_envvar=$1
shift
- if eval test x"\$$find_tool_envvar" = x; then
+ find_tool_names=$@
+ eval "find_tool_res=\$$find_tool_envvar"
+ if test x"$find_tool_res" = x; then
for i
do
if ($i --version </dev/null) >/dev/null 2>&1; then
@@ -163,16 +172,18 @@ find_tool ()
break
fi
done
+ else
+ find_tool_error_prefix="\$$find_tool_envvar: "
fi
if test x"$find_tool_res" = x; then
- echo >&2 "$0: $find_tool_name is required"
+ echo >&2 "$0: one of these is required: $find_tool_names"
exit 1
fi
($find_tool_res --version </dev/null) >/dev/null 2>&1 || {
- echo >&2 "$0: cannot run $find_tool_res --version"
+ echo >&2 "$0: ${find_tool_error_prefix}cannot run $find_tool_res --version"
exit 1
}
- eval "$find_tool_envvar=\"$find_tool_res\""
+ eval "$find_tool_envvar=\$find_tool_res"
eval "export $find_tool_envvar"
}
@@ -721,6 +732,10 @@ find "$m4_base" "$source_base" \
# Reconfigure, getting other files.
+# Skip autoheader if it's not needed.
+grep '^[ ]*AC_CONFIG_HEADERS\>' configure.ac >/dev/null ||
+ AUTOHEADER=true
+
for command in \
libtool \
"${ACLOCAL-aclocal} --force -I m4" \
@@ -789,10 +804,6 @@ if test $with_gettext = yes; then
fi
fi
-# Horrible, coreutils-specific kludges.
-# Change paths in gnulib-tests/gnulib.mk from "../.." to "..".
-m=gnulib-tests/gnulib.mk
-sed 's,\.\./\.\.,..,g' $m > $m-t
-mv -f $m-t $m
+bootstrap_epilogue
echo "$0: done. Now you can run './configure'."
diff --git a/bootstrap.conf b/bootstrap.conf
index 1001b0bdd..e9b198c53 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -20,7 +20,6 @@
avoided_gnulib_modules='
--avoid=canonicalize-lgpl
--avoid=dummy
- --avoid=lock
'
# These modules are obsolete and can probably be removed soon,
@@ -31,7 +30,6 @@ obsolete_gnulib_modules='
memcpy
memmove
memset
- rename
strcspn
strtod
strtol
@@ -91,12 +89,13 @@ gnulib_modules="
fnmatch-gnu
fopen-safer
fprintftime
+ freopen
fseeko
fsusage
+ fsync
ftello
ftruncate
fts
- gendocs
getdate
getgroups
gethrxtime
@@ -114,6 +113,7 @@ gnulib_modules="
git-version-gen
gitlog-to-changelog
gnu-make
+ gnu-web-doc-update
gnumakefile
gnupload
group-member
@@ -131,7 +131,9 @@ gnulib_modules="
lchown
lib-ignore
linebuffer
+ link
link-follow
+ linkat
long-options
lstat
maintainer-makefile
@@ -176,9 +178,9 @@ gnulib_modules="
readutmp
realloc
regex
+ rename
rename-dest-slash
rmdir
- rmdir-errno
root-dev-ino
rpmatch
safe-read
@@ -200,12 +202,15 @@ gnulib_modules="
strdup-posix
strftime
strpbrk
+ strsignal
strtoimax
strtoumax
strverscmp
+ symlink
sys_stat
timespec
tzset
+ uname
unicodeio
unistd-safer
unlink-busy
@@ -234,6 +239,7 @@ gnulib_modules="
xnanosleep
xprintf
xprintf-posix
+ xreadlink
xstrtod
xstrtoimax
xstrtol
@@ -290,7 +296,6 @@ if test $gettext_external = 1; then
m4/glibc2.m4
m4/intdiv0.m4
m4/lcmessage.m4
- m4/lock.m4
m4/uintmax_t.m4
m4/ulonglong.m4
m4/visibility.m4
@@ -317,3 +322,11 @@ tar -
# Automake requires that ChangeLog exist.
touch ChangeLog || exit 1
+
+bootstrap_epilogue()
+{
+ # Change paths in gnulib-tests/gnulib.mk from "../.." to "..".
+ m=gnulib-tests/gnulib.mk
+ sed 's,\.\./\.\.,..,g' $m > $m-t
+ mv -f $m-t $m
+}
diff --git a/cfg.mk b/cfg.mk
index 57f211b85..5de2f37d5 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -25,13 +25,13 @@ gnu_rel_host = $(gnu_ftp_host-$(RELEASE_TYPE))
manual_title = Core GNU utilities
url_dir_list = \
- ftp://$(gnu_rel_host)/gnu/coreutils
+ ftp://$(gnu_rel_host)/gnu/$(PACKAGE)
# The GnuPG ID of the key used to sign the tarballs.
gpg_key_ID = B9AB9A16
# Tests not to run as part of "make distcheck".
-local-checks-to-skip = strftime-check
+local-checks-to-skip =
# Tools used to bootstrap this package, used for "announcement".
bootstrap-tools = autoconf,automake,gnulib,bison
@@ -39,7 +39,7 @@ bootstrap-tools = autoconf,automake,gnulib,bison
# Now that we have better tests, make this the default.
export VERBOSE = yes
-old_NEWS_hash = 93ff8e5850f630855f9e834fec416830
+old_NEWS_hash = 785e51bc9af87e7eb004f9ba24a0ca27
# Ensure that the list of O_ symbols used to compute O_FULLBLOCK is complete.
dd = $(srcdir)/src/dd.c
diff --git a/configure.ac b/configure.ac
index fa82b4c09..4902fea67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,8 +118,6 @@ fi
AC_FUNC_FORK
optional_bin_progs=
-AC_CHECK_FUNCS([uname],
- gl_ADD_PROG([optional_bin_progs], [uname]))
AC_CHECK_FUNCS([chroot],
gl_ADD_PROG([optional_bin_progs], [chroot]))
AC_CHECK_FUNCS([gethostid],
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 86394a152..5026e7607 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -176,198 +176,198 @@ Free Documentation License''.
@cindex file utilities
@menu
-* Introduction:: Caveats, overview, and authors.
-* Common options:: Common options.
-* Output of entire files:: cat tac nl od
-* Formatting file contents:: fmt pr fold
-* Output of parts of files:: head tail split csplit
-* Summarizing files:: wc sum cksum md5sum sha1sum sha2
-* Operating on sorted files:: sort shuf uniq comm ptx tsort
-* Operating on fields within a line:: cut paste join
-* Operating on characters:: tr expand unexpand
-* Directory listing:: ls dir vdir dircolors
-* Basic operations:: cp dd install mv rm shred
-* Special file types:: ln mkdir rmdir mkfifo mknod
-* Changing file attributes:: chgrp chmod chown touch
-* Disk usage:: df du stat sync truncate
-* Printing text:: echo printf yes
-* Conditions:: false true test expr
-* Redirection:: tee
-* File name manipulation:: dirname basename pathchk
-* Working context:: pwd stty printenv tty
-* User information:: id logname whoami groups users who
-* System context:: date uname hostname hostid uptime
-* SELinux context:: chcon runcon
-* Modified command invocation:: chroot env nice nohup stdbuf su timeout
-* Process control:: kill
-* Delaying:: sleep
-* Numeric operations:: factor seq
-* File permissions:: Access modes.
-* Date input formats:: Specifying date strings.
-* Opening the software toolbox:: The software tools philosophy.
-* GNU Free Documentation License:: Copying and sharing this manual.
-* Concept index:: General index.
+* Introduction:: Caveats, overview, and authors
+* Common options:: Common options
+* Output of entire files:: cat tac nl od base64
+* Formatting file contents:: fmt pr fold
+* Output of parts of files:: head tail split csplit
+* Summarizing files:: wc sum cksum md5sum sha1sum sha2
+* Operating on sorted files:: sort shuf uniq comm ptx tsort
+* Operating on fields:: cut paste join
+* Operating on characters:: tr expand unexpand
+* Directory listing:: ls dir vdir dircolors
+* Basic operations:: cp dd install mv rm shred
+* Special file types:: mkdir rmdir unlink mkfifo mknod ln link readlink
+* Changing file attributes:: chgrp chmod chown touch
+* Disk usage:: df du stat sync truncate
+* Printing text:: echo printf yes
+* Conditions:: false true test expr
+* Redirection:: tee
+* File name manipulation:: dirname basename pathchk
+* Working context:: pwd stty printenv tty
+* User information:: id logname whoami groups users who
+* System context:: date arch uname hostname hostid uptime
+* SELinux context:: chcon runcon
+* Modified command invocation:: chroot env nice nohup stdbuf su timeout
+* Process control:: kill
+* Delaying:: sleep
+* Numeric operations:: factor seq
+* File permissions:: Access modes
+* Date input formats:: Specifying date strings
+* Opening the software toolbox:: The software tools philosophy
+* GNU Free Documentation License:: Copying and sharing this manual
+* Concept index:: General index
@detailmenu
--- The Detailed Node Listing ---
Common Options
-* Exit status:: Indicating program success or failure.
-* Backup options:: Backup options
-* Block size:: Block size
-* Signal specifications:: Specifying signals
+* Exit status:: Indicating program success or failure
+* Backup options:: Backup options
+* Block size:: Block size
+* Signal specifications:: Specifying signals
* Disambiguating names and IDs:: chgrp and chown owner and group syntax
-* Random sources:: Sources of random data
-* Target directory:: Target directory
-* Trailing slashes:: Trailing slashes
-* Traversing symlinks:: Traversing symlinks to directories
-* Treating / specially:: Treating / specially
-* Standards conformance:: Standards conformance
+* Random sources:: Sources of random data
+* Target directory:: Target directory
+* Trailing slashes:: Trailing slashes
+* Traversing symlinks:: Traversing symlinks to directories
+* Treating / specially:: Treating / specially
+* Standards conformance:: Standards conformance
Output of entire files
-* cat invocation:: Concatenate and write files.
-* tac invocation:: Concatenate and write files in reverse.
-* nl invocation:: Number lines and write files.
-* od invocation:: Write files in octal or other formats.
-* base64 invocation:: Transform data into printable data.
+* cat invocation:: Concatenate and write files
+* tac invocation:: Concatenate and write files in reverse
+* nl invocation:: Number lines and write files
+* od invocation:: Write files in octal or other formats
+* base64 invocation:: Transform data into printable data
Formatting file contents
-* fmt invocation:: Reformat paragraph text.
-* pr invocation:: Paginate or columnate files for printing.
-* fold invocation:: Wrap input lines to fit in specified width.
+* fmt invocation:: Reformat paragraph text
+* pr invocation:: Paginate or columnate files for printing
+* fold invocation:: Wrap input lines to fit in specified width
Output of parts of files
-* head invocation:: Output the first part of files.
-* tail invocation:: Output the last part of files.
-* split invocation:: Split a file into fixed-size pieces.
-* csplit invocation:: Split a file into context-determined pieces.
+* head invocation:: Output the first part of files
+* tail invocation:: Output the last part of files
+* split invocation:: Split a file into fixed-size pieces
+* csplit invocation:: Split a file into context-determined pieces
Summarizing files
-* wc invocation:: Print newline, word, and byte counts.
-* sum invocation:: Print checksum and block counts.
-* cksum invocation:: Print CRC checksum and byte counts.
-* md5sum invocation:: Print or check MD5 digests.
-* sha1sum invocation:: Print or check SHA-1 digests.
-* sha2 utilities:: Print or check SHA-2 digests.
+* wc invocation:: Print newline, word, and byte counts
+* sum invocation:: Print checksum and block counts
+* cksum invocation:: Print CRC checksum and byte counts
+* md5sum invocation:: Print or check MD5 digests
+* sha1sum invocation:: Print or check SHA-1 digests
+* sha2 utilities:: Print or check SHA-2 digests
Operating on sorted files
-* sort invocation:: Sort text files.
-* shuf invocation:: Shuffle text files.
-* uniq invocation:: Uniquify files.
-* comm invocation:: Compare two sorted files line by line.
-* ptx invocation:: Produce a permuted index of file contents.
-* tsort invocation:: Topological sort.
+* sort invocation:: Sort text files
+* shuf invocation:: Shuffle text files
+* uniq invocation:: Uniquify files
+* comm invocation:: Compare two sorted files line by line
+* ptx invocation:: Produce a permuted index of file contents
+* tsort invocation:: Topological sort
@command{ptx}: Produce permuted indexes
-* General options in ptx:: Options which affect general program behavior.
-* Charset selection in ptx:: Underlying character set considerations.
-* Input processing in ptx:: Input fields, contexts, and keyword selection.
-* Output formatting in ptx:: Types of output format, and sizing the fields.
-* Compatibility in ptx:: The @acronym{GNU} extensions to @command{ptx}
+* General options in ptx:: Options which affect general program behavior
+* Charset selection in ptx:: Underlying character set considerations
+* Input processing in ptx:: Input fields, contexts, and keyword selection
+* Output formatting in ptx:: Types of output format, and sizing the fields
+* Compatibility in ptx:: The @acronym{GNU} extensions to @command{ptx}
-Operating on fields within a line
+Operating on fields
-* cut invocation:: Print selected parts of lines.
-* paste invocation:: Merge lines of files.
-* join invocation:: Join lines on a common field.
+* cut invocation:: Print selected parts of lines
+* paste invocation:: Merge lines of files
+* join invocation:: Join lines on a common field
Operating on characters
-* tr invocation:: Translate, squeeze, and/or delete characters.
-* expand invocation:: Convert tabs to spaces.
-* unexpand invocation:: Convert spaces to tabs.
+* tr invocation:: Translate, squeeze, and/or delete characters
+* expand invocation:: Convert tabs to spaces
+* unexpand invocation:: Convert spaces to tabs
@command{tr}: Translate, squeeze, and/or delete characters
-* Character sets:: Specifying sets of characters.
-* Translating:: Changing one set of characters to another.
-* Squeezing:: Squeezing repeats and deleting.
+* Character sets:: Specifying sets of characters
+* Translating:: Changing one set of characters to another
+* Squeezing:: Squeezing repeats and deleting
Directory listing
-* ls invocation:: List directory contents
-* dir invocation:: Briefly list directory contents
-* vdir invocation:: Verbosely list directory contents
-* dircolors invocation:: Color setup for @command{ls}
+* ls invocation:: List directory contents
+* dir invocation:: Briefly list directory contents
+* vdir invocation:: Verbosely list directory contents
+* dircolors invocation:: Color setup for @command{ls}
@command{ls}: List directory contents
-* Which files are listed:: Which files are listed
-* What information is listed:: What information is listed
-* Sorting the output:: Sorting the output
-* More details about version sort:: More details about version sort
-* General output formatting:: General output formatting
-* Formatting the file names:: Formatting the file names
+* Which files are listed:: Which files are listed
+* What information is listed:: What information is listed
+* Sorting the output:: Sorting the output
+* Details about version sort:: More details about version sort
+* General output formatting:: General output formatting
+* Formatting the file names:: Formatting the file names
Basic operations
-* cp invocation:: Copy files and directories
-* dd invocation:: Convert and copy a file
-* install invocation:: Copy files and set attributes
-* mv invocation:: Move (rename) files
-* rm invocation:: Remove files or directories
-* shred invocation:: Remove files more securely
+* cp invocation:: Copy files and directories
+* dd invocation:: Convert and copy a file
+* install invocation:: Copy files and set attributes
+* mv invocation:: Move (rename) files
+* rm invocation:: Remove files or directories
+* shred invocation:: Remove files more securely
Special file types
-* link invocation:: Make a hard link via the link syscall
-* ln invocation:: Make links between files
-* mkdir invocation:: Make directories
-* mkfifo invocation:: Make FIFOs (named pipes)
-* mknod invocation:: Make block or character special files
-* readlink invocation:: Print value of a symlink or canonical file name
-* rmdir invocation:: Remove empty directories
-* unlink invocation:: Remove files via unlink syscall
+* link invocation:: Make a hard link via the link syscall
+* ln invocation:: Make links between files
+* mkdir invocation:: Make directories
+* mkfifo invocation:: Make FIFOs (named pipes)
+* mknod invocation:: Make block or character special files
+* readlink invocation:: Print value of a symlink or canonical file name
+* rmdir invocation:: Remove empty directories
+* unlink invocation:: Remove files via unlink syscall
Changing file attributes
-* chown invocation:: Change file owner and group
-* chgrp invocation:: Change group ownership
-* chmod invocation:: Change access permissions
-* touch invocation:: Change file timestamps
+* chown invocation:: Change file owner and group
+* chgrp invocation:: Change group ownership
+* chmod invocation:: Change access permissions
+* touch invocation:: Change file timestamps
Disk usage
-* df invocation:: Report file system disk space usage
-* du invocation:: Estimate file space usage
-* stat invocation:: Report file or file system status
-* sync invocation:: Synchronize data on disk with memory
-* truncate invocation:: Shrink or extend the size of a file
+* df invocation:: Report file system disk space usage
+* du invocation:: Estimate file space usage
+* stat invocation:: Report file or file system status
+* sync invocation:: Synchronize data on disk with memory
+* truncate invocation:: Shrink or extend the size of a file
Printing text
-* echo invocation:: Print a line of text
-* printf invocation:: Format and print data
-* yes invocation:: Print a string until interrupted
+* echo invocation:: Print a line of text
+* printf invocation:: Format and print data
+* yes invocation:: Print a string until interrupted
Conditions
-* false invocation:: Do nothing, unsuccessfully
-* true invocation:: Do nothing, successfully
-* test invocation:: Check file types and compare values
-* expr invocation:: Evaluate expressions
+* false invocation:: Do nothing, unsuccessfully
+* true invocation:: Do nothing, successfully
+* test invocation:: Check file types and compare values
+* expr invocation:: Evaluate expressions
@command{test}: Check file types and compare values
-* File type tests:: File type tests
-* Access permission tests:: Access permission tests
-* File characteristic tests:: File characteristic tests
-* String tests:: String tests
-* Numeric tests:: Numeric tests
+* File type tests:: File type tests
+* Access permission tests:: Access permission tests
+* File characteristic tests:: File characteristic tests
+* String tests:: String tests
+* Numeric tests:: Numeric tests
@command{expr}: Evaluate expression
-* String expressions:: + : match substr index length
-* Numeric expressions:: + - * / %
-* Relations for expr:: | & < <= = == != >= >
-* Examples of expr:: Examples of using @command{expr}
+* String expressions:: + : match substr index length
+* Numeric expressions:: + - * / %
+* Relations for expr:: | & < <= = == != >= >
+* Examples of expr:: Examples of using @command{expr}
Redirection
@@ -388,13 +388,13 @@ Working context
@command{stty}: Print or change terminal characteristics
-* Control:: Control settings
-* Input:: Input settings
-* Output:: Output settings
-* Local:: Local settings
-* Combination:: Combination settings
-* Characters:: Special characters
-* Special:: Special settings
+* Control:: Control settings
+* Input:: Input settings
+* Output:: Output settings
+* Local:: Local settings
+* Combination:: Combination settings
+* Characters:: Special characters
+* Special:: Special settings
User information
@@ -420,10 +420,10 @@ System context
* Date conversion specifiers:: %[aAbBcCdDeFgGhjmuUVwWxyY]
* Literal conversion specifiers:: %[%nt]
* Padding and other flags:: Pad with zeros, spaces, etc.
-* Setting the time:: Changing the system clock.
-* Options for date:: Instead of the current time.
-* Date input formats:: Specifying date strings.
-* Examples of date:: Examples.
+* Setting the time:: Changing the system clock
+* Options for date:: Instead of the current time
+* Date input formats:: Specifying date strings
+* Examples of date:: Examples
SELinux context
@@ -455,23 +455,23 @@ Numeric operations
File permissions
-* Mode Structure:: Structure of file mode bits.
-* Symbolic Modes:: Mnemonic representation of file mode bits.
-* Numeric Modes:: File mode bits as octal numbers.
-* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories.
+* Mode Structure:: Structure of file mode bits
+* Symbolic Modes:: Mnemonic representation of file mode bits
+* Numeric Modes:: File mode bits as octal numbers
+* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories
Date input formats
-* General date syntax:: Common rules.
-* Calendar date items:: 19 Dec 1994.
-* Time of day items:: 9:20pm.
-* Time zone items:: @sc{est}, @sc{pdt}, @sc{gmt}.
-* Day of week items:: Monday and others.
-* Relative items in date strings:: next tuesday, 2 years ago.
-* Pure numbers in date strings:: 19931219, 1440.
-* Seconds since the Epoch:: @@1078100502.
-* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0".
-* Authors of get_date:: Bellovin, Eggert, Salz, Berets, et al.
+* General date syntax:: Common rules
+* Calendar date items:: 19 Dec 1994
+* Time of day items:: 9:20pm
+* Time zone items:: @sc{est}, @sc{pdt}, @sc{gmt}
+* Day of week items:: Monday and others
+* Relative items in date strings:: next tuesday, 2 years ago
+* Pure numbers in date strings:: 19931219, 1440
+* Seconds since the Epoch:: @@1078100502
+* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0"
+* Authors of get_date:: Bellovin, Eggert, Salz, Berets, et al
Opening the software toolbox
@@ -485,7 +485,7 @@ Opening the software toolbox
Copying This Manual
-* GNU Free Documentation License:: Copying and sharing this manual.
+* GNU Free Documentation License:: Copying and sharing this manual
@end detailmenu
@end menu
@@ -618,15 +618,8 @@ from the shell.
@end macro
@macro multiplierSuffixes{varName}
-@ignore
-Appending @samp{b} multiplies @var{\varName\} by 512,
-@samp{kB} by 1000, @samp{K} by 1024,
-@samp{MB} by 1000*1000, @samp{M} by 1024*1024,
-@samp{GB} by 1000*1000*1000, @samp{G} by 1024*1024*1024,
-and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}.
-@end ignore
-@var{\varName\} is a number which may have one of the following
-multiplicative suffixes:
+@var{\varName\} may be, or may be an integer optionally followed by,
+one of the following multiplicative suffixes:
@example
@samp{b} => 512 ("blocks")
@samp{KB} => 1000 (KiloBytes)
@@ -641,8 +634,8 @@ and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}.
@c FIXME: same as above, but no ``blocks'' line.
@macro multiplierSuffixesNoBlocks{varName}
-@var{\varName\} is a number which may have one of the following
-multiplicative suffixes:
+@var{\varName\} may be, or may be an integer optionally followed by,
+one of the following multiplicative suffixes:
@example
@samp{KB} => 1000 (KiloBytes)
@samp{K} => 1024 (KibiBytes)
@@ -752,8 +745,8 @@ However, some of the programs documented here do produce
other exit status values and a few associate different
meanings with the values @samp{0} and @samp{1}.
Here are some of the exceptions:
-@command{chroot}, @command{env}, @command{expr},
-@command{nice}, @command{nohup}, @command{printenv}, @command{sort},
+@command{chroot}, @command{env}, @command{expr}, @command{nice},
+@command{nohup}, @command{printenv}, @command{sort}, @command{stdbuf},
@command{su}, @command{test}, @command{timeout}, @command{tty}.
@@ -2782,9 +2775,10 @@ growing.
The option values @samp{descriptor} and @samp{name} may be specified only
with the long form of the option, not with @option{-f}.
-@vindex POSIXLY_CORRECT
-If @env{POSIXLY_CORRECT} is set, the @option{-f} option is ignored if
+The @option{-f} option is ignored if
no @var{file} operand is specified and standard input is a FIFO or a pipe.
+Likewise, the @option{-f} option has no effect for any
+operand specified as @samp{-}, when standard input is a FIFO or a pipe.
@item -F
@opindex -F
@@ -5242,8 +5236,8 @@ the way the linker handled archive files, which has since been solved
in different ways.
-@node Operating on fields within a line
-@chapter Operating on fields within a line
+@node Operating on fields
+@chapter Operating on fields
@menu
* cut invocation:: Print selected parts of lines.
@@ -6119,8 +6113,9 @@ Exit status:
1 minor problems (e.g., failure to access a file or directory not
specified as a command line argument. This happens when listing a
directory in which entries are actively being removed or renamed.)
-2 serious trouble (e.g., memory exhausted, invalid option or failure
- to access file or directory specified as a command line argument)
+2 serious trouble (e.g., memory exhausted, invalid option, failure
+ to access a file or directory specified as a command line argument
+ or a directory loop)
@end display
Also see @ref{Common options}.
@@ -6129,7 +6124,7 @@ Also see @ref{Common options}.
* Which files are listed::
* What information is listed::
* Sorting the output::
-* More details about version sort::
+* Details about version sort::
* General output formatting::
* Formatting file timestamps::
* Formatting the file names::
@@ -6659,7 +6654,7 @@ directories, since not doing any sorting can be noticeably faster.
@opindex version@r{, sorting option for @command{ls}}
Sort by version name and number, lowest first. It behaves like a default
sort, except that each sequence of decimal digits is treated numerically
-as an index/version number. (@xref{More details about version sort}.)
+as an index/version number. (@xref{Details about version sort}.)
@item -X
@itemx --sort=extension
@@ -6672,8 +6667,8 @@ after the last @samp{.}); files with no extension are sorted first.
@end table
-@node More details about version sort
-@subsection More details about version sort
+@node Details about version sort
+@subsection Details about version sort
The version sort takes into account the fact that file names frequently include
indices or version numbers. Standard sorting functions usually do not produce
@@ -7774,8 +7769,8 @@ input newline with a space and padding with spaces as necessary.
@item unblock
@opindex unblock
-Replace trailing spaces in each @samp{cbs}-sized input block with a
-newline.
+Remove any trailing spaces in each @samp{cbs}-sized input block,
+and append a newline.
The @samp{block} and @samp{unblock} conversions are mutually exclusive.
@@ -8759,6 +8754,11 @@ On a @acronym{GNU} system, this command acts like @samp{ln --directory
not specified by @acronym{POSIX}, and the @command{link} command is
more portable in practice.
+If @var{filename} is a symbolic link, it is unspecified whether
+@var{linkname} will be a hard link to the symbolic link or to the
+target of the symbolic link. Use @command{ln -P} or @command{ln -L}
+to specify which behavior is desired.
+
@exitstatus
@@ -8814,8 +8814,10 @@ A @dfn{hard link} is another name for an existing file; the link and the
original are indistinguishable. Technically speaking, they share the
same inode, and the inode contains all the information about a
file---indeed, it is not incorrect to say that the inode @emph{is} the
-file. On all existing implementations, you cannot make a hard link to
-a directory, and hard links cannot cross file system boundaries. (These
+file. Most systems prohibit making a hard link to
+a directory; on those where it is allowed, only the super-user can do
+so (and with caution, since creating a cycle will cause problems to many
+other utilities). Hard links cannot cross file system boundaries. (These
restrictions are not mandated by @acronym{POSIX}, however.)
@cindex dereferencing symbolic links
@@ -8827,9 +8829,13 @@ refers to a different file, by name. When most operations (opening,
reading, writing, and so on) are passed the symbolic link file, the
kernel automatically @dfn{dereferences} the link and operates on the
target of the link. But some operations (e.g., removing) work on the
-link file itself, rather than on its target. The owner, group, and
-mode of a symlink are not significant to file access performed through
-the link. @xref{Symbolic Links,,,
+link file itself, rather than on its target. The owner and group of a
+symlink are not significant to file access performed through
+the link, but do have implications on deleting a symbolic link from a
+directory with the restricted deletion bit set. On the GNU system,
+the mode of a symlink has no significance and cannot be changed, but
+on some BSD systems, the mode can be changed and will affect whether
+the symlink will be traversed in file name resolution. @xref{Symbolic Links,,,
libc, The GNU C Library Reference Manual}.
Symbolic links can contain arbitrary strings; a @dfn{dangling symlink}
@@ -8884,6 +8890,14 @@ Remove existing destination files.
@cindex prompting, and @command{ln}
Prompt whether to remove existing destination files.
+@item -L
+@itemx --logical
+@opindex -L
+@opindex --logical
+If @option{-s} is not in effect, and the source file is a symbolic
+link, create the hard link to the file referred to by the symbolic
+link, rather than the symbolic link itself.
+
@item -n
@itemx --no-dereference
@opindex -n
@@ -8905,6 +8919,17 @@ just like a directory.
This option is weaker than the @option{--no-target-directory}
(@option{-T}) option, so it has no effect if both options are given.
+@item -P
+@itemx --physical
+@opindex -P
+@opindex --physical
+If @option{-s} is not in effect, and the source file is a symbolic
+link, create the hard link to the symbolic link itself. On platforms
+where this is not supported by the kernel, this option creates a
+symbolic link with identical contents; since symbolic link contents
+cannot be edited, any file name resolution performed through either
+link will be the same as if a hard link had been created.
+
@item -s
@itemx --symbolic
@opindex -s
@@ -8926,6 +8951,15 @@ Print the name of each file after linking it successfully.
@end table
+@cindex hard links to symbolic links
+@cindex symbolic links and @command{ln}
+If @option{-L} and @option{-P} are both given, the last one takes
+precedence. If @option{-s} is also given, @option{-L} and @option{-P}
+are silently ignored. If neither option is given, then this
+implementation defaults to @option{-P} if the system @code{link} supports
+hard links to symbolic links (such as the GNU system), and @option{-L}
+if @code{link} follows symbolic links (such as on BSD).
+
@exitstatus
Examples:
@@ -9210,7 +9244,8 @@ The program accepts the following options. Also see @ref{Common options}.
@opindex --canonicalize
Activate canonicalize mode.
If any component of the file name except the last one is missing or unavailable,
-@command{readlink} produces no output and exits with a nonzero exit code.
+@command{readlink} produces no output and exits with a nonzero exit
+code. A trailing slash is ignored.
@item -e
@itemx --canonicalize-existing
@@ -9218,7 +9253,8 @@ If any component of the file name except the last one is missing or unavailable,
@opindex --canonicalize-existing
Activate canonicalize mode.
If any component is missing or unavailable, @command{readlink} produces
-no output and exits with a nonzero exit code.
+no output and exits with a nonzero exit code. A trailing slash
+requires that the name resolve to a directory.
@item -m
@itemx --canonicalize-missing
@@ -9922,6 +9958,7 @@ If the year is specified with only two digits, then @var{cc}
is 20 for years in the range 0 @dots{} 68, and 19 for years in
69 @dots{} 99. If no digits of the year are specified,
the argument is interpreted as a date in the current year.
+Note that @var{ss} may be @samp{60}, to accommodate leap seconds.
@end table
@@ -12831,9 +12868,13 @@ running it if no user is specified. Synopsis:
id [@var{option}]@dots{} [@var{username}]
@end example
+@vindex POSIXLY_CORRECT
By default, it prints the real user ID, real group ID, effective user ID
if different from the real user ID, effective group ID if different from
the real group ID, and supplemental group IDs.
+In addition, if SELinux
+is enabled and the @env{POSIXLY_CORRECT} environment variable is not set,
+then print @samp{context=@var{c}}, where @var{c} is the security context.
Each of these numeric values is preceded by an identifying string and
followed by the corresponding user or group name in parentheses.
diff --git a/gl/lib/tempname.c b/gl/lib/tempname.c
index 01715168d..84679bcf2 100644
--- a/gl/lib/tempname.c
+++ b/gl/lib/tempname.c
@@ -41,8 +41,7 @@
# define TMP_MAX 238328
#endif
#ifndef __GT_FILE
-# define __GT_FILE 0
-# define __GT_BIGFILE 1
+# define __GT_FILE 1
# define __GT_DIR 2
# define __GT_NOCREATE 3
#endif
@@ -61,12 +60,9 @@
#if _LIBC
# define struct_stat64 struct stat64
-# define small_open __open
-# define large_open __open64
#else
# define struct_stat64 struct stat
-# define small_open open
-# define large_open open
+# define __open open
# define __gen_tempname gen_tempname
# define __getpid getpid
# define __gettimeofday gettimeofday
@@ -172,12 +168,11 @@ static const char letters[] =
at the time of the call.
__GT_FILE: create the file using open(O_CREAT|O_EXCL)
and return a read-write fd. The file is mode 0600.
- __GT_BIGFILE: same as __GT_FILE but use open64().
__GT_DIR: create a directory, which will be mode 0700.
We use a clever algorithm to get hard-to-predict names. */
int
-gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
+gen_tempname_len (char *tmpl, int flags, int kind, size_t x_suffix_len)
{
size_t len;
char *XXXXXX;
@@ -230,11 +225,9 @@ gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
switch (kind)
{
case __GT_FILE:
- fd = small_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
- break;
-
- case __GT_BIGFILE:
- fd = large_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ fd = __open (tmpl,
+ (flags & ~0777) | O_RDWR | O_CREAT | O_EXCL,
+ S_IRUSR | S_IWUSR);
break;
case __GT_DIR:
@@ -295,7 +288,7 @@ gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
}
int
-__gen_tempname (char *tmpl, int kind)
+__gen_tempname (char *tmpl, int flags, int kind)
{
- return gen_tempname_len (tmpl, kind, 6);
+ return gen_tempname_len (tmpl, flags, kind, 6);
}
diff --git a/gl/lib/tempname.h b/gl/lib/tempname.h
index ee34aca21..a942f07d7 100644
--- a/gl/lib/tempname.h
+++ b/gl/lib/tempname.h
@@ -37,5 +37,6 @@
We use a clever algorithm to get hard-to-predict names. */
#include <stddef.h>
-extern int gen_tempname (char *tmpl, int kind);
-extern int gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len);
+extern int gen_tempname (char *tmpl, int flags, int kind);
+extern int gen_tempname_len (char *tmpl, int flags, int kind,
+ size_t x_suffix_len);
diff --git a/gnulib b/gnulib
-Subproject c46ae39631773a7fdae7d171cc4ef0bf2123eff
+Subproject 959d9cb463d992f9c5cc2fbeb54bf12eee2346f
diff --git a/lib/fdopendir-glibc.c b/lib/fdopendir-glibc.c
deleted file mode 100644
index 1e6a460e9..000000000
--- a/lib/fdopendir-glibc.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* fdopendir implementation derived from glibc.
-
- Copyright (C) 2006, 2009 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- 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/>. */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdbool.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#if _LIBC
-# include <dirstream.h>
-# include <not-cancel.h>
-
-#else
-
-# if __GNUC__ < 3
-# define __builtin_expect(expr, expected_val) expr
-# endif
-
-# include "openat.h"
-# define stat64 stat
-# define dirent64 dirent
-# define __fxstat64(V, fd, sb) fstat(fd, sb)
-# define __fcntl fcntl
-# define __set_errno(Val) do { errno = (Val); } while (0)
-# define __libc_lock_init(NAME) ((NAME) = 0, 0)
-# define close_not_cancel_no_status(fd) close (fd)
-# ifdef __i386__
-# define internal_function __attribute ((regparm (3), stdcall))
-# else
-# define internal_function
-# endif
-
-struct __dirstream
- {
- int fd; /* File descriptor. */
-
- char *data; /* Directory block. */
- size_t allocation; /* Space allocated for the block. */
- size_t size; /* Total valid data in the block. */
- size_t offset; /* Current offset into the block. */
-
- off_t filepos; /* Position of next entry to read. */
- int lock;
- };
-#endif
-
-#undef _STATBUF_ST_BLKSIZE
-
-static DIR *
-internal_function
-__alloc_dir (int fd, bool close_fd)
-{
- if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0)
- goto lose;
-
- size_t allocation;
-#ifdef _STATBUF_ST_BLKSIZE
- if (__builtin_expect ((size_t) statp->st_blksize >= sizeof (struct dirent64),
- 1))
- allocation = statp->st_blksize;
- else
-#endif
- allocation = (BUFSIZ < sizeof (struct dirent64)
- ? sizeof (struct dirent64) : BUFSIZ);
-
- const int pad = -sizeof (DIR) % __alignof__ (struct dirent64);
-
- DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation + pad);
- if (dirp == NULL)
- lose:
- {
- if (close_fd)
- {
- int save_errno = errno;
- close_not_cancel_no_status (fd);
- __set_errno (save_errno);
- }
- return NULL;
- }
- memset (dirp, '\0', sizeof (DIR));
- dirp->data = (char *) (dirp + 1) + pad;
- dirp->allocation = allocation;
- dirp->fd = fd;
-
- __libc_lock_init (dirp->lock);
-
- return dirp;
-}
-
-DIR *
-fdopendir (int fd)
-{
-#if 0
- struct stat64 statbuf;
-
- if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &statbuf), 0) < 0)
- return NULL;
- if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
- {
- __set_errno (ENOTDIR);
- return NULL;
- }
- /* Make sure the descriptor allows for reading. */
- int flags = __fcntl (fd, F_GETFL);
- if (__builtin_expect (flags == -1, 0))
- return NULL;
- if (__builtin_expect ((flags & O_ACCMODE) == O_WRONLY, 0))
- {
- __set_errno (EINVAL);
- return NULL;
- }
-#endif
-
- return __alloc_dir (fd, false);
-}
diff --git a/m4/check-decl.m4 b/m4/check-decl.m4
index d1a520a71..530c59e16 100644
--- a/m4/check-decl.m4
+++ b/m4/check-decl.m4
@@ -1,4 +1,4 @@
-#serial 24
+#serial 25
# Check declarations for this package.
dnl Copyright (C) 1997-2001, 2003-2006, 2008-2009 Free Software
@@ -37,13 +37,7 @@ AC_DEFUN([gl_CHECK_DECLS],
AC_CHECK_DECLS([isblank], [], [], [#include <ctype.h>])
- AC_CHECK_DECLS_ONCE([free])
- AC_CHECK_DECLS_ONCE([getenv])
AC_CHECK_DECLS_ONCE([geteuid])
AC_CHECK_DECLS_ONCE([getlogin])
AC_CHECK_DECLS_ONCE([getuid])
- AC_CHECK_DECLS_ONCE([lseek])
- AC_CHECK_DECLS_ONCE([malloc])
- AC_CHECK_DECLS_ONCE([memchr])
- AC_CHECK_DECLS_ONCE([realloc])
])
diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4
index f4d43f1dd..833940469 100644
--- a/m4/jm-macros.m4
+++ b/m4/jm-macros.m4
@@ -89,9 +89,6 @@ AC_DEFUN([coreutils_MACROS],
tcgetpgrp \
)
- # for cp.c
- AC_CHECK_FUNCS_ONCE([utimensat])
-
dnl This can't use AC_REQUIRE; I'm not quite sure why.
cu_PREREQ_STAT_PROG
diff --git a/man/help2man b/man/help2man
index 7b7ce7a4b..3b19c6402 100755
--- a/man/help2man
+++ b/man/help2man
@@ -373,6 +373,7 @@ my $PAT_AUTHOR = _('Written +by');
my $PAT_OPTIONS = _('Options');
my $PAT_EXAMPLES = _('Examples');
my $PAT_FREE_SOFTWARE = _('This +is +free +software');
+my $PAT_INFO = _('For +complete +documentation');
# Start a new paragraph (if required) for these.
s/([^\n])\n($PAT_BUGS|$PAT_AUTHOR)/$1\n\n$2/og;
@@ -392,6 +393,11 @@ while (length)
$sect = _('EXAMPLES');
next;
}
+ # Skip any texinfo reference as that's handled separately
+ if (s/($PAT_INFO).*\n//o)
+ {
+ next;
+ }
# Copyright section
if (/^Copyright +[(\xa9]/)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6ded56861..e84e2eaf7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -20,6 +20,8 @@ lib/regcomp.c
lib/root-dev-ino.h
lib/rpmatch.c
lib/set-mode-acl.c
+lib/siglist.h
+lib/strsignal.c
lib/unicodeio.c
lib/userspec.c
lib/verror.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 0aa7599b4..915ea8165 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,25 +24,114 @@ no_install__progs = \
arch hostname su
build_if_possible__progs = \
- chroot df hostid nice pinky stdbuf libstdbuf.so stty su uname uptime users who
+ chroot \
+ df \
+ hostid \
+ libstdbuf.so \
+ nice \
+ pinky \
+ stdbuf \
+ stty \
+ su \
+ uptime \
+ users \
+ who
AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
EXTRA_PROGRAMS = \
$(no_install__progs) \
$(build_if_possible__progs) \
- [ chcon chgrp chown chmod cp dd dircolors du \
- ginstall link ln dir vdir ls mkdir \
- mkfifo mknod mktemp \
- mv nohup readlink rm rmdir shred stat sync touch unlink \
- cat cksum comm csplit cut expand fmt fold head join groups md5sum \
- nl od paste pr ptx sha1sum sha224sum sha256sum sha384sum sha512sum \
- shuf sort split sum tac tail tr tsort unexpand uniq wc \
- basename date dirname echo env expr factor false \
- id kill logname pathchk printenv printf pwd \
- runcon seq sleep tee \
- test timeout true truncate tty whoami yes \
- base64
+ [ \
+ base64 \
+ basename \
+ cat \
+ chcon \
+ chgrp \
+ chmod \
+ chown \
+ cksum \
+ comm \
+ cp \
+ csplit \
+ cut \
+ date \
+ dd \
+ dir \
+ dircolors \
+ dirname \
+ du \
+ echo \
+ env \
+ expand \
+ expr \
+ factor \
+ false \
+ fmt \
+ fold \
+ ginstall \
+ groups \
+ head \
+ id \
+ join \
+ kill \
+ link \
+ ln \
+ logname \
+ ls \
+ md5sum \
+ mkdir \
+ mkfifo \
+ mknod \
+ mktemp \
+ mv \
+ nl \
+ nohup \
+ od \
+ paste \
+ pathchk \
+ pr \
+ printenv \
+ printf \
+ ptx \
+ pwd \
+ readlink \
+ rm \
+ rmdir \
+ runcon \
+ seq \
+ sha1sum \
+ sha224sum \
+ sha256sum \
+ sha384sum \
+ sha512sum \
+ shred \
+ shuf \
+ sleep \
+ sort \
+ split \
+ stat \
+ sum \
+ sync \
+ tac \
+ tail \
+ tee \
+ test \
+ timeout \
+ touch \
+ tr \
+ true \
+ truncate \
+ tsort \
+ tty \
+ uname \
+ unexpand \
+ uniq \
+ unlink \
+ vdir \
+ wc \
+ whoami \
+ yes
bin_PROGRAMS = $(OPTIONAL_BIN_PROGS)
@@ -50,20 +139,20 @@ noinst_PROGRAMS = setuidgid getlimits
pkglib_PROGRAMS = $(OPTIONAL_PKGLIB_PROGS)
-noinst_HEADERS = \
- chown-core.h \
- copy.h \
- cp-hash.h \
- dircolors.h \
- fs.h \
- group-list.h \
- ls.h \
- operand2sig.h \
- prog-fprintf.h \
- remove.h \
- system.h \
- wheel-size.h \
- wheel.h \
+noinst_HEADERS = \
+ chown-core.h \
+ copy.h \
+ cp-hash.h \
+ dircolors.h \
+ fs.h \
+ group-list.h \
+ ls.h \
+ operand2sig.h \
+ prog-fprintf.h \
+ remove.h \
+ system.h \
+ wheel-size.h \
+ wheel.h \
uname.h
EXTRA_DIST = dcgen dircolors.hin tac-pipe.c \
@@ -87,99 +176,216 @@ nodist_libver_a_SOURCES = version.c version.h
# replacement functions defined in libcoreutils.a.
LDADD = libver.a ../lib/libcoreutils.a $(LIBINTL) ../lib/libcoreutils.a
+# First, list all programs, to make listing per-program libraries easier.
+# See [ below.
+arch_LDADD = $(LDADD)
+base64_LDADD = $(LDADD)
+basename_LDADD = $(LDADD)
cat_LDADD = $(LDADD)
+chcon_LDADD = $(LDADD)
+chgrp_LDADD = $(LDADD)
+chmod_LDADD = $(LDADD)
+chown_LDADD = $(LDADD)
+chroot_LDADD = $(LDADD)
+cksum_LDADD = $(LDADD)
+comm_LDADD = $(LDADD)
+cp_LDADD = $(LDADD)
+csplit_LDADD = $(LDADD)
+cut_LDADD = $(LDADD)
+date_LDADD = $(LDADD)
+dd_LDADD = $(LDADD)
df_LDADD = $(LDADD)
+# See dir_LDADD below
+dircolors_LDADD = $(LDADD)
+dirname_LDADD = $(LDADD)
du_LDADD = $(LDADD)
+echo_LDADD = $(LDADD)
+env_LDADD = $(LDADD)
+expand_LDADD = $(LDADD)
+expr_LDADD = $(LDADD)
+factor_LDADD = $(LDADD)
+false_LDADD = $(LDADD)
+fmt_LDADD = $(LDADD)
+fold_LDADD = $(LDADD)
getlimits_LDADD = $(LDADD)
+ginstall_LDADD = $(LDADD)
+groups_LDADD = $(LDADD)
+head_LDADD = $(LDADD)
+hostid_LDADD = $(LDADD)
+hostname_LDADD = $(LDADD)
+id_LDADD = $(LDADD)
+join_LDADD = $(LDADD)
+kill_LDADD = $(LDADD)
+link_LDADD = $(LDADD)
+ln_LDADD = $(LDADD)
+logname_LDADD = $(LDADD)
+ls_LDADD = $(LDADD)
+md5sum_LDADD = $(LDADD)
+mkdir_LDADD = $(LDADD)
+mkfifo_LDADD = $(LDADD)
+mknod_LDADD = $(LDADD)
+mktemp_LDADD = $(LDADD)
+mv_LDADD = $(LDADD)
+nice_LDADD = $(LDADD)
+nl_LDADD = $(LDADD)
+nohup_LDADD = $(LDADD)
+od_LDADD = $(LDADD)
+paste_LDADD = $(LDADD)
+pathchk_LDADD = $(LDADD)
+pinky_LDADD = $(LDADD)
+pr_LDADD = $(LDADD)
+printenv_LDADD = $(LDADD)
+printf_LDADD = $(LDADD)
ptx_LDADD = $(LDADD)
+pwd_LDADD = $(LDADD)
+readlink_LDADD = $(LDADD)
+rm_LDADD = $(LDADD)
+rmdir_LDADD = $(LDADD)
+runcon_LDADD = $(LDADD)
+seq_LDADD = $(LDADD)
+setuidgid_LDADD = $(LDADD)
+sha1sum_LDADD = $(LDADD)
+sha224sum_LDADD = $(LDADD)
+sha256sum_LDADD = $(LDADD)
+sha384sum_LDADD = $(LDADD)
+sha512sum_LDADD = $(LDADD)
+shred_LDADD = $(LDADD)
+shuf_LDADD = $(LDADD)
+sleep_LDADD = $(LDADD)
+sort_LDADD = $(LDADD)
split_LDADD = $(LDADD)
+stat_LDADD = $(LDADD)
stdbuf_LDADD = $(LDADD)
+stty_LDADD = $(LDADD)
+su_LDADD = $(LDADD)
+sum_LDADD = $(LDADD)
+sync_LDADD = $(LDADD)
+tac_LDADD = $(LDADD)
+tail_LDADD = $(LDADD)
+tee_LDADD = $(LDADD)
+test_LDADD = $(LDADD)
timeout_LDADD = $(LDADD)
+touch_LDADD = $(LDADD)
+tr_LDADD = $(LDADD)
+true_LDADD = $(LDADD)
truncate_LDADD = $(LDADD)
-
-# for eaccess in lib/euidaccess.c.
-chcon_LDADD = $(LDADD) $(LIB_SELINUX)
-cp_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX)
-ginstall_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX)
-mkdir_LDADD = $(LDADD) $(LIB_SELINUX)
-mkfifo_LDADD = $(LDADD) $(LIB_SELINUX)
-mknod_LDADD = $(LDADD) $(LIB_SELINUX)
-mv_LDADD = $(LDADD) $(LIB_EACCESS) $(LIB_SELINUX)
-runcon_LDADD = $(LDADD) $(LIB_SELINUX)
-pathchk_LDADD = $(LDADD) $(LIB_EACCESS)
-rm_LDADD = $(LDADD) $(LIB_EACCESS)
-test_LDADD = $(LDADD) $(LIB_EACCESS)
-# This is for the '[' program. Automake transliterates '[' to '_'.
-__LDADD = $(LDADD) $(LIB_EACCESS)
-
-# for clock_gettime and fdatasync
-dd_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC)
-dir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP)
-id_LDADD = $(LDADD) $(LIB_SELINUX)
-ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP)
-mktemp_LDADD = $(LDADD) $(LIB_GETHRXTIME)
-pr_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
-shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC)
-shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME)
-tac_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
-vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX) $(LIB_CAP)
-
-## If necessary, add -lm to resolve use of pow in lib/strtod.c.
-sort_LDADD = $(LDADD) $(POW_LIB) $(LIB_GETHRXTIME)
-
-# for get_date and gettime
-date_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
-touch_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
-
-# If necessary, add -lm to resolve use of pow in lib/strtod.c.
-# If necessary, add -liconv to resolve use of iconv in lib/unicodeio.c.
-printf_LDADD = $(LDADD) $(POW_LIB) $(LIBICONV)
-
-# If necessary, add -lm to resolve use of pow in lib/strtod.c.
-seq_LDADD = $(LDADD) $(POW_LIB)
-
-# If necessary, add libraries to resolve the `pow' reference in lib/strtod.c
-# and the `nanosleep' reference in lib/xnanosleep.c.
-nanosec_libs = $(LDADD) $(POW_LIB) $(LIB_NANOSLEEP)
-
-# for various GMP functions
-expr_LDADD = $(LDADD) $(LIB_GMP)
+tsort_LDADD = $(LDADD)
+tty_LDADD = $(LDADD)
+uname_LDADD = $(LDADD)
+unexpand_LDADD = $(LDADD)
+uniq_LDADD = $(LDADD)
+unlink_LDADD = $(LDADD)
+uptime_LDADD = $(LDADD)
+users_LDADD = $(LDADD)
+# See vdir_LDADD below
+wc_LDADD = $(LDADD)
+who_LDADD = $(LDADD)
+whoami_LDADD = $(LDADD)
+yes_LDADD = $(LDADD)
+
+# Synonyms. Recall that Automake transliterates '[' to '_'.
+__LDADD = $(test_LDADD)
+dir_LDADD = $(ls_LDADD)
+vdir_LDADD = $(ls_LDADD)
+
+# Shared files
+copy_LDADD =
+cp_LDADD += $(copy_LDADD)
+ginstall_LDADD += $(copy_LDADD)
+mv_LDADD += $(copy_LDADD)
+
+remove_LDADD =
+mv_LDADD += $(remove_LDADD)
+rm_LDADD += $(remove_LDADD)
+
+# for eaccess, euidaccess
+copy_LDADD += $(LIB_EACCESS)
+remove_LDADD += $(LIB_EACCESS)
+test_LDADD += $(LIB_EACCESS)
+
+# for selinux use
+chcon_LDADD += $(LIB_SELINUX)
+copy_LDADD += $(LIB_SELINUX)
+ginstall_LDADD += $(LIB_SELINUX)
+id_LDADD += $(LIB_SELINUX)
+ls_LDADD += $(LIB_SELINUX)
+mkdir_LDADD += $(LIB_SELINUX)
+mkfifo_LDADD += $(LIB_SELINUX)
+mknod_LDADD += $(LIB_SELINUX)
+runcon_LDADD += $(LIB_SELINUX)
+stat_LDADD += $(LIB_SELINUX)
+
+# for gettime, settime, utimecmp, utimens
+copy_LDADD += $(LIB_CLOCK_GETTIME)
+date_LDADD += $(LIB_CLOCK_GETTIME)
+ginstall_LDADD += $(LIB_CLOCK_GETTIME)
+ls_LDADD += $(LIB_CLOCK_GETTIME)
+pr_LDADD += $(LIB_CLOCK_GETTIME)
+touch_LDADD += $(LIB_CLOCK_GETTIME)
+
+# for gethrxtime, randint, randread, gen_tempname
+dd_LDADD += $(LIB_GETHRXTIME)
+mktemp_LDADD += $(LIB_GETHRXTIME)
+shred_LDADD += $(LIB_GETHRXTIME)
+shuf_LDADD += $(LIB_GETHRXTIME)
+sort_LDADD += $(LIB_GETHRXTIME)
+
+# for cap_get_file
+ls_LDADD += $(LIB_CAP)
+
+# for fdatasync
+dd_LDADD += $(LIB_FDATASYNC)
+shred_LDADD += $(LIB_FDATASYNC)
+
+# for strtod, strtold
+printf_LDADD += $(POW_LIB)
+seq_LDADD += $(POW_LIB)
+sleep_LDADD += $(POW_LIB)
+sort_LDADD += $(POW_LIB)
+tail_LDADD += $(POW_LIB)
+uptime_LDADD += $(POW_LIB)
+
+# for xnanosleep
+sleep_LDADD += $(LIB_NANOSLEEP)
+tail_LDADD += $(LIB_NANOSLEEP)
# for various GMP functions
-factor_LDADD = $(LDADD) $(LIB_GMP)
+expr_LDADD += $(LIB_GMP)
+factor_LDADD += $(LIB_GMP)
-sleep_LDADD = $(nanosec_libs)
-tail_LDADD = $(nanosec_libs)
+# for getloadavg
+uptime_LDADD += $(GETLOADAVG_LIBS)
-# If necessary, add -lm to resolve use of pow in lib/strtod.c.
-uptime_LDADD = $(LDADD) $(POW_LIB) $(GETLOADAVG_LIBS)
+# for crypt
+su_LDADD += $(LIB_CRYPT)
-su_LDADD = $(LDADD) $(LIB_CRYPT)
-
-dir_LDADD += $(LIB_ACL)
+# for various ACL functions
+copy_LDADD += $(LIB_ACL)
ls_LDADD += $(LIB_ACL)
-vdir_LDADD += $(LIB_ACL)
-cp_LDADD += $(LIB_ACL) $(LIB_XATTR)
-mv_LDADD += $(LIB_ACL) $(LIB_XATTR)
-ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR)
-stat_LDADD = $(LDADD) $(LIB_SELINUX)
+# for various xattr functions
+copy_LDADD += $(LIB_XATTR)
-# Append $(LIBICONV) to each program that uses proper_name_utf8.
+# for print_unicode_char, proper_name_utf8
cat_LDADD += $(LIBICONV)
cp_LDADD += $(LIBICONV)
df_LDADD += $(LIBICONV)
du_LDADD += $(LIBICONV)
getlimits_LDADD += $(LIBICONV)
+printf_LDADD += $(LIBICONV)
ptx_LDADD += $(LIBICONV)
split_LDADD += $(LIBICONV)
stdbuf_LDADD += $(LIBICONV)
timeout_LDADD += $(LIBICONV)
truncate_LDADD += $(LIBICONV)
-# programs that use getaddrinfo (e.g., via canon_host)
-pinky_LDADD = $(LDADD) $(GETADDRINFO_LIB)
-who_LDADD = $(LDADD) $(GETADDRINFO_LIB)
+# for canon_host
+pinky_LDADD += $(GETADDRINFO_LIB)
+who_LDADD += $(GETADDRINFO_LIB)
+
+# for gethostname, uname
+hostname_LDADD += $(GETHOSTNAME_LIB)
+uname_LDADD += $(GETHOSTNAME_LIB)
$(PROGRAMS): ../lib/libcoreutils.a
@@ -330,6 +536,61 @@ wheel.h: wheel-gen.pl Makefile.am
# Tell automake to exempt then from that installcheck test.
AM_INSTALLCHECK_STD_OPTIONS_EXEMPT = false test
+# Compare fs.h with the list of file system names/magic-numbers in the
+# Linux statfs man page. This target prints any new name/number pairs.
+.PHONY: fs-magic-compare
+fs-magic-compare: fs-magic fs-kernel-magic fs-def
+ join -v1 -t@ fs-magic fs-def
+ join -v1 -t@ fs-kernel-magic fs-def
+
+CLEANFILES += fs-def
+fs-def: fs.h
+ grep '^# *define ' $< > $@-t && mv $@-t $@
+
+CLEANFILES += fs-magic
+fs-magic: Makefile
+ man statfs \
+ |perl -ne '/File system types:/.../Nobody kno/ and print' \
+ |grep 0x | perl -p \
+ -e 's/MINIX_SUPER_MAGIC\b/MINIX/;' \
+ -e 's/MINIX_SUPER_MAGIC2\b/MINIX_30/;' \
+ -e 's/MINIX2_SUPER_MAGIC\b/MINIX_V2/;' \
+ -e 's/MINIX2_SUPER_MAGIC2\b/MINIX_V2_30/;' \
+ -e 's/CIFS_MAGIC_NUMBER/CIFS/;' \
+ -e 's/(_SUPER)?_MAGIC//;' \
+ -e 's/\s+0x(\S+)/" 0x" . uc $$1/e;' \
+ -e 's/^\s+//;' \
+ -e 's/^_(XIAFS)/$$1/;' \
+ -e 's/^USBDEVICE/USBDEVFS/;' \
+ -e 's/NTFS_SB/NTFS/;' \
+ -e 's/^/# define S_MAGIC_/;' \
+ -e 's,\s*/\* .*? \*/,,;' \
+ | grep -Ev 'S_MAGIC_EXT[34]|STACK_END' \
+ | LC_ALL=C sort \
+ > $@-t && mv $@-t $@
+
+CLEANFILES += fs-kernel-magic
+fs-kernel-magic: Makefile
+ perl -ne '/^#define.*0x/ and print' /usr/include/linux/magic.h \
+ | perl -p \
+ -e 's/MINIX_SUPER_MAGIC\b/MINIX/;' \
+ -e 's/MINIX_SUPER_MAGIC2\b/MINIX_30/;' \
+ -e 's/MINIX2_SUPER_MAGIC\b/MINIX_V2/;' \
+ -e 's/MINIX2_SUPER_MAGIC2\b/MINIX_V2_30/;' \
+ -e 's/MINIX3_SUPER_MAGIC\b/MINIX_V3/;' \
+ -e 's/(_SUPER)?_MAGIC//;' \
+ -e 's/\s+0x(\S+)/" 0x" . uc $$1/e;' \
+ -e 's/(\s+0x)(\X{3})\b/$${1}0$$2/;' \
+ -e 's/(\s+0x)(\X{6})\b/$${1}00$$2/;' \
+ -e 's/(\s+0x)(\X{7})\b/$${1}0$$2/;' \
+ -e 's/^#define\s+//;' \
+ -e 's/^USBDEVICE/USBDEVFS/;' \
+ -e 's/^/# define S_MAGIC_/;' \
+ -e 's,\s*/\* .*? \*/,,;' \
+ | grep -Ev 'S_MAGIC_EXT[34]|STACK_END' \
+ | LC_ALL=C sort \
+ > $@-t && mv $@-t $@
+
BUILT_SOURCES += fs.h
fs.h: stat.c extract-magic
$(AM_V_GEN)rm -f $@
diff --git a/src/base64.c b/src/base64.c
index c7cf034da..0bca87ce4 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -81,7 +81,7 @@ When decoding, the input may contain newlines in addition to the bytes of\n\
the formal base64 alphabet. Use --ignore-garbage to attempt to recover\n\
from any other non-alphabet bytes in the encoded stream.\n"),
stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
diff --git a/src/basename.c b/src/basename.c
index 4300d4983..3e6d93233 100644
--- a/src/basename.c
+++ b/src/basename.c
@@ -66,7 +66,7 @@ Examples:\n\
%s include/stdio.h .h Output \"stdio\".\n\
"),
program_name, program_name);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/cat.c b/src/cat.c
index 41b2637f2..9008957b7 100644
--- a/src/cat.c
+++ b/src/cat.c
@@ -119,7 +119,7 @@ Examples:\n\
%s Copy standard input to standard output.\n\
"),
program_name, program_name);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -388,7 +388,7 @@ cat (
/* Are line numbers to be written at empty lines (-n)? */
- if (number & !number_nonblank)
+ if (number && !number_nonblank)
{
next_line_num ();
bpout = stpcpy (bpout, line_num_print);
@@ -657,7 +657,7 @@ main (int argc, char **argv)
#endif
}
- if (! (number | show_ends | squeeze_blank))
+ if (! (number || show_ends || squeeze_blank))
{
file_open_mode |= O_BINARY;
if (O_BINARY && ! isatty (STDOUT_FILENO))
@@ -719,8 +719,8 @@ main (int argc, char **argv)
/* Select which version of `cat' to use. If any format-oriented
options were given use `cat'; otherwise use `simple_cat'. */
- if (! (number | show_ends | show_nonprinting
- | show_tabs | squeeze_blank))
+ if (! (number || show_ends || show_nonprinting
+ || show_tabs || squeeze_blank))
{
insize = MAX (insize, outsize);
inbuf = xmalloc (insize + page_size - 1);
diff --git a/src/chcon.c b/src/chcon.c
index 7e8250d3d..fbfdb4d29 100644
--- a/src/chcon.c
+++ b/src/chcon.c
@@ -380,7 +380,7 @@ one takes effect.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -549,7 +549,7 @@ main (int argc, char **argv)
usage (1);
}
- if (recurse & preserve_root)
+ if (recurse && preserve_root)
{
static struct dev_ino dev_ino_buf;
root_dev_ino = get_root_dev_ino (&dev_ino_buf);
diff --git a/src/chgrp.c b/src/chgrp.c
index 0102ef098..b9e3f4387 100644
--- a/src/chgrp.c
+++ b/src/chgrp.c
@@ -158,7 +158,7 @@ Examples:\n\
%s -hR staff /u Change the group of /u and subfiles to \"staff\".\n\
"),
program_name, program_name);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -293,7 +293,7 @@ main (int argc, char **argv)
gid = parse_group (group_name);
}
- if (chopt.recurse & preserve_root)
+ if (chopt.recurse && preserve_root)
{
static struct dev_ino dev_ino_buf;
chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
diff --git a/src/chmod.c b/src/chmod.c
index 282eadaff..da350032f 100644
--- a/src/chmod.c
+++ b/src/chmod.c
@@ -279,7 +279,7 @@ process_file (FTS *fts, FTSENT *ent)
}
}
- if (chmod_succeeded & diagnose_surprises)
+ if (chmod_succeeded && diagnose_surprises)
{
mode_t naively_expected_mode =
mode_adjust (old_mode, S_ISDIR (old_mode) != 0, 0, change, NULL);
@@ -379,7 +379,7 @@ Change the mode of each FILE to MODE.\n\
\n\
Each MODE is of the form `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -523,7 +523,7 @@ main (int argc, char **argv)
umask_value = umask (0);
}
- if (recurse & preserve_root)
+ if (recurse && preserve_root)
{
static struct dev_ino dev_ino_buf;
root_dev_ino = get_root_dev_ino (&dev_ino_buf);
diff --git a/src/chown-core.c b/src/chown-core.c
index 705a29bd3..e7dacf68c 100644
--- a/src/chown-core.c
+++ b/src/chown-core.c
@@ -440,7 +440,7 @@ change_file_owner (FTS *fts, FTSENT *ent,
if (chopt->verbosity != V_off)
{
bool changed =
- ((do_chown & ok & symlink_changed)
+ ((do_chown && ok && symlink_changed)
&& ! ((uid == (uid_t) -1 || uid == file_stats->st_uid)
&& (gid == (gid_t) -1 || gid == file_stats->st_gid)));
diff --git a/src/chown.c b/src/chown.c
index 35488d90e..4b7598653 100644
--- a/src/chown.c
+++ b/src/chown.c
@@ -153,7 +153,7 @@ Examples:\n\
%s -hR root /u Change the owner of /u and subfiles to \"root\".\n\
"),
program_name, program_name, program_name);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -317,7 +317,7 @@ main (int argc, char **argv)
optind++;
}
- if (chopt.recurse & preserve_root)
+ if (chopt.recurse && preserve_root)
{
static struct dev_ino dev_ino_buf;
chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
diff --git a/src/chroot.c b/src/chroot.c
index 3fa26f8da..9269f1b0e 100644
--- a/src/chroot.c
+++ b/src/chroot.c
@@ -91,7 +91,7 @@ set_additional_groups (char const *groups)
}
if (n_gids == n_gids_allocated)
- gids = x2nrealloc (gids, &n_gids_allocated, sizeof *gids);
+ gids = X2NREALLOC (gids, &n_gids_allocated);
gids[n_gids++] = value;
}
@@ -142,7 +142,7 @@ Run COMMAND with root directory set to NEWROOT.\n\
\n\
If no command is given, run ``${SHELL} -i'' (default: /bin/sh).\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/cksum.c b/src/cksum.c
index 25cdb4789..f847d0ebe 100644
--- a/src/cksum.c
+++ b/src/cksum.c
@@ -269,7 +269,7 @@ Print CRC checksum and byte counts of each FILE.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/comm.c b/src/comm.c
index 63b6b0c26..e9a66b49c 100644
--- a/src/comm.c
+++ b/src/comm.c
@@ -23,6 +23,7 @@
#include "system.h"
#include "linebuffer.h"
#include "error.h"
+#include "hard-locale.h"
#include "quote.h"
#include "stdio--.h"
#include "memcmp2.h"
@@ -140,7 +141,7 @@ Examples:\n\
%s -3 file1 file2 Print lines in file1 not in file2, and vice versa.\n\
"),
program_name, program_name);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/copy.c b/src/copy.c
index 178a6404b..0a8b0e41d 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -123,17 +123,12 @@ static char const *top_level_dst_name;
static inline int
utimens_symlink (char const *file, struct timespec const *timespec)
{
- int err = 0;
-
-#if HAVE_UTIMENSAT
- err = utimensat (AT_FDCWD, file, timespec, AT_SYMLINK_NOFOLLOW);
+ int err = lutimens (file, timespec);
/* When configuring on a system with new headers and libraries, and
running on one with a kernel that is old enough to lack the syscall,
utimensat fails with ENOSYS. Ignore that. */
if (err && errno == ENOSYS)
err = 0;
-#endif
-
return err;
}
@@ -360,11 +355,11 @@ set_owner (const struct cp_options *x, char const *dst_name, int dest_desc,
group. Avoid the window by first changing to a restrictive
temporary mode if necessary. */
- if (!new_dst && (x->preserve_mode | x->move_mode | x->set_mode))
+ if (!new_dst && (x->preserve_mode || x->move_mode || x->set_mode))
{
mode_t old_mode = dst_sb->st_mode;
mode_t new_mode =
- (x->preserve_mode | x->move_mode ? src_sb->st_mode : x->mode);
+ (x->preserve_mode || x->move_mode ? src_sb->st_mode : x->mode);
mode_t restrictive_temp_mode = old_mode & new_mode & S_IRWXU;
if ((USE_ACL
@@ -834,6 +829,24 @@ copy_reg (char const *src_name, char const *dst_name,
}
}
+ /* To allow copying xattrs on read-only files, temporarily chmod u+rw.
+ This workaround is required as an inode permission check is done
+ by xattr_permission() in fs/xattr.c of the GNU/Linux kernel tree. */
+ if (x->preserve_xattr)
+ {
+ bool access_changed = false;
+
+ if (!(sb.st_mode & S_IWUSR) && geteuid() != 0)
+ access_changed = fchmod_or_lchmod (dest_desc, dst_name, 0600) == 0;
+
+ if (!copy_attr_by_fd (src_name, source_desc, dst_name, dest_desc, x)
+ && x->require_preserve_xattr)
+ return_val = false;
+
+ if (access_changed)
+ fchmod_or_lchmod (dest_desc, dst_name, dst_mode & ~omitted_permissions);
+ }
+
if (x->preserve_ownership && ! SAME_OWNER_AND_GROUP (*src_sb, sb))
{
switch (set_owner (x, dst_name, dest_desc, src_sb, *new_dst, &sb))
@@ -850,11 +863,6 @@ copy_reg (char const *src_name, char const *dst_name,
set_author (dst_name, dest_desc, src_sb);
- if (x->preserve_xattr && ! copy_attr_by_fd (src_name, source_desc,
- dst_name, dest_desc, x)
- && x->require_preserve_xattr)
- return_val = false;
-
if (x->preserve_mode || x->move_mode)
{
if (copy_acl (src_name, source_desc, dst_name, dest_desc, src_mode) != 0
@@ -1671,7 +1679,9 @@ copy_internal (char const *src_name, char const *dst_name,
}
else
{
- bool link_failed = (link (earlier_file, dst_name) != 0);
+ /* We want to guarantee that symlinks are not followed. */
+ bool link_failed = (linkat (AT_FDCWD, earlier_file, AT_FDCWD,
+ dst_name, 0) != 0);
/* If the link failed because of an existing destination,
remove that file and then call link again. */
@@ -1684,7 +1694,8 @@ copy_internal (char const *src_name, char const *dst_name,
}
if (x->verbose)
printf (_("removed %s\n"), quote (dst_name));
- link_failed = (link (earlier_file, dst_name) != 0);
+ link_failed = (linkat (AT_FDCWD, earlier_file, AT_FDCWD,
+ dst_name, 0) != 0);
}
if (link_failed)
@@ -1974,25 +1985,15 @@ copy_internal (char const *src_name, char const *dst_name,
}
}
- /* POSIX 2008 states that it is implementation-defined whether
- link() on a symlink creates a hard-link to the symlink, or only
- to the referent (effectively dereferencing the symlink) (POSIX
- 2001 required the latter behavior, although many systems provided
- the former). Yet cp, invoked with `--link --no-dereference',
- should not follow the link. We can approximate the desired
- behavior by skipping this hard-link creating block and instead
- copying the symlink, via the `S_ISLNK'- copying code below.
- LINK_FOLLOWS_SYMLINKS is tri-state; if it is -1, we don't know
- how link() behaves, so we use the fallback case for safety.
-
- FIXME - use a gnulib linkat emulation for more fine-tuned
- emulation, particularly when LINK_FOLLOWS_SYMLINKS is -1. */
+ /* cp, invoked with `--link --no-dereference', should not follow the
+ link; we guarantee this with gnulib's linkat module (on systems
+ where link(2) follows the link, gnulib creates a symlink with
+ identical contents, which is good enough for our purposes). */
else if (x->hard_link
- && (!LINK_FOLLOWS_SYMLINKS
- || !S_ISLNK (src_mode)
- || x->dereference != DEREF_NEVER))
+ && (!S_ISLNK (src_mode)
+ || x->dereference != DEREF_NEVER))
{
- if (link (src_name, dst_name))
+ if (linkat (AT_FDCWD, src_name, AT_FDCWD, dst_name, 0))
{
error (0, errno, _("cannot create link %s"), quote (dst_name));
goto un_backup;
diff --git a/src/cp.c b/src/cp.c
index 2ba1dbf09..f3fc1aae7 100644
--- a/src/cp.c
+++ b/src/cp.c
@@ -257,7 +257,7 @@ As a special case, cp makes a backup of SOURCE when the force and backup\n\
options are given and SOURCE and DEST are the same name for an existing,\n\
regular file.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -1089,7 +1089,7 @@ main (int argc, char **argv)
}
}
- if (x.hard_link & x.symbolic_link)
+ if (x.hard_link && x.symbolic_link)
{
error (0, 0, _("cannot make both hard and symbolic links"));
usage (EXIT_FAILURE);
@@ -1130,7 +1130,7 @@ main (int argc, char **argv)
/* If --force (-f) was specified and we're in link-creation mode,
first remove any existing destination file. */
- if (x.unlink_dest_after_failed_open & (x.hard_link | x.symbolic_link))
+ if (x.unlink_dest_after_failed_open && (x.hard_link || x.symbolic_link))
x.unlink_dest_before_opening = true;
if (x.preserve_security_context)
diff --git a/src/csplit.c b/src/csplit.c
index ba93d2b59..8cc06b6ee 100644
--- a/src/csplit.c
+++ b/src/csplit.c
@@ -1481,7 +1481,7 @@ Read standard input if FILE is -. Each PATTERN may be:\n\
\n\
A line OFFSET is a required `+' or `-' followed by a positive integer.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/cut.c b/src/cut.c
index 448e7ed7a..119fb57bc 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -235,7 +235,7 @@ Each range is one of:\n\
\n\
With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/date.c b/src/date.c
index cbc53e6a5..75cf092b7 100644
--- a/src/date.c
+++ b/src/date.c
@@ -236,7 +236,7 @@ then an optional modifier, which is either\n\
E to use the locale's alternate representations if available, or\n\
O to use the locale's alternate numeric symbols if available.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/dd.c b/src/dd.c
index 04665f98f..c7fe5631e 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -575,7 +575,7 @@ Options are:\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -769,7 +769,7 @@ install_signal_handlers (void)
static void
process_signals (void)
{
- while (interrupt_signal | info_signal_count)
+ while (interrupt_signal || info_signal_count)
{
int interrupt;
int infos;
@@ -1785,10 +1785,11 @@ dd_copy (void)
output_char (space_character);
}
- if ((conversions_mask & C_UNBLOCK) && col == conversion_blocksize)
- /* Add a final '\n' if there are exactly `conversion_blocksize'
- characters in the final record. */
- output_char (newline_character);
+ if (col && (conversions_mask & C_UNBLOCK))
+ {
+ /* If there was any output, add a final '\n'. */
+ output_char (newline_character);
+ }
/* Write out the last block. */
if (oc != 0)
diff --git a/src/df.c b/src/df.c
index 86fd0e32e..411e61a48 100644
--- a/src/df.c
+++ b/src/df.c
@@ -24,7 +24,6 @@
#include <getopt.h>
#include "system.h"
-#include "canonicalize.h"
#include "error.h"
#include "fsusage.h"
#include "human.h"
@@ -333,10 +332,10 @@ show_dev (char const *disk, char const *mount_point,
bool negate_used;
double pct = -1;
- if (me_remote & show_local_fs)
+ if (me_remote && show_local_fs)
return;
- if (me_dummy & !show_all_fs & !show_listed_fs)
+ if (me_dummy && !show_all_fs && !show_listed_fs)
return;
if (!selected_fstype (fstype) || excluded_fstype (fstype))
@@ -431,7 +430,7 @@ show_dev (char const *disk, char const *mount_point,
total = fsu.fsu_blocks;
available = fsu.fsu_bavail;
negate_available = (fsu.fsu_bavail_top_bit_set
- & known_value (available));
+ && known_value (available));
available_to_root = fsu.fsu_bfree;
if (known_value (total))
@@ -833,11 +832,9 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\n\
-SIZE may be (or may be an integer optionally followed by) one of following:\n\
-kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
-"), stdout);
- emit_bug_reporting_address ();
+ emit_blocksize_note ("DF");
+ emit_size_note ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/dircolors.c b/src/dircolors.c
index b72415592..f28487ea3 100644
--- a/src/dircolors.c
+++ b/src/dircolors.c
@@ -112,7 +112,7 @@ If FILE is specified, read it to determine which colors to use for which\n\
file types and extensions. Otherwise, a precompiled database is used.\n\
For details on the format of these files, run `dircolors --print-database'.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
diff --git a/src/dircolors.hin b/src/dircolors.hin
index 91ddcb65a..1818634a1 100644
--- a/src/dircolors.hin
+++ b/src/dircolors.hin
@@ -116,6 +116,7 @@ EXEC 01;32
.Z 01;31
.dz 01;31
.gz 01;31
+.lz 01;31
.xz 01;31
.bz2 01;31
.bz 01;31
@@ -175,6 +176,8 @@ EXEC 01;32
.xcf 01;35
.xwd 01;35
.yuv 01;35
+.cgm 01;35
+.emf 01;35
# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
.axv 01;35
diff --git a/src/dirname.c b/src/dirname.c
index 53d0bdc7d..f47233415 100644
--- a/src/dirname.c
+++ b/src/dirname.c
@@ -61,7 +61,7 @@ Examples:\n\
%s stdio.h Output \".\".\n\
"),
program_name, program_name);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/du.c b/src/du.c
index 9da901a62..9831a1788 100644
--- a/src/du.c
+++ b/src/du.c
@@ -330,11 +330,9 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\n\
-SIZE may be (or may be an integer optionally followed by) one of following:\n\
-kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
-"), stdout);
- emit_bug_reporting_address ();
+ emit_blocksize_note ("DU");
+ emit_size_note ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -845,7 +843,7 @@ main (int argc, char **argv)
if (!ok)
usage (EXIT_FAILURE);
- if (opt_all & opt_summarize_only)
+ if (opt_all && opt_summarize_only)
{
error (0, 0, _("cannot both summarize and show all entries"));
usage (EXIT_FAILURE);
diff --git a/src/echo.c b/src/echo.c
index 210352ca7..90b978646 100644
--- a/src/echo.c
+++ b/src/echo.c
@@ -77,7 +77,7 @@ If -e is in effect, the following sequences are recognized:\n\
\\v vertical tab\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/env.c b/src/env.c
index c22981ba3..90edc5a33 100644
--- a/src/env.c
+++ b/src/env.c
@@ -125,7 +125,7 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\
\n\
A mere - implies -i. If no COMMAND, print the resulting environment.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/expand.c b/src/expand.c
index c8648335a..afc574b3c 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -121,7 +121,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -344,7 +344,7 @@ expand (void)
error (EXIT_FAILURE, 0, _("input line is too long"));
}
- convert &= convert_entire_line | !! isblank (c);
+ convert &= convert_entire_line || !! isblank (c);
}
if (c < 0)
diff --git a/src/expr.c b/src/expr.c
index 11bf7ed47..851f72892 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -55,7 +55,7 @@ static void integer_overflow (char) ATTRIBUTE_NORETURN;
#else
/* Approximate gmp.h well enough for expr.c's purposes. */
typedef intmax_t mpz_t[1];
-static void mpz_clear (mpz_t z) {}
+static void mpz_clear (mpz_t z) { (void) z; }
static void mpz_init_set_ui (mpz_t z, unsigned long int i) { z[0] = i; }
static int
mpz_init_set_str (mpz_t z, char *s, int base)
@@ -116,6 +116,7 @@ mpz_tdiv_r (mpz_t r, mpz_t a0, mpz_t b0)
static char *
mpz_get_str (char const *str, int base, mpz_t z)
{
+ (void) str; (void) base;
char buf[INT_BUFSIZE_BOUND (intmax_t)];
return xstrdup (imaxtostr (z[0], buf));
}
@@ -137,6 +138,7 @@ mpz_get_ui (mpz_t z)
static int
mpz_out_str (FILE *stream, int base, mpz_t z)
{
+ (void) base;
char buf[INT_BUFSIZE_BOUND (intmax_t)];
return fputs (imaxtostr (z[0], buf), stream) != EOF;
}
@@ -265,7 +267,7 @@ Pattern matches return the string matched between \\( and \\) or null; if\n\
Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION is null\n\
or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -923,7 +925,7 @@ eval1 (bool evaluate)
{
if (nextarg ("&"))
{
- r = eval2 (evaluate & ~ null (l));
+ r = eval2 (evaluate && !null (l));
if (null (l) || null (r))
{
freev (l);
@@ -954,7 +956,7 @@ eval (bool evaluate)
{
if (nextarg ("|"))
{
- r = eval1 (evaluate & null (l));
+ r = eval1 (evaluate && null (l));
if (null (l))
{
freev (l);
diff --git a/src/factor.c b/src/factor.c
index 59fe1f45f..38c9a115b 100644
--- a/src/factor.c
+++ b/src/factor.c
@@ -26,7 +26,7 @@
#include <stdio.h>
#include <sys/types.h>
#if HAVE_GMP
-#include <gmp.h>
+# include <gmp.h>
#endif
#include <assert.h>
@@ -67,7 +67,7 @@ static void
emit_factor (mpz_t n)
{
if (nfactors_found == nfactors_allocated)
- factor = x2nrealloc (factor, &nfactors_allocated, sizeof *factor);
+ factor = X2NREALLOC (factor, &nfactors_allocated);
mpz_init (factor[nfactors_found]);
mpz_set (factor[nfactors_found], n);
++nfactors_found;
@@ -502,7 +502,7 @@ are specified on the command line, read them from standard input.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/fmt.c b/src/fmt.c
index c12072c58..81a708e19 100644
--- a/src/fmt.c
+++ b/src/fmt.c
@@ -293,7 +293,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
\n\
With no FILE, or when FILE is -, read standard input.\n"),
stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/fold.c b/src/fold.c
index 52322657a..df771711c 100644
--- a/src/fold.c
+++ b/src/fold.c
@@ -82,7 +82,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/getlimits.c b/src/getlimits.c
index 82cd34531..a4e1d9b10 100644
--- a/src/getlimits.c
+++ b/src/getlimits.c
@@ -73,7 +73,7 @@ Output platform dependent limits in a format useful for shell scripts.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/groups.c b/src/groups.c
index 27e872406..f522ac4c4 100644
--- a/src/groups.c
+++ b/src/groups.c
@@ -58,7 +58,7 @@ the current process (which may differ if the groups database has changed).\n"),
stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/head.c b/src/head.c
index f01438809..9080168bc 100644
--- a/src/head.c
+++ b/src/head.c
@@ -138,7 +138,7 @@ K may have a multiplier suffix:\n\
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\
GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/hostid.c b/src/hostid.c
index 7c93f2e76..2b606a7ca 100644
--- a/src/hostid.c
+++ b/src/hostid.c
@@ -48,7 +48,7 @@ Print the numeric identifier (in hexadecimal) for the current host.\n\
"), program_name);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/hostname.c b/src/hostname.c
index 110014b3f..9726bd5f1 100644
--- a/src/hostname.c
+++ b/src/hostname.c
@@ -63,7 +63,7 @@ Print or set the hostname of the current system.\n\
program_name, program_name);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/id.c b/src/id.c
index b28643b18..601e77077 100644
--- a/src/id.c
+++ b/src/id.c
@@ -98,7 +98,7 @@ or (when USERNAME omitted) for the current user.\n\
\n\
Without any OPTION, print some useful set of identified information.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -187,7 +187,7 @@ main (int argc, char **argv)
if (just_user + just_group + just_group_list + just_context > 1)
error (EXIT_FAILURE, 0, _("cannot print \"only\" of more than one choice"));
- if (just_user + just_group + just_group_list == 0 && (use_real | use_name))
+ if (just_user + just_group + just_group_list == 0 && (use_real || use_name))
error (EXIT_FAILURE, 0,
_("cannot print only names or real IDs in default format"));
@@ -328,6 +328,9 @@ print_full_info (const char *username)
free (groups);
}
#endif /* HAVE_GETGROUPS */
- if (context != NULL)
+
+ /* POSIX mandates the precise output format, and that it not include
+ any context=... part, so skip that if POSIXLY_CORRECT is set. */
+ if (context != NULL && ! getenv ("POSIXLY_CORRECT"))
printf (_(" context=%s"), context);
}
diff --git a/src/install.c b/src/install.c
index fafa21a3c..ca0309654 100644
--- a/src/install.c
+++ b/src/install.c
@@ -563,7 +563,7 @@ main (int argc, char **argv)
}
/* Check for invalid combinations of arguments. */
- if (dir_arg & strip_files)
+ if (dir_arg && strip_files)
error (EXIT_FAILURE, 0,
_("the strip option may not be used when installing a directory"));
if (dir_arg && target_directory)
@@ -1005,7 +1005,7 @@ the VERSION_CONTROL environment variable. Here are the values:\n\
existing, nil numbered if numbered backups exist, simple otherwise\n\
simple, never always make simple backups\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/join.c b/src/join.c
index 73e1f37bb..d734a91ea 100644
--- a/src/join.c
+++ b/src/join.c
@@ -24,6 +24,7 @@
#include "system.h"
#include "error.h"
+#include "hard-locale.h"
#include "linebuffer.h"
#include "memcasecmp.h"
#include "quote.h"
@@ -208,7 +209,7 @@ Note, comparisons honor the rules specified by `LC_COLLATE'.\n\
If the input is not sorted and some lines cannot be joined, a\n\
warning message will be given.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/kill.c b/src/kill.c
index 3429cb19d..bff8c6c14 100644
--- a/src/kill.c
+++ b/src/kill.c
@@ -111,7 +111,7 @@ or the exit status of a process terminated by a signal.\n\
PID is an integer; if negative it identifies a process group.\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/link.c b/src/link.c
index ead3ac2f5..9e49a755b 100644
--- a/src/link.c
+++ b/src/link.c
@@ -51,7 +51,7 @@ Usage: %s FILE1 FILE2\n\
stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/ln.c b/src/ln.c
index 6a1dc3207..4f75c1919 100644
--- a/src/ln.c
+++ b/src/ln.c
@@ -39,26 +39,15 @@
proper_name ("Mike Parker"), \
proper_name ("David MacKenzie")
-/* In being careful not even to try to make hard links to directories,
- we have to know whether link(2) follows symlinks. If it does, then
- we have to *stat* the `source' to see if the resulting link would be
- to a directory. Otherwise, we have to use *lstat* so that we allow
- users to make hard links to symlinks-that-point-to-directories. */
-
-#if LINK_FOLLOWS_SYMLINKS
-# define STAT_LIKE_LINK(File, Stat_buf) \
- stat (File, Stat_buf)
-#else
-# define STAT_LIKE_LINK(File, Stat_buf) \
- lstat (File, Stat_buf)
-#endif
-
/* FIXME: document */
static enum backup_type backup_type;
/* If true, make symbolic links; otherwise, make hard links. */
static bool symbolic_link;
+/* If true, hard links are logical rather than physical. */
+static bool logical = !!LINK_FOLLOWS_SYMLINKS;
+
/* If true, ask the user before removing existing files. */
static bool interactive;
@@ -71,7 +60,7 @@ static bool verbose;
/* If true, allow the superuser to *attempt* to make hard links
to directories. However, it appears that this option is not useful
in practice, since even the superuser is prohibited from hard-linking
- directories on most (all?) existing systems. */
+ directories on most existing systems (Solaris being an exception). */
static bool hard_dir_link;
/* If nonzero, and the specified destination is a symbolic link to a
@@ -99,6 +88,8 @@ static struct option const long_options[] =
{"interactive", no_argument, NULL, 'i'},
{"suffix", required_argument, NULL, 'S'},
{"target-directory", required_argument, NULL, 't'},
+ {"logical", no_argument, NULL, 'L'},
+ {"physical", no_argument, NULL, 'P'},
{"symbolic", no_argument, NULL, 's'},
{"verbose", no_argument, NULL, 'v'},
{GETOPT_HELP_OPTION_DECL},
@@ -143,18 +134,15 @@ do_link (const char *source, const char *dest)
bool source_is_dir = false;
bool ok;
- /* Use stat here instead of lstat.
- On SVR4, link does not follow symlinks, so this check disallows
- making hard links to symlinks that point to directories. Big deal.
- On other systems, link follows symlinks, so this check is right.
-
- FIXME - POSIX 2008 added the AT_SYMLINK_FOLLOW flag to linkat so
- that we can specify either behavior, via the new options -L
- (hard-link to symlinks) and -P (hard-link to the referent). Once
- gnulib has a decent implementation, we should use it here. */
if (!symbolic_link)
{
- if (STAT_LIKE_LINK (source, &source_stats) != 0)
+ /* Which stat to use depends on whether linkat will follow the
+ symlink. We can't use the shorter
+ (logical ? stat : lstat) (source, &source_stats)
+ since stat might be a function-like macro. */
+ if ((logical ? stat (source, &source_stats)
+ : lstat (source, &source_stats))
+ != 0)
{
error (0, errno, _("accessing %s"), quote (source));
return false;
@@ -258,7 +246,9 @@ do_link (const char *source, const char *dest)
}
}
- ok = ((symbolic_link ? symlink (source, dest) : link (source, dest))
+ ok = ((symbolic_link ? symlink (source, dest)
+ : linkat (AT_FDCWD, source, AT_FDCWD, dest,
+ logical ? AT_SYMLINK_FOLLOW : 0))
== 0);
/* If the attempt to create a link failed and we are removing or
@@ -289,7 +279,9 @@ do_link (const char *source, const char *dest)
return false;
}
- ok = ((symbolic_link ? symlink (source, dest) : link (source, dest))
+ ok = ((symbolic_link ? symlink (source, dest)
+ : linkat (AT_FDCWD, source, AT_FDCWD, dest,
+ logical ? AT_SYMLINK_FOLLOW : 0))
== 0);
}
@@ -370,9 +362,11 @@ Mandatory arguments to long options are mandatory for short options too.\n\
-f, --force remove existing destination files\n\
"), stdout);
fputs (_("\
+ -i, --interactive prompt whether to remove destinations\n\
+ -L, --logical make hard links to symbolic link references\n\
-n, --no-dereference treat destination that is a symlink to a\n\
directory as if it were a normal file\n\
- -i, --interactive prompt whether to remove destinations\n\
+ -P, --physical make hard links directly to symbolic links\n\
-s, --symbolic make symbolic links instead of hard links\n\
"), stdout);
fputs (_("\
@@ -391,13 +385,18 @@ The version control method may be selected via the --backup option or through\n\
the VERSION_CONTROL environment variable. Here are the values:\n\
\n\
"), stdout);
+ printf (_("\
+Using -s ignores -L and -P. Otherwise, the last option specified controls\n\
+behavior when the source is a symbolic link, defaulting to %s.\n\
+\n\
+"), LINK_FOLLOWS_SYMLINKS ? "-L" : "-P");
fputs (_("\
none, off never make backups (even if --backup is given)\n\
numbered, t make numbered backups\n\
existing, nil numbered if numbered backups exist, simple otherwise\n\
simple, never always make simple backups\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -430,7 +429,7 @@ main (int argc, char **argv)
symbolic_link = remove_existing_files = interactive = verbose
= hard_dir_link = false;
- while ((c = getopt_long (argc, argv, "bdfinst:vFS:T", long_options, NULL))
+ while ((c = getopt_long (argc, argv, "bdfinst:vFLPS:T", long_options, NULL))
!= -1)
{
switch (c)
@@ -452,9 +451,15 @@ main (int argc, char **argv)
remove_existing_files = false;
interactive = true;
break;
+ case 'L':
+ logical = true;
+ break;
case 'n':
dereference_dest_dir_symlinks = false;
break;
+ case 'P':
+ logical = false;
+ break;
case 's':
symbolic_link = true;
break;
diff --git a/src/logname.c b/src/logname.c
index 8abb535f0..0a739cc50 100644
--- a/src/logname.c
+++ b/src/logname.c
@@ -44,7 +44,7 @@ Print the name of the current user.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/ls.c b/src/ls.c
index 553090dc5..08fdf5fdc 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -93,6 +93,7 @@
#include "dev-ino.h"
#include "error.h"
#include "filenamecat.h"
+#include "hard-locale.h"
#include "hash.h"
#include "human.h"
#include "filemode.h"
@@ -323,7 +324,7 @@ static bool color_symlink_as_referent;
/* mode of appropriate file for colorization */
#define FILE_OR_LINK_MODE(File) \
- ((color_symlink_as_referent & (File)->linkok) \
+ ((color_symlink_as_referent && (File)->linkok) \
? (File)->linkmode : (File)->stat.st_mode)
@@ -1175,7 +1176,7 @@ stophandler (int sig)
static void
process_signals (void)
{
- while (interrupt_signal | stop_signal_count)
+ while (interrupt_signal || stop_signal_count)
{
int sig;
int stops;
@@ -2470,13 +2471,14 @@ print_dir (char const *name, char const *realname, bool command_line_arg)
error (0, 0, _("%s: not listing already-listed directory"),
quotearg_colon (name));
closedir (dirp);
+ set_exit_status (true);
return;
}
DEV_INO_PUSH (dir_stat.st_dev, dir_stat.st_ino);
}
- if (recursive | print_dir_name)
+ if (recursive || print_dir_name)
{
if (!first)
DIRED_PUTCHAR ('\n');
@@ -2800,17 +2802,6 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
: lgetfilecon (absolute_name, &f->scontext));
err = (attr_len < 0);
- /* Contrary to its documented API, getfilecon may return 0,
- yet set f->scontext to NULL (on at least Debian's libselinux1
- 2.0.15-2+b1), so work around that bug.
- FIXME: remove this work-around in 2011, or whenever affected
- versions of libselinux are long gone. */
- if (attr_len == 0)
- {
- err = 0;
- f->scontext = xstrdup ("unlabeled");
- }
-
if (err == 0)
have_selinux = ! STREQ ("unlabeled", f->scontext);
else
@@ -2884,7 +2875,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
f->filetype = symbolic_link;
else if (S_ISDIR (f->stat.st_mode))
{
- if (command_line_arg & !immediate_dirs)
+ if (command_line_arg && !immediate_dirs)
f->filetype = arg_directory;
else
f->filetype = directory;
@@ -3554,9 +3545,19 @@ format_group_width (gid_t g)
return format_user_or_group_width (numeric_ids ? NULL : getgroup (g), g);
}
+/* Return a pointer to a formatted version of F->stat.st_ino,
+ possibly using buffer, BUF, of length BUFLEN, which must be at least
+ INT_BUFSIZE_BOUND (uintmax_t) bytes. */
+static char *
+format_inode (char *buf, size_t buflen, const struct fileinfo *f)
+{
+ assert (INT_BUFSIZE_BOUND (uintmax_t) <= buflen);
+ return (f->stat_ok && f->stat.st_ino != NOT_AN_INODE_NUMBER
+ ? umaxtostr (f->stat.st_ino, buf)
+ : (char *) "?");
+}
/* Print information about F in long format. */
-
static void
print_long_format (const struct fileinfo *f)
{
@@ -3613,9 +3614,7 @@ print_long_format (const struct fileinfo *f)
{
char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
sprintf (p, "%*s ", inode_number_width,
- (f->stat.st_ino == NOT_AN_INODE_NUMBER
- ? "?"
- : umaxtostr (f->stat.st_ino, hbuf)));
+ format_inode (hbuf, sizeof hbuf, f));
/* Increment by strlen (p) here, rather than by inode_number_width + 1.
The latter is wrong when inode_number_width is zero. */
p += strlen (p);
@@ -3651,7 +3650,7 @@ print_long_format (const struct fileinfo *f)
DIRED_INDENT ();
- if (print_owner | print_group | print_author | print_scontext)
+ if (print_owner || print_group || print_author || print_scontext)
{
DIRED_FPUTS (buf, stdout, p - buf);
@@ -4002,12 +4001,13 @@ print_file_name_and_frills (const struct fileinfo *f, size_t start_col)
if (print_inode)
printf ("%*s ", format == with_commas ? 0 : inode_number_width,
- umaxtostr (f->stat.st_ino, buf));
+ format_inode (buf, sizeof buf, f));
if (print_block_size)
printf ("%*s ", format == with_commas ? 0 : block_size_width,
- human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
- ST_NBLOCKSIZE, output_block_size));
+ ! f->stat_ok ? "?"
+ : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
+ ST_NBLOCKSIZE, output_block_size));
if (print_scontext)
printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext);
@@ -4102,7 +4102,7 @@ print_color_indicator (const char *name, mode_t mode, int linkok,
bool stat_ok, enum filetype filetype,
nlink_t nlink)
{
- int type;
+ enum indicator_no type;
struct color_ext_type *ext; /* Color extension */
size_t len; /* Length of name */
@@ -4120,27 +4120,30 @@ print_color_indicator (const char *name, mode_t mode, int linkok,
if (S_ISREG (mode))
{
type = C_FILE;
- if ((mode & S_ISUID) != 0)
+
+ if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
type = C_SETUID;
- else if ((mode & S_ISGID) != 0)
+ else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
type = C_SETGID;
+ /* has_capability() called second for performance. */
else if (is_colored (C_CAP) && has_capability (name))
type = C_CAP;
- else if ((mode & S_IXUGO) != 0)
+ else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
type = C_EXEC;
- else if (is_colored (C_MULTIHARDLINK) && (1 < nlink))
+ else if ((1 < nlink) && is_colored (C_MULTIHARDLINK))
type = C_MULTIHARDLINK;
}
else if (S_ISDIR (mode))
{
- if ((mode & S_ISVTX) && (mode & S_IWOTH))
+ type = C_DIR;
+
+ if ((mode & S_ISVTX) && (mode & S_IWOTH)
+ && is_colored (C_STICKY_OTHER_WRITABLE))
type = C_STICKY_OTHER_WRITABLE;
- else if ((mode & S_IWOTH) != 0)
+ else if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
type = C_OTHER_WRITABLE;
- else if ((mode & S_ISVTX) != 0)
+ else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
type = C_STICKY;
- else
- type = C_DIR;
}
else if (S_ISLNK (mode))
type = ((!linkok && color_indicator[C_ORPHAN].string)
@@ -4221,9 +4224,10 @@ length_of_file_name_and_frills (const struct fileinfo *f)
if (print_block_size)
len += 1 + (format == with_commas
- ? strlen (human_readable (ST_NBLOCKS (f->stat), buf,
- human_output_opts, ST_NBLOCKSIZE,
- output_block_size))
+ ? strlen (! f->stat_ok ? "?"
+ : human_readable (ST_NBLOCKS (f->stat), buf,
+ human_output_opts, ST_NBLOCKSIZE,
+ output_block_size))
: block_size_width);
if (print_scontext)
@@ -4543,7 +4547,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
-b, --escape print octal escapes for nongraphic characters\n\
"), stdout);
fputs (_("\
- --block-size=SIZE use SIZE-byte blocks\n\
+ --block-size=SIZE use SIZE-byte blocks. See SIZE format below\n\
-B, --ignore-backups do not list implied entries ending with ~\n\
-c with -lt: sort by, and show, ctime (time of last\n\
modification of file status information)\n\
@@ -4552,8 +4556,8 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (_("\
-C list entries by columns\n\
- --color[=WHEN] control whether color is used to distinguish file\n\
- types. WHEN may be `never', `always', or `auto'\n\
+ --color[=WHEN] colorize the output. WHEN defaults to `always'\n\
+ or can be `never' or `auto'. More info below\n\
-d, --directory list directory entries instead of contents,\n\
and do not dereference symbolic links\n\
-D, --dired generate output designed for Emacs' dired mode\n\
@@ -4664,18 +4668,13 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\n\
-SIZE may be (or may be an integer optionally followed by) one of following:\n\
-kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
-"), stdout);
+ emit_size_note ();
fputs (_("\
\n\
-By default, color is not used to distinguish types of files. That is\n\
-equivalent to using --color=none. Using the --color option without the\n\
-optional WHEN argument is equivalent to using --color=always. With\n\
---color=auto, color codes are output only if standard output is connected\n\
-to a terminal (tty). The environment variable LS_COLORS can influence the\n\
-colors, and can be set easily by the dircolors command.\n\
+Using color to distinguish file types is disabled both by default and\n\
+with --color=never. With --color=auto, ls emits color codes only when\n\
+standard output is connected to a terminal. The LS_COLORS environment\n\
+variable can change the settings. Use the dircolors command to set it.\n\
"), stdout);
fputs (_("\
\n\
@@ -4684,7 +4683,7 @@ Exit status:\n\
1 if minor problems (e.g., cannot access subdirectory),\n\
2 if serious trouble (e.g., cannot access command-line argument).\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/md5sum.c b/src/md5sum.c
index c8e01efb8..aa2a144a7 100644
--- a/src/md5sum.c
+++ b/src/md5sum.c
@@ -195,7 +195,7 @@ should be a former output of this program. The default mode is to print\n\
a line with checksum, a character indicating type (`*' for binary, ` ' for\n\
text), and name for each FILE.\n"),
DIGEST_REFERENCE);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
@@ -251,11 +251,10 @@ static bool
split_3 (char *s, size_t s_len,
unsigned char **hex_digest, int *binary, char **file_name)
{
- size_t i;
bool escaped_filename = false;
size_t algo_name_len;
- i = 0;
+ size_t i = 0;
while (ISWHITE (s[i]))
++i;
@@ -263,11 +262,13 @@ split_3 (char *s, size_t s_len,
algo_name_len = strlen (DIGEST_TYPE_STRING);
if (strncmp (s + i, DIGEST_TYPE_STRING, algo_name_len) == 0)
{
- if (strncmp (s + i + algo_name_len, " (", 2) == 0)
+ if (s[i + algo_name_len] == ' ')
+ ++i;
+ if (s[i + algo_name_len] == '(')
{
*binary = 0;
- return bsd_split_3 (s + i + algo_name_len + 2,
- s_len - (i + algo_name_len + 2),
+ return bsd_split_3 (s + i + algo_name_len + 1,
+ s_len - (i + algo_name_len + 1),
hex_digest, file_name);
}
}
@@ -661,21 +662,21 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- if (status_only & !do_check)
+ if (status_only && !do_check)
{
error (0, 0,
_("the --status option is meaningful only when verifying checksums"));
usage (EXIT_FAILURE);
}
- if (warn & !do_check)
+ if (warn && !do_check)
{
error (0, 0,
_("the --warn option is meaningful only when verifying checksums"));
usage (EXIT_FAILURE);
}
- if (quiet & !do_check)
+ if (quiet && !do_check)
{
error (0, 0,
_("the --quiet option is meaningful only when verifying checksums"));
diff --git a/src/mkdir.c b/src/mkdir.c
index 4ae487593..756cc4079 100644
--- a/src/mkdir.c
+++ b/src/mkdir.c
@@ -71,7 +71,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/mkfifo.c b/src/mkfifo.c
index 5ea3e3b82..f3767e015 100644
--- a/src/mkfifo.c
+++ b/src/mkfifo.c
@@ -65,7 +65,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/mknod.c b/src/mknod.c
index 94e4471ef..cf59c2bdd 100644
--- a/src/mknod.c
+++ b/src/mknod.c
@@ -81,7 +81,7 @@ otherwise, as decimal. TYPE may be:\n\
p create a FIFO\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/mktemp.c b/src/mktemp.c
index a9a8708ca..808efa914 100644
--- a/src/mktemp.c
+++ b/src/mktemp.c
@@ -95,7 +95,7 @@ If TEMPLATE is not specified, use tmp.XXXXXXXXXX.\n\
fputs ("\n", stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
@@ -114,13 +114,13 @@ count_trailing_X_s (const char *s)
static int
mkstemp_len (char *tmpl, size_t suff_len, bool dry_run)
{
- return gen_tempname_len (tmpl, dry_run ? GT_NOCREATE : GT_FILE, suff_len);
+ return gen_tempname_len (tmpl, 0, dry_run ? GT_NOCREATE : GT_FILE, suff_len);
}
static int
mkdtemp_len (char *tmpl, size_t suff_len, bool dry_run)
{
- return gen_tempname_len (tmpl, dry_run ? GT_NOCREATE : GT_DIR, suff_len);
+ return gen_tempname_len (tmpl, 0, dry_run ? GT_NOCREATE : GT_DIR, suff_len);
}
int
diff --git a/src/mv.c b/src/mv.c
index 97e9dd401..58dddda41 100644
--- a/src/mv.c
+++ b/src/mv.c
@@ -330,7 +330,7 @@ the VERSION_CONTROL environment variable. Here are the values:\n\
existing, nil numbered if numbered backups exist, simple otherwise\n\
simple, never always make simple backups\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/nice.c b/src/nice.c
index 4a3c09212..6cd5f3133 100644
--- a/src/nice.c
+++ b/src/nice.c
@@ -81,7 +81,7 @@ With no COMMAND, print the current niceness. Nicenesses range from\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/nl.c b/src/nl.c
index 773740fa5..c3a26a52b 100644
--- a/src/nl.c
+++ b/src/nl.c
@@ -231,7 +231,7 @@ FORMAT is one of:\n\
rz right justified, leading zeros\n\
\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/nohup.c b/src/nohup.c
index f4b1b2342..99bb86547 100644
--- a/src/nohup.c
+++ b/src/nohup.c
@@ -71,7 +71,7 @@ If standard error is a terminal, redirect it to standard output.\n\
To save output to FILE, use `%s COMMAND > FILE'.\n"),
program_name);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/od.c b/src/od.c
index 085d6406c..ef8883040 100644
--- a/src/od.c
+++ b/src/od.c
@@ -394,7 +394,7 @@ output line.\n\
Option --string without a number implies 3; option --width without a number\n\
implies 32. By default, od uses -A o -t oS -w16.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -878,7 +878,7 @@ open_next_file (void)
}
while (in_stream == NULL);
- if (limit_bytes_to_format & !flag_dump_strings)
+ if (limit_bytes_to_format && !flag_dump_strings)
setvbuf (in_stream, NULL, _IONBF, 0);
return ok;
@@ -1742,7 +1742,7 @@ it must be one character from [doxn]"),
od [file] [[+]offset[.][b]]
*/
- if (!modern | traditional)
+ if (!modern || traditional)
{
uintmax_t o1;
uintmax_t o2;
diff --git a/src/paste.c b/src/paste.c
index 730a28873..c3293f748 100644
--- a/src/paste.c
+++ b/src/paste.c
@@ -450,7 +450,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
/* FIXME: add a couple of examples. */
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/pathchk.c b/src/pathchk.c
index 04b70a389..a23b53c4c 100644
--- a/src/pathchk.c
+++ b/src/pathchk.c
@@ -104,7 +104,7 @@ Diagnose invalid or unportable file names.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -270,7 +270,7 @@ validate_file_name (char *file, bool check_basic_portability,
if (check_extra_portability && ! no_leading_hyphen (file))
return false;
- if ((check_basic_portability | check_extra_portability)
+ if ((check_basic_portability || check_extra_portability)
&& filelen == 0)
{
/* Fail, since empty names are not portable. As of
diff --git a/src/pinky.c b/src/pinky.c
index f75002e1f..393a20bb4 100644
--- a/src/pinky.c
+++ b/src/pinky.c
@@ -26,6 +26,7 @@
#include "canon-host.h"
#include "error.h"
+#include "hard-locale.h"
#include "readutmp.h"
/* The official name of this program (e.g., no `g' prefix). */
@@ -526,7 +527,7 @@ usage (int status)
A lightweight `finger' program; print user information.\n\
The utmp file will be %s.\n\
"), UTMP_FILE);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/pr.c b/src/pr.c
index f584fdd30..40c35e400 100644
--- a/src/pr.c
+++ b/src/pr.c
@@ -314,6 +314,7 @@
#include <sys/types.h>
#include "system.h"
#include "error.h"
+#include "hard-locale.h"
#include "mbswidth.h"
#include "quote.h"
#include "stat-time.h"
@@ -1094,11 +1095,11 @@ main (int argc, char **argv)
if (first_page_number == 0)
first_page_number = 1;
- if (parallel_files & explicit_columns)
+ if (parallel_files && explicit_columns)
error (EXIT_FAILURE, 0,
_("cannot specify number of columns when printing in parallel"));
- if (parallel_files & print_across_flag)
+ if (parallel_files && print_across_flag)
error (EXIT_FAILURE, 0,
_("cannot specify both printing across and printing in parallel"));
@@ -1110,7 +1111,7 @@ main (int argc, char **argv)
{
if (old_w)
{
- if (parallel_files | explicit_columns)
+ if (parallel_files || explicit_columns)
{
/* activate -W */
truncate_lines = true;
@@ -1127,7 +1128,7 @@ main (int argc, char **argv)
else if (!use_col_separator)
{
/* No -S option read */
- if (old_s & (parallel_files | explicit_columns))
+ if (old_s && (parallel_files || explicit_columns))
{
if (!truncate_lines)
{
@@ -1414,7 +1415,7 @@ init_funcs (void)
/* When numbering lines of parallel files, we enlarge the
first column to accomodate the number. Looks better than
the Sys V approach. */
- if (parallel_files & numbered_lines)
+ if (parallel_files && numbered_lines)
h_next = h + chars_per_column + number_width;
else
h_next = h + chars_per_column;
@@ -1465,7 +1466,7 @@ init_funcs (void)
Doesn't need to be stored unless we intend to balance
columns on the last page. */
- if (storing_columns & balance_columns)
+ if (storing_columns && balance_columns)
{
p->char_func = store_char;
p->print_func = print_stored;
@@ -1862,7 +1863,7 @@ print_page (void)
if (cols_ready_to_print () <= 0 && !extremities)
break;
- if (double_space & pv)
+ if (double_space && pv)
{
putchar ('\n');
--lines_left_on_page;
@@ -1876,9 +1877,9 @@ print_page (void)
pad_vertically = pv;
- if (pad_vertically & extremities)
+ if (pad_vertically && extremities)
pad_down (lines_left_on_page + lines_per_footer);
- else if (keep_FF & print_a_FF)
+ else if (keep_FF && print_a_FF)
{
putchar ('\f');
print_a_FF = false;
@@ -2068,7 +2069,7 @@ add_line_number (COLUMN *p)
output_position);
}
- if (truncate_lines & !parallel_files)
+ if (truncate_lines && !parallel_files)
input_position += number_width;
}
@@ -2457,7 +2458,7 @@ read_line (COLUMN *p)
if ((c = getc (p->fp)) != '\n')
ungetc (c, p->fp);
FF_only = true;
- if (print_a_header & !storing_columns)
+ if (print_a_header && !storing_columns)
{
pad_vertically = true;
print_header ();
@@ -2485,10 +2486,10 @@ read_line (COLUMN *p)
{
pad_vertically = true;
- if (print_a_header & !storing_columns)
+ if (print_a_header && !storing_columns)
print_header ();
- if (parallel_files & align_empty_cols)
+ if (parallel_files && align_empty_cols)
{
/* We have to align empty columns at the beginning of a line. */
k = separators_not_printed;
@@ -2870,7 +2871,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
-t is implied if PAGE_LENGTH <= 10. With no FILE, or when\n\
FILE is -, read standard input.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/printenv.c b/src/printenv.c
index 69e2a6639..8185da6f8 100644
--- a/src/printenv.c
+++ b/src/printenv.c
@@ -66,7 +66,7 @@ If no VARIABLE is specified, print name and value pairs for them all.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/printf.c b/src/printf.c
index 5fa25dee8..f6f86a573 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -130,7 +130,7 @@ and all C format specifications ending with one of diouxXfeEgGcs, with\n\
ARGUMENTs converted to proper type first. Variable widths are handled.\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/ptx.c b/src/ptx.c
index 806908eee..4947a0f91 100644
--- a/src/ptx.c
+++ b/src/ptx.c
@@ -455,7 +455,7 @@ initialize_regex (void)
if (!*context_regex.string)
context_regex.string = NULL;
}
- else if (gnu_extensions & !input_reference)
+ else if (gnu_extensions && !input_reference)
context_regex.string = "[.?!][]\"')}]*\\($\\|\t\\| \\)[ \t\n]*";
else
context_regex.string = "\n";
@@ -1296,7 +1296,7 @@ fix_output_parameters (void)
/* If the reference appears to the left of the output line, reserve some
space for it right away, including one gap size. */
- if ((auto_reference | input_reference) & !right_reference)
+ if ((auto_reference || input_reference) && !right_reference)
line_width -= reference_max_width + gap_size;
/* The output lines, minimally, will contain from left to right a left
@@ -1660,7 +1660,7 @@ output_one_roff_line (void)
/* Conditionally output the `reference' field. */
- if (auto_reference | input_reference)
+ if (auto_reference || input_reference)
{
fputs (" \"", stdout);
print_field (reference);
@@ -1699,7 +1699,7 @@ output_one_tex_line (void)
fputs ("}{", stdout);
print_field (head);
putchar ('}');
- if (auto_reference | input_reference)
+ if (auto_reference || input_reference)
{
putchar ('{');
print_field (reference);
@@ -1791,12 +1791,12 @@ output_one_dumb_line (void)
}
else
- if ((auto_reference | input_reference) & right_reference)
+ if ((auto_reference || input_reference) && right_reference)
print_spaces (half_line_width
- (keyafter.end - keyafter.start)
- (keyafter_truncation ? truncation_string_length : 0));
- if ((auto_reference | input_reference) & right_reference)
+ if ((auto_reference || input_reference) && right_reference)
{
/* Output the `reference' field. */
@@ -1923,7 +1923,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
\n\
With no FILE or if FILE is -, read Standard Input. `-F /' by default.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/pwd.c b/src/pwd.c
index b74ba4707..cfbf5b733 100644
--- a/src/pwd.c
+++ b/src/pwd.c
@@ -66,7 +66,7 @@ Print the full filename of the current working directory.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/readlink.c b/src/readlink.c
index a6f42f5c0..7e9812602 100644
--- a/src/readlink.c
+++ b/src/readlink.c
@@ -82,7 +82,7 @@ usage (int status)
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/rm.c b/src/rm.c
index 6c3255198..2b62e5b1a 100644
--- a/src/rm.c
+++ b/src/rm.c
@@ -180,7 +180,7 @@ Note that if you use rm to remove a file, it is usually possible to recover\n\
the contents of that file. If you want more assurance that the contents are\n\
truly unrecoverable, consider using shred.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -325,7 +325,7 @@ main (int argc, char **argv)
}
}
- if (x.recursive & preserve_root)
+ if (x.recursive && preserve_root)
{
static struct dev_ino dev_ino_buf;
x.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
diff --git a/src/rmdir.c b/src/rmdir.c
index 3bfff22d4..899964c2e 100644
--- a/src/rmdir.c
+++ b/src/rmdir.c
@@ -74,7 +74,7 @@ static struct option const longopts[] =
static bool
errno_rmdir_non_empty (int error_number)
{
- return (error_number == RMDIR_ERRNO_NOT_EMPTY);
+ return error_number == ENOTEMPTY || error_number == EEXIST;
}
/* Return true if when rmdir fails with errno == ERROR_NUMBER
@@ -177,7 +177,7 @@ Remove the DIRECTORY(ies), if they are empty.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/runcon.c b/src/runcon.c
index 7bf256821..f87eada6a 100644
--- a/src/runcon.c
+++ b/src/runcon.c
@@ -99,7 +99,7 @@ With neither CONTEXT nor COMMAND, print the current security context.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -195,7 +195,7 @@ main (int argc, char **argv)
if (is_selinux_enabled () != 1)
error (EXIT_FAILURE, 0,
- _("runcon may be used only on a SELinux kernel"));
+ _("%s may be used only on a SELinux kernel"), program_name);
if (context)
{
diff --git a/src/seq.c b/src/seq.c
index ef777bcfd..b82a3c728 100644
--- a/src/seq.c
+++ b/src/seq.c
@@ -94,7 +94,7 @@ FORMAT must be suitable for printing one argument of type `double';\n\
it defaults to %.PRECf if FIRST, INCREMENT, and LAST are all fixed point\n\
decimal numbers with maximum precision PREC, and to %g otherwise.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/setuidgid.c b/src/setuidgid.c
index 43aa16480..34be5155a 100644
--- a/src/setuidgid.c
+++ b/src/setuidgid.c
@@ -67,7 +67,7 @@ This program is useful only when run by root (user ID zero).\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -110,7 +110,7 @@ main (int argc, char **argv)
error (EXIT_FAILURE, 0, _("invalid group %s"),
quote (gr));
if (n_gids == n_gids_allocated)
- gids = x2nrealloc (gids, &n_gids_allocated, sizeof *gids);
+ gids = X2NREALLOC (gids, &n_gids_allocated);
gids[n_gids++] = tmp_ul;
if (*ptr == '\0')
diff --git a/src/shred.c b/src/shred.c
index 2f3178993..fdf098ac4 100644
--- a/src/shred.c
+++ b/src/shred.c
@@ -229,7 +229,7 @@ In addition, file system backups and remote mirrors may contain copies\n\
of the file that cannot be removed, and that will allow a shredded file\n\
to be recovered later.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/shuf.c b/src/shuf.c
index 0e61e32dd..0bb11abc1 100644
--- a/src/shuf.c
+++ b/src/shuf.c
@@ -71,7 +71,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
\n\
With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
diff --git a/src/sleep.c b/src/sleep.c
index 4c203e621..64e237b1d 100644
--- a/src/sleep.c
+++ b/src/sleep.c
@@ -56,7 +56,7 @@ specified by the sum of their values.\n\
program_name, program_name);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/sort.c b/src/sort.c
index b9ae19883..0213fee1f 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -30,6 +30,7 @@
#include "argmatch.h"
#include "error.h"
#include "filevercmp.h"
+#include "hard-locale.h"
#include "hash.h"
#include "md5.h"
#include "physmem.h"
@@ -414,7 +415,7 @@ The locale specified by the environment affects sort order.\n\
Set LC_ALL=C to get the traditional sort order that uses\n\
native byte values.\n\
"), stdout );
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
@@ -1473,7 +1474,7 @@ limfield (const struct line *line, const struct keyfield *key)
{
while (ptr < lim && *ptr != tab)
++ptr;
- if (ptr < lim && (eword | echar))
+ if (ptr < lim && (eword || echar))
++ptr;
}
else
@@ -2029,7 +2030,7 @@ keycompare (const struct line *a, const struct line *b)
if (key->random)
diff = compare_random (texta, lena, textb, lenb);
- else if (key->numeric | key->general_numeric | key->human_numeric)
+ else if (key->numeric || key->general_numeric || key->human_numeric)
{
char savea = *lima, saveb = *limb;
@@ -2194,7 +2195,7 @@ compare (const struct line *a, const struct line *b)
if (keylist)
{
diff = keycompare (a, b);
- if (diff | unique | stable)
+ if (diff || unique || stable)
return diff;
}
@@ -3298,7 +3299,7 @@ main (int argc, char **argv)
{
bool minus_pos_usage = (optind != argc && argv[optind][0] == '-'
&& ISDIGIT (argv[optind][1]));
- obsolete_usage |= minus_pos_usage & ~posixly_correct;
+ obsolete_usage |= minus_pos_usage && !posixly_correct;
if (obsolete_usage)
{
/* Treat +POS1 [-POS2] as a key if possible; but silently
@@ -3307,7 +3308,7 @@ main (int argc, char **argv)
s = parse_field_count (optarg + 1, &key->sword, NULL);
if (s && *s == '.')
s = parse_field_count (s + 1, &key->schar, NULL);
- if (! (key->sword | key->schar))
+ if (! (key->sword || key->schar))
key->sword = SIZE_MAX;
if (! s || *set_ordering (s, key, bl_start))
key = NULL;
@@ -3398,7 +3399,7 @@ main (int argc, char **argv)
badfieldspec (optarg, N_("character offset is zero"));
}
}
- if (! (key->sword | key->schar))
+ if (! (key->sword || key->schar))
key->sword = SIZE_MAX;
s = set_ordering (s, key, bl_start);
if (*s != ',')
@@ -3587,14 +3588,14 @@ main (int argc, char **argv)
if (! (key->ignore
|| key->translate
|| (key->skipsblanks
- | key->reverse
- | key->skipeblanks
- | key->month
- | key->numeric
- | key->version
- | key->general_numeric
- | key->human_numeric
- | key->random)))
+ || key->reverse
+ || key->skipeblanks
+ || key->month
+ || key->numeric
+ || key->version
+ || key->general_numeric
+ || key->human_numeric
+ || key->random)))
{
key->ignore = gkey.ignore;
key->translate = gkey.translate;
@@ -3615,13 +3616,13 @@ main (int argc, char **argv)
if (!keylist && (gkey.ignore
|| gkey.translate
|| (gkey.skipsblanks
- | gkey.skipeblanks
- | gkey.month
- | gkey.numeric
- | gkey.general_numeric
- | gkey.human_numeric
- | gkey.random
- | gkey.version)))
+ || gkey.skipeblanks
+ || gkey.month
+ || gkey.numeric
+ || gkey.general_numeric
+ || gkey.human_numeric
+ || gkey.random
+ || gkey.version)))
{
insertkey (&gkey);
need_random |= gkey.random;
diff --git a/src/split.c b/src/split.c
index 45c24aaa4..d1a0e0d54 100644
--- a/src/split.c
+++ b/src/split.c
@@ -126,13 +126,8 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
-SIZE may have a multiplier suffix:\n\
-b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\
-GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.\n\
-"), stdout);
- emit_bug_reporting_address ();
+ emit_size_note ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/stat.c b/src/stat.c
index 330227027..d3e16d705 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -219,25 +219,39 @@ human_fstype (STRUCT_STATVFS const *statfsbuf)
return "adfs";
case S_MAGIC_AFFS: /* 0xADFF */
return "affs";
- case S_MAGIC_AUTOFS: /* 0x187 */
+ case S_MAGIC_AFS: /* 0x5346414F */
+ return "afs";
+ case S_MAGIC_ANON_INODE_FS: /* 0x09041934 */
+ return "anon-inode FS";
+ case S_MAGIC_AUTOFS: /* 0x0187 */
return "autofs";
case S_MAGIC_BEFS: /* 0x42465331 */
return "befs";
case S_MAGIC_BFS: /* 0x1BADFACE */
return "bfs";
- case S_MAGIC_BINFMT_MISC: /* 0x42494e4d */
+ case S_MAGIC_BINFMT_MISC: /* 0x42494E4D */
return "binfmt_misc";
+ case S_MAGIC_BTRFS: /* 0x9123683E */
+ return "btrfs";
+ case S_MAGIC_CGROUP: /* 0x0027E0EB */
+ return "cgroupfs";
+ case S_MAGIC_CIFS: /* 0xFF534D42 */
+ return "cifs";
case S_MAGIC_CODA: /* 0x73757245 */
return "coda";
case S_MAGIC_COH: /* 0x012FF7B7 */
return "coh";
case S_MAGIC_CRAMFS: /* 0x28CD3D45 */
return "cramfs";
+ case S_MAGIC_CRAMFS_WEND: /* 0x453DCD28 */
+ return "cramfs-wend";
+ case S_MAGIC_DEBUGFS: /* 0x64626720 */
+ return "debugfs";
case S_MAGIC_DEVFS: /* 0x1373 */
return "devfs";
case S_MAGIC_DEVPTS: /* 0x1CD1 */
return "devpts";
- case S_MAGIC_EFS: /* 0x414A53 */
+ case S_MAGIC_EFS: /* 0x00414A53 */
return "efs";
case S_MAGIC_EXT: /* 0x137D */
return "ext";
@@ -249,20 +263,26 @@ human_fstype (STRUCT_STATVFS const *statfsbuf)
return "fat";
case S_MAGIC_FUSECTL: /* 0x65735543 */
return "fusectl";
+ case S_MAGIC_FUTEXFS: /* 0x0BAD1DEA */
+ return "futexfs";
+ case S_MAGIC_HFS: /* 0x4244 */
+ return "hfs";
case S_MAGIC_HPFS: /* 0xF995E849 */
return "hpfs";
- case S_MAGIC_HUGETLBFS: /* 0x958458f6 */
+ case S_MAGIC_HUGETLBFS: /* 0x958458F6 */
return "hugetlbfs";
+ case S_MAGIC_INOTIFYFS: /* 0x2BAD1DEA */
+ return "inotifyfs";
case S_MAGIC_ISOFS: /* 0x9660 */
return "isofs";
case S_MAGIC_ISOFS_R_WIN: /* 0x4004 */
return "isofs";
case S_MAGIC_ISOFS_WIN: /* 0x4000 */
return "isofs";
- case S_MAGIC_JFFS2: /* 0x72B6 */
- return "jffs2";
case S_MAGIC_JFFS: /* 0x07C0 */
return "jffs";
+ case S_MAGIC_JFFS2: /* 0x72B6 */
+ return "jffs2";
case S_MAGIC_JFS: /* 0x3153464A */
return "jfs";
case S_MAGIC_LUSTRE: /* 0x0BD00BD0 */
@@ -275,6 +295,8 @@ human_fstype (STRUCT_STATVFS const *statfsbuf)
return "minix v2";
case S_MAGIC_MINIX_V2_30: /* 0x2478 */
return "minix v2 (30 char.)";
+ case S_MAGIC_MINIX_V3: /* 0x4D5A */
+ return "minux3";
case S_MAGIC_MSDOS: /* 0x4D44 */
return "msdos";
case S_MAGIC_NCP: /* 0x564C */
@@ -283,9 +305,11 @@ human_fstype (STRUCT_STATVFS const *statfsbuf)
return "nfs";
case S_MAGIC_NFSD: /* 0x6E667364 */
return "nfsd";
+ case S_MAGIC_NILFS: /* 0x3434 */
+ return "nilfs";
case S_MAGIC_NTFS: /* 0x5346544E */
return "ntfs";
- case S_MAGIC_OPENPROM: /* 0x9fa1 */
+ case S_MAGIC_OPENPROM: /* 0x9FA1 */
return "openprom";
case S_MAGIC_PROC: /* 0x9FA0 */
return "proc";
@@ -297,6 +321,10 @@ human_fstype (STRUCT_STATVFS const *statfsbuf)
return "reiserfs";
case S_MAGIC_ROMFS: /* 0x7275 */
return "romfs";
+ case S_MAGIC_SECURITYFS: /* 0x73636673 */
+ return "securityfs";
+ case S_MAGIC_SELINUX: /* 0xF97CFF8C */
+ return "selinux";
case S_MAGIC_SMB: /* 0x517B */
return "smb";
case S_MAGIC_SQUASHFS: /* 0x73717368 */
@@ -307,7 +335,7 @@ human_fstype (STRUCT_STATVFS const *statfsbuf)
return "sysv2";
case S_MAGIC_SYSV4: /* 0x012FF7B5 */
return "sysv4";
- case S_MAGIC_TMPFS: /* 0x1021994 */
+ case S_MAGIC_TMPFS: /* 0x01021994 */
return "tmpfs";
case S_MAGIC_UDF: /* 0x15013346 */
return "udf";
@@ -319,6 +347,8 @@ human_fstype (STRUCT_STATVFS const *statfsbuf)
return "usbdevfs";
case S_MAGIC_VXFS: /* 0xA501FCF5 */
return "vxfs";
+ case S_MAGIC_XENFS: /* 0xABBA1974 */
+ return "xenfs";
case S_MAGIC_XENIX: /* 0x012FF7B4 */
return "xenix";
case S_MAGIC_XFS: /* 0x58465342 */
@@ -829,6 +859,13 @@ do_statfs (char const *filename, bool terse, char const *format)
{
STRUCT_STATVFS statfsbuf;
+ if (STREQ (filename, "-"))
+ {
+ error (0, 0, _("using %s to denote standard input does not work"
+ " in file system mode"), quote (filename));
+ return false;
+ }
+
if (STATFS (filename, &statfsbuf) != 0)
{
error (0, errno, _("cannot read file system information for %s"),
@@ -857,7 +894,20 @@ do_stat (char const *filename, bool terse, char const *format)
{
struct stat statbuf;
- if ((follow_links ? stat : lstat) (filename, &statbuf) != 0)
+ if (STREQ (filename, "-"))
+ {
+ if (fstat (STDIN_FILENO, &statbuf) != 0)
+ {
+ error (0, errno, _("cannot stat standard input"));
+ return false;
+ }
+ }
+ /* We can't use the shorter
+ (follow_links ? stat : lstat) (filename, &statbug)
+ since stat might be a function-like macro. */
+ else if ((follow_links
+ ? stat (filename, &statbuf)
+ : lstat (filename, &statbuf)) != 0)
{
error (0, errno, _("cannot stat %s"), quote (filename));
return false;
@@ -983,7 +1033,7 @@ Valid format sequences for file systems:\n\
%T Type in human readable form\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/stdbuf.c b/src/stdbuf.c
index 007cc2194..393071354 100644
--- a/src/stdbuf.c
+++ b/src/stdbuf.c
@@ -24,8 +24,10 @@
#include "system.h"
#include "error.h"
+#include "filenamecat.h"
#include "posixver.h"
#include "quote.h"
+#include "xreadlink.h"
#include "xstrtol.h"
#include "c-ctype.h"
@@ -35,9 +37,6 @@
#define AUTHORS proper_name_utf8 ("Padraig Brady", "P\303\241draig Brady")
-/* Internal error */
-enum { EXIT_CANCELED = 125 };
-
static char *program_path;
extern char **environ;
@@ -125,7 +124,7 @@ for e.g.) then that will override corresponding settings changed by `stdbuf'.\n\
Also some filters (like `dd' and `cat' etc.) don't use streams for I/O,\n\
and are thus unaffected by `stdbuf' settings.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -145,34 +144,26 @@ set_program_path (const char *arg)
}
else
{
- char *path;
- char tmppath[PATH_MAX + 1];
- ssize_t len = readlink ("/proc/self/exe", tmppath, sizeof (tmppath) - 1);
- if (len > 0)
- {
- tmppath[len] = '\0';
- program_path = dir_name (tmppath);
- }
+ char *path = xreadlink ("/proc/self/exe");
+ if (path)
+ program_path = dir_name (path);
else if ((path = getenv ("PATH")))
{
char *dir;
path = xstrdup (path);
for (dir = strtok (path, ":"); dir != NULL; dir = strtok (NULL, ":"))
{
- int req = snprintf (tmppath, sizeof (tmppath), "%s/%s", dir, arg);
- if (req >= sizeof (tmppath))
- {
- error (0, 0, _("path truncated when looking for %s"),
- quote (arg));
- }
- else if (access (tmppath, X_OK) == 0)
+ char *candidate = file_name_concat (dir, arg, NULL);
+ if (access (candidate, X_OK) == 0)
{
- program_path = dir_name (tmppath);
+ program_path = dir_name (candidate);
+ free (candidate);
break;
}
+ free (candidate);
}
- free (path);
}
+ free (path);
}
}
diff --git a/src/stty.c b/src/stty.c
index b980e8482..254504860 100644
--- a/src/stty.c
+++ b/src/stty.c
@@ -279,18 +279,18 @@ static struct mode_info const mode_info[] =
{"cr0", output, SANE_SET, CR0, CRDLY},
#endif
#ifdef TABDLY
-#ifdef TAB3
+# ifdef TAB3
{"tab3", output, SANE_UNSET, TAB3, TABDLY},
-#endif
-#ifdef TAB2
+# endif
+# ifdef TAB2
{"tab2", output, SANE_UNSET, TAB2, TABDLY},
-#endif
-#ifdef TAB1
+# endif
+# ifdef TAB1
{"tab1", output, SANE_UNSET, TAB1, TABDLY},
-#endif
-#ifdef TAB0
+# endif
+# ifdef TAB0
{"tab0", output, SANE_SET, TAB0, TABDLY},
-#endif
+# endif
#else
# ifdef OXTABS
{"tab3", output, SANE_UNSET, OXTABS, 0},
@@ -724,7 +724,7 @@ prints baud rate, line discipline, and deviations from stty sane. In\n\
settings, CHAR is taken literally, or coded as in ^c, 0x37, 0177 or\n\
127; special values ^- or undef used to disable special characters.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -817,13 +817,13 @@ main (int argc, char **argv)
}
/* Specifying both -a and -g gets an error. */
- if (verbose_output & recoverable_output)
+ if (verbose_output && recoverable_output)
error (EXIT_FAILURE, 0,
_("the options for verbose and stty-readable output styles are\n"
"mutually exclusive"));
/* Specifying any other arguments with -a or -g gets an error. */
- if (!noargs && (verbose_output | recoverable_output))
+ if (!noargs && (verbose_output || recoverable_output))
error (EXIT_FAILURE, 0,
_("when specifying an output style, modes may not be set"));
@@ -849,7 +849,7 @@ main (int argc, char **argv)
if (tcgetattr (STDIN_FILENO, &mode))
error (EXIT_FAILURE, errno, "%s", device_name);
- if (verbose_output | recoverable_output | noargs)
+ if (verbose_output || recoverable_output || noargs)
{
max_col = screen_columns ();
current_col = 0;
@@ -883,7 +883,7 @@ main (int argc, char **argv)
break;
}
}
- if (!match_found & reversed)
+ if (!match_found && reversed)
{
error (0, 0, _("invalid argument %s"), quote (arg - 1));
usage (EXIT_FAILURE);
diff --git a/src/su.c b/src/su.c
index ec9c6001c..25b883814 100644
--- a/src/su.c
+++ b/src/su.c
@@ -53,16 +53,9 @@
#include <pwd.h>
#include <grp.h>
-/* Hide any system prototype for getusershell.
- This is necessary because some Cray systems have a conflicting
- prototype (returning `int') in <unistd.h>. */
-#define getusershell _getusershell_sys_proto_
-
#include "system.h"
#include "getpass.h"
-#undef getusershell
-
#if HAVE_SYSLOG_H && HAVE_SYSLOG
# include <syslog.h>
#else
@@ -119,9 +112,6 @@
#define DEFAULT_USER "root"
char *crypt (char const *key, char const *salt);
-char *getusershell (void);
-void endusershell (void);
-void setusershell (void);
extern char **environ;
@@ -395,7 +385,7 @@ Change the effective user id and group id to that of USER.\n\
\n\
A mere - implies -l. If USER not given, assume root.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/sum.c b/src/sum.c
index e53bad2ca..91d7f34ba 100644
--- a/src/sum.c
+++ b/src/sum.c
@@ -72,7 +72,7 @@ Print checksum and block counts for each FILE.\n\
\n\
With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/sync.c b/src/sync.c
index 593071347..543cbde9b 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -45,7 +45,7 @@ Force changed blocks to disk, update the super block.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/system.h b/src/system.h
index 3a0550122..8de0f3cd2 100644
--- a/src/system.h
+++ b/src/system.h
@@ -44,16 +44,8 @@ you must include <sys/types.h> before including this file
#include "configmake.h"
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
+#include <sys/time.h>
+#include <time.h>
/* Since major is a function on SVR4, we can't use `ifndef major'. */
#if MAJOR_IN_MKDEV
@@ -86,16 +78,8 @@ you must include <sys/types.h> before including this file
#include <errno.h>
-/* Some systems don't define the following symbols. */
-#ifndef EDQUOT
-# define EDQUOT (-1)
-#endif
-#ifndef EISDIR
-# define EISDIR (-1)
-#endif
-#ifndef ENOSYS
-# define ENOSYS (-1)
-#endif
+/* Some systems don't define this; POSIX mentions it but says it is
+ obsolete, so gnulib does not provide it either. */
#ifndef ENODATA
# define ENODATA (-1)
#endif
@@ -107,8 +91,10 @@ you must include <sys/types.h> before including this file
/* Exit statuses for programs like 'env' that exec other programs. */
enum
{
- EXIT_CANNOT_INVOKE = 126,
- EXIT_ENOENT = 127
+ EXIT_TIMEDOUT = 124, /* Time expired before child completed. */
+ EXIT_CANCELED = 125, /* Internal error prior to exec attempt. */
+ EXIT_CANNOT_INVOKE = 126, /* Program located, but not usable. */
+ EXIT_ENOENT = 127 /* Could not find program to exec. */
};
#include "exitfail.h"
@@ -123,13 +109,6 @@ initialize_exit_failure (int status)
#include <fcntl.h>
-#ifndef F_OK
-# define F_OK 0
-# define X_OK 1
-# define W_OK 2
-# define R_OK 4
-#endif
-
#include <dirent.h>
#ifndef _D_EXACT_NAMLEN
# define _D_EXACT_NAMLEN(dp) strlen ((dp)->d_name)
@@ -279,30 +258,6 @@ select_plural (uintmax_t n)
#define STREQ(a, b) (strcmp (a, b) == 0)
-#if !HAVE_DECL_FREE
-void free ();
-#endif
-
-#if !HAVE_DECL_MALLOC
-char *malloc ();
-#endif
-
-#if !HAVE_DECL_MEMCHR
-char *memchr ();
-#endif
-
-#if !HAVE_DECL_REALLOC
-char *realloc ();
-#endif
-
-#if !HAVE_DECL_GETENV
-char *getenv ();
-#endif
-
-#if !HAVE_DECL_LSEEK
-off_t lseek ();
-#endif
-
#if !HAVE_DECL_GETLOGIN
char *getlogin ();
#endif
@@ -547,10 +502,6 @@ enum
while (0)
#endif
-#ifndef EOVERFLOW
-# define EOVERFLOW EINVAL
-#endif
-
#if ! HAVE_SYNC
# define sync() /* empty */
#endif
@@ -616,9 +567,27 @@ ptr_align (void const *ptr, size_t alignment)
? false : (((Accum) = (Accum) * 10 + (Digit_val)), true)) \
)
-#include "hard-locale.h"
static inline void
-emit_bug_reporting_address (void)
+emit_size_note (void)
+{
+ fputs (_("\n\
+SIZE may be (or may be an integer optionally followed by) one of following:\n\
+KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
+"), stdout);
+}
+
+static inline void
+emit_blocksize_note (char const *program)
+{
+ printf (_("\n\
+Display values are in units of the first available SIZE from --block-size,\n\
+and the %s_BLOCK_SIZE, BLOCK_SIZE and BLOCKSIZE environment variables.\n\
+Otherwise, units default to 1024 bytes (or 512 if POSIXLY_CORRECT is set).\n\
+"), program);
+}
+
+static inline void
+emit_ancillary_info (void)
{
printf (_("\nReport %s bugs to %s\n"), last_component (program_name),
PACKAGE_BUGREPORT);
@@ -627,8 +596,10 @@ emit_bug_reporting_address (void)
PACKAGE_NAME, PACKAGE);
fputs (_("General help using GNU software: <http://www.gnu.org/gethelp/>\n"),
stdout);
-
- if (hard_locale (LC_MESSAGES))
+ /* Don't output this redundant message for English locales.
+ Note we still output for 'C' so that it gets included in the man page. */
+ const char *lc_messages = setlocale (LC_MESSAGES, NULL);
+ if (lc_messages && strncmp (lc_messages, "en_", 3))
{
/* TRANSLATORS: Replace LANG_CODE in this URL with your language code
<http://translationproject.org/team/LANG_CODE.html> to form one of
@@ -638,6 +609,8 @@ emit_bug_reporting_address (void)
"<http://translationproject.org/team/>\n"),
last_component (program_name));
}
+ printf (_("For complete documentation, run: "
+ "info coreutils '%s invocation'\n"), last_component (program_name));
}
#include "inttostr.h"
diff --git a/src/tac.c b/src/tac.c
index e1f71945f..c6ba4e2f4 100644
--- a/src/tac.c
+++ b/src/tac.c
@@ -149,7 +149,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/tail.c b/src/tail.c
index f0dbf5d5e..f3fe6a341 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -201,6 +201,10 @@ static bool have_read_stdin;
more expensive) code unconditionally. Intended solely for testing. */
static bool presume_input_pipe;
+/* If nonzero then don't use inotify even if available.
+ Intended solely for testing. */
+static bool disable_inotify;
+
/* For long options that have no equivalent short option, use a
non-character as a pseudo short option, starting with CHAR_MAX + 1. */
enum
@@ -209,7 +213,8 @@ enum
MAX_UNCHANGED_STATS_OPTION,
PID_OPTION,
PRESUME_INPUT_PIPE_OPTION,
- LONG_FOLLOW_OPTION
+ LONG_FOLLOW_OPTION,
+ DISABLE_INOTIFY_OPTION
};
static struct option const long_options[] =
@@ -218,6 +223,8 @@ static struct option const long_options[] =
{"follow", optional_argument, NULL, LONG_FOLLOW_OPTION},
{"lines", required_argument, NULL, 'n'},
{"max-unchanged-stats", required_argument, NULL, MAX_UNCHANGED_STATS_OPTION},
+ {"-disable-inotify", no_argument, NULL,
+ DISABLE_INOTIFY_OPTION}, /* do not document */
{"pid", required_argument, NULL, PID_OPTION},
{"-presume-input-pipe", no_argument, NULL,
PRESUME_INPUT_PIPE_OPTION}, /* do not document */
@@ -283,7 +290,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
name, i.e., with --follow=name\n\
"), stdout);
fputs (_("\
- -s, --sleep-interval=S with -f, sleep for approximately S seconds\n\
+ -s, --sleep-interval=N with -f, sleep for approximately N seconds\n\
(default 1.0) between iterations\n\
-v, --verbose always output headers giving file names\n\
"), stdout);
@@ -310,7 +317,7 @@ rotation). Use --follow=name in that case. That causes tail to track the\n\
named file by reopening it periodically to see if it has been removed and\n\
recreated by some other program.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -351,7 +358,7 @@ record_open_fd (struct File_spec *f, int fd,
f->mode = st->st_mode;
f->blocking = blocking;
f->n_unchanged_stats = 0;
- f->ignore = 0;
+ f->ignore = false;
}
/* Close the file with descriptor FD and name FILENAME. */
@@ -1119,7 +1126,7 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
break;
}
- if ((!any_input | blocking) && fflush (stdout) != 0)
+ if ((!any_input || blocking) && fflush (stdout) != 0)
error (EXIT_FAILURE, errno, _("write error"));
/* If nothing was read, sleep and/or check for dead writers. */
@@ -1128,9 +1135,6 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
if (writer_is_dead)
break;
- if (xnanosleep (sleep_interval))
- error (EXIT_FAILURE, errno, _("cannot read realtime clock"));
-
/* Once the writer is dead, read the files once more to
avoid a race condition. */
writer_is_dead = (pid != 0
@@ -1139,6 +1143,10 @@ tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)
signal to the writer, so kill fails and sets
errno to EPERM. */
&& errno != EPERM);
+
+ if (!writer_is_dead && xnanosleep (sleep_interval))
+ error (EXIT_FAILURE, errno, _("cannot read realtime clock"));
+
}
}
}
@@ -1172,6 +1180,7 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
Hash_table *wd_table;
bool found_watchable = false;
+ bool writer_is_dead = false;
int prev_wd;
size_t evlen = 0;
char *evbuf;
@@ -1259,30 +1268,30 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
indefinetely. */
if (pid)
{
- fd_set rfd;
- struct timeval select_timeout;
- int n_descriptors;
-
- FD_ZERO (&rfd);
- FD_SET (wd, &rfd);
+ if (writer_is_dead)
+ exit (EXIT_SUCCESS);
- select_timeout.tv_sec = (time_t) sleep_interval;
- select_timeout.tv_usec = 1000000 * (sleep_interval
- - select_timeout.tv_sec);
+ writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM);
- n_descriptors = select (wd + 1, &rfd, NULL, NULL, &select_timeout);
+ struct timeval delay; /* how long to wait for file changes. */
+ if (writer_is_dead)
+ delay.tv_sec = delay.tv_usec = 0;
+ else
+ {
+ delay.tv_sec = (time_t) sleep_interval;
+ delay.tv_usec = 1000000 * (sleep_interval - delay.tv_sec);
+ }
- if (n_descriptors == -1)
- error (EXIT_FAILURE, errno, _("error monitoring inotify event"));
+ fd_set rfd;
+ FD_ZERO (&rfd);
+ FD_SET (wd, &rfd);
- if (n_descriptors == 0)
- {
- /* See if the process we are monitoring is still alive. */
- if (kill (pid, 0) != 0 && errno != EPERM)
- exit (EXIT_SUCCESS);
+ int file_change = select (wd + 1, &rfd, NULL, NULL, &delay);
- continue;
- }
+ if (file_change == 0)
+ continue;
+ else if (file_change == -1)
+ error (EXIT_FAILURE, errno, _("error monitoring inotify event"));
}
if (len <= evbuf_off)
@@ -1392,7 +1401,6 @@ tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,
if (fflush (stdout) != 0)
error (EXIT_FAILURE, errno, _("write error"));
}
-
}
#endif
@@ -1794,6 +1802,10 @@ parse_options (int argc, char **argv,
}
break;
+ case DISABLE_INOTIFY_OPTION:
+ disable_inotify = true;
+ break;
+
case PID_OPTION:
{
strtol_error s_err;
@@ -1912,28 +1924,6 @@ main (int argc, char **argv)
static char *dummy_stdin = (char *) "-";
n_files = 1;
file = &dummy_stdin;
-
- /* POSIX says that -f is ignored if no file operand is specified
- and standard input is a pipe. However, the GNU coding
- standards say that program behavior should not depend on
- device type, because device independence is an important
- principle of the system's design.
-
- Follow the POSIX requirement only if POSIXLY_CORRECT is set. */
-
- if (forever && getenv ("POSIXLY_CORRECT"))
- {
- struct stat st;
- int is_a_fifo_or_pipe =
- (fstat (STDIN_FILENO, &st) != 0 ? -1
- : S_ISFIFO (st.st_mode) ? 1
- : HAVE_FIFO_PIPES == 1 ? 0
- : isapipe (STDIN_FILENO));
- if (is_a_fifo_or_pipe < 0)
- error (EXIT_FAILURE, errno, _("standard input"));
- if (is_a_fifo_or_pipe)
- forever = false;
- }
}
{
@@ -1969,18 +1959,58 @@ main (int argc, char **argv)
for (i = 0; i < n_files; i++)
ok &= tail_file (&F[i], n_units);
- if (forever)
+ /* When there is no FILE operand and stdin is a pipe or FIFO
+ POSIX requires that tail ignore the -f option.
+ Since we allow multiple FILE operands, we extend that to say:
+ ignore any "-" operand that corresponds to a pipe or FIFO. */
+ size_t n_viable = 0;
+ for (i = 0; i < n_files; i++)
{
-#if HAVE_INOTIFY
- int wd = inotify_init ();
- if (wd < 0)
- error (0, errno, _("inotify cannot be used, reverting to polling"));
+ bool is_a_fifo_or_pipe =
+ (STREQ (F[i].name, "-")
+ && !F[i].ignore
+ && 0 <= F[i].fd
+ && (S_ISFIFO (F[i].mode)
+ || (HAVE_FIFO_PIPES != 1 && isapipe (F[i].fd))));
+ if (is_a_fifo_or_pipe)
+ F[i].ignore = true;
else
+ ++n_viable;
+ }
+
+ if (forever && n_viable)
+ {
+#if HAVE_INOTIFY
+ /* If the user specifies stdin via a command line argument of "-",
+ or implicitly by providing no arguments, we won't use inotify.
+ Technically, on systems with a working /dev/stdin, we *could*,
+ but would it be worth it? Verifying that it's a real device
+ and hooked up to stdin is not trivial, while reverting to
+ non-inotify-based tail_forever is easy and portable. */
+ bool stdin_cmdline_arg = false;
+
+ for (i = 0; i < n_files; i++)
+ if (!F[i].ignore && STREQ (F[i].name, "-"))
+ stdin_cmdline_arg = true;
+
+ if (!disable_inotify && !stdin_cmdline_arg)
{
- tail_forever_inotify (wd, F, n_files, sleep_interval);
+ int wd = inotify_init ();
+ if (wd < 0)
+ error (0, errno, _("inotify cannot be used, reverting to polling"));
+ else
+ {
+ /* Flush any output from tail_file, now, since
+ tail_forever_inotify flushes only after writing,
+ not before reading. */
+ if (fflush (stdout) != 0)
+ error (EXIT_FAILURE, errno, _("write error"));
- /* The only way the above returns is upon failure. */
- exit (EXIT_FAILURE);
+ tail_forever_inotify (wd, F, n_files, sleep_interval);
+
+ /* The only way the above returns is upon failure. */
+ exit (EXIT_FAILURE);
+ }
}
#endif
tail_forever (F, n_files, sleep_interval);
diff --git a/src/tee.c b/src/tee.c
index 03a33b060..b8996e6a5 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -72,7 +72,7 @@ Copy standard input to each FILE, and also to standard output.\n\
\n\
If a FILE is -, copy again to standard output.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/test.c b/src/test.c
index f7c689cf9..27db19da2 100644
--- a/src/test.c
+++ b/src/test.c
@@ -318,7 +318,7 @@ binary_operator (bool l_is_l)
struct timespec lt, rt;
bool le, re;
pos += 3;
- if (l_is_l | r_is_l)
+ if (l_is_l || r_is_l)
test_syntax_error (_("-nt does not accept -l"), NULL);
le = get_mtime (argv[op - 1], &lt);
re = get_mtime (argv[op + 1], &rt);
@@ -331,7 +331,7 @@ binary_operator (bool l_is_l)
{
/* ef - hard link? */
pos += 3;
- if (l_is_l | r_is_l)
+ if (l_is_l || r_is_l)
test_syntax_error (_("-ef does not accept -l"), NULL);
return (stat (argv[op - 1], &stat_buf) == 0
&& stat (argv[op + 1], &stat_spare) == 0
@@ -347,7 +347,7 @@ binary_operator (bool l_is_l)
struct timespec lt, rt;
bool le, re;
pos += 3;
- if (l_is_l | r_is_l)
+ if (l_is_l || r_is_l)
test_syntax_error (_("-ot does not accept -l"), NULL);
le = get_mtime (argv[op - 1], &lt);
re = get_mtime (argv[op + 1], &rt);
@@ -770,7 +770,7 @@ NOTE: [ honors the --help and --version options, but test does not.\n\
test treats each of those as it treats any other nonempty STRING.\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, _("test and/or ["));
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/timeout.c b/src/timeout.c
index 6d9d10912..7b0f1d7c5 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -73,12 +73,6 @@
#define AUTHORS proper_name_utf8 ("Padraig Brady", "P\303\241draig Brady")
-/* Note ETIMEDOUT is 110 on GNU/Linux systems but this is non standard */
-#define EXIT_TIMEDOUT 124
-
-/* Internal failure. */
-#define EXIT_CANCELED 125
-
static int timed_out;
static int term_signal = SIGTERM; /* same default as kill command. */
static int monitored_pid;
@@ -153,13 +147,12 @@ Mandatory arguments to long options are mandatory for short options too.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\n\
-If the command times out, then we exit with status 124,\n\
-otherwise the normal exit status of the command is returned.\n\
-If no signal is specified, the TERM signal is sent. The TERM signal\n\
-will kill processes which do not catch this signal. For other processes,\n\
-it may be necessary to use the KILL (9) signal, since this signal cannot\n\
-be caught.\n"), stdout);
- emit_bug_reporting_address ();
+If the command times out, then exit with status 124. Otherwise, exit\n\
+with the status of COMMAND. If no signal is specified, send the TERM\n\
+signal upon timeout. The TERM signal kills any process that does not\n\
+block or catch that signal. For other processes, it may be necessary to\n\
+use the KILL (9) signal, since this signal cannot be caught.\n"), stdout);
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/touch.c b/src/touch.c
index ed9847175..b4c45a1f8 100644
--- a/src/touch.c
+++ b/src/touch.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
+#include <assert.h>
#include "system.h"
#include "argmatch.h"
@@ -119,11 +120,9 @@ static bool
touch (const char *file)
{
bool ok;
- struct stat sbuf;
int fd = -1;
int open_errno = 0;
- struct timespec timespec[2];
- struct timespec const *t;
+ struct timespec const *t = newtime;
if (STREQ (file, "-"))
fd = STDOUT_FILENO;
@@ -144,24 +143,13 @@ touch (const char *file)
if (change_times != (CH_ATIME | CH_MTIME))
{
- /* We're setting only one of the time values. stat the target to get
- the other one. If we have the file descriptor already, use fstat.
- Otherwise, either we're in no-create mode (and hence didn't call open)
- or FILE is inaccessible or a directory, so we have to use stat. */
- if (fd != -1 ? fstat (fd, &sbuf) : stat (file, &sbuf))
+ /* We're setting only one of the time values. */
+ if (change_times == CH_MTIME)
+ newtime[0].tv_nsec = UTIME_OMIT;
+ else
{
- if (open_errno)
- error (0, open_errno, _("creating %s"), quote (file));
- else
- {
- if (no_create && (errno == ENOENT || errno == EBADF))
- return true;
- error (0, errno, _("failed to get attributes of %s"),
- quote (file));
- }
- if (fd == STDIN_FILENO)
- close (fd);
- return false;
+ assert (change_times == CH_ATIME);
+ newtime[1].tv_nsec = UTIME_OMIT;
}
}
@@ -171,16 +159,6 @@ touch (const char *file)
write access to the file, but don't own it. */
t = NULL;
}
- else
- {
- timespec[0] = (change_times & CH_ATIME
- ? newtime[0]
- : get_stat_atime (&sbuf));
- timespec[1] = (change_times & CH_MTIME
- ? newtime[1]
- : get_stat_mtime (&sbuf));
- t = timespec;
- }
ok = (gl_futimens (fd, (fd == STDOUT_FILENO ? NULL : file), t) == 0);
@@ -195,8 +173,7 @@ touch (const char *file)
else if (fd == STDOUT_FILENO)
{
/* Do not diagnose "touch -c - >&-". */
- if (!ok && errno == EBADF && no_create
- && change_times == (CH_ATIME | CH_MTIME))
+ if (!ok && errno == EBADF && no_create)
return true;
}
@@ -263,7 +240,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
\n\
Note that the -d and -t options accept different time-date formats.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -429,10 +406,7 @@ main (int argc, char **argv)
if (change_times == (CH_ATIME | CH_MTIME))
amtime_now = true;
else
- {
- gettime (&newtime[0]);
- newtime[1] = newtime[0];
- }
+ newtime[1].tv_nsec = newtime[0].tv_nsec = UTIME_NOW;
}
if (optind == argc)
diff --git a/src/tr.c b/src/tr.c
index 0b985f801..c5f18f983 100644
--- a/src/tr.c
+++ b/src/tr.c
@@ -346,7 +346,7 @@ only be used in pairs to specify case conversion. -s uses SET1 if not\n\
translating nor deleting; else squeezing uses SET2 and occurs after\n\
translation or deletion.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/true.c b/src/true.c
index 66d1e0111..f3e937f5a 100644
--- a/src/true.c
+++ b/src/true.c
@@ -47,7 +47,7 @@ Usage: %s [ignored command line arguments]\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
exit (status);
}
diff --git a/src/truncate.c b/src/truncate.c
index 0cb7b35ee..7f96483da 100644
--- a/src/truncate.c
+++ b/src/truncate.c
@@ -124,10 +124,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
-s, --size=SIZE use this SIZE\n"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\n\
-SIZE is a number which may be followed by one of the following suffixes:\n\
-KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
-"), stdout);
+ emit_size_note ();
fputs (_("\n\
SIZE may also be prefixed by one of the following modifying characters:\n\
`+' extend by, `-' reduce by, `<' at most, `>' at least,\n\
@@ -136,7 +133,7 @@ SIZE may also be prefixed by one of the following modifying characters:\n\
\n\
Note that the -r and -s options are mutually exclusive.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/tsort.c b/src/tsort.c
index d74b62091..09067f267 100644
--- a/src/tsort.c
+++ b/src/tsort.c
@@ -87,7 +87,7 @@ With no FILE, or when FILE is -, read standard input.\n\
"), program_name);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
diff --git a/src/tty.c b/src/tty.c
index cc15cfe4a..37443d22c 100644
--- a/src/tty.c
+++ b/src/tty.c
@@ -70,7 +70,7 @@ Print the file name of the terminal connected to standard input.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/uname.c b/src/uname.c
index 63b3374e3..adce750dc 100644
--- a/src/uname.c
+++ b/src/uname.c
@@ -150,7 +150,7 @@ Print machine architecture.\n\
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/unexpand.c b/src/unexpand.c
index bfe22964e..cfbc46bd7 100644
--- a/src/unexpand.c
+++ b/src/unexpand.c
@@ -130,7 +130,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -429,7 +429,7 @@ unexpand (void)
}
prev_blank = blank;
- convert &= convert_entire_line | blank;
+ convert &= convert_entire_line || blank;
}
if (c < 0)
diff --git a/src/uniq.c b/src/uniq.c
index 13aaebccc..7509bfce9 100644
--- a/src/uniq.c
+++ b/src/uniq.c
@@ -26,6 +26,7 @@
#include "argmatch.h"
#include "linebuffer.h"
#include "error.h"
+#include "hard-locale.h"
#include "posixver.h"
#include "quote.h"
#include "xmemcoll.h"
@@ -174,7 +175,7 @@ Note: 'uniq' does not detect repeated lines unless they are adjacent.\n\
You may want to sort the input first, or use `sort -u' without `uniq'.\n\
Also, comparisons honor the rules specified by `LC_COLLATE'.\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/unlink.c b/src/unlink.c
index 47cbfb2e3..209d0b6da 100644
--- a/src/unlink.c
+++ b/src/unlink.c
@@ -50,7 +50,7 @@ Usage: %s FILE\n\
stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/uptime.c b/src/uptime.c
index 175fe8f73..cb3dcf0f8 100644
--- a/src/uptime.c
+++ b/src/uptime.c
@@ -111,7 +111,11 @@ print_uptime (size_t n, const STRUCT_UTMP *this)
boot_time = UT_TIME_MEMBER (this);
++this;
}
+#else
+ (void) n;
+ (void) this;
#endif
+
time_now = time (NULL);
#if defined HAVE_PROC_UPTIME
if (uptime == 0)
@@ -216,7 +220,7 @@ If FILE is not specified, use %s. %s as FILE is common.\n\
UTMP_FILE, WTMP_FILE);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/users.c b/src/users.c
index d5115c691..fd1cbaaee 100644
--- a/src/users.c
+++ b/src/users.c
@@ -112,7 +112,7 @@ If FILE is not specified, use %s. %s as FILE is common.\n\
UTMP_FILE, WTMP_FILE);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/wc.c b/src/wc.c
index 0f7a36888..52e899e97 100644
--- a/src/wc.c
+++ b/src/wc.c
@@ -131,7 +131,7 @@ read standard input.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
@@ -205,10 +205,10 @@ wc (int fd, char const *file_x, struct fstatus *fstatus)
else
#endif
{
- count_bytes = print_bytes | print_chars;
+ count_bytes = print_bytes || print_chars;
count_chars = false;
}
- count_complicated = print_words | print_linelength;
+ count_complicated = print_words || print_linelength;
/* When counting only bytes, save some line- and word-counting
overhead. If FD is a `regular' Unix file, using lseek is enough
@@ -220,7 +220,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus)
`(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
should make wc report `0' bytes. */
- if (count_bytes & !count_chars & !print_lines & !count_complicated)
+ if (count_bytes && !count_chars && !print_lines && !count_complicated)
{
off_t current_pos, end_pos;
@@ -637,8 +637,8 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
- if (! (print_lines | print_words | print_chars | print_bytes
- | print_linelength))
+ if (! (print_lines || print_words || print_chars || print_bytes
+ || print_linelength))
print_lines = print_words = print_bytes = true;
bool read_tokens = false;
diff --git a/src/who.c b/src/who.c
index f162fab58..0ac971031 100644
--- a/src/who.c
+++ b/src/who.c
@@ -34,6 +34,7 @@
#include "canon-host.h"
#include "readutmp.h"
#include "error.h"
+#include "hard-locale.h"
#include "quote.h"
/* The official name of this program (e.g., no `g' prefix). */
@@ -665,7 +666,7 @@ Print information about users who are currently logged in.\n\
If FILE is not specified, use %s. %s as FILE is common.\n\
If ARG1 ARG2 given, -m presumed: `am i' or `mom likes' are usual.\n\
"), UTMP_FILE, WTMP_FILE);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/whoami.c b/src/whoami.c
index 928f69e45..d064cc2ef 100644
--- a/src/whoami.c
+++ b/src/whoami.c
@@ -51,7 +51,7 @@ Same as id -un.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/src/yes.c b/src/yes.c
index e974de29f..b45f96925 100644
--- a/src/yes.c
+++ b/src/yes.c
@@ -51,7 +51,7 @@ Repeatedly output a line with all specified STRING(s), or `y'.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d9ff95be4..8dc90f9f2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -216,7 +216,9 @@ TESTS = \
misc/split-fail \
misc/split-l \
misc/stat-fmt \
+ misc/stat-hyphen \
misc/stat-printf \
+ misc/stat-slash \
misc/stdbuf \
misc/stty \
misc/stty-invalid \
@@ -309,6 +311,7 @@ TESTS = \
dd/skip-seek2 \
dd/skip-seek-past-file \
dd/stderr \
+ dd/unblock \
dd/unblock-sync \
df/total-verify \
du/2g \
@@ -333,6 +336,7 @@ TESTS = \
du/slink \
du/trailing-slash \
du/two-args \
+ id/no-context \
install/basic-1 \
install/create-leading \
install/d-slashdot \
@@ -342,8 +346,10 @@ TESTS = \
install/trap \
ln/backup-1 \
ln/hard-backup \
+ ln/hard-to-sym \
ln/misc \
ln/sf-1 \
+ ln/slash-decorated-nonexistent-dest \
ln/target-1 \
ls/abmon-align \
ls/color-clear-to-eol \
@@ -427,8 +433,13 @@ TESTS = \
rmdir/t-slash \
tail-2/assert-2 \
tail-2/big-4gb \
+ tail-2/flush-initial \
+ tail-2/follow-stdin \
+ tail-2/pipe-f \
+ tail-2/pipe-f2 \
tail-2/proc-ksyms \
tail-2/start-middle \
+ touch/60-seconds \
touch/dangling-symlink \
touch/dir-1 \
touch/fail-diag \
diff --git a/tests/cp/preserve-slink-time b/tests/cp/preserve-slink-time
index c5c21a5e1..407b77272 100755
--- a/tests/cp/preserve-slink-time
+++ b/tests/cp/preserve-slink-time
@@ -24,6 +24,7 @@ fi
. $srcdir/test-lib.sh
grep '^#define HAVE_UTIMENSAT' "$CONFIG_HEADER" > /dev/null ||
+grep '^#define HAVE_LUTIMES' "$CONFIG_HEADER" > /dev/null ||
skip_test_ 'this system lacks the utimensat function'
ln -s no-such dangle || framework_failure
@@ -34,6 +35,7 @@ case $(stat --format=%y dangle) in
??:??:??.000000000) sleep 2;;
esac
+# Can't use --format=%x, as lstat() modifies atime on some platforms.
cp -Pp dangle d2 || framework_failure
stat --format=%y dangle > t1 || framework_failure
stat --format=%y d2 > t2 || framework_failure
diff --git a/tests/dd/skip-seek-past-file b/tests/dd/skip-seek-past-file
index cb36d08d9..937f99e17 100755
--- a/tests/dd/skip-seek-past-file
+++ b/tests/dd/skip-seek-past-file
@@ -22,7 +22,8 @@ if test "$VERBOSE" = yes; then
fi
. $srcdir/test-lib.sh
-eval $(getlimits) #for OFF_T limits
+require_sparse_support_ # for `truncate --size=$OFF_T_MAX`
+eval $(getlimits) # for OFF_T limits
fail=0
diff --git a/tests/dd/unblock b/tests/dd/unblock
new file mode 100755
index 000000000..6a3634cbb
--- /dev/null
+++ b/tests/dd/unblock
@@ -0,0 +1,59 @@
+#!/usr/bin/perl
+# Exercise dd's conv=unblock mode
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+use strict;
+
+(my $program_name = $0) =~ s|.*/||;
+
+# Turn off localization of executable's output.
+@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
+my $out = 'out';
+
+my @t =
+ (
+ # An empty test name signals that these are the arguments to use for the
+ # following tests.
+ ['', [qw (cbs=3 conv=unblock status=noxfer < )]],
+ ['0', '', ''],
+ ['1', "a\n ", "a\n\n\n"],
+ ['2', "a\n ", "a\n\n"],
+ ['3', "a ", "a\n"],
+ ['4', "a \n ", "a \n\n\n"],
+ ['5', "a \n", "a \n\n"],
+ ['6', "a ", "a\n\n"],
+ ['7', "a \n", "a\n\n\n"],
+ );
+
+my @Tests;
+my $args;
+foreach my $t (@t)
+ {
+ $t->[0] eq ''
+ and $args = $t->[1], next;
+
+ push @Tests, [$t->[0], @$args, {IN=>$t->[1]}, {OUT=>$t->[2]},
+ {ERR_SUBST=>'s/^\d+\+\d+ records (?:in|out)$//'},
+ {ERR=>"\n\n"}];
+ }
+
+my $save_temps = $ENV{DEBUG};
+my $verbose = $ENV{VERBOSE};
+
+my $prog = 'dd';
+my $fail = run_tests ($program_name, $prog, \@Tests, $save_temps, $verbose);
+exit $fail;
diff --git a/tests/id/no-context b/tests/id/no-context
new file mode 100755
index 000000000..f875ee0bc
--- /dev/null
+++ b/tests/id/no-context
@@ -0,0 +1,40 @@
+#!/bin/sh
+# With POSIXLY_CORRECT, id must not print context=...
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ id --version
+fi
+
+. $srcdir/test-lib.sh
+
+# We don't need selinux *FS* support to test id,
+# but this is as good a witness as any, in general.
+require_selinux_
+
+fail=0
+
+# Require the context=... part by default.
+id > out || fail=1
+grep context= out || fail=1
+
+# Require no context=... part in conforming mode.
+POSIXLY_CORRECT=1 id > out || fail=1
+grep context= out && fail=1
+
+Exit $fail
diff --git a/tests/ln/hard-to-sym b/tests/ln/hard-to-sym
new file mode 100755
index 000000000..510b57abf
--- /dev/null
+++ b/tests/ln/hard-to-sym
@@ -0,0 +1,82 @@
+#!/bin/sh
+# Tests for ln -L/-P.
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ ln --version
+fi
+
+. $srcdir/test-lib.sh
+
+fail=0
+
+# ===================================================
+# ensure -s silently overrides -L, -P
+touch a || framework_failure
+ln -L -s a symlink1 || fail=1
+ln -P -s symlink1 symlink2 || fail=1
+ln -s -L -P symlink2 symlink3 || fail=1
+
+# ===================================================
+# ensure that -L follows symlinks, and overrides -P
+ln -P -L symlink3 hard-to-a || fail=1
+ls=`ls -lG hard-to-a`x
+case "$ls" in
+ *'hard-to-ax') ;;
+ *'hard-to-a -> '*x) fail=1 ;;
+ *) framework_failure ;;
+esac
+
+# ===================================================
+# ensure that -P links (or at least duplicates) symlinks, and overrides -L
+ln -L -P symlink3 hard-to-3 || fail=1
+ls=`ls -lG hard-to-3`x
+case "$ls" in
+ *'hard-to-3 -> symlink2x') ;;
+ *'hard-to-3x') fail=1 ;;
+ *'hard-to-3 -> '*x) fail=1 ;;
+ *) framework_failure ;;
+esac
+
+# ===================================================
+# Create a hard link to a dangling symlink.
+ln -s /no-such-dir || framework_failure
+ln -L no-such-dir hard-to-dangle 2>err && fail=1
+case `cat err` in
+ *' accessing `no-such-dir'\':*) ;;
+ *) fail=1 ;;
+esac
+ln -P no-such-dir hard-to-dangle || fail=1
+
+# ===================================================
+# Create a hard link to a symlink to a directory.
+mkdir d || framework_failure
+ln -s d link-to-dir || framework_failure
+ln -L link-to-dir hard-to-dir-link 2>err && fail=1
+case `cat err` in
+ *': `link-to-dir'\'': hard link not allowed for directory'*) ;;
+ *) fail=1 ;;
+esac
+ln -P link-to-dir/ hard-to-dir-link 2>err && fail=1
+case `cat err` in
+ *': `link-to-dir/'\'': hard link not allowed for directory'*) ;;
+ *) fail=1 ;;
+esac
+ln -P link-to-dir hard-to-dir-link || fail=1
+
+Exit $fail
diff --git a/tests/ln/misc b/tests/ln/misc
index f13bd7bf3..d42d68a27 100755
--- a/tests/ln/misc
+++ b/tests/ln/misc
@@ -108,29 +108,6 @@ ln b b~ || framework_failure
ln -f --b=simple a b || fail=1
# ===================================================
-# determine if link(2) follows symlinks on this system
-touch a || framework_failure
-ln -s a symlink || framework_failure
-ln symlink hard-to-sym > /dev/null 2>&1 || framework_failure
-ls=`ls -lG hard-to-sym`x
-case "$ls" in
- *'hard-to-symx') link_follows_symlink=yes ;;
- *'hard-to-sym -> ax') link_follows_symlink=no ;;
- *) framework_failure ;;
-esac
-
-if test $link_follows_symlink = no; then
- # Create a hard link to a dangling symlink.
- # This is not portable. At least sunos4.1.4 and OpenBSD 2.3 fail this test.
- # They get this:
- # ln: cannot create hard link `hard-to-dangle' to `no-such-dir': \
- # No such file or directory
- #
- ln -s /no-such-dir || fail=1
- ln no-such-dir hard-to-dangle > /dev/null 2>&1 || fail=1
-fi
-rm -rf a symlink hard-to-sym hard-to-dangle
-# ===================================================
# Make sure ln can make simple backups.
# This was fixed in 4.0.34. Broken in 4.0r.
diff --git a/tests/ln/slash-decorated-nonexistent-dest b/tests/ln/slash-decorated-nonexistent-dest
new file mode 100755
index 000000000..afbbd060d
--- /dev/null
+++ b/tests/ln/slash-decorated-nonexistent-dest
@@ -0,0 +1,34 @@
+#!/bin/sh
+# ensure that touch f; ln -T f no-such-file/ does not mistakenly succeed
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ ln --version
+fi
+
+. $srcdir/test-lib.sh
+
+touch f || framework_failure
+
+fail=0
+
+# Before coreutils-7.6, this would succeed on Solaris 10
+ln -T f no-such-file/ && fail=1
+test -e no-such-file && fail=1
+
+Exit $fail
diff --git a/tests/ls/color-clear-to-eol b/tests/ls/color-clear-to-eol
index 92cf8a8ca..fd65ced08 100755
--- a/tests/ls/color-clear-to-eol
+++ b/tests/ls/color-clear-to-eol
@@ -30,11 +30,15 @@ e='\33'
color_code='0;31;42'
c_pre="$e[0m$e[${color_code}m"
c_post="$e[0m$e[K\n$e[m"
-printf "$c_pre$long_name$c_post" > exp || framework_failure
+printf "$c_pre$long_name$c_post\n" > exp || framework_failure
fail=0
env TERM=xterm COLUMNS=80 LS_COLORS="*.foo=$color_code" TIME_STYLE=+T \
ls -og --color=always $long_name > out || fail=1
+
+# Append a newline, to accommodate less-capable versions of sed.
+echo >> out || fail=1
+
sed 's/.*T //' out > k && mv k out
compare out exp || fail=1
diff --git a/tests/ls/color-dtype-dir b/tests/ls/color-dtype-dir
index 5381a6684..3ccf10eb8 100755
--- a/tests/ls/color-dtype-dir
+++ b/tests/ls/color-dtype-dir
@@ -50,4 +50,24 @@ EOF
compare out exp || fail=1
+rm exp
+
+# Turn off colors for other-writable dirs and ensure
+# we fall back to the color for standard directories.
+
+LS_COLORS="ow=:" ls --color=always > out || fail=1
+cat -A out > o1 || fail=1
+echo >> o1 || fail=1
+mv o1 out || fail=1
+
+cat <<\EOF > exp || fail=1
+^[[0m^[[01;34md^[[0m$
+^[[01;34mother-writable^[[0m$
+out$
+^[[37;44msticky^[[0m$
+^[[m
+EOF
+
+compare out exp || fail=1
+
Exit $fail
diff --git a/tests/ls/dangle b/tests/ls/dangle
index b2f8539b8..687d3dfba 100755
--- a/tests/ls/dangle
+++ b/tests/ls/dangle
@@ -26,6 +26,10 @@ fi
ln -s no-such-file dangle || framework_failure
mkdir -p dir/sub || framework_failure
ln -s dir slink-to-dir || framework_failure
+mkdir d || framework_failure
+ln -s no-such d/dangle || framework_failure
+printf '? dangle\n' > subdir_Li_exp || framework_failure
+printf 'total 0\n? dangle\n' > subdir_Ls_exp || framework_failure
fail=0
@@ -50,4 +54,14 @@ EOF
compare out exp || fail=1
+# Ensure that ls -Li prints "?" as the inode of a dangling symlink.
+rm -f out
+ls -Li d > out 2>/dev/null && fail=1
+compare out subdir_Li_exp || fail=1
+
+# Ensure that ls -Ls prints "?" as the allocation of a dangling symlink.
+rm -f out
+ls -Ls d > out 2>/dev/null && fail=1
+compare out subdir_Ls_exp || fail=1
+
Exit $fail
diff --git a/tests/ls/infloop b/tests/ls/infloop
index 419d7a9f7..b77f88cdb 100755
--- a/tests/ls/infloop
+++ b/tests/ls/infloop
@@ -1,7 +1,7 @@
#!/bin/sh
# show that the following no longer makes ls infloop
# mkdir loop; cd loop; ln -s ../loop sub; ls -RL
-
+# Also ensure ls exits with status = 2 in that case.
# Copyright (C) 2001-2002, 2004, 2006-2009 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
@@ -27,21 +27,22 @@ fi
mkdir loop || framework_failure
ln -s ../loop loop/sub || framework_failure
-fail=0
-
-ls -RL loop 2>err | head -n 7 > out
-# With an inf-looping ls, out will contain these 7 lines:
-cat <<EOF > bad
+cat <<\EOF > exp-out || framework_failure
loop:
sub
+EOF
-loop/sub:
-sub
-
-loop/sub/sub:
+cat <<\EOF > exp-err || framework_failure
+ls: loop/sub: not listing already-listed directory
EOF
-# Make sure we don't get the "bad" output.
-compare out bad > /dev/null 2>&1 && fail=1
+fail=0
+
+timeout 1 ls -RL loop 2>err > out
+# Ensure that ls exits with status 2 upon detecting a cycle
+test $? = 2 || fail=1
+
+compare err exp-err || fail=1
+compare out exp-out || fail=1
Exit $fail
diff --git a/tests/ls/stat-vs-dirent b/tests/ls/stat-vs-dirent
index 064ec12ae..9f2b14925 100755
--- a/tests/ls/stat-vs-dirent
+++ b/tests/ls/stat-vs-dirent
@@ -43,7 +43,10 @@ while :; do
# Make sure that they are the same.
# We know from experience that there may be mismatches on some
# buggy file systems, at mount points.
- if test "$d_ino" != "$st_ino"; then
+ # Note that when a directory contains only entries whose names
+ # start with ".", d_ino and file will both be empty. In that case,
+ # skip the test.
+ if test -n "$d_ino" && test "$d_ino" != "$st_ino"; then
echo "$0: test failed: $t/$file: d_ino($d_ino) != st_ino($st_ino)
This may indicate a flaw in your kernel or file system implementation.
The flaw isn't serious for coreutils, but it might break other tools,
diff --git a/tests/misc/cat-buf b/tests/misc/cat-buf
index fb9ae881e..11d553a2b 100755
--- a/tests/misc/cat-buf
+++ b/tests/misc/cat-buf
@@ -30,12 +30,17 @@ fi
# write separately.
mkfifo fifo || framework_failure
-echo '1' > exp
+fail=0
-dd count=1 if=fifo > out 2> err&
-(echo '1'; sleep .2; echo '2') | cat -v > fifo
-wait #for dd to complete
+echo 1 > exp
-compare out exp || fail=1
+dd count=1 if=fifo > out &
+(echo 1; sleep .5; echo 2) | cat -v > fifo
+wait # for dd to complete
+
+# Though unlikely, this test may fail because dd was starved
+# between opening the fifo and reading from it until after the
+# second echo. So ask to double check rather than failing.
+compare out exp || skip_test_ "possible test failure. Please verify."
Exit $fail
diff --git a/tests/misc/ls-misc b/tests/misc/ls-misc
index 63810a559..a734d5fb9 100755
--- a/tests/misc/ls-misc
+++ b/tests/misc/ls-misc
@@ -239,6 +239,8 @@ my @Tests =
],
);
+umask 022;
+
# Start with an unset LS_COLORS environment variable.
delete $ENV{LS_COLORS};
diff --git a/tests/misc/md5sum b/tests/misc/md5sum
index 2fb024d16..30edd9e7f 100755
--- a/tests/misc/md5sum
+++ b/tests/misc/md5sum
@@ -67,6 +67,16 @@ my @Tests =
['check-bsd3', '--check', '--status',
{IN=> {'f.md5' => "MD5 (f) = $degenerate\n"}},
{AUX=> {f=> 'bar'}}, {EXIT=> 1}],
+ ['check-openssl', '--check', {IN=> {'f.sha1' => "SHA1(f)= $degenerate\n"}},
+ {AUX=> {f=> ''}},
+ {ERR=>"md5sum: f.sha1: no properly formatted "
+ . "MD5 checksum lines found\n"},
+ {EXIT=> 1}],
+ ['check-openssl2', '--check', {IN=> {'f.md5' => "MD5(f)= $degenerate\n"}},
+ {AUX=> {f=> ''}}, {OUT=>"f: OK\n"}],
+ ['check-openssl3', '--check', '--status',
+ {IN=> {'f.md5' => "MD5(f)= $degenerate\n"}},
+ {AUX=> {f=> 'bar'}}, {EXIT=> 1}],
['bsd-segv', '--check', {IN=> {'z' => "MD5 ("}}, {EXIT=> 1},
{ERR=> "$prog: z: no properly formatted MD5 checksum lines found\n"}],
diff --git a/tests/misc/sha1sum b/tests/misc/sha1sum
index 3f09abaae..d084204d0 100755
--- a/tests/misc/sha1sum
+++ b/tests/misc/sha1sum
@@ -60,6 +60,17 @@ my @Tests =
['check-bsd3', '--check', '--status',
{IN=> {'f.sha1' => "SHA1 (f) = $sha_degenerate\n"}},
{AUX=> {f=> 'bar'}}, {EXIT=> 1}],
+ ['check-openssl', '--check', {IN=> {'f.md5' => "MD5(f)= $sha_degenerate\n"}},
+ {AUX=> {f=> ''}},
+ {ERR=>"sha1sum: f.md5: no properly formatted "
+ . "SHA1 checksum lines found\n"},
+ {EXIT=> 1}],
+ ['check-openssl2', '--check',
+ {IN=> {'f.sha1' => "SHA1(f)= $sha_degenerate\n"}},
+ {AUX=> {f=> ''}}, {OUT=>"f: OK\n"}],
+ ['check-openssl3', '--check', '--status',
+ {IN=> {'f.sha1' => "SHA1(f)= $sha_degenerate\n"}},
+ {AUX=> {f=> 'bar'}}, {EXIT=> 1}],
['bsd-segv', '--check', {IN=> {'z' => "SHA1 ("}}, {EXIT=> 1},
{ERR=> "$prog: z: no properly formatted SHA1 checksum lines found\n"}],
);
diff --git a/tests/misc/sort-continue b/tests/misc/sort-continue
index 1b0ef431c..8b206f35c 100755
--- a/tests/misc/sort-continue
+++ b/tests/misc/sort-continue
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
# Tests for file descriptor exhaustion.
# Copyright (C) 2009 Free Software Foundation, Inc.
diff --git a/tests/misc/stat-hyphen b/tests/misc/stat-hyphen
new file mode 100755
index 000000000..f0757fe39
--- /dev/null
+++ b/tests/misc/stat-hyphen
@@ -0,0 +1,35 @@
+#!/bin/sh
+# demonstrate that stat - works and stat -f - does not.
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ stat --version
+fi
+
+. $srcdir/test-lib.sh
+
+printf -- '-\n' > exp || framework_failure
+touch f || framework_failure
+
+fail=0
+stat --format=%n - < f > out || fail=1
+stat -f - < f && fail=1
+
+compare out exp || fail=1
+
+Exit $fail
diff --git a/tests/misc/stat-slash b/tests/misc/stat-slash
new file mode 100755
index 000000000..cda94c544
--- /dev/null
+++ b/tests/misc/stat-slash
@@ -0,0 +1,49 @@
+#!/bin/sh
+# demonstrate that stat handles trailing slashes correctly
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ stat --version
+fi
+
+. $srcdir/test-lib.sh
+
+touch file || framework_failure
+mkdir dir || framework_failure
+ln -s file link1 || framework_failure
+ln -s dir link2 || framework_failure
+
+cat <<EOF > exp || framework_failure
+link1
+symbolic link
+directory
+directory
+EOF
+
+fail=0
+# This failed on Solaris 9 for coreutils 8.0.
+stat --format=%n link1 > out || fail=1
+stat --format=%n link1/ >> out && fail=1
+
+stat --format=%F link2 >> out || fail=1
+stat -L --format=%F link2 >> out || fail=1
+stat --format=%F link2/ >> out || fail=1
+
+compare out exp || fail=1
+
+Exit $fail
diff --git a/tests/misc/xattr b/tests/misc/xattr
index a27e1f6d9..fcf7ceb79 100755
--- a/tests/misc/xattr
+++ b/tests/misc/xattr
@@ -29,7 +29,7 @@ fi
# Skip this test if cp was built without xattr support:
touch src dest || framework_failure
-cp --preserve=xattr -n src dest 2>/dev/null \
+cp --preserve=xattr -n src dest \
|| skip_test_ "coreutils built without xattr support"
# this code was taken from test mv/backup-is-src
@@ -46,13 +46,13 @@ xattr_pair="$xattr_name=\"$xattr_value\""
# create new file and check its xattrs
touch a || framework_failure
getfattr -d a >out_a || skip_test_ "failed to get xattr of file"
-grep -F "$xattr_pair" out_a >/dev/null && framework_failure
+grep -F "$xattr_pair" out_a && framework_failure
# try to set user xattr on file
setfattr -n "$xattr_name" -v "$xattr_value" a >out_a \
|| skip_test_ "failed to set xattr of file"
getfattr -d a >out_a || skip_test_ "failed to get xattr of file"
-grep -F "$xattr_pair" out_a >/dev/null \
+grep -F "$xattr_pair" out_a \
|| skip_test_ "failed to set xattr of file"
fail=0
@@ -60,36 +60,50 @@ fail=0
# cp should not preserve xattr by default
cp a b || fail=1
getfattr -d b >out_b || skip_test_ "failed to get xattr of file"
-grep -F "$xattr_pair" out_b >/dev/null && fail=1
+grep -F "$xattr_pair" out_b && fail=1
# test if --preserve=xattr option works
cp --preserve=xattr a b || fail=1
getfattr -d b >out_b || skip_test_ "failed to get xattr of file"
-grep -F "$xattr_pair" out_b >/dev/null || fail=1
+grep -F "$xattr_pair" out_b || fail=1
#test if --preserve=all option works
cp --preserve=all a c || fail=1
getfattr -d c >out_c || skip_test_ "failed to get xattr of file"
-grep -F "$xattr_pair" out_c >/dev/null || fail=1
+grep -F "$xattr_pair" out_c || fail=1
#test if -a option works without any diagnostics
cp -a a d 2>err && test -s err && fail=1
getfattr -d d >out_d || skip_test_ "failed to get xattr of file"
-grep -F "$xattr_pair" out_d >/dev/null || fail=1
+grep -F "$xattr_pair" out_d || fail=1
+
+#test if --preserve=xattr works even for files without write access
+chmod a-w a || framework_failure
+rm -f e
+cp --preserve=xattr a e || fail=1
+getfattr -d e >out_e || skip_test_ "failed to get xattr of file"
+grep -F "$xattr_pair" out_e || fail=1
+
+#Ensure that permission bits are preserved, too.
+src_perm=$(stat --format=%a a)
+dst_perm=$(stat --format=%a e)
+test "$dst_perm" = "$src_perm" || fail=1
+
+chmod u+w a || framework_failure
rm b || framework_failure
# install should never preserve xattr
ginstall a b || fail=1
getfattr -d b >out_b || skip_test_ "failed to get xattr of file"
-grep -F "$xattr_pair" out_b >/dev/null && fail=1
+grep -F "$xattr_pair" out_b && fail=1
# mv should preserve xattr when renaming within a file system.
# This is implicitly done by rename () and doesn't need explicit
# xattr support in mv.
mv a b || fail=1
getfattr -d b >out_b || skip_test_ "failed to get xattr of file"
-grep -F "$xattr_pair" out_b >/dev/null || cat >&2 <<EOF
+grep -F "$xattr_pair" out_b || cat >&2 <<EOF
=================================================================
$0: WARNING!!!
rename () does not preserve extended attributes
@@ -99,18 +113,18 @@ EOF
# try to set user xattr on file on other partition
test_mv=1
touch "$b_other" || framework_failure
-setfattr -n "$xattr_name" -v "$xattr_value" "$b_other" >out_a 2>/dev/null \
+setfattr -n "$xattr_name" -v "$xattr_value" "$b_other" >out_a \
|| test_mv=0
-getfattr -d "$b_other" >out_b 2>/dev/null || test_mv=0
-grep -F "$xattr_pair" out_b >/dev/null || test_mv=0
+getfattr -d "$b_other" >out_b || test_mv=0
+grep -F "$xattr_pair" out_b || test_mv=0
rm -f "$b_other" || framework_failure
if test $test_mv -eq 1; then
# mv should preserve xattr when copying content from one partition to another
mv b "$b_other" || fail=1
- getfattr -d "$b_other" >out_b 2>/dev/null ||
+ getfattr -d "$b_other" >out_b ||
skip_test_ "failed to get xattr of file"
- grep -F "$xattr_pair" out_b >/dev/null || fail=1
+ grep -F "$xattr_pair" out_b || fail=1
else
cat >&2 <<EOF
=================================================================
diff --git a/tests/readlink/can-f b/tests/readlink/can-f
index 8a000f8e9..a702ba990 100755
--- a/tests/readlink/can-f
+++ b/tests/readlink/can-f
@@ -38,6 +38,7 @@ ln -s regfile link1 || framework_failure
ln -s subdir link2 || framework_failure
ln -s missing link3 || framework_failure
ln -s subdir/missing link4 || framework_failure
+ln -s link5 link5 || framework_failure
cd "$pwd/$tmp/removed" || framework_failure
@@ -73,14 +74,14 @@ for p in "" "$pwd/$tmp/"; do
v=`readlink -f "${p}subdir/more"` || fail=1
test "$v" = "$my_pwd/$tmp/subdir/more" || fail=1
- v=`readlink -f "${p}./subdir/more/"` && fail=1
- test -z "$v" || fail=1
+ v=`readlink -f "${p}./subdir/more/"` || fail=1
+ test "$v" = "$my_pwd/$tmp/subdir/more" || fail=1
v=`readlink -f "${p}missing"` || fail=1
test "$v" = "$my_pwd/$tmp/missing" || fail=1
- v=`readlink -f "${p}./missing/"` && fail=1
- test -z "$v" || fail=1
+ v=`readlink -f "${p}./missing/"` || fail=1
+ test "$v" = "$my_pwd/$tmp/missing" || fail=1
v=`readlink -f "${p}missing/more"` && fail=1
test -z "$v" || fail=1
@@ -109,8 +110,8 @@ for p in "" "$pwd/$tmp/"; do
v=`readlink -f "${p}link2/more"` || fail=1
test "$v" = "$my_pwd/$tmp/subdir/more" || fail=1
- v=`readlink -f "${p}./link2/more/"` && fail=1
- test -z "$v" || fail=1
+ v=`readlink -f "${p}./link2/more/"` || fail=1
+ test "$v" = "$my_pwd/$tmp/subdir/more" || fail=1
v=`readlink -f "${p}link2/more/more2"` && fail=1
test -z "$v" || fail=1
@@ -121,8 +122,8 @@ for p in "" "$pwd/$tmp/"; do
v=`readlink -f "${p}link3"` || fail=1
test "$v" = "$my_pwd/$tmp/missing" || fail=1
- v=`readlink -f "${p}./link3/"` && fail=1
- test -z "$v" || fail=1
+ v=`readlink -f "${p}./link3/"` || fail=1
+ test "$v" = "$my_pwd/$tmp/missing" || fail=1
v=`readlink -f "${p}link3/more"` && fail=1
test -z "$v" || fail=1
@@ -133,11 +134,26 @@ for p in "" "$pwd/$tmp/"; do
v=`readlink -f "${p}link4"` || fail=1
test "$v" = "$my_pwd/$tmp/subdir/missing" || fail=1
- v=`readlink -f "${p}./link4/"` && fail=1
- test -z "$v" || fail=1
+ v=`readlink -f "${p}./link4/"` || fail=1
+ test "$v" = "$my_pwd/$tmp/subdir/missing" || fail=1
v=`readlink -f "${p}link4/more"` && fail=1
test -z "$v" || fail=1
+
+ v=`readlink -f "${p}./link4/more"` && fail=1
+ test -z "$v" || fail=1
+
+ v=`readlink -f "${p}link5"` && fail=1
+ test -z "$v" || fail=1
+
+ v=`readlink -f "${p}./link5/"` && fail=1
+ test -z "$v" || fail=1
+
+ v=`readlink -f "${p}link5/more"` && fail=1
+ test -z "$v" || fail=1
+
+ v=`readlink -f "${p}./link5/more"` && fail=1
+ test -z "$v" || fail=1
done
Exit $fail
diff --git a/tests/tail-2/append-only b/tests/tail-2/append-only
index 0b4a95958..2d38d4f0f 100755
--- a/tests/tail-2/append-only
+++ b/tests/tail-2/append-only
@@ -37,9 +37,12 @@ fi
fail=0
-sleep 1 &
-pid=$!
-tail --pid=$pid -f f || fail=1
+for inotify in ---disable-inotify ''; do
+ sleep 1 &
+ pid=$!
+ tail --pid=$pid -f $inotify f || fail=1
+done
+
chattr -a f 2>/dev/null
Exit $fail
diff --git a/tests/tail-2/assert b/tests/tail-2/assert
index 623c3684f..416f206a1 100755
--- a/tests/tail-2/assert
+++ b/tests/tail-2/assert
@@ -42,13 +42,9 @@ tail_pid=$!
echo sleeping for 7 seconds...
-# Wait for the backgrounded `tail' to start before removing foo.
+# Give the backgrounded `tail' a chance to start before removing foo.
# Otherwise, without --retry, tail wouldn't try to open `foo' again.
-while :; do
- env kill -0 $tail_pid && break
- echo sleep .1
- sleep .1
-done
+sleep 1
rm -f foo
sleep 6
diff --git a/tests/tail-2/flush-initial b/tests/tail-2/flush-initial
new file mode 100755
index 000000000..e0d79fe48
--- /dev/null
+++ b/tests/tail-2/flush-initial
@@ -0,0 +1,44 @@
+#!/bin/sh
+# inotify-based tail -f didn't flush its initial output before blocking
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ tail --version
+fi
+
+. $srcdir/test-lib.sh
+
+fail=0
+echo line > in || fail=1
+# Output should be buffered since we're writing to file
+# so we're depending on the flush to write out
+tail -f in > out &
+tail_pid=$!
+
+# Wait for 1 second for the file to be flushed.
+for i in $(seq 10); do
+ test -s out && break
+ echo sleep .1s
+ sleep .1
+done
+
+test -s out || fail=1
+
+kill $tail_pid
+
+Exit $fail
diff --git a/tests/tail-2/follow-stdin b/tests/tail-2/follow-stdin
new file mode 100755
index 000000000..46e7ce80f
--- /dev/null
+++ b/tests/tail-2/follow-stdin
@@ -0,0 +1,41 @@
+#!/bin/sh
+# tail -f - would fail with the initial inotify implementation
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ tail --version
+fi
+
+. $srcdir/test-lib.sh
+
+echo line > exp || framework_failure
+echo line > in || framework_failure
+
+fail=0
+timeout 1 tail -f < in > out 2> err
+
+# tail from coreutils-7.5 would fail
+test $? = 124 || fail=1
+
+# Ensure there was no error output.
+test -s err && fail=1
+
+# Ensure there was
+compare out exp || fail=1
+
+Exit $fail
diff --git a/tests/tail-2/infloop-1 b/tests/tail-2/infloop-1
index 6a456deac..72d51d975 100755
--- a/tests/tail-2/infloop-1
+++ b/tests/tail-2/infloop-1
@@ -27,16 +27,22 @@ yes > t &
yes_pid=$!
while :; do
test -s t && break
+ sleep .1
done
tail -n 1 t &
tail_pid=$!
kill $yes_pid
# This test is racy, and can fail under unusual circumstances.
-# On a busy system, "yes" will fail to write
-# (and hence fail to be killed by SIGPIPE) in that 1-second interval.
+# On a very busy system, tail will fail to notice that $yes_pid is gone.
# Then the following kill will succeed and cause this test to fail.
-sleep 1
+
+# Wait for up to 3 seconds for tail to detect the death of $yes_pid.
+for i in $(seq 30); do
+ kill -0 $tail_pid || break
+ echo sleep 0.1s
+ sleep .1
+done
fail=0
kill $tail_pid && fail=1 || :
diff --git a/tests/tail-2/pid b/tests/tail-2/pid
index a797666fe..760e289bc 100755
--- a/tests/tail-2/pid
+++ b/tests/tail-2/pid
@@ -22,32 +22,35 @@ if test "$VERBOSE" = yes; then
fi
. $srcdir/test-lib.sh
+getlimits_
touch here || framework_failure
fail=0
-# Use tail itself to create a background process to monitor.
-tail -f here &
-bg_pid=$!
-
-# Ensure that tail --pid=PID does not exit when PID is alive.
-timeout 1 tail -s.1 -f here --pid=$bg_pid
-test $? = 124 || fail=1
-
-# Cleanup background process
-kill $bg_pid
-
-# Ensure that tail --pid=PID exits successfully when PID is dead.
-# Use an unlikely-to-be-live PID
-getlimits_
-timeout 1 tail -s.1 --pid=$PID_T_MAX -f /dev/null
-ret=$?
-test $ret = 124 && skip_test_ "pid $PID_T_MAX present"
-test $ret = 0 || fail=1
-
-# Ensure fractional sleep parameter is honored with --pid
-timeout 1 tail -s.1 -f /dev/null --pid=$PID_T_MAX
-test $? = 124 && fail=1
+for inotify in ---disable-inotify ''; do
+ # Use tail itself to create a background process to monitor,
+ # which will auto exit when "here" is removed.
+ tail -f $inotify here &
+ bg_pid=$!
+
+ # Ensure that tail --pid=PID does not exit when PID is alive.
+ timeout 1 tail -f -s.1 --pid=$bg_pid $inotify here
+ test $? = 124 || fail=1
+
+ # Cleanup background process
+ kill $bg_pid
+
+ # Ensure that tail --pid=PID exits with success status when PID is dead.
+ # Use an unlikely-to-be-live PID
+ timeout 3 tail -f -s.1 --pid=$PID_T_MAX $inotify /dev/null
+ ret=$?
+ test $ret = 124 && skip_test_ "pid $PID_T_MAX present or tail too slow"
+ test $ret = 0 || fail=1
+
+ # Ensure tail doesn't wait for data when PID is dead
+ timeout 3 tail -f -s10 --pid=$PID_T_MAX $inotify /dev/null
+ test $? = 124 && fail=1
+done
Exit $fail
diff --git a/tests/tail-2/pipe-f b/tests/tail-2/pipe-f
new file mode 100755
index 000000000..b9f6ae389
--- /dev/null
+++ b/tests/tail-2/pipe-f
@@ -0,0 +1,32 @@
+#!/bin/sh
+# ensure that :|tail -f doesn't hang, per POSIX
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ tail --version
+fi
+
+. $srcdir/test-lib.sh
+
+fail=0
+echo foo | timeout 2 tail -f -c3 > out || fail=1
+echo oo > exp || fail=1
+
+compare out exp || fail=1
+
+Exit $fail
diff --git a/tests/tail-2/pipe-f2 b/tests/tail-2/pipe-f2
new file mode 100755
index 000000000..406ebcc91
--- /dev/null
+++ b/tests/tail-2/pipe-f2
@@ -0,0 +1,37 @@
+#!/bin/sh
+# Ensure that "tail -f fifo" tails indefinitely.
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ tail --version
+fi
+
+. $srcdir/test-lib.sh
+
+mkfifo_or_skip_ fifo
+
+echo 1 > fifo &
+echo 1 > exp || framework_failure
+
+fail=0
+timeout 1 tail -f fifo > out
+test $? = 124 || fail=1
+
+compare out exp || fail=1
+
+Exit $fail
diff --git a/tests/tail-2/tail-n0f b/tests/tail-2/tail-n0f
index fce7ed16e..ddfbe6645 100755
--- a/tests/tail-2/tail-n0f
+++ b/tests/tail-2/tail-n0f
@@ -35,17 +35,19 @@ echo anything > nonempty || framework_failure
fail=0
-for file in empty nonempty; do
- for c_or_n in c n; do
- tail --sleep=4 -${c_or_n} 0 -f $file &
- pid=$!
- sleep .5
- state=$(get_process_status_ $pid)
- case $state in
- S*) ;;
- *) echo $0: process in unexpected state: $state 1>&2; fail=1 ;;
- esac
- kill $pid
+for inotify in ---disable-inotify ''; do
+ for file in empty nonempty; do
+ for c_or_n in c n; do
+ tail --sleep=4 -${c_or_n} 0 -f $inotify $file &
+ pid=$!
+ sleep .5
+ state=$(get_process_status_ $pid)
+ case $state in
+ S*) ;;
+ *) echo $0: process in unexpected state: $state 1>&2; fail=1 ;;
+ esac
+ kill $pid
+ done
done
done
diff --git a/tests/tail-2/wait b/tests/tail-2/wait
index a5f189fe0..62498d5dc 100755
--- a/tests/tail-2/wait
+++ b/tests/tail-2/wait
@@ -30,43 +30,48 @@ touch k || framework_failure
fail=0
-timeout 1 tail -s0.1 -f not_here
-test $? = 124 && fail=1
-
-if test ! -r unreadable; then # can't test this when root
- timeout 1 tail -s0.1 -f unreadable
+for inotify in ---disable-inotify ''; do
+ timeout 1 tail -s0.1 -f $inotify not_here
test $? = 124 && fail=1
-fi
-timeout 1 tail -s0.1 -f here 2>tail.err
-test $? = 124 || fail=1
+ if test ! -r unreadable; then # can't test this when root
+ timeout 1 tail -s0.1 -f $inotify unreadable
+ test $? = 124 && fail=1
+ fi
-# `tail -F' must wait in any case.
+ timeout 1 tail -s0.1 -f $inotify here 2>tail.err
+ test $? = 124 || fail=1
-timeout 1 tail -s0.1 -F here 2>>tail.err
-test $? = 124 || fail=1
+ # `tail -F' must wait in any case.
-if test ! -r unreadable; then # can't test this when root
- timeout 1 tail -s0.1 -F unreadable
+ timeout 1 tail -s0.1 -F $inotify here 2>>tail.err
test $? = 124 || fail=1
-fi
-timeout 1 tail -s0.1 -F not_here
-test $? = 124 || fail=1
-
-test -s tail.err && fail=1
-
-tail -s.1 --max-unchanged-stats=2 -F k > tail.out &
-pid=$!
-sleep .5
-mv k l
-sleep .5
-touch k
-mv k l
-sleep .5
-echo NO >> l
-sleep .5
-kill $pid
-test -s tail.out && fail=1
+ if test ! -r unreadable; then # can't test this when root
+ timeout 1 tail -s0.1 -F $inotify unreadable
+ test $? = 124 || fail=1
+ fi
+
+ timeout 1 tail -s0.1 -F $inotify not_here
+ test $? = 124 || fail=1
+
+
+ test -s tail.err && fail=1
+ :>tail.err
+
+
+ tail -s.1 --max-unchanged-stats=2 -F $inotify k > tail.out &
+ pid=$!
+ sleep .5
+ mv k l
+ sleep .5
+ touch k
+ mv k l
+ sleep .5
+ echo NO >> l
+ sleep .5
+ kill $pid
+ test -s tail.out && fail=1
+done
Exit $fail
diff --git a/tests/touch/60-seconds b/tests/touch/60-seconds
new file mode 100755
index 000000000..b13ad06ff
--- /dev/null
+++ b/tests/touch/60-seconds
@@ -0,0 +1,38 @@
+#!/bin/sh
+# touch -t would mistakenly reject a time specifying "60" seconds
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+ set -x
+ touch --version
+fi
+
+. $srcdir/test-lib.sh
+
+echo 60 > exp || framework_failure
+
+fail=0
+
+# Before coreutils-7.7, this would fail, complaining of
+# an `invalid date format'. Specifying 60 seconds *is* valid.
+TZ=UTC0 touch -t 197001010000.60 f || fail=1
+
+stat --p='%Y\n' f > out || fail=1
+
+compare out exp || fail=1
+
+Exit $fail