Question

Un script Perl s'exécute dans une zone AIX.

Le script tente d'ouvrir un fichier à partir d'un certain répertoire et ne parvient pas à le lire car le fichier n'a pas de droit de lecture, mais un message d'erreur ioctl inapproprié pour le périphérique est généré.

Ne devrait-il pas dire quelque chose comme aucune permission de lecture pour le fichier ou quelque chose de similaire?

Que signifie ce message ioctl inapproprié pour le périphérique ?

Comment puis-je résoudre ce problème?

EDIT: C’est ce que j’ai trouvé en faisant 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)
Était-ce utile?

La solution

Cela signifie probablement que l'ouverture n'a pas échoué .

Lorsque Perl ouvre un fichier, il vérifie s'il est ou non un TTY (afin de pouvoir répondre à l'opérateur de fichier -T $ fh ) en émettant le TCGETS ioctl contre. Si le fichier est un fichier normal et non un tty, l'ioctl échoue et définit errno sur ENOTTY (valeur de chaîne: "ioctl inapproprié pour le périphérique"). Comme indiqué par ysth, la raison la plus courante de voir une valeur inattendue dans $! est de la vérifier lorsqu'elle n'est pas valide - c'est-à-dire partout autre que juste après l'échec d'un appel système. Il est donc extrêmement important de tester les codes de résultat de vos opérations.

Si open vous a effectivement renvoyé la valeur false et que vous avez trouvé ENOTTY dans $! , je considérerais cela comme un petit bug (donnant une valeur inutile de $! ) mais je serais aussi très curieux de savoir comment cela s'est passé. La sortie de code et / ou de structure serait astucieuse.

Autres conseils

Erreurs étranges telles que "ioctl inapproprié pour le périphérique". sont généralement le résultat de la vérification $! à un moment autre que juste après l'échec d'un appel système. Si vous montriez votre code, je parie que quelqu'un signalerait rapidement votre erreur.

" fichiers " Les systèmes de type in * nix sont très abstraits.

Il peut s’agir de zones organisées sur un disque organisées par un système de fichiers, mais il peut également s'agir d’une connexion réseau, d’un peu de mémoire partagée, de la mémoire tampon produite par un autre processus, d’un écran ou d’un clavier.

Pour que Perl soit vraiment utile, il reproduit très fidèlement ce modèle et ne traite pas les fichiers en émulant une bande magnétique, contrairement à beaucoup de lecteurs de 4 lbs.

Il a donc essayé un " IOCTL " opération "open for write" sur un descripteur de fichier qui n'autorise pas les opérations d'écriture, ce qui est une opération IOCTL inappropriée pour ce périphérique / ce fichier.

Le plus simple est de coller un " ou mourir "Vous ne pouvez pas ouvrir $ myfile" à la fin de votre ouverture et vous pouvez choisir votre propre message significatif.

"ioctl inapproprié pour le périphérique" est la chaîne d'erreur associée à l'erreur ENOTTY. Auparavant, il était principalement déclenché par des tentatives de configuration des propriétés du terminal (par exemple, le mode echo) sur un descripteur de fichier qui n'était pas un terminal (mais, par exemple, un fichier normal), donc 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 est créé qui é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. Recherchez ensuite quel numéro de fichier a été utilisé et quel appel open () a renvoyé ce numéro de fichier.

Je viens de corriger ce bogue Perl. Voir https://rt.perl.org/Ticket/Display.html?id= 124232

Lorsque nous poussons la couche tampon vers PerlIO et effectuons une vérification isatty () qui échoue qui échoue évidemment sur tous les fichiers normaux, ignore le mauvais errno ENOTTY.

Moment Eurêka!

J'ai déjà eu cette erreur.

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

perl -d yourprog.pl > log.txt

Si tel est le cas, Perl Debug essaie d'interroger et éventuellement de réinitialiser la largeur du terminal. Lorsque stdout n’est pas un terminal, le message IOCTL échoue.

L'alternative serait que votre session de débogage soit suspendue pour toujours car vous ne voyez pas l'invite pour obtenir des instructions.

Puisqu'il s'agit d'une erreur fatale et également assez difficile à déboguer, le correctif pourrait peut-être être placé quelque part (dans la ligne de commande fournie?):

export GPG_TTY=$(tty)

De: https://github.com/keybase/keybase-issues/issues / 2798

Nous nous sommes heurtés à cette erreur aujourd'hui en essayant d'utiliser du code pour supprimer un dossier / des fichiers hébergés sur une boîte Windoze 7 montée en tant que partage sur un serveur Centos. Vous avez l'icotl inapproprié pour l'erreur de périphérique et essayez tout ce qui vous passe par la tête. Lisez à peu près tous les posts sur le net qui y sont liés.

Évidemment, le problème était isolé du partage Windoze monté sur le serveur Linux. Regardé sur les autorisations de fichier sur la boîte de dialogue Windoze et a noté que les autorisations de fichiers étaient définies en lecture seule.

Changé ceux-ci, est retourné sur le serveur Linux et tout a fonctionné comme prévu. Ce n'est peut-être pas la solution pour la plupart des gens, mais j'espère que cela fera gagner du temps à quelqu'un.

J'ai essayé le code suivant qui semblait fonctionner:

if(open(my $FILE, "<File.txt")) {
    while(<$FILE>){
    print "

J'ai essayé le code suivant qui semblait fonctionner:

<*>";} } else { print "File could not be opened or did not exists\n"; }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top