1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//! Contains functions about /proc/self.
//!
//! There is no item named self in this crate, because self is a key word in rust, so we use _self instead.

use std::path::PathBuf;

type Result<T> = std::result::Result<T, crate::ProcErr>;

/// Return an PathBuf which /proc/self point to.
///
/// The returnd value should be same as `ls -l /proc/self`.
///
/// There is not self() function in this crate, because self is a key word in rust.
pub fn _self() -> Result<PathBuf> {
    Ok(std::fs::read_link("/proc/self")?)
}

/// Return the process ID (pid) of calling process.
///
/// This should have the same output of [`getpid()`](http://man7.org/linux/man-pages/man2/getpid.2.html]),
/// but it is a safe method.
///
/// *Note: std::process::id() have same behavior.*
pub fn self_pid() -> Result<u32> {
    let path = std::fs::read_link("/proc/self")?;
    let pid_str = path.display().to_string();
    let pid = pid_str.parse::<u32>()?;
    Ok(pid)
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_self_self_pid() {
        println!("/proc/self point to {:?}", _self().unwrap());
        println!("current pid is {:?}", self_pid().unwrap());
    }

    #[test]
    fn test_self_pid() {
        let pid = unsafe { libc::getpid() } as u32;
        assert_eq!(pid, self_pid().unwrap())
    }
}