Skip to content

Commit 26c35c0

Browse files
authored
Merge pull request #691 from asomers/ptsname
Fix thread safety issues in pty and termios tests
2 parents a4701e9 + ce04f1c commit 26c35c0

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

test/sys/test_termios.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ fn write_all(f: RawFd, buf: &[u8]) {
1818
// Test tcgetattr on a terminal
1919
#[test]
2020
fn test_tcgetattr_pty() {
21-
let pty = openpty(None, None).unwrap();
21+
// openpty uses ptname(3) internally
22+
#[allow(unused_variables)]
23+
let m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
24+
25+
let pty = openpty(None, None).expect("openpty failed");
2226
assert!(termios::tcgetattr(pty.master).is_ok());
23-
close(pty.master).unwrap();
24-
close(pty.slave).unwrap();
27+
close(pty.master).expect("closing the master failed");
28+
close(pty.slave).expect("closing the slave failed");
2529
}
2630
// Test tcgetattr on something that isn't a terminal
2731
#[test]
@@ -41,12 +45,16 @@ fn test_tcgetattr_ebadf() {
4145
// Test modifying output flags
4246
#[test]
4347
fn test_output_flags() {
48+
// openpty uses ptname(3) internally
49+
#[allow(unused_variables)]
50+
let m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
51+
4452
// Open one pty to get attributes for the second one
4553
let mut termios = {
46-
let pty = openpty(None, None).unwrap();
54+
let pty = openpty(None, None).expect("openpty failed");
4755
assert!(pty.master > 0);
4856
assert!(pty.slave > 0);
49-
let termios = tcgetattr(pty.master).unwrap();
57+
let termios = tcgetattr(pty.master).expect("tcgetattr failed");
5058
close(pty.master).unwrap();
5159
close(pty.slave).unwrap();
5260
termios
@@ -80,6 +88,10 @@ fn test_output_flags() {
8088
// Test modifying local flags
8189
#[test]
8290
fn test_local_flags() {
91+
// openpty uses ptname(3) internally
92+
#[allow(unused_variables)]
93+
let m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
94+
8395
// Open one pty to get attributes for the second one
8496
let mut termios = {
8597
let pty = openpty(None, None).unwrap();

test/test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ lazy_static! {
4545
/// Any test that creates child processes must grab this mutex, regardless
4646
/// of what it does with those children.
4747
pub static ref FORK_MTX: Mutex<()> = Mutex::new(());
48+
/// Any test that calls ptsname(3) must grab this mutex.
49+
pub static ref PTSNAME_MTX: Mutex<()> = Mutex::new(());
4850
/// Any test that alters signal handling must grab this mutex.
4951
pub static ref SIGNAL_MTX: Mutex<()> = Mutex::new(());
5052
}

test/test_pty.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ fn test_explicit_close() {
2727
#[test]
2828
#[cfg(any(target_os = "android", target_os = "linux"))]
2929
fn test_ptsname_equivalence() {
30+
#[allow(unused_variables)]
31+
let m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
32+
3033
// Open a new PTTY master
3134
let master_fd = posix_openpt(O_RDWR).unwrap();
3235
assert!(master_fd.as_raw_fd() > 0);
@@ -42,6 +45,9 @@ fn test_ptsname_equivalence() {
4245
#[test]
4346
#[cfg(any(target_os = "android", target_os = "linux"))]
4447
fn test_ptsname_copy() {
48+
#[allow(unused_variables)]
49+
let m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
50+
4551
// Open a new PTTY master
4652
let master_fd = posix_openpt(O_RDWR).unwrap();
4753
assert!(master_fd.as_raw_fd() > 0);
@@ -74,6 +80,9 @@ fn test_ptsname_r_copy() {
7480
#[test]
7581
#[cfg(any(target_os = "android", target_os = "linux"))]
7682
fn test_ptsname_unique() {
83+
#[allow(unused_variables)]
84+
let m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
85+
7786
// Open a new PTTY master
7887
let master1_fd = posix_openpt(O_RDWR).unwrap();
7988
assert!(master1_fd.as_raw_fd() > 0);
@@ -95,16 +104,19 @@ fn test_ptsname_unique() {
95104
/// pair.
96105
#[test]
97106
fn test_open_ptty_pair() {
107+
#[allow(unused_variables)]
108+
let m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
109+
98110
// Open a new PTTY master
99-
let master_fd = posix_openpt(O_RDWR).unwrap();
111+
let master_fd = posix_openpt(O_RDWR).expect("posix_openpt failed");
100112
assert!(master_fd.as_raw_fd() > 0);
101113

102114
// Allow a slave to be generated for it
103-
grantpt(&master_fd).unwrap();
104-
unlockpt(&master_fd).unwrap();
115+
grantpt(&master_fd).expect("grantpt failed");
116+
unlockpt(&master_fd).expect("unlockpt failed");
105117

106118
// Get the name of the slave
107-
let slave_name = ptsname(&master_fd).unwrap();
119+
let slave_name = ptsname(&master_fd).expect("ptsname failed");
108120

109121
// Open the slave device
110122
let slave_fd = open(Path::new(&slave_name), O_RDWR, stat::Mode::empty()).unwrap();
@@ -113,6 +125,10 @@ fn test_open_ptty_pair() {
113125

114126
#[test]
115127
fn test_openpty() {
128+
// openpty uses ptname(3) internally
129+
#[allow(unused_variables)]
130+
let m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
131+
116132
let pty = openpty(None, None).unwrap();
117133
assert!(pty.master > 0);
118134
assert!(pty.slave > 0);
@@ -145,6 +161,10 @@ fn test_openpty() {
145161

146162
#[test]
147163
fn test_openpty_with_termios() {
164+
// openpty uses ptname(3) internally
165+
#[allow(unused_variables)]
166+
let m = ::PTSNAME_MTX.lock().expect("Mutex got poisoned by another test");
167+
148168
// Open one pty to get attributes for the second one
149169
let mut termios = {
150170
let pty = openpty(None, None).unwrap();

0 commit comments

Comments
 (0)