Commit f0b6243d5d7c18efbfcc7e477ffb9b8f523e2fef
1 parent
64f0ce4c
linux-user symlinkat() syscall, by Thayne Harbaugh.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3224 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
27 additions
and
0 deletions
linux-user/syscall.c
@@ -149,6 +149,7 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ | @@ -149,6 +149,7 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ | ||
149 | #define __NR_sys_openat __NR_openat | 149 | #define __NR_sys_openat __NR_openat |
150 | #define __NR_sys_renameat __NR_renameat | 150 | #define __NR_sys_renameat __NR_renameat |
151 | #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo | 151 | #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo |
152 | +#define __NR_sys_symlinkat __NR_symlinkat | ||
152 | #define __NR_sys_syslog __NR_syslog | 153 | #define __NR_sys_syslog __NR_syslog |
153 | #define __NR_sys_tgkill __NR_tgkill | 154 | #define __NR_sys_tgkill __NR_tgkill |
154 | #define __NR_sys_tkill __NR_tkill | 155 | #define __NR_sys_tkill __NR_tkill |
@@ -196,6 +197,10 @@ _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath, | @@ -196,6 +197,10 @@ _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath, | ||
196 | int,newdirfd,const char *,newpath) | 197 | int,newdirfd,const char *,newpath) |
197 | #endif | 198 | #endif |
198 | _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo) | 199 | _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo) |
200 | +#ifdef TARGET_NR_symlinkat | ||
201 | +_syscall3(int,sys_symlinkat,const char *,oldpath, | ||
202 | + int,newdirfd,const char *,newpath) | ||
203 | +#endif | ||
199 | _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) | 204 | _syscall3(int,sys_syslog,int,type,char*,bufp,int,len) |
200 | #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill) | 205 | #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill) |
201 | _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) | 206 | _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig) |
@@ -3361,6 +3366,28 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | @@ -3361,6 +3366,28 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | ||
3361 | unlock_user(p, arg1, 0); | 3366 | unlock_user(p, arg1, 0); |
3362 | } | 3367 | } |
3363 | break; | 3368 | break; |
3369 | +#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat) | ||
3370 | + case TARGET_NR_symlinkat: | ||
3371 | + if (!arg1 || !arg3) { | ||
3372 | + ret = -EFAULT; | ||
3373 | + goto fail; | ||
3374 | + } | ||
3375 | + { | ||
3376 | + void *p2 = NULL; | ||
3377 | + p = lock_user_string(arg1); | ||
3378 | + p2 = lock_user_string(arg3); | ||
3379 | + if (!access_ok(VERIFY_READ, p, 1) | ||
3380 | + || !access_ok(VERIFY_READ, p2, 1)) | ||
3381 | + ret = -EFAULT; | ||
3382 | + else | ||
3383 | + ret = get_errno(sys_symlinkat(p, arg2, p2)); | ||
3384 | + if (p2) | ||
3385 | + unlock_user(p2, arg3, 0); | ||
3386 | + if (p) | ||
3387 | + unlock_user(p, arg1, 0); | ||
3388 | + } | ||
3389 | + break; | ||
3390 | +#endif | ||
3364 | #ifdef TARGET_NR_oldlstat | 3391 | #ifdef TARGET_NR_oldlstat |
3365 | case TARGET_NR_oldlstat: | 3392 | case TARGET_NR_oldlstat: |
3366 | goto unimplemented; | 3393 | goto unimplemented; |