Commit 64f0ce4c0d2c45ff69bfc09092649ee3674f6592
1 parent
722183f6
linux-user linkat() syscall, by Thayne Harbaugh.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3223 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
27 additions
and
0 deletions
linux-user/syscall.c
| @@ -143,6 +143,7 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ | @@ -143,6 +143,7 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ | ||
| 143 | #define __NR_sys_getcwd1 __NR_getcwd | 143 | #define __NR_sys_getcwd1 __NR_getcwd |
| 144 | #define __NR_sys_getdents __NR_getdents | 144 | #define __NR_sys_getdents __NR_getdents |
| 145 | #define __NR_sys_getdents64 __NR_getdents64 | 145 | #define __NR_sys_getdents64 __NR_getdents64 |
| 146 | +#define __NR_sys_linkat __NR_linkat | ||
| 146 | #define __NR_sys_mkdirat __NR_mkdirat | 147 | #define __NR_sys_mkdirat __NR_mkdirat |
| 147 | #define __NR_sys_mknodat __NR_mknodat | 148 | #define __NR_sys_mknodat __NR_mknodat |
| 148 | #define __NR_sys_openat __NR_openat | 149 | #define __NR_sys_openat __NR_openat |
| @@ -176,6 +177,10 @@ _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count); | @@ -176,6 +177,10 @@ _syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count); | ||
| 176 | #endif | 177 | #endif |
| 177 | _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, | 178 | _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, |
| 178 | loff_t *, res, uint, wh); | 179 | loff_t *, res, uint, wh); |
| 180 | +#if defined(TARGET_NR_linkat) && defined(__NR_linkat) | ||
| 181 | +_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath, | ||
| 182 | + int,newdirfd,const char *,newpath,int,flags) | ||
| 183 | +#endif | ||
| 179 | #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat) | 184 | #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat) |
| 180 | _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode) | 185 | _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode) |
| 181 | #endif | 186 | #endif |
| @@ -2581,6 +2586,28 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | @@ -2581,6 +2586,28 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, | ||
| 2581 | unlock_user(p, arg1, 0); | 2586 | unlock_user(p, arg1, 0); |
| 2582 | } | 2587 | } |
| 2583 | break; | 2588 | break; |
| 2589 | +#if defined(TARGET_NR_linkat) && defined(__NR_linkat) | ||
| 2590 | + case TARGET_NR_linkat: | ||
| 2591 | + if (!arg2 || !arg4) { | ||
| 2592 | + ret = -EFAULT; | ||
| 2593 | + goto fail; | ||
| 2594 | + } | ||
| 2595 | + { | ||
| 2596 | + void * p2 = NULL; | ||
| 2597 | + p = lock_user_string(arg2); | ||
| 2598 | + p2 = lock_user_string(arg4); | ||
| 2599 | + if (!access_ok(VERIFY_READ, p, 1) | ||
| 2600 | + || !access_ok(VERIFY_READ, p2, 1)) | ||
| 2601 | + ret = -EFAULT; | ||
| 2602 | + else | ||
| 2603 | + ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5)); | ||
| 2604 | + if (p2) | ||
| 2605 | + unlock_user(p, arg2, 0); | ||
| 2606 | + if (p) | ||
| 2607 | + unlock_user(p2, arg4, 0); | ||
| 2608 | + } | ||
| 2609 | + break; | ||
| 2610 | +#endif | ||
| 2584 | case TARGET_NR_unlink: | 2611 | case TARGET_NR_unlink: |
| 2585 | p = lock_user_string(arg1); | 2612 | p = lock_user_string(arg1); |
| 2586 | ret = get_errno(unlink(p)); | 2613 | ret = get_errno(unlink(p)); |