/*
* reads input from pipes p1, p2
* using select() for multiplexing
*
* tty1:cat > ./p1
* tty2:cat > ./p2
* tty3: ./select
*/
#include <fcntl.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int main(void) {
int fds[2]; char buf[4096];
int i, rc, maxfd;
fd_set watchset; /* 欲监听read操作的集合 */
fd_set inset; /* select()调用后,被修改的集合 */
if((fds[0]=open("p1", O_RDONLY|O_NONBLOCK)) < 0){
perror("open p1");
return 1;
}
if((fds[1]=open("p2", O_RDONLY|O_NONBLOCK)) < 0){
perror("open p2");
return 1;
}
/* 清零集合,将监听描述符加入集合内 */
FD_ZERO(&watchset);
FD_SET(fds[0], &watchset);
FD_SET(fds[1], &watchset);
/* 找出最大文件描述符, 用以select第一个参数 */
maxfd = fds[0] > fds[1] ? fds[0] : fds[1];
/* 循环监视两个文件描述符是否有read条件*/
while(FD_ISSET(fds[0], &watchset) || FD_ISSET(fds[1], &watchset)){
inset = watchset; // backup, 因为select()调用结束会修改参二(传出参数)
if(select(maxfd+1, &inset, NULL,NULL,NULL) < 0){
perror("select");
return 1;
}
//从监听的两个文件描述符中去判断,哪个还在集合中
for(i = 0; i < 2; i++){
if(FD_ISSET(fds[i], &inset)){ //具备read条件
rc = read(fds[i], buf, sizeof(buf) - 1);//read之
if(rc < 0){
perror("read");
return 1;
}else if(!rc){
/* 管道已经被关闭,无需再监听了 */
close(fds[i]);
FD_CLR(fds[i], &watchset); //清除出监听集合中
}else{
buf[rc] = '\0';
printf("read: %s", buf);
}
}
}
}
return 0;
}