O que faz um processo Unix morrer com cachimbo quebrado?

30

Aqui estão algumas opções em que pensei, sem saber qual é a correta.

  1. Ocorreu um erro de E / S na leitura do tubo.
  2. O processo de gravação na outra extremidade do tubo morreu com uma falha.
  3. Todos os processos que poderiam gravar no canal o fecharam.
  4. O buffer de gravação do pipe está cheio.
  5. O ponto fechou a outra direção do tubo duplex.
  6. A gravação falhou porque não há processos que possam ler do canal.
  7. Uma chamada do sistema retornou o erro EPIPE e não havia nenhum manipulador de erros instalado.
siamii
fonte
Qual a sua pergunta? Você está perguntando qual deles está correto ou se há outras coisas que podem causar o cano quebrado?
EightBitTony 29/07
@EightBitTony Qual destes está correto #
siamii

Respostas:

38

Um processo recebe um SIGPIPE quando tenta gravar em um canal (nomeado ou não) ou soquete do tipo SOCK_STREAM que não possui nenhum leitor restante.

Geralmente é um comportamento desejado. Um exemplo típico é:

find . | head -n 1

Você não deseja findcontinuar executando uma vez headfinalizado (e depois fechou o único descritor de arquivo aberto para leitura nesse canal).

O yescomando normalmente depende desse sinal para terminar.

yes | some-command

Irá escrever "y" até que algum comando termine.

Observe que não é apenas quando os comandos saem, é quando todos os leitores fecham suas leituras fd no canal. Em:

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

Haverá 1 (o subshell), depois 2 (subshell + sleep), depois 1 (subshell) e 0 leitura fd do canal após o subshell explicitamente fechar seu stdin, e é nesse momento yesque receberá um SIGPIPE.

Acima, a maioria das conchas usa um pipe(2)tempo ksh93usa a socketpair(2), mas o comportamento é o mesmo nesse sentido.

Quando um processo ignora a SIGPIPE, a chamada sistema de escrita (em geral write, mas poderia ser pwrite, send, splice...) retorna com um EPIPEerro. Portanto, os processos que desejam manipular o tubo quebrado manualmente geralmente ignoram o SIGPIPE e agem com um erro do EPIPE.

Stéphane Chazelas
fonte
14

6)

A gravação falhou porque não há processos que possam ler do canal.

Embora, a menos que você duplique descritores e bifurcações, só pode haver um processo para começar: geralmente um canal possui um leitor e um gravador e, quando um deles fecha a conexão, o canal está desativado. Se você estiver usando um canal nomeado, poderá fazer várias conexões (em série) com ele, mas cada uma representa um novo canal nesse sentido. Portanto, um "canal" para um encadeamento ou processo é sinônimo de um descritor de arquivo.

De man 7 pipe:

Se todos os descritores de arquivo referentes à extremidade de leitura de um canal foram fechados, uma gravação (2) fará com que um sinal SIGPIPE seja gerado para o processo de chamada. Se o processo de chamada estiver ignorando esse sinal, a gravação (2) falhará com o erro EPIPE.

Portanto, um "cano quebrado" é para o escritor o que é EOF para o leitor.

Cachinhos Dourados
fonte
0

Um tubo quebrado ocorre quando o processo de leitura sai antes do processo de gravação. Então eu iria com (6)

SidJ
fonte
2
Pode haver vários processos de leitura ou gravação em um canal, e o mesmo processo pode ser de leitura e gravação. Além disso, não se trata de sair, é de fechar o descritor de arquivo.
Stéphane Chazelas