Use getmntinfo(3) to list mounted volumes

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Max Brunsfeld 2021-04-22 15:40:39 -07:00
parent b37b047400
commit ae5f02d2e9
3 changed files with 15 additions and 30 deletions

2
Cargo.lock generated
View file

@ -2220,7 +2220,6 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"arrayvec", "arrayvec",
"cocoa",
"crossbeam-channel", "crossbeam-channel",
"ctor", "ctor",
"dirs", "dirs",
@ -2234,7 +2233,6 @@ dependencies = [
"libc", "libc",
"log", "log",
"num_cpus", "num_cpus",
"objc",
"parking_lot", "parking_lot",
"postage", "postage",
"rand 0.8.3", "rand 0.8.3",

View file

@ -42,7 +42,3 @@ env_logger = "0.8"
serde_json = {version = "1.0.64", features = ["preserve_order"]} serde_json = {version = "1.0.64", features = ["preserve_order"]}
tempdir = "0.3.7" tempdir = "0.3.7"
unindent = "0.1.7" unindent = "0.1.7"
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.24"
objc = "0.2"

View file

@ -18,13 +18,13 @@ use postage::{
use smol::{channel::Sender, Timer}; use smol::{channel::Sender, Timer};
use std::{ use std::{
collections::{BTreeMap, HashMap, HashSet}, collections::{BTreeMap, HashMap, HashSet},
ffi::OsStr, ffi::{CStr, OsStr},
fmt, fs, fmt, fs,
future::Future, future::Future,
io::{self, Read, Write}, io::{self, Read, Write},
mem, mem,
ops::{AddAssign, Deref}, ops::{AddAssign, Deref},
os::unix::fs::MetadataExt, os::unix::{ffi::OsStrExt, fs::MetadataExt},
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::Arc, sync::Arc,
time::Duration, time::Duration,
@ -1229,30 +1229,21 @@ impl<'a> Iterator for FileIter<'a> {
} }
fn mounted_volume_paths() -> Vec<PathBuf> { fn mounted_volume_paths() -> Vec<PathBuf> {
use cocoa::{
base::{id, nil},
foundation::{NSArray, NSString, NSURL},
};
use objc::{class, msg_send, sel, sel_impl};
unsafe { unsafe {
let manager: id = msg_send![class!(NSFileManager), defaultManager]; let mut stat_ptr: *mut libc::statfs = std::ptr::null_mut();
let array = NSArray::array(nil); let count = libc::getmntinfo(&mut stat_ptr as *mut _, libc::MNT_WAIT);
let urls: id = if count >= 0 {
msg_send![manager, mountedVolumeURLsIncludingResourceValuesForKeys:array options:0]; std::slice::from_raw_parts(stat_ptr, count as usize)
let len = urls.count() as usize; .iter()
let mut result = Vec::with_capacity(len); .map(|stat| {
for i in 0..len { PathBuf::from(OsStr::from_bytes(
let url = urls.objectAtIndex(i as u64); CStr::from_ptr(&stat.f_mntonname[0]).to_bytes(),
let string = url.absoluteString(); ))
let string = std::ffi::CStr::from_ptr(string.UTF8String()) })
.to_string_lossy() .collect()
.to_string(); } else {
if let Some(path) = string.strip_prefix("file://") { panic!("failed to run getmntinfo");
result.push(PathBuf::from(path));
} }
}
result
} }
} }