linux-user: implement renameat2

This is needed for new architectures like RISC-V which do not provide any
other rename-like syscall.

Signed-off-by: Andreas Schwab <schwab@suse.de>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <mvm607su9qs.fsf@suse.de>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
Andreas Schwab 2018-01-23 11:53:31 +01:00 committed by Laurent Vivier
parent 9c4bbee9e3
commit 95d0307cc1

View File

@ -600,6 +600,24 @@ static int sys_utimensat(int dirfd, const char *pathname,
#endif #endif
#endif /* TARGET_NR_utimensat */ #endif /* TARGET_NR_utimensat */
#ifdef TARGET_NR_renameat2
#if defined(__NR_renameat2)
#define __NR_sys_renameat2 __NR_renameat2
_syscall5(int, sys_renameat2, int, oldfd, const char *, old, int, newfd,
const char *, new, unsigned int, flags)
#else
static int sys_renameat2(int oldfd, const char *old,
int newfd, const char *new, int flags)
{
if (flags == 0) {
return renameat(oldfd, old, newfd, new);
}
errno = ENOSYS;
return -1;
}
#endif
#endif /* TARGET_NR_renameat2 */
#ifdef CONFIG_INOTIFY #ifdef CONFIG_INOTIFY
#include <sys/inotify.h> #include <sys/inotify.h>
@ -8426,6 +8444,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
} }
break; break;
#endif #endif
#if defined(TARGET_NR_renameat2)
case TARGET_NR_renameat2:
{
void *p2;
p = lock_user_string(arg2);
p2 = lock_user_string(arg4);
if (!p || !p2) {
ret = -TARGET_EFAULT;
} else {
ret = get_errno(sys_renameat2(arg1, p, arg3, p2, arg5));
}
unlock_user(p2, arg4, 0);
unlock_user(p, arg2, 0);
}
break;
#endif
#ifdef TARGET_NR_mkdir #ifdef TARGET_NR_mkdir
case TARGET_NR_mkdir: case TARGET_NR_mkdir:
if (!(p = lock_user_string(arg1))) if (!(p = lock_user_string(arg1)))