「inappropriate ioctl for device」表示给设备发送了不适当的ioctl命令,通常出现在打开设备或文件时出现,这个错误主要有两个原因:一是设备或文件不支持这个ioctl命令,二是程序使用了错误的ioctl命令。
解决办法有以下几种:
- 程序错误
在程序中使用了错误的ioctl命令,需要检查程序中使用的ioctl命令是否正确,有没有错误的拼写或使用。
示例:
int fd = open("/dev/ttyS0", O_RDWR);
if(fd < 0){
printf("Open serial device failed!\n");
return -1;
}
struct termios option;
tcgetattr(fd, &option);
option.c_cflag |= (CLOCAL | CREAD);
option.c_cflag &= ~CSIZE;
option.c_cflag |= CS8;
option.c_cflag &= ~CSTOPB;
option.c_cflag &= ~PARENB;
option.c_iflag &= ~(IXON | IXOFF | IXANY);
option.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
option.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
cfsetispeed(&option, B115200);
cfsetospeed(&option, B115200);
option.c_cc[VTIME] = 0;
option.c_cc[VMIN] = 1;
if(tcsetattr(fd, TCSANOW, &option) < 0){
printf("Set serial option failed!\n");
return -1;
}
int fl = fcntl(fd, F_GETFL, 0);
if(fl == -1){
printf("Get file status flags failed!\n");
return -1;
}
if(fcntl(fd, F_SETFL, fl | O_NONBLOCK) == -1){
printf("Set file status flags failed!\n");
return -1;
}
struct termios m_oldTermios;
bool m_bTermiosSaved = false;
if(tcgetattr(fd, &m_oldTermios) != -1)
{
m_bTermiosSaved = true;
struct termios newTermios = m_oldTermios;
if( /* optimization to only make changes if necessary */
newTermios.c_iflag & ~(IXOFF | IXON))
{
newTermios.c_iflag &= ~(IXOFF | IXON);
if(tcsetattr(fd, TCSANOW, &newTermios) == -1)
{
qWarning("GsmModule::disableSoftFlowControl: Couldn't set new termios attributes");
}
}
}
if(m_bTermiosSaved)
{
if(tcsetattr(fd, TCSANOW, &m_oldTermios) == -1)
{
qWarning("GsmModule::disableSoftFlowControl: Could not restore original tty attributes in the destructor");
}
}
- 设备或文件错误
检查设备或文件是否正确打开,以及设备或文件是否支持使用ioctl命令。
示例:
$ sudo touch /sys/kernel/debug/kgsl/graphics/fb0/bw_writeback_enabled
touch: cannot touch '/sys/kernel/debug/kgsl/graphics/fb0/bw_writeback_enabled': No such file or directory
$ sudo chmod 644 /sys/kernel/debug/kgsl/graphics/fb0/*
chmod: cannot access '/sys/kernel/debug/kgsl/graphics/fb0/*': No such file or directory
- 使用正确的ioctl命令
检查程序代码中使用的ioctl命令是否有误,以及是否传入正确的参数。
示例:
int fd;
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0) {
perror("open");
return errno;
}
struct termios tty;
memset(&tty, 0, sizeof(tty));
if (tcgetattr(fd, &tty) != 0) {
perror("tcgetattr");
return errno;
}
cfsetospeed(&tty, B115200);
cfsetispeed(&tty, B115200);
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit data */
tty.c_cflag &= ~PARENB; /* no parity */
tty.c_cflag &= ~CSTOPB; /* 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no flow control */
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
perror("tcsetattr");
return errno;
}
ioctl(fd, TCGETS, &tty);
tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 1;
ioctl(fd, TCSETS, &tty);
以上就是Linux报inappropriate ioctl for device的原因以及解决办法,需要根据具体情况适用。