【问题标题】:Can't set file descriptor to blocking mode无法将文件描述符设置为阻塞模式
【发布时间】:2019-09-26 14:03:40
【问题描述】:

我正在尝试编写最短的代码来获得阻塞文件描述符。

我先设置:O_NONBLOCK
第二:我的文件描述符的 ICANON、[VMIN]、[VTIME]...

我还需要设置哪些选项来设置阻塞文件描述符?

(sample.txt 是空的 & open() 不同的模式没有任何机会)


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


void set_blocking(int fd, int blocking) {

    int flags = fcntl(fd, F_GETFL, 0);

    if (blocking)
        flags &= ~O_NONBLOCK;
    else
        flags |= O_NONBLOCK;

    fcntl(fd, F_SETFL, flags);

    return;
}

int main(){

        int fd;
        char buff[100];
        struct termios options;

        options.c_lflag &= ~ICANON;

        options.c_cc[VMIN] = 2;
        options.c_cc[VTIME] = 0;

        fd = open("sample.txt",O_RDWR);

        tcsetattr(fd, TCSANOW, &options);

        set_blocking(fd,1);

        read(fd,buff,2);

        printf("%s\n",buff);

        return 0;
}

【问题讨论】:

  • 推荐使用fcntl()获取并保存原始终端设置,以便您可以在退出前恢复它们。并修改它们,而不是从头开始设置。
  • tcsetattr 仅适用于特殊终端设备文件,不适用于普通文件。我怀疑你的“sample.txt”是一个终端。
  • 您不检查任何系统调用的错误返回。如果您想知道为什么系统调用无法按预期工作,您必须诊断错误返回。至少使用perror 来显示错误原因。请在此处发布之前执行此操作。
  • 在我删除有关终端和终端选项的代码后,(因为据我所知,我不需要它们)代码仍然不等待空的 sample.txt 这是普通的文本文件。如果我有一个简约的示例代码,它在调用普通文本文件时具有等待读取功能,我将不胜感激。

标签: c linux file-descriptor termios


【解决方案1】:

您的代码只修改了未初始化的struct termios options 变量的一部分。当您的代码调用tcsetattr 时,大部分options 变量将被设置为随机位,因此tcsetattr 可能会返回错误或将虚假设置应用于终端。

由于您的代码仅显式修改某些终端设置,初始化 options 变量的最佳方法是使用对 tcgetattr 的调用将旧设置读入其中:

    ret = tcgetattr(fd, &options);
    if (ret < 0) {
        perror("tcgetattr");
        exit(1);
    }

    options.c_lflag &= ~ICANON;

    options.c_cc[VMIN] = 2;
    options.c_cc[VTIME] = 0;

    ret = tcsetattr(fd, TCSANOW, &options);
    if (ret < 0) {
        perror("tcsetattr");
        exit(1);
    }

上面的代码示例假定文件描述符fd 链接到终端,因此isatty(fd) 返回1。当fd 链接到普通文件时,它根本不适用。

在您发布的代码中,fd 链接到当前目录中名为“sample.txt”的文件,该文件不太可能是终端。在这种情况下,tcgetattrtcsetattr 调用将返回 -1 并将 errno 设置为 ENOTTY

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多