Skip to content

Commit d709179

Browse files
committed
fs: create mntent.h wrapper
1 parent 592f940 commit d709179

File tree

3 files changed

+139
-0
lines changed

3 files changed

+139
-0
lines changed

fs/df.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
// SPDX-License-Identifier: MIT
88
//
99

10+
#[cfg(target_os = "linux")]
11+
mod mntent;
12+
1013
use clap::Parser;
1114
use gettextrs::{bind_textdomain_codeset, gettext, setlocale, textdomain, LocaleCategory};
1215
use plib::PROJECT_NAME;

fs/mntent.rs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
//
2+
// Copyright (c) 2024 fox0
3+
//
4+
// This file is part of the posixutils-rs project covered under
5+
// the MIT License. For the full license text, please see the LICENSE
6+
// file in the root directory of this project.
7+
// SPDX-License-Identifier: MIT
8+
//
9+
10+
//! The mtab file
11+
//! https://www.gnu.org/software/libc/manual/html_node/mtab.html
12+
13+
use libc::{endmntent, getmntent, setmntent, FILE};
14+
use std::ffi::{CStr, CString};
15+
use std::io;
16+
use std::sync::Mutex;
17+
18+
const _PATH_MOUNTED: &CStr = c"/etc/mtab";
19+
20+
/// The mtab (contraction of mounted file systems table) file
21+
/// is a system information file, commonly found on Unix-like systems
22+
pub struct MountTable {
23+
inner: *mut FILE,
24+
}
25+
26+
/// Structure describing a mount table entry
27+
#[derive(Debug, PartialEq)]
28+
pub struct MountTableEntity {
29+
/// Device or server for filesystem
30+
pub fsname: CString,
31+
/// Directory mounted on
32+
pub dir: CString,
33+
/// Type of filesystem: ufs, nfs, etc
34+
pub fstype: CString,
35+
/// Comma-separated options for fs
36+
pub opts: CString,
37+
/// Dump frequency (in days)
38+
pub freq: i32,
39+
/// Pass number for `fsck``
40+
pub passno: i32,
41+
}
42+
43+
impl MountTable {
44+
pub fn try_new() -> Result<Self, io::Error> {
45+
Self::open(_PATH_MOUNTED, c"r")
46+
}
47+
48+
/// Open mtab file
49+
fn open(filename: &CStr, mode: &CStr) -> Result<Self, io::Error> {
50+
// Preliminary: | MT-Safe | AS-Unsafe heap lock | AC-Unsafe mem fd lock
51+
// https://www.gnu.org/software/libc/manual/html_node/POSIX-Safety-Concepts.html
52+
let inner = unsafe { setmntent(filename.as_ptr(), mode.as_ptr()) };
53+
if inner.is_null() {
54+
return Err(io::Error::last_os_error());
55+
}
56+
Ok(Self { inner })
57+
}
58+
}
59+
60+
impl Iterator for MountTable {
61+
type Item = MountTableEntity;
62+
63+
fn next(&mut self) -> Option<Self::Item> {
64+
static THREAD_UNSAFE_FUNCTION_MUTEX: Mutex<()> = Mutex::new(());
65+
let _lock = THREAD_UNSAFE_FUNCTION_MUTEX.lock().unwrap();
66+
67+
// Preliminary: | MT-Unsafe race:mntentbuf locale | AS-Unsafe corrupt heap init | AC-Unsafe init corrupt lock mem
68+
// https://www.gnu.org/software/libc/manual/html_node/POSIX-Safety-Concepts.html
69+
let me = unsafe { getmntent(self.inner) };
70+
if me.is_null() {
71+
return None;
72+
}
73+
74+
unsafe {
75+
Some(MountTableEntity {
76+
fsname: CStr::from_ptr((*me).mnt_fsname).into(),
77+
dir: CStr::from_ptr((*me).mnt_dir).into(),
78+
fstype: CStr::from_ptr((*me).mnt_type).into(),
79+
opts: CStr::from_ptr((*me).mnt_opts).into(),
80+
freq: (*me).mnt_freq,
81+
passno: (*me).mnt_passno,
82+
})
83+
}
84+
}
85+
}
86+
87+
impl Drop for MountTable {
88+
/// Close mtab file
89+
fn drop(&mut self) {
90+
// Preliminary: | MT-Safe | AS-Unsafe heap lock | AC-Unsafe lock mem fd
91+
// https://www.gnu.org/software/libc/manual/html_node/POSIX-Safety-Concepts.html
92+
let _rc = unsafe { endmntent(self.inner) };
93+
}
94+
}
95+
96+
#[cfg(test)]
97+
mod tests {
98+
use super::*;
99+
100+
#[test]
101+
fn test_open() {
102+
let mtab = MountTable::open(c"tests/mtab.txt", c"r");
103+
assert!(mtab.is_ok());
104+
}
105+
106+
#[test]
107+
fn test_iterable() {
108+
let mtab = MountTable::open(c"tests/mtab.txt", c"r").unwrap();
109+
let vec = Vec::from_iter(mtab);
110+
assert_eq!(vec.len(), 2);
111+
assert_eq!(
112+
vec[0],
113+
MountTableEntity {
114+
fsname: CString::new("/dev/sdb1").unwrap(),
115+
dir: CString::new("/").unwrap(),
116+
fstype: CString::new("ext3").unwrap(),
117+
opts: CString::new("rw,relatime,errors=remount-ro").unwrap(),
118+
freq: 0,
119+
passno: 0,
120+
}
121+
);
122+
assert_eq!(
123+
vec[1],
124+
MountTableEntity {
125+
fsname: CString::new("proc").unwrap(),
126+
dir: CString::new("/proc").unwrap(),
127+
fstype: CString::new("proc").unwrap(),
128+
opts: CString::new("rw,noexec,nosuid,nodev").unwrap(),
129+
freq: 0,
130+
passno: 0,
131+
}
132+
);
133+
}
134+
}

fs/tests/mtab.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/dev/sdb1 / ext3 rw,relatime,errors=remount-ro 0 0
2+
proc /proc proc rw,noexec,nosuid,nodev 0 0

0 commit comments

Comments
 (0)