Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add is_read_only flag for disks #1348

Merged
merged 4 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ disk = [
"windows/Win32_Security", # For `windows::Win32::Storage::FileSystem::CreateFileW`.
"windows/Win32_System_IO",
"windows/Win32_System_Ioctl",
"windows/Win32_System_SystemServices",
"windows/Win32_System_WindowsProgramming",
]
system = [
Expand Down
14 changes: 14 additions & 0 deletions src/common/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,20 @@ impl Disk {
self.inner.is_removable()
}

/// Returns `true` if the disk is read-only.
///
/// ```no_run
/// use sysinfo::Disks;
///
/// let disks = Disks::new_with_refreshed_list();
/// for disk in disks.list() {
/// println!("[{:?}] is read-only: {}", disk.name(), disk.is_read_only());
/// }
/// ```
pub fn is_read_only(&self) -> bool {
self.inner.is_read_only()
}

/// Updates the disk' information.
///
/// ```no_run
Expand Down
8 changes: 8 additions & 0 deletions src/unix/apple/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub(crate) struct DiskInner {
pub(crate) total_space: u64,
pub(crate) available_space: u64,
pub(crate) is_removable: bool,
pub(crate) is_read_only: bool,
}

impl DiskInner {
Expand Down Expand Up @@ -59,6 +60,10 @@ impl DiskInner {
self.is_removable
}

pub(crate) fn is_read_only(&self) -> bool {
self.is_read_only
}

pub(crate) fn refresh(&mut self) -> bool {
unsafe {
if let Some(requested_properties) = build_requested_properties(&[
Expand Down Expand Up @@ -422,6 +427,8 @@ unsafe fn new_disk(
)
};

let is_read_only = (c_disk.f_flags & libc::MNT_RDONLY as u32) != 0;

Some(Disk {
inner: DiskInner {
type_,
Expand All @@ -432,6 +439,7 @@ unsafe fn new_disk(
total_space,
available_space,
is_removable,
is_read_only,
},
})
}
Expand Down
8 changes: 8 additions & 0 deletions src/unix/freebsd/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub(crate) struct DiskInner {
available_space: u64,
file_system: OsString,
is_removable: bool,
is_read_only: bool,
}

impl DiskInner {
Expand Down Expand Up @@ -47,6 +48,10 @@ impl DiskInner {
self.is_removable
}

pub(crate) fn is_read_only(&self) -> bool {
self.is_read_only
}

pub(crate) fn refresh(&mut self) -> bool {
unsafe {
let mut vfs: libc::statvfs = std::mem::zeroed();
Expand Down Expand Up @@ -154,6 +159,8 @@ pub unsafe fn get_all_list(container: &mut Vec<Disk>) {

let f_frsize: u64 = vfs.f_frsize as _;

let is_read_only = (vfs.f_flag & libc::ST_RDONLY) != 0;

container.push(Disk {
inner: DiskInner {
name,
Expand All @@ -163,6 +170,7 @@ pub unsafe fn get_all_list(container: &mut Vec<Disk>) {
available_space: vfs.f_favail.saturating_mul(f_frsize),
file_system: OsString::from_vec(fs_type),
is_removable,
is_read_only,
},
});
}
Expand Down
8 changes: 8 additions & 0 deletions src/unix/linux/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub(crate) struct DiskInner {
total_space: u64,
available_space: u64,
is_removable: bool,
is_read_only: bool,
}

impl DiskInner {
Expand Down Expand Up @@ -55,6 +56,10 @@ impl DiskInner {
self.is_removable
}

pub(crate) fn is_read_only(&self) -> bool {
self.is_read_only
}

pub(crate) fn refresh(&mut self) -> bool {
unsafe {
let mut stat: statvfs = mem::zeroed();
Expand Down Expand Up @@ -103,6 +108,7 @@ fn new_disk(
let type_ = find_type_for_device_name(device_name);
let mut total = 0;
let mut available = 0;
let mut is_read_only = false;
unsafe {
let mut stat: statvfs = mem::zeroed();
if retry_eintr!(statvfs(mount_point_cpath.as_ptr() as *const _, &mut stat)) == 0 {
Expand All @@ -111,6 +117,7 @@ fn new_disk(
let bavail = cast!(stat.f_bavail);
total = bsize.saturating_mul(blocks);
available = bsize.saturating_mul(bavail);
is_read_only = (stat.f_flag & libc::ST_RDONLY) != 0;
}
if total == 0 {
return None;
Expand All @@ -128,6 +135,7 @@ fn new_disk(
total_space: cast!(total),
available_space: cast!(available),
is_removable,
is_read_only,
},
})
}
Expand Down
4 changes: 4 additions & 0 deletions src/unknown/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ impl DiskInner {
false
}

pub(crate) fn is_read_only(&self) -> bool {
false
}

pub(crate) fn refresh(&mut self) -> bool {
true
}
Expand Down
11 changes: 10 additions & 1 deletion src/windows/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use windows::Win32::Storage::FileSystem::{
FindFirstVolumeW, FindNextVolumeW, FindVolumeClose, GetDiskFreeSpaceExW, GetDriveTypeW,
GetVolumeInformationW, GetVolumePathNamesForVolumeNameW,
};
use windows::Win32::System::SystemServices::FILE_READ_ONLY_VOLUME;
use windows::Win32::System::Ioctl::{
PropertyStandardQuery, StorageDeviceSeekPenaltyProperty, DEVICE_SEEK_PENALTY_DESCRIPTOR,
IOCTL_STORAGE_QUERY_PROPERTY, STORAGE_PROPERTY_QUERY,
Expand Down Expand Up @@ -125,6 +126,7 @@ pub(crate) struct DiskInner {
total_space: u64,
available_space: u64,
is_removable: bool,
is_read_only: bool,
}

impl DiskInner {
Expand Down Expand Up @@ -156,6 +158,10 @@ impl DiskInner {
self.is_removable
}

pub(crate) fn is_read_only(&self) -> bool {
self.is_read_only
}

pub(crate) fn refresh(&mut self) -> bool {
if self.total_space != 0 {
unsafe {
Expand Down Expand Up @@ -239,12 +245,13 @@ pub(crate) unsafe fn get_list() -> Vec<Disk> {
}
let mut name = [0u16; MAX_PATH as usize + 1];
let mut file_system = [0u16; 32];
let mut flags = 0;
let volume_info_res = GetVolumeInformationW(
raw_volume_name,
Some(&mut name),
None,
None,
None,
Some(&mut flags),
Some(&mut file_system),
)
.is_ok();
Expand All @@ -255,6 +262,7 @@ pub(crate) unsafe fn get_list() -> Vec<Disk> {
);
return Vec::new();
}
let is_read_only = (flags & FILE_READ_ONLY_VOLUME) != 0;

let mount_paths = get_volume_path_names_for_volume_name(&volume_name[..]);
if mount_paths.is_empty() {
Expand Down Expand Up @@ -324,6 +332,7 @@ pub(crate) unsafe fn get_list() -> Vec<Disk> {
total_space,
available_space,
is_removable,
is_read_only,
},
})
.collect::<Vec<_>>()
Expand Down