“设备不合适的ioctl”

时间:2009-10-22 05:30:41

标签: perl ioctl

我有一个在AIX框中运行的Perl脚本。

该脚本尝试从某个目录打开文件,但由于该文件没有读取权限,因此无法读取该文件,但我收到的错误是inappropriate ioctl for device

不应该说no read permissions for file或类似的东西吗?

inappropriate ioctl for device消息的含义是什么?

我该如何解决?

编辑:这是我在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)

10 个答案:

答案 0 :(得分:35)

很可能这意味着打开的没有失败

当Perl打开一个文件时,它会通过发出-T $fh ioctl来检查该文件是否是TTY(以便它可以回答TCGETS filetest操作符)。如果文件是常规文件而不是tty,则ioctl失败并将errno设置为ENOTTY(字符串值:“设备的不适当的ioctl”)。正如ysth所说,在$!中看到意外值的最常见原因是在无效时检查它 - 也就是说,其他,而不是在系统调用失败后立即检查它,因此测试您的运营结果代码至关重要。

如果open确实为您返回了false,并且您在ENOTTY中找到了$!,那么我会认为这是一个小错误(给出$!无用的值但我也很好奇它是如何发生的。代码和/或桁架输出会很漂亮。

答案 1 :(得分:19)

奇怪的错误,例如“设备不合适的ioctl”通常是检查$的结果!在系统调用失败之后的某个时刻。如果你显示你的代码,我打赌有人会迅速指出你的错误。

答案 2 :(得分:5)

* nix类型系统中的“文件”是一个非常抽象的概念。

它们可以是由文件系统组织的磁盘上的区域,但它们同样可以是网络连接,一些共享内存,来自另一个进程的缓冲区输出,屏幕或键盘。

为了让perl非常有用,它会非常密切地反映这个模型,并且不会通过模拟磁带来处理文件,而不是4gls。

因此它尝试在文件句柄上执行“IOCTL”操作“open for write”,该操作不允许对该设备/文件进行不恰当的IOCTL操作的写操作。

最简单的方法是在打开结束时粘贴“or die 'Cannot open $myfile'语句,然后您可以选择自己有意义的信息。

答案 3 :(得分:4)

“不适当的设备ioctl”是ENOTTY错误的错误字符串。它曾经主要是通过尝试在没有终端(但是,例如,常规文件)的文件描述符上配置终端属性(例如回声模式)来触发,因此是ENOTTY。更一般地说,它是在不支持ioctl的设备上执行ioctl时触发的,因此是错误字符串。

要找出失败的ioctl,以及在什么文件描述符上,运行strace / truss下的脚本。您将识别ENOTTY,然后实际打印错误消息。然后找出使用了什么文件号,以及open()调用返回该文件号。

答案 4 :(得分:2)

尤里卡时刻!

之前我遇到过此错误。

您是否通过以下方式调用perl调试器: -

perl -d yourprog.pl > log.txt

如果是这样,perl调试尝试查询并可能重置终端宽度。 当stdout不是终端时,它会因IOCTL消息而失败。

另一种方法是让你的调试会话永远挂起,因为你没有看到提示说明。

答案 5 :(得分:2)

我刚修复了这个perl bug。 见https://rt.perl.org/Ticket/Display.html?id=124232

当我们将缓冲层推送到PerlIO并执行失败的isatty()检查时 显然在所有正常文件上失败,忽略错误的错误ENOTTY。

答案 6 :(得分:1)

由于这是一个致命错误,而且调试起来也很困难,所以也许可以将修复程序放在某个地方(在提供的命令行中?):

export GPG_TTY=$(tty)

发件人:https://github.com/keybase/keybase-issues/issues/2798

答案 7 :(得分:0)

今天遇到此错误,同时尝试使用代码删除生活在作为Centos服务器上的共享的Windoze 7盒子上的文件夹/文件。得到了不恰当的icotl设备错误,并尝试了所有想到的。阅读网上与此相关的每篇文章。

显然,问题与Linux服务器上挂载的Windoze共享隔离。看着 在Windoze框的文件权限上,并注意到文件的权限设置为只读。

更改了这些,返回Linux服务器,所有工作都按预期工作。这对大多数人来说可能不是解决方案,但希望能节省一些时间。

答案 8 :(得分:0)

我尝试了以下似乎有用的代码:

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

答案 9 :(得分:0)

最近,当我将具有基于DBM文件的数据库的旧UB2K论坛迁移到新主机时,收到错误Can't open file for reading. Inappropriate ioctl for device。显然,有多个不兼容的DBM实现。我有数据库的备份,所以我能够加载它,但似乎还有其他选择,例如moving a perl script/dbm to a new server, and shifting out of dbm?