Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

fonction ioctl FIONREAD sur Solaris

10 réponses
Avatar
Arnaud Meurgues
Bonjour à tous,

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)

10 réponses

Avatar
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.

Avatar
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)

Avatar
ts
"A" == Arnaud Meurgues writes:






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 ?


--

Guy Decoux





Avatar
Arnaud Meurgues
ts wrote:

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)

Avatar
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





Avatar
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)

Avatar
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





Avatar
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)

Avatar
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





Avatar
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)