Compare commits

...

148 Commits
v7.5 ... v8.0

Author SHA1 Message Date
Jim Meyering
ca1e31f3c5 version 8.0
* NEWS: Record release date.
2009-10-06 13:04:16 +02:00
Jim Meyering
3c40fdfba6 build: update gnulib submodule to latest 2009-10-06 11:15:54 +02:00
Ondřej Vašík
3a97d664b9 chcon: exit immediately if SELinux is disabled
This change happens to avoid an abort in chcon when SELinux is
disabled while operating on a file with an "unlabeled" context from
back in 2006.  However, that same abort can still be triggered by the
same file when running chcon with SELinux enabled.  This bug in chcon
will be fixed in a subsequent commit via a getfilecon wrapper.  See
http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/18378/focus=18384
for how to correct your disk attributes to avoid triggering this bug.
* src/chcon.c (main): Exit immediately if SELinux is disabled.
Reported in http://bugzilla.redhat.com/527142 by Yanko Kaneti.
* src/runcon.c (main): Do not hardcode program name in error message.
* THANKS: Update.
2009-10-06 10:10:51 +02:00
Jim Meyering
addb62da92 build: update gnulib submodule to latest 2009-10-03 06:56:55 +02:00
James R. Van Zandt
569df689e3 dircolors: highlight .cgm and .emf as images
* src/dircolors.hin: Add .cgm, .emf.
* THANKS: Update.
2009-10-02 10:58:05 -06:00
Jim Meyering
df0c0381ab maint: remove obsolete syntax-check exclusion
* cfg.mk (local-checks-to-skip): Remove strftime-check.
2009-10-02 15:48:08 +02:00
Pádraig Brady
f8726e05c4 tail: avoid a race where we could miss new data with --pid
* src/tail.c (tail_forever, tail_forever_inotify): Close a race in
tail_forever_inotify where new data written after the file check by
a now dead process, but before the pid check, is not output.  We use
the POSIX guarantee that read() and write() are serialized wrt each
other even in separate processes, to assume full file consistency
after exit() and so poll for new data _after_ the writer has exited.
This also allows us to not redundantly _wait_ for new data if the
process is dead.
* tests/tail-2/pid: Remove the now partially invalid sub second sleep
check as we now don't unconditionally wait, and replace it with a check
for the redundant sleep.  Also clarify some of the existing comments.
* NEWS: Mention the fix.
2009-10-02 14:00:06 +01:00
Jim Meyering
95c01c656e maint: move gnu-web-doc-update script to gnulib
* bootstrap.conf (gnulib_modules): Add gnu-web-doc-update.
Remove gendocs, since gnu-web-doc-update depends on it.
* gnu-web-doc-update: Remove file, now that we get it from gnulib.
2009-10-02 12:10:21 +02:00
Jim Meyering
8a7f66feb4 build: update gnulib submodule to latest 2009-10-02 12:10:21 +02:00
Jim Meyering
30a227673e tests: tail-2/pid: use a 3-second timeout, not 1
* tests/tail-2/pid: When using the timeout program to ensuring that
tail -s.1 --pid=$PID_T_MAX does not wait forever, use a timeout longer
than 1 second.  A 1-second timeout could be too short on a very busy
system, and result in a timeout, and hence false-positive failure.

2009-09-30  Jim Meyering  <meyering@redhat.com>
2009-09-30 23:28:13 +02:00
Jim Meyering
dd8db19cc7 build: update gnulib submodule to latest 2009-09-30 17:46:42 +02:00
Jim Meyering
569e387b8a build: translate diagnostics from two new files
* po/POTFILES.in: Add two new files: lib/siglist.h, lib/strsignal.c
2009-09-30 17:04:29 +02:00
Jim Meyering
9ca7d6b49e build: now that we use the lock module, don't exclude lock.m4
* bootstrap.conf: Don't exclude lock.m4.
2009-09-30 17:04:29 +02:00
Pádraig Brady
d4c7114bce ls: always print "?" for allocated size of a dereferenced dangling symlink
Previously for `ls -Ls` (but not `ls -Lsl`), we referenced
the st_blocks returned from the previous failed stat() call.
This undefined value was seen to be 0 for dangling symlinks at least.
* src/ls.c (print_file_name_and_frills, length_of_file_name_and_frills):
Don't use st_blocks if the previous stat() failed
* tests/ls/dangle: Add a test case
* NEWS: Mention the fix, and roll up related items into a single entry.
2009-09-30 15:42:35 +01:00
Jim Meyering
ce1069c215 build: use gnulib's freopen module
* bootstrap.conf (gnulib_modules): Add freopen, strsignal, fsync.
Exposed via make CFLAGS=-DGNULIB_POSIXCHECK 2>&1 \
|perl -lne '/.* use gnulib module (\S+).*/ and print $1' \
|sort |uniq -c|sort -nr
(avoided_gnulib_modules): Don't avoid the "lock" module.
Now it's required, as a dependency of the strsignal module.
2009-09-30 09:39:48 +02:00
Jim Meyering
a033e28737 stat: interpret "-" as standard input
* src/stat.c (do_stat): Interpret a command line argument of "-"
to mean "standard input", like many other tools do.
(do_statfs): Fail upon any attempt to use "-".
* NEWS (Changes in behavior): Mention it.
* tests/misc/stat-hyphen: New test, to exercise the above.
* tests/Makefile.am (TESTS): Add misc/stat-hyphen.
2009-09-29 16:04:12 +02:00
Jim Meyering
b7aaa0da8b ls: don't use an undefined struct stat after failed stat/lstat
* src/ls.c (format_inode): Access f->stat only if f->stat_ok is set.
* NEWS (Bug fixes): Mention it.
Improved-by: Pádraig Brady <P@draigBrady.com>
2009-09-29 14:12:30 +02:00
Jim Meyering
36edf7bad2 ls: print "?", not "0" as inode of dereferenced dangling symlink
ls prints inode numbers two ways: for long (-l) listings,
and for short ones, e.g., ls -li and ls -i.  The code to print
long listings properly printed "?" when the inode was unknown,
but the code for handling short listings would print 0 instead.
Factor out the formatting code into a new function so ls prints
the right string ("?") from both places:
* NEWS (Bug fixes): Mention it.
* src/ls.c (format_inode): New function.
(print_long_format): Use it here.
(print_file_name_and_frills): Use it here, too.
* tests/ls/dangle: Exercise this fix.
Reported by Yang Ren in http://bugzilla.redhat.com/525400
2009-09-29 11:42:45 +02:00
Jim Meyering
242689c7f9 ls: with -LR, exit with status 2 upon detecting a cycle
* src/ls.c (print_dir): Diagnosing the cycle is not enough.
Also set exit status to 2.  This is what Solaris' /bin/ls does, too.
* tests/ls/infloop: Rework test: match both expected stdout and stderr.
Require an exit status of 2 in this case.
* doc/coreutils.texi (ls invocation): Mention that a loop provokes
in an exit status of 2.
* NEWS (Bug fixes): Mention it.
Reported by Yang Ren in http://bugzilla.redhat.com/525402.
* THANKS: Correct ordering of Yang Ren's names.
2009-09-29 07:28:39 +02:00
Jim Meyering
30c65cd49c maint: factor coreutils-specific code out of bootstrap
* bootstrap (bootstrap_epilogue): Define a default, empty function.
Remove coreutils-specific code, and instead,
invoke this new function at the end of this script.
* bootstrap.conf (bootstrap_epilogue): Define, to override the default.
2009-09-26 14:45:50 +02:00
Eric Blake
ca9e212cf8 cp, mv: use linkat to guarantee semantics
* src/copy.c (copy_internal): Use linkat, not link.
2009-09-25 07:03:36 -06:00
Eric Blake
efcee783e4 ln: add -L/-P options
* src/ln.c (STAT_LIKE_LINK): Delete.
(logical): New flag.
(long_options): Add -L, -P.
(usage): Mention them.
(main): Choose between them.
(do_link): Perform correct action.
* tests/ln/misc: Move hard-to-sym portion of test...
* tests/ln/hard-to-sym: ...into new test, and add more.
* tests/Makefile.am (TESTS): Run new test.
* NEWS: Document this.
* doc/coreutils.texi (link invocation, ln invocation): Likewise.
* bootstrap.conf (gnulib_modules): Add linkat.
2009-09-25 07:03:03 -06:00
Eric Blake
fb59d72f0a build: update gnulib submodule to latest 2009-09-24 19:40:31 -06:00
Pádraig Brady
a037e838e1 maint: Use logical rather than bitwise operators on bools
This is because bitwise operators are:
- confusing and inconsistent in a boolean context
- non short circuiting
- brittle in C89 where bool can be an int (so > 1)
2009-09-23 14:33:40 +01:00
Pádraig Brady
ade8dd2096 maint: expr: avoid compiler warnings without GMP
* src/expr.c (mpz_clear, mpz_get_str, mpz_out_str)
[!HAVE_GMP]: Reference unused arguments.
2009-09-23 14:32:07 +01:00
Eric Blake
0cce690850 build: update gnulib submodule to latest 2009-09-23 06:47:46 -06:00
Eric Blake
82124c3c06 maint: summarize gnulib changes
* NEWS: Provide a blurb about recent gnulib improvements.  Fix typo
in readlink blurb.
2009-09-23 06:45:07 -06:00
Jim Meyering
38f1c2006e doc: ls: further improve --help message re --color
* src/ls.c (usage): Correct grammar, change voice, shorten.
Inspired by a report from Bruno Schulenberg.
2009-09-23 09:11:08 +02:00
Eric Blake
8a1edc971f readlink: pick up gnulib changes to readlink -f
* bootstrap.conf (obsolete_gnulib_modules): Move rename...
(gnulib_modules): ...here.  Add symlink.
* NEWS: Document the change in readlink.
* doc/coreutils.texi (readlink invocation): Likewise.
* tests/readlink/can-f: Update test to new semantics, and add test
of loop.
2009-09-23 08:45:08 +02:00
Jim Meyering
70253e9179 maint: df.c: adapt to newer gnulib
* src/df.c: Don't include "canonicalize.h".  No longer needed,
since canonicalize_file_name is now guaranteed to be declared
in <stdlib.h>, thanks to gnulib.
2009-09-23 08:38:00 +02:00
Jim Meyering
b18b6912e8 build: update gnulib submodule to latest 2009-09-23 08:37:59 +02:00
Pádraig Brady
fbfca3c675 doc: stdbuf: mention it can have a non standard exit status
* doc/coreutils.texi (Exit status): Add stdbuf to the list
2009-09-22 12:22:47 +01:00
Pádraig Brady
7a404d10f5 maint: uptime: fix a theoretical compile warning
* src/uptime.c (print_uptime) [!HAVE_UTMPX_H && !HAVE_UTMP_H]:
Reference possibly unused arguments.
2009-09-22 12:21:00 +01:00
Pádraig Brady
8c92bb3441 ls: fix a performance regression
* src/ls.c (print_color_indicator): This reinstates commit f3f1ccfd,
21-10-2008, "ls: make it possible to disable file capabilities checking"
which was inadvertently reverted with commit 3a169f4c, 14-09-2009,
"ls: handle disabling of colors consistently ...".
2009-09-22 10:07:21 +01:00
Eric Blake
32f987af12 build: avoid compiler warnings on cygwin 1.5
* src/copy.c (utimens_symlink): Avoid unused variables.
* src/su.c (getusershell): Rely on gnulib for prototype.
2009-09-21 20:42:16 -06:00
Jim Meyering
fee8694886 doc: ls: add an article, "the"
* src/ls.c (usage): Tweak wording.
2009-09-21 15:30:38 +02:00
Pádraig Brady
3a169f4c5d ls: handle disabling of colors consistently for all tile types
* src/ls.c (print_color_indicator): Use consistent syntax for
all file and directory subtypes, and fall back to the color
of the base type if there is no enabled color for the subtype.
This allows turning off specific colors for o+w dirs for example.
* tests/ls/color-dtype-dir: Add a case to test that turning off
coloring for o+w directories, falls back to standard dir color.
* NEWS: Mention the fix
Introduced by commit ac467814, 2005-09-05,
"Colorize set-user-ID ... files and sticky ... directories."
2009-09-21 13:16:44 +01:00
Pádraig Brady
29ec834c3b doc: ls: make help for --color more concise and accurate
* src/ls.c (usage): Shorten the --color ancillary info by
two lines, while replacing --color=none with --color=never.
Mention "always" is the default parameter of the --color option,
along with the primary help for that option.
Mention the ancillary --color info in the --color primary help.
2009-09-21 12:44:35 +01:00
Pádraig Brady
9837344837 doc: normalize and add missing entries to texinfo menu
* doc/coreutils.texi: Add the missing arch, base64, link, readlink,
and unlink entries.  Also remove extraneous '.' from some entries
and try to align all entries on the same column.
* THANKS: Add Benno Schulenberg.
2009-09-21 12:42:19 +01:00
Pádraig Brady
5d4f09d83a doc: mention the texinfo documentation in --help
* src/system.h: Rename emit_bug_reporting_address() to
emit_ancillary_info() and update it to not print the translation
project address in en_* locales, and _do_ print it in the 'C'
(and other) locales so that it's included in the default man page.
Also mention how to invoke the texinfo documentation for each command.
Also move the "hard-locale.h" include to the 8 files that now use it.
* man/help2man: Strip the newly added texinfo reference from the
--help output as a more verbose version is already added by help2man.
Suggestion from C de-Avillez
2009-09-21 12:37:57 +01:00
Jim Meyering
c48003a53c maint: automate the web-doc updating procedure
* gnu-web-doc-update: New script, destined for gnulib.
* README-release: Refer to the new script.
2009-09-21 08:56:17 +02:00
Jim Meyering
a2883947bc dircolors: arrange to highlight names with the .lz suffix
* src/dircolors.hin: Add .lz, for GNU lzip.
Suggested by Matias A. Fonzo.
2009-09-19 12:26:41 +02:00
Jim Meyering
99f59aaaf8 mktemp: adapt to new, 3-argument gen_tempname_len
* src/mktemp.c (mkstemp_len, mkdtemp_len): Update callers of
gen_tempname_len.
* gl/lib/tempname.c, gl/lib/tempname.h: Rebase against recently
API-modified copy of tempname module in gnulib.
Reported by Lluís Batlle.
2009-09-19 11:16:56 +02:00
Jim Meyering
6504d7e193 build: merge bootstrap changes from gnulib
* bootstrap: Update from gnulib.
2009-09-17 14:30:01 +02:00
Eric Blake
2bad8c0dea rm, rmdir: improve cross-compilation support
* bootstrap.conf (gnulib_modules): Drop rmdir-errno.
* src/rmdir.c (errno_rmdir_non_empty): Check both cases allowed by
POSIX, rather than relying on configure-time check that might
fail during cross-compilation.  Reverts commit 9b6eb98d41.
2009-09-16 21:26:58 -06:00
Ondřej Vašík
fe6f4e305c cp: fix a probably redundant chmod when setting xattrs
* src/copy.c (copy_reg): Fix initial value of access_changed variable.
This was introduced by Pádraig Brady in commit cca83faf, 2009-09-14,
"cp,mv: preserve extended attributes even for read-only files"
2009-09-15 10:51:13 +01:00
Jim Meyering
a77fb35364 doc: NEWS: mention origin of touch -t ....60 bug
* NEWS: It is an old bug.
2009-09-14 15:57:13 +02:00
Jim Meyering
94eca76776 doc: touch, document that it accepts .60
* doc/coreutils.texi (touch invocation): Document that SS may be 60.
2009-09-14 15:37:26 +02:00
Jim Meyering
20761ce686 touch: don't reject "60" as number of seconds in a legacy time stamp
A valid command like "touch -t 197101010000.60 F" would fail due
to the suffix of ".60".  This bug is fixed via the latest change
to gnulib's posixtm module.
* tests/touch/60-seconds: New test.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Bug fixes): Mention it.
2009-09-14 15:27:51 +02:00
Jim Meyering
df84346ebc build: update gnulib submodule to latest, for fixed posixtm module 2009-09-14 15:27:51 +02:00
Jim Meyering
71bac0dac3 maint: use #!/bin/sh consistently in shell-based test scripts
* tests/misc/sort-continue: Change first line to standard #!/bin/sh,
not #!/bin/bash (though it doesn't matter, since each is invoked
via $(SHELL) dir/test-name.
2009-09-14 15:27:02 +02:00
Pádraig Brady
d41dbb187f tests: fix dd/skip-seek-past-file to work on ecryptfs
* tests/dd/skip-seek-past-file: Require sparse support
to ensure that when we're checking if we can create an
$OFF_T_MAX length file, that we don't actually allocate
any space.  This was an issue on ecryptfs and was reported
by Bert Wesarg.
2009-09-14 14:22:02 +01:00
Ondřej Vašík
cca83fafa6 cp,mv: preserve extended attributes even for read-only files
* src/copy.c (copy_reg): Temporarily set u+rw on the destination file
to allow GNU/Linux to set xattrs.
* tests/misc/xattr: Test that change.
* NEWS (Bug fixes): Mention it.
Reported by Ernest N. Mamikonyan.
2009-09-14 14:19:03 +01:00
Jim Meyering
eb1299481a doc: improve timeout's --help message
* src/timeout.c (usage): Improve --help description.
2009-09-14 09:18:30 +02:00
Jim Meyering
255a6a201e maint: use consistent cpp indentation in all .c files
* src/stty.c: Make cpp indentation reflect nesting.
* src/factor.c: Likewise.
2009-09-13 22:05:37 +02:00
Jim Meyering
f6f78f093b doc: NEWS: say quadratic and linear, rather than O(N^2) and O(N)
* NEWS: Use a slightly less technical description.
Suggested by Andreas Schwab.
2009-09-13 12:11:57 +02:00
Jim Meyering
21b617b78b doc: improve NEWS
* NEWS (rm -r, without -f): Mention that the N in "O(N)" represents
hierarchy depth.  Suggested by Ralf Wildenhues.
(rm -r, standards conformance): Make wording more accurate.
2009-09-13 11:58:48 +02:00
Jim Meyering
ebbf0a1f0f id: don't print context=... when POSIXLY_CORRECT is set
* src/id.c (print_full_info) [POSIXLY_CORRECT]: Don't print context.
Reported by Ulrich Drepper.
* NEWS (Changes in behavior): Mention it.
* doc/coreutils.texi (id invocation): Document that id also prints the
security context, when possible, and when POSIXLY_CORRECT is not set.
* tests/id/no-context: New file.  Test for this.
* tests/Makefile.am (TESTS): Add it.
2009-09-11 19:58:18 +02:00
Eric Blake
398749b0cc rm: avoid compiler warning
* src/remove.c (rm_fts): Don't allow fall-through when assertions
are disabled.
2009-09-11 14:08:58 +02:00
Eric Blake
e5dba03d2f euidaccess-stat: remove unnecessary macros
* lib/euidaccess-stat.c (F_OK, R_OK, W_OK, X_OK): Delete; now
guaranteed by gnulib.
2009-09-11 14:08:58 +02:00
Eric Blake
c756343503 rm: use gnulib faccessat
* bootstrap.conf (gnulib_modules): Add faccessat.  Replace strdup
with strdup-posix.
* m4/jm-macros.m4 (coreutils_MACROS): Revert previous change, now
that gnulib does it for us.
* src/remove.c (write_protected_non_symlink): Use faccessat in
more situations.
2009-09-11 14:08:58 +02:00
Jim Meyering
722287e443 rm: improve efficiency of rm -r (without -f) from O(N^2) to O(N)
where N is the depth of the deepest hierarchy rm is processing.
* src/remove.c (write_protected_non_symlink): Use faccessat to
avoid O(N)-per-entry cost of calling euidaccess.
* m4/jm-macros.m4 (coreutils_MACROS): Check for faccessat.
* NEWS (Improvements): Mention it.
2009-09-11 14:08:58 +02:00
Jim Meyering
9966c92dd4 build: placate gcc's new -Wskip-jump-init
* remove.c (rm_fts): Put braces around each of the two offending blocks.
* configure.ac: Don't turn off -Wjump-misses-init.
With the rewrite of remove.c, it is no longer needed.
2009-09-11 14:08:58 +02:00
Jim Meyering
4f73ecaf7d rm: rewrite to use fts
* remove.c: Don't include "unlinkdir.h"; no longer used.
Do not include <setjmp.h> or "cycle-check.h".  Likewise.
Include "xfts.h".
(dir_name, dir_len): Remove definitions.
(CONSECUTIVE_READDIR_UNLINK_THRESHOLD): Likewise.
(INODE_SORT_DIR_ENTRIES_THRESHOLD, NEED_REWIND, D_TYPE): Likewise.
(struct dirstack_state, Dirstack_state): Likewise.
(g_buf, g_n_allocated): Remove declarations.
(hash_freer, hash_compare_strings, rm_malloc): Remove functions.
(rm_free, push_dir, top_dir, pop_dir, right_justify): Likewise.
(full_filename0, xfull_filename, full_filename_): Likewise.
(AD_stack_height, AD_stack_top, AD_stack_pop, AD_stack_clear): Likewise.
(obstack_init_minimal, ds_init, ds_clear, ds_free): Likewise.
(AD_pop_and_chdir, AD_ensure_initialized, AD_mark_helper): Likewise.
(AD_mark_as_unremovable, AD_mark_current_as_unremovable): Likewise.
(AD_push_initial, AD_push, AD_push, AD_is_removable): Likewise.
(write_protected_non_symlink): Change 3rd parameter from
dirstack_state "ds" to full_name.
(prompt): Adjust parameters.  Now, state comes from FTS/FTSENT pair.
Those replace fd_cwd and "ds".  Remove "filename".  Remove pdirent_type
in favor of new "is_dir" parameter.  Rename is_empty to is_empty_p.
(DO_RMDIR, DO_UNLINK): Remove definitions.
(remove_entry, fd_to_subdirp, compare_ino): Remove functions.
(dirent_count, dirent_inode_sort_may_be_useful): Likewise.
(preprocess_dir): Likewise.
(fts_skip_tree, mark_ancestor_dirs, excise, rm_fts): New functions.
(remove_cwd_entries, remove_dir, rm_1): Remove functions.
(rm): Rewrite as a simple loop calling fts_read and dispatching
each entry via rm_fts.
* src/rm.c (main): Adapt to new signature of rm().
* bootstrap.conf (gnulib_modules): Remove unlinkdir, no longer used.
* src/Makefile.am (sc_tight_scope): Also recognize an extern "enum"
declaration.
* tests/rm/empty-name: Adjust expected output to match new diagnostic.
* NEWS (Improvements): Mention it.
2009-09-11 14:08:51 +02:00
Jim Meyering
880a6e7723 maint: doc: adjust README-release
* README-release: Remove mention of bootstrap's old
--gnulib-srcdir=/gnulib option.  No longer needed, and its
use can lead to subtle problems.
2009-09-11 13:14:07 +02:00
Jim Meyering
bd11475627 post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2009-09-11 08:16:18 +02:00
Jim Meyering
aa2f797c7d version 7.6
* NEWS: Record release date.
2009-09-11 07:53:16 +02:00
Jim Meyering
ebc7aacf7b link,ln: use gnulib's link module to work around Solaris 10 deficiency
Before this change, :>f; ln -T f no-such/ would succeed on Solaris 10.
After it, ln fails, as it should: ln: accessing `z/': Not a directory
The command, link f no-such/, had the same problem on that system.
* bootstrap.conf (gnulib_modules): Add "link".
* tests/ln/slash-decorated-nonexistent-dest: New test.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Portability): Mention the improvement.
2009-09-10 18:52:12 +02:00
Jim Meyering
15223b0c3b build: update gnulib submodule to latest 2009-09-10 16:58:15 +02:00
Ondřej Vašík
b64d9b6d9e doc: improve various BLOCKSIZE and SIZE help
* doc/coreutils.texi (multiplierSuffixes): Mention that
the suffix can be specified without a leading number
* src/split.c (usage): Refactor SIZE help to within a function
* src/truncate.c (usage): Likewise
* src/ls.c (usage): Likewise
* src/df.c (usage): Likewise. Also add a function with BLOCKSIZE help
* src/du.c (usage): Likewise.
* src/system.h: Define 2 functions to emit common help text
This was prompted by https://bugzilla.redhat.com/show_bug.cgi?id=511188
2009-09-10 15:28:50 +01:00
Jim Meyering
0bbb9d7785 dd conv=unblock: print final newline consistently
* src/dd.c (dd_copy) [C_UNBLOCK]: Always print the final newline for
non-empty output, not just when output size is a multiple of cbs.
* doc/coreutils.texi (dd invocation) [conv=unblock]: Mention that dd
prints a newline after each output record, not just when replacing
trailing spaces.
Reported by Ulrich Drepper.
* tests/dd/unblock: New file.  Test for this.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Bug fixes): Mention it.
2009-09-10 12:25:04 +02:00
Jim Meyering
f1e1e89e81 maint: make cfg.mk slightly more generic
* cfg.mk (url_dir_list): Don't hard-code "coreutils".  Use $(PACKAGE).
2009-09-09 16:44:37 +02:00
Jim Meyering
1c0ec3541c * gnulib: Update submodule to latest. 2009-09-08 13:30:38 +02:00
Jim Meyering
f0ff8c73fe tail: make the new piped-stdin test as portable as the old one
* src/tail.c (main): Adapt piped-stdin test to use the same isapipe,
test as was used in the preceding POSIXLY_CORRECT condition.
Remove the now-subsumed POSIXLY_CORRECT test.
Reported by Pádraig Brady.
* doc/coreutils.texi (tail invocation): Document this change.
* NEWS (Changes in behavior): Reclassify, clarify.
2009-09-08 13:30:38 +02:00
Pádraig Brady
e8591fd39f tests: tail-2/assert: reduce risk of race condition
* tests/tail2/assert: This reverts commit be853120, 25-08-2009,
"tests: tail-2/assert: avoid risk of race condition"
kill -0 doesn't send a signal and so will only confirm that the
background process was forked, which we know already because
we have its pid.
2009-09-08 10:01:45 +01:00
Pádraig Brady
a863644397 tests: address a race condition in misc/cat-buf
* tests/misc/cat-buf: Increase the delay between writes
to decrease the chance that dd will read both at once.
Since the test is inherently racy, print a warning via
skip_test_ rather than failing outright.
Reported by Jim Meyering.
2009-09-08 01:43:31 +01:00
Jim Meyering
f6d1f70183 tail: syntax-only: use "false", rather than equivalent, 0
* src/tail.c (record_open_fd): Initialize "->ignore" to false, not 0.
2009-09-07 23:20:01 +02:00
Jim Meyering
af6436559c tail: ignore -f for piped-stdin, as POSIX requires
* src/tail.c (main): Tailing a pipe "forever" is not useful,
and POSIX specifies that tail ignore the -f when there is no
file argument and stdin is a FIFO or pipe.  So we do that.
In addition, GNU tail excludes "-" arguments from the list of files
to tail forever, when the associated file descriptor is connected
to a FIFO or pipe.  Before this change, ":|tail -f" would hang.
Reported by Ren Yang and Ulrich Drepper.
* tests/tail-2/pipe-f: Test for this.
* tests/tail-2/pipe-f2: Ensure tail doesn't exit early for a fifo.
* tests/Makefile.am (TESTS): Add these tests.
* NEWS (POSIX conformance): Mention it.
2009-09-07 23:19:56 +02:00
Pádraig Brady
fd9750b0ff tests: tail-2/flush-initial should not rely on stdbuf
* tests/tail-2/flush-initial: stdbuf is not built on all systems.
In any case it's redundant since stdout will automatically be buffered
since we're redirecting to file. So just call tail without using stdbuf.
2009-09-07 21:52:30 +01:00
Jim Meyering
a8d26b3ce1 tail: don't give up on inotify mode for an already-ignored "-"
* src/tail.c (main): Adjust today's change to honor the
F[i].ignore flag that may have been set in tail_file.
2009-09-07 20:56:38 +02:00
Jim Meyering
a4a864da36 tests: misc/cat-buf: clean up syntax
* tests/misc/cat-buf: Don't suppress dd's stderr.
Remove useless quotes.
2009-09-07 20:23:03 +02:00
Jim Meyering
9547a78bda tests: ls/color-clear-to-eol: append NL to accommodate old sed
* tests/ls/color-clear-to-eol: Some vendor sed programs fail
to operate on lines that are not NL-terminated.
This affects at least Solaris 10's /bin/sed.
Reported by Pádraig Brady.
2009-09-07 19:36:37 +02:00
Jim Meyering
494fed0271 tests: tail-2/infloop-1: avoid rare test failure on a busy system
* tests/tail-2/infloop-1: Sleep 3 seconds, not 1, but in increments
of 0.1 second.  Before, this test would fail ~1 time in 20 via
"make -j9 check" on a quad-core system.
Correct comment.
2009-09-07 13:55:37 +02:00
Jim Meyering
61cc6fbc27 build: update gnulib submodule to latest 2009-09-07 09:23:57 +02:00
Jim Meyering
f68f5f23c6 doc: tweak NEWS
* NEWS (dd): Tweak wording.
Two blank lines between sections.
2009-09-07 09:23:48 +02:00
Jim Meyering
cdfb703c5d tail -f: handle "-"/stdin once again
* src/tail.c (main) [HAVE_INOTIFY]: When stdin (i.e., "-", or no args,
but not /dev/stdin) is specified on the command line, don't use inotify.
Reported by Bill Brelsford in <http://bugs.debian.org/545422>.
* tests/tail-2/follow-stdin: New file.  Test for this.
* tests/Makefile.am (TESTS): Add the test.
* NEWS (Bug fixes): Mention it.
This bug was introduced in coreutils-7.5 via commit ae494d4b,
2009-06-02, "tail: use inotify if it is available".
2009-09-07 09:01:14 +02:00
Jim Meyering
15f26e296b tests: tail-2/flush-initial: correct race avoidance code
* tests/tail-2/flush-initial: Wait for the file to be nonempty,
not for the process.  Based on a suggestion from Pádraig Brady.
2009-09-06 20:00:34 +02:00
Jim Meyering
467cc9bb43 tests: ls-misc: don't let a bogus umask cause test failure
* tests/misc/ls-misc: Set umask to 022.  A umask setting permitting
world-write access, e.g., umask o+w, would cause this test to fail.
Report by Mathias Brodala and analysis by Tom Fitzhenry in
<http://bugs.debian.org/544965>.
2009-09-06 18:40:40 +02:00
Jim Meyering
d54376db68 tail: flush initial output before possibly blocking
* src/tail.c (main): Flush any output from tail_file,
before calling tail_forever_inotify, which can block.
* tests/tail-2/flush-initial: New file.  Test for the bug.
* tests/Makefile.am (TESTS): Add tail-2/flush-initial.
* NEWS (Bug fixes): Mention it.
This bug was introduced in coreutils-7.5 via commit ae494d4b,
2009-06-02, "tail: use inotify if it is available".
2009-09-06 09:40:43 +02:00
Jim Meyering
af054f80b2 maint: remove unused file: lib/fdopendir-glibc.c
* lib/fdopendir-glibc.c: Remove unused file.

2009-09-05  Jim Meyering  <meyering@redhat.com>
2009-09-05 19:52:16 +02:00
Jim Meyering
c392c4b8ef tests: ls/stat-vs-dirent: avoid spurious test failure
* tests/ls/stat-vs-dirent: Avoid test failure when run from a
directory whose name (or ancestor directory name) starts with ".".
2009-09-05 19:06:31 +02:00
Pádraig Brady
471f219ac7 doc: make the tail --sleep-interval help less confusing
* src/tail.c (usage): I read "approximately S seconds"
as "approximately 5 seconds" for approximately 5 seconds.
2009-09-05 17:25:40 +01:00
Pádraig Brady
a5e224d793 maint: remove some tab indentation from copy.c
* src/copy.c (copy_internal): Remove tabs erroneously added
in commit 3346c0af.
2009-09-05 17:22:09 +01:00
Pádraig Brady
526a057602 tests: test old tail -f method even on systems with inotify
* src/tail.c (main): Add an undocumented ---disable-inotify option
to allow disabling inotify.
* tests/tail-2/pid: Run test in both normal and "disable_inotify" modes.
* tests/tail-2/tail-n0f: Likewise.
* tests/tail-2/wait: Likewise.
* tests/tail-2/append-only: Likewise.
2009-09-05 17:19:03 +01:00
Jim Meyering
70eadcb4e6 build: update gnulib submodule to latest 2009-09-05 16:28:24 +02:00
Petr Salinger
305bbd99b2 stty: use TAB0, TAB1, and TAB2 only if defined
* src/stty.c (mode_info) [TAB0, TAB1, TAB2]: Guard each
entry with #ifdef.  Required for GNU/kFreeBSD.
Reported by Petr Salinger in http://bugs.debian.org/520368.
2009-09-05 15:54:26 +02:00
Eric Blake
c45b4237bc build: update from gnulib
* gnulib: Update submodule to latest.
2009-09-04 20:46:01 -06:00
Eric Blake
c692280926 ln: add comments related to POSIX 2008
* src/ln.c (ENABLE_HARD_LINK_TO_SYMLINK_WARNING): Delete.
(do_link): Update comments per POSIX; add FIXME for -L, -P.
2009-09-04 14:54:55 -06:00
Eric Blake
3346c0afbc mv, cp: tweak LINK_FOLLOWS_SYMLINKS logic
* gnulib: Update to latest gnulib.
* src/copy.c (copy_internal): Adjust comment in light of POSIX
2008, and deal with macro now being tri-state.
2009-09-04 14:54:52 -06:00
Petr Salinger
a23afe7b72 tests: fix a tail-2/pid failure on GNU/kFreeBSD
* tests/tail-2/wait: Increase the file name recheck frequency to
fix a failure on systems without inotify and a file timestamp precision
of 1 second (like GNU/kFreeBSD).
2009-09-04 18:14:55 +01:00
Pádraig Brady
82f09f4762 tests: fix a failure when running tail-2/wait as root
* tests/tail-2/wait: Silently skip a portion of the test
when running as root, rather than failing the whole test.
This regression was introduced with commit 84b5844d, 2009-09-03,
"tests: simplify and fix a race in 2 tail --follow tests".
2009-09-04 17:39:26 +01:00
Mike Frysinger
370fa0fa42 build: fix libcap configure flag handling
* m4/jm-macros.m4 (coreutils_MACROS): The code to handle configure-time
enabling or disabling of libcap support was broken.  It would treat any
libcap configure option as --disable-libcap because it doesn't check
$enableval at all.  This change makes sure we do the sane thing:
  --disable-libcap -> disable and don't run any tests
  --enable-libcap -> run tests and fail if not found
  default -> run tests and warn if not found
2009-09-04 08:48:03 +02:00
Jim Meyering
e0e8429c24 df: don't fail due to an unreadable argument
* src/df.c (main): If open or fstat fails when we're trying to ensure
that all arg-partitions are automounted, fall back on using stat.
Inspired by the report and patch from Olivier Fourdan in
http://bugzilla.redhat.com/520630.
* NEWS (Bug fixes): Mention it.
* tests/df/unreadable: New test for the above.
* tests/Makefile.am (TESTS): Add df/unreadable.
The bug was introduced in coreutils-7.3 via commit dbd17157,
2009-04-28, "df: use open(2), not stat, to trigger automounting".
2009-09-03 19:52:47 +02:00
Kamil Dudka
1422cabf93 doc: install -C: fix bug in the texi documentation
* doc/coreutils.texi: Move the documentation for install --compare (-C)
from the section on fmt to that for install.
Reported by Florian Schlichting.
2009-09-03 16:24:14 +02:00
Pádraig Brady
84b5844d21 tests: simplify and fix a race in 2 tail --follow tests
* tests/tail-2/pid: Use the timeout command to determine process
longevity, rather than querying /proc/$pid/status.
The latter was racy in any case when inotify is used, as then
tail wakes up periodically even for unchanging files therefore
causing the check for "S (sleeping)" state to fail intermittently.
* tests/tail-2/wait: Likewise.
2009-09-03 10:08:06 +01:00
Ondřej Vašík
1a94ac4a05 cp: don't leak resources for each xattr preservation failure
* src/copy.c (copy_reg): Don't return from the function after an
unsuccessful and required preservation of extended attributes.
This resulted in leaking the copy buffer and file descriptors.
* NEWS (Bug fixes): Mention the fix.
The bug was introduced in coreutils-7.1 via commit 0889381c, 2009-01-23,
"cp/mv: add xattr support".
2009-09-03 10:00:32 +01:00
Pádraig Brady
1b2d2635ee chcon, chmod, chgrp, chown, du: report fts_close failure
* src/du.c (du_files): Don't fail silently upon fts_close failure.
* src/chcon.c (process_files): Likewise.
* src/chmod.c (process_files): Likewise.
* src/chown-core.c (chown_files): Likewise.
2009-09-01 13:05:06 +02:00
Jim Meyering
fa3e9cb9af build: update from gnulib
* gnulib: Update submodule to latest.
2009-09-01 12:10:07 +02:00
Jim Meyering
228c8e9eec chcon, chmod, chgrp, chown, du: do not ignore fts_close failure
This is probably never visible, but who knows...
* src/chcon.c (process_files): Don't ignore fts_close failure.
* src/chmod.c (process_files): Likewise.
* src/chown-core.c (chown_files): Likewise.
* src/du.c (du_files): Likewise.
2009-09-01 12:10:07 +02:00
Jim Meyering
1ce27f74ec maint: du: remove unnecessary initialization
* src/du.c (main): Don't set "skip_file" unnecessarily.
2009-09-01 12:10:07 +02:00
Jim Meyering
b2c30136dc maint: chown, chgrp, chmod, chcon: remove unnecessary initialization
* src/chown-core.c: Include "ignore-value.h".
(change_file_owner): Don't set "ent" only to ignore it.
* src/chcon.c (process_file): Likewise.
* src/chmod.c: Include "ignore-value.h".
(process_file): Don't set "ent" only to ignore it.
After diagnosing root-dev/ino failure, return false immediately:
Now that we don't set "ent" we must be sure not to use it uninitialized,
and there's no point in issuing --verbose-related output in this case.
2009-09-01 12:10:07 +02:00
Jim Meyering
e3b14643f4 maint: shred: remove unnecessary initialization
* src/shred.c (genpattern): Value stored to "n" is never used.
2009-09-01 12:10:07 +02:00
Jim Meyering
e579a697b2 maint: dd: remove unnecessary initialization
* src/dd.c (skip): Remove set-but-never-used variable, soffset.
2009-09-01 12:10:07 +02:00
Jim Meyering
68c9b31834 maint: tail: remove unnecessary initialization
* src/tail.c (tail_bytes): Don't compute "diff" twice.
2009-09-01 12:10:07 +02:00
Jim Meyering
856ba44297 maint: mbsalign.c: remove unnecessary assignment
* gl/lib/mbsalign.c (mbsalign): Remove assignment, the result of which
is never used.
2009-09-01 12:10:06 +02:00
Pádraig Brady
8f7d8e3bc3 timeout: remove a redundant assignment
* src/timeout.c (main): While keeping argc and argv in
sync may be marginally useful, it is redundant to update argc,
so just remove that to suppress the clang warning.
2009-09-01 11:07:15 +01:00
Pádraig Brady
0b1dcf33f5 timeout: defensive handling of all wait() errors
* src/timeout.c (main): Handle all possible cases of unexpected
failures from wait().  This was prompted by the clang tool reporting
the possible non-initialization of the status variable.
2009-09-01 11:02:18 +01:00
Jim Meyering
a977dbbe78 ls -i: print consistent inode numbers also for mount points
On most unix- and linux-based kernels, ls -i DIR_CONTAINING_MOUNT_POINT
would print the wrong inode number for any entry that is a mount point.
It would do that by relying on readdir's dirent.d_ino values, while
most readdir implementations return the inode number of the underlying,
inaccessible directory.  Thus, it is not consistent with what you'd
get when applying stat to the same entry.  This bug led to surprising
results like "ls -i" and "ls -i --color" printing different numbers (ls
must usually "stat" a file to colorize its name).  This change makes it
so that on offending systems, ls must stat non-command-line-arguments
for which otherwise it would be able to use "for free" dirent.d_ino
values.  Regardless of this change, ls is already required to stat every
command-line argument.  Note: versions of GNU ls prior to coreutils-6.0
did not perform the invalid optimization, and hence always printed
correct inode numbers.  Thus, for the sake of correctness, ls -i is
forgoing the readdir optimization, for any kernel (including linux!)
with POSIX-nonconforming readdir.  Note that currently, only Cygwin has
been agile enough to conform.

* src/ls.c (RELIABLE_D_INO): Define.
(print_dir): Use it.
For plenty of discussion, see this long thread:
http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/14020
This bug was introduced by the 2006-02-26 commit, 33eb3efe:
"In ls, avoid calling stat for --inode (-i), when possible."
* tests/ls/readdir-mountpoint-inode: New test.
* tests/Makefile.am (TESTS): Add it.
* tests/ls/stat-vs-dirent: Don't suppress failure of this test,
now that ls -i is fixed.  Though note that it doesn't test well,
since it compares only the always-stat'd command-line arguments.
* NEWS (Bug fixes): Mention it.
2009-09-01 07:07:45 +02:00
Jim Meyering
a4e123abd3 maint: revert my stdbuf change: the result didn't even compile
This reverts commit c1e158489d.
2009-08-31 09:44:30 +02:00
Jim Meyering
c1e158489d maint: stdbuf: move a declaration; no-semantic-change
* src/stdbuf.c (set_program_path): Move a declaration down into
the scope where it's used.
2009-08-30 22:34:06 +02:00
Jim Meyering
12a104b45e build: quiet "make check" in src/
* src/Makefile.am (check-duplicate-no-install): Use $(AM_V_GEN).
(check-README): Likewise.  And $(AM_V_at).
2009-08-30 12:22:30 +02:00
Jim Meyering
e3ccc324d3 doc: cp: update note on preserving symlink time stamps
* doc/coreutils.texi (cp invocation): Now, we *do* preserve time
stamps on symlinks, when possible.
2009-08-30 12:02:02 +02:00
Jim Meyering
a10ba58f3c build: update bootstrap from gnulib
* bootstrap: Merge from gnulib.
2009-08-30 12:02:02 +02:00
Pádraig Brady
56300b1dc2 tests: don't misbehave if $TMPDIR contains spaces
* tests/misc/xattr: Add quotes.
* tests/mv/acl: Likewise.
* tests/mv/backup-is-src: Likewise.
* tests/mv/hard-link-1: Likewise.
* tests/mv/leak-fd: Likewise.
* tests/mv/mv-special-1: Likewise.
* tests/mv/part-fail: Likewise.
* tests/mv/part-hardlink: Likewise.
* tests/mv/part-rename: Likewise.
* tests/mv/part-symlink: Likewise.
* tests/mv/partition-perm: Likewise.
* tests/mv/sticky-to-xpart: Likewise.
2009-08-30 10:58:13 +01:00
Jim Meyering
0a859a6cb0 tests: other-fs-tmpdir: don't misbehave for quote-unfriendly $TMPDIR
* tests/other-fs-tmpdir: Quote uses of variables that might expand
to strings containing e.g., whitespace.
2009-08-29 19:19:37 +02:00
Jim Meyering
450df0f26d build: update from gnulib
* gnulib: Update submodule to latest.
2009-08-29 17:30:14 +02:00
Jim Meyering
98ec4beba5 tests: move a coreutils-specific test from maint.mk to Makefile.am
* Makefile.am (distcheck-hook): Make taint-distcheck here, since it's
no longer done via maint.mk.
2009-08-29 17:29:45 +02:00
Jim Meyering
6c497c6c2d tests: cp/reflink-auto guard against a pathological $TMPDIR
* tests/cp/reflink-auto: Add quotes.
2009-08-29 17:29:32 +02:00
Pádraig Brady
9e59f8c47c cp --reflink: preserve attributes on cloned files if asked
* src/copy.c (copy_reg): When cloning only skip the data copying
* tests/cp/reflink-perm: New test to check times and modes copied
* tests/Makefile.am: Reference the new test
* NEWS: Mention the fix
2009-08-29 01:37:05 +01:00
Pádraig Brady
72f98388c3 cp --reflink: add an "auto" parameter to fall back to a normal copy
* doc/coreutils.texi (cp invocation): Document the new
"auto" and "always" options to --reflink.
* src/copy.c (copy_reg): Fall back to a standard copy
when reflink() is not supported and --reflink=auto specified.
* src/copy.h [struct cp_options] (reflink): Change type s/bool/enum/.
* src/cp.c (usage): Describe the --reflink={always,auto} options
and expand a little on what --reflink does.
(main): parse the new parameters to --reflink and allow all
--sparse options with --reflink=auto.
* src/install.c (cp_option_init): Init the enum instead of bool.
* src/mv.c (cp_option_init): Likewise.
* tests/cp/reflink-auto: A new test for falling back to normal copy.
* tests/Makefile.am: Reference the new test.
* NEWS: Mention the new feature.
2009-08-29 00:24:49 +01:00
Pádraig Brady
f296cf4052 stdbuf: fix a small typo in --help output
* src/stdbuf.c (usage): s/then/the/
2009-08-28 23:35:48 +01:00
Eric Blake
359fa92f2a build: avoid unused variable warnings on cygwin
* src/copy.c (clone_file, copy_attr_by_fd, copy_attr_by_name):
Mark up unused variables.
* src/remove.c (dirent_inode_sort_may_be_useful): Likewise.
2009-08-28 12:56:53 -06:00
Eric Blake
31fa922e57 dd: detect closed stderr
* src/dd.c (maybe_close_stdout): Always flush stderr; regression
introduced in commit 381e69ea.
* tests/misc/close-stdout (p): Use consistent style.
* tests/dd/stderr: New test, borrowing from misc/close-stdout.
* tests/Makefile.am (TESTS): Run it.
* NEWS: Mention this.
2009-08-28 12:56:51 -06:00
Jim Meyering
59a6ddfca3 maint: ignore only man/*.1, not all *.1 files
* .gitignore: Ignore *.1 only in man/
2009-08-28 14:29:02 +02:00
Jim Meyering
de619c8fa5 build: prefix a few rules with $(AM_V_GEN)
* Makefile.am (.version, dist-hook, gen-ChangeLog): Use $(AM_V_GEN)
and $(AM_V_at), so that automake's silent-rules option (make V=1/V=0)
now controls whether the commands are printed at build time.
(THANKS-to-translators, check-ls-dircolors): Likewise.
2009-08-27 10:18:08 +02:00
Jim Meyering
847359b11d build: stop earlier if touching ChangeLog fails
* bootstrap.conf: Exit right away if touching ChangeLog fails.
Otherwise, the touch failure message is buried under configure output.
2009-08-26 18:21:12 +02:00
Jim Meyering
d6639ee63b tests: mkdir/selinux: avoid spurious failure on some SELinux systems
* tests/test-lib.sh (require_selinux_enforcing_): New function.
* tests/mkdir/selinux: Use it.
Otherwise, this test would fail on Rawhide with SELinux disabled.
2009-08-26 10:06:53 +02:00
Jim Meyering
be8531206b tests: tail-2/assert: avoid risk of race condition
* tests/tail-2/assert: Avoid spurious failure due to race condition.
Rather than sleeping for 1 second and crossing fingers,
wait explicitly for backgrounded tail process to start.
Otherwise, this test would fail under heavy load.
2009-08-26 09:25:21 +02:00
Jim Meyering
899c1d00fa maint: ensure we don't embed Emacs indent-tabs-mode setting lines
Now that we prohibit indentation via TABs, there's no need for
Emacs indent-tabs-mode setting lines, so prohibit those, too.
* cfg.mk (sc_prohibit_emacs__indent_tabs_mode__setting): New rule.
2009-08-25 09:21:00 +02:00
Jim Meyering
e2808a3999 maint: remove Local Variables: indent-tabs-mode: nil from all sources
* src/getlimits.c: Likewise.
* src/group-list.c: Likewise.
* src/groups.c: Likewise.
* src/mktemp.c: Likewise.
* src/setuidgid.c: Likewise.
* src/stdbuf.c: Likewise.
* src/timeout.c: Likewise.
* src/truncate.c: Likewise.
* gl/lib/mbsalign.c: Likewise.
* tests/test-lib.sh: Likewise.
* bootstrap: Likewise.
* README-hacking: Likewise.
2009-08-25 09:21:00 +02:00
Jim Meyering
ddfcccce51 doc: HACKING: mention the new space-only indentation policy 2009-08-25 09:21:00 +02:00
Jim Meyering
1130e181ee maint: teach "make syntax-check" the space-only indentation rule
* cfg.mk (sc_prohibit_tab_based_indentation): New rule.
* .x-sc_prohibit_tab_based_indentation: New file.
* Makefile.am (syntax_check_exceptions): Add file,
.x-sc_prohibit_tab_based_indentation.
2009-08-25 09:21:00 +02:00
Jim Meyering
5e778f7c8d global: convert indentation-TABs to spaces
Transformed via this shell code:
t=$'\t'
git ls-files \
  | grep -vE '(^|/)((GNU)?[Mm]akefile|ChangeLog)|\.(am|mk)$' \
  | grep -vE 'tests/pr/|help2man' \
  | xargs grep -lE "^ *$t" \
  | xargs perl -MText::Tabs -ni -le \
    '$m=/^( *\t[ \t]*)(.*)/; print $m ? expand($1) . $2 : $_'
2009-08-25 09:21:00 +02:00
Jim Meyering
2bc0f3caaa cp: ignore obscure failure to preserve symlink time stamps,
...when run on a kernel older than what was implied by headers and
libraries tested at configure time.
* src/copy.c (utimens_symlink): Ignore failure when errno == ENOSYS.
* NEWS (Bug fixes): Mention it.
Reported by Todd Zullinger and Kamil Dudka.
Details in this thread:
http://thread.gmane.org/gmane.linux.redhat.fedora.devel/119834
2009-08-24 12:44:13 +02:00
Jim Meyering
831acb987e tests: skip (don't fail) a cp test, upon mount-related failure
* tests/cp/cp-mv-enotsup-xattr: Upon a set-up failiure, rather than
failing the test with a "framework failure" diagnostic, just skip it.
Russell Whitaker reported that this test failed on slackware.
2009-08-23 22:05:58 +02:00
Jim Meyering
1d651b954f build: update from *public* gnulib
* gnulib: Update submodule to latest.
Kamil Dudka reported that bootstrap was broken.
2009-08-23 10:13:36 +02:00
Jim Meyering
99e607b910 build: update from gnulib
* gnulib: Update submodule to latest.
2009-08-22 16:12:26 +02:00
Jim Meyering
04a31ad99d post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2009-08-20 21:48:45 +02:00
248 changed files with 20834 additions and 21122 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,3 @@
*.1
*.I[12]
*.[EIOX]
*.o
@@ -57,6 +56,7 @@ lib/uniwidth
m4/.cvsignore
m4/.gitignore
maint.mk
man/*.1
po/*.gmo
po/*.po
po/.gitignore

4
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "gnulib"]
path = gnulib
url = git://git.sv.gnu.org/gnulib.git
path = gnulib
url = git://git.sv.gnu.org/gnulib.git

View File

@@ -1 +1 @@
7.4
7.6

View File

@@ -0,0 +1,6 @@
^GNUMakefile$
Makefile\.am$
\.mk$
^tests/pr/
ChangeLog.*
^man/help2man$

33
HACKING
View File

@@ -233,21 +233,26 @@ Try to make the summary line fit one of the following forms:
maint: change-description
Use SPACE-only indentation in new files.
========================================
In any new file, eliminate all leading TABs (e.g., via running GNU indent
with --no-tabs) and put these lines at the end of the file:
Use SPACE-only indentation in all[*] files
==========================================
We use space-only indentation in nearly all files.
If you use Emacs and your coreutils working directory name matches,
this code enables the right mode:
;; In coreutils, indent with spaces everywhere (not TABs).
;; Exceptions: Makefile and ChangeLog modes.
(add-hook 'find-file-hook '(lambda ()
(if (and buffer-file-name
(string-match "/coreutils\\>" (buffer-file-name))
(not (string-equal mode-name "Change Log"))
(not (string-equal mode-name "Makefile")))
(setq indent-tabs-mode nil))))
[*] Makefile and ChangeLog files are exempt, of course.
[FIXME: suggest vim syntax to do same thing, if it can be done safely.
Most distros now "set nomodeline" by default for a good reason. ]
/*
* Local variables:
* indent-tabs-mode: nil
* End:
*/
Do not change TABs to spaces or vice versa in any existing file.
Send patches to the address listed in --help output
===================================================
@@ -437,8 +442,8 @@ Miscellaneous useful git commands
its SHA1 and then tag it or cherry-pick it onto an existing branch.
For example, run this:
git fsck --lost-found HEAD && cd .git/lost-found/commit \
&& for i in *; do git show $i|grep SOME_IDENTIFYING_STRING \
&& echo $i; done
&& for i in *; do git show $i|grep SOME_IDENTIFYING_STRING \
&& echo $i; done
The "git fsck ..." command creates the .git/lost-found/... hierarchy
listing all unreachable objects. Then the for loop
print SHA1s for commits that match via log or patch.

View File

@@ -49,6 +49,7 @@ syntax_check_exceptions = \
.x-sc_prohibit_atoi_atof \
.x-sc_prohibit_stat_st_blocks \
.x-sc_prohibit_strcmp \
.x-sc_prohibit_tab_based_indentation \
.x-sc_require_config_h \
.x-sc_require_config_h_first \
.x-sc_space_tab \
@@ -97,20 +98,20 @@ rm_subst = \
BUILT_SOURCES = .version
.version:
echo $(VERSION) > $@-t && mv $@-t $@
$(AM_V_GEN)echo $(VERSION) > $@-t && mv $@-t $@
# Arrange so that .tarball-version appears only in the distribution
# tarball, and never in a checked-out repository.
# The perl substitution is to change some key uses of "rm" to "/bin/rm".
# See the rm_subst comment for details.
dist-hook: gen-ChangeLog
echo $(VERSION) > $(distdir)/.tarball-version
perl -pi -e '$(rm_subst)' $(distdir)/src/Makefile.in
$(AM_V_GEN)echo $(VERSION) > $(distdir)/.tarball-version
$(AM_V_at)perl -pi -e '$(rm_subst)' $(distdir)/src/Makefile.in
gen_start_date = 2008-02-08
.PHONY: gen-ChangeLog
gen-ChangeLog:
if test -d .git; then \
$(AM_V_GEN)if test -d .git; then \
$(top_srcdir)/build-aux/gitlog-to-changelog \
--since=$(gen_start_date) > $(distdir)/cl-t; \
rm -f $(distdir)/ChangeLog; \
@@ -120,11 +121,12 @@ gen-ChangeLog:
ALL_RECURSIVE_TARGETS += distcheck-hook
distcheck-hook: check-ls-dircolors
$(MAKE) my-distcheck
$(MAKE) taint-distcheck
DISTCLEANFILES = VERSION
MAINTAINERCLEANFILES = THANKS-to-translators
THANKS-to-translators: po/LINGUAS THANKStt.in
( \
$(AM_V_GEN)( \
cat $(srcdir)/THANKStt.in; \
for lang in `cat $(srcdir)/po/LINGUAS`; do \
echo http://translationproject.org/team/$$lang.html; \
@@ -135,7 +137,7 @@ THANKS-to-translators: po/LINGUAS THANKStt.in
# remain in sync.
.PHONY: check-ls-dircolors
check-ls-dircolors:
dc=$$(sed -n '/static.*ls_codes\[/,/};'/p \
$(AM_V_GEN)dc=$$(sed -n '/static.*ls_codes\[/,/};'/p \
$(srcdir)/src/dircolors.c \
|sed -n '/^ *"/p'|tr , '\n'|sed 's/^ *//' \
|sed -n 's/^"\(..\)"/\1/p'|sort -u); \

141
NEWS
View File

@@ -1,5 +1,146 @@
GNU coreutils NEWS -*- outline -*-
* Noteworthy changes in release 8.0 (2009-10-06) [beta]
** Bug fixes
cp --preserve=xattr and --archive now preserve extended attributes even
when the source file doesn't have write access.
[bug introduced in coreutils-7.1]
touch -t [[CC]YY]MMDDhhmm[.ss] now accepts a timestamp string ending in .60,
to accommodate leap seconds.
[the bug dates back to the initial implementation]
ls --color now reverts to the color of a base file type consistently
when the color of a more specific type is disabled.
[bug introduced in coreutils-5.90]
ls -LR exits with status 2, not 0, when it encounters a cycle
ls -is is now consistent with ls -lis in ignoring values returned
from a failed stat/lstat. For example ls -Lis now prints "?", not "0",
for the inode number and allocated size of a dereferenced dangling symlink.
tail --follow --pid now avoids a race condition where data written
just before the process dies might not have been output by tail.
Also, tail no longer delays at all when the specified pid is not live.
[The race was introduced in coreutils-7.5,
and the unnecessary delay was present since textutils-1.22o]
** Portability
On Solaris 9, many commands would mistakenly treat file/ the same as
file. Now, even on such a system, path resolution obeys the POSIX
rules that a trailing slash ensures that the preceeding name is a
directory or a symlink to a directory.
** Changes in behavior
id no longer prints SELinux " context=..." when the POSIXLY_CORRECT
environment variable is set.
readlink -f now ignores a trailing slash when deciding if the
last component (possibly via a dangling symlink) can be created,
since mkdir will succeed in that case.
** New features
ln now accepts the options --logical (-L) and --physical (-P),
added by POSIX 2008. The default behavior is -P on systems like
GNU/Linux where link(2) creates hard links to symlinks, and -L on
BSD systems where link(2) follows symlinks.
stat: without -f, a command-line argument of "-" now means standard input.
With --file-system (-f), an argument of "-" is now rejected.
If you really must operate on a file named "-", specify it as
"./-" or use "--" to separate options from arguments.
** Improvements
rm: rewrite to use gnulib's fts
This makes rm -rf significantly faster (400-500%) in some pathological
cases, and slightly slower (20%) in at least one pathological case.
rm -r deletes deep hierarchies more efficiently. Before, execution time
was quadratic in the depth of the hierarchy, now it is merely linear.
However, this improvement is not as pronounced as might be expected for
very deep trees, because prior to this change, for any relative name
length longer than 8KiB, rm -r would sacrifice official conformance to
avoid the disproportionate quadratic performance penalty. Leading to
another improvement:
rm -r is now slightly more standards-conformant when operating on
write-protected files with relative names longer than 8KiB.
* Noteworthy changes in release 7.6 (2009-09-11) [stable]
** Bug fixes
cp, mv now ignore failure to preserve a symlink time stamp, when it is
due to their running on a kernel older than what was implied by headers
and libraries tested at configure time.
[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

View File

@@ -64,7 +64,3 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Local Variables:
indent-tabs-mode: nil
End:

View File

@@ -14,8 +14,7 @@ Here are most of the steps we (maintainers) follow when making a release.
* Make sure your local gnulib directory is up to date.
* Run bootstrap, (assuming your local copy of gnulib is in /gnulib):
./bootstrap --gnulib-srcdir=/gnulib
* Run bootstrap: ./bootstrap
FIXME: enable excluded programs like arch? to get their manual pages?
@@ -82,17 +81,8 @@ Once all the builds and tests have passed,
Then go here to approve it:
https://savannah.gnu.org/news/approve.php?group=coreutils
* For non-alpha releases, update the on-line manual at
* After each non-alpha release, update the on-line manual accessible via
http://www.gnu.org/software/coreutils/manual/
Run `make web-manual', then copy the contents of doc/manual
into a CVS checkout of the coreutils manual repository.
Also edit coreutils.html (FIXME? why?) before doing a CVS commit.
CVS_RSH=ssh \
cvs -d:ext:$USER@cvs.savannah.gnu.org:/web/coreutils co coreutils
Be sure to "cvs add -ko" any files that "cvs status" marks with "?".
That is necessary whenever a new texinfo node is added. Each becomes
a new file in html_node that must then be "cvs add"ed.
by running the gnu-web-doc-update script.

13
THANKS
View File

@@ -66,8 +66,9 @@ Barry Kelly http://barrkel.blogspot.com/
Bauke Jan Douma bjdouma@xs4all.nl
Ben Elliston bje@air.net.au
Ben Harris bjh21@netbsd.org
Benjamin Cutler cutlerbc@simla.colostate.edu
Bengt Martensson bengt@mathematik.uni-Bremen.de
Benjamin Cutler cutlerbc@simla.colostate.edu
Benno Schulenberg bensberg@justemail.net
Bernard Giroud bernard.giroud@creditlyonnais.ch
Bernd Eckenfels ecki@debian.org
Bernd Leibing bernd.leibing@rz.uni-ulm.de
@@ -78,6 +79,7 @@ Bernhard Rosenkraenzer bero@redhat.de
Bernhard Voelker bernhard.voelker@siemens-enterprise.com
Bert Deknuydt Bert.Deknuydt@esat.kuleuven.ac.be
Bert Wesarg bert.wesarg@googlemail.com
Bill Brelsford wb@k2di.net
Bill Peters peters@gaffel.as.arizona.edu
Bjorn Helgaas helgaas@rsn.hp.com
Bob McCracken kerouac@ravenet.com
@@ -185,6 +187,7 @@ Felix Rauch Valenti frauch@cse.unsw.edu.au
Ferdinand fw@scenic.mine.nu
Fletcher Mattox fletcher@cs.utexas.edu
Florent Bayle florent@sarcelle.net
Florian Schlichting fschlich@cis.fu-berlin.de
Florin Iucha fiucha@hsys.mic.ro
Francesco Montorsi fr_m@hotmail.com
François Pinard pinard@iro.umontreal.ca
@@ -249,6 +252,7 @@ James Antill jmanti%essex.ac.uk@seralph21.essex.ac.uk
James Lemley James.Lemley@acxiom.com
James Hunt jamesodhunt@hotmail.com
James Ralston ralston@pobox.com
James R. Van Zandt jrvz@comcast.net
James Sneeringer jvs@ocslink.com
James Tanis jtt@soscorp.com
James Youngman jay@gnu.org
@@ -332,6 +336,7 @@ Leah Q eequor@earthlink.net
Lehti Rami rammer@cs.tut.fi
Leonard N. Zubkoff lnz@dandelion.com
Leonardo Milano lmilano@udel.edu
Lluís Batlle viriketo@gmail.com
Lorne Baker lbaker@nitro.avint.net
Luke Hassell lukehassell@yahoo.com
Luke Kendall lukekendall@optushome.com.au
@@ -370,6 +375,7 @@ Marty Leisner leisner@sdsp.mc.xerox.com
Masami Takikawa takikawm@CS.ORST.EDU
Mate Wierdl mw@moni.msci.memphis.edu
Matej Vela mvela@public.srce.hr
Matias A. Fonzo selk@dragora.org
Matt Kraai kraai@ftbfs.org
Matt Perry matt@primefactor.com
Matt Pham mattvpham@gmail.com
@@ -385,6 +391,7 @@ Matthew Swift swift@alum.mit.edu
Matthew Woehlke mw_triad@users.sourceforge.net
Matthias Urlichs smurf@noris.de
Matti Aarnio matti.aarnio@zmailer.org
Mathias Brodala info@noctus.net
Mattias Wadenstein maswan@acc.umu.se
Max Chang maxchang@ucla.edu
Meelis Roos mroos@tartu.cyber.ee
@@ -439,6 +446,7 @@ Olatunji Oluwabukunmi Ruwase tjruwase@stanford.edu
Olav Morkrid olav@funcom.com
Ole Laursen olau@hardworking.dk
Oliver Kiddle okiddle@yahoo.co.uk
Olivier Fourdan ofourdan@redhat.com
Ørn E. Hansen oehansen@daimi.aau.dk
Oskar Liljeblad osk@hem.passagen.se
Otavio Salvador otavio@ossystems.com.br
@@ -486,6 +494,7 @@ Ralph Loader loader@maths.ox.ac.uk
Raul Miller moth@magenta.com
Raúl Núñez de Arenas Coronado raul@pleyades.net
Reuben Thomas rrt@sc3d.org
Yang Ren ryang@redhat.com
Richard A Downing richard.downing@bcs.org.uk
Richard Braakman dark@xs4all.nl
Richard Dawe rich@phekda.freeserve.co.uk
@@ -560,6 +569,7 @@ Tim Waugh twaugh@redhat
Tobias Stoeckmann tobias@bugol.de
Toby Peterson toby@opendarwin.org
Todd A. Jacobs tjacobs@codegnome.org
Tom Fitzhenry tom@tom-fitzhenry.me.uk
Tom Haynes thomas@netapp.com
Tom Quinn trq@dionysos.thphys.ox.ac.uk
Tomas Pospisek tpo@sourcepole.ch
@@ -602,6 +612,7 @@ Wis Macomson wis.macomson@intel.com
Wojciech Purczynski cliph@isec.pl
Wolfram Kleff kleff@cs.uni-bonn.de
Won-kyu Park wkpark@chem.skku.ac.kr
Yanko Kaneti yaneti@declera.com
Yann Dirson dirson@debian.org
Zvi Har'El rl@math.technion.ac.il

View File

@@ -34,7 +34,7 @@ bt_regex=`echo "$bt"| sed 's/\./[.]/g'`
bt2=${bt}2
usage() {
echo >&2 "\
cat <<EOF
Usage: $0 [OPTION]...
Bootstrap this package from the checked-out sources.
@@ -56,7 +56,7 @@ For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
are honored.
Running without arguments will suffice in most cases.
"
EOF
}
# Configuration.
@@ -70,6 +70,9 @@ gnulib_modules=
# Any gnulib files needed that are not in modules.
gnulib_files=
# A function to be called after everything else in this script.
bootstrap_epilogue() { :; }
# The command to download all .po files for a specified domain into
# a specified directory. Fill in the first %s is the domain name, and
# the second with the destination directory. Use rsync's -L and -r
@@ -148,6 +151,45 @@ copy=false
# on which version control system (if any) is used in the source directory.
vc_ignore=auto
# find_tool ENVVAR NAMES...
# -------------------------
# Search for a required program. Use the value of ENVVAR, if set,
# otherwise find the first of the NAMES that can be run (i.e.,
# supports --version). If found, set ENVVAR to the program name,
# die otherwise.
find_tool ()
{
# Find sha1sum, named gsha1sum on MacPorts.
find_tool_envvar=$1
shift
find_tool_names=$@
eval "find_tool_res=\$$find_tool_envvar"
if test x"$find_tool_res" = x; then
for i
do
if ($i --version </dev/null) >/dev/null 2>&1; then
find_tool_res=$i
break
fi
done
else
find_tool_error_prefix="\$$find_tool_envvar: "
fi
if test x"$find_tool_res" = x; then
echo >&2 "$0: one of these is required: $find_tool_names"
exit 1
fi
($find_tool_res --version </dev/null) >/dev/null 2>&1 || {
echo >&2 "$0: ${find_tool_error_prefix}cannot run $find_tool_res --version"
exit 1
}
eval "$find_tool_envvar=\$find_tool_res"
eval "export $find_tool_envvar"
}
# Find sha1sum, named gsha1sum on MacPorts.
find_tool SHA1SUM sha1sum gsha1sum
# Override the default configuration, if necessary.
# Make sure that bootstrap.conf is sourced from the current directory
# if we were invoked as "sh bootstrap".
@@ -420,11 +462,11 @@ update_po_files() {
cksum_file="$ref_po_dir/$po.s1"
if ! test -f "$cksum_file" ||
! test -f "$po_dir/$po.po" ||
! ${SHA1SUM-sha1sum} -c --status "$cksum_file" \
! $SHA1SUM -c --status "$cksum_file" \
< "$new_po" > /dev/null; then
echo "updated $po_dir/$po.po..."
cp "$new_po" "$po_dir/$po.po" \
&& ${SHA1SUM-sha1sum} < "$new_po" > "$cksum_file"
&& $SHA1SUM < "$new_po" > "$cksum_file"
fi
done
}
@@ -690,6 +732,10 @@ find "$m4_base" "$source_base" \
# Reconfigure, getting other files.
# Skip autoheader if it's not needed.
grep '^[ ]*AC_CONFIG_HEADERS\>' configure.ac >/dev/null ||
AUTOHEADER=true
for command in \
libtool \
"${ACLOCAL-aclocal} --force -I m4" \
@@ -758,14 +804,6 @@ if test $with_gettext = yes; then
fi
fi
# Horrible, coreutils-specific kludges.
# Change paths in gnulib-tests/gnulib.mk from "../.." to "..".
m=gnulib-tests/gnulib.mk
sed 's,\.\./\.\.,..,g' $m > $m-t
mv -f $m-t $m
bootstrap_epilogue
echo "$0: done. Now you can run './configure'."
# Local Variables:
# indent-tabs-mode: nil
# End:

View File

@@ -20,7 +20,6 @@
avoided_gnulib_modules='
--avoid=canonicalize-lgpl
--avoid=dummy
--avoid=lock
'
# These modules are obsolete and can probably be removed soon,
@@ -31,7 +30,6 @@ obsolete_gnulib_modules='
memcpy
memmove
memset
rename
strcspn
strtod
strtol
@@ -78,6 +76,7 @@ gnulib_modules="
euidaccess
exclude
exitfail
faccessat
fchdir
fcntl
fcntl-safer
@@ -90,12 +89,13 @@ gnulib_modules="
fnmatch-gnu
fopen-safer
fprintftime
freopen
fseeko
fsusage
fsync
ftello
ftruncate
fts
gendocs
getdate
getgroups
gethrxtime
@@ -113,6 +113,7 @@ gnulib_modules="
git-version-gen
gitlog-to-changelog
gnu-make
gnu-web-doc-update
gnumakefile
gnupload
group-member
@@ -130,7 +131,9 @@ gnulib_modules="
lchown
lib-ignore
linebuffer
link
link-follow
linkat
long-options
lstat
maintainer-makefile
@@ -175,9 +178,9 @@ gnulib_modules="
readutmp
realloc
regex
rename
rename-dest-slash
rmdir
rmdir-errno
root-dev-ino
rpmatch
safe-read
@@ -196,19 +199,20 @@ gnulib_modules="
stdlib-safer
stpcpy
stpncpy
strdup
strdup-posix
strftime
strpbrk
strsignal
strtoimax
strtoumax
strverscmp
symlink
sys_stat
timespec
tzset
unicodeio
unistd-safer
unlink-busy
unlinkdir
unlocked-io
update-copyright
uptime
@@ -290,7 +294,6 @@ if test $gettext_external = 1; then
m4/glibc2.m4
m4/intdiv0.m4
m4/lcmessage.m4
m4/lock.m4
m4/uintmax_t.m4
m4/ulonglong.m4
m4/visibility.m4
@@ -316,4 +319,12 @@ tar -
"
# Automake requires that ChangeLog exist.
touch ChangeLog
touch ChangeLog || exit 1
bootstrap_epilogue()
{
# Change paths in gnulib-tests/gnulib.mk from "../.." to "..".
m=gnulib-tests/gnulib.mk
sed 's,\.\./\.\.,..,g' $m > $m-t
mv -f $m-t $m
}

View File

@@ -27,20 +27,20 @@ use Time::Local;
use strict;
use vars qw($list_types %messages %options @batch_list $batch_cmd
$no_recurse $explain_type $find_mode $short_print
$no_cvsignore $nolinks $file $single_filename $curr_dir
@common_ignores $ignore_rx %entries %subdirs %removed);
$no_recurse $explain_type $find_mode $short_print
$no_cvsignore $nolinks $file $single_filename $curr_dir
@common_ignores $ignore_rx %entries %subdirs %removed);
use constant SUBDIR_FOUND => 1;
use constant SUBDIR_CVS => 2;
# This list comes from the CVS manual.
use constant STANDARD_IGNORES =>
('RCS', 'SCCS', 'CVS', 'CVS.adm', 'RCSLOG', 'cvslog.*', 'tags',
'TAGS', '.make.state', '.nse_depinfo', '*~', '#*', '.#*', ',*',
"_\$*", "*\$", '*.old', '*.bak', '*.BAK', '*.orig', '*.rej',
'.del-*', '*.a', '*.olb', '*.o', '*.obj', '*.so', '*.exe',
'*.Z', '*.elc', '*.ln', 'core');
('RCS', 'SCCS', 'CVS', 'CVS.adm', 'RCSLOG', 'cvslog.*', 'tags',
'TAGS', '.make.state', '.nse_depinfo', '*~', '#*', '.#*', ',*',
"_\$*", "*\$", '*.old', '*.bak', '*.BAK', '*.orig', '*.rej',
'.del-*', '*.a', '*.olb', '*.o', '*.obj', '*.so', '*.exe',
'*.Z', '*.elc', '*.ln', 'core');
# 3-letter month names in POSIX locale, for fast date decoding
my %months = (
@@ -62,20 +62,20 @@ my %months = (
sub usage ()
{
print "Usage:\n" .
" cvsu [OPTIONS] [FILE] ...\n" .
"Options:\n" .
" --local Disable recursion\n" .
" --explain Verbosely print status of files\n" .
" --find Emulate find - filenames only\n" .
" --short Don't print paths\n" .
" --ignore Don't read .cvsignore\n" .
" --messages List known file types and long messages\n" .
" --nolinks Disable recognizing hard and soft links\n" .
" --types=[^]LIST Print only file types [not] from LIST\n" .
" --batch=COMMAND Execute this command on files\n" .
" --help Print this usage information\n" .
" --version Print version number\n" .
"Abbreviations and short options are supported\n";
" cvsu [OPTIONS] [FILE] ...\n" .
"Options:\n" .
" --local Disable recursion\n" .
" --explain Verbosely print status of files\n" .
" --find Emulate find - filenames only\n" .
" --short Don't print paths\n" .
" --ignore Don't read .cvsignore\n" .
" --messages List known file types and long messages\n" .
" --nolinks Disable recognizing hard and soft links\n" .
" --types=[^]LIST Print only file types [not] from LIST\n" .
" --batch=COMMAND Execute this command on files\n" .
" --help Print this usage information\n" .
" --version Print version number\n" .
"Abbreviations and short options are supported\n";
exit 0;
}
@@ -90,11 +90,11 @@ sub version ()
sub adjust_types ()
{
if ($list_types =~ m{^\^(.*)$}) {
$list_types = "";
foreach (keys %messages) {
$list_types .= $_
if (index ($1, $_) < 0);
}
$list_types = "";
foreach (keys %messages) {
$list_types .= $_
if (index ($1, $_) < 0);
}
}
}
@@ -104,12 +104,12 @@ sub list_messages ()
my $default_mark;
print "Recognizable file types are:\n";
foreach (sort keys %messages) {
if (index($list_types, $_) >= 0) {
$default_mark = "*";
} else {
$default_mark = " ";
}
print " $default_mark $_ $messages{$_}\n";
if (index($list_types, $_) >= 0) {
$default_mark = "*";
} else {
$default_mark = " ";
}
print " $default_mark $_ $messages{$_}\n";
}
print "* indicates file types listed by default\n";
exit 0;
@@ -124,28 +124,28 @@ sub init_ignores ()
push @common_ignores, STANDARD_IGNORES;
unless (defined($HOME)) {
return;
return;
}
my $home_cvsignore = "${HOME}/.cvsignore";
if (-f "$home_cvsignore") {
unless (open (CVSIGNORE, "< $home_cvsignore")) {
error ("couldn't open $home_cvsignore: $!");
}
unless (open (CVSIGNORE, "< $home_cvsignore")) {
error ("couldn't open $home_cvsignore: $!");
}
while (<CVSIGNORE>) {
push (@common_ignores, split);
}
while (<CVSIGNORE>) {
push (@common_ignores, split);
}
close (CVSIGNORE);
close (CVSIGNORE);
}
my $CVSIGNOREENV = $ENV{"CVSIGNORE"};
unless (defined($CVSIGNOREENV)) {
return;
return;
}
my @ignores_var = split (/ /, $CVSIGNOREENV);
@@ -157,15 +157,15 @@ sub init_ignores ()
# Newline is added at the end.
sub error ($)
{
print STDERR "cvsu: ERROR: " . shift(@_) . "\n";
exit 1;
print STDERR "cvsu: ERROR: " . shift(@_) . "\n";
exit 1;
}
# execute commands from @exec_list with $exec_cmd
sub do_batch ()
{
my @cmd_list = split (' ', $batch_cmd);
system (@cmd_list, @batch_list);
my @cmd_list = split (' ', $batch_cmd);
system (@cmd_list, @batch_list);
}
# print files status
@@ -177,34 +177,34 @@ sub file_status ($)
my $pathfile;
return
if $ignore_rx ne '' && $type =~ /[?SLD]/ && $file =~ /$ignore_rx/;
if $ignore_rx ne '' && $type =~ /[?SLD]/ && $file =~ /$ignore_rx/;
return
if (index($list_types, $type) < 0);
if (index($list_types, $type) < 0);
$pathfile = $curr_dir . $file;
if (defined($batch_cmd)) {
push (@batch_list, $pathfile);
# 1000 items in the command line might be too much for HP-UX
if ($#batch_list > 1000) {
do_batch();
undef @batch_list;
}
push (@batch_list, $pathfile);
# 1000 items in the command line might be too much for HP-UX
if ($#batch_list > 1000) {
do_batch();
undef @batch_list;
}
}
if ($short_print) {
$item = $file;
$item = $file;
} else {
$item = $pathfile;
$item = $pathfile;
}
if ($find_mode) {
print "$item\n";
print "$item\n";
} else {
$type = $messages{$type}
if ($explain_type);
print "$type $item\n";
$type = $messages{$type}
if ($explain_type);
print "$type $item\n";
}
}
@@ -219,28 +219,28 @@ sub load_entries ($)
my %ent = ();
unless (open (ENTRIES, "< $entries_file")) {
error ("couldn't open $entries_file: $!");
error ("couldn't open $entries_file: $!");
}
while (<ENTRIES>) {
chomp;
$ent{$_} = 1;
chomp;
$ent{$_} = 1;
}
close (ENTRIES);
if (open (ENTRIES, "< $entries_log_file")) {
while (<ENTRIES>) {
chomp;
if ( m{^A (.+)} ) {
$ent{$1} = 1;
} elsif ( m{^R (.+)} ) {
delete $ent{$1};
} else {
# Note: "cvs commit" helps even when you are offline
error ("$entries_log_file:$.: unrecognizable line, " .
"try \"cvs commit\"");
}
}
close (ENTRIES);
while (<ENTRIES>) {
chomp;
if ( m{^A (.+)} ) {
$ent{$1} = 1;
} elsif ( m{^R (.+)} ) {
delete $ent{$1};
} else {
# Note: "cvs commit" helps even when you are offline
error ("$entries_log_file:$.: unrecognizable line, " .
"try \"cvs commit\"");
}
}
close (ENTRIES);
}
return keys %ent;
@@ -260,28 +260,28 @@ sub process_arg ($)
local $single_filename = 0;
if ( $arg eq "" or -d $arg ) {
$curr_dir = $arg;
my $real_curr_dir = $curr_dir eq "" ? "." : $curr_dir;
$curr_dir = $arg;
my $real_curr_dir = $curr_dir eq "" ? "." : $curr_dir;
error ("$real_curr_dir is not a directory")
unless ( -d $real_curr_dir );
error ("$real_curr_dir is not a directory")
unless ( -d $real_curr_dir );
# Scan present files.
file_status (".");
opendir (DIR, $real_curr_dir) ||
error ("couldn't open directory $real_curr_dir: $!");
foreach (readdir (DIR)) {
$found_files {$_} = 1;
}
closedir (DIR);
# Scan present files.
file_status (".");
opendir (DIR, $real_curr_dir) ||
error ("couldn't open directory $real_curr_dir: $!");
foreach (readdir (DIR)) {
$found_files {$_} = 1;
}
closedir (DIR);
} else {
$single_filename = basename $arg;
$curr_dir = dirname $arg;
$found_files{$single_filename} = 1 if lstat $arg;
$single_filename = basename $arg;
$curr_dir = dirname $arg;
$found_files{$single_filename} = 1 if lstat $arg;
}
$curr_dir .= "/"
unless ( $curr_dir eq "" || $curr_dir =~ m{/$} );
unless ( $curr_dir eq "" || $curr_dir =~ m{/$} );
# Scan CVS/Entries.
my %entries = ();
@@ -289,118 +289,118 @@ sub process_arg ($)
my %removed = ();
foreach ( load_entries ("${curr_dir}CVS/Entries") ) {
if ( m{^D/([^/]+)/} ) {
$subdirs{$1} = SUBDIR_FOUND if !$single_filename;
} elsif ( m{^/([^/]+)/([^/])[^/]*/([^/]*)/} ) {
if ( !$single_filename or $single_filename eq $1 ) {
$entries{$1} = $3;
$removed{$1} = 1
if $2 eq '-';
}
} elsif ( m{^D$} ) {
next;
} else {
error ("${curr_dir}CVS/Entries: unrecognizable line");
}
if ( m{^D/([^/]+)/} ) {
$subdirs{$1} = SUBDIR_FOUND if !$single_filename;
} elsif ( m{^/([^/]+)/([^/])[^/]*/([^/]*)/} ) {
if ( !$single_filename or $single_filename eq $1 ) {
$entries{$1} = $3;
$removed{$1} = 1
if $2 eq '-';
}
} elsif ( m{^D$} ) {
next;
} else {
error ("${curr_dir}CVS/Entries: unrecognizable line");
}
}
if ( $single_filename && !$entries{$single_filename} &&
!$found_files{$single_filename} ) {
error ("nothing known about $arg");
!$found_files{$single_filename} ) {
error ("nothing known about $arg");
}
# Scan .cvsignore if any
unless ($no_cvsignore) {
my (@ignore_list) = ();
my (@ignore_list) = ();
if (-f "${curr_dir}.cvsignore") {
open (CVSIGNORE, "< ${curr_dir}.cvsignore")
|| error ("couldn't open ${curr_dir}.cvsignore: $!");
while (<CVSIGNORE>) {
push (@ignore_list, split);
}
close (CVSIGNORE);
}
if (-f "${curr_dir}.cvsignore") {
open (CVSIGNORE, "< ${curr_dir}.cvsignore")
|| error ("couldn't open ${curr_dir}.cvsignore: $!");
while (<CVSIGNORE>) {
push (@ignore_list, split);
}
close (CVSIGNORE);
}
my ($iter);
foreach $iter (@ignore_list, @common_ignores) {
if ($iter eq '!') {
$ignore_rx = ''
} else {
if ($ignore_rx eq '') {
$ignore_rx = '^(';
} else {
$ignore_rx .= '|';
}
$ignore_rx .= glob_to_rx ($iter);
}
}
$ignore_rx .= ')$'
if $ignore_rx ne '';
my ($iter);
foreach $iter (@ignore_list, @common_ignores) {
if ($iter eq '!') {
$ignore_rx = ''
} else {
if ($ignore_rx eq '') {
$ignore_rx = '^(';
} else {
$ignore_rx .= '|';
}
$ignore_rx .= glob_to_rx ($iter);
}
}
$ignore_rx .= ')$'
if $ignore_rx ne '';
}
# File is missing
foreach $file (sort keys %entries) {
unless ($found_files{$file}) {
if ($removed{$file}) {
file_status("R");
} else {
file_status("U");
}
}
unless ($found_files{$file}) {
if ($removed{$file}) {
file_status("R");
} else {
file_status("U");
}
}
}
foreach $file (sort keys %found_files) {
next if ($file eq '.' || $file eq '..');
lstat ($curr_dir . $file) ||
error ("lstat() failed on $curr_dir . $file");
if (! $nolinks && -l _) {
file_status ("L");
} elsif (-d _) {
if ($file eq 'CVS') {
file_status ("C");
} elsif ($subdirs{$file}) {
$subdirs{$file} = SUBDIR_CVS;
} else {
file_status ("D"); # Unknown directory
}
} elsif (! (-f _) && ! (-l _)) {
file_status ("S"); # This must be something very special
} elsif (! $nolinks && (stat _) [3] > 1 ) {
file_status ("H"); # Hard link
} elsif (! $entries{$file}) {
file_status ("?");
} elsif ($entries{$file} =~ /^Initial |^dummy /) {
file_status ("A");
} elsif ($entries{$file} =~ /^Result of merge/) {
file_status ("G");
} elsif ($entries{$file} !~
/^(...) (...) (..) (..):(..):(..) (....)$/) {
error ("Invalid timestamp for $curr_dir$file: $entries{$file}");
} else {
my $cvtime = timegm($6, $5, $4, $3, $months{$2}, $7 - 1900);
my $mtime = (stat _) [9];
if ($cvtime == $mtime) {
file_status ("F");
} elsif ($cvtime < $mtime) {
file_status ("M");
} else {
file_status ("O");
}
}
next if ($file eq '.' || $file eq '..');
lstat ($curr_dir . $file) ||
error ("lstat() failed on $curr_dir . $file");
if (! $nolinks && -l _) {
file_status ("L");
} elsif (-d _) {
if ($file eq 'CVS') {
file_status ("C");
} elsif ($subdirs{$file}) {
$subdirs{$file} = SUBDIR_CVS;
} else {
file_status ("D"); # Unknown directory
}
} elsif (! (-f _) && ! (-l _)) {
file_status ("S"); # This must be something very special
} elsif (! $nolinks && (stat _) [3] > 1 ) {
file_status ("H"); # Hard link
} elsif (! $entries{$file}) {
file_status ("?");
} elsif ($entries{$file} =~ /^Initial |^dummy /) {
file_status ("A");
} elsif ($entries{$file} =~ /^Result of merge/) {
file_status ("G");
} elsif ($entries{$file} !~
/^(...) (...) (..) (..):(..):(..) (....)$/) {
error ("Invalid timestamp for $curr_dir$file: $entries{$file}");
} else {
my $cvtime = timegm($6, $5, $4, $3, $months{$2}, $7 - 1900);
my $mtime = (stat _) [9];
if ($cvtime == $mtime) {
file_status ("F");
} elsif ($cvtime < $mtime) {
file_status ("M");
} else {
file_status ("O");
}
}
}
# Now do directories.
unless ($no_recurse) {
my $save_curr_dir = $curr_dir;
foreach $file (sort keys %subdirs) {
if ($subdirs{$file} == SUBDIR_FOUND) {
$curr_dir = $save_curr_dir;
file_status ("X");
} elsif ($subdirs{$file} == SUBDIR_CVS) {
process_arg ($save_curr_dir . $file)
}
}
my $save_curr_dir = $curr_dir;
foreach $file (sort keys %subdirs) {
if ($subdirs{$file} == SUBDIR_FOUND) {
$curr_dir = $save_curr_dir;
file_status ("X");
} elsif ($subdirs{$file} == SUBDIR_CVS) {
process_arg ($save_curr_dir . $file)
}
}
}
}
@@ -423,13 +423,13 @@ sub glob_to_rx ($)
# Find parts in square brackets and copy them literally
# Text outside brackets is processed by glob_to_rx_simple()
while ($expr ne '') {
if ($expr =~ /^(.*?)(\[.*?\])(.*)/) {
$expr = $3;
$result .= glob_to_rx_simple ($1) . $2;
} else {
$result .= glob_to_rx_simple ($expr);
last;
}
if ($expr =~ /^(.*?)(\[.*?\])(.*)/) {
$expr = $3;
$result .= glob_to_rx_simple ($1) . $2;
} else {
$result .= glob_to_rx_simple ($expr);
last;
}
}
return $result;
}
@@ -441,21 +441,21 @@ sub Main ()
# long status messages
%messages = (
"?" => "Unlisted file",
"." => "Known directory",
"F" => "Up-to-date file",
"C" => "CVS admin directory",
"M" => "Modified file",
"S" => "Special file",
"D" => "Unlisted directory",
"L" => "Symbolic link",
"H" => "Hard link",
"U" => "Lost file",
"X" => "Lost directory",
"A" => "Newly added",
"O" => "Older copy",
"G" => "Result of merge",
"R" => "Removed file"
"?" => "Unlisted file",
"." => "Known directory",
"F" => "Up-to-date file",
"C" => "CVS admin directory",
"M" => "Modified file",
"S" => "Special file",
"D" => "Unlisted directory",
"L" => "Symbolic link",
"H" => "Hard link",
"U" => "Lost file",
"X" => "Lost directory",
"A" => "Newly added",
"O" => "Older copy",
"G" => "Result of merge",
"R" => "Removed file"
);
undef @batch_list; # List of files for batch processing
@@ -471,17 +471,17 @@ sub Main ()
my $want_ver = 0; # Print version and exit
my %options = (
"types=s" => \$list_types,
"batch=s" => \$batch_cmd,
"local" => \$no_recurse,
"explain" => \$explain_type,
"find" => \$find_mode,
"short" => \$short_print,
"ignore" => \$no_cvsignore,
"messages" => \$want_msg,
"nolinks" => \$nolinks,
"help" => \$want_help,
"version" => \$want_ver
"types=s" => \$list_types,
"batch=s" => \$batch_cmd,
"local" => \$no_recurse,
"explain" => \$explain_type,
"find" => \$find_mode,
"short" => \$short_print,
"ignore" => \$no_cvsignore,
"messages" => \$want_msg,
"nolinks" => \$nolinks,
"help" => \$want_help,
"version" => \$want_ver
);
GetOptions(%options);
@@ -493,19 +493,19 @@ sub Main ()
version() if $want_ver;
unless ($no_cvsignore) {
init_ignores();
init_ignores();
}
if ($#ARGV < 0) {
@ARGV = ("");
@ARGV = ("");
}
foreach (@ARGV) {
process_arg ($_);
process_arg ($_);
}
if ($#batch_list >= 0) {
do_batch();
do_batch();
}
}

18
cfg.mk
View File

@@ -25,13 +25,13 @@ gnu_rel_host = $(gnu_ftp_host-$(RELEASE_TYPE))
manual_title = Core GNU utilities
url_dir_list = \
ftp://$(gnu_rel_host)/gnu/coreutils
ftp://$(gnu_rel_host)/gnu/$(PACKAGE)
# The GnuPG ID of the key used to sign the tarballs.
gpg_key_ID = B9AB9A16
# Tests not to run as part of "make distcheck".
local-checks-to-skip = strftime-check
local-checks-to-skip =
# Tools used to bootstrap this package, used for "announcement".
bootstrap-tools = autoconf,automake,gnulib,bison
@@ -39,7 +39,7 @@ bootstrap-tools = autoconf,automake,gnulib,bison
# Now that we have better tests, make this the default.
export VERBOSE = yes
old_NEWS_hash = 8ed224902e335a80ec8340cd0d594d7f
old_NEWS_hash = 0d22ab4ad3fedd9cf283b256b61e8080
# Ensure that the list of O_ symbols used to compute O_FULLBLOCK is complete.
dd = $(srcdir)/src/dd.c
@@ -206,4 +206,16 @@ sc_strftime_check:
rm -f $@-src $@-info; \
fi
# Indent only with spaces.
sc_prohibit_tab_based_indentation:
@re='^ * ' \
msg='TAB in indentation; use only spaces' \
$(_prohibit_regexp)
# Don't use "indent-tabs-mode: nil" anymore. No longer needed.
sc_prohibit_emacs__indent_tabs_mode__setting:
@re='^( *[*#] *)?indent-tabs-mode:' \
msg='use of emacs indent-tabs-mode: setting' \
$(_prohibit_regexp)
include $(srcdir)/dist-check.mk

View File

@@ -24,8 +24,8 @@ AC_PREREQ([2.61])
# indicates that it is built from the 219th delta (in _some_ repository)
# following the v6.9 tag, and that 58ddd is a prefix of the commit SHA1.
AC_INIT([GNU coreutils],
m4_esyscmd([build-aux/git-version-gen .tarball-version]),
[bug-coreutils@gnu.org])
m4_esyscmd([build-aux/git-version-gen .tarball-version]),
[bug-coreutils@gnu.org])
AC_CONFIG_SRCDIR([src/ls.c])
@@ -47,7 +47,7 @@ coreutils_MACROS
AC_ARG_ENABLE([gcc-warnings],
[AS_HELP_STRING([--enable-gcc-warnings],
[turn on lots of GCC warnings (for developers)])],
[turn on lots of GCC warnings (for developers)])],
[case $enableval in
yes|no) ;;
*) AC_MSG_ERROR([bad value $enableval for gcc-warnings option]) ;;
@@ -101,9 +101,6 @@ if test "$gl_gcc_warnings" = yes; then
gl_WARN_ADD([-Wno-pointer-sign]) # Too many warnings for now
gl_WARN_ADD([-Wno-unused-parameter]) # Too many warnings for now
# Offenders in pre-fts remove.c; FIXME: remove upon remove.c rewrite
gl_WARN_ADD([-Wno-jump-misses-init])
# In spite of excluding -Wlogical-op above, it is enabled, as of
# gcc 4.5.0 20090517, and it provokes warnings in cat.c, dd.c, truncate.c
gl_WARN_ADD([-Wno-logical-op])
@@ -122,11 +119,11 @@ AC_FUNC_FORK
optional_bin_progs=
AC_CHECK_FUNCS([uname],
gl_ADD_PROG([optional_bin_progs], [uname]))
gl_ADD_PROG([optional_bin_progs], [uname]))
AC_CHECK_FUNCS([chroot],
gl_ADD_PROG([optional_bin_progs], [chroot]))
gl_ADD_PROG([optional_bin_progs], [chroot]))
AC_CHECK_FUNCS([gethostid],
gl_ADD_PROG([optional_bin_progs], [hostid]))
gl_ADD_PROG([optional_bin_progs], [hostid]))
gl_WINSIZE_IN_PTEM
@@ -168,9 +165,9 @@ int main()
[# If we have tzset, assume the worst when cross-compiling.
utils_cv_localtime_cache=yes])
else
# If we lack tzset, report that localtime does not cache TZ,
# since we can't invalidate the cache if we don't have tzset.
utils_cv_localtime_cache=no
# If we lack tzset, report that localtime does not cache TZ,
# since we can't invalidate the cache if we don't have tzset.
utils_cv_localtime_cache=no
fi])dnl
AC_MSG_RESULT([$utils_cv_localtime_cache])
if test $utils_cv_localtime_cache = yes; then
@@ -197,7 +194,7 @@ AC_CACHE_CHECK([for 3-argument setpriority function],
[AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <sys/time.h>
#include <sys/resource.h>
#include <sys/resource.h>
]],
[[setpriority (0, 0, 0);]])],
[utils_cv_func_setpriority=yes],
@@ -374,8 +371,8 @@ case $t in
$no_install_progs_default) ;;
*) AC_MSG_ERROR([[internal error: g'l_INCLUDE_EXCLUDE_PROG's 2nd arg, $t,
does not match the list of default-not-installed programs
($no_install_progs_default) also recorded in $mk]],
1) ;;
($no_install_progs_default) also recorded in $mk]],
1) ;;
esac
# Given the name of a variable containing a space-separated list of

View File

@@ -176,198 +176,198 @@ Free Documentation License''.
@cindex file utilities
@menu
* Introduction:: Caveats, overview, and authors.
* Common options:: Common options.
* Output of entire files:: cat tac nl od
* Formatting file contents:: fmt pr fold
* Output of parts of files:: head tail split csplit
* Summarizing files:: wc sum cksum md5sum sha1sum sha2
* Operating on sorted files:: sort shuf uniq comm ptx tsort
* Operating on fields within a line:: cut paste join
* Operating on characters:: tr expand unexpand
* Directory listing:: ls dir vdir dircolors
* Basic operations:: cp dd install mv rm shred
* Special file types:: ln mkdir rmdir mkfifo mknod
* Changing file attributes:: chgrp chmod chown touch
* Disk usage:: df du stat sync truncate
* Printing text:: echo printf yes
* Conditions:: false true test expr
* Redirection:: tee
* File name manipulation:: dirname basename pathchk
* Working context:: pwd stty printenv tty
* User information:: id logname whoami groups users who
* System context:: date uname hostname hostid uptime
* SELinux context:: chcon runcon
* Modified command invocation:: chroot env nice nohup stdbuf su timeout
* Process control:: kill
* Delaying:: sleep
* Numeric operations:: factor seq
* File permissions:: Access modes.
* Date input formats:: Specifying date strings.
* Opening the software toolbox:: The software tools philosophy.
* GNU Free Documentation License:: Copying and sharing this manual.
* Concept index:: General index.
* Introduction:: Caveats, overview, and authors
* Common options:: Common options
* Output of entire files:: cat tac nl od base64
* Formatting file contents:: fmt pr fold
* Output of parts of files:: head tail split csplit
* Summarizing files:: wc sum cksum md5sum sha1sum sha2
* Operating on sorted files:: sort shuf uniq comm ptx tsort
* Operating on fields:: cut paste join
* Operating on characters:: tr expand unexpand
* Directory listing:: ls dir vdir dircolors
* Basic operations:: cp dd install mv rm shred
* Special file types:: mkdir rmdir unlink mkfifo mknod ln link readlink
* Changing file attributes:: chgrp chmod chown touch
* Disk usage:: df du stat sync truncate
* Printing text:: echo printf yes
* Conditions:: false true test expr
* Redirection:: tee
* File name manipulation:: dirname basename pathchk
* Working context:: pwd stty printenv tty
* User information:: id logname whoami groups users who
* System context:: date arch uname hostname hostid uptime
* SELinux context:: chcon runcon
* Modified command invocation:: chroot env nice nohup stdbuf su timeout
* Process control:: kill
* Delaying:: sleep
* Numeric operations:: factor seq
* File permissions:: Access modes
* Date input formats:: Specifying date strings
* Opening the software toolbox:: The software tools philosophy
* GNU Free Documentation License:: Copying and sharing this manual
* Concept index:: General index
@detailmenu
--- The Detailed Node Listing ---
Common Options
* Exit status:: Indicating program success or failure.
* Backup options:: Backup options
* Block size:: Block size
* Signal specifications:: Specifying signals
* Exit status:: Indicating program success or failure
* Backup options:: Backup options
* Block size:: Block size
* Signal specifications:: Specifying signals
* Disambiguating names and IDs:: chgrp and chown owner and group syntax
* Random sources:: Sources of random data
* Target directory:: Target directory
* Trailing slashes:: Trailing slashes
* Traversing symlinks:: Traversing symlinks to directories
* Treating / specially:: Treating / specially
* Standards conformance:: Standards conformance
* Random sources:: Sources of random data
* Target directory:: Target directory
* Trailing slashes:: Trailing slashes
* Traversing symlinks:: Traversing symlinks to directories
* Treating / specially:: Treating / specially
* Standards conformance:: Standards conformance
Output of entire files
* cat invocation:: Concatenate and write files.
* tac invocation:: Concatenate and write files in reverse.
* nl invocation:: Number lines and write files.
* od invocation:: Write files in octal or other formats.
* base64 invocation:: Transform data into printable data.
* cat invocation:: Concatenate and write files
* tac invocation:: Concatenate and write files in reverse
* nl invocation:: Number lines and write files
* od invocation:: Write files in octal or other formats
* base64 invocation:: Transform data into printable data
Formatting file contents
* fmt invocation:: Reformat paragraph text.
* pr invocation:: Paginate or columnate files for printing.
* fold invocation:: Wrap input lines to fit in specified width.
* fmt invocation:: Reformat paragraph text
* pr invocation:: Paginate or columnate files for printing
* fold invocation:: Wrap input lines to fit in specified width
Output of parts of files
* head invocation:: Output the first part of files.
* tail invocation:: Output the last part of files.
* split invocation:: Split a file into fixed-size pieces.
* csplit invocation:: Split a file into context-determined pieces.
* head invocation:: Output the first part of files
* tail invocation:: Output the last part of files
* split invocation:: Split a file into fixed-size pieces
* csplit invocation:: Split a file into context-determined pieces
Summarizing files
* wc invocation:: Print newline, word, and byte counts.
* sum invocation:: Print checksum and block counts.
* cksum invocation:: Print CRC checksum and byte counts.
* md5sum invocation:: Print or check MD5 digests.
* sha1sum invocation:: Print or check SHA-1 digests.
* sha2 utilities:: Print or check SHA-2 digests.
* wc invocation:: Print newline, word, and byte counts
* sum invocation:: Print checksum and block counts
* cksum invocation:: Print CRC checksum and byte counts
* md5sum invocation:: Print or check MD5 digests
* sha1sum invocation:: Print or check SHA-1 digests
* sha2 utilities:: Print or check SHA-2 digests
Operating on sorted files
* sort invocation:: Sort text files.
* shuf invocation:: Shuffle text files.
* uniq invocation:: Uniquify files.
* comm invocation:: Compare two sorted files line by line.
* ptx invocation:: Produce a permuted index of file contents.
* tsort invocation:: Topological sort.
* sort invocation:: Sort text files
* shuf invocation:: Shuffle text files
* uniq invocation:: Uniquify files
* comm invocation:: Compare two sorted files line by line
* ptx invocation:: Produce a permuted index of file contents
* tsort invocation:: Topological sort
@command{ptx}: Produce permuted indexes
* General options in ptx:: Options which affect general program behavior.
* Charset selection in ptx:: Underlying character set considerations.
* Input processing in ptx:: Input fields, contexts, and keyword selection.
* Output formatting in ptx:: Types of output format, and sizing the fields.
* Compatibility in ptx:: The @acronym{GNU} extensions to @command{ptx}
* General options in ptx:: Options which affect general program behavior
* Charset selection in ptx:: Underlying character set considerations
* Input processing in ptx:: Input fields, contexts, and keyword selection
* Output formatting in ptx:: Types of output format, and sizing the fields
* Compatibility in ptx:: The @acronym{GNU} extensions to @command{ptx}
Operating on fields within a line
Operating on fields
* cut invocation:: Print selected parts of lines.
* paste invocation:: Merge lines of files.
* join invocation:: Join lines on a common field.
* cut invocation:: Print selected parts of lines
* paste invocation:: Merge lines of files
* join invocation:: Join lines on a common field
Operating on characters
* tr invocation:: Translate, squeeze, and/or delete characters.
* expand invocation:: Convert tabs to spaces.
* unexpand invocation:: Convert spaces to tabs.
* tr invocation:: Translate, squeeze, and/or delete characters
* expand invocation:: Convert tabs to spaces
* unexpand invocation:: Convert spaces to tabs
@command{tr}: Translate, squeeze, and/or delete characters
* Character sets:: Specifying sets of characters.
* Translating:: Changing one set of characters to another.
* Squeezing:: Squeezing repeats and deleting.
* Character sets:: Specifying sets of characters
* Translating:: Changing one set of characters to another
* Squeezing:: Squeezing repeats and deleting
Directory listing
* ls invocation:: List directory contents
* dir invocation:: Briefly list directory contents
* vdir invocation:: Verbosely list directory contents
* dircolors invocation:: Color setup for @command{ls}
* ls invocation:: List directory contents
* dir invocation:: Briefly list directory contents
* vdir invocation:: Verbosely list directory contents
* dircolors invocation:: Color setup for @command{ls}
@command{ls}: List directory contents
* Which files are listed:: Which files are listed
* What information is listed:: What information is listed
* Sorting the output:: Sorting the output
* More details about version sort:: More details about version sort
* General output formatting:: General output formatting
* Formatting the file names:: Formatting the file names
* Which files are listed:: Which files are listed
* What information is listed:: What information is listed
* Sorting the output:: Sorting the output
* Details about version sort:: More details about version sort
* General output formatting:: General output formatting
* Formatting the file names:: Formatting the file names
Basic operations
* cp invocation:: Copy files and directories
* dd invocation:: Convert and copy a file
* install invocation:: Copy files and set attributes
* mv invocation:: Move (rename) files
* rm invocation:: Remove files or directories
* shred invocation:: Remove files more securely
* cp invocation:: Copy files and directories
* dd invocation:: Convert and copy a file
* install invocation:: Copy files and set attributes
* mv invocation:: Move (rename) files
* rm invocation:: Remove files or directories
* shred invocation:: Remove files more securely
Special file types
* link invocation:: Make a hard link via the link syscall
* ln invocation:: Make links between files
* mkdir invocation:: Make directories
* mkfifo invocation:: Make FIFOs (named pipes)
* mknod invocation:: Make block or character special files
* readlink invocation:: Print value of a symlink or canonical file name
* rmdir invocation:: Remove empty directories
* unlink invocation:: Remove files via unlink syscall
* link invocation:: Make a hard link via the link syscall
* ln invocation:: Make links between files
* mkdir invocation:: Make directories
* mkfifo invocation:: Make FIFOs (named pipes)
* mknod invocation:: Make block or character special files
* readlink invocation:: Print value of a symlink or canonical file name
* rmdir invocation:: Remove empty directories
* unlink invocation:: Remove files via unlink syscall
Changing file attributes
* chown invocation:: Change file owner and group
* chgrp invocation:: Change group ownership
* chmod invocation:: Change access permissions
* touch invocation:: Change file timestamps
* chown invocation:: Change file owner and group
* chgrp invocation:: Change group ownership
* chmod invocation:: Change access permissions
* touch invocation:: Change file timestamps
Disk usage
* df invocation:: Report file system disk space usage
* du invocation:: Estimate file space usage
* stat invocation:: Report file or file system status
* sync invocation:: Synchronize data on disk with memory
* truncate invocation:: Shrink or extend the size of a file
* df invocation:: Report file system disk space usage
* du invocation:: Estimate file space usage
* stat invocation:: Report file or file system status
* sync invocation:: Synchronize data on disk with memory
* truncate invocation:: Shrink or extend the size of a file
Printing text
* echo invocation:: Print a line of text
* printf invocation:: Format and print data
* yes invocation:: Print a string until interrupted
* echo invocation:: Print a line of text
* printf invocation:: Format and print data
* yes invocation:: Print a string until interrupted
Conditions
* false invocation:: Do nothing, unsuccessfully
* true invocation:: Do nothing, successfully
* test invocation:: Check file types and compare values
* expr invocation:: Evaluate expressions
* false invocation:: Do nothing, unsuccessfully
* true invocation:: Do nothing, successfully
* test invocation:: Check file types and compare values
* expr invocation:: Evaluate expressions
@command{test}: Check file types and compare values
* File type tests:: File type tests
* Access permission tests:: Access permission tests
* File characteristic tests:: File characteristic tests
* String tests:: String tests
* Numeric tests:: Numeric tests
* File type tests:: File type tests
* Access permission tests:: Access permission tests
* File characteristic tests:: File characteristic tests
* String tests:: String tests
* Numeric tests:: Numeric tests
@command{expr}: Evaluate expression
* String expressions:: + : match substr index length
* Numeric expressions:: + - * / %
* Relations for expr:: | & < <= = == != >= >
* Examples of expr:: Examples of using @command{expr}
* String expressions:: + : match substr index length
* Numeric expressions:: + - * / %
* Relations for expr:: | & < <= = == != >= >
* Examples of expr:: Examples of using @command{expr}
Redirection
@@ -388,13 +388,13 @@ Working context
@command{stty}: Print or change terminal characteristics
* Control:: Control settings
* Input:: Input settings
* Output:: Output settings
* Local:: Local settings
* Combination:: Combination settings
* Characters:: Special characters
* Special:: Special settings
* Control:: Control settings
* Input:: Input settings
* Output:: Output settings
* Local:: Local settings
* Combination:: Combination settings
* Characters:: Special characters
* Special:: Special settings
User information
@@ -420,10 +420,10 @@ System context
* Date conversion specifiers:: %[aAbBcCdDeFgGhjmuUVwWxyY]
* Literal conversion specifiers:: %[%nt]
* Padding and other flags:: Pad with zeros, spaces, etc.
* Setting the time:: Changing the system clock.
* Options for date:: Instead of the current time.
* Date input formats:: Specifying date strings.
* Examples of date:: Examples.
* Setting the time:: Changing the system clock
* Options for date:: Instead of the current time
* Date input formats:: Specifying date strings
* Examples of date:: Examples
SELinux context
@@ -455,23 +455,23 @@ Numeric operations
File permissions
* Mode Structure:: Structure of file mode bits.
* Symbolic Modes:: Mnemonic representation of file mode bits.
* Numeric Modes:: File mode bits as octal numbers.
* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories.
* Mode Structure:: Structure of file mode bits
* Symbolic Modes:: Mnemonic representation of file mode bits
* Numeric Modes:: File mode bits as octal numbers
* Directory Setuid and Setgid:: Set-user-ID and set-group-ID on directories
Date input formats
* General date syntax:: Common rules.
* Calendar date items:: 19 Dec 1994.
* Time of day items:: 9:20pm.
* Time zone items:: @sc{est}, @sc{pdt}, @sc{gmt}.
* Day of week items:: Monday and others.
* Relative items in date strings:: next tuesday, 2 years ago.
* Pure numbers in date strings:: 19931219, 1440.
* Seconds since the Epoch:: @@1078100502.
* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0".
* Authors of get_date:: Bellovin, Eggert, Salz, Berets, et al.
* General date syntax:: Common rules
* Calendar date items:: 19 Dec 1994
* Time of day items:: 9:20pm
* Time zone items:: @sc{est}, @sc{pdt}, @sc{gmt}
* Day of week items:: Monday and others
* Relative items in date strings:: next tuesday, 2 years ago
* Pure numbers in date strings:: 19931219, 1440
* Seconds since the Epoch:: @@1078100502
* Specifying time zone rules:: TZ="America/New_York", TZ="UTC0"
* Authors of get_date:: Bellovin, Eggert, Salz, Berets, et al
Opening the software toolbox
@@ -485,7 +485,7 @@ Opening the software toolbox
Copying This Manual
* GNU Free Documentation License:: Copying and sharing this manual.
* GNU Free Documentation License:: Copying and sharing this manual
@end detailmenu
@end menu
@@ -618,15 +618,8 @@ from the shell.
@end macro
@macro multiplierSuffixes{varName}
@ignore
Appending @samp{b} multiplies @var{\varName\} by 512,
@samp{kB} by 1000, @samp{K} by 1024,
@samp{MB} by 1000*1000, @samp{M} by 1024*1024,
@samp{GB} by 1000*1000*1000, @samp{G} by 1024*1024*1024,
and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}.
@end ignore
@var{\varName\} is a number which may have one of the following
multiplicative suffixes:
@var{\varName\} may be, or may be an integer optionally followed by,
one of the following multiplicative suffixes:
@example
@samp{b} => 512 ("blocks")
@samp{KB} => 1000 (KiloBytes)
@@ -641,8 +634,8 @@ and so on for @samp{T}, @samp{P}, @samp{E}, @samp{Z}, and @samp{Y}.
@c FIXME: same as above, but no ``blocks'' line.
@macro multiplierSuffixesNoBlocks{varName}
@var{\varName\} is a number which may have one of the following
multiplicative suffixes:
@var{\varName\} may be, or may be an integer optionally followed by,
one of the following multiplicative suffixes:
@example
@samp{KB} => 1000 (KiloBytes)
@samp{K} => 1024 (KibiBytes)
@@ -752,8 +745,8 @@ However, some of the programs documented here do produce
other exit status values and a few associate different
meanings with the values @samp{0} and @samp{1}.
Here are some of the exceptions:
@command{chroot}, @command{env}, @command{expr},
@command{nice}, @command{nohup}, @command{printenv}, @command{sort},
@command{chroot}, @command{env}, @command{expr}, @command{nice},
@command{nohup}, @command{printenv}, @command{sort}, @command{stdbuf},
@command{su}, @command{test}, @command{timeout}, @command{tty}.
@@ -2122,14 +2115,6 @@ The program accepts the following options. Also see @ref{Common options}.
@table @samp
@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.
@item -c
@itemx --crown-margin
@opindex -c
@@ -2790,9 +2775,10 @@ growing.
The option values @samp{descriptor} and @samp{name} may be specified only
with the long form of the option, not with @option{-f}.
@vindex POSIXLY_CORRECT
If @env{POSIXLY_CORRECT} is set, the @option{-f} option is ignored if
The @option{-f} option is ignored if
no @var{file} operand is specified and standard input is a FIFO or a pipe.
Likewise, the @option{-f} option has no effect for any
operand specified as @samp{-}, when standard input is a FIFO or a pipe.
@item -F
@opindex -F
@@ -5250,8 +5236,8 @@ the way the linker handled archive files, which has since been solved
in different ways.
@node Operating on fields within a line
@chapter Operating on fields within a line
@node Operating on fields
@chapter Operating on fields
@menu
* cut invocation:: Print selected parts of lines.
@@ -6127,8 +6113,9 @@ Exit status:
1 minor problems (e.g., failure to access a file or directory not
specified as a command line argument. This happens when listing a
directory in which entries are actively being removed or renamed.)
2 serious trouble (e.g., memory exhausted, invalid option or failure
to access file or directory specified as a command line argument)
2 serious trouble (e.g., memory exhausted, invalid option, failure
to access a file or directory specified as a command line argument
or a directory loop)
@end display
Also see @ref{Common options}.
@@ -6137,7 +6124,7 @@ Also see @ref{Common options}.
* Which files are listed::
* What information is listed::
* Sorting the output::
* More details about version sort::
* Details about version sort::
* General output formatting::
* Formatting file timestamps::
* Formatting the file names::
@@ -6667,7 +6654,7 @@ directories, since not doing any sorting can be noticeably faster.
@opindex version@r{, sorting option for @command{ls}}
Sort by version name and number, lowest first. It behaves like a default
sort, except that each sequence of decimal digits is treated numerically
as an index/version number. (@xref{More details about version sort}.)
as an index/version number. (@xref{Details about version sort}.)
@item -X
@itemx --sort=extension
@@ -6680,8 +6667,8 @@ after the last @samp{.}); files with no extension are sorted first.
@end table
@node More details about version sort
@subsection More details about version sort
@node Details about version sort
@subsection Details about version sort
The version sort takes into account the fact that file names frequently include
indices or version numbers. Standard sorting functions usually do not produce
@@ -7445,12 +7432,10 @@ may preserve the group ownership of a file only if they happen to be
a member of the desired group.
@itemx timestamps
Preserve the times of last access and last modification, when possible.
In general, it is not possible to preserve these attributes
On older systems, it is not possible to preserve these attributes
when the affected file is a symbolic link.
However, FreeBSD now provides the @code{lutimes} function, which makes
it possible even for symbolic links. However, this implementation does
not yet take advantage of that.
@c FIXME: once we provide lutimes support, update the above.
However, many systems now provide the @code{utimensat} function,
which makes it possible even for symbolic links.
@itemx links
Preserve in the destination files
any links between corresponding source files.
@@ -7543,15 +7528,31 @@ Also, it is not portable to use @option{-R} to copy symbolic links
unless you also specify @option{-P}, as @acronym{POSIX} allows
implementations that dereference symbolic links by default.
@item --reflink
@opindex --reflink
@item --reflink[=@var{when}]
@opindex --reflink[=@var{when}]
@cindex COW
@cindex clone
@cindex copy on write
Perform a lightweight, copy-on-write (COW) copy.
Copying with this option can succeed only on some relatively new file systems.
Copying with this option can succeed only on some file systems.
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 exact 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 behaviour.
@end table
@item --remove-destination
@opindex --remove-destination
Remove each existing destination file before attempting to open it
@@ -7768,8 +7769,8 @@ input newline with a space and padding with spaces as necessary.
@item unblock
@opindex unblock
Replace trailing spaces in each @samp{cbs}-sized input block with a
newline.
Remove any trailing spaces in each @samp{cbs}-sized input block,
and append a newline.
The @samp{block} and @samp{unblock} conversions are mutually exclusive.
@@ -8058,6 +8059,14 @@ The program accepts the following options. Also see @ref{Common options}.
@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.
@item -c
@opindex -c
Ignored; for compatibility with old Unix versions of @command{install}.
@@ -8745,6 +8754,11 @@ On a @acronym{GNU} system, this command acts like @samp{ln --directory
not specified by @acronym{POSIX}, and the @command{link} command is
more portable in practice.
If @var{filename} is a symbolic link, it is unspecified whether
@var{linkname} will be a hard link to the symbolic link or to the
target of the symbolic link. Use @command{ln -P} or @command{ln -L}
to specify which behavior is desired.
@exitstatus
@@ -8800,8 +8814,10 @@ A @dfn{hard link} is another name for an existing file; the link and the
original are indistinguishable. Technically speaking, they share the
same inode, and the inode contains all the information about a
file---indeed, it is not incorrect to say that the inode @emph{is} the
file. On all existing implementations, you cannot make a hard link to
a directory, and hard links cannot cross file system boundaries. (These
file. Most systems prohibit making a hard link to
a directory; on those where it is allowed, only the super-user can do
so (and with caution, since creating a cycle will cause problems to many
other utilities). Hard links cannot cross file system boundaries. (These
restrictions are not mandated by @acronym{POSIX}, however.)
@cindex dereferencing symbolic links
@@ -8813,9 +8829,13 @@ refers to a different file, by name. When most operations (opening,
reading, writing, and so on) are passed the symbolic link file, the
kernel automatically @dfn{dereferences} the link and operates on the
target of the link. But some operations (e.g., removing) work on the
link file itself, rather than on its target. The owner, group, and
mode of a symlink are not significant to file access performed through
the link. @xref{Symbolic Links,,,
link file itself, rather than on its target. The owner and group of a
symlink are not significant to file access performed through
the link, but do have implications on deleting a symbolic link from a
directory with the restricted deletion bit set. On the GNU system,
the mode of a symlink has no significance and cannot be changed, but
on some BSD systems, the mode can be changed and will affect whether
the symlink will be traversed in file name resolution. @xref{Symbolic Links,,,
libc, The GNU C Library Reference Manual}.
Symbolic links can contain arbitrary strings; a @dfn{dangling symlink}
@@ -8870,6 +8890,14 @@ Remove existing destination files.
@cindex prompting, and @command{ln}
Prompt whether to remove existing destination files.
@item -L
@itemx --logical
@opindex -L
@opindex --logical
If @option{-s} is not in effect, and the source file is a symbolic
link, create the hard link to the file referred to by the symbolic
link, rather than the symbolic link itself.
@item -n
@itemx --no-dereference
@opindex -n
@@ -8891,6 +8919,17 @@ just like a directory.
This option is weaker than the @option{--no-target-directory}
(@option{-T}) option, so it has no effect if both options are given.
@item -P
@itemx --physical
@opindex -P
@opindex --physical
If @option{-s} is not in effect, and the source file is a symbolic
link, create the hard link to the symbolic link itself. On platforms
where this is not supported by the kernel, this option creates a
symbolic link with identical contents; since symbolic link contents
cannot be edited, any file name resolution performed through either
link will be the same as if a hard link had been created.
@item -s
@itemx --symbolic
@opindex -s
@@ -8912,6 +8951,15 @@ Print the name of each file after linking it successfully.
@end table
@cindex hard links to symbolic links
@cindex symbolic links and @command{ln}
If @option{-L} and @option{-P} are both given, the last one takes
precedence. If @option{-s} is also given, @option{-L} and @option{-P}
are silently ignored. If neither option is given, then this
implementation defaults to @option{-P} if the system @code{link} supports
hard links to symbolic links (such as the GNU system), and @option{-L}
if @code{link} follows symbolic links (such as on BSD).
@exitstatus
Examples:
@@ -9196,7 +9244,8 @@ The program accepts the following options. Also see @ref{Common options}.
@opindex --canonicalize
Activate canonicalize mode.
If any component of the file name except the last one is missing or unavailable,
@command{readlink} produces no output and exits with a nonzero exit code.
@command{readlink} produces no output and exits with a nonzero exit
code. A trailing slash is ignored.
@item -e
@itemx --canonicalize-existing
@@ -9204,7 +9253,8 @@ If any component of the file name except the last one is missing or unavailable,
@opindex --canonicalize-existing
Activate canonicalize mode.
If any component is missing or unavailable, @command{readlink} produces
no output and exits with a nonzero exit code.
no output and exits with a nonzero exit code. A trailing slash
requires that the name resolve to a directory.
@item -m
@itemx --canonicalize-missing
@@ -9908,6 +9958,7 @@ If the year is specified with only two digits, then @var{cc}
is 20 for years in the range 0 @dots{} 68, and 19 for years in
69 @dots{} 99. If no digits of the year are specified,
the argument is interpreted as a date in the current year.
Note that @var{ss} may be @samp{60}, to accommodate leap seconds.
@end table
@@ -12817,9 +12868,13 @@ running it if no user is specified. Synopsis:
id [@var{option}]@dots{} [@var{username}]
@end example
@vindex POSIXLY_CORRECT
By default, it prints the real user ID, real group ID, effective user ID
if different from the real user ID, effective group ID if different from
the real group ID, and supplemental group IDs.
In addition, if SELinux
is enabled and the @env{POSIXLY_CORRECT} environment variable is not set,
then print @samp{context=@var{c}}, where @var{c} is the security context.
Each of these numeric values is preceded by an identifying string and
followed by the corresponding user or group name in parentheses.

View File

@@ -219,7 +219,7 @@ mbsalign (const char *src, char *dest, size_t dest_size,
dest = mbs_align_pad (dest, dest_end, start_spaces);
dest = mempcpy(dest, str_to_print, MIN (n_used_bytes, dest_end - dest));
dest = mbs_align_pad (dest, dest_end, end_spaces);
mbs_align_pad (dest, dest_end, end_spaces);
}
mbsalign_cleanup:
@@ -229,8 +229,3 @@ mbsalign_cleanup:
return ret;
}
/*
* Local variables:
* indent-tabs-mode: nil
* End:
*/

View File

@@ -76,45 +76,45 @@ mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
g = realloc_groupbuf (NULL, max_n_groups);
if (g == NULL)
return -1;
return -1;
while (1)
{
GETGROUPS_T *h;
int last_n_groups = max_n_groups;
{
GETGROUPS_T *h;
int last_n_groups = max_n_groups;
/* getgrouplist updates max_n_groups to num required. */
ng = getgrouplist (username, gid, g, &max_n_groups);
/* getgrouplist updates max_n_groups to num required. */
ng = getgrouplist (username, gid, g, &max_n_groups);
/* Some systems (like Darwin) have a bug where they
never increase max_n_groups. */
if (ng < 0 && last_n_groups == max_n_groups)
max_n_groups *= 2;
/* Some systems (like Darwin) have a bug where they
never increase max_n_groups. */
if (ng < 0 && last_n_groups == max_n_groups)
max_n_groups *= 2;
if ((h = realloc_groupbuf (g, max_n_groups)) == NULL)
{
int saved_errno = errno;
free (g);
errno = saved_errno;
return -1;
}
g = h;
if ((h = realloc_groupbuf (g, max_n_groups)) == NULL)
{
int saved_errno = errno;
free (g);
errno = saved_errno;
return -1;
}
g = h;
if (0 <= ng)
{
*groups = g;
/* On success some systems just return 0 from getgrouplist,
so return max_n_groups rather than ng. */
return max_n_groups;
}
}
if (0 <= ng)
{
*groups = g;
/* On success some systems just return 0 from getgrouplist,
so return max_n_groups rather than ng. */
return max_n_groups;
}
}
}
/* else no username, so fall through and use getgroups. */
#endif
max_n_groups = (username
? getugroups (0, NULL, username, gid)
: getgroups (0, NULL));
? getugroups (0, NULL, username, gid)
: getgroups (0, NULL));
/* If we failed to count groups with NULL for a buffer,
try again with a non-NULL one, just in case. */
@@ -126,8 +126,8 @@ mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
return -1;
ng = (username
? getugroups (max_n_groups, g, username, gid)
: getgroups (max_n_groups, g));
? getugroups (max_n_groups, g, username, gid)
: getgroups (max_n_groups, g));
if (ng < 0)
{

View File

@@ -43,7 +43,7 @@
/* This index operation is more efficient on many processors */
#define ind(mm, x) \
(* (uint32_t *) ((char *) (mm) \
+ ((x) & (ISAAC_WORDS - 1) * sizeof (uint32_t))))
+ ((x) & (ISAAC_WORDS - 1) * sizeof (uint32_t))))
/*
* The central step. This uses two temporaries, x and y. mm is the
@@ -191,18 +191,18 @@ isaac_init (struct isaac_state *s, uint32_t const *seed, size_t seedsize)
isaac_mix (s, seed);
/* Second and subsequent passes (extension to ISAAC) */
while (seedsize -= ISAAC_BYTES)
{
seed += ISAAC_WORDS;
for (i = 0; i < ISAAC_WORDS; i++)
s->mm[i] += seed[i];
isaac_mix (s, s->mm);
}
{
seed += ISAAC_WORDS;
for (i = 0; i < ISAAC_WORDS; i++)
s->mm[i] += seed[i];
isaac_mix (s, s->mm);
}
}
else
{
/* The no seed case (as in reference ISAAC code) */
for (i = 0; i < ISAAC_WORDS; i++)
s->mm[i] = 0;
s->mm[i] = 0;
}
/* Final pass */
@@ -252,7 +252,7 @@ isaac_seed_data (struct isaac_state *s, void const *buffer, size_t size)
{
p = (unsigned char *) s->mm + s->c;
for (i = 0; i < avail; i++)
p[i] ^= buf[i];
p[i] ^= buf[i];
buf += avail;
size -= avail;
isaac_mix (s, s->mm);

View File

@@ -128,75 +128,75 @@ randint_genmax (struct randint_source *s, randint genmax)
for (;;)
{
if (randmax < genmax)
{
/* Calculate how many input bytes will be needed, and read
the bytes. */
{
/* Calculate how many input bytes will be needed, and read
the bytes. */
size_t i = 0;
randint rmax = randmax;
unsigned char buf[sizeof randnum];
size_t i = 0;
randint rmax = randmax;
unsigned char buf[sizeof randnum];
do
{
rmax = shift_left (rmax) + UCHAR_MAX;
i++;
}
while (rmax < genmax);
do
{
rmax = shift_left (rmax) + UCHAR_MAX;
i++;
}
while (rmax < genmax);
randread (source, buf, i);
randread (source, buf, i);
/* Increase RANDMAX by appending random bytes to RANDNUM and
UCHAR_MAX to RANDMAX until RANDMAX is no less than
GENMAX. This may lose up to CHAR_BIT bits of information
if shift_right (RANDINT_MAX) < GENMAX, but it is not
worth the programming hassle of saving these bits since
GENMAX is rarely that large in practice. */
/* Increase RANDMAX by appending random bytes to RANDNUM and
UCHAR_MAX to RANDMAX until RANDMAX is no less than
GENMAX. This may lose up to CHAR_BIT bits of information
if shift_right (RANDINT_MAX) < GENMAX, but it is not
worth the programming hassle of saving these bits since
GENMAX is rarely that large in practice. */
i = 0;
i = 0;
do
{
randnum = shift_left (randnum) + buf[i];
randmax = shift_left (randmax) + UCHAR_MAX;
i++;
}
while (randmax < genmax);
}
do
{
randnum = shift_left (randnum) + buf[i];
randmax = shift_left (randmax) + UCHAR_MAX;
i++;
}
while (randmax < genmax);
}
if (randmax == genmax)
{
s->randnum = s->randmax = 0;
return randnum;
}
{
s->randnum = s->randmax = 0;
return randnum;
}
else
{
/* GENMAX < RANDMAX, so attempt to generate a random number
by taking RANDNUM modulo GENMAX+1. This will choose
fairly so long as RANDNUM falls within an integral
multiple of GENMAX+1; otherwise, LAST_USABLE_CHOICE < RANDNUM,
so discard this attempt and try again.
{
/* GENMAX < RANDMAX, so attempt to generate a random number
by taking RANDNUM modulo GENMAX+1. This will choose
fairly so long as RANDNUM falls within an integral
multiple of GENMAX+1; otherwise, LAST_USABLE_CHOICE < RANDNUM,
so discard this attempt and try again.
Since GENMAX cannot be RANDINT_MAX, CHOICES cannot be
zero and there is no need to worry about dividing by
zero. */
Since GENMAX cannot be RANDINT_MAX, CHOICES cannot be
zero and there is no need to worry about dividing by
zero. */
randint excess_choices = randmax - genmax;
randint unusable_choices = excess_choices % choices;
randint last_usable_choice = randmax - unusable_choices;
randint reduced_randnum = randnum % choices;
randint excess_choices = randmax - genmax;
randint unusable_choices = excess_choices % choices;
randint last_usable_choice = randmax - unusable_choices;
randint reduced_randnum = randnum % choices;
if (randnum <= last_usable_choice)
{
s->randnum = randnum / choices;
s->randmax = excess_choices / choices;
return reduced_randnum;
}
if (randnum <= last_usable_choice)
{
s->randnum = randnum / choices;
s->randmax = excess_choices / choices;
return reduced_randnum;
}
/* Retry, but retain the randomness from the fact that RANDNUM fell
into the range LAST_USABLE_CHOICE+1 .. RANDMAX. */
randnum = reduced_randnum;
randmax = unusable_choices - 1;
}
/* Retry, but retain the randomness from the fact that RANDNUM fell
into the range LAST_USABLE_CHOICE+1 .. RANDMAX. */
randnum = reduced_randnum;
randmax = unusable_choices - 1;
}
}
}

View File

@@ -79,21 +79,21 @@ randperm_new (struct randint_source *r, size_t h, size_t n)
default:
{
size_t i;
size_t i;
v = xnmalloc (n, sizeof *v);
for (i = 0; i < n; i++)
v[i] = i;
v = xnmalloc (n, sizeof *v);
for (i = 0; i < n; i++)
v[i] = i;
for (i = 0; i < h; i++)
{
size_t j = i + randint_choose (r, n - i);
size_t t = v[i];
v[i] = v[j];
v[j] = t;
}
for (i = 0; i < h; i++)
{
size_t j = i + randint_choose (r, n - i);
size_t t = v[i];
v[i] = v[j];
v[j] = t;
}
v = xnrealloc (v, h, sizeof *v);
v = xnrealloc (v, h, sizeof *v);
}
break;
}

View File

@@ -100,8 +100,8 @@ struct randread_source
/* Up to a buffer's worth of pseudorandom data. */
union
{
uint32_t w[ISAAC_WORDS];
unsigned char b[ISAAC_BYTES];
uint32_t w[ISAAC_WORDS];
unsigned char b[ISAAC_BYTES];
} data;
} isaac;
} buf;
@@ -115,8 +115,8 @@ randread_error (void const *file_name)
{
if (file_name)
error (exit_failure, errno,
_(errno == 0 ? "%s: end of file" : "%s: read error"),
quotearg_colon (file_name));
_(errno == 0 ? "%s: end of file" : "%s: read error"),
quotearg_colon (file_name));
abort ();
}
@@ -155,18 +155,18 @@ randread_new (char const *name, size_t bytes_bound)
struct randread_source *s;
if (name)
if (! (source = fopen_safer (name, "rb")))
return NULL;
if (! (source = fopen_safer (name, "rb")))
return NULL;
s = simple_new (source, name);
if (source)
setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
else
{
s->buf.isaac.buffered = 0;
isaac_seed (&s->buf.isaac.state);
}
{
s->buf.isaac.buffered = 0;
isaac_seed (&s->buf.isaac.state);
}
return s;
}
@@ -206,7 +206,7 @@ readsource (struct randread_source *s, unsigned char *p, size_t size)
p += inbytes;
size -= inbytes;
if (size == 0)
break;
break;
errno = (ferror (s->source) ? fread_errno : 0);
s->handler (s->handler_arg);
}
@@ -224,34 +224,34 @@ readisaac (struct isaac *isaac, unsigned char *p, size_t size)
for (;;)
{
if (size <= inbytes)
{
memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, size);
isaac->buffered = inbytes - size;
return;
}
{
memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, size);
isaac->buffered = inbytes - size;
return;
}
memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, inbytes);
p += inbytes;
size -= inbytes;
/* If P is aligned, write to *P directly to avoid the overhead
of copying from the buffer. */
of copying from the buffer. */
if (ALIGNED_POINTER (p, uint32_t))
{
uint32_t *wp = (uint32_t *) p;
while (ISAAC_BYTES <= size)
{
isaac_refill (&isaac->state, wp);
wp += ISAAC_WORDS;
size -= ISAAC_BYTES;
if (size == 0)
{
isaac->buffered = 0;
return;
}
}
p = (unsigned char *) wp;
}
{
uint32_t *wp = (uint32_t *) p;
while (ISAAC_BYTES <= size)
{
isaac_refill (&isaac->state, wp);
wp += ISAAC_WORDS;
size -= ISAAC_BYTES;
if (size == 0)
{
isaac->buffered = 0;
return;
}
}
p = (unsigned char *) wp;
}
isaac_refill (&isaac->state, isaac->data.w);
inbytes = ISAAC_BYTES;

View File

@@ -34,12 +34,12 @@ get_root_dev_ino (struct dev_ino *root_d_i);
do \
{ \
if (STREQ (Dirname, "/")) \
error (0, 0, _("it is dangerous to operate recursively on %s"), \
quote (Dirname)); \
error (0, 0, _("it is dangerous to operate recursively on %s"), \
quote (Dirname)); \
else \
error (0, 0, \
_("it is dangerous to operate recursively on %s (same as %s)"), \
quote_n (0, Dirname), quote_n (1, "/")); \
error (0, 0, \
_("it is dangerous to operate recursively on %s (same as %s)"), \
quote_n (0, Dirname), quote_n (1, "/")); \
error (0, 0, _("use --no-preserve-root to override this failsafe")); \
} \
while (0)

View File

@@ -41,8 +41,7 @@
# define TMP_MAX 238328
#endif
#ifndef __GT_FILE
# define __GT_FILE 0
# define __GT_BIGFILE 1
# define __GT_FILE 1
# define __GT_DIR 2
# define __GT_NOCREATE 3
#endif
@@ -61,12 +60,9 @@
#if _LIBC
# define struct_stat64 struct stat64
# define small_open __open
# define large_open __open64
#else
# define struct_stat64 struct stat
# define small_open open
# define large_open open
# define __open open
# define __gen_tempname gen_tempname
# define __getpid getpid
# define __gettimeofday gettimeofday
@@ -96,7 +92,7 @@ direxists (const char *dir)
enough space in TMPL. */
int
__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
int try_tmpdir)
int try_tmpdir)
{
const char *d;
size_t dlen, plen;
@@ -110,30 +106,30 @@ __path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx,
{
plen = strlen (pfx);
if (plen > 5)
plen = 5;
plen = 5;
}
if (try_tmpdir)
{
d = __secure_getenv ("TMPDIR");
if (d != NULL && direxists (d))
dir = d;
dir = d;
else if (dir != NULL && direxists (dir))
/* nothing */ ;
/* nothing */ ;
else
dir = NULL;
dir = NULL;
}
if (dir == NULL)
{
if (direxists (P_tmpdir))
dir = P_tmpdir;
dir = P_tmpdir;
else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp"))
dir = "/tmp";
dir = "/tmp";
else
{
__set_errno (ENOENT);
return -1;
}
{
__set_errno (ENOENT);
return -1;
}
}
dlen = strlen (dir);
@@ -169,15 +165,14 @@ static const char letters[] =
KIND may be one of:
__GT_NOCREATE: simply verify that the name does not exist
at the time of the call.
at the time of the call.
__GT_FILE: create the file using open(O_CREAT|O_EXCL)
and return a read-write fd. The file is mode 0600.
__GT_BIGFILE: same as __GT_FILE but use open64().
and return a read-write fd. The file is mode 0600.
__GT_DIR: create a directory, which will be mode 0700.
We use a clever algorithm to get hard-to-predict names. */
int
gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
gen_tempname_len (char *tmpl, int flags, int kind, size_t x_suffix_len)
{
size_t len;
char *XXXXXX;
@@ -205,7 +200,7 @@ gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
len = strlen (tmpl);
if (len < x_suffix_len || ! check_x_suffix (&tmpl[len - x_suffix_len],
x_suffix_len))
x_suffix_len))
{
__set_errno (EINVAL);
return -1;
@@ -223,60 +218,58 @@ gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
size_t i;
for (i = 0; i < x_suffix_len; i++)
{
XXXXXX[i] = letters[randint_genmax (rand_src, sizeof letters - 2)];
}
{
XXXXXX[i] = letters[randint_genmax (rand_src, sizeof letters - 2)];
}
switch (kind)
{
case __GT_FILE:
fd = small_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
break;
{
case __GT_FILE:
fd = __open (tmpl,
(flags & ~0777) | O_RDWR | O_CREAT | O_EXCL,
S_IRUSR | S_IWUSR);
break;
case __GT_BIGFILE:
fd = large_open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
break;
case __GT_DIR:
fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
break;
case __GT_DIR:
fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR);
break;
case __GT_NOCREATE:
/* This case is backward from the other three. This function
succeeds if __xstat fails because the name does not exist.
Note the continue to bypass the common logic at the bottom
of the loop. */
if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
{
if (errno == ENOENT)
{
__set_errno (save_errno);
fd = 0;
goto done;
}
else
{
/* Give up now. */
fd = -1;
goto done;
}
}
continue;
case __GT_NOCREATE:
/* This case is backward from the other three. This function
succeeds if __xstat fails because the name does not exist.
Note the continue to bypass the common logic at the bottom
of the loop. */
if (__lxstat64 (_STAT_VER, tmpl, &st) < 0)
{
if (errno == ENOENT)
{
__set_errno (save_errno);
fd = 0;
goto done;
}
else
{
/* Give up now. */
fd = -1;
goto done;
}
}
continue;
default:
assert (! "invalid KIND in __gen_tempname");
}
default:
assert (! "invalid KIND in __gen_tempname");
}
if (fd >= 0)
{
__set_errno (save_errno);
goto done;
}
{
__set_errno (save_errno);
goto done;
}
else if (errno != EEXIST)
{
fd = -1;
goto done;
}
{
fd = -1;
goto done;
}
}
randint_all_free (rand_src);
@@ -295,7 +288,7 @@ gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len)
}
int
__gen_tempname (char *tmpl, int kind)
__gen_tempname (char *tmpl, int flags, int kind)
{
return gen_tempname_len (tmpl, kind, 6);
return gen_tempname_len (tmpl, flags, kind, 6);
}

View File

@@ -30,12 +30,13 @@
KIND may be one of:
GT_NOCREATE: simply verify that the name does not exist
at the time of the call.
at the time of the call.
GT_FILE: create a large file using open(O_CREAT|O_EXCL)
and return a read-write fd. The file is mode 0600.
and return a read-write fd. The file is mode 0600.
GT_DIR: create a directory, which will be mode 0700.
We use a clever algorithm to get hard-to-predict names. */
#include <stddef.h>
extern int gen_tempname (char *tmpl, int kind);
extern int gen_tempname_len (char *tmpl, int kind, size_t x_suffix_len);
extern int gen_tempname (char *tmpl, int flags, int kind);
extern int gen_tempname_len (char *tmpl, int flags, int kind,
size_t x_suffix_len);

View File

@@ -31,11 +31,11 @@ xfreopen (char const *filename, char const *mode, FILE *fp)
if (!freopen (filename, mode, fp))
{
char const *f = (filename ? filename
: (fp == stdin ? _("stdin")
: (fp == stdout ? _("stdout")
: (fp == stderr ? _("stderr")
: _("unknown stream")))));
: (fp == stdin ? _("stdin")
: (fp == stdout ? _("stdout")
: (fp == stderr ? _("stderr")
: _("unknown stream")))));
error (exit_failure, errno, _("failed to reopen %s with mode %s"),
quote_n (0, f), quote_n (1, mode));
quote_n (0, f), quote_n (1, mode));
}
}

2
gnulib

Submodule gnulib updated: 3ef64012bf...6f6420cc97

View File

@@ -34,22 +34,22 @@ buffer_lcm (size_t a, size_t b, size_t lcm_max)
else
{
if (b)
{
/* Return lcm (A, B) if it is in range; otherwise, fall back
on A. */
{
/* Return lcm (A, B) if it is in range; otherwise, fall back
on A. */
size_t lcm, m, n, q, r;
size_t lcm, m, n, q, r;
/* N = gcd (A, B). */
for (m = a, n = b; (r = m % n) != 0; m = n, n = r)
continue;
/* N = gcd (A, B). */
for (m = a, n = b; (r = m % n) != 0; m = n, n = r)
continue;
/* LCM = lcm (A, B), if in range. */
q = a / n;
lcm = q * b;
if (lcm <= lcm_max && lcm / b == q)
return lcm;
}
/* LCM = lcm (A, B), if in range. */
q = a / n;
lcm = q * b;
if (lcm <= lcm_max && lcm / b == q)
return lcm;
}
size = a;
}

View File

@@ -25,13 +25,6 @@
#include <unistd.h>
#ifndef F_OK
# define F_OK 0
# define X_OK 1
# define W_OK 2
# define R_OK 4
#endif
#include "group-member.h"
#include "stat-macros.h"
@@ -57,8 +50,8 @@ euidaccess_stat (struct stat const *st, int mode)
mode &= 7;
else
mode = ((mode & R_OK ? 4 : 0)
+ (mode & W_OK ? 2 : 0)
+ (mode & X_OK ? 1 : 0));
+ (mode & W_OK ? 2 : 0)
+ (mode & X_OK ? 1 : 0));
if (mode == 0)
return true; /* The file exists. */
@@ -68,7 +61,7 @@ euidaccess_stat (struct stat const *st, int mode)
/* The super-user can read and write any file, and execute any file
that anyone can execute. */
if (euid == 0 && ((mode & X_OK) == 0
|| (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
|| (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
return true;
/* Convert the file's permission bits to traditional form. */
@@ -84,14 +77,14 @@ euidaccess_stat (struct stat const *st, int mode)
granted = st->st_mode;
else
granted = ( (st->st_mode & S_IRUSR ? 4 << 6 : 0)
+ (st->st_mode & S_IWUSR ? 2 << 6 : 0)
+ (st->st_mode & S_IXUSR ? 1 << 6 : 0)
+ (st->st_mode & S_IRGRP ? 4 << 3 : 0)
+ (st->st_mode & S_IWGRP ? 2 << 3 : 0)
+ (st->st_mode & S_IXGRP ? 1 << 3 : 0)
+ (st->st_mode & S_IROTH ? 4 << 0 : 0)
+ (st->st_mode & S_IWOTH ? 2 << 0 : 0)
+ (st->st_mode & S_IXOTH ? 1 << 0 : 0));
+ (st->st_mode & S_IWUSR ? 2 << 6 : 0)
+ (st->st_mode & S_IXUSR ? 1 << 6 : 0)
+ (st->st_mode & S_IRGRP ? 4 << 3 : 0)
+ (st->st_mode & S_IWGRP ? 2 << 3 : 0)
+ (st->st_mode & S_IXGRP ? 1 << 3 : 0)
+ (st->st_mode & S_IROTH ? 4 << 0 : 0)
+ (st->st_mode & S_IWOTH ? 2 << 0 : 0)
+ (st->st_mode & S_IXOTH ? 1 << 0 : 0));
if (euid == st->st_uid)
granted >>= 6;
@@ -99,7 +92,7 @@ euidaccess_stat (struct stat const *st, int mode)
{
gid_t egid = getegid ();
if (egid == st->st_gid || group_member (st->st_gid))
granted >>= 3;
granted >>= 3;
}
if ((mode & ~granted) == 0)

View File

@@ -1,136 +0,0 @@
/* fdopendir implementation derived from glibc.
Copyright (C) 2006, 2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#if _LIBC
# include <dirstream.h>
# include <not-cancel.h>
#else
# if __GNUC__ < 3
# define __builtin_expect(expr, expected_val) expr
# endif
# include "openat.h"
# define stat64 stat
# define dirent64 dirent
# define __fxstat64(V, fd, sb) fstat(fd, sb)
# define __fcntl fcntl
# define __set_errno(Val) do { errno = (Val); } while (0)
# define __libc_lock_init(NAME) ((NAME) = 0, 0)
# define close_not_cancel_no_status(fd) close (fd)
# ifdef __i386__
# define internal_function __attribute ((regparm (3), stdcall))
# else
# define internal_function
# endif
struct __dirstream
{
int fd; /* File descriptor. */
char *data; /* Directory block. */
size_t allocation; /* Space allocated for the block. */
size_t size; /* Total valid data in the block. */
size_t offset; /* Current offset into the block. */
off_t filepos; /* Position of next entry to read. */
int lock;
};
#endif
#undef _STATBUF_ST_BLKSIZE
static DIR *
internal_function
__alloc_dir (int fd, bool close_fd)
{
if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0)
goto lose;
size_t allocation;
#ifdef _STATBUF_ST_BLKSIZE
if (__builtin_expect ((size_t) statp->st_blksize >= sizeof (struct dirent64),
1))
allocation = statp->st_blksize;
else
#endif
allocation = (BUFSIZ < sizeof (struct dirent64)
? sizeof (struct dirent64) : BUFSIZ);
const int pad = -sizeof (DIR) % __alignof__ (struct dirent64);
DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation + pad);
if (dirp == NULL)
lose:
{
if (close_fd)
{
int save_errno = errno;
close_not_cancel_no_status (fd);
__set_errno (save_errno);
}
return NULL;
}
memset (dirp, '\0', sizeof (DIR));
dirp->data = (char *) (dirp + 1) + pad;
dirp->allocation = allocation;
dirp->fd = fd;
__libc_lock_init (dirp->lock);
return dirp;
}
DIR *
fdopendir (int fd)
{
#if 0
struct stat64 statbuf;
if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &statbuf), 0) < 0)
return NULL;
if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
{
__set_errno (ENOTDIR);
return NULL;
}
/* Make sure the descriptor allows for reading. */
int flags = __fcntl (fd, F_GETFL);
if (__builtin_expect (flags == -1, 0))
return NULL;
if (__builtin_expect ((flags & O_ACCMODE) == O_WRONLY, 0))
{
__set_errno (EINVAL);
return NULL;
}
#endif
return __alloc_dir (fd, false);
}

View File

@@ -40,7 +40,7 @@
size_t
memxfrm (char *restrict dest, size_t destsize,
char *restrict src, size_t srcsize)
char *restrict src, size_t srcsize)
{
#if HAVE_STRXFRM
@@ -59,33 +59,33 @@ memxfrm (char *restrict dest, size_t destsize,
errno = 0;
result += strxfrm (dest + di, src + si, destsize - di) + 1;
if (errno != 0)
break;
break;
if (result <= result0)
{
errno = ERANGE;
break;
}
{
errno = ERANGE;
break;
}
if (result == destsize + 1 && si + slen == srcsize)
{
/* The destination is exactly the right size, but strxfrm wants
room for a trailing null. Work around the problem with a
temporary buffer. */
size_t bufsize = destsize - di + 1;
char stackbuf[4000];
char *buf = stackbuf;
if (sizeof stackbuf < bufsize)
{
buf = malloc (bufsize);
if (! buf)
break;
}
strxfrm (buf, src + si, bufsize);
memcpy (dest + di, buf, destsize - di);
if (sizeof stackbuf < bufsize)
free (buf);
errno = 0;
}
{
/* The destination is exactly the right size, but strxfrm wants
room for a trailing null. Work around the problem with a
temporary buffer. */
size_t bufsize = destsize - di + 1;
char stackbuf[4000];
char *buf = stackbuf;
if (sizeof stackbuf < bufsize)
{
buf = malloc (bufsize);
if (! buf)
break;
}
strxfrm (buf, src + si, bufsize);
memcpy (dest + di, buf, destsize - di);
if (sizeof stackbuf < bufsize)
free (buf);
errno = 0;
}
di = (result < destsize ? result : destsize);
si += slen + 1;

View File

@@ -77,28 +77,28 @@ fraccompare (char const *a, char const *b, char decimal_point)
if (*a == decimal_point && *b == decimal_point)
{
while (*++a == *++b)
if (! ISDIGIT (*a))
return 0;
if (! ISDIGIT (*a))
return 0;
if (ISDIGIT (*a) && ISDIGIT (*b))
return *a - *b;
return *a - *b;
if (ISDIGIT (*a))
goto a_trailing_nonzero;
goto a_trailing_nonzero;
if (ISDIGIT (*b))
goto b_trailing_nonzero;
goto b_trailing_nonzero;
return 0;
}
else if (*a++ == decimal_point)
{
a_trailing_nonzero:
while (*a == NUMERIC_ZERO)
a++;
a++;
return ISDIGIT (*a);
}
else if (*b++ == decimal_point)
{
b_trailing_nonzero:
while (*b == NUMERIC_ZERO)
b++;
b++;
return - ISDIGIT (*b);
}
return 0;
@@ -113,7 +113,7 @@ fraccompare (char const *a, char const *b, char decimal_point)
static inline int
numcompare (char const *a, char const *b,
int decimal_point, int thousands_sep)
int decimal_point, int thousands_sep)
{
unsigned char tmpa = *a;
unsigned char tmpb = *b;
@@ -124,119 +124,119 @@ numcompare (char const *a, char const *b,
if (tmpa == NEGATION_SIGN)
{
do
tmpa = *++a;
tmpa = *++a;
while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep);
if (tmpb != NEGATION_SIGN)
{
if (tmpa == decimal_point)
do
tmpa = *++a;
while (tmpa == NUMERIC_ZERO);
if (ISDIGIT (tmpa))
return -1;
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep)
tmpb = *++b;
if (tmpb == decimal_point)
do
tmpb = *++b;
while (tmpb == NUMERIC_ZERO);
return - ISDIGIT (tmpb);
}
{
if (tmpa == decimal_point)
do
tmpa = *++a;
while (tmpa == NUMERIC_ZERO);
if (ISDIGIT (tmpa))
return -1;
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep)
tmpb = *++b;
if (tmpb == decimal_point)
do
tmpb = *++b;
while (tmpb == NUMERIC_ZERO);
return - ISDIGIT (tmpb);
}
do
tmpb = *++b;
tmpb = *++b;
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep);
while (tmpa == tmpb && ISDIGIT (tmpa))
{
do
tmpa = *++a;
while (tmpa == thousands_sep);
do
tmpb = *++b;
while (tmpb == thousands_sep);
}
{
do
tmpa = *++a;
while (tmpa == thousands_sep);
do
tmpb = *++b;
while (tmpb == thousands_sep);
}
if ((tmpa == decimal_point && !ISDIGIT (tmpb))
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
return fraccompare (b, a, decimal_point);
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
return fraccompare (b, a, decimal_point);
tmp = tmpb - tmpa;
for (log_a = 0; ISDIGIT (tmpa); ++log_a)
do
tmpa = *++a;
while (tmpa == thousands_sep);
do
tmpa = *++a;
while (tmpa == thousands_sep);
for (log_b = 0; ISDIGIT (tmpb); ++log_b)
do
tmpb = *++b;
while (tmpb == thousands_sep);
do
tmpb = *++b;
while (tmpb == thousands_sep);
if (log_a != log_b)
return log_a < log_b ? 1 : -1;
return log_a < log_b ? 1 : -1;
if (!log_a)
return 0;
return 0;
return tmp;
}
else if (tmpb == NEGATION_SIGN)
{
do
tmpb = *++b;
tmpb = *++b;
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep);
if (tmpb == decimal_point)
do
tmpb = *++b;
while (tmpb == NUMERIC_ZERO);
do
tmpb = *++b;
while (tmpb == NUMERIC_ZERO);
if (ISDIGIT (tmpb))
return 1;
return 1;
while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep)
tmpa = *++a;
tmpa = *++a;
if (tmpa == decimal_point)
do
tmpa = *++a;
while (tmpa == NUMERIC_ZERO);
do
tmpa = *++a;
while (tmpa == NUMERIC_ZERO);
return ISDIGIT (tmpa);
}
else
{
while (tmpa == NUMERIC_ZERO || tmpa == thousands_sep)
tmpa = *++a;
tmpa = *++a;
while (tmpb == NUMERIC_ZERO || tmpb == thousands_sep)
tmpb = *++b;
tmpb = *++b;
while (tmpa == tmpb && ISDIGIT (tmpa))
{
do
tmpa = *++a;
while (tmpa == thousands_sep);
do
tmpb = *++b;
while (tmpb == thousands_sep);
}
{
do
tmpa = *++a;
while (tmpa == thousands_sep);
do
tmpb = *++b;
while (tmpb == thousands_sep);
}
if ((tmpa == decimal_point && !ISDIGIT (tmpb))
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
return fraccompare (a, b, decimal_point);
|| (tmpb == decimal_point && !ISDIGIT (tmpa)))
return fraccompare (a, b, decimal_point);
tmp = tmpa - tmpb;
for (log_a = 0; ISDIGIT (tmpa); ++log_a)
do
tmpa = *++a;
while (tmpa == thousands_sep);
do
tmpa = *++a;
while (tmpa == thousands_sep);
for (log_b = 0; ISDIGIT (tmpb); ++log_b)
do
tmpb = *++b;
while (tmpb == thousands_sep);
do
tmpb = *++b;
while (tmpb == thousands_sep);
if (log_a != log_b)
return log_a < log_b ? -1 : 1;
return log_a < log_b ? -1 : 1;
if (!log_a)
return 0;
return 0;
return tmp;
}

View File

@@ -25,7 +25,7 @@
int
strnumcmp (char const *a, char const *b,
int decimal_point, int thousands_sep)
int decimal_point, int thousands_sep)
{
return numcompare (a, b, decimal_point, thousands_sep);
}

View File

@@ -38,10 +38,10 @@ function mkdir_len
( cd $root &&
perl -e 'my $len='$n'-length "'$root'";$i=100;$d="z"x$i;
while ($i+2 < $len) {
$len -= $i + 1;
mkdir $d,0700 or die "$!\n";
chdir $d} $d="z"x($len-1);
mkdir $d or die "mkdir_len: $d: $!\n"' )
$len -= $i + 1;
mkdir $d,0700 or die "$!\n";
chdir $d} $d="z"x($len-1);
mkdir $d or die "mkdir_len: $d: $!\n"' )
}
size_list=

View File

@@ -35,28 +35,28 @@
FTS *
xfts_open (char * const *argv, int options,
int (*compar) (const FTSENT **, const FTSENT **))
int (*compar) (const FTSENT **, const FTSENT **))
{
FTS *fts = fts_open (argv, options | FTS_CWDFD, compar);
if (fts == NULL)
{
/* This can fail in three ways: out of memory, invalid bit_flags,
and one or more of the FILES is an empty string. We could try
to decipher that errno==EINVAL means invalid bit_flags and
errno==ENOENT means there's an empty string, but that seems wrong.
Ideally, fts_open would return a proper error indicator. For now,
we'll presume that the bit_flags are valid and just check for
empty strings. */
and one or more of the FILES is an empty string. We could try
to decipher that errno==EINVAL means invalid bit_flags and
errno==ENOENT means there's an empty string, but that seems wrong.
Ideally, fts_open would return a proper error indicator. For now,
we'll presume that the bit_flags are valid and just check for
empty strings. */
bool invalid_arg = false;
for (; *argv; ++argv)
{
if (**argv == '\0')
invalid_arg = true;
}
{
if (**argv == '\0')
invalid_arg = true;
}
if (invalid_arg)
error (EXIT_FAILURE, 0, _("invalid argument: %s"), quote (""));
error (EXIT_FAILURE, 0, _("invalid argument: %s"), quote (""));
else
xalloc_die ();
xalloc_die ();
}
return fts;

View File

@@ -2,4 +2,4 @@
FTS *
xfts_open (char * const *, int options,
int (*) (const FTSENT **, const FTSENT **));
int (*) (const FTSENT **, const FTSENT **));

View File

@@ -45,7 +45,7 @@
size_t
xmemxfrm (char *restrict dest, size_t destsize,
char *restrict src, size_t srcsize)
char *restrict src, size_t srcsize)
{
size_t translated_size = memxfrm (dest, destsize, src, srcsize);
@@ -54,8 +54,8 @@ xmemxfrm (char *restrict dest, size_t destsize,
error (0, errno, _("string transformation failed"));
error (0, 0, _("set LC_ALL='C' to work around the problem"));
error (exit_failure, 0,
_("the untransformed string was %s"),
quotearg_n_style_mem (0, locale_quoting_style, src, srcsize));
_("the untransformed string was %s"),
quotearg_n_style_mem (0, locale_quoting_style, src, srcsize));
}
return translated_size;

View File

@@ -36,8 +36,8 @@ AC_DEFUN([gl_INCLUDE_EXCLUDE_PROG],
gl_no_install_progs_default=`echo '$2'|sed 's/,/ /g'`
AC_ARG_ENABLE([install-program],
[AS_HELP_STRING([--enable-install-program=PROG_LIST],
[install the programs in PROG_LIST (comma-separated,
default: none)])],
[install the programs in PROG_LIST (comma-separated,
default: none)])],
[gl_do_install_prog=$enableval],
[gl_do_install_prog=]
)
@@ -46,8 +46,8 @@ AC_DEFUN([gl_INCLUDE_EXCLUDE_PROG],
# use --enable-no-install-program=A,B
AC_ARG_ENABLE([no-install-program],
[AS_HELP_STRING([--enable-no-install-program=PROG_LIST],
[do NOT install the programs in PROG_LIST
(comma-separated, default: $2)])],
[do NOT install the programs in PROG_LIST
(comma-separated, default: $2)])],
[gl_no_install_prog=$enableval],
[gl_no_install_prog=]
)
@@ -78,7 +78,7 @@ AC_DEFUN([gl_INCLUDE_EXCLUDE_PROG],
# Warn about a request not to install a program that is
# already on the default-no-install list.
case " $gl_no_install_progs_default " in
*" $gl_i "*) gl_msg="by default, '$gl_i' is not installed" ;;
*" $gl_i "*) gl_msg="by default, '$gl_i' is not installed" ;;
esac
fi

View File

@@ -37,9 +37,9 @@ AC_DEFUN([coreutils_MACROS],
# By default, argmatch should fail calling usage (1).
AC_DEFINE([ARGMATCH_DIE], [usage (1)],
[Define to the function xargmatch calls on failures.])
[Define to the function xargmatch calls on failures.])
AC_DEFINE([ARGMATCH_DIE_DECL], [void usage (int _e)],
[Define to the declaration of the xargmatch failure function.])
[Define to the declaration of the xargmatch failure function.])
# used by ls
AC_REQUIRE([gl_CLOCK_TIME])
@@ -52,13 +52,13 @@ AC_DEFUN([coreutils_MACROS],
AC_CHECK_FUNCS([matchpathcon_init_prefix], [],
[
case "$ac_cv_search_setfilecon:$ac_cv_header_selinux_selinux_h" in
no:*) # SELinux disabled
;;
*:no) # SELinux disabled
;;
*)
AC_MSG_WARN([SELinux enabled, but matchpathcon_init_prefix not found])
AC_MSG_WARN([The install utility may run slowly])
no:*) # SELinux disabled
;;
*:no) # SELinux disabled
;;
*)
AC_MSG_WARN([SELinux enabled, but matchpathcon_init_prefix not found])
AC_MSG_WARN([The install utility may run slowly])
esac
])
LIBS=$coreutils_saved_libs
@@ -98,24 +98,32 @@ AC_DEFUN([coreutils_MACROS],
# for dd.c and shred.c
coreutils_saved_libs=$LIBS
AC_SEARCH_LIBS([fdatasync], [rt posix4],
[test "$ac_cv_search_fdatasync" = "none required" ||
LIB_FDATASYNC=$ac_cv_search_fdatasync])
[test "$ac_cv_search_fdatasync" = "none required" ||
LIB_FDATASYNC=$ac_cv_search_fdatasync])
AC_SUBST([LIB_FDATASYNC])
AC_CHECK_FUNCS([fdatasync])
LIBS=$coreutils_saved_libs
# Check whether libcap is usable -- for ls --color support
LIB_CAP=
AC_ARG_ENABLE([libcap],
AC_HELP_STRING([--disable-libcap], [disable libcap support]),
AC_MSG_WARN([libcap support disabled by user]),
[AC_CHECK_LIB([cap], [cap_get_file],
AC_HELP_STRING([--disable-libcap], [disable libcap support]))
if test "X$enable_libcap" != "Xno"; then
AC_CHECK_LIB([cap], [cap_get_file],
[AC_CHECK_HEADER([sys/capability.h],
[LIB_CAP=-lcap
AC_DEFINE([HAVE_CAP], [1], [libcap usability])],
[AC_MSG_WARN([header sys/capability.h was not found, support for libcap will not be built])]
)],
[AC_MSG_WARN([libcap library was not found or not usable, support for libcap will not be built])])
])
[LIB_CAP=-lcap
AC_DEFINE([HAVE_CAP], [1], [libcap usability])]
)])
if test "X$LIB_CAP" = "X"; then
if test "X$enable_libcap" = "Xyes"; then
AC_MSG_ERROR([libcap library was not found or not usable])
else
AC_MSG_WARN([libcap library was not found or not usable, support for libcap will not be built])
fi
fi
else
AC_MSG_WARN([libcap support disabled by user])
fi
AC_SUBST([LIB_CAP])
# See if linking `seq' requires -lm.

View File

@@ -53,8 +53,8 @@ $ac_includes_default
# NetBSD needs -lcrypt for crypt.
cu_saved_libs="$LIBS"
AC_SEARCH_LIBS([crypt], [ufc crypt],
[test "$ac_cv_search_crypt" = "none required" ||
LIB_CRYPT="$ac_cv_search_crypt"])
[test "$ac_cv_search_crypt" = "none required" ||
LIB_CRYPT="$ac_cv_search_crypt"])
LIBS="$cu_saved_libs"
AC_SUBST([LIB_CRYPT])
])

View File

@@ -57,30 +57,30 @@ AC_INCLUDES_DEFAULT
{ AC_CHECK_MEMBERS([struct statvfs.f_basetype],,, [$statvfs_includes])
test $ac_cv_member_struct_statvfs_f_basetype = yes ||
{ AC_CHECK_MEMBERS([struct statvfs.f_fstypename],,, [$statvfs_includes])
test $ac_cv_member_struct_statvfs_f_fstypename = yes ||
{ test $ac_cv_member_struct_statfs_f_fstypename != yes &&
{ AC_CHECK_MEMBERS([struct statvfs.f_type],,, [$statvfs_includes])
test $ac_cv_member_struct_statvfs_f_type = yes; }; }; }; }
test $ac_cv_member_struct_statvfs_f_fstypename = yes ||
{ test $ac_cv_member_struct_statfs_f_fstypename != yes &&
{ AC_CHECK_MEMBERS([struct statvfs.f_type],,, [$statvfs_includes])
test $ac_cv_member_struct_statvfs_f_type = yes; }; }; }; }
then
AC_CHECK_MEMBERS([struct statvfs.f_namemax],,, [$statvfs_includes])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[$statvfs_includes],
[static statvfs s;
return (s.s_fsid ^ 0) == 0;])],
[$statvfs_includes],
[static statvfs s;
return (s.s_fsid ^ 0) == 0;])],
[AC_DEFINE([STRUCT_STATVFS_F_FSID_IS_INTEGER], [1],
[Define to 1 if the f_fsid member of struct statvfs is an integer.])])
[Define to 1 if the f_fsid member of struct statvfs is an integer.])])
else
AC_CHECK_MEMBERS([struct statfs.f_namelen, struct statfs.f_type],,,
[$statfs_includes])
if test $ac_cv_header_OS_h != yes; then
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[$statfs_includes],
[static statfs s;
return (s.s_fsid ^ 0) == 0;])],
[AC_DEFINE([STRUCT_STATFS_F_FSID_IS_INTEGER], [1],
[Define to 1 if the f_fsid member of struct statfs is an integer.])])
[AC_LANG_PROGRAM(
[$statfs_includes],
[static statfs s;
return (s.s_fsid ^ 0) == 0;])],
[AC_DEFINE([STRUCT_STATFS_F_FSID_IS_INTEGER], [1],
[Define to 1 if the f_fsid member of struct statfs is an integer.])])
fi
fi
])

View File

@@ -11,9 +11,9 @@
AC_DEFUN([gl_FUNC_XATTR],
[
AC_ARG_ENABLE([xattr],
AC_HELP_STRING([--disable-xattr],
[do not support extended attributes]),
[use_xattr=$enableval], [use_xattr=yes])
AC_HELP_STRING([--disable-xattr],
[do not support extended attributes]),
[use_xattr=$enableval], [use_xattr=yes])
if test "$use_xattr" = "yes"; then
AC_CHECK_HEADERS([attr/error_context.h attr/libattr.h])
@@ -24,11 +24,11 @@ AC_DEFUN([gl_FUNC_XATTR],
use_xattr=0
fi
AC_DEFINE_UNQUOTED([USE_XATTR], [$use_xattr],
[Define if you want extended attribute support.])
[Define if you want extended attribute support.])
xattr_saved_LIBS=$LIBS
AC_SEARCH_LIBS([attr_copy_file], [attr],
[test "$ac_cv_search_attr_copy_file" = "none required" ||
LIB_XATTR=$ac_cv_search_attr_copy_file])
[test "$ac_cv_search_attr_copy_file" = "none required" ||
LIB_XATTR=$ac_cv_search_attr_copy_file])
AC_CHECK_FUNCS([attr_copy_file])
LIBS=$xattr_saved_LIBS
AC_SUBST([LIB_XATTR])

View File

@@ -373,6 +373,7 @@ my $PAT_AUTHOR = _('Written +by');
my $PAT_OPTIONS = _('Options');
my $PAT_EXAMPLES = _('Examples');
my $PAT_FREE_SOFTWARE = _('This +is +free +software');
my $PAT_INFO = _('For +complete +documentation');
# Start a new paragraph (if required) for these.
s/([^\n])\n($PAT_BUGS|$PAT_AUTHOR)/$1\n\n$2/og;
@@ -392,6 +393,11 @@ while (length)
$sect = _('EXAMPLES');
next;
}
# Skip any texinfo reference as that's handled separately
if (s/($PAT_INFO).*\n//o)
{
next;
}
# Copyright section
if (/^Copyright +[(\xa9]/)

View File

@@ -504,17 +504,17 @@ Changes in release 4.0:
* ls accepts new options:
--indicator-style=none (no indicators, the default)
--indicator-style=classify (all indicators)
(equivalent to -F or --classify)
(equivalent to -F or --classify)
--indicator-style=file-type (file type indicators)
(equivalent to -p or --file-type)
(equivalent to -p or --file-type)
--quoting-style=literal (do not quote output)
--quoting-style=shell (minimally quote output for the shell)
--quoting-style=shell-always (always quote output with '' for the shell)
--quoting-style=c (quote output as for a C-language string)
(equivalent to -Q or --quote-name)
(equivalent to -Q or --quote-name)
--quoting-style=escape (like c but omit enclosing "")
(equivalent to -b or --escape)
(equivalent to -b or --escape)
--show-control-chars is the opposite of --hide-control-chars
This option can be useful if output is to a terminal,

View File

@@ -20,6 +20,8 @@ lib/regcomp.c
lib/root-dev-ino.h
lib/rpmatch.c
lib/set-mode-acl.c
lib/siglist.h
lib/strsignal.c
lib/unicodeio.c
lib/userspec.c
lib/verror.c

View File

@@ -385,21 +385,21 @@ pr = progs-readme
check: check-README check-duplicate-no-install
.PHONY: check-README
check-README:
rm -rf $(pr) $(pm)
echo $(all_programs) \
$(AM_V_GEN)rm -rf $(pr) $(pm)
$(AM_V_at)echo $(all_programs) \
| tr -s ' ' '\n' | sed -e 's,$(EXEEXT)$$,,;s/ginstall/install/' \
| sed /libstdbuf/d \
| $(ASSORT) -u > $(pm) && \
sed -n '/^The programs .* are:/,/^[a-zA-Z]/p' $(top_srcdir)/README \
| sed -n '/^ */s///p' | tr -s ' ' '\n' > $(pr)
diff $(pm) $(pr) && rm -rf $(pr) $(pm)
$(AM_V_at)diff $(pm) $(pr) && rm -rf $(pr) $(pm)
# Ensure that a by-default-not-installed program (listed in
# $(no_install__progs) is not also listed in $(EXTRA_PROGRAMS), because
# if that were to happen, it *would* be installed by default.
.PHONY: check-duplicate-no-install
check-duplicate-no-install: tr
test -z "`echo '$(EXTRA_PROGRAMS)'| ./tr ' ' '\n' | uniq -d`"
$(AM_V_GEN)test -z "`echo '$(EXTRA_PROGRAMS)'| ./tr ' ' '\n' | uniq -d`"
# Ensure that the list of programs and author names is accurate.
# We need a UTF8 locale. If a lack of locale support or a missing
@@ -453,7 +453,7 @@ sc_tight_scope: $(bin_PROGRAMS)
( printf 'main\nusage\n_.*\n'; \
grep -h -A1 '^extern .*[^;]$$' $$src \
| grep -vE '^(extern |--)' | sed 's/ .*//'; \
perl -ne '/^extern \S+ (\S*) \(/ and print "$$1\n"' $$hdr; \
perl -ne '/^extern (?:enum )?\S+ (\S*) \(/ and print "$$1\n"' $$hdr; \
) | $(ASSORT) -u | sed 's/^/^/;s/$$/$$/' > $$t; \
nm -e *.$(OBJEXT) \
| sed -n 's/.* T //p' \

View File

@@ -53,7 +53,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -80,8 +80,8 @@ The data are encoded as described for the base64 alphabet in RFC 3548.\n\
When decoding, the input may contain newlines in addition to the bytes of\n\
the formal base64 alphabet. Use --ignore-garbage to attempt to recover\n\
from any other non-alphabet bytes in the encoded stream.\n"),
stdout);
emit_bug_reporting_address ();
stdout);
emit_ancillary_info ();
}
exit (status);
@@ -99,7 +99,7 @@ from any other non-alphabet bytes in the encoded stream.\n"),
static void
wrap_write (const char *buffer, size_t len,
uintmax_t wrap_column, size_t *current_column, FILE *out)
uintmax_t wrap_column, size_t *current_column, FILE *out)
{
size_t written;
@@ -107,28 +107,28 @@ wrap_write (const char *buffer, size_t len,
{
/* Simple write. */
if (fwrite (buffer, 1, len, stdout) < len)
error (EXIT_FAILURE, errno, _("write error"));
error (EXIT_FAILURE, errno, _("write error"));
}
else
for (written = 0; written < len;)
{
uintmax_t cols_remaining = wrap_column - *current_column;
size_t to_write = MIN (cols_remaining, SIZE_MAX);
to_write = MIN (to_write, len - written);
uintmax_t cols_remaining = wrap_column - *current_column;
size_t to_write = MIN (cols_remaining, SIZE_MAX);
to_write = MIN (to_write, len - written);
if (to_write == 0)
{
if (fputs ("\n", out) < 0)
error (EXIT_FAILURE, errno, _("write error"));
*current_column = 0;
}
else
{
if (fwrite (buffer + written, 1, to_write, stdout) < to_write)
error (EXIT_FAILURE, errno, _("write error"));
*current_column += to_write;
written += to_write;
}
if (to_write == 0)
{
if (fputs ("\n", out) < 0)
error (EXIT_FAILURE, errno, _("write error"));
*current_column = 0;
}
else
{
if (fwrite (buffer + written, 1, to_write, stdout) < to_write)
error (EXIT_FAILURE, errno, _("write error"));
*current_column += to_write;
written += to_write;
}
}
}
@@ -146,21 +146,21 @@ do_encode (FILE *in, FILE *out, uintmax_t wrap_column)
sum = 0;
do
{
n = fread (inbuf + sum, 1, BLOCKSIZE - sum, in);
sum += n;
}
{
n = fread (inbuf + sum, 1, BLOCKSIZE - sum, in);
sum += n;
}
while (!feof (in) && !ferror (in) && sum < BLOCKSIZE);
if (sum > 0)
{
/* Process input one block at a time. Note that BLOCKSIZE %
3 == 0, so that no base64 pads will appear in output. */
base64_encode (inbuf, sum, outbuf, BASE64_LENGTH (sum));
{
/* Process input one block at a time. Note that BLOCKSIZE %
3 == 0, so that no base64 pads will appear in output. */
base64_encode (inbuf, sum, outbuf, BASE64_LENGTH (sum));
wrap_write (outbuf, BASE64_LENGTH (sum), wrap_column,
&current_column, out);
}
wrap_write (outbuf, BASE64_LENGTH (sum), wrap_column,
&current_column, out);
}
}
while (!feof (in) && !ferror (in) && sum == BLOCKSIZE);
@@ -190,43 +190,43 @@ do_decode (FILE *in, FILE *out, bool ignore_garbage)
sum = 0;
do
{
n = fread (inbuf + sum, 1, B64BLOCKSIZE - sum, in);
{
n = fread (inbuf + sum, 1, B64BLOCKSIZE - sum, in);
if (ignore_garbage)
{
size_t i;
for (i = 0; n > 0 && i < n;)
if (isbase64 (inbuf[sum + i]) || inbuf[sum + i] == '=')
i++;
else
memmove (inbuf + sum + i, inbuf + sum + i + 1, --n - i);
}
if (ignore_garbage)
{
size_t i;
for (i = 0; n > 0 && i < n;)
if (isbase64 (inbuf[sum + i]) || inbuf[sum + i] == '=')
i++;
else
memmove (inbuf + sum + i, inbuf + sum + i + 1, --n - i);
}
sum += n;
sum += n;
if (ferror (in))
error (EXIT_FAILURE, errno, _("read error"));
}
if (ferror (in))
error (EXIT_FAILURE, errno, _("read error"));
}
while (sum < B64BLOCKSIZE && !feof (in));
/* The following "loop" is usually iterated just once.
However, when it processes the final input buffer, we want
to iterate it one additional time, but with an indicator
telling it to flush what is in CTX. */
However, when it processes the final input buffer, we want
to iterate it one additional time, but with an indicator
telling it to flush what is in CTX. */
for (k = 0; k < 1 + !!feof (in); k++)
{
if (k == 1 && ctx.i == 0)
break;
n = BLOCKSIZE;
ok = base64_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n);
{
if (k == 1 && ctx.i == 0)
break;
n = BLOCKSIZE;
ok = base64_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n);
if (fwrite (outbuf, 1, n, out) < n)
error (EXIT_FAILURE, errno, _("write error"));
if (fwrite (outbuf, 1, n, out) < n)
error (EXIT_FAILURE, errno, _("write error"));
if (!ok)
error (EXIT_FAILURE, 0, _("invalid input"));
}
if (!ok)
error (EXIT_FAILURE, 0, _("invalid input"));
}
}
while (!feof (in));
}
@@ -257,26 +257,26 @@ main (int argc, char **argv)
switch (opt)
{
case 'd':
decode = true;
break;
decode = true;
break;
case 'w':
if (xstrtoumax (optarg, NULL, 0, &wrap_column, NULL) != LONGINT_OK)
error (EXIT_FAILURE, 0, _("invalid wrap size: %s"),
quotearg (optarg));
break;
if (xstrtoumax (optarg, NULL, 0, &wrap_column, NULL) != LONGINT_OK)
error (EXIT_FAILURE, 0, _("invalid wrap size: %s"),
quotearg (optarg));
break;
case 'i':
ignore_garbage = true;
break;
ignore_garbage = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
break;
usage (EXIT_FAILURE);
break;
}
if (argc - optind > 1)
@@ -296,7 +296,7 @@ main (int argc, char **argv)
{
input_fh = fopen (infile, "r");
if (input_fh == NULL)
error (EXIT_FAILURE, errno, "%s", infile);
error (EXIT_FAILURE, errno, "%s", infile);
}
if (decode)
@@ -307,9 +307,9 @@ main (int argc, char **argv)
if (fclose (input_fh) == EOF)
{
if (STREQ (infile, "-"))
error (EXIT_FAILURE, errno, _("closing standard input"));
error (EXIT_FAILURE, errno, _("closing standard input"));
else
error (EXIT_FAILURE, errno, "%s", infile);
error (EXIT_FAILURE, errno, "%s", infile);
}
exit (EXIT_SUCCESS);

View File

@@ -44,14 +44,14 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s NAME [SUFFIX]\n\
or: %s OPTION\n\
"),
program_name, program_name);
program_name, program_name);
fputs (_("\
Print NAME with any leading directory components removed.\n\
If specified, also remove a trailing SUFFIX.\n\
@@ -65,8 +65,8 @@ Examples:\n\
%s /usr/bin/sort Output \"sort\".\n\
%s include/stdio.h .h Output \"stdio\".\n\
"),
program_name, program_name);
emit_bug_reporting_address ();
program_name, program_name);
emit_ancillary_info ();
}
exit (status);
}
@@ -104,7 +104,7 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
usage, AUTHORS, (char const *) NULL);
usage, AUTHORS, (char const *) NULL);
if (getopt_long (argc, argv, "+", NULL, NULL) != -1)
usage (EXIT_FAILURE);

View File

@@ -43,21 +43,21 @@ diff -upr src/remove.c src/remove.c
&& ((x->interactive == RMI_ALWAYS) || x->stdin_tty)
&& dirent_type != DT_LNK)
@@ -889,6 +890,7 @@ prompt (int fd_cwd, Dirstack_state const
break;
}
break;
}
+ {
char const *quoted_name = quote (full_filename (filename));
if (write_protected < 0)
@@ -928,6 +930,7 @@ prompt (int fd_cwd, Dirstack_state const
: _("%s: remove %s %s? ")),
program_name, file_type (sbuf), quoted_name);
}
: _("%s: remove %s %s? ")),
program_name, file_type (sbuf), quoted_name);
}
+ }
if (!yesno ())
return RM_USER_DECLINED;
return RM_USER_DECLINED;
@@ -1547,6 +1550,7 @@ rm_1 (Dirstack_state *ds, char const *fi
return RM_ERROR;
}
@@ -72,7 +72,7 @@ diff -upr src/remove.c src/remove.c
+ {
enum RM_status status = remove_entry (AT_FDCWD, ds, filename,
DT_UNKNOWN, &st, x);
DT_UNKNOWN, &st, x);
if (status == RM_NONEMPTY_DIR)
@@ -1587,6 +1592,8 @@ rm_1 (Dirstack_state *ds, char const *fi
ds_clear (ds);
@@ -87,7 +87,7 @@ diff -upr src/rm.c src/rm.c
--- src/rm.c 1970-01-01 00:00:00.000000000 +0000
+++ src/rm.c 1970-01-01 00:00:00.000000000 +0000
@@ -354,6 +354,7 @@ main (int argc, char **argv)
quote ("/"));
quote ("/"));
}
+ {
@@ -96,7 +96,7 @@ diff -upr src/rm.c src/rm.c
@@ -367,7 +368,10 @@ main (int argc, char **argv)
if (!yesno ())
exit (EXIT_SUCCESS);
exit (EXIT_SUCCESS);
}
+ {
enum RM_status status = rm (n_files, file, &x);
@@ -109,37 +109,37 @@ diff -upr src/seq.c src/seq.c
--- src/seq.c 1970-01-01 00:00:00.000000000 +0000
+++ src/seq.c 1970-01-01 00:00:00.000000000 +0000
@@ -163,6 +163,7 @@ scan_arg (const char *arg)
: (decimal_point == arg /* .# -> 0.# */
|| ! ISDIGIT (decimal_point[-1]))); /* -.# -> 0.# */
}
: (decimal_point == arg /* .# -> 0.# */
|| ! ISDIGIT (decimal_point[-1]))); /* -.# -> 0.# */
}
+ {
char const *e = strchr (arg, 'e');
if (! e)
e = strchr (arg, 'E');
e = strchr (arg, 'E');
@@ -171,6 +172,7 @@ scan_arg (const char *arg)
long exponent = strtol (e + 1, NULL, 10);
ret.precision += exponent < 0 ? -exponent : 0;
}
long exponent = strtol (e + 1, NULL, 10);
ret.precision += exponent < 0 ? -exponent : 0;
}
+ }
}
return ret;
@@ -346,6 +348,7 @@ get_default_format (operand first, opera
size_t last_width = last.width + (prec - last.precision);
if (last.precision && prec == 0)
last_width--; /* don't include space for '.' */
size_t last_width = last.width + (prec - last.precision);
if (last.precision && prec == 0)
last_width--; /* don't include space for '.' */
+ {
size_t width = MAX (first_width, last_width);
if (width <= INT_MAX)
{
size_t width = MAX (first_width, last_width);
if (width <= INT_MAX)
{
@@ -353,6 +356,7 @@ get_default_format (operand first, opera
sprintf (format_buf, "%%0%d.%dLf", w, prec);
return format_buf;
}
sprintf (format_buf, "%%0%d.%dLf", w, prec);
return format_buf;
}
+ }
}
}
else
{
{
@@ -441,6 +445,7 @@ main (int argc, char **argv)
if (format_str)
{
@@ -147,10 +147,10 @@ diff -upr src/seq.c src/seq.c
+ {
char const *f = long_double_format (format_str, &layout);
if (! f)
{
{
@@ -448,6 +453,7 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
usage (EXIT_FAILURE);
}
format_str = f;
+ }
}
@@ -160,11 +160,11 @@ diff -upr src/shred.c src/shred.c
--- src/shred.c 1970-01-01 00:00:00.000000000 +0000
+++ src/shred.c 1970-01-01 00:00:00.000000000 +0000
@@ -468,7 +468,7 @@ dopass (int fd, char const *qname, off_t
out. Thus, it shouldn't give up on bad blocks. This
code works because lim is always a multiple of
SECTOR_SIZE, except at the end. */
out. Thus, it shouldn't give up on bad blocks. This
code works because lim is always a multiple of
SECTOR_SIZE, except at the end. */
- verify (sizeof r % SECTOR_SIZE == 0);
+ { verify (sizeof r % SECTOR_SIZE == 0); }
if (errnum == EIO && 0 <= size && (soff | SECTOR_MASK) < lim)
{
size_t soff1 = (soff | SECTOR_MASK) + 1;
if (errnum == EIO && 0 <= size && (soff | SECTOR_MASK) < lim)
{
size_t soff1 = (soff | SECTOR_MASK) + 1;

626
src/cat.c
View File

@@ -83,13 +83,13 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
"),
program_name);
program_name);
fputs (_("\
Concatenate FILE(s), or standard input, to standard output.\n\
\n\
@@ -118,8 +118,8 @@ Examples:\n\
%s f - g Output f's contents, then standard input, then g's contents.\n\
%s Copy standard input to standard output.\n\
"),
program_name, program_name);
emit_bug_reporting_address ();
program_name, program_name);
emit_ancillary_info ();
}
exit (status);
}
@@ -133,7 +133,7 @@ next_line_num (void)
do
{
if ((*endp)++ < '9')
return;
return;
*endp-- = '0';
}
while (endp >= line_num_start);
@@ -168,23 +168,23 @@ simple_cat (
n_read = safe_read (input_desc, buf, bufsize);
if (n_read == SAFE_READ_ERROR)
{
error (0, errno, "%s", infile);
return false;
}
{
error (0, errno, "%s", infile);
return false;
}
/* End of this file? */
if (n_read == 0)
return true;
return true;
/* Write this block out. */
{
/* The following is ok, since we know that 0 < n_read. */
size_t n = n_read;
if (full_write (STDOUT_FILENO, buf, n) != n)
error (EXIT_FAILURE, errno, _("write error"));
/* The following is ok, since we know that 0 < n_read. */
size_t n = n_read;
if (full_write (STDOUT_FILENO, buf, n) != n)
error (EXIT_FAILURE, errno, _("write error"));
}
}
}
@@ -274,227 +274,227 @@ cat (
for (;;)
{
do
{
/* Write if there are at least OUTSIZE bytes in OUTBUF. */
{
/* Write if there are at least OUTSIZE bytes in OUTBUF. */
if (outbuf + outsize <= bpout)
{
char *wp = outbuf;
size_t remaining_bytes;
do
{
if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
error (EXIT_FAILURE, errno, _("write error"));
wp += outsize;
remaining_bytes = bpout - wp;
}
while (outsize <= remaining_bytes);
if (outbuf + outsize <= bpout)
{
char *wp = outbuf;
size_t remaining_bytes;
do
{
if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
error (EXIT_FAILURE, errno, _("write error"));
wp += outsize;
remaining_bytes = bpout - wp;
}
while (outsize <= remaining_bytes);
/* Move the remaining bytes to the beginning of the
buffer. */
/* Move the remaining bytes to the beginning of the
buffer. */
memmove (outbuf, wp, remaining_bytes);
bpout = outbuf + remaining_bytes;
}
memmove (outbuf, wp, remaining_bytes);
bpout = outbuf + remaining_bytes;
}
/* Is INBUF empty? */
/* Is INBUF empty? */
if (bpin > eob)
{
bool input_pending = false;
if (bpin > eob)
{
bool input_pending = false;
#ifdef FIONREAD
int n_to_read = 0;
int n_to_read = 0;
/* Is there any input to read immediately?
If not, we are about to wait,
so write all buffered output before waiting. */
/* Is there any input to read immediately?
If not, we are about to wait,
so write all buffered output before waiting. */
if (use_fionread
&& ioctl (input_desc, FIONREAD, &n_to_read) < 0)
{
/* Ultrix returns EOPNOTSUPP on NFS;
HP-UX returns ENOTTY on pipes.
SunOS returns EINVAL and
More/BSD returns ENODEV on special files
like /dev/null.
Irix-5 returns ENOSYS on pipes. */
if (errno == EOPNOTSUPP || errno == ENOTTY
|| errno == EINVAL || errno == ENODEV
|| errno == ENOSYS)
use_fionread = false;
else
{
error (0, errno, _("cannot do ioctl on %s"), quote (infile));
newlines2 = newlines;
return false;
}
}
if (n_to_read != 0)
input_pending = true;
if (use_fionread
&& ioctl (input_desc, FIONREAD, &n_to_read) < 0)
{
/* Ultrix returns EOPNOTSUPP on NFS;
HP-UX returns ENOTTY on pipes.
SunOS returns EINVAL and
More/BSD returns ENODEV on special files
like /dev/null.
Irix-5 returns ENOSYS on pipes. */
if (errno == EOPNOTSUPP || errno == ENOTTY
|| errno == EINVAL || errno == ENODEV
|| errno == ENOSYS)
use_fionread = false;
else
{
error (0, errno, _("cannot do ioctl on %s"), quote (infile));
newlines2 = newlines;
return false;
}
}
if (n_to_read != 0)
input_pending = true;
#endif
if (!input_pending)
write_pending (outbuf, &bpout);
if (!input_pending)
write_pending (outbuf, &bpout);
/* Read more input into INBUF. */
/* Read more input into INBUF. */
n_read = safe_read (input_desc, inbuf, insize);
if (n_read == SAFE_READ_ERROR)
{
error (0, errno, "%s", infile);
write_pending (outbuf, &bpout);
newlines2 = newlines;
return false;
}
if (n_read == 0)
{
write_pending (outbuf, &bpout);
newlines2 = newlines;
return true;
}
n_read = safe_read (input_desc, inbuf, insize);
if (n_read == SAFE_READ_ERROR)
{
error (0, errno, "%s", infile);
write_pending (outbuf, &bpout);
newlines2 = newlines;
return false;
}
if (n_read == 0)
{
write_pending (outbuf, &bpout);
newlines2 = newlines;
return true;
}
/* Update the pointers and insert a sentinel at the buffer
end. */
/* Update the pointers and insert a sentinel at the buffer
end. */
bpin = inbuf;
eob = bpin + n_read;
*eob = '\n';
}
else
{
/* It was a real (not a sentinel) newline. */
bpin = inbuf;
eob = bpin + n_read;
*eob = '\n';
}
else
{
/* It was a real (not a sentinel) newline. */
/* Was the last line empty?
(i.e. have two or more consecutive newlines been read?) */
/* Was the last line empty?
(i.e. have two or more consecutive newlines been read?) */
if (++newlines > 0)
{
if (newlines >= 2)
{
/* Limit this to 2 here. Otherwise, with lots of
consecutive newlines, the counter could wrap
around at INT_MAX. */
newlines = 2;
if (++newlines > 0)
{
if (newlines >= 2)
{
/* Limit this to 2 here. Otherwise, with lots of
consecutive newlines, the counter could wrap
around at INT_MAX. */
newlines = 2;
/* Are multiple adjacent empty lines to be substituted
by single ditto (-s), and this was the second empty
line? */
if (squeeze_blank)
{
ch = *bpin++;
continue;
}
}
/* Are multiple adjacent empty lines to be substituted
by single ditto (-s), and this was the second empty
line? */
if (squeeze_blank)
{
ch = *bpin++;
continue;
}
}
/* Are line numbers to be written at empty lines (-n)? */
/* Are line numbers to be written at empty lines (-n)? */
if (number & !number_nonblank)
{
next_line_num ();
bpout = stpcpy (bpout, line_num_print);
}
}
if (number && !number_nonblank)
{
next_line_num ();
bpout = stpcpy (bpout, line_num_print);
}
}
/* Output a currency symbol if requested (-e). */
/* Output a currency symbol if requested (-e). */
if (show_ends)
*bpout++ = '$';
if (show_ends)
*bpout++ = '$';
/* Output the newline. */
/* Output the newline. */
*bpout++ = '\n';
}
ch = *bpin++;
}
*bpout++ = '\n';
}
ch = *bpin++;
}
while (ch == '\n');
/* Are we at the beginning of a line, and line numbers are requested? */
if (newlines >= 0 && number)
{
next_line_num ();
bpout = stpcpy (bpout, line_num_print);
}
{
next_line_num ();
bpout = stpcpy (bpout, line_num_print);
}
/* Here CH cannot contain a newline character. */
/* The loops below continue until a newline character is found,
which means that the buffer is empty or that a proper newline
has been found. */
which means that the buffer is empty or that a proper newline
has been found. */
/* If quoting, i.e. at least one of -v, -e, or -t specified,
scan for chars that need conversion. */
scan for chars that need conversion. */
if (show_nonprinting)
{
for (;;)
{
if (ch >= 32)
{
if (ch < 127)
*bpout++ = ch;
else if (ch == 127)
{
*bpout++ = '^';
*bpout++ = '?';
}
else
{
*bpout++ = 'M';
*bpout++ = '-';
if (ch >= 128 + 32)
{
if (ch < 128 + 127)
*bpout++ = ch - 128;
else
{
*bpout++ = '^';
*bpout++ = '?';
}
}
else
{
*bpout++ = '^';
*bpout++ = ch - 128 + 64;
}
}
}
else if (ch == '\t' && !show_tabs)
*bpout++ = '\t';
else if (ch == '\n')
{
newlines = -1;
break;
}
else
{
*bpout++ = '^';
*bpout++ = ch + 64;
}
{
for (;;)
{
if (ch >= 32)
{
if (ch < 127)
*bpout++ = ch;
else if (ch == 127)
{
*bpout++ = '^';
*bpout++ = '?';
}
else
{
*bpout++ = 'M';
*bpout++ = '-';
if (ch >= 128 + 32)
{
if (ch < 128 + 127)
*bpout++ = ch - 128;
else
{
*bpout++ = '^';
*bpout++ = '?';
}
}
else
{
*bpout++ = '^';
*bpout++ = ch - 128 + 64;
}
}
}
else if (ch == '\t' && !show_tabs)
*bpout++ = '\t';
else if (ch == '\n')
{
newlines = -1;
break;
}
else
{
*bpout++ = '^';
*bpout++ = ch + 64;
}
ch = *bpin++;
}
}
ch = *bpin++;
}
}
else
{
/* Not quoting, neither of -v, -e, or -t specified. */
for (;;)
{
if (ch == '\t' && show_tabs)
{
*bpout++ = '^';
*bpout++ = ch + 64;
}
else if (ch != '\n')
*bpout++ = ch;
else
{
newlines = -1;
break;
}
{
/* Not quoting, neither of -v, -e, or -t specified. */
for (;;)
{
if (ch == '\t' && show_tabs)
{
*bpout++ = '^';
*bpout++ = ch + 64;
}
else if (ch != '\n')
*bpout++ = ch;
else
{
newlines = -1;
break;
}
ch = *bpin++;
}
}
ch = *bpin++;
}
}
}
}
@@ -573,62 +573,62 @@ main (int argc, char **argv)
/* Parse command line options. */
while ((c = getopt_long (argc, argv, "benstuvAET", long_options, NULL))
!= -1)
!= -1)
{
switch (c)
{
case 'b':
number = true;
number_nonblank = true;
break;
{
case 'b':
number = true;
number_nonblank = true;
break;
case 'e':
show_ends = true;
show_nonprinting = true;
break;
case 'e':
show_ends = true;
show_nonprinting = true;
break;
case 'n':
number = true;
break;
case 'n':
number = true;
break;
case 's':
squeeze_blank = true;
break;
case 's':
squeeze_blank = true;
break;
case 't':
show_tabs = true;
show_nonprinting = true;
break;
case 't':
show_tabs = true;
show_nonprinting = true;
break;
case 'u':
/* We provide the -u feature unconditionally. */
break;
case 'u':
/* We provide the -u feature unconditionally. */
break;
case 'v':
show_nonprinting = true;
break;
case 'v':
show_nonprinting = true;
break;
case 'A':
show_nonprinting = true;
show_ends = true;
show_tabs = true;
break;
case 'A':
show_nonprinting = true;
show_ends = true;
show_tabs = true;
break;
case 'E':
show_ends = true;
break;
case 'E':
show_ends = true;
break;
case 'T':
show_tabs = true;
break;
case 'T':
show_tabs = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
default:
usage (EXIT_FAILURE);
}
}
/* Get device, i-node number, and optimal blocksize of output. */
@@ -657,11 +657,11 @@ main (int argc, char **argv)
#endif
}
if (! (number | show_ends | squeeze_blank))
if (! (number || show_ends || squeeze_blank))
{
file_open_mode |= O_BINARY;
if (O_BINARY && ! isatty (STDOUT_FILENO))
xfreopen (NULL, "wb", stdout);
xfreopen (NULL, "wb", stdout);
}
/* Check if any of the input files are the same as the output file. */
@@ -674,104 +674,104 @@ main (int argc, char **argv)
do
{
if (argind < argc)
infile = argv[argind];
infile = argv[argind];
if (STREQ (infile, "-"))
{
have_read_stdin = true;
input_desc = STDIN_FILENO;
if ((file_open_mode & O_BINARY) && ! isatty (STDIN_FILENO))
xfreopen (NULL, "rb", stdin);
}
{
have_read_stdin = true;
input_desc = STDIN_FILENO;
if ((file_open_mode & O_BINARY) && ! isatty (STDIN_FILENO))
xfreopen (NULL, "rb", stdin);
}
else
{
input_desc = open (infile, file_open_mode);
if (input_desc < 0)
{
error (0, errno, "%s", infile);
ok = false;
continue;
}
}
{
input_desc = open (infile, file_open_mode);
if (input_desc < 0)
{
error (0, errno, "%s", infile);
ok = false;
continue;
}
}
if (fstat (input_desc, &stat_buf) < 0)
{
error (0, errno, "%s", infile);
ok = false;
goto contin;
}
{
error (0, errno, "%s", infile);
ok = false;
goto contin;
}
insize = io_blksize (stat_buf);
/* Compare the device and i-node numbers of this input file with
the corresponding values of the (output file associated with)
stdout, and skip this input file if they coincide. Input
files cannot be redirected to themselves. */
the corresponding values of the (output file associated with)
stdout, and skip this input file if they coincide. Input
files cannot be redirected to themselves. */
if (check_redirection
&& stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino
&& (input_desc != STDIN_FILENO))
{
error (0, 0, _("%s: input file is output file"), infile);
ok = false;
goto contin;
}
&& stat_buf.st_dev == out_dev && stat_buf.st_ino == out_ino
&& (input_desc != STDIN_FILENO))
{
error (0, 0, _("%s: input file is output file"), infile);
ok = false;
goto contin;
}
/* Select which version of `cat' to use. If any format-oriented
options were given use `cat'; otherwise use `simple_cat'. */
options were given use `cat'; otherwise use `simple_cat'. */
if (! (number | show_ends | show_nonprinting
| show_tabs | squeeze_blank))
{
insize = MAX (insize, outsize);
inbuf = xmalloc (insize + page_size - 1);
if (! (number || show_ends || show_nonprinting
|| show_tabs || squeeze_blank))
{
insize = MAX (insize, outsize);
inbuf = xmalloc (insize + page_size - 1);
ok &= simple_cat (ptr_align (inbuf, page_size), insize);
}
ok &= simple_cat (ptr_align (inbuf, page_size), insize);
}
else
{
inbuf = xmalloc (insize + 1 + page_size - 1);
{
inbuf = xmalloc (insize + 1 + page_size - 1);
/* Why are
(OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN + PAGE_SIZE - 1)
bytes allocated for the output buffer?
/* Why are
(OUTSIZE - 1 + INSIZE * 4 + LINE_COUNTER_BUF_LEN + PAGE_SIZE - 1)
bytes allocated for the output buffer?
A test whether output needs to be written is done when the input
buffer empties or when a newline appears in the input. After
output is written, at most (OUTSIZE - 1) bytes will remain in the
buffer. Now INSIZE bytes of input is read. Each input character
may grow by a factor of 4 (by the prepending of M-^). If all
characters do, and no newlines appear in this block of input, we
will have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.
If the last character in the preceding block of input was a
newline, a line number may be written (according to the given
options) as the first thing in the output buffer. (Done after the
new input is read, but before processing of the input begins.)
A line number requires seldom more than LINE_COUNTER_BUF_LEN
positions.
A test whether output needs to be written is done when the input
buffer empties or when a newline appears in the input. After
output is written, at most (OUTSIZE - 1) bytes will remain in the
buffer. Now INSIZE bytes of input is read. Each input character
may grow by a factor of 4 (by the prepending of M-^). If all
characters do, and no newlines appear in this block of input, we
will have at most (OUTSIZE - 1 + INSIZE * 4) bytes in the buffer.
If the last character in the preceding block of input was a
newline, a line number may be written (according to the given
options) as the first thing in the output buffer. (Done after the
new input is read, but before processing of the input begins.)
A line number requires seldom more than LINE_COUNTER_BUF_LEN
positions.
Align the output buffer to a page size boundary, for efficency on
some paging implementations, so add PAGE_SIZE - 1 bytes to the
request to make room for the alignment. */
Align the output buffer to a page size boundary, for efficency on
some paging implementations, so add PAGE_SIZE - 1 bytes to the
request to make room for the alignment. */
outbuf = xmalloc (outsize - 1 + insize * 4 + LINE_COUNTER_BUF_LEN
+ page_size - 1);
outbuf = xmalloc (outsize - 1 + insize * 4 + LINE_COUNTER_BUF_LEN
+ page_size - 1);
ok &= cat (ptr_align (inbuf, page_size), insize,
ptr_align (outbuf, page_size), outsize, show_nonprinting,
show_tabs, number, number_nonblank, show_ends,
squeeze_blank);
ok &= cat (ptr_align (inbuf, page_size), insize,
ptr_align (outbuf, page_size), outsize, show_nonprinting,
show_tabs, number, number_nonblank, show_ends,
squeeze_blank);
free (outbuf);
}
free (outbuf);
}
free (inbuf);
contin:
if (!STREQ (infile, "-") && close (input_desc) < 0)
{
error (0, errno, "%s", infile);
ok = false;
}
{
error (0, errno, "%s", infile);
ok = false;
}
}
while (++argind < argc);

View File

@@ -22,6 +22,7 @@
#include "system.h"
#include "dev-ino.h"
#include "error.h"
#include "ignore-value.h"
#include "quote.h"
#include "quotearg.h"
#include "root-dev-ino.h"
@@ -97,7 +98,7 @@ compute_context_from_mask (security_context_t context, context_t *ret)
if (!new_context)
{
error (0, errno, _("failed to create security context: %s"),
quotearg_colon (context));
quotearg_colon (context));
return 1;
}
@@ -105,13 +106,13 @@ compute_context_from_mask (security_context_t context, context_t *ret)
do \
{ \
if (specified_ ## comp \
&& context_ ## comp ## _set ((C), specified_ ## comp)) \
&& context_ ## comp ## _set ((C), specified_ ## comp)) \
{ \
error (0, errno, \
_("failed to set %s security context component to %s"), \
#comp, quote (specified_ ## comp)); \
error (0, errno, \
_("failed to set %s security context component to %s"), \
#comp, quote (specified_ ## comp)); \
ok = false; \
} \
} \
} \
while (0)
@@ -147,35 +148,35 @@ change_file_context (int fd, char const *file)
if (specified_context == NULL)
{
int status = (affect_symlink_referent
? getfileconat (fd, file, &file_context)
: lgetfileconat (fd, file, &file_context));
? getfileconat (fd, file, &file_context)
: lgetfileconat (fd, file, &file_context));
if (status < 0 && errno != ENODATA)
{
error (0, errno, _("failed to get security context of %s"),
quote (file));
return 1;
}
{
error (0, errno, _("failed to get security context of %s"),
quote (file));
return 1;
}
/* If the file doesn't have a context, and we're not setting all of
the context components, there isn't really an obvious default.
Thus, we just give up. */
the context components, there isn't really an obvious default.
Thus, we just give up. */
if (file_context == NULL)
{
error (0, 0, _("can't apply partial context to unlabeled file %s"),
quote (file));
return 1;
}
{
error (0, 0, _("can't apply partial context to unlabeled file %s"),
quote (file));
return 1;
}
if (compute_context_from_mask (file_context, &context))
return 1;
return 1;
}
else
{
/* FIXME: this should be done exactly once, in main. */
context = context_new (specified_context);
if (!context)
abort ();
abort ();
}
context_string = context_str (context);
@@ -183,15 +184,15 @@ change_file_context (int fd, char const *file)
if (file_context == NULL || ! STREQ (context_string, file_context))
{
int fail = (affect_symlink_referent
? setfileconat (fd, file, context_string)
: lsetfileconat (fd, file, context_string));
? setfileconat (fd, file, context_string)
: lsetfileconat (fd, file, context_string));
if (fail)
{
errors = 1;
error (0, errno, _("failed to change context of %s to %s"),
quote_n (0, file), quote_n (1, context_string));
}
{
errors = 1;
error (0, errno, _("failed to change context of %s to %s"),
quote_n (0, file), quote_n (1, context_string));
}
}
context_free (context);
@@ -216,41 +217,41 @@ process_file (FTS *fts, FTSENT *ent)
{
case FTS_D:
if (recurse)
{
if (ROOT_DEV_INO_CHECK (root_dev_ino, ent->fts_statp))
{
/* This happens e.g., with "chcon -R --preserve-root ... /"
and with "chcon -RH --preserve-root ... symlink-to-root". */
ROOT_DEV_INO_WARN (file_full_name);
/* Tell fts not to traverse into this hierarchy. */
fts_set (fts, ent, FTS_SKIP);
/* Ensure that we do not process "/" on the second visit. */
ent = fts_read (fts);
return false;
}
return true;
}
{
if (ROOT_DEV_INO_CHECK (root_dev_ino, ent->fts_statp))
{
/* This happens e.g., with "chcon -R --preserve-root ... /"
and with "chcon -RH --preserve-root ... symlink-to-root". */
ROOT_DEV_INO_WARN (file_full_name);
/* Tell fts not to traverse into this hierarchy. */
fts_set (fts, ent, FTS_SKIP);
/* Ensure that we do not process "/" on the second visit. */
ignore_ptr (fts_read (fts));
return false;
}
return true;
}
break;
case FTS_DP:
if (! recurse)
return true;
return true;
break;
case FTS_NS:
/* For a top-level file or directory, this FTS_NS (stat failed)
indicator is determined at the time of the initial fts_open call.
With programs like chmod, chown, and chgrp, that modify
permissions, it is possible that the file in question is
accessible when control reaches this point. So, if this is
the first time we've seen the FTS_NS for this file, tell
fts_read to stat it "again". */
indicator is determined at the time of the initial fts_open call.
With programs like chmod, chown, and chgrp, that modify
permissions, it is possible that the file in question is
accessible when control reaches this point. So, if this is
the first time we've seen the FTS_NS for this file, tell
fts_read to stat it "again". */
if (ent->fts_level == 0 && ent->fts_number == 0)
{
ent->fts_number = 1;
fts_set (fts, ent, FTS_AGAIN);
return true;
}
{
ent->fts_number = 1;
fts_set (fts, ent, FTS_AGAIN);
return true;
}
error (0, ent->fts_errno, _("cannot access %s"), quote (file_full_name));
ok = false;
break;
@@ -262,7 +263,7 @@ process_file (FTS *fts, FTSENT *ent)
case FTS_DNR:
error (0, ent->fts_errno, _("cannot read directory %s"),
quote (file_full_name));
quote (file_full_name));
ok = false;
break;
@@ -280,11 +281,11 @@ process_file (FTS *fts, FTSENT *ent)
if (ok)
{
if (verbose)
printf (_("changing security context of %s\n"),
quote (file_full_name));
printf (_("changing security context of %s\n"),
quote (file_full_name));
if (change_file_context (fts->fts_cwd_fd, file) != 0)
ok = false;
ok = false;
}
if ( ! recurse)
@@ -310,23 +311,24 @@ process_files (char **files, int bit_flags)
ent = fts_read (fts);
if (ent == NULL)
{
if (errno != 0)
{
/* FIXME: try to give a better message */
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
{
if (errno != 0)
{
/* FIXME: try to give a better message */
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
ok &= process_file (fts, ent);
}
/* Ignore failure, since the only way it can do so is in failing to
return to the original directory, and since we're about to exit,
that doesn't matter. */
fts_close (fts);
if (fts_close (fts) != 0)
{
error (0, errno, _("fts_close failed"));
ok = false;
}
return ok;
}
@@ -336,7 +338,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -344,7 +346,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\
or: %s [OPTION]... [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE...\n\
or: %s [OPTION]... --reference=RFILE FILE...\n\
"),
program_name, program_name, program_name);
program_name, program_name, program_name);
fputs (_("\
Change the security context of each FILE to CONTEXT.\n\
With --reference, change the security context of each FILE to that of RFILE.\n\
@@ -378,7 +380,7 @@ one takes effect.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -410,97 +412,97 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, "HLPRhvu:r:t:l:", long_options, NULL))
!= -1)
!= -1)
{
switch (optc)
{
case 'H': /* Traverse command-line symlinks-to-directories. */
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
break;
{
case 'H': /* Traverse command-line symlinks-to-directories. */
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
break;
case 'L': /* Traverse all symlinks-to-directories. */
bit_flags = FTS_LOGICAL;
break;
case 'L': /* Traverse all symlinks-to-directories. */
bit_flags = FTS_LOGICAL;
break;
case 'P': /* Traverse no symlinks-to-directories. */
bit_flags = FTS_PHYSICAL;
break;
case 'P': /* Traverse no symlinks-to-directories. */
bit_flags = FTS_PHYSICAL;
break;
case 'h': /* --no-dereference: affect symlinks */
dereference = 0;
break;
case 'h': /* --no-dereference: affect symlinks */
dereference = 0;
break;
case DEREFERENCE_OPTION: /* --dereference: affect the referent
of each symlink */
dereference = 1;
break;
case DEREFERENCE_OPTION: /* --dereference: affect the referent
of each symlink */
dereference = 1;
break;
case NO_PRESERVE_ROOT:
preserve_root = false;
break;
case NO_PRESERVE_ROOT:
preserve_root = false;
break;
case PRESERVE_ROOT:
preserve_root = true;
break;
case PRESERVE_ROOT:
preserve_root = true;
break;
case REFERENCE_FILE_OPTION:
reference_file = optarg;
break;
case REFERENCE_FILE_OPTION:
reference_file = optarg;
break;
case 'R':
recurse = true;
break;
case 'R':
recurse = true;
break;
case 'f':
/* ignore */
break;
case 'f':
/* ignore */
break;
case 'v':
verbose = true;
break;
case 'v':
verbose = true;
break;
case 'u':
specified_user = optarg;
component_specified = true;
break;
case 'u':
specified_user = optarg;
component_specified = true;
break;
case 'r':
specified_role = optarg;
component_specified = true;
break;
case 'r':
specified_role = optarg;
component_specified = true;
break;
case 't':
specified_type = optarg;
component_specified = true;
break;
case 't':
specified_type = optarg;
component_specified = true;
break;
case 'l':
specified_range = optarg;
component_specified = true;
break;
case 'l':
specified_range = optarg;
component_specified = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
if (recurse)
{
if (bit_flags == FTS_PHYSICAL)
{
if (dereference == 1)
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
affect_symlink_referent = false;
}
{
if (dereference == 1)
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
affect_symlink_referent = false;
}
else
{
if (dereference == 0)
error (EXIT_FAILURE, 0, _("-R -h requires -P"));
affect_symlink_referent = true;
}
{
if (dereference == 0)
error (EXIT_FAILURE, 0, _("-R -h requires -P"));
affect_symlink_referent = true;
}
}
else
{
@@ -511,17 +513,21 @@ main (int argc, char **argv)
if (argc - optind < (reference_file || component_specified ? 1 : 2))
{
if (argc <= optind)
error (0, 0, _("missing operand"));
error (0, 0, _("missing operand"));
else
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
usage (EXIT_FAILURE);
}
if (is_selinux_enabled () != 1)
error (EXIT_FAILURE, 0,
_("%s may be used only on a SELinux kernel"), program_name);
if (reference_file)
{
if (getfilecon (reference_file, &ref_context) < 0)
error (EXIT_FAILURE, errno, _("failed to get security context of %s"),
quote (reference_file));
error (EXIT_FAILURE, errno, _("failed to get security context of %s"),
quote (reference_file));
specified_context = ref_context;
}
@@ -536,8 +542,8 @@ main (int argc, char **argv)
specified_context = argv[optind++];
context = context_new (specified_context);
if (!context)
error (EXIT_FAILURE, 0, _("invalid context: %s"),
quotearg_colon (specified_context));
error (EXIT_FAILURE, 0, _("invalid context: %s"),
quotearg_colon (specified_context));
context_free (context);
}
@@ -547,13 +553,13 @@ main (int argc, char **argv)
usage (1);
}
if (recurse & preserve_root)
if (recurse && preserve_root)
{
static struct dev_ino dev_ino_buf;
root_dev_ino = get_root_dev_ino (&dev_ino_buf);
if (root_dev_ino == NULL)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote ("/"));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote ("/"));
}
else
{

View File

@@ -84,15 +84,15 @@ parse_group (const char *name)
{
struct group *grp = getgrnam (name);
if (grp)
gid = grp->gr_gid;
gid = grp->gr_gid;
else
{
unsigned long int tmp;
if (! (xstrtoul (name, NULL, 10, &tmp, "") == LONGINT_OK
&& tmp <= GID_T_MAX))
error (EXIT_FAILURE, 0, _("invalid group: %s"), quote (name));
gid = tmp;
}
{
unsigned long int tmp;
if (! (xstrtoul (name, NULL, 10, &tmp, "") == LONGINT_OK
&& tmp <= GID_T_MAX))
error (EXIT_FAILURE, 0, _("invalid group: %s"), quote (name));
gid = tmp;
}
endgrent (); /* Save a file descriptor. */
}
@@ -104,14 +104,14 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... GROUP FILE...\n\
or: %s [OPTION]... --reference=RFILE FILE...\n\
"),
program_name, program_name);
program_name, program_name);
fputs (_("\
Change the group of each FILE to GROUP.\n\
With --reference, change the group of each FILE to that of RFILE.\n\
@@ -157,8 +157,8 @@ Examples:\n\
%s staff /u Change the group of /u to \"staff\".\n\
%s -hR staff /u Change the group of /u and subfiles to \"staff\".\n\
"),
program_name, program_name);
emit_bug_reporting_address ();
program_name, program_name);
emit_ancillary_info ();
}
exit (status);
}
@@ -191,75 +191,75 @@ main (int argc, char **argv)
chopt_init (&chopt);
while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, NULL))
!= -1)
!= -1)
{
switch (optc)
{
case 'H': /* Traverse command-line symlinks-to-directories. */
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
break;
{
case 'H': /* Traverse command-line symlinks-to-directories. */
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
break;
case 'L': /* Traverse all symlinks-to-directories. */
bit_flags = FTS_LOGICAL;
break;
case 'L': /* Traverse all symlinks-to-directories. */
bit_flags = FTS_LOGICAL;
break;
case 'P': /* Traverse no symlinks-to-directories. */
bit_flags = FTS_PHYSICAL;
break;
case 'P': /* Traverse no symlinks-to-directories. */
bit_flags = FTS_PHYSICAL;
break;
case 'h': /* --no-dereference: affect symlinks */
dereference = 0;
break;
case 'h': /* --no-dereference: affect symlinks */
dereference = 0;
break;
case DEREFERENCE_OPTION: /* --dereference: affect the referent
of each symlink */
dereference = 1;
break;
case DEREFERENCE_OPTION: /* --dereference: affect the referent
of each symlink */
dereference = 1;
break;
case NO_PRESERVE_ROOT:
preserve_root = false;
break;
case NO_PRESERVE_ROOT:
preserve_root = false;
break;
case PRESERVE_ROOT:
preserve_root = true;
break;
case PRESERVE_ROOT:
preserve_root = true;
break;
case REFERENCE_FILE_OPTION:
reference_file = optarg;
break;
case REFERENCE_FILE_OPTION:
reference_file = optarg;
break;
case 'R':
chopt.recurse = true;
break;
case 'R':
chopt.recurse = true;
break;
case 'c':
chopt.verbosity = V_changes_only;
break;
case 'c':
chopt.verbosity = V_changes_only;
break;
case 'f':
chopt.force_silent = true;
break;
case 'f':
chopt.force_silent = true;
break;
case 'v':
chopt.verbosity = V_high;
break;
case 'v':
chopt.verbosity = V_high;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
if (chopt.recurse)
{
if (bit_flags == FTS_PHYSICAL)
{
if (dereference == 1)
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
dereference = 0;
}
{
if (dereference == 1)
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
dereference = 0;
}
}
else
{
@@ -270,9 +270,9 @@ main (int argc, char **argv)
if (argc - optind < (reference_file ? 1 : 2))
{
if (argc <= optind)
error (0, 0, _("missing operand"));
error (0, 0, _("missing operand"));
else
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
usage (EXIT_FAILURE);
}
@@ -280,8 +280,8 @@ main (int argc, char **argv)
{
struct stat ref_stats;
if (stat (reference_file, &ref_stats))
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote (reference_file));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote (reference_file));
gid = ref_stats.st_gid;
chopt.group_name = gid_to_name (ref_stats.st_gid);
@@ -293,19 +293,19 @@ main (int argc, char **argv)
gid = parse_group (group_name);
}
if (chopt.recurse & preserve_root)
if (chopt.recurse && preserve_root)
{
static struct dev_ino dev_ino_buf;
chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
if (chopt.root_dev_ino == NULL)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote ("/"));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote ("/"));
}
bit_flags |= FTS_DEFER_STAT;
ok = chown_files (argv + optind, bit_flags,
(uid_t) -1, gid,
(uid_t) -1, (gid_t) -1, &chopt);
(uid_t) -1, gid,
(uid_t) -1, (gid_t) -1, &chopt);
chopt_free (&chopt);

View File

@@ -25,6 +25,7 @@
#include "dev-ino.h"
#include "error.h"
#include "filemode.h"
#include "ignore-value.h"
#include "modechange.h"
#include "quote.h"
#include "quotearg.h"
@@ -115,16 +116,16 @@ mode_changed (char const *file, mode_t old_mode, mode_t new_mode)
if (new_mode & (S_ISUID | S_ISGID | S_ISVTX))
{
/* The new mode contains unusual bits that the call to chmod may
have silently cleared. Check whether they actually changed. */
have silently cleared. Check whether they actually changed. */
struct stat new_stats;
if (stat (file, &new_stats) != 0)
{
if (! force_silent)
error (0, errno, _("getting new attributes of %s"), quote (file));
return false;
}
{
if (! force_silent)
error (0, errno, _("getting new attributes of %s"), quote (file));
return false;
}
new_mode = new_stats.st_mode;
}
@@ -137,7 +138,7 @@ mode_changed (char const *file, mode_t old_mode, mode_t new_mode)
static void
describe_change (const char *file, mode_t mode,
enum Change_status changed)
enum Change_status changed)
{
char perms[12]; /* "-rwxrwxrwx" ls-style modes. */
const char *fmt;
@@ -145,7 +146,7 @@ describe_change (const char *file, mode_t mode,
if (changed == CH_NOT_APPLIED)
{
printf (_("neither symbolic link %s nor referent has been changed\n"),
quote (file));
quote (file));
return;
}
@@ -166,7 +167,7 @@ describe_change (const char *file, mode_t mode,
abort ();
}
printf (fmt, quote (file),
(unsigned long int) (mode & CHMOD_MODE_BITS), &perms[1]);
(unsigned long int) (mode & CHMOD_MODE_BITS), &perms[1]);
}
/* Change the mode of FILE.
@@ -191,21 +192,21 @@ process_file (FTS *fts, FTSENT *ent)
case FTS_NS:
/* For a top-level file or directory, this FTS_NS (stat failed)
indicator is determined at the time of the initial fts_open call.
With programs like chmod, chown, and chgrp, that modify
permissions, it is possible that the file in question is
accessible when control reaches this point. So, if this is
the first time we've seen the FTS_NS for this file, tell
fts_read to stat it "again". */
indicator is determined at the time of the initial fts_open call.
With programs like chmod, chown, and chgrp, that modify
permissions, it is possible that the file in question is
accessible when control reaches this point. So, if this is
the first time we've seen the FTS_NS for this file, tell
fts_read to stat it "again". */
if (ent->fts_level == 0 && ent->fts_number == 0)
{
ent->fts_number = 1;
fts_set (fts, ent, FTS_AGAIN);
return true;
}
{
ent->fts_number = 1;
fts_set (fts, ent, FTS_AGAIN);
return true;
}
if (! force_silent)
error (0, ent->fts_errno, _("cannot access %s"),
quote (file_full_name));
quote (file_full_name));
ok = false;
break;
@@ -218,14 +219,14 @@ process_file (FTS *fts, FTSENT *ent)
case FTS_DNR:
if (! force_silent)
error (0, ent->fts_errno, _("cannot read directory %s"),
quote (file_full_name));
quote (file_full_name));
ok = false;
break;
case FTS_SLNONE:
if (! force_silent)
error (0, 0, _("cannot operate on dangling symlink %s"),
quote (file_full_name));
quote (file_full_name));
ok = false;
default:
@@ -238,63 +239,63 @@ process_file (FTS *fts, FTSENT *ent)
/* Tell fts not to traverse into this hierarchy. */
fts_set (fts, ent, FTS_SKIP);
/* Ensure that we do not process "/" on the second visit. */
ent = fts_read (fts);
ok = false;
ignore_ptr (fts_read (fts));
return false;
}
if (ok)
{
old_mode = file_stats->st_mode;
new_mode = mode_adjust (old_mode, S_ISDIR (old_mode) != 0, umask_value,
change, NULL);
change, NULL);
if (! S_ISLNK (old_mode))
{
if (chmodat (fts->fts_cwd_fd, file, new_mode) == 0)
chmod_succeeded = true;
else
{
if (! force_silent)
error (0, errno, _("changing permissions of %s"),
quote (file_full_name));
ok = false;
}
}
{
if (chmodat (fts->fts_cwd_fd, file, new_mode) == 0)
chmod_succeeded = true;
else
{
if (! force_silent)
error (0, errno, _("changing permissions of %s"),
quote (file_full_name));
ok = false;
}
}
}
if (verbosity != V_off)
{
bool changed = (chmod_succeeded
&& mode_changed (file, old_mode, new_mode));
&& mode_changed (file, old_mode, new_mode));
if (changed || verbosity == V_high)
{
enum Change_status ch_status =
(!ok ? CH_FAILED
: !chmod_succeeded ? CH_NOT_APPLIED
: !changed ? CH_NO_CHANGE_REQUESTED
: CH_SUCCEEDED);
describe_change (file_full_name, new_mode, ch_status);
}
{
enum Change_status ch_status =
(!ok ? CH_FAILED
: !chmod_succeeded ? CH_NOT_APPLIED
: !changed ? CH_NO_CHANGE_REQUESTED
: CH_SUCCEEDED);
describe_change (file_full_name, new_mode, ch_status);
}
}
if (chmod_succeeded & diagnose_surprises)
if (chmod_succeeded && diagnose_surprises)
{
mode_t naively_expected_mode =
mode_adjust (old_mode, S_ISDIR (old_mode) != 0, 0, change, NULL);
mode_adjust (old_mode, S_ISDIR (old_mode) != 0, 0, change, NULL);
if (new_mode & ~naively_expected_mode)
{
char new_perms[12];
char naively_expected_perms[12];
strmode (new_mode, new_perms);
strmode (naively_expected_mode, naively_expected_perms);
new_perms[10] = naively_expected_perms[10] = '\0';
error (0, 0,
_("%s: new permissions are %s, not %s"),
quotearg_colon (file_full_name),
new_perms + 1, naively_expected_perms + 1);
ok = false;
}
{
char new_perms[12];
char naively_expected_perms[12];
strmode (new_mode, new_perms);
strmode (naively_expected_mode, naively_expected_perms);
new_perms[10] = naively_expected_perms[10] = '\0';
error (0, 0,
_("%s: new permissions are %s, not %s"),
quotearg_colon (file_full_name),
new_perms + 1, naively_expected_perms + 1);
ok = false;
}
}
if ( ! recurse)
@@ -320,24 +321,25 @@ process_files (char **files, int bit_flags)
ent = fts_read (fts);
if (ent == NULL)
{
if (errno != 0)
{
/* FIXME: try to give a better message */
if (! force_silent)
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
{
if (errno != 0)
{
/* FIXME: try to give a better message */
if (! force_silent)
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
ok &= process_file (fts, ent);
}
/* Ignore failure, since the only way it can do so is in failing to
return to the original directory, and since we're about to exit,
that doesn't matter. */
fts_close (fts);
if (fts_close (fts) != 0)
{
error (0, errno, _("fts_close failed"));
ok = false;
}
return ok;
}
@@ -347,7 +349,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -355,7 +357,7 @@ Usage: %s [OPTION]... MODE[,MODE]... FILE...\n\
or: %s [OPTION]... OCTAL-MODE FILE...\n\
or: %s [OPTION]... --reference=RFILE FILE...\n\
"),
program_name, program_name, program_name);
program_name, program_name, program_name);
fputs (_("\
Change the mode of each FILE to MODE.\n\
\n\
@@ -377,7 +379,7 @@ Change the mode of each FILE to MODE.\n\
\n\
Each MODE is of the form `[ugoa]*([-+=]([rwxXst]*|[ugo]))+'.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -407,99 +409,99 @@ main (int argc, char **argv)
recurse = force_silent = diagnose_surprises = false;
while ((c = getopt_long (argc, argv,
"Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::",
long_options, NULL))
!= -1)
"Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::",
long_options, NULL))
!= -1)
{
switch (c)
{
case 'r':
case 'w':
case 'x':
case 'X':
case 's':
case 't':
case 'u':
case 'g':
case 'o':
case 'a':
case ',':
case '+':
case '=':
/* Support nonportable uses like "chmod -w", but diagnose
surprises due to umask confusion. Even though "--", "--r",
etc., are valid modes, there is no "case '-'" here since
getopt_long reserves leading "--" for long options. */
{
/* Allocate a mode string (e.g., "-rwx") by concatenating
the argument containing this option. If a previous mode
string was given, concatenate the previous string, a
comma, and the new string (e.g., "-s,-rwx"). */
{
case 'r':
case 'w':
case 'x':
case 'X':
case 's':
case 't':
case 'u':
case 'g':
case 'o':
case 'a':
case ',':
case '+':
case '=':
/* Support nonportable uses like "chmod -w", but diagnose
surprises due to umask confusion. Even though "--", "--r",
etc., are valid modes, there is no "case '-'" here since
getopt_long reserves leading "--" for long options. */
{
/* Allocate a mode string (e.g., "-rwx") by concatenating
the argument containing this option. If a previous mode
string was given, concatenate the previous string, a
comma, and the new string (e.g., "-s,-rwx"). */
char const *arg = argv[optind - 1];
size_t arg_len = strlen (arg);
size_t mode_comma_len = mode_len + !!mode_len;
size_t new_mode_len = mode_comma_len + arg_len;
if (mode_alloc <= new_mode_len)
{
mode_alloc = new_mode_len + 1;
mode = X2REALLOC (mode, &mode_alloc);
}
mode[mode_len] = ',';
strcpy (mode + mode_comma_len, arg);
mode_len = new_mode_len;
char const *arg = argv[optind - 1];
size_t arg_len = strlen (arg);
size_t mode_comma_len = mode_len + !!mode_len;
size_t new_mode_len = mode_comma_len + arg_len;
if (mode_alloc <= new_mode_len)
{
mode_alloc = new_mode_len + 1;
mode = X2REALLOC (mode, &mode_alloc);
}
mode[mode_len] = ',';
strcpy (mode + mode_comma_len, arg);
mode_len = new_mode_len;
diagnose_surprises = true;
}
break;
case NO_PRESERVE_ROOT:
preserve_root = false;
break;
case PRESERVE_ROOT:
preserve_root = true;
break;
case REFERENCE_FILE_OPTION:
reference_file = optarg;
break;
case 'R':
recurse = true;
break;
case 'c':
verbosity = V_changes_only;
break;
case 'f':
force_silent = true;
break;
case 'v':
verbosity = V_high;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
diagnose_surprises = true;
}
break;
case NO_PRESERVE_ROOT:
preserve_root = false;
break;
case PRESERVE_ROOT:
preserve_root = true;
break;
case REFERENCE_FILE_OPTION:
reference_file = optarg;
break;
case 'R':
recurse = true;
break;
case 'c':
verbosity = V_changes_only;
break;
case 'f':
force_silent = true;
break;
case 'v':
verbosity = V_high;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
if (reference_file)
{
if (mode)
{
error (0, 0, _("cannot combine mode and --reference options"));
usage (EXIT_FAILURE);
}
{
error (0, 0, _("cannot combine mode and --reference options"));
usage (EXIT_FAILURE);
}
}
else
{
if (!mode)
mode = argv[optind++];
mode = argv[optind++];
}
if (optind >= argc)
{
if (!mode || mode != argv[optind - 1])
error (0, 0, _("missing operand"));
error (0, 0, _("missing operand"));
else
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
usage (EXIT_FAILURE);
}
@@ -507,27 +509,27 @@ main (int argc, char **argv)
{
change = mode_create_from_ref (reference_file);
if (!change)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote (reference_file));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote (reference_file));
}
else
{
change = mode_compile (mode);
if (!change)
{
error (0, 0, _("invalid mode: %s"), quote (mode));
usage (EXIT_FAILURE);
}
{
error (0, 0, _("invalid mode: %s"), quote (mode));
usage (EXIT_FAILURE);
}
umask_value = umask (0);
}
if (recurse & preserve_root)
if (recurse && preserve_root)
{
static struct dev_ino dev_ino_buf;
root_dev_ino = get_root_dev_ino (&dev_ino_buf);
if (root_dev_ino == NULL)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote ("/"));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote ("/"));
}
else
{
@@ -535,7 +537,7 @@ main (int argc, char **argv)
}
ok = process_files (argv + optind,
FTS_COMFOLLOW | FTS_PHYSICAL | FTS_DEFER_STAT);
FTS_COMFOLLOW | FTS_PHYSICAL | FTS_DEFER_STAT);
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
}

View File

@@ -25,6 +25,7 @@
#include "system.h"
#include "chown-core.h"
#include "error.h"
#include "ignore-value.h"
#include "quote.h"
#include "root-dev-ino.h"
#include "xfts.h"
@@ -83,8 +84,8 @@ gid_to_name (gid_t gid)
char buf[INT_BUFSIZE_BOUND (intmax_t)];
struct group *grp = getgrgid (gid);
return xstrdup (grp ? grp->gr_name
: TYPE_SIGNED (gid_t) ? imaxtostr (gid, buf)
: umaxtostr (gid, buf));
: TYPE_SIGNED (gid_t) ? imaxtostr (gid, buf)
: umaxtostr (gid, buf));
}
/* Convert the numeric user-id, UID, to a string stored in xmalloc'd memory,
@@ -97,8 +98,8 @@ uid_to_name (uid_t uid)
char buf[INT_BUFSIZE_BOUND (intmax_t)];
struct passwd *pwd = getpwuid (uid);
return xstrdup (pwd ? pwd->pw_name
: TYPE_SIGNED (uid_t) ? imaxtostr (uid, buf)
: umaxtostr (uid, buf));
: TYPE_SIGNED (uid_t) ? imaxtostr (uid, buf)
: umaxtostr (uid, buf));
}
/* Tell the user how/if the user and group of FILE have been changed.
@@ -107,7 +108,7 @@ uid_to_name (uid_t uid)
static void
describe_change (const char *file, enum Change_status changed,
char const *user, char const *group)
char const *user, char const *group)
{
const char *fmt;
char const *spec;
@@ -116,22 +117,22 @@ describe_change (const char *file, enum Change_status changed,
if (changed == CH_NOT_APPLIED)
{
printf (_("neither symbolic link %s nor referent has been changed\n"),
quote (file));
quote (file));
return;
}
if (user)
{
if (group)
{
spec_allocated = xmalloc (strlen (user) + 1 + strlen (group) + 1);
stpcpy (stpcpy (stpcpy (spec_allocated, user), ":"), group);
spec = spec_allocated;
}
{
spec_allocated = xmalloc (strlen (user) + 1 + strlen (group) + 1);
stpcpy (stpcpy (stpcpy (spec_allocated, user), ":"), group);
spec = spec_allocated;
}
else
{
spec = user;
}
{
spec = user;
}
}
else
{
@@ -142,18 +143,18 @@ describe_change (const char *file, enum Change_status changed,
{
case CH_SUCCEEDED:
fmt = (user ? _("changed ownership of %s to %s\n")
: group ? _("changed group of %s to %s\n")
: _("no change to ownership of %s\n"));
: group ? _("changed group of %s to %s\n")
: _("no change to ownership of %s\n"));
break;
case CH_FAILED:
fmt = (user ? _("failed to change ownership of %s to %s\n")
: group ? _("failed to change group of %s to %s\n")
: _("failed to change ownership of %s\n"));
: group ? _("failed to change group of %s to %s\n")
: _("failed to change ownership of %s\n"));
break;
case CH_NO_CHANGE_REQUESTED:
fmt = (user ? _("ownership of %s retained as %s\n")
: group ? _("group of %s retained as %s\n")
: _("ownership of %s retained\n"));
: group ? _("group of %s retained as %s\n")
: _("ownership of %s retained\n"));
break;
default:
abort ();
@@ -184,9 +185,9 @@ describe_change (const char *file, enum Change_status changed,
static enum RCH_status
restricted_chown (int cwd_fd, char const *file,
struct stat const *orig_st,
uid_t uid, gid_t gid,
uid_t required_uid, gid_t required_gid)
struct stat const *orig_st,
uid_t uid, gid_t gid,
uid_t required_uid, gid_t required_gid)
{
enum RCH_status status = RC_ok;
struct stat st;
@@ -199,15 +200,15 @@ restricted_chown (int cwd_fd, char const *file,
if (! S_ISREG (orig_st->st_mode))
{
if (S_ISDIR (orig_st->st_mode))
open_flags |= O_DIRECTORY;
open_flags |= O_DIRECTORY;
else
return RC_do_ordinary_chown;
return RC_do_ordinary_chown;
}
fd = openat (cwd_fd, file, O_RDONLY | open_flags);
if (! (0 <= fd
|| (errno == EACCES && S_ISREG (orig_st->st_mode)
&& 0 <= (fd = openat (cwd_fd, file, O_WRONLY | open_flags)))))
|| (errno == EACCES && S_ISREG (orig_st->st_mode)
&& 0 <= (fd = openat (cwd_fd, file, O_WRONLY | open_flags)))))
return (errno == EACCES ? RC_do_ordinary_chown : RC_error);
if (fstat (fd, &st) != 0)
@@ -215,18 +216,18 @@ restricted_chown (int cwd_fd, char const *file,
else if (! SAME_INODE (*orig_st, st))
status = RC_inode_changed;
else if ((required_uid == (uid_t) -1 || required_uid == st.st_uid)
&& (required_gid == (gid_t) -1 || required_gid == st.st_gid))
&& (required_gid == (gid_t) -1 || required_gid == st.st_gid))
{
if (fchown (fd, uid, gid) == 0)
{
status = (close (fd) == 0
? RC_ok : RC_error);
return status;
}
{
status = (close (fd) == 0
? RC_ok : RC_error);
return status;
}
else
{
status = RC_error;
}
{
status = RC_error;
}
}
{ /* FIXME: remove these curly braces when we assume C99. */
@@ -245,9 +246,9 @@ restricted_chown (int cwd_fd, char const *file,
Return true if successful. */
static bool
change_file_owner (FTS *fts, FTSENT *ent,
uid_t uid, gid_t gid,
uid_t required_uid, gid_t required_gid,
struct Chown_option const *chopt)
uid_t uid, gid_t gid,
uid_t required_uid, gid_t required_gid,
struct Chown_option const *chopt)
{
char const *file_full_name = ent->fts_path;
char const *file = ent->fts_accpath;
@@ -261,44 +262,44 @@ change_file_owner (FTS *fts, FTSENT *ent,
{
case FTS_D:
if (chopt->recurse)
{
if (ROOT_DEV_INO_CHECK (chopt->root_dev_ino, ent->fts_statp))
{
/* This happens e.g., with "chown -R --preserve-root 0 /"
and with "chown -RH --preserve-root 0 symlink-to-root". */
ROOT_DEV_INO_WARN (file_full_name);
/* Tell fts not to traverse into this hierarchy. */
fts_set (fts, ent, FTS_SKIP);
/* Ensure that we do not process "/" on the second visit. */
ent = fts_read (fts);
return false;
}
return true;
}
{
if (ROOT_DEV_INO_CHECK (chopt->root_dev_ino, ent->fts_statp))
{
/* This happens e.g., with "chown -R --preserve-root 0 /"
and with "chown -RH --preserve-root 0 symlink-to-root". */
ROOT_DEV_INO_WARN (file_full_name);
/* Tell fts not to traverse into this hierarchy. */
fts_set (fts, ent, FTS_SKIP);
/* Ensure that we do not process "/" on the second visit. */
ignore_ptr (fts_read (fts));
return false;
}
return true;
}
break;
case FTS_DP:
if (! chopt->recurse)
return true;
return true;
break;
case FTS_NS:
/* For a top-level file or directory, this FTS_NS (stat failed)
indicator is determined at the time of the initial fts_open call.
With programs like chmod, chown, and chgrp, that modify
permissions, it is possible that the file in question is
accessible when control reaches this point. So, if this is
the first time we've seen the FTS_NS for this file, tell
fts_read to stat it "again". */
indicator is determined at the time of the initial fts_open call.
With programs like chmod, chown, and chgrp, that modify
permissions, it is possible that the file in question is
accessible when control reaches this point. So, if this is
the first time we've seen the FTS_NS for this file, tell
fts_read to stat it "again". */
if (ent->fts_level == 0 && ent->fts_number == 0)
{
ent->fts_number = 1;
fts_set (fts, ent, FTS_AGAIN);
return true;
}
{
ent->fts_number = 1;
fts_set (fts, ent, FTS_AGAIN);
return true;
}
if (! chopt->force_silent)
error (0, ent->fts_errno, _("cannot access %s"),
quote (file_full_name));
quote (file_full_name));
ok = false;
break;
@@ -311,7 +312,7 @@ change_file_owner (FTS *fts, FTSENT *ent,
case FTS_DNR:
if (! chopt->force_silent)
error (0, ent->fts_errno, _("cannot read directory %s"),
quote (file_full_name));
quote (file_full_name));
ok = false;
break;
@@ -325,9 +326,9 @@ change_file_owner (FTS *fts, FTSENT *ent,
file_stats = NULL;
}
else if (required_uid == (uid_t) -1 && required_gid == (gid_t) -1
&& chopt->verbosity == V_off
&& ! chopt->root_dev_ino
&& ! chopt->affect_symlink_referent)
&& chopt->verbosity == V_off
&& ! chopt->root_dev_ino
&& ! chopt->affect_symlink_referent)
{
do_chown = true;
file_stats = ent->fts_statp;
@@ -337,25 +338,25 @@ change_file_owner (FTS *fts, FTSENT *ent,
file_stats = ent->fts_statp;
/* If this is a symlink and we're dereferencing them,
stat it to get info on the referent. */
stat it to get info on the referent. */
if (chopt->affect_symlink_referent && S_ISLNK (file_stats->st_mode))
{
if (fstatat (fts->fts_cwd_fd, file, &stat_buf, 0) != 0)
{
if (! chopt->force_silent)
error (0, errno, _("cannot dereference %s"),
quote (file_full_name));
ok = false;
}
{
if (fstatat (fts->fts_cwd_fd, file, &stat_buf, 0) != 0)
{
if (! chopt->force_silent)
error (0, errno, _("cannot dereference %s"),
quote (file_full_name));
ok = false;
}
file_stats = &stat_buf;
}
file_stats = &stat_buf;
}
do_chown = (ok
&& (required_uid == (uid_t) -1
|| required_uid == file_stats->st_uid)
&& (required_gid == (gid_t) -1
|| required_gid == file_stats->st_gid));
&& (required_uid == (uid_t) -1
|| required_uid == file_stats->st_uid)
&& (required_gid == (gid_t) -1
|| required_gid == file_stats->st_gid));
}
/* This happens when chown -LR --preserve-root encounters a symlink-to-/. */
@@ -370,89 +371,89 @@ change_file_owner (FTS *fts, FTSENT *ent,
if (do_chown)
{
if ( ! chopt->affect_symlink_referent)
{
ok = (lchownat (fts->fts_cwd_fd, file, uid, gid) == 0);
{
ok = (lchownat (fts->fts_cwd_fd, file, uid, gid) == 0);
/* Ignore any error due to lack of support; POSIX requires
this behavior for top-level symbolic links with -h, and
implies that it's required for all symbolic links. */
if (!ok && errno == EOPNOTSUPP)
{
ok = true;
symlink_changed = false;
}
}
/* Ignore any error due to lack of support; POSIX requires
this behavior for top-level symbolic links with -h, and
implies that it's required for all symbolic links. */
if (!ok && errno == EOPNOTSUPP)
{
ok = true;
symlink_changed = false;
}
}
else
{
/* If possible, avoid a race condition with --from=O:G and without the
(-h) --no-dereference option. If fts's stat call determined
that the uid/gid of FILE matched the --from=O:G-selected
owner and group IDs, blindly using chown(2) here could lead
chown(1) or chgrp(1) mistakenly to dereference a *symlink*
to an arbitrary file that an attacker had moved into the
place of FILE during the window between the stat and
chown(2) calls. If FILE is a regular file or a directory
that can be opened, this race condition can be avoided safely. */
{
/* If possible, avoid a race condition with --from=O:G and without the
(-h) --no-dereference option. If fts's stat call determined
that the uid/gid of FILE matched the --from=O:G-selected
owner and group IDs, blindly using chown(2) here could lead
chown(1) or chgrp(1) mistakenly to dereference a *symlink*
to an arbitrary file that an attacker had moved into the
place of FILE during the window between the stat and
chown(2) calls. If FILE is a regular file or a directory
that can be opened, this race condition can be avoided safely. */
enum RCH_status err
= restricted_chown (fts->fts_cwd_fd, file, file_stats, uid, gid,
required_uid, required_gid);
switch (err)
{
case RC_ok:
break;
enum RCH_status err
= restricted_chown (fts->fts_cwd_fd, file, file_stats, uid, gid,
required_uid, required_gid);
switch (err)
{
case RC_ok:
break;
case RC_do_ordinary_chown:
ok = (chownat (fts->fts_cwd_fd, file, uid, gid) == 0);
break;
case RC_do_ordinary_chown:
ok = (chownat (fts->fts_cwd_fd, file, uid, gid) == 0);
break;
case RC_error:
ok = false;
break;
case RC_error:
ok = false;
break;
case RC_inode_changed:
/* FIXME: give a diagnostic in this case? */
case RC_excluded:
do_chown = false;
ok = false;
break;
case RC_inode_changed:
/* FIXME: give a diagnostic in this case? */
case RC_excluded:
do_chown = false;
ok = false;
break;
default:
abort ();
}
}
default:
abort ();
}
}
/* On some systems (e.g., GNU/Linux 2.4.x),
the chown function resets the `special' permission bits.
Do *not* restore those bits; doing so would open a window in
which 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. */
the chown function resets the `special' permission bits.
Do *not* restore those bits; doing so would open a window in
which 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. */
if (do_chown && !ok && ! chopt->force_silent)
error (0, errno, (uid != (uid_t) -1
? _("changing ownership of %s")
: _("changing group of %s")),
quote (file_full_name));
error (0, errno, (uid != (uid_t) -1
? _("changing ownership of %s")
: _("changing group of %s")),
quote (file_full_name));
}
if (chopt->verbosity != V_off)
{
bool changed =
((do_chown & ok & symlink_changed)
&& ! ((uid == (uid_t) -1 || uid == file_stats->st_uid)
&& (gid == (gid_t) -1 || gid == file_stats->st_gid)));
((do_chown && ok && symlink_changed)
&& ! ((uid == (uid_t) -1 || uid == file_stats->st_uid)
&& (gid == (gid_t) -1 || gid == file_stats->st_gid)));
if (changed || chopt->verbosity == V_high)
{
enum Change_status ch_status =
(!ok ? CH_FAILED
: !symlink_changed ? CH_NOT_APPLIED
: !changed ? CH_NO_CHANGE_REQUESTED
: CH_SUCCEEDED);
describe_change (file_full_name, ch_status,
chopt->user_name, chopt->group_name);
}
{
enum Change_status ch_status =
(!ok ? CH_FAILED
: !symlink_changed ? CH_NOT_APPLIED
: !changed ? CH_NO_CHANGE_REQUESTED
: CH_SUCCEEDED);
describe_change (file_full_name, ch_status,
chopt->user_name, chopt->group_name);
}
}
if ( ! chopt->recurse)
@@ -472,18 +473,18 @@ change_file_owner (FTS *fts, FTSENT *ent,
Return true if successful. */
extern bool
chown_files (char **files, int bit_flags,
uid_t uid, gid_t gid,
uid_t required_uid, gid_t required_gid,
struct Chown_option const *chopt)
uid_t uid, gid_t gid,
uid_t required_uid, gid_t required_gid,
struct Chown_option const *chopt)
{
bool ok = true;
/* Use lstat and stat only if they're needed. */
int stat_flags = ((required_uid != (uid_t) -1 || required_gid != (gid_t) -1
|| chopt->affect_symlink_referent
|| chopt->verbosity != V_off)
? 0
: FTS_NOSTAT);
|| chopt->affect_symlink_referent
|| chopt->verbosity != V_off)
? 0
: FTS_NOSTAT);
FTS *fts = xfts_open (files, bit_flags | stat_flags, NULL);
@@ -493,25 +494,26 @@ chown_files (char **files, int bit_flags,
ent = fts_read (fts);
if (ent == NULL)
{
if (errno != 0)
{
/* FIXME: try to give a better message */
if (! chopt->force_silent)
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
{
if (errno != 0)
{
/* FIXME: try to give a better message */
if (! chopt->force_silent)
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
ok &= change_file_owner (fts, ent, uid, gid,
required_uid, required_gid, chopt);
required_uid, required_gid, chopt);
}
/* Ignore failure, since the only way it can do so is in failing to
return to the original directory, and since we're about to exit,
that doesn't matter. */
fts_close (fts);
if (fts_close (fts) != 0)
{
error (0, errno, _("fts_close failed"));
ok = false;
}
return ok;
}

View File

@@ -79,8 +79,8 @@ uid_to_name (uid_t);
bool
chown_files (char **files, int bit_flags,
uid_t uid, gid_t gid,
uid_t required_uid, gid_t required_gid,
struct Chown_option const *chopt);
uid_t uid, gid_t gid,
uid_t required_uid, gid_t required_gid,
struct Chown_option const *chopt);
#endif /* CHOWN_CORE_H */

View File

@@ -85,14 +85,14 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [OWNER][:[GROUP]] FILE...\n\
or: %s [OPTION]... --reference=RFILE FILE...\n\
"),
program_name, program_name);
program_name, program_name);
fputs (_("\
Change the owner and/or group of each FILE to OWNER and/or GROUP.\n\
With --reference, change the owner and group of each FILE to those of RFILE.\n\
@@ -152,8 +152,8 @@ Examples:\n\
%s root:staff /u Likewise, but also change its group to \"staff\".\n\
%s -hR root /u Change the owner of /u and subfiles to \"root\".\n\
"),
program_name, program_name, program_name);
emit_bug_reporting_address ();
program_name, program_name, program_name);
emit_ancillary_info ();
}
exit (status);
}
@@ -193,86 +193,86 @@ main (int argc, char **argv)
chopt_init (&chopt);
while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, NULL))
!= -1)
!= -1)
{
switch (optc)
{
case 'H': /* Traverse command-line symlinks-to-directories. */
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
break;
{
case 'H': /* Traverse command-line symlinks-to-directories. */
bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
break;
case 'L': /* Traverse all symlinks-to-directories. */
bit_flags = FTS_LOGICAL;
break;
case 'L': /* Traverse all symlinks-to-directories. */
bit_flags = FTS_LOGICAL;
break;
case 'P': /* Traverse no symlinks-to-directories. */
bit_flags = FTS_PHYSICAL;
break;
case 'P': /* Traverse no symlinks-to-directories. */
bit_flags = FTS_PHYSICAL;
break;
case 'h': /* --no-dereference: affect symlinks */
dereference = 0;
break;
case 'h': /* --no-dereference: affect symlinks */
dereference = 0;
break;
case DEREFERENCE_OPTION: /* --dereference: affect the referent
of each symlink */
dereference = 1;
break;
case DEREFERENCE_OPTION: /* --dereference: affect the referent
of each symlink */
dereference = 1;
break;
case NO_PRESERVE_ROOT:
preserve_root = false;
break;
case NO_PRESERVE_ROOT:
preserve_root = false;
break;
case PRESERVE_ROOT:
preserve_root = true;
break;
case PRESERVE_ROOT:
preserve_root = true;
break;
case REFERENCE_FILE_OPTION:
reference_file = optarg;
break;
case REFERENCE_FILE_OPTION:
reference_file = optarg;
break;
case FROM_OPTION:
{
char *u_dummy, *g_dummy;
const char *e = parse_user_spec (optarg,
&required_uid, &required_gid,
&u_dummy, &g_dummy);
if (e)
error (EXIT_FAILURE, 0, "%s: %s", e, quote (optarg));
break;
}
case FROM_OPTION:
{
char *u_dummy, *g_dummy;
const char *e = parse_user_spec (optarg,
&required_uid, &required_gid,
&u_dummy, &g_dummy);
if (e)
error (EXIT_FAILURE, 0, "%s: %s", e, quote (optarg));
break;
}
case 'R':
chopt.recurse = true;
break;
case 'R':
chopt.recurse = true;
break;
case 'c':
chopt.verbosity = V_changes_only;
break;
case 'c':
chopt.verbosity = V_changes_only;
break;
case 'f':
chopt.force_silent = true;
break;
case 'f':
chopt.force_silent = true;
break;
case 'v':
chopt.verbosity = V_high;
break;
case 'v':
chopt.verbosity = V_high;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
if (chopt.recurse)
{
if (bit_flags == FTS_PHYSICAL)
{
if (dereference == 1)
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
dereference = 0;
}
{
if (dereference == 1)
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
dereference = 0;
}
}
else
{
@@ -283,9 +283,9 @@ main (int argc, char **argv)
if (argc - optind < (reference_file ? 1 : 2))
{
if (argc <= optind)
error (0, 0, _("missing operand"));
error (0, 0, _("missing operand"));
else
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
usage (EXIT_FAILURE);
}
@@ -293,8 +293,8 @@ main (int argc, char **argv)
{
struct stat ref_stats;
if (stat (reference_file, &ref_stats))
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote (reference_file));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote (reference_file));
uid = ref_stats.st_uid;
gid = ref_stats.st_gid;
@@ -304,32 +304,32 @@ main (int argc, char **argv)
else
{
const char *e = parse_user_spec (argv[optind], &uid, &gid,
&chopt.user_name, &chopt.group_name);
&chopt.user_name, &chopt.group_name);
if (e)
error (EXIT_FAILURE, 0, "%s: %s", e, quote (argv[optind]));
/* If a group is specified but no user, set the user name to the
empty string so that diagnostics say "ownership :GROUP"
rather than "group GROUP". */
empty string so that diagnostics say "ownership :GROUP"
rather than "group GROUP". */
if (!chopt.user_name && chopt.group_name)
chopt.user_name = bad_cast ("");
optind++;
}
if (chopt.recurse & preserve_root)
if (chopt.recurse && preserve_root)
{
static struct dev_ino dev_ino_buf;
chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
if (chopt.root_dev_ino == NULL)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote ("/"));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote ("/"));
}
bit_flags |= FTS_DEFER_STAT;
ok = chown_files (argv + optind, bit_flags,
uid, gid,
required_uid, required_gid, &chopt);
uid, gid,
required_uid, required_gid, &chopt);
chopt_free (&chopt);

View File

@@ -118,7 +118,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -142,7 +142,7 @@ Run COMMAND with root directory set to NEWROOT.\n\
\n\
If no command is given, run ``${SHELL} -i'' (default: /bin/sh).\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -164,7 +164,7 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
usage, AUTHORS, (char const *) NULL);
usage, AUTHORS, (char const *) NULL);
while ((c = getopt_long (argc, argv, "+", long_opts, NULL)) != -1)
{
@@ -189,7 +189,7 @@ main (int argc, char **argv)
if (chroot (argv[optind]) != 0)
error (EXIT_FAILURE, errno, _("cannot change root directory to %s"),
argv[optind]);
argv[optind]);
if (chdir ("/"))
error (EXIT_FAILURE, errno, _("cannot chdir to root directory"));
@@ -199,7 +199,7 @@ main (int argc, char **argv)
/* No command. Run an interactive shell. */
char *shell = getenv ("SHELL");
if (shell == NULL)
shell = bad_cast ("/bin/sh");
shell = bad_cast ("/bin/sh");
argv[0] = shell;
argv[1] = bad_cast ("-i");
argv[2] = NULL;

View File

@@ -58,8 +58,8 @@
The i bit in GEN is set if X^i is a summand of G(X) except X^32. */
# define GEN (BIT (26) | BIT (23) | BIT (22) | BIT (16) | BIT (12) \
| BIT (11) | BIT (10) | BIT (8) | BIT (7) | BIT (5) \
| BIT (4) | BIT (2) | BIT (1) | BIT (0))
| BIT (11) | BIT (10) | BIT (8) | BIT (7) | BIT (5) \
| BIT (4) | BIT (2) | BIT (1) | BIT (0))
static uint_fast32_t r[8];
@@ -96,9 +96,9 @@ main (void)
for (i = 0; i < 51; i++)
{
printf (",\n 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x",
crc_remainder (i * 5 + 1), crc_remainder (i * 5 + 2),
crc_remainder (i * 5 + 3), crc_remainder (i * 5 + 4),
crc_remainder (i * 5 + 5));
crc_remainder (i * 5 + 1), crc_remainder (i * 5 + 2),
crc_remainder (i * 5 + 3), crc_remainder (i * 5 + 4),
crc_remainder (i * 5 + 5));
}
printf ("\n};\n");
exit (EXIT_SUCCESS);
@@ -193,16 +193,16 @@ cksum (const char *file, bool print_name)
fp = stdin;
have_read_stdin = true;
if (O_BINARY && ! isatty (STDIN_FILENO))
xfreopen (NULL, "rb", stdin);
xfreopen (NULL, "rb", stdin);
}
else
{
fp = fopen (file, (O_BINARY ? "rb" : "r"));
if (fp == NULL)
{
error (0, errno, "%s", file);
return false;
}
{
error (0, errno, "%s", file);
return false;
}
}
while ((bytes_read = fread (buf, 1, BUFLEN, fp)) > 0)
@@ -210,19 +210,19 @@ cksum (const char *file, bool print_name)
unsigned char *cp = buf;
if (length + bytes_read < length)
error (EXIT_FAILURE, 0, _("%s: file too long"), file);
error (EXIT_FAILURE, 0, _("%s: file too long"), file);
length += bytes_read;
while (bytes_read--)
crc = (crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
crc = (crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF];
if (feof (fp))
break;
break;
}
if (ferror (fp))
{
error (0, errno, "%s", file);
if (!STREQ (file, "-"))
fclose (fp);
fclose (fp);
return false;
}
@@ -255,21 +255,21 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [FILE]...\n\
or: %s [OPTION]\n\
"),
program_name, program_name);
program_name, program_name);
fputs (_("\
Print CRC checksum and byte counts of each FILE.\n\
\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -289,7 +289,7 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE, Version,
usage, AUTHORS, (char const *) NULL);
usage, AUTHORS, (char const *) NULL);
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
usage (EXIT_FAILURE);
@@ -301,7 +301,7 @@ main (int argc, char **argv)
{
ok = true;
for (i = optind; i < argc; i++)
ok &= cksum (argv[i], true);
ok &= cksum (argv[i], true);
}
if (have_read_stdin && fclose (stdin) == EOF)

View File

@@ -23,6 +23,7 @@
#include "system.h"
#include "linebuffer.h"
#include "error.h"
#include "hard-locale.h"
#include "quote.h"
#include "stdio--.h"
#include "memcmp2.h"
@@ -96,13 +97,13 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... FILE1 FILE2\n\
"),
program_name);
program_name);
fputs (_("\
Compare sorted files FILE1 and FILE2 line by line.\n\
"), stdout);
@@ -139,8 +140,8 @@ Examples:\n\
%s -12 file1 file2 Print only lines present in both file1 and file2.\n\
%s -3 file1 file2 Print lines in file1 not in file2, and vice versa.\n\
"),
program_name, program_name);
emit_bug_reporting_address ();
program_name, program_name);
emit_ancillary_info ();
}
exit (status);
}
@@ -157,26 +158,26 @@ writeline (struct linebuffer const *line, FILE *stream, int class)
{
case 1:
if (!only_file_1)
return;
return;
break;
case 2:
if (!only_file_2)
return;
return;
/* Print a delimiter if we are printing lines from file 1. */
if (only_file_1)
fputs (delimiter, stream);
fputs (delimiter, stream);
break;
case 3:
if (!both)
return;
return;
/* Print a delimiter if we are printing lines from file 1. */
if (only_file_1)
fputs (delimiter, stream);
fputs (delimiter, stream);
/* Print a delimiter if we are printing lines from file 2. */
if (only_file_2)
fputs (delimiter, stream);
fputs (delimiter, stream);
break;
}
@@ -196,35 +197,35 @@ writeline (struct linebuffer const *line, FILE *stream, int class)
static void
check_order (struct linebuffer const *prev,
struct linebuffer const *current,
int whatfile)
struct linebuffer const *current,
int whatfile)
{
if (check_input_order != CHECK_ORDER_DISABLED
&& ((check_input_order == CHECK_ORDER_ENABLED) || seen_unpairable))
{
if (!issued_disorder_warning[whatfile - 1])
{
int order;
{
int order;
if (hard_LC_COLLATE)
order = xmemcoll (prev->buffer, prev->length - 1,
current->buffer, current->length - 1);
else
order = memcmp2 (prev->buffer, prev->length - 1,
current->buffer, current->length - 1);
if (hard_LC_COLLATE)
order = xmemcoll (prev->buffer, prev->length - 1,
current->buffer, current->length - 1);
else
order = memcmp2 (prev->buffer, prev->length - 1,
current->buffer, current->length - 1);
if (0 < order)
{
error ((check_input_order == CHECK_ORDER_ENABLED
? EXIT_FAILURE : 0),
0, _("file %d is not in sorted order"), whatfile);
if (0 < order)
{
error ((check_input_order == CHECK_ORDER_ENABLED
? EXIT_FAILURE : 0),
0, _("file %d is not in sorted order"), whatfile);
/* If we get to here, the message was just a warning, but we
want only to issue it once. */
issued_disorder_warning[whatfile - 1] = true;
}
}
/* If we get to here, the message was just a warning, but we
want only to issue it once. */
issued_disorder_warning[whatfile - 1] = true;
}
}
}
}
@@ -260,20 +261,20 @@ compare_files (char **infiles)
for (i = 0; i < 2; i++)
{
for (j = 0; j < 4; j++)
{
initbuffer (&lba[i][j]);
all_line[i][j] = &lba[i][j];
}
{
initbuffer (&lba[i][j]);
all_line[i][j] = &lba[i][j];
}
alt[i][0] = 0;
alt[i][1] = 0;
alt[i][2] = 0;
streams[i] = (STREQ (infiles[i], "-") ? stdin : fopen (infiles[i], "r"));
if (!streams[i])
error (EXIT_FAILURE, errno, "%s", infiles[i]);
error (EXIT_FAILURE, errno, "%s", infiles[i]);
thisline[i] = readlinebuffer (all_line[i][alt[i][0]], streams[i]);
if (ferror (streams[i]))
error (EXIT_FAILURE, errno, "%s", infiles[i]);
error (EXIT_FAILURE, errno, "%s", infiles[i]);
}
while (thisline[0] || thisline[1])
@@ -284,69 +285,69 @@ compare_files (char **infiles)
/* Compare the next available lines of the two files. */
if (!thisline[0])
order = 1;
order = 1;
else if (!thisline[1])
order = -1;
order = -1;
else
{
if (hard_LC_COLLATE)
order = xmemcoll (thisline[0]->buffer, thisline[0]->length - 1,
thisline[1]->buffer, thisline[1]->length - 1);
else
{
size_t len = min (thisline[0]->length, thisline[1]->length) - 1;
order = memcmp (thisline[0]->buffer, thisline[1]->buffer, len);
if (order == 0)
order = (thisline[0]->length < thisline[1]->length
? -1
: thisline[0]->length != thisline[1]->length);
}
}
{
if (hard_LC_COLLATE)
order = xmemcoll (thisline[0]->buffer, thisline[0]->length - 1,
thisline[1]->buffer, thisline[1]->length - 1);
else
{
size_t len = min (thisline[0]->length, thisline[1]->length) - 1;
order = memcmp (thisline[0]->buffer, thisline[1]->buffer, len);
if (order == 0)
order = (thisline[0]->length < thisline[1]->length
? -1
: thisline[0]->length != thisline[1]->length);
}
}
/* Output the line that is lesser. */
if (order == 0)
writeline (thisline[1], stdout, 3);
writeline (thisline[1], stdout, 3);
else
{
seen_unpairable = true;
if (order <= 0)
writeline (thisline[0], stdout, 1);
else
writeline (thisline[1], stdout, 2);
}
{
seen_unpairable = true;
if (order <= 0)
writeline (thisline[0], stdout, 1);
else
writeline (thisline[1], stdout, 2);
}
/* Step the file the line came from.
If the files match, step both files. */
If the files match, step both files. */
if (0 <= order)
fill_up[1] = true;
fill_up[1] = true;
if (order <= 0)
fill_up[0] = true;
fill_up[0] = true;
for (i = 0; i < 2; i++)
if (fill_up[i])
{
/* Rotate the buffers for this file. */
alt[i][2] = alt[i][1];
alt[i][1] = alt[i][0];
alt[i][0] = (alt[i][0] + 1) & 0x03;
if (fill_up[i])
{
/* Rotate the buffers for this file. */
alt[i][2] = alt[i][1];
alt[i][1] = alt[i][0];
alt[i][0] = (alt[i][0] + 1) & 0x03;
thisline[i] = readlinebuffer (all_line[i][alt[i][0]], streams[i]);
thisline[i] = readlinebuffer (all_line[i][alt[i][0]], streams[i]);
if (thisline[i])
check_order (all_line[i][alt[i][1]], thisline[i], i + 1);
if (thisline[i])
check_order (all_line[i][alt[i][1]], thisline[i], i + 1);
/* If this is the end of the file we may need to re-check
the order of the previous two lines, since we might have
discovered an unpairable match since we checked before. */
else if (all_line[i][alt[i][2]]->buffer)
check_order (all_line[i][alt[i][2]],
all_line[i][alt[i][1]], i + 1);
/* If this is the end of the file we may need to re-check
the order of the previous two lines, since we might have
discovered an unpairable match since we checked before. */
else if (all_line[i][alt[i][2]]->buffer)
check_order (all_line[i][alt[i][2]],
all_line[i][alt[i][1]], i + 1);
if (ferror (streams[i]))
error (EXIT_FAILURE, errno, "%s", infiles[i]);
if (ferror (streams[i]))
error (EXIT_FAILURE, errno, "%s", infiles[i]);
fill_up[i] = false;
}
fill_up[i] = false;
}
}
for (i = 0; i < 2; i++)
@@ -380,50 +381,50 @@ main (int argc, char **argv)
switch (c)
{
case '1':
only_file_1 = false;
break;
only_file_1 = false;
break;
case '2':
only_file_2 = false;
break;
only_file_2 = false;
break;
case '3':
both = false;
break;
both = false;
break;
case NOCHECK_ORDER_OPTION:
check_input_order = CHECK_ORDER_DISABLED;
break;
check_input_order = CHECK_ORDER_DISABLED;
break;
case CHECK_ORDER_OPTION:
check_input_order = CHECK_ORDER_ENABLED;
break;
check_input_order = CHECK_ORDER_ENABLED;
break;
case OUTPUT_DELIMITER_OPTION:
if (delimiter && !STREQ (delimiter, optarg))
error (EXIT_FAILURE, 0, _("multiple delimiters specified"));
delimiter = optarg;
if (!*delimiter)
{
error (EXIT_FAILURE, 0, _("empty %s not allowed"),
quote ("--output-delimiter"));
}
break;
if (delimiter && !STREQ (delimiter, optarg))
error (EXIT_FAILURE, 0, _("multiple delimiters specified"));
delimiter = optarg;
if (!*delimiter)
{
error (EXIT_FAILURE, 0, _("empty %s not allowed"),
quote ("--output-delimiter"));
}
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
usage (EXIT_FAILURE);
}
if (argc - optind < 2)
{
if (argc <= optind)
error (0, 0, _("missing operand"));
error (0, 0, _("missing operand"));
else
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
usage (EXIT_FAILURE);
}

2160
src/copy.c

File diff suppressed because it is too large Load Diff

View File

@@ -43,6 +43,19 @@ enum Sparse_type
SPARSE_ALWAYS
};
/* Control creation of COW files. */
enum Reflink_type
{
/* Default to a standard copy. */
REFLINK_NEVER,
/* Try a COW copy and fall back to a standard copy. */
REFLINK_AUTO,
/* Require a COW copy and fail if not available. */
REFLINK_ALWAYS
};
/* This type is used to help mv (via copy.c) distinguish these cases. */
enum Interactive
{
@@ -73,6 +86,11 @@ enum Dereference_symlink
|| (Mode) == SPARSE_AUTO \
|| (Mode) == SPARSE_ALWAYS)
# define VALID_REFLINK_MODE(Mode) \
((Mode) == REFLINK_NEVER \
|| (Mode) == REFLINK_AUTO \
|| (Mode) == REFLINK_ALWAYS)
/* These options control how files are copied by at least the
following programs: mv (when rename doesn't work), cp, install.
So, if you add a new member, be sure to initialize it in
@@ -219,8 +237,8 @@ struct cp_options
such a symlink) and returns false. */
bool open_dangling_dest_symlink;
/* If true, attempt to clone the file instead of copying it. */
bool reflink;
/* Control creation of COW files. */
enum Reflink_type reflink_mode;
/* This is a set of destination name/inode/dev triples. Each such triple
represents a file we have created corresponding to a source file name
@@ -252,8 +270,8 @@ int rpl_rename (const char *, const char *);
# endif
bool copy (char const *src_name, char const *dst_name,
bool nonexistent_dst, const struct cp_options *options,
bool *copy_into_self, bool *rename_succeeded);
bool nonexistent_dst, const struct cp_options *options,
bool *copy_into_self, bool *rename_succeeded);
void dest_info_init (struct cp_options *);
void src_info_init (struct cp_options *);

View File

@@ -148,9 +148,9 @@ extern void
hash_init (void)
{
src_to_dest = hash_initialize (INITIAL_TABLE_SIZE, NULL,
src_to_dest_hash,
src_to_dest_compare,
src_to_dest_free);
src_to_dest_hash,
src_to_dest_compare,
src_to_dest_free);
if (src_to_dest == NULL)
xalloc_die ();
}

916
src/cp.c

File diff suppressed because it is too large Load Diff

View File

@@ -346,7 +346,7 @@ record_line_starts (struct buffer_record *b)
{
line_end = memchr (line_start, '\n', bytes_left);
if (line_end == NULL)
break;
break;
line_length = line_end - line_start + 1;
keep_new_line (b, line_start, line_length);
bytes_left -= line_length;
@@ -358,12 +358,12 @@ record_line_starts (struct buffer_record *b)
if (bytes_left)
{
if (have_read_eof)
{
keep_new_line (b, line_start, bytes_left);
lines++;
}
{
keep_new_line (b, line_start, bytes_left);
lines++;
}
else
save_to_hold_area (xmemdup (line_start, bytes_left), bytes_left);
save_to_hold_area (xmemdup (line_start, bytes_left), bytes_left);
}
b->num_lines = lines;
@@ -438,7 +438,7 @@ save_buffer (struct buffer_record *buf)
else
{
for (p = head; p->next; p = p->next)
/* Do nothing. */ ;
/* Do nothing. */ ;
p->next = buf;
}
}
@@ -481,25 +481,25 @@ load_buffer (void)
/* First check the `holding' area for a partial line. */
if (hold_count)
{
memcpy (p, hold_area, hold_count);
p += hold_count;
b->bytes_used += hold_count;
bytes_avail -= hold_count;
hold_count = 0;
}
{
memcpy (p, hold_area, hold_count);
p += hold_count;
b->bytes_used += hold_count;
bytes_avail -= hold_count;
hold_count = 0;
}
b->bytes_used += read_input (p, bytes_avail);
lines_found = record_line_starts (b);
if (!lines_found)
free_buffer (b);
free_buffer (b);
if (lines_found || have_read_eof)
break;
break;
if (xalloc_oversized (2, b->bytes_alloc))
xalloc_die ();
xalloc_die ();
bytes_wanted = 2 * b->bytes_alloc;
free_buffer (b);
free (b);
@@ -563,13 +563,13 @@ remove_line (void)
/* Go on to the next line record. */
head->curr_line = l->next;
if (head->curr_line == NULL || head->curr_line->used == 0)
{
/* Go on to the next data block.
but first record the current one so we can free it
once the line we're returning has been processed. */
prev_buf = head;
head = head->next;
}
{
/* Go on to the next data block.
but first record the current one so we can free it
once the line we're returning has been processed. */
prev_buf = head;
head = head->next;
}
}
return line;
@@ -592,23 +592,23 @@ find_line (uintmax_t linenum)
for (b = head;;)
{
if (linenum < b->start_line + b->num_lines)
{
/* The line is in this buffer. */
struct line *l;
size_t offset; /* How far into the buffer the line is. */
{
/* The line is in this buffer. */
struct line *l;
size_t offset; /* How far into the buffer the line is. */
l = b->line_start;
offset = linenum - b->start_line;
/* Find the control record. */
while (offset >= CTRL_SIZE)
{
l = l->next;
offset -= CTRL_SIZE;
}
return &l->starts[offset];
}
l = b->line_start;
offset = linenum - b->start_line;
/* Find the control record. */
while (offset >= CTRL_SIZE)
{
l = l->next;
offset -= CTRL_SIZE;
}
return &l->starts[offset];
}
if (b->next == NULL && !load_buffer ())
return NULL;
return NULL;
b = b->next; /* Try the next data block. */
}
}
@@ -657,12 +657,12 @@ write_to_file (uintmax_t last_line, bool ignore, int argnum)
{
line = remove_line ();
if (line == NULL)
{
error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
cleanup_fatal ();
}
{
error (0, 0, _("%s: line number out of range"), global_argv[argnum]);
cleanup_fatal ();
}
if (!ignore)
save_line_to_file (line);
save_line_to_file (line);
}
}
@@ -688,7 +688,7 @@ handle_line_error (const struct control *p, uintmax_t repetition)
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
fprintf (stderr, _("%s: %s: line number out of range"),
program_name, quote (umaxtostr (p->lines_required, buf)));
program_name, quote (umaxtostr (p->lines_required, buf)));
if (repetition)
fprintf (stderr, _(" on repetition %s\n"), umaxtostr (repetition, buf));
else
@@ -717,7 +717,7 @@ process_line_count (const struct control *p, uintmax_t repetition)
{
line = remove_line ();
if (line == NULL)
handle_line_error (p, repetition);
handle_line_error (p, repetition);
save_line_to_file (line);
}
@@ -734,7 +734,7 @@ static void
regexp_error (struct control *p, uintmax_t repetition, bool ignore)
{
fprintf (stderr, _("%s: %s: match not found"),
program_name, quote (global_argv[p->argnum]));
program_name, quote (global_argv[p->argnum]));
if (repetition)
{
@@ -774,75 +774,75 @@ process_regexp (struct control *p, uintmax_t repetition)
if (p->offset >= 0)
{
for (;;)
{
line = find_line (++current_line);
if (line == NULL)
{
if (p->repeat_forever)
{
if (!ignore)
{
dump_rest_of_file ();
close_output_file ();
}
exit (EXIT_SUCCESS);
}
else
regexp_error (p, repetition, ignore);
}
line_len = line->len;
if (line->str[line_len - 1] == '\n')
line_len--;
ret = re_search (&p->re_compiled, line->str, line_len,
0, line_len, NULL);
if (ret == -2)
{
error (0, 0, _("error in regular expression search"));
cleanup_fatal ();
}
if (ret == -1)
{
line = remove_line ();
if (!ignore)
save_line_to_file (line);
}
else
break;
}
{
line = find_line (++current_line);
if (line == NULL)
{
if (p->repeat_forever)
{
if (!ignore)
{
dump_rest_of_file ();
close_output_file ();
}
exit (EXIT_SUCCESS);
}
else
regexp_error (p, repetition, ignore);
}
line_len = line->len;
if (line->str[line_len - 1] == '\n')
line_len--;
ret = re_search (&p->re_compiled, line->str, line_len,
0, line_len, NULL);
if (ret == -2)
{
error (0, 0, _("error in regular expression search"));
cleanup_fatal ();
}
if (ret == -1)
{
line = remove_line ();
if (!ignore)
save_line_to_file (line);
}
else
break;
}
}
else
{
/* Buffer the lines. */
for (;;)
{
line = find_line (++current_line);
if (line == NULL)
{
if (p->repeat_forever)
{
if (!ignore)
{
dump_rest_of_file ();
close_output_file ();
}
exit (EXIT_SUCCESS);
}
else
regexp_error (p, repetition, ignore);
}
line_len = line->len;
if (line->str[line_len - 1] == '\n')
line_len--;
ret = re_search (&p->re_compiled, line->str, line_len,
0, line_len, NULL);
if (ret == -2)
{
error (0, 0, _("error in regular expression search"));
cleanup_fatal ();
}
if (ret != -1)
break;
}
{
line = find_line (++current_line);
if (line == NULL)
{
if (p->repeat_forever)
{
if (!ignore)
{
dump_rest_of_file ();
close_output_file ();
}
exit (EXIT_SUCCESS);
}
else
regexp_error (p, repetition, ignore);
}
line_len = line->len;
if (line->str[line_len - 1] == '\n')
line_len--;
ret = re_search (&p->re_compiled, line->str, line_len,
0, line_len, NULL);
if (ret == -2)
{
error (0, 0, _("error in regular expression search"));
cleanup_fatal ();
}
if (ret != -1)
break;
}
}
/* Account for any offset from this regexp. */
@@ -868,17 +868,17 @@ split_file (void)
{
uintmax_t j;
if (controls[i].regexpr)
{
for (j = 0; (controls[i].repeat_forever
|| j <= controls[i].repeat); j++)
process_regexp (&controls[i], j);
}
{
for (j = 0; (controls[i].repeat_forever
|| j <= controls[i].repeat); j++)
process_regexp (&controls[i], j);
}
else
{
for (j = 0; (controls[i].repeat_forever
|| j <= controls[i].repeat); j++)
process_line_count (&controls[i], j);
}
{
for (j = 0; (controls[i].repeat_forever
|| j <= controls[i].repeat); j++)
process_line_count (&controls[i], j);
}
}
create_output_file ();
@@ -946,7 +946,7 @@ delete_all_files (bool in_signal_handler)
{
const char *name = make_filename (i);
if (unlink (name) != 0 && !in_signal_handler)
error (0, errno, "%s", name);
error (0, errno, "%s", name);
}
files_created = 0;
@@ -961,41 +961,41 @@ close_output_file (void)
if (output_stream)
{
if (ferror (output_stream))
{
error (0, 0, _("write error for %s"), quote (output_filename));
output_stream = NULL;
cleanup_fatal ();
}
{
error (0, 0, _("write error for %s"), quote (output_filename));
output_stream = NULL;
cleanup_fatal ();
}
if (fclose (output_stream) != 0)
{
error (0, errno, "%s", output_filename);
output_stream = NULL;
cleanup_fatal ();
}
{
error (0, errno, "%s", output_filename);
output_stream = NULL;
cleanup_fatal ();
}
if (bytes_written == 0 && elide_empty_files)
{
sigset_t oldset;
bool unlink_ok;
int unlink_errno;
{
sigset_t oldset;
bool unlink_ok;
int unlink_errno;
/* Remove the output file in a critical section, to avoid races. */
sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
unlink_ok = (unlink (output_filename) == 0);
unlink_errno = errno;
files_created -= unlink_ok;
sigprocmask (SIG_SETMASK, &oldset, NULL);
/* Remove the output file in a critical section, to avoid races. */
sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
unlink_ok = (unlink (output_filename) == 0);
unlink_errno = errno;
files_created -= unlink_ok;
sigprocmask (SIG_SETMASK, &oldset, NULL);
if (! unlink_ok)
error (0, unlink_errno, "%s", output_filename);
}
if (! unlink_ok)
error (0, unlink_errno, "%s", output_filename);
}
else
{
if (!suppress_count)
{
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
fprintf (stdout, "%s\n", umaxtostr (bytes_written, buf));
}
}
{
if (!suppress_count)
{
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
fprintf (stdout, "%s\n", umaxtostr (bytes_written, buf));
}
}
output_stream = NULL;
}
}
@@ -1062,11 +1062,11 @@ parse_repeat_count (int argnum, struct control *p, char *str)
else
{
if (xstrtoumax (str + 1, NULL, 10, &val, "") != LONGINT_OK)
{
error (EXIT_FAILURE, 0,
_("%s}: integer required between `{' and `}'"),
global_argv[argnum]);
}
{
error (EXIT_FAILURE, 0,
_("%s}: integer required between `{' and `}'"),
global_argv[argnum]);
}
p->repeat = val;
}
@@ -1091,7 +1091,7 @@ extract_regexp (int argnum, bool ignore, char const *str)
closing_delim = strrchr (str + 1, delim);
if (closing_delim == NULL)
error (EXIT_FAILURE, 0,
_("%s: closing delimiter `%c' missing"), str, delim);
_("%s: closing delimiter `%c' missing"), str, delim);
len = closing_delim - str - 1;
p = new_control_record ();
@@ -1132,44 +1132,44 @@ parse_patterns (int argc, int start, char **argv)
for (i = start; i < argc; i++)
{
if (*argv[i] == '/' || *argv[i] == '%')
{
p = extract_regexp (i, *argv[i] == '%', argv[i]);
}
{
p = extract_regexp (i, *argv[i] == '%', argv[i]);
}
else
{
p = new_control_record ();
p->argnum = i;
{
p = new_control_record ();
p->argnum = i;
if (xstrtoumax (argv[i], NULL, 10, &val, "") != LONGINT_OK)
error (EXIT_FAILURE, 0, _("%s: invalid pattern"), argv[i]);
if (val == 0)
error (EXIT_FAILURE, 0,
_("%s: line number must be greater than zero"),
argv[i]);
if (val < last_val)
{
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
error (EXIT_FAILURE, 0,
_("line number %s is smaller than preceding line number, %s"),
quote (argv[i]), umaxtostr (last_val, buf));
}
if (xstrtoumax (argv[i], NULL, 10, &val, "") != LONGINT_OK)
error (EXIT_FAILURE, 0, _("%s: invalid pattern"), argv[i]);
if (val == 0)
error (EXIT_FAILURE, 0,
_("%s: line number must be greater than zero"),
argv[i]);
if (val < last_val)
{
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
error (EXIT_FAILURE, 0,
_("line number %s is smaller than preceding line number, %s"),
quote (argv[i]), umaxtostr (last_val, buf));
}
if (val == last_val)
error (0, 0,
_("warning: line number %s is the same as preceding line number"),
quote (argv[i]));
if (val == last_val)
error (0, 0,
_("warning: line number %s is the same as preceding line number"),
quote (argv[i]));
last_val = val;
last_val = val;
p->lines_required = val;
}
p->lines_required = val;
}
if (i + 1 < argc && *argv[i + 1] == '{')
{
/* We have a repeat count. */
i++;
parse_repeat_count (i, p, argv[i]);
}
{
/* We have a repeat count. */
i++;
parse_repeat_count (i, p, argv[i]);
}
}
}
@@ -1181,22 +1181,22 @@ get_format_flags (char **format_ptr)
for (; **format_ptr; (*format_ptr)++)
{
switch (**format_ptr)
{
case '-':
break;
{
case '-':
break;
case '+':
case ' ':
count |= 1;
break;
case '+':
case ' ':
count |= 1;
break;
case '#':
count |= 2; /* Allow for 0x prefix preceding an `x' conversion. */
break;
case '#':
count |= 2; /* Allow for 0x prefix preceding an `x' conversion. */
break;
default:
return count;
}
default:
return count;
}
}
return count;
}
@@ -1208,7 +1208,7 @@ get_format_width (char **format_ptr)
if (ISDIGIT (**format_ptr)
&& (xstrtoul (*format_ptr, format_ptr, 10, &val, NULL) != LONGINT_OK
|| SIZE_MAX < val))
|| SIZE_MAX < val))
error (EXIT_FAILURE, 0, _("invalid format width"));
/* Allow for enough octal digits to represent the value of UINT_MAX,
@@ -1229,8 +1229,8 @@ get_format_prec (char **format_ptr)
{
unsigned long int val;
if (xstrtoul (*format_ptr, format_ptr, 10, &val, NULL) != LONGINT_OK
|| SIZE_MAX < val)
error (EXIT_FAILURE, 0, _("invalid format precision"));
|| SIZE_MAX < val)
error (EXIT_FAILURE, 0, _("invalid format precision"));
return val;
}
}
@@ -1257,10 +1257,10 @@ get_format_conv_type (char **format_ptr)
default:
if (isprint (ch))
error (EXIT_FAILURE, 0,
_("invalid conversion specifier in suffix: %c"), ch);
_("invalid conversion specifier in suffix: %c"), ch);
else
error (EXIT_FAILURE, 0,
_("invalid conversion specifier in suffix: \\%.3o"), ch);
error (EXIT_FAILURE, 0,
_("invalid conversion specifier in suffix: \\%.3o"), ch);
}
}
@@ -1275,30 +1275,30 @@ max_out (char *format)
if (*format++ != '%')
out_count++;
else if (*format == '%')
{
format++;
out_count++;
}
{
format++;
out_count++;
}
else
{
if (percent)
error (EXIT_FAILURE, 0,
_("too many %% conversion specifications in suffix"));
percent = true;
out_count += get_format_flags (&format);
{
size_t width = get_format_width (&format);
size_t prec = get_format_prec (&format);
{
if (percent)
error (EXIT_FAILURE, 0,
_("too many %% conversion specifications in suffix"));
percent = true;
out_count += get_format_flags (&format);
{
size_t width = get_format_width (&format);
size_t prec = get_format_prec (&format);
out_count += MAX (width, prec);
}
get_format_conv_type (&format);
}
out_count += MAX (width, prec);
}
get_format_conv_type (&format);
}
}
if (! percent)
error (EXIT_FAILURE, 0,
_("missing %% conversion specification in suffix"));
_("missing %% conversion specification in suffix"));
return out_count;
}
@@ -1328,47 +1328,47 @@ main (int argc, char **argv)
switch (optc)
{
case 'f':
prefix = optarg;
break;
prefix = optarg;
break;
case 'b':
suffix = optarg;
break;
suffix = optarg;
break;
case 'k':
remove_files = false;
break;
remove_files = false;
break;
case 'n':
if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
|| val > INT_MAX)
error (EXIT_FAILURE, 0, _("%s: invalid number"), optarg);
digits = val;
break;
if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
|| val > INT_MAX)
error (EXIT_FAILURE, 0, _("%s: invalid number"), optarg);
digits = val;
break;
case 's':
case 'q':
suppress_count = true;
break;
suppress_count = true;
break;
case 'z':
elide_empty_files = true;
break;
elide_empty_files = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
usage (EXIT_FAILURE);
}
if (argc - optind < 2)
{
if (argc <= optind)
error (0, 0, _("missing operand"));
error (0, 0, _("missing operand"));
else
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
usage (EXIT_FAILURE);
}
@@ -1385,22 +1385,22 @@ main (int argc, char **argv)
int i;
static int const sig[] =
{
/* The usual suspects. */
SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
/* The usual suspects. */
SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
#ifdef SIGPOLL
SIGPOLL,
SIGPOLL,
#endif
#ifdef SIGPROF
SIGPROF,
SIGPROF,
#endif
#ifdef SIGVTALRM
SIGVTALRM,
SIGVTALRM,
#endif
#ifdef SIGXCPU
SIGXCPU,
SIGXCPU,
#endif
#ifdef SIGXFSZ
SIGXFSZ,
SIGXFSZ,
#endif
};
enum { nsigs = ARRAY_CARDINALITY (sig) };
@@ -1410,9 +1410,9 @@ main (int argc, char **argv)
sigemptyset (&caught_signals);
for (i = 0; i < nsigs; i++)
{
sigaction (sig[i], NULL, &act);
if (act.sa_handler != SIG_IGN)
sigaddset (&caught_signals, sig[i]);
sigaction (sig[i], NULL, &act);
if (act.sa_handler != SIG_IGN)
sigaddset (&caught_signals, sig[i]);
}
act.sa_handler = interrupt_handler;
@@ -1421,7 +1421,7 @@ main (int argc, char **argv)
for (i = 0; i < nsigs; i++)
if (sigismember (&caught_signals, sig[i]))
sigaction (sig[i], &act, NULL);
sigaction (sig[i], &act, NULL);
}
split_file ();
@@ -1440,13 +1440,13 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... FILE PATTERN...\n\
"),
program_name);
program_name);
fputs (_("\
Output pieces of FILE separated by PATTERN(s) to files `xx00', `xx01', ...,\n\
and output byte counts of each piece to standard output.\n\
@@ -1481,7 +1481,7 @@ Read standard input if FILE is -. Each PATTERN may be:\n\
\n\
A line OFFSET is a required `+' or `-' followed by a positive integer.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}

570
src/cut.c
View File

@@ -60,11 +60,11 @@
do \
{ \
if (low == 0 || high == 0) \
FATAL_ERROR (_("fields and positions are numbered from 1")); \
FATAL_ERROR (_("fields and positions are numbered from 1")); \
if (n_rp >= n_rp_allocated) \
{ \
(rp) = X2NREALLOC (rp, &n_rp_allocated); \
} \
{ \
(rp) = X2NREALLOC (rp, &n_rp_allocated); \
} \
rp[n_rp].lo = (low); \
rp[n_rp].hi = (high); \
++n_rp; \
@@ -183,13 +183,13 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s OPTION... [FILE]...\n\
"),
program_name);
program_name);
fputs (_("\
Print selected parts of lines from each FILE to standard output.\n\
\n\
@@ -235,7 +235,7 @@ Each range is one of:\n\
\n\
With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -347,7 +347,7 @@ set_fields (const char *fieldstr)
bool rhs_specified = false;
bool dash_found = false; /* True if a '-' is found in this field. */
bool field_found = false; /* True if at least one field spec
has been processed. */
has been processed. */
struct range_pair *rp = NULL;
size_t n_rp = 0;
@@ -361,139 +361,139 @@ set_fields (const char *fieldstr)
for (;;)
{
if (*fieldstr == '-')
{
in_digits = false;
/* Starting a range. */
if (dash_found)
FATAL_ERROR (_("invalid byte or field list"));
dash_found = true;
fieldstr++;
{
in_digits = false;
/* Starting a range. */
if (dash_found)
FATAL_ERROR (_("invalid byte or field list"));
dash_found = true;
fieldstr++;
initial = (lhs_specified ? value : 1);
value = 0;
}
initial = (lhs_specified ? value : 1);
value = 0;
}
else if (*fieldstr == ',' ||
isblank (to_uchar (*fieldstr)) || *fieldstr == '\0')
{
in_digits = false;
/* Ending the string, or this field/byte sublist. */
if (dash_found)
{
dash_found = false;
isblank (to_uchar (*fieldstr)) || *fieldstr == '\0')
{
in_digits = false;
/* Ending the string, or this field/byte sublist. */
if (dash_found)
{
dash_found = false;
if (!lhs_specified && !rhs_specified)
FATAL_ERROR (_("invalid range with no endpoint: -"));
if (!lhs_specified && !rhs_specified)
FATAL_ERROR (_("invalid range with no endpoint: -"));
/* A range. Possibilities: -n, m-n, n-.
In any case, `initial' contains the start of the range. */
if (!rhs_specified)
{
/* `n-'. From `initial' to end of line. */
eol_range_start = initial;
field_found = true;
}
else
{
/* `m-n' or `-n' (1-n). */
if (value < initial)
FATAL_ERROR (_("invalid decreasing range"));
/* A range. Possibilities: -n, m-n, n-.
In any case, `initial' contains the start of the range. */
if (!rhs_specified)
{
/* `n-'. From `initial' to end of line. */
eol_range_start = initial;
field_found = true;
}
else
{
/* `m-n' or `-n' (1-n). */
if (value < initial)
FATAL_ERROR (_("invalid decreasing range"));
/* Is there already a range going to end of line? */
if (eol_range_start != 0)
{
/* Yes. Is the new sequence already contained
in the old one? If so, no processing is
necessary. */
if (initial < eol_range_start)
{
/* No, the new sequence starts before the
old. Does the old range going to end of line
extend into the new range? */
if (eol_range_start <= value)
{
/* Yes. Simply move the end of line marker. */
eol_range_start = initial;
}
else
{
/* No. A simple range, before and disjoint from
the range going to end of line. Fill it. */
ADD_RANGE_PAIR (rp, initial, value);
}
/* Is there already a range going to end of line? */
if (eol_range_start != 0)
{
/* Yes. Is the new sequence already contained
in the old one? If so, no processing is
necessary. */
if (initial < eol_range_start)
{
/* No, the new sequence starts before the
old. Does the old range going to end of line
extend into the new range? */
if (eol_range_start <= value)
{
/* Yes. Simply move the end of line marker. */
eol_range_start = initial;
}
else
{
/* No. A simple range, before and disjoint from
the range going to end of line. Fill it. */
ADD_RANGE_PAIR (rp, initial, value);
}
/* In any case, some fields were selected. */
field_found = true;
}
}
else
{
/* There is no range going to end of line. */
ADD_RANGE_PAIR (rp, initial, value);
field_found = true;
}
value = 0;
}
}
else
{
/* A simple field number, not a range. */
ADD_RANGE_PAIR (rp, value, value);
value = 0;
field_found = true;
}
/* In any case, some fields were selected. */
field_found = true;
}
}
else
{
/* There is no range going to end of line. */
ADD_RANGE_PAIR (rp, initial, value);
field_found = true;
}
value = 0;
}
}
else
{
/* A simple field number, not a range. */
ADD_RANGE_PAIR (rp, value, value);
value = 0;
field_found = true;
}
if (*fieldstr == '\0')
{
break;
}
if (*fieldstr == '\0')
{
break;
}
fieldstr++;
lhs_specified = false;
rhs_specified = false;
}
fieldstr++;
lhs_specified = false;
rhs_specified = false;
}
else if (ISDIGIT (*fieldstr))
{
/* Record beginning of digit string, in case we have to
complain about it. */
static char const *num_start;
if (!in_digits || !num_start)
num_start = fieldstr;
in_digits = true;
{
/* Record beginning of digit string, in case we have to
complain about it. */
static char const *num_start;
if (!in_digits || !num_start)
num_start = fieldstr;
in_digits = true;
if (dash_found)
rhs_specified = 1;
else
lhs_specified = 1;
if (dash_found)
rhs_specified = 1;
else
lhs_specified = 1;
/* Detect overflow. */
if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t))
{
/* In case the user specified -c$(echo 2^64|bc),22,
complain only about the first number. */
/* Determine the length of the offending number. */
size_t len = strspn (num_start, "0123456789");
char *bad_num = xstrndup (num_start, len);
if (operating_mode == byte_mode)
error (0, 0,
_("byte offset %s is too large"), quote (bad_num));
else
error (0, 0,
_("field number %s is too large"), quote (bad_num));
free (bad_num);
exit (EXIT_FAILURE);
}
/* Detect overflow. */
if (!DECIMAL_DIGIT_ACCUMULATE (value, *fieldstr - '0', size_t))
{
/* In case the user specified -c$(echo 2^64|bc),22,
complain only about the first number. */
/* Determine the length of the offending number. */
size_t len = strspn (num_start, "0123456789");
char *bad_num = xstrndup (num_start, len);
if (operating_mode == byte_mode)
error (0, 0,
_("byte offset %s is too large"), quote (bad_num));
else
error (0, 0,
_("field number %s is too large"), quote (bad_num));
free (bad_num);
exit (EXIT_FAILURE);
}
fieldstr++;
}
fieldstr++;
}
else
FATAL_ERROR (_("invalid byte or field list"));
FATAL_ERROR (_("invalid byte or field list"));
}
max_range_endpoint = 0;
for (i = 0; i < n_rp; i++)
{
if (rp[i].hi > max_range_endpoint)
max_range_endpoint = rp[i].hi;
max_range_endpoint = rp[i].hi;
}
/* Allocate an array large enough so that it may be indexed by
@@ -511,14 +511,14 @@ set_fields (const char *fieldstr)
size_t rsi_candidate;
/* Record the range-start indices, i.e., record each start
index that is not part of any other (lo..hi] range. */
index that is not part of any other (lo..hi] range. */
rsi_candidate = complement ? rp[i].hi + 1 : rp[i].lo;
if (output_delimiter_specified
&& !is_printable_field (rsi_candidate))
mark_range_start (rsi_candidate);
&& !is_printable_field (rsi_candidate))
mark_range_start (rsi_candidate);
for (j = rp[i].lo; j <= rp[i].hi; j++)
mark_printable_field (j);
mark_printable_field (j);
}
if (output_delimiter_specified
@@ -550,32 +550,32 @@ cut_bytes (FILE *stream)
c = getc (stream);
if (c == '\n')
{
putchar ('\n');
byte_idx = 0;
print_delimiter = false;
}
{
putchar ('\n');
byte_idx = 0;
print_delimiter = false;
}
else if (c == EOF)
{
if (byte_idx > 0)
putchar ('\n');
break;
}
{
if (byte_idx > 0)
putchar ('\n');
break;
}
else
{
bool range_start;
bool *rs = output_delimiter_specified ? &range_start : NULL;
if (print_kth (++byte_idx, rs))
{
if (rs && *rs && print_delimiter)
{
fwrite (output_delimiter_string, sizeof (char),
output_delimiter_length, stdout);
}
print_delimiter = true;
putchar (c);
}
}
{
bool range_start;
bool *rs = output_delimiter_specified ? &range_start : NULL;
if (print_kth (++byte_idx, rs))
{
if (rs && *rs && print_delimiter)
{
fwrite (output_delimiter_string, sizeof (char),
output_delimiter_length, stdout);
}
print_delimiter = true;
putchar (c);
}
}
}
}
@@ -606,98 +606,98 @@ cut_fields (FILE *stream)
while (1)
{
if (field_idx == 1 && buffer_first_field)
{
ssize_t len;
size_t n_bytes;
{
ssize_t len;
size_t n_bytes;
len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0,
GETNLINE_NO_LIMIT, delim, '\n', stream);
if (len < 0)
{
free (field_1_buffer);
field_1_buffer = NULL;
if (ferror (stream) || feof (stream))
break;
xalloc_die ();
}
len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0,
GETNLINE_NO_LIMIT, delim, '\n', stream);
if (len < 0)
{
free (field_1_buffer);
field_1_buffer = NULL;
if (ferror (stream) || feof (stream))
break;
xalloc_die ();
}
n_bytes = len;
assert (n_bytes != 0);
n_bytes = len;
assert (n_bytes != 0);
/* If the first field extends to the end of line (it is not
delimited) and we are printing all non-delimited lines,
print this one. */
if (to_uchar (field_1_buffer[n_bytes - 1]) != delim)
{
if (suppress_non_delimited)
{
/* Empty. */
}
else
{
fwrite (field_1_buffer, sizeof (char), n_bytes, stdout);
/* Make sure the output line is newline terminated. */
if (field_1_buffer[n_bytes - 1] != '\n')
putchar ('\n');
}
continue;
}
if (print_kth (1, NULL))
{
/* Print the field, but not the trailing delimiter. */
fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout);
found_any_selected_field = true;
}
++field_idx;
}
/* If the first field extends to the end of line (it is not
delimited) and we are printing all non-delimited lines,
print this one. */
if (to_uchar (field_1_buffer[n_bytes - 1]) != delim)
{
if (suppress_non_delimited)
{
/* Empty. */
}
else
{
fwrite (field_1_buffer, sizeof (char), n_bytes, stdout);
/* Make sure the output line is newline terminated. */
if (field_1_buffer[n_bytes - 1] != '\n')
putchar ('\n');
}
continue;
}
if (print_kth (1, NULL))
{
/* Print the field, but not the trailing delimiter. */
fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout);
found_any_selected_field = true;
}
++field_idx;
}
if (c != EOF)
{
if (print_kth (field_idx, NULL))
{
if (found_any_selected_field)
{
fwrite (output_delimiter_string, sizeof (char),
output_delimiter_length, stdout);
}
found_any_selected_field = true;
{
if (print_kth (field_idx, NULL))
{
if (found_any_selected_field)
{
fwrite (output_delimiter_string, sizeof (char),
output_delimiter_length, stdout);
}
found_any_selected_field = true;
while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
{
putchar (c);
}
}
else
{
while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
{
/* Empty. */
}
}
}
while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
{
putchar (c);
}
}
else
{
while ((c = getc (stream)) != delim && c != '\n' && c != EOF)
{
/* Empty. */
}
}
}
if (c == '\n')
{
c = getc (stream);
if (c != EOF)
{
ungetc (c, stream);
c = '\n';
}
}
{
c = getc (stream);
if (c != EOF)
{
ungetc (c, stream);
c = '\n';
}
}
if (c == delim)
++field_idx;
++field_idx;
else if (c == '\n' || c == EOF)
{
if (found_any_selected_field
|| !(suppress_non_delimited && field_idx == 1))
putchar ('\n');
if (c == EOF)
break;
field_idx = 1;
found_any_selected_field = false;
}
{
if (found_any_selected_field
|| !(suppress_non_delimited && field_idx == 1))
putchar ('\n');
if (c == EOF)
break;
field_idx = 1;
found_any_selected_field = false;
}
}
}
@@ -727,10 +727,10 @@ cut_file (char const *file)
{
stream = fopen (file, "r");
if (stream == NULL)
{
error (0, errno, "%s", file);
return false;
}
{
error (0, errno, "%s", file);
return false;
}
}
cut_stream (stream);
@@ -777,60 +777,60 @@ main (int argc, char **argv)
while ((optc = getopt_long (argc, argv, "b:c:d:f:ns", longopts, NULL)) != -1)
{
switch (optc)
{
case 'b':
case 'c':
/* Build the byte list. */
if (operating_mode != undefined_mode)
FATAL_ERROR (_("only one type of list may be specified"));
operating_mode = byte_mode;
spec_list_string = optarg;
break;
{
case 'b':
case 'c':
/* Build the byte list. */
if (operating_mode != undefined_mode)
FATAL_ERROR (_("only one type of list may be specified"));
operating_mode = byte_mode;
spec_list_string = optarg;
break;
case 'f':
/* Build the field list. */
if (operating_mode != undefined_mode)
FATAL_ERROR (_("only one type of list may be specified"));
operating_mode = field_mode;
spec_list_string = optarg;
break;
case 'f':
/* Build the field list. */
if (operating_mode != undefined_mode)
FATAL_ERROR (_("only one type of list may be specified"));
operating_mode = field_mode;
spec_list_string = optarg;
break;
case 'd':
/* New delimiter. */
/* Interpret -d '' to mean `use the NUL byte as the delimiter.' */
if (optarg[0] != '\0' && optarg[1] != '\0')
FATAL_ERROR (_("the delimiter must be a single character"));
delim = optarg[0];
delim_specified = true;
break;
case 'd':
/* New delimiter. */
/* Interpret -d '' to mean `use the NUL byte as the delimiter.' */
if (optarg[0] != '\0' && optarg[1] != '\0')
FATAL_ERROR (_("the delimiter must be a single character"));
delim = optarg[0];
delim_specified = true;
break;
case OUTPUT_DELIMITER_OPTION:
output_delimiter_specified = true;
/* Interpret --output-delimiter='' to mean
`use the NUL byte as the delimiter.' */
output_delimiter_length = (optarg[0] == '\0'
? 1 : strlen (optarg));
output_delimiter_string = xstrdup (optarg);
break;
case OUTPUT_DELIMITER_OPTION:
output_delimiter_specified = true;
/* Interpret --output-delimiter='' to mean
`use the NUL byte as the delimiter.' */
output_delimiter_length = (optarg[0] == '\0'
? 1 : strlen (optarg));
output_delimiter_string = xstrdup (optarg);
break;
case 'n':
break;
case 'n':
break;
case 's':
suppress_non_delimited = true;
break;
case 's':
suppress_non_delimited = true;
break;
case COMPLEMENT_OPTION:
complement = true;
break;
case COMPLEMENT_OPTION:
complement = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
default:
usage (EXIT_FAILURE);
}
}
if (operating_mode == undefined_mode)
@@ -847,19 +847,19 @@ main (int argc, char **argv)
if (output_delimiter_specified)
{
range_start_ht = hash_initialize (HT_RANGE_START_INDEX_INITIAL_CAPACITY,
NULL, hash_int,
hash_compare_ints, NULL);
NULL, hash_int,
hash_compare_ints, NULL);
if (range_start_ht == NULL)
xalloc_die ();
xalloc_die ();
}
if (! set_fields (spec_list_string))
{
if (operating_mode == field_mode)
FATAL_ERROR (_("missing list of fields"));
FATAL_ERROR (_("missing list of fields"));
else
FATAL_ERROR (_("missing list of positions"));
FATAL_ERROR (_("missing list of positions"));
}
if (!delim_specified)

View File

@@ -118,14 +118,14 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [+FORMAT]\n\
or: %s [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]\n\
"),
program_name, program_name);
program_name, program_name);
fputs (_("\
Display the current time in the given FORMAT, or set the system date.\n\
\n\
@@ -236,7 +236,7 @@ then an optional modifier, which is either\n\
E to use the locale's alternate representations if available, or\n\
O to use the locale's alternate numeric symbols if available.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -264,9 +264,9 @@ batch_convert (const char *input_filename, const char *format)
{
in_stream = fopen (input_filename, "r");
if (in_stream == NULL)
{
error (EXIT_FAILURE, errno, "%s", quote (input_filename));
}
{
error (EXIT_FAILURE, errno, "%s", quote (input_filename));
}
}
line = NULL;
@@ -276,22 +276,22 @@ batch_convert (const char *input_filename, const char *format)
{
ssize_t line_length = getline (&line, &buflen, in_stream);
if (line_length < 0)
{
/* FIXME: detect/handle error here. */
break;
}
{
/* FIXME: detect/handle error here. */
break;
}
if (! get_date (&when, line, NULL))
{
if (line[line_length - 1] == '\n')
line[line_length - 1] = '\0';
error (0, 0, _("invalid date %s"), quote (line));
ok = false;
}
{
if (line[line_length - 1] == '\n')
line[line_length - 1] = '\0';
error (0, 0, _("invalid date %s"), quote (line));
ok = false;
}
else
{
ok &= show_date (format, when);
}
{
ok &= show_date (format, when);
}
}
if (fclose (in_stream) == EOF)
@@ -326,138 +326,138 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, short_options, long_options, NULL))
!= -1)
!= -1)
{
char const *new_format = NULL;
switch (optc)
{
case 'd':
datestr = optarg;
break;
case 'f':
batch_file = optarg;
break;
case RFC_3339_OPTION:
{
static char const rfc_3339_format[][32] =
{
"%Y-%m-%d",
"%Y-%m-%d %H:%M:%S%:z",
"%Y-%m-%d %H:%M:%S.%N%:z"
};
enum Time_spec i =
XARGMATCH ("--rfc-3339", optarg,
time_spec_string + 2, time_spec + 2);
new_format = rfc_3339_format[i];
break;
}
case 'I':
{
static char const iso_8601_format[][32] =
{
"%Y-%m-%d",
"%Y-%m-%dT%H:%M:%S%z",
"%Y-%m-%dT%H:%M:%S,%N%z",
"%Y-%m-%dT%H%z",
"%Y-%m-%dT%H:%M%z"
};
enum Time_spec i =
(optarg
? XARGMATCH ("--iso-8601", optarg, time_spec_string, time_spec)
: TIME_SPEC_DATE);
new_format = iso_8601_format[i];
break;
}
case 'r':
reference = optarg;
break;
case 'R':
new_format = rfc_2822_format;
break;
case 's':
set_datestr = optarg;
set_date = true;
break;
case 'u':
/* POSIX says that `date -u' is equivalent to setting the TZ
environment variable, so this option should do nothing other
than setting TZ. */
if (putenv (bad_cast ("TZ=UTC0")) != 0)
xalloc_die ();
TZSET;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
{
case 'd':
datestr = optarg;
break;
case 'f':
batch_file = optarg;
break;
case RFC_3339_OPTION:
{
static char const rfc_3339_format[][32] =
{
"%Y-%m-%d",
"%Y-%m-%d %H:%M:%S%:z",
"%Y-%m-%d %H:%M:%S.%N%:z"
};
enum Time_spec i =
XARGMATCH ("--rfc-3339", optarg,
time_spec_string + 2, time_spec + 2);
new_format = rfc_3339_format[i];
break;
}
case 'I':
{
static char const iso_8601_format[][32] =
{
"%Y-%m-%d",
"%Y-%m-%dT%H:%M:%S%z",
"%Y-%m-%dT%H:%M:%S,%N%z",
"%Y-%m-%dT%H%z",
"%Y-%m-%dT%H:%M%z"
};
enum Time_spec i =
(optarg
? XARGMATCH ("--iso-8601", optarg, time_spec_string, time_spec)
: TIME_SPEC_DATE);
new_format = iso_8601_format[i];
break;
}
case 'r':
reference = optarg;
break;
case 'R':
new_format = rfc_2822_format;
break;
case 's':
set_datestr = optarg;
set_date = true;
break;
case 'u':
/* POSIX says that `date -u' is equivalent to setting the TZ
environment variable, so this option should do nothing other
than setting TZ. */
if (putenv (bad_cast ("TZ=UTC0")) != 0)
xalloc_die ();
TZSET;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
if (new_format)
{
if (format)
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
format = new_format;
}
{
if (format)
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
format = new_format;
}
}
option_specified_date = ((datestr ? 1 : 0)
+ (batch_file ? 1 : 0)
+ (reference ? 1 : 0));
+ (batch_file ? 1 : 0)
+ (reference ? 1 : 0));
if (option_specified_date > 1)
{
error (0, 0,
_("the options to specify dates for printing are mutually exclusive"));
_("the options to specify dates for printing are mutually exclusive"));
usage (EXIT_FAILURE);
}
if (set_date && option_specified_date)
{
error (0, 0,
_("the options to print and set the time may not be used together"));
_("the options to print and set the time may not be used together"));
usage (EXIT_FAILURE);
}
if (optind < argc)
{
if (optind + 1 < argc)
{
error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
usage (EXIT_FAILURE);
}
{
error (0, 0, _("extra operand %s"), quote (argv[optind + 1]));
usage (EXIT_FAILURE);
}
if (argv[optind][0] == '+')
{
if (format)
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
format = argv[optind++] + 1;
}
{
if (format)
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
format = argv[optind++] + 1;
}
else if (set_date || option_specified_date)
{
error (0, 0,
_("the argument %s lacks a leading `+';\n"
"when using an option to specify date(s), any non-option\n"
"argument must be a format string beginning with `+'"),
quote (argv[optind]));
usage (EXIT_FAILURE);
}
{
error (0, 0,
_("the argument %s lacks a leading `+';\n"
"when using an option to specify date(s), any non-option\n"
"argument must be a format string beginning with `+'"),
quote (argv[optind]));
usage (EXIT_FAILURE);
}
}
if (!format)
{
format = DATE_FMT_LANGINFO ();
if (! *format)
{
/* Do not wrap the following literal format string with _(...).
For example, suppose LC_ALL is unset, LC_TIME="POSIX",
and LANG="ko_KR". In that case, POSIX says that LC_TIME
determines the format and contents of date and time strings
written by date, which means "date" must generate output
using the POSIX locale; but adding _() would cause "date"
to use a Korean translation of the format. */
format = "%a %b %e %H:%M:%S %Z %Y";
}
{
/* Do not wrap the following literal format string with _(...).
For example, suppose LC_ALL is unset, LC_TIME="POSIX",
and LANG="ko_KR". In that case, POSIX says that LC_TIME
determines the format and contents of date and time strings
written by date, which means "date" must generate output
using the POSIX locale; but adding _() would cause "date"
to use a Korean translation of the format. */
format = "%a %b %e %H:%M:%S %Z %Y";
}
}
if (batch_file != NULL)
@@ -468,55 +468,55 @@ main (int argc, char **argv)
ok = true;
if (!option_specified_date && !set_date)
{
if (optind < argc)
{
/* Prepare to set system clock to the specified date/time
given in the POSIX-format. */
set_date = true;
datestr = argv[optind];
valid_date = posixtime (&when.tv_sec,
datestr,
(PDS_TRAILING_YEAR
| PDS_CENTURY | PDS_SECONDS));
when.tv_nsec = 0; /* FIXME: posixtime should set this. */
}
else
{
/* Prepare to print the current date/time. */
gettime (&when);
}
}
{
if (optind < argc)
{
/* Prepare to set system clock to the specified date/time
given in the POSIX-format. */
set_date = true;
datestr = argv[optind];
valid_date = posixtime (&when.tv_sec,
datestr,
(PDS_TRAILING_YEAR
| PDS_CENTURY | PDS_SECONDS));
when.tv_nsec = 0; /* FIXME: posixtime should set this. */
}
else
{
/* Prepare to print the current date/time. */
gettime (&when);
}
}
else
{
/* (option_specified_date || set_date) */
if (reference != NULL)
{
if (stat (reference, &refstats) != 0)
error (EXIT_FAILURE, errno, "%s", reference);
when = get_stat_mtime (&refstats);
}
else
{
if (set_datestr)
datestr = set_datestr;
valid_date = get_date (&when, datestr, NULL);
}
}
{
/* (option_specified_date || set_date) */
if (reference != NULL)
{
if (stat (reference, &refstats) != 0)
error (EXIT_FAILURE, errno, "%s", reference);
when = get_stat_mtime (&refstats);
}
else
{
if (set_datestr)
datestr = set_datestr;
valid_date = get_date (&when, datestr, NULL);
}
}
if (! valid_date)
error (EXIT_FAILURE, 0, _("invalid date %s"), quote (datestr));
error (EXIT_FAILURE, 0, _("invalid date %s"), quote (datestr));
if (set_date)
{
/* Set the system clock to the specified date, then regardless of
the success of that operation, format and print that date. */
if (settime (&when) != 0)
{
error (0, errno, _("cannot set date"));
ok = false;
}
}
{
/* Set the system clock to the specified date, then regardless of
the success of that operation, format and print that date. */
if (settime (&when) != 0)
{
error (0, errno, _("cannot set date"));
ok = false;
}
}
ok &= show_date (format, when);
}

855
src/dd.c

File diff suppressed because it is too large Load Diff

558
src/df.c
View File

@@ -24,7 +24,6 @@
#include <getopt.h>
#include "system.h"
#include "canonicalize.h"
#include "error.h"
#include "fsusage.h"
#include "human.h"
@@ -158,22 +157,22 @@ print_header (void)
else if (human_output_opts & human_autoscale)
{
if (human_output_opts & human_base_1024)
printf (_(" Size Used Avail Use%%"));
printf (_(" Size Used Avail Use%%"));
else
printf (_(" Size Used Avail Use%%"));
printf (_(" Size Used Avail Use%%"));
}
else if (posix_format)
printf (_(" %s-blocks Used Available Capacity"),
umaxtostr (output_block_size, buf));
umaxtostr (output_block_size, buf));
else
{
int opts = (human_suppress_point_zero
| human_autoscale | human_SI
| (human_output_opts
& (human_group_digits | human_base_1024 | human_B)));
| human_autoscale | human_SI
| (human_output_opts
& (human_group_digits | human_base_1024 | human_B)));
/* Prefer the base that makes the human-readable value more exact,
if there is a difference. */
if there is a difference. */
uintmax_t q1000 = output_block_size;
uintmax_t q1024 = output_block_size;
@@ -181,21 +180,21 @@ print_header (void)
bool divisible_by_1024;
do
{
divisible_by_1000 = q1000 % 1000 == 0; q1000 /= 1000;
divisible_by_1024 = q1024 % 1024 == 0; q1024 /= 1024;
}
{
divisible_by_1000 = q1000 % 1000 == 0; q1000 /= 1000;
divisible_by_1024 = q1024 % 1024 == 0; q1024 /= 1024;
}
while (divisible_by_1000 & divisible_by_1024);
if (divisible_by_1000 < divisible_by_1024)
opts |= human_base_1024;
opts |= human_base_1024;
if (divisible_by_1024 < divisible_by_1000)
opts &= ~human_base_1024;
opts &= ~human_base_1024;
if (! (opts & human_base_1024))
opts |= human_B;
opts |= human_B;
printf (_(" %4s-blocks Used Available Use%%"),
human_readable (output_block_size, buf, opts, 1, 1));
human_readable (output_block_size, buf, opts, 1, 1));
}
printf (_(" Mounted on\n"));
@@ -250,16 +249,16 @@ known_value (uintmax_t n)
static char const *
df_readable (bool negative, uintmax_t n, char *buf,
uintmax_t input_units, uintmax_t output_units)
uintmax_t input_units, uintmax_t output_units)
{
if (! known_value (n) && !negative)
return "-";
else
{
char *p = human_readable (negative ? -n : n, buf + negative,
human_output_opts, input_units, output_units);
human_output_opts, input_units, output_units);
if (negative)
*--p = '-';
*--p = '-';
return p;
}
}
@@ -273,7 +272,7 @@ df_readable (bool negative, uintmax_t n, char *buf,
how the negation flag is used. */
static void
add_uint_with_neg_flag (uintmax_t *dest, bool *dest_neg,
uintmax_t src, bool src_neg)
uintmax_t src, bool src_neg)
{
if (LOG_EQ (*dest_neg, src_neg))
{
@@ -314,9 +313,9 @@ add_uint_with_neg_flag (uintmax_t *dest, bool *dest_neg,
static void
show_dev (char const *disk, char const *mount_point,
char const *stat_file, char const *fstype,
bool me_dummy, bool me_remote,
const struct fs_usage *force_fsu)
char const *stat_file, char const *fstype,
bool me_dummy, bool me_remote,
const struct fs_usage *force_fsu)
{
struct fs_usage fsu;
char buf[3][LONGEST_HUMAN_READABLE + 2];
@@ -333,10 +332,10 @@ show_dev (char const *disk, char const *mount_point,
bool negate_used;
double pct = -1;
if (me_remote & show_local_fs)
if (me_remote && show_local_fs)
return;
if (me_dummy & !show_all_fs & !show_listed_fs)
if (me_dummy && !show_all_fs && !show_listed_fs)
return;
if (!selected_fstype (fstype) || excluded_fstype (fstype))
@@ -379,18 +378,18 @@ show_dev (char const *disk, char const *mount_point,
size_t disk_name_len = strlen (disk);
size_t fstype_len = strlen (fstype);
if (disk_name_len + fstype_len < 18)
printf ("%s%*s ", disk, 18 - (int) disk_name_len, fstype);
printf ("%s%*s ", disk, 18 - (int) disk_name_len, fstype);
else if (!posix_format)
printf ("%s\n%18s ", disk, fstype);
printf ("%s\n%18s ", disk, fstype);
else
printf ("%s %s", disk, fstype);
printf ("%s %s", disk, fstype);
}
else
{
if (strlen (disk) > 20 && !posix_format)
printf ("%s\n%20s", disk, "");
printf ("%s\n%20s", disk, "");
else
printf ("%-20s", disk);
printf ("%-20s", disk);
}
if (inode_format)
@@ -404,44 +403,44 @@ show_dev (char const *disk, char const *mount_point,
available_to_root = available;
if (known_value (total))
grand_fsu.fsu_files += total;
grand_fsu.fsu_files += total;
if (known_value (available))
grand_fsu.fsu_ffree += available;
grand_fsu.fsu_ffree += available;
}
else
{
if (human_output_opts & human_autoscale)
width = 5 + ! (human_output_opts & human_base_1024);
width = 5 + ! (human_output_opts & human_base_1024);
else
{
width = 9;
if (posix_format)
{
uintmax_t b;
col1_adjustment = -3;
for (b = output_block_size; 9 < b; b /= 10)
col1_adjustment++;
}
}
{
width = 9;
if (posix_format)
{
uintmax_t b;
col1_adjustment = -3;
for (b = output_block_size; 9 < b; b /= 10)
col1_adjustment++;
}
}
use_width = ((posix_format
&& ! (human_output_opts & human_autoscale))
? 8 : 4);
&& ! (human_output_opts & human_autoscale))
? 8 : 4);
input_units = fsu.fsu_blocksize;
output_units = output_block_size;
total = fsu.fsu_blocks;
available = fsu.fsu_bavail;
negate_available = (fsu.fsu_bavail_top_bit_set
& known_value (available));
&& known_value (available));
available_to_root = fsu.fsu_bfree;
if (known_value (total))
grand_fsu.fsu_blocks += input_units * total;
grand_fsu.fsu_blocks += input_units * total;
if (known_value (available_to_root))
grand_fsu.fsu_bfree += input_units * available_to_root;
grand_fsu.fsu_bfree += input_units * available_to_root;
if (known_value (available))
add_uint_with_neg_flag (&grand_fsu.fsu_bavail,
&grand_fsu.fsu_bavail_top_bit_set,
input_units * available, negate_available);
add_uint_with_neg_flag (&grand_fsu.fsu_bavail,
&grand_fsu.fsu_bavail_top_bit_set,
input_units * available, negate_available);
}
used = UINTMAX_MAX;
@@ -453,20 +452,20 @@ show_dev (char const *disk, char const *mount_point,
}
printf (" %*s %*s %*s ",
width + col1_adjustment,
df_readable (false, total,
buf[0], input_units, output_units),
width, df_readable (negate_used, used,
buf[1], input_units, output_units),
width, df_readable (negate_available, available,
buf[2], input_units, output_units));
width + col1_adjustment,
df_readable (false, total,
buf[0], input_units, output_units),
width, df_readable (negate_used, used,
buf[1], input_units, output_units),
width, df_readable (negate_available, available,
buf[2], input_units, output_units));
if (! known_value (used) || ! known_value (available))
;
else if (!negate_used
&& used <= TYPE_MAXIMUM (uintmax_t) / 100
&& used + available != 0
&& (used + available < used) == negate_available)
&& used <= TYPE_MAXIMUM (uintmax_t) / 100
&& used + available != 0
&& (used + available < used) == negate_available)
{
uintmax_t u100 = used * 100;
uintmax_t nonroot_total = used + available;
@@ -475,23 +474,23 @@ show_dev (char const *disk, char const *mount_point,
else
{
/* The calculation cannot be done easily with integer
arithmetic. Fall back on floating point. This can suffer
from minor rounding errors, but doing it exactly requires
multiple precision arithmetic, and it's not worth the
aggravation. */
arithmetic. Fall back on floating point. This can suffer
from minor rounding errors, but doing it exactly requires
multiple precision arithmetic, and it's not worth the
aggravation. */
double u = negate_used ? - (double) - used : used;
double a = negate_available ? - (double) - available : available;
double nonroot_total = u + a;
if (nonroot_total)
{
long int lipct = pct = u * 100 / nonroot_total;
double ipct = lipct;
{
long int lipct = pct = u * 100 / nonroot_total;
double ipct = lipct;
/* Like `pct = ceil (dpct);', but avoid ceil so that
the math library needn't be linked. */
if (ipct - 1 < pct && pct <= ipct + 1)
pct = ipct + (ipct < pct);
}
/* Like `pct = ceil (dpct);', but avoid ceil so that
the math library needn't be linked. */
if (ipct - 1 < pct && pct <= ipct + 1)
pct = ipct + (ipct < pct);
}
}
if (0 <= pct)
@@ -503,12 +502,12 @@ show_dev (char const *disk, char const *mount_point,
{
#ifdef HIDE_AUTOMOUNT_PREFIX
/* Don't print the first directory name in MOUNT_POINT if it's an
artifact of an automounter. This is a bit too aggressive to be
the default. */
artifact of an automounter. This is a bit too aggressive to be
the default. */
if (strncmp ("/auto/", mount_point, 6) == 0)
mount_point += 5;
mount_point += 5;
else if (strncmp ("/tmp_mnt/", mount_point, 9) == 0)
mount_point += 8;
mount_point += 8;
#endif
printf (" %s", mount_point);
}
@@ -537,10 +536,10 @@ find_mount_point (const char *file, const struct stat *file_stat)
{
last_stat = *file_stat;
if (chdir (file) < 0)
{
error (0, errno, _("cannot change to directory %s"), quote (file));
return NULL;
}
{
error (0, errno, _("cannot change to directory %s"), quote (file));
return NULL;
}
}
else
/* FILE is some other kind of file; use its directory. */
@@ -551,17 +550,17 @@ find_mount_point (const char *file, const struct stat *file_stat)
free (xdir);
if (chdir (dir) < 0)
{
error (0, errno, _("cannot change to directory %s"), quote (dir));
return NULL;
}
{
error (0, errno, _("cannot change to directory %s"), quote (dir));
return NULL;
}
if (stat (".", &last_stat) < 0)
{
error (0, errno, _("cannot stat current directory (now %s)"),
quote (dir));
goto done;
}
{
error (0, errno, _("cannot stat current directory (now %s)"),
quote (dir));
goto done;
}
}
/* Now walk up FILE's parents until we find another file system or /,
@@ -571,18 +570,18 @@ find_mount_point (const char *file, const struct stat *file_stat)
{
struct stat st;
if (stat ("..", &st) < 0)
{
error (0, errno, _("cannot stat %s"), quote (".."));
goto done;
}
{
error (0, errno, _("cannot stat %s"), quote (".."));
goto done;
}
if (st.st_dev != last_stat.st_dev || st.st_ino == last_stat.st_ino)
/* cwd is the mount point. */
break;
/* cwd is the mount point. */
break;
if (chdir ("..") < 0)
{
error (0, errno, _("cannot change to directory %s"), quote (".."));
goto done;
}
{
error (0, errno, _("cannot change to directory %s"), quote (".."));
goto done;
}
last_stat = st;
}
@@ -595,7 +594,7 @@ done:
int save_errno = errno;
if (restore_cwd (&cwd) != 0)
error (EXIT_FAILURE, errno,
_("failed to return to initial working directory"));
_("failed to return to initial working directory"));
free_cwd (&cwd);
errno = save_errno;
}
@@ -618,8 +617,8 @@ show_disk (char const *disk)
if (best_match)
{
show_dev (best_match->me_devname, best_match->me_mountdir, NULL,
best_match->me_type, best_match->me_dummy,
best_match->me_remote, NULL);
best_match->me_type, best_match->me_dummy,
best_match->me_remote, NULL);
return true;
}
@@ -641,12 +640,12 @@ show_point (const char *point, const struct stat *statp)
if (*point == '/')
{
/* Find the best match: prefer non-dummies, and then prefer the
last match if there are ties. */
last match if there are ties. */
for (me = mount_list; me; me = me->me_next)
if (STREQ (me->me_mountdir, point) && !STREQ (me->me_type, "lofs")
&& (!best_match || best_match->me_dummy || !me->me_dummy))
best_match = me;
if (STREQ (me->me_mountdir, point) && !STREQ (me->me_type, "lofs")
&& (!best_match || best_match->me_dummy || !me->me_dummy))
best_match = me;
}
/* Calculate the real absolute file name for POINT, and use that to find
@@ -657,87 +656,87 @@ show_point (const char *point, const struct stat *statp)
char *resolved = canonicalize_file_name (point);
if (resolved && resolved[0] == '/')
{
size_t resolved_len = strlen (resolved);
size_t best_match_len = 0;
{
size_t resolved_len = strlen (resolved);
size_t best_match_len = 0;
for (me = mount_list; me; me = me->me_next)
if (!STREQ (me->me_type, "lofs")
&& (!best_match || best_match->me_dummy || !me->me_dummy))
{
size_t len = strlen (me->me_mountdir);
if (best_match_len <= len && len <= resolved_len
&& (len == 1 /* root file system */
|| ((len == resolved_len || resolved[len] == '/')
&& strncmp (me->me_mountdir, resolved, len) == 0)))
{
best_match = me;
best_match_len = len;
}
}
}
for (me = mount_list; me; me = me->me_next)
if (!STREQ (me->me_type, "lofs")
&& (!best_match || best_match->me_dummy || !me->me_dummy))
{
size_t len = strlen (me->me_mountdir);
if (best_match_len <= len && len <= resolved_len
&& (len == 1 /* root file system */
|| ((len == resolved_len || resolved[len] == '/')
&& strncmp (me->me_mountdir, resolved, len) == 0)))
{
best_match = me;
best_match_len = len;
}
}
}
free (resolved);
if (best_match
&& (stat (best_match->me_mountdir, &disk_stats) != 0
|| disk_stats.st_dev != statp->st_dev))
best_match = NULL;
&& (stat (best_match->me_mountdir, &disk_stats) != 0
|| disk_stats.st_dev != statp->st_dev))
best_match = NULL;
}
if (! best_match)
for (me = mount_list; me; me = me->me_next)
{
if (me->me_dev == (dev_t) -1)
{
if (stat (me->me_mountdir, &disk_stats) == 0)
me->me_dev = disk_stats.st_dev;
else
{
/* Report only I/O errors. Other errors might be
caused by shadowed mount points, which means POINT
can't possibly be on this file system. */
if (errno == EIO)
{
error (0, errno, "%s", quote (me->me_mountdir));
exit_status = EXIT_FAILURE;
}
if (me->me_dev == (dev_t) -1)
{
if (stat (me->me_mountdir, &disk_stats) == 0)
me->me_dev = disk_stats.st_dev;
else
{
/* Report only I/O errors. Other errors might be
caused by shadowed mount points, which means POINT
can't possibly be on this file system. */
if (errno == EIO)
{
error (0, errno, "%s", quote (me->me_mountdir));
exit_status = EXIT_FAILURE;
}
/* So we won't try and fail repeatedly. */
me->me_dev = (dev_t) -2;
}
}
/* So we won't try and fail repeatedly. */
me->me_dev = (dev_t) -2;
}
}
if (statp->st_dev == me->me_dev
&& !STREQ (me->me_type, "lofs")
&& (!best_match || best_match->me_dummy || !me->me_dummy))
{
/* Skip bogus mtab entries. */
if (stat (me->me_mountdir, &disk_stats) != 0
|| disk_stats.st_dev != me->me_dev)
me->me_dev = (dev_t) -2;
else
best_match = me;
}
if (statp->st_dev == me->me_dev
&& !STREQ (me->me_type, "lofs")
&& (!best_match || best_match->me_dummy || !me->me_dummy))
{
/* Skip bogus mtab entries. */
if (stat (me->me_mountdir, &disk_stats) != 0
|| disk_stats.st_dev != me->me_dev)
me->me_dev = (dev_t) -2;
else
best_match = me;
}
}
if (best_match)
show_dev (best_match->me_devname, best_match->me_mountdir, point,
best_match->me_type, best_match->me_dummy, best_match->me_remote,
NULL);
best_match->me_type, best_match->me_dummy, best_match->me_remote,
NULL);
else
{
/* We couldn't find the mount entry corresponding to POINT. Go ahead and
print as much info as we can; methods that require the device to be
present will fail at a later point. */
print as much info as we can; methods that require the device to be
present will fail at a later point. */
/* Find the actual mount point. */
char *mp = find_mount_point (point, statp);
if (mp)
{
show_dev (NULL, mp, NULL, NULL, false, false, NULL);
free (mp);
}
{
show_dev (NULL, mp, NULL, NULL, false, false, NULL);
free (mp);
}
}
}
@@ -764,7 +763,7 @@ show_all_entries (void)
for (me = mount_list; me; me = me->me_next)
show_dev (me->me_devname, me->me_mountdir, NULL, me->me_type,
me->me_dummy, me->me_remote, NULL);
me->me_dummy, me->me_remote, NULL);
}
/* Add FSTYPE to the list of file system types to display. */
@@ -798,7 +797,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);
@@ -833,11 +832,9 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\n\
SIZE may be (or may be an integer optionally followed by) one of following:\n\
kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
"), stdout);
emit_bug_reporting_address ();
emit_blocksize_note ("DF");
emit_size_note ();
emit_ancillary_info ();
}
exit (status);
}
@@ -872,93 +869,93 @@ main (int argc, char **argv)
{
int oi = -1;
int c = getopt_long (argc, argv, "aB:iF:hHklmPTt:vx:", long_options,
&oi);
&oi);
if (c == -1)
break;
break;
switch (c)
{
case 'a':
show_all_fs = true;
break;
case 'B':
{
enum strtol_error e = human_options (optarg, &human_output_opts,
&output_block_size);
if (e != LONGINT_OK)
xstrtol_fatal (e, oi, c, long_options, optarg);
}
break;
case 'i':
inode_format = true;
break;
case 'h':
human_output_opts = human_autoscale | human_SI | human_base_1024;
output_block_size = 1;
break;
case 'H':
human_output_opts = human_autoscale | human_SI;
output_block_size = 1;
break;
case 'k':
human_output_opts = 0;
output_block_size = 1024;
break;
case 'l':
show_local_fs = true;
break;
case 'm': /* obsolescent */
human_output_opts = 0;
output_block_size = 1024 * 1024;
break;
case 'T':
print_type = true;
break;
case 'P':
posix_format = true;
break;
case SYNC_OPTION:
require_sync = true;
break;
case NO_SYNC_OPTION:
require_sync = false;
break;
{
case 'a':
show_all_fs = true;
break;
case 'B':
{
enum strtol_error e = human_options (optarg, &human_output_opts,
&output_block_size);
if (e != LONGINT_OK)
xstrtol_fatal (e, oi, c, long_options, optarg);
}
break;
case 'i':
inode_format = true;
break;
case 'h':
human_output_opts = human_autoscale | human_SI | human_base_1024;
output_block_size = 1;
break;
case 'H':
human_output_opts = human_autoscale | human_SI;
output_block_size = 1;
break;
case 'k':
human_output_opts = 0;
output_block_size = 1024;
break;
case 'l':
show_local_fs = true;
break;
case 'm': /* obsolescent */
human_output_opts = 0;
output_block_size = 1024 * 1024;
break;
case 'T':
print_type = true;
break;
case 'P':
posix_format = true;
break;
case SYNC_OPTION:
require_sync = true;
break;
case NO_SYNC_OPTION:
require_sync = false;
break;
case 'F':
/* Accept -F as a synonym for -t for compatibility with Solaris. */
case 't':
add_fs_type (optarg);
break;
case 'F':
/* Accept -F as a synonym for -t for compatibility with Solaris. */
case 't':
add_fs_type (optarg);
break;
case 'v': /* For SysV compatibility. */
/* ignore */
break;
case 'x':
add_excluded_fs_type (optarg);
break;
case 'v': /* For SysV compatibility. */
/* ignore */
break;
case 'x':
add_excluded_fs_type (optarg);
break;
case 'c':
print_grand_total = true;
break;
case 'c':
print_grand_total = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
default:
usage (EXIT_FAILURE);
}
}
if (human_output_opts == -1)
{
if (posix_format)
{
human_output_opts = 0;
output_block_size = (getenv ("POSIXLY_CORRECT") ? 512 : 1024);
}
{
human_output_opts = 0;
output_block_size = (getenv ("POSIXLY_CORRECT") ? 512 : 1024);
}
else
human_options (getenv ("DF_BLOCK_SIZE"),
&human_output_opts, &output_block_size);
human_options (getenv ("DF_BLOCK_SIZE"),
&human_output_opts, &output_block_size);
}
/* Fail if the same file system type was both selected and excluded. */
@@ -967,18 +964,18 @@ main (int argc, char **argv)
struct fs_type_list *fs_incl;
for (fs_incl = fs_select_list; fs_incl; fs_incl = fs_incl->fs_next)
{
struct fs_type_list *fs_excl;
for (fs_excl = fs_exclude_list; fs_excl; fs_excl = fs_excl->fs_next)
{
if (STREQ (fs_incl->fs_name, fs_excl->fs_name))
{
error (0, 0,
_("file system type %s both selected and excluded"),
quote (fs_incl->fs_name));
match = true;
break;
}
}
struct fs_type_list *fs_excl;
for (fs_excl = fs_exclude_list; fs_excl; fs_excl = fs_excl->fs_next)
{
if (STREQ (fs_incl->fs_name, fs_excl->fs_name))
{
error (0, 0,
_("file system type %s both selected and excluded"),
quote (fs_incl->fs_name));
match = true;
break;
}
}
}
if (match)
exit (EXIT_FAILURE);
@@ -989,38 +986,41 @@ main (int argc, char **argv)
int i;
/* Open each of the given entries to make sure any corresponding
partition is automounted. This must be done before reading the
file system table. */
partition is automounted. This must be done before reading the
file system table. */
stats = xnmalloc (argc - optind, sizeof *stats);
for (i = optind; i < argc; ++i)
{
int fd = open (argv[i], O_RDONLY | O_NOCTTY);
if (fd < 0 || fstat (fd, &stats[i - optind]))
{
error (0, errno, "%s", quote (argv[i]));
exit_status = EXIT_FAILURE;
argv[i] = NULL;
}
if (0 <= fd)
close (fd);
}
{
/* Prefer to open with O_NOCTTY and use fstat, but fall back
on using "stat", in case the file is unreadable. */
int fd = open (argv[i], O_RDONLY | O_NOCTTY);
if ((fd < 0 || fstat (fd, &stats[i - optind]))
&& stat (argv[i], &stats[i - optind]))
{
error (0, errno, "%s", quote (argv[i]));
exit_status = EXIT_FAILURE;
argv[i] = NULL;
}
if (0 <= fd)
close (fd);
}
}
mount_list =
read_file_system_list ((fs_select_list != NULL
|| fs_exclude_list != NULL
|| print_type
|| show_local_fs));
|| fs_exclude_list != NULL
|| print_type
|| show_local_fs));
if (mount_list == NULL)
{
/* Couldn't read the table of mounted file systems.
Fail if df was invoked with no file name arguments;
Otherwise, merely give a warning and proceed. */
Fail if df was invoked with no file name arguments;
Otherwise, merely give a warning and proceed. */
int status = (optind < argc ? 0 : EXIT_FAILURE);
const char *warning = (optind < argc ? _("Warning: ") : "");
error (status, errno, "%s%s", warning,
_("cannot read table of mounted file systems"));
_("cannot read table of mounted file systems"));
}
if (require_sync)
@@ -1034,8 +1034,8 @@ main (int argc, char **argv)
show_listed_fs = true;
for (i = optind; i < argc; ++i)
if (argv[i])
show_entry (argv[i], &stats[i - optind]);
if (argv[i])
show_entry (argv[i], &stats[i - optind]);
}
else
show_all_entries ();
@@ -1043,7 +1043,7 @@ main (int argc, char **argv)
if (print_grand_total)
{
if (inode_format)
grand_fsu.fsu_blocks = 1;
grand_fsu.fsu_blocks = 1;
show_dev ("total", NULL, NULL, NULL, false, false, &grand_fsu);
}

View File

@@ -112,7 +112,7 @@ If FILE is specified, read it to determine which colors to use for which\n\
file types and extensions. Otherwise, a precompiled database is used.\n\
For details on the format of these files, run `dircolors --print-database'.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
@@ -198,29 +198,29 @@ append_quoted (const char *str)
while (*str != '\0')
{
switch (*str)
{
case '\'':
APPEND_CHAR ('\'');
APPEND_CHAR ('\\');
APPEND_CHAR ('\'');
need_backslash = true;
break;
{
case '\'':
APPEND_CHAR ('\'');
APPEND_CHAR ('\\');
APPEND_CHAR ('\'');
need_backslash = true;
break;
case '\\':
case '^':
need_backslash = !need_backslash;
break;
case '\\':
case '^':
need_backslash = !need_backslash;
break;
case ':':
case '=':
if (need_backslash)
APPEND_CHAR ('\\');
/* Fall through */
case ':':
case '=':
if (need_backslash)
APPEND_CHAR ('\\');
/* Fall through */
default:
need_backslash = true;
break;
}
default:
need_backslash = true;
break;
}
APPEND_CHAR (*str);
++str;
@@ -261,106 +261,106 @@ dc_parse_stream (FILE *fp, const char *filename)
++line_number;
if (fp)
{
if (getline (&input_line, &input_line_size, fp) <= 0)
{
free (input_line);
break;
}
line = input_line;
}
{
if (getline (&input_line, &input_line_size, fp) <= 0)
{
free (input_line);
break;
}
line = input_line;
}
else
{
if (next_G_line == G_line + sizeof G_line)
break;
line = next_G_line;
next_G_line += strlen (next_G_line) + 1;
}
{
if (next_G_line == G_line + sizeof G_line)
break;
line = next_G_line;
next_G_line += strlen (next_G_line) + 1;
}
parse_line (line, &keywd, &arg);
if (keywd == NULL)
continue;
continue;
if (arg == NULL)
{
error (0, 0, _("%s:%lu: invalid line; missing second token"),
filename, (unsigned long int) line_number);
ok = false;
free (keywd);
continue;
}
{
error (0, 0, _("%s:%lu: invalid line; missing second token"),
filename, (unsigned long int) line_number);
ok = false;
free (keywd);
continue;
}
unrecognized = false;
if (c_strcasecmp (keywd, "TERM") == 0)
{
if (STREQ (arg, term))
state = ST_TERMSURE;
else if (state != ST_TERMSURE)
state = ST_TERMNO;
}
{
if (STREQ (arg, term))
state = ST_TERMSURE;
else if (state != ST_TERMSURE)
state = ST_TERMNO;
}
else
{
if (state == ST_TERMSURE)
state = ST_TERMYES; /* Another TERM can cancel */
{
if (state == ST_TERMSURE)
state = ST_TERMYES; /* Another TERM can cancel */
if (state != ST_TERMNO)
{
if (keywd[0] == '.')
{
APPEND_CHAR ('*');
append_quoted (keywd);
APPEND_CHAR ('=');
append_quoted (arg);
APPEND_CHAR (':');
}
else if (keywd[0] == '*')
{
append_quoted (keywd);
APPEND_CHAR ('=');
append_quoted (arg);
APPEND_CHAR (':');
}
else if (c_strcasecmp (keywd, "OPTIONS") == 0
|| c_strcasecmp (keywd, "COLOR") == 0
|| c_strcasecmp (keywd, "EIGHTBIT") == 0)
{
/* Ignore. */
}
else
{
int i;
if (state != ST_TERMNO)
{
if (keywd[0] == '.')
{
APPEND_CHAR ('*');
append_quoted (keywd);
APPEND_CHAR ('=');
append_quoted (arg);
APPEND_CHAR (':');
}
else if (keywd[0] == '*')
{
append_quoted (keywd);
APPEND_CHAR ('=');
append_quoted (arg);
APPEND_CHAR (':');
}
else if (c_strcasecmp (keywd, "OPTIONS") == 0
|| c_strcasecmp (keywd, "COLOR") == 0
|| c_strcasecmp (keywd, "EIGHTBIT") == 0)
{
/* Ignore. */
}
else
{
int i;
for (i = 0; slack_codes[i] != NULL; ++i)
if (c_strcasecmp (keywd, slack_codes[i]) == 0)
break;
for (i = 0; slack_codes[i] != NULL; ++i)
if (c_strcasecmp (keywd, slack_codes[i]) == 0)
break;
if (slack_codes[i] != NULL)
{
APPEND_TWO_CHAR_STRING (ls_codes[i]);
APPEND_CHAR ('=');
append_quoted (arg);
APPEND_CHAR (':');
}
else
{
unrecognized = true;
}
}
}
else
{
unrecognized = true;
}
}
if (slack_codes[i] != NULL)
{
APPEND_TWO_CHAR_STRING (ls_codes[i]);
APPEND_CHAR ('=');
append_quoted (arg);
APPEND_CHAR (':');
}
else
{
unrecognized = true;
}
}
}
else
{
unrecognized = true;
}
}
if (unrecognized && (state == ST_TERMSURE || state == ST_TERMYES))
{
error (0, 0, _("%s:%lu: unrecognized keyword %s"),
(filename ? quote (filename) : _("<internal>")),
(unsigned long int) line_number, keywd);
ok = false;
}
{
error (0, 0, _("%s:%lu: unrecognized keyword %s"),
(filename ? quote (filename) : _("<internal>")),
(unsigned long int) line_number, keywd);
ok = false;
}
free (keywd);
free (arg);
@@ -411,23 +411,23 @@ main (int argc, char **argv)
switch (optc)
{
case 'b': /* Bourne shell syntax. */
syntax = SHELL_SYNTAX_BOURNE;
break;
syntax = SHELL_SYNTAX_BOURNE;
break;
case 'c': /* C shell syntax. */
syntax = SHELL_SYNTAX_C;
break;
syntax = SHELL_SYNTAX_C;
break;
case 'p':
print_database = true;
break;
print_database = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
usage (EXIT_FAILURE);
}
argc -= optind;
@@ -438,7 +438,7 @@ main (int argc, char **argv)
if (print_database && syntax != SHELL_SYNTAX_UNKNOWN)
{
error (0, 0,
_("the options to output dircolors' internal database and\n\
_("the options to output dircolors' internal database and\n\
to select a shell syntax are mutually exclusive"));
usage (EXIT_FAILURE);
}
@@ -447,9 +447,9 @@ to select a shell syntax are mutually exclusive"));
{
error (0, 0, _("extra operand %s"), quote (argv[!print_database]));
if (print_database)
fprintf (stderr, "%s\n",
_("file operands cannot be combined with "
"--print-database (-p)"));
fprintf (stderr, "%s\n",
_("file operands cannot be combined with "
"--print-database (-p)"));
usage (EXIT_FAILURE);
}
@@ -457,51 +457,51 @@ to select a shell syntax are mutually exclusive"));
{
char const *p = G_line;
while (p < G_line + sizeof G_line)
{
puts (p);
p += strlen (p) + 1;
}
{
puts (p);
p += strlen (p) + 1;
}
}
else
{
/* If shell syntax was not explicitly specified, try to guess it. */
if (syntax == SHELL_SYNTAX_UNKNOWN)
{
syntax = guess_shell_syntax ();
if (syntax == SHELL_SYNTAX_UNKNOWN)
{
error (EXIT_FAILURE, 0,
_("no SHELL environment variable, and no shell type option given"));
}
}
{
syntax = guess_shell_syntax ();
if (syntax == SHELL_SYNTAX_UNKNOWN)
{
error (EXIT_FAILURE, 0,
_("no SHELL environment variable, and no shell type option given"));
}
}
obstack_init (&lsc_obstack);
if (argc == 0)
ok = dc_parse_stream (NULL, NULL);
ok = dc_parse_stream (NULL, NULL);
else
ok = dc_parse_file (argv[0]);
ok = dc_parse_file (argv[0]);
if (ok)
{
size_t len = obstack_object_size (&lsc_obstack);
char *s = obstack_finish (&lsc_obstack);
const char *prefix;
const char *suffix;
{
size_t len = obstack_object_size (&lsc_obstack);
char *s = obstack_finish (&lsc_obstack);
const char *prefix;
const char *suffix;
if (syntax == SHELL_SYNTAX_BOURNE)
{
prefix = "LS_COLORS='";
suffix = "';\nexport LS_COLORS\n";
}
else
{
prefix = "setenv LS_COLORS '";
suffix = "'\n";
}
fputs (prefix, stdout);
fwrite (s, 1, len, stdout);
fputs (suffix, stdout);
}
if (syntax == SHELL_SYNTAX_BOURNE)
{
prefix = "LS_COLORS='";
suffix = "';\nexport LS_COLORS\n";
}
else
{
prefix = "setenv LS_COLORS '";
suffix = "'\n";
}
fputs (prefix, stdout);
fwrite (s, 1, len, stdout);
fputs (suffix, stdout);
}
}
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);

View File

@@ -69,7 +69,7 @@ TERM xterm-debian
RESET 0 # reset to "normal" color
DIR 01;34 # directory
LINK 01;36 # symbolic link. (If you set this to 'target' instead of a
# numerical value, the color is as for the file pointed to.)
# numerical value, the color is as for the file pointed to.)
MULTIHARDLINK 00 # regular file with more than one link
FIFO 40;33 # pipe
SOCK 01;35 # socket
@@ -116,6 +116,7 @@ EXEC 01;32
.Z 01;31
.dz 01;31
.gz 01;31
.lz 01;31
.xz 01;31
.bz2 01;31
.bz 01;31
@@ -175,6 +176,8 @@ EXEC 01;32
.xcf 01;35
.xwd 01;35
.yuv 01;35
.cgm 01;35
.emf 01;35
# http://wiki.xiph.org/index.php/MIME_Types_and_File_Extensions
.axv 01;35

View File

@@ -39,14 +39,14 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s NAME\n\
or: %s OPTION\n\
"),
program_name, program_name);
program_name, program_name);
fputs (_("\
Print NAME with its trailing /component removed; if NAME contains no /'s,\n\
output `.' (meaning the current directory).\n\
@@ -60,8 +60,8 @@ Examples:\n\
%s /usr/bin/sort Output \"/usr/bin\".\n\
%s stdio.h Output \".\".\n\
"),
program_name, program_name);
emit_bug_reporting_address ();
program_name, program_name);
emit_ancillary_info ();
}
exit (status);
}
@@ -82,7 +82,7 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
usage, AUTHORS, (char const *) NULL);
usage, AUTHORS, (char const *) NULL);
if (getopt_long (argc, argv, "+", NULL, NULL) != -1)
usage (EXIT_FAILURE);

568
src/du.c
View File

@@ -262,7 +262,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -330,11 +330,9 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\n\
SIZE may be (or may be an integer optionally followed by) one of following:\n\
kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
"), stdout);
emit_bug_reporting_address ();
emit_blocksize_note ("DU");
emit_size_note ();
emit_ancillary_info ();
}
exit (status);
}
@@ -396,7 +394,7 @@ static void
hash_init (void)
{
htab = hash_initialize (INITIAL_TABLE_SIZE, NULL,
entry_hash, entry_compare, free);
entry_hash, entry_compare, free);
if (htab == NULL)
xalloc_die ();
}
@@ -427,7 +425,7 @@ print_only_size (uintmax_t n_bytes)
{
char buf[LONGEST_HUMAN_READABLE + 1];
fputs (human_readable (n_bytes, buf, human_output_opts,
1, output_block_size), stdout);
1, output_block_size), stdout);
}
/* Print size (and optionally time) indicated by *PDUI, followed by STRING. */
@@ -492,7 +490,7 @@ process_file (FTS *fts, FTSENT *ent)
case FTS_DNR:
/* Don't return just yet, since although the directory is not readable,
we were able to stat it, so we do have a size. */
we were able to stat it, so we do have a size. */
error (0, ent->fts_errno, _("cannot read directory %s"), quote (file));
ok = false;
break;
@@ -512,25 +510,25 @@ process_file (FTS *fts, FTSENT *ent)
via a hard link, then don't let it contribute to the sums. */
if (skip
|| (!opt_count_all
&& ! S_ISDIR (sb->st_mode)
&& 1 < sb->st_nlink
&& ! hash_ins (sb->st_ino, sb->st_dev)))
&& ! S_ISDIR (sb->st_mode)
&& 1 < sb->st_nlink
&& ! hash_ins (sb->st_ino, sb->st_dev)))
{
/* Note that we must not simply return here.
We still have to update prev_level and maybe propagate
some sums up the hierarchy. */
We still have to update prev_level and maybe propagate
some sums up the hierarchy. */
duinfo_init (&dui);
print = false;
}
else
{
duinfo_set (&dui,
(apparent_size
? sb->st_size
: (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE),
(time_type == time_mtime ? get_stat_mtime (sb)
: time_type == time_atime ? get_stat_atime (sb)
: get_stat_ctime (sb)));
(apparent_size
? sb->st_size
: (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE),
(time_type == time_mtime ? get_stat_mtime (sb)
: time_type == time_atime ? get_stat_atime (sb)
: get_stat_ctime (sb)));
}
level = ent->fts_level;
@@ -544,44 +542,44 @@ process_file (FTS *fts, FTSENT *ent)
else
{
if (level == prev_level)
{
/* This is usually the most common case. Do nothing. */
}
{
/* This is usually the most common case. Do nothing. */
}
else if (level > prev_level)
{
/* Descending the hierarchy.
Clear the accumulators for *all* levels between prev_level
and the current one. The depth may change dramatically,
e.g., from 1 to 10. */
size_t i;
{
/* Descending the hierarchy.
Clear the accumulators for *all* levels between prev_level
and the current one. The depth may change dramatically,
e.g., from 1 to 10. */
size_t i;
if (n_alloc <= level)
{
dulvl = xnrealloc (dulvl, level, 2 * sizeof *dulvl);
n_alloc = level * 2;
}
if (n_alloc <= level)
{
dulvl = xnrealloc (dulvl, level, 2 * sizeof *dulvl);
n_alloc = level * 2;
}
for (i = prev_level + 1; i <= level; i++)
{
duinfo_init (&dulvl[i].ent);
duinfo_init (&dulvl[i].subdir);
}
}
for (i = prev_level + 1; i <= level; i++)
{
duinfo_init (&dulvl[i].ent);
duinfo_init (&dulvl[i].subdir);
}
}
else /* level < prev_level */
{
/* Ascending the hierarchy.
Process a directory only after all entries in that
directory have been processed. When the depth decreases,
propagate sums from the children (prev_level) to the parent.
Here, the current level is always one smaller than the
previous one. */
assert (level == prev_level - 1);
duinfo_add (&dui_to_print, &dulvl[prev_level].ent);
if (!opt_separate_dirs)
duinfo_add (&dui_to_print, &dulvl[prev_level].subdir);
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].ent);
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].subdir);
}
{
/* Ascending the hierarchy.
Process a directory only after all entries in that
directory have been processed. When the depth decreases,
propagate sums from the children (prev_level) to the parent.
Here, the current level is always one smaller than the
previous one. */
assert (level == prev_level - 1);
duinfo_add (&dui_to_print, &dulvl[prev_level].ent);
if (!opt_separate_dirs)
duinfo_add (&dui_to_print, &dulvl[prev_level].subdir);
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].ent);
duinfo_add (&dulvl[level].subdir, &dulvl[prev_level].subdir);
}
}
prev_level = level;
@@ -623,29 +621,30 @@ du_files (char **files, int bit_flags)
FTS *fts = xfts_open (files, bit_flags, NULL);
while (1)
{
FTSENT *ent;
{
FTSENT *ent;
ent = fts_read (fts);
if (ent == NULL)
{
if (errno != 0)
{
/* FIXME: try to give a better message */
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
FTS_CROSS_CHECK (fts);
ent = fts_read (fts);
if (ent == NULL)
{
if (errno != 0)
{
/* FIXME: try to give a better message */
error (0, errno, _("fts_read failed"));
ok = false;
}
break;
}
FTS_CROSS_CHECK (fts);
ok &= process_file (fts, ent);
}
ok &= process_file (fts, ent);
}
/* Ignore failure, since the only way it can do so is in failing to
return to the original directory, and since we're about to exit,
that doesn't matter. */
fts_close (fts);
if (fts_close (fts) != 0)
{
error (0, errno, _("fts_close failed"));
ok = false;
}
}
return ok;
@@ -683,168 +682,168 @@ main (int argc, char **argv)
exclude = new_exclude ();
human_options (getenv ("DU_BLOCK_SIZE"),
&human_output_opts, &output_block_size);
&human_output_opts, &output_block_size);
for (;;)
{
int oi = -1;
int c = getopt_long (argc, argv, DEBUG_OPT "0abchHklmsxB:DLPSX:",
long_options, &oi);
long_options, &oi);
if (c == -1)
break;
break;
switch (c)
{
{
#if DU_DEBUG
case 'd':
fts_debug = true;
break;
case 'd':
fts_debug = true;
break;
#endif
case '0':
opt_nul_terminate_output = true;
break;
case '0':
opt_nul_terminate_output = true;
break;
case 'a':
opt_all = true;
break;
case 'a':
opt_all = true;
break;
case APPARENT_SIZE_OPTION:
apparent_size = true;
break;
case APPARENT_SIZE_OPTION:
apparent_size = true;
break;
case 'b':
apparent_size = true;
human_output_opts = 0;
output_block_size = 1;
break;
case 'b':
apparent_size = true;
human_output_opts = 0;
output_block_size = 1;
break;
case 'c':
print_grand_total = true;
break;
case 'c':
print_grand_total = true;
break;
case 'h':
human_output_opts = human_autoscale | human_SI | human_base_1024;
output_block_size = 1;
break;
case 'h':
human_output_opts = human_autoscale | human_SI | human_base_1024;
output_block_size = 1;
break;
case HUMAN_SI_OPTION:
human_output_opts = human_autoscale | human_SI;
output_block_size = 1;
break;
case HUMAN_SI_OPTION:
human_output_opts = human_autoscale | human_SI;
output_block_size = 1;
break;
case 'k':
human_output_opts = 0;
output_block_size = 1024;
break;
case 'k':
human_output_opts = 0;
output_block_size = 1024;
break;
case MAX_DEPTH_OPTION: /* --max-depth=N */
{
unsigned long int tmp_ulong;
if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
&& tmp_ulong <= SIZE_MAX)
{
max_depth_specified = true;
max_depth = tmp_ulong;
}
else
{
error (0, 0, _("invalid maximum depth %s"),
quote (optarg));
ok = false;
}
}
break;
case MAX_DEPTH_OPTION: /* --max-depth=N */
{
unsigned long int tmp_ulong;
if (xstrtoul (optarg, NULL, 0, &tmp_ulong, NULL) == LONGINT_OK
&& tmp_ulong <= SIZE_MAX)
{
max_depth_specified = true;
max_depth = tmp_ulong;
}
else
{
error (0, 0, _("invalid maximum depth %s"),
quote (optarg));
ok = false;
}
}
break;
case MEGABYTES_LONG_OPTION: /* FIXME: remove in 2009 */
error (0, 0,
_("the --megabytes option is deprecated; use -m instead"));
/* fall through */
case 'm':
human_output_opts = 0;
output_block_size = 1024 * 1024;
break;
case MEGABYTES_LONG_OPTION: /* FIXME: remove in 2009 */
error (0, 0,
_("the --megabytes option is deprecated; use -m instead"));
/* fall through */
case 'm':
human_output_opts = 0;
output_block_size = 1024 * 1024;
break;
case 'l':
opt_count_all = true;
break;
case 'l':
opt_count_all = true;
break;
case 's':
opt_summarize_only = true;
break;
case 's':
opt_summarize_only = true;
break;
case 'x':
bit_flags |= FTS_XDEV;
break;
case 'x':
bit_flags |= FTS_XDEV;
break;
case 'B':
{
enum strtol_error e = human_options (optarg, &human_output_opts,
&output_block_size);
if (e != LONGINT_OK)
xstrtol_fatal (e, oi, c, long_options, optarg);
}
break;
case 'B':
{
enum strtol_error e = human_options (optarg, &human_output_opts,
&output_block_size);
if (e != LONGINT_OK)
xstrtol_fatal (e, oi, c, long_options, optarg);
}
break;
case 'H': /* NOTE: before 2008-12, -H was equivalent to --si. */
case 'D':
symlink_deref_bits = FTS_COMFOLLOW | FTS_PHYSICAL;
break;
case 'H': /* NOTE: before 2008-12, -H was equivalent to --si. */
case 'D':
symlink_deref_bits = FTS_COMFOLLOW | FTS_PHYSICAL;
break;
case 'L': /* --dereference */
symlink_deref_bits = FTS_LOGICAL;
break;
case 'L': /* --dereference */
symlink_deref_bits = FTS_LOGICAL;
break;
case 'P': /* --no-dereference */
symlink_deref_bits = FTS_PHYSICAL;
break;
case 'P': /* --no-dereference */
symlink_deref_bits = FTS_PHYSICAL;
break;
case 'S':
opt_separate_dirs = true;
break;
case 'S':
opt_separate_dirs = true;
break;
case 'X':
if (add_exclude_file (add_exclude, exclude, optarg,
EXCLUDE_WILDCARDS, '\n'))
{
error (0, errno, "%s", quotearg_colon (optarg));
ok = false;
}
break;
case 'X':
if (add_exclude_file (add_exclude, exclude, optarg,
EXCLUDE_WILDCARDS, '\n'))
{
error (0, errno, "%s", quotearg_colon (optarg));
ok = false;
}
break;
case FILES0_FROM_OPTION:
files_from = optarg;
break;
case FILES0_FROM_OPTION:
files_from = optarg;
break;
case EXCLUDE_OPTION:
add_exclude (exclude, optarg, EXCLUDE_WILDCARDS);
break;
case EXCLUDE_OPTION:
add_exclude (exclude, optarg, EXCLUDE_WILDCARDS);
break;
case TIME_OPTION:
opt_time = true;
time_type =
(optarg
? XARGMATCH ("--time", optarg, time_args, time_types)
: time_mtime);
break;
case TIME_OPTION:
opt_time = true;
time_type =
(optarg
? XARGMATCH ("--time", optarg, time_args, time_types)
: time_mtime);
break;
case TIME_STYLE_OPTION:
time_style = optarg;
break;
case TIME_STYLE_OPTION:
time_style = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
ok = false;
}
default:
ok = false;
}
}
if (!ok)
usage (EXIT_FAILURE);
if (opt_all & opt_summarize_only)
if (opt_all && opt_summarize_only)
{
error (0, 0, _("cannot both summarize and show all entries"));
usage (EXIT_FAILURE);
@@ -853,7 +852,7 @@ main (int argc, char **argv)
if (opt_summarize_only && max_depth_specified && max_depth == 0)
{
error (0, 0,
_("warning: summarizing is the same as using --max-depth=0"));
_("warning: summarizing is the same as using --max-depth=0"));
}
if (opt_summarize_only && max_depth_specified && max_depth != 0)
@@ -870,48 +869,48 @@ main (int argc, char **argv)
if (opt_time)
{
if (! time_style)
{
time_style = getenv ("TIME_STYLE");
{
time_style = getenv ("TIME_STYLE");
/* Ignore TIMESTYLE="locale", for compatibility with ls. */
if (! time_style || STREQ (time_style, "locale"))
time_style = "long-iso";
else if (*time_style == '+')
{
/* Ignore anything after a newline, for compatibility
with ls. */
char *p = strchr (time_style, '\n');
if (p)
*p = '\0';
}
else
{
/* Ignore "posix-" prefix, for compatibility with ls. */
static char const posix_prefix[] = "posix-";
while (strncmp (time_style, posix_prefix, sizeof posix_prefix - 1)
== 0)
time_style += sizeof posix_prefix - 1;
}
}
/* Ignore TIMESTYLE="locale", for compatibility with ls. */
if (! time_style || STREQ (time_style, "locale"))
time_style = "long-iso";
else if (*time_style == '+')
{
/* Ignore anything after a newline, for compatibility
with ls. */
char *p = strchr (time_style, '\n');
if (p)
*p = '\0';
}
else
{
/* Ignore "posix-" prefix, for compatibility with ls. */
static char const posix_prefix[] = "posix-";
while (strncmp (time_style, posix_prefix, sizeof posix_prefix - 1)
== 0)
time_style += sizeof posix_prefix - 1;
}
}
if (*time_style == '+')
time_format = time_style + 1;
time_format = time_style + 1;
else
{
switch (XARGMATCH ("time style", time_style,
time_style_args, time_style_types))
{
case full_iso_time_style:
time_format = "%Y-%m-%d %H:%M:%S.%N %z";
break;
case full_iso_time_style:
time_format = "%Y-%m-%d %H:%M:%S.%N %z";
break;
case long_iso_time_style:
time_format = "%Y-%m-%d %H:%M";
break;
case long_iso_time_style:
time_format = "%Y-%m-%d %H:%M";
break;
case iso_time_style:
time_format = "%Y-%m-%d";
break;
case iso_time_style:
time_format = "%Y-%m-%d";
break;
}
}
}
@@ -920,18 +919,18 @@ main (int argc, char **argv)
if (files_from)
{
/* When using --files0-from=F, you may not specify any files
on the command-line. */
on the command-line. */
if (optind < argc)
{
error (0, 0, _("extra operand %s"), quote (argv[optind]));
fprintf (stderr, "%s\n",
_("file operands cannot be combined with --files0-from"));
usage (EXIT_FAILURE);
}
{
error (0, 0, _("extra operand %s"), quote (argv[optind]));
fprintf (stderr, "%s\n",
_("file operands cannot be combined with --files0-from"));
usage (EXIT_FAILURE);
}
if (! (STREQ (files_from, "-") || freopen (files_from, "r", stdin)))
error (EXIT_FAILURE, errno, _("cannot open %s for reading"),
quote (files_from));
error (EXIT_FAILURE, errno, _("cannot open %s for reading"),
quote (files_from));
ai = argv_iter_init_stream (stdin);
}
@@ -956,64 +955,63 @@ main (int argc, char **argv)
enum argv_iter_err ai_err;
char *file_name = argv_iter (ai, &ai_err);
if (ai_err == AI_ERR_EOF)
break;
break;
if (!file_name)
{
switch (ai_err)
{
case AI_ERR_READ:
error (0, errno, _("%s: read error"), quote (files_from));
skip_file = true;
continue;
{
switch (ai_err)
{
case AI_ERR_READ:
error (0, errno, _("%s: read error"), quote (files_from));
continue;
case AI_ERR_MEM:
xalloc_die ();
case AI_ERR_MEM:
xalloc_die ();
default:
assert (!"unexpected error code from argv_iter");
}
}
default:
assert (!"unexpected error code from argv_iter");
}
}
if (files_from && STREQ (files_from, "-") && STREQ (file_name, "-"))
{
/* Give a better diagnostic in an unusual case:
printf - | du --files0-from=- */
error (0, 0, _("when reading file names from stdin, "
"no file name of %s allowed"),
quote (file_name));
skip_file = true;
}
{
/* Give a better diagnostic in an unusual case:
printf - | du --files0-from=- */
error (0, 0, _("when reading file names from stdin, "
"no file name of %s allowed"),
quote (file_name));
skip_file = true;
}
/* Report and skip any empty file names before invoking fts.
This works around a glitch in fts, which fails immediately
(without looking at the other file names) when given an empty
file name. */
This works around a glitch in fts, which fails immediately
(without looking at the other file names) when given an empty
file name. */
if (!file_name[0])
{
/* Diagnose a zero-length file name. When it's one
among many, knowing the record number may help.
FIXME: currently print the record number only with
--files0-from=FILE. Maybe do it for argv, too? */
if (files_from == NULL)
error (0, 0, "%s", _("invalid zero-length file name"));
else
{
/* Using the standard `filename:line-number:' prefix here is
not totally appropriate, since NUL is the separator, not NL,
but it might be better than nothing. */
unsigned long int file_number = argv_iter_n_args (ai);
error (0, 0, "%s:%lu: %s", quotearg_colon (files_from),
file_number, _("invalid zero-length file name"));
}
skip_file = true;
}
{
/* Diagnose a zero-length file name. When it's one
among many, knowing the record number may help.
FIXME: currently print the record number only with
--files0-from=FILE. Maybe do it for argv, too? */
if (files_from == NULL)
error (0, 0, "%s", _("invalid zero-length file name"));
else
{
/* Using the standard `filename:line-number:' prefix here is
not totally appropriate, since NUL is the separator, not NL,
but it might be better than nothing. */
unsigned long int file_number = argv_iter_n_args (ai);
error (0, 0, "%s:%lu: %s", quotearg_colon (files_from),
file_number, _("invalid zero-length file name"));
}
skip_file = true;
}
if (skip_file)
ok = false;
ok = false;
else
{
temp_argv[0] = file_name;
ok &= du_files (temp_argv, bit_flags);
}
{
temp_argv[0] = file_name;
ok &= du_files (temp_argv, bit_flags);
}
}
argv_iter_free (ai);

View File

@@ -37,7 +37,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -50,13 +50,13 @@ Echo the STRING(s) to standard output.\n\
-n do not output the trailing newline\n\
"), stdout);
fputs (_(DEFAULT_ECHO_TO_XPG
? N_("\
? N_("\
-e enable interpretation of backslash escapes (default)\n\
-E disable interpretation of backslash escapes\n")
: N_("\
: N_("\
-e enable interpretation of backslash escapes\n\
-E disable interpretation of backslash escapes (default)\n")),
stdout);
stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
@@ -77,7 +77,7 @@ If -e is in effect, the following sequences are recognized:\n\
\\v vertical tab\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -128,14 +128,14 @@ main (int argc, char **argv)
if (allow_options && argc == 2)
{
if (STREQ (argv[1], "--help"))
usage (EXIT_SUCCESS);
usage (EXIT_SUCCESS);
if (STREQ (argv[1], "--version"))
{
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
(char *) NULL);
exit (EXIT_SUCCESS);
}
{
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
(char *) NULL);
exit (EXIT_SUCCESS);
}
}
--argc;
@@ -144,45 +144,45 @@ main (int argc, char **argv)
if (allow_options)
while (argc > 0 && *argv[0] == '-')
{
char const *temp = argv[0] + 1;
size_t i;
char const *temp = argv[0] + 1;
size_t i;
/* If it appears that we are handling options, then make sure that
all of the options specified are actually valid. Otherwise, the
string should just be echoed. */
/* If it appears that we are handling options, then make sure that
all of the options specified are actually valid. Otherwise, the
string should just be echoed. */
for (i = 0; temp[i]; i++)
switch (temp[i])
{
case 'e': case 'E': case 'n':
break;
default:
goto just_echo;
}
for (i = 0; temp[i]; i++)
switch (temp[i])
{
case 'e': case 'E': case 'n':
break;
default:
goto just_echo;
}
if (i == 0)
goto just_echo;
if (i == 0)
goto just_echo;
/* All of the options in TEMP are valid options to ECHO.
Handle them. */
while (*temp)
switch (*temp++)
{
case 'e':
do_v9 = true;
break;
/* All of the options in TEMP are valid options to ECHO.
Handle them. */
while (*temp)
switch (*temp++)
{
case 'e':
do_v9 = true;
break;
case 'E':
do_v9 = false;
break;
case 'E':
do_v9 = false;
break;
case 'n':
display_return = false;
break;
}
case 'n':
display_return = false;
break;
}
argc--;
argv++;
argc--;
argv++;
}
just_echo:
@@ -190,77 +190,77 @@ just_echo:
if (do_v9)
{
while (argc > 0)
{
char const *s = argv[0];
unsigned char c;
{
char const *s = argv[0];
unsigned char c;
while ((c = *s++))
{
if (c == '\\' && *s)
{
switch (c = *s++)
{
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'c': exit (EXIT_SUCCESS);
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case 'x':
{
unsigned char ch = *s;
if (! isxdigit (ch))
goto not_an_escape;
s++;
c = hextobin (ch);
ch = *s;
if (isxdigit (ch))
{
s++;
c = c * 16 + hextobin (ch);
}
}
break;
case '0':
c = 0;
if (! ('0' <= *s && *s <= '7'))
break;
c = *s++;
/* Fall through. */
case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
c -= '0';
if ('0' <= *s && *s <= '7')
c = c * 8 + (*s++ - '0');
if ('0' <= *s && *s <= '7')
c = c * 8 + (*s++ - '0');
break;
case '\\': break;
while ((c = *s++))
{
if (c == '\\' && *s)
{
switch (c = *s++)
{
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'c': exit (EXIT_SUCCESS);
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case 'x':
{
unsigned char ch = *s;
if (! isxdigit (ch))
goto not_an_escape;
s++;
c = hextobin (ch);
ch = *s;
if (isxdigit (ch))
{
s++;
c = c * 16 + hextobin (ch);
}
}
break;
case '0':
c = 0;
if (! ('0' <= *s && *s <= '7'))
break;
c = *s++;
/* Fall through. */
case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
c -= '0';
if ('0' <= *s && *s <= '7')
c = c * 8 + (*s++ - '0');
if ('0' <= *s && *s <= '7')
c = c * 8 + (*s++ - '0');
break;
case '\\': break;
not_an_escape:
default: putchar ('\\'); break;
}
}
putchar (c);
}
argc--;
argv++;
if (argc > 0)
putchar (' ');
}
not_an_escape:
default: putchar ('\\'); break;
}
}
putchar (c);
}
argc--;
argv++;
if (argc > 0)
putchar (' ');
}
}
else
{
while (argc > 0)
{
fputs (argv[0], stdout);
argc--;
argv++;
if (argc > 0)
putchar (' ');
}
{
fputs (argv[0], stdout);
argc--;
argv++;
if (argc > 0)
putchar (' ');
}
}
if (display_return)

View File

@@ -20,24 +20,24 @@
-
-i
--ignore-environment
Construct a new environment from scratch; normally the
environment is inherited from the parent process, except as
modified by other options.
Construct a new environment from scratch; normally the
environment is inherited from the parent process, except as
modified by other options.
-u variable
--unset=variable
Unset variable VARIABLE (remove it from the environment).
If VARIABLE was not set, does nothing.
Unset variable VARIABLE (remove it from the environment).
If VARIABLE was not set, does nothing.
variable=value (an arg containing a "=" character)
Set the environment variable VARIABLE to value VALUE. VALUE
may be of zero length ("variable="). Setting a variable to a
zero-length value is different from unsetting it.
Set the environment variable VARIABLE to value VALUE. VALUE
may be of zero length ("variable="). Setting a variable to a
zero-length value is different from unsetting it.
--
Indicate that the following argument is the program
to invoke. This is necessary when the program's name
begins with "-" or contains a "=".
Indicate that the following argument is the program
to invoke. This is necessary when the program's name
begins with "-" or contains a "=".
The first remaining argument specifies a program to invoke;
it is searched for according to the specification of the PATH
@@ -51,29 +51,29 @@
Examples:
If the environment passed to "env" is
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
env - foo
runs "foo" in a null environment.
runs "foo" in a null environment.
env foo
runs "foo" in the environment
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
runs "foo" in the environment
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
env DISPLAY=gnu:0 nemacs
runs "nemacs" in the environment
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks DISPLAY=gnu:0 }
runs "nemacs" in the environment
{ LOGNAME=rms EDITOR=emacs PATH=.:/gnubin:/hacks DISPLAY=gnu:0 }
env - LOGNAME=foo /hacks/hack bar baz
runs the "hack" program on arguments "bar" and "baz" in an
environment in which the only variable is "LOGNAME". Note that
the "-" option clears out the PATH variable, so one should be
careful to specify in which directory to find the program to
call.
runs the "hack" program on arguments "bar" and "baz" in an
environment in which the only variable is "LOGNAME". Note that
the "-" option clears out the PATH variable, so one should be
careful to specify in which directory to find the program to
call.
env -u EDITOR LOGNAME=foo PATH=/energy -- e=mc2 bar baz
runs the program "/energy/e=mc2" with environment
{ LOGNAME=foo PATH=/energy }
runs the program "/energy/e=mc2" with environment
{ LOGNAME=foo PATH=/energy }
*/
#include <config.h>
@@ -107,12 +107,12 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]\n"),
program_name);
program_name);
fputs (_("\
Set each NAME to VALUE in the environment and run COMMAND.\n\
\n\
@@ -125,7 +125,7 @@ Set each NAME to VALUE in the environment and run COMMAND.\n\
\n\
A mere - implies -i. If no COMMAND, print the resulting environment.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -148,17 +148,17 @@ main (int argc, char **argv)
while ((optc = getopt_long (argc, argv, "+iu:", longopts, NULL)) != -1)
{
switch (optc)
{
case 'i':
ignore_environment = true;
break;
case 'u':
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
{
case 'i':
ignore_environment = true;
break;
case 'u':
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
if (optind < argc && STREQ (argv[optind], "-"))
@@ -186,7 +186,7 @@ main (int argc, char **argv)
{
char *const *e = environ;
while (*e)
puts (*e++);
puts (*e++);
exit (EXIT_SUCCESS);
}

View File

@@ -23,10 +23,10 @@
--tabs=tab1[,tab2[,...]]
-t tab1[,tab2[,...]]
-tab1[,tab2[,...]] If only one tab stop is given, set the tabs tab1
columns apart instead of the default 8. Otherwise,
set the tabs at columns tab1, tab2, etc. (numbered from
0); replace any tabs beyond the tab stops given with
single spaces.
columns apart instead of the default 8. Otherwise,
set the tabs at columns tab1, tab2, etc. (numbered from
0); replace any tabs beyond the tab stops given with
single spaces.
--initial
-i Only convert initial tabs on each line to spaces.
@@ -97,13 +97,13 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
"),
program_name);
program_name);
fputs (_("\
Convert tabs in each FILE to spaces, writing to standard output.\n\
With no FILE, or when FILE is -, read standard input.\n\
@@ -121,7 +121,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -150,38 +150,38 @@ parse_tab_stops (char const *stops)
for (; *stops; stops++)
{
if (*stops == ',' || isblank (to_uchar (*stops)))
{
if (have_tabval)
add_tab_stop (tabval);
have_tabval = false;
}
{
if (have_tabval)
add_tab_stop (tabval);
have_tabval = false;
}
else if (ISDIGIT (*stops))
{
if (!have_tabval)
{
tabval = 0;
have_tabval = true;
num_start = stops;
}
{
if (!have_tabval)
{
tabval = 0;
have_tabval = true;
num_start = stops;
}
/* Detect overflow. */
if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t))
{
size_t len = strspn (num_start, "0123456789");
char *bad_num = xstrndup (num_start, len);
error (0, 0, _("tab stop is too large %s"), quote (bad_num));
free (bad_num);
ok = false;
stops = num_start + len - 1;
}
}
/* Detect overflow. */
if (!DECIMAL_DIGIT_ACCUMULATE (tabval, *stops - '0', uintmax_t))
{
size_t len = strspn (num_start, "0123456789");
char *bad_num = xstrndup (num_start, len);
error (0, 0, _("tab stop is too large %s"), quote (bad_num));
free (bad_num);
ok = false;
stops = num_start + len - 1;
}
}
else
{
error (0, 0, _("tab size contains invalid character(s): %s"),
quote (stops));
ok = false;
break;
}
{
error (0, 0, _("tab size contains invalid character(s): %s"),
quote (stops));
ok = false;
break;
}
}
if (!ok)
@@ -203,9 +203,9 @@ validate_tab_stops (uintmax_t const *tabs, size_t entries)
for (i = 0; i < entries; i++)
{
if (tabs[i] == 0)
error (EXIT_FAILURE, 0, _("tab size cannot be 0"));
error (EXIT_FAILURE, 0, _("tab size cannot be 0"));
if (tabs[i] <= prev_tab)
error (EXIT_FAILURE, 0, _("tab sizes must be ascending"));
error (EXIT_FAILURE, 0, _("tab sizes must be ascending"));
prev_tab = tabs[i];
}
}
@@ -224,33 +224,33 @@ next_file (FILE *fp)
if (fp)
{
if (ferror (fp))
{
error (0, errno, "%s", prev_file);
exit_status = EXIT_FAILURE;
}
{
error (0, errno, "%s", prev_file);
exit_status = EXIT_FAILURE;
}
if (STREQ (prev_file, "-"))
clearerr (fp); /* Also clear EOF. */
clearerr (fp); /* Also clear EOF. */
else if (fclose (fp) != 0)
{
error (0, errno, "%s", prev_file);
exit_status = EXIT_FAILURE;
}
{
error (0, errno, "%s", prev_file);
exit_status = EXIT_FAILURE;
}
}
while ((file = *file_list++) != NULL)
{
if (STREQ (file, "-"))
{
have_read_stdin = true;
prev_file = file;
return stdin;
}
{
have_read_stdin = true;
prev_file = file;
return stdin;
}
fp = fopen (file, "r");
if (fp)
{
prev_file = file;
return fp;
}
{
prev_file = file;
return fp;
}
error (0, errno, "%s", file);
exit_status = EXIT_FAILURE;
}
@@ -279,7 +279,7 @@ expand (void)
/* The following variables have valid values only when CONVERT
is true: */
is true: */
/* Column of next input character. */
uintmax_t column = 0;
@@ -291,68 +291,68 @@ expand (void)
/* Convert a line of text. */
do
{
while ((c = getc (fp)) < 0 && (fp = next_file (fp)))
continue;
{
while ((c = getc (fp)) < 0 && (fp = next_file (fp)))
continue;
if (convert)
{
if (c == '\t')
{
/* Column the next input tab stop is on. */
uintmax_t next_tab_column;
if (convert)
{
if (c == '\t')
{
/* Column the next input tab stop is on. */
uintmax_t next_tab_column;
if (tab_size)
next_tab_column = column + (tab_size - column % tab_size);
else
for (;;)
if (tab_index == first_free_tab)
{
next_tab_column = column + 1;
break;
}
else
{
uintmax_t tab = tab_list[tab_index++];
if (column < tab)
{
next_tab_column = tab;
break;
}
}
if (tab_size)
next_tab_column = column + (tab_size - column % tab_size);
else
for (;;)
if (tab_index == first_free_tab)
{
next_tab_column = column + 1;
break;
}
else
{
uintmax_t tab = tab_list[tab_index++];
if (column < tab)
{
next_tab_column = tab;
break;
}
}
if (next_tab_column < column)
error (EXIT_FAILURE, 0, _("input line is too long"));
if (next_tab_column < column)
error (EXIT_FAILURE, 0, _("input line is too long"));
while (++column < next_tab_column)
if (putchar (' ') < 0)
error (EXIT_FAILURE, errno, _("write error"));
while (++column < next_tab_column)
if (putchar (' ') < 0)
error (EXIT_FAILURE, errno, _("write error"));
c = ' ';
}
else if (c == '\b')
{
/* Go back one column, and force recalculation of the
next tab stop. */
column -= !!column;
tab_index -= !!tab_index;
}
else
{
column++;
if (!column)
error (EXIT_FAILURE, 0, _("input line is too long"));
}
c = ' ';
}
else if (c == '\b')
{
/* Go back one column, and force recalculation of the
next tab stop. */
column -= !!column;
tab_index -= !!tab_index;
}
else
{
column++;
if (!column)
error (EXIT_FAILURE, 0, _("input line is too long"));
}
convert &= convert_entire_line | !! isblank (c);
}
convert &= convert_entire_line || !! isblank (c);
}
if (c < 0)
return;
if (c < 0)
return;
if (putchar (c) < 0)
error (EXIT_FAILURE, errno, _("write error"));
}
if (putchar (c) < 0)
error (EXIT_FAILURE, errno, _("write error"));
}
while (c != '\n');
}
}
@@ -379,35 +379,35 @@ main (int argc, char **argv)
while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
{
switch (c)
{
case 'i':
convert_entire_line = false;
break;
{
case 'i':
convert_entire_line = false;
break;
case 't':
parse_tab_stops (optarg);
break;
case 't':
parse_tab_stops (optarg);
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (optarg)
parse_tab_stops (optarg - 1);
else
{
char tab_stop[2];
tab_stop[0] = c;
tab_stop[1] = '\0';
parse_tab_stops (tab_stop);
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (optarg)
parse_tab_stops (optarg - 1);
else
{
char tab_stop[2];
tab_stop[0] = c;
tab_stop[1] = '\0';
parse_tab_stops (tab_stop);
}
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
default:
usage (EXIT_FAILURE);
}
}
validate_tab_stops (tab_list, first_free_tab);

View File

@@ -55,7 +55,7 @@ static void integer_overflow (char) ATTRIBUTE_NORETURN;
#else
/* Approximate gmp.h well enough for expr.c's purposes. */
typedef intmax_t mpz_t[1];
static void mpz_clear (mpz_t z) {}
static void mpz_clear (mpz_t z) { (void) z; }
static void mpz_init_set_ui (mpz_t z, unsigned long int i) { z[0] = i; }
static int
mpz_init_set_str (mpz_t z, char *s, int base)
@@ -89,7 +89,7 @@ mpz_mul (mpz_t r, mpz_t a0, mpz_t b0)
intmax_t b = b0[0];
intmax_t val = a * b;
if (! (a == 0 || b == 0
|| ((val < 0) == ((a < 0) ^ (b < 0)) && val / a == b)))
|| ((val < 0) == ((a < 0) ^ (b < 0)) && val / a == b)))
integer_overflow ('*');
r[0] = val;
}
@@ -116,6 +116,7 @@ mpz_tdiv_r (mpz_t r, mpz_t a0, mpz_t b0)
static char *
mpz_get_str (char const *str, int base, mpz_t z)
{
(void) str; (void) base;
char buf[INT_BUFSIZE_BOUND (intmax_t)];
return xstrdup (imaxtostr (z[0], buf));
}
@@ -137,6 +138,7 @@ mpz_get_ui (mpz_t z)
static int
mpz_out_str (FILE *stream, int base, mpz_t z)
{
(void) base;
char buf[INT_BUFSIZE_BOUND (intmax_t)];
return fputs (imaxtostr (z[0], buf), stream) != EOF;
}
@@ -196,14 +198,14 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s EXPRESSION\n\
or: %s OPTION\n\
"),
program_name, program_name);
program_name, program_name);
putchar ('\n');
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -231,7 +233,7 @@ separates increasing precedence groups. EXPRESSION may be:\n\
ARG1 - ARG2 arithmetic difference of ARG1 and ARG2\n\
"), stdout);
/* Tell xgettext that the "% A" below is not a printf-style
format string: xgettext:no-c-format */
format string: xgettext:no-c-format */
fputs (_("\
\n\
ARG1 * ARG2 arithmetic product of ARG1 and ARG2\n\
@@ -265,7 +267,7 @@ Pattern matches return the string matched between \\( and \\) or null; if\n\
Exit status is 0 if EXPRESSION is neither null nor 0, 1 if EXPRESSION is null\n\
or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -309,7 +311,7 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, VERSION,
usage, AUTHORS, (char const *) NULL);
usage, AUTHORS, (char const *) NULL);
/* The above handles --help and --version.
Since there is no other invocation of getopt, handle `--' here. */
if (argc > 1 && STREQ (argv[1], "--"))
@@ -398,20 +400,20 @@ null (VALUE *v)
return mpz_sgn (v->u.i) == 0;
case string:
{
char const *cp = v->u.s;
if (*cp == '\0')
return true;
char const *cp = v->u.s;
if (*cp == '\0')
return true;
cp += (*cp == '-');
cp += (*cp == '-');
do
{
if (*cp != '0')
return false;
}
while (*++cp);
do
{
if (*cp != '0')
return false;
}
while (*++cp);
return true;
return true;
}
default:
abort ();
@@ -442,10 +444,10 @@ tostring (VALUE *v)
{
case integer:
{
char *s = mpz_get_str (NULL, 10, v->u.i);
mpz_clear (v->u.i);
v->u.s = s;
v->type = string;
char *s = mpz_get_str (NULL, 10, v->u.i);
mpz_clear (v->u.i);
v->u.s = s;
v->type = string;
}
break;
case string:
@@ -466,15 +468,15 @@ toarith (VALUE *v)
return true;
case string:
{
char *s = v->u.s;
char *s = v->u.s;
if (! looks_like_integer (s))
return false;
if (mpz_init_set_str (v->u.i, s, 10) != 0 && !HAVE_GMP)
error (EXPR_FAILURE, ERANGE, "%s", s);
free (s);
v->type = integer;
return true;
if (! looks_like_integer (s))
return false;
if (mpz_init_set_str (v->u.i, s, 10) != 0 && !HAVE_GMP)
error (EXPR_FAILURE, ERANGE, "%s", s);
free (s);
v->type = integer;
return true;
}
default:
abort ();
@@ -493,7 +495,7 @@ getsize (mpz_t i)
{
unsigned long int ul = mpz_get_ui (i);
if (ul < SIZE_MAX)
return ul;
return ul;
}
return SIZE_MAX - 1;
}
@@ -575,25 +577,25 @@ docolon (VALUE *sv, VALUE *pv)
{
/* Were \(...\) used? */
if (re_buffer.re_nsub > 0)
{
sv->u.s[re_regs.end[1]] = '\0';
v = str_value (sv->u.s + re_regs.start[1]);
}
{
sv->u.s[re_regs.end[1]] = '\0';
v = str_value (sv->u.s + re_regs.start[1]);
}
else
v = int_value (matchlen);
v = int_value (matchlen);
}
else if (matchlen == -1)
{
/* Match failed -- return the right kind of null. */
if (re_buffer.re_nsub > 0)
v = str_value ("");
v = str_value ("");
else
v = int_value (0);
v = int_value (0);
}
else
error (EXPR_FAILURE,
(matchlen == -2 ? errno : EOVERFLOW),
_("error in regular expression matcher"));
(matchlen == -2 ? errno : EOVERFLOW),
_("error in regular expression matcher"));
if (0 < re_regs.num_regs)
{
@@ -622,7 +624,7 @@ eval7 (bool evaluate)
{
v = eval (evaluate);
if (!nextarg (")"))
syntax_error ();
syntax_error ();
return v;
}
@@ -649,7 +651,7 @@ eval6 (bool evaluate)
if (nextarg ("+"))
{
if (nomoreargs ())
syntax_error ();
syntax_error ();
return str_value (*args++);
}
else if (nextarg ("length"))
@@ -665,12 +667,12 @@ eval6 (bool evaluate)
l = eval6 (evaluate);
r = eval6 (evaluate);
if (evaluate)
{
v = docolon (l, r);
freev (l);
}
{
v = docolon (l, r);
freev (l);
}
else
v = l;
v = l;
freev (r);
return v;
}
@@ -698,25 +700,25 @@ eval6 (bool evaluate)
llen = strlen (l->u.s);
if (!toarith (i1) || !toarith (i2))
v = str_value ("");
v = str_value ("");
else
{
size_t pos = getsize (i1->u.i);
size_t len = getsize (i2->u.i);
{
size_t pos = getsize (i1->u.i);
size_t len = getsize (i2->u.i);
if (llen < pos || pos == 0 || len == 0 || len == SIZE_MAX)
v = str_value ("");
else
{
size_t vlen = MIN (len, llen - pos + 1);
char *vlim;
v = xmalloc (sizeof *v);
v->type = string;
v->u.s = xmalloc (vlen + 1);
vlim = mempcpy (v->u.s, l->u.s + pos - 1, vlen);
*vlim = '\0';
}
}
if (llen < pos || pos == 0 || len == 0 || len == SIZE_MAX)
v = str_value ("");
else
{
size_t vlen = MIN (len, llen - pos + 1);
char *vlim;
v = xmalloc (sizeof *v);
v->type = string;
v->u.s = xmalloc (vlen + 1);
vlim = mempcpy (v->u.s, l->u.s + pos - 1, vlen);
*vlim = '\0';
}
}
freev (l);
freev (i1);
freev (i2);
@@ -743,18 +745,18 @@ eval5 (bool evaluate)
while (1)
{
if (nextarg (":"))
{
r = eval6 (evaluate);
if (evaluate)
{
v = docolon (l, r);
freev (l);
l = v;
}
freev (r);
}
{
r = eval6 (evaluate);
if (evaluate)
{
v = docolon (l, r);
freev (l);
l = v;
}
freev (r);
}
else
return l;
return l;
}
}
@@ -774,25 +776,25 @@ eval4 (bool evaluate)
while (1)
{
if (nextarg ("*"))
fxn = multiply;
fxn = multiply;
else if (nextarg ("/"))
fxn = divide;
fxn = divide;
else if (nextarg ("%"))
fxn = mod;
fxn = mod;
else
return l;
return l;
r = eval5 (evaluate);
if (evaluate)
{
if (!toarith (l) || !toarith (r))
error (EXPR_INVALID, 0, _("non-numeric argument"));
if (fxn != multiply && mpz_sgn (r->u.i) == 0)
error (EXPR_INVALID, 0, _("division by zero"));
((fxn == multiply ? mpz_mul
: fxn == divide ? mpz_tdiv_q
: mpz_tdiv_r)
(l->u.i, l->u.i, r->u.i));
}
{
if (!toarith (l) || !toarith (r))
error (EXPR_INVALID, 0, _("non-numeric argument"));
if (fxn != multiply && mpz_sgn (r->u.i) == 0)
error (EXPR_INVALID, 0, _("division by zero"));
((fxn == multiply ? mpz_mul
: fxn == divide ? mpz_tdiv_q
: mpz_tdiv_r)
(l->u.i, l->u.i, r->u.i));
}
freev (r);
}
}
@@ -813,18 +815,18 @@ eval3 (bool evaluate)
while (1)
{
if (nextarg ("+"))
fxn = plus;
fxn = plus;
else if (nextarg ("-"))
fxn = minus;
fxn = minus;
else
return l;
return l;
r = eval4 (evaluate);
if (evaluate)
{
if (!toarith (l) || !toarith (r))
error (EXPR_INVALID, 0, _("non-numeric argument"));
(fxn == plus ? mpz_add : mpz_sub) (l->u.i, l->u.i, r->u.i);
}
{
if (!toarith (l) || !toarith (r))
error (EXPR_INVALID, 0, _("non-numeric argument"));
(fxn == plus ? mpz_add : mpz_sub) (l->u.i, l->u.i, r->u.i);
}
freev (r);
}
}
@@ -844,62 +846,62 @@ eval2 (bool evaluate)
{
VALUE *r;
enum
{
less_than, less_equal, equal, not_equal, greater_equal, greater_than
} fxn;
{
less_than, less_equal, equal, not_equal, greater_equal, greater_than
} fxn;
bool val = false;
if (nextarg ("<"))
fxn = less_than;
fxn = less_than;
else if (nextarg ("<="))
fxn = less_equal;
fxn = less_equal;
else if (nextarg ("=") || nextarg ("=="))
fxn = equal;
fxn = equal;
else if (nextarg ("!="))
fxn = not_equal;
fxn = not_equal;
else if (nextarg (">="))
fxn = greater_equal;
fxn = greater_equal;
else if (nextarg (">"))
fxn = greater_than;
fxn = greater_than;
else
return l;
return l;
r = eval3 (evaluate);
if (evaluate)
{
int cmp;
tostring (l);
tostring (r);
{
int cmp;
tostring (l);
tostring (r);
if (looks_like_integer (l->u.s) && looks_like_integer (r->u.s))
cmp = strintcmp (l->u.s, r->u.s);
else
{
errno = 0;
cmp = strcoll (l->u.s, r->u.s);
if (looks_like_integer (l->u.s) && looks_like_integer (r->u.s))
cmp = strintcmp (l->u.s, r->u.s);
else
{
errno = 0;
cmp = strcoll (l->u.s, r->u.s);
if (errno)
{
error (0, errno, _("string comparison failed"));
error (0, 0, _("set LC_ALL='C' to work around the problem"));
error (EXPR_INVALID, 0,
_("the strings compared were %s and %s"),
quotearg_n_style (0, locale_quoting_style, l->u.s),
quotearg_n_style (1, locale_quoting_style, r->u.s));
}
}
if (errno)
{
error (0, errno, _("string comparison failed"));
error (0, 0, _("set LC_ALL='C' to work around the problem"));
error (EXPR_INVALID, 0,
_("the strings compared were %s and %s"),
quotearg_n_style (0, locale_quoting_style, l->u.s),
quotearg_n_style (1, locale_quoting_style, r->u.s));
}
}
switch (fxn)
{
case less_than: val = (cmp < 0); break;
case less_equal: val = (cmp <= 0); break;
case equal: val = (cmp == 0); break;
case not_equal: val = (cmp != 0); break;
case greater_equal: val = (cmp >= 0); break;
case greater_than: val = (cmp > 0); break;
default: abort ();
}
}
switch (fxn)
{
case less_than: val = (cmp < 0); break;
case less_equal: val = (cmp <= 0); break;
case equal: val = (cmp == 0); break;
case not_equal: val = (cmp != 0); break;
case greater_equal: val = (cmp >= 0); break;
case greater_than: val = (cmp > 0); break;
default: abort ();
}
}
freev (l);
freev (r);
@@ -922,19 +924,19 @@ eval1 (bool evaluate)
while (1)
{
if (nextarg ("&"))
{
r = eval2 (evaluate & ~ null (l));
if (null (l) || null (r))
{
freev (l);
freev (r);
l = int_value (0);
}
else
freev (r);
}
{
r = eval2 (evaluate && !null (l));
if (null (l) || null (r))
{
freev (l);
freev (r);
l = int_value (0);
}
else
freev (r);
}
else
return l;
return l;
}
}
@@ -953,22 +955,22 @@ eval (bool evaluate)
while (1)
{
if (nextarg ("|"))
{
r = eval1 (evaluate & null (l));
if (null (l))
{
freev (l);
l = r;
if (null (l))
{
freev (l);
l = int_value (0);
}
}
else
freev (r);
}
{
r = eval1 (evaluate && null (l));
if (null (l))
{
freev (l);
l = r;
if (null (l))
{
freev (l);
l = int_value (0);
}
}
else
freev (r);
}
else
return l;
return l;
}
}

View File

@@ -114,10 +114,10 @@ EOF
while (defined (my $line = <FH>))
{
$line =~ /^[ \t]+case S_MAGIC_/
or next;
or next;
$line =~ m!^[ \t]+case (S_MAGIC_\w+): /\* (0x[0-9A-Fa-f]+) \*/$!
or (warn "$ME:$file:$.: malformed case S_MAGIC_... line"),
$fail = 1, next;
or (warn "$ME:$file:$.: malformed case S_MAGIC_... line"),
$fail = 1, next;
my $name = $1;
my $value = $2;
print "# define $name $value\n";

View File

@@ -26,7 +26,7 @@
#include <stdio.h>
#include <sys/types.h>
#if HAVE_GMP
#include <gmp.h>
# include <gmp.h>
#endif
#include <assert.h>
@@ -110,7 +110,7 @@ factor_using_division (mpz_t t, unsigned int limit)
{
mpz_tdiv_qr_ui (q, r, t, 3);
if (mpz_cmp_ui (r, 0) != 0)
break;
break;
mpz_set (t, q);
emit_ul_factor (3);
}
@@ -119,7 +119,7 @@ factor_using_division (mpz_t t, unsigned int limit)
{
mpz_tdiv_qr_ui (q, r, t, 5);
if (mpz_cmp_ui (r, 0) != 0)
break;
break;
mpz_set (t, q);
emit_ul_factor (5);
}
@@ -131,21 +131,21 @@ factor_using_division (mpz_t t, unsigned int limit)
{
mpz_tdiv_qr_ui (q, r, t, f);
if (mpz_cmp_ui (r, 0) != 0)
{
f += addv[ai];
if (mpz_cmp_ui (q, f) < 0)
break;
ai = (ai + 1) & 7;
failures++;
if (failures > limit)
break;
}
{
f += addv[ai];
if (mpz_cmp_ui (q, f) < 0)
break;
ai = (ai + 1) & 7;
failures++;
if (failures > limit)
break;
}
else
{
mpz_swap (t, q);
emit_ul_factor (f);
failures = 0;
}
{
mpz_swap (t, q);
emit_ul_factor (f);
failures = 0;
}
}
mpz_clear (q);
@@ -184,67 +184,67 @@ S2:
mpz_sub (t1, x1, x); mpz_mul (t2, P, t1); mpz_mod (P, t2, n);
c++;
if (c == 20)
{
c = 0;
mpz_gcd (g, P, n);
if (mpz_cmp_ui (g, 1) != 0)
goto S4;
mpz_set (y, x);
}
{
c = 0;
mpz_gcd (g, P, n);
if (mpz_cmp_ui (g, 1) != 0)
goto S4;
mpz_set (y, x);
}
k--;
if (k > 0)
goto S2;
goto S2;
mpz_gcd (g, P, n);
if (mpz_cmp_ui (g, 1) != 0)
goto S4;
goto S4;
mpz_set (x1, x);
k = l;
l = 2 * l;
for (i = 0; i < k; i++)
{
mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
}
{
mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
}
mpz_set (y, x);
c = 0;
goto S2;
S4:
do
{
mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);
mpz_sub (t1, x1, y); mpz_gcd (g, t1, n);
}
{
mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);
mpz_sub (t1, x1, y); mpz_gcd (g, t1, n);
}
while (mpz_cmp_ui (g, 1) == 0);
mpz_div (n, n, g); /* divide by g, before g is overwritten */
if (!mpz_probab_prime_p (g, 3))
{
do
{
mp_limb_t a_limb;
mpn_random (&a_limb, (mp_size_t) 1);
a_int = (int) a_limb;
}
while (a_int == -2 || a_int == 0);
{
do
{
mp_limb_t a_limb;
mpn_random (&a_limb, (mp_size_t) 1);
a_int = (int) a_limb;
}
while (a_int == -2 || a_int == 0);
debug ("[composite factor--restarting pollard-rho] ");
factor_using_pollard_rho (g, a_int);
}
debug ("[composite factor--restarting pollard-rho] ");
factor_using_pollard_rho (g, a_int);
}
else
{
emit_factor (g);
}
{
emit_factor (g);
}
mpz_mod (x, x, n);
mpz_mod (x1, x1, n);
mpz_mod (y, y, n);
if (mpz_probab_prime_p (n, 3))
{
emit_factor (n);
break;
}
{
emit_factor (n);
break;
}
}
mpz_clear (g);
@@ -309,15 +309,15 @@ factor_wheel (uintmax_t n0, size_t max_n_factors, uintmax_t *factors)
{
q = n / d;
while (n == q * d)
{
assert (n_factors < max_n_factors);
factors[n_factors++] = d;
n = q;
q = n / d;
}
{
assert (n_factors < max_n_factors);
factors[n_factors++] = d;
n = q;
q = n / d;
}
d += *(w++);
if (w == WHEEL_END)
w = WHEEL_START;
w = WHEEL_START;
}
while (d <= q);
@@ -407,13 +407,13 @@ print_factors_multi (mpz_t t)
factor_using_division (t, division_limit);
if (mpz_cmp_ui (t, 1) != 0)
{
debug ("[is number prime?] ");
if (mpz_probab_prime_p (t, 3))
emit_factor (t);
else
factor_using_pollard_rho (t, 1);
}
{
debug ("[is number prime?] ");
if (mpz_probab_prime_p (t, 3))
emit_factor (t);
else
factor_using_pollard_rho (t, 1);
}
}
mpz_clear (t);
@@ -443,11 +443,11 @@ print_factors (char const *s)
mpz_t t;
mpz_init (t);
if (gmp_sscanf (s, "%Zd", t) == 1)
{
debug ("[%s]", _("using arbitrary-precision arithmetic"));
print_factors_multi (t);
return true;
}
{
debug ("[%s]", _("using arbitrary-precision arithmetic"));
print_factors_multi (t);
return true;
}
err = LONGINT_INVALID;
}
#endif
@@ -487,14 +487,14 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [NUMBER]...\n\
or: %s OPTION\n\
"),
program_name, program_name);
program_name, program_name);
fputs (_("\
Print the prime factors of each specified integer NUMBER. If none\n\
are specified on the command line, read them from standard input.\n\
@@ -502,7 +502,7 @@ are specified on the command line, read them from standard input.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -518,9 +518,9 @@ do_stdin (void)
for (;;)
{
size_t token_length = readtoken (stdin, DELIM, sizeof (DELIM) - 1,
&tokenbuffer);
&tokenbuffer);
if (token_length == (size_t) -1)
break;
break;
ok &= print_factors (tokenbuffer.buffer);
}
free (tokenbuffer.buffer);
@@ -545,18 +545,18 @@ main (int argc, char **argv)
while ((c = getopt_long (argc, argv, "", long_options, NULL)) != -1)
{
switch (c)
{
case VERBOSE_OPTION:
verbose = true;
break;
{
case VERBOSE_OPTION:
verbose = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
default:
usage (EXIT_FAILURE);
}
}
if (argc <= optind)
@@ -566,8 +566,8 @@ main (int argc, char **argv)
int i;
ok = true;
for (i = optind; i < argc; i++)
if (! print_factors (argv[i]))
ok = false;
if (! print_factors (argv[i]))
ok = false;
}
#if HAVE_GMP
free (factor);

296
src/fmt.c
View File

@@ -263,7 +263,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("Usage: %s [-WIDTH] [OPTION]... [FILE]...\n"), program_name);
@@ -281,7 +281,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
reattaching the prefix to reformatted lines\n\
-s, --split-only split long lines, but do not refill\n\
"),
stdout);
stdout);
fputs (_("\
-t, --tagged-paragraph indentation of first line different from second\n\
-u, --uniform-spacing one space between words, two after sentences\n\
@@ -292,8 +292,8 @@ Mandatory arguments to long options are mandatory for short options too.\n\
fputs (_("\
\n\
With no FILE, or when FILE is -, read standard input.\n"),
stdout);
emit_bug_reporting_address ();
stdout);
emit_ancillary_info ();
}
exit (status);
}
@@ -345,40 +345,40 @@ main (int argc, char **argv)
}
while ((optchar = getopt_long (argc, argv, "0123456789cstuw:p:",
long_options, NULL))
!= -1)
long_options, NULL))
!= -1)
switch (optchar)
{
default:
if (ISDIGIT (optchar))
error (0, 0, _("invalid option -- %c; -WIDTH is recognized\
if (ISDIGIT (optchar))
error (0, 0, _("invalid option -- %c; -WIDTH is recognized\
only when it is the first\noption; use -w N instead"),
optchar);
usage (EXIT_FAILURE);
optchar);
usage (EXIT_FAILURE);
case 'c':
crown = true;
break;
crown = true;
break;
case 's':
split = true;
break;
split = true;
break;
case 't':
tagged = true;
break;
tagged = true;
break;
case 'u':
uniform = true;
break;
uniform = true;
break;
case 'w':
max_width_option = optarg;
break;
max_width_option = optarg;
break;
case 'p':
set_prefix (optarg);
break;
set_prefix (optarg);
break;
case_GETOPT_HELP_CHAR;
@@ -389,12 +389,12 @@ main (int argc, char **argv)
if (max_width_option)
{
/* Limit max_width to MAXCHARS / 2; otherwise, the resulting
output can be quite ugly. */
output can be quite ugly. */
unsigned long int tmp;
if (! (xstrtoul (max_width_option, NULL, 10, &tmp, "") == LONGINT_OK
&& tmp <= MAXCHARS / 2))
error (EXIT_FAILURE, 0, _("invalid width: %s"),
quote (max_width_option));
&& tmp <= MAXCHARS / 2))
error (EXIT_FAILURE, 0, _("invalid width: %s"),
quote (max_width_option));
max_width = tmp;
}
@@ -405,31 +405,31 @@ main (int argc, char **argv)
else
{
for (; optind < argc; optind++)
{
char *file = argv[optind];
if (STREQ (file, "-"))
fmt (stdin);
else
{
FILE *in_stream;
in_stream = fopen (file, "r");
if (in_stream != NULL)
{
fmt (in_stream);
if (fclose (in_stream) == EOF)
{
error (0, errno, "%s", file);
ok = false;
}
}
else
{
error (0, errno, _("cannot open %s for reading"),
quote (file));
ok = false;
}
}
}
{
char *file = argv[optind];
if (STREQ (file, "-"))
fmt (stdin);
else
{
FILE *in_stream;
in_stream = fopen (file, "r");
if (in_stream != NULL)
{
fmt (in_stream);
if (fclose (in_stream) == EOF)
{
error (0, errno, "%s", file);
ok = false;
}
}
else
{
error (0, errno, _("cannot open %s for reading"),
quote (file));
ok = false;
}
}
}
}
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
@@ -488,9 +488,9 @@ set_other_indent (bool same_paragraph)
else if (tagged)
{
if (same_paragraph && in_column != first_indent)
{
other_indent = in_column;
}
{
other_indent = in_column;
}
/* Only one line: use the secondary indent from last time if it
splits, or 0 if there have been no multi-line paragraphs in the
@@ -498,7 +498,7 @@ set_other_indent (bool same_paragraph)
pick a new secondary indent. */
else if (other_indent == first_indent)
other_indent = first_indent == 0 ? DEF_INDENT : 0;
other_indent = first_indent == 0 ? DEF_INDENT : 0;
}
else
{
@@ -532,15 +532,15 @@ get_paragraph (FILE *f)
/* Scan (and copy) blank lines, and lines not introduced by the prefix. */
while (c == '\n' || c == EOF
|| next_prefix_indent < prefix_lead_space
|| in_column < next_prefix_indent + prefix_full_length)
|| next_prefix_indent < prefix_lead_space
|| in_column < next_prefix_indent + prefix_full_length)
{
c = copy_rest (f, c);
if (c == EOF)
{
next_char = EOF;
return false;
}
{
next_char = EOF;
return false;
}
putchar ('\n');
c = get_prefix (f);
}
@@ -563,29 +563,29 @@ get_paragraph (FILE *f)
else if (crown)
{
if (same_para (c))
{
do
{ /* for each line till the end of the para */
c = get_line (f, c);
}
while (same_para (c) && in_column == other_indent);
}
{
do
{ /* for each line till the end of the para */
c = get_line (f, c);
}
while (same_para (c) && in_column == other_indent);
}
}
else if (tagged)
{
if (same_para (c) && in_column != first_indent)
{
do
{ /* for each line till the end of the para */
c = get_line (f, c);
}
while (same_para (c) && in_column == other_indent);
}
{
do
{ /* for each line till the end of the para */
c = get_line (f, c);
}
while (same_para (c) && in_column == other_indent);
}
}
else
{
while (same_para (c) && in_column == other_indent)
c = get_line (f, c);
c = get_line (f, c);
}
(word_limit - 1)->period = (word_limit - 1)->final = true;
next_char = c;
@@ -607,11 +607,11 @@ copy_rest (FILE *f, int c)
{
put_space (next_prefix_indent);
for (s = prefix; out_column != in_column && *s; out_column++)
putchar (*s++);
putchar (*s++);
if (c != EOF && c != '\n')
put_space (in_column - out_column);
put_space (in_column - out_column);
if (c == EOF && in_column >= next_prefix_indent + prefix_length)
putchar ('\n');
putchar ('\n');
}
while (c != '\n' && c != EOF)
{
@@ -629,8 +629,8 @@ static bool
same_para (int c)
{
return (next_prefix_indent == prefix_indent
&& in_column >= next_prefix_indent + prefix_full_length
&& c != '\n' && c != EOF);
&& in_column >= next_prefix_indent + prefix_full_length
&& c != '\n' && c != EOF);
}
/* Read a line from input file F, given first non-blank character C
@@ -658,15 +658,15 @@ get_line (FILE *f, int c)
word_limit->text = wptr;
do
{
if (wptr == end_of_parabuf)
{
set_other_indent (true);
flush_paragraph ();
}
*wptr++ = c;
c = getc (f);
}
{
if (wptr == end_of_parabuf)
{
set_other_indent (true);
flush_paragraph ();
}
*wptr++ = c;
c = getc (f);
}
while (c != EOF && !isspace (c));
in_column += word_limit->length = wptr - word_limit->text;
check_punctuation (word_limit);
@@ -677,15 +677,15 @@ get_line (FILE *f, int c)
c = get_space (f, c);
word_limit->space = in_column - start;
word_limit->final = (c == EOF
|| (word_limit->period
&& (c == '\n' || word_limit->space > 1)));
|| (word_limit->period
&& (c == '\n' || word_limit->space > 1)));
if (c == '\n' || c == EOF || uniform)
word_limit->space = word_limit->final ? 2 : 1;
word_limit->space = word_limit->final ? 2 : 1;
if (word_limit == end_of_word)
{
set_other_indent (true);
flush_paragraph ();
}
{
set_other_indent (true);
flush_paragraph ();
}
word_limit++;
}
while (c != '\n' && c != EOF);
@@ -710,13 +710,13 @@ get_prefix (FILE *f)
const char *p;
next_prefix_indent = in_column;
for (p = prefix; *p != '\0'; p++)
{
unsigned char pc = *p;
if (c != pc)
return c;
in_column++;
c = getc (f);
}
{
unsigned char pc = *p;
if (c != pc)
return c;
in_column++;
c = getc (f);
}
c = get_space (f, c);
}
return c;
@@ -731,14 +731,14 @@ get_space (FILE *f, int c)
for (;;)
{
if (c == ' ')
in_column++;
in_column++;
else if (c == '\t')
{
tabs = true;
in_column = (in_column / TABWIDTH + 1) * TABWIDTH;
}
{
tabs = true;
in_column = (in_column / TABWIDTH + 1) * TABWIDTH;
}
else
return c;
return c;
c = getc (f);
}
}
@@ -794,12 +794,12 @@ flush_paragraph (void)
for (w = word->next_break; w != word_limit; w = w->next_break)
{
if (w->best_cost - w->next_break->best_cost < best_break)
{
split_point = w;
best_break = w->best_cost - w->next_break->best_cost;
}
{
split_point = w;
best_break = w->best_cost - w->next_break->best_cost;
}
if (best_break <= MAXCOST - LINE_CREDIT)
best_break += LINE_CREDIT;
best_break += LINE_CREDIT;
}
put_paragraph (split_point);
@@ -848,30 +848,30 @@ fmt_paragraph (void)
w = start;
len += w->length;
do
{
w++;
{
w++;
/* Consider breaking before w. */
/* Consider breaking before w. */
wcost = line_cost (w, len) + w->best_cost;
if (start == word && last_line_length > 0)
wcost += RAGGED_COST (len - last_line_length);
if (wcost < best)
{
best = wcost;
start->next_break = w;
start->line_length = len;
}
wcost = line_cost (w, len) + w->best_cost;
if (start == word && last_line_length > 0)
wcost += RAGGED_COST (len - last_line_length);
if (wcost < best)
{
best = wcost;
start->next_break = w;
start->line_length = len;
}
/* This is a kludge to keep us from computing `len' as the
sum of the sentinel length and some non-zero number.
Since the sentinel w->length may be INT_MAX, adding
to that would give a negative result. */
if (w == word_limit)
break;
/* This is a kludge to keep us from computing `len' as the
sum of the sentinel length and some non-zero number.
Since the sentinel w->length may be INT_MAX, adding
to that would give a negative result. */
if (w == word_limit)
break;
len += (w - 1)->space + w->length; /* w > start >= word */
}
len += (w - 1)->space + w->length; /* w > start >= word */
}
while (len < max_width);
start->best_cost = best + base_cost (start);
}
@@ -892,16 +892,16 @@ base_cost (WORD *this)
if (this > word)
{
if ((this - 1)->period)
{
if ((this - 1)->final)
cost -= SENTENCE_BONUS;
else
cost += NOBREAK_COST;
}
{
if ((this - 1)->final)
cost -= SENTENCE_BONUS;
else
cost += NOBREAK_COST;
}
else if ((this - 1)->punct)
cost -= PUNCT_BONUS;
cost -= PUNCT_BONUS;
else if (this > word + 1 && (this - 2)->final)
cost += WIDOW_COST ((this - 1)->length);
cost += WIDOW_COST ((this - 1)->length);
}
if (this->paren)
@@ -997,11 +997,11 @@ put_space (int space)
{
tab_target = space_target / TABWIDTH * TABWIDTH;
if (out_column + 1 < tab_target)
while (out_column < tab_target)
{
putchar ('\t');
out_column = (out_column / TABWIDTH + 1) * TABWIDTH;
}
while (out_column < tab_target)
{
putchar ('\t');
out_column = (out_column / TABWIDTH + 1) * TABWIDTH;
}
}
while (out_column < space_target)
{

View File

@@ -60,13 +60,13 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
"),
program_name);
program_name);
fputs (_("\
Wrap input lines in each FILE (standard input by default), writing to\n\
standard output.\n\
@@ -82,7 +82,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -97,16 +97,16 @@ adjust_column (size_t column, char c)
if (!count_bytes)
{
if (c == '\b')
{
if (column > 0)
column--;
}
{
if (column > 0)
column--;
}
else if (c == '\r')
column = 0;
column = 0;
else if (c == '\t')
column += TAB_WIDTH - column % TAB_WIDTH;
column += TAB_WIDTH - column % TAB_WIDTH;
else /* if (isprint (c)) */
column++;
column++;
}
else
column++;
@@ -145,71 +145,71 @@ fold_file (char const *filename, size_t width)
while ((c = getc (istream)) != EOF)
{
if (offset_out + 1 >= allocated_out)
line_out = X2REALLOC (line_out, &allocated_out);
line_out = X2REALLOC (line_out, &allocated_out);
if (c == '\n')
{
line_out[offset_out++] = c;
fwrite (line_out, sizeof (char), offset_out, stdout);
column = offset_out = 0;
continue;
}
{
line_out[offset_out++] = c;
fwrite (line_out, sizeof (char), offset_out, stdout);
column = offset_out = 0;
continue;
}
rescan:
column = adjust_column (column, c);
if (column > width)
{
/* This character would make the line too long.
Print the line plus a newline, and make this character
start the next line. */
if (break_spaces)
{
bool found_blank = false;
size_t logical_end = offset_out;
{
/* This character would make the line too long.
Print the line plus a newline, and make this character
start the next line. */
if (break_spaces)
{
bool found_blank = false;
size_t logical_end = offset_out;
/* Look for the last blank. */
while (logical_end)
{
--logical_end;
if (isblank (to_uchar (line_out[logical_end])))
{
found_blank = true;
break;
}
}
/* Look for the last blank. */
while (logical_end)
{
--logical_end;
if (isblank (to_uchar (line_out[logical_end])))
{
found_blank = true;
break;
}
}
if (found_blank)
{
size_t i;
if (found_blank)
{
size_t i;
/* Found a blank. Don't output the part after it. */
logical_end++;
fwrite (line_out, sizeof (char), (size_t) logical_end,
stdout);
putchar ('\n');
/* Move the remainder to the beginning of the next line.
The areas being copied here might overlap. */
memmove (line_out, line_out + logical_end,
offset_out - logical_end);
offset_out -= logical_end;
for (column = i = 0; i < offset_out; i++)
column = adjust_column (column, line_out[i]);
goto rescan;
}
}
/* Found a blank. Don't output the part after it. */
logical_end++;
fwrite (line_out, sizeof (char), (size_t) logical_end,
stdout);
putchar ('\n');
/* Move the remainder to the beginning of the next line.
The areas being copied here might overlap. */
memmove (line_out, line_out + logical_end,
offset_out - logical_end);
offset_out -= logical_end;
for (column = i = 0; i < offset_out; i++)
column = adjust_column (column, line_out[i]);
goto rescan;
}
}
if (offset_out == 0)
{
line_out[offset_out++] = c;
continue;
}
if (offset_out == 0)
{
line_out[offset_out++] = c;
continue;
}
line_out[offset_out++] = '\n';
fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
column = offset_out = 0;
goto rescan;
}
line_out[offset_out++] = '\n';
fwrite (line_out, sizeof (char), (size_t) offset_out, stdout);
column = offset_out = 0;
goto rescan;
}
line_out[offset_out++] = c;
}
@@ -223,7 +223,7 @@ fold_file (char const *filename, size_t width)
{
error (0, saved_errno, "%s", filename);
if (!STREQ (filename, "-"))
fclose (istream);
fclose (istream);
return false;
}
if (!STREQ (filename, "-") && fclose (istream) == EOF)
@@ -258,44 +258,44 @@ main (int argc, char **argv)
char optargbuf[2];
switch (optc)
{
case 'b': /* Count bytes rather than columns. */
count_bytes = true;
break;
{
case 'b': /* Count bytes rather than columns. */
count_bytes = true;
break;
case 's': /* Break at word boundaries. */
break_spaces = true;
break;
case 's': /* Break at word boundaries. */
break_spaces = true;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (optarg)
optarg--;
else
{
optargbuf[0] = optc;
optargbuf[1] = '\0';
optarg = optargbuf;
}
/* Fall through. */
case 'w': /* Line width. */
{
unsigned long int tmp_ulong;
if (! (xstrtoul (optarg, NULL, 10, &tmp_ulong, "") == LONGINT_OK
&& 0 < tmp_ulong && tmp_ulong < SIZE_MAX - TAB_WIDTH))
error (EXIT_FAILURE, 0,
_("invalid number of columns: %s"), quote (optarg));
width = tmp_ulong;
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (optarg)
optarg--;
else
{
optargbuf[0] = optc;
optargbuf[1] = '\0';
optarg = optargbuf;
}
/* Fall through. */
case 'w': /* Line width. */
{
unsigned long int tmp_ulong;
if (! (xstrtoul (optarg, NULL, 10, &tmp_ulong, "") == LONGINT_OK
&& 0 < tmp_ulong && tmp_ulong < SIZE_MAX - TAB_WIDTH))
error (EXIT_FAILURE, 0,
_("invalid number of columns: %s"), quote (optarg));
width = tmp_ulong;
}
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
default:
usage (EXIT_FAILURE);
}
}
if (argc == optind)
@@ -304,7 +304,7 @@ main (int argc, char **argv)
{
ok = true;
for (i = optind; i < argc; i++)
ok &= fold_file (argv[i], width);
ok &= fold_file (argv[i], width);
}
if (have_read_stdin && fclose (stdin) == EOF)

View File

@@ -73,7 +73,7 @@ Output platform dependent limits in a format useful for shell scripts.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -172,9 +172,3 @@ main (int argc, char **argv)
print_int (INTMAX);
print_int (UINTMAX);
}
/*
* Local variables:
* indent-tabs-mode: nil
* End:
*/

View File

@@ -113,9 +113,3 @@ print_group (gid_t gid, bool use_name)
printf ("%s", grp->gr_name);
return ok;
}
/*
* Local variables:
* indent-tabs-mode: nil
* End:
*/

View File

@@ -58,7 +58,7 @@ the current process (which may differ if the groups database has changed).\n"),
stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -124,9 +124,3 @@ main (int argc, char **argv)
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
}
/*
* Local variables:
* indent-tabs-mode: nil
* End:
*/

View File

@@ -102,13 +102,13 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
"),
program_name);
program_name);
fputs (_("\
Print the first 10 lines of each FILE to standard output.\n\
With more than one FILE, precede each with a header giving the file name.\n\
@@ -138,7 +138,7 @@ K may have a multiplier suffix:\n\
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\
GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -186,15 +186,15 @@ copy_fd (int src_fd, FILE *o_stream, uintmax_t n_bytes)
size_t n_to_read = MIN (buf_size, n_bytes);
size_t n_read = safe_read (src_fd, buf, n_to_read);
if (n_read == SAFE_READ_ERROR)
return COPY_FD_READ_ERROR;
return COPY_FD_READ_ERROR;
n_bytes -= n_read;
if (n_read == 0 && n_bytes != 0)
return COPY_FD_UNEXPECTED_EOF;
return COPY_FD_UNEXPECTED_EOF;
if (fwrite (buf, 1, n_read, o_stream) < n_read)
return COPY_FD_WRITE_ERROR;
return COPY_FD_WRITE_ERROR;
}
return COPY_FD_OK;
@@ -229,7 +229,7 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
{
char umax_buf[INT_BUFSIZE_BOUND (uintmax_t)];
error (EXIT_FAILURE, 0, _("%s: number of bytes is too large"),
umaxtostr (n_elide_0, umax_buf));
umaxtostr (n_elide_0, umax_buf));
}
/* Two cases to consider...
@@ -255,54 +255,54 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
b[1] = b[0] + n_to_read;
for (i = false; ! eof ; i = !i)
{
size_t n_read = full_read (fd, b[i], n_to_read);
size_t delta = 0;
if (n_read < n_to_read)
{
if (errno != 0)
{
error (0, errno, _("error reading %s"), quote (filename));
ok = false;
break;
}
{
size_t n_read = full_read (fd, b[i], n_to_read);
size_t delta = 0;
if (n_read < n_to_read)
{
if (errno != 0)
{
error (0, errno, _("error reading %s"), quote (filename));
ok = false;
break;
}
/* reached EOF */
if (n_read <= n_elide)
{
if (first)
{
/* The input is no larger than the number of bytes
to elide. So there's nothing to output, and
we're done. */
}
else
{
delta = n_elide - n_read;
}
}
eof = true;
}
/* reached EOF */
if (n_read <= n_elide)
{
if (first)
{
/* The input is no larger than the number of bytes
to elide. So there's nothing to output, and
we're done. */
}
else
{
delta = n_elide - n_read;
}
}
eof = true;
}
/* Output any (but maybe just part of the) elided data from
the previous round. */
if ( ! first)
{
/* Don't bother checking for errors here.
If there's a failure, the test of the following
fwrite or in close_stdout will catch it. */
fwrite (b[!i] + READ_BUFSIZE, 1, n_elide - delta, stdout);
}
first = false;
/* Output any (but maybe just part of the) elided data from
the previous round. */
if ( ! first)
{
/* Don't bother checking for errors here.
If there's a failure, the test of the following
fwrite or in close_stdout will catch it. */
fwrite (b[!i] + READ_BUFSIZE, 1, n_elide - delta, stdout);
}
first = false;
if (n_elide < n_read
&& fwrite (b[i], 1, n_read - n_elide, stdout) < n_read - n_elide)
{
error (0, errno, _("write error"));
ok = false;
break;
}
}
if (n_elide < n_read
&& fwrite (b[i], 1, n_read - n_elide, stdout) < n_read - n_elide)
{
error (0, errno, _("write error"));
ok = false;
break;
}
}
free (b[0]);
return ok;
@@ -310,7 +310,7 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
else
{
/* Read blocks of size READ_BUFSIZE, until we've read at least n_elide
bytes. Then, for each new buffer we read, also write an old one. */
bytes. Then, for each new buffer we read, also write an old one. */
bool ok = true;
bool eof = false;
@@ -326,74 +326,74 @@ elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
buffered_enough = false;
for (i = 0, i_next = 1; !eof; i = i_next, i_next = (i_next + 1) % n_bufs)
{
if (b[i] == NULL)
b[i] = xmalloc (READ_BUFSIZE);
n_read = full_read (fd, b[i], READ_BUFSIZE);
if (n_read < READ_BUFSIZE)
{
if (errno != 0)
{
error (0, errno, _("error reading %s"), quote (filename));
ok = false;
goto free_mem;
}
eof = true;
}
{
if (b[i] == NULL)
b[i] = xmalloc (READ_BUFSIZE);
n_read = full_read (fd, b[i], READ_BUFSIZE);
if (n_read < READ_BUFSIZE)
{
if (errno != 0)
{
error (0, errno, _("error reading %s"), quote (filename));
ok = false;
goto free_mem;
}
eof = true;
}
if (i + 1 == n_bufs)
buffered_enough = true;
if (i + 1 == n_bufs)
buffered_enough = true;
if (buffered_enough)
{
if (fwrite (b[i_next], 1, n_read, stdout) < n_read)
{
error (0, errno, _("write error"));
ok = false;
goto free_mem;
}
}
}
if (buffered_enough)
{
if (fwrite (b[i_next], 1, n_read, stdout) < n_read)
{
error (0, errno, _("write error"));
ok = false;
goto free_mem;
}
}
}
/* Output any remainder: rem bytes from b[i] + n_read. */
if (rem)
{
if (buffered_enough)
{
size_t n_bytes_left_in_b_i = READ_BUFSIZE - n_read;
if (rem < n_bytes_left_in_b_i)
{
fwrite (b[i] + n_read, 1, rem, stdout);
}
else
{
fwrite (b[i] + n_read, 1, n_bytes_left_in_b_i, stdout);
fwrite (b[i_next], 1, rem - n_bytes_left_in_b_i, stdout);
}
}
else if (i + 1 == n_bufs)
{
/* This happens when n_elide < file_size < n_elide_round.
{
if (buffered_enough)
{
size_t n_bytes_left_in_b_i = READ_BUFSIZE - n_read;
if (rem < n_bytes_left_in_b_i)
{
fwrite (b[i] + n_read, 1, rem, stdout);
}
else
{
fwrite (b[i] + n_read, 1, n_bytes_left_in_b_i, stdout);
fwrite (b[i_next], 1, rem - n_bytes_left_in_b_i, stdout);
}
}
else if (i + 1 == n_bufs)
{
/* This happens when n_elide < file_size < n_elide_round.
|READ_BUF.|
| | rem |
|---------!---------!---------!---------|
|---- n_elide ---------|
| | x |
| |y |
|---- file size -----------|
| |n_read|
|---- n_elide_round ----------|
*/
size_t y = READ_BUFSIZE - rem;
size_t x = n_read - y;
fwrite (b[i_next], 1, x, stdout);
}
}
|READ_BUF.|
| | rem |
|---------!---------!---------!---------|
|---- n_elide ---------|
| | x |
| |y |
|---- file size -----------|
| |n_read|
|---- n_elide_round ----------|
*/
size_t y = READ_BUFSIZE - rem;
size_t x = n_read - y;
fwrite (b[i_next], 1, x, stdout);
}
}
free_mem:;
for (i = 0; i < n_bufs; i++)
free (b[i]);
free (b[i]);
free (b);
return ok;
@@ -424,31 +424,31 @@ elide_tail_bytes_file (const char *filename, int fd, uintmax_t n_elide)
enum Copy_fd_status err;
if ((current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) == -1
|| (end_pos = lseek (fd, (off_t) 0, SEEK_END)) == -1)
{
error (0, errno, _("cannot lseek %s"), quote (filename));
return false;
}
|| (end_pos = lseek (fd, (off_t) 0, SEEK_END)) == -1)
{
error (0, errno, _("cannot lseek %s"), quote (filename));
return false;
}
/* Be careful here. The current position may actually be
beyond the end of the file. */
beyond the end of the file. */
bytes_remaining = (diff = end_pos - current_pos) < 0 ? 0 : diff;
if (bytes_remaining <= n_elide)
return true;
return true;
/* Seek back to `current' position, then copy the required
number of bytes from fd. */
number of bytes from fd. */
if (lseek (fd, (off_t) 0, current_pos) == -1)
{
error (0, errno, _("%s: cannot lseek back to original position"),
quote (filename));
return false;
}
{
error (0, errno, _("%s: cannot lseek back to original position"),
quote (filename));
return false;
}
err = copy_fd (fd, stdout, bytes_remaining - n_elide);
if (err == COPY_FD_OK)
return true;
return true;
diagnose_copy_fd_failure (err, filename);
return false;
@@ -488,20 +488,20 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
{
n_read = safe_read (fd, tmp->buffer, BUFSIZ);
if (n_read == 0 || n_read == SAFE_READ_ERROR)
break;
break;
tmp->nbytes = n_read;
tmp->nlines = 0;
tmp->next = NULL;
/* Count the number of newlines just read. */
{
char const *buffer_end = tmp->buffer + n_read;
char const *p = tmp->buffer;
while ((p = memchr (p, '\n', buffer_end - p)))
{
++p;
++tmp->nlines;
}
char const *buffer_end = tmp->buffer + n_read;
char const *p = tmp->buffer;
while ((p = memchr (p, '\n', buffer_end - p)))
{
++p;
++tmp->nlines;
}
}
total_lines += tmp->nlines;
@@ -509,29 +509,29 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
one to it. This is because when reading from a pipe, `n_read' can
often be very small. */
if (tmp->nbytes + last->nbytes < BUFSIZ)
{
memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
last->nbytes += tmp->nbytes;
last->nlines += tmp->nlines;
}
{
memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
last->nbytes += tmp->nbytes;
last->nlines += tmp->nlines;
}
else
{
/* If there's not enough room, link the new buffer onto the end of
the list, then either free up the oldest buffer for the next
read if that would leave enough lines, or else malloc a new one.
Some compaction mechanism is possible but probably not
worthwhile. */
last = last->next = tmp;
if (n_elide < total_lines - first->nlines)
{
fwrite (first->buffer, 1, first->nbytes, stdout);
tmp = first;
total_lines -= first->nlines;
first = first->next;
}
else
tmp = xmalloc (sizeof (LBUFFER));
}
{
/* If there's not enough room, link the new buffer onto the end of
the list, then either free up the oldest buffer for the next
read if that would leave enough lines, or else malloc a new one.
Some compaction mechanism is possible but probably not
worthwhile. */
last = last->next = tmp;
if (n_elide < total_lines - first->nlines)
{
fwrite (first->buffer, 1, first->nbytes, stdout);
tmp = first;
total_lines -= first->nlines;
first = first->next;
}
else
tmp = xmalloc (sizeof (LBUFFER));
}
}
free (tmp);
@@ -564,11 +564,11 @@ elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
char const *buffer_end = tmp->buffer + tmp->nbytes;
char const *p = tmp->buffer;
while (n && (p = memchr (p, '\n', buffer_end - p)))
{
++p;
++tmp->nlines;
--n;
}
{
++p;
++tmp->nlines;
--n;
}
fwrite (tmp->buffer, 1, p - tmp->buffer, stdout);
}
@@ -595,8 +595,8 @@ free_lbuffers:
in a less efficient implementation or a messy interface. */
static bool
elide_tail_lines_seekable (const char *pretty_filename, int fd,
uintmax_t n_lines,
off_t start_pos, off_t end_pos)
uintmax_t n_lines,
off_t start_pos, off_t end_pos)
{
char buffer[BUFSIZ];
size_t bytes_read;
@@ -614,7 +614,7 @@ elide_tail_lines_seekable (const char *pretty_filename, int fd,
{
char offset_buf[INT_BUFSIZE_BOUND (off_t)];
error (0, errno, _("%s: cannot seek to offset %s"),
pretty_filename, offtostr (pos, offset_buf));
pretty_filename, offtostr (pos, offset_buf));
return false;
}
bytes_read = safe_read (fd, buffer, bytes_read);
@@ -634,72 +634,72 @@ elide_tail_lines_seekable (const char *pretty_filename, int fd,
size_t n = bytes_read;
while (n)
{
char const *nl;
nl = memrchr (buffer, '\n', n);
if (nl == NULL)
break;
n = nl - buffer;
if (n_lines-- == 0)
{
/* Found it. */
/* If necessary, restore the file pointer and copy
input to output up to position, POS. */
if (start_pos < pos)
{
enum Copy_fd_status err;
if (lseek (fd, start_pos, SEEK_SET) < 0)
{
/* Failed to reposition file pointer. */
error (0, errno,
"%s: unable to restore file pointer to initial offset",
quote (pretty_filename));
return false;
}
{
char const *nl;
nl = memrchr (buffer, '\n', n);
if (nl == NULL)
break;
n = nl - buffer;
if (n_lines-- == 0)
{
/* Found it. */
/* If necessary, restore the file pointer and copy
input to output up to position, POS. */
if (start_pos < pos)
{
enum Copy_fd_status err;
if (lseek (fd, start_pos, SEEK_SET) < 0)
{
/* Failed to reposition file pointer. */
error (0, errno,
"%s: unable to restore file pointer to initial offset",
quote (pretty_filename));
return false;
}
err = copy_fd (fd, stdout, pos - start_pos);
if (err != COPY_FD_OK)
{
diagnose_copy_fd_failure (err, pretty_filename);
return false;
}
}
err = copy_fd (fd, stdout, pos - start_pos);
if (err != COPY_FD_OK)
{
diagnose_copy_fd_failure (err, pretty_filename);
return false;
}
}
/* Output the initial portion of the buffer
in which we found the desired newline byte.
Don't bother testing for failure for such a small amount.
Any failure will be detected upon close. */
fwrite (buffer, 1, n + 1, stdout);
return true;
}
}
/* Output the initial portion of the buffer
in which we found the desired newline byte.
Don't bother testing for failure for such a small amount.
Any failure will be detected upon close. */
fwrite (buffer, 1, n + 1, stdout);
return true;
}
}
/* Not enough newlines in that bufferfull. */
if (pos == start_pos)
{
/* Not enough lines in the file. */
return true;
}
{
/* Not enough lines in the file. */
return true;
}
pos -= BUFSIZ;
if (lseek (fd, pos, SEEK_SET) < 0)
{
char offset_buf[INT_BUFSIZE_BOUND (off_t)];
error (0, errno, _("%s: cannot seek to offset %s"),
pretty_filename, offtostr (pos, offset_buf));
return false;
}
{
char offset_buf[INT_BUFSIZE_BOUND (off_t)];
error (0, errno, _("%s: cannot seek to offset %s"),
pretty_filename, offtostr (pos, offset_buf));
return false;
}
bytes_read = safe_read (fd, buffer, BUFSIZ);
if (bytes_read == SAFE_READ_ERROR)
{
error (0, errno, _("error reading %s"), quote (pretty_filename));
return false;
}
{
error (0, errno, _("error reading %s"), quote (pretty_filename));
return false;
}
/* FIXME: is this dead code?
Consider the test, pos == start_pos, above. */
Consider the test, pos == start_pos, above. */
if (bytes_read == 0)
return true;
return true;
}
}
@@ -713,24 +713,24 @@ elide_tail_lines_file (const char *filename, int fd, uintmax_t n_elide)
if (!presume_input_pipe)
{
/* Find the offset, OFF, of the Nth newline from the end,
but not counting the last byte of the file.
If found, write from current position to OFF, inclusive.
Otherwise, just return true. */
but not counting the last byte of the file.
If found, write from current position to OFF, inclusive.
Otherwise, just return true. */
off_t start_pos = lseek (fd, (off_t) 0, SEEK_CUR);
off_t end_pos = lseek (fd, (off_t) 0, SEEK_END);
if (0 <= start_pos && start_pos < end_pos)
{
/* If the file is empty, we're done. */
if (end_pos == 0)
return true;
{
/* If the file is empty, we're done. */
if (end_pos == 0)
return true;
return elide_tail_lines_seekable (filename, fd, n_elide,
start_pos, end_pos);
}
return elide_tail_lines_seekable (filename, fd, n_elide,
start_pos, end_pos);
}
/* lseek failed or the end offset precedes start.
Fall through. */
Fall through. */
}
return elide_tail_lines_pipe (filename, fd, n_elide);
@@ -746,17 +746,17 @@ head_bytes (const char *filename, int fd, uintmax_t bytes_to_write)
{
size_t bytes_read;
if (bytes_to_write < bytes_to_read)
bytes_to_read = bytes_to_write;
bytes_to_read = bytes_to_write;
bytes_read = safe_read (fd, buffer, bytes_to_read);
if (bytes_read == SAFE_READ_ERROR)
{
error (0, errno, _("error reading %s"), quote (filename));
return false;
}
{
error (0, errno, _("error reading %s"), quote (filename));
return false;
}
if (bytes_read == 0)
break;
break;
if (fwrite (buffer, 1, bytes_read, stdout) < bytes_read)
error (EXIT_FAILURE, errno, _("write error"));
error (EXIT_FAILURE, errno, _("write error"));
bytes_to_write -= bytes_read;
}
return true;
@@ -773,31 +773,31 @@ head_lines (const char *filename, int fd, uintmax_t lines_to_write)
size_t bytes_to_write = 0;
if (bytes_read == SAFE_READ_ERROR)
{
error (0, errno, _("error reading %s"), quote (filename));
return false;
}
{
error (0, errno, _("error reading %s"), quote (filename));
return false;
}
if (bytes_read == 0)
break;
break;
while (bytes_to_write < bytes_read)
if (buffer[bytes_to_write++] == '\n' && --lines_to_write == 0)
{
off_t n_bytes_past_EOL = bytes_read - bytes_to_write;
/* If we have read more data than that on the specified number
of lines, try to seek back to the position we would have
gotten to had we been reading one byte at a time. */
if (lseek (fd, -n_bytes_past_EOL, SEEK_CUR) < 0)
{
int e = errno;
struct stat st;
if (fstat (fd, &st) != 0 || S_ISREG (st.st_mode))
error (0, e, _("cannot reposition file pointer for %s"),
quote (filename));
}
break;
}
if (buffer[bytes_to_write++] == '\n' && --lines_to_write == 0)
{
off_t n_bytes_past_EOL = bytes_read - bytes_to_write;
/* If we have read more data than that on the specified number
of lines, try to seek back to the position we would have
gotten to had we been reading one byte at a time. */
if (lseek (fd, -n_bytes_past_EOL, SEEK_CUR) < 0)
{
int e = errno;
struct stat st;
if (fstat (fd, &st) != 0 || S_ISREG (st.st_mode))
error (0, e, _("cannot reposition file pointer for %s"),
quote (filename));
}
break;
}
if (fwrite (buffer, 1, bytes_to_write, stdout) < bytes_to_write)
error (EXIT_FAILURE, errno, _("write error"));
error (EXIT_FAILURE, errno, _("write error"));
}
return true;
}
@@ -812,13 +812,13 @@ head (const char *filename, int fd, uintmax_t n_units, bool count_lines,
if (elide_from_end)
{
if (count_lines)
{
return elide_tail_lines_file (filename, fd, n_units);
}
{
return elide_tail_lines_file (filename, fd, n_units);
}
else
{
return elide_tail_bytes_file (filename, fd, n_units);
}
{
return elide_tail_bytes_file (filename, fd, n_units);
}
}
if (count_lines)
return head_lines (filename, fd, n_units);
@@ -828,7 +828,7 @@ head (const char *filename, int fd, uintmax_t n_units, bool count_lines,
static bool
head_file (const char *filename, uintmax_t n_units, bool count_lines,
bool elide_from_end)
bool elide_from_end)
{
int fd;
bool ok;
@@ -840,16 +840,16 @@ head_file (const char *filename, uintmax_t n_units, bool count_lines,
fd = STDIN_FILENO;
filename = _("standard input");
if (O_BINARY && ! isatty (STDIN_FILENO))
xfreopen (NULL, "rb", stdin);
xfreopen (NULL, "rb", stdin);
}
else
{
fd = open (filename, O_RDONLY | O_BINARY);
if (fd < 0)
{
error (0, errno, _("cannot open %s for reading"), quote (filename));
return false;
}
{
error (0, errno, _("cannot open %s for reading"), quote (filename));
return false;
}
}
ok = head (filename, fd, n_units, count_lines, elide_from_end);
@@ -878,16 +878,16 @@ string_to_integer (bool count_lines, const char *n_string)
if (s_err == LONGINT_OVERFLOW)
{
error (EXIT_FAILURE, 0,
_("%s: %s is so large that it is not representable"), n_string,
count_lines ? _("number of lines") : _("number of bytes"));
_("%s: %s is so large that it is not representable"), n_string,
count_lines ? _("number of lines") : _("number of bytes"));
}
if (s_err != LONGINT_OK)
{
error (EXIT_FAILURE, 0, "%s: %s", n_string,
(count_lines
? _("invalid number of lines")
: _("invalid number of bytes")));
(count_lines
? _("invalid number of lines")
: _("invalid number of bytes")));
}
return n;
@@ -937,7 +937,7 @@ main (int argc, char **argv)
char multiplier_char = 0;
/* Old option syntax; a dash, one or more digits, and one or
more option letters. Move past the number. */
more option letters. Move past the number. */
do ++a;
while (ISDIGIT (*a));
@@ -946,44 +946,44 @@ main (int argc, char **argv)
/* Parse any appended option letters. */
for (; *a; a++)
{
switch (*a)
{
case 'c':
count_lines = false;
multiplier_char = 0;
break;
{
switch (*a)
{
case 'c':
count_lines = false;
multiplier_char = 0;
break;
case 'b':
case 'k':
case 'm':
count_lines = false;
multiplier_char = *a;
break;
case 'b':
case 'k':
case 'm':
count_lines = false;
multiplier_char = *a;
break;
case 'l':
count_lines = true;
break;
case 'l':
count_lines = true;
break;
case 'q':
header_mode = never;
break;
case 'q':
header_mode = never;
break;
case 'v':
header_mode = always;
break;
case 'v':
header_mode = always;
break;
default:
error (0, 0, _("invalid trailing option -- %c"), *a);
usage (EXIT_FAILURE);
}
}
default:
error (0, 0, _("invalid trailing option -- %c"), *a);
usage (EXIT_FAILURE);
}
}
/* Append the multiplier character (if any) onto the end of
the digit string. Then add NUL byte if necessary. */
the digit string. Then add NUL byte if necessary. */
*end_n_string = multiplier_char;
if (multiplier_char)
*(++end_n_string) = 0;
*(++end_n_string) = 0;
n_units = string_to_integer (count_lines, n_string);
@@ -994,47 +994,47 @@ main (int argc, char **argv)
}
while ((c = getopt_long (argc, argv, "c:n:qv0123456789", long_options, NULL))
!= -1)
!= -1)
{
switch (c)
{
case PRESUME_INPUT_PIPE_OPTION:
presume_input_pipe = true;
break;
{
case PRESUME_INPUT_PIPE_OPTION:
presume_input_pipe = true;
break;
case 'c':
count_lines = false;
elide_from_end = (*optarg == '-');
if (elide_from_end)
++optarg;
n_units = string_to_integer (count_lines, optarg);
break;
case 'c':
count_lines = false;
elide_from_end = (*optarg == '-');
if (elide_from_end)
++optarg;
n_units = string_to_integer (count_lines, optarg);
break;
case 'n':
count_lines = true;
elide_from_end = (*optarg == '-');
if (elide_from_end)
++optarg;
n_units = string_to_integer (count_lines, optarg);
break;
case 'n':
count_lines = true;
elide_from_end = (*optarg == '-');
if (elide_from_end)
++optarg;
n_units = string_to_integer (count_lines, optarg);
break;
case 'q':
header_mode = never;
break;
case 'q':
header_mode = never;
break;
case 'v':
header_mode = always;
break;
case 'v':
header_mode = always;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
if (ISDIGIT (c))
error (0, 0, _("invalid trailing option -- %c"), c);
usage (EXIT_FAILURE);
}
default:
if (ISDIGIT (c))
error (0, 0, _("invalid trailing option -- %c"), c);
usage (EXIT_FAILURE);
}
}
if (header_mode == always
@@ -1045,12 +1045,12 @@ main (int argc, char **argv)
{
char umax_buf[INT_BUFSIZE_BOUND (uintmax_t)];
error (EXIT_FAILURE, 0, _("%s: number of bytes is too large"),
umaxtostr (n_units, umax_buf));
umaxtostr (n_units, umax_buf));
}
file_list = (optind < argc
? (char const *const *) &argv[optind]
: default_file_list);
? (char const *const *) &argv[optind]
: default_file_list);
if (O_BINARY && ! isatty (STDOUT_FILENO))
xfreopen (NULL, "wb", stdout);

View File

@@ -38,7 +38,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -48,7 +48,7 @@ Print the numeric identifier (in hexadecimal) for the current host.\n\
"), program_name);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -67,7 +67,7 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
usage, AUTHORS, (char const *) NULL);
usage, AUTHORS, (char const *) NULL);
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
usage (EXIT_FAILURE);

View File

@@ -51,7 +51,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -63,7 +63,7 @@ Print or set the hostname of the current system.\n\
program_name, program_name);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -82,7 +82,7 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
usage, AUTHORS, (char const *) NULL);
usage, AUTHORS, (char const *) NULL);
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
usage (EXIT_FAILURE);
@@ -92,10 +92,10 @@ main (int argc, char **argv)
/* Set hostname to operand. */
char const *name = argv[optind];
if (sethostname (name, strlen (name)) != 0)
error (EXIT_FAILURE, errno, _("cannot set name to %s"), quote (name));
error (EXIT_FAILURE, errno, _("cannot set name to %s"), quote (name));
#else
error (EXIT_FAILURE, 0,
_("cannot set hostname; this system lacks the functionality"));
_("cannot set hostname; this system lacks the functionality"));
#endif
}
@@ -103,7 +103,7 @@ main (int argc, char **argv)
{
hostname = xgethostname ();
if (hostname == NULL)
error (EXIT_FAILURE, errno, _("cannot determine hostname"));
error (EXIT_FAILURE, errno, _("cannot determine hostname"));
printf ("%s\n", hostname);
}

127
src/id.c
View File

@@ -76,7 +76,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("Usage: %s [OPTION]... [USERNAME]\n"), program_name);
@@ -98,7 +98,7 @@ or (when USERNAME omitted) for the current user.\n\
\n\
Without any OPTION, print some useful set of identified information.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -129,39 +129,39 @@ main (int argc, char **argv)
while ((optc = getopt_long (argc, argv, "agnruGZ", longopts, NULL)) != -1)
{
switch (optc)
{
case 'a':
/* Ignore -a, for compatibility with SVR4. */
break;
{
case 'a':
/* Ignore -a, for compatibility with SVR4. */
break;
case 'Z':
/* politely decline if we're not on a selinux-enabled kernel. */
if (!selinux_enabled)
error (EXIT_FAILURE, 0,
_("--context (-Z) works only on an SELinux-enabled kernel"));
/* politely decline if we're not on a selinux-enabled kernel. */
if (!selinux_enabled)
error (EXIT_FAILURE, 0,
_("--context (-Z) works only on an SELinux-enabled kernel"));
just_context = 1;
break;
case 'g':
just_group = true;
break;
case 'n':
use_name = true;
break;
case 'r':
use_real = true;
break;
case 'u':
just_user = true;
break;
case 'G':
just_group_list = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
case 'g':
just_group = true;
break;
case 'n':
use_name = true;
break;
case 'r':
use_real = true;
break;
case 'u':
just_user = true;
break;
case 'G':
just_group_list = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
if (1 < argc - optind)
@@ -172,7 +172,7 @@ main (int argc, char **argv)
if (argc - optind == 1 && just_context)
error (EXIT_FAILURE, 0,
_("cannot print security context when user specified"));
_("cannot print security context when user specified"));
/* If we are on a selinux-enabled kernel and no user is specified,
get our context. Otherwise, leave the context variable alone -
@@ -187,15 +187,15 @@ main (int argc, char **argv)
if (just_user + just_group + just_group_list + just_context > 1)
error (EXIT_FAILURE, 0, _("cannot print \"only\" of more than one choice"));
if (just_user + just_group + just_group_list == 0 && (use_real | use_name))
if (just_user + just_group + just_group_list == 0 && (use_real || use_name))
error (EXIT_FAILURE, 0,
_("cannot print only names or real IDs in default format"));
_("cannot print only names or real IDs in default format"));
if (argc - optind == 1)
{
struct passwd *pwd = getpwnam (argv[optind]);
if (pwd == NULL)
error (EXIT_FAILURE, 0, _("%s: No such user"), argv[optind]);
error (EXIT_FAILURE, 0, _("%s: No such user"), argv[optind]);
ruid = euid = pwd->pw_uid;
rgid = egid = pwd->pw_gid;
}
@@ -214,12 +214,12 @@ main (int argc, char **argv)
else if (just_group)
{
if (!print_group (use_real ? rgid : egid, use_name))
ok = false;
ok = false;
}
else if (just_group_list)
{
if (!print_group_list (argv[optind], ruid, rgid, egid, use_name))
ok = false;
ok = false;
}
else if (just_context)
{
@@ -245,11 +245,11 @@ print_user (uid_t uid)
{
pwd = getpwuid (uid);
if (pwd == NULL)
{
error (0, 0, _("cannot find name for user ID %lu"),
(unsigned long int) uid);
ok = false;
}
{
error (0, 0, _("cannot find name for user ID %lu"),
(unsigned long int) uid);
ok = false;
}
}
if (pwd == NULL)
@@ -281,7 +281,7 @@ print_full_info (const char *username)
printf (_(" euid=%lu"), (unsigned long int) euid);
pwd = getpwuid (euid);
if (pwd)
printf ("(%s)", pwd->pw_name);
printf ("(%s)", pwd->pw_name);
}
if (egid != rgid)
@@ -289,7 +289,7 @@ print_full_info (const char *username)
printf (_(" egid=%lu"), (unsigned long int) egid);
grp = getgrgid (egid);
if (grp)
printf ("(%s)", grp->gr_name);
printf ("(%s)", grp->gr_name);
}
#if HAVE_GETGROUPS
@@ -298,36 +298,39 @@ print_full_info (const char *username)
int i;
int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
&groups);
&groups);
if (n_groups < 0)
{
if (username)
{
error (0, errno, _("failed to get groups for user %s"),
quote (username));
}
else
{
error (0, errno, _("failed to get groups for the current process"));
}
ok = false;
return;
if (username)
{
error (0, errno, _("failed to get groups for user %s"),
quote (username));
}
else
{
error (0, errno, _("failed to get groups for the current process"));
}
ok = false;
return;
}
if (n_groups > 0)
fputs (_(" groups="), stdout);
for (i = 0; i < n_groups; i++)
{
if (i > 0)
putchar (',');
printf ("%lu", (unsigned long int) groups[i]);
grp = getgrgid (groups[i]);
if (grp)
printf ("(%s)", grp->gr_name);
if (i > 0)
putchar (',');
printf ("%lu", (unsigned long int) groups[i]);
grp = getgrgid (groups[i]);
if (grp)
printf ("(%s)", grp->gr_name);
}
free (groups);
}
#endif /* HAVE_GETGROUPS */
if (context != NULL)
/* POSIX mandates the precise output format, and that it not include
any context=... part, so skip that if POSIXLY_CORRECT is set. */
if (context != NULL && ! getenv ("POSIXLY_CORRECT"))
printf (_(" context=%s"), context);
}

View File

@@ -74,18 +74,18 @@ static bool use_default_selinux_context = true;
static bool change_timestamps (struct stat const *from_sb, char const *to);
static bool change_attributes (char const *name);
static bool copy_file (const char *from, const char *to,
const struct cp_options *x);
const struct cp_options *x);
static bool install_file_in_file_parents (char const *from, char *to,
struct cp_options *x);
struct cp_options *x);
static bool install_file_in_dir (const char *from, const char *to_dir,
const struct cp_options *x);
const struct cp_options *x);
static bool install_file_in_file (const char *from, const char *to,
const struct cp_options *x);
const struct cp_options *x);
static void get_ids (void);
static void strip (char const *name);
static void announce_mkdir (char const *dir, void *options);
static int make_ancestor (char const *dir, char const *component,
void *options);
void *options);
void usage (int status);
/* The user name that will own the files, or NULL to make the owner
@@ -195,7 +195,7 @@ extra_mode (mode_t input)
/* Return true if copy of file SRC_NAME to file DEST_NAME is necessary. */
static bool
need_copy (const char *src_name, const char *dest_name,
const struct cp_options *x)
const struct cp_options *x)
{
struct stat src_sb, dest_sb;
int src_fd, dest_fd;
@@ -229,20 +229,20 @@ need_copy (const char *src_name, const char *dest_name,
bool scontext_match;
if (getfilecon (src_name, &file_scontext) == -1)
return true;
return true;
if (getfilecon (dest_name, &to_scontext) == -1)
{
freecon (file_scontext);
return true;
}
{
freecon (file_scontext);
return true;
}
scontext_match = STREQ (file_scontext, to_scontext);
freecon (file_scontext);
freecon (to_scontext);
if (!scontext_match)
return true;
return true;
}
/* compare files content */
@@ -269,7 +269,7 @@ cp_option_init (struct cp_options *x)
{
cp_options_default (x);
x->copy_as_regular = true;
x->reflink = false;
x->reflink_mode = REFLINK_NEVER;
x->dereference = DEREF_ALWAYS;
x->unlink_dest_before_opening = true;
x->unlink_dest_after_failed_open = false;
@@ -328,37 +328,37 @@ setdefaultfilecon (char const *file)
if (first_call && IS_ABSOLUTE_FILE_NAME (file))
{
/* Calling matchpathcon_init_prefix (NULL, "/first_component/")
is an optimization to minimize the expense of the following
matchpathcon call. Do it only once, just before the first
matchpathcon call. We *could* call matchpathcon_fini after
the final matchpathcon call, but that's not necessary, since
by then we're about to exit, and besides, the buffers it
would free are still reachable. */
is an optimization to minimize the expense of the following
matchpathcon call. Do it only once, just before the first
matchpathcon call. We *could* call matchpathcon_fini after
the final matchpathcon call, but that's not necessary, since
by then we're about to exit, and besides, the buffers it
would free are still reachable. */
char const *p0;
char const *p = file + 1;
while (ISSLASH (*p))
++p;
++p;
/* Record final leading slash, for when FILE starts with two or more. */
p0 = p - 1;
if (*p)
{
char *prefix;
do
{
++p;
}
while (*p && !ISSLASH (*p));
{
char *prefix;
do
{
++p;
}
while (*p && !ISSLASH (*p));
prefix = malloc (p - p0 + 2);
if (prefix)
{
stpcpy (stpncpy (prefix, p0, p - p0), "/");
matchpathcon_init_prefix (NULL, prefix);
free (prefix);
}
}
prefix = malloc (p - p0 + 2);
if (prefix)
{
stpcpy (stpncpy (prefix, p0, p - p0), "/");
matchpathcon_init_prefix (NULL, prefix);
free (prefix);
}
}
}
first_call = false;
@@ -368,14 +368,14 @@ setdefaultfilecon (char const *file)
STREQ (scontext, "<<none>>"))
{
if (scontext != NULL)
freecon (scontext);
freecon (scontext);
return;
}
if (lsetfilecon (file, scontext) < 0 && errno != ENOTSUP)
error (0, errno,
_("warning: %s: failed to change context to %s"),
quotearg_colon (file), scontext);
_("warning: %s: failed to change context to %s"),
quotearg_colon (file), scontext);
freecon (scontext);
return;
@@ -414,11 +414,11 @@ static int
process_dir (char *dir, struct savewd *wd, void *options)
{
return (make_dir_parents (dir, wd,
make_ancestor, options,
dir_mode, announce_mkdir,
dir_mode_bits, owner_id, group_id, false)
? EXIT_SUCCESS
: EXIT_FAILURE);
make_ancestor, options,
dir_mode, announce_mkdir,
dir_mode_bits, owner_id, group_id, false)
? EXIT_SUCCESS
: EXIT_FAILURE);
}
int
@@ -462,131 +462,131 @@ main (int argc, char **argv)
backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z:", long_options,
NULL)) != -1)
NULL)) != -1)
{
switch (optc)
{
case 'b':
make_backups = true;
if (optarg)
version_control_string = optarg;
break;
case 'c':
break;
case 'C':
copy_only_if_needed = true;
break;
case 's':
strip_files = true;
{
case 'b':
make_backups = true;
if (optarg)
version_control_string = optarg;
break;
case 'c':
break;
case 'C':
copy_only_if_needed = true;
break;
case 's':
strip_files = true;
#ifdef SIGCHLD
/* System V fork+wait does not work if SIGCHLD is ignored. */
signal (SIGCHLD, SIG_DFL);
/* System V fork+wait does not work if SIGCHLD is ignored. */
signal (SIGCHLD, SIG_DFL);
#endif
break;
case STRIP_PROGRAM_OPTION:
strip_program = xstrdup (optarg);
strip_program_specified = true;
break;
case 'd':
dir_arg = true;
break;
case 'D':
mkdir_and_install = true;
break;
case 'v':
x.verbose = true;
break;
case 'g':
group_name = optarg;
break;
case 'm':
specified_mode = optarg;
break;
case 'o':
owner_name = optarg;
break;
case 'p':
x.preserve_timestamps = true;
break;
case 'S':
make_backups = true;
backup_suffix_string = optarg;
break;
case 't':
if (target_directory)
error (EXIT_FAILURE, 0,
_("multiple target directories specified"));
else
{
struct stat st;
if (stat (optarg, &st) != 0)
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
if (! S_ISDIR (st.st_mode))
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (optarg));
}
target_directory = optarg;
break;
case 'T':
no_target_directory = true;
break;
break;
case STRIP_PROGRAM_OPTION:
strip_program = xstrdup (optarg);
strip_program_specified = true;
break;
case 'd':
dir_arg = true;
break;
case 'D':
mkdir_and_install = true;
break;
case 'v':
x.verbose = true;
break;
case 'g':
group_name = optarg;
break;
case 'm':
specified_mode = optarg;
break;
case 'o':
owner_name = optarg;
break;
case 'p':
x.preserve_timestamps = true;
break;
case 'S':
make_backups = true;
backup_suffix_string = optarg;
break;
case 't':
if (target_directory)
error (EXIT_FAILURE, 0,
_("multiple target directories specified"));
else
{
struct stat st;
if (stat (optarg, &st) != 0)
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
if (! S_ISDIR (st.st_mode))
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (optarg));
}
target_directory = optarg;
break;
case 'T':
no_target_directory = true;
break;
case PRESERVE_CONTEXT_OPTION_DEPRECATED:
error (0, 0, _("WARNING: --preserve_context is deprecated; "
"use --preserve-context instead"));
/* fall through */
case PRESERVE_CONTEXT_OPTION:
if ( ! selinux_enabled)
{
error (0, 0, _("WARNING: ignoring --preserve-context; "
"this kernel is not SELinux-enabled"));
break;
}
x.preserve_security_context = true;
use_default_selinux_context = false;
break;
case 'Z':
if ( ! selinux_enabled)
{
error (0, 0, _("WARNING: ignoring --context (-Z); "
"this kernel is not SELinux-enabled"));
break;
}
scontext = optarg;
use_default_selinux_context = false;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
case PRESERVE_CONTEXT_OPTION_DEPRECATED:
error (0, 0, _("WARNING: --preserve_context is deprecated; "
"use --preserve-context instead"));
/* fall through */
case PRESERVE_CONTEXT_OPTION:
if ( ! selinux_enabled)
{
error (0, 0, _("WARNING: ignoring --preserve-context; "
"this kernel is not SELinux-enabled"));
break;
}
x.preserve_security_context = true;
use_default_selinux_context = false;
break;
case 'Z':
if ( ! selinux_enabled)
{
error (0, 0, _("WARNING: ignoring --context (-Z); "
"this kernel is not SELinux-enabled"));
break;
}
scontext = optarg;
use_default_selinux_context = false;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
/* Check for invalid combinations of arguments. */
if (dir_arg & strip_files)
if (dir_arg && strip_files)
error (EXIT_FAILURE, 0,
_("the strip option may not be used when installing a directory"));
_("the strip option may not be used when installing a directory"));
if (dir_arg && target_directory)
error (EXIT_FAILURE, 0,
_("target directory not allowed when installing a directory"));
_("target directory not allowed when installing a directory"));
if (x.preserve_security_context && scontext != NULL)
error (EXIT_FAILURE, 0,
_("cannot force target context to %s and preserve it"),
quote (scontext));
_("cannot force target context to %s and preserve it"),
quote (scontext));
if (backup_suffix_string)
simple_backup_suffix = xstrdup (backup_suffix_string);
x.backup_type = (make_backups
? xget_version (_("backup type"),
version_control_string)
: no_backups);
? xget_version (_("backup type"),
version_control_string)
: no_backups);
if (scontext && setfscreatecon (scontext) < 0)
error (EXIT_FAILURE, errno,
_("failed to set default file creation context to %s"),
quote (scontext));
_("failed to set default file creation context to %s"),
quote (scontext));
n_files = argc - optind;
file = argv + optind;
@@ -594,39 +594,39 @@ main (int argc, char **argv)
if (n_files <= ! (dir_arg || target_directory))
{
if (n_files <= 0)
error (0, 0, _("missing file operand"));
error (0, 0, _("missing file operand"));
else
error (0, 0, _("missing destination file operand after %s"),
quote (file[0]));
error (0, 0, _("missing destination file operand after %s"),
quote (file[0]));
usage (EXIT_FAILURE);
}
if (no_target_directory)
{
if (target_directory)
error (EXIT_FAILURE, 0,
_("cannot combine --target-directory (-t) "
"and --no-target-directory (-T)"));
error (EXIT_FAILURE, 0,
_("cannot combine --target-directory (-t) "
"and --no-target-directory (-T)"));
if (2 < n_files)
{
error (0, 0, _("extra operand %s"), quote (file[2]));
usage (EXIT_FAILURE);
}
{
error (0, 0, _("extra operand %s"), quote (file[2]));
usage (EXIT_FAILURE);
}
}
else if (! (dir_arg || target_directory))
{
if (2 <= n_files && target_directory_operand (file[n_files - 1]))
target_directory = file[--n_files];
target_directory = file[--n_files];
else if (2 < n_files)
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (file[n_files - 1]));
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (file[n_files - 1]));
}
if (specified_mode)
{
struct mode_change *change = mode_compile (specified_mode);
if (!change)
error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
mode = mode_adjust (0, false, 0, change, NULL);
dir_mode = mode_adjust (0, true, 0, change, &dir_mode_bits);
free (change);
@@ -634,25 +634,25 @@ main (int argc, char **argv)
if (strip_program_specified && !strip_files)
error (0, 0, _("WARNING: ignoring --strip-program option as -s option was "
"not specified"));
"not specified"));
if (copy_only_if_needed && x.preserve_timestamps)
{
error (0, 0, _("options --compare (-C) and --preserve-timestamps are "
"mutually exclusive"));
"mutually exclusive"));
usage (EXIT_FAILURE);
}
if (copy_only_if_needed && strip_files)
{
error (0, 0, _("options --compare (-C) and --strip are mutually "
"exclusive"));
"exclusive"));
usage (EXIT_FAILURE);
}
if (copy_only_if_needed && extra_mode (mode))
error (0, 0, _("the --compare (-C) option is ignored when you"
" specify a mode with non-permission bits"));
" specify a mode with non-permission bits"));
get_ids ();
@@ -661,24 +661,24 @@ main (int argc, char **argv)
else
{
/* FIXME: it's a little gross that this initialization is
required by copy.c::copy. */
required by copy.c::copy. */
hash_init ();
if (!target_directory)
{
if (! (mkdir_and_install
? install_file_in_file_parents (file[0], file[1], &x)
: install_file_in_file (file[0], file[1], &x)))
exit_status = EXIT_FAILURE;
}
? install_file_in_file_parents (file[0], file[1], &x)
: install_file_in_file (file[0], file[1], &x)))
exit_status = EXIT_FAILURE;
}
else
{
int i;
dest_info_init (&x);
for (i = 0; i < n_files; i++)
if (! install_file_in_dir (file[i], target_directory, &x))
exit_status = EXIT_FAILURE;
}
{
int i;
dest_info_init (&x);
for (i = 0; i < n_files; i++)
if (! install_file_in_dir (file[i], target_directory, &x))
exit_status = EXIT_FAILURE;
}
}
exit (exit_status);
@@ -689,7 +689,7 @@ main (int argc, char **argv)
static bool
install_file_in_file_parents (char const *from, char *to,
struct cp_options *x)
struct cp_options *x)
{
bool save_working_directory =
! (IS_ABSOLUTE_FILE_NAME (from) && IS_ABSOLUTE_FILE_NAME (to));
@@ -712,12 +712,12 @@ install_file_in_file_parents (char const *from, char *to,
int restore_errno = errno;
savewd_finish (&wd);
if (EXIT_SUCCESS < restore_result)
return false;
return false;
if (restore_result < 0 && status == EXIT_SUCCESS)
{
error (0, restore_errno, _("cannot create directory %s"), to);
return false;
}
{
error (0, restore_errno, _("cannot create directory %s"), to);
return false;
}
}
return (status == EXIT_SUCCESS && install_file_in_file (from, to, x));
@@ -729,7 +729,7 @@ install_file_in_file_parents (char const *from, char *to,
static bool
install_file_in_file (const char *from, const char *to,
const struct cp_options *x)
const struct cp_options *x)
{
struct stat from_sb;
if (x->preserve_timestamps && stat (from, &from_sb) != 0)
@@ -753,7 +753,7 @@ install_file_in_file (const char *from, const char *to,
static bool
install_file_in_dir (const char *from, const char *to_dir,
const struct cp_options *x)
const struct cp_options *x)
{
const char *from_base = last_component (from);
char *to = file_name_concat (to_dir, from_base, NULL);
@@ -856,9 +856,9 @@ strip (char const *name)
break;
default: /* Parent. */
if (waitpid (pid, &status, 0) < 0)
error (EXIT_FAILURE, errno, _("waiting for strip"));
error (EXIT_FAILURE, errno, _("waiting for strip"));
else if (! WIFEXITED (status) || WEXITSTATUS (status))
error (EXIT_FAILURE, 0, _("strip process terminated abnormally"));
error (EXIT_FAILURE, 0, _("strip process terminated abnormally"));
break;
}
}
@@ -875,15 +875,15 @@ get_ids (void)
{
pw = getpwnam (owner_name);
if (pw == NULL)
{
unsigned long int tmp;
if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
|| UID_T_MAX < tmp)
error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
owner_id = tmp;
}
{
unsigned long int tmp;
if (xstrtoul (owner_name, NULL, 0, &tmp, NULL) != LONGINT_OK
|| UID_T_MAX < tmp)
error (EXIT_FAILURE, 0, _("invalid user %s"), quote (owner_name));
owner_id = tmp;
}
else
owner_id = pw->pw_uid;
owner_id = pw->pw_uid;
endpwent ();
}
else
@@ -893,15 +893,15 @@ get_ids (void)
{
gr = getgrnam (group_name);
if (gr == NULL)
{
unsigned long int tmp;
if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
|| GID_T_MAX < tmp)
error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
group_id = tmp;
}
{
unsigned long int tmp;
if (xstrtoul (group_name, NULL, 0, &tmp, NULL) != LONGINT_OK
|| GID_T_MAX < tmp)
error (EXIT_FAILURE, 0, _("invalid group %s"), quote (group_name));
group_id = tmp;
}
else
group_id = gr->gr_gid;
group_id = gr->gr_gid;
endgrent ();
}
else
@@ -934,7 +934,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -943,7 +943,7 @@ Usage: %s [OPTION]... [-T] SOURCE DEST\n\
or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
or: %s [OPTION]... -d DIRECTORY...\n\
"),
program_name, program_name, program_name, program_name);
program_name, program_name, program_name, program_name);
fputs (_("\
\n\
This install program copies files (often just compiled) into destination\n\
@@ -1005,7 +1005,7 @@ the VERSION_CONTROL environment variable. Here are the values:\n\
existing, nil numbered if numbered backups exist, simple otherwise\n\
simple, never always make simple backups\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}

View File

@@ -24,6 +24,7 @@
#include "system.h"
#include "error.h"
#include "hard-locale.h"
#include "linebuffer.h"
#include "memcasecmp.h"
#include "quote.h"
@@ -161,13 +162,13 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
Usage: %s [OPTION]... FILE1 FILE2\n\
"),
program_name);
program_name);
fputs (_("\
For each pair of input lines with identical join fields, write a line to\n\
standard output. The default join field is the first, delimited\n\
@@ -208,7 +209,7 @@ Note, comparisons honor the rules specified by `LC_COLLATE'.\n\
If the input is not sorted and some lines cannot be joined, a\n\
warning message will be given.\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -242,26 +243,26 @@ xfields (struct line *line)
{
char *sep;
for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1)
extract_field (line, ptr, sep - ptr);
extract_field (line, ptr, sep - ptr);
}
else
{
/* Skip leading blanks before the first field. */
while (isblank (to_uchar (*ptr)))
if (++ptr == lim)
return;
if (++ptr == lim)
return;
do
{
char *sep;
for (sep = ptr + 1; sep != lim && ! isblank (to_uchar (*sep)); sep++)
continue;
extract_field (line, ptr, sep - ptr);
if (sep == lim)
return;
for (ptr = sep + 1; ptr != lim && isblank (to_uchar (*ptr)); ptr++)
continue;
}
{
char *sep;
for (sep = ptr + 1; sep != lim && ! isblank (to_uchar (*sep)); sep++)
continue;
extract_field (line, ptr, sep - ptr);
if (sep == lim)
return;
for (ptr = sep + 1; ptr != lim && isblank (to_uchar (*ptr)); ptr++)
continue;
}
while (ptr != lim);
}
@@ -283,7 +284,7 @@ freeline (struct line *line)
static int
keycmp (struct line const *line1, struct line const *line2,
size_t jf_1, size_t jf_2)
size_t jf_1, size_t jf_2)
{
/* Start of field to compare in each file. */
char *beg1;
@@ -329,7 +330,7 @@ keycmp (struct line const *line1, struct line const *line2,
else
{
if (hard_LC_COLLATE)
return xmemcoll (beg1, len1, beg2, len2);
return xmemcoll (beg1, len1, beg2, len2);
diff = memcmp (beg1, beg2, MIN (len1, len2));
}
@@ -351,26 +352,26 @@ keycmp (struct line const *line1, struct line const *line2,
static void
check_order (const struct line *prev,
const struct line *current,
int whatfile)
const struct line *current,
int whatfile)
{
if (check_input_order != CHECK_ORDER_DISABLED
&& ((check_input_order == CHECK_ORDER_ENABLED) || seen_unpairable))
{
if (!issued_disorder_warning[whatfile-1])
{
size_t join_field = whatfile == 1 ? join_field_1 : join_field_2;
if (keycmp (prev, current, join_field, join_field) > 0)
{
error ((check_input_order == CHECK_ORDER_ENABLED
? EXIT_FAILURE : 0),
0, _("file %d is not in sorted order"), whatfile);
{
size_t join_field = whatfile == 1 ? join_field_1 : join_field_2;
if (keycmp (prev, current, join_field, join_field) > 0)
{
error ((check_input_order == CHECK_ORDER_ENABLED
? EXIT_FAILURE : 0),
0, _("file %d is not in sorted order"), whatfile);
/* If we get to here, the message was just a warning, but we
want only to issue it once. */
issued_disorder_warning[whatfile-1] = true;
}
}
/* If we get to here, the message was just a warning, but we
want only to issue it once. */
issued_disorder_warning[whatfile-1] = true;
}
}
}
}
@@ -411,7 +412,7 @@ get_line (FILE *fp, struct line **linep, int which)
if (! readlinebuffer (&line->buf, fp))
{
if (ferror (fp))
error (EXIT_FAILURE, errno, _("read error"));
error (EXIT_FAILURE, errno, _("read error"));
freeline (line);
return false;
}
@@ -433,10 +434,10 @@ free_spareline (void)
for (i = 0; i < ARRAY_CARDINALITY (spareline); i++)
{
if (spareline[i])
{
freeline (spareline[i]);
free (spareline[i]);
}
{
freeline (spareline[i]);
free (spareline[i]);
}
}
}
@@ -458,7 +459,7 @@ getseq (FILE *fp, struct seq *seq, int whichfile)
size_t i;
seq->lines = X2NREALLOC (seq->lines, &seq->alloc);
for (i = seq->count; i < seq->alloc; i++)
seq->lines[i] = NULL;
seq->lines[i] = NULL;
}
if (get_line (fp, &seq->lines[seq->count], whichfile))
@@ -487,9 +488,9 @@ delseq (struct seq *seq)
for (i = 0; i < seq->alloc; i++)
if (seq->lines[i])
{
if (seq->lines[i]->buf.buffer)
freeline (seq->lines[i]);
free (seq->lines[i]);
if (seq->lines[i]->buf.buffer)
freeline (seq->lines[i]);
free (seq->lines[i]);
}
free (seq->lines);
}
@@ -507,9 +508,9 @@ prfield (size_t n, struct line const *line)
{
len = line->fields[n].len;
if (len)
fwrite (line->fields[n].beg, 1, len, stdout);
fwrite (line->fields[n].beg, 1, len, stdout);
else if (empty_filler)
fputs (empty_filler, stdout);
fputs (empty_filler, stdout);
}
else if (empty_filler)
fputs (empty_filler, stdout);
@@ -530,34 +531,34 @@ prjoin (struct line const *line1, struct line const *line2)
o = outlist;
while (1)
{
size_t field;
struct line const *line;
{
size_t field;
struct line const *line;
if (o->file == 0)
{
if (line1 == &uni_blank)
{
line = line2;
field = join_field_2;
}
else
{
line = line1;
field = join_field_1;
}
}
else
{
line = (o->file == 1 ? line1 : line2);
field = o->field;
}
prfield (field, line);
o = o->next;
if (o == NULL)
break;
putchar (output_separator);
}
if (o->file == 0)
{
if (line1 == &uni_blank)
{
line = line2;
field = join_field_2;
}
else
{
line = line1;
field = join_field_1;
}
}
else
{
line = (o->file == 1 ? line1 : line2);
field = o->field;
}
prfield (field, line);
o = o->next;
if (o == NULL)
break;
putchar (output_separator);
}
putchar ('\n');
}
else
@@ -565,34 +566,34 @@ prjoin (struct line const *line1, struct line const *line2)
size_t i;
if (line1 == &uni_blank)
{
struct line const *t;
t = line1;
line1 = line2;
line2 = t;
}
{
struct line const *t;
t = line1;
line1 = line2;
line2 = t;
}
prfield (join_field_1, line1);
for (i = 0; i < join_field_1 && i < line1->nfields; ++i)
{
putchar (output_separator);
prfield (i, line1);
}
{
putchar (output_separator);
prfield (i, line1);
}
for (i = join_field_1 + 1; i < line1->nfields; ++i)
{
putchar (output_separator);
prfield (i, line1);
}
{
putchar (output_separator);
prfield (i, line1);
}
for (i = 0; i < join_field_2 && i < line2->nfields; ++i)
{
putchar (output_separator);
prfield (i, line2);
}
{
putchar (output_separator);
prfield (i, line2);
}
for (i = join_field_2 + 1; i < line2->nfields; ++i)
{
putchar (output_separator);
prfield (i, line2);
}
{
putchar (output_separator);
prfield (i, line2);
}
putchar ('\n');
}
}
@@ -619,75 +620,75 @@ join (FILE *fp1, FILE *fp2)
{
size_t i;
diff = keycmp (seq1.lines[0], seq2.lines[0],
join_field_1, join_field_2);
join_field_1, join_field_2);
if (diff < 0)
{
if (print_unpairables_1)
prjoin (seq1.lines[0], &uni_blank);
advance_seq (fp1, &seq1, true, 1);
seen_unpairable = true;
continue;
}
{
if (print_unpairables_1)
prjoin (seq1.lines[0], &uni_blank);
advance_seq (fp1, &seq1, true, 1);
seen_unpairable = true;
continue;
}
if (diff > 0)
{
if (print_unpairables_2)
prjoin (&uni_blank, seq2.lines[0]);
advance_seq (fp2, &seq2, true, 2);
seen_unpairable = true;
continue;
}
{
if (print_unpairables_2)
prjoin (&uni_blank, seq2.lines[0]);
advance_seq (fp2, &seq2, true, 2);
seen_unpairable = true;
continue;
}
/* Keep reading lines from file1 as long as they continue to
match the current line from file2. */
eof1 = false;
do
if (!advance_seq (fp1, &seq1, false, 1))
{
eof1 = true;
++seq1.count;
break;
}
if (!advance_seq (fp1, &seq1, false, 1))
{
eof1 = true;
++seq1.count;
break;
}
while (!keycmp (seq1.lines[seq1.count - 1], seq2.lines[0],
join_field_1, join_field_2));
join_field_1, join_field_2));
/* Keep reading lines from file2 as long as they continue to
match the current line from file1. */
eof2 = false;
do
if (!advance_seq (fp2, &seq2, false, 2))
{
eof2 = true;
++seq2.count;
break;
}
if (!advance_seq (fp2, &seq2, false, 2))
{
eof2 = true;
++seq2.count;
break;
}
while (!keycmp (seq1.lines[0], seq2.lines[seq2.count - 1],
join_field_1, join_field_2));
join_field_1, join_field_2));
if (print_pairables)
{
for (i = 0; i < seq1.count - 1; ++i)
{
size_t j;
for (j = 0; j < seq2.count - 1; ++j)
prjoin (seq1.lines[i], seq2.lines[j]);
}
}
{
for (i = 0; i < seq1.count - 1; ++i)
{
size_t j;
for (j = 0; j < seq2.count - 1; ++j)
prjoin (seq1.lines[i], seq2.lines[j]);
}
}
if (!eof1)
{
SWAPLINES (seq1.lines[0], seq1.lines[seq1.count - 1]);
seq1.count = 1;
}
{
SWAPLINES (seq1.lines[0], seq1.lines[seq1.count - 1]);
seq1.count = 1;
}
else
seq1.count = 0;
seq1.count = 0;
if (!eof2)
{
SWAPLINES (seq2.lines[0], seq2.lines[seq2.count - 1]);
seq2.count = 1;
}
{
SWAPLINES (seq2.lines[0], seq2.lines[seq2.count - 1]);
seq2.count = 1;
}
else
seq2.count = 0;
seq2.count = 0;
}
/* If the user did not specify --check-order, and the we read the
@@ -703,29 +704,29 @@ join (FILE *fp1, FILE *fp2)
if ((print_unpairables_1 || checktail) && seq1.count)
{
if (print_unpairables_1)
prjoin (seq1.lines[0], &uni_blank);
prjoin (seq1.lines[0], &uni_blank);
seen_unpairable = true;
while (get_line (fp1, linep, 1))
{
if (print_unpairables_1)
prjoin (*linep, &uni_blank);
if (issued_disorder_warning[0] && !print_unpairables_1)
break;
}
{
if (print_unpairables_1)
prjoin (*linep, &uni_blank);
if (issued_disorder_warning[0] && !print_unpairables_1)
break;
}
}
if ((print_unpairables_2 || checktail) && seq2.count)
{
if (print_unpairables_2)
prjoin (&uni_blank, seq2.lines[0]);
prjoin (&uni_blank, seq2.lines[0]);
seen_unpairable = true;
while (get_line (fp2, linep, 2))
{
if (print_unpairables_2)
prjoin (&uni_blank, *linep);
if (issued_disorder_warning[1] && !print_unpairables_2)
break;
}
{
if (print_unpairables_2)
prjoin (&uni_blank, *linep);
if (issued_disorder_warning[1] && !print_unpairables_2)
break;
}
}
free (*linep);
@@ -792,9 +793,9 @@ decode_field_spec (const char *s, int *file_index, size_t *field_index)
case '0':
if (s[1])
{
/* `0' must be all alone -- no `.FIELD'. */
error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
}
/* `0' must be all alone -- no `.FIELD'. */
error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
}
*file_index = 0;
*field_index = 0;
break;
@@ -802,18 +803,18 @@ decode_field_spec (const char *s, int *file_index, size_t *field_index)
case '1':
case '2':
if (s[1] != '.')
error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
*file_index = s[0] - '0';
*field_index = string_to_join_field (s + 2);
break;
default:
error (EXIT_FAILURE, 0,
_("invalid file number in field spec: %s"), quote (s));
_("invalid file number in field spec: %s"), quote (s));
/* Tell gcc -W -Wall that we can't get beyond this point.
This avoids a warning (otherwise legit) that the caller's copies
of *file_index and *field_index might be used uninitialized. */
This avoids a warning (otherwise legit) that the caller's copies
of *file_index and *field_index might be used uninitialized. */
abort ();
break;
@@ -853,7 +854,7 @@ set_join_field (size_t *var, size_t val)
unsigned long int var1 = *var + 1;
unsigned long int val1 = val + 1;
error (EXIT_FAILURE, 0, _("incompatible join fields %lu, %lu"),
var1, val1);
var1, val1);
}
*var = val;
}
@@ -881,8 +882,8 @@ enum operand_status
static void
add_file_name (char *name, char *names[2],
int operand_status[2], int joption_count[2], int *nfiles,
int *prev_optc_status, int *optc_status)
int operand_status[2], int joption_count[2], int *nfiles,
int *prev_optc_status, int *optc_status)
{
int n = *nfiles;
@@ -891,30 +892,30 @@ add_file_name (char *name, char *names[2],
bool op0 = (operand_status[0] == MUST_BE_OPERAND);
char *arg = names[op0];
switch (operand_status[op0])
{
case MUST_BE_OPERAND:
error (0, 0, _("extra operand %s"), quote (name));
usage (EXIT_FAILURE);
{
case MUST_BE_OPERAND:
error (0, 0, _("extra operand %s"), quote (name));
usage (EXIT_FAILURE);
case MIGHT_BE_J1_ARG:
joption_count[0]--;
set_join_field (&join_field_1, string_to_join_field (arg));
break;
case MIGHT_BE_J1_ARG:
joption_count[0]--;
set_join_field (&join_field_1, string_to_join_field (arg));
break;
case MIGHT_BE_J2_ARG:
joption_count[1]--;
set_join_field (&join_field_2, string_to_join_field (arg));
break;
case MIGHT_BE_J2_ARG:
joption_count[1]--;
set_join_field (&join_field_2, string_to_join_field (arg));
break;
case MIGHT_BE_O_ARG:
add_field_list (arg);
break;
}
case MIGHT_BE_O_ARG:
add_field_list (arg);
break;
}
if (!op0)
{
operand_status[0] = operand_status[1];
names[0] = names[1];
}
{
operand_status[0] = operand_status[1];
names[0] = names[1];
}
n = 1;
}
@@ -954,110 +955,110 @@ main (int argc, char **argv)
check_input_order = CHECK_ORDER_DEFAULT;
while ((optc = getopt_long (argc, argv, "-a:e:i1:2:j:o:t:v:",
longopts, NULL))
!= -1)
longopts, NULL))
!= -1)
{
optc_status = MUST_BE_OPERAND;
switch (optc)
{
case 'v':
print_pairables = false;
/* Fall through. */
{
case 'v':
print_pairables = false;
/* Fall through. */
case 'a':
{
unsigned long int val;
if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
|| (val != 1 && val != 2))
error (EXIT_FAILURE, 0,
_("invalid field number: %s"), quote (optarg));
if (val == 1)
print_unpairables_1 = true;
else
print_unpairables_2 = true;
}
break;
case 'a':
{
unsigned long int val;
if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
|| (val != 1 && val != 2))
error (EXIT_FAILURE, 0,
_("invalid field number: %s"), quote (optarg));
if (val == 1)
print_unpairables_1 = true;
else
print_unpairables_2 = true;
}
break;
case 'e':
if (empty_filler && ! STREQ (empty_filler, optarg))
error (EXIT_FAILURE, 0,
_("conflicting empty-field replacement strings"));
empty_filler = optarg;
break;
case 'e':
if (empty_filler && ! STREQ (empty_filler, optarg))
error (EXIT_FAILURE, 0,
_("conflicting empty-field replacement strings"));
empty_filler = optarg;
break;
case 'i':
ignore_case = true;
break;
case 'i':
ignore_case = true;
break;
case '1':
set_join_field (&join_field_1, string_to_join_field (optarg));
break;
case '1':
set_join_field (&join_field_1, string_to_join_field (optarg));
break;
case '2':
set_join_field (&join_field_2, string_to_join_field (optarg));
break;
case '2':
set_join_field (&join_field_2, string_to_join_field (optarg));
break;
case 'j':
if ((optarg[0] == '1' || optarg[0] == '2') && !optarg[1]
&& optarg == argv[optind - 1] + 2)
{
/* The argument was either "-j1" or "-j2". */
bool is_j2 = (optarg[0] == '2');
joption_count[is_j2]++;
optc_status = MIGHT_BE_J1_ARG + is_j2;
}
else
{
set_join_field (&join_field_1, string_to_join_field (optarg));
set_join_field (&join_field_2, join_field_1);
}
break;
case 'j':
if ((optarg[0] == '1' || optarg[0] == '2') && !optarg[1]
&& optarg == argv[optind - 1] + 2)
{
/* The argument was either "-j1" or "-j2". */
bool is_j2 = (optarg[0] == '2');
joption_count[is_j2]++;
optc_status = MIGHT_BE_J1_ARG + is_j2;
}
else
{
set_join_field (&join_field_1, string_to_join_field (optarg));
set_join_field (&join_field_2, join_field_1);
}
break;
case 'o':
add_field_list (optarg);
optc_status = MIGHT_BE_O_ARG;
break;
case 'o':
add_field_list (optarg);
optc_status = MIGHT_BE_O_ARG;
break;
case 't':
{
unsigned char newtab = optarg[0];
if (! newtab)
error (EXIT_FAILURE, 0, _("empty tab"));
if (optarg[1])
{
if (STREQ (optarg, "\\0"))
newtab = '\0';
else
error (EXIT_FAILURE, 0, _("multi-character tab %s"),
quote (optarg));
}
if (0 <= tab && tab != newtab)
error (EXIT_FAILURE, 0, _("incompatible tabs"));
tab = newtab;
}
break;
case 't':
{
unsigned char newtab = optarg[0];
if (! newtab)
error (EXIT_FAILURE, 0, _("empty tab"));
if (optarg[1])
{
if (STREQ (optarg, "\\0"))
newtab = '\0';
else
error (EXIT_FAILURE, 0, _("multi-character tab %s"),
quote (optarg));
}
if (0 <= tab && tab != newtab)
error (EXIT_FAILURE, 0, _("incompatible tabs"));
tab = newtab;
}
break;
case NOCHECK_ORDER_OPTION:
check_input_order = CHECK_ORDER_DISABLED;
break;
case NOCHECK_ORDER_OPTION:
check_input_order = CHECK_ORDER_DISABLED;
break;
case CHECK_ORDER_OPTION:
check_input_order = CHECK_ORDER_ENABLED;
break;
case CHECK_ORDER_OPTION:
check_input_order = CHECK_ORDER_ENABLED;
break;
case 1: /* Non-option argument. */
add_file_name (optarg, names, operand_status, joption_count,
&nfiles, &prev_optc_status, &optc_status);
break;
case 1: /* Non-option argument. */
add_file_name (optarg, names, operand_status, joption_count,
&nfiles, &prev_optc_status, &optc_status);
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
default:
usage (EXIT_FAILURE);
}
prev_optc_status = optc_status;
}
@@ -1066,14 +1067,14 @@ main (int argc, char **argv)
prev_optc_status = MUST_BE_OPERAND;
while (optind < argc)
add_file_name (argv[optind++], names, operand_status, joption_count,
&nfiles, &prev_optc_status, &optc_status);
&nfiles, &prev_optc_status, &optc_status);
if (nfiles != 2)
{
if (nfiles == 0)
error (0, 0, _("missing operand"));
error (0, 0, _("missing operand"));
else
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
usage (EXIT_FAILURE);
}
@@ -1082,8 +1083,8 @@ main (int argc, char **argv)
for (i = 0; i < 2; i++)
if (joption_count[i] != 0)
{
set_join_field (&join_field_1, i);
set_join_field (&join_field_2, i);
set_join_field (&join_field_1, i);
set_join_field (&join_field_2, i);
}
if (join_field_1 == SIZE_MAX)

View File

@@ -52,8 +52,8 @@
# endif
# if HAVE_DECL_SYS_SIGLIST || defined sys_siglist
# define strsignal(signum) (0 <= (signum) && (signum) <= SIGNUM_BOUND \
? sys_siglist[signum] \
: 0)
? sys_siglist[signum] \
: 0)
# endif
# ifndef strsignal
# define strsignal(signum) 0
@@ -81,7 +81,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -89,7 +89,7 @@ Usage: %s [-s SIGNAL | -SIGNAL] PID...\n\
or: %s -l [SIGNAL]...\n\
or: %s -t [SIGNAL]...\n\
"),
program_name, program_name, program_name);
program_name, program_name, program_name);
fputs (_("\
Send signals to processes, or list signals.\n\
\n\
@@ -111,7 +111,7 @@ or the exit status of a process terminated by a signal.\n\
PID is an integer; if negative it identifies a process group.\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -122,11 +122,11 @@ PID is an integer; if negative it identifies a process group.\n\
static void
print_table_row (unsigned int num_width, int signum,
unsigned int name_width, char const *signame)
unsigned int name_width, char const *signame)
{
char const *description = strsignal (signum);
printf ("%*d %-*s %s\n", num_width, signum, name_width, signame,
description ? description : "?");
description ? description : "?");
}
/* Print a list of signal names. If TABLE, print a table.
@@ -147,51 +147,51 @@ list_signals (bool table, char *const *argv)
/* Compute the maximum width of a signal number. */
unsigned int num_width = 1;
for (signum = 1; signum <= SIGNUM_BOUND / 10; signum *= 10)
num_width++;
num_width++;
/* Compute the maximum width of a signal name. */
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
if (sig2str (signum, signame) == 0)
{
size_t len = strlen (signame);
if (name_width < len)
name_width = len;
}
if (sig2str (signum, signame) == 0)
{
size_t len = strlen (signame);
if (name_width < len)
name_width = len;
}
if (argv)
for (; *argv; argv++)
{
signum = operand2sig (*argv, signame);
if (signum < 0)
status = EXIT_FAILURE;
else
print_table_row (num_width, signum, name_width, signame);
}
for (; *argv; argv++)
{
signum = operand2sig (*argv, signame);
if (signum < 0)
status = EXIT_FAILURE;
else
print_table_row (num_width, signum, name_width, signame);
}
else
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
if (sig2str (signum, signame) == 0)
print_table_row (num_width, signum, name_width, signame);
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
if (sig2str (signum, signame) == 0)
print_table_row (num_width, signum, name_width, signame);
}
else
{
if (argv)
for (; *argv; argv++)
{
signum = operand2sig (*argv, signame);
if (signum < 0)
status = EXIT_FAILURE;
else
{
if (ISDIGIT (**argv))
puts (signame);
else
printf ("%d\n", signum);
}
}
for (; *argv; argv++)
{
signum = operand2sig (*argv, signame);
if (signum < 0)
status = EXIT_FAILURE;
else
{
if (ISDIGIT (**argv))
puts (signame);
else
printf ("%d\n", signum);
}
}
else
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
if (sig2str (signum, signame) == 0)
puts (signame);
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
if (sig2str (signum, signame) == 0)
puts (signame);
}
return status;
@@ -213,15 +213,15 @@ send_signals (int signum, char *const *argv)
pid_t pid = n;
if (errno == ERANGE || pid != n || arg == endp || *endp)
{
error (0, 0, _("%s: invalid process id"), arg);
status = EXIT_FAILURE;
}
{
error (0, 0, _("%s: invalid process id"), arg);
status = EXIT_FAILURE;
}
else if (kill (pid, signum) != 0)
{
error (0, errno, "%s", arg);
status = EXIT_FAILURE;
}
{
error (0, errno, "%s", arg);
status = EXIT_FAILURE;
}
}
while ((arg = *++argv));
@@ -246,61 +246,61 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, short_options, long_options, NULL))
!= -1)
!= -1)
switch (optc)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (optind != 2)
{
/* This option is actually a process-id. */
optind--;
goto no_more_options;
}
/* Fall through. */
if (optind != 2)
{
/* This option is actually a process-id. */
optind--;
goto no_more_options;
}
/* Fall through. */
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':
if (! optarg)
optarg = argv[optind - 1] + strlen (argv[optind - 1]);
if (optarg != argv[optind - 1] + 2)
{
error (0, 0, _("invalid option -- %c"), optc);
usage (EXIT_FAILURE);
}
optarg--;
/* Fall through. */
if (! optarg)
optarg = argv[optind - 1] + strlen (argv[optind - 1]);
if (optarg != argv[optind - 1] + 2)
{
error (0, 0, _("invalid option -- %c"), optc);
usage (EXIT_FAILURE);
}
optarg--;
/* Fall through. */
case 'n': /* -n is not documented, but is for Bash compatibility. */
case 's':
if (0 <= signum)
{
error (0, 0, _("%s: multiple signals specified"), optarg);
usage (EXIT_FAILURE);
}
signum = operand2sig (optarg, signame);
if (signum < 0)
usage (EXIT_FAILURE);
break;
if (0 <= signum)
{
error (0, 0, _("%s: multiple signals specified"), optarg);
usage (EXIT_FAILURE);
}
signum = operand2sig (optarg, signame);
if (signum < 0)
usage (EXIT_FAILURE);
break;
case 't':
table = true;
/* Fall through. */
table = true;
/* Fall through. */
case 'l':
if (list)
{
error (0, 0, _("multiple -l or -t options specified"));
usage (EXIT_FAILURE);
}
list = true;
break;
if (list)
{
error (0, 0, _("multiple -l or -t options specified"));
usage (EXIT_FAILURE);
}
list = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
usage (EXIT_FAILURE);
}
no_more_options:;
@@ -319,6 +319,6 @@ main (int argc, char **argv)
}
return (list
? list_signals (table, optind < argc ? argv + optind : NULL)
: send_signals (signum, argv + optind));
? list_signals (table, optind < argc ? argv + optind : NULL)
: send_signals (signum, argv + optind));
}

View File

@@ -40,7 +40,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -48,10 +48,10 @@ Usage: %s FILE1 FILE2\n\
or: %s OPTION\n"), program_name, program_name);
fputs (_("Call the link function to create a link named FILE2\
to an existing FILE1.\n\n"),
stdout);
stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -68,16 +68,16 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
usage, AUTHORS, (char const *) NULL);
usage, AUTHORS, (char const *) NULL);
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
usage (EXIT_FAILURE);
if (argc < optind + 2)
{
if (argc < optind + 1)
error (0, 0, _("missing operand"));
error (0, 0, _("missing operand"));
else
error (0, 0, _("missing operand after %s"), quote (argv[optind]));
error (0, 0, _("missing operand after %s"), quote (argv[optind]));
usage (EXIT_FAILURE);
}
@@ -89,7 +89,7 @@ main (int argc, char **argv)
if (link (argv[optind], argv[optind + 1]) != 0)
error (EXIT_FAILURE, errno, _("cannot create link %s to %s"),
quote_n (0, argv[optind + 1]), quote_n (1, argv[optind]));
quote_n (0, argv[optind + 1]), quote_n (1, argv[optind]));
exit (EXIT_SUCCESS);
}

461
src/ln.c
View File

@@ -39,30 +39,15 @@
proper_name ("Mike Parker"), \
proper_name ("David MacKenzie")
#ifndef ENABLE_HARD_LINK_TO_SYMLINK_WARNING
# define ENABLE_HARD_LINK_TO_SYMLINK_WARNING 0
#endif
/* In being careful not even to try to make hard links to directories,
we have to know whether link(2) follows symlinks. If it does, then
we have to *stat* the `source' to see if the resulting link would be
to a directory. Otherwise, we have to use *lstat* so that we allow
users to make hard links to symlinks-that-point-to-directories. */
#if LINK_FOLLOWS_SYMLINKS
# define STAT_LIKE_LINK(File, Stat_buf) \
stat (File, Stat_buf)
#else
# define STAT_LIKE_LINK(File, Stat_buf) \
lstat (File, Stat_buf)
#endif
/* FIXME: document */
static enum backup_type backup_type;
/* If true, make symbolic links; otherwise, make hard links. */
static bool symbolic_link;
/* If true, hard links are logical rather than physical. */
static bool logical = !!LINK_FOLLOWS_SYMLINKS;
/* If true, ask the user before removing existing files. */
static bool interactive;
@@ -75,7 +60,7 @@ static bool verbose;
/* If true, allow the superuser to *attempt* to make hard links
to directories. However, it appears that this option is not useful
in practice, since even the superuser is prohibited from hard-linking
directories on most (all?) existing systems. */
directories on most existing systems (Solaris being an exception). */
static bool hard_dir_link;
/* If nonzero, and the specified destination is a symbolic link to a
@@ -103,6 +88,8 @@ static struct option const long_options[] =
{"interactive", no_argument, NULL, 'i'},
{"suffix", required_argument, NULL, 'S'},
{"target-directory", required_argument, NULL, 't'},
{"logical", no_argument, NULL, 'L'},
{"physical", no_argument, NULL, 'P'},
{"symbolic", no_argument, NULL, 's'},
{"verbose", no_argument, NULL, 'v'},
{GETOPT_HELP_OPTION_DECL},
@@ -147,46 +134,40 @@ do_link (const char *source, const char *dest)
bool source_is_dir = false;
bool ok;
/* Use stat here instead of lstat.
On SVR4, link does not follow symlinks, so this check disallows
making hard links to symlinks that point to directories. Big deal.
On other systems, link follows symlinks, so this check is right. */
if (!symbolic_link)
{
if (STAT_LIKE_LINK (source, &source_stats) != 0)
{
error (0, errno, _("accessing %s"), quote (source));
return false;
}
if (ENABLE_HARD_LINK_TO_SYMLINK_WARNING
&& S_ISLNK (source_stats.st_mode))
{
error (0, 0, _("%s: warning: making a hard link to a symbolic link\
is not portable"),
quote (source));
}
/* Which stat to use depends on whether linkat will follow the
symlink. We can't use the shorter
(logical ? stat : lstat) (source, &source_stats)
since stat might be a function-like macro. */
if ((logical ? stat (source, &source_stats)
: lstat (source, &source_stats))
!= 0)
{
error (0, errno, _("accessing %s"), quote (source));
return false;
}
if (S_ISDIR (source_stats.st_mode))
{
source_is_dir = true;
if (! hard_dir_link)
{
error (0, 0, _("%s: hard link not allowed for directory"),
quote (source));
return false;
}
}
{
source_is_dir = true;
if (! hard_dir_link)
{
error (0, 0, _("%s: hard link not allowed for directory"),
quote (source));
return false;
}
}
}
if (remove_existing_files || interactive || backup_type != no_backups)
{
dest_lstat_ok = (lstat (dest, &dest_stats) == 0);
if (!dest_lstat_ok && errno != ENOENT)
{
error (0, errno, _("accessing %s"), quote (dest));
return false;
}
{
error (0, errno, _("accessing %s"), quote (dest));
return false;
}
}
/* If the current target was created as a hard link to another
@@ -196,8 +177,8 @@ do_link (const char *source, const char *dest)
&& seen_file (dest_set, dest, &dest_stats))
{
error (0, 0,
_("will not overwrite just-created %s with %s"),
quote_n (0, dest), quote_n (1, source));
_("will not overwrite just-created %s with %s"),
quote_n (0, dest), quote_n (1, source));
return false;
}
@@ -208,77 +189,80 @@ do_link (const char *source, const char *dest)
anything and fail right here. */
if ((remove_existing_files
/* Ensure that "ln --backup f f" fails here, with the
"... same file" diagnostic, below. Otherwise, subsequent
code would give a misleading "file not found" diagnostic.
This case is different than the others handled here, since
the command in question doesn't use --force. */
"... same file" diagnostic, below. Otherwise, subsequent
code would give a misleading "file not found" diagnostic.
This case is different than the others handled here, since
the command in question doesn't use --force. */
|| (!symbolic_link && backup_type != no_backups))
&& dest_lstat_ok
/* Allow `ln -sf --backup k k' to succeed in creating the
self-referential symlink, but don't allow the hard-linking
equivalent: `ln -f k k' (with or without --backup) to get
beyond this point, because the error message you'd get is
misleading. */
self-referential symlink, but don't allow the hard-linking
equivalent: `ln -f k k' (with or without --backup) to get
beyond this point, because the error message you'd get is
misleading. */
&& (backup_type == no_backups || !symbolic_link)
&& (!symbolic_link || stat (source, &source_stats) == 0)
&& SAME_INODE (source_stats, dest_stats)
/* The following detects whether removing DEST will also remove
SOURCE. If the file has only one link then both are surely
the same link. Otherwise check whether they point to the same
name in the same directory. */
SOURCE. If the file has only one link then both are surely
the same link. Otherwise check whether they point to the same
name in the same directory. */
&& (source_stats.st_nlink == 1 || same_name (source, dest)))
{
error (0, 0, _("%s and %s are the same file"),
quote_n (0, source), quote_n (1, dest));
quote_n (0, source), quote_n (1, dest));
return false;
}
if (dest_lstat_ok)
{
if (S_ISDIR (dest_stats.st_mode))
{
error (0, 0, _("%s: cannot overwrite directory"), quote (dest));
return false;
}
{
error (0, 0, _("%s: cannot overwrite directory"), quote (dest));
return false;
}
if (interactive)
{
fprintf (stderr, _("%s: replace %s? "), program_name, quote (dest));
if (!yesno ())
return true;
remove_existing_files = true;
}
{
fprintf (stderr, _("%s: replace %s? "), program_name, quote (dest));
if (!yesno ())
return true;
remove_existing_files = true;
}
if (backup_type != no_backups)
{
dest_backup = find_backup_file_name (dest, backup_type);
if (rename (dest, dest_backup) != 0)
{
int rename_errno = errno;
free (dest_backup);
dest_backup = NULL;
if (rename_errno != ENOENT)
{
error (0, rename_errno, _("cannot backup %s"), quote (dest));
return false;
}
}
}
{
dest_backup = find_backup_file_name (dest, backup_type);
if (rename (dest, dest_backup) != 0)
{
int rename_errno = errno;
free (dest_backup);
dest_backup = NULL;
if (rename_errno != ENOENT)
{
error (0, rename_errno, _("cannot backup %s"), quote (dest));
return false;
}
}
}
}
ok = ((symbolic_link ? symlink (source, dest) : link (source, dest))
== 0);
ok = ((symbolic_link ? symlink (source, dest)
: linkat (AT_FDCWD, source, AT_FDCWD, dest,
logical ? AT_SYMLINK_FOLLOW : 0))
== 0);
/* If the attempt to create a link failed and we are removing or
backing up destinations, unlink the destination and try again.
POSIX 1003.1-2004 requires that ln -f A B must unlink B even on
failure (e.g., when A does not exist). This is counterintuitive,
and we submitted a defect report
<http://www.opengroup.org/austin/mailarchives/ag-review/msg01794.html>
(2004-06-24). If the committee does not fix the standard we'll
have to change the behavior of ln -f, at least if POSIXLY_CORRECT
is set. In the meantime ln -f A B will not unlink B unless the
attempt to link A to B failed because B already existed.
On the surface, POSIX describes an algorithm that states that
'ln -f A B' will call unlink() on B before ever attempting
link() on A. But strictly following this has the counterintuitive
effect of losing the contents of B, if A does not exist.
Fortunately, POSIX 2008 clarified that an application is free
to fail early if it can prove that continuing onwards cannot
succeed, so we are justified in trying link() before blindly
removing B, thus sometimes calling link() a second time during
a successful 'ln -f A B'.
Try to unlink DEST even if we may have backed it up successfully.
In some unusual cases (when DEST and DEST_BACKUP are hard-links
@@ -289,50 +273,52 @@ do_link (const char *source, const char *dest)
if (!ok && errno == EEXIST && (remove_existing_files || dest_backup))
{
if (unlink (dest) != 0)
{
error (0, errno, _("cannot remove %s"), quote (dest));
free (dest_backup);
return false;
}
{
error (0, errno, _("cannot remove %s"), quote (dest));
free (dest_backup);
return false;
}
ok = ((symbolic_link ? symlink (source, dest) : link (source, dest))
== 0);
ok = ((symbolic_link ? symlink (source, dest)
: linkat (AT_FDCWD, source, AT_FDCWD, dest,
logical ? AT_SYMLINK_FOLLOW : 0))
== 0);
}
if (ok)
{
/* Right after creating a hard link, do this: (note dest name and
source_stats, which are also the just-linked-destinations stats) */
source_stats, which are also the just-linked-destinations stats) */
record_file (dest_set, dest, &source_stats);
if (verbose)
{
if (dest_backup)
printf ("%s ~ ", quote (dest_backup));
printf ("%s %c> %s\n", quote_n (0, dest), (symbolic_link ? '-' : '='),
quote_n (1, source));
}
{
if (dest_backup)
printf ("%s ~ ", quote (dest_backup));
printf ("%s %c> %s\n", quote_n (0, dest), (symbolic_link ? '-' : '='),
quote_n (1, source));
}
}
else
{
error (0, errno,
(symbolic_link
? (errno != ENAMETOOLONG && *source
? _("creating symbolic link %s")
: _("creating symbolic link %s -> %s"))
: (errno == EMLINK && !source_is_dir
? _("creating hard link to %.0s%s")
: (errno == EDQUOT || errno == EEXIST || errno == ENOSPC
|| errno == EROFS)
? _("creating hard link %s")
: _("creating hard link %s => %s"))),
quote_n (0, dest), quote_n (1, source));
(symbolic_link
? (errno != ENAMETOOLONG && *source
? _("creating symbolic link %s")
: _("creating symbolic link %s -> %s"))
: (errno == EMLINK && !source_is_dir
? _("creating hard link to %.0s%s")
: (errno == EDQUOT || errno == EEXIST || errno == ENOSPC
|| errno == EROFS)
? _("creating hard link %s")
: _("creating hard link %s => %s"))),
quote_n (0, dest), quote_n (1, source));
if (dest_backup)
{
if (rename (dest_backup, dest) != 0)
error (0, errno, _("cannot un-backup %s"), quote (dest));
}
{
if (rename (dest_backup, dest) != 0)
error (0, errno, _("cannot un-backup %s"), quote (dest));
}
}
free (dest_backup);
@@ -344,7 +330,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -353,7 +339,7 @@ Usage: %s [OPTION]... [-T] TARGET LINK_NAME (1st form)\n\
or: %s [OPTION]... TARGET... DIRECTORY (3rd form)\n\
or: %s [OPTION]... -t DIRECTORY TARGET... (4th form)\n\
"),
program_name, program_name, program_name, program_name);
program_name, program_name, program_name, program_name);
fputs (_("\
In the 1st form, create a link to TARGET with the name LINK_NAME.\n\
In the 2nd form, create a link to TARGET in the current directory.\n\
@@ -376,9 +362,11 @@ Mandatory arguments to long options are mandatory for short options too.\n\
-f, --force remove existing destination files\n\
"), stdout);
fputs (_("\
-i, --interactive prompt whether to remove destinations\n\
-L, --logical make hard links to symbolic link references\n\
-n, --no-dereference treat destination that is a symlink to a\n\
directory as if it were a normal file\n\
-i, --interactive prompt whether to remove destinations\n\
-P, --physical make hard links directly to symbolic links\n\
-s, --symbolic make symbolic links instead of hard links\n\
"), stdout);
fputs (_("\
@@ -397,13 +385,18 @@ The version control method may be selected via the --backup option or through\n\
the VERSION_CONTROL environment variable. Here are the values:\n\
\n\
"), stdout);
printf (_("\
Using -s ignores -L and -P. Otherwise, the last option specified controls\n\
behavior when the source is a symbolic link, defaulting to %s.\n\
\n\
"), LINK_FOLLOWS_SYMLINKS ? "-L" : "-P");
fputs (_("\
none, off never make backups (even if --backup is given)\n\
numbered, t make numbered backups\n\
existing, nil numbered if numbered backups exist, simple otherwise\n\
simple, never always make simple backups\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -436,64 +429,70 @@ main (int argc, char **argv)
symbolic_link = remove_existing_files = interactive = verbose
= hard_dir_link = false;
while ((c = getopt_long (argc, argv, "bdfinst:vFS:T", long_options, NULL))
!= -1)
while ((c = getopt_long (argc, argv, "bdfinst:vFLPS:T", long_options, NULL))
!= -1)
{
switch (c)
{
case 'b':
make_backups = true;
if (optarg)
version_control_string = optarg;
break;
case 'd':
case 'F':
hard_dir_link = true;
break;
case 'f':
remove_existing_files = true;
interactive = false;
break;
case 'i':
remove_existing_files = false;
interactive = true;
break;
case 'n':
dereference_dest_dir_symlinks = false;
break;
case 's':
symbolic_link = true;
break;
case 't':
if (target_directory)
error (EXIT_FAILURE, 0, _("multiple target directories specified"));
else
{
struct stat st;
if (stat (optarg, &st) != 0)
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
if (! S_ISDIR (st.st_mode))
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (optarg));
}
target_directory = optarg;
break;
case 'T':
no_target_directory = true;
break;
case 'v':
verbose = true;
break;
case 'S':
make_backups = true;
backup_suffix_string = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
break;
}
{
case 'b':
make_backups = true;
if (optarg)
version_control_string = optarg;
break;
case 'd':
case 'F':
hard_dir_link = true;
break;
case 'f':
remove_existing_files = true;
interactive = false;
break;
case 'i':
remove_existing_files = false;
interactive = true;
break;
case 'L':
logical = true;
break;
case 'n':
dereference_dest_dir_symlinks = false;
break;
case 'P':
logical = false;
break;
case 's':
symbolic_link = true;
break;
case 't':
if (target_directory)
error (EXIT_FAILURE, 0, _("multiple target directories specified"));
else
{
struct stat st;
if (stat (optarg, &st) != 0)
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
if (! S_ISDIR (st.st_mode))
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (optarg));
}
target_directory = optarg;
break;
case 'T':
no_target_directory = true;
break;
case 'v':
verbose = true;
break;
case 'S':
make_backups = true;
backup_suffix_string = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
break;
}
}
n_files = argc - optind;
@@ -508,75 +507,75 @@ main (int argc, char **argv)
if (no_target_directory)
{
if (target_directory)
error (EXIT_FAILURE, 0,
_("cannot combine --target-directory "
"and --no-target-directory"));
error (EXIT_FAILURE, 0,
_("cannot combine --target-directory "
"and --no-target-directory"));
if (n_files != 2)
{
if (n_files < 2)
error (0, 0,
_("missing destination file operand after %s"),
quote (file[0]));
else
error (0, 0, _("extra operand %s"), quote (file[2]));
usage (EXIT_FAILURE);
}
{
if (n_files < 2)
error (0, 0,
_("missing destination file operand after %s"),
quote (file[0]));
else
error (0, 0, _("extra operand %s"), quote (file[2]));
usage (EXIT_FAILURE);
}
}
else if (!target_directory)
{
if (n_files < 2)
target_directory = ".";
target_directory = ".";
else if (2 <= n_files && target_directory_operand (file[n_files - 1]))
target_directory = file[--n_files];
target_directory = file[--n_files];
else if (2 < n_files)
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (file[n_files - 1]));
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (file[n_files - 1]));
}
if (backup_suffix_string)
simple_backup_suffix = xstrdup (backup_suffix_string);
backup_type = (make_backups
? xget_version (_("backup type"), version_control_string)
: no_backups);
? xget_version (_("backup type"), version_control_string)
: no_backups);
if (target_directory)
{
int i;
/* Create the data structure we'll use to record which hard links we
create. Used to ensure that ln detects an obscure corner case that
might result in user data loss. Create it only if needed. */
create. Used to ensure that ln detects an obscure corner case that
might result in user data loss. Create it only if needed. */
if (2 <= n_files
&& remove_existing_files
/* Don't bother trying to protect symlinks, since ln clobbering
a just-created symlink won't ever lead to real data loss. */
&& ! symbolic_link
/* No destination hard link can be clobbered when making
numbered backups. */
&& backup_type != numbered_backups)
&& remove_existing_files
/* Don't bother trying to protect symlinks, since ln clobbering
a just-created symlink won't ever lead to real data loss. */
&& ! symbolic_link
/* No destination hard link can be clobbered when making
numbered backups. */
&& backup_type != numbered_backups)
{
dest_set = hash_initialize (DEST_INFO_INITIAL_CAPACITY,
NULL,
triple_hash,
triple_compare,
triple_free);
if (dest_set == NULL)
xalloc_die ();
}
{
dest_set = hash_initialize (DEST_INFO_INITIAL_CAPACITY,
NULL,
triple_hash,
triple_compare,
triple_free);
if (dest_set == NULL)
xalloc_die ();
}
ok = true;
for (i = 0; i < n_files; ++i)
{
char *dest_base;
char *dest = file_name_concat (target_directory,
last_component (file[i]),
&dest_base);
strip_trailing_slashes (dest_base);
ok &= do_link (file[i], dest);
free (dest);
}
{
char *dest_base;
char *dest = file_name_concat (target_directory,
last_component (file[i]),
&dest_base);
strip_trailing_slashes (dest_base);
ok &= do_link (file[i], dest);
free (dest);
}
}
else
ok = do_link (file[0], file[1]);

View File

@@ -34,7 +34,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("Usage: %s [OPTION]\n"), program_name);
@@ -44,7 +44,7 @@ Print the name of the current user.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -63,7 +63,7 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
usage, AUTHORS, (char const *) NULL);
usage, AUTHORS, (char const *) NULL);
if (getopt_long (argc, argv, "", NULL, NULL) != -1)
usage (EXIT_FAILURE);

2827
src/ls.c

File diff suppressed because it is too large Load Diff

View File

@@ -147,7 +147,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -156,26 +156,26 @@ Print or check %s (%d-bit) checksums.\n\
With no FILE, or when FILE is -, read standard input.\n\
\n\
"),
program_name,
DIGEST_TYPE_STRING,
DIGEST_BITS);
program_name,
DIGEST_TYPE_STRING,
DIGEST_BITS);
if (O_BINARY)
fputs (_("\
fputs (_("\
-b, --binary read in binary mode (default unless reading tty stdin)\n\
"), stdout);
else
fputs (_("\
fputs (_("\
-b, --binary read in binary mode\n\
"), stdout);
printf (_("\
-c, --check read %s sums from the FILEs and check them\n"),
DIGEST_TYPE_STRING);
DIGEST_TYPE_STRING);
if (O_BINARY)
fputs (_("\
fputs (_("\
-t, --text read in text mode (default if reading tty stdin)\n\
"), stdout);
else
fputs (_("\
fputs (_("\
-t, --text read in text mode (default)\n\
"), stdout);
fputs (_("\
@@ -194,8 +194,8 @@ The sums are computed as described in %s. When checking, the input\n\
should be a former output of this program. The default mode is to print\n\
a line with checksum, a character indicating type (`*' for binary, ` ' for\n\
text), and name for each FILE.\n"),
DIGEST_REFERENCE);
emit_bug_reporting_address ();
DIGEST_REFERENCE);
emit_ancillary_info ();
}
exit (status);
@@ -249,7 +249,7 @@ bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest, char **file_name
static bool
split_3 (char *s, size_t s_len,
unsigned char **hex_digest, int *binary, char **file_name)
unsigned char **hex_digest, int *binary, char **file_name)
{
size_t i;
bool escaped_filename = false;
@@ -264,12 +264,12 @@ split_3 (char *s, size_t s_len,
if (strncmp (s + i, DIGEST_TYPE_STRING, algo_name_len) == 0)
{
if (strncmp (s + i + algo_name_len, " (", 2) == 0)
{
*binary = 0;
return bsd_split_3 (s + i + algo_name_len + 2,
s_len - (i + algo_name_len + 2),
hex_digest, file_name);
}
{
*binary = 0;
return bsd_split_3 (s + i + algo_name_len + 2,
s_len - (i + algo_name_len + 2),
hex_digest, file_name);
}
}
/* Ignore this line if it is too short.
@@ -306,45 +306,45 @@ split_3 (char *s, size_t s_len,
if (escaped_filename)
{
/* Translate each `\n' string in the file name to a NEWLINE,
and each `\\' string to a backslash. */
and each `\\' string to a backslash. */
char *dst = &s[i];
while (i < s_len)
{
switch (s[i])
{
case '\\':
if (i == s_len - 1)
{
/* A valid line does not end with a backslash. */
return false;
}
++i;
switch (s[i++])
{
case 'n':
*dst++ = '\n';
break;
case '\\':
*dst++ = '\\';
break;
default:
/* Only `\' or `n' may follow a backslash. */
return false;
}
break;
{
switch (s[i])
{
case '\\':
if (i == s_len - 1)
{
/* A valid line does not end with a backslash. */
return false;
}
++i;
switch (s[i++])
{
case 'n':
*dst++ = '\n';
break;
case '\\':
*dst++ = '\\';
break;
default:
/* Only `\' or `n' may follow a backslash. */
return false;
}
break;
case '\0':
/* The file name may not contain a NUL. */
return false;
break;
case '\0':
/* The file name may not contain a NUL. */
return false;
break;
default:
*dst++ = s[i++];
break;
}
}
default:
*dst++ = s[i++];
break;
}
}
*dst = '\0';
}
return true;
@@ -388,21 +388,21 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result)
have_read_stdin = true;
fp = stdin;
if (O_BINARY && *binary)
{
if (*binary < 0)
*binary = ! isatty (STDIN_FILENO);
if (*binary)
xfreopen (NULL, "rb", stdin);
}
{
if (*binary < 0)
*binary = ! isatty (STDIN_FILENO);
if (*binary)
xfreopen (NULL, "rb", stdin);
}
}
else
{
fp = fopen (filename, (O_BINARY && *binary ? "rb" : "r"));
if (fp == NULL)
{
error (0, errno, "%s", filename);
return false;
}
{
error (0, errno, "%s", filename);
return false;
}
}
err = DIGEST_STREAM (fp, bin_result);
@@ -410,7 +410,7 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result)
{
error (0, errno, "%s", filename);
if (fp != stdin)
fclose (fp);
fclose (fp);
return false;
}
@@ -448,10 +448,10 @@ digest_check (const char *checkfile_name)
{
checkfile_stream = fopen (checkfile_name, "r");
if (checkfile_stream == NULL)
{
error (0, errno, "%s", checkfile_name);
return false;
}
{
error (0, errno, "%s", checkfile_name);
return false;
}
}
line_number = 0;
@@ -466,82 +466,82 @@ digest_check (const char *checkfile_name)
++line_number;
if (line_number == 0)
error (EXIT_FAILURE, 0, _("%s: too many checksum lines"),
checkfile_name);
error (EXIT_FAILURE, 0, _("%s: too many checksum lines"),
checkfile_name);
line_length = getline (&line, &line_chars_allocated, checkfile_stream);
if (line_length <= 0)
break;
break;
/* Ignore comment lines, which begin with a '#' character. */
if (line[0] == '#')
continue;
continue;
/* Remove any trailing newline. */
if (line[line_length - 1] == '\n')
line[--line_length] = '\0';
line[--line_length] = '\0';
if (! (split_3 (line, line_length, &hex_digest, &binary, &filename)
&& ! (is_stdin && STREQ (filename, "-"))
&& hex_digits (hex_digest)))
{
if (warn)
{
error (0, 0,
_("%s: %" PRIuMAX
": improperly formatted %s checksum line"),
checkfile_name, line_number,
DIGEST_TYPE_STRING);
}
}
&& ! (is_stdin && STREQ (filename, "-"))
&& hex_digits (hex_digest)))
{
if (warn)
{
error (0, 0,
_("%s: %" PRIuMAX
": improperly formatted %s checksum line"),
checkfile_name, line_number,
DIGEST_TYPE_STRING);
}
}
else
{
static const char bin2hex[] = { '0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f' };
bool ok;
{
static const char bin2hex[] = { '0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f' };
bool ok;
++n_properly_formatted_lines;
++n_properly_formatted_lines;
ok = digest_file (filename, &binary, bin_buffer);
ok = digest_file (filename, &binary, bin_buffer);
if (!ok)
{
++n_open_or_read_failures;
if (!status_only)
{
printf (_("%s: FAILED open or read\n"), filename);
fflush (stdout);
}
}
else
{
size_t digest_bin_bytes = digest_hex_bytes / 2;
size_t cnt;
/* Compare generated binary number with text representation
in check file. Ignore case of hex digits. */
for (cnt = 0; cnt < digest_bin_bytes; ++cnt)
{
if (tolower (hex_digest[2 * cnt])
!= bin2hex[bin_buffer[cnt] >> 4]
|| (tolower (hex_digest[2 * cnt + 1])
!= (bin2hex[bin_buffer[cnt] & 0xf])))
break;
}
if (cnt != digest_bin_bytes)
++n_mismatched_checksums;
if (!ok)
{
++n_open_or_read_failures;
if (!status_only)
{
printf (_("%s: FAILED open or read\n"), filename);
fflush (stdout);
}
}
else
{
size_t digest_bin_bytes = digest_hex_bytes / 2;
size_t cnt;
/* Compare generated binary number with text representation
in check file. Ignore case of hex digits. */
for (cnt = 0; cnt < digest_bin_bytes; ++cnt)
{
if (tolower (hex_digest[2 * cnt])
!= bin2hex[bin_buffer[cnt] >> 4]
|| (tolower (hex_digest[2 * cnt + 1])
!= (bin2hex[bin_buffer[cnt] & 0xf])))
break;
}
if (cnt != digest_bin_bytes)
++n_mismatched_checksums;
if (!status_only)
{
if (cnt != digest_bin_bytes)
printf ("%s: %s\n", filename, _("FAILED"));
else if (!quiet)
printf ("%s: %s\n", filename, _("OK"));
fflush (stdout);
}
}
}
if (!status_only)
{
if (cnt != digest_bin_bytes)
printf ("%s: %s\n", filename, _("FAILED"));
else if (!quiet)
printf ("%s: %s\n", filename, _("OK"));
fflush (stdout);
}
}
}
}
while (!feof (checkfile_stream) && !ferror (checkfile_stream));
@@ -563,39 +563,39 @@ digest_check (const char *checkfile_name)
{
/* Warn if no tests are found. */
error (0, 0, _("%s: no properly formatted %s checksum lines found"),
checkfile_name, DIGEST_TYPE_STRING);
checkfile_name, DIGEST_TYPE_STRING);
}
else
{
if (!status_only)
{
if (n_open_or_read_failures != 0)
error (0, 0,
ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX
" listed file could not be read",
"WARNING: %" PRIuMAX " of %" PRIuMAX
" listed files could not be read",
select_plural (n_properly_formatted_lines)),
n_open_or_read_failures, n_properly_formatted_lines);
{
if (n_open_or_read_failures != 0)
error (0, 0,
ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX
" listed file could not be read",
"WARNING: %" PRIuMAX " of %" PRIuMAX
" listed files could not be read",
select_plural (n_properly_formatted_lines)),
n_open_or_read_failures, n_properly_formatted_lines);
if (n_mismatched_checksums != 0)
{
uintmax_t n_computed_checksums =
(n_properly_formatted_lines - n_open_or_read_failures);
error (0, 0,
ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX
" computed checksum did NOT match",
"WARNING: %" PRIuMAX " of %" PRIuMAX
" computed checksums did NOT match",
select_plural (n_computed_checksums)),
n_mismatched_checksums, n_computed_checksums);
}
}
if (n_mismatched_checksums != 0)
{
uintmax_t n_computed_checksums =
(n_properly_formatted_lines - n_open_or_read_failures);
error (0, 0,
ngettext ("WARNING: %" PRIuMAX " of %" PRIuMAX
" computed checksum did NOT match",
"WARNING: %" PRIuMAX " of %" PRIuMAX
" computed checksums did NOT match",
select_plural (n_computed_checksums)),
n_mismatched_checksums, n_computed_checksums);
}
}
}
return (n_properly_formatted_lines != 0
&& n_mismatched_checksums == 0
&& n_open_or_read_failures == 0);
&& n_mismatched_checksums == 0
&& n_open_or_read_failures == 0);
}
int
@@ -622,33 +622,33 @@ main (int argc, char **argv)
switch (opt)
{
case 'b':
binary = 1;
break;
binary = 1;
break;
case 'c':
do_check = true;
break;
do_check = true;
break;
case STATUS_OPTION:
status_only = true;
warn = false;
quiet = false;
break;
status_only = true;
warn = false;
quiet = false;
break;
case 't':
binary = 0;
break;
binary = 0;
break;
case 'w':
status_only = false;
warn = true;
quiet = false;
break;
status_only = false;
warn = true;
quiet = false;
break;
case QUIET_OPTION:
status_only = false;
warn = false;
quiet = true;
break;
status_only = false;
warn = false;
quiet = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
usage (EXIT_FAILURE);
}
min_digest_line_length = MIN_DIGEST_LINE_LENGTH;
@@ -657,25 +657,25 @@ main (int argc, char **argv)
if (0 <= binary && do_check)
{
error (0, 0, _("the --binary and --text options are meaningless when "
"verifying checksums"));
"verifying checksums"));
usage (EXIT_FAILURE);
}
if (status_only & !do_check)
if (status_only && !do_check)
{
error (0, 0,
_("the --status option is meaningful only when verifying checksums"));
usage (EXIT_FAILURE);
}
if (warn & !do_check)
if (warn && !do_check)
{
error (0, 0,
_("the --warn option is meaningful only when verifying checksums"));
usage (EXIT_FAILURE);
}
if (quiet & !do_check)
if (quiet && !do_check)
{
error (0, 0,
_("the --quiet option is meaningful only when verifying checksums"));
@@ -693,53 +693,53 @@ main (int argc, char **argv)
char *file = argv[optind];
if (do_check)
ok &= digest_check (file);
ok &= digest_check (file);
else
{
int file_is_binary = binary;
{
int file_is_binary = binary;
if (! digest_file (file, &file_is_binary, bin_buffer))
ok = false;
else
{
size_t i;
if (! digest_file (file, &file_is_binary, bin_buffer))
ok = false;
else
{
size_t i;
/* Output a leading backslash if the file name contains
a newline or backslash. */
if (strchr (file, '\n') || strchr (file, '\\'))
putchar ('\\');
/* Output a leading backslash if the file name contains
a newline or backslash. */
if (strchr (file, '\n') || strchr (file, '\\'))
putchar ('\\');
for (i = 0; i < (digest_hex_bytes / 2); ++i)
printf ("%02x", bin_buffer[i]);
for (i = 0; i < (digest_hex_bytes / 2); ++i)
printf ("%02x", bin_buffer[i]);
putchar (' ');
if (file_is_binary)
putchar ('*');
else
putchar (' ');
putchar (' ');
if (file_is_binary)
putchar ('*');
else
putchar (' ');
/* Translate each NEWLINE byte to the string, "\\n",
and each backslash to "\\\\". */
for (i = 0; i < strlen (file); ++i)
{
switch (file[i])
{
case '\n':
fputs ("\\n", stdout);
break;
/* Translate each NEWLINE byte to the string, "\\n",
and each backslash to "\\\\". */
for (i = 0; i < strlen (file); ++i)
{
switch (file[i])
{
case '\n':
fputs ("\\n", stdout);
break;
case '\\':
fputs ("\\\\", stdout);
break;
case '\\':
fputs ("\\\\", stdout);
break;
default:
putchar (file[i]);
break;
}
}
putchar ('\n');
}
}
default:
putchar (file[i]);
break;
}
}
putchar ('\n');
}
}
}
if (have_read_stdin && fclose (stdin) == EOF)

View File

@@ -51,7 +51,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("Usage: %s [OPTION]... DIRECTORY...\n"), program_name);
@@ -71,7 +71,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -129,10 +129,10 @@ process_dir (char *dir, struct savewd *wd, void *options)
{
struct mkdir_options const *o = options;
return (make_dir_parents (dir, wd, o->make_ancestor_function, options,
o->mode, announce_mkdir,
o->mode_bits, (uid_t) -1, (gid_t) -1, true)
? EXIT_SUCCESS
: EXIT_FAILURE);
o->mode, announce_mkdir,
o->mode_bits, (uid_t) -1, (gid_t) -1, true)
? EXIT_SUCCESS
: EXIT_FAILURE);
}
int
@@ -159,24 +159,24 @@ main (int argc, char **argv)
while ((optc = getopt_long (argc, argv, "pm:vZ:", longopts, NULL)) != -1)
{
switch (optc)
{
case 'p':
options.make_ancestor_function = make_ancestor;
break;
case 'm':
specified_mode = optarg;
break;
case 'v': /* --verbose */
options.created_directory_format = _("created directory %s");
break;
case 'Z':
scontext = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
{
case 'p':
options.make_ancestor_function = make_ancestor;
break;
case 'm':
specified_mode = optarg;
break;
case 'v': /* --verbose */
options.created_directory_format = _("created directory %s");
break;
case 'Z':
scontext = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
if (optind == argc)
@@ -187,8 +187,8 @@ main (int argc, char **argv)
if (scontext && setfscreatecon (scontext) < 0)
error (EXIT_FAILURE, errno,
_("failed to set default file creation context to %s"),
quote (scontext));
_("failed to set default file creation context to %s"),
quote (scontext));
if (options.make_ancestor_function || specified_mode)
{
@@ -197,19 +197,19 @@ main (int argc, char **argv)
options.ancestor_mode = (S_IRWXUGO & ~umask_value) | (S_IWUSR | S_IXUSR);
if (specified_mode)
{
struct mode_change *change = mode_compile (specified_mode);
if (!change)
error (EXIT_FAILURE, 0, _("invalid mode %s"),
quote (specified_mode));
options.mode = mode_adjust (S_IRWXUGO, true, umask_value, change,
&options.mode_bits);
free (change);
}
{
struct mode_change *change = mode_compile (specified_mode);
if (!change)
error (EXIT_FAILURE, 0, _("invalid mode %s"),
quote (specified_mode));
options.mode = mode_adjust (S_IRWXUGO, true, umask_value, change,
&options.mode_bits);
free (change);
}
else
options.mode = S_IRWXUGO & ~umask_value;
options.mode = S_IRWXUGO & ~umask_value;
}
exit (savewd_process_files (argc - optind, argv + optind,
process_dir, &options));
process_dir, &options));
}

View File

@@ -46,7 +46,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("Usage: %s [OPTION]... NAME...\n"), program_name);
@@ -65,7 +65,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -90,18 +90,18 @@ main (int argc, char **argv)
while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1)
{
switch (optc)
{
case 'm':
specified_mode = optarg;
break;
case 'Z':
scontext = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
{
case 'm':
specified_mode = optarg;
break;
case 'Z':
scontext = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
if (optind == argc)
@@ -112,27 +112,27 @@ main (int argc, char **argv)
if (scontext && setfscreatecon (scontext) < 0)
error (EXIT_FAILURE, errno,
_("failed to set default file creation context to %s"),
quote (scontext));
_("failed to set default file creation context to %s"),
quote (scontext));
newmode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (specified_mode)
{
struct mode_change *change = mode_compile (specified_mode);
if (!change)
error (EXIT_FAILURE, 0, _("invalid mode"));
error (EXIT_FAILURE, 0, _("invalid mode"));
newmode = mode_adjust (newmode, false, umask (0), change, NULL);
free (change);
if (newmode & ~S_IRWXUGO)
error (EXIT_FAILURE, 0,
_("mode must specify only file permission bits"));
error (EXIT_FAILURE, 0,
_("mode must specify only file permission bits"));
}
for (; optind < argc; ++optind)
if (mkfifo (argv[optind], newmode) != 0)
{
error (0, errno, _("cannot create fifo %s"), quote (argv[optind]));
exit_status = EXIT_FAILURE;
error (0, errno, _("cannot create fifo %s"), quote (argv[optind]));
exit_status = EXIT_FAILURE;
}
exit (exit_status);

View File

@@ -47,11 +47,11 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("Usage: %s [OPTION]... NAME TYPE [MAJOR MINOR]\n"),
program_name);
program_name);
fputs (_("\
Create the special file NAME of the given TYPE.\n\
\n\
@@ -81,7 +81,7 @@ otherwise, as decimal. TYPE may be:\n\
p create a FIFO\n\
"), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -107,18 +107,18 @@ main (int argc, char **argv)
while ((optc = getopt_long (argc, argv, "m:Z:", longopts, NULL)) != -1)
{
switch (optc)
{
case 'm':
specified_mode = optarg;
break;
case 'Z':
scontext = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
{
case 'm':
specified_mode = optarg;
break;
case 'Z':
scontext = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
newmode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
@@ -126,47 +126,47 @@ main (int argc, char **argv)
{
struct mode_change *change = mode_compile (specified_mode);
if (!change)
error (EXIT_FAILURE, 0, _("invalid mode"));
error (EXIT_FAILURE, 0, _("invalid mode"));
newmode = mode_adjust (newmode, false, umask (0), change, NULL);
free (change);
if (newmode & ~S_IRWXUGO)
error (EXIT_FAILURE, 0,
_("mode must specify only file permission bits"));
error (EXIT_FAILURE, 0,
_("mode must specify only file permission bits"));
}
/* If the number of arguments is 0 or 1,
or (if it's 2 or more and the second one starts with `p'), then there
must be exactly two operands. Otherwise, there must be four. */
expected_operands = (argc <= optind
|| (optind + 1 < argc && argv[optind + 1][0] == 'p')
? 2 : 4);
|| (optind + 1 < argc && argv[optind + 1][0] == 'p')
? 2 : 4);
if (argc - optind < expected_operands)
{
if (argc <= optind)
error (0, 0, _("missing operand"));
error (0, 0, _("missing operand"));
else
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
error (0, 0, _("missing operand after %s"), quote (argv[argc - 1]));
if (expected_operands == 4 && argc - optind == 2)
fprintf (stderr, "%s\n",
_("Special files require major and minor device numbers."));
fprintf (stderr, "%s\n",
_("Special files require major and minor device numbers."));
usage (EXIT_FAILURE);
}
if (expected_operands < argc - optind)
{
error (0, 0, _("extra operand %s"),
quote (argv[optind + expected_operands]));
quote (argv[optind + expected_operands]));
if (expected_operands == 2 && argc - optind == 4)
fprintf (stderr, "%s\n",
_("Fifos do not have major and minor device numbers."));
fprintf (stderr, "%s\n",
_("Fifos do not have major and minor device numbers."));
usage (EXIT_FAILURE);
}
if (scontext && setfscreatecon (scontext) < 0)
error (EXIT_FAILURE, errno,
_("failed to set default file creation context to %s"),
quote (scontext));
_("failed to set default file creation context to %s"),
quote (scontext));
/* Only check the first character, to allow mnemonic usage like
`mknod /dev/rst0 character 18 0'. */
@@ -192,35 +192,35 @@ main (int argc, char **argv)
block_or_character:
{
char const *s_major = argv[optind + 2];
char const *s_minor = argv[optind + 3];
uintmax_t i_major, i_minor;
dev_t device;
char const *s_major = argv[optind + 2];
char const *s_minor = argv[optind + 3];
uintmax_t i_major, i_minor;
dev_t device;
if (xstrtoumax (s_major, NULL, 0, &i_major, NULL) != LONGINT_OK
|| i_major != (major_t) i_major)
error (EXIT_FAILURE, 0,
_("invalid major device number %s"), quote (s_major));
if (xstrtoumax (s_major, NULL, 0, &i_major, NULL) != LONGINT_OK
|| i_major != (major_t) i_major)
error (EXIT_FAILURE, 0,
_("invalid major device number %s"), quote (s_major));
if (xstrtoumax (s_minor, NULL, 0, &i_minor, NULL) != LONGINT_OK
|| i_minor != (minor_t) i_minor)
error (EXIT_FAILURE, 0,
_("invalid minor device number %s"), quote (s_minor));
if (xstrtoumax (s_minor, NULL, 0, &i_minor, NULL) != LONGINT_OK
|| i_minor != (minor_t) i_minor)
error (EXIT_FAILURE, 0,
_("invalid minor device number %s"), quote (s_minor));
device = makedev (i_major, i_minor);
device = makedev (i_major, i_minor);
#ifdef NODEV
if (device == NODEV)
error (EXIT_FAILURE, 0, _("invalid device %s %s"), s_major, s_minor);
if (device == NODEV)
error (EXIT_FAILURE, 0, _("invalid device %s %s"), s_major, s_minor);
#endif
if (mknod (argv[optind], newmode | node_type, device) != 0)
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
if (mknod (argv[optind], newmode | node_type, device) != 0)
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
}
break;
case 'p': /* `pipe' */
if (mkfifo (argv[optind], newmode) != 0)
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
error (EXIT_FAILURE, errno, "%s", quote (argv[optind]));
break;
default:

View File

@@ -95,7 +95,7 @@ If TEMPLATE is not specified, use tmp.XXXXXXXXXX.\n\
fputs ("\n", stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
@@ -114,13 +114,13 @@ count_trailing_X_s (const char *s)
static int
mkstemp_len (char *tmpl, size_t suff_len, bool dry_run)
{
return gen_tempname_len (tmpl, dry_run ? GT_NOCREATE : GT_FILE, suff_len);
return gen_tempname_len (tmpl, 0, dry_run ? GT_NOCREATE : GT_FILE, suff_len);
}
static int
mkdtemp_len (char *tmpl, size_t suff_len, bool dry_run)
{
return gen_tempname_len (tmpl, dry_run ? GT_NOCREATE : GT_DIR, suff_len);
return gen_tempname_len (tmpl, 0, dry_run ? GT_NOCREATE : GT_DIR, suff_len);
}
int
@@ -286,9 +286,3 @@ main (int argc, char **argv)
exit (status);
}
/*
* Local variables:
* indent-tabs-mode: nil
* End:
*/

257
src/mv.c
View File

@@ -94,7 +94,7 @@ rm_option_init (struct rm_options *x)
x->root_dev_ino = get_root_dev_ino (&dev_ino_buf);
if (x->root_dev_ino == NULL)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quote ("/"));
quote ("/"));
}
}
@@ -105,7 +105,7 @@ cp_option_init (struct cp_options *x)
cp_options_default (x);
x->copy_as_regular = false; /* FIXME: maybe make this an option */
x->reflink = false;
x->reflink_mode = REFLINK_NEVER;
x->dereference = DEREF_NEVER;
x->unlink_dest_before_opening = false;
x->unlink_dest_after_failed_open = false;
@@ -167,67 +167,70 @@ do_move (const char *source, const char *dest, const struct cp_options *x)
{
char const *dir_to_remove;
if (copy_into_self)
{
/* In general, when copy returns with copy_into_self set, SOURCE is
the same as, or a parent of DEST. In this case we know it's a
parent. It doesn't make sense to move a directory into itself, and
besides in some situations doing so would give highly nonintuitive
results. Run this `mkdir b; touch a c; mv * b' in an empty
directory. Here's the result of running echo `find b -print`:
b b/a b/b b/b/a b/c. Notice that only file `a' was copied
into b/b. Handle this by giving a diagnostic, removing the
copied-into-self directory, DEST (`b/b' in the example),
and failing. */
{
/* In general, when copy returns with copy_into_self set, SOURCE is
the same as, or a parent of DEST. In this case we know it's a
parent. It doesn't make sense to move a directory into itself, and
besides in some situations doing so would give highly nonintuitive
results. Run this `mkdir b; touch a c; mv * b' in an empty
directory. Here's the result of running echo `find b -print`:
b b/a b/b b/b/a b/c. Notice that only file `a' was copied
into b/b. Handle this by giving a diagnostic, removing the
copied-into-self directory, DEST (`b/b' in the example),
and failing. */
dir_to_remove = NULL;
ok = false;
}
dir_to_remove = NULL;
ok = false;
}
else if (rename_succeeded)
{
/* No need to remove anything. SOURCE was successfully
renamed to DEST. Or the user declined to rename a file. */
dir_to_remove = NULL;
}
{
/* No need to remove anything. SOURCE was successfully
renamed to DEST. Or the user declined to rename a file. */
dir_to_remove = NULL;
}
else
{
/* This may mean SOURCE and DEST referred to different devices.
It may also conceivably mean that even though they referred
to the same device, rename wasn't implemented for that device.
{
/* This may mean SOURCE and DEST referred to different devices.
It may also conceivably mean that even though they referred
to the same device, rename wasn't implemented for that device.
E.g., (from Joel N. Weber),
[...] there might someday be cases where you can't rename
but you can copy where the device name is the same, especially
on Hurd. Consider an ftpfs with a primitive ftp server that
supports uploading, downloading and deleting, but not renaming.
E.g., (from Joel N. Weber),
[...] there might someday be cases where you can't rename
but you can copy where the device name is the same, especially
on Hurd. Consider an ftpfs with a primitive ftp server that
supports uploading, downloading and deleting, but not renaming.
Also, note that comparing device numbers is not a reliable
check for `can-rename'. Some systems can be set up so that
files from many different physical devices all have the same
st_dev field. This is a feature of some NFS mounting
configurations.
Also, note that comparing device numbers is not a reliable
check for `can-rename'. Some systems can be set up so that
files from many different physical devices all have the same
st_dev field. This is a feature of some NFS mounting
configurations.
We reach this point if SOURCE has been successfully copied
to DEST. Now we have to remove SOURCE.
We reach this point if SOURCE has been successfully copied
to DEST. Now we have to remove SOURCE.
This function used to resort to copying only when rename
failed and set errno to EXDEV. */
This function used to resort to copying only when rename
failed and set errno to EXDEV. */
dir_to_remove = source;
}
dir_to_remove = source;
}
if (dir_to_remove != NULL)
{
struct rm_options rm_options;
enum RM_status status;
{
struct rm_options rm_options;
enum RM_status status;
char const *dir[2];
rm_option_init (&rm_options);
rm_options.verbose = x->verbose;
rm_option_init (&rm_options);
rm_options.verbose = x->verbose;
dir[0] = dir_to_remove;
dir[1] = NULL;
status = rm (1, &dir_to_remove, &rm_options);
assert (VALID_STATUS (status));
if (status == RM_ERROR)
ok = false;
}
status = rm ((void*) dir, &rm_options);
assert (VALID_STATUS (status));
if (status == RM_ERROR)
ok = false;
}
}
return ok;
@@ -239,7 +242,7 @@ do_move (const char *source, const char *dest, const struct cp_options *x)
static bool
movefile (char *source, char *dest, bool dest_is_dir,
const struct cp_options *x)
const struct cp_options *x)
{
bool ok;
@@ -275,7 +278,7 @@ usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
program_name);
else
{
printf (_("\
@@ -283,7 +286,7 @@ Usage: %s [OPTION]... [-T] SOURCE DEST\n\
or: %s [OPTION]... SOURCE... DIRECTORY\n\
or: %s [OPTION]... -t DIRECTORY SOURCE...\n\
"),
program_name, program_name, program_name);
program_name, program_name, program_name);
fputs (_("\
Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n\
\n\
@@ -327,7 +330,7 @@ the VERSION_CONTROL environment variable. Here are the values:\n\
existing, nil numbered if numbered backups exist, simple otherwise\n\
simple, never always make simple backups\n\
"), stdout);
emit_bug_reporting_address ();
emit_ancillary_info ();
}
exit (status);
}
@@ -364,59 +367,59 @@ main (int argc, char **argv)
backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX");
while ((c = getopt_long (argc, argv, "bfint:uvS:T", long_options, NULL))
!= -1)
!= -1)
{
switch (c)
{
case 'b':
make_backups = true;
if (optarg)
version_control_string = optarg;
break;
case 'f':
x.interactive = I_ALWAYS_YES;
break;
case 'i':
x.interactive = I_ASK_USER;
break;
case 'n':
x.interactive = I_ALWAYS_NO;
break;
case STRIP_TRAILING_SLASHES_OPTION:
remove_trailing_slashes = true;
break;
case 't':
if (target_directory)
error (EXIT_FAILURE, 0, _("multiple target directories specified"));
else
{
struct stat st;
if (stat (optarg, &st) != 0)
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
if (! S_ISDIR (st.st_mode))
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (optarg));
}
target_directory = optarg;
break;
case 'T':
no_target_directory = true;
break;
case 'u':
x.update = true;
break;
case 'v':
x.verbose = true;
break;
case 'S':
make_backups = true;
backup_suffix_string = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
{
case 'b':
make_backups = true;
if (optarg)
version_control_string = optarg;
break;
case 'f':
x.interactive = I_ALWAYS_YES;
break;
case 'i':
x.interactive = I_ASK_USER;
break;
case 'n':
x.interactive = I_ALWAYS_NO;
break;
case STRIP_TRAILING_SLASHES_OPTION:
remove_trailing_slashes = true;
break;
case 't':
if (target_directory)
error (EXIT_FAILURE, 0, _("multiple target directories specified"));
else
{
struct stat st;
if (stat (optarg, &st) != 0)
error (EXIT_FAILURE, errno, _("accessing %s"), quote (optarg));
if (! S_ISDIR (st.st_mode))
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (optarg));
}
target_directory = optarg;
break;
case 'T':
no_target_directory = true;
break;
case 'u':
x.update = true;
break;
case 'v':
x.verbose = true;
break;
case 'S':
make_backups = true;
backup_suffix_string = optarg;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
n_files = argc - optind;
@@ -425,39 +428,39 @@ main (int argc, char **argv)
if (n_files <= !target_directory)
{
if (n_files <= 0)
error (0, 0, _("missing file operand"));
error (0, 0, _("missing file operand"));
else
error (0, 0, _("missing destination file operand after %s"),
quote (file[0]));
error (0, 0, _("missing destination file operand after %s"),
quote (file[0]));
usage (EXIT_FAILURE);
}
if (no_target_directory)
{
if (target_directory)
error (EXIT_FAILURE, 0,
_("cannot combine --target-directory (-t) "
"and --no-target-directory (-T)"));
error (EXIT_FAILURE, 0,
_("cannot combine --target-directory (-t) "
"and --no-target-directory (-T)"));
if (2 < n_files)
{
error (0, 0, _("extra operand %s"), quote (file[2]));
usage (EXIT_FAILURE);
}
{
error (0, 0, _("extra operand %s"), quote (file[2]));
usage (EXIT_FAILURE);
}
}
else if (!target_directory)
{
assert (2 <= n_files);
if (target_directory_operand (file[n_files - 1]))
target_directory = file[--n_files];
target_directory = file[--n_files];
else if (2 < n_files)
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (file[n_files - 1]));
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quote (file[n_files - 1]));
}
if (make_backups && x.interactive == I_ALWAYS_NO)
{
error (0, 0,
_("options --backup and --no-clobber are mutually exclusive"));
_("options --backup and --no-clobber are mutually exclusive"));
usage (EXIT_FAILURE);
}
@@ -465,9 +468,9 @@ main (int argc, char **argv)
simple_backup_suffix = xstrdup (backup_suffix_string);
x.backup_type = (make_backups
? xget_version (_("backup type"),
version_control_string)
: no_backups);
? xget_version (_("backup type"),
version_control_string)
: no_backups);
hash_init ();
@@ -476,14 +479,14 @@ main (int argc, char **argv)
int i;
/* Initialize the hash table only if we'll need it.
The problem it is used to detect can arise only if there are
two or more files to move. */
The problem it is used to detect can arise only if there are
two or more files to move. */
if (2 <= n_files)
dest_info_init (&x);
dest_info_init (&x);
ok = true;
for (i = 0; i < n_files; ++i)
ok &= movefile (file[i], target_directory, true, &x);
ok &= movefile (file[i], target_directory, true, &x);
}
else
ok = movefile (file[0], file[1], false, &x);

Some files were not shown because too many files have changed in this diff Show More