This signal is raised when a program writes to a socket or fifo that has no readers. The default action of this signal is to cause the program to terminate.
You might see this message if you have a series of commands in a shell pipe line and one of the processes quits. Eg:
$ cat somefile | head
After “head” has printed out the first 10 lines and quits, “cat” will get a pipe error. However, cat catches the signal and quits gracefully. If you pipe the output of some cvs(1) commands into less(1) and quit, then you might see the shell print out a message as cvs doesn’t handle this signal gracefully.
// google suche nach “sigpipe”, 2. ergebnis
falls dir die erklärung aber nichts hilft, kann ichs gerne noch mal mit eigenen worten versuchen
sowas hab ich schon auch gelesen, ich weiss nur nicht wie ich das anwenden soll? Heisst dass, ich muss einfach das write()machen, und wenn “-1” zurückkommt kam das SigPipe Signal (oder es gab einen Fehler)?
Oder muss ich das Sigpipe Signal irgendwie speziell abfangen (hab die trshell noch nicht, da kommen doch auch Signale vor, muss ich die schon kennen dazu?)
timed.c: In function `main':
timed.c:30: warning: implicit declaration of function `write'
timed.c:39: warning: implicit declaration of function `close'
… hab ich falsche flags für den gcc gesetzt oder woher kommt das ??? bzw. was ist das
noch ein (hoffentlich) letztes mal zu sigpipe. mein bisheriger code:
while (write (othersocketchild [...]) != -1) {
[...]
}
close (othersocketchild);
exit (EXIT_SUCCESS);
heisst das also, dass meine letzten beiden zeilen nicht noetig sind, er bei einem sigpipe also schon vorher terminiert und gar nicht soweit kommt? dann waere es immerhin noch sinnvoll, fehlerabfrage zu machen, weil write () ja auch wegen anderen sachen -1 returnen kann…
noch eine frage:
soll man den port, den man benutzen soll irgendwie ueber den output von /usr/bin/id ermittelt oder einfach per #define an den anfang machen?
ist egal ob du den hardcodest oder getuid() aufrufst
Fehlerabfrage für write auf jeden Fall. Schöner wäre es auch wenn du das SIGPIPE abfängst, zB SIG_IGN und danach errno auf EPIPE prüfst, dann terminiert dein Programm auch gescheit.
Arghh, was heisst dass denn jetzt schon wieder. Kannst du das vielleicht noch ein bisschen in Kot umformulieren, vielleicht check ichs dann besser?
Im Moment siehts so bei mir aus
das was du geschrieben hast is nur die fehlerabfrage, passt auch wenn du dir den prozess von sigpipe killen lässt.
wenn du für sigpipe mit sigaction das signal ignorierst (SIG_IGN) (>manpage) wirft dein write auch einen fehler, und du kannst prüfen ob errno==EPIPE dann weisst du nämlich dass die pipe geschlossen wurde und kein sonstiger fehjler aufgetreten ist
Ich habe jedoch eine kleine Bbesonderheit bei der Behandlung von accept:
Wenn mir ein Client durch eine unterbrochene Terminalverbindung abgurkt (SIGPIPE wird mit SIG_IGN behandelt), läuft das accept mit einem EINTR schief. Vermutlich ein SIGCHLD während dem accept. Soweit so gut.
Mit kreativem Einsatz von if und errno macht das Programm auch so in etwa was es soll.
Vielleicht nochmal zur Erklaerung, warum es sinnvoll (aber nicht unbedingt notwendig) ist, das SIGPIPE abzufangen und dann mit exit(EXIT_SUCCESS); zu beenden:
Der Prozess, der diesen beendeten Prozess dann mit waitpid/wait abfaengt bekommt so ueber den Rueckgabewert die Information, dass dieser ordnungsgemaess beendet wurde. Wenn SIGPIPE direkt beendet wuerde da ein Fehlerstatus drinstehen.
Die Sache mit dem unterbrochenen accept ist ganz normal und deshalb muss accept auch neu gestartet werden, wenn accept fehlschlaegt und die errno danach gleich EINTR ist. Unterbrochen wird das durch das SIGCHLD, in dessen Signalhandler ja die terminierten Sohnprozesse aufgesammelt werden sollen.
" free(socket)" ist nicht so ganz richtig, du willst (vermutlich) den socket, also einen filedescriptor schliesen, das geht mit close(socket); . free darf nur auf Pointer angewandt werden, die malloc, realloc oder calloc mal zurueckgeliefert haben.
Scheinbar nicht. Hätte ich aber auch gerne! Nur leider steht auch in der accept-manpage nix von einem EINTR oder dieser Erscheinung drin. Kann mir jemand verraten, wie man sowas anstellt? Ansonsten werden meine Childprozesse jetzt eben so lange aufgehoben, bis der timed beendet wird.
Update: es bleibt immer nur ein Prozess übrig. Alle anderen werden entfernt, soweit vorhanden. Aber erst, wenn eine neue Verbindung aufgebaut wird…
Dafür müsste accept aber auch unterbrochen werden, oder? Und wenn bei mir accept unterbricht ohne ein Socket zu liefern, ist es aus! Da mein timed aber munter weiterläuft, kann bei mir kein EINTR auftreten.
Denke schon… wüsste jedenfalls nicht, was es sonst sein soll.