Commit 6556a833fa894bb9981dd273026d3615db1fffdc

Authored by aurel32
1 parent 2054ac9b

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
linux-user/syscall.c
... ... @@ -28,7 +28,6 @@
28 28 #include <fcntl.h>
29 29 #include <time.h>
30 30 #include <limits.h>
31   -#include <dirent.h>
32 31 #include <sys/types.h>
33 32 #include <sys/ipc.h>
34 33 #include <sys/msg.h>
... ... @@ -94,8 +93,8 @@
94 93 #endif
95 94  
96 95 //#include <linux/msdos_fs.h>
97   -#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
98   -#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
  96 +#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2])
  97 +#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2])
99 98  
100 99  
101 100 #undef _syscall0
... ... @@ -216,10 +215,10 @@ _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
216 215 #endif
217 216 _syscall2(int,sys_getcwd1,char *,buf,size_t,size)
218 217 #if TARGET_ABI_BITS == 32
219   -_syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count);
  218 +_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
220 219 #endif
221 220 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
222   -_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count);
  221 +_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
223 222 #endif
224 223 _syscall2(int, sys_getpriority, int, which, int, who);
225 224 #if !defined (__x86_64__)
... ... @@ -4879,7 +4878,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4879 4878 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
4880 4879 {
4881 4880 struct target_dirent *target_dirp;
4882   - struct dirent *dirp;
  4881 + struct linux_dirent *dirp;
4883 4882 abi_long count = arg3;
4884 4883  
4885 4884 dirp = malloc(count);
... ... @@ -4890,7 +4889,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4890 4889  
4891 4890 ret = get_errno(sys_getdents(arg1, dirp, count));
4892 4891 if (!is_error(ret)) {
4893   - struct dirent *de;
  4892 + struct linux_dirent *de;
4894 4893 struct target_dirent *tde;
4895 4894 int len = ret;
4896 4895 int reclen, treclen;
... ... @@ -4912,7 +4911,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4912 4911 tnamelen = 256;
4913 4912 /* XXX: may not be correct */
4914 4913 strncpy(tde->d_name, de->d_name, tnamelen);
4915   - de = (struct dirent *)((char *)de + reclen);
  4914 + de = (struct linux_dirent *)((char *)de + reclen);
4916 4915 len -= reclen;
4917 4916 tde = (struct target_dirent *)((char *)tde + treclen);
4918 4917 count1 += treclen;
... ... @@ -4924,14 +4923,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4924 4923 }
4925 4924 #else
4926 4925 {
4927   - struct dirent *dirp;
  4926 + struct linux_dirent *dirp;
4928 4927 abi_long count = arg3;
4929 4928  
4930 4929 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4931 4930 goto efault;
4932 4931 ret = get_errno(sys_getdents(arg1, dirp, count));
4933 4932 if (!is_error(ret)) {
4934   - struct dirent *de;
  4933 + struct linux_dirent *de;
4935 4934 int len = ret;
4936 4935 int reclen;
4937 4936 de = dirp;
... ... @@ -4942,7 +4941,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4942 4941 de->d_reclen = tswap16(reclen);
4943 4942 tswapls(&de->d_ino);
4944 4943 tswapls(&de->d_off);
4945   - de = (struct dirent *)((char *)de + reclen);
  4944 + de = (struct linux_dirent *)((char *)de + reclen);
4946 4945 len -= reclen;
4947 4946 }
4948 4947 }
... ... @@ -4953,13 +4952,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4953 4952 #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
4954 4953 case TARGET_NR_getdents64:
4955 4954 {
4956   - struct dirent64 *dirp;
  4955 + struct linux_dirent64 *dirp;
4957 4956 abi_long count = arg3;
4958 4957 if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
4959 4958 goto efault;
4960 4959 ret = get_errno(sys_getdents64(arg1, dirp, count));
4961 4960 if (!is_error(ret)) {
4962   - struct dirent64 *de;
  4961 + struct linux_dirent64 *de;
4963 4962 int len = ret;
4964 4963 int reclen;
4965 4964 de = dirp;
... ... @@ -4970,7 +4969,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4970 4969 de->d_reclen = tswap16(reclen);
4971 4970 tswap64s((uint64_t *)&de->d_ino);
4972 4971 tswap64s((uint64_t *)&de->d_off);
4973   - de = (struct dirent64 *)((char *)de + reclen);
  4972 + de = (struct linux_dirent64 *)((char *)de + reclen);
4974 4973 len -= reclen;
4975 4974 }
4976 4975 }
... ...
linux-user/syscall_defs.h
... ... @@ -1963,6 +1963,21 @@ struct target_sysinfo {
1963 1963 char _f[20-2*sizeof(abi_long)-sizeof(int)]; /* Padding: libc5 uses this.. */
1964 1964 };
1965 1965  
  1966 +struct linux_dirent {
  1967 + long d_ino;
  1968 + unsigned long d_off;
  1969 + unsigned short d_reclen;
  1970 + char d_name[256]; /* We must not include limits.h! */
  1971 +};
  1972 +
  1973 +struct linux_dirent64 {
  1974 + uint64_t d_ino;
  1975 + int64_t d_off;
  1976 + unsigned short d_reclen;
  1977 + unsigned char d_type;
  1978 + char d_name[256];
  1979 +};
  1980 +
1966 1981 #include "socket.h"
1967 1982  
1968 1983 #include "errno_defs.h"
... ...