select系统调用源码分析

select系统调用

主要对select调用过程进行一些总结,后边也会有poll和epoll相关的一系列分析。

对于分析系统调用select的源码版本是2.6.25。

select系统调用的用途是:在一段指定时间内,监听用户感兴趣的文件描述符上的可读、可写和异常等事件。

1. select系统调用的原型如下:

#include <sys/select.h>
int select( int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout );

主要调用流程如下:


2. select流程

2.1 sys_select


asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
						   fd_set __user *exp, struct timeval __user *tvp)
{
	s64 timeout = -1;
	struct timeval tv;
	int ret;

	if (tvp) {    /*如果有超时值*/
		if (copy_from_user(&tv, tvp, sizeof(tv)))
			return -EFAULT;

		if (tv.tv_sec < 0 || tv.tv_usec < 0)    /*时间无效*/
			return -EINVAL;

		/* Cast to u64 to make GCC stop complaining */
		if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
			timeout = -1;	    /* 无限等待*/
		else {
			timeout = DIV_ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ);
			timeout += tv.tv_sec * HZ;\		}
	}

	/*主要工作都在core_sys_select中做了*/
	ret = core_sys_select(n, inp, outp, exp, &timeout);

	if (tvp) {/*如果有超时值*/
		struct timeval rtv;

		if (current->personality & STICKY_TIMEOUTS)/*模拟bug的一个机制,不详细描述*/
			goto sticky;
		/*rtv中是剩余的时间*/
		rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));
		rtv.tv_sec = timeout;
		if (timeval_compare(&rtv, &tv) >= 0)/*如果core_sys_select超时返回,更新时间*/
			rtv = tv;
		/*拷贝更新后的时间到用户空间*/
		if (copy_to_user(tvp, &rtv, sizeof(rtv))) {
sticky:
		if (ret == -ERESTARTNOHAND)    /*ERESTARTNOHAND表明,被中断的系统调用*/
			ret = -EINTR;
		}
	}

	return ret;
}

2.2 core_sys_select

    在28行处调用core_sys_select函数,然后处理三个fd_set参数,调用do_select,将返回的结果集,返回到用户空间。

首先,fd_set结构体仅包含一个整型数组,该数组的每一位(bit)标记一个文件描述符。fd_set能容纳的文件描述符数量由FD_SETSIZE指定,这也就

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值