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