Skip to content

Commit 432e8c2

Browse files
authored
Merge pull request #357 from eminence/fix_pasta_mountinfo
Fix parsing for mountinfo and related fields when presented with empty fields
2 parents d618111 + bffec12 commit 432e8c2

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

procfs-core/src/mounts.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl super::FromBufRead for Vec<MountEntry> {
3131

3232
for line in r.lines() {
3333
let line = expect!(line);
34-
let mut s = line.split_whitespace();
34+
let mut s = line.split(' '); // not using split_whitespace because we might have empty fields
3535

3636
let fs_spec = unmangle_octal(expect!(s.next()));
3737
let fs_file = unmangle_octal(expect!(s.next()));
@@ -104,4 +104,13 @@ Downloads /media/sf_downloads vboxsf rw,nodev,relatime,iocharset=utf8,uid=0,gid=
104104
let cursor = Cursor::new(s);
105105
let mounts = Vec::<MountEntry>::from_buf_read(cursor).unwrap();
106106
assert_eq!(mounts.len(), 4);
107+
108+
// https://github.com/eminence/procfs/issues/333
109+
let s = " / tmpfs ro,nosuid,nodev,noexec,relatime,size=0k,nr_inodes=2,uid=1000,gid=1000,inode64 0 0";
110+
let mounts = Vec::<MountEntry>::from_buf_read(Cursor::new(s)).unwrap();
111+
assert_eq!(mounts.len(), 1);
112+
assert_eq!(mounts[0].fs_spec, "");
113+
assert_eq!(mounts[0].fs_file, "/");
114+
assert_eq!(mounts[0].fs_vfstype, "tmpfs");
115+
assert!(mounts[0].fs_mntops.contains_key("ro"));
107116
}

procfs-core/src/process/mount.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ pub struct MountInfo {
128128

129129
impl MountInfo {
130130
pub fn from_line(line: &str) -> ProcResult<MountInfo> {
131-
let mut split = line.split_whitespace();
131+
let mut split = line.split(' '); // not using split_whitespace because we might have empty fields
132132

133133
let mnt_id = expect!(from_iter(&mut split));
134134
let pid = expect!(from_iter(&mut split));
@@ -173,7 +173,7 @@ impl MountInfo {
173173
}
174174
let fs_type: String = expect!(from_iter(&mut split));
175175
let mount_source = match expect!(split.next()) {
176-
"none" => None,
176+
"none" | "" => None,
177177
x => Some(x.to_owned()),
178178
};
179179
let super_options = {
@@ -248,7 +248,7 @@ impl crate::FromBufRead for MountStats {
248248
if line.starts_with("device ") {
249249
// line will be of the format:
250250
// device proc mounted on /proc with fstype proc
251-
let mut s = line.split_whitespace();
251+
let mut s = line.split(' '); // not splitwhitespace because we can have some empty fields
252252

253253
let device = Some(expect!(s.nth(1)).to_owned());
254254
let mount_point = PathBuf::from(expect!(s.nth(2)));
@@ -589,6 +589,18 @@ mod tests {
589589
println!("{:?}", stat);
590590
}
591591

592+
#[test]
593+
fn test_mountinfo_pasta() {
594+
// See https://github.com/eminence/procfs/issues/333
595+
let s =
596+
"303 98 0:47 / / ro,nosuid,nodev,noexec,relatime - tmpfs ro,size=0k,nr_inodes=2,uid=1000,gid=1000,inode64";
597+
598+
let stat = MountInfo::from_line(s).unwrap();
599+
assert_eq!(stat.fs_type, "tmpfs");
600+
assert_eq!(stat.mount_source, None);
601+
assert_eq!(stat.super_options.get("ro"), Some(&None));
602+
}
603+
592604
#[test]
593605
fn test_proc_mountstats() {
594606
let MountStats(simple) = FromRead::from_read(
@@ -651,5 +663,12 @@ device tmpfs mounted on /run/user/0 with fstype tmpfs
651663
panic!("Failed to retrieve nfs statistics");
652664
}
653665
}
666+
667+
// https://github.com/eminence/procfs/issues/333
668+
let MountStats(stats) = FromRead::from_read("device mounted on / with fstype tmpfs".as_bytes()).unwrap();
669+
assert_eq!(stats[0].device, Some("".to_string()));
670+
assert_eq!(stats[0].mount_point, PathBuf::from("/"));
671+
assert_eq!(stats[0].fs, "tmpfs");
672+
assert_eq!(stats[0].statistics, None);
654673
}
655674
}

0 commit comments

Comments
 (0)