amend to 39d4bb3c35 (#2758): better reaction on broken pipe (on long output), don't close stdout explicitly (allows usage of modules like cProfile, which outputs result on exit), just flush it before exit.

pull/2842/head^2^2
sebres 2020-09-07 22:11:51 +02:00
parent f555ff45e9
commit 5abc4ba4ae
2 changed files with 19 additions and 10 deletions

View File

@ -27,13 +27,17 @@ import sys
from ..version import version, normVersion from ..version import version, normVersion
from ..protocol import printFormatted from ..protocol import printFormatted
from ..helpers import getLogger, str2LogLevel, getVerbosityFormat from ..helpers import getLogger, str2LogLevel, getVerbosityFormat, BrokenPipeError
# Gets the instance of the logger. # Gets the instance of the logger.
logSys = getLogger("fail2ban") logSys = getLogger("fail2ban")
def output(s): # pragma: no cover def output(s): # pragma: no cover
print(s) try:
print(s)
except (BrokenPipeError, IOError) as e: # pragma: no cover
if e.errno != 32: # closed / broken pipe
raise
# Config parameters required to start fail2ban which can be also set via command line (overwrite fail2ban.conf), # Config parameters required to start fail2ban which can be also set via command line (overwrite fail2ban.conf),
CONFIG_PARAMS = ("socket", "pidfile", "logtarget", "loglevel", "syslogsocket") CONFIG_PARAMS = ("socket", "pidfile", "logtarget", "loglevel", "syslogsocket")
@ -310,12 +314,16 @@ class Fail2banCmdLine():
def _exit(code=0): def _exit(code=0):
# implicit flush without to produce broken pipe error (32): # implicit flush without to produce broken pipe error (32):
sys.stderr.close() sys.stderr.close()
sys.stdout.close() try:
# exit: sys.stdout.flush()
if hasattr(os, '_exit') and os._exit: # exit:
os._exit(code) if hasattr(sys, 'exit') and sys.exit:
else: sys.exit(code)
sys.exit(code) else:
os._exit(code)
except (BrokenPipeError, IOError) as e: # pragma: no cover
if e.errno != 32: # closed / broken pipe
raise
@staticmethod @staticmethod
def exit(code=0): def exit(code=0):

View File

@ -224,9 +224,10 @@ def __stopOnIOError(logSys=None, logHndlr=None): # pragma: no cover
sys.exit(0) sys.exit(0)
try: try:
BrokenPipeError BrokenPipeError = BrokenPipeError
except NameError: # pragma: 3.x no cover except NameError: # pragma: 3.x no cover
BrokenPipeError = IOError BrokenPipeError = IOError
__origLog = logging.Logger._log __origLog = logging.Logger._log
def __safeLog(self, level, msg, args, **kwargs): def __safeLog(self, level, msg, args, **kwargs):
"""Safe log inject to avoid possible errors by unsafe log-handlers, """Safe log inject to avoid possible errors by unsafe log-handlers,