Commit 6a24a778baa2ced9982d036db90bf7ae98b4669a

Authored by balrog
1 parent a2155fcc

Implement fstatat64() syscall (by Kirill Shutemov).

Move the transformation of struct stat64 into a separate function and
implement fstatat64() using it.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5268 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 83 additions and 58 deletions
linux-user/syscall.c
... ... @@ -156,6 +156,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
156 156 #define __NR_sys_faccessat __NR_faccessat
157 157 #define __NR_sys_fchmodat __NR_fchmodat
158 158 #define __NR_sys_fchownat __NR_fchownat
  159 +#define __NR_sys_fstatat64 __NR_fstatat64
159 160 #define __NR_sys_getcwd1 __NR_getcwd
160 161 #define __NR_sys_getdents __NR_getdents
161 162 #define __NR_sys_getdents64 __NR_getdents64
... ... @@ -200,6 +201,10 @@ _syscall4(int,sys_fchmodat,int,dirfd,const char *,pathname,
200 201 _syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
201 202 uid_t,owner,gid_t,group,int,flags)
202 203 #endif
  204 +#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
  205 +_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
  206 + struct stat *,buf,int,flags)
  207 +#endif
203 208 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
204 209 #if TARGET_ABI_BITS == 32
205 210 _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
... ... @@ -3149,6 +3154,67 @@ static inline abi_long host_to_target_timespec(abi_ulong target_addr,
3149 3154 return 0;
3150 3155 }
3151 3156  
  3157 +#ifdef TARGET_NR_stat64
  3158 +static inline abi_long host_to_target_stat64(void *cpu_env,
  3159 + abi_ulong target_addr,
  3160 + struct stat *host_st)
  3161 +{
  3162 +#ifdef TARGET_ARM
  3163 + if (((CPUARMState *)cpu_env)->eabi) {
  3164 + struct target_eabi_stat64 *target_st;
  3165 +
  3166 + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
  3167 + return -TARGET_EFAULT;
  3168 + memset(target_st, 0, sizeof(struct target_eabi_stat64));
  3169 + __put_user(host_st->st_dev, &target_st->st_dev);
  3170 + __put_user(host_st->st_ino, &target_st->st_ino);
  3171 +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
  3172 + __put_user(host_st->st_ino, &target_st->__st_ino);
  3173 +#endif
  3174 + __put_user(host_st->st_mode, &target_st->st_mode);
  3175 + __put_user(host_st->st_nlink, &target_st->st_nlink);
  3176 + __put_user(host_st->st_uid, &target_st->st_uid);
  3177 + __put_user(host_st->st_gid, &target_st->st_gid);
  3178 + __put_user(host_st->st_rdev, &target_st->st_rdev);
  3179 + __put_user(host_st->st_size, &target_st->st_size);
  3180 + __put_user(host_st->st_blksize, &target_st->st_blksize);
  3181 + __put_user(host_st->st_blocks, &target_st->st_blocks);
  3182 + __put_user(host_st->st_atime, &target_st->target_st_atime);
  3183 + __put_user(host_st->st_mtime, &target_st->target_st_mtime);
  3184 + __put_user(host_st->st_ctime, &target_st->target_st_ctime);
  3185 + unlock_user_struct(target_st, target_addr, 1);
  3186 + } else
  3187 +#endif
  3188 + {
  3189 + struct target_stat64 *target_st;
  3190 +
  3191 + if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
  3192 + return -TARGET_EFAULT;
  3193 + memset(target_st, 0, sizeof(struct target_stat64));
  3194 + __put_user(host_st->st_dev, &target_st->st_dev);
  3195 + __put_user(host_st->st_ino, &target_st->st_ino);
  3196 +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
  3197 + __put_user(host_st->st_ino, &target_st->__st_ino);
  3198 +#endif
  3199 + __put_user(host_st->st_mode, &target_st->st_mode);
  3200 + __put_user(host_st->st_nlink, &target_st->st_nlink);
  3201 + __put_user(host_st->st_uid, &target_st->st_uid);
  3202 + __put_user(host_st->st_gid, &target_st->st_gid);
  3203 + __put_user(host_st->st_rdev, &target_st->st_rdev);
  3204 + /* XXX: better use of kernel struct */
  3205 + __put_user(host_st->st_size, &target_st->st_size);
  3206 + __put_user(host_st->st_blksize, &target_st->st_blksize);
  3207 + __put_user(host_st->st_blocks, &target_st->st_blocks);
  3208 + __put_user(host_st->st_atime, &target_st->target_st_atime);
  3209 + __put_user(host_st->st_mtime, &target_st->target_st_mtime);
  3210 + __put_user(host_st->st_ctime, &target_st->target_st_ctime);
  3211 + unlock_user_struct(target_st, target_addr, 1);
  3212 + }
  3213 +
  3214 + return 0;
  3215 +}
  3216 +#endif
  3217 +
