@@ -7897,6 +7897,123 @@ IMPL(dup3)
return ret;
}
+#ifdef CONFIG_EPOLL
+# ifdef TARGET_NR_epoll_create
+IMPL(epoll_create)
+{
+ return get_errno(epoll_create(arg1));
+}
+# endif
+
+IMPL(epoll_create1)
+{
+# ifdef CONFIG_EPOLL_CREATE1
+ return get_errno(epoll_create1(arg1));
+# else
+ /* If flags are 0, we can emulate with epoll_create.
+ * The size argument is ignored after linux 2.6.8,
+ * other than verifying that it is positive.
+ */
+ if (arg1 == 0) {
+ return get_errno(epoll_create(1));
+ }
+ return -TARGET_ENOSYS;
+# endif
+}
+
+IMPL(epoll_ctl)
+{
+ struct epoll_event ep;
+ struct epoll_event *epp = 0;
+
+ if (arg4) {
+ struct target_epoll_event *target_ep;
+ if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
+ return -TARGET_EFAULT;
+ }
+ ep.events = tswap32(target_ep->events);
+ /* The epoll_data_t union is just opaque data to the kernel,
+ * so we transfer all 64 bits across and need not worry what
+ * actual data type it is.
+ */
+ ep.data.u64 = tswap64(target_ep->data.u64);
+ unlock_user_struct(target_ep, arg4, 0);
+ epp = &ep;
+ }
+ return get_errno(epoll_ctl(arg1, arg2, arg3, epp));
+}
+
+IMPL(epoll_pwait_wait)
+{
+ struct target_epoll_event *target_ep;
+ struct epoll_event *ep;
+ int epfd = arg1;
+ int maxevents = arg3;
+ int timeout = arg4;
+ abi_long ret;
+
+ if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) {
+ return -TARGET_EINVAL;
+ }
+
+ target_ep = lock_user(VERIFY_WRITE, arg2,
+ maxevents * sizeof(struct target_epoll_event), 1);
+ if (!target_ep) {
+ return -TARGET_EFAULT;
+ }
+
+ ep = g_try_new(struct epoll_event, maxevents);
+ if (!ep) {
+ unlock_user(target_ep, arg2, 0);
+ return -TARGET_ENOMEM;
+ }
+
+ switch (num) {
+ default: /* TARGET_NR_epoll_pwait */
+ if (arg5) {
+ target_sigset_t *target_set;
+ sigset_t set;
+
+ if (arg6 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
+ target_set = lock_user(VERIFY_READ, arg5,
+ sizeof(target_sigset_t), 1);
+ if (!target_set) {
+ ret = -TARGET_EFAULT;
+ break;
+ }
+ target_to_host_sigset(&set, target_set);
+ unlock_user(target_set, arg5, 0);
+
+ ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
+ &set, SIGSET_T_SIZE));
+ break;
+ }
+ /* fallthru */
+# ifdef TARGET_NR_epoll_wait
+ case TARGET_NR_epoll_wait:
+# endif
+ ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents,
+ timeout, NULL, 0));
+ break;
+ }
+ if (!is_error(ret)) {
+ int i;
+ for (i = 0; i < ret; i++) {
+ target_ep[i].events = tswap32(ep[i].events);
+ target_ep[i].data.u64 = tswap64(ep[i].data.u64);
+ }
+ unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
+ } else {
+ unlock_user(target_ep, arg2, 0);
+ }
+ g_free(ep);
+ return ret;
+}
+#endif /* CONFIG_EPOLL */
+
#ifdef CONFIG_EVENTFD
# ifdef TARGET_NR_eventfd
IMPL(eventfd)
@@ -12856,122 +12973,6 @@ static abi_long do_syscall1(void *cpu_env, unsigned num, abi_long arg1,
abi_long ret;
switch(num) {
-#if defined(CONFIG_EPOLL)
-#if defined(TARGET_NR_epoll_create)
- case TARGET_NR_epoll_create:
- return get_errno(epoll_create(arg1));
-#endif
-#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
- case TARGET_NR_epoll_create1:
- return get_errno(epoll_create1(arg1));
-#endif
-#if defined(TARGET_NR_epoll_ctl)
- case TARGET_NR_epoll_ctl:
- {
- struct epoll_event ep;
- struct epoll_event *epp = 0;
- if (arg4) {
- struct target_epoll_event *target_ep;
- if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
- return -TARGET_EFAULT;
- }
- ep.events = tswap32(target_ep->events);
- /* The epoll_data_t union is just opaque data to the kernel,
- * so we transfer all 64 bits across and need not worry what
- * actual data type it is.
- */
- ep.data.u64 = tswap64(target_ep->data.u64);
- unlock_user_struct(target_ep, arg4, 0);
- epp = &ep;
- }
- return get_errno(epoll_ctl(arg1, arg2, arg3, epp));
- }
-#endif
-
-#if defined(TARGET_NR_epoll_wait) || defined(TARGET_NR_epoll_pwait)
-#if defined(TARGET_NR_epoll_wait)
- case TARGET_NR_epoll_wait:
-#endif
-#if defined(TARGET_NR_epoll_pwait)
- case TARGET_NR_epoll_pwait:
-#endif
- {
- struct target_epoll_event *target_ep;
- struct epoll_event *ep;
- int epfd = arg1;
- int maxevents = arg3;
- int timeout = arg4;
-
- if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) {
- return -TARGET_EINVAL;
- }
-
- target_ep = lock_user(VERIFY_WRITE, arg2,
- maxevents * sizeof(struct target_epoll_event), 1);
- if (!target_ep) {
- return -TARGET_EFAULT;
- }
-
- ep = g_try_new(struct epoll_event, maxevents);
- if (!ep) {
- unlock_user(target_ep, arg2, 0);
- return -TARGET_ENOMEM;
- }
-
- switch (num) {
-#if defined(TARGET_NR_epoll_pwait)
- case TARGET_NR_epoll_pwait:
- {
- target_sigset_t *target_set;
- sigset_t _set, *set = &_set;
-
- if (arg5) {
- if (arg6 != sizeof(target_sigset_t)) {
- ret = -TARGET_EINVAL;
- break;
- }
-
- target_set = lock_user(VERIFY_READ, arg5,
- sizeof(target_sigset_t), 1);
- if (!target_set) {
- ret = -TARGET_EFAULT;
- break;
- }
- target_to_host_sigset(set, target_set);
- unlock_user(target_set, arg5, 0);
- } else {
- set = NULL;
- }
-
- ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
- set, SIGSET_T_SIZE));
- }
-#endif
-#if defined(TARGET_NR_epoll_wait)
- case TARGET_NR_epoll_wait:
- ret = get_errno(safe_epoll_pwait(epfd, ep, maxevents, timeout,
- NULL, 0));
- break;
-#endif
- default:
- ret = -TARGET_ENOSYS;
- }
- if (!is_error(ret)) {
- int i;
- for (i = 0; i < ret; i++) {
- target_ep[i].events = tswap32(ep[i].events);
- target_ep[i].data.u64 = tswap64(ep[i].data.u64);
- }
- unlock_user(target_ep, arg2,
- ret * sizeof(struct target_epoll_event));
- } else {
- unlock_user(target_ep, arg2, 0);
- }
- g_free(ep);
- return ret;
- }
-#endif
-#endif
#ifdef TARGET_NR_prlimit64
case TARGET_NR_prlimit64:
{
@@ -13330,6 +13331,17 @@ static impl_fn *syscall_table(unsigned num)
SYSCALL(dup2);
#endif
SYSCALL(dup3);
+#ifdef CONFIG_EPOLL
+# ifdef TARGET_NR_epoll_create
+ SYSCALL(epoll_create);
+# endif
+ SYSCALL(epoll_create1);
+ SYSCALL(epoll_ctl);
+ SYSCALL_WITH(epoll_pwait, epoll_pwait_wait);
+# ifdef TARGET_NR_epoll_wait
+ SYSCALL_WITH(epoll_wait, epoll_pwait_wait);
+# endif
+#endif
#ifdef CONFIG_EVENTFD
# ifdef TARGET_NR_eventfd
SYSCALL(eventfd);
This includes epoll_create, epoll_create1, epoll_ctl, epoll_pwait, epoll_wait. All targets define epoll_create1, epoll_ctl, epoll_pwait; remove those ifdefs. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/syscall.c | 244 +++++++++++++++++++++++-------------------- 1 file changed, 128 insertions(+), 116 deletions(-) -- 2.17.1