Get st_flags from MetadataExt on MacOS

I missed that `st_flags` is available on `MetadataExt` on MacOS, so get
them from there, instead of calling `libc::stat`.

type: reform
This commit is contained in:
Casey Rodarmor 2020-04-20 15:04:30 -07:00
parent deca555ac3
commit 4f4464e3a2
No known key found for this signature in database
GPG Key ID: 556186B153EC6FE0
2 changed files with 37 additions and 20 deletions

View File

@ -4,7 +4,8 @@ Changelog
UNRELEASED - 2020-04-21
-----------------------
- :sparkles: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Allow suppressing output with `--quiet` - Fixes [#174](https://github.com/casey/intermodal/issues/174) - _Celeo <celeodor@gmail.com>_
- :art: [`xxxxxxxxxxxx`](https://github.com/casey/intermodal/commits/master) Get `st_flags` from `MetadataExt` on MacOS - _Casey Rodarmor <casey@rodarmor.com>_
- :sparkles: [`deca555ac3b3`](https://github.com/casey/intermodal/commit/deca555ac3b3b8f665ee6415f80e05b2bb5e4af7) Allow suppressing output with `--quiet` - Fixes [#174](https://github.com/casey/intermodal/issues/174) - _Celeo <celeodor@gmail.com>_
- :books: [`838167c4d3bc`](https://github.com/casey/intermodal/commit/838167c4d3bcbe2fa28f27a00bd94b959ad31e15) Describe in FAQ creating torrent from git repo - _Casey Rodarmor <casey@rodarmor.com>_
- :sparkles: [`9b72873ed13e`](https://github.com/casey/intermodal/commit/9b72873ed13e8f0ae747714545c48c6e37c67dd0) Optionally respect `.gitignore` in `imdl torrent create` - Fixes [#378](https://github.com/casey/intermodal/issues/378) - _Celeo <celeodor@gmail.com>_
- :books: [`9f480624616b`](https://github.com/casey/intermodal/commit/9f480624616b77995befec722effda22cc2d06ad) Improve FAQ template - _Casey Rodarmor <casey@rodarmor.com>_

View File

@ -17,29 +17,13 @@ impl PlatformInterface for Platform {
#[cfg(target_os = "macos")]
impl PlatformInterface for Platform {
fn hidden(path: &Path) -> Result<bool, Error> {
use std::{ffi::CString, mem, os::unix::ffi::OsStrExt};
use std::os::macos::fs::MetadataExt;
const HIDDEN_MASK_MAC: u32 = 0x0000_8000;
let mut stat: libc::stat = unsafe { mem::zeroed() };
let metadata = path.metadata().context(error::Filesystem { path })?;
let cpath = if let Ok(cstr) = CString::new(path.as_os_str().as_bytes()) {
cstr
} else {
// Consider paths containing null bytes to be hidden
return Ok(true);
};
let error_code = unsafe { libc::stat(cpath.as_ptr(), &mut stat) };
if error_code != 0 {
return Err(Error::Filesystem {
source: io::Error::from_raw_os_error(error_code),
path: path.to_owned(),
});
}
Ok(stat.st_flags & HIDDEN_MASK_MAC != 0)
Ok(metadata.st_flags() & HIDDEN_MASK_MAC != 0)
}
}
@ -49,3 +33,35 @@ impl PlatformInterface for Platform {
Ok(false)
}
}
#[cfg(tests)]
mod tests {
use super::*;
#[test]
fn hidden() {
let tmp = tempdir().unwrap();
let file = tmp.path().join("file");
assert!(!Platform::hidden(&file));
if cfg!(target_os = "windows") {
Command::new("attrib")
.arg("+h")
.arg(&file)
.status()
.unwrap();
} else if cfg!(target_os = "macos") {
Command::new("chflags")
.arg("hidden")
.arg(&file)
.status()
.unwrap();
} else {
return;
}
assert!(Platform::hidden(&file));
}
}