如果我使用O_NDELAY,为什么errno会设置EAGAIN?从dev / tty读取

时间:2013-03-10 08:09:21

标签: c unix system-calls

我有这个:

//...
      if ((tty = open("/dev/tty",O_RDONLY | O_NDELAY) ) == -1 )
        {
                perror("/dev/tty");
                return 1;
        }
        //...
        if (-1 == (fi = open(argv[1], O_RDONLY)) )
        {
                perror(argv[1]);
                return 1;
        }
        //...
        while (1)
        {
                printf("you have five seconds to enter a line number %d", line); 
                sleep(5);
                i = read(tty, buf, 257);
                printf("read %d\n", i);
                if ( i == -1) {
                        perror("dev/tty/"); 
                        // if nothing was entered read always returns -1
                        //and perror prints: Resource temporarily unavailable. it's STRANGE!!!
                }
                if ( i == 0 )
                {
                        lseek(fi, 0, SEEK_SET);
                        while((i = read(fi, buf, BUFSIZ)) > 0) 
                              write(1, buf, i);
                        return 0;
                }
                //...
                if ( 0 == read(fi, buf, lines_length[line]))
                {
                        fprintf(stderr,"can't read\n");
                        return 1;
                }
                write(1, buf, lines_length[line]);
        }
 //...

所以我用O_NDELAY标志打开/ dev / tty,但看起来有点不对,因为后来的read返回-1(它必须返回0)。我找不出有什么问题。   还有一个问题:为什么 printf(“你有5秒”)写入后打印(1,buf,lines_length [line]);

2 个答案:

答案 0 :(得分:4)

  

如果没有输入,则read始终返回-1并且perror打印:   资源暂时不可用。它的奇怪!!!

这正是O_NDELAY应该做的事情。它不会等待读取操作完成。如果无法立即执行,则不会阻止它返回-1并设置errno = EAGAIN


至于你的第二个问题,你不会刷新输出。尝试:fflush(stdout)

答案 1 :(得分:1)

在早期版本的UNIX系统中,使用标志为O_NDELAY的非阻塞操作。如果设置了O_NDELAY,则读取返回0.由于它与Unix约定相矛盾(返回0表示文件结束),POSIX.1定义了非阻塞模式的标志 - O_NONBLOCK。现在标志O_NDELAY仅用于兼容性,不应在现代应用程序中使用。