mirror of https://github.com/xemu-project/xemu.git
bsd-user: Implement freebsd11 getdirents related syscalls
Implement the freebsd11 variant of the following syscalls: getdirentries(2) Co-authored-by: Stacey Son <sson@FreeBSD.org> Signed-off-by: Stacey Son <sson@FreeBSD.org> Signed-off-by: Michal Meloun <mmel@FreeBSD.org> Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Warner Losh <imp@bsdimp.com>
This commit is contained in:
parent
196da9d3d3
commit
91a98c9bbc
|
@ -41,6 +41,11 @@ __sym_compat(statfs, freebsd11_statfs, FBSD_1.0);
|
||||||
int freebsd11_fstatfs(int fd, struct freebsd11_statfs *buf);
|
int freebsd11_fstatfs(int fd, struct freebsd11_statfs *buf);
|
||||||
__sym_compat(fstatfs, freebsd11_fstatfs, FBSD_1.0);
|
__sym_compat(fstatfs, freebsd11_fstatfs, FBSD_1.0);
|
||||||
|
|
||||||
|
ssize_t freebsd11_getdirentries(int fd, char *buf, size_t nbytes, off_t *basep);
|
||||||
|
__sym_compat(getdirentries, freebsd11_getdirentries, FBSD_1.0);
|
||||||
|
ssize_t freebsd11_getdents(int fd, char *buf, size_t nbytes);
|
||||||
|
__sym_compat(getdents, freebsd11_getdents, FBSD_1.0);
|
||||||
|
|
||||||
|
|
||||||
/* stat(2) */
|
/* stat(2) */
|
||||||
static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2)
|
static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2)
|
||||||
|
@ -468,6 +473,45 @@ static inline abi_long do_freebsd11_getdents(abi_long arg1,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* getdirecentries(2) */
|
||||||
|
static inline abi_long do_freebsd11_getdirentries(abi_long arg1,
|
||||||
|
abi_ulong arg2, abi_long nbytes, abi_ulong arg4)
|
||||||
|
{
|
||||||
|
abi_long ret;
|
||||||
|
struct freebsd11_dirent *dirp;
|
||||||
|
long basep;
|
||||||
|
|
||||||
|
dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0);
|
||||||
|
if (dirp == NULL) {
|
||||||
|
return -TARGET_EFAULT;
|
||||||
|
}
|
||||||
|
ret = get_errno(freebsd11_getdirentries(arg1, (char *)dirp, nbytes, &basep));
|
||||||
|
if (!is_error(ret)) {
|
||||||
|
struct freebsd11_dirent *de;
|
||||||
|
int len = ret;
|
||||||
|
int reclen;
|
||||||
|
|
||||||
|
de = dirp;
|
||||||
|
while (len > 0) {
|
||||||
|
reclen = de->d_reclen;
|
||||||
|
if (reclen > len) {
|
||||||
|
return -TARGET_EFAULT;
|
||||||
|
}
|
||||||
|
de->d_reclen = tswap16(reclen);
|
||||||
|
de->d_fileno = tswap32(de->d_fileno);
|
||||||
|
len -= reclen;
|
||||||
|
de = (struct freebsd11_dirent *)((void *)de + reclen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlock_user(dirp, arg2, ret);
|
||||||
|
if (arg4) {
|
||||||
|
if (put_user(basep, arg4, abi_ulong)) {
|
||||||
|
return -TARGET_EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* getdirecentries(2) */
|
/* getdirecentries(2) */
|
||||||
static inline abi_long do_freebsd_getdirentries(abi_long arg1,
|
static inline abi_long do_freebsd_getdirentries(abi_long arg1,
|
||||||
abi_ulong arg2, abi_long nbytes, abi_ulong arg4)
|
abi_ulong arg2, abi_long nbytes, abi_ulong arg4)
|
||||||
|
|
Loading…
Reference in New Issue