Skip to content

Commit f257bd4

Browse files
committed
process: replace unsafe code with safe equivalent
1 parent d65af24 commit f257bd4

File tree

1 file changed

+17
-33
lines changed

1 file changed

+17
-33
lines changed

src/process/terminal_source.rs

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ use console::Term;
22
use indicatif::TermLike;
33
use std::{
44
io::{self, Write},
5-
mem::MaybeUninit,
65
num::NonZero,
76
ops::DerefMut,
8-
ptr::addr_of_mut,
9-
sync::{Arc, Mutex, MutexGuard},
7+
sync::{Arc, Mutex},
108
};
119

1210
#[cfg(feature = "test")]
@@ -83,36 +81,26 @@ impl ColorableTerminal {
8381
}
8482

8583
pub fn lock(&self) -> ColorableTerminalLocked {
86-
let mut uninit = MaybeUninit::<ColorableTerminalLocked>::uninit();
87-
let ptr = uninit.as_mut_ptr();
88-
89-
// Safety: panics during this will leak an arc reference, or an arc
90-
// reference and a mutex guard, or an arc reference, mutex guard and a
91-
// stream lock. Drop proceeds in field order after initialization,
92-
// so the stream lock is dropped before the mutex guard, which is dropped
93-
// before the arc<mutex>.
94-
unsafe {
95-
// let inner: Arc<Mutex<TerminalInner>> = self.inner.clone();
96-
addr_of_mut!((*ptr).inner).write(self.inner.clone());
97-
// let guard = inner.lock().unwrap();
98-
addr_of_mut!((*ptr).guard).write((*ptr).inner.lock().unwrap());
99-
// let locked = match *guard {....}
100-
addr_of_mut!((*ptr).locked).write(match (*ptr).guard.deref_mut() {
101-
TerminalInner::Stdout(_) => {
102-
let locked = io::stdout().lock();
103-
TerminalInnerLocked::Stdout(AutoStream::new(locked, self.color_choice))
104-
}
105-
TerminalInner::Stderr(_) => {
106-
let locked = io::stderr().lock();
107-
TerminalInnerLocked::Stderr(AutoStream::new(locked, self.color_choice))
108-
}
84+
let locked = match self.inner.lock() {
85+
Ok(l) => l,
86+
Err(e) => e.into_inner(),
87+
};
88+
89+
ColorableTerminalLocked {
90+
locked: match &*locked {
91+
TerminalInner::Stdout(s) => TerminalInnerLocked::Stdout(AutoStream::new(
92+
s.as_inner().lock(),
93+
self.color_choice,
94+
)),
95+
TerminalInner::Stderr(s) => TerminalInnerLocked::Stderr(AutoStream::new(
96+
s.as_inner().lock(),
97+
self.color_choice,
98+
)),
10999
#[cfg(feature = "test")]
110100
TerminalInner::TestWriter(w) => {
111101
TerminalInnerLocked::TestWriter(StripStream::new(Box::new(w.clone())))
112102
}
113-
});
114-
// ColorableTerminalLocked { inner, guard, locked }
115-
uninit.assume_init()
103+
},
116104
}
117105
}
118106

@@ -231,11 +219,7 @@ impl std::fmt::Debug for ColorableTerminal {
231219
}
232220

233221
pub struct ColorableTerminalLocked {
234-
// Must drop the lock before the guard, as the guard borrows from inner.
235222
locked: TerminalInnerLocked,
236-
// must drop the guard before inner as the guard borrows from inner.
237-
guard: MutexGuard<'static, TerminalInner>,
238-
inner: Arc<Mutex<TerminalInner>>,
239223
}
240224

241225
impl io::Write for ColorableTerminalLocked {

0 commit comments

Comments
 (0)