Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

383 Commits   1 Branch   1 Tag
Index: Makefile
===================================================================
--- Makefile	(nonexistent)
+++ Makefile	(revision 5)
@@ -0,0 +1,60 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/GNU/coreutils
+
+versions    = 8.32
+pkgname     = coreutils
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+patches     = $(CURDIR)/patches/coreutils-8.32-uname.patch
+patches    += $(CURDIR)/patches/coreutils-8.32-syscall64-ls.patch
+patches    += $(CURDIR)/patches/coreutils-8.32-no-ls-quoting.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-8.32-uname-patch         ; ./create.patch.sh ) ; \
+	 ( cd create-8.32-syscall64-ls-patch  ; ./create.patch.sh ) ; \
+	 ( cd create-8.32-no-ls-quoting-patch ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: create-8.32-no-ls-quoting-patch/coreutils-8.32-new/NEWS
===================================================================
--- create-8.32-no-ls-quoting-patch/coreutils-8.32-new/NEWS	(nonexistent)
+++ create-8.32-no-ls-quoting-patch/coreutils-8.32-new/NEWS	(revision 5)
@@ -0,0 +1,5147 @@
+GNU coreutils NEWS                                    -*- outline -*-
+
+* Noteworthy changes in release 8.32 (2020-03-05) [stable]
+
+** Bug fixes
+
+  cp now copies /dev/fd/N correctly on platforms like Solaris where
+  it is a character-special file whose minor device number is N.
+  [bug introduced in fileutils-4.1.6]
+
+  dd conv=fdatasync no longer reports a "Bad file descriptor" error
+  when fdatasync is interrupted, and dd now retries interrupted calls
+  to close, fdatasync, fstat and fsync instead of incorrectly
+  reporting an "Interrupted system call" error.
+  [bugs introduced in coreutils-6.0]
+
+  df now correctly parses the /proc/self/mountinfo file for unusual entries
+  like ones with '\r' in a field value ("mount -t tmpfs tmpfs /foo$'\r'bar"),
+  when the source field is empty ('mount -t tmpfs "" /mnt'), and when the
+  filesystem type contains characters like a blank which need escaping.
+  [bugs introduced in coreutils-8.24 with the introduction of reading
+   the /proc/self/mountinfo file]
+
+  factor again outputs immediately when stdout is a tty but stdin is not.
+  [bug introduced in coreutils-8.24]
+
+  ln works again on old systems without O_DIRECTORY support (like Solaris 10),
+  and on systems where symlink ("x", ".") fails with errno == EINVAL
+  (like Solaris 10 and Solaris 11).
+  [bug introduced in coreutils-8.31]
+
+  rmdir --ignore-fail-on-non-empty now works correctly for directories
+  that fail to be removed due to permission issues.  Previously the exit status
+  was reversed, failing for non empty and succeeding for empty directories.
+  [bug introduced in coreutils-6.11]
+
+  'shuf -r -n 0 file' no longer mistakenly reads from standard input.
+  [bug introduced with the --repeat feature in coreutils-8.22]
+
+  split no longer reports a "output file suffixes exhausted" error
+  when the specified number of files is evenly divisible by 10, 16, 26,
+  for --numeric, --hex, or default alphabetic suffixes respectively.
+  [bug introduced in coreutils-8.24]
+
+  seq no longer prints an extra line under certain circumstances (such as
+  'seq -f "%g " 1000000 1000000').
+  [bug introduced in coreutils-6.10]
+
+** Changes in behavior
+
+  Several programs now check that numbers end properly.  For example,
+  'du -d 1x' now reports an error instead of silently ignoring the 'x'.
+  Affected programs and options include du -d, expr's numeric operands
+  on non-GMP builds, install -g and -o, ls's TABSIZE environment
+  variable, mknod b and c, ptx -g and -w, shuf -n, and sort --batch-size
+  and --parallel.
+
+  date now parses military time zones in accordance with common usage:
+    "A" to "M"  are equivalent to UTC+1 to UTC+12
+    "N" to "Y"  are equivalent to UTC-1 to UTC-12
+    "Z" is "zulu" time (UTC).
+  For example, 'date -d "09:00B" is now equivalent to 9am in UTC+2 time zone.
+  Previously, military time zones were parsed according to the obsolete
+  rfc822, with their value negated (e.g., "B" was equivalent to UTC-2).
+  [The old behavior was introduced in sh-utils 2.0.15 ca. 1999, predating
+  coreutils package.]
+
+  ls issues an error message on a removed directory, on GNU/Linux systems.
+  Previously no error and no entries were output, and so indistinguishable
+  from an empty directory, with default ls options.
+
+  uniq no longer uses strcoll() to determine string equivalence,
+  and so will operate more efficiently and consistently.
+
+** New Features
+
+  ls now supports the --time=birth option to display and sort by
+  file creation time, where available.
+
+  od --skip-bytes now can use lseek even if the input is not a regular
+  file, greatly improving performance in some cases.
+
+  stat(1) supports a new --cached= option, used on systems with statx(2)
+  to control cache coherency of file system attributes,
+  useful on network file systems.
+
+** Improvements
+
+  stat and ls now use the statx() system call where available, which can
+  operate more efficiently by only retrieving requested attributes.
+
+  stat and tail now know about the "binderfs", "dma-buf-fs", "erofs",
+  "ppc-cmm-fs", and "z3fold" file systems.
+  stat -f -c%T now reports the file system type, and tail -f uses inotify.
+
+** Build-related
+
+  gzip-compressed tarballs are distributed once again
+
+
+* Noteworthy changes in release 8.31 (2019-03-10) [stable]
+
+** Bug fixes
+
+  'base64 a b' now correctly diagnoses 'b' as the extra operand, not 'a'.
+  [bug introduced in coreutils-5.3.0]
+
+  When B already exists, 'cp -il A B' no longer immediately fails
+  after asking the user whether to proceed.
+  [This bug was present in "the beginning".]
+
+  df no longer corrupts displayed multibyte characters on macOS.
+  [bug introduced with coreutils-8.18]
+
+  seq no longer outputs inconsistent decimal point characters
+  for the last number, when locales are misconfigured.
+  [bug introduced in coreutils-7.0]
+
+  shred, sort, and split no longer falsely report ftruncate errors
+  when outputting to less-common file types.  For example, the shell
+  command 'sort /dev/null -o /dev/stdout | cat' no longer fails with
+  an "error truncating" diagnostic.
+  [bug was introduced with coreutils-8.18 for sort and split, and
+   (for shared memory objects only) with fileutils-4.1 for shred]
+
+  sync no longer fails for write-only file arguments.
+  [bug introduced with argument support to sync in coreutils-8.24]
+
+  'tail -f file | filter' no longer exits immediately on AIX.
+  [bug introduced in coreutils-8.28]
+
+  'tail -f file | filter' no longer goes into an infinite loop
+  if filter exits and SIGPIPE is ignored.
+  [bug introduced in coreutils-8.28]
+
+** Changes in behavior
+
+  cksum, dd, hostid, hostname, link, logname, sleep, tsort, unlink,
+  uptime, users, whoami, yes: now always process --help and --version options,
+  regardless of any other arguments present before any optional '--'
+  end-of-options marker.
+
+  nohup now processes --help and --version as first options even if other
+  parameters follow.
+
+  'yes a -- b' now outputs 'a b' instead of including the end-of-options
+  marker as before: 'a -- b'.
+
+  echo now always processes backslash escapes when the POSIXLY_CORRECT
+  environment variable is set.
+
+  When possible 'ln A B' now merely links A to B and reports an error
+  if this fails, instead of statting A and B before linking.  This
+  uses fewer system calls and avoids some races.  The old statting
+  approach is still used in situations where hard links to directories
+  are allowed (e.g., NetBSD when superuser).
+
+  ls --group-directories-first will also group symlinks to directories.
+
+  'test -a FILE' is not supported anymore.  Long ago, there were concerns about
+  the high probability of humans confusing the -a primary with the -a binary
+  operator, so POSIX changed this to 'test -e FILE'.  Scripts using it were
+  already broken and non-portable; the -a unary operator was never documented.
+
+  wc now treats non breaking space characters as word delimiters
+  unless the POSIXLY_CORRECT environment variable is set.
+
+** New features
+
+  id now supports specifying multiple users.
+
+  'date' now supports the '+' conversion specification flag,
+  introduced in POSIX.1-2017.
+
+  printf, seq, sleep, tail, and timeout now accept floating point
+  numbers in either the current or the C locale.  For example, if the
+  current locale's decimal point is ',', 'sleep 0,1' and 'sleep 0.1'
+  now mean the same thing.  Previously, these commands accepted only
+  C-locale syntax with '.' as the decimal point.  The new behavior is
+  more compatible with other implementations in non-C locales.
+
+  test now supports the '-N FILE' unary operator (like e.g. bash) to check
+  whether FILE exists and has been modified since it was last read.
+
+  env now supports '--default-signal[=SIG]', '--ignore-signal[=SIG]', and
+  '--block-signal[=SIG], to setup signal handling before executing a program.
+
+  env now supports '--list-signal-handling' to indicate non-default
+  signal handling before executing a program.
+
+** New commands
+
+  basenc is added to complement existing base64,base32 commands,
+  and encodes and decodes printable text using various common encodings:
+  base64,base64url,base32,base32hex,base16,base2,z85.
+
+** Improvements
+
+  ls -l now better aligns abbreviated months containing digits,
+  which is common in Asian locales.
+
+  stat and tail now know about the "sdcardfs" file system on Android.
+  stat -f -c%T now reports the file system type, and tail -f uses inotify.
+
+  stat now prints file creation time when supported by the file system,
+  on GNU Linux systems with glibc >= 2.28 and kernel >= 4.11.
+
+
+* Noteworthy changes in release 8.30 (2018-07-01) [stable]
+
+** Bug fixes
+
+  'cp --symlink SRC DST' will again correctly validate DST.
+  If DST is a regular file and SRC is a symlink to DST,
+  then cp will no longer allow that operation to clobber DST.
+  Also with -d, if DST is a symlink, then it can always be replaced,
+  even if it points to SRC on a separate device.
+  [bugs introduced with coreutils-8.27]
+
+  'cp -n -u' and 'mv -n -u' now consistently ignore the -u option.
+  Previously, this option combination suffered from race conditions
+  that caused -u to sometimes override -n.
+  [bug introduced with coreutils-7.1]
+
+  'cp -a --no-preserve=mode' now sets appropriate default permissions
+  for non regular files like fifos and character device nodes etc.,
+  and leaves mode bits of existing files unchanged.
+  Previously it would have set executable bits on created special files,
+  and set mode bits for existing files as if they had been created.
+  [bug introduced with coreutils-8.20]
+
+  'cp --remove-destination file symlink' now removes the symlink
+  even if it can't be traversed.
+  [bug introduced with --remove-destination in fileutils-4.1.1]
+
+  ls no longer truncates the abbreviated month names that have a
+  display width between 6 and 12 inclusive.  Previously this would have
+  output ambiguous months for Arabic or Catalan locales.
+
+  'ls -aA' is now equivalent to 'ls -A', since -A now overrides -a.
+  [bug introduced in coreutils-5.3.0]
+
+  'mv -n A B' no longer suffers from a race condition that can
+  overwrite a simultaneously-created B.  This bug fix requires
+  platform support for the renameat2 or renameatx_np syscalls, found
+  in recent Linux and macOS kernels.  As a side effect, 'mv -n A A'
+  now silently does nothing if A exists.
+  [bug introduced with coreutils-7.1]
+
+** Changes in behavior
+
+  'cp --force file symlink' now removes the symlink even if
+  it is self referential.
+
+  ls --color now matches file extensions case insensitively.
+
+** New features
+
+  cp --reflink now supports --reflink=never to enforce a standard copy.
+
+  env supports a new -v/--debug option to show verbose information about
+  each processing step.
+
+  env supports a new -S/--split-string=S option to split a single argument
+  string into multiple arguments. Used to pass multiple arguments in scripts
+  (shebang lines).
+
+  md5sum accepts a new option: --zero (-z) to delimit the output lines with a
+  NUL instead of a newline character.  This also disables file name escaping.
+  This also applies to sha*sum and b2sum.
+
+  rm --preserve-root now supports the --preserve-root=all option to
+  reject any command line argument that is mounted to a separate file system.
+
+** Improvements
+
+  cut supports line lengths up to the max file size on 32 bit systems.
+  Previously only offsets up to SIZE_MAX-1 were supported.
+
+  stat and tail now know about the "exfs" file system, which is a
+  version of XFS.  stat -f --format=%T now reports the file system type,
+  and tail -f uses inotify.
+
+  wc avoids redundant processing of ASCII text in multibyte locales,
+  which is especially significant on macOS.
+
+
+* Noteworthy changes in release 8.29 (2017-12-27) [stable]
+
+** Bug fixes
+
+  b2sum no longer crashes when processing certain truncated check files.
+  [bug introduced with b2sum coreutils-8.26]
+
+  dd now ensures the correct cache ranges are specified for the "nocache"
+  and "direct" flags.  Previously some pages in the page cache were not
+  invalidated.  [bug introduced for "direct" in coreutils-7.5,
+  and with the "nocache" implementation in coreutils-8.11]
+
+  df no longer hangs when given a fifo argument.
+  [bug introduced in coreutils-7.3]
+
+  ptx -S no longer infloops for a pattern which returns zero-length matches.
+  [the bug dates back to the initial implementation]
+
+  shred --remove will again repeatedly rename files with shortening names
+  to attempt to hide the original length of the file name.
+  [bug introduced in coreutils-8.28]
+
+  stty no longer crashes when processing settings with -F also specified.
+  [bug introduced in fileutils-4.0]
+
+  tail --bytes again supports non seekable inputs on all systems.
+  On systems like android it always tried to process as seekable inputs.
+  [bug introduced in coreutils-8.24]
+
+  timeout will again notice its managed command exiting, even when
+  invoked with blocked CHLD signal, or in a narrow window where
+  this CHLD signal from the exiting child was missed.  In each case
+  timeout would have then waited for the time limit to expire.
+  [bug introduced in coreutils-8.27]
+
+** New features
+
+  timeout now supports the --verbose option to diagnose forced termination.
+
+** Improvements
+
+  dd now supports iflag=direct with arbitrary sized files on all file systems.
+
+  tail --bytes=NUM will efficiently seek to the end of block devices,
+  rather than reading from the start.
+
+  Utilities which do not support long options (other than the default --help
+  and --version), e.g. cksum and sleep, now use more consistent error diagnostic
+  for unknown long options.
+
+** Build-related
+
+  Default man pages are now distributed which are used if perl is
+  not available on the build system, or when cross compiling.
+
+
+* Noteworthy changes in release 8.28 (2017-09-01) [stable]
+
+** Bug fixes
+
+  cp and mv now merely warn about any failure to preserve symlink ownership.
+  Before, cp (without -p) would exit with a failure status, and a cross-device
+  mv would leave such symlinks behind in the source file system.
+  [the bug dates back to the initial implementation]
+
+  When creating numbered backups, cp, install, ln, and mv now avoid
+  races that could lose backup data in unlikely circumstances.  Since
+  the fix relies on the renameat2 system call of Linux kernel 3.15 and
+  later, the races are still present on other platforms.
+  [the bug dates back to the initial implementation]
+
+  cp, install, ln, and mv no longer lose data when asked to copy a
+  backup file to its original via a differently-spelled file name.
+  E.g., 'rm -f a a~; : > a; echo data > a~; cp --backup=simple a~ ./a'
+  now fails instead of losing the data.
+  [the bug dates back to the initial implementation]
+
+  cp, install, ln, and mv now ignore nonsensical backup suffixes.
+  For example, --suffix='/' and --suffix='' are now no-ops.
+  [the bug dates back to the initial implementation]
+
+  date and touch no longer overwrite the heap with large
+  user specified TZ values (CVE-2017-7476).
+  [bug introduced in coreutils-8.27]
+
+  dd status=progress now just counts seconds; e.g., it outputs "6 s"
+  consistently rather than sometimes outputting "6.00001 s".
+  [bug introduced in coreutils-8.24]
+
+  df no longer interacts with excluded file system types, so for example
+  specifying -x nfs no longer hangs with problematic nfs mounts.
+  [bug introduced in coreutils-8.21]
+
+  df no longer interacts with dummy file system types, so for example
+  no longer hangs with problematic nfs mounted via system.automount(5).
+  [bug introduced in coreutils-8.21]
+
+  `groups inva:lid root` no longer exits immediately upon failure.
+  Now, it prints a diagnostic or a line to stdout for each argument.
+  [bug introduced in the bourne-shell-to-C rewrite for coreutils-6.11]
+
+  kill now converts from number to signal name correctly on AIX.
+  Previously it would have always returned the 'EXIT' name.
+  [bug introduced in fileutils-4.1.9]
+
+  ls now quotes symlink targets consistently.  Previously it may not
+  have quoted the target name if the link name itself didn't need quoting.
+  [bug introduced in coreutils-8.26]
+
+  split no longer exits when invocations of a --filter return EPIPE.
+  [bug introduced in coreutils-8.26]
+
+  md5sum --check no longer incorrectly enables BSD reversed format mode when
+  ignoring some non checksum lines.  This also affects sha*sum and b2sum.
+  [bug introduced in coreutils-8.14]
+
+  tail -F 'dir/file' is now monitored even when 'dir' is replaced.
+  [bug introduced with inotify support added in coreutils-7.5]
+
+  tail -f with --pid=PID now processes all inotify events.
+  Previously events may have been ignored completely upon PID death,
+  or ignored until future events on the monitored files.
+  [bug introduced with inotify support added in coreutils-7.5]
+
+  tail -f /dev/tty is now supported by not using inotify when any
+  non regular files are specified, as inotify is ineffective with these.
+  [bug introduced with inotify support added in coreutils-7.5]
+
+  uptime no longer outputs the AM/PM component of the current time,
+  as that's inconsistent with the 24 hour time format used.
+  [bug introduced in coreutils-7.0]
+
+  expr now returns number of characters matched (instead of incorrect
+  number of bytes matched) with 'match'/':' operators on multibyte strings.
+
+** New features
+
+  expand and unexpand now support specifying an offset for tab stops
+  by prefixing the last specified number like --tabs=1,+8 which is
+  useful for visualizing diff output for example.
+
+  ls supports a new --hyperlink[=when] option to output file://
+  format links to files, supported by some terminals.
+
+  split supports a new --hex-suffixes[=from] option to create files with
+  lower case hexadecimal suffixes, similar to the --numeric-suffixes option.
+
+  env now has a --chdir (-C) option to change the working directory before
+  executing the subsidiary program.
+
+  expr supports multibyte strings for all string operations.
+
+** Changes in behavior
+
+  tail -f now exits immediately if the output is piped and the reader of
+  the pipe terminates.  That allows `tail -f file | grep -q foo` to return
+  responsively, but does make `tail -f file | :` exit immediately without
+  waiting for data.  Instead one should now `tail -f file | grep -q .`
+
+** Improvements
+
+  mv --verbose now distinguishes rename and copy operations.
+
+  stat -f -c %l, used to output the max file name length on a file system,
+  is now supported on FreeBSD and OpenBSD.
+
+  tail -f no longer erroneously warns about being ineffective
+  when following a single tty, as the simple blocking loop used
+  is effective in this case.
+
+
+* Noteworthy changes in release 8.27 (2017-03-08) [stable]
+
+** Bug fixes
+
+  cp --parents will now set an SELinux context for created directories,
+  as appropriate for the -a, --preseve=context, or -Z options.
+  [bug present since SELinux support added in coreutils-6.10]
+
+  date again converts from a specified time zone.  Previously output was
+  not converted to the local time zone, and remained in the specified one.
+  [bug introduced in coreutils-8.26]
+
+  Commands like 'cp --no-dereference -l A B' are no longer quiet no-ops
+  when A is a regular file and B is a symbolic link that points to A.
+  [bug introduced in fileutils-4.0]
+
+  factor no longer goes into an infinite loop for certain numbers like
+  158909489063877810457 and 222087527029934481871.
+  [bug introduced in coreutils-8.20]
+
+  tail no longer prints redundant file headers with interleaved inotify events,
+  which could be triggered especially when tail was suspended and resumed.
+  [bug introduced with inotify support added in coreutils-7.5]
+
+  timeout no longer has a race that may terminate the wrong process.
+  The race is unlikely, as timeout(1) needs to receive a signal right
+  after the command being monitored finishes.  Also the system needs
+  to have reallocated that command's pid in that short time window.
+  [bug introduced when timeout was added in coreutils-7.0]
+
+  wc --bytes --files0-from now correctly reports byte counts.
+  Previously it may have returned values that were too large,
+  depending on the size of the first file processed.
+  [bug introduced in coreutils-8.24]
+
+** Improvements
+
+  The new 'date' option --rfc-email is now the long form for -R.
+  The new option spelling is intended to avoid the need to track the
+  Internet RFC number for email dates (currently RFC 5322).  The old
+  option spellings --rfc-2822 and --rfc-822 still work.
+
+  date now outputs "-00" for a numeric time zone if the time is UTC
+  and the time zone abbreviation begins with "-", indicating that the
+  time zone is indeterminate.
+
+  nproc now honors the OMP_THREAD_LIMIT environment variable to
+  set the maximum returned value.  OMP_NUM_THREADS continues to
+  set the minimum returned value, but is updated to support the
+  nested level syntax allowed in this variable.
+
+  stat and tail now know about the "rdt" file system, which is an interface
+  to Resource Director Technology.  stat -f --format=%T now reports the
+  file system type, and tail -f uses inotify.
+
+  stty now validates arguments before interacting with the device,
+  ensuring there are no side effects to specifying an invalid option.
+
+  If the file B already exists, commands like 'ln -f A B' and
+  'cp -fl A B' no longer remove B before creating the new link.
+  That is, there is no longer a brief moment when B does not exist.
+
+** New features
+
+  expand and unexpand now support specifying a tab size to use
+  after explicitly specified tab stops, by prefixing the last
+  specified number like --tabs=2,4,/8.
+
+
+* Noteworthy changes in release 8.26 (2016-11-30) [stable]
+
+** Bug fixes
+
+  cp, mv, and install no longer run into undefined behavior when
+  handling ACLs on Cygwin and Solaris platforms. [bug introduced in
+  coreutils-8.24]
+
+  cp --parents --no-preserve=mode, no longer copies permissions from source
+  directories, instead using default permissions for created directories.
+  [bug introduced in coreutils-5.93]
+
+  chcon, chgrp, chmod, chown, du, and rm, or specifically utilities
+  using the FTS interface, now diagnose failures returned by readdir().
+  [this bug was inherent in the use of fts: thus, for rm the bug was
+  introduced in coreutils-8.0.  du, chmod, chgrp and chown started using
+  fts in 6.0.  chcon was added in coreutils-6.9.91 with fts support.  ]
+
+  date, du, ls, and pr no longer mishandle time zone abbreviations on
+  System V style platforms where this information is available only
+  in the global variable 'tzname'. [bug introduced in coreutils-8.24]
+
+  factor again outputs immediately when numbers are input interactively.
+  [bug introduced in coreutils-8.24]
+
+  head no longer tries to process non-seekable input as seekable,
+  which resulted in failures on FreeBSD 11 at least.
+  [bug introduced in coreutils-8.24]
+
+  install -DZ and mkdir -pZ now set default SELinux context correctly even if
+  two or more directories nested in each other are created and each of them
+  defaults to a different SELinux context.
+
+  ls --time-style no longer mishandles '%%b' in formats.
+  [bug introduced in coreutils-7.2]
+
+  md5sum --check --ignore-missing no longer treats files with checksums
+  starting with "00" as missing.  This also affects sha*sum.
+  [bug introduced with the --ignore-missing feature in coreutils-8.25]
+
+  nl now resets numbering for each page section rather than just for each page.
+  [This bug was present in "the beginning".]
+
+  pr now handles specified separator strings containing tabs correctly.
+  Previously it would have output random data from memory.
+  [This bug was detected with ASAN and present in "the beginning".]
+
+  sort -h -k now works even in locales that use blank as thousands separator.
+
+  stty --help no longer outputs extraneous gettext header lines
+  for translated languages. [bug introduced in coreutils-8.24]
+
+  stty "sane" again sets "susp" to ^z on Solaris, and leaves "swtch" undefined.
+  [This bug previously fixed only on some older Solaris systems]
+
+  seq now immediately exits upon write errors.
+  [This bug was present in "the beginning".]
+
+  tac no longer crashes when there are issues reading from non-seekable inputs.
+  [bug introduced in coreutils-8.15]
+
+  tail -F now continues to process initially untailable files that are replaced
+  by a tailable file.  This was handled correctly when inotify was available,
+  and is now handled correctly in all cases.
+  [bug introduced in fileutils-4.0h]
+
+  tail -f - 'untailable file' will now terminate when there is no more data
+  to read from stdin.  Previously it behaved as if --retry was specified.
+  [This bug was present in "the beginning".]
+
+  tail -f 'remote file' will now avoid outputting repeated data on network
+  file systems that misreport file sizes through stale metadata.
+  [This bug was present in "the beginning" but exacerbated in coreutils-8.24]
+
+  tail -f --retry 'missing file' will now process truncations of that file.
+  Previously truncation was ignored thus not outputting new data in the file.
+  [bug introduced in coreutils-5.3.0]
+
+  tail -f will no longer continually try to open inaccessible files,
+  only doing so if --retry is specified.
+  [This bug was present in "the beginning".]
+
+  yes now handles short writes, rather than assuming all writes complete.
+  [bug introduced in coreutils-8.24]
+
+** Changes in behavior
+
+  rm no longer accepts shortened variants of the --no-preserve-root option.
+
+  seq no longer accepts 0 value as increment, and now also rejects NaN
+  values for any argument.
+
+  stat now outputs nanosecond information for timestamps even if
+  they are out of localtime range.
+
+  sort, tail, and uniq now support traditional usage like 'sort +2'
+  and 'tail +10' on systems conforming to POSIX 1003.1-2008 and later.
+  The 2008 edition of POSIX dropped the requirement that arguments
+  like '+2' must be treated as file names.
+
+** Improvements
+
+  dd now warns about counts specified with a 0x "prefix", since dd will
+  interpret those as a zero multiplier rather than a hex constant.
+  The warning suggests to use 00x if a zero multiplier is really intended.
+
+  df now filters the system mount list more efficiently, with 20000
+  mount entries now being processed in about 1.1s compared to 1.7s.
+
+  du, shuf, sort, and uniq no longer fail to process a specified file
+  when their stdin is closed, which would have happened with glibc >= 2.14.
+
+  install -Z now also sets the default SELinux context for created directories.
+
+  ls is now fully responsive to signals until the first escape sequence is
+  written to a terminal.
+
+  ls now aligns quoted items with non quoted items, which is easier to read,
+  and also better indicates that the quote is not part of the actual name.
+
+  stat and tail now know about these file systems:
+    "balloon-kvm-fs"    KVM dynamic RAM allocation support,
+    "cgroup2"           Linux Control Groups V2 support,
+    "daxfs"             Optical media file system,
+    "m1fs"              A Plexistor file system,
+    "prl_fs"            A parallels file system,
+    "smb2"              Samba for SMB protocol V2,
+    "wslfs"             Windows Subsystem for Linux,
+    "zsmalloc"          Linux compressed swap support,
+  stat -f --format=%T now reports the file system type, and
+  tail -f uses polling for "prl_fs" and "smb2", and inotify for others.
+
+  stat --format=%N for quoting file names now honors the
+  same QUOTING_STYLE environment variable values as ls.
+
+** New programs
+
+  b2sum is added to support the BLAKE2 digest algorithm with
+  a similar interface to the existing md5sum and sha1sum, etc. commands.
+
+** New Features
+
+  comm now accepts the --total option to output a summary at the end.
+
+  date now accepts the --debug option, to annotate the parsed date string,
+  display timezone information, and warn about potential misuse.
+
+  date now accepts the %q format to output the quarter of the year.
+
+
+* Noteworthy changes in release 8.25 (2016-01-20) [stable]
+
+** Bug fixes
+
+  cp now correctly copies files with a hole at the end of the file,
+  and extents allocated beyond the apparent size of the file.
+  That combination resulted in the trailing hole not being reproduced.
+  [bug introduced in coreutils-8.10]
+
+  cut --fields no longer outputs extraneous characters on some uClibc configs.
+  [bug introduced in coreutils-6.11]
+
+  install -D again copies relative file names when absolute file names
+  are also specified along with an absolute destination directory name.
+  [bug introduced in coreutils-6.2]
+
+  ls no longer prematurely wraps lines when printing short file names.
+  [bug introduced in coreutils-5.1.0]
+
+  mv no longer causes data loss due to removing a source directory specified
+  multiple times, when that directory is also specified as the destination.
+  [bug introduced in coreutils-8.24]
+
+  shred again uses defined patterns for all iteration counts.
+  [bug introduced in coreutils-5.93]
+
+  sort --debug -b now correctly marks the matching extents for keys
+  that specify an offset for the first field.
+  [bug introduced with the --debug feature in coreutils-8.6]
+
+  tail -F now works with initially non existent files on a remote file system.
+  [bug introduced in coreutils-7.5]
+
+** New commands
+
+  base32 is added to complement the existing base64 command,
+  and encodes and decodes printable text as per RFC 4648.
+
+** New features
+
+  comm,cut,head,numfmt,paste,tail now have the -z,--zero-terminated option, and
+  tac --separator accepts an empty argument, to work with NUL delimited items.
+
+  dd now summarizes sizes in --human-readable format too, not just --si.
+  E.g., "3441325000 bytes (3.4 GB, 3.2 GiB) copied".  It omits the summaries
+  if they would not provide useful information, e.g., "3 bytes copied".
+  Its status=progress output now uses the same format as ordinary status,
+  perhaps with trailing spaces to erase previous progress output.
+
+  md5sum now supports the --ignore-missing option to allow
+  verifying a subset of files given a larger list of checksums.
+  This also affects sha1sum, sha224sum, sha256sum, sha384sum and sha512sum.
+
+  printf now supports the '%q' format to print arguments in a form that
+  is reusable by most shells, with non-printable characters escaped
+  with the POSIX proposed $'...' syntax.
+
+  stty now supports the "[-]drain" setting to control whether to wait
+  for transmission of pending output before application of settings.
+
+** Changes in behavior
+
+  base64 no longer supports hex or oct --wrap parameters,
+  thus better supporting decimals with leading zeros.
+
+  date --iso-8601 now uses +00:00 timezone format rather than +0000.
+  The standard states to use this "extended" format throughout a timestamp.
+
+  df now prefers sources towards the root of a device when
+  eliding duplicate bind mounted entries.
+
+  join, sort, uniq with --zero-terminated, now treat '\n' as a field delimiter.
+
+** Improvements
+
+  All utilities now quote user supplied arguments in error strings,
+  which avoids confusing error messages in the presence of '\r' chars etc.
+
+  Utilities that traverse directories, like chmod, cp, and rm etc., will operate
+  more efficiently on XFS through the use of "leaf optimization".
+
+  md5sum now ensures a single line per file for status on standard output,
+  by using a '\' at the start of the line, and replacing any newlines with '\n'.
+  This also affects sha1sum, sha224sum, sha256sum, sha384sum and sha512sum.
+
+  dircolors now supports globbing of TERM entries in its database.
+  For example "TERM *256color*" is now supported.
+
+  du no longer stats all mount points at startup, only doing so
+  upon detection of a directory cycle.
+  [issue introduced in coreutils-8.20]
+
+  ls -w0 is now interpreted as no limit on the length of the outputted line.
+
+  stat -f --format=%T now reports the file system type for new Linux
+  pseudo file systems "bpf_fs", "btrfs_test", "nsfs", "overlayfs"
+  and "tracefs", and remote file system "acfs".
+
+  wc now ensures a single line per file for counts on standard output,
+  by quoting names containing '\n' characters; appropriate for use in a shell.
+
+
+* Noteworthy changes in release 8.24 (2015-07-03) [stable]
+
+** Bug fixes
+
+  dd supports more robust SIGINFO/SIGUSR1 handling for outputting statistics.
+  Previously those signals may have inadvertently terminated the process.
+
+  df --local no longer hangs with inaccessible remote mounts.
+  [bug introduced in coreutils-8.21]
+
+  du now silently ignores all directory cycles due to bind mounts.
+  Previously it would issue a warning and exit with a failure status.
+  [bug introduced in coreutils-8.1 and partially fixed in coreutils-8.23]
+
+  chroot again calls chroot(DIR) and chdir("/"), even if DIR is "/".
+  This handles separate bind mounted "/" trees, and environments
+  depending on the implicit chdir("/").
+  [bugs introduced in coreutils-8.23]
+
+  cp no longer issues an incorrect warning about directory hardlinks when a
+  source directory is specified multiple times.  Now, consistent with other
+  file types, a warning is issued for source directories with duplicate names,
+  or with -H the directory is copied again using the symlink name.
+
+  factor avoids writing partial lines, thus supporting parallel operation.
+  [the bug dates back to the initial implementation]
+
+  head, od, split, tac, tail, and wc no longer mishandle input from files in
+  /proc and /sys file systems that report somewhat-incorrect file sizes.
+
+  mkdir --parents -Z now correctly sets the context for the last component,
+  even if the parent directory exists and has a different default context.
+  [bug introduced with the -Z restorecon functionality in coreutils-8.22]
+
+  numfmt no longer outputs incorrect overflowed values seen with certain
+  large numbers, or with numbers with increased precision.
+  [bug introduced when numfmt was added in coreutils-8.21]
+
+  numfmt now handles leading zeros correctly, not counting them when
+  settings processing limits, and making them optional with floating point.
+  [bug introduced when numfmt was added in coreutils-8.21]
+
+  paste no longer truncates output for large input files.  This would happen
+  for example with files larger than 4GiB on 32 bit systems with a '\n'
+  character at the 4GiB position.
+  [the bug dates back to the initial implementation]
+
+  rm indicates the correct number of arguments in its confirmation prompt,
+  on all platforms.  [bug introduced in coreutils-8.22]
+
+  shuf -i with a single redundant operand, would crash instead of issuing
+  a diagnostic.  [bug introduced in coreutils-8.22]
+
+  tail releases inotify resources when unused.  Previously it could exhaust
+  resources with many files, or with -F if files were replaced many times.
+  [bug introduced in coreutils-7.5]
+
+  tail -f again follows changes to a file after it's renamed.
+  [bug introduced in coreutils-7.5]
+
+  tail --follow no longer misses changes to files if those files were
+  replaced before inotify watches were created.
+  [bug introduced in coreutils-7.5]
+
+  tail --follow consistently outputs all data for a truncated file.
+  [bug introduced in the beginning]
+
+  tail --follow=name correctly outputs headers for multiple files
+  when those files are being created or renamed.
+  [bug introduced in coreutils-7.5]
+
+** New features
+
+  chroot accepts the new --skip-chdir option to not change the working directory
+  to "/" after changing into the chroot(2) jail, thus retaining the current wor-
+  king directory.  The new option is only permitted if the new root directory is
+  the old "/", and therefore is useful with the --group and --userspec options.
+
+  dd accepts a new status=progress level to print data transfer statistics
+  on stderr approximately every second.
+
+  numfmt can now process multiple fields with field range specifications similar
+  to cut, and supports setting the output precision with the --format option.
+
+  split accepts a new --separator option to select a record separator character
+  other than the default newline character.
+
+  stty allows setting the "extproc" option where supported, which is
+  a useful setting with high latency links.
+
+  sync no longer ignores arguments, and syncs each specified file, or with the
+  --file-system option, the file systems associated with each specified file.
+
+  tee accepts a new --output-error option to control operation with pipes
+  and output errors in general.
+
+** Changes in behavior
+
+  df no longer suppresses separate exports of the same remote device, as
+  these are generally explicitly mounted.  The --total option does still
+  suppress duplicate remote file systems.
+  [suppression was introduced in coreutils-8.21]
+
+  mv no longer supports moving a file to a hardlink, instead issuing an error.
+  The implementation was susceptible to races in the presence of multiple mv
+  instances, which could result in both hardlinks being deleted.  Also on case
+  insensitive file systems like HFS, mv would just remove a hardlinked 'file'
+  if called like `mv file File`.  The feature was added in coreutils-5.0.1.
+
+  numfmt --from-unit and --to-unit options now interpret suffixes as SI units,
+  and IEC (power of 2) units are now specified by appending 'i'.
+
+  tee will exit early if there are no more writable outputs.
+
+  tee does not treat the file operand '-' as meaning standard output any longer,
+  for better conformance to POSIX.  This feature was added in coreutils-5.3.0.
+
+  timeout --foreground no longer sends SIGCONT to the monitored process,
+  which was seen to cause intermittent issues with GDB for example.
+
+** Improvements
+
+  cp,install,mv will convert smaller runs of NULs in the input to holes,
+  and cp --sparse=always avoids speculative preallocation on XFS for example.
+
+  cp will read sparse files more efficiently when the destination is a
+  non regular file.  For example when copying a disk image to a device node.
+
+  mv will try a reflink before falling back to a standard copy, which is
+  more efficient when moving files across BTRFS subvolume boundaries.
+
+  stat and tail now know about IBRIX.  stat -f --format=%T now reports the file
+  system type, and tail -f uses polling for files on IBRIX file systems.
+
+  wc -l processes short lines much more efficiently.
+
+  References from --help and the man pages of utilities have been corrected
+  in various cases, and more direct links to the corresponding online
+  documentation are provided.
+
+
+* Noteworthy changes in release 8.23 (2014-07-18) [stable]
+
+** Bug fixes
+
+  chmod -Rc no longer issues erroneous warnings for files with special bits set.
+  [bug introduced in coreutils-6.0]
+
+  cp -a, mv, and install --preserve-context, once again set the correct SELinux
+  context for existing directories in the destination.  Previously they set
+  the context of an existing directory to that of its last copied descendant.
+  [bug introduced in coreutils-8.22]
+
+  cp -a, mv, and install --preserve-context, no longer seg fault when running
+  with SELinux enabled, when copying from file systems that return an error
+  when reading the SELinux context for a file.
+  [bug introduced in coreutils-8.22]
+
+  cp -a and mv now preserve xattrs of symlinks copied across file systems.
+  [bug introduced with extended attribute preservation feature in coreutils-7.1]
+
+  date could crash or go into an infinite loop when parsing a malformed TZ="".
+  [bug introduced with the --date='TZ="" ..' parsing feature in coreutils-5.3.0]
+
+  dd's ASCII and EBCDIC conversions were incompatible with common practice and
+  with POSIX, and have been corrected as follows.  First, conv=ascii now
+  implies conv=unblock, and conv=ebcdic and conv=ibm now imply conv=block.
+  Second, the translation tables for dd conv=ascii and conv=ebcdic have been
+  corrected as shown in the following table, where A is the ASCII value, W is
+  the old, wrong EBCDIC value, and E is the new, corrected EBCDIC value; all
+  values are in octal.
+
+      A   W   E
+     041 117 132
+     133 112 255
+     135 132 275
+     136 137 232
+     174 152 117
+     176 241 137
+     313 232 152
+     325 255 112
+     345 275 241
+
+  [These dd bugs were present in "the beginning".]
+
+  df has more fixes related to the newer dynamic representation of file systems:
+  Duplicates are elided for virtual file systems like tmpfs.
+  Details for the correct device are output for points mounted multiple times.
+  Placeholder values are output for inaccessible file systems, rather than
+  than error messages or values for the wrong file system.
+  [These bugs were present in "the beginning".]
+
+  df now outputs all appropriate entries in the presence of bind mounts.
+  On some systems, entries would have been incorrectly elided due to
+  them being considered "dummy" mounts.
+  [bug introduced in coreutils-8.22]
+
+  du now silently ignores directory cycles introduced with bind mounts.
+  Previously it would issue a warning and exit with a failure status.
+  [bug introduced in coreutils-8.1]
+
+  head --bytes=-N and --lines=-N now handles devices more
+  consistently, not ignoring data from virtual devices like /dev/zero,
+  or on BSD systems data from tty devices.
+  [bug introduced in coreutils-5.0.1]
+
+  head --bytes=-N - no longer fails with a bogus diagnostic when stdin's
+  seek pointer is not at the beginning.
+  [bug introduced with the --bytes=-N feature in coreutils-5.0.1]
+
+  head --lines=-0, when the input does not contain a trailing '\n',
+  now copies all input to stdout.  Previously nothing was output in this case.
+  [bug introduced with the --lines=-N feature in coreutils-5.0.1]
+
+  id, when invoked with no user name argument, now prints the correct group ID.
+  Previously, in the default output format, it would print the default group ID
+  in the password database, which may be neither real nor effective.  For e.g.,
+  when run set-GID, or when the database changes outside the current session.
+  [bug introduced in coreutils-8.1]
+
+  ln -sf now replaces symbolic links whose targets can't exist.  Previously
+  it would display an error, requiring --no-dereference to avoid the issue.
+  [bug introduced in coreutils-5.3.0]
+
+  ln -sr '' F no longer segfaults.  Now works as expected.
+  [bug introduced with the --relative feature in coreutils-8.16]
+
+  numfmt now handles blanks correctly in all unibyte locales.  Previously
+  in locales where character 0xA0 is a blank, numfmt would mishandle it.
+  [bug introduced when numfmt was added in coreutils-8.21]
+
+  ptx --format long option parsing no longer falls through into the --help case.
+  [bug introduced in TEXTUTILS-1_22i]
+
+  ptx now consistently trims whitespace when processing multiple files.
+  [This bug was present in "the beginning".]
+
+  seq again generates correct output with start or end values = -0.
+  [bug introduced in coreutils-8.20.]
+
+  shuf --repeat no longer dumps core if the input is empty.
+  [bug introduced with the --repeat feature in coreutils-8.22]
+
+  sort when using multiple threads now avoids undefined behavior with mutex
+  destruction, which could cause deadlocks on some implementations.
+  [bug introduced in coreutils-8.6]
+
+  tail -f now uses polling mode for VXFS to cater for its clustered mode.
+  [bug introduced with inotify support added in coreutils-7.5]
+
+** New features
+
+  od accepts a new option: --endian=TYPE to handle inputs with different byte
+  orders, or to provide consistent output on systems with disparate endianness.
+
+  configure accepts the new option --enable-single-binary to build all the
+  selected programs in a single binary called "coreutils".  The selected
+  programs can still be called directly using symlinks to "coreutils" or
+  shebangs with the option --coreutils-prog= passed to this program.  The
+  install behavior is determined by the option --enable-single-binary=symlinks
+  or --enable-single-binary=shebangs (the default).  With the symlinks option,
+  you can't make a second symlink to any program because that will change the
+  name of the called program, which is used by coreutils to determine the
+  desired program.  The shebangs option doesn't suffer from this problem, but
+  the /proc/$pid/cmdline file might not be updated on all the platforms.  The
+  functionality of each program is not affected but this single binary will
+  depend on all the required dynamic libraries even to run simple programs.
+  If you desire to build some tools outside the single binary file, you can
+  pass the option --enable-single-binary-exceptions=PROG_LIST with the comma
+  separated list of programs you want to build separately.  This flag
+  considerably reduces the overall size of the installed binaries which makes
+  it suitable for embedded system.
+
+** Changes in behavior
+
+  chroot with an argument of "/" no longer implicitly changes the current
+  directory to "/", allowing changing only user credentials for a command.
+
+  chroot --userspec will now unset supplemental groups associated with root,
+  and instead use the supplemental groups of the specified user.
+
+  cut -d$'\n' again outputs lines identified in the --fields list, having
+  not done so in v8.21 and v8.22.  Note using this non portable functionality
+  will result in the delayed output of lines.
+
+  ls with none of LS_COLORS or COLORTERM environment variables set,
+  will now honor an empty or unknown TERM environment variable,
+  and not output colors even with --colors=always.
+
+** Improvements
+
+  chroot has better --userspec and --group look-ups, with numeric IDs never
+  causing name look-up errors.  Also look-ups are first done outside the chroot,
+  in case the look-up within the chroot fails due to library conflicts etc.
+
+  install now allows the combination of the -D and -t options.
+
+  numfmt supports zero padding of numbers using the standard printf
+  syntax of a leading zero, for example --format="%010f".
+  Also throughput was improved by up to 800% by avoiding redundant processing.
+
+  shred now supports multiple passes on GNU/Linux tape devices by rewinding
+  the tape before each pass, avoids redundant writes to empty files,
+  uses direct I/O for all passes where possible, and attempts to clear
+  inode storage used for small files on some file systems.
+
+  split avoids unnecessary input buffering, immediately writing input to output
+  which is significant with --filter or when writing to fifos or stdout etc.
+
+  stat and tail work better with HFS+, HFSX, LogFS and ConfigFS.  stat -f
+  --format=%T now reports the file system type, and tail -f now uses inotify,
+  rather than the default of issuing a warning and reverting to polling.
+
+
+* Noteworthy changes in release 8.22 (2013-12-13) [stable]
+
+** Bug fixes
+
+  df now processes the mount list correctly in the presence of unstatable
+  mount points.  Previously it may have failed to output some mount points.
+  [bug introduced in coreutils-8.21]
+
+  df now processes symbolic links and relative paths to special files containing
+  a mounted file system correctly.  Previously df displayed the statistics about
+  the file system the file is stored on rather than the one inside.
+  [This bug was present in "the beginning".]
+
+  df now processes disk device nodes correctly in the presence of bind mounts.
+  Now df shows the base mounted file system rather than the last one mounted.
+  [This bug was present in "the beginning".]
+
+  install now removes the target file if the strip program failed for any
+  reason.  Before, that file was left behind, sometimes even with wrong
+  permissions.
+  [This bug was present in "the beginning".]
+
+  ln --relative now updates existing symlinks correctly.  Previously it based
+  the relative link on the dereferenced path of an existing link.
+  [This bug was introduced when --relative was added in coreutils-8.16.]
+
+  ls --recursive will no longer exit with "serious" exit code (2), if there
+  is an error reading a directory not specified on the command line.
+  [Bug introduced in coreutils-5.3.0]
+
+  mkdir, mkfifo, and mknod now work better when creating a file in a directory
+  with a default ACL whose umask disagrees with the process's umask, on a
+  system such as GNU/Linux where directory ACL umasks override process umasks.
+  [bug introduced in coreutils-6.0]
+
+  mv will now replace empty directories in the destination with directories
+  from the source, when copying across file systems.
+  [This bug was present in "the beginning".]
+
+  od -wN with N larger than 64K on a system with 32-bit size_t would
+  print approximately 2*N bytes of extraneous padding.
+  [Bug introduced in coreutils-7.0]
+
+  rm -I now prompts for confirmation before removing a write protected file.
+  [Bug introduced in coreutils-6.8]
+
+  shred once again uses direct I/O on systems requiring aligned buffers.
+  Also direct I/O failures for odd sized writes at end of file are now handled.
+  [The "last write" bug was introduced in coreutils-5.3.0 but masked
+   by the alignment bug introduced in coreutils-6.0]
+
+  tail --retry -f now waits for the files specified to appear.  Before, tail
+  would immediately exit when such a file is initially inaccessible.
+  [This bug was introduced when inotify support was added in coreutils-7.5]
+
+  tail -F has improved handling of symlinks.  Previously tail didn't respond
+  to the symlink target (re)appearing after being (re)created.
+  [This bug was introduced when inotify support was added in coreutils-7.5]
+
+** New features
+
+  cp, install, mkdir, mknod, mkfifo and mv now support "restorecon"
+  functionality through the -Z option, to set the SELinux context
+  appropriate for the new item location in the file system.
+
+  csplit accepts a new option: --suppressed-matched, to elide the lines
+  used to identify the split points.
+
+  df --output now accepts a 'file' field, to propagate a specified
+  command line argument through to the output.
+
+  du accepts a new option: --inodes to show the number of inodes instead
+  of the blocks used.
+
+  id accepts a new option: --zero (-z) to delimit the output entries by
+  a NUL instead of a white space character.
+
+  id and ls with -Z report the SMACK security context where available.
+  mkdir, mkfifo and mknod with --context set the SMACK context where available.
+
+  id can now lookup by user ID, in addition to the existing name lookup.
+
+  join accepts a new option: --zero-terminated (-z). As with the sort,uniq
+  option of the same name, this makes join consume and produce NUL-terminated
+  lines rather than newline-terminated lines.
+
+  uniq accepts a new option: --group to print all items, while separating
+  unique groups with empty lines.
+
+  shred accepts new parameters to the --remove option to give greater
+  control over that operation, which can greatly reduce sync overhead.
+
+  shuf accepts a new option: --repeat (-r), which can repeat items in
+  the output.
+
+** Changes in behavior
+
+  cp --link now dereferences a symbolic link as source before creating the
+  hard link in the destination unless the -P,--no-deref option is specified.
+  Previously, it would create a hard link of the symbolic link, even when
+  the dereferencing options -L or -H were specified.
+
+  cp, install, mkdir, mknod and mkfifo no longer accept an argument to the
+  short -Z option.  The --context equivalent still takes an optional argument.
+
+  dd status=none now suppresses all non fatal diagnostic messages,
+  not just the transfer counts.
+
+  df no longer accepts the long-obsolescent --megabytes option.
+
+  stdbuf now requires at least one buffering mode option to be specified,
+  as per the documented interface.
+
+** Improvements
+
+  base64 encoding throughput for bulk data is increased by about 60%.
+
+  md5sum can use libcrypto hash routines where allowed to potentially
+  get better performance through using more system specific logic.
+  sha1sum for example has improved throughput by 40% on an i3-2310M.
+  This also affects sha1sum, sha224sum, sha256sum, sha384sum and sha512sum.
+
+  stat and tail work better with EFIVARFS, EXOFS, F2FS, HOSTFS, SMACKFS, SNFS
+  and UBIFS.  stat -f --format=%T now reports the file system type, and tail -f
+  now uses inotify for files on all those except SNFS, rather than the default
+  (for unknown file system types) of issuing a warning and reverting to polling.
+
+  shuf outputs subsets of large inputs much more efficiently.
+  Reservoir sampling is used to limit memory usage based on the number of
+  outputs, rather than the number of inputs.
+
+  shred increases the default write block size from 12KiB to 64KiB
+  to align with other utilities and reduce the system call overhead.
+
+  split --line-bytes=SIZE, now only allocates memory as needed rather
+  than allocating SIZE bytes at program start.
+
+  stty now supports configuring "stick" (mark/space) parity where available.
+
+** Build-related
+
+  factor now builds on aarch64 based systems [bug introduced in coreutils-8.20]
+
+
+* Noteworthy changes in release 8.21 (2013-02-14) [stable]
+
+** New programs
+
+  numfmt: reformat numbers
+
+** New features
+
+  df now accepts the --output[=FIELD_LIST] option to define the list of columns
+  to include in the output, or all available columns if the FIELD_LIST is
+  omitted.  Note this enables df to output both block and inode fields together.
+
+  du now accepts the --threshold=SIZE option to restrict the output to entries
+  with such a minimum SIZE (or a maximum SIZE if it is negative).
+  du recognizes -t SIZE as equivalent, for compatibility with FreeBSD.
+
+  timeout now accepts the --preserve-status option to always propagate the exit
+  status, useful for commands that can run for an indeterminate amount of time.
+
+** Bug fixes
+
+  cp --no-preserve=mode now no longer exits non-zero.
+  [bug introduced in coreutils-8.20]
+
+  cut with a range like "N-" no longer allocates N/8 bytes.  That buffer
+  would never be used, and allocation failure could cause cut to fail.
+  [bug introduced in coreutils-8.10]
+
+  cut no longer accepts the invalid range 0-, which made it print empty lines.
+  Instead, cut now fails and emits an appropriate diagnostic.
+  [This bug was present in "the beginning".]
+
+  cut now handles overlapping to-EOL ranges properly.  Before, it would
+  interpret "-b2-,3-" like "-b3-".  Now it's treated like "-b2-".
+  [This bug was present in "the beginning".]
+
+  cut no longer prints extraneous delimiters when a to-EOL range subsumes
+  another range.  Before, "echo 123|cut --output-delim=: -b2-,3" would print
+  "2:3".  Now it prints "23".  [bug introduced in 5.3.0]
+
+  cut -f no longer inspects input line N+1 before fully outputting line N,
+  which avoids delayed output for intermittent input.
+  [bug introduced in TEXTUTILS-1_8b]
+
+  factor no longer loops infinitely on 32 bit powerpc or sparc systems.
+  [bug introduced in coreutils-8.20]
+
+  install -m M SOURCE DEST no longer has a race condition where DEST's
+  permissions are temporarily derived from SOURCE instead of from M.
+
+  pr -n no longer crashes when passed values >= 32.  Also, line numbers are
+  consistently padded with spaces, rather than with zeros for certain widths.
+  [bug introduced in TEXTUTILS-1_22i]
+
+  seq -w ensures that for numbers input in scientific notation,
+  the output numbers are properly aligned and of the correct width.
+  [This bug was present in "the beginning".]
+
+  seq -w ensures correct alignment when the step value includes a precision
+  while the start value does not, and the number sequence narrows.
+  [This bug was present in "the beginning".]
+
+  seq -s no longer prints an erroneous newline after the first number, and
+  outputs a newline after the last number rather than a trailing separator.
+  Also seq no longer ignores a specified step value when the end value is 1.
+  [bugs introduced in coreutils-8.20]
+
+  timeout now ensures that blocking of ALRM signals is not inherited from
+  its parent, which would cause timeouts to be ignored.
+  [the bug dates back to the initial implementation]
+
+** Changes in behavior
+
+  df --total now prints '-' into the target column (mount point) of the
+  summary line, accommodating the --output option where the target field
+  can be in any column.  If there is no source column, then df prints
+  'total' in the target column.
+
+  df now properly outputs file system information with bind mounts present on
+  the system by skipping duplicate entries (identified by the device number).
+  Consequently, df also elides the early-boot pseudo file system type "rootfs".
+
+  cut -d$'\n' no longer outputs lines identified in the --fields list,
+  to align with other implementations and to avoid delayed output of lines.
+
+  nl no longer supports the --page-increment option, which has been
+  deprecated since coreutils-7.5.  Use --line-increment instead.
+
+** Improvements
+
+  readlink now supports multiple arguments, and a complementary
+  -z, --zero option to delimit output items with the NUL character.
+
+  stat and tail now know about CEPH.  stat -f --format=%T now reports the file
+  system type, and tail -f uses polling for files on CEPH file systems.
+
+  stty now supports configuring DTR/DSR hardware flow control where available.
+
+** Build-related
+
+  Perl is now more of a prerequisite.  It has long been required in order
+  to run (not skip) a significant percentage of the tests.  Now, it is
+  also required in order to generate proper man pages, via help2man.  The
+  generated man/*.1 man pages are no longer distributed.  Building without
+  perl, you would create stub man pages.  Thus, while perl is not an
+  official prerequisite (build and "make check" will still succeed), any
+  resulting man pages would be inferior.  In addition, this fixes a bug
+  in distributed (not from clone) Makefile.in that could cause parallel
+  build failure when building from modified sources, as is common practice
+  for a patched distribution package.
+
+  factor now builds on x86_64 with x32 ABI, 32 bit MIPS, and all HPPA systems,
+  by avoiding incompatible asm.  [bug introduced in coreutils-8.20]
+
+  A root-only test predicate would always fail.  Its job was to determine
+  whether our dummy user, $NON_ROOT_USERNAME, was able to run binaries from
+  the build directory.  As a result, all dependent tests were always skipped.
+  Now, those tests may be run once again.  [bug introduced in coreutils-8.20]
+
+
+* Noteworthy changes in release 8.20 (2012-10-23) [stable]
+
+** New features
+
+  dd now accepts 'status=none' to suppress all informational output.
+
+  md5sum now accepts the --tag option to print BSD-style output with GNU
+  file name escaping.  This also affects sha1sum, sha224sum, sha256sum,
+  sha384sum and sha512sum.
+
+** Bug fixes
+
+  cp could read from freed memory and could even make corrupt copies.
+  This could happen with a very fragmented and sparse input file,
+  on GNU/Linux file systems supporting fiemap extent scanning.
+  This bug also affects mv when it resorts to copying, and install.
+  [bug introduced in coreutils-8.11]
+
+  cp --no-preserve=mode now no longer preserves the original file's
+  permissions but correctly sets mode specified by 0666 & ~umask
+
+  du no longer emits a "disk-corrupted"-style diagnostic when it detects
+  a directory cycle that is due to a bind-mounted directory.  Instead,
+  it detects this precise type of cycle, diagnoses it as such and
+  eventually exits nonzero.
+
+  factor (when using gmp) would mistakenly declare some composite numbers
+  to be prime, e.g., 465658903, 2242724851, 6635692801 and many more.
+  The fix makes factor somewhat slower (~25%) for ranges of consecutive
+  numbers, and up to 8 times slower for some worst-case individual numbers.
+  [bug introduced in coreutils-7.0, with GNU MP support]
+
+  ls now correctly colors dangling symlinks when listing their containing
+  directories, with orphaned symlink coloring disabled in LS_COLORS.
+  [bug introduced in coreutils-8.14]
+
+  rm -i -d now prompts the user then removes an empty directory, rather
+  than ignoring the -d option and failing with an 'Is a directory' error.
+  [bug introduced in coreutils-8.19, with the addition of --dir (-d)]
+
+  rm -r S/ (where S is a symlink-to-directory) no longer gives the invalid
+  "Too many levels of symbolic links" diagnostic.
+  [bug introduced in coreutils-8.6]
+
+  seq now handles arbitrarily long non-negative whole numbers when the
+  increment is 1 and when no format-changing option is specified.
+  Before, this would infloop:
+    b=100000000000000000000; seq $b $b
+  [the bug dates back to the initial implementation]
+
+** Changes in behavior
+
+  nproc now diagnoses with an error, non option command line parameters.
+
+** Improvements
+
+  factor's core has been rewritten for speed and increased range.
+  It can now factor numbers up to 2^128, even without GMP support.
+  Its speed is from a few times better (for small numbers) to over
+  10,000 times better (just below 2^64).  The new code also runs a
+  deterministic primality test for each prime factor, not just a
+  probabilistic test.
+
+  seq is now up to 70 times faster than it was in coreutils-8.19 and prior,
+  but only with non-negative whole numbers, an increment of 1, and no
+  format-changing options.
+
+  stat and tail know about ZFS, VZFS and VMHGFS.  stat -f --format=%T now
+  reports the file system type, and tail -f now uses inotify for files on
+  ZFS and VZFS file systems, rather than the default (for unknown file
+  system types) of issuing a warning and reverting to polling.  tail -f
+  still uses polling for files on VMHGFS file systems.
+
+** Build-related
+
+  root-only tests now check for permissions of our dummy user,
+  $NON_ROOT_USERNAME, before trying to run binaries from the build directory.
+  Before, we would get hard-to-diagnose reports of failing root-only tests.
+  Now, those tests are skipped with a useful diagnostic when the root tests
+  are run without following the instructions in README.
+
+  We now build most directories using non-recursive make rules.  I.e.,
+  rather than running make in man/, lib/, src/, tests/, instead, the top
+  level Makefile.am includes a $dir/local.mk that describes how to build
+  the targets in the corresponding directory.  Two directories remain
+  unconverted: po/, gnulib-tests/.  One nice side-effect is that the more
+  accurate dependencies have eliminated a nagging occasional failure that
+  was seen when running parallel "make syntax-check".
+
+
+* Noteworthy changes in release 8.19 (2012-08-20) [stable]
+
+** Bug fixes
+
+  df now fails when the list of mounted file systems (/etc/mtab) cannot
+  be read, yet the file system type information is needed to process
+  certain options like -a, -l, -t and -x.
+  [This bug was present in "the beginning".]
+
+  sort -u could fail to output one or more result lines.
+  For example, this command would fail to print "1":
+  (yes 7 | head -11; echo 1) | sort --p=1 -S32b -u
+  [bug introduced in coreutils-8.6]
+
+  sort -u could read freed memory.
+  For example, this evokes a read from freed memory:
+  perl -le 'print "a\n"."0"x900'|valgrind sort --p=1 -S32b -u>/dev/null
+  [bug introduced in coreutils-8.6]
+
+** New features
+
+  rm now accepts the --dir (-d) option which makes it remove empty directories.
+  Since removing empty directories is relatively safe, this option can be
+  used as a part of the alias rm='rm --dir'.  This improves compatibility
+  with Mac OS X and BSD systems which also honor the -d option.
+
+
+* Noteworthy changes in release 8.18 (2012-08-12) [stable]
+
+** Bug fixes
+
+  cksum now prints checksums atomically so that concurrent
+  processes will not intersperse their output.
+  [the bug dates back to the initial implementation]
+
+  date -d "$(printf '\xb0')" would print 00:00:00 with today's date
+  rather than diagnosing the invalid input.  Now it reports this:
+  date: invalid date '\260'
+  [This bug was present in "the beginning".]
+
+  df no longer outputs control characters present in the mount point name.
+  Such characters are replaced with '?', so for example, scripts consuming
+  lines output by df, can work reliably.
+  [This bug was present in "the beginning".]
+
+  df --total now exits with an appropriate diagnostic and error code, when
+  file system --type options do not lead to a processed file system.
+  [This bug dates back to when --total was added in coreutils-7.0]
+
+  head --lines=-N (-n-N) now resets the read pointer of a seekable input file.
+  This means that "head -n-3" no longer consumes all of its input, and lines
+  not output by head may be processed by other programs.  For example, this
+  command now prints the final line, 2, while before it would print nothing:
+    seq 2 > k; (head -n-1 > /dev/null; cat) < k
+  [This bug was present in "the beginning".]
+
+  ls --color would mis-color relative-named symlinks in /
+  [bug introduced in coreutils-8.17]
+
+  split now ensures it doesn't overwrite the input file with generated output.
+  [the bug dates back to the initial implementation]
+
+  stat and df now report the correct file system usage,
+  in all situations on GNU/Linux, by correctly determining the block size.
+  [df bug since coreutils-5.0.91, stat bug since the initial implementation]
+
+  tail -f no longer tries to use inotify on AUFS or PanFS file systems
+  [you might say this was introduced in coreutils-7.5, along with inotify
+   support, but even now, its magic number isn't in the usual place.]
+
+** New features
+
+  stat -f recognizes the new remote file system types: aufs, panfs.
+
+** Changes in behavior
+
+  su: this program has been removed.  We stopped installing "su" by
+  default with the release of coreutils-6.9.90 on 2007-12-01.  Now,
+  that the util-linux package has the union of the Suse and Fedora
+  patches as well as enough support to build on the Hurd, we no longer
+  have any reason to include it here.
+
+** Improvements
+
+  sort avoids redundant processing in the presence of inaccessible inputs,
+  or unwritable output.  Sort now diagnoses certain errors at start-up,
+  rather than after potentially expensive processing.
+
+  sort now allocates no more than 75% of physical memory by default,
+  to better share system resources, and thus operate more efficiently.
+  [The default max memory usage changed from 50% to 100% in coreutils-8.16]
+
+
+* Noteworthy changes in release 8.17 (2012-05-10) [stable]
+
+** Bug fixes
+
+  id and groups, when invoked with no user name argument, would print
+  the default group ID listed in the password database, and sometimes
+  that ID would be neither real nor effective.  For example, when run
+  set-GID, or in a session for which the default group has just been
+  changed, the new group ID would be listed, even though it is not
+  yet effective. [bug introduced in coreutils-8.1]
+
+  cp S D is no longer subject to a race: if an existing D were removed
+  between the initial stat and subsequent open-without-O_CREATE, cp would
+  fail with a confusing diagnostic saying that the destination, D, was not
+  found.  Now, in this unusual case, it retries the open (but with O_CREATE),
+  and hence usually succeeds.  With NFS attribute caching, the condition
+  was particularly easy to trigger, since there, the removal of D could
+  precede the initial stat.  [This bug was present in "the beginning".]
+
+  split --number=C /dev/null no longer appears to infloop on GNU/Hurd
+  [bug introduced in coreutils-8.8]
+
+  stat no longer reports a negative file size as a huge positive number.
+  [bug present since 'stat' was introduced in fileutils-4.1.9]
+
+** New features
+
+  split and truncate now allow any seekable files in situations where
+  the file size is needed, instead of insisting on regular files.
+
+  fmt now accepts the --goal=WIDTH (-g) option.
+
+  stat -f recognizes new file system types: bdevfs, inodefs, qnx6
+
+** Changes in behavior
+
+  cp,mv,install,cat,split: now read and write a minimum of 64KiB at a time.
+  This was previously 32KiB and increasing to 64KiB was seen to increase
+  throughput by about 10% when reading cached files on 64 bit GNU/Linux.
+
+  cp --attributes-only no longer truncates any existing destination file,
+  allowing for more general copying of attributes from one file to another.
+
+
+* Noteworthy changes in release 8.16 (2012-03-26) [stable]
+
+** New features
+
+  As a GNU extension, 'chmod', 'mkdir', and 'install' now accept operators
+  '-', '+', '=' followed by octal modes; for example, 'chmod +40 FOO' enables
+  and 'chmod -40 FOO' disables FOO's group-read permissions.  Operator
+  numeric modes can be combined with symbolic modes by separating them with
+  commas; for example, =0,u+r clears all permissions except for enabling
+  user-read permissions.  Unlike ordinary numeric modes, operator numeric
+  modes do not preserve directory setuid and setgid bits; for example,
+  'chmod =0 FOO' clears all of FOO's permissions, including setuid and setgid.
+
+  Also, ordinary numeric modes with five or more digits no longer preserve
+  setuid and setgid bits, so that 'chmod 00755 FOO' now clears FOO's setuid
+  and setgid bits.  This allows scripts to be portable to other systems which
+  lack the GNU extension mentioned previously, and where ordinary numeric
+  modes do not preserve directory setuid and setgid bits.
+
+  dd now accepts the count_bytes, skip_bytes iflags and the seek_bytes
+  oflag, to more easily allow processing portions of a file.
+
+  dd now accepts the conv=sparse flag to attempt to create sparse
+  output, by seeking rather than writing to the output file.
+
+  ln now accepts the --relative option, to generate a relative
+  symbolic link to a target, irrespective of how the target is specified.
+
+  split now accepts an optional "from" argument to --numeric-suffixes,
+  which changes the start number from the default of 0.
+
+  split now accepts the --additional-suffix option, to append an
+  additional static suffix to output file names.
+
+  basename now supports the -a and -s options, which allow processing
+  of more than one argument at a time.  Also the complementary
+  -z option was added to delimit output items with the NUL character.
+
+  dirname now supports more than one argument.  Also the complementary
+  -z option was added to delimit output items with the NUL character.
+
+** Bug fixes
+
+  du --one-file-system (-x) would ignore any non-directory specified on
+  the command line.  For example, "touch f; du -x f" would print nothing.
+  [bug introduced in coreutils-8.15]
+
+  mv now lets you move a symlink onto a same-inode destination file that
+  has two or more hard links.  Before, it would reject that, saying that
+  they are the same, implicitly warning you that the move would result in
+  data loss.  In this unusual case, when not moving the symlink onto its
+  referent, there is no risk of data loss, since the symlink will
+  typically still point to one of the hard links.
+
+  "mv A B" could succeed, yet A would remain.  This would happen only when
+  both A and B were hard links to the same symlink, and with a kernel for
+  which rename("A","B") does nothing and returns 0 (POSIX mandates this
+  surprising rename no-op behavior).  Now, mv handles this case by skipping
+  the usually-useless rename and simply unlinking A.
+
+  realpath no longer mishandles a root directory.  This was most
+  noticeable on platforms where // is a different directory than /,
+  but could also be observed with --relative-base=/ or
+  --relative-to=/.  [bug since the beginning, in 8.15]
+
+** Improvements
+
+  ls can be much more efficient, especially with large directories on file
+  systems for which getfilecon-, ACL-check- and XATTR-check-induced syscalls
+  fail with ENOTSUP or similar.
+
+  'realpath --relative-base=dir' in isolation now implies '--relative-to=dir'
+  instead of causing a usage failure.
+
+  split now supports an unlimited number of split files as default behavior.
+
+
+* Noteworthy changes in release 8.15 (2012-01-06) [stable]
+
+** New programs
+
+  realpath: print resolved file names.
+
+** Bug fixes
+
+  du -x no longer counts root directories of other file systems.
+  [bug introduced in coreutils-5.1.0]
+
+  ls --color many-entry-directory was uninterruptible for too long
+  [bug introduced in coreutils-5.2.1]
+
+  ls's -k option no longer affects how ls -l outputs file sizes.
+  It now affects only the per-directory block counts written by -l,
+  and the sizes written by -s.  This is for compatibility with BSD
+  and with POSIX 2008.  Because -k is no longer equivalent to
+  --block-size=1KiB, a new long option --kibibyte stands for -k.
+  [bug introduced in coreutils-4.5.4]
+
+  ls -l would leak a little memory (security context string) for each
+  nonempty directory listed on the command line, when using SELinux.
+  [bug probably introduced in coreutils-6.10 with SELinux support]
+
+  rm -rf DIR would fail with "Device or resource busy" on Cygwin with NWFS
+  and NcFsd file systems.  This did not affect Unix/Linux-based kernels.
+  [bug introduced in coreutils-8.0, when rm began using fts]
+
+  split -n 1/2 FILE no longer fails when operating on a growing file, or
+  (on some systems) when operating on a non-regular file like /dev/zero.
+  It would report "/dev/zero: No such file or directory" even though
+  the file obviously exists.  Same for -n l/2.
+  [bug introduced in coreutils-8.8, with the addition of the -n option]
+
+  stat -f now recognizes the FhGFS and PipeFS file system types.
+
+  tac no longer fails to handle two or more non-seekable inputs
+  [bug introduced in coreutils-5.3.0]
+
+  tail -f no longer tries to use inotify on GPFS or FhGFS file systems
+  [you might say this was introduced in coreutils-7.5, along with inotify
+   support, but the new magic numbers weren't in the usual places then.]
+
+** Changes in behavior
+
+  df avoids long UUID-including file system names in the default listing.
+  With recent enough kernel/tools, these long names would be used, pushing
+  second and subsequent columns far to the right.  Now, when a long name
+  refers to a symlink, and no file systems are specified, df prints the
+  usually-short referent instead.
+
+  tail -f now uses polling (not inotify) when any of its file arguments
+  resides on a file system of unknown type.  In addition, for each such
+  argument, tail -f prints a warning with the FS type magic number and a
+  request to report it to the bug-reporting address.
+
+
+* Noteworthy changes in release 8.14 (2011-10-12) [stable]
+
+** Bug fixes
+
+  ls --dereference no longer outputs erroneous "argetm" strings for
+  dangling symlinks when an 'ln=target' entry is in $LS_COLORS.
+  [bug introduced in fileutils-4.0]
+
+  ls -lL symlink once again properly prints "+" when the referent has an ACL.
+  [bug introduced in coreutils-8.13]
+
+  sort -g no longer infloops for certain inputs containing NaNs
+  [bug introduced in coreutils-8.5]
+
+** Improvements
+
+  md5sum --check now supports the -r format from the corresponding BSD tool.
+  This also affects sha1sum, sha224sum, sha384sum and sha512sum.
+
+  pwd now works also on systems without openat.  On such systems, pwd
+  would fail when run from a directory whose absolute name contained
+  more than PATH_MAX / 3 components.  The df, stat and readlink programs
+  are also affected due to their use of the canonicalize_* functions.
+
+** Changes in behavior
+
+  timeout now only processes the first signal received from the set
+  it is handling (SIGTERM, SIGINT, ...).  This is to support systems that
+  implicitly create threads for some timer functions (like GNU/kFreeBSD).
+
+** Build-related
+
+  "make dist" no longer builds .tar.gz files.
+  xz is portable enough and in wide-enough use that distributing
+  only .tar.xz files is enough.
+
+
+* Noteworthy changes in release 8.13 (2011-09-08) [stable]
+
+** Bug fixes
+
+  chown and chgrp with the -v --from= options, now output the correct owner.
+  I.e., for skipped files, the original ownership is output, not the new one.
+  [bug introduced in sh-utils-2.0g]
+
+  cp -r could mistakenly change the permissions of an existing destination
+  directory.  [bug introduced in coreutils-6.8]
+
+  cp -u -p would fail to preserve one hard link for each up-to-date copy
+  of a src-hard-linked name in the destination tree.  I.e., if s/a and s/b
+  are hard-linked and dst/s/a is up to date, "cp -up s dst" would copy s/b
+  to dst/s/b rather than simply linking dst/s/b to dst/s/a.
+  [This bug appears to have been present in "the beginning".]
+
+  fts-using tools (rm, du, chmod, chgrp, chown, chcon) no longer use memory
+  proportional to the number of entries in each directory they process.
+  Before, rm -rf 4-million-entry-directory would consume about 1GiB of memory.
+  Now, it uses less than 30MB, no matter how many entries there are.
+  [this bug was inherent in the use of fts: thus, for rm the bug was
+  introduced in coreutils-8.0.  The prior implementation of rm did not use
+  as much memory.  du, chmod, chgrp and chown started using fts in 6.0.
+  chcon was added in coreutils-6.9.91 with fts support.  ]
+
+  pr -T no longer ignores a specified LAST_PAGE to stop at.
+  [bug introduced in textutils-1.19q]
+
+  printf '%d' '"' no longer accesses out-of-bounds memory in the diagnostic.
+  [bug introduced in sh-utils-1.16]
+
+  split --number l/... no longer creates extraneous files in certain cases.
+  [bug introduced in coreutils-8.8]
+
+  timeout now sends signals to commands that create their own process group.
+  timeout is no longer confused when starting off with a child process.
+  [bugs introduced in coreutils-7.0]
+
+  unexpand -a now aligns correctly when there are spaces spanning a tabstop,
+  followed by a tab.  In that case a space was dropped, causing misalignment.
+  We also now ensure that a space never precedes a tab.
+  [bug introduced in coreutils-5.3.0]
+
+** Changes in behavior
+
+  chmod, chown and chgrp now output the original attributes in messages,
+  when -v or -c specified.
+
+  cp -au (where --preserve=links is implicit) may now replace newer
+  files in the destination, to mirror hard links from the source.
+
+** New features
+
+  date now accepts ISO 8601 date-time strings with "T" as the
+  separator.  It has long parsed dates like "2004-02-29 16:21:42"
+  with a space between the date and time strings.  Now it also parses
+  "2004-02-29T16:21:42" and fractional-second and time-zone-annotated
+  variants like "2004-02-29T16:21:42.333-07:00"
+
+  md5sum accepts the new --strict option.  With --check, it makes the
+  tool exit non-zero for any invalid input line, rather than just warning.
+  This also affects sha1sum, sha224sum, sha384sum and sha512sum.
+
+  split accepts a new --filter=CMD option.  With it, split filters output
+  through CMD.  CMD may use the $FILE environment variable, which is set to
+  the nominal output file name for each invocation of CMD.  For example, to
+  split a file into 3 approximately equal parts, which are then compressed:
+    split -n3 --filter='xz > $FILE.xz' big
+  Note the use of single quotes, not double quotes.
+  That creates files named xaa.xz, xab.xz and xac.xz.
+
+  timeout accepts a new --foreground option, to support commands not started
+  directly from a shell prompt, where the command is interactive or needs to
+  receive signals initiated from the terminal.
+
+** Improvements
+
+  cp -p now copies trivial NSFv4 ACLs on Solaris 10.  Before, it would
+  mistakenly apply a non-trivial ACL to the destination file.
+
+  cp and ls now support HP-UX 11.11's ACLs, thanks to improved support
+  in gnulib.
+
+  df now supports disk partitions larger than 4 TiB on MacOS X 10.5
+  or newer and on AIX 5.2 or newer.
+
+  join --check-order now prints "join: FILE:LINE_NUMBER: bad_line" for an
+  unsorted input, rather than e.g., "join: file 1 is not in sorted order".
+
+  shuf outputs small subsets of large permutations much more efficiently.
+  For example 'shuf -i1-$((2**32-1)) -n2' no longer exhausts memory.
+
+  stat -f now recognizes the GPFS, MQUEUE and PSTOREFS file system types.
+
+  timeout now supports sub-second timeouts.
+
+** Build-related
+
+  Changes inherited from gnulib address a build failure on HP-UX 11.11
+  when using /opt/ansic/bin/cc.
+
+  Numerous portability and build improvements inherited via gnulib.
+
+
+* Noteworthy changes in release 8.12 (2011-04-26) [stable]
+
+** Bug fixes
+
+  tail's --follow=name option no longer implies --retry on systems
+  with inotify support.  [bug introduced in coreutils-7.5]
+
+** Changes in behavior
+
+  cp's extent-based (FIEMAP) copying code is more reliable in the face
+  of varying and undocumented file system semantics:
+  - it no longer treats unwritten extents specially
+  - a FIEMAP-based extent copy always uses the FIEMAP_FLAG_SYNC flag.
+      Before, it would incur the performance penalty of that sync only
+      for 2.6.38 and older kernels.  We thought all problems would be
+      resolved for 2.6.39.
+  - it now attempts a FIEMAP copy only on a file that appears sparse.
+      Sparse files are relatively unusual, and the copying code incurs
+      the performance penalty of the now-mandatory sync only for them.
+
+** Portability
+
+  dd once again compiles on AIX 5.1 and 5.2
+
+
+* Noteworthy changes in release 8.11 (2011-04-13) [stable]
+
+** Bug fixes
+
+  cp -a --link would not create a hardlink to a symlink, instead
+  copying the symlink and then not preserving its timestamp.
+  [bug introduced in coreutils-8.0]
+
+  cp now avoids FIEMAP issues with BTRFS before Linux 2.6.38,
+  which could result in corrupt copies of sparse files.
+  [bug introduced in coreutils-8.10]
+
+  cut could segfault when invoked with a user-specified output
+  delimiter and an unbounded range like "-f1234567890-".
+  [bug introduced in coreutils-5.3.0]
+
+  du would infloop when given --files0-from=DIR
+  [bug introduced in coreutils-7.1]
+
+  sort no longer spawns 7 worker threads to sort 16 lines
+  [bug introduced in coreutils-8.6]
+
+  touch built on Solaris 9 would segfault when run on Solaris 10
+  [bug introduced in coreutils-8.8]
+
+  wc would dereference a NULL pointer upon an early out-of-memory error
+  [bug introduced in coreutils-7.1]
+
+** New features
+
+  dd now accepts the 'nocache' flag to the iflag and oflag options,
+  which will discard any cache associated with the files, or
+  processed portion thereof.
+
+  dd now warns that 'iflag=fullblock' should be used,
+  in various cases where partial reads can cause issues.
+
+** Changes in behavior
+
+  cp now avoids syncing files when possible, when doing a FIEMAP copy.
+  The sync is only needed on Linux kernels before 2.6.39.
+  [The sync was introduced in coreutils-8.10]
+
+  cp now copies empty extents efficiently, when doing a FIEMAP copy.
+  It no longer reads the zero bytes from the input, and also can efficiently
+  create a hole in the output file when --sparse=always is specified.
+
+  df now aligns columns consistently, and no longer wraps entries
+  with longer device identifiers, over two lines.
+
+  install now rejects its long-deprecated --preserve_context option.
+  Use --preserve-context instead.
+
+  test now accepts "==" as a synonym for "="
+
+
+* Noteworthy changes in release 8.10 (2011-02-04) [stable]
+
+** Bug fixes
+
+  du would abort with a failed assertion when two conditions are met:
+  part of the hierarchy being traversed is moved to a higher level in the
+  directory tree, and there is at least one more command line directory
+  argument following the one containing the moved sub-tree.
+  [bug introduced in coreutils-5.1.0]
+
+  join --header now skips the ordering check for the first line
+  even if the other file is empty.  [bug introduced in coreutils-8.5]
+
+  join -v2 now ensures the default output format prints the match field
+  at the start of the line when it is different to the match field for
+  the first file. [bug present in "the beginning".]
+
+  rm -f no longer fails for EINVAL or EILSEQ on file systems that
+  reject file names invalid for that file system.
+
+  uniq -f NUM no longer tries to process fields after end of line.
+  [bug introduced in coreutils-7.0]
+
+** New features
+
+  cp now copies sparse files efficiently on file systems with FIEMAP
+  support (ext4, btrfs, xfs, ocfs2).  Before, it had to read 2^20 bytes
+  when copying a 1MiB sparse file.  Now, it copies bytes only for the
+  non-sparse sections of a file.  Similarly, to induce a hole in the
+  output file, it had to detect a long sequence of zero bytes.  Now,
+  it knows precisely where each hole in an input file is, and can
+  reproduce them efficiently in the output file.  mv also benefits
+  when it resorts to copying, e.g., between file systems.
+
+  join now supports -o 'auto' which will automatically infer the
+  output format from the first line in each file, to ensure
+  the same number of fields are output for each line.
+
+** Changes in behavior
+
+  join no longer reports disorder when one of the files is empty.
+  This allows one to use join as a field extractor like:
+  join -a1 -o 1.3,1.1 - /dev/null
+
+
+* Noteworthy changes in release 8.9 (2011-01-04) [stable]
+
+** Bug fixes
+
+  split no longer creates files with a suffix length that
+  is dependent on the number of bytes or lines per file.
+  [bug introduced in coreutils-8.8]
+
+
+* Noteworthy changes in release 8.8 (2010-12-22) [stable]
+
+** Bug fixes
+
+  cp -u no longer does unnecessary copying merely because the source
+  has finer-grained timestamps than the destination.
+
+  od now prints floating-point numbers without losing information, and
+  it no longer omits spaces between floating-point columns in some cases.
+
+  sort -u with at least two threads could attempt to read through a
+  corrupted pointer. [bug introduced in coreutils-8.6]
+
+  sort with at least two threads and with blocked output would busy-loop
+  (spinlock) all threads, often using 100% of available CPU cycles to
+  do no work.  I.e., "sort < big-file | less" could waste a lot of power.
+  [bug introduced in coreutils-8.6]
+
+  sort with at least two threads no longer segfaults due to use of pointers
+  into the stack of an expired thread. [bug introduced in coreutils-8.6]
+
+  sort --compress no longer mishandles subprocesses' exit statuses,
+  no longer hangs indefinitely due to a bug in waiting for subprocesses,
+  and no longer generates many more than NMERGE subprocesses.
+
+  sort -m -o f f ... f no longer dumps core when file descriptors are limited.
+
+** Changes in behavior
+
+  sort will not create more than 8 threads by default due to diminishing
+  performance gains.  Also the --parallel option is no longer restricted
+  to the number of available processors.
+
+** New features
+
+  split accepts the --number/-n option to generate a specific number of
+  files, as well as the --elide-empty-files/-e and --unbuffered/-u
+  options to fine-tune the resulting output.
+
+
+* Noteworthy changes in release 8.7 (2010-11-13) [stable]
+
+** Bug fixes
+
+  cp, install, mv, and touch no longer crash when setting file times
+  on Solaris 10 Update 9 [Solaris PatchID 144488 and newer expose a
+  latent bug introduced in coreutils 8.1, and possibly a second latent
+  bug going at least as far back as coreutils 5.97]
+
+  csplit no longer corrupts heap when writing more than 999 files,
+  nor does it leak memory for every chunk of input processed
+  [the bugs were present in the initial implementation]
+
+  tail -F once again notices changes in a currently unavailable
+  remote directory [bug introduced in coreutils-7.5]
+
+** Changes in behavior
+
+  cp --attributes-only now completely overrides --reflink.
+  Previously a reflink was needlessly attempted.
+
+  stat's %X, %Y, and %Z directives once again print only the integer
+  part of seconds since the epoch.  This reverts a change from
+  coreutils-8.6, that was deemed unnecessarily disruptive.
+  To obtain a nanosecond-precision timestamp for %X use %.X;
+  if you want (say) just 3 fractional digits, use %.3X.
+  Likewise for %Y and %Z.
+
+  stat's new %W format directive would print floating point seconds.
+  However, with the above change to %X, %Y and %Z, we've made %W work
+  the same way as the others.
+
+  stat gained support for several printf-style flags, such as %'s for
+  listing sizes with the current locale's thousands separator.
+
+
+* Noteworthy changes in release 8.6 (2010-10-15) [stable]
+
+** Bug fixes
+
+  du no longer multiply counts a file that is a directory or whose
+  link count is 1, even if the file is reached multiple times by
+  following symlinks or via multiple arguments.
+
+  du -H and -L now consistently count pointed-to files instead of
+  symbolic links, and correctly diagnose dangling symlinks.
+
+  du --ignore=D now ignores directory D even when that directory is
+  found to be part of a directory cycle.  Before, du would issue a
+  "NOTIFY YOUR SYSTEM MANAGER" diagnostic and fail.
+
+  split now diagnoses read errors rather than silently exiting.
+  [bug introduced in coreutils-4.5.8]
+
+  tac would perform a double-free when given an input line longer than 16KiB.
+  [bug introduced in coreutils-8.3]
+
+  tail -F once again notices changes in a currently unavailable directory,
+  and works around a Linux kernel bug where inotify runs out of resources.
+  [bugs introduced in coreutils-7.5]
+
+  tr now consistently handles case conversion character classes.
+  In some locales, valid conversion specifications caused tr to abort,
+  while in all locales, some invalid specifications were undiagnosed.
+  [bugs introduced in coreutils 6.9.90 and 6.9.92]
+
+** New features
+
+  cp now accepts the --attributes-only option to not copy file data,
+  which is useful for efficiently modifying files.
+
+  du recognizes -d N as equivalent to --max-depth=N, for compatibility
+  with FreeBSD.
+
+  sort now accepts the --debug option, to highlight the part of the
+  line significant in the sort, and warn about questionable options.
+
+  sort now supports -d, -f, -i, -R, and -V in any combination.
+
+  stat now accepts the %m format directive to output the mount point
+  for a file.  It also accepts the %w and %W format directives for
+  outputting the birth time of a file, if one is available.
+
+** Changes in behavior
+
+  df now consistently prints the device name for a bind mounted file,
+  rather than its aliased target.
+
+  du now uses less than half as much memory when operating on trees
+  with many hard-linked files.  With --count-links (-l), or when
+  operating on trees with no hard-linked files, there is no change.
+
+  ls -l now uses the traditional three field time style rather than
+  the wider two field numeric ISO style, in locales where a style has
+  not been specified.  The new approach has nicer behavior in some
+  locales, including English, which was judged to outweigh the disadvantage
+  of generating less-predictable and often worse output in poorly-configured
+  locales where there is an onus to specify appropriate non-default styles.
+  [The old behavior was introduced in coreutils-6.0 and had been removed
+   for English only using a different method since coreutils-8.1]
+
+  rm's -d now evokes an error;  before, it was silently ignored.
+
+  sort -g now uses long doubles for greater range and precision.
+
+  sort -h no longer rejects numbers with leading or trailing ".", and
+  no longer accepts numbers with multiple ".".  It now considers all
+  zeros to be equal.
+
+  sort now uses the number of available processors to parallelize
+  the sorting operation.  The number of sorts run concurrently can be
+  limited with the --parallel option or with external process
+  control like taskset for example.
+
+  stat now provides translated output when no format is specified.
+
+  stat no longer accepts the --context (-Z) option.  Initially it was
+  merely accepted and ignored, for compatibility.  Starting two years
+  ago, with coreutils-7.0, its use evoked a warning.  Printing the
+  SELinux context of a file can be done with the %C format directive,
+  and the default output when no format is specified now automatically
+  includes %C when context information is available.
+
+  stat no longer accepts the %C directive when the --file-system
+  option is in effect, since security context is a file attribute
+  rather than a file system attribute.
+
+  stat now outputs the full sub-second resolution for the atime,
+  mtime, and ctime values since the Epoch, when using the %X, %Y, and
+  %Z directives of the --format option.  This matches the fact that
+  %x, %y, and %z were already doing so for the human-readable variant.
+
+  touch's --file option is no longer recognized.  Use --reference=F (-r)
+  instead.  --file has not been documented for 15 years, and its use has
+  elicited a warning since coreutils-7.1.
+
+  truncate now supports setting file sizes relative to a reference file.
+  Also errors are no longer suppressed for unsupported file types, and
+  relative sizes are restricted to supported file types.
+
+
+* Noteworthy changes in release 8.5 (2010-04-23) [stable]
+
+** Bug fixes
+
+  cp and mv once again support preserving extended attributes.
+  [bug introduced in coreutils-8.4]
+
+  cp now preserves "capabilities" when also preserving file ownership.
+
+  ls --color once again honors the 'NORMAL' dircolors directive.
+  [bug introduced in coreutils-6.11]
+
+  sort -M now handles abbreviated months that are aligned using blanks
+  in the locale database.  Also locales with 8 bit characters are
+  handled correctly, including multi byte locales with the caveat
+  that multi byte characters are matched case sensitively.
+
+  sort again handles obsolescent key formats (+POS -POS) correctly.
+  Previously if -POS was specified, 1 field too many was used in the sort.
+  [bug introduced in coreutils-7.2]
+
+** New features
+
+  join now accepts the --header option, to treat the first line of each
+  file as a header line to be joined and printed unconditionally.
+
+  timeout now accepts the --kill-after option which sends a kill
+  signal to the monitored command if it's still running the specified
+  duration after the initial signal was sent.
+
+  who: the "+/-" --mesg (-T) indicator of whether a user/tty is accepting
+  messages could be incorrectly listed as "+", when in fact, the user was
+  not accepting messages (mesg no).  Before, who would examine only the
+  permission bits, and not consider the group of the TTY device file.
+  Thus, if a login tty's group would change somehow e.g., to "root",
+  that would make it unwritable (via write(1)) by normal users, in spite
+  of whatever the permission bits might imply.  Now, when configured
+  using the --with-tty-group[=NAME] option, who also compares the group
+  of the TTY device with NAME (or "tty" if no group name is specified).
+
+** Changes in behavior
+
+  ls --color no longer emits the final 3-byte color-resetting escape
+  sequence when it would be a no-op.
+
+  join -t '' no longer emits an error and instead operates on
+  each line as a whole (even if they contain NUL characters).
+
+
+* Noteworthy changes in release 8.4 (2010-01-13) [stable]
+
+** Bug fixes
+
+  nproc --all is now guaranteed to be as large as the count
+  of available processors, which may not have been the case
+  on GNU/Linux systems with neither /proc nor /sys available.
+  [bug introduced in coreutils-8.1]
+
+** Build-related
+
+  Work around a build failure when using buggy <sys/capability.h>.
+  Alternatively, configure with --disable-libcap.
+
+  Compilation would fail on systems using glibc-2.7..2.9 due to changes in
+  gnulib's wchar.h that tickled a bug in at least those versions of glibc's
+  own <wchar.h> header.  Now, gnulib works around the bug in those older
+  glibc <wchar.h> headers.
+
+  Building would fail with a link error (cp/copy.o) when XATTR headers
+  were installed without the corresponding library.  Now, configure
+  detects that and disables xattr support, as one would expect.
+
+
+* Noteworthy changes in release 8.3 (2010-01-07) [stable]
+
+** Bug fixes
+
+  cp -p, install -p, mv, and touch -c could trigger a spurious error
+  message when using new glibc coupled with an old kernel.
+  [bug introduced in coreutils-6.12].
+
+  ls -l --color no longer prints "argetm" in front of dangling
+  symlinks when the 'LINK target' directive was given to dircolors.
+  [bug introduced in fileutils-4.0]
+
+  pr's page header was improperly formatted for long file names.
+  [bug introduced in coreutils-7.2]
+
+  rm -r --one-file-system works once again.
+  The rewrite to make rm use fts introduced a regression whereby
+  a commmand of the above form would fail for all subdirectories.
+  [bug introduced in coreutils-8.0]
+
+  stat -f recognizes more file system types: k-afs, fuseblk, gfs/gfs2, ocfs2,
+  and rpc_pipefs. Also Minix V3 is displayed correctly as minix3, not minux3.
+  [bug introduced in coreutils-8.1]
+
+  tail -f (inotify-enabled) once again works with remote files.
+  The use of inotify with remote files meant that any changes to those
+  files that was not done from the local system would go unnoticed.
+  [bug introduced in coreutils-7.5]
+
+  tail -F (inotify-enabled) would abort when a tailed file is repeatedly
+  renamed-aside and then recreated.
+  [bug introduced in coreutils-7.5]
+
+  tail -F (inotify-enabled) could fail to follow renamed files.
+  E.g., given a "tail -F a b" process, running "mv a b" would
+  make tail stop tracking additions to "b".
+  [bug introduced in coreutils-7.5]
+
+  touch -a and touch -m could trigger bugs in some file systems, such
+  as xfs or ntfs-3g, and fail to update timestamps.
+  [bug introduced in coreutils-8.1]
+
+  wc now prints counts atomically so that concurrent
+  processes will not intersperse their output.
+  [the issue dates back to the initial implementation]
+
+
+* Noteworthy changes in release 8.2 (2009-12-11) [stable]
+
+** Bug fixes
+
+  id's use of mgetgroups no longer writes beyond the end of a malloc'd buffer
+  [bug introduced in coreutils-8.1]
+
+  id no longer crashes on systems without supplementary group support.
+  [bug introduced in coreutils-8.1]
+
+  rm once again handles zero-length arguments properly.
+  The rewrite to make rm use fts introduced a regression whereby
+  a command like "rm a '' b" would fail to remove "a" and "b", due to
+  the presence of the empty string argument.
+  [bug introduced in coreutils-8.0]
+
+  sort is now immune to the signal handling of its parent.
+  Specifically sort now doesn't exit with an error message
+  if it uses helper processes for compression and its parent
+  ignores CHLD signals. [bug introduced in coreutils-6.9]
+
+  tail without -f no longer accesses uninitialized memory
+  [bug introduced in coreutils-7.6]
+
+  timeout is now immune to the signal handling of its parent.
+  Specifically timeout now doesn't exit with an error message
+  if its parent ignores CHLD signals. [bug introduced in coreutils-7.6]
+
+  a user running "make distcheck" in the coreutils source directory,
+  with TMPDIR unset or set to the name of a world-writable directory,
+  and with a malicious user on the same system
+  was vulnerable to arbitrary code execution
+  [bug introduced in coreutils-5.0]
+
+
+* Noteworthy changes in release 8.1 (2009-11-18) [stable]
+
+** 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]
+
+  chcon, chgrp, chmod, chown and du now diagnose an ostensible directory cycle
+  and arrange to exit nonzero.  Before, they would silently ignore the
+  offending directory and all "contents."
+
+  env -u A=B now fails, rather than silently adding A to the
+  environment.  Likewise, printenv A=B silently ignores the invalid
+  name.  [the bugs date back to the initial implementation]
+
+  ls --color now handles files with capabilities correctly.  Previously
+  files with capabilities were often not colored, and also sometimes, files
+  without capabilites were colored in error. [bug introduced in coreutils-7.0]
+
+  md5sum now prints checksums atomically so that concurrent
+  processes will not intersperse their output.
+  This also affected sum, sha1sum, sha224sum, sha384sum and sha512sum.
+  [the bug dates back to the initial implementation]
+
+  mktemp no longer leaves a temporary file behind if it was unable to
+  output the name of the file to stdout.
+  [the bug dates back to the initial implementation]
+
+  nice -n -1 PROGRAM now runs PROGRAM even when its internal setpriority
+  call fails with errno == EACCES.
+  [the bug dates back to the initial implementation]
+
+  nice, nohup, and su now refuse to execute the subsidiary program if
+  they detect write failure in printing an otherwise non-fatal warning
+  message to stderr.
+
+  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
+
+  tail -f (inotify-enabled) now avoids a race condition.
+  Before, any data appended in the tiny interval between the initial
+  read-to-EOF and the inotify watch initialization would be ignored
+  initially (until more data was appended), or forever, if the file
+  were first renamed or unlinked or never modified.
+  [The race was introduced in coreutils-7.5]
+
+  tail -F (inotify-enabled) now consistently tails a file that has been
+  replaced via renaming.  That operation provokes either of two sequences
+  of inotify events.  The less common sequence is now handled as well.
+  [The bug came with the implementation change in coreutils-7.5]
+
+  timeout now doesn't exit unless the command it is monitoring does,
+  for any specified signal. [bug introduced in coreutils-7.0].
+
+** Changes in behavior
+
+  chroot, env, nice, and su fail with status 125, rather than 1, on
+  internal error such as failure to parse command line arguments; this
+  is for consistency with stdbuf and timeout, and avoids ambiguity
+  with the invoked command failing with status 1.  Likewise, nohup
+  fails with status 125 instead of 127.
+
+  du (due to a change in gnulib's fts) can now traverse NFSv4 automounted
+  directories in which the stat'd device number of the mount point differs
+  during a traversal.  Before, it would fail, because such a mismatch would
+  usually represent a serious error or a subversion attempt.
+
+  echo and printf now interpret \e as the Escape character (0x1B).
+
+  rm -f /read-only-fs/nonexistent now succeeds and prints no diagnostic
+  on systems with an unlinkat syscall that sets errno to EROFS in that case.
+  Before, it would fail with a "Read-only file system" diagnostic.
+  Also, "rm /read-only-fs/nonexistent" now reports "file not found" rather
+  than the less precise "Read-only file system" error.
+
+** New programs
+
+  nproc: Print the number of processing units available to a process.
+
+** New features
+
+  env and printenv now accept the option --null (-0), as a means to
+  avoid ambiguity with newlines embedded in the environment.
+
+  md5sum --check now also accepts openssl-style checksums.
+  So do sha1sum, sha224sum, sha384sum and sha512sum.
+
+  mktemp now accepts the option --suffix to provide a known suffix
+  after the substitution in the template.  Additionally, uses such as
+  "mktemp fileXXXXXX.txt" are able to infer an appropriate --suffix.
+
+  touch now accepts the option --no-dereference (-h), as a means to
+  change symlink timestamps on platforms with enough support.
+
+
+* 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 preceding 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 timestamp, when it is
+  due to their running on a kernel older than what was implied by headers
+  and libraries tested at configure time.
+  [bug introduced in coreutils-7.5]
+
+  cp --reflink --preserve now preserves attributes when cloning a file.
+  [bug introduced in coreutils-7.5]
+
+  cp --preserve=xattr no longer leaks resources on each preservation failure.
+  [bug introduced in coreutils-7.1]
+
+  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]
+
+  ls -i now prints consistent inode numbers also for mount points.
+  This makes ls -i DIR less efficient on systems with dysfunctional readdir,
+  because ls must stat every file in order to obtain a guaranteed-valid
+  inode number.  [bug introduced in coreutils-6.0]
+
+  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]
+
+  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
+
+  dd's oflag=direct option now works even when the size of the input
+  is not a multiple of e.g., 512 bytes.
+
+  dd now handles signals consistently even when they're received
+  before data copying has started.
+
+  install runs faster again with SELinux enabled
+  [introduced in coreutils-7.0]
+
+  ls -1U (with two or more arguments, at least one a nonempty directory)
+  would print entry names *before* the name of the containing directory.
+  Also fixed incorrect output of ls -1RU and ls -1sU.
+  [introduced in coreutils-7.0]
+
+  sort now correctly ignores fields whose ending position is specified
+  before the start position. Previously in numeric mode the remaining
+  part of the line after the start position was used as the sort key.
+  [This bug appears to have been present in "the beginning".]
+
+  truncate -s failed to skip all whitespace in the option argument in
+  some locales.
+
+** New programs
+
+  stdbuf: A new program to run a command with modified stdio buffering
+  for its standard streams.
+
+** Changes in behavior
+
+  ls --color: files with multiple hard links are no longer colored differently
+  by default. That can be enabled by changing the LS_COLORS environment
+  variable. You can control that using the MULTIHARDLINK dircolors input
+  variable which corresponds to the 'mh' LS_COLORS item. Note these variables
+  were renamed from 'HARDLINK' and 'hl' which were available since
+  coreutils-7.1 when this feature was introduced.
+
+** Deprecated options
+
+  nl --page-increment: deprecated in favor of --line-increment, the new option
+  maintains the previous semantics and the same short option, -i.
+
+** New features
+
+  chroot now accepts the options --userspec and --groups.
+
+  cp accepts a new option, --reflink: create a lightweight copy
+  using copy-on-write (COW).  This is currently only supported within
+  a btrfs file system.
+
+  cp now preserves timestamps on symbolic links, when possible
+
+  sort accepts a new option, --human-numeric-sort (-h): sort numbers
+  while honoring human readable suffixes like KiB and MB etc.
+
+  tail --follow now uses inotify when possible, to be more responsive
+  to file changes and more efficient when monitoring many files.
+
+
+* Noteworthy changes in release 7.4 (2009-05-07) [stable]
+
+** Bug fixes
+
+  date -d 'next mon', when run on a Monday, now prints the date
+  7 days in the future rather than the current day.  Same for any other
+  day-of-the-week name, when run on that same day of the week.
+  [This bug appears to have been present in "the beginning". ]
+
+  date -d tuesday, when run on a Tuesday -- using date built from the 7.3
+  release tarball, not from git -- would print the date 7 days in the future.
+  Now, it works properly and prints the current date.  That was due to
+  human error (including not-committed changes in a release tarball)
+  and the fact that there is no check to detect when the gnulib/ git
+  submodule is dirty.
+
+** Build-related
+
+  make check: two tests have been corrected
+
+** Portability
+
+  There have been some ACL-related portability fixes for *BSD,
+  inherited from gnulib.
+
+
+* Noteworthy changes in release 7.3 (2009-05-01) [stable]
+
+** Bug fixes
+
+  cp now diagnoses failure to preserve selinux/xattr attributes when
+  --preserve=context,xattr is specified in combination with -a.
+  Also, cp no longer suppresses attribute-preservation diagnostics
+  when preserving SELinux context was explicitly requested.
+
+  ls now aligns output correctly in the presence of abbreviated month
+  names from the locale database that have differing widths.
+
+  ls -v and sort -V now order names like "#.b#" properly
+
+  mv: do not print diagnostics when failing to preserve xattr's on file
+  systems without xattr support.
+
+  sort -m no longer segfaults when its output file is also an input file.
+  E.g., with this, touch 1; sort -m -o 1 1, sort would segfault.
+  [introduced in coreutils-7.2]
+
+** Changes in behavior
+
+  shred, sort, shuf: now use an internal pseudorandom generator by default.
+  This is mainly noticeable in shred where the 3 random passes it does by
+  default should proceed at the speed of the disk.  Previously /dev/urandom
+  was used if available, which is relatively slow on GNU/Linux systems.
+
+** Improved robustness
+
+  cp would exit successfully after copying less than the full contents
+  of a file larger than ~4000 bytes from a linux-/proc file system to a
+  destination file system with a fundamental block size of 4KiB or greater.
+  Reading into a 4KiB-or-larger buffer, cp's "read" syscall would return
+  a value smaller than 4096, and cp would interpret that as EOF (POSIX
+  allows this).  This optimization, now removed, saved 50% of cp's read
+  syscalls when copying small files.  Affected linux kernels: at least
+  2.6.9 through 2.6.29.
+  [the optimization was introduced in coreutils-6.0]
+
+** Portability
+
+  df now pre-mounts automountable directories even with automounters for
+  which stat-like syscalls no longer provoke mounting.  Now, df uses open.
+
+  'id -G $USER' now works correctly even on Darwin and NetBSD. Previously it
+  would either truncate the group list to 10, or go into an infinite loop,
+  due to their non-standard getgrouplist implementations.
+  [truncation introduced in coreutils-6.11]
+  [infinite loop introduced in coreutils-7.1]
+
+
+* Noteworthy changes in release 7.2 (2009-03-31) [stable]
+
+** New features
+
+  pwd now accepts the options --logical (-L) and --physical (-P).  For
+  compatibility with existing scripts, -P is the default behavior
+  unless POSIXLY_CORRECT is requested.
+
+** Bug fixes
+
+  cat once again immediately outputs data it has processed.
+  Previously it would have been buffered and only output if enough
+  data was read, or on process exit.
+  [bug introduced in coreutils-6.0]
+
+  comm's new --check-order option would fail to detect disorder on any pair
+  of lines where one was a prefix of the other.  For example, this would
+  fail to report the disorder: printf 'Xb\nX\n'>k; comm --check-order k k
+  [bug introduced in coreutils-7.0]
+
+  cp once again diagnoses the invalid "cp -rl dir dir" right away,
+  rather than after creating a very deep dir/dir/dir/... hierarchy.
+  The bug strikes only with both --recursive (-r, -R) and --link (-l).
+  [bug introduced in coreutils-7.1]
+
+  ls --sort=version (-v) sorted names beginning with "." inconsistently.
+  Now, names that start with "." are always listed before those that don't.
+
+  pr: fix the bug whereby --indent=N (-o) did not indent header lines
+  [bug introduced in coreutils-6.9.90]
+
+  sort now handles specified key ends correctly.
+  Previously -k1,1b would have caused leading space from field 2 to be
+  included in the sort while -k2,3.0 would have not included field 3.
+
+** Changes in behavior
+
+  cat,cp,install,mv,split: these programs now read and write a minimum
+  of 32KiB at a time.  This was seen to double throughput when reading
+  cached files on GNU/Linux-based systems.
+
+  cp -a now tries to preserve extended attributes (xattr), but does not
+  diagnose xattr-preservation failure.  However, cp --preserve=all still does.
+
+  ls --color: hard link highlighting can be now disabled by changing the
+  LS_COLORS environment variable. To disable it you can add something like
+  this to your profile: eval `dircolors | sed s/hl=[^:]*:/hl=:/`
+
+
+* Noteworthy changes in release 7.1 (2009-02-21) [stable]
+
+** New features
+
+  Add extended attribute support available on certain filesystems like ext2
+  and XFS.
+    cp: Tries to copy xattrs when --preserve=xattr or --preserve=all specified
+    mv: Always tries to copy xattrs
+    install: Never copies xattrs
+
+  cp and mv accept a new option, --no-clobber (-n): silently refrain
+  from overwriting any existing destination file
+
+  dd accepts iflag=cio and oflag=cio to open the file in CIO (concurrent I/O)
+  mode where this feature is available.
+
+  install accepts a new option, --compare (-C): compare each pair of source
+  and destination files, and if the destination has identical content and
+  any specified owner, group, permissions, and possibly SELinux context, then
+  do not modify the destination at all.
+
+  ls --color now highlights hard linked files, too
+
+  stat -f recognizes the Lustre file system type
+
+** Bug fixes
+
+  chgrp, chmod, chown --silent (--quiet, -f) no longer print some diagnostics
+  [bug introduced in coreutils-5.1]
+
+  cp uses much less memory in some situations
+
+  cp -a now correctly tries to preserve SELinux context (announced in 6.9.90),
+  doesn't inform about failure, unlike with --preserve=all
+
+  du --files0-from=FILE no longer reads all of FILE into RAM before
+  processing the first file name
+
+  seq 9223372036854775807 9223372036854775808 now prints only two numbers
+  on systems with extended long double support and good library support.
+  Even with this patch, on some systems, it still produces invalid output,
+  from 3 to at least 1026 lines long. [bug introduced in coreutils-6.11]
+
+  seq -w now accounts for a decimal point added to the last number
+  to correctly print all numbers to the same width.
+
+  wc --files0-from=FILE no longer reads all of FILE into RAM, before
+  processing the first file name, unless the list of names is known
+  to be small enough.
+
+** Changes in behavior
+
+  cp and mv: the --reply={yes,no,query} option has been removed.
+  Using it has elicited a warning for the last three years.
+
+  dd: user specified offsets that are too big are handled better.
+  Previously, erroneous parameters to skip and seek could result
+  in redundant reading of the file with no warnings or errors.
+
+  du: -H (initially equivalent to --si) is now equivalent to
+  --dereference-args, and thus works as POSIX requires
+
+  shred: now does 3 overwrite passes by default rather than 25.
+
+  ls -l now marks SELinux-only files with the less obtrusive '.',
+  rather than '+'.  A file with any other combination of MAC and ACL
+  is still marked with a '+'.
+
+
+* Noteworthy changes in release 7.0 (2008-10-05) [beta]
+
+** New programs
+
+  timeout: Run a command with bounded time.
+  truncate: Set the size of a file to a specified size.
+
+** New features
+
+  chgrp, chmod, chown, chcon, du, rm: now all display linear performance,
+  even when operating on million-entry directories on ext3 and ext4 file
+  systems.  Before, they would exhibit O(N^2) performance, due to linear
+  per-entry seek time cost when operating on entries in readdir order.
+  Rm was improved directly, while the others inherit the improvement
+  from the newer version of fts in gnulib.
+
+  comm now verifies that the inputs are in sorted order.  This check can
+  be turned off with the --nocheck-order option.
+
+  comm accepts new option, --output-delimiter=STR, that allows specification
+  of an output delimiter other than the default single TAB.
+
+  cp and mv: the deprecated --reply=X option is now also undocumented.
+
+  dd accepts iflag=fullblock to make it accumulate full input blocks.
+  With this new option, after a short read, dd repeatedly calls read,
+  until it fills the incomplete block, reaches EOF, or encounters an error.
+
+  df accepts a new option --total, which produces a grand total of all
+  arguments after all arguments have been processed.
+
+  If the GNU MP library is available at configure time, factor and
+  expr support arbitrarily large numbers.  Pollard's rho algorithm is
+  used to factor large numbers.
+
+  install accepts a new option --strip-program to specify the program used to
+  strip binaries.
+
+  ls now colorizes files with capabilities if libcap is available
+
+  ls -v now uses filevercmp function as sort predicate (instead of strverscmp)
+
+  md5sum now accepts the new option, --quiet, to suppress the printing of
+  'OK' messages.  sha1sum, sha224sum, sha384sum, and sha512sum accept it, too.
+
+  sort accepts a new option, --files0-from=F, that specifies a file
+  containing a null-separated list of files to sort.  This list is used
+  instead of filenames passed on the command-line to avoid problems with
+  maximum command-line (argv) length.
+
+  sort accepts a new option --batch-size=NMERGE, where NMERGE
+  represents the maximum number of inputs that will be merged at once.
+  When processing more than NMERGE inputs, sort uses temporary files.
+
+  sort accepts a new option --version-sort (-V, --sort=version),
+  specifying that ordering is to be based on filevercmp.
+
+** Bug fixes
+
+  chcon --verbose now prints a newline after each message
+
+  od no longer suffers from platform bugs in printf(3).  This is
+  probably most noticeable when using 'od -tfL' to print long doubles.
+
+  seq -0.1 0.1 2 now prints 2,0 when locale's decimal point is ",".
+  Before, it would mistakenly omit the final number in that example.
+
+  shuf honors the --zero-terminated (-z) option, even with --input-range=LO-HI
+
+  shuf --head-count is now correctly documented.  The documentation
+  previously claimed it was called --head-lines.
+
+** Improvements
+
+  Improved support for access control lists (ACLs): On MacOS X, Solaris 7..10,
+  HP-UX 11, Tru64, AIX, IRIX 6.5, and Cygwin, "ls -l" now displays the presence
+  of an ACL on a file via a '+' sign after the mode, and "cp -p" copies ACLs.
+
+  join has significantly better performance due to better memory management
+
+  ls now uses constant memory when not sorting and using one_per_line format,
+  no matter how many files are in a given directory.  I.e., to list a directory
+  with very many files, ls -1U is much more efficient.
+
+  od now aligns fields across lines when printing multiple -t
+  specifiers, and no longer prints fields that resulted entirely from
+  padding the input out to the least common multiple width.
+
+** Changes in behavior
+
+  stat's --context (-Z) option has always been a no-op.
+  Now it evokes a warning that it is obsolete and will be removed.
+
+
+* Noteworthy changes in release 6.12 (2008-05-31) [stable]
+
+** New features
+
+  cp, install, mv, and touch now preserve nanosecond resolution on
+  file timestamps, on platforms that have the 'utimensat' and
+  'futimens' system calls.
+
+** Bug fixes
+
+  chcon, runcon: --help output now includes the bug-reporting address
+
+  cp -p copies permissions more portably.  For example, on MacOS X 10.5,
+  "cp -p some-fifo some-file" no longer fails while trying to copy the
+  permissions from the some-fifo argument.
+
+  id with no options now prints the SELinux context only when invoked
+  with no USERNAME argument.
+
+  id and groups once again print the AFS-specific nameless group-ID (PAG).
+  Printing of such large-numbered, kernel-only (not in /etc/group) group-IDs
+  was suppressed in 6.11 due to ignorance that they are useful.
+
+  uniq: avoid subtle field-skipping malfunction due to isblank misuse.
+  In some locales on some systems, isblank(240) (aka &nbsp) is nonzero.
+  On such systems, uniq --skip-fields=N would fail to skip the proper
+  number of fields for some inputs.
+
+  tac: avoid segfault with --regex (-r) and multiple files, e.g.,
+  "echo > x; tac -r x x".  [bug present at least in textutils-1.8b, from 1992]
+
+** Changes in behavior
+
+  install once again sets SELinux context, when possible
+  [it was deliberately disabled in 6.9.90]
+
+
+* Noteworthy changes in release 6.11 (2008-04-19) [stable]
+
+** Bug fixes
+
+  configure --enable-no-install-program=groups now works.
+
+  "cp -fR fifo E" now succeeds with an existing E.  Before this fix, using
+  -fR to copy a fifo or "special" file onto an existing file would fail
+  with EEXIST.  Now, it once again unlinks the destination before trying
+  to create the destination file.  [bug introduced in coreutils-5.90]
+
+  dd once again works with unnecessary options like if=/dev/stdin and
+  of=/dev/stdout.  [bug introduced in fileutils-4.0h]
+
+  id now uses getgrouplist, when possible.  This results in
+  much better performance when there are many users and/or groups.
+
+  ls no longer segfaults on files in /proc when linked with an older version
+  of libselinux.  E.g., ls -l /proc/sys would dereference a NULL pointer.
+
+  md5sum would segfault for invalid BSD-style input, e.g.,
+  echo 'MD5 (' | md5sum -c -  Now, md5sum ignores that line.
+  sha1sum, sha224sum, sha384sum, and sha512sum are affected, too.
+  [bug introduced in coreutils-5.1.0]
+
+  md5sum -c would accept a NUL-containing checksum string like "abcd\0..."
+  and would unnecessarily read and compute the checksum of the named file,
+  and then compare that checksum to the invalid one: guaranteed to fail.
+  Now, it recognizes that the line is not valid and skips it.
+  sha1sum, sha224sum, sha384sum, and sha512sum are affected, too.
+  [bug present in the original version, in coreutils-4.5.1, 1995]
+
+  "mkdir -Z x dir" no longer segfaults when diagnosing invalid context "x"
+  mkfifo and mknod would fail similarly.  Now they're fixed.
+
+  mv would mistakenly unlink a destination file before calling rename,
+  when the destination had two or more hard links.  It no longer does that.
+  [bug introduced in coreutils-5.3.0]
+
+  "paste -d'\' file" no longer overruns memory (heap since coreutils-5.1.2,
+  stack before then) [bug present in the original version, in 1992]
+
+  "pr -e" with a mix of backspaces and TABs no longer corrupts the heap
+  [bug present in the original version, in 1992]
+
+  "ptx -F'\' long-file-name" would overrun a malloc'd buffer and corrupt
+  the heap.  That was triggered by a lone backslash (or odd number of them)
+  at the end of the option argument to --flag-truncation=STRING (-F),
+  --word-regexp=REGEXP (-W), or --sentence-regexp=REGEXP (-S).
+
+  "rm -r DIR" would mistakenly declare to be "write protected" -- and
+  prompt about -- full DIR-relative names longer than MIN (PATH_MAX, 8192).
+
+  "rmdir --ignore-fail-on-non-empty" detects and ignores the failure
+  in more cases when a directory is empty.
+
+  "seq -f % 1" would issue the erroneous diagnostic "seq: memory exhausted"
+  rather than reporting the invalid string format.
+  [bug introduced in coreutils-6.0]
+
+** New features
+
+  join now verifies that the inputs are in sorted order.  This check can
+  be turned off with the --nocheck-order option.
+
+  sort accepts the new option --sort=WORD, where WORD can be one of
+  general-numeric, month, numeric or random.  These are equivalent to the
+  options --general-numeric-sort/-g, --month-sort/-M, --numeric-sort/-n
+  and --random-sort/-R, resp.
+
+** Improvements
+
+  id and groups work around an AFS-related bug whereby those programs
+  would print an invalid group number, when given no user-name argument.
+
+  ls --color no longer outputs unnecessary escape sequences
+
+  seq gives better diagnostics for invalid formats.
+
+** Portability
+
+  rm now works properly even on systems like BeOS and Haiku,
+  which have negative errno values.
+
+** Consistency
+
+  install, mkdir, rmdir and split now write --verbose output to stdout,
+  not to stderr.
+
+
+* Noteworthy changes in release 6.10 (2008-01-22) [stable]
+
+** Bug fixes
+
+  Fix a non-portable use of sed in configure.ac.
+  [bug introduced in coreutils-6.9.92]
+
+
+* Noteworthy changes in release 6.9.92 (2008-01-12) [beta]
+
+** Bug fixes
+
+  cp --parents no longer uses uninitialized memory when restoring the
+  permissions of a just-created destination directory.
+  [bug introduced in coreutils-6.9.90]
+
+  tr's case conversion would fail in a locale with differing numbers
+  of lower case and upper case characters.  E.g., this would fail:
+  env LC_CTYPE=en_US.ISO-8859-1 tr '[:upper:]' '[:lower:]'
+  [bug introduced in coreutils-6.9.90]
+
+** Improvements
+
+  "touch -d now writable-but-owned-by-someone-else" now succeeds
+  whenever that same command would succeed without "-d now".
+  Before, it would work fine with no -d option, yet it would
+  fail with the ostensibly-equivalent "-d now".
+
+
+* Noteworthy changes in release 6.9.91 (2007-12-15) [beta]
+
+** Bug fixes
+
+  "ls -l" would not output "+" on SELinux hosts unless -Z was also given.
+
+  "rm" would fail to unlink a non-directory when run in an environment
+  in which the user running rm is capable of unlinking a directory.
+  [bug introduced in coreutils-6.9]
+
+
+* Noteworthy changes in release 6.9.90 (2007-12-01) [beta]
+
+** New programs
+
+  arch: equivalent to uname -m, not installed by default
+  But don't install this program on Solaris systems.
+
+  chcon: change the SELinux security context of a file
+
+  mktemp: create a temporary file or directory (or names)
+
+  runcon: run a program in a different SELinux security context
+
+** Programs no longer installed by default
+
+  hostname, su
+
+** Changes in behavior
+
+  cp, by default, refuses to copy through a dangling destination symlink
+  Set POSIXLY_CORRECT if you require the old, risk-prone behavior.
+
+  pr -F no longer suppresses the footer or the first two blank lines in
+  the header.  This is for compatibility with BSD and POSIX.
+
+  tr now warns about an unescaped backslash at end of string.
+  The tr from coreutils-5.2.1 and earlier would fail for such usage,
+  and Solaris' tr ignores that final byte.
+
+** New features
+
+  Add SELinux support, based on the patch from Fedora:
+  * cp accepts new --preserve=context option.
+  * "cp -a" works with SELinux:
+  Now, cp -a attempts to preserve context, but failure to do so does
+  not change cp's exit status.  However "cp --preserve=context" is
+  similar, but failure *does* cause cp to exit with nonzero status.
+  * install accepts new "-Z, --context=C" option.
+  * id accepts new "-Z" option.
+  * stat honors the new %C format directive: SELinux security context string
+  * ls accepts a slightly modified -Z option.
+  * ls: contrary to Fedora version, does not accept --lcontext and --scontext
+
+  The following commands and options now support the standard size
+  suffixes kB, M, MB, G, GB, and so on for T, P, Y, Z, and Y:
+  head -c, head -n, od -j, od -N, od -S, split -b, split -C,
+  tail -c, tail -n.
+
+  cp -p tries to preserve the GID of a file even if preserving the UID
+  is not possible.
+
+  uniq accepts a new option: --zero-terminated (-z).  As with the sort
+  option of the same name, this makes uniq consume and produce
+  NUL-terminated lines rather than newline-terminated lines.
+
+  wc no longer warns about character decoding errors in multibyte locales.
+  This means for example that "wc /bin/sh" now produces normal output
+  (though the word count will have no real meaning) rather than many
+  error messages.
+
+** New build options
+
+  By default, "make install" no longer attempts to install (or even build) su.
+  To change that, use ./configure --enable-install-program=su.
+  If you also want to install the new "arch" program, do this:
+  ./configure --enable-install-program=arch,su.
+
+  You can inhibit the compilation and installation of selected programs
+  at configure time.  For example, to avoid installing "hostname" and
+  "uptime", use ./configure --enable-no-install-program=hostname,uptime
+  Note: currently, "make check" passes, even when arch and su are not
+  built (that's the new default).  However, if you inhibit the building
+  and installation of other programs, don't be surprised if some parts
+  of "make check" fail.
+
+** Remove deprecated options
+
+  df no longer accepts the --kilobytes option.
+  du no longer accepts the --kilobytes or --megabytes options.
+  ls no longer accepts the --kilobytes option.
+  ptx longer accepts the --copyright option.
+  who no longer accepts -i or --idle.
+
+** Improved robustness
+
+  ln -f can no longer silently clobber a just-created hard link.
+  In some cases, ln could be seen as being responsible for data loss.
+  For example, given directories a, b, c, and files a/f and b/f, we
+  should be able to do this safely: ln -f a/f b/f c && rm -f a/f b/f
+  However, before this change, ln would succeed, and thus cause the
+  loss of the contents of a/f.
+
+  stty no longer silently accepts certain invalid hex values
+  in its 35-colon command-line argument
+
+** Bug fixes
+
+  chmod no longer ignores a dangling symlink.  Now, chmod fails
+  with a diagnostic saying that it cannot operate on such a file.
+  [bug introduced in coreutils-5.1.0]
+
+  cp attempts to read a regular file, even if stat says it is empty.
+  Before, "cp /proc/cpuinfo c" would create an empty file when the kernel
+  reports stat.st_size == 0, while "cat /proc/cpuinfo > c" would "work",
+  and create a nonempty one. [bug introduced in coreutils-6.0]
+
+  cp --parents no longer mishandles symlinks to directories in file
+  name components in the source, e.g., "cp --parents symlink/a/b d"
+  no longer fails.  Also, 'cp' no longer considers a destination
+  symlink to be the same as the referenced file when copying links
+  or making backups.  For example, if SYM is a symlink to FILE,
+  "cp -l FILE SYM" now reports an error instead of silently doing
+  nothing.  The behavior of 'cp' is now better documented when the
+  destination is a symlink.
+
+  "cp -i --update older newer" no longer prompts; same for mv
+
+  "cp -i" now detects read errors on standard input, and no longer consumes
+  too much seekable input; same for ln, install, mv, and rm.
+
+  cut now diagnoses a range starting with zero (e.g., -f 0-2) as invalid;
+  before, it would treat it as if it started with 1 (-f 1-2).
+
+  "cut -f 2-0" now fails; before, it was equivalent to "cut -f 2-"
+
+  cut now diagnoses the '-' in "cut -f -" as an invalid range, rather
+  than interpreting it as the unlimited range, "1-".
+
+  date -d now accepts strings of the form e.g., 'YYYYMMDD +N days',
+  in addition to the usual 'YYYYMMDD N days'.
+
+  du -s now includes the size of any stat'able-but-inaccessible directory
+  in the total size.
+
+  du (without -s) prints whatever it knows of the size of an inaccessible
+  directory.  Before, du would print nothing for such a directory.
+
+  ls -x DIR would sometimes output the wrong string in place of the
+  first entry.  [introduced in coreutils-6.8]
+
+  ls --color would mistakenly color a dangling symlink as if it were
+  a regular symlink.  This would happen only when the dangling symlink
+  was not a command-line argument and in a directory with d_type support.
+  [introduced in coreutils-6.0]
+
+  ls --color, (with a custom LS_COLORS envvar value including the
+  ln=target attribute) would mistakenly output the string "target"
+  before the name of each symlink.  [introduced in coreutils-6.0]
+
+  od's --skip (-j) option now works even when the kernel says that a
+  nonempty regular file has stat.st_size = 0.  This happens at least
+  with files in /proc and linux-2.6.22.
+
+  "od -j L FILE" had a bug: when the number of bytes to skip, L, is exactly
+  the same as the length of FILE, od would skip *no* bytes.  When the number
+  of bytes to skip is exactly the sum of the lengths of the first N files,
+  od would skip only the first N-1 files. [introduced in textutils-2.0.9]
+
+  ./printf %.10000000f 1 could get an internal ENOMEM error and generate
+  no output, yet erroneously exit with status 0.  Now it diagnoses the error
+  and exits with nonzero status.  [present in initial implementation]
+
+  seq no longer mishandles obvious cases like "seq 0 0.000001 0.000003",
+  so workarounds like "seq 0 0.000001 0.0000031" are no longer needed.
+
+  seq would mistakenly reject some valid format strings containing %%,
+  and would mistakenly accept some invalid ones. e.g., %g%% and %%g, resp.
+
+  "seq .1 .1" would mistakenly generate no output on some systems
+
+  Obsolete sort usage with an invalid ordering-option character, e.g.,
+  "env _POSIX2_VERSION=199209 sort +1x" no longer makes sort free an
+  invalid pointer [introduced in coreutils-6.5]
+
+  sorting very long lines (relative to the amount of available memory)
+  no longer provokes unaligned memory access
+
+  split --line-bytes=N (-C N) no longer creates an empty file
+  [this bug is present at least as far back as textutils-1.22 (Jan, 1997)]
+
+  tr -c no longer aborts when translating with Set2 larger than the
+  complement of Set1.  [present in the original version, in 1992]
+
+  tr no longer rejects an unmatched [:lower:] or [:upper:] in SET1.
+  [present in the original version]
+
+
+* Noteworthy changes in release 6.9 (2007-03-22) [stable]
+
+** Bug fixes
+
+  cp -x (--one-file-system) would fail to set mount point permissions
+
+  The default block size and output format for df -P are now unaffected by
+  the DF_BLOCK_SIZE, BLOCK_SIZE, and BLOCKSIZE environment variables.  It
+  is still affected by POSIXLY_CORRECT, though.
+
+  Using pr -m -s (i.e., merging files, with TAB as the output separator)
+  no longer inserts extraneous spaces between output columns.
+
+* Noteworthy changes in release 6.8 (2007-02-24) [not-unstable]
+
+** Bug fixes
+
+  chgrp, chmod, and chown now honor the --preserve-root option.
+  Before, they would warn, yet continuing traversing and operating on /.
+
+  chmod no longer fails in an environment (e.g., a chroot) with openat
+  support but with insufficient /proc support.
+
+  "cp --parents F/G D" no longer creates a directory D/F when F is not
+  a directory (and F/G is therefore invalid).
+
+  "cp --preserve=mode" would create directories that briefly had
+  too-generous permissions in some cases.  For example, when copying a
+  directory with permissions 777 the destination directory might
+  temporarily be setgid on some file systems, which would allow other
+  users to create subfiles with the same group as the directory.  Fix
+  similar problems with 'install' and 'mv'.
+
+  cut no longer dumps core for usage like "cut -f2- f1 f2" with two or
+  more file arguments.  This was due to a double-free bug, introduced
+  in coreutils-5.3.0.
+
+  dd bs= operands now silently override any later ibs= and obs=
+  operands, as POSIX and tradition require.
+
+  "ls -FRL" always follows symbolic links on Linux.  Introduced in
+  coreutils-6.0.
+
+  A cross-partition "mv /etc/passwd ~" (by non-root) now prints
+  a reasonable diagnostic.  Before, it would print this:
+  "mv: cannot remove `/etc/passwd': Not a directory".
+
+  pwd and "readlink -e ." no longer fail unnecessarily when a parent
+  directory is unreadable.
+
+  rm (without -f) could prompt when it shouldn't, or fail to prompt
+  when it should, when operating on a full name longer than 511 bytes
+  and getting an ENOMEM error while trying to form the long name.
+
+  rm could mistakenly traverse into the wrong directory under unusual
+  conditions: when a full name longer than 511 bytes specifies a search-only
+  directory, and when forming that name fails with ENOMEM, rm would attempt
+  to open a truncated-to-511-byte name with the first five bytes replaced
+  with "[...]".  If such a directory were to actually exist, rm would attempt
+  to remove it.
+
+  "rm -rf /etc/passwd" (run by non-root) now prints a diagnostic.
+  Before it would print nothing.
+
+  "rm --interactive=never F" no longer prompts for an unwritable F
+
+  "rm -rf D" would emit a misleading diagnostic when failing to
+  remove a symbolic link within the unwritable directory, D.
+  Introduced in coreutils-6.0.  Similarly, when a cross-partition
+  "mv" fails because the source directory is unwritable, it now gives
+  a reasonable diagnostic.  Before, this would print
+    $ mkdir /tmp/x; touch /tmp/x/y; chmod -w /tmp/x;
+    $ test $(stat -c %d /tmp/x) -ne $(stat -c %d .) && mv /tmp/x/y .
+    mv: cannot remove `/tmp/x/y': Not a directory
+  Now it prints this:
+    mv: cannot remove `/tmp/x/y': Permission denied.
+
+** New features
+
+  sort's new --compress-program=PROG option specifies a compression
+  program to use when writing and reading temporary files.
+  This can help save both time and disk space when sorting large inputs.
+
+  sort accepts the new option -C, which acts like -c except no diagnostic
+  is printed.  Its --check option now accepts an optional argument, and
+  --check=quiet and --check=silent are now aliases for -C, while
+  --check=diagnose-first is an alias for -c or plain --check.
+
+
+* Noteworthy changes in release 6.7 (2006-12-08) [stable]
+
+** Bug fixes
+
+  When cp -p copied a file with special mode bits set, the same bits
+  were set on the copy even when ownership could not be preserved.
+  This could result in files that were setuid to the wrong user.
+  To fix this, special mode bits are now set in the copy only if its
+  ownership is successfully preserved.  Similar problems were fixed
+  with mv when copying across file system boundaries.  This problem
+  affects all versions of coreutils through 6.6.
+
+  cp --preserve=ownership would create output files that temporarily
+  had too-generous permissions in some cases.  For example, when
+  copying a file with group A and mode 644 into a group-B sticky
+  directory, the output file was briefly readable by group B.
+  Fix similar problems with cp options like -p that imply
+  --preserve=ownership, with install -d when combined with either -o
+  or -g, and with mv when copying across file system boundaries.
+  This bug affects all versions of coreutils through 6.6.
+
+  du --one-file-system (-x) would skip subdirectories of any directory
+  listed as second or subsequent command line argument.  This bug affects
+  coreutils-6.4, 6.5 and 6.6.
+
+
+* Noteworthy changes in release 6.6 (2006-11-22) [stable]
+
+** Bug fixes
+
+  ls would segfault (dereference a NULL pointer) for a file with a
+  nameless group or owner.  This bug was introduced in coreutils-6.5.
+
+  A bug in the latest official m4/gettext.m4 (from gettext-0.15)
+  made configure fail to detect gettext support, due to the unusual
+  way in which coreutils uses AM_GNU_GETTEXT.
+
+** Improved robustness
+
+  Now, du (and the other fts clients: chmod, chgrp, chown) honor a
+  trailing slash in the name of a symlink-to-directory even on
+  Solaris 9, by working around its buggy fstatat implementation.
+
+
+* Major changes in release 6.5 (2006-11-19) [stable]
+
+** Bug fixes
+
+  du (and the other fts clients: chmod, chgrp, chown) would exit early
+  when encountering an inaccessible directory on a system with native
+  openat support (i.e., linux-2.6.16 or newer along with glibc-2.4
+  or newer).  This bug was introduced with the switch to gnulib's
+  openat-based variant of fts, for coreutils-6.0.
+
+  "ln --backup f f" now produces a sensible diagnostic
+
+** New features
+
+  rm accepts a new option: --one-file-system
+
+
+* Major changes in release 6.4 (2006-10-22) [stable]
+
+** Bug fixes
+
+  chgrp and chown would malfunction when invoked with both -R and -H and
+  with one or more of the following: --preserve-root, --verbose, --changes,
+  --from=o:g (chown only).  This bug was introduced with the switch to
+  gnulib's openat-based variant of fts, for coreutils-6.0.
+
+  cp --backup dir1 dir2, would rename an existing dir2/dir1 to dir2/dir1~.
+  This bug was introduced in coreutils-6.0.
+
+  With --force (-f), rm no longer fails for ENOTDIR.
+  For example, "rm -f existing-non-directory/anything" now exits
+  successfully, ignoring the error about a nonexistent file.
+
+
+* Major changes in release 6.3 (2006-09-30) [stable]
+
+** Improved robustness
+
+  pinky no longer segfaults on Darwin 7.9.0 (MacOS X 10.3.9) due to a
+  buggy native getaddrinfo function.
+
+  rm works around a bug in Darwin 7.9.0 (MacOS X 10.3.9) that would
+  sometimes keep it from removing all entries in a directory on an HFS+
+  or NFS-mounted partition.
+
+  sort would fail to handle very large input (around 40GB) on systems with a
+  mkstemp function that returns a file descriptor limited to 32-bit offsets.
+
+** Bug fixes
+
+  chmod would fail unnecessarily in an unusual case: when an initially-
+  inaccessible argument is rendered accessible by chmod's action on a
+  preceding command line argument.  This bug also affects chgrp, but
+  it is harder to demonstrate.  It does not affect chown.  The bug was
+  introduced with the switch from explicit recursion to the use of fts
+  in coreutils-5.1.0 (2003-10-15).
+
+  cp -i and mv -i occasionally neglected to prompt when the copy or move
+  action was bound to fail.  This bug dates back to before fileutils-4.0.
+
+  With --verbose (-v), cp and mv would sometimes generate no output,
+  or neglect to report file removal.
+
+  For the "groups" command:
+
+    "groups" no longer prefixes the output with "user :" unless more
+    than one user is specified; this is for compatibility with BSD.
+
+    "groups user" now exits nonzero when it gets a write error.
+
+    "groups" now processes options like --help more compatibly.
+
+  shuf would infloop, given 8KB or more of piped input
+
+** Portability
+
+  Versions of chmod, chown, chgrp, du, and rm (tools that use openat etc.)
+  compiled for Solaris 8 now also work when run on Solaris 10.
+
+
+* Major changes in release 6.2 (2006-09-18) [stable candidate]
+
+** Changes in behavior
+
+  mkdir -p and install -d (or -D) now use a method that forks a child
+  process if the working directory is unreadable and a later argument
+  uses a relative file name.  This avoids some race conditions, but it
+  means you may need to kill two processes to stop these programs.
+
+  rm now rejects attempts to remove the root directory, e.g., 'rm -fr /'
+  now fails without removing anything.  Likewise for any file name with
+  a final './' or '../' component.
+
+  tail now ignores the -f option if POSIXLY_CORRECT is set, no file
+  operand is given, and standard input is any FIFO; formerly it did
+  this only for pipes.
+
+** Infrastructure changes
+
+  Coreutils now uses gnulib via the gnulib-tool script.
+  If you check the source out from CVS, then follow the instructions
+  in README-cvs.  Although this represents a large change to the
+  infrastructure, it should cause no change in how the tools work.
+
+** Bug fixes
+
+  cp --backup no longer fails when the last component of a source file
+  name is "." or "..".
+
+  "ls --color" would highlight other-writable and sticky directories
+  no differently than regular directories on a file system with
+  dirent.d_type support.
+
+  "mv -T --verbose --backup=t A B" now prints the " (backup: B.~1~)"
+  suffix when A and B are directories as well as when they are not.
+
+  mv and "cp -r" no longer fail when invoked with two arguments
+  where the first one names a directory and the second name ends in
+  a slash and doesn't exist.  E.g., "mv dir B/", for nonexistent B,
+  now succeeds, once more.  This bug was introduced in coreutils-5.3.0.
+
+
+* Major changes in release 6.1 (2006-08-19) [unstable]
+
+** Changes in behavior
+
+  df now considers BSD "kernfs" file systems to be dummies
+
+** New features
+
+  printf now supports the 'I' flag on hosts whose underlying printf
+  implementations support 'I', e.g., "printf %Id 2".
+
+** Bug fixes
+
+  cp --sparse preserves sparseness at the end of a file, even when
+  the file's apparent size is not a multiple of its block size.
+  [introduced with the original design, in fileutils-4.0r, 2000-04-29]
+
+  df (with a command line argument) once again prints its header
+  [introduced in coreutils-6.0]
+
+  ls -CF would misalign columns in some cases involving non-stat'able files
+  [introduced in coreutils-6.0]
+
+* Major changes in release 6.0 (2006-08-15) [unstable]
+
+** Improved robustness
+
+  df: if the file system claims to have more available than total blocks,
+  report the number of used blocks as being "total - available"
+  (a negative number) rather than as garbage.
+
+  dircolors: a new autoconf run-test for AIX's buggy strndup function
+  prevents malfunction on that system;  may also affect cut, expand,
+  and unexpand.
+
+  fts no longer changes the current working directory, so its clients
+  (chmod, chown, chgrp, du) no longer malfunction under extreme conditions.
+
+  pwd and other programs using lib/getcwd.c work even on file systems
+  where dirent.d_ino values are inconsistent with those from stat.st_ino.
+
+  rm's core is now reentrant: rm --recursive (-r) now processes
+  hierarchies without changing the working directory at all.
+
+** Changes in behavior
+
+  basename and dirname now treat // as different from / on platforms
+  where the two are distinct.
+
+  chmod, install, and mkdir now preserve a directory's set-user-ID and
+  set-group-ID bits unless you explicitly request otherwise.  E.g.,
+  'chmod 755 DIR' and 'chmod u=rwx,go=rx DIR' now preserve DIR's
+  set-user-ID and set-group-ID bits instead of clearing them, and
+  similarly for 'mkdir -m 755 DIR' and 'mkdir -m u=rwx,go=rx DIR'.  To
+  clear the bits, mention them explicitly in a symbolic mode, e.g.,
+  'mkdir -m u=rwx,go=rx,-s DIR'.  To set them, mention them explicitly
+  in either a symbolic or a numeric mode, e.g., 'mkdir -m 2755 DIR',
+  'mkdir -m u=rwx,go=rx,g+s' DIR.  This change is for convenience on
+  systems where these bits inherit from parents.  Unfortunately other
+  operating systems are not consistent here, and portable scripts
+  cannot assume the bits are set, cleared, or preserved, even when the
+  bits are explicitly mentioned.  For example, OpenBSD 3.9 'mkdir -m
+  777 D' preserves D's setgid bit but 'chmod 777 D' clears it.
+  Conversely, Solaris 10 'mkdir -m 777 D', 'mkdir -m g-s D', and
+  'chmod 0777 D' all preserve D's setgid bit, and you must use
+  something like 'chmod g-s D' to clear it.
+
+  'cp --link --no-dereference' now works also on systems where the
+  link system call cannot create a hard link to a symbolic link.
+  This change has no effect on systems with a Linux-based kernel.
+
+  csplit and nl now use POSIX syntax for regular expressions, not
+  Emacs syntax.  As a result, character classes like [[:print:]] and
+  interval expressions like A\{1,9\} now have their usual meaning,
+  . no longer matches the null character, and \ must precede the + and
+  ? operators.
+
+  date: a command like date -d '2006-04-23 21 days ago' would print
+  the wrong date in some time zones.  (see the test for an example)
+
+  df changes:
+
+    df now considers "none" and "proc" file systems to be dummies and
+    therefore does not normally display them.  Also, inaccessible file
+    systems (which can be caused by shadowed mount points or by
+    chrooted bind mounts) are now dummies, too.
+
+    df now fails if it generates no output, so you can inspect the
+    exit status of a command like "df -t ext3 -t reiserfs DIR" to test
+    whether DIR is on a file system of type "ext3" or "reiserfs".
+
+  expr no longer complains about leading ^ in a regular expression
+  (the anchor is ignored), or about regular expressions like A** (the
+  second "*" is ignored).  expr now exits with status 2 (not 3) for
+  errors it detects in the expression's values; exit status 3 is now
+  used only for internal errors (such as integer overflow, which expr
+  now checks for).
+
+  install and mkdir now implement the X permission symbol correctly,
+  e.g., 'mkdir -m a+X dir'; previously the X was ignored.
+
+  install now creates parent directories with mode u=rwx,go=rx (755)
+  instead of using the mode specified by the -m option; and it does
+  not change the owner or group of parent directories.  This is for
+  compatibility with BSD and closes some race conditions.
+
+  ln now uses different (and we hope clearer) diagnostics when it fails.
+  ln -v now acts more like FreeBSD, so it generates output only when
+  successful and the output is easier to parse.
+
+  ls now defaults to --time-style='locale', not --time-style='posix-long-iso'.
+  However, the 'locale' time style now behaves like 'posix-long-iso'
+  if your locale settings appear to be messed up.  This change
+  attempts to have the default be the best of both worlds.
+
+  mkfifo and mknod no longer set special mode bits (setuid, setgid,
+  and sticky) with the -m option.
+
+  nohup's usual diagnostic now more precisely specifies the I/O
+  redirections, e.g., "ignoring input and appending output to
+  nohup.out".  Also, nohup now redirects stderr to nohup.out (or
+  $HOME/nohup.out) if stdout is closed and stderr is a tty; this is in
+  response to Open Group XCU ERN 71.
+
+  rm --interactive now takes an optional argument, although the
+  default of using no argument still acts like -i.
+
+  rm no longer fails to remove an empty, unreadable directory
+
+  seq changes:
+
+    seq defaults to a minimal fixed point format that does not lose
+    information if seq's operands are all fixed point decimal numbers.
+    You no longer need the '-f%.f' in 'seq -f%.f 1048575 1024 1050623',
+    for example, since the default format now has the same effect.
+
+    seq now lets you use %a, %A, %E, %F, and %G formats.
+
+    seq now uses long double internally rather than double.
+
+  sort now reports incompatible options (e.g., -i and -n) rather than
+  silently ignoring one of them.
+
+  stat's --format=FMT option now works the way it did before 5.3.0:
+  FMT is automatically newline terminated.  The first stable release
+  containing this change was 5.92.
+
+  stat accepts the new option --printf=FMT, where FMT is *not*
+  automatically newline terminated.
+
+  stat: backslash escapes are interpreted in a format string specified
+  via --printf=FMT, but not one specified via --format=FMT.  That includes
+  octal (\ooo, at most three octal digits), hexadecimal (\xhh, one or
+  two hex digits), and the standard sequences (\a, \b, \f, \n, \r, \t,
+  \v, \", \\).
+
+  With no operand, 'tail -f' now silently ignores the '-f' only if
+  standard input is a FIFO or pipe and POSIXLY_CORRECT is set.
+  Formerly, it ignored the '-f' when standard input was a FIFO, pipe,
+  or socket.
+
+** Scheduled for removal
+
+  ptx's --copyright (-C) option is scheduled for removal in 2007, and
+  now evokes a warning.  Use --version instead.
+
+  rm's --directory (-d) option is scheduled for removal in 2006.  This
+  option has been silently ignored since coreutils 5.0.  On systems
+  that support unlinking of directories, you can use the "unlink"
+  command to unlink a directory.
+
+  Similarly, we are considering the removal of ln's --directory (-d,
+  -F) option in 2006.  Please write to <bug-coreutils@gnu.org> if this
+  would cause a problem for you.  On systems that support hard links
+  to directories, you can use the "link" command to create one.
+
+** New programs
+
+  base64: base64 encoding and decoding (RFC 3548) functionality.
+  sha224sum: print or check a SHA224 (224-bit) checksum
+  sha256sum: print or check a SHA256 (256-bit) checksum
+  sha384sum: print or check a SHA384 (384-bit) checksum
+  sha512sum: print or check a SHA512 (512-bit) checksum
+  shuf: Shuffle lines of text.
+
+** New features
+
+  chgrp now supports --preserve-root, --no-preserve-root (default),
+  as it was documented to do, and just as chmod, chown, and rm do.
+
+  New dd iflag= and oflag= flags:
+
+    'directory' causes dd to fail unless the file is a directory, on
+    hosts that support this (e.g., Linux kernels, version 2.1.126 and
+    later).  This has limited utility but is present for completeness.
+
+    'noatime' causes dd to read a file without updating its access
+    time, on hosts that support this (e.g., Linux kernels, version
+    2.6.8 and later).
+
+    'nolinks' causes dd to fail if the file has multiple hard links,
+    on hosts that support this (e.g., Solaris 10 and later).
+
+  ls accepts the new option --group-directories-first, to make it
+  list directories before files.
+
+  rm now accepts the -I (--interactive=once) option.  This new option
+  prompts once if rm is invoked recursively or if more than three
+  files are being deleted, which is less intrusive than -i prompting
+  for every file, but provides almost the same level of protection
+  against mistakes.
+
+  shred and sort now accept the --random-source option.
+
+  sort now accepts the --random-sort (-R) option and 'R' ordering option.
+
+  sort now supports obsolete usages like "sort +1 -2" unless
+  POSIXLY_CORRECT is set.  However, when conforming to POSIX
+  1003.1-2001 "sort +1" still sorts the file named "+1".
+
+  wc accepts a new option --files0-from=FILE, where FILE contains a
+  list of NUL-terminated file names.
+
+** Bug fixes
+
+  cat with any of the options, -A -v -e -E -T, when applied to a
+  file in /proc or /sys (linux-specific), would truncate its output,
+  usually printing nothing.
+
+  cp -p would fail in a /proc-less chroot, on some systems
+
+  When 'cp -RL' encounters the same directory more than once in the
+  hierarchy beneath a single command-line argument, it no longer confuses
+  them with hard-linked directories.
+
+  fts-using tools (chmod, chown, chgrp, du) no longer fail due to
+  a double-free bug -- it could be triggered by making a directory
+  inaccessible while e.g., du is traversing the hierarchy under it.
+
+  fts-using tools (chmod, chown, chgrp, du) no longer misinterpret
+  a very long symlink chain as a dangling symlink.  Before, such a
+  misinterpretation would cause these tools not to diagnose an ELOOP error.
+
+  ls --indicator-style=file-type would sometimes stat a symlink
+  unnecessarily.
+
+  ls --file-type worked like --indicator-style=slash (-p),
+  rather than like --indicator-style=file-type.
+
+  mv: moving a symlink into the place of an existing non-directory is
+  now done atomically;  before, mv would first unlink the destination.
+
+  mv -T DIR EMPTY_DIR no longer fails unconditionally.  Also, mv can
+  now remove an empty destination directory: mkdir -p a b/a; mv a b
+
+  rm (on systems with openat) can no longer exit before processing
+  all command-line arguments.
+
+  rm is no longer susceptible to a few low-probability memory leaks.
+
+  rm -r no longer fails to remove an inaccessible and empty directory
+
+  rm -r's cycle detection code can no longer be tricked into reporting
+  a false positive (introduced in fileutils-4.1.9).
+
+  shred --remove FILE no longer segfaults on Gentoo systems
+
+  sort would fail for large inputs (~50MB) on systems with a buggy
+  mkstemp function.  sort and tac now use the replacement mkstemp
+  function, and hence are no longer subject to limitations (of 26 or 32,
+  on the maximum number of files from a given template) on HP-UX 10.20,
+  SunOS 4.1.4, Solaris 2.5.1 and OSF1/Tru64 V4.0F&V5.1.
+
+  tail -f once again works on a file with the append-only
+  attribute (affects at least Linux ext2, ext3, xfs file systems)
+
+* Major changes in release 5.97 (2006-06-24) [stable]
+* Major changes in release 5.96 (2006-05-22) [stable]
+* Major changes in release 5.95 (2006-05-12) [stable]
+* Major changes in release 5.94 (2006-02-13) [stable]
+
+[see the b5_9x branch for details]
+
+* Major changes in release 5.93 (2005-11-06) [stable]
+
+** Bug fixes
+
+  dircolors no longer segfaults upon an attempt to use the new
+  STICKY_OTHER_WRITABLE (OWT) attribute.
+
+  du no longer overflows a counter when processing a file larger than
+  2^31-1 on some 32-bit systems (at least some AIX 5.1 configurations).
+
+  md5sum once again defaults to using the ' ' non-binary marker
+  (rather than the '*' binary marker) by default on Unix-like systems.
+
+  mkdir -p and install -d no longer exit nonzero when asked to create
+  a directory like 'nonexistent/.'
+
+  rm emits a better diagnostic when (without -r) it fails to remove
+  a directory on e.g., Solaris 9/10 systems.
+
+  tac now works when stdin is a tty, even on non-Linux systems.
+
+  "tail -c 2 FILE" and "touch 0101000000" now operate as POSIX
+  1003.1-2001 requires, even when coreutils is conforming to older
+  POSIX standards, as the newly-required behavior is upward-compatible
+  with the old.
+
+  The documentation no longer mentions rm's --directory (-d) option.
+
+** Build-related bug fixes
+
+  installing .mo files would fail
+
+
+* Major changes in release 5.92 (2005-10-22) [stable]
+
+** Bug fixes
+
+  chmod now diagnoses an invalid mode string starting with an octal digit
+
+  dircolors now properly quotes single-quote characters
+
+
+* Major changes in release 5.91 (2005-10-17) [stable candidate]
+
+** Bug fixes
+
+  "mkdir -p /a/b/c" no longer fails merely because a leading prefix
+  directory (e.g., /a or /a/b) exists on a read-only file system.
+
+** Removed options
+
+  tail's --allow-missing option has been removed.  Use --retry instead.
+
+  stat's --link and -l options have been removed.
+  Use --dereference (-L) instead.
+
+** Deprecated options
+
+  Using ls, du, or df with the --kilobytes option now evokes a warning
+  that the long-named option is deprecated.  Use '-k' instead.
+
+  du's long-named --megabytes option now evokes a warning.
+  Use -m instead.
+
+
+* Major changes in release 5.90 (2005-09-29) [unstable]
+
+** Bring back support for 'head -NUM', 'tail -NUM', etc. even when
+  conforming to POSIX 1003.1-2001.  The following changes apply only
+  when conforming to POSIX 1003.1-2001; there is no effect when
+  conforming to older POSIX versions.
+
+  The following usages now behave just as when conforming to older POSIX:
+
+    date -I
+    expand -TAB1[,TAB2,...]
+    fold -WIDTH
+    head -NUM
+    join -j FIELD
+    join -j1 FIELD
+    join -j2 FIELD
+    join -o FIELD_NAME1 FIELD_NAME2...
+    nice -NUM
+    od -w
+    pr -S
+    split -NUM
+    tail -[NUM][bcl][f] [FILE]
+
+  The following usages no longer work, due to the above changes:
+
+    date -I TIMESPEC  (use 'date -ITIMESPEC' instead)
+    od -w WIDTH       (use 'od -wWIDTH' instead)
+    pr -S STRING      (use 'pr -SSTRING' instead)
+
+  A few usages still have behavior that depends on which POSIX standard is
+  being conformed to, and portable applications should beware these
+  problematic usages.  These include:
+
+    Problematic       Standard-conforming replacement, depending on
+       usage            whether you prefer the behavior of:
+                      POSIX 1003.2-1992    POSIX 1003.1-2001
+    sort +4           sort -k 5            sort ./+4
+    tail +4           tail -n +4           tail ./+4
+    tail - f          tail f               [see (*) below]
+    tail -c 4         tail -c 10 ./4       tail -c4
+    touch 12312359 f  touch -t 12312359 f  touch ./12312359 f
+    uniq +4           uniq -s 4            uniq ./+4
+
+    (*) "tail - f" does not conform to POSIX 1003.1-2001; to read
+    standard input and then "f", use the command "tail -- - f".
+
+  These changes are in response to decisions taken in the January 2005
+  Austin Group standardization meeting.  For more details, please see
+  "Utility Syntax Guidelines" in the Minutes of the January 2005
+  Meeting <https://www.opengroup.org/austin/docs/austin_239.html>.
+
+** Binary input and output are now implemented more consistently.
+  These changes affect only platforms like MS-DOS that distinguish
+  between binary and text files.
+
+  The following programs now always use text input/output:
+
+    expand unexpand
+
+  The following programs now always use binary input/output to copy data:
+
+    cp install mv shred
+
+  The following programs now always use binary input/output to copy
+  data, except for stdin and stdout when it is a terminal.
+
+    head tac tail tee tr
+    (cat behaves similarly, unless one of the options -bensAE is used.)
+
+  cat's --binary or -B option has been removed.  It existed only on
+  MS-DOS-like platforms, and didn't work as documented there.
+
+  md5sum and sha1sum now obey the -b or --binary option, even if
+  standard input is a terminal, and they no longer report files to be
+  binary if they actually read them in text mode.
+
+** Changes for better conformance to POSIX
+
+  cp, ln, mv, rm changes:
+
+    Leading white space is now significant in responses to yes-or-no questions.
+    For example, if "rm" asks "remove regular file `foo'?" and you respond
+    with " y" (i.e., space before "y"), it counts as "no".
+
+  dd changes:
+
+    On a QUIT or PIPE signal, dd now exits without printing statistics.
+
+    On hosts lacking the INFO signal, dd no longer treats the USR1
+    signal as if it were INFO when POSIXLY_CORRECT is set.
+
+    If the file F is non-seekable and contains fewer than N blocks,
+    then before copying "dd seek=N of=F" now extends F with zeroed
+    blocks until F contains N blocks.
+
+  fold changes:
+
+    When POSIXLY_CORRECT is set, "fold file -3" is now equivalent to
+    "fold file ./-3", not the obviously-erroneous "fold file ./-w3".
+
+  ls changes:
+
+    -p now marks only directories; it is equivalent to the new option
+    --indicator-style=slash.  Use --file-type or
+    --indicator-style=file-type to get -p's old behavior.
+
+  nice changes:
+
+    Documentation and diagnostics now refer to "nicenesses" (commonly
+    in the range -20...19) rather than "nice values" (commonly 0...39).
+
+  nohup changes:
+
+    nohup now ignores the umask when creating nohup.out.
+
+    nohup now closes stderr if it is a terminal and stdout is closed.
+
+    nohup now exits with status 127 (not 1) when given an invalid option.
+
+  pathchk changes:
+
+    It now rejects the empty name in the normal case.  That is,
+    "pathchk -p ''" now fails, and "pathchk ''" fails unless the
+    current host (contra POSIX) allows empty file names.
+
+    The new -P option checks whether a file name component has leading "-",
+    as suggested in interpretation "Austin-039:XCU:pathchk:pathchk -p"
+    <https://collaboration.opengroup.org/austin/interps/documents.php?action=show&gdid=6232>.
+    It also rejects the empty name even if the current host accepts it; see
+    <https://collaboration.opengroup.org/austin/interps/documents.php?action=show&gdid=6233>.
+
+    The --portability option is now equivalent to -p -P.
+
+** Bug fixes
+
+  chmod, mkdir, mkfifo, and mknod formerly mishandled rarely-used symbolic
+  permissions like =xX and =u, and did not properly diagnose some invalid
+  strings like g+gr, ug,+x, and +1.  These bugs have been fixed.
+
+  csplit could produce corrupt output, given input lines longer than 8KB
+
+  dd now computes statistics using a realtime clock (if available)
+  rather than the time-of-day clock, to avoid glitches if the
+  time-of-day is changed while dd is running.  Also, it avoids
+  using unsafe code in signal handlers; this fixes some core dumps.
+
+  expr and test now correctly compare integers of unlimited magnitude.
+
+  expr now detects integer overflow when converting strings to integers,
+  rather than silently wrapping around.
+
+  ls now refuses to generate timestamps containing more than 1000 bytes, to
+  foil potential denial-of-service attacks on hosts with very large stacks.
+
+  "mkdir -m =+x dir" no longer ignores the umask when evaluating "+x",
+  and similarly for mkfifo and mknod.
+
+  "mkdir -p /tmp/a/b dir" no longer attempts to create the '.'-relative
+  directory, dir (in /tmp/a), when, after creating /tmp/a/b, it is unable
+  to return to its initial working directory.  Similarly for "install -D
+  file /tmp/a/b/file".
+
+  "pr -D FORMAT" now accepts the same formats that "date +FORMAT" does.
+
+  stat now exits nonzero if a file operand does not exist
+
+** Improved robustness
+
+  Date no longer needs to allocate virtual memory to do its job,
+  so it can no longer fail due to an out-of-memory condition,
+  no matter how large the result.
+
+** Improved portability
+
+  hostid now prints exactly 8 hexadecimal digits, possibly with leading zeros,
+  and without any spurious leading "fff..." on 64-bit hosts.
+
+  nice now works on Darwin 7.7.0 in spite of its invalid definition of NZERO.
+
+  'rm -r' can remove all entries in a directory even when it is on a
+  file system for which readdir is buggy and that was not checked by
+  coreutils' old configure-time run-test.
+
+  sleep no longer fails when resumed after being suspended on linux-2.6.8.1,
+  in spite of that kernel's buggy nanosleep implementation.
+
+** New features
+
+  chmod -w now complains if its behavior differs from what chmod a-w
+  would do, and similarly for chmod -r, chmod -x, etc.
+
+  cp and mv: the --reply=X option is deprecated
+
+  date accepts the new option --rfc-3339=TIMESPEC.  The old --iso-8601 (-I)
+  option is deprecated; it still works, but new applications should avoid it.
+  date, du, ls, and pr's time formats now support new %:z, %::z, %:::z
+  specifiers for numeric time zone offsets like -07:00, -07:00:00, and -07.
+
+  dd has new iflag= and oflag= flags "binary" and "text", which have an
+  effect only on nonstandard platforms that distinguish text from binary I/O.
+
+  dircolors now supports SETUID, SETGID, STICKY_OTHER_WRITABLE,
+  OTHER_WRITABLE, and STICKY, with ls providing default colors for these
+  categories if not specified by dircolors.
+
+  du accepts new options: --time[=TYPE] and --time-style=STYLE
+
+  join now supports a NUL field separator, e.g., "join -t '\0'".
+  join now detects and reports incompatible options, e.g., "join -t x -t y",
+
+  ls no longer outputs an extra space between the mode and the link count
+  when none of the listed files has an ACL.
+
+  md5sum --check now accepts multiple input files, and similarly for sha1sum.
+
+  If stdin is a terminal, nohup now redirects it from /dev/null to
+  prevent the command from tying up an OpenSSH session after you logout.
+
+  "rm -FOO" now suggests "rm ./-FOO" if the file "-FOO" exists and
+  "-FOO" is not a valid option.
+
+  stat -f -c %S outputs the fundamental block size (used for block counts).
+  stat -f's default output format has been changed to output this size as well.
+  stat -f recognizes file systems of type XFS and JFS
+
+  "touch -" now touches standard output, not a file named "-".
+
+  uname -a no longer generates the -p and -i outputs if they are unknown.
+
+* Major changes in release 5.3.0 (2005-01-08) [unstable]
+
+** Bug fixes
+
+  Several fixes to chgrp and chown for compatibility with POSIX and BSD:
+
+    Do not affect symbolic links by default.
+    Now, operate on whatever a symbolic link points to, instead.
+    To get the old behavior, use --no-dereference (-h).
+
+    --dereference now works, even when the specified owner
+    and/or group match those of an affected symlink.
+
+    Check for incompatible options.  When -R and --dereference are
+    both used, then either -H or -L must also be used.  When -R and -h
+    are both used, then -P must be in effect.
+
+    -H, -L, and -P have no effect unless -R is also specified.
+    If -P and -R are both specified, -h is assumed.
+
+    Do not optimize away the chown() system call when the file's owner
+    and group already have the desired value.  This optimization was
+    incorrect, as it failed to update the last-changed time and reset
+    special permission bits, as POSIX requires.
+
+    "chown : file", "chown '' file", and "chgrp '' file" now succeed
+    without changing the uid or gid, instead of reporting an error.
+
+    Do not report an error if the owner or group of a
+    recursively-encountered symbolic link cannot be updated because
+    the file system does not support it.
+
+  chmod now accepts multiple mode-like options, e.g., "chmod -r -w f".
+
+  chown is no longer subject to a race condition vulnerability, when
+  used with --from=O:G and without the (-h) --no-dereference option.
+
+  cut's --output-delimiter=D option works with abutting byte ranges.
+
+  dircolors's documentation now recommends that shell scripts eval
+  "`dircolors`" rather than `dircolors`, to avoid shell expansion pitfalls.
+
+  du no longer segfaults when a subdirectory of an operand
+  directory is removed while du is traversing that subdirectory.
+  Since the bug was in the underlying fts.c module, it also affected
+  chown, chmod, and chgrp.
+
+  du's --exclude-from=FILE and --exclude=P options now compare patterns
+  against the entire name of each file, rather than against just the
+  final component.
+
+  echo now conforms to POSIX better.  It supports the \0ooo syntax for
+  octal escapes, and \c now terminates printing immediately.  If
+  POSIXLY_CORRECT is set and the first argument is not "-n", echo now
+  outputs all option-like arguments instead of treating them as options.
+
+  expand and unexpand now conform to POSIX better.  They check for
+  blanks (which can include characters other than space and tab in
+  non-POSIX locales) instead of spaces and tabs.  Unexpand now
+  preserves some blanks instead of converting them to tabs or spaces.
+
+  "ln x d/" now reports an error if d/x is a directory and x a file,
+  instead of incorrectly creating a link to d/x/x.
+
+  ls no longer segfaults on systems for which SIZE_MAX != (size_t) -1.
+
+  md5sum and sha1sum now report an error when given so many input
+  lines that their line counter overflows, instead of silently
+  reporting incorrect results.
+
+  Fixes for "nice":
+
+    If it fails to lower the niceness due to lack of permissions,
+    it goes ahead and runs the command anyway, as POSIX requires.
+
+    It no longer incorrectly reports an error if the current niceness
+    happens to be -1.
+
+    It no longer assumes that nicenesses range from -20 through 19.
+
+    It now consistently adjusts out-of-range nicenesses to the
+    closest values in range; formerly it sometimes reported an error.
+
+  pathchk no longer accepts trailing options, e.g., "pathchk -p foo -b"
+  now treats -b as a file name to check, not as an invalid option.
+
+  'pr --columns=N' was not equivalent to 'pr -N' when also using
+  either -s or -w.
+
+  pr now supports page numbers up to 2**64 on most hosts, and it
+  detects page number overflow instead of silently wrapping around.
+  pr now accepts file names that begin with "+" so long as the rest of
+  the file name does not look like a page range.
+
+  printf has several changes:
+
+    It now uses 'intmax_t' (not 'long int') to format integers, so it
+    can now format 64-bit integers on most modern hosts.
+
+    On modern hosts it now supports the C99-inspired %a, %A, %F conversion
+    specs, the "'" and "0" flags, and the ll, j, t, and z length modifiers
+    (this is compatible with recent Bash versions).
+
+    The printf command now rejects invalid conversion specifications
+    like %#d, instead of relying on undefined behavior in the underlying
+    printf function.
+
+  ptx now diagnoses invalid values for its --width=N (-w)
+  and --gap-size=N (-g) options.
+
+  mv (when moving between partitions) no longer fails when
+  operating on too many command-line-specified nonempty directories.
+
+  "readlink -f" is more compatible with prior implementations
+
+  rm (without -f) no longer hangs when attempting to remove a symlink
+  to a file on an off-line NFS-mounted partition.
+
+  rm no longer gets a failed assertion under some unusual conditions.
+
+  rm no longer requires read access to the current directory.
+
+  "rm -r" would mistakenly fail to remove files under a directory
+  for some types of errors (e.g., read-only file system, I/O error)
+  when first encountering the directory.
+
+  "sort" fixes:
+
+    "sort -o -" now writes to a file named "-" instead of to standard
+    output; POSIX requires this.
+
+    An unlikely race condition has been fixed where "sort" could have
+    mistakenly removed a temporary file belonging to some other process.
+
+    "sort" no longer has O(N**2) behavior when it creates many temporary files.
+
+  tac can now handle regular, nonseekable files like Linux's
+  /proc/modules.  Before, it would produce no output for such a file.
+
+  tac would exit immediately upon I/O or temp-file creation failure.
+  Now it continues on, processing any remaining command line arguments.
+
+  "tail -f" no longer mishandles pipes and fifos.  With no operands,
+  tail now ignores -f if standard input is a pipe, as POSIX requires.
+  When conforming to POSIX 1003.2-1992, tail now supports the SUSv2 b
+  modifier (e.g., "tail -10b file") and it handles some obscure cases
+  more correctly, e.g., "tail +cl" now reads the file "+cl" rather
+  than reporting an error, "tail -c file" no longer reports an error,
+  and "tail - file" no longer reads standard input.
+
+  tee now exits when it gets a SIGPIPE signal, as POSIX requires.
+  To get tee's old behavior, use the shell command "(trap '' PIPE; tee)".
+  Also, "tee -" now writes to standard output instead of to a file named "-".
+
+  "touch -- MMDDhhmm[yy] file" is now equivalent to
+  "touch MMDDhhmm[yy] file" even when conforming to pre-2001 POSIX.
+
+  tr no longer mishandles a second operand with leading "-".
+
+  who now prints user names in full instead of truncating them after 8 bytes.
+
+  The following commands now reject unknown options instead of
+  accepting them as operands, so that users are properly warned that
+  options may be added later.  Formerly they accepted unknown options
+  as operands; e.g., "basename -a a" acted like "basename -- -a a".
+
+    basename dirname factor hostname link nohup sync unlink yes
+
+** New features
+
+  For efficiency, 'sort -m' no longer copies input to a temporary file
+  merely because the input happens to come from a pipe.  As a result,
+  some relatively-contrived examples like 'cat F | sort -m -o F - G'
+  are no longer safe, as 'sort' might start writing F before 'cat' is
+  done reading it.  This problem cannot occur unless '-m' is used.
+
+  When outside the default POSIX locale, the 'who' and 'pinky'
+  commands now output timestamps like "2004-06-21 13:09" instead of
+  the traditional "Jun 21 13:09".
+
+  pwd now works even when run from a working directory whose name
+  is longer than PATH_MAX.
+
+  cp, install, ln, and mv have a new --no-target-directory (-T) option,
+  and -t is now a short name for their --target-directory option.
+
+  cp -pu and mv -u (when copying) now don't bother to update the
+  destination if the resulting timestamp would be no newer than the
+  preexisting timestamp.  This saves work in the common case when
+  copying or moving multiple times to the same destination in a file
+  system with a coarse timestamp resolution.
+
+  cut accepts a new option, --complement, to complement the set of
+  selected bytes, characters, or fields.
+
+  dd now also prints the number of bytes transferred, the time, and the
+  transfer rate.  The new "status=noxfer" operand suppresses this change.
+
+  dd has new conversions for the conv= option:
+
+    nocreat   do not create the output file
+    excl      fail if the output file already exists
+    fdatasync physically write output file data before finishing
+    fsync     likewise, but also write metadata
+
+  dd has new iflag= and oflag= options with the following flags:
+
+    append    append mode (makes sense for output file only)
+    direct    use direct I/O for data
+    dsync     use synchronized I/O for data
+    sync      likewise, but also for metadata
+    nonblock  use non-blocking I/O
+    nofollow  do not follow symlinks
+    noctty    do not assign controlling terminal from file
+
+  stty now provides support (iutf8) for setting UTF-8 input mode.
+
+  With stat, a specified format is no longer automatically newline terminated.
+  If you want a newline at the end of your output, append '\n' to the format
+  string.
+
+  'df', 'du', and 'ls' now take the default block size from the
+  BLOCKSIZE environment variable if the BLOCK_SIZE, DF_BLOCK_SIZE,
+  DU_BLOCK_SIZE, and LS_BLOCK_SIZE environment variables are not set.
+  Unlike the other variables, though, BLOCKSIZE does not affect
+  values like 'ls -l' sizes that are normally displayed as bytes.
+  This new behavior is for compatibility with BSD.
+
+  du accepts a new option --files0-from=FILE, where FILE contains a
+  list of NUL-terminated file names.
+
+  Date syntax as used by date -d, date -f, and touch -d has been
+  changed as follows:
+
+    Dates like 'January 32' with out-of-range components are now rejected.
+
+    Dates can have fractional timestamps like 2004-02-27 14:19:13.489392193.
+
+    Dates can be entered via integer counts of seconds since 1970 when
+    prefixed by '@'.  For example, '@321' represents 1970-01-01 00:05:21 UTC.
+
+    Time zone corrections can now separate hours and minutes with a colon,
+    and can follow standard abbreviations like "UTC".  For example,
+    "UTC +0530" and "+05:30" are supported, and are both equivalent to "+0530".
+
+    Date values can now have leading TZ="..." assignments that override
+    the environment only while that date is being processed.  For example,
+    the following shell command converts from Paris to New York time:
+
+      TZ="America/New_York" date --date='TZ="Europe/Paris" 2004-10-31 06:30'
+
+  'date' has a new option --iso-8601=ns that outputs
+  nanosecond-resolution timestamps.
+
+  echo -e '\xHH' now outputs a byte whose hexadecimal value is HH,
+  for compatibility with bash.
+
+  ls now exits with status 1 on minor problems, 2 if serious trouble.
+
+  ls has a new --hide=PATTERN option that behaves like
+  --ignore=PATTERN, except that it is overridden by -a or -A.
+  This can be useful for aliases, e.g., if lh is an alias for
+  "ls --hide='*~'", then "lh -A" lists the file "README~".
+
+  In the following cases POSIX allows the default GNU behavior,
+  so when POSIXLY_CORRECT is set:
+
+    false, printf, true, unlink, and yes all support --help and --option.
+    ls supports TABSIZE.
+    pr no longer depends on LC_TIME for the date format in non-POSIX locales.
+    printf supports \u, \U, \x.
+    tail supports two or more files when using the obsolete option syntax.
+
+  The usual '--' operand is now supported by chroot, hostid, hostname,
+  pwd, sync, and yes.
+
+  'od' now conforms to POSIX better, and is more compatible with BSD:
+
+    The older syntax "od [-abcdfilosx]... [FILE] [[+]OFFSET[.][b]]" now works
+    even without --traditional.  This is a change in behavior if there
+    are one or two operands and the last one begins with +, or if
+    there are two operands and the latter one begins with a digit.
+    For example, "od foo 10" and "od +10" now treat the last operand as
+    an offset, not as a file name.
+
+    -h is no longer documented, and may be withdrawn in future versions.
+    Use -x or -t x2 instead.
+
+    -i is now equivalent to -t dI (not -t d2), and
+    -l is now equivalent to -t dL (not -t d4).
+
+    -s is now equivalent to -t d2.  The old "-s[NUM]" or "-s NUM"
+    option has been renamed to "-S NUM".
+
+    The default output format is now -t oS, not -t o2, i.e., short int
+    rather than two-byte int.  This makes a difference only on hosts like
+    Cray systems where the C short int type requires more than two bytes.
+
+  readlink accepts new options: --canonicalize-existing (-e)
+  and --canonicalize-missing (-m).
+
+  The stat option --filesystem has been renamed to --file-system, for
+  consistency with POSIX "file system" and with cp and du --one-file-system.
+
+** Removed features
+
+  md5sum and sha1sum's undocumented --string option has been removed.
+
+  tail's undocumented --max-consecutive-size-changes option has been removed.
+
+* Major changes in release 5.2.1 (2004-03-12) [stable]
+
+** Bug fixes
+
+  mv could mistakenly fail to preserve hard links when moving two
+  or more arguments between partitions.
+
+  'cp --sparse=always F /dev/hdx' no longer tries to use lseek to create
+  holes in the destination.
+
+  nohup now sets the close-on-exec flag for its copy of the stderr file
+  descriptor.  This avoids some nohup-induced hangs.  For example, before
+  this change, if you ran 'ssh localhost', then 'nohup sleep 600 </dev/null &',
+  and then exited that remote shell, the ssh session would hang until the
+  10-minute sleep terminated.  With the fixed nohup, the ssh session
+  terminates immediately.
+
+  'expr' now conforms to POSIX better:
+
+    Integers like -0 and 00 are now treated as zero.
+
+    The '|' operator now returns 0, not its first argument, if both
+    arguments are null or zero.  E.g., 'expr "" \| ""' now returns 0,
+    not the empty string.
+
+    The '|' and '&' operators now use short-circuit evaluation, e.g.,
+    'expr 1 \| 1 / 0' no longer reports a division by zero.
+
+** New features
+
+  'chown user.group file' now has its traditional meaning even when
+  conforming to POSIX 1003.1-2001, so long as no user has a name
+  containing '.' that happens to equal 'user.group'.
+
+
+* Major changes in release 5.2.0 (2004-02-19) [stable]
+
+** Bug fixes
+
+  none
+
+
+* Major changes in release 5.1.3 (2004-02-08): candidate to become stable 5.2.0
+
+** Bug fixes
+
+  'cp -d' now works as required even on systems like OSF V5.1 that
+  declare stat and lstat as 'static inline' functions.
+
+  timestamps output by stat now include actual fractional seconds,
+  when available -- or .0000000 for files without that information.
+
+  seq no longer infloops when printing 2^31 or more numbers.
+  For reference, seq `echo 2^31|bc` > /dev/null takes about one hour
+  on a 1.6 GHz Athlon 2000 XP.  Now it can output 2^53-1 numbers before
+  misbehaving.
+
+* Major changes in release 5.1.2 (2004-01-25):
+
+** Bug fixes
+
+  rmdir -p exits with status 1 on error; formerly it sometimes exited
+  with status 0 when given more than one argument.
+
+  nohup now always exits with status 127 when it finds an error,
+  as POSIX requires; formerly it sometimes exited with status 1.
+
+  Several programs (including cut, date, dd, env, hostname, nl, pr,
+  stty, and tr) now always exit with status 1 when they find an error;
+  formerly they sometimes exited with status 2.
+
+  factor no longer reports a usage error if stdin has the wrong format.
+
+  paste no longer infloops on ppc systems (bug introduced in 5.1.1)
+
+
+* Major changes in release 5.1.1 (2004-01-17):
+
+** Configuration option
+
+  You can select the default level of POSIX conformance at configure-time,
+  e.g., by ./configure DEFAULT_POSIX2_VERSION=199209
+
+** Bug fixes
+
+  fold -s works once again on systems with differing sizes for int
+  and size_t (bug introduced in 5.1.0)
+
+** New features
+
+  touch -r now specifies the origin for any relative times in the -d
+  operand, if both options are given.  For example, "touch -r FOO -d
+  '-5 seconds' BAR" sets BAR's modification time to be five seconds
+  before FOO's.
+
+  join: The obsolete options "-j1 FIELD", "-j2 FIELD", and
+  "-o LIST1 LIST2..." are no longer supported on POSIX 1003.1-2001 systems.
+  Portable scripts should use "-1 FIELD", "-2 FIELD", and
+  "-o LIST1,LIST2..." respectively.  If join was compiled on a
+  POSIX 1003.1-2001 system, you may enable the old behavior
+  by setting _POSIX2_VERSION=199209 in your environment.
+  [This change was reverted in coreutils 5.3.1.]
+
+
+* Major changes in release 5.1.0 (2003-12-21):
+
+** New features
+
+  chgrp, chmod, and chown can now process (with -R) hierarchies of virtually
+  unlimited depth.  Before, they would fail to operate on any file they
+  encountered with a relative name of length PATH_MAX (often 4096) or longer.
+
+  chgrp, chmod, chown, and rm accept the new options:
+  --preserve-root, --no-preserve-root (default)
+
+  chgrp and chown now accept POSIX-mandated -L, -H, and -P options
+
+  du can now process hierarchies of virtually unlimited depth.
+  Before, du was limited by the user's stack size and it would get a
+  stack overflow error (often a segmentation fault) when applied to
+  a hierarchy of depth around 30,000 or larger.
+
+  du works even when run from an inaccessible directory
+
+  du -D now dereferences all symlinks specified on the command line,
+  not just the ones that reference directories
+
+  du now accepts -P (--no-dereference), for compatibility with du
+  of NetBSD and for consistency with e.g., chown and chgrp
+
+  du's -H option will soon have the meaning required by POSIX
+  (--dereference-args, aka -D) rather then the current meaning of --si.
+  Now, using -H elicits a warning to that effect.
+
+  When given -l and similar options, ls now adjusts the output column
+  widths to fit the data, so that output lines are shorter and have
+  columns that line up better.  This may adversely affect shell
+  scripts that expect fixed-width columns, but such shell scripts were
+  not portable anyway, even with old GNU ls where the columns became
+  ragged when a datum was too wide.
+
+  du accepts a new option, -0/--null, to make it produce NUL-terminated
+  output lines
+
+** Bug fixes
+
+  printf, seq, tail, and sleep now parse floating-point operands
+  and options in the C locale.  POSIX requires this for printf.
+
+  od -c -w9999999 no longer segfaults
+
+  csplit no longer reads from freed memory (dumping core on some systems)
+
+  csplit would mistakenly exhaust virtual memory in some cases
+
+  ls --width=N (for very large N) is no longer subject to an address
+  arithmetic bug that could result in bounds violations.
+
+  ls --width=N (with -x or -C) no longer allocates more space
+  (potentially much more) than necessary for a given directory.
+
+  dd 'unblock' and 'sync' may now be combined (e.g., dd conv=unblock,sync)
+
+* Major changes in release 5.0.91 (2003-09-08):
+
+** New features
+
+  date accepts a new option --rfc-2822, an alias for --rfc-822.
+
+  split accepts a new option -d or --numeric-suffixes.
+
+  cp, install, mv, and touch now preserve microsecond resolution on
+  file timestamps, on platforms that have the 'utimes' system call.
+  Unfortunately there is no system call yet to preserve file
+  timestamps to their full nanosecond resolution; microsecond
+  resolution is the best we can do right now.
+
+  sort now supports the zero byte (NUL) as a field separator; use -t '\0'.
+  The -t '' option, which formerly had no effect, is now an error.
+
+  sort option order no longer matters for the options -S, -d, -i, -o, and -t.
+  Stronger options override weaker, and incompatible options are diagnosed.
+
+  'sha1sum --check' now accepts the BSD format for SHA1 message digests
+  in addition to the BSD format for MD5 ones.
+
+  who -l now means 'who --login', not 'who --lookup', per POSIX.
+  who's -l option has been eliciting an unconditional warning about
+  this impending change since sh-utils-2.0.12 (April 2002).
+
+** Bug fixes
+
+  Mistakenly renaming a file onto itself, e.g., via 'mv B b' when 'B' is
+  the same directory entry as 'b' no longer destroys the directory entry
+  referenced by both 'b' and 'B'.  Note that this would happen only on
+  file systems like VFAT where two different names may refer to the same
+  directory entry, usually due to lower->upper case mapping of file names.
+  Now, the above can happen only on file systems that perform name mapping and
+  that support hard links (stat.st_nlink > 1).  This mitigates the problem
+  in two ways: few file systems appear to be affected (hpfs and ntfs are),
+  when the bug is triggered, mv no longer removes the last hard link to a file.
+  *** ATTENTION ***: if you know how to distinguish the following two cases
+  without writing to the file system in question, please let me know:
+  1) B and b refer to the same directory entry on a file system like NTFS
+       (B may well have a link count larger than 1)
+  2) B and b are hard links to the same file
+
+  stat no longer overruns a buffer for format strings ending in '%'
+
+  fold -s -wN would infloop for N < 8 with TABs in the input.
+  E.g., this would not terminate: printf 'a\t' | fold -w2 -s
+
+  'split -a0', although of questionable utility, is accepted once again.
+
+  'df DIR' used to hang under some conditions on OSF/1 5.1.  Now it doesn't.
+
+  seq's --width (-w) option now works properly even when the endpoint
+  requiring the larger width is negative and smaller than the other endpoint.
+
+  seq's default step is 1, even if LAST < FIRST.
+
+  paste no longer mistakenly outputs 0xFF bytes for a nonempty input file
+  without a trailing newline.
+
+  'tail -n0 -f FILE' and 'tail -c0 -f FILE' no longer perform what amounted
+  to a busy wait, rather than sleeping between iterations.
+
+  tail's long-undocumented --allow-missing option now elicits a warning
+
+
+* Major changes in release 5.0.90 (2003-07-29):
+
+** New features
+
+  sort is now up to 30% more CPU-efficient in some cases
+
+  'test' is now more compatible with Bash and POSIX:
+
+    'test -t', 'test --help', and 'test --version' now silently exit
+    with status 0.  To test whether standard output is a terminal, use
+    'test -t 1'.  To get help and version info for 'test', use
+    '[ --help' and '[ --version'.
+
+    'test' now exits with status 2 (not 1) if there is an error.
+
+  wc count field widths now are heuristically adjusted depending on the input
+  size, if known.  If only one count is printed, it is guaranteed to
+  be printed without leading spaces.
+
+  Previously, wc did not align the count fields if POSIXLY_CORRECT was set,
+  but POSIX did not actually require this undesirable behavior, so it
+  has been removed.
+
+** Bug fixes
+
+  kill no longer tries to operate on argv[0] (introduced in 5.0.1)
+  Why wasn't this noticed?  Although many tests use kill, none of
+  them made an effort to avoid using the shell's built-in kill.
+
+  '[' invoked with no arguments no longer evokes a segfault
+
+  rm without --recursive (aka -r or -R) no longer prompts regarding
+  unwritable directories, as required by POSIX.
+
+  uniq -c now uses a SPACE, not a TAB between the count and the
+  corresponding line, as required by POSIX.
+
+  expr now exits with status 2 if the expression is syntactically valid,
+  and with status 3 if an error occurred.  POSIX requires this.
+
+  expr now reports trouble if string comparison fails due to a collation error.
+
+  split now generates suffixes properly on EBCDIC hosts.
+
+  split -a0 now works, as POSIX requires.
+
+  'sort --version' and 'sort --help' fail, as they should
+  when their output is redirected to /dev/full.
+
+  'su --version > /dev/full' now fails, as it should.
+
+** Fewer arbitrary limitations
+
+  cut requires 97% less memory when very large field numbers or
+  byte offsets are specified.
+
+
+* Major changes in release 5.0.1 (2003-07-15):
+
+** New programs
+- new program: '[' (much like 'test')
+
+** New features
+- head now accepts --lines=-N (--bytes=-N) to print all but the
+  N lines (bytes) at the end of the file
+- md5sum --check now accepts the output of the BSD md5sum program, e.g.,
+  MD5 (f) = d41d8cd98f00b204e9800998ecf8427e
+- date -d DATE can now parse a DATE string like May-23-2003
+- chown: '.' is no longer recognized as a separator in the OWNER:GROUP
+  specifier on POSIX 1003.1-2001 systems.  If chown *was not* compiled
+  on such a system, then it still accepts '.', by default.  If chown
+  was compiled on a POSIX 1003.1-2001 system, then you may enable the
+  old behavior by setting _POSIX2_VERSION=199209 in your environment.
+- chown no longer tries to preserve set-user-ID and set-group-ID bits;
+  on some systems, the chown syscall resets those bits, and previous
+  versions of the chown command would call chmod to restore the original,
+  pre-chown(2) settings, but that behavior is problematic.
+  1) There was a window whereby a malicious user, M, could subvert a
+  chown command run by some other user and operating on files in a
+  directory where M has write access.
+  2) Before (and even now, on systems with chown(2) that doesn't reset
+  those bits), an unwary admin. could use chown unwittingly to create e.g.,
+  a set-user-ID root copy of /bin/sh.
+
+** Bug fixes
+- chown --dereference no longer leaks a file descriptor per symlink processed
+- 'du /' once again prints the '/' on the last line
+- split's --verbose option works once again [broken in 4.5.10 and 5.0]
+- tail -f is no longer subject to a race condition that could make it
+  delay displaying the last part of a file that had stopped growing.  That
+  bug could also make tail -f give an unwarranted 'file truncated' warning.
+- du no longer runs out of file descriptors unnecessarily
+- df and 'readlink --canonicalize' no longer corrupt the heap on
+  non-glibc, non-solaris systems
+- 'env -u UNSET_VARIABLE' no longer dumps core on non-glibc systems
+- readlink's --canonicalize option now works on systems like Solaris that
+  lack the canonicalize_file_name function but do have resolvepath.
+- mv now removes 'a' in this example on all systems: touch a; ln a b; mv a b
+  This behavior is contrary to POSIX (which requires that the mv command do
+  nothing and exit successfully), but I suspect POSIX will change.
+- date's %r format directive now honors locale settings
+- date's '-' (no-pad) format flag now affects the space-padded-by-default
+  conversion specifiers, %e, %k, %l
+- fmt now diagnoses invalid obsolescent width specifications like '-72x'
+- fmt now exits nonzero when unable to open an input file
+- tsort now fails when given an odd number of input tokens,
+  as required by POSIX.  Before, it would act as if the final token
+  appeared one additional time.
+
+** Fewer arbitrary limitations
+- tail's byte and line counts are no longer limited to OFF_T_MAX.
+  Now the limit is UINTMAX_MAX (usually 2^64).
+- split can now handle --bytes=N and --lines=N with N=2^31 or more.
+
+** Portability
+- 'kill -t' now prints signal descriptions (rather than '?') on systems
+  like Tru64 with __sys_siglist but no strsignal function.
+- stat.c now compiles on Ultrix systems
+- sleep now works on AIX systems that lack support for clock_gettime
+- rm now works around Darwin6.5's broken readdir function
+  Before 'rm -rf DIR' would fail to remove all files in DIR
+  if there were more than 338.
+
+* Major changes in release 5.0 (2003-04-02):
+- false --help now exits nonzero
+
+[4.5.12]
+* printf no longer treats \x specially when POSIXLY_CORRECT is set
+* printf avoids buffer overrun with format ending in a backslash and
+* printf avoids buffer overrun with incomplete conversion specifier
+* printf accepts multiple flags in a single conversion specifier
+
+[4.5.11]
+* seq no longer requires that a field width be specified
+* seq no longer fails when given a field width of '0'
+* seq now accepts " " and "'" as valid format flag characters
+* df now shows a HOSTNAME: prefix for each remote-mounted file system on AIX 5.1
+* portability tweaks for HP-UX, AIX 5.1, DJGPP
+
+[4.5.10]
+* printf no longer segfaults for a negative field width or precision
+* shred now always enables --exact for non-regular files
+* du no longer lists hard-linked files more than once
+* du no longer dumps core on some systems due to "infinite" recursion
+  via nftw's use of the buggy replacement function in getcwd.c
+* portability patches for a few vendor compilers and 64-bit systems
+* du -S *really* now works like it did before the change in 4.5.5
+
+[4.5.9]
+* du no longer truncates file sizes or sums to fit in 32-bit size_t
+* work around Linux kernel bug in getcwd (fixed in 2.4.21-pre4), so that pwd
+  now fails if the name of the working directory is so long that getcwd
+  truncates it.  Before it would print the truncated name and exit successfully.
+* 'df /some/mount-point' no longer hangs on a GNU libc system when another
+  hard-mounted NFS file system (preceding /some/mount-point in /proc/mounts)
+  is inaccessible.
+* rm -rf now gives an accurate diagnostic when failing to remove a file
+  under certain unusual conditions
+* mv and 'cp --preserve=links' now preserve multiple hard links even under
+  certain unusual conditions where they used to fail
+
+[4.5.8]
+* du -S once again works like it did before the change in 4.5.5
+* stat accepts a new file format, %B, for the size of each block reported by %b
+* du accepts new option: --apparent-size
+* du --bytes (-b) works the same way it did in fileutils-3.16 and before
+* du reports proper sizes for directories (not zero) (broken in 4.5.6 or 4.5.7)
+* df now always displays under 'Filesystem', the device file name
+  corresponding to the listed mount point.  Before, for a block- or character-
+  special file command line argument, df would display that argument.  E.g.,
+  'df /dev/hda' would list '/dev/hda' as the 'Filesystem', rather than say
+  /dev/hda3 (the device on which '/' is mounted), as it does now.
+* test now works properly when invoked from a set user ID or set group ID
+  context and when testing access to files subject to alternate protection
+  mechanisms.  For example, without this change, a set-UID program that invoked
+  'test -w F' (to see if F is writable) could mistakenly report that it *was*
+  writable, even though F was on a read-only file system, or F had an ACL
+  prohibiting write access, or F was marked as immutable.
+
+[4.5.7]
+* du would fail with more than one DIR argument when any but the last did not
+  contain a slash (due to a bug in ftw.c)
+
+[4.5.6]
+* du no longer segfaults on Solaris systems (fixed heap-corrupting bug in ftw.c)
+* du --exclude=FILE works once again (this was broken by the rewrite for 4.5.5)
+* du no longer gets a failed assertion for certain hierarchy lay-outs
+  involving hard-linked directories
+* 'who -r' no longer segfaults when using non-C-locale messages
+* df now displays a mount point (usually '/') for non-mounted
+  character-special and block files
+
+[4.5.5]
+* ls --dired produces correct byte offset for file names containing
+  nonprintable characters in a multibyte locale
+* du has been rewritten to use a variant of GNU libc's ftw.c
+* du now counts the space associated with a directory's directory entry,
+  even if it cannot list or chdir into that subdirectory.
+* du -S now includes the st_size of each entry corresponding to a subdirectory
+* rm on FreeBSD can once again remove directories from NFS-mounted file systems
+* ls has a new option --dereference-command-line-symlink-to-dir, which
+  corresponds to the new default behavior when none of -d, -l -F, -H, -L
+  has been specified.
+* ls dangling-symlink now prints 'dangling-symlink'.
+  Before, it would fail with 'no such file or directory'.
+* ls -s symlink-to-non-dir and ls -i symlink-to-non-dir now print
+  attributes of 'symlink', rather than attributes of their referents.
+* Fix a bug introduced in 4.5.4 that made it so that ls --color would no
+  longer highlight the names of files with the execute bit set when not
+  specified on the command line.
+* shred's --zero (-z) option no longer gobbles up any following argument.
+  Before, 'shred --zero file' would produce 'shred: missing file argument',
+  and worse, 'shred --zero f1 f2 ...' would appear to work, but would leave
+  the first file untouched.
+* readlink: new program
+* cut: new feature: when used to select ranges of byte offsets (as opposed
+  to ranges of fields) and when --output-delimiter=STRING is specified,
+  output STRING between ranges of selected bytes.
+* rm -r can no longer be tricked into mistakenly reporting a cycle.
+* when rm detects a directory cycle, it no longer aborts the entire command,
+  but rather merely stops processing the affected command line argument.
+
+[4.5.4]
+* cp no longer fails to parse options like this: --preserve=mode,ownership
+* 'ls --color -F symlink-to-dir' works properly
+* ls is much more efficient on directories with valid dirent.d_type.
+* stty supports all baud rates defined in linux-2.4.19.
+* 'du symlink-to-dir/' would improperly remove the trailing slash
+* 'du ""' would evoke a bounds violation.
+* In the unlikely event that running 'du /' resulted in 'stat ("/", ...)'
+  failing, du would give a diagnostic about '' (empty string) rather than '/'.
+* printf: a hexadecimal escape sequence has at most two hex. digits, not three.
+* The following features have been added to the --block-size option
+  and similar environment variables of df, du, and ls.
+  - A leading "'" generates numbers with thousands separators.
+    For example:
+      $ ls -l --block-size="'1" file
+      -rw-rw-r--    1 eggert   src      47,483,707 Sep 24 23:40 file
+  - A size suffix without a leading integer generates a suffix in the output.
+    For example:
+      $ ls -l --block-size="K"
+      -rw-rw-r--    1 eggert   src          46371K Sep 24 23:40 file
+* ls's --block-size option now affects file sizes in all cases, not
+  just for --block-size=human-readable and --block-size=si.  Fractional
+  sizes are now always rounded up, for consistency with df and du.
+* df now displays the block size using powers of 1000 if the requested
+  block size seems to be a multiple of a power of 1000.
+* nl no longer gets a segfault when run like this 'yes|nl -s%n'
+
+[4.5.3]
+* du --dereference-args (-D) no longer fails in certain cases
+* 'ln --target-dir=DIR' no longer fails when given a single argument
+
+[4.5.2]
+* 'rm -i dir' (without --recursive (-r)) no longer recurses into dir
+* 'tail -c N FILE' now works with files of size >= 4GB
+* 'mkdir -p' can now create very deep (e.g. 40,000-component) directories
+* rmdir -p dir-with-trailing-slash/ no longer fails
+* printf now honors the '--' command line delimiter
+* od's 8-byte formats x8, o8, and u8 now work
+* tail now accepts fractional seconds for its --sleep-interval=S (-s) option
+
+[4.5.1]
+* du and ls now report sizes of symbolic links (before they'd always report 0)
+* uniq now obeys the LC_COLLATE locale, as per POSIX 1003.1-2001 TC1.
+
+========================================================================
+Here are the NEWS entries made from fileutils-4.1 until the
+point at which the packages merged to form the coreutils:
+
+[4.1.11]
+* 'rm symlink-to-unwritable' doesn't prompt [introduced in 4.1.10]
+[4.1.10]
+* rm once again gives a reasonable diagnostic when failing to remove a file
+    owned by someone else in a sticky directory [introduced in 4.1.9]
+* df now rounds all quantities up, as per POSIX.
+* New ls time style: long-iso, which generates YYYY-MM-DD HH:MM.
+* Any time style can be preceded by "posix-"; this causes "ls" to
+  use traditional timestamp format when in the POSIX locale.
+* The default time style is now posix-long-iso instead of posix-iso.
+  Set TIME_STYLE="posix-iso" to revert to the behavior of 4.1.1 through 4.1.9.
+* 'rm dangling-symlink' doesn't prompt [introduced in 4.1.9]
+* stat: remove support for --secure/-s option and related %S and %C format specs
+* stat: rename --link/-l to --dereference/-L.
+    The old options will continue to work for a while.
+[4.1.9]
+* rm can now remove very deep hierarchies, in spite of any limit on stack size
+* new programs: link, unlink, and stat
+* New ls option: --author (for the Hurd).
+* 'touch -c no-such-file' no longer fails, per POSIX
+[4.1.8]
+* mv no longer mistakenly creates links to preexisting destination files
+    that aren't moved
+[4.1.7]
+* rm: close a hole that would allow a running rm process to be subverted
+[4.1.6]
+* New cp option: --copy-contents.
+* cp -r is now equivalent to cp -R.  Use cp -R -L --copy-contents to get the
+  traditional (and rarely desirable) cp -r behavior.
+* ls now accepts --time-style=+FORMAT, where +FORMAT works like date's format
+* The obsolete usage 'touch [-acm] MMDDhhmm[YY] FILE...' is no longer
+  supported on systems conforming to POSIX 1003.1-2001.  Use touch -t instead.
+* cp and inter-partition mv no longer give a misleading diagnostic in some
+    unusual cases
+[4.1.5]
+* cp -r no longer preserves symlinks
+* The block size notation is now compatible with SI and with IEC 60027-2.
+  For example, --block-size=1MB now means --block-size=1000000,
+  whereas --block-size=1MiB now means --block-size=1048576.
+  A missing 'B' (e.g. '1M') has the same meaning as before.
+  A trailing 'B' now means decimal, not binary; this is a silent change.
+  The nonstandard 'D' suffix (e.g. '1MD') is now obsolescent.
+* -H or --si now outputs the trailing 'B', for consistency with the above.
+* Programs now output trailing 'K' (not 'k') to mean 1024, as per IEC 60027-2.
+* New df, du short option -B is short for --block-size.
+* You can omit an integer '1' before a block size suffix,
+  e.g. 'df -BG' is equivalent to 'df -B 1G' and to 'df --block-size=1G'.
+* The following options are now obsolescent, as their names are
+  incompatible with IEC 60027-2:
+   df, du: -m or --megabytes (use -BM or --block-size=1M)
+   df, du, ls: --kilobytes (use --block-size=1K)
+[4.1.4]
+* df --local no longer lists smbfs file systems whose name starts with //
+* dd now detects the Linux/tape/lseek bug at run time and warns about it.
+[4.1.3]
+* ls -R once again outputs a blank line between per-directory groups of files.
+    This was broken by the cycle-detection change in 4.1.1.
+* dd once again uses 'lseek' on character devices like /dev/mem and /dev/kmem.
+    On systems with the linux kernel (at least up to 2.4.16), dd must still
+    resort to emulating 'skip=N' behavior using reads on tape devices, because
+    lseek has no effect, yet appears to succeed.  This may be a kernel bug.
+[4.1.2]
+* cp no longer fails when two or more source files are the same;
+    now it just gives a warning and doesn't copy the file the second time.
+    E.g., cp a a d/ produces this:
+    cp: warning: source file `a' specified more than once
+* chmod would set the wrong bit when given symbolic mode strings like
+    these: g=o, o=g, o=u.  E.g., 'chmod a=,o=w,ug=o f' would give a mode
+    of --w-r---w- rather than --w--w--w-.
+[4.1.1]
+* mv (likewise for cp), now fails rather than silently clobbering one of
+    the source files in the following example:
+    rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c
+* ls -R detects directory cycles, per POSIX.  It warns and doesn't infloop.
+* cp's -P option now means the same as --no-dereference, per POSIX.
+    Use --parents to get the old meaning.
+* When copying with the -H and -L options, cp can preserve logical
+    links between source files with --preserve=links
+* cp accepts new options:
+    --preserve[={mode,ownership,timestamps,links,all}]
+    --no-preserve={mode,ownership,timestamps,links,all}
+* cp's -p and --preserve options remain unchanged and are equivalent
+    to '--preserve=mode,ownership,timestamps'
+* mv and cp accept a new option: --reply={yes,no,query};  provides a consistent
+    mechanism to control whether one is prompted about certain existing
+    destination files.  Note that cp's and mv's -f options don't have the
+    same meaning: cp's -f option no longer merely turns off '-i'.
+* remove portability limitations (e.g., PATH_MAX on the Hurd, fixes for
+    64-bit systems)
+* mv now prompts before overwriting an existing, unwritable destination file
+    when stdin is a tty, unless --force (-f) is specified, as per POSIX.
+* mv: fix the bug whereby 'mv -uf source dest' would delete source,
+    even though it's older than dest.
+* chown's --from=CURRENT_OWNER:CURRENT_GROUP option now works
+* cp now ensures that the set-user-ID and set-group-ID bits are cleared for
+    the destination file when when copying and not preserving permissions.
+* 'ln -f --backup k k' gives a clearer diagnostic
+* ls no longer truncates user names or group names that are longer
+    than 8 characters.
+* ls's new --dereference-command-line option causes it to dereference
+  symbolic links on the command-line only.  It is the default unless
+  one of the -d, -F, or -l options are given.
+* ls -H now means the same as ls --dereference-command-line, as per POSIX.
+* ls -g now acts like ls -l, except it does not display owner, as per POSIX.
+* ls -n now implies -l, as per POSIX.
+* ls can now display dates and times in one of four time styles:
+
+  - The 'full-iso' time style gives full ISO-style timestamps like
+    '2001-05-14 23:45:56.477817180 -0700'.
+  - The 'iso' time style gives ISO-style timestamps like '2001-05-14 '
+    and '05-14 23:45'.
+  - The 'locale' time style gives locale-dependent timestamps like
+    'touko  14  2001' and 'touko  14 23:45' (in a Finnish locale).
+  - The 'posix-iso' time style gives traditional POSIX-locale
+    timestamps like 'May 14  2001' and 'May 14 23:45' unless the user
+    specifies a non-POSIX locale, in which case it uses ISO-style dates.
+    This is the default.
+
+  You can specify a time style with an option like --time-style='iso'
+  or with an environment variable like TIME_STYLE='iso'.  GNU Emacs 21
+  and later can parse ISO dates, but older Emacs versions cannot, so
+  if you are using an older version of Emacs outside the default POSIX
+  locale, you may need to set TIME_STYLE="locale".
+
+* --full-time is now an alias for "-l --time-style=full-iso".
+
+
+========================================================================
+Here are the NEWS entries made from sh-utils-2.0 until the
+point at which the packages merged to form the coreutils:
+
+ [2.0.15]
+* date no longer accepts e.g., September 31 in the MMDDhhmm syntax
+* fix a bug in this package's .m4 files and in configure.ac
+ [2.0.14]
+* nohup's behavior is changed as follows, to conform to POSIX 1003.1-2001:
+  - nohup no longer adjusts scheduling priority; use "nice" for that.
+  - nohup now redirects stderr to stdout, if stderr is not a terminal.
+  - nohup exit status is now 126 if command was found but not invoked,
+    127 if nohup failed or if command was not found.
+ [2.0.13]
+* uname and uptime work better on *BSD systems
+* pathchk now exits nonzero for a path with a directory component
+    that specifies a non-directory
+ [2.0.12]
+* kill: new program
+* who accepts new options: --all (-a), --boot (-b), --dead (-d), --login,
+   --process (-p), --runlevel (-r), --short (-s), --time (-t), --users (-u).
+   The -u option now produces POSIX-specified results and is the same as
+   the long option '--users'.  --idle is no longer the same as -u.
+* The following changes apply on systems conforming to POSIX 1003.1-2001:
+   - 'date -I' is no longer supported.  Instead, use 'date --iso-8601'.
+   - 'nice -NUM' is no longer supported.  Instead, use 'nice -n NUM'.
+  [This change was reverted in coreutils 5.3.1.]
+* New 'uname' options -i or --hardware-platform, and -o or --operating-system.
+   'uname -a' now outputs -i and -o information at the end.
+   New uname option --kernel-version is an alias for -v.
+   Uname option --release has been renamed to --kernel-release,
+   and --sysname has been renamed to --kernel-name;
+   the old options will work for a while, but are no longer documented.
+* 'expr' now uses the LC_COLLATE locale for string comparison, as per POSIX.
+* 'expr' now requires '+' rather than 'quote' to quote tokens;
+    this removes an incompatibility with POSIX.
+* date -d 'last friday' would print a date/time that was one hour off
+    (e.g., 23:00 on *thursday* rather than 00:00 of the preceding friday)
+    when run such that the current time and the target date/time fall on
+    opposite sides of a daylight savings time transition.
+    This problem arose only with relative date strings like 'last monday'.
+    It was not a problem with strings that include absolute dates.
+* factor is twice as fast, for large numbers
+ [2.0.11]
+* setting the date now works properly, even when using -u
+* 'date -f - < /dev/null' no longer dumps core
+* some DOS/Windows portability changes
+ [2.0j]
+* 'date -d DATE' now parses certain relative DATEs correctly
+ [2.0i]
+* fixed a bug introduced in 2.0h that made many programs fail with a
+ 'write error' when invoked with the --version option
+ [2.0h]
+* all programs fail when printing --help or --version output to a full device
+* printf exits nonzero upon write failure
+* yes now detects and terminates upon write failure
+* date --rfc-822 now always emits day and month names from the 'C' locale
+* portability tweaks for Solaris8, Ultrix, and DOS
+ [2.0g]
+* date now handles two-digit years with leading zeros correctly.
+* printf interprets unicode, \uNNNN \UNNNNNNNN, on systems with the
+  required support;  from Bruno Haible.
+* stty's rprnt attribute now works on HPUX 10.20
+* seq's --equal-width option works more portably
+ [2.0f]
+* fix build problems with ut_name vs. ut_user
+ [2.0e]
+* stty: fix long-standing bug that caused test failures on at least HPUX
+  systems when COLUMNS was set to zero
+* still more portability fixes
+* unified lib/: now that directory and most of the configuration framework
+  is common between fileutils, textutils, and sh-utils
+ [2.0d]
+* fix portability problem with sleep vs lib/strtod.c's requirement for -lm
+ [2.0c]
+* fix portability problems with nanosleep.c and with the new code in sleep.c
+ [2.0b]
+* Regenerate lib/Makefile.in so that nanosleep.c is distributed.
+ [2.0a]
+* sleep accepts floating point arguments on command line
+* sleep's clock continues counting down when sleep is suspended
+* when a suspended sleep process is resumed, it continues sleeping if
+  there is any time remaining
+* who once again prints whatever host information it has, even without --lookup
+
+========================================================================
+For older NEWS entries for the fileutils, textutils, and sh-utils
+packages, see ./old/*/NEWS.
+
+  This package began as the union of the following:
+  textutils-2.1, fileutils-4.1.11, sh-utils-2.0.15.
+
+========================================================================
+
+Copyright (C) 2001-2020 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
+Texts.  A copy of the license is included in the "GNU Free
+Documentation License" file as part of this distribution.
Index: create-8.32-no-ls-quoting-patch/coreutils-8.32-new/doc/coreutils.texi
===================================================================
--- create-8.32-no-ls-quoting-patch/coreutils-8.32-new/doc/coreutils.texi	(nonexistent)
+++ create-8.32-no-ls-quoting-patch/coreutils-8.32-new/doc/coreutils.texi	(revision 5)
@@ -0,0 +1,19492 @@
+\input texinfo
+@c %**start of header
+@setfilename coreutils.info
+@settitle GNU Coreutils
+@documentencoding UTF-8
+@allowcodebreaks false
+
+@c %**end of header
+
+@include version.texi
+@include constants.texi
+
+@c Define new indices.
+@defcodeindex op
+@defcodeindex fl
+
+@c Put everything in one index (arbitrarily chosen to be the concept index).
+@syncodeindex fl cp
+@syncodeindex fn cp
+@syncodeindex ky cp
+@syncodeindex op cp
+@syncodeindex pg cp
+@syncodeindex vr cp
+
+@dircategory Basics
+@direntry
+* Coreutils: (coreutils).       Core GNU (file, text, shell) utilities.
+* Common options: (coreutils)Common options.
+* File permissions: (coreutils)File permissions.  Access modes.
+* Date input formats: (coreutils)Date input formats.
+@end direntry
+
+@c FIXME: the following need documentation
+@c * [: (coreutils)[ invocation.                   File/string tests.
+@c * pinky: (coreutils)pinky invocation.           FIXME.
+
+@dircategory Individual utilities
+@direntry
+* arch: (coreutils)arch invocation.             Print machine hardware name.
+* b2sum: (coreutils)b2sum invocation.           Print or check BLAKE2 digests.
+* base32: (coreutils)base32 invocation.         Base32 encode/decode data.
+* base64: (coreutils)base64 invocation.         Base64 encode/decode data.
+* basename: (coreutils)basename invocation.     Strip directory and suffix.
+* basenc: (coreutils)basenc invocation.         Encoding/decoding of data.
+* cat: (coreutils)cat invocation.               Concatenate and write files.
+* chcon: (coreutils)chcon invocation.           Change SELinux CTX of files.
+* chgrp: (coreutils)chgrp invocation.           Change file groups.
+* chmod: (coreutils)chmod invocation.           Change access permissions.
+* chown: (coreutils)chown invocation.           Change file owners and groups.
+* chroot: (coreutils)chroot invocation.         Specify the root directory.
+* cksum: (coreutils)cksum invocation.           Print POSIX CRC checksum.
+* comm: (coreutils)comm invocation.             Compare sorted files by line.
+* cp: (coreutils)cp invocation.                 Copy files.
+* csplit: (coreutils)csplit invocation.         Split by context.
+* cut: (coreutils)cut invocation.               Print selected parts of lines.
+* date: (coreutils)date invocation.             Print/set system date and time.
+* dd: (coreutils)dd invocation.                 Copy and convert a file.
+* df: (coreutils)df invocation.                 Report file system disk usage.
+* dir: (coreutils)dir invocation.               List directories briefly.
+* dircolors: (coreutils)dircolors invocation.   Color setup for ls.
+* dirname: (coreutils)dirname invocation.       Strip last file name component.
+* du: (coreutils)du invocation.                 Report on disk usage.
+* echo: (coreutils)echo invocation.             Print a line of text.
+* env: (coreutils)env invocation.               Modify the environment.
+* expand: (coreutils)expand invocation.         Convert tabs to spaces.
+* expr: (coreutils)expr invocation.             Evaluate expressions.
+* factor: (coreutils)factor invocation.         Print prime factors
+* false: (coreutils)false invocation.           Do nothing, unsuccessfully.
+* fmt: (coreutils)fmt invocation.               Reformat paragraph text.
+* fold: (coreutils)fold invocation.             Wrap long input lines.
+* groups: (coreutils)groups invocation.         Print group names a user is in.
+* head: (coreutils)head invocation.             Output the first part of files.
+* hostid: (coreutils)hostid invocation.         Print numeric host identifier.
+* hostname: (coreutils)hostname invocation.     Print or set system name.
+* id: (coreutils)id invocation.                 Print user identity.
+* install: (coreutils)install invocation.       Copy files and set attributes.
+* join: (coreutils)join invocation.             Join lines on a common field.
+* kill: (coreutils)kill invocation.             Send a signal to processes.
+* link: (coreutils)link invocation.             Make hard links between files.
+* ln: (coreutils)ln invocation.                 Make links between files.
+* logname: (coreutils)logname invocation.       Print current login name.
+* ls: (coreutils)ls invocation.                 List directory contents.
+* md5sum: (coreutils)md5sum invocation.         Print or check MD5 digests.
+* mkdir: (coreutils)mkdir invocation.           Create directories.
+* mkfifo: (coreutils)mkfifo invocation.         Create FIFOs (named pipes).
+* mknod: (coreutils)mknod invocation.           Create special files.
+* mktemp: (coreutils)mktemp invocation.         Create temporary files.
+* mv: (coreutils)mv invocation.                 Rename files.
+* nice: (coreutils)nice invocation.             Modify niceness.
+* nl: (coreutils)nl invocation.                 Number lines and write files.
+* nohup: (coreutils)nohup invocation.           Immunize to hangups.
+* nproc: (coreutils)nproc invocation.           Print the number of processors.
+* numfmt: (coreutils)numfmt invocation.         Reformat numbers.
+* od: (coreutils)od invocation.                 Dump files in octal, etc.
+* paste: (coreutils)paste invocation.           Merge lines of files.
+* pathchk: (coreutils)pathchk invocation.       Check file name portability.
+* pr: (coreutils)pr invocation.                 Paginate or columnate files.
+* printenv: (coreutils)printenv invocation.     Print environment variables.
+* printf: (coreutils)printf invocation.         Format and print data.
+* ptx: (coreutils)ptx invocation.               Produce permuted indexes.
+* pwd: (coreutils)pwd invocation.               Print working directory.
+* readlink: (coreutils)readlink invocation.     Print referent of a symlink.
+* realpath: (coreutils)realpath invocation.     Print resolved file names.
+* rm: (coreutils)rm invocation.                 Remove files.
+* rmdir: (coreutils)rmdir invocation.           Remove empty directories.
+* runcon: (coreutils)runcon invocation.         Run in specified SELinux CTX.
+* seq: (coreutils)seq invocation.               Print numeric sequences
+* sha1sum: (coreutils)sha1sum invocation.       Print or check SHA-1 digests.
+* sha2: (coreutils)sha2 utilities.              Print or check SHA-2 digests.
+* shred: (coreutils)shred invocation.           Remove files more securely.
+* shuf: (coreutils)shuf invocation.             Shuffling text files.
+* sleep: (coreutils)sleep invocation.           Delay for a specified time.
+* sort: (coreutils)sort invocation.             Sort text files.
+* split: (coreutils)split invocation.           Split into pieces.
+* stat: (coreutils)stat invocation.             Report file(system) status.
+* stdbuf: (coreutils)stdbuf invocation.         Modify stdio buffering.
+* stty: (coreutils)stty invocation.             Print/change terminal settings.
+* sum: (coreutils)sum invocation.               Print traditional checksum.
+* sync: (coreutils)sync invocation.             Synchronize memory to disk.
+* tac: (coreutils)tac invocation.               Reverse files.
+* tail: (coreutils)tail invocation.             Output the last part of files.
+* tee: (coreutils)tee invocation.               Redirect to multiple files.
+* test: (coreutils)test invocation.             File/string tests.
+* timeout: (coreutils)timeout invocation.       Run with time limit.
+* touch: (coreutils)touch invocation.           Change file timestamps.
+* tr: (coreutils)tr invocation.                 Translate characters.
+* true: (coreutils)true invocation.             Do nothing, successfully.
+* truncate: (coreutils)truncate invocation.     Shrink/extend size of a file.
+* tsort: (coreutils)tsort invocation.           Topological sort.
+* tty: (coreutils)tty invocation.               Print terminal name.
+* uname: (coreutils)uname invocation.           Print system information.
+* unexpand: (coreutils)unexpand invocation.     Convert spaces to tabs.
+* uniq: (coreutils)uniq invocation.             Uniquify files.
+* unlink: (coreutils)unlink invocation.         Removal via unlink(2).
+* uptime: (coreutils)uptime invocation.         Print uptime and load.
+* users: (coreutils)users invocation.           Print current user names.
+* vdir: (coreutils)vdir invocation.             List directories verbosely.
+* wc: (coreutils)wc invocation.                 Line, word, and byte counts.
+* who: (coreutils)who invocation.               Print who is logged in.
+* whoami: (coreutils)whoami invocation.         Print effective user ID.
+* yes: (coreutils)yes invocation.               Print a string indefinitely.
+@end direntry
+
+@copying
+This manual documents version @value{VERSION} of the GNU core
+utilities, including the standard programs for text and file manipulation.
+
+Copyright @copyright{} 1994-2020 Free Software Foundation, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
+Texts.  A copy of the license is included in the section entitled ``GNU
+Free Documentation License''.
+@end quotation
+@end copying
+
+@titlepage
+@title GNU @code{Coreutils}
+@subtitle Core GNU utilities
+@subtitle for version @value{VERSION}, @value{UPDATED}
+@author David MacKenzie et al.
+
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+@shortcontents
+@contents
+
+@ifnottex
+@node Top
+@top GNU Coreutils
+
+@insertcopying
+@end ifnottex
+
+@cindex core utilities
+@cindex text utilities
+@cindex shell utilities
+@cindex file utilities
+
+@menu
+* Introduction::                 Caveats, overview, and authors
+* Common options::               Common options
+* Output of entire files::       cat tac nl od base32 base64 basenc
+* Formatting file contents::     fmt pr fold
+* Output of parts of files::     head tail split csplit
+* Summarizing files::            wc sum cksum b2sum 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 mktemp realpath
+* Working context::              pwd stty printenv tty
+* User information::             id logname whoami groups users who
+* System context::               date arch nproc uname hostname hostid uptime
+* SELinux context::              chcon runcon
+* Modified command invocation::  chroot env nice nohup stdbuf timeout
+* Process control::              kill
+* Delaying::                     sleep
+* Numeric operations::           factor numfmt seq
+* File permissions::             Access modes
+* File timestamps::              File timestamp issues
+* Date input formats::           Specifying date strings
+* Version sort ordering::        Details on version-sort algorithm
+* 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
+* Floating point::               Floating point number representation
+* Signal specifications::        Specifying signals
+* Disambiguating names and IDs:: chgrp, chown, chroot, id: user 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
+* Multi-call invocation::        Multi-call program invocation
+
+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
+* base32 invocation::            Transform data into printable data
+* base64 invocation::            Transform data into printable data
+* basenc 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
+
+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
+
+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
+* b2sum invocation::             Print or check BLAKE2 digests
+* 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
+
+@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 GNU extensions to @command{ptx}
+
+Operating on fields
+
+* 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
+
+@command{tr}: Translate, squeeze, and/or delete characters
+
+* Character sets::               Specifying sets of characters
+* Translating::                  Changing one set of characters to another
+* Squeezing and deleting::       Removing characters
+
+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}
+
+@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
+* 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
+
+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
+
+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
+
+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 cached writes to persistent storage
+* 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
+
+Conditions
+
+* 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
+
+@command{expr}: Evaluate expression
+
+* String expressions::           + : match substr index length
+* Numeric expressions::          + - * / %
+* Relations for expr::           | & < <= = == != >= >
+* Examples of expr::             Examples of using @command{expr}
+
+Redirection
+
+* tee invocation::               Redirect output to multiple files or processes
+
+File name manipulation
+
+* basename invocation::          Strip directory and suffix from a file name
+* dirname invocation::           Strip last file name component
+* pathchk invocation::           Check file name validity and portability
+* mktemp invocation::            Create temporary file or directory
+* realpath invocation::          Print resolved file names
+
+Working context
+
+* pwd invocation::               Print working directory
+* stty invocation::              Print or change terminal characteristics
+* printenv invocation::          Print all or some environment variables
+* tty invocation::               Print file name of terminal on standard input
+
+@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
+
+User information
+
+* id invocation::                Print user identity
+* logname invocation::           Print current login name
+* whoami invocation::            Print effective user ID
+* groups invocation::            Print group names a user is in
+* users invocation::             Print login names of users currently logged in
+* who invocation::               Print who is currently logged in
+
+System context
+
+* arch invocation::              Print machine hardware name
+* date invocation::              Print or set system date and time
+* nproc invocation::             Print the number of processors
+* uname invocation::             Print system information
+* hostname invocation::          Print or set system name
+* hostid invocation::            Print numeric host identifier
+* uptime invocation::            Print system uptime and load
+
+@command{date}: Print or set system date and time
+
+* Time conversion specifiers::   %[HIklMNpPrRsSTXzZ]
+* 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
+
+SELinux context
+
+* chcon invocation::             Change SELinux context of file
+* runcon invocation::            Run a command in specified SELinux context
+
+Modified command invocation
+
+* chroot invocation::            Run a command with a different root directory
+* env invocation::               Run a command in a modified environment
+* nice invocation::              Run a command with modified niceness
+* nohup invocation::             Run a command immune to hangups
+* stdbuf invocation::            Run a command with modified I/O buffering
+* timeout invocation::           Run a command with a time limit
+
+Process control
+
+* kill invocation::              Sending a signal to processes.
+
+Delaying
+
+* sleep invocation::             Delay for a specified time
+
+Numeric operations
+
+* factor invocation::            Print prime factors
+* numfmt invocation::            Reformat numbers
+* seq invocation::               Print numeric sequences
+
+
+File timestamps
+
+* File timestamps::              File timestamp issues
+
+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
+
+Date input formats
+
+* General date syntax::          Common rules
+* Calendar date items::          19 Dec 1994
+* Time of day items::            9:20pm
+* Time zone items::              EST, PDT, UTC, @dots{}
+* Combined date and time of day items:: 1972-09-24T20:02:00,000000-0500
+* 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 parse_datetime::    Bellovin, Eggert, Salz, Berets, et al.
+
+Version sorting order
+
+* Version sort overview::
+* Implementation Details::
+* Differences from the official Debian Algorithm::
+* Advanced Topics::
+
+Opening the software toolbox
+
+* Toolbox introduction::         Toolbox introduction
+* I/O redirection::              I/O redirection
+* The who command::              The @command{who} command
+* The cut command::              The @command{cut} command
+* The sort command::             The @command{sort} command
+* The uniq command::             The @command{uniq} command
+* Putting the tools together::   Putting the tools together
+
+Copying This Manual
+
+* GNU Free Documentation License::     Copying and sharing this manual
+
+@end detailmenu
+@end menu
+
+
+@node Introduction
+@chapter Introduction
+
+This manual is a work in progress: many sections make no attempt to explain
+basic concepts in a way suitable for novices.  Thus, if you are interested,
+please get involved in improving this manual.  The entire GNU community
+will benefit.
+
+@cindex POSIX
+The GNU utilities documented here are mostly compatible with the
+POSIX standard.
+@cindex bugs, reporting
+
+Please report bugs to @email{bug-coreutils@@gnu.org}.
+Include the version number, machine architecture, input files, and
+any other information needed to reproduce the bug: your input, what you
+expected, what you got, and why it is wrong.
+
+If you have a problem with @command{sort} or @command{date}, try using the
+@option{--debug} option, as it can can often help find and fix problems without
+having to wait for an answer to a bug report.  If the debug output
+does not suffice to fix the problem on your own, please compress and
+attach it to the rest of your bug report.
+
+Although diffs are welcome,
+please include a description of the problem as well, since this is
+sometimes difficult to infer.  @xref{Bugs, , , gcc, Using and Porting GNU CC}.
+
+@cindex Berry, K.
+@cindex Paterson, R.
+@cindex Stallman, R.
+@cindex Pinard, F.
+@cindex MacKenzie, D.
+@cindex Meyering, J.
+@cindex Youmans, B.
+This manual was originally derived from the Unix man pages in the
+distributions, which were written by David MacKenzie and updated by Jim
+Meyering.  What you are reading now is the authoritative documentation
+for these utilities; the man pages are no longer being maintained.  The
+original @command{fmt} man page was written by Ross Paterson.  Fran@,{c}ois
+Pinard did the initial conversion to Texinfo format.  Karl Berry did the
+indexing, some reorganization, and editing of the results.  Brian
+Youmans of the Free Software Foundation office staff combined the
+manuals for textutils, fileutils, and sh-utils to produce the present
+omnibus manual.  Richard Stallman contributed his usual invaluable
+insights to the overall process.
+
+@node Common options
+@chapter Common options
+
+@macro optBackup
+@item -b
+@itemx --backup[=@var{method}]
+@opindex -b
+@opindex --backup
+@vindex VERSION_CONTROL
+@cindex backups, making
+@xref{Backup options}.
+Make a backup of each file that would otherwise be overwritten or removed.
+@end macro
+
+@macro optBackupSuffix
+@item -S @var{suffix}
+@itemx --suffix=@var{suffix}
+@opindex -S
+@opindex --suffix
+Append @var{suffix} to each backup file made with @option{-b}.
+@xref{Backup options}.
+@end macro
+
+@macro optTargetDirectory
+@item -t @var{directory}
+@itemx --target-directory=@var{directory}
+@opindex -t
+@opindex --target-directory
+@cindex target directory
+@cindex destination directory
+Specify the destination @var{directory}.
+@xref{Target directory}.
+@end macro
+
+@macro optNoTargetDirectory
+@item -T
+@itemx --no-target-directory
+@opindex -T
+@opindex --no-target-directory
+@cindex target directory
+@cindex destination directory
+Do not treat the last operand specially when it is a directory or a
+symbolic link to a directory.  @xref{Target directory}.
+@end macro
+
+@macro outputNUL
+@cindex output NUL-byte-terminated lines
+Output a zero byte (ASCII NUL) at the end of each line,
+rather than a newline.  This option enables other programs to parse the
+output even when that output would contain data with embedded newlines.
+@end macro
+
+@macro optNull
+@item -0
+@itemx --null
+@opindex -0
+@opindex --null
+@outputNUL
+@end macro
+
+@macro optZero
+@item -z
+@itemx --zero
+@opindex -z
+@opindex --zero
+@outputNUL
+@end macro
+
+@macro optZeroTerminated
+@item -z
+@itemx --zero-terminated
+@opindex -z
+@opindex --zero-terminated
+@cindex process zero-terminated items
+Delimit items with a zero byte rather than a newline (ASCII LF).
+I.e., treat input as items separated by ASCII NUL
+and terminate output items with ASCII NUL.
+This option can be useful in conjunction with @samp{perl -0} or
+@samp{find -print0} and @samp{xargs -0} which do the same in order to
+reliably handle arbitrary file names (even those containing blanks
+or other special characters).
+@end macro
+
+@macro optSi
+@item --si
+@opindex --si
+@cindex SI output
+Append an SI-style abbreviation to each size, such as @samp{M} for
+megabytes.  Powers of 1000 are used, not 1024; @samp{M} stands for
+1,000,000 bytes.  This option is equivalent to
+@option{--block-size=si}.  Use the @option{-h} or
+@option{--human-readable} option if
+you prefer powers of 1024.
+@end macro
+
+@macro optHumanReadable
+@item -h
+@itemx --human-readable
+@opindex -h
+@opindex --human-readable
+@cindex human-readable output
+Append a size letter to each size, such as @samp{M} for mebibytes.
+Powers of 1024 are used, not 1000; @samp{M} stands for 1,048,576 bytes.
+This option is equivalent to @option{--block-size=human-readable}.
+Use the @option{--si} option if you prefer powers of 1000.
+@end macro
+
+@macro optStripTrailingSlashes
+@item --strip-trailing-slashes
+@opindex --strip-trailing-slashes
+@cindex stripping trailing slashes
+Remove any trailing slashes from each @var{source} argument.
+@xref{Trailing slashes}.
+@end macro
+
+@macro mayConflictWithShellBuiltIn{cmd}
+@cindex conflicts with shell built-ins
+@cindex built-in shell commands, conflicts with
+Due to shell aliases and built-in @command{\cmd\} functions, using an
+unadorned @command{\cmd\} interactively or in a script may get you
+different functionality than that described here.  Invoke it via
+@command{env} (i.e., @code{env \cmd\ @dots{}}) to avoid interference
+from the shell.
+
+@end macro
+
+@macro multiplierSuffixes{varName}
+@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)
+@samp{K}  =>           1024 (KibiBytes)
+@samp{MB} =>      1000*1000 (MegaBytes)
+@samp{M}  =>      1024*1024 (MebiBytes)
+@samp{GB} => 1000*1000*1000 (GigaBytes)
+@samp{G}  => 1024*1024*1024 (GibiBytes)
+@end example
+and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}.
+Binary prefixes can be used, too: @samp{KiB}=@samp{K}, @samp{MiB}=@samp{M},
+and so on.
+@end macro
+
+@c FIXME: same as above, but no ``blocks'' line.
+@macro multiplierSuffixesNoBlocks{varName}
+@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)
+@samp{MB} =>      1000*1000 (MegaBytes)
+@samp{M}  =>      1024*1024 (MebiBytes)
+@samp{GB} => 1000*1000*1000 (GigaBytes)
+@samp{G}  => 1024*1024*1024 (GibiBytes)
+@end example
+and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}.
+Binary prefixes can be used, too: @samp{KiB}=@samp{K}, @samp{MiB}=@samp{M},
+and so on.
+@end macro
+
+@cindex common options
+
+Certain options are available in all of these programs.  Rather than
+writing identical descriptions for each of the programs, they are
+described here.  (In fact, every GNU program accepts (or should accept)
+these options.)
+
+@vindex POSIXLY_CORRECT
+Normally options and operands can appear in any order, and programs act
+as if all the options appear before any operands.  For example,
+@samp{sort -r passwd -t :} acts like @samp{sort -r -t : passwd}, since
+@samp{:} is an option-argument of @option{-t}.  However, if the
+@env{POSIXLY_CORRECT} environment variable is set, options must appear
+before operands, unless otherwise specified for a particular command.
+
+A few programs can usefully have trailing operands with leading
+@samp{-}.  With such a program, options must precede operands even if
+@env{POSIXLY_CORRECT} is not set, and this fact is noted in the
+program description.  For example, the @command{env} command's options
+must appear before its operands, since in some cases the operands
+specify a command that itself contains options.
+
+Most programs that accept long options recognize unambiguous
+abbreviations of those options.  For example, @samp{rmdir
+--ignore-fail-on-non-empty} can be invoked as @samp{rmdir
+--ignore-fail} or even @samp{rmdir --i}.  Ambiguous options, such as
+@samp{ls --h}, are identified as such.
+
+Some of these programs recognize the @option{--help} and @option{--version}
+options only when one of them is the sole command line argument.  For
+these programs, abbreviations of the long options are not always recognized.
+
+@table @samp
+
+@item --help
+@opindex --help
+@cindex help, online
+Print a usage message listing all available options, then exit successfully.
+
+@item --version
+@opindex --version
+@cindex version number, finding
+Print the version number, then exit successfully.
+
+@item --
+@opindex --
+@cindex option delimiter
+Delimit the option list.  Later arguments, if any, are treated as
+operands even if they begin with @samp{-}.  For example, @samp{sort --
+-r} reads from the file named @file{-r}.
+
+@end table
+
+@cindex standard input
+@cindex standard output
+A single @samp{-} operand is not really an option, though it looks like one.  It
+stands for a file operand, and some tools treat it as standard input, or as
+standard output if that is clear from the context.  For example, @samp{sort -}
+reads from standard input, and is equivalent to plain @samp{sort}.  Unless
+otherwise specified, a @samp{-} can appear as any operand that requires a file
+name.
+
+@menu
+* Exit status::                 Indicating program success or failure.
+* Backup options::              -b -S, in some programs.
+* Block size::                  BLOCK_SIZE and --block-size, in some programs.
+* Floating point::              Floating point number representation.
+* Signal specifications::       Specifying signals using the --signal option.
+* Disambiguating names and IDs:: chgrp, chown, chroot, id: user and group syntax
+* Random sources::              --random-source, in some programs.
+* Target directory::            Specifying a target directory, in some programs.
+* Trailing slashes::            --strip-trailing-slashes, in some programs.
+* Traversing symlinks::         -H, -L, or -P, in some programs.
+* Treating / specially::        --preserve-root and --no-preserve-root.
+* Special built-in utilities::  @command{break}, @command{:}, @dots{}
+* Standards conformance::       Conformance to the POSIX standard.
+* Multi-call invocation::       Multi-call program invocation.
+@end menu
+
+
+@node Exit status
+@section Exit status
+
+@macro exitstatus
+An exit status of zero indicates success,
+and a nonzero value indicates failure.
+@end macro
+
+Nearly every command invocation yields an integral @dfn{exit status}
+that can be used to change how other commands work.
+For the vast majority of commands, an exit status of zero indicates
+success.  Failure is indicated by a nonzero value---typically
+@samp{1}, though it may differ on unusual platforms as POSIX
+requires only that it be nonzero.
+
+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{numfmt}, @command{printenv}, @command{sort},
+@command{stdbuf}, @command{test}, @command{timeout}, @command{tty}.
+
+
+@node Backup options
+@section Backup options
+
+@cindex backup options
+
+Some GNU programs (at least @command{cp}, @command{install},
+@command{ln}, and @command{mv}) optionally make backups of files
+before writing new versions.
+These options control the details of these backups.  The options are also
+briefly mentioned in the descriptions of the particular programs.
+
+@table @samp
+
+@item -b
+@itemx --backup[=@var{method}]
+@opindex -b
+@opindex --backup
+@vindex VERSION_CONTROL
+@cindex backups, making
+Make a backup of each file that would otherwise be overwritten or removed.
+Without this option, the original versions are destroyed.
+Use @var{method} to determine the type of backups to make.
+When this option is used but @var{method} is not specified,
+then the value of the @env{VERSION_CONTROL}
+environment variable is used.  And if @env{VERSION_CONTROL} is not set,
+the default backup type is @samp{existing}.
+
+Note that the short form of this option, @option{-b} does not accept any
+argument.  Using @option{-b} is equivalent to using @option{--backup=existing}.
+
+@vindex version-control @r{Emacs variable}
+This option corresponds to the Emacs variable @samp{version-control};
+the values for @var{method} are the same as those used in Emacs.
+This option also accepts more descriptive names.
+The valid @var{method}s are (unique abbreviations are accepted):
+
+@table @samp
+@item none
+@itemx off
+@opindex none @r{backup method}
+Never make backups.
+
+@item numbered
+@itemx t
+@opindex numbered @r{backup method}
+Always make numbered backups.
+
+@item existing
+@itemx nil
+@opindex existing @r{backup method}
+Make numbered backups of files that already have them, simple backups
+of the others.
+
+@item simple
+@itemx never
+@opindex simple @r{backup method}
+Always make simple backups.  Please note @samp{never} is not to be
+confused with @samp{none}.
+
+@end table
+
+@item -S @var{suffix}
+@itemx --suffix=@var{suffix}
+@opindex -S
+@opindex --suffix
+@cindex backup suffix
+@vindex SIMPLE_BACKUP_SUFFIX
+Append @var{suffix} to each backup file made with @option{-b}.  If this
+option is not specified, the value of the @env{SIMPLE_BACKUP_SUFFIX}
+environment variable is used.  And if @env{SIMPLE_BACKUP_SUFFIX} is not
+set, the default is @samp{~}, just as in Emacs.
+
+@end table
+
+@node Block size
+@section Block size
+
+@cindex block size
+
+Some GNU programs (at least @command{df}, @command{du}, and
+@command{ls}) display sizes in ``blocks''.  You can adjust the block size
+and method of display to make sizes easier to read.  The block size
+used for display is independent of any file system block size.
+Fractional block counts are rounded up to the nearest integer.
+
+@opindex --block-size=@var{size}
+@vindex BLOCKSIZE
+@vindex BLOCK_SIZE
+@vindex DF_BLOCK_SIZE
+@vindex DU_BLOCK_SIZE
+@vindex LS_BLOCK_SIZE
+@vindex POSIXLY_CORRECT@r{, and block size}
+
+The default block size is chosen by examining the following environment
+variables in turn; the first one that is set determines the block size.
+
+@table @code
+
+@item DF_BLOCK_SIZE
+This specifies the default block size for the @command{df} command.
+Similarly, @env{DU_BLOCK_SIZE} specifies the default for @command{du} and
+@env{LS_BLOCK_SIZE} for @command{ls}.
+
+@item BLOCK_SIZE
+This specifies the default block size for all three commands, if the
+above command-specific environment variables are not set.
+
+@item BLOCKSIZE
+This specifies the default block size for all values that are normally
+printed as blocks, if neither @env{BLOCK_SIZE} nor the above
+command-specific environment variables are set.  Unlike the other
+environment variables, @env{BLOCKSIZE} does not affect values that are
+normally printed as byte counts, e.g., the file sizes contained in
+@code{ls -l} output.
+
+@item POSIXLY_CORRECT
+If neither @env{@var{command}_BLOCK_SIZE}, nor @env{BLOCK_SIZE}, nor
+@env{BLOCKSIZE} is set, but this variable is set, the block size
+defaults to 512.
+
+@end table
+
+If none of the above environment variables are set, the block size
+currently defaults to 1024 bytes in most contexts, but this number may
+change in the future.  For @command{ls} file sizes, the block size
+defaults to 1 byte.
+
+@cindex human-readable output
+@cindex SI output
+
+A block size specification can be a positive integer specifying the number
+of bytes per block, or it can be @code{human-readable} or @code{si} to
+select a human-readable format.  Integers may be followed by suffixes
+that are upward compatible with the
+@uref{http://www.bipm.org/en/publications/si-brochure/chapter3.html,
+SI prefixes}
+for decimal multiples and with the
+@uref{https://physics.nist.gov/cuu/Units/binary.html, ISO/IEC 80000-13
+(formerly IEC 60027-2) prefixes} for binary multiples.
+
+With human-readable formats, output sizes are followed by a size letter
+such as @samp{M} for megabytes.  @code{BLOCK_SIZE=human-readable} uses
+powers of 1024; @samp{M} stands for 1,048,576 bytes.
+@code{BLOCK_SIZE=si} is similar, but uses powers of 1000 and appends
+@samp{B}; @samp{MB} stands for 1,000,000 bytes.
+
+@vindex LC_NUMERIC
+A block size specification preceded by @samp{'} causes output sizes to
+be displayed with thousands separators.  The @env{LC_NUMERIC} locale
+specifies the thousands separator and grouping.  For example, in an
+American English locale, @samp{--block-size="'1kB"} would cause a size
+of 1234000 bytes to be displayed as @samp{1,234}.  In the default C
+locale, there is no thousands separator so a leading @samp{'} has no
+effect.
+
+An integer block size can be followed by a suffix to specify a
+multiple of that size.  A bare size letter,
+or one followed by @samp{iB}, specifies
+a multiple using powers of 1024.  A size letter followed by @samp{B}
+specifies powers of 1000 instead.  For example, @samp{1M} and
+@samp{1MiB} are equivalent to @samp{1048576}, whereas @samp{1MB} is
+equivalent to @samp{1000000}.
+
+A plain suffix without a preceding integer acts as if @samp{1} were
+prepended, except that it causes a size indication to be appended to
+the output.  For example, @samp{--block-size="kB"} displays 3000 as
+@samp{3kB}.
+
+The following suffixes are defined.  Large sizes like @code{1Y}
+may be rejected by your computer due to limitations of its arithmetic.
+
+@table @samp
+@item kB
+@cindex kilobyte, definition of
+kilobyte: @math{10^3 = 1000}.
+@item k
+@itemx K
+@itemx KiB
+@cindex kibibyte, definition of
+kibibyte: @math{2^{10} = 1024}.  @samp{K} is special: the SI prefix is
+@samp{k} and the ISO/IEC 80000-13 prefix is @samp{Ki}, but tradition and
+POSIX use @samp{k} to mean @samp{KiB}.
+@item MB
+@cindex megabyte, definition of
+megabyte: @math{10^6 = 1,000,000}.
+@item M
+@itemx MiB
+@cindex mebibyte, definition of
+mebibyte: @math{2^{20} = 1,048,576}.
+@item GB
+@cindex gigabyte, definition of
+gigabyte: @math{10^9 = 1,000,000,000}.
+@item G
+@itemx GiB
+@cindex gibibyte, definition of
+gibibyte: @math{2^{30} = 1,073,741,824}.
+@item TB
+@cindex terabyte, definition of
+terabyte:  @math{10^{12} = 1,000,000,000,000}.
+@item T
+@itemx TiB
+@cindex tebibyte, definition of
+tebibyte: @math{2^{40} = 1,099,511,627,776}.
+@item PB
+@cindex petabyte, definition of
+petabyte: @math{10^{15} = 1,000,000,000,000,000}.
+@item P
+@itemx PiB
+@cindex pebibyte, definition of
+pebibyte: @math{2^{50} = 1,125,899,906,842,624}.
+@item EB
+@cindex exabyte, definition of
+exabyte: @math{10^{18} = 1,000,000,000,000,000,000}.
+@item E
+@itemx EiB
+@cindex exbibyte, definition of
+exbibyte: @math{2^{60} = 1,152,921,504,606,846,976}.
+@item ZB
+@cindex zettabyte, definition of
+zettabyte: @math{10^{21} = 1,000,000,000,000,000,000,000}
+@item Z
+@itemx ZiB
+@math{2^{70} = 1,180,591,620,717,411,303,424}.
+@item YB
+@cindex yottabyte, definition of
+yottabyte: @math{10^{24} = 1,000,000,000,000,000,000,000,000}.
+@item Y
+@itemx YiB
+@math{2^{80} = 1,208,925,819,614,629,174,706,176}.
+@end table
+
+@opindex -k
+@opindex -h
+@opindex --block-size
+@opindex --human-readable
+@opindex --si
+
+Block size defaults can be overridden by an explicit
+@option{--block-size=@var{size}} option.  The @option{-k}
+option is equivalent to @option{--block-size=1K}, which
+is the default unless the @env{POSIXLY_CORRECT} environment variable is
+set.  The @option{-h} or @option{--human-readable} option is equivalent to
+@option{--block-size=human-readable}.  The @option{--si} option is
+equivalent to @option{--block-size=si}.  Note for @command{ls}
+the @option{-k} option does not control the display of the
+apparent file sizes, whereas the @option{--block-size} option does.
+
+@node Floating point
+@section Floating point numbers
+@cindex floating point
+@cindex IEEE floating point
+
+Commands that accept or produce floating point numbers employ the
+floating point representation of the underlying system, and suffer
+from rounding error, overflow, and similar floating-point issues.
+Almost all modern systems use IEEE-754 floating point, and it is
+typically portable to assume IEEE-754 behavior these days.  IEEE-754
+has positive and negative infinity, distinguishes positive from
+negative zero, and uses special values called NaNs to represent
+invalid computations such as dividing zero by itself.  For more
+information, please see David Goldberg's paper
+@uref{https://@/docs.oracle.com/@/cd/@/E19957-01/@/806-3568/@/ncg_goldberg.html,
+What Every Computer Scientist Should Know About Floating-Point Arithmetic}.
+
+Commands that accept floating point numbers as options, operands or
+input use the standard C functions @code{strtod} and @code{strtold} to
+convert from text to floating point numbers.  These floating point
+numbers therefore can use scientific notation like @code{1.0e-34} and
+@code{-10e100}.  Commands that parse floating point also understand
+case-insensitive @code{inf}, @code{infinity}, and @code{NaN}, although
+whether such values are useful depends on the command in question.
+Modern C implementations also accept hexadecimal floating point
+numbers such as @code{-0x.ep-3}, which stands for @minus{}14/16 times
+@math{2^-3}, which equals @minus{}0.109375.  @xref{Parsing of
+Floats,,, libc, The GNU C Library Reference Manual}.
+
+@vindex LC_NUMERIC
+Normally the @env{LC_NUMERIC} locale determines the decimal-point
+character.  However, some commands' descriptions specify that they
+accept numbers in either the current or the C locale; for example,
+they treat @samp{3.14} like @samp{3,14} if the current locale uses
+comma as a decimal point.
+
+@node Signal specifications
+@section Signal specifications
+@cindex signals, specifying
+
+A @var{signal} may be a signal name like @samp{HUP}, or a signal
+number like @samp{1}, or an exit status of a process terminated by the
+signal.  A signal name can be given in canonical form or prefixed by
+@samp{SIG}@.  The case of the letters is ignored.  The following signal names
+and numbers are supported on all POSIX compliant systems:
+
+@table @samp
+@item HUP
+1.  Hangup.
+@item INT
+2.  Terminal interrupt.
+@item QUIT
+3.  Terminal quit.
+@item ABRT
+6.  Process abort.
+@item KILL
+9.  Kill (cannot be caught or ignored).
+@item ALRM
+14.  Alarm Clock.
+@item TERM
+15.  Termination.
+@end table
+
+@noindent
+Other supported signal names have system-dependent corresponding
+numbers.  All systems conforming to POSIX 1003.1-2001 also
+support the following signals:
+
+@table @samp
+@item BUS
+Access to an undefined portion of a memory object.
+@item CHLD
+Child process terminated, stopped, or continued.
+@item CONT
+Continue executing, if stopped.
+@item FPE
+Erroneous arithmetic operation.
+@item ILL
+Illegal Instruction.
+@item PIPE
+Write on a pipe with no one to read it.
+@item SEGV
+Invalid memory reference.
+@item STOP
+Stop executing (cannot be caught or ignored).
+@item TSTP
+Terminal stop.
+@item TTIN
+Background process attempting read.
+@item TTOU
+Background process attempting write.
+@item URG
+High bandwidth data is available at a socket.
+@item USR1
+User-defined signal 1.
+@item USR2
+User-defined signal 2.
+@end table
+
+@noindent
+POSIX 1003.1-2001 systems that support the XSI extension
+also support the following signals:
+
+@table @samp
+@item POLL
+Pollable event.
+@item PROF
+Profiling timer expired.
+@item SYS
+Bad system call.
+@item TRAP
+Trace/breakpoint trap.
+@item VTALRM
+Virtual timer expired.
+@item XCPU
+CPU time limit exceeded.
+@item XFSZ
+File size limit exceeded.
+@end table
+
+@noindent
+POSIX 1003.1-2001 systems that support the XRT extension
+also support at least eight real-time signals called @samp{RTMIN},
+@samp{RTMIN+1}, @dots{}, @samp{RTMAX-1}, @samp{RTMAX}.
+
+@node Disambiguating names and IDs
+@section chown, chgrp, chroot, id: Disambiguating user names and IDs
+@cindex user names, disambiguating
+@cindex user IDs, disambiguating
+@cindex group names, disambiguating
+@cindex group IDs, disambiguating
+@cindex disambiguating group names and IDs
+
+Since the @var{user} and @var{group} arguments to these commands
+may be specified as names or numeric IDs, there is an
+apparent ambiguity.
+What if a user or group @emph{name} is a string of digits?
+@footnote{Using a number as a user name is common in some environments.}
+Should the command interpret it as a user name or as an ID@?
+POSIX requires that these commands
+first attempt to resolve the specified string as a name, and
+only once that fails, then try to interpret it as an ID@.
+This is troublesome when you want to specify a numeric ID, say 42,
+and it must work even in a pathological situation where
+@samp{42} is a user name that maps to some other user ID, say 1000.
+Simply invoking @code{chown 42 F}, will set @file{F}s owner ID to
+1000---not what you intended.
+
+GNU @command{chown}, @command{chgrp}, @command{chroot}, and @command{id}
+provide a way to work around this, that at the same time may result in a
+significant performance improvement by eliminating a database look-up.
+Simply precede each numeric user ID and/or group ID with a @samp{+},
+in order to force its interpretation as an integer:
+
+@example
+chown +42 F
+chgrp +$numeric_group_id another-file
+chown +0:+0 /
+@end example
+
+The name look-up process is skipped for each @samp{+}-prefixed string,
+because a string containing @samp{+} is never a valid user or group name.
+This syntax is accepted on most common Unix systems, but not on Solaris 10.
+
+@node Random sources
+@section Sources of random data
+
+@cindex random sources
+
+The @command{shuf}, @command{shred}, and @command{sort} commands
+sometimes need random data to do their work.  For example, @samp{sort
+-R} must choose a hash function at random, and it needs random data to
+make this selection.
+
+By default these commands use an internal pseudo-random generator
+initialized by a small amount of entropy, but can be directed to use
+an external source with the @option{--random-source=@var{file}} option.
+An error is reported if @var{file} does not contain enough bytes.
+
+For example, the device file @file{/dev/urandom} could be used as the
+source of random data.  Typically, this device gathers environmental
+noise from device drivers and other sources into an entropy pool, and
+uses the pool to generate random bits.  If the pool is short of data,
+the device reuses the internal pool to produce more bits, using a
+cryptographically secure pseudo-random number generator.  But be aware
+that this device is not designed for bulk random data generation
+and is relatively slow.
+
+@file{/dev/urandom} suffices for most practical uses, but applications
+requiring high-value or long-term protection of private data may
+require an alternate data source like @file{/dev/random} or
+@file{/dev/arandom}.  The set of available sources depends on your
+operating system.
+
+To reproduce the results of an earlier invocation of a command, you
+can save some random data into a file and then use that file as the
+random source in earlier and later invocations of the command.
+@cindex random seed
+Rather than depending on a file, one can generate a reproducible
+arbitrary amount of pseudo-random data given a seed value, using
+for example:
+
+@example
+get_seeded_random()
+@{
+  seed="$1"
+  openssl enc -aes-256-ctr -pass pass:"$seed" -nosalt \
+    </dev/zero 2>/dev/null
+@}
+
+shuf -i1-100 --random-source=<(get_seeded_random 42)
+@end example
+
+@node Target directory
+@section Target directory
+
+@cindex target directory
+
+The @command{cp}, @command{install}, @command{ln}, and @command{mv}
+commands normally treat the last operand specially when it is a
+directory or a symbolic link to a directory.  For example, @samp{cp
+source dest} is equivalent to @samp{cp source dest/source} if
+@file{dest} is a directory.  Sometimes this behavior is not exactly
+what is wanted, so these commands support the following options to
+allow more fine-grained control:
+
+@table @samp
+
+@item -T
+@itemx --no-target-directory
+@opindex --no-target-directory
+@cindex target directory
+@cindex destination directory
+Do not treat the last operand specially when it is a directory or a
+symbolic link to a directory.  This can help avoid race conditions in
+programs that operate in a shared area.  For example, when the command
+@samp{mv /tmp/source /tmp/dest} succeeds, there is no guarantee that
+@file{/tmp/source} was renamed to @file{/tmp/dest}: it could have been
+renamed to @file{/tmp/dest/source} instead, if some other process
+created @file{/tmp/dest} as a directory.  However, if @file{mv
+-T /tmp/source /tmp/dest} succeeds, there is no
+question that @file{/tmp/source} was renamed to @file{/tmp/dest}.
+
+In the opposite situation, where you want the last operand to be
+treated as a directory and want a diagnostic otherwise, you can use
+the @option{--target-directory} (@option{-t}) option.
+
+@item -t @var{directory}
+@itemx --target-directory=@var{directory}
+@opindex --target-directory
+@cindex target directory
+@cindex destination directory
+Use @var{directory} as the directory component of each destination
+file name.
+
+The interface for most programs is that after processing options and a
+finite (possibly zero) number of fixed-position arguments, the remaining
+argument list is either expected to be empty, or is a list of items
+(usually files) that will all be handled identically.  The @command{xargs}
+program is designed to work well with this convention.
+
+The commands in the @command{mv}-family are unusual in that they take
+a variable number of arguments with a special case at the @emph{end}
+(namely, the target directory).  This makes it nontrivial to perform some
+operations, e.g., ``move all files from here to ../d/'', because
+@code{mv * ../d/} might exhaust the argument space, and @code{ls | xargs ...}
+doesn't have a clean way to specify an extra final argument for each
+invocation of the subject command.  (It can be done by going through a
+shell command, but that requires more human labor and brain power than
+it should.)
+
+The @option{--target-directory} (@option{-t}) option allows the @command{cp},
+@command{install}, @command{ln}, and @command{mv} programs to be used
+conveniently with @command{xargs}.  For example, you can move the files
+from the current directory to a sibling directory, @code{d} like this:
+
+@example
+ls | xargs mv -t ../d --
+@end example
+
+However, this doesn't move files whose names begin with @samp{.}.
+If you use the GNU @command{find} program, you can move those
+files too, with this command:
+
+@example
+find . -mindepth 1 -maxdepth 1 \
+  | xargs mv -t ../d
+@end example
+
+But both of the above approaches fail if there are no files in the
+current directory, or if any file has a name containing a blank or
+some other special characters.
+The following example removes those limitations and requires both
+GNU @command{find} and GNU @command{xargs}:
+
+@example
+find . -mindepth 1 -maxdepth 1 -print0 \
+  | xargs --null --no-run-if-empty \
+      mv -t ../d
+@end example
+
+@end table
+
+@noindent
+The @option{--target-directory} (@option{-t}) and
+@option{--no-target-directory} (@option{-T})
+options cannot be combined.
+
+@node Trailing slashes
+@section Trailing slashes
+
+@cindex trailing slashes
+
+Some GNU programs (at least @command{cp} and @command{mv}) allow you to
+remove any trailing slashes from each @var{source} argument before
+operating on it.  The @option{--strip-trailing-slashes} option enables
+this behavior.
+
+This is useful when a @var{source} argument may have a trailing slash and
+@c FIXME: mv's behavior in this case is system-dependent
+specify a symbolic link to a directory.  This scenario is in fact rather
+common because some shells can automatically append a trailing slash when
+performing file name completion on such symbolic links.  Without this
+option, @command{mv}, for example, (via the system's rename function) must
+interpret a trailing slash as a request to dereference the symbolic link
+and so must rename the indirectly referenced @emph{directory} and not
+the symbolic link.  Although it may seem surprising that such behavior
+be the default, it is required by POSIX and is consistent with
+other parts of that standard.
+
+@node Traversing symlinks
+@section Traversing symlinks
+
+@cindex symbolic link to directory, controlling traversal of
+
+The following options modify how @command{chown} and @command{chgrp}
+@c FIXME: note that 'du' has these options, too, but they have slightly
+@c different meaning.
+traverse a hierarchy when the @option{--recursive} (@option{-R})
+option is also specified.
+If more than one of the following options is specified, only the final
+one takes effect.
+These options specify whether processing a symbolic link to a directory
+entails operating on just the symbolic link or on all files in the
+hierarchy rooted at that directory.
+
+These options are independent of @option{--dereference} and
+@option{--no-dereference} (@option{-h}), which control whether to modify
+a symlink or its referent.
+
+@table @samp
+
+@macro choptH
+@item -H
+@opindex -H
+@cindex symbolic link to directory, traverse if on the command line
+If @option{--recursive} (@option{-R}) is specified and
+a command line argument is a symbolic link to a directory, traverse it.
+@end macro
+@choptH
+
+@macro choptL
+@item -L
+@opindex -L
+@cindex symbolic link to directory, traverse each that is encountered
+In a recursive traversal, traverse every symbolic link to a directory
+that is encountered.
+@end macro
+
+@c Append the following warning to -L where appropriate (e.g. chown).
+@macro warnOptDerefWithRec
+
+Combining this dereferencing option with the @option{--recursive} option
+may create a security risk:
+During the traversal of the directory tree, an attacker may be able to
+introduce a symlink to an arbitrary target; when the tool reaches that,
+the operation will be performed on the target of that symlink,
+possibly allowing the attacker to escalate privileges.
+
+@end macro
+
+@choptL
+
+@macro choptP
+@item -P
+@opindex -P
+@cindex symbolic link to directory, never traverse
+Do not traverse any symbolic links.
+This is the default if none of @option{-H}, @option{-L},
+or @option{-P} is specified.
+@end macro
+@choptP
+
+@end table
+
+
+@node Treating / specially
+@section Treating @file{/} specially
+
+Certain commands can operate destructively on entire hierarchies.
+For example, if a user with appropriate privileges mistakenly runs
+@samp{rm -rf / tmp/junk}, that may remove
+all files on the entire system.  Since there are so few
+legitimate uses for such a command,
+GNU @command{rm} normally declines to operate on any directory
+that resolves to @file{/}.  If you really want to try to remove all
+the files on your system, you can use the @option{--no-preserve-root}
+option, but the default behavior, specified by the
+@option{--preserve-root} option, is safer for most purposes.
+
+The commands @command{chgrp}, @command{chmod} and @command{chown}
+can also operate destructively on entire hierarchies, so they too
+support these options.  Although, unlike @command{rm}, they don't
+actually unlink files, these commands are arguably more dangerous
+when operating recursively on @file{/}, since they often work much
+more quickly, and hence damage more files before an alert user can
+interrupt them.  Tradition and POSIX require these commands
+to operate recursively on @file{/}, so they default to
+@option{--no-preserve-root}, but using the @option{--preserve-root}
+option makes them safer for most purposes.  For convenience you can
+specify @option{--preserve-root} in an alias or in a shell function.
+
+Note that the @option{--preserve-root} option also ensures
+that @command{chgrp} and @command{chown} do not modify @file{/}
+even when dereferencing a symlink pointing to @file{/}.
+
+@node Special built-in utilities
+@section Special built-in utilities
+
+Some programs like @command{nice} can invoke other programs; for
+example, the command @samp{nice cat file} invokes the program
+@command{cat} by executing the command @samp{cat file}.  However,
+@dfn{special built-in utilities} like @command{exit} cannot be invoked
+this way.  For example, the command @samp{nice exit} does not have a
+well-defined behavior: it may generate an error message instead of
+exiting.
+
+Here is a list of the special built-in utilities that are standardized
+by POSIX 1003.1-2004.
+
+@quotation
+@t{.@: : break continue eval exec exit export readonly
+return set shift times trap unset}
+@end quotation
+
+For example, because @samp{.}, @samp{:}, and @samp{exec} are special,
+the commands @samp{nice . foo.sh}, @samp{nice :}, and @samp{nice exec
+pwd} do not work as you might expect.
+
+Many shells extend this list.  For example, Bash has several extra
+special built-in utilities like @command{history}, and
+@command{suspend}, and with Bash the command @samp{nice suspend}
+generates an error message instead of suspending.
+
+@node Standards conformance
+@section Standards conformance
+
+@vindex POSIXLY_CORRECT
+In a few cases, the GNU utilities' default behavior is
+incompatible with the POSIX standard.  To suppress these
+incompatibilities, define the @env{POSIXLY_CORRECT} environment
+variable.  Unless you are checking for POSIX conformance, you
+probably do not need to define @env{POSIXLY_CORRECT}.
+
+Newer versions of POSIX are occasionally incompatible with older
+versions.  For example, older versions of POSIX required the
+command @samp{sort +1} to sort based on the second and succeeding
+fields in each input line, but in POSIX 1003.1-2001
+the same command is required to sort the file named @file{+1}, and you
+must instead use the command @samp{sort -k 2} to get the field-based
+sort.  To complicate things further, POSIX 1003.1-2008 allows an
+implementation to have either the old or the new behavior.
+
+@vindex _POSIX2_VERSION
+The GNU utilities normally conform to the version of POSIX
+that is standard for your system.  To cause them to conform to a
+different version of POSIX, define the @env{_POSIX2_VERSION}
+environment variable to a value of the form @var{yyyymm} specifying
+the year and month the standard was adopted.  Three values are currently
+supported for @env{_POSIX2_VERSION}: @samp{199209} stands for
+POSIX 1003.2-1992, @samp{200112} stands for POSIX
+1003.1-2001, and @samp{200809} stands for POSIX 1003.1-2008.
+For example, if you have a POSIX 1003.1-2001 system but are running software
+containing traditional usage like @samp{sort +1} or @samp{tail +10},
+you can work around the compatibility problems by setting
+@samp{_POSIX2_VERSION=200809} in your environment.
+
+@c This node is named "Multi-call invocation", not the usual
+@c "coreutils invocation", so that shell commands like
+@c 'info coreutils "touch invocation"' work as expected.
+@node Multi-call invocation
+@section @command{coreutils}: Multi-call program
+
+@pindex multicall
+@cindex combined
+@cindex calling combined multi-call program
+
+The @command{coreutils} command invokes an individual utility, either
+implicitly selected by the last component of the name used to invoke
+@command{coreutils}, or explicitly with the
+@option{--coreutils-prog} option.  Synopsis:
+
+@example
+coreutils @option{--coreutils-prog=PROGRAM} @dots{}
+@end example
+
+The @command{coreutils} command is not installed by default, so
+portable scripts should not rely on its existence.
+
+@node Output of entire files
+@chapter Output of entire files
+
+@cindex output of entire files
+@cindex entire files, output of
+
+These commands read and write entire files, possibly transforming them
+in some way.
+
+@menu
+* 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.
+* base32 invocation::           Transform data into printable data.
+* base64 invocation::           Transform data into printable data.
+* basenc invocation::           Transform data into printable data.
+@end menu
+
+@node cat invocation
+@section @command{cat}: Concatenate and write files
+
+@pindex cat
+@cindex concatenate and write files
+@cindex copying files
+
+@command{cat} copies each @var{file} (@samp{-} means standard input), or
+standard input if none are given, to standard output.  Synopsis:
+
+@example
+cat [@var{option}] [@var{file}]@dots{}
+@end example
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -A
+@itemx --show-all
+@opindex -A
+@opindex --show-all
+Equivalent to @option{-vET}.
+
+@item -b
+@itemx --number-nonblank
+@opindex -b
+@opindex --number-nonblank
+Number all nonempty output lines, starting with 1.
+
+@item -e
+@opindex -e
+Equivalent to @option{-vE}.
+
+@item -E
+@itemx --show-ends
+@opindex -E
+@opindex --show-ends
+Display a @samp{$} after the end of each line.
+
+@item -n
+@itemx --number
+@opindex -n
+@opindex --number
+Number all output lines, starting with 1.  This option is ignored
+if @option{-b} is in effect.
+
+@item -s
+@itemx --squeeze-blank
+@opindex -s
+@opindex --squeeze-blank
+@cindex squeezing empty lines
+@cindex squeezing blank lines
+Suppress repeated adjacent blank lines; output just one empty line
+instead of several.
+
+@item -t
+@opindex -t
+Equivalent to @option{-vT}.
+
+@item -T
+@itemx --show-tabs
+@opindex -T
+@opindex --show-tabs
+Display TAB characters as @samp{^I}.
+
+@item -u
+@opindex -u
+Ignored; for POSIX compatibility.
+
+@item -v
+@itemx --show-nonprinting
+@opindex -v
+@opindex --show-nonprinting
+Display control characters except for LFD and TAB using
+@samp{^} notation and precede characters that have the high bit set with
+@samp{M-}.
+
+@end table
+
+On systems like MS-DOS that distinguish between text and binary files,
+@command{cat} normally reads and writes in binary mode.  However,
+@command{cat} reads in text mode if one of the options
+@option{-bensAE} is used or if @command{cat} is reading from standard
+input and standard input is a terminal.  Similarly, @command{cat}
+writes in text mode if one of the options @option{-bensAE} is used or
+if standard output is a terminal.
+
+@exitstatus
+
+Examples:
+
+@example
+# Output f's contents, then standard input, then g's contents.
+cat f - g
+
+# Copy standard input to standard output.
+cat
+@end example
+
+
+@node tac invocation
+@section @command{tac}: Concatenate and write files in reverse
+
+@pindex tac
+@cindex reversing files
+
+@command{tac} copies each @var{file} (@samp{-} means standard input), or
+standard input if none are given, to standard output, reversing the
+records (lines by default) in each separately.  Synopsis:
+
+@example
+tac [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+@dfn{Records} are separated by instances of a string (newline by
+default).  By default, this separator string is attached to the end of
+the record that it follows in the file.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -b
+@itemx --before
+@opindex -b
+@opindex --before
+The separator is attached to the beginning of the record that it
+precedes in the file.
+
+@item -r
+@itemx --regex
+@opindex -r
+@opindex --regex
+Treat the separator string as a regular expression.
+
+@item -s @var{separator}
+@itemx --separator=@var{separator}
+@opindex -s
+@opindex --separator
+Use @var{separator} as the record separator, instead of newline.
+Note an empty @var{separator} is treated as a zero byte.
+I.e., input and output items are delimited with ASCII NUL.
+
+@end table
+
+On systems like MS-DOS that distinguish between text and binary files,
+@command{tac} reads and writes in binary mode.
+
+@exitstatus
+
+Example:
+
+@example
+# Reverse a file character by character.
+tac -r -s 'x\|[^x]'
+@end example
+
+
+@node nl invocation
+@section @command{nl}: Number lines and write files
+
+@pindex nl
+@cindex numbering lines
+@cindex line numbering
+
+@command{nl} writes each @var{file} (@samp{-} means standard input), or
+standard input if none are given, to standard output, with line numbers
+added to some or all of the lines.  Synopsis:
+
+@example
+nl [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+@cindex logical pages, numbering on
+@command{nl} decomposes its input into (logical) page sections;
+by default, the line number is reset to 1 at each logical page section.
+@command{nl} treats all of the input files as a single document;
+it does not reset line numbers or logical pages between files.
+
+@cindex headers, numbering
+@cindex body, numbering
+@cindex footers, numbering
+A logical page consists of three sections: header, body, and footer.
+Any of the sections can be empty.  Each can be numbered in a different
+style from the others.
+
+The beginnings of the sections of logical pages are indicated in the
+input file by a line containing exactly one of these delimiter strings:
+
+@table @samp
+@item \:\:\:
+start of header;
+@item \:\:
+start of body;
+@item \:
+start of footer.
+@end table
+
+The two characters from which these strings are made can be changed from
+@samp{\} and @samp{:} via options (see below), but the pattern and
+length of each string cannot be changed.
+
+A section delimiter is replaced by an empty line on output.  Any text
+that comes before the first section delimiter string in the input file
+is considered to be part of a body section, so @command{nl} treats a
+file that contains no section delimiters as a single body section.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -b @var{style}
+@itemx --body-numbering=@var{style}
+@opindex -b
+@opindex --body-numbering
+Select the numbering style for lines in the body section of each
+logical page.  When a line is not numbered, the current line number
+is not incremented, but the line number separator character is still
+prepended to the line.  The styles are:
+
+@table @samp
+@item a
+number all lines,
+@item t
+number only nonempty lines (default for body),
+@item n
+do not number lines (default for header and footer),
+@item p@var{bre}
+number only lines that contain a match for the basic regular
+expression @var{bre}.
+@xref{Regular Expressions, , Regular Expressions, grep, The GNU Grep Manual}.
+@end table
+
+@item -d @var{cd}
+@itemx --section-delimiter=@var{cd}
+@opindex -d
+@opindex --section-delimiter
+@cindex section delimiters of pages
+Set the section delimiter characters to @var{cd}; default is
+@samp{\:}.  If only @var{c} is given, the second remains @samp{:}.
+(Remember to protect @samp{\} or other metacharacters from shell
+expansion with quotes or extra backslashes.)
+
+@item -f @var{style}
+@itemx --footer-numbering=@var{style}
+@opindex -f
+@opindex --footer-numbering
+Analogous to @option{--body-numbering}.
+
+@item -h @var{style}
+@itemx --header-numbering=@var{style}
+@opindex -h
+@opindex --header-numbering
+Analogous to @option{--body-numbering}.
+
+@item -i @var{number}
+@itemx --line-increment=@var{number}
+@opindex -i
+@opindex --line-increment
+Increment line numbers by @var{number} (default 1).
+
+@item -l @var{number}
+@itemx --join-blank-lines=@var{number}
+@opindex -l
+@opindex --join-blank-lines
+@cindex empty lines, numbering
+@cindex blank lines, numbering
+Consider @var{number} (default 1) consecutive empty lines to be one
+logical line for numbering, and only number the last one.  Where fewer
+than @var{number} consecutive empty lines occur, do not number them.
+An empty line is one that contains no characters, not even spaces
+or tabs.
+
+@item -n @var{format}
+@itemx --number-format=@var{format}
+@opindex -n
+@opindex --number-format
+Select the line numbering format (default is @code{rn}):
+
+@table @samp
+@item ln
+@opindex ln @r{format for @command{nl}}
+left justified, no leading zeros;
+@item rn
+@opindex rn @r{format for @command{nl}}
+right justified, no leading zeros;
+@item rz
+@opindex rz @r{format for @command{nl}}
+right justified, leading zeros.
+@end table
+
+@item -p
+@itemx --no-renumber
+@opindex -p
+@opindex --no-renumber
+Do not reset the line number at the start of a logical page.
+
+@item -s @var{string}
+@itemx --number-separator=@var{string}
+@opindex -s
+@opindex --number-separator
+Separate the line number from the text line in the output with
+@var{string} (default is the TAB character).
+
+@item -v @var{number}
+@itemx --starting-line-number=@var{number}
+@opindex -v
+@opindex --starting-line-number
+Set the initial line number on each logical page to @var{number} (default 1).
+
+@item -w @var{number}
+@itemx --number-width=@var{number}
+@opindex -w
+@opindex --number-width
+Use @var{number} characters for line numbers (default 6).
+
+@end table
+
+@exitstatus
+
+
+@node od invocation
+@section @command{od}: Write files in octal or other formats
+
+@pindex od
+@cindex octal dump of files
+@cindex hex dump of files
+@cindex ASCII dump of files
+@cindex file contents, dumping unambiguously
+
+@command{od} writes an unambiguous representation of each @var{file}
+(@samp{-} means standard input), or standard input if none are given.
+Synopses:
+
+@example
+od [@var{option}]@dots{} [@var{file}]@dots{}
+od [-abcdfilosx]@dots{} [@var{file}] [[+]@var{offset}[.][b]]
+od [@var{option}]@dots{} --traditional [@var{file}]@c
+ [[+]@var{offset}[.][b] [[+]@var{label}[.][b]]]
+@end example
+
+Each line of output consists of the offset in the input, followed by
+groups of data from the file.  By default, @command{od} prints the offset in
+octal, and each group of file data is a C @code{short int}'s worth of input
+printed as a single octal number.
+
+If @var{offset} is given, it specifies how many input bytes to skip
+before formatting and writing.  By default, it is interpreted as an
+octal number, but the optional trailing decimal point causes it to be
+interpreted as decimal.  If no decimal is specified and the offset
+begins with @samp{0x} or @samp{0X} it is interpreted as a hexadecimal
+number.  If there is a trailing @samp{b}, the number of bytes skipped
+will be @var{offset} multiplied by 512.
+
+If a command is of both the first and second forms, the second form is
+assumed if the last operand begins with @samp{+} or (if there are two
+operands) a digit.  For example, in @samp{od foo 10} and @samp{od +10}
+the @samp{10} is an offset, whereas in @samp{od 10} the @samp{10} is a
+file name.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -A @var{radix}
+@itemx --address-radix=@var{radix}
+@opindex -A
+@opindex --address-radix
+@cindex radix for file offsets
+@cindex file offset radix
+Select the base in which file offsets are printed.  @var{radix} can
+be one of the following:
+
+@table @samp
+@item d
+decimal;
+@item o
+octal;
+@item x
+hexadecimal;
+@item n
+none (do not print offsets).
+@end table
+
+The default is octal.
+
+@item --endian=@var{order}
+@opindex --endian
+@cindex byte-swapping
+@cindex endianness
+Reorder input bytes, to handle inputs with differing byte orders,
+or to provide consistent output independent of the endian convention
+of the current system.  Swapping is performed according to the
+specified @option{--type} size and endian @var{order}, which can be
+@samp{little} or @samp{big}.
+
+@item -j @var{bytes}
+@itemx --skip-bytes=@var{bytes}
+@opindex -j
+@opindex --skip-bytes
+Skip @var{bytes} input bytes before formatting and writing.  If
+@var{bytes} begins with @samp{0x} or @samp{0X}, it is interpreted in
+hexadecimal; otherwise, if it begins with @samp{0}, in octal; otherwise,
+in decimal.
+@multiplierSuffixes{bytes}
+
+@item -N @var{bytes}
+@itemx --read-bytes=@var{bytes}
+@opindex -N
+@opindex --read-bytes
+Output at most @var{bytes} bytes of the input.  Prefixes and suffixes on
+@code{bytes} are interpreted as for the @option{-j} option.
+
+@item -S @var{bytes}
+@itemx --strings[=@var{bytes}]
+@opindex -S
+@opindex --strings
+@cindex string constants, outputting
+Instead of the normal output, output only @dfn{string constants}: at
+least @var{bytes} consecutive ASCII graphic characters,
+followed by a zero byte (ASCII NUL).
+Prefixes and suffixes on @var{bytes} are interpreted as for the
+@option{-j} option.
+
+If @var{bytes} is omitted with @option{--strings}, the default is 3.
+
+@item -t @var{type}
+@itemx --format=@var{type}
+@opindex -t
+@opindex --format
+Select the format in which to output the file data.  @var{type} is a
+string of one or more of the below type indicator characters.  If you
+include more than one type indicator character in a single @var{type}
+string, or use this option more than once, @command{od} writes one copy
+of each output line using each of the data types that you specified,
+in the order that you specified.
+
+Adding a trailing ``z'' to any type specification appends a display
+of the single byte character representation of the printable characters
+to the output line generated by the type specification.
+
+@table @samp
+@item a
+named character, ignoring high-order bit
+@item c
+printable single byte character, C backslash escape
+or a 3 digit octal sequence
+@item d
+signed decimal
+@item f
+floating point (@pxref{Floating point})
+@item o
+octal
+@item u
+unsigned decimal
+@item x
+hexadecimal
+@end table
+
+The type @code{a} outputs things like @samp{sp} for space, @samp{nl} for
+newline, and @samp{nul} for a zero byte.  Only the least significant
+seven bits of each byte is used; the high-order bit is ignored.
+Type @code{c} outputs
+@samp{ }, @samp{\n}, and @code{\0}, respectively.
+
+@cindex type size
+Except for types @samp{a} and @samp{c}, you can specify the number
+of bytes to use in interpreting each number in the given data type
+by following the type indicator character with a decimal integer.
+Alternately, you can specify the size of one of the C compiler's
+built-in data types by following the type indicator character with
+one of the following characters.  For integers (@samp{d}, @samp{o},
+@samp{u}, @samp{x}):
+
+@table @samp
+@item C
+char
+@item S
+short
+@item I
+int
+@item L
+long
+@end table
+
+For floating point (@code{f}):
+
+@table @asis
+@item F
+float
+@item D
+double
+@item L
+long double
+@end table
+
+@item -v
+@itemx --output-duplicates
+@opindex -v
+@opindex --output-duplicates
+Output consecutive lines that are identical.  By default, when two or
+more consecutive output lines would be identical, @command{od} outputs only
+the first line, and puts just an asterisk on the following line to
+indicate the elision.
+
+@item -w[@var{n}]
+@itemx --width[=@var{n}]
+@opindex -w
+@opindex --width
+Dump @code{n} input bytes per output line.  This must be a multiple of
+the least common multiple of the sizes associated with the specified
+output types.
+
+If this option is not given at all, the default is 16.  If @var{n} is
+omitted, the default is 32.
+
+@end table
+
+The next several options are shorthands for format specifications.
+GNU @command{od} accepts any combination of shorthands and format
+specification options.  These options accumulate.
+
+@table @samp
+
+@item -a
+@opindex -a
+Output as named characters.  Equivalent to @samp{-t a}.
+
+@item -b
+@opindex -b
+Output as octal bytes.  Equivalent to @samp{-t o1}.
+
+@item -c
+@opindex -c
+Output as printable single byte characters, C backslash escapes
+or 3 digit octal sequences.  Equivalent to @samp{-t c}.
+
+@item -d
+@opindex -d
+Output as unsigned decimal two-byte units.  Equivalent to @samp{-t u2}.
+
+@item -f
+@opindex -f
+Output as floats.  Equivalent to @samp{-t fF}.
+
+@item -i
+@opindex -i
+Output as decimal ints.  Equivalent to @samp{-t dI}.
+
+@item -l
+@opindex -l
+Output as decimal long ints.  Equivalent to @samp{-t dL}.
+
+@item -o
+@opindex -o
+Output as octal two-byte units.  Equivalent to @option{-t o2}.
+
+@item -s
+@opindex -s
+Output as decimal two-byte units.  Equivalent to @option{-t d2}.
+
+@item -x
+@opindex -x
+Output as hexadecimal two-byte units.  Equivalent to @samp{-t x2}.
+
+@item --traditional
+@opindex --traditional
+Recognize the non-option label argument that traditional @command{od}
+accepted.  The following syntax:
+
+@example
+od --traditional [@var{file}] [[+]@var{offset}[.][b] [[+]@var{label}[.][b]]]
+@end example
+
+@noindent
+can be used to specify at most one file and optional arguments
+specifying an offset and a pseudo-start address, @var{label}.
+The @var{label} argument is interpreted
+just like @var{offset}, but it specifies an initial pseudo-address.  The
+pseudo-addresses are displayed in parentheses following any normal
+address.
+
+@end table
+
+@exitstatus
+
+
+@node base32 invocation
+@section @command{base32}: Transform data into printable data
+
+@pindex base32
+@cindex base32 encoding
+
+@command{base32} transforms data read from a file, or standard input,
+into (or from) base32 encoded form.  The base32 encoded form uses
+printable ASCII characters to represent binary data.
+The usage and options of this command are precisely the
+same as for @command{base64}.  @xref{base64 invocation}.
+
+
+@node base64 invocation
+@section @command{base64}: Transform data into printable data
+
+@pindex base64
+@cindex base64 encoding
+
+@command{base64} transforms data read from a file, or standard input,
+into (or from) base64 encoded form.  The base64 encoded form uses
+printable ASCII characters to represent binary data.
+Synopses:
+
+@example
+base64 [@var{option}]@dots{} [@var{file}]
+base64 --decode [@var{option}]@dots{} [@var{file}]
+@end example
+
+The base64 encoding expands data to roughly 133% of the original.
+The base32 encoding expands data to roughly 160% of the original.
+The format conforms to
+@uref{https://tools.ietf.org/search/rfc4648, RFC 4648}.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -w @var{cols}
+@itemx --wrap=@var{cols}
+@opindex -w
+@opindex --wrap
+@cindex wrap data
+@cindex column to wrap data after
+During encoding, wrap lines after @var{cols} characters.  This must be
+a positive number.
+
+The default is to wrap after 76 characters.  Use the value 0 to
+disable line wrapping altogether.
+
+@item -d
+@itemx --decode
+@opindex -d
+@opindex --decode
+@cindex Decode base64 data
+@cindex Base64 decoding
+Change the mode of operation, from the default of encoding data, to
+decoding data.  Input is expected to be base64 encoded data, and the
+output will be the original data.
+
+@item -i
+@itemx --ignore-garbage
+@opindex -i
+@opindex --ignore-garbage
+@cindex Ignore garbage in base64 stream
+When decoding, newlines are always accepted.
+During decoding, ignore unrecognized bytes,
+to permit distorted data to be decoded.
+
+@end table
+
+@exitstatus
+
+@node basenc invocation
+@section @command{basenc}: Transform data into printable data
+
+@pindex basenc
+@cindex base32 encoding
+
+@command{basenc} transforms data read from a file, or standard input,
+into (or from) various common encoding forms.  The encoded form uses
+printable ASCII characters to represent binary data.
+
+Synopses:
+
+@example
+basenc @var{encoding} [@var{option}]@dots{} [@var{file}]
+basenc @var{encoding} --decode [@var{option}]@dots{} [@var{file}]
+@end example
+
+The @var{encoding} argument is required. If @var{file} is omitted,
+reads input from stdin. The @option{-w/--wrap},@option{-i/--ignore-garbage},
+@option{-d/--decode} options of this command are precisely the same as
+for @command{base64}. @xref{base64 invocation}.
+
+
+Supported @var{encoding}s are:
+
+@table @samp
+
+@item --base64
+@opindex --base64
+Encode into (or decode from with @option{-d/--decode}) base64 form.
+The format conforms to
+@uref{https://tools.ietf.org/search/rfc4648#section-4, RFC 4648#4}.
+Equivalent to the @command{base64} command.
+
+@item --base64url
+@opindex --base64url
+Encode into (or decode from with @option{-d/--decode}) file-and-url-safe
+base64 form (using @samp{_} and @samp{-} instead of @samp{+} and @samp{/}).
+The format conforms to
+@uref{https://tools.ietf.org/search/rfc4648#section-5, RFC 4648#5}.
+
+@item --base32
+@opindex --base32
+Encode into (or decode from with @option{-d/--decode}) base32 form.
+The encoded data uses the @samp{ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=} characters.
+The format conforms to
+@uref{https://tools.ietf.org/search/rfc4648#section-6, RFC 4648#6}.
+Equivalent to the @command{base32} command.
+
+@item --base32hex
+@opindex --base32hex
+Encode into (or decode from with @option{-d/--decode}) Extended Hex Alphabet
+base32 form. The encoded data uses the
+@samp{0123456789ABCDEFGHIJKLMNOPQRSTUV=} characters. The format conforms to
+@uref{https://tools.ietf.org/search/rfc4648#section-7, RFC 4648#7}.
+
+@item --base16
+@opindex --base16
+Encode into (or decode from with @option{-d/--decode}) base16 (hexadecimal)
+form. The encoded data uses the @samp{0123456789ABCDEF} characters. The format
+conforms to
+@uref{https://tools.ietf.org/search/rfc4648#section-8, RFC 4648#8}.
+
+@item --base2lsbf
+@opindex --base2lsbf
+Encode into (or decode from with @option{-d/--decode}) binary string form
+(@samp{0} and @samp{1}) with the @emph{least} significant bit of every byte
+first.
+
+@item --base2msbf
+@opindex --base2msbf
+Encode into (or decode from with @option{-d/--decode}) binary string form
+(@samp{0} and @samp{1}) with the @emph{most} significant bit of every byte
+first.
+
+@item --z85
+@opindex --z85
+Encode into (or decode from with @option{-d/--decode}) Z85 form
+(a modified Ascii85 form). The encoded data uses the
+@samp{0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU@
+VWXYZ.-:+=^!/*?&<>()[]@{@}@@%$#}.
+characters. The format conforms to
+@uref{https://rfc.zeromq.org/spec:32/Z85/, ZeroMQ spec:32/Z85}.
+
+When encoding with @option{--z85}, input length must be a multiple of 4;
+when decoding with @option{--z85}, input length must be a multiple of 5.
+
+@end table
+
+
+
+Encoding/decoding examples:
+
+@example
+$ printf '\376\117\202' | basenc --base64
+/k+C
+
+$ printf '\376\117\202' | basenc --base64url
+_k-C
+
+$ printf '\376\117\202' | basenc --base32
+7ZHYE===
+
+$ printf '\376\117\202' | basenc --base32hex
+VP7O4===
+
+$ printf '\376\117\202' | basenc --base16
+FE4F82
+
+$ printf '\376\117\202' | basenc --base2lsbf
+011111111111001001000001
+
+$ printf '\376\117\202' | basenc --base2msbf
+111111100100111110000010
+
+$ printf '\376\117\202\000' | basenc --z85
+@@.FaC
+
+$ printf 01010100 | basenc --base2msbf --decode
+T
+
+$ printf 01010100 | basenc --base2lsbf --decode
+*
+@end example
+
+
+
+@node Formatting file contents
+@chapter Formatting file contents
+
+@cindex formatting file contents
+
+These commands reformat the contents of files.
+
+@menu
+* fmt invocation::              Reformat paragraph text.
+* pr invocation::               Paginate or columnate files for printing.
+* fold invocation::             Wrap input lines to fit in specified width.
+@end menu
+
+
+@node fmt invocation
+@section @command{fmt}: Reformat paragraph text
+
+@pindex fmt
+@cindex reformatting paragraph text
+@cindex paragraphs, reformatting
+@cindex text, reformatting
+
+@command{fmt} fills and joins lines to produce output lines of (at most)
+a given number of characters (75 by default).  Synopsis:
+
+@example
+fmt [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+@command{fmt} reads from the specified @var{file} arguments (or standard
+input if none are given), and writes to standard output.
+
+By default, blank lines, spaces between words, and indentation are
+preserved in the output; successive input lines with different
+indentation are not joined; tabs are expanded on input and introduced on
+output.
+
+@cindex line-breaking
+@cindex sentences and line-breaking
+@cindex Knuth, Donald E.
+@cindex Plass, Michael F.
+@command{fmt} prefers breaking lines at the end of a sentence, and tries to
+avoid line breaks after the first word of a sentence or before the last
+word of a sentence.  A @dfn{sentence break} is defined as either the end
+of a paragraph or a word ending in any of @samp{.?!}, followed by two
+spaces or end of line, ignoring any intervening parentheses or quotes.
+Like @TeX{}, @command{fmt} reads entire ``paragraphs'' before choosing line
+breaks; the algorithm is a variant of that given by Donald E. Knuth
+and Michael F. Plass in ``Breaking Paragraphs Into Lines'',
+@cite{Software---Practice & Experience} @b{11}, 11 (November 1981),
+1119--1184.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -c
+@itemx --crown-margin
+@opindex -c
+@opindex --crown-margin
+@cindex crown margin
+@dfn{Crown margin} mode: preserve the indentation of the first two
+lines within a paragraph, and align the left margin of each subsequent
+line with that of the second line.
+
+@item -t
+@itemx --tagged-paragraph
+@opindex -t
+@opindex --tagged-paragraph
+@cindex tagged paragraphs
+@dfn{Tagged paragraph} mode: like crown margin mode, except that if
+indentation of the first line of a paragraph is the same as the
+indentation of the second, the first line is treated as a one-line
+paragraph.
+
+@item -s
+@itemx --split-only
+@opindex -s
+@opindex --split-only
+Split lines only.  Do not join short lines to form longer ones.  This
+prevents sample lines of code, and other such ``formatted'' text from
+being unduly combined.
+
+@item -u
+@itemx --uniform-spacing
+@opindex -u
+@opindex --uniform-spacing
+Uniform spacing.  Reduce spacing between words to one space, and spacing
+between sentences to two spaces.
+
+@item -@var{width}
+@itemx -w @var{width}
+@itemx --width=@var{width}
+@opindex -@var{width}
+@opindex -w
+@opindex --width
+Fill output lines up to @var{width} characters (default 75 or @var{goal}
+plus 10, if @var{goal} is provided).
+
+@item -g @var{goal}
+@itemx --goal=@var{goal}
+@opindex -g
+@opindex --goal
+@command{fmt} initially tries to make lines @var{goal} characters wide.
+By default, this is 7% shorter than @var{width}.
+
+@item -p @var{prefix}
+@itemx --prefix=@var{prefix}
+Only lines beginning with @var{prefix} (possibly preceded by whitespace)
+are subject to formatting.  The prefix and any preceding whitespace are
+stripped for the formatting and then re-attached to each formatted output
+line.  One use is to format certain kinds of program comments, while
+leaving the code unchanged.
+
+@end table
+
+@exitstatus
+
+@node pr invocation
+@section @command{pr}: Paginate or columnate files for printing
+
+@pindex pr
+@cindex printing, preparing files for
+@cindex multicolumn output, generating
+@cindex merging files in parallel
+
+@command{pr} writes each @var{file} (@samp{-} means standard input), or
+standard input if none are given, to standard output, paginating and
+optionally outputting in multicolumn format; optionally merges all
+@var{file}s, printing all in parallel, one per column.  Synopsis:
+
+@example
+pr [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+@vindex LC_MESSAGES
+By default, a 5-line header is printed at each page: two blank lines;
+a line with the date, the file name, and the page count; and two more
+blank lines.  A footer of five blank lines is also printed.
+The default @var{page_length} is 66
+lines.  The default number of text lines is therefore 56.
+The text line of the header takes the form
+@samp{@var{date} @var{string} @var{page}}, with spaces inserted around
+@var{string} so that the line takes up the full @var{page_width}.  Here,
+@var{date} is the date (see the @option{-D} or @option{--date-format}
+option for details), @var{string} is the centered header string, and
+@var{page} identifies the page number.  The @env{LC_MESSAGES} locale
+category affects the spelling of @var{page}; in the default C locale, it
+is @samp{Page @var{number}} where @var{number} is the decimal page
+number.
+
+Form feeds in the input cause page breaks in the output.  Multiple form
+feeds produce empty pages.
+
+Columns are of equal width, separated by an optional string (default
+is @samp{space}).  For multicolumn output, lines will always be truncated to
+@var{page_width} (default 72), unless you use the @option{-J} option.
+For single
+column output no line truncation occurs by default.  Use @option{-W} option to
+truncate lines in that case.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item +@var{first_page}[:@var{last_page}]
+@itemx --pages=@var{first_page}[:@var{last_page}]
+@c The two following @opindex lines evoke warnings because they contain ':'
+@c The 'info' spec does not permit that.  If we use those lines, we end
+@c up with truncated index entries that don't work.
+@c @opindex +@var{first_page}[:@var{last_page}]
+@c @opindex --pages=@var{first_page}[:@var{last_page}]
+@opindex +@var{page_range}
+@opindex --pages=@var{page_range}
+Begin printing with page @var{first_page} and stop with @var{last_page}.
+Missing @samp{:@var{last_page}} implies end of file.  While estimating
+the number of skipped pages each form feed in the input file results
+in a new page.  Page counting with and without @samp{+@var{first_page}}
+is identical.  By default, counting starts with the first page of input
+file (not first page printed).  Line numbering may be altered by @option{-N}
+option.
+
+@item -@var{column}
+@itemx --columns=@var{column}
+@opindex -@var{column}
+@opindex --columns
+@cindex down columns
+With each single @var{file}, produce @var{column} columns of output
+(default is 1) and print columns down, unless @option{-a} is used.  The
+column width is automatically decreased as @var{column} increases; unless
+you use the @option{-W/-w} option to increase @var{page_width} as well.
+This option might well cause some lines to be truncated.  The number of
+lines in the columns on each page are balanced.  The options @option{-e}
+and @option{-i} are on for multiple text-column output.  Together with
+@option{-J} option column alignment and line truncation is turned off.
+Lines of full length are joined in a free field format and @option{-S}
+option may set field separators.  @option{-@var{column}} may not be used
+with @option{-m} option.
+
+@item -a
+@itemx --across
+@opindex -a
+@opindex --across
+@cindex across columns
+With each single @var{file}, print columns across rather than down.  The
+@option{-@var{column}} option must be given with @var{column} greater than one.
+If a line is too long to fit in a column, it is truncated.
+
+@item -c
+@itemx --show-control-chars
+@opindex -c
+@opindex --show-control-chars
+Print control characters using hat notation (e.g., @samp{^G}); print
+other nonprinting characters in octal backslash notation.  By default,
+nonprinting characters are not changed.
+
+@item -d
+@itemx --double-space
+@opindex -d
+@opindex --double-space
+@cindex double spacing
+Double space the output.
+
+@item -D @var{format}
+@itemx --date-format=@var{format}
+@cindex time formats
+@cindex formatting times
+Format header dates using @var{format}, using the same conventions as
+for the command @samp{date +@var{format}}.  @xref{date invocation}.
+Except for directives, which start with
+@samp{%}, characters in @var{format} are printed unchanged.  You can use
+this option to specify an arbitrary string in place of the header date,
+e.g., @option{--date-format="Monday morning"}.
+
+@vindex POSIXLY_CORRECT
+@vindex LC_TIME
+The default date format is @samp{%Y-%m-%d %H:%M} (for example,
+@samp{2001-12-04 23:59});
+but if the @env{POSIXLY_CORRECT} environment variable is set
+and the @env{LC_TIME} locale category specifies the POSIX
+locale, the default is @samp{%b %e %H:%M %Y} (for example,
+@samp{Dec@ @ 4 23:59 2001}.
+
+@vindex TZ
+Timestamps are listed according to the time zone rules specified by
+the @env{TZ} environment variable, or by the system default rules if
+@env{TZ} is not set.  @xref{TZ Variable,, Specifying the Time Zone
+with @env{TZ}, libc, The GNU C Library Reference Manual}.
+
+@item -e[@var{in-tabchar}[@var{in-tabwidth}]]
+@itemx --expand-tabs[=@var{in-tabchar}[@var{in-tabwidth}]]
+@opindex -e
+@opindex --expand-tabs
+@cindex input tabs
+Expand @var{tab}s to spaces on input.  Optional argument @var{in-tabchar} is
+the input tab character (default is the TAB character).  Second optional
+argument @var{in-tabwidth} is the input tab character's width (default
+is 8).
+
+@item -f
+@itemx -F
+@itemx --form-feed
+@opindex -F
+@opindex -f
+@opindex --form-feed
+Use a form feed instead of newlines to separate output pages.  This does
+not alter the default page length of 66 lines.
+
+@item -h @var{header}
+@itemx --header=@var{header}
+@opindex -h
+@opindex --header
+Replace the file name in the header with the centered string @var{header}.
+When using the shell, @var{header} should be quoted and should be
+separated from @option{-h} by a space.
+
+@item -i[@var{out-tabchar}[@var{out-tabwidth}]]
+@itemx --output-tabs[=@var{out-tabchar}[@var{out-tabwidth}]]
+@opindex -i
+@opindex --output-tabs
+@cindex output tabs
+Replace spaces with @var{tab}s on output.  Optional argument @var{out-tabchar}
+is the output tab character (default is the TAB character).  Second optional
+argument @var{out-tabwidth} is the output tab character's width (default
+is 8).
+
+@item -J
+@itemx --join-lines
+@opindex -J
+@opindex --join-lines
+Merge lines of full length.  Used together with the column options
+@option{-@var{column}}, @option{-a -@var{column}} or @option{-m}.  Turns off
+@option{-W/-w} line truncation;
+no column alignment used; may be used with
+@option{--sep-string[=@var{string}]}.  @option{-J} has been introduced
+(together with @option{-W} and @option{--sep-string})
+to disentangle the old (POSIX-compliant) options @option{-w} and
+@option{-s} along with the three column options.
+
+
+@item -l @var{page_length}
+@itemx --length=@var{page_length}
+@opindex -l
+@opindex --length
+Set the page length to @var{page_length} (default 66) lines, including
+the lines of the header [and the footer].  If @var{page_length} is less
+than or equal to 10, the header and footer are omitted, as if the
+@option{-t} option had been given.
+
+@item -m
+@itemx --merge
+@opindex -m
+@opindex --merge
+Merge and print all @var{file}s in parallel, one in each column.  If a
+line is too long to fit in a column, it is truncated, unless the @option{-J}
+option is used.  @option{--sep-string[=@var{string}]} may be used.
+Empty pages in
+some @var{file}s (form feeds set) produce empty columns, still marked
+by @var{string}.  The result is a continuous line numbering and column
+marking throughout the whole merged file.  Completely empty merged pages
+show no separators or line numbers.  The default header becomes
+@samp{@var{date} @var{page}} with spaces inserted in the middle; this
+may be used with the @option{-h} or @option{--header} option to fill up
+the middle blank part.
+
+@item -n[@var{number-separator}[@var{digits}]]
+@itemx --number-lines[=@var{number-separator}[@var{digits}]]
+@opindex -n
+@opindex --number-lines
+Provide @var{digits} digit line numbering (default for @var{digits} is
+5).  With multicolumn output the number occupies the first @var{digits}
+column positions of each text column or only each line of @option{-m}
+output.  With single column output the number precedes each line just as
+@option{-m} does.  Default counting of the line numbers starts with the
+first line of the input file (not the first line printed, compare the
+@option{--page} option and @option{-N} option).
+Optional argument @var{number-separator} is the character appended to
+the line number to separate it from the text followed.  The default
+separator is the TAB character.  In a strict sense a TAB is always
+printed with single column output only.  The TAB width varies
+with the TAB position, e.g., with the left @var{margin} specified
+by @option{-o} option.  With multicolumn output priority is given to
+@samp{equal width of output columns} (a POSIX specification).
+The TAB width is fixed to the value of the first column and does
+not change with different values of left @var{margin}.  That means a
+fixed number of spaces is always printed in the place of the
+@var{number-separator} TAB@.  The tabification depends upon the output
+position.
+
+@item -N @var{line_number}
+@itemx --first-line-number=@var{line_number}
+@opindex -N
+@opindex --first-line-number
+Start line counting with the number @var{line_number} at first line of
+first page printed (in most cases not the first line of the input file).
+
+@item -o @var{margin}
+@itemx --indent=@var{margin}
+@opindex -o
+@opindex --indent
+@cindex indenting lines
+@cindex left margin
+Indent each line with a margin @var{margin} spaces wide (default is zero).
+The total page width is the size of the margin plus the @var{page_width}
+set with the @option{-W/-w} option.  A limited overflow may occur with
+numbered single column output (compare @option{-n} option).
+
+@item -r
+@itemx --no-file-warnings
+@opindex -r
+@opindex --no-file-warnings
+Do not print a warning message when an argument @var{file} cannot be
+opened.  (The exit status will still be nonzero, however.)
+
+@item -s[@var{char}]
+@itemx --separator[=@var{char}]
+@opindex -s
+@opindex --separator
+Separate columns by a single character @var{char}.  The default for
+@var{char} is the TAB character without @option{-w} and @samp{no
+character} with @option{-w}.  Without @option{-s} the default separator
+@samp{space} is set.  @option{-s[char]} turns off line truncation of all
+three column options (@option{-COLUMN}|@option{-a -COLUMN}|@option{-m}) unless
+@option{-w} is set.  This is a POSIX-compliant formulation.
+
+
+@item -S[@var{string}]
+@itemx --sep-string[=@var{string}]
+@opindex -S
+@opindex --sep-string
+Use @var{string} to separate output columns.  The @option{-S} option doesn't
+affect the @option{-W/-w} option, unlike the @option{-s} option which does.  It
+does not affect line truncation or column alignment.
+Without @option{-S}, and with @option{-J}, @command{pr} uses the default output
+separator, TAB@.
+Without @option{-S} or @option{-J}, @command{pr} uses a @samp{space}
+(same as @option{-S"@w{ }"}).
+If no @samp{@var{string}} argument is specified, @samp{""} is assumed.
+
+@item -t
+@itemx --omit-header
+@opindex -t
+@opindex --omit-header
+Do not print the usual header [and footer] on each page, and do not fill
+out the bottom of pages (with blank lines or a form feed).  No page
+structure is produced, but form feeds set in the input files are retained.
+The predefined pagination is not changed.  @option{-t} or @option{-T} may be
+useful together with other options; e.g.: @option{-t -e4}, expand TAB characters
+in the input file to 4 spaces but don't make any other changes.  Use of
+@option{-t} overrides @option{-h}.
+
+@item -T
+@itemx --omit-pagination
+@opindex -T
+@opindex --omit-pagination
+Do not print header [and footer].  In addition eliminate all form feeds
+set in the input files.
+
+@item -v
+@itemx --show-nonprinting
+@opindex -v
+@opindex --show-nonprinting
+Print nonprinting characters in octal backslash notation.
+
+@item -w @var{page_width}
+@itemx --width=@var{page_width}
+@opindex -w
+@opindex --width
+Set page width to @var{page_width} characters for multiple text-column
+output only (default for @var{page_width} is 72).  The specified
+@var{page_width} is rounded down so that columns have equal width.
+@option{-s[CHAR]} turns off the default page width and any line truncation
+and column alignment.
+Lines of full length are merged, regardless of the column options
+set.  No @var{page_width} setting is possible with single column output.
+A POSIX-compliant formulation.
+
+@item -W @var{page_width}
+@itemx --page_width=@var{page_width}
+@opindex -W
+@opindex --page_width
+Set the page width to @var{page_width} characters, honored with and
+without a column option.  With a column option, the specified @var{page_width}
+is rounded down so that columns have equal width.  Text lines are truncated,
+unless @option{-J} is used. Together with one of the three column options
+(@option{-@var{column}}, @option{-a -@var{column}} or @option{-m}) column
+alignment is always used.  The separator options @option{-S} or @option{-s}
+don't disable the @option{-W} option.  Default is 72 characters.  Without
+@option{-W @var{page_width}} and without any of the column options NO line
+truncation is used (defined to keep downward compatibility and to meet
+most frequent tasks).  That's equivalent to @option{-W 72 -J}@.  The header
+line is never truncated.
+
+@end table
+
+@exitstatus
+
+
+@node fold invocation
+@section @command{fold}: Wrap input lines to fit in specified width
+
+@pindex fold
+@cindex wrapping long input lines
+@cindex folding long input lines
+
+@command{fold} writes each @var{file} (@option{-} means standard input), or
+standard input if none are given, to standard output, breaking long
+lines.  Synopsis:
+
+@example
+fold [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+By default, @command{fold} breaks lines wider than 80 columns.  The output
+is split into as many lines as necessary.
+
+@cindex screen columns
+@command{fold} counts screen columns by default; thus, a tab may count more
+than one column, backspace decreases the column count, and carriage
+return sets the column to zero.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -b
+@itemx --bytes
+@opindex -b
+@opindex --bytes
+Count bytes rather than columns, so that tabs, backspaces, and carriage
+returns are each counted as taking up one column, just like other
+characters.
+
+@item -s
+@itemx --spaces
+@opindex -s
+@opindex --spaces
+Break at word boundaries: the line is broken after the last blank before
+the maximum line length.  If the line contains no such blanks, the line
+is broken at the maximum line length as usual.
+
+@item -w @var{width}
+@itemx --width=@var{width}
+@opindex -w
+@opindex --width
+Use a maximum line length of @var{width} columns instead of 80.
+
+For compatibility @command{fold} supports an obsolete option syntax
+@option{-@var{width}}.  New scripts should use @option{-w @var{width}}
+instead.
+
+@end table
+
+@exitstatus
+
+
+@node Output of parts of files
+@chapter Output of parts of files
+
+@cindex output of parts of files
+@cindex parts of files, output of
+
+These commands output pieces of the input.
+
+@menu
+* head invocation::             Output the first part of files.
+* tail invocation::             Output the last part of files.
+* split invocation::            Split a file into pieces.
+* csplit invocation::           Split a file into context-determined pieces.
+@end menu
+
+@node head invocation
+@section @command{head}: Output the first part of files
+
+@pindex head
+@cindex initial part of files, outputting
+@cindex first part of files, outputting
+
+@command{head} prints the first part (10 lines by default) of each
+@var{file}; it reads from standard input if no files are given or
+when given a @var{file} of @option{-}.  Synopsis:
+
+@example
+head [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+If more than one @var{file} is specified, @command{head} prints a
+one-line header consisting of:
+
+@example
+==> @var{file name} <==
+@end example
+
+@noindent
+before the output for each @var{file}.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -c [-]@var{num}
+@itemx --bytes=[-]@var{num}
+@opindex -c
+@opindex --bytes
+Print the first @var{num} bytes, instead of initial lines.
+However, if @var{num} is prefixed with a @samp{-},
+print all but the last @var{num} bytes of each file.
+@multiplierSuffixes{num}
+
+@item -n [-]@var{num}
+@itemx --lines=[-]@var{num}
+@opindex -n
+@opindex --lines
+Output the first @var{num} lines.
+However, if @var{num} is prefixed with a @samp{-},
+print all but the last @var{num} lines of each file.
+Size multiplier suffixes are the same as with the @option{-c} option.
+
+@item -q
+@itemx --quiet
+@itemx --silent
+@opindex -q
+@opindex --quiet
+@opindex --silent
+Never print file name headers.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Always print file name headers.
+
+@optZeroTerminated
+
+@end table
+
+For compatibility @command{head} also supports an obsolete option syntax
+@option{-[@var{num}][bkm][cqv]}, which is recognized only if it is
+specified first.  @var{num} is a decimal number optionally followed
+by a size letter (@samp{b}, @samp{k}, @samp{m}) as in @option{-c}, or
+@samp{l} to mean count by lines, or other option letters (@samp{cqv}).
+Scripts intended for standard hosts should use @option{-c @var{num}}
+or @option{-n @var{num}} instead.  If your script must also run on
+hosts that support only the obsolete syntax, it is usually simpler to
+avoid @command{head}, e.g., by using @samp{sed 5q} instead of
+@samp{head -5}.
+
+@exitstatus
+
+
+@node tail invocation
+@section @command{tail}: Output the last part of files
+
+@pindex tail
+@cindex last part of files, outputting
+
+@command{tail} prints the last part (10 lines by default) of each
+@var{file}; it reads from standard input if no files are given or
+when given a @var{file} of @samp{-}.  Synopsis:
+
+@example
+tail [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+If more than one @var{file} is specified, @command{tail} prints a
+one-line header before the output for each @var{file}, consisting of:
+
+@example
+==> @var{file name} <==
+@end example
+
+For further processing of tail output, it can be useful to convert the
+file headers to line prefixes, which can be done like:
+
+@example
+tail @dots{} |
+awk '
+  /^==> .* <==$/ @{prefix=substr($0,5,length-8)":"; next@}
+  @{print prefix$0@}
+' | @dots{}
+@end example
+
+@cindex BSD @command{tail}
+GNU @command{tail} can output any amount of data (some other versions of
+@command{tail} cannot).  It also has no @option{-r} option (print in
+reverse), since reversing a file is really a different job from printing
+the end of a file; BSD @command{tail} (which is the one with @option{-r}) can
+only reverse files that are at most as large as its buffer, which is
+typically 32 KiB@.  A more reliable and versatile way to reverse files is
+the GNU @command{tac} command.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -c [+]@var{num}
+@itemx --bytes=[+]@var{num}
+@opindex -c
+@opindex --bytes
+Output the last @var{num} bytes, instead of final lines.
+However, if @var{num} is prefixed with a @samp{+}, start printing with
+byte @var{num} from the start of each file, instead of from the end.
+@multiplierSuffixes{num}
+
+@item -f
+@itemx --follow[=@var{how}]
+@opindex -f
+@opindex --follow
+@cindex growing files
+@vindex name @r{follow option}
+@vindex descriptor @r{follow option}
+Loop forever trying to read more characters at the end of the file,
+presumably because the file is growing.
+If more than one file is given, @command{tail} prints a header whenever it
+gets output from a different file, to indicate which file that output is
+from.
+
+There are two ways to specify how you'd like to track files with this option,
+but that difference is noticeable only when a followed file is removed or
+renamed.
+If you'd like to continue to track the end of a growing file even after
+it has been unlinked, use @option{--follow=descriptor}.  This is the default
+behavior, but it is not useful if you're tracking a log file that may be
+rotated (removed or renamed, then reopened).  In that case, use
+@option{--follow=name} to track the named file, perhaps by reopening it
+periodically to see if it has been removed and recreated by some other program.
+Note that the inotify-based implementation handles this case without
+the need for any periodic reopening.
+
+No matter which method you use, if the tracked file is determined to have
+shrunk, @command{tail} prints a message saying the file has been truncated
+and resumes tracking from the start of the file, assuming it has been
+truncated to 0, which is the usual truncation operation for log files.
+
+When a file is removed, @command{tail}'s behavior depends on whether it is
+following the name or the descriptor.  When following by name, tail can
+detect that a file has been removed and gives a message to that effect,
+and if @option{--retry} has been specified it will continue checking
+periodically to see if the file reappears.
+When following a descriptor, tail does not detect that the file has
+been unlinked or renamed and issues no message;  even though the file
+may no longer be accessible via its original name, it may still be
+growing.
+
+The option values @samp{descriptor} and @samp{name} may be specified only
+with the long form of the option, not with @option{-f}.
+
+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.
+
+With kernel inotify support, output is triggered by file changes
+and is generally very prompt.
+Otherwise, @command{tail} sleeps for one second between checks---
+use @option{--sleep-interval=@var{n}} to change that default---which can
+make the output appear slightly less responsive or bursty.
+When using tail without inotify support, you can make it more responsive
+by using a sub-second sleep interval, e.g., via an alias like this:
+
+@example
+alias tail='tail -s.1'
+@end example
+
+@item -F
+@opindex -F
+This option is the same as @option{--follow=name --retry}.  That is, tail
+will attempt to reopen a file when it is removed.  Should this fail, tail
+will keep trying until it becomes accessible again.
+
+@item --max-unchanged-stats=@var{n}
+@opindex --max-unchanged-stats
+When tailing a file by name, if there have been @var{n} (default
+n=@value{DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS}) consecutive
+iterations for which the file has not changed, then
+@code{open}/@code{fstat} the file to determine if that file name is
+still associated with the same device/inode-number pair as before.
+When following a log file that is rotated, this is approximately the
+number of seconds between when tail prints the last pre-rotation lines
+and when it prints the lines that have accumulated in the new log file.
+This option is meaningful only when polling (i.e., without inotify)
+and when following by name.
+
+@item -n [+]@var{num}
+@itemx --lines=[+]@var{}
+@opindex -n
+@opindex --lines
+Output the last @var{num} lines.
+However, if @var{num} is prefixed with a @samp{+}, start printing with
+line @var{num} from the start of each file, instead of from the end.
+Size multiplier suffixes are the same as with the @option{-c} option.
+
+@item --pid=@var{pid}
+@opindex --pid
+When following by name or by descriptor, you may specify the process ID,
+@var{pid}, of the sole writer of all @var{file} arguments.  Then, shortly
+after that process terminates, tail will also terminate.  This will
+work properly only if the writer and the tailing process are running on
+the same machine.  For example, to save the output of a build in a file
+and to watch the file grow, if you invoke @command{make} and @command{tail}
+like this then the tail process will stop when your build completes.
+Without this option, you would have had to kill the @code{tail -f}
+process yourself.
+
+@example
+$ make >& makerr & tail --pid=$! -f makerr
+@end example
+
+If you specify a @var{pid} that is not in use or that does not correspond
+to the process that is writing to the tailed files, then @command{tail}
+may terminate long before any @var{file}s stop growing or it may not
+terminate until long after the real writer has terminated.
+Note that @option{--pid} cannot be supported on some systems; @command{tail}
+will print a warning if this is the case.
+
+@item -q
+@itemx --quiet
+@itemx --silent
+@opindex -q
+@opindex --quiet
+@opindex --silent
+Never print file name headers.
+
+@item --retry
+@opindex --retry
+Indefinitely try to open the specified file.
+This option is useful mainly when following (and otherwise issues a warning).
+
+When following by file descriptor (i.e., with @option{--follow=descriptor}),
+this option only affects the initial open of the file, as after a successful
+open, @command{tail} will start following the file descriptor.
+
+When following by name (i.e., with @option{--follow=name}), @command{tail}
+infinitely retries to re-open the given files until killed.
+
+Without this option, when @command{tail} encounters a file that doesn't
+exist or is otherwise inaccessible, it reports that fact and
+never checks it again.
+
+@item -s @var{number}
+@itemx --sleep-interval=@var{number}
+@opindex -s
+@opindex --sleep-interval
+Change the number of seconds to wait between iterations (the default is 1.0).
+During one iteration, every specified file is checked to see if it has
+changed size.
+When @command{tail} uses inotify, this polling-related option
+is usually ignored.  However, if you also specify @option{--pid=@var{p}},
+@command{tail} checks whether process @var{p} is alive at least
+every @var{number} seconds.
+The @var{number} must be non-negative and can be a floating-point number
+in either the current or the C locale.  @xref{Floating point}.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Always print file name headers.
+
+@optZeroTerminated
+
+@end table
+
+For compatibility @command{tail} also supports an obsolete usage
+@samp{tail -[@var{num}][bcl][f] [@var{file}]}, which is recognized
+only if it does not conflict with the usage described
+above.  This obsolete form uses exactly one option and at most one
+file.  In the option, @var{num} is an optional decimal number optionally
+followed by a size letter (@samp{b}, @samp{c}, @samp{l}) to mean count
+by 512-byte blocks, bytes, or lines, optionally followed by @samp{f}
+which has the same meaning as @option{-f}.
+
+@vindex _POSIX2_VERSION
+On systems not conforming to POSIX 1003.1-2001, the leading @samp{-}
+can be replaced by @samp{+} in the traditional option syntax with the
+same meaning as in counts, and on obsolete systems predating POSIX
+1003.1-2001 traditional usage overrides normal usage when the two
+conflict.  This behavior can be controlled with the
+@env{_POSIX2_VERSION} environment variable (@pxref{Standards
+conformance}).
+
+Scripts intended for use on standard hosts should avoid traditional
+syntax and should use @option{-c @var{num}[b]}, @option{-n
+@var{num}}, and/or @option{-f} instead.  If your script must also
+run on hosts that support only the traditional syntax, you can often
+rewrite it to avoid problematic usages, e.g., by using @samp{sed -n
+'$p'} rather than @samp{tail -1}.  If that's not possible, the script
+can use a test like @samp{if tail -c +1 </dev/null >/dev/null 2>&1;
+then @dots{}} to decide which syntax to use.
+
+Even if your script assumes the standard behavior, you should still
+beware usages whose behaviors differ depending on the POSIX
+version.  For example, avoid @samp{tail - main.c}, since it might be
+interpreted as either @samp{tail main.c} or as @samp{tail -- -
+main.c}; avoid @samp{tail -c 4}, since it might mean either @samp{tail
+-c4} or @samp{tail -c 10 4}; and avoid @samp{tail +4}, since it might
+mean either @samp{tail ./+4} or @samp{tail -n +4}.
+
+@exitstatus
+
+
+@node split invocation
+@section @command{split}: Split a file into pieces.
+
+@pindex split
+@cindex splitting a file into pieces
+@cindex pieces, splitting a file into
+
+@command{split} creates output files containing consecutive or interleaved
+sections of @var{input}  (standard input if none is given or @var{input}
+is @samp{-}).  Synopsis:
+
+@example
+split [@var{option}] [@var{input} [@var{prefix}]]
+@end example
+
+By default, @command{split} puts 1000 lines of @var{input} (or whatever is
+left over for the last section), into each output file.
+
+@cindex output file name prefix
+The output files' names consist of @var{prefix} (@samp{x} by default)
+followed by a group of characters (@samp{aa}, @samp{ab}, @dots{} by
+default), such that concatenating the output files in traditional
+sorted order by file name produces the original input file (except
+@option{-nr/@var{n}}).  By default split will initially create files
+with two generated suffix characters, and will increase this width by two
+when the next most significant position reaches the last character.
+(@samp{yz}, @samp{zaaa}, @samp{zaab}, @dots{}).  In this way an arbitrary
+number of output files are supported, which sort as described above,
+even in the presence of an @option{--additional-suffix} option.
+If the @option{-a} option is specified and the output file names are
+exhausted, @command{split} reports an error without deleting the
+output files that it did create.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -l @var{lines}
+@itemx --lines=@var{lines}
+@opindex -l
+@opindex --lines
+Put @var{lines} lines of @var{input} into each output file.
+If @option{--separator} is specified, then @var{lines} determines
+the number of records.
+
+For compatibility @command{split} also supports an obsolete
+option syntax @option{-@var{lines}}.  New scripts should use
+@option{-l @var{lines}} instead.
+
+@item -b @var{size}
+@itemx --bytes=@var{size}
+@opindex -b
+@opindex --bytes
+Put @var{size} bytes of @var{input} into each output file.
+@multiplierSuffixes{size}
+
+@item -C @var{size}
+@itemx --line-bytes=@var{size}
+@opindex -C
+@opindex --line-bytes
+Put into each output file as many complete lines of @var{input} as
+possible without exceeding @var{size} bytes.  Individual lines or records
+longer than @var{size} bytes are broken into multiple files.
+@var{size} has the same format as for the @option{--bytes} option.
+If @option{--separator} is specified, then @var{lines} determines
+the number of records.
+
+@item --filter=@var{command}
+@opindex --filter
+With this option, rather than simply writing to each output file,
+write through a pipe to the specified shell @var{command} for each output file.
+@var{command} should use the $FILE environment variable, which is set
+to a different output file name for each invocation of the command.
+For example, imagine that you have a 1TiB compressed file
+that, if uncompressed, would be too large to reside on disk,
+yet you must split it into individually-compressed pieces
+of a more manageable size.
+To do that, you might run this command:
+
+@example
+xz -dc BIG.xz | split -b200G --filter='xz > $FILE.xz' - big-
+@end example
+
+Assuming a 10:1 compression ratio, that would create about fifty 20GiB files
+with names @file{big-aa.xz}, @file{big-ab.xz}, @file{big-ac.xz}, etc.
+
+@item -n @var{chunks}
+@itemx --number=@var{chunks}
+@opindex -n
+@opindex --number
+
+Split @var{input} to @var{chunks} output files where @var{chunks} may be:
+
+@example
+@var{n}      generate @var{n} files based on current size of @var{input}
+@var{k}/@var{n}    only output @var{k}th of @var{n} to stdout
+l/@var{n}    generate @var{n} files without splitting lines or records
+l/@var{k}/@var{n}  likewise but only output @var{k}th of @var{n} to stdout
+r/@var{n}    like @samp{l} but use round robin distribution
+r/@var{k}/@var{n}  likewise but only output @var{k}th of @var{n} to stdout
+@end example
+
+Any excess bytes remaining after dividing the @var{input}
+into @var{n} chunks, are assigned to the last chunk.
+Any excess bytes appearing after the initial calculation are discarded
+(except when using @samp{r} mode).
+
+All @var{n} files are created even if there are fewer than @var{n} lines,
+or the @var{input} is truncated.
+
+For @samp{l} mode, chunks are approximately @var{input} size / @var{n}.
+The @var{input} is partitioned into @var{n} equal sized portions, with
+the last assigned any excess.  If a line @emph{starts} within a partition
+it is written completely to the corresponding file.  Since lines or records
+are not split even if they overlap a partition, the files written
+can be larger or smaller than the partition size, and even empty
+if a line/record is so long as to completely overlap the partition.
+
+For @samp{r} mode, the size of @var{input} is irrelevant,
+and so can be a pipe for example.
+
+@item -a @var{length}
+@itemx --suffix-length=@var{length}
+@opindex -a
+@opindex --suffix-length
+Use suffixes of length @var{length}.  If a @var{length} of 0 is specified,
+this is the same as if (any previous) @option{-a} was not specified, and
+thus enables the default behavior, which starts the suffix length at 2,
+and unless @option{-n} or @option{--numeric-suffixes=@var{from}} is
+specified, will auto increase the length by 2 as required.
+
+@item -d
+@itemx --numeric-suffixes[=@var{from}]
+@opindex -d
+@opindex --numeric-suffixes
+Use digits in suffixes rather than lower-case letters.  The numerical
+suffix counts from @var{from} if specified, 0 otherwise.
+
+@var{from} is supported with the long form option, and is used to either set the
+initial suffix for a single run, or to set the suffix offset for independently
+split inputs, and consequently the auto suffix length expansion described above
+is disabled.  Therefore you may also want to use option @option{-a} to allow
+suffixes beyond @samp{99}.  Note if option @option{--number} is specified and
+the number of files is less than @var{from}, a single run is assumed and the
+minimum suffix length required is automatically determined.
+
+@item -x
+@itemx --hex-suffixes[=@var{from}]
+@opindex -x
+@opindex --hex-suffixes
+Like @option{--numeric-suffixes}, but use hexadecimal numbers (in lower case).
+
+@item --additional-suffix=@var{suffix}
+@opindex --additional-suffix
+Append an additional @var{suffix} to output file names.  @var{suffix}
+must not contain slash.
+
+@item -e
+@itemx --elide-empty-files
+@opindex -e
+@opindex --elide-empty-files
+Suppress the generation of zero-length output files.  This can happen
+with the @option{--number} option if a file is (truncated to be) shorter
+than the number requested, or if a line is so long as to completely
+span a chunk.  The output file sequence numbers, always run consecutively
+even when this option is specified.
+
+@item -t @var{separator}
+@itemx --separator=@var{separator}
+@opindex -t
+@opindex --separator
+@cindex line separator character
+@cindex record separator character
+Use character @var{separator} as the record separator instead of the default
+newline character (ASCII LF).
+To specify ASCII NUL as the separator, use the two-character string @samp{\0},
+e.g., @samp{split -t '\0'}.
+
+@item -u
+@itemx --unbuffered
+@opindex -u
+@opindex --unbuffered
+Immediately copy input to output in @option{--number r/@dots{}} mode,
+which is a much slower mode of operation.
+
+@item --verbose
+@opindex --verbose
+Write a diagnostic just before each output file is opened.
+
+@end table
+
+@exitstatus
+
+Here are a few examples to illustrate how the
+@option{--number} (@option{-n}) option works:
+
+Notice how, by default, one line may be split onto two or more:
+
+@example
+$ seq -w 6 10 > k; split -n3 k; head xa?
+==> xaa <==
+06
+07
+==> xab <==
+
+08
+0
+==> xac <==
+9
+10
+@end example
+
+Use the "l/" modifier to suppress that:
+
+@example
+$ seq -w 6 10 > k; split -nl/3 k; head xa?
+==> xaa <==
+06
+07
+
+==> xab <==
+08
+09
+
+==> xac <==
+10
+@end example
+
+Use the "r/" modifier to distribute lines in a round-robin fashion:
+
+@example
+$ seq -w 6 10 > k; split -nr/3 k; head xa?
+==> xaa <==
+06
+09
+
+==> xab <==
+07
+10
+
+==> xac <==
+08
+@end example
+
+You can also extract just the Kth chunk.
+This extracts and prints just the 7th "chunk" of 33:
+
+@example
+$ seq 100 > k; split -nl/7/33 k
+20
+21
+22
+@end example
+
+
+@node csplit invocation
+@section @command{csplit}: Split a file into context-determined pieces
+
+@pindex csplit
+@cindex context splitting
+@cindex splitting a file into pieces by context
+
+@command{csplit} creates zero or more output files containing sections of
+@var{input} (standard input if @var{input} is @samp{-}).  Synopsis:
+
+@example
+csplit [@var{option}]@dots{} @var{input} @var{pattern}@dots{}
+@end example
+
+The contents of the output files are determined by the @var{pattern}
+arguments, as detailed below.  An error occurs if a @var{pattern}
+argument refers to a nonexistent line of the input file (e.g., if no
+remaining line matches a given regular expression).  After every
+@var{pattern} has been matched, any remaining input is copied into one
+last output file.
+
+By default, @command{csplit} prints the number of bytes written to each
+output file after it has been created.
+
+The types of pattern arguments are:
+
+@table @samp
+
+@item @var{n}
+Create an output file containing the input up to but not including line
+@var{n} (a positive integer).  If followed by a repeat count, also
+create an output file containing the next @var{n} lines of the input
+file once for each repeat.
+
+@item /@var{regexp}/[@var{offset}]
+Create an output file containing the current line up to (but not
+including) the next line of the input file that contains a match for
+@var{regexp}.  The optional @var{offset} is an integer.
+If it is given, the input up to (but not including) the
+matching line plus or minus @var{offset} is put into the output file,
+and the line after that begins the next section of input.
+Note lines within a negative offset of a regexp pattern
+are not matched in subsequent regexp patterns.
+
+@item %@var{regexp}%[@var{offset}]
+Like the previous type, except that it does not create an output
+file, so that section of the input file is effectively ignored.
+
+@item @{@var{repeat-count}@}
+Repeat the previous pattern @var{repeat-count} additional
+times.  The @var{repeat-count} can either be a positive integer or an
+asterisk, meaning repeat as many times as necessary until the input is
+exhausted.
+
+@end table
+
+The output files' names consist of a prefix (@samp{xx} by default)
+followed by a suffix.  By default, the suffix is an ascending sequence
+of two-digit decimal numbers from @samp{00} to @samp{99}.  In any case,
+concatenating the output files in sorted order by file name produces the
+original input file, excluding portions skipped with a %@var{regexp}%
+pattern or the @option{--suppress-matched} option.
+
+By default, if @command{csplit} encounters an error or receives a hangup,
+interrupt, quit, or terminate signal, it removes any output files
+that it has created so far before it exits.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -f @var{prefix}
+@itemx --prefix=@var{prefix}
+@opindex -f
+@opindex --prefix
+@cindex output file name prefix
+Use @var{prefix} as the output file name prefix.
+
+@item -b @var{format}
+@itemx --suffix-format=@var{format}
+@opindex -b
+@opindex --suffix-format
+@cindex output file name suffix
+Use @var{format} as the output file name suffix.  When this option is
+specified, the suffix string must include exactly one
+@code{printf(3)}-style conversion specification, possibly including
+format specification flags, a field width, a precision specifications,
+or all of these kinds of modifiers.  The format letter must convert a
+binary unsigned integer argument to readable form.  The format letters
+@samp{d} and @samp{i} are aliases for @samp{u}, and the
+@samp{u}, @samp{o}, @samp{x}, and @samp{X} conversions are allowed.  The
+entire @var{format} is given (with the current output file number) to
+@code{sprintf(3)} to form the file name suffixes for each of the
+individual output files in turn.  If this option is used, the
+@option{--digits} option is ignored.
+
+@item -n @var{digits}
+@itemx --digits=@var{digits}
+@opindex -n
+@opindex --digits
+Use output file names containing numbers that are @var{digits} digits
+long instead of the default 2.
+
+@item -k
+@itemx --keep-files
+@opindex -k
+@opindex --keep-files
+Do not remove output files when errors are encountered.
+
+@item --suppress-matched
+@opindex --suppress-matched
+Do not output lines matching the specified @var{pattern}.
+I.e., suppress the boundary line from the start of the second
+and subsequent splits.
+
+@item -z
+@itemx --elide-empty-files
+@opindex -z
+@opindex --elide-empty-files
+Suppress the generation of zero-length output files.  (In cases where
+the section delimiters of the input file are supposed to mark the first
+lines of each of the sections, the first output file will generally be a
+zero-length file unless you use this option.)  The output file sequence
+numbers always run consecutively starting from 0, even when this option
+is specified.
+
+@item -s
+@itemx -q
+@itemx --silent
+@itemx --quiet
+@opindex -s
+@opindex -q
+@opindex --silent
+@opindex --quiet
+Do not print counts of output file sizes.
+
+@end table
+
+@exitstatus
+
+Here is an example of its usage.
+First, create an empty directory for the exercise,
+and cd into it:
+
+@example
+$ mkdir d && cd d
+@end example
+
+Now, split the sequence of 1..14 on lines that end with 0 or 5:
+
+@example
+$ seq 14 | csplit - '/[05]$/' '@{*@}'
+8
+10
+15
+@end example
+
+Each number printed above is the size of an output
+file that csplit has just created.
+List the names of those output files:
+
+@example
+$ ls
+xx00  xx01  xx02
+@end example
+
+Use @command{head} to show their contents:
+
+@example
+$ head xx*
+==> xx00 <==
+1
+2
+3
+4
+
+==> xx01 <==
+5
+6
+7
+8
+9
+
+==> xx02 <==
+10
+11
+12
+13
+14
+@end example
+
+Example of splitting input by empty lines:
+
+@example
+$ csplit --suppress-matched @var{input.txt} '/^$/' '@{*@}'
+@end example
+
+@c
+@c TODO: "uniq" already supports "--group".
+@c        when it gets the "--key" option, uncomment this example.
+@c
+@c Example of splitting input file, based on the value of column 2:
+@c
+@c @example
+@c $ cat @var{input.txt} |
+@c       sort -k2,2 |
+@c       uniq --group -k2,2 |
+@c       csplit -m '/^$/' '@{*@}'
+@c @end example
+
+@node Summarizing files
+@chapter Summarizing files
+
+@cindex summarizing files
+
+These commands generate just a few numbers representing entire
+contents of files.
+
+@menu
+* wc invocation::               Print newline, word, and byte counts.
+* sum invocation::              Print checksum and block counts.
+* cksum invocation::            Print CRC checksum and byte counts.
+* b2sum invocation::            Print or check BLAKE2 digests.
+* md5sum invocation::           Print or check MD5 digests.
+* sha1sum invocation::          Print or check SHA-1 digests.
+* sha2 utilities::              Print or check SHA-2 digests.
+@end menu
+
+
+@node wc invocation
+@section @command{wc}: Print newline, word, and byte counts
+
+@pindex wc
+@cindex byte count
+@cindex character count
+@cindex word count
+@cindex line count
+
+@command{wc} counts the number of bytes, characters, whitespace-separated
+words, and newlines in each given @var{file}, or standard input if none
+are given or for a @var{file} of @samp{-}.  Synopsis:
+
+@example
+wc [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+@cindex total counts
+@command{wc} prints one line of counts for each file, and if the file was
+given as an argument, it prints the file name following the counts.  If
+more than one @var{file} is given, @command{wc} prints a final line
+containing the cumulative counts, with the file name @file{total}.  The
+counts are printed in this order: newlines, words, characters, bytes,
+maximum line length.
+Each count is printed right-justified in a field with at least one
+space between fields so that the numbers and file names normally line
+up nicely in columns.  The width of the count fields varies depending
+on the inputs, so you should not depend on a particular field width.
+However, as a GNU extension, if only one count is printed,
+it is guaranteed to be printed without leading spaces.
+
+By default, @command{wc} prints three counts: the newline, words, and byte
+counts.  Options can specify that only certain counts be printed.
+Options do not undo others previously given, so
+
+@example
+wc --bytes --words
+@end example
+
+@noindent
+prints both the byte counts and the word counts.
+
+With the @option{--max-line-length} option, @command{wc} prints the length
+of the longest line per file, and if there is more than one file it
+prints the maximum (not the sum) of those lengths.  The line lengths here
+are measured in screen columns, according to the current locale and
+assuming tab positions in every 8th column.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -c
+@itemx --bytes
+@opindex -c
+@opindex --bytes
+Print only the byte counts.
+
+@item -m
+@itemx --chars
+@opindex -m
+@opindex --chars
+Print only the character counts.
+
+@item -w
+@itemx --words
+@opindex -w
+@opindex --words
+Print only the word counts.
+
+@item -l
+@itemx --lines
+@opindex -l
+@opindex --lines
+Print only the newline counts.
+
+@item -L
+@itemx --max-line-length
+@opindex -L
+@opindex --max-line-length
+Print only the maximum display widths.
+Tabs are set at every 8th column.
+Display widths of wide characters are considered.
+Non-printable characters are given 0 width.
+
+@macro filesZeroFromOption{cmd,withTotalOption,subListOutput}
+@item --files0-from=@var{file}
+@opindex --files0-from=@var{file}
+@c This is commented out to avoid a texi2dvi failure.
+@c texi2dvi (GNU Texinfo 4.11) 1.104
+@c @cindex including files from @command{\cmd\}
+Disallow processing files named on the command line, and instead process
+those named in file @var{file}; each name being terminated by a zero byte
+(ASCII NUL).
+This is useful \withTotalOption\
+when the list of file names is so long that it may exceed a command line
+length limitation.
+In such cases, running @command{\cmd\} via @command{xargs} is undesirable
+because it splits the list into pieces and makes @command{\cmd\} print
+\subListOutput\ for each sublist rather than for the entire list.
+One way to produce a list of ASCII NUL terminated file
+names is with GNU
+@command{find}, using its @option{-print0} predicate.
+If @var{file} is @samp{-} then the ASCII NUL terminated
+file names are read from standard input.
+@end macro
+@filesZeroFromOption{wc,,a total}
+
+For example, to find the length of the longest line in any @file{.c} or
+@file{.h} file in the current hierarchy, do this:
+
+@example
+find . -name '*.[ch]' -print0 |
+  wc -L --files0-from=- | tail -n1
+@end example
+
+@end table
+
+@exitstatus
+
+
+@node sum invocation
+@section @command{sum}: Print checksum and block counts
+
+@pindex sum
+@cindex 16-bit checksum
+@cindex checksum, 16-bit
+
+@command{sum} computes a 16-bit checksum for each given @var{file}, or
+standard input if none are given or for a @var{file} of @samp{-}.  Synopsis:
+
+@example
+sum [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+@command{sum} prints the checksum for each @var{file} followed by the
+number of blocks in the file (rounded up).  If more than one @var{file}
+is given, file names are also printed (by default).  (With the
+@option{--sysv} option, corresponding file names are printed when there is
+at least one file argument.)
+
+By default, GNU @command{sum} computes checksums using an algorithm
+compatible with BSD @command{sum} and prints file sizes in units of
+1024-byte blocks.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -r
+@opindex -r
+@cindex BSD @command{sum}
+Use the default (BSD compatible) algorithm.  This option is included for
+compatibility with the System V @command{sum}.  Unless @option{-s} was also
+given, it has no effect.
+
+@item -s
+@itemx --sysv
+@opindex -s
+@opindex --sysv
+@cindex System V @command{sum}
+Compute checksums using an algorithm compatible with System V
+@command{sum}'s default, and print file sizes in units of 512-byte blocks.
+
+@end table
+
+@command{sum} is provided for compatibility; the @command{cksum} program (see
+next section) is preferable in new applications.
+
+@exitstatus
+
+
+@node cksum invocation
+@section @command{cksum}: Print CRC checksum and byte counts
+
+@pindex cksum
+@cindex cyclic redundancy check
+@cindex CRC checksum
+
+@command{cksum} computes a cyclic redundancy check (CRC) checksum for each
+given @var{file}, or standard input if none are given or for a
+@var{file} of @samp{-}.  Synopsis:
+
+@example
+cksum [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+@command{cksum} prints the CRC checksum for each file along with the number
+of bytes in the file, and the file name unless no arguments were given.
+
+@command{cksum} is typically used to ensure that files
+transferred by unreliable means (e.g., netnews) have not been corrupted,
+by comparing the @command{cksum} output for the received files with the
+@command{cksum} output for the original files (typically given in the
+distribution).
+
+The CRC algorithm is specified by the POSIX standard.  It is not
+compatible with the BSD or System V @command{sum} algorithms (see the
+previous section); it is more robust.
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.
+
+@exitstatus
+
+
+@node b2sum invocation
+@section @command{b2sum}: Print or check BLAKE2 digests
+
+@pindex b2sum
+@cindex BLAKE2
+@cindex 512-bit checksum
+@cindex checksum, 512-bit
+@cindex fingerprint, 512-bit
+@cindex message-digest, 512-bit
+
+@command{b2sum} computes a 512-bit checksum for each specified
+@var{file}.  The same usage and options as the @command{md5sum}
+command are supported.  @xref{md5sum invocation}.
+In addition @command{b2sum} supports the following options.
+
+@table @samp
+@item -l
+@itemx --length
+@opindex -l
+@opindex --length
+@cindex BLAKE2 hash length
+Change (shorten) the default digest length.
+This is specified in bits and thus must be a multiple of 8.
+This option is ignored when @option{--check} is specified,
+as the length is automatically determined when checking.
+@end table
+
+@node md5sum invocation
+@section @command{md5sum}: Print or check MD5 digests
+
+@pindex md5sum
+@cindex MD5
+@cindex 128-bit checksum
+@cindex checksum, 128-bit
+@cindex fingerprint, 128-bit
+@cindex message-digest, 128-bit
+
+@command{md5sum} computes a 128-bit checksum (or @dfn{fingerprint} or
+@dfn{message-digest}) for each specified @var{file}.
+
+@macro weakHash{hash}
+Note: The \hash\ digest is more reliable than a simple CRC (provided by
+the @command{cksum} command) for detecting accidental file corruption,
+as the chances of accidentally having two files with identical \hash\
+are vanishingly small.  However, it should not be considered secure
+against malicious tampering: although finding a file with a given \hash\
+fingerprint is considered infeasible at the moment, it is known how
+to modify certain files, including digital certificates, so that they
+appear valid when signed with an \hash\ digest.  For more secure hashes,
+consider using SHA-2, or the newer @command{b2sum} command.
+@xref{sha2 utilities}. @xref{b2sum invocation}.
+@end macro
+@weakHash{MD5}
+
+If a @var{file} is specified as @samp{-} or if no files are given
+@command{md5sum} computes the checksum for the standard input.
+@command{md5sum} can also determine whether a file and checksum are
+consistent.  Synopsis:
+
+@example
+md5sum [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+For each @var{file}, @samp{md5sum} outputs by default, the MD5 checksum,
+a space, a flag indicating binary or text input mode, and the file name.
+Binary mode is indicated with @samp{*}, text mode with @samp{ } (space).
+Binary mode is the default on systems where it's significant,
+otherwise text mode is the default.
+Without @option{--zero}, if @var{file} contains a backslash or newline,
+the line is started with a backslash, and each problematic character in
+the file name is escaped with a backslash, making the output
+unambiguous even in the presence of arbitrary file names.
+If @var{file} is omitted or specified as @samp{-}, standard input is read.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -b
+@itemx --binary
+@opindex -b
+@opindex --binary
+@cindex binary input files
+Treat each input file as binary, by reading it in binary mode and
+outputting a @samp{*} flag.  This is the inverse of @option{--text}.
+On systems like GNU that do not distinguish between binary
+and text files, this option merely flags each input mode as binary:
+the MD5 checksum is unaffected.  This option is the default on systems
+like MS-DOS that distinguish between binary and text files, except
+for reading standard input when standard input is a terminal.
+
+@item -c
+@itemx --check
+Read file names and checksum information (not data) from each
+@var{file} (or from stdin if no @var{file} was specified) and report
+whether the checksums match the contents of the named files.
+The input to this mode of @command{md5sum} is usually the output of
+a prior, checksum-generating run of @samp{md5sum}.
+Three input formats are supported.  Either the default output
+format described above, the @option{--tag} output format,
+or the BSD reversed mode format which is similar to the default mode,
+but doesn't use a character to distinguish binary and text modes.
+Output with @option{--zero} enabled is not supported by @option{--check}.
+@sp 1
+For each such line, @command{md5sum} reads the named file and computes its
+MD5 checksum.  Then, if the computed message digest does not match the
+one on the line with the file name, the file is noted as having
+failed the test.  Otherwise, the file passes the test.
+By default, for each valid line, one line is written to standard
+output indicating whether the named file passed the test.
+After all checks have been performed, if there were any failures,
+a warning is issued to standard error.
+Use the @option{--status} option to inhibit that output.
+If any listed file cannot be opened or read, if any valid line has
+an MD5 checksum inconsistent with the associated file, or if no valid
+line is found, @command{md5sum} exits with nonzero status.  Otherwise,
+it exits successfully.
+
+@item --ignore-missing
+@opindex --ignore-missing
+@cindex verifying MD5 checksums
+This option is useful only when verifying checksums.
+When verifying checksums, don't fail or report any status
+for missing files.  This is useful when verifying a subset
+of downloaded files given a larger list of checksums.
+
+@item --quiet
+@opindex --quiet
+@cindex verifying MD5 checksums
+This option is useful only when verifying checksums.
+When verifying checksums, don't generate an 'OK' message per successfully
+checked file.  Files that fail the verification are reported in the
+default one-line-per-file format.  If there is any checksum mismatch,
+print a warning summarizing the failures to standard error.
+
+@item --status
+@opindex --status
+@cindex verifying MD5 checksums
+This option is useful only when verifying checksums.
+When verifying checksums, don't generate the default one-line-per-file
+diagnostic and don't output the warning summarizing any failures.
+Failures to open or read a file still evoke individual diagnostics to
+standard error.
+If all listed files are readable and are consistent with the associated
+MD5 checksums, exit successfully.  Otherwise exit with a status code
+indicating there was a failure.
+
+@item --tag
+@opindex --tag
+@cindex BSD output
+Output BSD style checksums, which indicate the checksum algorithm used.
+As a GNU extension, if @option{--zero} is not used, file names with problematic
+characters are escaped as described above, with the same escaping indicator of
+@samp{\} at the start of the line, being used.
+The @option{--tag} option implies binary mode, and is disallowed with
+@option{--text} mode as supporting that would unnecessarily complicate
+the output format, while providing little benefit.
+
+@item -t
+@itemx --text
+@opindex -t
+@opindex --text
+@cindex text input files
+Treat each input file as text, by reading it in text mode and
+outputting a @samp{ } flag.  This is the inverse of @option{--binary}.
+This option is the default on systems like GNU that do not
+distinguish between binary and text files.  On other systems, it is
+the default for reading standard input when standard input is a
+terminal.  This mode is never defaulted to if @option{--tag} is used.
+
+@item -w
+@itemx --warn
+@opindex -w
+@opindex --warn
+@cindex verifying MD5 checksums
+When verifying checksums, warn about improperly formatted MD5 checksum lines.
+This option is useful only if all but a few lines in the checked input
+are valid.
+
+@item --strict
+@opindex --strict
+@cindex verifying MD5 checksums
+When verifying checksums,
+if one or more input line is invalid,
+exit nonzero after all warnings have been issued.
+
+@optZero
+Also file name escaping is not used.
+@end table
+
+@exitstatus
+
+
+@node sha1sum invocation
+@section @command{sha1sum}: Print or check SHA-1 digests
+
+@pindex sha1sum
+@cindex SHA-1
+@cindex 160-bit checksum
+@cindex checksum, 160-bit
+@cindex fingerprint, 160-bit
+@cindex message-digest, 160-bit
+
+@command{sha1sum} computes a 160-bit checksum for each specified
+@var{file}.  The usage and options of this command are precisely the
+same as for @command{md5sum}.  @xref{md5sum invocation}.
+
+@weakHash{SHA-1}
+
+
+@node sha2 utilities
+@section sha2 utilities: Print or check SHA-2 digests
+
+@pindex sha224sum
+@pindex sha256sum
+@pindex sha384sum
+@pindex sha512sum
+@cindex SHA-2
+@cindex 224-bit checksum
+@cindex 256-bit checksum
+@cindex 384-bit checksum
+@cindex 512-bit checksum
+@cindex checksum, 224-bit
+@cindex checksum, 256-bit
+@cindex checksum, 384-bit
+@cindex checksum, 512-bit
+@cindex fingerprint, 224-bit
+@cindex fingerprint, 256-bit
+@cindex fingerprint, 384-bit
+@cindex fingerprint, 512-bit
+@cindex message-digest, 224-bit
+@cindex message-digest, 256-bit
+@cindex message-digest, 384-bit
+@cindex message-digest, 512-bit
+
+The commands @command{sha224sum}, @command{sha256sum},
+@command{sha384sum} and @command{sha512sum} compute checksums of
+various lengths (respectively 224, 256, 384 and 512 bits),
+collectively known as the SHA-2 hashes.  The usage and options of
+these commands are precisely the same as for @command{md5sum}
+and @command{sha1sum}.
+@xref{md5sum invocation}.
+
+
+@node Operating on sorted files
+@chapter Operating on sorted files
+
+@cindex operating on sorted files
+@cindex sorted files, operations on
+
+These commands work with (or produce) sorted files.
+
+@menu
+* 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.
+@end menu
+
+
+@node sort invocation
+@section @command{sort}: Sort text files
+
+@pindex sort
+@cindex sorting files
+
+@command{sort} sorts, merges, or compares all the lines from the given
+files, or standard input if none are given or for a @var{file} of
+@samp{-}.  By default, @command{sort} writes the results to standard
+output.  Synopsis:
+
+@example
+sort [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+@cindex sort stability
+@cindex sort's last-resort comparison
+Many options affect how @command{sort} compares lines; if the results
+are unexpected, try the @option{--debug} option to see what happened.
+A pair of lines is compared as follows:
+@command{sort} compares each pair of fields (see @option{--key}), in the
+order specified on the command line, according to the associated
+ordering options, until a difference is found or no fields are left.
+If no key fields are specified, @command{sort} uses a default key of
+the entire line.  Finally, as a last resort when all keys compare
+equal, @command{sort} compares entire lines as if no ordering options
+other than @option{--reverse} (@option{-r}) were specified.  The
+@option{--stable} (@option{-s}) option disables this @dfn{last-resort
+comparison} so that lines in which all fields compare equal are left
+in their original relative order.  The @option{--unique}
+(@option{-u}) option also disables the last-resort comparison.
+@vindex LC_ALL
+@vindex LC_COLLATE
+
+Unless otherwise specified, all comparisons use the character collating
+sequence specified by the @env{LC_COLLATE} locale.@footnote{If you
+use a non-POSIX locale (e.g., by setting @env{LC_ALL}
+to @samp{en_US}), then @command{sort} may produce output that is sorted
+differently than you're accustomed to.  In that case, set the @env{LC_ALL}
+environment variable to @samp{C}@.  Note that setting only @env{LC_COLLATE}
+has two problems.  First, it is ineffective if @env{LC_ALL} is also set.
+Second, it has undefined behavior if @env{LC_CTYPE} (or @env{LANG}, if
+@env{LC_CTYPE} is unset) is set to an incompatible value.  For example,
+you get undefined behavior if @env{LC_CTYPE} is @code{ja_JP.PCK} but
+@env{LC_COLLATE} is @code{en_US.UTF-8}.}
+A line's trailing newline is not part of the line for comparison
+purposes.  If the final byte of an input file is not a newline, GNU
+@command{sort} silently supplies one.  GNU @command{sort} (as
+specified for all GNU utilities) has no limit on input line length or
+restrictions on bytes allowed within lines.
+
+@command{sort} has three modes of operation: sort (the default), merge,
+and check for sortedness.  The following options change the operation
+mode:
+
+@table @samp
+
+@item -c
+@itemx --check
+@itemx --check=diagnose-first
+@opindex -c
+@opindex --check
+@cindex checking for sortedness
+Check whether the given file is already sorted: if it is not all
+sorted, print a diagnostic containing the first out-of-order line and
+exit with a status of 1.
+Otherwise, exit successfully.
+At most one input file can be given.
+
+@item -C
+@itemx --check=quiet
+@itemx --check=silent
+@opindex -c
+@opindex --check
+@cindex checking for sortedness
+Exit successfully if the given file is already sorted, and
+exit with status 1 otherwise.
+At most one input file can be given.
+This is like @option{-c}, except it does not print a diagnostic.
+
+@item -m
+@itemx --merge
+@opindex -m
+@opindex --merge
+@cindex merging sorted files
+Merge the given files by sorting them as a group.  Each input file must
+always be individually sorted.  It always works to sort instead of
+merge; merging is provided because it is faster, in the case where it
+works.
+
+@end table
+
+@cindex exit status of @command{sort}
+Exit status:
+
+@display
+0 if no error occurred
+1 if invoked with @option{-c} or @option{-C} and the input is not sorted
+2 if an error occurred
+@end display
+
+@vindex TMPDIR
+If the environment variable @env{TMPDIR} is set, @command{sort} uses its
+value as the directory for temporary files instead of @file{/tmp}.  The
+@option{--temporary-directory} (@option{-T}) option in turn overrides
+the environment variable.
+
+The following options affect the ordering of output lines.  They may be
+specified globally or as part of a specific key field.  If no key
+fields are specified, global options apply to comparison of entire
+lines; otherwise the global options are inherited by key fields that do
+not specify any special options of their own.  In pre-POSIX
+versions of @command{sort}, global options affect only later key fields,
+so portable shell scripts should specify global options first.
+
+@table @samp
+
+@item -b
+@itemx --ignore-leading-blanks
+@opindex -b
+@opindex --ignore-leading-blanks
+@cindex blanks, ignoring leading
+@vindex LC_CTYPE
+Ignore leading blanks when finding sort keys in each line.
+By default a blank is a space or a tab, but the @env{LC_CTYPE} locale
+can change this.  Note blanks may be ignored by your locale's collating
+rules, but without this option they will be significant for character
+positions specified in keys with the @option{-k} option.
+
+@item -d
+@itemx --dictionary-order
+@opindex -d
+@opindex --dictionary-order
+@cindex dictionary order
+@cindex phone directory order
+@cindex telephone directory order
+@vindex LC_CTYPE
+Sort in @dfn{phone directory} order: ignore all characters except
+letters, digits and blanks when sorting.
+By default letters and digits are those of ASCII and a blank
+is a space or a tab, but the @env{LC_CTYPE} locale can change this.
+
+@item -f
+@itemx --ignore-case
+@opindex -f
+@opindex --ignore-case
+@cindex ignoring case
+@cindex case folding
+@vindex LC_CTYPE
+Fold lowercase characters into the equivalent uppercase characters when
+comparing so that, for example, @samp{b} and @samp{B} sort as equal.
+The @env{LC_CTYPE} locale determines character types.
+When used with @option{--unique} those lower case equivalent lines are
+thrown away.  (There is currently no way to throw away the upper case
+equivalent instead.  (Any @option{--reverse} given would only affect
+the final result, after the throwing away.))
+
+@item -g
+@itemx --general-numeric-sort
+@itemx --sort=general-numeric
+@opindex -g
+@opindex --general-numeric-sort
+@opindex --sort
+@cindex general numeric sort
+@vindex LC_NUMERIC
+Sort numerically, converting a prefix of each line to a long
+double-precision floating point number.  @xref{Floating point}.
+Do not report overflow, underflow, or conversion errors.
+Use the following collating sequence:
+
+@itemize @bullet
+@item
+Lines that do not start with numbers (all considered to be equal).
+@item
+NaNs (``Not a Number'' values, in IEEE floating point arithmetic)
+in a consistent but machine-dependent order.
+@item
+Minus infinity.
+@item
+Finite numbers in ascending numeric order (with @math{-0} and @math{+0} equal).
+@item
+Plus infinity.
+@end itemize
+
+Use this option only if there is no alternative; it is much slower than
+@option{--numeric-sort} (@option{-n}) and it can lose information when
+converting to floating point.
+
+@item -h
+@itemx --human-numeric-sort
+@itemx --sort=human-numeric
+@opindex -h
+@opindex --human-numeric-sort
+@opindex --sort
+@cindex human numeric sort
+@vindex LC_NUMERIC
+Sort numerically, first by numeric sign (negative, zero, or positive);
+then by SI suffix (either empty, or @samp{k} or @samp{K}, or
+one of @samp{MGTPEZY}, in that order; @pxref{Block size}); and finally
+by numeric value.  For example, @samp{1023M} sorts before @samp{1G}
+because @samp{M} (mega) precedes @samp{G} (giga) as an SI
+suffix.  This option sorts values that are consistently scaled to the
+nearest suffix, regardless of whether suffixes denote powers of 1000
+or 1024, and it therefore sorts the output of any single invocation of
+the @command{df}, @command{du}, or @command{ls} commands that are
+invoked with their @option{--human-readable} or @option{--si} options.
+The syntax for numbers is the same as for the @option{--numeric-sort}
+option; the SI suffix must immediately follow the number.
+Note also the @command{numfmt} command, which can be used to reformat
+numbers to human format @emph{after} the sort, thus often allowing
+sort to operate on more accurate numbers.
+
+@item -i
+@itemx --ignore-nonprinting
+@opindex -i
+@opindex --ignore-nonprinting
+@cindex nonprinting characters, ignoring
+@cindex unprintable characters, ignoring
+@vindex LC_CTYPE
+Ignore nonprinting characters.
+The @env{LC_CTYPE} locale determines character types.
+This option has no effect if the stronger @option{--dictionary-order}
+(@option{-d}) option is also given.
+
+@item -M
+@itemx --month-sort
+@itemx --sort=month
+@opindex -M
+@opindex --month-sort
+@opindex --sort
+@cindex months, sorting by
+@vindex LC_TIME
+An initial string, consisting of any amount of blanks, followed
+by a month name abbreviation, is folded to UPPER case and
+compared in the order @samp{JAN} < @samp{FEB} < @dots{} < @samp{DEC}@.
+Invalid names compare low to valid names.  The @env{LC_TIME} locale
+category determines the month spellings.
+By default a blank is a space or a tab, but the @env{LC_CTYPE} locale
+can change this.
+
+@item -n
+@itemx --numeric-sort
+@itemx --sort=numeric
+@opindex -n
+@opindex --numeric-sort
+@opindex --sort
+@cindex numeric sort
+@vindex LC_NUMERIC
+Sort numerically.  The number begins each line and consists
+of optional blanks, an optional @samp{-} sign, and zero or more
+digits possibly separated by thousands separators, optionally followed
+by a decimal-point character and zero or more digits.  An empty
+number is treated as @samp{0}.  The @env{LC_NUMERIC}
+locale specifies the decimal-point character and thousands separator.
+By default a blank is a space or a tab, but the @env{LC_CTYPE} locale
+can change this.
+
+Comparison is exact; there is no rounding error.
+
+Neither a leading @samp{+} nor exponential notation is recognized.
+To compare such strings numerically, use the
+@option{--general-numeric-sort} (@option{-g}) option.
+
+@item -V
+@itemx --version-sort
+@opindex -V
+@opindex --version-sort
+@cindex version number sort
+Sort by version name and number.  It behaves like a standard sort,
+except that each sequence of decimal digits is treated numerically
+as an index/version number.  (@xref{Version sort ordering}.)
+
+@item -r
+@itemx --reverse
+@opindex -r
+@opindex --reverse
+@cindex reverse sorting
+Reverse the result of comparison, so that lines with greater key values
+appear earlier in the output instead of later.
+
+@item -R
+@itemx --random-sort
+@itemx --sort=random
+@opindex -R
+@opindex --random-sort
+@opindex --sort
+@cindex random sort
+Sort by hashing the input keys and then sorting the hash values.
+Choose the hash function at random, ensuring that it is free of
+collisions so that differing keys have differing hash values.  This is
+like a random permutation of the inputs (@pxref{shuf invocation}),
+except that keys with the same value sort together.
+
+If multiple random sort fields are specified, the same random hash
+function is used for all fields.  To use different random hash
+functions for different fields, you can invoke @command{sort} more
+than once.
+
+The choice of hash function is affected by the
+@option{--random-source} option.
+
+@end table
+
+Other options are:
+
+@table @samp
+
+@item --compress-program=@var{prog}
+Compress any temporary files with the program @var{prog}.
+
+With no arguments, @var{prog} must compress standard input to standard
+output, and when given the @option{-d} option it must decompress
+standard input to standard output.
+
+Terminate with an error if @var{prog} exits with nonzero status.
+
+White space and the backslash character should not appear in
+@var{prog}; they are reserved for future use.
+
+@filesZeroFromOption{sort,,sorted output}
+
+@item -k @var{pos1}[,@var{pos2}]
+@itemx --key=@var{pos1}[,@var{pos2}]
+@opindex -k
+@opindex --key
+@cindex sort field
+Specify a sort field that consists of the part of the line between
+@var{pos1} and @var{pos2} (or the end of the line, if @var{pos2} is
+omitted), @emph{inclusive}.
+
+In its simplest form @var{pos} specifies a field number (starting with 1),
+with fields being separated by runs of blank characters, and by default
+those blanks being included in the comparison at the start of each field.
+To adjust the handling of blank characters see the @option{-b} and
+@option{-t} options.
+
+More generally,
+each @var{pos} has the form @samp{@var{f}[.@var{c}][@var{opts}]},
+where @var{f} is the number of the field to use, and @var{c} is the number
+of the first character from the beginning of the field.  Fields and character
+positions are numbered starting with 1; a character position of zero in
+@var{pos2} indicates the field's last character.  If @samp{.@var{c}} is
+omitted from @var{pos1}, it defaults to 1 (the beginning of the field);
+if omitted from @var{pos2}, it defaults to 0 (the end of the field).
+@var{opts} are ordering options, allowing individual keys to be sorted
+according to different rules; see below for details.  Keys can span
+multiple fields.
+
+Example:  To sort on the second field, use @option{--key=2,2}
+(@option{-k 2,2}).  See below for more notes on keys and more examples.
+See also the @option{--debug} option to help determine the part
+of the line being used in the sort.
+
+@item --debug
+Highlight the portion of each line used for sorting.
+Also issue warnings about questionable usage to stderr.
+
+@item --batch-size=@var{nmerge}
+@opindex --batch-size
+@cindex number of inputs to merge, nmerge
+Merge at most @var{nmerge} inputs at once.
+
+When @command{sort} has to merge more than @var{nmerge} inputs,
+it merges them in groups of @var{nmerge}, saving the result in
+a temporary file, which is then used as an input in a subsequent merge.
+
+A large value of @var{nmerge} may improve merge performance and decrease
+temporary storage utilization at the expense of increased memory usage
+and I/O@.  Conversely a small value of @var{nmerge} may reduce memory
+requirements and I/O at the expense of temporary storage consumption and
+merge performance.
+
+The value of @var{nmerge} must be at least 2.  The default value is
+currently 16, but this is implementation-dependent and may change in
+the future.
+
+The value of @var{nmerge} may be bounded by a resource limit for open
+file descriptors.  The commands @samp{ulimit -n} or @samp{getconf
+OPEN_MAX} may display limits for your systems; these limits may be
+modified further if your program already has some files open, or if
+the operating system has other limits on the number of open files.  If
+the value of @var{nmerge} exceeds the resource limit, @command{sort}
+silently uses a smaller value.
+
+@item -o @var{output-file}
+@itemx --output=@var{output-file}
+@opindex -o
+@opindex --output
+@cindex overwriting of input, allowed
+Write output to @var{output-file} instead of standard output.
+Normally, @command{sort} reads all input before opening
+@var{output-file}, so you can sort a file in place by using
+commands like @code{sort -o F F} and @code{cat F | sort -o F}@.
+However, it is often safer to output to an otherwise-unused file, as
+data may be lost if the system crashes or @command{sort} encounters
+an I/O or other serious error while a file is being sorted in place.
+Also, @command{sort} with @option{--merge} (@option{-m}) can open
+the output file before reading all input, so a command like @code{cat
+F | sort -m -o F - G} is not safe as @command{sort} might start
+writing @file{F} before @command{cat} is done reading it.
+
+@vindex POSIXLY_CORRECT
+On newer systems, @option{-o} cannot appear after an input file if
+@env{POSIXLY_CORRECT} is set, e.g., @samp{sort F -o F}@.  Portable
+scripts should specify @option{-o @var{output-file}} before any input
+files.
+
+@item --random-source=@var{file}
+@opindex --random-source
+@cindex random source for sorting
+Use @var{file} as a source of random data used to determine which
+random hash function to use with the @option{-R} option.  @xref{Random
+sources}.
+
+@item -s
+@itemx --stable
+@opindex -s
+@opindex --stable
+@cindex sort stability
+@cindex sort's last-resort comparison
+
+Make @command{sort} stable by disabling its last-resort comparison.
+This option has no effect if no fields or global ordering options
+other than @option{--reverse} (@option{-r}) are specified.
+
+@item -S @var{size}
+@itemx --buffer-size=@var{size}
+@opindex -S
+@opindex --buffer-size
+@cindex size for main memory sorting
+Use a main-memory sort buffer of the given @var{size}.  By default,
+@var{size} is in units of 1024 bytes.  Appending @samp{%} causes
+@var{size} to be interpreted as a percentage of physical memory.
+Appending @samp{K} multiplies @var{size} by 1024 (the default),
+@samp{M} by 1,048,576, @samp{G} by 1,073,741,824, and so on for
+@samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}@.  Appending
+@samp{b} causes @var{size} to be interpreted as a byte count, with no
+multiplication.
+
+This option can improve the performance of @command{sort} by causing it
+to start with a larger or smaller sort buffer than the default.
+However, this option affects only the initial buffer size.  The buffer
+grows beyond @var{size} if @command{sort} encounters input lines larger
+than @var{size}.
+
+@item -t @var{separator}
+@itemx --field-separator=@var{separator}
+@opindex -t
+@opindex --field-separator
+@cindex field separator character
+Use character @var{separator} as the field separator when finding the
+sort keys in each line.  By default, fields are separated by the empty
+string between a non-blank character and a blank character.
+By default a blank is a space or a tab, but the @env{LC_CTYPE} locale
+can change this.
+
+That is, given the input line @w{@samp{ foo bar}}, @command{sort} breaks it
+into fields @w{@samp{ foo}} and @w{@samp{ bar}}.  The field separator is
+not considered to be part of either the field preceding or the field
+following, so with @samp{sort @w{-t " "}} the same input line has
+three fields: an empty field, @samp{foo}, and @samp{bar}.
+However, fields that extend to the end of the line,
+as @option{-k 2}, or fields consisting of a range, as @option{-k 2,3},
+retain the field separators present between the endpoints of the range.
+
+To specify ASCII NUL as the field separator,
+use the two-character string @samp{\0}, e.g., @samp{sort -t '\0'}.
+
+@item -T @var{tempdir}
+@itemx --temporary-directory=@var{tempdir}
+@opindex -T
+@opindex --temporary-directory
+@cindex temporary directory
+@vindex TMPDIR
+Use directory @var{tempdir} to store temporary files, overriding the
+@env{TMPDIR} environment variable.  If this option is given more than
+once, temporary files are stored in all the directories given.  If you
+have a large sort or merge that is I/O-bound, you can often improve
+performance by using this option to specify directories on different
+disks and controllers.
+
+@item --parallel=@var{n}
+@opindex --parallel
+@cindex multithreaded sort
+Set the number of sorts run in parallel to @var{n}. By default,
+@var{n} is set to the number of available processors, but limited
+to 8, as there are diminishing performance gains after that.
+Note also that using @var{n} threads increases the memory usage by
+a factor of log @var{n}.  Also see @ref{nproc invocation}.
+
+@item -u
+@itemx --unique
+@opindex -u
+@opindex --unique
+@cindex uniquifying output
+
+Normally, output only the first of a sequence of lines that compare
+equal.  For the @option{--check} (@option{-c} or @option{-C}) option,
+check that no pair of consecutive lines compares equal.
+
+This option also disables the default last-resort comparison.
+
+The commands @code{sort -u} and @code{sort | uniq} are equivalent, but
+this equivalence does not extend to arbitrary @command{sort} options.
+For example, @code{sort -n -u} inspects only the value of the initial
+numeric string when checking for uniqueness, whereas @code{sort -n |
+uniq} inspects the entire line.  @xref{uniq invocation}.
+
+@optZeroTerminated
+@macro newlineFieldSeparator
+Note with @option{-z} the newline character is treated as a field separator.
+@end macro
+
+@end table
+
+Historical (BSD and System V) implementations of @command{sort} have
+differed in their interpretation of some options, particularly
+@option{-b}, @option{-f}, and @option{-n}.
+GNU sort follows the POSIX
+behavior, which is usually (but not always!) like the System V behavior.
+According to POSIX, @option{-n} no longer implies @option{-b}.  For
+consistency, @option{-M} has been changed in the same way.  This may
+affect the meaning of character positions in field specifications in
+obscure cases.  The only fix is to add an explicit @option{-b}.
+
+A position in a sort field specified with @option{-k} may have any
+of the option letters @samp{MbdfghinRrV} appended to it, in which case no
+global ordering options are inherited by that particular field.  The
+@option{-b} option may be independently attached to either or both of
+the start and end positions of a field specification, and if it is
+inherited from the global options it will be attached to both.
+If input lines can contain leading or adjacent blanks and @option{-t}
+is not used, then @option{-k} is typically combined with @option{-b} or
+an option that implicitly ignores leading blanks (@samp{Mghn}) as otherwise
+the varying numbers of leading blanks in fields can cause confusing results.
+
+If the start position in a sort field specifier falls after the end of
+the line or after the end field, the field is empty.  If the @option{-b}
+option was specified, the @samp{.@var{c}} part of a field specification
+is counted from the first nonblank character of the field.
+
+@vindex _POSIX2_VERSION
+@vindex POSIXLY_CORRECT
+On systems not conforming to POSIX 1003.1-2001,
+@command{sort} supports a traditional origin-zero
+syntax @samp{+@var{pos1} [-@var{pos2}]} for specifying sort keys.
+The traditional command @samp{sort +@var{a}.@var{x} -@var{b}.@var{y}}
+is equivalent to @samp{sort -k @var{a+1}.@var{x+1},@var{b}} if @var{y}
+is @samp{0} or absent, otherwise it is equivalent to @samp{sort -k
+@var{a+1}.@var{x+1},@var{b+1}.@var{y}}.
+
+This traditional behavior can be controlled with the
+@env{_POSIX2_VERSION} environment variable (@pxref{Standards
+conformance}); it can also be enabled when @env{POSIXLY_CORRECT} is
+not set by using the traditional syntax with @samp{-@var{pos2}} present.
+
+Scripts intended for use on standard hosts should avoid traditional
+syntax and should use @option{-k} instead.  For example, avoid
+@samp{sort +2}, since it might be interpreted as either @samp{sort
+./+2} or @samp{sort -k 3}.  If your script must also run on hosts that
+support only the traditional syntax, it can use a test like @samp{if sort
+-k 1 </dev/null >/dev/null 2>&1; then @dots{}} to decide which syntax
+to use.
+
+Here are some examples to illustrate various combinations of options.
+
+@itemize @bullet
+
+@item
+Sort in descending (reverse) numeric order.
+
+@example
+sort -n -r
+@end example
+
+@item
+Run no more than 4 sorts concurrently, using a buffer size of 10M.
+
+@example
+sort --parallel=4 -S 10M
+@end example
+
+@item
+Sort alphabetically, omitting the first and second fields
+and the blanks at the start of the third field.
+This uses a single key composed of the characters beginning
+at the start of the first nonblank character in field three
+and extending to the end of each line.
+
+@example
+sort -k 3b
+@end example
+
+@item
+Sort numerically on the second field and resolve ties by sorting
+alphabetically on the third and fourth characters of field five.
+Use @samp{:} as the field delimiter.
+
+@example
+sort -t : -k 2,2n -k 5.3,5.4
+@end example
+
+Note that if you had written @option{-k 2n} instead of @option{-k 2,2n}
+@command{sort} would have used all characters beginning in the second field
+and extending to the end of the line as the primary @emph{numeric}
+key.  For the large majority of applications, treating keys spanning
+more than one field as numeric will not do what you expect.
+
+Also note that the @samp{n} modifier was applied to the field-end
+specifier for the first key.  It would have been equivalent to
+specify @option{-k 2n,2} or @option{-k 2n,2n}.  All modifiers except
+@samp{b} apply to the associated @emph{field}, regardless of whether
+the modifier character is attached to the field-start and/or the
+field-end part of the key specifier.
+
+@item
+Sort the password file on the fifth field and ignore any
+leading blanks.  Sort lines with equal values in field five
+on the numeric user ID in field three.  Fields are separated
+by @samp{:}.
+
+@example
+sort -t : -k 5b,5 -k 3,3n /etc/passwd
+sort -t : -n -k 5b,5 -k 3,3 /etc/passwd
+sort -t : -b -k 5,5 -k 3,3n /etc/passwd
+@end example
+
+These three commands have equivalent effect.  The first specifies that
+the first key's start position ignores leading blanks and the second
+key is sorted numerically.  The other two commands rely on global
+options being inherited by sort keys that lack modifiers.  The inheritance
+works in this case because @option{-k 5b,5b} and @option{-k 5b,5} are
+equivalent, as the location of a field-end lacking a @samp{.@var{c}}
+character position is not affected by whether initial blanks are
+skipped.
+
+@item
+Sort a set of log files, primarily by IPv4 address and secondarily by
+timestamp.  If two lines' primary and secondary keys are identical,
+output the lines in the same order that they were input.  The log
+files contain lines that look like this:
+
+@example
+4.150.156.3 - - [01/Apr/2004:06:31:51 +0000] message 1
+211.24.3.231 - - [24/Apr/2004:20:17:39 +0000] message 2
+@end example
+
+Fields are separated by exactly one space.  Sort IPv4 addresses
+lexicographically, e.g., 212.61.52.2 sorts before 212.129.233.201
+because 61 is less than 129.
+
+@example
+sort -s -t ' ' -k 4.9n -k 4.5M -k 4.2n -k 4.14,4.21 file*.log |
+sort -s -t '.' -k 1,1n -k 2,2n -k 3,3n -k 4,4n
+@end example
+
+This example cannot be done with a single @command{sort} invocation,
+since IPv4 address components are separated by @samp{.} while dates
+come just after a space.  So it is broken down into two invocations of
+@command{sort}: the first sorts by timestamp and the second by IPv4
+address.  The timestamp is sorted by year, then month, then day, and
+finally by hour-minute-second field, using @option{-k} to isolate each
+field.  Except for hour-minute-second there's no need to specify the
+end of each key field, since the @samp{n} and @samp{M} modifiers sort
+based on leading prefixes that cannot cross field boundaries.  The
+IPv4 addresses are sorted lexicographically.  The second sort uses
+@samp{-s} so that ties in the primary key are broken by the secondary
+key; the first sort uses @samp{-s} so that the combination of the two
+sorts is stable.
+
+@item
+Generate a tags file in case-insensitive sorted order.
+
+@example
+find src -type f -print0 | sort -z -f | xargs -0 etags --append
+@end example
+
+The use of @option{-print0}, @option{-z}, and @option{-0} in this case means
+that file names that contain blanks or other special characters are
+not broken up
+by the sort operation.
+
+@c This example is a bit contrived and needs more explanation.
+@c @item
+@c Sort records separated by an arbitrary string by using a pipe to convert
+@c each record delimiter string to @samp{\0}, then using sort's -z option,
+@c and converting each @samp{\0} back to the original record delimiter.
+@c
+@c @example
+@c printf 'c\n\nb\n\na\n' |
+@c perl -0pe 's/\n\n/\n\0/g' |
+@c sort -z |
+@c perl -0pe 's/\0/\n/g'
+@c @end example
+
+@item
+Use the common DSU, Decorate Sort Undecorate idiom to
+sort lines according to their length.
+
+@example
+awk '@{print length, $0@}' /etc/passwd | sort -n | cut -f2- -d' '
+@end example
+
+In general this technique can be used to sort data that the @command{sort}
+command does not support, or is inefficient at, sorting directly.
+
+@item
+Shuffle a list of directories, but preserve the order of files within
+each directory.  For instance, one could use this to generate a music
+playlist in which albums are shuffled but the songs of each album are
+played in order.
+
+@example
+ls */* | sort -t / -k 1,1R -k 2,2
+@end example
+
+@end itemize
+
+
+@node shuf invocation
+@section @command{shuf}: Shuffling text
+
+@pindex shuf
+@cindex shuffling files
+
+@command{shuf} shuffles its input by outputting a random permutation
+of its input lines.  Each output permutation is equally likely.
+Synopses:
+
+@example
+shuf [@var{option}]@dots{} [@var{file}]
+shuf -e [@var{option}]@dots{} [@var{arg}]@dots{}
+shuf -i @var{lo}-@var{hi} [@var{option}]@dots{}
+@end example
+
+@command{shuf} has three modes of operation that affect where it
+obtains its input lines.  By default, it reads lines from standard
+input.  The following options change the operation mode:
+
+@table @samp
+
+@item -e
+@itemx --echo
+@opindex -c
+@opindex --echo
+@cindex command-line operands to shuffle
+Treat each command-line operand as an input line.
+
+@item -i @var{lo}-@var{hi}
+@itemx --input-range=@var{lo}-@var{hi}
+@opindex -i
+@opindex --input-range
+@cindex input range to shuffle
+Act as if input came from a file containing the range of unsigned
+decimal integers @var{lo}@dots{}@var{hi}, one per line.
+
+@end table
+
+@command{shuf}'s other options can affect its behavior in all
+operation modes:
+
+@table @samp
+
+@item -n @var{count}
+@itemx --head-count=@var{count}
+@opindex -n
+@opindex --head-count
+@cindex head of output
+Output at most @var{count} lines.  By default, all input lines are
+output.
+
+@item -o @var{output-file}
+@itemx --output=@var{output-file}
+@opindex -o
+@opindex --output
+@cindex overwriting of input, allowed
+Write output to @var{output-file} instead of standard output.
+@command{shuf} reads all input before opening
+@var{output-file}, so you can safely shuffle a file in place by using
+commands like @code{shuf -o F <F} and @code{cat F | shuf -o F}.
+
+@item --random-source=@var{file}
+@opindex --random-source
+@cindex random source for shuffling
+Use @var{file} as a source of random data used to determine which
+permutation to generate.  @xref{Random sources}.
+
+@item -r
+@itemx --repeat
+@opindex -r
+@opindex --repeat
+@cindex repeat output values
+Repeat output values, that is, select with replacement.  With this
+option the output is not a permutation of the input; instead, each
+output line is randomly chosen from all the inputs.  This option is
+typically combined with @option{--head-count}; if
+@option{--head-count} is not given, @command{shuf} repeats
+indefinitely.
+
+@optZeroTerminated
+
+@end table
+
+For example:
+
+@example
+shuf <<EOF
+A man,
+a plan,
+a canal:
+Panama!
+EOF
+@end example
+
+@noindent
+might produce the output
+
+@example
+Panama!
+A man,
+a canal:
+a plan,
+@end example
+
+@noindent
+Similarly, the command:
+
+@example
+shuf -e clubs hearts diamonds spades
+@end example
+
+@noindent
+might output:
+
+@example
+clubs
+diamonds
+spades
+hearts
+@end example
+
+@noindent
+and the command @samp{shuf -i 1-4} might output:
+
+@example
+4
+2
+1
+3
+@end example
+
+@noindent
+The above examples all have four input lines, so @command{shuf} might
+produce any of the twenty-four possible permutations of the input.  In
+general, if there are @var{n} input lines, there are @var{n}! (i.e.,
+@var{n} factorial, or @var{n} * (@var{n} - 1) * @dots{} * 1) possible
+output permutations.
+
+@noindent
+To output 50 random numbers each in the range 0 through 9, use:
+
+@example
+shuf -r -n 50 -i 0-9
+@end example
+
+@noindent
+To simulate 100 coin flips, use:
+
+@example
+shuf -r -n 100 -e Head Tail
+@end example
+
+@exitstatus
+
+
+@node uniq invocation
+@section @command{uniq}: Uniquify files
+
+@pindex uniq
+@cindex uniquify files
+
+@command{uniq} writes the unique lines in the given @file{input}, or
+standard input if nothing is given or for an @var{input} name of
+@samp{-}.  Synopsis:
+
+@example
+uniq [@var{option}]@dots{} [@var{input} [@var{output}]]
+@end example
+
+By default, @command{uniq} prints its input lines, except that
+it discards all but the first of adjacent repeated lines, so that
+no output lines are repeated.  Optionally, it can instead discard
+lines that are not repeated, or all repeated lines.
+
+The input need not be sorted, but repeated input lines are detected
+only if they are adjacent.  If you want to discard non-adjacent
+duplicate lines, perhaps you want to use @code{sort -u}.
+@xref{sort invocation}.
+
+@vindex LC_COLLATE
+Comparisons honor the rules specified by the @env{LC_COLLATE}
+locale category.
+
+If no @var{output} file is specified, @command{uniq} writes to standard
+output.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -f @var{n}
+@itemx --skip-fields=@var{n}
+@opindex -f
+@opindex --skip-fields
+Skip @var{n} fields on each line before checking for uniqueness.  Use
+a null string for comparison if a line has fewer than @var{n} fields.  Fields
+are sequences of non-space non-tab characters that are separated from
+each other by at least one space or tab.
+
+For compatibility @command{uniq} supports a traditional option syntax
+@option{-@var{n}}.  New scripts should use @option{-f @var{n}} instead.
+
+@item -s @var{n}
+@itemx --skip-chars=@var{n}
+@opindex -s
+@opindex --skip-chars
+Skip @var{n} characters before checking for uniqueness.  Use a null string
+for comparison if a line has fewer than @var{n} characters.  If you use both
+the field and character skipping options, fields are skipped over first.
+
+@vindex _POSIX2_VERSION
+On systems not conforming to POSIX 1003.1-2001,
+@command{uniq} supports a traditional option syntax
+@option{+@var{n}}.
+Although this traditional behavior can be controlled with the
+@env{_POSIX2_VERSION} environment variable (@pxref{Standards
+conformance}), portable scripts should avoid commands whose
+behavior depends on this variable.
+For example, use @samp{uniq ./+10} or @samp{uniq -s 10} rather than
+the ambiguous @samp{uniq +10}.
+
+@item -c
+@itemx --count
+@opindex -c
+@opindex --count
+Print the number of times each line occurred along with the line.
+
+@item -i
+@itemx --ignore-case
+@opindex -i
+@opindex --ignore-case
+Ignore differences in case when comparing lines.
+
+@item -d
+@itemx --repeated
+@opindex -d
+@opindex --repeated
+@cindex repeated lines, outputting
+Discard lines that are not repeated.  When used by itself, this option
+causes @command{uniq} to print the first copy of each repeated line,
+and nothing else.
+
+@item -D
+@itemx --all-repeated[=@var{delimit-method}]
+@opindex -D
+@opindex --all-repeated
+@cindex all repeated lines, outputting
+Do not discard the second and subsequent repeated input lines,
+but discard lines that are not repeated.
+This option is useful mainly in conjunction with other options e.g.,
+to ignore case or to compare only selected fields.
+The optional @var{delimit-method}, supported with the long form option,
+specifies how to delimit groups of repeated lines, and must be one of the
+following:
+
+@table @samp
+
+@item none
+Do not delimit groups of repeated lines.
+This is equivalent to @option{--all-repeated} (@option{-D}).
+
+@item prepend
+Output a newline before each group of repeated lines.
+@macro nulOutputNote
+With @option{--zero-terminated} (@option{-z}), use a zero
+byte (ASCII NUL) instead of a newline as the delimiter.
+@end macro
+@nulOutputNote
+
+@item separate
+Separate groups of repeated lines with a single newline.
+This is the same as using @samp{prepend}, except that
+no delimiter is inserted before the first group, and hence
+may be better suited for output direct to users.
+@nulOutputNote
+@end table
+
+@macro ambiguousGroupNote
+Note that when groups are delimited and the input stream contains
+blank lines, then the output is ambiguous.
+To avoid that, filter the input through @samp{tr -s '\\n'} to
+remove blank lines.
+@end macro
+@ambiguousGroupNote
+
+This is a GNU extension.
+@c FIXME: give an example showing *how* it's useful
+
+@item --group[=@var{delimit-method}]
+@opindex --group
+@cindex all lines, grouping
+Output all lines, and delimit each unique group.
+@nulOutputNote
+The optional @var{delimit-method} specifies how to delimit
+groups, and must be one of the following:
+
+@table @samp
+
+@item separate
+Separate unique groups with a single delimiter.
+This is the default delimiting method if none is specified,
+and better suited for output direct to users.
+
+@item prepend
+Output a delimiter before each group of unique items.
+
+@item append
+Output a delimiter after each group of unique items.
+
+@item both
+Output a delimiter around each group of unique items.
+@end table
+
+@ambiguousGroupNote
+
+This is a GNU extension.
+
+@item -u
+@itemx --unique
+@opindex -u
+@opindex --unique
+@cindex unique lines, outputting
+Discard the last line that would be output for a repeated input group.
+When used by itself, this option causes @command{uniq} to print unique
+lines, and nothing else.
+
+@item -w @var{n}
+@itemx --check-chars=@var{n}
+@opindex -w
+@opindex --check-chars
+Compare at most @var{n} characters on each line (after skipping any specified
+fields and characters).  By default the entire rest of the lines are
+compared.
+
+@optZeroTerminated
+@newlineFieldSeparator
+
+@end table
+
+@exitstatus
+
+
+@node comm invocation
+@section @command{comm}: Compare two sorted files line by line
+
+@pindex comm
+@cindex line-by-line comparison
+@cindex comparing sorted files
+
+@command{comm} writes to standard output lines that are common, and lines
+that are unique, to two input files; a file name of @samp{-} means
+standard input.  Synopsis:
+
+@example
+comm [@var{option}]@dots{} @var{file1} @var{file2}
+@end example
+
+@vindex LC_COLLATE
+Before @command{comm} can be used, the input files must be sorted using the
+collating sequence specified by the @env{LC_COLLATE} locale.
+If an input file ends in a non-newline
+character, a newline is silently appended.  The @command{sort} command with
+no options always outputs a file that is suitable input to @command{comm}.
+
+@cindex differing lines
+@cindex common lines
+With no options, @command{comm} produces three-column output.  Column one
+contains lines unique to @var{file1}, column two contains lines unique
+to @var{file2}, and column three contains lines common to both files.
+Columns are separated by a single TAB character.
+@c FIXME: when there's an option to supply an alternative separator
+@c string, append "by default" to the above sentence.
+
+@opindex -1
+@opindex -2
+@opindex -3
+The options @option{-1}, @option{-2}, and @option{-3} suppress printing of
+the corresponding columns (and separators).  Also see @ref{Common options}.
+
+Unlike some other comparison utilities, @command{comm} has an exit
+status that does not depend on the result of the comparison.
+Upon normal completion @command{comm} produces an exit code of zero.
+If there is an error it exits with nonzero status.
+
+@macro checkOrderOption{cmd}
+If the @option{--check-order} option is given, unsorted inputs will
+cause a fatal error message.  If the option @option{--nocheck-order}
+is given, unsorted inputs will never cause an error message.  If neither
+of these options is given, wrongly sorted inputs are diagnosed
+only if an input file is found to contain unpairable
+@ifset JOIN_COMMAND
+lines, and when both input files are non empty.
+@end ifset
+@ifclear JOIN_COMMAND
+lines.
+@end ifclear
+If an input file is diagnosed as being unsorted, the @command{\cmd\}
+command will exit with a nonzero status (and the output should not be used).
+
+Forcing @command{\cmd\} to process wrongly sorted input files
+containing unpairable lines by specifying @option{--nocheck-order} is
+not guaranteed to produce any particular output.  The output will
+probably not correspond with whatever you hoped it would be.
+@end macro
+@checkOrderOption{comm}
+
+@table @samp
+
+@item --check-order
+Fail with an error message if either input file is wrongly ordered.
+
+@item --nocheck-order
+Do not check that both input files are in sorted order.
+
+Other options are:
+
+@item --output-delimiter=@var{str}
+Print @var{str} between adjacent output columns,
+rather than the default of a single TAB character.
+
+The delimiter @var{str} may not be empty.
+
+@item --total
+Output a summary at the end.
+
+Similar to the regular output,
+column one contains the total number of lines unique to @var{file1},
+column two contains the total number of lines unique to @var{file2}, and
+column three contains the total number of lines common to both files,
+followed by the word @samp{total} in the additional column four.
+
+In the following example, @command{comm} omits the regular output
+(@option{-123}), thus just printing the summary:
+
+@example
+$ printf '%s\n' a b c d e     > file1
+$ printf '%s\n'   b c d e f g > file2
+$ comm --total -123 file1 file2
+1       2       4       total
+@end example
+
+This option is a GNU extension.  Portable scripts should use @command{wc} to
+get the totals, e.g. for the above example files:
+
+@example
+$ comm -23 file1 file2 | wc -l    # number of lines only in file1
+1
+$ comm -13 file1 file2 | wc -l    # number of lines only in file2
+2
+$ comm -12 file1 file2 | wc -l    # number of lines common to both files
+4
+@end example
+
+@optZeroTerminated
+
+@end table
+
+@node ptx invocation
+@section @command{ptx}: Produce permuted indexes
+
+@pindex ptx
+
+@command{ptx} reads a text file and essentially produces a permuted index, with
+each keyword in its context.  The calling sketch is either one of:
+
+@example
+ptx [@var{option} @dots{}] [@var{file} @dots{}]
+ptx -G [@var{option} @dots{}] [@var{input} [@var{output}]]
+@end example
+
+The @option{-G} (or its equivalent: @option{--traditional}) option disables
+all GNU extensions and reverts to traditional mode, thus introducing some
+limitations and changing several of the program's default option values.
+When @option{-G} is not specified, GNU extensions are always enabled.
+GNU extensions to @command{ptx} are documented wherever appropriate in this
+document.  @xref{Compatibility in ptx}, for the full list.
+
+Individual options are explained in the following sections.
+
+When GNU extensions are enabled, there may be zero, one or several
+@var{file}s after the options.  If there is no @var{file}, the program
+reads the standard input.  If there is one or several @var{file}s, they
+give the name of input files which are all read in turn, as if all the
+input files were concatenated.  However, there is a full contextual
+break between each file and, when automatic referencing is requested,
+file names and line numbers refer to individual text input files.  In
+all cases, the program outputs the permuted index to the standard
+output.
+
+When GNU extensions are @emph{not} enabled, that is, when the program
+operates in traditional mode, there may be zero, one or two parameters
+besides the options.  If there are no parameters, the program reads the
+standard input and outputs the permuted index to the standard output.
+If there is only one parameter, it names the text @var{input} to be read
+instead of the standard input.  If two parameters are given, they give
+respectively the name of the @var{input} file to read and the name of
+the @var{output} file to produce.  @emph{Be very careful} to note that,
+in this case, the contents of file given by the second parameter is
+destroyed.  This behavior is dictated by System V @command{ptx}
+compatibility; GNU Standards normally discourage output parameters not
+introduced by an option.
+
+Note that for @emph{any} file named as the value of an option or as an
+input text file, a single dash @samp{-} may be used, in which case
+standard input is assumed.  However, it would not make sense to use this
+convention more than once per program invocation.
+
+@menu
+* 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::
+@end menu
+
+
+@node General options in ptx
+@subsection General options
+
+@table @samp
+
+@item -G
+@itemx --traditional
+As already explained, this option disables all GNU extensions to
+@command{ptx} and switches to traditional mode.
+
+@item --help
+Print a short help on standard output, then exit without further
+processing.
+
+@item --version
+Print the program version on standard output, then exit without further
+processing.
+
+@end table
+
+@exitstatus
+
+
+@node Charset selection in ptx
+@subsection Charset selection
+
+@c FIXME:  People don't necessarily know what an IBM-PC was these days.
+As it is set up now, the program assumes that the input file is coded
+using 8-bit ISO 8859-1 code, also known as Latin-1 character set,
+@emph{unless} it is compiled for MS-DOS, in which case it uses the
+character set of the IBM-PC@.  (GNU @command{ptx} is not known to work on
+smaller MS-DOS machines anymore.)  Compared to 7-bit ASCII, the set
+of characters which are letters is different; this alters the behavior
+of regular expression matching.  Thus, the default regular expression
+for a keyword allows foreign or diacriticized letters.  Keyword sorting,
+however, is still crude; it obeys the underlying character set ordering
+quite blindly.
+
+@table @samp
+
+@item -f
+@itemx --ignore-case
+@opindex -f
+@opindex --ignore-case
+Fold lower case letters to upper case for sorting.
+
+@end table
+
+
+@node Input processing in ptx
+@subsection Word selection and input processing
+
+@table @samp
+
+@item -b @var{file}
+@itemx --break-file=@var{file}
+@opindex -b
+@opindex --break-file
+
+This option provides an alternative (to @option{-W}) method of describing
+which characters make up words.  It introduces the name of a
+file which contains a list of characters which can@emph{not} be part of
+one word; this file is called the @dfn{Break file}.  Any character which
+is not part of the Break file is a word constituent.  If both options
+@option{-b} and @option{-W} are specified, then @option{-W} has precedence and
+@option{-b} is ignored.
+
+When GNU extensions are enabled, the only way to avoid newline as a
+break character is to write all the break characters in the file with no
+newline at all, not even at the end of the file.  When GNU extensions
+are disabled, spaces, tabs and newlines are always considered as break
+characters even if not included in the Break file.
+
+@item -i @var{file}
+@itemx --ignore-file=@var{file}
+@opindex -i
+@opindex --ignore-file
+
+The file associated with this option contains a list of words which will
+never be taken as keywords in concordance output.  It is called the
+@dfn{Ignore file}.  The file contains exactly one word in each line; the
+end of line separation of words is not subject to the value of the
+@option{-S} option.
+
+@item -o @var{file}
+@itemx --only-file=@var{file}
+@opindex -o
+@opindex --only-file
+
+The file associated with this option contains a list of words which will
+be retained in concordance output; any word not mentioned in this file
+is ignored.  The file is called the @dfn{Only file}.  The file contains
+exactly one word in each line; the end of line separation of words is
+not subject to the value of the @option{-S} option.
+
+There is no default for the Only file.  When both an Only file and an
+Ignore file are specified, a word is considered a keyword only
+if it is listed in the Only file and not in the Ignore file.
+
+@item -r
+@itemx --references
+@opindex -r
+@opindex --references
+
+On each input line, the leading sequence of non-white space characters will be
+taken to be a reference that has the purpose of identifying this input
+line in the resulting permuted index.
+@xref{Output formatting in ptx},
+for more information about reference production.
+Using this option changes the default value for option @option{-S}.
+
+Using this option, the program does not try very hard to remove
+references from contexts in output, but it succeeds in doing so
+@emph{when} the context ends exactly at the newline.  If option
+@option{-r} is used with @option{-S} default value, or when GNU extensions
+are disabled, this condition is always met and references are completely
+excluded from the output contexts.
+
+@item -S @var{regexp}
+@itemx --sentence-regexp=@var{regexp}
+@opindex -S
+@opindex --sentence-regexp
+
+This option selects which regular expression will describe the end of a
+line or the end of a sentence.  In fact, this regular expression is not
+the only distinction between end of lines or end of sentences, and input
+line boundaries have no special significance outside this option.  By
+default, when GNU extensions are enabled and if @option{-r} option is not
+used, end of sentences are used.  In this case, this @var{regex} is
+imported from GNU Emacs:
+
+@example
+[.?!][]\"')@}]*\\($\\|\t\\|  \\)[ \t\n]*
+@end example
+
+Whenever GNU extensions are disabled or if @option{-r} option is used, end
+of lines are used; in this case, the default @var{regexp} is just:
+
+@example
+\n
+@end example
+
+Using an empty @var{regexp} is equivalent to completely disabling end of
+line or end of sentence recognition.  In this case, the whole file is
+considered to be a single big line or sentence.  The user might want to
+disallow all truncation flag generation as well, through option @option{-F
+""}.  @xref{Regexps, , Syntax of Regular Expressions, emacs, The GNU Emacs
+Manual}.
+
+When the keywords happen to be near the beginning of the input line or
+sentence, this often creates an unused area at the beginning of the
+output context line; when the keywords happen to be near the end of the
+input line or sentence, this often creates an unused area at the end of
+the output context line.  The program tries to fill those unused areas
+by wrapping around context in them; the tail of the input line or
+sentence is used to fill the unused area on the left of the output line;
+the head of the input line or sentence is used to fill the unused area
+on the right of the output line.
+
+As a matter of convenience to the user, many usual backslashed escape
+sequences from the C language are recognized and converted to the
+corresponding characters by @command{ptx} itself.
+
+@item -W @var{regexp}
+@itemx --word-regexp=@var{regexp}
+@opindex -W
+@opindex --word-regexp
+
+This option selects which regular expression will describe each keyword.
+By default, if GNU extensions are enabled, a word is a sequence of
+letters; the @var{regexp} used is @samp{\w+}.  When GNU extensions are
+disabled, a word is by default anything which ends with a space, a tab
+or a newline; the @var{regexp} used is @samp{[^ \t\n]+}.
+
+An empty @var{regexp} is equivalent to not using this option.
+@xref{Regexps, , Syntax of Regular Expressions, emacs, The GNU Emacs
+Manual}.
+
+As a matter of convenience to the user, many usual backslashed escape
+sequences, as found in the C language, are recognized and converted to
+the corresponding characters by @command{ptx} itself.
+
+@end table
+
+
+@node Output formatting in ptx
+@subsection Output formatting
+
+Output format is mainly controlled by the @option{-O} and @option{-T} options
+described in the table below.  When neither @option{-O} nor @option{-T} are
+selected, and if GNU extensions are enabled, the program chooses an
+output format suitable for a dumb terminal.  Each keyword occurrence is
+output to the center of one line, surrounded by its left and right
+contexts.  Each field is properly justified, so the concordance output
+can be readily observed.  As a special feature, if automatic
+references are selected by option @option{-A} and are output before the
+left context, that is, if option @option{-R} is @emph{not} selected, then
+a colon is added after the reference; this nicely interfaces with GNU
+Emacs @code{next-error} processing.  In this default output format, each
+white space character, like newline and tab, is merely changed to
+exactly one space, with no special attempt to compress consecutive
+spaces.  This might change in the future.  Except for those white space
+characters, every other character of the underlying set of 256
+characters is transmitted verbatim.
+
+Output format is further controlled by the following options.
+
+@table @samp
+
+@item -g @var{number}
+@itemx --gap-size=@var{number}
+@opindex -g
+@opindex --gap-size
+
+Select the size of the minimum white space gap between the fields on the
+output line.
+
+@item -w @var{number}
+@itemx --width=@var{number}
+@opindex -w
+@opindex --width
+
+Select the maximum output width of each final line.  If references are
+used, they are included or excluded from the maximum output width
+depending on the value of option @option{-R}@.  If this option is not
+selected, that is, when references are output before the left context,
+the maximum output width takes into account the maximum length of all
+references.  If this option is selected, that is, when references are
+output after the right context, the maximum output width does not take
+into account the space taken by references, nor the gap that precedes
+them.
+
+@item -A
+@itemx --auto-reference
+@opindex -A
+@opindex --auto-reference
+
+Select automatic references.  Each input line will have an automatic
+reference made up of the file name and the line ordinal, with a single
+colon between them.  However, the file name will be empty when standard
+input is being read.  If both @option{-A} and @option{-r} are selected, then
+the input reference is still read and skipped, but the automatic
+reference is used at output time, overriding the input reference.
+
+@item -R
+@itemx --right-side-refs
+@opindex -R
+@opindex --right-side-refs
+
+In the default output format, when option @option{-R} is not used, any
+references produced by the effect of options @option{-r} or @option{-A} are
+placed to the far right of output lines, after the right context.  With
+default output format, when the @option{-R} option is specified, references
+are rather placed at the beginning of each output line, before the left
+context.  For any other output format, option @option{-R} is
+ignored, with one exception:  with @option{-R} the width of references
+is @emph{not} taken into account in total output width given by @option{-w}.
+
+This option is automatically selected whenever GNU extensions are
+disabled.
+
+@item -F @var{string}
+@itemx --flag-truncation=@var{string}
+@opindex -F
+@opindex --flag-truncation
+
+This option will request that any truncation in the output be reported
+using the string @var{string}.  Most output fields theoretically extend
+towards the beginning or the end of the current line, or current
+sentence, as selected with option @option{-S}@.  But there is a maximum
+allowed output line width, changeable through option @option{-w}, which is
+further divided into space for various output fields.  When a field has
+to be truncated because it cannot extend beyond the beginning or the end of
+the current line to fit in, then a truncation occurs.  By default,
+the string used is a single slash, as in @option{-F /}.
+
+@var{string} may have more than one character, as in @option{-F @dots{}}.
+Also, in the particular case when @var{string} is empty (@option{-F ""}),
+truncation flagging is disabled, and no truncation marks are appended in
+this case.
+
+As a matter of convenience to the user, many usual backslashed escape
+sequences, as found in the C language, are recognized and converted to
+the corresponding characters by @command{ptx} itself.
+
+@item -M @var{string}
+@itemx --macro-name=@var{string}
+@opindex -M
+@opindex --macro-name
+
+Select another @var{string} to be used instead of @samp{xx}, while
+generating output suitable for @command{nroff}, @command{troff} or @TeX{}.
+
+@item -O
+@itemx --format=roff
+@opindex -O
+@opindex --format=roff
+
+Choose an output format suitable for @command{nroff} or @command{troff}
+processing.  Each output line will look like:
+
+@example
+.xx "@var{tail}" "@var{before}" "@var{keyword_and_after}"@c
+ "@var{head}" "@var{ref}"
+@end example
+
+so it will be possible to write a @samp{.xx} roff macro to take care of
+the output typesetting.  This is the default output format when GNU
+extensions are disabled.  Option @option{-M} can be used to change
+@samp{xx} to another macro name.
+
+In this output format, each non-graphical character, like newline and
+tab, is merely changed to exactly one space, with no special attempt to
+compress consecutive spaces.  Each quote character @samp{"} is doubled
+so it will be correctly processed by @command{nroff} or @command{troff}.
+
+@item -T
+@itemx --format=tex
+@opindex -T
+@opindex --format=tex
+
+Choose an output format suitable for @TeX{} processing.  Each output
+line will look like:
+
+@example
+\xx @{@var{tail}@}@{@var{before}@}@{@var{keyword}@}@c
+@{@var{after}@}@{@var{head}@}@{@var{ref}@}
+@end example
+
+@noindent
+so it will be possible to write a @code{\xx} definition to take care of
+the output typesetting.  Note that when references are not being
+produced, that is, neither option @option{-A} nor option @option{-r} is
+selected, the last parameter of each @code{\xx} call is inhibited.
+Option @option{-M} can be used to change @samp{xx} to another macro
+name.
+
+In this output format, some special characters, like @samp{$}, @samp{%},
+@samp{&}, @samp{#} and @samp{_} are automatically protected with a
+backslash.  Curly brackets @samp{@{}, @samp{@}} are protected with a
+backslash and a pair of dollar signs (to force mathematical mode).  The
+backslash itself produces the sequence @code{\backslash@{@}}.
+Circumflex and tilde diacritical marks produce the sequence @code{^\@{ @}} and
+@code{~\@{ @}} respectively.  Other diacriticized characters of the
+underlying character set produce an appropriate @TeX{} sequence as far
+as possible.  The other non-graphical characters, like newline and tab,
+and all other characters which are not part of ASCII, are merely
+changed to exactly one space, with no special attempt to compress
+consecutive spaces.  Let me know how to improve this special character
+processing for @TeX{}.
+
+@end table
+
+
+@node Compatibility in ptx
+@subsection The GNU extensions to @command{ptx}
+
+This version of @command{ptx} contains a few features which do not exist in
+System V @command{ptx}.  These extra features are suppressed by using the
+@option{-G} command line option, unless overridden by other command line
+options.  Some GNU extensions cannot be recovered by overriding, so the
+simple rule is to avoid @option{-G} if you care about GNU extensions.
+Here are the differences between this program and System V @command{ptx}.
+
+@itemize @bullet
+
+@item
+This program can read many input files at once, it always writes the
+resulting concordance on standard output.  On the other hand, System V
+@command{ptx} reads only one file and sends the result to standard output
+or, if a second @var{file} parameter is given on the command, to that
+@var{file}.
+
+Having output parameters not introduced by options is a dangerous
+practice which GNU avoids as far as possible.  So, for using @command{ptx}
+portably between GNU and System V, you should always use it with a
+single input file, and always expect the result on standard output.  You
+might also want to automatically configure in a @option{-G} option to
+@command{ptx} calls in products using @command{ptx}, if the configurator finds
+that the installed @command{ptx} accepts @option{-G}.
+
+@item
+The only options available in System V @command{ptx} are options @option{-b},
+@option{-f}, @option{-g}, @option{-i}, @option{-o}, @option{-r}, @option{-t} and
+@option{-w}.  All other options are GNU extensions and are not repeated in
+this enumeration.  Moreover, some options have a slightly different
+meaning when GNU extensions are enabled, as explained below.
+
+@item
+By default, concordance output is not formatted for @command{troff} or
+@command{nroff}.  It is rather formatted for a dumb terminal.  @command{troff}
+or @command{nroff} output may still be selected through option @option{-O}.
+
+@item
+Unless @option{-R} option is used, the maximum reference width is
+subtracted from the total output line width.  With GNU extensions
+disabled, width of references is not taken into account in the output
+line width computations.
+
+@item
+All 256 bytes, even ASCII NUL bytes, are always read and
+processed from input file with no adverse effect, even if GNU extensions
+are disabled.  However, System V @command{ptx} does not accept 8-bit
+characters, a few control characters are rejected, and the tilde
+@samp{~} is also rejected.
+
+@item
+Input line length is only limited by available memory, even if GNU
+extensions are disabled.  However, System V @command{ptx} processes only
+the first 200 characters in each line.
+
+@item
+The break (non-word) characters default to be every character except all
+letters of the underlying character set, diacriticized or not.  When GNU
+extensions are disabled, the break characters default to space, tab and
+newline only.
+
+@item
+The program makes better use of output line width.  If GNU extensions
+are disabled, the program rather tries to imitate System V @command{ptx},
+but still, there are some slight disposition glitches this program does
+not completely reproduce.
+
+@item
+The user can specify both an Ignore file and an Only file.  This is not
+allowed with System V @command{ptx}.
+
+@end itemize
+
+
+@node tsort invocation
+@section @command{tsort}: Topological sort
+
+@pindex tsort
+@cindex topological sort
+
+@command{tsort} performs a topological sort on the given @var{file}, or
+standard input if no input file is given or for a @var{file} of
+@samp{-}.  For more details and some history, see @ref{tsort background}.
+Synopsis:
+
+@example
+tsort [@var{option}] [@var{file}]
+@end example
+
+@command{tsort} reads its input as pairs of strings, separated by blanks,
+indicating a partial ordering.  The output is a total ordering that
+corresponds to the given partial ordering.
+
+For example
+
+@example
+tsort <<EOF
+a b c
+d
+e f
+b c d e
+EOF
+@end example
+
+@noindent
+will produce the output
+
+@example
+a
+b
+c
+d
+e
+f
+@end example
+
+Consider a more realistic example.
+You have a large set of functions all in one file, and they may all be
+declared static except one.  Currently that one (say @code{main}) is the
+first function defined in the file, and the ones it calls directly follow
+it, followed by those they call, etc.  Let's say that you are determined
+to take advantage of prototypes, so you have to choose between declaring
+all of those functions (which means duplicating a lot of information from
+the definitions) and rearranging the functions so that as many as possible
+are defined before they are used.  One way to automate the latter process
+is to get a list for each function of the functions it calls directly.
+Many programs can generate such lists.  They describe a call graph.
+Consider the following list, in which a given line indicates that the
+function on the left calls the one on the right directly.
+
+@example
+main parse_options
+main tail_file
+main tail_forever
+tail_file pretty_name
+tail_file write_header
+tail_file tail
+tail_forever recheck
+tail_forever pretty_name
+tail_forever write_header
+tail_forever dump_remainder
+tail tail_lines
+tail tail_bytes
+tail_lines start_lines
+tail_lines dump_remainder
+tail_lines file_lines
+tail_lines pipe_lines
+tail_bytes xlseek
+tail_bytes start_bytes
+tail_bytes dump_remainder
+tail_bytes pipe_bytes
+file_lines dump_remainder
+recheck pretty_name
+@end example
+
+then you can use @command{tsort} to produce an ordering of those
+functions that satisfies your requirement.
+
+@example
+example$ tsort call-graph | tac
+dump_remainder
+start_lines
+file_lines
+pipe_lines
+xlseek
+start_bytes
+pipe_bytes
+tail_lines
+tail_bytes
+pretty_name
+write_header
+tail
+recheck
+parse_options
+tail_file
+tail_forever
+main
+@end example
+
+@command{tsort} detects any cycles in the input and writes the first cycle
+encountered to standard error.
+
+Note that for a given partial ordering, generally there is no unique
+total ordering.  In the context of the call graph above, the function
+@code{parse_options} may be placed anywhere in the list as long as it
+precedes @code{main}.
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.
+
+@exitstatus
+
+@menu
+* tsort background::            Where tsort came from.
+@end menu
+
+@node tsort background
+@subsection @command{tsort}: Background
+
+@command{tsort} exists because very early versions of the Unix linker processed
+an archive file exactly once, and in order.  As @command{ld} read each object
+in the archive, it decided whether it was needed in the program based on
+whether it defined any symbols which were undefined at that point in
+the link.
+
+This meant that dependencies within the archive had to be handled
+specially.  For example, @code{scanf} probably calls @code{read}.  That means
+that in a single pass through an archive, it was important for @code{scanf.o}
+to appear before read.o, because otherwise a program which calls
+@code{scanf} but not @code{read} might end up with an unexpected unresolved
+reference to @code{read}.
+
+The way to address this problem was to first generate a set of
+dependencies of one object file on another.  This was done by a shell
+script called @command{lorder}.  The GNU tools don't provide a version of
+lorder, as far as I know, but you can still find it in BSD
+distributions.
+
+Then you ran @command{tsort} over the @command{lorder} output, and you used the
+resulting sort to define the order in which you added objects to the archive.
+
+This whole procedure has been obsolete since about 1980, because
+Unix archives now contain a symbol table (traditionally built by
+@command{ranlib}, now generally built by @command{ar} itself), and the Unix
+linker uses the symbol table to effectively make multiple passes over
+an archive file.
+
+Anyhow, that's where tsort came from.  To solve an old problem with
+the way the linker handled archive files, which has since been solved
+in different ways.
+
+
+@node Operating on fields
+@chapter Operating on fields
+
+@menu
+* cut invocation::              Print selected parts of lines.
+* paste invocation::            Merge lines of files.
+* join invocation::             Join lines on a common field.
+@end menu
+
+
+@node cut invocation
+@section @command{cut}: Print selected parts of lines
+
+@pindex cut
+@command{cut} writes to standard output selected parts of each line of each
+input file, or standard input if no files are given or for a file name of
+@samp{-}.  Synopsis:
+
+@example
+cut @var{option}@dots{} [@var{file}]@dots{}
+@end example
+
+In the table which follows, the @var{byte-list}, @var{character-list},
+and @var{field-list} are one or more numbers or ranges (two numbers
+separated by a dash) separated by commas.  Bytes, characters, and
+fields are numbered starting at 1.  Incomplete ranges may be
+given: @option{-@var{m}} means @samp{1-@var{m}}; @samp{@var{n}-} means
+@samp{@var{n}} through end of line or last field.  The list elements
+can be repeated, can overlap, and can be specified in any order; but
+the selected input is written in the same order that it is read, and
+is written exactly once.
+
+The program accepts the following options.  Also see @ref{Common
+options}.
+
+@table @samp
+
+@item -b @var{byte-list}
+@itemx --bytes=@var{byte-list}
+@opindex -b
+@opindex --bytes
+Select for printing only the bytes in positions listed in
+@var{byte-list}.  Tabs and backspaces are treated like any other
+character; they take up 1 byte.  If an output delimiter is specified,
+(see the description of @option{--output-delimiter}), then output that
+string between ranges of selected bytes.
+
+@item -c @var{character-list}
+@itemx --characters=@var{character-list}
+@opindex -c
+@opindex --characters
+Select for printing only the characters in positions listed in
+@var{character-list}.  The same as @option{-b} for now, but
+internationalization will change that.  Tabs and backspaces are
+treated like any other character; they take up 1 character.  If an
+output delimiter is specified, (see the description of
+@option{--output-delimiter}), then output that string between ranges
+of selected bytes.
+
+@item -f @var{field-list}
+@itemx --fields=@var{field-list}
+@opindex -f
+@opindex --fields
+Select for printing only the fields listed in @var{field-list}.
+Fields are separated by a TAB character by default.  Also print any
+line that contains no delimiter character, unless the
+@option{--only-delimited} (@option{-s}) option is specified.
+
+Note @command{awk} supports more sophisticated field processing,
+like reordering fields, and handling fields aligned with blank characters.
+By default @command{awk} uses (and discards) runs of blank characters
+to separate fields, and ignores leading and trailing blanks.
+@example
+@verbatim
+awk '{print $2}'      # print the second field
+awk '{print $(NF-1)}' # print the penultimate field
+awk '{print $2,$1}'   # reorder the first two fields
+@end verbatim
+@end example
+Note while @command{cut} accepts field specifications in
+arbitrary order, output is always in the order encountered in the file.
+
+In the unlikely event that @command{awk} is unavailable,
+one can use the @command{join} command, to process blank
+characters as @command{awk} does above.
+@example
+@verbatim
+join -a1 -o 1.2     - /dev/null # print the second field
+join -a1 -o 1.2,1.1 - /dev/null # reorder the first two fields
+@end verbatim
+@end example
+
+@item -d @var{input_delim_byte}
+@itemx --delimiter=@var{input_delim_byte}
+@opindex -d
+@opindex --delimiter
+With @option{-f}, use the first byte of @var{input_delim_byte} as
+the input fields separator (default is TAB).
+
+@item -n
+@opindex -n
+Do not split multi-byte characters (no-op for now).
+
+@item -s
+@itemx --only-delimited
+@opindex -s
+@opindex --only-delimited
+For @option{-f}, do not print lines that do not contain the field separator
+character.  Normally, any line without a field separator is printed verbatim.
+
+@item --output-delimiter=@var{output_delim_string}
+@opindex --output-delimiter
+With @option{-f}, output fields are separated by @var{output_delim_string}.
+The default with @option{-f} is to use the input delimiter.
+When using @option{-b} or @option{-c} to select ranges of byte or
+character offsets (as opposed to ranges of fields),
+output @var{output_delim_string} between non-overlapping
+ranges of selected bytes.
+
+@item --complement
+@opindex --complement
+This option is a GNU extension.
+Select for printing the complement of the bytes, characters or fields
+selected with the @option{-b}, @option{-c} or @option{-f} options.
+In other words, do @emph{not} print the bytes, characters or fields
+specified via those options.  This option is useful when you have
+many fields and want to print all but a few of them.
+
+@optZeroTerminated
+
+@end table
+
+@exitstatus
+
+
+@node paste invocation
+@section @command{paste}: Merge lines of files
+
+@pindex paste
+@cindex merging files
+
+@command{paste} writes to standard output lines consisting of sequentially
+corresponding lines of each given file, separated by a TAB character.
+Standard input is used for a file name of @samp{-} or if no input files
+are given.
+
+Synopsis:
+
+@example
+paste [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+For example, with:
+@example
+$ cat num2
+1
+2
+$ cat let3
+a
+b
+c
+@end example
+
+Take lines sequentially from each file:
+@example
+$ paste num2 let3
+1       a
+2       b
+       @ c
+@end example
+
+Duplicate lines from a file:
+@example
+$ paste num2 let3 num2
+1       a      1
+2       b      2
+       @ c
+@end example
+
+Intermix lines from stdin:
+@example
+$ paste - let3 - < num2
+1       a      2
+       @ b
+       @ c
+@end example
+
+Join consecutive lines with a space:
+@example
+$ seq 4 | paste -d ' ' - -
+1 2
+3 4
+@end example
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -s
+@itemx --serial
+@opindex -s
+@opindex --serial
+Paste the lines of one file at a time rather than one line from each
+file.  Using the above example data:
+
+@example
+$ paste -s num2 let3
+1       2
+a       b       c
+@end example
+
+@item -d @var{delim-list}
+@itemx --delimiters=@var{delim-list}
+@opindex -d
+@opindex --delimiters
+Consecutively use the characters in @var{delim-list} instead of
+TAB to separate merged lines.  When @var{delim-list} is
+exhausted, start again at its beginning.  Using the above example data:
+
+@example
+$ paste -d '%_' num2 let3 num2
+1%a_1
+2%b_2
+%c_
+@end example
+
+@optZeroTerminated
+
+@end table
+
+@exitstatus
+
+
+@node join invocation
+@section @command{join}: Join lines on a common field
+
+@pindex join
+@cindex common field, joining on
+
+@command{join} writes to standard output a line for each pair of input
+lines that have identical join fields.  Synopsis:
+
+@example
+join [@var{option}]@dots{} @var{file1} @var{file2}
+@end example
+
+Either @var{file1} or @var{file2} (but not both) can be @samp{-},
+meaning standard input.  @var{file1} and @var{file2} should be
+sorted on the join fields.
+
+@example
+@group
+$ cat file1
+a 1
+b 2
+e 5
+
+$ cat file2
+a X
+e Y
+f Z
+
+$ join file1 file2
+a 1 X
+e 5 Y
+@end group
+@end example
+
+
+@noindent
+@command{join}'s default behavior (when no options are given):
+@itemize
+@item the join field is the first field in each line;
+@item fields in the input are separated by one or more blanks, with leading
+blanks on the line ignored;
+@item fields in the output are separated by a space;
+@item each output line consists of the join field, the remaining
+fields from @var{file1}, then the remaining fields from @var{file2}.
+@end itemize
+
+
+@menu
+* General options in join::      Options which affect general program behavior.
+* Sorting files for join::       Using @command{sort} before @command{join}.
+* Working with fields::          Joining on different fields.
+* Paired and unpaired lines::    Controlling @command{join}'s field matching.
+* Header lines::                 Working with header lines in files.
+* Set operations::               Union, Intersection and Difference of files.
+@end menu
+
+@node General options in join
+@subsection General options
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -a @var{file-number}
+@opindex -a
+Print a line for each unpairable line in file @var{file-number} (either
+@samp{1} or @samp{2}), in addition to the normal output.
+
+@item --check-order
+Fail with an error message if either input file is wrongly ordered.
+
+@item --nocheck-order
+Do not check that both input files are in sorted order.  This is the default.
+
+@item -e @var{string}
+@opindex -e
+Replace those output fields that are missing in the input with @var{string}.
+I.e., missing fields specified with the @option{-12jo} options.
+
+@item --header
+@opindex --header
+Treat the first line of each input file as a header line.  The header lines
+will be joined and printed as the first output line.  If @option{-o} is used to
+specify output format, the header line will be printed according to the
+specified format.  The header lines will not be checked for ordering even if
+@option{--check-order} is specified.  Also if the header lines from each file
+do not match, the heading fields from the first file will be used.
+
+@item -i
+@itemx --ignore-case
+@opindex -i
+@opindex --ignore-case
+Ignore differences in case when comparing keys.
+With this option, the lines of the input files must be ordered in the same way.
+Use @samp{sort -f} to produce this ordering.
+
+@item -1 @var{field}
+@opindex -1
+Join on field @var{field} (a positive integer) of file 1.
+
+@item -2 @var{field}
+@opindex -2
+Join on field @var{field} (a positive integer) of file 2.
+
+@item -j @var{field}
+Equivalent to @option{-1 @var{field} -2 @var{field}}.
+
+@item -o @var{field-list}
+@itemx -o auto
+If the keyword @samp{auto} is specified, infer the output format from
+the first line in each file.  This is the same as the default output format
+but also ensures the same number of fields are output for each line.
+Missing fields are replaced with the @option{-e} option and extra fields
+are discarded.
+
+Otherwise, construct each output line according to the format in
+@var{field-list}.  Each element in @var{field-list} is either the single
+character @samp{0} or has the form @var{m.n} where the file number, @var{m},
+is @samp{1} or @samp{2} and @var{n} is a positive field number.
+
+A field specification of @samp{0} denotes the join field.
+In most cases, the functionality of the @samp{0} field spec
+may be reproduced using the explicit @var{m.n} that corresponds
+to the join field.  However, when printing unpairable lines
+(using either of the @option{-a} or @option{-v} options), there is no way
+to specify the join field using @var{m.n} in @var{field-list}
+if there are unpairable lines in both files.
+To give @command{join} that functionality, POSIX invented the @samp{0}
+field specification notation.
+
+The elements in @var{field-list}
+are separated by commas or blanks.
+Blank separators typically need to be quoted for the shell.  For
+example, the commands @samp{join -o 1.2,2.2} and @samp{join -o '1.2
+2.2'} are equivalent.
+
+All output lines---including those printed because of any -a or -v
+option---are subject to the specified @var{field-list}.
+
+@item -t @var{char}
+Use character @var{char} as the input and output field separator.
+Treat as significant each occurrence of @var{char} in the input file.
+Use @samp{sort -t @var{char}}, without the @option{-b} option of
+@samp{sort}, to produce this ordering.  If @samp{join -t ''} is specified,
+the whole line is considered, matching the default operation of sort.
+If @samp{-t '\0'} is specified then the ASCII NUL
+character is used to delimit the fields.
+
+@item -v @var{file-number}
+Print a line for each unpairable line in file @var{file-number}
+(either @samp{1} or @samp{2}), instead of the normal output.
+
+@optZeroTerminated
+@newlineFieldSeparator
+
+@end table
+
+@exitstatus
+
+@set JOIN_COMMAND
+@checkOrderOption{join}
+@clear JOIN_COMMAND
+
+
+
+@node Sorting files for join
+@subsection Pre-sorting
+
+@command{join} requires sorted input files. Each input file should be
+sorted according to the key (=field/column number) used in
+@command{join}. The recommended sorting option is @samp{sort -k 1b,1}
+(assuming the desired key is in the first column).
+
+@noindent Typical usage:
+@example
+@group
+$ sort -k 1b,1 file1 > file1.sorted
+$ sort -k 1b,1 file2 > file2.sorted
+$ join file1.sorted file2.sorted > file3
+@end group
+@end example
+
+@vindex LC_COLLATE
+Normally, the sort order is that of the
+collating sequence specified by the @env{LC_COLLATE} locale.  Unless
+the @option{-t} option is given, the sort comparison ignores blanks at
+the start of the join field, as in @code{sort -b}.  If the
+@option{--ignore-case} option is given, the sort comparison ignores
+the case of characters in the join field, as in @code{sort -f}:
+
+@example
+@group
+$ sort -k 1bf,1 file1 > file1.sorted
+$ sort -k 1bf,1 file2 > file2.sorted
+$ join --ignore-case file1.sorted file2.sorted > file3
+@end group
+@end example
+
+The @command{sort} and @command{join} commands should use consistent
+locales and options if the output of @command{sort} is fed to
+@command{join}.  You can use a command like @samp{sort -k 1b,1} to
+sort a file on its default join field, but if you select a non-default
+locale, join field, separator, or comparison options, then you should
+do so consistently between @command{join} and @command{sort}.
+
+@noindent To avoid any locale-related issues, it is recommended to use the
+@samp{C} locale for both commands:
+
+@example
+@group
+$ LC_ALL=C sort -k 1b,1 file1 > file1.sorted
+$ LC_ALL=C sort -k 1b,1 file2 > file2.sorted
+$ LC_ALL=C join file1.sorted file2.sorted > file3
+@end group
+@end example
+
+
+@node Working with fields
+@subsection Working with fields
+
+Use @option{-1},@option{-2} to set the key fields for each of the input files.
+Ensure the preceding @command{sort} commands operated on the same fields.
+
+@noindent
+The following example joins two files, using the values from seventh field
+of the first file and the third field of the second file:
+
+@example
+@group
+$ sort -k 7b,7 file1 > file1.sorted
+$ sort -k 3b,3 file2 > file2.sorted
+$ join -1 7 -2 3 file1.sorted file2.sorted > file3
+@end group
+@end example
+
+@noindent
+If the field number is the same for both files, use @option{-j}:
+
+@example
+@group
+$ sort -k4b,4 file1 > file1.sorted
+$ sort -k4b,4 file2 > file2.sorted
+$ join -j4    file1.sorted file2.sorted > file3
+@end group
+@end example
+
+@noindent
+Both @command{sort} and @command{join} operate of whitespace-delimited
+fields. To specify a different delimiter, use @option{-t} in @emph{both}:
+
+@example
+@group
+$ sort -t, -k3b,3 file1 > file1.sorted
+$ sort -t, -k3b,3 file2 > file2.sorted
+$ join -t, -j3    file1.sorted file2.sorted > file3
+@end group
+@end example
+
+@noindent
+To specify a tab (@sc{ascii} 0x09) character instead of whitespace, use
+@footnote{the @code{$'\t'} is supported in most modern shells.
+For older shells, use a literal tab}:
+
+@example
+@group
+$ sort -t$'\t' -k3b,3 file1 > file1.sorted
+$ sort -t$'\t' -k3b,3 file2 > file2.sorted
+$ join -t$'\t' -j3    file1.sorted file2.sorted > file3
+@end group
+@end example
+
+
+@noindent
+If @samp{join -t ''} is specified then the whole line is considered which
+matches the default operation of sort:
+
+@example
+@group
+$ sort file1 > file1.sorted
+$ sort file2 > file2.sorted
+$ join -t '' file1.sorted file2.sorted > file3
+@end group
+@end example
+
+
+@node Paired and unpaired lines
+@subsection Controlling @command{join}'s field matching
+
+In this section the @command{sort} commands are omitted for brevity.
+Sorting the files before joining is still required.
+
+@command{join}'s default behavior is to print only lines common to
+both input files. Use @option{-a} and @option{-v} to print unpairable lines
+from one or both files.
+
+@noindent
+All examples below use the following two (pre-sorted) input files:
+
+@multitable @columnfractions .5 .5
+@item
+@example
+$ cat file1
+a 1
+b 2
+@end example
+
+@tab
+@example
+$ cat file2
+a A
+c C
+@end example
+@end multitable
+
+
+@c TODO: Find better column widths that work for both HTML and PDF
+@c       and disable indentation of @example.
+@multitable @columnfractions 0.5 0.5
+
+@headitem Command @tab Outcome
+
+
+@item
+@example
+$ join file1 file2
+a 1 A
+@end example
+@tab
+common lines
+(@emph{intersection})
+
+
+
+@item
+@example
+$ join -a 1 file1 file2
+a 1 A
+b 2
+@end example
+@tab
+common lines @emph{and} unpaired
+lines from the first file
+
+
+@item
+@example
+$ join -a 2 file1 file2
+a 1 A
+c C
+@end example
+@tab
+common lines @emph{and} unpaired lines from the second file
+
+
+@item
+@example
+$ join -a 1 -a 2 file1 file2
+a 1 A
+b 2
+c C
+@end example
+@tab
+all lines (paired and unpaired) from both files
+(@emph{union}).
+@*
+see note below regarding @code{-o auto}.
+
+
+@item
+@example
+$ join -v 1 file1 file2
+b 2
+@end example
+@tab
+unpaired lines from the first file
+(@emph{difference})
+
+
+@item
+@example
+$ join -v 2 file1 file2
+c C
+@end example
+@tab
+unpaired lines from the second file
+(@emph{difference})
+
+
+@item
+@example
+$ join -v 1 -v 2 file1 file2
+b 2
+c C
+@end example
+@tab
+unpaired lines from both files, omitting common lines
+(@emph{symmetric difference}).
+
+
+@end multitable
+
+@noindent
+The @option{-o auto -e X} options are useful when dealing with unpaired lines.
+The following example prints all lines (common and unpaired) from both files.
+Without @option{-o auto} it is not easy to discern which fields originate from
+which file:
+
+@example
+$ join -a 1 -a 2 file1 file2
+a 1 A
+b 2
+c C
+
+$ join -o auto -e X -a 1 -a 2 file1 file2
+a 1 A
+b 2 X
+c X C
+@end example
+
+
+If the input has no unpairable lines, a GNU extension is
+available; the sort order can be any order that considers two fields
+to be equal if and only if the sort comparison described above
+considers them to be equal.  For example:
+
+@example
+@group
+$ cat file1
+a a1
+c c1
+b b1
+
+$ cat file2
+a a2
+c c2
+b b2
+
+$ join file1 file2
+a a1 a2
+c c1 c2
+b b1 b2
+@end group
+@end example
+
+
+@node Header lines
+@subsection Header lines
+
+The @option{--header} option can be used when the files to join
+have a header line which is not sorted:
+
+@example
+@group
+$ cat file1
+Name     Age
+Alice    25
+Charlie  34
+
+$ cat file2
+Name   Country
+Alice  France
+Bob    Spain
+
+$ join --header -o auto -e NA -a1 -a2 file1 file2
+Name     Age   Country
+Alice    25    France
+Bob      NA    Spain
+Charlie  34    NA
+@end group
+@end example
+
+
+To sort a file with a header line, use GNU @command{sed -u}.
+The following example sort the files but keeps the first line of each
+file in place:
+
+@example
+@group
+$ ( sed -u 1q ; sort -k2b,2 ) < file1 > file1.sorted
+$ ( sed -u 1q ; sort -k2b,2 ) < file2 > file2.sorted
+$ join --header -o auto -e NA -a1 -a2 file1.sorted file2.sorted > file3
+@end group
+@end example
+
+@node Set operations
+@subsection Union, Intersection and Difference of files
+
+Combine @command{sort}, @command{uniq} and @command{join} to
+perform the equivalent of set operations on files:
+
+@c From https://www.pixelbeat.org/cmdline.html#sets
+@multitable @columnfractions 0.5 0.5
+@headitem Command @tab outcome
+@item @code{sort -u file1 file2}
+@tab Union of unsorted files
+
+@item @code{sort file1 file2 | uniq -d}
+@tab Intersection of unsorted files
+
+@item @code{sort file1 file1 file2 | uniq -u}
+@tab Difference of unsorted files
+
+@item @code{sort file1 file2 | uniq -u}
+@tab Symmetric Difference of unsorted files
+
+@item @code{join -t '' -a1 -a2 file1 file2}
+@tab Union of sorted files
+
+@item @code{join -t '' file1 file2}
+@tab Intersection of sorted files
+
+@item @code{join -t '' -v2 file1 file2}
+@tab Difference of sorted files
+
+@item @code{join -t '' -v1 -v2 file1 file2}
+@tab Symmetric Difference of sorted files
+
+@end multitable
+
+All examples above operate on entire lines and not on specific fields:
+@command{sort} without @option{-k} and @command{join -t ''} both consider
+entire lines as the key.
+
+
+@node Operating on characters
+@chapter Operating on characters
+
+@cindex operating on characters
+
+These commands operate on individual characters.
+
+@menu
+* tr invocation::               Translate, squeeze, and/or delete characters.
+* expand invocation::           Convert tabs to spaces.
+* unexpand invocation::         Convert spaces to tabs.
+@end menu
+
+
+@node tr invocation
+@section @command{tr}: Translate, squeeze, and/or delete characters
+
+@pindex tr
+
+Synopsis:
+
+@example
+tr [@var{option}]@dots{} @var{set1} [@var{set2}]
+@end example
+
+@command{tr} copies standard input to standard output, performing
+one of the following operations:
+
+@itemize @bullet
+@item
+translate, and optionally squeeze repeated characters in the result,
+@item
+squeeze repeated characters,
+@item
+delete characters,
+@item
+delete characters, then squeeze repeated characters from the result.
+@end itemize
+
+The @var{set1} and (if given) @var{set2} arguments define ordered
+sets of characters, referred to below as @var{set1} and @var{set2}.  These
+sets are the characters of the input that @command{tr} operates on.
+The @option{--complement} (@option{-c}, @option{-C}) option replaces
+@var{set1} with its
+complement (all of the characters that are not in @var{set1}).
+
+Currently @command{tr} fully supports only single-byte characters.
+Eventually it will support multibyte characters; when it does, the
+@option{-C} option will cause it to complement the set of characters,
+whereas @option{-c} will cause it to complement the set of values.
+This distinction will matter only when some values are not characters,
+and this is possible only in locales using multibyte encodings when
+the input contains encoding errors.
+
+The program accepts the @option{--help} and @option{--version}
+options.  @xref{Common options}.  Options must precede operands.
+
+@exitstatus
+
+@menu
+* Character sets::              Specifying sets of characters.
+* Translating::                 Changing one set of characters to another.
+* Squeezing and deleting::      Removing characters.
+@end menu
+
+
+@node Character sets
+@subsection Specifying sets of characters
+
+@cindex specifying sets of characters
+
+The format of the @var{set1} and @var{set2} arguments resembles
+the format of regular expressions; however, they are not regular
+expressions, only lists of characters.  Most characters simply
+represent themselves in these strings, but the strings can contain
+the shorthands listed below, for convenience.  Some of them can be
+used only in @var{set1} or @var{set2}, as noted below.
+
+@table @asis
+
+@item Backslash escapes
+@cindex backslash escapes
+
+The following backslash escape sequences are recognized:
+
+@table @samp
+@item \a
+Control-G.
+@item \b
+Control-H.
+@item \f
+Control-L.
+@item \n
+Control-J.
+@item \r
+Control-M.
+@item \t
+Control-I.
+@item \v
+Control-K.
+@item \@var{ooo}
+The 8-bit character with the value given by @var{ooo}, which is 1 to 3
+octal digits.  Note that @samp{\400} is interpreted as the two-byte
+sequence, @samp{\040} @samp{0}.
+@item \\
+A backslash.
+@end table
+
+While a backslash followed by a character not listed above is
+interpreted as that character, the backslash also effectively
+removes any special significance, so it is useful to escape
+@samp{[}, @samp{]}, @samp{*}, and @samp{-}.
+
+@item Ranges
+@cindex ranges
+
+The notation @samp{@var{m}-@var{n}} expands to all of the characters
+from @var{m} through @var{n}, in ascending order.  @var{m} should
+collate before @var{n}; if it doesn't, an error results.  As an example,
+@samp{0-9} is the same as @samp{0123456789}.
+
+GNU @command{tr} does not support the System V syntax that uses square
+brackets to enclose ranges.  Translations specified in that format
+sometimes work as expected, since the brackets are often transliterated
+to themselves.  However, they should be avoided because they sometimes
+behave unexpectedly.  For example, @samp{tr -d '[0-9]'} deletes brackets
+as well as digits.
+
+Many historically common and even accepted uses of ranges are not
+portable.  For example, on EBCDIC hosts using the @samp{A-Z}
+range will not do what most would expect because @samp{A} through @samp{Z}
+are not contiguous as they are in ASCII@.
+If you can rely on a POSIX compliant version of @command{tr}, then
+the best way to work around this is to use character classes (see below).
+Otherwise, it is most portable (and most ugly) to enumerate the members
+of the ranges.
+
+@item Repeated characters
+@cindex repeated characters
+
+The notation @samp{[@var{c}*@var{n}]} in @var{set2} expands to @var{n}
+copies of character @var{c}.  Thus, @samp{[y*6]} is the same as
+@samp{yyyyyy}.  The notation @samp{[@var{c}*]} in @var{string2} expands
+to as many copies of @var{c} as are needed to make @var{set2} as long as
+@var{set1}.  If @var{n} begins with @samp{0}, it is interpreted in
+octal, otherwise in decimal.
+
+@item Character classes
+@cindex character classes
+
+The notation @samp{[:@var{class}:]} expands to all of the characters in
+the (predefined) class @var{class}.  The characters expand in no
+particular order, except for the @code{upper} and @code{lower} classes,
+which expand in ascending order.  When the @option{--delete} (@option{-d})
+and @option{--squeeze-repeats} (@option{-s}) options are both given, any
+character class can be used in @var{set2}.  Otherwise, only the
+character classes @code{lower} and @code{upper} are accepted in
+@var{set2}, and then only if the corresponding character class
+(@code{upper} and @code{lower}, respectively) is specified in the same
+relative position in @var{set1}.  Doing this specifies case conversion.
+The class names are given below; an error results when an invalid class
+name is given.
+
+@table @code
+@item alnum
+@opindex alnum
+Letters and digits.
+@item alpha
+@opindex alpha
+Letters.
+@item blank
+@opindex blank
+Horizontal whitespace.
+@item cntrl
+@opindex cntrl
+Control characters.
+@item digit
+@opindex digit
+Digits.
+@item graph
+@opindex graph
+Printable characters, not including space.
+@item lower
+@opindex lower
+Lowercase letters.
+@item print
+@opindex print
+Printable characters, including space.
+@item punct
+@opindex punct
+Punctuation characters.
+@item space
+@opindex space
+Horizontal or vertical whitespace.
+@item upper
+@opindex upper
+Uppercase letters.
+@item xdigit
+@opindex xdigit
+Hexadecimal digits.
+@end table
+
+@item Equivalence classes
+@cindex equivalence classes
+
+The syntax @samp{[=@var{c}=]} expands to all of the characters that are
+equivalent to @var{c}, in no particular order.  Equivalence classes are
+a relatively recent invention intended to support non-English alphabets.
+But there seems to be no standard way to define them or determine their
+contents.  Therefore, they are not fully implemented in GNU @command{tr};
+each character's equivalence class consists only of that character,
+which is of no particular use.
+
+@end table
+
+
+@node Translating
+@subsection Translating
+
+@cindex translating characters
+
+@command{tr} performs translation when @var{set1} and @var{set2} are
+both given and the @option{--delete} (@option{-d}) option is not given.
+@command{tr} translates each character of its input that is in @var{set1}
+to the corresponding character in @var{set2}.  Characters not in
+@var{set1} are passed through unchanged.  When a character appears more
+than once in @var{set1} and the corresponding characters in @var{set2}
+are not all the same, only the final one is used.  For example, these
+two commands are equivalent:
+
+@example
+tr aaa xyz
+tr a z
+@end example
+
+A common use of @command{tr} is to convert lowercase characters to
+uppercase.  This can be done in many ways.  Here are three of them:
+
+@example
+tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+tr a-z A-Z
+tr '[:lower:]' '[:upper:]'
+@end example
+
+@noindent
+But note that using ranges like @code{a-z} above is not portable.
+
+When @command{tr} is performing translation, @var{set1} and @var{set2}
+typically have the same length.  If @var{set1} is shorter than
+@var{set2}, the extra characters at the end of @var{set2} are ignored.
+
+On the other hand, making @var{set1} longer than @var{set2} is not
+portable; POSIX says that the result is undefined.  In this situation,
+BSD @command{tr} pads @var{set2} to the length of @var{set1} by repeating
+the last character of @var{set2} as many times as necessary.  System V
+@command{tr} truncates @var{set1} to the length of @var{set2}.
+
+By default, GNU @command{tr} handles this case like BSD @command{tr}.
+When the @option{--truncate-set1} (@option{-t}) option is given,
+GNU @command{tr} handles this case like the System V @command{tr}
+instead.  This option is ignored for operations other than translation.
+
+Acting like System V @command{tr} in this case breaks the relatively common
+BSD idiom:
+
+@example
+tr -cs A-Za-z0-9 '\012'
+@end example
+
+@noindent
+because it converts only zero bytes (the first element in the
+complement of @var{set1}), rather than all non-alphanumerics, to
+newlines.
+
+@noindent
+By the way, the above idiom is not portable because it uses ranges, and
+it assumes that the octal code for newline is 012.
+Assuming a POSIX compliant @command{tr}, here is a better
+way to write it:
+
+@example
+tr -cs '[:alnum:]' '[\n*]'
+@end example
+
+
+@node Squeezing and deleting
+@subsection Squeezing repeats and deleting
+
+@cindex squeezing repeat characters
+@cindex deleting characters
+@cindex removing characters
+
+When given just the @option{--delete} (@option{-d}) option, @command{tr}
+removes any input characters that are in @var{set1}.
+
+When given just the @option{--squeeze-repeats} (@option{-s}) option
+and not translating, @command{tr} replaces each input sequence of a
+repeated character that is in @var{set1} with a single occurrence of
+that character.
+
+When given both @option{--delete} and @option{--squeeze-repeats}, @command{tr}
+first performs any deletions using @var{set1}, then squeezes repeats
+from any remaining characters using @var{set2}.
+
+The @option{--squeeze-repeats} option may also be used when translating,
+in which case @command{tr} first performs translation, then squeezes
+repeats from any remaining characters using @var{set2}.
+
+Here are some examples to illustrate various combinations of options:
+
+@itemize @bullet
+
+@item
+Remove all zero bytes:
+
+@example
+tr -d '\0'
+@end example
+
+@item
+Put all words on lines by themselves.  This converts all
+non-alphanumeric characters to newlines, then squeezes each string
+of repeated newlines into a single newline:
+
+@example
+tr -cs '[:alnum:]' '[\n*]'
+@end example
+
+@item
+Convert each sequence of repeated newlines to a single newline.
+I.e., delete blank lines:
+
+@example
+tr -s '\n'
+@end example
+
+@item
+Find doubled occurrences of words in a document.
+@c Separate the following two "the"s, so typo checkers don't complain.
+For example, people often write ``the @w{}the'' with the repeated words
+separated by a newline.  The Bourne shell script below works first
+by converting each sequence of punctuation and blank characters to a
+single newline.  That puts each ``word'' on a line by itself.
+Next it maps all uppercase characters to lower case, and finally it
+runs @command{uniq} with the @option{-d} option to print out only the words
+that were repeated.
+
+@example
+#!/bin/sh
+cat -- "$@@" \
+  | tr -s '[:punct:][:blank:]' '[\n*]' \
+  | tr '[:upper:]' '[:lower:]' \
+  | uniq -d
+@end example
+
+@item
+Deleting a small set of characters is usually straightforward.  For example,
+to remove all @samp{a}s, @samp{x}s, and @samp{M}s you would do this:
+
+@example
+tr -d axM
+@end example
+
+However, when @samp{-} is one of those characters, it can be tricky because
+@samp{-} has special meanings.  Performing the same task as above but also
+removing all @samp{-} characters, we might try @code{tr -d -axM}, but
+that would fail because @command{tr} would try to interpret @option{-a} as
+a command-line option.  Alternatively, we could try putting the hyphen
+inside the string, @code{tr -d a-xM}, but that wouldn't work either because
+it would make @command{tr} interpret @code{a-x} as the range of characters
+@samp{a}@dots{}@samp{x} rather than the three.
+One way to solve the problem is to put the hyphen at the end of the list
+of characters:
+
+@example
+tr -d axM-
+@end example
+
+Or you can use @samp{--} to terminate option processing:
+
+@example
+tr -d -- -axM
+@end example
+
+More generally, use the character class notation @code{[=c=]}
+with @samp{-} (or any other character) in place of the @samp{c}:
+
+@example
+tr -d '[=-=]axM'
+@end example
+
+Note how single quotes are used in the above example to protect the
+square brackets from interpretation by a shell.
+
+@end itemize
+
+
+@node expand invocation
+@section @command{expand}: Convert tabs to spaces
+
+@pindex expand
+@cindex tabs to spaces, converting
+@cindex converting tabs to spaces
+
+@command{expand} writes the contents of each given @var{file}, or standard
+input if none are given or for a @var{file} of @samp{-}, to standard
+output, with tab characters converted to the appropriate number of
+spaces.  Synopsis:
+
+@example
+expand [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+By default, @command{expand} converts all tabs to spaces.  It preserves
+backspace characters in the output; they decrement the column count for
+tab calculations.  The default action is equivalent to @option{-t 8} (set
+tabs every 8 columns).
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -t @var{tab1}[,@var{tab2}]@dots{}
+@itemx --tabs=@var{tab1}[,@var{tab2}]@dots{}
+@opindex -t
+@opindex --tabs
+@cindex tab stops, setting
+If only one tab stop is given, set the tabs @var{tab1} spaces apart
+(default is 8).  Otherwise, set the tabs at columns @var{tab1},
+@var{tab2}, @dots{} (numbered from 0), and replace any tabs beyond the
+last tab stop given with single spaces.
+@macro gnuExpandTabs
+Tab stops can be separated by blanks as well as by commas.
+
+As a GNU extension the last @var{tab} specified can be prefixed
+with a @samp{/} to indicate a tab size to use for remaining positions.
+For example, @option{--tabs=2,4,/8} will set tab stops at position 2 and 4,
+and every multiple of 8 after that.
+
+Also the last @var{tab} specified can be prefixed with a @samp{+} to indicate
+a tab size to use for remaining positions, offset from the final explicitly
+specified tab stop.
+For example, to ignore the 1 character gutter present in diff output,
+one can specify a 1 character offset using @option{--tabs=1,+8},
+which will set tab stops at positions 1,9,17,@dots{}
+@end macro
+@gnuExpandTabs
+
+
+For compatibility, GNU @command{expand} also accepts the obsolete
+option syntax, @option{-@var{t1}[,@var{t2}]@dots{}}.  New scripts
+should use @option{-t @var{t1}[,@var{t2}]@dots{}} instead.
+
+@item -i
+@itemx --initial
+@opindex -i
+@opindex --initial
+@cindex initial tabs, converting
+Only convert initial tabs (those that precede all non-space or non-tab
+characters) on each line to spaces.
+
+@end table
+
+@exitstatus
+
+
+@node unexpand invocation
+@section @command{unexpand}: Convert spaces to tabs
+
+@pindex unexpand
+
+@command{unexpand} writes the contents of each given @var{file}, or
+standard input if none are given or for a @var{file} of @samp{-}, to
+standard output, converting blanks at the beginning of each line into
+as many tab characters as needed.  In the default POSIX
+locale, a @dfn{blank} is a space or a tab; other locales may specify
+additional blank characters.  Synopsis:
+
+@example
+unexpand [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+By default, @command{unexpand} converts only initial blanks (those
+that precede all non-blank characters) on each line.  It
+preserves backspace characters in the output; they decrement the column
+count for tab calculations.  By default, tabs are set at every 8th
+column.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -t @var{tab1}[,@var{tab2}]@dots{}
+@itemx --tabs=@var{tab1}[,@var{tab2}]@dots{}
+@opindex -t
+@opindex --tabs
+If only one tab stop is given, set the tabs @var{tab1} columns apart
+instead of the default 8.  Otherwise, set the tabs at columns
+@var{tab1}, @var{tab2}, @dots{} (numbered from 0), and leave blanks
+beyond the tab stops given unchanged.
+@gnuExpandTabs
+
+This option implies the @option{-a} option.
+
+For compatibility, GNU @command{unexpand} supports the obsolete option syntax,
+@option{-@var{tab1}[,@var{tab2}]@dots{}}, where tab stops must be
+separated by commas.  (Unlike @option{-t}, this obsolete option does
+not imply @option{-a}.)  New scripts should use @option{--first-only -t
+@var{tab1}[,@var{tab2}]@dots{}} instead.
+
+@item -a
+@itemx --all
+@opindex -a
+@opindex --all
+Also convert all sequences of two or more blanks just before a tab stop,
+even if they occur after non-blank characters in a line.
+
+@end table
+
+@exitstatus
+
+
+@node Directory listing
+@chapter Directory listing
+
+This chapter describes the @command{ls} command and its variants @command{dir}
+and @command{vdir}, which list information about files.
+
+@menu
+* ls invocation::               List directory contents.
+* dir invocation::              Briefly ls.
+* vdir invocation::             Verbosely ls.
+* dircolors invocation::        Color setup for ls, etc.
+@end menu
+
+
+@node ls invocation
+@section @command{ls}: List directory contents
+
+@pindex ls
+@cindex directory listing
+
+The @command{ls} program lists information about files (of any type,
+including directories).  Options and file arguments can be intermixed
+arbitrarily, as usual.
+
+For non-option command-line arguments that are directories, by default
+@command{ls} lists the contents of directories, not recursively, and
+omitting files with names beginning with @samp{.}.  For other non-option
+arguments, by default @command{ls} lists just the file name.  If no
+non-option argument is specified, @command{ls} operates on the current
+directory, acting as if it had been invoked with a single argument of @samp{.}.
+
+@vindex LC_ALL
+By default, the output is sorted alphabetically, according to the locale
+settings in effect.@footnote{If you use a non-POSIX
+locale (e.g., by setting @env{LC_ALL} to @samp{en_US}), then @command{ls} may
+produce output that is sorted differently than you're accustomed to.
+In that case, set the @env{LC_ALL} environment variable to @samp{C}.}
+If standard output is
+a terminal, the output is in columns (sorted vertically) and control
+characters are output as question marks; otherwise, the output is listed
+one per line and control characters are output as-is.
+
+Because @command{ls} is such a fundamental program, it has accumulated many
+options over the years.  They are described in the subsections below;
+within each section, options are listed alphabetically (ignoring case).
+The division of options into the subsections is not absolute, since some
+options affect more than one aspect of @command{ls}'s operation.
+
+@cindex exit status of @command{ls}
+Exit status:
+
+@display
+0 success
+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, failure
+  to access a file or directory specified as a command line argument
+  or a directory loop)
+@end display
+
+Also see @ref{Common options}.
+
+@menu
+* Which files are listed::
+* What information is listed::
+* Sorting the output::
+* General output formatting::
+* Formatting file timestamps::
+* Formatting the file names::
+@end menu
+
+
+@node Which files are listed
+@subsection Which files are listed
+
+These options determine which files @command{ls} lists information for.
+By default, @command{ls} lists files and the contents of any
+directories on the command line, except that in directories it ignores
+files whose names start with @samp{.}.
+
+@table @samp
+
+@item -a
+@itemx --all
+@opindex -a
+@opindex --all
+In directories, do not ignore file names that start with @samp{.}.
+
+@item -A
+@itemx --almost-all
+@opindex -A
+@opindex --almost-all
+In directories, do not ignore all file names that start with @samp{.};
+ignore only @file{.} and @file{..}.  The @option{--all} (@option{-a})
+option overrides this option.
+
+@item -B
+@itemx --ignore-backups
+@opindex -B
+@opindex --ignore-backups
+@cindex backup files, ignoring
+In directories, ignore files that end with @samp{~}.  This option is
+equivalent to @samp{--ignore='*~' --ignore='.*~'}.
+
+@item -d
+@itemx --directory
+@opindex -d
+@opindex --directory
+List just the names of directories, as with other types of files, rather
+than listing their contents.
+@c The following sentence is the same as the one for -F.
+Do not follow symbolic links listed on the
+command line unless the @option{--dereference-command-line} (@option{-H}),
+@option{--dereference} (@option{-L}), or
+@option{--dereference-command-line-symlink-to-dir} options are specified.
+
+@item -H
+@itemx --dereference-command-line
+@opindex -H
+@opindex --dereference-command-line
+@cindex symbolic links, dereferencing
+If a command line argument specifies a symbolic link, show information
+for the file the link references rather than for the link itself.
+
+@item --dereference-command-line-symlink-to-dir
+@opindex --dereference-command-line-symlink-to-dir
+@cindex symbolic links, dereferencing
+Do not dereference symbolic links, with one exception:
+if a command line argument specifies a symbolic link that refers to
+a directory, show information for that directory rather than for the
+link itself.
+This is the default behavior when no other dereferencing-related
+option has been specified (@option{--classify} (@option{-F}),
+@option{--directory} (@option{-d}),
+(@option{-l}),
+@option{--dereference} (@option{-L}), or
+@option{--dereference-command-line} (@option{-H})).
+
+@item --group-directories-first
+@opindex --group-directories-first
+Group all the directories before the files and then sort the
+directories and the files separately using the selected sort key
+(see --sort option).
+That is, this option specifies a primary sort key,
+and the --sort option specifies a secondary key.
+However, any use of @option{--sort=none}
+(@option{-U}) disables this option altogether.
+
+@item --hide=PATTERN
+@opindex --hide=@var{pattern}
+In directories, ignore files whose names match the shell pattern
+@var{pattern}, unless the @option{--all} (@option{-a}) or
+@option{--almost-all} (@option{-A}) is also given.  This
+option acts like @option{--ignore=@var{pattern}} except that it has no
+effect if @option{--all} (@option{-a}) or @option{--almost-all}
+(@option{-A}) is also given.
+
+This option can be useful in shell aliases.  For example, if
+@command{lx} is an alias for @samp{ls --hide='*~'} and @command{ly} is
+an alias for @samp{ls --ignore='*~'}, then the command @samp{lx -A}
+lists the file @file{README~} even though @samp{ly -A} would not.
+
+@item -I @var{pattern}
+@itemx --ignore=@var{pattern}
+@opindex -I
+@opindex --ignore=@var{pattern}
+In directories, ignore files whose names match the shell pattern
+(not regular expression) @var{pattern}.  As
+in the shell, an initial @samp{.} in a file name does not match a
+wildcard at the start of @var{pattern}.  Sometimes it is useful
+to give this option several times.  For example,
+
+@example
+$ ls --ignore='.??*' --ignore='.[^.]' --ignore='#*'
+@end example
+
+The first option ignores names of length 3 or more that start with @samp{.},
+the second ignores all two-character names that start with @samp{.}
+except @samp{..}, and the third ignores names that start with @samp{#}.
+
+@item -L
+@itemx --dereference
+@opindex -L
+@opindex --dereference
+@cindex symbolic links, dereferencing
+When showing file information for a symbolic link, show information
+for the file the link references rather than the link itself.
+However, even with this option, @command{ls} still prints the name
+of the link itself, not the name of the file that the link points to.
+
+@item -R
+@itemx --recursive
+@opindex -R
+@opindex --recursive
+@cindex recursive directory listing
+@cindex directory listing, recursive
+List the contents of all directories recursively.
+
+@end table
+
+
+@node What information is listed
+@subsection What information is listed
+
+These options affect the information that @command{ls} displays.  By
+default, only file names are shown.
+
+@table @samp
+
+@item --author
+@opindex --author
+@cindex hurd, author, printing
+List each file's author when producing long format directory listings.
+In GNU/Hurd, file authors can differ from their owners, but in other
+operating systems the two are the same.
+
+@item -D
+@itemx --dired
+@opindex -D
+@opindex --dired
+@cindex dired Emacs mode support
+With the long listing (@option{-l}) format, print an additional line after
+the main output:
+
+@example
+//DIRED// @var{beg1} @var{end1} @var{beg2} @var{end2} @dots{}
+@end example
+
+@noindent
+The @var{begn} and @var{endn} are unsigned integers that record the
+byte position of the beginning and end of each file name in the output.
+This makes it easy for Emacs to find the names, even when they contain
+unusual characters such as space or newline, without fancy searching.
+
+If directories are being listed recursively (@option{-R}), output a similar
+line with offsets for each subdirectory name:
+
+@example
+//SUBDIRED// @var{beg1} @var{end1} @dots{}
+@end example
+
+Finally, output a line of the form:
+
+@example
+//DIRED-OPTIONS// --quoting-style=@var{word}
+@end example
+
+@noindent
+where @var{word} is the quoting style (@pxref{Formatting the file names}).
+
+Here is an actual example:
+
+@example
+$ mkdir -p a/sub/deeper a/sub2
+$ touch a/f1 a/f2
+$ touch a/sub/deeper/file
+$ ls -gloRF --dired a
+  a:
+  total 8
+  -rw-r--r-- 1    0 Jun 10 12:27 f1
+  -rw-r--r-- 1    0 Jun 10 12:27 f2
+  drwxr-xr-x 3 4096 Jun 10 12:27 sub/
+  drwxr-xr-x 2 4096 Jun 10 12:27 sub2/
+
+  a/sub:
+  total 4
+  drwxr-xr-x 2 4096 Jun 10 12:27 deeper/
+
+  a/sub/deeper:
+  total 0
+  -rw-r--r-- 1 0 Jun 10 12:27 file
+
+  a/sub2:
+  total 0
+//DIRED// 48 50 84 86 120 123 158 162 217 223 282 286
+//SUBDIRED// 2 3 167 172 228 240 290 296
+//DIRED-OPTIONS// --quoting-style=literal
+@end example
+
+Note that the pairs of offsets on the @samp{//DIRED//} line above delimit
+these names: @file{f1}, @file{f2}, @file{sub}, @file{sub2}, @file{deeper},
+@file{file}.
+The offsets on the @samp{//SUBDIRED//} line delimit the following
+directory names: @file{a}, @file{a/sub}, @file{a/sub/deeper}, @file{a/sub2}.
+
+Here is an example of how to extract the fifth entry name, @samp{deeper},
+corresponding to the pair of offsets, 222 and 228:
+
+@example
+$ ls -gloRF --dired a > out
+$ dd bs=1 skip=222 count=6 < out 2>/dev/null; echo
+deeper
+@end example
+
+Note that although the listing above includes a trailing slash
+for the @samp{deeper} entry, the offsets select the name without
+the trailing slash.  However, if you invoke @command{ls} with @option{--dired}
+along with an option like @option{--escape} (aka @option{-b}) and operate
+on a file whose name contains special characters, notice that the backslash
+@emph{is} included:
+
+@example
+$ touch 'a b'
+$ ls -blog --dired 'a b'
+  -rw-r--r-- 1 0 Jun 10 12:28 a\ b
+//DIRED// 30 34
+//DIRED-OPTIONS// --quoting-style=escape
+@end example
+
+If you use a quoting style that adds quote marks
+(e.g., @option{--quoting-style=c}), then the offsets include the quote marks.
+So beware that the user may select the quoting style via the environment
+variable @env{QUOTING_STYLE}@.  Hence, applications using @option{--dired}
+should either specify an explicit @option{--quoting-style=literal} option
+(aka @option{-N} or @option{--literal}) on the command line, or else be
+prepared to parse the escaped names.
+
+@item --full-time
+@opindex --full-time
+Produce long format directory listings, and list times in full.  It is
+equivalent to using @option{--format=long} with
+@option{--time-style=full-iso} (@pxref{Formatting file timestamps}).
+
+@item -g
+@opindex -g
+Produce long format directory listings, but don't display owner information.
+
+@item -G
+@itemx --no-group
+@opindex -G
+@opindex --no-group
+Inhibit display of group information in a long format directory listing.
+(This is the default in some non-GNU versions of @command{ls}, so we
+provide this option for compatibility.)
+
+@optHumanReadable
+
+@item -i
+@itemx --inode
+@opindex -i
+@opindex --inode
+@cindex inode number, printing
+Print the inode number (also called the file serial number and index
+number) of each file to the left of the file name.  (This number
+uniquely identifies each file within a particular file system.)
+
+@item -l
+@itemx --format=long
+@itemx --format=verbose
+@opindex -l
+@opindex --format
+@opindex long ls @r{format}
+@opindex verbose ls @r{format}
+In addition to the name of each file, print the file type, file mode bits,
+number of hard links, owner name, group name, size, and
+timestamp (@pxref{Formatting file timestamps}), normally
+the modification timestamp (the mtime, @pxref{File timestamps}).
+If the owner or group name cannot be determined, print
+the owner or group ID instead, right-justified as a cue
+that it is a number rather than a textual name.
+Print question marks for other information that
+cannot be determined.
+
+Normally the size is printed as a byte count without punctuation, but
+this can be overridden (@pxref{Block size}).  For example, @option{-h}
+prints an abbreviated, human-readable count, and
+@samp{--block-size="'1"} prints a byte count with the thousands
+separator of the current locale.
+
+For each directory that is listed, preface the files with a line
+@samp{total @var{blocks}}, where @var{blocks} is the total disk allocation
+for all files in that directory.  The block size currently defaults to 1024
+bytes, but this can be overridden (@pxref{Block size}).
+The @var{blocks} computed counts each hard link separately;
+this is arguably a deficiency.
+
+The file type is one of the following characters:
+
+@c The commented-out entries are ones we're not sure about.
+
+@table @samp
+@item -
+regular file
+@item b
+block special file
+@item c
+character special file
+@item C
+high performance (``contiguous data'') file
+@item d
+directory
+@item D
+door (Solaris 2.5 and up)
+@c @item F
+@c semaphore, if this is a distinct file type
+@item l
+symbolic link
+@c @item m
+@c multiplexed file (7th edition Unix; obsolete)
+@item M
+off-line (``migrated'') file (Cray DMF)
+@item n
+network special file (HP-UX)
+@item p
+FIFO (named pipe)
+@item P
+port (Solaris 10 and up)
+@c @item Q
+@c message queue, if this is a distinct file type
+@item s
+socket
+@c @item S
+@c shared memory object, if this is a distinct file type
+@c @item T
+@c typed memory object, if this is a distinct file type
+@c @item w
+@c whiteout (4.4BSD; not implemented)
+@item ?
+some other file type
+@end table
+
+@cindex permissions, output by @command{ls}
+The file mode bits listed are similar to symbolic mode specifications
+(@pxref{Symbolic Modes}).  But @command{ls} combines multiple bits into the
+third character of each set of permissions as follows:
+
+@table @samp
+@item s
+If the set-user-ID or set-group-ID bit and the corresponding executable bit
+are both set.
+
+@item S
+If the set-user-ID or set-group-ID bit is set but the corresponding
+executable bit is not set.
+
+@item t
+If the restricted deletion flag or sticky bit, and the
+other-executable bit, are both set.  The restricted deletion flag is
+another name for the sticky bit.  @xref{Mode Structure}.
+
+@item T
+If the restricted deletion flag or sticky bit is set but the
+other-executable bit is not set.
+
+@item x
+If the executable bit is set and none of the above apply.
+
+@item -
+Otherwise.
+@end table
+
+Following the file mode bits is a single character that specifies
+whether an alternate access method such as an access control list
+applies to the file.  When the character following the file mode bits is a
+space, there is no alternate access method.  When it is a printing
+character, then there is such a method.
+
+GNU @command{ls} uses a @samp{.} character to indicate a file
+with a security context, but no other alternate access method.
+
+A file with any other combination of alternate access methods
+is marked with a @samp{+} character.
+
+@item -n
+@itemx --numeric-uid-gid
+@opindex -n
+@opindex --numeric-uid-gid
+@cindex numeric uid and gid
+@cindex numeric user and group IDs
+Produce long format directory listings, but
+display right-justified numeric user and group IDs
+instead of left-justified owner and group names.
+
+@item -o
+@opindex -o
+Produce long format directory listings, but don't display group information.
+It is equivalent to using @option{--format=long} with @option{--no-group} .
+
+@item -s
+@itemx --size
+@opindex -s
+@opindex --size
+@cindex disk allocation
+@cindex size of files, reporting
+Print the disk allocation of each file to the left of the file name.
+This is the amount of disk space used by the file, which is usually a
+bit more than the file's size, but it can be less if the file has holes.
+
+Normally the disk allocation is printed in units of
+1024 bytes, but this can be overridden (@pxref{Block size}).
+
+@cindex NFS mounts from BSD to HP-UX
+For files that are NFS-mounted from an HP-UX system to a BSD system,
+this option reports sizes that are half the correct values.  On HP-UX
+systems, it reports sizes that are twice the correct values for files
+that are NFS-mounted from BSD systems.  This is due to a flaw in HP-UX;
+it also affects the HP-UX @command{ls} program.
+
+@optSi
+
+@item -Z
+@itemx --context
+@opindex -Z
+@opindex --context
+@cindex SELinux
+@cindex security context
+Display the SELinux security context or @samp{?} if none is found.
+When used with the @option{-l} option, print the security context
+to the left of the size column.
+
+@end table
+
+
+@node Sorting the output
+@subsection Sorting the output
+
+@cindex sorting @command{ls} output
+These options change the order in which @command{ls} sorts the information
+it outputs.  By default, sorting is done by character code
+(e.g., ASCII order).
+
+@table @samp
+
+@item -c
+@itemx --time=ctime
+@itemx --time=status
+@opindex -c
+@opindex --time
+@opindex ctime@r{, printing or sorting by}
+@opindex status time@r{, printing or sorting by}
+@opindex use time@r{, printing or sorting files by}
+If the long listing format (e.g., @option{-l}, @option{-o}) is being used,
+print the status change timestamp (the ctime) instead of the mtime.
+When explicitly sorting by time (@option{--sort=time} or @option{-t})
+or when not using a long listing format,
+sort according to the ctime.  @xref{File timestamps}.
+
+@item -f
+@opindex -f
+@cindex unsorted directory listing
+@cindex directory order, listing by
+Primarily, like @option{-U}---do not sort; list the files in whatever
+order they are stored in the directory.  But also enable @option{-a} (list
+all files) and disable @option{-l}, @option{--color}, and @option{-s} (if they
+were specified before the @option{-f}).
+
+@item -r
+@itemx --reverse
+@opindex -r
+@opindex --reverse
+@cindex reverse sorting
+Reverse whatever the sorting method is---e.g., list files in reverse
+alphabetical order, youngest first, smallest first, or whatever.
+
+@item -S
+@itemx --sort=size
+@opindex -S
+@opindex --sort
+@opindex size of files@r{, sorting files by}
+Sort by file size, largest first.
+
+@item -t
+@itemx --sort=time
+@opindex -t
+@opindex --sort
+@opindex modification timestamp@r{, sorting files by}
+Sort by modification timestamp (mtime) by default, newest first.
+The timestamp to order by can be changed with the @option{--time} option.
+@xref{File timestamps}.
+
+@item -u
+@itemx --time=atime
+@itemx --time=access
+@itemx --time=use
+@opindex -u
+@opindex --time
+@opindex use time@r{, printing or sorting files by}
+@opindex atime@r{, printing or sorting files by}
+@opindex access timestamp@r{, printing or sorting files by}
+If the long listing format (e.g., @option{--format=long}) is being used,
+print the last access timestamp (the atime).
+When explicitly sorting by time (@option{--sort=time} or @option{-t})
+or when not using a long listing format, sort according to the atime.
+@xref{File timestamps}.
+
+@item --time=birth
+@itemx --time=creation
+@opindex --time
+@opindex birth time@r{, printing or sorting files by}
+@opindex creation timestamp@r{, printing or sorting files by}
+If the long listing format (e.g., @option{--format=long}) is being used,
+print the file creation timestamp if available.
+When explicitly sorting by time (@option{--sort=time} or @option{-t})
+or when not using a long listing format, sort according to the birth time.
+@xref{File timestamps}.
+
+@item -U
+@itemx --sort=none
+@opindex -U
+@opindex --sort
+@opindex none@r{, sorting option for @command{ls}}
+Do not sort; list the files in whatever order they are
+stored in the directory.  (Do not do any of the other unrelated things
+that @option{-f} does.)  This is especially useful when listing very large
+directories, since not doing any sorting can be noticeably faster.
+
+@item -v
+@itemx --sort=version
+@opindex -v
+@opindex --sort
+@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{Version sort ordering}.)
+
+@item -X
+@itemx --sort=extension
+@opindex -X
+@opindex --sort
+@opindex extension@r{, sorting files by}
+Sort directory contents alphabetically by file extension (characters
+after the last @samp{.}); files with no extension are sorted first.
+
+@end table
+
+
+@node General output formatting
+@subsection General output formatting
+
+These options affect the appearance of the overall output.
+
+@table @samp
+
+@item -1
+@itemx --format=single-column
+@opindex -1
+@opindex --format
+@opindex single-column @r{output of files}
+List one file per line.  This is the default for @command{ls} when standard
+output is not a terminal.  See also the @option{-b} and @option{-q} options
+to suppress direct output of newline characters within a file name.
+
+@item -C
+@itemx --format=vertical
+@opindex -C
+@opindex --format
+@opindex vertical @r{sorted files in columns}
+List files in columns, sorted vertically.  This is the default for
+@command{ls} if standard output is a terminal.  It is always the default
+for the @command{dir} program.
+GNU @command{ls} uses variable width columns to display as many files as
+possible in the fewest lines.
+
+@item --color [=@var{when}]
+@opindex --color
+@cindex color, distinguishing file types with
+Specify whether to use color for distinguishing file types.  @var{when}
+may be omitted, or one of:
+@itemize @bullet
+@item none
+@vindex none @r{color option}
+- Do not use color at all.  This is the default.
+@item auto
+@vindex auto @r{color option}
+@cindex terminal, using color iff
+- Only use color if standard output is a terminal.
+@item always
+@vindex always @r{color option}
+- Always use color.
+@end itemize
+Specifying @option{--color} and no @var{when} is equivalent to
+@option{--color=always}.
+If piping a colorized listing through a pager like @command{less},
+use the @option{-R} option to pass the color codes to the terminal.
+
+@vindex LS_COLORS
+@vindex SHELL @r{environment variable, and color}
+Note that using the @option{--color} option may incur a noticeable
+performance penalty when run in a directory with very many entries,
+because the default settings require that @command{ls} @code{stat} every
+single file it lists.
+However, if you would like most of the file-type coloring
+but can live without the other coloring options (e.g.,
+executable, orphan, sticky, other-writable, capability), use
+@command{dircolors} to set the @env{LS_COLORS} environment variable like this,
+@example
+eval $(dircolors -p | perl -pe \
+  's/^((CAP|S[ET]|O[TR]|M|E)\w+).*/$1 00/' | dircolors -)
+@end example
+and on a @code{dirent.d_type}-capable file system, @command{ls}
+will perform only one @code{stat} call per command line argument.
+
+@item -F
+@itemx --classify
+@itemx --indicator-style=classify
+@opindex -F
+@opindex --classify
+@opindex --indicator-style
+@cindex file type and executables, marking
+@cindex executables and file type, marking
+Append a character to each file name indicating the file type.  Also,
+for regular files that are executable, append @samp{*}.  The file type
+indicators are @samp{/} for directories, @samp{@@} for symbolic links,
+@samp{|} for FIFOs, @samp{=} for sockets, @samp{>} for doors,
+and nothing for regular files.
+@c The following sentence is the same as the one for -d.
+Do not follow symbolic links listed on the
+command line unless the @option{--dereference-command-line} (@option{-H}),
+@option{--dereference} (@option{-L}), or
+@option{--dereference-command-line-symlink-to-dir} options are specified.
+
+@item --file-type
+@itemx --indicator-style=file-type
+@opindex --file-type
+@opindex --indicator-style
+@cindex file type, marking
+Append a character to each file name indicating the file type.  This is
+like @option{-F}, except that executables are not marked.
+
+@item --hyperlink [=@var{when}]
+@opindex --hyperlink
+@cindex hyperlink, linking to files
+Output codes recognized by some terminals to link
+to files using the @samp{file://} URI format.
+@var{when} may be omitted, or one of:
+@itemize @bullet
+@item none
+@vindex none @r{hyperlink option}
+- Do not use hyperlinks at all.  This is the default.
+@item auto
+@vindex auto @r{hyperlink option}
+@cindex terminal, using hyperlink iff
+- Only use hyperlinks if standard output is a terminal.
+@item always
+@vindex always @r{hyperlink option}
+- Always use hyperlinks.
+@end itemize
+Specifying @option{--hyperlink} and no @var{when} is equivalent to
+@option{--hyperlink=always}.
+
+@item --indicator-style=@var{word}
+@opindex --indicator-style
+Append a character indicator with style @var{word} to entry names,
+as follows:
+
+@table @samp
+@item none
+Do not append any character indicator; this is the default.
+@item slash
+Append @samp{/} for directories.  This is the same as the @option{-p}
+option.
+@item file-type
+Append @samp{/} for directories, @samp{@@} for symbolic links, @samp{|}
+for FIFOs, @samp{=} for sockets, and nothing for regular files.  This is
+the same as the @option{--file-type} option.
+@item classify
+Append @samp{*} for executable regular files, otherwise behave as for
+@samp{file-type}.  This is the same as the @option{-F} or
+@option{--classify} option.
+@end table
+
+@item -k
+@itemx --kibibytes
+@opindex -k
+@opindex --kibibytes
+Set the default block size to its normal value of 1024 bytes,
+overriding any contrary specification in environment variables
+(@pxref{Block size}).  If @option{--block-size}, @option{-h},
+@option{--human-readable}, or @option{--si} options are used,
+they take precedence over @option{-k} or @option{--kibibytes}
+even if @option{-k} or @option{--kibibytes} is placed after
+the other options.
+
+The @option{-k} or @option{--kibibytes} option affects the
+per-directory block count written by the @option{-l} and similar
+options, and the size written by the @option{-s} or @option{--size}
+option.  It does not affect the file size written by @option{-l}.
+
+@item -m
+@itemx --format=commas
+@opindex -m
+@opindex --format
+@opindex commas@r{, outputting between files}
+List files horizontally, with as many as will fit on each line,
+separated by @samp{, } (a comma and a space).
+
+@item -p
+@itemx --indicator-style=slash
+@opindex -p
+@opindex --indicator-style
+@cindex file type, marking
+Append a @samp{/} to directory names.
+
+@item -x
+@itemx --format=across
+@itemx --format=horizontal
+@opindex -x
+@opindex --format
+@opindex across@r{, listing files}
+@opindex horizontal@r{, listing files}
+List the files in columns, sorted horizontally.
+
+@item -T @var{cols}
+@itemx --tabsize=@var{cols}
+@opindex -T
+@opindex --tabsize
+Assume that each tab stop is @var{cols} columns wide.  The default is 8.
+@command{ls} uses tabs where possible in the output, for efficiency.  If
+@var{cols} is zero, do not use tabs at all.
+
+Some terminal emulators might not properly align columns to the right of a
+TAB following a non-ASCII byte.  You can avoid that issue by using the
+@option{-T0} option or put @code{TABSIZE=0} in your environment, to tell
+@command{ls} to align using spaces, not tabs.
+
+@item -w @var{cols}
+@itemx --width=@var{cols}
+@opindex -w
+@opindex --width
+@vindex COLUMNS
+Assume the screen is @var{cols} columns wide.  The default is taken
+from the terminal settings if possible; otherwise the environment
+variable @env{COLUMNS} is used if it is set; otherwise the default
+is 80.  With a @var{cols} value of @samp{0}, there is no limit on
+the length of the output line, and that single output line will
+be delimited with spaces, not tabs.
+
+@end table
+
+
+@node Formatting file timestamps
+@subsection Formatting file timestamps
+
+By default, file timestamps are listed in abbreviated form, using
+a date like @samp{Mar 30@ @ 2002} for non-recent timestamps, and a
+date-without-year and time like @samp{Mar 30 23:45} for recent timestamps.
+This format can change depending on the current locale as detailed below.
+
+@cindex clock skew
+A timestamp is considered to be @dfn{recent} if it is less than six
+months old, and is not dated in the future.  If a timestamp dated
+today is not listed in recent form, the timestamp is in the future,
+which means you probably have clock skew problems which may break
+programs like @command{make} that rely on file timestamps.
+@xref{File timestamps}.
+
+@vindex TZ
+Timestamps are listed according to the time zone rules specified by
+the @env{TZ} environment variable, or by the system default rules if
+@env{TZ} is not set.  @xref{TZ Variable,, Specifying the Time Zone
+with @env{TZ}, libc, The GNU C Library Reference Manual}.
+
+The following option changes how file timestamps are printed.
+
+@table @samp
+@item --time-style=@var{style}
+@opindex --time-style
+@cindex time style
+List timestamps in style @var{style}.  The @var{style} should
+be one of the following:
+
+@table @samp
+@item +@var{format}
+@vindex LC_TIME
+List timestamps using @var{format}, where @var{format} is interpreted
+like the format argument of @command{date} (@pxref{date invocation}).
+For example, @option{--time-style="+%Y-%m-%d %H:%M:%S"} causes
+@command{ls} to list timestamps like @samp{2002-03-30 23:45:56}.  As
+with @command{date}, @var{format}'s interpretation is affected by the
+@env{LC_TIME} locale category.
+
+If @var{format} contains two format strings separated by a newline,
+the former is used for non-recent files and the latter for recent
+files; if you want output columns to line up, you may need to insert
+spaces in one of the two formats.
+
+@item full-iso
+List timestamps in full using ISO 8601-like date, time, and time zone
+components with nanosecond precision, e.g., @samp{2002-03-30
+23:45:56.477817180 -0700}.  This style is equivalent to
+@samp{+%Y-%m-%d %H:%M:%S.%N %z}.
+
+This is useful because the time output includes all the information that
+is available from the operating system.  For example, this can help
+explain @command{make}'s behavior, since GNU @command{make}
+uses the full timestamp to determine whether a file is out of date.
+
+@item long-iso
+List ISO 8601 date and time components with minute precision, e.g.,
+@samp{2002-03-30 23:45}.  These timestamps are shorter than
+@samp{full-iso} timestamps, and are usually good enough for everyday
+work.  This style is equivalent to @samp{+%Y-%m-%d %H:%M}.
+
+@item iso
+List ISO 8601 dates for non-recent timestamps (e.g.,
+@samp{2002-03-30@ }), and ISO 8601-like month, day, hour, and
+minute for recent timestamps (e.g., @samp{03-30 23:45}).  These
+timestamps are uglier than @samp{long-iso} timestamps, but they carry
+nearly the same information in a smaller space and their brevity helps
+@command{ls} output fit within traditional 80-column output lines.
+The following two @command{ls} invocations are equivalent:
+
+@example
+newline='
+'
+ls -l --time-style="+%Y-%m-%d $newline%m-%d %H:%M"
+ls -l --time-style="iso"
+@end example
+
+@item locale
+@vindex LC_TIME
+List timestamps in a locale-dependent form.  For example, a Finnish
+locale might list non-recent timestamps like @samp{maalis 30@ @ 2002}
+and recent timestamps like @samp{maalis 30 23:45}.  Locale-dependent
+timestamps typically consume more space than @samp{iso} timestamps and
+are harder for programs to parse because locale conventions vary so
+widely, but they are easier for many people to read.
+
+The @env{LC_TIME} locale category specifies the timestamp format.  The
+default POSIX locale uses timestamps like @samp{Mar 30@
+@ 2002} and @samp{Mar 30 23:45}; in this locale, the following two
+@command{ls} invocations are equivalent:
+
+@example
+newline='
+'
+ls -l --time-style="+%b %e  %Y$newline%b %e %H:%M"
+ls -l --time-style="locale"
+@end example
+
+Other locales behave differently.  For example, in a German locale,
+@option{--time-style="locale"} might be equivalent to
+@option{--time-style="+%e. %b %Y $newline%e. %b %H:%M"}
+and might generate timestamps like @samp{30. M@"ar 2002@ } and
+@samp{30. M@"ar 23:45}.
+
+@item posix-@var{style}
+@vindex LC_TIME
+List POSIX-locale timestamps if the @env{LC_TIME} locale
+category is POSIX, @var{style} timestamps otherwise.  For
+example, the @samp{posix-long-iso} style lists
+timestamps like @samp{Mar 30@ @ 2002} and @samp{Mar 30 23:45} when in
+the POSIX locale, and like @samp{2002-03-30 23:45} otherwise.
+@end table
+@end table
+
+@vindex TIME_STYLE
+You can specify the default value of the @option{--time-style} option
+with the environment variable @env{TIME_STYLE}; if @env{TIME_STYLE} is not set
+the default style is @samp{locale}.  GNU Emacs 21.3 and
+later use the @option{--dired} option and therefore can parse any date
+format, but if you are using Emacs 21.1 or 21.2 and specify a
+non-POSIX locale you may need to set
+@samp{TIME_STYLE="posix-long-iso"}.
+
+To avoid certain denial-of-service attacks, timestamps that would be
+longer than 1000 bytes may be treated as errors.
+
+
+@node Formatting the file names
+@subsection Formatting the file names
+
+These options change how file names themselves are printed.
+
+@table @samp
+
+@item -b
+@itemx --escape
+@itemx --quoting-style=escape
+@opindex -b
+@opindex --escape
+@opindex --quoting-style
+@cindex backslash sequences for file names
+Quote nongraphic characters in file names using alphabetic and octal
+backslash sequences like those used in C.
+
+@item -N
+@itemx --literal
+@itemx --quoting-style=literal
+@opindex -N
+@opindex --literal
+@opindex --quoting-style
+Do not quote file names.  However, with @command{ls} nongraphic
+characters are still printed as question marks if the output is a
+terminal and you do not specify the @option{--show-control-chars}
+option.
+
+@item -q
+@itemx --hide-control-chars
+@opindex -q
+@opindex --hide-control-chars
+Print question marks instead of nongraphic characters in file names.
+This is the default if the output is a terminal and the program is
+@command{ls}.
+
+@item -Q
+@itemx --quote-name
+@itemx --quoting-style=c
+@opindex -Q
+@opindex --quote-name
+@opindex --quoting-style
+Enclose file names in double quotes and quote nongraphic characters as
+in C.
+
+@item --quoting-style=@var{word}
+@opindex --quoting-style
+@cindex quoting style
+Use style @var{word} to quote file names and other strings that may
+contain arbitrary characters.  The @var{word} should
+be one of the following:
+
+@macro quotingStyles
+@table @samp
+@item literal
+Output strings as-is; this is the same as the @option{-N} or
+@option{--literal} option.
+@item shell
+Quote strings for the shell if they contain shell metacharacters or would
+cause ambiguous output.
+The quoting is suitable for POSIX-compatible shells like
+@command{bash}, but it does not always work for incompatible shells
+like @command{csh}.
+@item shell-always
+Quote strings for the shell, even if they would normally not require quoting.
+@item shell-escape
+Like @samp{shell}, but also quoting non-printable characters using the POSIX
+proposed @samp{$''} syntax suitable for most shells.
+@item shell-escape-always
+Like @samp{shell-escape}, but quote strings even if they would
+normally not require quoting.
+@item c
+Quote strings as for C character string literals, including the
+surrounding double-quote characters; this is the same as the
+@option{-Q} or @option{--quote-name} option.
+@item escape
+Quote strings as for C character string literals, except omit the
+surrounding double-quote
+characters; this is the same as the @option{-b} or @option{--escape} option.
+@item clocale
+Quote strings as for C character string literals, except use
+surrounding quotation marks appropriate for the
+locale.
+@item locale
+@c Use @t instead of @samp to avoid duplicate quoting in some output styles.
+Quote strings as for C character string literals, except use
+surrounding quotation marks appropriate for the locale, and quote
+@t{'like this'} instead of @t{"like
+this"} in the default C locale.  This looks nicer on many displays.
+@end table
+@end macro
+@quotingStyles
+
+You can specify the default value of the @option{--quoting-style} option
+with the environment variable @env{QUOTING_STYLE}@.  If that environment
+variable is not set, the default value is @samp{literal}, but this
+default may change to @samp{shell-escape} in a future version of this package.
+
+@item --show-control-chars
+@opindex --show-control-chars
+Print nongraphic characters as-is in file names.
+This is the default unless the output is a terminal and the program is
+@command{ls}.
+
+@end table
+
+
+@node dir invocation
+@section @command{dir}: Briefly list directory contents
+
+@pindex dir
+@cindex directory listing, brief
+
+@command{dir} is equivalent to @code{ls -C
+-b}; that is, by default files are listed in columns, sorted vertically,
+and special characters are represented by backslash escape sequences.
+
+@xref{ls invocation, @command{ls}}.
+
+
+@node vdir invocation
+@section @command{vdir}: Verbosely list directory contents
+
+@pindex vdir
+@cindex directory listing, verbose
+
+@command{vdir} is equivalent to @code{ls -l
+-b}; that is, by default files are listed in long format and special
+characters are represented by backslash escape sequences.
+
+@xref{ls invocation, @command{ls}}.
+
+@node dircolors invocation
+@section @command{dircolors}: Color setup for @command{ls}
+
+@pindex dircolors
+@cindex color setup
+@cindex setup for color
+
+@command{dircolors} outputs a sequence of shell commands to set up the
+terminal for color output from @command{ls} (and @command{dir}, etc.).
+Typical usage:
+
+@example
+eval "$(dircolors [@var{option}]@dots{} [@var{file}])"
+@end example
+
+If @var{file} is specified, @command{dircolors} reads it to determine which
+colors to use for which file types and extensions.  Otherwise, a
+precompiled database is used.  For details on the format of these files,
+run @samp{dircolors --print-database}.
+
+To make @command{dircolors} read a @file{~/.dircolors} file if it
+exists, you can put the following lines in your @file{~/.bashrc} (or
+adapt them to your favorite shell):
+
+@example
+d=.dircolors
+test -r $d && eval "$(dircolors $d)"
+@end example
+
+@vindex LS_COLORS
+@vindex SHELL @r{environment variable, and color}
+The output is a shell command to set the @env{LS_COLORS} environment
+variable.  You can specify the shell syntax to use on the command line,
+or @command{dircolors} will guess it from the value of the @env{SHELL}
+environment variable.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+@item -b
+@itemx --sh
+@itemx --bourne-shell
+@opindex -b
+@opindex --sh
+@opindex --bourne-shell
+@cindex Bourne shell syntax for color setup
+@cindex @command{sh} syntax for color setup
+Output Bourne shell commands.  This is the default if the @env{SHELL}
+environment variable is set and does not end with @samp{csh} or
+@samp{tcsh}.
+
+@item -c
+@itemx --csh
+@itemx --c-shell
+@opindex -c
+@opindex --csh
+@opindex --c-shell
+@cindex C shell syntax for color setup
+@cindex @command{csh} syntax for color setup
+Output C shell commands.  This is the default if @code{SHELL} ends with
+@command{csh} or @command{tcsh}.
+
+@item -p
+@itemx --print-database
+@opindex -p
+@opindex --print-database
+@cindex color database, printing
+@cindex database for color setup, printing
+@cindex printing color database
+Print the (compiled-in) default color configuration database.  This
+output is itself a valid configuration file, and is fairly descriptive
+of the possibilities.
+
+@end table
+
+@exitstatus
+
+
+@node Basic operations
+@chapter Basic operations
+
+@cindex manipulating files
+
+This chapter describes the commands for basic file manipulation:
+copying, moving (renaming), and deleting (removing).
+
+@menu
+* cp invocation::               Copy files.
+* 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.
+@end menu
+
+
+@node cp invocation
+@section @command{cp}: Copy files and directories
+
+@pindex cp
+@cindex copying files and directories
+@cindex files, copying
+@cindex directories, copying
+
+@command{cp} copies files (or, optionally, directories).  The copy is
+completely independent of the original.  You can either copy one file to
+another, or copy arbitrarily many files to a destination directory.
+Synopses:
+
+@example
+cp [@var{option}]@dots{} [-T] @var{source} @var{dest}
+cp [@var{option}]@dots{} @var{source}@dots{} @var{directory}
+cp [@var{option}]@dots{} -t @var{directory} @var{source}@dots{}
+@end example
+
+@itemize @bullet
+@item
+If two file names are given, @command{cp} copies the first file to the
+second.
+
+@item
+If the @option{--target-directory} (@option{-t}) option is given, or
+failing that if the last file is a directory and the
+@option{--no-target-directory} (@option{-T}) option is not given,
+@command{cp} copies each @var{source} file to the specified directory,
+using the @var{source}s' names.
+@end itemize
+
+Generally, files are written just as they are read.  For exceptions,
+see the @option{--sparse} option below.
+
+By default, @command{cp} does not copy directories.  However, the
+@option{-R}, @option{-a}, and @option{-r} options cause @command{cp} to
+copy recursively by descending into source directories and copying files
+to corresponding destination directories.
+
+When copying from a symbolic link, @command{cp} normally follows the
+link only when not copying recursively or when @option{--link}
+(@option{-l}) is used.  This default can be overridden with the
+@option{--archive} (@option{-a}), @option{-d}, @option{--dereference}
+(@option{-L}), @option{--no-dereference} (@option{-P}), and
+@option{-H} options.  If more than one of these options is specified,
+the last one silently overrides the others.
+
+When copying to a symbolic link, @command{cp} follows the
+link only when it refers to an existing regular file.
+However, when copying to a dangling symbolic link, @command{cp}
+refuses by default, and fails with a diagnostic, since the operation
+is inherently dangerous.  This behavior is contrary to historical
+practice and to POSIX@.
+Set @env{POSIXLY_CORRECT} to make @command{cp} attempt to create
+the target of a dangling destination symlink, in spite of the possible risk.
+Also, when an option like
+@option{--backup} or @option{--link} acts to rename or remove the
+destination before copying, @command{cp} renames or removes the
+symbolic link rather than the file it points to.
+
+By default, @command{cp} copies the contents of special files only
+when not copying recursively.  This default can be overridden with the
+@option{--copy-contents} option.
+
+@cindex self-backups
+@cindex backups, making only
+@command{cp} generally refuses to copy a file onto itself, with the
+following exception: if @option{--force --backup} is specified with
+@var{source} and @var{dest} identical, and referring to a regular file,
+@command{cp} will make a backup file, either regular or numbered, as
+specified in the usual ways (@pxref{Backup options}).  This is useful when
+you simply want to make a backup of an existing file before changing it.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+@item -a
+@itemx --archive
+@opindex -a
+@opindex --archive
+Preserve as much as possible of the structure and attributes of the
+original files in the copy (but do not attempt to preserve internal
+directory structure; i.e., @samp{ls -U} may list the entries in a copied
+directory in a different order).
+Try to preserve SELinux security context and extended attributes (xattr),
+but ignore any failure to do that and print no corresponding diagnostic.
+Equivalent to @option{-dR --preserve=all} with the reduced diagnostics.
+
+@item --attributes-only
+@opindex --attributes-only
+Copy only the specified attributes of the source file to the destination.
+If the destination already exists, do not alter its contents.
+See the @option{--preserve} option for controlling which attributes to copy.
+
+@item -b
+@itemx --backup[=@var{method}]
+@opindex -b
+@opindex --backup
+@vindex VERSION_CONTROL
+@cindex backups, making
+@xref{Backup options}.
+Make a backup of each file that would otherwise be overwritten or removed.
+As a special case, @command{cp} makes a backup of @var{source} when the force
+and backup options are given and @var{source} and @var{dest} are the same
+name for an existing, regular file.  One useful application of this
+combination of options is this tiny Bourne shell script:
+
+@example
+#!/bin/sh
+# Usage: backup FILE...
+# Create a GNU-style backup of each listed FILE.
+fail=0
+for i; do
+  cp --backup --force --preserve=all -- "$i" "$i" || fail=1
+done
+exit $fail
+@end example
+
+@item --copy-contents
+@cindex directories, copying recursively
+@cindex copying directories recursively
+@cindex recursively copying directories
+@cindex non-directories, copying as special files
+If copying recursively, copy the contents of any special files (e.g.,
+FIFOs and device files) as if they were regular files.  This means
+trying to read the data in each source file and writing it to the
+destination.  It is usually a mistake to use this option, as it
+normally has undesirable effects on special files like FIFOs and the
+ones typically found in the @file{/dev} directory.  In most cases,
+@code{cp -R --copy-contents} will hang indefinitely trying to read
+from FIFOs and special files like @file{/dev/console}, and it will
+fill up your destination disk if you use it to copy @file{/dev/zero}.
+This option has no effect unless copying recursively, and it does not
+affect the copying of symbolic links.
+
+@item -d
+@opindex -d
+@cindex symbolic links, copying
+@cindex hard links, preserving
+Copy symbolic links as symbolic links rather than copying the files that
+they point to, and preserve hard links between source files in the copies.
+Equivalent to @option{--no-dereference --preserve=links}.
+
+@item -f
+@itemx --force
+@opindex -f
+@opindex --force
+When copying without this option and an existing destination file cannot
+be opened for writing, the copy fails.  However, with @option{--force},
+when a destination file cannot be opened, @command{cp} then
+tries to recreate the file by first removing it.  Note @option{--force}
+alone will not remove dangling symlinks.
+When this option is combined with
+@option{--link} (@option{-l}) or @option{--symbolic-link}
+(@option{-s}), the destination link is replaced, and unless
+@option{--backup} (@option{-b}) is also given there is no brief
+moment when the destination does not exist.  Also see the
+description of @option{--remove-destination}.
+
+This option is independent of the @option{--interactive} or
+@option{-i} option: neither cancels the effect of the other.
+
+This option is ignored when the @option{--no-clobber} or @option{-n} option
+is also used.
+
+@item -H
+@opindex -H
+If a command line argument specifies a symbolic link, then copy the
+file it points to rather than the symbolic link itself.  However,
+copy (preserving its nature) any symbolic link that is encountered
+via recursive traversal.
+
+@item -i
+@itemx --interactive
+@opindex -i
+@opindex --interactive
+When copying a file other than a directory, prompt whether to
+overwrite an existing destination file.  The @option{-i} option overrides
+a previous @option{-n} option.
+
+@item -l
+@itemx --link
+@opindex -l
+@opindex --link
+Make hard links instead of copies of non-directories.
+
+@item -L
+@itemx --dereference
+@opindex -L
+@opindex --dereference
+Follow symbolic links when copying from them.
+With this option, @command{cp} cannot create a symbolic link.
+For example, a symlink (to regular file) in the source tree will be copied to
+a regular file in the destination tree.
+
+@item -n
+@itemx --no-clobber
+@opindex -n
+@opindex --no-clobber
+Do not overwrite an existing file; silently do nothing instead.
+This option overrides a previous
+@option{-i} option.  This option is mutually exclusive with @option{-b} or
+@option{--backup} option.
+
+@item -P
+@itemx --no-dereference
+@opindex -P
+@opindex --no-dereference
+@cindex symbolic links, copying
+Copy symbolic links as symbolic links rather than copying the files that
+they point to.  This option affects only symbolic links in the source;
+symbolic links in the destination are always followed if possible.
+
+@item -p
+@itemx --preserve[=@var{attribute_list}]
+@opindex -p
+@opindex --preserve
+@cindex file information, preserving, extended attributes, xattr
+Preserve the specified attributes of the original files.
+If specified, the @var{attribute_list} must be a comma-separated list
+of one or more of the following strings:
+
+@table @samp
+@item mode
+Preserve the file mode bits and access control lists.
+@item ownership
+Preserve the owner and group.  On most modern systems,
+only users with appropriate privileges may change the owner of a file,
+and ordinary users
+may preserve the group ownership of a file only if they happen to be
+a member of the desired group.
+@item timestamps
+Preserve the times of last access and last modification, when possible.
+On older systems, it is not possible to preserve these attributes
+when the affected file is a symbolic link.
+However, many systems now provide the @code{utimensat} function,
+which makes it possible even for symbolic links.
+@item links
+Preserve in the destination files
+any links between corresponding source files.
+Note that with @option{-L} or @option{-H}, this option can convert
+symbolic links to hard links.  For example,
+@example
+$ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c
+74161745 a
+74161745 b
+@end example
+@noindent
+Note the inputs: @file{b} is a symlink to regular file @file{a},
+yet the files in destination directory, @file{c/}, are hard-linked.
+Since @option{-a} implies @option{--no-dereference} it would copy the symlink,
+but the later @option{-H} tells @command{cp} to dereference the command line
+arguments where it then sees two files with the same inode number.
+Then the @option{--preserve=links} option also implied by @option{-a}
+will preserve the perceived hard link.
+
+Here is a similar example that exercises @command{cp}'s @option{-L} option:
+@example
+$ mkdir b c; (cd b; : > a; ln -s a b); cp -aL b c; ls -i1 c/b
+74163295 a
+74163295 b
+@end example
+
+@item context
+Preserve SELinux security context of the file, or fail with full diagnostics.
+@item xattr
+Preserve extended attributes of the file, or fail with full diagnostics.
+If @command{cp} is built without xattr support, ignore this option.
+If SELinux context, ACLs or Capabilities are implemented using xattrs,
+they are preserved implicitly by this option as well, i.e., even without
+specifying @option{--preserve=mode} or @option{--preserve=context}.
+@item all
+Preserve all file attributes.
+Equivalent to specifying all of the above, but with the difference
+that failure to preserve SELinux security context or extended attributes
+does not change @command{cp}'s exit status.  In contrast to @option{-a},
+all but @samp{Operation not supported} warnings are output.
+@end table
+
+Using @option{--preserve} with no @var{attribute_list} is equivalent
+to @option{--preserve=mode,ownership,timestamps}.
+
+In the absence of this option, the permissions of existing destination
+files are unchanged.  Each new file is created with the mode of the
+corresponding source file minus the set-user-ID, set-group-ID, and
+sticky bits as the create mode; the operating system then applies either
+the umask or a default ACL, possibly resulting in a more restrictive
+file mode.
+@xref{File permissions}.
+
+@item --no-preserve=@var{attribute_list}
+@cindex file information, preserving
+Do not preserve the specified attributes.  The @var{attribute_list}
+has the same form as for @option{--preserve}.
+
+@item --parents
+@opindex --parents
+@cindex parent directories and @command{cp}
+Form the name of each destination file by appending to the target
+directory a slash and the specified name of the source file.  The last
+argument given to @command{cp} must be the name of an existing directory.
+For example, the command:
+
+@example
+cp --parents a/b/c existing_dir
+@end example
+
+@noindent
+copies the file @file{a/b/c} to @file{existing_dir/a/b/c}, creating
+any missing intermediate directories.
+
+@item -R
+@itemx -r
+@itemx --recursive
+@opindex -R
+@opindex -r
+@opindex --recursive
+@cindex directories, copying recursively
+@cindex copying directories recursively
+@cindex recursively copying directories
+@cindex non-directories, copying as special files
+Copy directories recursively.  By default, do not follow symbolic
+links in the source unless used together with the @option{--link}
+(@option{-l}) option; see the @option{--archive} (@option{-a}), @option{-d},
+@option{--dereference} (@option{-L}), @option{--no-dereference}
+(@option{-P}), and @option{-H} options.  Special files are copied by
+creating a destination file of the same type as the source; see the
+@option{--copy-contents} option.  It is not portable to use
+@option{-r} to copy symbolic links or special files.  On some
+non-GNU systems, @option{-r} implies the equivalent of
+@option{-L} and @option{--copy-contents} for historical reasons.
+Also, it is not portable to use @option{-R} to copy symbolic links
+unless you also specify @option{-P}, as POSIX allows
+implementations that dereference symbolic links by default.
+
+@item --reflink[=@var{when}]
+@opindex --reflink[=@var{when}]
+@cindex COW
+@cindex clone
+@cindex copy on write
+Perform a lightweight, copy-on-write (COW) copy, if supported by the
+file system.  Once it has succeeded, beware that the source and destination
+files share the same disk data blocks as long as they remain unmodified.
+Thus, if a disk I/O error affects data blocks of one of the files,
+the other suffers the same fate.
+
+The @var{when} value can be one of the following:
+
+@table @samp
+@item always
+The default behavior: if the copy-on-write operation is not supported
+then report the failure for each file and exit with a failure status.
+
+@item auto
+If the copy-on-write operation is not supported then fall back
+to the standard copy behavior.
+
+@item never
+Disable copy-on-write operation and use the standard copy behavior.
+@end table
+
+This option is overridden by the @option{--link}, @option{--symbolic-link}
+and @option{--attributes-only} options, thus allowing it to be used
+to configure the default data copying behavior for @command{cp}.
+For example, with the following alias, @command{cp} will use the
+minimum amount of space supported by the file system.
+
+@example
+alias cp='cp --reflink=auto --sparse=always'
+@end example
+
+@item --remove-destination
+@opindex --remove-destination
+Remove each existing destination file before attempting to open it
+(contrast with @option{-f} above).
+
+@item --sparse=@var{when}
+@opindex --sparse=@var{when}
+@cindex sparse files, copying
+@cindex holes, copying files with
+@findex read @r{system call, and holes}
+A @dfn{sparse file} contains @dfn{holes}---a sequence of zero bytes that
+does not occupy any physical disk blocks; the @samp{read} system call
+reads these as zeros.  This can both save considerable disk space and
+increase speed, since many binary files contain lots of consecutive zero
+bytes.  By default, @command{cp} detects holes in input source files via a crude
+heuristic and makes the corresponding output file sparse as well.
+Only regular files may be sparse.
+
+The @var{when} value can be one of the following:
+
+@table @samp
+@item auto
+The default behavior: if the input file is sparse, attempt to make
+the output file sparse, too.  However, if an output file exists but
+refers to a non-regular file, then do not attempt to make it sparse.
+
+@item always
+For each sufficiently long sequence of zero bytes in the input file,
+attempt to create a corresponding hole in the output file, even if the
+input file does not appear to be sparse.
+This is useful when the input file resides on a file system
+that does not support sparse files
+(for example,  @samp{efs} file systems in SGI IRIX 5.3 and earlier),
+but the output file is on a type of file system that does support them.
+Holes may be created only in regular files, so if the destination file
+is of some other type, @command{cp} does not even try to make it sparse.
+
+@item never
+Never make the output file sparse.
+This is useful in creating a file for use with the @command{mkswap} command,
+since such a file must not have any holes.
+@end table
+
+@optStripTrailingSlashes
+
+@item -s
+@itemx --symbolic-link
+@opindex -s
+@opindex --symbolic-link
+@cindex symbolic links, copying with
+Make symbolic links instead of copies of non-directories.  All source
+file names must be absolute (starting with @samp{/}) unless the
+destination files are in the current directory.  This option merely
+results in an error message on systems that do not support symbolic links.
+
+@optBackupSuffix
+
+@optTargetDirectory
+
+@optNoTargetDirectory
+
+@item -u
+@itemx --update
+@opindex -u
+@opindex --update
+@cindex newer files, copying only
+Do not copy a non-directory that has an existing destination with the
+same or newer modification timestamp.  If timestamps are being preserved,
+the comparison is to the source timestamp truncated to the
+resolutions of the destination file system and of the system calls
+used to update timestamps; this avoids duplicate work if several
+@samp{cp -pu} commands are executed with the same source and destination.
+This option is ignored if the @option{-n} or @option{--no-clobber}
+option is also specified.
+Also, if @option{--preserve=links} is also specified (like with @samp{cp -au}
+for example), that will take precedence; consequently, depending on the
+order that files are processed from the source, newer files in the destination
+may be replaced, to mirror hard links in the source.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Print the name of each file before copying it.
+
+@item -x
+@itemx --one-file-system
+@opindex -x
+@opindex --one-file-system
+@cindex file systems, omitting copying to different
+Skip subdirectories that are on different file systems from the one that
+the copy started on.
+However, mount point directories @emph{are} copied.
+
+@macro optContext
+@item -Z
+@itemx --context[=@var{context}]
+@opindex -Z
+@opindex --context
+@cindex SELinux, setting/restoring security context
+@cindex security context
+Without a specified @var{context}, adjust the SELinux security context according
+to the system default type for destination files, similarly to the
+@command{restorecon} command.
+The long form of this option with a specific context specified,
+will set the context for newly created files only.
+With a specified context, if both SELinux and SMACK are disabled, a warning is
+issued.
+@end macro
+@optContext
+This option is mutually exclusive with the @option{--preserve=context}
+option, and overrides the @option{--preserve=all} and @option{-a} options.
+
+@end table
+
+@exitstatus
+
+
+@node dd invocation
+@section @command{dd}: Convert and copy a file
+
+@pindex dd
+@cindex converting while copying a file
+
+@command{dd} copies a file (from standard input to standard output, by
+default) with a changeable I/O block size, while optionally performing
+conversions on it.  Synopses:
+
+@example
+dd [@var{operand}]@dots{}
+dd @var{option}
+@end example
+
+The only options are @option{--help} and @option{--version}.
+@xref{Common options}.  @command{dd} accepts the following operands,
+whose syntax was inspired by the DD (data definition) statement of
+OS/360 JCL.
+
+@table @samp
+
+@item if=@var{file}
+@opindex if
+Read from @var{file} instead of standard input.
+
+@item of=@var{file}
+@opindex of
+Write to @var{file} instead of standard output.  Unless
+@samp{conv=notrunc} is given, @command{dd} truncates @var{file} to zero
+bytes (or the size specified with @samp{seek=}).
+
+@item ibs=@var{bytes}
+@opindex ibs
+@cindex block size of input
+@cindex input block size
+Set the input block size to @var{bytes}.
+This makes @command{dd} read @var{bytes} per block.
+The default is 512 bytes.
+
+@item obs=@var{bytes}
+@opindex obs
+@cindex block size of output
+@cindex output block size
+Set the output block size to @var{bytes}.
+This makes @command{dd} write @var{bytes} per block.
+The default is 512 bytes.
+
+@item bs=@var{bytes}
+@opindex bs
+@cindex block size
+Set both input and output block sizes to @var{bytes}.
+This makes @command{dd} read and write @var{bytes} per block,
+overriding any @samp{ibs} and @samp{obs} settings.
+In addition, if no data-transforming @option{conv} operand is specified,
+input is copied to the output as soon as it's read,
+even if it is smaller than the block size.
+
+@item cbs=@var{bytes}
+@opindex cbs
+@cindex block size of conversion
+@cindex conversion block size
+@cindex fixed-length records, converting to variable-length
+@cindex variable-length records, converting to fixed-length
+Set the conversion block size to @var{bytes}.
+When converting variable-length records to fixed-length ones
+(@option{conv=block}) or the reverse (@option{conv=unblock}),
+use @var{bytes} as the fixed record length.
+
+@item skip=@var{n}
+@opindex skip
+Skip @var{n} @samp{ibs}-byte blocks in the input file before copying.
+If @samp{iflag=skip_bytes} is specified, @var{n} is interpreted
+as a byte count rather than a block count.
+
+@item seek=@var{n}
+@opindex seek
+Skip @var{n} @samp{obs}-byte blocks in the output file before copying.
+if @samp{oflag=seek_bytes} is specified, @var{n} is interpreted
+as a byte count rather than a block count.
+
+@item count=@var{n}
+@opindex count
+Copy @var{n} @samp{ibs}-byte blocks from the input file, instead
+of everything until the end of the file.
+if @samp{iflag=count_bytes} is specified, @var{n} is interpreted
+as a byte count rather than a block count.
+Note if the input may return short reads as could be the case
+when reading from a pipe for example, @samp{iflag=fullblock}
+will ensure that @samp{count=} corresponds to complete input blocks
+rather than the traditional POSIX specified behavior of counting
+input read operations.
+
+@item status=@var{level}
+@opindex status
+Specify the amount of information printed.
+If this operand is given multiple times, the last one takes precedence.
+The @var{level} value can be one of the following:
+
+@table @samp
+
+@item none
+@opindex none @r{dd status=}
+Do not print any informational or warning messages to stderr.
+Error messages are output as normal.
+
+@item noxfer
+@opindex noxfer @r{dd status=}
+Do not print the final transfer rate and volume statistics
+that normally make up the last status line.
+
+@item progress
+@opindex progress @r{dd status=}
+Print the transfer rate and volume statistics on stderr,
+when processing each input block.  Statistics are output
+on a single line at most once every second, but updates
+can be delayed when waiting on I/O.
+
+@end table
+
+Transfer information is normally output to stderr upon
+receipt of the @samp{INFO} signal or when @command{dd} exits,
+and defaults to the following form in the C locale:
+
+@example
+7287+1 records in
+116608+0 records out
+59703296 bytes (60 MB, 57 MiB) copied, 0.0427974 s, 1.4 GB/s
+@end example
+
+The notation @samp{@var{w}+@var{p}} stands for @var{w} whole blocks
+and @var{p} partial blocks.  A partial block occurs when a read or
+write operation succeeds but transfers less data than the block size.
+An additional line like @samp{1 truncated record} or @samp{10
+truncated records} is output after the @samp{records out} line if
+@samp{conv=block} processing truncated one or more input records.
+
+@item conv=@var{conversion}[,@var{conversion}]@dots{}
+@opindex conv
+Convert the file as specified by the @var{conversion} argument(s).
+(No spaces around any comma(s).)
+
+Conversions:
+
+@table @samp
+
+@item ascii
+@opindex ascii@r{, converting to}
+Convert EBCDIC to ASCII,
+using the conversion table specified by POSIX@.
+This provides a 1:1 translation for all 256 bytes.
+This implies @samp{conv=unblock}; input is converted to
+ASCII before trailing spaces are deleted.
+
+@item ebcdic
+@opindex ebcdic@r{, converting to}
+Convert ASCII to EBCDIC@.
+This is the inverse of the @samp{ascii} conversion.
+This implies @samp{conv=block}; trailing spaces are added
+before being converted to EBCDIC@.
+
+@item ibm
+@opindex alternate ebcdic@r{, converting to}
+This acts like @samp{conv=ebcdic}, except it
+uses the alternate conversion table specified by POSIX@.
+This is not a 1:1 translation, but reflects common historical practice
+for @samp{~}, @samp{[}, and @samp{]}.
+
+The @samp{ascii}, @samp{ebcdic}, and @samp{ibm} conversions are
+mutually exclusive.  If you use any of these conversions, you should also
+use the @samp{cbs=} operand.
+
+@item block
+@opindex block @r{(space-padding)}
+For each line in the input, output @samp{cbs} bytes, replacing the
+input newline with a space and truncating or padding input lines with
+spaces as necessary.
+
+@item unblock
+@opindex unblock
+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.
+
+@item lcase
+@opindex lcase@r{, converting to}
+Change uppercase letters to lowercase.
+
+@item ucase
+@opindex ucase@r{, converting to}
+Change lowercase letters to uppercase.
+
+The @samp{lcase} and @samp{ucase} conversions are mutually exclusive.
+
+@item sparse
+@opindex sparse
+Try to seek rather than write NUL output blocks.
+On a file system that supports sparse files, this will create
+sparse output when extending the output file.
+Be careful when using this conversion in conjunction with
+@samp{conv=notrunc} or @samp{oflag=append}.
+With @samp{conv=notrunc}, existing data in the output file
+corresponding to NUL blocks from the input, will be untouched.
+With @samp{oflag=append} the seeks performed will be ineffective.
+Similarly, when the output is a device rather than a file,
+NUL input blocks are not copied, and therefore this conversion
+is most useful with virtual or pre zeroed devices.
+
+@item swab
+@opindex swab @r{(byte-swapping)}
+@cindex byte-swapping
+Swap every pair of input bytes.  GNU @command{dd}, unlike others, works
+when an odd number of bytes are read---the last byte is simply copied
+(since there is nothing to swap it with).
+
+@item sync
+@opindex sync @r{(padding with ASCII NULs)}
+Pad every input block to size of @samp{ibs} with trailing zero bytes.
+When used with @samp{block} or @samp{unblock}, pad with spaces instead of
+zero bytes.
+
+@end table
+
+The following ``conversions'' are really file flags
+and don't affect internal processing:
+
+@table @samp
+@item excl
+@opindex excl
+@cindex creating output file, requiring
+Fail if the output file already exists; @command{dd} must create the
+output file itself.
+
+@item nocreat
+@opindex nocreat
+@cindex creating output file, avoiding
+Do not create the output file; the output file must already exist.
+
+The @samp{excl} and @samp{nocreat} conversions are mutually exclusive.
+
+@item notrunc
+@opindex notrunc
+@cindex truncating output file, avoiding
+Do not truncate the output file.
+
+@item noerror
+@opindex noerror
+@cindex read errors, ignoring
+Continue after read errors.
+
+@item fdatasync
+@opindex fdatasync
+@cindex synchronized data writes, before finishing
+Synchronize output data just before finishing.  This forces a physical
+write of output data.
+
+@item fsync
+@opindex fsync
+@cindex synchronized data and metadata writes, before finishing
+Synchronize output data and metadata just before finishing.  This
+forces a physical write of output data and metadata.
+
+@end table
+
+@item iflag=@var{flag}[,@var{flag}]@dots{}
+@opindex iflag
+Access the input file using the flags specified by the @var{flag}
+argument(s).  (No spaces around any comma(s).)
+
+@item oflag=@var{flag}[,@var{flag}]@dots{}
+@opindex oflag
+Access the output file using the flags specified by the @var{flag}
+argument(s).  (No spaces around any comma(s).)
+
+Here are the flags.  Not every flag is supported on every operating
+system.
+
+@table @samp
+
+@item append
+@opindex append
+@cindex appending to the output file
+Write in append mode, so that even if some other process is writing to
+this file, every @command{dd} write will append to the current
+contents of the file.  This flag makes sense only for output.
+If you combine this flag with the @samp{of=@var{file}} operand,
+you should also specify @samp{conv=notrunc} unless you want the
+output file to be truncated before being appended to.
+
+@item cio
+@opindex cio
+@cindex concurrent I/O
+Use concurrent I/O mode for data.  This mode performs direct I/O
+and drops the POSIX requirement to serialize all I/O to the same file.
+A file cannot be opened in CIO mode and with a standard open at the
+same time.
+
+@item direct
+@opindex direct
+@cindex direct I/O
+Use direct I/O for data, avoiding the buffer cache.
+Note that the kernel may impose restrictions on read or write buffer sizes.
+For example, with an ext4 destination file system and a Linux-based kernel,
+using @samp{oflag=direct} will cause writes to fail with @code{EINVAL} if the
+output buffer size is not a multiple of 512.
+
+@item directory
+@opindex directory
+@cindex directory I/O
+
+Fail unless the file is a directory.  Most operating systems do not
+allow I/O to a directory, so this flag has limited utility.
+
+@item dsync
+@opindex dsync
+@cindex synchronized data reads
+Use synchronized I/O for data.  For the output file, this forces a
+physical write of output data on each write.  For the input file,
+this flag can matter when reading from a remote file that has been
+written to synchronously by some other process.  Metadata (e.g.,
+last-access and last-modified time) is not necessarily synchronized.
+
+@item sync
+@opindex sync
+@cindex synchronized data and metadata I/O
+Use synchronized I/O for both data and metadata.
+
+@item nocache
+@opindex nocache
+@cindex discarding file cache
+Request to discard the system data cache for a file.
+When count=0 all cached data for the file is specified,
+otherwise the cache is dropped for the processed
+portion of the file.  Also when count=0,
+failure to discard the cache is diagnosed
+and reflected in the exit status.
+
+Note data that is not already persisted to storage will not
+be discarded from cache, so note the use of the @samp{sync} conversions
+in the examples below, which are used to maximize the
+effectiveness of the @samp{nocache} flag.
+
+Here are some usage examples:
+
+@example
+# Advise to drop cache for whole file
+dd if=ifile iflag=nocache count=0
+
+# Ensure drop cache for the whole file
+dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
+
+# Advise to drop cache for part of file
+# Note the kernel will only consider complete and
+# already persisted pages.
+dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
+
+# Stream data using just the read-ahead cache.
+# See also the @samp{direct} flag.
+dd if=ifile of=ofile iflag=nocache oflag=nocache,sync
+@end example
+
+@item nonblock
+@opindex nonblock
+@cindex nonblocking I/O
+Use non-blocking I/O.
+
+@item noatime
+@opindex noatime
+@cindex access timestamp
+Do not update the file's access timestamp.
+@xref{File timestamps}.
+Some older file systems silently ignore this flag, so it is a good
+idea to test it on your files before relying on it.
+
+@item noctty
+@opindex noctty
+@cindex controlling terminal
+Do not assign the file to be a controlling terminal for @command{dd}.
+This has no effect when the file is not a terminal.
+On many hosts (e.g., GNU/Linux hosts), this flag has no effect
+at all.
+
+@item nofollow
+@opindex nofollow
+@cindex symbolic links, following
+Do not follow symbolic links.
+
+@item nolinks
+@opindex nolinks
+@cindex hard links
+Fail if the file has multiple hard links.
+
+@item binary
+@opindex binary
+@cindex binary I/O
+Use binary I/O@.  This flag has an effect only on nonstandard
+platforms that distinguish binary from text I/O.
+
+@item text
+@opindex text
+@cindex text I/O
+Use text I/O@.  Like @samp{binary}, this flag has no effect on
+standard platforms.
+
+@item fullblock
+@opindex fullblock
+Accumulate full blocks from input.  The @code{read} system call
+may return early if a full block is not available.
+When that happens, continue calling @code{read} to fill the remainder
+of the block.
+This flag can be used only with @code{iflag}.
+This flag is useful with pipes for example
+as they may return short reads. In that case,
+this flag is needed to ensure that a @samp{count=} argument is
+interpreted as a block count rather than a count of read operations.
+
+@item count_bytes
+@opindex count_bytes
+Interpret the @samp{count=} operand as a byte count,
+rather than a block count, which allows specifying
+a length that is not a multiple of the I/O block size.
+This flag can be used only with @code{iflag}.
+
+@item skip_bytes
+@opindex skip_bytes
+Interpret the @samp{skip=} operand as a byte count,
+rather than a block count, which allows specifying
+an offset that is not a multiple of the I/O block size.
+This flag can be used only with @code{iflag}.
+
+@item seek_bytes
+@opindex seek_bytes
+Interpret the @samp{seek=} operand as a byte count,
+rather than a block count, which allows specifying
+an offset that is not a multiple of the I/O block size.
+This flag can be used only with @code{oflag}.
+
+@end table
+
+These flags are not supported on all systems, and @samp{dd} rejects
+attempts to use them when they are not supported.  When reading from
+standard input or writing to standard output, the @samp{nofollow} and
+@samp{noctty} flags should not be specified, and the other flags
+(e.g., @samp{nonblock}) can affect how other processes behave with the
+affected file descriptors, even after @command{dd} exits.
+
+@end table
+
+@cindex multipliers after numbers
+The numeric-valued strings above (@var{n} and @var{bytes})
+can be followed by a multiplier: @samp{b}=512, @samp{c}=1,
+@samp{w}=2, @samp{x@var{m}}=@var{m}, or any of the
+standard block size suffixes like @samp{k}=1024 (@pxref{Block size}).
+
+Any block size you specify via @samp{bs=}, @samp{ibs=}, @samp{obs=}, @samp{cbs=}
+should not be too large---values larger than a few megabytes
+are generally wasteful or (as in the gigabyte..exabyte case) downright
+counterproductive or error-inducing.
+
+To process data that is at an offset or size that is not a
+multiple of the I/O@ block size, you can use the @samp{skip_bytes},
+@samp{seek_bytes} and @samp{count_bytes} flags.  Alternatively
+the traditional method of separate @command{dd} invocations can be used.
+For example, the following shell commands copy data
+in 512 KiB blocks between a disk and a tape, but do not save
+or restore a 4 KiB label at the start of the disk:
+
+@example
+disk=/dev/rdsk/c0t1d0s2
+tape=/dev/rmt/0
+
+# Copy all but the label from disk to tape.
+(dd bs=4k skip=1 count=0 && dd bs=512k) <$disk >$tape
+
+# Copy from tape back to disk, but leave the disk label alone.
+(dd bs=4k seek=1 count=0 && dd bs=512k) <$tape >$disk
+@end example
+
+@cindex ddrescue
+@cindex disks, failing
+For failing disks, other tools come with a great variety of extra
+functionality to ease the saving of as much data as possible before the
+disk finally dies, e.g.
+@uref{https://www.gnu.org/software/ddrescue/, GNU @command{ddrescue}}.
+However, in some cases such a tool is not available or the administrator
+feels more comfortable with the handling of @command{dd}.
+As a simple rescue method, call @command{dd} as shown in the following
+example: the operand @samp{conv=noerror,sync} is used to continue
+after read errors and to pad out bad reads with NULs, while
+@samp{iflag=fullblock} caters for short reads (which traditionally never
+occur on disk based devices):
+
+@example
+# Rescue data from an (unmounted!) partition of a failing disk.
+dd conv=noerror,sync iflag=fullblock </dev/sda1 > /mnt/rescue.img
+@end example
+
+Sending an @samp{INFO} signal (or @samp{USR1} signal where that is unavailable)
+to a running @command{dd} process makes it print I/O statistics to
+standard error and then resume copying.   In the example below,
+@command{dd} is run in the background to copy 5GB of data.
+The @command{kill} command makes it output intermediate I/O statistics,
+and when @command{dd} completes normally or is killed by the
+@code{SIGINT} signal, it outputs the final statistics.
+
+@example
+# Ignore the signal so we never inadvertently terminate the dd child.
+# Note this is not needed when SIGINFO is available.
+trap '' USR1
+
+# Run dd with the fullblock iflag to avoid short reads
+# which can be triggered by reception of signals.
+dd iflag=fullblock if=/dev/zero of=/dev/null count=5000000 bs=1000 & pid=$!
+
+# Output stats every second.
+while kill -s USR1 $pid 2>/dev/null; do sleep 1; done
+@end example
+
+The above script will output in the following format:
+
+@example
+3441325+0 records in
+3441325+0 records out
+3441325000 bytes (3.4 GB, 3.2 GiB) copied, 1.00036 s, 3.4 GB/s
+5000000+0 records in
+5000000+0 records out
+5000000000 bytes (5.0 GB, 4.7 GiB) copied, 1.44433 s, 3.5 GB/s
+@end example
+
+The @samp{status=progress} operand periodically updates the last line
+of the transfer statistics above.
+
+@vindex POSIXLY_CORRECT
+On systems lacking the @samp{INFO} signal @command{dd} responds to the
+@samp{USR1} signal instead, unless the @env{POSIXLY_CORRECT}
+environment variable is set.
+
+@exitstatus
+
+
+@node install invocation
+@section @command{install}: Copy files and set attributes
+
+@pindex install
+@cindex copying files and setting attributes
+
+@command{install} copies files while setting their file mode bits and, if
+possible, their owner and group.  Synopses:
+
+@example
+install [@var{option}]@dots{} [-T] @var{source} @var{dest}
+install [@var{option}]@dots{} @var{source}@dots{} @var{directory}
+install [@var{option}]@dots{} -t @var{directory} @var{source}@dots{}
+install [@var{option}]@dots{} -d @var{directory}@dots{}
+@end example
+
+@itemize @bullet
+@item
+If two file names are given, @command{install} copies the first file to the
+second.
+
+@item
+If the @option{--target-directory} (@option{-t}) option is given, or
+failing that if the last file is a directory and the
+@option{--no-target-directory} (@option{-T}) option is not given,
+@command{install} copies each @var{source} file to the specified
+directory, using the @var{source}s' names.
+
+@item
+If the @option{--directory} (@option{-d}) option is given,
+@command{install} creates each @var{directory} and any missing parent
+directories.  Parent directories are created with mode
+@samp{u=rwx,go=rx} (755), regardless of the @option{-m} option or the
+current umask.  @xref{Directory Setuid and Setgid}, for how the
+set-user-ID and set-group-ID bits of parent directories are inherited.
+@end itemize
+
+@cindex Makefiles, installing programs in
+@command{install} is similar to @command{cp}, but allows you to control the
+attributes of destination files.  It is typically used in Makefiles to
+copy programs into their destination directories.  It refuses to copy
+files onto themselves.
+
+@cindex extended attributes, xattr
+@command{install} never preserves extended attributes (xattr).
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@optBackup
+
+@item -C
+@itemx --compare
+@opindex -C
+@opindex --compare
+Compare each pair of source and destination files, and if the destination has
+identical content and any specified owner, group, permissions, and possibly
+SELinux context, then do not modify the destination at all.
+Note this option is best used in conjunction with @option{--user},
+@option{--group} and @option{--mode} options, lest @command{install}
+incorrectly determines the default attributes that installed files would have
+(as it doesn't consider setgid directories and POSIX default ACLs for example).
+This could result in redundant copies or attributes that are not reset to the
+correct defaults.
+
+@item -c
+@opindex -c
+Ignored; for compatibility with old Unix versions of @command{install}.
+
+@item -D
+@opindex -D
+Create any missing parent directories of @var{dest},
+then copy @var{source} to @var{dest}.
+Explicitly specifying the @option{--target-directory=@var{dir}} will similarly
+ensure the presence of that hierarchy before copying @var{source} arguments.
+
+@item -d
+@itemx --directory
+@opindex -d
+@opindex --directory
+@cindex directories, creating with given attributes
+@cindex parent directories, creating missing
+@cindex leading directories, creating missing
+Create any missing parent directories, giving them the default
+attributes.  Then create each given directory, setting their owner,
+group and mode as given on the command line or to the defaults.
+
+@item -g @var{group}
+@itemx --group=@var{group}
+@opindex -g
+@opindex --group
+@cindex group ownership of installed files, setting
+Set the group ownership of installed files or directories to
+@var{group}.  The default is the process's current group.  @var{group}
+may be either a group name or a numeric group ID.
+
+@item -m @var{mode}
+@itemx --mode=@var{mode}
+@opindex -m
+@opindex --mode
+@cindex permissions of installed files, setting
+Set the file mode bits for the installed file or directory to @var{mode},
+which can be either an octal number, or a symbolic mode as in
+@command{chmod}, with @samp{a=} (no access allowed to anyone) as the
+point of departure (@pxref{File permissions}).
+The default mode is @samp{u=rwx,go=rx,a-s}---read, write, and
+execute for the owner, read and execute for group and other, and with
+set-user-ID and set-group-ID disabled.
+This default is not quite the same as @samp{755}, since it disables
+instead of preserving set-user-ID and set-group-ID on directories.
+@xref{Directory Setuid and Setgid}.
+
+@item -o @var{owner}
+@itemx --owner=@var{owner}
+@opindex -o
+@opindex --owner
+@cindex ownership of installed files, setting
+@cindex appropriate privileges
+@vindex root @r{as default owner}
+If @command{install} has appropriate privileges (is run as root), set the
+ownership of installed files or directories to @var{owner}.  The default
+is @code{root}.  @var{owner} may be either a user name or a numeric user
+ID.
+
+@item --preserve-context
+@opindex --preserve-context
+@cindex SELinux
+@cindex security context
+Preserve the SELinux security context of files and directories.
+Failure to preserve the context in all of the files or directories
+will result in an exit status of 1.  If SELinux is disabled then
+print a warning and ignore the option.
+
+@item -p
+@itemx --preserve-timestamps
+@opindex -p
+@opindex --preserve-timestamps
+@cindex timestamps of installed files, preserving
+Set the time of last access and the time of last modification of each
+installed file to match those of each corresponding original file.
+When a file is installed without this option, its last access and
+last modification timestamps are both set to the time of installation.
+This option is useful if you want to use the last modification timestamps
+of installed files to keep track of when they were last built as opposed
+to when they were last installed.
+
+@item -s
+@itemx --strip
+@opindex -s
+@opindex --strip
+@cindex symbol table information, stripping
+@cindex stripping symbol table information
+Strip the symbol tables from installed binary executables.
+
+@item --strip-program=@var{program}
+@opindex --strip-program
+@cindex symbol table information, stripping, program
+Program used to strip binaries.
+
+@optBackupSuffix
+
+@optTargetDirectory
+Also specifying the @option{-D} option will ensure the directory is present.
+
+@optNoTargetDirectory
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Print the name of each file before copying it.
+
+@optContext
+This option is mutually exclusive with the @option{--preserve-context} option.
+
+
+@end table
+
+@exitstatus
+
+
+@node mv invocation
+@section @command{mv}: Move (rename) files
+
+@pindex mv
+
+@command{mv} moves or renames files (or directories).  Synopses:
+
+@example
+mv [@var{option}]@dots{} [-T] @var{source} @var{dest}
+mv [@var{option}]@dots{} @var{source}@dots{} @var{directory}
+mv [@var{option}]@dots{} -t @var{directory} @var{source}@dots{}
+@end example
+
+@itemize @bullet
+@item
+If two file names are given, @command{mv} moves the first file to the
+second.
+
+@item
+If the @option{--target-directory} (@option{-t}) option is given, or
+failing that if the last file is a directory and the
+@option{--no-target-directory} (@option{-T}) option is not given,
+@command{mv} moves each @var{source} file to the specified
+directory, using the @var{source}s' names.
+@end itemize
+
+@command{mv} can move any type of file from one file system to another.
+Prior to version @code{4.0} of the fileutils,
+@command{mv} could move only regular files between file systems.
+For example, now @command{mv} can move an entire directory hierarchy
+including special device files from one partition to another.  It first
+uses some of the same code that's used by @code{cp -a} to copy the
+requested directories and files, then (assuming the copy succeeded)
+it removes the originals.  If the copy fails, then the part that was
+copied to the destination partition is removed.  If you were to copy
+three directories from one partition to another and the copy of the first
+directory succeeded, but the second didn't, the first would be left on
+the destination partition and the second and third would be left on the
+original partition.
+
+@cindex extended attributes, xattr
+@command{mv} always tries to copy extended attributes (xattr), which may
+include SELinux context, ACLs or Capabilities.
+Upon failure all but @samp{Operation not supported} warnings are output.
+
+@cindex prompting, and @command{mv}
+If a destination file exists but is normally unwritable, standard input
+is a terminal, and the @option{-f} or @option{--force} option is not given,
+@command{mv} prompts the user for whether to replace the file.  (You might
+own the file, or have write permission on its directory.)  If the
+response is not affirmative, the file is skipped.
+
+@emph{Warning}: Avoid specifying a source name with a trailing slash,
+when it might be a symlink to a directory.
+Otherwise, @command{mv} may do something very surprising, since
+its behavior depends on the underlying rename system call.
+On a system with a modern Linux-based kernel, it fails with
+@code{errno=ENOTDIR}@.
+However, on other systems (at least FreeBSD 6.1 and Solaris 10) it silently
+renames not the symlink but rather the directory referenced by the symlink.
+@xref{Trailing slashes}.
+
+@emph{Note}: @command{mv} will only replace empty directories in the
+destination.  Conflicting populated directories are skipped with a diagnostic.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@optBackup
+
+@item -f
+@itemx --force
+@opindex -f
+@opindex --force
+@cindex prompts, omitting
+Do not prompt the user before removing a destination file.
+@macro mvOptsIfn
+If you specify more than one of the @option{-i}, @option{-f}, @option{-n}
+options, only the final one takes effect.
+@end macro
+@mvOptsIfn
+
+@item -i
+@itemx --interactive
+@opindex -i
+@opindex --interactive
+@cindex prompts, forcing
+Prompt whether to overwrite each existing destination file, regardless
+of its permissions.
+If the response is not affirmative, the file is skipped.
+@mvOptsIfn
+
+@item -n
+@itemx --no-clobber
+@opindex -n
+@opindex --no-clobber
+@cindex prompts, omitting
+Do not overwrite an existing file; silently do nothing instead.
+@mvOptsIfn
+This option is mutually exclusive with @option{-b} or @option{--backup} option.
+
+@item -u
+@itemx --update
+@opindex -u
+@opindex --update
+@cindex newer files, moving only
+Do not move a non-directory that has an existing destination with the
+same or newer modification timestamp.
+If the move is across file system boundaries, the comparison is to the
+source timestamp truncated to the resolutions of the destination file
+system and of the system calls used to update timestamps; this avoids
+duplicate work if several @samp{mv -u} commands are executed with the
+same source and destination.
+This option is ignored if the @option{-n} or @option{--no-clobber}
+option is also specified.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Print the name of each file before moving it.
+
+@optStripTrailingSlashes
+
+@optBackupSuffix
+
+@optTargetDirectory
+
+@optNoTargetDirectory
+
+@item -Z
+@itemx --context
+@opindex -Z
+@opindex --context
+@cindex SELinux, restoring security context
+@cindex security context
+This option functions similarly to the @command{restorecon} command,
+by adjusting the SELinux security context according
+to the system default type for destination files and each created directory.
+
+@end table
+
+@exitstatus
+
+
+@node rm invocation
+@section @command{rm}: Remove files or directories
+
+@pindex rm
+@cindex removing files or directories
+
+@command{rm} removes each given @var{file}.  By default, it does not remove
+directories.  Synopsis:
+
+@example
+rm [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+@cindex prompting, and @command{rm}
+If the @option{-I} or @option{--interactive=once} option is given,
+and there are more than three files or the @option{-r}, @option{-R},
+or @option{--recursive} are given, then @command{rm} prompts the user
+for whether to proceed with the entire operation.  If the response is
+not affirmative, the entire command is aborted.
+
+Otherwise, if a file is unwritable, standard input is a terminal, and
+the @option{-f} or @option{--force} option is not given, or the
+@option{-i} or @option{--interactive=always} option @emph{is} given,
+@command{rm} prompts the user for whether to remove the file.
+If the response is not affirmative, the file is skipped.
+
+Any attempt to remove a file whose last file name component is
+@file{.} or @file{..} is rejected without any prompting, as mandated
+by POSIX.
+
+@emph{Warning}: If you use @command{rm} to remove a file, it is usually
+possible to recover the contents of that file.  If you want more assurance
+that the contents are unrecoverable, consider using @command{shred}.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -d
+@itemx --dir
+@opindex -d
+@opindex --dir
+@cindex directories, removing
+Remove the listed directories if they are empty.
+
+@item -f
+@itemx --force
+@opindex -f
+@opindex --force
+Ignore nonexistent files and missing operands, and never prompt the user.
+Ignore any previous @option{--interactive} (@option{-i}) option.
+
+@item -i
+@opindex -i
+Prompt whether to remove each file.
+If the response is not affirmative, the file is skipped.
+Ignore any previous @option{--force} (@option{-f}) option.
+Equivalent to @option{--interactive=always}.
+
+@item -I
+@opindex -I
+Prompt once whether to proceed with the command, if more than three
+files are named or if a recursive removal is requested.  Ignore any
+previous @option{--force} (@option{-f}) option.  Equivalent to
+@option{--interactive=once}.
+
+@item --interactive [=@var{when}]
+@opindex --interactive
+Specify when to issue an interactive prompt.  @var{when} may be
+omitted, or one of:
+@itemize @bullet
+@item never
+@vindex never @r{interactive option}
+- Do not prompt at all.
+@item once
+@vindex once @r{interactive option}
+- Prompt once if more than three files are named or if a recursive
+removal is requested.  Equivalent to @option{-I}.
+@item always
+@vindex always @r{interactive option}
+- Prompt for every file being removed.  Equivalent to @option{-i}.
+@end itemize
+@option{--interactive} with no @var{when} is equivalent to
+@option{--interactive=always}.
+
+@item --one-file-system
+@opindex --one-file-system
+@cindex one file system, restricting @command{rm} to
+When removing a hierarchy recursively, skip any directory that is on a
+file system different from that of the corresponding command line argument.
+@cindex bind mount
+This option is useful when removing a build ``chroot'' hierarchy,
+which normally contains no valuable data.  However, it is not uncommon
+to bind-mount @file{/home} into such a hierarchy, to make it easier to
+use one's start-up file.  The catch is that it's easy to forget to
+unmount @file{/home}.  Then, when you use @command{rm -rf} to remove
+your normally throw-away chroot, that command will remove everything
+under @file{/home}, too.
+Use the @option{--one-file-system} option, and it will
+warn about and skip directories on other file systems.
+Of course, this will not save your @file{/home} if it and your
+chroot happen to be on the same file system.
+See also @option{--preserve-root=all} to protect command line arguments
+themselves.
+
+@item --preserve-root [=all]
+@opindex --preserve-root
+@cindex root directory, disallow recursive destruction
+Fail upon any attempt to remove the root directory, @file{/},
+when used with the @option{--recursive} option.
+This is the default behavior.
+@xref{Treating / specially}.
+When @samp{all} is specified, reject any command line argument
+that is not on the same file system as its parent.
+
+@item --no-preserve-root
+@opindex --no-preserve-root
+@cindex root directory, allow recursive destruction
+Do not treat @file{/} specially when removing recursively.
+This option is not recommended unless you really want to
+remove all the files on your computer.
+@xref{Treating / specially}.
+
+@item -r
+@itemx -R
+@itemx --recursive
+@opindex -r
+@opindex -R
+@opindex --recursive
+@cindex directories, removing (recursively)
+Remove the listed directories and their contents recursively.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Print the name of each file before removing it.
+
+@end table
+
+@cindex files beginning with @samp{-}, removing
+@cindex @samp{-}, removing files beginning with
+One common question is how to remove files whose names begin with a
+@samp{-}.  GNU @command{rm}, like every program that uses the @code{getopt}
+function to parse its arguments, lets you use the @samp{--} option to
+indicate that all following arguments are non-options.  To remove a file
+called @file{-f} in the current directory, you could type either:
+
+@example
+rm -- -f
+@end example
+
+@noindent
+or:
+
+@example
+rm ./-f
+@end example
+
+@opindex - @r{and Unix @command{rm}}
+The Unix @command{rm} program's use of a single @samp{-} for this purpose
+predates the development of the @code{getopt} standard syntax.
+
+@exitstatus
+
+
+@node shred invocation
+@section @command{shred}: Remove files more securely
+
+@pindex shred
+@cindex data, erasing
+@cindex erasing data
+
+@command{shred} overwrites devices or files, to help prevent even
+extensive forensics from recovering the data.
+
+Ordinarily when you remove a file (@pxref{rm invocation}), its data
+and metadata are not actually destroyed.  Only the file's directory
+entry is removed, and the file's storage is reclaimed only when no
+process has the file open and no other directory entry links to the
+file.  And even if file's data and metadata's storage space is freed
+for further reuse, there are undelete utilities that will attempt to
+reconstruct the file from the data in freed storage, and that can
+bring the file back if the storage was not rewritten.
+
+On a busy system with a nearly-full device, space can get reused in a few
+seconds.  But there is no way to know for sure.  And although the
+undelete utilities and already-existing processes require insider or
+superuser access, you may be wary of the superuser,
+of processes running on your behalf, or of attackers
+that can physically access the storage device.  So if you have sensitive
+data, you may want to be sure that recovery is not possible
+by plausible attacks like these.
+
+The best way to remove something irretrievably is to destroy the media
+it's on with acid, melt it down, or the like.  For cheap removable media
+this is often the preferred method.  However, some storage devices
+are expensive or are harder to destroy, so the @command{shred} utility tries
+to achieve a similar effect non-destructively, by overwriting the file
+with non-sensitive data.
+
+@strong{Please note} that @command{shred} relies on a crucial
+assumption: that the file system and hardware overwrite data in place.
+Although this is common and is the traditional
+way to do things, but many modern file system designs do not satisfy this
+assumption.  Exceptions include:
+
+@itemize @bullet
+
+@item
+Log-structured or journaled file systems, such as ext3/ext4 (in
+@code{data=journal} mode), Btrfs, NTFS, ReiserFS, XFS, ZFS, file
+systems supplied with AIX and Solaris, etc., when they are configured to
+journal data.
+
+@item
+File systems that write redundant data and carry on even if some writes
+fail, such as RAID-based file systems.
+
+@item
+File systems that make snapshots, such as Network Appliance's NFS server.
+
+@item
+File systems that cache in temporary locations, such as NFS version 3
+clients.
+
+@item
+Compressed file systems.
+@end itemize
+
+For ext3 and ext4 file systems, @command{shred} is less effective
+when the file system is in @code{data=journal}
+mode, which journals file data in addition to just metadata.  In both
+the @code{data=ordered} (default) and @code{data=writeback} modes,
+@command{shred} works as usual.  The ext3/ext4 journaling modes can be changed
+by adding the @code{data=something} option to the mount options for a
+particular file system in the @file{/etc/fstab} file, as documented in
+the @command{mount} man page (@samp{man mount}).  Alternatively, if
+you know how large the journal is, you can shred the journal by
+shredding enough file data so that the journal cycles around and fills
+up with shredded data.
+
+If you are not sure how your file system operates, then you should assume
+that it does not overwrite data in place, which means @command{shred} cannot
+reliably operate on regular files in your file system.
+
+Generally speaking, it is more reliable to shred a device than a file,
+since this bypasses file system design issues mentioned above.
+However, devices are also problematic for shredding, for reasons
+such as the following:
+
+@itemize @bullet
+
+@item
+Solid-state storage devices (SSDs) typically do wear leveling to
+prolong service life, and this means writes are distributed to other
+blocks by the hardware, so ``overwritten'' data blocks are still
+present in the underlying device.
+
+@item
+Most storage devices map out bad blocks invisibly to
+the application; if the bad blocks contain sensitive data,
+@command{shred} won't be able to destroy it.
+
+@item
+With some obsolete storage technologies,
+it may be possible to take (say) a floppy disk back
+to a laboratory and use a lot of sensitive (and expensive) equipment
+to look for the faint ``echoes'' of the original data underneath the
+overwritten data.  With these older technologies, if the file has been
+overwritten only once, it's reputedly not even that hard.  Luckily,
+this kind of data recovery has become difficult, and there is no
+public evidence that today's higher-density storage devices can be
+analyzed in this way.
+
+The @command{shred} command can use many overwrite passes,
+with data patterns chosen to
+maximize the damage they do to the old data.
+By default the patterns are designed for best effect on hard drives using
+now-obsolete technology; for newer devices, a single pass should suffice.
+For more details, see the source code and Peter Gutmann's paper
+@uref{https://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html,
+@cite{Secure Deletion of Data from Magnetic and Solid-State Memory}},
+from the proceedings of the Sixth USENIX Security Symposium (San Jose,
+California, July 22--25, 1996).
+@end itemize
+
+@command{shred} makes no attempt to detect or report these problems, just as
+it makes no attempt to do anything about backups.  However, since it is
+more reliable to shred devices than files, @command{shred} by default does
+not deallocate or remove the output file.  This default is more suitable
+for devices, which typically cannot be deallocated and should not be
+removed.
+
+Finally, consider the risk of backups and mirrors.
+File system backups and remote mirrors may contain copies of the
+file that cannot be removed, and that will allow a shredded file
+to be recovered later.  So if you keep any data you may later want
+to destroy using @command{shred}, be sure that it is not backed up or mirrored.
+
+@example
+shred [@var{option}]@dots{} @var{file}[@dots{}]
+@end example
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -f
+@itemx --force
+@opindex -f
+@opindex --force
+@cindex force deletion
+Override file permissions if necessary to allow overwriting.
+
+@item -n @var{number}
+@itemx --iterations=@var{number}
+@opindex -n @var{number}
+@opindex --iterations=@var{number}
+@cindex iterations, selecting the number of
+By default, @command{shred} uses @value{SHRED_DEFAULT_PASSES} passes of
+overwrite.  You can reduce this to save time, or increase it if you think it's
+appropriate.  After 25 passes all of the internal overwrite patterns will have
+been used at least once.
+
+@item --random-source=@var{file}
+@opindex --random-source
+@cindex random source for shredding
+Use @var{file} as a source of random data used to overwrite and to
+choose pass ordering.  @xref{Random sources}.
+
+@item -s @var{bytes}
+@itemx --size=@var{bytes}
+@opindex -s @var{bytes}
+@opindex --size=@var{bytes}
+@cindex size of file to shred
+Shred the first @var{bytes} bytes of the file.  The default is to shred
+the whole file.  @var{bytes} can be followed by a size specification like
+@samp{K}, @samp{M}, or @samp{G} to specify a multiple.  @xref{Block size}.
+
+@item -u
+@itemx --remove[=@var{how}]
+@opindex -u
+@opindex --remove
+@opindex --remove=unlink
+@opindex --remove=wipe
+@opindex --remove=wipesync
+@cindex removing files after shredding
+After shredding a file, deallocate it (if possible) and then remove it.
+If a file has multiple links, only the named links will be removed.
+Often the file name is less sensitive than the file data, in which case
+the optional @var{how} parameter, supported with the long form option,
+gives control of how to more efficiently remove each directory entry.
+The @samp{unlink} parameter will just use a standard unlink call,
+@samp{wipe} will also first obfuscate bytes in the name, and
+@samp{wipesync} will also sync each obfuscated byte in the name to disk.
+Note @samp{wipesync} is the default method, but can be expensive,
+requiring a sync for every character in every file.  This can become
+significant with many files, or is redundant if your file system provides
+synchronous metadata updates.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Display to standard error all status updates as sterilization proceeds.
+
+@item -x
+@itemx --exact
+@opindex -x
+@opindex --exact
+By default, @command{shred} rounds the size of a regular file up to the next
+multiple of the file system block size to fully erase the slack space in
+the last block of the file.  This space may contain portions of the current
+system memory on some systems for example.
+Use @option{--exact} to suppress that behavior.
+Thus, by default if you shred a 10-byte regular file on a system with 512-byte
+blocks, the resulting file will be 512 bytes long.  With this option,
+shred does not increase the apparent size of the file.
+
+@item -z
+@itemx --zero
+@opindex -z
+@opindex --zero
+Normally, the last pass that @command{shred} writes is made up of
+random data.  If this would be conspicuous on your storage device (for
+example, because it looks like encrypted data), or you just think
+it's tidier, the @option{--zero} option adds an additional overwrite pass with
+all zero bits.  This is in addition to the number of passes specified
+by the @option{--iterations} option.
+
+@end table
+
+You might use the following command to erase the file system you
+created on a USB flash drive.  This command typically takes several
+minutes, depending on the drive's size and write speed.  On modern
+storage devices a single pass should be adequate, and will take one
+third the time of the default three-pass approach.
+
+@example
+shred -v -n 1 /dev/sdd1
+@end example
+
+Similarly, to erase all data on a selected partition of
+your hard disk, you could give a command like the following.
+
+@example
+# 1 pass, write pseudo-random data; 3x faster than the default
+shred -v -n1 /dev/sda5
+@end example
+
+To be on the safe side, use at least one pass that overwrites using
+pseudo-random data.  I.e., don't be tempted to use @samp{-n0 --zero},
+in case some disk controller optimizes the process of writing blocks
+of all zeros, and thereby does not clear all bytes in a block.
+Some SSDs may do just that.
+
+A @var{file} of @samp{-} denotes standard output.
+The intended use of this is to shred a removed temporary file.
+For example:
+
+@example
+i=$(mktemp)
+exec 3<>"$i"
+rm -- "$i"
+echo "Hello, world" >&3
+shred - >&3
+exec 3>-
+@end example
+
+However, the command @samp{shred - >file} does not shred the contents
+of @var{file}, since the shell truncates @var{file} before invoking
+@command{shred}.  Use the command @samp{shred file} or (if using a
+Bourne-compatible shell) the command @samp{shred - 1<>file} instead.
+
+@exitstatus
+
+
+@node Special file types
+@chapter Special file types
+
+@cindex special file types
+@cindex file types, special
+
+This chapter describes commands which create special types of files (and
+@command{rmdir}, which removes directories, one special file type).
+
+@cindex special file types
+@cindex file types
+Although Unix-like operating systems have markedly fewer special file
+types than others, not @emph{everything} can be treated only as the
+undifferentiated byte stream of @dfn{normal files}.  For example, when a
+file is created or removed, the system must record this information,
+which it does in a @dfn{directory}---a special type of file.  Although
+you can read directories as normal files, if you're curious, in order
+for the system to do its job it must impose a structure, a certain
+order, on the bytes of the file.  Thus it is a ``special'' type of file.
+
+Besides directories, other special file types include named pipes
+(FIFOs), symbolic links, sockets, and so-called @dfn{special files}.
+
+@menu
+* 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 the unlink syscall
+@end menu
+
+
+@node link invocation
+@section @command{link}: Make a hard link via the link syscall
+
+@pindex link
+@cindex links, creating
+@cindex hard links, creating
+@cindex creating links (hard only)
+
+@command{link} creates a single hard link at a time.
+It is a minimalist interface to the system-provided
+@code{link} function.  @xref{Hard Links, , , libc,
+The GNU C Library Reference Manual}.
+It avoids the bells and whistles of the more commonly-used
+@command{ln} command (@pxref{ln invocation}).
+Synopsis:
+
+@example
+link @var{filename} @var{linkname}
+@end example
+
+@var{filename} must specify an existing file, and @var{linkname}
+must specify a nonexistent entry in an existing directory.
+@command{link} simply calls @code{link (@var{filename}, @var{linkname})}
+to create the link.
+
+On a GNU system, this command acts like @samp{ln --directory
+--no-target-directory @var{filename} @var{linkname}}.  However, the
+@option{--directory} and @option{--no-target-directory} options are
+not specified by 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
+
+
+@node ln invocation
+@section @command{ln}: Make links between files
+
+@pindex ln
+@cindex links, creating
+@cindex hard links, creating
+@cindex symbolic (soft) links, creating
+@cindex creating links (hard or soft)
+
+@cindex file systems and hard links
+@command{ln} makes links between files.  By default, it makes hard links;
+with the @option{-s} option, it makes symbolic (or @dfn{soft}) links.
+Synopses:
+
+@example
+ln [@var{option}]@dots{} [-T] @var{target} @var{linkname}
+ln [@var{option}]@dots{} @var{target}
+ln [@var{option}]@dots{} @var{target}@dots{} @var{directory}
+ln [@var{option}]@dots{} -t @var{directory} @var{target}@dots{}
+@end example
+
+@itemize @bullet
+
+@item
+If two file names are given, @command{ln} creates a link to the first
+file from the second.
+
+@item
+If one @var{target} is given, @command{ln} creates a link to that file
+in the current directory.
+
+@item
+If the @option{--target-directory} (@option{-t}) option is given, or
+failing that if the last file is a directory and the
+@option{--no-target-directory} (@option{-T}) option is not given,
+@command{ln} creates a link to each @var{target} file in the specified
+directory, using the @var{target}s' names.
+
+@end itemize
+
+Normally @command{ln} does not replace existing files.  Use the
+@option{--force} (@option{-f}) option to replace them unconditionally,
+the @option{--interactive} (@option{-i}) option to replace them
+conditionally, and the @option{--backup} (@option{-b}) option to
+rename them.  Unless the @option{--backup} (@option{-b}) option is
+used there is no brief moment when the destination does not exist;
+this is an extension to POSIX.
+
+@cindex hard link, defined
+@cindex inode, and hard links
+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.  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 POSIX, however.)
+
+@cindex dereferencing symbolic links
+@cindex symbolic link, defined
+@dfn{Symbolic links} (@dfn{symlinks} for short), on the other hand, are
+a special file type (which not all kernels support: System V release 3
+(and older) systems lack symlinks) in which the link file actually
+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 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}
+occurs when the string in the symlink does not resolve to a file.
+There are no restrictions against creating dangling symbolic links.
+There are trade-offs to using absolute or relative symlinks.  An
+absolute symlink always points to the same file, even if the directory
+containing the link is moved.  However, if the symlink is visible from
+more than one machine (such as on a networked file system), the file
+pointed to might not always be the same.  A relative symbolic link is
+resolved in relation to the directory that contains the link, and is
+often useful in referring to files on the same device without regards
+to what name that device is mounted on when accessed via networked
+machines.
+
+When creating a relative symlink in a different location than the
+current directory, the resolution of the symlink will be different
+than the resolution of the same string from the current directory.
+Therefore, many users prefer to first change directories to the
+location where the relative symlink will be created, so that
+tab-completion or other file resolution will find the same target as
+what will be placed in the symlink.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@optBackup
+
+@item -d
+@itemx -F
+@itemx --directory
+@opindex -d
+@opindex -F
+@opindex --directory
+@cindex hard links to directories
+Allow users with appropriate privileges to attempt to make hard links
+to directories.
+However, note that this will probably fail due to
+system restrictions, even for the super-user.
+
+@item -f
+@itemx --force
+@opindex -f
+@opindex --force
+Remove existing destination files.
+
+@item -i
+@itemx --interactive
+@opindex -i
+@opindex --interactive
+@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
+@opindex --no-dereference
+Do not treat the last operand specially when it is a symbolic link to
+a directory.  Instead, treat it as if it were a normal file.
+
+When the destination is an actual directory (not a symlink to one),
+there is no ambiguity.  The link is created in that directory.
+But when the specified destination is a symlink to a directory,
+there are two ways to treat the user's request.  @command{ln} can
+treat the destination just as it would a normal directory and create
+the link in it.  On the other hand, the destination can be viewed as a
+non-directory---as the symlink itself.  In that case, @command{ln}
+must delete or backup that symlink before creating the new link.
+The default is to treat a destination that is a symlink to a directory
+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 -r
+@itemx --relative
+@opindex -r
+@opindex --relative
+Make symbolic links relative to the link location.
+
+Example:
+
+@example
+ln -srv /a/file /tmp
+'/tmp/file' -> '../a/file'
+@end example
+
+Relative symbolic links are generated based on their canonicalized
+containing directory, and canonicalized targets.  I.e., all symbolic
+links in these file names will be resolved.
+@xref{realpath invocation}, which gives greater control
+over relative file name generation, as demonstrated in the following example:
+
+@example
+@verbatim
+ln--relative() {
+  test "$1" = --no-symlinks && { nosym=$1; shift; }
+  target="$1";
+  test -d "$2" && link="$2/." || link="$2"
+  rtarget="$(realpath $nosym -m "$target" \
+              --relative-to "$(dirname "$link")")"
+  ln -s -v "$rtarget" "$link"
+}
+@end verbatim
+@end example
+
+@item -s
+@itemx --symbolic
+@opindex -s
+@opindex --symbolic
+Make symbolic links instead of hard links.  This option merely produces
+an error message on systems that do not support symbolic links.
+
+@optBackupSuffix
+
+@optTargetDirectory
+
+@optNoTargetDirectory
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+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:
+
+@example
+Bad Example:
+
+# Create link ../a pointing to a in that directory.
+# Not really useful because it points to itself.
+ln -s a ..
+
+Better Example:
+
+# Change to the target before creating symlinks to avoid being confused.
+cd ..
+ln -s adir/a .
+
+Bad Example:
+
+# Hard coded file names don't move well.
+ln -s $(pwd)/a /some/dir/
+
+Better Example:
+
+# Relative file names survive directory moves and also
+# work across networked file systems.
+ln -s afile anotherfile
+ln -s ../adir/afile yetanotherfile
+@end example
+
+
+@node mkdir invocation
+@section @command{mkdir}: Make directories
+
+@pindex mkdir
+@cindex directories, creating
+@cindex creating directories
+
+@command{mkdir} creates directories with the specified names.  Synopsis:
+
+@example
+mkdir [@var{option}]@dots{} @var{name}@dots{}
+@end example
+
+@command{mkdir} creates each directory @var{name} in the order given.
+It reports an error if @var{name} already exists, unless the
+@option{-p} option is given and @var{name} is a directory.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -m @var{mode}
+@itemx --mode=@var{mode}
+@opindex -m
+@opindex --mode
+@cindex modes of created directories, setting
+Set the file permission bits of created directories to @var{mode},
+which uses the same syntax as
+in @command{chmod} and uses @samp{a=rwx} (read, write and execute allowed for
+everyone) for the point of the departure.  @xref{File permissions}.
+
+Normally the directory has the desired file mode bits at the moment it
+is created.  As a GNU extension, @var{mode} may also mention
+special mode bits, but in this case there may be a temporary window
+during which the directory exists but its special mode bits are
+incorrect.  @xref{Directory Setuid and Setgid}, for how the
+set-user-ID and set-group-ID bits of directories are inherited unless
+overridden in this way.
+
+@item -p
+@itemx --parents
+@opindex -p
+@opindex --parents
+@cindex parent directories, creating
+Make any missing parent directories for each argument, setting their
+file permission bits to the umask modified by @samp{u+wx}.  Ignore
+existing parent directories, and do not change their file permission
+bits.
+
+To set the file permission bits of any newly-created parent
+directories to a value that includes @samp{u+wx}, you can set the
+umask before invoking @command{mkdir}.  For example, if the shell
+command @samp{(umask u=rwx,go=rx; mkdir -p P/Q)} creates the parent
+@file{P} it sets the parent's permission bits to @samp{u=rwx,go=rx}.
+To set a parent's special mode bits as well, you can invoke
+@command{chmod} after @command{mkdir}.  @xref{Directory Setuid and
+Setgid}, for how the set-user-ID and set-group-ID bits of
+newly-created parent directories are inherited.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Print a message for each created directory.  This is most useful with
+@option{--parents}.
+
+@optContext
+
+@end table
+
+@exitstatus
+
+
+@node mkfifo invocation
+@section @command{mkfifo}: Make FIFOs (named pipes)
+
+@pindex mkfifo
+@cindex FIFOs, creating
+@cindex named pipes, creating
+@cindex creating FIFOs (named pipes)
+
+@command{mkfifo} creates FIFOs (also called @dfn{named pipes}) with the
+specified names.  Synopsis:
+
+@example
+mkfifo [@var{option}] @var{name}@dots{}
+@end example
+
+A @dfn{FIFO} is a special file type that permits independent processes
+to communicate.  One process opens the FIFO file for writing, and
+another for reading, after which data can flow as with the usual
+anonymous pipe in shells or elsewhere.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -m @var{mode}
+@itemx --mode=@var{mode}
+@opindex -m
+@opindex --mode
+@cindex modes of created FIFOs, setting
+Set the mode of created FIFOs to @var{mode}, which is symbolic as in
+@command{chmod} and uses @samp{a=rw} (read and write allowed for everyone)
+for the point of departure.  @var{mode} should specify only file
+permission bits.  @xref{File permissions}.
+
+@optContext
+
+@end table
+
+@exitstatus
+
+
+@node mknod invocation
+@section @command{mknod}: Make block or character special files
+
+@pindex mknod
+@cindex block special files, creating
+@cindex character special files, creating
+
+@command{mknod} creates a FIFO, character special file, or block special
+file with the specified name.  Synopsis:
+
+@example
+mknod [@var{option}]@dots{} @var{name} @var{type} [@var{major} @var{minor}]
+@end example
+
+@cindex special files
+@cindex block special files
+@cindex character special files
+Unlike the phrase ``special file type'' above, the term @dfn{special
+file} has a technical meaning on Unix: something that can generate or
+receive data.  Usually this corresponds to a physical piece of hardware,
+e.g., a printer or a disk.  (These files are typically created at
+system-configuration time.)  The @command{mknod} command is what creates
+files of this type.  Such devices can be read either a character at a
+time or a ``block'' (many characters) at a time, hence we say there are
+@dfn{block special} files and @dfn{character special} files.
+
+@c mknod is a shell built-in at least with OpenBSD's /bin/sh
+@mayConflictWithShellBuiltIn{mknod}
+
+The arguments after @var{name} specify the type of file to make:
+
+@table @samp
+
+@item p
+@opindex p @r{for FIFO file}
+for a FIFO
+
+@item b
+@opindex b @r{for block special file}
+for a block special file
+
+@item c
+@c Don't document the 'u' option -- it's just a synonym for 'c'.
+@c Do *any* versions of mknod still use it?
+@c @itemx u
+@opindex c @r{for character special file}
+@c @opindex u @r{for character special file}
+for a character special file
+
+@end table
+
+When making a block or character special file, the major and minor
+device numbers must be given after the file type.
+If a major or minor device number begins with @samp{0x} or @samp{0X},
+it is interpreted as hexadecimal; otherwise, if it begins with @samp{0},
+as octal; otherwise, as decimal.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -m @var{mode}
+@itemx --mode=@var{mode}
+@opindex -m
+@opindex --mode
+Set the mode of created files to @var{mode}, which is symbolic as in
+@command{chmod} and uses @samp{a=rw} as the point of departure.
+@var{mode} should specify only file permission bits.
+@xref{File permissions}.
+
+@optContext
+
+@end table
+
+@exitstatus
+
+
+@node readlink invocation
+@section @command{readlink}: Print value of a symlink or canonical file name
+
+@pindex readlink
+@cindex displaying value of a symbolic link
+@cindex canonical file name
+@cindex canonicalize a file name
+@cindex realpath
+
+@command{readlink} may work in one of two supported modes:
+
+@table @samp
+
+@item Readlink mode
+
+@command{readlink} outputs the value of the given symbolic links.
+If @command{readlink} is invoked with an argument other than the name
+of a symbolic link, it produces no output and exits with a nonzero exit code.
+
+@item Canonicalize mode
+
+@command{readlink} outputs the absolute name of the given files which contain
+no @file{.}, @file{..} components nor any repeated separators
+(@file{/}) or symbolic links.  Note the @command{realpath} command is the
+preferred command to use for canonicalization.  @xref{realpath invocation}.
+
+@end table
+
+@example
+readlink [@var{option}]@dots{} @var{file}@dots{}
+@end example
+
+By default, @command{readlink} operates in readlink mode.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -f
+@itemx --canonicalize
+@opindex -f
+@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.  A trailing slash is ignored.
+
+@item -e
+@itemx --canonicalize-existing
+@opindex -e
+@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.  A trailing slash
+requires that the name resolve to a directory.
+
+@item -m
+@itemx --canonicalize-missing
+@opindex -m
+@opindex --canonicalize-missing
+Activate canonicalize mode.
+If any component is missing or unavailable, @command{readlink} treats it
+as a directory.
+
+@item -n
+@itemx --no-newline
+@opindex -n
+@opindex --no-newline
+Do not print the output delimiter, when a single @var{file} is specified.
+Print a warning if specified along with multiple @var{file}s.
+
+@item -s
+@itemx -q
+@itemx --silent
+@itemx --quiet
+@opindex -s
+@opindex -q
+@opindex --silent
+@opindex --quiet
+Suppress most error messages.  On by default.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Report error messages.
+
+@optZero
+
+@end table
+
+The @command{readlink} utility first appeared in OpenBSD 2.1.
+
+The @command{realpath} command without options, operates like
+@command{readlink} in canonicalize mode.
+
+@exitstatus
+
+
+@node rmdir invocation
+@section @command{rmdir}: Remove empty directories
+
+@pindex rmdir
+@cindex removing empty directories
+@cindex directories, removing empty
+
+@command{rmdir} removes empty directories.  Synopsis:
+
+@example
+rmdir [@var{option}]@dots{} @var{directory}@dots{}
+@end example
+
+If any @var{directory} argument does not refer to an existing empty
+directory, it is an error.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item --ignore-fail-on-non-empty
+@opindex --ignore-fail-on-non-empty
+@cindex directory deletion, ignoring failures
+Ignore each failure to remove a directory that is solely because
+the directory is non-empty.
+
+@item -p
+@itemx --parents
+@opindex -p
+@opindex --parents
+@cindex parent directories, removing
+Remove @var{directory}, then try to remove each component of @var{directory}.
+So, for example, @samp{rmdir -p a/b/c} is similar to @samp{rmdir a/b/c a/b a}.
+As such, it fails if any of those directories turns out not to be empty.
+Use the @option{--ignore-fail-on-non-empty} option to make it so such
+a failure does not evoke a diagnostic and does not cause @command{rmdir} to
+exit unsuccessfully.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+@cindex directory deletion, reporting
+Give a diagnostic for each successful removal.
+@var{directory} is removed.
+
+@end table
+
+@xref{rm invocation}, for how to remove non-empty directories (recursively).
+
+@exitstatus
+
+
+@node unlink invocation
+@section @command{unlink}: Remove files via the unlink syscall
+
+@pindex unlink
+@cindex removing files or directories (via the unlink syscall)
+
+@command{unlink} deletes a single specified file name.
+It is a minimalist interface to the system-provided
+@code{unlink} function.  @xref{Deleting Files, , , libc,
+The GNU C Library Reference Manual}.  Synopsis:
+It avoids the bells and whistles of the more commonly-used
+@command{rm} command (@pxref{rm invocation}).
+
+@example
+unlink @var{filename}
+@end example
+
+On some systems @code{unlink} can be used to delete the name of a
+directory.  On others, it can be used that way only by a privileged user.
+In the GNU system @code{unlink} can never delete the name of a directory.
+
+The @command{unlink} command honors the @option{--help} and
+@option{--version} options.  To remove a file whose name begins with
+@samp{-}, prefix the name with @samp{./}, e.g., @samp{unlink ./--help}.
+
+@exitstatus
+
+
+@node Changing file attributes
+@chapter Changing file attributes
+
+@cindex changing file attributes
+@cindex file attributes, changing
+@cindex attributes, file
+
+A file is not merely its contents, a name, and a file type
+(@pxref{Special file types}).  A file also has an owner (a user ID), a
+group (a group ID), permissions (what the owner can do with the file,
+what people in the group can do, and what everyone else can do), various
+timestamps, and other information.  Collectively, we call these a file's
+@dfn{attributes}.
+
+These commands change file attributes.
+
+@menu
+* chown invocation::            Change file owners and groups.
+* chgrp invocation::            Change file groups.
+* chmod invocation::            Change access permissions.
+* touch invocation::            Change file timestamps.
+@end menu
+
+
+@node chown invocation
+@section @command{chown}: Change file owner and group
+
+@pindex chown
+@cindex file ownership, changing
+@cindex group ownership, changing
+@cindex changing file ownership
+@cindex changing group ownership
+
+@command{chown} changes the user and/or group ownership of each given @var{file}
+to @var{new-owner} or to the user and group of an existing reference file.
+Synopsis:
+
+@example
+chown [@var{option}]@dots{} @{@var{new-owner} | --reference=@var{ref_file}@}@c
+ @var{file}@dots{}
+@end example
+
+If used, @var{new-owner} specifies the new owner and/or group as follows
+(with no embedded white space):
+
+@example
+[@var{owner}] [ : [@var{group}] ]
+@end example
+
+Specifically:
+
+@table @var
+@item owner
+If only an @var{owner} (a user name or numeric user ID) is given, that
+user is made the owner of each given file, and the files' group is not
+changed.
+
+@item owner@samp{:}group
+If the @var{owner} is followed by a colon and a @var{group} (a
+group name or numeric group ID), with no spaces between them, the group
+ownership of the files is changed as well (to @var{group}).
+
+@item owner@samp{:}
+If a colon but no group name follows @var{owner}, that user is
+made the owner of the files and the group of the files is changed to
+@var{owner}'s login group.
+
+@item @samp{:}group
+If the colon and following @var{group} are given, but the owner
+is omitted, only the group of the files is changed; in this case,
+@command{chown} performs the same function as @command{chgrp}.
+
+@item @samp{:}
+If only a colon is given, or if @var{new-owner} is empty, neither the
+owner nor the group is changed.
+
+@end table
+
+If @var{owner} or @var{group} is intended to represent a numeric user
+or group ID, then you may specify it with a leading @samp{+}.
+@xref{Disambiguating names and IDs}.
+
+Some older scripts may still use @samp{.} in place of the @samp{:} separator.
+POSIX 1003.1-2001 (@pxref{Standards conformance}) does not
+require support for that, but for backward compatibility GNU
+@command{chown} supports @samp{.} so long as no ambiguity results.
+New scripts should avoid the use of @samp{.} because it is not
+portable, and because it has undesirable results if the entire
+@var{owner@samp{.}group} happens to identify a user whose name
+contains @samp{.}.
+
+@macro chownGroupRestrictions
+It is system dependent whether a user can change the group to an arbitrary one,
+or the more portable behavior of being restricted to setting a group of
+which the user is a member.
+@end macro
+@chownGroupRestrictions
+
+The @command{chown} command sometimes clears the set-user-ID or
+set-group-ID permission bits.  This behavior depends on the policy and
+functionality of the underlying @code{chown} system call, which may
+make system-dependent file mode modifications outside the control of
+the @command{chown} command.  For example, the @command{chown} command
+might not affect those bits when invoked by a user with appropriate
+privileges, or when the
+bits signify some function other than executable permission (e.g.,
+mandatory locking).
+When in doubt, check the underlying system behavior.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -c
+@itemx --changes
+@opindex -c
+@opindex --changes
+@cindex changed owners, verbosely describing
+Verbosely describe the action for each @var{file} whose ownership
+actually changes.
+
+@item -f
+@itemx --silent
+@itemx --quiet
+@opindex -f
+@opindex --silent
+@opindex --quiet
+@cindex error messages, omitting
+Do not print error messages about files whose ownership cannot be
+changed.
+
+@item --from=@var{old-owner}
+@opindex --from
+@cindex symbolic links, changing owner
+Change a @var{file}'s ownership only if it has current attributes specified
+by @var{old-owner}.  @var{old-owner} has the same form as @var{new-owner}
+described above.
+This option is useful primarily from a security standpoint in that
+it narrows considerably the window of potential abuse.
+For example, to reflect a user ID numbering change for one user's files
+without an option like this, @code{root} might run
+
+@example
+find / -owner OLDUSER -print0 | xargs -0 chown -h NEWUSER
+@end example
+
+But that is dangerous because the interval between when the @command{find}
+tests the existing file's owner and when the @command{chown} is actually run
+may be quite large.
+One way to narrow the gap would be to invoke chown for each file
+as it is found:
+
+@example
+find / -owner OLDUSER -exec chown -h NEWUSER @{@} \;
+@end example
+
+But that is very slow if there are many affected files.
+With this option, it is safer (the gap is narrower still)
+though still not perfect:
+
+@example
+chown -h -R --from=OLDUSER NEWUSER /
+@end example
+
+@item --dereference
+@opindex --dereference
+@cindex symbolic links, changing owner
+@findex lchown
+Do not act on symbolic links themselves but rather on what they point to.
+This is the default when not operating recursively.
+@warnOptDerefWithRec
+
+@item -h
+@itemx --no-dereference
+@opindex -h
+@opindex --no-dereference
+@cindex symbolic links, changing owner
+@findex lchown
+Act on symbolic links themselves instead of what they point to.
+This mode relies on the @code{lchown} system call.
+On systems that do not provide the @code{lchown} system call,
+@command{chown} fails when a file specified on the command line
+is a symbolic link.
+By default, no diagnostic is issued for symbolic links encountered
+during a recursive traversal, but see @option{--verbose}.
+
+@item --preserve-root
+@opindex --preserve-root
+@cindex root directory, disallow recursive modification
+Fail upon any attempt to recursively change the root directory, @file{/}.
+Without @option{--recursive}, this option has no effect.
+@xref{Treating / specially}.
+
+@item --no-preserve-root
+@opindex --no-preserve-root
+@cindex root directory, allow recursive modification
+Cancel the effect of any preceding @option{--preserve-root} option.
+@xref{Treating / specially}.
+
+@item --reference=@var{ref_file}
+@opindex --reference
+Change the user and group of each @var{file} to be the same as those of
+@var{ref_file}.  If @var{ref_file} is a symbolic link, do not use the
+user and group of the symbolic link, but rather those of the file it
+refers to.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Output a diagnostic for every file processed.
+If a symbolic link is encountered during a recursive traversal
+on a system without the @code{lchown} system call, and @option{--no-dereference}
+is in effect, then issue a diagnostic saying neither the symbolic link nor
+its referent is being changed.
+
+@item -R
+@itemx --recursive
+@opindex -R
+@opindex --recursive
+@cindex recursively changing file ownership
+Recursively change ownership of directories and their contents.
+
+@choptH
+@xref{Traversing symlinks}.
+
+@choptL
+@warnOptDerefWithRec
+@xref{Traversing symlinks}.
+
+@choptP
+@xref{Traversing symlinks}.
+
+@end table
+
+@exitstatus
+
+Examples:
+
+@example
+# Change the owner of /u to "root".
+chown root /u
+
+# Likewise, but also change its group to "staff".
+chown root:staff /u
+
+# Change the owner of /u and subfiles to "root".
+chown -hR root /u
+@end example
+
+
+@node chgrp invocation
+@section @command{chgrp}: Change group ownership
+
+@pindex chgrp
+@cindex group ownership, changing
+@cindex changing group ownership
+
+@command{chgrp} changes the group ownership of each given @var{file}
+to @var{group} (which can be either a group name or a numeric group ID)
+or to the group of an existing reference file.  @xref{chown invocation}.
+Synopsis:
+
+@example
+chgrp [@var{option}]@dots{} @{@var{group} | --reference=@var{ref_file}@}@c
+ @var{file}@dots{}
+@end example
+
+If @var{group} is intended to represent a
+numeric group ID, then you may specify it with a leading @samp{+}.
+@xref{Disambiguating names and IDs}.
+
+@chownGroupRestrictions
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -c
+@itemx --changes
+@opindex -c
+@opindex --changes
+@cindex changed files, verbosely describing
+Verbosely describe the action for each @var{file} whose group actually
+changes.
+
+@item -f
+@itemx --silent
+@itemx --quiet
+@opindex -f
+@opindex --silent
+@opindex --quiet
+@cindex error messages, omitting
+Do not print error messages about files whose group cannot be
+changed.
+
+@item --dereference
+@opindex --dereference
+@cindex symbolic links, changing owner
+@findex lchown
+Do not act on symbolic links themselves but rather on what they point to.
+This is the default when not operating recursively.
+@warnOptDerefWithRec
+
+@item -h
+@itemx --no-dereference
+@opindex -h
+@opindex --no-dereference
+@cindex symbolic links, changing group
+@findex lchown
+Act on symbolic links themselves instead of what they point to.
+This mode relies on the @code{lchown} system call.
+On systems that do not provide the @code{lchown} system call,
+@command{chgrp} fails when a file specified on the command line
+is a symbolic link.
+By default, no diagnostic is issued for symbolic links encountered
+during a recursive traversal, but see @option{--verbose}.
+
+@item --preserve-root
+@opindex --preserve-root
+@cindex root directory, disallow recursive modification
+Fail upon any attempt to recursively change the root directory, @file{/}.
+Without @option{--recursive}, this option has no effect.
+@xref{Treating / specially}.
+
+@item --no-preserve-root
+@opindex --no-preserve-root
+@cindex root directory, allow recursive modification
+Cancel the effect of any preceding @option{--preserve-root} option.
+@xref{Treating / specially}.
+
+@item --reference=@var{ref_file}
+@opindex --reference
+Change the group of each @var{file} to be the same as that of
+@var{ref_file}.  If @var{ref_file} is a symbolic link, do not use the
+group of the symbolic link, but rather that of the file it refers to.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Output a diagnostic for every file processed.
+If a symbolic link is encountered during a recursive traversal
+on a system without the @code{lchown} system call, and @option{--no-dereference}
+is in effect, then issue a diagnostic saying neither the symbolic link nor
+its referent is being changed.
+
+@item -R
+@itemx --recursive
+@opindex -R
+@opindex --recursive
+@cindex recursively changing group ownership
+Recursively change the group ownership of directories and their contents.
+
+@choptH
+@xref{Traversing symlinks}.
+
+@choptL
+@warnOptDerefWithRec
+@xref{Traversing symlinks}.
+
+@choptP
+@xref{Traversing symlinks}.
+
+@end table
+
+@exitstatus
+
+Examples:
+
+@example
+# Change the group of /u to "staff".
+chgrp staff /u
+
+# Change the group of /u and subfiles to "staff".
+chgrp -hR staff /u
+@end example
+
+
+@node chmod invocation
+@section @command{chmod}: Change access permissions
+
+@pindex chmod
+@cindex changing access permissions
+@cindex access permissions, changing
+@cindex permissions, changing access
+
+@command{chmod} changes the access permissions of the named files.  Synopsis:
+
+@example
+chmod [@var{option}]@dots{} @{@var{mode} | --reference=@var{ref_file}@}@c
+ @var{file}@dots{}
+@end example
+
+@cindex symbolic links, permissions of
+@command{chmod} never changes the permissions of symbolic links, since
+the @command{chmod} system call cannot change their permissions.
+This is not a problem since the permissions of symbolic links are
+never used.  However, for each symbolic link listed on the command
+line, @command{chmod} changes the permissions of the pointed-to file.
+In contrast, @command{chmod} ignores symbolic links encountered during
+recursive directory traversals.
+
+Only a process whose effective user ID matches the user ID of the file,
+or a process with appropriate privileges, is permitted to change the
+file mode bits of a file.
+
+A successful use of @command{chmod} clears the set-group-ID bit of a
+regular file if the file's group ID does not match the user's
+effective group ID or one of the user's supplementary group IDs,
+unless the user has appropriate privileges.  Additional restrictions
+may cause the set-user-ID and set-group-ID bits of @var{mode} or
+@var{ref_file} to be ignored.  This behavior depends on the policy and
+functionality of the underlying @code{chmod} system call.  When in
+doubt, check the underlying system behavior.
+
+If used, @var{mode} specifies the new file mode bits.
+For details, see the section on @ref{File permissions}.
+If you really want @var{mode} to have a leading @samp{-}, you should
+use @option{--} first, e.g., @samp{chmod -- -w file}.  Typically,
+though, @samp{chmod a-w file} is preferable, and @command{chmod -w
+file} (without the @option{--}) complains if it behaves differently
+from what @samp{chmod a-w file} would do.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -c
+@itemx --changes
+@opindex -c
+@opindex --changes
+Verbosely describe the action for each @var{file} whose permissions
+actually changes.
+
+@item -f
+@itemx --silent
+@itemx --quiet
+@opindex -f
+@opindex --silent
+@opindex --quiet
+@cindex error messages, omitting
+Do not print error messages about files whose permissions cannot be
+changed.
+
+@item --preserve-root
+@opindex --preserve-root
+@cindex root directory, disallow recursive modification
+Fail upon any attempt to recursively change the root directory, @file{/}.
+Without @option{--recursive}, this option has no effect.
+@xref{Treating / specially}.
+
+@item --no-preserve-root
+@opindex --no-preserve-root
+@cindex root directory, allow recursive modification
+Cancel the effect of any preceding @option{--preserve-root} option.
+@xref{Treating / specially}.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Verbosely describe the action or non-action taken for every @var{file}.
+
+@item --reference=@var{ref_file}
+@opindex --reference
+Change the mode of each @var{file} to be the same as that of @var{ref_file}.
+@xref{File permissions}.
+If @var{ref_file} is a symbolic link, do not use the mode
+of the symbolic link, but rather that of the file it refers to.
+
+@item -R
+@itemx --recursive
+@opindex -R
+@opindex --recursive
+@cindex recursively changing access permissions
+Recursively change permissions of directories and their contents.
+
+@end table
+
+@exitstatus
+
+Examples:
+
+@smallexample
+# Change file permissions of FOO to be world readable
+# and user writable, with no other permissions.
+chmod 644 foo
+chmod a=r,u+w foo
+
+# Add user and group execute permissions to FOO.
+chmod +110 file
+chmod ug+x file
+
+# Set file permissions of DIR and subsidiary files to
+# be the umask default, assuming execute permissions for
+# directories and for files already executable.
+chmod -R a=,+rwX dir
+@end smallexample
+
+
+@node touch invocation
+@section @command{touch}: Change file timestamps
+
+@pindex touch
+@cindex changing file timestamps
+@cindex file timestamps, changing
+@cindex timestamps, changing file
+
+@command{touch} changes the access and/or modification timestamps of the
+specified files.  Synopsis:
+
+@example
+touch [@var{option}]@dots{} @var{file}@dots{}
+@end example
+
+@cindex empty files, creating
+Any @var{file} argument that does not exist is created empty, unless
+option @option{--no-create} (@option{-c}) or @option{--no-dereference}
+(@option{-h}) was in effect.
+
+A @var{file} argument string of @samp{-} is handled specially and
+causes @command{touch} to change the times of the file associated with
+standard output.
+
+By default, @command{touch} sets file timestamps to the current time.
+Because @command{touch} acts on its operands left to right, the
+resulting timestamps of earlier and later operands may disagree.
+
+@cindex permissions, for changing file timestamps
+When setting file timestamps to the current time, @command{touch} can
+change the timestamps for files that the user does not own but has
+write permission for.  Otherwise, the user must own the files.  Some
+older systems have a further restriction: the user must own the files
+unless both the access and modification timestamps are being set to the
+current time.
+
+The @command{touch} command cannot set a file's status change timestamp to
+a user-specified value, and cannot change the file's birth time (if
+supported) at all.  Also, @command{touch} has issues similar to those
+affecting all programs that update file timestamps.  For example,
+@command{touch} may set a file's timestamp to a value that differs
+slightly from the requested time.  @xref{File timestamps}.
+
+@vindex TZ
+Timestamps assume the time zone rules specified by the @env{TZ}
+environment variable, or by the system default rules if @env{TZ} is
+not set.  @xref{TZ Variable,, Specifying the Time Zone with @env{TZ},
+libc, The GNU C Library Reference Manual}.
+You can avoid ambiguities during
+daylight saving transitions by using UTC timestamps.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -a
+@itemx --time=atime
+@itemx --time=access
+@itemx --time=use
+@opindex -a
+@opindex --time
+@opindex atime@r{, changing}
+@opindex access @r{time, changing}
+@opindex use @r{time, changing}
+Change the access timestamp only.  @xref{File timestamps}.
+
+@item -c
+@itemx --no-create
+@opindex -c
+@opindex --no-create
+Do not warn about or create files that do not exist.
+
+@item -d @var{time}
+@itemx --date=@var{time}
+@opindex -d
+@opindex --date
+@opindex time
+Use @var{time} instead of the current time.  It can contain month names,
+time zones, @samp{am} and @samp{pm}, @samp{yesterday}, etc.  For
+example, @option{--date="2004-02-27 14:19:13.489392193 +0530"}
+specifies the instant of time that is 489,392,193 nanoseconds after
+February 27, 2004 at 2:19:13 PM in a time zone that is 5 hours and 30
+minutes east of UTC@.  @xref{Date input formats}.
+File systems that do not support high-resolution timestamps
+silently ignore any excess precision here.
+
+@item -f
+@opindex -f
+@cindex BSD @command{touch} compatibility
+Ignored; for compatibility with BSD versions of @command{touch}.
+
+@item -h
+@itemx --no-dereference
+@opindex -h
+@opindex --no-dereference
+@cindex symbolic links, changing time
+@findex lutimes
+Attempt to change the timestamps of a symbolic link, rather than what
+the link refers to.  When using this option, empty files are not
+created, but option @option{-c} must also be used to avoid warning
+about files that do not exist.  Not all systems support changing the
+timestamps of symlinks, since underlying system support for this
+action was not required until POSIX 2008.  Also, on some
+systems, the mere act of examining a symbolic link changes the access
+timestamp, such that only changes to the modification timestamp will persist
+long enough to be observable.  When coupled with option @option{-r}, a
+reference timestamp is taken from a symbolic link rather than the file
+it refers to.
+
+@item -m
+@itemx --time=mtime
+@itemx --time=modify
+@opindex -m
+@opindex --time
+@opindex mtime@r{, changing}
+@opindex modify @r{time, changing}
+Change the modification timestamp only.
+
+@item -r @var{file}
+@itemx --reference=@var{file}
+@opindex -r
+@opindex --reference
+Use the times of the reference @var{file} instead of the current time.
+If this option is combined with the @option{--date=@var{time}}
+(@option{-d @var{time}}) option, the reference @var{file}'s time is
+the origin for any relative @var{time}s given, but is otherwise ignored.
+For example, @samp{-r foo -d '-5 seconds'} specifies a timestamp
+equal to five seconds before the corresponding timestamp for @file{foo}.
+If @var{file} is a symbolic link, the reference timestamp is taken
+from the target of the symlink, unless @option{-h} was also in effect.
+
+@item -t [[@var{cc}]@var{yy}]@var{mmddhhmm}[.@var{ss}]
+@cindex leap seconds
+Use the argument (optional four-digit or two-digit years, months,
+days, hours, minutes, optional seconds) instead of the current time.
+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.
+On the atypical systems that support leap seconds, @var{ss} may be
+@samp{60}.
+
+@end table
+
+@vindex _POSIX2_VERSION
+On systems predating POSIX 1003.1-2001,
+@command{touch} supports an obsolete syntax, as follows.
+If no timestamp is given with any of the @option{-d}, @option{-r}, or
+@option{-t} options, and if there are two or more @var{file}s and the
+first @var{file} is of the form @samp{@var{mmddhhmm}[@var{yy}]} and this
+would be a valid argument to the @option{-t} option (if the @var{yy}, if
+any, were moved to the front), and if the represented year
+is in the range 1969--1999, that argument is interpreted as the time
+for the other files instead of as a file name.
+Although this obsolete behavior can be controlled with the
+@env{_POSIX2_VERSION} environment variable (@pxref{Standards
+conformance}), portable scripts should avoid commands whose
+behavior depends on this variable.
+For example, use @samp{touch ./12312359 main.c} or @samp{touch -t
+12312359 main.c} rather than the ambiguous @samp{touch 12312359 main.c}.
+
+@exitstatus
+
+
+@node Disk usage
+@chapter Disk usage
+
+@cindex disk usage
+
+No disk can hold an infinite amount of data.  These commands report
+how much disk storage is in use or available, report other file and
+file status information, and write buffers to disk.
+
+@menu
+* 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 cached writes to persistent storage.
+* truncate invocation::         Shrink or extend the size of a file.
+@end menu
+
+
+@node df invocation
+@section @command{df}: Report file system disk space usage
+
+@pindex df
+@cindex file system disk usage
+@cindex disk usage by file system
+
+@command{df} reports the amount of disk space used and available on
+file systems.  Synopsis:
+
+@example
+df [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+With no arguments, @command{df} reports the space used and available on all
+currently mounted file systems (of all types).  Otherwise, @command{df}
+reports on the file system containing each argument @var{file}.
+
+Normally the disk space is printed in units of
+1024 bytes, but this can be overridden (@pxref{Block size}).
+Non-integer quantities are rounded up to the next higher unit.
+
+For bind mounts and without arguments, @command{df} only outputs the statistics
+for that device with the shortest mount point name in the list of file systems
+(@var{mtab}), i.e., it hides duplicate entries, unless the @option{-a} option is
+specified.
+
+With the same logic, @command{df} elides a mount entry of a dummy pseudo device
+if there is another mount entry of a real block device for that mount point with
+the same device number, e.g. the early-boot pseudo file system @samp{rootfs} is
+not shown per default when already the real root device has been mounted.
+
+@cindex disk device file
+@cindex device file, disk
+If an argument @var{file} resolves to a special file containing
+a mounted file system, @command{df} shows the space available on that
+file system rather than on the file system containing the device node.
+GNU @command{df} does not attempt to determine the disk usage
+on unmounted file systems, because on most kinds of systems doing so
+requires extremely nonportable intimate knowledge of file system structures.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -a
+@itemx --all
+@opindex -a
+@opindex --all
+@cindex ignore file systems
+Include in the listing dummy, duplicate, or inaccessible file systems, which
+are omitted by default.  Dummy file systems are typically special purpose
+pseudo file systems such as @samp{/proc}, with no associated storage.
+Duplicate file systems are local or remote file systems that are mounted
+at separate locations in the local file hierarchy, or bind mounted locations.
+Inaccessible file systems are those which are mounted but subsequently
+over-mounted by another file system at that point, or otherwise inaccessible
+due to permissions of the mount point etc.
+
+@item -B @var{size}
+@itemx --block-size=@var{size}
+@opindex -B
+@opindex --block-size
+@cindex file system sizes
+Scale sizes by @var{size} before printing them (@pxref{Block size}).
+For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes.
+
+@optHumanReadable
+
+@item -H
+@opindex -H
+Equivalent to @option{--si}.
+
+@item -i
+@itemx --inodes
+@opindex -i
+@opindex --inodes
+@cindex inode usage
+List inode usage information instead of block usage.  An inode (short
+for index node) contains information about a file such as its owner,
+permissions, timestamps, and location on the disk.
+
+@item -k
+@opindex -k
+@cindex kibibytes for file system sizes
+Print sizes in 1024-byte blocks, overriding the default block size
+(@pxref{Block size}).
+This option is equivalent to @option{--block-size=1K}.
+
+@item -l
+@itemx --local
+@opindex -l
+@opindex --local
+@cindex file system types, limiting output to certain
+Limit the listing to local file systems.  By default, remote file systems
+are also listed.
+
+@item --no-sync
+@opindex --no-sync
+@cindex file system space, retrieving old data more quickly
+Do not invoke the @code{sync} system call before getting any usage data.
+This may make @command{df} run significantly faster on systems with many
+disks, but on some systems (notably SunOS) the results may be slightly
+out of date.  This is the default.
+
+@item --output
+@itemx --output[=@var{field_list}]
+@opindex --output
+Use the output format defined by @var{field_list}, or print all fields if
+@var{field_list} is omitted.  In the latter case, the order of the columns
+conforms to the order of the field descriptions below.
+
+The use of the @option{--output} together with each of the options @option{-i},
+@option{-P}, and @option{-T} is mutually exclusive.
+
+FIELD_LIST is a comma-separated list of columns to be included in @command{df}'s
+output and therefore effectively controls the order of output columns.
+Each field can thus be used at the place of choice, but yet must only be
+used once.
+
+Valid field names in the @var{field_list} are:
+@table @samp
+@item source
+The source of the mount point, usually a device.
+@item fstype
+File system type.
+
+@item itotal
+Total number of inodes.
+@item iused
+Number of used inodes.
+@item iavail
+Number of available inodes.
+@item ipcent
+Percentage of @var{iused} divided by @var{itotal}.
+
+@item size
+Total number of blocks.
+@item used
+Number of used blocks.
+@item avail
+Number of available blocks.
+@item pcent
+Percentage of @var{used} divided by @var{size}.
+
+@item file
+The file name if specified on the command line.
+@item target
+The mount point.
+@end table
+
+The fields for block and inodes statistics are affected by the scaling
+options like @option{-h} as usual.
+
+The definition of the @var{field_list} can even be split among several
+@option{--output} uses.
+
+@example
+#!/bin/sh
+# Print the TARGET (i.e., the mount point) along with their percentage
+# statistic regarding the blocks and the inodes.
+df --out=target --output=pcent,ipcent
+
+# Print all available fields.
+df --o
+@end example
+
+
+@item -P
+@itemx --portability
+@opindex -P
+@opindex --portability
+@cindex one-line output format
+@cindex POSIX output format
+@cindex portable output format
+@cindex output format, portable
+Use the POSIX output format.  This is like the default format except
+for the following:
+
+@enumerate
+@item
+The information about each file system is always printed on exactly
+one line; a mount device is never put on a line by itself.  This means
+that if the mount device name is more than 20 characters long (e.g., for
+some network mounts), the columns are misaligned.
+
+@item
+The labels in the header output line are changed to conform to POSIX.
+
+@item
+The default block size and output format are unaffected by the
+@env{DF_BLOCK_SIZE}, @env{BLOCK_SIZE} and @env{BLOCKSIZE} environment
+variables.  However, the default block size is still affected by
+@env{POSIXLY_CORRECT}: it is 512 if @env{POSIXLY_CORRECT} is set, 1024
+otherwise.  @xref{Block size}.
+@end enumerate
+
+@optSi
+
+@item --sync
+@opindex --sync
+@cindex file system space, retrieving current data more slowly
+Invoke the @code{sync} system call before getting any usage data.  On
+some systems (notably SunOS), doing this yields more up to date results,
+but in general this option makes @command{df} much slower, especially when
+there are many or very busy file systems.
+
+@item --total
+@opindex --total
+@cindex grand total of disk size, usage and available space
+Print a grand total of all arguments after all arguments have
+been processed.  This can be used to find out the total disk size, usage
+and available space of all listed devices.  If no arguments are specified
+df will try harder to elide file systems insignificant to the total
+available space, by suppressing duplicate remote file systems.
+
+For the grand total line, @command{df} prints @samp{"total"} into the
+@var{source} column, and @samp{"-"} into the @var{target} column.
+If there is no @var{source} column (see @option{--output}), then
+@command{df} prints @samp{"total"} into the @var{target} column,
+if present.
+
+@item -t @var{fstype}
+@itemx --type=@var{fstype}
+@opindex -t
+@opindex --type
+@cindex file system types, limiting output to certain
+Limit the listing to file systems of type @var{fstype}.  Multiple
+file system types can be specified by giving multiple @option{-t} options.
+By default, nothing is omitted.
+
+@item -T
+@itemx --print-type
+@opindex -T
+@opindex --print-type
+@cindex file system types, printing
+Print each file system's type.  The types printed here are the same ones
+you can include or exclude with @option{-t} and @option{-x}.  The particular
+types printed are whatever is supported by the system.  Here are some of
+the common names (this list is certainly not exhaustive):
+
+@table @samp
+
+@item nfs
+@cindex NFS file system type
+An NFS file system, i.e., one mounted over a network from another
+machine.  This is the one type name which seems to be used uniformly by
+all systems.
+
+@item ext2@r{, }ext3@r{, }ext4@r{, }xfs@r{, }btrfs@dots{}
+@cindex Linux file system types
+@cindex local file system types
+@opindex ext2 @r{file system type}
+@opindex ext3 @r{file system type}
+@opindex ext4 @r{file system type}
+@opindex xfs @r{file system type}
+@opindex btrfs @r{file system type}
+A file system on a locally-mounted hard disk.  (The system might even
+support more than one type here; Linux does.)
+
+@item iso9660@r{, }cdfs
+@cindex CD-ROM file system type
+@cindex DVD file system type
+@cindex ISO9660 file system type
+@opindex iso9660 @r{file system type}
+@opindex cdfs @r{file system type}
+A file system on a CD or DVD drive.  HP-UX uses @samp{cdfs}, most other
+systems use @samp{iso9660}.
+
+@item ntfs@r{,}fat
+@cindex NTFS file system
+@cindex DOS file system
+@cindex MS-DOS file system
+@cindex MS-Windows file system
+@opindex ntfs @r{file system file}
+@opindex fat @r{file system file}
+File systems used by MS-Windows / MS-DOS.
+
+@end table
+
+@item -x @var{fstype}
+@itemx --exclude-type=@var{fstype}
+@opindex -x
+@opindex --exclude-type
+Limit the listing to file systems not of type @var{fstype}.
+Multiple file system types can be eliminated by giving multiple
+@option{-x} options.  By default, no file system types are omitted.
+
+@item -v
+Ignored; for compatibility with System V versions of @command{df}.
+
+@end table
+
+@command{df} is installed only on systems that have usable mount tables,
+so portable scripts should not rely on its existence.
+
+@exitstatus
+Failure includes the case where no output is generated, so you can
+inspect the exit status of a command like @samp{df -t ext3 -t reiserfs
+@var{dir}} to test whether @var{dir} is on a file system of type
+@samp{ext3} or @samp{reiserfs}.
+
+Since the list of file systems (@var{mtab}) is needed to determine the
+file system type, failure includes the cases when that list cannot
+be read and one or more of the options @option{-a}, @option{-l}, @option{-t}
+or @option{-x} is used together with a file name argument.
+
+
+@node du invocation
+@section @command{du}: Estimate file space usage
+
+@pindex du
+@cindex file space usage
+@cindex disk usage for files
+
+@command{du} reports the amount of disk space used by the set of specified files
+and for each subdirectory (of directory arguments).  Synopsis:
+
+@example
+du [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+With no arguments, @command{du} reports the disk space for the current
+directory.  Normally the disk space is printed in units of
+1024 bytes, but this can be overridden (@pxref{Block size}).
+Non-integer quantities are rounded up to the next higher unit.
+
+If two or more hard links point to the same file, only one of the hard
+links is counted.  The @var{file} argument order affects which links
+are counted, and changing the argument order may change the numbers
+and entries that @command{du} outputs.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@optNull
+
+@item -a
+@itemx --all
+@opindex -a
+@opindex --all
+Show counts for all files, not just directories.
+
+@item --apparent-size
+@opindex --apparent-size
+Print apparent sizes, rather than disk usage.  The apparent size of a
+file is the number of bytes reported by @code{wc -c} on regular files,
+or more generally, @code{ls -l --block-size=1} or @code{stat --format=%s}.
+For example, a file containing the word @samp{zoo} with no newline would,
+of course, have an apparent size of 3.  Such a small file may require
+anywhere from 0 to 16 KiB or more of disk space, depending on
+the type and configuration of the file system on which the file resides.
+However, a sparse file created with this command:
+
+@example
+dd bs=1 seek=2GiB if=/dev/null of=big
+@end example
+
+@noindent
+has an apparent size of 2 GiB, yet on most modern
+systems, it actually uses almost no disk space.
+
+@item -B @var{size}
+@itemx --block-size=@var{size}
+@opindex -B
+@opindex --block-size
+@cindex file sizes
+Scale sizes by @var{size} before printing them (@pxref{Block size}).
+For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes.
+
+@item -b
+@itemx --bytes
+@opindex -b
+@opindex --bytes
+Equivalent to @code{--apparent-size --block-size=1}.
+
+@item -c
+@itemx --total
+@opindex -c
+@opindex --total
+@cindex grand total of disk space
+Print a grand total of all arguments after all arguments have
+been processed.  This can be used to find out the total disk usage of
+a given set of files or directories.
+
+@item -D
+@itemx --dereference-args
+@opindex -D
+@opindex --dereference-args
+Dereference symbolic links that are command line arguments.
+Does not affect other symbolic links.  This is helpful for finding
+out the disk usage of directories, such as @file{/usr/tmp}, which
+are often symbolic links.
+
+@item -d @var{depth}
+@itemx --max-depth=@var{depth}
+@opindex -d @var{depth}
+@opindex --max-depth=@var{depth}
+@cindex limiting output of @command{du}
+Show the total for each directory (and file if --all) that is at
+most MAX_DEPTH levels down from the root of the hierarchy.  The root
+is at level 0, so @code{du --max-depth=0} is equivalent to @code{du -s}.
+
+@c --files0-from=FILE
+@filesZeroFromOption{du,, with the @option{--total} (@option{-c}) option}
+
+@item -H
+@opindex -H
+Equivalent to @option{--dereference-args} (@option{-D}).
+
+@optHumanReadable
+
+@item --inodes
+@opindex --inodes
+@cindex inode usage, dereferencing in @command{du}
+List inode usage information instead of block usage.
+This option is useful for finding directories which contain many files, and
+therefore eat up most of the inodes space of a file system (see @command{df},
+option @option{--inodes}).
+It can well be combined with the options @option{-a}, @option{-c},
+@option{-h}, @option{-l}, @option{-s}, @option{-S}, @option{-t} and
+@option{-x}; however, passing other options regarding the block size, for
+example @option{-b}, @option{-m} and @option{--apparent-size}, is ignored.
+
+@item -k
+@opindex -k
+@cindex kibibytes for file sizes
+Print sizes in 1024-byte blocks, overriding the default block size
+(@pxref{Block size}).
+This option is equivalent to @option{--block-size=1K}.
+
+@item -L
+@itemx --dereference
+@opindex -L
+@opindex --dereference
+@cindex symbolic links, dereferencing in @command{du}
+Dereference symbolic links (show the disk space used by the file
+or directory that the link points to instead of the space used by
+the link).
+
+@item -l
+@itemx --count-links
+@opindex -l
+@opindex --count-links
+@cindex hard links, counting in @command{du}
+Count the size of all files, even if they have appeared already (as a
+hard link).
+
+@item -m
+@opindex -m
+@cindex mebibytes for file sizes
+Print sizes in 1,048,576-byte blocks, overriding the default block size
+(@pxref{Block size}).
+This option is equivalent to @option{--block-size=1M}.
+
+@item -P
+@itemx --no-dereference
+@opindex -P
+@opindex --no-dereference
+@cindex symbolic links, dereferencing in @command{du}
+For each symbolic links encountered by @command{du},
+consider the disk space used by the symbolic link.
+
+@item -S
+@itemx --separate-dirs
+@opindex -S
+@opindex --separate-dirs
+Normally, in the output of @command{du} (when not using @option{--summarize}),
+the size listed next to a directory name, @var{d}, represents the sum
+of sizes of all entries beneath @var{d} as well as the size of @var{d} itself.
+With @option{--separate-dirs}, the size reported for a directory name,
+@var{d}, will exclude the size of any subdirectories.
+
+@optSi
+
+@item -s
+@itemx --summarize
+@opindex -s
+@opindex --summarize
+Display only a total for each argument.
+
+@item -t @var{size}
+@itemx --threshold=@var{size}
+@opindex -t
+@opindex --threshold
+Exclude entries based on a given @var{size}.  The @var{size} refers to used
+blocks in normal mode (@pxref{Block size}), or inodes count in conjunction
+with the @option{--inodes} option.
+
+If @var{size} is positive, then @command{du} will only print entries with a size
+greater than or equal to that.
+
+If @var{size} is negative, then @command{du} will only print entries with a size
+smaller than or equal to that.
+
+Although GNU @command{find} can be used to find files of a certain size,
+@command{du}'s @option{--threshold} option can be used to also filter
+directories based on a given size.
+
+Please note that the @option{--threshold} option can be combined with the
+@option{--apparent-size} option, and in this case would elide entries based on
+its apparent size.
+
+Please note that the @option{--threshold} option can be combined with the
+@option{--inodes} option, and in this case would elide entries based on
+its inodes count.
+
+Here's how you would use @option{--threshold} to find directories with a size
+greater than or equal to 200 megabytes:
+
+@example
+du --threshold=200MB
+@end example
+
+Here's how you would use @option{--threshold} to find directories and files -
+note the @option{-a} - with an apparent size smaller than or equal to 500 bytes:
+
+@example
+du -a -t -500 --apparent-size
+@end example
+
+Here's how you would use @option{--threshold} to find directories on the root
+file system with more than 20000 inodes used in the directory tree below:
+
+@example
+du --inodes -x --threshold=20000 /
+@end example
+
+
+@item --time
+@opindex --time
+@cindex last modified dates, displaying in @command{du}
+Show the most recent modification timestamp (mtime) of any file in the
+directory, or any of its subdirectories.  @xref{File timestamps}.
+
+@item --time=ctime
+@itemx --time=status
+@itemx --time=use
+@opindex --time
+@opindex ctime@r{, show the most recent}
+@opindex status time@r{, show the most recent}
+@opindex use time@r{, show the most recent}
+Show the most recent status change timestamp (ctime) of any file in
+the directory, or any of its subdirectories.  @xref{File timestamps}.
+
+@item --time=atime
+@itemx --time=access
+@opindex --time
+@opindex atime@r{, show the most recent}
+@opindex access timestamp@r{, show the most recent}
+Show the most recent access timestamp (atime) of any file in the
+directory, or any of its subdirectories.  @xref{File timestamps}.
+
+@item --time-style=@var{style}
+@opindex --time-style
+@cindex time style
+List timestamps in style @var{style}.  This option has an effect only if
+the @option{--time} option is also specified.  The @var{style} should
+be one of the following:
+
+@table @samp
+@item +@var{format}
+@vindex LC_TIME
+List timestamps using @var{format}, where @var{format} is interpreted
+like the format argument of @command{date} (@pxref{date invocation}).
+For example, @option{--time-style="+%Y-%m-%d %H:%M:%S"} causes
+@command{du} to list timestamps like @samp{2002-03-30 23:45:56}.  As
+with @command{date}, @var{format}'s interpretation is affected by the
+@env{LC_TIME} locale category.
+
+@item full-iso
+List timestamps in full using ISO 8601-like date, time, and time zone
+components with nanosecond precision, e.g., @samp{2002-03-30
+23:45:56.477817180 -0700}.  This style is equivalent to
+@samp{+%Y-%m-%d %H:%M:%S.%N %z}.
+
+@item long-iso
+List ISO 8601 date and time components with minute precision, e.g.,
+@samp{2002-03-30 23:45}.  These timestamps are shorter than
+@samp{full-iso} timestamps, and are usually good enough for everyday
+work.  This style is equivalent to @samp{+%Y-%m-%d %H:%M}.
+
+@item iso
+List ISO 8601 dates for timestamps, e.g., @samp{2002-03-30}.
+This style is equivalent to @samp{+%Y-%m-%d}.
+@end table
+
+@vindex TIME_STYLE
+You can specify the default value of the @option{--time-style} option
+with the environment variable @env{TIME_STYLE}; if @env{TIME_STYLE} is not set
+the default style is @samp{long-iso}.  For compatibility with @command{ls},
+if @env{TIME_STYLE} begins with @samp{+} and contains a newline,
+the newline and any later characters are ignored; if @env{TIME_STYLE}
+begins with @samp{posix-} the @samp{posix-} is ignored; and if
+@env{TIME_STYLE} is @samp{locale} it is ignored.
+
+@item -X @var{file}
+@itemx --exclude-from=@var{file}
+@opindex -X @var{file}
+@opindex --exclude-from=@var{file}
+@cindex excluding files from @command{du}
+Like @option{--exclude}, except take the patterns to exclude from @var{file},
+one per line.  If @var{file} is @samp{-}, take the patterns from standard
+input.
+
+@item --exclude=@var{pattern}
+@opindex --exclude=@var{pattern}
+@cindex excluding files from @command{du}
+When recursing, skip subdirectories or files matching @var{pattern}.
+For example, @code{du --exclude='*.o'} excludes files whose names
+end in @samp{.o}.
+
+@item -x
+@itemx --one-file-system
+@opindex -x
+@opindex --one-file-system
+@cindex one file system, restricting @command{du} to
+Skip directories that are on different file systems from the one that
+the argument being processed is on.
+
+@end table
+
+@cindex NFS mounts from BSD to HP-UX
+On BSD systems, @command{du} reports sizes that are half the correct
+values for files that are NFS-mounted from HP-UX systems.  On HP-UX
+systems, it reports sizes that are twice the correct values for
+files that are NFS-mounted from BSD systems.  This is due to a flaw
+in HP-UX; it also affects the HP-UX @command{du} program.
+
+@exitstatus
+
+
+@node stat invocation
+@section @command{stat}: Report file or file system status
+
+@pindex stat
+@cindex file status
+@cindex file system status
+
+@command{stat} displays information about the specified file(s).  Synopsis:
+
+@example
+stat [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+With no option, @command{stat} reports all information about the given files.
+But it also can be used to report the information of the file systems the
+given files are located on.  If the files are links, @command{stat} can
+also give information about the files the links point to.
+
+@mayConflictWithShellBuiltIn{stat}
+
+@table @samp
+
+@item -L
+@itemx --dereference
+@opindex -L
+@opindex --dereference
+@cindex symbolic links, dereferencing in @command{stat}
+Change how @command{stat} treats symbolic links.
+With this option, @command{stat} acts on the file referenced
+by each symbolic link argument.
+Without it, @command{stat} acts on any symbolic link argument directly.
+
+@item -f
+@itemx --file-system
+@opindex -f
+@opindex --file-system
+@cindex file systems
+Report information about the file systems where the given files are located
+instead of information about the files themselves.
+This option implies the @option{-L} option.
+
+@item --cached=@var{mode}
+@opindex --cached=@var{mode}
+@cindex attribute caching
+Control how attributes are read from the file system;
+if supported by the system.  This allows one to
+control the trade-off between freshness and efficiency
+of attribute access, especially useful with remote file systems.
+@var{mode} can be:
+
+@table @samp
+@item always
+Always read the already cached attributes if available.
+
+@item never
+Always sychronize with the latest file system attributes.
+
+@item default
+Leave the caching behavior to the underlying file system.
+
+@end table
+
+@item -c
+@itemx --format=@var{format}
+@opindex -c
+@opindex --format=@var{format}
+@cindex output format
+Use @var{format} rather than the default format.
+@var{format} is automatically newline-terminated, so
+running a command like the following with two or more @var{file}
+operands produces a line of output for each operand:
+@example
+$ stat --format=%d:%i / /usr
+2050:2
+2057:2
+@end example
+
+@item --printf=@var{format}
+@opindex --printf=@var{format}
+@cindex output format
+Use @var{format} rather than the default format.
+Like @option{--format}, but interpret backslash escapes,
+and do not output a mandatory trailing newline.
+If you want a newline, include @samp{\n} in the @var{format}.
+Here's how you would use @option{--printf} to print the device
+and inode numbers of @file{/} and @file{/usr}:
+@example
+$ stat --printf='%d:%i\n' / /usr
+2050:2
+2057:2
+@end example
+
+@item -t
+@itemx --terse
+@opindex -t
+@opindex --terse
+@cindex terse output
+Print the information in terse form, suitable for parsing by other programs.
+
+The output of the following commands are identical and the @option{--format}
+also identifies the items printed (in fuller form) in the default format.
+Note the format string would include another @samp{%C} at the end with an
+active SELinux security context.
+@example
+$ stat --format="%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %W %o" ...
+$ stat --terse ...
+@end example
+
+The same illustrating terse output in @option{--file-system} mode:
+@example
+$ stat -f --format="%n %i %l %t %s %S %b %f %a %c %d" ...
+$ stat -f --terse ...
+@end example
+@end table
+
+The valid @var{format} directives for files with @option{--format} and
+@option{--printf} are:
+
+@itemize @bullet
+@item %a - Permission bits in octal (note @samp{#} and @samp{0} printf flags)
+@item %A - Permission bits in symbolic form (similar to @command{ls -ld})
+@item %b - Number of blocks allocated (see @samp{%B})
+@item %B - The size in bytes of each block reported by @samp{%b}
+@item %C - The SELinux security context of a file, if available
+@item %d - Device number in decimal
+@item %D - Device number in hex
+@item %f - Raw mode in hex
+@item %F - File type
+@item %g - Group ID of owner
+@item %G - Group name of owner
+@item %h - Number of hard links
+@item %i - Inode number
+@item %m - Mount point (See note below)
+@item %n - File name
+@item %N - Quoted file name with dereference if symbolic link (see below)
+@item %o - Optimal I/O transfer size hint
+@item %s - Total size, in bytes
+@item %t - Major device type in hex (see below)
+@item %T - Minor device type in hex (see below)
+@item %u - User ID of owner
+@item %U - User name of owner
+@item %w - Time of file birth, or @samp{-} if unknown
+@item %W - Time of file birth as seconds since Epoch, or @samp{0}
+@item %x - Time of last access
+@item %X - Time of last access as seconds since Epoch
+@item %y - Time of last data modification
+@item %Y - Time of last data modification as seconds since Epoch
+@item %z - Time of last status change
+@item %Z - Time of last status change as seconds since Epoch
+@end itemize
+
+The @samp{%a} format prints the octal mode, and so it is useful
+to control the zero padding of the output with the @samp{#} and @samp{0}
+printf flags. For example to pad to at least 3 wide while making larger
+numbers unambiguously octal, you can use @samp{%#03a}.
+
+The @samp{%N} format can be set with the environment variable
+@env{QUOTING_STYLE}@.  If that environment variable is not set,
+the default value is @samp{shell-escape-always}.  Valid quoting styles are:
+@quotingStyles
+
+The @samp{%t} and @samp{%T} formats operate on the st_rdev member of
+the stat(2) structure, and are only defined for character and block
+special files.  On some systems or file types, st_rdev may be used to
+represent other quantities.
+
+The @samp{%W}, @samp{%X}, @samp{%Y}, and @samp{%Z} formats accept a
+precision preceded by a period to specify the number of digits to
+print after the decimal point.  For example, @samp{%.3X} outputs the
+access timestamp to millisecond precision.  If a period is given but no
+precision, @command{stat} uses 9 digits, so @samp{%.X} is equivalent to
+@samp{%.9X}@.  When discarding excess precision, timestamps are truncated
+toward minus infinity.
+
+@example
+zero pad:
+  $ stat -c '[%015Y]' /usr
+  [000001288929712]
+space align:
+  $ stat -c '[%15Y]' /usr
+  [     1288929712]
+  $ stat -c '[%-15Y]' /usr
+  [1288929712     ]
+precision:
+  $ stat -c '[%.3Y]' /usr
+  [1288929712.114]
+  $ stat -c '[%.Y]' /usr
+  [1288929712.114951834]
+@end example
+
+The mount point printed by @samp{%m} is similar to that output
+by @command{df}, except that:
+@itemize @bullet
+@item
+stat does not dereference symlinks by default
+(unless @option{-L} is specified)
+@item
+stat does not search for specified device nodes in the
+file system list, instead operating on them directly
+@item
+@cindex bind mount
+stat outputs the alias for a bind mounted file, rather than
+the initial mount point of its backing device.
+One can recursively call stat until there is no change in output,
+to get the current base mount point
+@end itemize
+
+When listing file system information (@option{--file-system} (@option{-f})),
+you must use a different set of @var{format} directives:
+
+@itemize @bullet
+@item %a - Free blocks available to non-super-user
+@item %b - Total data blocks in file system
+@item %c - Total file nodes in file system
+@item %d - Free file nodes in file system
+@item %f - Free blocks in file system
+@item %i - File System ID in hex
+@item %l - Maximum length of file names
+@item %n - File name
+@item %s - Block size (for faster transfers)
+@item %S - Fundamental block size (for block counts)
+@item %t - Type in hex
+@item %T - Type in human readable form
+@end itemize
+
+@vindex TZ
+Timestamps are listed according to the time zone rules specified by
+the @env{TZ} environment variable, or by the system default rules if
+@env{TZ} is not set.  @xref{TZ Variable,, Specifying the Time Zone
+with @env{TZ}, libc, The GNU C Library Reference Manual}.
+
+@exitstatus
+
+
+@node sync invocation
+@section @command{sync}: Synchronize cached writes to persistent storage
+
+@pindex sync
+@cindex synchronize disk and memory
+@cindex Synchronize cached writes to persistent storage
+
+@command{sync} synchronizes in memory files or file systems to persistent
+storage.  Synopsis:
+
+@example
+sync [@var{option}] [@var{file}]@dots{}
+@end example
+
+@cindex superblock, writing
+@cindex inodes, written buffered
+@command{sync} writes any data buffered in memory out to disk.  This can
+include (but is not limited to) modified superblocks, modified inodes,
+and delayed reads and writes.  This must be implemented by the kernel;
+The @command{sync} program does nothing but exercise the @code{sync},
+@code{syncfs}, @code{fsync}, and @code{fdatasync} system calls.
+
+@cindex crashes and corruption
+The kernel keeps data in memory to avoid doing (relatively slow) disk
+reads and writes.  This improves performance, but if the computer
+crashes, data may be lost or the file system corrupted as a
+result.  The @command{sync} command instructs the kernel to write
+data in memory to persistent storage.
+
+If any argument is specified then only those files will be
+synchronized using the fsync(2) syscall by default.
+
+If at least one file is specified, it is possible to change the
+synchronization method with the following options.  Also see
+@ref{Common options}.
+
+@table @samp
+@item -d
+@itemx --data
+@opindex --data
+Use fdatasync(2) to sync only the data for the file,
+and any metadata required to maintain file system consistency.
+
+@item -f
+@itemx --file-system
+@opindex --file-system
+Synchronize all the I/O waiting for the file systems that contain the file,
+using the syscall syncfs(2).  Note you would usually @emph{not} specify
+this option if passing a device node like @samp{/dev/sda} for example,
+as that would sync the containing file system rather than the referenced one.
+Note also that depending on the system, passing individual device nodes or files
+may have different sync characteristics than using no arguments.
+I.e., arguments passed to fsync(2) may provide greater guarantees through
+write barriers, than a global sync(2) used when no arguments are provided.
+@end table
+
+@exitstatus
+
+
+@node truncate invocation
+@section @command{truncate}: Shrink or extend the size of a file
+
+@pindex truncate
+@cindex truncating, file sizes
+
+@command{truncate} shrinks or extends the size of each @var{file} to the
+specified size.  Synopsis:
+
+@example
+truncate @var{option}@dots{} @var{file}@dots{}
+@end example
+
+@cindex files, creating
+Any @var{file} that does not exist is created.
+
+@cindex sparse files, creating
+@cindex holes, creating files with
+If a @var{file} is larger than the specified size, the extra data is lost.
+If a @var{file} is shorter, it is extended and the sparse extended part
+(or hole) reads as zero bytes.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -c
+@itemx --no-create
+@opindex -c
+@opindex --no-create
+Do not create files that do not exist.
+
+@item -o
+@itemx --io-blocks
+@opindex -o
+@opindex --io-blocks
+Treat @var{size} as number of I/O blocks of the @var{file} rather than bytes.
+
+@item -r @var{rfile}
+@itemx --reference=@var{rfile}
+@opindex -r
+@opindex --reference
+Base the size of each @var{file} on the size of @var{rfile}.
+
+@item -s @var{size}
+@itemx --size=@var{size}
+@opindex -s
+@opindex --size
+Set or adjust the size of each @var{file} according to @var{size}.
+@var{size} is in bytes unless @option{--io-blocks} is specified.
+@multiplierSuffixesNoBlocks{size}
+
+@var{size} may also be prefixed by one of the following to adjust
+the size of each @var{file} based on its current size:
+@example
+@samp{+}  => extend by
+@samp{-}  => reduce by
+@samp{<}  => at most
+@samp{>}  => at least
+@samp{/}  => round down to multiple of
+@samp{%}  => round up to multiple of
+@end example
+
+@end table
+
+@exitstatus
+
+
+@node Printing text
+@chapter Printing text
+
+@cindex printing text, commands for
+@cindex commands for printing text
+
+This section describes commands that display text strings.
+
+@menu
+* echo invocation::             Print a line of text.
+* printf invocation::           Format and print data.
+* yes invocation::              Print a string until interrupted.
+@end menu
+
+
+@node echo invocation
+@section @command{echo}: Print a line of text
+
+@pindex echo
+@cindex displaying text
+@cindex printing text
+@cindex text, displaying
+@cindex arbitrary text, displaying
+
+@command{echo} writes each given @var{string} to standard output, with a
+space between each and a newline after the last one.  Synopsis:
+
+@example
+echo [@var{option}]@dots{} [@var{string}]@dots{}
+@end example
+
+@mayConflictWithShellBuiltIn{echo}
+
+The program accepts the following options.  Also see @ref{Common options}.
+Options must precede operands, and the normally-special argument
+@samp{--} has no special meaning and is treated like any other
+@var{string}.
+
+@table @samp
+@item -n
+@opindex -n
+Do not output the trailing newline.
+
+@item -e
+@opindex -e
+@cindex backslash escapes
+Enable interpretation of the following backslash-escaped characters in
+each @var{string}:
+
+@table @samp
+@item \a
+alert (bell)
+@item \b
+backspace
+@item \c
+produce no further output
+@item \e
+escape
+@item \f
+form feed
+@item \n
+newline
+@item \r
+carriage return
+@item \t
+horizontal tab
+@item \v
+vertical tab
+@item \\
+backslash
+@item \0@var{nnn}
+the eight-bit value that is the octal number @var{nnn}
+(zero to three octal digits), if @var{nnn} is
+a nine-bit value, the ninth bit is ignored
+@item \@var{nnn}
+the eight-bit value that is the octal number @var{nnn}
+(one to three octal digits), if @var{nnn} is
+a nine-bit value, the ninth bit is ignored
+@item \x@var{hh}
+the eight-bit value that is the hexadecimal number @var{hh}
+(one or two hexadecimal digits)
+@end table
+
+@item -E
+@opindex -E
+@cindex backslash escapes
+Disable interpretation of backslash escapes in each @var{string}.
+This is the default.  If @option{-e} and @option{-E} are both
+specified, the last one given takes effect.
+
+@end table
+
+@vindex POSIXLY_CORRECT
+If the @env{POSIXLY_CORRECT} environment variable is set, then when
+@command{echo}'s first argument is not @option{-n} it outputs
+option-like arguments instead of treating them as options.  For
+example, @code{echo -ne hello} outputs @samp{-ne hello} instead of
+plain @samp{hello}.  Also backslash escapes are always enabled.
+
+POSIX does not require support for any options, and says
+that the behavior of @command{echo} is implementation-defined if any
+@var{string} contains a backslash or if the first argument is
+@option{-n}.  Portable programs can use the @command{printf} command
+if they need to omit trailing newlines or output control characters or
+backslashes.  @xref{printf invocation}.
+
+@exitstatus
+
+
+@node printf invocation
+@section @command{printf}: Format and print data
+
+@pindex printf
+@command{printf} does formatted printing of text.  Synopsis:
+
+@example
+printf @var{format} [@var{argument}]@dots{}
+@end example
+
+@command{printf} prints the @var{format} string, interpreting @samp{%}
+directives and @samp{\} escapes to format numeric and string arguments
+in a way that is mostly similar to the C @samp{printf} function.
+@xref{Output Conversion Syntax,, @command{printf} format directives,
+libc, The GNU C Library Reference Manual}, for details.
+The differences are listed below.
+
+@mayConflictWithShellBuiltIn{printf}
+
+@itemize @bullet
+
+@item
+The @var{format} argument is reused as necessary to convert all the
+given @var{argument}s.  For example, the command @samp{printf %s a b}
+outputs @samp{ab}.
+
+@item
+Missing @var{argument}s are treated as null strings or as zeros,
+depending on whether the context expects a string or a number.  For
+example, the command @samp{printf %sx%d} prints @samp{x0}.
+
+@item
+@kindex \c
+An additional escape, @samp{\c}, causes @command{printf} to produce no
+further output.  For example, the command @samp{printf 'A%sC\cD%sF' B
+E} prints @samp{ABC}.
+
+@item
+The hexadecimal escape sequence @samp{\x@var{hh}} has at most two
+digits, as opposed to C where it can have an unlimited number of
+digits.  For example, the command @samp{printf '\x07e'} prints two
+bytes, whereas the C statement @samp{printf ("\x07e")} prints just
+one.
+
+@item
+@kindex %b
+An additional directive @samp{%b}, prints its
+argument string with @samp{\} escapes interpreted in the same way as in
+the @var{format} string, except that octal escapes are of the form
+@samp{\0@var{ooo}} where @var{ooo} is 0 to 3 octal digits.  If
+@samp{\@var{ooo}} is nine-bit value, ignore the ninth bit.
+If a precision is also given, it limits the number of bytes printed
+from the converted string.
+
+@item
+@kindex %q
+An additional directive @samp{%q}, prints its argument string
+in a format that can be reused as input by most shells.
+Non-printable characters are escaped with the POSIX proposed @samp{$''} syntax,
+and shell metacharacters are quoted appropriately.
+This is an equivalent format to @command{ls --quoting=shell-escape} output.
+
+@item
+Numeric arguments must be single C constants, possibly with leading
+@samp{+} or @samp{-}.  For example, @samp{printf %.4d -3} outputs
+@samp{-0003}.
+
+@item
+@vindex POSIXLY_CORRECT
+If the leading character of a numeric argument is @samp{"} or @samp{'}
+then its value is the numeric value of the immediately following
+character.  Any remaining characters are silently ignored if the
+@env{POSIXLY_CORRECT} environment variable is set; otherwise, a
+warning is printed.  For example, @samp{printf "%d" "'a"} outputs
+@samp{97} on hosts that use the ASCII character set, since
+@samp{a} has the numeric value 97 in ASCII.
+
+@end itemize
+
+@vindex LC_NUMERIC
+A floating point argument is interpreted according to
+the @env{LC_NUMERIC} category of either the current or the C locale,
+and is printed according to the current locale.
+For example, in a locale whose decimal point character is a comma,
+the command @samp{printf '%g %g' 2,5 2.5} outputs @samp{2,5 2,5}.
+@xref{Floating point}.
+
+@kindex \@var{ooo}
+@kindex \x@var{hh}
+@command{printf} interprets @samp{\@var{ooo}} in @var{format} as an octal number
+(if @var{ooo} is 1 to 3 octal digits) specifying a byte to print,
+and @samp{\x@var{hh}} as a hexadecimal number (if @var{hh} is 1 to 2 hex
+digits) specifying a character to print.
+Note however that when @samp{\@var{ooo}} specifies a number larger than 255,
+@command{printf} ignores the ninth bit.
+For example, @samp{printf '\400'} is equivalent to @samp{printf '\0'}.
+
+@kindex \uhhhh
+@kindex \Uhhhhhhhh
+@cindex Unicode
+@cindex ISO/IEC 10646
+@vindex LC_CTYPE
+@command{printf} interprets two character syntaxes introduced in
+ISO C 99:
+@samp{\u} for 16-bit Unicode (ISO/IEC 10646)
+characters, specified as
+four hexadecimal digits @var{hhhh}, and @samp{\U} for 32-bit Unicode
+characters, specified as eight hexadecimal digits @var{hhhhhhhh}.
+@command{printf} outputs the Unicode characters
+according to the @env{LC_CTYPE} locale.  Unicode characters in the ranges
+U+0000@dots{}U+009F, U+D800@dots{}U+DFFF cannot be specified by this syntax,
+except for U+0024 ($), U+0040 (@@), and U+0060 (@`).
+
+The processing of @samp{\u} and @samp{\U} requires a full-featured
+@code{iconv} facility.  It is activated on systems with glibc 2.2 (or newer),
+or when @code{libiconv} is installed prior to this package.  Otherwise
+@samp{\u} and @samp{\U} will print as-is.
+
+The only options are a lone @option{--help} or
+@option{--version}.  @xref{Common options}.
+Options must precede operands.
+
+The Unicode character syntaxes are useful for writing strings in a locale
+independent way.  For example, a string containing the Euro currency symbol
+
+@example
+$ env printf '\u20AC 14.95'
+@end example
+
+@noindent
+will be output correctly in all locales supporting the Euro symbol
+(ISO-8859-15, UTF-8, and others).  Similarly, a Chinese string
+
+@example
+$ env printf '\u4e2d\u6587'
+@end example
+
+@noindent
+will be output correctly in all Chinese locales (GB2312, BIG5, UTF-8, etc).
+
+Note that in these examples, the @command{printf} command has been
+invoked via @command{env} to ensure that we run the program found via
+your shell's search path, and not a shell alias or a built-in function.
+
+For larger strings, you don't need to look up the hexadecimal code
+values of each character one by one.  ASCII characters mixed with \u
+escape sequences is also known as the JAVA source file encoding.  You can
+use GNU recode 3.5c (or newer) to convert strings to this encoding.  Here
+is how to convert a piece of text into a shell script which will output
+this text in a locale-independent way:
+
+@example
+$ LC_CTYPE=zh_CN.big5 /usr/local/bin/printf \
+    '\u4e2d\u6587\n' > sample.txt
+$ recode BIG5..JAVA < sample.txt \
+    | sed -e "s|^|/usr/local/bin/printf '|" -e "s|$|\\\\n'|" \
+    > sample.sh
+@end example
+
+@exitstatus
+
+
+@node yes invocation
+@section @command{yes}: Print a string until interrupted
+
+@pindex yes
+@cindex repeated output of a string
+
+@command{yes} prints the command line arguments, separated by spaces and
+followed by a newline, forever until it is killed.  If no arguments are
+given, it prints @samp{y} followed by a newline forever until killed.
+
+Upon a write error, @command{yes} exits with status @samp{1}.
+
+The only options are a lone @option{--help} or @option{--version}.
+To output an argument that begins with
+@samp{-}, precede it with @option{--}, e.g., @samp{yes -- --help}.
+@xref{Common options}.
+
+
+@node Conditions
+@chapter Conditions
+
+@cindex conditions
+@cindex commands for exit status
+@cindex exit status commands
+
+This section describes commands that are primarily useful for their exit
+status, rather than their output.  Thus, they are often used as the
+condition of shell @code{if} statements, or as the last command in a
+pipeline.
+
+@menu
+* false invocation::            Do nothing, unsuccessfully.
+* true invocation::             Do nothing, successfully.
+* test invocation::             Check file types and compare values.
+* expr invocation::             Evaluate expressions.
+@end menu
+
+
+@node false invocation
+@section @command{false}: Do nothing, unsuccessfully
+
+@pindex false
+@cindex do nothing, unsuccessfully
+@cindex failure exit status
+@cindex exit status of @command{false}
+
+@command{false} does nothing except return an exit status of 1, meaning
+@dfn{failure}.  It can be used as a place holder in shell scripts
+where an unsuccessful command is needed.
+In most modern shells, @command{false} is a built-in command, so when
+you use @samp{false} in a script, you're probably using the built-in
+command, not the one documented here.
+
+@command{false} honors the @option{--help} and @option{--version} options.
+
+This version of @command{false} is implemented as a C program, and is thus
+more secure and faster than a shell script implementation, and may safely
+be used as a dummy shell for the purpose of disabling accounts.
+
+Note that @command{false} (unlike all other programs documented herein)
+exits unsuccessfully, even when invoked with
+@option{--help} or @option{--version}.
+
+Portable programs should not assume that the exit status of
+@command{false} is 1, as it is greater than 1 on some
+non-GNU hosts.
+
+
+@node true invocation
+@section @command{true}: Do nothing, successfully
+
+@pindex true
+@cindex do nothing, successfully
+@cindex no-op
+@cindex successful exit
+@cindex exit status of @command{true}
+
+@command{true} does nothing except return an exit status of 0, meaning
+@dfn{success}.  It can be used as a place holder in shell scripts
+where a successful command is needed, although the shell built-in
+command @code{:} (colon) may do the same thing faster.
+In most modern shells, @command{true} is a built-in command, so when
+you use @samp{true} in a script, you're probably using the built-in
+command, not the one documented here.
+
+@command{true} honors the @option{--help} and @option{--version} options.
+
+Note, however, that it is possible to cause @command{true}
+to exit with nonzero status: with the @option{--help} or @option{--version}
+option, and with standard
+output already closed or redirected to a file that evokes an I/O error.
+For example, using a Bourne-compatible shell:
+
+@example
+$ ./true --version >&-
+./true: write error: Bad file number
+$ ./true --version > /dev/full
+./true: write error: No space left on device
+@end example
+
+This version of @command{true} is implemented as a C program, and is thus
+more secure and faster than a shell script implementation, and may safely
+be used as a dummy shell for the purpose of disabling accounts.
+
+@node test invocation
+@section @command{test}: Check file types and compare values
+
+@pindex test
+@cindex check file types
+@cindex compare values
+@cindex expression evaluation
+
+@command{test} returns a status of 0 (true) or 1 (false) depending on the
+evaluation of the conditional expression @var{expr}.  Each part of the
+expression must be a separate argument.
+
+@command{test} has file status checks, string operators, and numeric
+comparison operators.
+
+@command{test} has an alternate form that uses opening and closing
+square brackets instead a leading @samp{test}.  For example, instead
+of @samp{test -d /}, you can write @samp{[ -d / ]}.  The square
+brackets must be separate arguments; for example, @samp{[-d /]} does
+not have the desired effect.  Since @samp{test @var{expr}} and @samp{[
+@var{expr} ]} have the same meaning, only the former form is discussed
+below.
+
+Synopses:
+
+@example
+test @var{expression}
+test
+[ @var{expression} ]
+[ ]
+[ @var{option}
+@end example
+
+@mayConflictWithShellBuiltIn{test}
+
+If @var{expression} is omitted, @command{test} returns false.
+If @var{expression} is a single argument,
+@command{test} returns false if the argument is null and true
+otherwise.  The argument
+can be any string, including strings like @samp{-d}, @samp{-1},
+@samp{--}, @samp{--help}, and @samp{--version} that most other
+programs would treat as options.  To get help and version information,
+invoke the commands @samp{[ --help} and @samp{[ --version}, without
+the usual closing brackets.  @xref{Common options}.
+
+@cindex exit status of @command{test}
+Exit status:
+
+@display
+0 if the expression is true,
+1 if the expression is false,
+2 if an error occurred.
+@end display
+
+@menu
+* File type tests::             -[bcdfhLpSt]
+* Access permission tests::     -[gkruwxOG]
+* File characteristic tests::   -e -s -nt -ot -ef
+* String tests::                -z -n = == !=
+* Numeric tests::               -eq -ne -lt -le -gt -ge
+* Connectives for test::        ! -a -o
+@end menu
+
+
+@node File type tests
+@subsection File type tests
+
+@cindex file type tests
+
+These options test for particular types of files.  (Everything's a file,
+but not all files are the same!)
+
+@table @samp
+
+@item -b @var{file}
+@opindex -b
+@cindex block special check
+True if @var{file} exists and is a block special device.
+
+@item -c @var{file}
+@opindex -c
+@cindex character special check
+True if @var{file} exists and is a character special device.
+
+@item -d @var{file}
+@opindex -d
+@cindex directory check
+True if @var{file} exists and is a directory.
+
+@item -f @var{file}
+@opindex -f
+@cindex regular file check
+True if @var{file} exists and is a regular file.
+
+@item -h @var{file}
+@itemx -L @var{file}
+@opindex -L
+@opindex -h
+@cindex symbolic link check
+True if @var{file} exists and is a symbolic link.
+Unlike all other file-related tests, this test does not dereference
+@var{file} if it is a symbolic link.
+
+@item -p @var{file}
+@opindex -p
+@cindex named pipe check
+True if @var{file} exists and is a named pipe.
+
+@item -S @var{file}
+@opindex -S
+@cindex socket check
+True if @var{file} exists and is a socket.
+
+@item -t @var{fd}
+@opindex -t
+@cindex terminal check
+True if @var{fd} is a file descriptor that is associated with a
+terminal.
+
+@end table
+
+
+@node Access permission tests
+@subsection Access permission tests
+
+@cindex access permission tests
+@cindex permission tests
+
+These options test for particular access permissions.
+
+@table @samp
+
+@item -g @var{file}
+@opindex -g
+@cindex set-group-ID check
+True if @var{file} exists and has its set-group-ID bit set.
+
+@item -k @var{file}
+@opindex -k
+@cindex sticky bit check
+True if @var{file} exists and has its @dfn{sticky} bit set.
+
+@item -r @var{file}
+@opindex -r
+@cindex readable file check
+True if @var{file} exists and read permission is granted.
+
+@item -u @var{file}
+@opindex -u
+@cindex set-user-ID check
+True if @var{file} exists and has its set-user-ID bit set.
+
+@item -w @var{file}
+@opindex -w
+@cindex writable file check
+True if @var{file} exists and write permission is granted.
+
+@item -x @var{file}
+@opindex -x
+@cindex executable file check
+True if @var{file} exists and execute permission is granted
+(or search permission, if it is a directory).
+
+@item -O @var{file}
+@opindex -O
+@cindex owned by effective user ID check
+True if @var{file} exists and is owned by the current effective user ID.
+
+@item -G @var{file}
+@opindex -G
+@cindex owned by effective group ID check
+True if @var{file} exists and is owned by the current effective group ID.
+
+@end table
+
+@node File characteristic tests
+@subsection File characteristic tests
+
+@cindex file characteristic tests
+
+These options test other file characteristics.
+
+@table @samp
+
+@item -e @var{file}
+@opindex -e
+@cindex existence-of-file check
+True if @var{file} exists.
+
+@item -s @var{file}
+@opindex -s
+@cindex nonempty file check
+True if @var{file} exists and has a size greater than zero.
+
+@item @var{file1} -nt @var{file2}
+@opindex -nt
+@cindex newer-than file check
+True if @var{file1} is newer (according to modification date) than
+@var{file2}, or if @var{file1} exists and @var{file2} does not.
+
+@item @var{file1} -ot @var{file2}
+@opindex -ot
+@cindex older-than file check
+True if @var{file1} is older (according to modification date) than
+@var{file2}, or if @var{file2} exists and @var{file1} does not.
+
+@item @var{file1} -ef @var{file2}
+@opindex -ef
+@cindex same file check
+@cindex hard link check
+True if @var{file1} and @var{file2} have the same device and inode
+numbers, i.e., if they are hard links to each other.
+
+@item -N @var{file}
+@opindex -N
+@cindex mtime-greater-atime file check
+True if @var{file} exists and has been modified (mtime) since it was
+last read (atime).
+
+@end table
+
+
+@node String tests
+@subsection String tests
+
+@cindex string tests
+
+These options test string characteristics.  You may need to quote
+@var{string} arguments for the shell.  For example:
+
+@example
+test -n "$V"
+@end example
+
+The quotes here prevent the wrong arguments from being passed to
+@command{test} if @samp{$V} is empty or contains special characters.
+
+@table @samp
+
+@item -z @var{string}
+@opindex -z
+@cindex zero-length string check
+True if the length of @var{string} is zero.
+
+@item -n @var{string}
+@itemx @var{string}
+@opindex -n
+@cindex nonzero-length string check
+True if the length of @var{string} is nonzero.
+
+@item @var{string1} = @var{string2}
+@opindex =
+@cindex equal string check
+True if the strings are equal.
+
+@item @var{string1} == @var{string2}
+@opindex ==
+@cindex equal string check
+True if the strings are equal (synonym for =).
+
+@item @var{string1} != @var{string2}
+@opindex !=
+@cindex not-equal string check
+True if the strings are not equal.
+
+@end table
+
+
+@node Numeric tests
+@subsection Numeric tests
+
+@cindex numeric tests
+@cindex arithmetic tests
+
+Numeric relational operators.  The arguments must be entirely numeric
+(possibly negative), or the special expression @w{@code{-l @var{string}}},
+which evaluates to the length of @var{string}.
+
+@table @samp
+
+@item @var{arg1} -eq @var{arg2}
+@itemx @var{arg1} -ne @var{arg2}
+@itemx @var{arg1} -lt @var{arg2}
+@itemx @var{arg1} -le @var{arg2}
+@itemx @var{arg1} -gt @var{arg2}
+@itemx @var{arg1} -ge @var{arg2}
+@opindex -eq
+@opindex -ne
+@opindex -lt
+@opindex -le
+@opindex -gt
+@opindex -ge
+These arithmetic binary operators return true if @var{arg1} is equal,
+not-equal, less-than, less-than-or-equal, greater-than, or
+greater-than-or-equal than @var{arg2}, respectively.
+
+@end table
+
+For example:
+
+@example
+test -1 -gt -2 && echo yes
+@result{} yes
+test -l abc -gt 1 && echo yes
+@result{} yes
+test 0x100 -eq 1
+@error{} test: integer expression expected before -eq
+@end example
+
+
+@node Connectives for test
+@subsection Connectives for @command{test}
+
+@cindex logical connectives
+@cindex connectives, logical
+
+Note it's preferred to use shell logical primitives
+rather than these logical connectives internal to @command{test},
+because an expression may become ambiguous
+depending on the expansion of its parameters.
+
+For example, this becomes ambiguous when @samp{$1}
+is set to @samp{'!'} and @samp{$2} to the empty string @samp{''}:
+
+@example
+test "$1" -a "$2"
+@end example
+
+and should be written as:
+
+@example
+test "$1" && test "$2"
+@end example
+
+Note the shell logical primitives also benefit from
+short circuit operation, which can be significant
+for file attribute tests.
+
+@table @samp
+
+@item ! @var{expr}
+@opindex !
+True if @var{expr} is false.
+@samp{!} has lower precedence than all parts of @var{expr}.
+Note @samp{!} needs to be specified to the left
+of a binary expression, I.e., @samp{'!' 1 -gt 2}
+rather than @samp{1 '!' -gt 2}.
+Also @samp{!} is often a shell special character
+and is best used quoted.
+
+
+@item @var{expr1} -a @var{expr2}
+@opindex -a
+@cindex logical and operator
+@cindex and operator
+True if both @var{expr1} and @var{expr2} are true.
+@samp{-a} is left associative,
+and has a higher precedence than @samp{-o}.
+
+@item @var{expr1} -o @var{expr2}
+@opindex -o
+@cindex logical or operator
+@cindex or operator
+True if either @var{expr1} or @var{expr2} is true.
+@samp{-o} is left associative.
+
+@end table
+
+
+@node expr invocation
+@section @command{expr}: Evaluate expressions
+
+@pindex expr
+@cindex expression evaluation
+@cindex evaluation of expressions
+
+@command{expr} evaluates an expression and writes the result on standard
+output.  Each token of the expression must be a separate argument.
+
+Operands are either integers or strings.  Integers consist of one or
+more decimal digits, with an optional leading @samp{-}.
+@command{expr} converts
+anything appearing in an operand position to an integer or a string
+depending on the operation being applied to it.
+
+Strings are not quoted for @command{expr} itself, though you may need to
+quote them to protect characters with special meaning to the shell,
+e.g., spaces.  However, regardless of whether it is quoted, a string
+operand should not be a parenthesis or any of @command{expr}'s
+operators like @code{+}, so you cannot safely pass an arbitrary string
+@code{$str} to expr merely by quoting it to the shell.  One way to
+work around this is to use the GNU extension @code{+},
+(e.g., @code{+ "$str" = foo}); a more portable way is to use
+@code{@w{" $str"}} and to adjust the rest of the expression to take
+the leading space into account (e.g., @code{@w{" $str" = " foo"}}).
+
+You should not pass a negative integer or a string with leading
+@samp{-} as @command{expr}'s first argument, as it might be
+misinterpreted as an option; this can be avoided by parenthesization.
+Also, portable scripts should not use a string operand that happens to
+take the form of an integer; this can be worked around by inserting
+leading spaces as mentioned above.
+
+@cindex parentheses for grouping
+Operators may be given as infix symbols or prefix keywords.  Parentheses
+may be used for grouping in the usual manner.  You must quote
+parentheses and many operators to avoid the shell evaluating them,
+however.
+
+When built with support for the GNU MP library, @command{expr} uses
+arbitrary-precision arithmetic; otherwise, it uses native arithmetic
+types and may fail due to arithmetic overflow.
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.  Options must precede operands.
+
+@cindex exit status of @command{expr}
+Exit status:
+
+@display
+0 if the expression is neither null nor 0,
+1 if the expression is null or 0,
+2 if the expression is invalid,
+3 if an internal error occurred (e.g., arithmetic overflow).
+@end display
+
+@menu
+* String expressions::          + : match substr index length
+* Numeric expressions::         + - * / %
+* Relations for expr::          | & < <= = == != >= >
+* Examples of expr::            Examples.
+@end menu
+
+
+@node String expressions
+@subsection String expressions
+
+@cindex string expressions
+@cindex expressions, string
+
+@command{expr} supports pattern matching and other string operators.  These
+have higher precedence than both the numeric and relational operators (in
+the next sections).
+
+@table @samp
+
+@item @var{string} : @var{regex}
+@cindex pattern matching
+@cindex regular expression matching
+@cindex matching patterns
+Perform pattern matching.  The arguments are converted to strings and the
+second is considered to be a (basic, a la GNU @code{grep}) regular
+expression, with a @code{^} implicitly prepended.  The first argument is
+then matched against this regular expression.
+
+If the match succeeds and @var{regex} uses @samp{\(} and @samp{\)}, the
+@code{:} expression returns the part of @var{string} that matched the
+subexpression; otherwise, it returns the number of characters matched.
+
+If the match fails, the @code{:} operator returns the null string if
+@samp{\(} and @samp{\)} are used in @var{regex}, otherwise 0.
+
+@kindex \( @r{regexp operator}
+Only the first @samp{\( @dots{} \)} pair is relevant to the return
+value; additional pairs are meaningful only for grouping the regular
+expression operators.
+
+@kindex \+ @r{regexp operator}
+@kindex \? @r{regexp operator}
+@kindex \| @r{regexp operator}
+In the regular expression, @code{\+}, @code{\?}, and @code{\|} are
+operators which respectively match one or more, zero or one, or separate
+alternatives.  SunOS and other @command{expr}'s treat these as regular
+characters.  (POSIX allows either behavior.)
+@xref{Top, , Regular Expression Library, regex, Regex}, for details of
+regular expression syntax.  Some examples are in @ref{Examples of expr}.
+
+@item match @var{string} @var{regex}
+@findex match
+An alternative way to do pattern matching.  This is the same as
+@w{@samp{@var{string} : @var{regex}}}.
+
+@item substr @var{string} @var{position} @var{length}
+@findex substr
+Returns the substring of @var{string} beginning at @var{position}
+with length at most @var{length}.  If either @var{position} or
+@var{length} is negative, zero, or non-numeric, returns the null string.
+
+@item index @var{string} @var{charset}
+@findex index
+Returns the first position in @var{string} where the first character in
+@var{charset} was found.  If no character in @var{charset} is found in
+@var{string}, return 0.
+
+@item length @var{string}
+@findex length
+Returns the length of @var{string}.
+
+@item + @var{token}
+@kindex +
+Interpret @var{token} as a string, even if it is a keyword like @var{match}
+or an operator like @code{/}.
+This makes it possible to test @code{expr length + "$x"} or
+@code{expr + "$x" : '.*/\(.\)'} and have it do the right thing even if
+the value of @var{$x} happens to be (for example) @code{/} or @code{index}.
+This operator is a GNU extension.  Portable shell scripts should use
+@code{@w{" $token"} : @w{' \(.*\)'}} instead of @code{+ "$token"}.
+
+@end table
+
+To make @command{expr} interpret keywords as strings, you must use the
+@code{quote} operator.
+
+
+@node Numeric expressions
+@subsection Numeric expressions
+
+@cindex numeric expressions
+@cindex expressions, numeric
+
+@command{expr} supports the usual numeric operators, in order of increasing
+precedence.  These numeric operators have lower precedence than the
+string operators described in the previous section, and higher precedence
+than the connectives (next section).
+
+@table @samp
+
+@item + -
+@kindex +
+@kindex -
+@cindex addition
+@cindex subtraction
+Addition and subtraction.  Both arguments are converted to integers;
+an error occurs if this cannot be done.
+
+@item * / %
+@kindex *
+@kindex /
+@kindex %
+@cindex multiplication
+@cindex division
+@cindex remainder
+Multiplication, division, remainder.  Both arguments are converted to
+integers; an error occurs if this cannot be done.
+
+@end table
+
+
+@node Relations for expr
+@subsection Relations for @command{expr}
+
+@cindex connectives, logical
+@cindex logical connectives
+@cindex relations, numeric or string
+
+@command{expr} supports the usual logical connectives and relations.  These
+have lower precedence than the string and numeric operators
+(previous sections).  Here is the list, lowest-precedence operator first.
+
+@table @samp
+
+@item |
+@kindex |
+@cindex logical or operator
+@cindex or operator
+Returns its first argument if that is neither null nor zero, otherwise
+its second argument if it is neither null nor zero, otherwise 0.  It
+does not evaluate its second argument if its first argument is neither
+null nor zero.
+
+@item &
+@kindex &
+@cindex logical and operator
+@cindex and operator
+Return its first argument if neither argument is null or zero, otherwise
+0.  It does not evaluate its second argument if its first argument is
+null or zero.
+
+@item < <= = == != >= >
+@kindex <
+@kindex <=
+@kindex =
+@kindex ==
+@kindex >
+@kindex >=
+@cindex comparison operators
+@vindex LC_COLLATE
+Compare the arguments and return 1 if the relation is true, 0 otherwise.
+@code{==} is a synonym for @code{=}.  @command{expr} first tries to convert
+both arguments to integers and do a numeric comparison; if either
+conversion fails, it does a lexicographic comparison using the character
+collating sequence specified by the @env{LC_COLLATE} locale.
+
+@end table
+
+
+@node Examples of expr
+@subsection Examples of using @command{expr}
+
+@cindex examples of @command{expr}
+Here are a few examples, including quoting for shell metacharacters.
+
+To add 1 to the shell variable @code{foo}, in Bourne-compatible shells:
+
+@example
+foo=$(expr $foo + 1)
+@end example
+
+To print the non-directory part of the file name stored in
+@code{$fname}, which need not contain a @code{/}:
+
+@example
+expr $fname : '.*/\(.*\)' '|' $fname
+@end example
+
+An example showing that @code{\+} is an operator:
+
+@example
+expr aaa : 'a\+'
+@result{} 3
+@end example
+
+@example
+expr abc : 'a\(.\)c'
+@result{} b
+expr index abcdef cz
+@result{} 3
+expr index index a
+@error{} expr: syntax error
+expr index + index a
+@result{} 0
+@end example
+
+
+@node Redirection
+@chapter Redirection
+
+@cindex redirection
+@cindex commands for redirection
+
+Unix shells commonly provide several forms of @dfn{redirection}---ways
+to change the input source or output destination of a command.  But one
+useful redirection is performed by a separate command, not by the shell;
+it's described here.
+
+@menu
+* tee invocation::              Redirect output to multiple files or processes.
+@end menu
+
+
+@node tee invocation
+@section @command{tee}: Redirect output to multiple files or processes
+
+@pindex tee
+@cindex pipe fitting
+@cindex destinations, multiple output
+@cindex read from stdin and write to stdout and files
+
+The @command{tee} command copies standard input to standard output and also
+to any files given as arguments.  This is useful when you want not only
+to send some data down a pipe, but also to save a copy.  Synopsis:
+
+@example
+tee [@var{option}]@dots{} [@var{file}]@dots{}
+@end example
+
+If a file being written to does not already exist, it is created.  If a
+file being written to already exists, the data it previously contained
+is overwritten unless the @option{-a} option is used.
+
+In previous versions of GNU coreutils (v5.3.0 - v8.23), a @var{file} of @samp{-}
+caused @command{tee} to send another copy of input to standard output.
+However, as the interleaved output was not very useful, @command{tee} now
+conforms to POSIX which explicitly mandates it to treat @samp{-} as a file
+with such name.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+@item -a
+@itemx --append
+@opindex -a
+@opindex --append
+Append standard input to the given files rather than overwriting
+them.
+
+@item -i
+@itemx --ignore-interrupts
+@opindex -i
+@opindex --ignore-interrupts
+Ignore interrupt signals.
+
+@item -p
+@itemx --output-error[=@var{mode}]
+@opindex -p
+@opindex --output-error
+Adjust the behavior with errors on the outputs,
+with the long form option supporting selection
+between the following @var{mode}s:
+
+@table @samp
+@item warn
+Warn on error opening or writing any output, including pipes.
+Writing is continued to still open files/pipes.
+Exit status indicates failure if any output has an error.
+
+@item warn-nopipe
+This is the default @var{mode} when not specified,
+or when the short form @option{-p} is used.
+Warn on error opening or writing any output, except pipes.
+Writing is continued to still open files/pipes.
+Exit status indicates failure if any non pipe output had an error.
+
+@item exit
+Exit on error opening or writing any output, including pipes.
+
+@item exit-nopipe
+Exit on error opening or writing any output, except pipes.
+@end table
+
+@end table
+
+The @command{tee} command is useful when you happen to be transferring a large
+amount of data and also want to summarize that data without reading
+it a second time.  For example, when you are downloading a DVD image,
+you often want to verify its signature or checksum right away.
+The inefficient way to do it is simply:
+
+@example
+wget https://example.com/some.iso && sha1sum some.iso
+@end example
+
+One problem with the above is that it makes you wait for the
+download to complete before starting the time-consuming SHA1 computation.
+Perhaps even more importantly, the above requires reading
+the DVD image a second time (the first was from the network).
+
+The efficient way to do it is to interleave the download
+and SHA1 computation.  Then, you'll get the checksum for
+free, because the entire process parallelizes so well:
+
+@example
+# slightly contrived, to demonstrate process substitution
+wget -O - https://example.com/dvd.iso \
+  | tee >(sha1sum > dvd.sha1) > dvd.iso
+@end example
+
+That makes @command{tee} write not just to the expected output file,
+but also to a pipe running @command{sha1sum} and saving the final
+checksum in a file named @file{dvd.sha1}.
+
+Note, however, that this example relies on a feature of modern shells
+called @dfn{process substitution}
+(the @samp{>(command)} syntax, above;
+@xref{Process Substitution,,Process Substitution, bash,
+The Bash Reference Manual}.),
+so it works with @command{zsh}, @command{bash}, and @command{ksh},
+but not with @command{/bin/sh}.  So if you write code like this
+in a shell script, be sure to start the script with @samp{#!/bin/bash}.
+
+Note also that if any of the process substitutions (or piped stdout)
+might exit early without consuming all the data, the @option{-p} option
+is needed to allow @command{tee} to continue to process the input
+to any remaining outputs.
+
+Since the above example writes to one file and one process,
+a more conventional and portable use of @command{tee} is even better:
+
+@example
+wget -O - https://example.com/dvd.iso \
+  | tee dvd.iso | sha1sum > dvd.sha1
+@end example
+
+You can extend this example to make @command{tee} write to two processes,
+computing MD5 and SHA1 checksums in parallel.  In this case,
+process substitution is required:
+
+@example
+wget -O - https://example.com/dvd.iso \
+  | tee >(sha1sum > dvd.sha1) \
+        >(md5sum > dvd.md5) \
+  > dvd.iso
+@end example
+
+This technique is also useful when you want to make a @emph{compressed}
+copy of the contents of a pipe.
+Consider a tool to graphically summarize disk usage data from @samp{du -ak}.
+For a large hierarchy, @samp{du -ak} can run for a long time,
+and can easily produce terabytes of data, so you won't want to
+rerun the command unnecessarily.  Nor will you want to save
+the uncompressed output.
+
+Doing it the inefficient way, you can't even start the GUI
+until after you've compressed all of the @command{du} output:
+
+@example
+du -ak | gzip -9 > /tmp/du.gz
+gzip -d /tmp/du.gz | xdiskusage -a
+@end example
+
+With @command{tee} and process substitution, you start the GUI
+right away and eliminate the decompression completely:
+
+@example
+du -ak | tee >(gzip -9 > /tmp/du.gz) | xdiskusage -a
+@end example
+
+Finally, if you regularly create more than one type of
+compressed tarball at once, for example when @code{make dist} creates
+both @command{gzip}-compressed and @command{bzip2}-compressed tarballs,
+there may be a better way.
+Typical @command{automake}-generated @file{Makefile} rules create
+the two compressed tar archives with commands in sequence, like this
+(slightly simplified):
+
+@example
+tardir=your-pkg-M.N
+tar chof - "$tardir" | gzip  -9 -c > your-pkg-M.N.tar.gz
+tar chof - "$tardir" | bzip2 -9 -c > your-pkg-M.N.tar.bz2
+@end example
+
+However, if the hierarchy you are archiving and compressing is larger
+than a couple megabytes, and especially if you are using a multi-processor
+system with plenty of memory, then you can do much better by reading the
+directory contents only once and running the compression programs in parallel:
+
+@example
+tardir=your-pkg-M.N
+tar chof - "$tardir" \
+  | tee >(gzip -9 -c > your-pkg-M.N.tar.gz) \
+  | bzip2 -9 -c > your-pkg-M.N.tar.bz2
+@end example
+
+If you want to further process the output from process substitutions,
+and those processes write atomically (i.e., write less than the system's
+PIPE_BUF size at a time), that's possible with a construct like:
+
+@example
+tardir=your-pkg-M.N
+tar chof - "$tardir" \
+  | tee >(md5sum --tag) > >(sha256sum --tag) \
+  | sort | gpg --clearsign > your-pkg-M.N.tar.sig
+@end example
+
+@exitstatus
+
+
+@node File name manipulation
+@chapter File name manipulation
+
+@cindex file name manipulation
+@cindex manipulation of file names
+@cindex commands for file name manipulation
+
+This section describes commands that manipulate file names.
+
+@menu
+* basename invocation::         Strip directory and suffix from a file name.
+* dirname invocation::          Strip last file name component.
+* pathchk invocation::          Check file name validity and portability.
+* mktemp invocation::           Create temporary file or directory.
+* realpath invocation::         Print resolved file names.
+@end menu
+
+
+@node basename invocation
+@section @command{basename}: Strip directory and suffix from a file name
+
+@pindex basename
+@cindex strip directory and suffix from file names
+@cindex directory, stripping from file names
+@cindex suffix, stripping from file names
+@cindex file names, stripping directory and suffix
+@cindex leading directory components, stripping
+
+@command{basename} removes any leading directory components from
+@var{name}.  Synopsis:
+
+@example
+basename @var{name} [@var{suffix}]
+basename @var{option}@dots{} @var{name}@dots{}
+@end example
+
+If @var{suffix} is specified and is identical to the end of @var{name},
+it is removed from @var{name} as well.  Note that since trailing slashes
+are removed prior to suffix matching, @var{suffix} will do nothing if it
+contains slashes.  @command{basename} prints the result on standard
+output.
+
+@c This test is used both here and in the section on dirname.
+@macro basenameAndDirname
+Together, @command{basename} and @command{dirname} are designed such
+that if @samp{ls "$name"} succeeds, then the command sequence @samp{cd
+"$(dirname "$name")"; ls "$(basename "$name")"} will, too.  This works
+for everything except file names containing a trailing newline.
+@end macro
+@basenameAndDirname
+
+POSIX allows the implementation to define the results if
+@var{name} is empty or @samp{//}.  In the former case, GNU
+@command{basename} returns the empty string.  In the latter case, the
+result is @samp{//} on platforms where @var{//} is distinct from
+@var{/}, and @samp{/} on platforms where there is no difference.
+
+The program accepts the following options.  Also see @ref{Common options}.
+Options must precede operands.
+
+@table @samp
+
+@item -a
+@itemx --multiple
+@opindex -a
+@opindex --multiple
+Support more than one argument.  Treat every argument as a @var{name}.
+With this, an optional @var{suffix} must be specified using the
+@option{-s} option.
+
+@item -s @var{suffix}
+@itemx --suffix=@var{suffix}
+@opindex -s
+@opindex --suffix
+Remove a trailing @var{suffix}.
+This option implies the @option{-a} option.
+
+@optZero
+
+@end table
+
+@exitstatus
+
+Examples:
+
+@example
+# Output "sort".
+basename /usr/bin/sort
+
+# Output "stdio".
+basename include/stdio.h .h
+
+# Output "stdio".
+basename -s .h include/stdio.h
+
+# Output "stdio" followed by "stdlib"
+basename -a -s .h include/stdio.h include/stdlib.h
+@end example
+
+
+@node dirname invocation
+@section @command{dirname}: Strip last file name component
+
+@pindex dirname
+@cindex directory components, printing
+@cindex stripping non-directory suffix
+@cindex non-directory suffix, stripping
+
+@command{dirname} prints all but the final slash-delimited component
+of each @var{name}.  Slashes on either side of the final component are
+also removed.  If the string contains no slash, @command{dirname}
+prints @samp{.} (meaning the current directory).  Synopsis:
+
+@example
+dirname [@var{option}] @var{name}@dots{}
+@end example
+
+@var{name} need not be a file name, but if it is, this operation
+effectively lists the directory that contains the final component,
+including the case when the final component is itself a directory.
+
+@basenameAndDirname
+
+POSIX allows the implementation to define the results if
+@var{name} is @samp{//}.  With GNU @command{dirname}, the
+result is @samp{//} on platforms where @var{//} is distinct from
+@var{/}, and @samp{/} on platforms where there is no difference.
+
+The program accepts the following option.  Also see @ref{Common options}.
+
+@table @samp
+
+@optZero
+
+@end table
+
+@exitstatus
+
+Examples:
+
+@example
+# Output "/usr/bin".
+dirname /usr/bin/sort
+dirname /usr/bin//.//
+
+# Output "dir1" followed by "dir2"
+dirname dir1/str dir2/str
+
+# Output ".".
+dirname stdio.h
+@end example
+
+
+@node pathchk invocation
+@section @command{pathchk}: Check file name validity and portability
+
+@pindex pathchk
+@cindex file names, checking validity and portability
+@cindex valid file names, checking for
+@cindex portable file names, checking for
+
+@command{pathchk} checks validity and portability of file names.  Synopsis:
+
+@example
+pathchk [@var{option}]@dots{} @var{name}@dots{}
+@end example
+
+For each @var{name}, @command{pathchk} prints an error message if any of
+these conditions is true:
+
+@enumerate
+@item
+One of the existing directories in @var{name} does not have search
+(execute) permission,
+@item
+The length of @var{name} is larger than the maximum supported by the
+operating system.
+@item
+The length of one component of @var{name} is longer than
+its file system's maximum.
+@end enumerate
+
+A nonexistent @var{name} is not an error, so long a file with that
+name could be created under the above conditions.
+
+The program accepts the following options.  Also see @ref{Common options}.
+Options must precede operands.
+
+@table @samp
+
+@item -p
+@opindex -p
+Instead of performing checks based on the underlying file system,
+print an error message if any of these conditions is true:
+
+@enumerate
+@item
+A file name is empty.
+
+@item
+A file name contains a character outside the POSIX portable file
+name character set, namely, the ASCII letters and digits, @samp{.},
+@samp{_}, @samp{-}, and @samp{/}.
+
+@item
+The length of a file name or one of its components exceeds the
+POSIX minimum limits for portability.
+@end enumerate
+
+@item -P
+@opindex -P
+Print an error message if a file name is empty, or if it contains a component
+that begins with @samp{-}.
+
+@item --portability
+@opindex --portability
+Print an error message if a file name is not portable to all POSIX
+hosts.  This option is equivalent to @samp{-p -P}.
+
+@end table
+
+@cindex exit status of @command{pathchk}
+Exit status:
+
+@display
+0 if all specified file names passed all checks,
+1 otherwise.
+@end display
+
+@node mktemp invocation
+@section @command{mktemp}: Create temporary file or directory
+
+@pindex mktemp
+@cindex file names, creating temporary
+@cindex directory, creating temporary
+@cindex temporary files and directories
+
+@command{mktemp} manages the creation of temporary files and
+directories.  Synopsis:
+
+@example
+mktemp [@var{option}]@dots{} [@var{template}]
+@end example
+
+Safely create a temporary file or directory based on @var{template},
+and print its name.  If given, @var{template} must include at least
+three consecutive @samp{X}s in the last component.  If omitted, the template
+@samp{tmp.XXXXXXXXXX} is used, and option @option{--tmpdir} is
+implied.  The final run of @samp{X}s in the @var{template} will be replaced
+by alpha-numeric characters; thus, on a case-sensitive file system,
+and with a @var{template} including a run of @var{n} instances of @samp{X},
+there are @samp{62**@var{n}} potential file names.
+
+Older scripts used to create temporary files by simply joining the
+name of the program with the process id (@samp{$$}) as a suffix.
+However, that naming scheme is easily predictable, and suffers from a
+race condition where the attacker can create an appropriately named
+symbolic link, such that when the script then opens a handle to what
+it thought was an unused file, it is instead modifying an existing
+file.  Using the same scheme to create a directory is slightly safer,
+since the @command{mkdir} will fail if the target already exists, but
+it is still inferior because it allows for denial of service attacks.
+Therefore, modern scripts should use the @command{mktemp} command to
+guarantee that the generated name will be unpredictable, and that
+knowledge of the temporary file name implies that the file was created
+by the current script and cannot be modified by other users.
+
+When creating a file, the resulting file has read and write
+permissions for the current user, but no permissions for the group or
+others; these permissions are reduced if the current umask is more
+restrictive.
+
+Here are some examples (although note that if you repeat them, you
+will most likely get different file names):
+
+@itemize @bullet
+
+@item
+Create a temporary file in the current directory.
+@example
+$ mktemp file.XXXX
+file.H47c
+@end example
+
+@item
+Create a temporary file with a known suffix.
+@example
+$ mktemp --suffix=.txt file-XXXX
+file-H08W.txt
+$ mktemp file-XXXX-XXXX.txt
+file-XXXX-eI9L.txt
+@end example
+
+@item
+Create a secure fifo relative to the user's choice of @env{TMPDIR},
+but falling back to the current directory rather than @file{/tmp}.
+Note that @command{mktemp} does not create fifos, but can create a
+secure directory in which the fifo can live.  Exit the shell if the
+directory or fifo could not be created.
+@example
+$ dir=$(mktemp -p "$@{TMPDIR:-.@}" -d dir-XXXX) || exit 1
+$ fifo=$dir/fifo
+$ mkfifo "$fifo" || @{ rmdir "$dir"; exit 1; @}
+@end example
+
+@item
+Create and use a temporary file if possible, but ignore failure.  The
+file will reside in the directory named by @env{TMPDIR}, if specified,
+or else in @file{/tmp}.
+@example
+$ file=$(mktemp -q) && @{
+>   # Safe to use $file only within this block.  Use quotes,
+>   # since $TMPDIR, and thus $file, may contain whitespace.
+>   echo ... > "$file"
+>   rm "$file"
+> @}
+@end example
+
+@item
+Act as a semi-random character generator (it is not fully random,
+since it is impacted by the contents of the current directory).  To
+avoid security holes, do not use the resulting names to create a file.
+@example
+$ mktemp -u XXX
+Gb9
+$ mktemp -u XXX
+nzC
+@end example
+
+@end itemize
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -d
+@itemx --directory
+@opindex -d
+@opindex --directory
+Create a directory rather than a file.  The directory will have read,
+write, and search permissions for the current user, but no permissions
+for the group or others; these permissions are reduced if the current
+umask is more restrictive.
+
+@item -q
+@itemx --quiet
+@opindex -q
+@opindex --quiet
+Suppress diagnostics about failure to create a file or directory.  The
+exit status will still reflect whether a file was created.
+
+@item -u
+@itemx --dry-run
+@opindex -u
+@opindex --dry-run
+Generate a temporary name that does not name an existing file, without
+changing the file system contents.  Using the output of this command
+to create a new file is inherently unsafe, as there is a window of
+time between generating the name and using it where another process
+can create an object by the same name.
+
+@item -p @var{dir}
+@itemx --tmpdir[=@var{dir}]
+@opindex -p
+@opindex --tmpdir
+Treat @var{template} relative to the directory @var{dir}.  If
+@var{dir} is not specified (only possible with the long option
+@option{--tmpdir}) or is the empty string, use the value of
+@env{TMPDIR} if available, otherwise use @samp{/tmp}.  If this is
+specified, @var{template} must not be absolute.  However,
+@var{template} can still contain slashes, although intermediate
+directories must already exist.
+
+@item --suffix=@var{suffix}
+@opindex --suffix
+Append @var{suffix} to the @var{template}.  @var{suffix} must not
+contain slash.  If @option{--suffix} is specified, @var{template} must
+end in @samp{X}; if it is not specified, then an appropriate
+@option{--suffix} is inferred by finding the last @samp{X} in
+@var{template}.  This option exists for use with the default
+@var{template} and for the creation of a @var{suffix} that starts with
+@samp{X}.
+
+@item -t
+@opindex -t
+Treat @var{template} as a single file relative to the value of
+@env{TMPDIR} if available, or to the directory specified by
+@option{-p}, otherwise to @samp{/tmp}.  @var{template} must not
+contain slashes.  This option is deprecated; the use of @option{-p}
+without @option{-t} offers better defaults (by favoring the command
+line over @env{TMPDIR}) and more flexibility (by allowing intermediate
+directories).
+
+@end table
+
+@cindex exit status of @command{mktemp}
+Exit status:
+
+@display
+0 if the file was created,
+1 otherwise.
+@end display
+
+
+@node realpath invocation
+@section @command{realpath}: Print the resolved file name.
+
+@pindex realpath
+@cindex file names, canonicalization
+@cindex symlinks, resolution
+@cindex canonical file name
+@cindex canonicalize a file name
+@pindex realpath
+@findex realpath
+
+@command{realpath} expands all symbolic links and resolves references to
+@samp{/./}, @samp{/../} and extra @samp{/} characters.  By default,
+all but the last component of the specified files must exist.  Synopsis:
+
+@example
+realpath [@var{option}]@dots{} @var{file}@dots{}
+@end example
+
+The file name canonicalization functionality overlaps with that of the
+@command{readlink} command.  This is the preferred command for
+canonicalization as it's a more suitable and standard name.  In addition
+this command supports relative file name processing functionality.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -e
+@itemx --canonicalize-existing
+@opindex -e
+@opindex --canonicalize-existing
+Ensure that all components of the specified file names exist.
+If any component is missing or unavailable, @command{realpath} will output
+a diagnostic unless the @option{-q} option is specified, and exit with a
+nonzero exit code.  A trailing slash requires that the name resolve to a
+directory.
+
+@item -m
+@itemx --canonicalize-missing
+@opindex -m
+@opindex --canonicalize-missing
+If any component of a specified file name is missing or unavailable,
+treat it as a directory.
+
+@item -L
+@itemx --logical
+@opindex -L
+@opindex --logical
+Symbolic links are resolved in the specified file names,
+but they are resolved after any subsequent @samp{..} components are processed.
+
+@item -P
+@itemx --physical
+@opindex -P
+@opindex --physical
+Symbolic links are resolved in the specified file names,
+and they are resolved before any subsequent @samp{..} components are processed.
+This is the default mode of operation.
+
+@item -q
+@itemx --quiet
+@opindex -q
+@opindex --quiet
+Suppress diagnostic messages for specified file names.
+
+@item --relative-to=@var{dir}
+@opindex --relative-to
+@cindex relpath
+Print the resolved file names relative to the specified directory.
+Note this option honors the @option{-m} and @option{-e} options
+pertaining to file existence.
+
+@item --relative-base=@var{dir}
+@opindex --relative-base
+Print the resolved file names as relative @emph{if} the files
+are descendants of @var{dir}.
+Otherwise, print the resolved file names as absolute.
+Note this option honors the @option{-m} and @option{-e} options
+pertaining to file existence.
+For details about combining @option{--relative-to} and @option{--relative-base},
+@pxref{Realpath usage examples}.
+
+@item -s
+@itemx --strip
+@itemx --no-symlinks
+@opindex -s
+@opindex --strip
+@opindex --no-symlinks
+Do not resolve symbolic links.  Only resolve references to
+@samp{/./}, @samp{/../} and remove extra @samp{/} characters.
+When combined with the @option{-m} option, realpath operates
+only on the file name, and does not touch any actual file.
+
+@optZero
+
+@end table
+
+@cindex exit status of @command{realpath}
+Exit status:
+
+@display
+0 if all file names were printed without issue.
+1 otherwise.
+@end display
+
+@menu
+* Realpath usage examples::              Realpath usage examples.
+@end menu
+
+
+@node Realpath usage examples
+@subsection Realpath usage examples
+
+@opindex --relative-to
+@opindex --relative-base
+
+By default, @command{realpath} prints the absolute file name of given files
+(symlinks are resolved, @file{words} is resolved to @file{american-english}):
+
+@example
+@group
+cd /home/user
+realpath /usr/bin/sort /tmp/foo /usr/share/dict/words 1.txt
+@result{} /usr/bin/sort
+@result{} /tmp/foo
+@result{} /usr/share/dict/american-english
+@result{} /home/user/1.txt
+@end group
+@end example
+
+With @option{--relative-to}, file names are printed relative to
+the given directory:
+
+@example
+@group
+realpath --relative-to=/usr/bin \
+         /usr/bin/sort /tmp/foo /usr/share/dict/words 1.txt
+@result{} sort
+@result{} ../../tmp/foo
+@result{} ../share/dict/american-english
+@result{} ../../home/user/1.txt
+@end group
+@end example
+
+With @option{--relative-base}, relative file names are printed @emph{if}
+the resolved file name is below the given base directory. For files outside the
+base directory absolute file names are printed:
+
+@example
+@group
+realpath --relative-base=/usr \
+         /usr/bin/sort /tmp/foo /usr/share/dict/words 1.txt
+@result{} bin/sort
+@result{} /tmp/foo
+@result{} share/dict/american-english
+@result{} /home/user/1.txt
+@end group
+@end example
+
+When both @option{--relative-to=DIR1} and @option{--relative-base=DIR2}
+are used, file names are printed relative to @var{dir1} @emph{if} they are
+located below @var{dir2}. If the files are not below @var{dir2}, they are
+printed as absolute file names:
+
+@example
+@group
+realpath --relative-to=/usr/bin --relative-base=/usr \
+         /usr/bin/sort /tmp/foo /usr/share/dict/words 1.txt
+@result{} sort
+@result{} /tmp/foo
+@result{} ../share/dict/american-english
+@result{} /home/user/1.txt
+@end group
+@end example
+
+When both @option{--relative-to=DIR1} and @option{--relative-base=DIR2}
+are used, @var{dir1} @emph{must} be a subdirectory of @var{dir2}. Otherwise,
+@command{realpath} prints absolutes file names.
+
+
+@node Working context
+@chapter Working context
+
+@cindex working context
+@cindex commands for printing the working context
+
+This section describes commands that display or alter the context in
+which you are working: the current directory, the terminal settings, and
+so forth.  See also the user-related commands in the next section.
+
+@menu
+* pwd invocation::              Print working directory.
+* stty invocation::             Print or change terminal characteristics.
+* printenv invocation::         Print environment variables.
+* tty invocation::              Print file name of terminal on standard input.
+@end menu
+
+
+@node pwd invocation
+@section @command{pwd}: Print working directory
+
+@pindex pwd
+@cindex print name of current directory
+@cindex current working directory, printing
+@cindex working directory, printing
+
+
+@command{pwd} prints the name of the current directory.  Synopsis:
+
+@example
+pwd [@var{option}]@dots{}
+@end example
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+@item -L
+@itemx --logical
+@opindex -L
+@opindex --logical
+If the contents of the environment variable @env{PWD} provide an
+absolute name of the current directory with no @samp{.} or @samp{..}
+components, but possibly with symbolic links, then output those
+contents.  Otherwise, fall back to default @option{-P} handling.
+
+@item -P
+@itemx --physical
+@opindex -P
+@opindex --physical
+Print a fully resolved name for the current directory.  That is, all
+components of the printed name will be actual directory names---none
+will be symbolic links.
+@end table
+
+@cindex symbolic links and @command{pwd}
+If @option{-L} and @option{-P} are both given, the last one takes
+precedence.  If neither option is given, then this implementation uses
+@option{-P} as the default unless the @env{POSIXLY_CORRECT}
+environment variable is set.
+
+@mayConflictWithShellBuiltIn{pwd}
+
+@exitstatus
+
+
+@node stty invocation
+@section @command{stty}: Print or change terminal characteristics
+
+@pindex stty
+@cindex change or print terminal settings
+@cindex terminal settings
+@cindex line settings of terminal
+
+@command{stty} prints or changes terminal characteristics, such as baud rate.
+Synopses:
+
+@example
+stty [@var{option}] [@var{setting}]@dots{}
+stty [@var{option}]
+@end example
+
+If given no line settings, @command{stty} prints the baud rate, line
+discipline number (on systems that support it), and line settings
+that have been changed from the values set by @samp{stty sane}.
+By default, mode reading and setting are performed on the tty line
+connected to standard input, although this can be modified by the
+@option{--file} option.
+
+@command{stty} accepts many non-option arguments that change aspects of
+the terminal line operation, as described below.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+@item -a
+@itemx --all
+@opindex -a
+@opindex --all
+Print all current settings in human-readable form.  This option may not
+be used in combination with any line settings.
+
+@item -F @var{device}
+@itemx --file=@var{device}
+@opindex -F
+@opindex --file
+Set the line opened by the file name specified in @var{device} instead of
+the tty line connected to standard input.  This option is necessary
+because opening a POSIX tty requires use of the
+@code{O_NONDELAY} flag to prevent a POSIX tty from blocking
+until the carrier detect line is high if
+the @code{clocal} flag is not set.  Hence, it is not always possible
+to allow the shell to open the device in the traditional manner.
+
+@item -g
+@itemx --save
+@opindex -g
+@opindex --save
+@cindex machine-readable @command{stty} output
+Print all current settings in a form that can be used as an argument to
+another @command{stty} command to restore the current settings.  This option
+may not be used in combination with any line settings.
+
+@end table
+
+Many settings can be turned off by preceding them with a @samp{-}.
+Such arguments are marked below with ``May be negated'' in their
+description.  The descriptions themselves refer to the positive
+case, that is, when @emph{not} negated (unless stated otherwise,
+of course).
+
+Some settings are not available on all POSIX systems, since they use
+extensions.  Such arguments are marked below with
+``Non-POSIX'' in their description.  On non-POSIX
+systems, those or other settings also may not
+be available, but it's not feasible to document all the variations: just
+try it and see.
+
+@command{stty} is installed only on platforms with the POSIX terminal
+interface, so portable scripts should not rely on its existence on
+non-POSIX platforms.
+
+@exitstatus
+
+@menu
+* Control::                     Control settings
+* Input::                       Input settings
+* Output::                      Output settings
+* Local::                       Local settings
+* Combination::                 Combination settings
+* Characters::                  Special characters
+* Special::                     Special settings
+@end menu
+
+
+@node Control
+@subsection Control settings
+
+@cindex control settings
+Control settings:
+
+@table @samp
+@item parenb
+@opindex parenb
+@cindex two-way parity
+Generate parity bit in output and expect parity bit in input.
+May be negated.
+
+@item parodd
+@opindex parodd
+@cindex odd parity
+@cindex even parity
+Set odd parity (even if negated).  May be negated.
+
+@item cmspar
+@opindex cmspar
+@cindex constant parity
+@cindex stick parity
+@cindex mark parity
+@cindex space parity
+Use "stick" (mark/space) parity.  If parodd is set, the parity bit is
+always 1; if parodd is not set, the parity bit is always zero.
+Non-POSIX@.  May be negated.
+
+@item cs5
+@itemx cs6
+@itemx cs7
+@itemx cs8
+@opindex cs@var{n}
+@cindex character size
+@cindex eight-bit characters
+Set character size to 5, 6, 7, or 8 bits.
+
+@item hup
+@itemx hupcl
+@opindex hup[cl]
+Send a hangup signal when the last process closes the tty.  May be
+negated.
+
+@item cstopb
+@opindex cstopb
+@cindex stop bits
+Use two stop bits per character (one if negated).  May be negated.
+
+@item cread
+@opindex cread
+Allow input to be received.  May be negated.
+
+@item clocal
+@opindex clocal
+@cindex modem control
+Disable modem control signals.  May be negated.
+
+@item crtscts
+@opindex crtscts
+@cindex hardware flow control
+@cindex flow control, hardware
+@cindex RTS/CTS flow control
+Enable RTS/CTS flow control.  Non-POSIX@.  May be negated.
+
+@item cdtrdsr
+@opindex cdtrdsr
+@cindex hardware flow control
+@cindex flow control, hardware
+@cindex DTR/DSR flow control
+Enable DTR/DSR flow control. Non-POSIX@.  May be negated.
+@end table
+
+
+@node Input
+@subsection Input settings
+
+@cindex input settings
+These settings control operations on data received from the terminal.
+
+@table @samp
+@item ignbrk
+@opindex ignbrk
+@cindex breaks, ignoring
+Ignore break characters.  May be negated.
+
+@item brkint
+@opindex brkint
+@cindex breaks, cause interrupts
+Make breaks cause an interrupt signal.  May be negated.
+
+@item ignpar
+@opindex ignpar
+@cindex parity, ignoring
+Ignore characters with parity errors.  May be negated.
+
+@item parmrk
+@opindex parmrk
+@cindex parity errors, marking
+Mark parity errors (with a 255-0-character sequence).  May be negated.
+
+@item inpck
+@opindex inpck
+Enable input parity checking.  May be negated.
+
+@item istrip
+@opindex istrip
+@cindex eight-bit input
+Clear high (8th) bit of input characters.  May be negated.
+
+@item inlcr
+@opindex inlcr
+@cindex newline, translating to return
+Translate newline to carriage return.  May be negated.
+
+@item igncr
+@opindex igncr
+@cindex return, ignoring
+Ignore carriage return.  May be negated.
+
+@item icrnl
+@opindex icrnl
+@cindex return, translating to newline
+Translate carriage return to newline.  May be negated.
+
+@item iutf8
+@opindex iutf8
+@cindex input encoding, UTF-8
+Assume input characters are UTF-8 encoded.  May be negated.
+
+@item ixon
+@opindex ixon
+@kindex C-s/C-q flow control
+@cindex XON/XOFF flow control
+Enable XON/XOFF flow control (that is, @kbd{Ctrl-S}/@kbd{Ctrl-Q}).  May
+be negated.
+
+@item ixoff
+@itemx tandem
+@opindex ixoff
+@opindex tandem
+@cindex software flow control
+@cindex flow control, software
+Enable sending of @code{stop} character when the system input buffer
+is almost full, and @code{start} character when it becomes almost
+empty again.  May be negated.
+
+@item iuclc
+@opindex iuclc
+@cindex uppercase, translating to lowercase
+Translate uppercase characters to lowercase.  Non-POSIX@.  May be
+negated.  Note ilcuc is not implemented, as one would not be able to issue
+almost any (lowercase) Unix command, after invoking it.
+
+@item ixany
+@opindex ixany
+Allow any character to restart output (only the start character
+if negated).  Non-POSIX@.  May be negated.
+
+@item imaxbel
+@opindex imaxbel
+@cindex beeping at input buffer full
+Enable beeping and not flushing input buffer if a character arrives
+when the input buffer is full.  Non-POSIX@.  May be negated.
+@end table
+
+
+@node Output
+@subsection Output settings
+
+@cindex output settings
+These settings control operations on data sent to the terminal.
+
+@table @samp
+@item opost
+@opindex opost
+Postprocess output.  May be negated.
+
+@item olcuc
+@opindex olcuc
+@cindex lowercase, translating to output
+Translate lowercase characters to uppercase.  Non-POSIX@.  May be
+negated.  (Note ouclc is not currently implemented.)
+
+@item ocrnl
+@opindex ocrnl
+@cindex return, translating to newline
+Translate carriage return to newline.  Non-POSIX@.  May be negated.
+
+@item onlcr
+@opindex onlcr
+@cindex newline, translating to crlf
+Translate newline to carriage return-newline.  Non-POSIX@.  May be
+negated.
+
+@item onocr
+@opindex onocr
+Do not print carriage returns in the first column.  Non-POSIX@.
+May be negated.
+
+@item onlret
+@opindex onlret
+Newline performs a carriage return.  Non-POSIX@.  May be negated.
+
+@item ofill
+@opindex ofill
+@cindex pad instead of timing for delaying
+Use fill (padding) characters instead of timing for delays.
+Non-POSIX@.
+May be negated.
+
+@item ofdel
+@opindex ofdel
+@cindex pad character
+Use ASCII DEL characters for fill instead of
+ASCII NUL characters.  Non-POSIX@.
+May be negated.
+
+@item nl1
+@itemx nl0
+@opindex nl@var{n}
+Newline delay style.  Non-POSIX.
+
+@item cr3
+@itemx cr2
+@itemx cr1
+@itemx cr0
+@opindex cr@var{n}
+Carriage return delay style.  Non-POSIX.
+
+@item tab3
+@itemx tab2
+@itemx tab1
+@itemx tab0
+@opindex tab@var{n}
+Horizontal tab delay style.  Non-POSIX.
+
+@item bs1
+@itemx bs0
+@opindex bs@var{n}
+Backspace delay style.  Non-POSIX.
+
+@item vt1
+@itemx vt0
+@opindex vt@var{n}
+Vertical tab delay style.  Non-POSIX.
+
+@item ff1
+@itemx ff0
+@opindex ff@var{n}
+Form feed delay style.  Non-POSIX.
+@end table
+
+
+@node Local
+@subsection Local settings
+
+@cindex local settings
+
+@table @samp
+@item isig
+@opindex isig
+Enable @code{interrupt}, @code{quit}, and @code{suspend} special
+characters.  May be negated.
+
+@item icanon
+@opindex icanon
+Enable @code{erase}, @code{kill}, @code{werase}, and @code{rprnt}
+special characters.  May be negated.
+
+@item iexten
+@opindex iexten
+Enable non-POSIX special characters.  May be negated.
+
+@item echo
+@opindex echo
+Echo input characters.  May be negated.
+
+@item echoe
+@itemx crterase
+@opindex echoe
+@opindex crterase
+Echo @code{erase} characters as backspace-space-backspace.  May be
+negated.
+
+@item echok
+@opindex echok
+@cindex newline echoing after @code{kill}
+Echo a newline after a @code{kill} character.  May be negated.
+
+@item echonl
+@opindex echonl
+@cindex newline, echoing
+Echo newline even if not echoing other characters.  May be negated.
+
+@item noflsh
+@opindex noflsh
+@cindex flushing, disabling
+Disable flushing after @code{interrupt} and @code{quit} special
+characters.  May be negated.
+
+@item xcase
+@opindex xcase
+@cindex case translation
+Enable input and output of uppercase characters by preceding their
+lowercase equivalents with @samp{\}, when @code{icanon} is set.
+Non-POSIX@.  May be negated.
+
+@item tostop
+@opindex tostop
+@cindex background jobs, stopping at terminal write
+Stop background jobs that try to write to the terminal.  Non-POSIX@.
+May be negated.
+
+@item echoprt
+@itemx prterase
+@opindex echoprt
+@opindex prterase
+Echo erased characters backward, between @samp{\} and @samp{/}.
+Non-POSIX@.  May be negated.
+
+@item echoctl
+@itemx ctlecho
+@opindex echoctl
+@opindex ctlecho
+@cindex control characters, using @samp{^@var{c}}
+@cindex hat notation for control characters
+Echo control characters in hat notation (@samp{^@var{c}}) instead
+of literally.  Non-POSIX@.  May be negated.
+
+@item echoke
+@itemx crtkill
+@opindex echoke
+@opindex crtkill
+Echo the @code{kill} special character by erasing each character on
+the line as indicated by the @code{echoprt} and @code{echoe} settings,
+instead of by the @code{echoctl} and @code{echok} settings.
+Non-POSIX@.
+May be negated.
+
+@item extproc
+@opindex extproc
+Enable @samp{LINEMODE}, which is used to avoid echoing
+each character over high latency links.  See also
+@uref{https://tools.ietf.org/search/rfc1116, Internet RFC 1116}.
+Non-POSIX@.
+May be negated.
+
+@item flusho
+@opindex flusho
+Discard output.
+Note this setting is currently ignored on GNU/Linux systems.
+Non-POSIX@.
+May be negated.
+@end table
+
+
+@node Combination
+@subsection Combination settings
+
+@cindex combination settings
+Combination settings:
+
+@table @samp
+@item evenp
+@opindex evenp
+@itemx parity
+@opindex parity
+Same as @code{parenb -parodd cs7}.  May be negated.  If negated, same
+as @code{-parenb cs8}.
+
+@item oddp
+@opindex oddp
+Same as @code{parenb parodd cs7}.  May be negated.  If negated, same
+as @code{-parenb cs8}.
+
+@item nl
+@opindex nl
+Same as @code{-icrnl -onlcr}.  May be negated.  If negated, same as
+@code{icrnl -inlcr -igncr onlcr -ocrnl -onlret}.
+
+@item ek
+@opindex ek
+Reset the @code{erase} and @code{kill} special characters to their default
+values.
+
+@item sane
+@opindex sane
+Same as:
+
+@c This is too long to write inline.
+@example
+cread -ignbrk brkint -inlcr -igncr icrnl
+icanon iexten echo echoe echok -echonl -noflsh
+-ixoff -iutf8 -iuclc -ixany imaxbel -xcase -olcuc -ocrnl
+opost -ofill onlcr -onocr -onlret nl0 cr0 tab0 bs0 vt0 ff0
+isig -tostop -ofdel -echoprt echoctl echoke -extproc
+@end example
+
+@noindent
+and also sets all special characters to their default values.
+
+@item cooked
+@opindex cooked
+Same as @code{brkint ignpar istrip icrnl ixon opost isig icanon}, plus
+sets the @code{eof} and @code{eol} characters to their default values
+if they are the same as the @code{min} and @code{time} characters.
+May be negated.  If negated, same as @code{raw}.
+
+@item raw
+@opindex raw
+Same as:
+
+@example
+-ignbrk -brkint -ignpar -parmrk -inpck -istrip
+-inlcr -igncr -icrnl -ixon -ixoff -icanon -opost
+-isig -iuclc -ixany -imaxbel -xcase min 1 time 0
+@end example
+
+@noindent
+May be negated.  If negated, same as @code{cooked}.
+
+@item cbreak
+@opindex cbreak
+Same as @option{-icanon}.  May be negated.  If negated, same as
+@code{icanon}.
+
+@item pass8
+@opindex pass8
+@cindex eight-bit characters
+Same as @code{-parenb -istrip cs8}.  May be negated.  If negated,
+same as @code{parenb istrip cs7}.
+
+@item litout
+@opindex litout
+Same as @option{-parenb -istrip -opost cs8}.  May be negated.
+If negated, same as @code{parenb istrip opost cs7}.
+
+@item decctlq
+@opindex decctlq
+Same as @option{-ixany}.  Non-POSIX@.  May be negated.
+
+@item tabs
+@opindex tabs
+Same as @code{tab0}.  Non-POSIX@.  May be negated.  If negated, same
+as @code{tab3}.
+
+@item lcase
+@itemx LCASE
+@opindex lcase
+@opindex LCASE
+Same as @code{xcase iuclc olcuc}.  Non-POSIX@.  May be negated.
+(Used for terminals with uppercase characters only.)
+
+@item crt
+@opindex crt
+Same as @code{echoe echoctl echoke}.
+
+@item dec
+@opindex dec
+Same as @code{echoe echoctl echoke -ixany intr ^C erase ^? kill C-u}.
+@end table
+
+
+@node Characters
+@subsection Special characters
+
+@cindex special characters
+@cindex characters, special
+
+The special characters' default values vary from system to system.
+They are set with the syntax @samp{name value}, where the names are
+listed below and the value can be given either literally, in hat
+notation (@samp{^@var{c}}), or as an integer which may start with
+@samp{0x} to indicate hexadecimal, @samp{0} to indicate octal, or
+any other digit to indicate decimal.
+
+@cindex disabling special characters
+@kindex u@r{, and disabling special characters}
+For GNU stty, giving a value of @code{^-} or @code{undef} disables that
+special character.  (This is incompatible with Ultrix @command{stty},
+which uses  a value of @samp{u} to disable a special character.  GNU
+@command{stty} treats a value @samp{u} like any other, namely to set that
+special character to @key{U}.)
+
+@table @samp
+
+@item intr
+@opindex intr
+Send an interrupt signal.
+
+@item quit
+@opindex quit
+Send a quit signal.
+
+@item erase
+@opindex erase
+Erase the last character typed.
+
+@item kill
+@opindex kill
+Erase the current line.
+
+@item eof
+@opindex eof
+Send an end of file (terminate the input).
+
+@item eol
+@opindex eol
+End the line.
+
+@item eol2
+@opindex eol2
+Alternate character to end the line.  Non-POSIX.
+
+@item discard
+@opindex discard
+@opindex flush
+Alternate character to toggle discarding of output.  Non-POSIX.
+
+@item swtch
+@opindex swtch
+Switch to a different shell layer.  Non-POSIX.
+
+@item status
+@opindex status
+Send an info signal.  Not currently supported on Linux.  Non-POSIX.
+
+@item start
+@opindex start
+Restart the output after stopping it.
+
+@item stop
+@opindex stop
+Stop the output.
+
+@item susp
+@opindex susp
+Send a terminal stop signal.
+
+@item dsusp
+@opindex dsusp
+Send a terminal stop signal after flushing the input.  Non-POSIX.
+
+@item rprnt
+@opindex rprnt
+Redraw the current line.  Non-POSIX.
+
+@item werase
+@opindex werase
+Erase the last word typed.  Non-POSIX.
+
+@item lnext
+@opindex lnext
+Enter the next character typed literally, even if it is a special
+character.  Non-POSIX.
+@end table
+
+
+@node Special
+@subsection Special settings
+
+@cindex special settings
+
+@table @samp
+@item min @var{n}
+@opindex min
+Set the minimum number of characters that will satisfy a read until
+the time value has expired, when @option{-icanon} is set.
+
+@item time @var{n}
+@opindex time
+Set the number of tenths of a second before reads time out if the minimum
+number of characters have not been read, when @option{-icanon} is set.
+
+@item ispeed @var{n}
+@opindex ispeed
+Set the input speed to @var{n}.
+
+@item ospeed @var{n}
+@opindex ospeed
+Set the output speed to @var{n}.
+
+@item rows @var{n}
+@opindex rows
+Tell the tty kernel driver that the terminal has @var{n} rows.
+Non-POSIX.
+
+@item cols @var{n}
+@itemx columns @var{n}
+@opindex cols
+@opindex columns
+Tell the kernel that the terminal has @var{n} columns.  Non-POSIX.
+
+@item drain
+@opindex drain
+@cindex nonblocking @command{stty} setting
+Apply settings after first waiting for pending output to be transmitted.
+This is enabled by default for GNU @command{stty}.
+It is useful to disable this option
+in cases where the system may be in a state where serial transmission
+is not possible.
+For example, if the system has received the @samp{DC3} character
+with @code{ixon} (software flow control) enabled, then @command{stty} would
+block without @code{-drain} being specified.
+May be negated. Non-POSIX.
+
+@item size
+@opindex size
+@vindex LINES
+@vindex COLUMNS
+Print the number of rows and columns that the kernel thinks the
+terminal has.  (Systems that don't support rows and columns in the kernel
+typically use the environment variables @env{LINES} and @env{COLUMNS}
+instead; however, GNU @command{stty} does not know anything about them.)
+Non-POSIX.
+
+@item line @var{n}
+@opindex line
+Use line discipline @var{n}.  Non-POSIX.
+
+@item speed
+@opindex speed
+Print the terminal speed.
+
+@item @var{n}
+@cindex baud rate, setting
+Set the input and output speeds to @var{n}.  @var{n} can be one of: 0
+50 75 110 134 134.5 150 200 300 600 1200 1800 2400 4800 9600 19200
+38400 @code{exta} @code{extb}.  @code{exta} is the same as 19200;
+@code{extb} is the same as 38400.  Many systems, including GNU/Linux,
+support higher speeds.  The @command{stty} command includes support
+for speeds of
+57600,
+115200,
+230400,
+460800,
+500000,
+576000,
+921600,
+1000000,
+1152000,
+1500000,
+2000000,
+2500000,
+3000000,
+3500000,
+or
+4000000 where the system supports these.
+0 hangs up the line if @option{-clocal} is set.
+@end table
+
+
+@node printenv invocation
+@section @command{printenv}: Print all or some environment variables
+
+@pindex printenv
+@cindex printing all or some environment variables
+@cindex environment variables, printing
+
+@command{printenv} prints environment variable values.  Synopsis:
+
+@example
+printenv [@var{option}] [@var{variable}]@dots{}
+@end example
+
+If no @var{variable}s are specified, @command{printenv} prints the value of
+every environment variable.  Otherwise, it prints the value of each
+@var{variable} that is set, and nothing for those that are not set.
+
+The program accepts the following option.  Also see @ref{Common options}.
+
+@table @samp
+
+@optNull
+
+@end table
+
+@cindex exit status of @command{printenv}
+Exit status:
+
+@display
+0 if all variables specified were found
+1 if at least one specified variable was not found
+2 if a write error occurred
+@end display
+
+
+@node tty invocation
+@section @command{tty}: Print file name of terminal on standard input
+
+@pindex tty
+@cindex print terminal file name
+@cindex terminal file name, printing
+
+@command{tty} prints the file name of the terminal connected to its standard
+input.  It prints @samp{not a tty} if standard input is not a terminal.
+Synopsis:
+
+@example
+tty [@var{option}]@dots{}
+@end example
+
+The program accepts the following option.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -s
+@itemx --silent
+@itemx --quiet
+@opindex -s
+@opindex --silent
+@opindex --quiet
+Print nothing; only return an exit status.
+
+@end table
+
+@cindex exit status of @command{tty}
+Exit status:
+
+@display
+0 if standard input is a terminal
+1 if standard input is a non-terminal file
+2 if given incorrect arguments
+3 if a write error occurs
+@end display
+
+
+@node User information
+@chapter User information
+
+@cindex user information, commands for
+@cindex commands for printing user information
+
+This section describes commands that print user-related information:
+logins, groups, and so forth.
+
+@menu
+* id invocation::               Print user identity.
+* logname invocation::          Print current login name.
+* whoami invocation::           Print effective user ID.
+* groups invocation::           Print group names a user is in.
+* users invocation::            Print login names of users currently logged in.
+* who invocation::              Print who is currently logged in.
+@end menu
+
+
+@node id invocation
+@section @command{id}: Print user identity
+
+@pindex id
+@cindex real user and group IDs, printing
+@cindex effective user and group IDs, printing
+@cindex printing real and effective user and group IDs
+
+@command{id} prints information about the given user, or the process
+running it if no user is specified.  Synopsis:
+
+@example
+id [@var{option}]@dots{} [@var{user}]@dots{}
+@end example
+
+@var{user} can be either a user ID or a name, with name look-up
+taking precedence unless the ID is specified with a leading @samp{+}.
+@xref{Disambiguating names and IDs}.
+
+@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.
+
+The options cause @command{id} to print only part of the above information.
+Also see @ref{Common options}.
+
+@table @samp
+@item -g
+@itemx --group
+@opindex -g
+@opindex --group
+Print only the group ID.
+
+@item -G
+@itemx --groups
+@opindex -G
+@opindex --groups
+Print only the group ID and the supplementary groups.
+
+@item -n
+@itemx --name
+@opindex -n
+@opindex --name
+Print the user or group name instead of the ID number.  Requires
+@option{-u}, @option{-g}, or @option{-G}.
+
+@item -r
+@itemx --real
+@opindex -r
+@opindex --real
+Print the real, instead of effective, user or group ID@.  Requires
+@option{-u}, @option{-g}, or @option{-G}.
+
+@item -u
+@itemx --user
+@opindex -u
+@opindex --user
+Print only the user ID.
+
+@item -Z
+@itemx --context
+@opindex -Z
+@opindex --context
+@cindex SELinux
+@cindex security context
+Print only the security context of the process, which is generally
+the user's security context inherited from the parent process.
+If neither SELinux or SMACK is enabled then print a warning and
+set the exit status to 1.
+
+@item -z
+@itemx --zero
+@opindex -z
+@opindex --zero
+Delimit output items with ASCII NUL characters.
+This option is not permitted when using the default format.
+When multiple users are specified, and the @option{--groups} option
+is also in effect, groups are delimited with a single NUL character,
+while users are delimited with two NUL characters.
+
+Example:
+@example
+$ id -Gn --zero
+users <NUL> devs <NUL>
+@end example
+
+@end table
+
+@macro primaryAndSupplementaryGroups{cmd,arg}
+Primary and supplementary groups for a process are normally inherited
+from its parent and are usually unchanged since login.  This means
+that if you change the group database after logging in, @command{\cmd\}
+will not reflect your changes within your existing login session.
+Running @command{\cmd\} with a \arg\ causes the user and group
+database to be consulted afresh, and so will give a different result.
+@end macro
+@primaryAndSupplementaryGroups{id,user argument}
+
+@exitstatus
+
+@node logname invocation
+@section @command{logname}: Print current login name
+
+@pindex logname
+@cindex printing user's login name
+@cindex login name, printing
+@cindex user name, printing
+
+@flindex utmp
+@command{logname} prints the calling user's name, as found in a
+system-maintained file (often @file{/var/run/utmp} or
+@file{/etc/utmp}), and exits with a status of 0.  If there is no entry
+for the calling process, @command{logname} prints
+an error message and exits with a status of 1.
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.
+
+@exitstatus
+
+
+@node whoami invocation
+@section @command{whoami}: Print effective user ID
+
+@pindex whoami
+@cindex effective user ID, printing
+@cindex printing the effective user ID
+
+@command{whoami} prints the user name associated with the current
+effective user ID@.  It is equivalent to the command @samp{id -un}.
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.
+
+@exitstatus
+
+
+@node groups invocation
+@section @command{groups}: Print group names a user is in
+
+@pindex groups
+@cindex printing groups a user is in
+@cindex supplementary groups, printing
+
+@command{groups} prints the names of the primary and any supplementary
+groups for each given @var{username}, or the current process if no names
+are given.  If more than one name is given, the name of each user is
+printed before
+the list of that user's groups and the user name is separated from the
+group list by a colon.  Synopsis:
+
+@example
+groups [@var{username}]@dots{}
+@end example
+
+The group lists are equivalent to the output of the command @samp{id -Gn}.
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.
+
+@primaryAndSupplementaryGroups{groups,list of users}
+
+@exitstatus
+
+@node users invocation
+@section @command{users}: Print login names of users currently logged in
+
+@pindex users
+@cindex printing current usernames
+@cindex usernames, printing current
+
+@cindex login sessions, printing users with
+@command{users} prints on a single line a blank-separated list of user
+names of users currently logged in to the current host.  Each user name
+corresponds to a login session, so if a user has more than one login
+session, that user's name will appear the same number of times in the
+output.  Synopsis:
+
+@example
+users [@var{file}]
+@end example
+
+@flindex utmp
+@flindex wtmp
+With no @var{file} argument, @command{users} extracts its information from
+a system-maintained file (often @file{/var/run/utmp} or
+@file{/etc/utmp}).  If a file argument is given, @command{users} uses
+that file instead.  A common choice is @file{/var/log/wtmp}.
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.
+
+The @command{users} command is installed only on platforms with the
+POSIX @code{<utmpx.h>} include file or equivalent, so portable scripts
+should not rely on its existence on non-POSIX platforms.
+
+@exitstatus
+
+
+@node who invocation
+@section @command{who}: Print who is currently logged in
+
+@pindex who
+@cindex printing current user information
+@cindex information, about current users
+
+@command{who} prints information about users who are currently logged on.
+Synopsis:
+
+@example
+@command{who} [@var{option}] [@var{file}] [am i]
+@end example
+
+@cindex terminal lines, currently used
+@cindex login time
+@cindex remote hostname
+If given no non-option arguments, @command{who} prints the following
+information for each user currently logged on: login name, terminal
+line, login time, and remote hostname or X display.
+
+@flindex utmp
+@flindex wtmp
+If given one non-option argument, @command{who} uses that instead of
+a default system-maintained file (often @file{/var/run/utmp} or
+@file{/etc/utmp}) as the name of the file containing the record of
+users logged on.  @file{/var/log/wtmp} is commonly given as an argument
+to @command{who} to look at who has previously logged on.
+
+@opindex am i
+@opindex who am i
+If given two non-option arguments, @command{who} prints only the entry
+for the user running it (determined from its standard input), preceded
+by the hostname.  Traditionally, the two arguments given are @samp{am
+i}, as in @samp{who am i}.
+
+@vindex TZ
+Timestamps are listed according to the time zone rules specified by
+the @env{TZ} environment variable, or by the system default rules if
+@env{TZ} is not set.  @xref{TZ Variable,, Specifying the Time Zone
+with @env{TZ}, libc, The GNU C Library Reference Manual}.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -a
+@itemx --all
+@opindex -a
+@opindex --all
+Same as @samp{-b -d --login -p -r -t -T -u}.
+
+@item -b
+@itemx --boot
+@opindex -b
+@opindex --boot
+Print the date and time of last system boot.
+
+@item -d
+@itemx --dead
+@opindex -d
+@opindex --dead
+Print information corresponding to dead processes.
+
+@item -H
+@itemx --heading
+@opindex -H
+@opindex --heading
+Print a line of column headings.
+
+@item -l
+@itemx --login
+@opindex -l
+@opindex --login
+List only the entries that correspond to processes via which the
+system is waiting for a user to login.  The user name is always @samp{LOGIN}.
+
+@item --lookup
+@opindex --lookup
+Attempt to canonicalize hostnames found in utmp through a DNS lookup.  This
+is not the default because it can cause significant delays on systems with
+automatic dial-up internet access.
+
+@item -m
+@opindex -m
+Same as @samp{who am i}.
+
+@item -p
+@itemx --process
+@opindex -p
+@opindex --process
+List active processes spawned by init.
+
+@item -q
+@itemx --count
+@opindex -q
+@opindex --count
+Print only the login names and the number of users logged on.
+Overrides all other options.
+
+@item -r
+@itemx --runlevel
+@opindex -r
+@opindex --runlevel
+Print the current (and maybe previous) run-level of the init process.
+
+@item -s
+@opindex -s
+Ignored; for compatibility with other versions of @command{who}.
+
+@item -t
+@itemx --time
+@opindex -t
+@opindex --time
+Print last system clock change.
+
+@item -u
+@opindex -u
+@cindex idle time
+After the login time, print the number of hours and minutes that the
+user has been idle.  @samp{.} means the user was active in the last minute.
+@samp{old} means the user has been idle for more than 24 hours.
+
+@item -w
+@itemx -T
+@itemx --mesg
+@itemx --message
+@itemx --writable
+@opindex -w
+@opindex -T
+@opindex --mesg
+@opindex --message
+@opindex --writable
+@cindex message status
+@pindex write@r{, allowed}
+After each login name print a character indicating the user's message status:
+
+@display
+@samp{+} allowing @code{write} messages
+@samp{-} disallowing @code{write} messages
+@samp{?} cannot find terminal device
+@end display
+
+@end table
+
+The @command{who} command is installed only on platforms with the
+POSIX @code{<utmpx.h>} include file or equivalent, so portable scripts
+should not rely on its existence on non-POSIX platforms.
+
+@exitstatus
+
+
+@node System context
+@chapter System context
+
+@cindex system context
+@cindex context, system
+@cindex commands for system context
+
+This section describes commands that print or change system-wide
+information.
+
+@menu
+* date invocation::             Print or set system date and time.
+* arch invocation::             Print machine hardware name.
+* nproc invocation::            Print the number of processors.
+* uname invocation::            Print system information.
+* hostname invocation::         Print or set system name.
+* hostid invocation::           Print numeric host identifier.
+* uptime invocation::           Print system uptime and load.
+@end menu
+
+@node date invocation
+@section @command{date}: Print or set system date and time
+
+@pindex date
+@cindex time, printing or setting
+@cindex printing the current time
+
+Synopses:
+
+@example
+date [@var{option}]@dots{} [+@var{format}]
+date [-u|--utc|--universal] @c this avoids a newline in the output
+[ MMDDhhmm[[CC]YY][.ss] ]
+@end example
+
+@vindex LC_TIME
+Invoking @command{date} with no @var{format} argument is equivalent to invoking
+it with a default format that depends on the @env{LC_TIME} locale category.
+In the default C locale, this format is @samp{'+%a %b %e %H:%M:%S %Z %Y'},
+so the output looks like @samp{Thu Mar @ 3 13:47:51 PST 2005}.
+
+@vindex TZ
+Normally, @command{date} uses the time zone rules indicated by the
+@env{TZ} environment variable, or the system default rules if @env{TZ}
+is not set.  @xref{TZ Variable,, Specifying the Time Zone with
+@env{TZ}, libc, The GNU C Library Reference Manual}.
+
+@findex strftime @r{and @command{date}}
+@cindex time formats
+@cindex formatting times
+If given an argument that starts with a @samp{+}, @command{date} prints the
+current date and time (or the date and time specified by the
+@option{--date} option, see below) in the format defined by that argument,
+which is similar to that of the @code{strftime} function.  Except for
+conversion specifiers, which start with @samp{%}, characters in the
+format string are printed unchanged.  The conversion specifiers are
+described below.
+
+@exitstatus
+
+@menu
+* Time conversion specifiers::     %[HIklMNpPrRsSTXzZ]
+* 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.
+@detailmenu
+* Date input formats::             Specifying date strings.
+@end detailmenu
+* Examples of date::               Examples.
+@end menu
+
+@node Time conversion specifiers
+@subsection Time conversion specifiers
+
+@cindex time conversion specifiers
+@cindex conversion specifiers, time
+
+@command{date} conversion specifiers related to times.
+
+@table @samp
+@item %H
+hour (@samp{00}@dots{}@samp{23})
+@item %I
+hour (@samp{01}@dots{}@samp{12})
+@item %k
+hour, space padded (@samp{ 0}@dots{}@samp{23}); equivalent to @samp{%_H}@.
+This is a GNU extension.
+@item %l
+hour, space padded (@samp{ 1}@dots{}@samp{12}); equivalent to @samp{%_I}@.
+This is a GNU extension.
+@item %M
+minute (@samp{00}@dots{}@samp{59})
+@item %N
+nanoseconds (@samp{000000000}@dots{}@samp{999999999}).
+This is a GNU extension.
+@item %p
+locale's equivalent of either @samp{AM} or @samp{PM};
+blank in many locales.
+Noon is treated as @samp{PM} and midnight as @samp{AM}.
+@item %P
+like @samp{%p}, except lower case.
+This is a GNU extension.
+@item %r
+locale's 12-hour clock time (e.g., @samp{11:11:04 PM})
+@item %R
+24-hour hour and minute.  Same as @samp{%H:%M}.
+@item %s
+@cindex epoch, seconds since
+@cindex seconds since the epoch
+@cindex beginning of time
+@cindex leap seconds
+seconds since the epoch, i.e., since 1970-01-01 00:00:00 UTC@.
+Leap seconds are not counted unless leap second support is available.
+@xref{%s-examples}, for examples.
+This is a GNU extension.
+@item %S
+@cindex leap seconds
+second (@samp{00}@dots{}@samp{60}).
+This may be @samp{60} if leap seconds are supported.
+@item %T
+24-hour hour, minute, and second.  Same as @samp{%H:%M:%S}.
+@item %X
+locale's time representation (e.g., @samp{23:13:48})
+@item %z
+Four-digit numeric time zone, e.g., @samp{-0600} or @samp{+0530}, or
+@samp{-0000} if no
+time zone is determinable.  This value reflects the numeric time zone
+appropriate for the current time, using the time zone rules specified
+by the @env{TZ} environment variable.  A time zone is not determinable if
+its numeric offset is zero and its abbreviation begins with @samp{-}.
+The time (and optionally, the time zone rules) can be overridden
+by the @option{--date} option.
+@item %:z
+Numeric time zone with @samp{:}, e.g., @samp{-06:00} or
+@samp{+05:30}), or @samp{-00:00} if no time zone is determinable.
+This is a GNU extension.
+@item %::z
+Numeric time zone to the nearest second with @samp{:} (e.g.,
+@samp{-06:00:00} or @samp{+05:30:00}), or @samp{-00:00:00} if no time zone is
+determinable.
+This is a GNU extension.
+@item %:::z
+Numeric time zone with @samp{:} using the minimum necessary precision
+(e.g., @samp{-06}, @samp{+05:30}, or @samp{-04:56:02}), or @samp{-00} if
+no time zone is determinable.
+This is a GNU extension.
+@item %Z
+alphabetic time zone abbreviation (e.g., @samp{EDT}), or nothing if no
+time zone is determinable.  See @samp{%z} for how it is determined.
+@end table
+
+
+@node Date conversion specifiers
+@subsection Date conversion specifiers
+
+@cindex date conversion specifiers
+@cindex conversion specifiers, date
+
+@command{date} conversion specifiers related to dates.
+
+@table @samp
+@item %a
+locale's abbreviated weekday name (e.g., @samp{Sun})
+@item %A
+locale's full weekday name, variable length (e.g., @samp{Sunday})
+@item %b
+locale's abbreviated month name (e.g., @samp{Jan})
+@item %B
+locale's full month name, variable length (e.g., @samp{January})
+@item %c
+locale's date and time (e.g., @samp{Thu Mar @ 3 23:05:25 2005})
+@item %C
+century.  This is like @samp{%Y}, except the last two digits are omitted.
+For example, it is @samp{20} if @samp{%Y} is @samp{2000},
+and is @samp{-0} if @samp{%Y} is @samp{-001}.
+It is normally at least two characters, but it may be more.
+@item %d
+day of month (e.g., @samp{01})
+@item %D
+date; same as @samp{%m/%d/%y}
+@item %e
+day of month, space padded; same as @samp{%_d}
+@item %F
+full date in ISO 8601 format; like @samp{%+4Y-%m-%d}
+except that any flags or field width override the @samp{+}
+and (after subtracting 6) the @samp{4}.
+This is a good choice for a date format, as it is standard and
+is easy to sort in the usual case where years are in the range
+0000@dots{}9999.
+@item %g
+year corresponding to the ISO week number, but without the century
+(range @samp{00} through @samp{99}).  This has the same format and value
+as @samp{%y}, except that if the ISO week number (see
+@samp{%V}) belongs
+to the previous or next year, that year is used instead.
+@item %G
+year corresponding to the ISO week number.  This has the
+same format and value as @samp{%Y}, except that if the ISO
+week number (see
+@samp{%V}) belongs to the previous or next year, that year is used
+instead.
+It is normally useful only if @samp{%V} is also used;
+for example, the format @samp{%G-%m-%d} is probably a mistake,
+since it combines the ISO week number year with the conventional month and day.
+@item %h
+same as @samp{%b}
+@item %j
+day of year (@samp{001}@dots{}@samp{366})
+@item %m
+month (@samp{01}@dots{}@samp{12})
+@item %q
+quarter of year (@samp{1}@dots{}@samp{4})
+@item %u
+day of week (@samp{1}@dots{}@samp{7}) with @samp{1} corresponding to Monday
+@item %U
+week number of year, with Sunday as the first day of the week
+(@samp{00}@dots{}@samp{53}).
+Days in a new year preceding the first Sunday are in week zero.
+@item %V
+ISO week number, that is, the
+week number of year, with Monday as the first day of the week
+(@samp{01}@dots{}@samp{53}).
+If the week containing January 1 has four or more days in
+the new year, then it is considered week 1; otherwise, it is week 53 of
+the previous year, and the next week is week 1.  (See the ISO 8601
+standard.)
+@item %w
+day of week (@samp{0}@dots{}@samp{6}) with 0 corresponding to Sunday
+@item %W
+week number of year, with Monday as first day of week
+(@samp{00}@dots{}@samp{53}).
+Days in a new year preceding the first Monday are in week zero.
+@item %x
+locale's date representation (e.g., @samp{12/31/99})
+@item %y
+last two digits of year (@samp{00}@dots{}@samp{99})
+@item %Y
+year.  This is normally at least four characters, but it may be more.
+Year @samp{0000} precedes year @samp{0001}, and year @samp{-001}
+precedes year @samp{0000}.
+@end table
+
+
+@node Literal conversion specifiers
+@subsection Literal conversion specifiers
+
+@cindex literal conversion specifiers
+@cindex conversion specifiers, literal
+
+@command{date} conversion specifiers that produce literal strings.
+
+@table @samp
+@item %%
+a literal %
+@item %n
+a newline
+@item %t
+a horizontal tab
+@end table
+
+
+@node Padding and other flags
+@subsection Padding and other flags
+
+@cindex numeric field padding
+@cindex padding of numeric fields
+@cindex fields, padding numeric
+
+Unless otherwise specified, @command{date} normally pads numeric fields
+with zeros, so that, for
+example, numeric months are always output as two digits.
+Seconds since the epoch are not padded, though,
+since there is no natural width for them.
+
+The following optional flags can appear after the @samp{%}:
+
+@table @samp
+@item -
+(hyphen) Do not pad the field; useful if the output is intended for
+human consumption.
+This is a GNU extension.
+@item _
+(underscore) Pad with spaces; useful if you need a fixed
+number of characters in the output, but zeros are too distracting.
+This is a GNU extension.
+@item 0
+(zero) Pad with zeros even if the conversion specifier
+would normally pad with spaces.
+@item +
+Pad with zeros, like @samp{0}.  In addition, precede any year number
+with @samp{+} if it exceeds 9999 or if its field width exceeds 4;
+similarly, precede any century number with @samp{+} if it exceeds 99
+or if its field width exceeds 2.  This supports ISO 8601 formats
+for dates far in the future; for example, the command @code{date
+--date=12019-02-25 +%+13F} outputs the string @samp{+012019-02-25}.
+@item ^
+Use upper case characters if possible.
+This is a GNU extension.
+@item #
+Use opposite case characters if possible.
+A field that is normally upper case becomes lower case, and vice versa.
+This is a GNU extension.
+@end table
+
+@noindent
+Here are some examples of padding:
+
+@example
+date +%d/%m -d "Feb 1"
+@result{} 01/02
+date +%-d/%-m -d "Feb 1"
+@result{} 1/2
+date +%_d/%_m -d "Feb 1"
+@result{}  1/ 2
+@end example
+
+You can optionally specify the field width
+(after any flag, if present) as a decimal number.  If the natural size of the
+output of the field has less than the specified number of characters,
+the result is written right adjusted and padded to the given
+size.  For example, @samp{%9B} prints the right adjusted month name in
+a field of width 9.
+
+An optional modifier can follow the optional flag and width
+specification.  The modifiers are:
+
+@table @samp
+@item E
+Use the locale's alternate representation for date and time.  This
+modifier applies to the @samp{%c}, @samp{%C}, @samp{%x}, @samp{%X},
+@samp{%y} and @samp{%Y} conversion specifiers.  In a Japanese locale, for
+example, @samp{%Ex} might yield a date format based on the Japanese
+Emperors' reigns.
+
+@item O
+Use the locale's alternate numeric symbols for numbers.  This modifier
+applies only to numeric conversion specifiers.
+@end table
+
+If the format supports the modifier but no alternate representation
+is available, it is ignored.
+
+POSIX specifies the behavior of flags and field widths only for
+@samp{%C}, @samp{%F}, @samp{%G}, and @samp{%Y} (all without
+modifiers), and requires a flag to be present if and only if a field
+width is also present.  Other combinations of flags, field widths and
+modifiers are GNU extensions.
+
+
+@node Setting the time
+@subsection Setting the time
+
+@cindex setting the time
+@cindex time setting
+@cindex appropriate privileges
+
+If given an argument that does not start with @samp{+}, @command{date} sets
+the system clock to the date and time specified by that argument (as
+described below).  You must have appropriate privileges to set the
+system clock.  Note for changes to persist across a reboot, the
+hardware clock may need to be updated from the system clock, which
+might not happen automatically on your system.
+
+The argument must consist entirely of digits, which have the following
+meaning:
+
+@table @samp
+@item MM
+month
+@item DD
+day within month
+@item hh
+hour
+@item mm
+minute
+@item CC
+first two digits of year (optional)
+@item YY
+last two digits of year (optional)
+@item ss
+second (optional)
+@end table
+
+Note, the @option{--date} and @option{--set} options may not be used with an
+argument in the above format.  The @option{--universal} option may be used
+with such an argument to indicate that the specified date and time are
+relative to Universal Time rather than to the local time zone.
+
+
+@node Options for date
+@subsection Options for @command{date}
+
+@cindex @command{date} options
+@cindex options for @command{date}
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -d @var{datestr}
+@itemx --date=@var{datestr}
+@opindex -d
+@opindex --date
+@cindex parsing date strings
+@cindex date strings, parsing
+@cindex arbitrary date strings, parsing
+@opindex yesterday
+@opindex tomorrow
+@opindex next @var{day}
+@opindex last @var{day}
+Display the date and time specified in @var{datestr} instead of the
+current date and time.  @var{datestr} can be in almost any common
+format.  It can contain month names, time zones, @samp{am} and @samp{pm},
+@samp{yesterday}, etc.  For example, @option{--date="2004-02-27
+14:19:13.489392193 +0530"} specifies the instant of time that is
+489,392,193 nanoseconds after February 27, 2004 at 2:19:13 PM in a
+time zone that is 5 hours and 30 minutes east of UTC.@*
+Note: input currently must be in locale independent format.  E.g., the
+LC_TIME=C below is needed to print back the correct date in many locales:
+@example
+date -d "$(LC_TIME=C date)"
+@end example
+@xref{Date input formats}.
+
+@item --debug
+@opindex --debug
+@cindex debugging date strings
+@cindex date strings, debugging
+@cindex arbitrary date strings, debugging
+Annotate the parsed date, display the effective time zone, and warn about
+potential misuse.
+
+@item -f @var{datefile}
+@itemx --file=@var{datefile}
+@opindex -f
+@opindex --file
+Parse each line in @var{datefile} as with @option{-d} and display the
+resulting date and time.  If @var{datefile} is @samp{-}, use standard
+input.  This is useful when you have many dates to process, because the
+system overhead of starting up the @command{date} executable many times can
+be considerable.
+
+@item -I[@var{timespec}]
+@itemx --iso-8601[=@var{timespec}]
+@opindex -I[@var{timespec}]
+@opindex --iso-8601[=@var{timespec}]
+Display the date using an ISO 8601 format, @samp{%Y-%m-%d}.
+
+The argument @var{timespec} specifies the number of additional
+terms of the time to include.  It can be one of the following:
+@table @samp
+@item auto
+Print just the date.  This is the default if @var{timespec} is omitted.
+
+@item hours
+Append the hour of the day to the date.
+
+@item minutes
+Append the hours and minutes.
+
+@item seconds
+Append the hours, minutes and seconds.
+
+@item ns
+Append the hours, minutes, seconds and nanoseconds.
+@end table
+
+If showing any time terms, then include the time zone using the format
+@samp{%:z}.
+@macro dateParseNote
+This format is always suitable as input
+for the @option{--date} (@option{-d}) and @option{--file}
+(@option{-f}) options, regardless of the current locale.
+@end macro
+@dateParseNote
+
+@item -r @var{file}
+@itemx --reference=@var{file}
+@opindex -r
+@opindex --reference
+Display the date and time of the last modification of @var{file},
+instead of the current date and time.
+
+@item -R
+@itemx --rfc-email
+@opindex -R
+@opindex --rfc-email
+Display the date and time using the format @samp{%a, %d %b %Y %H:%M:%S
+%z}, evaluated in the C locale so abbreviations are always in English.
+For example:
+
+@example
+Fri, 09 Sep 2005 13:51:39 -0700
+@end example
+
+@opindex --rfc-822
+@opindex --rfc-2822
+This format conforms to Internet RFCs
+@uref{https://tools.ietf.org/search/rfc5322, 5322},
+@uref{https://tools.ietf.org/search/rfc2822, 2822} and
+@uref{https://tools.ietf.org/search/rfc822, 822}, the
+current and previous standards for Internet email.
+For compatibility with older versions of @command{date},
+@option{--rfc-2822} and @option{--rfc-822} are aliases for
+@option{--rfc-email}.
+
+@item --rfc-3339=@var{timespec}
+@opindex --rfc-3339=@var{timespec}
+Display the date using a format specified by
+@uref{https://tools.ietf.org/search/rfc3339, Internet
+RFC 3339}.  This is like @option{--iso-8601}, except that a space rather
+than a @samp{T} separates dates from times.
+@dateParseNote
+
+The argument @var{timespec} specifies how much of the time to include.
+It can be one of the following:
+
+@table @samp
+@item date
+Print just the full-date, e.g., @samp{2005-09-14}.
+This is equivalent to the format @samp{%Y-%m-%d}.
+
+@item seconds
+Print the full-date and full-time separated by a space, e.g.,
+@samp{2005-09-14 00:56:06+05:30}.  The output ends with a numeric
+time-offset; here the @samp{+05:30} means that local time is five
+hours and thirty minutes east of UTC@.  This is equivalent to
+the format @samp{%Y-%m-%d %H:%M:%S%:z}.
+
+@item ns
+Like @samp{seconds}, but also print nanoseconds, e.g.,
+@samp{2005-09-14 00:56:06.998458565+05:30}.
+This is equivalent to the format @samp{%Y-%m-%d %H:%M:%S.%N%:z}.
+
+@end table
+
+@item -s @var{datestr}
+@itemx --set=@var{datestr}
+@opindex -s
+@opindex --set
+Set the date and time to @var{datestr}.  See @option{-d} above.
+See also @ref{Setting the time}.
+
+@item -u
+@itemx --utc
+@itemx --universal
+@opindex -u
+@opindex --utc
+@opindex --universal
+@cindex Coordinated Universal Time
+@cindex UTC
+@cindex Greenwich Mean Time
+@cindex GMT
+@cindex leap seconds
+@vindex TZ
+@cindex Universal Time
+Use Universal Time by operating as if the
+@env{TZ} environment variable were set to the string @samp{UTC0}.
+UTC stands for Coordinated Universal Time, established in 1960.
+Universal Time is often called ``Greenwich Mean Time'' (GMT) for
+historical reasons.
+Typically, systems ignore leap seconds and thus implement an
+approximation to UTC rather than true UTC.
+@end table
+
+
+@node Examples of date
+@subsection Examples of @command{date}
+
+@cindex examples of @command{date}
+
+Here are a few examples.  Also see the documentation for the @option{-d}
+option in the previous section.
+
+@itemize @bullet
+
+@item
+To print the date of the day before yesterday:
+
+@example
+date --date='2 days ago'
+@end example
+
+@item
+To print the date of the day three months and one day hence:
+
+@example
+date --date='3 months 1 day'
+@end example
+
+@item
+To print the day of year of Christmas in the current year:
+
+@example
+date --date='25 Dec' +%j
+@end example
+
+@item
+To print the current full month name and the day of the month:
+
+@example
+date '+%B %d'
+@end example
+
+But this may not be what you want because for the first nine days of
+the month, the @samp{%d} expands to a zero-padded two-digit field,
+for example @samp{date -d 1may '+%B %d'} will print @samp{May 01}.
+
+@item
+To print a date without the leading zero for one-digit days
+of the month, you can use the (GNU extension)
+@samp{-} flag to suppress
+the padding altogether:
+
+@example
+date -d 1may '+%B %-d'
+@end example
+
+@item
+To print the current date and time in the format required by many
+non-GNU versions of @command{date} when setting the system clock:
+
+@example
+date +%m%d%H%M%Y.%S
+@end example
+
+@item
+To set the system clock forward by two minutes:
+
+@example
+date --set='+2 minutes'
+@end example
+
+@item
+To print the date in Internet RFC 5322 format,
+use @samp{date --rfc-email}.  Here is some example output:
+
+@example
+Fri, 09 Sep 2005 13:51:39 -0700
+@end example
+
+@anchor{%s-examples}
+@item
+To convert a date string to the number of seconds since the epoch
+(which is 1970-01-01 00:00:00 UTC), use the @option{--date} option with
+the @samp{%s} format.  That can be useful in sorting and/or graphing
+and/or comparing data by date.  The following command outputs the
+number of the seconds since the epoch for the time two minutes after the
+epoch:
+
+@example
+date --date='1970-01-01 00:02:00 +0000' +%s
+120
+@end example
+
+If you do not specify time zone information in the date string,
+@command{date} uses your computer's idea of the time zone when
+interpreting the string.  For example, if your computer's time zone is
+that of Cambridge, Massachusetts, which was then 5 hours (i.e., 18,000
+seconds) behind UTC:
+
+@example
+# local time zone used
+date --date='1970-01-01 00:02:00' +%s
+18120
+@end example
+
+@item
+If you're sorting or graphing dated data, your raw date values may be
+represented as seconds since the epoch.  But few people can look at
+the date @samp{946684800} and casually note ``Oh, that's the first second
+of the year 2000 in Greenwich, England.''
+
+@example
+date --date='2000-01-01 UTC' +%s
+946684800
+@end example
+
+An alternative is to use the @option{--utc} (@option{-u}) option.
+Then you may omit @samp{UTC} from the date string.  Although this
+produces the same result for @samp{%s} and many other format sequences,
+with a time zone offset different from zero, it would give a different
+result for zone-dependent formats like @samp{%z}.
+
+@example
+date -u --date=2000-01-01 +%s
+946684800
+@end example
+
+To convert such an unwieldy number of seconds back to
+a more readable form, use a command like this:
+
+@example
+# local time zone used
+date -d '1970-01-01 UTC 946684800 seconds' +"%Y-%m-%d %T %z"
+1999-12-31 19:00:00 -0500
+@end example
+
+Or if you do not mind depending on the @samp{@@} feature present since
+coreutils 5.3.0, you could shorten this to:
+
+@example
+date -d @@946684800 +"%F %T %z"
+1999-12-31 19:00:00 -0500
+@end example
+
+Often it is better to output UTC-relative date and time:
+
+@example
+date -u -d '1970-01-01 946684800 seconds' +"%Y-%m-%d %T %z"
+2000-01-01 00:00:00 +0000
+@end example
+
+@item
+@cindex leap seconds
+Typically the seconds count omits leap seconds, but some systems are
+exceptions.  Because leap seconds are not predictable, the mapping
+between the seconds count and a future timestamp is not reliable on
+the atypical systems that include leap seconds in their counts.
+
+Here is how the two kinds of systems handle the leap second at
+2012-06-30 23:59:60 UTC:
+
+@example
+# Typical systems ignore leap seconds:
+date --date='2012-06-30 23:59:59 +0000' +%s
+1341100799
+date --date='2012-06-30 23:59:60 +0000' +%s
+date: invalid date '2012-06-30 23:59:60 +0000'
+date --date='2012-07-01 00:00:00 +0000' +%s
+1341100800
+@end example
+
+@example
+# Atypical systems count leap seconds:
+date --date='2012-06-30 23:59:59 +0000' +%s
+1341100823
+date --date='2012-06-30 23:59:60 +0000' +%s
+1341100824
+date --date='2012-07-01 00:00:00 +0000' +%s
+1341100825
+@end example
+
+@end itemize
+
+
+@node arch invocation
+@section @command{arch}: Print machine hardware name
+
+@pindex arch
+@cindex print machine hardware name
+@cindex system information, printing
+
+@command{arch} prints the machine hardware name,
+and is equivalent to @samp{uname -m}.
+Synopsis:
+
+@example
+arch [@var{option}]
+@end example
+
+The program accepts the @ref{Common options} only.
+
+@command{arch} is not installed by default, so portable scripts should
+not rely on its existence.
+
+@exitstatus
+
+
+@node nproc invocation
+@section @command{nproc}: Print the number of available processors
+
+@pindex nproc
+@cindex Print the number of processors
+@cindex system information, printing
+
+Print the number of processing units available to the current process,
+which may be less than the number of online processors.
+If this information is not accessible, then print the number of
+processors installed.  If the @env{OMP_NUM_THREADS} or @env{OMP_THREAD_LIMIT}
+environment variables are set, then they will determine the minimum
+and maximum returned value respectively.  The result is guaranteed to be
+greater than zero.  Synopsis:
+
+@example
+nproc [@var{option}]
+@end example
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item --all
+@opindex --all
+Print the number of installed processors on the system, which may
+be greater than the number online or available to the current process.
+The @env{OMP_NUM_THREADS} or @env{OMP_THREAD_LIMIT} environment variables
+are not honored in this case.
+
+@item --ignore=@var{number}
+@opindex --ignore
+If possible, exclude this @var{number} of processing units.
+
+@end table
+
+@exitstatus
+
+
+@node uname invocation
+@section @command{uname}: Print system information
+
+@pindex uname
+@cindex print system information
+@cindex system information, printing
+
+@command{uname} prints information about the machine and operating system
+it is run on.  If no options are given, @command{uname} acts as if the
+@option{-s} option were given.  Synopsis:
+
+@example
+uname [@var{option}]@dots{}
+@end example
+
+If multiple options or @option{-a} are given, the selected information is
+printed in this order:
+
+@example
+@var{kernel-name} @var{nodename} @var{kernel-release} @var{kernel-version}
+@var{machine} @var{processor} @var{hardware-platform} @var{operating-system}
+@end example
+
+The information may contain internal spaces, so such output cannot be
+parsed reliably.  In the following example, @var{release} is
+@samp{2.2.18ss.e820-bda652a #4 SMP Tue Jun 5 11:24:08 PDT 2001}:
+
+@example
+uname -a
+@result{} Linux dumdum 2.2.18 #4 SMP Tue Jun 5 11:24:08 PDT 2001 i686@c
+ unknown unknown GNU/Linux
+@end example
+
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -a
+@itemx --all
+@opindex -a
+@opindex --all
+Print all of the below information, except omit the processor type
+and the hardware platform name if they are unknown.
+
+@item -i
+@itemx --hardware-platform
+@opindex -i
+@opindex --hardware-platform
+@cindex implementation, hardware
+@cindex hardware platform
+@cindex platform, hardware
+Print the hardware platform name
+(sometimes called the hardware implementation).
+Print @samp{unknown} if this information is not available.
+Note this is non-portable (even across GNU/Linux distributions).
+
+@item -m
+@itemx --machine
+@opindex -m
+@opindex --machine
+@cindex machine type
+@cindex hardware class
+@cindex hardware type
+Print the machine hardware name (sometimes called the hardware class
+or hardware type).
+
+@item -n
+@itemx --nodename
+@opindex -n
+@opindex --nodename
+@cindex hostname
+@cindex node name
+@cindex network node name
+Print the network node hostname.
+
+@item -p
+@itemx --processor
+@opindex -p
+@opindex --processor
+@cindex host processor type
+Print the processor type (sometimes called the instruction set
+architecture or ISA).
+Print @samp{unknown} if this information is not available.
+Note this is non-portable (even across GNU/Linux distributions).
+
+@item -o
+@itemx --operating-system
+@opindex -o
+@opindex --operating-system
+@cindex operating system name
+Print the name of the operating system.
+
+@item -r
+@itemx --kernel-release
+@opindex -r
+@opindex --kernel-release
+@cindex kernel release
+@cindex release of kernel
+Print the kernel release.
+
+@item -s
+@itemx --kernel-name
+@opindex -s
+@opindex --kernel-name
+@cindex kernel name
+@cindex name of kernel
+Print the kernel name.
+POSIX 1003.1-2001 (@pxref{Standards conformance}) calls this
+``the implementation of the operating system'', because the
+POSIX specification itself has no notion of ``kernel''.
+The kernel name might be the same as the operating system name printed
+by the @option{-o} or @option{--operating-system} option, but it might
+differ.  Some operating systems (e.g., FreeBSD, HP-UX) have the same
+name as their underlying kernels; others (e.g., GNU/Linux, Solaris)
+do not.
+
+@item -v
+@itemx --kernel-version
+@opindex -v
+@opindex --kernel-version
+@cindex kernel version
+@cindex version of kernel
+Print the kernel version.
+
+@end table
+
+@exitstatus
+
+
+@node hostname invocation
+@section @command{hostname}: Print or set system name
+
+@pindex hostname
+@cindex setting the hostname
+@cindex printing the hostname
+@cindex system name, printing
+@cindex appropriate privileges
+
+With no arguments, @command{hostname} prints the name of the current host
+system.  With one argument, it sets the current host name to the
+specified string.  You must have appropriate privileges to set the host
+name.  Synopsis:
+
+@example
+hostname [@var{name}]
+@end example
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.
+
+@command{hostname} is not installed by default, and other packages
+also supply a @command{hostname} command, so portable scripts should
+not rely on its existence or on the exact behavior documented above.
+
+@exitstatus
+
+
+@node hostid invocation
+@section @command{hostid}: Print numeric host identifier
+
+@pindex hostid
+@cindex printing the host identifier
+
+@command{hostid} prints the numeric identifier of the current host
+in hexadecimal.  This command accepts no arguments.
+The only options are @option{--help} and @option{--version}.
+@xref{Common options}.
+
+For example, here's what it prints on one system I use:
+
+@example
+$ hostid
+1bac013d
+@end example
+
+On that system, the 32-bit quantity happens to be closely
+related to the system's Internet address, but that isn't always
+the case.
+
+@command{hostid} is installed only on systems that have the
+@code{gethostid} function, so portable scripts should not rely on its
+existence.
+
+@exitstatus
+
+@node uptime invocation
+@section @command{uptime}: Print system uptime and load
+
+@pindex uptime
+@cindex printing the system uptime and load
+
+@command{uptime} prints the current time, the system's uptime, the
+number of logged-in users and the current load average.
+
+If an argument is specified, it is used as the file to be read
+to discover how many users are logged in.  If no argument is
+specified, a system default is used (@command{uptime --help} indicates
+the default setting).
+
+The only options are @option{--help} and @option{--version}.
+@xref{Common options}.
+
+For example, here's what it prints right now on one system I use:
+
+@example
+$ uptime
+ 14:07  up   3:35,  3 users,  load average: 1.39, 1.15, 1.04
+@end example
+
+The precise method of calculation of load average varies somewhat
+between systems.  Some systems calculate it as the average number of
+runnable processes over the last 1, 5 and 15 minutes, but some systems
+also include processes in the uninterruptible sleep state (that is,
+those processes which are waiting for disk I/O).  The Linux kernel
+includes uninterruptible processes.
+
+@command{uptime} is installed only on platforms with infrastructure
+for obtaining the boot time, and other packages also supply an
+@command{uptime} command, so portable scripts should not rely on its
+existence or on the exact behavior documented above.
+
+@exitstatus
+
+@node SELinux context
+@chapter SELinux context
+
+@cindex SELinux context
+@cindex SELinux, context
+@cindex commands for SELinux context
+
+This section describes commands for operations with SELinux
+contexts.
+
+@menu
+* chcon invocation::            Change SELinux context of file
+* runcon invocation::           Run a command in specified SELinux context
+@end menu
+
+@node chcon invocation
+@section @command{chcon}: Change SELinux context of file
+
+@pindex chcon
+@cindex changing security context
+@cindex change SELinux context
+
+@command{chcon} changes the SELinux security context of the selected files.
+Synopses:
+
+@example
+chcon [@var{option}]@dots{} @var{context} @var{file}@dots{}
+chcon [@var{option}]@dots{} [-u @var{user}] [-r @var{role}] [-l @var{range}]@c
+ [-t @var{type}] @var{file}@dots{}
+chcon [@var{option}]@dots{} --reference=@var{rfile} @var{file}@dots{}
+@end example
+
+Change the SELinux security context of each @var{file} to @var{context}.
+With @option{--reference}, change the security context of each @var{file}
+to that of @var{rfile}.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item --dereference
+@opindex --dereference
+Do not affect symbolic links but what they refer to; this is the default.
+
+@item -h
+@itemx --no-dereference
+@opindex -h
+@opindex --no-dereference
+@cindex no dereference
+Affect the symbolic links themselves instead of any referenced file.
+
+@item --reference=@var{rfile}
+@opindex --reference
+@cindex reference file
+Use @var{rfile}'s security context rather than specifying a @var{context} value.
+
+@item -R
+@itemx --recursive
+@opindex -R
+@opindex --recursive
+Operate on files and directories recursively.
+
+@item --preserve-root
+@opindex --preserve-root
+Refuse to operate recursively on the root directory, @file{/},
+when used together with the @option{--recursive} option.
+@xref{Treating / specially}.
+
+@item --no-preserve-root
+@opindex --no-preserve-root
+Do not treat the root directory, @file{/}, specially when operating
+recursively; this is the default.
+@xref{Treating / specially}.
+
+@choptH
+@xref{Traversing symlinks}.
+
+@choptL
+@xref{Traversing symlinks}.
+
+@choptP
+@xref{Traversing symlinks}.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+@cindex diagnostic
+Output a diagnostic for every file processed.
+
+@item -u @var{user}
+@itemx --user=@var{user}
+@opindex -u
+@opindex --user
+Set user @var{user} in the target security context.
+
+@item -r @var{role}
+@itemx --role=@var{role}
+@opindex -r
+@opindex --role
+Set role @var{role} in the target security context.
+
+@item -t @var{type}
+@itemx --type=@var{type}
+@opindex -t
+@opindex --type
+Set type @var{type} in the target security context.
+
+@item -l @var{range}
+@itemx --range=@var{range}
+@opindex -l
+@opindex --range
+Set range @var{range} in the target security context.
+
+@end table
+
+@exitstatus
+
+@node runcon invocation
+@section @command{runcon}: Run a command in specified SELinux context
+
+@pindex runcon
+@cindex run with security context
+
+
+@command{runcon} runs file in specified SELinux security context.
+
+Synopses:
+@example
+runcon @var{context} @var{command} [@var{args}]
+runcon [ -c ] [-u @var{user}] [-r @var{role}] [-t @var{type}]@c
+ [-l @var{range}] @var{command} [@var{args}]
+@end example
+
+Run @var{command} with completely-specified @var{context}, or with
+current or transitioned security context modified by one or more of @var{level},
+@var{role}, @var{type} and @var{user}.
+
+If none of @option{-c}, @option{-t}, @option{-u}, @option{-r}, or @option{-l}
+is specified, the first argument is used as the complete context.
+Any additional arguments after @var{command}
+are interpreted as arguments to the command.
+
+With neither @var{context} nor @var{command}, print the current
+security context.
+
+@cindex restricted security context
+@cindex NO_NEW_PRIVS
+Note also the @command{setpriv} command which can be used to set the
+NO_NEW_PRIVS bit using @command{setpriv --no-new-privs runcon ...},
+thus disallowing usage of a security context with more privileges
+than the process would normally have.
+
+@command{runcon} accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -c
+@itemx --compute
+@opindex -c
+@opindex --compute
+Compute process transition context before modifying.
+
+@item -u @var{user}
+@itemx --user=@var{user}
+@opindex -u
+@opindex --user
+Set user @var{user} in the target security context.
+
+@item -r @var{role}
+@itemx --role=@var{role}
+@opindex -r
+@opindex --role
+Set role @var{role} in the target security context.
+
+@item -t @var{type}
+@itemx --type=@var{type}
+@opindex -t
+@opindex --type
+Set type @var{type} in the target security context.
+
+@item -l @var{range}
+@itemx --range=@var{range}
+@opindex -l
+@opindex --range
+Set range @var{range} in the target security context.
+
+@end table
+
+@cindex exit status of @command{runcon}
+Exit status:
+
+@display
+126 if @var{command} is found but cannot be invoked
+127 if @command{runcon} itself fails or if @var{command} cannot be found
+the exit status of @var{command} otherwise
+@end display
+
+@node Modified command invocation
+@chapter Modified command invocation
+
+@cindex modified command invocation
+@cindex invocation of commands, modified
+@cindex commands for invoking other commands
+
+This section describes commands that run other commands in some context
+different than the current one: a modified environment, as a different
+user, etc.
+
+@menu
+* chroot invocation::           Modify the root directory.
+* env invocation::              Modify environment variables.
+* nice invocation::             Modify niceness.
+* nohup invocation::            Immunize to hangups.
+* stdbuf invocation::           Modify buffering of standard streams.
+* timeout invocation::          Run with time limit.
+@end menu
+
+
+@node chroot invocation
+@section @command{chroot}: Run a command with a different root directory
+
+@pindex chroot
+@cindex running a program in a specified root directory
+@cindex root directory, running a program in a specified
+
+@command{chroot} runs a command with a specified root directory.
+On many systems, only the super-user can do this.@footnote{However,
+some systems (e.g., FreeBSD) can be configured to allow certain regular
+users to use the @code{chroot} system call, and hence to run this program.
+Also, on Cygwin, anyone can run the @command{chroot} command, because the
+underlying function is non-privileged due to lack of support in MS-Windows.
+Furthermore, the @command{chroot} command avoids the @code{chroot} system call
+when @var{newroot} is identical to the old @file{/} directory for consistency
+with systems where this is allowed for non-privileged users.}.
+Synopses:
+
+@example
+chroot @var{option} @var{newroot} [@var{command} [@var{args}]@dots{}]
+chroot @var{option}
+@end example
+
+Ordinarily, file names are looked up starting at the root of the
+directory structure, i.e., @file{/}.  @command{chroot} changes the root to
+the directory @var{newroot} (which must exist), then changes the working
+directory to @file{/}, and finally runs @var{command} with optional @var{args}.
+If @var{command} is not specified, the default is the value of the @env{SHELL}
+environment variable or @command{/bin/sh} if not set, invoked with the
+@option{-i} option.
+@var{command} must not be a special built-in utility
+(@pxref{Special built-in utilities}).
+
+The program accepts the following options.  Also see @ref{Common options}.
+Options must precede operands.
+
+@table @samp
+
+@item --groups=@var{groups}
+@opindex --groups
+Use this option to override the supplementary @var{groups} to be
+used by the new process.
+The items in the list (names or numeric IDs) must be separated by commas.
+Use @samp{--groups=''} to disable the supplementary group look-up
+implicit in the @option{--userspec} option.
+
+@item --userspec=@var{user}[:@var{group}]
+@opindex --userspec
+By default, @var{command} is run with the same credentials
+as the invoking process.
+Use this option to run it as a different @var{user} and/or with a
+different primary @var{group}.
+If a @var{user} is specified then the supplementary groups
+are set according to the system defined list for that user,
+unless overridden with the @option{--groups} option.
+
+@item --skip-chdir
+@opindex --skip-chdir
+Use this option to not change the working directory to @file{/} after changing
+the root directory to @var{newroot}, i.e., inside the chroot.
+This option is only permitted when @var{newroot} is the old @file{/} directory,
+and therefore is mostly useful together with the @option{--groups} and
+@option{--userspec} options to retain the previous working directory.
+
+@end table
+
+The user and group name look-up performed by the @option{--userspec}
+and @option{--groups} options, is done both outside and inside
+the chroot, with successful look-ups inside the chroot taking precedence.
+If the specified user or group items are intended to represent a numeric ID,
+then a name to ID resolving step is avoided by specifying a leading @samp{+}.
+@xref{Disambiguating names and IDs}.
+
+Here are a few tips to help avoid common problems in using chroot.
+To start with a simple example, make @var{command} refer to a statically
+linked binary.  If you were to use a dynamically linked executable, then
+you'd have to arrange to have the shared libraries in the right place under
+your new root directory.
+
+For example, if you create a statically linked @command{ls} executable,
+and put it in @file{/tmp/empty}, you can run this command as root:
+
+@example
+$ chroot /tmp/empty /ls -Rl /
+@end example
+
+Then you'll see output like this:
+
+@example
+/:
+total 1023
+-rwxr-xr-x 1 0 0 1041745 Aug 16 11:17 ls
+@end example
+
+If you want to use a dynamically linked executable, say @command{bash},
+then first run @samp{ldd bash} to see what shared objects it needs.
+Then, in addition to copying the actual binary, also copy the listed
+files to the required positions under your intended new root directory.
+Finally, if the executable requires any other files (e.g., data, state,
+device files), copy them into place, too.
+
+@command{chroot} is installed only on systems that have the
+@code{chroot} function, so portable scripts should not rely on its
+existence.
+
+@cindex exit status of @command{chroot}
+Exit status:
+
+@display
+125 if @command{chroot} itself fails
+126 if @var{command} is found but cannot be invoked
+127 if @var{command} cannot be found
+the exit status of @var{command} otherwise
+@end display
+
+
+@node env invocation
+@section @command{env}: Run a command in a modified environment
+
+@pindex env
+@cindex environment, running a program in a modified
+@cindex modified environment, running a program in a
+@cindex running a program in a modified environment
+
+@command{env} runs a command with a modified environment.  Synopses:
+
+@example
+env [@var{option}]@dots{} [@var{name}=@var{value}]@dots{} @c
+[@var{command} [@var{args}]@dots{}]
+env -[v]S'[@var{option}]@dots{} [@var{name}=@var{value}]@dots{} @c
+[@var{command} [@var{args}]@dots{}]'
+env
+@end example
+
+@command{env} is commonly used on first line of scripts (shebang line):
+@example
+#!/usr/bin/env @var{command}
+#!/usr/bin/env -[v]S[@var{option}]@dots{} [@var{name}=@var{value}]@dots{} @c
+@var{command} [@var{args}]@dots{}
+@end example
+
+Operands of the form @samp{@var{variable}=@var{value}} set
+the environment variable @var{variable} to value @var{value}.
+@var{value} may be empty (@samp{@var{variable}=}).  Setting a variable
+to an empty value is different from unsetting it.
+These operands are evaluated left-to-right, so if two operands
+mention the same variable the earlier is ignored.
+
+Environment variable names can be empty, and can contain any
+characters other than @samp{=} and ASCII NUL.
+However, it is wise to limit yourself to names that
+consist solely of underscores, digits, and ASCII letters,
+and that begin with a non-digit, as applications like the shell do not
+work well with other names.
+
+@vindex PATH
+The first operand that does not contain the character @samp{=}
+specifies the program to invoke; it is
+searched for according to the @env{PATH} environment variable.  Any
+remaining arguments are passed as arguments to that program.
+The program should not be a special built-in utility
+(@pxref{Special built-in utilities}).
+
+Modifications to @env{PATH} take effect prior to searching for
+@var{command}.  Use caution when reducing @env{PATH}; behavior is
+not portable when @env{PATH} is undefined or omits key directories
+such as @file{/bin}.
+
+In the rare case that a utility contains a @samp{=} in the name, the
+only way to disambiguate it from a variable assignment is to use an
+intermediate command for @var{command}, and pass the problematic
+program name via @var{args}.  For example, if @file{./prog=} is an
+executable in the current @env{PATH}:
+
+@example
+env prog= true # runs 'true', with prog= in environment
+env ./prog= true # runs 'true', with ./prog= in environment
+env -- prog= true # runs 'true', with prog= in environment
+env sh -c '\prog= true' # runs 'prog=' with argument 'true'
+env sh -c 'exec "$@@"' sh prog= true # also runs 'prog='
+@end example
+
+@cindex environment, printing
+
+If no command name is specified following the environment
+specifications, the resulting environment is printed.  This is like
+specifying the @command{printenv} program.
+
+For some examples, suppose the environment passed to @command{env}
+contains @samp{LOGNAME=rms}, @samp{EDITOR=emacs}, and
+@samp{PATH=.:/gnubin:/hacks}:
+
+@itemize @bullet
+
+@item
+Output the current environment.
+@example
+$ env | LC_ALL=C sort
+EDITOR=emacs
+LOGNAME=rms
+PATH=.:/gnubin:/hacks
+@end example
+
+@item
+Run @command{foo} with a reduced environment, preserving only the
+original @env{PATH} to avoid problems in locating @command{foo}.
+@example
+env - PATH="$PATH" foo
+@end example
+
+@item
+Run @command{foo} with the environment containing @samp{LOGNAME=rms},
+@samp{EDITOR=emacs}, and @samp{PATH=.:/gnubin:/hacks}, and guarantees
+that @command{foo} was found in the file system rather than as a shell
+built-in.
+@example
+env foo
+@end example
+
+@item
+Run @command{nemacs} with the environment containing @samp{LOGNAME=foo},
+@samp{EDITOR=emacs}, @samp{PATH=.:/gnubin:/hacks}, and
+@samp{DISPLAY=gnu:0}.
+@example
+env DISPLAY=gnu:0 LOGNAME=foo nemacs
+@end example
+
+@item
+Attempt to run the program @command{/energy/--} (as that is the only
+possible path search result); if the command exists, the environment
+will contain @samp{LOGNAME=rms} and @samp{PATH=/energy}, and the
+arguments will be @samp{e=mc2}, @samp{bar}, and @samp{baz}.
+@example
+env -u EDITOR PATH=/energy -- e=mc2 bar baz
+@end example
+
+@end itemize
+
+
+@subsection General options
+
+The program accepts the following options.  Also see @ref{Common options}.
+Options must precede operands.
+
+@table @samp
+
+@optNull
+
+@item -u @var{name}
+@itemx --unset=@var{name}
+@opindex -u
+@opindex --unset
+Remove variable @var{name} from the environment, if it was in the
+environment.
+
+@item -
+@itemx -i
+@itemx --ignore-environment
+@opindex -
+@opindex -i
+@opindex --ignore-environment
+Start with an empty environment, ignoring the inherited environment.
+
+@item -C @var{dir}
+@itemx --chdir=@var{dir}
+@opindex -C
+@opindex --chdir
+Change the working directory to @var{dir} before invoking @var{command}.
+This differs from the shell built-in @command{cd} in that it starts
+@var{command} as a subprocess rather than altering the shell's own working
+directory; this allows it to be chained with other commands that run commands
+in a different context.  For example:
+
+@example
+# Run 'true' with /chroot as its root directory and /srv as its working
+# directory.
+chroot /chroot env --chdir=/srv true
+# Run 'true' with /build as its working directory, FOO=bar in its
+# environment, and a time limit of five seconds.
+env --chdir=/build FOO=bar timeout 5 true
+@end example
+
+@item --default-signal[=@var{sig}]
+Unblock and reset signal @var{sig} to its default signal handler.
+Without @var{sig} all known signals are unblocked and reset to their defaults.
+Multiple signals can be comma-separated.  The following command runs
+@command{seq} with SIGINT and SIGPIPE set to their default
+(which is to terminate the program):
+
+@example
+env --default-signal=PIPE,INT seq 1000 | head -n1
+@end example
+
+In the following example, we see how this is not
+possible to do with traditional shells.
+Here the first trap command sets SIGPIPE to ignore.
+The second trap command ostensibly sets it back to its default,
+but POSIX mandates that the shell must not change inherited
+state of the signal - so it is a no-op.
+
+@example
+trap '' PIPE && sh -c 'trap - PIPE ; seq inf | head -n1'
+@end example
+
+Using @option{--default-signal=PIPE} we can
+ensure the signal handling is set to its default behavior:
+
+@example
+trap '' PIPE && sh -c 'env --default-signal=PIPE seq inf | head -n1'
+@end example
+
+
+@item --ignore-signal[=@var{sig}]
+Ignore signal @var{sig} when running a program.  Without @var{sig} all
+known signals are set to ignore.  Multiple signals can be
+comma-separated.  The following command runs @command{seq} with SIGINT set
+to be ignored - pressing @kbd{Ctrl-C} will not terminate it:
+
+@example
+env --ignore-signal=INT seq inf > /dev/null
+@end example
+
+@samp{SIGCHLD} is special, in that @option{--ignore-signal=CHLD} might have
+no effect (POSIX says it's unspecified).
+
+Most operating systems do not allow ignoring @samp{SIGKILL}, @samp{SIGSTOP}
+(and possibly other signals).  Attempting to ignore these signals will fail.
+
+Multiple (and contradictory) @option{--default-signal=SIG} and
+@option{--ignore-signal=SIG} options are processed left-to-right,
+with the latter taking precedence.  In the following example, @samp{SIGPIPE} is
+set to default while @samp{SIGINT} is ignored:
+
+@example
+env --default-signal=INT,PIPE --ignore-signal=INT
+@end example
+
+@item --block-signal[=@var{sig}]
+Block signal(s) @var{sig} from being delivered.
+
+@item --list-signal-handling
+List blocked or ignored signals to stderr, before executing a command.
+
+@item -v
+@itemx --debug
+@opindex -v
+@opindex --debug
+Show verbose information for each processing step.
+
+@example
+$ env -v -uTERM A=B uname -s
+unset:    TERM
+setenv:   A=B
+executing: uname
+   arg[0]= 'uname'
+   arg[1]= '-s'
+Linux
+@end example
+
+When combined with @option{-S} it is recommended to list @option{-v}
+first, e.g. @command{env -vS'string'}.
+
+@item -S @var{string}
+@itemx --split-string=@var{string}
+@opindex -S
+@opindex --split-string
+@cindex shebang arguments
+@cindex scripts arguments
+@cindex env in scripts
+process and split @var{string} into separate arguments used to pass
+multiple arguments on shebang lines.  @command{env} supports FreeBSD's
+syntax of several escape sequences and environment variable
+expansions. See below for details and examples.
+
+@end table
+
+@cindex exit status of @command{env}
+Exit status:
+
+@display
+0   if no @var{command} is specified and the environment is output
+125 if @command{env} itself fails
+126 if @var{command} is found but cannot be invoked
+127 if @var{command} cannot be found
+the exit status of @var{command} otherwise
+@end display
+
+@subsection @option{-S}/@option{--split-string} usage in scripts
+
+The @option{-S}/@option{--split-string} options enable using multiple
+arguments on the first one of scripts (shebang line, @samp{#!}).
+
+When a script's interpreter is in a known location, scripts typically
+contain the absolute file name in their first line:
+
+@multitable {Python Script:} {#!/usr/bin/python3}
+@item Shell script:
+@tab
+@example
+#!/bin/sh
+echo hello
+@end example
+
+@item Perl script:
+@tab
+@example
+#!/usr/bin/perl
+print "hello\n";
+@end example
+
+@item Python script:
+@tab
+@example
+#!/usr/bin/python3
+print("hello")
+@end example
+
+@end multitable
+
+When a script's interpreter is in a non-standard location
+in the @env{PATH} environment variable, it is recommended
+to use @command{env} on the first line of the script to
+find the executable and run it:
+
+@multitable {Python Script:} {#!/usr/bin/env python3}
+@item Shell script:
+@tab
+@example
+#!/usr/bin/env bash
+echo hello
+@end example
+
+@item Perl script:
+@tab
+@example
+#!/usr/bin/env perl
+print "hello\n";
+@end example
+
+@item Python script:
+@tab
+@example
+#!/usr/bin/env python3
+print("hello")
+@end example
+
+@end multitable
+
+Most operating systems (e.g. GNU/Linux, BSDs) treat all text after the
+first space as a single argument. When using @command{env} in a script
+it is thus not possible to specify multiple arguments.
+
+In the following example:
+@example
+#!/usr/bin/env perl -T -w
+print "hello\n";
+@end example
+
+The operating system treats @samp{perl -T -w} as one argument (the
+program's name), and executing the script fails with:
+
+@example
+/usr/bin/env: 'perl -T -w': No such file or directory
+@end example
+
+The @option{-S} option instructs @command{env} to split the single string
+into multiple arguments. The following example works as expected:
+
+@example
+$ cat hello.pl
+#!/usr/bin/env -S perl -T -w
+print "hello\n";
+
+$ chmod a+x hello.pl
+$ ./hello.pl
+hello
+@end example
+
+And is equivalent to running @command{perl -T -w hello.pl} on the command line
+prompt.
+
+@unnumberedsubsubsec Testing and troubleshooting
+
+@cindex single quotes, and @command{env -S}
+@cindex @command{env -S}, and single quotes
+@cindex @option{-S}, env and single quotes
+To test @command{env -S} on the command line, use single quotes for the
+@option{-S} string to emulate a single paramter. Single quotes are not
+needed when using @command{env -S} in a shebang line on the first line of a
+script (the operating system already treats it as one argument).
+
+The following command is equivalent to the @file{hello.pl} script above:
+
+@example
+$ env -S'perl -T -w' hello.pl
+@end example
+
+@cindex @command{env -S}, debugging
+@cindex debugging, @command{env -S}
+
+To troubleshoot @option{-S} usage add the @option{-v} as the first
+argument (before @option{-S}).
+
+Using @option{-vS} on a shebang line in a script:
+
+@example
+$ cat hello-debug.pl
+#!/usr/bin/env -vS perl -T -w
+print "hello\n";
+
+$ chmod a+x hello-debug.pl
+$ ./hello-debug.pl
+split -S:  'perl -T -w'
+ into:    'perl'
+     &    '-T'
+     &    '-w'
+executing: perl
+   arg[0]= 'perl'
+   arg[1]= '-T'
+   arg[2]= '-w'
+   arg[3]= './hello-debug.pl'
+hello
+@end example
+
+Using @option{-vS} on the command line prompt (adding single quotes):
+
+@example
+$ env -vS'perl -T -w' hello-debug.pl
+split -S:  'perl -T -w'
+ into:    'perl'
+     &    '-T'
+     &    '-w'
+executing: perl
+   arg[0]= 'perl'
+   arg[1]= '-T'
+   arg[2]= '-w'
+   arg[3]= 'hello-debug.pl'
+hello
+@end example
+
+@subsection @option{-S}/@option{--split-string} syntax
+
+@unnumberedsubsubsec Splitting arguments by whitespace
+
+Running @command{env -Sstring} splits the @var{string} into
+arguments based on unquoted spaces or tab characters.
+
+In the following contrived example the @command{awk} variable
+@samp{OFS} will be @code{<space>xyz<space>} as these spaces are inside
+double quotes. The other space characters are used as argument separators:
+
+@example
+$ cat one.awk
+#!/usr/bin/env -S awk -v OFS=" xyz " -f
+BEGIN @{print 1,2,3@}
+
+$ chmod a+x one.awk
+$ ./one.awk
+1 xyz 2 xyz 3
+@end example
+
+When using @option{-S} on the command line prompt, remember to add
+single quotes around the entire string:
+
+@example
+$ env -S'awk -v OFS=" xyz " -f' one.awk
+1 xyz 2 xyz 3
+@end example
+
+@unnumberedsubsubsec Escape sequences
+
+@command{env} supports several escape sequences. These sequences
+are processed when unquoted or inside double quotes (unless otherwise noted).
+Single quotes disable escape sequences except @samp{\'} and @samp{\\}.
+
+@multitable @columnfractions .10 .90
+
+@item @code{\c}
+@tab Ignore the remaining characters in the string.
+Cannot be used inside double quotes.
+
+@item @code{\f}
+@tab form-feed character (ASCII 0x0C)
+
+@item @code{\n}
+@tab new-line character (ASCII 0x0A)
+
+@item @code{\r}
+@tab carriage-return character (ASCII 0x0D)
+
+@item @code{\t}
+@tab tab character (ASCII 0x09)
+
+@item @code{\v}
+@tab vertical tab character (ASCII 0x0B)
+
+@item @code{\#}
+@tab A hash @samp{#} character. Used when a @samp{#} character
+is needed as the first character of an argument (see 'comments' section
+below).
+
+@item @code{\$}
+@tab A dollar-sign character @samp{$}. Unescaped @samp{$} characters
+are used to expand environment variables (see 'variables' section below).
+
+@item @code{\_}
+@tab Inside double-quotes, replaced with a single space character.
+Outside quotes, treated as an argument separator. @samp{\_} can be used
+to avoid space characters in a shebang line (see examples below).
+
+@item @code{\"}
+@tab A double-quote character.
+
+@item @code{\'}
+@tab A single-quote character.
+This escape sequence works inside single-quoted strings.
+
+@item @code{\\}
+@tab A backslash character.
+This escape sequence works inside single-quoted strings.
+
+@end multitable
+
+The following @command{awk} script will use tab character as input and output
+field separator (instead of spaces and tabs):
+
+@example
+$ cat tabs.awk
+#!/usr/bin/env -S awk -v FS="\t" -v OFS="\t" -f
+...
+@end example
+
+@unnumberedsubsubsec Comments
+
+The escape sequence @samp{\c} (used outside single/double quotes)
+causes @command{env} to ignore the rest of the string.
+
+The @samp{#} character causes @command{env} to ignore the rest of
+the string when it appears as the first character of an argument.
+Use @samp{\#} to reverse this behavior.
+
+@example
+$ env -S'printf %s\n A B C'
+A
+B
+C
+
+$ env -S'printf %s\n A# B C'
+A#
+B
+C
+
+$ env -S'printf %s\n A #B C'
+A
+
+$ env -S'printf %s\n A \#B C'
+A
+#B
+C
+
+$ env -S'printf %s\n A\cB C'
+A
+@end example
+
+NOTE: The above examples use single quotes as they are executed
+on the command-line.
+
+
+
+@unnumberedsubsubsec Environment variable expansion
+
+The pattern @samp{$@{VARNAME@}} is used to substitute a value from
+the environment variable. The pattern must include the curly braces
+(@samp{@{},@samp{@}}). Without them @command{env} will reject the string.
+Special shell variables (such as @samp{$@@}, @samp{$*}, @samp{$$}) are
+not supported.
+
+If the environment variable is empty or not set, the pattern will be replaced
+by an empty string. The value of @samp{$@{VARNAME@}} will be that of
+the executed @command{env}, before any modifications using
+@option{-i}/@option{--ignore-environment}/@option{-u}/@option{--unset} or
+setting new values using @samp{VAR=VALUE}.
+
+The following python script prepends @file{/opt/custom/modules} to the python
+module search path environment variable (@samp{PYTHONPATH}):
+
+@example
+$ cat custom.py
+#!/usr/bin/env -S PYTHONPATH=/opt/custom/modules/:$@{PYTHONPATH@} python
+print "hello"
+...
+@end example
+
+The expansion of @samp{$@{PYTHONPATH@}} is performed by @command{env},
+not by a shell. If the curly braces are omitted, @command{env} will fail:
+
+@example
+$ cat custom.py
+#!/usr/bin/env -S PYTHONPATH=/opt/custom/modules/:$PYTHONPATH python
+print "hello"
+...
+
+$ chmod a+x custom.py
+$ custom.py
+/usr/bin/env: only $@{VARNAME@} expansion is supported, error at: $PYTHONPATH @c
+python
+@end example
+
+Environment variable expansion happens before clearing the environment
+(with @option{-i}) or unsetting specific variables (with @option{-u}):
+
+@example
+$ env -S'-i OLDUSER=$@{USER@} env'
+OLDUSER=gordon
+@end example
+
+Use @option{-v} to diagnose the operations step-by-step:
+
+@example
+$ env -vS'-i OLDUSER=$@{USER@} env'
+expanding $@{USER@} into 'gordon'
+split -S:  '-i OLDUSER=$@{USER@} env'
+ into:    '-i'
+     &    'OLDUSER=gordon'
+     &    'env'
+cleaning environ
+setenv:   OLDUSER=gordon
+executing: env
+   arg[0]= 'env'
+OLDUSER=gordon
+@end example
+
+
+
+@node nice invocation
+@section @command{nice}: Run a command with modified niceness
+
+@pindex nice
+@cindex niceness
+@cindex scheduling, affecting
+@cindex appropriate privileges
+
+@command{nice} prints a process's @dfn{niceness}, or runs
+a command with modified niceness.  @dfn{niceness} affects how
+favorably the process is scheduled in the system.
+Synopsis:
+
+@example
+nice [@var{option}]@dots{} [@var{command} [@var{arg}]@dots{}]
+@end example
+
+If no arguments are given, @command{nice} prints the current niceness.
+Otherwise, @command{nice} runs the given @var{command} with its
+niceness adjusted.  By default, its niceness is incremented by 10.
+
+Niceness values range at least from @minus{}20 (process has high priority
+and gets more resources, thus slowing down other processes) through 19
+(process has lower priority and runs slowly itself, but has less impact
+on the speed of other running processes).  Some systems
+may have a wider range of niceness values; conversely, other systems may
+enforce more restrictive limits.  An attempt to set the niceness
+outside the supported range is treated as an attempt to use the
+minimum or maximum supported value.
+
+A niceness should not be confused with a scheduling priority, which
+lets applications determine the order in which threads are scheduled
+to run.  Unlike a priority, a niceness is merely advice to the
+scheduler, which the scheduler is free to ignore.  Also, as a point of
+terminology, POSIX defines the behavior of @command{nice} in
+terms of a @dfn{nice value}, which is the non-negative difference
+between a niceness and the minimum niceness.  Though @command{nice}
+conforms to POSIX, its documentation and diagnostics use the
+term ``niceness'' for compatibility with historical practice.
+
+@var{command} must not be a special built-in utility (@pxref{Special
+built-in utilities}).
+
+@mayConflictWithShellBuiltIn{nice}
+
+Note to change the @dfn{niceness} of an existing process,
+one needs to use the @command{renice} command.
+
+The program accepts the following option.  Also see @ref{Common options}.
+Options must precede operands.
+
+@table @samp
+@item -n @var{adjustment}
+@itemx --adjustment=@var{adjustment}
+@opindex -n
+@opindex --adjustment
+Add @var{adjustment} instead of 10 to the command's niceness.  If
+@var{adjustment} is negative and you lack appropriate privileges,
+@command{nice} issues a warning but otherwise acts as if you specified
+a zero adjustment.
+
+For compatibility @command{nice} also supports an obsolete
+option syntax @option{-@var{adjustment}}.  New scripts should use
+@option{-n @var{adjustment}} instead.
+
+@end table
+
+@command{nice} is installed only on systems that have the POSIX
+@code{setpriority} function, so portable scripts should not rely on
+its existence on non-POSIX platforms.
+
+@cindex exit status of @command{nice}
+Exit status:
+
+@display
+0   if no @var{command} is specified and the niceness is output
+125 if @command{nice} itself fails
+126 if @var{command} is found but cannot be invoked
+127 if @var{command} cannot be found
+the exit status of @var{command} otherwise
+@end display
+
+It is sometimes useful to run a non-interactive program with reduced niceness.
+
+@example
+$ nice factor 4611686018427387903
+@end example
+
+Since @command{nice} prints the current niceness,
+you can invoke it through itself to demonstrate how it works.
+
+The default behavior is to increase the niceness by @samp{10}:
+
+@example
+$ nice
+0
+$ nice nice
+10
+$ nice -n 10 nice
+10
+@end example
+
+The @var{adjustment} is relative to the current niceness.  In the
+next example, the first @command{nice} invocation runs the second one
+with niceness 10, and it in turn runs the final one with a niceness
+that is 3 more:
+
+@example
+$ nice nice -n 3 nice
+13
+@end example
+
+Specifying a niceness larger than the supported range
+is the same as specifying the maximum supported value:
+
+@example
+$ nice -n 10000000000 nice
+19
+@end example
+
+Only a privileged user may run a process with lower niceness:
+
+@example
+$ nice -n -1 nice
+nice: cannot set niceness: Permission denied
+0
+$ sudo nice -n -1 nice
+-1
+@end example
+
+
+@node nohup invocation
+@section @command{nohup}: Run a command immune to hangups
+
+@pindex nohup
+@cindex hangups, immunity to
+@cindex immunity to hangups
+@cindex logging out and continuing to run
+
+@flindex nohup.out
+@command{nohup} runs the given @var{command} with hangup signals ignored,
+so that the command can continue running in the background after you log
+out.  Synopsis:
+
+@example
+nohup @var{command} [@var{arg}]@dots{}
+@end example
+
+If standard input is a terminal, redirect it so that terminal sessions
+do not mistakenly consider the terminal to be used by the command.
+Make the substitute file descriptor unreadable, so that commands that
+mistakenly attempt to read from standard input can report an error.
+This redirection is a GNU extension; programs intended to be portable
+to non-GNU hosts can use @samp{nohup @var{command} [@var{arg}]@dots{}
+0>/dev/null} instead.
+
+@flindex nohup.out
+If standard output is a terminal, the command's standard output is appended
+to the file @file{nohup.out}; if that cannot be written to, it is appended
+to the file @file{$HOME/nohup.out}; and if that cannot be written to, the
+command is not run.
+Any @file{nohup.out} or @file{$HOME/nohup.out} file created by
+@command{nohup} is made readable and writable only to the user,
+regardless of the current umask settings.
+
+If standard error is a terminal, it is normally redirected to the same file
+descriptor as the (possibly-redirected) standard output.
+However, if standard output is closed, standard error terminal output
+is instead appended to the file @file{nohup.out} or
+@file{$HOME/nohup.out} as above.
+
+To capture the command's output to a file other than @file{nohup.out}
+you can redirect it.  For example, to capture the output of
+@command{make}:
+
+@example
+nohup make > make.log
+@end example
+
+@command{nohup} does not automatically put the command it runs in the
+background; you must do that explicitly, by ending the command line
+with an @samp{&}.  Also, @command{nohup} does not alter the
+niceness of @var{command}; use @command{nice} for that,
+e.g., @samp{nohup nice @var{command}}.
+
+@var{command} must not be a special built-in utility (@pxref{Special
+built-in utilities}).
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.  Options must precede operands.
+
+@cindex exit status of @command{nohup}
+Exit status:
+
+@display
+125 if @command{nohup} itself fails, and @env{POSIXLY_CORRECT} is not set
+126 if @var{command} is found but cannot be invoked
+127 if @var{command} cannot be found
+the exit status of @var{command} otherwise
+@end display
+
+If @env{POSIXLY_CORRECT} is set, internal failures give status 127
+instead of 125.
+
+
+@node stdbuf invocation
+@section @command{stdbuf}: Run a command with modified I/O stream buffering
+
+@pindex stdbuf
+@cindex standard streams, buffering
+@cindex line buffered
+
+@command{stdbuf} allows one to modify the buffering operations of the
+three standard I/O streams associated with a program.  Synopsis:
+
+@example
+stdbuf @var{option}@dots{} @var{command}
+@end example
+
+@var{command} must start with the name of a program that
+@enumerate
+@item
+uses the ISO C @code{FILE} streams for input/output (note the
+programs @command{dd} and @command{cat} don't do that),
+
+@item
+does not adjust the buffering of its standard streams (note the
+program @command{tee} is not in this category).
+@end enumerate
+
+Any additional @var{arg}s are passed as additional arguments to the
+@var{command}.
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item -i @var{mode}
+@itemx --input=@var{mode}
+@opindex -i
+@opindex --input
+Adjust the standard input stream buffering.
+
+@item -o @var{mode}
+@itemx --output=@var{mode}
+@opindex -o
+@opindex --output
+Adjust the standard output stream buffering.
+
+@item -e @var{mode}
+@itemx --error=@var{mode}
+@opindex -e
+@opindex --error
+Adjust the standard error stream buffering.
+
+@end table
+
+The @var{mode} can be specified as follows:
+
+@table @samp
+
+@item L
+Set the stream to line buffered mode.
+In this mode data is coalesced until a newline is output or
+input is read from any stream attached to a terminal device.
+This option is invalid with standard input.
+
+@item 0
+Disable buffering of the selected stream.
+In this mode, data is output immediately and only the
+amount of data requested is read from input.
+Note the difference in function for input and output.
+Disabling buffering for input will not influence the responsiveness
+or blocking behavior of the stream input functions.
+For example @code{fread} will still block until @code{EOF} or error,
+even if the underlying @code{read} returns less data than requested.
+
+@item @var{size}
+Specify the size of the buffer to use in fully buffered mode.
+@multiplierSuffixesNoBlocks{size}
+
+@end table
+
+@command{stdbuf} is installed only on platforms that use the
+Executable and Linkable Format (ELF) and support the
+@code{constructor} attribute, so portable scripts should not rely on
+its existence.
+
+@cindex exit status of @command{stdbuf}
+Exit status:
+
+@display
+125 if @command{stdbuf} itself fails
+126 if @var{command} is found but cannot be invoked
+127 if @var{command} cannot be found
+the exit status of @var{command} otherwise
+@end display
+
+
+@node timeout invocation
+@section @command{timeout}: Run a command with a time limit
+
+@pindex timeout
+@cindex time limit
+@cindex run commands with bounded time
+
+@command{timeout} runs the given @var{command} and kills it if it is
+still running after the specified time interval.  Synopsis:
+
+@example
+timeout [@var{option}] @var{duration} @var{command} [@var{arg}]@dots{}
+@end example
+
+@var{command} must not be a special built-in utility (@pxref{Special
+built-in utilities}).
+
+The program accepts the following options.  Also see @ref{Common options}.
+Options must precede operands.
+
+@table @samp
+@item --preserve-status
+@opindex --preserve-status
+Return the exit status of the managed @var{command} on timeout, rather than
+a specific exit status indicating a timeout.  This is useful if the
+managed @var{command} supports running for an indeterminate amount of time.
+
+@item --foreground
+@opindex --foreground
+Don't create a separate background program group, so that
+the managed @var{command} can use the foreground TTY normally.
+This is needed to support timing out commands not started
+directly from an interactive shell, in two situations.
+@enumerate
+@item
+@var{command} is interactive and needs to read from the terminal for example
+@item
+the user wants to support sending signals directly to @var{command}
+from the terminal (like Ctrl-C for example)
+@end enumerate
+
+Note in this mode of operation, any children of @var{command}
+will not be timed out.  Also SIGCONT will not be sent to @var{command},
+as it's generally not needed with foreground processes, and can
+cause intermittent signal delivery issues with programs that are monitors
+themselves (like GDB for example).
+
+@item -k @var{duration}
+@itemx --kill-after=@var{duration}
+@opindex -k
+@opindex --kill-after
+Ensure the monitored @var{command} is killed by also sending a @samp{KILL}
+signal, after the specified @var{duration}.  Without this option, if the
+selected signal proves not to be fatal, @command{timeout} does not kill
+the @var{command}.
+
+@item -s @var{signal}
+@itemx --signal=@var{signal}
+@opindex -s
+@opindex --signal
+Send this @var{signal} to @var{command} on timeout, rather than the
+default @samp{TERM} signal.  @var{signal} may be a name like @samp{HUP}
+or a number.  @xref{Signal specifications}.
+
+@item -v
+@itemx --verbose
+@opindex -v
+@opindex --verbose
+Diagnose to stderr, any signal sent upon timeout.
+@end table
+
+@cindex time units
+@var{duration} is a floating point number in either the current or the
+C locale (@pxref{Floating point}) followed by an optional unit:
+@display
+@samp{s} for seconds (the default)
+@samp{m} for minutes
+@samp{h} for hours
+@samp{d} for days
+@end display
+A duration of 0 disables the associated timeout.
+Note that the actual timeout duration is dependent on system conditions,
+which should be especially considered when specifying sub-second timeouts.
+
+@cindex exit status of @command{timeout}
+Exit status:
+
+@display
+124 if @var{command} times out
+125 if @command{timeout} itself fails
+126 if @var{command} is found but cannot be invoked
+127 if @var{command} cannot be found
+137 if @var{command} is sent the KILL(9) signal (128+9)
+the exit status of @var{command} otherwise
+@end display
+
+
+@node Process control
+@chapter Process control
+
+@cindex processes, commands for controlling
+@cindex commands for controlling processes
+
+@menu
+* kill invocation::             Sending a signal to processes.
+@end menu
+
+
+@node kill invocation
+@section @command{kill}: Send a signal to processes
+
+@pindex kill
+@cindex send a signal to processes
+
+The @command{kill} command sends a signal to processes, causing them
+to terminate or otherwise act upon receiving the signal in some way.
+Alternatively, it lists information about signals.  Synopses:
+
+@example
+kill [-s @var{signal} | --signal @var{signal} | -@var{signal}] @var{pid}@dots{}
+kill [-l | --list | -t | --table] [@var{signal}]@dots{}
+@end example
+
+@mayConflictWithShellBuiltIn{kill}
+
+The first form of the @command{kill} command sends a signal to all
+@var{pid} arguments.  The default signal to send if none is specified
+is @samp{TERM}@.  The special signal number @samp{0} does not denote a
+valid signal, but can be used to test whether the @var{pid} arguments
+specify processes to which a signal could be sent.
+
+If @var{pid} is positive, the signal is sent to the process with the
+process ID @var{pid}.  If @var{pid} is zero, the signal is sent to all
+processes in the process group of the current process.  If @var{pid}
+is @minus{}1, the signal is sent to all processes for which the user has
+permission to send a signal.  If @var{pid} is less than @minus{}1, the signal
+is sent to all processes in the process group that equals the absolute
+value of @var{pid}.
+
+If @var{pid} is not positive, a system-dependent set of system
+processes is excluded from the list of processes to which the signal
+is sent.
+
+If a negative @var{pid} argument is desired as the first one, it
+should be preceded by @option{--}.  However, as a common extension to
+POSIX, @option{--} is not required with @samp{kill
+-@var{signal} -@var{pid}}.  The following commands are equivalent:
+
+@example
+kill -15 -1
+kill -TERM -1
+kill -s TERM -- -1
+kill -- -1
+@end example
+
+The first form of the @command{kill} command succeeds if every @var{pid}
+argument specifies at least one process that the signal was sent to.
+
+The second form of the @command{kill} command lists signal information.
+Either the @option{-l} or @option{--list} option, or the @option{-t}
+or @option{--table} option must be specified.  Without any
+@var{signal} argument, all supported signals are listed.  The output
+of @option{-l} or @option{--list} is a list of the signal names, one
+per line; if @var{signal} is already a name, the signal number is
+printed instead.  The output of @option{-t} or @option{--table} is a
+table of signal numbers, names, and descriptions.  This form of the
+@command{kill} command succeeds if all @var{signal} arguments are valid
+and if there is no output error.
+
+The @command{kill} command also supports the @option{--help} and
+@option{--version} options.  @xref{Common options}.
+
+A @var{signal} may be a signal name like @samp{HUP}, or a signal
+number like @samp{1}, or an exit status of a process terminated by the
+signal.  A signal name can be given in canonical form or prefixed by
+@samp{SIG}@.  The case of the letters is ignored, except for the
+@option{-@var{signal}} option which must use upper case to avoid
+ambiguity with lower case option letters.
+@xref{Signal specifications}, for a list of supported
+signal names and numbers.
+
+@node Delaying
+@chapter Delaying
+
+@cindex delaying commands
+@cindex commands for delaying
+
+@c Perhaps @command{wait} or other commands should be described here also?
+
+@menu
+* sleep invocation::            Delay for a specified time.
+@end menu
+
+
+@node sleep invocation
+@section @command{sleep}: Delay for a specified time
+
+@pindex sleep
+@cindex delay for a specified time
+
+@command{sleep} pauses for an amount of time specified by the sum of
+the values of the command line arguments.
+Synopsis:
+
+@example
+sleep @var{number}[smhd]@dots{}
+@end example
+
+@cindex time units
+Each argument is a non-negative number followed by an optional unit; the default
+is seconds.  The units are:
+
+@table @samp
+@item s
+seconds
+@item m
+minutes
+@item h
+hours
+@item d
+days
+@end table
+
+Although portable POSIX scripts must give @command{sleep} a single
+non-negative integer argument without a suffix, GNU @command{sleep}
+also accepts two or more arguments, unit suffixes, and floating-point
+numbers in either the current or the C locale.  @xref{Floating point}.
+
+For instance, the following could be used to @command{sleep} for
+1 second, 234 milli-, 567 micro- and 890 nanoseconds:
+
+@example
+sleep 1234e-3 567.89e-6
+@end example
+
+The only options are @option{--help} and @option{--version}.  @xref{Common
+options}.
+
+@c sleep is a shell built-in at least with Solaris 11's /bin/sh
+@mayConflictWithShellBuiltIn{sleep}
+
+@exitstatus
+
+
+@node Numeric operations
+@chapter Numeric operations
+
+@cindex numeric operations
+These programs do numerically-related operations.
+
+@menu
+* factor invocation::              Show factors of numbers.
+* numfmt invocation::              Reformat numbers.
+* seq invocation::                 Print sequences of numbers.
+@end menu
+
+
+@node factor invocation
+@section @command{factor}: Print prime factors
+
+@pindex factor
+@cindex prime factors
+
+@command{factor} prints prime factors.  Synopses:
+
+@example
+factor [@var{number}]@dots{}
+factor @var{option}
+@end example
+
+If no @var{number} is specified on the command line, @command{factor} reads
+numbers from standard input, delimited by newlines, tabs, or spaces.
+
+The @command{factor} command supports only a small number of options:
+
+@table @samp
+@item --help
+Print a short help on standard output, then exit without further
+processing.
+
+@item --version
+Print the program version on standard output, then exit without further
+processing.
+@end table
+
+Factoring the product of the eighth and ninth Mersenne primes
+takes about 30 milliseconds of CPU time on a 2.2 GHz Athlon.
+
+@example
+M8=$(echo 2^31-1|bc)
+M9=$(echo 2^61-1|bc)
+n=$(echo "$M8 * $M9" | bc)
+/usr/bin/time -f %U factor $n
+4951760154835678088235319297: 2147483647 2305843009213693951
+0.03
+@end example
+
+Similarly, factoring the eighth Fermat number @math{2^{256}+1} takes
+about 20 seconds on the same machine.
+
+Factoring large numbers is, in general, hard.  The Pollard-Brent rho
+algorithm used by @command{factor} is particularly effective for
+numbers with relatively small factors.  If you wish to factor large
+numbers which do not have small factors (for example, numbers which
+are the product of two large primes), other methods are far better.
+
+If @command{factor} is built without using GNU MP, only
+single-precision arithmetic is available, and so large numbers
+(typically @math{2^{128}} and above) will not be supported.
+The single-precision code uses an algorithm which is designed
+for factoring smaller numbers.
+
+@exitstatus
+
+
+@node numfmt invocation
+@section @command{numfmt}: Reformat numbers
+
+@pindex numfmt
+
+@command{numfmt} reads numbers in various representations and reformats them
+as requested.  The most common usage is converting numbers to/from @emph{human}
+representation (e.g. @samp{4G} @expansion{} @samp{4,000,000,000}).
+
+@example
+numfmt [@var{option}]@dots{} [@var{number}]
+@end example
+
+@command{numfmt} converts each @var{number} on the command-line according to the
+specified options (see below).  If no @var{number}s are given, it reads numbers
+from standard input.  @command{numfmt} can optionally extract numbers from
+specific columns, maintaining proper line padding and alignment.
+
+@exitstatus
+
+See @option{--invalid} for additional information regarding exit status.
+
+@subsection General options
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+
+@item --debug
+@opindex --debug
+Print (to standard error) warning messages about possible erroneous usage.
+
+@item -d @var{d}
+@itemx --delimiter=@var{d}
+@opindex -d
+@opindex --delimiter
+Use the character @var{d} as input field separator (default: whitespace).
+@emph{Note}: Using non-default delimiter turns off automatic padding.
+
+@item --field=@var{fields}
+@opindex --field
+Convert the number in input field @var{fields} (default: 1).
+@var{fields} supports @command{cut} style field ranges:
+
+@example
+N    N'th field, counted from 1
+N-   from N'th field, to end of line
+N-M  from N'th to M'th field (inclusive)
+-M   from first to M'th field (inclusive)
+-    all fields
+@end example
+
+
+@item --format=@var{format}
+@opindex --format
+Use printf-style floating FORMAT string.  The @var{format} string must contain
+one @samp{%f} directive, optionally with @samp{'}, @samp{-}, @samp{0}, width
+or precision modifiers.  The @samp{'} modifier will enable @option{--grouping},
+the @samp{-} modifier will enable left-aligned @option{--padding} and the width
+modifier will enable right-aligned @option{--padding}.  The @samp{0} width
+modifier (without the @samp{-} modifier) will generate leading zeros on the
+number, up to the specified width.  A precision specification like @samp{%.1f}
+will override the precision determined from the input data or set due to
+@option{--to} option auto scaling.
+
+@item --from=@var{unit}
+@opindex --from
+Auto-scales input numbers according to @var{unit}.  See UNITS below.
+The default is no scaling, meaning suffixes (e.g. @samp{M}, @samp{G}) will
+trigger an error.
+
+@item --from-unit=@var{n}
+@opindex --from-unit
+Specify the input unit size (instead of the default 1).  Use this option when
+the input numbers represent other units (e.g. if the input number @samp{10}
+represents 10 units of 512 bytes, use @samp{--from-unit=512}).
+Suffixes are handled as with @samp{--from=auto}.
+
+@item --grouping
+@opindex --grouping
+Group digits in output numbers according to the current locale's grouping rules
+(e.g @emph{Thousands Separator} character, commonly @samp{.} (dot) or @samp{,}
+comma).  This option has no effect in @samp{POSIX/C} locale.
+
+@item --header[=@var{n}]
+@opindex --header
+@opindex --header=N
+Print the first @var{n} (default: 1) lines without any conversion.
+
+@item --invalid=@var{mode}
+@opindex --invalid
+The default action on input errors is to exit immediately with status code 2.
+@option{--invalid=@samp{abort}} explicitly specifies this default mode.
+With a @var{mode} of @samp{fail}, print a warning for @emph{each} conversion
+error, and exit with status 2.  With a @var{mode} of @samp{warn}, exit with
+status 0, even in the presence of conversion errors, and with a @var{mode} of
+@samp{ignore} do not even print diagnostics.
+
+@item --padding=@var{n}
+@opindex --padding
+Pad the output numbers to @var{n} characters, by adding spaces.  If @var{n} is
+a positive number, numbers will be right-aligned.  If @var{n} is a negative
+number, numbers will be left-aligned.  By default, numbers are automatically
+aligned based on the input line's width (only with the default delimiter).
+
+@item --round=@var{method}
+@opindex --round
+@opindex --round=up
+@opindex --round=down
+@opindex --round=from-zero
+@opindex --round=towards-zero
+@opindex --round=nearest
+When converting number representations, round the number according to
+@var{method}, which can be @samp{up}, @samp{down},
+@samp{from-zero} (the default), @samp{towards-zero}, @samp{nearest}.
+
+@item --suffix=@var{suffix}
+@opindex --suffix
+Add @samp{SUFFIX} to the output numbers, and accept optional @samp{SUFFIX} in
+input numbers.
+
+@item --to=@var{unit}
+@opindex --to
+Auto-scales output numbers according to @var{unit}.  See @emph{Units} below.
+The default is no scaling, meaning all the digits of the number are printed.
+
+@item --to-unit=@var{n}
+@opindex --to-unit
+Specify the output unit size (instead of the default 1).  Use this option when
+the output numbers represent other units (e.g. to represent @samp{4,000,000}
+bytes in blocks of 1KB, use @samp{--to=si --to-unit=1000}).
+Suffixes are handled as with @samp{--from=auto}.
+
+@optZeroTerminated
+@newlineFieldSeparator
+
+@end table
+
+@subsection Possible @var{unit}s:
+
+The following are the possible @var{unit} options with @option{--from=UNITS} and
+@option{--to=UNITS}:
+
+@table @var
+
+@item none
+No scaling is performed.  For input numbers, no suffixes are accepted, and any
+trailing characters following the number will trigger an error.  For output
+numbers, all digits of the numbers will be printed.
+
+@item si
+Auto-scale numbers according to the @emph{International System of Units (SI)}
+standard.
+For input numbers, accept one of the following suffixes.
+For output numbers, values larger than 1000 will be rounded, and printed with
+one of the following suffixes:
+
+@example
+@samp{K}  =>  @math{1000^1 = 10^3} (Kilo)
+@samp{M}  =>  @math{1000^2 = 10^6} (Mega)
+@samp{G}  =>  @math{1000^3 = 10^9} (Giga)
+@samp{T}  =>  @math{1000^4 = 10^{12}} (Tera)
+@samp{P}  =>  @math{1000^5 = 10^{15}} (Peta)
+@samp{E}  =>  @math{1000^6 = 10^{18}} (Exa)
+@samp{Z}  =>  @math{1000^7 = 10^{21}} (Zetta)
+@samp{Y}  =>  @math{1000^8 = 10^{24}} (Yotta)
+@end example
+
+@item iec
+Auto-scale numbers according to the @emph{International Electrotechnical
+Commission (IEC)} standard.
+For input numbers, accept one of the following suffixes.
+For output numbers, values larger than 1024 will be rounded, and printed with
+one of the following suffixes:
+
+@example
+@samp{K}  =>  @math{1024^1 = 2^{10}} (Kibi)
+@samp{M}  =>  @math{1024^2 = 2^{20}} (Mebi)
+@samp{G}  =>  @math{1024^3 = 2^{30}} (Gibi)
+@samp{T}  =>  @math{1024^4 = 2^{40}} (Tebi)
+@samp{P}  =>  @math{1024^5 = 2^{50}} (Pebi)
+@samp{E}  =>  @math{1024^6 = 2^{60}} (Exbi)
+@samp{Z}  =>  @math{1024^7 = 2^{70}} (Zebi)
+@samp{Y}  =>  @math{1024^8 = 2^{80}} (Yobi)
+@end example
+
+The @option{iec} option uses a single letter suffix (e.g. @samp{G}), which is
+not fully standard, as the @emph{iec} standard recommends a two-letter symbol
+(e.g @samp{Gi}) - but in practice, this method common.  Compare with
+the @option{iec-i} option.
+
+@item iec-i
+Auto-scale numbers according to the @emph{International Electrotechnical
+Commission (IEC)} standard.
+For input numbers, accept one of the following suffixes.
+For output numbers, values larger than 1024 will be rounded, and printed with
+one of the following suffixes:
+
+@example
+@samp{Ki}  =>  @math{1024^1 = 2^{10}} (Kibi)
+@samp{Mi}  =>  @math{1024^2 = 2^{20}} (Mebi)
+@samp{Gi}  =>  @math{1024^3 = 2^{30}} (Gibi)
+@samp{Ti}  =>  @math{1024^4 = 2^{40}} (Tebi)
+@samp{Pi}  =>  @math{1024^5 = 2^{50}} (Pebi)
+@samp{Ei}  =>  @math{1024^6 = 2^{60}} (Exbi)
+@samp{Zi}  =>  @math{1024^7 = 2^{70}} (Zebi)
+@samp{Yi}  =>  @math{1024^8 = 2^{80}} (Yobi)
+@end example
+
+The @option{iec-i} option uses a two-letter suffix symbol (e.g. @samp{Gi}),
+as the @emph{iec} standard recommends, but this is not always common in
+practice.  Compare with the @option{iec} option.
+
+@item auto
+@samp{auto} can only be used with @option{--from}.  With this method, numbers
+with @samp{K},@samp{M},@samp{G},@samp{T},@samp{P},@samp{E},@samp{Z},@samp{Y}
+suffixes are interpreted as @emph{SI} values, and numbers with @samp{Ki},
+@samp{Mi},@samp{Gi},@samp{Ti},@samp{Pi},@samp{Ei},@samp{Zi},@samp{Yi} suffixes
+are interpreted as @emph{IEC} values.
+
+@end table
+
+@subsection Examples of using @command{numfmt}
+
+Converting a single number from/to @emph{human} representation:
+@example
+$ numfmt --to=si 500000
+500K
+
+$ numfmt --to=iec 500000
+489K
+
+$ numfmt --to=iec-i 500000
+489Ki
+
+$ numfmt --from=si 1M
+1000000
+
+$ numfmt --from=iec 1M
+1048576
+
+# with '--from=auto', M=Mega, Mi=Mebi
+$ numfmt --from=auto 1M
+1000000
+$ numfmt --from=auto 1Mi
+1048576
+@end example
+
+Converting from @samp{SI} to @samp{IEC} scales (e.g. when a harddisk capacity is
+advertised as @samp{1TB}, while checking the drive's capacity gives lower
+values):
+
+@example
+$ numfmt --from=si --to=iec 1T
+932G
+@end example
+
+
+Converting a single field from an input file / piped input (these contrived
+examples are for demonstration purposes only, as both @command{ls} and
+@command{df} support the @option{--human-readable} option to
+output sizes in human-readable format):
+
+@example
+# Third field (file size) will be shown in SI representation
+$ ls -log | numfmt --field 3 --header --to=si | head -n4
+-rw-r--r--  1     94K Aug 23  2011 ABOUT-NLS
+-rw-r--r--  1    3.7K Jan  7 16:15 AUTHORS
+-rw-r--r--  1     36K Jun  1  2011 COPYING
+-rw-r--r--  1       0 Jan  7 15:15 ChangeLog
+
+# Second field (size) will be shown in IEC representation
+$ df --block-size=1 | numfmt --field 2 --header --to=iec | head -n4
+File system   1B-blocks        Used  Available Use% Mounted on
+rootfs             132G   104741408   26554036  80% /
+tmpfs              794M        7580     804960   1% /run/shm
+/dev/sdb1          694G   651424756   46074696  94% /home
+@end example
+
+
+Output can be tweaked using @option{--padding} or @option{--format}:
+
+@example
+# Pad to 10 characters, right-aligned
+$ du -s * | numfmt --to=si --padding=10
+      2.5K config.log
+       108 config.status
+      1.7K configure
+        20 configure.ac
+
+# Pad to 10 characters, left-aligned
+$ du -s * | numfmt --to=si --padding=-10
+2.5K       config.log
+108        config.status
+1.7K       configure
+20         configure.ac
+
+# Pad to 10 characters, left-aligned, using 'format'
+$ du -s * | numfmt --to=si --format="%10f"
+      2.5K config.log
+       108 config.status
+      1.7K configure
+        20 configure.ac
+
+# Pad to 10 characters, left-aligned, using 'format'
+$ du -s * | numfmt --to=si --padding="%-10f"
+2.5K       config.log
+108        config.status
+1.7K       configure
+20         configure.ac
+@end example
+
+With locales that support grouping digits, using @option{--grouping} or
+@option{--format} enables grouping.  In @samp{POSIX} locale, grouping is
+silently ignored:
+
+@example
+$ LC_ALL=C numfmt --from=iec --grouping 2G
+2147483648
+
+$ LC_ALL=en_US.utf8 numfmt --from=iec --grouping 2G
+2,147,483,648
+
+$ LC_ALL=ta_IN numfmt --from=iec --grouping 2G
+2,14,74,83,648
+
+$ LC_ALL=C ./src/numfmt --from=iec --format="==%'15f==" 2G
+==     2147483648==
+
+$ LC_ALL=en_US.utf8 ./src/numfmt --from=iec --format="==%'15f==" 2G
+==  2,147,483,648==
+
+$ LC_ALL=en_US.utf8 ./src/numfmt --from=iec --format="==%'-15f==" 2G
+==2,147,483,648  ==
+
+$ LC_ALL=ta_IN ./src/numfmt --from=iec --format="==%'15f==" 2G
+== 2,14,74,83,648==
+@end example
+
+
+@node seq invocation
+@section @command{seq}: Print numeric sequences
+
+@pindex seq
+@cindex numeric sequences
+@cindex sequence of numbers
+
+@command{seq} prints a sequence of numbers to standard output.  Synopses:
+
+@example
+seq [@var{option}]@dots{} @var{last}
+seq [@var{option}]@dots{} @var{first} @var{last}
+seq [@var{option}]@dots{} @var{first} @var{increment} @var{last}
+@end example
+
+@command{seq} prints the numbers from @var{first} to @var{last} by
+@var{increment}.  By default, each number is printed on a separate line.
+When @var{increment} is not specified, it defaults to @samp{1},
+even when @var{first} is larger than @var{last}.
+@var{first} also defaults to @samp{1}.  So @code{seq 1} prints
+@samp{1}, but @code{seq 0} and @code{seq 10 5} produce no output.
+The sequence of numbers ends when the sum of the current number and
+@var{increment} would become greater than @var{last},
+so @code{seq 1 10 10} only produces @samp{1}.
+@var{increment} must not be @samp{0}; use the tool @command{yes} to get
+repeated output of a constant number.
+@var{first}, @var{increment} and @var{last} must not be @code{NaN}.
+Floating-point numbers may be specified in either the current or
+the C locale.  @xref{Floating point}.
+
+The program accepts the following options.  Also see @ref{Common options}.
+Options must precede operands.
+
+@table @samp
+@item -f @var{format}
+@itemx --format=@var{format}
+@opindex -f
+@opindex --format
+@cindex formatting of numbers in @command{seq}
+Print all numbers using @var{format}.
+@var{format} must contain exactly one of the @samp{printf}-style
+floating point conversion specifications @samp{%a}, @samp{%e},
+@samp{%f}, @samp{%g}, @samp{%A}, @samp{%E}, @samp{%F}, @samp{%G}@.
+The @samp{%} may be followed by zero or more flags taken from the set
+@samp{-+#0 '}, then an optional width containing one or more digits,
+then an optional precision consisting of a @samp{.} followed by zero
+or more digits.  @var{format} may also contain any number of @samp{%%}
+conversion specifications.  All conversion specifications have the
+same meaning as with @samp{printf}.
+
+The default format is derived from @var{first}, @var{step}, and
+@var{last}.  If these all use a fixed point decimal representation,
+the default format is @samp{%.@var{p}f}, where @var{p} is the minimum
+precision that can represent the output numbers exactly.  Otherwise,
+the default format is @samp{%g}.
+
+@item -s @var{string}
+@itemx --separator=@var{string}
+@opindex -s
+@opindex --separator
+@cindex separator for numbers in @command{seq}
+Separate numbers with @var{string}; default is a newline.
+The output always terminates with a newline.
+
+@item -w
+@itemx --equal-width
+@opindex -w
+@opindex --equal-width
+Print all numbers with the same width, by padding with leading zeros.
+@var{first}, @var{step}, and @var{last} should all use a fixed point
+decimal representation.
+(To have other kinds of padding, use @option{--format}).
+
+@end table
+
+You can get finer-grained control over output with @option{-f}:
+
+@example
+$ seq -f '(%9.2E)' -9e5 1.1e6 1.3e6
+(-9.00E+05)
+( 2.00E+05)
+( 1.30E+06)
+@end example
+
+If you want hexadecimal integer output, you can use @command{printf}
+to perform the conversion:
+
+@example
+$ printf '%x\n' $(seq 1048575 1024 1050623)
+fffff
+1003ff
+1007ff
+@end example
+
+For very long lists of numbers, use xargs to avoid
+system limitations on the length of an argument list:
+
+@example
+$ seq 1000000 | xargs printf '%x\n' | tail -n 3
+f423e
+f423f
+f4240
+@end example
+
+To generate octal output, use the printf @code{%o} format instead
+of @code{%x}.
+
+On most systems, seq can produce whole-number output for values up to
+at least @math{2^{53}}.  Larger integers are approximated.  The details
+differ depending on your floating-point implementation.
+@xref{Floating point}.  A common
+case is that @command{seq} works with integers through @math{2^{64}},
+and larger integers may not be numerically correct:
+
+@example
+$ seq 50000000000000000000 2 50000000000000000004
+50000000000000000000
+50000000000000000000
+50000000000000000004
+@end example
+
+However, note that when limited to non-negative whole numbers,
+an increment of 1 and no format-specifying option, seq can print
+arbitrarily large numbers.
+
+Be careful when using @command{seq} with outlandish values: otherwise
+you may see surprising results, as @command{seq} uses floating point
+internally.  For example, on the x86 platform, where the internal
+representation uses a 64-bit fraction, the command:
+
+@example
+seq 1 0.0000000000000000001 1.0000000000000000009
+@end example
+
+outputs 1.0000000000000000007 twice and skips 1.0000000000000000008.
+
+@exitstatus
+
+
+@node File permissions
+@chapter File permissions
+@include perm.texi
+
+
+@node File timestamps
+@chapter File timestamps
+
+@cindex atime
+@cindex birthtime
+@cindex ctime
+@cindex mtime
+Standard POSIX files have three timestamps: the access timestamp
+(atime) of the last read, the modification timestamp (mtime) of the
+last write, and the status change timestamp (ctime) of the last change
+to the file's meta-information.  Some file systems support a
+fourth time: the birth timestamp (birthtime) of when the file was
+created; by definition, birthtime never changes.
+
+One common example of a ctime change is when the permissions of a file
+change.  Changing the permissions doesn't access the file, so atime
+doesn't change, nor does it modify the file, so the mtime doesn't
+change.  Yet, something about the file itself has changed, and this
+must be noted somewhere.  This is the job of the ctime field.  This is
+necessary, so that, for example, a backup program can make a fresh
+copy of the file, including the new permissions value.  Another
+operation that modifies a file's ctime without affecting the others is
+renaming.
+
+Naively, a file's atime, mtime, and ctime are set to the current time
+whenever you read, write, or change the attributes of the file
+respectively, and searching a directory counts as reading it.  A
+file's atime and mtime can also be set directly, via the
+@command{touch} command (@pxref{touch invocation}).  In practice,
+though, timestamps are not updated quite that way.
+
+For efficiency reasons, many systems are lazy about updating atimes:
+when a program accesses a file, they may delay updating the file's
+atime, or may not update the file's atime if the file has been
+accessed recently, or may not update the atime at all.  Similar
+laziness, though typically not quite so extreme, applies to mtimes and
+ctimes.
+
+Some systems emulate timestamps instead of supporting them directly,
+and these emulations may disagree with the naive interpretation.  For
+example, a system may fake an atime or ctime by using the mtime.
+
+@cindex clock skew
+The determination of what time is ``current'' depends on the
+platform.  Platforms with network file systems often use different
+clocks for the operating system and for file systems; because
+updates typically uses file systems' clocks by default, clock
+skew can cause the resulting file timestamps to appear to be in a
+program's ``future'' or ``past''.
+
+@cindex file timestamp resolution
+When the system updates a file timestamp to a desired time @var{t}
+(which is either the current time, or a time specified via the
+@command{touch} command), there are several reasons the file's
+timestamp may be set to a value that differs from @var{t}.  First,
+@var{t} may have a higher resolution than supported.  Second, a file
+system may use different resolutions for different types of times.
+Third, file timestamps may use a different resolution than operating
+system timestamps.  Fourth, the operating system primitives used to
+update timestamps may employ yet a different resolution.  For example,
+in theory a file system might use 10-microsecond resolution for access
+timestamp and 100-nanosecond resolution for modification timestamp, and the
+operating system might use nanosecond resolution for the current time
+and microsecond resolution for the primitive that @command{touch} uses
+to set a file's timestamp to an arbitrary value.
+
+
+@include parse-datetime.texi
+
+@include sort-version.texi
+
+@c              What's GNU?
+@c              Arnold Robbins
+@node Opening the software toolbox
+@chapter Opening the Software Toolbox
+
+An earlier version of this chapter appeared in
+@uref{https://www.linuxjournal.com/article.php?sid=2762, the
+@cite{What's GNU@?} column of the June 1994 @cite{Linux Journal}}.
+It was written by Arnold Robbins.
+
+@menu
+* Toolbox introduction::        Toolbox introduction
+* I/O redirection::             I/O redirection
+* The who command::             The @command{who} command
+* The cut command::             The @command{cut} command
+* The sort command::            The @command{sort} command
+* The uniq command::            The @command{uniq} command
+* Putting the tools together::  Putting the tools together
+@end menu
+
+
+@node Toolbox introduction
+@unnumberedsec Toolbox Introduction
+
+This month's column is only peripherally related to the GNU Project, in
+that it describes a number of the GNU tools on your GNU/Linux system
+and how they
+might be used.  What it's really about is the ``Software Tools'' philosophy
+of program development and usage.
+
+The software tools philosophy was an important and integral concept
+in the initial design and development of Unix (of which Linux and GNU are
+essentially clones).  Unfortunately, in the modern day press of
+Internetworking and flashy GUIs, it seems to have fallen by the
+wayside.  This is a shame, since it provides a powerful mental model
+for solving many kinds of problems.
+
+Many people carry a Swiss Army knife around in their pants pockets (or
+purse).  A Swiss Army knife is a handy tool to have: it has several knife
+blades, a screwdriver, tweezers, toothpick, nail file, corkscrew, and perhaps
+a number of other things on it.  For the everyday, small miscellaneous jobs
+where you need a simple, general purpose tool, it's just the thing.
+
+On the other hand, an experienced carpenter doesn't build a house using
+a Swiss Army knife.  Instead, he has a toolbox chock full of specialized
+tools---a saw, a hammer, a screwdriver, a plane, and so on.  And he knows
+exactly when and where to use each tool; you won't catch him hammering nails
+with the handle of his screwdriver.
+
+The Unix developers at Bell Labs were all professional programmers and trained
+computer scientists.  They had found that while a one-size-fits-all program
+might appeal to a user because there's only one program to use, in practice
+such programs are
+
+@enumerate a
+@item
+difficult to write,
+
+@item
+difficult to maintain and
+debug, and
+
+@item
+difficult to extend to meet new situations.
+@end enumerate
+
+Instead, they felt that programs should be specialized tools.  In short, each
+program ``should do one thing well.''  No more and no less.  Such programs are
+simpler to design, write, and get right---they only do one thing.
+
+Furthermore, they found that with the right machinery for hooking programs
+together, that the whole was greater than the sum of the parts.  By combining
+several special purpose programs, you could accomplish a specific task
+that none of the programs was designed for, and accomplish it much more
+quickly and easily than if you had to write a special purpose program.
+We will see some (classic) examples of this further on in the column.
+(An important additional point was that, if necessary, take a detour
+and build any software tools you may need first, if you don't already
+have something appropriate in the toolbox.)
+
+@node I/O redirection
+@unnumberedsec I/O Redirection
+
+Hopefully, you are familiar with the basics of I/O redirection in the
+shell, in particular the concepts of ``standard input,'' ``standard output,''
+and ``standard error''.  Briefly, ``standard input'' is a data source, where
+data comes from.  A program should not need to either know or care if the
+data source is a disk file, a keyboard, a magnetic tape, or even a punched
+card reader.  Similarly, ``standard output'' is a data sink, where data goes
+to.  The program should neither know nor care where this might be.
+Programs that only read their standard input, do something to the data,
+and then send it on, are called @dfn{filters}, by analogy to filters in a
+water pipeline.
+
+With the Unix shell, it's very easy to set up data pipelines:
+
+@example
+program_to_create_data | filter1 | ... | filterN > final.pretty.data
+@end example
+
+We start out by creating the raw data; each filter applies some successive
+transformation to the data, until by the time it comes out of the pipeline,
+it is in the desired form.
+
+This is fine and good for standard input and standard output.  Where does the
+standard error come in to play?  Well, think about @command{filter1} in
+the pipeline above.  What happens if it encounters an error in the data it
+sees?  If it writes an error message to standard output, it will just
+disappear down the pipeline into @command{filter2}'s input, and the
+user will probably never see it.  So programs need a place where they can send
+error messages so that the user will notice them.  This is standard error,
+and it is usually connected to your console or window, even if you have
+redirected standard output of your program away from your screen.
+
+For filter programs to work together, the format of the data has to be
+agreed upon.  The most straightforward and easiest format to use is simply
+lines of text.  Unix data files are generally just streams of bytes, with
+lines delimited by the ASCII LF (Line Feed) character,
+conventionally called a ``newline'' in the Unix literature.  (This is
+@code{'\n'} if you're a C programmer.)  This is the format used by all
+the traditional filtering programs.  (Many earlier operating systems
+had elaborate facilities and special purpose programs for managing
+binary data.  Unix has always shied away from such things, under the
+philosophy that it's easiest to simply be able to view and edit your
+data with a text editor.)
+
+OK, enough introduction.  Let's take a look at some of the tools, and then
+we'll see how to hook them together in interesting ways.   In the following
+discussion, we will only present those command line options that interest
+us.  As you should always do, double check your system documentation
+for the full story.
+
+@node The who command
+@unnumberedsec The @command{who} Command
+
+The first program is the @command{who} command.  By itself, it generates a
+list of the users who are currently logged in.  Although I'm writing
+this on a single-user system, we'll pretend that several people are
+logged in:
+
+@example
+$ who
+@print{} arnold   console Jan 22 19:57
+@print{} miriam   ttyp0   Jan 23 14:19(:0.0)
+@print{} bill     ttyp1   Jan 21 09:32(:0.0)
+@print{} arnold   ttyp2   Jan 23 20:48(:0.0)
+@end example
+
+Here, the @samp{$} is the usual shell prompt, at which I typed @samp{who}.
+There are three people logged in, and I am logged in twice.  On traditional
+Unix systems, user names are never more than eight characters long.  This
+little bit of trivia will be useful later.  The output of @command{who} is nice,
+but the data is not all that exciting.
+
+@node The cut command
+@unnumberedsec The @command{cut} Command
+
+The next program we'll look at is the @command{cut} command.  This program
+cuts out columns or fields of input data.  For example, we can tell it
+to print just the login name and full name from the @file{/etc/passwd}
+file.  The @file{/etc/passwd} file has seven fields, separated by
+colons:
+
+@example
+arnold:xyzzy:2076:10:Arnold D. Robbins:/home/arnold:/bin/bash
+@end example
+
+To get the first and fifth fields, we would use @command{cut} like this:
+
+@example
+$ cut -d: -f1,5 /etc/passwd
+@print{} root:Operator
+@dots{}
+@print{} arnold:Arnold D. Robbins
+@print{} miriam:Miriam A. Robbins
+@dots{}
+@end example
+
+With the @option{-c} option, @command{cut} will cut out specific characters
+(i.e., columns) in the input lines.  This is useful for input data
+that has fixed width fields, and does not have a field separator.  For
+example, list the Monday dates for the current month:
+
+@c Is using cal ok?  Looked at gcal, but I don't like it.
+@example
+$ cal | cut -c 3-5
+@print{}Mo
+@print{}
+@print{}  6
+@print{} 13
+@print{} 20
+@print{} 27
+@end example
+
+@node The sort command
+@unnumberedsec The @command{sort} Command
+
+Next we'll look at the @command{sort} command.  This is one of the most
+powerful commands on a Unix-style system; one that you will often find
+yourself using when setting up fancy data plumbing.
+
+The @command{sort}
+command reads and sorts each file named on the command line.  It then
+merges the sorted data and writes it to standard output.  It will read
+standard input if no files are given on the command line (thus
+making it into a filter).  The sort is based on the character collating
+sequence or based on user-supplied ordering criteria.
+
+
+@node The uniq command
+@unnumberedsec The @command{uniq} Command
+
+Finally (at least for now), we'll look at the @command{uniq} program.  When
+sorting data, you will often end up with duplicate lines, lines that
+are identical.  Usually, all you need is one instance of each line.
+This is where @command{uniq} comes in.  The @command{uniq} program reads its
+standard input.  It prints only one
+copy of each repeated line.  It does have several options.  Later on,
+we'll use the @option{-c} option, which prints each unique line, preceded
+by a count of the number of times that line occurred in the input.
+
+
+@node Putting the tools together
+@unnumberedsec Putting the Tools Together
+
+Now, let's suppose this is a large ISP server system with dozens of users
+logged in.  The management wants the system administrator to write a
+program that will
+generate a sorted list of logged in users.  Furthermore, even if a user
+is logged in multiple times, his or her name should only show up in the
+output once.
+
+The administrator could sit down with the system documentation and write a C
+program that did this.  It would take perhaps a couple of hundred lines
+of code and about two hours to write it, test it, and debug it.
+However, knowing the software toolbox, the administrator can instead start out
+by generating just a list of logged on users:
+
+@example
+$ who | cut -c1-8
+@print{} arnold
+@print{} miriam
+@print{} bill
+@print{} arnold
+@end example
+
+Next, sort the list:
+
+@example
+$ who | cut -c1-8 | sort
+@print{} arnold
+@print{} arnold
+@print{} bill
+@print{} miriam
+@end example
+
+Finally, run the sorted list through @command{uniq}, to weed out duplicates:
+
+@example
+$ who | cut -c1-8 | sort | uniq
+@print{} arnold
+@print{} bill
+@print{} miriam
+@end example
+
+The @command{sort} command actually has a @option{-u} option that does what
+@command{uniq} does.  However, @command{uniq} has other uses for which one
+cannot substitute @samp{sort -u}.
+
+The administrator puts this pipeline into a shell script, and makes it
+available for
+all the users on the system (@samp{#} is the system administrator,
+or @code{root}, prompt):
+
+@example
+# cat > /usr/local/bin/listusers
+who | cut -c1-8 | sort | uniq
+^D
+# chmod +x /usr/local/bin/listusers
+@end example
+
+There are four major points to note here.  First, with just four
+programs, on one command line, the administrator was able to save about two
+hours worth of work.  Furthermore, the shell pipeline is just about as
+efficient as the C program would be, and it is much more efficient in
+terms of programmer time.  People time is much more expensive than
+computer time, and in our modern ``there's never enough time to do
+everything'' society, saving two hours of programmer time is no mean
+feat.
+
+Second, it is also important to emphasize that with the
+@emph{combination} of the tools, it is possible to do a special
+purpose job never imagined by the authors of the individual programs.
+
+Third, it is also valuable to build up your pipeline in stages, as we did here.
+This allows you to view the data at each stage in the pipeline, which helps
+you acquire the confidence that you are indeed using these tools correctly.
+
+Finally, by bundling the pipeline in a shell script, other users can use
+your command, without having to remember the fancy plumbing you set up for
+them.  In terms of how you run them, shell scripts and compiled programs are
+indistinguishable.
+
+After the previous warm-up exercise, we'll look at two additional, more
+complicated pipelines.  For them, we need to introduce two more tools.
+
+The first is the @command{tr} command, which stands for ``transliterate.''
+The @command{tr} command works on a character-by-character basis, changing
+characters.  Normally it is used for things like mapping upper case to
+lower case:
+
+@example
+$ echo ThIs ExAmPlE HaS MIXED case! | tr '[:upper:]' '[:lower:]'
+@print{} this example has mixed case!
+@end example
+
+There are several options of interest:
+
+@table @code
+@item -c
+work on the complement of the listed characters, i.e.,
+operations apply to characters not in the given set
+
+@item -d
+delete characters in the first set from the output
+
+@item -s
+squeeze repeated characters in the output into just one character.
+@end table
+
+We will be using all three options in a moment.
+
+The other command we'll look at is @command{comm}.  The @command{comm}
+command takes two sorted input files as input data, and prints out the
+files' lines in three columns.  The output columns are the data lines
+unique to the first file, the data lines unique to the second file, and
+the data lines that are common to both.  The @option{-1}, @option{-2}, and
+@option{-3} command line options @emph{omit} the respective columns.  (This is
+non-intuitive and takes a little getting used to.)  For example:
+
+@example
+$ cat f1
+@print{} 11111
+@print{} 22222
+@print{} 33333
+@print{} 44444
+$ cat f2
+@print{} 00000
+@print{} 22222
+@print{} 33333
+@print{} 55555
+$ comm f1 f2
+@print{}         00000
+@print{} 11111
+@print{}                 22222
+@print{}                 33333
+@print{} 44444
+@print{}         55555
+@end example
+
+The file name @file{-} tells @command{comm} to read standard input
+instead of a regular file.
+
+Now we're ready to build a fancy pipeline.  The first application is a word
+frequency counter.  This helps an author determine if he or she is over-using
+certain words.
+
+The first step is to change the case of all the letters in our input file
+to one case.  ``The'' and ``the'' are the same word when doing counting.
+
+@example
+$ tr '[:upper:]' '[:lower:]' < whats.gnu | ...
+@end example
+
+The next step is to get rid of punctuation.  Quoted words and unquoted words
+should be treated identically; it's easiest to just get the punctuation out of
+the way.
+
+@example
+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' | ...
+@end example
+
+The second @command{tr} command operates on the complement of the listed
+characters, which are all the letters, the digits, the underscore, and
+the blank.  The @samp{\n} represents the newline character; it has to
+be left alone.  (The ASCII tab character should also be included for
+good measure in a production script.)
+
+At this point, we have data consisting of words separated by blank space.
+The words only contain alphanumeric characters (and the underscore).  The
+next step is break the data apart so that we have one word per line.  This
+makes the counting operation much easier, as we will see shortly.
+
+@example
+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
+> tr -s ' ' '\n' | ...
+@end example
+
+This command turns blanks into newlines.  The @option{-s} option squeezes
+multiple newline characters in the output into just one, removing
+blank lines.  (The @samp{>} is the shell's ``secondary prompt.''
+This is what the shell prints when it notices you haven't finished
+typing in all of a command.)
+
+We now have data consisting of one word per line, no punctuation, all one
+case.  We're ready to count each word:
+
+@example
+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
+> tr -s ' ' '\n' | sort | uniq -c | ...
+@end example
+
+At this point, the data might look something like this:
+
+@example
+     60 a
+      2 able
+      6 about
+      1 above
+      2 accomplish
+      1 acquire
+      1 actually
+      2 additional
+@end example
+
+The output is sorted by word, not by count!  What we want is the most
+frequently used words first.  Fortunately, this is easy to accomplish,
+with the help of two more @command{sort} options:
+
+@table @code
+@item -n
+do a numeric sort, not a textual one
+
+@item -r
+reverse the order of the sort
+@end table
+
+The final pipeline looks like this:
+
+@example
+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
+> tr -s ' ' '\n' | sort | uniq -c | sort -n -r
+@print{}    156 the
+@print{}     60 a
+@print{}     58 to
+@print{}     51 of
+@print{}     51 and
+@dots{}
+@end example
+
+Whew!  That's a lot to digest.  Yet, the same principles apply.  With six
+commands, on two lines (really one long one split for convenience), we've
+created a program that does something interesting and useful, in much
+less time than we could have written a C program to do the same thing.
+
+A minor modification to the above pipeline can give us a simple spelling
+checker!  To determine if you've spelled a word correctly, all you have to
+do is look it up in a dictionary.  If it is not there, then chances are
+that your spelling is incorrect.  So, we need a dictionary.
+The conventional location for a dictionary is @file{/usr/dict/words}.
+On my GNU/Linux system,@footnote{Redhat Linux 6.1, for the November 2000
+revision of this article.}
+this is a sorted, 45,402 word dictionary.
+
+Now, how to compare our file with the dictionary?  As before, we generate
+a sorted list of words, one per line:
+
+@example
+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
+> tr -s ' ' '\n' | sort -u | ...
+@end example
+
+Now, all we need is a list of words that are @emph{not} in the
+dictionary.  Here is where the @command{comm} command comes in.
+
+@example
+$ tr '[:upper:]' '[:lower:]' < whats.gnu | tr -cd '[:alnum:]_ \n' |
+> tr -s ' ' '\n' | sort -u |
+> comm -23 - /usr/dict/words
+@end example
+
+The @option{-2} and @option{-3} options eliminate lines that are only in the
+dictionary (the second file), and lines that are in both files.  Lines
+only in the first file (standard input, our stream of words), are
+words that are not in the dictionary.  These are likely candidates for
+spelling errors.  This pipeline was the first cut at a production
+spelling checker on Unix.
+
+There are some other tools that deserve brief mention.
+
+@table @command
+@item grep
+search files for text that matches a regular expression
+
+@item wc
+count lines, words, characters
+
+@item tee
+a T-fitting for data pipes, copies data to files and to standard output
+
+@item sed
+the stream editor, an advanced tool
+
+@item awk
+a data manipulation language, another advanced tool
+@end table
+
+The software tools philosophy also espoused the following bit of
+advice: ``Let someone else do the hard part.''  This means, take
+something that gives you most of what you need, and then massage it the
+rest of the way until it's in the form that you want.
+
+To summarize:
+
+@enumerate 1
+@item
+Each program should do one thing well.  No more, no less.
+
+@item
+Combining programs with appropriate plumbing leads to results where
+the whole is greater than the sum of the parts.  It also leads to novel
+uses of programs that the authors might never have imagined.
+
+@item
+Programs should never print extraneous header or trailer data, since these
+could get sent on down a pipeline.  (A point we didn't mention earlier.)
+
+@item
+Let someone else do the hard part.
+
+@item
+Know your toolbox!  Use each program appropriately.  If you don't have an
+appropriate tool, build one.
+@end enumerate
+
+All the programs discussed are available as described in
+@uref{https://www.gnu.org/software/coreutils/coreutils.html,
+GNU core utilities}.
+
+None of what I have presented in this column is new.  The Software Tools
+philosophy was first introduced in the book @cite{Software Tools}, by
+Brian Kernighan and P.J. Plauger (Addison-Wesley, ISBN 0-201-03669-X).
+This book showed how to write and use software tools.  It was written in
+1976, using a preprocessor for FORTRAN named @command{ratfor} (RATional
+FORtran).  At the time, C was not as ubiquitous as it is now; FORTRAN
+was.  The last chapter presented a @command{ratfor} to FORTRAN
+processor, written in @command{ratfor}.  @command{ratfor} looks an awful
+lot like C; if you know C, you won't have any problem following the
+code.
+
+In 1981, the book was updated and made available as @cite{Software Tools
+in Pascal} (Addison-Wesley, ISBN 0-201-10342-7).  Both books are
+still in print and are well worth
+reading if you're a programmer.  They certainly made a major change in
+how I view programming.
+
+The programs in both books are available from
+@uref{https://www.cs.princeton.edu/~bwk/, Brian Kernighan's home page}.
+For a number of years, there was an active
+Software Tools Users Group, whose members had ported the original
+@command{ratfor} programs to essentially every computer system with a
+FORTRAN compiler.  The popularity of the group waned in the middle 1980s
+as Unix began to spread beyond universities.
+
+With the current proliferation of GNU code and other clones of Unix programs,
+these programs now receive little attention; modern C versions are
+much more efficient and do more than these programs do.  Nevertheless, as
+exposition of good programming style, and evangelism for a still-valuable
+philosophy, these books are unparalleled, and I recommend them highly.
+
+Acknowledgment: I would like to express my gratitude to Brian Kernighan
+of Bell Labs, the original Software Toolsmith, for reviewing this column.
+
+@node GNU Free Documentation License
+@appendix GNU Free Documentation License
+
+@include fdl.texi
+
+@node Concept index
+@unnumbered Index
+
+@printindex cp
+
+@bye
+
+@c Local variables:
+@c texinfo-column-for-description: 32
+@c End:
Index: create-8.32-no-ls-quoting-patch/coreutils-8.32-new/doc
===================================================================
--- create-8.32-no-ls-quoting-patch/coreutils-8.32-new/doc	(nonexistent)
+++ create-8.32-no-ls-quoting-patch/coreutils-8.32-new/doc	(revision 5)

Property changes on: create-8.32-no-ls-quoting-patch/coreutils-8.32-new/doc
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-8.32-no-ls-quoting-patch/coreutils-8.32-new/src/ls.c
===================================================================
--- create-8.32-no-ls-quoting-patch/coreutils-8.32-new/src/ls.c	(nonexistent)
+++ create-8.32-no-ls-quoting-patch/coreutils-8.32-new/src/ls.c	(revision 5)
@@ -0,0 +1,5519 @@
+/* 'dir', 'vdir' and 'ls' directory listing programs for GNU.
+   Copyright (C) 1985-2020 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 <https://www.gnu.org/licenses/>.  */
+
+/* If ls_mode is LS_MULTI_COL,
+   the multi-column format is the default regardless
+   of the type of output device.
+   This is for the 'dir' program.
+
+   If ls_mode is LS_LONG_FORMAT,
+   the long format is the default regardless of the
+   type of output device.
+   This is for the 'vdir' program.
+
+   If ls_mode is LS_LS,
+   the output format depends on whether the output
+   device is a terminal.
+   This is for the 'ls' program.  */
+
+/* Written by Richard Stallman and David MacKenzie.  */
+
+/* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
+   Flaherty <dennisf@denix.elk.miles.com> based on original patches by
+   Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  */
+
+#include <config.h>
+#include <sys/types.h>
+
+#include <termios.h>
+#if HAVE_STROPTS_H
+# include <stropts.h>
+#endif
+#include <sys/ioctl.h>
+
+#ifdef WINSIZE_IN_PTEM
+# include <sys/stream.h>
+# include <sys/ptem.h>
+#endif
+
+#ifdef __linux__
+# include <sys/syscall.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <setjmp.h>
+#include <pwd.h>
+#include <getopt.h>
+#include <signal.h>
+#include <selinux/selinux.h>
+#include <wchar.h>
+
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+
+/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is
+   present.  */
+#ifndef SA_NOCLDSTOP
+# define SA_NOCLDSTOP 0
+# define sigprocmask(How, Set, Oset) /* empty */
+# define sigset_t int
+# if ! HAVE_SIGINTERRUPT
+#  define siginterrupt(sig, flag) /* empty */
+# endif
+#endif
+
+/* NonStop circa 2011 lacks both SA_RESTART and siginterrupt, so don't
+   restart syscalls after a signal handler fires.  This may cause
+   colors to get messed up on the screen if 'ls' is interrupted, but
+   that's the best we can do on such a platform.  */
+#ifndef SA_RESTART
+# define SA_RESTART 0
+#endif
+
+#include "system.h"
+#include <fnmatch.h>
+
+#include "acl.h"
+#include "argmatch.h"
+#include "c-strcase.h"
+#include "dev-ino.h"
+#include "die.h"
+#include "error.h"
+#include "filenamecat.h"
+#include "hard-locale.h"
+#include "hash.h"
+#include "human.h"
+#include "filemode.h"
+#include "filevercmp.h"
+#include "idcache.h"
+#include "ls.h"
+#include "mbswidth.h"
+#include "mpsort.h"
+#include "obstack.h"
+#include "quote.h"
+#include "smack.h"
+#include "stat-size.h"
+#include "stat-time.h"
+#include "strftime.h"
+#include "xdectoint.h"
+#include "xstrtol.h"
+#include "xstrtol-error.h"
+#include "areadlink.h"
+#include "mbsalign.h"
+#include "dircolors.h"
+#include "xgethostname.h"
+#include "c-ctype.h"
+#include "canonicalize.h"
+#include "statx.h"
+
+/* Include <sys/capability.h> last to avoid a clash of <sys/types.h>
+   include guards with some premature versions of libcap.
+   For more details, see <https://bugzilla.redhat.com/483548>.  */
+#ifdef HAVE_CAP
+# include <sys/capability.h>
+#endif
+
+#define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
+                      : (ls_mode == LS_MULTI_COL \
+                         ? "dir" : "vdir"))
+
+#define AUTHORS \
+  proper_name ("Richard M. Stallman"), \
+  proper_name ("David MacKenzie")
+
+#define obstack_chunk_alloc malloc
+#define obstack_chunk_free free
+
+/* Return an int indicating the result of comparing two integers.
+   Subtracting doesn't always work, due to overflow.  */
+#define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b))
+
+/* Unix-based readdir implementations have historically returned a dirent.d_ino
+   value that is sometimes not equal to the stat-obtained st_ino value for
+   that same entry.  This error occurs for a readdir entry that refers
+   to a mount point.  readdir's error is to return the inode number of
+   the underlying directory -- one that typically cannot be stat'ed, as
+   long as a file system is mounted on that directory.  RELIABLE_D_INO
+   encapsulates whether we can use the more efficient approach of relying
+   on readdir-supplied d_ino values, or whether we must incur the cost of
+   calling stat or lstat to obtain each guaranteed-valid inode number.  */
+
+#ifndef READDIR_LIES_ABOUT_MOUNTPOINT_D_INO
+# define READDIR_LIES_ABOUT_MOUNTPOINT_D_INO 1
+#endif
+
+#if READDIR_LIES_ABOUT_MOUNTPOINT_D_INO
+# define RELIABLE_D_INO(dp) NOT_AN_INODE_NUMBER
+#else
+# define RELIABLE_D_INO(dp) D_INO (dp)
+#endif
+
+#if ! HAVE_STRUCT_STAT_ST_AUTHOR
+# define st_author st_uid
+#endif
+
+enum filetype
+  {
+    unknown,
+    fifo,
+    chardev,
+    directory,
+    blockdev,
+    normal,
+    symbolic_link,
+    sock,
+    whiteout,
+    arg_directory
+  };
+
+/* Display letters and indicators for each filetype.
+   Keep these in sync with enum filetype.  */
+static char const filetype_letter[] = "?pcdb-lswd";
+
+/* Ensure that filetype and filetype_letter have the same
+   number of elements.  */
+verify (sizeof filetype_letter - 1 == arg_directory + 1);
+
+#define FILETYPE_INDICATORS				\
+  {							\
+    C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE,	\
+    C_LINK, C_SOCK, C_FILE, C_DIR			\
+  }
+
+enum acl_type
+  {
+    ACL_T_NONE,
+    ACL_T_LSM_CONTEXT_ONLY,
+    ACL_T_YES
+  };
+
+struct fileinfo
+  {
+    /* The file name.  */
+    char *name;
+
+    /* For symbolic link, name of the file linked to, otherwise zero.  */
+    char *linkname;
+
+    /* For terminal hyperlinks. */
+    char *absolute_name;
+
+    struct stat stat;
+
+    enum filetype filetype;
+
+    /* For symbolic link and long listing, st_mode of file linked to, otherwise
+       zero.  */
+    mode_t linkmode;
+
+    /* security context.  */
+    char *scontext;
+
+    bool stat_ok;
+
+    /* For symbolic link and color printing, true if linked-to file
+       exists, otherwise false.  */
+    bool linkok;
+
+    /* For long listings, true if the file has an access control list,
+       or a security context.  */
+    enum acl_type acl_type;
+
+    /* For color listings, true if a regular file has capability info.  */
+    bool has_capability;
+
+    /* Whether file name needs quoting. tri-state with -1 == unknown.  */
+    int quoted;
+  };
+
+#define LEN_STR_PAIR(s) sizeof (s) - 1, s
+
+/* Null is a valid character in a color indicator (think about Epson
+   printers, for example) so we have to use a length/buffer string
+   type.  */
+
+struct bin_str
+  {
+    size_t len;			/* Number of bytes */
+    const char *string;		/* Pointer to the same */
+  };
+
+#if ! HAVE_TCGETPGRP
+# define tcgetpgrp(Fd) 0
+#endif
+
+static size_t quote_name (char const *name,
+                          struct quoting_options const *options,
+                          int needs_general_quoting,
+                          const struct bin_str *color,
+                          bool allow_pad, struct obstack *stack,
+                          char const *absolute_name);
+static size_t quote_name_buf (char **inbuf, size_t bufsize, char *name,
+                              struct quoting_options const *options,
+                              int needs_general_quoting, size_t *width,
+                              bool *pad);
+static char *make_link_name (char const *name, char const *linkname);
+static int decode_switches (int argc, char **argv);
+static bool file_ignored (char const *name);
+static uintmax_t gobble_file (char const *name, enum filetype type,
+                              ino_t inode, bool command_line_arg,
+                              char const *dirname);
+static const struct bin_str * get_color_indicator (const struct fileinfo *f,
+                                                   bool symlink_target);
+static bool print_color_indicator (const struct bin_str *ind);
+static void put_indicator (const struct bin_str *ind);
+static void add_ignore_pattern (const char *pattern);
+static void attach (char *dest, const char *dirname, const char *name);
+static void clear_files (void);
+static void extract_dirs_from_files (char const *dirname,
+                                     bool command_line_arg);
+static void get_link_name (char const *filename, struct fileinfo *f,
+                           bool command_line_arg);
+static void indent (size_t from, size_t to);
+static size_t calculate_columns (bool by_columns);
+static void print_current_files (void);
+static void print_dir (char const *name, char const *realname,
+                       bool command_line_arg);
+static size_t print_file_name_and_frills (const struct fileinfo *f,
+                                          size_t start_col);
+static void print_horizontal (void);
+static int format_user_width (uid_t u);
+static int format_group_width (gid_t g);
+static void print_long_format (const struct fileinfo *f);
+static void print_many_per_line (void);
+static size_t print_name_with_quoting (const struct fileinfo *f,
+                                       bool symlink_target,
+                                       struct obstack *stack,
+                                       size_t start_col);
+static void prep_non_filename_text (void);
+static bool print_type_indicator (bool stat_ok, mode_t mode,
+                                  enum filetype type);
+static void print_with_separator (char sep);
+static void queue_directory (char const *name, char const *realname,
+                             bool command_line_arg);
+static void sort_files (void);
+static void parse_ls_color (void);
+
+static void getenv_quoting_style (void);
+
+/* Initial size of hash table.
+   Most hierarchies are likely to be shallower than this.  */
+#define INITIAL_TABLE_SIZE 30
+
+/* The set of 'active' directories, from the current command-line argument
+   to the level in the hierarchy at which files are being listed.
+   A directory is represented by its device and inode numbers (struct dev_ino).
+   A directory is added to this set when ls begins listing it or its
+   entries, and it is removed from the set just after ls has finished
+   processing it.  This set is used solely to detect loops, e.g., with
+   mkdir loop; cd loop; ln -s ../loop sub; ls -RL  */
+static Hash_table *active_dir_set;
+
+#define LOOP_DETECT (!!active_dir_set)
+
+/* The table of files in the current directory:
+
+   'cwd_file' points to a vector of 'struct fileinfo', one per file.
+   'cwd_n_alloc' is the number of elements space has been allocated for.
+   'cwd_n_used' is the number actually in use.  */
+
+/* Address of block containing the files that are described.  */
+static struct fileinfo *cwd_file;
+
+/* Length of block that 'cwd_file' points to, measured in files.  */
+static size_t cwd_n_alloc;
+
+/* Index of first unused slot in 'cwd_file'.  */
+static size_t cwd_n_used;
+
+/* Whether files needs may need padding due to quoting.  */
+static bool cwd_some_quoted;
+
+/* Whether quoting style _may_ add outer quotes,
+   and whether aligning those is useful.  */
+static bool align_variable_outer_quotes;
+
+/* Vector of pointers to files, in proper sorted order, and the number
+   of entries allocated for it.  */
+static void **sorted_file;
+static size_t sorted_file_alloc;
+
+/* When true, in a color listing, color each symlink name according to the
+   type of file it points to.  Otherwise, color them according to the 'ln'
+   directive in LS_COLORS.  Dangling (orphan) symlinks are treated specially,
+   regardless.  This is set when 'ln=target' appears in LS_COLORS.  */
+
+static bool color_symlink_as_referent;
+
+static char const *hostname;
+
+/* mode of appropriate file for colorization */
+#define FILE_OR_LINK_MODE(File) \
+    ((color_symlink_as_referent && (File)->linkok) \
+     ? (File)->linkmode : (File)->stat.st_mode)
+
+
+/* Record of one pending directory waiting to be listed.  */
+
+struct pending
+  {
+    char *name;
+    /* If the directory is actually the file pointed to by a symbolic link we
+       were told to list, 'realname' will contain the name of the symbolic
+       link, otherwise zero.  */
+    char *realname;
+    bool command_line_arg;
+    struct pending *next;
+  };
+
+static struct pending *pending_dirs;
+
+/* Current time in seconds and nanoseconds since 1970, updated as
+   needed when deciding whether a file is recent.  */
+
+static struct timespec current_time;
+
+static bool print_scontext;
+static char UNKNOWN_SECURITY_CONTEXT[] = "?";
+
+/* Whether any of the files has an ACL.  This affects the width of the
+   mode column.  */
+
+static bool any_has_acl;
+
+/* The number of columns to use for columns containing inode numbers,
+   block sizes, link counts, owners, groups, authors, major device
+   numbers, minor device numbers, and file sizes, respectively.  */
+
+static int inode_number_width;
+static int block_size_width;
+static int nlink_width;
+static int scontext_width;
+static int owner_width;
+static int group_width;
+static int author_width;
+static int major_device_number_width;
+static int minor_device_number_width;
+static int file_size_width;
+
+/* Option flags */
+
+/* long_format for lots of info, one per line.
+   one_per_line for just names, one per line.
+   many_per_line for just names, many per line, sorted vertically.
+   horizontal for just names, many per line, sorted horizontally.
+   with_commas for just names, many per line, separated by commas.
+
+   -l (and other options that imply -l), -1, -C, -x and -m control
+   this parameter.  */
+
+enum format
+  {
+    long_format,		/* -l and other options that imply -l */
+    one_per_line,		/* -1 */
+    many_per_line,		/* -C */
+    horizontal,			/* -x */
+    with_commas			/* -m */
+  };
+
+static enum format format;
+
+/* 'full-iso' uses full ISO-style dates and times.  'long-iso' uses longer
+   ISO-style timestamps, though shorter than 'full-iso'.  'iso' uses shorter
+   ISO-style timestamps.  'locale' uses locale-dependent timestamps.  */
+enum time_style
+  {
+    full_iso_time_style,	/* --time-style=full-iso */
+    long_iso_time_style,	/* --time-style=long-iso */
+    iso_time_style,		/* --time-style=iso */
+    locale_time_style		/* --time-style=locale */
+  };
+
+static char const *const time_style_args[] =
+{
+  "full-iso", "long-iso", "iso", "locale", NULL
+};
+static enum time_style const time_style_types[] =
+{
+  full_iso_time_style, long_iso_time_style, iso_time_style,
+  locale_time_style
+};
+ARGMATCH_VERIFY (time_style_args, time_style_types);
+
+/* Type of time to print or sort by.  Controlled by -c and -u.
+   The values of each item of this enum are important since they are
+   used as indices in the sort functions array (see sort_files()).  */
+
+enum time_type
+  {
+    time_mtime,			/* default */
+    time_ctime,			/* -c */
+    time_atime,			/* -u */
+    time_btime,                 /* birth time */
+    time_numtypes		/* the number of elements of this enum */
+  };
+
+static enum time_type time_type;
+
+/* The file characteristic to sort by.  Controlled by -t, -S, -U, -X, -v.
+   The values of each item of this enum are important since they are
+   used as indices in the sort functions array (see sort_files()).  */
+
+enum sort_type
+  {
+    sort_none = -1,		/* -U */
+    sort_name,			/* default */
+    sort_extension,		/* -X */
+    sort_size,			/* -S */
+    sort_version,		/* -v */
+    sort_time,			/* -t */
+    sort_numtypes		/* the number of elements of this enum */
+  };
+
+static enum sort_type sort_type;
+
+/* Direction of sort.
+   false means highest first if numeric,
+   lowest first if alphabetic;
+   these are the defaults.
+   true means the opposite order in each case.  -r  */
+
+static bool sort_reverse;
+
+/* True means to display owner information.  -g turns this off.  */
+
+static bool print_owner = true;
+
+/* True means to display author information.  */
+
+static bool print_author;
+
+/* True means to display group information.  -G and -o turn this off.  */
+
+static bool print_group = true;
+
+/* True means print the user and group id's as numbers rather
+   than as names.  -n  */
+
+static bool numeric_ids;
+
+/* True means mention the size in blocks of each file.  -s  */
+
+static bool print_block_size;
+
+/* Human-readable options for output, when printing block counts.  */
+static int human_output_opts;
+
+/* The units to use when printing block counts.  */
+static uintmax_t output_block_size;
+
+/* Likewise, but for file sizes.  */
+static int file_human_output_opts;
+static uintmax_t file_output_block_size = 1;
+
+/* Follow the output with a special string.  Using this format,
+   Emacs' dired mode starts up twice as fast, and can handle all
+   strange characters in file names.  */
+static bool dired;
+
+/* 'none' means don't mention the type of files.
+   'slash' means mention directories only, with a '/'.
+   'file_type' means mention file types.
+   'classify' means mention file types and mark executables.
+
+   Controlled by -F, -p, and --indicator-style.  */
+
+enum indicator_style
+  {
+    none,	/*     --indicator-style=none */
+    slash,	/* -p, --indicator-style=slash */
+    file_type,	/*     --indicator-style=file-type */
+    classify	/* -F, --indicator-style=classify */
+  };
+
+static enum indicator_style indicator_style;
+
+/* Names of indicator styles.  */
+static char const *const indicator_style_args[] =
+{
+  "none", "slash", "file-type", "classify", NULL
+};
+static enum indicator_style const indicator_style_types[] =
+{
+  none, slash, file_type, classify
+};
+ARGMATCH_VERIFY (indicator_style_args, indicator_style_types);
+
+/* True means use colors to mark types.  Also define the different
+   colors as well as the stuff for the LS_COLORS environment variable.
+   The LS_COLORS variable is now in a termcap-like format.  */
+
+static bool print_with_color;
+
+static bool print_hyperlink;
+
+/* Whether we used any colors in the output so far.  If so, we will
+   need to restore the default color later.  If not, we will need to
+   call prep_non_filename_text before using color for the first time. */
+
+static bool used_color = false;
+
+enum when_type
+  {
+    when_never,		/* 0: default or --color=never */
+    when_always,	/* 1: --color=always */
+    when_if_tty		/* 2: --color=tty */
+  };
+
+enum Dereference_symlink
+  {
+    DEREF_UNDEFINED = 1,
+    DEREF_NEVER,
+    DEREF_COMMAND_LINE_ARGUMENTS,	/* -H */
+    DEREF_COMMAND_LINE_SYMLINK_TO_DIR,	/* the default, in certain cases */
+    DEREF_ALWAYS			/* -L */
+  };
+
+enum indicator_no
+  {
+    C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK,
+    C_FIFO, C_SOCK,
+    C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID,
+    C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_MULTIHARDLINK,
+    C_CLR_TO_EOL
+  };
+
+static const char *const indicator_name[]=
+  {
+    "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so",
+    "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st",
+    "ow", "tw", "ca", "mh", "cl", NULL
+  };
+
+struct color_ext_type
+  {
+    struct bin_str ext;		/* The extension we're looking for */
+    struct bin_str seq;		/* The sequence to output when we do */
+    struct color_ext_type *next;	/* Next in list */
+  };
+
+static struct bin_str color_indicator[] =
+  {
+    { LEN_STR_PAIR ("\033[") },		/* lc: Left of color sequence */
+    { LEN_STR_PAIR ("m") },		/* rc: Right of color sequence */
+    { 0, NULL },			/* ec: End color (replaces lc+rs+rc) */
+    { LEN_STR_PAIR ("0") },		/* rs: Reset to ordinary colors */
+    { 0, NULL },			/* no: Normal */
+    { 0, NULL },			/* fi: File: default */
+    { LEN_STR_PAIR ("01;34") },		/* di: Directory: bright blue */
+    { LEN_STR_PAIR ("01;36") },		/* ln: Symlink: bright cyan */
+    { LEN_STR_PAIR ("33") },		/* pi: Pipe: yellow/brown */
+    { LEN_STR_PAIR ("01;35") },		/* so: Socket: bright magenta */
+    { LEN_STR_PAIR ("01;33") },		/* bd: Block device: bright yellow */
+    { LEN_STR_PAIR ("01;33") },		/* cd: Char device: bright yellow */
+    { 0, NULL },			/* mi: Missing file: undefined */
+    { 0, NULL },			/* or: Orphaned symlink: undefined */
+    { LEN_STR_PAIR ("01;32") },		/* ex: Executable: bright green */
+    { LEN_STR_PAIR ("01;35") },		/* do: Door: bright magenta */
+    { LEN_STR_PAIR ("37;41") },		/* su: setuid: white on red */
+    { LEN_STR_PAIR ("30;43") },		/* sg: setgid: black on yellow */
+    { LEN_STR_PAIR ("37;44") },		/* st: sticky: black on blue */
+    { LEN_STR_PAIR ("34;42") },		/* ow: other-writable: blue on green */
+    { LEN_STR_PAIR ("30;42") },		/* tw: ow w/ sticky: black on green */
+    { LEN_STR_PAIR ("30;41") },		/* ca: black on red */
+    { 0, NULL },			/* mh: disabled by default */
+    { LEN_STR_PAIR ("\033[K") },	/* cl: clear to end of line */
+  };
+
+/* FIXME: comment  */
+static struct color_ext_type *color_ext_list = NULL;
+
+/* Buffer for color sequences */
+static char *color_buf;
+
+/* True means to check for orphaned symbolic link, for displaying
+   colors, or to group symlink to directories with other dirs.  */
+
+static bool check_symlink_mode;
+
+/* True means mention the inode number of each file.  -i  */
+
+static bool print_inode;
+
+/* What to do with symbolic links.  Affected by -d, -F, -H, -l (and
+   other options that imply -l), and -L.  */
+
+static enum Dereference_symlink dereference;
+
+/* True means when a directory is found, display info on its
+   contents.  -R  */
+
+static bool recursive;
+
+/* True means when an argument is a directory name, display info
+   on it itself.  -d  */
+
+static bool immediate_dirs;
+
+/* True means that directories are grouped before files. */
+
+static bool directories_first;
+
+/* Which files to ignore.  */
+
+static enum
+{
+  /* Ignore files whose names start with '.', and files specified by
+     --hide and --ignore.  */
+  IGNORE_DEFAULT,
+
+  /* Ignore '.', '..', and files specified by --ignore.  */
+  IGNORE_DOT_AND_DOTDOT,
+
+  /* Ignore only files specified by --ignore.  */
+  IGNORE_MINIMAL
+} ignore_mode;
+
+/* A linked list of shell-style globbing patterns.  If a non-argument
+   file name matches any of these patterns, it is ignored.
+   Controlled by -I.  Multiple -I options accumulate.
+   The -B option adds '*~' and '.*~' to this list.  */
+
+struct ignore_pattern
+  {
+    const char *pattern;
+    struct ignore_pattern *next;
+  };
+
+static struct ignore_pattern *ignore_patterns;
+
+/* Similar to IGNORE_PATTERNS, except that -a or -A causes this
+   variable itself to be ignored.  */
+static struct ignore_pattern *hide_patterns;
+
+/* True means output nongraphic chars in file names as '?'.
+   (-q, --hide-control-chars)
+   qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are
+   independent.  The algorithm is: first, obey the quoting style to get a
+   string representing the file name;  then, if qmark_funny_chars is set,
+   replace all nonprintable chars in that string with '?'.  It's necessary
+   to replace nonprintable chars even in quoted strings, because we don't
+   want to mess up the terminal if control chars get sent to it, and some
+   quoting methods pass through control chars as-is.  */
+static bool qmark_funny_chars;
+
+/* Quoting options for file and dir name output.  */
+
+static struct quoting_options *filename_quoting_options;
+static struct quoting_options *dirname_quoting_options;
+
+/* The number of chars per hardware tab stop.  Setting this to zero
+   inhibits the use of TAB characters for separating columns.  -T */
+static size_t tabsize;
+
+/* True means print each directory name before listing it.  */
+
+static bool print_dir_name;
+
+/* The line length to use for breaking lines in many-per-line format.
+   Can be set with -w.  */
+
+static size_t line_length;
+
+/* The local time zone rules, as per the TZ environment variable.  */
+
+static timezone_t localtz;
+
+/* If true, the file listing format requires that stat be called on
+   each file.  */
+
+static bool format_needs_stat;
+
+/* Similar to 'format_needs_stat', but set if only the file type is
+   needed.  */
+
+static bool format_needs_type;
+
+/* An arbitrary limit on the number of bytes in a printed timestamp.
+   This is set to a relatively small value to avoid the need to worry
+   about denial-of-service attacks on servers that run "ls" on behalf
+   of remote clients.  1000 bytes should be enough for any practical
+   timestamp format.  */
+
+enum { TIME_STAMP_LEN_MAXIMUM = MAX (1000, INT_STRLEN_BOUND (time_t)) };
+
+/* strftime formats for non-recent and recent files, respectively, in
+   -l output.  */
+
+static char const *long_time_format[2] =
+  {
+    /* strftime format for non-recent files (older than 6 months), in
+       -l output.  This should contain the year, month and day (at
+       least), in an order that is understood by people in your
+       locale's territory.  Please try to keep the number of used
+       screen columns small, because many people work in windows with
+       only 80 columns.  But make this as wide as the other string
+       below, for recent files.  */
+    /* TRANSLATORS: ls output needs to be aligned for ease of reading,
+       so be wary of using variable width fields from the locale.
+       Note %b is handled specially by ls and aligned correctly.
+       Note also that specifying a width as in %5b is erroneous as strftime
+       will count bytes rather than characters in multibyte locales.  */
+    N_("%b %e  %Y"),
+    /* strftime format for recent files (younger than 6 months), in -l
+       output.  This should contain the month, day and time (at
+       least), in an order that is understood by people in your
+       locale's territory.  Please try to keep the number of used
+       screen columns small, because many people work in windows with
+       only 80 columns.  But make this as wide as the other string
+       above, for non-recent files.  */
+    /* TRANSLATORS: ls output needs to be aligned for ease of reading,
+       so be wary of using variable width fields from the locale.
+       Note %b is handled specially by ls and aligned correctly.
+       Note also that specifying a width as in %5b is erroneous as strftime
+       will count bytes rather than characters in multibyte locales.  */
+    N_("%b %e %H:%M")
+  };
+
+/* The set of signals that are caught.  */
+
+static sigset_t caught_signals;
+
+/* If nonzero, the value of the pending fatal signal.  */
+
+static sig_atomic_t volatile interrupt_signal;
+
+/* A count of the number of pending stop signals that have been received.  */
+
+static sig_atomic_t volatile stop_signal_count;
+
+/* Desired exit status.  */
+
+static int exit_status;
+
+/* Exit statuses.  */
+enum
+  {
+    /* "ls" had a minor problem.  E.g., while processing a directory,
+       ls obtained the name of an entry via readdir, yet was later
+       unable to stat that name.  This happens when listing a directory
+       in which entries are actively being removed or renamed.  */
+    LS_MINOR_PROBLEM = 1,
+
+    /* "ls" had more serious trouble (e.g., memory exhausted, invalid
+       option or failure to stat a command line argument.  */
+    LS_FAILURE = 2
+  };
+
+/* For long options that have no equivalent short option, use a
+   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
+enum
+{
+  AUTHOR_OPTION = CHAR_MAX + 1,
+  BLOCK_SIZE_OPTION,
+  COLOR_OPTION,
+  DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION,
+  FILE_TYPE_INDICATOR_OPTION,
+  FORMAT_OPTION,
+  FULL_TIME_OPTION,
+  GROUP_DIRECTORIES_FIRST_OPTION,
+  HIDE_OPTION,
+  HYPERLINK_OPTION,
+  INDICATOR_STYLE_OPTION,
+  QUOTING_STYLE_OPTION,
+  SHOW_CONTROL_CHARS_OPTION,
+  SI_OPTION,
+  SORT_OPTION,
+  TIME_OPTION,
+  TIME_STYLE_OPTION
+};
+
+static struct option const long_options[] =
+{
+  {"all", no_argument, NULL, 'a'},
+  {"escape", no_argument, NULL, 'b'},
+  {"directory", no_argument, NULL, 'd'},
+  {"dired", no_argument, NULL, 'D'},
+  {"full-time", no_argument, NULL, FULL_TIME_OPTION},
+  {"group-directories-first", no_argument, NULL,
+   GROUP_DIRECTORIES_FIRST_OPTION},
+  {"human-readable", no_argument, NULL, 'h'},
+  {"inode", no_argument, NULL, 'i'},
+  {"kibibytes", no_argument, NULL, 'k'},
+  {"numeric-uid-gid", no_argument, NULL, 'n'},
+  {"no-group", no_argument, NULL, 'G'},
+  {"hide-control-chars", no_argument, NULL, 'q'},
+  {"reverse", no_argument, NULL, 'r'},
+  {"size", no_argument, NULL, 's'},
+  {"width", required_argument, NULL, 'w'},
+  {"almost-all", no_argument, NULL, 'A'},
+  {"ignore-backups", no_argument, NULL, 'B'},
+  {"classify", no_argument, NULL, 'F'},
+  {"file-type", no_argument, NULL, FILE_TYPE_INDICATOR_OPTION},
+  {"si", no_argument, NULL, SI_OPTION},
+  {"dereference-command-line", no_argument, NULL, 'H'},
+  {"dereference-command-line-symlink-to-dir", no_argument, NULL,
+   DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION},
+  {"hide", required_argument, NULL, HIDE_OPTION},
+  {"ignore", required_argument, NULL, 'I'},
+  {"indicator-style", required_argument, NULL, INDICATOR_STYLE_OPTION},
+  {"dereference", no_argument, NULL, 'L'},
+  {"literal", no_argument, NULL, 'N'},
+  {"quote-name", no_argument, NULL, 'Q'},
+  {"quoting-style", required_argument, NULL, QUOTING_STYLE_OPTION},
+  {"recursive", no_argument, NULL, 'R'},
+  {"format", required_argument, NULL, FORMAT_OPTION},
+  {"show-control-chars", no_argument, NULL, SHOW_CONTROL_CHARS_OPTION},
+  {"sort", required_argument, NULL, SORT_OPTION},
+  {"tabsize", required_argument, NULL, 'T'},
+  {"time", required_argument, NULL, TIME_OPTION},
+  {"time-style", required_argument, NULL, TIME_STYLE_OPTION},
+  {"color", optional_argument, NULL, COLOR_OPTION},
+  {"hyperlink", optional_argument, NULL, HYPERLINK_OPTION},
+  {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
+  {"context", no_argument, 0, 'Z'},
+  {"author", no_argument, NULL, AUTHOR_OPTION},
+  {GETOPT_HELP_OPTION_DECL},
+  {GETOPT_VERSION_OPTION_DECL},
+  {NULL, 0, NULL, 0}
+};
+
+static char const *const format_args[] =
+{
+  "verbose", "long", "commas", "horizontal", "across",
+  "vertical", "single-column", NULL
+};
+static enum format const format_types[] =
+{
+  long_format, long_format, with_commas, horizontal, horizontal,
+  many_per_line, one_per_line
+};
+ARGMATCH_VERIFY (format_args, format_types);
+
+static char const *const sort_args[] =
+{
+  "none", "time", "size", "extension", "version", NULL
+};
+static enum sort_type const sort_types[] =
+{
+  sort_none, sort_time, sort_size, sort_extension, sort_version
+};
+ARGMATCH_VERIFY (sort_args, sort_types);
+
+static char const *const time_args[] =
+{
+  "atime", "access", "use",
+  "ctime", "status",
+  "birth", "creation",
+  NULL
+};
+static enum time_type const time_types[] =
+{
+  time_atime, time_atime, time_atime,
+  time_ctime, time_ctime,
+  time_btime, time_btime,
+};
+ARGMATCH_VERIFY (time_args, time_types);
+
+static char const *const when_args[] =
+{
+  /* force and none are for compatibility with another color-ls version */
+  "always", "yes", "force",
+  "never", "no", "none",
+  "auto", "tty", "if-tty", NULL
+};
+static enum when_type const when_types[] =
+{
+  when_always, when_always, when_always,
+  when_never, when_never, when_never,
+  when_if_tty, when_if_tty, when_if_tty
+};
+ARGMATCH_VERIFY (when_args, when_types);
+
+/* Information about filling a column.  */
+struct column_info
+{
+  bool valid_len;
+  size_t line_len;
+  size_t *col_arr;
+};
+
+/* Array with information about column filledness.  */
+static struct column_info *column_info;
+
+/* Maximum number of columns ever possible for this display.  */
+static size_t max_idx;
+
+/* The minimum width of a column is 3: 1 character for the name and 2
+   for the separating white space.  */
+#define MIN_COLUMN_WIDTH	3
+
+
+/* This zero-based index is used solely with the --dired option.
+   When that option is in effect, this counter is incremented for each
+   byte of output generated by this program so that the beginning
+   and ending indices (in that output) of every file name can be recorded
+   and later output themselves.  */
+static size_t dired_pos;
+
+#define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0)
+
+/* Write S to STREAM and increment DIRED_POS by S_LEN.  */
+#define DIRED_FPUTS(s, stream, s_len) \
+    do {fputs (s, stream); dired_pos += s_len;} while (0)
+
+/* Like DIRED_FPUTS, but for use when S is a literal string.  */
+#define DIRED_FPUTS_LITERAL(s, stream) \
+    do {fputs (s, stream); dired_pos += sizeof (s) - 1;} while (0)
+
+#define DIRED_INDENT()							\
+    do									\
+      {									\
+        if (dired)							\
+          DIRED_FPUTS_LITERAL ("  ", stdout);				\
+      }									\
+    while (0)
+
+/* With --dired, store pairs of beginning and ending indices of file names.  */
+static struct obstack dired_obstack;
+
+/* With --dired, store pairs of beginning and ending indices of any
+   directory names that appear as headers (just before 'total' line)
+   for lists of directory entries.  Such directory names are seen when
+   listing hierarchies using -R and when a directory is listed with at
+   least one other command line argument.  */
+static struct obstack subdired_obstack;
+
+/* Save the current index on the specified obstack, OBS.  */
+#define PUSH_CURRENT_DIRED_POS(obs)					\
+  do									\
+    {									\
+      if (dired)							\
+        obstack_grow (obs, &dired_pos, sizeof (dired_pos));		\
+    }									\
+  while (0)
+
+/* With -R, this stack is used to help detect directory cycles.
+   The device/inode pairs on this stack mirror the pairs in the
+   active_dir_set hash table.  */
+static struct obstack dev_ino_obstack;
+
+/* Push a pair onto the device/inode stack.  */
+static void
+dev_ino_push (dev_t dev, ino_t ino)
+{
+  void *vdi;
+  struct dev_ino *di;
+  int dev_ino_size = sizeof *di;
+  obstack_blank (&dev_ino_obstack, dev_ino_size);
+  vdi = obstack_next_free (&dev_ino_obstack);
+  di = vdi;
+  di--;
+  di->st_dev = dev;
+  di->st_ino = ino;
+}
+
+/* Pop a dev/ino struct off the global dev_ino_obstack
+   and return that struct.  */
+static struct dev_ino
+dev_ino_pop (void)
+{
+  void *vdi;
+  struct dev_ino *di;
+  int dev_ino_size = sizeof *di;
+  assert (dev_ino_size <= obstack_object_size (&dev_ino_obstack));
+  obstack_blank_fast (&dev_ino_obstack, -dev_ino_size);
+  vdi = obstack_next_free (&dev_ino_obstack);
+  di = vdi;
+  return *di;
+}
+
+/* Note the use commented out below:
+#define ASSERT_MATCHING_DEV_INO(Name, Di)	\
+  do						\
+    {						\
+      struct stat sb;				\
+      assert (Name);				\
+      assert (0 <= stat (Name, &sb));		\
+      assert (sb.st_dev == Di.st_dev);		\
+      assert (sb.st_ino == Di.st_ino);		\
+    }						\
+  while (0)
+*/
+
+/* Write to standard output PREFIX, followed by the quoting style and
+   a space-separated list of the integers stored in OS all on one line.  */
+
+static void
+dired_dump_obstack (const char *prefix, struct obstack *os)
+{
+  size_t n_pos;
+
+  n_pos = obstack_object_size (os) / sizeof (dired_pos);
+  if (n_pos > 0)
+    {
+      size_t *pos = (size_t *) obstack_finish (os);
+      fputs (prefix, stdout);
+      for (size_t i = 0; i < n_pos; i++)
+        printf (" %lu", (unsigned long int) pos[i]);
+      putchar ('\n');
+    }
+}
+
+/* Return the platform birthtime member of the stat structure,
+   or fallback to the mtime member, which we have populated
+   from the statx structure or reset to an invalid timestamp
+   where birth time is not supported.  */
+static struct timespec
+get_stat_btime (struct stat const *st)
+{
+  struct timespec btimespec;
+
+#if HAVE_STATX && defined STATX_INO
+  btimespec = get_stat_mtime (st);
+#else
+  btimespec = get_stat_birthtime (st);
+#endif
+
+  return btimespec;
+}
+
+#if HAVE_STATX && defined STATX_INO
+static unsigned int _GL_ATTRIBUTE_PURE
+time_type_to_statx (void)
+{
+  switch (time_type)
+    {
+    case time_ctime:
+      return STATX_CTIME;
+    case time_mtime:
+      return STATX_MTIME;
+    case time_atime:
+      return STATX_ATIME;
+    case time_btime:
+      return STATX_BTIME;
+    default:
+      abort ();
+    }
+    return 0;
+}
+
+static unsigned int _GL_ATTRIBUTE_PURE
+calc_req_mask (void)
+{
+  unsigned int mask = STATX_MODE;
+
+  if (print_inode)
+    mask |= STATX_INO;
+
+  if (print_block_size)
+    mask |= STATX_BLOCKS;
+
+  if (format == long_format) {
+    mask |= STATX_NLINK | STATX_SIZE | time_type_to_statx ();
+    if (print_owner || print_author)
+      mask |= STATX_UID;
+    if (print_group)
+      mask |= STATX_GID;
+  }
+
+  switch (sort_type)
+    {
+    case sort_none:
+    case sort_name:
+    case sort_version:
+    case sort_extension:
+      break;
+    case sort_time:
+      mask |= time_type_to_statx ();
+      break;
+    case sort_size:
+      mask |= STATX_SIZE;
+      break;
+    default:
+      abort ();
+    }
+
+  return mask;
+}
+
+static int
+do_statx (int fd, const char *name, struct stat *st, int flags,
+          unsigned int mask)
+{
+  struct statx stx;
+  bool want_btime = mask & STATX_BTIME;
+  int ret = statx (fd, name, flags, mask, &stx);
+  if (ret >= 0)
+    {
+      statx_to_stat (&stx, st);
+      /* Since we only need one timestamp type,
+         store birth time in st_mtim.  */
+      if (want_btime)
+        {
+          if (stx.stx_mask & STATX_BTIME)
+            st->st_mtim = statx_timestamp_to_timespec (stx.stx_btime);
+          else
+            st->st_mtim.tv_sec = st->st_mtim.tv_nsec = -1;
+        }
+    }
+
+  return ret;
+}
+
+static inline int
+do_stat (const char *name, struct stat *st)
+{
+  return do_statx (AT_FDCWD, name, st, 0, calc_req_mask ());
+}
+
+static inline int
+do_lstat (const char *name, struct stat *st)
+{
+  return do_statx (AT_FDCWD, name, st, AT_SYMLINK_NOFOLLOW, calc_req_mask ());
+}
+
+static inline int
+stat_for_mode (const char *name, struct stat *st)
+{
+  return do_statx (AT_FDCWD, name, st, 0, STATX_MODE);
+}
+
+/* dev+ino should be static, so no need to sync with backing store */
+static inline int
+stat_for_ino (const char *name, struct stat *st)
+{
+  return do_statx (AT_FDCWD, name, st, 0, STATX_INO);
+}
+
+static inline int
+fstat_for_ino (int fd, struct stat *st)
+{
+  return do_statx (fd, "", st, AT_EMPTY_PATH, STATX_INO);
+}
+#else
+static inline int
+do_stat (const char *name, struct stat *st)
+{
+  return stat (name, st);
+}
+
+static inline int
+do_lstat (const char *name, struct stat *st)
+{
+  return lstat (name, st);
+}
+
+static inline int
+stat_for_mode (const char *name, struct stat *st)
+{
+  return stat (name, st);
+}
+
+static inline int
+stat_for_ino (const char *name, struct stat *st)
+{
+  return stat (name, st);
+}
+
+static inline int
+fstat_for_ino (int fd, struct stat *st)
+{
+  return fstat (fd, st);
+}
+#endif
+
+/* Return the address of the first plain %b spec in FMT, or NULL if
+   there is no such spec.  %5b etc. do not match, so that user
+   widths/flags are honored.  */
+
+static char const * _GL_ATTRIBUTE_PURE
+first_percent_b (char const *fmt)
+{
+  for (; *fmt; fmt++)
+    if (fmt[0] == '%')
+      switch (fmt[1])
+        {
+        case 'b': return fmt;
+        case '%': fmt++; break;
+        }
+  return NULL;
+}
+
+static char RFC3986[256];
+static void
+file_escape_init (void)
+{
+  for (int i = 0; i < 256; i++)
+    RFC3986[i] |= c_isalnum (i) || i == '~' || i == '-' || i == '.' || i == '_';
+}
+
+/* Read the abbreviated month names from the locale, to align them
+   and to determine the max width of the field and to truncate names
+   greater than our max allowed.
+   Note even though this handles multibyte locales correctly
+   it's not restricted to them as single byte locales can have
+   variable width abbreviated months and also precomputing/caching
+   the names was seen to increase the performance of ls significantly.  */
+
+/* max number of display cells to use.
+   As of 2018 the abmon for Arabic has entries with width 12.
+   It doesn't make much sense to support wider than this
+   and locales should aim for abmon entries of width <= 5.  */
+enum { MAX_MON_WIDTH = 12 };
+/* abformat[RECENT][MON] is the format to use for timestamps with
+   recentness RECENT and month MON.  */
+enum { ABFORMAT_SIZE = 128 };
+static char abformat[2][12][ABFORMAT_SIZE];
+/* True if precomputed formats should be used.  This can be false if
+   nl_langinfo fails, if a format or month abbreviation is unusually
+   long, or if a month abbreviation contains '%'.  */
+static bool use_abformat;
+
+/* Store into ABMON the abbreviated month names, suitably aligned.
+   Return true if successful.  */
+
+static bool
+abmon_init (char abmon[12][ABFORMAT_SIZE])
+{
+#ifndef HAVE_NL_LANGINFO
+  return false;
+#else
+  size_t required_mon_width = MAX_MON_WIDTH;
+  size_t curr_max_width;
+  do
+    {
+      curr_max_width = required_mon_width;
+      required_mon_width = 0;
+      for (int i = 0; i < 12; i++)
+        {
+          size_t width = curr_max_width;
+          char const *abbr = nl_langinfo (ABMON_1 + i);
+          if (strchr (abbr, '%'))
+            return false;
+          mbs_align_t alignment = isdigit (to_uchar (*abbr))
+                                  ? MBS_ALIGN_RIGHT : MBS_ALIGN_LEFT;
+          size_t req = mbsalign (abbr, abmon[i], ABFORMAT_SIZE,
+                                 &width, alignment, 0);
+          if (! (req < ABFORMAT_SIZE))
+            return false;
+          required_mon_width = MAX (required_mon_width, width);
+        }
+    }
+  while (curr_max_width > required_mon_width);
+
+  return true;
+#endif
+}
+
+/* Initialize ABFORMAT and USE_ABFORMAT.  */
+
+static void
+abformat_init (void)
+{
+  char const *pb[2];
+  for (int recent = 0; recent < 2; recent++)
+    pb[recent] = first_percent_b (long_time_format[recent]);
+  if (! (pb[0] || pb[1]))
+    return;
+
+  char abmon[12][ABFORMAT_SIZE];
+  if (! abmon_init (abmon))
+    return;
+
+  for (int recent = 0; recent < 2; recent++)
+    {
+      char const *fmt = long_time_format[recent];
+      for (int i = 0; i < 12; i++)
+        {
+          char *nfmt = abformat[recent][i];
+          int nbytes;
+
+          if (! pb[recent])
+            nbytes = snprintf (nfmt, ABFORMAT_SIZE, "%s", fmt);
+          else
+            {
+              if (! (pb[recent] - fmt <= MIN (ABFORMAT_SIZE, INT_MAX)))
+                return;
+              int prefix_len = pb[recent] - fmt;
+              nbytes = snprintf (nfmt, ABFORMAT_SIZE, "%.*s%s%s",
+                                 prefix_len, fmt, abmon[i], pb[recent] + 2);
+            }
+
+          if (! (0 <= nbytes && nbytes < ABFORMAT_SIZE))
+            return;
+        }
+    }
+
+  use_abformat = true;
+}
+
+static size_t
+dev_ino_hash (void const *x, size_t table_size)
+{
+  struct dev_ino const *p = x;
+  return (uintmax_t) p->st_ino % table_size;
+}
+
+static bool
+dev_ino_compare (void const *x, void const *y)
+{
+  struct dev_ino const *a = x;
+  struct dev_ino const *b = y;
+  return SAME_INODE (*a, *b) ? true : false;
+}
+
+static void
+dev_ino_free (void *x)
+{
+  free (x);
+}
+
+/* Add the device/inode pair (P->st_dev/P->st_ino) to the set of
+   active directories.  Return true if there is already a matching
+   entry in the table.  */
+
+static bool
+visit_dir (dev_t dev, ino_t ino)
+{
+  struct dev_ino *ent;
+  struct dev_ino *ent_from_table;
+  bool found_match;
+
+  ent = xmalloc (sizeof *ent);
+  ent->st_ino = ino;
+  ent->st_dev = dev;
+
+  /* Attempt to insert this entry into the table.  */
+  ent_from_table = hash_insert (active_dir_set, ent);
+
+  if (ent_from_table == NULL)
+    {
+      /* Insertion failed due to lack of memory.  */
+      xalloc_die ();
+    }
+
+  found_match = (ent_from_table != ent);
+
+  if (found_match)
+    {
+      /* ent was not inserted, so free it.  */
+      free (ent);
+    }
+
+  return found_match;
+}
+
+static void
+free_pending_ent (struct pending *p)
+{
+  free (p->name);
+  free (p->realname);
+  free (p);
+}
+
+static bool
+is_colored (enum indicator_no type)
+{
+  size_t len = color_indicator[type].len;
+  char const *s = color_indicator[type].string;
+  return ! (len == 0
+            || (len == 1 && STRNCMP_LIT (s, "0") == 0)
+            || (len == 2 && STRNCMP_LIT (s, "00") == 0));
+}
+
+static void
+restore_default_color (void)
+{
+  put_indicator (&color_indicator[C_LEFT]);
+  put_indicator (&color_indicator[C_RIGHT]);
+}
+
+static void
+set_normal_color (void)
+{
+  if (print_with_color && is_colored (C_NORM))
+    {
+      put_indicator (&color_indicator[C_LEFT]);
+      put_indicator (&color_indicator[C_NORM]);
+      put_indicator (&color_indicator[C_RIGHT]);
+    }
+}
+
+/* An ordinary signal was received; arrange for the program to exit.  */
+
+static void
+sighandler (int sig)
+{
+  if (! SA_NOCLDSTOP)
+    signal (sig, SIG_IGN);
+  if (! interrupt_signal)
+    interrupt_signal = sig;
+}
+
+/* A SIGTSTP was received; arrange for the program to suspend itself.  */
+
+static void
+stophandler (int sig)
+{
+  if (! SA_NOCLDSTOP)
+    signal (sig, stophandler);
+  if (! interrupt_signal)
+    stop_signal_count++;
+}
+
+/* Process any pending signals.  If signals are caught, this function
+   should be called periodically.  Ideally there should never be an
+   unbounded amount of time when signals are not being processed.
+   Signal handling can restore the default colors, so callers must
+   immediately change colors after invoking this function.  */
+
+static void
+process_signals (void)
+{
+  while (interrupt_signal || stop_signal_count)
+    {
+      int sig;
+      int stops;
+      sigset_t oldset;
+
+      if (used_color)
+        restore_default_color ();
+      fflush (stdout);
+
+      sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
+
+      /* Reload interrupt_signal and stop_signal_count, in case a new
+         signal was handled before sigprocmask took effect.  */
+      sig = interrupt_signal;
+      stops = stop_signal_count;
+
+      /* SIGTSTP is special, since the application can receive that signal
+         more than once.  In this case, don't set the signal handler to the
+         default.  Instead, just raise the uncatchable SIGSTOP.  */
+      if (stops)
+        {
+          stop_signal_count = stops - 1;
+          sig = SIGSTOP;
+        }
+      else
+        signal (sig, SIG_DFL);
+
+      /* Exit or suspend the program.  */
+      raise (sig);
+      sigprocmask (SIG_SETMASK, &oldset, NULL);
+
+      /* If execution reaches here, then the program has been
+         continued (after being suspended).  */
+    }
+}
+
+/* Setup signal handlers if INIT is true,
+   otherwise restore to the default.  */
+
+static void
+signal_setup (bool init)
+{
+  /* The signals that are trapped, and the number of such signals.  */
+  static int const sig[] =
+    {
+      /* This one is handled specially.  */
+      SIGTSTP,
+
+      /* The usual suspects.  */
+      SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
+#ifdef SIGPOLL
+      SIGPOLL,
+#endif
+#ifdef SIGPROF
+      SIGPROF,
+#endif
+#ifdef SIGVTALRM
+      SIGVTALRM,
+#endif
+#ifdef SIGXCPU
+      SIGXCPU,
+#endif
+#ifdef SIGXFSZ
+      SIGXFSZ,
+#endif
+    };
+  enum { nsigs = ARRAY_CARDINALITY (sig) };
+
+#if ! SA_NOCLDSTOP
+  static bool caught_sig[nsigs];
+#endif
+
+  int j;
+
+  if (init)
+    {
+#if SA_NOCLDSTOP
+      struct sigaction act;
+
+      sigemptyset (&caught_signals);
+      for (j = 0; j < nsigs; j++)
+        {
+          sigaction (sig[j], NULL, &act);
+          if (act.sa_handler != SIG_IGN)
+            sigaddset (&caught_signals, sig[j]);
+        }
+
+      act.sa_mask = caught_signals;
+      act.sa_flags = SA_RESTART;
+
+      for (j = 0; j < nsigs; j++)
+        if (sigismember (&caught_signals, sig[j]))
+          {
+            act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler;
+            sigaction (sig[j], &act, NULL);
+          }
+#else
+      for (j = 0; j < nsigs; j++)
+        {
+          caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN);
+          if (caught_sig[j])
+            {
+              signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler);
+              siginterrupt (sig[j], 0);
+            }
+        }
+#endif
+    }
+  else /* restore.  */
+    {
+#if SA_NOCLDSTOP
+      for (j = 0; j < nsigs; j++)
+        if (sigismember (&caught_signals, sig[j]))
+          signal (sig[j], SIG_DFL);
+#else
+      for (j = 0; j < nsigs; j++)
+        if (caught_sig[j])
+          signal (sig[j], SIG_DFL);
+#endif
+    }
+}
+
+static inline void
+signal_init (void)
+{
+  signal_setup (true);
+}
+
+static inline void
+signal_restore (void)
+{
+  signal_setup (false);
+}
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  struct pending *thispend;
+  int n_files;
+
+  initialize_main (&argc, &argv);
+  set_program_name (argv[0]);
+  setlocale (LC_ALL, "");
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
+  initialize_exit_failure (LS_FAILURE);
+  atexit (close_stdout);
+
+  assert (ARRAY_CARDINALITY (color_indicator) + 1
+          == ARRAY_CARDINALITY (indicator_name));
+
+  exit_status = EXIT_SUCCESS;
+  print_dir_name = true;
+  pending_dirs = NULL;
+
+  current_time.tv_sec = TYPE_MINIMUM (time_t);
+  current_time.tv_nsec = -1;
+
+  i = decode_switches (argc, argv);
+
+  if (print_with_color)
+    parse_ls_color ();
+
+  /* Test print_with_color again, because the call to parse_ls_color
+     may have just reset it -- e.g., if LS_COLORS is invalid.  */
+  if (directories_first)
+    check_symlink_mode = true;
+  else if (print_with_color)
+    {
+      /* Avoid following symbolic links when possible.  */
+      if (is_colored (C_ORPHAN)
+          || (is_colored (C_EXEC) && color_symlink_as_referent)
+          || (is_colored (C_MISSING) && format == long_format))
+        check_symlink_mode = true;
+    }
+
+  if (dereference == DEREF_UNDEFINED)
+    dereference = ((immediate_dirs
+                    || indicator_style == classify
+                    || format == long_format)
+                   ? DEREF_NEVER
+                   : DEREF_COMMAND_LINE_SYMLINK_TO_DIR);
+
+  /* When using -R, initialize a data structure we'll use to
+     detect any directory cycles.  */
+  if (recursive)
+    {
+      active_dir_set = hash_initialize (INITIAL_TABLE_SIZE, NULL,
+                                        dev_ino_hash,
+                                        dev_ino_compare,
+                                        dev_ino_free);
+      if (active_dir_set == NULL)
+        xalloc_die ();
+
+      obstack_init (&dev_ino_obstack);
+    }
+
+  localtz = tzalloc (getenv ("TZ"));
+
+  format_needs_stat = sort_type == sort_time || sort_type == sort_size
+    || format == long_format
+    || print_scontext
+    || print_block_size;
+  format_needs_type = (! format_needs_stat
+                       && (recursive
+                           || print_with_color
+                           || indicator_style != none
+                           || directories_first));
+
+  if (dired)
+    {
+      obstack_init (&dired_obstack);
+      obstack_init (&subdired_obstack);
+    }
+
+  if (print_hyperlink)
+    {
+      file_escape_init ();
+
+      hostname = xgethostname ();
+      /* The hostname is generally ignored,
+         so ignore failures obtaining it.  */
+      if (! hostname)
+        hostname = "";
+    }
+
+  cwd_n_alloc = 100;
+  cwd_file = xnmalloc (cwd_n_alloc, sizeof *cwd_file);
+  cwd_n_used = 0;
+
+  clear_files ();
+
+  n_files = argc - i;
+
+  if (n_files <= 0)
+    {
+      if (immediate_dirs)
+        gobble_file (".", directory, NOT_AN_INODE_NUMBER, true, "");
+      else
+        queue_directory (".", NULL, true);
+    }
+  else
+    do
+      gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, "");
+    while (i < argc);
+
+  if (cwd_n_used)
+    {
+      sort_files ();
+      if (!immediate_dirs)
+        extract_dirs_from_files (NULL, true);
+      /* 'cwd_n_used' might be zero now.  */
+    }
+
+  /* In the following if/else blocks, it is sufficient to test 'pending_dirs'
+     (and not pending_dirs->name) because there may be no markers in the queue
+     at this point.  A marker may be enqueued when extract_dirs_from_files is
+     called with a non-empty string or via print_dir.  */
+  if (cwd_n_used)
+    {
+      print_current_files ();
+      if (pending_dirs)
+        DIRED_PUTCHAR ('\n');
+    }
+  else if (n_files <= 1 && pending_dirs && pending_dirs->next == 0)
+    print_dir_name = false;
+
+  while (pending_dirs)
+    {
+      thispend = pending_dirs;
+      pending_dirs = pending_dirs->next;
+
+      if (LOOP_DETECT)
+        {
+          if (thispend->name == NULL)
+            {
+              /* thispend->name == NULL means this is a marker entry
+                 indicating we've finished processing the directory.
+                 Use its dev/ino numbers to remove the corresponding
+                 entry from the active_dir_set hash table.  */
+              struct dev_ino di = dev_ino_pop ();
+              struct dev_ino *found = hash_delete (active_dir_set, &di);
+              /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */
+              assert (found);
+              dev_ino_free (found);
+              free_pending_ent (thispend);
+              continue;
+            }
+        }
+
+      print_dir (thispend->name, thispend->realname,
+                 thispend->command_line_arg);
+
+      free_pending_ent (thispend);
+      print_dir_name = true;
+    }
+
+  if (print_with_color && used_color)
+    {
+      int j;
+
+      /* Skip the restore when it would be a no-op, i.e.,
+         when left is "\033[" and right is "m".  */
+      if (!(color_indicator[C_LEFT].len == 2
+            && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0
+            && color_indicator[C_RIGHT].len == 1
+            && color_indicator[C_RIGHT].string[0] == 'm'))
+        restore_default_color ();
+
+      fflush (stdout);
+
+      signal_restore ();
+
+      /* Act on any signals that arrived before the default was restored.
+         This can process signals out of order, but there doesn't seem to
+         be an easy way to do them in order, and the order isn't that
+         important anyway.  */
+      for (j = stop_signal_count; j; j--)
+        raise (SIGSTOP);
+      j = interrupt_signal;
+      if (j)
+        raise (j);
+    }
+
+  if (dired)
+    {
+      /* No need to free these since we're about to exit.  */
+      dired_dump_obstack ("//DIRED//", &dired_obstack);
+      dired_dump_obstack ("//SUBDIRED//", &subdired_obstack);
+      printf ("//DIRED-OPTIONS// --quoting-style=%s\n",
+              quoting_style_args[get_quoting_style (filename_quoting_options)]);
+    }
+
+  if (LOOP_DETECT)
+    {
+      assert (hash_get_n_entries (active_dir_set) == 0);
+      hash_free (active_dir_set);
+    }
+
+  return exit_status;
+}
+
+/* Set the line length to the value given by SPEC.  Return true if
+   successful.  0 means no limit on line length.  */
+
+static bool
+set_line_length (char const *spec)
+{
+  uintmax_t val;
+
+  /* Treat too-large values as if they were SIZE_MAX, which is
+     effectively infinity.  */
+  switch (xstrtoumax (spec, NULL, 0, &val, ""))
+    {
+    case LONGINT_OK:
+      line_length = MIN (val, SIZE_MAX);
+      return true;
+
+    case LONGINT_OVERFLOW:
+      line_length = SIZE_MAX;
+      return true;
+
+    default:
+      return false;
+    }
+}
+
+/* Set all the option flags according to the switches specified.
+   Return the index of the first non-option argument.  */
+
+static int
+decode_switches (int argc, char **argv)
+{
+  char *time_style_option = NULL;
+
+  bool sort_type_specified = false;
+  bool kibibytes_specified = false;
+
+  qmark_funny_chars = false;
+
+  /* initialize all switches to default settings */
+
+  switch (ls_mode)
+    {
+    case LS_MULTI_COL:
+      /* This is for the 'dir' program.  */
+      format = many_per_line;
+      set_quoting_style (NULL, escape_quoting_style);
+      break;
+
+    case LS_LONG_FORMAT:
+      /* This is for the 'vdir' program.  */
+      format = long_format;
+      set_quoting_style (NULL, escape_quoting_style);
+      break;
+
+    case LS_LS:
+      /* This is for the 'ls' program.  */
+      if (isatty (STDOUT_FILENO))
+        {
+          format = many_per_line;
+          /* See description of qmark_funny_chars, above.  */
+          qmark_funny_chars = true;
+        }
+      else
+        {
+          format = one_per_line;
+          qmark_funny_chars = false;
+        }
+      break;
+
+    default:
+      abort ();
+    }
+
+  time_type = time_mtime;
+  sort_type = sort_name;
+  sort_reverse = false;
+  numeric_ids = false;
+  print_block_size = false;
+  indicator_style = none;
+  print_inode = false;
+  dereference = DEREF_UNDEFINED;
+  recursive = false;
+  immediate_dirs = false;
+  ignore_mode = IGNORE_DEFAULT;
+  ignore_patterns = NULL;
+  hide_patterns = NULL;
+  print_scontext = false;
+
+  getenv_quoting_style ();
+
+  line_length = 80;
+  {
+    char const *p = getenv ("COLUMNS");
+    if (p && *p && ! set_line_length (p))
+      error (0, 0,
+             _("ignoring invalid width in environment variable COLUMNS: %s"),
+             quote (p));
+  }
+
+#ifdef TIOCGWINSZ
+  {
+    struct winsize ws;
+
+    if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1
+        && 0 < ws.ws_col && ws.ws_col == (size_t) ws.ws_col)
+      line_length = ws.ws_col;
+  }
+#endif
+
+  {
+    char const *p = getenv ("TABSIZE");
+    tabsize = 8;
+    if (p)
+      {
+        uintmax_t tmp;
+        if (xstrtoumax (p, NULL, 0, &tmp, "") == LONGINT_OK
+            && tmp <= SIZE_MAX)
+          tabsize = tmp;
+        else
+          error (0, 0,
+                 _("ignoring invalid tab size in environment variable TABSIZE:"
+                   " %s"),
+                 quote (p));
+      }
+  }
+
+  while (true)
+    {
+      int oi = -1;
+      int c = getopt_long (argc, argv,
+                           "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
+                           long_options, &oi);
+      if (c == -1)
+        break;
+
+      switch (c)
+        {
+        case 'a':
+          ignore_mode = IGNORE_MINIMAL;
+          break;
+
+        case 'b':
+          set_quoting_style (NULL, escape_quoting_style);
+          break;
+
+        case 'c':
+          time_type = time_ctime;
+          break;
+
+        case 'd':
+          immediate_dirs = true;
+          break;
+
+        case 'f':
+          /* Same as enabling -a -U and disabling -l -s.  */
+          ignore_mode = IGNORE_MINIMAL;
+          sort_type = sort_none;
+          sort_type_specified = true;
+          /* disable -l */
+          if (format == long_format)
+            format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
+          print_block_size = false;	/* disable -s */
+          print_with_color = false;	/* disable --color */
+          print_hyperlink = false;	/* disable --hyperlink */
+          break;
+
+        case FILE_TYPE_INDICATOR_OPTION: /* --file-type */
+          indicator_style = file_type;
+          break;
+
+        case 'g':
+          format = long_format;
+          print_owner = false;
+          break;
+
+        case 'h':
+          file_human_output_opts = human_output_opts =
+            human_autoscale | human_SI | human_base_1024;
+          file_output_block_size = output_block_size = 1;
+          break;
+
+        case 'i':
+          print_inode = true;
+          break;
+
+        case 'k':
+          kibibytes_specified = true;
+          break;
+
+        case 'l':
+          format = long_format;
+          break;
+
+        case 'm':
+          format = with_commas;
+          break;
+
+        case 'n':
+          numeric_ids = true;
+          format = long_format;
+          break;
+
+        case 'o':  /* Just like -l, but don't display group info.  */
+          format = long_format;
+          print_group = false;
+          break;
+
+        case 'p':
+          indicator_style = slash;
+          break;
+
+        case 'q':
+          qmark_funny_chars = true;
+          break;
+
+        case 'r':
+          sort_reverse = true;
+          break;
+
+        case 's':
+          print_block_size = true;
+          break;
+
+        case 't':
+          sort_type = sort_time;
+          sort_type_specified = true;
+          break;
+
+        case 'u':
+          time_type = time_atime;
+          break;
+
+        case 'v':
+          sort_type = sort_version;
+          sort_type_specified = true;
+          break;
+
+        case 'w':
+          if (! set_line_length (optarg))
+            die (LS_FAILURE, 0, "%s: %s", _("invalid line width"),
+                 quote (optarg));
+          break;
+
+        case 'x':
+          format = horizontal;
+          break;
+
+        case 'A':
+          ignore_mode = IGNORE_DOT_AND_DOTDOT;
+          break;
+
+        case 'B':
+          add_ignore_pattern ("*~");
+          add_ignore_pattern (".*~");
+          break;
+
+        case 'C':
+          format = many_per_line;
+          break;
+
+        case 'D':
+          dired = true;
+          break;
+
+        case 'F':
+          indicator_style = classify;
+          break;
+
+        case 'G':		/* inhibit display of group info */
+          print_group = false;
+          break;
+
+        case 'H':
+          dereference = DEREF_COMMAND_LINE_ARGUMENTS;
+          break;
+
+        case DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION:
+          dereference = DEREF_COMMAND_LINE_SYMLINK_TO_DIR;
+          break;
+
+        case 'I':
+          add_ignore_pattern (optarg);
+          break;
+
+        case 'L':
+          dereference = DEREF_ALWAYS;
+          break;
+
+        case 'N':
+          set_quoting_style (NULL, literal_quoting_style);
+          break;
+
+        case 'Q':
+          set_quoting_style (NULL, c_quoting_style);
+          break;
+
+        case 'R':
+          recursive = true;
+          break;
+
+        case 'S':
+          sort_type = sort_size;
+          sort_type_specified = true;
+          break;
+
+        case 'T':
+          tabsize = xnumtoumax (optarg, 0, 0, SIZE_MAX, "",
+                                _("invalid tab size"), LS_FAILURE);
+          break;
+
+        case 'U':
+          sort_type = sort_none;
+          sort_type_specified = true;
+          break;
+
+        case 'X':
+          sort_type = sort_extension;
+          sort_type_specified = true;
+          break;
+
+        case '1':
+          /* -1 has no effect after -l.  */
+          if (format != long_format)
+            format = one_per_line;
+          break;
+
+        case AUTHOR_OPTION:
+          print_author = true;
+          break;
+
+        case HIDE_OPTION:
+          {
+            struct ignore_pattern *hide = xmalloc (sizeof *hide);
+            hide->pattern = optarg;
+            hide->next = hide_patterns;
+            hide_patterns = hide;
+          }
+          break;
+
+        case SORT_OPTION:
+          sort_type = XARGMATCH ("--sort", optarg, sort_args, sort_types);
+          sort_type_specified = true;
+          break;
+
+        case GROUP_DIRECTORIES_FIRST_OPTION:
+          directories_first = true;
+          break;
+
+        case TIME_OPTION:
+          time_type = XARGMATCH ("--time", optarg, time_args, time_types);
+          break;
+
+        case FORMAT_OPTION:
+          format = XARGMATCH ("--format", optarg, format_args, format_types);
+          break;
+
+        case FULL_TIME_OPTION:
+          format = long_format;
+          time_style_option = bad_cast ("full-iso");
+          break;
+
+        case COLOR_OPTION:
+          {
+            int i;
+            if (optarg)
+              i = XARGMATCH ("--color", optarg, when_args, when_types);
+            else
+              /* Using --color with no argument is equivalent to using
+                 --color=always.  */
+              i = when_always;
+
+            print_with_color = (i == when_always
+                                || (i == when_if_tty
+                                    && isatty (STDOUT_FILENO)));
+
+            if (print_with_color)
+              {
+                /* Don't use TAB characters in output.  Some terminal
+                   emulators can't handle the combination of tabs and
+                   color codes on the same line.  */
+                tabsize = 0;
+              }
+            break;
+          }
+
+        case HYPERLINK_OPTION:
+          {
+            int i;
+            if (optarg)
+              i = XARGMATCH ("--hyperlink", optarg, when_args, when_types);
+            else
+              /* Using --hyperlink with no argument is equivalent to using
+                 --hyperlink=always.  */
+              i = when_always;
+
+            print_hyperlink = (i == when_always
+                               || (i == when_if_tty
+                                   && isatty (STDOUT_FILENO)));
+            break;
+          }
+
+        case INDICATOR_STYLE_OPTION:
+          indicator_style = XARGMATCH ("--indicator-style", optarg,
+                                       indicator_style_args,
+                                       indicator_style_types);
+          break;
+
+        case QUOTING_STYLE_OPTION:
+          set_quoting_style (NULL,
+                             XARGMATCH ("--quoting-style", optarg,
+                                        quoting_style_args,
+                                        quoting_style_vals));
+          break;
+
+        case TIME_STYLE_OPTION:
+          time_style_option = optarg;
+          break;
+
+        case SHOW_CONTROL_CHARS_OPTION:
+          qmark_funny_chars = false;
+          break;
+
+        case BLOCK_SIZE_OPTION:
+          {
+            enum strtol_error e = human_options (optarg, &human_output_opts,
+                                                 &output_block_size);
+            if (e != LONGINT_OK)
+              xstrtol_fatal (e, oi, 0, long_options, optarg);
+            file_human_output_opts = human_output_opts;
+            file_output_block_size = output_block_size;
+          }
+          break;
+
+        case SI_OPTION:
+          file_human_output_opts = human_output_opts =
+            human_autoscale | human_SI;
+          file_output_block_size = output_block_size = 1;
+          break;
+
+        case 'Z':
+          print_scontext = true;
+          break;
+
+        case_GETOPT_HELP_CHAR;
+
+        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+        default:
+          usage (LS_FAILURE);
+        }
+    }
+
+  if (! output_block_size)
+    {
+      char const *ls_block_size = getenv ("LS_BLOCK_SIZE");
+      human_options (ls_block_size,
+                     &human_output_opts, &output_block_size);
+      if (ls_block_size || getenv ("BLOCK_SIZE"))
+        {
+          file_human_output_opts = human_output_opts;
+          file_output_block_size = output_block_size;
+        }
+      if (kibibytes_specified)
+        {
+          human_output_opts = 0;
+          output_block_size = 1024;
+        }
+    }
+
+  /* Determine the max possible number of display columns.  */
+  max_idx = line_length / MIN_COLUMN_WIDTH;
+  /* Account for first display column not having a separator,
+     or line_lengths shorter than MIN_COLUMN_WIDTH.  */
+  max_idx += line_length % MIN_COLUMN_WIDTH != 0;
+
+  enum quoting_style qs = get_quoting_style (NULL);
+  align_variable_outer_quotes = format != with_commas
+                                && format != one_per_line
+                                && (line_length || format == long_format)
+                                && (qs == shell_quoting_style
+                                    || qs == shell_escape_quoting_style
+                                    || qs == c_maybe_quoting_style);
+  filename_quoting_options = clone_quoting_options (NULL);
+  if (qs == escape_quoting_style)
+    set_char_quoting (filename_quoting_options, ' ', 1);
+  if (file_type <= indicator_style)
+    {
+      char const *p;
+      for (p = &"*=>@|"[indicator_style - file_type]; *p; p++)
+        set_char_quoting (filename_quoting_options, *p, 1);
+    }
+
+  dirname_quoting_options = clone_quoting_options (NULL);
+  set_char_quoting (dirname_quoting_options, ':', 1);
+
+  /* --dired is meaningful only with --format=long (-l).
+     Otherwise, ignore it.  FIXME: warn about this?
+     Alternatively, make --dired imply --format=long?  */
+  if (dired && (format != long_format || print_hyperlink))
+    dired = false;
+
+  /* If -c or -u is specified and not -l (or any other option that implies -l),
+     and no sort-type was specified, then sort by the ctime (-c) or atime (-u).
+     The behavior of ls when using either -c or -u but with neither -l nor -t
+     appears to be unspecified by POSIX.  So, with GNU ls, '-u' alone means
+     sort by atime (this is the one that's not specified by the POSIX spec),
+     -lu means show atime and sort by name, -lut means show atime and sort
+     by atime.  */
+
+  if ((time_type == time_ctime || time_type == time_atime
+       || time_type == time_btime)
+      && !sort_type_specified && format != long_format)
+    {
+      sort_type = sort_time;
+    }
+
+  if (format == long_format)
+    {
+      char *style = time_style_option;
+      static char const posix_prefix[] = "posix-";
+
+      if (! style)
+        if (! (style = getenv ("TIME_STYLE")))
+          style = bad_cast ("locale");
+
+      while (STREQ_LEN (style, posix_prefix, sizeof posix_prefix - 1))
+        {
+          if (! hard_locale (LC_TIME))
+            return optind;
+          style += sizeof posix_prefix - 1;
+        }
+
+      if (*style == '+')
+        {
+          char *p0 = style + 1;
+          char *p1 = strchr (p0, '\n');
+          if (! p1)
+            p1 = p0;
+          else
+            {
+              if (strchr (p1 + 1, '\n'))
+                die (LS_FAILURE, 0, _("invalid time style format %s"),
+                     quote (p0));
+              *p1++ = '\0';
+            }
+          long_time_format[0] = p0;
+          long_time_format[1] = p1;
+        }
+      else
+        {
+          ptrdiff_t res = argmatch (style, time_style_args,
+                                    (char const *) time_style_types,
+                                    sizeof (*time_style_types));
+          if (res < 0)
+            {
+              /* This whole block used to be a simple use of XARGMATCH.
+                 but that didn't print the "posix-"-prefixed variants or
+                 the "+"-prefixed format string option upon failure.  */
+              argmatch_invalid ("time style", style, res);
+
+              /* The following is a manual expansion of argmatch_valid,
+                 but with the added "+ ..." description and the [posix-]
+                 prefixes prepended.  Note that this simplification works
+                 only because all four existing time_style_types values
+                 are distinct.  */
+              fputs (_("Valid arguments are:\n"), stderr);
+              char const *const *p = time_style_args;
+              while (*p)
+                fprintf (stderr, "  - [posix-]%s\n", *p++);
+              fputs (_("  - +FORMAT (e.g., +%H:%M) for a 'date'-style"
+                       " format\n"), stderr);
+              usage (LS_FAILURE);
+            }
+          switch (res)
+            {
+            case full_iso_time_style:
+              long_time_format[0] = long_time_format[1] =
+                "%Y-%m-%d %H:%M:%S.%N %z";
+              break;
+
+            case long_iso_time_style:
+              long_time_format[0] = long_time_format[1] = "%Y-%m-%d %H:%M";
+              break;
+
+            case iso_time_style:
+              long_time_format[0] = "%Y-%m-%d ";
+              long_time_format[1] = "%m-%d %H:%M";
+              break;
+
+            case locale_time_style:
+              if (hard_locale (LC_TIME))
+                {
+                  for (int i = 0; i < 2; i++)
+                    long_time_format[i] =
+                      dcgettext (NULL, long_time_format[i], LC_TIME);
+                }
+            }
+        }
+
+      abformat_init ();
+    }
+
+  return optind;
+}
+
+/* Parse a string as part of the LS_COLORS variable; this may involve
+   decoding all kinds of escape characters.  If equals_end is set an
+   unescaped equal sign ends the string, otherwise only a : or \0
+   does.  Set *OUTPUT_COUNT to the number of bytes output.  Return
+   true if successful.
+
+   The resulting string is *not* null-terminated, but may contain
+   embedded nulls.
+
+   Note that both dest and src are char **; on return they point to
+   the first free byte after the array and the character that ended
+   the input string, respectively.  */
+
+static bool
+get_funky_string (char **dest, const char **src, bool equals_end,
+                  size_t *output_count)
+{
+  char num;			/* For numerical codes */
+  size_t count;			/* Something to count with */
+  enum {
+    ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR
+  } state;
+  const char *p;
+  char *q;
+
+  p = *src;			/* We don't want to double-indirect */
+  q = *dest;			/* the whole darn time.  */
+
+  count = 0;			/* No characters counted in yet.  */
+  num = 0;
+
+  state = ST_GND;		/* Start in ground state.  */
+  while (state < ST_END)
+    {
+      switch (state)
+        {
+        case ST_GND:		/* Ground state (no escapes) */
+          switch (*p)
+            {
+            case ':':
+            case '\0':
+              state = ST_END;	/* End of string */
+              break;
+            case '\\':
+              state = ST_BACKSLASH; /* Backslash escape sequence */
+              ++p;
+              break;
+            case '^':
+              state = ST_CARET; /* Caret escape */
+              ++p;
+              break;
+            case '=':
+              if (equals_end)
+                {
+                  state = ST_END; /* End */
+                  break;
+                }
+              FALLTHROUGH;
+            default:
+              *(q++) = *(p++);
+              ++count;
+              break;
+            }
+          break;
+
+        case ST_BACKSLASH:	/* Backslash escaped character */
+          switch (*p)
+            {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+              state = ST_OCTAL;	/* Octal sequence */
+              num = *p - '0';
+              break;
+            case 'x':
+            case 'X':
+              state = ST_HEX;	/* Hex sequence */
+              num = 0;
+              break;
+            case 'a':		/* Bell */
+              num = '\a';
+              break;
+            case 'b':		/* Backspace */
+              num = '\b';
+              break;
+            case 'e':		/* Escape */
+              num = 27;
+              break;
+            case 'f':		/* Form feed */
+              num = '\f';
+              break;
+            case 'n':		/* Newline */
+              num = '\n';
+              break;
+            case 'r':		/* Carriage return */
+              num = '\r';
+              break;
+            case 't':		/* Tab */
+              num = '\t';
+              break;
+            case 'v':		/* Vtab */
+              num = '\v';
+              break;
+            case '?':		/* Delete */
+              num = 127;
+              break;
+            case '_':		/* Space */
+              num = ' ';
+              break;
+            case '\0':		/* End of string */
+              state = ST_ERROR;	/* Error! */
+              break;
+            default:		/* Escaped character like \ ^ : = */
+              num = *p;
+              break;
+            }
+          if (state == ST_BACKSLASH)
+            {
+              *(q++) = num;
+              ++count;
+              state = ST_GND;
+            }
+          ++p;
+          break;
+
+        case ST_OCTAL:		/* Octal sequence */
+          if (*p < '0' || *p > '7')
+            {
+              *(q++) = num;
+              ++count;
+              state = ST_GND;
+            }
+          else
+            num = (num << 3) + (*(p++) - '0');
+          break;
+
+        case ST_HEX:		/* Hex sequence */
+          switch (*p)
+            {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+              num = (num << 4) + (*(p++) - '0');
+              break;
+            case 'a':
+            case 'b':
+            case 'c':
+            case 'd':
+            case 'e':
+            case 'f':
+              num = (num << 4) + (*(p++) - 'a') + 10;
+              break;
+            case 'A':
+            case 'B':
+            case 'C':
+            case 'D':
+            case 'E':
+            case 'F':
+              num = (num << 4) + (*(p++) - 'A') + 10;
+              break;
+            default:
+              *(q++) = num;
+              ++count;
+              state = ST_GND;
+              break;
+            }
+          break;
+
+        case ST_CARET:		/* Caret escape */
+          state = ST_GND;	/* Should be the next state... */
+          if (*p >= '@' && *p <= '~')
+            {
+              *(q++) = *(p++) & 037;
+              ++count;
+            }
+          else if (*p == '?')
+            {
+              *(q++) = 127;
+              ++count;
+            }
+          else
+            state = ST_ERROR;
+          break;
+
+        default:
+          abort ();
+        }
+    }
+
+  *dest = q;
+  *src = p;
+  *output_count = count;
+
+  return state != ST_ERROR;
+}
+
+enum parse_state
+  {
+    PS_START = 1,
+    PS_2,
+    PS_3,
+    PS_4,
+    PS_DONE,
+    PS_FAIL
+  };
+
+
+/* Check if the content of TERM is a valid name in dircolors.  */
+
+static bool
+known_term_type (void)
+{
+  char const *term = getenv ("TERM");
+  if (! term || ! *term)
+    return false;
+
+  char const *line = G_line;
+  while (line - G_line < sizeof (G_line))
+    {
+      if (STRNCMP_LIT (line, "TERM ") == 0)
+        {
+          if (fnmatch (line + 5, term, 0) == 0)
+            return true;
+        }
+      line += strlen (line) + 1;
+    }
+
+  return false;
+}
+
+static void
+parse_ls_color (void)
+{
+  const char *p;		/* Pointer to character being parsed */
+  char *buf;			/* color_buf buffer pointer */
+  int ind_no;			/* Indicator number */
+  char label[3];		/* Indicator label */
+  struct color_ext_type *ext;	/* Extension we are working on */
+
+  if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0')
+    {
+      /* LS_COLORS takes precedence, but if that's not set then
+         honor the COLORTERM and TERM env variables so that
+         we only go with the internal ANSI color codes if the
+         former is non empty or the latter is set to a known value.  */
+      char const *colorterm = getenv ("COLORTERM");
+      if (! (colorterm && *colorterm) && ! known_term_type ())
+        print_with_color = false;
+      return;
+    }
+
+  ext = NULL;
+  strcpy (label, "??");
+
+  /* This is an overly conservative estimate, but any possible
+     LS_COLORS string will *not* generate a color_buf longer than
+     itself, so it is a safe way of allocating a buffer in
+     advance.  */
+  buf = color_buf = xstrdup (p);
+
+  enum parse_state state = PS_START;
+  while (true)
+    {
+      switch (state)
+        {
+        case PS_START:		/* First label character */
+          switch (*p)
+            {
+            case ':':
+              ++p;
+              break;
+
+            case '*':
+              /* Allocate new extension block and add to head of
+                 linked list (this way a later definition will
+                 override an earlier one, which can be useful for
+                 having terminal-specific defs override global).  */
+
+              ext = xmalloc (sizeof *ext);
+              ext->next = color_ext_list;
+              color_ext_list = ext;
+
+              ++p;
+              ext->ext.string = buf;
+
+              state = (get_funky_string (&buf, &p, true, &ext->ext.len)
+                       ? PS_4 : PS_FAIL);
+              break;
+
+            case '\0':
+              state = PS_DONE;	/* Done! */
+              goto done;
+
+            default:	/* Assume it is file type label */
+              label[0] = *(p++);
+              state = PS_2;
+              break;
+            }
+          break;
+
+        case PS_2:		/* Second label character */
+          if (*p)
+            {
+              label[1] = *(p++);
+              state = PS_3;
+            }
+          else
+            state = PS_FAIL;	/* Error */
+          break;
+
+        case PS_3:		/* Equal sign after indicator label */
+          state = PS_FAIL;	/* Assume failure...  */
+          if (*(p++) == '=')/* It *should* be...  */
+            {
+              for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no)
+                {
+                  if (STREQ (label, indicator_name[ind_no]))
+                    {
+                      color_indicator[ind_no].string = buf;
+                      state = (get_funky_string (&buf, &p, false,
+                                                 &color_indicator[ind_no].len)
+                               ? PS_START : PS_FAIL);
+                      break;
+                    }
+                }
+              if (state == PS_FAIL)
+                error (0, 0, _("unrecognized prefix: %s"), quote (label));
+            }
+          break;
+
+        case PS_4:		/* Equal sign after *.ext */
+          if (*(p++) == '=')
+            {
+              ext->seq.string = buf;
+              state = (get_funky_string (&buf, &p, false, &ext->seq.len)
+                       ? PS_START : PS_FAIL);
+            }
+          else
+            state = PS_FAIL;
+          break;
+
+        case PS_FAIL:
+          goto done;
+
+        default:
+          abort ();
+        }
+    }
+ done:
+
+  if (state == PS_FAIL)
+    {
+      struct color_ext_type *e;
+      struct color_ext_type *e2;
+
+      error (0, 0,
+             _("unparsable value for LS_COLORS environment variable"));
+      free (color_buf);
+      for (e = color_ext_list; e != NULL; /* empty */)
+        {
+          e2 = e;
+          e = e->next;
+          free (e2);
+        }
+      print_with_color = false;
+    }
+
+  if (color_indicator[C_LINK].len == 6
+      && !STRNCMP_LIT (color_indicator[C_LINK].string, "target"))
+    color_symlink_as_referent = true;
+}
+
+/* Set the quoting style default if the environment variable
+   QUOTING_STYLE is set.  */
+
+static void
+getenv_quoting_style (void)
+{
+  char const *q_style = getenv ("QUOTING_STYLE");
+  if (q_style)
+    {
+      int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals);
+      if (0 <= i)
+        set_quoting_style (NULL, quoting_style_vals[i]);
+      else
+        error (0, 0,
+       _("ignoring invalid value of environment variable QUOTING_STYLE: %s"),
+               quote (q_style));
+    }
+}
+
+/* Set the exit status to report a failure.  If SERIOUS, it is a
+   serious failure; otherwise, it is merely a minor problem.  */
+
+static void
+set_exit_status (bool serious)
+{
+  if (serious)
+    exit_status = LS_FAILURE;
+  else if (exit_status == EXIT_SUCCESS)
+    exit_status = LS_MINOR_PROBLEM;
+}
+
+/* Assuming a failure is serious if SERIOUS, use the printf-style
+   MESSAGE to report the failure to access a file named FILE.  Assume
+   errno is set appropriately for the failure.  */
+
+static void
+file_failure (bool serious, char const *message, char const *file)
+{
+  error (0, errno, message, quoteaf (file));
+  set_exit_status (serious);
+}
+
+/* Request that the directory named NAME have its contents listed later.
+   If REALNAME is nonzero, it will be used instead of NAME when the
+   directory name is printed.  This allows symbolic links to directories
+   to be treated as regular directories but still be listed under their
+   real names.  NAME == NULL is used to insert a marker entry for the
+   directory named in REALNAME.
+   If NAME is non-NULL, we use its dev/ino information to save
+   a call to stat -- when doing a recursive (-R) traversal.
+   COMMAND_LINE_ARG means this directory was mentioned on the command line.  */
+
+static void
+queue_directory (char const *name, char const *realname, bool command_line_arg)
+{
+  struct pending *new = xmalloc (sizeof *new);
+  new->realname = realname ? xstrdup (realname) : NULL;
+  new->name = name ? xstrdup (name) : NULL;
+  new->command_line_arg = command_line_arg;
+  new->next = pending_dirs;
+  pending_dirs = new;
+}
+
+/* Read directory NAME, and list the files in it.
+   If REALNAME is nonzero, print its name instead of NAME;
+   this is used for symbolic links to directories.
+   COMMAND_LINE_ARG means this directory was mentioned on the command line.  */
+
+static void
+print_dir (char const *name, char const *realname, bool command_line_arg)
+{
+  DIR *dirp;
+  struct dirent *next;
+  uintmax_t total_blocks = 0;
+  static bool first = true;
+  bool found_any_entries = false;
+
+  errno = 0;
+  dirp = opendir (name);
+  if (!dirp)
+    {
+      file_failure (command_line_arg, _("cannot open directory %s"), name);
+      return;
+    }
+
+  if (LOOP_DETECT)
+    {
+      struct stat dir_stat;
+      int fd = dirfd (dirp);
+
+      /* If dirfd failed, endure the overhead of stat'ing by path  */
+      if ((0 <= fd
+           ? fstat_for_ino (fd, &dir_stat)
+           : stat_for_ino (name, &dir_stat)) < 0)
+        {
+          file_failure (command_line_arg,
+                        _("cannot determine device and inode of %s"), name);
+          closedir (dirp);
+          return;
+        }
+
+      /* If we've already visited this dev/inode pair, warn that
+         we've found a loop, and do not process this directory.  */
+      if (visit_dir (dir_stat.st_dev, dir_stat.st_ino))
+        {
+          error (0, 0, _("%s: not listing already-listed directory"),
+                 quotef (name));
+          closedir (dirp);
+          set_exit_status (true);
+          return;
+        }
+
+      dev_ino_push (dir_stat.st_dev, dir_stat.st_ino);
+    }
+
+  clear_files ();
+
+  if (recursive || print_dir_name)
+    {
+      if (!first)
+        DIRED_PUTCHAR ('\n');
+      first = false;
+      DIRED_INDENT ();
+
+      char *absolute_name = NULL;
+      if (print_hyperlink)
+        {
+          absolute_name = canonicalize_filename_mode (name, CAN_MISSING);
+          if (! absolute_name)
+            file_failure (command_line_arg,
+                          _("error canonicalizing %s"), name);
+        }
+      quote_name (realname ? realname : name, dirname_quoting_options, -1,
+                  NULL, true, &subdired_obstack, absolute_name);
+
+      free (absolute_name);
+
+      DIRED_FPUTS_LITERAL (":\n", stdout);
+    }
+
+  /* Read the directory entries, and insert the subfiles into the 'cwd_file'
+     table.  */
+
+  while (1)
+    {
+      /* Set errno to zero so we can distinguish between a readdir failure
+         and when readdir simply finds that there are no more entries.  */
+      errno = 0;
+      next = readdir (dirp);
+      if (next)
+        {
+          found_any_entries = true;
+          if (! file_ignored (next->d_name))
+            {
+              enum filetype type = unknown;
+
+#if HAVE_STRUCT_DIRENT_D_TYPE
+              switch (next->d_type)
+                {
+                case DT_BLK:  type = blockdev;		break;
+                case DT_CHR:  type = chardev;		break;
+                case DT_DIR:  type = directory;		break;
+                case DT_FIFO: type = fifo;		break;
+                case DT_LNK:  type = symbolic_link;	break;
+                case DT_REG:  type = normal;		break;
+                case DT_SOCK: type = sock;		break;
+# ifdef DT_WHT
+                case DT_WHT:  type = whiteout;		break;
+# endif
+                }
+#endif
+              total_blocks += gobble_file (next->d_name, type,
+                                           RELIABLE_D_INO (next),
+                                           false, name);
+
+              /* In this narrow case, print out each name right away, so
+                 ls uses constant memory while processing the entries of
+                 this directory.  Useful when there are many (millions)
+                 of entries in a directory.  */
+              if (format == one_per_line && sort_type == sort_none
+                      && !print_block_size && !recursive)
+                {
+                  /* We must call sort_files in spite of
+                     "sort_type == sort_none" for its initialization
+                     of the sorted_file vector.  */
+                  sort_files ();
+                  print_current_files ();
+                  clear_files ();
+                }
+            }
+        }
+      else if (errno != 0)
+        {
+          file_failure (command_line_arg, _("reading directory %s"), name);
+          if (errno != EOVERFLOW)
+            break;
+        }
+#ifdef __linux__
+      else if (! found_any_entries)
+        {
+          /* If readdir finds no directory entries at all, not even "." or
+             "..", then double check that the directory exists.  */
+          if (syscall (SYS_getdents, dirfd (dirp), NULL, 0) == -1
+              && errno != EINVAL)
+            {
+              /* We exclude EINVAL as that pertains to buffer handling,
+                 and we've passed NULL as the buffer for simplicity.
+                 ENOENT is returned if appropriate before buffer handling.  */
+              file_failure (command_line_arg, _("reading directory %s"), name);
+            }
+          break;
+        }
+#endif
+      else
+        break;
+
+      /* When processing a very large directory, and since we've inhibited
+         interrupts, this loop would take so long that ls would be annoyingly
+         uninterruptible.  This ensures that it handles signals promptly.  */
+      process_signals ();
+    }
+
+  if (closedir (dirp) != 0)
+    {
+      file_failure (command_line_arg, _("closing directory %s"), name);
+      /* Don't return; print whatever we got.  */
+    }
+
+  /* Sort the directory contents.  */
+  sort_files ();
+
+  /* If any member files are subdirectories, perhaps they should have their
+     contents listed rather than being mentioned here as files.  */
+
+  if (recursive)
+    extract_dirs_from_files (name, false);
+
+  if (format == long_format || print_block_size)
+    {
+      const char *p;
+      char buf[LONGEST_HUMAN_READABLE + 1];
+
+      DIRED_INDENT ();
+      p = _("total");
+      DIRED_FPUTS (p, stdout, strlen (p));
+      DIRED_PUTCHAR (' ');
+      p = human_readable (total_blocks, buf, human_output_opts,
+                          ST_NBLOCKSIZE, output_block_size);
+      DIRED_FPUTS (p, stdout, strlen (p));
+      DIRED_PUTCHAR ('\n');
+    }
+
+  if (cwd_n_used)
+    print_current_files ();
+}
+
+/* Add 'pattern' to the list of patterns for which files that match are
+   not listed.  */
+
+static void
+add_ignore_pattern (const char *pattern)
+{
+  struct ignore_pattern *ignore;
+
+  ignore = xmalloc (sizeof *ignore);
+  ignore->pattern = pattern;
+  /* Add it to the head of the linked list.  */
+  ignore->next = ignore_patterns;
+  ignore_patterns = ignore;
+}
+
+/* Return true if one of the PATTERNS matches FILE.  */
+
+static bool
+patterns_match (struct ignore_pattern const *patterns, char const *file)
+{
+  struct ignore_pattern const *p;
+  for (p = patterns; p; p = p->next)
+    if (fnmatch (p->pattern, file, FNM_PERIOD) == 0)
+      return true;
+  return false;
+}
+
+/* Return true if FILE should be ignored.  */
+
+static bool
+file_ignored (char const *name)
+{
+  return ((ignore_mode != IGNORE_MINIMAL
+           && name[0] == '.'
+           && (ignore_mode == IGNORE_DEFAULT || ! name[1 + (name[1] == '.')]))
+          || (ignore_mode == IGNORE_DEFAULT
+              && patterns_match (hide_patterns, name))
+          || patterns_match (ignore_patterns, name));
+}
+
+/* POSIX requires that a file size be printed without a sign, even
+   when negative.  Assume the typical case where negative sizes are
+   actually positive values that have wrapped around.  */
+
+static uintmax_t
+unsigned_file_size (off_t size)
+{
+  return size + (size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1);
+}
+
+#ifdef HAVE_CAP
+/* Return true if NAME has a capability (see linux/capability.h) */
+static bool
+has_capability (char const *name)
+{
+  char *result;
+  bool has_cap;
+
+  cap_t cap_d = cap_get_file (name);
+  if (cap_d == NULL)
+    return false;
+
+  result = cap_to_text (cap_d, NULL);
+  cap_free (cap_d);
+  if (!result)
+    return false;
+
+  /* check if human-readable capability string is empty */
+  has_cap = !!*result;
+
+  cap_free (result);
+  return has_cap;
+}
+#else
+static bool
+has_capability (char const *name _GL_UNUSED)
+{
+  errno = ENOTSUP;
+  return false;
+}
+#endif
+
+/* Enter and remove entries in the table 'cwd_file'.  */
+
+static void
+free_ent (struct fileinfo *f)
+{
+  free (f->name);
+  free (f->linkname);
+  free (f->absolute_name);
+  if (f->scontext != UNKNOWN_SECURITY_CONTEXT)
+    {
+      if (is_smack_enabled ())
+        free (f->scontext);
+      else
+        freecon (f->scontext);
+    }
+}
+
+/* Empty the table of files.  */
+static void
+clear_files (void)
+{
+  for (size_t i = 0; i < cwd_n_used; i++)
+    {
+      struct fileinfo *f = sorted_file[i];
+      free_ent (f);
+    }
+
+  cwd_n_used = 0;
+  cwd_some_quoted = false;
+  any_has_acl = false;
+  inode_number_width = 0;
+  block_size_width = 0;
+  nlink_width = 0;
+  owner_width = 0;
+  group_width = 0;
+  author_width = 0;
+  scontext_width = 0;
+  major_device_number_width = 0;
+  minor_device_number_width = 0;
+  file_size_width = 0;
+}
+
+/* Return true if ERR implies lack-of-support failure by a
+   getxattr-calling function like getfilecon or file_has_acl.  */
+static bool
+errno_unsupported (int err)
+{
+  return (err == EINVAL || err == ENOSYS || is_ENOTSUP (err));
+}
+
+/* Cache *getfilecon failure, when it's trivial to do so.
+   Like getfilecon/lgetfilecon, but when F's st_dev says it's doesn't
+   support getting the security context, fail with ENOTSUP immediately.  */
+static int
+getfilecon_cache (char const *file, struct fileinfo *f, bool deref)
+{
+  /* st_dev of the most recently processed device for which we've
+     found that [l]getfilecon fails indicating lack of support.  */
+  static dev_t unsupported_device;
+
+  if (f->stat.st_dev == unsupported_device)
+    {
+      errno = ENOTSUP;
+      return -1;
+    }
+  int r = 0;
+#ifdef HAVE_SMACK
+  if (is_smack_enabled ())
+    r = smack_new_label_from_path (file, "security.SMACK64", deref,
+                                   &f->scontext);
+  else
+#endif
+    r = (deref
+         ? getfilecon (file, &f->scontext)
+         : lgetfilecon (file, &f->scontext));
+  if (r < 0 && errno_unsupported (errno))
+    unsupported_device = f->stat.st_dev;
+  return r;
+}
+
+/* Cache file_has_acl failure, when it's trivial to do.
+   Like file_has_acl, but when F's st_dev says it's on a file
+   system lacking ACL support, return 0 with ENOTSUP immediately.  */
+static int
+file_has_acl_cache (char const *file, struct fileinfo *f)
+{
+  /* st_dev of the most recently processed device for which we've
+     found that file_has_acl fails indicating lack of support.  */
+  static dev_t unsupported_device;
+
+  if (f->stat.st_dev == unsupported_device)
+    {
+      errno = ENOTSUP;
+      return 0;
+    }
+
+  /* Zero errno so that we can distinguish between two 0-returning cases:
+     "has-ACL-support, but only a default ACL" and "no ACL support". */
+  errno = 0;
+  int n = file_has_acl (file, &f->stat);
+  if (n <= 0 && errno_unsupported (errno))
+    unsupported_device = f->stat.st_dev;
+  return n;
+}
+
+/* Cache has_capability failure, when it's trivial to do.
+   Like has_capability, but when F's st_dev says it's on a file
+   system lacking capability support, return 0 with ENOTSUP immediately.  */
+static bool
+has_capability_cache (char const *file, struct fileinfo *f)
+{
+  /* st_dev of the most recently processed device for which we've
+     found that has_capability fails indicating lack of support.  */
+  static dev_t unsupported_device;
+
+  if (f->stat.st_dev == unsupported_device)
+    {
+      errno = ENOTSUP;
+      return 0;
+    }
+
+  bool b = has_capability (file);
+  if ( !b && errno_unsupported (errno))
+    unsupported_device = f->stat.st_dev;
+  return b;
+}
+
+static bool
+needs_quoting (char const* name)
+{
+  char test[2];
+  size_t len = quotearg_buffer (test, sizeof test , name, -1,
+                                filename_quoting_options);
+  return *name != *test || strlen (name) != len;
+}
+
+/* Add a file to the current table of files.
+   Verify that the file exists, and print an error message if it does not.
+   Return the number of blocks that the file occupies.  */
+static uintmax_t
+gobble_file (char const *name, enum filetype type, ino_t inode,
+             bool command_line_arg, char const *dirname)
+{
+  uintmax_t blocks = 0;
+  struct fileinfo *f;
+
+  /* An inode value prior to gobble_file necessarily came from readdir,
+     which is not used for command line arguments.  */
+  assert (! command_line_arg || inode == NOT_AN_INODE_NUMBER);
+
+  if (cwd_n_used == cwd_n_alloc)
+    {
+      cwd_file = xnrealloc (cwd_file, cwd_n_alloc, 2 * sizeof *cwd_file);
+      cwd_n_alloc *= 2;
+    }
+
+  f = &cwd_file[cwd_n_used];
+  memset (f, '\0', sizeof *f);
+  f->stat.st_ino = inode;
+  f->filetype = type;
+
+  f->quoted = -1;
+  if ((! cwd_some_quoted) && align_variable_outer_quotes)
+    {
+      /* Determine if any quoted for padding purposes.  */
+      f->quoted = needs_quoting (name);
+      if (f->quoted)
+        cwd_some_quoted = 1;
+    }
+
+  if (command_line_arg
+      || print_hyperlink
+      || format_needs_stat
+      /* When coloring a directory (we may know the type from
+         direct.d_type), we have to stat it in order to indicate
+         sticky and/or other-writable attributes.  */
+      || (type == directory && print_with_color
+          && (is_colored (C_OTHER_WRITABLE)
+              || is_colored (C_STICKY)
+              || is_colored (C_STICKY_OTHER_WRITABLE)))
+      /* When dereferencing symlinks, the inode and type must come from
+         stat, but readdir provides the inode and type of lstat.  */
+      || ((print_inode || format_needs_type)
+          && (type == symbolic_link || type == unknown)
+          && (dereference == DEREF_ALWAYS
+              || color_symlink_as_referent || check_symlink_mode))
+      /* Command line dereferences are already taken care of by the above
+         assertion that the inode number is not yet known.  */
+      || (print_inode && inode == NOT_AN_INODE_NUMBER)
+      || (format_needs_type
+          && (type == unknown || command_line_arg
+              /* --indicator-style=classify (aka -F)
+                 requires that we stat each regular file
+                 to see if it's executable.  */
+              || (type == normal && (indicator_style == classify
+                                     /* This is so that --color ends up
+                                        highlighting files with these mode
+                                        bits set even when options like -F are
+                                        not specified.  Note we do a redundant
+                                        stat in the very unlikely case where
+                                        C_CAP is set but not the others. */
+                                     || (print_with_color
+                                         && (is_colored (C_EXEC)
+                                             || is_colored (C_SETUID)
+                                             || is_colored (C_SETGID)
+                                             || is_colored (C_CAP)))
+                                     )))))
+
+    {
+      /* Absolute name of this file.  */
+      char *full_name;
+      bool do_deref;
+      int err;
+
+      if (name[0] == '/' || dirname[0] == 0)
+        full_name = (char *) name;
+      else
+        {
+          full_name = alloca (strlen (name) + strlen (dirname) + 2);
+          attach (full_name, dirname, name);
+        }
+
+      if (print_hyperlink)
+        {
+          f->absolute_name = canonicalize_filename_mode (full_name,
+                                                         CAN_MISSING);
+          if (! f->absolute_name)
+            file_failure (command_line_arg,
+                          _("error canonicalizing %s"), full_name);
+        }
+
+      switch (dereference)
+        {
+        case DEREF_ALWAYS:
+          err = do_stat (full_name, &f->stat);
+          do_deref = true;
+          break;
+
+        case DEREF_COMMAND_LINE_ARGUMENTS:
+        case DEREF_COMMAND_LINE_SYMLINK_TO_DIR:
+          if (command_line_arg)
+            {
+              bool need_lstat;
+              err = do_stat (full_name, &f->stat);
+              do_deref = true;
+
+              if (dereference == DEREF_COMMAND_LINE_ARGUMENTS)
+                break;
+
+              need_lstat = (err < 0
+                            ? errno == ENOENT
+                            : ! S_ISDIR (f->stat.st_mode));
+              if (!need_lstat)
+                break;
+
+              /* stat failed because of ENOENT, maybe indicating a dangling
+                 symlink.  Or stat succeeded, FULL_NAME does not refer to a
+                 directory, and --dereference-command-line-symlink-to-dir is
+                 in effect.  Fall through so that we call lstat instead.  */
+            }
+          FALLTHROUGH;
+
+        default: /* DEREF_NEVER */
+          err = do_lstat (full_name, &f->stat);
+          do_deref = false;
+          break;
+        }
+
+      if (err != 0)
+        {
+          /* Failure to stat a command line argument leads to
+             an exit status of 2.  For other files, stat failure
+             provokes an exit status of 1.  */
+          file_failure (command_line_arg,
+                        _("cannot access %s"), full_name);
+          if (command_line_arg)
+            return 0;
+
+          f->name = xstrdup (name);
+          cwd_n_used++;
+
+          return 0;
+        }
+
+      f->stat_ok = true;
+
+      /* Note has_capability() adds around 30% runtime to 'ls --color'  */
+      if ((type == normal || S_ISREG (f->stat.st_mode))
+          && print_with_color && is_colored (C_CAP))
+        f->has_capability = has_capability_cache (full_name, f);
+
+      if (format == long_format || print_scontext)
+        {
+          bool have_scontext = false;
+          bool have_acl = false;
+          int attr_len = getfilecon_cache (full_name, f, do_deref);
+          err = (attr_len < 0);
+
+          if (err == 0)
+            {
+              if (is_smack_enabled ())
+                have_scontext = ! STREQ ("_", f->scontext);
+              else
+                have_scontext = ! STREQ ("unlabeled", f->scontext);
+            }
+          else
+            {
+              f->scontext = UNKNOWN_SECURITY_CONTEXT;
+
+              /* When requesting security context information, don't make
+                 ls fail just because the file (even a command line argument)
+                 isn't on the right type of file system.  I.e., a getfilecon
+                 failure isn't in the same class as a stat failure.  */
+              if (is_ENOTSUP (errno) || errno == ENODATA)
+                err = 0;
+            }
+
+          if (err == 0 && format == long_format)
+            {
+              int n = file_has_acl_cache (full_name, f);
+              err = (n < 0);
+              have_acl = (0 < n);
+            }
+
+          f->acl_type = (!have_scontext && !have_acl
+                         ? ACL_T_NONE
+                         : (have_scontext && !have_acl
+                            ? ACL_T_LSM_CONTEXT_ONLY
+                            : ACL_T_YES));
+          any_has_acl |= f->acl_type != ACL_T_NONE;
+
+          if (err)
+            error (0, errno, "%s", quotef (full_name));
+        }
+
+      if (S_ISLNK (f->stat.st_mode)
+          && (format == long_format || check_symlink_mode))
+        {
+          struct stat linkstats;
+
+          get_link_name (full_name, f, command_line_arg);
+          char *linkname = make_link_name (full_name, f->linkname);
+
+          /* Use the slower quoting path for this entry, though
+             don't update CWD_SOME_QUOTED since alignment not affected.  */
+          if (linkname && f->quoted == 0 && needs_quoting (f->linkname))
+            f->quoted = -1;
+
+          /* Avoid following symbolic links when possible, ie, when
+             they won't be traced and when no indicator is needed.  */
+          if (linkname
+              && (file_type <= indicator_style || check_symlink_mode)
+              && stat_for_mode (linkname, &linkstats) == 0)
+            {
+              f->linkok = true;
+              f->linkmode = linkstats.st_mode;
+            }
+          free (linkname);
+        }
+
+      if (S_ISLNK (f->stat.st_mode))
+        f->filetype = symbolic_link;
+      else if (S_ISDIR (f->stat.st_mode))
+        {
+          if (command_line_arg && !immediate_dirs)
+            f->filetype = arg_directory;
+          else
+            f->filetype = directory;
+        }
+      else
+        f->filetype = normal;
+
+      blocks = ST_NBLOCKS (f->stat);
+      if (format == long_format || print_block_size)
+        {
+          char buf[LONGEST_HUMAN_READABLE + 1];
+          int len = mbswidth (human_readable (blocks, buf, human_output_opts,
+                                              ST_NBLOCKSIZE, output_block_size),
+                              0);
+          if (block_size_width < len)
+            block_size_width = len;
+        }
+
+      if (format == long_format)
+        {
+          if (print_owner)
+            {
+              int len = format_user_width (f->stat.st_uid);
+              if (owner_width < len)
+                owner_width = len;
+            }
+
+          if (print_group)
+            {
+              int len = format_group_width (f->stat.st_gid);
+              if (group_width < len)
+                group_width = len;
+            }
+
+          if (print_author)
+            {
+              int len = format_user_width (f->stat.st_author);
+              if (author_width < len)
+                author_width = len;
+            }
+        }
+
+      if (print_scontext)
+        {
+          int len = strlen (f->scontext);
+          if (scontext_width < len)
+            scontext_width = len;
+        }
+
+      if (format == long_format)
+        {
+          char b[INT_BUFSIZE_BOUND (uintmax_t)];
+          int b_len = strlen (umaxtostr (f->stat.st_nlink, b));
+          if (nlink_width < b_len)
+            nlink_width = b_len;
+
+          if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))
+            {
+              char buf[INT_BUFSIZE_BOUND (uintmax_t)];
+              int len = strlen (umaxtostr (major (f->stat.st_rdev), buf));
+              if (major_device_number_width < len)
+                major_device_number_width = len;
+              len = strlen (umaxtostr (minor (f->stat.st_rdev), buf));
+              if (minor_device_number_width < len)
+                minor_device_number_width = len;
+              len = major_device_number_width + 2 + minor_device_number_width;
+              if (file_size_width < len)
+                file_size_width = len;
+            }
+          else
+            {
+              char buf[LONGEST_HUMAN_READABLE + 1];
+              uintmax_t size = unsigned_file_size (f->stat.st_size);
+              int len = mbswidth (human_readable (size, buf,
+                                                  file_human_output_opts,
+                                                  1, file_output_block_size),
+                                  0);
+              if (file_size_width < len)
+                file_size_width = len;
+            }
+        }
+    }
+
+  if (print_inode)
+    {
+      char buf[INT_BUFSIZE_BOUND (uintmax_t)];
+      int len = strlen (umaxtostr (f->stat.st_ino, buf));
+      if (inode_number_width < len)
+        inode_number_width = len;
+    }
+
+  f->name = xstrdup (name);
+  cwd_n_used++;
+
+  return blocks;
+}
+
+/* Return true if F refers to a directory.  */
+static bool
+is_directory (const struct fileinfo *f)
+{
+  return f->filetype == directory || f->filetype == arg_directory;
+}
+
+/* Return true if F refers to a (symlinked) directory.  */
+static bool
+is_linked_directory (const struct fileinfo *f)
+{
+  return f->filetype == directory || f->filetype == arg_directory
+         || S_ISDIR (f->linkmode);
+}
+
+/* Put the name of the file that FILENAME is a symbolic link to
+   into the LINKNAME field of 'f'.  COMMAND_LINE_ARG indicates whether
+   FILENAME is a command-line argument.  */
+
+static void
+get_link_name (char const *filename, struct fileinfo *f, bool command_line_arg)
+{
+  f->linkname = areadlink_with_size (filename, f->stat.st_size);
+  if (f->linkname == NULL)
+    file_failure (command_line_arg, _("cannot read symbolic link %s"),
+                  filename);
+}
+
+/* If LINKNAME is a relative name and NAME contains one or more
+   leading directories, return LINKNAME with those directories
+   prepended; otherwise, return a copy of LINKNAME.
+   If LINKNAME is NULL, return NULL.  */
+
+static char *
+make_link_name (char const *name, char const *linkname)
+{
+  if (!linkname)
+    return NULL;
+
+  if (IS_ABSOLUTE_FILE_NAME (linkname))
+    return xstrdup (linkname);
+
+  /* The link is to a relative name.  Prepend any leading directory
+     in 'name' to the link name.  */
+  size_t prefix_len = dir_len (name);
+  if (prefix_len == 0)
+    return xstrdup (linkname);
+
+  char *p = xmalloc (prefix_len + 1 + strlen (linkname) + 1);
+
+  /* PREFIX_LEN usually specifies a string not ending in slash.
+     In that case, extend it by one, since the next byte *is* a slash.
+     Otherwise, the prefix is "/", so leave the length unchanged.  */
+  if ( ! ISSLASH (name[prefix_len - 1]))
+    ++prefix_len;
+
+  stpcpy (stpncpy (p, name, prefix_len), linkname);
+  return p;
+}
+
+/* Return true if the last component of NAME is '.' or '..'
+   This is so we don't try to recurse on '././././. ...' */
+
+static bool
+basename_is_dot_or_dotdot (const char *name)
+{
+  char const *base = last_component (name);
+  return dot_or_dotdot (base);
+}
+
+/* Remove any entries from CWD_FILE that are for directories,
+   and queue them to be listed as directories instead.
+   DIRNAME is the prefix to prepend to each dirname
+   to make it correct relative to ls's working dir;
+   if it is null, no prefix is needed and "." and ".." should not be ignored.
+   If COMMAND_LINE_ARG is true, this directory was mentioned at the top level,
+   This is desirable when processing directories recursively.  */
+
+static void
+extract_dirs_from_files (char const *dirname, bool command_line_arg)
+{
+  size_t i;
+  size_t j;
+  bool ignore_dot_and_dot_dot = (dirname != NULL);
+
+  if (dirname && LOOP_DETECT)
+    {
+      /* Insert a marker entry first.  When we dequeue this marker entry,
+         we'll know that DIRNAME has been processed and may be removed
+         from the set of active directories.  */
+      queue_directory (NULL, dirname, false);
+    }
+
+  /* Queue the directories last one first, because queueing reverses the
+     order.  */
+  for (i = cwd_n_used; i-- != 0; )
+    {
+      struct fileinfo *f = sorted_file[i];
+
+      if (is_directory (f)
+          && (! ignore_dot_and_dot_dot
+              || ! basename_is_dot_or_dotdot (f->name)))
+        {
+          if (!dirname || f->name[0] == '/')
+            queue_directory (f->name, f->linkname, command_line_arg);
+          else
+            {
+              char *name = file_name_concat (dirname, f->name, NULL);
+              queue_directory (name, f->linkname, command_line_arg);
+              free (name);
+            }
+          if (f->filetype == arg_directory)
+            free_ent (f);
+        }
+    }
+
+  /* Now delete the directories from the table, compacting all the remaining
+     entries.  */
+
+  for (i = 0, j = 0; i < cwd_n_used; i++)
+    {
+      struct fileinfo *f = sorted_file[i];
+      sorted_file[j] = f;
+      j += (f->filetype != arg_directory);
+    }
+  cwd_n_used = j;
+}
+
+/* Use strcoll to compare strings in this locale.  If an error occurs,
+   report an error and longjmp to failed_strcoll.  */
+
+static jmp_buf failed_strcoll;
+
+static int
+xstrcoll (char const *a, char const *b)
+{
+  int diff;
+  errno = 0;
+  diff = strcoll (a, b);
+  if (errno)
+    {
+      error (0, errno, _("cannot compare file names %s and %s"),
+             quote_n (0, a), quote_n (1, b));
+      set_exit_status (false);
+      longjmp (failed_strcoll, 1);
+    }
+  return diff;
+}
+
+/* Comparison routines for sorting the files.  */
+
+typedef void const *V;
+typedef int (*qsortFunc)(V a, V b);
+
+/* Used below in DEFINE_SORT_FUNCTIONS for _df_ sort function variants.
+   The do { ... } while(0) makes it possible to use the macro more like
+   a statement, without violating C89 rules: */
+#define DIRFIRST_CHECK(a, b)						\
+  do									\
+    {									\
+      bool a_is_dir = is_linked_directory ((struct fileinfo const *) a);\
+      bool b_is_dir = is_linked_directory ((struct fileinfo const *) b);\
+      if (a_is_dir && !b_is_dir)					\
+        return -1;         /* a goes before b */			\
+      if (!a_is_dir && b_is_dir)					\
+        return 1;          /* b goes before a */			\
+    }									\
+  while (0)
+
+/* Define the 8 different sort function variants required for each sortkey.
+   KEY_NAME is a token describing the sort key, e.g., ctime, atime, size.
+   KEY_CMP_FUNC is a function to compare records based on that key, e.g.,
+   ctime_cmp, atime_cmp, size_cmp.  Append KEY_NAME to the string,
+   '[rev_][x]str{cmp|coll}[_df]_', to create each function name.  */
+#define DEFINE_SORT_FUNCTIONS(key_name, key_cmp_func)			\
+  /* direct, non-dirfirst versions */					\
+  static int xstrcoll_##key_name (V a, V b)				\
+  { return key_cmp_func (a, b, xstrcoll); }				\
+  static int _GL_ATTRIBUTE_PURE strcmp_##key_name (V a, V b)		\
+  { return key_cmp_func (a, b, strcmp); }				\
+                                                                        \
+  /* reverse, non-dirfirst versions */					\
+  static int rev_xstrcoll_##key_name (V a, V b)				\
+  { return key_cmp_func (b, a, xstrcoll); }				\
+  static int _GL_ATTRIBUTE_PURE rev_strcmp_##key_name (V a, V b)	\
+  { return key_cmp_func (b, a, strcmp); }				\
+                                                                        \
+  /* direct, dirfirst versions */					\
+  static int xstrcoll_df_##key_name (V a, V b)				\
+  { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, xstrcoll); }	\
+  static int _GL_ATTRIBUTE_PURE strcmp_df_##key_name (V a, V b)		\
+  { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, strcmp); }	\
+                                                                        \
+  /* reverse, dirfirst versions */					\
+  static int rev_xstrcoll_df_##key_name (V a, V b)			\
+  { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, xstrcoll); }	\
+  static int _GL_ATTRIBUTE_PURE rev_strcmp_df_##key_name (V a, V b)	\
+  { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, strcmp); }
+
+static inline int
+cmp_ctime (struct fileinfo const *a, struct fileinfo const *b,
+           int (*cmp) (char const *, char const *))
+{
+  int diff = timespec_cmp (get_stat_ctime (&b->stat),
+                           get_stat_ctime (&a->stat));
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_mtime (struct fileinfo const *a, struct fileinfo const *b,
+           int (*cmp) (char const *, char const *))
+{
+  int diff = timespec_cmp (get_stat_mtime (&b->stat),
+                           get_stat_mtime (&a->stat));
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_atime (struct fileinfo const *a, struct fileinfo const *b,
+           int (*cmp) (char const *, char const *))
+{
+  int diff = timespec_cmp (get_stat_atime (&b->stat),
+                           get_stat_atime (&a->stat));
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_btime (struct fileinfo const *a, struct fileinfo const *b,
+           int (*cmp) (char const *, char const *))
+{
+  int diff = timespec_cmp (get_stat_btime (&b->stat),
+                           get_stat_btime (&a->stat));
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_size (struct fileinfo const *a, struct fileinfo const *b,
+          int (*cmp) (char const *, char const *))
+{
+  int diff = longdiff (b->stat.st_size, a->stat.st_size);
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_name (struct fileinfo const *a, struct fileinfo const *b,
+          int (*cmp) (char const *, char const *))
+{
+  return cmp (a->name, b->name);
+}
+
+/* Compare file extensions.  Files with no extension are 'smallest'.
+   If extensions are the same, compare by file names instead.  */
+
+static inline int
+cmp_extension (struct fileinfo const *a, struct fileinfo const *b,
+               int (*cmp) (char const *, char const *))
+{
+  char const *base1 = strrchr (a->name, '.');
+  char const *base2 = strrchr (b->name, '.');
+  int diff = cmp (base1 ? base1 : "", base2 ? base2 : "");
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+DEFINE_SORT_FUNCTIONS (ctime, cmp_ctime)
+DEFINE_SORT_FUNCTIONS (mtime, cmp_mtime)
+DEFINE_SORT_FUNCTIONS (atime, cmp_atime)
+DEFINE_SORT_FUNCTIONS (btime, cmp_btime)
+DEFINE_SORT_FUNCTIONS (size, cmp_size)
+DEFINE_SORT_FUNCTIONS (name, cmp_name)
+DEFINE_SORT_FUNCTIONS (extension, cmp_extension)
+
+/* Compare file versions.
+   Unlike all other compare functions above, cmp_version depends only
+   on filevercmp, which does not fail (even for locale reasons), and does not
+   need a secondary sort key. See lib/filevercmp.h for function description.
+
+   All the other sort options, in fact, need xstrcoll and strcmp variants,
+   because they all use a string comparison (either as the primary or secondary
+   sort key), and xstrcoll has the ability to do a longjmp if strcoll fails for
+   locale reasons.  Lastly, filevercmp is ALWAYS available with gnulib.  */
+static inline int
+cmp_version (struct fileinfo const *a, struct fileinfo const *b)
+{
+  return filevercmp (a->name, b->name);
+}
+
+static int xstrcoll_version (V a, V b)
+{ return cmp_version (a, b); }
+static int rev_xstrcoll_version (V a, V b)
+{ return cmp_version (b, a); }
+static int xstrcoll_df_version (V a, V b)
+{ DIRFIRST_CHECK (a, b); return cmp_version (a, b); }
+static int rev_xstrcoll_df_version (V a, V b)
+{ DIRFIRST_CHECK (a, b); return cmp_version (b, a); }
+
+
+/* We have 2^3 different variants for each sort-key function
+   (for 3 independent sort modes).
+   The function pointers stored in this array must be dereferenced as:
+
+    sort_variants[sort_key][use_strcmp][reverse][dirs_first]
+
+   Note that the order in which sort keys are listed in the function pointer
+   array below is defined by the order of the elements in the time_type and
+   sort_type enums!  */
+
+#define LIST_SORTFUNCTION_VARIANTS(key_name)                        \
+  {                                                                 \
+    {                                                               \
+      { xstrcoll_##key_name, xstrcoll_df_##key_name },              \
+      { rev_xstrcoll_##key_name, rev_xstrcoll_df_##key_name },      \
+    },                                                              \
+    {                                                               \
+      { strcmp_##key_name, strcmp_df_##key_name },                  \
+      { rev_strcmp_##key_name, rev_strcmp_df_##key_name },          \
+    }                                                               \
+  }
+
+static qsortFunc const sort_functions[][2][2][2] =
+  {
+    LIST_SORTFUNCTION_VARIANTS (name),
+    LIST_SORTFUNCTION_VARIANTS (extension),
+    LIST_SORTFUNCTION_VARIANTS (size),
+
+    {
+      {
+        { xstrcoll_version, xstrcoll_df_version },
+        { rev_xstrcoll_version, rev_xstrcoll_df_version },
+      },
+
+      /* We use NULL for the strcmp variants of version comparison
+         since as explained in cmp_version definition, version comparison
+         does not rely on xstrcoll, so it will never longjmp, and never
+         need to try the strcmp fallback. */
+      {
+        { NULL, NULL },
+        { NULL, NULL },
+      }
+    },
+
+    /* last are time sort functions */
+    LIST_SORTFUNCTION_VARIANTS (mtime),
+    LIST_SORTFUNCTION_VARIANTS (ctime),
+    LIST_SORTFUNCTION_VARIANTS (atime),
+    LIST_SORTFUNCTION_VARIANTS (btime)
+  };
+
+/* The number of sort keys is calculated as the sum of
+     the number of elements in the sort_type enum (i.e., sort_numtypes)
+     the number of elements in the time_type enum (i.e., time_numtypes) - 1
+   This is because when sort_type==sort_time, we have up to
+   time_numtypes possible sort keys.
+
+   This line verifies at compile-time that the array of sort functions has been
+   initialized for all possible sort keys. */
+verify (ARRAY_CARDINALITY (sort_functions)
+        == sort_numtypes + time_numtypes - 1 );
+
+/* Set up SORTED_FILE to point to the in-use entries in CWD_FILE, in order.  */
+
+static void
+initialize_ordering_vector (void)
+{
+  for (size_t i = 0; i < cwd_n_used; i++)
+    sorted_file[i] = &cwd_file[i];
+}
+
+/* Sort the files now in the table.  */
+
+static void
+sort_files (void)
+{
+  bool use_strcmp;
+
+  if (sorted_file_alloc < cwd_n_used + cwd_n_used / 2)
+    {
+      free (sorted_file);
+      sorted_file = xnmalloc (cwd_n_used, 3 * sizeof *sorted_file);
+      sorted_file_alloc = 3 * cwd_n_used;
+    }
+
+  initialize_ordering_vector ();
+
+  if (sort_type == sort_none)
+    return;
+
+  /* Try strcoll.  If it fails, fall back on strcmp.  We can't safely
+     ignore strcoll failures, as a failing strcoll might be a
+     comparison function that is not a total order, and if we ignored
+     the failure this might cause qsort to dump core.  */
+
+  if (! setjmp (failed_strcoll))
+    use_strcmp = false;      /* strcoll() succeeded */
+  else
+    {
+      use_strcmp = true;
+      assert (sort_type != sort_version);
+      initialize_ordering_vector ();
+    }
+
+  /* When sort_type == sort_time, use time_type as subindex.  */
+  mpsort ((void const **) sorted_file, cwd_n_used,
+          sort_functions[sort_type + (sort_type == sort_time ? time_type : 0)]
+                        [use_strcmp][sort_reverse]
+                        [directories_first]);
+}
+
+/* List all the files now in the table.  */
+
+static void
+print_current_files (void)
+{
+  size_t i;
+
+  switch (format)
+    {
+    case one_per_line:
+      for (i = 0; i < cwd_n_used; i++)
+        {
+          print_file_name_and_frills (sorted_file[i], 0);
+          putchar ('\n');
+        }
+      break;
+
+    case many_per_line:
+      if (! line_length)
+        print_with_separator (' ');
+      else
+        print_many_per_line ();
+      break;
+
+    case horizontal:
+      if (! line_length)
+        print_with_separator (' ');
+      else
+        print_horizontal ();
+      break;
+
+    case with_commas:
+      print_with_separator (',');
+      break;
+
+    case long_format:
+      for (i = 0; i < cwd_n_used; i++)
+        {
+          set_normal_color ();
+          print_long_format (sorted_file[i]);
+          DIRED_PUTCHAR ('\n');
+        }
+      break;
+    }
+}
+
+/* Replace the first %b with precomputed aligned month names.
+   Note on glibc-2.7 at least, this speeds up the whole 'ls -lU'
+   process by around 17%, compared to letting strftime() handle the %b.  */
+
+static size_t
+align_nstrftime (char *buf, size_t size, bool recent, struct tm const *tm,
+                 timezone_t tz, int ns)
+{
+  char const *nfmt = (use_abformat
+                      ? abformat[recent][tm->tm_mon]
+                      : long_time_format[recent]);
+  return nstrftime (buf, size, nfmt, tm, tz, ns);
+}
+
+/* Return the expected number of columns in a long-format timestamp,
+   or zero if it cannot be calculated.  */
+
+static int
+long_time_expected_width (void)
+{
+  static int width = -1;
+
+  if (width < 0)
+    {
+      time_t epoch = 0;
+      struct tm tm;
+      char buf[TIME_STAMP_LEN_MAXIMUM + 1];
+
+      /* In case you're wondering if localtime_rz can fail with an input time_t
+         value of 0, let's just say it's very unlikely, but not inconceivable.
+         The TZ environment variable would have to specify a time zone that
+         is 2**31-1900 years or more ahead of UTC.  This could happen only on
+         a 64-bit system that blindly accepts e.g., TZ=UTC+20000000000000.
+         However, this is not possible with Solaris 10 or glibc-2.3.5, since
+         their implementations limit the offset to 167:59 and 24:00, resp.  */
+      if (localtime_rz (localtz, &epoch, &tm))
+        {
+          size_t len = align_nstrftime (buf, sizeof buf, false,
+                                        &tm, localtz, 0);
+          if (len != 0)
+            width = mbsnwidth (buf, len, 0);
+        }
+
+      if (width < 0)
+        width = 0;
+    }
+
+  return width;
+}
+
+/* Print the user or group name NAME, with numeric id ID, using a
+   print width of WIDTH columns.  */
+
+static void
+format_user_or_group (char const *name, unsigned long int id, int width)
+{
+  size_t len;
+
+  if (name)
+    {
+      int width_gap = width - mbswidth (name, 0);
+      int pad = MAX (0, width_gap);
+      fputs (name, stdout);
+      len = strlen (name) + pad;
+
+      do
+        putchar (' ');
+      while (pad--);
+    }
+  else
+    {
+      printf ("%*lu ", width, id);
+      len = width;
+    }
+
+  dired_pos += len + 1;
+}
+
+/* Print the name or id of the user with id U, using a print width of
+   WIDTH.  */
+
+static void
+format_user (uid_t u, int width, bool stat_ok)
+{
+  format_user_or_group (! stat_ok ? "?" :
+                        (numeric_ids ? NULL : getuser (u)), u, width);
+}
+
+/* Likewise, for groups.  */
+
+static void
+format_group (gid_t g, int width, bool stat_ok)
+{
+  format_user_or_group (! stat_ok ? "?" :
+                        (numeric_ids ? NULL : getgroup (g)), g, width);
+}
+
+/* Return the number of columns that format_user_or_group will print.  */
+
+static int
+format_user_or_group_width (char const *name, unsigned long int id)
+{
+  if (name)
+    {
+      int len = mbswidth (name, 0);
+      return MAX (0, len);
+    }
+  else
+    {
+      char buf[INT_BUFSIZE_BOUND (id)];
+      sprintf (buf, "%lu", id);
+      return strlen (buf);
+    }
+}
+
+/* Return the number of columns that format_user will print.  */
+
+static int
+format_user_width (uid_t u)
+{
+  return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u);
+}
+
+/* Likewise, for groups.  */
+
+static int
+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)
+{
+  char modebuf[12];
+  char buf
+    [LONGEST_HUMAN_READABLE + 1		/* inode */
+     + LONGEST_HUMAN_READABLE + 1	/* size in blocks */
+     + sizeof (modebuf) - 1 + 1		/* mode string */
+     + INT_BUFSIZE_BOUND (uintmax_t)	/* st_nlink */
+     + LONGEST_HUMAN_READABLE + 2	/* major device number */
+     + LONGEST_HUMAN_READABLE + 1	/* minor device number */
+     + TIME_STAMP_LEN_MAXIMUM + 1	/* max length of time/date */
+     ];
+  size_t s;
+  char *p;
+  struct timespec when_timespec;
+  struct tm when_local;
+  bool btime_ok = true;
+
+  /* Compute the mode string, except remove the trailing space if no
+     file in this directory has an ACL or security context.  */
+  if (f->stat_ok)
+    filemodestring (&f->stat, modebuf);
+  else
+    {
+      modebuf[0] = filetype_letter[f->filetype];
+      memset (modebuf + 1, '?', 10);
+      modebuf[11] = '\0';
+    }
+  if (! any_has_acl)
+    modebuf[10] = '\0';
+  else if (f->acl_type == ACL_T_LSM_CONTEXT_ONLY)
+    modebuf[10] = '.';
+  else if (f->acl_type == ACL_T_YES)
+    modebuf[10] = '+';
+
+  switch (time_type)
+    {
+    case time_ctime:
+      when_timespec = get_stat_ctime (&f->stat);
+      break;
+    case time_mtime:
+      when_timespec = get_stat_mtime (&f->stat);
+      break;
+    case time_atime:
+      when_timespec = get_stat_atime (&f->stat);
+      break;
+    case time_btime:
+      when_timespec = get_stat_btime (&f->stat);
+      if (when_timespec.tv_sec == -1 && when_timespec.tv_nsec == -1)
+        btime_ok = false;
+      break;
+    default:
+      abort ();
+    }
+
+  p = buf;
+
+  if (print_inode)
+    {
+      char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
+      sprintf (p, "%*s ", inode_number_width,
+               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);
+    }
+
+  if (print_block_size)
+    {
+      char hbuf[LONGEST_HUMAN_READABLE + 1];
+      char const *blocks =
+        (! f->stat_ok
+         ? "?"
+         : human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts,
+                           ST_NBLOCKSIZE, output_block_size));
+      int pad;
+      for (pad = block_size_width - mbswidth (blocks, 0); 0 < pad; pad--)
+        *p++ = ' ';
+      while ((*p++ = *blocks++))
+        continue;
+      p[-1] = ' ';
+    }
+
+  /* The last byte of the mode string is the POSIX
+     "optional alternate access method flag".  */
+  {
+    char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
+    sprintf (p, "%s %*s ", modebuf, nlink_width,
+             ! f->stat_ok ? "?" : umaxtostr (f->stat.st_nlink, hbuf));
+  }
+  /* Increment by strlen (p) here, rather than by, e.g.,
+     sizeof modebuf - 2 + any_has_acl + 1 + nlink_width + 1.
+     The latter is wrong when nlink_width is zero.  */
+  p += strlen (p);
+
+  DIRED_INDENT ();
+
+  if (print_owner || print_group || print_author || print_scontext)
+    {
+      DIRED_FPUTS (buf, stdout, p - buf);
+
+      if (print_owner)
+        format_user (f->stat.st_uid, owner_width, f->stat_ok);
+
+      if (print_group)
+        format_group (f->stat.st_gid, group_width, f->stat_ok);
+
+      if (print_author)
+        format_user (f->stat.st_author, author_width, f->stat_ok);
+
+      if (print_scontext)
+        format_user_or_group (f->scontext, 0, scontext_width);
+
+      p = buf;
+    }
+
+  if (f->stat_ok
+      && (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode)))
+    {
+      char majorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
+      char minorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
+      int blanks_width = (file_size_width
+                          - (major_device_number_width + 2
+                             + minor_device_number_width));
+      sprintf (p, "%*s, %*s ",
+               major_device_number_width + MAX (0, blanks_width),
+               umaxtostr (major (f->stat.st_rdev), majorbuf),
+               minor_device_number_width,
+               umaxtostr (minor (f->stat.st_rdev), minorbuf));
+      p += file_size_width + 1;
+    }
+  else
+    {
+      char hbuf[LONGEST_HUMAN_READABLE + 1];
+      char const *size =
+        (! f->stat_ok
+         ? "?"
+         : human_readable (unsigned_file_size (f->stat.st_size),
+                           hbuf, file_human_output_opts, 1,
+                           file_output_block_size));
+      int pad;
+      for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--)
+        *p++ = ' ';
+      while ((*p++ = *size++))
+        continue;
+      p[-1] = ' ';
+    }
+
+  s = 0;
+  *p = '\1';
+
+  if (f->stat_ok && btime_ok
+      && localtime_rz (localtz, &when_timespec.tv_sec, &when_local))
+    {
+      struct timespec six_months_ago;
+      bool recent;
+
+      /* If the file appears to be in the future, update the current
+         time, in case the file happens to have been modified since
+         the last time we checked the clock.  */
+      if (timespec_cmp (current_time, when_timespec) < 0)
+        gettime (&current_time);
+
+      /* Consider a time to be recent if it is within the past six months.
+         A Gregorian year has 365.2425 * 24 * 60 * 60 == 31556952 seconds
+         on the average.  Write this value as an integer constant to
+         avoid floating point hassles.  */
+      six_months_ago.tv_sec = current_time.tv_sec - 31556952 / 2;
+      six_months_ago.tv_nsec = current_time.tv_nsec;
+
+      recent = (timespec_cmp (six_months_ago, when_timespec) < 0
+                && (timespec_cmp (when_timespec, current_time) < 0));
+
+      /* We assume here that all time zones are offset from UTC by a
+         whole number of seconds.  */
+      s = align_nstrftime (p, TIME_STAMP_LEN_MAXIMUM + 1, recent,
+                           &when_local, localtz, when_timespec.tv_nsec);
+    }
+
+  if (s || !*p)
+    {
+      p += s;
+      *p++ = ' ';
+
+      /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it.  */
+      *p = '\0';
+    }
+  else
+    {
+      /* The time cannot be converted using the desired format, so
+         print it as a huge integer number of seconds.  */
+      char hbuf[INT_BUFSIZE_BOUND (intmax_t)];
+      sprintf (p, "%*s ", long_time_expected_width (),
+               (! f->stat_ok || ! btime_ok
+                ? "?"
+                : timetostr (when_timespec.tv_sec, hbuf)));
+      /* FIXME: (maybe) We discarded when_timespec.tv_nsec. */
+      p += strlen (p);
+    }
+
+  DIRED_FPUTS (buf, stdout, p - buf);
+  size_t w = print_name_with_quoting (f, false, &dired_obstack, p - buf);
+
+  if (f->filetype == symbolic_link)
+    {
+      if (f->linkname)
+        {
+          DIRED_FPUTS_LITERAL (" -> ", stdout);
+          print_name_with_quoting (f, true, NULL, (p - buf) + w + 4);
+          if (indicator_style != none)
+            print_type_indicator (true, f->linkmode, unknown);
+        }
+    }
+  else if (indicator_style != none)
+    print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
+}
+
+/* Write to *BUF a quoted representation of the file name NAME, if non-NULL,
+   using OPTIONS to control quoting.  *BUF is set to NAME if no quoting
+   is required.  *BUF is allocated if more space required (and the original
+   *BUF is not deallocated).
+   Store the number of screen columns occupied by NAME's quoted
+   representation into WIDTH, if non-NULL.
+   Store into PAD whether an initial space is needed for padding.
+   Return the number of bytes in *BUF.  */
+
+static size_t
+quote_name_buf (char **inbuf, size_t bufsize, char *name,
+                struct quoting_options const *options,
+                int needs_general_quoting, size_t *width, bool *pad)
+{
+  char *buf = *inbuf;
+  size_t displayed_width IF_LINT ( = 0);
+  size_t len = 0;
+  bool quoted;
+
+  enum quoting_style qs = get_quoting_style (options);
+  bool needs_further_quoting = qmark_funny_chars
+                               && (qs == shell_quoting_style
+                                   || qs == shell_always_quoting_style
+                                   || qs == literal_quoting_style);
+
+  if (needs_general_quoting != 0)
+    {
+      len = quotearg_buffer (buf, bufsize, name, -1, options);
+      if (bufsize <= len)
+        {
+          buf = xmalloc (len + 1);
+          quotearg_buffer (buf, len + 1, name, -1, options);
+        }
+
+      quoted = (*name != *buf) || strlen (name) != len;
+    }
+  else if (needs_further_quoting)
+    {
+      len = strlen (name);
+      if (bufsize <= len)
+        buf = xmalloc (len + 1);
+      memcpy (buf, name, len + 1);
+
+      quoted = false;
+    }
+  else
+    {
+      len = strlen (name);
+      buf = name;
+      quoted = false;
+    }
+
+  if (needs_further_quoting)
+    {
+      if (MB_CUR_MAX > 1)
+        {
+          char const *p = buf;
+          char const *plimit = buf + len;
+          char *q = buf;
+          displayed_width = 0;
+
+          while (p < plimit)
+            switch (*p)
+              {
+                case ' ': case '!': case '"': case '#': case '%':
+                case '&': case '\'': case '(': case ')': case '*':
+                case '+': case ',': case '-': case '.': case '/':
+                case '0': case '1': case '2': case '3': case '4':
+                case '5': case '6': case '7': case '8': case '9':
+                case ':': case ';': case '<': case '=': case '>':
+                case '?':
+                case 'A': case 'B': case 'C': case 'D': case 'E':
+                case 'F': case 'G': case 'H': case 'I': case 'J':
+                case 'K': case 'L': case 'M': case 'N': case 'O':
+                case 'P': case 'Q': case 'R': case 'S': case 'T':
+                case 'U': case 'V': case 'W': case 'X': case 'Y':
+                case 'Z':
+                case '[': case '\\': case ']': case '^': case '_':
+                case 'a': case 'b': case 'c': case 'd': case 'e':
+                case 'f': case 'g': case 'h': case 'i': case 'j':
+                case 'k': case 'l': case 'm': case 'n': case 'o':
+                case 'p': case 'q': case 'r': case 's': case 't':
+                case 'u': case 'v': case 'w': case 'x': case 'y':
+                case 'z': case '{': case '|': case '}': case '~':
+                  /* These characters are printable ASCII characters.  */
+                  *q++ = *p++;
+                  displayed_width += 1;
+                  break;
+                default:
+                  /* If we have a multibyte sequence, copy it until we
+                     reach its end, replacing each non-printable multibyte
+                     character with a single question mark.  */
+                  {
+                    mbstate_t mbstate = { 0, };
+                    do
+                      {
+                        wchar_t wc;
+                        size_t bytes;
+                        int w;
+
+                        bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
+
+                        if (bytes == (size_t) -1)
+                          {
+                            /* An invalid multibyte sequence was
+                               encountered.  Skip one input byte, and
+                               put a question mark.  */
+                            p++;
+                            *q++ = '?';
+                            displayed_width += 1;
+                            break;
+                          }
+
+                        if (bytes == (size_t) -2)
+                          {
+                            /* An incomplete multibyte character
+                               at the end.  Replace it entirely with
+                               a question mark.  */
+                            p = plimit;
+                            *q++ = '?';
+                            displayed_width += 1;
+                            break;
+                          }
+
+                        if (bytes == 0)
+                          /* A null wide character was encountered.  */
+                          bytes = 1;
+
+                        w = wcwidth (wc);
+                        if (w >= 0)
+                          {
+                            /* A printable multibyte character.
+                               Keep it.  */
+                            for (; bytes > 0; --bytes)
+                              *q++ = *p++;
+                            displayed_width += w;
+                          }
+                        else
+                          {
+                            /* An unprintable multibyte character.
+                               Replace it entirely with a question
+                               mark.  */
+                            p += bytes;
+                            *q++ = '?';
+                            displayed_width += 1;
+                          }
+                      }
+                    while (! mbsinit (&mbstate));
+                  }
+                  break;
+              }
+
+          /* The buffer may have shrunk.  */
+          len = q - buf;
+        }
+      else
+        {
+          char *p = buf;
+          char const *plimit = buf + len;
+
+          while (p < plimit)
+            {
+              if (! isprint (to_uchar (*p)))
+                *p = '?';
+              p++;
+            }
+          displayed_width = len;
+        }
+    }
+  else if (width != NULL)
+    {
+      if (MB_CUR_MAX > 1)
+        displayed_width = mbsnwidth (buf, len, 0);
+      else
+        {
+          char const *p = buf;
+          char const *plimit = buf + len;
+
+          displayed_width = 0;
+          while (p < plimit)
+            {
+              if (isprint (to_uchar (*p)))
+                displayed_width++;
+              p++;
+            }
+        }
+    }
+
+  /* Set padding to better align quoted items,
+     and also give a visual indication that quotes are
+     not actually part of the name.  */
+  *pad = (align_variable_outer_quotes && cwd_some_quoted && ! quoted);
+
+  if (width != NULL)
+    *width = displayed_width;
+
+  *inbuf = buf;
+
+  return len;
+}
+
+static size_t
+quote_name_width (const char *name, struct quoting_options const *options,
+                  int needs_general_quoting)
+{
+  char smallbuf[BUFSIZ];
+  char *buf = smallbuf;
+  size_t width;
+  bool pad;
+
+  quote_name_buf (&buf, sizeof smallbuf, (char *) name, options,
+                  needs_general_quoting, &width, &pad);
+
+  if (buf != smallbuf && buf != name)
+    free (buf);
+
+  width += pad;
+
+  return width;
+}
+
+/* %XX escape any input out of range as defined in RFC3986,
+   and also if PATH, convert all path separators to '/'.  */
+static char *
+file_escape (const char *str, bool path)
+{
+  char *esc = xnmalloc (3, strlen (str) + 1);
+  char *p = esc;
+  while (*str)
+    {
+      if (path && ISSLASH (*str))
+        {
+          *p++ = '/';
+          str++;
+        }
+      else if (RFC3986[to_uchar (*str)])
+        *p++ = *str++;
+      else
+        p += sprintf (p, "%%%02x", to_uchar (*str++));
+    }
+  *p = '\0';
+  return esc;
+}
+
+static size_t
+quote_name (char const *name, struct quoting_options const *options,
+            int needs_general_quoting, const struct bin_str *color,
+            bool allow_pad, struct obstack *stack, char const *absolute_name)
+{
+  char smallbuf[BUFSIZ];
+  char *buf = smallbuf;
+  size_t len;
+  bool pad;
+
+  len = quote_name_buf (&buf, sizeof smallbuf, (char *) name, options,
+                        needs_general_quoting, NULL, &pad);
+
+  if (pad && allow_pad)
+      DIRED_PUTCHAR (' ');
+
+  if (color)
+    print_color_indicator (color);
+
+  /* If we're padding, then don't include the outer quotes in
+     the --hyperlink, to improve the alignment of those links.  */
+  bool skip_quotes = false;
+
+  if (absolute_name)
+    {
+      if (align_variable_outer_quotes && cwd_some_quoted && ! pad)
+        {
+          skip_quotes = true;
+          putchar (*buf);
+        }
+      char *h = file_escape (hostname, /* path= */ false);
+      char *n = file_escape (absolute_name, /* path= */ true);
+      /* TODO: It would be good to be able to define parameters
+         to give hints to the terminal as how best to render the URI.
+         For example since ls is outputting a dense block of URIs
+         it would be best to not underline by default, and only
+         do so upon hover etc.  */
+      printf ("\033]8;;file://%s%s%s\a", h, *n == '/' ? "" : "/", n);
+      free (h);
+      free (n);
+    }
+
+  if (stack)
+    PUSH_CURRENT_DIRED_POS (stack);
+
+  fwrite (buf + skip_quotes, 1, len - (skip_quotes * 2), stdout);
+
+  dired_pos += len;
+
+  if (stack)
+    PUSH_CURRENT_DIRED_POS (stack);
+
+  if (absolute_name)
+    {
+      fputs ("\033]8;;\a", stdout);
+      if (skip_quotes)
+        putchar (*(buf + len - 1));
+    }
+
+  if (buf != smallbuf && buf != name)
+    free (buf);
+
+  return len + pad;
+}
+
+static size_t
+print_name_with_quoting (const struct fileinfo *f,
+                         bool symlink_target,
+                         struct obstack *stack,
+                         size_t start_col)
+{
+  const char* name = symlink_target ? f->linkname : f->name;
+
+  const struct bin_str *color = print_with_color ?
+                                get_color_indicator (f, symlink_target) : NULL;
+
+  bool used_color_this_time = (print_with_color
+                               && (color || is_colored (C_NORM)));
+
+  size_t len = quote_name (name, filename_quoting_options, f->quoted,
+                           color, !symlink_target, stack, f->absolute_name);
+
+  process_signals ();
+  if (used_color_this_time)
+    {
+      prep_non_filename_text ();
+
+      /* We use the byte length rather than display width here as
+         an optimization to avoid accurately calculating the width,
+         because we only output the clear to EOL sequence if the name
+         _might_ wrap to the next line.  This may output a sequence
+         unnecessarily in multi-byte locales for example,
+         but in that case it's inconsequential to the output.  */
+      if (line_length
+          && (start_col / line_length != (start_col + len - 1) / line_length))
+        put_indicator (&color_indicator[C_CLR_TO_EOL]);
+    }
+
+  return len;
+}
+
+static void
+prep_non_filename_text (void)
+{
+  if (color_indicator[C_END].string != NULL)
+    put_indicator (&color_indicator[C_END]);
+  else
+    {
+      put_indicator (&color_indicator[C_LEFT]);
+      put_indicator (&color_indicator[C_RESET]);
+      put_indicator (&color_indicator[C_RIGHT]);
+    }
+}
+
+/* Print the file name of 'f' with appropriate quoting.
+   Also print file size, inode number, and filetype indicator character,
+   as requested by switches.  */
+
+static size_t
+print_file_name_and_frills (const struct fileinfo *f, size_t start_col)
+{
+  char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
+
+  set_normal_color ();
+
+  if (print_inode)
+    printf ("%*s ", format == with_commas ? 0 : inode_number_width,
+            format_inode (buf, sizeof buf, f));
+
+  if (print_block_size)
+    printf ("%*s ", format == with_commas ? 0 : block_size_width,
+            ! 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);
+
+  size_t width = print_name_with_quoting (f, false, NULL, start_col);
+
+  if (indicator_style != none)
+    width += print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
+
+  return width;
+}
+
+/* Given these arguments describing a file, return the single-byte
+   type indicator, or 0.  */
+static char
+get_type_indicator (bool stat_ok, mode_t mode, enum filetype type)
+{
+  char c;
+
+  if (stat_ok ? S_ISREG (mode) : type == normal)
+    {
+      if (stat_ok && indicator_style == classify && (mode & S_IXUGO))
+        c = '*';
+      else
+        c = 0;
+    }
+  else
+    {
+      if (stat_ok ? S_ISDIR (mode) : type == directory || type == arg_directory)
+        c = '/';
+      else if (indicator_style == slash)
+        c = 0;
+      else if (stat_ok ? S_ISLNK (mode) : type == symbolic_link)
+        c = '@';
+      else if (stat_ok ? S_ISFIFO (mode) : type == fifo)
+        c = '|';
+      else if (stat_ok ? S_ISSOCK (mode) : type == sock)
+        c = '=';
+      else if (stat_ok && S_ISDOOR (mode))
+        c = '>';
+      else
+        c = 0;
+    }
+  return c;
+}
+
+static bool
+print_type_indicator (bool stat_ok, mode_t mode, enum filetype type)
+{
+  char c = get_type_indicator (stat_ok, mode, type);
+  if (c)
+    DIRED_PUTCHAR (c);
+  return !!c;
+}
+
+/* Returns if color sequence was printed.  */
+static bool
+print_color_indicator (const struct bin_str *ind)
+{
+  if (ind)
+    {
+      /* Need to reset so not dealing with attribute combinations */
+      if (is_colored (C_NORM))
+        restore_default_color ();
+      put_indicator (&color_indicator[C_LEFT]);
+      put_indicator (ind);
+      put_indicator (&color_indicator[C_RIGHT]);
+    }
+
+  return ind != NULL;
+}
+
+/* Returns color indicator or NULL if none.  */
+static const struct bin_str* _GL_ATTRIBUTE_PURE
+get_color_indicator (const struct fileinfo *f, bool symlink_target)
+{
+  enum indicator_no type;
+  struct color_ext_type *ext;	/* Color extension */
+  size_t len;			/* Length of name */
+
+  const char* name;
+  mode_t mode;
+  int linkok;
+  if (symlink_target)
+    {
+      name = f->linkname;
+      mode = f->linkmode;
+      linkok = f->linkok ? 0 : -1;
+    }
+  else
+    {
+      name = f->name;
+      mode = FILE_OR_LINK_MODE (f);
+      linkok = f->linkok;
+    }
+
+  /* Is this a nonexistent file?  If so, linkok == -1.  */
+
+  if (linkok == -1 && is_colored (C_MISSING))
+    type = C_MISSING;
+  else if (!f->stat_ok)
+    {
+      static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
+      type = filetype_indicator[f->filetype];
+    }
+  else
+    {
+      if (S_ISREG (mode))
+        {
+          type = C_FILE;
+
+          if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
+            type = C_SETUID;
+          else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
+            type = C_SETGID;
+          else if (is_colored (C_CAP) && f->has_capability)
+            type = C_CAP;
+          else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
+            type = C_EXEC;
+          else if ((1 < f->stat.st_nlink) && is_colored (C_MULTIHARDLINK))
+            type = C_MULTIHARDLINK;
+        }
+      else if (S_ISDIR (mode))
+        {
+          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 && is_colored (C_OTHER_WRITABLE))
+            type = C_OTHER_WRITABLE;
+          else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
+            type = C_STICKY;
+        }
+      else if (S_ISLNK (mode))
+        type = C_LINK;
+      else if (S_ISFIFO (mode))
+        type = C_FIFO;
+      else if (S_ISSOCK (mode))
+        type = C_SOCK;
+      else if (S_ISBLK (mode))
+        type = C_BLK;
+      else if (S_ISCHR (mode))
+        type = C_CHR;
+      else if (S_ISDOOR (mode))
+        type = C_DOOR;
+      else
+        {
+          /* Classify a file of some other type as C_ORPHAN.  */
+          type = C_ORPHAN;
+        }
+    }
+
+  /* Check the file's suffix only if still classified as C_FILE.  */
+  ext = NULL;
+  if (type == C_FILE)
+    {
+      /* Test if NAME has a recognized suffix.  */
+
+      len = strlen (name);
+      name += len;		/* Pointer to final \0.  */
+      for (ext = color_ext_list; ext != NULL; ext = ext->next)
+        {
+          if (ext->ext.len <= len
+              && c_strncasecmp (name - ext->ext.len, ext->ext.string,
+                                ext->ext.len) == 0)
+            break;
+        }
+    }
+
+  /* Adjust the color for orphaned symlinks.  */
+  if (type == C_LINK && !linkok)
+    {
+      if (color_symlink_as_referent || is_colored (C_ORPHAN))
+        type = C_ORPHAN;
+    }
+
+  const struct bin_str *const s
+    = ext ? &(ext->seq) : &color_indicator[type];
+
+  return s->string ? s : NULL;
+}
+
+/* Output a color indicator (which may contain nulls).  */
+static void
+put_indicator (const struct bin_str *ind)
+{
+  if (! used_color)
+    {
+      used_color = true;
+
+      /* If the standard output is a controlling terminal, watch out
+         for signals, so that the colors can be restored to the
+         default state if "ls" is suspended or interrupted.  */
+
+      if (0 <= tcgetpgrp (STDOUT_FILENO))
+        signal_init ();
+
+      prep_non_filename_text ();
+    }
+
+  fwrite (ind->string, ind->len, 1, stdout);
+}
+
+static size_t
+length_of_file_name_and_frills (const struct fileinfo *f)
+{
+  size_t len = 0;
+  char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
+
+  if (print_inode)
+    len += 1 + (format == with_commas
+                ? strlen (umaxtostr (f->stat.st_ino, buf))
+                : inode_number_width);
+
+  if (print_block_size)
+    len += 1 + (format == with_commas
+                ? 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)
+    len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width);
+
+  len += quote_name_width (f->name, filename_quoting_options, f->quoted);
+
+  if (indicator_style != none)
+    {
+      char c = get_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
+      len += (c != 0);
+    }
+
+  return len;
+}
+
+static void
+print_many_per_line (void)
+{
+  size_t row;			/* Current row.  */
+  size_t cols = calculate_columns (true);
+  struct column_info const *line_fmt = &column_info[cols - 1];
+
+  /* Calculate the number of rows that will be in each column except possibly
+     for a short column on the right.  */
+  size_t rows = cwd_n_used / cols + (cwd_n_used % cols != 0);
+
+  for (row = 0; row < rows; row++)
+    {
+      size_t col = 0;
+      size_t filesno = row;
+      size_t pos = 0;
+
+      /* Print the next row.  */
+      while (1)
+        {
+          struct fileinfo const *f = sorted_file[filesno];
+          size_t name_length = length_of_file_name_and_frills (f);
+          size_t max_name_length = line_fmt->col_arr[col++];
+          print_file_name_and_frills (f, pos);
+
+          filesno += rows;
+          if (filesno >= cwd_n_used)
+            break;
+
+          indent (pos + name_length, pos + max_name_length);
+          pos += max_name_length;
+        }
+      putchar ('\n');
+    }
+}
+
+static void
+print_horizontal (void)
+{
+  size_t filesno;
+  size_t pos = 0;
+  size_t cols = calculate_columns (false);
+  struct column_info const *line_fmt = &column_info[cols - 1];
+  struct fileinfo const *f = sorted_file[0];
+  size_t name_length = length_of_file_name_and_frills (f);
+  size_t max_name_length = line_fmt->col_arr[0];
+
+  /* Print first entry.  */
+  print_file_name_and_frills (f, 0);
+
+  /* Now the rest.  */
+  for (filesno = 1; filesno < cwd_n_used; ++filesno)
+    {
+      size_t col = filesno % cols;
+
+      if (col == 0)
+        {
+          putchar ('\n');
+          pos = 0;
+        }
+      else
+        {
+          indent (pos + name_length, pos + max_name_length);
+          pos += max_name_length;
+        }
+
+      f = sorted_file[filesno];
+      print_file_name_and_frills (f, pos);
+
+      name_length = length_of_file_name_and_frills (f);
+      max_name_length = line_fmt->col_arr[col];
+    }
+  putchar ('\n');
+}
+
+/* Output name + SEP + ' '.  */
+
+static void
+print_with_separator (char sep)
+{
+  size_t filesno;
+  size_t pos = 0;
+
+  for (filesno = 0; filesno < cwd_n_used; filesno++)
+    {
+      struct fileinfo const *f = sorted_file[filesno];
+      size_t len = line_length ? length_of_file_name_and_frills (f) : 0;
+
+      if (filesno != 0)
+        {
+          char separator;
+
+          if (! line_length
+              || ((pos + len + 2 < line_length)
+                  && (pos <= SIZE_MAX - len - 2)))
+            {
+              pos += 2;
+              separator = ' ';
+            }
+          else
+            {
+              pos = 0;
+              separator = '\n';
+            }
+
+          putchar (sep);
+          putchar (separator);
+        }
+
+      print_file_name_and_frills (f, pos);
+      pos += len;
+    }
+  putchar ('\n');
+}
+
+/* Assuming cursor is at position FROM, indent up to position TO.
+   Use a TAB character instead of two or more spaces whenever possible.  */
+
+static void
+indent (size_t from, size_t to)
+{
+  while (from < to)
+    {
+      if (tabsize != 0 && to / tabsize > (from + 1) / tabsize)
+        {
+          putchar ('\t');
+          from += tabsize - from % tabsize;
+        }
+      else
+        {
+          putchar (' ');
+          from++;
+        }
+    }
+}
+
+/* Put DIRNAME/NAME into DEST, handling '.' and '/' properly.  */
+/* FIXME: maybe remove this function someday.  See about using a
+   non-malloc'ing version of file_name_concat.  */
+
+static void
+attach (char *dest, const char *dirname, const char *name)
+{
+  const char *dirnamep = dirname;
+
+  /* Copy dirname if it is not ".".  */
+  if (dirname[0] != '.' || dirname[1] != 0)
+    {
+      while (*dirnamep)
+        *dest++ = *dirnamep++;
+      /* Add '/' if 'dirname' doesn't already end with it.  */
+      if (dirnamep > dirname && dirnamep[-1] != '/')
+        *dest++ = '/';
+    }
+  while (*name)
+    *dest++ = *name++;
+  *dest = 0;
+}
+
+/* Allocate enough column info suitable for the current number of
+   files and display columns, and initialize the info to represent the
+   narrowest possible columns.  */
+
+static void
+init_column_info (void)
+{
+  size_t i;
+  size_t max_cols = MIN (max_idx, cwd_n_used);
+
+  /* Currently allocated columns in column_info.  */
+  static size_t column_info_alloc;
+
+  if (column_info_alloc < max_cols)
+    {
+      size_t new_column_info_alloc;
+      size_t *p;
+
+      if (max_cols < max_idx / 2)
+        {
+          /* The number of columns is far less than the display width
+             allows.  Grow the allocation, but only so that it's
+             double the current requirements.  If the display is
+             extremely wide, this avoids allocating a lot of memory
+             that is never needed.  */
+          column_info = xnrealloc (column_info, max_cols,
+                                   2 * sizeof *column_info);
+          new_column_info_alloc = 2 * max_cols;
+        }
+      else
+        {
+          column_info = xnrealloc (column_info, max_idx, sizeof *column_info);
+          new_column_info_alloc = max_idx;
+        }
+
+      /* Allocate the new size_t objects by computing the triangle
+         formula n * (n + 1) / 2, except that we don't need to
+         allocate the part of the triangle that we've already
+         allocated.  Check for address arithmetic overflow.  */
+      {
+        size_t column_info_growth = new_column_info_alloc - column_info_alloc;
+        size_t s = column_info_alloc + 1 + new_column_info_alloc;
+        size_t t = s * column_info_growth;
+        if (s < new_column_info_alloc || t / column_info_growth != s)
+          xalloc_die ();
+        p = xnmalloc (t / 2, sizeof *p);
+      }
+
+      /* Grow the triangle by parceling out the cells just allocated.  */
+      for (i = column_info_alloc; i < new_column_info_alloc; i++)
+        {
+          column_info[i].col_arr = p;
+          p += i + 1;
+        }
+
+      column_info_alloc = new_column_info_alloc;
+    }
+
+  for (i = 0; i < max_cols; ++i)
+    {
+      size_t j;
+
+      column_info[i].valid_len = true;
+      column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH;
+      for (j = 0; j <= i; ++j)
+        column_info[i].col_arr[j] = MIN_COLUMN_WIDTH;
+    }
+}
+
+/* Calculate the number of columns needed to represent the current set
+   of files in the current display width.  */
+
+static size_t
+calculate_columns (bool by_columns)
+{
+  size_t filesno;		/* Index into cwd_file.  */
+  size_t cols;			/* Number of files across.  */
+
+  /* Normally the maximum number of columns is determined by the
+     screen width.  But if few files are available this might limit it
+     as well.  */
+  size_t max_cols = MIN (max_idx, cwd_n_used);
+
+  init_column_info ();
+
+  /* Compute the maximum number of possible columns.  */
+  for (filesno = 0; filesno < cwd_n_used; ++filesno)
+    {
+      struct fileinfo const *f = sorted_file[filesno];
+      size_t name_length = length_of_file_name_and_frills (f);
+
+      for (size_t i = 0; i < max_cols; ++i)
+        {
+          if (column_info[i].valid_len)
+            {
+              size_t idx = (by_columns
+                            ? filesno / ((cwd_n_used + i) / (i + 1))
+                            : filesno % (i + 1));
+              size_t real_length = name_length + (idx == i ? 0 : 2);
+
+              if (column_info[i].col_arr[idx] < real_length)
+                {
+                  column_info[i].line_len += (real_length
+                                              - column_info[i].col_arr[idx]);
+                  column_info[i].col_arr[idx] = real_length;
+                  column_info[i].valid_len = (column_info[i].line_len
+                                              < line_length);
+                }
+            }
+        }
+    }
+
+  /* Find maximum allowed columns.  */
+  for (cols = max_cols; 1 < cols; --cols)
+    {
+      if (column_info[cols - 1].valid_len)
+        break;
+    }
+
+  return cols;
+}
+
+void
+usage (int status)
+{
+  if (status != EXIT_SUCCESS)
+    emit_try_help ();
+  else
+    {
+      printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
+      fputs (_("\
+List information about the FILEs (the current directory by default).\n\
+Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n\
+"), stdout);
+
+      emit_mandatory_arg_note ();
+
+      fputs (_("\
+  -a, --all                  do not ignore entries starting with .\n\
+  -A, --almost-all           do not list implied . and ..\n\
+      --author               with -l, print the author of each file\n\
+  -b, --escape               print C-style escapes for nongraphic characters\n\
+"), stdout);
+      fputs (_("\
+      --block-size=SIZE      with -l, scale sizes by SIZE when printing them;\n\
+                               e.g., '--block-size=M'; see SIZE format below\n\
+"), stdout);
+      fputs (_("\
+  -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\
+                               with -l: show ctime and sort by name;\n\
+                               otherwise: sort by ctime, newest first\n\
+"), stdout);
+      fputs (_("\
+  -C                         list entries by columns\n\
+      --color[=WHEN]         colorize the output; WHEN can be 'always' (default\
+\n\
+                               if omitted), 'auto', or 'never'; more info below\
+\n\
+  -d, --directory            list directories themselves, not their contents\n\
+  -D, --dired                generate output designed for Emacs' dired mode\n\
+"), stdout);
+      fputs (_("\
+  -f                         do not sort, enable -aU, disable -ls --color\n\
+  -F, --classify             append indicator (one of */=>@|) to entries\n\
+      --file-type            likewise, except do not append '*'\n\
+      --format=WORD          across -x, commas -m, horizontal -x, long -l,\n\
+                               single-column -1, verbose -l, vertical -C\n\
+      --full-time            like -l --time-style=full-iso\n\
+"), stdout);
+      fputs (_("\
+  -g                         like -l, but do not list owner\n\
+"), stdout);
+      fputs (_("\
+      --group-directories-first\n\
+                             group directories before files;\n\
+                               can be augmented with a --sort option, but any\n\
+                               use of --sort=none (-U) disables grouping\n\
+"), stdout);
+      fputs (_("\
+  -G, --no-group             in a long listing, don't print group names\n\
+"), stdout);
+      fputs (_("\
+  -h, --human-readable       with -l and -s, print sizes like 1K 234M 2G etc.\n\
+      --si                   likewise, but use powers of 1000 not 1024\n\
+"), stdout);
+      fputs (_("\
+  -H, --dereference-command-line\n\
+                             follow symbolic links listed on the command line\n\
+      --dereference-command-line-symlink-to-dir\n\
+                             follow each command line symbolic link\n\
+                               that points to a directory\n\
+      --hide=PATTERN         do not list implied entries matching shell PATTERN\
+\n\
+                               (overridden by -a or -A)\n\
+"), stdout);
+      fputs (_("\
+      --hyperlink[=WHEN]     hyperlink file names; WHEN can be 'always'\n\
+                               (default if omitted), 'auto', or 'never'\n\
+"), stdout);
+      fputs (_("\
+      --indicator-style=WORD  append indicator with style WORD to entry names:\
+\n\
+                               none (default), slash (-p),\n\
+                               file-type (--file-type), classify (-F)\n\
+  -i, --inode                print the index number of each file\n\
+  -I, --ignore=PATTERN       do not list implied entries matching shell PATTERN\
+\n\
+"), stdout);
+      fputs (_("\
+  -k, --kibibytes            default to 1024-byte blocks for disk usage;\n\
+                               used only with -s and per directory totals\n\
+"), stdout);
+      fputs (_("\
+  -l                         use a long listing format\n\
+  -L, --dereference          when showing file information for a symbolic\n\
+                               link, show information for the file the link\n\
+                               references rather than for the link itself\n\
+  -m                         fill width with a comma separated list of entries\
+\n\
+"), stdout);
+      fputs (_("\
+  -n, --numeric-uid-gid      like -l, but list numeric user and group IDs\n\
+  -N, --literal              print entry names without quoting\n\
+  -o                         like -l, but do not list group information\n\
+  -p, --indicator-style=slash\n\
+                             append / indicator to directories\n\
+"), stdout);
+      fputs (_("\
+  -q, --hide-control-chars   print ? instead of nongraphic characters\n\
+      --show-control-chars   show nongraphic characters as-is (the default,\n\
+                               unless program is 'ls' and output is a terminal)\
+\n\
+  -Q, --quote-name           enclose entry names in double quotes\n\
+      --quoting-style=WORD   use quoting style WORD for entry names:\n\
+                               literal, locale, shell, shell-always,\n\
+                               shell-escape, shell-escape-always, c, escape\n\
+                               (overrides QUOTING_STYLE environment variable)\n\
+"), stdout);
+      fputs (_("\
+  -r, --reverse              reverse order while sorting\n\
+  -R, --recursive            list subdirectories recursively\n\
+  -s, --size                 print the allocated size of each file, in blocks\n\
+"), stdout);
+      fputs (_("\
+  -S                         sort by file size, largest first\n\
+      --sort=WORD            sort by WORD instead of name: none (-U), size (-S)\
+,\n\
+                               time (-t), version (-v), extension (-X)\n\
+      --time=WORD            change the default of using modification times;\n\
+                               access time (-u): atime, access, use;\n\
+                               change time (-c): ctime, status;\n\
+                               birth time: birth, creation;\n\
+                             with -l, WORD determines which time to show;\n\
+                             with --sort=time, sort by WORD (newest first)\n\
+"), stdout);
+      fputs (_("\
+      --time-style=TIME_STYLE  time/date format with -l; see TIME_STYLE below\n\
+"), stdout);
+      fputs (_("\
+  -t                         sort by time, newest first; see --time\n\
+  -T, --tabsize=COLS         assume tab stops at each COLS instead of 8\n\
+"), stdout);
+      fputs (_("\
+  -u                         with -lt: sort by, and show, access time;\n\
+                               with -l: show access time and sort by name;\n\
+                               otherwise: sort by access time, newest first\n\
+  -U                         do not sort; list entries in directory order\n\
+  -v                         natural sort of (version) numbers within text\n\
+"), stdout);
+      fputs (_("\
+  -w, --width=COLS           set output width to COLS.  0 means no limit\n\
+  -x                         list entries by lines instead of by columns\n\
+  -X                         sort alphabetically by entry extension\n\
+  -Z, --context              print any security context of each file\n\
+  -1                         list one file per line.  Avoid '\\n' with -q or -b\
+\n\
+"), stdout);
+      fputs (HELP_OPTION_DESCRIPTION, stdout);
+      fputs (VERSION_OPTION_DESCRIPTION, stdout);
+      emit_size_note ();
+      fputs (_("\
+\n\
+The TIME_STYLE argument can be full-iso, long-iso, iso, locale, or +FORMAT.\n\
+FORMAT is interpreted like in date(1).  If FORMAT is FORMAT1<newline>FORMAT2,\n\
+then FORMAT1 applies to non-recent files and FORMAT2 to recent files.\n\
+TIME_STYLE prefixed with 'posix-' takes effect only outside the POSIX locale.\n\
+Also the TIME_STYLE environment variable sets the default style to use.\n\
+"), stdout);
+      fputs (_("\
+\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\
+Exit status:\n\
+ 0  if OK,\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_ancillary_info (PROGRAM_NAME);
+    }
+  exit (status);
+}
Index: create-8.32-no-ls-quoting-patch/coreutils-8.32-new/src
===================================================================
--- create-8.32-no-ls-quoting-patch/coreutils-8.32-new/src	(nonexistent)
+++ create-8.32-no-ls-quoting-patch/coreutils-8.32-new/src	(revision 5)

Property changes on: create-8.32-no-ls-quoting-patch/coreutils-8.32-new/src
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-8.32-no-ls-quoting-patch/coreutils-8.32-new
===================================================================
--- create-8.32-no-ls-quoting-patch/coreutils-8.32-new	(nonexistent)
+++ create-8.32-no-ls-quoting-patch/coreutils-8.32-new	(revision 5)

Property changes on: create-8.32-no-ls-quoting-patch/coreutils-8.32-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-8.32-no-ls-quoting-patch/create.patch.sh
===================================================================
--- create-8.32-no-ls-quoting-patch/create.patch.sh	(nonexistent)
+++ create-8.32-no-ls-quoting-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=8.32
+
+tar --files-from=file.list -xJvf ../coreutils-$VERSION.tar.xz
+mv coreutils-$VERSION coreutils-$VERSION-orig
+
+cp -rf ./coreutils-$VERSION-new ./coreutils-$VERSION
+
+diff --unified -Nr  coreutils-$VERSION-orig  coreutils-$VERSION > coreutils-$VERSION-no-ls-quoting.patch
+
+mv coreutils-$VERSION-no-ls-quoting.patch ../patches
+
+rm -rf ./coreutils-$VERSION
+rm -rf ./coreutils-$VERSION-orig

Property changes on: create-8.32-no-ls-quoting-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: create-8.32-no-ls-quoting-patch/file.list
===================================================================
--- create-8.32-no-ls-quoting-patch/file.list	(nonexistent)
+++ create-8.32-no-ls-quoting-patch/file.list	(revision 5)
@@ -0,0 +1,3 @@
+coreutils-8.32/NEWS
+coreutils-8.32/doc/coreutils.texi
+coreutils-8.32/src/ls.c
Index: create-8.32-no-ls-quoting-patch
===================================================================
--- create-8.32-no-ls-quoting-patch	(nonexistent)
+++ create-8.32-no-ls-quoting-patch	(revision 5)

Property changes on: create-8.32-no-ls-quoting-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-8.32-syscall64-ls-patch/coreutils-8.32-new/src/ls.c
===================================================================
--- create-8.32-syscall64-ls-patch/coreutils-8.32-new/src/ls.c	(nonexistent)
+++ create-8.32-syscall64-ls-patch/coreutils-8.32-new/src/ls.c	(revision 5)
@@ -0,0 +1,5529 @@
+/* 'dir', 'vdir' and 'ls' directory listing programs for GNU.
+   Copyright (C) 1985-2020 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 <https://www.gnu.org/licenses/>.  */
+
+/* If ls_mode is LS_MULTI_COL,
+   the multi-column format is the default regardless
+   of the type of output device.
+   This is for the 'dir' program.
+
+   If ls_mode is LS_LONG_FORMAT,
+   the long format is the default regardless of the
+   type of output device.
+   This is for the 'vdir' program.
+
+   If ls_mode is LS_LS,
+   the output format depends on whether the output
+   device is a terminal.
+   This is for the 'ls' program.  */
+
+/* Written by Richard Stallman and David MacKenzie.  */
+
+/* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
+   Flaherty <dennisf@denix.elk.miles.com> based on original patches by
+   Greg Lee <lee@uhunix.uhcc.hawaii.edu>.  */
+
+#include <config.h>
+#include <sys/types.h>
+
+#include <termios.h>
+#if HAVE_STROPTS_H
+# include <stropts.h>
+#endif
+#include <sys/ioctl.h>
+
+#ifdef WINSIZE_IN_PTEM
+# include <sys/stream.h>
+# include <sys/ptem.h>
+#endif
+
+#ifdef __linux__
+# include <sys/syscall.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <setjmp.h>
+#include <pwd.h>
+#include <getopt.h>
+#include <signal.h>
+#include <selinux/selinux.h>
+#include <wchar.h>
+
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+
+/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is
+   present.  */
+#ifndef SA_NOCLDSTOP
+# define SA_NOCLDSTOP 0
+# define sigprocmask(How, Set, Oset) /* empty */
+# define sigset_t int
+# if ! HAVE_SIGINTERRUPT
+#  define siginterrupt(sig, flag) /* empty */
+# endif
+#endif
+
+/* NonStop circa 2011 lacks both SA_RESTART and siginterrupt, so don't
+   restart syscalls after a signal handler fires.  This may cause
+   colors to get messed up on the screen if 'ls' is interrupted, but
+   that's the best we can do on such a platform.  */
+#ifndef SA_RESTART
+# define SA_RESTART 0
+#endif
+
+#include "system.h"
+#include <fnmatch.h>
+
+#include "acl.h"
+#include "argmatch.h"
+#include "c-strcase.h"
+#include "dev-ino.h"
+#include "die.h"
+#include "error.h"
+#include "filenamecat.h"
+#include "hard-locale.h"
+#include "hash.h"
+#include "human.h"
+#include "filemode.h"
+#include "filevercmp.h"
+#include "idcache.h"
+#include "ls.h"
+#include "mbswidth.h"
+#include "mpsort.h"
+#include "obstack.h"
+#include "quote.h"
+#include "smack.h"
+#include "stat-size.h"
+#include "stat-time.h"
+#include "strftime.h"
+#include "xdectoint.h"
+#include "xstrtol.h"
+#include "xstrtol-error.h"
+#include "areadlink.h"
+#include "mbsalign.h"
+#include "dircolors.h"
+#include "xgethostname.h"
+#include "c-ctype.h"
+#include "canonicalize.h"
+#include "statx.h"
+
+/* Include <sys/capability.h> last to avoid a clash of <sys/types.h>
+   include guards with some premature versions of libcap.
+   For more details, see <https://bugzilla.redhat.com/483548>.  */
+#ifdef HAVE_CAP
+# include <sys/capability.h>
+#endif
+
+#define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
+                      : (ls_mode == LS_MULTI_COL \
+                         ? "dir" : "vdir"))
+
+#define AUTHORS \
+  proper_name ("Richard M. Stallman"), \
+  proper_name ("David MacKenzie")
+
+#define obstack_chunk_alloc malloc
+#define obstack_chunk_free free
+
+/* Return an int indicating the result of comparing two integers.
+   Subtracting doesn't always work, due to overflow.  */
+#define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b))
+
+/* Unix-based readdir implementations have historically returned a dirent.d_ino
+   value that is sometimes not equal to the stat-obtained st_ino value for
+   that same entry.  This error occurs for a readdir entry that refers
+   to a mount point.  readdir's error is to return the inode number of
+   the underlying directory -- one that typically cannot be stat'ed, as
+   long as a file system is mounted on that directory.  RELIABLE_D_INO
+   encapsulates whether we can use the more efficient approach of relying
+   on readdir-supplied d_ino values, or whether we must incur the cost of
+   calling stat or lstat to obtain each guaranteed-valid inode number.  */
+
+#ifndef READDIR_LIES_ABOUT_MOUNTPOINT_D_INO
+# define READDIR_LIES_ABOUT_MOUNTPOINT_D_INO 1
+#endif
+
+#if READDIR_LIES_ABOUT_MOUNTPOINT_D_INO
+# define RELIABLE_D_INO(dp) NOT_AN_INODE_NUMBER
+#else
+# define RELIABLE_D_INO(dp) D_INO (dp)
+#endif
+
+#if ! HAVE_STRUCT_STAT_ST_AUTHOR
+# define st_author st_uid
+#endif
+
+enum filetype
+  {
+    unknown,
+    fifo,
+    chardev,
+    directory,
+    blockdev,
+    normal,
+    symbolic_link,
+    sock,
+    whiteout,
+    arg_directory
+  };
+
+/* Display letters and indicators for each filetype.
+   Keep these in sync with enum filetype.  */
+static char const filetype_letter[] = "?pcdb-lswd";
+
+/* Ensure that filetype and filetype_letter have the same
+   number of elements.  */
+verify (sizeof filetype_letter - 1 == arg_directory + 1);
+
+#define FILETYPE_INDICATORS				\
+  {							\
+    C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE,	\
+    C_LINK, C_SOCK, C_FILE, C_DIR			\
+  }
+
+enum acl_type
+  {
+    ACL_T_NONE,
+    ACL_T_LSM_CONTEXT_ONLY,
+    ACL_T_YES
+  };
+
+struct fileinfo
+  {
+    /* The file name.  */
+    char *name;
+
+    /* For symbolic link, name of the file linked to, otherwise zero.  */
+    char *linkname;
+
+    /* For terminal hyperlinks. */
+    char *absolute_name;
+
+    struct stat stat;
+
+    enum filetype filetype;
+
+    /* For symbolic link and long listing, st_mode of file linked to, otherwise
+       zero.  */
+    mode_t linkmode;
+
+    /* security context.  */
+    char *scontext;
+
+    bool stat_ok;
+
+    /* For symbolic link and color printing, true if linked-to file
+       exists, otherwise false.  */
+    bool linkok;
+
+    /* For long listings, true if the file has an access control list,
+       or a security context.  */
+    enum acl_type acl_type;
+
+    /* For color listings, true if a regular file has capability info.  */
+    bool has_capability;
+
+    /* Whether file name needs quoting. tri-state with -1 == unknown.  */
+    int quoted;
+  };
+
+#define LEN_STR_PAIR(s) sizeof (s) - 1, s
+
+/* Null is a valid character in a color indicator (think about Epson
+   printers, for example) so we have to use a length/buffer string
+   type.  */
+
+struct bin_str
+  {
+    size_t len;			/* Number of bytes */
+    const char *string;		/* Pointer to the same */
+  };
+
+#if ! HAVE_TCGETPGRP
+# define tcgetpgrp(Fd) 0
+#endif
+
+static size_t quote_name (char const *name,
+                          struct quoting_options const *options,
+                          int needs_general_quoting,
+                          const struct bin_str *color,
+                          bool allow_pad, struct obstack *stack,
+                          char const *absolute_name);
+static size_t quote_name_buf (char **inbuf, size_t bufsize, char *name,
+                              struct quoting_options const *options,
+                              int needs_general_quoting, size_t *width,
+                              bool *pad);
+static char *make_link_name (char const *name, char const *linkname);
+static int decode_switches (int argc, char **argv);
+static bool file_ignored (char const *name);
+static uintmax_t gobble_file (char const *name, enum filetype type,
+                              ino_t inode, bool command_line_arg,
+                              char const *dirname);
+static const struct bin_str * get_color_indicator (const struct fileinfo *f,
+                                                   bool symlink_target);
+static bool print_color_indicator (const struct bin_str *ind);
+static void put_indicator (const struct bin_str *ind);
+static void add_ignore_pattern (const char *pattern);
+static void attach (char *dest, const char *dirname, const char *name);
+static void clear_files (void);
+static void extract_dirs_from_files (char const *dirname,
+                                     bool command_line_arg);
+static void get_link_name (char const *filename, struct fileinfo *f,
+                           bool command_line_arg);
+static void indent (size_t from, size_t to);
+static size_t calculate_columns (bool by_columns);
+static void print_current_files (void);
+static void print_dir (char const *name, char const *realname,
+                       bool command_line_arg);
+static size_t print_file_name_and_frills (const struct fileinfo *f,
+                                          size_t start_col);
+static void print_horizontal (void);
+static int format_user_width (uid_t u);
+static int format_group_width (gid_t g);
+static void print_long_format (const struct fileinfo *f);
+static void print_many_per_line (void);
+static size_t print_name_with_quoting (const struct fileinfo *f,
+                                       bool symlink_target,
+                                       struct obstack *stack,
+                                       size_t start_col);
+static void prep_non_filename_text (void);
+static bool print_type_indicator (bool stat_ok, mode_t mode,
+                                  enum filetype type);
+static void print_with_separator (char sep);
+static void queue_directory (char const *name, char const *realname,
+                             bool command_line_arg);
+static void sort_files (void);
+static void parse_ls_color (void);
+
+static void getenv_quoting_style (void);
+
+/* Initial size of hash table.
+   Most hierarchies are likely to be shallower than this.  */
+#define INITIAL_TABLE_SIZE 30
+
+/* The set of 'active' directories, from the current command-line argument
+   to the level in the hierarchy at which files are being listed.
+   A directory is represented by its device and inode numbers (struct dev_ino).
+   A directory is added to this set when ls begins listing it or its
+   entries, and it is removed from the set just after ls has finished
+   processing it.  This set is used solely to detect loops, e.g., with
+   mkdir loop; cd loop; ln -s ../loop sub; ls -RL  */
+static Hash_table *active_dir_set;
+
+#define LOOP_DETECT (!!active_dir_set)
+
+/* The table of files in the current directory:
+
+   'cwd_file' points to a vector of 'struct fileinfo', one per file.
+   'cwd_n_alloc' is the number of elements space has been allocated for.
+   'cwd_n_used' is the number actually in use.  */
+
+/* Address of block containing the files that are described.  */
+static struct fileinfo *cwd_file;
+
+/* Length of block that 'cwd_file' points to, measured in files.  */
+static size_t cwd_n_alloc;
+
+/* Index of first unused slot in 'cwd_file'.  */
+static size_t cwd_n_used;
+
+/* Whether files needs may need padding due to quoting.  */
+static bool cwd_some_quoted;
+
+/* Whether quoting style _may_ add outer quotes,
+   and whether aligning those is useful.  */
+static bool align_variable_outer_quotes;
+
+/* Vector of pointers to files, in proper sorted order, and the number
+   of entries allocated for it.  */
+static void **sorted_file;
+static size_t sorted_file_alloc;
+
+/* When true, in a color listing, color each symlink name according to the
+   type of file it points to.  Otherwise, color them according to the 'ln'
+   directive in LS_COLORS.  Dangling (orphan) symlinks are treated specially,
+   regardless.  This is set when 'ln=target' appears in LS_COLORS.  */
+
+static bool color_symlink_as_referent;
+
+static char const *hostname;
+
+/* mode of appropriate file for colorization */
+#define FILE_OR_LINK_MODE(File) \
+    ((color_symlink_as_referent && (File)->linkok) \
+     ? (File)->linkmode : (File)->stat.st_mode)
+
+
+/* Record of one pending directory waiting to be listed.  */
+
+struct pending
+  {
+    char *name;
+    /* If the directory is actually the file pointed to by a symbolic link we
+       were told to list, 'realname' will contain the name of the symbolic
+       link, otherwise zero.  */
+    char *realname;
+    bool command_line_arg;
+    struct pending *next;
+  };
+
+static struct pending *pending_dirs;
+
+/* Current time in seconds and nanoseconds since 1970, updated as
+   needed when deciding whether a file is recent.  */
+
+static struct timespec current_time;
+
+static bool print_scontext;
+static char UNKNOWN_SECURITY_CONTEXT[] = "?";
+
+/* Whether any of the files has an ACL.  This affects the width of the
+   mode column.  */
+
+static bool any_has_acl;
+
+/* The number of columns to use for columns containing inode numbers,
+   block sizes, link counts, owners, groups, authors, major device
+   numbers, minor device numbers, and file sizes, respectively.  */
+
+static int inode_number_width;
+static int block_size_width;
+static int nlink_width;
+static int scontext_width;
+static int owner_width;
+static int group_width;
+static int author_width;
+static int major_device_number_width;
+static int minor_device_number_width;
+static int file_size_width;
+
+/* Option flags */
+
+/* long_format for lots of info, one per line.
+   one_per_line for just names, one per line.
+   many_per_line for just names, many per line, sorted vertically.
+   horizontal for just names, many per line, sorted horizontally.
+   with_commas for just names, many per line, separated by commas.
+
+   -l (and other options that imply -l), -1, -C, -x and -m control
+   this parameter.  */
+
+enum format
+  {
+    long_format,		/* -l and other options that imply -l */
+    one_per_line,		/* -1 */
+    many_per_line,		/* -C */
+    horizontal,			/* -x */
+    with_commas			/* -m */
+  };
+
+static enum format format;
+
+/* 'full-iso' uses full ISO-style dates and times.  'long-iso' uses longer
+   ISO-style timestamps, though shorter than 'full-iso'.  'iso' uses shorter
+   ISO-style timestamps.  'locale' uses locale-dependent timestamps.  */
+enum time_style
+  {
+    full_iso_time_style,	/* --time-style=full-iso */
+    long_iso_time_style,	/* --time-style=long-iso */
+    iso_time_style,		/* --time-style=iso */
+    locale_time_style		/* --time-style=locale */
+  };
+
+static char const *const time_style_args[] =
+{
+  "full-iso", "long-iso", "iso", "locale", NULL
+};
+static enum time_style const time_style_types[] =
+{
+  full_iso_time_style, long_iso_time_style, iso_time_style,
+  locale_time_style
+};
+ARGMATCH_VERIFY (time_style_args, time_style_types);
+
+/* Type of time to print or sort by.  Controlled by -c and -u.
+   The values of each item of this enum are important since they are
+   used as indices in the sort functions array (see sort_files()).  */
+
+enum time_type
+  {
+    time_mtime,			/* default */
+    time_ctime,			/* -c */
+    time_atime,			/* -u */
+    time_btime,                 /* birth time */
+    time_numtypes		/* the number of elements of this enum */
+  };
+
+static enum time_type time_type;
+
+/* The file characteristic to sort by.  Controlled by -t, -S, -U, -X, -v.
+   The values of each item of this enum are important since they are
+   used as indices in the sort functions array (see sort_files()).  */
+
+enum sort_type
+  {
+    sort_none = -1,		/* -U */
+    sort_name,			/* default */
+    sort_extension,		/* -X */
+    sort_size,			/* -S */
+    sort_version,		/* -v */
+    sort_time,			/* -t */
+    sort_numtypes		/* the number of elements of this enum */
+  };
+
+static enum sort_type sort_type;
+
+/* Direction of sort.
+   false means highest first if numeric,
+   lowest first if alphabetic;
+   these are the defaults.
+   true means the opposite order in each case.  -r  */
+
+static bool sort_reverse;
+
+/* True means to display owner information.  -g turns this off.  */
+
+static bool print_owner = true;
+
+/* True means to display author information.  */
+
+static bool print_author;
+
+/* True means to display group information.  -G and -o turn this off.  */
+
+static bool print_group = true;
+
+/* True means print the user and group id's as numbers rather
+   than as names.  -n  */
+
+static bool numeric_ids;
+
+/* True means mention the size in blocks of each file.  -s  */
+
+static bool print_block_size;
+
+/* Human-readable options for output, when printing block counts.  */
+static int human_output_opts;
+
+/* The units to use when printing block counts.  */
+static uintmax_t output_block_size;
+
+/* Likewise, but for file sizes.  */
+static int file_human_output_opts;
+static uintmax_t file_output_block_size = 1;
+
+/* Follow the output with a special string.  Using this format,
+   Emacs' dired mode starts up twice as fast, and can handle all
+   strange characters in file names.  */
+static bool dired;
+
+/* 'none' means don't mention the type of files.
+   'slash' means mention directories only, with a '/'.
+   'file_type' means mention file types.
+   'classify' means mention file types and mark executables.
+
+   Controlled by -F, -p, and --indicator-style.  */
+
+enum indicator_style
+  {
+    none,	/*     --indicator-style=none */
+    slash,	/* -p, --indicator-style=slash */
+    file_type,	/*     --indicator-style=file-type */
+    classify	/* -F, --indicator-style=classify */
+  };
+
+static enum indicator_style indicator_style;
+
+/* Names of indicator styles.  */
+static char const *const indicator_style_args[] =
+{
+  "none", "slash", "file-type", "classify", NULL
+};
+static enum indicator_style const indicator_style_types[] =
+{
+  none, slash, file_type, classify
+};
+ARGMATCH_VERIFY (indicator_style_args, indicator_style_types);
+
+/* True means use colors to mark types.  Also define the different
+   colors as well as the stuff for the LS_COLORS environment variable.
+   The LS_COLORS variable is now in a termcap-like format.  */
+
+static bool print_with_color;
+
+static bool print_hyperlink;
+
+/* Whether we used any colors in the output so far.  If so, we will
+   need to restore the default color later.  If not, we will need to
+   call prep_non_filename_text before using color for the first time. */
+
+static bool used_color = false;
+
+enum when_type
+  {
+    when_never,		/* 0: default or --color=never */
+    when_always,	/* 1: --color=always */
+    when_if_tty		/* 2: --color=tty */
+  };
+
+enum Dereference_symlink
+  {
+    DEREF_UNDEFINED = 1,
+    DEREF_NEVER,
+    DEREF_COMMAND_LINE_ARGUMENTS,	/* -H */
+    DEREF_COMMAND_LINE_SYMLINK_TO_DIR,	/* the default, in certain cases */
+    DEREF_ALWAYS			/* -L */
+  };
+
+enum indicator_no
+  {
+    C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK,
+    C_FIFO, C_SOCK,
+    C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID,
+    C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_MULTIHARDLINK,
+    C_CLR_TO_EOL
+  };
+
+static const char *const indicator_name[]=
+  {
+    "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so",
+    "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st",
+    "ow", "tw", "ca", "mh", "cl", NULL
+  };
+
+struct color_ext_type
+  {
+    struct bin_str ext;		/* The extension we're looking for */
+    struct bin_str seq;		/* The sequence to output when we do */
+    struct color_ext_type *next;	/* Next in list */
+  };
+
+static struct bin_str color_indicator[] =
+  {
+    { LEN_STR_PAIR ("\033[") },		/* lc: Left of color sequence */
+    { LEN_STR_PAIR ("m") },		/* rc: Right of color sequence */
+    { 0, NULL },			/* ec: End color (replaces lc+rs+rc) */
+    { LEN_STR_PAIR ("0") },		/* rs: Reset to ordinary colors */
+    { 0, NULL },			/* no: Normal */
+    { 0, NULL },			/* fi: File: default */
+    { LEN_STR_PAIR ("01;34") },		/* di: Directory: bright blue */
+    { LEN_STR_PAIR ("01;36") },		/* ln: Symlink: bright cyan */
+    { LEN_STR_PAIR ("33") },		/* pi: Pipe: yellow/brown */
+    { LEN_STR_PAIR ("01;35") },		/* so: Socket: bright magenta */
+    { LEN_STR_PAIR ("01;33") },		/* bd: Block device: bright yellow */
+    { LEN_STR_PAIR ("01;33") },		/* cd: Char device: bright yellow */
+    { 0, NULL },			/* mi: Missing file: undefined */
+    { 0, NULL },			/* or: Orphaned symlink: undefined */
+    { LEN_STR_PAIR ("01;32") },		/* ex: Executable: bright green */
+    { LEN_STR_PAIR ("01;35") },		/* do: Door: bright magenta */
+    { LEN_STR_PAIR ("37;41") },		/* su: setuid: white on red */
+    { LEN_STR_PAIR ("30;43") },		/* sg: setgid: black on yellow */
+    { LEN_STR_PAIR ("37;44") },		/* st: sticky: black on blue */
+    { LEN_STR_PAIR ("34;42") },		/* ow: other-writable: blue on green */
+    { LEN_STR_PAIR ("30;42") },		/* tw: ow w/ sticky: black on green */
+    { LEN_STR_PAIR ("30;41") },		/* ca: black on red */
+    { 0, NULL },			/* mh: disabled by default */
+    { LEN_STR_PAIR ("\033[K") },	/* cl: clear to end of line */
+  };
+
+/* FIXME: comment  */
+static struct color_ext_type *color_ext_list = NULL;
+
+/* Buffer for color sequences */
+static char *color_buf;
+
+/* True means to check for orphaned symbolic link, for displaying
+   colors, or to group symlink to directories with other dirs.  */
+
+static bool check_symlink_mode;
+
+/* True means mention the inode number of each file.  -i  */
+
+static bool print_inode;
+
+/* What to do with symbolic links.  Affected by -d, -F, -H, -l (and
+   other options that imply -l), and -L.  */
+
+static enum Dereference_symlink dereference;
+
+/* True means when a directory is found, display info on its
+   contents.  -R  */
+
+static bool recursive;
+
+/* True means when an argument is a directory name, display info
+   on it itself.  -d  */
+
+static bool immediate_dirs;
+
+/* True means that directories are grouped before files. */
+
+static bool directories_first;
+
+/* Which files to ignore.  */
+
+static enum
+{
+  /* Ignore files whose names start with '.', and files specified by
+     --hide and --ignore.  */
+  IGNORE_DEFAULT,
+
+  /* Ignore '.', '..', and files specified by --ignore.  */
+  IGNORE_DOT_AND_DOTDOT,
+
+  /* Ignore only files specified by --ignore.  */
+  IGNORE_MINIMAL
+} ignore_mode;
+
+/* A linked list of shell-style globbing patterns.  If a non-argument
+   file name matches any of these patterns, it is ignored.
+   Controlled by -I.  Multiple -I options accumulate.
+   The -B option adds '*~' and '.*~' to this list.  */
+
+struct ignore_pattern
+  {
+    const char *pattern;
+    struct ignore_pattern *next;
+  };
+
+static struct ignore_pattern *ignore_patterns;
+
+/* Similar to IGNORE_PATTERNS, except that -a or -A causes this
+   variable itself to be ignored.  */
+static struct ignore_pattern *hide_patterns;
+
+/* True means output nongraphic chars in file names as '?'.
+   (-q, --hide-control-chars)
+   qmark_funny_chars and the quoting style (-Q, --quoting-style=WORD) are
+   independent.  The algorithm is: first, obey the quoting style to get a
+   string representing the file name;  then, if qmark_funny_chars is set,
+   replace all nonprintable chars in that string with '?'.  It's necessary
+   to replace nonprintable chars even in quoted strings, because we don't
+   want to mess up the terminal if control chars get sent to it, and some
+   quoting methods pass through control chars as-is.  */
+static bool qmark_funny_chars;
+
+/* Quoting options for file and dir name output.  */
+
+static struct quoting_options *filename_quoting_options;
+static struct quoting_options *dirname_quoting_options;
+
+/* The number of chars per hardware tab stop.  Setting this to zero
+   inhibits the use of TAB characters for separating columns.  -T */
+static size_t tabsize;
+
+/* True means print each directory name before listing it.  */
+
+static bool print_dir_name;
+
+/* The line length to use for breaking lines in many-per-line format.
+   Can be set with -w.  */
+
+static size_t line_length;
+
+/* The local time zone rules, as per the TZ environment variable.  */
+
+static timezone_t localtz;
+
+/* If true, the file listing format requires that stat be called on
+   each file.  */
+
+static bool format_needs_stat;
+
+/* Similar to 'format_needs_stat', but set if only the file type is
+   needed.  */
+
+static bool format_needs_type;
+
+/* An arbitrary limit on the number of bytes in a printed timestamp.
+   This is set to a relatively small value to avoid the need to worry
+   about denial-of-service attacks on servers that run "ls" on behalf
+   of remote clients.  1000 bytes should be enough for any practical
+   timestamp format.  */
+
+enum { TIME_STAMP_LEN_MAXIMUM = MAX (1000, INT_STRLEN_BOUND (time_t)) };
+
+/* strftime formats for non-recent and recent files, respectively, in
+   -l output.  */
+
+static char const *long_time_format[2] =
+  {
+    /* strftime format for non-recent files (older than 6 months), in
+       -l output.  This should contain the year, month and day (at
+       least), in an order that is understood by people in your
+       locale's territory.  Please try to keep the number of used
+       screen columns small, because many people work in windows with
+       only 80 columns.  But make this as wide as the other string
+       below, for recent files.  */
+    /* TRANSLATORS: ls output needs to be aligned for ease of reading,
+       so be wary of using variable width fields from the locale.
+       Note %b is handled specially by ls and aligned correctly.
+       Note also that specifying a width as in %5b is erroneous as strftime
+       will count bytes rather than characters in multibyte locales.  */
+    N_("%b %e  %Y"),
+    /* strftime format for recent files (younger than 6 months), in -l
+       output.  This should contain the month, day and time (at
+       least), in an order that is understood by people in your
+       locale's territory.  Please try to keep the number of used
+       screen columns small, because many people work in windows with
+       only 80 columns.  But make this as wide as the other string
+       above, for non-recent files.  */
+    /* TRANSLATORS: ls output needs to be aligned for ease of reading,
+       so be wary of using variable width fields from the locale.
+       Note %b is handled specially by ls and aligned correctly.
+       Note also that specifying a width as in %5b is erroneous as strftime
+       will count bytes rather than characters in multibyte locales.  */
+    N_("%b %e %H:%M")
+  };
+
+/* The set of signals that are caught.  */
+
+static sigset_t caught_signals;
+
+/* If nonzero, the value of the pending fatal signal.  */
+
+static sig_atomic_t volatile interrupt_signal;
+
+/* A count of the number of pending stop signals that have been received.  */
+
+static sig_atomic_t volatile stop_signal_count;
+
+/* Desired exit status.  */
+
+static int exit_status;
+
+/* Exit statuses.  */
+enum
+  {
+    /* "ls" had a minor problem.  E.g., while processing a directory,
+       ls obtained the name of an entry via readdir, yet was later
+       unable to stat that name.  This happens when listing a directory
+       in which entries are actively being removed or renamed.  */
+    LS_MINOR_PROBLEM = 1,
+
+    /* "ls" had more serious trouble (e.g., memory exhausted, invalid
+       option or failure to stat a command line argument.  */
+    LS_FAILURE = 2
+  };
+
+/* For long options that have no equivalent short option, use a
+   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
+enum
+{
+  AUTHOR_OPTION = CHAR_MAX + 1,
+  BLOCK_SIZE_OPTION,
+  COLOR_OPTION,
+  DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION,
+  FILE_TYPE_INDICATOR_OPTION,
+  FORMAT_OPTION,
+  FULL_TIME_OPTION,
+  GROUP_DIRECTORIES_FIRST_OPTION,
+  HIDE_OPTION,
+  HYPERLINK_OPTION,
+  INDICATOR_STYLE_OPTION,
+  QUOTING_STYLE_OPTION,
+  SHOW_CONTROL_CHARS_OPTION,
+  SI_OPTION,
+  SORT_OPTION,
+  TIME_OPTION,
+  TIME_STYLE_OPTION
+};
+
+static struct option const long_options[] =
+{
+  {"all", no_argument, NULL, 'a'},
+  {"escape", no_argument, NULL, 'b'},
+  {"directory", no_argument, NULL, 'd'},
+  {"dired", no_argument, NULL, 'D'},
+  {"full-time", no_argument, NULL, FULL_TIME_OPTION},
+  {"group-directories-first", no_argument, NULL,
+   GROUP_DIRECTORIES_FIRST_OPTION},
+  {"human-readable", no_argument, NULL, 'h'},
+  {"inode", no_argument, NULL, 'i'},
+  {"kibibytes", no_argument, NULL, 'k'},
+  {"numeric-uid-gid", no_argument, NULL, 'n'},
+  {"no-group", no_argument, NULL, 'G'},
+  {"hide-control-chars", no_argument, NULL, 'q'},
+  {"reverse", no_argument, NULL, 'r'},
+  {"size", no_argument, NULL, 's'},
+  {"width", required_argument, NULL, 'w'},
+  {"almost-all", no_argument, NULL, 'A'},
+  {"ignore-backups", no_argument, NULL, 'B'},
+  {"classify", no_argument, NULL, 'F'},
+  {"file-type", no_argument, NULL, FILE_TYPE_INDICATOR_OPTION},
+  {"si", no_argument, NULL, SI_OPTION},
+  {"dereference-command-line", no_argument, NULL, 'H'},
+  {"dereference-command-line-symlink-to-dir", no_argument, NULL,
+   DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION},
+  {"hide", required_argument, NULL, HIDE_OPTION},
+  {"ignore", required_argument, NULL, 'I'},
+  {"indicator-style", required_argument, NULL, INDICATOR_STYLE_OPTION},
+  {"dereference", no_argument, NULL, 'L'},
+  {"literal", no_argument, NULL, 'N'},
+  {"quote-name", no_argument, NULL, 'Q'},
+  {"quoting-style", required_argument, NULL, QUOTING_STYLE_OPTION},
+  {"recursive", no_argument, NULL, 'R'},
+  {"format", required_argument, NULL, FORMAT_OPTION},
+  {"show-control-chars", no_argument, NULL, SHOW_CONTROL_CHARS_OPTION},
+  {"sort", required_argument, NULL, SORT_OPTION},
+  {"tabsize", required_argument, NULL, 'T'},
+  {"time", required_argument, NULL, TIME_OPTION},
+  {"time-style", required_argument, NULL, TIME_STYLE_OPTION},
+  {"color", optional_argument, NULL, COLOR_OPTION},
+  {"hyperlink", optional_argument, NULL, HYPERLINK_OPTION},
+  {"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
+  {"context", no_argument, 0, 'Z'},
+  {"author", no_argument, NULL, AUTHOR_OPTION},
+  {GETOPT_HELP_OPTION_DECL},
+  {GETOPT_VERSION_OPTION_DECL},
+  {NULL, 0, NULL, 0}
+};
+
+static char const *const format_args[] =
+{
+  "verbose", "long", "commas", "horizontal", "across",
+  "vertical", "single-column", NULL
+};
+static enum format const format_types[] =
+{
+  long_format, long_format, with_commas, horizontal, horizontal,
+  many_per_line, one_per_line
+};
+ARGMATCH_VERIFY (format_args, format_types);
+
+static char const *const sort_args[] =
+{
+  "none", "time", "size", "extension", "version", NULL
+};
+static enum sort_type const sort_types[] =
+{
+  sort_none, sort_time, sort_size, sort_extension, sort_version
+};
+ARGMATCH_VERIFY (sort_args, sort_types);
+
+static char const *const time_args[] =
+{
+  "atime", "access", "use",
+  "ctime", "status",
+  "birth", "creation",
+  NULL
+};
+static enum time_type const time_types[] =
+{
+  time_atime, time_atime, time_atime,
+  time_ctime, time_ctime,
+  time_btime, time_btime,
+};
+ARGMATCH_VERIFY (time_args, time_types);
+
+static char const *const when_args[] =
+{
+  /* force and none are for compatibility with another color-ls version */
+  "always", "yes", "force",
+  "never", "no", "none",
+  "auto", "tty", "if-tty", NULL
+};
+static enum when_type const when_types[] =
+{
+  when_always, when_always, when_always,
+  when_never, when_never, when_never,
+  when_if_tty, when_if_tty, when_if_tty
+};
+ARGMATCH_VERIFY (when_args, when_types);
+
+/* Information about filling a column.  */
+struct column_info
+{
+  bool valid_len;
+  size_t line_len;
+  size_t *col_arr;
+};
+
+/* Array with information about column filledness.  */
+static struct column_info *column_info;
+
+/* Maximum number of columns ever possible for this display.  */
+static size_t max_idx;
+
+/* The minimum width of a column is 3: 1 character for the name and 2
+   for the separating white space.  */
+#define MIN_COLUMN_WIDTH	3
+
+
+/* This zero-based index is used solely with the --dired option.
+   When that option is in effect, this counter is incremented for each
+   byte of output generated by this program so that the beginning
+   and ending indices (in that output) of every file name can be recorded
+   and later output themselves.  */
+static size_t dired_pos;
+
+#define DIRED_PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0)
+
+/* Write S to STREAM and increment DIRED_POS by S_LEN.  */
+#define DIRED_FPUTS(s, stream, s_len) \
+    do {fputs (s, stream); dired_pos += s_len;} while (0)
+
+/* Like DIRED_FPUTS, but for use when S is a literal string.  */
+#define DIRED_FPUTS_LITERAL(s, stream) \
+    do {fputs (s, stream); dired_pos += sizeof (s) - 1;} while (0)
+
+#define DIRED_INDENT()							\
+    do									\
+      {									\
+        if (dired)							\
+          DIRED_FPUTS_LITERAL ("  ", stdout);				\
+      }									\
+    while (0)
+
+/* With --dired, store pairs of beginning and ending indices of file names.  */
+static struct obstack dired_obstack;
+
+/* With --dired, store pairs of beginning and ending indices of any
+   directory names that appear as headers (just before 'total' line)
+   for lists of directory entries.  Such directory names are seen when
+   listing hierarchies using -R and when a directory is listed with at
+   least one other command line argument.  */
+static struct obstack subdired_obstack;
+
+/* Save the current index on the specified obstack, OBS.  */
+#define PUSH_CURRENT_DIRED_POS(obs)					\
+  do									\
+    {									\
+      if (dired)							\
+        obstack_grow (obs, &dired_pos, sizeof (dired_pos));		\
+    }									\
+  while (0)
+
+/* With -R, this stack is used to help detect directory cycles.
+   The device/inode pairs on this stack mirror the pairs in the
+   active_dir_set hash table.  */
+static struct obstack dev_ino_obstack;
+
+/* Push a pair onto the device/inode stack.  */
+static void
+dev_ino_push (dev_t dev, ino_t ino)
+{
+  void *vdi;
+  struct dev_ino *di;
+  int dev_ino_size = sizeof *di;
+  obstack_blank (&dev_ino_obstack, dev_ino_size);
+  vdi = obstack_next_free (&dev_ino_obstack);
+  di = vdi;
+  di--;
+  di->st_dev = dev;
+  di->st_ino = ino;
+}
+
+/* Pop a dev/ino struct off the global dev_ino_obstack
+   and return that struct.  */
+static struct dev_ino
+dev_ino_pop (void)
+{
+  void *vdi;
+  struct dev_ino *di;
+  int dev_ino_size = sizeof *di;
+  assert (dev_ino_size <= obstack_object_size (&dev_ino_obstack));
+  obstack_blank_fast (&dev_ino_obstack, -dev_ino_size);
+  vdi = obstack_next_free (&dev_ino_obstack);
+  di = vdi;
+  return *di;
+}
+
+/* Note the use commented out below:
+#define ASSERT_MATCHING_DEV_INO(Name, Di)	\
+  do						\
+    {						\
+      struct stat sb;				\
+      assert (Name);				\
+      assert (0 <= stat (Name, &sb));		\
+      assert (sb.st_dev == Di.st_dev);		\
+      assert (sb.st_ino == Di.st_ino);		\
+    }						\
+  while (0)
+*/
+
+/* Write to standard output PREFIX, followed by the quoting style and
+   a space-separated list of the integers stored in OS all on one line.  */
+
+static void
+dired_dump_obstack (const char *prefix, struct obstack *os)
+{
+  size_t n_pos;
+
+  n_pos = obstack_object_size (os) / sizeof (dired_pos);
+  if (n_pos > 0)
+    {
+      size_t *pos = (size_t *) obstack_finish (os);
+      fputs (prefix, stdout);
+      for (size_t i = 0; i < n_pos; i++)
+        printf (" %lu", (unsigned long int) pos[i]);
+      putchar ('\n');
+    }
+}
+
+/* Return the platform birthtime member of the stat structure,
+   or fallback to the mtime member, which we have populated
+   from the statx structure or reset to an invalid timestamp
+   where birth time is not supported.  */
+static struct timespec
+get_stat_btime (struct stat const *st)
+{
+  struct timespec btimespec;
+
+#if HAVE_STATX && defined STATX_INO
+  btimespec = get_stat_mtime (st);
+#else
+  btimespec = get_stat_birthtime (st);
+#endif
+
+  return btimespec;
+}
+
+#if HAVE_STATX && defined STATX_INO
+static unsigned int _GL_ATTRIBUTE_PURE
+time_type_to_statx (void)
+{
+  switch (time_type)
+    {
+    case time_ctime:
+      return STATX_CTIME;
+    case time_mtime:
+      return STATX_MTIME;
+    case time_atime:
+      return STATX_ATIME;
+    case time_btime:
+      return STATX_BTIME;
+    default:
+      abort ();
+    }
+    return 0;
+}
+
+static unsigned int _GL_ATTRIBUTE_PURE
+calc_req_mask (void)
+{
+  unsigned int mask = STATX_MODE;
+
+  if (print_inode)
+    mask |= STATX_INO;
+
+  if (print_block_size)
+    mask |= STATX_BLOCKS;
+
+  if (format == long_format) {
+    mask |= STATX_NLINK | STATX_SIZE | time_type_to_statx ();
+    if (print_owner || print_author)
+      mask |= STATX_UID;
+    if (print_group)
+      mask |= STATX_GID;
+  }
+
+  switch (sort_type)
+    {
+    case sort_none:
+    case sort_name:
+    case sort_version:
+    case sort_extension:
+      break;
+    case sort_time:
+      mask |= time_type_to_statx ();
+      break;
+    case sort_size:
+      mask |= STATX_SIZE;
+      break;
+    default:
+      abort ();
+    }
+
+  return mask;
+}
+
+static int
+do_statx (int fd, const char *name, struct stat *st, int flags,
+          unsigned int mask)
+{
+  struct statx stx;
+  bool want_btime = mask & STATX_BTIME;
+  int ret = statx (fd, name, flags, mask, &stx);
+  if (ret >= 0)
+    {
+      statx_to_stat (&stx, st);
+      /* Since we only need one timestamp type,
+         store birth time in st_mtim.  */
+      if (want_btime)
+        {
+          if (stx.stx_mask & STATX_BTIME)
+            st->st_mtim = statx_timestamp_to_timespec (stx.stx_btime);
+          else
+            st->st_mtim.tv_sec = st->st_mtim.tv_nsec = -1;
+        }
+    }
+
+  return ret;
+}
+
+static inline int
+do_stat (const char *name, struct stat *st)
+{
+  return do_statx (AT_FDCWD, name, st, 0, calc_req_mask ());
+}
+
+static inline int
+do_lstat (const char *name, struct stat *st)
+{
+  return do_statx (AT_FDCWD, name, st, AT_SYMLINK_NOFOLLOW, calc_req_mask ());
+}
+
+static inline int
+stat_for_mode (const char *name, struct stat *st)
+{
+  return do_statx (AT_FDCWD, name, st, 0, STATX_MODE);
+}
+
+/* dev+ino should be static, so no need to sync with backing store */
+static inline int
+stat_for_ino (const char *name, struct stat *st)
+{
+  return do_statx (AT_FDCWD, name, st, 0, STATX_INO);
+}
+
+static inline int
+fstat_for_ino (int fd, struct stat *st)
+{
+  return do_statx (fd, "", st, AT_EMPTY_PATH, STATX_INO);
+}
+#else
+static inline int
+do_stat (const char *name, struct stat *st)
+{
+  return stat (name, st);
+}
+
+static inline int
+do_lstat (const char *name, struct stat *st)
+{
+  return lstat (name, st);
+}
+
+static inline int
+stat_for_mode (const char *name, struct stat *st)
+{
+  return stat (name, st);
+}
+
+static inline int
+stat_for_ino (const char *name, struct stat *st)
+{
+  return stat (name, st);
+}
+
+static inline int
+fstat_for_ino (int fd, struct stat *st)
+{
+  return fstat (fd, st);
+}
+#endif
+
+/* Return the address of the first plain %b spec in FMT, or NULL if
+   there is no such spec.  %5b etc. do not match, so that user
+   widths/flags are honored.  */
+
+static char const * _GL_ATTRIBUTE_PURE
+first_percent_b (char const *fmt)
+{
+  for (; *fmt; fmt++)
+    if (fmt[0] == '%')
+      switch (fmt[1])
+        {
+        case 'b': return fmt;
+        case '%': fmt++; break;
+        }
+  return NULL;
+}
+
+static char RFC3986[256];
+static void
+file_escape_init (void)
+{
+  for (int i = 0; i < 256; i++)
+    RFC3986[i] |= c_isalnum (i) || i == '~' || i == '-' || i == '.' || i == '_';
+}
+
+/* Read the abbreviated month names from the locale, to align them
+   and to determine the max width of the field and to truncate names
+   greater than our max allowed.
+   Note even though this handles multibyte locales correctly
+   it's not restricted to them as single byte locales can have
+   variable width abbreviated months and also precomputing/caching
+   the names was seen to increase the performance of ls significantly.  */
+
+/* max number of display cells to use.
+   As of 2018 the abmon for Arabic has entries with width 12.
+   It doesn't make much sense to support wider than this
+   and locales should aim for abmon entries of width <= 5.  */
+enum { MAX_MON_WIDTH = 12 };
+/* abformat[RECENT][MON] is the format to use for timestamps with
+   recentness RECENT and month MON.  */
+enum { ABFORMAT_SIZE = 128 };
+static char abformat[2][12][ABFORMAT_SIZE];
+/* True if precomputed formats should be used.  This can be false if
+   nl_langinfo fails, if a format or month abbreviation is unusually
+   long, or if a month abbreviation contains '%'.  */
+static bool use_abformat;
+
+/* Store into ABMON the abbreviated month names, suitably aligned.
+   Return true if successful.  */
+
+static bool
+abmon_init (char abmon[12][ABFORMAT_SIZE])
+{
+#ifndef HAVE_NL_LANGINFO
+  return false;
+#else
+  size_t required_mon_width = MAX_MON_WIDTH;
+  size_t curr_max_width;
+  do
+    {
+      curr_max_width = required_mon_width;
+      required_mon_width = 0;
+      for (int i = 0; i < 12; i++)
+        {
+          size_t width = curr_max_width;
+          char const *abbr = nl_langinfo (ABMON_1 + i);
+          if (strchr (abbr, '%'))
+            return false;
+          mbs_align_t alignment = isdigit (to_uchar (*abbr))
+                                  ? MBS_ALIGN_RIGHT : MBS_ALIGN_LEFT;
+          size_t req = mbsalign (abbr, abmon[i], ABFORMAT_SIZE,
+                                 &width, alignment, 0);
+          if (! (req < ABFORMAT_SIZE))
+            return false;
+          required_mon_width = MAX (required_mon_width, width);
+        }
+    }
+  while (curr_max_width > required_mon_width);
+
+  return true;
+#endif
+}
+
+/* Initialize ABFORMAT and USE_ABFORMAT.  */
+
+static void
+abformat_init (void)
+{
+  char const *pb[2];
+  for (int recent = 0; recent < 2; recent++)
+    pb[recent] = first_percent_b (long_time_format[recent]);
+  if (! (pb[0] || pb[1]))
+    return;
+
+  char abmon[12][ABFORMAT_SIZE];
+  if (! abmon_init (abmon))
+    return;
+
+  for (int recent = 0; recent < 2; recent++)
+    {
+      char const *fmt = long_time_format[recent];
+      for (int i = 0; i < 12; i++)
+        {
+          char *nfmt = abformat[recent][i];
+          int nbytes;
+
+          if (! pb[recent])
+            nbytes = snprintf (nfmt, ABFORMAT_SIZE, "%s", fmt);
+          else
+            {
+              if (! (pb[recent] - fmt <= MIN (ABFORMAT_SIZE, INT_MAX)))
+                return;
+              int prefix_len = pb[recent] - fmt;
+              nbytes = snprintf (nfmt, ABFORMAT_SIZE, "%.*s%s%s",
+                                 prefix_len, fmt, abmon[i], pb[recent] + 2);
+            }
+
+          if (! (0 <= nbytes && nbytes < ABFORMAT_SIZE))
+            return;
+        }
+    }
+
+  use_abformat = true;
+}
+
+static size_t
+dev_ino_hash (void const *x, size_t table_size)
+{
+  struct dev_ino const *p = x;
+  return (uintmax_t) p->st_ino % table_size;
+}
+
+static bool
+dev_ino_compare (void const *x, void const *y)
+{
+  struct dev_ino const *a = x;
+  struct dev_ino const *b = y;
+  return SAME_INODE (*a, *b) ? true : false;
+}
+
+static void
+dev_ino_free (void *x)
+{
+  free (x);
+}
+
+/* Add the device/inode pair (P->st_dev/P->st_ino) to the set of
+   active directories.  Return true if there is already a matching
+   entry in the table.  */
+
+static bool
+visit_dir (dev_t dev, ino_t ino)
+{
+  struct dev_ino *ent;
+  struct dev_ino *ent_from_table;
+  bool found_match;
+
+  ent = xmalloc (sizeof *ent);
+  ent->st_ino = ino;
+  ent->st_dev = dev;
+
+  /* Attempt to insert this entry into the table.  */
+  ent_from_table = hash_insert (active_dir_set, ent);
+
+  if (ent_from_table == NULL)
+    {
+      /* Insertion failed due to lack of memory.  */
+      xalloc_die ();
+    }
+
+  found_match = (ent_from_table != ent);
+
+  if (found_match)
+    {
+      /* ent was not inserted, so free it.  */
+      free (ent);
+    }
+
+  return found_match;
+}
+
+static void
+free_pending_ent (struct pending *p)
+{
+  free (p->name);
+  free (p->realname);
+  free (p);
+}
+
+static bool
+is_colored (enum indicator_no type)
+{
+  size_t len = color_indicator[type].len;
+  char const *s = color_indicator[type].string;
+  return ! (len == 0
+            || (len == 1 && STRNCMP_LIT (s, "0") == 0)
+            || (len == 2 && STRNCMP_LIT (s, "00") == 0));
+}
+
+static void
+restore_default_color (void)
+{
+  put_indicator (&color_indicator[C_LEFT]);
+  put_indicator (&color_indicator[C_RIGHT]);
+}
+
+static void
+set_normal_color (void)
+{
+  if (print_with_color && is_colored (C_NORM))
+    {
+      put_indicator (&color_indicator[C_LEFT]);
+      put_indicator (&color_indicator[C_NORM]);
+      put_indicator (&color_indicator[C_RIGHT]);
+    }
+}
+
+/* An ordinary signal was received; arrange for the program to exit.  */
+
+static void
+sighandler (int sig)
+{
+  if (! SA_NOCLDSTOP)
+    signal (sig, SIG_IGN);
+  if (! interrupt_signal)
+    interrupt_signal = sig;
+}
+
+/* A SIGTSTP was received; arrange for the program to suspend itself.  */
+
+static void
+stophandler (int sig)
+{
+  if (! SA_NOCLDSTOP)
+    signal (sig, stophandler);
+  if (! interrupt_signal)
+    stop_signal_count++;
+}
+
+/* Process any pending signals.  If signals are caught, this function
+   should be called periodically.  Ideally there should never be an
+   unbounded amount of time when signals are not being processed.
+   Signal handling can restore the default colors, so callers must
+   immediately change colors after invoking this function.  */
+
+static void
+process_signals (void)
+{
+  while (interrupt_signal || stop_signal_count)
+    {
+      int sig;
+      int stops;
+      sigset_t oldset;
+
+      if (used_color)
+        restore_default_color ();
+      fflush (stdout);
+
+      sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
+
+      /* Reload interrupt_signal and stop_signal_count, in case a new
+         signal was handled before sigprocmask took effect.  */
+      sig = interrupt_signal;
+      stops = stop_signal_count;
+
+      /* SIGTSTP is special, since the application can receive that signal
+         more than once.  In this case, don't set the signal handler to the
+         default.  Instead, just raise the uncatchable SIGSTOP.  */
+      if (stops)
+        {
+          stop_signal_count = stops - 1;
+          sig = SIGSTOP;
+        }
+      else
+        signal (sig, SIG_DFL);
+
+      /* Exit or suspend the program.  */
+      raise (sig);
+      sigprocmask (SIG_SETMASK, &oldset, NULL);
+
+      /* If execution reaches here, then the program has been
+         continued (after being suspended).  */
+    }
+}
+
+/* Setup signal handlers if INIT is true,
+   otherwise restore to the default.  */
+
+static void
+signal_setup (bool init)
+{
+  /* The signals that are trapped, and the number of such signals.  */
+  static int const sig[] =
+    {
+      /* This one is handled specially.  */
+      SIGTSTP,
+
+      /* The usual suspects.  */
+      SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
+#ifdef SIGPOLL
+      SIGPOLL,
+#endif
+#ifdef SIGPROF
+      SIGPROF,
+#endif
+#ifdef SIGVTALRM
+      SIGVTALRM,
+#endif
+#ifdef SIGXCPU
+      SIGXCPU,
+#endif
+#ifdef SIGXFSZ
+      SIGXFSZ,
+#endif
+    };
+  enum { nsigs = ARRAY_CARDINALITY (sig) };
+
+#if ! SA_NOCLDSTOP
+  static bool caught_sig[nsigs];
+#endif
+
+  int j;
+
+  if (init)
+    {
+#if SA_NOCLDSTOP
+      struct sigaction act;
+
+      sigemptyset (&caught_signals);
+      for (j = 0; j < nsigs; j++)
+        {
+          sigaction (sig[j], NULL, &act);
+          if (act.sa_handler != SIG_IGN)
+            sigaddset (&caught_signals, sig[j]);
+        }
+
+      act.sa_mask = caught_signals;
+      act.sa_flags = SA_RESTART;
+
+      for (j = 0; j < nsigs; j++)
+        if (sigismember (&caught_signals, sig[j]))
+          {
+            act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler;
+            sigaction (sig[j], &act, NULL);
+          }
+#else
+      for (j = 0; j < nsigs; j++)
+        {
+          caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN);
+          if (caught_sig[j])
+            {
+              signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler);
+              siginterrupt (sig[j], 0);
+            }
+        }
+#endif
+    }
+  else /* restore.  */
+    {
+#if SA_NOCLDSTOP
+      for (j = 0; j < nsigs; j++)
+        if (sigismember (&caught_signals, sig[j]))
+          signal (sig[j], SIG_DFL);
+#else
+      for (j = 0; j < nsigs; j++)
+        if (caught_sig[j])
+          signal (sig[j], SIG_DFL);
+#endif
+    }
+}
+
+static inline void
+signal_init (void)
+{
+  signal_setup (true);
+}
+
+static inline void
+signal_restore (void)
+{
+  signal_setup (false);
+}
+
+int
+main (int argc, char **argv)
+{
+  int i;
+  struct pending *thispend;
+  int n_files;
+
+  initialize_main (&argc, &argv);
+  set_program_name (argv[0]);
+  setlocale (LC_ALL, "");
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
+  initialize_exit_failure (LS_FAILURE);
+  atexit (close_stdout);
+
+  assert (ARRAY_CARDINALITY (color_indicator) + 1
+          == ARRAY_CARDINALITY (indicator_name));
+
+  exit_status = EXIT_SUCCESS;
+  print_dir_name = true;
+  pending_dirs = NULL;
+
+  current_time.tv_sec = TYPE_MINIMUM (time_t);
+  current_time.tv_nsec = -1;
+
+  i = decode_switches (argc, argv);
+
+  if (print_with_color)
+    parse_ls_color ();
+
+  /* Test print_with_color again, because the call to parse_ls_color
+     may have just reset it -- e.g., if LS_COLORS is invalid.  */
+  if (directories_first)
+    check_symlink_mode = true;
+  else if (print_with_color)
+    {
+      /* Avoid following symbolic links when possible.  */
+      if (is_colored (C_ORPHAN)
+          || (is_colored (C_EXEC) && color_symlink_as_referent)
+          || (is_colored (C_MISSING) && format == long_format))
+        check_symlink_mode = true;
+    }
+
+  if (dereference == DEREF_UNDEFINED)
+    dereference = ((immediate_dirs
+                    || indicator_style == classify
+                    || format == long_format)
+                   ? DEREF_NEVER
+                   : DEREF_COMMAND_LINE_SYMLINK_TO_DIR);
+
+  /* When using -R, initialize a data structure we'll use to
+     detect any directory cycles.  */
+  if (recursive)
+    {
+      active_dir_set = hash_initialize (INITIAL_TABLE_SIZE, NULL,
+                                        dev_ino_hash,
+                                        dev_ino_compare,
+                                        dev_ino_free);
+      if (active_dir_set == NULL)
+        xalloc_die ();
+
+      obstack_init (&dev_ino_obstack);
+    }
+
+  localtz = tzalloc (getenv ("TZ"));
+
+  format_needs_stat = sort_type == sort_time || sort_type == sort_size
+    || format == long_format
+    || print_scontext
+    || print_block_size;
+  format_needs_type = (! format_needs_stat
+                       && (recursive
+                           || print_with_color
+                           || indicator_style != none
+                           || directories_first));
+
+  if (dired)
+    {
+      obstack_init (&dired_obstack);
+      obstack_init (&subdired_obstack);
+    }
+
+  if (print_hyperlink)
+    {
+      file_escape_init ();
+
+      hostname = xgethostname ();
+      /* The hostname is generally ignored,
+         so ignore failures obtaining it.  */
+      if (! hostname)
+        hostname = "";
+    }
+
+  cwd_n_alloc = 100;
+  cwd_file = xnmalloc (cwd_n_alloc, sizeof *cwd_file);
+  cwd_n_used = 0;
+
+  clear_files ();
+
+  n_files = argc - i;
+
+  if (n_files <= 0)
+    {
+      if (immediate_dirs)
+        gobble_file (".", directory, NOT_AN_INODE_NUMBER, true, "");
+      else
+        queue_directory (".", NULL, true);
+    }
+  else
+    do
+      gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, "");
+    while (i < argc);
+
+  if (cwd_n_used)
+    {
+      sort_files ();
+      if (!immediate_dirs)
+        extract_dirs_from_files (NULL, true);
+      /* 'cwd_n_used' might be zero now.  */
+    }
+
+  /* In the following if/else blocks, it is sufficient to test 'pending_dirs'
+     (and not pending_dirs->name) because there may be no markers in the queue
+     at this point.  A marker may be enqueued when extract_dirs_from_files is
+     called with a non-empty string or via print_dir.  */
+  if (cwd_n_used)
+    {
+      print_current_files ();
+      if (pending_dirs)
+        DIRED_PUTCHAR ('\n');
+    }
+  else if (n_files <= 1 && pending_dirs && pending_dirs->next == 0)
+    print_dir_name = false;
+
+  while (pending_dirs)
+    {
+      thispend = pending_dirs;
+      pending_dirs = pending_dirs->next;
+
+      if (LOOP_DETECT)
+        {
+          if (thispend->name == NULL)
+            {
+              /* thispend->name == NULL means this is a marker entry
+                 indicating we've finished processing the directory.
+                 Use its dev/ino numbers to remove the corresponding
+                 entry from the active_dir_set hash table.  */
+              struct dev_ino di = dev_ino_pop ();
+              struct dev_ino *found = hash_delete (active_dir_set, &di);
+              /* ASSERT_MATCHING_DEV_INO (thispend->realname, di); */
+              assert (found);
+              dev_ino_free (found);
+              free_pending_ent (thispend);
+              continue;
+            }
+        }
+
+      print_dir (thispend->name, thispend->realname,
+                 thispend->command_line_arg);
+
+      free_pending_ent (thispend);
+      print_dir_name = true;
+    }
+
+  if (print_with_color && used_color)
+    {
+      int j;
+
+      /* Skip the restore when it would be a no-op, i.e.,
+         when left is "\033[" and right is "m".  */
+      if (!(color_indicator[C_LEFT].len == 2
+            && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0
+            && color_indicator[C_RIGHT].len == 1
+            && color_indicator[C_RIGHT].string[0] == 'm'))
+        restore_default_color ();
+
+      fflush (stdout);
+
+      signal_restore ();
+
+      /* Act on any signals that arrived before the default was restored.
+         This can process signals out of order, but there doesn't seem to
+         be an easy way to do them in order, and the order isn't that
+         important anyway.  */
+      for (j = stop_signal_count; j; j--)
+        raise (SIGSTOP);
+      j = interrupt_signal;
+      if (j)
+        raise (j);
+    }
+
+  if (dired)
+    {
+      /* No need to free these since we're about to exit.  */
+      dired_dump_obstack ("//DIRED//", &dired_obstack);
+      dired_dump_obstack ("//SUBDIRED//", &subdired_obstack);
+      printf ("//DIRED-OPTIONS// --quoting-style=%s\n",
+              quoting_style_args[get_quoting_style (filename_quoting_options)]);
+    }
+
+  if (LOOP_DETECT)
+    {
+      assert (hash_get_n_entries (active_dir_set) == 0);
+      hash_free (active_dir_set);
+    }
+
+  return exit_status;
+}
+
+/* Set the line length to the value given by SPEC.  Return true if
+   successful.  0 means no limit on line length.  */
+
+static bool
+set_line_length (char const *spec)
+{
+  uintmax_t val;
+
+  /* Treat too-large values as if they were SIZE_MAX, which is
+     effectively infinity.  */
+  switch (xstrtoumax (spec, NULL, 0, &val, ""))
+    {
+    case LONGINT_OK:
+      line_length = MIN (val, SIZE_MAX);
+      return true;
+
+    case LONGINT_OVERFLOW:
+      line_length = SIZE_MAX;
+      return true;
+
+    default:
+      return false;
+    }
+}
+
+/* Set all the option flags according to the switches specified.
+   Return the index of the first non-option argument.  */
+
+static int
+decode_switches (int argc, char **argv)
+{
+  char *time_style_option = NULL;
+
+  bool sort_type_specified = false;
+  bool kibibytes_specified = false;
+
+  qmark_funny_chars = false;
+
+  /* initialize all switches to default settings */
+
+  switch (ls_mode)
+    {
+    case LS_MULTI_COL:
+      /* This is for the 'dir' program.  */
+      format = many_per_line;
+      set_quoting_style (NULL, escape_quoting_style);
+      break;
+
+    case LS_LONG_FORMAT:
+      /* This is for the 'vdir' program.  */
+      format = long_format;
+      set_quoting_style (NULL, escape_quoting_style);
+      break;
+
+    case LS_LS:
+      /* This is for the 'ls' program.  */
+      if (isatty (STDOUT_FILENO))
+        {
+          format = many_per_line;
+          set_quoting_style (NULL, shell_escape_quoting_style);
+          /* See description of qmark_funny_chars, above.  */
+          qmark_funny_chars = true;
+        }
+      else
+        {
+          format = one_per_line;
+          qmark_funny_chars = false;
+        }
+      break;
+
+    default:
+      abort ();
+    }
+
+  time_type = time_mtime;
+  sort_type = sort_name;
+  sort_reverse = false;
+  numeric_ids = false;
+  print_block_size = false;
+  indicator_style = none;
+  print_inode = false;
+  dereference = DEREF_UNDEFINED;
+  recursive = false;
+  immediate_dirs = false;
+  ignore_mode = IGNORE_DEFAULT;
+  ignore_patterns = NULL;
+  hide_patterns = NULL;
+  print_scontext = false;
+
+  getenv_quoting_style ();
+
+  line_length = 80;
+  {
+    char const *p = getenv ("COLUMNS");
+    if (p && *p && ! set_line_length (p))
+      error (0, 0,
+             _("ignoring invalid width in environment variable COLUMNS: %s"),
+             quote (p));
+  }
+
+#ifdef TIOCGWINSZ
+  {
+    struct winsize ws;
+
+    if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws) != -1
+        && 0 < ws.ws_col && ws.ws_col == (size_t) ws.ws_col)
+      line_length = ws.ws_col;
+  }
+#endif
+
+  {
+    char const *p = getenv ("TABSIZE");
+    tabsize = 8;
+    if (p)
+      {
+        uintmax_t tmp;
+        if (xstrtoumax (p, NULL, 0, &tmp, "") == LONGINT_OK
+            && tmp <= SIZE_MAX)
+          tabsize = tmp;
+        else
+          error (0, 0,
+                 _("ignoring invalid tab size in environment variable TABSIZE:"
+                   " %s"),
+                 quote (p));
+      }
+  }
+
+  while (true)
+    {
+      int oi = -1;
+      int c = getopt_long (argc, argv,
+                           "abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",
+                           long_options, &oi);
+      if (c == -1)
+        break;
+
+      switch (c)
+        {
+        case 'a':
+          ignore_mode = IGNORE_MINIMAL;
+          break;
+
+        case 'b':
+          set_quoting_style (NULL, escape_quoting_style);
+          break;
+
+        case 'c':
+          time_type = time_ctime;
+          break;
+
+        case 'd':
+          immediate_dirs = true;
+          break;
+
+        case 'f':
+          /* Same as enabling -a -U and disabling -l -s.  */
+          ignore_mode = IGNORE_MINIMAL;
+          sort_type = sort_none;
+          sort_type_specified = true;
+          /* disable -l */
+          if (format == long_format)
+            format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
+          print_block_size = false;	/* disable -s */
+          print_with_color = false;	/* disable --color */
+          print_hyperlink = false;	/* disable --hyperlink */
+          break;
+
+        case FILE_TYPE_INDICATOR_OPTION: /* --file-type */
+          indicator_style = file_type;
+          break;
+
+        case 'g':
+          format = long_format;
+          print_owner = false;
+          break;
+
+        case 'h':
+          file_human_output_opts = human_output_opts =
+            human_autoscale | human_SI | human_base_1024;
+          file_output_block_size = output_block_size = 1;
+          break;
+
+        case 'i':
+          print_inode = true;
+          break;
+
+        case 'k':
+          kibibytes_specified = true;
+          break;
+
+        case 'l':
+          format = long_format;
+          break;
+
+        case 'm':
+          format = with_commas;
+          break;
+
+        case 'n':
+          numeric_ids = true;
+          format = long_format;
+          break;
+
+        case 'o':  /* Just like -l, but don't display group info.  */
+          format = long_format;
+          print_group = false;
+          break;
+
+        case 'p':
+          indicator_style = slash;
+          break;
+
+        case 'q':
+          qmark_funny_chars = true;
+          break;
+
+        case 'r':
+          sort_reverse = true;
+          break;
+
+        case 's':
+          print_block_size = true;
+          break;
+
+        case 't':
+          sort_type = sort_time;
+          sort_type_specified = true;
+          break;
+
+        case 'u':
+          time_type = time_atime;
+          break;
+
+        case 'v':
+          sort_type = sort_version;
+          sort_type_specified = true;
+          break;
+
+        case 'w':
+          if (! set_line_length (optarg))
+            die (LS_FAILURE, 0, "%s: %s", _("invalid line width"),
+                 quote (optarg));
+          break;
+
+        case 'x':
+          format = horizontal;
+          break;
+
+        case 'A':
+          ignore_mode = IGNORE_DOT_AND_DOTDOT;
+          break;
+
+        case 'B':
+          add_ignore_pattern ("*~");
+          add_ignore_pattern (".*~");
+          break;
+
+        case 'C':
+          format = many_per_line;
+          break;
+
+        case 'D':
+          dired = true;
+          break;
+
+        case 'F':
+          indicator_style = classify;
+          break;
+
+        case 'G':		/* inhibit display of group info */
+          print_group = false;
+          break;
+
+        case 'H':
+          dereference = DEREF_COMMAND_LINE_ARGUMENTS;
+          break;
+
+        case DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION:
+          dereference = DEREF_COMMAND_LINE_SYMLINK_TO_DIR;
+          break;
+
+        case 'I':
+          add_ignore_pattern (optarg);
+          break;
+
+        case 'L':
+          dereference = DEREF_ALWAYS;
+          break;
+
+        case 'N':
+          set_quoting_style (NULL, literal_quoting_style);
+          break;
+
+        case 'Q':
+          set_quoting_style (NULL, c_quoting_style);
+          break;
+
+        case 'R':
+          recursive = true;
+          break;
+
+        case 'S':
+          sort_type = sort_size;
+          sort_type_specified = true;
+          break;
+
+        case 'T':
+          tabsize = xnumtoumax (optarg, 0, 0, SIZE_MAX, "",
+                                _("invalid tab size"), LS_FAILURE);
+          break;
+
+        case 'U':
+          sort_type = sort_none;
+          sort_type_specified = true;
+          break;
+
+        case 'X':
+          sort_type = sort_extension;
+          sort_type_specified = true;
+          break;
+
+        case '1':
+          /* -1 has no effect after -l.  */
+          if (format != long_format)
+            format = one_per_line;
+          break;
+
+        case AUTHOR_OPTION:
+          print_author = true;
+          break;
+
+        case HIDE_OPTION:
+          {
+            struct ignore_pattern *hide = xmalloc (sizeof *hide);
+            hide->pattern = optarg;
+            hide->next = hide_patterns;
+            hide_patterns = hide;
+          }
+          break;
+
+        case SORT_OPTION:
+          sort_type = XARGMATCH ("--sort", optarg, sort_args, sort_types);
+          sort_type_specified = true;
+          break;
+
+        case GROUP_DIRECTORIES_FIRST_OPTION:
+          directories_first = true;
+          break;
+
+        case TIME_OPTION:
+          time_type = XARGMATCH ("--time", optarg, time_args, time_types);
+          break;
+
+        case FORMAT_OPTION:
+          format = XARGMATCH ("--format", optarg, format_args, format_types);
+          break;
+
+        case FULL_TIME_OPTION:
+          format = long_format;
+          time_style_option = bad_cast ("full-iso");
+          break;
+
+        case COLOR_OPTION:
+          {
+            int i;
+            if (optarg)
+              i = XARGMATCH ("--color", optarg, when_args, when_types);
+            else
+              /* Using --color with no argument is equivalent to using
+                 --color=always.  */
+              i = when_always;
+
+            print_with_color = (i == when_always
+                                || (i == when_if_tty
+                                    && isatty (STDOUT_FILENO)));
+
+            if (print_with_color)
+              {
+                /* Don't use TAB characters in output.  Some terminal
+                   emulators can't handle the combination of tabs and
+                   color codes on the same line.  */
+                tabsize = 0;
+              }
+            break;
+          }
+
+        case HYPERLINK_OPTION:
+          {
+            int i;
+            if (optarg)
+              i = XARGMATCH ("--hyperlink", optarg, when_args, when_types);
+            else
+              /* Using --hyperlink with no argument is equivalent to using
+                 --hyperlink=always.  */
+              i = when_always;
+
+            print_hyperlink = (i == when_always
+                               || (i == when_if_tty
+                                   && isatty (STDOUT_FILENO)));
+            break;
+          }
+
+        case INDICATOR_STYLE_OPTION:
+          indicator_style = XARGMATCH ("--indicator-style", optarg,
+                                       indicator_style_args,
+                                       indicator_style_types);
+          break;
+
+        case QUOTING_STYLE_OPTION:
+          set_quoting_style (NULL,
+                             XARGMATCH ("--quoting-style", optarg,
+                                        quoting_style_args,
+                                        quoting_style_vals));
+          break;
+
+        case TIME_STYLE_OPTION:
+          time_style_option = optarg;
+          break;
+
+        case SHOW_CONTROL_CHARS_OPTION:
+          qmark_funny_chars = false;
+          break;
+
+        case BLOCK_SIZE_OPTION:
+          {
+            enum strtol_error e = human_options (optarg, &human_output_opts,
+                                                 &output_block_size);
+            if (e != LONGINT_OK)
+              xstrtol_fatal (e, oi, 0, long_options, optarg);
+            file_human_output_opts = human_output_opts;
+            file_output_block_size = output_block_size;
+          }
+          break;
+
+        case SI_OPTION:
+          file_human_output_opts = human_output_opts =
+            human_autoscale | human_SI;
+          file_output_block_size = output_block_size = 1;
+          break;
+
+        case 'Z':
+          print_scontext = true;
+          break;
+
+        case_GETOPT_HELP_CHAR;
+
+        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+        default:
+          usage (LS_FAILURE);
+        }
+    }
+
+  if (! output_block_size)
+    {
+      char const *ls_block_size = getenv ("LS_BLOCK_SIZE");
+      human_options (ls_block_size,
+                     &human_output_opts, &output_block_size);
+      if (ls_block_size || getenv ("BLOCK_SIZE"))
+        {
+          file_human_output_opts = human_output_opts;
+          file_output_block_size = output_block_size;
+        }
+      if (kibibytes_specified)
+        {
+          human_output_opts = 0;
+          output_block_size = 1024;
+        }
+    }
+
+  /* Determine the max possible number of display columns.  */
+  max_idx = line_length / MIN_COLUMN_WIDTH;
+  /* Account for first display column not having a separator,
+     or line_lengths shorter than MIN_COLUMN_WIDTH.  */
+  max_idx += line_length % MIN_COLUMN_WIDTH != 0;
+
+  enum quoting_style qs = get_quoting_style (NULL);
+  align_variable_outer_quotes = format != with_commas
+                                && format != one_per_line
+                                && (line_length || format == long_format)
+                                && (qs == shell_quoting_style
+                                    || qs == shell_escape_quoting_style
+                                    || qs == c_maybe_quoting_style);
+  filename_quoting_options = clone_quoting_options (NULL);
+  if (qs == escape_quoting_style)
+    set_char_quoting (filename_quoting_options, ' ', 1);
+  if (file_type <= indicator_style)
+    {
+      char const *p;
+      for (p = &"*=>@|"[indicator_style - file_type]; *p; p++)
+        set_char_quoting (filename_quoting_options, *p, 1);
+    }
+
+  dirname_quoting_options = clone_quoting_options (NULL);
+  set_char_quoting (dirname_quoting_options, ':', 1);
+
+  /* --dired is meaningful only with --format=long (-l).
+     Otherwise, ignore it.  FIXME: warn about this?
+     Alternatively, make --dired imply --format=long?  */
+  if (dired && (format != long_format || print_hyperlink))
+    dired = false;
+
+  /* If -c or -u is specified and not -l (or any other option that implies -l),
+     and no sort-type was specified, then sort by the ctime (-c) or atime (-u).
+     The behavior of ls when using either -c or -u but with neither -l nor -t
+     appears to be unspecified by POSIX.  So, with GNU ls, '-u' alone means
+     sort by atime (this is the one that's not specified by the POSIX spec),
+     -lu means show atime and sort by name, -lut means show atime and sort
+     by atime.  */
+
+  if ((time_type == time_ctime || time_type == time_atime
+       || time_type == time_btime)
+      && !sort_type_specified && format != long_format)
+    {
+      sort_type = sort_time;
+    }
+
+  if (format == long_format)
+    {
+      char *style = time_style_option;
+      static char const posix_prefix[] = "posix-";
+
+      if (! style)
+        if (! (style = getenv ("TIME_STYLE")))
+          style = bad_cast ("locale");
+
+      while (STREQ_LEN (style, posix_prefix, sizeof posix_prefix - 1))
+        {
+          if (! hard_locale (LC_TIME))
+            return optind;
+          style += sizeof posix_prefix - 1;
+        }
+
+      if (*style == '+')
+        {
+          char *p0 = style + 1;
+          char *p1 = strchr (p0, '\n');
+          if (! p1)
+            p1 = p0;
+          else
+            {
+              if (strchr (p1 + 1, '\n'))
+                die (LS_FAILURE, 0, _("invalid time style format %s"),
+                     quote (p0));
+              *p1++ = '\0';
+            }
+          long_time_format[0] = p0;
+          long_time_format[1] = p1;
+        }
+      else
+        {
+          ptrdiff_t res = argmatch (style, time_style_args,
+                                    (char const *) time_style_types,
+                                    sizeof (*time_style_types));
+          if (res < 0)
+            {
+              /* This whole block used to be a simple use of XARGMATCH.
+                 but that didn't print the "posix-"-prefixed variants or
+                 the "+"-prefixed format string option upon failure.  */
+              argmatch_invalid ("time style", style, res);
+
+              /* The following is a manual expansion of argmatch_valid,
+                 but with the added "+ ..." description and the [posix-]
+                 prefixes prepended.  Note that this simplification works
+                 only because all four existing time_style_types values
+                 are distinct.  */
+              fputs (_("Valid arguments are:\n"), stderr);
+              char const *const *p = time_style_args;
+              while (*p)
+                fprintf (stderr, "  - [posix-]%s\n", *p++);
+              fputs (_("  - +FORMAT (e.g., +%H:%M) for a 'date'-style"
+                       " format\n"), stderr);
+              usage (LS_FAILURE);
+            }
+          switch (res)
+            {
+            case full_iso_time_style:
+              long_time_format[0] = long_time_format[1] =
+                "%Y-%m-%d %H:%M:%S.%N %z";
+              break;
+
+            case long_iso_time_style:
+              long_time_format[0] = long_time_format[1] = "%Y-%m-%d %H:%M";
+              break;
+
+            case iso_time_style:
+              long_time_format[0] = "%Y-%m-%d ";
+              long_time_format[1] = "%m-%d %H:%M";
+              break;
+
+            case locale_time_style:
+              if (hard_locale (LC_TIME))
+                {
+                  for (int i = 0; i < 2; i++)
+                    long_time_format[i] =
+                      dcgettext (NULL, long_time_format[i], LC_TIME);
+                }
+            }
+        }
+
+      abformat_init ();
+    }
+
+  return optind;
+}
+
+/* Parse a string as part of the LS_COLORS variable; this may involve
+   decoding all kinds of escape characters.  If equals_end is set an
+   unescaped equal sign ends the string, otherwise only a : or \0
+   does.  Set *OUTPUT_COUNT to the number of bytes output.  Return
+   true if successful.
+
+   The resulting string is *not* null-terminated, but may contain
+   embedded nulls.
+
+   Note that both dest and src are char **; on return they point to
+   the first free byte after the array and the character that ended
+   the input string, respectively.  */
+
+static bool
+get_funky_string (char **dest, const char **src, bool equals_end,
+                  size_t *output_count)
+{
+  char num;			/* For numerical codes */
+  size_t count;			/* Something to count with */
+  enum {
+    ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR
+  } state;
+  const char *p;
+  char *q;
+
+  p = *src;			/* We don't want to double-indirect */
+  q = *dest;			/* the whole darn time.  */
+
+  count = 0;			/* No characters counted in yet.  */
+  num = 0;
+
+  state = ST_GND;		/* Start in ground state.  */
+  while (state < ST_END)
+    {
+      switch (state)
+        {
+        case ST_GND:		/* Ground state (no escapes) */
+          switch (*p)
+            {
+            case ':':
+            case '\0':
+              state = ST_END;	/* End of string */
+              break;
+            case '\\':
+              state = ST_BACKSLASH; /* Backslash escape sequence */
+              ++p;
+              break;
+            case '^':
+              state = ST_CARET; /* Caret escape */
+              ++p;
+              break;
+            case '=':
+              if (equals_end)
+                {
+                  state = ST_END; /* End */
+                  break;
+                }
+              FALLTHROUGH;
+            default:
+              *(q++) = *(p++);
+              ++count;
+              break;
+            }
+          break;
+
+        case ST_BACKSLASH:	/* Backslash escaped character */
+          switch (*p)
+            {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+              state = ST_OCTAL;	/* Octal sequence */
+              num = *p - '0';
+              break;
+            case 'x':
+            case 'X':
+              state = ST_HEX;	/* Hex sequence */
+              num = 0;
+              break;
+            case 'a':		/* Bell */
+              num = '\a';
+              break;
+            case 'b':		/* Backspace */
+              num = '\b';
+              break;
+            case 'e':		/* Escape */
+              num = 27;
+              break;
+            case 'f':		/* Form feed */
+              num = '\f';
+              break;
+            case 'n':		/* Newline */
+              num = '\n';
+              break;
+            case 'r':		/* Carriage return */
+              num = '\r';
+              break;
+            case 't':		/* Tab */
+              num = '\t';
+              break;
+            case 'v':		/* Vtab */
+              num = '\v';
+              break;
+            case '?':		/* Delete */
+              num = 127;
+              break;
+            case '_':		/* Space */
+              num = ' ';
+              break;
+            case '\0':		/* End of string */
+              state = ST_ERROR;	/* Error! */
+              break;
+            default:		/* Escaped character like \ ^ : = */
+              num = *p;
+              break;
+            }
+          if (state == ST_BACKSLASH)
+            {
+              *(q++) = num;
+              ++count;
+              state = ST_GND;
+            }
+          ++p;
+          break;
+
+        case ST_OCTAL:		/* Octal sequence */
+          if (*p < '0' || *p > '7')
+            {
+              *(q++) = num;
+              ++count;
+              state = ST_GND;
+            }
+          else
+            num = (num << 3) + (*(p++) - '0');
+          break;
+
+        case ST_HEX:		/* Hex sequence */
+          switch (*p)
+            {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+              num = (num << 4) + (*(p++) - '0');
+              break;
+            case 'a':
+            case 'b':
+            case 'c':
+            case 'd':
+            case 'e':
+            case 'f':
+              num = (num << 4) + (*(p++) - 'a') + 10;
+              break;
+            case 'A':
+            case 'B':
+            case 'C':
+            case 'D':
+            case 'E':
+            case 'F':
+              num = (num << 4) + (*(p++) - 'A') + 10;
+              break;
+            default:
+              *(q++) = num;
+              ++count;
+              state = ST_GND;
+              break;
+            }
+          break;
+
+        case ST_CARET:		/* Caret escape */
+          state = ST_GND;	/* Should be the next state... */
+          if (*p >= '@' && *p <= '~')
+            {
+              *(q++) = *(p++) & 037;
+              ++count;
+            }
+          else if (*p == '?')
+            {
+              *(q++) = 127;
+              ++count;
+            }
+          else
+            state = ST_ERROR;
+          break;
+
+        default:
+          abort ();
+        }
+    }
+
+  *dest = q;
+  *src = p;
+  *output_count = count;
+
+  return state != ST_ERROR;
+}
+
+enum parse_state
+  {
+    PS_START = 1,
+    PS_2,
+    PS_3,
+    PS_4,
+    PS_DONE,
+    PS_FAIL
+  };
+
+
+/* Check if the content of TERM is a valid name in dircolors.  */
+
+static bool
+known_term_type (void)
+{
+  char const *term = getenv ("TERM");
+  if (! term || ! *term)
+    return false;
+
+  char const *line = G_line;
+  while (line - G_line < sizeof (G_line))
+    {
+      if (STRNCMP_LIT (line, "TERM ") == 0)
+        {
+          if (fnmatch (line + 5, term, 0) == 0)
+            return true;
+        }
+      line += strlen (line) + 1;
+    }
+
+  return false;
+}
+
+static void
+parse_ls_color (void)
+{
+  const char *p;		/* Pointer to character being parsed */
+  char *buf;			/* color_buf buffer pointer */
+  int ind_no;			/* Indicator number */
+  char label[3];		/* Indicator label */
+  struct color_ext_type *ext;	/* Extension we are working on */
+
+  if ((p = getenv ("LS_COLORS")) == NULL || *p == '\0')
+    {
+      /* LS_COLORS takes precedence, but if that's not set then
+         honor the COLORTERM and TERM env variables so that
+         we only go with the internal ANSI color codes if the
+         former is non empty or the latter is set to a known value.  */
+      char const *colorterm = getenv ("COLORTERM");
+      if (! (colorterm && *colorterm) && ! known_term_type ())
+        print_with_color = false;
+      return;
+    }
+
+  ext = NULL;
+  strcpy (label, "??");
+
+  /* This is an overly conservative estimate, but any possible
+     LS_COLORS string will *not* generate a color_buf longer than
+     itself, so it is a safe way of allocating a buffer in
+     advance.  */
+  buf = color_buf = xstrdup (p);
+
+  enum parse_state state = PS_START;
+  while (true)
+    {
+      switch (state)
+        {
+        case PS_START:		/* First label character */
+          switch (*p)
+            {
+            case ':':
+              ++p;
+              break;
+
+            case '*':
+              /* Allocate new extension block and add to head of
+                 linked list (this way a later definition will
+                 override an earlier one, which can be useful for
+                 having terminal-specific defs override global).  */
+
+              ext = xmalloc (sizeof *ext);
+              ext->next = color_ext_list;
+              color_ext_list = ext;
+
+              ++p;
+              ext->ext.string = buf;
+
+              state = (get_funky_string (&buf, &p, true, &ext->ext.len)
+                       ? PS_4 : PS_FAIL);
+              break;
+
+            case '\0':
+              state = PS_DONE;	/* Done! */
+              goto done;
+
+            default:	/* Assume it is file type label */
+              label[0] = *(p++);
+              state = PS_2;
+              break;
+            }
+          break;
+
+        case PS_2:		/* Second label character */
+          if (*p)
+            {
+              label[1] = *(p++);
+              state = PS_3;
+            }
+          else
+            state = PS_FAIL;	/* Error */
+          break;
+
+        case PS_3:		/* Equal sign after indicator label */
+          state = PS_FAIL;	/* Assume failure...  */
+          if (*(p++) == '=')/* It *should* be...  */
+            {
+              for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no)
+                {
+                  if (STREQ (label, indicator_name[ind_no]))
+                    {
+                      color_indicator[ind_no].string = buf;
+                      state = (get_funky_string (&buf, &p, false,
+                                                 &color_indicator[ind_no].len)
+                               ? PS_START : PS_FAIL);
+                      break;
+                    }
+                }
+              if (state == PS_FAIL)
+                error (0, 0, _("unrecognized prefix: %s"), quote (label));
+            }
+          break;
+
+        case PS_4:		/* Equal sign after *.ext */
+          if (*(p++) == '=')
+            {
+              ext->seq.string = buf;
+              state = (get_funky_string (&buf, &p, false, &ext->seq.len)
+                       ? PS_START : PS_FAIL);
+            }
+          else
+            state = PS_FAIL;
+          break;
+
+        case PS_FAIL:
+          goto done;
+
+        default:
+          abort ();
+        }
+    }
+ done:
+
+  if (state == PS_FAIL)
+    {
+      struct color_ext_type *e;
+      struct color_ext_type *e2;
+
+      error (0, 0,
+             _("unparsable value for LS_COLORS environment variable"));
+      free (color_buf);
+      for (e = color_ext_list; e != NULL; /* empty */)
+        {
+          e2 = e;
+          e = e->next;
+          free (e2);
+        }
+      print_with_color = false;
+    }
+
+  if (color_indicator[C_LINK].len == 6
+      && !STRNCMP_LIT (color_indicator[C_LINK].string, "target"))
+    color_symlink_as_referent = true;
+}
+
+/* Set the quoting style default if the environment variable
+   QUOTING_STYLE is set.  */
+
+static void
+getenv_quoting_style (void)
+{
+  char const *q_style = getenv ("QUOTING_STYLE");
+  if (q_style)
+    {
+      int i = ARGMATCH (q_style, quoting_style_args, quoting_style_vals);
+      if (0 <= i)
+        set_quoting_style (NULL, quoting_style_vals[i]);
+      else
+        error (0, 0,
+       _("ignoring invalid value of environment variable QUOTING_STYLE: %s"),
+               quote (q_style));
+    }
+}
+
+/* Set the exit status to report a failure.  If SERIOUS, it is a
+   serious failure; otherwise, it is merely a minor problem.  */
+
+static void
+set_exit_status (bool serious)
+{
+  if (serious)
+    exit_status = LS_FAILURE;
+  else if (exit_status == EXIT_SUCCESS)
+    exit_status = LS_MINOR_PROBLEM;
+}
+
+/* Assuming a failure is serious if SERIOUS, use the printf-style
+   MESSAGE to report the failure to access a file named FILE.  Assume
+   errno is set appropriately for the failure.  */
+
+static void
+file_failure (bool serious, char const *message, char const *file)
+{
+  error (0, errno, message, quoteaf (file));
+  set_exit_status (serious);
+}
+
+/* Request that the directory named NAME have its contents listed later.
+   If REALNAME is nonzero, it will be used instead of NAME when the
+   directory name is printed.  This allows symbolic links to directories
+   to be treated as regular directories but still be listed under their
+   real names.  NAME == NULL is used to insert a marker entry for the
+   directory named in REALNAME.
+   If NAME is non-NULL, we use its dev/ino information to save
+   a call to stat -- when doing a recursive (-R) traversal.
+   COMMAND_LINE_ARG means this directory was mentioned on the command line.  */
+
+static void
+queue_directory (char const *name, char const *realname, bool command_line_arg)
+{
+  struct pending *new = xmalloc (sizeof *new);
+  new->realname = realname ? xstrdup (realname) : NULL;
+  new->name = name ? xstrdup (name) : NULL;
+  new->command_line_arg = command_line_arg;
+  new->next = pending_dirs;
+  pending_dirs = new;
+}
+
+/* Read directory NAME, and list the files in it.
+   If REALNAME is nonzero, print its name instead of NAME;
+   this is used for symbolic links to directories.
+   COMMAND_LINE_ARG means this directory was mentioned on the command line.  */
+
+static void
+print_dir (char const *name, char const *realname, bool command_line_arg)
+{
+  DIR *dirp;
+  struct dirent *next;
+  uintmax_t total_blocks = 0;
+  static bool first = true;
+  bool found_any_entries = false;
+
+  errno = 0;
+  dirp = opendir (name);
+  if (!dirp)
+    {
+      file_failure (command_line_arg, _("cannot open directory %s"), name);
+      return;
+    }
+
+  if (LOOP_DETECT)
+    {
+      struct stat dir_stat;
+      int fd = dirfd (dirp);
+
+      /* If dirfd failed, endure the overhead of stat'ing by path  */
+      if ((0 <= fd
+           ? fstat_for_ino (fd, &dir_stat)
+           : stat_for_ino (name, &dir_stat)) < 0)
+        {
+          file_failure (command_line_arg,
+                        _("cannot determine device and inode of %s"), name);
+          closedir (dirp);
+          return;
+        }
+
+      /* If we've already visited this dev/inode pair, warn that
+         we've found a loop, and do not process this directory.  */
+      if (visit_dir (dir_stat.st_dev, dir_stat.st_ino))
+        {
+          error (0, 0, _("%s: not listing already-listed directory"),
+                 quotef (name));
+          closedir (dirp);
+          set_exit_status (true);
+          return;
+        }
+
+      dev_ino_push (dir_stat.st_dev, dir_stat.st_ino);
+    }
+
+  clear_files ();
+
+  if (recursive || print_dir_name)
+    {
+      if (!first)
+        DIRED_PUTCHAR ('\n');
+      first = false;
+      DIRED_INDENT ();
+
+      char *absolute_name = NULL;
+      if (print_hyperlink)
+        {
+          absolute_name = canonicalize_filename_mode (name, CAN_MISSING);
+          if (! absolute_name)
+            file_failure (command_line_arg,
+                          _("error canonicalizing %s"), name);
+        }
+      quote_name (realname ? realname : name, dirname_quoting_options, -1,
+                  NULL, true, &subdired_obstack, absolute_name);
+
+      free (absolute_name);
+
+      DIRED_FPUTS_LITERAL (":\n", stdout);
+    }
+
+  /* Read the directory entries, and insert the subfiles into the 'cwd_file'
+     table.  */
+
+  while (1)
+    {
+      /* Set errno to zero so we can distinguish between a readdir failure
+         and when readdir simply finds that there are no more entries.  */
+      errno = 0;
+      next = readdir (dirp);
+      if (next)
+        {
+          found_any_entries = true;
+          if (! file_ignored (next->d_name))
+            {
+              enum filetype type = unknown;
+
+#if HAVE_STRUCT_DIRENT_D_TYPE
+              switch (next->d_type)
+                {
+                case DT_BLK:  type = blockdev;		break;
+                case DT_CHR:  type = chardev;		break;
+                case DT_DIR:  type = directory;		break;
+                case DT_FIFO: type = fifo;		break;
+                case DT_LNK:  type = symbolic_link;	break;
+                case DT_REG:  type = normal;		break;
+                case DT_SOCK: type = sock;		break;
+# ifdef DT_WHT
+                case DT_WHT:  type = whiteout;		break;
+# endif
+                }
+#endif
+              total_blocks += gobble_file (next->d_name, type,
+                                           RELIABLE_D_INO (next),
+                                           false, name);
+
+              /* In this narrow case, print out each name right away, so
+                 ls uses constant memory while processing the entries of
+                 this directory.  Useful when there are many (millions)
+                 of entries in a directory.  */
+              if (format == one_per_line && sort_type == sort_none
+                      && !print_block_size && !recursive)
+                {
+                  /* We must call sort_files in spite of
+                     "sort_type == sort_none" for its initialization
+                     of the sorted_file vector.  */
+                  sort_files ();
+                  print_current_files ();
+                  clear_files ();
+                }
+            }
+        }
+      else if (errno != 0)
+        {
+          file_failure (command_line_arg, _("reading directory %s"), name);
+          if (errno != EOVERFLOW)
+            break;
+        }
+#ifdef __linux__
+      else if (! found_any_entries)
+        {
+          /* If readdir finds no directory entries at all, not even "." or
+             "..", then double check that the directory exists.  */
+#if defined(__x86_64__)    || \
+    defined(__aarch64__)   || \
+    defined(__powerpc64__) || \
+    defined(__sparc__) && defined(__arch64__) || \
+    defined(__riscv_xlen) && __riscv_xlen == 64
+          if (syscall (SYS_getdents64, dirfd (dirp), NULL, 0) == -1
+              && errno != EINVAL)
+#else
+          if (syscall (SYS_getdents, dirfd (dirp), NULL, 0) == -1
+              && errno != EINVAL)
+#endif
+            {
+              /* We exclude EINVAL as that pertains to buffer handling,
+                 and we've passed NULL as the buffer for simplicity.
+                 ENOENT is returned if appropriate before buffer handling.  */
+              file_failure (command_line_arg, _("reading directory %s"), name);
+            }
+          break;
+        }
+#endif
+      else
+        break;
+
+      /* When processing a very large directory, and since we've inhibited
+         interrupts, this loop would take so long that ls would be annoyingly
+         uninterruptible.  This ensures that it handles signals promptly.  */
+      process_signals ();
+    }
+
+  if (closedir (dirp) != 0)
+    {
+      file_failure (command_line_arg, _("closing directory %s"), name);
+      /* Don't return; print whatever we got.  */
+    }
+
+  /* Sort the directory contents.  */
+  sort_files ();
+
+  /* If any member files are subdirectories, perhaps they should have their
+     contents listed rather than being mentioned here as files.  */
+
+  if (recursive)
+    extract_dirs_from_files (name, false);
+
+  if (format == long_format || print_block_size)
+    {
+      const char *p;
+      char buf[LONGEST_HUMAN_READABLE + 1];
+
+      DIRED_INDENT ();
+      p = _("total");
+      DIRED_FPUTS (p, stdout, strlen (p));
+      DIRED_PUTCHAR (' ');
+      p = human_readable (total_blocks, buf, human_output_opts,
+                          ST_NBLOCKSIZE, output_block_size);
+      DIRED_FPUTS (p, stdout, strlen (p));
+      DIRED_PUTCHAR ('\n');
+    }
+
+  if (cwd_n_used)
+    print_current_files ();
+}
+
+/* Add 'pattern' to the list of patterns for which files that match are
+   not listed.  */
+
+static void
+add_ignore_pattern (const char *pattern)
+{
+  struct ignore_pattern *ignore;
+
+  ignore = xmalloc (sizeof *ignore);
+  ignore->pattern = pattern;
+  /* Add it to the head of the linked list.  */
+  ignore->next = ignore_patterns;
+  ignore_patterns = ignore;
+}
+
+/* Return true if one of the PATTERNS matches FILE.  */
+
+static bool
+patterns_match (struct ignore_pattern const *patterns, char const *file)
+{
+  struct ignore_pattern const *p;
+  for (p = patterns; p; p = p->next)
+    if (fnmatch (p->pattern, file, FNM_PERIOD) == 0)
+      return true;
+  return false;
+}
+
+/* Return true if FILE should be ignored.  */
+
+static bool
+file_ignored (char const *name)
+{
+  return ((ignore_mode != IGNORE_MINIMAL
+           && name[0] == '.'
+           && (ignore_mode == IGNORE_DEFAULT || ! name[1 + (name[1] == '.')]))
+          || (ignore_mode == IGNORE_DEFAULT
+              && patterns_match (hide_patterns, name))
+          || patterns_match (ignore_patterns, name));
+}
+
+/* POSIX requires that a file size be printed without a sign, even
+   when negative.  Assume the typical case where negative sizes are
+   actually positive values that have wrapped around.  */
+
+static uintmax_t
+unsigned_file_size (off_t size)
+{
+  return size + (size < 0) * ((uintmax_t) OFF_T_MAX - OFF_T_MIN + 1);
+}
+
+#ifdef HAVE_CAP
+/* Return true if NAME has a capability (see linux/capability.h) */
+static bool
+has_capability (char const *name)
+{
+  char *result;
+  bool has_cap;
+
+  cap_t cap_d = cap_get_file (name);
+  if (cap_d == NULL)
+    return false;
+
+  result = cap_to_text (cap_d, NULL);
+  cap_free (cap_d);
+  if (!result)
+    return false;
+
+  /* check if human-readable capability string is empty */
+  has_cap = !!*result;
+
+  cap_free (result);
+  return has_cap;
+}
+#else
+static bool
+has_capability (char const *name _GL_UNUSED)
+{
+  errno = ENOTSUP;
+  return false;
+}
+#endif
+
+/* Enter and remove entries in the table 'cwd_file'.  */
+
+static void
+free_ent (struct fileinfo *f)
+{
+  free (f->name);
+  free (f->linkname);
+  free (f->absolute_name);
+  if (f->scontext != UNKNOWN_SECURITY_CONTEXT)
+    {
+      if (is_smack_enabled ())
+        free (f->scontext);
+      else
+        freecon (f->scontext);
+    }
+}
+
+/* Empty the table of files.  */
+static void
+clear_files (void)
+{
+  for (size_t i = 0; i < cwd_n_used; i++)
+    {
+      struct fileinfo *f = sorted_file[i];
+      free_ent (f);
+    }
+
+  cwd_n_used = 0;
+  cwd_some_quoted = false;
+  any_has_acl = false;
+  inode_number_width = 0;
+  block_size_width = 0;
+  nlink_width = 0;
+  owner_width = 0;
+  group_width = 0;
+  author_width = 0;
+  scontext_width = 0;
+  major_device_number_width = 0;
+  minor_device_number_width = 0;
+  file_size_width = 0;
+}
+
+/* Return true if ERR implies lack-of-support failure by a
+   getxattr-calling function like getfilecon or file_has_acl.  */
+static bool
+errno_unsupported (int err)
+{
+  return (err == EINVAL || err == ENOSYS || is_ENOTSUP (err));
+}
+
+/* Cache *getfilecon failure, when it's trivial to do so.
+   Like getfilecon/lgetfilecon, but when F's st_dev says it's doesn't
+   support getting the security context, fail with ENOTSUP immediately.  */
+static int
+getfilecon_cache (char const *file, struct fileinfo *f, bool deref)
+{
+  /* st_dev of the most recently processed device for which we've
+     found that [l]getfilecon fails indicating lack of support.  */
+  static dev_t unsupported_device;
+
+  if (f->stat.st_dev == unsupported_device)
+    {
+      errno = ENOTSUP;
+      return -1;
+    }
+  int r = 0;
+#ifdef HAVE_SMACK
+  if (is_smack_enabled ())
+    r = smack_new_label_from_path (file, "security.SMACK64", deref,
+                                   &f->scontext);
+  else
+#endif
+    r = (deref
+         ? getfilecon (file, &f->scontext)
+         : lgetfilecon (file, &f->scontext));
+  if (r < 0 && errno_unsupported (errno))
+    unsupported_device = f->stat.st_dev;
+  return r;
+}
+
+/* Cache file_has_acl failure, when it's trivial to do.
+   Like file_has_acl, but when F's st_dev says it's on a file
+   system lacking ACL support, return 0 with ENOTSUP immediately.  */
+static int
+file_has_acl_cache (char const *file, struct fileinfo *f)
+{
+  /* st_dev of the most recently processed device for which we've
+     found that file_has_acl fails indicating lack of support.  */
+  static dev_t unsupported_device;
+
+  if (f->stat.st_dev == unsupported_device)
+    {
+      errno = ENOTSUP;
+      return 0;
+    }
+
+  /* Zero errno so that we can distinguish between two 0-returning cases:
+     "has-ACL-support, but only a default ACL" and "no ACL support". */
+  errno = 0;
+  int n = file_has_acl (file, &f->stat);
+  if (n <= 0 && errno_unsupported (errno))
+    unsupported_device = f->stat.st_dev;
+  return n;
+}
+
+/* Cache has_capability failure, when it's trivial to do.
+   Like has_capability, but when F's st_dev says it's on a file
+   system lacking capability support, return 0 with ENOTSUP immediately.  */
+static bool
+has_capability_cache (char const *file, struct fileinfo *f)
+{
+  /* st_dev of the most recently processed device for which we've
+     found that has_capability fails indicating lack of support.  */
+  static dev_t unsupported_device;
+
+  if (f->stat.st_dev == unsupported_device)
+    {
+      errno = ENOTSUP;
+      return 0;
+    }
+
+  bool b = has_capability (file);
+  if ( !b && errno_unsupported (errno))
+    unsupported_device = f->stat.st_dev;
+  return b;
+}
+
+static bool
+needs_quoting (char const* name)
+{
+  char test[2];
+  size_t len = quotearg_buffer (test, sizeof test , name, -1,
+                                filename_quoting_options);
+  return *name != *test || strlen (name) != len;
+}
+
+/* Add a file to the current table of files.
+   Verify that the file exists, and print an error message if it does not.
+   Return the number of blocks that the file occupies.  */
+static uintmax_t
+gobble_file (char const *name, enum filetype type, ino_t inode,
+             bool command_line_arg, char const *dirname)
+{
+  uintmax_t blocks = 0;
+  struct fileinfo *f;
+
+  /* An inode value prior to gobble_file necessarily came from readdir,
+     which is not used for command line arguments.  */
+  assert (! command_line_arg || inode == NOT_AN_INODE_NUMBER);
+
+  if (cwd_n_used == cwd_n_alloc)
+    {
+      cwd_file = xnrealloc (cwd_file, cwd_n_alloc, 2 * sizeof *cwd_file);
+      cwd_n_alloc *= 2;
+    }
+
+  f = &cwd_file[cwd_n_used];
+  memset (f, '\0', sizeof *f);
+  f->stat.st_ino = inode;
+  f->filetype = type;
+
+  f->quoted = -1;
+  if ((! cwd_some_quoted) && align_variable_outer_quotes)
+    {
+      /* Determine if any quoted for padding purposes.  */
+      f->quoted = needs_quoting (name);
+      if (f->quoted)
+        cwd_some_quoted = 1;
+    }
+
+  if (command_line_arg
+      || print_hyperlink
+      || format_needs_stat
+      /* When coloring a directory (we may know the type from
+         direct.d_type), we have to stat it in order to indicate
+         sticky and/or other-writable attributes.  */
+      || (type == directory && print_with_color
+          && (is_colored (C_OTHER_WRITABLE)
+              || is_colored (C_STICKY)
+              || is_colored (C_STICKY_OTHER_WRITABLE)))
+      /* When dereferencing symlinks, the inode and type must come from
+         stat, but readdir provides the inode and type of lstat.  */
+      || ((print_inode || format_needs_type)
+          && (type == symbolic_link || type == unknown)
+          && (dereference == DEREF_ALWAYS
+              || color_symlink_as_referent || check_symlink_mode))
+      /* Command line dereferences are already taken care of by the above
+         assertion that the inode number is not yet known.  */
+      || (print_inode && inode == NOT_AN_INODE_NUMBER)
+      || (format_needs_type
+          && (type == unknown || command_line_arg
+              /* --indicator-style=classify (aka -F)
+                 requires that we stat each regular file
+                 to see if it's executable.  */
+              || (type == normal && (indicator_style == classify
+                                     /* This is so that --color ends up
+                                        highlighting files with these mode
+                                        bits set even when options like -F are
+                                        not specified.  Note we do a redundant
+                                        stat in the very unlikely case where
+                                        C_CAP is set but not the others. */
+                                     || (print_with_color
+                                         && (is_colored (C_EXEC)
+                                             || is_colored (C_SETUID)
+                                             || is_colored (C_SETGID)
+                                             || is_colored (C_CAP)))
+                                     )))))
+
+    {
+      /* Absolute name of this file.  */
+      char *full_name;
+      bool do_deref;
+      int err;
+
+      if (name[0] == '/' || dirname[0] == 0)
+        full_name = (char *) name;
+      else
+        {
+          full_name = alloca (strlen (name) + strlen (dirname) + 2);
+          attach (full_name, dirname, name);
+        }
+
+      if (print_hyperlink)
+        {
+          f->absolute_name = canonicalize_filename_mode (full_name,
+                                                         CAN_MISSING);
+          if (! f->absolute_name)
+            file_failure (command_line_arg,
+                          _("error canonicalizing %s"), full_name);
+        }
+
+      switch (dereference)
+        {
+        case DEREF_ALWAYS:
+          err = do_stat (full_name, &f->stat);
+          do_deref = true;
+          break;
+
+        case DEREF_COMMAND_LINE_ARGUMENTS:
+        case DEREF_COMMAND_LINE_SYMLINK_TO_DIR:
+          if (command_line_arg)
+            {
+              bool need_lstat;
+              err = do_stat (full_name, &f->stat);
+              do_deref = true;
+
+              if (dereference == DEREF_COMMAND_LINE_ARGUMENTS)
+                break;
+
+              need_lstat = (err < 0
+                            ? errno == ENOENT
+                            : ! S_ISDIR (f->stat.st_mode));
+              if (!need_lstat)
+                break;
+
+              /* stat failed because of ENOENT, maybe indicating a dangling
+                 symlink.  Or stat succeeded, FULL_NAME does not refer to a
+                 directory, and --dereference-command-line-symlink-to-dir is
+                 in effect.  Fall through so that we call lstat instead.  */
+            }
+          FALLTHROUGH;
+
+        default: /* DEREF_NEVER */
+          err = do_lstat (full_name, &f->stat);
+          do_deref = false;
+          break;
+        }
+
+      if (err != 0)
+        {
+          /* Failure to stat a command line argument leads to
+             an exit status of 2.  For other files, stat failure
+             provokes an exit status of 1.  */
+          file_failure (command_line_arg,
+                        _("cannot access %s"), full_name);
+          if (command_line_arg)
+            return 0;
+
+          f->name = xstrdup (name);
+          cwd_n_used++;
+
+          return 0;
+        }
+
+      f->stat_ok = true;
+
+      /* Note has_capability() adds around 30% runtime to 'ls --color'  */
+      if ((type == normal || S_ISREG (f->stat.st_mode))
+          && print_with_color && is_colored (C_CAP))
+        f->has_capability = has_capability_cache (full_name, f);
+
+      if (format == long_format || print_scontext)
+        {
+          bool have_scontext = false;
+          bool have_acl = false;
+          int attr_len = getfilecon_cache (full_name, f, do_deref);
+          err = (attr_len < 0);
+
+          if (err == 0)
+            {
+              if (is_smack_enabled ())
+                have_scontext = ! STREQ ("_", f->scontext);
+              else
+                have_scontext = ! STREQ ("unlabeled", f->scontext);
+            }
+          else
+            {
+              f->scontext = UNKNOWN_SECURITY_CONTEXT;
+
+              /* When requesting security context information, don't make
+                 ls fail just because the file (even a command line argument)
+                 isn't on the right type of file system.  I.e., a getfilecon
+                 failure isn't in the same class as a stat failure.  */
+              if (is_ENOTSUP (errno) || errno == ENODATA)
+                err = 0;
+            }
+
+          if (err == 0 && format == long_format)
+            {
+              int n = file_has_acl_cache (full_name, f);
+              err = (n < 0);
+              have_acl = (0 < n);
+            }
+
+          f->acl_type = (!have_scontext && !have_acl
+                         ? ACL_T_NONE
+                         : (have_scontext && !have_acl
+                            ? ACL_T_LSM_CONTEXT_ONLY
+                            : ACL_T_YES));
+          any_has_acl |= f->acl_type != ACL_T_NONE;
+
+          if (err)
+            error (0, errno, "%s", quotef (full_name));
+        }
+
+      if (S_ISLNK (f->stat.st_mode)
+          && (format == long_format || check_symlink_mode))
+        {
+          struct stat linkstats;
+
+          get_link_name (full_name, f, command_line_arg);
+          char *linkname = make_link_name (full_name, f->linkname);
+
+          /* Use the slower quoting path for this entry, though
+             don't update CWD_SOME_QUOTED since alignment not affected.  */
+          if (linkname && f->quoted == 0 && needs_quoting (f->linkname))
+            f->quoted = -1;
+
+          /* Avoid following symbolic links when possible, ie, when
+             they won't be traced and when no indicator is needed.  */
+          if (linkname
+              && (file_type <= indicator_style || check_symlink_mode)
+              && stat_for_mode (linkname, &linkstats) == 0)
+            {
+              f->linkok = true;
+              f->linkmode = linkstats.st_mode;
+            }
+          free (linkname);
+        }
+
+      if (S_ISLNK (f->stat.st_mode))
+        f->filetype = symbolic_link;
+      else if (S_ISDIR (f->stat.st_mode))
+        {
+          if (command_line_arg && !immediate_dirs)
+            f->filetype = arg_directory;
+          else
+            f->filetype = directory;
+        }
+      else
+        f->filetype = normal;
+
+      blocks = ST_NBLOCKS (f->stat);
+      if (format == long_format || print_block_size)
+        {
+          char buf[LONGEST_HUMAN_READABLE + 1];
+          int len = mbswidth (human_readable (blocks, buf, human_output_opts,
+                                              ST_NBLOCKSIZE, output_block_size),
+                              0);
+          if (block_size_width < len)
+            block_size_width = len;
+        }
+
+      if (format == long_format)
+        {
+          if (print_owner)
+            {
+              int len = format_user_width (f->stat.st_uid);
+              if (owner_width < len)
+                owner_width = len;
+            }
+
+          if (print_group)
+            {
+              int len = format_group_width (f->stat.st_gid);
+              if (group_width < len)
+                group_width = len;
+            }
+
+          if (print_author)
+            {
+              int len = format_user_width (f->stat.st_author);
+              if (author_width < len)
+                author_width = len;
+            }
+        }
+
+      if (print_scontext)
+        {
+          int len = strlen (f->scontext);
+          if (scontext_width < len)
+            scontext_width = len;
+        }
+
+      if (format == long_format)
+        {
+          char b[INT_BUFSIZE_BOUND (uintmax_t)];
+          int b_len = strlen (umaxtostr (f->stat.st_nlink, b));
+          if (nlink_width < b_len)
+            nlink_width = b_len;
+
+          if (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode))
+            {
+              char buf[INT_BUFSIZE_BOUND (uintmax_t)];
+              int len = strlen (umaxtostr (major (f->stat.st_rdev), buf));
+              if (major_device_number_width < len)
+                major_device_number_width = len;
+              len = strlen (umaxtostr (minor (f->stat.st_rdev), buf));
+              if (minor_device_number_width < len)
+                minor_device_number_width = len;
+              len = major_device_number_width + 2 + minor_device_number_width;
+              if (file_size_width < len)
+                file_size_width = len;
+            }
+          else
+            {
+              char buf[LONGEST_HUMAN_READABLE + 1];
+              uintmax_t size = unsigned_file_size (f->stat.st_size);
+              int len = mbswidth (human_readable (size, buf,
+                                                  file_human_output_opts,
+                                                  1, file_output_block_size),
+                                  0);
+              if (file_size_width < len)
+                file_size_width = len;
+            }
+        }
+    }
+
+  if (print_inode)
+    {
+      char buf[INT_BUFSIZE_BOUND (uintmax_t)];
+      int len = strlen (umaxtostr (f->stat.st_ino, buf));
+      if (inode_number_width < len)
+        inode_number_width = len;
+    }
+
+  f->name = xstrdup (name);
+  cwd_n_used++;
+
+  return blocks;
+}
+
+/* Return true if F refers to a directory.  */
+static bool
+is_directory (const struct fileinfo *f)
+{
+  return f->filetype == directory || f->filetype == arg_directory;
+}
+
+/* Return true if F refers to a (symlinked) directory.  */
+static bool
+is_linked_directory (const struct fileinfo *f)
+{
+  return f->filetype == directory || f->filetype == arg_directory
+         || S_ISDIR (f->linkmode);
+}
+
+/* Put the name of the file that FILENAME is a symbolic link to
+   into the LINKNAME field of 'f'.  COMMAND_LINE_ARG indicates whether
+   FILENAME is a command-line argument.  */
+
+static void
+get_link_name (char const *filename, struct fileinfo *f, bool command_line_arg)
+{
+  f->linkname = areadlink_with_size (filename, f->stat.st_size);
+  if (f->linkname == NULL)
+    file_failure (command_line_arg, _("cannot read symbolic link %s"),
+                  filename);
+}
+
+/* If LINKNAME is a relative name and NAME contains one or more
+   leading directories, return LINKNAME with those directories
+   prepended; otherwise, return a copy of LINKNAME.
+   If LINKNAME is NULL, return NULL.  */
+
+static char *
+make_link_name (char const *name, char const *linkname)
+{
+  if (!linkname)
+    return NULL;
+
+  if (IS_ABSOLUTE_FILE_NAME (linkname))
+    return xstrdup (linkname);
+
+  /* The link is to a relative name.  Prepend any leading directory
+     in 'name' to the link name.  */
+  size_t prefix_len = dir_len (name);
+  if (prefix_len == 0)
+    return xstrdup (linkname);
+
+  char *p = xmalloc (prefix_len + 1 + strlen (linkname) + 1);
+
+  /* PREFIX_LEN usually specifies a string not ending in slash.
+     In that case, extend it by one, since the next byte *is* a slash.
+     Otherwise, the prefix is "/", so leave the length unchanged.  */
+  if ( ! ISSLASH (name[prefix_len - 1]))
+    ++prefix_len;
+
+  stpcpy (stpncpy (p, name, prefix_len), linkname);
+  return p;
+}
+
+/* Return true if the last component of NAME is '.' or '..'
+   This is so we don't try to recurse on '././././. ...' */
+
+static bool
+basename_is_dot_or_dotdot (const char *name)
+{
+  char const *base = last_component (name);
+  return dot_or_dotdot (base);
+}
+
+/* Remove any entries from CWD_FILE that are for directories,
+   and queue them to be listed as directories instead.
+   DIRNAME is the prefix to prepend to each dirname
+   to make it correct relative to ls's working dir;
+   if it is null, no prefix is needed and "." and ".." should not be ignored.
+   If COMMAND_LINE_ARG is true, this directory was mentioned at the top level,
+   This is desirable when processing directories recursively.  */
+
+static void
+extract_dirs_from_files (char const *dirname, bool command_line_arg)
+{
+  size_t i;
+  size_t j;
+  bool ignore_dot_and_dot_dot = (dirname != NULL);
+
+  if (dirname && LOOP_DETECT)
+    {
+      /* Insert a marker entry first.  When we dequeue this marker entry,
+         we'll know that DIRNAME has been processed and may be removed
+         from the set of active directories.  */
+      queue_directory (NULL, dirname, false);
+    }
+
+  /* Queue the directories last one first, because queueing reverses the
+     order.  */
+  for (i = cwd_n_used; i-- != 0; )
+    {
+      struct fileinfo *f = sorted_file[i];
+
+      if (is_directory (f)
+          && (! ignore_dot_and_dot_dot
+              || ! basename_is_dot_or_dotdot (f->name)))
+        {
+          if (!dirname || f->name[0] == '/')
+            queue_directory (f->name, f->linkname, command_line_arg);
+          else
+            {
+              char *name = file_name_concat (dirname, f->name, NULL);
+              queue_directory (name, f->linkname, command_line_arg);
+              free (name);
+            }
+          if (f->filetype == arg_directory)
+            free_ent (f);
+        }
+    }
+
+  /* Now delete the directories from the table, compacting all the remaining
+     entries.  */
+
+  for (i = 0, j = 0; i < cwd_n_used; i++)
+    {
+      struct fileinfo *f = sorted_file[i];
+      sorted_file[j] = f;
+      j += (f->filetype != arg_directory);
+    }
+  cwd_n_used = j;
+}
+
+/* Use strcoll to compare strings in this locale.  If an error occurs,
+   report an error and longjmp to failed_strcoll.  */
+
+static jmp_buf failed_strcoll;
+
+static int
+xstrcoll (char const *a, char const *b)
+{
+  int diff;
+  errno = 0;
+  diff = strcoll (a, b);
+  if (errno)
+    {
+      error (0, errno, _("cannot compare file names %s and %s"),
+             quote_n (0, a), quote_n (1, b));
+      set_exit_status (false);
+      longjmp (failed_strcoll, 1);
+    }
+  return diff;
+}
+
+/* Comparison routines for sorting the files.  */
+
+typedef void const *V;
+typedef int (*qsortFunc)(V a, V b);
+
+/* Used below in DEFINE_SORT_FUNCTIONS for _df_ sort function variants.
+   The do { ... } while(0) makes it possible to use the macro more like
+   a statement, without violating C89 rules: */
+#define DIRFIRST_CHECK(a, b)						\
+  do									\
+    {									\
+      bool a_is_dir = is_linked_directory ((struct fileinfo const *) a);\
+      bool b_is_dir = is_linked_directory ((struct fileinfo const *) b);\
+      if (a_is_dir && !b_is_dir)					\
+        return -1;         /* a goes before b */			\
+      if (!a_is_dir && b_is_dir)					\
+        return 1;          /* b goes before a */			\
+    }									\
+  while (0)
+
+/* Define the 8 different sort function variants required for each sortkey.
+   KEY_NAME is a token describing the sort key, e.g., ctime, atime, size.
+   KEY_CMP_FUNC is a function to compare records based on that key, e.g.,
+   ctime_cmp, atime_cmp, size_cmp.  Append KEY_NAME to the string,
+   '[rev_][x]str{cmp|coll}[_df]_', to create each function name.  */
+#define DEFINE_SORT_FUNCTIONS(key_name, key_cmp_func)			\
+  /* direct, non-dirfirst versions */					\
+  static int xstrcoll_##key_name (V a, V b)				\
+  { return key_cmp_func (a, b, xstrcoll); }				\
+  static int _GL_ATTRIBUTE_PURE strcmp_##key_name (V a, V b)		\
+  { return key_cmp_func (a, b, strcmp); }				\
+                                                                        \
+  /* reverse, non-dirfirst versions */					\
+  static int rev_xstrcoll_##key_name (V a, V b)				\
+  { return key_cmp_func (b, a, xstrcoll); }				\
+  static int _GL_ATTRIBUTE_PURE rev_strcmp_##key_name (V a, V b)	\
+  { return key_cmp_func (b, a, strcmp); }				\
+                                                                        \
+  /* direct, dirfirst versions */					\
+  static int xstrcoll_df_##key_name (V a, V b)				\
+  { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, xstrcoll); }	\
+  static int _GL_ATTRIBUTE_PURE strcmp_df_##key_name (V a, V b)		\
+  { DIRFIRST_CHECK (a, b); return key_cmp_func (a, b, strcmp); }	\
+                                                                        \
+  /* reverse, dirfirst versions */					\
+  static int rev_xstrcoll_df_##key_name (V a, V b)			\
+  { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, xstrcoll); }	\
+  static int _GL_ATTRIBUTE_PURE rev_strcmp_df_##key_name (V a, V b)	\
+  { DIRFIRST_CHECK (a, b); return key_cmp_func (b, a, strcmp); }
+
+static inline int
+cmp_ctime (struct fileinfo const *a, struct fileinfo const *b,
+           int (*cmp) (char const *, char const *))
+{
+  int diff = timespec_cmp (get_stat_ctime (&b->stat),
+                           get_stat_ctime (&a->stat));
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_mtime (struct fileinfo const *a, struct fileinfo const *b,
+           int (*cmp) (char const *, char const *))
+{
+  int diff = timespec_cmp (get_stat_mtime (&b->stat),
+                           get_stat_mtime (&a->stat));
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_atime (struct fileinfo const *a, struct fileinfo const *b,
+           int (*cmp) (char const *, char const *))
+{
+  int diff = timespec_cmp (get_stat_atime (&b->stat),
+                           get_stat_atime (&a->stat));
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_btime (struct fileinfo const *a, struct fileinfo const *b,
+           int (*cmp) (char const *, char const *))
+{
+  int diff = timespec_cmp (get_stat_btime (&b->stat),
+                           get_stat_btime (&a->stat));
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_size (struct fileinfo const *a, struct fileinfo const *b,
+          int (*cmp) (char const *, char const *))
+{
+  int diff = longdiff (b->stat.st_size, a->stat.st_size);
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+static inline int
+cmp_name (struct fileinfo const *a, struct fileinfo const *b,
+          int (*cmp) (char const *, char const *))
+{
+  return cmp (a->name, b->name);
+}
+
+/* Compare file extensions.  Files with no extension are 'smallest'.
+   If extensions are the same, compare by file names instead.  */
+
+static inline int
+cmp_extension (struct fileinfo const *a, struct fileinfo const *b,
+               int (*cmp) (char const *, char const *))
+{
+  char const *base1 = strrchr (a->name, '.');
+  char const *base2 = strrchr (b->name, '.');
+  int diff = cmp (base1 ? base1 : "", base2 ? base2 : "");
+  return diff ? diff : cmp (a->name, b->name);
+}
+
+DEFINE_SORT_FUNCTIONS (ctime, cmp_ctime)
+DEFINE_SORT_FUNCTIONS (mtime, cmp_mtime)
+DEFINE_SORT_FUNCTIONS (atime, cmp_atime)
+DEFINE_SORT_FUNCTIONS (btime, cmp_btime)
+DEFINE_SORT_FUNCTIONS (size, cmp_size)
+DEFINE_SORT_FUNCTIONS (name, cmp_name)
+DEFINE_SORT_FUNCTIONS (extension, cmp_extension)
+
+/* Compare file versions.
+   Unlike all other compare functions above, cmp_version depends only
+   on filevercmp, which does not fail (even for locale reasons), and does not
+   need a secondary sort key. See lib/filevercmp.h for function description.
+
+   All the other sort options, in fact, need xstrcoll and strcmp variants,
+   because they all use a string comparison (either as the primary or secondary
+   sort key), and xstrcoll has the ability to do a longjmp if strcoll fails for
+   locale reasons.  Lastly, filevercmp is ALWAYS available with gnulib.  */
+static inline int
+cmp_version (struct fileinfo const *a, struct fileinfo const *b)
+{
+  return filevercmp (a->name, b->name);
+}
+
+static int xstrcoll_version (V a, V b)
+{ return cmp_version (a, b); }
+static int rev_xstrcoll_version (V a, V b)
+{ return cmp_version (b, a); }
+static int xstrcoll_df_version (V a, V b)
+{ DIRFIRST_CHECK (a, b); return cmp_version (a, b); }
+static int rev_xstrcoll_df_version (V a, V b)
+{ DIRFIRST_CHECK (a, b); return cmp_version (b, a); }
+
+
+/* We have 2^3 different variants for each sort-key function
+   (for 3 independent sort modes).
+   The function pointers stored in this array must be dereferenced as:
+
+    sort_variants[sort_key][use_strcmp][reverse][dirs_first]
+
+   Note that the order in which sort keys are listed in the function pointer
+   array below is defined by the order of the elements in the time_type and
+   sort_type enums!  */
+
+#define LIST_SORTFUNCTION_VARIANTS(key_name)                        \
+  {                                                                 \
+    {                                                               \
+      { xstrcoll_##key_name, xstrcoll_df_##key_name },              \
+      { rev_xstrcoll_##key_name, rev_xstrcoll_df_##key_name },      \
+    },                                                              \
+    {                                                               \
+      { strcmp_##key_name, strcmp_df_##key_name },                  \
+      { rev_strcmp_##key_name, rev_strcmp_df_##key_name },          \
+    }                                                               \
+  }
+
+static qsortFunc const sort_functions[][2][2][2] =
+  {
+    LIST_SORTFUNCTION_VARIANTS (name),
+    LIST_SORTFUNCTION_VARIANTS (extension),
+    LIST_SORTFUNCTION_VARIANTS (size),
+
+    {
+      {
+        { xstrcoll_version, xstrcoll_df_version },
+        { rev_xstrcoll_version, rev_xstrcoll_df_version },
+      },
+
+      /* We use NULL for the strcmp variants of version comparison
+         since as explained in cmp_version definition, version comparison
+         does not rely on xstrcoll, so it will never longjmp, and never
+         need to try the strcmp fallback. */
+      {
+        { NULL, NULL },
+        { NULL, NULL },
+      }
+    },
+
+    /* last are time sort functions */
+    LIST_SORTFUNCTION_VARIANTS (mtime),
+    LIST_SORTFUNCTION_VARIANTS (ctime),
+    LIST_SORTFUNCTION_VARIANTS (atime),
+    LIST_SORTFUNCTION_VARIANTS (btime)
+  };
+
+/* The number of sort keys is calculated as the sum of
+     the number of elements in the sort_type enum (i.e., sort_numtypes)
+     the number of elements in the time_type enum (i.e., time_numtypes) - 1
+   This is because when sort_type==sort_time, we have up to
+   time_numtypes possible sort keys.
+
+   This line verifies at compile-time that the array of sort functions has been
+   initialized for all possible sort keys. */
+verify (ARRAY_CARDINALITY (sort_functions)
+        == sort_numtypes + time_numtypes - 1 );
+
+/* Set up SORTED_FILE to point to the in-use entries in CWD_FILE, in order.  */
+
+static void
+initialize_ordering_vector (void)
+{
+  for (size_t i = 0; i < cwd_n_used; i++)
+    sorted_file[i] = &cwd_file[i];
+}
+
+/* Sort the files now in the table.  */
+
+static void
+sort_files (void)
+{
+  bool use_strcmp;
+
+  if (sorted_file_alloc < cwd_n_used + cwd_n_used / 2)
+    {
+      free (sorted_file);
+      sorted_file = xnmalloc (cwd_n_used, 3 * sizeof *sorted_file);
+      sorted_file_alloc = 3 * cwd_n_used;
+    }
+
+  initialize_ordering_vector ();
+
+  if (sort_type == sort_none)
+    return;
+
+  /* Try strcoll.  If it fails, fall back on strcmp.  We can't safely
+     ignore strcoll failures, as a failing strcoll might be a
+     comparison function that is not a total order, and if we ignored
+     the failure this might cause qsort to dump core.  */
+
+  if (! setjmp (failed_strcoll))
+    use_strcmp = false;      /* strcoll() succeeded */
+  else
+    {
+      use_strcmp = true;
+      assert (sort_type != sort_version);
+      initialize_ordering_vector ();
+    }
+
+  /* When sort_type == sort_time, use time_type as subindex.  */
+  mpsort ((void const **) sorted_file, cwd_n_used,
+          sort_functions[sort_type + (sort_type == sort_time ? time_type : 0)]
+                        [use_strcmp][sort_reverse]
+                        [directories_first]);
+}
+
+/* List all the files now in the table.  */
+
+static void
+print_current_files (void)
+{
+  size_t i;
+
+  switch (format)
+    {
+    case one_per_line:
+      for (i = 0; i < cwd_n_used; i++)
+        {
+          print_file_name_and_frills (sorted_file[i], 0);
+          putchar ('\n');
+        }
+      break;
+
+    case many_per_line:
+      if (! line_length)
+        print_with_separator (' ');
+      else
+        print_many_per_line ();
+      break;
+
+    case horizontal:
+      if (! line_length)
+        print_with_separator (' ');
+      else
+        print_horizontal ();
+      break;
+
+    case with_commas:
+      print_with_separator (',');
+      break;
+
+    case long_format:
+      for (i = 0; i < cwd_n_used; i++)
+        {
+          set_normal_color ();
+          print_long_format (sorted_file[i]);
+          DIRED_PUTCHAR ('\n');
+        }
+      break;
+    }
+}
+
+/* Replace the first %b with precomputed aligned month names.
+   Note on glibc-2.7 at least, this speeds up the whole 'ls -lU'
+   process by around 17%, compared to letting strftime() handle the %b.  */
+
+static size_t
+align_nstrftime (char *buf, size_t size, bool recent, struct tm const *tm,
+                 timezone_t tz, int ns)
+{
+  char const *nfmt = (use_abformat
+                      ? abformat[recent][tm->tm_mon]
+                      : long_time_format[recent]);
+  return nstrftime (buf, size, nfmt, tm, tz, ns);
+}
+
+/* Return the expected number of columns in a long-format timestamp,
+   or zero if it cannot be calculated.  */
+
+static int
+long_time_expected_width (void)
+{
+  static int width = -1;
+
+  if (width < 0)
+    {
+      time_t epoch = 0;
+      struct tm tm;
+      char buf[TIME_STAMP_LEN_MAXIMUM + 1];
+
+      /* In case you're wondering if localtime_rz can fail with an input time_t
+         value of 0, let's just say it's very unlikely, but not inconceivable.
+         The TZ environment variable would have to specify a time zone that
+         is 2**31-1900 years or more ahead of UTC.  This could happen only on
+         a 64-bit system that blindly accepts e.g., TZ=UTC+20000000000000.
+         However, this is not possible with Solaris 10 or glibc-2.3.5, since
+         their implementations limit the offset to 167:59 and 24:00, resp.  */
+      if (localtime_rz (localtz, &epoch, &tm))
+        {
+          size_t len = align_nstrftime (buf, sizeof buf, false,
+                                        &tm, localtz, 0);
+          if (len != 0)
+            width = mbsnwidth (buf, len, 0);
+        }
+
+      if (width < 0)
+        width = 0;
+    }
+
+  return width;
+}
+
+/* Print the user or group name NAME, with numeric id ID, using a
+   print width of WIDTH columns.  */
+
+static void
+format_user_or_group (char const *name, unsigned long int id, int width)
+{
+  size_t len;
+
+  if (name)
+    {
+      int width_gap = width - mbswidth (name, 0);
+      int pad = MAX (0, width_gap);
+      fputs (name, stdout);
+      len = strlen (name) + pad;
+
+      do
+        putchar (' ');
+      while (pad--);
+    }
+  else
+    {
+      printf ("%*lu ", width, id);
+      len = width;
+    }
+
+  dired_pos += len + 1;
+}
+
+/* Print the name or id of the user with id U, using a print width of
+   WIDTH.  */
+
+static void
+format_user (uid_t u, int width, bool stat_ok)
+{
+  format_user_or_group (! stat_ok ? "?" :
+                        (numeric_ids ? NULL : getuser (u)), u, width);
+}
+
+/* Likewise, for groups.  */
+
+static void
+format_group (gid_t g, int width, bool stat_ok)
+{
+  format_user_or_group (! stat_ok ? "?" :
+                        (numeric_ids ? NULL : getgroup (g)), g, width);
+}
+
+/* Return the number of columns that format_user_or_group will print.  */
+
+static int
+format_user_or_group_width (char const *name, unsigned long int id)
+{
+  if (name)
+    {
+      int len = mbswidth (name, 0);
+      return MAX (0, len);
+    }
+  else
+    {
+      char buf[INT_BUFSIZE_BOUND (id)];
+      sprintf (buf, "%lu", id);
+      return strlen (buf);
+    }
+}
+
+/* Return the number of columns that format_user will print.  */
+
+static int
+format_user_width (uid_t u)
+{
+  return format_user_or_group_width (numeric_ids ? NULL : getuser (u), u);
+}
+
+/* Likewise, for groups.  */
+
+static int
+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)
+{
+  char modebuf[12];
+  char buf
+    [LONGEST_HUMAN_READABLE + 1		/* inode */
+     + LONGEST_HUMAN_READABLE + 1	/* size in blocks */
+     + sizeof (modebuf) - 1 + 1		/* mode string */
+     + INT_BUFSIZE_BOUND (uintmax_t)	/* st_nlink */
+     + LONGEST_HUMAN_READABLE + 2	/* major device number */
+     + LONGEST_HUMAN_READABLE + 1	/* minor device number */
+     + TIME_STAMP_LEN_MAXIMUM + 1	/* max length of time/date */
+     ];
+  size_t s;
+  char *p;
+  struct timespec when_timespec;
+  struct tm when_local;
+  bool btime_ok = true;
+
+  /* Compute the mode string, except remove the trailing space if no
+     file in this directory has an ACL or security context.  */
+  if (f->stat_ok)
+    filemodestring (&f->stat, modebuf);
+  else
+    {
+      modebuf[0] = filetype_letter[f->filetype];
+      memset (modebuf + 1, '?', 10);
+      modebuf[11] = '\0';
+    }
+  if (! any_has_acl)
+    modebuf[10] = '\0';
+  else if (f->acl_type == ACL_T_LSM_CONTEXT_ONLY)
+    modebuf[10] = '.';
+  else if (f->acl_type == ACL_T_YES)
+    modebuf[10] = '+';
+
+  switch (time_type)
+    {
+    case time_ctime:
+      when_timespec = get_stat_ctime (&f->stat);
+      break;
+    case time_mtime:
+      when_timespec = get_stat_mtime (&f->stat);
+      break;
+    case time_atime:
+      when_timespec = get_stat_atime (&f->stat);
+      break;
+    case time_btime:
+      when_timespec = get_stat_btime (&f->stat);
+      if (when_timespec.tv_sec == -1 && when_timespec.tv_nsec == -1)
+        btime_ok = false;
+      break;
+    default:
+      abort ();
+    }
+
+  p = buf;
+
+  if (print_inode)
+    {
+      char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
+      sprintf (p, "%*s ", inode_number_width,
+               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);
+    }
+
+  if (print_block_size)
+    {
+      char hbuf[LONGEST_HUMAN_READABLE + 1];
+      char const *blocks =
+        (! f->stat_ok
+         ? "?"
+         : human_readable (ST_NBLOCKS (f->stat), hbuf, human_output_opts,
+                           ST_NBLOCKSIZE, output_block_size));
+      int pad;
+      for (pad = block_size_width - mbswidth (blocks, 0); 0 < pad; pad--)
+        *p++ = ' ';
+      while ((*p++ = *blocks++))
+        continue;
+      p[-1] = ' ';
+    }
+
+  /* The last byte of the mode string is the POSIX
+     "optional alternate access method flag".  */
+  {
+    char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
+    sprintf (p, "%s %*s ", modebuf, nlink_width,
+             ! f->stat_ok ? "?" : umaxtostr (f->stat.st_nlink, hbuf));
+  }
+  /* Increment by strlen (p) here, rather than by, e.g.,
+     sizeof modebuf - 2 + any_has_acl + 1 + nlink_width + 1.
+     The latter is wrong when nlink_width is zero.  */
+  p += strlen (p);
+
+  DIRED_INDENT ();
+
+  if (print_owner || print_group || print_author || print_scontext)
+    {
+      DIRED_FPUTS (buf, stdout, p - buf);
+
+      if (print_owner)
+        format_user (f->stat.st_uid, owner_width, f->stat_ok);
+
+      if (print_group)
+        format_group (f->stat.st_gid, group_width, f->stat_ok);
+
+      if (print_author)
+        format_user (f->stat.st_author, author_width, f->stat_ok);
+
+      if (print_scontext)
+        format_user_or_group (f->scontext, 0, scontext_width);
+
+      p = buf;
+    }
+
+  if (f->stat_ok
+      && (S_ISCHR (f->stat.st_mode) || S_ISBLK (f->stat.st_mode)))
+    {
+      char majorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
+      char minorbuf[INT_BUFSIZE_BOUND (uintmax_t)];
+      int blanks_width = (file_size_width
+                          - (major_device_number_width + 2
+                             + minor_device_number_width));
+      sprintf (p, "%*s, %*s ",
+               major_device_number_width + MAX (0, blanks_width),
+               umaxtostr (major (f->stat.st_rdev), majorbuf),
+               minor_device_number_width,
+               umaxtostr (minor (f->stat.st_rdev), minorbuf));
+      p += file_size_width + 1;
+    }
+  else
+    {
+      char hbuf[LONGEST_HUMAN_READABLE + 1];
+      char const *size =
+        (! f->stat_ok
+         ? "?"
+         : human_readable (unsigned_file_size (f->stat.st_size),
+                           hbuf, file_human_output_opts, 1,
+                           file_output_block_size));
+      int pad;
+      for (pad = file_size_width - mbswidth (size, 0); 0 < pad; pad--)
+        *p++ = ' ';
+      while ((*p++ = *size++))
+        continue;
+      p[-1] = ' ';
+    }
+
+  s = 0;
+  *p = '\1';
+
+  if (f->stat_ok && btime_ok
+      && localtime_rz (localtz, &when_timespec.tv_sec, &when_local))
+    {
+      struct timespec six_months_ago;
+      bool recent;
+
+      /* If the file appears to be in the future, update the current
+         time, in case the file happens to have been modified since
+         the last time we checked the clock.  */
+      if (timespec_cmp (current_time, when_timespec) < 0)
+        gettime (&current_time);
+
+      /* Consider a time to be recent if it is within the past six months.
+         A Gregorian year has 365.2425 * 24 * 60 * 60 == 31556952 seconds
+         on the average.  Write this value as an integer constant to
+         avoid floating point hassles.  */
+      six_months_ago.tv_sec = current_time.tv_sec - 31556952 / 2;
+      six_months_ago.tv_nsec = current_time.tv_nsec;
+
+      recent = (timespec_cmp (six_months_ago, when_timespec) < 0
+                && (timespec_cmp (when_timespec, current_time) < 0));
+
+      /* We assume here that all time zones are offset from UTC by a
+         whole number of seconds.  */
+      s = align_nstrftime (p, TIME_STAMP_LEN_MAXIMUM + 1, recent,
+                           &when_local, localtz, when_timespec.tv_nsec);
+    }
+
+  if (s || !*p)
+    {
+      p += s;
+      *p++ = ' ';
+
+      /* NUL-terminate the string -- fputs (via DIRED_FPUTS) requires it.  */
+      *p = '\0';
+    }
+  else
+    {
+      /* The time cannot be converted using the desired format, so
+         print it as a huge integer number of seconds.  */
+      char hbuf[INT_BUFSIZE_BOUND (intmax_t)];
+      sprintf (p, "%*s ", long_time_expected_width (),
+               (! f->stat_ok || ! btime_ok
+                ? "?"
+                : timetostr (when_timespec.tv_sec, hbuf)));
+      /* FIXME: (maybe) We discarded when_timespec.tv_nsec. */
+      p += strlen (p);
+    }
+
+  DIRED_FPUTS (buf, stdout, p - buf);
+  size_t w = print_name_with_quoting (f, false, &dired_obstack, p - buf);
+
+  if (f->filetype == symbolic_link)
+    {
+      if (f->linkname)
+        {
+          DIRED_FPUTS_LITERAL (" -> ", stdout);
+          print_name_with_quoting (f, true, NULL, (p - buf) + w + 4);
+          if (indicator_style != none)
+            print_type_indicator (true, f->linkmode, unknown);
+        }
+    }
+  else if (indicator_style != none)
+    print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
+}
+
+/* Write to *BUF a quoted representation of the file name NAME, if non-NULL,
+   using OPTIONS to control quoting.  *BUF is set to NAME if no quoting
+   is required.  *BUF is allocated if more space required (and the original
+   *BUF is not deallocated).
+   Store the number of screen columns occupied by NAME's quoted
+   representation into WIDTH, if non-NULL.
+   Store into PAD whether an initial space is needed for padding.
+   Return the number of bytes in *BUF.  */
+
+static size_t
+quote_name_buf (char **inbuf, size_t bufsize, char *name,
+                struct quoting_options const *options,
+                int needs_general_quoting, size_t *width, bool *pad)
+{
+  char *buf = *inbuf;
+  size_t displayed_width IF_LINT ( = 0);
+  size_t len = 0;
+  bool quoted;
+
+  enum quoting_style qs = get_quoting_style (options);
+  bool needs_further_quoting = qmark_funny_chars
+                               && (qs == shell_quoting_style
+                                   || qs == shell_always_quoting_style
+                                   || qs == literal_quoting_style);
+
+  if (needs_general_quoting != 0)
+    {
+      len = quotearg_buffer (buf, bufsize, name, -1, options);
+      if (bufsize <= len)
+        {
+          buf = xmalloc (len + 1);
+          quotearg_buffer (buf, len + 1, name, -1, options);
+        }
+
+      quoted = (*name != *buf) || strlen (name) != len;
+    }
+  else if (needs_further_quoting)
+    {
+      len = strlen (name);
+      if (bufsize <= len)
+        buf = xmalloc (len + 1);
+      memcpy (buf, name, len + 1);
+
+      quoted = false;
+    }
+  else
+    {
+      len = strlen (name);
+      buf = name;
+      quoted = false;
+    }
+
+  if (needs_further_quoting)
+    {
+      if (MB_CUR_MAX > 1)
+        {
+          char const *p = buf;
+          char const *plimit = buf + len;
+          char *q = buf;
+          displayed_width = 0;
+
+          while (p < plimit)
+            switch (*p)
+              {
+                case ' ': case '!': case '"': case '#': case '%':
+                case '&': case '\'': case '(': case ')': case '*':
+                case '+': case ',': case '-': case '.': case '/':
+                case '0': case '1': case '2': case '3': case '4':
+                case '5': case '6': case '7': case '8': case '9':
+                case ':': case ';': case '<': case '=': case '>':
+                case '?':
+                case 'A': case 'B': case 'C': case 'D': case 'E':
+                case 'F': case 'G': case 'H': case 'I': case 'J':
+                case 'K': case 'L': case 'M': case 'N': case 'O':
+                case 'P': case 'Q': case 'R': case 'S': case 'T':
+                case 'U': case 'V': case 'W': case 'X': case 'Y':
+                case 'Z':
+                case '[': case '\\': case ']': case '^': case '_':
+                case 'a': case 'b': case 'c': case 'd': case 'e':
+                case 'f': case 'g': case 'h': case 'i': case 'j':
+                case 'k': case 'l': case 'm': case 'n': case 'o':
+                case 'p': case 'q': case 'r': case 's': case 't':
+                case 'u': case 'v': case 'w': case 'x': case 'y':
+                case 'z': case '{': case '|': case '}': case '~':
+                  /* These characters are printable ASCII characters.  */
+                  *q++ = *p++;
+                  displayed_width += 1;
+                  break;
+                default:
+                  /* If we have a multibyte sequence, copy it until we
+                     reach its end, replacing each non-printable multibyte
+                     character with a single question mark.  */
+                  {
+                    mbstate_t mbstate = { 0, };
+                    do
+                      {
+                        wchar_t wc;
+                        size_t bytes;
+                        int w;
+
+                        bytes = mbrtowc (&wc, p, plimit - p, &mbstate);
+
+                        if (bytes == (size_t) -1)
+                          {
+                            /* An invalid multibyte sequence was
+                               encountered.  Skip one input byte, and
+                               put a question mark.  */
+                            p++;
+                            *q++ = '?';
+                            displayed_width += 1;
+                            break;
+                          }
+
+                        if (bytes == (size_t) -2)
+                          {
+                            /* An incomplete multibyte character
+                               at the end.  Replace it entirely with
+                               a question mark.  */
+                            p = plimit;
+                            *q++ = '?';
+                            displayed_width += 1;
+                            break;
+                          }
+
+                        if (bytes == 0)
+                          /* A null wide character was encountered.  */
+                          bytes = 1;
+
+                        w = wcwidth (wc);
+                        if (w >= 0)
+                          {
+                            /* A printable multibyte character.
+                               Keep it.  */
+                            for (; bytes > 0; --bytes)
+                              *q++ = *p++;
+                            displayed_width += w;
+                          }
+                        else
+                          {
+                            /* An unprintable multibyte character.
+                               Replace it entirely with a question
+                               mark.  */
+                            p += bytes;
+                            *q++ = '?';
+                            displayed_width += 1;
+                          }
+                      }
+                    while (! mbsinit (&mbstate));
+                  }
+                  break;
+              }
+
+          /* The buffer may have shrunk.  */
+          len = q - buf;
+        }
+      else
+        {
+          char *p = buf;
+          char const *plimit = buf + len;
+
+          while (p < plimit)
+            {
+              if (! isprint (to_uchar (*p)))
+                *p = '?';
+              p++;
+            }
+          displayed_width = len;
+        }
+    }
+  else if (width != NULL)
+    {
+      if (MB_CUR_MAX > 1)
+        displayed_width = mbsnwidth (buf, len, 0);
+      else
+        {
+          char const *p = buf;
+          char const *plimit = buf + len;
+
+          displayed_width = 0;
+          while (p < plimit)
+            {
+              if (isprint (to_uchar (*p)))
+                displayed_width++;
+              p++;
+            }
+        }
+    }
+
+  /* Set padding to better align quoted items,
+     and also give a visual indication that quotes are
+     not actually part of the name.  */
+  *pad = (align_variable_outer_quotes && cwd_some_quoted && ! quoted);
+
+  if (width != NULL)
+    *width = displayed_width;
+
+  *inbuf = buf;
+
+  return len;
+}
+
+static size_t
+quote_name_width (const char *name, struct quoting_options const *options,
+                  int needs_general_quoting)
+{
+  char smallbuf[BUFSIZ];
+  char *buf = smallbuf;
+  size_t width;
+  bool pad;
+
+  quote_name_buf (&buf, sizeof smallbuf, (char *) name, options,
+                  needs_general_quoting, &width, &pad);
+
+  if (buf != smallbuf && buf != name)
+    free (buf);
+
+  width += pad;
+
+  return width;
+}
+
+/* %XX escape any input out of range as defined in RFC3986,
+   and also if PATH, convert all path separators to '/'.  */
+static char *
+file_escape (const char *str, bool path)
+{
+  char *esc = xnmalloc (3, strlen (str) + 1);
+  char *p = esc;
+  while (*str)
+    {
+      if (path && ISSLASH (*str))
+        {
+          *p++ = '/';
+          str++;
+        }
+      else if (RFC3986[to_uchar (*str)])
+        *p++ = *str++;
+      else
+        p += sprintf (p, "%%%02x", to_uchar (*str++));
+    }
+  *p = '\0';
+  return esc;
+}
+
+static size_t
+quote_name (char const *name, struct quoting_options const *options,
+            int needs_general_quoting, const struct bin_str *color,
+            bool allow_pad, struct obstack *stack, char const *absolute_name)
+{
+  char smallbuf[BUFSIZ];
+  char *buf = smallbuf;
+  size_t len;
+  bool pad;
+
+  len = quote_name_buf (&buf, sizeof smallbuf, (char *) name, options,
+                        needs_general_quoting, NULL, &pad);
+
+  if (pad && allow_pad)
+      DIRED_PUTCHAR (' ');
+
+  if (color)
+    print_color_indicator (color);
+
+  /* If we're padding, then don't include the outer quotes in
+     the --hyperlink, to improve the alignment of those links.  */
+  bool skip_quotes = false;
+
+  if (absolute_name)
+    {
+      if (align_variable_outer_quotes && cwd_some_quoted && ! pad)
+        {
+          skip_quotes = true;
+          putchar (*buf);
+        }
+      char *h = file_escape (hostname, /* path= */ false);
+      char *n = file_escape (absolute_name, /* path= */ true);
+      /* TODO: It would be good to be able to define parameters
+         to give hints to the terminal as how best to render the URI.
+         For example since ls is outputting a dense block of URIs
+         it would be best to not underline by default, and only
+         do so upon hover etc.  */
+      printf ("\033]8;;file://%s%s%s\a", h, *n == '/' ? "" : "/", n);
+      free (h);
+      free (n);
+    }
+
+  if (stack)
+    PUSH_CURRENT_DIRED_POS (stack);
+
+  fwrite (buf + skip_quotes, 1, len - (skip_quotes * 2), stdout);
+
+  dired_pos += len;
+
+  if (stack)
+    PUSH_CURRENT_DIRED_POS (stack);
+
+  if (absolute_name)
+    {
+      fputs ("\033]8;;\a", stdout);
+      if (skip_quotes)
+        putchar (*(buf + len - 1));
+    }
+
+  if (buf != smallbuf && buf != name)
+    free (buf);
+
+  return len + pad;
+}
+
+static size_t
+print_name_with_quoting (const struct fileinfo *f,
+                         bool symlink_target,
+                         struct obstack *stack,
+                         size_t start_col)
+{
+  const char* name = symlink_target ? f->linkname : f->name;
+
+  const struct bin_str *color = print_with_color ?
+                                get_color_indicator (f, symlink_target) : NULL;
+
+  bool used_color_this_time = (print_with_color
+                               && (color || is_colored (C_NORM)));
+
+  size_t len = quote_name (name, filename_quoting_options, f->quoted,
+                           color, !symlink_target, stack, f->absolute_name);
+
+  process_signals ();
+  if (used_color_this_time)
+    {
+      prep_non_filename_text ();
+
+      /* We use the byte length rather than display width here as
+         an optimization to avoid accurately calculating the width,
+         because we only output the clear to EOL sequence if the name
+         _might_ wrap to the next line.  This may output a sequence
+         unnecessarily in multi-byte locales for example,
+         but in that case it's inconsequential to the output.  */
+      if (line_length
+          && (start_col / line_length != (start_col + len - 1) / line_length))
+        put_indicator (&color_indicator[C_CLR_TO_EOL]);
+    }
+
+  return len;
+}
+
+static void
+prep_non_filename_text (void)
+{
+  if (color_indicator[C_END].string != NULL)
+    put_indicator (&color_indicator[C_END]);
+  else
+    {
+      put_indicator (&color_indicator[C_LEFT]);
+      put_indicator (&color_indicator[C_RESET]);
+      put_indicator (&color_indicator[C_RIGHT]);
+    }
+}
+
+/* Print the file name of 'f' with appropriate quoting.
+   Also print file size, inode number, and filetype indicator character,
+   as requested by switches.  */
+
+static size_t
+print_file_name_and_frills (const struct fileinfo *f, size_t start_col)
+{
+  char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
+
+  set_normal_color ();
+
+  if (print_inode)
+    printf ("%*s ", format == with_commas ? 0 : inode_number_width,
+            format_inode (buf, sizeof buf, f));
+
+  if (print_block_size)
+    printf ("%*s ", format == with_commas ? 0 : block_size_width,
+            ! 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);
+
+  size_t width = print_name_with_quoting (f, false, NULL, start_col);
+
+  if (indicator_style != none)
+    width += print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
+
+  return width;
+}
+
+/* Given these arguments describing a file, return the single-byte
+   type indicator, or 0.  */
+static char
+get_type_indicator (bool stat_ok, mode_t mode, enum filetype type)
+{
+  char c;
+
+  if (stat_ok ? S_ISREG (mode) : type == normal)
+    {
+      if (stat_ok && indicator_style == classify && (mode & S_IXUGO))
+        c = '*';
+      else
+        c = 0;
+    }
+  else
+    {
+      if (stat_ok ? S_ISDIR (mode) : type == directory || type == arg_directory)
+        c = '/';
+      else if (indicator_style == slash)
+        c = 0;
+      else if (stat_ok ? S_ISLNK (mode) : type == symbolic_link)
+        c = '@';
+      else if (stat_ok ? S_ISFIFO (mode) : type == fifo)
+        c = '|';
+      else if (stat_ok ? S_ISSOCK (mode) : type == sock)
+        c = '=';
+      else if (stat_ok && S_ISDOOR (mode))
+        c = '>';
+      else
+        c = 0;
+    }
+  return c;
+}
+
+static bool
+print_type_indicator (bool stat_ok, mode_t mode, enum filetype type)
+{
+  char c = get_type_indicator (stat_ok, mode, type);
+  if (c)
+    DIRED_PUTCHAR (c);
+  return !!c;
+}
+
+/* Returns if color sequence was printed.  */
+static bool
+print_color_indicator (const struct bin_str *ind)
+{
+  if (ind)
+    {
+      /* Need to reset so not dealing with attribute combinations */
+      if (is_colored (C_NORM))
+        restore_default_color ();
+      put_indicator (&color_indicator[C_LEFT]);
+      put_indicator (ind);
+      put_indicator (&color_indicator[C_RIGHT]);
+    }
+
+  return ind != NULL;
+}
+
+/* Returns color indicator or NULL if none.  */
+static const struct bin_str* _GL_ATTRIBUTE_PURE
+get_color_indicator (const struct fileinfo *f, bool symlink_target)
+{
+  enum indicator_no type;
+  struct color_ext_type *ext;	/* Color extension */
+  size_t len;			/* Length of name */
+
+  const char* name;
+  mode_t mode;
+  int linkok;
+  if (symlink_target)
+    {
+      name = f->linkname;
+      mode = f->linkmode;
+      linkok = f->linkok ? 0 : -1;
+    }
+  else
+    {
+      name = f->name;
+      mode = FILE_OR_LINK_MODE (f);
+      linkok = f->linkok;
+    }
+
+  /* Is this a nonexistent file?  If so, linkok == -1.  */
+
+  if (linkok == -1 && is_colored (C_MISSING))
+    type = C_MISSING;
+  else if (!f->stat_ok)
+    {
+      static enum indicator_no filetype_indicator[] = FILETYPE_INDICATORS;
+      type = filetype_indicator[f->filetype];
+    }
+  else
+    {
+      if (S_ISREG (mode))
+        {
+          type = C_FILE;
+
+          if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
+            type = C_SETUID;
+          else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
+            type = C_SETGID;
+          else if (is_colored (C_CAP) && f->has_capability)
+            type = C_CAP;
+          else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
+            type = C_EXEC;
+          else if ((1 < f->stat.st_nlink) && is_colored (C_MULTIHARDLINK))
+            type = C_MULTIHARDLINK;
+        }
+      else if (S_ISDIR (mode))
+        {
+          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 && is_colored (C_OTHER_WRITABLE))
+            type = C_OTHER_WRITABLE;
+          else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
+            type = C_STICKY;
+        }
+      else if (S_ISLNK (mode))
+        type = C_LINK;
+      else if (S_ISFIFO (mode))
+        type = C_FIFO;
+      else if (S_ISSOCK (mode))
+        type = C_SOCK;
+      else if (S_ISBLK (mode))
+        type = C_BLK;
+      else if (S_ISCHR (mode))
+        type = C_CHR;
+      else if (S_ISDOOR (mode))
+        type = C_DOOR;
+      else
+        {
+          /* Classify a file of some other type as C_ORPHAN.  */
+          type = C_ORPHAN;
+        }
+    }
+
+  /* Check the file's suffix only if still classified as C_FILE.  */
+  ext = NULL;
+  if (type == C_FILE)
+    {
+      /* Test if NAME has a recognized suffix.  */
+
+      len = strlen (name);
+      name += len;		/* Pointer to final \0.  */
+      for (ext = color_ext_list; ext != NULL; ext = ext->next)
+        {
+          if (ext->ext.len <= len
+              && c_strncasecmp (name - ext->ext.len, ext->ext.string,
+                                ext->ext.len) == 0)
+            break;
+        }
+    }
+
+  /* Adjust the color for orphaned symlinks.  */
+  if (type == C_LINK && !linkok)
+    {
+      if (color_symlink_as_referent || is_colored (C_ORPHAN))
+        type = C_ORPHAN;
+    }
+
+  const struct bin_str *const s
+    = ext ? &(ext->seq) : &color_indicator[type];
+
+  return s->string ? s : NULL;
+}
+
+/* Output a color indicator (which may contain nulls).  */
+static void
+put_indicator (const struct bin_str *ind)
+{
+  if (! used_color)
+    {
+      used_color = true;
+
+      /* If the standard output is a controlling terminal, watch out
+         for signals, so that the colors can be restored to the
+         default state if "ls" is suspended or interrupted.  */
+
+      if (0 <= tcgetpgrp (STDOUT_FILENO))
+        signal_init ();
+
+      prep_non_filename_text ();
+    }
+
+  fwrite (ind->string, ind->len, 1, stdout);
+}
+
+static size_t
+length_of_file_name_and_frills (const struct fileinfo *f)
+{
+  size_t len = 0;
+  char buf[MAX (LONGEST_HUMAN_READABLE + 1, INT_BUFSIZE_BOUND (uintmax_t))];
+
+  if (print_inode)
+    len += 1 + (format == with_commas
+                ? strlen (umaxtostr (f->stat.st_ino, buf))
+                : inode_number_width);
+
+  if (print_block_size)
+    len += 1 + (format == with_commas
+                ? 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)
+    len += 1 + (format == with_commas ? strlen (f->scontext) : scontext_width);
+
+  len += quote_name_width (f->name, filename_quoting_options, f->quoted);
+
+  if (indicator_style != none)
+    {
+      char c = get_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
+      len += (c != 0);
+    }
+
+  return len;
+}
+
+static void
+print_many_per_line (void)
+{
+  size_t row;			/* Current row.  */
+  size_t cols = calculate_columns (true);
+  struct column_info const *line_fmt = &column_info[cols - 1];
+
+  /* Calculate the number of rows that will be in each column except possibly
+     for a short column on the right.  */
+  size_t rows = cwd_n_used / cols + (cwd_n_used % cols != 0);
+
+  for (row = 0; row < rows; row++)
+    {
+      size_t col = 0;
+      size_t filesno = row;
+      size_t pos = 0;
+
+      /* Print the next row.  */
+      while (1)
+        {
+          struct fileinfo const *f = sorted_file[filesno];
+          size_t name_length = length_of_file_name_and_frills (f);
+          size_t max_name_length = line_fmt->col_arr[col++];
+          print_file_name_and_frills (f, pos);
+
+          filesno += rows;
+          if (filesno >= cwd_n_used)
+            break;
+
+          indent (pos + name_length, pos + max_name_length);
+          pos += max_name_length;
+        }
+      putchar ('\n');
+    }
+}
+
+static void
+print_horizontal (void)
+{
+  size_t filesno;
+  size_t pos = 0;
+  size_t cols = calculate_columns (false);
+  struct column_info const *line_fmt = &column_info[cols - 1];
+  struct fileinfo const *f = sorted_file[0];
+  size_t name_length = length_of_file_name_and_frills (f);
+  size_t max_name_length = line_fmt->col_arr[0];
+
+  /* Print first entry.  */
+  print_file_name_and_frills (f, 0);
+
+  /* Now the rest.  */
+  for (filesno = 1; filesno < cwd_n_used; ++filesno)
+    {
+      size_t col = filesno % cols;
+
+      if (col == 0)
+        {
+          putchar ('\n');
+          pos = 0;
+        }
+      else
+        {
+          indent (pos + name_length, pos + max_name_length);
+          pos += max_name_length;
+        }
+
+      f = sorted_file[filesno];
+      print_file_name_and_frills (f, pos);
+
+      name_length = length_of_file_name_and_frills (f);
+      max_name_length = line_fmt->col_arr[col];
+    }
+  putchar ('\n');
+}
+
+/* Output name + SEP + ' '.  */
+
+static void
+print_with_separator (char sep)
+{
+  size_t filesno;
+  size_t pos = 0;
+
+  for (filesno = 0; filesno < cwd_n_used; filesno++)
+    {
+      struct fileinfo const *f = sorted_file[filesno];
+      size_t len = line_length ? length_of_file_name_and_frills (f) : 0;
+
+      if (filesno != 0)
+        {
+          char separator;
+
+          if (! line_length
+              || ((pos + len + 2 < line_length)
+                  && (pos <= SIZE_MAX - len - 2)))
+            {
+              pos += 2;
+              separator = ' ';
+            }
+          else
+            {
+              pos = 0;
+              separator = '\n';
+            }
+
+          putchar (sep);
+          putchar (separator);
+        }
+
+      print_file_name_and_frills (f, pos);
+      pos += len;
+    }
+  putchar ('\n');
+}
+
+/* Assuming cursor is at position FROM, indent up to position TO.
+   Use a TAB character instead of two or more spaces whenever possible.  */
+
+static void
+indent (size_t from, size_t to)
+{
+  while (from < to)
+    {
+      if (tabsize != 0 && to / tabsize > (from + 1) / tabsize)
+        {
+          putchar ('\t');
+          from += tabsize - from % tabsize;
+        }
+      else
+        {
+          putchar (' ');
+          from++;
+        }
+    }
+}
+
+/* Put DIRNAME/NAME into DEST, handling '.' and '/' properly.  */
+/* FIXME: maybe remove this function someday.  See about using a
+   non-malloc'ing version of file_name_concat.  */
+
+static void
+attach (char *dest, const char *dirname, const char *name)
+{
+  const char *dirnamep = dirname;
+
+  /* Copy dirname if it is not ".".  */
+  if (dirname[0] != '.' || dirname[1] != 0)
+    {
+      while (*dirnamep)
+        *dest++ = *dirnamep++;
+      /* Add '/' if 'dirname' doesn't already end with it.  */
+      if (dirnamep > dirname && dirnamep[-1] != '/')
+        *dest++ = '/';
+    }
+  while (*name)
+    *dest++ = *name++;
+  *dest = 0;
+}
+
+/* Allocate enough column info suitable for the current number of
+   files and display columns, and initialize the info to represent the
+   narrowest possible columns.  */
+
+static void
+init_column_info (void)
+{
+  size_t i;
+  size_t max_cols = MIN (max_idx, cwd_n_used);
+
+  /* Currently allocated columns in column_info.  */
+  static size_t column_info_alloc;
+
+  if (column_info_alloc < max_cols)
+    {
+      size_t new_column_info_alloc;
+      size_t *p;
+
+      if (max_cols < max_idx / 2)
+        {
+          /* The number of columns is far less than the display width
+             allows.  Grow the allocation, but only so that it's
+             double the current requirements.  If the display is
+             extremely wide, this avoids allocating a lot of memory
+             that is never needed.  */
+          column_info = xnrealloc (column_info, max_cols,
+                                   2 * sizeof *column_info);
+          new_column_info_alloc = 2 * max_cols;
+        }
+      else
+        {
+          column_info = xnrealloc (column_info, max_idx, sizeof *column_info);
+          new_column_info_alloc = max_idx;
+        }
+
+      /* Allocate the new size_t objects by computing the triangle
+         formula n * (n + 1) / 2, except that we don't need to
+         allocate the part of the triangle that we've already
+         allocated.  Check for address arithmetic overflow.  */
+      {
+        size_t column_info_growth = new_column_info_alloc - column_info_alloc;
+        size_t s = column_info_alloc + 1 + new_column_info_alloc;
+        size_t t = s * column_info_growth;
+        if (s < new_column_info_alloc || t / column_info_growth != s)
+          xalloc_die ();
+        p = xnmalloc (t / 2, sizeof *p);
+      }
+
+      /* Grow the triangle by parceling out the cells just allocated.  */
+      for (i = column_info_alloc; i < new_column_info_alloc; i++)
+        {
+          column_info[i].col_arr = p;
+          p += i + 1;
+        }
+
+      column_info_alloc = new_column_info_alloc;
+    }
+
+  for (i = 0; i < max_cols; ++i)
+    {
+      size_t j;
+
+      column_info[i].valid_len = true;
+      column_info[i].line_len = (i + 1) * MIN_COLUMN_WIDTH;
+      for (j = 0; j <= i; ++j)
+        column_info[i].col_arr[j] = MIN_COLUMN_WIDTH;
+    }
+}
+
+/* Calculate the number of columns needed to represent the current set
+   of files in the current display width.  */
+
+static size_t
+calculate_columns (bool by_columns)
+{
+  size_t filesno;		/* Index into cwd_file.  */
+  size_t cols;			/* Number of files across.  */
+
+  /* Normally the maximum number of columns is determined by the
+     screen width.  But if few files are available this might limit it
+     as well.  */
+  size_t max_cols = MIN (max_idx, cwd_n_used);
+
+  init_column_info ();
+
+  /* Compute the maximum number of possible columns.  */
+  for (filesno = 0; filesno < cwd_n_used; ++filesno)
+    {
+      struct fileinfo const *f = sorted_file[filesno];
+      size_t name_length = length_of_file_name_and_frills (f);
+
+      for (size_t i = 0; i < max_cols; ++i)
+        {
+          if (column_info[i].valid_len)
+            {
+              size_t idx = (by_columns
+                            ? filesno / ((cwd_n_used + i) / (i + 1))
+                            : filesno % (i + 1));
+              size_t real_length = name_length + (idx == i ? 0 : 2);
+
+              if (column_info[i].col_arr[idx] < real_length)
+                {
+                  column_info[i].line_len += (real_length
+                                              - column_info[i].col_arr[idx]);
+                  column_info[i].col_arr[idx] = real_length;
+                  column_info[i].valid_len = (column_info[i].line_len
+                                              < line_length);
+                }
+            }
+        }
+    }
+
+  /* Find maximum allowed columns.  */
+  for (cols = max_cols; 1 < cols; --cols)
+    {
+      if (column_info[cols - 1].valid_len)
+        break;
+    }
+
+  return cols;
+}
+
+void
+usage (int status)
+{
+  if (status != EXIT_SUCCESS)
+    emit_try_help ();
+  else
+    {
+      printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
+      fputs (_("\
+List information about the FILEs (the current directory by default).\n\
+Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.\n\
+"), stdout);
+
+      emit_mandatory_arg_note ();
+
+      fputs (_("\
+  -a, --all                  do not ignore entries starting with .\n\
+  -A, --almost-all           do not list implied . and ..\n\
+      --author               with -l, print the author of each file\n\
+  -b, --escape               print C-style escapes for nongraphic characters\n\
+"), stdout);
+      fputs (_("\
+      --block-size=SIZE      with -l, scale sizes by SIZE when printing them;\n\
+                               e.g., '--block-size=M'; see SIZE format below\n\
+"), stdout);
+      fputs (_("\
+  -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\
+                               with -l: show ctime and sort by name;\n\
+                               otherwise: sort by ctime, newest first\n\
+"), stdout);
+      fputs (_("\
+  -C                         list entries by columns\n\
+      --color[=WHEN]         colorize the output; WHEN can be 'always' (default\
+\n\
+                               if omitted), 'auto', or 'never'; more info below\
+\n\
+  -d, --directory            list directories themselves, not their contents\n\
+  -D, --dired                generate output designed for Emacs' dired mode\n\
+"), stdout);
+      fputs (_("\
+  -f                         do not sort, enable -aU, disable -ls --color\n\
+  -F, --classify             append indicator (one of */=>@|) to entries\n\
+      --file-type            likewise, except do not append '*'\n\
+      --format=WORD          across -x, commas -m, horizontal -x, long -l,\n\
+                               single-column -1, verbose -l, vertical -C\n\
+      --full-time            like -l --time-style=full-iso\n\
+"), stdout);
+      fputs (_("\
+  -g                         like -l, but do not list owner\n\
+"), stdout);
+      fputs (_("\
+      --group-directories-first\n\
+                             group directories before files;\n\
+                               can be augmented with a --sort option, but any\n\
+                               use of --sort=none (-U) disables grouping\n\
+"), stdout);
+      fputs (_("\
+  -G, --no-group             in a long listing, don't print group names\n\
+"), stdout);
+      fputs (_("\
+  -h, --human-readable       with -l and -s, print sizes like 1K 234M 2G etc.\n\
+      --si                   likewise, but use powers of 1000 not 1024\n\
+"), stdout);
+      fputs (_("\
+  -H, --dereference-command-line\n\
+                             follow symbolic links listed on the command line\n\
+      --dereference-command-line-symlink-to-dir\n\
+                             follow each command line symbolic link\n\
+                               that points to a directory\n\
+      --hide=PATTERN         do not list implied entries matching shell PATTERN\
+\n\
+                               (overridden by -a or -A)\n\
+"), stdout);
+      fputs (_("\
+      --hyperlink[=WHEN]     hyperlink file names; WHEN can be 'always'\n\
+                               (default if omitted), 'auto', or 'never'\n\
+"), stdout);
+      fputs (_("\
+      --indicator-style=WORD  append indicator with style WORD to entry names:\
+\n\
+                               none (default), slash (-p),\n\
+                               file-type (--file-type), classify (-F)\n\
+  -i, --inode                print the index number of each file\n\
+  -I, --ignore=PATTERN       do not list implied entries matching shell PATTERN\
+\n\
+"), stdout);
+      fputs (_("\
+  -k, --kibibytes            default to 1024-byte blocks for disk usage;\n\
+                               used only with -s and per directory totals\n\
+"), stdout);
+      fputs (_("\
+  -l                         use a long listing format\n\
+  -L, --dereference          when showing file information for a symbolic\n\
+                               link, show information for the file the link\n\
+                               references rather than for the link itself\n\
+  -m                         fill width with a comma separated list of entries\
+\n\
+"), stdout);
+      fputs (_("\
+  -n, --numeric-uid-gid      like -l, but list numeric user and group IDs\n\
+  -N, --literal              print entry names without quoting\n\
+  -o                         like -l, but do not list group information\n\
+  -p, --indicator-style=slash\n\
+                             append / indicator to directories\n\
+"), stdout);
+      fputs (_("\
+  -q, --hide-control-chars   print ? instead of nongraphic characters\n\
+      --show-control-chars   show nongraphic characters as-is (the default,\n\
+                               unless program is 'ls' and output is a terminal)\
+\n\
+  -Q, --quote-name           enclose entry names in double quotes\n\
+      --quoting-style=WORD   use quoting style WORD for entry names:\n\
+                               literal, locale, shell, shell-always,\n\
+                               shell-escape, shell-escape-always, c, escape\n\
+                               (overrides QUOTING_STYLE environment variable)\n\
+"), stdout);
+      fputs (_("\
+  -r, --reverse              reverse order while sorting\n\
+  -R, --recursive            list subdirectories recursively\n\
+  -s, --size                 print the allocated size of each file, in blocks\n\
+"), stdout);
+      fputs (_("\
+  -S                         sort by file size, largest first\n\
+      --sort=WORD            sort by WORD instead of name: none (-U), size (-S)\
+,\n\
+                               time (-t), version (-v), extension (-X)\n\
+      --time=WORD            change the default of using modification times;\n\
+                               access time (-u): atime, access, use;\n\
+                               change time (-c): ctime, status;\n\
+                               birth time: birth, creation;\n\
+                             with -l, WORD determines which time to show;\n\
+                             with --sort=time, sort by WORD (newest first)\n\
+"), stdout);
+      fputs (_("\
+      --time-style=TIME_STYLE  time/date format with -l; see TIME_STYLE below\n\
+"), stdout);
+      fputs (_("\
+  -t                         sort by time, newest first; see --time\n\
+  -T, --tabsize=COLS         assume tab stops at each COLS instead of 8\n\
+"), stdout);
+      fputs (_("\
+  -u                         with -lt: sort by, and show, access time;\n\
+                               with -l: show access time and sort by name;\n\
+                               otherwise: sort by access time, newest first\n\
+  -U                         do not sort; list entries in directory order\n\
+  -v                         natural sort of (version) numbers within text\n\
+"), stdout);
+      fputs (_("\
+  -w, --width=COLS           set output width to COLS.  0 means no limit\n\
+  -x                         list entries by lines instead of by columns\n\
+  -X                         sort alphabetically by entry extension\n\
+  -Z, --context              print any security context of each file\n\
+  -1                         list one file per line.  Avoid '\\n' with -q or -b\
+\n\
+"), stdout);
+      fputs (HELP_OPTION_DESCRIPTION, stdout);
+      fputs (VERSION_OPTION_DESCRIPTION, stdout);
+      emit_size_note ();
+      fputs (_("\
+\n\
+The TIME_STYLE argument can be full-iso, long-iso, iso, locale, or +FORMAT.\n\
+FORMAT is interpreted like in date(1).  If FORMAT is FORMAT1<newline>FORMAT2,\n\
+then FORMAT1 applies to non-recent files and FORMAT2 to recent files.\n\
+TIME_STYLE prefixed with 'posix-' takes effect only outside the POSIX locale.\n\
+Also the TIME_STYLE environment variable sets the default style to use.\n\
+"), stdout);
+      fputs (_("\
+\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\
+Exit status:\n\
+ 0  if OK,\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_ancillary_info (PROGRAM_NAME);
+    }
+  exit (status);
+}
Index: create-8.32-syscall64-ls-patch/coreutils-8.32-new/src
===================================================================
--- create-8.32-syscall64-ls-patch/coreutils-8.32-new/src	(nonexistent)
+++ create-8.32-syscall64-ls-patch/coreutils-8.32-new/src	(revision 5)

Property changes on: create-8.32-syscall64-ls-patch/coreutils-8.32-new/src
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-8.32-syscall64-ls-patch/coreutils-8.32-new
===================================================================
--- create-8.32-syscall64-ls-patch/coreutils-8.32-new	(nonexistent)
+++ create-8.32-syscall64-ls-patch/coreutils-8.32-new	(revision 5)

Property changes on: create-8.32-syscall64-ls-patch/coreutils-8.32-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-8.32-syscall64-ls-patch/create.patch.sh
===================================================================
--- create-8.32-syscall64-ls-patch/create.patch.sh	(nonexistent)
+++ create-8.32-syscall64-ls-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=8.32
+
+tar --files-from=file.list -xJvf ../coreutils-$VERSION.tar.xz
+mv coreutils-$VERSION coreutils-$VERSION-orig
+
+cp -rf ./coreutils-$VERSION-new ./coreutils-$VERSION
+
+diff --unified -Nr  coreutils-$VERSION-orig  coreutils-$VERSION > coreutils-$VERSION-syscall64-ls.patch
+
+mv coreutils-$VERSION-syscall64-ls.patch ../patches
+
+rm -rf ./coreutils-$VERSION
+rm -rf ./coreutils-$VERSION-orig

Property changes on: create-8.32-syscall64-ls-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: create-8.32-syscall64-ls-patch/file.list
===================================================================
--- create-8.32-syscall64-ls-patch/file.list	(nonexistent)
+++ create-8.32-syscall64-ls-patch/file.list	(revision 5)
@@ -0,0 +1 @@
+coreutils-8.32/src/ls.c
Index: create-8.32-syscall64-ls-patch
===================================================================
--- create-8.32-syscall64-ls-patch	(nonexistent)
+++ create-8.32-syscall64-ls-patch	(revision 5)

Property changes on: create-8.32-syscall64-ls-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-8.32-uname-patch/coreutils-8.32-new/src/uname.c
===================================================================
--- create-8.32-uname-patch/coreutils-8.32-new/src/uname.c	(nonexistent)
+++ create-8.32-uname-patch/coreutils-8.32-new/src/uname.c	(revision 5)
@@ -0,0 +1,489 @@
+/* uname -- print system information
+
+   Copyright (C) 1989-2020 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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
+
+#include <config.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <getopt.h>
+
+#if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
+# include <sys/systeminfo.h>
+#endif
+
+#if HAVE_SYS_SYSCTL_H && ! defined __GLIBC__
+# if HAVE_SYS_PARAM_H
+#  include <sys/param.h> /* needed for OpenBSD 3.0 */
+# endif
+# include <sys/sysctl.h>
+# ifdef HW_MODEL
+#  ifdef HW_MACHINE_ARCH
+/* E.g., FreeBSD 4.5, NetBSD 1.5.2 */
+#   define UNAME_HARDWARE_PLATFORM HW_MODEL
+#   define UNAME_PROCESSOR HW_MACHINE_ARCH
+#  else
+/* E.g., OpenBSD 3.0 */
+#   define UNAME_PROCESSOR HW_MODEL
+#  endif
+# endif
+#endif
+
+#ifdef __APPLE__
+# include <mach/machine.h>
+# include <mach-o/arch.h>
+#endif
+
+#if defined (__linux__)
+# define USE_PROCINFO
+# define UNAME_HARDWARE_PLATFORM
+#endif
+
+#include "system.h"
+#include "die.h"
+#include "error.h"
+#include "quote.h"
+#include "uname.h"
+
+/* The official name of this program (e.g., no 'g' prefix).  */
+#define PROGRAM_NAME (uname_mode == UNAME_UNAME ? "uname" : "arch")
+
+#define AUTHORS proper_name ("David MacKenzie")
+#define ARCH_AUTHORS "David MacKenzie", "Karel Zak"
+
+/* Values that are bitwise or'd into 'toprint'. */
+/* Kernel name. */
+#define PRINT_KERNEL_NAME 1
+
+/* Node name on a communications network. */
+#define PRINT_NODENAME 2
+
+/* Kernel release. */
+#define PRINT_KERNEL_RELEASE 4
+
+/* Kernel version. */
+#define PRINT_KERNEL_VERSION 8
+
+/* Machine hardware name. */
+#define PRINT_MACHINE 16
+
+/* Processor type. */
+#define PRINT_PROCESSOR 32
+
+/* Hardware platform.  */
+#define PRINT_HARDWARE_PLATFORM 64
+
+/* Operating system.  */
+#define PRINT_OPERATING_SYSTEM 128
+
+static struct option const uname_long_options[] =
+{
+  {"all", no_argument, NULL, 'a'},
+  {"kernel-name", no_argument, NULL, 's'},
+  {"sysname", no_argument, NULL, 's'},	/* Obsolescent.  */
+  {"nodename", no_argument, NULL, 'n'},
+  {"kernel-release", no_argument, NULL, 'r'},
+  {"release", no_argument, NULL, 'r'},  /* Obsolescent.  */
+  {"kernel-version", no_argument, NULL, 'v'},
+  {"machine", no_argument, NULL, 'm'},
+  {"processor", no_argument, NULL, 'p'},
+  {"hardware-platform", no_argument, NULL, 'i'},
+  {"operating-system", no_argument, NULL, 'o'},
+  {GETOPT_HELP_OPTION_DECL},
+  {GETOPT_VERSION_OPTION_DECL},
+  {NULL, 0, NULL, 0}
+};
+
+static struct option const arch_long_options[] =
+{
+  {GETOPT_HELP_OPTION_DECL},
+  {GETOPT_VERSION_OPTION_DECL},
+  {NULL, 0, NULL, 0}
+};
+
+void
+usage (int status)
+{
+  if (status != EXIT_SUCCESS)
+    emit_try_help ();
+  else
+    {
+      printf (_("Usage: %s [OPTION]...\n"), program_name);
+
+      if (uname_mode == UNAME_UNAME)
+        {
+          fputs (_("\
+Print certain system information.  With no OPTION, same as -s.\n\
+\n\
+  -a, --all                print all information, in the following order,\n\
+                             except omit -p and -i if unknown:\n\
+  -s, --kernel-name        print the kernel name\n\
+  -n, --nodename           print the network node hostname\n\
+  -r, --kernel-release     print the kernel release\n\
+"), stdout);
+          fputs (_("\
+  -v, --kernel-version     print the kernel version\n\
+  -m, --machine            print the machine hardware name\n\
+  -p, --processor          print the processor type (non-portable)\n\
+  -i, --hardware-platform  print the hardware platform (non-portable)\n\
+  -o, --operating-system   print the operating system\n\
+"), stdout);
+        }
+      else
+        {
+          fputs (_("\
+Print machine architecture.\n\
+\n\
+"), stdout);
+        }
+
+      fputs (HELP_OPTION_DESCRIPTION, stdout);
+      fputs (VERSION_OPTION_DESCRIPTION, stdout);
+      emit_ancillary_info (PROGRAM_NAME);
+    }
+  exit (status);
+}
+
+#if defined(USE_PROCINFO)
+
+# if defined(__s390__) || defined(__s390x__)
+#  define CPUINFO_FILE    "/proc/sysinfo"
+#  define CPUINFO_FORMAT  "%64[^\t :]%*[ :]%256[^\n]%c"
+# else
+#  define CPUINFO_FILE    "/proc/cpuinfo"
+#  define CPUINFO_FORMAT  "%64[^\t:]\t:%256[^\n]%c"
+# endif
+
+# define PROCINFO_PROCESSOR      0
+# define PROCINFO_HARDWARE_PLATFORM 1
+
+static void __eat_cpuinfo_space(char *buf)
+{
+       /* first eat trailing space */
+       char *tmp = buf + strlen(buf) - 1;
+       while (tmp > buf && isspace(*tmp))
+               *tmp-- = '\0';
+       /* then eat leading space */
+       tmp = buf;
+       while (*tmp && isspace(*tmp))
+               tmp++;
+       if (tmp != buf)
+               memmove(buf, tmp, strlen(tmp)+1);
+}
+
+static int __linux_procinfo (int x, char *fstr, size_t s)
+{
+       FILE *fp;
+
+       char *procinfo_keys[] = {
+               /* --processor --hardware-platform */
+               #if defined(__alpha__)
+                       "cpu model", "system type"
+               #elif defined(__arm__)
+                       "Processor", "Hardware"
+               #elif defined(bfin)
+                       "CPU", "BOARD Name"
+               #elif defined(__cris__)
+                       "cpu", "cpu model"
+               #elif defined(__frv__)
+                       "CPU-Core", "System"
+               #elif defined(__i386__) || defined(__x86_64__)
+                       "model name", "vendor_id"
+               #elif defined(__ia64__)
+                       "family", "vendor"
+               #elif defined(__hppa__)
+                       "cpu", "model"
+               #elif defined(__m68k__)
+                       "CPU", "MMU"
+               #elif defined(__mips__)
+                       "cpu model", "system type"
+               #elif defined(__powerpc__) || defined(__powerpc64__)
+                       "cpu", "machine"
+               #elif defined(__s390__) || defined(__s390x__)
+                       "Type", "Manufacturer"
+               #elif defined(__sh__)
+                       "cpu type", "machine"
+               #elif defined(sparc) || defined(__sparc__)
+                       "type", "cpu"
+               #elif defined(__vax__)
+                       "cpu type", "cpu"
+               #else
+                       "unknown", "unknown"
+               #endif
+       };
+
+       if ((fp = fopen(CPUINFO_FILE, "r")) != NULL) {
+               char key[65], value[257], eol, *ret = NULL;
+
+               while (fscanf(fp, CPUINFO_FORMAT, key, value, &eol) != EOF) {
+                       __eat_cpuinfo_space(key);
+                       if (!strcmp(key, procinfo_keys[x])) {
+                               __eat_cpuinfo_space(value);
+                               ret = value;
+                               break;
+                       }
+                       if (eol != '\n') {
+                               /* we need two fscanf's here in case the previous
+                                * length limit caused us to read right up to the
+                                * newline ... doing "%*[^\n]\n" wont eat the newline
+                                */
+                               fscanf(fp, "%*[^\n]");
+                               fscanf(fp, "\n");
+                       }
+               }
+               fclose(fp);
+
+               if (ret) {
+                       strncpy(fstr, ret, s);
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+#endif
+
+/* Print ELEMENT, preceded by a space if something has already been
+   printed.  */
+
+static void
+print_element (char const *element)
+{
+  static bool printed;
+  if (printed)
+    putchar (' ');
+  printed = true;
+  fputs (element, stdout);
+}
+
+
+/* Set all the option flags according to the switches specified.
+   Return the mask indicating which elements to print.  */
+
+static int
+decode_switches (int argc, char **argv)
+{
+  int c;
+  unsigned int toprint = 0;
+
+  if (uname_mode == UNAME_ARCH)
+    {
+      while ((c = getopt_long (argc, argv, "",
+                               arch_long_options, NULL)) != -1)
+        {
+          switch (c)
+            {
+            case_GETOPT_HELP_CHAR;
+
+            case_GETOPT_VERSION_CHAR (PROGRAM_NAME, ARCH_AUTHORS);
+
+            default:
+              usage (EXIT_FAILURE);
+            }
+        }
+      toprint = PRINT_MACHINE;
+    }
+  else
+    {
+      while ((c = getopt_long (argc, argv, "asnrvmpio",
+                               uname_long_options, NULL)) != -1)
+        {
+          switch (c)
+            {
+            case 'a':
+              toprint = UINT_MAX;
+              break;
+
+            case 's':
+              toprint |= PRINT_KERNEL_NAME;
+              break;
+
+            case 'n':
+              toprint |= PRINT_NODENAME;
+              break;
+
+            case 'r':
+              toprint |= PRINT_KERNEL_RELEASE;
+              break;
+
+            case 'v':
+              toprint |= PRINT_KERNEL_VERSION;
+              break;
+
+            case 'm':
+              toprint |= PRINT_MACHINE;
+              break;
+
+            case 'p':
+              toprint |= PRINT_PROCESSOR;
+              break;
+
+            case 'i':
+              toprint |= PRINT_HARDWARE_PLATFORM;
+              break;
+
+            case 'o':
+              toprint |= PRINT_OPERATING_SYSTEM;
+              break;
+
+            case_GETOPT_HELP_CHAR;
+
+            case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+            default:
+              usage (EXIT_FAILURE);
+            }
+        }
+    }
+
+  if (argc != optind)
+    {
+      error (0, 0, _("extra operand %s"), quote (argv[optind]));
+      usage (EXIT_FAILURE);
+    }
+
+  return toprint;
+}
+
+int
+main (int argc, char **argv)
+{
+  static char const unknown[] = "unknown";
+
+  /* Mask indicating which elements to print. */
+  unsigned int toprint = 0;
+
+  initialize_main (&argc, &argv);
+  set_program_name (argv[0]);
+  setlocale (LC_ALL, "");
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
+  atexit (close_stdout);
+
+  toprint = decode_switches (argc, argv);
+
+  if (toprint == 0)
+    toprint = PRINT_KERNEL_NAME;
+
+  if (toprint
+       & (PRINT_KERNEL_NAME | PRINT_NODENAME | PRINT_KERNEL_RELEASE
+          | PRINT_KERNEL_VERSION | PRINT_MACHINE))
+    {
+      struct utsname name;
+
+      if (uname (&name) == -1)
+        die (EXIT_FAILURE, errno, _("cannot get system name"));
+
+      if (toprint & PRINT_KERNEL_NAME)
+        print_element (name.sysname);
+      if (toprint & PRINT_NODENAME)
+        print_element (name.nodename);
+      if (toprint & PRINT_KERNEL_RELEASE)
+        print_element (name.release);
+      if (toprint & PRINT_KERNEL_VERSION)
+        print_element (name.version);
+      if (toprint & PRINT_MACHINE)
+        print_element (name.machine);
+    }
+
+  if (toprint & PRINT_PROCESSOR)
+    {
+      char const *element = unknown;
+#if ( HAVE_SYSINFO && defined SI_ARCHITECTURE ) || defined(USE_PROCINFO)
+      {
+        static char processor[257];
+#if defined(USE_PROCINFO)
+       if (0 <= __linux_procinfo (PROCINFO_PROCESSOR, processor, sizeof processor))
+#else
+        if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
+#endif
+          element = processor;
+      }
+#endif
+#ifdef UNAME_PROCESSOR
+      if (element == unknown)
+        {
+          static char processor[257];
+          size_t s = sizeof processor;
+          static int mib[] = { CTL_HW, UNAME_PROCESSOR };
+          if (sysctl (mib, 2, processor, &s, 0, 0) >= 0)
+            element = processor;
+
+# ifdef __APPLE__
+          /* This kludge works around a bug in Mac OS X.  */
+          if (element == unknown)
+            {
+              cpu_type_t cputype;
+              size_t cs = sizeof cputype;
+              NXArchInfo const *ai;
+              if (sysctlbyname ("hw.cputype", &cputype, &cs, NULL, 0) == 0
+                  && (ai = NXGetArchInfoFromCpuType (cputype,
+                                                     CPU_SUBTYPE_MULTIPLE))
+                  != NULL)
+                element = ai->name;
+
+              /* Hack "safely" around the ppc vs. powerpc return value. */
+              if (cputype == CPU_TYPE_POWERPC
+                  && STRNCMP_LIT (element, "ppc") == 0)
+                element = "powerpc";
+            }
+# endif
+        }
+#endif
+      if (! (toprint == UINT_MAX && element == unknown))
+        print_element (element);
+    }
+
+  if (toprint & PRINT_HARDWARE_PLATFORM)
+    {
+      char const *element = unknown;
+#if HAVE_SYSINFO && defined SI_PLATFORM
+      {
+        static char hardware_platform[257];
+        if (0 <= sysinfo (SI_PLATFORM,
+                          hardware_platform, sizeof hardware_platform))
+          element = hardware_platform;
+      }
+#endif
+#ifdef UNAME_HARDWARE_PLATFORM
+      if (element == unknown)
+        {
+          static char hardware_platform[257];
+#if defined(USE_PROCINFO)
+         if (0 <= __linux_procinfo (PROCINFO_HARDWARE_PLATFORM, hardware_platform, sizeof hardware_platform))
+#else
+          size_t s = sizeof hardware_platform;
+          static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };
+          if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)
+#endif
+            element = hardware_platform;
+        }
+#endif
+      if (! (toprint == UINT_MAX && element == unknown))
+        print_element (element);
+    }
+
+  if (toprint & PRINT_OPERATING_SYSTEM)
+    print_element (HOST_OPERATING_SYSTEM);
+
+  putchar ('\n');
+
+  return EXIT_SUCCESS;
+}
Index: create-8.32-uname-patch/coreutils-8.32-new/src
===================================================================
--- create-8.32-uname-patch/coreutils-8.32-new/src	(nonexistent)
+++ create-8.32-uname-patch/coreutils-8.32-new/src	(revision 5)

Property changes on: create-8.32-uname-patch/coreutils-8.32-new/src
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-8.32-uname-patch/coreutils-8.32-new
===================================================================
--- create-8.32-uname-patch/coreutils-8.32-new	(nonexistent)
+++ create-8.32-uname-patch/coreutils-8.32-new	(revision 5)

Property changes on: create-8.32-uname-patch/coreutils-8.32-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-8.32-uname-patch/create.patch.sh
===================================================================
--- create-8.32-uname-patch/create.patch.sh	(nonexistent)
+++ create-8.32-uname-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=8.32
+
+tar --files-from=file.list -xJvf ../coreutils-$VERSION.tar.xz
+mv coreutils-$VERSION coreutils-$VERSION-orig
+
+cp -rf ./coreutils-$VERSION-new ./coreutils-$VERSION
+
+diff --unified -Nr  coreutils-$VERSION-orig  coreutils-$VERSION > coreutils-$VERSION-uname.patch
+
+mv coreutils-$VERSION-uname.patch ../patches
+
+rm -rf ./coreutils-$VERSION
+rm -rf ./coreutils-$VERSION-orig

Property changes on: create-8.32-uname-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: create-8.32-uname-patch/file.list
===================================================================
--- create-8.32-uname-patch/file.list	(nonexistent)
+++ create-8.32-uname-patch/file.list	(revision 5)
@@ -0,0 +1 @@
+coreutils-8.32/src/uname.c
Index: create-8.32-uname-patch
===================================================================
--- create-8.32-uname-patch	(nonexistent)
+++ create-8.32-uname-patch	(revision 5)

Property changes on: create-8.32-uname-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: patches/README
===================================================================
--- patches/README	(nonexistent)
+++ patches/README	(revision 5)
@@ -0,0 +1,6 @@
+
+/* begin *
+
+   coreutils-8.32-syscall64-ls.patch - should be applied before coreutils-8.32-no-ls-quoting.patch
+
+ * end */
Index: patches
===================================================================
--- patches	(nonexistent)
+++ patches	(revision 5)

Property changes on: patches
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: .
===================================================================
--- .	(nonexistent)
+++ .	(revision 5)

Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~