Parce que votre programme peut être en attente d'E / S ou suspendu. Un SIGPIPE interrompt votre programme de manière asynchrone, mettant fin à l'appel système, et peut donc être traité immédiatement.
Mettre à jour
Prenons un pipeline A | B | C
.
Juste pour être précis, nous supposerons que B est la boucle de copie canonique:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
write(STDOUT,bufr,sz);
B
est bloqué sur l' appel read (2) en attente de données à partir de A
quand se C
termine. Si vous attendez le code retour de write (2) , quand B le verra-t-il? La réponse, bien sûr, n'est pas tant que A n'a pas écrit plus de données (ce qui pourrait être une longue attente - et si A était bloqué par autre chose?). Notez, en passant, que cela nous permet également un programme plus simple et plus propre. Si vous dépendiez du code d'erreur de l'écriture, vous auriez besoin de quelque chose comme:
while((sz = read(STDIN,bufr,BUFSIZE))>=0)
if(write(STDOUT,bufr,sz)<0)
break;
Une autre mise à jour
Aha, vous êtes confus sur le comportement de l'écriture. Vous voyez, lorsque le descripteur de fichier avec l'écriture en attente est fermé, le SIGPIPE se produit alors. Alors que l'écriture renverra finalement -1 , le but du signal est de vous avertir de manière asynchrone que l'écriture n'est plus possible. Cela fait partie de ce qui fait que toute la structure élégante de co-routine des tubes fonctionne sous UNIX.
Maintenant, je pourrais vous indiquer toute une discussion dans l'un des nombreux livres de programmation système UNIX, mais il y a une meilleure réponse: vous pouvez le vérifier vous-même. Écrivez un B
programme simple [1] - vous avez déjà le courage, tout ce dont vous avez besoin est un main
et quelques inclus - et ajoutez un gestionnaire de signal pour SIGPIPE
. Exécutez un pipeline comme
cat | B | more
et dans une autre fenêtre de terminal, attachez un débogueur à B et placez un point d'arrêt dans le gestionnaire de signal B.
Maintenant, tuez le plus et B devrait casser votre gestionnaire de signaux. examinez la pile. Vous constaterez que la lecture est toujours en attente. laissez le gestionnaire de signaux continuer et revenir, et regardez le résultat renvoyé par écriture - qui sera alors -1.
[1] Naturellement, vous allez écrire votre programme B en C. :-)
write
.