O que faz um processo Unix morrer com um cano quebrado?

24

Aqui estão algumas opções que eu pensei, não tenho certeza qual é a certa.

  1. Ocorreu um erro de E / S no canal.
  2. O processo de gravação para a outra extremidade do pipe morreu com uma falha.
  3. Todos os processos que poderiam gravar no pipe o fecharam.
  4. O buffer de gravação do pipe está cheio.
  5. O peer fechou a outra direção do tubo duplex.
  6. A escrita falhou porque não há processos que possam ler do canal.
  7. Uma chamada do sistema retornou o erro EPIPE e não havia manipulador de erro instalado.
por siamii 29.07.2013 / 17:11

3 respostas

34

Um processo recebe um SIGPIPE quando tenta gravar em um pipe (chamado ou não) ou no soquete do tipo SOCK_STREAM que não tem mais nenhum leitor.

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

find . | head -n 1

Você não deseja que find continue sendo executado depois que head tenha terminado (e, em seguida, fechado o único descritor de arquivo aberto para leitura nesse canal).

O comando yes normalmente depende desse sinal para finalizar.

yes | some-command

Escreve "y" até que algum comando termine.

Note que não é apenas quando os comandos saem, é quando todo o leitor fechou a leitura fd para o pipe. Em:

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

Haverá 1 (o subshell), depois 2 (subshell + sleep), depois 1 (subshell) e depois 0 fd lendo o pipe depois que a subshell fechar explicitamente seu stdin, e é quando yes receberá um SIGPIPE .

Acima, a maioria dos shells usa pipe(2) , enquanto ksh93 usa socketpair(2) , mas o comportamento é o mesmo nesse sentido.

Quando um processo ignora o SIGPIPE, a chamada do sistema de escrita (geralmente write , mas pode ser pwrite , send , splice ...) retorna com um erro EPIPE . Portanto, os processos que desejam manipular o canal quebrado manualmente normalmente ignorariam o SIGPIPE e agiriam sobre um erro EPIPE.

    
por 29.07.2013 / 19:27
11

(6)

Writing failed because there are no processes which could read from the pipe.

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

De man 7 pipe :

If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling process. If the calling process is ignoring this signal, then write(2) fails with the error EPIPE.

Assim, um "tubo quebrado" é para o escritor o que o EOF é para o leitor.

    
por 29.07.2013 / 17:55
0

Um cano quebrado acontece quando o processo de leitura sai antes do processo de escrita. Então eu iria com (6)

    
por 29.07.2013 / 17:41

Tags