pyc_shell/shell/proc/
mod.rs

1//! ## Proc
2//!
3//! `Proc` is the module which takes care of executing processes and handling the process execution
4
5/*
6*
7*   Copyright (C) 2020 Christian Visintin - christian.visintin1997@gmail.com
8*
9* 	This file is part of "Pyc"
10*
11*   Pyc is free software: you can redistribute it and/or modify
12*   it under the terms of the GNU General Public License as published by
13*   the Free Software Foundation, either version 3 of the License, or
14*   (at your option) any later version.
15*
16*   Pyc is distributed in the hope that it will be useful,
17*   but WITHOUT ANY WARRANTY; without even the implied warranty of
18*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19*   GNU General Public License for more details.
20*
21*   You should have received a copy of the GNU General Public License
22*   along with Pyc.  If not, see <http://www.gnu.org/licenses/>.
23*
24*/
25
26extern crate nix;
27
28mod pipe;
29pub mod process;
30
31use std::path::PathBuf;
32use std::time::{Duration, Instant};
33
34use pipe::Pipe;
35
36//Proc has a thread which runs the subprocess of the shell and 3 pipes (stdout, stdin, stderr). It must provides the function to write and to read
37
38/// ### ShellProcState
39///
40/// ShellProcState represents the current shell state
41#[derive(Copy, Clone, PartialEq, std::fmt::Debug)]
42pub enum ShellProcState {
43    Idle,
44    SubprocessRunning,
45    Terminated
46}
47
48/// ### ShellError
49///
50/// ShellError represents an error caused by shell module
51#[derive(Copy, Clone, PartialEq, std::fmt::Debug)]
52pub enum ShellError {
53    CouldNotStartProcess,
54    InvalidData,
55    IoTimeout,
56    ShellRunning,
57    ShellTerminated,
58    CouldNotKill,
59    PipeError(nix::errno::Errno)
60}
61
62/// ### ShellProc
63/// 
64/// Shell Proc represents an instance of the shell process wrapper
65#[derive(std::fmt::Debug)]
66pub struct ShellProc {
67    pub state: ShellProcState,                  //Shell process state
68    pub exit_status: u8,                    //Exit status of the subprocess (child of shell)
69    pub pid: i32,                           //Shell pid
70    pub wrkdir: PathBuf,                    //Working directory
71    pub exec_time: Duration,                //Execution time of the last command
72    //Private
73    rc: u8,                                 //Return code of the shell process
74    uuid: String,                           //UUID used for handshake with the shell
75    start_time: Instant,                    //Instant when the last command was started
76    stdout_cache: Option<String>,           //Used to prevent buffer fragmentation
77    echo_command: String,                   //Echo command
78    //Pipes
79    stdin_pipe: Pipe,
80    stdout_pipe: Pipe,
81    stderr_pipe: Pipe
82}
83
84impl std::fmt::Display for ShellError {
85    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
86        let code_str: String = match self {
87            ShellError::CouldNotStartProcess => String::from("Could not start process"),
88            ShellError::InvalidData => String::from("Invalid data from process"),
89            ShellError::IoTimeout => String::from("I/O timeout"),
90            ShellError::ShellTerminated => String::from("Shell has terminated"),
91            ShellError::ShellRunning => String::from("Tried to clean shell up while still running"),
92            ShellError::CouldNotKill => String::from("Could not send signal to shell process"),
93            ShellError::PipeError(errno) => format!("Pipe error: {}", errno),
94        };
95        write!(f, "{}", code_str)
96    }
97}
98
99//@! Test module
100
101#[cfg(test)]
102mod tests {
103
104    use super::*;
105
106    #[test]
107    fn test_proc_fmt_shell_error() {
108        assert_eq!(format!("{}", ShellError::CouldNotStartProcess), String::from("Could not start process"));
109        assert_eq!(format!("{}", ShellError::InvalidData), String::from("Invalid data from process"));
110        assert_eq!(format!("{}", ShellError::IoTimeout), String::from("I/O timeout"));
111        assert_eq!(format!("{}", ShellError::ShellTerminated), String::from("Shell has terminated"));
112        assert_eq!(format!("{}", ShellError::ShellRunning), String::from("Tried to clean shell up while still running"));
113        assert_eq!(format!("{}", ShellError::CouldNotKill), String::from("Could not send signal to shell process"));
114        assert_eq!(format!("{}", ShellError::PipeError(nix::errno::Errno::EACCES)), format!("Pipe error: {}", nix::errno::Errno::EACCES));
115    }
116
117}