2014-01-23 39 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]# 

回答