Skip to content

Commit

Permalink
Merge pull request #1811 from EliahKagan/run-ci/fchmod-next
Browse files Browse the repository at this point in the history
Get and set mode using std, still on open file descriptor
  • Loading branch information
Byron authored Jan 26, 2025
2 parents 79cb655 + 53ded78 commit f3dc83b
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 24 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions gix-worktree-state/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,3 @@ gix-filter = { version = "^0.17.0", path = "../gix-filter" }
io-close = "0.3.7"
thiserror = "2.0.0"
bstr = { version = "1.3.0", default-features = false }

[target.'cfg(unix)'.dependencies]
rustix = { version = "0.38.20", default-features = false, features = [
"std",
"fs",
] }
30 changes: 13 additions & 17 deletions gix-worktree-state/src/checkout/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,10 @@ pub(crate) fn finalize_entry(
/// See `let_readers_execute` for the exact details of how the mode is transformed.
#[cfg(unix)]
fn set_executable(file: &std::fs::File) -> Result<(), std::io::Error> {
let old_raw_mode = rustix::fs::fstat(file)?.st_mode;
let new_mode = let_readers_execute(old_raw_mode);
rustix::fs::fchmod(file, new_mode)?;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
let old_mode = file.metadata()?.mode();
let new_mode = let_readers_execute(old_mode);
file.set_permissions(std::fs::Permissions::from_mode(new_mode))?;
Ok(())
}

Expand All @@ -309,20 +310,16 @@ fn set_executable(file: &std::fs::File) -> Result<(), std::io::Error> {
/// Currently this adds executable bits for whoever has read bits already. It doesn't use the umask.
/// Set-user-ID and set-group-ID bits are unset for safety. The sticky bit is also unset.
///
/// This returns only mode bits, not file type. The return value can be passed to chmod or fchmod.
#[cfg(unix)]
fn let_readers_execute(mut raw_mode: rustix::fs::RawMode) -> rustix::fs::Mode {
assert_eq!(
raw_mode & 0o170000,
0o100000,
"bug in caller if not from a regular file"
);
raw_mode &= 0o777; // Clear type, non-rwx mode bits (setuid, setgid, sticky).
raw_mode |= (raw_mode & 0o444) >> 2; // Let readers also execute.
rustix::fs::Mode::from_bits(raw_mode).expect("all bits recognized")
/// This returns only mode bits, not file type. The return value can be used in chmod or fchmod.
#[cfg(any(unix, test))]
fn let_readers_execute(mut mode: u32) -> u32 {
assert_eq!(mode & 0o170000, 0o100000, "bug in caller if not from a regular file");
mode &= 0o777; // Clear type, non-rwx mode bits (setuid, setgid, sticky).
mode |= (mode & 0o444) >> 2; // Let readers also execute.
mode
}

#[cfg(all(test, unix))]
#[cfg(test)]
mod tests {
#[test]
fn let_readers_execute() {
Expand Down Expand Up @@ -372,8 +369,7 @@ mod tests {
(0o106400, 0o500),
(0o102462, 0o572),
];
for (st_mode, raw_expected) in cases {
let expected = rustix::fs::Mode::from_bits(raw_expected).expect("expected mode is a mode");
for (st_mode, expected) in cases {
let actual = super::let_readers_execute(st_mode);
assert_eq!(
actual, expected,
Expand Down

0 comments on commit f3dc83b

Please sign in to comment.