76 votes

"inapproprié ioctl pour le périphérique"

J'ai un script Perl qui tourne dans une boîte AIX.

Le script essaie d'ouvrir un fichier à partir d'un certain répertoire et il échoue à lire le fichier car le fichier n'a pas la permission de lecture, mais j'obtiens une erreur différente disant inappropriate ioctl for device.

Ne devrait-il pas dire quelque chose comme no read permissions for file ou quelque chose de similaire ?

Que signifie ce message inappropriate ioctl for device ?

Comment puis-je le réparer ?

MODIFICATION : Voici ce que j'ai trouvé quand j'ai fait strace.

open("/local/logs/xxx/xxxxServer.log", O\_WRONLY|O\_CREAT|O\_APPEND|O\_LARGEFILE, 
    0666) = 4 \_llseek(4, 0, \[77146\], SEEK\_END) = 0
ioctl(4, SNDCTL\_TMR\_TIMEBASE or TCGETS, 0xbffc14f8) = -1 ENOTTY 
    (Inappropriate ioctl for  device)

0 votes

Si vous soupçonnez les autorisations - avez-vous déjà essayé de définir les permissions de lecture sur le fichier en question?

1 votes

Réponse à la mise à jour : C'est une ouverture pour écrire / ajouter, pas pour lire, et cela réussit.

0 votes

Oui mais ioctl échoue pour ce handle de fichier. une idée pourquoi?

50voto

hobbs Points 71946

Il est très probable que cela signifie que l'ouverture n'a pas échoué.

Lorsque Perl ouvre un fichier, il vérifie si le fichier est un terminal (afin de pouvoir répondre à l'opérateur de test de fichier -T $fh) en exécutant l'appel système TCGETS sur celui-ci. Si le fichier est un fichier ordinaire et non un terminal, l'appel système échoue et définit errno à ENOTTY (valeur de chaîne : "Appel système inapproprié pour le périphérique"). Comme le dit ysth, la raison la plus courante de voir une valeur inattendue dans $! est de le vérifier lorsqu'il n'est pas valide -- c'est-à-dire, n'importe où autre qu'immédiatement après un échec de l'appel système, donc tester les codes de résultat de vos opérations est extrêmement important.

Si open a réellement renvoyé false pour vous, et que vous avez trouvé ENOTTY dans $! alors je considérerais cela comme un léger bug (retournant une valeur inutile de $!) mais je serais aussi très curieux de savoir comment cela s'est produit. Le code et/ou la sortie de truss seraient intéressants.

0 votes

Mémorisation bien à l'avance de l'utilisation/besoin réel. L'endroit où cela est un peu gaspillé est sur un serveur occupé ouverture/fermeture de sockets... que perl teste également pour voir s'ils sont des tty's.

25voto

ysth Points 54757

Les erreurs étranges telles que "inappropriate ioctl for device" sont généralement le résultat de la vérification de $! à un moment autre que juste après un appel système échoué. Si vous montrez votre code, je parie que quelqu'un soulignerait rapidement votre erreur.

1 votes

Est-ce que die vérifie toujours $!? Par exemple, die "my bad!\n" ne fait pas explicitement référence à $! -- mais je reçois le message d'erreur de l'OP.

0 votes

@wcochran: die ne montrerait pas un message basé sur $1, mais il peut changer le code d'erreur pour le processus (qui sera $! || $? >> 8 || 255)

0 votes

Ainsi, l'utilisation de die devrait uniquement être utilisée pour les erreurs générées par des appels système je suppose. Merci.

9voto

Martin v. Löwis Points 61768

"inappropriate ioctl for device" est la chaîne d'erreur pour l'erreur ENOTTY. Il était principalement déclenché par des tentatives de configuration des propriétés du terminal (par exemple, le mode d'écho) sur un descripteur de fichier qui n'était pas un terminal (mais, disons, un fichier régulier), d'où ENOTTY. Plus généralement, il est déclenché lors de l'exécution d'un ioctl sur un périphérique qui ne prend pas en charge cet ioctl, d'où la chaîne d'erreur.

Pour savoir quel ioctl échoue, et sur quel descripteur de fichier, exécutez le script sous strace/truss. Vous reconnaîtrez ENOTTY, suivi de l'impression réelle du message d'erreur. Ensuite, découvrez quel numéro de fichier a été utilisé, et quel appel open() a renvoyé ce numéro de fichier.

7voto

James Anderson Points 18253

"fichiers" dans les systèmes de type *nix sont très largement un concept abstrait.

Ils peuvent être des zones sur le disque organisées par un système de fichiers, mais ils pourraient tout aussi bien être une connexion réseau, un morceau de mémoire partagée, le tampon de sortie d'un autre processus, un écran ou un clavier.

Pour que perl soit vraiment utile, il reflette très étroitement ce modèle, et ne traite pas les fichiers en émulant une bande magnétique comme le font de nombreux langages de 4GL.

Il a donc essayé une opération "IOCTL" 'ouvrir en écriture' sur une poignée de fichier qui n'autorise pas les opérations en écriture, ce qui est une opération IOCTL inappropriée pour ce périphérique/fichier.

La chose la plus simple à faire est de mettre une instruction "or die 'Impossible d'ouvrir $myfile' à la fin de votre ouverture et vous pouvez choisir votre propre message significatif.

2voto

James Anderson Points 18253

Moment Eureka!

J'ai déjà eu cette erreur avant.

Avez-vous invoqué le débogueur Perl avec quelque chose comme :-

perl -d yourprog.pl > log.txt

Si c'est le cas, ce qui se passe est que le débogage Perl essaie d'interroger et peut-être de réinitialiser la largeur du terminal. Lorsque stdout n'est pas un terminal, cela échoue avec le message IOCTL.

L'alternative serait que votre session de débogage reste suspendue pour toujours car vous n'avez pas vu le prompt pour les instructions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X