“不适当的ioctl设备'用C错误 [英] 'Inappropriate ioctl for device' error in C

查看:2194
本文介绍了“不适当的ioctl设备'用C错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个残培()功能,我的导师给我,这是越来越键盘输入不点击ENTER键。但是,当我在Ubuntu 12在Eclipse中运行它,我得到以下错误:

I have a getch() function which my tutor gave me, which is getting input from the keyboard without clicking on 'ENTER'. But, when I run it in Ubuntu 12 in Eclipse, I get the following error:

tcsetattr(): Inappropriate ioctl for device
tcsetattr ICANON: Inappropriate ioctl for device

这是我的code:

#include <stdio.h>
#include <unistd.h>
#include <termios.h>

char getch();

int main(int argc, const char* argv[])
{
    char c;
    do
    {
        c=getch();
        printf("%c",c);
    } while(c!='q');

    return 0;
}

char getch()
{
    char buf = 0;
    struct termios old = {0};
    if (tcgetattr(0, &old) < 0)
        perror("tcsetattr()");
    old.c_lflag &= ~ICANON;
    old.c_lflag &= ~ECHO;
    old.c_cc[VMIN] = 1;
    old.c_cc[VTIME] = 0;

    if (tcsetattr(0, TCSANOW, &old) < 0)
        perror("tcsetattr ICANON");
    if (read(0, &buf, 1) < 0)
        perror ("read()");
    old.c_lflag |= ICANON;
    old.c_lflag |= ECHO;
    if (tcsetattr(0, TCSADRAIN, &old) < 0)
        perror ("tcsetattr ~ICANON");
    return (buf);
}

注:code不用在SSH工作安全Shell。但是,我有我的Ubuntu得到这个工作,因为我写我的code那里。
谢谢

NOTE: The code DOES work in SSH Secure Shell. But I have to get this work in my Ubuntu, since I write my code there. Thanks

推荐答案

这可能是因为Eclipse是不提供的 伪终端应用于IDE下运行的程序。试试这个另类依赖于非阻塞I / O,而不是终端的控制。

This is probably because Eclipse is not providing a pseudoterminal to programs run under the IDE. Try this alternative which relies on nonblocking I/O rather than terminal controls.

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define perror_exit(msg) do { perror(msg); exit(1); } while(0)

#if defined EAGAIN && defined EWOULDBLOCK
#define retry_p(err) ((err) == EAGAIN || (err) == EWOULDBLOCK)
#elif defined EAGAIN
#define retry_p(err) ((err) == EAGAIN)
#elif defined EWOULDBLOCK
#define retry_p(err) ((err) == EWOULDBLOCK)
#else
#error "Don't know how to detect read-would-block condition."
#endif

int
main(void)
{
    int flags = fcntl(0, F_GETFL);
    if (flags == -1)
        perror_exit("fcntl(F_GETFL)");
    flags |= O_NONBLOCK;
    if (fcntl(0, F_SETFL, flags))
        perror_exit("fcntl(F_SETFL, O_NONBLOCK)");

    for (;;)
    {
       char ch;
       ssize_t n = read(0, &ch, 1);
       if (n == 1)
       {
           putchar(ch);
           if (ch == 'q')
               break;
       }
       else if (n < 0 && !retry_p(errno))
          perror_exit("read");
    }
    return 0;
}

如果这仍然不起作用,尝试修改它做的两个的这是什么呢,什么你的残培()确实,忽略失败的 tcsetattr tcgetattr 的errno == ENOTTY

If this still doesn't work, try modifying it to do both what this does and what your getch() does, ignoring failure of tcsetattr and tcgetattr when errno == ENOTTY.

请注意,无论这和你原来的code是忙等待I / O,这是不好的做法。你什么确实的应该是使用 ncurses的库做,其中有一个更复杂的方法来同时处理,并等待适合具有多任务环境更好,也输入,缺的一TTY您的问题和任意数量的,你不希望其他低级别交易头痛浪费在努力。

Note that both this and your original code are busy-waiting for I/O, which is bad practice. What you really should be doing is using the ncurses library, which has a more sophisticated approach to simultaneous processing and waiting for input that fits better with a multitasking environment, and also deals with your lack-of-a-tty problem and any number of other low-level headaches that you don't want to waste effort on.

这篇关于“不适当的ioctl设备'用C错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