Skip to content

chmod: report the real error when a target's metadata is inaccessible - #13637

Open
0xfandom wants to merge 2 commits into
uutils:mainfrom
0xfandom:chmod-inaccessible-permission-denied
Open

chmod: report the real error when a target's metadata is inaccessible#13637
0xfandom wants to merge 2 commits into
uutils:mainfrom
0xfandom:chmod-inaccessible-permission-denied

Conversation

@0xfandom

Copy link
Copy Markdown
Contributor

Fixes #9789.

chmod used Path::exists() to decide whether a target exists. Path::exists() returns false for any metadata access error, including permission errors, so a file whose parent directory lacks search permission was reported as:

chmod: cannot access 'locked/file': No such file or directory

instead of GNU's:

chmod: cannot access 'locked/file': Permission denied

This switches the non-recursive path to Path::try_exists(), which returns Ok(false) only for a genuine ENOENT and Err(..) for a permission error. A permission error is now reported via the existing ChmodError::PermissionDenied variant, whose message already matches GNU. Any other unexpected metadata error falls through to the normal chmod attempt so it can surface a precise message.

Added a regression test (test_chmod_inaccessible_file_reports_permission_denied) for the non-recursive case; it fails on the old Path::exists() code (prints "No such file or directory") and passes with the fix. The existing permission-denied tests only covered the recursive (-R) path.

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Note: The gnu test tests/seq/seq-epipe is now being skipped but was previously passing.

@sylvestre

Copy link
Copy Markdown
Contributor

a few jobs are failing

chmod used Path::exists() to decide whether a target exists, but exists() returns false on any metadata error, so a file whose parent directory lacks search permission was reported as "No such file or directory" instead of "Permission denied". Use try_exists() to distinguish a genuine ENOENT from a permission error, matching GNU. Fixes uutils#9789.
@sylvestre
sylvestre force-pushed the chmod-inaccessible-permission-denied branch from 44c1f3f to 7308279 Compare July 30, 2026 20:49
@codspeed-hq

codspeed-hq Bot commented Jul 30, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 22.62%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 344 untouched benchmarks
⏩ 46 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation df_with_path 700.8 µs 571.5 µs +22.62%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing 0xfandom:chmod-inaccessible-permission-denied (6dadcce) with main (a730551)

Open in CodSpeed

Footnotes

  1. 46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Satisfy clippy::unreadable_literal (0o100644 -> 0o100_644) so the
Style and Lint job passes.
@0xfandom

0xfandom commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the heads up. The failing job was clippy's unreadable_literal on the new test — I'd written the octal mode as 0o100644. Pushed a fixup that changes it to 0o100_644, and clippy is clean locally now.

The CodSpeed report flags a ~3.5% change on du_wide_tree, but that's an unrelated du benchmark this PR doesn't touch, and the report itself notes it compared across different runtime environments. Should be noise. Let me know if you'd like anything else adjusted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chmod: behavioral divergence from coreutils when the target file is not accessible

2 participants