[Python-bugs-list] [Bug #110676] fd.readlines() hangs (via popen3) (PR#385)

noreply@sourceforge.net noreply@sourceforge.net
Wed, 20 Sep 2000 13:39:21 -0700


Bug #110676, was updated on 2000-Jul-31 14:13
Here is a current snapshot of the bug.

Project: Python
Category: Modules
Status: Closed
Resolution: Invalid
Bug Group: Not a Bug
Priority: 5
Summary: fd.readlines() hangs (via popen3) (PR#385)

Details: Jitterbug-Id: 385
Submitted-By: aron@gweep.net
Date: Tue,  4 Jul 2000 19:07:55 -0400 (EDT)
Version: 1.5.2
OS: Red Hat Linux 6.1 (2.1.12-20)


The following scripts cause a hang at the denoted line. To execute
this code, copy the first bit to master.py and the second to slave.py
(both should be in the same directory). Then, "cd" to that directory
and "python master.py".

Manually killing the program is necessary.

This script has also been tested on a Solaris 5.7 box and worked.

---master.py---
import popen2

r,w,e = popen2.popen3 ( 'python slave.py' )
r.readlines() # Hangs here
e.readlines()
r.close()
e.close()
w.close()

---end---

---slave.py---
import sys

e = sys.stderr.write
w = sys.stdout.write

e(400*'this is a test\n')
w(400*'this is another test\n')
---end---



====================================================================
Audit trail:
Tue Jul 11 08:24:23 2000	guido	moved from incoming to open

Follow-Ups:

Date: 2000-Sep-07 15:03
By: jhylton

Comment:
Please do triage on this bug.
-------------------------------------------------------

Date: 2000-Sep-20 13:39
By: loewis

Comment:
That is a bug in the application code. The slave tries to write 6000 bytes to stderr, and blocks after writing 4096 (number measured on Linux, more generally, after _PC_PIPE_BUF bytes). 
The server starts reading on stdin, and blocks also, so you get a deadlock.
The proper solution is to use
import popen2

r,w,e = popen2.popen3 ( 'python slave.py' )
e.readlines()
r.readlines()
r.close()
e.close()
w.close()

as the server, and 
import sys,posix

e = sys.stderr.write
w = sys.stdout.write

e(400*'this is a test\n')
posix.close(2)
w(400*'this is another test\n')

as the slave. Notice that stderr must be closed after writing all data, or readlines won't return. Also notice that posix.close must be used, as sys.stderr.close() won't close stderr (apparently due to concerns that assigning to sys.stderr will silently close is, so no further errors can be printed).
-------------------------------------------------------

For detailed info, follow this link:
http://sourceforge.net/bugs/?func=detailbug&bug_id=110676&group_id=5470