MCPcopy Create free account
hub / github.com/PowerShell/DSC / run_process_async

Function run_process_async

lib/dsc-lib/src/dscresources/command_resource.rs:761–871  ·  view source on GitHub ↗

Asynchronously invoke a command and return the exit code, stdout, and stderr. # Arguments `executable` - The command to execute `args` - Optional arguments to pass to the command `input` - Optional input to pass to the command `cwd` - Optional working directory to execute the command in `env` - Optional environment variable mappings to add or update `exit_codes` - Descriptions of exit codes, eit

(executable: &str, args: Option<Vec<String>>, input: Option<&str>, cwd: Option<&Path>, env: Option<HashMap<String, String>>, exit_codes: &ExitCodesMap)

Source from the content-addressed store, hash-verified

759/// Error is returned if the command fails to execute or stdin/stdout/stderr cannot be opened.
760///
761async fn run_process_async(executable: &str, args: Option<Vec<String>>, input: Option<&str>, cwd: Option<&Path>, env: Option<HashMap<String, String>>, exit_codes: &ExitCodesMap) -> Result<(i32, String, String), DscError> {
762
763 // use somewhat large initial buffer to avoid early string reallocations;
764 // the value is based on list result of largest of built-in adapters - WMI adapter ~500KB
765 const INITIAL_BUFFER_CAPACITY: usize = 1024*1024;
766
767 let mut command = Command::new(executable);
768 if input.is_some() {
769 command.stdin(Stdio::piped());
770 } else {
771 command.stdin(Stdio::null());
772 }
773 command.stdout(Stdio::piped());
774 command.stderr(Stdio::piped());
775 if let Some(args) = args {
776 command.args(args);
777 }
778 if let Some(cwd) = cwd {
779 command.current_dir(cwd);
780 }
781 if let Some(env) = env {
782 command.envs(env);
783 }
784 if executable == "dsc" && env::var("DEBUG_DSC").is_ok() {
785 // remove this env var from child process as it will fail reading from keyboard to allow attaching
786 command.env_remove("DEBUG_DSC");
787 }
788
789 let mut child = match command.spawn() {
790 Ok(c) => c,
791 Err(e) => {
792 return Err(DscError::CommandOperation(e.to_string(), executable.to_string()))
793 }
794 };
795
796 let Some(stdout) = child.stdout.take() else {
797 return Err(DscError::CommandOperation(t!("dscresources.commandResource.processChildStdout").to_string(), executable.to_string()));
798 };
799 let Some(stderr) = child.stderr.take() else {
800 return Err(DscError::CommandOperation(t!("dscresources.commandResource.processChildStderr").to_string(), executable.to_string()));
801 };
802 let mut stdout_reader = BufReader::new(stdout).lines();
803 let mut stderr_reader = BufReader::new(stderr).lines();
804
805 if let Some(input) = input {
806 trace!("Writing to command STDIN: {input}");
807 let Some(mut stdin) = child.stdin.take() else {
808 return Err(DscError::CommandOperation(t!("dscresources.commandResource.processChildStdin").to_string(), executable.to_string()));
809 };
810 if stdin.write_all(input.as_bytes()).await.is_err() {
811 return Err(DscError::CommandOperation(t!("dscresources.commandResource.processWriteStdin").to_string(), executable.to_string()));
812 }
813 drop(stdin);
814 }
815
816 let Some(child_id) = child.id() else {
817 return Err(DscError::CommandOperation(t!("dscresources.commandResource.processChildId").to_string(), executable.to_string()));
818 };

Callers 1

invoke_commandFunction · 0.85

Calls 7

log_stderr_lineFunction · 0.85
CommandEnum · 0.85
is_empty_or_defaultMethod · 0.80
get_codeMethod · 0.80
newFunction · 0.50
with_capacityFunction · 0.50
is_emptyMethod · 0.45

Tested by

no test coverage detected