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" | ... | ... |