"inappropriate ioctl for device"
Asked Answered
N

12

87

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)
Naara answered 22/10, 2009 at 5:30 Comment(8)
If you suspect the permissions - have you already tried setting the read permissions on the file in question?Classified
Response to update: That's an open for write/append, not read, and it's succeeding.Scab
yes but ioctl is failing for that filehandle. any idea why?Naara
@Naara : its failing becoz ioctl is expeceting a serial file(/dev/tty) and NOT a text file(/local/logs/xxx/xxxxServer.log). Hence inappriporate iotcl for deviceNaara
Yes, as I point out in my post, it's not an error at all. Well, it's an expected error that's not exposed at the abstraction level you're using, anyway :)Scab
but my perl script we are using $!..which was catching "Inappropriate ioctl for device" when we were opening a file.. while open was failing for some other reason..we were catching ioctl' error in $!.. So we must never trust $! in perl..Naara
Again, no. Read my answer. You can trust $! if you use it properly.Scab
Or ysth's answer, for that matter. :)Scab
S
54

Most likely it means that the open didn't fail.

When Perl opens a file, it checks whether or not the file is a TTY (so that it can answer the -T $fh filetest operator) by issuing the TCGETS ioctl against it. If the file is a regular file and not a tty, the ioctl fails and sets errno to ENOTTY (string value: "Inappropriate ioctl for device"). As ysth says, the most common reason for seeing an unexpected value in $! is checking it when it's not valid -- that is, anywhere other than immediately after a syscall failed, so testing the result codes of your operations is critically important.

If open actually did return false for you, and you found ENOTTY in $! then I would consider this a small bug (giving a useless value of $!) but I would also be very curious as to how it happened. Code and/or truss output would be nifty.

Scab answered 22/10, 2009 at 7:20 Comment(1)
memoizing well in advance of actual use/need. where this is a bit of a waste is on a busy server opening/closing sockets... which perl also tests to see if they are tty'sGerdagerdeen
R
26

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.

Roebuck answered 22/10, 2009 at 6:31 Comment(4)
Does die always check $!? For example, die "my bad!\n" does not explicitly reference $! -- but I am getting the OP's error message.Riesman
@wcochran: die wouldn't be showing a message based on $1, but it can change the error code for the process (which will be $! || $? >> 8 || 255 )Roebuck
So using die should only be used for errors that are generated by system calls I suppose. Thanks.Riesman
@wcochran: no, not at all. if you care what exit code your process gives, avoid die and explicitly exit(somenumber). but if you don't, die will just try to use a code that has some meaning rather than just using a single default value. this isn't a bad thing.Roebuck
K
11

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

Kaseykasha answered 27/4, 2019 at 0:4 Comment(3)
Whatever you are talking about, it seems to be something different than this question?Roebuck
Yes. It was a mistake, but I didn't delete because surprisingly it got an upvote. Maybe it could be useful for someone lost here.Kaseykasha
This answer indeed solved my problem. I encountered the "inappropriate ioctl for device" error message when using maven-gpg-plugin (inside WSL, in case that matters).Underweight
V
9

"inappropriate ioctl for device" is the error string for the ENOTTY error. It used to be triggered 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.

Vada answered 22/10, 2009 at 6:6 Comment(0)
K
7

"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.

Kakalina answered 22/10, 2009 at 6:7 Comment(0)
C
4

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.

Cremona answered 3/4, 2015 at 10:31 Comment(1)
As perl5 decided not to fix this bug (as usual), you have to use cperl, which did fix it.Cremona
K
2

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.

Kakalina answered 22/10, 2009 at 8:21 Comment(0)
B
0

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.

Baku answered 10/3, 2013 at 18:16 Comment(0)
E
0

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";
}
Extinct answered 4/2, 2015 at 17:44 Comment(0)
F
0

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?.

Filet answered 11/12, 2020 at 8:3 Comment(0)
D
0

I also get this error "inappropriate ioctl for device" when try to fetch file stat. It was first time when I got a chance to work on perl script.

my $mtime = (stat("/home/ec2-user/sample/test/status.xml"))[9]

Above code snippet was throwing error. Perl script was written in version 5.12 on Windows, and I have to run it on amazon linux having perl 5.15.

In my case error was because of Array index out of bond ( In java language sense).

When I modified code my $var = (stat("/home/ec2-user/sample/test/status.xml"))[0][9]; error gone and I get correct value.

Of course, it is too late to answer, but I am posting my finding so that it can be helpful for developer community. If some perl expert can verify this, it will be great..

Diction answered 14/6, 2022 at 14:16 Comment(0)
S
0

FWIW, I received the Inappropriate ioctl for device error on a file that I had made immutable...and forgot :P

chattr -i (filename) fixed it.

Syndic answered 2/8, 2023 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.