1 use crate::ffi::OsStr; 2 use crate::fmt; 3 use crate::io; 4 use crate::marker::PhantomData; 5 use crate::num::NonZeroI32; 6 use crate::path::Path; 7 use crate::sys::fs::File; 8 use crate::sys::pipe::AnonPipe; 9 use crate::sys::unsupported; 10 use crate::sys_common::process::{CommandEnv, CommandEnvs}; 11 12 pub use crate::ffi::OsString as EnvKey; 13 14 //////////////////////////////////////////////////////////////////////////////// 15 // Command 16 //////////////////////////////////////////////////////////////////////////////// 17 18 pub struct Command { 19 env: CommandEnv, 20 } 21 22 // passed back to std::process with the pipes connected to the child, if any 23 // were requested 24 pub struct StdioPipes { 25 pub stdin: Option<AnonPipe>, 26 pub stdout: Option<AnonPipe>, 27 pub stderr: Option<AnonPipe>, 28 } 29 30 pub enum Stdio { 31 Inherit, 32 Null, 33 MakePipe, 34 } 35 36 impl Command { new(_program: &OsStr) -> Command37 pub fn new(_program: &OsStr) -> Command { 38 Command { env: Default::default() } 39 } 40 arg(&mut self, _arg: &OsStr)41 pub fn arg(&mut self, _arg: &OsStr) {} 42 env_mut(&mut self) -> &mut CommandEnv43 pub fn env_mut(&mut self) -> &mut CommandEnv { 44 &mut self.env 45 } 46 cwd(&mut self, _dir: &OsStr)47 pub fn cwd(&mut self, _dir: &OsStr) {} 48 stdin(&mut self, _stdin: Stdio)49 pub fn stdin(&mut self, _stdin: Stdio) {} 50 stdout(&mut self, _stdout: Stdio)51 pub fn stdout(&mut self, _stdout: Stdio) {} 52 stderr(&mut self, _stderr: Stdio)53 pub fn stderr(&mut self, _stderr: Stdio) {} 54 get_program(&self) -> &OsStr55 pub fn get_program(&self) -> &OsStr { 56 panic!("unsupported") 57 } 58 get_args(&self) -> CommandArgs<'_>59 pub fn get_args(&self) -> CommandArgs<'_> { 60 CommandArgs { _p: PhantomData } 61 } 62 get_envs(&self) -> CommandEnvs<'_>63 pub fn get_envs(&self) -> CommandEnvs<'_> { 64 self.env.iter() 65 } 66 get_current_dir(&self) -> Option<&Path>67 pub fn get_current_dir(&self) -> Option<&Path> { 68 None 69 } 70 spawn( &mut self, _default: Stdio, _needs_stdin: bool, ) -> io::Result<(Process, StdioPipes)>71 pub fn spawn( 72 &mut self, 73 _default: Stdio, 74 _needs_stdin: bool, 75 ) -> io::Result<(Process, StdioPipes)> { 76 unsupported() 77 } 78 } 79 80 impl From<AnonPipe> for Stdio { from(pipe: AnonPipe) -> Stdio81 fn from(pipe: AnonPipe) -> Stdio { 82 pipe.diverge() 83 } 84 } 85 86 impl From<File> for Stdio { from(_file: File) -> Stdio87 fn from(_file: File) -> Stdio { 88 panic!("unsupported") 89 } 90 } 91 92 impl fmt::Debug for Command { fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result93 fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { 94 Ok(()) 95 } 96 } 97 98 pub struct ExitStatus(!); 99 100 impl ExitStatus { exit_ok(&self) -> Result<(), ExitStatusError>101 pub fn exit_ok(&self) -> Result<(), ExitStatusError> { 102 self.0 103 } 104 code(&self) -> Option<i32>105 pub fn code(&self) -> Option<i32> { 106 self.0 107 } 108 } 109 110 impl Clone for ExitStatus { clone(&self) -> ExitStatus111 fn clone(&self) -> ExitStatus { 112 self.0 113 } 114 } 115 116 impl Copy for ExitStatus {} 117 118 impl PartialEq for ExitStatus { eq(&self, _other: &ExitStatus) -> bool119 fn eq(&self, _other: &ExitStatus) -> bool { 120 self.0 121 } 122 } 123 124 impl Eq for ExitStatus {} 125 126 impl fmt::Debug for ExitStatus { fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result127 fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { 128 self.0 129 } 130 } 131 132 impl fmt::Display for ExitStatus { fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result133 fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { 134 self.0 135 } 136 } 137 138 #[derive(PartialEq, Eq, Clone, Copy, Debug)] 139 pub struct ExitStatusError(ExitStatus); 140 141 impl Into<ExitStatus> for ExitStatusError { into(self) -> ExitStatus142 fn into(self) -> ExitStatus { 143 self.0.0 144 } 145 } 146 147 impl ExitStatusError { code(self) -> Option<NonZeroI32>148 pub fn code(self) -> Option<NonZeroI32> { 149 self.0.0 150 } 151 } 152 153 #[derive(PartialEq, Eq, Clone, Copy, Debug)] 154 pub struct ExitCode(bool); 155 156 impl ExitCode { 157 pub const SUCCESS: ExitCode = ExitCode(false); 158 pub const FAILURE: ExitCode = ExitCode(true); 159 as_i32(&self) -> i32160 pub fn as_i32(&self) -> i32 { 161 self.0 as i32 162 } 163 } 164 165 pub struct Process(!); 166 167 impl Process { id(&self) -> u32168 pub fn id(&self) -> u32 { 169 self.0 170 } 171 kill(&mut self) -> io::Result<()>172 pub fn kill(&mut self) -> io::Result<()> { 173 self.0 174 } 175 wait(&mut self) -> io::Result<ExitStatus>176 pub fn wait(&mut self) -> io::Result<ExitStatus> { 177 self.0 178 } 179 try_wait(&mut self) -> io::Result<Option<ExitStatus>>180 pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { 181 self.0 182 } 183 } 184 185 pub struct CommandArgs<'a> { 186 _p: PhantomData<&'a ()>, 187 } 188 189 impl<'a> Iterator for CommandArgs<'a> { 190 type Item = &'a OsStr; next(&mut self) -> Option<&'a OsStr>191 fn next(&mut self) -> Option<&'a OsStr> { 192 None 193 } 194 } 195 196 impl<'a> ExactSizeIterator for CommandArgs<'a> {} 197 198 impl<'a> fmt::Debug for CommandArgs<'a> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 200 f.debug_list().finish() 201 } 202 } 203