コード例 #1
0
ファイル: select.c プロジェクト: 0x1abin/linux_kernel_driver
int do_select(fd_set in, fd_set out, fd_set ex,
	fd_set *inp, fd_set *outp, fd_set *exp)
{
	int count;
	select_table wait_table;
	int i;
	fd_set mask;

	mask = in | out | ex;
	for (i = 0 ; i < NR_OPEN ; i++,mask >>= 1) {
		if (!(mask & 1))
			continue;
		if (!current->filp[i])
			return -EBADF;
		if (!current->filp[i]->f_inode)
			return -EBADF;
		if (current->filp[i]->f_inode->i_pipe)
			continue;
		if (S_ISCHR(current->filp[i]->f_inode->i_mode))
			continue;
		if (S_ISFIFO(current->filp[i]->f_inode->i_mode))
			continue;
		return -EBADF;
	}
repeat:
	wait_table.nr = 0;
	*inp = *outp = *exp = 0;
	count = 0;
	mask = 1;
	for (i = 0 ; i < NR_OPEN ; i++, mask += mask) {
		if (mask & in)
			if (check_in(&wait_table,current->filp[i]->f_inode)) {
				*inp |= mask;
				count++;
			}
		if (mask & out)
			if (check_out(&wait_table,current->filp[i]->f_inode)) {
				*outp |= mask;
				count++;
			}
		if (mask & ex)
			if (check_ex(&wait_table,current->filp[i]->f_inode)) {
				*exp |= mask;
				count++;
			}
	}
	if (!(current->signal & ~current->blocked) &&
	    (wait_table.nr || current->timeout) && !count) {
		current->state = TASK_INTERRUPTIBLE;
		schedule();
		free_wait(&wait_table);
		goto repeat;
	}
	free_wait(&wait_table);
	return count;
}
コード例 #2
0
ファイル: sys_sunos.c プロジェクト: andreiw/mkunity
int sunos_poll(struct poll * ufds, size_t nfds, int timeout)
{
        int i,j, count, fdcount, error, retflag;
	struct poll * fdpnt;
	struct poll * fds, *fds1;
	select_table wait_table, *wait;
	struct select_table_entry *entry;

	if ((error = verify_area(VERIFY_READ, ufds, nfds*sizeof(struct poll))))
		return error;

	if (nfds > NR_OPEN)
		return -EINVAL;

	if (!(entry = (struct select_table_entry*)__get_free_page(GFP_KERNEL))
	|| !(fds = (struct poll *)kmalloc(nfds*sizeof(struct poll), GFP_KERNEL)))
		return -ENOMEM;

	memcpy_fromfs(fds, ufds, nfds*sizeof(struct poll));

	if (timeout < 0)
		current->timeout = 0x7fffffff;
	else {
		current->timeout = jiffies + POLL_ROUND_UP(timeout, (1000/HZ));
		if (current->timeout <= jiffies)
			current->timeout = 0;
	}

	count = 0;
	wait_table.nr = 0;
	wait_table.entry = entry;
	wait = &wait_table;

	for(fdpnt = fds, j = 0; j < (int)nfds; j++, fdpnt++) {
		i = fdpnt->fd;
		fdpnt->revents = 0;
		if (!current->files->fd[i] || !current->files->fd[i]->f_inode)
			fdpnt->revents = POLLNVAL;
	}
repeat:
	current->state = TASK_INTERRUPTIBLE;
	for(fdpnt = fds, j = 0; j < (int)nfds; j++, fdpnt++) {
		i = fdpnt->fd;

		if(i < 0) continue;
		if (!current->files->fd[i] || !current->files->fd[i]->f_inode) continue;

		if ((fdpnt->events & LINUX_POLLIN)
		&& check(SEL_IN, wait, current->files->fd[i])) {
			if (fdpnt->events & POLLIN)
				retflag = POLLIN;
			if (fdpnt->events & POLLRDNORM)
				retflag = POLLRDNORM;
			fdpnt->revents |= retflag; 
			count++;
			wait = NULL;
		}

		if ((fdpnt->events & LINUX_POLLOUT) &&
		check(SEL_OUT, wait, current->files->fd[i])) {
			fdpnt->revents |= (LINUX_POLLOUT & fdpnt->events);
			count++;
			wait = NULL;
		}

		if (check(SEL_EX, wait, current->files->fd[i])) {
			fdpnt->revents |= POLLHUP;
			count++;
			wait = NULL;
		}
	}

	if ((current->signal & (~current->blocked)))
		return -EINTR;

	wait = NULL;
	if (!count && current->timeout > jiffies) {
		schedule();
		goto repeat;
	}

	free_wait(&wait_table);
	free_page((unsigned long) entry);

	/* OK, now copy the revents fields back to user space. */
	fds1 = fds;
	fdcount = 0;
	for(i=0; i < (int)nfds; i++, ufds++, fds++) {
		if (fds->revents) {
			fdcount++;
		}
		put_fs_word(fds->revents, &ufds->revents);
	}
	kfree(fds1);
	current->timeout = 0;
	current->state = TASK_RUNNING;
	return fdcount;
}