Need help w 'Broken pipe' handling

G

gb345

Hi! I'm having a hard time figuring out how to handle a Unix
SIGPIPE exception cleanly. The following short script illustrates
the problem:

------------------------------------------------------------------
#!/usr/bin/python
# sigpipebug.py
import sys
import random
from signal import signal, SIGPIPE, SIGINT

def handle_sigpipe(signo, frame):
print >> sys.stderr, "caught SIGPIPE (%d)" % signo
sys.exit(0)

def handle_sigint(signo, frame):
print >> sys.stderr, "caught SIGINT (%d)" % signo
sys.exit(1)

def my_excepthook(exc_type, exc_obj, exc_tb):
print >> sys.stderr, "excepthook called"
sys.exit(0)

signal(SIGPIPE, handle_sigpipe)
signal(SIGINT, handle_sigint)
# sys.excepthook = my_excepthook

while True:
try:
print random.random()
except IOError as (_, error):
if error == 'Broken pipe':
print >> sys.stderr, 'EXCEPTION: %s' % error
sys.exit(0)
raise
------------------------------------------------------------------



The problem shows up only occasionally; the following bash one-liner
helps to see the problem (terminate with Ctrl-C):

while [ 1 ]; do (./sigpipebug.py||break) | head -1; done

(The pipe through head should cause the script to receive a PIPE
signal.)

The typical output from the above one-liner will start out as
something like this:

0.666233280308
caught SIGPIPE (13)
0.554289690682
caught SIGPIPE (13)
0.438033929588
caught SIGPIPE (13)
0.969307976257
caught SIGPIPE (13)
close failed in file object destructor:
Error in sys.excepthook:

Original exception was:
0.916260186232
caught SIGPIPE (13)
0.798590903019
caught SIGPIPE (13)
0.737496617527

....though the length of the output preceding "close failed..." is
highly variable.

My problem is that I can't figure out how to get rid of this unwanted
extra output:

close failed in file object destructor:
Error in sys.excepthook:

Original exception was:



I figure that the way the script is handling the SIGPIPE is somehow
incorrect, but I don't see what is it that I'm doing wrong (BTW,
I'm a Python noob). Is there some cleanup method I should invoke
in the sigpipe handler before executing sys.exit(0)? (BTW, I'm
using sys.exit in this script instead of plain exit to avoid a
strange error of the form "NameError: global name 'exit' is not
defined".)

The same thing happens when I redefine sys.excepthook (by uncommenting
the commented-out line).

Also, is there a way to define the SIGPIPE handler to obviate the
need to trap the IOError exception? (Without this try block, I
get a traceback when the script receives the PIPE signal. This
traceback is also unwanted output.)

Any suggestions or comments would be appreciated!

Gabe
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top