20646 Commits
Author SHA1 Message Date
Sylvestre Ledru bf65901e1e ci: do not train a PGO profile on Windows arm64
The instrumented aarch64-pc-windows-msvc binary writes .profraw files that llvm-profdata rejects with "symbol name is empty" (rust-lang/rust#150123, rust-lang/rust#156675). The job keeps building natively, without PGO.
0.11.0
2026-08-30 23:38:17 +02:00
Sylvestre Ledru cddda2844c tests: make env and expr pass on Windows arm64 2026-08-30 23:38:17 +02:00
Sylvestre Ledru dea554da9f pgo: write the profile before exiting on Windows 2026-08-30 23:38:17 +02:00
Sylvestre Ledru 25bf6ba5a2 ci: build the Windows arm64 artifact natively with PGO 2026-08-30 23:38:17 +02:00
Sylvestre Ledru f36da45909 ci: build the published macOS and Windows artifacts with PGO 2026-08-30 23:38:17 +02:00
Asifur Rahaman Meeru 2228600268 date: reject a trailing timezone when the input already has one
`try_parse_with_abbreviation` strips a trailing timezone abbreviation and
re-parses what is left, which let it accept strings the parser had already
rejected. Its guard only caught a remaining bare abbreviation such as
"EST PST", so anything else carrying zone information slipped past it:

    date -d "Jan 23 6:00PM GMT-1 EST"    # an offset and a zone
    date -d "023-060 MEST"               # a time with an offset, and a zone
    date -d "@0 EST"                     # a timestamp cannot take a zone

GNU date rejects all of these. We accepted them, and the "023-060" case
quietly answered with today's date.

Rather than reimplement the offset grammar here, read the answer off the
parse this path already performs. parse_datetime hands back the zone the
input named, or the current zone when it named none, so a mismatch says the
remainder carries its own. A leading "@" is tested directly, since a
timestamp cannot take a zone at all. The parser is consulted a second time
only when the remainder does name a zone whose offset coincides with the
current one, which the comparison cannot see on its own. The common case
stays at a single parse, and that matters because -f runs this once per line.

Input that carries zone information of its own, or cannot take one at all,
now falls through to the standard parser and is rejected.

The abbreviations this path exists for are unaffected, including the
Australian ones that GNU does not support. Checked against GNU coreutils
9.11 over the conflicting forms in several timezones, and over 300 inputs
GNU accepts, none of which this change rejects.

Closes #13865
2026-08-30 23:09:01 +02:00
Ivan Teresenko 0155dfb5b8 stat: restrict the new fs-format test to linux and android
`stat -f` panics with `unimplemented!()` in `fs_type` on the other unix
targets, so the test failed on the OpenBSD leg of the unix job.
2026-08-30 22:17:13 +02:00
Ivan Teresenko d1d4ca958c stat: print "Block size" in file system mode
In `stat -f` the label was composed from two separate words, which
rendered as "Block Size:". GNU prints "Block size:", so the label is now
a single localizable string. As a side effect the French output becomes
"Taille bloc:" instead of the word-by-word "Bloc Taille:".
2026-08-30 22:17:13 +02:00
arbelonson-source a43e94fe41 head, tail: keep leading zeros in an invalid count message
Closes #14229.

`parse_signed_num_max` strips leading zeros so the count is read as
decimal rather than octal, then hands the trimmed string to the size
parser. The error carries that trimmed string, so the zeros the user
typed never reach the message:

    $ tail -c0fb a
    tail: invalid number of bytes: 'fb'      # GNU: '0fb'
    $ head -n0x a
    head: invalid number of lines: 'x'       # GNU: '0x'

Rebuild the error around the untrimmed operand instead. Only the two
variants that carry the operand alone are rebuilt; `SizeTooBig` also
carries an explanation and `PhysicalMem` is not about the operand, and
neither can arise here anyway, since `parse_size_u64_max` clamps rather
than overflowing.

The sign stays stripped, matching GNU, which reports the operand of
`tail -c-0fb` as '0fb'. This also lines the message up with
`number_offset`, which already counts leading zeros as part of the
number when placing the caret.
2026-08-30 22:13:19 +02:00
arbelonson-source c28d64216a join, od: report a hyphen-leading value instead of rejecting it
GNU hands the argument after an option to that option even when it
starts with a hyphen, and then reports it as invalid:

    $ join -1 -1 a b
    join: invalid field number: '-1'
    $ od -N -1 a
    od: invalid -N argument '-1'

Both refused it as an unknown option instead. The validation that
produces those exact messages is already there — `join -1 abc` and
`od -N abc` match GNU today — so the value simply never reached it.
Let it through with allow_hyphen_values.
2026-08-30 22:07:32 +02:00
Sylvestre Ledru 21a5e91ea5 mv: check the single source open at the syscall level
mv already holds the invariant: it has its own cross-device fallback
rather than cp's copy machinery, so it never had the three-open problem.
These pin it in place, since the pending fd-anchored rework of the EXDEV
directory path (GHSA-pp2g) touches exactly this code.

Three assertions: a same-filesystem move must open the source zero times
(it is a rename, not a copy), and the cross-device file and directory
fallbacks must open each source exactly once. Each was verified to fail
by injecting a redundant File::open at the matching call site.

The directory case matches any path ending in the source name opened
O_RDONLY, so it keeps working once the traversal opens by bare name
under a directory fd. Cross-device needs a second filesystem; /dev/shm
supplies it, and the checks skip loudly when it shares a device with
TEMP_DIR rather than passing vacuously.
2026-08-30 21:57:17 +02:00
Sylvestre Ledru 1de64e48b4 cp: check the single source open at the syscall level
New util/check-open-once.sh straces cp and asserts the source path is
opened exactly once, across the default, --sparse=always and
--sparse=never paths. Verified it fails on the previous code with 'opened
the source 3 times', so it guards the invariant rather than restating it.

Kept out of check-toctou.sh: no exploit is known for the old window --
every open used the same credentials and flags -- and the security
scripts should stay about attacker-exploitable splits. The new header
says so and points at the two that do.

Traces open(2) as well as openat(2): rustix issues the former on Linux,
so an openat-only filter matches nothing and passes vacuously.
2026-08-30 21:57:17 +02:00
Sylvestre Ledru 7f845515b1 cp: open the source once per copy
Every regular-file copy on Linux opened the source three times: once in
check_for_data, once in check_sparse_detection, then again in the copy
itself. Open it once and thread the descriptor through the probe and the
copy, so the strategy and the bytes come from the same fd.

  before: open("src", O_RDONLY) x3 + open("dst", O_WRONLY|O_CREAT) x1
  after:  open("src", O_RDONLY) x1 + open("dst", O_WRONLY|O_CREAT) x1

Copying 3000 small files, 50 runs: 199.9ms +/- 14.9 -> 171.7ms +/- 23.6.
The ratio's error bars overlap; the stable signal is system time,
177.3ms -> 146.9ms, with user time unchanged at ~18ms.
2026-08-30 21:57:17 +02:00
Sylvestre Ledru 112dd107e4 docs: document the PGO training/build settings requirement
Record what the LTO mismatch cost and why the existing function-count check
does not catch it, and add measured per-utility gains to the performance page.
2026-08-30 21:53:55 +02:00
Sylvestre Ledru 0fb2882f8b build-pgo.sh: instrument with the same LTO settings as the final build
The instrumented binary was built with LTO off and 16 codegen units, but the
profile is consumed by a fat-LTO build. Inlining runs before instrumentation,
so the counters describe a different call graph: the mismatched profile covers
4098 functions where the matched one covers 1883.

The result was a profile that made several utils slower than no PGO at all:
wc -w regressed 57% (+21.7% instructions, all in uu_wc::process_chunk).

With the instrumented build matched to the final one, wc -w is back to
parity and PGO gives cat -n -29%, uniq -c -27%, nl -26%, fold -22%,
sort -18%, sort -n -17%, wc -15%, sort -k -11%. Build time goes from
1m56s to 2m58s.
2026-08-30 21:53:55 +02:00
xtqqczze 4a41d0ba51 remove some more clone 2026-08-30 21:33:55 +02:00
xtqqczze 360493a3ae remove a few unnecessary clone 2026-08-30 21:33:55 +02:00
Haydon Ryan 31d71040e6 pr: replace page/group deep clone with mem::take 2026-08-30 21:33:55 +02:00
xtqqczze dd9198f3f8 clippy: fix redundant_clone lint
https://rust-lang.github.io/rust-clippy/master/#redundant_clone
2026-08-30 21:33:55 +02:00
oech3 6cb1d5eb01 test_cp.rs: fix error message of ficlone on musl 2026-08-30 19:03:36 +02:00
Sylvestre Ledru 1cba018e1c Document PGO 2026-08-30 16:41:13 +02:00
Sylvestre Ledru abe8aaff53 env: drop the unused StringExpander::put_native_string 2026-08-30 16:20:07 +02:00
Sylvestre Ledru 29495ad158 env: drop the unused NCvt::into_native
native() covers every call site.
2026-08-30 16:20:07 +02:00
Sylvestre Ledru 8d0161ad22 dd: drop the unused Alarm interval getter
get_interval had no callers, and it was the only reader of the interval
field. with_interval still moves the duration into the timer thread, so
Alarm keeps only the shared trigger.
2026-08-30 16:20:07 +02:00
Abhijeet Vichare 35782c48ab tsort: include filename in error message
GNU tsort names the file it could not open; ours dropped it because the
File::open error was propagated without context. Use map_err_context,
as nl and wc already do.
2026-08-30 14:30:54 +02:00