Commit 5e0ccb18da28cc9fdac725ef41a7c174125b56ac
1 parent
f0b6243d
linux-user readlinkat() syscall, by Thayne Harbaugh.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3225 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
27 additions
and
0 deletions
linux-user/syscall.c
| @@ -147,6 +147,7 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ | @@ -147,6 +147,7 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ | ||
| 147 | #define __NR_sys_mkdirat __NR_mkdirat | 147 | #define __NR_sys_mkdirat __NR_mkdirat |
| 148 | #define __NR_sys_mknodat __NR_mknodat | 148 | #define __NR_sys_mknodat __NR_mknodat |
| 149 | #define __NR_sys_openat __NR_openat | 149 | #define __NR_sys_openat __NR_openat |
| 150 | +#define __NR_sys_readlinkat __NR_readlinkat | ||
| 150 | #define __NR_sys_renameat __NR_renameat | 151 | #define __NR_sys_renameat __NR_renameat |
| 151 | #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo | 152 | #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo |
| 152 | #define __NR_sys_symlinkat __NR_symlinkat | 153 | #define __NR_sys_symlinkat __NR_symlinkat |
| @@ -192,6 +193,10 @@ _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname, | @@ -192,6 +193,10 @@ _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname, | ||
| 192 | #if defined(TARGET_NR_openat) && defined(__NR_openat) | 193 | #if defined(TARGET_NR_openat) && defined(__NR_openat) |
| 193 | _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode) | 194 | _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode) |
| 194 | #endif | 195 | #endif |
| 196 | +#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat) | ||
| 197 | +_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname, | ||
| 198 | + char *,buf,size_t,bufsize) | ||
| 199 | +#endif | ||
| 195 | #if defined(TARGET_NR_renameat) && defined(__NR_renameat) | 200 | #if defined(TARGET_NR_renameat) && defined(__NR_renameat) |
| 196 | _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath, | 201 | _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath, |
| 197 | int,newdirfd,const char *,newpath) | 202 | int,newdirfd,const char *,newpath) |
| @@ -3402,6 +3407,28 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | @@ -3402,6 +3407,28 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | ||
| 3402 | unlock_user(p, arg1, 0); | 3407 | unlock_user(p, arg1, 0); |
| 3403 | } | 3408 | } |
| 3404 | break; | 3409 | break; |
| 3410 | +#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat) | ||
| 3411 | + case TARGET_NR_readlinkat: | ||
| 3412 | + if (!arg2 || !arg3) { | ||
| 3413 | + ret = -EFAULT; | ||
| 3414 | + goto fail; | ||
| 3415 | + } | ||
| 3416 | + { | ||
| 3417 | + void *p2 = NULL; | ||
| 3418 | + p = lock_user_string(arg2); | ||
| 3419 | + p2 = lock_user(arg3, arg4, 0); | ||
| 3420 | + if (!access_ok(VERIFY_READ, p, 1) | ||
| 3421 | + || !access_ok(VERIFY_READ, p2, 1)) | ||
| 3422 | + ret = -EFAULT; | ||
| 3423 | + else | ||
| 3424 | + ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4)); | ||
| 3425 | + if (p2) | ||
| 3426 | + unlock_user(p2, arg3, ret); | ||
| 3427 | + if (p) | ||
| 3428 | + unlock_user(p, arg2, 0); | ||
| 3429 | + } | ||
| 3430 | + break; | ||
| 3431 | +#endif | ||
| 3405 | #ifdef TARGET_NR_uselib | 3432 | #ifdef TARGET_NR_uselib |
| 3406 | case TARGET_NR_uselib: | 3433 | case TARGET_NR_uselib: |
| 3407 | goto unimplemented; | 3434 | goto unimplemented; |