22import os
33import sys
44import tempfile
5+ import threading
56import unittest
67from test import support
8+ from test .support import threading_helper
79from test .support .import_helper import import_module
810
911termios = import_module ('termios' )
1315class TestFunctions (unittest .TestCase ):
1416
1517 def setUp (self ):
16- master_fd , self .fd = os .openpty ()
17- self .addCleanup (os .close , master_fd )
18+ self . master_fd , self .fd = os .openpty ()
19+ self .addCleanup (os .close , self . master_fd )
1820 self .stream = self .enterContext (open (self .fd , 'wb' , buffering = 0 ))
1921 tmp = self .enterContext (tempfile .TemporaryFile (mode = 'wb' , buffering = 0 ))
2022 self .bad_fd = tmp .fileno ()
@@ -147,6 +149,29 @@ def test_tcflush_errors(self):
147149 self .assertRaises (TypeError , termios .tcflush , object (), termios .TCIFLUSH )
148150 self .assertRaises (TypeError , termios .tcflush , self .fd )
149151
152+ def test_tcflush_clear_input_or_output (self ):
153+ wfd = self .fd
154+ rfd = self .master_fd
155+ inbuf = sys .platform == 'linux'
156+
157+ os .write (wfd , b'abcdef' )
158+ self .assertEqual (os .read (rfd , 2 ), b'ab' )
159+ if inbuf :
160+ # don't flush input
161+ termios .tcflush (rfd , termios .TCOFLUSH )
162+ else :
163+ # don't flush output
164+ termios .tcflush (wfd , termios .TCIFLUSH )
165+ self .assertEqual (os .read (rfd , 2 ), b'cd' )
166+ if inbuf :
167+ # flush input
168+ termios .tcflush (rfd , termios .TCIFLUSH )
169+ else :
170+ # flush output
171+ termios .tcflush (wfd , termios .TCOFLUSH )
172+ os .write (wfd , b'ABCDEF' )
173+ self .assertEqual (os .read (rfd , 1024 ), b'ABCDEF' )
174+
150175 @support .skip_android_selinux ('tcflow' )
151176 def test_tcflow (self ):
152177 termios .tcflow (self .fd , termios .TCOOFF )
@@ -165,6 +190,32 @@ def test_tcflow_errors(self):
165190 self .assertRaises (TypeError , termios .tcflow , object (), termios .TCOON )
166191 self .assertRaises (TypeError , termios .tcflow , self .fd )
167192
193+ @unittest .skipUnless (sys .platform == 'linux' , 'only works on Linux' )
194+ def test_tcflow_suspend_and_resume_output (self ):
195+ wfd = self .fd
196+ rfd = self .master_fd
197+ write_suspended = threading .Event ()
198+ write_finished = threading .Event ()
199+
200+ def writer ():
201+ os .write (wfd , b'abc' )
202+ write_suspended .wait ()
203+ os .write (wfd , b'def' )
204+ write_finished .set ()
205+
206+ with threading_helper .start_threads ([threading .Thread (target = writer )]):
207+ self .assertEqual (os .read (rfd , 3 ), b'abc' )
208+ try :
209+ termios .tcflow (wfd , termios .TCOOFF )
210+ write_suspended .set ()
211+ self .assertFalse (write_finished .wait (0.5 ),
212+ 'output was not suspended' )
213+ finally :
214+ termios .tcflow (wfd , termios .TCOON )
215+ self .assertTrue (write_finished .wait (0.5 ),
216+ 'output was not resumed' )
217+ self .assertEqual (os .read (rfd , 1024 ), b'def' )
218+
168219 def test_tcgetwinsize (self ):
169220 size = termios .tcgetwinsize (self .fd )
170221 self .assertIsInstance (size , tuple )
0 commit comments