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