Skip to content

mkdir:Refactor: replace direct libc calls with nix wrappers for umask/mkdirat#11138

Open
mattsu2020 wants to merge 2 commits intouutils:mainfrom
mattsu2020:mkdir
Open

mkdir:Refactor: replace direct libc calls with nix wrappers for umask/mkdirat#11138
mattsu2020 wants to merge 2 commits intouutils:mainfrom
mattsu2020:mkdir

Conversation

@mattsu2020
Copy link
Contributor

Summary

This PR replaces a few direct libc syscall usages with nix wrappers to reduce unsafe surface area and improve consistency in Unix-specific filesystem/process code.

@github-actions
Copy link

GNU testsuite comparison:

Skipping an intermittent issue tests/pr/bounded-memory (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/misc/io-errors is no longer failing!
Congrats! The gnu test tests/tail/tail-n0f is now passing!

@@ -10,6 +10,8 @@ use clap::parser::ValuesRef;
use clap::{Arg, ArgAction, ArgMatches, Command};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you putting this in this PR???

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These imports are required for this refactor: UmaskGuard now uses nix::sys::stat::umask/Mode, and create_dir_with_mode uses DirBuilderExt::mode.

Copy link
Contributor

@xtqqczze xtqqczze Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each of these imports is only used oncetwice, I think we can remove them and qualify the method calls instead for clarity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally if it's less than three, I would just qualify them

@xtqqczze
Copy link
Contributor

xtqqczze commented Feb 27, 2026

@mattsu2020 The change is sound, but the commit description isn't helpful. In general, replacing unsafe libc calls with nix in simple cases like this doesn't require extensive justification. I would also suggest that you squash your commits.

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/tail/retry. tests/tail/retry is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/misc/io-errors is no longer failing!
Note: The gnu test tests/seq/seq-epipe is now being skipped but was previously passing.
Note: The gnu test tests/tail/pipe-f is now being skipped but was previously passing.
Congrats! The gnu test tests/tail/tail-n0f is now passing!

@github-actions
Copy link

GNU testsuite comparison:

Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/inotify-dir-recreate (passes in this run but fails in the 'main' branch)
Note: The gnu test tests/expand/bounded-memory is now being skipped but was previously passing.
Congrats! The gnu test tests/tail/tail-n0f is now passing!

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 27, 2026

Merging this PR will not alter performance

✅ 294 untouched benchmarks
⏩ 42 skipped benchmarks1


Comparing mattsu2020:mkdir (95df9c8) with main (6de55b4)

Open in CodSpeed

Footnotes

  1. 42 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.

@xtqqczze
Copy link
Contributor

@mattsu2020 Could you please run cargo fmt and then squash the commits into a single one? For the commit description, you might also ask your AI to make it concise :)

@github-actions
Copy link

GNU testsuite comparison:

GNU test failed: tests/rm/isatty. tests/rm/isatty is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/inotify-dir-recreate (passes in this run but fails in the 'main' branch)

use nix::sys::stat::{Mode, umask};
use std::ffi::OsString;
use std::io::{Write, stdout};
#[cfg(unix)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this import can go back in create_dir_with_mode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good point. I’ll move DirBuilderExt back into create_dir_with_mode. Mode/umask will stay at module scope because UmaskGuard also uses them.

Moved the `std::os::unix::fs::DirBuilderExt` import from module-level to inside the `create_dir_with_mode` function where it's actually used. This improves code organization by keeping platform-specific imports closer to their usage and reduces the module's import surface.
@github-actions
Copy link

GNU testsuite comparison:

Skip an intermittent issue tests/tail/follow-name (fails in this run but passes in the 'main' branch)
Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/date/resolution (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tty/tty-eof (passes in this run but fails in the 'main' branch)
Note: The gnu test tests/cut/bounded-memory is now being skipped but was previously passing.
Congrats! The gnu test tests/expand/bounded-memory is now passing!
Note: The gnu test tests/env/env-signal-handler was skipped on 'main' but is now failing.

let old_mask = unsafe { uucore::libc::umask(new_mask) };
Self(old_mask)
/// Set umask to 0 and return a guard that restores the original on drop.
fn set_zero() -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can rename this function to new, see existing pattern in:

struct SigpipeGuard {
previous: libc::sighandler_t,
}
#[cfg(unix)]
impl SigpipeGuard {
fn new() -> Self {
let previous = unsafe { libc::signal(libc::SIGPIPE, libc::SIG_IGN) };
Self { previous }
}
}

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.

3 participants