MCPcopy Index your code
hub / github.com/enowdev/enowX-Coder / run_command

Method run_command

src-tauri/src/tools/executor.rs:404–547  ·  view source on GitHub ↗
(&self, input: &serde_json::Value)

Source from the content-addressed store, hash-verified

402 }
403
404 async fn run_command(&self, input: &serde_json::Value) -> AppResult<String> {
405 let cmd = input["command"]
406 .as_str()
407 .ok_or_else(|| AppError::Validation("Missing 'command' field".to_string()))?;
408
409 // Platform-specific shell selection
410 let mut command = if cfg!(target_os = "windows") {
411 let mut cmd_process = Command::new("cmd");
412 cmd_process.arg("/C").arg(cmd);
413 cmd_process
414 } else {
415 let mut sh_process = Command::new("sh");
416 sh_process.arg("-c").arg(cmd);
417 sh_process
418 };
419
420 let safe_path = std::env::var("PATH")
421 .unwrap_or_else(|_| "/usr/local/bin:/usr/bin:/bin".to_string());
422
423 command
424 .current_dir(&self.sandbox)
425 .env_clear()
426 .env("PATH", safe_path)
427 .env("LANG", std::env::var("LANG").unwrap_or_else(|_| "en_US.UTF-8".to_string()))
428 .env("LC_ALL", std::env::var("LC_ALL").unwrap_or_else(|_| "en_US.UTF-8".to_string()))
429 .stdout(Stdio::piped())
430 .stderr(Stdio::piped())
431 .kill_on_drop(true);
432
433 // On Unix, place the child in its own process group so we can kill any
434 // descendants the shell backgrounds. Without this, a command like
435 // `sh -c "sleep 60 &"` orphans the sleep when sh exits or is killed —
436 // it survives the timeout and continues to run with the agent's privileges.
437 #[cfg(unix)]
438 command.process_group(0);
439
440 const MAX_OUTPUT_BYTES: usize = 256 * 1024; // 256KB limit
441
442 let mut child = command.spawn().map_err(AppError::from)?;
443
444 // Capture the leader pid before waiting. This is the process group ID
445 // since we requested process_group(0).
446 #[cfg(unix)]
447 let pgid = child.id().map(|id| id as i32);
448
449 let stdout_pipe = child.stdout.take();
450 let stderr_pipe = child.stderr.take();
451
452 let stdout_task = tokio::spawn(async move {
453 let mut buf = Vec::new();
454 let mut total = 0usize;
455 if let Some(mut out) = stdout_pipe {
456 let mut chunk = [0u8; 8192];
457 loop {
458 let n = tokio::io::AsyncReadExt::read(&mut out, &mut chunk).await?;
459 if n == 0 {
460 break;
461 }

Callers 1

executeMethod · 0.80

Calls

no outgoing calls

Tested by

no test coverage detected