¿Qué hace que un proceso de Unix muera con la tubería rota?

30

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

  1. Hubo un error de E / S en la lectura de la tubería.
  2. El proceso de escritura en el otro extremo de la tubería murió con un error.
  3. Todos los procesos que podrían escribir en la tubería la han cerrado.
  4. El búfer 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 procesos que puedan leer desde la tubería.
  7. Una llamada al sistema devolvió el error EPIPE y no se instaló ningún controlador de errores.
siamii
fuente
¿Cuál es tu pregunta? ¿Está preguntando cuál de ellos es correcto o si hay otras cosas que pueden causar la tubería rota?
EightBitTony
@EightBitTony ¿Cuál de estos es correcto?
siamii

Respuestas:

38

Un proceso recibe un SIGPIPE cuando intenta escribir en una tubería (con nombre o no) o en un socket de tipo SOCK_STREAM que no tiene ningún lector.

Generalmente es un comportamiento deseado. Un ejemplo típico es:

find . | head -n 1

No querrá findseguir ejecutándose una vez que headhaya finalizado (y luego haya cerrado el único descriptor de archivo abierto para leer en esa tubería).

El yescomando generalmente se basa en esa señal para terminar.

yes | some-command

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

Tenga en cuenta que no es solo cuando los comandos salen, es cuando todos los lectores han cerrado su lectura fd a la tubería. En:

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

Habrá 1 (la subshell), luego 2 (subshell + sleep), luego 1 (subshell) luego 0 fd lectura de la tubería después de que la subshell cierre explícitamente su stdin, y es entonces cuando yesrecibirá un SIGPIPE.

Arriba, la mayoría de los shells usan a pipe(2)while ksh93y a socketpair(2), pero el comportamiento es el mismo en ese sentido.

Cuando un proceso ignora el SIGPIPE, la llamada al sistema de escritura (por lo general write, pero podría ser pwrite, send, splice...) vuelve con un EPIPEerror. Por lo tanto, los procesos que desean manejar la tubería rota manualmente ignorarían SIGPIPE y tomarían medidas ante un error EPIPE.

Stéphane Chazelas
fuente
14

(6)

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

Aunque a menos que duplique los descriptores y la bifurcación, solo puede haber un proceso para comenzar: en general, una tubería tiene un lector y un escritor, y cuando uno de ellos cierra la conexión, la tubería está desactivada. Si está utilizando una tubería con nombre, puede hacer múltiples conexiones (en serie) con ella, pero cada una representa una nueva tubería en este sentido. Entonces, una "tubería" a un hilo o proceso es sinónimo de un descriptor de archivo.

De man 7 pipe:

Si todos los descriptores de archivos que se refieren al final de lectura de una tubería se han cerrado, entonces una escritura (2) hará que se genere una señal SIGPIPE para el proceso de llamada. Si el proceso de llamada ignora esta señal, entonces la escritura (2) falla con el error EPIPE.

Entonces, un "tubo roto" es para el escritor lo que EOF es para el lector.

encerrada dorada
fuente
0

Una tubería rota ocurre cuando el proceso de lectura sale antes que el proceso de escritura. Entonces iría con (6)

SidJ
fuente
2
Puede haber varios procesos de lectura o escritura en una tubería, y el mismo proceso puede ser lectura y escritura. Además, no se trata de salir, se trata de cerrar el descriptor de archivo.
Stéphane Chazelas