2014-01-23 40 views
0

考虑下面的情况后:TTY事件epoll的队列闭FD 0

  • 一个EPOLLIN事件被注册用于FD 0(标准输入)
  • 用于FD 0则生成EPOLLIN事件和隐式排队读epoll的内
  • FD 0之前闭合(并且EPOLL_CTL_DELeted)调用epoll_wait()
  • epoll_wait()被调用以读取排队的事件

目前:

  • 如果标准输入是一个终端,当epoll_wait()被调用时,从步骤2 EPOLLIN事件将被报告
  • 如果标准输入不是终端,但管道,从EPOLLIN事件第2步将不是被举报

为什么tty案件不同?

测试程序:

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/epoll.h> 

struct epoll_event event1 = { 
    .events = EPOLLIN, 
    .data = { .fd = 0} 
}; 

int main(int argc, char **argv) 
{ 
    int epfd = epoll_create(1); 
    int rc; 
    epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event1); 
    sleep(2); //allow meself time to type false\n 
    printf("closing stdin ...\n"); 
    close(0); 
    //even if i remove it explicitly the event will be found in the que after 
    epoll_ctl(epfd, EPOLL_CTL_DEL, 0, &event1); 
    printf("gathering events ...\n"); 
    event1.events = 0; 
    event1.data.fd = -1; 
    rc = epoll_wait(epfd, &event1, 1, 0); 
    switch(rc) { 
     case 1: 
      printf("event received: event=%d on fd %d\n", event1.events, event1.data.fd); 
      break; 
     case 0: 
      printf("no events received"); 
      break; 
     case -1: 
      printf("epoll_wait error\n"); 
      break; 
     default: 
      printf("weird event count %d\n", rc); 
    } 

    return 0; 
} 

与标准输入从TTY运行程序:

[[email protected] src]# ./epolltest 
false 
closing stdin ... 
gathering events ... 
event received: event=1 on fd 0 
[[email protected] src]# false 
[[email protected] src]# 

从管道与标准输入运行程序:

[[email protected] src]# cat t.sh 
#!/bin/bash 

echo "bah"; 
sleep 10; 
[[email protected] src]# ./t.sh | ./epolltest 
closing stdin ... 
gathering events ... 
no events received[[email protected] src]# 

回答