From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KchKu-00082I-8L for qemu-devel@nongnu.org; Mon, 08 Sep 2008 10:03:24 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KchKq-0007zi-Bj for qemu-devel@nongnu.org; Mon, 08 Sep 2008 10:03:23 -0400 Received: from [199.232.76.173] (port=39234 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KchKp-0007zL-VF for qemu-devel@nongnu.org; Mon, 08 Sep 2008 10:03:20 -0400 Received: from gv-out-0910.google.com ([216.239.58.191]:33180) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KchKo-0007FW-TV for qemu-devel@nongnu.org; Mon, 08 Sep 2008 10:03:19 -0400 Received: by gv-out-0910.google.com with SMTP id n8so222137gve.36 for ; Mon, 08 Sep 2008 07:03:17 -0700 (PDT) From: "Kirill A. Shutemov" Date: Mon, 8 Sep 2008 17:03:33 +0300 Message-Id: <1220882616-18735-5-git-send-email-kirill@shutemov.name> In-Reply-To: <1220882616-18735-4-git-send-email-kirill@shutemov.name> References: <1220882616-18735-1-git-send-email-kirill@shutemov.name> <1220882616-18735-2-git-send-email-kirill@shutemov.name> <1220882616-18735-3-git-send-email-kirill@shutemov.name> <1220882616-18735-4-git-send-email-kirill@shutemov.name> Subject: [Qemu-devel] [PATCH] Implement syscall fstatat64() Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: "Kirill A. Shutemov" Move transformation of struct stat64 into the separate function and implement fstatat64() using it. Signed-off-by: Kirill A. Shutemov --- linux-user/syscall.c | 136 ++++++++++++++++++++++++++++--------------------- 1 files changed, 78 insertions(+), 58 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 88954eb..863e319 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3148,6 +3148,67 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr, return 0; } +#ifdef TARGET_NR_stat64 +static inline abi_long host_to_target_stat64(void *cpu_env, + abi_ulong target_addr, + struct stat *host_st) +{ +#ifdef TARGET_ARM + if (((CPUARMState *)cpu_env)->eabi) { + struct target_eabi_stat64 *target_st; + + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) + return -TARGET_EFAULT; + memset(target_st, 0, sizeof(struct target_eabi_stat64)); + __put_user(host_st->st_dev, &target_st->st_dev); + __put_user(host_st->st_ino, &target_st->st_ino); +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO + __put_user(host_st->st_ino, &target_st->__st_ino); +#endif + __put_user(host_st->st_mode, &target_st->st_mode); + __put_user(host_st->st_nlink, &target_st->st_nlink); + __put_user(host_st->st_uid, &target_st->st_uid); + __put_user(host_st->st_gid, &target_st->st_gid); + __put_user(host_st->st_rdev, &target_st->st_rdev); + __put_user(host_st->st_size, &target_st->st_size); + __put_user(host_st->st_blksize, &target_st->st_blksize); + __put_user(host_st->st_blocks, &target_st->st_blocks); + __put_user(host_st->st_atime, &target_st->target_st_atime); + __put_user(host_st->st_mtime, &target_st->target_st_mtime); + __put_user(host_st->st_ctime, &target_st->target_st_ctime); + unlock_user_struct(target_st, target_addr, 1); + } else +#endif + { + struct target_stat64 *target_st; + + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) + return -TARGET_EFAULT; + memset(target_st, 0, sizeof(struct target_stat64)); + __put_user(host_st->st_dev, &target_st->st_dev); + __put_user(host_st->st_ino, &target_st->st_ino); +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO + __put_user(host_st->st_ino, &target_st->__st_ino); +#endif + __put_user(host_st->st_mode, &target_st->st_mode); + __put_user(host_st->st_nlink, &target_st->st_nlink); + __put_user(host_st->st_uid, &target_st->st_uid); + __put_user(host_st->st_gid, &target_st->st_gid); + __put_user(host_st->st_rdev, &target_st->st_rdev); + /* XXX: better use of kernel struct */ + __put_user(host_st->st_size, &target_st->st_size); + __put_user(host_st->st_blksize, &target_st->st_blksize); + __put_user(host_st->st_blocks, &target_st->st_blocks); + __put_user(host_st->st_atime, &target_st->target_st_atime); + __put_user(host_st->st_mtime, &target_st->target_st_mtime); + __put_user(host_st->st_ctime, &target_st->target_st_ctime); + unlock_user_struct(target_st, target_addr, 1); + } + + return 0; +} +#endif + #if defined(USE_NPTL) /* ??? Using host futex calls even when target atomic operations are not really atomic probably breaks things. However implementing @@ -5149,7 +5210,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto efault; ret = get_errno(stat(path(p), &st)); unlock_user(p, arg1, 0); - goto do_stat64; + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg2, &st); + break; #endif #ifdef TARGET_NR_lstat64 case TARGET_NR_lstat64: @@ -5157,67 +5220,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, goto efault; ret = get_errno(lstat(path(p), &st)); unlock_user(p, arg1, 0); - goto do_stat64; + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg2, &st); + break; #endif #ifdef TARGET_NR_fstat64 case TARGET_NR_fstat64: - { - ret = get_errno(fstat(arg1, &st)); - do_stat64: - if (!is_error(ret)) { -#ifdef TARGET_ARM - if (((CPUARMState *)cpu_env)->eabi) { - struct target_eabi_stat64 *target_st; - - if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0)) - goto efault; - memset(target_st, 0, sizeof(struct target_eabi_stat64)); - __put_user(st.st_dev, &target_st->st_dev); - __put_user(st.st_ino, &target_st->st_ino); -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO - __put_user(st.st_ino, &target_st->__st_ino); -#endif - __put_user(st.st_mode, &target_st->st_mode); - __put_user(st.st_nlink, &target_st->st_nlink); - __put_user(st.st_uid, &target_st->st_uid); - __put_user(st.st_gid, &target_st->st_gid); - __put_user(st.st_rdev, &target_st->st_rdev); - __put_user(st.st_size, &target_st->st_size); - __put_user(st.st_blksize, &target_st->st_blksize); - __put_user(st.st_blocks, &target_st->st_blocks); - __put_user(st.st_atime, &target_st->target_st_atime); - __put_user(st.st_mtime, &target_st->target_st_mtime); - __put_user(st.st_ctime, &target_st->target_st_ctime); - unlock_user_struct(target_st, arg2, 1); - } else + ret = get_errno(fstat(arg1, &st)); + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg2, &st); + break; #endif - { - struct target_stat64 *target_st; - - if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0)) - goto efault; - memset(target_st, 0, sizeof(struct target_stat64)); - __put_user(st.st_dev, &target_st->st_dev); - __put_user(st.st_ino, &target_st->st_ino); -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO - __put_user(st.st_ino, &target_st->__st_ino); -#endif - __put_user(st.st_mode, &target_st->st_mode); - __put_user(st.st_nlink, &target_st->st_nlink); - __put_user(st.st_uid, &target_st->st_uid); - __put_user(st.st_gid, &target_st->st_gid); - __put_user(st.st_rdev, &target_st->st_rdev); - /* XXX: better use of kernel struct */ - __put_user(st.st_size, &target_st->st_size); - __put_user(st.st_blksize, &target_st->st_blksize); - __put_user(st.st_blocks, &target_st->st_blocks); - __put_user(st.st_atime, &target_st->target_st_atime); - __put_user(st.st_mtime, &target_st->target_st_mtime); - __put_user(st.st_ctime, &target_st->target_st_ctime); - unlock_user_struct(target_st, arg2, 1); - } - } - } +#ifdef TARGET_NR_fstatat64 + case TARGET_NR_fstatat64: + if (!(p = lock_user_string(arg2))) + goto efault; + ret = get_errno(fstatat(arg1, p, &st, arg4)); + if (!is_error(ret)) + ret = host_to_target_stat64(cpu_env, arg3, &st); break; #endif #ifdef USE_UID16 -- 1.5.6.5.GIT