it-swarm.dev

"unangemessenes ioctl für Gerät"

Ich habe ein Perl-Skript in einer AIX-Box. 

Das Skript versucht, eine Datei aus einem bestimmten Verzeichnis zu öffnen. Die Datei kann nicht gelesen werden, da die Datei keine Leseberechtigung hat. Ich erhalte jedoch eine andere Fehlermeldung, die inappropriate ioctl for device sagt. 

Sollte es nicht etwas wie no read permissions for file oder ähnliches sagen?

Was bedeutet diese inappropriate ioctl for device-Nachricht?

Wie kann ich es reparieren?

EDIT: Das habe ich gefunden, als ich strace gemacht habe.

 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 oder TCGETS, 0xbffc14f8) = -1 ENOTTY 
 (Unangemessenes Ioctl für Gerät) 
47
someguy

Höchstwahrscheinlich bedeutet dies, dass das Öffnen nicht fehlgeschlagen ist.

Wenn Perl eine Datei öffnet, prüft es, ob es sich um eine TTY-Datei handelt oder nicht (damit der -T $fh-Filetest-Operator beantwortet werden kann), indem er die Variable TCGETS ioctl dagegen ausstellt. Wenn es sich bei der Datei um eine reguläre Datei und nicht um eine TTY-Datei handelt, schlägt das ioctl fehl und setzt errno auf ENOTTY (Zeichenfolgewert: "Ungeeignetes ioctl für Gerät"). Wie Ysth sagt, besteht der häufigste Grund dafür, einen unerwarteten Wert in $! zu sehen, darin, ihn zu überprüfen, wenn er nicht gültig ist, dh other als unmittelbar nach dem Fehlschlagen eines Syscalls. Daher ist das Testen der Ergebniscodes Ihrer Operationen kritisch wichtig.

Wenn open tatsächlich falsch für Sie zurückgegeben wurde und Sie ENOTTY in $! gefunden haben, würde ich dies als einen kleinen Fehler betrachten (der einen unbrauchbaren Wert von $! ergibt), aber ich wäre auch sehr neugierig, wie es passiert ist. Code- und/oder Traversenausgabe wäre geschickt.

35
hobbs

Ungerade Fehler wie "Unangemessenes ioctl für Gerät" sind normalerweise ein Ergebnis der Prüfung von $! zu einem anderen Zeitpunkt als nach einem fehlgeschlagenen Systemaufruf. Wenn Sie Ihren Code zeigen, würde ich wetten, dass jemand schnell auf Ihren Fehler aufmerksam wird.

19
ysth

"Dateien" in * nix-Typsystemen sind sehr abstrakt.

Dies können Bereiche auf der Festplatte sein, die von einem Dateisystem organisiert werden, aber es kann sich auch um eine Netzwerkverbindung, ein bisschen gemeinsam genutzten Speicher, die Pufferausgabe eines anderen Prozesses, einen Bildschirm oder eine Tastatur handeln.

Damit Perl wirklich nützlich ist, spiegelt es dieses Modell sehr genau wider und behandelt Dateien nicht durch Emulation eines Magnetbands, wie dies bei vielen 4gls der Fall ist.

Es wurde also eine "IOCTL" -Operation "open for write" an einem Dateihandle ausprobiert, die keine Schreiboperationen zulässt, was eine ungeeignete IOCTL-Operation für dieses Gerät/diese Datei ist.

Am einfachsten ist es, eine or die 'Cannot open $myfile'-Anweisung an das Ende Ihres Open zu setzen, und Sie können Ihre eigene aussagekräftige Nachricht auswählen.

5
James Anderson

"Unpassendes ioctl für Gerät" ist die Fehlerzeichenfolge für den ENOTTY-Fehler. Es wurde früher hauptsächlich durch Versuche ausgelöst, Terminal-Eigenschaften (z. B. Echo-Modus) auf einem Dateideskriptor zu konfigurieren, der kein Terminal war (aber beispielsweise eine reguläre Datei), daher ENOTTY. Im Allgemeinen wird es ausgelöst, wenn ein Ioctl auf einem Gerät ausgeführt wird, das dieses Ioctl nicht unterstützt, daher die Fehlerzeichenfolge.

Führen Sie das Skript unter strace/truss aus, um herauszufinden, was bei ioctl fehlgeschlagen ist und auf welchem ​​Dateideskriptor es ausgeführt wird. Sie erkennen ENOTTY, gefolgt vom tatsächlichen Ausdruck der Fehlermeldung. Finden Sie dann heraus, welche Dateinummer verwendet wurde und welcher Aufruf von open () diese Dateinummer zurückgegeben hat.

4

Eureka-Moment!

Ich habe diesen Fehler schon einmal gehabt. 

Haben Sie den Perl-Debugger aufgerufen mit:

Perl -d yourprog.pl > log.txt

Wenn dies der Fall ist, versucht Perl debug die Terminalbreite abzufragen und möglicherweise zurückzusetzen. Wenn stdout kein Terminal ist, schlägt dies mit der IOCTL-Nachricht fehl.

Die Alternative wäre, dass Ihre Debug-Sitzung für immer hängen bleibt, weil Sie die Aufforderung nicht nach Anweisungen sehen.

2
James Anderson

Ich habe gerade diesen Perl-Fehler behoben ... __ Siehe https://rt.Perl.org/Ticket/Display.html?id=124232

Wenn wir die Pufferschicht auf PerlIO verschieben und eine fehlgeschlagene isatty () - Prüfung durchführen.

2
rurban

Da dies ein schwerwiegender Fehler ist und auch schwierig zu debuggen ist, könnte der Fix möglicherweise irgendwo platziert werden (in der bereitgestellten Befehlszeile?):

export GPG_TTY=$(tty)

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

1
Felipe

Dieser Fehler ist heute beim Versuch aufgetreten, Code zu verwenden, um einen Ordner bzw. Dateien zu löschen, die in einer Windoze 7-Box leben, die als Freigabe auf einem Centos-Server bereitgestellt wird. Ich bekam den unangemessenen icotl für Gerätefehler und versuchte alles, was mir in den Sinn kam. Lesen Sie so ziemlich jeden Post im Netz, der sich auf dieses Thema bezieht.

Offensichtlich war das Problem auf die gemountete Windoze-Freigabe auf dem Linux-Server zurückzuführen. Lookedat die Dateiberechtigungen für die Windoze-Box und stellte fest, dass die Berechtigungen der Dateien auf "Nur Lesen" festgelegt waren.

Veränderte diese, kehrte zum Linux-Server zurück und alles funktionierte wie erwartet. Dies ist möglicherweise nicht die Lösung für die meisten, aber hoffentlich spart es jemandem etwas Zeit.

0

Ich habe den folgenden Code ausprobiert, der zu funktionieren schien:

if(open(my $FILE, "<File.txt")) {
    while(<$FILE>){
    print "$_";}
} else {
    print "File could not be opened or did not exists\n";
}
0
Nitish