*参照元 [#bbe269fe] #backlinks *説明 [#ae42a17c] -パス: [[linux-4.4.1/fs/select.c]] -FIXME: これは何? --説明 **引数 [#e9cc0de8] -struct pollfd __user *ufds -- --[[linux-4.4.1/pollfd]] -unsigned int nfds -- -struct timespec *end_time -- --[[linux-4.4.1/timespec]] **返り値 [#p0149fe4] -int -- **参考 [#e8c52795] *実装 [#e45b950b] int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, struct timespec *end_time) { struct poll_wqueues table; int err = -EFAULT, fdcount, len, size; /* Allocate small arguments on the stack to save memory and be faster - use long to make sure the buffer is aligned properly on 64 bit archs to avoid unaligned access */ long stack_pps[POLL_STACK_ALLOC/sizeof(long)]; struct poll_list *const head = (struct poll_list *)stack_pps; struct poll_list *walk = head; unsigned long todo = nfds; - --[[linux-4.4.1/poll_wqueues]] --[[linux-4.4.1/POLL_STACK_ALLOC]] --[[linux-4.4.1/poll_list]] if (nfds > rlimit(RLIMIT_NOFILE)) return -EINVAL; - --[[linux-4.4.1/rlimit()]] len = min_t(unsigned int, nfds, N_STACK_PPS); - --[[linux-4.4.1/min_t()]] for (;;) { walk->next = NULL; walk->len = len; if (!len) break; if (copy_from_user(walk->entries, ufds + nfds-todo, sizeof(struct pollfd) * walk->len)) goto out_fds; - --[[linux-4.4.1/copy_from_user()]] todo -= walk->len; if (!todo) break; len = min(todo, POLLFD_PER_PAGE); size = sizeof(struct poll_list) + sizeof(struct pollfd) * len; walk = walk->next = kmalloc(size, GFP_KERNEL); if (!walk) { err = -ENOMEM; goto out_fds; } - --[[linux-4.4.1/kmalloc()]] } poll_initwait(&table); fdcount = do_poll(nfds, head, &table, end_time); poll_freewait(&table); - --[[linux-4.4.1/poll_initwait()]] --[[linux-4.4.1/do_poll()]] --[[linux-4.4.1/poll_freewait()]] for (walk = head; walk; walk = walk->next) { struct pollfd *fds = walk->entries; int j; for (j = 0; j < walk->len; j++, ufds++) if (__put_user(fds[j].revents, &ufds->revents)) goto out_fds; } - --[[linux-4.4.1/pollfd]] --[[linux-4.4.1/__put_user()]] err = fdcount; out_fds: walk = head->next; while (walk) { struct poll_list *pos = walk; walk = walk->next; kfree(pos); } - --[[linux-4.4.1/kfree()]] return err; } *コメント [#u2b590ef]