Porque seu programa pode estar aguardando E / S ou suspenso. Um SIGPIPE interrompe seu programa de forma assíncrona, encerrando a chamada do sistema e, portanto, pode ser tratado imediatamente.
Atualizar
Considere um pipeline A | B | C
.
Apenas para definição, vamos supor que B é o loop de cópia canônico:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
write(STDOUT,bufr,sz);
B
é bloqueado na chamada read (2) em espera por dados A
quando C
termina. Se você esperar pelo código de retorno de write (2) , quando B o verá? A resposta, é claro, não é até que A grave mais dados (o que pode ser uma longa espera - e se A for bloqueado por outra coisa?). Observe, a propósito, que isso também nos permite um programa mais simples e mais limpo. Se dependesse do código de erro de gravação, você precisaria de algo como:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
if(write(STDOUT,bufr,sz)<0)
break;
Outra atualização
Aha, você está confuso sobre o comportamento da escrita. Veja, quando o descritor de arquivo com a gravação pendente é fechado, o SIGPIPE acontece imediatamente. Embora a gravação retorne -1 eventualmente , o objetivo do sinal é notificá-lo de forma assíncrona de que a gravação não é mais possível. Isso é parte do que faz com que toda a elegante estrutura co-rotineira de tubos funcione no UNIX.
Agora, eu poderia apontar uma discussão inteira em qualquer um dos vários livros de programação de sistemas UNIX, mas há uma resposta melhor: você pode verificar isso sozinho. Escreva um B
programa simples [1] - você já tem coragem, tudo que você precisa é um main
e alguns inclusos - e adicione um manipulador de sinal para SIGPIPE
. Execute um pipeline como
cat | B | more
e em outra janela de terminal, conecte um depurador a B e coloque um ponto de interrupção dentro do manipulador de sinal B.
Agora, mate o mais e B deve interromper seu manipulador de sinal. examine a pilha. Você verá que a leitura ainda está pendente. deixe o sinal manipulador de prosseguir e retorno, e olhar para o resultado retornado por write - que irá então ser -1.
[1] Naturalmente, você escreverá seu programa B em C. :-)
write
.