Typischerweise ignoriert man anstelle des Fangens von SIGPIPE
diese, was dazu führt, dass write
mit EPIPE
fehlschlägt anstatt dass Ihr Programm still beendet wird.
Allerdings: Wenn Sie ein SIGPIPE
erhalten, wenn Sie in ein Rohr schreiben, dann versuchen Sie es nicht erneut. Es wird niemals funktionieren. SIGPIPE
bedeutet, dass das Rohr keinen Leser hat -- und wenn das Rohr jetzt keinen Leser hat, wird es niemals einen Leser haben. (Denken Sie darüber nach: Wie könnte ein Rohr ohne Leser einen bekommen? Es ist unmöglich!)
Ihr Problem ist, dass Sie das andere Ende des Rohrs schließen. Beheben Sie das und kümmern Sie sich nicht um SIGPIPE
. SIGPIPE
ist nur das Symptom.
Bearbeitung: Hier gibt es zwei Fragen zu beantworten. Wenn Sie beide Fragen nicht beantworten können, versuchen Sie nicht, SIGPIPE
zu behandeln.
-
Was würde dazu führen, dass mein Programm SIGPIPE
empfängt? Der einzige Weg, SIGPIPE
zu empfangen, ist, dass das Lesenende des Rohrs geschlossen wird. Dies passiert, wenn der Leseprozess abstürzt oder programmiert ist, um das Rohr zu schließen. Wenn Sie einen Netzwerkserver schreiben oder mit einem unbekannten Prozess kommunizieren, könnte dies häufig vorkommen. Wenn Sie jedoch beide Programme schreiben und beide lokal laufen, deutet dies wahrscheinlich auf einen Programmierfehler hin.
-
Was sollte mein Programm tun, wenn es SIGPIPE
fängt? Wenn Sie einen Client-Prozess schreiben, der eine Pipe zur Kommunikation mit einem Server verwendet, was sollen Sie mit SIGPIPE
tun? Sie können nicht erneut versuchen, und Clients können normalerweise den Server, mit dem sie verbunden sind, nicht neu starten. Tun Sie einfach das Vernünftige und lassen Sie SIGPIPE
Ihr Programm beenden. Wenn der Server jedoch Daten an einen von ihm gesteuerten Client sendet und SIGPIPE
empfängt, könnte er den Client neu starten. Aber das könnte eine sehr schlechte Idee sein -- zum Beispiel, wenn der Client deterministisch ist, wird er einfach abstürzen und Sie werden mit einer Endlosschleife anstelle eines einfachen Absturzes enden.
Also lautet die allgemeine Maxime hier "Fange nur Fehler, die du bereit bist zu behandeln." Fangen Sie Fehler nicht nur der Vollständigkeit halber. Lassen Sie sie einfach Ihr Programm beenden oder die Operation zum Scheitern bringen, und Sie können später zurückgehen und debuggen.
Code-Schnipsel: Dies ist ein Ausschnitt aus einem meiner Projekte. Wenn Sie es ausführen, wird SIGPIPE
Ihren Prozess nicht beenden. Stattdessen wird write
einen EPIPE
-Fehler generieren. Wenn Sie einen Netzwerkserver schreiben, ist EPIPE
eine mögliche Art und Weise, wie ein Client plötzlich die Verbindung trennen könnte.
void
ignore_sigpipe(void)
{
struct sigaction act;
int r;
memset(&act, 0, sizeof(act));
act.sa_handler = SIG_IGN;
act.sa_flags = SA_RESTART;
r = sigaction(SIGPIPE, &act, NULL);
if (r)
err(1, "sigaction");
}