Implement epoll_pwait() system call.
This commit is contained in:
parent
b7c4ebdb56
commit
6e4c8004dc
@ -98,7 +98,6 @@ DUMMY(tee);
|
||||
DUMMY(sync_file_range);
|
||||
DUMMY(vmsplice);
|
||||
DUMMY(move_pages);
|
||||
DUMMY(epoll_pwait);
|
||||
DUMMY(signalfd);
|
||||
DUMMY(timerfd);
|
||||
DUMMY(timerfd_settime);
|
||||
|
@ -102,7 +102,6 @@ DUMMY(vmsplice);
|
||||
DUMMY(move_pages);
|
||||
/* linux 2.6.19: */
|
||||
DUMMY(getcpu);
|
||||
DUMMY(epoll_pwait);
|
||||
/* linux 2.6.22: */
|
||||
DUMMY(signalfd);
|
||||
DUMMY(timerfd_create);
|
||||
|
@ -531,7 +531,7 @@
|
||||
; linux 2.6.19:
|
||||
318 AUE_NULL STD { int linux_getcpu(void); }
|
||||
319 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \
|
||||
l_int maxevents, l_int timeout, l_osigset_t *mask); }
|
||||
l_int maxevents, l_int timeout, l_sigset_t *mask); }
|
||||
; linux 2.6.22:
|
||||
320 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \
|
||||
const struct l_timespec *times, l_int flags); }
|
||||
|
@ -471,8 +471,9 @@ leave1:
|
||||
/*
|
||||
* Wait for a filter to be triggered on the epoll file descriptor.
|
||||
*/
|
||||
int
|
||||
linux_epoll_wait(struct thread *td, struct linux_epoll_wait_args *args)
|
||||
static int
|
||||
linux_epoll_wait_common(struct thread *td, int epfd, struct epoll_event *events,
|
||||
int maxevents, int timeout, sigset_t *uset)
|
||||
{
|
||||
struct file *epfp;
|
||||
struct timespec ts, *tsp;
|
||||
@ -483,33 +484,49 @@ linux_epoll_wait(struct thread *td, struct linux_epoll_wait_args *args)
|
||||
NULL};
|
||||
int error;
|
||||
|
||||
if (args->maxevents <= 0 || args->maxevents > LINUX_MAX_EVENTS)
|
||||
if (maxevents <= 0 || maxevents > LINUX_MAX_EVENTS)
|
||||
return (EINVAL);
|
||||
|
||||
error = fget(td, args->epfd,
|
||||
if (uset != NULL) {
|
||||
error = kern_sigprocmask(td, SIG_SETMASK, uset,
|
||||
&td->td_oldsigmask, 0);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
td->td_pflags |= TDP_OLDMASK;
|
||||
/*
|
||||
* Make sure that ast() is called on return to
|
||||
* usermode and TDP_OLDMASK is cleared, restoring old
|
||||
* sigmask.
|
||||
*/
|
||||
thread_lock(td);
|
||||
td->td_flags |= TDF_ASTPENDING;
|
||||
thread_unlock(td);
|
||||
}
|
||||
|
||||
error = fget(td, epfd,
|
||||
cap_rights_init(&rights, CAP_KQUEUE_EVENT), &epfp);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
coargs.leventlist = args->events;
|
||||
coargs.leventlist = events;
|
||||
coargs.p = td->td_proc;
|
||||
coargs.count = 0;
|
||||
coargs.error = 0;
|
||||
|
||||
if (args->timeout != -1) {
|
||||
if (args->timeout < 0) {
|
||||
if (timeout != -1) {
|
||||
if (timeout < 0) {
|
||||
error = EINVAL;
|
||||
goto leave;
|
||||
}
|
||||
/* Convert from milliseconds to timespec. */
|
||||
ts.tv_sec = args->timeout / 1000;
|
||||
ts.tv_nsec = (args->timeout % 1000) * 1000000;
|
||||
ts.tv_sec = timeout / 1000;
|
||||
ts.tv_nsec = (timeout % 1000) * 1000000;
|
||||
tsp = &ts;
|
||||
} else {
|
||||
tsp = NULL;
|
||||
}
|
||||
|
||||
error = kern_kevent_fp(td, epfp, 0, args->maxevents, &k_ops, tsp);
|
||||
error = kern_kevent_fp(td, epfp, 0, maxevents, &k_ops, tsp);
|
||||
if (error == 0 && coargs.error != 0)
|
||||
error = coargs.error;
|
||||
|
||||
@ -524,6 +541,33 @@ leave:
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
linux_epoll_wait(struct thread *td, struct linux_epoll_wait_args *args)
|
||||
{
|
||||
|
||||
return (linux_epoll_wait_common(td, args->epfd, args->events,
|
||||
args->maxevents, args->timeout, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
linux_epoll_pwait(struct thread *td, struct linux_epoll_pwait_args *args)
|
||||
{
|
||||
sigset_t mask, *pmask;
|
||||
l_sigset_t lmask;
|
||||
int error;
|
||||
|
||||
if (args->mask != NULL) {
|
||||
error = copyin(args->mask, &lmask, sizeof(l_sigset_t));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
linux_to_bsd_sigset(&lmask, &mask);
|
||||
pmask = &mask;
|
||||
} else
|
||||
pmask = NULL;
|
||||
return (linux_epoll_wait_common(td, args->epfd, args->events,
|
||||
args->maxevents, args->timeout, pmask));
|
||||
}
|
||||
|
||||
static int
|
||||
epoll_delete_event(struct thread *td, struct file *epfp, int fd, int filter)
|
||||
{
|
||||
|
@ -98,7 +98,6 @@ DUMMY(vmsplice);
|
||||
DUMMY(move_pages);
|
||||
/* linux 2.6.19: */
|
||||
DUMMY(getcpu);
|
||||
DUMMY(epoll_pwait);
|
||||
/* linux 2.6.22: */
|
||||
DUMMY(signalfd);
|
||||
DUMMY(timerfd_create);
|
||||
|
@ -539,7 +539,7 @@
|
||||
; linux 2.6.19:
|
||||
318 AUE_NULL STD { int linux_getcpu(void); }
|
||||
319 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \
|
||||
l_int maxevents, l_int timeout, l_osigset_t *mask); }
|
||||
l_int maxevents, l_int timeout, l_sigset_t *mask); }
|
||||
; linux 2.6.22:
|
||||
320 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \
|
||||
const struct l_timespec *times, l_int flags); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user