¿Qué hace que un process de Unix muera con Broken pipe?

Aquí hay algunas opciones en las que pensé, no estoy seguro de cuál es la correcta.

  1. Hubo un error de E / S en la tubería.
  2. El process de escritura en el otro extremo de la tubería murió con una falla.
  3. Todos los processs que pudieron escribir en la tubería lo han cerrado.
  4. El buffer de escritura de la tubería está lleno.
  5. El par ha cerrado la otra dirección de la tubería dúplex.
  6. La escritura falló porque no hay processs que puedan leer desde la tubería.
  7. Una llamada al sistema devolvió el error EPIPE y no se instaló ningún controller de errores.

Un process recibe un SIGPIPE cuando intenta escribir en un conducto (con nombre o no) o un socket de tipo SOCK_STREAM que no tiene lector.

En general, es un comportamiento deseado. Un ejemplo típico es:

find . | head -n 1 

No desea que siga funcionando una vez que la head ha terminado (y luego cierra el único descriptor de file abierto para leer en esa tubería).

El command yes generalmente se basa en esa señal para terminar.

 yes | some-command 

Escribirá "y" hasta que algún command termine.

Tenga en count que no solo cuando los commands salen, sino que todo el lector ha cerrado su lectura fd al conducto. En:

 yes | ( sleep 1; exec <&-; ps -fC yes) 1 2 1 0 

Su será 1 (la subshell), luego 2 (subshell + sleep), luego 1 (subshell) luego 0 fd leyendo de la tubería después de que la subshell explícitamente cierra su stdin, y es entonces cuando yes recibirá un SIGPIPE.

Arriba, la mayoría de los proyectiles usan un pipe(2) mientras que ksh93 usa un socketpair(2) , pero el comportamiento es el mismo en ese aspecto.

Cuando un process ignora el SIGPIPE, la llamada al sistema de escritura (generalmente write , pero puede ser pwrite , send , splice …) regresa con un error EPIPE . Por lo tanto, los processs que quieran manejar la tubería rota manualmente normalmente ignorarían a SIGPIPE y tomarían medidas ante un error EPIPE.

(6)

La escritura falló porque no hay processs que puedan leer desde la tubería.

Aunque a less que duplique descriptores y fork, solo puede haber un process para comenzar: en general, un conducto tiene un lector y un escritor, y cuando uno de ellos cierra la connection, el conducto está desactivado. Si está utilizando un conducto con nombre, puede hacer múltiples conexiones (en serie) con él, pero cada uno representa un nuevo conducto en este sentido. Por lo tanto, un "conducto" para un hilo o process es sinónimo de un descriptor de file.

De man 7 pipe :

Si se han cerrado todos los descriptores de file que hacen reference al extremo de lectura de una tubería, una escritura (2) generará una señal SIGPIPE para el process de llamada. Si el process de llamada está ignorando esta señal, entonces la escritura (2) falla con el error EPIPE.

Entonces, una "tubería rota" es para el escritor lo que EOF es para el lector.

Una tubería rota ocurre cuando el process de lectura finaliza antes del process de escritura. Entonces yo iría con (6)