Skip to content

Commit 6778642

Browse files
committed
[timeout] fix locale problem
1 parent ae14c65 commit 6778642

File tree

3 files changed

+37
-14
lines changed

3 files changed

+37
-14
lines changed

process/tests/timeout/mod.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use std::{
1111
io::Write,
1212
process::{Command, Output, Stdio},
13+
thread,
14+
time::Duration,
1315
};
1416

1517
use sysinfo::System;
@@ -43,15 +45,33 @@ fn run_test_base(cmd: &str, args: &Vec<String>, stdin_data: &[u8]) -> (Output, i
4345
.stdout(Stdio::piped())
4446
.stderr(Stdio::piped())
4547
.spawn()
46-
.expect("failed to spawn head");
48+
.expect(format!("failed to spawn command {}", cmd).as_str());
4749

4850
let pgid = unsafe { libc::getpgid(child.id() as i32) };
4951

50-
let stdin = child.stdin.as_mut().expect("failed to get stdin");
51-
stdin
52-
.write_all(stdin_data)
53-
.expect("failed to write to stdin");
52+
// Separate the mutable borrow of stdin from the child process
53+
if let Some(mut stdin) = child.stdin.take() {
54+
let chunk_size = 1024; // Arbitrary chunk size, adjust if needed
55+
for chunk in stdin_data.chunks(chunk_size) {
56+
// Write each chunk
57+
if let Err(e) = stdin.write_all(chunk) {
58+
eprintln!("Error writing to stdin: {}", e);
59+
break;
60+
}
61+
// Flush after writing each chunk
62+
if let Err(e) = stdin.flush() {
63+
eprintln!("Error flushing stdin: {}", e);
64+
break;
65+
}
66+
67+
// Sleep briefly to avoid CPU spinning
68+
thread::sleep(Duration::from_millis(10));
69+
}
70+
// Explicitly drop stdin to close the pipe
71+
drop(stdin);
72+
}
5473

74+
// Ensure we wait for the process to complete after writing to stdin
5575
let output = child.wait_with_output().expect("failed to wait for child");
5676
(output, pgid)
5777
}
@@ -113,6 +133,7 @@ fn timeout_test_extended(
113133
const TRUE: &'static str = "true";
114134
const SLEEP: &'static str = "sleep";
115135
const NON_EXECUTABLE: &'static str = "tests/timeout/non_executable.sh";
136+
const WITH_ARGUMENT: &'static str = "tests/timeout/with_argument.sh";
116137
const SPAWN_CHILD: &'static str = "tests/timeout/spawn_child.sh";
117138

118139
#[test]
@@ -235,13 +256,7 @@ fn test_utility_not_found() {
235256

236257
#[test]
237258
fn test_utility_error() {
238-
let message: String = if cfg!(target_os = "macos") {
239-
String::from("usage: sleep seconds\n")
240-
} else {
241-
String::from("/usr/bin/sleep: invalid time interval ‘invalid_value’\nTry '/usr/bin/sleep --help' for more information.\n")
242-
};
243-
244-
timeout_test(&["1", SLEEP, "invalid_value"], &message, 1);
259+
timeout_test(&["1", WITH_ARGUMENT], "error: enter some argument\n", 1);
245260
}
246261

247262
#[test]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
3+
if [ $# -eq 0 ]; then
4+
echo "error: enter some argument" >&2
5+
exit 1
6+
fi
7+
8+
echo "You have passed: $1"

process/timeout.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ static MONITORED_PID: AtomicI32 = AtomicI32::new(0);
103103
static TIMED_OUT: AtomicBool = AtomicBool::new(false);
104104

105105
/// timeout — execute a utility with a time limit
106-
#[derive(Parser, Debug)]
107-
#[command(author, version, about, long_about)]
106+
#[derive(Parser)]
107+
#[command(version, about)]
108108
struct Args {
109109
/// Only time out the utility itself, not its descendants.
110110
#[arg(short = 'f', long)]

0 commit comments

Comments
 (0)