@@ -180,6 +180,7 @@ SYSCALL_DEF_FULL(preadv, .impl = impl_preadv,
SYSCALL_DEF_FULL(pwritev, .impl = impl_pwritev,
.args = args_preadv_pwritev,
.arg_type = { ARG_DEC, ARG_PTR, ARG_DEC, ARG_DEC64 });
+SYSCALL_DEF(pselect6, ARG_DEC, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR, ARG_PTR);
SYSCALL_DEF(read, ARG_DEC, ARG_PTR, ARG_DEC);
#ifdef TARGET_NR_readlink
SYSCALL_DEF(readlink, ARG_STR, ARG_PTR, ARG_DEC);
@@ -934,6 +934,102 @@ SYSCALL_IMPL(pwritev)
return ret;
}
+SYSCALL_IMPL(pselect6)
+{
+ abi_long n = arg1;
+ abi_ulong rfd_addr = arg2;
+ abi_ulong wfd_addr = arg3;
+ abi_ulong efd_addr = arg4;
+ abi_ulong ts_addr = arg5;
+ fd_set rfds, wfds, efds;
+ fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+ struct timespec ts, *ts_ptr = NULL;
+ abi_long ret;
+
+ /*
+ * The 6th arg is actually two args smashed together, and since
+ * we are using safe_syscall, we must handle this ourselves.
+ */
+ sigset_t set;
+ struct {
+ sigset_t *set;
+ size_t size;
+ } sig, *sig_ptr = NULL;
+
+ abi_ulong arg_sigset, arg_sigsize, *arg7;
+ target_sigset_t *target_sigset;
+
+ ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
+ if (ret) {
+ return ret;
+ }
+ ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
+ if (ret) {
+ return ret;
+ }
+ ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
+ if (ret) {
+ return ret;
+ }
+
+ if (ts_addr) {
+ if (target_to_host_timespec(&ts, ts_addr)) {
+ return -TARGET_EFAULT;
+ }
+ ts_ptr = &ts;
+ }
+
+ /* Extract the two packed args for the sigset */
+ if (arg6) {
+ sig_ptr = &sig;
+ sig.size = SIGSET_T_SIZE;
+
+ arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
+ if (!arg7) {
+ return -TARGET_EFAULT;
+ }
+ arg_sigset = tswapal(arg7[0]);
+ arg_sigsize = tswapal(arg7[1]);
+ unlock_user(arg7, arg6, 0);
+
+ if (arg_sigset) {
+ sig.set = &set;
+ if (arg_sigsize != sizeof(*target_sigset)) {
+ /* Like the kernel, we enforce correct size sigsets */
+ return -TARGET_EINVAL;
+ }
+ target_sigset = lock_user(VERIFY_READ, arg_sigset,
+ sizeof(*target_sigset), 1);
+ if (!target_sigset) {
+ return -TARGET_EFAULT;
+ }
+ target_to_host_sigset(&set, target_sigset);
+ unlock_user(target_sigset, arg_sigset, 0);
+ } else {
+ sig.set = NULL;
+ }
+ }
+
+ ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
+ ts_ptr, sig_ptr));
+
+ if (!is_error(ret)) {
+ if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) {
+ return -TARGET_EFAULT;
+ }
+ if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) {
+ return -TARGET_EFAULT;
+ }
+ if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) {
+ return -TARGET_EFAULT;
+ }
+ if (ts_addr && host_to_target_timespec(ts_addr, &ts)) {
+ return -TARGET_EFAULT;
+ }
+ }
+ return ret;
+}
+
SYSCALL_IMPL(read)
{
int fd = arg1;
@@ -4158,109 +4158,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
void *p;
switch(num) {
-#ifdef TARGET_NR_pselect6
- case TARGET_NR_pselect6:
- {
- abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
- fd_set rfds, wfds, efds;
- fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
- struct timespec ts, *ts_ptr;
-
- /*
- * The 6th arg is actually two args smashed together,
- * so we cannot use the C library.
- */
- sigset_t set;
- struct {
- sigset_t *set;
- size_t size;
- } sig, *sig_ptr;
-
- abi_ulong arg_sigset, arg_sigsize, *arg7;
- target_sigset_t *target_sigset;
-
- n = arg1;
- rfd_addr = arg2;
- wfd_addr = arg3;
- efd_addr = arg4;
- ts_addr = arg5;
-
- ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
- if (ret) {
- return ret;
- }
- ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
- if (ret) {
- return ret;
- }
- ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
- if (ret) {
- return ret;
- }
-
- /*
- * This takes a timespec, and not a timeval, so we cannot
- * use the do_select() helper ...
- */
- if (ts_addr) {
- if (target_to_host_timespec(&ts, ts_addr)) {
- return -TARGET_EFAULT;
- }
- ts_ptr = &ts;
- } else {
- ts_ptr = NULL;
- }
-
- /* Extract the two packed args for the sigset */
- if (arg6) {
- sig_ptr = &sig;
- sig.size = SIGSET_T_SIZE;
-
- arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
- if (!arg7) {
- return -TARGET_EFAULT;
- }
- arg_sigset = tswapal(arg7[0]);
- arg_sigsize = tswapal(arg7[1]);
- unlock_user(arg7, arg6, 0);
-
- if (arg_sigset) {
- sig.set = &set;
- if (arg_sigsize != sizeof(*target_sigset)) {
- /* Like the kernel, we enforce correct size sigsets */
- return -TARGET_EINVAL;
- }
- target_sigset = lock_user(VERIFY_READ, arg_sigset,
- sizeof(*target_sigset), 1);
- if (!target_sigset) {
- return -TARGET_EFAULT;
- }
- target_to_host_sigset(&set, target_sigset);
- unlock_user(target_sigset, arg_sigset, 0);
- } else {
- sig.set = NULL;
- }
- } else {
- sig_ptr = NULL;
- }
-
- ret = get_errno(safe_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
- ts_ptr, sig_ptr));
-
- if (!is_error(ret)) {
- if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
- return -TARGET_EFAULT;
- if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
- return -TARGET_EFAULT;
- if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
- return -TARGET_EFAULT;
-
- if (ts_addr && host_to_target_timespec(ts_addr, &ts))
- return -TARGET_EFAULT;
- }
- }
- return ret;
-#endif
#ifdef TARGET_NR_symlink
case TARGET_NR_symlink:
{
@@ -848,9 +848,6 @@
#ifdef TARGET_NR_profil
{ TARGET_NR_profil, "profil" , NULL, NULL, NULL },
#endif
-#ifdef TARGET_NR_pselect6
-{ TARGET_NR_pselect6, "pselect6" , NULL, NULL, NULL },
-#endif
#ifdef TARGET_NR_ptrace
{ TARGET_NR_ptrace, "ptrace" , NULL, NULL, NULL },
#endif
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- linux-user/syscall-defs.h | 1 + linux-user/syscall-file.inc.c | 96 +++++++++++++++++++++++++++++++ linux-user/syscall.c | 103 ---------------------------------- linux-user/strace.list | 3 - 4 files changed, 97 insertions(+), 106 deletions(-)