unsupported.rs - source
Description: Source of the Rust file `library/std/src/sys/process/unsupported.rs`.

#
std/sys/process/
unsupported.rs

    1use super::env::{CommandEnv, CommandEnvs};
    2pub use crate::ffi::OsString as EnvKey;
    3use crate::ffi::{OsStr, OsString};
    4use crate::num::NonZero;
    5use crate::path::Path;
    6use crate::process::StdioPipes;
    7use crate::sys::fs::File;
    8use crate::sys::unsupported;
    9use crate::{fmt, io};
    10
    11////////////////////////////////////////////////////////////////////////////////
    12// Command
    13////////////////////////////////////////////////////////////////////////////////
    14
    15pub struct Command {
    16    program: OsString,
    17    args: Vec<OsString>,
    18    env: CommandEnv,
    19
    20    cwd: Option<OsString>,
    21    stdin: Option<Stdio>,
    22    stdout: Option<Stdio>,
    23    stderr: Option<Stdio>,
    24}
    25
    26#[derive(Debug)]
    27pub enum Stdio {
    28    Inherit,
    29    Null,
    30    MakePipe,
    31    ParentStdout,
    32    ParentStderr,
    33    #[allow(dead_code)] // This variant exists only for the Debug impl
    34    InheritFile(File),
    35}
    36
    37impl Command {
    38    pub fn new(program: &OsStr) -> Command {
    39        Command {
    40            program: program.to_owned(),
    41            args: vec![program.to_owned()],
    42            env: Default::default(),
    43            cwd: None,
    44            stdin: None,
    45            stdout: None,
    46            stderr: None,
    47        }
    48    }
    49
    50    pub fn arg(&mut self, arg: &OsStr) {
    51        self.args.push(arg.to_owned());
    52    }
    53
    54    pub fn env_mut(&mut self) -> &mut CommandEnv {
    55        &mut self.env
    56    }
    57
    58    pub fn cwd(&mut self, dir: &OsStr) {
    59        self.cwd = Some(dir.to_owned());
    60    }
    61
    62    pub fn stdin(&mut self, stdin: Stdio) {
    63        self.stdin = Some(stdin);
    64    }
    65
    66    pub fn stdout(&mut self, stdout: Stdio) {
    67        self.stdout = Some(stdout);
    68    }
    69
    70    pub fn stderr(&mut self, stderr: Stdio) {
    71        self.stderr = Some(stderr);
    72    }
    73
    74    pub fn get_program(&self) -> &OsStr {
    75        &self.program
    76    }
    77
    78    pub fn get_args(&self) -> CommandArgs<'_> {
    79        let mut iter = self.args.iter();
    80        iter.next();
    81        CommandArgs { iter }
    82    }
    83
    84    pub fn get_envs(&self) -> CommandEnvs<'_> {
    85        self.env.iter()
    86    }
    87
    88    pub fn get_env_clear(&self) -> bool {
    89        self.env.does_clear()
    90    }
    91
    92    pub fn get_current_dir(&self) -> Option<&Path> {
    93        self.cwd.as_ref().map(|cs| Path::new(cs))
    94    }
    95
    96    pub fn spawn(
    97        &mut self,
    98        _default: Stdio,
    99        _needs_stdin: bool,
    100    ) -> io::Result<(Process, StdioPipes)> {
    101        unsupported()
    102    }
    103}
    104
    105pub fn output(_cmd: &mut Command) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
    106    unsupported()
    107}
    108
    109impl From<ChildPipe> for Stdio {
    110    fn from(pipe: ChildPipe) -> Stdio {
    111        pipe.diverge()
    112    }
    113}
    114
    115impl From<io::Stdout> for Stdio {
    116    fn from(_: io::Stdout) -> Stdio {
    117        Stdio::ParentStdout
    118    }
    119}
    120
    121impl From<io::Stderr> for Stdio {
    122    fn from(_: io::Stderr) -> Stdio {
    123        Stdio::ParentStderr
    124    }
    125}
    126
    127impl From<File> for Stdio {
    128    fn from(file: File) -> Stdio {
    129        Stdio::InheritFile(file)
    130    }
    131}
    132
    133impl fmt::Debug for Command {
    134    // show all attributes
    135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    136        if f.alternate() {
    137            let mut debug_command = f.debug_struct("Command");
    138            debug_command.field("program", &self.program).field("args", &self.args);
    139            if !self.env.is_unchanged() {
    140                debug_command.field("env", &self.env);
    141            }
    142
    143            if self.cwd.is_some() {
    144                debug_command.field("cwd", &self.cwd);
    145            }
    146
    147            if self.stdin.is_some() {
    148                debug_command.field("stdin", &self.stdin);
    149            }
    150            if self.stdout.is_some() {
    151                debug_command.field("stdout", &self.stdout);
    152            }
    153            if self.stderr.is_some() {
    154                debug_command.field("stderr", &self.stderr);
    155            }
    156
    157            debug_command.finish()
    158        } else {
    159            if let Some(ref cwd) = self.cwd {
    160                write!(f, "cd {cwd:?} && ")?;
    161            }
    162            if self.env.does_clear() {
    163                write!(f, "env -i ")?;
    164                // Altered env vars will be printed next, that should exactly work as expected.
    165            } else {
    166                // Removed env vars need the command to be wrapped in `env`.
    167                let mut any_removed = false;
    168                for (key, value_opt) in self.get_envs() {
    169                    if value_opt.is_none() {
    170                        if !any_removed {
    171                            write!(f, "env ")?;
    172                            any_removed = true;
    173                        }
    174                        write!(f, "-u {} ", key.to_string_lossy())?;
    175                    }
    176                }
    177            }
    178            // Altered env vars can just be added in front of the program.
    179            for (key, value_opt) in self.get_envs() {
    180                if let Some(value) = value_opt {
    181                    write!(f, "{}={value:?} ", key.to_string_lossy())?;
    182                }
    183            }
    184            if self.program != self.args[0] {
    185                write!(f, "[{:?}] ", self.program)?;
    186            }
    187            write!(f, "{:?}", self.args[0])?;
    188
    189            for arg in &self.args[1..] {
    190                write!(f, " {:?}", arg)?;
    191            }
    192            Ok(())
    193        }
    194    }
    195}
    196
    197#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
    198#[non_exhaustive]
    199pub struct ExitStatus();
    200
    201impl ExitStatus {
    202    pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
    203        Ok(())
    204    }
    205
    206    pub fn code(&self) -> Option<i32> {
    207        Some(0)
    208    }
    209}
    210
    211impl fmt::Display for ExitStatus {
    212    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    213        write!(f, "<dummy exit status>")
    214    }
    215}
    216
    217pub struct ExitStatusError(!);
    218
    219impl Clone for ExitStatusError {
    220    fn clone(&self) -> ExitStatusError {
    221        self.0
    222    }
    223}
    224
    225impl Copy for ExitStatusError {}
    226
    227impl PartialEq for ExitStatusError {
    228    fn eq(&self, _other: &ExitStatusError) -> bool {
    229        self.0
    230    }
    231}
    232
    233impl Eq for ExitStatusError {}
    234
    235impl fmt::Debug for ExitStatusError {
    236    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
    237        self.0
    238    }
    239}
    240
    241impl Into<ExitStatus> for ExitStatusError {
    242    fn into(self) -> ExitStatus {
    243        self.0
    244    }
    245}
    246
    247impl ExitStatusError {
    248    pub fn code(self) -> Option<NonZero<i32>> {
    249        self.0
    250    }
    251}
    252
    253#[derive(PartialEq, Eq, Clone, Copy, Debug)]
    254pub struct ExitCode(u8);
    255
    256impl ExitCode {
    257    pub const SUCCESS: ExitCode = ExitCode(0);
    258    pub const FAILURE: ExitCode = ExitCode(1);
    259
    260    pub fn as_i32(&self) -> i32 {
    261        self.0 as i32
    262    }
    263}
    264
    265impl From<u8> for ExitCode {
    266    fn from(code: u8) -> Self {
    267        Self(code)
    268    }
    269}
    270
    271pub struct Process(!);
    272
    273impl Process {
    274    pub fn id(&self) -> u32 {
    275        self.0
    276    }
    277
    278    pub fn kill(&mut self) -> io::Result<()> {
    279        self.0
    280    }
    281
    282    pub fn wait(&mut self) -> io::Result<ExitStatus> {
    283        self.0
    284    }
    285
    286    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
    287        self.0
    288    }
    289}
    290
    291pub struct CommandArgs<'a> {
    292    iter: crate::slice::Iter<'a, OsString>,
    293}
    294
    295impl<'a> Iterator for CommandArgs<'a> {
    296    type Item = &'a OsStr;
    297    fn next(&mut self) -> Option<&'a OsStr> {
    298        self.iter.next().map(|os| &**os)
    299    }
    300    fn size_hint(&self) -> (usize, Option<usize>) {
    301        self.iter.size_hint()
    302    }
    303}
    304
    305impl<'a> ExactSizeIterator for CommandArgs<'a> {
    306    fn len(&self) -> usize {
    307        self.iter.len()
    308    }
    309    fn is_empty(&self) -> bool {
    310        self.iter.is_empty()
    311    }
    312}
    313
    314impl<'a> fmt::Debug for CommandArgs<'a> {
    315    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    316        f.debug_list().entries(self.iter.clone()).finish()
    317    }
    318}
    319
    320pub type ChildPipe = crate::sys::pipe::Pipe;
    321
    322pub fn read_output(
    323    out: ChildPipe,
    324    _stdout: &mut Vec<u8>,
    325    _err: ChildPipe,
    326    _stderr: &mut Vec<u8>,
    327) -> io::Result<()> {
    328    match out.diverge() {}
    329}