readline() blocks after select() says there's data??
wealthychef
wealthychef at mac.com
Thu Mar 14 22:34:42 EST 2002
Hi, I'm pretty clueless about sockets, but here's my problem. Please
help!
I have a process (actually a 'make') which takes a long time to
complete and periodically spits out lines of information. I want to
keep an eye on it, echo what it says as it says it, and report its
status when done. So I wrote a function called "WaitForCommand",
which in turn periodically calls CheckForOutput() to see if there's
anything to get.
My code is below. The relevant lines are the following:
selectables = [theProcess.childerr, theProcess.fromchild]
(input, output, exc) = select.select([],selectables,
selectables)
if output:
for theOutput in output:
if theOutput == theProcess.childerr:
eoutput = theProcess.childerr.readline(bufsize)
print eoutput
elif theOutput == theProcess.fromchild:
stdoutput = theProcess.fromchild.readline(bufsize)
print stdoutput
It blocks forever waiting for theProcess.childerr.readline(bufsize) to
return. I expect it to block waiting for select.select(); that would
not be a problem. The problem is that select is claiming there's
stuff to be read, then when I try to read it, it's not there! How can
that be? I don't want to block forever waiting for childerr when
fromchild has something for me; that's why I am using select, to be
able to see what's ready, right? I don't get it.
******************************************************
Here is the full code if that's useful. Please trim this out of your
replies if not needed. This message is heinously long as it is.
def CheckForOutput(theProcess, selectables, bufsize, NoStdErr,
Verbose):
while 1:
(input, output, exc) = ([],[],[])
(input, output, exc) =
select.select([],selectables,selectables)
if output:
for theOutput in output:
if theOutput == theProcess.childerr:
eoutput = theProcess.childerr.readline(bufsize)
print eoutput
elif theOutput == theProcess.fromchild:
stdoutput = theProcess.fromchild.readline(bufsize)
print stdoutput
if exc:
pollNum = theProcess.poll()
if pollNum != -1:
print "process closed"
break
raise ("WaitForCommand-- Unknown Error from process
pipe.")
if not output and not exc:
break
return
def WaitForCommand(iCommand, NoStdErr=None, RaiseExceptionOnErr=None,
Verbose=None, bufsize=-1):
theProcess = popen2.Popen3(iCommand,capturestderr=1,
bufsize=bufsize)
selectables = [theProcess.childerr, theProcess.fromchild]
while 1:
CheckForOutput(theProcess, selectables, bufsize, NoStdErr,
Verbose)
returnCode = theProcess.poll()
if returnCode != -1:
CheckForOutput(theProcess, selectables, bufsize, NoStdErr,
Verbose)
if returnCode and RaiseExceptionOnErr:
raise 'Error: return code is ' + str(returnCode)
if Verbose:
print 'return code is ', returnCode
break
return
More information about the Python-list
mailing list