From 6556a833fa894bb9981dd273026d3615db1fffdc Mon Sep 17 00:00:00 2001 From: aurel32 Date: Mon, 13 Oct 2008 21:08:17 +0000 Subject: [PATCH] linux-user: fix getdents* syscalls glibc's structs dirent and dirent64 is different from in-kernel dirent and dirent64. Kernel headers doesn't provide structs dirent(64) any more. So we should add it to qemu headers. To avoid conflict with glibc it called struct linux_dirent(64). Signed-off-by: Kirill A. Shutemov Signed-off-by: Aurelien Jarno git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5480 c046a42c-6fe2-441c-8c8c-71466251a162 --- linux-user/syscall.c | 27 +++++++++++++-------------- linux-user/syscall_defs.h | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index dc7e561009..40e985adec 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -94,8 +93,8 @@ #endif //#include -#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) -#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) +#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2]) +#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2]) #undef _syscall0 @@ -216,10 +215,10 @@ _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname, #endif _syscall2(int,sys_getcwd1,char *,buf,size_t,size) #if TARGET_ABI_BITS == 32 -_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count); +_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count); #endif #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) -_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count); +_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count); #endif _syscall2(int, sys_getpriority, int, which, int, who); #if !defined (__x86_64__) @@ -4879,7 +4878,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 { struct target_dirent *target_dirp; - struct dirent *dirp; + struct linux_dirent *dirp; abi_long count = arg3; dirp = malloc(count); @@ -4890,7 +4889,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(sys_getdents(arg1, dirp, count)); if (!is_error(ret)) { - struct dirent *de; + struct linux_dirent *de; struct target_dirent *tde; int len = ret; int reclen, treclen; @@ -4912,7 +4911,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, tnamelen = 256; /* XXX: may not be correct */ strncpy(tde->d_name, de->d_name, tnamelen); - de = (struct dirent *)((char *)de + reclen); + de = (struct linux_dirent *)((char *)de + reclen); len -= reclen; tde = (struct target_dirent *)((char *)tde + treclen); count1 += treclen; @@ -4924,14 +4923,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } #else { - struct dirent *dirp; + struct linux_dirent *dirp; abi_long count = arg3; if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0))) goto efault; ret = get_errno(sys_getdents(arg1, dirp, count)); if (!is_error(ret)) { - struct dirent *de; + struct linux_dirent *de; int len = ret; int reclen; de = dirp; @@ -4942,7 +4941,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, de->d_reclen = tswap16(reclen); tswapls(&de->d_ino); tswapls(&de->d_off); - de = (struct dirent *)((char *)de + reclen); + de = (struct linux_dirent *)((char *)de + reclen); len -= reclen; } } @@ -4953,13 +4952,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) case TARGET_NR_getdents64: { - struct dirent64 *dirp; + struct linux_dirent64 *dirp; abi_long count = arg3; if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0))) goto efault; ret = get_errno(sys_getdents64(arg1, dirp, count)); if (!is_error(ret)) { - struct dirent64 *de; + struct linux_dirent64 *de; int len = ret; int reclen; de = dirp; @@ -4970,7 +4969,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, de->d_reclen = tswap16(reclen); tswap64s((uint64_t *)&de->d_ino); tswap64s((uint64_t *)&de->d_off); - de = (struct dirent64 *)((char *)de + reclen); + de = (struct linux_dirent64 *)((char *)de + reclen); len -= reclen; } } diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index c30bb1532b..5a580100cb 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -1963,6 +1963,21 @@ struct target_sysinfo { char _f[20-2*sizeof(abi_long)-sizeof(int)]; /* Padding: libc5 uses this.. */ }; +struct linux_dirent { + long d_ino; + unsigned long d_off; + unsigned short d_reclen; + char d_name[256]; /* We must not include limits.h! */ +}; + +struct linux_dirent64 { + uint64_t d_ino; + int64_t d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[256]; +}; + #include "socket.h" #include "errno_defs.h"