IOError: [Errno 4] Interrupted system call

M

Marco

Hello,every one, I meet a question:

in my old script, I usually use os.popen2() to get info from standard
unix(LinuX) program like ps,ifconfig...

Now, I write a OO-based programme, I still use os.popen2( check
whether mplayer still working via ps command ), but some things I got
the following message:

Traceback (most recent call last):
File "./mkt.py", line 351, in loop_timeout
self.process(self.event.get_next())
File "./mkt.py", line 361, in process
self.player.play(command[1])
File "./mkt.py", line 107, in play
if self.is_playing():
File "./mkt.py", line 78, in is_playing
info = rfd.readlines()
IOError: [Errno 4] Interrupted system call

why? Thank you!
 
D

Donn Cave

Marco said:
Hello,every one, I meet a question:

in my old script, I usually use os.popen2() to get info from standard
unix(LinuX) program like ps,ifconfig...

Now, I write a OO-based programme, I still use os.popen2( check
whether mplayer still working via ps command ), but some things I got
the following message:

Traceback (most recent call last):
File "./mkt.py", line 351, in loop_timeout
self.process(self.event.get_next())
File "./mkt.py", line 361, in process
self.player.play(command[1])
File "./mkt.py", line 107, in play
if self.is_playing():
File "./mkt.py", line 78, in is_playing
info = rfd.readlines()
IOError: [Errno 4] Interrupted system call

why? Thank you!

Some signal was evidently delivered to your process, while
you had a "slow" read in progress (i.e., not from disk.)
The read was interrupted to deliver the signal.

Look for signal handlers in your code and any library functions
you call. I hope library functions don't have signal handlers,
sounds like a horrible idea to me. If your code has a signal
handler for SIGCHLD, try to get rid of that - the handler itself
is causing your problem.

OO (Object Oriented?) doesn't have anything to do with the problem,
that I can think of.

Donn Cave, (e-mail address removed)
 
C

chadrik

i'm getting the same error when trying to read results from popen2
within a pyQt window. is this a threading issue? is my pyQt window
responsible for interrupting the read? i'm fairly new to python so
i'm struggling to figure this out. can you recommend any possible
methods of preventing this? for instance, could acquiring a thread
lock before calling popen solve the problem?

thanks,
chad
 
G

Gabriel Genellina

i'm getting the same error when trying to read results from popen2
within a pyQt window. is this a threading issue? is my pyQt window
responsible for interrupting the read? i'm fairly new to python so
i'm struggling to figure this out. can you recommend any possible
methods of preventing this? for instance, could acquiring a thread
lock before calling popen solve the problem?

I dont know pyQt but in general, blocking operations (like a syncronous
read) can return EINTR when a signal arrives in the middle. Just retrying
the operation would be enough; by example, if you have a read() inside a
loop, just ignore the exception and continue.
 
D

Donn Cave

i'm getting the same error when trying to read results from popen2
within a pyQt window. is this a threading issue? is my pyQt window
responsible for interrupting the read? i'm fairly new to python so
i'm struggling to figure this out. can you recommend any possible
methods of preventing this? for instance, could acquiring a thread
lock before calling popen solve the problem?

No.

Did you look at the text of the post you responded to here?
What do you think about that advice? Do you have any
signal handlers?

Donn Cave, (e-mail address removed)
 
C

chadrik

i don't have any signal handlers in my code, but i have no idea what
is going on in the internals of the pyQt framework that i'm using for
the GUI.

as far as simply ignoring the exception, that does not seem to work.
for instance, here's some code i've tried:


p = subprocess.Popen('mycommand', shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, close_fds=True)
output = ''
tries = 0
while tries < 12:
try:
tries = tries+1
print "retrieving results"
output = p.stdout.readlines()

except IOError:
print "IOError! try %s" % tries
print "output:", output
#time.sleep(1)
else:
print "Great Success"
print "output:", output
break


--printout: successful run--
retrieving results
Great Success
output: []

--printout: IOError run--
retrieving results
IOError! try 1
output:
retrieving results
Great Success
output: []

if the first try raises an error output does not get set and then the
second try succeeds but returns an empty list when it should return
results. moving the Popen inside the loop isn't an option either,
because, in addition to returning results, the command performs an
action which should only run once.

sorry if i'm missing something obvious here, i'm a python newb.

-chad
 
D

Donn Cave

i don't have any signal handlers in my code, but i have no idea what
is going on in the internals of the pyQt framework that i'm using for
the GUI.

as far as simply ignoring the exception, that does not seem to work.
for instance, here's some code i've tried:


p = subprocess.Popen('mycommand', shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, close_fds=True)
output = ''
tries = 0
while tries < 12:
try:
tries = tries+1
print "retrieving results"
output = p.stdout.readlines()

except IOError:
print "IOError! try %s" % tries
print "output:", output
#time.sleep(1)
else:
print "Great Success"
print "output:", output
break ....
if the first try raises an error output does not get set and then the
second try succeeds but returns an empty list when it should return
results. moving the Popen inside the loop isn't an option either,
because, in addition to returning results, the command performs an
action which should only run once.

sorry if i'm missing something obvious here, i'm a python newb.

No, actually this is somewhat non-obvious, if I'm right.

You can't use readlines() like that, it's a Python
thing that evidently loses some or all of its buffered
data, and you start over from scratch.

Instead, probably the simplest thing would be to implement
your own readlines around that restart loop, actually reading
one line at a time and appending to the line list. I'm not
sure that's totally bulletproof - probably will work, but
if you need a sure thing, I would go to UNIX I/O (posix.read),
in a loop, and then split the concatenated results by newline.

Or, of course if you could shut down the signals...

Donn Cave, (e-mail address removed)
 
G

Gabriel Genellina

i don't have any signal handlers in my code, but i have no idea what
is going on in the internals of the pyQt framework that i'm using for
the GUI.

p = subprocess.Popen('mycommand', shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, close_fds=True)
output = p.stdout.readlines()

There is a problem using a high-level approach like readlines(): *either*
there is no exception, and you get all the output, *or* there is an
exception and you get nothing. readlines() can't return a partial result
*and* raise an exception at the same time. (Perhaps EINTR should be a
special case, but currently it's converted into an IOError like all other
error codes).

You could read one character at a time with read(1) (to minimize the risk
of data loss), or simply use a temporary file: "mycomand >temporary" and
then read its contents. This appears to be the safest way.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top