如何检查是否标准输入仍然没有阻止打开?(How to check if stdin is still

2019-08-21 15:58发布

我需要我的程序写在纯C停止执行时,标准输入被关闭。

有一个在程序主循环进行无限期的工作,也没有办法,我可以使用阻塞检查(如getc()有(没有数据被认为标准输入到达-它只是停留打开未知的时间)。

我打算在实现的inetd,xinetd的或它们的类似物托管的网络守护进程的使用描述的功能 - 同时连接保持打开它应该发出在标准输出上的数据并将其正确关闭时完成工作。 现在我的计划是由托管服务杀死,因为它不会连接终止后停止。

我不知道如果fctntl()O_NONBLOCK适用于标准输入描述符标志将允许我使用read()在非阻塞模式功能? 我应该使用select()不知何故?

PS数据是不应该,但可能到达标准输入。 非阻塞读出的方式woould是这个问题的答案。

Answer 1:

选择()正是你想要做什么:信号操作(读,在这种情况下)上的文件描述符(文件,插座,不管)不会阻止。

#include <stdio.h>
#include <sys/select.h>

int is_ready(int fd) {
    fd_set fdset;
    struct timeval timeout;
    int ret;
    FD_ZERO(&fdset);
    FD_SET(fd, &fdset);
    timeout.tv_sec = 0;
    timeout.tv_usec = 1;
    //int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
     struct timeval *timeout);
    return select(fd+1, &fdset, NULL, NULL, &timeout) == 1 ? 1 : 0;
}

现在,您可以在使用前检查文件描述符,例如为了清空文件描述符:

void empty_fd(int fd) {
    char buffer[1024];
    while (is_ready(fd)) {
        read(fd, buffer, sizeof(buffer));
    }
}

在你的情况,使用的fileno(标准输入),以获得标准输入的文件描述符:

if (is_ready(fileno(stdin))) {
    /* read stuff from stdin will not block */
}


Answer 2:

我不知道是否适用于标准输入描述符fctntl()与O_NONBLOCK标志将允许我使用read()在非阻塞模式功能?

与O_NONBLOCK运行标准输入了选择具有优势。 选择说有一些数据,但没多少。 有迹象表明,要获得所有可用数据的时间,但不封锁,不论多少在队列中。 选择运行每个角色看起来很多工作繁忙... O_NONBLOCK并没有为我工作。 这是一个内部标志,在大部分的tty驱动不暴露。

检查出的ioctl(... FIONBIO)。 它似乎把工作做好。



Answer 3:

我不知道你是否能在标准输入设为O_NONBLOCK,但select()poll()肯定会完成这项工作。



Answer 4:

这有什么错feof(stdin)



Answer 5:

是的,你可以使用select (以零超时)。 你并不需要设置文件描述符非阻塞,但-如果select告诉你的文件描述符可读,然后read它肯定不会阻止。

因此,调查文件描述符0 occaisionally与select ,如果它是可读, read它。 如果read返回0,那么这意味着它已经关闭。



文章来源: How to check if stdin is still opened without blocking?