Compare commits

...

188 Commits
v9.2 ... v9.4

Author SHA1 Message Date
Pádraig Brady
9530a14420 version 9.4
* NEWS: Record release date.
2023-08-29 14:36:22 +01:00
Paul Eggert
2dddc87214 maint: spelling fixes, including author names
Most of this just affects commentary and documentations.  The only
significant behavior change is translating author names via
proper_name_lite rather than proper_name_utf8, or not translating
them at all.  proper_name_lite is good enough for coreutils and
avoids the bloat that had coreutils not using Gnulib proper_name.
* bootstrap.conf (gnulib_modules): Use propername-lite instead
of propername.
(XGETTEXT_OPTIONS): Look for proper_name_lite instead of for
proper_name_utf8.
* cfg.mk (local-checks-to-skip): Remove
sc_proper_name_utf8_requires_ICONV, since we no longer use
proper_name_utf8.
(old_NEWS_hash): Update.
(sc_check-I18N-AUTHORS): Remove; no longer needed.
2023-08-28 14:06:43 -07:00
Paul Eggert
e3f15c9c4a test: omit unreachable code
* src/test.c (unary_operator): Omit unreachable ‘return false;’.
Oracle Solaris Studio 12.6 warns about it.
2023-08-28 14:06:43 -07:00
Bruno Haible
c8340962dd tests: avoid test failure on Android
* gl/tests/test-mbsalign.c (main): Skip the unibyte truncation test
on Android, when the "C" locale in fact is multibyte.
2023-08-28 12:18:26 +01:00
Paul Eggert
9348edb6b6 sort: port sort-merge-fdlimit test to Solaris 10
* tests/sort/sort-merge-fdlimit.sh: Give 'sort' fd 6 too.
Needed for the same reason sort-continue.sh needed a ulimit -n boost.
2023-08-27 20:50:04 -07:00
Paul Eggert
5c9998fbab sort: port sort-continue test back to Solaris 10
* tests/sort/sort-continue.sh: Use ulimit -n 7 not -n 6.  On
Solaris 10 'sort' uses Gnulib mkostemp, which calls Gnulib
getrandom, which opens /dev/urandom to calculate the temp file's
name, which means 'sort' needs one more file descriptor to work.
2023-08-27 19:15:31 -07:00
Pádraig Brady
b3afbcad9c tests: avoid false failure on cygwin
* tests/cksum/md5sum-bsd.sh: Avoid part of test dealing with backslashes
in file names, on systems where backslash is a directory separator.
Issue reported by Bruno Haible on cygwin.
2023-08-27 20:22:32 +01:00
Pádraig Brady
f4e2e2bb57 cksum: adjust tests and docs to binary mode handling
Following commit v9.3-80-g5e1e0993b which makes cksum
match the output of the standalone utilities...

* doc/coreutils.texi (cksum output modes): Remove the mention
that cksum never outputs a binary indicator, as that's no longer the
case.
* tests/cksum/b2sum.sh: Avoid outputting a binary indicator.
* tests/cksum/sm3sum.pl: Likewise.
2023-08-27 19:53:52 +01:00
Pádraig Brady
5e44ad4e6d all: avoid duplicated write errors on FreeBSD
* src/system.h (write_error): Also call fpurge(), which was seen to
be needed on FreeBSD 13.1 to avoid duplicated write errors.
* src/head.c (xwrite_stdout): Likewise.
* bootstrap.conf: Depend on fpurge.
Reported by Bruno Haible.
2023-08-27 17:32:07 +01:00
Pádraig Brady
13e13107e1 tests: avoid false failure where sleep is a shell builtin
* tests/misc/usage_vs_getopt.sh: Handle sleep as a shell builtin,
which was seen on Alpine Linux 3.18.
2023-08-27 17:18:01 +01:00
Bruno Haible
900606431e build: fix link errors of sort, split on CentOS 5 and Solaris 10
* src/local.mk (src_sort_LDADD, src_split_LDADD): Add $(CLOCK_TIME_LIB).
2023-08-27 16:37:54 +01:00
Bruno Haible
016e9a3bb8 build: fix compilation error on AIX 7.1
* src/copy.c (copy_internal): Don't test for ENOTEMPTY if it has the
same value as EEXIST.
2023-08-27 16:37:52 +01:00
Pádraig Brady
32e8ead131 build: update with gnulib fixes
* gnulib: Update to incorporate gnulib fixes
from Bruno Haible from his coreutils 9.4 pre-release testing.
2023-08-27 16:09:07 +01:00
Pádraig Brady
25727ebd6a doc: remove older ChangeLog items
* Makefile.am: Update the oldest documented version
to 8.30 which is now about 5 years old.
2023-08-24 12:10:49 +01:00
Pádraig Brady
13f439ce56 shred: fix operation on Solaris with 64 bit builds
* NEWS: Mention the bug fix.
* gl/lib/randread.c (get_nonce): Limit getrandom() <= 1024 bytes.
2023-08-23 15:23:42 +01:00
Pádraig Brady
d553ab43c6 build: update gnulib submodule to latest
* gnulib: Update to latest
2023-08-22 12:10:09 +01:00
Pádraig Brady
e15f5ab354 doc: reorg texinfo for the checksumming utilities
* doc/coreutils.texi: Reorg so that 'cksum invocation' is the
main node listing all options and output formats, which is then
referenced by the descriptions of the standalone utilities.
Use macros in the description of the standalone utilities
rather than referencing 'md5sum invocation' to be more direct.
2023-08-22 12:09:57 +01:00
Pádraig Brady
b0af86d062 doc: cksum: remove -b description from texinfo
* doc/coreutils.texi (cksum invocation): Following commit 5e1e0993
also remove the desciption of the -b option for the cksum command.
2023-08-21 22:20:39 +01:00
Pádraig Brady
4f92de5822 cp: with --sparse=never, avoid COW and copy offload
* src/cp.c (main): Set default reflink mode appropriately
with --sparse=never.
* src/copy.c (infer_scantype): Add a comment to related code.
* tests/cp/sparse-2.sh: Add a test case.
* NEWS: Mention the bug.
2023-08-21 14:28:14 +01:00
Pádraig Brady
27c76b83b4 maint: comment spelling fix
* tests/split/l-chunk-root.sh: Fix recently introduced typo.
2023-08-19 16:45:17 +01:00
Pádraig Brady
20b9a015e5 maint: remove extraneous line in NEWS
* NEWS: Remove extraneous line.
2023-08-16 11:47:54 +01:00
Bruno Haible
622eea03cd uptime: simplify following gnulib changes
* build-aux/gen-lists-of-programs.sh (build_if_possible_progs):
Remove uptime.
(normal_progs): Add uptime.
* configure.ac: Remove GNULIB_BOOT_TIME invocation.
* m4/boottime.m4: Remove file.
* src/uptime.c: Don't include <sys/sysctl.h>, <OS.h>.
(print_uptime): Don't call sysctl, get_system_info, as Gnulib's
readutmp module now does this.
2023-08-15 15:22:27 -07:00
Paul Eggert
f2c2643fc5 maint: update uptime NEWS
* NEWS: Update as per Bruno Haible <https://bugs.gnu.org/65255#14>.
2023-08-15 15:22:27 -07:00
Pádraig Brady
fc5e68612f tests: fix false failure due to locale on alpine
* tests/sort/sort-debug-keys.sh: Decimal point was seen to be '.'
on fr_FR.UTF-8 on Alpine Linux 3.18, so add an extra guard
to ensure we've a ',' as the decimal point on this locale.
Fixes https://bugs.gnu.org/65310
2023-08-15 22:55:41 +01:00
Paul Eggert
1ea34cbf6a uptime: be more generous about read_utmp failure
* src/uptime.c (print_uptime): Check for overflow
when computing uptime.  Use C99-style decl after statements.
Do not let an idx_t value go negative.
(print_uptime, uptime): Be more generous about read_utmp failures,
or when read_utmp does not report the boot time.  Instead of
failing, warn but keep going, printing the information that we did
get, and then exit with nonzero status.
(print_uptime): Return the desired exit status.  Caller changed.
2023-08-15 14:01:58 -07:00
Bruno Haible
d8cfa5db49 uptime: Include VM sleep time in the "up" duration
* src/uptime.c: Don't include c-strtod.h.
(print_uptime): Don't read /proc/uptime, because the value it provides
does not change when a date adjustment occurs.
* bootstrap.conf (gnulib_modules): Remove 'uptime'.
2023-08-15 14:01:58 -07:00
Paul Eggert
58977651ec build: update gnulib submodule to latest 2023-08-15 14:01:58 -07:00
Bernhard Voelker
0cb8332196 maint: fix typo in NEWS
* NEWS: s|/who/log/wtmp|/var/log/tmp|, introduced in commit 85edb4afbd.
2023-08-15 13:35:13 +02:00
Bernhard Voelker
d428096a6a doc: reference install(1) and cp(1) from each other
* man/cp.x (SEE ALSO): Add install(1).
* man/install.x (SEE ALSO): Add cp(1).

Discussed at
https://lists.gnu.org/r/coreutils/2023-08/msg00026.html
2023-08-15 13:29:41 +02:00
Bruno Haible
db1d95f43b build: fix recent compilation error on GNU/Hurd
* src/copy.c (set_author): Revert change from MACH_PORT_NULL to
MACH_PORT_nullptr from commit 16b5ca6e (2023-06-29).
2023-08-14 22:11:57 +01:00
Pádraig Brady
dc3c843187 maint: avoid syntax-check failure
* po/POTFILES.in: Cater to lib/file-type.c adjustments
as suggested by sc_po_check.
2023-08-14 14:03:35 +01:00
Bruno Haible
049e5b0f87 build: fix link errors with gcc < 4.8
* configure.ac: Attempt to link, not only compile, the test programs
with __builtin_cpu_supports, to avoid link errors with cksum and wc.
2023-08-14 13:45:44 +01:00
Paul Eggert
85edb4afbd doc: improve NEWS discussion of systemd 2023-08-12 23:51:59 -07:00
Paul Eggert
9b673e61af build: update gnulib submodule to latest 2023-08-12 23:51:59 -07:00
Pádraig Brady
f31229ebd1 maint: allow use of printf C99 integer size specifiers
Older systems that had issues with these like HP-UX and Solaris 8
are now obsolete, and can easily apply patches to provide support.
Also we've used %td since coreutils 9.1, with no reported issues.

* cfg.mk (sc_prohibit-c99-printf-format): Remove to allow use of
%[jtz] size specifiers, which allows for cleaner code
by avoiding the need to cast to PRI?MAX etc.
2023-08-12 11:32:25 +01:00
Pádraig Brady
5420604332 doc: separate out description of 2038 time stamp change
* NEWS: Separate out the description of the _existing_ issues
with outputting timestamps on 32 bit systems, from _future_ issues
outputting timestamps on all systems.  Also move this to the
"improvement" section, since it's not really a coreutils
specific issue, and also is a build time configurable option.
2023-08-11 14:34:49 +01:00
Bruno Haible
d70d55c0a4 pinky,users,who: optimize read_utmp invocation
When we are only interested in entries of type USER_PROCESS, tell
read_utmp that it does not need to determine the boot time.

* src/pinky.c (short_pinky): Pass option READ_UTMP_USER_PROCESS.
* src/users.c (users): Likewise.
* src/who.c (who): Likewise, if calling list_entries_who.
2023-08-11 14:07:37 +01:00
Paul Eggert
ad82336026 who: simplify based on readutmp changes
* src/pinky.c (time_string, print_entry, scan_entries, short_pinky):
* src/uptime.c (print_uptime, uptime):
* src/users.c (list_entries_users, users):
* src/who.c (UT_TYPE_RUN_LVL, UT_TYPE_INIT_PROCESS)
(UT_TYPE_LOGIN_PROCESS, UT_TYPE_DEAD_PROCESS, UT_TYPE_NEW_TIME)
(time_string, print_user, print_boottime)
(make_id_equals_comment, print_deadprocs, print_login)
(print_initspawn, print_clockchange, print_runlevel)
(list_entries_who, scan_entries, who):
Simplify, partly by using plain -> rather than macros.
2023-08-08 20:05:33 -07:00
Paul Eggert
422dcd424c pinky,who: omit pragma
* src/pinky.c, src/who.c:
Omit no-longer-needed -Wstringop-overread pragma.
2023-08-08 20:05:33 -07:00
Bruno Haible
911c0bc41d maint: Simplify after gnulib changed
Update gnulib submodule to latest.
All of UT_USER_SIZE, UT_ID_SIZE, UT_LINE_SIZE, UT_HOST_SIZE are now -1.

* src/pinky.c (print_entry): Remove code for bounded-length ut_line,
ut_user, ut_host.
(scan_entries): Remove code for bounded-length ut_user.
* src/who.c (print_line): Remove userlen, linelen arguments.
(print_user): Remove code for bounded-length ut_line, ut_user, ut_host.
(make_id_equals_comment): Remove code for bounded-length ut_id.
(print_boottime, print_deadprocs, print_login, print_initspawn,
print_clockchange, print_runlevel, print_heading): Update print_line
invocations.
(scan_entries): Remove code for bounded-length ut_line.
2023-08-08 20:05:33 -07:00
Paul Eggert
0e58c95000 maint: Update after gnulib module 'readutmp' changed
(This patch is coauthored with Bruno Haible,
with original version at <https://bugs.gnu.org/64937#>.)
This updates the gnulib submodule to latest.
For year-2038 safety on Linux/{x86,arm},
this adds an --enable-systemd option to ‘configure’.
The idea is that this sort of thing will become the default
after it has been tested more.
* configure.ac: Don't test whether struct utmp and struct utmpx
have the ut_host field; this is now done in gnulib's readutmp module.
* src/local.mk: Link the programs 'pinky', 'uptime', 'users',
'who' with $(READUTMP_LIB).
* src/pinky.c, src/who.c:
Test HAVE_STRUCT_XTMP_UT_HOST instead of HAVE_UT_HOST.
* src/pinky.c (print_entry):
* src/who.c (print_user, print_deadprocs, print_login)
(print_initspawn, scan_entries):
Support the situation where ut_line is a 'char *' rather than a
'char[]' of fixed size.  Likewise for ut_user and ut_host.
(make_id_equals_comment): Likewise for ut_id.
* src/pinky.c (print_entry):
* src/who.c (print_user):
Open /dev to simplify looking up its entries.
Don’t use printf if the output might in theory be longer than INT_MAX.
* src/pinky.c (scan_entries, short_pinky):
* src/uptime.c (print_uptime, uptime):
* src/users.c (list_entries_users, users):
* src/who.c (who):
Use idx_t where new read_utmp needs it.
* src/system.h (STREQ_LEN): Add comment that last arg can be -1.
2023-08-03 23:16:00 -07:00
Paul Eggert
cb7bb52551 uptime: fix Y5881633 bug
* src/uptime.c (print_uptime): Prefer signed types.
Fix unlikely bug on platforms with 32-bit long and 64-bit time_t
if the idle time exceeds 2**31 days (about 6 million years...).
2023-08-02 06:52:39 -07:00
Paul Eggert
93e30466ff pinky: fix "d" typo
Problem reported by Bruno Haible (bug#65003).
* src/pinky.c (idle_string): Fix recently-introduced typo:
missing "d" for "days".
2023-08-02 06:52:39 -07:00
Dragan Simic
73ba9f71e1 maint: minor comment cleanups
* src/cut.c: Adjust a few comments slightly, simply to have their
trailing whitespace the same as in the majority of the comments.
2023-08-01 15:35:44 +01:00
Dragan Simic
7783df863a cut: promptly diagnose write errors, continued
* src/cut.c: Complete the error-handling improvements started in
commit e0a4a60af5, by adding a couple of remaining checks for putchar().
While there, sprinkle a few rather useful comments, and perform a few
small code cleanups, to make the code and the comments more uniform
and more conformant to the official coding style.  Also make the help
message slightly more uniform.
2023-08-01 15:34:50 +01:00
Dragan Simic
10dcb0b125 maint: reformat text width in HACKING
* HACKING: Adjust line lengths.
2023-08-01 15:32:21 +01:00
Pádraig Brady
e886b300f7 pinky: fix buffer size on 32 bit builds
* src/pinky.c (idle_string): Use the correct buffer size
following the recent int type adjustment.
2023-08-01 14:59:29 +01:00
Pádraig Brady
89c8c5fff3 od: fix issues with recent format string changes
* src/ioblksize.h: Avoid syntax check with redundant idx.h inclusion.
* src/od.c (FMT_BYTES_ALLOCATED): Increase by two to avoid:
  error: '%s' directive writing between 1 and 2 bytes into a region
  of size between 1 and 4 [-Werror=format-overflow=]
(maint): Use %td to print idx_t rather than invalid %jt format.
2023-08-01 13:30:02 +01:00
Paul Eggert
0b2796750f pinky: prefer signed types
* src/pinky.c (idle_string): Prefer intmax_t to unsigned long int;
this avoids an overflow on platforms where unsigned long is 32
bits and time_t is 64 bits (the bug could occur on such a system
that was idle for more than 6 million years, so it’s a bit
hard to supply a test case...).
2023-07-31 17:51:29 -07:00
Paul Eggert
703d2d6bd4 pathchk: prefer signed types
* src/pathchk.c (validate_file_name): Prefer signed types.
2023-07-31 17:51:29 -07:00
Paul Eggert
244268f719 numfmt: prefer signed types
* src/numfmt.c (suffix_power_char, powerld, expld)
(simple_strtod_int, double_to_human, prepare_padded_number)
(process_suffixed_number): Prefer signed types.
(process_suffixed_number): Fix an unlikely bug if an
arg has exactly 2**32 spaces at the start.
2023-07-31 17:51:29 -07:00
Paul Eggert
df73cf50e9 mktemp,seq: prefer signed types
* src/mktemp.c (main):
* src/seq.c (main): Prefer signed types.
2023-07-31 17:51:28 -07:00
Paul Eggert
a0b8c4ad61 kill: prefer signed types
* src/kill.c (list_signals):
Prefer signed types.  This avoids undefined behavior on
theoretical platforms where unsigned and signed int have
different representations.
2023-07-31 17:51:28 -07:00
Paul Eggert
6387164e5e groups,id: don’t assume gid_t fits in unsigned long
* src/group-list.c (print_group): Convert to intmax_t or
uintmax_t, not to unsigned long.
2023-07-31 17:51:28 -07:00
Paul Eggert
e20d63c442 dircolors,du,expr: prefer signed types
* src/dircolors.c (dc_parse_stream):
* src/du.c (max_depth, main):
* src/expr.c (main):
Prefer signed types.
2023-07-31 17:51:28 -07:00
Paul Eggert
08c325c63b od: prefer signed types
* src/od.c: Include stdckdint.h.
(bytes_to_oct_digits, bytes_to_signed_dec_digits)
(bytes_to_unsigned_dec_digits, bytes_to_hex_digits):
Use ‘char’ for these small constants.
(simple_strtoi): Rename from simple_strtoul.  Convert to int
instead of unsigned long; that’s good enough.  All uses changed.
Simplify by using ckd_mul and ckd_add to check for overflow.
(main): Prefer signed types to unsigned.
2023-07-31 17:51:28 -07:00
Paul Eggert
89f7d44912 cksum,df,digest: prefer signed types
* src/cksum.c (main):
* src/df.c (decode_output_arg):
* src/digest.c (valid_digits):
Prefer idx_t to unsigned types when the value is an index
into an array.
2023-07-31 17:51:28 -07:00
Paul Eggert
73a813e484 join: prefer signed types
* src/join.c (struct outlist, struct field, struct line)
(struct seq, autocount_1, autocount_2, join_field_1, join_field_2)
(extract_field, keycmp, check_order, init_linep, free_spareline)
(getseq, delseq, prfield, prfields, prjoin, join, add_field)
(string_to_join_field, decode_field_spec, add_field_list)
(set_join_field, main):
Prefer signed integers to unsigned.
2023-07-31 17:51:28 -07:00
Paul Eggert
46e5702bf3 factor: prefer signed types
When it’s easy, prefer signed types to unsigned, as
they are less confusing and allow overflow checking.
* src/factor.c (struct mp_factors, udiv_qrnnd)
(count_leading_zeros, count_trailing_zeros)
(factor_insert_multiplicity, mp_factor_clear, mp_factor_insert)
(factor_insert_refind, factor_using_division)
(mp_factor_using_division, powm2, millerrabin, millerrabin2)
(mp_millerrabin, prime_p, prime2_p, mp_prime_p, isqrt, isqrt2)
(invtab, q_freq, factor_using_squfof, strto2uintmax)
(print_factors_single, main):
Prefer signed integers to unsigned.
2023-07-31 17:51:28 -07:00
Paul Eggert
9970fac34b maint: include idx.h everywhere
* src/system.h: Include idx.h here, instead of in every file
that currently uses idx_t.  This should make it easier to use
idx_t in the future.
2023-07-31 17:51:28 -07:00
Paul Eggert
9cbda6e1f8 who: fix only-theoretical overflow
Change stzncpy’s implementation to match its comment, in the case
where SRC + LEN would overflow.  This case never happens in coreutils.
* src/system.h (stzncpy): Work even if SRC + LEN would overflow.
2023-07-31 11:21:43 -07:00
Pádraig Brady
779f34e180 tac: handle short reads on input
This can be reproduced by getting the read() above 2G,
which induces a short read, thus triggering the erroneous failure.

  $ truncate -s 5G 5G

  $ cat 5G | TMPDIR=$PWD tac | wc -c
  tac: /tmp/tacFt7txA: read error: Illegal seek
  0

With the fix in place we now get:

  $ cat 5G | TMPDIR=$PWD src/tac | wc -c
  5368709120

* src/tac.c (tac_seekable): Use full_read() to handle short reads.
* NEWS: Mention the bug fix.
Reported at https://bugs.debian.org/1042546
2023-07-31 18:55:19 +01:00
Bruno Haible
a102826245 uptime: output correct user count on OpenBSD
* src/uptime.c (print_uptime, uptime): Always call read_utmp
and count the result.
* NEWS: Mention the fix (text by Bruno Haible).
2023-07-31 09:28:04 -07:00
Paul Eggert
76c795bf2e build: update gnulib submodule to latest 2023-07-31 09:28:04 -07:00
Paul Eggert
39f5c3f92e build: update gnulib submodule to latest
* NEWS: Mention a bug that this fixes.
2023-07-29 17:23:15 -07:00
Paul Eggert
3cb862ce5f mv: better diagnostic for 'mv dir x' failure
Problem reported by Nir Oren <https://bugs.gnu.org/64785>.
* src/copy.c (copy_internal): Use a more-specific diagnostic when
a rename fails due to a problem that must be due to the
destination, avoiding user confusion in cases like 'mv dir x'
where x is a nonempty directory.
* tests/mv/dir2dir.sh: Adjust to match.
2023-07-22 13:41:07 -07:00
Pádraig Brady
b0e41e3f30 doc: clarify tail -n/-c +NUM operation
tail -n/-c +NUM, is different from tail -n/-c NUM,
and head -n/-c NUM, and head -n/c -NUM, in that it
specifies a 1 based index rather than a count to skip/include.
So clarify this in tail --help and tail info manual.
Note we also mention this gotcha at:
https://www.pixelbeat.org/docs/coreutils-gotchas.html#tail

* doc/coreutils.texi (tail invocation): Give examples for -c/-n +NUM,
to make it clear one has to specify a number 1 larger than
might be expected.
* src/tail.c (usage): State the skip at start edge case more clearly
in the -n description. -c is not often used with tail so we leave
full explanation of that to the info manual.  Also split the string
to simplify translation.
2023-07-20 15:13:01 +01:00
Pádraig Brady
4bf182f92a maint: add a syntax check to prevent use of NULL
* cfg.mk (sc_prohibit_NULL): Direct to use nullptr instead.
2023-07-18 23:13:06 +01:00
Pádraig Brady
8fd50b8672 tests: split: provide more isolated /tmp handling
* tests/split/l-chunk.sh: Move the "expensive" portion to ...
* tests/split/l-chunk-root.sh: .. A new test split from l-chunk.sh
which uses an isolated TMPDIR, rather than exhausting /tmp,
as that gives false positive failures with some other coreutils tests
like tac-2-nonseekable.sh and shuf-reservoir.sh at least.
* tests/local.mk: Reference the new test.
2023-07-18 23:11:24 +01:00
Pádraig Brady
464be62df6 split: honor $TMPDIR for temp files
* bootstrap.conf: Depend on tmpdir rather than tmpfile,
as the standard tmpfile() doesn't honor $TMPDIR.
* src/split.c (copy_to_tmpfile): Adjust to call temp_stream() rather
than tmpfile();
* NEWS: Mention the improvement.
2023-07-18 23:11:24 +01:00
Pádraig Brady
1b86b70dd5 tac: fall back to /tmp if $TMPDIR is unavailable
This also refactors temp_stream() to its own module,
in preparation for use by split.

* src/tac.c: Refactor temp_stream() out to ...
* src/temp-stream.c: ... A new module mostly refactored from tac,
but uses tmpdir to more robustly support $TMPDIR,
while falling back to /tmp if not available.
* src/temp-stream.h: The new module interface.
* src/local.mk: Reference the new module from tac.
* tests/tac/tac.pl: Adjust to non failing missing $TMPDIR.
* po/POTFILES.in: Reference the new module with translatable strings.
* NEWS: Mention the user visible improvements to tac TMPDIR handling.
2023-07-18 23:10:40 +01:00
Pádraig Brady
47e1388d6f maint: add syntax check to ensure safe mkstemp usage
One needs to include stdlib--.h if using mkstemp()
lest one hits esoteric bugs with closed stdin etc.

* cfg.mk (sc_require_stdlib_safer): Add a new syntax check.
(sc_require_stdio_safer): Fix this; broken since commit fa7ed969c3.
2023-07-18 18:59:10 +01:00
Pádraig Brady
02a4ebd6c4 join: promptly diagnose write errors
* src/join.c (prjoin): Check for write errors after each line.
* tests/misc/write-errors.sh: enable the test for join.
* NEWS: Mention the improvement.
2023-07-17 11:28:36 +01:00
Pádraig Brady
b1df1d557e comm: promptly diagnose write errors
* src/comm.c (writeline): Simplify by removing the unneeded STREAM
parameter.  Call write_error() upon ferror().
(compare_files): Adjust to simplified writeline().
* tests/misc/write-errors.sh: Enable comm test.
* NEWS: Mention the improvement.
2023-07-17 11:28:36 +01:00
Pádraig Brady
e0a4a60af5 cut: promptly diagnose write errors
* src/cut.c (cut_bytes): Diagnose errors from fwrite() and putchar().
(cut_fields): Likewise.
* tests/misc/write-errors.sh: Enable the test for cut,
and augment to cover both cut_bytes() and cut_fields().
* NEWS: Mention the improvement.
2023-07-17 11:28:36 +01:00
Pádraig Brady
ca7711456f uniq: promptly diagnose write errors
* src/uniq.c (write_line): Check the output from fwrite() immediately.
(check_file): Likewise.
* tests/misc/write-errors.sh: Enable the test case.
* NEWS: Mention the improvement.
2023-07-17 11:28:36 +01:00
Pádraig Brady
a03c00023a od: promptly diagnose write errors
* src/od.c (dump): Check for write errors after each block written,
to exit early even with large / unbounded inputs.
* tests/misc/write-errors.sh: enable od check.
* NEWS: Mention the improvement.
Fixes https://bugs.gnu.org/64540
2023-07-17 11:28:36 +01:00
Pádraig Brady
0b2ff7637f all: avoid repeated diagnostic upon write error
* cfg.mk (sc_some_programs_must_avoid_exit_failure): Adjust to
avoid false positive.
(sc_prohibit_exit_write_error): A new syntax check to prohibit
open coding error(..., "write error"); instead directing to use...
* src/system.h (write_error): ... a new function to clear stdout errors
before we explicitly diagnose a write error and exit.
* src/basenc.c: Use write_error() to ensure no repeated diagnostics.
* src/cat.c: Likewise.
* src/expand.c: Likewise.
* src/factor.c: Likewise.
* src/paste.c: Likewise.
* src/seq.c: Likewise.
* src/shuf.c: Likewise.
* src/split.c: Likewise.
* src/tail.c: Likewise.
* src/tr.c: Likewise.
* src/unexpand.c: Likewise.
* tests/misc/write-errors.sh: Remove TODOs for the fixed utilities:
expand, factor, paste, shuf, tr, unexpand.
2023-07-17 11:28:36 +01:00
Pádraig Brady
ef47b928d0 tests: ensure utilties exit promptly upon write error
* tests/local.mk: Reference the new test.
* tests/misc/write-errors.sh: A new test to ensure utilities
exit promptly upon writing to /dev/full.
2023-07-17 11:28:30 +01:00
Jim Meyering
c0e7e4a1d4 cksum: improve problematic_chars function
* src/digest.c (problematic_chars): Implement using strcspn,
and traversing S only once, rather than once per escaped byte.
2023-07-13 22:39:04 -07:00
Pádraig Brady
ebd776a422 maint: give a new function the "pure" attribute
* src/digest.c (problematic_chars): This recently introduced
function does not modify state so is pure, even though GCC 13.1 at least
did not warn about that attribute being appropriate.
2023-07-12 20:41:00 +01:00
Pádraig Brady
86614ba1c2 cksum: escape filenames with a leading '\' in --check status
* src/digest.c (digest_check): Also escape in the case that the
file name contains '\'.
* tests/cksum/md5sum-bsd.sh: Add a test case.
* doc/coreutils.texi (md5um invocation): Clarify escaping operation.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/64392
2023-07-11 12:16:41 +01:00
Pádraig Brady
5e1e0993b5 cksum: support transparent emulation of older utils
Support -b, --binary, and -t, --text
to allow full emulation of older utilities with:
  exec cksum -a $algo --untagged "$@"
Note this would diverge from OpenBSD's support of cksum -b.

* src/digest.c: Change -b to mean --binary, not --base64 in all cases.
Accept -b and -t in all cases.  Keep --binary and --text undocumented
for cksum.
* tests/cksum/cksum-base64.pl: s/-b/--base64/.
* tests/cksum/cksum-a.sh: Ensure cksum supports -b and -t appropriately.
* NEWS: Mention the change in behavior.
2023-07-09 14:33:14 +01:00
Pádraig Brady
2f1cffe07a maint: avoid static analysis failure for ignored dup2 return
* src/sort.c: We're ignoring failures from these calls,
so do so explicitly to avoid static analysis issues
as reported by coverity.
2023-07-08 13:42:51 +01:00
Sylvestre Ledru
1ac8630f1e tests: mktemp -t: $TMPDIR has higher priority than -p
* tests/misc/mktemp.pl: Ensure that with -t,
$TMPDIR has precedence over -p.
2023-07-04 12:11:16 +01:00
Paul Eggert
80a6c7faa2 maint: update .gitignore
Add some newly-created Gnulib files,
plus some bootstrap temporaries.
2023-07-01 11:51:17 -07:00
Paul Eggert
57ffc40323 stty: fix untranslated diagnostics
* src/stty.c (set_speed): Translate diagnostics.
2023-07-01 11:51:17 -07:00
Paul Eggert
6380a66a7d maint: sync bootstrap from Gnulib
* bootstrap: Copy from gnulib/build-aux/bootstrap.
2023-07-01 11:51:17 -07:00
Paul Eggert
d727aba601 maint: prefer ckd_add to INT_ADD_WRAPV etc
* bootstrap.conf (gnulib_modules): Add stdckdint.
Also, in C source code, prefer C23 macros like ckd_add
to their Gnulib near-equivalents like INT_ADD_WRAPV.
Include <stdckdint.h> as needed.
2023-07-01 11:51:16 -07:00
Paul Eggert
123d03dca4 who: don’t crash if clock gyrates
* src/who.c (idle_string): Avoid signed integer overflow
if the superuser messes with the clock in bizarre ways.
Remove an ‘assume’ that wasn’t correct under this scenario.
2023-07-01 11:51:16 -07:00
Paul Eggert
c0285a7136 df: omit GCC 5 ‘assume’s
* src/df.c (main):
* src/shred.c (dopass):
Omit ‘assumes’ needed to pacify GCC 5 but not needed with GCC 13.
2023-07-01 11:51:16 -07:00
Paul Eggert
17aaba6a41 maint: pacify GCC bug#109613 better
* src/cut.c (cut_file):
* src/nl.c (nl_file): Pacify GCC Bug#109613 in a better way, by
narrowing the coverage of the ‘assume’ so that bugs in the
no-longer-covered part are not masked.
2023-07-01 11:51:16 -07:00
Paul Eggert
d438486cb5 maint: stop pacifying Parfait
* src/fmt.c (get_paragraph):
* src/stty.c (display_changed, display_all): Omit calls to
‘assume’ that are present only to pacify false positives by Parfait
<https://labs.oracle.com/pls/apex/f?p=94065:12:17236785746387:13>,
which went in-house in 2012 and never came back.
2023-07-01 11:51:16 -07:00
Paul Eggert
a44b866b11 build: update gnulib submodule to latest 2023-07-01 11:51:16 -07:00
Paul Eggert
6d61667d0d maint: go back to using ‘error’
Now that Gnulib’s ‘error’ module does proper static checking
for not returning, we need no longer use the ‘die’ macro.
This makes code easier to read for people that are used to ‘error’.
* cfg.mk (error_fns, exclude_file_name_regexp): Remove ‘die’.
(sc_die_EXIT_FAILURE): Remove.
* src/die.h: Remove.  All includes removed.  All calls to ‘die’
changed back to calls to ‘error’.
* src/install.c (get_ids): Use quoteaf (problem found with
make syntax-check).
* src/system.h: Include error.h, since some of our macros call ‘error’.
Stop including error.h elsewhere.
2023-07-01 11:51:16 -07:00
Paul Eggert
478055dc30 maint: improve static and dynamic checking
This modernizes the source code somewhat, to take advantage
of advances in GCC over the years, and Gnulib’s ‘assure’ module.
Include assure.h in files that now need it.
Do not include assert.h directly; it’s no longer needed.
* bootstrap.conf (gnulib_modules): Add ‘assure’.
* gl/lib/randread.c (randread_error):
* src/chmod.c (describe_change):
* src/chown-core.c (describe_change):
* src/cp.c (decode_preserve_arg):
* src/head.c (diagnose_copy_fd_failure):
* src/ls.c (parse_ls_color):
* src/od.c (decode_one_format):
* src/split.c (main):
* src/test.c (binary_operator, posixtest):
Prefer affirm to abort, since it has better diagnostics in the
normal case and better performance with -DNDEBUG.
* gl/lib/xdectoint.c, src/die.h: Include stddef.h, for unreachable.
* gl/lib/xdectoint.c: Do not include verify.h; no longer needed.
* gl/lib/xdectoint.c (__xnumtoint):
* src/die.h (die):
Prefer C23 unreachable () to assume (false).
* gl/lib/xfts.c (xfts_open):
* src/basenc.c (base32hex_encode):
* src/copy.c (abandon_move, copy_internal, valid_options):
* src/cut.c (cut_fields):
* src/df.c (alloc_field, decode_output_arg, get_dev):
* src/du.c (process_file, main):
* src/echo.c (usage):
* src/factor.c (udiv_qrnnd, mod2, gcd2_odd, factor_insert_large)
(mulredc2, factor_using_pollard_rho, isqrt2, div_smallq)
(factor_using_squfof):
* src/iopoll.c (iopoll_internal, fwrite_wait):
* src/join.c (add_field):
* src/ls.c (dev_ino_pop, main, gobble_file, sort_files):
* src/mv.c (do_move):
* src/od.c (decode_format_string, read_block, dump, main):
* src/remove.c (rm):
* src/rm.c (main):
* src/sort.c (stream_open):
* src/split.c (next_file_name, lines_chunk_split):
* src/stdbuf.c (main):
* src/stty.c (set_speed):
* src/tac-pipe.c (line_ptr_decrement, line_ptr_increment):
* src/touch.c (touch):
* src/tr.c (find_bracketed_repeat, get_next)
(validate_case_classes, get_spec_stats, string2_extend, main):
* src/tsort.c (search_item, tsort):
* src/wc.c (main):
Prefer affirm to assert, as it allows for better static
checking when compiling with -DNDEBUG.
* src/chown-core.c (change_file_owner):
* src/df.c (get_field_list):
* src/expr.c (printv, null, tostring, toarith, eval2):
* src/ls.c (time_type_to_statx, calc_req_mask, get_funky_string)
(print_long_format):
* src/numfmt.c (simple_strtod_fatal):
* src/od.c (decode_one_format):
* src/stty.c (mode_type_flag):
* src/tail.c (xlseek):
* src/tr.c (is_char_class_member, get_next, get_spec_stats)
(string2_extend):
Prefer unreachable () to abort () or assert (false) when merely
pacifying the compiler, e.g., in a switch statement on an enum
where all cases are covered.
* src/copy.c (valid_options): Now returns void; the bool was useless.
Caller no longer needs to assert.
* src/csplit.c (find_line):
* src/expand-common.c (next_file):
* src/shred.c (incname):
* src/sort.c (main):
* src/tr.c (append_normal_char, append_range, append_char_class)
(append_repeated_char, append_equiv_class):
* src/tsort.c (search_item):
Omit assert, since the hardware will check for us.
* src/df.c (header_mode): Now the enum type it should have been.
* src/du.c (process_file):
* src/ls.c (assert_matching_dev_ino):
* src/tail.c (valid_file_spec):
* src/tr.c (validate_case_classes):
Mark defns with MAYBE_UNUSED if they’re not used when -DNDEBUG.
* src/factor.c (prime_p, prime2_p, mp_prime_p): Now ATTRIBUTE_PURE.
Prefer affirm to error+abort.  No need to translate this diagnostic.
* src/fmt.c (get_paragraph):
* src/stty.c (display_changed, display_all, sane_mode):
* src/who.c (idle_string):
Prefer assume to assert, since the goal is merely pacification
and assert doesn’t pacify anyway if -DNDEBUG is used.
* src/join.c (decode_field_spec):
Omit unreachable abort.
* src/ls.c (assert_matching_dev_ino, main):
* src/tr.c (get_next):
Prefer assure to assert, since the check is relatively expensive
and won’t help static analysis.
* src/ls.c (main):
Prefer static_assert to assert of a constant expression.
(format_inode): Redo to make it clear that buflen doesn’t matter,
and that buf must have a certain number of bytes.  All callers changed.
This pacifies -Wformat-overflow.
* src/od.c (decode_one_format):
Omit an assert that tested for obviously undefined behavior,
as the compiler could optimize it away anyway.
* src/od.c (decode_one_format, decode_format_string):
Prefer ATTRIBUTE_NONNULL to runtime checking.
* src/stat.c: Do not include <stddef.h> since system.h does that now.
* src/sync.c (sync_arg):
Prefer unreachable () to assert (true), which was a typo.
* src/system.h: Include stddef.h, for unreachable.
* src/tail.c (xlseek): Simplify by relying on ‘error’ to exit.
2023-07-01 11:51:15 -07:00
Paul Eggert
2522c1db68 maint: fix indenting in previous change
* src/ptx.c: Adjust to fit into 80 columns.
2023-07-01 11:51:14 -07:00
Paul Eggert
16b5ca6e0d maint: prefer C23-style nullptr
* bootstrap.conf (gnulib_modules): Add nullptr.
In code, prefer nullptr to NULL where either will do.
2023-06-29 15:29:29 -07:00
Bruno Haible
e600fbb764 build: ensure that makeinfo ≥ 6.8 checks the @menu structure
See <https://lists.gnu.org/r/bug-texinfo/2023-06/msg00015.html>.

* doc/local.mk (MAKEINFO): New variable.
* cfg.mk (_makefile_at_at_check_exceptions): Update.
2023-06-22 23:22:07 +01:00
Pádraig Brady
e8858f1515 b2sum: fix UAR with --check with malformed checksum lines
* src/digest.c (split_3): Reinstate the check for whitespace after the
digest portion of the line, so that we exit early before inspecting
the file name which would be outside the passed buffer in the case
where the input does not contain a newline.
* tests/cksum/b2sum.sh: Add a test case.
* NEWS: Mention the bug fix.
* THANKS.in: Add Frank Busse who has reported multiple bugs using KLEE.
Fixes https://bugs.gnu.org/64229
2023-06-22 23:22:07 +01:00
Paul Eggert
ed9d8b8730 maint: update GCC bug number in comment 2023-06-21 00:08:21 -07:00
Paul Eggert
3638944ff5 doc: mention fix for bug#64123 2023-06-19 23:24:02 -07:00
Paul Eggert
5ac7f2d281 build: update gnulib submodule to latest 2023-06-19 23:24:02 -07:00
Sylvestre Ledru
15925d0e5b tests: move tests to a directory per utility
* cfg.mk: Adjust syntax check exclusion paths.
* tests/local.mk: Adjust for renamed tests.
2023-06-19 13:12:37 +01:00
Pádraig Brady
d53190ed46 doc: mention cksum error fix with cpu feature checks changes
* NEWS: Mention the error message to aid those searching
for solutions to the issue, and mention cksum also
as that was confirmed to fix the error with the adjusted
cpu feature detection, as discussed at https://bugs.debian.org/1037264
* src/cksum.c: Cleanup syntax-check failure from previous commit.
2023-06-15 01:00:05 +01:00
Paul Eggert
f780a85985 cksum,wc: clean up hw capability checking
* src/cksum.c (cksum_pclmul) [!CRCTAB && !USE_PCLMUL_CRC32]:
Remove macro.
(cksum_fp): No longer file-scope.
(pclmul_supported): Define only if USE_PCLMUL_CRC32.
This omits the debug output "using generic hardware support"
for simplicity and consistency with wc’s output.
(crc_sum_stream) [!USE_PCLMUL_32]: No need for static function pointer.
* src/wc.c (wc_lines_p) [USE_AVX2_WC_LINECOUNT]: No longer file-scope.
(wc) [USE_AVX2_WC_LINECOUNT]: Check for avx2 support at most once,
which was surely the code’s original intent.
(wc) [!USE_AVX2_WC_LINECOUNT]: No need for static function pointer.
2023-06-14 14:54:46 -07:00
Paul Eggert
4ac941565f cksum,wc: don’t include <cpuid.h>
* src/cksum.c [!CRCTAB && USE_PCLMUL_CRC32]:
* src/wc.c [USE_AVX2_WC_LINECOUNT]:
Don’t include <cpuid.h>; no longer needed.
2023-06-14 14:54:46 -07:00
Paul Eggert
7814596fa9 cksum: fix bug in check for cksum_pclmul
This fixes a typo in the previous patch.
Problem reported by Pádraig Brady <https://bugs.gnu.org/64058#11>.
* src/cksum.c (pclmul_supported): Also require AVX support
to use cksum_pclmul.
2023-06-14 14:54:46 -07:00
Paul Eggert
91a74d3614 wc: port to kernels that disable XSAVE YMM
Problem reported by Dave Hansen <https://bugs.gnu.org/64058>.
Apply similar change to cksum and pclmul, too.
* NEWS: Mention wc fix.
* configure.ac (cpuid_exists, get_cpuid_count_exists):
Remove.  All uses removed, since we no longer use __get_cpuid or
__get_cpuid_count.
(pclmul_intrinsic_exists, avx2_intrinsic_exists): Set to no if
__builtin_cpu_supports calls cannot be compiled.
(HAVE_PCLMUL_INTRINSIC, HAVE_AVX2_INTRINSIC): Remove; unused.
Simplify surrounding code because of this.
* src/cksum.c (pclmul_supported):
* src/wc.c (avx2_supported):
Use __builtin_cpu_supports instead of doing it by hand.
Simplify surrounding code because of this.
2023-06-13 21:14:29 -07:00
Ville Skyttä
3789024073 dircolors: update list of backup file extensions
* src/dircolors.hin: Sort backup section by extension.
Treat .dpkg-new and .dpkg-tmp as backup files.
Treat .crdownload (Chromium based browsers' partial download)
as a backup file.
2023-06-12 21:55:51 +01:00
Pádraig Brady
e8e81fc44b dd: fix parsing of numbers with more than two multipliers
* src/dd.c (parse_integer): Use recursion to support more than two
multipliers.  Also protect suffix[-1] access to ensure we don't
inspect before the passed string.
* tests/dd/bytes.sh: Add test cases.
* doc/coreutils.texi (dd invocation): Note the support for specifying
many multipliers in a number.
* NEWS: Mention the bug fix.
Fixes https://bugs.debian.org/1037275
2023-06-11 23:10:34 +01:00
Pádraig Brady
b841f111de build: update gnulib submodule to latest
* gnulib: Update to latest.
* po/POTFILES.in: Remove recent sc_po_check workaround.
* tests/misc/date-debug.sh: Adjust as per spelling fix.
2023-06-09 11:27:35 +01:00
Pádraig Brady
66ea09b0fe doc: od --strings: clarify operation
* doc/coreutils.texi (od invocation): Remove mention of ASCII,
as all printable characters in unibyte locales are output.
* src/od.c (usage): Clarify that only NUL terminated strings
are displayed, and that it's printable chars, not only graphic chars
that are output. I.e., spaces are output also if part of the string.
Reported at https://bugs.ddebian.org/1037217
2023-06-08 11:06:20 +01:00
Pádraig Brady
c2173c0a52 maint: ls.c: update stale comment for previous commit
* src/ls.c (gobble_file): Update comment to correspond with
the changes in the previous commit.
2023-06-07 21:51:47 +01:00
Pádraig Brady
bf574deec8 ls: display command line symlinks that return ELOOP
* src/ls.c (gobble_file): Ensure we lstat() a symlink
specified on the command line, if we receive ELOOP from stat().
* tests/ls/symlink-loop.sh: Add a new test.
* tests/local.mk: Reference the new test.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/63931
2023-06-07 19:59:40 +01:00
Pádraig Brady
e1e21f6dff ls: use more standard symlink traversal
* src/ls.c (gobble_file): stat() symlinks directly,
rather than their targets.  This will be more consistent
with how symlinks are generally accessed.
(make_link_name): Remove no longer used function.
Addresses https://bugs.gnu.org/63931
2023-06-07 19:59:30 +01:00
Pádraig Brady
6c975de166 doc: reference COPYING from README
* README: Reference COPYING as per the GNU coding standards,
and soon to be enforced with a syntax-check from gnulib.
2023-06-07 16:05:15 +01:00
Pádraig Brady
6a61883757 maint: avoid syntax-check failure
* po/POTFILES.in: Add lib/propername.h due to new comments
that trigger sc_po_check.
2023-06-06 11:34:09 +01:00
Pádraig Brady
3621d51c9d doc: NEWS: mention the more defensive copy_file_range avoidance
* NEWS: Mention the improvement in reinstating runtime avoidance
of copy_file_range(), that came with the last gnulib update,
picking up gnulib commit fb034b35.
2023-06-06 11:16:39 +01:00
Paul Eggert
e8909df3ce build: update gnulib submodule to latest 2023-06-05 22:44:22 -07:00
Pádraig Brady
4d12f4df0c maint: use consistent make variable interpolation syntax
* cfg.mk: Prefer $() interpolation over ${}
lest the reader is confused as to whether shell interpolation,
i.e. $${} was intended.
2023-06-01 13:21:12 +01:00
Pádraig Brady
0147288d20 split: --additional-suffix: disallow trailing '/'
Note mktemp --suffix has the same inconsistency,
but mktemp -d does support creating dirs
so probably best to leave that as is.

* src/split.c (main): Check for trailing /.
* tests/split/additional-suffix.sh: Augment the test.
Reported in https://bugs.debian.org/1036827
2023-05-31 17:26:13 +01:00
Pádraig Brady
d055228e34 maint: adjust code to handle "error" syntax-check changes
* src/dd.c: Don't include no longer used error.h.
Use quoteaf() rather than quote() to quote appropriate for the shell
and to avoid the syntax-check failure,
* src/stty.c: Use quoteaf() rather than quotef()
to have more consistent quoting of the invalid arg.
2023-05-31 17:24:13 +01:00
Pádraig Brady
b7c8eb0046 maint: augment syntax checks to cater for more "error" functions
src/cfg.mk (sc_error_quotes, sc_error_shell_quotes,
sc_error_shell_always_quotes): Include "die" and "diagnose"
in the class of error functions to check arguments for.
2023-05-31 17:20:09 +01:00
Paul Eggert
48f5a39872 dd: fix ‘error’ name issue without macros
* src/dd.c (_GL_NO_INLINE_ERROR): Remove; no longer needed.
(diagnose): Rename from nl_error and omit first arg since it is
always zero.  All uses changed.
(error): Remove macro.
2023-05-30 14:25:03 -07:00
Pádraig Brady
fe18d3982a build: update gnulib submodule to latest
* gnulib: Update to latest.
* src/dd.c: Avoid error macro redefinition.
2023-05-28 15:03:00 +01:00
Pádraig Brady
17479ef60c build: modernize bootstrap prerequsite tools
Following on from commit v9.0-15-gaa31b919c
which updated README-prereq...

* bootstrap.conf: Add an explicit requirement on m4.
Add an explicit requirement on texi2pdf which is often
packaged separately to makeinfo and induces a failure
far down the distribution phase if not present.
Replace the rsync dependency with wget,
which gnulib changed to in 2018.
2023-05-19 22:20:07 +01:00
Pádraig Brady
d5d9b67eec build: update gnulib submodule to latest
* gnulib: Update to latest.
* configure.ac: Remove gnulib reference, as that specific issue
is now explicitly avoided in gnulib itself.
2023-05-19 18:40:53 +01:00
Pádraig Brady
76e1200eeb build: pacify GCC 13 with -flto
* src/cut.c (cut_file): Explicitly mark STREAM as nonnull to avoid
-Werror=null-dereference.
* src/nl.c (nl_file): Likewise.
2023-05-19 11:32:14 +01:00
Pádraig Brady
ba0527d4ca build: revert -Wmaybe-uninitialized warnings avoidance
This reverts commit 800c86d5, as that was deemed too invasive.
We do keep the change to tee.c to allow using -O3 without warnings.
For other optimization options like -O0, -Og, -O1, -Os,
one can use WERROR_CFLAGS= to stop warnings inducing a build failure.
2023-05-19 09:58:50 +01:00
Pádraig Brady
800c86d5fa build: avoid false -Wmaybe-uninitialized warnings
Allow easily building a debug build for example with:
  make CFLAGS='-O0 -ggdb'

False -Wmaybe-uninitialized warnings hit in different
places depending on the compiler passes used.
These changes were tested with gcc 10.2.1, 12.2.1, and 13.1.1 like:
  for o in g s z fast 0 1 2 3; do
    make clean && make -j$(nproc) CFLAGS="-O$o" || break
  done

* src/digest.c: Disable -Wmaybe-uninitialized that gives
false positive here at -O0.
* src/ln.c: Avoid -Wmaybe-uninitialized that gives
false positive here at -O1.
* src/pr.c: Likewise.
* src/sort.c: Likewise.
* src/tee.c: Avoid -Wmaybe-uninitialized that gives
false positive here at -O3 on gcc 13.1.1 at least.
* src/cp.c: Avoid -Wmaybe-uninitialized that gives
false positive here at -Os on gcc 13.1.1 at least.
* src/copy.c: Avoid -Wmaybe-uninitialized that gives
false positive here at -Og on gcc 13.1.1 at least.
* src/head.c: Likewise.
* src/paste.c: Likewise.
2023-05-18 12:13:47 +01:00
Pádraig Brady
aed3b8190a build: gnulib: avoid false -Wstringop-overflow warning
Tested on gcc 13.1.1 with: make CFLAGS='-O0 -ggdb'

* configure.ac: Disable -Wstringop-overflow for gnulib.
This warning is far too problematic in my experience:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443
and triggers with gcc -O0 with versions 12,13 at least.
2023-05-18 11:57:26 +01:00
Pádraig Brady
f218412b9a maint: cleanups to NEWS
* NEWS: Use more consistent wording, ordering, and formatting
for recent entries.
2023-05-13 10:33:14 +01:00
Pádraig Brady
059e53e5b4 split: advise the kernel of sequential access pattern
As split is often dealing with large files,
ensure we indicate to the kernel our sequential access pattern.
This was seen to operate 5% faster when reading from SSD,
as tested with:

dd bs=1M count=2K if=/dev/urandom of=big.in

for split in split.orig split; do
  # Ensure big file is not cached
  dd of=big.in oflag=nocache conv=notrunc,fdatasync count=0 status=none
  # Test read efficiency
  CWD=$PWD; (cd /dev/shm && time $CWD/src/$split -n2 $CWD/big.in)
done

real    0m9.039s
user    0m0.055s
sys     0m3.510s

real    0m8.568s
user    0m0.056s
sys     0m3.752s

* src/split.c (main): Use fdadvise to help the kernel
choose a more appropriate readahead buffer.
* NEWS: Mention the improvement.
2023-05-08 21:34:58 +01:00
Pádraig Brady
ba128e628c doc: adjust build instructions for disabling year 2038 support
* README-install: Adjust the instructions as per recent gnulib updates.
2023-05-08 12:57:56 +01:00
Bernhard Voelker
3f942cd03f build: update gnulib submodule to latest
This fixes failures in "very-expensive" tests on FTS with many
directory entries:
  FAIL: tests/rm/ext3-perf
  FAIL: tests/rm/many-dir-entries-vs-OOM

The following shows the problem in the former of the above tests:
  $ mkdir d && seq 400000 | env -C d xargs touch )
  $ rm -rf d
  rm: traversal failed: d: Operation not supported

Gnulib commit 3f0950f65abb (2023-04-26) introduced this regression
which was fixed again with gnulib commit d4d8abb39eb0.

See discussion in
<https://lists.gnu.org/r/bug-gnulib/2023-05/msg00040.html>

* bootstrap.conf (gnulib_modules): Change "year2038-required" to
"year2038-recommended"; the module has been replaced.
* gnulib: Update to latest.
* tests/init.sh: Likewise.
2023-05-07 23:07:12 +02:00
Paul Eggert
42f33ae68c doc: time zone conversion example
* doc/coreutils.texi (Examples of date):
Give time zone conversion example.
2023-05-07 09:17:27 -07:00
Paul Eggert
7edec89fc3 doc: new subsection for date format specs
* doc/coreutils.texi (Date format specifiers): New subsection,
which groups the date format specifiers without otherwise
changing contents.
2023-05-07 09:17:26 -07:00
Pádraig Brady
fae65623a9 pr: fix parsing of empty arguments
Before:
  $ pr --expand-tabs=
  pr: '-e' extra characters or invalid number in the argument:
   ‘SHELL=/bin/bash’: Value too large for defined data type

After:
  $ pr --expand-tabs=
  pr: '-e': Invalid argument: ‘’

* src/pr.c (getoptarg): Ensure we don't parse beyond the
end of an empty argument, thus outputting arbitrary stack
info in subsequent error messages.

Addresses https://bugs.debian.org/1035596
2023-05-06 11:26:04 +01:00
Paul Eggert
300af78691 cp: -p --parents: minor cleanup of previous patch
This doesn’t change behavior; it just clarifies the code a bit.
* src/cp.c (re_protect): New arg DST_SRC_NAME, for clarity, and so
that we need to skip '/'s only once.  Caller changed.
Rename a couple of local variables to try to make things clearer.
2023-05-05 11:05:03 -07:00
Pádraig Brady
c6b1fe4347 cp: -p --parents: fix failure to preserve permissions for absolute paths
* src/cp.c (re_protect): Ensure copy_acl() is passed an absolute path.
* tests/cp/cp-parents.sh: Add a test case.
* NEWS: Mention the bug.
Fixes https://bugs.gnu.org/63245
2023-05-03 18:15:59 +01:00
Pádraig Brady
7223651ad1 tests: provide more info on DEBUG=yes
* README: State that DEBUG=yes is particularly useful with perl tests.
* tests/split/l-chunk.sh: Use the more standard $DEBUG variable
rather than an internal $DEBUGGING variable.
2023-05-02 22:39:03 +01:00
Pádraig Brady
6d683a1d02 doc: provide more info on the default 32-bit cksum digest
* doc/coreutils.texi (cksum invocation): Say that the default
digest format is 32-bit and based on the Ethernet standard CRC.
2023-04-30 22:10:25 +01:00
Pádraig Brady
2cae0419c9 maint: remove redundant exit status handling
* src/numfmt.c: Remove redundant / confusing
use of TIMEOUT_FAILURE.
2023-04-30 13:05:12 +01:00
Paul Eggert
35adc746a0 maint: simplify --enable-gcc-warnings='expensive'
* configure.ac (WERROR_CFLAGS): Omit mention of
-Wno-analyzer-double-free, -Wno-analyzer-null-dereference, and
-Wno-analyzer-use-after-free as manywarnings no longer uses them.
2023-04-26 18:20:20 -07:00
Paul Eggert
21e7573508 maint: suppress GCC 13 false alarms
* src/csplit.c, src/fmt.c, src/make-prime-list.c, src/nohup.c:
Add pragmas to pacify GCC 13 when coreutils is configured
with --enable-gcc-warnings='expensive'.
2023-04-26 18:20:20 -07:00
Paul Eggert
6c199713ed chmod: pacify GCC 13
* src/chmod.c (main): Use xpalloc instead of X2REALLOC,
and make the corresponding variables signed instead of unsigned.
When reallocating the buffer, this grows it by a factor of 1.5, not 2.
This also pacifies gcc -Wanalyzer-null-dereference.
2023-04-26 18:20:19 -07:00
Paul Eggert
d178b49754 csplit: pacify GCC 13
* src/csplit.c (load_buffer): Refactor for clarity.
This also xpacifies gcc -Wanalyzer-use-of-uninitialized-value.
When reallocating the buffer, grow it by a factor of 1.5, not 2.
2023-04-26 18:20:19 -07:00
Paul Eggert
941027eeb7 build: update gnulib submodule to latest 2023-04-26 18:20:19 -07:00
Pádraig Brady
5e1c5f2d71 tests: more cases for read input diagnostics
* tests/misc/read-errors.sh: Exercise more modes of
various utilities for better read error coverage.
* tests/split/fail.sh: Remove part refactored into the above test.
2023-04-26 16:20:50 +01:00
Pádraig Brady
4eb5abbff4 uniq: be more specific when diagnosing read errors
* src/uniq.c (check_file): Use the errno when diagnosing read errors.
2023-04-26 16:19:51 +01:00
Jaroslav Skarvada
b16553cdad build: fix build with -mno-ssse3
Avoid the following error with -mno-ssse3:
 inlining failed in call to 'always_inline' '_mm_shuffle_epi8':
 target specific option mismatch

* configure.ac: Ensure we use ssse3 specific code when
checking whether to enable the pclmul cksum implementation.
2023-04-26 13:51:42 +01:00
Pádraig Brady
3fb0cc80fa pr: fix infinite loop when double spacing
* src/pr.c (init_parameters): Ensure we avoid a 0 lines_per_body
which was possible when adjusting for double spacing.
That caused print_page() to always return true,
causing an infinite loop.
* tests/pr/pr-tests.pl: Add a test case.
* NEWS: Mention the fix.
Fixes https://bugs.debian.org/1034808
2023-04-25 14:18:35 +01:00
Pádraig Brady
cc078f747f copy: reduce verbosity of -i and -u with --verbose
Since skipping of files is central to the operation of -i and -u,
and with -u one may be updating few files out of many,
reinstate the verbosity of this functionality as it was before 9.3.

* src/copy.c (copy_internal): Only output "skipped" message
with --debug.  Also adjust so message never changes with --debug.
* tests/cp/cp-i.sh: Adjust accordingly.
* tests/mv/mv-n.sh: Likewise.
* tests/cp/debug.sh: Add explicit test case for message.
* NEWS: Mention the change in behavior.
2023-04-25 11:17:54 +01:00
Pádraig Brady
7ea7c020e8 tests: ensure all utilities that read input diagnose errors
* tests/misc/read-errors.sh: Add a new test.
* tests/misc/date-f.sh: Remove unneeded test.
* tests/misc/dircolors.sh: Likewise.
* tests/local.mk: Reference new test, and dereference removed ones.
2023-04-24 11:46:28 +01:00
Pádraig Brady
82e1750daa factor: diagnose errors reading the input
* src/factor.c (do_stdin): Exit with failure upon read errors.
* NEWS: Mention the bug fix.
2023-04-24 11:46:28 +01:00
Pádraig Brady
5595673d5c numfmt: diagnose errors reading the input
* src/numfmt.c (main): Exit with failure upon read errors.
* NEWS: Mention the bug fix.
2023-04-24 11:46:28 +01:00
Pádraig Brady
0e62ba282e tsort: diagnose errors reading the input
* src/tsort.c (tsort): Check for errors after readtoken().
* NEWS: Mention the bug fix.
2023-04-24 11:46:28 +01:00
Pádraig Brady
9d333aca43 cksum: fix failure to diagnose read errors with crc32
The default crc32 mode fails to diagnose read errors.

* src/cksum.c (cksum_slice8): Fix the check for read errors.
(cksum_pclmul): Likewise.
* NEWS: Mention the bug fix.
2023-04-24 11:46:28 +01:00
Andreas Schwab
e29f4411c8 tests: avoid failure when cp fails for proc files
When run under QEmu emulation emulated /proc files have
unstable inode numbers.

* tests/cp/proc-short-read.sh: Skip if unstable inode numbers detected.
2023-04-24 11:37:09 +01:00
Pádraig Brady
6bab375973 install: support stripping files with a leading hyphen
* src/install.c (strip): Prepend "./" to file names with a leading "-".
* tests/install/strip-program.sh: Add a test case.
* NEWS: Mention the bug fix.
Reported in https://bugs.debian.org/1034429
2023-04-21 19:13:52 +01:00
Pádraig Brady
f6229adb09 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2023-04-18 15:32:53 +01:00
Pádraig Brady
f386722dc0 version 9.3
* NEWS: Record release date.
2023-04-18 15:08:11 +01:00
Pádraig Brady
d81094dc7b tests: avoid allocation checks on ZFS
* tests/du/basic.sh: Allocation of files was seen to change
asynchronously on ZFS, so avoid allocation comparisons there.
2023-04-16 16:11:20 +01:00
Pádraig Brady
cf91b9d62c tests: tty-eof: fix various issues
* tests/misc/tty-eof.pl: Ensure we don't erroneously
skip commands with parameters.
Comment as to why cut(1) is treated differently.
Adjust expect calls to not wait needlessly for cut output.
2023-04-14 00:02:22 +01:00
Pádraig Brady
daa1e4f557 tests: avoid dependence on file layout for cp sparse check
* tests/cp/sparse-2.sh: Don't depend on the copy taking
<= allocation of the source.  Instead leverage --debug
to check that zero detection is being enabled.
2023-04-13 20:19:18 +01:00
Pádraig Brady
854c90ecc0 copy: --debug: indicate if NUL detection is used with SEEK_HOLE
* src/copy.c (sparse_copy): With --sparse=always we also detect
NULs in extents we're copying, so indicate this with --debug.
2023-04-13 20:19:09 +01:00
Paul Eggert
cc95246ee2 doc: update re 32-bit builds
* README-install: Mention how to build on 32-bit-only hosts.
This builds on a previous patch by Pádraig Brady.
2023-04-10 11:56:43 -07:00
Pádraig Brady
ae4dace2ec build: fix _Noreturn compilation failure
Fix a build failure seen on gcc 3.4 on Solaris 10 at least.

* src/crctab.c: Ensure we include config.h for all compilation units.
This is now required for new _Noreturn usage in gnulib for stdint.h.
* src/cksum.c: Update generation code to ensure config.h included.
* cfg.mk: Remove crctab.c exclusion from the config.h check.
2023-04-10 19:45:14 +01:00
Pádraig Brady
09ded7049b tests: avoid non portable brace expansion
* tests/cp/backup-dir.sh: Avoid non portable brace expansion
which is not supported by FreeBSD or Solaris shells at least.
2023-04-10 18:54:19 +01:00
Paul Eggert
ffd62ab92c maint: require support for post-2038 timestamps
* bootstrap.conf (gnulib_modules): Replace year2038 with
year2038-required.
2023-04-09 19:21:55 -07:00
Paul Eggert
6f91c2eac3 build: update gnulib submodule to latest 2023-04-09 19:21:55 -07:00
Pádraig Brady
ce630dfc7e wc: ensure we update file offset
* src/wc.c (wc): Update the offset when not reading,
and do read if we can't update the offset.
* tests/misc/wc-proc.sh: Add a test case.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/61300
2023-04-08 12:19:40 +01:00
Pádraig Brady
f6c21f6d3a cp,mv: issue "skipped" messages when skipping files
* NEWS: Mention the change in behavior to issue a "not replaced"
error diagnostic with -n, and the "skipped" message with -v.
* src/copy.c (copy_internal): Adjust to output the "skipped" messages
depending on -i, -n, -u.
* tests/cp/cp-i.sh: Adjust accordingly.
* tests/mv/mv-n.sh: Likewise.
2023-04-08 12:11:58 +01:00
Pádraig Brady
db28af406f cp,mv: add --update=none to always skip existing files
Add --update=none which is equivalent to the --no-clobber behavior
from before coreutils 9.2.  I.e. existing files are unconditionally
skipped, and them not being replaced does not affect the exit status.

* src/copy.h [enum Update_type]: A new type to support parameters
to the --update command line option.
[enum Interactive]: Add I_ALWAYS_SKIP.
* src/copy.c: Treat I_ALWAYS_SKIP like I_ALWAYS_NO (-n),
except that we don't fail when skipping.
* src/system.h (emit_update_parameters_note): A new function
to output the description of the new --update parameters.
* src/cp.c (main): Parse --update arguments, ensuring that
-n takes precedence if specified.
(usage): Describe the new option.  Also allude that
-u is related in the -n description.
* src/mv.c: Accept the new --update parameters and
update usage() accordingly.
* doc/coreutils.texi (cp invocation): Describe the new --update
parameters.  Also reference --update from the --no-clobber description.
(mv invocation): Likewise.
* tests/mv/update.sh: Test the new parameters.
* NEWS: Mention the new feature.
Addresses https://bugs.gnu.org/62572
2023-04-08 12:11:50 +01:00
Pádraig Brady
5891d28ede cp: fix --backup with subdirectories
* gnulib: Reference the latest gnulib including the
fix to the backupfile module in commit 94496522.
* tests/cp/backup-dir.sh: Add a test to ensure
we rename appropriately when backing up through subdirs.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/62607
2023-04-04 12:00:11 +01:00
Pádraig Brady
17c31a73f1 tests: tee: avoid false failure due to fifo usage
* tests/misc/tee.sh: Call cleanup_ in all cases to ensure
there are no overlapping interactions on the fifo that
might impact later parts of the test.  This was seen to
cause issue with dash on musl libc.
Addresses https://bugs.gnu.org/62542
2023-03-31 11:58:53 +01:00
Pádraig Brady
5e170ff0b8 tests: adjust csplit VM limit
* tests/misc/csplit-heap.sh: More memory is required to avoid
a false failure on some systems.  Noticed with musl libc
with bash as the shell.  This is confirmed to still easily
trigger with the original memory leak being tested.
Addresses https://bugs.gnu.org/62542
2023-03-31 11:58:53 +01:00
Pádraig Brady
7ad749886c wc: diagnose overflow of total counts
* src/wc.c (wc): Use INT_ADD_WRAPV() to detect overflow.
(main): Upon overflow, saturate the total, print a diagnostic,
and set exit status.
* tests/misc/wc-total.sh: Add a test case, which operates
on BTRFS and 64 bit systems at least.
Reported at https://bugs.debian.org/1027100
2023-03-31 11:58:49 +01:00
Pádraig Brady
a9bd274616 dircolors: diagnose read errors
* NEWS: Mention the fix.
* src/dircolors.c: Fail upon read error from getline().
* tests/misc/dircolors.sh: Add a new test.
* tests/local.mk: Reference the new test.
2023-03-28 14:24:29 +01:00
Pádraig Brady
a4525de1ef tests: add a test case for the previous date fix
* NEWS: Also mention this bug fix.
* tests/misc/date-f.sh: Add a new test.
* tests/local.mk: Reference the new test.
2023-03-28 13:40:43 +01:00
Paul Eggert
9c5e542fd1 date: diagnose -f read errors
* src/date.c (batch_convert): Diagnose read errors, fixing Bug#62497.
2023-03-28 01:53:06 -07:00
Paul Eggert
6272817de0 cp: clarify commentary
* src/copy.c: Make comments a bit clearer.
2023-03-25 13:20:16 -07:00
Pádraig Brady
093a8b4bfa copy: fix --reflink=auto to fallback in more cases
On restricted systems like android or some containers,
FICLONE could return EPERM, EACCES, or ENOTTY,
which would have induced the command to fail to copy
rather than falling back to a more standard copy.

* src/copy.c (is_terminal_failure): A new function refactored
from handle_clone_fail().
(is_CLONENOTSUP): Merge in the handling of EACCES, ENOTTY, EPERM
as they also pertain to determination of whether cloning is supported
if we ever use this function in that context.
(handle_clone_fail): Use is_terminal_failure() in all cases,
so that we assume a terminal failure in less errno cases.
* NEWS: Mention the bug fix.
Addresses https://bugs.gnu.org/62404
2023-03-24 13:12:51 +00:00
Pádraig Brady
55456b95d8 doc: add a NEWS entry for the previous fix
* NEWS: Mention the previous cksum --check fix.
2023-03-24 12:52:13 +00:00
Pádraig Brady
76f2fb6271 cksum: fix reporting of failed checks
This applies to all checksumming utilities,
where we incorrectly report all subsequent files as checking 'OK'
once any file has passed a digest check.
The exit status was not impacted, only the printed status.

* src/digest.c (digest_check): Use the correct state variable
to determine if the _current_ file has passed or not.
* tests/misc/md5sum.pl: Add a test case.
Fixes https://bugs.gnu.org/62403
2023-03-23 12:36:53 +00:00
Nick Alcock
eeabb11eb6 tests: skip some parts of tests/misc/tee.sh if run as root
Similarly to the fix to tests/rmdir/ignore.sh in c0e5f8c59,
tee should not be expected to fail when run with read-only outputs
when run as root.

* tests/misc/tee.sh: Add uid_is_privileged_ guard around test for
read-only outputs.
2023-03-21 16:15:18 +00:00
Pádraig Brady
bdda9adb38 maint: post-release administrivia
* NEWS: Add header line for next release.
* .prev-version: Record previous version.
* cfg.mk (old_NEWS_hash): Auto-update.
2023-03-20 14:08:46 +00:00
407 changed files with 6682 additions and 5830 deletions

View File

@@ -13,7 +13,7 @@ Before reporting a new bug, please check the following resources:
* Coreutils FAQ: https://www.gnu.org/software/coreutils/faq/coreutils-faq.html
* Coreutils Gotchas: https://www.pixelbeat.org/docs/coreutils-gotchas.html
contains a list of some quirks and unexpected behaviour (which are often
contains a list of some quirks and unexpected behavior (which are often
mistaken for bugs).
* Online Manual:

View File

@@ -22,7 +22,7 @@ contributing to the GNU Project, please read
* Coreutils FAQ: https://www.gnu.org/software/coreutils/faq/coreutils-faq.html
* Coreutils Gotchas: https://www.pixelbeat.org/docs/coreutils-gotchas.html
contains a list of some quirks and unexpected behaviour (which are often
contains a list of some quirks and unexpected behavior (which are often
mistaken for bugs).
* Online Manual:

15
.gitignore vendored
View File

@@ -1,16 +1,19 @@
*.I[12]
*.[EIOX]
*.[EIOXao]
*.bak
*.gcda
*.gcno
*.o
*.a
*~
._bootmp
.deps
.gdb-history
.kludge-stamp
.version
/*.patch
/.Tpo
/.am*
/.re-list
/.sc-start-*
/ABOUT-NLS
/ChangeLog
/GNUmakefile
@@ -111,7 +114,12 @@
/lib/sys/
/lib/termios.h
/lib/time.h
/lib/uchar.h
/lib/unicase.h
/lib/unicase/
/lib/unictype
/lib/unictype.h
/lib/uninorm.h
/lib/unistd.h
/lib/unistr
/lib/unistr.h
@@ -200,6 +208,7 @@
/tests/factor/t[0-9][0-9].sh
/tests/t?
/tests/test-suite.log
/tight-scope.mk
ID
Makefile
Makefile.in

View File

@@ -1 +1 @@
9.1
9.3

22
AUTHORS
View File

@@ -2,30 +2,30 @@ Here are the names of the programs in this package,
each followed by the name(s) of its author(s).
arch: David MacKenzie, Karel Zak
b2sum: Padraig Brady, Samuel Neves
b2sum: Pádraig Brady, Samuel Neves
base32: Simon Josefsson
base64: Simon Josefsson
basename: David MacKenzie
basenc: Simon Josefsson, Assaf Gordon
cat: Torbjorn Granlund, Richard M. Stallman
cat: Torbjörn Granlund, Richard M. Stallman
chcon: Russell Coker, Jim Meyering
chgrp: David MacKenzie, Jim Meyering
chmod: David MacKenzie, Jim Meyering
chown: David MacKenzie, Jim Meyering
chroot: Roland McGrath
cksum: Padraig Brady, Q. Frank Xia
cksum: Pádraig Brady, Q. Frank Xia
comm: Richard M. Stallman, David MacKenzie
coreutils: Alex Deymo
cp: Torbjorn Granlund, David MacKenzie, Jim Meyering
cp: Torbjörn Granlund, David MacKenzie, Jim Meyering
csplit: Stuart Kemp, David MacKenzie
cut: David M. Ihnat, David MacKenzie, Jim Meyering
date: David MacKenzie
dd: Paul Rubin, David MacKenzie, Stuart Kemp
df: Torbjorn Granlund, David MacKenzie, Paul Eggert
df: Torbjörn Granlund, David MacKenzie, Paul Eggert
dir: Richard M. Stallman, David MacKenzie
dircolors: H. Peter Anvin
dirname: David MacKenzie, Jim Meyering
du: Torbjorn Granlund, David MacKenzie, Paul Eggert, Jim Meyering
du: Torbjörn Granlund, David MacKenzie, Paul Eggert, Jim Meyering
echo: Brian Fox, Chet Ramey
env: Richard Mlynarik, David MacKenzie, Assaf Gordon
expand: David MacKenzie
@@ -67,7 +67,7 @@ printf: David MacKenzie
ptx: François Pinard
pwd: Jim Meyering
readlink: Dmitry V. Levin
realpath: Padraig Brady
realpath: Pádraig Brady
rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering
rmdir: David MacKenzie
runcon: Russell Coker
@@ -81,9 +81,9 @@ shred: Colin Plumb
shuf: Paul Eggert
sleep: Jim Meyering, Paul Eggert
sort: Mike Haertel, Paul Eggert
split: Torbjorn Granlund, Richard M. Stallman
split: Torbjörn Granlund, Richard M. Stallman
stat: Michael Meskes
stdbuf: Padraig Brady
stdbuf: Pádraig Brady
stty: David MacKenzie
sum: Kayvan Aghaiepour, David MacKenzie
sync: Jim Meyering, Giuseppe Scrivano
@@ -91,11 +91,11 @@ tac: Jay Lepreau, David MacKenzie
tail: Paul Rubin, David MacKenzie, Ian Lance Taylor, Jim Meyering
tee: Mike Parker, Richard M. Stallman, David MacKenzie
test: Kevin Braunsdorf, Matthew Bradburn
timeout: Padraig Brady
timeout: Pádraig Brady
touch: Paul Rubin, Arnold Robbins, Jim Kingdon, David MacKenzie, Randy Smith
tr: Jim Meyering
true: Jim Meyering
truncate: Padraig Brady
truncate: Pádraig Brady
tsort: Mark Kettenis
tty: David MacKenzie
uname: David MacKenzie

17
HACKING
View File

@@ -3,22 +3,21 @@ Coreutils Contribution Guidelines
Prerequisites
=============
You will need the "git" version control tools.
On Fedora-based systems, do "yum install git".
On Debian-based ones install the "git-core" package.
Then run "git --version". If that says it's older than
version 1.4.4, then you'd do well to get a newer version.
You will need the "git" version control tools. On Fedora-based
systems, do "yum install git". On Debian-based ones install the
"git-core" package. Then run "git --version". If that says it's
older than version 1.4.4, then you'd do well to get a newer version.
At worst, just download the latest stable release from
https://git-scm.com/ and build from source.
For details on building the programs in this package, see
the file, README-hacking.
For details on building the programs in this package, see the file,
README-hacking.
Use the latest upstream sources
===============================
Base any changes you make on the latest upstream sources.
You can get a copy of the latest with this command:
Base any changes you make on the latest upstream sources. You can get
a copy of the latest with this command:
git clone https://git.savannah.gnu.org/git/coreutils.git
cd coreutils

View File

@@ -94,7 +94,7 @@ dist-hook: gen-ChangeLog
$(AM_V_at)touch $(distdir)/doc/constants.texi \
$(distdir)/doc/coreutils.info
gen_start_ver = 8.29
gen_start_ver = 8.30
.PHONY: gen-ChangeLog
gen-ChangeLog:
$(AM_V_GEN)if test -d .git; then \

177
NEWS
View File

@@ -1,5 +1,170 @@
GNU coreutils NEWS -*- outline -*-
* Noteworthy changes in release 9.4 (2023-08-29) [stable]
** Bug fixes
On GNU/Linux s390x and alpha, programs like 'cp' and 'ls' no longer
fail on files with inode numbers that do not fit into 32 bits.
[This bug was present in "the beginning".]
'b2sum --check' will no longer read unallocated memory when
presented with malformed checksum lines.
[bug introduced in coreutils-9.2]
'cp --parents' again succeeds when preserving mode for absolute directories.
Previously it would have failed with a "No such file or directory" error.
[bug introduced in coreutils-9.1]
'cp --sparse=never' will avoid copy-on-write (reflinking) and copy offloading,
to ensure no holes present in the destination copy.
[bug introduced in coreutils-9.0]
cksum again diagnoses read errors in its default CRC32 mode.
[bug introduced in coreutils-9.0]
'cksum --check' now ensures filenames with a leading backslash character
are escaped appropriately in the status output.
This also applies to the standalone checksumming utilities.
[bug introduced in coreutils-8.25]
dd again supports more than two multipliers for numbers.
Previously numbers of the form '1024x1024x32' gave "invalid number" errors.
[bug introduced in coreutils-9.1]
factor, numfmt, and tsort now diagnose read errors on the input.
[This bug was present in "the beginning".]
'install --strip' now supports installing to files with a leading hyphen.
Previously such file names would have caused the strip process to fail.
[This bug was present in "the beginning".]
ls now shows symlinks specified on the command line that can't be traversed.
Previously a "Too many levels of symbolic links" diagnostic was given.
[This bug was present in "the beginning".]
pinky, uptime, users, and who no longer misbehave on 32-bit GNU/Linux
platforms like x86 and ARM where time_t was historically 32 bits.
Also see the new --enable-systemd option mentioned below.
[bug introduced in coreutils-9.0]
'pr --length=1 --double-space' no longer enters an infinite loop.
[This bug was present in "the beginning".]
shred again operates on Solaris when built for 64 bits.
Previously it would have exited with a "getrandom: Invalid argument" error.
[bug introduced in coreutils-9.0]
tac now handles short reads on its input. Previously it may have exited
erroneously, especially with large input files with no separators.
[This bug was present in "the beginning".]
'uptime' no longer incorrectly prints "0 users" on OpenBSD,
and is being built again on FreeBSD and Haiku.
[bugs introduced in coreutils-9.2]
'wc -l' and 'cksum' no longer crash with an "Illegal instruction" error
on x86 Linux kernels that disable XSAVE YMM. This was seen on Xen VMs.
[bug introduced in coreutils-9.0]
** Changes in behavior
'cp -v' and 'mv -v' will no longer output a message for each file skipped
due to -i, or -u. Instead they only output this information with --debug.
I.e., 'cp -u -v' etc. will have the same verbosity as before coreutils-9.3.
'cksum -b' no longer prints base64-encoded checksums. Rather that
short option is reserved to better support emulation of the standalone
checksum utilities with cksum.
'mv dir x' now complains differently if x/dir is a nonempty directory.
Previously it said "mv: cannot move 'dir' to 'x/dir': Directory not empty",
where it was unclear whether 'dir' or 'x/dir' was the problem.
Now it says "mv: cannot overwrite 'x/dir': Directory not empty".
Similarly for other renames where the destination must be the problem.
[problem introduced in coreutils-6.0]
** Improvements
cp, mv, and install now avoid copy_file_range on linux kernels before 5.3
irrespective of which kernel version coreutils is built against,
reinstating that behavior from coreutils-9.0.
comm, cut, join, od, and uniq will now exit immediately upon receiving a
write error, which is significant when reading large / unbounded inputs.
split now uses more tuned access patterns for its potentially large input.
This was seen to improve throughput by 5% when reading from SSD.
split now supports a configurable $TMPDIR for handling any temporary files.
tac now falls back to '/tmp' if a configured $TMPDIR is unavailable.
'who -a' now displays the boot time on Alpine Linux, OpenBSD,
Cygwin, Haiku, and some Android distributions
'uptime' now succeeds on some Android distributions, and now counts
VM saved/sleep time on GNU (Linux, Hurd, kFreeBSD), NetBSD, OpenBSD,
Minix, and Cygwin.
On GNU/Linux platforms where utmp-format files have 32-bit timestamps,
pinky, uptime, and who can now work for times after the year 2038,
so long as systemd is installed, you configure with a new, experimental
option --enable-systemd, and you use the programs without file arguments.
(For example, with systemd 'who /var/log/wtmp' does not work because
systemd does not support the equivalent of /var/log/wtmp.)
* Noteworthy changes in release 9.3 (2023-04-18) [stable]
** Bug fixes
cp --reflink=auto (the default), mv, and install
will again fall back to a standard copy in more cases.
Previously copies could fail with permission errors on
more restricted systems like android or containers etc.
[bug introduced in coreutils-9.2]
cp --recursive --backup will again operate correctly.
Previously it may have issued "File exists" errors when
it failed to appropriately rename files being replaced.
[bug introduced in coreutils-9.2]
date --file and dircolors will now diagnose a failure to read a file.
Previously they would have silently ignored the failure.
[This bug was present in "the beginning".]
md5sum --check again correctly prints the status of each file checked.
Previously the status for files was printed as 'OK' once any file had passed.
This also applies to cksum, sha*sum, and b2sum.
[bug introduced in coreutils-9.2]
wc will now diagnose if any total counts have overflowed.
[This bug was present in "the beginning".]
`wc -c` will again correctly update the read offset of inputs.
Previously it deduced the size of inputs while leaving the offset unchanged.
[bug introduced in coreutils-8.27]
Coreutils programs no longer fail for timestamps past the year 2038
on obsolete configurations with 32-bit signed time_t, because the
build procedure now rejects these configurations.
[This bug was present in "the beginning".]
** Changes in behavior
'cp -n' and 'mv -n' now issue an error diagnostic if skipping a file,
to correspond with -n inducing a nonzero exit status as of coreutils 9.2.
Similarly 'cp -v' and 'mv -v' will output a message for each file skipped
due to -n, -i, or -u.
** New features
cp and mv now support --update=none to always skip existing files
in the destination, while not affecting the exit status.
This is equivalent to the --no-clobber behavior from before v9.2.
* Noteworthy changes in release 9.2 (2023-03-20) [stable]
** Bug fixes
@@ -251,7 +416,7 @@ GNU coreutils NEWS -*- outline -*-
though they still work.
ls no longer colors files with capabilities by default, as file-based
capabilties are very rarely used, and lookup increases processing per file by
capabilities are rarely used, and lookup increases processing per file by
about 30%. It's best to use getcap [-r] to identify files with capabilities.
ls no longer tries to automount files, reverting to the behavior
@@ -342,7 +507,7 @@ GNU coreutils NEWS -*- outline -*-
expr no longer mishandles unmatched \(...\) in regular expressions.
[bug introduced in coreutils-6.0]
ls no longer crashes when printing the SELinux context for unstatable files.
ls no longer crashes when printing the SELinux context for unstattable files.
[bug introduced in coreutils-6.9.91]
mkdir -m no longer mishandles modes more generous than the umask.
@@ -921,7 +1086,7 @@ GNU coreutils NEWS -*- outline -*-
** Bug fixes
cp --parents will now set an SELinux context for created directories,
as appropriate for the -a, --preseve=context, or -Z options.
as appropriate for the -a, --preserve=context, or -Z options.
[bug present since SELinux support added in coreutils-6.10]
date again converts from a specified time zone. Previously output was
@@ -1558,7 +1723,7 @@ GNU coreutils NEWS -*- outline -*-
** Bug fixes
df now processes the mount list correctly in the presence of unstatable
df now processes the mount list correctly in the presence of unstattable
mount points. Previously it may have failed to output some mount points.
[bug introduced in coreutils-8.21]
@@ -2811,7 +2976,7 @@ GNU coreutils NEWS -*- outline -*-
ls --color now handles files with capabilities correctly. Previously
files with capabilities were often not colored, and also sometimes, files
without capabilites were colored in error. [bug introduced in coreutils-7.0]
without capabilities were colored in error. [bug introduced in coreutils-7.0]
md5sum now prints checksums atomically so that concurrent
processes will not intersperse their output.
@@ -2960,7 +3125,7 @@ GNU coreutils NEWS -*- outline -*-
avoid the disproportionate quadratic performance penalty. Leading to
another improvement:
rm -r is now slightly more standards-conformant when operating on
rm -r is now slightly more standard-conforming when operating on
write-protected files with relative names longer than 8KiB.

5
README
View File

@@ -96,8 +96,8 @@ run this command:
make check TESTS=tests/df/df-P.sh VERBOSE=yes SUBDIRS=. >> log 2>&1
For some tests, you can get even more detail by adding DEBUG=yes.
Then include the contents of the file 'log' in your bug report.
For some tests, particularly perl tests, you can get even more detail by adding
DEBUG=yes. Then include the contents of the file 'log' in your bug report.
***************************************
@@ -127,6 +127,7 @@ https://www.gnu.org/prep/standards/
For any copyright year range specified as YYYY-ZZZZ in this package
note that the range specifies every single year in that closed interval.
Please see the file COPYING for copying conditions.
========================================================================

View File

@@ -54,13 +54,13 @@ all mention of "[$(EXEEXT)" from src/Makefile.
32 bit time_t build failures
------------------------
On systems where it's determined that 64 bit time_t is supported
(indicated by touch -t <some time after 2038>), but that coreutils
would be built with a narrower time_t, the build will fail.
This can be allowed by passing TIME_T_32_BIT_OK=yes to configure,
or avoided by enabling 64 bit builds. For example GCC on AIX defaults
to 32 bit, and to enable the 64 bit ABI one can use:
./configure CFLAGS=-maix64 LDFLAGs=-maix64 AR='ar -X64'
Although 32-bit builds fail if that forces time_t to be 32 bits, this
can be fixed by using 64-bit builds. For example, on AIX where GCC
defaults to 32 bits, one can use "./configure CC='gcc -maix64' AR='ar
-X64'"; similarly, on Solaris one can configure with CC='gcc -m64'.
If all else fails one can configure with --disable-year2038;
however, this will mishandle timestamps after 2038, and please file
bug reports for any such situations.
*************************************************

View File

@@ -41,7 +41,7 @@ _path='export PATH='$srcdir':${PATH#*:}'
pre='#!/bin/sh\n'"$_path"'\n'
n=15 # stack trace depth
log_fd=3 # One can redirect this to file like 3>vg.log
test -e /tmp/cu-vg && suppressions='--supressions=/tmp/cu-vg'
test -e /tmp/cu-vg && suppressions='--suppressions=/tmp/cu-vg'
vg="exec /usr/bin/valgrind $suppressions --log-fd=$log_fd \
--leak-check=yes --track-fds=yes --leak-check=full --num-callers=$n"
cat <<EOF > src/vg/gen

View File

@@ -211,6 +211,7 @@ Francesco Montorsi fr_m@hotmail.com
François Pinard pinard@iro.umontreal.ca
François Rigault rigault.francois@gmail.com
Frank Adler fadler@allesklar.de
Frank Busse f.busse@imperial.ac.uk
Frank T Lofaro ftlofaro@snooks.Egr.UNLV.EDU
Fred Fish fnf@ninemoons.com
Frédéric L. W. Meunier 0@pervalidus.net
@@ -634,7 +635,7 @@ Tony Leneis tony@plaza.ds.adp.com
Tony Robinson ajr@eng.cam.ac.uk
Toomas Soome Toomas.Soome@Elion.ee
Toralf Förster toralf.foerster@gmx.de
Torbjorn Lindgren tl@funcom.no
Torbjörn Lindgren tl@funcom.no
Torsten Landschoff torsten@pclab.ifg.uni-kiel.de
Travis Gummels tgummels@redhat.com
Tristan Miller psychonaut@nothingisreal.com

1881
bootstrap

File diff suppressed because it is too large Load Diff

View File

@@ -36,6 +36,7 @@ gnulib_modules="
argv-iter
assert
assert-h
assure
attribute
autobuild
backupfile
@@ -103,6 +104,7 @@ gnulib_modules="
fnmatch-gnu
fopen-safer
fprintftime
fpurge
free-posix
freopen
freopen-safer
@@ -188,6 +190,7 @@ gnulib_modules="
mkostemp
mkstemp
mktime
nullptr
modechange
mountlist
mpsort
@@ -209,7 +212,7 @@ gnulib_modules="
posixver
priv-set
progname
propername
propername-lite
pthread-cond
pthread-mutex
pthread-thread
@@ -251,6 +254,7 @@ gnulib_modules="
stat-size
stat-time
stdbool
stdckdint
stdlib-safer
stpcpy
stpncpy
@@ -271,7 +275,7 @@ gnulib_modules="
time_rz
timer-time
timespec
tmpfile
tmpdir
tzset
uname
unicodeio
@@ -282,7 +286,6 @@ gnulib_modules="
unlocked-io
unsetenv
update-copyright
uptime
useless-if-before-free
userspec
utimecmp
@@ -318,7 +321,7 @@ gnulib_modules="
xstrtol-error
xstrtold
xstrtoumax
year2038
year2038-recommended
yesno
"
@@ -347,7 +350,7 @@ see_manual='"This is a proper name. See the gettext manual, section Names."'
see_manual=\'"$see_manual"\'
XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
--keyword=proper_name:1,'"$see_manual"'\\\
--keyword=proper_name_utf8:1,'"$see_manual"'\\\
--keyword=proper_name_lite:1,'"$see_manual"'\\\
'
gnulib_tool_option_extras="--tests-base=gnulib-tests --with-tests --symlink\
@@ -364,11 +367,13 @@ gettext 0.19.2
git 1.4.4
gperf -
gzip -
m4 -
makeinfo 6.1
texi2pdf 6.1
patch -
perl 5.5
rsync -
tar -
wget -
xz -
"

View File

@@ -33,7 +33,6 @@ build_if_possible_progs='
stdbuf
stty
timeout
uptime
users
who
'
@@ -132,6 +131,7 @@ normal_progs='
unexpand
uniq
unlink
uptime
vdir
wc
whoami

85
cfg.mk
View File

@@ -26,7 +26,6 @@ VC_LIST_ALWAYS_EXCLUDE_REGEX = src/blake2/.*$$
# Tests not to run as part of "make distcheck".
local-checks-to-skip = \
sc_proper_name_utf8_requires_ICONV \
sc_indent
# Tools used to bootstrap this package, used for "announcement".
@@ -49,10 +48,11 @@ export VERBOSE = yes
# 4914152 9e
export XZ_OPT = -8e
old_NEWS_hash = ffba6793067438bae569f42acb4c5ab9
old_NEWS_hash = c550e6659b8350f62d9cd0483bf0c199
# Add an exemption for sc_makefile_at_at_check.
_makefile_at_at_check_exceptions = ' && !/^cu_install_prog/ && !/dynamic-dep/'
_makefile_at_at_check_exceptions = \
' && !/MAKEINFO/ && !/^cu_install_prog/ && !/dynamic-dep/'
# Our help-version script is in a slightly different location.
_hv_file ?= $(srcdir)/tests/misc/help-version
@@ -189,12 +189,15 @@ sc_prohibit_quotes_notation:
exit 1; } \
|| :
error_fns = (error|diagnose)
# Files in src/ should quote all strings in error() output, so that
# unexpected input chars like \r etc. don't corrupt the error.
# In edge cases this can be avoided by putting the format string
# on a separate line to the arguments, or the arguments in parenthesis.
sc_error_quotes:
@cd $(srcdir)/src && GIT_PAGER= git grep -n 'error *(.*%s.*, [^(]*);$$'\
@cd $(srcdir)/src \
&& GIT_PAGER= git grep -E -n '$(error_fns) *\(.*%s.*, [^(]*\);$$' \
*.c | grep -v ', q' \
&& { echo '$(ME): '"Use quote() for error string arguments" 1>&2; \
exit 1; } \
@@ -206,7 +209,7 @@ sc_error_quotes:
sc_error_shell_quotes:
@cd $(srcdir)/src && \
{ GIT_PAGER= git grep -E \
'error \(.*%s[:"], .*(name|file)[^"]*\);$$' *.c; \
'$(error_fns) \(.*%s[:"], .*(name|file)[^"]*\);$$' *.c; \
GIT_PAGER= git grep -E \
' quote[ _].*file' *.c; } \
| grep -Ev '(quotef|q[^ ]*name)' \
@@ -220,27 +223,17 @@ sc_error_shell_quotes:
# to provide better support for copy and paste.
sc_error_shell_always_quotes:
@cd $(srcdir)/src && GIT_PAGER= git grep -E \
'error \(.*[^:] %s[ "].*, .*(name|file)[^"]*\);$$' \
'$(error_fns) \(.*[^:] %s[ "].*, .*(name|file)[^"]*\);$$' \
*.c | grep -Ev '(quoteaf|q[^ ]*name)' \
&& { echo '$(ME): '"Use quoteaf() for space delimited names" 1>&2; \
exit 1; } \
|| :
@cd $(srcdir)/src && GIT_PAGER= git grep -E -A1 \
'error \([^%]*[^:] %s[ "]' *.c | grep 'quotef' \
'$(error_fns) \([^%]*[^:] %s[ "]' *.c | grep 'quotef' \
&& { echo '$(ME): '"Use quoteaf() for space delimited names" 1>&2; \
exit 1; } \
|| :
# Usage of error() with an exit constant, should instead use die(),
# as that avoids warnings and may generate better code, due to being apparent
# to the compiler that it doesn't return.
sc_die_EXIT_FAILURE:
@cd $(srcdir)/src && GIT_PAGER= git grep -E \
'error \([^?]*EXIT_' \
&& { echo '$(ME): '"Use die() instead of error" 1>&2; \
exit 1; } \
|| :
# Avoid unstyled quoting to internal slots and thus destined for diagnostics
# as that can leak unescaped control characters to the output, when using
# the default "literal" quoting style.
@@ -295,27 +288,6 @@ sc_check-AUTHORS: $(all_programs)
&& diff $(au_actual) $(au_dotdot) \
&& rm -f $(au_actual) $(au_dotdot)
# Each program with a non-ASCII author name must link with LIBICONV.
sc_check-I18N-AUTHORS:
@cd $(srcdir)/src && \
for i in $$(git grep -l -w proper_name_utf8 *.c|sed 's/\.c//'); do \
grep -E "^src_$${i}_LDADD"' .?= .*\$$\(LIBICONV\)' local.mk \
> /dev/null \
|| { echo "$(ME): link rules for $$i do not include" \
'$$(LIBICONV)' 1>&2; exit 1; }; \
done
# Disallow the C99 printf size specifiers %z and %j as they're not portable.
# The gnulib printf replacement does support them, however the printf
# replacement is not currently explicitly depended on by the gnulib error()
# module for example. Also we use fprintf() in a few places to output simple
# formats but don't use the gnulib module as it is seen as overkill at present.
# We'd have to adjust the above gnulib items before disabling this.
sc_prohibit-c99-printf-format:
@cd $(srcdir)/src && GIT_PAGER= git grep -n '%[0*]*[jz][udx]' *.c \
&& { echo '$(ME): Use PRI*MAX instead of %j or %z' 1>&2; exit 1; } \
|| :
# Ensure the alternative __attribute (keyword) form isn't used as
# that form is not elided where required. Also ensure that we don't
# directly use attributes already defined by gnulib.
@@ -343,7 +315,7 @@ FILTER_LONG_LINES = \
\|^[^:]*NEWS:.*https\{,1\}://| d; \
\|^[^:]*doc/fdl.texi:| d; \
\|^[^:]*man/help2man:| d; \
\|^[^:]*tests/misc/sha[0-9]*sum.*\.pl[-:]| d; \
\|^[^:]*tests/cksum/sha[0-9]*sum.*\.pl[-:]| d; \
\|^[^:]*tests/pr/|{ \|^[^:]*tests/pr/pr-tests:| !d; };
sc_long_lines:
@wc -L /dev/null >/dev/null 2>/dev/null \
@@ -509,6 +481,18 @@ sc_prohibit_man_see_also_period:
{ echo '$(ME): do not end "SEE ALSO" section with a period' \
1>&2; exit 1; } || :
sc_prohibit_exit_write_error:
@prohibit='error.*EXIT_FAILURE.*write error' \
in_vc_files='\.c$$' \
halt='Use write_error() instead' \
$(_sc_search_regexp)
sc_prohibit_NULL:
@prohibit='$(begword)NULL$(endword)' \
in_vc_files='\.[ch]$$' \
halt='use nullptr instead' \
$(_sc_search_regexp)
# Don't use "indent-tabs-mode: nil" anymore. No longer needed.
sc_prohibit_emacs__indent_tabs_mode__setting:
@prohibit='^( *[*#] *)?indent-tabs-mode:' \
@@ -561,7 +545,7 @@ sc_prohibit_short_facl_mode_spec:
# Ensure that "stdio--.h" is used where appropriate.
sc_require_stdio_safer:
@if $(VC_LIST_EXCEPT) | grep -l '\.[ch]$$' > /dev/null; then \
files=$$(grep -l '$(begword)freopen \?(' $$($(VC_LIST_EXCEPT) \
files=$$(grep -El '$(begword)freopen ?\(' $$($(VC_LIST_EXCEPT)\
| grep '\.[ch]$$')); \
test -n "$$files" && grep -LE 'include "stdio--.h"' $$files \
| grep . && \
@@ -570,6 +554,18 @@ sc_require_stdio_safer:
else :; \
fi
# Ensure that "stdlib--.h" is used where appropriate.
sc_require_stdlib_safer:
@if $(VC_LIST_EXCEPT) | grep -l '\.[ch]$$' > /dev/null; then \
files=$$(grep -El '$(begword)mkstemp ?\(' $$($(VC_LIST_EXCEPT)\
| grep '\.[ch]$$')); \
test -n "$$files" && grep -LE 'include "stdlib--.h"' $$files \
| grep . && \
{ echo '$(ME): the above files should use "stdlib--.h"' \
1>&2; exit 1; } || :; \
else :; \
fi
sc_prohibit_perl_hash_quotes:
@prohibit="\{'[A-Z_]+' *[=}]" \
halt="in Perl code, write \$$hash{KEY}, not \$$hash{'K''EY'}" \
@@ -626,7 +622,8 @@ sc_prohibit_test_empty:
sc_some_programs_must_avoid_exit_failure:
@cd $(srcdir) \
&& grep -nw EXIT_FAILURE \
$$(git grep -El '[^T]_FAILURE|EXIT_CANCELED' $(srcdir)/src) \
$$(git grep -El '[^T]_FAILURE|EXIT_CANCELED' src/) \
| grep -v '^src/system\.h:' \
| grep -vE '= EXIT_FAILURE|return .* \?' | grep . \
&& { echo '$(ME): do not use EXIT_FAILURE in the above' \
1>&2; exit 1; } || :
@@ -842,9 +839,9 @@ exclude_file_name_regexp--sc_bindtextdomain = \
exclude_file_name_regexp--sc_trailing_blank = \
^(tests/pr/|gl/.*\.diff$$|man/help2man)
exclude_file_name_regexp--sc_system_h_headers = \
^src/((die|system|copy|chown-core|find-mount-point)\.h|make-prime-list\.c)$$
^src/((system|copy|chown-core|find-mount-point)\.h|make-prime-list\.c)$$
_src = (crctab|false|lbracket|ls-(dir|ls|vdir)|tac-pipe|uname-(arch|uname))
_src = (false|lbracket|ls-(dir|ls|vdir)|tac-pipe|uname-(arch|uname))
_gl_src = (xdecto.max|cl-strtold)
exclude_file_name_regexp--sc_require_config_h_first = \
(^lib/buffer-lcm\.c|gl/lib/$(_gl_src)\.c|src/$(_src)\.c)$$
@@ -885,7 +882,7 @@ exclude_file_name_regexp--sc_prohibit_stat_st_blocks = \
exclude_file_name_regexp--sc_prohibit_continued_string_alpha_in_column_1 = \
^src/(system\.h|od\.c|printf\.c|getlimits\.c)$$
_cksum = ^tests/misc/cksum-base64\.pl$$
_cksum = ^tests/cksum/cksum-base64\.pl$$
exclude_file_name_regexp--sc_prohibit_test_backticks = \
^tests/(local\.mk|(init|misc/stdbuf|factor/create-test)\.sh)$$|$(_cksum)

View File

@@ -160,8 +160,7 @@ if test $gl_gcc_warnings != no; then
ew=
AS_IF([test $gl_gcc_warnings != expensive],
[# -fanalyzer and related options slow GCC considerably.
ew="$ew -fanalyzer -Wno-analyzer-double-free -Wno-analyzer-malloc-leak"
ew="$ew -Wno-analyzer-null-dereference -Wno-analyzer-use-after-free"])
ew="$ew -fanalyzer -Wno-analyzer-malloc-leak"])
# This, $nw, is the list of warnings we disable.
nw=$ew
@@ -184,7 +183,7 @@ if test $gl_gcc_warnings != no; then
nw="$nw -Wswitch-enum" # Too many warnings for now
nw="$nw -Wswitch-default" # Too many warnings for now
nw="$nw -Wstack-protector" # not worth working around
nw="$nw -Wformat-overflow=2" # False alarms due to GCC bug 80776
nw="$nw -Wformat-overflow=2" # False alarms due to GCC bug 110333
nw="$nw -Wformat-truncation=2" # False alarm in ls.c, probably related
# things I might fix soon:
nw="$nw -Wfloat-equal" # sort.c, seq.c
@@ -262,6 +261,10 @@ if test $gl_gcc_warnings != no; then
# FP in careadlinkat.c w/gcc 10.0.1 20200205
gl_WARN_ADD([-Wno-return-local-addr])
# FIXME: remove this line when gcc improves
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443
gl_WARN_ADD([-Wno-stringop-overflow])
gl_MANYWARN_COMPLEMENT([GNULIB_WARN_CFLAGS], [$WARN_CFLAGS], [$nw])
AC_SUBST([GNULIB_WARN_CFLAGS])
@@ -403,38 +406,6 @@ AC_DEFUN([coreutils_DUMMY_1],
])
coreutils_DUMMY_1
AC_MSG_CHECKING([ut_host in struct utmp])
AC_CACHE_VAL([su_cv_func_ut_host_in_utmp],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <utmp.h>
struct utmp ut;
int s = sizeof ut.ut_host;]])],
[su_cv_func_ut_host_in_utmp=yes],
[su_cv_func_ut_host_in_utmp=no])])
AC_MSG_RESULT([$su_cv_func_ut_host_in_utmp])
if test $su_cv_func_ut_host_in_utmp = yes; then
have_ut_host=1
AC_DEFINE([HAVE_UT_HOST], [1], [FIXME])
fi
if test -z "$have_ut_host"; then
AC_MSG_CHECKING([ut_host in struct utmpx])
AC_CACHE_VAL([su_cv_func_ut_host_in_utmpx],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
#include <utmpx.h>
struct utmpx ut;
int s = sizeof ut.ut_host;]])],
[su_cv_func_ut_host_in_utmpx=yes],
[su_cv_func_ut_host_in_utmpx=no])])
AC_MSG_RESULT([$su_cv_func_ut_host_in_utmpx])
if test $su_cv_func_ut_host_in_utmpx = yes; then
AC_DEFINE([HAVE_UTMPX_H], [1], [FIXME])
AC_DEFINE([HAVE_UT_HOST], [1], [FIXME])
fi
fi
GNULIB_BOOT_TIME([gl_ADD_PROG([optional_bin_progs], [uptime])])
AC_SYS_POSIX_TERMIOS()
gl_HEADER_TIOCGWINSZ_NEEDS_SYS_IOCTL
@@ -545,31 +516,10 @@ CFLAGS=$ac_save_CFLAGS
LDFLAGS=$ac_save_LDFLAGS
ac_c_werror_flag=$cu_save_c_werror_flag
AC_MSG_CHECKING([if __get_cpuid available])
AC_LINK_IFELSE(
[AC_LANG_SOURCE([[
#include <cpuid.h>
int
main (void)
{
unsigned int eax, ebx, ecx, edx;
__get_cpuid (1, &eax, &ebx, &ecx, &edx);
return 1;
}
]])
],[
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_CPUID], [1], [__get_cpuid available])
cpuid_exists=yes
],[
AC_MSG_RESULT([no])
])
ac_save_CFLAGS=$CFLAGS
CFLAGS="-mavx -mpclmul $CFLAGS"
AC_MSG_CHECKING([if pclmul intrinsic exists])
AC_COMPILE_IFELSE(
AC_LINK_IFELSE(
[AC_LANG_SOURCE([[
#include <x86intrin.h>
@@ -578,49 +528,27 @@ AC_COMPILE_IFELSE(
{
__m128i a, b;
a = _mm_clmulepi64_si128 (a, b, 0x00);
return 1;
a = _mm_shuffle_epi8 (a, b);
return __builtin_cpu_supports ("pclmul");
}
]])
],[
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_PCLMUL_INTRINSIC], [1], [pclmul intrinsic exists])
pclmul_intrinsic_exists=yes
],[
AC_MSG_RESULT([no])
pclmul_intrinsic_exists=no
])
if test "x$cpuid_exists" = "xyes" &&
test "x$pclmul_intrinsic_exists" = "xyes"; then
AC_MSG_RESULT([$pclmul_intrinsic_exists])
if test $pclmul_intrinsic_exists = yes; then
AC_DEFINE([USE_PCLMUL_CRC32], [1],
[CRC32 calculation by pclmul hardware instruction enabled])
fi
AM_CONDITIONAL([USE_PCLMUL_CRC32],
[test "x$cpuid_exists" = "xyes" &&
test "x$pclmul_intrinsic_exists" = "xyes"])
[test $pclmul_intrinsic_exists = yes])
CFLAGS=$ac_save_CFLAGS
AC_MSG_CHECKING([if __get_cpuid_count exists])
AC_LINK_IFELSE(
[AC_LANG_SOURCE([[
#include <cpuid.h>
int
main (void)
{
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
__get_cpuid_count (7, 0, &eax, &ebx, &ecx, &edx);
return 1;
}
]])
],[
AC_MSG_RESULT([yes])
get_cpuid_count_exists=yes
],[
AC_MSG_RESULT([no])
])
CFLAGS="-mavx2 $CFLAGS"
AC_MSG_CHECKING([if avx2 intrinstics exists])
AC_COMPILE_IFELSE(
AC_MSG_CHECKING([for avx2 intrinsics])
AC_LINK_IFELSE(
[AC_LANG_SOURCE([[
#include <x86intrin.h>
@@ -629,23 +557,20 @@ AC_COMPILE_IFELSE(
{
__m256i a, b;
a = _mm256_sad_epu8 (a, b);
return 1;
return __builtin_cpu_supports ("avx2");
}
]])
],[
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_AVX2_INTRINSIC], [1], [avx2 intrinsics exists])
avx2_intrinsic_exists=yes
],[
AC_MSG_RESULT([no])
avx2_intrinsic_exists=no
])
if test "x$get_cpuid_count_exists" = "xyes" &&
test "x$avx2_intrinsic_exists" = "xyes"; then
AC_MSG_RESULT([$avx2_intrinsic_exists])
if test $avx2_intrinsic_exists = yes; then
AC_DEFINE([USE_AVX2_WC_LINECOUNT], [1], [Counting lines with AVX2 enabled])
fi
AM_CONDITIONAL([USE_AVX2_WC_LINECOUNT],
[test "x$get_cpuid_count_exists" = "xyes" &&
test "x$avx2_intrinsic_exists" = "xyes"])
[test $avx2_intrinsic_exists = yes])
CFLAGS=$ac_save_CFLAGS

View File

@@ -266,8 +266,8 @@ Summarizing files
* wc invocation:: Print newline, word, and byte counts
* sum invocation:: Print checksum and block counts
* cksum invocation:: Print CRC checksum and byte counts
* b2sum invocation:: Print or check BLAKE2 digests
* md5sum invocation:: Print or check MD5 digests
* b2sum invocation:: Print or check BLAKE2 digests
* sha1sum invocation:: Print or check SHA-1 digests
* sha2 utilities:: Print or check SHA-2 digests
@@ -2058,7 +2058,7 @@ Output at most @var{bytes} bytes of the input. Prefixes and suffixes on
@opindex --strings
@cindex string constants, outputting
Instead of the normal output, output only @dfn{string constants}: at
least @var{bytes} consecutive ASCII graphic characters,
least @var{bytes} consecutive printable characters,
followed by a zero byte (ASCII NUL).
Prefixes and suffixes on @var{bytes} are interpreted as for the
@option{-j} option.
@@ -3090,8 +3090,9 @@ The program accepts the following options. Also see @ref{Common options}.
@opindex -c
@opindex --bytes
Output the last @var{num} bytes, instead of final lines.
However, if @var{num} is prefixed with a @samp{+}, start printing with
byte @var{num} from the start of each file, instead of from the end.
If @var{num} is prefixed with a @samp{+}, start printing with
byte @var{num} from the start of each file. For example to skip the first byte
use @code{tail -c +2}, while to skip all but the last byte use @code{tail -c 1}.
@multiplierSuffixes{num}
@item -f
@@ -3178,8 +3179,9 @@ and when following by name.
@opindex -n
@opindex --lines
Output the last @var{num} lines.
However, if @var{num} is prefixed with a @samp{+}, start printing with
line @var{num} from the start of each file, instead of from the end.
If @var{num} is prefixed with a @samp{+}, start printing with
line @var{num} from the start of each file. For example to skip the first line
use @code{tail -n +2}, while to skip all but the last line use @code{tail -n 1}.
Size multiplier suffixes are the same as with the @option{-c} option.
@item --pid=@var{pid}
@@ -3771,8 +3773,8 @@ contents of files.
* wc invocation:: Print newline, word, and byte counts.
* sum invocation:: Print checksum and block counts.
* cksum invocation:: Print CRC checksum and byte counts.
* b2sum invocation:: Print or check BLAKE2 digests.
* md5sum invocation:: Print or check MD5 digests.
* b2sum invocation:: Print or check BLAKE2 digests.
* sha1sum invocation:: Print or check SHA-1 digests.
* sha2 utilities:: Print or check SHA-2 digests.
@end menu
@@ -3984,11 +3986,13 @@ next section) is preferable in new applications.
@pindex cksum
@cindex cyclic redundancy check
@cindex CRC checksum
@cindex 32-bit checksum
@cindex checksum, 32-bit
@cindex digest
@command{cksum} by default computes a cyclic redundancy check (CRC) checksum
for each given @var{file}, or standard input if none are given or for a
@var{file} of @samp{-}.
@command{cksum} by default computes a 32-bit cyclic redundancy check (CRC)
checksum for each given @var{file}, or standard input if none are given or for
a @var{file} of @samp{-}.
cksum also supports the @option{-a/--algorithm} option to select the
digest algorithm to use. @command{cksum} is the preferred interface
@@ -4005,14 +4009,56 @@ by comparing the @command{cksum} output for the received files with the
@command{cksum} output for the original files (typically given in the
distribution).
@menu
* cksum output modes:: Legacy and non Legacy output formats
* cksum general options:: Options supported only by cksum
* cksum common options:: Options supported also by standalone utilities
@end menu
@node cksum output modes
@table @asis
@item Legacy output format
@command{cksum} by default prints the POSIX standard CRC checksum
for each file along with the number of bytes in the file,
and the file name unless no arguments were given.
The 32-bit CRC used is based on the polynomial used
for CRC error checking in the ISO/IEC 8802-3:1996 standard (Ethernet).
Similar output formats are used for the other legacy checksums
selectable with @option{--algorithm=sysv} or @option{--algorithm=bsd},
detailed at @ref{sum invocation}.
The same usage and options as the @command{b2sum}
command are supported. @xref{b2sum invocation}.
In addition @command{cksum} supports the following options.
@item Tagged output format
With the @option{--algorithm} option selecting non legacy checksums,
the @command{cksum} command defaults to output of the form:
@example
@var{digest_name} (@var{file name}) = @var{digest}
@end example
Note the standalone checksum utilities can select this output
mode by using the @option{--tag} option.
@item Untagged output format
With the @option{--untagged} option and the @option{--algorithm} option
selecting non legacy checksums, the following output format is used.
Note this is the default output format of the standalone checksum utilities.
For each @var{file}, we print the checksum, a space, a flag indicating
binary or text input mode, and the file name.
Binary mode is indicated with @samp{*}, text mode with @samp{ } (space).
Binary mode is the default on systems where it's significant,
otherwise text mode is the default.
@end table
Note without @option{--zero}, and with non legacy output formats,
if @var{file} contains a backslash, newline, or carriage return,
the line is started with a backslash, and each problematic character
in the file name is escaped with a backslash, making the output unambiguous
even in the presence of arbitrary file names.
Since the backslash character itself is escaped, any other backslash
escape sequences are reserved for future use.
@node cksum general options
@table @samp
@item -a
@@ -4041,9 +4087,7 @@ Supported more modern digest algorithms are:
@samp{sm3} only available through @command{cksum}
@end example
@item -b
@itemx --base64
@opindex -b
@item --base64
@opindex --base64
@cindex base64 checksum encoding
Print base64-encoded digests not hexadecimal.
@@ -4061,6 +4105,19 @@ input digest string as what is output. I.e., removing or adding any
@opindex --debug
Output extra information to stderr, like the checksum implementation being used.
@macro cksumLengthOption
@item -l
@itemx --length
@opindex -l
@opindex --length
@cindex BLAKE2 hash length
Change (shorten) the default digest length.
This is specified in bits and thus must be a multiple of 8.
This option is ignored when @option{--check} is specified,
as the length is automatically determined when checking.
@end macro
@cksumLengthOption
@item --raw
@opindex --raw
@cindex raw binary checksum
@@ -4080,35 +4137,140 @@ This format has the checksum at the start of the line, and may be
more amenable to further processing by other utilities,
especially in combination with the @option{--zero} option.
Note this does not identify the digest algorithm used for the checksum.
@xref{md5sum invocation} for details of this format.
@xref{cksum output modes} for details of this format.
@end table
@node b2sum invocation
@section @command{b2sum}: Print or check BLAKE2 digests
@pindex b2sum
@cindex BLAKE2
@cindex 512-bit checksum
@cindex checksum, 512-bit
@cindex fingerprint, 512-bit
@cindex message-digest, 512-bit
@command{b2sum} computes a 512-bit checksum for each specified
@var{file}. The same usage and options as the @command{md5sum}
command are supported. @xref{md5sum invocation}.
In addition @command{b2sum} supports the following options.
@node cksum common options
@table @samp
@item -l
@itemx --length
@opindex -l
@opindex --length
@cindex BLAKE2 hash length
Change (shorten) the default digest length.
This is specified in bits and thus must be a multiple of 8.
This option is ignored when @option{--check} is specified,
as the length is automatically determined when checking.
@item -b
@itemx --binary
@opindex -b
@opindex --binary
@cindex binary input files
Note this option is not supported by the @command{cksum} command,
as it operates in binary mode exclusively.
Treat each input file as binary, by reading it in binary mode and
outputting a @samp{*} flag. This is the inverse of @option{--text}.
On systems like GNU that do not distinguish between binary
and text files, this option merely flags each input mode as binary:
the checksum is unaffected. This option is the default on systems
like MS-DOS that distinguish between binary and text files, except
for reading standard input when standard input is a terminal.
@item -c
@itemx --check
Read file names and checksum information (not data) from each
@var{file} (or from standard input if no @var{file} was specified) and report
whether the checksums match the contents of the named files.
The input to this mode is usually the output of
a prior, checksum-generating run of the command.
Three input formats are supported. Either the default output
format described above, the @option{--tag} output format,
or the BSD reversed mode format which is similar to the default mode,
but doesn't use a character to distinguish binary and text modes.
For the @command{cksum} command, the @option{--check} option
supports auto-detecting the digest algorithm to use,
when presented with checksum information in the @option{--tag} output format.
Also for the @command{cksum} command, the @option{--check} option
auto-detects the digest encoding, accepting both standard hexadecimal
checksums and those generated via @command{cksum} with its
@option{--base64} option.
Output with @option{--zero} enabled is not supported by @option{--check}.
@sp 1
For each such line, @command{cksum} reads the named file and computes its
checksum. Then, if the computed message digest does not match the
one on the line with the file name, the file is noted as having
failed the test. Otherwise, the file passes the test.
By default, for each valid line, one line is written to standard
output indicating whether the named file passed the test.
After all checks have been performed, if there were any failures,
a warning is issued to standard error.
Use the @option{--status} option to inhibit that output.
If any listed file cannot be opened or read, if any valid line has
a checksum inconsistent with the associated file, or if no valid
line is found, @command{cksum} exits with nonzero status. Otherwise,
it exits successfully.
Note the @command{cksum} command doesn't support @option{--check}
with the older @samp{sysv}, @samp{bsd}, or @samp{crc} algorithms.
@item --ignore-missing
@opindex --ignore-missing
@cindex verifying checksums
This option is useful only when verifying checksums.
When verifying checksums, don't fail or report any status
for missing files. This is useful when verifying a subset
of downloaded files given a larger list of checksums.
@item --quiet
@opindex --quiet
@cindex verifying checksums
This option is useful only when verifying checksums.
When verifying checksums, don't generate an 'OK' message per successfully
checked file. Files that fail the verification are reported in the
default one-line-per-file format. If there is any checksum mismatch,
print a warning summarizing the failures to standard error.
@item --status
@opindex --status
@cindex verifying checksums
This option is useful only when verifying checksums.
When verifying checksums, don't generate the default one-line-per-file
diagnostic and don't output the warning summarizing any failures.
Failures to open or read a file still evoke individual diagnostics to
standard error.
If all listed files are readable and are consistent with the associated
checksums, exit successfully. Otherwise exit with a status code
indicating there was a failure.
@item --tag
@opindex --tag
@cindex BSD output
Output BSD style checksums, which indicate the checksum algorithm used.
As a GNU extension, if @option{--zero} is not used, file names with problematic
characters are escaped as described above, using the same escaping indicator of
@samp{\} at the start of the line, as used with the other output format.
The @option{--tag} option implies binary mode, and is disallowed with
@option{--text} mode as supporting that would unnecessarily complicate
the output format, while providing little benefit.
@xref{cksum output modes} for details of this format.
The @command{cksum} command, uses @option{--tag} as its default output format.
@item -t
@itemx --text
@opindex -t
@opindex --text
@cindex text input files
Note this option is not supported by the @command{cksum} command.
Treat each input file as text, by reading it in text mode and
outputting a @samp{ } flag. This is the inverse of @option{--binary}.
This option is the default on systems like GNU that do not
distinguish between binary and text files. On other systems, it is
the default for reading standard input when standard input is a
terminal. This mode is never defaulted to if @option{--tag} is used.
@item -w
@itemx --warn
@opindex -w
@opindex --warn
@cindex verifying checksums
When verifying checksums, warn about improperly formatted checksum lines.
This option is useful only if all but a few lines in the checked input
are valid.
@item --strict
@opindex --strict
@cindex verifying checksums
When verifying checksums,
if one or more input line is invalid,
exit nonzero after all warnings have been issued.
@optZero
Also file name escaping is not used.
@end table
@node md5sum invocation
@@ -4138,165 +4300,48 @@ consider using SHA-2, or the newer @command{b2sum} command.
@end macro
@weakHash{MD5}
@macro checksumUsage{command}
If a @var{file} is specified as @samp{-} or if no files are given
@command{md5sum} computes the checksum for the standard input.
@command{md5sum} can also determine whether a file and checksum are
@command{\command\} computes the checksum for the standard input.
@command{\command\} can also determine whether a file and checksum are
consistent. Synopsis:
@example
md5sum [@var{option}]@dots{} [@var{file}]@dots{}
\command\ [@var{option}]@dots{} [@var{file}]@dots{}
@end example
For each @var{file}, @samp{md5sum} outputs by default, the MD5 checksum,
a space, a flag indicating binary or text input mode, and the file name.
Binary mode is indicated with @samp{*}, text mode with @samp{ } (space).
Binary mode is the default on systems where it's significant,
otherwise text mode is the default. The @command{cksum} command always
uses binary mode and a @samp{ } (space) flag.
@command{\command\} uses the @samp{Untagged output format}
for each specified file, as described at @ref{cksum output modes}.
Without @option{--zero}, if @var{file} contains a backslash, newline,
or carriage return, the line is started with a backslash, and each
problematic character in the file name is escaped with a backslash,
making the output unambiguous even in the presence of arbitrary file names.
If @var{file} is omitted or specified as @samp{-}, standard input is read.
The program accepts the following options. Also see @ref{Common options}.
@table @samp
@item -b
@itemx --binary
@opindex -b
@opindex --binary
@cindex binary input files
Note this option is not supported by the @command{cksum} command,
as it operates in binary mode exclusively.
Treat each input file as binary, by reading it in binary mode and
outputting a @samp{*} flag. This is the inverse of @option{--text}.
On systems like GNU that do not distinguish between binary
and text files, this option merely flags each input mode as binary:
the MD5 checksum is unaffected. This option is the default on systems
like MS-DOS that distinguish between binary and text files, except
for reading standard input when standard input is a terminal.
@item -c
@itemx --check
Read file names and checksum information (not data) from each
@var{file} (or from standard input if no @var{file} was specified) and report
whether the checksums match the contents of the named files.
The input to this mode of @command{md5sum} is usually the output of
a prior, checksum-generating run of @samp{md5sum}.
Three input formats are supported. Either the default output
format described above, the @option{--tag} output format,
or the BSD reversed mode format which is similar to the default mode,
but doesn't use a character to distinguish binary and text modes.
For the @command{cksum} command, the @option{--check} option
supports auto-detecting the digest algorithm to use,
when presented with checksum information in the @option{--tag} output format.
Also for the @command{cksum} command, the @option{--check} option
auto-detects the digest encoding, accepting both standard hexidecimal
checksums and those generated via @command{cksum} with its
@option{--base64} option.
Output with @option{--zero} enabled is not supported by @option{--check}.
@sp 1
For each such line, @command{md5sum} reads the named file and computes its
MD5 checksum. Then, if the computed message digest does not match the
one on the line with the file name, the file is noted as having
failed the test. Otherwise, the file passes the test.
By default, for each valid line, one line is written to standard
output indicating whether the named file passed the test.
After all checks have been performed, if there were any failures,
a warning is issued to standard error.
Use the @option{--status} option to inhibit that output.
If any listed file cannot be opened or read, if any valid line has
an MD5 checksum inconsistent with the associated file, or if no valid
line is found, @command{md5sum} exits with nonzero status. Otherwise,
it exits successfully.
Note the @command{cksum} command doesn't support @option{--check}
with the older @samp{sysv}, @samp{bsd}, or @samp{crc} algorithms.
@item --ignore-missing
@opindex --ignore-missing
@cindex verifying MD5 checksums
This option is useful only when verifying checksums.
When verifying checksums, don't fail or report any status
for missing files. This is useful when verifying a subset
of downloaded files given a larger list of checksums.
@item --quiet
@opindex --quiet
@cindex verifying MD5 checksums
This option is useful only when verifying checksums.
When verifying checksums, don't generate an 'OK' message per successfully
checked file. Files that fail the verification are reported in the
default one-line-per-file format. If there is any checksum mismatch,
print a warning summarizing the failures to standard error.
@item --status
@opindex --status
@cindex verifying MD5 checksums
This option is useful only when verifying checksums.
When verifying checksums, don't generate the default one-line-per-file
diagnostic and don't output the warning summarizing any failures.
Failures to open or read a file still evoke individual diagnostics to
standard error.
If all listed files are readable and are consistent with the associated
MD5 checksums, exit successfully. Otherwise exit with a status code
indicating there was a failure.
@item --tag
@opindex --tag
@cindex BSD output
Output BSD style checksums, which indicate the checksum algorithm used.
As a GNU extension, if @option{--zero} is not used, file names with problematic
characters are escaped as described above, with the same escaping indicator of
@samp{\} at the start of the line, being used.
The @option{--tag} option implies binary mode, and is disallowed with
@option{--text} mode as supporting that would unnecessarily complicate
the output format, while providing little benefit.
The @command{cksum} command, uses @option{--tag} as its default output format.
@item -t
@itemx --text
@opindex -t
@opindex --text
@cindex text input files
Note this option is not supported by the @command{cksum} command.
Treat each input file as text, by reading it in text mode and
outputting a @samp{ } flag. This is the inverse of @option{--binary}.
This option is the default on systems like GNU that do not
distinguish between binary and text files. On other systems, it is
the default for reading standard input when standard input is a
terminal. This mode is never defaulted to if @option{--tag} is used.
@item -w
@itemx --warn
@opindex -w
@opindex --warn
@cindex verifying MD5 checksums
When verifying checksums, warn about improperly formatted MD5 checksum lines.
This option is useful only if all but a few lines in the checked input
are valid.
@item --strict
@opindex --strict
@cindex verifying MD5 checksums
When verifying checksums,
if one or more input line is invalid,
exit nonzero after all warnings have been issued.
@optZero
Also file name escaping is not used.
@end table
The program accepts @ref{cksum common options}. Also see @ref{Common options}.
@end macro
@checksumUsage{md5sum}
@exitstatus
@node b2sum invocation
@section @command{b2sum}: Print or check BLAKE2 digests
@pindex b2sum
@cindex BLAKE2
@cindex 512-bit checksum
@cindex checksum, 512-bit
@cindex fingerprint, 512-bit
@cindex message-digest, 512-bit
@command{b2sum} computes a 512-bit checksum for each specified
@var{file}.
@checksumUsage{b2sum}
In addition @command{b2sum} supports the following options.
@table @samp
@cksumLengthOption
@end table
@node sha1sum invocation
@section @command{sha1sum}: Print or check SHA-1 digests
@@ -4307,12 +4352,11 @@ Also file name escaping is not used.
@cindex fingerprint, 160-bit
@cindex message-digest, 160-bit
@command{sha1sum} computes a 160-bit checksum for each specified
@var{file}. The usage and options of this command are precisely the
same as for @command{md5sum}. @xref{md5sum invocation}.
@command{sha1sum} computes a 160-bit checksum for each specified @var{file}.
@weakHash{SHA-1}
@checksumUsage{sha1sum}
@node sha2 utilities
@section sha2 utilities: Print or check SHA-2 digests
@@ -4342,10 +4386,9 @@ same as for @command{md5sum}. @xref{md5sum invocation}.
The commands @command{sha224sum}, @command{sha256sum},
@command{sha384sum} and @command{sha512sum} compute checksums of
various lengths (respectively 224, 256, 384 and 512 bits),
collectively known as the SHA-2 hashes. The usage and options of
these commands are precisely the same as for @command{md5sum}
and @command{sha1sum}.
@xref{md5sum invocation}.
collectively known as the SHA-2 hashes.
@checksumUsage{sha???sum}
@node Operating on sorted files
@@ -4418,7 +4461,7 @@ specified for all GNU utilities) has no limit on input line length or
restrictions on bytes allowed within lines.
@command{sort} has three modes of operation: sort (the default), merge,
and check for sortedness. The following options change the operation
and check for order. The following options change the operation
mode:
@table @samp
@@ -4428,7 +4471,7 @@ mode:
@itemx --check=diagnose-first
@opindex -c
@opindex --check
@cindex checking for sortedness
@cindex checking whether a file is sorted
Check whether the given file is already sorted: if it is not all
sorted, print a diagnostic containing the first out-of-order line and
exit with a status of 1.
@@ -4440,7 +4483,7 @@ At most one input file can be given.
@itemx --check=silent
@opindex -c
@opindex --check
@cindex checking for sortedness
@cindex checking whether a file is sorted
Exit successfully if the given file is already sorted, and
exit with status 1 otherwise.
At most one input file can be given.
@@ -9236,9 +9279,9 @@ results in an error message on systems that do not support symbolic links.
@optNoTargetDirectory
@item -u
@itemx --update
@itemx --update[=@var{which}]
@opindex -u
@opindex --update
@opindex --update[=@var{which}]
@cindex newer files, copying only
Do not copy a non-directory that has an existing destination with the
same or newer modification timestamp; instead, silently skip the file
@@ -9254,6 +9297,26 @@ for example), that will take precedence; consequently, depending on the
order that files are processed from the source, newer files in the destination
may be replaced, to mirror hard links in the source.
@macro whichUpdate
@var{which} gives more control over which existing files in the
destination are replaced, and its value can be one of the following:
@table @samp
@item all
This is the default operation when an @option{--update} option is not specified,
and results in all existing files in the destination being replaced.
@item none
This is similar to the @option{--no-clobber} option, in that no files in the
destination are replaced, but also skipping a file does not induce a failure.
@item older
This is the default operation when @option{--update} is specified, and results
in files being replaced if they're older than the corresponding source file.
@end table
@end macro
@whichUpdate
@item -v
@itemx --verbose
@opindex -v
@@ -9794,7 +9857,7 @@ can be followed by a multiplier: @samp{b}=512, @samp{c}=1,
standard block size suffixes like @samp{k}=1024 (@pxref{Block size}).
These multipliers are GNU extensions to POSIX, except that
POSIX allows @var{bytes} to be followed by @samp{k}, @samp{b}, and
@samp{x@var{m}}.
@samp{x@var{m}}. Note @samp{x@var{m}} can be used more than once in a number.
Block sizes (i.e., specified by @var{bytes} strings) must be nonzero.
Any block size you specify via @samp{bs=}, @samp{ibs=}, @samp{obs=}, @samp{cbs=}
@@ -10165,6 +10228,8 @@ of its permissions, and fail if the response is not affirmative.
Do not overwrite an existing file; silently fail instead.
@mvOptsIfn
This option is mutually exclusive with @option{-b} or @option{--backup} option.
See also the @option{--update=none} option which will
skip existing files but not fail.
@item --no-copy
@opindex --no-copy
@@ -10188,6 +10253,8 @@ same source and destination.
This option is ignored if the @option{-n} or @option{--no-clobber}
option is also specified.
@whichUpdate
@item -v
@itemx --verbose
@opindex -v
@@ -12106,7 +12173,7 @@ a mounted file system, @command{df} shows the space available on that
file system rather than on the file system containing the device node.
GNU @command{df} does not attempt to determine the usage
on unmounted file systems, because on most kinds of systems doing so
requires extremely nonportable intimate knowledge of file system structures.
requires extremely non-portable intimate knowledge of file system structures.
The program accepts the following options. Also see @ref{Common options}.
@@ -13320,7 +13387,7 @@ For example, @samp{printf '\400'} is equivalent to @samp{printf '\0'}.
@cindex Unicode
@cindex ISO/IEC 10646
@vindex LC_CTYPE
@command{printf} interprets two syntaxes for specifying Unicode
@command{printf} interprets two syntax forms for specifying Unicode
(ISO/IEC 10646) characters.
@samp{\u} for 16-bit Unicode characters, specified as
four hexadecimal digits @var{hhhh}, and @samp{\U} for 32-bit Unicode
@@ -13336,7 +13403,7 @@ The processing of @samp{\u} and @samp{\U} requires a full-featured
or when @code{libiconv} is installed prior to this package. Otherwise
@samp{\u} and @samp{\U} will print as-is.
The Unicode character syntaxes are useful for writing strings in a locale
Unicode character syntax is useful for writing strings in a locale
independent way. For example, a string containing the Euro currency symbol
@example
@@ -16240,6 +16307,21 @@ Normally, @command{date} uses the time zone rules indicated by the
is not set. @xref{TZ Variable,, Specifying the Time Zone with
@env{TZ}, libc, The GNU C Library Reference Manual}.
@exitstatus
@menu
* Date format specifiers:: Used in @samp{date '+...'}
* Setting the time:: Changing the system clock.
* Options for date:: Instead of the current time.
@detailmenu
* Date input formats:: Specifying date strings.
@end detailmenu
* Examples of date:: Examples.
@end menu
@node Date format specifiers
@subsection Specifying the format of @command{date} output
@findex strftime @r{and @command{date}}
@cindex time formats
@cindex formatting times
@@ -16251,23 +16333,15 @@ conversion specifiers, which start with @samp{%}, characters in the
format string are printed unchanged. The conversion specifiers are
described below.
@exitstatus
@menu
* Time conversion specifiers:: %[HIklMNpPrRsSTXzZ]
* Date conversion specifiers:: %[aAbBcCdDeFgGhjmuUVwWxyY]
* Literal conversion specifiers:: %[%nt]
* Padding and other flags:: Pad with zeros, spaces, etc.
* Setting the time:: Changing the system clock.
* Options for date:: Instead of the current time.
@detailmenu
* Date input formats:: Specifying date strings.
@end detailmenu
* Examples of date:: Examples.
@end menu
@node Time conversion specifiers
@subsection Time conversion specifiers
@subsubsection Time conversion specifiers
@cindex time conversion specifiers
@cindex conversion specifiers, time
@@ -16348,7 +16422,7 @@ time zone is determinable. See @samp{%z} for how it is determined.
@node Date conversion specifiers
@subsection Date conversion specifiers
@subsubsection Date conversion specifiers
@cindex date conversion specifiers
@cindex conversion specifiers, date
@@ -16439,7 +16513,7 @@ precedes year @samp{0000}.
@node Literal conversion specifiers
@subsection Literal conversion specifiers
@subsubsection Literal conversion specifiers
@cindex literal conversion specifiers
@cindex conversion specifiers, literal
@@ -16457,7 +16531,7 @@ a horizontal tab
@node Padding and other flags
@subsection Padding and other flags
@subsubsection Padding and other flags
@cindex numeric field padding
@cindex padding of numeric fields
@@ -16883,6 +16957,16 @@ date --date='1970-01-01 00:02:00 +0000' +%s
120
@end example
To convert a date string from one time zone @var{from} to another @var{to},
specify @samp{TZ="@var{from}"} in the environment and @samp{TZ="@var{to}"}
in the @option{--date} option. @xref{Specifying time zone rules}.
For example:
@smallexample
TZ="Asia/Tokyo" date --date='TZ="America/New_York" 2023-05-07 12:23'
Mon May @ 8 01:23:00 JST 2023
@end smallexample
If you do not specify time zone information in the date string,
@command{date} uses your computer's idea of the time zone when
interpreting the string. For example, if your computer's time zone is

View File

@@ -25,6 +25,10 @@ doc_coreutils_TEXINFOS = \
doc/fdl.texi \
doc/sort-version.texi
# The customization variable CHECK_NORMAL_MENU_STRUCTURE is necessary with
# makeinfo versions ≥ 6.8.
MAKEINFO = @MAKEINFO@ -c CHECK_NORMAL_MENU_STRUCTURE=1
# The following is necessary if the package name is 8 characters or longer.
# If the info documentation would be split into 10 or more separate files,
# then this is necessary even if the package name is 7 characters long.

View File

@@ -843,7 +843,7 @@ natsort -- how it works}).
Ruby's @uref{https://github.com/github/version_sorter,version_sorter}.
@item
Perl has multiple packages for natual and version sorts
Perl has multiple packages for natural and version sorts
(each likely with its own rules and nuances):
@uref{https://metacpan.org/pod/Sort::Naturally,Sort::Naturally},
@uref{https://metacpan.org/pod/Sort::Versions,Sort::Versions},
@@ -865,7 +865,7 @@ glob modifier} @samp{*(n)} will expand to files in natural sort order.
When writing C programs, the GNU libc library (@samp{glibc})
provides the
@uref{https://man7.org/linux/man-pages/man3/strverscmp.3.html,
strvercmp(3)} function to compare two strings, and
strverscmp(3)} function to compare two strings, and
@uref{https://man7.org/linux/man-pages/man3/versionsort.3.html,versionsort(3)}
function to compare two directory entries (despite the names, they are
not identical to GNU Coreutils version sort ordering).

View File

@@ -46,7 +46,7 @@
Parse the initial prefix of NPTR as a floating-point number in the
current locale or in the C locale (preferring the locale that
yields the longer parse, or the current locale if there is a tie).
If ENDPTR is not NULL, set *ENDPTR to the first unused byte, or to
If ENDPTR is non-null, set *ENDPTR to the first unused byte, or to
NPTR if the prefix cannot be parsed.
If successful, return a number without changing errno.

View File

@@ -50,7 +50,7 @@ heap_alloc (int (*compare) (void const *, void const *), size_t n_reserve)
heap->array = xnmalloc (n_reserve, sizeof *(heap->array));
heap->array[0] = NULL;
heap->array[0] = nullptr;
heap->capacity = n_reserve;
heap->count = 0;
heap->compare = compare ? compare : heap_default_compare;
@@ -96,7 +96,7 @@ heap_remove_top (struct heap *heap)
void *top;
if (heap->count == 0)
return NULL;
return nullptr;
top = heap->array[1];
heap->array[1] = heap->array[heap->count--];

View File

@@ -111,8 +111,8 @@ mbsalign (char const *src, char *dest, size_t dest_size,
{
size_t ret = SIZE_MAX;
size_t src_size = strlen (src) + 1;
char *newstr = NULL;
wchar_t *str_wc = NULL;
char *newstr = nullptr;
wchar_t *str_wc = nullptr;
char const *str_to_print = src;
size_t n_cols = src_size - 1;
size_t n_used_bytes = n_cols; /* Not including NUL */
@@ -125,7 +125,7 @@ mbsalign (char const *src, char *dest, size_t dest_size,
of screen columns used. */
if (!(flags & MBA_UNIBYTE_ONLY) && MB_CUR_MAX > 1)
{
size_t src_chars = mbstowcs (NULL, src, 0);
size_t src_chars = mbstowcs (nullptr, src, 0);
if (src_chars == SIZE_MAX)
{
if (flags & MBA_UNIBYTE_FALLBACK)
@@ -135,7 +135,7 @@ mbsalign (char const *src, char *dest, size_t dest_size,
}
src_chars += 1; /* make space for NUL */
str_wc = malloc (src_chars * sizeof (wchar_t));
if (str_wc == NULL)
if (str_wc == nullptr)
{
if (flags & MBA_UNIBYTE_FALLBACK)
goto mbsalign_unibyte;
@@ -159,10 +159,10 @@ mbsalign (char const *src, char *dest, size_t dest_size,
{
/* May have increased the size by converting
\t to \uFFFD for example. */
src_size = wcstombs (NULL, str_wc, 0) + 1;
src_size = wcstombs (nullptr, str_wc, 0) + 1;
}
newstr = malloc (src_size);
if (newstr == NULL)
if (newstr == nullptr)
{
if (flags & MBA_UNIBYTE_FALLBACK)
goto mbsalign_unibyte;
@@ -239,7 +239,7 @@ mbsalign_cleanup:
/* A wrapper around mbsalign() to dynamically allocate the
minimum amount of memory to store the result.
Return NULL on failure. */
Return nullptr on failure. */
char *
ambsalign (char const *src, size_t *width, mbs_align_t align, int flags)
@@ -247,17 +247,17 @@ ambsalign (char const *src, size_t *width, mbs_align_t align, int flags)
size_t orig_width = *width;
size_t size = *width; /* Start with enough for unibyte mode. */
size_t req = size;
char *buf = NULL;
char *buf = nullptr;
while (req >= size)
{
char *nbuf;
size = req + 1; /* Space for NUL. */
nbuf = realloc (buf, size);
if (nbuf == NULL)
if (nbuf == nullptr)
{
free (buf);
buf = NULL;
buf = nullptr;
break;
}
buf = nbuf;
@@ -266,7 +266,7 @@ ambsalign (char const *src, size_t *width, mbs_align_t align, int flags)
if (req == SIZE_MAX)
{
free (buf);
buf = NULL;
buf = nullptr;
break;
}
}

View File

@@ -35,8 +35,8 @@ int
main (int argc, char **argv)
{
randint i;
randint n = strtoumax (argv[1], NULL, 10);
randint choices = strtoumax (argv[2], NULL, 10);
randint n = strtoumax (argv[1], nullptr, 10);
randint choices = strtoumax (argv[2], nullptr, 10);
char const *name = argv[3];
struct randint_source *ints = randint_all_new (name, SIZE_MAX);
@@ -77,14 +77,14 @@ randint_new (struct randread_source *source)
}
/* Create a new randint_source by creating a randread_source from
NAME and ESTIMATED_BYTES. Return NULL (setting errno) if
NAME and ESTIMATED_BYTES. Return nullptr (setting errno) if
unsuccessful. */
struct randint_source *
randint_all_new (char const *name, size_t bytes_bound)
{
struct randread_source *source = randread_new (name, bytes_bound);
return (source ? randint_new (source) : NULL);
return (source ? randint_new (source) : nullptr);
}
/* Return the random data source of *S. */

View File

@@ -109,7 +109,7 @@ typedef Hash_table sparse_map;
static sparse_map *
sparse_new (size_t size_hint)
{
return hash_initialize (size_hint, NULL, sparse_hash_, sparse_cmp_, free);
return hash_initialize (size_hint, nullptr, sparse_hash_, sparse_cmp_, free);
}
/* Swap the values for I and J. If a value is not already present
@@ -154,7 +154,7 @@ sparse_free (sparse_map *sv)
/* From R, allocate and return a malloc'd array of the first H elements
of a random permutation of N elements. H must not exceed N.
Return NULL if H is zero. */
Return nullptr if H is zero. */
size_t *
randperm_new (struct randint_source *r, size_t h, size_t n)
@@ -164,7 +164,7 @@ randperm_new (struct randint_source *r, size_t h, size_t n)
switch (h)
{
case 0:
v = NULL;
v = nullptr;
break;
case 1:
@@ -209,13 +209,13 @@ randperm_new (struct randint_source *r, size_t h, size_t n)
if (sparse)
{
sv = sparse_new (h * 2);
if (sv == NULL)
if (sv == nullptr)
xalloc_die ();
v = xnmalloc (h, sizeof *v);
}
else
{
sv = NULL; /* To placate GCC's -Wuninitialized. */
sv = nullptr; /* To placate GCC's -Wuninitialized. */
v = xnmalloc (n, sizeof *v);
for (i = 0; i < n; i++)
v[i] = i;

View File

@@ -38,6 +38,7 @@
#include "gettext.h"
#define _(msgid) gettext (msgid)
#include "assure.h"
#include "minmax.h"
#include "rand-isaac.h"
#include "stdio-safer.h"
@@ -103,11 +104,10 @@ struct randread_source
static void
randread_error (void const *file_name)
{
if (file_name)
error (exit_failure, errno,
errno == 0 ? _("%s: end of file") : _("%s: read error"),
quote (file_name));
abort ();
affirm (exit_failure);
error (exit_failure, errno,
errno == 0 ? _("%s: end of file") : _("%s: read error"),
quote (file_name));
}
/* Simply return a new randread_source object with the default error
@@ -132,7 +132,13 @@ get_nonce (void *buffer, size_t bufsize)
char *buf = buffer, *buflim = buf + bufsize;
while (buf < buflim)
{
ssize_t nbytes = getrandom (buf, buflim - buf, 0);
#if defined __sun
# define MAX_GETRANDOM 1024
#else
# define MAX_GETRANDOM SIZE_MAX
#endif
size_t max_bytes = MIN (buflim - buf, MAX_GETRANDOM);
ssize_t nbytes = getrandom (buf, max_bytes, 0);
if (0 <= nbytes)
buf += nbytes;
else if (errno != EINTR)
@@ -161,21 +167,21 @@ randread_free_body (struct randread_source *s)
default handler. Unless a non-default handler is used, NAME's
lifetime should be at least that of the returned value.
Return NULL (setting errno) on failure. */
Return nullptr (setting errno) on failure. */
struct randread_source *
randread_new (char const *name, size_t bytes_bound)
{
if (bytes_bound == 0)
return simple_new (NULL, NULL);
return simple_new (nullptr, nullptr);
else
{
FILE *source = NULL;
FILE *source = nullptr;
struct randread_source *s;
if (name)
if (! (source = fopen_safer (name, "rb")))
return NULL;
return nullptr;
s = simple_new (source, name);
@@ -190,7 +196,7 @@ randread_new (char const *name, size_t bytes_bound)
int e = errno;
randread_free_body (s);
errno = e;
return NULL;
return nullptr;
}
isaac_seed (&s->buf.isaac.state);
}

View File

@@ -23,14 +23,14 @@
#include <stdlib.h>
/* Call lstat to get the device and inode numbers for '/'.
Upon failure, return NULL. Otherwise, set the members of
Upon failure, return nullptr. Otherwise, set the members of
*ROOT_D_I accordingly and return ROOT_D_I. */
struct dev_ino *
get_root_dev_ino (struct dev_ino *root_d_i)
{
struct stat statbuf;
if (lstat ("/", &statbuf))
return NULL;
return nullptr;
root_d_i->st_ino = statbuf.st_ino;
root_d_i->st_dev = statbuf.st_dev;
return root_d_i;

View File

@@ -37,7 +37,7 @@ static inline bool
is_smack_enabled (void)
{
#ifdef HAVE_SMACK
return smack_smackfs_path () != NULL;
return smack_smackfs_path () != nullptr;
#else
return false;
#endif

View File

@@ -21,11 +21,11 @@
#include <errno.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdlib.h>
#include "error.h"
#include "quote.h"
#include "verify.h"
#include "xstrtol.h"
/* Parse numeric string N_STR of base BASE, and return the value.
@@ -40,7 +40,7 @@ __xnumtoint (char const *n_str, int base, __xdectoint_t min, __xdectoint_t max,
strtol_error s_err;
__xdectoint_t tnum;
s_err = __xstrtol (n_str, NULL, base, &tnum, suffixes);
s_err = __xstrtol (n_str, nullptr, base, &tnum, suffixes);
if (s_err == LONGINT_OK)
{
@@ -69,7 +69,7 @@ __xnumtoint (char const *n_str, int base, __xdectoint_t min, __xdectoint_t max,
/* EINVAL error message is redundant in this context. */
error (err_exit ? err_exit : EXIT_FAILURE, errno == EINVAL ? 0 : errno,
"%s: %s", err, quote (n_str));
assume (false);
unreachable ();
}
return tnum;

View File

@@ -21,8 +21,8 @@
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include "assure.h"
#include "xalloc.h"
#include "xfts.h"
@@ -33,11 +33,11 @@ xfts_open (char * const *argv, int options,
int (*compar) (const FTSENT **, const FTSENT **))
{
FTS *fts = fts_open (argv, options | FTS_CWDFD, compar);
if (fts == NULL)
if (fts == nullptr)
{
/* This can fail in two ways: out of memory or with errno==EINVAL,
which indicates it was called with invalid bit_flags. */
assert (errno != EINVAL);
affirm (errno != EINVAL);
xalloc_die ();
}

View File

@@ -36,7 +36,7 @@ main (void)
fdadvise (fileno (stdin), 0, 0, FADVISE_RANDOM);
/* Ignored. */
fadvise (NULL, FADVISE_RANDOM);
fadvise (nullptr, FADVISE_RANDOM);
/* Invalid. */
fdadvise (42, 0, 0, FADVISE_RANDOM);

View File

@@ -29,10 +29,19 @@ main (void)
char dest[4 * 16 + 1];
size_t width, n;
/* Test unibyte truncation. */
width = 4;
n = mbsalign ("t\tés", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0);
ASSERT (n == 4);
#ifdef __ANDROID__
/* On Android ≥ 5.0, the default locale is the "C.UTF-8" locale, not the
"C" locale. Furthermore, when you attempt to set the "C" or "POSIX"
locale via setlocale(), what you get is a "C" locale with UTF-8 encoding,
that is, effectively the "C.UTF-8" locale. */
if (MB_CUR_MAX == 1)
#endif
{
/* Test unibyte truncation. */
width = 4;
n = mbsalign ("t\tés", dest, sizeof dest, &width, MBS_ALIGN_LEFT, 0);
ASSERT (n == 4);
}
/* Test center alignment. */
width = 4;

View File

@@ -581,7 +581,7 @@ main (int argc, char **argv)
/* If invoked with a positive argument, run a benchmark;
if with a negative, run a do-nothing benchmark. */
for (iterations = argc <= 1 ? 0 : strtol (argv[1], NULL, 10);
for (iterations = argc <= 1 ? 0 : strtol (argv[1], nullptr, 10);
iterations != 0;
iterations += (iterations < 0 ? 1 : -1))
if (0 <= iterations)

2
gnulib

Submodule gnulib updated: f17d397771...bb5bb43a1e

View File

@@ -275,7 +275,7 @@ require_valgrind_()
# If the given ACL spec would not change the ACLs on the file, then setfacl
# does not invoke the underlying system call - setxattr(). Therefore, to test
# if setting ACLs really works on the current file system, call setfacl twice
# with conflictive ACL specs.
# with conflicting ACL specs.
require_setfacl_()
{
local d='acltestdir_'
@@ -539,7 +539,7 @@ require_trap_signame_()
# dash 0.5.8 at least does not.
require_kill_group_()
{
kill -0 -- -1 || skip_ 'requires kill with group signalling support'
kill -0 -- -1 || skip_ 'requires kill with group signaling support'
}
# Return nonzero if the specified path is on a file system for

View File

@@ -1,65 +0,0 @@
# boottime.m4 serial 4
# Determine whether this system has infrastructure for obtaining the boot time.
# Copyright (C) 1996-2023 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# GNULIB_BOOT_TIME([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
* ----------------------------------------------------------
AC_DEFUN([GNULIB_BOOT_TIME],
[
AC_CHECK_FUNCS([sysctl])
AC_CHECK_HEADERS_ONCE([sys/param.h])
AC_CHECK_HEADERS([sys/sysctl.h], [], [],
[AC_INCLUDES_DEFAULT
[#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif]])
AC_CHECK_HEADERS_ONCE([utmpx.h OS.h])
AC_CACHE_CHECK(
[whether we can get the system boot time],
[gnulib_cv_have_boot_time],
[
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[AC_INCLUDES_DEFAULT
#if HAVE_SYSCTL && HAVE_SYS_SYSCTL_H
# if HAVE_SYS_PARAM_H
# include <sys/param.h> /* needed for OpenBSD 3.0 */
# endif
# include <sys/sysctl.h>
#endif
#if HAVE_UTMPX_H
# include <utmpx.h>
#endif
#include <utmp.h>
#if HAVE_OS_H
# include <OS.h>
#endif
],
[[
#if (defined BOOT_TIME \
|| (defined CTL_KERN && defined KERN_BOOTTIME) \
|| HAVE_OS_H)
/* your system *does* have the infrastructure to determine boot time */
#else
please_tell_us_how_to_determine_boot_time_on_your_system
#endif
]])],
[gnulib_cv_have_boot_time=yes],
[gnulib_cv_have_boot_time=no])
])
AS_IF([test $gnulib_cv_have_boot_time = yes], [$1], [$2])
])

View File

@@ -7,7 +7,7 @@
basenc \- Encode/decode data and print to standard output
[DESCRIPTION]
.\" Add any additional description here
[ENCODINGS EXAMPLES]
[ENCODING EXAMPLES]
.PP
.nf
.RS

View File

@@ -2,3 +2,5 @@
cp \- copy files and directories
[DESCRIPTION]
.\" Add any additional description here
[SEE ALSO]
install(1)

View File

@@ -24,6 +24,6 @@ shows the space available on that file system rather than on the
file system containing the device node. This version of
.B df
cannot show the space available on unmounted file systems, because on
most kinds of systems doing so requires very nonportable intimate
most kinds of systems doing so requires non-portable intimate
knowledge of file system structures.
.SH OPTIONS

View File

@@ -2,3 +2,5 @@
install \- copy files and set attributes
[DESCRIPTION]
.\" Add any additional description here
[SEE ALSO]
cp(1)

View File

@@ -4,11 +4,11 @@
# These are nominally temporary...
lib/argmatch.c
lib/argmatch.h
lib/c-file-type.c
lib/closein.c
lib/closeout.c
lib/copy-acl.c
lib/error.c
lib/file-type.c
lib/gai_strerror.c
lib/getopt.c
lib/mkdir-p.c
@@ -125,6 +125,7 @@ src/tac-pipe.c
src/tac.c
src/tail.c
src/tee.c
src/temp-stream.c
src/test.c
src/timeout.c
src/touch.c

View File

@@ -32,7 +32,7 @@ Older version (pre 7.2) mention 'tee','eaccess','futimens'.
Details
-------
GLibC version 2.28 removed non-standed headre file (libio.h) and some
GLibC version 2.28 removed a non-standard header file (libio.h) and some
internal symbols which were used by gnulib (a core component of GNU coreutils).
These were announced as 'deprecated' in version 2.27 [1], and removed in

View File

@@ -20,7 +20,6 @@
#include <sys/types.h>
#include "system.h"
#include "error.h"
#include "quote.h"
/* The official name of this program (e.g., no 'g' prefix). */
@@ -30,12 +29,12 @@
static struct option const longopts[] =
{
{"multiple", no_argument, NULL, 'a'},
{"suffix", required_argument, NULL, 's'},
{"zero", no_argument, NULL, 'z'},
{"multiple", no_argument, nullptr, 'a'},
{"suffix", required_argument, nullptr, 's'},
{"zero", no_argument, nullptr, 'z'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -97,7 +96,7 @@ remove_suffix (char *name, char const *suffix)
*np = '\0';
}
/* Perform the basename operation on STRING. If SUFFIX is non-NULL, remove
/* Perform the basename operation on STRING. If SUFFIX is non-null, remove
the trailing SUFFIX. Finally, output the result string. */
static void
@@ -125,7 +124,7 @@ main (int argc, char **argv)
{
bool multiple_names = false;
bool use_nuls = false;
char const *suffix = NULL;
char const *suffix = nullptr;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -137,7 +136,7 @@ main (int argc, char **argv)
while (true)
{
int c = getopt_long (argc, argv, "+as:z", longopts, NULL);
int c = getopt_long (argc, argv, "+as:z", longopts, nullptr);
if (c == -1)
break;
@@ -184,7 +183,8 @@ main (int argc, char **argv)
}
else
perform_basename (argv[optind],
optind + 2 == argc ? argv[optind + 1] : NULL, use_nuls);
optind + 2 == argc ? argv[optind + 1] : nullptr,
use_nuls);
return EXIT_SUCCESS;
}

View File

@@ -24,10 +24,7 @@
#include "system.h"
#include "c-ctype.h"
#include "die.h"
#include "error.h"
#include "fadvise.h"
#include "idx.h"
#include "quote.h"
#include "xstrtol.h"
#include "xdectoint.h"
@@ -50,7 +47,7 @@
#elif BASE_TYPE == 42
# include "base32.h"
# include "base64.h"
# include <assert.h>
# include "assure.h"
# define PROGRAM_NAME "basenc"
#else
# error missing/invalid BASE_TYPE definition
@@ -89,7 +86,7 @@ static struct option const long_options[] =
#endif
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -449,7 +446,7 @@ base32hex_encode (char const *restrict in, idx_t inlen,
for (char *p = out; outlen--; p++)
{
assert (0x32 <= *p && *p <= 0x5a); /* LCOV_EXCL_LINE */
affirm (0x32 <= *p && *p <= 0x5a); /* LCOV_EXCL_LINE */
*p = base32_norm_to_hex[*p - 0x32];
}
}
@@ -588,7 +585,7 @@ z85_length (int len)
static bool
isz85 (char ch)
{
return c_isalnum (ch) || (strchr (".-:+=^!/*?&<>()[]{}@%$#", ch) != NULL);
return c_isalnum (ch) || strchr (".-:+=^!/*?&<>()[]{}@%$#", ch) != nullptr;
}
static char const z85_encoding[85] =
@@ -614,8 +611,8 @@ z85_encode (char const *restrict in, idx_t inlen,
return;
/* currently, there's no way to return an error in encoding. */
die (EXIT_FAILURE, 0,
_("invalid input (length must be multiple of 4 characters)"));
error (EXIT_FAILURE, 0,
_("invalid input (length must be multiple of 4 characters)"));
}
else
{
@@ -926,7 +923,7 @@ wrap_write (char const *buffer, idx_t len,
{
/* Simple write. */
if (fwrite (buffer, 1, len, stdout) < len)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
}
else
for (idx_t written = 0; written < len; )
@@ -936,13 +933,13 @@ wrap_write (char const *buffer, idx_t len,
if (to_write == 0)
{
if (fputc ('\n', out) == EOF)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
*current_column = 0;
}
else
{
if (fwrite (buffer + written, 1, to_write, stdout) < to_write)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
*current_column += to_write;
written += to_write;
}
@@ -955,9 +952,9 @@ finish_and_exit (FILE *in, char const *infile)
if (fclose (in) != 0)
{
if (STREQ (infile, "-"))
die (EXIT_FAILURE, errno, _("closing standard input"));
error (EXIT_FAILURE, errno, _("closing standard input"));
else
die (EXIT_FAILURE, errno, "%s", quotef (infile));
error (EXIT_FAILURE, errno, "%s", quotef (infile));
}
exit (EXIT_SUCCESS);
@@ -999,10 +996,10 @@ do_encode (FILE *in, char const *infile, FILE *out, idx_t wrap_column)
/* When wrapping, terminate last line. */
if (wrap_column && current_column > 0 && fputc ('\n', out) == EOF)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
if (ferror (in))
die (EXIT_FAILURE, errno, _("read error"));
error (EXIT_FAILURE, errno, _("read error"));
finish_and_exit (in, infile);
}
@@ -1018,7 +1015,7 @@ do_decode (FILE *in, char const *infile, FILE *out, bool ignore_garbage)
outbuf = xmalloc (DEC_BLOCKSIZE);
#if BASE_TYPE == 42
ctx.inbuf = NULL;
ctx.inbuf = nullptr;
#endif
base_decode_ctx_init (&ctx);
@@ -1046,7 +1043,7 @@ do_decode (FILE *in, char const *infile, FILE *out, bool ignore_garbage)
sum += n;
if (ferror (in))
die (EXIT_FAILURE, errno, _("read error"));
error (EXIT_FAILURE, errno, _("read error"));
}
while (sum < BASE_LENGTH (DEC_BLOCKSIZE) && !feof (in));
@@ -1062,10 +1059,10 @@ do_decode (FILE *in, char const *infile, FILE *out, bool ignore_garbage)
ok = base_decode_ctx (&ctx, inbuf, (k == 0 ? sum : 0), outbuf, &n);
if (fwrite (outbuf, 1, n, out) < n)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
if (!ok)
die (EXIT_FAILURE, 0, _("invalid input"));
error (EXIT_FAILURE, 0, _("invalid input"));
}
}
while (!feof (in));
@@ -1099,7 +1096,7 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((opt = getopt_long (argc, argv, "diw:", long_options, NULL)) != -1)
while ((opt = getopt_long (argc, argv, "diw:", long_options, nullptr)) != -1)
switch (opt)
{
case 'd':
@@ -1109,10 +1106,10 @@ main (int argc, char **argv)
case 'w':
{
intmax_t w;
strtol_error s_err = xstrtoimax (optarg, NULL, 10, &w, "");
strtol_error s_err = xstrtoimax (optarg, nullptr, 10, &w, "");
if (LONGINT_OVERFLOW < s_err || w < 0)
die (EXIT_FAILURE, 0, "%s: %s",
_("invalid wrap size"), quote (optarg));
error (EXIT_FAILURE, 0, "%s: %s",
_("invalid wrap size"), quote (optarg));
wrap_column = s_err == LONGINT_OVERFLOW || IDX_MAX < w ? 0 : w;
}
break;
@@ -1235,8 +1232,8 @@ main (int argc, char **argv)
else
{
input_fh = fopen (infile, "rb");
if (input_fh == NULL)
die (EXIT_FAILURE, errno, "%s", quotef (infile));
if (input_fh == nullptr)
error (EXIT_FAILURE, errno, "%s", quotef (infile));
}
fadvise (input_fh, FADVISE_SEQUENTIAL);

View File

@@ -20,7 +20,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <ctype.h>
@@ -269,12 +268,12 @@ int main( int argc, char **argv )
while( 1 )
{
int option_index = 0;
char *end = NULL;
char *end = nullptr;
unsigned long outbits;
static struct option long_options[] = {
{ "help", no_argument, 0, 0 },
{ "tag", no_argument, 0, 0 },
{ NULL, 0, NULL, 0 }
{ nullptr, 0, nullptr, 0 }
};
c = getopt_long( argc, argv, "a:l:", long_options, &option_index );
@@ -351,7 +350,7 @@ int main( int argc, char **argv )
for( i = optind; i < argc; ++i )
{
FILE *f = NULL;
FILE *f = nullptr;
if( argv[i][0] == '-' && argv[i][1] == '\0' )
f = stdin;
else

View File

@@ -19,10 +19,11 @@
* Usually much faster than other versions of cat, the difference
is especially apparent when using the -v option.
By tege@sics.se, Torbjorn Granlund, advised by rms, Richard Stallman. */
By tege@sics.se, Torbjörn Granlund, advised by rms, Richard Stallman. */
#include <config.h>
#include <stdckdint.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
@@ -34,10 +35,7 @@
#include "system.h"
#include "alignalloc.h"
#include "idx.h"
#include "ioblksize.h"
#include "die.h"
#include "error.h"
#include "fadvise.h"
#include "full-write.h"
#include "safe-read.h"
@@ -47,7 +45,7 @@
#define PROGRAM_NAME "cat"
#define AUTHORS \
proper_name ("Torbjorn Granlund"), \
proper_name_lite ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
proper_name ("Richard M. Stallman")
/* Name of input file. May be "-". */
@@ -179,7 +177,7 @@ simple_cat (char *buf, idx_t bufsize)
/* Write this block out. */
if (full_write (STDOUT_FILENO, buf, n_read) != n_read)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
}
}
@@ -194,7 +192,7 @@ write_pending (char *outbuf, char **bpout)
if (0 < n_write)
{
if (full_write (STDOUT_FILENO, outbuf, n_write) != n_write)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
*bpout = outbuf;
}
}
@@ -258,7 +256,7 @@ cat (char *inbuf, idx_t insize, char *outbuf, idx_t outsize,
do
{
if (full_write (STDOUT_FILENO, wp, outsize) != outsize)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
wp += outsize;
remaining_bytes = bpout - wp;
}
@@ -518,7 +516,7 @@ copy_cat (void)
unsupported or the input file seems empty. */
for (bool some_copied = false; ; some_copied = true)
switch (copy_file_range (input_desc, NULL, STDOUT_FILENO, NULL,
switch (copy_file_range (input_desc, nullptr, STDOUT_FILENO, nullptr,
copy_max, 0))
{
case 0:
@@ -554,16 +552,16 @@ main (int argc, char **argv)
static struct option const long_options[] =
{
{"number-nonblank", no_argument, NULL, 'b'},
{"number", no_argument, NULL, 'n'},
{"squeeze-blank", no_argument, NULL, 's'},
{"show-nonprinting", no_argument, NULL, 'v'},
{"show-ends", no_argument, NULL, 'E'},
{"show-tabs", no_argument, NULL, 'T'},
{"show-all", no_argument, NULL, 'A'},
{"number-nonblank", no_argument, nullptr, 'b'},
{"number", no_argument, nullptr, 'n'},
{"squeeze-blank", no_argument, nullptr, 's'},
{"show-nonprinting", no_argument, nullptr, 'v'},
{"show-ends", no_argument, nullptr, 'E'},
{"show-tabs", no_argument, nullptr, 'T'},
{"show-all", no_argument, nullptr, 'A'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
initialize_main (&argc, &argv);
@@ -581,7 +579,7 @@ main (int argc, char **argv)
/* Parse command line options. */
int c;
while ((c = getopt_long (argc, argv, "benstuvAET", long_options, NULL))
while ((c = getopt_long (argc, argv, "benstuvAET", long_options, nullptr))
!= -1)
{
switch (c)
@@ -643,7 +641,7 @@ main (int argc, char **argv)
/* Get device, i-node number, and optimal blocksize of output. */
if (fstat (STDOUT_FILENO, &stat_buf) < 0)
die (EXIT_FAILURE, errno, _("standard output"));
error (EXIT_FAILURE, errno, _("standard output"));
/* Optimal size of i/o operations of output. */
idx_t outsize = io_blksize (stat_buf);
@@ -731,7 +729,7 @@ main (int argc, char **argv)
out_isreg && S_ISREG (stat_buf.st_mode) ? copy_cat () : 0;
if (copy_cat_status != 0)
{
inbuf = NULL;
inbuf = nullptr;
ok &= 0 < copy_cat_status;
}
else
@@ -768,9 +766,9 @@ main (int argc, char **argv)
on some paging implementations. */
idx_t bufsize;
if (INT_MULTIPLY_WRAPV (insize, 4, &bufsize)
|| INT_ADD_WRAPV (bufsize, outsize, &bufsize)
|| INT_ADD_WRAPV (bufsize, LINE_COUNTER_BUF_LEN - 1, &bufsize))
if (ckd_mul (&bufsize, insize, 4)
|| ckd_add (&bufsize, bufsize, outsize)
|| ckd_add (&bufsize, bufsize, LINE_COUNTER_BUF_LEN - 1))
xalloc_die ();
char *outbuf = xalignalloc (page_size, bufsize);
@@ -795,11 +793,11 @@ main (int argc, char **argv)
if (pending_cr)
{
if (full_write (STDOUT_FILENO, "\r", 1) != 1)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
}
if (have_read_stdin && close (STDIN_FILENO) < 0)
die (EXIT_FAILURE, errno, _("closing standard input"));
error (EXIT_FAILURE, errno, _("closing standard input"));
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -22,8 +22,6 @@
#include "system.h"
#include "dev-ino.h"
#include "die.h"
#include "error.h"
#include "ignore-value.h"
#include "quote.h"
#include "root-dev-ino.h"
@@ -48,7 +46,7 @@ static bool recurse;
static bool verbose;
/* Pointer to the device and inode numbers of '/', when --recursive.
Otherwise NULL. */
Otherwise nullptr. */
static struct dev_ino *root_dev_ino;
/* The name of the context file is being given. */
@@ -72,20 +70,20 @@ enum
static struct option const long_options[] =
{
{"recursive", no_argument, NULL, 'R'},
{"dereference", no_argument, NULL, DEREFERENCE_OPTION},
{"no-dereference", no_argument, NULL, 'h'},
{"no-preserve-root", no_argument, NULL, NO_PRESERVE_ROOT},
{"preserve-root", no_argument, NULL, PRESERVE_ROOT},
{"reference", required_argument, NULL, REFERENCE_FILE_OPTION},
{"user", required_argument, NULL, 'u'},
{"role", required_argument, NULL, 'r'},
{"type", required_argument, NULL, 't'},
{"range", required_argument, NULL, 'l'},
{"verbose", no_argument, NULL, 'v'},
{"recursive", no_argument, nullptr, 'R'},
{"dereference", no_argument, nullptr, DEREFERENCE_OPTION},
{"no-dereference", no_argument, nullptr, 'h'},
{"no-preserve-root", no_argument, nullptr, NO_PRESERVE_ROOT},
{"preserve-root", no_argument, nullptr, PRESERVE_ROOT},
{"reference", required_argument, nullptr, REFERENCE_FILE_OPTION},
{"user", required_argument, nullptr, 'u'},
{"role", required_argument, nullptr, 'r'},
{"type", required_argument, nullptr, 't'},
{"range", required_argument, nullptr, 'l'},
{"verbose", no_argument, nullptr, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* Given a security context, CONTEXT, derive a context_t (*RET),
@@ -141,12 +139,12 @@ compute_context_from_mask (char const *context, context_t *ret)
static int
change_file_context (int fd, char const *file)
{
char *file_context = NULL;
char *file_context = nullptr;
context_t context IF_LINT (= 0);
char const * context_string;
int errors = 0;
if (specified_context == NULL)
if (specified_context == nullptr)
{
int status = (affect_symlink_referent
? getfileconat (fd, file, &file_context)
@@ -162,7 +160,7 @@ change_file_context (int fd, char const *file)
/* 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. */
if (file_context == NULL)
if (file_context == nullptr)
{
error (0, 0, _("can't apply partial context to unlabeled file %s"),
quoteaf (file));
@@ -179,7 +177,7 @@ change_file_context (int fd, char const *file)
context_string = specified_context;
}
if (file_context == NULL || ! STREQ (context_string, file_context))
if (file_context == nullptr || ! STREQ (context_string, file_context))
{
int fail = (affect_symlink_referent
? setfileconat (fd, file, context_string)
@@ -193,7 +191,7 @@ change_file_context (int fd, char const *file)
}
}
if (specified_context == NULL)
if (specified_context == nullptr)
{
context_free (context);
freecon (file_context);
@@ -305,7 +303,7 @@ process_file (FTS *fts, FTSENT *ent)
}
/* Recursively operate on the specified FILES (the last entry
of which is NULL). BIT_FLAGS controls how fts works.
of which is null). BIT_FLAGS controls how fts works.
Return true if successful. */
static bool
@@ -313,14 +311,14 @@ process_files (char **files, int bit_flags)
{
bool ok = true;
FTS *fts = xfts_open (files, bit_flags, NULL);
FTS *fts = xfts_open (files, bit_flags, nullptr);
while (true)
{
FTSENT *ent;
ent = fts_read (fts);
if (ent == NULL)
if (ent == nullptr)
{
if (errno != 0)
{
@@ -421,7 +419,7 @@ main (int argc, char **argv)
bool ok;
bool preserve_root = false;
bool component_specified = false;
char *reference_file = NULL;
char *reference_file = nullptr;
int optc;
initialize_main (&argc, &argv);
@@ -432,7 +430,8 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, "HLPRhvu:r:t:l:", long_options, NULL))
while ((optc = getopt_long (argc, argv, "HLPRhvu:r:t:l:",
long_options, nullptr))
!= -1)
{
switch (optc)
@@ -514,14 +513,14 @@ main (int argc, char **argv)
if (bit_flags == FTS_PHYSICAL)
{
if (dereference == 1)
die (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
affect_symlink_referent = false;
}
else
{
if (dereference == 0)
die (EXIT_FAILURE, 0, _("-R -h requires -P"));
error (EXIT_FAILURE, 0, _("-R -h requires -P"));
affect_symlink_referent = true;
}
}
@@ -542,26 +541,26 @@ main (int argc, char **argv)
if (reference_file)
{
char *ref_context = NULL;
char *ref_context = nullptr;
if (getfilecon (reference_file, &ref_context) < 0)
die (EXIT_FAILURE, errno, _("failed to get security context of %s"),
quoteaf (reference_file));
error (EXIT_FAILURE, errno, _("failed to get security context of %s"),
quoteaf (reference_file));
specified_context = ref_context;
}
else if (component_specified)
{
/* FIXME: it's already null, so this is a no-op. */
specified_context = NULL;
specified_context = nullptr;
}
else
{
specified_context = argv[optind++];
if (0 < is_selinux_enabled ()
&& security_check_context (specified_context) < 0)
die (EXIT_FAILURE, errno, _("invalid context: %s"),
quote (specified_context));
error (EXIT_FAILURE, errno, _("invalid context: %s"),
quote (specified_context));
}
if (reference_file && component_specified)
@@ -574,13 +573,13 @@ main (int argc, char **argv)
{
static struct dev_ino dev_ino_buf;
root_dev_ino = get_root_dev_ino (&dev_ino_buf);
if (root_dev_ino == NULL)
die (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf ("/"));
if (root_dev_ino == nullptr)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf ("/"));
}
else
{
root_dev_ino = NULL;
root_dev_ino = nullptr;
}
ok = process_files (argv + optind, bit_flags | FTS_NOSTAT);

View File

@@ -24,8 +24,6 @@
#include "system.h"
#include "chown-core.h"
#include "die.h"
#include "error.h"
#include "fts_.h"
#include "quote.h"
#include "root-dev-ino.h"
@@ -58,19 +56,19 @@ enum
static struct option const long_options[] =
{
{"recursive", no_argument, NULL, 'R'},
{"changes", no_argument, NULL, 'c'},
{"dereference", no_argument, NULL, DEREFERENCE_OPTION},
{"no-dereference", no_argument, NULL, 'h'},
{"no-preserve-root", no_argument, NULL, NO_PRESERVE_ROOT},
{"preserve-root", no_argument, NULL, PRESERVE_ROOT},
{"quiet", no_argument, NULL, 'f'},
{"silent", no_argument, NULL, 'f'},
{"reference", required_argument, NULL, REFERENCE_FILE_OPTION},
{"verbose", no_argument, NULL, 'v'},
{"recursive", no_argument, nullptr, 'R'},
{"changes", no_argument, nullptr, 'c'},
{"dereference", no_argument, nullptr, DEREFERENCE_OPTION},
{"no-dereference", no_argument, nullptr, 'h'},
{"no-preserve-root", no_argument, nullptr, NO_PRESERVE_ROOT},
{"preserve-root", no_argument, nullptr, PRESERVE_ROOT},
{"quiet", no_argument, nullptr, 'f'},
{"silent", no_argument, nullptr, 'f'},
{"reference", required_argument, nullptr, REFERENCE_FILE_OPTION},
{"verbose", no_argument, nullptr, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* Return the group ID of NAME, or -1 if no name was specified. */
@@ -88,10 +86,10 @@ parse_group (char const *name)
else
{
uintmax_t tmp;
if (! (xstrtoumax (name, NULL, 10, &tmp, "") == LONGINT_OK
if (! (xstrtoumax (name, nullptr, 10, &tmp, "") == LONGINT_OK
&& tmp <= GID_T_MAX))
die (EXIT_FAILURE, 0, _("invalid group: %s"),
quote (name));
error (EXIT_FAILURE, 0, _("invalid group: %s"),
quote (name));
gid = tmp;
}
endgrent (); /* Save a file descriptor. */
@@ -196,7 +194,7 @@ main (int argc, char **argv)
chopt_init (&chopt);
while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, NULL))
while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, nullptr))
!= -1)
{
switch (optc)
@@ -262,8 +260,8 @@ main (int argc, char **argv)
if (bit_flags == FTS_PHYSICAL)
{
if (dereference == 1)
die (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
dereference = 0;
}
}
@@ -286,8 +284,8 @@ main (int argc, char **argv)
{
struct stat ref_stats;
if (stat (reference_file, &ref_stats))
die (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf (reference_file));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf (reference_file));
gid = ref_stats.st_gid;
chopt.group_name = gid_to_name (ref_stats.st_gid);
@@ -295,7 +293,7 @@ main (int argc, char **argv)
else
{
char *group_name = argv[optind++];
chopt.group_name = (*group_name ? xstrdup (group_name) : NULL);
chopt.group_name = (*group_name ? xstrdup (group_name) : nullptr);
gid = parse_group (group_name);
}
@@ -303,9 +301,9 @@ main (int argc, char **argv)
{
static struct dev_ino dev_ino_buf;
chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
if (chopt.root_dev_ino == NULL)
die (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf ("/"));
if (chopt.root_dev_ino == nullptr)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf ("/"));
}
bit_flags |= FTS_DEFER_STAT;

View File

@@ -22,9 +22,8 @@
#include <sys/types.h>
#include "system.h"
#include "assure.h"
#include "dev-ino.h"
#include "die.h"
#include "error.h"
#include "filemode.h"
#include "ignore-value.h"
#include "modechange.h"
@@ -87,7 +86,7 @@ static bool diagnose_surprises;
static enum Verbosity verbosity = V_off;
/* Pointer to the device and inode numbers of '/', when --recursive.
Otherwise NULL. */
Otherwise nullptr. */
static struct dev_ino *root_dev_ino;
/* For long options that have no equivalent short option, use a
@@ -101,17 +100,17 @@ enum
static struct option const long_options[] =
{
{"changes", no_argument, NULL, 'c'},
{"recursive", no_argument, NULL, 'R'},
{"no-preserve-root", no_argument, NULL, NO_PRESERVE_ROOT},
{"preserve-root", no_argument, NULL, PRESERVE_ROOT},
{"quiet", no_argument, NULL, 'f'},
{"reference", required_argument, NULL, REFERENCE_FILE_OPTION},
{"silent", no_argument, NULL, 'f'},
{"verbose", no_argument, NULL, 'v'},
{"changes", no_argument, nullptr, 'c'},
{"recursive", no_argument, nullptr, 'R'},
{"no-preserve-root", no_argument, nullptr, NO_PRESERVE_ROOT},
{"preserve-root", no_argument, nullptr, PRESERVE_ROOT},
{"quiet", no_argument, nullptr, 'f'},
{"reference", required_argument, nullptr, REFERENCE_FILE_OPTION},
{"silent", no_argument, nullptr, 'f'},
{"verbose", no_argument, nullptr, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* Return true if the chmodable permission bits of FILE changed.
@@ -191,7 +190,7 @@ describe_change (char const *file, struct change_status const *ch)
printf (fmt, quoted_file, m, &perms[1]);
return;
default:
abort ();
affirm (false);
}
printf (fmt, quoted_file, old_m, &old_perms[1], m, &perms[1]);
}
@@ -277,7 +276,7 @@ process_file (FTS *fts, FTSENT *ent)
{
ch.old_mode = file_stats->st_mode;
ch.new_mode = mode_adjust (ch.old_mode, S_ISDIR (ch.old_mode) != 0,
umask_value, change, NULL);
umask_value, change, nullptr);
if (chmodat (fts->fts_cwd_fd, file, ch.new_mode) == 0)
ch.status = CH_SUCCEEDED;
else
@@ -303,7 +302,8 @@ process_file (FTS *fts, FTSENT *ent)
if (CH_NO_CHANGE_REQUESTED <= ch.status && diagnose_surprises)
{
mode_t naively_expected_mode =
mode_adjust (ch.old_mode, S_ISDIR (ch.old_mode) != 0, 0, change, NULL);
mode_adjust (ch.old_mode, S_ISDIR (ch.old_mode) != 0,
0, change, nullptr);
if (ch.new_mode & ~naively_expected_mode)
{
char new_perms[12];
@@ -326,7 +326,7 @@ process_file (FTS *fts, FTSENT *ent)
}
/* Recursively change the modes of the specified FILES (the last entry
of which is NULL). BIT_FLAGS controls how fts works.
of which is null). BIT_FLAGS controls how fts works.
Return true if successful. */
static bool
@@ -334,14 +334,14 @@ process_files (char **files, int bit_flags)
{
bool ok = true;
FTS *fts = xfts_open (files, bit_flags, NULL);
FTS *fts = xfts_open (files, bit_flags, nullptr);
while (true)
{
FTSENT *ent;
ent = fts_read (fts);
if (ent == NULL)
if (ent == nullptr)
{
if (errno != 0)
{
@@ -416,12 +416,12 @@ Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+'.\n\
int
main (int argc, char **argv)
{
char *mode = NULL;
size_t mode_len = 0;
size_t mode_alloc = 0;
char *mode = nullptr;
idx_t mode_len = 0;
idx_t mode_alloc = 0;
bool ok;
bool preserve_root = false;
char const *reference_file = NULL;
char const *reference_file = nullptr;
int c;
initialize_main (&argc, &argv);
@@ -437,7 +437,7 @@ main (int argc, char **argv)
while ((c = getopt_long (argc, argv,
("Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"
"0::1::2::3::4::5::6::7::"),
long_options, NULL))
long_options, nullptr))
!= -1)
{
switch (c)
@@ -457,7 +457,7 @@ main (int argc, char **argv)
case '=':
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
/* Support nonportable uses like "chmod -w", but diagnose
/* Support non-portable 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. */
@@ -468,14 +468,13 @@ main (int argc, char **argv)
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;
idx_t arg_len = strlen (arg);
idx_t mode_comma_len = mode_len + !!mode_len;
idx_t new_mode_len = mode_comma_len + arg_len;
assume (0 <= new_mode_len); /* Pacify GCC bug #109613. */
if (mode_alloc <= new_mode_len)
{
mode_alloc = new_mode_len + 1;
mode = X2REALLOC (mode, &mode_alloc);
}
mode = xpalloc (mode, &mode_alloc,
new_mode_len + 1 - mode_alloc, -1, 1);
mode[mode_len] = ',';
memcpy (mode + mode_comma_len, arg, arg_len + 1);
mode_len = new_mode_len;
@@ -538,8 +537,8 @@ main (int argc, char **argv)
{
change = mode_create_from_ref (reference_file);
if (!change)
die (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf (reference_file));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf (reference_file));
}
else
{
@@ -556,13 +555,13 @@ main (int argc, char **argv)
{
static struct dev_ino dev_ino_buf;
root_dev_ino = get_root_dev_ino (&dev_ino_buf);
if (root_dev_ino == NULL)
die (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf ("/"));
if (root_dev_ino == nullptr)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf ("/"));
}
else
{
root_dev_ino = NULL;
root_dev_ino = nullptr;
}
ok = process_files (argv + optind,

View File

@@ -23,8 +23,8 @@
#include <grp.h>
#include "system.h"
#include "assure.h"
#include "chown-core.h"
#include "error.h"
#include "ignore-value.h"
#include "root-dev-ino.h"
#include "xfts.h"
@@ -58,12 +58,12 @@ extern void
chopt_init (struct Chown_option *chopt)
{
chopt->verbosity = V_off;
chopt->root_dev_ino = NULL;
chopt->root_dev_ino = nullptr;
chopt->affect_symlink_referent = true;
chopt->recurse = false;
chopt->force_silent = false;
chopt->user_name = NULL;
chopt->group_name = NULL;
chopt->user_name = nullptr;
chopt->group_name = nullptr;
}
extern void
@@ -122,7 +122,7 @@ uid_to_name (uid_t uid)
static char *
user_group_str (char const *user, char const *group)
{
char *spec = NULL;
char *spec = nullptr;
if (user)
{
@@ -145,7 +145,7 @@ user_group_str (char const *user, char const *group)
}
/* Tell the user how/if the user and group of FILE have been changed.
If USER is NULL, give the group-oriented messages.
If USER is null, give the group-oriented messages.
CHANGED describes what (if anything) has happened. */
static void
@@ -165,7 +165,8 @@ describe_change (char const *file, enum Change_status changed,
}
spec = user_group_str (user, group);
old_spec = user_group_str (user ? old_user : NULL, group ? old_group : NULL);
old_spec = user_group_str (user ? old_user : nullptr,
group ? old_group : nullptr);
switch (changed)
{
@@ -188,7 +189,7 @@ describe_change (char const *file, enum Change_status changed,
: _("failed to change ownership of %s\n"));
free (old_spec);
old_spec = spec;
spec = NULL;
spec = nullptr;
}
break;
case CH_NO_CHANGE_REQUESTED:
@@ -197,7 +198,7 @@ describe_change (char const *file, enum Change_status changed,
: _("ownership of %s retained\n"));
break;
default:
abort ();
affirm (false);
}
printf (fmt, quoteaf (file), old_spec, spec);
@@ -370,7 +371,7 @@ change_file_owner (FTS *fts, FTSENT *ent,
if (!ok)
{
do_chown = false;
file_stats = NULL;
file_stats = nullptr;
}
else if (required_uid == (uid_t) -1 && required_gid == (gid_t) -1
&& chopt->verbosity == V_off
@@ -466,7 +467,7 @@ change_file_owner (FTS *fts, FTSENT *ent,
break;
default:
abort ();
unreachable ();
}
}
@@ -498,14 +499,16 @@ change_file_owner (FTS *fts, FTSENT *ent,
: !symlink_changed ? CH_NOT_APPLIED
: !changed ? CH_NO_CHANGE_REQUESTED
: CH_SUCCEEDED);
char *old_usr = file_stats ? uid_to_name (file_stats->st_uid) : NULL;
char *old_grp = file_stats ? gid_to_name (file_stats->st_gid) : NULL;
char *old_usr = (file_stats
? uid_to_name (file_stats->st_uid) : nullptr);
char *old_grp = (file_stats
? gid_to_name (file_stats->st_gid) : nullptr);
char *new_usr = chopt->user_name
? chopt->user_name : uid != -1
? uid_to_str (uid) : NULL;
? uid_to_str (uid) : nullptr;
char *new_grp = chopt->group_name
? chopt->group_name : gid != -1
? gid_to_str (gid) : NULL;
? gid_to_str (gid) : nullptr;
describe_change (file_full_name, ch_status,
old_usr, old_grp,
new_usr, new_grp);
@@ -548,14 +551,14 @@ chown_files (char **files, int bit_flags,
? 0
: FTS_NOSTAT);
FTS *fts = xfts_open (files, bit_flags | stat_flags, NULL);
FTS *fts = xfts_open (files, bit_flags | stat_flags, nullptr);
while (true)
{
FTSENT *ent;
ent = fts_read (fts);
if (ent == NULL)
if (ent == nullptr)
{
if (errno != 0)
{

View File

@@ -50,7 +50,7 @@ struct Chown_option
bool recurse;
/* Pointer to the device and inode numbers of '/', when --recursive.
Need not be freed. Otherwise NULL. */
Need not be freed. Otherwise nullptr. */
struct dev_ino *root_dev_ino;
/* This corresponds to the --dereference (opposite of -h) option. */

View File

@@ -23,8 +23,6 @@
#include "system.h"
#include "chown-core.h"
#include "die.h"
#include "error.h"
#include "fts_.h"
#include "quote.h"
#include "root-dev-ino.h"
@@ -54,20 +52,20 @@ enum
static struct option const long_options[] =
{
{"recursive", no_argument, NULL, 'R'},
{"changes", no_argument, NULL, 'c'},
{"dereference", no_argument, NULL, DEREFERENCE_OPTION},
{"from", required_argument, NULL, FROM_OPTION},
{"no-dereference", no_argument, NULL, 'h'},
{"no-preserve-root", no_argument, NULL, NO_PRESERVE_ROOT},
{"preserve-root", no_argument, NULL, PRESERVE_ROOT},
{"quiet", no_argument, NULL, 'f'},
{"silent", no_argument, NULL, 'f'},
{"reference", required_argument, NULL, REFERENCE_FILE_OPTION},
{"verbose", no_argument, NULL, 'v'},
{"recursive", no_argument, nullptr, 'R'},
{"changes", no_argument, nullptr, 'c'},
{"dereference", no_argument, nullptr, DEREFERENCE_OPTION},
{"from", required_argument, nullptr, FROM_OPTION},
{"no-dereference", no_argument, nullptr, 'h'},
{"no-preserve-root", no_argument, nullptr, NO_PRESERVE_ROOT},
{"preserve-root", no_argument, nullptr, PRESERVE_ROOT},
{"quiet", no_argument, nullptr, 'f'},
{"silent", no_argument, nullptr, 'f'},
{"reference", required_argument, nullptr, REFERENCE_FILE_OPTION},
{"verbose", no_argument, nullptr, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -187,7 +185,7 @@ main (int argc, char **argv)
chopt_init (&chopt);
while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, NULL))
while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, nullptr))
!= -1)
{
switch (optc)
@@ -230,7 +228,7 @@ main (int argc, char **argv)
bool warn;
char const *e = parse_user_spec_warn (optarg,
&required_uid, &required_gid,
NULL, NULL, &warn);
nullptr, nullptr, &warn);
if (e)
error (warn ? 0 : EXIT_FAILURE, 0, "%s: %s", e, quote (optarg));
break;
@@ -264,8 +262,8 @@ main (int argc, char **argv)
if (bit_flags == FTS_PHYSICAL)
{
if (dereference == 1)
die (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
error (EXIT_FAILURE, 0,
_("-R --dereference requires either -H or -L"));
dereference = 0;
}
}
@@ -288,8 +286,8 @@ main (int argc, char **argv)
{
struct stat ref_stats;
if (stat (reference_file, &ref_stats))
die (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf (reference_file));
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf (reference_file));
uid = ref_stats.st_uid;
gid = ref_stats.st_gid;
@@ -318,9 +316,9 @@ main (int argc, char **argv)
{
static struct dev_ino dev_ino_buf;
chopt.root_dev_ino = get_root_dev_ino (&dev_ino_buf);
if (chopt.root_dev_ino == NULL)
die (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf ("/"));
if (chopt.root_dev_ino == nullptr)
error (EXIT_FAILURE, errno, _("failed to get attributes of %s"),
quoteaf ("/"));
}
bit_flags |= FTS_DEFER_STAT;

View File

@@ -24,8 +24,6 @@
#include <grp.h>
#include "system.h"
#include "die.h"
#include "error.h"
#include "ignore-value.h"
#include "mgetgroups.h"
#include "quote.h"
@@ -56,12 +54,12 @@ enum
static struct option const long_opts[] =
{
{"groups", required_argument, NULL, GROUPS},
{"userspec", required_argument, NULL, USERSPEC},
{"skip-chdir", no_argument, NULL, SKIP_CHDIR},
{"groups", required_argument, nullptr, GROUPS},
{"userspec", required_argument, nullptr, USERSPEC},
{"skip-chdir", no_argument, nullptr, SKIP_CHDIR},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
#if ! HAVE_SETGROUPS
@@ -96,19 +94,19 @@ static int
parse_additional_groups (char const *groups, GETGROUPS_T **pgids,
size_t *pn_gids, bool show_errors)
{
GETGROUPS_T *gids = NULL;
GETGROUPS_T *gids = nullptr;
size_t n_gids_allocated = 0;
size_t n_gids = 0;
char *buffer = xstrdup (groups);
char const *tmp;
int ret = 0;
for (tmp = strtok (buffer, ","); tmp; tmp = strtok (NULL, ","))
for (tmp = strtok (buffer, ","); tmp; tmp = strtok (nullptr, ","))
{
struct group *g;
uintmax_t value;
if (xstrtoumax (tmp, NULL, 10, &value, "") == LONGINT_OK
if (xstrtoumax (tmp, nullptr, 10, &value, "") == LONGINT_OK
&& value <= MAXGID)
{
while (isspace (to_uchar (*tmp)))
@@ -117,20 +115,20 @@ parse_additional_groups (char const *groups, GETGROUPS_T **pgids,
{
/* Handle the case where the name is numeric. */
g = getgrnam (tmp);
if (g != NULL)
if (g != nullptr)
value = g->gr_gid;
}
/* Flag that we've got a group from the number. */
g = (struct group *) (intptr_t) ! NULL;
g = (struct group *) (intptr_t) ! nullptr;
}
else
{
g = getgrnam (tmp);
if (g != NULL)
if (g != nullptr)
value = g->gr_gid;
}
if (g == NULL)
if (g == nullptr)
{
ret = -1;
@@ -222,15 +220,15 @@ main (int argc, char **argv)
int c;
/* Input user and groups spec. */
char *userspec = NULL;
char const *username = NULL;
char const *groups = NULL;
char *userspec = nullptr;
char const *username = nullptr;
char const *groups = nullptr;
bool skip_chdir = false;
/* Parsed user and group IDs. */
uid_t uid = -1;
gid_t gid = -1;
GETGROUPS_T *out_gids = NULL;
GETGROUPS_T *out_gids = nullptr;
size_t n_gids = 0;
initialize_main (&argc, &argv);
@@ -242,7 +240,7 @@ main (int argc, char **argv)
initialize_exit_failure (EXIT_CANCELED);
atexit (close_stdout);
while ((c = getopt_long (argc, argv, "+", long_opts, NULL)) != -1)
while ((c = getopt_long (argc, argv, "+", long_opts, nullptr)) != -1)
{
switch (c)
{
@@ -300,7 +298,7 @@ main (int argc, char **argv)
Within chroot lookup is the main justification for having
the --user option supported by the chroot command itself. */
if (userspec)
ignore_value (parse_user_spec (userspec, &uid, &gid, NULL, NULL));
ignore_value (parse_user_spec (userspec, &uid, &gid, nullptr, nullptr));
/* If no gid is supplied or looked up, do so now.
Also lookup the username for use with getgroups. */
@@ -329,21 +327,21 @@ main (int argc, char **argv)
}
if (chroot (newroot) != 0)
die (EXIT_CANCELED, errno, _("cannot change root directory to %s"),
quoteaf (newroot));
error (EXIT_CANCELED, errno, _("cannot change root directory to %s"),
quoteaf (newroot));
if (! skip_chdir && chdir ("/"))
die (EXIT_CANCELED, errno, _("cannot chdir to root directory"));
error (EXIT_CANCELED, errno, _("cannot chdir to root directory"));
if (argc == optind + 1)
{
/* No command. Run an interactive shell. */
char *shell = getenv ("SHELL");
if (shell == NULL)
if (shell == nullptr)
shell = bad_cast ("/bin/sh");
argv[0] = shell;
argv[1] = bad_cast ("-i");
argv[2] = NULL;
argv[2] = nullptr;
}
else
{
@@ -357,7 +355,7 @@ main (int argc, char **argv)
{
bool warn;
char const *err = parse_user_spec_warn (userspec, &uid, &gid,
NULL, NULL, &warn);
nullptr, nullptr, &warn);
if (err)
error (warn ? 0 : EXIT_CANCELED, 0, "%s", (err));
}
@@ -375,13 +373,13 @@ main (int argc, char **argv)
}
else if (gid_unset (gid))
{
die (EXIT_CANCELED, errno,
_("no group specified for unknown uid: %d"), (int) uid);
error (EXIT_CANCELED, errno,
_("no group specified for unknown uid: %d"), (int) uid);
}
}
GETGROUPS_T *gids = out_gids;
GETGROUPS_T *in_gids = NULL;
GETGROUPS_T *in_gids = nullptr;
if (groups && *groups)
{
if (parse_additional_groups (groups, &in_gids, &n_gids, !n_gids) != 0)
@@ -400,8 +398,8 @@ main (int argc, char **argv)
if (ngroups <= 0)
{
if (! n_gids)
die (EXIT_CANCELED, errno,
_("failed to get supplemental groups"));
error (EXIT_CANCELED, errno,
_("failed to get supplemental groups"));
/* else look-up outside the chroot worked, then go with those. */
}
else
@@ -413,16 +411,16 @@ main (int argc, char **argv)
#endif
if ((uid_set (uid) || groups) && setgroups (n_gids, gids) != 0)
die (EXIT_CANCELED, errno, _("failed to set supplemental groups"));
error (EXIT_CANCELED, errno, _("failed to set supplemental groups"));
free (in_gids);
free (out_gids);
if (gid_set (gid) && setgid (gid))
die (EXIT_CANCELED, errno, _("failed to set group-ID"));
error (EXIT_CANCELED, errno, _("failed to set group-ID"));
if (uid_set (uid) && setuid (uid))
die (EXIT_CANCELED, errno, _("failed to set user-ID"));
error (EXIT_CANCELED, errno, _("failed to set user-ID"));
/* Execute the given command. */
execvp (argv[0], argv);

View File

@@ -109,15 +109,16 @@ main (void)
uint32_t crc = 0;
crc = (crc << 8) ^ crctab[0][((crc >> 24) ^ (i & 0xFF)) & 0xFF];
for (unsigned int offset = 1; offset < 8; offset++)
for (idx_t offset = 1; offset < 8; offset++)
{
crc = (crc << 8) ^ crctab[0][((crc >> 24) ^ 0x00) & 0xFF];
crctab[offset][i] = crc;
}
}
printf ("#include <stdint.h>\n\n");
printf ("uint_fast32_t const crctab[8][256] = {\n");
printf ("#include <config.h>\n");
printf ("#include <stdint.h>\n");
printf ("\nuint_fast32_t const crctab[8][256] = {\n");
for (int y = 0; y < 8; y++)
{
printf ("{\n 0x%08x", crctab[y][0]);
@@ -136,58 +137,27 @@ main (void)
#else /* !CRCTAB */
# include "die.h"
# include "error.h"
# include "cksum.h"
# if USE_PCLMUL_CRC32
# include "cpuid.h"
# else
# define cksum_pclmul cksum_slice8
# endif /* USE_PCLMUL_CRC32 */
/* Number of bytes to read at once. */
# define BUFLEN (1 << 16)
static bool
cksum_slice8 (FILE *fp, uint_fast32_t *crc_out, uintmax_t *length_out);
static bool
(*cksum_fp)(FILE *, uint_fast32_t *, uintmax_t *);
# if USE_PCLMUL_CRC32
static bool
pclmul_supported (void)
{
# if USE_PCLMUL_CRC32
unsigned int eax = 0;
unsigned int ebx = 0;
unsigned int ecx = 0;
unsigned int edx = 0;
if (! __get_cpuid (1, &eax, &ebx, &ecx, &edx))
{
if (cksum_debug)
error (0, 0, "%s", _("failed to get cpuid"));
return false;
}
if (! (ecx & bit_PCLMUL) || ! (ecx & bit_AVX))
{
if (cksum_debug)
error (0, 0, "%s", _("pclmul support not detected"));
return false;
}
bool pclmul_enabled = (0 < __builtin_cpu_supports ("pclmul")
&& 0 < __builtin_cpu_supports ("avx"));
if (cksum_debug)
error (0, 0, "%s", _("using pclmul hardware support"));
error (0, 0, "%s",
(pclmul_enabled
? _("using pclmul hardware support")
: _("pclmul support not detected")));
return true;
# else
if (cksum_debug)
error (0, 0, "%s", _("using generic hardware support"));
return false;
# endif /* USE_PCLMUL_CRC32 */
return pclmul_enabled;
}
# endif /* USE_PCLMUL_CRC32 */
static bool
cksum_slice8 (FILE *fp, uint_fast32_t *crc_out, uintmax_t *length_out)
@@ -211,12 +181,6 @@ cksum_slice8 (FILE *fp, uint_fast32_t *crc_out, uintmax_t *length_out)
}
length += bytes_read;
if (bytes_read == 0)
{
if (ferror (fp))
return false;
}
/* Process multiples of 8 bytes */
datap = (uint32_t *)buf;
while (bytes_read >= 8)
@@ -246,7 +210,7 @@ cksum_slice8 (FILE *fp, uint_fast32_t *crc_out, uintmax_t *length_out)
*crc_out = crc;
*length_out = length;
return true;
return !ferror (fp);
}
/* Calculate the checksum and length in bytes of stream STREAM.
@@ -258,13 +222,13 @@ crc_sum_stream (FILE *stream, void *resstream, uintmax_t *length)
uintmax_t total_bytes = 0;
uint_fast32_t crc = 0;
# if USE_PCLMUL_CRC32
static bool (*cksum_fp) (FILE *, uint_fast32_t *, uintmax_t *);
if (! cksum_fp)
{
if (pclmul_supported ())
cksum_fp = cksum_pclmul;
else
cksum_fp = cksum_slice8;
}
cksum_fp = pclmul_supported () ? cksum_pclmul : cksum_slice8;
# else
bool (*cksum_fp) (FILE *, uint_fast32_t *, uintmax_t *) = cksum_slice8;
# endif
if (! cksum_fp (stream, &crc, &total_bytes))
return -1;

View File

@@ -77,12 +77,6 @@ cksum_pclmul (FILE *fp, uint_fast32_t *crc_out, uintmax_t *length_out)
}
length += bytes_read;
if (bytes_read == 0)
{
if (ferror (fp))
return false;
}
datap = (__m128i *)buf;
/* Fold in parallel eight 16-byte blocks into four 16-byte blocks */
@@ -191,5 +185,5 @@ cksum_pclmul (FILE *fp, uint_fast32_t *crc_out, uintmax_t *length_out)
*crc_out = crc;
*length_out = length;
return true;
return !ferror (fp);
}

View File

@@ -22,8 +22,6 @@
#include <sys/types.h>
#include "system.h"
#include "linebuffer.h"
#include "die.h"
#include "error.h"
#include "fadvise.h"
#include "hard-locale.h"
#include "quote.h"
@@ -91,14 +89,14 @@ enum
static struct option const long_options[] =
{
{"check-order", no_argument, NULL, CHECK_ORDER_OPTION},
{"nocheck-order", no_argument, NULL, NOCHECK_ORDER_OPTION},
{"output-delimiter", required_argument, NULL, OUTPUT_DELIMITER_OPTION},
{"total", no_argument, NULL, TOTAL_OPTION},
{"zero-terminated", no_argument, NULL, 'z'},
{"check-order", no_argument, nullptr, CHECK_ORDER_OPTION},
{"nocheck-order", no_argument, nullptr, NOCHECK_ORDER_OPTION},
{"output-delimiter", required_argument, nullptr, OUTPUT_DELIMITER_OPTION},
{"total", no_argument, nullptr, TOTAL_OPTION},
{"zero-terminated", no_argument, nullptr, 'z'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
@@ -165,13 +163,13 @@ Examples:\n\
exit (status);
}
/* Output the line in linebuffer LINE to stream STREAM
/* Output the line in linebuffer LINE to stdout
provided the switches say it should be output.
CLASS is 1 for a line found only in file 1,
2 for a line only in file 2, 3 for a line in both. */
static void
writeline (struct linebuffer const *line, FILE *stream, int class)
writeline (struct linebuffer const *line, int class)
{
switch (class)
{
@@ -184,20 +182,23 @@ writeline (struct linebuffer const *line, FILE *stream, int class)
if (!only_file_2)
return;
if (only_file_1)
fwrite (col_sep, 1, col_sep_len, stream);
fwrite (col_sep, 1, col_sep_len, stdout);
break;
case 3:
if (!both)
return;
if (only_file_1)
fwrite (col_sep, 1, col_sep_len, stream);
fwrite (col_sep, 1, col_sep_len, stdout);
if (only_file_2)
fwrite (col_sep, 1, col_sep_len, stream);
fwrite (col_sep, 1, col_sep_len, stdout);
break;
}
fwrite (line->buffer, sizeof (char), line->length, stream);
fwrite (line->buffer, sizeof (char), line->length, stdout);
if (ferror (stdout))
write_error ();
}
/* Check that successive input lines PREV and CURRENT from input file
@@ -258,7 +259,7 @@ compare_files (char **infiles)
struct linebuffer lba[2][4];
/* thisline[i] points to the linebuffer holding the next available line
in file i, or is NULL if there are no lines left in that file. */
in file i, or is null if there are no lines left in that file. */
struct linebuffer *thisline[2];
/* all_line[i][alt[i][0]] also points to the linebuffer holding the
@@ -290,14 +291,14 @@ compare_files (char **infiles)
alt[i][2] = 0;
streams[i] = (STREQ (infiles[i], "-") ? stdin : fopen (infiles[i], "r"));
if (!streams[i])
die (EXIT_FAILURE, errno, "%s", quotef (infiles[i]));
error (EXIT_FAILURE, errno, "%s", quotef (infiles[i]));
fadvise (streams[i], FADVISE_SEQUENTIAL);
thisline[i] = readlinebuffer_delim (all_line[i][alt[i][0]], streams[i],
delim);
if (ferror (streams[i]))
die (EXIT_FAILURE, errno, "%s", quotef (infiles[i]));
error (EXIT_FAILURE, errno, "%s", quotef (infiles[i]));
}
while (thisline[0] || thisline[1])
@@ -331,7 +332,7 @@ compare_files (char **infiles)
{
/* Line is seen in both files. */
total[2]++;
writeline (thisline[1], stdout, 3);
writeline (thisline[1], 3);
}
else
{
@@ -340,13 +341,13 @@ compare_files (char **infiles)
{
/* Line is seen in file 1 only. */
total[0]++;
writeline (thisline[0], stdout, 1);
writeline (thisline[0], 1);
}
else
{
/* Line is seen in file 2 only. */
total[1]++;
writeline (thisline[1], stdout, 2);
writeline (thisline[1], 2);
}
}
@@ -379,7 +380,7 @@ compare_files (char **infiles)
all_line[i][alt[i][1]], i + 1);
if (ferror (streams[i]))
die (EXIT_FAILURE, errno, "%s", quotef (infiles[i]));
error (EXIT_FAILURE, errno, "%s", quotef (infiles[i]));
fill_up[i] = false;
}
@@ -387,7 +388,7 @@ compare_files (char **infiles)
for (i = 0; i < 2; i++)
if (fclose (streams[i]) != 0)
die (EXIT_FAILURE, errno, "%s", quotef (infiles[i]));
error (EXIT_FAILURE, errno, "%s", quotef (infiles[i]));
if (total_option)
{
@@ -414,7 +415,7 @@ compare_files (char **infiles)
}
if (issued_disorder_warning[0] || issued_disorder_warning[1])
die (EXIT_FAILURE, 0, _("input is not in sorted order"));
error (EXIT_FAILURE, 0, _("input is not in sorted order"));
/* Exit here to pacify gcc -fsanitizer=leak. */
exit (EXIT_SUCCESS);
@@ -443,7 +444,7 @@ main (int argc, char **argv)
check_input_order = CHECK_ORDER_DEFAULT;
total_option = false;
while ((c = getopt_long (argc, argv, "123z", long_options, NULL)) != -1)
while ((c = getopt_long (argc, argv, "123z", long_options, nullptr)) != -1)
switch (c)
{
case '1':
@@ -472,7 +473,7 @@ main (int argc, char **argv)
case OUTPUT_DELIMITER_OPTION:
if (col_sep_len && !STREQ (col_sep, optarg))
die (EXIT_FAILURE, 0, _("multiple output delimiters specified"));
error (EXIT_FAILURE, 0, _("multiple output delimiters specified"));
col_sep = optarg;
col_sep_len = *optarg ? strlen (optarg) : 1;
break;

View File

@@ -17,8 +17,8 @@
/* Extracted from cp.c and librarified by Jim Meyering. */
#include <config.h>
#include <stdckdint.h>
#include <stdio.h>
#include <assert.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <selinux/selinux.h>
@@ -33,13 +33,12 @@
#include "system.h"
#include "acl.h"
#include "alignalloc.h"
#include "assure.h"
#include "backupfile.h"
#include "buffer-lcm.h"
#include "canonicalize.h"
#include "copy.h"
#include "cp-hash.h"
#include "die.h"
#include "error.h"
#include "fadvise.h"
#include "fcntl--.h"
#include "file-set.h"
@@ -146,6 +145,7 @@ enum copy_debug_val
COPY_DEBUG_NO,
COPY_DEBUG_YES,
COPY_DEBUG_EXTERNAL,
COPY_DEBUG_EXTERNAL_INTERNAL,
COPY_DEBUG_AVOIDED,
COPY_DEBUG_UNSUPPORTED,
};
@@ -179,6 +179,7 @@ copy_debug_sparse_string (enum copy_debug_val debug_val)
case COPY_DEBUG_NO: return "no";
case COPY_DEBUG_YES: return "zeros";
case COPY_DEBUG_EXTERNAL: return "SEEK_HOLE";
case COPY_DEBUG_EXTERNAL_INTERNAL: return "SEEK_HOLE + zeros";
default: return "unknown";
}
}
@@ -278,15 +279,28 @@ create_hole (int fd, char const *name, bool punch_holes, off_t size)
}
/* Whether the errno from FICLONE, or copy_file_range
indicates operation is not supported for this file or file system. */
/* Whether an errno value ERR, set by FICLONE or copy_file_range,
indicates that the copying operation has terminally failed, even
though it was invoked correctly (so that, e.g, EBADF cannot occur)
and even though !is_CLONENOTSUP (ERR). */
static bool
is_terminal_error (int err)
{
return err == EIO || err == ENOMEM || err == ENOSPC || err == EDQUOT;
}
/* Similarly, whether ERR indicates that the copying operation is not
supported or allowed for this file or process, even though the
operation was invoked correctly. */
static bool
is_CLONENOTSUP (int err)
{
return err == ENOSYS || is_ENOTSUP (err)
return err == ENOSYS || err == ENOTTY || is_ENOTSUP (err)
|| err == EINVAL || err == EBADF
|| err == EXDEV || err == ETXTBSY;
|| err == EXDEV || err == ETXTBSY
|| err == EPERM || err == EACCES;
}
@@ -312,6 +326,8 @@ sparse_copy (int src_fd, int dest_fd, char **abuf, size_t buf_size,
if (copy_debug.sparse_detection == COPY_DEBUG_UNKNOWN)
copy_debug.sparse_detection = hole_size ? COPY_DEBUG_YES : COPY_DEBUG_NO;
else if (hole_size && copy_debug.sparse_detection == COPY_DEBUG_EXTERNAL)
copy_debug.sparse_detection = COPY_DEBUG_EXTERNAL_INTERNAL;
/* If not looking for holes, use copy_file_range if functional,
but don't use if reflink disallowed as that may be implicit. */
@@ -322,7 +338,7 @@ sparse_copy (int src_fd, int dest_fd, char **abuf, size_t buf_size,
(SSIZE_MAX, SIZE_MAX) truncated to a value that is
surely aligned well. */
ssize_t copy_max = MIN (SSIZE_MAX, SIZE_MAX) >> 30 << 30;
ssize_t n_copied = copy_file_range (src_fd, NULL, dest_fd, NULL,
ssize_t n_copied = copy_file_range (src_fd, nullptr, dest_fd, nullptr,
MIN (max_n_read, copy_max), 0);
if (n_copied == 0)
{
@@ -339,20 +355,18 @@ sparse_copy (int src_fd, int dest_fd, char **abuf, size_t buf_size,
{
copy_debug.offload = COPY_DEBUG_UNSUPPORTED;
if (is_CLONENOTSUP (errno))
break;
/* copy_file_range might not be enabled in seccomp filters,
so retry with a standard copy. EPERM can also occur
for immutable files, but that would only be in the edge case
where the file is made immutable after creating/truncating,
/* Consider operation unsupported only if no data copied.
For example, EPERM could occur if copy_file_range not enabled
in seccomp filters, so retry with a standard copy. EPERM can
also occur for immutable files, but that would only be in the
edge case where the file is made immutable after creating,
in which case the (more accurate) error is still shown. */
if (errno == EPERM && *total_n_read == 0)
if (*total_n_read == 0 && is_CLONENOTSUP (errno))
break;
/* ENOENT was seen sometimes across CIFS shares, resulting in
no data being copied, but subsequent standard copies succeed. */
if (errno == ENOENT && *total_n_read == 0)
if (*total_n_read == 0 && errno == ENOENT)
break;
if (errno == EINTR)
@@ -445,7 +459,7 @@ sparse_copy (int src_fd, int dest_fd, char **abuf, size_t buf_size,
}
else /* Coalesce writes/seeks. */
{
if (INT_ADD_WRAPV (psize, csize, &psize))
if (ckd_add (&psize, psize, csize))
{
error (0, 0, _("overflow reading %s"), quoteaf (src_name));
return false;
@@ -498,11 +512,11 @@ write_zeros (int fd, off_t n_bytes)
/* Attempt to use a relatively large calloc'd source buffer for
efficiency, but if that allocation fails, resort to a smaller
statically allocated one. */
if (zeros == NULL)
if (zeros == nullptr)
{
static char fallback[1024];
zeros = calloc (nz, 1);
if (zeros == NULL)
if (zeros == nullptr)
{
zeros = fallback;
nz = sizeof fallback;
@@ -755,7 +769,7 @@ copy_attr (char const *src_path, int src_fd,
bool some_errors = (!all_errors && !x->reduce_diagnostics);
int (*check) (char const *, struct error_context *)
= (x->preserve_security_context || x->set_security_context
? check_selinux_attr : NULL);
? check_selinux_attr : nullptr);
# if 4 < __GNUC__ + (8 <= __GNUC_MINOR__)
/* Pacify gcc -Wsuggest-attribute=format through at least GCC 11.2.1. */
@@ -769,7 +783,7 @@ copy_attr (char const *src_path, int src_fd,
.quote = copy_attr_quote,
.quote_free = copy_attr_free
})
: NULL);
: nullptr);
# if 4 < __GNUC__ + (8 <= __GNUC_MINOR__)
# pragma GCC diagnostic pop
# endif
@@ -818,7 +832,7 @@ copy_dir (char const *src_name_in, char const *dst_name_in,
bool ok = true;
name_space = savedir (src_name_in, SAVEDIR_SORT_FASTREAD);
if (name_space == NULL)
if (name_space == nullptr)
{
/* This diagnostic is a bit vague because savedir can fail in
several different ways. */
@@ -836,8 +850,8 @@ copy_dir (char const *src_name_in, char const *dst_name_in,
while (*namep != '\0')
{
bool local_copy_into_self;
char *src_name = file_name_concat (src_name_in, namep, NULL);
char *dst_name = file_name_concat (dst_name_in, namep, NULL);
char *src_name = file_name_concat (src_name_in, namep, nullptr);
char *dst_name = file_name_concat (dst_name_in, namep, nullptr);
bool first_dir_created = *first_dir_created_per_command_line_arg;
bool rename_succeeded;
@@ -1125,6 +1139,8 @@ infer_scantype (int fd, struct stat const *sb,
{
scan_inference->ext_start = -1; /* avoid -Wmaybe-uninitialized */
/* Only attempt SEEK_HOLE if this heuristic
suggests the file is sparse. */
if (! (HAVE_STRUCT_STAT_ST_BLOCKS
&& S_ISREG (sb->st_mode)
&& ST_NBLOCKS (*sb) < sb->st_size / ST_NBLOCKSIZE))
@@ -1168,21 +1184,18 @@ fd_has_acl (int fd)
Return FALSE if it's a terminal failure for this file. */
static bool
handle_clone_fail (int dst_dirfd, char const* dst_relname,
char const* src_name, char const* dst_name,
handle_clone_fail (int dst_dirfd, char const *dst_relname,
char const *src_name, char const *dst_name,
int dest_desc, bool new_dst, enum Reflink_type reflink_mode)
{
/* If the clone operation is creating the destination,
then don't try and cater for all non transient file system errors,
and instead only cater for specific transient errors. */
bool transient_failure;
if (dest_desc < 0) /* currently for fclonefileat(). */
transient_failure = errno == EIO || errno == ENOMEM
|| errno == ENOSPC || errno == EDQUOT;
else /* currently for FICLONE. */
transient_failure = ! is_CLONENOTSUP (errno);
/* When the clone operation fails, report failure only with errno values
known to mean trouble when the clone is supported and called properly.
Do not report failure merely because !is_CLONENOTSUP (errno),
as systems may yield oddball errno values here with FICLONE,
and is_CLONENOTSUP is not appropriate for fclonefileat. */
bool report_failure = is_terminal_error (errno);
if (reflink_mode == REFLINK_ALWAYS || transient_failure)
if (reflink_mode == REFLINK_ALWAYS || report_failure)
error (0, errno, _("failed to clone %s from %s"),
quoteaf_n (0, dst_name), quoteaf_n (1, src_name));
@@ -1190,14 +1203,14 @@ handle_clone_fail (int dst_dirfd, char const* dst_relname,
but cloned no data. */
if (new_dst /* currently not for fclonefileat(). */
&& reflink_mode == REFLINK_ALWAYS
&& ((! transient_failure) || lseek (dest_desc, 0, SEEK_END) == 0)
&& ((! report_failure) || lseek (dest_desc, 0, SEEK_END) == 0)
&& unlinkat (dst_dirfd, dst_relname, 0) != 0 && errno != ENOENT)
error (0, errno, _("cannot remove %s"), quoteaf (dst_name));
if (! transient_failure)
if (! report_failure)
copy_debug.reflink = COPY_DEBUG_UNSUPPORTED;
if (reflink_mode == REFLINK_ALWAYS || transient_failure)
if (reflink_mode == REFLINK_ALWAYS || report_failure)
return false;
return true;
@@ -1225,7 +1238,7 @@ copy_reg (char const *src_name, char const *dst_name,
mode_t dst_mode, mode_t omitted_permissions, bool *new_dst,
struct stat const *src_sb)
{
char *buf = NULL;
char *buf = nullptr;
int dest_desc;
int dest_errno;
int source_desc;
@@ -2006,7 +2019,7 @@ dest_info_init (struct cp_options *x)
{
x->dest_info
= hash_initialize (DEST_INFO_INITIAL_CAPACITY,
NULL,
nullptr,
triple_hash,
triple_compare,
triple_free);
@@ -2030,7 +2043,7 @@ src_info_init (struct cp_options *x)
*/
x->src_info
= hash_initialize (DEST_INFO_INITIAL_CAPACITY,
NULL,
nullptr,
triple_hash_no_name,
triple_compare,
triple_free);
@@ -2051,8 +2064,9 @@ abandon_move (const struct cp_options *x,
int dst_dirfd, char const *dst_relname,
struct stat const *dst_sb)
{
assert (x->move_mode);
affirm (x->move_mode);
return (x->interactive == I_ALWAYS_NO
|| x->interactive == I_ALWAYS_SKIP
|| ((x->interactive == I_ASK_USER
|| (x->interactive == I_UNSPECIFIED
&& x->stdin_tty
@@ -2062,7 +2076,7 @@ abandon_move (const struct cp_options *x,
}
/* Print --verbose output on standard output, e.g. 'new' -> 'old'.
If BACKUP_DST_NAME is non-NULL, then also indicate that it is
If BACKUP_DST_NAME is non-null, then also indicate that it is
the name of a backup file. */
static void
emit_verbose (char const *src, char const *dst, char const *backup_dst_name)
@@ -2073,13 +2087,13 @@ emit_verbose (char const *src, char const *dst, char const *backup_dst_name)
putchar ('\n');
}
/* A wrapper around "setfscreatecon (NULL)" that exits upon failure. */
/* A wrapper around "setfscreatecon (nullptr)" that exits upon failure. */
static void
restore_default_fscreatecon_or_die (void)
{
if (setfscreatecon (NULL) != 0)
die (EXIT_FAILURE, errno,
_("failed to restore the default file creation context"));
if (setfscreatecon (nullptr) != 0)
error (EXIT_FAILURE, errno,
_("failed to restore the default file creation context"));
}
/* Return a newly-allocated string that is like STR
@@ -2115,7 +2129,7 @@ create_hard_link (char const *src_name, int src_dirfd, char const *src_relname,
if (0 < err)
{
char *a_src_name = NULL;
char *a_src_name = nullptr;
if (!src_name)
src_name = a_src_name = subst_suffix (dst_name, dst_relname,
src_relname);
@@ -2198,8 +2212,8 @@ copy_internal (char const *src_name, char const *dst_name,
mode_t dst_mode_bits;
mode_t omitted_permissions;
bool restore_dst_mode = false;
char *earlier_file = NULL;
char *dst_backup = NULL;
char *earlier_file = nullptr;
char *dst_backup = nullptr;
char const *drelname = *dst_relname ? dst_relname : ".";
bool delayed_ok;
bool copied_as_regular = false;
@@ -2226,7 +2240,8 @@ copy_internal (char const *src_name, char const *dst_name,
if (rename_errno == 0
? !x->last_file
: rename_errno != EEXIST || x->interactive != I_ALWAYS_NO)
: rename_errno != EEXIST
|| (x->interactive != I_ALWAYS_NO && x->interactive != I_ALWAYS_SKIP))
{
char const *name = rename_errno == 0 ? dst_name : src_name;
int dirfd = rename_errno == 0 ? dst_dirfd : AT_FDCWD;
@@ -2253,7 +2268,7 @@ copy_internal (char const *src_name, char const *dst_name,
else
{
#if defined lint && (defined __clang__ || defined __COVERITY__)
assert (x->move_mode);
affirm (x->move_mode);
memset (&src_sb, 0, sizeof src_sb);
#endif
}
@@ -2261,7 +2276,7 @@ copy_internal (char const *src_name, char const *dst_name,
/* Detect the case in which the same source file appears more than
once on the command line and no backup option has been selected.
If so, simply warn and don't copy it the second time.
This check is enabled only if x->src_info is non-NULL. */
This check is enabled only if x->src_info is non-null. */
if (command_line_arg && x->src_info)
{
if ( ! S_ISDIR (src_mode)
@@ -2280,7 +2295,9 @@ copy_internal (char const *src_name, char const *dst_name,
if (nonexistent_dst <= 0)
{
if (! (rename_errno == EEXIST && x->interactive == I_ALWAYS_NO))
if (! (rename_errno == EEXIST
&& (x->interactive == I_ALWAYS_NO
|| x->interactive == I_ALWAYS_SKIP)))
{
/* Regular files can be created by writing through symbolic
links, but other files cannot. So use stat on the
@@ -2321,8 +2338,10 @@ copy_internal (char const *src_name, char const *dst_name,
if (rename_errno == EEXIST)
{
bool return_now = false;
bool return_val = true;
bool skipped = false;
if (x->interactive != I_ALWAYS_NO
if ((x->interactive != I_ALWAYS_NO && x->interactive != I_ALWAYS_SKIP)
&& ! same_file_ok (src_name, &src_sb, dst_dirfd, drelname,
&dst_sb, x, &return_now))
{
@@ -2364,7 +2383,7 @@ copy_internal (char const *src_name, char const *dst_name,
{
/* Note we currently replace DST_NAME unconditionally,
even if it was a newer separate file. */
if (! create_hard_link (NULL, dst_dirfd, earlier_file,
if (! create_hard_link (nullptr, dst_dirfd, earlier_file,
dst_name, dst_dirfd, dst_relname,
true,
x->verbose, dereference))
@@ -2373,7 +2392,8 @@ copy_internal (char const *src_name, char const *dst_name,
}
}
return true;
skipped = true;
goto skip;
}
}
@@ -2392,21 +2412,38 @@ copy_internal (char const *src_name, char const *dst_name,
doesn't end up removing the source file. */
if (rename_succeeded)
*rename_succeeded = true;
return false;
skipped = true;
return_val = x->interactive == I_ALWAYS_SKIP;
}
}
else
{
if (! S_ISDIR (src_mode)
&& (x->interactive == I_ALWAYS_NO
|| x->interactive == I_ALWAYS_SKIP
|| (x->interactive == I_ASK_USER
&& ! overwrite_ok (x, dst_name, dst_dirfd,
dst_relname, &dst_sb))))
return false;
{
skipped = true;
return_val = x->interactive == I_ALWAYS_SKIP;
}
}
skip:
if (skipped)
{
if (x->interactive == I_ALWAYS_NO)
error (0, 0, _("not replacing %s"), quoteaf (dst_name));
else if (x->debug)
printf (_("skipped %s\n"), quoteaf (dst_name));
return_now = true;
}
if (return_now)
return true;
return return_val;
if (!S_ISDIR (dst_sb.st_mode))
{
@@ -2623,7 +2660,7 @@ copy_internal (char const *src_name, char const *dst_name,
We'll use that info to detect this problem: cp -R dir dir. */
if (rename_errno == 0)
earlier_file = NULL;
earlier_file = nullptr;
else if (x->recursive && S_ISDIR (src_mode))
{
if (command_line_arg)
@@ -2706,7 +2743,7 @@ copy_internal (char const *src_name, char const *dst_name,
}
else
{
if (! create_hard_link (NULL, dst_dirfd, earlier_file,
if (! create_hard_link (nullptr, dst_dirfd, earlier_file,
dst_name, dst_dirfd, dst_relname,
true, x->verbose, dereference))
goto un_backup;
@@ -2805,9 +2842,26 @@ copy_internal (char const *src_name, char const *dst_name,
If the permissions on the directory containing the source or
destination file are made too restrictive, the rename will
fail. Etc. */
error (0, rename_errno,
_("cannot move %s to %s"),
quoteaf_n (0, src_name), quoteaf_n (1, dst_name));
char const *quoted_dst_name = quoteaf_n (1, dst_name);
switch (rename_errno)
{
case EDQUOT: case EEXIST: case EISDIR: case EMLINK:
case ENOSPC: case ETXTBSY:
#if ENOTEMPTY != EEXIST
case ENOTEMPTY:
#endif
/* The destination must be the problem. Don't mention
the source as that is more likely to confuse the user
than be helpful. */
error (0, rename_errno, _("cannot overwrite %s"),
quoted_dst_name);
break;
default:
error (0, rename_errno, _("cannot move %s to %s"),
quoteaf_n (0, src_name), quoted_dst_name);
break;
}
forget_created (src_sb.st_ino, src_sb.st_dev);
return false;
}
@@ -2934,7 +2988,7 @@ copy_internal (char const *src_name, char const *dst_name,
if (x->move_mode)
printf (_("created directory %s\n"), quoteaf (dst_name));
else
emit_verbose (src_name, dst_name, NULL);
emit_verbose (src_name, dst_name, nullptr);
}
}
else
@@ -2942,7 +2996,7 @@ copy_internal (char const *src_name, char const *dst_name,
omitted_permissions = 0;
/* For directories, the process global context could be reset for
descendents, so use it to set the context for existing dirs here.
descendants, so use it to set the context for existing dirs here.
This will also give earlier indication of failure to set ctx. */
if (x->set_security_context || x->preserve_security_context)
if (! set_file_security_ctx (dst_name, false, x))
@@ -3082,7 +3136,7 @@ copy_internal (char const *src_name, char const *dst_name,
{
char *src_link_val = areadlink_with_size (src_name, src_sb.st_size);
dest_is_symlink = true;
if (src_link_val == NULL)
if (src_link_val == nullptr)
{
error (0, errno, _("cannot read symbolic link %s"),
quoteaf (src_name));
@@ -3304,7 +3358,7 @@ un_backup:
remove the entry associating the source dev/ino with the
destination file name, so we don't try to 'preserve' a link
to a file we didn't create. */
if (earlier_file == NULL)
if (earlier_file == nullptr)
forget_created (src_sb.st_ino, src_sb.st_dev);
if (dst_backup)
@@ -3322,18 +3376,16 @@ un_backup:
return false;
}
ATTRIBUTE_PURE
static bool
static void
valid_options (const struct cp_options *co)
{
assert (VALID_BACKUP_TYPE (co->backup_type));
assert (VALID_SPARSE_MODE (co->sparse_mode));
assert (VALID_REFLINK_MODE (co->reflink_mode));
assert (!(co->hard_link && co->symbolic_link));
assert (!
affirm (VALID_BACKUP_TYPE (co->backup_type));
affirm (VALID_SPARSE_MODE (co->sparse_mode));
affirm (VALID_REFLINK_MODE (co->reflink_mode));
affirm (!(co->hard_link && co->symbolic_link));
affirm (!
(co->reflink_mode == REFLINK_ALWAYS
&& co->sparse_mode != SPARSE_AUTO));
return true;
}
/* Copy the file SRC_NAME to the file DST_NAME aka DST_DIRFD+DST_RELNAME.
@@ -3353,7 +3405,7 @@ copy (char const *src_name, char const *dst_name,
int nonexistent_dst, const struct cp_options *options,
bool *copy_into_self, bool *rename_succeeded)
{
assert (valid_options (options));
valid_options (options);
/* Record the file names: they're used in case of error, when copying
a directory into itself. I don't like to make these tools do *any*
@@ -3367,7 +3419,7 @@ copy (char const *src_name, char const *dst_name,
bool first_dir_created_per_command_line_arg = false;
return copy_internal (src_name, dst_name, dst_dirfd, dst_relname,
nonexistent_dst, NULL, NULL,
nonexistent_dst, nullptr, nullptr,
options, true,
&first_dir_created_per_command_line_arg,
copy_into_self, rename_succeeded);

View File

@@ -57,11 +57,25 @@ enum Reflink_type
REFLINK_ALWAYS
};
/* Control how existing destination files are updated. */
enum Update_type
{
/* Always update.. */
UPDATE_ALL,
/* Update if dest older. */
UPDATE_OLDER,
/* Leave existing files. */
UPDATE_NONE,
};
/* This type is used to help mv (via copy.c) distinguish these cases. */
enum Interactive
{
I_ALWAYS_YES = 1,
I_ALWAYS_NO,
I_ALWAYS_NO, /* Skip and fail. */
I_ALWAYS_SKIP, /* Skip and ignore. */
I_ASK_USER,
I_UNSPECIFIED
};
@@ -272,7 +286,7 @@ struct cp_options
rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c
For now, it protects only regular files when copying (i.e., not renaming).
When renaming, it protects all non-directories.
Use dest_info_init to initialize it, or set it to NULL to disable
Use dest_info_init to initialize it, or set it to nullptr to disable
this feature. */
Hash_table *dest_info;

View File

@@ -27,8 +27,6 @@
#endif
#include "system.h"
#include "die.h"
#include "error.h"
#include "quote.h"
#ifdef SINGLE_BINARY
@@ -51,7 +49,7 @@ static struct option const long_options[] =
{
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
@@ -95,7 +93,7 @@ Use: '%s --coreutils-prog=PROGRAM_NAME --help' for individual program help.\n"),
static void
launch_program (char const *prog_name, int prog_argc, char **prog_argv)
{
int (*prog_main) (int, char **) = NULL;
int (*prog_main) (int, char **) = nullptr;
/* Ensure that at least one parameter was passed. */
if (!prog_argc || !prog_argv || !prog_argv[0] || !prog_name)
@@ -153,7 +151,7 @@ main (int argc, char **argv)
if (argc >= 2)
{
size_t nskip = 0;
char *arg_name = NULL;
char *arg_name = nullptr;
/* If calling coreutils directly, the "script" name isn't passed.
Distinguish the two cases with a -shebang suffix. */
@@ -176,8 +174,8 @@ main (int argc, char **argv)
{
argv[nskip] = arg_name; /* XXX: Discards any specified path. */
launch_program (prog_name, argc - nskip, argv + nskip);
die (EXIT_FAILURE, 0, _("unknown program %s"),
quote (prog_name));
error (EXIT_FAILURE, 0, _("unknown program %s"),
quote (prog_name));
}
}
@@ -190,7 +188,7 @@ main (int argc, char **argv)
textdomain (PACKAGE);
atexit (close_stdout);
if ((optc = getopt_long (argc, argv, "", long_options, NULL)) != -1)
if ((optc = getopt_long (argc, argv, "", long_options, nullptr)) != -1)
switch (optc)
{
case_GETOPT_HELP_CHAR;

View File

@@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Written by Torbjorn Granlund, Sweden (tege@sics.se).
Written by Torbjörn Granlund, Sweden (tege@sics.se).
Rewritten to use lib/hash.c by Jim Meyering. */
#include <config.h>
@@ -86,7 +86,7 @@ forget_created (ino_t ino, dev_t dev)
probe.st_ino = ino;
probe.st_dev = dev;
probe.name = NULL;
probe.name = nullptr;
ent = hash_remove (src_to_dest, &probe);
if (ent)
@@ -94,7 +94,7 @@ forget_created (ino_t ino, dev_t dev)
}
/* If INO/DEV correspond to an already-copied source file, return the
name of the corresponding destination file. Otherwise, return NULL. */
name of the corresponding destination file. Otherwise, return nullptr. */
extern char *
src_to_dest_lookup (ino_t ino, dev_t dev)
@@ -104,12 +104,12 @@ src_to_dest_lookup (ino_t ino, dev_t dev)
ent.st_ino = ino;
ent.st_dev = dev;
e = hash_lookup (src_to_dest, &ent);
return e ? e->name : NULL;
return e ? e->name : nullptr;
}
/* Add file NAME, copied from inode number INO and device number DEV,
to the list of files we have copied.
Return NULL if inserted, otherwise non-NULL. */
Return nullptr if inserted, otherwise a non-null pointer. */
extern char *
remember_copied (char const *name, ino_t ino, dev_t dev)
@@ -123,7 +123,7 @@ remember_copied (char const *name, ino_t ino, dev_t dev)
ent->st_dev = dev;
ent_from_table = hash_insert (src_to_dest, ent);
if (ent_from_table == NULL)
if (ent_from_table == nullptr)
{
/* Insertion failed due to lack of memory. */
xalloc_die ();
@@ -139,17 +139,17 @@ remember_copied (char const *name, ino_t ino, dev_t dev)
}
/* New key; insertion succeeded. */
return NULL;
return nullptr;
}
/* Initialize the hash table. */
extern void
hash_init (void)
{
src_to_dest = hash_initialize (INITIAL_TABLE_SIZE, NULL,
src_to_dest = hash_initialize (INITIAL_TABLE_SIZE, nullptr,
src_to_dest_hash,
src_to_dest_compare,
src_to_dest_free);
if (src_to_dest == NULL)
if (src_to_dest == nullptr)
xalloc_die ();
}

250
src/cp.c
View File

@@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Written by Torbjorn Granlund, David MacKenzie, and Jim Meyering. */
Written by Torbjörn Granlund, David MacKenzie, and Jim Meyering. */
#include <config.h>
#include <stdio.h>
@@ -24,11 +24,10 @@
#include "system.h"
#include "argmatch.h"
#include "assure.h"
#include "backupfile.h"
#include "copy.h"
#include "cp-hash.h"
#include "die.h"
#include "error.h"
#include "filenamecat.h"
#include "ignore-value.h"
#include "quote.h"
@@ -41,7 +40,7 @@
#define PROGRAM_NAME "cp"
#define AUTHORS \
proper_name ("Torbjorn Granlund"), \
proper_name_lite ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
proper_name ("David MacKenzie"), \
proper_name ("Jim Meyering")
@@ -84,7 +83,7 @@ static bool remove_trailing_slashes;
static char const *const sparse_type_string[] =
{
"never", "auto", "always", NULL
"never", "auto", "always", nullptr
};
static enum Sparse_type const sparse_type[] =
{
@@ -94,7 +93,7 @@ ARGMATCH_VERIFY (sparse_type_string, sparse_type);
static char const *const reflink_type_string[] =
{
"auto", "always", "never", NULL
"auto", "always", "never", nullptr
};
static enum Reflink_type const reflink_type[] =
{
@@ -102,39 +101,50 @@ static enum Reflink_type const reflink_type[] =
};
ARGMATCH_VERIFY (reflink_type_string, reflink_type);
static char const *const update_type_string[] =
{
"all", "none", "older", nullptr
};
static enum Update_type const update_type[] =
{
UPDATE_ALL, UPDATE_NONE, UPDATE_OLDER,
};
ARGMATCH_VERIFY (update_type_string, update_type);
static struct option const long_opts[] =
{
{"archive", no_argument, NULL, 'a'},
{"attributes-only", no_argument, NULL, ATTRIBUTES_ONLY_OPTION},
{"backup", optional_argument, NULL, 'b'},
{"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},
{"debug", no_argument, NULL, DEBUG_OPTION},
{"dereference", no_argument, NULL, 'L'},
{"force", no_argument, NULL, 'f'},
{"interactive", no_argument, NULL, 'i'},
{"link", no_argument, NULL, 'l'},
{"no-clobber", no_argument, NULL, 'n'},
{"no-dereference", no_argument, NULL, 'P'},
{"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION},
{"no-target-directory", no_argument, NULL, 'T'},
{"one-file-system", no_argument, NULL, 'x'},
{"parents", no_argument, NULL, PARENTS_OPTION},
{"path", no_argument, NULL, PARENTS_OPTION}, /* Deprecated. */
{"preserve", optional_argument, NULL, PRESERVE_ATTRIBUTES_OPTION},
{"recursive", no_argument, NULL, 'R'},
{"remove-destination", no_argument, NULL, UNLINK_DEST_BEFORE_OPENING},
{"sparse", required_argument, NULL, SPARSE_OPTION},
{"reflink", optional_argument, NULL, REFLINK_OPTION},
{"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION},
{"suffix", required_argument, NULL, 'S'},
{"symbolic-link", no_argument, NULL, 's'},
{"target-directory", required_argument, NULL, 't'},
{"update", no_argument, NULL, 'u'},
{"verbose", no_argument, NULL, 'v'},
{"archive", no_argument, nullptr, 'a'},
{"attributes-only", no_argument, nullptr, ATTRIBUTES_ONLY_OPTION},
{"backup", optional_argument, nullptr, 'b'},
{"copy-contents", no_argument, nullptr, COPY_CONTENTS_OPTION},
{"debug", no_argument, nullptr, DEBUG_OPTION},
{"dereference", no_argument, nullptr, 'L'},
{"force", no_argument, nullptr, 'f'},
{"interactive", no_argument, nullptr, 'i'},
{"link", no_argument, nullptr, 'l'},
{"no-clobber", no_argument, nullptr, 'n'},
{"no-dereference", no_argument, nullptr, 'P'},
{"no-preserve", required_argument, nullptr, NO_PRESERVE_ATTRIBUTES_OPTION},
{"no-target-directory", no_argument, nullptr, 'T'},
{"one-file-system", no_argument, nullptr, 'x'},
{"parents", no_argument, nullptr, PARENTS_OPTION},
{"path", no_argument, nullptr, PARENTS_OPTION}, /* Deprecated. */
{"preserve", optional_argument, nullptr, PRESERVE_ATTRIBUTES_OPTION},
{"recursive", no_argument, nullptr, 'R'},
{"remove-destination", no_argument, nullptr, UNLINK_DEST_BEFORE_OPENING},
{"sparse", required_argument, nullptr, SPARSE_OPTION},
{"reflink", optional_argument, nullptr, REFLINK_OPTION},
{"strip-trailing-slashes", no_argument, nullptr,
STRIP_TRAILING_SLASHES_OPTION},
{"suffix", required_argument, nullptr, 'S'},
{"symbolic-link", no_argument, nullptr, 's'},
{"target-directory", required_argument, nullptr, 't'},
{"update", optional_argument, nullptr, 'u'},
{"verbose", no_argument, nullptr, 'v'},
{GETOPT_SELINUX_CONTEXT_OPTION_DECL},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -182,8 +192,10 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
-L, --dereference always follow symbolic links in SOURCE\n\
"), stdout);
fputs (_("\
-n, --no-clobber do not overwrite an existing file (overrides\n\
a previous -i option)\n\
-n, --no-clobber do not overwrite an existing file (overrides a\n\
-u or previous -i option). See also --update\n\
"), stdout);
fputs (_("\
-P, --no-dereference never follow symbolic links in SOURCE\n\
"), stdout);
fputs (_("\
@@ -212,10 +224,14 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
-T, --no-target-directory treat DEST as a normal file\n\
"), stdout);
fputs (_("\
-u, --update copy only when the SOURCE file is newer\n\
than the destination file or when the\n\
destination file is missing\n\
--update[=UPDATE] control which existing files are updated;\n\
UPDATE={all,none,older(default)}. See below\n\
-u equivalent to --update[=older]\n\
"), stdout);
fputs (_("\
-v, --verbose explain what is being done\n\
"), stdout);
fputs (_("\
-x, --one-file-system stay on this file system\n\
"), stdout);
fputs (_("\
@@ -242,6 +258,7 @@ selected by --sparse=auto. Specify --sparse=always to create a sparse DEST\n\
file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\
Use --sparse=never to inhibit creation of sparse files.\n\
"), stdout);
emit_update_parameters_note ();
fputs (_("\
\n\
When --reflink[=always] is specified, perform a lightweight copy, where the\n\
@@ -261,10 +278,13 @@ regular file.\n\
exit (status);
}
/* Ensure that parents of CONST_DST_NAME aka DST_DIRFD+DST_RELNAME have the
correct protections, for the --parents option. This is done
after all copying has been completed, to allow permissions
that don't include user write/execute.
/* Ensure that parents of CONST_DST_NAME have correct protections, for
the --parents option. This is done after all copying has been
completed, to allow permissions that don't include user write/execute.
DST_SRC_NAME is the suffix of CONST_DST_NAME that is the source file name,
DST_DIRFD+DST_RELNAME is equivalent to CONST_DST_NAME, and
DST_RELNAME equals DST_SRC_NAME after skipping any leading '/'s.
ATTR_LIST is a null-terminated linked list of structures that
indicates the end of the filename of each intermediate directory
@@ -279,15 +299,21 @@ regular file.\n\
when done. */
static bool
re_protect (char const *const_dst_name, int dst_dirfd, char const *dst_relname,
re_protect (char const *const_dst_name, char const *dst_src_name,
int dst_dirfd, char const *dst_relname,
struct dir_attr *attr_list, const struct cp_options *x)
{
struct dir_attr *p;
char *dst_name; /* A copy of CONST_DST_NAME we can change. */
char *src_name; /* The source name in 'dst_name'. */
ASSIGN_STRDUPA (dst_name, const_dst_name);
src_name = dst_name + (dst_relname - const_dst_name);
/* The suffix of DST_NAME that is a copy of the source file name,
possibly truncated to name a parent directory. */
char const *src_name = dst_name + (dst_src_name - const_dst_name);
/* Likewise, but with any leading '/'s skipped. */
char const *relname = dst_name + (dst_relname - const_dst_name);
for (p = attr_list; p; p = p->next)
{
@@ -304,7 +330,7 @@ re_protect (char const *const_dst_name, int dst_dirfd, char const *dst_relname,
timespec[0] = get_stat_atime (&p->st);
timespec[1] = get_stat_mtime (&p->st);
if (utimensat (dst_dirfd, src_name, timespec, 0))
if (utimensat (dst_dirfd, relname, timespec, 0))
{
error (0, errno, _("failed to preserve times for %s"),
quoteaf (dst_name));
@@ -314,7 +340,8 @@ re_protect (char const *const_dst_name, int dst_dirfd, char const *dst_relname,
if (x->preserve_ownership)
{
if (lchownat (dst_dirfd, src_name, p->st.st_uid, p->st.st_gid) != 0)
if (lchownat (dst_dirfd, relname, p->st.st_uid, p->st.st_gid)
!= 0)
{
if (! chown_failure_ok (x))
{
@@ -324,7 +351,7 @@ re_protect (char const *const_dst_name, int dst_dirfd, char const *dst_relname,
}
/* Failing to preserve ownership is OK. Still, try to preserve
the group, but ignore the possible error. */
ignore_value (lchownat (dst_dirfd, src_name, -1, p->st.st_gid));
ignore_value (lchownat (dst_dirfd, relname, -1, p->st.st_gid));
}
}
@@ -335,7 +362,7 @@ re_protect (char const *const_dst_name, int dst_dirfd, char const *dst_relname,
}
else if (p->restore_mode)
{
if (lchmodat (dst_dirfd, src_name, p->st.st_mode) != 0)
if (lchmodat (dst_dirfd, relname, p->st.st_mode) != 0)
{
error (0, errno, _("failed to preserve permissions for %s"),
quoteaf (dst_name));
@@ -381,7 +408,7 @@ make_dir_parents_private (char const *const_dir, size_t src_offset,
char *dst_dir; /* Leading directory of DIR. */
idx_t dirlen = dir_len (const_dir);
*attr_list = NULL;
*attr_list = nullptr;
/* Succeed immediately if the parent of CONST_DIR must already exist,
as the target directory has already been checked. */
@@ -490,7 +517,7 @@ make_dir_parents_private (char const *const_dir, size_t src_offset,
}
else
{
if (verbose_fmt_string != NULL)
if (verbose_fmt_string != nullptr)
printf (verbose_fmt_string, src, dir);
}
@@ -600,9 +627,9 @@ do_copy (int n_files, char **file, char const *target_directory,
if (no_target_directory)
{
if (target_directory)
die (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"), quoteaf (file[2]));
@@ -613,8 +640,8 @@ do_copy (int n_files, char **file, char const *target_directory,
{
target_dirfd = target_directory_operand (target_directory, &sb);
if (! target_dirfd_valid (target_dirfd))
die (EXIT_FAILURE, errno, _("target directory %s"),
quoteaf (target_directory));
error (EXIT_FAILURE, errno, _("target directory %s"),
quoteaf (target_directory));
}
else
{
@@ -645,7 +672,7 @@ do_copy (int n_files, char **file, char const *target_directory,
|| (O_PATHSEARCH == O_SEARCH && err == EACCES
&& (sb.st_mode || stat (lastfile, &sb) == 0)
&& S_ISDIR (sb.st_mode)))
die (EXIT_FAILURE, err, _("target %s"), quoteaf (lastfile));
error (EXIT_FAILURE, err, _("target %s"), quoteaf (lastfile));
}
}
@@ -669,7 +696,7 @@ do_copy (int n_files, char **file, char const *target_directory,
char *dst_name;
bool parent_exists = true; /* True if dir_name (dst_name) exists. */
struct dir_attr *attr_list;
char *arg_in_concat = NULL;
char *arg_in_concat;
char *arg = file[i];
/* Trailing slashes are meaningful (i.e., maybe worth preserving)
@@ -699,11 +726,8 @@ do_copy (int n_files, char **file, char const *target_directory,
parent_exists =
(make_dir_parents_private
(dst_name, arg_in_concat - dst_name, target_dirfd,
(x->verbose ? "%s -> %s\n" : NULL),
(x->verbose ? "%s -> %s\n" : nullptr),
&attr_list, &new_dst, x));
while (*arg_in_concat == '/')
arg_in_concat++;
}
else
{
@@ -725,13 +749,17 @@ do_copy (int n_files, char **file, char const *target_directory,
}
else
{
char const *dst_relname = arg_in_concat;
while (*dst_relname == '/')
dst_relname++;
bool copy_into_self;
ok &= copy (arg, dst_name, target_dirfd, arg_in_concat,
new_dst, x, &copy_into_self, NULL);
ok &= copy (arg, dst_name, target_dirfd, dst_relname,
new_dst, x, &copy_into_self, nullptr);
if (parents_option)
ok &= re_protect (dst_name, target_dirfd, arg_in_concat,
attr_list, x);
ok &= re_protect (dst_name, arg_in_concat, target_dirfd,
dst_relname, attr_list, x);
}
if (parents_option)
@@ -785,7 +813,7 @@ do_copy (int n_files, char **file, char const *target_directory,
x = &x_tmp;
}
ok = copy (source, dest, AT_FDCWD, dest, -new_dst, x, &unused, NULL);
ok = copy (source, dest, AT_FDCWD, dest, -new_dst, x, &unused, nullptr);
}
return ok;
@@ -813,7 +841,7 @@ cp_option_init (struct cp_options *x)
x->explicit_no_preserve_mode = false;
x->preserve_security_context = false; /* -a or --preserve=context. */
x->require_preserve_context = false; /* --preserve=context. */
x->set_security_context = NULL; /* -Z, set sys default context. */
x->set_security_context = nullptr; /* -Z, set sys default context. */
x->preserve_xattr = false;
x->reduce_diagnostics = false;
x->require_preserve_xattr = false;
@@ -836,10 +864,10 @@ cp_option_init (struct cp_options *x)
in general one cannot do that safely, give the current semantics of
open's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw).
But POSIX requires it. */
x->open_dangling_dest_symlink = getenv ("POSIXLY_CORRECT") != NULL;
x->open_dangling_dest_symlink = getenv ("POSIXLY_CORRECT") != nullptr;
x->dest_info = NULL;
x->src_info = NULL;
x->dest_info = nullptr;
x->src_info = nullptr;
}
/* Given a string, ARG, containing a comma-separated list of arguments
@@ -867,7 +895,7 @@ decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
static char const *const preserve_args[] =
{
"mode", "timestamps",
"ownership", "links", "context", "xattr", "all", NULL
"ownership", "links", "context", "xattr", "all", nullptr
};
ARGMATCH_VERIFY (preserve_args, preserve_vals);
@@ -927,7 +955,7 @@ decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
break;
default:
abort ();
affirm (false);
}
s = comma;
}
@@ -942,13 +970,13 @@ main (int argc, char **argv)
int c;
bool ok;
bool make_backups = false;
char const *backup_suffix = NULL;
char *version_control_string = NULL;
char const *backup_suffix = nullptr;
char *version_control_string = nullptr;
struct cp_options x;
bool copy_contents = false;
char *target_directory = NULL;
char *target_directory = nullptr;
bool no_target_directory = false;
char const *scontext = NULL;
char const *scontext = nullptr;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -962,7 +990,7 @@ main (int argc, char **argv)
cp_option_init (&x);
while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ",
long_opts, NULL))
long_opts, nullptr))
!= -1)
{
switch (c)
@@ -973,7 +1001,7 @@ main (int argc, char **argv)
break;
case REFLINK_OPTION:
if (optarg == NULL)
if (optarg == nullptr)
x.reflink_mode = REFLINK_ALWAYS;
else
x.reflink_mode = XARGMATCH ("--reflink", optarg,
@@ -1051,7 +1079,7 @@ main (int argc, char **argv)
break;
case PRESERVE_ATTRIBUTES_OPTION:
if (optarg == NULL)
if (optarg == nullptr)
{
/* Fall through to the case for 'p' below. */
}
@@ -1093,8 +1121,8 @@ main (int argc, char **argv)
case 't':
if (target_directory)
die (EXIT_FAILURE, 0,
_("multiple target directories specified"));
error (EXIT_FAILURE, 0,
_("multiple target directories specified"));
target_directory = optarg;
break;
@@ -1103,7 +1131,30 @@ main (int argc, char **argv)
break;
case 'u':
x.update = true;
if (optarg == nullptr)
x.update = true;
else if (x.interactive != I_ALWAYS_NO) /* -n takes precedence. */
{
enum Update_type update_opt;
update_opt = XARGMATCH ("--update", optarg,
update_type_string, update_type);
if (update_opt == UPDATE_ALL)
{
/* Default cp operation. */
x.update = false;
x.interactive = I_UNSPECIFIED;
}
else if (update_opt == UPDATE_NONE)
{
x.update = false;
x.interactive = I_ALWAYS_SKIP;
}
else if (update_opt == UPDATE_OLDER)
{
x.update = true;
x.interactive = I_UNSPECIFIED;
}
}
break;
case 'v':
@@ -1123,7 +1174,7 @@ main (int argc, char **argv)
else
{
x.set_security_context = selabel_open (SELABEL_CTX_FILE,
NULL, 0);
nullptr, 0);
if (! x.set_security_context)
error (0, errno, _("warning: ignoring --context"));
}
@@ -1150,6 +1201,13 @@ main (int argc, char **argv)
}
}
/* With --sparse=never, disable reflinking so we create a non sparse copy.
This will also have the effect of disabling copy offload as that may
propagate holes. For e.g. FreeBSD documents that copy_file_range()
will try to propagate holes. */
if (x.reflink_mode == REFLINK_AUTO && x.sparse_mode == SPARSE_NEVER)
x.reflink_mode = REFLINK_NEVER;
if (x.hard_link && x.symbolic_link)
{
error (0, 0, _("cannot make both hard and symbolic links"));
@@ -1196,29 +1254,29 @@ main (int argc, char **argv)
x.preserve_security_context = false;
if (x.preserve_security_context && (x.set_security_context || scontext))
die (EXIT_FAILURE, 0,
_("cannot set target context and preserve it"));
error (EXIT_FAILURE, 0,
_("cannot set target context and preserve it"));
if (x.require_preserve_context && ! selinux_enabled)
die (EXIT_FAILURE, 0,
_("cannot preserve security context "
"without an SELinux-enabled kernel"));
error (EXIT_FAILURE, 0,
_("cannot preserve security context "
"without an SELinux-enabled kernel"));
/* FIXME: This handles new files. But what about existing files?
I.e., if updating a tree, new files would have the specified context,
but shouldn't existing files be updated for consistency like this?
if (scontext && !restorecon (NULL, dst_path, 0))
if (scontext && !restorecon (nullptr, dst_path, 0))
error (...);
*/
if (scontext && setfscreatecon (scontext) < 0)
die (EXIT_FAILURE, errno,
_("failed to set default file creation context to %s"),
quote (scontext));
error (EXIT_FAILURE, errno,
_("failed to set default file creation context to %s"),
quote (scontext));
#if !USE_XATTR
if (x.require_preserve_xattr)
die (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is "
"built without xattr support"));
error (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is "
"built without xattr support"));
#endif
/* Allocate space for remembering copied and created files. */

View File

@@ -1,3 +1,4 @@
#include <config.h>
#include <stdint.h>
uint_fast32_t const crctab[8][256] = {

View File

@@ -19,19 +19,16 @@
#include <config.h>
#include <assert.h>
#include <getopt.h>
#include <sys/types.h>
#include <signal.h>
#include <stdckdint.h>
#include "system.h"
#include <regex.h>
#include "die.h"
#include "error.h"
#include "fd-reopen.h"
#include "idx.h"
#include "quote.h"
#include "safe-read.h"
#include "stdio--.h"
@@ -113,10 +110,10 @@ static void delete_all_files (bool);
static void save_line_to_file (const struct cstring *line);
/* Start of buffer list. */
static struct buffer_record *head = NULL;
static struct buffer_record *head = nullptr;
/* Partially read line. */
static char *hold_area = NULL;
static char *hold_area = nullptr;
/* Number of bytes in 'hold_area'. */
static idx_t hold_count = 0;
@@ -131,13 +128,13 @@ static intmax_t current_line = 0;
static bool have_read_eof = false;
/* Name of output files. */
static char *volatile filename_space = NULL;
static char *volatile filename_space = nullptr;
/* Prefix part of output file names. */
static char const *volatile prefix = NULL;
static char const *volatile prefix = nullptr;
/* Suffix part of output file names. */
static char *volatile suffix = NULL;
static char *volatile suffix = nullptr;
/* Number of digits to use in output file names. */
static int volatile digits = 2;
@@ -149,10 +146,10 @@ static int volatile files_created = 0;
static intmax_t bytes_written;
/* Output file pointer. */
static FILE *output_stream = NULL;
static FILE *output_stream = nullptr;
/* Output file name. */
static char *output_filename = NULL;
static char *output_filename = nullptr;
/* Perhaps it would be cleaner to pass arg values instead of indexes. */
static char **global_argv;
@@ -188,17 +185,17 @@ enum
static struct option const longopts[] =
{
{"digits", required_argument, NULL, 'n'},
{"quiet", no_argument, NULL, 'q'},
{"silent", no_argument, NULL, 's'},
{"keep-files", no_argument, NULL, 'k'},
{"elide-empty-files", no_argument, NULL, 'z'},
{"prefix", required_argument, NULL, 'f'},
{"suffix-format", required_argument, NULL, 'b'},
{"suppress-matched", no_argument, NULL, SUPPRESS_MATCHED_OPTION},
{"digits", required_argument, nullptr, 'n'},
{"quiet", no_argument, nullptr, 'q'},
{"silent", no_argument, nullptr, 's'},
{"keep-files", no_argument, nullptr, 'k'},
{"elide-empty-files", no_argument, nullptr, 'z'},
{"prefix", required_argument, nullptr, 'f'},
{"suffix-format", required_argument, nullptr, 'b'},
{"suppress-matched", no_argument, nullptr, SUPPRESS_MATCHED_OPTION},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* Optionally remove files created so far; then exit.
@@ -213,7 +210,7 @@ cleanup (void)
sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
delete_all_files (false);
sigprocmask (SIG_SETMASK, &oldset, NULL);
sigprocmask (SIG_SETMASK, &oldset, nullptr);
}
static _Noreturn void
@@ -294,7 +291,7 @@ new_line_control (void)
{
struct line *p = xmalloc (sizeof *p);
p->next = NULL;
p->next = nullptr;
clear_line_control (p);
return p;
@@ -309,7 +306,7 @@ keep_new_line (struct buffer_record *b, char *line_start, idx_t line_len)
struct line *l;
/* If there is no existing area to keep line info, get some. */
if (b->line_start == NULL)
if (b->line_start == nullptr)
b->line_start = b->curr_line = new_line_control ();
/* If existing area for lines is full, get more. */
@@ -382,6 +379,13 @@ record_line_starts (struct buffer_record *b)
return lines;
}
/* Work around <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109614>. */
#if 13 <= __GNUC__
# pragma GCC diagnostic ignored "-Wanalyzer-mismatching-deallocation"
# pragma GCC diagnostic ignored "-Wanalyzer-use-after-free"
# pragma GCC diagnostic ignored "-Wanalyzer-use-of-uninitialized-value"
#endif
static void
free_buffer (struct buffer_record *buf)
{
@@ -403,13 +407,13 @@ get_new_buffer (idx_t min_size)
{
struct buffer_record *new_buffer = xmalloc (sizeof *new_buffer);
new_buffer->bytes_alloc = 0;
new_buffer->buffer = xpalloc (NULL, &new_buffer->bytes_alloc, min_size,
new_buffer->buffer = xpalloc (nullptr, &new_buffer->bytes_alloc, min_size,
-1, 1);
new_buffer->bytes_used = 0;
new_buffer->start_line = new_buffer->first_available = last_line_number + 1;
new_buffer->num_lines = 0;
new_buffer->line_start = new_buffer->curr_line = NULL;
new_buffer->next = NULL;
new_buffer->line_start = new_buffer->curr_line = nullptr;
new_buffer->next = nullptr;
return new_buffer;
}
@@ -422,10 +426,10 @@ save_buffer (struct buffer_record *buf)
{
struct buffer_record *p;
buf->next = NULL;
buf->next = nullptr;
buf->curr_line = buf->line_start;
if (head == NULL)
if (head == nullptr)
head = buf;
else
{
@@ -451,32 +455,25 @@ save_buffer (struct buffer_record *buf)
static bool
load_buffer (void)
{
struct buffer_record *b;
idx_t bytes_wanted = START_SIZE; /* Minimum buffer size. */
idx_t bytes_avail; /* Size of new buffer created. */
idx_t lines_found; /* Number of lines in this new buffer. */
char *p; /* Place to load into buffer. */
if (have_read_eof)
return false;
/* We must make the buffer at least as large as the amount of data
in the partial line left over from the last call,
plus room for a sentinel '\n'. */
if (bytes_wanted <= hold_count)
bytes_wanted = hold_count + 1;
idx_t bytes_wanted = MAX (START_SIZE, hold_count + 1);
while (true)
{
b = get_new_buffer (bytes_wanted);
bytes_avail = b->bytes_alloc; /* Size of buffer returned. */
p = b->buffer;
struct buffer_record *b = get_new_buffer (bytes_wanted);
idx_t bytes_alloc = b->bytes_alloc;
idx_t bytes_avail = bytes_alloc;
char *p = b->buffer;
/* First check the 'holding' area for a partial line. */
if (hold_count)
{
memcpy (p, hold_area, hold_count);
p += hold_count;
p = mempcpy (p, hold_area, hold_count);
b->bytes_used += hold_count;
bytes_avail -= hold_count;
hold_count = 0;
@@ -484,22 +481,18 @@ load_buffer (void)
b->bytes_used += read_input (p, bytes_avail - 1);
lines_found = record_line_starts (b);
if (record_line_starts (b) != 0)
{
save_buffer (b);
return true;
}
if (lines_found || have_read_eof)
break;
if (INT_MULTIPLY_WRAPV (b->bytes_alloc, 2, &bytes_wanted))
xalloc_die ();
free_buffer (b);
if (have_read_eof)
return false;
if (ckd_add (&bytes_wanted, bytes_alloc, bytes_alloc >> 1))
xalloc_die ();
}
if (lines_found)
save_buffer (b);
else
free_buffer (b);
return lines_found != 0;
}
/* Return the line number of the first line that has not yet been retrieved. */
@@ -507,23 +500,23 @@ load_buffer (void)
static intmax_t
get_first_line_in_buffer (void)
{
if (head == NULL && !load_buffer ())
die (EXIT_FAILURE, errno, _("input disappeared"));
if (head == nullptr && !load_buffer ())
error (EXIT_FAILURE, errno, _("input disappeared"));
return head->first_available;
}
/* Return a pointer to the logical first line in the buffer and make the
next line the logical first line.
Return NULL if there is no more input. */
Return nullptr if there is no more input. */
static struct cstring *
remove_line (void)
{
/* If non-NULL, this is the buffer for which the previous call
/* If non-null, this is the buffer for which the previous call
returned the final line. So now, presuming that line has been
processed, we can free the buffer and reset this pointer. */
static struct buffer_record *prev_buf = NULL;
static struct buffer_record *prev_buf = nullptr;
struct cstring *line; /* Return value. */
struct line *l; /* For convenience. */
@@ -531,11 +524,11 @@ remove_line (void)
if (prev_buf)
{
free_buffer (prev_buf);
prev_buf = NULL;
prev_buf = nullptr;
}
if (head == NULL && !load_buffer ())
return NULL;
if (head == nullptr && !load_buffer ())
return nullptr;
if (current_line < head->first_available)
current_line = head->first_available;
@@ -551,7 +544,7 @@ 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)
if (head->curr_line == nullptr || head->curr_line->used == 0)
{
/* Go on to the next data block.
but first record the current one so we can free it
@@ -565,22 +558,21 @@ remove_line (void)
}
/* Search the buffers for line LINENUM, reading more input if necessary.
Return a pointer to the line, or NULL if it is not found in the file. */
Return a pointer to the line, or nullptr if it is not found in the file. */
static struct cstring *
find_line (intmax_t linenum)
{
struct buffer_record *b;
if (head == NULL && !load_buffer ())
return NULL;
if (head == nullptr && !load_buffer ())
return nullptr;
if (linenum < head->start_line)
return NULL;
return nullptr;
for (b = head;;)
{
assert (b);
if (linenum < b->start_line + b->num_lines)
{
/* The line is in this buffer. */
@@ -597,8 +589,8 @@ find_line (intmax_t linenum)
}
return &l->starts[offset];
}
if (b->next == NULL && !load_buffer ())
return NULL;
if (b->next == nullptr && !load_buffer ())
return nullptr;
b = b->next; /* Try the next data block. */
}
}
@@ -608,7 +600,7 @@ find_line (intmax_t linenum)
static bool
no_more_lines (void)
{
return find_line (current_line + 1) == NULL;
return find_line (current_line + 1) == nullptr;
}
/* Open NAME as standard input. */
@@ -617,8 +609,8 @@ static void
set_input_file (char const *name)
{
if (! STREQ (name, "-") && fd_reopen (STDIN_FILENO, name, O_RDONLY, 0) < 0)
die (EXIT_FAILURE, errno, _("cannot open %s for reading"),
quoteaf (name));
error (EXIT_FAILURE, errno, _("cannot open %s for reading"),
quoteaf (name));
}
/* Write all lines from the beginning of the buffer up to, but
@@ -648,7 +640,7 @@ write_to_file (intmax_t last_line, bool ignore, int argnum)
for (i = 0; i < lines; i++)
{
line = remove_line ();
if (line == NULL)
if (line == nullptr)
{
error (0, 0, _("%s: line number out of range"),
quote (global_argv[argnum]));
@@ -666,7 +658,7 @@ dump_rest_of_file (void)
{
struct cstring *line;
while ((line = remove_line ()) != NULL)
while ((line = remove_line ()) != nullptr)
save_line_to_file (line);
}
@@ -711,7 +703,7 @@ process_line_count (const struct control *p, intmax_t repetition)
while (linenum++ < last_line_to_save)
{
struct cstring *line = remove_line ();
if (line == NULL)
if (line == nullptr)
handle_line_error (p, repetition);
save_line_to_file (line);
}
@@ -773,7 +765,7 @@ process_regexp (struct control *p, intmax_t repetition)
while (true)
{
line = find_line (++current_line);
if (line == NULL)
if (line == nullptr)
{
if (p->repeat_forever)
{
@@ -791,7 +783,7 @@ process_regexp (struct control *p, intmax_t repetition)
if (line->str[line_len - 1] == '\n')
line_len--;
ret = re_search (&p->re_compiled, line->str, line_len,
0, line_len, NULL);
0, line_len, nullptr);
if (ret == -2)
{
error (0, 0, _("error in regular expression search"));
@@ -813,7 +805,7 @@ process_regexp (struct control *p, intmax_t repetition)
while (true)
{
line = find_line (++current_line);
if (line == NULL)
if (line == nullptr)
{
if (p->repeat_forever)
{
@@ -831,7 +823,7 @@ process_regexp (struct control *p, intmax_t repetition)
if (line->str[line_len - 1] == '\n')
line_len--;
ret = re_search (&p->re_compiled, line->str, line_len,
0, line_len, NULL);
0, line_len, nullptr);
if (ret == -2)
{
error (0, 0, _("error in regular expression search"));
@@ -924,10 +916,10 @@ create_output_file (void)
sigset_t oldset;
sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
output_stream = fopen (output_filename, "w");
fopen_ok = (output_stream != NULL);
fopen_ok = (output_stream != nullptr);
fopen_errno = errno;
files_created = nfiles + fopen_ok;
sigprocmask (SIG_SETMASK, &oldset, NULL);
sigprocmask (SIG_SETMASK, &oldset, nullptr);
}
if (! fopen_ok)
@@ -968,13 +960,13 @@ close_output_file (void)
if (ferror (output_stream))
{
error (0, 0, _("write error for %s"), quoteaf (output_filename));
output_stream = NULL;
output_stream = nullptr;
cleanup_fatal ();
}
if (fclose (output_stream) != 0)
{
error (0, errno, "%s", quotef (output_filename));
output_stream = NULL;
output_stream = nullptr;
cleanup_fatal ();
}
if (bytes_written == 0 && elide_empty_files)
@@ -988,7 +980,7 @@ close_output_file (void)
unlink_ok = (unlink (output_filename) == 0);
unlink_errno = errno;
files_created--;
sigprocmask (SIG_SETMASK, &oldset, NULL);
sigprocmask (SIG_SETMASK, &oldset, nullptr);
if (! unlink_ok && unlink_errno != ENOENT)
error (0, unlink_errno, "%s", quotef (output_filename));
@@ -1001,7 +993,7 @@ close_output_file (void)
fprintf (stdout, "%s\n", imaxtostr (bytes_written, buf));
}
}
output_stream = NULL;
output_stream = nullptr;
}
}
@@ -1015,7 +1007,7 @@ save_line_to_file (const struct cstring *line)
if (l != line->len)
{
error (0, errno, _("write error for %s"), quoteaf (output_filename));
output_stream = NULL;
output_stream = nullptr;
cleanup_fatal ();
}
bytes_written += line->len;
@@ -1048,9 +1040,9 @@ new_control_record (void)
static void
check_for_offset (struct control *p, char const *str, char const *num)
{
if (xstrtoimax (num, NULL, 10, &p->offset, "") != LONGINT_OK)
die (EXIT_FAILURE, 0, _("%s: integer expected after delimiter"),
quote (str));
if (xstrtoimax (num, nullptr, 10, &p->offset, "") != LONGINT_OK)
error (EXIT_FAILURE, 0, _("%s: integer expected after delimiter"),
quote (str));
}
/* Given that the first character of command line arg STR is '{',
@@ -1065,8 +1057,8 @@ parse_repeat_count (int argnum, struct control *p, char *str)
end = str + strlen (str) - 1;
if (*end != '}')
die (EXIT_FAILURE, 0, _("%s: '}' is required in repeat count"),
quote (str));
error (EXIT_FAILURE, 0, _("%s: '}' is required in repeat count"),
quote (str));
*end = '\0';
if (str + 1 == end - 1 && *(str + 1) == '*')
@@ -1074,12 +1066,12 @@ parse_repeat_count (int argnum, struct control *p, char *str)
else
{
uintmax_t val;
if (xstrtoumax (str + 1, NULL, 10, &val, "") != LONGINT_OK
if (xstrtoumax (str + 1, nullptr, 10, &val, "") != LONGINT_OK
|| INTMAX_MAX < val)
{
die (EXIT_FAILURE, 0,
_("%s}: integer required between '{' and '}'"),
quote (global_argv[argnum]));
error (EXIT_FAILURE, 0,
_("%s}: integer required between '{' and '}'"),
quote (global_argv[argnum]));
}
p->repeat = val;
}
@@ -1103,9 +1095,9 @@ extract_regexp (int argnum, bool ignore, char const *str)
char const *err;
closing_delim = strrchr (str + 1, delim);
if (closing_delim == NULL)
die (EXIT_FAILURE, 0,
_("%s: closing delimiter '%c' missing"), str, delim);
if (closing_delim == nullptr)
error (EXIT_FAILURE, 0,
_("%s: closing delimiter '%c' missing"), str, delim);
len = closing_delim - str - 1;
p = new_control_record ();
@@ -1113,10 +1105,10 @@ extract_regexp (int argnum, bool ignore, char const *str)
p->ignore = ignore;
p->regexpr = true;
p->re_compiled.buffer = NULL;
p->re_compiled.buffer = nullptr;
p->re_compiled.allocated = 0;
p->re_compiled.fastmap = xmalloc (UCHAR_MAX + 1);
p->re_compiled.translate = NULL;
p->re_compiled.translate = nullptr;
re_syntax_options =
RE_SYNTAX_POSIX_BASIC & ~RE_CONTEXT_INVALID_DUP & ~RE_NO_EMPTY_RANGES;
err = re_compile_pattern (str + 1, len, &p->re_compiled);
@@ -1153,18 +1145,19 @@ parse_patterns (int argc, int start, char **argv)
p->argnum = i;
uintmax_t val;
if (xstrtoumax (argv[i], NULL, 10, &val, "") != LONGINT_OK
if (xstrtoumax (argv[i], nullptr, 10, &val, "") != LONGINT_OK
|| INTMAX_MAX < val)
die (EXIT_FAILURE, 0, _("%s: invalid pattern"), quote (argv[i]));
error (EXIT_FAILURE, 0, _("%s: invalid pattern"), quote (argv[i]));
if (val == 0)
die (EXIT_FAILURE, 0,
_("%s: line number must be greater than zero"), argv[i]);
error (EXIT_FAILURE, 0,
_("%s: line number must be greater than zero"), argv[i]);
if (val < last_val)
{
char buf[INT_BUFSIZE_BOUND (intmax_t)];
die (EXIT_FAILURE, 0,
_("line number %s is smaller than preceding line number, %s"),
quote (argv[i]), imaxtostr (last_val, buf));
error (EXIT_FAILURE, 0,
_("line number %s is smaller than preceding line number,"
" %s"),
quote (argv[i]), imaxtostr (last_val, buf));
}
if (val == last_val)
@@ -1247,21 +1240,21 @@ check_format_conv_type (char *format, int flags)
break;
case 0:
die (EXIT_FAILURE, 0, _("missing conversion specifier in suffix"));
error (EXIT_FAILURE, 0, _("missing conversion specifier in suffix"));
default:
if (isprint (ch))
die (EXIT_FAILURE, 0,
_("invalid conversion specifier in suffix: %c"), ch);
error (EXIT_FAILURE, 0,
_("invalid conversion specifier in suffix: %c"), ch);
else
die (EXIT_FAILURE, 0,
_("invalid conversion specifier in suffix: \\%.3o"), ch);
error (EXIT_FAILURE, 0,
_("invalid conversion specifier in suffix: \\%.3o"), ch);
}
if (flags & ~ compatible_flags)
die (EXIT_FAILURE, 0,
_("invalid flags in conversion specification: %%%c%c"),
(flags & ~ compatible_flags & FLAG_ALTERNATIVE ? '#' : '\''), ch);
error (EXIT_FAILURE, 0,
_("invalid flags in conversion specification: %%%c%c"),
(flags & ~ compatible_flags & FLAG_ALTERNATIVE ? '#' : '\''), ch);
}
/* Return the maximum number of bytes that can be generated by
@@ -1276,8 +1269,8 @@ max_out (char *format)
if (*f == '%' && *++f != '%')
{
if (percent)
die (EXIT_FAILURE, 0,
_("too many %% conversion specifications in suffix"));
error (EXIT_FAILURE, 0,
_("too many %% conversion specifications in suffix"));
percent = true;
int flags;
f += get_format_flags (f, &flags);
@@ -1290,10 +1283,10 @@ max_out (char *format)
}
if (! percent)
die (EXIT_FAILURE, 0,
_("missing %% conversion specification in suffix"));
error (EXIT_FAILURE, 0,
_("missing %% conversion specification in suffix"));
int maxlen = snprintf (NULL, 0, format, INT_MAX);
int maxlen = snprintf (nullptr, 0, format, INT_MAX);
if (maxlen < 0)
xalloc_die ();
return maxlen;
@@ -1313,14 +1306,15 @@ main (int argc, char **argv)
atexit (close_stdout);
global_argv = argv;
controls = NULL;
controls = nullptr;
control_used = 0;
suppress_count = false;
remove_files = true;
suppress_matched = false;
prefix = DEFAULT_PREFIX;
while ((optc = getopt_long (argc, argv, "f:b:kn:sqz", longopts, NULL)) != -1)
while ((optc = getopt_long (argc, argv, "f:b:kn:sqz", longopts, nullptr))
!= -1)
switch (optc)
{
case 'f':
@@ -1376,7 +1370,7 @@ main (int argc, char **argv)
? max_out (suffix)
: MAX (INT_STRLEN_BOUND (int), digits));
idx_t filename_size;
if (INT_ADD_WRAPV (prefix_len, max_digit_string_len + 1, &filename_size))
if (ckd_add (&filename_size, prefix_len, max_digit_string_len + 1))
xalloc_die ();
filename_space = ximalloc (filename_size);
@@ -1413,7 +1407,7 @@ main (int argc, char **argv)
sigemptyset (&caught_signals);
for (i = 0; i < nsigs; i++)
{
sigaction (sig[i], NULL, &act);
sigaction (sig[i], nullptr, &act);
if (act.sa_handler != SIG_IGN)
sigaddset (&caught_signals, sig[i]);
}
@@ -1424,7 +1418,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, nullptr);
}
split_file ();

123
src/cut.c
View File

@@ -25,12 +25,11 @@
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <getopt.h>
#include <sys/types.h>
#include "system.h"
#include "error.h"
#include "assure.h"
#include "fadvise.h"
#include "getndelim2.h"
@@ -56,7 +55,7 @@
/* Pointer inside RP. When checking if a byte or field is selected
by a finite range, we check if it is between CURRENT_RP.LO
and CURRENT_RP.HI. If the byte or field index is greater than
CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */
CURRENT_RP.HI then we make CURRENT_RP to point to the next range pair. */
static struct field_range_pair *current_rp;
/* This buffer is used to support the semantics of the -s option
@@ -71,7 +70,7 @@ static char *field_1_buffer;
/* The number of bytes allocated for FIELD_1_BUFFER. */
static size_t field_1_bufsize;
/* If true do not output lines containing no delimiter characters.
/* If true, do not output lines containing no delimiter characters.
Otherwise, all such lines are printed. This option is valid only
with field mode. */
static bool suppress_non_delimited;
@@ -80,10 +79,10 @@ static bool suppress_non_delimited;
those that were specified. */
static bool complement;
/* The delimiter character for field mode. */
/* The delimiter character for field mode. */
static unsigned char delim;
/* The delimiter for each line/record. */
/* The delimiter for each line/record. */
static unsigned char line_delim = '\n';
/* The length of output_delimiter_string. */
@@ -96,7 +95,7 @@ static char *output_delimiter_string;
/* The output delimiter string contents, if the default. */
static char output_delimiter_default[1];
/* True if we have ever read standard input. */
/* True if we have ever read standard input. */
static bool have_read_stdin;
/* For long options that have no equivalent short option, use a
@@ -109,17 +108,17 @@ enum
static struct option const longopts[] =
{
{"bytes", required_argument, NULL, 'b'},
{"characters", required_argument, NULL, 'c'},
{"fields", required_argument, NULL, 'f'},
{"delimiter", required_argument, NULL, 'd'},
{"only-delimited", no_argument, NULL, 's'},
{"output-delimiter", required_argument, NULL, OUTPUT_DELIMITER_OPTION},
{"complement", no_argument, NULL, COMPLEMENT_OPTION},
{"zero-terminated", no_argument, NULL, 'z'},
{"bytes", required_argument, nullptr, 'b'},
{"characters", required_argument, nullptr, 'c'},
{"fields", required_argument, nullptr, 'f'},
{"delimiter", required_argument, nullptr, 'd'},
{"only-delimited", no_argument, nullptr, 's'},
{"output-delimiter", required_argument, nullptr, OUTPUT_DELIMITER_OPTION},
{"complement", no_argument, nullptr, COMPLEMENT_OPTION},
{"zero-terminated", no_argument, nullptr, 'z'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -161,7 +160,7 @@ Print selected parts of lines from each FILE to standard output.\n\
the default is to use the input delimiter\n\
"), stdout);
fputs (_("\
-z, --zero-terminated line delimiter is NUL, not newline\n\
-z, --zero-terminated line delimiter is NUL, not newline\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -196,7 +195,7 @@ next_item (uintmax_t *item_idx)
current_rp++;
}
/* Return nonzero if the K'th field or byte is printable. */
/* Return nonzero if the K'th field or byte is printable. */
static inline bool
print_kth (uintmax_t k)
@@ -204,7 +203,7 @@ print_kth (uintmax_t k)
return current_rp->lo <= k;
}
/* Return nonzero if K'th byte is the beginning of a range. */
/* Return nonzero if K'th byte is the beginning of a range. */
static inline bool
is_range_start_index (uintmax_t k)
@@ -217,7 +216,7 @@ is_range_start_index (uintmax_t k)
static void
cut_bytes (FILE *stream)
{
uintmax_t byte_idx; /* Number of bytes in the line so far. */
uintmax_t byte_idx; /* Number of bytes in the line so far. */
/* Whether to begin printing delimiters between ranges for the current line.
Set after we've begun printing data corresponding to the first range. */
bool print_delimiter;
@@ -227,13 +226,14 @@ cut_bytes (FILE *stream)
current_rp = frp;
while (true)
{
int c; /* Each character from the file. */
int c; /* Each character from the file. */
c = getc (stream);
if (c == line_delim)
{
putchar (c);
if (putchar (c) < 0)
write_error ();
byte_idx = 0;
print_delimiter = false;
current_rp = frp;
@@ -241,7 +241,10 @@ cut_bytes (FILE *stream)
else if (c == EOF)
{
if (byte_idx > 0)
putchar (line_delim);
{
if (putchar (line_delim) < 0)
write_error ();
}
break;
}
else
@@ -253,13 +256,16 @@ cut_bytes (FILE *stream)
{
if (print_delimiter && is_range_start_index (byte_idx))
{
fwrite (output_delimiter_string, sizeof (char),
output_delimiter_length, stdout);
if (fwrite (output_delimiter_string, sizeof (char),
output_delimiter_length, stdout)
!= output_delimiter_length)
write_error ();
}
print_delimiter = true;
}
putchar (c);
if (putchar (c) < 0)
write_error ();
}
}
}
@@ -270,7 +276,7 @@ cut_bytes (FILE *stream)
static void
cut_fields (FILE *stream)
{
int c;
int c; /* Each character from the file. */
uintmax_t field_idx = 1;
bool found_any_selected_field = false;
bool buffer_first_field;
@@ -304,14 +310,14 @@ cut_fields (FILE *stream)
if (len < 0)
{
free (field_1_buffer);
field_1_buffer = NULL;
field_1_buffer = nullptr;
if (ferror (stream) || feof (stream))
break;
xalloc_die ();
}
n_bytes = len;
assert (n_bytes != 0);
affirm (n_bytes != 0);
c = 0;
@@ -326,18 +332,26 @@ cut_fields (FILE *stream)
}
else
{
fwrite (field_1_buffer, sizeof (char), n_bytes, stdout);
if (fwrite (field_1_buffer, sizeof (char), n_bytes, stdout)
!= n_bytes)
write_error ();
/* Make sure the output line is newline terminated. */
if (field_1_buffer[n_bytes - 1] != line_delim)
putchar (line_delim);
{
if (putchar (line_delim) < 0)
write_error ();
}
c = line_delim;
}
continue;
}
if (print_kth (1))
{
/* Print the field, but not the trailing delimiter. */
fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout);
if (fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout)
!= n_bytes - 1)
write_error ();
/* With -d$'\n' don't treat the last '\n' as a delimiter. */
if (delim == line_delim)
@@ -350,7 +364,9 @@ cut_fields (FILE *stream)
}
}
else
found_any_selected_field = true;
{
found_any_selected_field = true;
}
}
next_item (&field_idx);
}
@@ -361,23 +377,24 @@ cut_fields (FILE *stream)
{
if (found_any_selected_field)
{
fwrite (output_delimiter_string, sizeof (char),
output_delimiter_length, stdout);
if (fwrite (output_delimiter_string, sizeof (char),
output_delimiter_length, stdout)
!= output_delimiter_length)
write_error ();
}
found_any_selected_field = true;
while ((c = getc (stream)) != delim && c != line_delim && c != EOF)
{
putchar (c);
if (putchar (c) < 0)
write_error ();
prev_c = c;
}
}
else
{
while ((c = getc (stream)) != delim && c != line_delim && c != EOF)
{
prev_c = c;
}
prev_c = c;
}
/* With -d$'\n' don't treat the last '\n' as a delimiter. */
@@ -397,12 +414,18 @@ cut_fields (FILE *stream)
if (found_any_selected_field
|| !(suppress_non_delimited && field_idx == 1))
{
/* Make sure the output line is newline terminated. */
if (c == line_delim || prev_c != line_delim
|| delim == line_delim)
putchar (line_delim);
{
if (putchar (line_delim) < 0)
write_error ();
}
}
if (c == EOF)
break;
/* Start processing the next input line. */
field_idx = 1;
current_rp = frp;
found_any_selected_field = false;
@@ -422,11 +445,12 @@ cut_file (char const *file, void (*cut_stream) (FILE *))
{
have_read_stdin = true;
stream = stdin;
assume (stream); /* Pacify GCC bug#109613. */
}
else
{
stream = fopen (file, "r");
if (stream == NULL)
if (stream == nullptr)
{
error (0, errno, "%s", quotef (file));
return false;
@@ -441,7 +465,7 @@ cut_file (char const *file, void (*cut_stream) (FILE *))
if (!ferror (stream))
err = 0;
if (STREQ (file, "-"))
clearerr (stream); /* Also clear EOF. */
clearerr (stream); /* Also clear EOF. */
else if (fclose (stream) == EOF)
err = errno;
if (err)
@@ -459,7 +483,7 @@ main (int argc, char **argv)
bool ok;
bool delim_specified = false;
bool byte_mode = false;
char *spec_list_string = NULL;
char *spec_list_string = nullptr;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -475,24 +499,25 @@ main (int argc, char **argv)
delim = '\0';
have_read_stdin = false;
while ((optc = getopt_long (argc, argv, "b:c:d:f:nsz", longopts, NULL)) != -1)
while ((optc = getopt_long (argc, argv, "b:c:d:f:nsz", longopts, nullptr))
!= -1)
{
switch (optc)
{
case 'b':
case 'c':
/* Build the byte list. */
/* Build the byte list. */
byte_mode = true;
FALLTHROUGH;
case 'f':
/* Build the field list. */
/* Build the field list. */
if (spec_list_string)
FATAL_ERROR (_("only one list may be specified"));
spec_list_string = optarg;
break;
case 'd':
/* New delimiter. */
/* 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"));
@@ -524,9 +549,7 @@ main (int argc, char **argv)
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (EXIT_FAILURE);
}
@@ -553,7 +576,7 @@ main (int argc, char **argv)
if (!delim_specified)
delim = '\t';
if (output_delimiter_string == NULL)
if (output_delimiter_string == nullptr)
{
output_delimiter_default[0] = delim;
output_delimiter_string = output_delimiter_default;

View File

@@ -26,8 +26,6 @@
#include "system.h"
#include "argmatch.h"
#include "die.h"
#include "error.h"
#include "parse-datetime.h"
#include "posixtm.h"
#include "quote.h"
@@ -63,7 +61,7 @@ static char const *const time_spec_string[] =
/* Put "hours" and "minutes" first, since they aren't valid for
--rfc-3339. */
"hours", "minutes",
"date", "seconds", "ns", NULL
"date", "seconds", "ns", nullptr
};
static enum Time_spec const time_spec[] =
{
@@ -88,23 +86,23 @@ static char const short_options[] = "d:f:I::r:Rs:u";
static struct option const long_options[] =
{
{"date", required_argument, NULL, 'd'},
{"debug", no_argument, NULL, DEBUG_DATE_PARSING_OPTION},
{"file", required_argument, NULL, 'f'},
{"iso-8601", optional_argument, NULL, 'I'},
{"reference", required_argument, NULL, 'r'},
{"resolution", no_argument, NULL, RESOLUTION_OPTION},
{"rfc-email", no_argument, NULL, 'R'},
{"rfc-822", no_argument, NULL, 'R'},
{"rfc-2822", no_argument, NULL, 'R'},
{"rfc-3339", required_argument, NULL, RFC_3339_OPTION},
{"set", required_argument, NULL, 's'},
{"uct", no_argument, NULL, 'u'},
{"utc", no_argument, NULL, 'u'},
{"universal", no_argument, NULL, 'u'},
{"date", required_argument, nullptr, 'd'},
{"debug", no_argument, nullptr, DEBUG_DATE_PARSING_OPTION},
{"file", required_argument, nullptr, 'f'},
{"iso-8601", optional_argument, nullptr, 'I'},
{"reference", required_argument, nullptr, 'r'},
{"resolution", no_argument, nullptr, RESOLUTION_OPTION},
{"rfc-email", no_argument, nullptr, 'R'},
{"rfc-822", no_argument, nullptr, 'R'},
{"rfc-2822", no_argument, nullptr, 'R'},
{"rfc-3339", required_argument, nullptr, RFC_3339_OPTION},
{"set", required_argument, nullptr, 's'},
{"uct", no_argument, nullptr, 'u'},
{"utc", no_argument, nullptr, 'u'},
{"universal", no_argument, nullptr, 'u'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* flags for parse_datetime2 */
@@ -307,12 +305,12 @@ res_width (long int res)
/* Return a newly allocated copy of FORMAT with each "%-N" adjusted to
be "%9N", "%6N", or whatever other resolution is appropriate for
the current platform. If no "%-N" appears, return NULL. */
the current platform. If no "%-N" appears, return nullptr. */
static char *
adjust_resolution (char const *format)
{
char *copy = NULL;
char *copy = nullptr;
for (char const *f = format; *f; f++)
if (f[0] == '%')
@@ -354,13 +352,11 @@ batch_convert (char const *input_filename, char const *format,
else
{
in_stream = fopen (input_filename, "r");
if (in_stream == NULL)
{
die (EXIT_FAILURE, errno, "%s", quotef (input_filename));
}
if (in_stream == nullptr)
error (EXIT_FAILURE, errno, "%s", quotef (input_filename));
}
line = NULL;
line = nullptr;
buflen = 0;
ok = true;
while (true)
@@ -368,11 +364,13 @@ batch_convert (char const *input_filename, char const *format,
ssize_t line_length = getline (&line, &buflen, in_stream);
if (line_length < 0)
{
/* FIXME: detect/handle error here. */
if (ferror (in_stream))
error (EXIT_FAILURE, errno, _("%s: read error"),
quotef (input_filename));
break;
}
if (! parse_datetime2 (&when, line, NULL,
if (! parse_datetime2 (&when, line, nullptr,
parse_datetime_flags, tz, tzstring))
{
if (line[line_length - 1] == '\n')
@@ -387,7 +385,7 @@ batch_convert (char const *input_filename, char const *format,
}
if (fclose (in_stream) == EOF)
die (EXIT_FAILURE, errno, "%s", quotef (input_filename));
error (EXIT_FAILURE, errno, "%s", quotef (input_filename));
free (line);
@@ -398,14 +396,14 @@ int
main (int argc, char **argv)
{
int optc;
char const *datestr = NULL;
char const *set_datestr = NULL;
char const *datestr = nullptr;
char const *set_datestr = nullptr;
struct timespec when;
bool set_date = false;
char const *format = NULL;
char const *format = nullptr;
bool get_resolution = false;
char *batch_file = NULL;
char *reference = NULL;
char *batch_file = nullptr;
char *reference = nullptr;
struct stat refstats;
bool ok;
bool discarded_datestr = false;
@@ -419,10 +417,10 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, short_options, long_options, NULL))
while ((optc = getopt_long (argc, argv, short_options, long_options, nullptr))
!= -1)
{
char const *new_format = NULL;
char const *new_format = nullptr;
switch (optc)
{
@@ -500,7 +498,7 @@ main (int argc, char **argv)
if (new_format)
{
if (format)
die (EXIT_FAILURE, 0, _("multiple output formats specified"));
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
format = new_format;
}
}
@@ -539,7 +537,7 @@ main (int argc, char **argv)
if (argv[optind][0] == '+')
{
if (format)
die (EXIT_FAILURE, 0, _("multiple output formats specified"));
error (EXIT_FAILURE, 0, _("multiple output formats specified"));
format = argv[optind++] + 1;
}
else if (set_date || option_specified_date)
@@ -578,7 +576,7 @@ main (int argc, char **argv)
char const *tzstring = getenv ("TZ");
timezone_t tz = tzalloc (tzstring);
if (batch_file != NULL)
if (batch_file != nullptr)
ok = batch_convert (batch_file, format_res, tz, tzstring);
else
{
@@ -608,10 +606,10 @@ main (int argc, char **argv)
else
{
/* (option_specified_date || set_date) */
if (reference != NULL)
if (reference != nullptr)
{
if (stat (reference, &refstats) != 0)
die (EXIT_FAILURE, errno, "%s", quotef (reference));
error (EXIT_FAILURE, errno, "%s", quotef (reference));
when = get_stat_mtime (&refstats);
}
else if (get_resolution)
@@ -624,14 +622,14 @@ main (int argc, char **argv)
{
if (set_datestr)
datestr = set_datestr;
valid_date = parse_datetime2 (&when, datestr, NULL,
valid_date = parse_datetime2 (&when, datestr, nullptr,
parse_datetime_flags,
tz, tzstring);
}
}
if (! valid_date)
die (EXIT_FAILURE, 0, _("invalid date %s"), quote (datestr));
error (EXIT_FAILURE, 0, _("invalid date %s"), quote (datestr));
if (set_date)
{

233
src/dd.c
View File

@@ -20,12 +20,11 @@
#include <sys/types.h>
#include <signal.h>
#include <stdckdint.h>
#include "system.h"
#include "alignalloc.h"
#include "close-stream.h"
#include "die.h"
#include "error.h"
#include "fd-reopen.h"
#include "gethrxtime.h"
#include "human.h"
@@ -127,11 +126,11 @@ enum
STATUS_PROGRESS = 4
};
/* The name of the input file, or NULL for the standard input. */
static char const *input_file = NULL;
/* The name of the input file, or nullptr for the standard input. */
static char const *input_file = nullptr;
/* The name of the output file, or NULL for the standard output. */
static char const *output_file = NULL;
/* The name of the output file, or nullptr for the standard output. */
static char const *output_file = nullptr;
/* The page size on this host. */
static idx_t page_size;
@@ -514,11 +513,12 @@ maybe_close_stdout (void)
_exit (EXIT_FAILURE);
}
/* Like the 'error' function but handle any pending newline. */
/* Like the 'error' function but handle any pending newline,
and do not exit. */
ATTRIBUTE_FORMAT ((__printf__, 3, 4))
ATTRIBUTE_FORMAT ((__printf__, 2, 3))
static void
nl_error (int status, int errnum, char const *fmt, ...)
diagnose (int errnum, char const *fmt, ...)
{
if (0 < progress_len)
{
@@ -528,12 +528,10 @@ nl_error (int status, int errnum, char const *fmt, ...)
va_list ap;
va_start (ap, fmt);
verror (status, errnum, fmt, ap);
verror (0, errnum, fmt, ap);
va_end (ap);
}
#define error nl_error
void
usage (int status)
{
@@ -676,11 +674,11 @@ alloc_ibuf (void)
if (!ibuf)
{
char hbuf[LONGEST_HUMAN_READABLE + 1];
die (EXIT_FAILURE, 0,
_("memory exhausted by input buffer of size %td bytes (%s)"),
input_blocksize,
human_readable (input_blocksize, hbuf,
human_opts | human_base_1024, 1, 1));
error (EXIT_FAILURE, 0,
_("memory exhausted by input buffer of size %td bytes (%s)"),
input_blocksize,
human_readable (input_blocksize, hbuf,
human_opts | human_base_1024, 1, 1));
}
}
@@ -698,12 +696,12 @@ alloc_obuf (void)
if (!obuf)
{
char hbuf[LONGEST_HUMAN_READABLE + 1];
die (EXIT_FAILURE, 0,
_("memory exhausted by output buffer of size %td"
" bytes (%s)"),
output_blocksize,
human_readable (output_blocksize, hbuf,
human_opts | human_base_1024, 1, 1));
error (EXIT_FAILURE, 0,
_("memory exhausted by output buffer of size %td"
" bytes (%s)"),
output_blocksize,
human_readable (output_blocksize, hbuf,
human_opts | human_base_1024, 1, 1));
}
}
else
@@ -877,7 +875,7 @@ install_signal_handlers (void)
sigemptyset (&caught_signals);
if (catch_siginfo)
sigaddset (&caught_signals, SIGINFO);
sigaction (SIGINT, NULL, &act);
sigaction (SIGINT, nullptr, &act);
if (act.sa_handler != SIG_IGN)
sigaddset (&caught_signals, SIGINT);
act.sa_mask = caught_signals;
@@ -887,16 +885,16 @@ install_signal_handlers (void)
act.sa_handler = siginfo_handler;
/* Note we don't use SA_RESTART here and instead
handle EINTR explicitly in iftruncate etc.
to avoid blocking on noncommitted read/write calls. */
to avoid blocking on uncommitted read/write calls. */
act.sa_flags = 0;
sigaction (SIGINFO, &act, NULL);
sigaction (SIGINFO, &act, nullptr);
}
if (sigismember (&caught_signals, SIGINT))
{
act.sa_handler = interrupt_handler;
act.sa_flags = SA_NODEFER | SA_RESETHAND;
sigaction (SIGINT, &act, NULL);
sigaction (SIGINT, &act, nullptr);
}
#else
@@ -944,14 +942,15 @@ cleanup (void)
}
if (iclose (STDIN_FILENO) != 0)
die (EXIT_FAILURE, errno, _("closing input file %s"), quoteaf (input_file));
error (EXIT_FAILURE, errno, _("closing input file %s"),
quoteaf (input_file));
/* Don't remove this call to close, even though close_stdout
closes standard output. This close is necessary when cleanup
is called as a consequence of signal handling. */
if (iclose (STDOUT_FILENO) != 0)
die (EXIT_FAILURE, errno,
_("closing output file %s"), quoteaf (output_file));
error (EXIT_FAILURE, errno,
_("closing output file %s"), quoteaf (output_file));
}
/* Process any pending signals. If signals are caught, this function
@@ -977,7 +976,7 @@ process_signals (void)
if (infos)
info_signal_count = infos - 1;
sigprocmask (SIG_SETMASK, &oldset, NULL);
sigprocmask (SIG_SETMASK, &oldset, nullptr);
if (interrupt)
cleanup ();
@@ -1017,7 +1016,7 @@ cache_round (int fd, off_t len)
if (len)
{
intmax_t c_pending;
if (INT_ADD_WRAPV (*pending, len, &c_pending))
if (ckd_add (&c_pending, *pending, len))
c_pending = INTMAX_MAX;
*pending = c_pending % IO_BUFSIZE;
if (c_pending > *pending)
@@ -1137,12 +1136,12 @@ iread (int fd, char *buf, idx_t size)
{
idx_t prev = prev_nread;
if (status_level != STATUS_NONE)
error (0, 0, ngettext (("warning: partial read (%td byte); "
diagnose (0, ngettext (("warning: partial read (%td byte); "
"suggest iflag=fullblock"),
("warning: partial read (%td bytes); "
"suggest iflag=fullblock"),
select_plural (prev)),
prev);
prev);
warn_partial_read = false;
}
}
@@ -1187,8 +1186,8 @@ iwrite (int fd, char const *buf, idx_t size)
int old_flags = fcntl (STDOUT_FILENO, F_GETFL);
if (fcntl (STDOUT_FILENO, F_SETFL, old_flags & ~O_DIRECT) != 0
&& status_level != STATUS_NONE)
error (0, errno, _("failed to turn off O_DIRECT: %s"),
quotef (output_file));
diagnose (errno, _("failed to turn off O_DIRECT: %s"),
quotef (output_file));
/* Since we have just turned off O_DIRECT for the final write,
we try to preserve some of its semantics. */
@@ -1262,7 +1261,7 @@ write_output (void)
w_bytes += nwritten;
if (nwritten != output_blocksize)
{
error (0, errno, _("writing to %s"), quoteaf (output_file));
diagnose (errno, _("writing to %s"), quoteaf (output_file));
if (nwritten != 0)
w_partial++;
quit (EXIT_FAILURE);
@@ -1391,8 +1390,9 @@ parse_symbols (char const *str, struct symbol_value const *table,
if (! entry->symbol[0])
{
idx_t slen = strcomma ? strcomma - str : strlen (str);
error (0, 0, "%s: %s", _(error_msgid),
quotearg_n_style_mem (0, locale_quoting_style, str, slen));
diagnose (0, "%s: %s", _(error_msgid),
quotearg_n_style_mem (0, locale_quoting_style,
str, slen));
usage (EXIT_FAILURE);
}
}
@@ -1418,7 +1418,7 @@ static intmax_t
parse_integer (char const *str, strtol_error *invalid)
{
/* Call xstrtoumax, not xstrtoimax, since we don't want to
allow strings like " -0". Initialize N to an interminate value;
allow strings like " -0". Initialize N to an indeterminate value;
calling code should not rely on this function returning 0
when *INVALID represents a non-overflow error. */
int indeterminate = 0;
@@ -1429,7 +1429,7 @@ parse_integer (char const *str, strtol_error *invalid)
intmax_t result;
if ((e & ~LONGINT_OVERFLOW) == LONGINT_INVALID_SUFFIX_CHAR
&& suffix[-1] != 'B' && *suffix == 'B')
&& *suffix == 'B' && str < suffix && suffix[-1] != 'B')
{
suffix++;
if (!*suffix)
@@ -1437,16 +1437,16 @@ parse_integer (char const *str, strtol_error *invalid)
}
if ((e & ~LONGINT_OVERFLOW) == LONGINT_INVALID_SUFFIX_CHAR
&& *suffix == 'x' && ! (suffix[-1] == 'B' && strchr (suffix + 1, 'B')))
&& *suffix == 'x')
{
uintmax_t o;
strtol_error f = xstrtoumax (suffix + 1, &suffix, 10, &o, suffixes);
strtol_error f = LONGINT_OK;
intmax_t o = parse_integer (suffix + 1, &f);
if ((f & ~LONGINT_OVERFLOW) != LONGINT_OK)
{
e = f;
result = indeterminate;
}
else if (INT_MULTIPLY_WRAPV (n, o, &result)
else if (ckd_mul (&result, n, o)
|| (result != 0 && ((e | f) & LONGINT_OVERFLOW)))
{
e = LONGINT_OVERFLOW;
@@ -1455,10 +1455,9 @@ parse_integer (char const *str, strtol_error *invalid)
else
{
if (result == 0 && STRPREFIX (str, "0x"))
error (0, 0,
_("warning: %s is a zero multiplier; "
"use %s if that is intended"),
quote_n (0, "0x"), quote_n (1, "00x"));
diagnose (0, _("warning: %s is a zero multiplier; "
"use %s if that is intended"),
quote_n (0, "0x"), quote_n (1, "00x"));
e = LONGINT_OK;
}
}
@@ -1497,10 +1496,9 @@ scanargs (int argc, char *const *argv)
char const *name = argv[i];
char const *val = strchr (name, '=');
if (val == NULL)
if (val == nullptr)
{
error (0, 0, _("unrecognized operand %s"),
quote (name));
diagnose (0, _("unrecognized operand %s"), quoteaf (name));
usage (EXIT_FAILURE);
}
val++;
@@ -1528,7 +1526,7 @@ scanargs (int argc, char *const *argv)
bool has_B = !!strchr (val, 'B');
intmax_t n_min = 0;
intmax_t n_max = INTMAX_MAX;
idx_t *converted_idx = NULL;
idx_t *converted_idx = nullptr;
/* Maximum blocksize. Keep it smaller than IDX_MAX, so that
it fits into blocksize vars even if 1 is added for conv=swab.
@@ -1578,8 +1576,7 @@ scanargs (int argc, char *const *argv)
}
else
{
error (0, 0, _("unrecognized operand %s"),
quote (name));
diagnose (0, _("unrecognized operand %s"), quoteaf (name));
usage (EXIT_FAILURE);
}
@@ -1589,8 +1586,8 @@ scanargs (int argc, char *const *argv)
invalid = LONGINT_OVERFLOW;
if (invalid != LONGINT_OK)
die (EXIT_FAILURE, invalid == LONGINT_OVERFLOW ? EOVERFLOW : 0,
"%s: %s", _("invalid number"), quote (val));
error (EXIT_FAILURE, invalid == LONGINT_OVERFLOW ? EOVERFLOW : 0,
"%s: %s", _("invalid number"), quoteaf (val));
else if (converted_idx)
*converted_idx = n;
}
@@ -1617,7 +1614,7 @@ scanargs (int argc, char *const *argv)
if (output_flags & O_FULLBLOCK)
{
error (0, 0, "%s: %s", _("invalid output flag"), quote ("fullblock"));
diagnose (0, "%s: %s", _("invalid output flag"), quote ("fullblock"));
usage (EXIT_FAILURE);
}
@@ -1667,16 +1664,16 @@ scanargs (int argc, char *const *argv)
input_flags &= ~O_FULLBLOCK;
if (multiple_bits_set (conversions_mask & (C_ASCII | C_EBCDIC | C_IBM)))
die (EXIT_FAILURE, 0, _("cannot combine any two of {ascii,ebcdic,ibm}"));
error (EXIT_FAILURE, 0, _("cannot combine any two of {ascii,ebcdic,ibm}"));
if (multiple_bits_set (conversions_mask & (C_BLOCK | C_UNBLOCK)))
die (EXIT_FAILURE, 0, _("cannot combine block and unblock"));
error (EXIT_FAILURE, 0, _("cannot combine block and unblock"));
if (multiple_bits_set (conversions_mask & (C_LCASE | C_UCASE)))
die (EXIT_FAILURE, 0, _("cannot combine lcase and ucase"));
error (EXIT_FAILURE, 0, _("cannot combine lcase and ucase"));
if (multiple_bits_set (conversions_mask & (C_EXCL | C_NOCREAT)))
die (EXIT_FAILURE, 0, _("cannot combine excl and nocreat"));
error (EXIT_FAILURE, 0, _("cannot combine excl and nocreat"));
if (multiple_bits_set (input_flags & (O_DIRECT | O_NOCACHE))
|| multiple_bits_set (output_flags & (O_DIRECT | O_NOCACHE)))
die (EXIT_FAILURE, 0, _("cannot combine direct and nocache"));
error (EXIT_FAILURE, 0, _("cannot combine direct and nocache"));
if (input_flags & O_NOCACHE)
{
@@ -1784,7 +1781,7 @@ swab_buffer (char *buf, idx_t *nread, int *saved_byte)
static void
advance_input_offset (intmax_t offset)
{
if (0 <= input_offset && INT_ADD_WRAPV (input_offset, offset, &input_offset))
if (0 <= input_offset && ckd_add (&input_offset, input_offset, offset))
input_offset = -1;
}
@@ -1807,15 +1804,15 @@ skip (int fdesc, char const *file, intmax_t records, idx_t blocksize,
errno = 0;
off_t offset;
if (! INT_MULTIPLY_WRAPV (records, blocksize, &offset)
&& ! INT_ADD_WRAPV (offset, *bytes, &offset)
if (! ckd_mul (&offset, records, blocksize)
&& ! ckd_add (&offset, offset, *bytes)
&& 0 <= lseek (fdesc, offset, SEEK_CUR))
{
if (fdesc == STDIN_FILENO)
{
struct stat st;
if (ifstat (STDIN_FILENO, &st) != 0)
die (EXIT_FAILURE, errno, _("cannot fstat %s"), quoteaf (file));
error (EXIT_FAILURE, errno, _("cannot fstat %s"), quoteaf (file));
if (usable_st_size (&st) && 0 <= input_offset
&& st.st_size - input_offset < offset)
{
@@ -1862,10 +1859,11 @@ skip (int fdesc, char const *file, intmax_t records, idx_t blocksize,
lseek_errno = EOVERFLOW;
}
if (fdesc == STDIN_FILENO)
error (0, lseek_errno, _("%s: cannot skip"), quotef (file));
else
error (0, lseek_errno, _("%s: cannot seek"), quotef (file));
diagnose (lseek_errno,
gettext (fdesc == STDIN_FILENO
? N_("%s: cannot skip")
: N_("%s: cannot seek")),
quotef (file));
/* If the file has a specific size and we've asked
to skip/seek beyond the max allowable, then quit. */
quit (EXIT_FAILURE);
@@ -1891,12 +1889,12 @@ skip (int fdesc, char const *file, intmax_t records, idx_t blocksize,
{
if (fdesc == STDIN_FILENO)
{
error (0, errno, _("error reading %s"), quoteaf (file));
diagnose (errno, _("error reading %s"), quoteaf (file));
if (conversions_mask & C_NOERROR)
print_stats ();
}
else
error (0, lseek_errno, _("%s: cannot seek"), quotef (file));
diagnose (lseek_errno, _("%s: cannot seek"), quotef (file));
quit (EXIT_FAILURE);
}
else if (nread == 0)
@@ -1936,8 +1934,8 @@ advance_input_after_read_error (idx_t nbytes)
advance_input_offset (nbytes);
if (input_offset < 0)
{
error (0, 0, _("offset overflow while reading file %s"),
quoteaf (input_file));
diagnose (0, _("offset overflow while reading file %s"),
quoteaf (input_file));
return false;
}
offset = lseek (STDIN_FILENO, 0, SEEK_CUR);
@@ -1948,15 +1946,15 @@ advance_input_after_read_error (idx_t nbytes)
return true;
diff = input_offset - offset;
if (! (0 <= diff && diff <= nbytes) && status_level != STATUS_NONE)
error (0, 0, _("warning: invalid file offset after failed read"));
diagnose (0, _("warning: invalid file offset after failed read"));
if (0 <= lseek (STDIN_FILENO, diff, SEEK_CUR))
return true;
if (errno == 0)
error (0, 0, _("cannot work around kernel bug after all"));
diagnose (0, _("cannot work around kernel bug after all"));
}
}
error (0, errno, _("%s: cannot seek"), quotef (input_file));
diagnose (errno, _("%s: cannot seek"), quotef (input_file));
return false;
}
@@ -2091,7 +2089,7 @@ set_fd_flags (int fd, int add_flags, char const *name)
}
if (!ok)
die (EXIT_FAILURE, errno, _("setting flags for %s"), quoteaf (name));
error (EXIT_FAILURE, errno, _("setting flags for %s"), quoteaf (name));
}
}
@@ -2114,8 +2112,8 @@ dd_copy (void)
{
intmax_t us_bytes;
bool us_bytes_overflow =
(INT_MULTIPLY_WRAPV (skip_records, input_blocksize, &us_bytes)
|| INT_ADD_WRAPV (skip_bytes, us_bytes, &us_bytes));
(ckd_mul (&us_bytes, skip_records, input_blocksize)
|| ckd_add (&us_bytes, skip_bytes, us_bytes));
off_t input_offset0 = input_offset;
intmax_t us_blocks = skip (STDIN_FILENO, input_file,
skip_records, input_blocksize, &skip_bytes);
@@ -2132,8 +2130,8 @@ dd_copy (void)
|| us_bytes != input_offset - input_offset0)))
&& status_level != STATUS_NONE)
{
error (0, 0,
_("%s: cannot skip to specified offset"), quotef (input_file));
diagnose (0, _("%s: cannot skip to specified offset"),
quotef (input_file));
}
}
@@ -2152,7 +2150,7 @@ dd_copy (void)
idx_t size = write_records ? output_blocksize : bytes;
if (iwrite (STDOUT_FILENO, obuf, size) != size)
{
error (0, errno, _("writing to %s"), quoteaf (output_file));
diagnose (errno, _("writing to %s"), quoteaf (output_file));
quit (EXIT_FAILURE);
}
@@ -2215,7 +2213,7 @@ dd_copy (void)
else
{
if (!(conversions_mask & C_NOERROR) || status_level != STATUS_NONE)
error (0, errno, _("error reading %s"), quoteaf (input_file));
diagnose (errno, _("error reading %s"), quoteaf (input_file));
if (conversions_mask & C_NOERROR)
{
@@ -2278,7 +2276,7 @@ dd_copy (void)
w_bytes += nwritten;
if (nwritten != n_bytes_read)
{
error (0, errno, _("error writing %s"), quoteaf (output_file));
diagnose (errno, _("error writing %s"), quoteaf (output_file));
return EXIT_FAILURE;
}
else if (n_bytes_read == input_blocksize)
@@ -2341,7 +2339,7 @@ dd_copy (void)
w_partial++;
if (nwritten != oc)
{
error (0, errno, _("error writing %s"), quoteaf (output_file));
diagnose (errno, _("error writing %s"), quoteaf (output_file));
return EXIT_FAILURE;
}
}
@@ -2353,7 +2351,7 @@ dd_copy (void)
struct stat stdout_stat;
if (ifstat (STDOUT_FILENO, &stdout_stat) != 0)
{
error (0, errno, _("cannot fstat %s"), quoteaf (output_file));
diagnose (errno, _("cannot fstat %s"), quoteaf (output_file));
return EXIT_FAILURE;
}
if (S_ISREG (stdout_stat.st_mode) || S_TYPEISSHM (&stdout_stat))
@@ -2363,10 +2361,9 @@ dd_copy (void)
{
if (iftruncate (STDOUT_FILENO, output_offset) != 0)
{
error (0, errno,
_("failed to truncate to %" PRIdMAX " bytes"
" in output file %s"),
(intmax_t) output_offset, quoteaf (output_file));
diagnose (errno, _("failed to truncate to %" PRIdMAX " bytes"
" in output file %s"),
(intmax_t) output_offset, quoteaf (output_file));
return EXIT_FAILURE;
}
}
@@ -2400,7 +2397,7 @@ synchronize_output (void)
{
if (errno != ENOSYS && errno != EINVAL)
{
error (0, errno, _("fdatasync failed for %s"), quoteaf (output_file));
diagnose (errno, _("fdatasync failed for %s"), quoteaf (output_file));
exit_status = EXIT_FAILURE;
}
mask |= C_FSYNC;
@@ -2408,7 +2405,7 @@ synchronize_output (void)
if ((mask & C_FSYNC) && ifsync (STDOUT_FILENO) != 0)
{
error (0, errno, _("fsync failed for %s"), quoteaf (output_file));
diagnose (errno, _("fsync failed for %s"), quoteaf (output_file));
return EXIT_FAILURE;
}
@@ -2436,7 +2433,8 @@ main (int argc, char **argv)
page_size = getpagesize ();
parse_gnu_standard_options_only (argc, argv, PROGRAM_NAME, PACKAGE, Version,
true, usage, AUTHORS, (char const *) NULL);
true, usage, AUTHORS,
(char const *) nullptr);
close_stdout_required = false;
/* Initialize translation table to identity translation. */
@@ -2448,7 +2446,7 @@ main (int argc, char **argv)
apply_translations ();
if (input_file == NULL)
if (input_file == nullptr)
{
input_file = _("standard input");
set_fd_flags (STDIN_FILENO, input_flags, input_file);
@@ -2456,8 +2454,8 @@ main (int argc, char **argv)
else
{
if (ifd_reopen (STDIN_FILENO, input_file, O_RDONLY | input_flags, 0) < 0)
die (EXIT_FAILURE, errno, _("failed to open %s"),
quoteaf (input_file));
error (EXIT_FAILURE, errno, _("failed to open %s"),
quoteaf (input_file));
}
offset = lseek (STDIN_FILENO, 0, SEEK_CUR);
@@ -2465,7 +2463,7 @@ main (int argc, char **argv)
input_offset = MAX (0, offset);
input_seek_errno = errno;
if (output_file == NULL)
if (output_file == nullptr)
{
output_file = _("standard output");
set_fd_flags (STDOUT_FILENO, output_flags, output_file);
@@ -2480,14 +2478,14 @@ main (int argc, char **argv)
| (seek_records || (conversions_mask & C_NOTRUNC) ? 0 : O_TRUNC));
off_t size;
if ((INT_MULTIPLY_WRAPV (seek_records, output_blocksize, &size)
|| INT_ADD_WRAPV (seek_bytes, size, &size))
if ((ckd_mul (&size, seek_records, output_blocksize)
|| ckd_add (&size, seek_bytes, size))
&& !(conversions_mask & C_NOTRUNC))
die (EXIT_FAILURE, 0,
_("offset too large: "
"cannot truncate to a length of seek=%"PRIdMAX""
" (%td-byte) blocks"),
seek_records, output_blocksize);
error (EXIT_FAILURE, 0,
_("offset too large: "
"cannot truncate to a length of seek=%"PRIdMAX""
" (%td-byte) blocks"),
seek_records, output_blocksize);
/* Open the output file with *read* access only if we might
need to read to satisfy a 'seek=' request. If we can't read
@@ -2496,8 +2494,8 @@ main (int argc, char **argv)
|| ifd_reopen (STDOUT_FILENO, output_file, O_RDWR | opts, perms) < 0)
&& (ifd_reopen (STDOUT_FILENO, output_file, O_WRONLY | opts, perms)
< 0))
die (EXIT_FAILURE, errno, _("failed to open %s"),
quoteaf (output_file));
error (EXIT_FAILURE, errno, _("failed to open %s"),
quoteaf (output_file));
if (seek_records != 0 && !(conversions_mask & C_NOTRUNC))
{
@@ -2512,8 +2510,7 @@ main (int argc, char **argv)
struct stat stdout_stat;
if (ifstat (STDOUT_FILENO, &stdout_stat) != 0)
{
error (0, errno, _("cannot fstat %s"),
quoteaf (output_file));
diagnose (errno, _("cannot fstat %s"), quoteaf (output_file));
exit_status = EXIT_FAILURE;
}
else if (S_ISREG (stdout_stat.st_mode)
@@ -2521,10 +2518,10 @@ main (int argc, char **argv)
|| S_TYPEISSHM (&stdout_stat))
{
intmax_t isize = size;
error (0, ftruncate_errno,
_("failed to truncate to %"PRIdMAX" bytes"
" in output file %s"),
isize, quoteaf (output_file));
diagnose (ftruncate_errno,
_("failed to truncate to %"PRIdMAX" bytes"
" in output file %s"),
isize, quoteaf (output_file));
exit_status = EXIT_FAILURE;
}
}
@@ -2545,14 +2542,14 @@ main (int argc, char **argv)
/* Special case to invalidate cache to end of file. */
if (i_nocache && !invalidate_cache (STDIN_FILENO, 0))
{
error (0, errno, _("failed to discard cache for: %s"),
quotef (input_file));
diagnose (errno, _("failed to discard cache for: %s"),
quotef (input_file));
exit_status = EXIT_FAILURE;
}
if (o_nocache && !invalidate_cache (STDOUT_FILENO, 0))
{
error (0, errno, _("failed to discard cache for: %s"),
quotef (output_file));
diagnose (errno, _("failed to discard cache for: %s"),
quotef (output_file));
exit_status = EXIT_FAILURE;
}
}

219
src/df.c
View File

@@ -22,15 +22,13 @@
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include <assert.h>
#include <c-ctype.h>
#include <wchar.h>
#include <wctype.h>
#include "system.h"
#include "assure.h"
#include "canonicalize.h"
#include "die.h"
#include "error.h"
#include "fsusage.h"
#include "human.h"
#include "mbsalign.h"
@@ -45,7 +43,7 @@
#define PROGRAM_NAME "df"
#define AUTHORS \
proper_name ("Torbjorn Granlund"), \
proper_name_lite ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
proper_name ("David MacKenzie"), \
proper_name ("Paul Eggert")
@@ -99,7 +97,7 @@ struct fs_type_list
};
/* Linked list of file system types to display.
If 'fs_select_list' is NULL, list all types.
If 'fs_select_list' is null, list all types.
This table is generated dynamically from command-line options,
rather than hardcoding into the program what it thinks are the
valid file system types; let the user specify any file system type
@@ -129,15 +127,14 @@ static bool print_grand_total;
static struct fs_usage grand_fsu;
/* Display modes. */
enum
static enum
{
DEFAULT_MODE,
INODES_MODE,
HUMAN_MODE,
POSIX_MODE,
OUTPUT_MODE
};
static int header_mode = DEFAULT_MODE;
} header_mode = DEFAULT_MODE;
/* Displayable fields. */
typedef enum
@@ -171,7 +168,7 @@ struct field_data_t
display_field_t field;
char const *arg;
field_type_t field_type;
char const *caption;/* NULL means to use the default header of this field. */
char const *caption;/* nullptr means use default header of this field. */
size_t width; /* Auto adjusted (up) widths used to align columns. */
mbs_align_t align; /* Alignment for this field. */
bool used;
@@ -257,23 +254,23 @@ enum
static struct option const long_options[] =
{
{"all", no_argument, NULL, 'a'},
{"block-size", required_argument, NULL, 'B'},
{"inodes", no_argument, NULL, 'i'},
{"human-readable", no_argument, NULL, 'h'},
{"si", no_argument, NULL, 'H'},
{"local", no_argument, NULL, 'l'},
{"output", optional_argument, NULL, OUTPUT_OPTION},
{"portability", no_argument, NULL, 'P'},
{"print-type", no_argument, NULL, 'T'},
{"sync", no_argument, NULL, SYNC_OPTION},
{"no-sync", no_argument, NULL, NO_SYNC_OPTION},
{"total", no_argument, NULL, TOTAL_OPTION},
{"type", required_argument, NULL, 't'},
{"exclude-type", required_argument, NULL, 'x'},
{"all", no_argument, nullptr, 'a'},
{"block-size", required_argument, nullptr, 'B'},
{"inodes", no_argument, nullptr, 'i'},
{"human-readable", no_argument, nullptr, 'h'},
{"si", no_argument, nullptr, 'H'},
{"local", no_argument, nullptr, 'l'},
{"output", optional_argument, nullptr, OUTPUT_OPTION},
{"portability", no_argument, nullptr, 'P'},
{"print-type", no_argument, nullptr, 'T'},
{"sync", no_argument, nullptr, SYNC_OPTION},
{"no-sync", no_argument, nullptr, NO_SYNC_OPTION},
{"total", no_argument, nullptr, TOTAL_OPTION},
{"type", required_argument, nullptr, 't'},
{"exclude-type", required_argument, nullptr, 'x'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* Stat FILE and put the results into *ST. Return 0 if successful, an
@@ -418,11 +415,10 @@ alloc_field (int f, char const *c)
ncolumns++;
columns = xnrealloc (columns, ncolumns, sizeof (struct field_data_t *));
columns[ncolumns - 1] = &field_data[f];
if (c != NULL)
if (c != nullptr)
columns[ncolumns - 1]->caption = c;
if (field_data[f].used)
assert (!"field used");
affirm (!field_data[f].used);
/* Mark field as used. */
field_data[f].used = true;
@@ -447,7 +443,7 @@ decode_output_arg (char const *arg)
/* process S. */
display_field_t field = INVALID_FIELD;
for (unsigned int i = 0; i < ARRAY_CARDINALITY (field_data); i++)
for (idx_t i = 0; i < ARRAY_CARDINALITY (field_data); i++)
{
if (STREQ (field_data[i].arg, s))
{
@@ -481,7 +477,7 @@ decode_output_arg (char const *arg)
case IPCENT_FIELD:
case TARGET_FIELD:
case FILE_FIELD:
alloc_field (field, NULL);
alloc_field (field, nullptr);
break;
case SIZE_FIELD:
@@ -493,7 +489,7 @@ decode_output_arg (char const *arg)
break;
default:
assert (!"invalid field");
affirm (!"invalid field");
}
s = comma;
}
@@ -509,48 +505,48 @@ get_field_list (void)
switch (header_mode)
{
case DEFAULT_MODE:
alloc_field (SOURCE_FIELD, NULL);
alloc_field (SOURCE_FIELD, nullptr);
if (print_type)
alloc_field (FSTYPE_FIELD, NULL);
alloc_field (SIZE_FIELD, NULL);
alloc_field (USED_FIELD, NULL);
alloc_field (AVAIL_FIELD, NULL);
alloc_field (PCENT_FIELD, NULL);
alloc_field (TARGET_FIELD, NULL);
alloc_field (FSTYPE_FIELD, nullptr);
alloc_field (SIZE_FIELD, nullptr);
alloc_field (USED_FIELD, nullptr);
alloc_field (AVAIL_FIELD, nullptr);
alloc_field (PCENT_FIELD, nullptr);
alloc_field (TARGET_FIELD, nullptr);
break;
case HUMAN_MODE:
alloc_field (SOURCE_FIELD, NULL);
alloc_field (SOURCE_FIELD, nullptr);
if (print_type)
alloc_field (FSTYPE_FIELD, NULL);
alloc_field (FSTYPE_FIELD, nullptr);
alloc_field (SIZE_FIELD, N_("Size"));
alloc_field (USED_FIELD, NULL);
alloc_field (USED_FIELD, nullptr);
alloc_field (AVAIL_FIELD, N_("Avail"));
alloc_field (PCENT_FIELD, NULL);
alloc_field (TARGET_FIELD, NULL);
alloc_field (PCENT_FIELD, nullptr);
alloc_field (TARGET_FIELD, nullptr);
break;
case INODES_MODE:
alloc_field (SOURCE_FIELD, NULL);
alloc_field (SOURCE_FIELD, nullptr);
if (print_type)
alloc_field (FSTYPE_FIELD, NULL);
alloc_field (ITOTAL_FIELD, NULL);
alloc_field (IUSED_FIELD, NULL);
alloc_field (IAVAIL_FIELD, NULL);
alloc_field (IPCENT_FIELD, NULL);
alloc_field (TARGET_FIELD, NULL);
alloc_field (FSTYPE_FIELD, nullptr);
alloc_field (ITOTAL_FIELD, nullptr);
alloc_field (IUSED_FIELD, nullptr);
alloc_field (IAVAIL_FIELD, nullptr);
alloc_field (IPCENT_FIELD, nullptr);
alloc_field (TARGET_FIELD, nullptr);
break;
case POSIX_MODE:
alloc_field (SOURCE_FIELD, NULL);
alloc_field (SOURCE_FIELD, nullptr);
if (print_type)
alloc_field (FSTYPE_FIELD, NULL);
alloc_field (SIZE_FIELD, NULL);
alloc_field (USED_FIELD, NULL);
alloc_field (AVAIL_FIELD, NULL);
alloc_field (FSTYPE_FIELD, nullptr);
alloc_field (SIZE_FIELD, nullptr);
alloc_field (USED_FIELD, nullptr);
alloc_field (AVAIL_FIELD, nullptr);
alloc_field (PCENT_FIELD, N_("Capacity"));
alloc_field (TARGET_FIELD, NULL);
alloc_field (TARGET_FIELD, nullptr);
break;
case OUTPUT_MODE:
@@ -562,7 +558,7 @@ get_field_list (void)
break;
default:
assert (!"invalid header_mode");
unreachable ();
}
}
@@ -577,7 +573,7 @@ get_header (void)
for (col = 0; col < ncolumns; col++)
{
char *cell = NULL;
char *cell = nullptr;
char const *header = _(columns[col]->caption);
if (columns[col]->field == SIZE_FIELD
@@ -621,7 +617,7 @@ get_header (void)
/* TRANSLATORS: this is the "1K-blocks" header in "df" output. */
if (asprintf (&cell, _("%s-%s"), num, header) == -1)
cell = NULL;
cell = nullptr;
}
else if (header_mode == POSIX_MODE && columns[col]->field == SIZE_FIELD)
{
@@ -630,7 +626,7 @@ get_header (void)
/* TRANSLATORS: this is the "1024-blocks" header in "df -P". */
if (asprintf (&cell, _("%s-%s"), num, header) == -1)
cell = NULL;
cell = nullptr;
}
else
cell = strdup (header);
@@ -655,7 +651,7 @@ selected_fstype (char const *fstype)
{
const struct fs_type_list *fsp;
if (fs_select_list == NULL || fstype == NULL)
if (fs_select_list == nullptr || fstype == nullptr)
return true;
for (fsp = fs_select_list; fsp; fsp = fsp->fs_next)
if (STREQ (fstype, fsp->fs_name))
@@ -671,7 +667,7 @@ excluded_fstype (char const *fstype)
{
const struct fs_type_list *fsp;
if (fs_exclude_list == NULL || fstype == NULL)
if (fs_exclude_list == nullptr || fstype == nullptr)
return false;
for (fsp = fs_exclude_list; fsp; fsp = fsp->fs_next)
if (STREQ (fstype, fsp->fs_name))
@@ -697,14 +693,14 @@ devlist_compare (void const *x, void const *y)
static struct devlist *
devlist_for_dev (dev_t dev)
{
if (devlist_table == NULL)
return NULL;
if (devlist_table == nullptr)
return nullptr;
struct devlist dev_entry;
dev_entry.dev_num = dev;
struct devlist *found = hash_lookup (devlist_table, &dev_entry);
if (found == NULL)
return NULL;
if (found == nullptr)
return nullptr;
/* Return the last devlist entry we have seen with this dev_num */
return found->seen_last;
@@ -723,22 +719,22 @@ filter_mount_list (bool devices_only)
struct mount_entry *me;
/* Temporary list to keep entries ordered. */
struct devlist *device_list = NULL;
struct devlist *device_list = nullptr;
int mount_list_size = 0;
for (me = mount_list; me; me = me->me_next)
mount_list_size++;
devlist_table = hash_initialize (mount_list_size, NULL,
devlist_hash, devlist_compare, NULL);
if (devlist_table == NULL)
devlist_table = hash_initialize (mount_list_size, nullptr,
devlist_hash, devlist_compare, nullptr);
if (devlist_table == nullptr)
xalloc_die ();
/* Sort all 'wanted' entries into the list device_list. */
for (me = mount_list; me;)
{
struct stat buf;
struct mount_entry *discard_me = NULL;
struct mount_entry *discard_me = nullptr;
/* Avoid stating remote file systems as that may hang.
On Linux we probably have me_dev populated from /proc/self/mountinfo,
@@ -763,8 +759,8 @@ filter_mount_list (bool devices_only)
bool target_nearer_root = strlen (seen_dev->me->me_mountdir)
> strlen (me->me_mountdir);
/* With bind mounts, prefer items nearer the root of the source */
bool source_below_root = seen_dev->me->me_mntroot != NULL
&& me->me_mntroot != NULL
bool source_below_root = seen_dev->me->me_mntroot != nullptr
&& me->me_mntroot != nullptr
&& (strlen (seen_dev->me->me_mntroot)
< strlen (me->me_mntroot));
if (! print_grand_total
@@ -819,7 +815,7 @@ filter_mount_list (bool devices_only)
device_list = devlist;
struct devlist *hash_entry = hash_insert (devlist_table, devlist);
if (hash_entry == NULL)
if (hash_entry == nullptr)
xalloc_die ();
/* Ensure lookups use this latest devlist. */
hash_entry->seen_last = devlist;
@@ -830,7 +826,7 @@ filter_mount_list (bool devices_only)
/* Finally rebuild the mount_list from the devlist. */
if (! devices_only) {
mount_list = NULL;
mount_list = nullptr;
while (device_list)
{
/* Add the mount entry. */
@@ -843,13 +839,13 @@ filter_mount_list (bool devices_only)
}
hash_free (devlist_table);
devlist_table = NULL;
devlist_table = nullptr;
}
}
/* Search a mount entry list for device id DEV.
Return the corresponding mount entry if found or NULL if not. */
Return the corresponding mount entry if found or nullptr if not. */
ATTRIBUTE_PURE
static struct mount_entry const *
@@ -859,7 +855,7 @@ me_for_dev (dev_t dev)
if (dl)
return dl->me;
return NULL;
return nullptr;
}
/* Return true if N is a known integer value. On many file systems,
@@ -999,15 +995,15 @@ add_to_grand_total (struct field_values_t *bv, struct field_values_t *iv)
}
/* Obtain a space listing for the device with absolute file name DEVICE.
If MOUNT_POINT is non-NULL, it is the name of the root of the
If MOUNT_POINT is non-null, it is the name of the root of the
file system on DEVICE.
If STAT_FILE is non-null, it is the name of a file within the file
system that the user originally asked for; this provides better
diagnostics, and sometimes it provides better results on networked
file systems that give different free-space results depending on
where in the file system you probe.
If FSTYPE is non-NULL, it is the type of the file system on DEVICE.
If MOUNT_POINT is non-NULL, then DEVICE may be NULL -- certain systems may
If FSTYPE is non-null, it is the type of the file system on DEVICE.
If MOUNT_POINT is non-null, then DEVICE may be null -- certain systems may
not be able to produce statistics in this case.
ME_DUMMY and ME_REMOTE are the mount entry flags.
Caller must set PROCESS_ALL to true when iterating over all entries, as
@@ -1034,7 +1030,7 @@ get_dev (char const *device, char const *mount_point, char const *file,
if (!force_fsu && mount_point && ! IS_ABSOLUTE_FILE_NAME (mount_point))
return;
/* If MOUNT_POINT is NULL, then the file system is not mounted, and this
/* If MOUNT_POINT is null, then the file system is not mounted, and this
program reports on the file system that the special file is on.
It would be better to report on the unmounted file system,
but statfs doesn't do that on most systems. */
@@ -1145,11 +1141,10 @@ get_dev (char const *device, char const *mount_point, char const *file,
v = &inode_values;
break;
case OTHER_FLD:
v = NULL;
v = nullptr;
break;
default:
v = NULL; /* Avoid warnings where assert() is not __noreturn__. */
assert (!"bad field_type");
affirm (!"bad field_type");
}
switch (columns[col]->field)
@@ -1222,7 +1217,7 @@ get_dev (char const *device, char const *mount_point, char const *file,
if (0 <= pct)
{
if (asprintf (&cell, "%.0f%%", pct) == -1)
cell = NULL;
cell = nullptr;
}
else
cell = strdup ("-");
@@ -1251,11 +1246,10 @@ get_dev (char const *device, char const *mount_point, char const *file,
break;
default:
assert (!"unhandled field");
affirm (!"unhandled field");
}
if (!cell)
assert (!"empty cell");
affirm (cell);
replace_problematic_chars (cell);
size_t cell_width = mbswidth (cell, 0);
@@ -1266,12 +1260,12 @@ get_dev (char const *device, char const *mount_point, char const *file,
}
/* Scan the mount list returning the _last_ device found for MOUNT.
NULL is returned if MOUNT not found. The result is malloced. */
nullptr is returned if MOUNT not found. The result is malloced. */
static char *
last_device_for_mount (char const *mount)
{
struct mount_entry const *me;
struct mount_entry const *le = NULL;
struct mount_entry const *le = nullptr;
for (me = mount_list; me; me = me->me_next)
{
@@ -1289,7 +1283,7 @@ last_device_for_mount (char const *mount)
return xstrdup (le->me_devname);
}
else
return NULL;
return nullptr;
}
/* If DEVICE corresponds to a mount point, show its usage
@@ -1298,7 +1292,7 @@ static bool
get_device (char const *device)
{
struct mount_entry const *me;
struct mount_entry const *best_match = NULL;
struct mount_entry const *best_match = nullptr;
bool best_match_accessible = false;
bool eclipsed_device = false;
char const *file = device;
@@ -1356,9 +1350,9 @@ get_device (char const *device)
if (best_match)
{
get_dev (best_match->me_devname, best_match->me_mountdir, file, NULL,
get_dev (best_match->me_devname, best_match->me_mountdir, file, nullptr,
best_match->me_type, best_match->me_dummy,
best_match->me_remote, NULL, false);
best_match->me_remote, nullptr, false);
return true;
}
else if (eclipsed_device)
@@ -1380,7 +1374,7 @@ get_point (char const *point, const struct stat *statp)
{
struct stat device_stats;
struct mount_entry *me;
struct mount_entry const *best_match = NULL;
struct mount_entry const *best_match = nullptr;
/* Calculate the real absolute file name for POINT, and use that to find
the mount point. This avoids statting unavailable mount points,
@@ -1412,7 +1406,7 @@ get_point (char const *point, const struct stat *statp)
if (best_match
&& (stat (best_match->me_mountdir, &device_stats) != 0
|| device_stats.st_dev != statp->st_dev))
best_match = NULL;
best_match = nullptr;
if (! best_match)
for (me = mount_list; me; me = me->me_next)
@@ -1453,7 +1447,7 @@ get_point (char const *point, const struct stat *statp)
if (best_match)
get_dev (best_match->me_devname, best_match->me_mountdir, point, point,
best_match->me_type, best_match->me_dummy, best_match->me_remote,
NULL, false);
nullptr, false);
else
{
/* We couldn't find the mount entry corresponding to POINT. Go ahead and
@@ -1464,7 +1458,8 @@ get_point (char const *point, const struct stat *statp)
char *mp = find_mount_point (point, statp);
if (mp)
{
get_dev (NULL, mp, point, NULL, NULL, false, false, NULL, false);
get_dev (nullptr, mp, point, nullptr, nullptr,
false, false, nullptr, false);
free (mp);
}
}
@@ -1494,8 +1489,8 @@ get_all_entries (void)
filter_mount_list (show_all_fs);
for (me = mount_list; me; me = me->me_next)
get_dev (me->me_devname, me->me_mountdir, NULL, NULL, me->me_type,
me->me_dummy, me->me_remote, NULL, true);
get_dev (me->me_devname, me->me_mountdir, nullptr, nullptr, me->me_type,
me->me_dummy, me->me_remote, nullptr, true);
}
/* Add FSTYPE to the list of file system types to display. */
@@ -1589,7 +1584,7 @@ field names are: 'source', 'fstype', 'itotal', 'iused', 'iavail', 'ipcent',\n\
int
main (int argc, char **argv)
{
struct stat *stats = NULL;
struct stat *stats = nullptr;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -1599,8 +1594,8 @@ main (int argc, char **argv)
atexit (close_stdout);
fs_select_list = NULL;
fs_exclude_list = NULL;
fs_select_list = nullptr;
fs_exclude_list = nullptr;
show_all_fs = false;
show_listed_fs = false;
human_output_opts = -1;
@@ -1774,8 +1769,6 @@ main (int argc, char **argv)
return EXIT_FAILURE;
}
assume (0 < optind);
if (optind < argc)
{
/* stat each of the given entries to make sure any corresponding
@@ -1789,19 +1782,19 @@ main (int argc, char **argv)
{
error (0, err, "%s", quotef (argv[i]));
exit_status = EXIT_FAILURE;
argv[i] = NULL;
argv[i] = nullptr;
}
}
}
mount_list =
read_file_system_list ((fs_select_list != NULL
|| fs_exclude_list != NULL
read_file_system_list ((fs_select_list != nullptr
|| fs_exclude_list != nullptr
|| print_type
|| field_data[FSTYPE_FIELD].used
|| show_local_fs));
if (mount_list == NULL)
if (mount_list == nullptr)
{
/* Couldn't read the table of mounted file systems.
Fail if df was invoked with no file name arguments,
@@ -1811,8 +1804,8 @@ main (int argc, char **argv)
if ( ! (optind < argc)
|| (show_all_fs
|| show_local_fs
|| fs_select_list != NULL
|| fs_exclude_list != NULL))
|| fs_select_list != nullptr
|| fs_exclude_list != nullptr))
{
status = EXIT_FAILURE;
}
@@ -1844,7 +1837,7 @@ main (int argc, char **argv)
if (print_grand_total)
get_dev ("total",
(field_data[SOURCE_FIELD].used ? "-" : "total"),
NULL, NULL, NULL, false, false, &grand_fsu, false);
nullptr, nullptr, nullptr, false, false, &grand_fsu, false);
print_table ();
}
@@ -1853,7 +1846,7 @@ main (int argc, char **argv)
/* Print the "no FS processed" diagnostic only if there was no preceding
diagnostic, e.g., if all have been excluded. */
if (exit_status == EXIT_SUCCESS)
die (EXIT_FAILURE, 0, _("no file systems processed"));
error (EXIT_FAILURE, 0, _("no file systems processed"));
}
main_exit (exit_status);

View File

@@ -1,30 +0,0 @@
/* Report an error and exit.
Copyright 2016-2023 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, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#ifndef DIE_H
# define DIE_H
# include <error.h>
# include <verify.h>
/* Like 'error (STATUS, ...)', except STATUS must be a nonzero constant.
This may pacify the compiler or help it generate better code. */
# define die(status, ...) \
verify_expr (status, (error (status, __VA_ARGS__), assume (false)))
#endif /* DIE_H */

View File

@@ -52,8 +52,6 @@
#if HASH_ALGO_CKSUM
# include "sm3.h"
#endif
#include "die.h"
#include "error.h"
#include "fadvise.h"
#include "stdio--.h"
#include "xbinary-io.h"
@@ -137,11 +135,11 @@
proper_name ("David MacKenzie")
#elif HASH_ALGO_CKSUM
# define AUTHORS \
proper_name ("Padraig Brady"), \
proper_name_lite ("Padraig Brady", "P\303\241draig Brady"), \
proper_name ("Q. Frank Xia")
#elif HASH_ALGO_BLAKE2
# define AUTHORS \
proper_name ("Padraig Brady"), \
proper_name_lite ("Padraig Brady", "P\303\241draig Brady"), \
proper_name ("Samuel Neves")
#else
# define AUTHORS \
@@ -300,7 +298,7 @@ enum Algorithm
static char const *const algorithm_args[] =
{
"bsd", "sysv", "crc", "md5", "sha1", "sha224",
"sha256", "sha384", "sha512", "blake2b", "sm3", NULL
"sha256", "sha384", "sha512", "blake2b", "sm3", nullptr
};
static enum Algorithm const algorithm_types[] =
{
@@ -312,7 +310,7 @@ ARGMATCH_VERIFY (algorithm_args, algorithm_types);
static char const *const algorithm_tags[] =
{
"BSD", "SYSV", "CRC", "MD5", "SHA1", "SHA224",
"SHA256", "SHA384", "SHA512", "BLAKE2b", "SM3", NULL
"SHA256", "SHA384", "SHA512", "BLAKE2b", "SM3", nullptr
};
static int const algorithm_bits[] =
{
@@ -369,42 +367,42 @@ enum
UNTAG_OPTION,
DEBUG_PROGRAM_OPTION,
RAW_OPTION,
BASE64_OPTION,
};
static struct option const long_options[] =
{
#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
{ "length", required_argument, NULL, 'l'},
{ "length", required_argument, nullptr, 'l'},
#endif
#if !HASH_ALGO_SUM
{ "check", no_argument, NULL, 'c' },
{ "ignore-missing", no_argument, NULL, IGNORE_MISSING_OPTION},
{ "quiet", no_argument, NULL, QUIET_OPTION },
{ "status", no_argument, NULL, STATUS_OPTION },
{ "warn", no_argument, NULL, 'w' },
{ "strict", no_argument, NULL, STRICT_OPTION },
{ "tag", no_argument, NULL, TAG_OPTION },
{ "zero", no_argument, NULL, 'z' },
{ "check", no_argument, nullptr, 'c' },
{ "ignore-missing", no_argument, nullptr, IGNORE_MISSING_OPTION},
{ "quiet", no_argument, nullptr, QUIET_OPTION },
{ "status", no_argument, nullptr, STATUS_OPTION },
{ "warn", no_argument, nullptr, 'w' },
{ "strict", no_argument, nullptr, STRICT_OPTION },
{ "tag", no_argument, nullptr, TAG_OPTION },
{ "zero", no_argument, nullptr, 'z' },
# if HASH_ALGO_CKSUM
{ "algorithm", required_argument, NULL, 'a'},
{ "base64", no_argument, NULL, 'b' },
{ "debug", no_argument, NULL, DEBUG_PROGRAM_OPTION},
{ "raw", no_argument, NULL, RAW_OPTION},
{ "untagged", no_argument, NULL, UNTAG_OPTION },
# else
{ "binary", no_argument, NULL, 'b' },
{ "text", no_argument, NULL, 't' },
{ "algorithm", required_argument, nullptr, 'a'},
{ "base64", no_argument, nullptr, BASE64_OPTION },
{ "debug", no_argument, nullptr, DEBUG_PROGRAM_OPTION},
{ "raw", no_argument, nullptr, RAW_OPTION},
{ "untagged", no_argument, nullptr, UNTAG_OPTION },
# endif
{ "binary", no_argument, nullptr, 'b' },
{ "text", no_argument, nullptr, 't' },
#else
{"sysv", no_argument, NULL, 's'},
{"sysv", no_argument, nullptr, 's'},
#endif
{ GETOPT_HELP_OPTION_DECL },
{ GETOPT_VERSION_OPTION_DECL },
{ NULL, 0, NULL, 0 }
{ nullptr, 0, nullptr, 0 }
};
void
@@ -447,7 +445,7 @@ Print or check %s (%d-bit) checksums.\n\
\n\
"), stdout);
fputs (_("\
-b, --base64 emit base64-encoded digests, not hexadecimal\
--base64 emit base64-encoded digests, not hexadecimal\
\n\
"), stdout);
#endif
@@ -562,6 +560,18 @@ or equivalent standalone program.\
exit (status);
}
/* Given a string S, return TRUE if it contains problematic characters
that need escaping. Note we escape '\' itself to provide some forward
compat to introduce escaping of other characters. */
ATTRIBUTE_PURE
static bool
problematic_chars (char const *s)
{
size_t length = strcspn (s, "\\\n\r");
return s[length] != '\0';
}
#define ISWHITE(c) ((c) == ' ' || (c) == '\t')
/* Given a file name, S of length S_LEN, that is not NUL-terminated,
@@ -571,7 +581,7 @@ or equivalent standalone program.\
and each "\\\\" with a single backslash, NUL-terminate it and return S.
If S is not a valid escaped file name, i.e., if it ends with an odd number
of backslashes or if it contains a backslash followed by anything other
than "n" or another backslash, return NULL. */
than "n" or another backslash, return nullptr. */
static char *
filename_unescape (char *s, size_t s_len)
@@ -586,7 +596,7 @@ filename_unescape (char *s, size_t s_len)
if (i == s_len - 1)
{
/* File name ends with an unescaped backslash: invalid. */
return NULL;
return nullptr;
}
++i;
switch (s[i])
@@ -602,13 +612,13 @@ filename_unescape (char *s, size_t s_len)
break;
default:
/* Only '\', 'n' or 'r' may follow a backslash. */
return NULL;
return nullptr;
}
break;
case '\0':
/* The file name may not contain a NUL. */
return NULL;
return nullptr;
default:
*dst++ = s[i];
@@ -648,7 +658,7 @@ valid_digits (unsigned char const *s, size_t len)
#endif
if (len == digest_hex_bytes)
{
for (unsigned int i = 0; i < digest_hex_bytes; i++)
for (idx_t i = 0; i < digest_hex_bytes; i++)
{
if (!isxdigit (*s))
return false;
@@ -684,7 +694,7 @@ bsd_split_3 (char *s, size_t s_len,
*file_name = s;
if (escaped_filename && filename_unescape (s, i) == NULL)
if (escaped_filename && filename_unescape (s, i) == nullptr)
return false;
s[i++] = '\0';
@@ -808,7 +818,7 @@ split_3 (char *s, size_t s_len,
{
uintmax_t length;
char *siend;
if (! (xstrtoumax (s + i, &siend, 0, &length, NULL) == LONGINT_OK
if (! (xstrtoumax (s + i, &siend, 0, &length, nullptr) == LONGINT_OK
&& 0 < length && length <= digest_length
&& length % 8 == 0))
return false;
@@ -862,6 +872,10 @@ split_3 (char *s, size_t s_len,
while (s[i] && !ISWHITE (s[i]))
i++;
/* The digest must be followed by at least one whitespace character. */
if (i == s_len)
return false;
*d_len = &s[i] - (char *) *digest;
s[i++] = '\0';
@@ -892,7 +906,7 @@ split_3 (char *s, size_t s_len,
*file_name = &s[i];
if (escaped_filename)
return filename_unescape (&s[i], s_len - i) != NULL;
return filename_unescape (&s[i], s_len - i) != nullptr;
return true;
}
@@ -971,7 +985,7 @@ digest_file (char const *filename, int *binary, unsigned char *bin_result,
else
{
fp = fopen (filename, (O_BINARY && *binary ? "rb" : "r"));
if (fp == NULL)
if (fp == nullptr)
{
if (ignore_missing && errno == ENOENT)
{
@@ -1027,12 +1041,9 @@ output_file (char const *file, int binary_file, void const *digest,
unsigned char const *bin_buffer = digest;
/* Output a leading backslash if the file name contains problematic chars.
Note we escape '\' itself to provide some forward compat to introduce
escaping of other characters. */
bool needs_escape = delim == '\n' && (strchr (file, '\\')
|| strchr (file, '\n')
|| strchr (file, '\r'));
/* Output a leading backslash if the file name contains problematic chars. */
bool needs_escape = delim == '\n' && problematic_chars (file);
if (needs_escape)
putchar ('\\');
@@ -1072,14 +1083,7 @@ output_file (char const *file, int binary_file, void const *digest,
if (!tagged)
{
putchar (' ');
# if HASH_ALGO_CKSUM
/* Simplify output as always in binary mode. */
putchar (' ');
# else
putchar (binary_file ? '*' : ' ');
# endif
print_filename (file, needs_escape);
}
@@ -1151,7 +1155,7 @@ digest_check (char const *checkfile_name)
else
{
checkfile_stream = fopen (checkfile_name, "r");
if (checkfile_stream == NULL)
if (checkfile_stream == nullptr)
{
error (0, errno, "%s", quotef (checkfile_name));
return false;
@@ -1159,7 +1163,7 @@ digest_check (char const *checkfile_name)
}
line_number = 0;
line = NULL;
line = nullptr;
line_chars_allocated = 0;
do
{
@@ -1170,8 +1174,8 @@ digest_check (char const *checkfile_name)
++line_number;
if (line_number == 0)
die (EXIT_FAILURE, 0, _("%s: too many checksum lines"),
quotef (checkfile_name));
error (EXIT_FAILURE, 0, _("%s: too many checksum lines"),
quotef (checkfile_name));
line_length = getline (&line, &line_chars_allocated, checkfile_stream);
if (line_length <= 0)
@@ -1211,9 +1215,7 @@ digest_check (char const *checkfile_name)
{
bool ok;
bool missing;
/* Only escape in the edge case producing multiple lines,
to ease automatic processing of status output. */
bool needs_escape = ! status_only && strchr (filename, '\n');
bool needs_escape = ! status_only && problematic_chars (filename);
properly_formatted_lines = true;
@@ -1254,14 +1256,14 @@ digest_check (char const *checkfile_name)
if (!status_only)
{
if ( ! matched_checksums || ! quiet)
if (! match || ! quiet)
{
if (needs_escape)
putchar ('\\');
print_filename (filename, needs_escape);
}
if ( ! matched_checksums)
if (! match)
printf (": %s\n", _("FAILED"));
else if (!quiet)
printf (": %s\n", _("OK"));
@@ -1342,11 +1344,10 @@ main (int argc, char **argv)
bool do_check = false;
int opt;
bool ok = true;
int binary = -1;
#if HASH_ALGO_CKSUM
int binary = 1;
bool prefix_tag = true;
#else
int binary = -1;
bool prefix_tag = false;
#endif
@@ -1361,7 +1362,7 @@ main (int argc, char **argv)
/* Line buffer stdout to ensure lines are written atomically and immediately
so that processes running in parallel do not intersperse their output. */
setvbuf (stdout, NULL, _IOLBF, 0);
setvbuf (stdout, nullptr, _IOLBF, 0);
#if HASH_ALGO_SUM
char const *short_opts = "rs";
@@ -1375,7 +1376,8 @@ main (int argc, char **argv)
char const *short_opts = "bctwz";
#endif
while ((opt = getopt_long (argc, argv, short_opts, long_options, NULL)) != -1)
while ((opt = getopt_long (argc, argv, short_opts, long_options, nullptr))
!= -1)
switch (opt)
{
#if HASH_ALGO_CKSUM
@@ -1397,7 +1399,7 @@ main (int argc, char **argv)
if (digest_length % 8 != 0)
{
error (0, 0, _("invalid length: %s"), quote (digest_length_str));
die (EXIT_FAILURE, 0, _("length is not a multiple of 8"));
error (EXIT_FAILURE, 0, _("length is not a multiple of 8"));
}
break;
#endif
@@ -1410,14 +1412,12 @@ main (int argc, char **argv)
warn = false;
quiet = false;
break;
# if !HASH_ALGO_CKSUM
case 'b':
binary = 1;
break;
case 't':
binary = 0;
break;
# endif
case 'w':
status_only = false;
warn = true;
@@ -1435,7 +1435,7 @@ main (int argc, char **argv)
strict = true;
break;
# if HASH_ALGO_CKSUM
case 'b':
case BASE64_OPTION:
base64_digest = true;
break;
case RAW_OPTION:
@@ -1472,16 +1472,16 @@ main (int argc, char **argv)
#if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM
# if HASH_ALGO_CKSUM
if (digest_length && cksum_algorithm != blake2b)
die (EXIT_FAILURE, 0,
_("--length is only supported with --algorithm=blake2b"));
error (EXIT_FAILURE, 0,
_("--length is only supported with --algorithm=blake2b"));
# endif
if (digest_length > BLAKE2B_MAX_LEN * 8)
{
error (0, 0, _("invalid length: %s"), quote (digest_length_str));
die (EXIT_FAILURE, 0,
_("maximum digest length for %s is %d bits"),
quote (DIGEST_TYPE_STRING),
BLAKE2B_MAX_LEN * 8);
error (EXIT_FAILURE, 0,
_("maximum digest length for %s is %d bits"),
quote (DIGEST_TYPE_STRING),
BLAKE2B_MAX_LEN * 8);
}
if (digest_length == 0)
{
@@ -1503,8 +1503,8 @@ main (int argc, char **argv)
case sysv:
case crc:
if (do_check && algorithm_specified)
die (EXIT_FAILURE, 0,
_("--check is not supported with --algorithm={bsd,sysv,crc}"));
error (EXIT_FAILURE, 0,
_("--check is not supported with --algorithm={bsd,sysv,crc}"));
break;
default:
break;
@@ -1524,7 +1524,11 @@ main (int argc, char **argv)
However that's invasive enough that it was agreed to
not support this mode with --tag, as --text use cases
are adequately supported by the default output format. */
#if !HASH_ALGO_CKSUM
error (0, 0, _("--tag does not support --text mode"));
#else
error (0, 0, _("--text mode is only supported with --untagged"));
#endif
usage (EXIT_FAILURE);
}
@@ -1543,14 +1547,12 @@ main (int argc, char **argv)
}
#endif
#if !HASH_ALGO_CKSUM
if (0 <= binary && do_check)
{
error (0, 0, _("the --binary and --text options are meaningless when "
"verifying checksums"));
usage (EXIT_FAILURE);
}
#endif
if (ignore_missing && !do_check)
{
@@ -1595,10 +1597,8 @@ main (int argc, char **argv)
if (optind == argc)
*operand_lim++ = bad_cast ("-");
else if (1 < argc - optind && raw_digest)
{
die (EXIT_FAILURE, 0,
_("the --raw option is not supported with multiple files"));
}
error (EXIT_FAILURE, 0,
_("the --raw option is not supported with multiple files"));
for (char **operandp = argv + optind; operandp < operand_lim; operandp++)
{
@@ -1622,7 +1622,7 @@ main (int argc, char **argv)
}
if (have_read_stdin && fclose (stdin) == EOF)
die (EXIT_FAILURE, errno, _("standard input"));
error (EXIT_FAILURE, errno, _("standard input"));
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -24,8 +24,6 @@
#include "system.h"
#include "dircolors.h"
#include "c-strcase.h"
#include "die.h"
#include "error.h"
#include "obstack.h"
#include "quote.h"
#include "stdio--.h"
@@ -58,14 +56,15 @@ static char const *const slack_codes[] =
"CHR", "CHAR", "DOOR", "EXEC", "LEFT", "LEFTCODE", "RIGHT", "RIGHTCODE",
"END", "ENDCODE", "SUID", "SETUID", "SGID", "SETGID", "STICKY",
"OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE", "OWT", "CAPABILITY",
"MULTIHARDLINK", "CLRTOEOL", NULL
"MULTIHARDLINK", "CLRTOEOL", nullptr
};
static char const *const ls_codes[] =
{
"no", "no", "fi", "rs", "di", "ln", "ln", "ln", "or", "mi", "pi", "pi",
"so", "bd", "bd", "cd", "cd", "do", "ex", "lc", "lc", "rc", "rc", "ec", "ec",
"su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", "ca", "mh", "cl", NULL
"su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", "ca", "mh", "cl",
nullptr
};
static_assert (ARRAY_CARDINALITY (slack_codes) == ARRAY_CARDINALITY (ls_codes));
@@ -81,15 +80,15 @@ enum
static struct option const long_options[] =
{
{"bourne-shell", no_argument, NULL, 'b'},
{"sh", no_argument, NULL, 'b'},
{"csh", no_argument, NULL, 'c'},
{"c-shell", no_argument, NULL, 'c'},
{"print-database", no_argument, NULL, 'p'},
{"print-ls-colors", no_argument, NULL, PRINT_LS_COLORS_OPTION},
{"bourne-shell", no_argument, nullptr, 'b'},
{"sh", no_argument, nullptr, 'b'},
{"csh", no_argument, nullptr, 'c'},
{"c-shell", no_argument, nullptr, 'c'},
{"print-database", no_argument, nullptr, 'p'},
{"print-ls-colors", no_argument, nullptr, PRINT_LS_COLORS_OPTION},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -132,7 +131,7 @@ guess_shell_syntax (void)
char *shell;
shell = getenv ("SHELL");
if (shell == NULL || *shell == '\0')
if (shell == nullptr || *shell == '\0')
return SHELL_SYNTAX_UNKNOWN;
shell = last_component (shell);
@@ -150,8 +149,8 @@ parse_line (char const *line, char **keyword, char **arg)
char const *keyword_start;
char const *arg_start;
*keyword = NULL;
*arg = NULL;
*keyword = nullptr;
*arg = nullptr;
for (p = line; isspace (to_uchar (*p)); ++p)
continue;
@@ -265,9 +264,9 @@ append_entry (char prefix, char const *item, char const *arg)
static bool
dc_parse_stream (FILE *fp, char const *filename)
{
size_t line_number = 0;
idx_t line_number = 0;
char const *next_G_line = G_line;
char *input_line = NULL;
char *input_line = nullptr;
size_t input_line_size = 0;
char const *line;
char const *term;
@@ -279,12 +278,12 @@ dc_parse_stream (FILE *fp, char const *filename)
/* Get terminal type */
term = getenv ("TERM");
if (term == NULL || *term == '\0')
if (term == nullptr || *term == '\0')
term = "none";
/* Also match $COLORTERM. */
colorterm = getenv ("COLORTERM");
if (colorterm == NULL)
if (colorterm == nullptr)
colorterm = ""; /* Doesn't match default "?*" */
while (true)
@@ -298,6 +297,11 @@ dc_parse_stream (FILE *fp, char const *filename)
{
if (getline (&input_line, &input_line_size, fp) <= 0)
{
if (ferror (fp))
{
error (0, errno, _("%s: read error"), quotef (filename));
ok = false;
}
free (input_line);
break;
}
@@ -313,13 +317,13 @@ dc_parse_stream (FILE *fp, char const *filename)
parse_line (line, &keywd, &arg);
if (keywd == NULL)
if (keywd == nullptr)
continue;
if (arg == NULL)
if (arg == nullptr)
{
error (0, 0, _("%s:%lu: invalid line; missing second token"),
quotef (filename), (unsigned long int) line_number);
error (0, 0, _("%s:%td: invalid line; missing second token"),
quotef (filename), line_number);
ok = false;
free (keywd);
continue;
@@ -357,11 +361,11 @@ dc_parse_stream (FILE *fp, char const *filename)
{
int i;
for (i = 0; slack_codes[i] != NULL; ++i)
for (i = 0; slack_codes[i] != nullptr; ++i)
if (c_strcasecmp (keywd, slack_codes[i]) == 0)
break;
if (slack_codes[i] != NULL)
if (slack_codes[i] != nullptr)
append_entry (0, ls_codes[i], arg);
else
unrecognized = true;
@@ -373,9 +377,9 @@ dc_parse_stream (FILE *fp, char const *filename)
if (unrecognized && (state == ST_TERMSURE || state == ST_TERMYES))
{
error (0, 0, _("%s:%lu: unrecognized keyword %s"),
error (0, 0, _("%s:%td: unrecognized keyword %s"),
(filename ? quotef (filename) : _("<internal>")),
(unsigned long int) line_number, keywd);
line_number, keywd);
ok = false;
}
@@ -391,7 +395,7 @@ dc_parse_file (char const *filename)
{
bool ok;
if (! STREQ (filename, "-") && freopen (filename, "r", stdin) == NULL)
if (! STREQ (filename, "-") && freopen (filename, "r", stdin) == nullptr)
{
error (0, errno, "%s", quotef (filename));
return false;
@@ -424,7 +428,7 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, "bcp", long_options, NULL)) != -1)
while ((optc = getopt_long (argc, argv, "bcp", long_options, nullptr)) != -1)
switch (optc)
{
case 'b': /* Bourne shell syntax. */
@@ -499,15 +503,14 @@ main (int argc, char **argv)
{
syntax = guess_shell_syntax ();
if (syntax == SHELL_SYNTAX_UNKNOWN)
{
die (EXIT_FAILURE, 0,
_("no SHELL environment variable, and no shell type option given"));
}
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 (nullptr, nullptr);
else
ok = dc_parse_file (argv[0]);

View File

@@ -228,20 +228,23 @@ EXEC 01;32
*~ 00;90
*# 00;90
.bak 00;90
.crdownload 00;90
.dpkg-dist 00;90
.dpkg-new 00;90
.dpkg-old 00;90
.dpkg-tmp 00;90
.old 00;90
.orig 00;90
.part 00;90
.rej 00;90
.swp 00;90
.tmp 00;90
.dpkg-dist 00;90
.dpkg-old 00;90
.ucf-dist 00;90
.ucf-new 00;90
.ucf-old 00;90
.rpmnew 00;90
.rpmorig 00;90
.rpmsave 00;90
.swp 00;90
.tmp 00;90
.ucf-dist 00;90
.ucf-new 00;90
.ucf-old 00;90
#
# Subsequent TERM or COLORTERM entries, can be used to add / override

View File

@@ -23,7 +23,6 @@
#include <sys/types.h>
#include "system.h"
#include "error.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "dirname"
@@ -34,10 +33,10 @@
static struct option const longopts[] =
{
{"zero", no_argument, NULL, 'z'},
{"zero", no_argument, nullptr, 'z'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -92,7 +91,7 @@ main (int argc, char **argv)
while (true)
{
int c = getopt_long (argc, argv, "z", longopts, NULL);
int c = getopt_long (argc, argv, "z", longopts, nullptr);
if (c == -1)
break;

119
src/du.c
View File

@@ -18,7 +18,7 @@
* Doesn't simply ignore the names of regular files given as arguments
when -a is given.
By tege@sics.se, Torbjorn Granlund,
By tege@sics.se, Torbjörn Granlund,
and djm@ai.mit.edu, David MacKenzie.
Variable blocks added by lm@sgi.com and eggert@twinsun.com.
Rewritten to use nftw, then to use fts by Jim Meyering. */
@@ -26,13 +26,11 @@
#include <config.h>
#include <getopt.h>
#include <sys/types.h>
#include <assert.h>
#include "system.h"
#include "argmatch.h"
#include "argv-iter.h"
#include "assure.h"
#include "di-set.h"
#include "die.h"
#include "error.h"
#include "exclude.h"
#include "fprintftime.h"
#include "human.h"
@@ -51,7 +49,7 @@ extern bool fts_debug;
#define PROGRAM_NAME "du"
#define AUTHORS \
proper_name ("Torbjorn Granlund"), \
proper_name_lite ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
proper_name ("David MacKenzie"), \
proper_name ("Paul Eggert"), \
proper_name ("Jim Meyering")
@@ -152,7 +150,7 @@ static bool opt_separate_dirs = false;
/* Show the total for each directory (and file if --all) that is at
most MAX_DEPTH levels down from the root of the hierarchy. The root
is at level 0, so 'du --max-depth=0' is equivalent to 'du -s'. */
static size_t max_depth = SIZE_MAX;
static idx_t max_depth = IDX_MAX;
/* Only output entries with at least this SIZE if positive,
or at most if negative. See --threshold option. */
@@ -179,10 +177,10 @@ enum time_type
static enum time_type time_type = time_mtime;
/* User specified date / time style */
static char const *time_style = NULL;
static char const *time_style = nullptr;
/* Format used to display date / time. Controlled by --time-style */
static char const *time_format = NULL;
static char const *time_format = nullptr;
/* The local time zone rules, as per the TZ environment variable. */
static timezone_t localtz;
@@ -216,38 +214,38 @@ enum
static struct option const long_options[] =
{
{"all", no_argument, NULL, 'a'},
{"apparent-size", no_argument, NULL, APPARENT_SIZE_OPTION},
{"block-size", required_argument, NULL, 'B'},
{"bytes", no_argument, NULL, 'b'},
{"count-links", no_argument, NULL, 'l'},
/* {"-debug", no_argument, NULL, FTS_DEBUG}, */
{"dereference", no_argument, NULL, 'L'},
{"dereference-args", no_argument, NULL, 'D'},
{"exclude", required_argument, NULL, EXCLUDE_OPTION},
{"exclude-from", required_argument, NULL, 'X'},
{"files0-from", required_argument, NULL, FILES0_FROM_OPTION},
{"human-readable", no_argument, NULL, 'h'},
{"inodes", no_argument, NULL, INODES_OPTION},
{"si", no_argument, NULL, HUMAN_SI_OPTION},
{"max-depth", required_argument, NULL, 'd'},
{"null", no_argument, NULL, '0'},
{"no-dereference", no_argument, NULL, 'P'},
{"one-file-system", no_argument, NULL, 'x'},
{"separate-dirs", no_argument, NULL, 'S'},
{"summarize", no_argument, NULL, 's'},
{"total", no_argument, NULL, 'c'},
{"threshold", required_argument, NULL, 't'},
{"time", optional_argument, NULL, TIME_OPTION},
{"time-style", required_argument, NULL, TIME_STYLE_OPTION},
{"all", no_argument, nullptr, 'a'},
{"apparent-size", no_argument, nullptr, APPARENT_SIZE_OPTION},
{"block-size", required_argument, nullptr, 'B'},
{"bytes", no_argument, nullptr, 'b'},
{"count-links", no_argument, nullptr, 'l'},
/* {"-debug", no_argument, nullptr, FTS_DEBUG}, */
{"dereference", no_argument, nullptr, 'L'},
{"dereference-args", no_argument, nullptr, 'D'},
{"exclude", required_argument, nullptr, EXCLUDE_OPTION},
{"exclude-from", required_argument, nullptr, 'X'},
{"files0-from", required_argument, nullptr, FILES0_FROM_OPTION},
{"human-readable", no_argument, nullptr, 'h'},
{"inodes", no_argument, nullptr, INODES_OPTION},
{"si", no_argument, nullptr, HUMAN_SI_OPTION},
{"max-depth", required_argument, nullptr, 'd'},
{"null", no_argument, nullptr, '0'},
{"no-dereference", no_argument, nullptr, 'P'},
{"one-file-system", no_argument, nullptr, 'x'},
{"separate-dirs", no_argument, nullptr, 'S'},
{"summarize", no_argument, nullptr, 's'},
{"total", no_argument, nullptr, 'c'},
{"threshold", required_argument, nullptr, 't'},
{"time", optional_argument, nullptr, TIME_OPTION},
{"time-style", required_argument, nullptr, TIME_STYLE_OPTION},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
static char const *const time_args[] =
{
"atime", "access", "use", "ctime", "status", NULL
"atime", "access", "use", "ctime", "status", nullptr
};
static enum time_type const time_types[] =
{
@@ -267,7 +265,7 @@ enum time_style
static char const *const time_style_args[] =
{
"full-iso", "long-iso", "iso", NULL
"full-iso", "long-iso", "iso", nullptr
};
static enum time_style const time_style_types[] =
{
@@ -523,8 +521,8 @@ process_file (FTS *fts, FTSENT *ent)
if (info == FTS_NSOK)
{
fts_set (fts, ent, FTS_AGAIN);
FTSENT const *e = fts_read (fts);
assert (e == ent);
MAYBE_UNUSED FTSENT const *e = fts_read (fts);
affirm (e == ent);
info = ent->fts_info;
}
@@ -556,8 +554,8 @@ process_file (FTS *fts, FTSENT *ent)
if (info == FTS_D)
{
fts_set (fts, ent, FTS_SKIP);
FTSENT const *e = fts_read (fts);
assert (e == ent);
MAYBE_UNUSED FTSENT const *e = fts_read (fts);
affirm (e == ent);
}
return true;
@@ -635,7 +633,7 @@ process_file (FTS *fts, FTSENT *ent)
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);
affirm (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);
@@ -671,7 +669,7 @@ process_file (FTS *fts, FTSENT *ent)
}
/* Recursively print the sizes of the directories (and, if selected, files)
named in FILES, the last entry of which is NULL.
named in FILES, the last entry of which is null.
BIT_FLAGS controls how fts works.
Return true if successful. */
@@ -682,14 +680,14 @@ du_files (char **files, int bit_flags)
if (*files)
{
FTS *fts = xfts_open (files, bit_flags, NULL);
FTS *fts = xfts_open (files, bit_flags, nullptr);
while (true)
{
FTSENT *ent;
ent = fts_read (fts);
if (ent == NULL)
if (ent == nullptr)
{
if (errno != 0)
{
@@ -725,7 +723,7 @@ main (int argc, char **argv)
char *cwd_only[2];
bool max_depth_specified = false;
bool ok = true;
char *files_from = NULL;
char *files_from = nullptr;
/* Bit flags that control how fts works. */
int bit_flags = FTS_NOSTAT;
@@ -738,7 +736,7 @@ main (int argc, char **argv)
bool opt_summarize_only = false;
cwd_only[0] = bad_cast (".");
cwd_only[1] = NULL;
cwd_only[1] = nullptr;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -808,9 +806,9 @@ main (int argc, char **argv)
case 'd': /* --max-depth=N */
{
uintmax_t tmp;
if (xstrtoumax (optarg, NULL, 0, &tmp, "") == LONGINT_OK
&& tmp <= SIZE_MAX)
intmax_t tmp;
if (xstrtoimax (optarg, nullptr, 0, &tmp, "") == LONGINT_OK
&& tmp <= IDX_MAX)
{
max_depth_specified = true;
max_depth = tmp;
@@ -840,13 +838,14 @@ main (int argc, char **argv)
case 't':
{
enum strtol_error e;
e = xstrtoimax (optarg, NULL, 0, &opt_threshold, "kKmMGTPEZYRQ0");
e = xstrtoimax (optarg, nullptr, 0, &opt_threshold,
"kKmMGTPEZYRQ0");
if (e != LONGINT_OK)
xstrtol_fatal (e, oi, c, long_options, optarg);
if (opt_threshold == 0 && *optarg == '-')
{
/* Do not allow -0, as this wouldn't make sense anyway. */
die (EXIT_FAILURE, 0, _("invalid --threshold argument '-0'"));
error (EXIT_FAILURE, 0, _("invalid --threshold argument '-0'"));
}
}
break;
@@ -941,8 +940,8 @@ main (int argc, char **argv)
if (opt_summarize_only && max_depth_specified && max_depth != 0)
{
unsigned long int d = max_depth;
error (0, 0, _("warning: summarizing conflicts with --max-depth=%lu"), d);
error (0, 0, _("warning: summarizing conflicts with --max-depth=%td"),
max_depth);
usage (EXIT_FAILURE);
}
@@ -1023,8 +1022,8 @@ main (int argc, char **argv)
}
if (! (STREQ (files_from, "-") || freopen (files_from, "r", stdin)))
die (EXIT_FAILURE, errno, _("cannot open %s for reading"),
quoteaf (files_from));
error (EXIT_FAILURE, errno, _("cannot open %s for reading"),
quoteaf (files_from));
ai = argv_iter_init_stream (stdin);
@@ -1057,7 +1056,7 @@ main (int argc, char **argv)
bit_flags |= FTS_TIGHT_CYCLE_CHECK;
bit_flags |= symlink_deref_bits;
static char *temp_argv[] = { NULL, NULL };
static char *temp_argv[] = { nullptr, nullptr };
while (true)
{
@@ -1078,7 +1077,7 @@ main (int argc, char **argv)
case AI_ERR_MEM:
xalloc_die ();
default:
assert (!"unexpected error code from argv_iter");
affirm (!"unexpected error code from argv_iter");
}
}
if (files_from && STREQ (files_from, "-") && STREQ (file_name, "-"))
@@ -1101,15 +1100,15 @@ main (int argc, char **argv)
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)
if (files_from == nullptr)
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", quotef (files_from),
idx_t file_number = argv_iter_n_args (ai);
error (0, 0, "%s:%td: %s", quotef (files_from),
file_number, _("invalid zero-length file name"));
}
skip_file = true;
@@ -1131,7 +1130,7 @@ main (int argc, char **argv)
di_set_free (di_mnt);
if (files_from && (ferror (stdin) || fclose (stdin) != 0) && ok)
die (EXIT_FAILURE, 0, _("error reading %s"), quoteaf (files_from));
error (EXIT_FAILURE, 0, _("error reading %s"), quoteaf (files_from));
if (print_grand_total)
print_size (&tot_dui, _("total"));

View File

@@ -16,9 +16,9 @@
#include <config.h>
#include <stdio.h>
#include <assert.h>
#include <sys/types.h>
#include "system.h"
#include "assure.h"
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "echo"
@@ -37,7 +37,7 @@ usage (int status)
{
/* STATUS should always be EXIT_SUCCESS (unlike in most other
utilities which would call emit_try_help otherwise). */
assert (status == EXIT_SUCCESS);
affirm (status == EXIT_SUCCESS);
printf (_("\
Usage: %s [SHORT-OPTION]... [STRING]...\n\
@@ -140,7 +140,7 @@ main (int argc, char **argv)
if (STREQ (argv[1], "--version"))
{
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME, Version, AUTHORS,
(char *) NULL);
(char *) nullptr);
return EXIT_SUCCESS;
}
}

106
src/env.c
View File

@@ -24,9 +24,6 @@
#include <signal.h>
#include "system.h"
#include "die.h"
#include "error.h"
#include "idx.h"
#include "operand2sig.h"
#include "quote.h"
#include "sig2str.h"
@@ -90,19 +87,19 @@ enum
static struct option const longopts[] =
{
{"ignore-environment", no_argument, NULL, 'i'},
{"null", no_argument, NULL, '0'},
{"unset", required_argument, NULL, 'u'},
{"chdir", required_argument, NULL, 'C'},
{"default-signal", optional_argument, NULL, DEFAULT_SIGNAL_OPTION},
{"ignore-signal", optional_argument, NULL, IGNORE_SIGNAL_OPTION},
{"block-signal", optional_argument, NULL, BLOCK_SIGNAL_OPTION},
{"list-signal-handling", no_argument, NULL, LIST_SIGNAL_HANDLING_OPTION},
{"debug", no_argument, NULL, 'v'},
{"split-string", required_argument, NULL, 'S'},
{"ignore-environment", no_argument, nullptr, 'i'},
{"null", no_argument, nullptr, '0'},
{"unset", required_argument, nullptr, 'u'},
{"chdir", required_argument, nullptr, 'C'},
{"default-signal", optional_argument, nullptr, DEFAULT_SIGNAL_OPTION},
{"ignore-signal", optional_argument, nullptr, IGNORE_SIGNAL_OPTION},
{"block-signal", optional_argument, nullptr, BLOCK_SIGNAL_OPTION},
{"list-signal-handling", no_argument, nullptr, LIST_SIGNAL_HANDLING_OPTION},
{"debug", no_argument, nullptr, 'v'},
{"split-string", required_argument, nullptr, 'S'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -182,12 +179,12 @@ unset_envvars (void)
devmsg ("unset: %s\n", usvars[i]);
if (unsetenv (usvars[i]))
die (EXIT_CANCELED, errno, _("cannot unset %s"),
quote (usvars[i]));
error (EXIT_CANCELED, errno, _("cannot unset %s"),
quote (usvars[i]));
}
}
/* Return a pointer to the end of a valid ${VARNAME} string, or NULL.
/* Return a pointer to the end of a valid ${VARNAME} string, or nullptr.
'str' should point to the '$' character.
First letter in VARNAME must be alpha or underscore,
rest of letters are alnum or underscore.
@@ -205,14 +202,14 @@ scan_varname (char const *str)
return end;
}
return NULL;
return nullptr;
}
/* Return a pointer to a static buffer containing the VARNAME as
extracted from a '${VARNAME}' string.
The returned string will be NUL terminated.
The returned pointer should not be freed.
Return NULL if not a valid ${VARNAME} syntax. */
Return nullptr if not a valid ${VARNAME} syntax. */
static char *
extract_varname (char const *str)
{
@@ -221,7 +218,7 @@ extract_varname (char const *str)
p = scan_varname (str);
if (!p)
return NULL;
return nullptr;
/* -2 and +2 (below) account for the '${' prefix. */
i = p - str - 2;
@@ -424,8 +421,8 @@ build_argv (char const *str, int extra_argc, int *argc)
case 'c':
if (dq)
die (EXIT_CANCELED, 0,
_("'\\c' must not appear in double-quoted -S string"));
error (EXIT_CANCELED, 0,
_("'\\c' must not appear in double-quoted -S string"));
goto eos; /* '\c' terminates the string. */
case 'f': newc = '\f'; break;
@@ -435,11 +432,12 @@ build_argv (char const *str, int extra_argc, int *argc)
case 'v': newc = '\v'; break;
case '\0':
die (EXIT_CANCELED, 0,
_("invalid backslash at end of string in -S"));
error (EXIT_CANCELED, 0,
_("invalid backslash at end of string in -S"));
default:
die (EXIT_CANCELED, 0, _("invalid sequence '\\%c' in -S"), newc);
error (EXIT_CANCELED, 0,
_("invalid sequence '\\%c' in -S"), newc);
}
break;
@@ -452,9 +450,9 @@ build_argv (char const *str, int extra_argc, int *argc)
{
char *n = extract_varname (str);
if (!n)
die (EXIT_CANCELED, 0,
_("only ${VARNAME} expansion is supported, error at: %s"),
str);
error (EXIT_CANCELED, 0,
_("only ${VARNAME} expansion is supported, error at: %s"),
str);
char *v = getenv (n);
if (v)
@@ -478,7 +476,7 @@ build_argv (char const *str, int extra_argc, int *argc)
}
if (dq || sq)
die (EXIT_CANCELED, 0, _("no terminating quote in -S string"));
error (EXIT_CANCELED, 0, _("no terminating quote in -S string"));
eos:
splitbuf_append_byte (&ss, '\0');
@@ -496,7 +494,7 @@ build_argv (char const *str, int extra_argc, int *argc)
argv[1] = "-S-i -C/tmp A=B"
argv[2] = "foo"
argv[3] = "bar"
argv[4] = NULL
argv[4] = nullptr
This function will modify argv to be:
argv[0] = "env"
argv[1] = "-i"
@@ -504,7 +502,7 @@ build_argv (char const *str, int extra_argc, int *argc)
argv[3] = "A=B"
argv[4] = "foo"
argv[5] = "bar"
argv[6] = NULL
argv[6] = nullptr
argc will be updated from 4 to 6.
optind will be reset to 0 to force getopt_long to rescan all arguments. */
static void
@@ -569,7 +567,7 @@ parse_signal_action_params (char const *optarg, bool set_default)
signals[signum] = set_default ? DEFAULT : IGNORE;
opt_sig = strtok (NULL, ",");
opt_sig = strtok (nullptr, ",");
}
free (optarg_writable);
@@ -591,19 +589,19 @@ reset_signal_handlers (void)
bool set_to_default = (signals[i] == DEFAULT
|| signals[i] == DEFAULT_NOERR);
int sig_err = sigaction (i, NULL, &act);
int sig_err = sigaction (i, nullptr, &act);
if (sig_err && !ignore_errors)
die (EXIT_CANCELED, errno,
_("failed to get signal action for signal %d"), i);
error (EXIT_CANCELED, errno,
_("failed to get signal action for signal %d"), i);
if (! sig_err)
{
act.sa_handler = set_to_default ? SIG_DFL : SIG_IGN;
sig_err = sigaction (i, &act, NULL);
sig_err = sigaction (i, &act, nullptr);
if (sig_err && !ignore_errors)
die (EXIT_CANCELED, errno,
_("failed to set signal action for signal %d"), i);
error (EXIT_CANCELED, errno,
_("failed to set signal action for signal %d"), i);
}
if (dev_debug)
@@ -659,7 +657,7 @@ parse_block_signal_params (char const *optarg, bool block)
sigaddset (block ? &block_signals : &unblock_signals, signum);
sigdelset (block ? &unblock_signals : &block_signals, signum);
opt_sig = strtok (NULL, ",");
opt_sig = strtok (nullptr, ",");
}
free (optarg_writable);
@@ -674,8 +672,8 @@ set_signal_proc_mask (void)
sigemptyset (&set);
if (sigprocmask (0, NULL, &set))
die (EXIT_CANCELED, errno, _("failed to get signal process mask"));
if (sigprocmask (0, nullptr, &set))
error (EXIT_CANCELED, errno, _("failed to get signal process mask"));
for (int i = 1; i <= SIGNUM_BOUND; i++)
{
@@ -691,7 +689,7 @@ set_signal_proc_mask (void)
}
else
{
debug_act = NULL;
debug_act = nullptr;
}
if (dev_debug && debug_act)
@@ -703,8 +701,8 @@ set_signal_proc_mask (void)
}
}
if (sigprocmask (SIG_SETMASK, &set, NULL))
die (EXIT_CANCELED, errno, _("failed to set signal process mask"));
if (sigprocmask (SIG_SETMASK, &set, nullptr))
error (EXIT_CANCELED, errno, _("failed to set signal process mask"));
}
static void
@@ -714,13 +712,13 @@ list_signal_handling (void)
char signame[SIG2STR_MAX];
sigemptyset (&set);
if (sigprocmask (0, NULL, &set))
die (EXIT_CANCELED, errno, _("failed to get signal process mask"));
if (sigprocmask (0, nullptr, &set))
error (EXIT_CANCELED, errno, _("failed to get signal process mask"));
for (int i = 1; i <= SIGNUM_BOUND; i++)
{
struct sigaction act;
if (sigaction (i, NULL, &act))
if (sigaction (i, nullptr, &act))
continue;
char const *ignored = act.sa_handler == SIG_IGN ? "IGNORE" : "";
@@ -753,7 +751,7 @@ main (int argc, char **argv)
int optc;
bool ignore_environment = false;
bool opt_nul_terminate_output = false;
char const *newdir = NULL;
char const *newdir = nullptr;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -766,7 +764,7 @@ main (int argc, char **argv)
initialize_signals ();
while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1)
{
switch (optc)
{
@@ -826,7 +824,7 @@ main (int argc, char **argv)
if (ignore_environment)
{
devmsg ("cleaning environ\n");
static char *dummy_environ[] = { NULL };
static char *dummy_environ[] = { nullptr };
environ = dummy_environ;
}
else
@@ -840,8 +838,8 @@ main (int argc, char **argv)
if (putenv (argv[optind]))
{
*eq = '\0';
die (EXIT_CANCELED, errno, _("cannot set %s"),
quote (argv[optind]));
error (EXIT_CANCELED, errno, _("cannot set %s"),
quote (argv[optind]));
}
optind++;
}
@@ -881,8 +879,8 @@ main (int argc, char **argv)
devmsg ("chdir: %s\n", quoteaf (newdir));
if (chdir (newdir) != 0)
die (EXIT_CANCELED, errno, _("cannot change directory to %s"),
quoteaf (newdir));
error (EXIT_CANCELED, errno, _("cannot change directory to %s"),
quoteaf (newdir));
}
if (dev_debug)

View File

@@ -1,4 +1,4 @@
/* expand-common - common functionality for expand/unexapnd
/* expand-common - common functionality for expand/unexpand
Copyright (C) 1989-2023 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
@@ -16,12 +16,9 @@
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include "system.h"
#include "die.h"
#include "error.h"
#include "fadvise.h"
#include "quote.h"
@@ -46,7 +43,7 @@ size_t max_column_width;
/* Array of the explicit column numbers of the tab stops;
after 'tab_list' is exhausted, each additional tab is replaced
by a space. The first column is column 0. */
static uintmax_t *tab_list = NULL;
static uintmax_t *tab_list = nullptr;
/* The number of allocated entries in 'tab_list'. */
static size_t n_tabs_allocated = 0;
@@ -56,12 +53,12 @@ static size_t n_tabs_allocated = 0;
static size_t first_free_tab = 0;
/* Null-terminated array of input filenames. */
static char **file_list = NULL;
static char **file_list = nullptr;
/* Default for 'file_list' if no files are given on the command line. */
static char *stdin_argv[] =
{
(char *) "-", NULL
(char *) "-", nullptr
};
/* True if we have ever read standard input. */
@@ -86,7 +83,7 @@ add_tab_stop (uintmax_t tabval)
if (max_column_width < column_width)
{
if (SIZE_MAX < column_width)
die (EXIT_FAILURE, 0, _("tabs are too far apart"));
error (EXIT_FAILURE, 0, _("tabs are too far apart"));
max_column_width = column_width;
}
}
@@ -134,7 +131,7 @@ parse_tab_stops (char const *stops)
uintmax_t tabval = 0;
bool extend_tabval = false;
bool increment_tabval = false;
char const *num_start = NULL;
char const *num_start = nullptr;
bool ok = true;
for (; *stops; stops++)
@@ -240,14 +237,14 @@ validate_tab_stops (uintmax_t const *tabs, size_t entries)
for (size_t i = 0; i < entries; i++)
{
if (tabs[i] == 0)
die (EXIT_FAILURE, 0, _("tab size cannot be 0"));
error (EXIT_FAILURE, 0, _("tab size cannot be 0"));
if (tabs[i] <= prev_tab)
die (EXIT_FAILURE, 0, _("tab sizes must be ascending"));
error (EXIT_FAILURE, 0, _("tab sizes must be ascending"));
prev_tab = tabs[i];
}
if (increment_size && extend_size)
die (EXIT_FAILURE, 0, _("'/' specifier is mutually exclusive with '+'"));
error (EXIT_FAILURE, 0, _("'/' specifier is mutually exclusive with '+'"));
}
/* Called after all command-line options have been parsed,
@@ -324,10 +321,10 @@ set_file_list (char **list)
file_list = list;
}
/* Close the old stream pointer FP if it is non-NULL,
/* Close the old stream pointer FP if it is non-null,
and return a new one opened to read the next input file.
Open a filename of '-' as the standard input.
Return NULL if there are no more input files. */
Return nullptr if there are no more input files. */
extern FILE *
next_file (FILE *fp)
@@ -337,7 +334,6 @@ next_file (FILE *fp)
if (fp)
{
assert (prev_file);
int err = errno;
if (!ferror (fp))
err = 0;
@@ -352,7 +348,7 @@ next_file (FILE *fp)
}
}
while ((file = *file_list++) != NULL)
while ((file = *file_list++) != nullptr)
{
if (STREQ (file, "-"))
{
@@ -370,7 +366,7 @@ next_file (FILE *fp)
error (0, errno, "%s", quotef (file));
exit_status = EXIT_FAILURE;
}
return NULL;
return nullptr;
}
/* */
@@ -378,7 +374,7 @@ extern void
cleanup_file_list_stdin (void)
{
if (have_read_stdin && fclose (stdin) != 0)
die (EXIT_FAILURE, errno, "-");
error (EXIT_FAILURE, errno, "-");
}

View File

@@ -1,4 +1,4 @@
/* expand-common - common functionality for expand/unexapnd
/* expand-common - common functionality for expand/unexpand
Copyright (C) 1989-2023 Free Software Foundation, Inc.
@@ -52,10 +52,10 @@ finalize_tab_stops (void);
extern void
set_file_list (char **file_list);
/* Close the old stream pointer FP if it is non-NULL,
/* Close the old stream pointer FP if it is non-null,
and return a new one opened to read the next input file.
Open a filename of '-' as the standard input.
Return NULL if there are no more input files. */
Return nullptr if there are no more input files. */
extern FILE *
next_file (FILE *fp);

View File

@@ -38,8 +38,6 @@
#include <getopt.h>
#include <sys/types.h>
#include "system.h"
#include "die.h"
#include "expand-common.h"
/* The official name of this program (e.g., no 'g' prefix). */
@@ -51,11 +49,11 @@ static char const shortopts[] = "it:0::1::2::3::4::5::6::7::8::9::";
static struct option const longopts[] =
{
{"tabs", required_argument, NULL, 't'},
{"initial", no_argument, NULL, 'i'},
{"tabs", required_argument, nullptr, 't'},
{"initial", no_argument, nullptr, 'i'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -96,7 +94,7 @@ static void
expand (void)
{
/* Input stream. */
FILE *fp = next_file (NULL);
FILE *fp = next_file (nullptr);
if (!fp)
return;
@@ -142,11 +140,11 @@ expand (void)
next_tab_column = column + 1;
if (next_tab_column < column)
die (EXIT_FAILURE, 0, _("input line is too long"));
error (EXIT_FAILURE, 0, _("input line is too long"));
while (++column < next_tab_column)
if (putchar (' ') < 0)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
c = ' ';
}
@@ -161,7 +159,7 @@ expand (void)
{
column++;
if (!column)
die (EXIT_FAILURE, 0, _("input line is too long"));
error (EXIT_FAILURE, 0, _("input line is too long"));
}
convert &= convert_entire_line || !! isblank (c);
@@ -171,7 +169,7 @@ expand (void)
return;
if (putchar (c) < 0)
die (EXIT_FAILURE, errno, _("write error"));
write_error ();
}
while (c != '\n');
}
@@ -191,7 +189,7 @@ main (int argc, char **argv)
atexit (close_stdout);
convert_entire_line = true;
while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
while ((c = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1)
{
switch (c)
{
@@ -227,7 +225,7 @@ main (int argc, char **argv)
finalize_tab_stops ();
set_file_list ((optind < argc) ? &argv[optind] : NULL);
set_file_list (optind < argc ? &argv[optind] : nullptr);
expand ();

View File

@@ -35,8 +35,6 @@
#include <gmp.h>
#include <regex.h>
#include "die.h"
#include "error.h"
#include "long-options.h"
#include "mbuiter.h"
#include "strnumcmp.h"
@@ -331,18 +329,17 @@ 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 *) nullptr);
/* The above handles --help and --version.
Since there is no other invocation of getopt, handle '--' here. */
unsigned int u_argc = argc;
if (1 < u_argc && STREQ (argv[1], "--"))
if (1 < argc && STREQ (argv[1], "--"))
{
--u_argc;
--argc;
++argv;
}
if (u_argc <= 1)
if (argc <= 1)
{
error (0, 0, _("missing operand"));
usage (EXPR_INVALID);
@@ -352,8 +349,8 @@ main (int argc, char **argv)
v = eval (true);
if (!nomoreargs ())
die (EXPR_INVALID, 0, _("syntax error: unexpected argument %s"),
quotearg_n_style (0, locale_quoting_style, *args));
error (EXPR_INVALID, 0, _("syntax error: unexpected argument %s"),
quotearg_n_style (0, locale_quoting_style, *args));
printv (v);
@@ -409,7 +406,7 @@ printv (VALUE *v)
puts (v->u.s);
break;
default:
abort ();
unreachable ();
}
}
@@ -441,7 +438,7 @@ null (VALUE *v)
return true;
}
default:
abort ();
unreachable ();
}
}
@@ -470,7 +467,7 @@ tostring (VALUE *v)
{
case integer:
{
char *s = mpz_get_str (NULL, 10, v->u.i);
char *s = mpz_get_str (nullptr, 10, v->u.i);
mpz_clear (v->u.i);
v->u.s = s;
v->type = string;
@@ -479,7 +476,7 @@ tostring (VALUE *v)
case string:
break;
default:
abort ();
unreachable ();
}
}
@@ -499,13 +496,13 @@ toarith (VALUE *v)
if (! looks_like_integer (s))
return false;
if (mpz_init_set_str (v->u.i, s, 10) != 0)
die (EXPR_FAILURE, ERANGE, "%s", (s));
error (EXPR_FAILURE, ERANGE, "%s", (s));
free (s);
v->type = integer;
return true;
}
default:
abort ();
unreachable ();
}
}
@@ -527,12 +524,12 @@ getsize (mpz_t i)
}
/* Return true and advance if the next token matches STR exactly.
STR must not be NULL. */
STR must not be null. */
static bool
nextarg (char const *str)
{
if (*args == NULL)
if (*args == nullptr)
return false;
else
{
@@ -557,8 +554,8 @@ static void
require_more_args (void)
{
if (nomoreargs ())
die (EXPR_INVALID, 0, _("syntax error: missing argument after %s"),
quotearg_n_style (0, locale_quoting_style, *(args - 1)));
error (EXPR_INVALID, 0, _("syntax error: missing argument after %s"),
quotearg_n_style (0, locale_quoting_style, *(args - 1)));
}
@@ -596,18 +593,18 @@ docolon (VALUE *sv, VALUE *pv)
tostring (pv);
re_regs.num_regs = 0;
re_regs.start = NULL;
re_regs.end = NULL;
re_regs.start = nullptr;
re_regs.end = nullptr;
re_buffer.buffer = NULL;
re_buffer.buffer = nullptr;
re_buffer.allocated = 0;
re_buffer.fastmap = fastmap;
re_buffer.translate = NULL;
re_buffer.translate = nullptr;
re_syntax_options =
RE_SYNTAX_POSIX_BASIC & ~RE_CONTEXT_INVALID_DUP & ~RE_NO_EMPTY_RANGES;
errmsg = re_compile_pattern (pv->u.s, strlen (pv->u.s), &re_buffer);
if (errmsg)
die (EXPR_INVALID, 0, "%s", (errmsg));
error (EXPR_INVALID, 0, "%s", (errmsg));
re_buffer.newline_anchor = 0;
matchlen = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs);
@@ -643,16 +640,16 @@ docolon (VALUE *sv, VALUE *pv)
v = int_value (0);
}
else
die (EXPR_FAILURE,
(matchlen == -2 ? errno : EOVERFLOW),
_("error in regular expression matcher"));
error (EXPR_FAILURE,
matchlen == -2 ? errno : EOVERFLOW,
_("error in regular expression matcher"));
if (0 < re_regs.num_regs)
{
free (re_regs.start);
free (re_regs.end);
}
re_buffer.fastmap = NULL;
re_buffer.fastmap = nullptr;
regfree (&re_buffer);
return v;
}
@@ -673,16 +670,16 @@ eval7 (bool evaluate)
{
v = eval (evaluate);
if (nomoreargs ())
die (EXPR_INVALID, 0, _("syntax error: expecting ')' after %s"),
quotearg_n_style (0, locale_quoting_style, *(args - 1)));
error (EXPR_INVALID, 0, _("syntax error: expecting ')' after %s"),
quotearg_n_style (0, locale_quoting_style, *(args - 1)));
if (!nextarg (")"))
die (EXPR_INVALID, 0, _("syntax error: expecting ')' instead of %s"),
quotearg_n_style (0, locale_quoting_style, *args));
error (EXPR_INVALID, 0, _("syntax error: expecting ')' instead of %s"),
quotearg_n_style (0, locale_quoting_style, *args));
return v;
}
if (nextarg (")"))
die (EXPR_INVALID, 0, _("syntax error: unexpected ')'"));
error (EXPR_INVALID, 0, _("syntax error: unexpected ')'"));
return str_value (*args++);
}
@@ -828,9 +825,9 @@ eval4 (bool evaluate)
if (evaluate)
{
if (!toarith (l) || !toarith (r))
die (EXPR_INVALID, 0, _("non-integer argument"));
error (EXPR_INVALID, 0, _("non-integer argument"));
if (fxn != multiply && mpz_sgn (r->u.i) == 0)
die (EXPR_INVALID, 0, _("division by zero"));
error (EXPR_INVALID, 0, _("division by zero"));
((fxn == multiply ? mpz_mul
: fxn == divide ? mpz_tdiv_q
: mpz_tdiv_r)
@@ -865,7 +862,7 @@ eval3 (bool evaluate)
if (evaluate)
{
if (!toarith (l) || !toarith (r))
die (EXPR_INVALID, 0, _("non-integer argument"));
error (EXPR_INVALID, 0, _("non-integer argument"));
(fxn == plus ? mpz_add : mpz_sub) (l->u.i, l->u.i, r->u.i);
}
freev (r);
@@ -925,10 +922,10 @@ eval2 (bool evaluate)
{
error (0, errno, _("string comparison failed"));
error (0, 0, _("set LC_ALL='C' to work around the problem"));
die (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));
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));
}
}
@@ -940,7 +937,7 @@ eval2 (bool evaluate)
case not_equal: val = (cmp != 0); break;
case greater_equal: val = (cmp >= 0); break;
case greater_than: val = (cmp > 0); break;
default: abort ();
default: unreachable ();
}
}

View File

@@ -24,7 +24,7 @@
/* Efficiently factor numbers that fit in one or two words (word = uintmax_t),
or, with GMP, numbers of any size.
Code organisation:
Code organization:
There are several variants of many functions, for handling one word, two
words, and GMP's mpz_t type. If the one-word variant is called foo, the
@@ -48,7 +48,7 @@
Status of found factors are checked again using Miller-Rabin and Lucas.
We prefer using Hensel norm in the divisions, not the more familiar
Euclidian norm, since the former leads to much faster code. In the
Euclidean norm, since the former leads to much faster code. In the
Pollard-Brent rho code and the prime testing code, we use Montgomery's
trick of multiplying all n-residues by the word base, allowing cheap Hensel
reductions mod n.
@@ -77,10 +77,10 @@
using gcc 4.6 and 4.7. Some software pipelining should help; 1, 2, and 4
respectively cycles ought to be possible.
* The redcify function could be vastly improved by using (plain Euclidian)
* The redcify function could be vastly improved by using (plain Euclidean)
pre-inversion (such as GMP's invert_limb) and udiv_qrnnd_preinv (from
GMP's gmp-impl.h). The redcify2 function could be vastly improved using
similar methoods. These functions currently dominate run time when using
similar methods. These functions currently dominate run time when using
the -w option.
*/
@@ -105,11 +105,9 @@
#include <getopt.h>
#include <stdio.h>
#include <gmp.h>
#include <assert.h>
#include "system.h"
#include "die.h"
#include "error.h"
#include "assure.h"
#include "full-write.h"
#include "quote.h"
#include "readtokens.h"
@@ -120,8 +118,8 @@
#define AUTHORS \
proper_name ("Paul Rubin"), \
proper_name_utf8 ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
proper_name_utf8 ("Niels Moller", "Niels M\303\266ller")
proper_name_lite ("Torbjorn Granlund", "Torbj\303\266rn Granlund"), \
proper_name_lite ("Niels Moller", "Niels M\303\266ller")
/* Token delimiters when reading from a file. */
#define DELIM "\n\t "
@@ -226,11 +224,11 @@ enum
static struct option const long_options[] =
{
{"exponents", no_argument, NULL, 'h'},
{"-debug", no_argument, NULL, DEV_DEBUG_OPTION},
{"exponents", no_argument, nullptr, 'h'},
{"-debug", no_argument, nullptr, DEV_DEBUG_OPTION},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* If true, use p^e output format. */
@@ -248,7 +246,7 @@ struct mp_factors
{
mpz_t *p;
unsigned long int *e;
unsigned long int nfactors;
idx_t nfactors;
};
static void factor (uintmax_t, uintmax_t, struct factors *);
@@ -289,11 +287,11 @@ static void factor (uintmax_t, uintmax_t, struct factors *);
do { \
uintmax_t __d1, __d0, __q, __r1, __r0; \
\
assert ((n1) < (d)); \
__d1 = (d); __d0 = 0; \
__r1 = (n1); __r0 = (n0); \
affirm (__r1 < __d1); \
__q = 0; \
for (unsigned int __i = W_TYPE_SIZE; __i > 0; __i--) \
for (int __i = W_TYPE_SIZE; __i > 0; __i--) \
{ \
rsh2 (__d1, __d0, __d1, __d0, 1); \
__q <<= 1; \
@@ -349,7 +347,7 @@ static void factor (uintmax_t, uintmax_t, struct factors *);
#ifndef count_leading_zeros
# define count_leading_zeros(count, x) do { \
uintmax_t __clz_x = (x); \
unsigned int __clz_c; \
int __clz_c; \
for (__clz_c = 0; \
(__clz_x & ((uintmax_t) 0xff << (W_TYPE_SIZE - 8))) == 0; \
__clz_c += 8) \
@@ -363,7 +361,7 @@ static void factor (uintmax_t, uintmax_t, struct factors *);
#ifndef count_trailing_zeros
# define count_trailing_zeros(count, x) do { \
uintmax_t __ctz_x = (x); \
unsigned int __ctz_c = 0; \
int __ctz_c = 0; \
while ((__ctz_x & 1) == 0) \
{ \
__ctz_x >>= 1; \
@@ -412,7 +410,7 @@ mod2 (uintmax_t *r1, uintmax_t a1, uintmax_t a0, uintmax_t d1, uintmax_t d0)
{
int cntd, cnta;
assert (d1 != 0);
affirm (d1 != 0);
if (a1 == 0)
{
@@ -477,7 +475,7 @@ gcd_odd (uintmax_t a, uintmax_t b)
static uintmax_t
gcd2_odd (uintmax_t *r1, uintmax_t a1, uintmax_t a0, uintmax_t b1, uintmax_t b0)
{
assert (b0 & 1);
affirm (b0 & 1);
if ((a0 | a1) == 0)
{
@@ -520,9 +518,9 @@ gcd2_odd (uintmax_t *r1, uintmax_t a1, uintmax_t a0, uintmax_t b1, uintmax_t b0)
static void
factor_insert_multiplicity (struct factors *factors,
uintmax_t prime, unsigned int m)
uintmax_t prime, int m)
{
unsigned int nfactors = factors->nfactors;
int nfactors = factors->nfactors;
uintmax_t *p = factors->p;
unsigned char *e = factors->e;
@@ -559,7 +557,7 @@ factor_insert_large (struct factors *factors,
{
if (p1 > 0)
{
assert (factors->plarge[1] == 0);
affirm (factors->plarge[1] == 0);
factors->plarge[0] = p0;
factors->plarge[1] = p1;
}
@@ -594,15 +592,15 @@ static void mp_factor (mpz_t, struct mp_factors *);
static void
mp_factor_init (struct mp_factors *factors)
{
factors->p = NULL;
factors->e = NULL;
factors->p = nullptr;
factors->e = nullptr;
factors->nfactors = 0;
}
static void
mp_factor_clear (struct mp_factors *factors)
{
for (unsigned int i = 0; i < factors->nfactors; i++)
for (idx_t i = 0; i < factors->nfactors; i++)
mpz_clear (factors->p[i]);
free (factors->p);
@@ -612,10 +610,10 @@ mp_factor_clear (struct mp_factors *factors)
static void
mp_factor_insert (struct mp_factors *factors, mpz_t prime)
{
unsigned long int nfactors = factors->nfactors;
mpz_t *p = factors->p;
unsigned long int *e = factors->e;
long i;
idx_t nfactors = factors->nfactors;
mpz_t *p = factors->p;
unsigned long int *e = factors->e;
ptrdiff_t i;
/* Locate position for insert new or increment e. */
for (i = nfactors - 1; i >= 0; i--)
@@ -626,8 +624,8 @@ mp_factor_insert (struct mp_factors *factors, mpz_t prime)
if (i < 0 || mpz_cmp (p[i], prime) != 0)
{
p = xrealloc (p, (nfactors + 1) * sizeof p[0]);
e = xrealloc (e, (nfactors + 1) * sizeof e[0]);
p = xireallocarray (p, nfactors + 1, sizeof p[0]);
e = xireallocarray (e, nfactors + 1, sizeof e[0]);
mpz_init (p[nfactors]);
for (long j = nfactors - 1; j > i; j--)
@@ -709,10 +707,9 @@ static bool flag_prove_primality = PROVE_PRIMALITY;
#define MR_REPS 25
static void
factor_insert_refind (struct factors *factors, uintmax_t p, unsigned int i,
unsigned int off)
factor_insert_refind (struct factors *factors, uintmax_t p, int i, int off)
{
for (unsigned int j = 0; j < off; j++)
for (int j = 0; j < off; j++)
p += primes_diff[i + j];
factor_insert (factors, p);
}
@@ -756,7 +753,7 @@ factor_using_division (uintmax_t *t1p, uintmax_t t1, uintmax_t t0,
{
if (t0 % 2 == 0)
{
unsigned int cnt;
int cnt;
if (t0 == 0)
{
@@ -775,7 +772,7 @@ factor_using_division (uintmax_t *t1p, uintmax_t t1, uintmax_t t0,
}
uintmax_t p = 3;
unsigned int i;
idx_t i;
for (i = 0; t1 > 0 && i < PRIMES_PTAB_ENTRIES; i++)
{
for (;;)
@@ -836,7 +833,7 @@ static void
mp_factor_using_division (mpz_t t, struct mp_factors *factors)
{
mpz_t q;
unsigned long int p;
mp_bitcnt_t p;
devmsg ("[trial division] ");
@@ -850,19 +847,19 @@ mp_factor_using_division (mpz_t t, struct mp_factors *factors)
--p;
}
p = 3;
for (unsigned int i = 1; i <= PRIMES_PTAB_ENTRIES;)
unsigned long int d = 3;
for (idx_t i = 1; i <= PRIMES_PTAB_ENTRIES;)
{
if (! mpz_divisible_ui_p (t, p))
if (! mpz_divisible_ui_p (t, d))
{
p += primes_diff[i++];
if (mpz_cmp_ui (t, p * p) < 0)
d += primes_diff[i++];
if (mpz_cmp_ui (t, d * d) < 0)
break;
}
else
{
mpz_tdiv_q_ui (t, t, p);
mp_factor_insert_ui (factors, p);
mpz_tdiv_q_ui (t, t, d);
mp_factor_insert_ui (factors, d);
}
}
@@ -994,9 +991,9 @@ mulredc2 (uintmax_t *r1p,
uintmax_t r1, r0, q, p1, t1, t0, s1, s0;
MAYBE_UNUSED uintmax_t p0;
mi = -mi;
assert ((a1 >> (W_TYPE_SIZE - 1)) == 0);
assert ((b1 >> (W_TYPE_SIZE - 1)) == 0);
assert ((m1 >> (W_TYPE_SIZE - 1)) == 0);
affirm ((a1 >> (W_TYPE_SIZE - 1)) == 0);
affirm ((b1 >> (W_TYPE_SIZE - 1)) == 0);
affirm ((m1 >> (W_TYPE_SIZE - 1)) == 0);
/* First compute a0 * <b1, b0> B^{-1}
+-----+
@@ -1082,7 +1079,7 @@ powm2 (uintmax_t *r1m,
uintmax_t ni, const uintmax_t *one)
{
uintmax_t r1, r0, b1, b0, n1, n0;
unsigned int i;
int i;
uintmax_t e;
b0 = bp[0];
@@ -1120,7 +1117,7 @@ powm2 (uintmax_t *r1m,
ATTRIBUTE_CONST
static bool
millerrabin (uintmax_t n, uintmax_t ni, uintmax_t b, uintmax_t q,
unsigned int k, uintmax_t one)
int k, uintmax_t one)
{
uintmax_t y = powm (b, q, n, ni, one);
@@ -1129,7 +1126,7 @@ millerrabin (uintmax_t n, uintmax_t ni, uintmax_t b, uintmax_t q,
if (y == one || y == nm1)
return true;
for (unsigned int i = 1; i < k; i++)
for (int i = 1; i < k; i++)
{
y = mulredc (y, y, n, ni);
@@ -1143,7 +1140,7 @@ millerrabin (uintmax_t n, uintmax_t ni, uintmax_t b, uintmax_t q,
ATTRIBUTE_PURE static bool
millerrabin2 (const uintmax_t *np, uintmax_t ni, const uintmax_t *bp,
const uintmax_t *qp, unsigned int k, const uintmax_t *one)
const uintmax_t *qp, int k, const uintmax_t *one)
{
uintmax_t y1, y0, nm1_1, nm1_0, r1m;
@@ -1158,7 +1155,7 @@ millerrabin2 (const uintmax_t *np, uintmax_t ni, const uintmax_t *bp,
if (y0 == nm1_0 && y1 == nm1_1)
return true;
for (unsigned int i = 1; i < k; i++)
for (int i = 1; i < k; i++)
{
y0 = mulredc2 (&r1m, y1, y0, y1, y0, np[1], np[0], ni);
y1 = r1m;
@@ -1173,14 +1170,14 @@ millerrabin2 (const uintmax_t *np, uintmax_t ni, const uintmax_t *bp,
static bool
mp_millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y,
mpz_srcptr q, unsigned long int k)
mpz_srcptr q, mp_bitcnt_t k)
{
mpz_powm (y, x, q, n);
if (mpz_cmp_ui (y, 1) == 0 || mpz_cmp (y, nm1) == 0)
return true;
for (unsigned long int i = 1; i < k; i++)
for (mp_bitcnt_t i = 1; i < k; i++)
{
mpz_powm_ui (y, y, 2, n);
if (mpz_cmp (y, nm1) == 0)
@@ -1193,10 +1190,10 @@ mp_millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y,
/* Lucas' prime test. The number of iterations vary greatly, up to a few dozen
have been observed. The average seem to be about 2. */
static bool
static bool ATTRIBUTE_PURE
prime_p (uintmax_t n)
{
int k;
mp_bitcnt_t k;
bool is_prime;
uintmax_t a_prim, one, ni;
struct factors factors;
@@ -1204,7 +1201,7 @@ prime_p (uintmax_t n)
if (n <= 1)
return false;
/* We have already casted out small primes. */
/* We have already cast out small primes. */
if (n < (uintmax_t) FIRST_OMITTED_PRIME * FIRST_OMITTED_PRIME)
return true;
@@ -1230,12 +1227,12 @@ prime_p (uintmax_t n)
/* Loop until Lucas proves our number prime, or Miller-Rabin proves our
number composite. */
for (unsigned int r = 0; r < PRIMES_PTAB_ENTRIES; r++)
for (idx_t r = 0; r < PRIMES_PTAB_ENTRIES; r++)
{
if (flag_prove_primality)
{
is_prime = true;
for (unsigned int i = 0; i < factors.nfactors && is_prime; i++)
for (int i = 0; i < factors.nfactors && is_prime; i++)
{
is_prime
= powm (a_prim, (n - 1) / factors.p[i], n, ni, one) != one;
@@ -1271,11 +1268,10 @@ prime_p (uintmax_t n)
return false;
}
error (0, 0, _("Lucas prime test failure. This should not happen"));
abort ();
affirm (!"Lucas prime test failure. This should not happen");
}
static bool
static bool ATTRIBUTE_PURE
prime2_p (uintmax_t n1, uintmax_t n0)
{
uintmax_t q[2], nm1[2];
@@ -1283,7 +1279,7 @@ prime2_p (uintmax_t n1, uintmax_t n0)
uintmax_t one[2];
uintmax_t na[2];
uintmax_t ni;
unsigned int k;
int k;
struct factors factors;
if (n1 == 0)
@@ -1325,7 +1321,7 @@ prime2_p (uintmax_t n1, uintmax_t n0)
/* Loop until Lucas proves our number prime, or Miller-Rabin proves our
number composite. */
for (unsigned int r = 0; r < PRIMES_PTAB_ENTRIES; r++)
for (idx_t r = 0; r < PRIMES_PTAB_ENTRIES; r++)
{
bool is_prime;
uintmax_t e[2], y[2];
@@ -1342,7 +1338,7 @@ prime2_p (uintmax_t n1, uintmax_t n0)
y[0] = powm2 (&y[1], a_prim, e, na, ni, one);
is_prime = (y[0] != one[0] || y[1] != one[1]);
}
for (unsigned int i = 0; i < factors.nfactors && is_prime; i++)
for (int i = 0; i < factors.nfactors && is_prime; i++)
{
/* FIXME: We always have the factor 2. Do we really need to
handle it here? We have done the same powering as part
@@ -1371,8 +1367,7 @@ prime2_p (uintmax_t n1, uintmax_t n0)
return false;
}
error (0, 0, _("Lucas prime test failure. This should not happen"));
abort ();
affirm (!"Lucas prime test failure. This should not happen");
}
static bool
@@ -1385,17 +1380,17 @@ mp_prime_p (mpz_t n)
if (mpz_cmp_ui (n, 1) <= 0)
return false;
/* We have already casted out small primes. */
/* We have already cast out small primes. */
if (mpz_cmp_ui (n, (long) FIRST_OMITTED_PRIME * FIRST_OMITTED_PRIME) < 0)
return true;
mpz_inits (q, a, nm1, tmp, NULL);
mpz_inits (q, a, nm1, tmp, nullptr);
/* Precomputation for Miller-Rabin. */
mpz_sub_ui (nm1, n, 1);
/* Find q and k, where q is odd and n = 1 + 2**k * q. */
unsigned long int k = mpz_scan1 (nm1, 0);
mp_bitcnt_t k = mpz_scan1 (nm1, 0);
mpz_tdiv_q_2exp (q, nm1, k);
mpz_set_ui (a, 2);
@@ -1416,12 +1411,12 @@ mp_prime_p (mpz_t n)
/* Loop until Lucas proves our number prime, or Miller-Rabin proves our
number composite. */
for (unsigned int r = 0; r < PRIMES_PTAB_ENTRIES; r++)
for (idx_t r = 0; r < PRIMES_PTAB_ENTRIES; r++)
{
if (flag_prove_primality)
{
is_prime = true;
for (unsigned long int i = 0; i < factors.nfactors && is_prime; i++)
for (idx_t i = 0; i < factors.nfactors && is_prime; i++)
{
mpz_divexact (tmp, nm1, factors.p[i]);
mpz_powm (tmp, a, tmp, n);
@@ -1446,14 +1441,13 @@ mp_prime_p (mpz_t n)
}
}
error (0, 0, _("Lucas prime test failure. This should not happen"));
abort ();
affirm (!"Lucas prime test failure. This should not happen");
ret1:
if (flag_prove_primality)
mp_factor_clear (&factors);
ret2:
mpz_clears (q, a, nm1, tmp, NULL);
mpz_clears (q, a, nm1, tmp, nullptr);
return is_prime;
}
@@ -1473,7 +1467,7 @@ factor_using_pollard_rho (uintmax_t n, unsigned long int a,
while (n != 1)
{
assert (a < n);
affirm (a < n);
binv (ni, n); /* FIXME: when could we use old 'ni' value? */
@@ -1677,7 +1671,7 @@ mp_factor_using_pollard_rho (mpz_t n, unsigned long int a,
devmsg ("[pollard-rho (%lu)] ", a);
mpz_inits (t, t2, NULL);
mpz_inits (t, t2, nullptr);
mpz_init_set_si (y, 2);
mpz_init_set_si (x, 2);
mpz_init_set_si (z, 2);
@@ -1757,7 +1751,7 @@ mp_factor_using_pollard_rho (mpz_t n, unsigned long int a,
mpz_mod (y, y, n);
}
mpz_clears (P, t2, t, z, x, y, NULL);
mpz_clears (P, t2, t, z, x, y, nullptr);
}
#if USE_SQUFOF
@@ -1768,14 +1762,14 @@ static uintmax_t
isqrt (uintmax_t n)
{
uintmax_t x;
unsigned c;
int c;
if (n == 0)
return 0;
count_leading_zeros (c, n);
/* Make x > sqrt(n). This will be invariant through the loop. */
x = (uintmax_t) 1 << ((W_TYPE_SIZE + 1 - c) / 2);
x = (uintmax_t) 1 << ((W_TYPE_SIZE + 1 - c) >> 1);
for (;;)
{
@@ -1791,11 +1785,11 @@ ATTRIBUTE_CONST
static uintmax_t
isqrt2 (uintmax_t nh, uintmax_t nl)
{
unsigned int shift;
int shift;
uintmax_t x;
/* Ensures the remainder fits in an uintmax_t. */
assert (nh < ((uintmax_t) 1 << (W_TYPE_SIZE - 2)));
affirm (nh < ((uintmax_t) 1 << (W_TYPE_SIZE - 2)));
if (nh == 0)
return isqrt (nl);
@@ -1805,7 +1799,7 @@ isqrt2 (uintmax_t nh, uintmax_t nl)
/* Make x > sqrt (n). */
x = isqrt ((nh << shift) + (nl >> (W_TYPE_SIZE - shift))) + 1;
x <<= (W_TYPE_SIZE - shift) / 2;
x <<= (W_TYPE_SIZE - shift) >> 1;
/* Do we need more than one iteration? */
for (;;)
@@ -1819,12 +1813,12 @@ isqrt2 (uintmax_t nh, uintmax_t nl)
{
uintmax_t hi, lo;
umul_ppmm (hi, lo, x + 1, x + 1);
assert (gt2 (hi, lo, nh, nl));
affirm (gt2 (hi, lo, nh, nl));
umul_ppmm (hi, lo, x, x);
assert (ge2 (nh, nl, hi, lo));
affirm (ge2 (nh, nl, hi, lo));
sub_ddmmss (hi, lo, nh, nl, hi, lo);
assert (hi == 0);
affirm (hi == 0);
return x;
}
@@ -1860,7 +1854,7 @@ is_square (uintmax_t x)
}
/* invtab[i] = floor (0x10000 / (0x100 + i) */
static const unsigned short invtab[0x81] =
static short const invtab[0x81] =
{
0x200,
0x1fc, 0x1f8, 0x1f4, 0x1f0, 0x1ec, 0x1e9, 0x1e5, 0x1e1,
@@ -1882,7 +1876,7 @@ static const unsigned short invtab[0x81] =
};
/* Compute q = [u/d], r = u mod d. Avoids slow hardware division for the case
that q < 0x40; here it instead uses a table of (Euclidian) inverses. */
that q < 0x40; here it instead uses a table of (Euclidean) inverses. */
# define div_smallq(q, r, u, d) \
do { \
if ((u) / 0x40 < (d)) \
@@ -1906,7 +1900,7 @@ static const unsigned short invtab[0x81] =
_mask = -(uintmax_t) (_r >= (d)); \
(r) = _r - (_mask & (d)); \
(q) = _q - _mask; \
assert ((q) * (d) + (r) == u); \
affirm ((q) * (d) + (r) == u); \
} \
else \
{ \
@@ -1957,7 +1951,7 @@ static const unsigned short invtab[0x81] =
#if STAT_SQUFOF
# define Q_FREQ_SIZE 50
/* Element 0 keeps the total */
static unsigned int q_freq[Q_FREQ_SIZE + 1];
static int q_freq[Q_FREQ_SIZE + 1];
#endif
#if USE_SQUFOF
@@ -1974,17 +1968,15 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
https://homes.cerias.purdue.edu/~ssw/squfof.pdf
*/
static const unsigned int multipliers_1[] =
static short const multipliers_1[] =
{ /* = 1 (mod 4) */
105, 165, 21, 385, 33, 5, 77, 1, 0
};
static const unsigned int multipliers_3[] =
static short const multipliers_3[] =
{ /* = 3 (mod 4) */
1155, 15, 231, 35, 3, 55, 7, 11, 0
};
const unsigned int *m;
struct { uintmax_t Q; uintmax_t P; } queue[QUEUE_SIZE];
if (n1 >= ((uintmax_t) 1 << (W_TYPE_SIZE - 2)))
@@ -1997,7 +1989,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
uintmax_t p1, p0;
umul_ppmm (p1, p0, sqrt_n, sqrt_n);
assert (p0 == n0);
affirm (p0 == n0);
if (n1 == p1)
{
@@ -2022,15 +2014,15 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
}
/* Select multipliers so we always get n * mu = 3 (mod 4) */
for (m = (n0 % 4 == 1) ? multipliers_3 : multipliers_1;
for (short const *m = (n0 % 4 == 1) ? multipliers_3 : multipliers_1;
*m; m++)
{
uintmax_t S, Dh, Dl, Q1, Q, P, L, L1, B;
unsigned int i;
unsigned int mu = *m;
unsigned int qpos = 0;
int qpos = 0;
assert (mu * n0 % 4 == 3);
affirm (mu * n0 % 4 == 3);
/* In the notation of the paper, with mu * n == 3 (mod 4), we
get \Delta = 4 mu * n, and the paper's \mu is 2 mu. As far as
@@ -2055,8 +2047,8 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
umul_ppmm (Dh, Dl, n0, mu);
Dh += n1 * mu;
assert (Dl % 4 != 1);
assert (Dh < (uintmax_t) 1 << (W_TYPE_SIZE - 2));
affirm (Dl % 4 != 1);
affirm (Dh < (uintmax_t) 1 << (W_TYPE_SIZE - 2));
S = isqrt2 (Dh, Dl);
@@ -2080,7 +2072,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
div_smallq (q, rem, S + P, Q);
P1 = S - rem; /* P1 = q*Q - P */
assert (q > 0 && Q > 0);
affirm (q > 0 && Q > 0);
# if STAT_SQUFOF
q_freq[0]++;
@@ -2099,7 +2091,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
if (g <= L)
{
if (qpos >= QUEUE_SIZE)
die (EXIT_FAILURE, 0, _("squfof queue overflow"));
error (EXIT_FAILURE, 0, _("squfof queue overflow"));
queue[qpos].Q = g;
queue[qpos].P = P % g;
qpos++;
@@ -2118,7 +2110,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
uintmax_t r = is_square (Q);
if (r)
{
for (unsigned int j = 0; j < qpos; j++)
for (int j = 0; j < qpos; j++)
{
if (queue[j].Q == r)
{
@@ -2146,7 +2138,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
/* We have found a square form, which should give a
factor. */
Q1 = r;
assert (S >= P); /* What signs are possible? */
affirm (S >= P); /* What signs are possible? */
P += r * ((S - P) / r);
/* Note: Paper says (N - P*P) / Q1, that seems incorrect
@@ -2157,7 +2149,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
umul_ppmm (hi, lo, P, P);
sub_ddmmss (hi, lo, Dh, Dl, hi, lo);
udiv_qrnnd (Q, rem, hi, lo, Q1);
assert (rem == 0);
affirm (rem == 0);
for (;;)
{
@@ -2185,7 +2177,7 @@ factor_using_squfof (uintmax_t n1, uintmax_t n0, struct factors *factors)
Q /= 2;
Q /= gcd_odd (Q, mu);
assert (Q > 1 && (n1 || Q < n0));
affirm (Q > 1 && (n1 || Q < n0));
if (prime_p (Q))
factor_insert (factors, Q);
@@ -2275,7 +2267,7 @@ mp_factor (mpz_t t, struct mp_factors *factors)
static strtol_error
strto2uintmax (uintmax_t *hip, uintmax_t *lop, char const *s)
{
unsigned int lo_carry;
int lo_carry;
uintmax_t hi = 0, lo = 0;
strtol_error err = LONGINT_INVALID;
@@ -2284,7 +2276,7 @@ strto2uintmax (uintmax_t *hip, uintmax_t *lop, char const *s)
char const *p = s;
for (;;)
{
unsigned int c = *p++;
unsigned char c = *p++;
if (c == 0)
break;
@@ -2299,7 +2291,7 @@ strto2uintmax (uintmax_t *hip, uintmax_t *lop, char const *s)
while (err == LONGINT_OK)
{
unsigned int c = *s++;
unsigned char c = *s++;
if (c == 0)
break;
@@ -2366,7 +2358,7 @@ lbuf_flush (void)
{
size_t size = lbuf.end - lbuf.buf;
if (full_write (STDOUT_FILENO, lbuf.buf, size) != size)
die (EXIT_FAILURE, errno, "%s", _("write error"));
write_error ();
lbuf.end = lbuf.buf;
}
@@ -2456,8 +2448,8 @@ print_factors_single (uintmax_t t1, uintmax_t t0)
factor (t1, t0, &factors);
for (unsigned int j = 0; j < factors.nfactors; j++)
for (unsigned int k = 0; k < factors.e[j]; k++)
for (int j = 0; j < factors.nfactors; j++)
for (int k = 0; k < factors.e[j]; k++)
{
lbuf_putc (' ');
print_uintmaxes (0, factors.p[j]);
@@ -2530,8 +2522,8 @@ print_factors (char const *input)
putchar (':');
mp_factor (t, &factors);
for (unsigned int j = 0; j < factors.nfactors; j++)
for (unsigned int k = 0; k < factors.e[j]; k++)
for (idx_t j = 0; j < factors.nfactors; j++)
for (unsigned long int k = 0; k < factors.e[j]; k++)
{
putchar (' ');
mpz_out_str (stdout, 10, factors.p[j]);
@@ -2588,7 +2580,12 @@ do_stdin (void)
size_t token_length = readtoken (stdin, DELIM, sizeof (DELIM) - 1,
&tokenbuffer);
if (token_length == (size_t) -1)
break;
{
if (ferror (stdin))
error (EXIT_FAILURE, errno, _("error reading input"));
break;
}
ok &= print_factors (tokenbuffer.buffer);
}
free (tokenbuffer.buffer);
@@ -2610,7 +2607,7 @@ main (int argc, char **argv)
atexit (lbuf_flush);
int c;
while ((c = getopt_long (argc, argv, "h", long_options, NULL)) != -1)
while ((c = getopt_long (argc, argv, "h", long_options, nullptr)) != -1)
{
switch (c)
{
@@ -2651,7 +2648,7 @@ main (int argc, char **argv)
{
double acc_f;
printf ("q freq. cum. freq.(total: %d)\n", q_freq[0]);
for (unsigned int i = 1, acc_f = 0.0; i <= Q_FREQ_SIZE; i++)
for (int i = 1, acc_f = 0.0; i <= Q_FREQ_SIZE; i++)
{
double f = (double) q_freq[i] / q_freq[0];
acc_f += f;

View File

@@ -18,27 +18,25 @@
#include <sys/types.h>
#include "system.h"
#include "die.h"
#include "error.h"
#include "save-cwd.h"
#include "xgetcwd.h"
#include "find-mount-point.h"
/* Return the root mountpoint of the file system on which FILE exists, in
malloced storage. FILE_STAT should be the result of stating FILE.
Give a diagnostic and return NULL if unable to determine the mount point.
Give a diagnostic and return nullptr if unable to determine the mount point.
Exit if unable to restore current working directory. */
extern char *
find_mount_point (char const *file, struct stat const *file_stat)
{
struct saved_cwd cwd;
struct stat last_stat;
char *mp = NULL; /* The malloc'd mount point. */
char *mp = nullptr; /* The malloc'd mount point. */
if (save_cwd (&cwd) != 0)
{
error (0, errno, _("cannot get current directory"));
return NULL;
return nullptr;
}
if (S_ISDIR (file_stat->st_mode))
@@ -48,7 +46,7 @@ find_mount_point (char const *file, struct stat const *file_stat)
if (chdir (file) < 0)
{
error (0, errno, _("cannot change to directory %s"), quoteaf (file));
return NULL;
return nullptr;
}
}
else
@@ -62,7 +60,7 @@ find_mount_point (char const *file, struct stat const *file_stat)
if (chdir (dir) < 0)
{
error (0, errno, _("cannot change to directory %s"), quoteaf (dir));
return NULL;
return nullptr;
}
if (stat (".", &last_stat) < 0)
@@ -103,8 +101,8 @@ done:
{
int save_errno = errno;
if (restore_cwd (&cwd) != 0)
die (EXIT_FAILURE, errno,
_("failed to return to initial working directory"));
error (EXIT_FAILURE, errno,
_("failed to return to initial working directory"));
free_cwd (&cwd);
errno = save_errno;
}

View File

@@ -20,7 +20,6 @@
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include <assert.h>
/* Redefine. Otherwise, systems (Unicos for one) with headers that define
it to be a type get syntax errors for the variable declaration below. */
@@ -28,8 +27,6 @@
#include "c-ctype.h"
#include "system.h"
#include "error.h"
#include "die.h"
#include "fadvise.h"
#include "xdectoint.h"
@@ -118,9 +115,9 @@ typedef long int COST;
/* Extra ctype(3)-style macros. */
#define isopen(c) (strchr ("(['`\"", c) != NULL)
#define isclose(c) (strchr (")]'\"", c) != NULL)
#define isperiod(c) (strchr (".?!", c) != NULL)
#define isopen(c) (strchr ("(['`\"", c) != nullptr)
#define isclose(c) (strchr (")]'\"", c) != nullptr)
#define isperiod(c) (strchr (".?!", c) != nullptr)
/* Size of a tab stop, for expansion on input and re-introduction on
output. */
@@ -303,16 +300,16 @@ The option -WIDTH is an abbreviated form of --width=DIGITS.\n\
static struct option const long_options[] =
{
{"crown-margin", no_argument, NULL, 'c'},
{"prefix", required_argument, NULL, 'p'},
{"split-only", no_argument, NULL, 's'},
{"tagged-paragraph", no_argument, NULL, 't'},
{"uniform-spacing", no_argument, NULL, 'u'},
{"width", required_argument, NULL, 'w'},
{"goal", required_argument, NULL, 'g'},
{"crown-margin", no_argument, nullptr, 'c'},
{"prefix", required_argument, nullptr, 'p'},
{"split-only", no_argument, nullptr, 's'},
{"tagged-paragraph", no_argument, nullptr, 't'},
{"uniform-spacing", no_argument, nullptr, 'u'},
{"width", required_argument, nullptr, 'w'},
{"goal", required_argument, nullptr, 'g'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0},
{nullptr, 0, nullptr, 0},
};
int
@@ -320,8 +317,8 @@ main (int argc, char **argv)
{
int optchar;
bool ok = true;
char const *max_width_option = NULL;
char const *goal_width_option = NULL;
char const *max_width_option = nullptr;
char const *goal_width_option = nullptr;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -348,7 +345,7 @@ main (int argc, char **argv)
}
while ((optchar = getopt_long (argc, argv, "0123456789cstuw:p:g:",
long_options, NULL))
long_options, nullptr))
!= -1)
switch (optchar)
{
@@ -406,7 +403,7 @@ main (int argc, char **argv)
/* Limit goal_width to max_width. */
goal_width = xdectoumax (goal_width_option, 0, max_width, "",
_("invalid width"), 0);
if (max_width_option == NULL)
if (max_width_option == nullptr)
max_width = goal_width + 10;
}
else
@@ -435,7 +432,7 @@ main (int argc, char **argv)
{
FILE *in_stream;
in_stream = fopen (file, "r");
if (in_stream != NULL)
if (in_stream != nullptr)
ok &= fmt (in_stream, file);
else
{
@@ -448,7 +445,7 @@ main (int argc, char **argv)
}
if (have_read_stdin && fclose (stdin) != 0)
die (EXIT_FAILURE, errno, "%s", _("closing standard input"));
error (EXIT_FAILURE, errno, "%s", _("closing standard input"));
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
@@ -619,10 +616,6 @@ get_paragraph (FILE *f)
c = get_line (f, c);
}
/* Tell static analysis tools that using word_limit[-1] is ok.
word_limit is guaranteed to have been incremented by get_line. */
assert (word < word_limit);
(word_limit - 1)->period = (word_limit - 1)->final = true;
next_char = c;
return true;
@@ -915,6 +908,11 @@ fmt_paragraph (void)
word_limit->length = saved_length;
}
/* Work around <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109628>. */
#if 13 <= __GNUC__
# pragma GCC diagnostic ignored "-Wanalyzer-use-of-uninitialized-value"
#endif
/* Return the constant component of the cost of breaking before the
word THIS. */

View File

@@ -23,8 +23,6 @@
#include <sys/types.h>
#include "system.h"
#include "die.h"
#include "error.h"
#include "fadvise.h"
#include "xdectoint.h"
@@ -48,12 +46,12 @@ static char const shortopts[] = "bsw:0::1::2::3::4::5::6::7::8::9::";
static struct option const longopts[] =
{
{"bytes", no_argument, NULL, 'b'},
{"spaces", no_argument, NULL, 's'},
{"width", required_argument, NULL, 'w'},
{"bytes", no_argument, nullptr, 'b'},
{"spaces", no_argument, nullptr, 's'},
{"width", required_argument, nullptr, 'w'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -123,7 +121,7 @@ fold_file (char const *filename, size_t width)
int c;
size_t column = 0; /* Screen column where next char will go. */
size_t offset_out = 0; /* Index in 'line_out' for next char. */
static char *line_out = NULL;
static char *line_out = nullptr;
static size_t allocated_out = 0;
int saved_errno;
@@ -135,7 +133,7 @@ fold_file (char const *filename, size_t width)
else
istream = fopen (filename, "r");
if (istream == NULL)
if (istream == nullptr)
{
error (0, errno, "%s", quotef (filename));
return false;
@@ -254,7 +252,7 @@ main (int argc, char **argv)
break_spaces = count_bytes = have_read_stdin = false;
while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
while ((optc = getopt_long (argc, argv, shortopts, longopts, nullptr)) != -1)
{
char optargbuf[2];
@@ -303,7 +301,7 @@ main (int argc, char **argv)
}
if (have_read_stdin && fclose (stdin) == EOF)
die (EXIT_FAILURE, errno, "-");
error (EXIT_FAILURE, errno, "-");
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -44,7 +44,7 @@ enum { x_suffix_len = sizeof "XXXXXX" - 1 };
enum { smallsize = 256 };
/* Return a template for a file in the same directory as DSTNAME.
Use BUF if the template fits, otherwise use malloc and return NULL
Use BUF if the template fits, otherwise use malloc and return nullptr
(setting errno) if unsuccessful. */
static char *

View File

@@ -27,7 +27,7 @@
#define PROGRAM_NAME "getlimits"
#define AUTHORS proper_name ("Padraig Brady")
#define AUTHORS proper_name_lite ("Padraig Brady", "P\303\241draig Brady")
#ifndef TIME_T_MAX
# define TIME_T_MAX TYPE_MAXIMUM (time_t)
@@ -126,7 +126,8 @@ main (int argc, char **argv)
atexit (close_stdout);
parse_gnu_standard_options_only (argc, argv, PROGRAM_NAME, PACKAGE_NAME,
VERSION, true, usage, AUTHORS, NULL);
VERSION, true, usage, AUTHORS,
(char const *) nullptr);
#define print_int(TYPE) \
sprintf (limit + 1, "%"PRIuMAX, (uintmax_t) TYPE##_MAX); \

View File

@@ -25,7 +25,6 @@
#include <grp.h>
#include "system.h"
#include "error.h"
#include "mgetgroups.h"
#include "quote.h"
#include "group-list.h"
@@ -38,12 +37,12 @@ print_group_list (char const *username,
bool use_names, char delim)
{
bool ok = true;
struct passwd *pwd = NULL;
struct passwd *pwd = nullptr;
if (username)
{
pwd = getpwuid (ruid);
if (pwd == NULL)
if (pwd == nullptr)
ok = false;
}
@@ -102,16 +101,24 @@ gidtostr_ptr (gid_t const *gid)
extern bool
print_group (gid_t gid, bool use_name)
{
struct group *grp = NULL;
struct group *grp = nullptr;
bool ok = true;
if (use_name)
{
grp = getgrgid (gid);
if (grp == NULL)
if (grp == nullptr)
{
error (0, 0, _("cannot find name for group ID %lu"),
(unsigned long int) gid);
if (TYPE_SIGNED (gid_t))
{
intmax_t g = gid;
error (0, 0, _("cannot find name for group ID %"PRIdMAX), g);
}
else
{
uintmax_t g = gid;
error (0, 0, _("cannot find name for group ID %"PRIuMAX), g);
}
ok = false;
}
}

View File

@@ -25,7 +25,6 @@
#include <getopt.h>
#include "system.h"
#include "die.h"
#include "group-list.h"
#include "quote.h"
@@ -41,7 +40,7 @@ static struct option const longopts[] =
{
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -83,7 +82,7 @@ main (int argc, char **argv)
/* Processing the arguments this way makes groups.c behave differently to
* groups.sh if one of the arguments is "--".
*/
while ((optc = getopt_long (argc, argv, "", longopts, NULL)) != -1)
while ((optc = getopt_long (argc, argv, "", longopts, nullptr)) != -1)
{
switch (optc)
{
@@ -103,19 +102,19 @@ main (int argc, char **argv)
errno = 0;
ruid = getuid ();
if (ruid == NO_UID && errno)
die (EXIT_FAILURE, errno, _("cannot get real UID"));
error (EXIT_FAILURE, errno, _("cannot get real UID"));
errno = 0;
egid = getegid ();
if (egid == NO_GID && errno)
die (EXIT_FAILURE, errno, _("cannot get effective GID"));
error (EXIT_FAILURE, errno, _("cannot get effective GID"));
errno = 0;
rgid = getgid ();
if (rgid == NO_GID && errno)
die (EXIT_FAILURE, errno, _("cannot get real GID"));
error (EXIT_FAILURE, errno, _("cannot get real GID"));
if (!print_group_list (NULL, ruid, rgid, egid, true, ' '))
if (!print_group_list (nullptr, ruid, rgid, egid, true, ' '))
ok = false;
putchar ('\n');
}
@@ -125,7 +124,7 @@ main (int argc, char **argv)
for ( ; optind < argc; optind++)
{
struct passwd *pwd = getpwnam (argv[optind]);
if (pwd == NULL)
if (pwd == nullptr)
{
error (0, 0, _("%s: no such user"), quote (argv[optind]));
ok = false;

View File

@@ -31,8 +31,7 @@
#include "system.h"
#include "die.h"
#include "error.h"
#include "assure.h"
#include "full-read.h"
#include "quote.h"
#include "safe-read.h"
@@ -87,17 +86,17 @@ enum
static struct option const long_options[] =
{
{"bytes", required_argument, NULL, 'c'},
{"lines", required_argument, NULL, 'n'},
{"-presume-input-pipe", no_argument, NULL,
{"bytes", required_argument, nullptr, 'c'},
{"lines", required_argument, nullptr, 'n'},
{"-presume-input-pipe", no_argument, nullptr,
PRESUME_INPUT_PIPE_OPTION}, /* do not document */
{"quiet", no_argument, NULL, 'q'},
{"silent", no_argument, NULL, 'q'},
{"verbose", no_argument, NULL, 'v'},
{"zero-terminated", no_argument, NULL, 'z'},
{"quiet", no_argument, nullptr, 'q'},
{"silent", no_argument, nullptr, 'q'},
{"verbose", no_argument, nullptr, 'v'},
{"zero-terminated", no_argument, nullptr, 'z'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -160,7 +159,7 @@ diagnose_copy_fd_failure (enum Copy_fd_status err, char const *filename)
error (0, errno, _("%s: file has shrunk too much"), quotef (filename));
break;
default:
abort ();
affirm (false);
}
}
@@ -182,8 +181,9 @@ xwrite_stdout (char const *buffer, size_t n_bytes)
if (n_bytes > 0 && fwrite (buffer, 1, n_bytes, stdout) < n_bytes)
{
clearerr (stdout); /* To avoid redundant close_stdout diagnostic. */
die (EXIT_FAILURE, errno, _("error writing %s"),
quoteaf ("standard output"));
fpurge (stdout);
error (EXIT_FAILURE, errno, _("error writing %s"),
quoteaf ("standard output"));
}
}
@@ -272,8 +272,8 @@ elide_tail_bytes_pipe (char const *filename, int fd, uintmax_t n_elide_0,
if (SIZE_MAX < n_elide_0 + READ_BUFSIZE)
{
char umax_buf[INT_BUFSIZE_BOUND (n_elide_0)];
die (EXIT_FAILURE, 0, _("%s: number of bytes is too large"),
umaxtostr (n_elide_0, umax_buf));
error (EXIT_FAILURE, 0, _("%s: number of bytes is too large"),
umaxtostr (n_elide_0, umax_buf));
}
/* Two cases to consider...
@@ -354,7 +354,7 @@ elide_tail_bytes_pipe (char const *filename, int fd, uintmax_t n_elide_0,
size_t n_read;
bool buffered_enough;
size_t i, i_next;
char **b = NULL;
char **b = nullptr;
/* Round n_elide up to a multiple of READ_BUFSIZE. */
size_t rem = READ_BUFSIZE - (n_elide % READ_BUFSIZE);
size_t n_elide_round = n_elide + rem;
@@ -514,7 +514,7 @@ elide_tail_lines_pipe (char const *filename, int fd, uintmax_t n_elide,
first = last = xmalloc (sizeof (LBUFFER));
first->nbytes = first->nlines = 0;
first->next = NULL;
first->next = nullptr;
tmp = xmalloc (sizeof (LBUFFER));
/* Always read into a fresh buffer.
@@ -535,7 +535,7 @@ elide_tail_lines_pipe (char const *filename, int fd, uintmax_t n_elide,
tmp->nbytes = n_read;
tmp->nlines = 0;
tmp->next = NULL;
tmp->next = nullptr;
/* Count the number of newlines just read. */
{
@@ -690,7 +690,7 @@ elide_tail_lines_seekable (char const *pretty_filename, int fd,
{
char const *nl;
nl = memrchr (buffer, line_end, n);
if (nl == NULL)
if (nl == nullptr)
break;
n = nl - buffer;
}
@@ -936,7 +936,7 @@ main (int argc, char **argv)
/* Initializer for file_list if no file-arguments
were specified on the command line. */
static char const *const default_file_list[] = {"-", NULL};
static char const *const default_file_list[] = {"-", nullptr};
char const *const *file_list;
initialize_main (&argc, &argv);
@@ -1021,7 +1021,8 @@ main (int argc, char **argv)
argc--;
}
while ((c = getopt_long (argc, argv, "c:n:qvz0123456789", long_options, NULL))
while ((c = getopt_long (argc, argv, "c:n:qvz0123456789",
long_options, nullptr))
!= -1)
{
switch (c)
@@ -1076,8 +1077,8 @@ main (int argc, char **argv)
if ( ! count_lines && elide_from_end && OFF_T_MAX < n_units)
{
char umax_buf[INT_BUFSIZE_BOUND (n_units)];
die (EXIT_FAILURE, EOVERFLOW, "%s: %s", _("invalid number of bytes"),
quote (umaxtostr (n_units, umax_buf)));
error (EXIT_FAILURE, EOVERFLOW, "%s: %s", _("invalid number of bytes"),
quote (umaxtostr (n_units, umax_buf)));
}
file_list = (optind < argc
@@ -1090,7 +1091,7 @@ main (int argc, char **argv)
ok &= head_file (file_list[i], n_units, count_lines, elide_from_end);
if (have_read_stdin && close (STDIN_FILENO) < 0)
die (EXIT_FAILURE, errno, "-");
error (EXIT_FAILURE, errno, "-");
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -23,7 +23,6 @@
#include "system.h"
#include "long-options.h"
#include "error.h"
#include "quote.h"
/* The official name of this program (e.g., no 'g' prefix). */
@@ -65,7 +64,7 @@ main (int argc, char **argv)
parse_gnu_standard_options_only (argc, argv, PROGRAM_NAME, PACKAGE_NAME,
Version, true, usage, AUTHORS,
(char const *) NULL);
(char const *) nullptr);
if (optind < argc)
{

View File

@@ -22,8 +22,6 @@
#include "system.h"
#include "long-options.h"
#include "die.h"
#include "error.h"
#include "quote.h"
#include "xgethostname.h"
@@ -86,7 +84,7 @@ main (int argc, char **argv)
parse_gnu_standard_options_only (argc, argv, PROGRAM_NAME, PACKAGE_NAME,
Version, true, usage, AUTHORS,
(char const *) NULL);
(char const *) nullptr);
if (optind + 1 < argc)
{
@@ -99,14 +97,14 @@ main (int argc, char **argv)
/* Set hostname to operand. */
char const *name = argv[optind];
if (sethostname (name, strlen (name)) != 0)
die (EXIT_FAILURE, errno, _("cannot set name to %s"),
quote (name));
error (EXIT_FAILURE, errno, _("cannot set name to %s"),
quote (name));
}
else
{
hostname = xgethostname ();
if (hostname == NULL)
die (EXIT_FAILURE, errno, _("cannot determine hostname"));
if (hostname == nullptr)
error (EXIT_FAILURE, errno, _("cannot determine hostname"));
puts (hostname);
}

View File

@@ -26,8 +26,6 @@
#include <selinux/selinux.h>
#include "system.h"
#include "die.h"
#include "error.h"
#include "mgetgroups.h"
#include "quote.h"
#include "group-list.h"
@@ -66,7 +64,7 @@ static gid_t rgid, egid;
/* The SELinux context. Start with a known invalid value so print_full_info
knows when 'context' has not been set to a meaningful value. */
static char *context = NULL;
static char *context = nullptr;
static void print_user (uid_t uid);
static void print_full_info (char const *username);
@@ -74,16 +72,16 @@ static void print_stuff (char const *pw_name);
static struct option const longopts[] =
{
{"context", no_argument, NULL, 'Z'},
{"group", no_argument, NULL, 'g'},
{"groups", no_argument, NULL, 'G'},
{"name", no_argument, NULL, 'n'},
{"real", no_argument, NULL, 'r'},
{"user", no_argument, NULL, 'u'},
{"zero", no_argument, NULL, 'z'},
{"context", no_argument, nullptr, 'Z'},
{"group", no_argument, nullptr, 'g'},
{"groups", no_argument, nullptr, 'G'},
{"name", no_argument, nullptr, 'n'},
{"real", no_argument, nullptr, 'r'},
{"user", no_argument, nullptr, 'u'},
{"zero", no_argument, nullptr, 'z'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -136,7 +134,7 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, "agnruzGZ", longopts, NULL)) != -1)
while ((optc = getopt_long (argc, argv, "agnruzGZ", longopts, nullptr)) != -1)
{
switch (optc)
{
@@ -148,13 +146,13 @@ main (int argc, char **argv)
/* politely decline if we're not on a SELinux/SMACK-enabled kernel. */
#ifdef HAVE_SMACK
if (!selinux_enabled && !smack_enabled)
die (EXIT_FAILURE, 0,
_("--context (-Z) works only on "
"an SELinux/SMACK-enabled kernel"));
error (EXIT_FAILURE, 0,
_("--context (-Z) works only on "
"an SELinux/SMACK-enabled kernel"));
#else
if (!selinux_enabled)
die (EXIT_FAILURE, 0,
_("--context (-Z) works only on an SELinux-enabled kernel"));
error (EXIT_FAILURE, 0,
_("--context (-Z) works only on an SELinux-enabled kernel"));
#endif
just_context = true;
break;
@@ -187,11 +185,11 @@ main (int argc, char **argv)
size_t n_ids = argc - optind;
if (n_ids && just_context)
die (EXIT_FAILURE, 0,
_("cannot print security context when user specified"));
error (EXIT_FAILURE, 0,
_("cannot print security context when user specified"));
if (just_user + just_group + just_group_list + just_context > 1)
die (EXIT_FAILURE, 0, _("cannot print \"only\" of more than one choice"));
error (EXIT_FAILURE, 0, _("cannot print \"only\" of more than one choice"));
bool default_format = ! (just_user
|| just_group
@@ -199,12 +197,12 @@ main (int argc, char **argv)
|| just_context);
if (default_format && (use_real || use_name))
die (EXIT_FAILURE, 0,
_("cannot print only names or real IDs in default format"));
error (EXIT_FAILURE, 0,
_("cannot print only names or real IDs in default format"));
if (default_format && opt_zero)
die (EXIT_FAILURE, 0,
_("option --zero not permitted in default format"));
error (EXIT_FAILURE, 0,
_("option --zero not permitted in default format"));
/* If we are on a SELinux/SMACK-enabled kernel, no user is specified, and
either --context is specified or none of (-u,-g,-G) is specified,
@@ -220,7 +218,7 @@ main (int argc, char **argv)
|| (smack_enabled
&& smack_new_label_from_self (&context) < 0
&& just_context))
die (EXIT_FAILURE, 0, _("can't get process context"));
error (EXIT_FAILURE, 0, _("can't get process context"));
}
if (n_ids >= 1)
@@ -234,18 +232,18 @@ main (int argc, char **argv)
/* For each username/userid to get its pw_name field */
for (; optind < n_ids; optind++)
{
char *pw_name = NULL;
struct passwd *pwd = NULL;
char *pw_name = nullptr;
struct passwd *pwd = nullptr;
char const *spec = argv[optind];
/* Disallow an empty spec here as parse_user_spec() doesn't
give an error for that as it seems it's a valid way to
specify a noop or "reset special bits" depending on the system. */
if (*spec)
{
if (parse_user_spec (spec, &euid, NULL, &pw_name, NULL) == NULL)
if (! parse_user_spec (spec, &euid, nullptr, &pw_name, nullptr))
pwd = pw_name ? getpwnam (pw_name) : getpwuid (euid);
}
if (pwd == NULL)
if (pwd == nullptr)
{
error (0, errno, _("%s: no such user"), quote (spec));
ok &= false;
@@ -275,7 +273,7 @@ main (int argc, char **argv)
errno = 0;
euid = geteuid ();
if (euid == NO_UID && errno)
die (EXIT_FAILURE, errno, _("cannot get effective UID"));
error (EXIT_FAILURE, errno, _("cannot get effective UID"));
}
if (just_user ? use_real
@@ -284,7 +282,7 @@ main (int argc, char **argv)
errno = 0;
ruid = getuid ();
if (ruid == NO_UID && errno)
die (EXIT_FAILURE, errno, _("cannot get real UID"));
error (EXIT_FAILURE, errno, _("cannot get real UID"));
}
if (!just_user && (just_group || just_group_list || !just_context))
@@ -292,14 +290,14 @@ main (int argc, char **argv)
errno = 0;
egid = getegid ();
if (egid == NO_GID && errno)
die (EXIT_FAILURE, errno, _("cannot get effective GID"));
error (EXIT_FAILURE, errno, _("cannot get effective GID"));
errno = 0;
rgid = getgid ();
if (rgid == NO_GID && errno)
die (EXIT_FAILURE, errno, _("cannot get real GID"));
error (EXIT_FAILURE, errno, _("cannot get real GID"));
}
print_stuff (NULL);
print_stuff (nullptr);
}
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
@@ -332,12 +330,12 @@ uidtostr_ptr (uid_t const *uid)
static void
print_user (uid_t uid)
{
struct passwd *pwd = NULL;
struct passwd *pwd = nullptr;
if (use_name)
{
pwd = getpwuid (uid);
if (pwd == NULL)
if (pwd == nullptr)
{
error (0, 0, _("cannot find name for user ID %s"),
uidtostr (uid));

View File

@@ -28,10 +28,8 @@
#include "system.h"
#include "backupfile.h"
#include "error.h"
#include "cp-hash.h"
#include "copy.h"
#include "die.h"
#include "filenamecat.h"
#include "full-read.h"
#include "mkancesdirs.h"
@@ -62,14 +60,14 @@ static bool use_default_selinux_context = true;
# define endpwent() ((void) 0)
#endif
/* The user name that will own the files, or NULL to make the owner
/* The user name that will own the files, or nullptr to make the owner
the current user ID. */
static char *owner_name;
/* The user ID corresponding to 'owner_name'. */
static uid_t owner_id;
/* The group name that will own the files, or NULL to make the group
/* The group name that will own the files, or nullptr to make the group
the current group ID. */
static char *group_name;
@@ -114,25 +112,25 @@ enum
static struct option const long_options[] =
{
{"backup", optional_argument, NULL, 'b'},
{"compare", no_argument, NULL, 'C'},
{"backup", optional_argument, nullptr, 'b'},
{"compare", no_argument, nullptr, 'C'},
{GETOPT_SELINUX_CONTEXT_OPTION_DECL},
{"debug", no_argument, NULL, DEBUG_OPTION},
{"directory", no_argument, NULL, 'd'},
{"group", required_argument, NULL, 'g'},
{"mode", required_argument, NULL, 'm'},
{"no-target-directory", no_argument, NULL, 'T'},
{"owner", required_argument, NULL, 'o'},
{"preserve-timestamps", no_argument, NULL, 'p'},
{"preserve-context", no_argument, NULL, PRESERVE_CONTEXT_OPTION},
{"strip", no_argument, NULL, 's'},
{"strip-program", required_argument, NULL, STRIP_PROGRAM_OPTION},
{"suffix", required_argument, NULL, 'S'},
{"target-directory", required_argument, NULL, 't'},
{"verbose", no_argument, NULL, 'v'},
{"debug", no_argument, nullptr, DEBUG_OPTION},
{"directory", no_argument, nullptr, 'd'},
{"group", required_argument, nullptr, 'g'},
{"mode", required_argument, nullptr, 'm'},
{"no-target-directory", no_argument, nullptr, 'T'},
{"owner", required_argument, nullptr, 'o'},
{"preserve-timestamps", no_argument, nullptr, 'p'},
{"preserve-context", no_argument, nullptr, PRESERVE_CONTEXT_OPTION},
{"strip", no_argument, nullptr, 's'},
{"strip-program", required_argument, nullptr, STRIP_PROGRAM_OPTION},
{"suffix", required_argument, nullptr, 'S'},
{"target-directory", required_argument, nullptr, 't'},
{"verbose", no_argument, nullptr, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* Compare content of opened files using file descriptors A_FD and B_FD. Return
@@ -216,8 +214,8 @@ need_copy (char const *src_name, char const *dest_name,
/* compare SELinux context if preserving */
if (selinux_enabled && x->preserve_security_context)
{
char *file_scontext = NULL;
char *to_scontext = NULL;
char *file_scontext = nullptr;
char *to_scontext = nullptr;
bool scontext_match;
if (getfilecon (src_name, &file_scontext) == -1)
@@ -295,11 +293,11 @@ cp_option_init (struct cp_options *x)
x->update = false;
x->require_preserve_context = false; /* Not used by install currently. */
x->preserve_security_context = false; /* Whether to copy context from src. */
x->set_security_context = NULL; /* Whether to set sys default context. */
x->set_security_context = nullptr; /* Whether to set sys default context. */
x->preserve_xattr = false;
x->verbose = false;
x->dest_info = NULL;
x->src_info = NULL;
x->dest_info = nullptr;
x->src_info = nullptr;
}
static struct selabel_handle *
@@ -310,7 +308,7 @@ get_labeling_handle (void)
if (!initialized)
{
initialized = true;
hnd = selabel_open (SELABEL_CTX_FILE, NULL, 0);
hnd = selabel_open (SELABEL_CTX_FILE, nullptr, 0);
if (!hnd)
error (0, errno, _("warning: security labeling handle failed"));
}
@@ -325,7 +323,7 @@ static void
setdefaultfilecon (char const *file)
{
struct stat st;
char *scontext = NULL;
char *scontext = nullptr;
if (selinux_enabled != 1)
{
@@ -428,7 +426,7 @@ copy_file (char const *from, char const *to,
However, since !x->recursive, the call to "copy" will fail if FROM
is a directory. */
return copy (from, to, to_dirfd, to_relname, 0, x, &copy_into_self, NULL);
return copy (from, to, to_dirfd, to_relname, 0, x, &copy_into_self, nullptr);
}
/* Set the attributes of file or directory NAME aka DIRFD+RELNAME.
@@ -502,8 +500,14 @@ strip (char const *name)
error (0, errno, _("fork system call failed"));
break;
case 0: /* Child. */
execlp (strip_program, strip_program, name, NULL);
die (EXIT_FAILURE, errno, _("cannot run %s"), quoteaf (strip_program));
{
char const *safe_name = name;
if (name && *name == '-')
safe_name = file_name_concat (".", name, nullptr);
execlp (strip_program, strip_program, safe_name, nullptr);
error (EXIT_FAILURE, errno, _("cannot run %s"),
quoteaf (strip_program));
}
default: /* Parent. */
if (waitpid (pid, &status, 0) < 0)
error (0, errno, _("waiting for strip"));
@@ -527,13 +531,13 @@ get_ids (void)
if (owner_name)
{
pw = getpwnam (owner_name);
if (pw == NULL)
if (pw == nullptr)
{
uintmax_t tmp;
if (xstrtoumax (owner_name, NULL, 0, &tmp, "") != LONGINT_OK
if (xstrtoumax (owner_name, nullptr, 0, &tmp, "") != LONGINT_OK
|| UID_T_MAX < tmp)
die (EXIT_FAILURE, 0, _("invalid user %s"),
quote (owner_name));
error (EXIT_FAILURE, 0, _("invalid user %s"),
quoteaf (owner_name));
owner_id = tmp;
}
else
@@ -546,13 +550,13 @@ get_ids (void)
if (group_name)
{
gr = getgrnam (group_name);
if (gr == NULL)
if (gr == nullptr)
{
uintmax_t tmp;
if (xstrtoumax (group_name, NULL, 0, &tmp, "") != LONGINT_OK
if (xstrtoumax (group_name, nullptr, 0, &tmp, "") != LONGINT_OK
|| GID_T_MAX < tmp)
die (EXIT_FAILURE, 0, _("invalid group %s"),
quote (group_name));
error (EXIT_FAILURE, 0, _("invalid group %s"),
quoteaf (group_name));
group_id = tmp;
}
else
@@ -663,7 +667,7 @@ install_file_in_file (char const *from, char const *to,
if (! strip (to))
{
if (unlinkat (to_dirfd, to_relname, 0) != 0) /* Cleanup. */
die (EXIT_FAILURE, errno, _("cannot unlink %s"), quoteaf (to));
error (EXIT_FAILURE, errno, _("cannot unlink %s"), quoteaf (to));
return false;
}
if (x->preserve_timestamps && (strip_files || ! S_ISREG (from_sb.st_mode))
@@ -772,18 +776,18 @@ main (int argc, char **argv)
{
int optc;
int exit_status = EXIT_SUCCESS;
char const *specified_mode = NULL;
char const *specified_mode = nullptr;
bool make_backups = false;
char const *backup_suffix = NULL;
char *version_control_string = NULL;
char const *backup_suffix = nullptr;
char *version_control_string = nullptr;
bool mkdir_and_install = false;
struct cp_options x;
char const *target_directory = NULL;
char const *target_directory = nullptr;
bool no_target_directory = false;
int n_files;
char **file;
bool strip_program_specified = false;
char const *scontext = NULL;
char const *scontext = nullptr;
/* set iff kernel has extra selinux system calls */
selinux_enabled = (0 < is_selinux_enabled ());
@@ -797,14 +801,15 @@ main (int argc, char **argv)
cp_option_init (&x);
owner_name = NULL;
group_name = NULL;
owner_name = nullptr;
group_name = nullptr;
strip_files = false;
dir_arg = false;
umask (0);
while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pt:TvS:Z", long_options,
NULL)) != -1)
nullptr))
!= -1)
{
switch (optc)
{
@@ -859,8 +864,8 @@ main (int argc, char **argv)
break;
case 't':
if (target_directory)
die (EXIT_FAILURE, 0,
_("multiple target directories specified"));
error (EXIT_FAILURE, 0,
_("multiple target directories specified"));
target_directory = optarg;
break;
case 'T':
@@ -909,11 +914,11 @@ main (int argc, char **argv)
/* Check for invalid combinations of arguments. */
if (dir_arg && strip_files)
die (EXIT_FAILURE, 0,
_("the strip option may not be used when installing a directory"));
error (EXIT_FAILURE, 0,
_("the strip option may not be used when installing a directory"));
if (dir_arg && target_directory)
die (EXIT_FAILURE, 0,
_("target directory not allowed when installing a directory"));
error (EXIT_FAILURE, 0,
_("target directory not allowed when installing a directory"));
x.backup_type = (make_backups
? xget_version (_("backup type"),
@@ -922,12 +927,12 @@ main (int argc, char **argv)
set_simple_backup_suffix (backup_suffix);
if (x.preserve_security_context && (x.set_security_context || scontext))
die (EXIT_FAILURE, 0,
_("cannot set target context and preserve it"));
error (EXIT_FAILURE, 0,
_("cannot set target context and preserve it"));
if (scontext && setfscreatecon (scontext) < 0)
die (EXIT_FAILURE, errno,
_("failed to set default file creation context to %s"),
error (EXIT_FAILURE, errno,
_("failed to set default file creation context to %s"),
quote (scontext));
n_files = argc - optind;
@@ -948,9 +953,9 @@ main (int argc, char **argv)
if (no_target_directory)
{
if (target_directory)
die (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"), quoteaf (file[2]));
@@ -962,8 +967,8 @@ main (int argc, char **argv)
target_dirfd = target_directory_operand (target_directory, &sb);
if (! (target_dirfd_valid (target_dirfd)
|| (mkdir_and_install && errno == ENOENT)))
die (EXIT_FAILURE, errno, _("failed to access %s"),
quoteaf (target_directory));
error (EXIT_FAILURE, errno, _("failed to access %s"),
quoteaf (target_directory));
}
else if (!dir_arg)
{
@@ -976,15 +981,15 @@ main (int argc, char **argv)
n_files--;
}
else if (2 < n_files)
die (EXIT_FAILURE, errno, _("target %s"), quoteaf (lastfile));
error (EXIT_FAILURE, errno, _("target %s"), quoteaf (lastfile));
}
if (specified_mode)
{
struct mode_change *change = mode_compile (specified_mode);
if (!change)
die (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
mode = mode_adjust (0, false, 0, change, NULL);
error (EXIT_FAILURE, 0, _("invalid mode %s"), quote (specified_mode));
mode = mode_adjust (0, false, 0, change, nullptr);
dir_mode = mode_adjust (0, true, 0, change, &dir_mode_bits);
free (change);
}

View File

@@ -17,12 +17,11 @@
/* Include this file _after_ system headers if possible. */
/* sys/stat.h and minmax.h will already have been included by system.h. */
#include "idx.h"
#include "count-leading-zeros.h"
#include "stat-size.h"
/* As of May 2014, 128KiB is determined to be the minimium
/* As of May 2014, 128KiB is determined to be the minimum
blksize to best minimize system call overhead.
This can be tested with this script:

View File

@@ -18,8 +18,6 @@
#include <config.h>
#include <assert.h>
/* poll(2) is needed on AIX (where 'select' gives a readable
event immediately) and Solaris (where 'select' never gave
a readable event). Also use poll(2) on systems we know work
@@ -43,6 +41,7 @@
#endif
#include "system.h"
#include "assure.h"
#include "iopoll.h"
#include "isapipe.h"
@@ -55,13 +54,13 @@
to wait for an event, otherwise return the status immediately.
Return 0 if not BLOCKing and there is no event on the requested descriptors.
Return 0 if FDIN can be read() without blocking, or IOPOLL_BROKEN_OUTPUT if
FDOUT becomes a broken pipe. If !BROKEN_OUTPUT return 0 if FDOUT writeable.
FDOUT becomes a broken pipe. If !BROKEN_OUTPUT return 0 if FDOUT writable.
Otherwise return IOPOLL_ERROR if there is a poll() or select() error. */
static int
iopoll_internal (int fdin, int fdout, bool block, bool broken_output)
{
assert (fdin != -1 || fdout != -1);
affirm (fdin != -1 || fdout != -1);
#if IOPOLL_USES_POLL
struct pollfd pfds[2] = { /* POLLRDBAND needed for illumos, macOS. */
@@ -85,7 +84,7 @@ iopoll_internal (int fdin, int fdout, bool block, bool broken_output)
continue;
if (ret == 0 && ! block)
return 0;
assert (0 < ret);
affirm (0 < ret);
if (pfds[0].revents) /* input available or pipe closed indicating EOF; */
return 0; /* should now be able to read() without blocking */
if (pfds[1].revents & check_out_events)
@@ -116,15 +115,15 @@ iopoll_internal (int fdin, int fdout, bool block, bool broken_output)
struct timeval delay = { .tv_sec = 0, .tv_usec = 0 };
ret = select (nfds,
broken_output ? &fds : NULL,
broken_output ? NULL : &fds,
NULL, block ? NULL : &delay);
broken_output ? &fds : nullptr,
broken_output ? nullptr : &fds,
nullptr, block ? nullptr : &delay);
if (ret < 0)
continue;
if (ret == 0 && ! block)
return 0;
assert (0 < ret);
affirm (0 < ret);
if (0 <= fdin && FD_ISSET (fdin, &fds)) /* input available or EOF; */
return 0; /* should now be able to read() without blocking */
if (0 <= fdout && FD_ISSET (fdout, &fds)) /* equiv to POLLERR */
@@ -228,7 +227,7 @@ fwrite_wait (char const *buf, ssize_t size, FILE *f)
{
const size_t written = fwrite (buf, 1, size, f);
size -= written;
assert (size >= 0);
affirm (size >= 0);
if (size <= 0) /* everything written */
return true;

View File

@@ -18,13 +18,11 @@
#include <config.h>
#include <assert.h>
#include <sys/types.h>
#include <getopt.h>
#include "system.h"
#include "die.h"
#include "error.h"
#include "assure.h"
#include "fadvise.h"
#include "hard-locale.h"
#include "linebuffer.h"
@@ -57,7 +55,7 @@ struct outlist
int file;
/* Field index (zero-based), specified only when FILE is 1 or 2. */
size_t field;
idx_t field;
struct outlist *next;
};
@@ -66,15 +64,15 @@ struct outlist
struct field
{
char *beg; /* First character in field. */
size_t len; /* The length of the field. */
idx_t len; /* The length of the field. */
};
/* A line read from an input file. */
struct line
{
struct linebuffer buf; /* The line itself. */
size_t nfields; /* Number of elements in 'fields'. */
size_t nfields_allocated; /* Number of elements allocated for 'fields'. */
idx_t nfields; /* Number of elements in 'fields'. */
idx_t nfields_allocated; /* Number of elements allocated for 'fields'. */
struct field *fields;
};
@@ -82,13 +80,13 @@ struct line
same join field value. */
struct seq
{
size_t count; /* Elements used in 'lines'. */
size_t alloc; /* Elements allocated in 'lines'. */
idx_t count; /* Elements used in 'lines'. */
idx_t alloc; /* Elements allocated in 'lines'. */
struct line **lines;
};
/* The previous line read from each file. */
static struct line *prevline[2] = {NULL, NULL};
static struct line *prevline[2] = {nullptr, nullptr};
/* The number of lines read from each file. */
static uintmax_t line_no[2] = {0, 0};
@@ -99,7 +97,7 @@ static char *g_names[2];
/* This provides an extra line buffer for each file. We need these if we
try to read two consecutive lines into the same buffer, since we don't
want to overwrite the previous buffer before we check order. */
static struct line *spareline[2] = {NULL, NULL};
static struct line *spareline[2] = {nullptr, nullptr};
/* True if the LC_COLLATE locale is hard. */
static bool hard_LC_COLLATE;
@@ -123,12 +121,12 @@ static char const *empty_filler;
static bool autoformat;
/* The number of fields to output for each line.
Only significant when autoformat is true. */
static size_t autocount_1;
static size_t autocount_2;
static idx_t autocount_1;
static idx_t autocount_2;
/* Field to join on; SIZE_MAX means they haven't been determined yet. */
static size_t join_field_1 = SIZE_MAX;
static size_t join_field_2 = SIZE_MAX;
/* Field to join on; -1 means they haven't been determined yet. */
static ptrdiff_t join_field_1 = -1;
static ptrdiff_t join_field_2 = -1;
/* List of fields to print. */
static struct outlist outlist_head;
@@ -159,14 +157,14 @@ enum
static struct option const longopts[] =
{
{"ignore-case", no_argument, NULL, 'i'},
{"check-order", no_argument, NULL, CHECK_ORDER_OPTION},
{"nocheck-order", no_argument, NULL, NOCHECK_ORDER_OPTION},
{"zero-terminated", no_argument, NULL, 'z'},
{"header", no_argument, NULL, HEADER_LINE_OPTION},
{"ignore-case", no_argument, nullptr, 'i'},
{"check-order", no_argument, nullptr, CHECK_ORDER_OPTION},
{"nocheck-order", no_argument, nullptr, NOCHECK_ORDER_OPTION},
{"zero-terminated", no_argument, nullptr, 'z'},
{"header", no_argument, nullptr, HEADER_LINE_OPTION},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* Used to print non-joining lines */
@@ -258,12 +256,11 @@ warning message will be given.\n\
/* Record a field in LINE, with location FIELD and size LEN. */
static void
extract_field (struct line *line, char *field, size_t len)
extract_field (struct line *line, char *field, idx_t len)
{
if (line->nfields >= line->nfields_allocated)
{
line->fields = X2NREALLOC (line->fields, &line->nfields_allocated);
}
line->fields = xpalloc (line->fields, &line->nfields_allocated, 1,
-1, sizeof *line->fields);
line->fields[line->nfields].beg = field;
line->fields[line->nfields].len = len;
++(line->nfields);
@@ -283,7 +280,7 @@ xfields (struct line *line)
if (0 <= tab && tab != '\n')
{
char *sep;
for (; (sep = memchr (ptr, tab, lim - ptr)) != NULL; ptr = sep + 1)
for (; (sep = memchr (ptr, tab, lim - ptr)) != nullptr; ptr = sep + 1)
extract_field (line, ptr, sep - ptr);
}
else if (tab < 0)
@@ -313,12 +310,12 @@ xfields (struct line *line)
static void
freeline (struct line *line)
{
if (line == NULL)
if (line == nullptr)
return;
free (line->fields);
line->fields = NULL;
line->fields = nullptr;
free (line->buf.buffer);
line->buf.buffer = NULL;
line->buf.buffer = nullptr;
}
/* Return <0 if the join field in LINE1 compares less than the one in LINE2;
@@ -328,14 +325,14 @@ freeline (struct line *line)
static int
keycmp (struct line const *line1, struct line const *line2,
size_t jf_1, size_t jf_2)
idx_t jf_1, idx_t jf_2)
{
/* Start of field to compare in each file. */
char *beg1;
char *beg2;
size_t len1;
size_t len2; /* Length of fields to compare. */
idx_t len1;
idx_t len2; /* Length of fields to compare. */
int diff;
if (jf_1 < line1->nfields)
@@ -345,7 +342,7 @@ keycmp (struct line const *line1, struct line const *line2,
}
else
{
beg1 = NULL;
beg1 = nullptr;
len1 = 0;
}
@@ -356,7 +353,7 @@ keycmp (struct line const *line1, struct line const *line2,
}
else
{
beg2 = NULL;
beg2 = nullptr;
len2 = 0;
}
@@ -404,11 +401,11 @@ check_order (const struct line *prev,
{
if (!issued_disorder_warning[whatfile - 1])
{
size_t join_field = whatfile == 1 ? join_field_1 : join_field_2;
idx_t join_field = whatfile == 1 ? join_field_1 : join_field_2;
if (keycmp (prev, current, join_field, join_field) > 0)
{
/* Exclude any trailing newline. */
size_t len = current->buf.length;
idx_t len = current->buf.length;
if (0 < len && current->buf.buffer[len - 1] == '\n')
--len;
@@ -439,7 +436,7 @@ reset_line (struct line *line)
static struct line *
init_linep (struct line **linep)
{
struct line *line = xcalloc (1, sizeof *line);
struct line *line = xzalloc (sizeof *line);
*linep = line;
return line;
}
@@ -466,7 +463,7 @@ get_line (FILE *fp, struct line **linep, int which)
if (! readlinebuffer_delim (&line->buf, fp, eolchar))
{
if (ferror (fp))
die (EXIT_FAILURE, errno, _("read error"));
error (EXIT_FAILURE, errno, _("read error"));
freeline (line);
return false;
}
@@ -484,7 +481,7 @@ get_line (FILE *fp, struct line **linep, int which)
static void
free_spareline (void)
{
for (size_t i = 0; i < ARRAY_CARDINALITY (spareline); i++)
for (idx_t i = 0; i < ARRAY_CARDINALITY (spareline); i++)
{
if (spareline[i])
{
@@ -499,7 +496,7 @@ initseq (struct seq *seq)
{
seq->count = 0;
seq->alloc = 0;
seq->lines = NULL;
seq->lines = nullptr;
}
/* Read a line from FP and add it to SEQ. Return true if successful. */
@@ -509,9 +506,9 @@ getseq (FILE *fp, struct seq *seq, int whichfile)
{
if (seq->count == seq->alloc)
{
seq->lines = X2NREALLOC (seq->lines, &seq->alloc);
for (size_t i = seq->count; i < seq->alloc; i++)
seq->lines[i] = NULL;
seq->lines = xpalloc (seq->lines, &seq->alloc, 1, -1, sizeof *seq->lines);
for (idx_t i = seq->count; i < seq->alloc; i++)
seq->lines[i] = nullptr;
}
if (get_line (fp, &seq->lines[seq->count], whichfile))
@@ -536,7 +533,7 @@ advance_seq (FILE *fp, struct seq *seq, bool first, int whichfile)
static void
delseq (struct seq *seq)
{
for (size_t i = 0; i < seq->alloc; i++)
for (idx_t i = 0; i < seq->alloc; i++)
{
freeline (seq->lines[i]);
free (seq->lines[i]);
@@ -549,13 +546,11 @@ delseq (struct seq *seq)
'empty_filler' if it is nonempty. */
static void
prfield (size_t n, struct line const *line)
prfield (idx_t n, struct line const *line)
{
size_t len;
if (n < line->nfields)
{
len = line->fields[n].len;
idx_t len = line->fields[n].len;
if (len)
fwrite (line->fields[n].beg, 1, len, stdout);
else if (empty_filler)
@@ -568,10 +563,10 @@ prfield (size_t n, struct line const *line)
/* Output all the fields in line, other than the join field. */
static void
prfields (struct line const *line, size_t join_field, size_t autocount)
prfields (struct line const *line, idx_t join_field, idx_t autocount)
{
size_t i;
size_t nfields = autoformat ? autocount : line->nfields;
idx_t i;
idx_t nfields = autoformat ? autocount : line->nfields;
char output_separator = tab < 0 ? ' ' : tab;
for (i = 0; i < join_field && i < nfields; ++i)
@@ -593,7 +588,7 @@ prjoin (struct line const *line1, struct line const *line2)
{
const struct outlist *outlist;
char output_separator = tab < 0 ? ' ' : tab;
size_t field;
idx_t field;
struct line const *line;
outlist = outlist_head.next;
@@ -624,7 +619,7 @@ prjoin (struct line const *line1, struct line const *line2)
}
prfield (field, line);
o = o->next;
if (o == NULL)
if (o == nullptr)
break;
putchar (output_separator);
}
@@ -652,6 +647,9 @@ prjoin (struct line const *line1, struct line const *line2)
putchar (eolchar);
}
if (ferror (stdout))
write_error ();
}
/* Print the join of the files in FP1 and FP2. */
@@ -683,8 +681,8 @@ join (FILE *fp1, FILE *fp2)
struct line const *hline1 = seq1.count ? seq1.lines[0] : &uni_blank;
struct line const *hline2 = seq2.count ? seq2.lines[0] : &uni_blank;
prjoin (hline1, hline2);
prevline[0] = NULL;
prevline[1] = NULL;
prevline[0] = nullptr;
prevline[1] = nullptr;
if (seq1.count)
advance_seq (fp1, &seq1, true, 1);
if (seq2.count)
@@ -740,9 +738,9 @@ join (FILE *fp1, FILE *fp2)
if (print_pairables)
{
for (size_t i = 0; i < seq1.count - 1; ++i)
for (idx_t i = 0; i < seq1.count - 1; ++i)
{
size_t j;
idx_t j;
for (j = 0; j < seq2.count - 1; ++j)
prjoin (seq1.lines[i], seq2.lines[j]);
}
@@ -769,7 +767,7 @@ join (FILE *fp1, FILE *fp2)
tail ends of both inputs to verify that they are in order. We
skip the rest of the tail once we have issued a warning for that
file, unless we actually need to print the unpairable lines. */
struct line *line = NULL;
struct line *line = nullptr;
bool checktail = false;
if (check_input_order != CHECK_ORDER_DISABLED
@@ -816,17 +814,17 @@ join (FILE *fp1, FILE *fp2)
/* Add a field spec for field FIELD of file FILE to 'outlist'. */
static void
add_field (int file, size_t field)
add_field (int file, idx_t field)
{
struct outlist *o;
assert (file == 0 || file == 1 || file == 2);
assert (file != 0 || field == 0);
affirm (file == 0 || file == 1 || file == 2);
affirm (file != 0 || field == 0);
o = xmalloc (sizeof *o);
o->file = file;
o->field = field;
o->next = NULL;
o->next = nullptr;
/* Add to the end of the list so the fields are in the right order. */
outlist_end->next = o;
@@ -836,24 +834,21 @@ add_field (int file, size_t field)
/* Convert a string of decimal digits, STR (the 1-based join field number),
to an integral value. Upon successful conversion, return one less
(the zero-based field number). Silently convert too-large values
to SIZE_MAX - 1. Otherwise, if a value cannot be converted, give a
to PTRDIFF_MAX. Otherwise, if a value cannot be converted, give a
diagnostic and exit. */
static size_t
static idx_t
string_to_join_field (char const *str)
{
size_t result;
uintmax_t val;
intmax_t val;
strtol_error s_err = xstrtoumax (str, NULL, 10, &val, "");
if (s_err == LONGINT_OVERFLOW || (s_err == LONGINT_OK && SIZE_MAX < val))
val = SIZE_MAX;
else if (s_err != LONGINT_OK || val == 0)
die (EXIT_FAILURE, 0, _("invalid field number: %s"), quote (str));
strtol_error s_err = xstrtoimax (str, nullptr, 10, &val, "");
if (s_err == LONGINT_OVERFLOW || (s_err == LONGINT_OK && PTRDIFF_MAX < val))
val = PTRDIFF_MAX;
else if (s_err != LONGINT_OK || val <= 0)
error (EXIT_FAILURE, 0, _("invalid field number: %s"), quote (str));
result = val - 1;
return result;
return val - 1;
}
/* Convert a single field specifier string, S, to a *FILE_INDEX, *FIELD_INDEX
@@ -861,7 +856,7 @@ string_to_join_field (char const *str)
If S is valid, return true. Otherwise, give a diagnostic and exit. */
static void
decode_field_spec (char const *s, int *file_index, size_t *field_index)
decode_field_spec (char const *s, int *file_index, idx_t *field_index)
{
/* The first character must be 0, 1, or 2. */
switch (s[0])
@@ -870,7 +865,7 @@ decode_field_spec (char const *s, int *file_index, size_t *field_index)
if (s[1])
{
/* '0' must be all alone -- no '.FIELD'. */
die (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
error (EXIT_FAILURE, 0, _("invalid field specifier: %s"), quote (s));
}
*file_index = 0;
*field_index = 0;
@@ -879,21 +874,14 @@ decode_field_spec (char const *s, int *file_index, size_t *field_index)
case '1':
case '2':
if (s[1] != '.')
die (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:
die (EXIT_FAILURE, 0,
_("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. */
abort ();
break;
error (EXIT_FAILURE, 0,
_("invalid file number in field spec: %s"), quote (s));
}
}
@@ -907,7 +895,7 @@ add_field_list (char *str)
do
{
int file_index;
size_t field_index;
idx_t field_index;
char const *spec_item = p;
p = strpbrk (p, ", \t");
@@ -923,15 +911,11 @@ add_field_list (char *str)
more than once to incompatible values. */
static void
set_join_field (size_t *var, size_t val)
set_join_field (ptrdiff_t *var, idx_t val)
{
if (*var != SIZE_MAX && *var != val)
{
unsigned long int var1 = *var + 1;
unsigned long int val1 = val + 1;
die (EXIT_FAILURE, 0,
_("incompatible join fields %lu, %lu"), var1, val1);
}
if (0 <= *var && *var != val)
error (EXIT_FAILURE, 0,
_("incompatible join fields %td, %td"), *var, val);
*var = val;
}
@@ -1030,7 +1014,7 @@ 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:z",
longopts, NULL))
longopts, nullptr))
!= -1)
{
optc_status = MUST_BE_OPERAND;
@@ -1043,11 +1027,11 @@ main (int argc, char **argv)
case 'a':
{
unsigned long int val;
if (xstrtoul (optarg, NULL, 10, &val, "") != LONGINT_OK
long int val;
if (xstrtol (optarg, nullptr, 10, &val, "") != LONGINT_OK
|| (val != 1 && val != 2))
die (EXIT_FAILURE, 0,
_("invalid field number: %s"), quote (optarg));
error (EXIT_FAILURE, 0,
_("invalid field number: %s"), quote (optarg));
if (val == 1)
print_unpairables_1 = true;
else
@@ -1057,8 +1041,8 @@ main (int argc, char **argv)
case 'e':
if (empty_filler && ! STREQ (empty_filler, optarg))
die (EXIT_FAILURE, 0,
_("conflicting empty-field replacement strings"));
error (EXIT_FAILURE, 0,
_("conflicting empty-field replacement strings"));
empty_filler = optarg;
break;
@@ -1110,11 +1094,11 @@ main (int argc, char **argv)
if (STREQ (optarg, "\\0"))
newtab = '\0';
else
die (EXIT_FAILURE, 0, _("multi-character tab %s"),
quote (optarg));
error (EXIT_FAILURE, 0, _("multi-character tab %s"),
quote (optarg));
}
if (0 <= tab && tab != newtab)
die (EXIT_FAILURE, 0, _("incompatible tabs"));
error (EXIT_FAILURE, 0, _("incompatible tabs"));
tab = newtab;
}
break;
@@ -1175,28 +1159,28 @@ main (int argc, char **argv)
set_join_field (&join_field_2, i);
}
if (join_field_1 == SIZE_MAX)
if (join_field_1 < 0)
join_field_1 = 0;
if (join_field_2 == SIZE_MAX)
if (join_field_2 < 0)
join_field_2 = 0;
fp1 = STREQ (g_names[0], "-") ? stdin : fopen (g_names[0], "r");
if (!fp1)
die (EXIT_FAILURE, errno, "%s", quotef (g_names[0]));
error (EXIT_FAILURE, errno, "%s", quotef (g_names[0]));
fp2 = STREQ (g_names[1], "-") ? stdin : fopen (g_names[1], "r");
if (!fp2)
die (EXIT_FAILURE, errno, "%s", quotef (g_names[1]));
error (EXIT_FAILURE, errno, "%s", quotef (g_names[1]));
if (fp1 == fp2)
die (EXIT_FAILURE, errno, _("both files cannot be standard input"));
error (EXIT_FAILURE, errno, _("both files cannot be standard input"));
join (fp1, fp2);
if (fclose (fp1) != 0)
die (EXIT_FAILURE, errno, "%s", quotef (g_names[0]));
error (EXIT_FAILURE, errno, "%s", quotef (g_names[0]));
if (fclose (fp2) != 0)
die (EXIT_FAILURE, errno, "%s", quotef (g_names[1]));
error (EXIT_FAILURE, errno, "%s", quotef (g_names[1]));
if (issued_disorder_warning[0] || issued_disorder_warning[1])
die (EXIT_FAILURE, 0, _("input is not in sorted order"));
error (EXIT_FAILURE, 0, _("input is not in sorted order"));
else
return EXIT_SUCCESS;
}

View File

@@ -17,13 +17,13 @@
/* Written by Paul Eggert. */
#include <config.h>
#include <stdckdint.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <signal.h>
#include "system.h"
#include "error.h"
#include "sig2str.h"
#include "operand2sig.h"
#include "quote.h"
@@ -59,12 +59,12 @@ static char const short_options[] =
static struct option const long_options[] =
{
{"list", no_argument, NULL, 'l'},
{"signal", required_argument, NULL, 's'},
{"table", no_argument, NULL, 't'},
{"list", no_argument, nullptr, 'l'},
{"signal", required_argument, nullptr, 's'},
{"table", no_argument, nullptr, 't'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
void
@@ -131,10 +131,10 @@ list_signals (bool table, char *const *argv)
if (table)
{
unsigned int name_width = 0;
int name_width = 0;
/* Compute the maximum width of a signal number. */
unsigned int num_width = 1;
int num_width = 1;
for (signum = 1; signum <= SIGNUM_BOUND / 10; signum *= 10)
num_width++;
@@ -142,7 +142,7 @@ list_signals (bool table, char *const *argv)
for (signum = 1; signum <= SIGNUM_BOUND; signum++)
if (sig2str (signum, signame) == 0)
{
size_t len = strlen (signame);
idx_t len = strlen (signame);
if (name_width < len)
name_width = len;
}
@@ -201,7 +201,7 @@ send_signals (int signum, char *const *argv)
intmax_t n = (errno = 0, strtoimax (arg, &endp, 10));
pid_t pid;
if (errno == ERANGE || INT_ADD_WRAPV (n, 0, &pid)
if (errno == ERANGE || ckd_add (&pid, n, 0)
|| arg == endp || *endp)
{
error (0, 0, _("%s: invalid process id"), quote (arg));
@@ -235,7 +235,7 @@ main (int argc, char **argv)
atexit (close_stdout);
while ((optc = getopt_long (argc, argv, short_options, long_options, NULL))
while ((optc = getopt_long (argc, argv, short_options, long_options, nullptr))
!= -1)
switch (optc)
{
@@ -310,6 +310,6 @@ main (int argc, char **argv)
}
return (list
? list_signals (table, optind < argc ? argv + optind : NULL)
? list_signals (table, optind < argc ? argv + optind : nullptr)
: send_signals (signum, argv + optind));
}

View File

@@ -32,7 +32,7 @@
the buffer size, and more problematically does not give any indication
that the new size request was ignored:
setvbuf (stdout, NULL, _IOFBF, 8192);
setvbuf (stdout, nullptr, _IOFBF, 8192);
The ISO C99 standard section 7.19.5.6 on the setvbuf function says:
@@ -50,9 +50,9 @@
buffer allocation as usual. If it is not zero, then except for
unbuffered files, the buf argument should point to a buffer at least size
bytes long; this buffer will be used instead of the current buffer. (If
the size argument is not zero but buf is NULL, a buffer of the given size
the size argument is not zero but buf is null, a buffer of the given size
will be allocated immediately, and released on close. This is an extension
to ANSI C; portable code should use a size of 0 with any NULL buffer.)
to ANSI C; portable code should use a size of 0 with any null buffer.)
--------------------
Another issue is that on glibc-2.7 the following doesn't buffer
the first write if it's greater than 1 byte.
@@ -67,7 +67,7 @@
static char const *
fileno_to_name (const int fd)
{
char const *ret = NULL;
char const *ret = nullptr;
switch (fd)
{
@@ -91,7 +91,7 @@ fileno_to_name (const int fd)
static void
apply_mode (FILE *stream, char const *mode)
{
char *buf = NULL;
char *buf = nullptr;
int setvbuf_mode;
uintmax_t size = 0;
@@ -111,11 +111,11 @@ apply_mode (FILE *stream, char const *mode)
return;
}
buf = size <= SIZE_MAX ? malloc (size) : NULL;
buf = size <= SIZE_MAX ? malloc (size) : nullptr;
if (!buf)
{
/* We could defer the allocation to libc, however since
glibc currently ignores the combination of NULL buffer
glibc currently ignores the combination of null buffer
with non zero size, we'll fail here. */
fprintf (stderr,
_("failed to allocate a %" PRIuMAX

View File

@@ -25,8 +25,6 @@
#include <sys/types.h>
#include "system.h"
#include "die.h"
#include "error.h"
#include "long-options.h"
#include "quote.h"
@@ -68,7 +66,7 @@ main (int argc, char **argv)
parse_gnu_standard_options_only (argc, argv, PROGRAM_NAME, PACKAGE_NAME,
Version, true, usage, AUTHORS,
(char const *) NULL);
(char const *) nullptr);
if (argc < optind + 2)
{
@@ -86,8 +84,8 @@ main (int argc, char **argv)
}
if (link (argv[optind], argv[optind + 1]) != 0)
die (EXIT_FAILURE, errno, _("cannot create link %s to %s"),
quoteaf_n (0, argv[optind + 1]), quoteaf_n (1, argv[optind]));
error (EXIT_FAILURE, errno, _("cannot create link %s to %s"),
quoteaf_n (0, argv[optind + 1]), quoteaf_n (1, argv[optind]));
return EXIT_SUCCESS;
}

View File

@@ -23,8 +23,6 @@
#include "system.h"
#include "backupfile.h"
#include "die.h"
#include "error.h"
#include "fcntl-safer.h"
#include "filenamecat.h"
#include "file-set.h"
@@ -92,22 +90,22 @@ enum { DEST_INFO_INITIAL_CAPACITY = 61 };
static struct option const long_options[] =
{
{"backup", optional_argument, NULL, 'b'},
{"directory", no_argument, NULL, 'F'},
{"no-dereference", no_argument, NULL, 'n'},
{"no-target-directory", no_argument, NULL, 'T'},
{"force", no_argument, NULL, 'f'},
{"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'},
{"relative", no_argument, NULL, 'r'},
{"symbolic", no_argument, NULL, 's'},
{"verbose", no_argument, NULL, 'v'},
{"backup", optional_argument, nullptr, 'b'},
{"directory", no_argument, nullptr, 'F'},
{"no-dereference", no_argument, nullptr, 'n'},
{"no-target-directory", no_argument, nullptr, 'T'},
{"force", no_argument, nullptr, 'f'},
{"interactive", no_argument, nullptr, 'i'},
{"suffix", required_argument, nullptr, 'S'},
{"target-directory", required_argument, nullptr, 't'},
{"logical", no_argument, nullptr, 'L'},
{"physical", no_argument, nullptr, 'P'},
{"relative", no_argument, nullptr, 'r'},
{"symbolic", no_argument, nullptr, 's'},
{"verbose", no_argument, nullptr, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
{nullptr, 0, nullptr, 0}
};
/* Return an errno value for a system call that returned STATUS.
@@ -132,7 +130,7 @@ convert_abs_rel (char const *from, char const *target)
char *realdest = canonicalize_filename_mode (targetdir, CAN_MISSING);
char *realfrom = canonicalize_filename_mode (from, CAN_MISSING);
char *relative_from = NULL;
char *relative_from = nullptr;
if (realdest && realfrom)
{
/* Write to a PATH_MAX buffer. */
@@ -141,7 +139,7 @@ convert_abs_rel (char const *from, char const *target)
if (!relpath (realfrom, realdest, relative_from, PATH_MAX))
{
free (relative_from);
relative_from = NULL;
relative_from = nullptr;
}
}
@@ -182,8 +180,8 @@ do_link (char const *source, int destdir_fd, char const *dest_base,
{
struct stat source_stats;
int source_status = 1;
char *backup_base = NULL;
char *rel_source = NULL;
char *backup_base = nullptr;
char *rel_source = nullptr;
int nofollow_flag = logical ? 0 : AT_SYMLINK_NOFOLLOW;
if (link_errno < 0)
link_errno = atomic_link (source, destdir_fd, dest_base);
@@ -296,7 +294,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base,
{
int rename_errno = errno;
free (backup_base);
backup_base = NULL;
backup_base = nullptr;
if (rename_errno != ENOENT)
{
error (0, rename_errno, _("cannot backup %s"),
@@ -317,7 +315,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base,
to link A to B. 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 can try to
can prove that continuing onward cannot succeed, so we can try to
link A to B before blindly unlinking B, thus sometimes attempting to
link a second time during a successful 'ln -f A B'.
@@ -352,7 +350,7 @@ do_link (char const *source, int destdir_fd, char const *dest_base,
if (backup_base)
{
char *backup = backup_base;
void *alloc = NULL;
void *alloc = nullptr;
ptrdiff_t destdirlen = dest_base - dest;
if (0 < destdirlen)
{
@@ -470,9 +468,9 @@ main (int argc, char **argv)
int c;
bool ok;
bool make_backups = false;
char const *backup_suffix = NULL;
char *version_control_string = NULL;
char const *target_directory = NULL;
char const *backup_suffix = nullptr;
char *version_control_string = nullptr;
char const *target_directory = nullptr;
int destdir_fd;
bool no_target_directory = false;
int n_files;
@@ -490,7 +488,8 @@ main (int argc, char **argv)
symbolic_link = remove_existing_files = interactive = verbose
= hard_dir_link = false;
while ((c = getopt_long (argc, argv, "bdfinrst:vFLPS:T", long_options, NULL))
while ((c = getopt_long (argc, argv, "bdfinrst:vFLPS:T",
long_options, nullptr))
!= -1)
{
switch (c)
@@ -529,16 +528,16 @@ main (int argc, char **argv)
break;
case 't':
if (target_directory)
die (EXIT_FAILURE, 0, _("multiple target directories specified"));
error (EXIT_FAILURE, 0, _("multiple target directories specified"));
else
{
struct stat st;
if (stat (optarg, &st) != 0)
die (EXIT_FAILURE, errno, _("failed to access %s"),
quoteaf (optarg));
error (EXIT_FAILURE, errno, _("failed to access %s"),
quoteaf (optarg));
if (! S_ISDIR (st.st_mode))
die (EXIT_FAILURE, 0, _("target %s is not a directory"),
quoteaf (optarg));
error (EXIT_FAILURE, 0, _("target %s is not a directory"),
quoteaf (optarg));
}
target_directory = optarg;
break;
@@ -570,7 +569,7 @@ main (int argc, char **argv)
}
if (relative && !symbolic_link)
die (EXIT_FAILURE, 0, _("cannot do --relative without --symbolic"));
error (EXIT_FAILURE, 0, _("cannot do --relative without --symbolic"));
if (!hard_dir_link)
{
@@ -581,9 +580,9 @@ main (int argc, char **argv)
if (no_target_directory)
{
if (target_directory)
die (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)
@@ -630,7 +629,7 @@ main (int argc, char **argv)
target_directory = d;
}
else if (! (n_files == 2 && !target_directory))
die (EXIT_FAILURE, err, _("target %s"), quoteaf (d));
error (EXIT_FAILURE, err, _("target %s"), quoteaf (d));
}
}
@@ -655,11 +654,11 @@ main (int argc, char **argv)
&& backup_type != numbered_backups)
{
dest_set = hash_initialize (DEST_INFO_INITIAL_CAPACITY,
NULL,
nullptr,
triple_hash,
triple_compare,
triple_free);
if (dest_set == NULL)
if (dest_set == nullptr)
xalloc_die ();
}

View File

@@ -43,7 +43,6 @@ noinst_HEADERS = \
src/chown-core.h \
src/copy.h \
src/cp-hash.h \
src/die.h \
src/dircolors.h \
src/expand-common.h \
src/find-mount-point.h \
@@ -60,6 +59,7 @@ noinst_HEADERS = \
src/set-fields.h \
src/statx.h \
src/system.h \
src/temp-stream.h \
src/uname.h
EXTRA_DIST += \
@@ -260,6 +260,8 @@ src_ln_LDADD += $(CLOCK_TIME_LIB)
src_ls_LDADD += $(CLOCK_TIME_LIB)
src_mktemp_LDADD += $(CLOCK_TIME_LIB)
src_pr_LDADD += $(CLOCK_TIME_LIB)
src_sort_LDADD += $(CLOCK_TIME_LIB)
src_split_LDADD += $(CLOCK_TIME_LIB)
src_tac_LDADD += $(CLOCK_TIME_LIB)
src_timeout_LDADD += $(LIB_TIMER_TIME)
src_touch_LDADD += $(CLOCK_TIME_LIB)
@@ -294,10 +296,8 @@ src_ls_LDADD += $(FILE_HAS_ACL_LIB)
# for various xattr functions
copy_ldadd += $(LIB_XATTR)
# for print_unicode_char, proper_name_utf8
src_factor_LDADD += $(LIBICONV)
# for print_unicode_char
src_printf_LDADD += $(LIBICONV)
src_ptx_LDADD += $(LIBICONV)
# for libcrypto hash routines
src_md5sum_LDADD += $(LIB_CRYPTO)
@@ -317,6 +317,12 @@ src_who_LDADD += $(GETADDRINFO_LIB)
src_hostname_LDADD += $(GETHOSTNAME_LIB)
src_uname_LDADD += $(GETHOSTNAME_LIB)
# for read_utmp
src_pinky_LDADD += $(READUTMP_LIB)
src_uptime_LDADD += $(READUTMP_LIB)
src_users_LDADD += $(READUTMP_LIB)
src_who_LDADD += $(READUTMP_LIB)
# for strsignal
src_kill_LDADD += $(LIBTHREAD)
@@ -396,6 +402,9 @@ src_arch_SOURCES = src/uname.c src/uname-arch.c
src_cut_SOURCES = src/cut.c src/set-fields.c
src_numfmt_SOURCES = src/numfmt.c src/set-fields.c
src_split_SOURCES = src/split.c src/temp-stream.c
src_tac_SOURCES = src/tac.c src/temp-stream.c
src_tail_SOURCES = src/tail.c src/iopoll.c
src_tee_SOURCES = src/tee.c src/iopoll.c

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