Skip to content

Commit ba19a23

Browse files
committed
Added parser for /proc/<pid>/environ
1 parent 32aa416 commit ba19a23

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ currently the following interfaces are provided:
1515

1616
* `/proc/loadavg`
1717
* `/proc/<pid>/cwd`
18+
* `/proc/<pid>/environ`
1819
* `/proc/<pid>/limits`
1920
* `/proc/<pid>/mountinfo`
2021
* `/proc/<pid>/stat`

src/pid/environ.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//! Process initial environment from `/proc/[pid]/environ`.
2+
3+
use std::collections::BTreeMap;
4+
use std::fs::{File, metadata};
5+
use std::io::{Result, Read};
6+
use std::path::Path;
7+
8+
use parsers::map_result;
9+
use nom::IResult;
10+
11+
use libc::pid_t;
12+
13+
/// Parses the provided buffer.
14+
fn parse_environ(input: &[u8]) -> IResult<&[u8], BTreeMap<Vec<u8>, Vec<u8>>> {
15+
// Parse 'key=value" pair.
16+
named!(
17+
pair<&[u8], (&[u8], &[u8])>,
18+
tuple!(take_until_and_consume!("="), take_until!("\0"))
19+
);
20+
// Parse (key=value\0) list.
21+
named!(
22+
multi<&[u8],Vec<(&[u8], &[u8])> >,
23+
terminated!(
24+
separated_list!(tag!("\0"), pair),
25+
tag!("\0")
26+
)
27+
);
28+
multi(input).map(|r| {
29+
r.into_iter()
30+
.map(|(x, y)| (x.to_vec(), y.to_vec()))
31+
.collect()
32+
})
33+
}
34+
35+
#[test]
36+
fn test_parse() {
37+
use nom::IResult::Done;
38+
let res = parse_environ(&b"key1=val1\0key2=val2\0"[..]);
39+
let reference = vec![
40+
(b"key1".to_vec(), b"val1".to_vec()),
41+
(b"key2".to_vec(), b"val2".to_vec()),
42+
];
43+
assert_eq!(res, Done(&b""[..], reference.into_iter().collect()));
44+
}
45+
46+
/// Parses the provided environ file.
47+
fn environ_path<P: AsRef<Path>>(path: P) -> Result<BTreeMap<Vec<u8>, Vec<u8>>> {
48+
let file_size = metadata(&path)?.len();
49+
let mut buf = vec![0u8; file_size as usize];
50+
File::open(path)?.read_exact(&mut buf)?;
51+
map_result(parse_environ(&buf))
52+
}
53+
54+
/// Returns initial environment for the process with the provided pid in the form of 'key' =>
55+
/// 'value' BTreeMap.
56+
pub fn environ(pid: pid_t) -> Result<BTreeMap<Vec<u8>, Vec<u8>>> {
57+
environ_path(format!("/proc/{}/environ", pid))
58+
}
59+
60+
/// Returns initial environment for the current process in the form of 'key' => 'value' BTreeMap.
61+
pub fn environ_self() -> Result<BTreeMap<Vec<u8>, Vec<u8>>> {
62+
environ_path("/proc/self/environ")
63+
}

src/pid/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ mod mountinfo;
66
mod stat;
77
mod statm;
88
mod status;
9+
mod environ;
910

1011
pub use pid::cwd::{cwd, cwd_self};
1112
pub use pid::limits::{Limit, Limits, limits, limits_self};
1213
pub use pid::mountinfo::{Mountinfo, mountinfo, mountinfo_self};
1314
pub use pid::statm::{Statm, statm, statm_self};
1415
pub use pid::status::{SeccompMode, Status, status, status_self};
1516
pub use pid::stat::{Stat, stat, stat_self};
17+
pub use pid::environ::{environ, environ_self};
1618

1719
/// The state of a process.
1820
#[derive(Debug, PartialEq, Eq, Hash)]

0 commit comments

Comments
 (0)