Commit 6556a833fa894bb9981dd273026d3615db1fffdc
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
Showing
2 changed files
with
28 additions
and
14 deletions
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" | ... | ... |