#include <sys/types.h> #include <sys/time.h> #include <stdio.h> #include <fcntl.h> #include <sys/ioctl.h> #include <unistd.h> int main() { char buffer[128]; int result,nread; fd_set inputs,testfds; struct timeval timeout; FD_ZERO(&inputs); FD_SET(0,&inputs); while(1) { testfds = inputs; timeout.tv_sec = 2; timeout.tv_usec = 500000; result = select(FD_SETSIZE,&testfds,(fd_set *)NULL,(fd_set *)NULL,&timeout); switch(result) { case 0: printf("timeout\n"); break; case -1: perror("select"); exit(1); default: if(FD_ISSET(0,&testfds)) { ioctl(0,FIONREAD,&nread); if(nread == 0) { printf("keyboard done\n"); exit(0); } nread = read(0,buffer,nread); buffer[nread] = 0; printf("read %d from keyboard: %s",nread,buffer); } break; } } }
void FD_ZERO(fd_set *fdset);
void FD_CLR(int fd,fd_set *fdset);
void FD_SET(int fd,fd_set *fdset);
int FD_ISSET(int fd,fd_set *fdset);
FD_ZERO用于将fd_set初始化为空集合
FD_SET和FD_CLR分别用于在集合中设置和清除由参数fd传递的文件描述符。
FD_ISSET由参数fd指向的文件描述符是由参数fdset指向的fd_set集合中的一个元素,FD_ISSET将返回非0值。FD_ISSET查看某个文件句柄是否被设置了。
select调用用于测试文件描述符集合中,是否有一个文件描述符已处于可读或可写或错误状态,它将阻塞以等待某个文件描述符进入上述这些状态。
select调用返回状态发生变化的描述符总数。失败时它将返回-1并设置errorno来描述错误。
参数nfds指定测试文件描述符数目,测试的描述符范围从0到nfds-1.
用 法: int ioctl(int handle, int cmd,[int *argdx, int argcx]);
功 能: 控制I/O设备 ,提供了一种获得设备信息和向设备发送控制参数的手段。用于向设备发控制和配置命令 ,有些命令需要控制参数,这些数据是不能用read / write 读写的,称为Out-of-band数据。也就是说,read / write 读写的数据是in-band数据,是I/O操作的主体,而ioctl 命令传送的是控制信息,其中的数据是辅助的数据。
FIONREAD :获取接收缓存区中的字节数
运行这个程序时,它会每隔2.5秒打印一个timeout。如果在键盘上敲人字符。它就会从标准输入读取数据并报告敲人的内容。
./select
timeout
hello
read 6 from keyboard:hello
fred
read 5 from keyboard:fred
timeout
CTRL+D
keyboard done