Blob Blame History Raw
From 0bed778c53a4f93b1b092b3db33e8c36aabfa39d Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Tue, 5 Jan 2021 17:00:21 +0100
Subject: [PATCH] python/semanage: empty stdout before exiting on
 BrokenPipeError

Empty stdout buffer before exiting when BrokenPipeError is
encountered. Otherwise python will flush the bufer during exit, which
may trigger the exception again.
https://docs.python.org/3/library/signal.html#note-on-sigpipe

Fixes:
   #semanage fcontext -l | egrep -q -e '^/home'
   BrokenPipeError: [Errno 32] Broken pipe
   Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
   BrokenPipeError: [Errno 32] Broken pipe

Note that the error above only appears occasionally (usually only the
first line is printed).

Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
---
 python/semanage/semanage | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/python/semanage/semanage b/python/semanage/semanage
index b2bd9df9..1abe3536 100644
--- a/python/semanage/semanage
+++ b/python/semanage/semanage
@@ -26,6 +26,7 @@
 import traceback
 import argparse
 import sys
+import os
 PROGNAME = "selinux-python"
 try:
     import gettext
@@ -953,6 +954,13 @@ def do_parser():
         args = commandParser.parse_args(make_args(sys.argv))
         args.func(args)
         sys.exit(0)
+    except BrokenPipeError as e:
+        sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
+        # Python flushes standard streams on exit; redirect remaining output
+        # to devnull to avoid another BrokenPipeError at shutdown
+        devnull = os.open(os.devnull, os.O_WRONLY)
+        os.dup2(devnull, sys.stdout.fileno())
+        sys.exit(1)
     except IOError as e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
         sys.exit(1)
-- 
2.29.2