Question: If I run these commands:

```
dmesg | head -n 10

```

I presume the OS sends back some kind of signal to `dmesg` once `head` has read 10 lines. How does this work? What does `head` tell the kernel?

This is different from a program dying since this is a normal, 'clean' stop.

Answer: 
Take a look at the [POSIX specification for the `write()` function](http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html):

> 
> The `write()` function shall fail if:
> 
> 
> … An attempt is made to write to a pipe or FIFO that is not open for reading by any process, or that only has one end open. A SIGPIPE signal shall also be sent to the thread.
> 
> 
> 

So the sequence of events is:

1. The `head` process exits. This causes all its open file descriptors to be closed, including its standard input, which is one end of the pipe.
2. The `dmesg` process calls `write()` on its standard output, which is the other end of the pipe.
3. This causes a SIGPIPE to be delivered to the `dmesg` process.
4. `dmesg` has no special handling of SIGPIPE, so the default action is applied, which is to terminate the process.

You can experiment with this by changing the action for the SIGPIPE signal. For example, this pipeline terminates after printing one line:

```
$ yes | head -1
y
$

```

but if you ignore SIGPIPE, then it doesn't terminate:

```
$ trap '' PIPE
$ yes | head -1
y

```

At this point the `yes` process is still trying to write to the pipe but the writes are failing with EPIPE.
`head` closes *stdin* after printing 10 lines. Then `dmesg` detects that the *stdout* is closed and exits.

To be more precise, `dmesg` will receive the `EPIPE` error from the `write` call to *stdout*.

From the *dmesg.c* source code here: <https://github.com/karelzak/util-linux/blob/v2.27.1/sys-utils/dmesg.c#L654-L659>

```c
rc = fwrite(p, 1, len, out) != len;
if (rc != 0) {
    if (errno != EPIPE)
        err(EXIT_FAILURE, _("write failed"));
    exit(EXIT_SUCCESS);
}

```