procfs_core/process/
syscall.rs

1use crate::{from_iter, from_iter_radix, ProcResult};
2#[cfg(feature = "serde1")]
3use serde::{Deserialize, Serialize};
4
5use std::io::Read;
6
7/// Syscall information about the process, based on the `/proc/<pid>/syscall` file.
8///
9/// New variants to this enum may be added at any time (even without a major or minor semver bump).
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
12#[non_exhaustive]
13pub enum Syscall {
14    /// The process is running, and so the values are not present
15    Running,
16    Blocked {
17        /// The syscall this process is blocked on.
18        /// If the syscall_number is -1, then not blocked on a syscall (blocked for another reason).
19        /// Note that the rest of the values are still filled in.
20        syscall_number: i64,
21        /// The argument registers
22        argument_registers: [u64; 6],
23        /// e.g. rsp
24        stack_pointer: u64,
25        /// e.g. rip
26        program_counter: u64,
27    },
28}
29
30impl crate::FromRead for Syscall {
31    fn from_read<R: Read>(mut r: R) -> ProcResult<Self> {
32        // read in entire thing, this is only going to be 1 line
33        let mut buf = Vec::with_capacity(512);
34        r.read_to_end(&mut buf)?;
35
36        let line = String::from_utf8_lossy(&buf);
37        let buf = line.trim();
38
39        if buf == "running" {
40            Ok(Self::Running)
41        } else {
42            let mut values = buf.split(' ');
43
44            let syscall_number: i64 = expect!(from_iter(&mut values), "failed to read syscall number");
45
46            let mut argument_registers: [u64; 6] = [0; 6];
47            for arg_reg in argument_registers.iter_mut() {
48                *arg_reg = expect!(from_iter_radix(&mut values, 16), "failed to read argument register");
49            }
50
51            let stack_pointer: u64 = expect!(from_iter_radix(&mut values, 16), "failed to read stack pointer");
52            let program_counter: u64 = expect!(from_iter_radix(&mut values, 16), "failed to read program counter");
53
54            Ok(Self::Blocked {
55                syscall_number,
56                argument_registers,
57                stack_pointer,
58                program_counter,
59            })
60        }
61    }
62}