[perl] "inappropriate ioctl for device"

I have a Perl script running in an AIX box.

The script tries to open a file from a certain directory and it fails to read the file because file has no read permission, but I get a different error saying inappropriate ioctl for device.

Shouldn't it say something like no read permissions for file or something similar?

What does this inappropriate ioctl for device message mean?

How can I fix it?

EDIT: This is what I found when I did 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)

This question is related to perl ioctl

The answer is


Odd errors like "inappropriate ioctl for device" are usually a result of checking $! at some point other than just after a system call failed. If you'd show your code, I bet someone would rapidly point out your error.


I got the error Can't open file for reading. Inappropriate ioctl for device recently when I migrated an old UB2K forum with a DBM file-based database to a new host. Apparently there are multiple, incompatible implementations of DBM. I had a backup of the database, so I was able to load that, but it seems there are other options e.g. moving a perl script/dbm to a new server, and shifting out of dbm?.


"inappropriate ioctl for device" is the error string for the ENOTTY error. It used to be triggerred primarily by attempts to configure terminal properties (e.g. echo mode) on a file descriptor that was no terminal (but, say, a regular file), hence ENOTTY. More generally, it is triggered when doing an ioctl on a device that does not support that ioctl, hence the error string.

To find out what ioctl is being made that fails, and on what file descriptor, run the script under strace/truss. You'll recognize ENOTTY, followed by the actual printing of the error message. Then find out what file number was used, and what open() call returned that file number.


"files" in *nix type systems are very much an abstract concept.

They can be areas on disk organized by a file system, but they could equally well be a network connection, a bit of shared memory, the buffer output from another process, a screen or a keyboard.

In order for perl to be really useful it mirrors this model very closely, and does not treat files by emulating a magnetic tape as many 4gls do.

So it tried an "IOCTL" operation 'open for write' on a file handle which does not allow write operations which is an inappropriate IOCTL operation for that device/file.

The easiest thing to do is stick an " or die 'Cannot open $myfile' statement at the end of you open and you can choose your own meaningful message.


Ran into this error today while trying to use code to delete a folder/files that are living on a Windoze 7 box that's mounted as a share on a Centos server. Got the inappropriate icotl for device error and tried everything that came to mind. Read just about every post on the net related to this.

Obviously the problem was isolated to the mounted Windoze share on the Linux server. Looked at the file permissions on the Windoze box and noted the files had their permissions set to read only.

Changed those, went back to the Linux server and all worked as expected. This may not be the solution for most but hopefully it saves someone some time.


Since this is a fatal error and also quite difficult to debug, maybe the fix could be put somewhere (in the provided command line?):

export GPG_TTY=$(tty)

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


Eureka moment!

I have had this error before.

Did you invoke the perl debugger with something like :-

perl -d yourprog.pl > log.txt

If so whats going on is perl debug tries to query and perhaps reset the terminal width. When stdout is not a terminal this fails with the IOCTL message.

The alternative would be for your debug session to hang forever because you did not see the prompt for instructions.


I just fixed this perl bug. See https://rt.perl.org/Ticket/Display.html?id=124232

When we push the buffer layer to PerlIO and do a failing isatty() check which obviously fails on all normal files, ignore the wrong errno ENOTTY.


I tried the following code that seemed to work:

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