2011-04-13 4 views
5

Je travaille avec du code qui doit être sûr de tuer l'appelant en raison de SIGPIPE, mais les seules écritures de socket qu'il exécute vont à des sockets datagram (UDP et socket de datagramme de domaine Unix). Dois-je m'inquiéter de SIGPIPE? J'utilise connect sur le socket, mais des tests préliminaires (sous Linux) ont montré que je reçois simplement ECONNREFUSED sur send si personne n'écoute sur le socket du domaine Unix. Pas sûr de ce qui se passe avec UDP.Peut écrire à un socket datagramme jamais augmenter SIGPIPE?

Je peux envelopper le tout dans des hacks pour se débarrasser de SIGPIPE, mais si ce n'est pas un problème, je préfère économiser la surcharge et réduire la complexité du code.

+0

Je vais vous donner une mauvaise réponse. Je pense que je l'ai déjà vu lors du démarrage d'une application au démarrage du système Linux. Je ne peux pas dire si c'était définitivement un socket datagramme qui était le problème sous-jacent, mais pour autant que je sache, nous n'utilisions pas de socket TCP pour cette application. Juste un test pour vous de considérer si cela pourrait s'appliquer à vous. – Jeff

+0

Je pense que je pourrais juste organiser les choses à utiliser 'sendto' plutôt que' write' afin que je puisse passer ce drapeau qui désactive 'SIGPIPE'. –

Répondre

8

La réponse est dans la spécification pour send:

[EPIPE] La douille est fermée pour l'écriture ou la douille est en mode connexion et n'est plus connecté. Dans ce dernier cas, et si le socket est de type SOCK_STREAM ou SOCK_SEQPACKET et que l'indicateur MSG_NOSIGNAL n'est pas défini, le signal SIGPIPE est généré dans le thread appelant.

http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html

Ainsi, non, écrit aux sockets datagrammes ne génèrent pas SIGPIPE ou une erreur EPIPE.

+0

Le texte ci-dessus ne dit-il pas réellement que vous * pourriez * l'obtenir en UDP si "le socket est éteint pour l'écriture" (quoi que cela signifie)? –

+0

@ T.E.D .: Peut-être (si shutdown-for-write fonctionne sur une socket datagramme), mais c'est une condition qui ne se produirait pas sans intention ou erreur du programmeur. Ce n'est pas causé par le pair. –

1

Selon man 2 write sur ma boîte Debian,

EPIPE: fd est reliée à un tuyau ou d'une douille dont l'extrémité de lecture est fermée. Lorsque cela se produit, le processus d'écriture recevra également un signal SIGPIPE. (Ainsi, la valeur de retour d'écriture n'est visible que si le programme attrape, bloque ou ignore ce signal.)

Il semble qu'il est possible d'obtenir SIGPIPE lors de l'écriture sur une socket, mais il n'est pas clair si cela peut arriver pour les sockets UDP spécifiquement.

+0

La page de manuel pour 'send' est un peu plus spécifique, mais ce n'est pas aussi clair que ce que POSIX dit à propos de' send' .. –

+0

En effet, @R ... j'ai rehaussé et votre réponse secondes après que vous l'ayez posté. Je voulais juste lancer la balle avec mon message. – ikegami

8

Le groupe ouvert est une chose, et Apple en est une autre. Il est certainement possible d'obtenir un SIGPIPE sur iOS lors de l'écriture sur un socket UDP mort, comme certains de mes journaux de plantage ont révélé récemment. iOS tend à fermer les sockets UDP alors que l'application est en arrière-plan, écrire sur ces sockets peut faire apparaître un SIGPIPE.
De mon journal de plantage (avec la permission de testflightapp):

Exception dernière victime Occurrences
SIGPIPE
2 libsystem_c.dylib 0x32df47ec _sigtramp + 48
3 talk 0x0005b10e instantanée - [IPRSNetDatagramSocket envoyer: Taille: à: ] (iprs_iphone_net.m: 671) ...

ne pas rappeler ce qui se passe sous Linux, Solaris ou Windows - bien que je ne ai jamais essayé de fermer un socket et puis écrire.

+0

La fermeture d'une socket puis l'écriture ne donnera pas 'SIGPIPE' ou' EPIPE'; cela donnera 'EBADF'. iOS doit mettre la socket dans un mode spécial non standard pour provoquer 'SIGPIPE'. En tout cas ma question a été taguée POSIX parce que je cherchais le comportement standard, mais ta réponse est aussi informative. –

Questions connexes