From owner-svn-src-user@FreeBSD.ORG Sun Feb 22 17:48:51 2015 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 656D5158; Sun, 22 Feb 2015 17:48:51 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4F5DEDE8; Sun, 22 Feb 2015 17:48:51 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t1MHmp5N064554; Sun, 22 Feb 2015 17:48:51 GMT (envelope-from dchagin@FreeBSD.org) Received: (from dchagin@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t1MHmnqm064546; Sun, 22 Feb 2015 17:48:49 GMT (envelope-from dchagin@FreeBSD.org) Message-Id: <201502221748.t1MHmnqm064546@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: dchagin set sender to dchagin@FreeBSD.org using -f From: Dmitry Chagin Date: Sun, 22 Feb 2015 17:48:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r279168 - in user/dchagin/lemul/sys: amd64/linux amd64/linux32 compat/linux i386/linux X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Feb 2015 17:48:51 -0000 Author: dchagin Date: Sun Feb 22 17:48:48 2015 New Revision: 279168 URL: https://svnweb.freebsd.org/changeset/base/279168 Log: Implement epoll_pwait() system call. Modified: user/dchagin/lemul/sys/amd64/linux/linux_dummy.c user/dchagin/lemul/sys/amd64/linux32/linux32_dummy.c user/dchagin/lemul/sys/amd64/linux32/syscalls.master user/dchagin/lemul/sys/compat/linux/linux_event.c user/dchagin/lemul/sys/i386/linux/linux_dummy.c user/dchagin/lemul/sys/i386/linux/syscalls.master Modified: user/dchagin/lemul/sys/amd64/linux/linux_dummy.c ============================================================================== --- user/dchagin/lemul/sys/amd64/linux/linux_dummy.c Sun Feb 22 17:45:09 2015 (r279167) +++ user/dchagin/lemul/sys/amd64/linux/linux_dummy.c Sun Feb 22 17:48:48 2015 (r279168) @@ -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); Modified: user/dchagin/lemul/sys/amd64/linux32/linux32_dummy.c ============================================================================== --- user/dchagin/lemul/sys/amd64/linux32/linux32_dummy.c Sun Feb 22 17:45:09 2015 (r279167) +++ user/dchagin/lemul/sys/amd64/linux32/linux32_dummy.c Sun Feb 22 17:48:48 2015 (r279168) @@ -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); Modified: user/dchagin/lemul/sys/amd64/linux32/syscalls.master ============================================================================== --- user/dchagin/lemul/sys/amd64/linux32/syscalls.master Sun Feb 22 17:45:09 2015 (r279167) +++ user/dchagin/lemul/sys/amd64/linux32/syscalls.master Sun Feb 22 17:48:48 2015 (r279168) @@ -529,7 +529,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); } Modified: user/dchagin/lemul/sys/compat/linux/linux_event.c ============================================================================== --- user/dchagin/lemul/sys/compat/linux/linux_event.c Sun Feb 22 17:45:09 2015 (r279167) +++ user/dchagin/lemul/sys/compat/linux/linux_event.c Sun Feb 22 17:48:48 2015 (r279168) @@ -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, stru 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) { Modified: user/dchagin/lemul/sys/i386/linux/linux_dummy.c ============================================================================== --- user/dchagin/lemul/sys/i386/linux/linux_dummy.c Sun Feb 22 17:45:09 2015 (r279167) +++ user/dchagin/lemul/sys/i386/linux/linux_dummy.c Sun Feb 22 17:48:48 2015 (r279168) @@ -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); Modified: user/dchagin/lemul/sys/i386/linux/syscalls.master ============================================================================== --- user/dchagin/lemul/sys/i386/linux/syscalls.master Sun Feb 22 17:45:09 2015 (r279167) +++ user/dchagin/lemul/sys/i386/linux/syscalls.master Sun Feb 22 17:48:48 2015 (r279168) @@ -537,7 +537,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); }