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 <kirill@shutemov.name>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5480 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aurel32 2008-10-13 21:08:17 +00:00
parent 2054ac9baf
commit 6556a833fa
2 changed files with 28 additions and 14 deletions

View File

@ -28,7 +28,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
#include <limits.h> #include <limits.h>
#include <dirent.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/msg.h> #include <sys/msg.h>
@ -94,8 +93,8 @@
#endif #endif
//#include <linux/msdos_fs.h> //#include <linux/msdos_fs.h>
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) #define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) #define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
#undef _syscall0 #undef _syscall0
@ -216,10 +215,10 @@ _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
#endif #endif
_syscall2(int,sys_getcwd1,char *,buf,size_t,size) _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
#if TARGET_ABI_BITS == 32 #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 #endif
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) #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 #endif
_syscall2(int, sys_getpriority, int, which, int, who); _syscall2(int, sys_getpriority, int, which, int, who);
#if !defined (__x86_64__) #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 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
{ {
struct target_dirent *target_dirp; struct target_dirent *target_dirp;
struct dirent *dirp; struct linux_dirent *dirp;
abi_long count = arg3; abi_long count = arg3;
dirp = malloc(count); 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)); ret = get_errno(sys_getdents(arg1, dirp, count));
if (!is_error(ret)) { if (!is_error(ret)) {
struct dirent *de; struct linux_dirent *de;
struct target_dirent *tde; struct target_dirent *tde;
int len = ret; int len = ret;
int reclen, treclen; int reclen, treclen;
@ -4912,7 +4911,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
tnamelen = 256; tnamelen = 256;
/* XXX: may not be correct */ /* XXX: may not be correct */
strncpy(tde->d_name, de->d_name, tnamelen); strncpy(tde->d_name, de->d_name, tnamelen);
de = (struct dirent *)((char *)de + reclen); de = (struct linux_dirent *)((char *)de + reclen);
len -= reclen; len -= reclen;
tde = (struct target_dirent *)((char *)tde + treclen); tde = (struct target_dirent *)((char *)tde + treclen);
count1 += treclen; count1 += treclen;
@ -4924,14 +4923,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
} }
#else #else
{ {
struct dirent *dirp; struct linux_dirent *dirp;
abi_long count = arg3; abi_long count = arg3;
if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0))) if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
goto efault; goto efault;
ret = get_errno(sys_getdents(arg1, dirp, count)); ret = get_errno(sys_getdents(arg1, dirp, count));
if (!is_error(ret)) { if (!is_error(ret)) {
struct dirent *de; struct linux_dirent *de;
int len = ret; int len = ret;
int reclen; int reclen;
de = dirp; de = dirp;
@ -4942,7 +4941,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
de->d_reclen = tswap16(reclen); de->d_reclen = tswap16(reclen);
tswapls(&de->d_ino); tswapls(&de->d_ino);
tswapls(&de->d_off); tswapls(&de->d_off);
de = (struct dirent *)((char *)de + reclen); de = (struct linux_dirent *)((char *)de + reclen);
len -= 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) #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
case TARGET_NR_getdents64: case TARGET_NR_getdents64:
{ {
struct dirent64 *dirp; struct linux_dirent64 *dirp;
abi_long count = arg3; abi_long count = arg3;
if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0))) if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
goto efault; goto efault;
ret = get_errno(sys_getdents64(arg1, dirp, count)); ret = get_errno(sys_getdents64(arg1, dirp, count));
if (!is_error(ret)) { if (!is_error(ret)) {
struct dirent64 *de; struct linux_dirent64 *de;
int len = ret; int len = ret;
int reclen; int reclen;
de = dirp; de = dirp;
@ -4970,7 +4969,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
de->d_reclen = tswap16(reclen); de->d_reclen = tswap16(reclen);
tswap64s((uint64_t *)&de->d_ino); tswap64s((uint64_t *)&de->d_ino);
tswap64s((uint64_t *)&de->d_off); tswap64s((uint64_t *)&de->d_off);
de = (struct dirent64 *)((char *)de + reclen); de = (struct linux_dirent64 *)((char *)de + reclen);
len -= reclen; len -= reclen;
} }
} }

View File

@ -1963,6 +1963,21 @@ struct target_sysinfo {
char _f[20-2*sizeof(abi_long)-sizeof(int)]; /* Padding: libc5 uses this.. */ 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 "socket.h"
#include "errno_defs.h" #include "errno_defs.h"