[Python-bugs-list] [ python-Bugs-405831 ] popen3 read fails in blocks

nobody nobody@sourceforge.net
Sat, 10 Mar 2001 11:28:01 -0800


Bugs #405831, was updated on 2001-03-04 06:17
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=405831&group_id=5470

Category: Python Library
Group: Not a Bug
Status: Closed
Priority: 1
Submitted By: Luke Kenneth Casson Leighton
Assigned to: Guido van Rossum
Summary: popen3 read fails in blocks

Initial Comment:
bash$ python2
from popen2 import popen3
r,w,e = popen3("bash")
w.write("ls")
w.flush()
print select([r],[],[],0)
[r],[],[]
t = r.read(50)
print t
"file1
file2
"
print select([r],[],[],0)
[],[],[]

r,w,e = popen3("bash")
w.write("ls")
w.close()
t = r.read(50)
print t
"file1
file2
[50 bytes of file listings]
"
t = r.read(50)
print t
"file3
file4
[50 more bytes of file listings]
"

print select([r],[],[],0)
[r],[],[]

what is going on????

when you do a w.flush(), the read file descriptor
can get the first 50 bytes, and then select
will *always* return [],[],[] - EVEN if there's
really more data pending to be read.

it is as if there is double-buffering being
done in os.popen3() which select() is failing
to access.

this is standard-compiled version of python 2.0
on linux mandrake 7.1.  if it makes any difference.

luke

----------------------------------------------------------------------

Comment By: Guido van Rossum
Date: 2001-03-10 11:28

Message:
Logged In: YES 
user_id=6380

Not a bug -- you just can't do what you want there.

The data is being buffered in the file object (which is a
wrapper around a stdio file), and this makes it invisible
for select.

----------------------------------------------------------------------

Comment By: Luke Kenneth Casson Leighton
Date: 2001-03-09 03:34

Message:
Logged In: YES 
user_id=80200

the following test DOES work as expected, which is good news
because i can use this in my [current] project.  the
work-around is to bypass r.read() and use
os.read(r.fileno(), 50), like so:

import os
from select import select

w,r,e = os.popen3("bash")
w.write("ls -al\n")
w.flush()

while select([r],[],[],1) == ([r],[],[]):
    print os.read(r.fileno(), 50),

this would indicate that there is double-buffering or
similar in the r.read() function.  at a guess, it is
something to do with the way that read has to work in
allowing r.read() as well as r.read(50).  so, select doesn't
work because you've already _read_ all the outstanding data,
and stored it in the r object!

which means that really, the r object must support the
select() method correctly, which at the moment it does not.

with this slightly confused reasoning, without having delved
into the code, i'm sure you can work this out.  i have
enough to go on, now :)

luke

----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=405831&group_id=5470