Skip to content

Commit 7b0ed43

Browse files
miss-islingtonsplbio
authored andcommitted
bpo-33550: Warn not to set SIGPIPE to SIG_DFL (GH-6773)
(cherry picked from commit a251073) Co-authored-by: Alfred Perlstein <[email protected]>
1 parent 0dc75f0 commit 7b0ed43

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

Doc/library/signal.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,3 +485,37 @@ be sent, and the handler raises an exception. ::
485485

486486
signal.alarm(0) # Disable the alarm
487487

488+
Note on SIGPIPE
489+
---------------
490+
491+
Piping output of your program to tools like :manpage:`head(1)` will
492+
cause a :const:`SIGPIPE` signal to be sent to your process when the receiver
493+
of its standard output closes early. This results in an exception
494+
like :code:`BrokenPipeError: [Errno 32] Broken pipe`. To handle this
495+
case, wrap your entry point to catch this exception as follows::
496+
497+
import os
498+
import sys
499+
500+
def main():
501+
try:
502+
# simulate large output (your code replaces this loop)
503+
for x in range(10000):
504+
print("y")
505+
# flush output here to force SIGPIPE to be triggered
506+
# while inside this try block.
507+
sys.stdout.flush()
508+
except BrokenPipeError:
509+
# Python flushes standard streams on exit; redirect remaining output
510+
# to devnull to avoid another BrokenPipeError at shutdown
511+
devnull = os.open(os.devnull, os.O_WRONLY)
512+
os.dup2(devnull, sys.stdout.fileno())
513+
sys.exit(1) # Python exits with error code 1 on EPIPE
514+
515+
if __name__ == '__main__':
516+
main()
517+
518+
Do not set :const:`SIGPIPE`'s disposition to :const:`SIG_DFL`
519+
in order to avoid :exc:`BrokenPipeError`. Doing that would cause
520+
your program to exit unexpectedly also whenever any socket connection
521+
is interrupted while your program is still writing to it.

0 commit comments

Comments
 (0)