3152 3218 #if defined(USE_NPTL)
3153 3219 /* ??? Using host futex calls even when target atomic operations
3154 3220 are not really atomic probably breaks things. However implementing
... ... @@ -5142,7 +5208,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5142 5208 goto efault;
5143 5209 ret = get_errno(stat(path(p), &st));
5144 5210 unlock_user(p, arg1, 0);
5145   - goto do_stat64;
  5211 + if (!is_error(ret))
  5212 + ret = host_to_target_stat64(cpu_env, arg2, &st);
  5213 + break;
5146 5214 #endif
5147 5215 #ifdef TARGET_NR_lstat64
5148 5216 case TARGET_NR_lstat64:
... ... @@ -5150,67 +5218,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
5150 5218 goto efault;
5151 5219 ret = get_errno(lstat(path(p), &st));
5152 5220 unlock_user(p, arg1, 0);
5153   - goto do_stat64;
  5221 + if (!is_error(ret))
  5222 + ret = host_to_target_stat64(cpu_env, arg2, &st);
  5223 + break;
5154 5224 #endif
5155 5225 #ifdef TARGET_NR_fstat64
5156 5226 case TARGET_NR_fstat64:
5157   - {
5158   - ret = get_errno(fstat(arg1, &st));
5159   - do_stat64:
5160   - if (!is_error(ret)) {
5161   -#ifdef TARGET_ARM
5162   - if (((CPUARMState *)cpu_env)->eabi) {
5163   - struct target_eabi_stat64 *target_st;
5164   -
5165   - if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5166   - goto efault;
5167   - memset(target_st, 0, sizeof(struct target_eabi_stat64));
5168   - __put_user(st.st_dev, &target_st->st_dev);
5169   - __put_user(st.st_ino, &target_st->st_ino);
5170   -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5171   - __put_user(st.st_ino, &target_st->__st_ino);
5172   -#endif
5173   - __put_user(st.st_mode, &target_st->st_mode);
5174   - __put_user(st.st_nlink, &target_st->st_nlink);
5175   - __put_user(st.st_uid, &target_st->st_uid);
5176   - __put_user(st.st_gid, &target_st->st_gid);
5177   - __put_user(st.st_rdev, &target_st->st_rdev);
5178   - __put_user(st.st_size, &target_st->st_size);
5179   - __put_user(st.st_blksize, &target_st->st_blksize);
5180   - __put_user(st.st_blocks, &target_st->st_blocks);
5181   - __put_user(st.st_atime, &target_st->target_st_atime);
5182   - __put_user(st.st_mtime, &target_st->target_st_mtime);
5183   - __put_user(st.st_ctime, &target_st->target_st_ctime);
5184   - unlock_user_struct(target_st, arg2, 1);
5185   - } else
  5227 + ret = get_errno(fstat(arg1, &st));
  5228 + if (!is_error(ret))
  5229 + ret = host_to_target_stat64(cpu_env, arg2, &st);
  5230 + break;
5186 5231 #endif
5187   - {
5188   - struct target_stat64 *target_st;
5189   -
5190   - if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
5191   - goto efault;
5192   - memset(target_st, 0, sizeof(struct target_stat64));
5193   - __put_user(st.st_dev, &target_st->st_dev);
5194   - __put_user(st.st_ino, &target_st->st_ino);
5195   -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
5196   - __put_user(st.st_ino, &target_st->__st_ino);
5197   -#endif
5198   - __put_user(st.st_mode, &target_st->st_mode);
5199   - __put_user(st.st_nlink, &target_st->st_nlink);
5200   - __put_user(st.st_uid, &target_st->st_uid);
5201   - __put_user(st.st_gid, &target_st->st_gid);
5202   - __put_user(st.st_rdev, &target_st->st_rdev);
5203   - /* XXX: better use of kernel struct */
5204   - __put_user(st.st_size, &target_st->st_size);
5205   - __put_user(st.st_blksize, &target_st->st_blksize);
5206   - __put_user(st.st_blocks, &target_st->st_blocks);
5207   - __put_user(st.st_atime, &target_st->target_st_atime);
5208   - __put_user(st.st_mtime, &target_st->target_st_mtime);
5209   - __put_user(st.st_ctime, &target_st->target_st_ctime);
5210   - unlock_user_struct(target_st, arg2, 1);
5211   - }
5212   - }
5213   - }
  5232 +#if defined(TARGET_NR_fstatat64) && defined(__NR_fstatat64)
  5233 + case TARGET_NR_fstatat64:
  5234 + if (!(p = lock_user_string(arg2)))
  5235 + goto efault;
  5236 + ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
  5237 + if (!is_error(ret))
  5238 + ret = host_to_target_stat64(cpu_env, arg3, &st);
5214 5239 break;
5215 5240 #endif
5216 5241 #ifdef USE_UID16
... ...