@@ -1725,6 +1725,48 @@ def reader(data):
17251725 self .loop .run_until_complete (proto .done )
17261726 self .assertEqual ('CLOSED' , proto .state )
17271727
1728+ @unittest .skipUnless (sys .platform != 'win32' ,
1729+ "Don't support pipes for Windows" )
1730+ @unittest .skipUnless (hasattr (os , 'mkfifo' ), 'requires os.mkfifo()' )
1731+ def test_write_named_fifo_unread_data (self ):
1732+ # gh-145030: on macOS, the write end of a named FIFO polls as
1733+ # readable while unread data sits in the FIFO, which made the
1734+ # transport misinterpret the event as the reader hanging up
1735+ # and close itself.
1736+ path = os_helper .TESTFN
1737+ os .mkfifo (path )
1738+ self .assertNotEqual (os .stat (path ).st_nlink , 0 )
1739+ self .addCleanup (os_helper .unlink , path )
1740+ rfd = os .open (path , os .O_RDONLY | os .O_NONBLOCK )
1741+ self .addCleanup (os .close , rfd )
1742+ wfd = os .open (path , os .O_WRONLY | os .O_NONBLOCK )
1743+ pipeobj = io .open (wfd , 'wb' , 1024 )
1744+
1745+ proto = MyWritePipeProto (loop = self .loop )
1746+ connect = self .loop .connect_write_pipe (lambda : proto , pipeobj )
1747+ transport , p = self .loop .run_until_complete (connect )
1748+ self .assertIs (p , proto )
1749+ self .assertEqual ('CONNECTED' , proto .state )
1750+
1751+ transport .write (b'1' )
1752+ # Iterate the event loop while the data stays unread in the FIFO;
1753+ # the transport must not detect a false disconnection.
1754+ for _ in range (10 ):
1755+ test_utils .run_briefly (self .loop )
1756+ self .assertEqual ('CONNECTED' , proto .state )
1757+ self .assertFalse (transport .is_closing ())
1758+ self .assertEqual (b'1' , os .read (rfd , 1024 ))
1759+
1760+ transport .write (b'2345' )
1761+ for _ in range (10 ):
1762+ test_utils .run_briefly (self .loop )
1763+ self .assertEqual ('CONNECTED' , proto .state )
1764+ self .assertEqual (b'2345' , os .read (rfd , 1024 ))
1765+
1766+ transport .close ()
1767+ self .loop .run_until_complete (proto .done )
1768+ self .assertEqual ('CLOSED' , proto .state )
1769+
17281770 @unittest .skipUnless (sys .platform != 'win32' ,
17291771 "Don't support pipes for Windows" )
17301772 def test_write_pipe_disconnect_on_close (self ):
0 commit comments