Under what condition does a Python subprocess get a SIGPIPE?
Question: I am reading the the Python documentation on the Popen class in the subprocess
module section and I came across the following code:

    
    
    p1 = Popen(["dmesg"], stdout=PIPE)
    p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
    p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
    output = p2.communicate()[0]
    

The
[documentation](https://docs.python.org/2/library/subprocess.html#replacing-
shell-pipeline) also states that

> "The p1.stdout.close() call after starting the p2 is important in order for
> p1 to receive a SIGPIPE if p2 exits before p1.

Why must the p1.stdout be closed before we can receive a SIGPIPE and how does
p1 knows that p2 exits before p1 if we already closed it?


Answer: `SIGPIPE` is a signal that would be sent if `dmesg` tried to write to a closed
pipe. Here, `dmesg` ends up with _two_ targets to write to, your Python
process and the `grep` process.

That's because `subprocess` clones file handles (using the [`os.dup2()`
function](https://docs.python.org/2/library/os.html#os.dup2)). Configuring
`p2` to use `p1.stdout` triggers a `os.dup2()` call that asks the OS to
duplicate the pipe filehandle; the duplicate is used to connect `dmesg` to
`grep`.

With two open file handles for `dmesg` stdout, `dmesg` is never given a
`SIGPIPE` signal if only _one_ of them closes early, so `grep` closing would
never be detected. `dmesg` would needlessly continue to produce output.

So by closing `p1.stdout` immediately, you ensure that the only remaining
filehandle reading from `dmesg` stdout is the `grep` process, and if that
process were to exit, `dmesg` receives a `SIGPIPE`.

