J'ai un petit problème avec l'utilisation de la fonction ioctl FIONREAD
sur une socket sur Solaris.
Normalement, quand on est réveillé d'un select, on peut interroger une
socket avec ioctl(fd,FIONREAD,&nb) pour récupérer dans nb le nombre
d'octets à lire sur la socket.
Si nb==0, c'est que la socket a été fermée de l'autre côté et qu'on peut
la fermer de son côté.
Or, sur Solaris, il semble pouvoir arriver que FIONREAD renvoie 0 alors
que la socket n'est pas fermé. Si l'on attend un peu et que l'on refait
un appel à FIONREAD, alors on finit par avoir une valeur != 0
correspondant à ce qu'on attend.
Je rencontrais le problème d'un appel à FIONREAD qui retournait 0 alors
que la socket n'était pas fermée et c'est le code d'un proxy de SuSe
(http://www.suse.de/~mt/proxy-suite/) qui m'a mis sur la voie :
static int socket_ll_FIONREAD(HLS *hls, int *len)
{
int ret;
errno=0;
ret=ioctl(hls->sock, FIONREAD, len);
#if defined(COMPILE_DEBUG)
debug(4, "ll_FIONREAD: ret=%d, len=%d for %s %d=%s",
ret, *len, hls->ctyp, hls->sock, hls->peer);
#endif
if(0 > ret) {
#if defined(__sun__)
/*
** we are running on solaris - wait a little bit...
*/
if(0 == *len && 0 == errno && (++hls->retr <
MAX_RETRIES)) {
syslog_write(T_DBG,
"can't get num of bytes: %s %d=%s - retry %d",
hls->ctyp, hls->sock,
hls->peer, hls->retr);
usleep(10000);
return 1; /* retry */
}
#endif
syslog_error("can't get num of bytes: %s %d=%s",
hls->ctyp, hls->sock, hls->peer);
hls->ernr = errno;
close(hls->sock);
hls->sock = -1;
return -1;
}
return ret;
}
Le commentaire "we are running on solaris - wait a little bit..." me
laisse songeur car je n'ai rien trouvé dans la documentation Solaris qui
justifie ça.
Quelqu'un sait-il quelque chose à ce propos ?
Merci d'avance pour toute piste, lien, info permettant d'éclairer le sujet.
--
Arnaud
(Supprimez les geneurs pour me répondre)
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Laurent Wacrenier
Arnaud Meurgues écrit:
Or, sur Solaris, il semble pouvoir arriver que FIONREAD renvoie 0 alors que la socket n'est pas fermé. Si l'on attend un peu et que l'on refait un appel à FIONREAD, alors on finit par avoir une valeur != 0 correspondant à ce qu'on attend.
Si le but du ioctl est de voir si la socket est fermée, fait un select() ou un poll() en lecture avant. À la place de ioctl(FIONREAD), tu peux essayer de lancer recv(...,...,1,MSG_PEEK) pour voir s'il y a un octet dans queue.
Or, sur Solaris, il semble pouvoir arriver que FIONREAD renvoie 0 alors
que la socket n'est pas fermé. Si l'on attend un peu et que l'on refait
un appel à FIONREAD, alors on finit par avoir une valeur != 0
correspondant à ce qu'on attend.
Si le but du ioctl est de voir si la socket est fermée, fait un
select() ou un poll() en lecture avant. À la place de ioctl(FIONREAD),
tu peux essayer de lancer recv(...,...,1,MSG_PEEK) pour voir s'il y a
un octet dans queue.
Or, sur Solaris, il semble pouvoir arriver que FIONREAD renvoie 0 alors que la socket n'est pas fermé. Si l'on attend un peu et que l'on refait un appel à FIONREAD, alors on finit par avoir une valeur != 0 correspondant à ce qu'on attend.
Si le but du ioctl est de voir si la socket est fermée, fait un select() ou un poll() en lecture avant. À la place de ioctl(FIONREAD), tu peux essayer de lancer recv(...,...,1,MSG_PEEK) pour voir s'il y a un octet dans queue.
Arnaud Meurgues
Laurent Wacrenier wrote:
Si le but du ioctl est de voir si la socket est fermée, fait un
Non. Le but est de connaître le nombre d'octets à lire dans la socket.
tu peux essayer de lancer recv(...,...,1,MSG_PEEK) pour voir s'il y a un octet dans queue.
Ok, merci. Mais ce comportement de Solaris sur FIONREAD est-il connu ?
-- Arnaud (Supprimez les geneurs pour me répondre)
Laurent Wacrenier wrote:
Si le but du ioctl est de voir si la socket est fermée, fait un
Non. Le but est de connaître le nombre d'octets à lire dans la socket.
tu peux essayer de lancer recv(...,...,1,MSG_PEEK) pour voir s'il y a
un octet dans queue.
Ok, merci. Mais ce comportement de Solaris sur FIONREAD est-il connu ?
--
Arnaud
(Supprimez les geneurs pour me répondre)
A> Or, sur Solaris, il semble pouvoir arriver que FIONREAD renvoie 0 A> alors que la socket n'est pas fermé. C'est un solaris 2.8 ?
Oui.
-- Arnaud (Supprimez les geneurs pour me répondre)
ts
"A" == Arnaud Meurgues writes:
A> ts wrote:
C'est un solaris 2.8 ?
A> Oui.
C'est un problème connu sur Solaris 8 : il est fréquent que solaris soit impossible de lire des données sur le socket alors que ioctl() a signaler que des données étaient disponibles : il retourne alors une lecture de zéro byte.
Suivant les softs j'ai vu traité cela de façon très variable (erreur, fermeture du socket, ré-essayer ...)
--
Guy Decoux
"A" == Arnaud Meurgues <arnaud@meurgues.non.fr.invalid> writes:
A> ts wrote:
C'est un solaris 2.8 ?
A> Oui.
C'est un problème connu sur Solaris 8 : il est fréquent que solaris soit
impossible de lire des données sur le socket alors que ioctl() a signaler
que des données étaient disponibles : il retourne alors une lecture de
zéro byte.
Suivant les softs j'ai vu traité cela de façon très variable (erreur,
fermeture du socket, ré-essayer ...)
C'est un problème connu sur Solaris 8 : il est fréquent que solaris soit impossible de lire des données sur le socket alors que ioctl() a signaler que des données étaient disponibles : il retourne alors une lecture de zéro byte.
Suivant les softs j'ai vu traité cela de façon très variable (erreur, fermeture du socket, ré-essayer ...)
--
Guy Decoux
Arnaud Meurgues
ts wrote:
C'est un problème connu sur Solaris 8 : il est fréquent que solaris soit impossible de lire des données sur le socket alors que ioctl() a signaler que des données étaient disponibles : il retourne alors une lecture de zéro byte.
Cool. Je vais essayer de trouver une référence à ce problème sur le site de Sun. J'avais déjà cherché, mais sans succès.
Suivant les softs j'ai vu traité cela de façon très variable (erreur, fermeture du socket, ré-essayer ...)
C'est bizarre qu'en réessayant, ça marche...
Merci, -- Arnaud (Supprimez les geneurs pour me répondre)
ts wrote:
C'est un problème connu sur Solaris 8 : il est fréquent que solaris soit
impossible de lire des données sur le socket alors que ioctl() a signaler
que des données étaient disponibles : il retourne alors une lecture de
zéro byte.
Cool. Je vais essayer de trouver une référence à ce problème sur le site
de Sun. J'avais déjà cherché, mais sans succès.
Suivant les softs j'ai vu traité cela de façon très variable (erreur,
fermeture du socket, ré-essayer ...)
C'est bizarre qu'en réessayant, ça marche...
Merci,
--
Arnaud
(Supprimez les geneurs pour me répondre)
C'est un problème connu sur Solaris 8 : il est fréquent que solaris soit impossible de lire des données sur le socket alors que ioctl() a signaler que des données étaient disponibles : il retourne alors une lecture de zéro byte.
Cool. Je vais essayer de trouver une référence à ce problème sur le site de Sun. J'avais déjà cherché, mais sans succès.
Suivant les softs j'ai vu traité cela de façon très variable (erreur, fermeture du socket, ré-essayer ...)
C'est bizarre qu'en réessayant, ça marche...
Merci, -- Arnaud (Supprimez les geneurs pour me répondre)
ts
"A" == Arnaud Meurgues writes:
Suivant les softs j'ai vu traité cela de façon très variable (erreur, fermeture du socket, ré-essayer ...)
A> C'est bizarre qu'en réessayant, ça marche...
Non, d'après ce que j'ai compris : il est en erreur (ie. il ne peut accéder aux données) juste au moment au ioctl() a signalé des données, attendez un peu et il peut y accéder.
En fait, il faudrait avoir le source et le bug pour savoir exactement ce qui se passe.
--
Guy Decoux
"A" == Arnaud Meurgues <arnaud@meurgues.non.fr.invalid> writes:
Suivant les softs j'ai vu traité cela de façon très variable (erreur,
fermeture du socket, ré-essayer ...)
A> C'est bizarre qu'en réessayant, ça marche...
Non, d'après ce que j'ai compris : il est en erreur (ie. il ne peut
accéder aux données) juste au moment au ioctl() a signalé des données,
attendez un peu et il peut y accéder.
En fait, il faudrait avoir le source et le bug pour savoir exactement ce
qui se passe.
Suivant les softs j'ai vu traité cela de façon très variable (erreur, fermeture du socket, ré-essayer ...)
A> C'est bizarre qu'en réessayant, ça marche...
Non, d'après ce que j'ai compris : il est en erreur (ie. il ne peut accéder aux données) juste au moment au ioctl() a signalé des données, attendez un peu et il peut y accéder.
En fait, il faudrait avoir le source et le bug pour savoir exactement ce qui se passe.
--
Guy Decoux
Arnaud Meurgues
ts wrote:
A> C'est bizarre qu'en réessayant, ça marche...
Non, d'après ce que j'ai compris : il est en erreur (ie. il ne peut accéder aux données) juste au moment au ioctl() a signalé des données, attendez un peu et il peut y accéder.
En fait, il faudrait avoir le source et le bug pour savoir exactement ce qui se passe.
Vi. Malheureusement, j'ai eu beau chercher sur le site de Sun, je n'ai rien trouvé sur ce sujet. Le problème ne semble même pas être référencé.
-- Arnaud (Supprimez les geneurs pour me répondre)
ts wrote:
A> C'est bizarre qu'en réessayant, ça marche...
Non, d'après ce que j'ai compris : il est en erreur (ie. il ne peut
accéder aux données) juste au moment au ioctl() a signalé des données,
attendez un peu et il peut y accéder.
En fait, il faudrait avoir le source et le bug pour savoir exactement ce
qui se passe.
Vi. Malheureusement, j'ai eu beau chercher sur le site de Sun, je n'ai
rien trouvé sur ce sujet. Le problème ne semble même pas être référencé.
--
Arnaud
(Supprimez les geneurs pour me répondre)
Non, d'après ce que j'ai compris : il est en erreur (ie. il ne peut accéder aux données) juste au moment au ioctl() a signalé des données, attendez un peu et il peut y accéder.
En fait, il faudrait avoir le source et le bug pour savoir exactement ce qui se passe.
Vi. Malheureusement, j'ai eu beau chercher sur le site de Sun, je n'ai rien trouvé sur ce sujet. Le problème ne semble même pas être référencé.
-- Arnaud (Supprimez les geneurs pour me répondre)
ts
"A" == Arnaud Meurgues writes:
A> Vi. Malheureusement, j'ai eu beau chercher sur le site de Sun, je n'ai A> rien trouvé sur ce sujet. Le problème ne semble même pas être A> référencé.
Je ne suis même pas sur que c'est considéré comme un bug par Sun. Un autre exemple
Solaris 8, when doing SLEMR direct connect msging, frequently (but not always) is unable to read data on a socket on which ioctl() has reported data are available, but a zero-byte read returns. Current logic is to treat this as a failed connection; and, therefore slers.c:blocking_socket_read() and slers.c:partial_socket_read() return SLEPI_ERROR.
Il n'y aucune erreur, ce qui vous laisse penser que vous avez reçu une réponse mais quand vous essayez de lire il retourne zéro byte : cela surprend ...
--
Guy Decoux
"A" == Arnaud Meurgues <arnaud@meurgues.non.fr.invalid> writes:
A> Vi. Malheureusement, j'ai eu beau chercher sur le site de Sun, je n'ai
A> rien trouvé sur ce sujet. Le problème ne semble même pas être
A> référencé.
Je ne suis même pas sur que c'est considéré comme un bug par Sun. Un autre
exemple
Solaris 8, when doing SLEMR direct connect msging, frequently
(but not always) is unable to read data on a socket on which
ioctl() has reported data are available, but a zero-byte read
returns. Current logic is to treat this as a failed connection;
and, therefore slers.c:blocking_socket_read() and
slers.c:partial_socket_read() return SLEPI_ERROR.
Il n'y aucune erreur, ce qui vous laisse penser que vous avez reçu une
réponse mais quand vous essayez de lire il retourne zéro byte : cela
surprend ...
A> Vi. Malheureusement, j'ai eu beau chercher sur le site de Sun, je n'ai A> rien trouvé sur ce sujet. Le problème ne semble même pas être A> référencé.
Je ne suis même pas sur que c'est considéré comme un bug par Sun. Un autre exemple
Solaris 8, when doing SLEMR direct connect msging, frequently (but not always) is unable to read data on a socket on which ioctl() has reported data are available, but a zero-byte read returns. Current logic is to treat this as a failed connection; and, therefore slers.c:blocking_socket_read() and slers.c:partial_socket_read() return SLEPI_ERROR.
Il n'y aucune erreur, ce qui vous laisse penser que vous avez reçu une réponse mais quand vous essayez de lire il retourne zéro byte : cela surprend ...
--
Guy Decoux
Arnaud Meurgues
ts wrote:
Il n'y aucune erreur, ce qui vous laisse penser que vous avez reçu une réponse mais quand vous essayez de lire il retourne zéro byte : cela surprend ...
Effectivement. C'est plus qu'étrange. Si encore c'était documenté... Bon, j'ai contacté le support de Sun pour voir ce qu'ils seraient capable de me dire à ce sujet.
Merci beaucoup pour votre aide. -- Arnaud (Supprimez les geneurs pour me répondre)
ts wrote:
Il n'y aucune erreur, ce qui vous laisse penser que vous avez reçu une
réponse mais quand vous essayez de lire il retourne zéro byte : cela
surprend ...
Effectivement. C'est plus qu'étrange. Si encore c'était documenté...
Bon, j'ai contacté le support de Sun pour voir ce qu'ils seraient
capable de me dire à ce sujet.
Merci beaucoup pour votre aide.
--
Arnaud
(Supprimez les geneurs pour me répondre)
Il n'y aucune erreur, ce qui vous laisse penser que vous avez reçu une réponse mais quand vous essayez de lire il retourne zéro byte : cela surprend ...
Effectivement. C'est plus qu'étrange. Si encore c'était documenté... Bon, j'ai contacté le support de Sun pour voir ce qu'ils seraient capable de me dire à ce sujet.
Merci beaucoup pour votre aide. -- Arnaud (Supprimez les geneurs pour me répondre)