Skip to content

Commit c7392be

Browse files
committed
Rollup merge of #23468 - sfackler:stdio-panic, r=alexcrichton
Nothing inside of the read/write interface itself can panic, so any poison must have been the result of user code which the lock isn't protecting. This seems safe to me, but if we don't want to go this route we should update the docs to indicate that these methods can panic. r? @alexcrichton
2 parents 05354e8 + a51cd61 commit c7392be

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

src/libstd/io/stdio.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ impl Stdin {
146146
/// accessing the underlying data.
147147
#[stable(feature = "rust1", since = "1.0.0")]
148148
pub fn lock(&self) -> StdinLock {
149-
StdinLock { inner: self.inner.lock().unwrap() }
149+
StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
150150
}
151151

152152
/// Locks this handle and reads a line of input into the specified buffer.
@@ -249,7 +249,7 @@ impl Stdout {
249249
/// returned guard also implements the `Write` trait for writing data.
250250
#[stable(feature = "rust1", since = "1.0.0")]
251251
pub fn lock(&self) -> StdoutLock {
252-
StdoutLock { inner: self.inner.lock().unwrap() }
252+
StdoutLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
253253
}
254254
}
255255

@@ -319,7 +319,7 @@ impl Stderr {
319319
/// returned guard also implements the `Write` trait for writing data.
320320
#[stable(feature = "rust1", since = "1.0.0")]
321321
pub fn lock(&self) -> StderrLock {
322-
StderrLock { inner: self.inner.lock().unwrap() }
322+
StderrLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
323323
}
324324
}
325325

@@ -402,3 +402,29 @@ pub fn _print(args: fmt::Arguments) {
402402
panic!("failed printing to stdout: {}", e);
403403
}
404404
}
405+
406+
#[cfg(test)]
407+
mod test {
408+
use thread;
409+
use super::*;
410+
411+
#[test]
412+
fn panic_doesnt_poison() {
413+
thread::spawn(|| {
414+
let _a = stdin();
415+
let _a = _a.lock();
416+
let _a = stdout();
417+
let _a = _a.lock();
418+
let _a = stderr();
419+
let _a = _a.lock();
420+
panic!();
421+
}).join().unwrap_err();
422+
423+
let _a = stdin();
424+
let _a = _a.lock();
425+
let _a = stdout();
426+
let _a = _a.lock();
427+
let _a = stderr();
428+
let _a = _a.lock();
429+
}
430+
}

0 commit comments

Comments
 (0)