Skip to content

Commit e89287f

Browse files
committed
fix: correct hang when tokio is not used
1 parent 936c72b commit e89287f

File tree

1 file changed

+44
-26
lines changed

1 file changed

+44
-26
lines changed

postgresql_commands/src/traits.rs

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::error::{Error, Result};
22
use std::ffi::{OsStr, OsString};
33
use std::fmt::Debug;
44
use std::path::PathBuf;
5+
use std::process::Child;
56
use std::time::Duration;
67
use tracing::debug;
78

@@ -140,32 +141,46 @@ impl CommandExecutor for std::process::Command {
140141
/// Execute the command and return the stdout and stderr
141142
fn execute(&mut self) -> Result<(String, String)> {
142143
debug!("Executing command: {}", self.to_command_string());
143-
let output = self.output()?;
144-
145144
#[cfg(not(target_os = "windows"))]
146-
let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
147-
#[cfg(target_os = "windows")]
148-
let stdout = String::new();
145+
{
146+
let output = self.output()?;
147+
let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
148+
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
149+
150+
debug!(
151+
"Result: {}\nstdout: {}\nstderr: {}",
152+
output
153+
.status
154+
.code()
155+
.map_or("None".to_string(), |c| c.to_string()),
156+
stdout,
157+
stderr
158+
);
159+
160+
if output.status.success() {
161+
Ok((stdout, stderr))
162+
} else {
163+
Err(Error::CommandError { stdout, stderr })
164+
}
165+
}
149166

150-
#[cfg(not(target_os = "windows"))]
151-
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
167+
// TODO: Processes can hang on Windows when attempting to get stdout/stderr using code
168+
// that works for Linux/MacOS; this implementation should be updated to retrieve the
169+
// values of stdout/stderr without hanging
152170
#[cfg(target_os = "windows")]
153-
let stderr = String::new();
154-
155-
debug!(
156-
"Result: {}\nstdout: {}\nstderr: {}",
157-
output
158-
.status
159-
.code()
160-
.map_or("None".to_string(), |c| c.to_string()),
161-
stdout,
162-
stderr
163-
);
164-
165-
if output.status.success() {
166-
Ok((stdout, stderr))
167-
} else {
168-
Err(Error::CommandError { stdout, stderr })
171+
{
172+
let mut process = self
173+
.stdout(std::process::Stdio::piped())
174+
.stderr(std::process::Stdio::piped())
175+
.spawn()?;
176+
let status = process.wait()?;
177+
let stdout = String::new();
178+
let stderr = String::new();
179+
if status.success() {
180+
Ok((stdout, stderr))
181+
} else {
182+
Err(Error::CommandError { stdout, stderr })
183+
}
169184
}
170185
}
171186
}
@@ -183,11 +198,14 @@ impl AsyncCommandExecutor for tokio::process::Command {
183198

184199
#[cfg(not(target_os = "windows"))]
185200
let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
186-
#[cfg(target_os = "windows")]
187-
let stdout = String::new();
188-
189201
#[cfg(not(target_os = "windows"))]
190202
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
203+
204+
// TODO: Processes can hang on Windows when attempting to get stdout/stderr using code
205+
// that works for Linux/MacOS; this implementation should be updated to retrieve the
206+
// values of stdout/stderr without hanging
207+
#[cfg(target_os = "windows")]
208+
let stdout = String::new();
191209
#[cfg(target_os = "windows")]
192210
let stderr = String::new();
193211

0 commit comments

Comments
 (0)