Avant la normalisation, il y avait ioctl(
... FIONBIO
... )
et fcntl(
... O_NDELAY
... )
, mais ceux-ci se comportaient de manière incohérente entre les systèmes, et même au sein du même système. Par exemple, il était courant FIONBIO
de travailler sur des sockets et O_NDELAY
de travailler sur des ttys, avec beaucoup d'incohérences pour des choses comme les tuyaux, les fifos et les périphériques. Et si vous ne saviez pas quel type de descripteur de fichier vous aviez, vous devrez définir les deux pour être sûr. Mais en outre, une lecture non bloquante sans données disponibles était également indiquée de manière incohérente; selon le système d'exploitation et le type de descripteur de fichier, la lecture peut renvoyer 0, ou -1 avec errno EAGAIN, ou -1 avec errno EWOULDBLOCK. Même aujourd'hui, le réglage FIONBIO
ouO_NDELAY
sous Solaris, une lecture sans données renvoie 0 sur un tty ou un tube, ou -1 avec errno EAGAIN sur un socket. Cependant 0 est ambigu car il est également renvoyé pour EOF.
POSIX a résolu ce problème avec l'introduction de O_NONBLOCK
, qui a normalisé le comportement de différents systèmes et types de descripteurs de fichiers. Parce que les systèmes existants veulent généralement éviter tout changement de comportement qui pourrait briser la compatibilité descendante, POSIX a défini un nouvel indicateur plutôt que d'imposer un comportement spécifique pour l'un des autres. Certains systèmes comme Linux traitent les trois de la même manière et définissent également EAGAIN et EWOULDBLOCK à la même valeur, mais les systèmes souhaitant conserver un autre comportement hérité pour la compatibilité descendante peuvent le faire lorsque les mécanismes plus anciens sont utilisés.
Les nouveaux programmes devraient utiliser fcntl(
... O_NONBLOCK
... )
, tel que standardisé par POSIX.
Comme @Sean l'a dit, il
fcntl()
est largement standardisé et donc disponible sur toutes les plateformes. Laioctl()
fonction est antérieurefcntl()
à Unix, mais n'est pas du tout standardisée. Le fait que celaioctl()
fonctionne pour vous sur toutes les plates-formes pertinentes pour vous est une chance, mais pas garanti. En particulier, les noms utilisés pour le deuxième argument sont obscurs et non fiables sur toutes les plates-formes. En effet, ils sont souvent propres au pilote de périphérique particulier auquel le descripteur de fichier fait référence. (Lesioctl()
appels utilisés pour un périphérique graphique bitmap fonctionnant sur un ICL Perq exécutant PNX (Perq Unix) d'il y a vingt ans ne se sont jamais traduits nulle part ailleurs, par exemple.)la source
Je crois que
fcntl()
c'est une fonction POSIX. Oùioctl()
est une chose UNIX standard. Voici une liste de POSIX io .ioctl()
est une chose très spécifique au noyau / pilote / système d'exploitation, mais je suis sûr que ce que vous utilisez fonctionne sur la plupart des versions d'Unix. certains autresioctl()
éléments peuvent ne fonctionner que sur certains OS ou même sur certains régimes de son noyau.la source