(
program: PathBuf,
args: [&str; N],
stdin_input: Option<&[u8]>,
)
| 1468 | } |
| 1469 | |
| 1470 | fn run_command_with_stdin<const N: usize>( |
| 1471 | program: PathBuf, |
| 1472 | args: [&str; N], |
| 1473 | stdin_input: Option<&[u8]>, |
| 1474 | ) -> Result<Vec<u8>, AppError> { |
| 1475 | if !program.exists() { |
| 1476 | return Err(AppError::native(format!( |
| 1477 | "Android SDK binary not found at {}.", |
| 1478 | program.display() |
| 1479 | ))); |
| 1480 | } |
| 1481 | let sdk_root = sdk_root(); |
| 1482 | let mut command = Command::new(&program); |
| 1483 | command |
| 1484 | .args(args) |
| 1485 | .env("ANDROID_HOME", &sdk_root) |
| 1486 | .env("ANDROID_SDK_ROOT", &sdk_root); |
| 1487 | if let Some(java_home) = java_home() { |
| 1488 | command.env("JAVA_HOME", java_home); |
| 1489 | } |
| 1490 | let mut child = command |
| 1491 | .stdin(if stdin_input.is_some() { |
| 1492 | Stdio::piped() |
| 1493 | } else { |
| 1494 | Stdio::null() |
| 1495 | }) |
| 1496 | .stdout(Stdio::piped()) |
| 1497 | .stderr(Stdio::piped()) |
| 1498 | .spawn() |
| 1499 | .map_err(|error| { |
| 1500 | AppError::native(format!("Unable to run {}: {error}", program.display())) |
| 1501 | })?; |
| 1502 | if let Some(input) = stdin_input { |
| 1503 | let mut stdin = child.stdin.take().ok_or_else(|| { |
| 1504 | AppError::native(format!("Unable to open stdin for {}.", program.display())) |
| 1505 | })?; |
| 1506 | stdin.write_all(input).map_err(|error| { |
| 1507 | AppError::native(format!( |
| 1508 | "Unable to write stdin for {}: {error}", |
| 1509 | program.display() |
| 1510 | )) |
| 1511 | })?; |
| 1512 | } |
| 1513 | let stdout = child.stdout.take().ok_or_else(|| { |
| 1514 | AppError::native(format!( |
| 1515 | "Unable to capture stdout from {}.", |
| 1516 | program.display() |
| 1517 | )) |
| 1518 | })?; |
| 1519 | let stderr = child.stderr.take().ok_or_else(|| { |
| 1520 | AppError::native(format!( |
| 1521 | "Unable to capture stderr from {}.", |
| 1522 | program.display() |
| 1523 | )) |
| 1524 | })?; |
| 1525 | let stdout_reader = thread::spawn(move || read_command_stream(stdout)); |
| 1526 | let stderr_reader = thread::spawn(move || read_command_stream(stderr)); |
| 1527 | let deadline = Instant::now() + ANDROID_COMMAND_TIMEOUT; |
no test coverage detected