如何检查stdin是否仍然没有阻塞打开?

我需要用纯C编写的程序在stdin关闭时停止执行。

在程序主循环中有不确定的工作,并且我无法在那里使用阻塞检查(如getc() )(没有数据应该到达stdin – 它只是在未知时间保持打开状态)。

我打算在实现inetd,xinetd或其类似物中托管的网络守护程序时使用所描述的function – 它应该在连接保持打开时在stdout上发出数据,并在关闭时正确完成工作。 现在我的程序被托管服务杀死,因为它在连接终止后不会停止。

我想知道将带有O_NONBLOCK标志的fctntl()应用于stdin描述符是否允许我在非阻塞模式下使用read()函数? 我应该以某种方式使用select()吗?

PS数据不是假定的,但可能会到达stdin。 一种非阻塞读出方式应该是问题的答案。

select()完全符合你的要求:表示文件描述符(文件,套接字等)上的操作(在本例中为read)不会阻塞。

 #include  #include  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(stdin)来获取stdin的文件描述符:

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

我想知道将带有O_NONBLOCK标志的fctntl()应用于stdin描述符是否允许我在非阻塞模式下使用read()函数?

使用O_NONBLOCK运行stdin比select更有优势。 选择说有一些数据,但不是多少。 有时候,无论队列中有多少数据,您都希望获得所有可用数据,但不能阻止。 为每个角色运行选择似乎很繁忙的工作…… O_NONBLOCK对我不起作用。 它是一个内部标志,没有在大多数tty驱动程序中暴露。

看看ioctl(…,FIONBIO)。 它似乎完成了工作。

我不确定你是否可以在stdin上设置O_NONBLOCK,但是select()或者poll()肯定会完成工作。

feof(stdin)什么问题?

是的,您可以使用select (零超时)。 您不需要将文件描述符设置为非阻塞,但是如果select告诉您文件描述符是可读的,那么read它肯定不会阻塞。

因此,使用select轮询文件描述符0,如果它是可读的, read它。 如果read返回0,那表示它已被关闭。