Re: [PATCH] scripts: handle BrokenPipeError for python scripts

Kees Cook
2023-01-12T22:14:32Z

On Thu, Jan 12, 2023 at 11:30:06AM +0900, Masahiro Yamada wrote:
> def main():
> try:
> # simulate large output (your code replaces this loop)
> for x in range(10000):
> print("y")
> # flush output here to force SIGPIPE to be triggered
> # while inside this try block.
> sys.stdout.flush()
> except BrokenPipeError:
> # 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) # Python exits with error code 1 on EPIPE

I still think this is wrong -- they should not continue piping, and
should just die with SIGPIPE. It should simply be:

signal(SIGPIPE, SIG_DFL);

Nothing else needed. No wasted CPU cycles, shell handling continues as
per normal.

> if __name__ == '__main__':
> main()
>
> Do not set SIGPIPE’s disposition to SIG_DFL in order to avoid
> BrokenPipeError. Doing that would cause your program to exit
> unexpectedly whenever any socket connection is interrupted while
> your program is still writing to it.

This advise is for socket programs, not command-line tools.

-Kees

--
Kees Cook