bsd-user: Implement getdents related syscalls
Implement the following syscalls: getdents(2) getdirecentries(2) Signed-off-by: Stacey Son <sson@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
191fe50d5d
commit
213444529d
@ -279,4 +279,76 @@ static inline abi_long do_freebsd_getfsstat(abi_ulong target_addr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* getdents(2) */
|
||||
static inline abi_long do_freebsd11_getdents(abi_long arg1,
|
||||
abi_ulong arg2, abi_long nbytes)
|
||||
{
|
||||
abi_long ret;
|
||||
struct freebsd11_dirent *dirp;
|
||||
|
||||
dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0);
|
||||
if (dirp == NULL) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(freebsd11_getdents(arg1, (char *)dirp, nbytes));
|
||||
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;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* getdirecentries(2) */
|
||||
static inline abi_long do_freebsd_getdirentries(abi_long arg1,
|
||||
abi_ulong arg2, abi_long nbytes, abi_ulong arg4)
|
||||
{
|
||||
abi_long ret;
|
||||
struct dirent *dirp;
|
||||
long basep;
|
||||
|
||||
dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0);
|
||||
if (dirp == NULL) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(getdirentries(arg1, (char *)dirp, nbytes, &basep));
|
||||
if (!is_error(ret)) {
|
||||
struct dirent *de;
|
||||
int len = ret;
|
||||
int reclen;
|
||||
|
||||
de = dirp;
|
||||
while (len > 0) {
|
||||
reclen = de->d_reclen;
|
||||
if (reclen > len) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
de->d_fileno = tswap64(de->d_fileno);
|
||||
de->d_off = tswap64(de->d_off);
|
||||
de->d_reclen = tswap16(de->d_reclen);
|
||||
de->d_namlen = tswap16(de->d_namlen);
|
||||
len -= reclen;
|
||||
de = (struct dirent *)((void *)de + reclen);
|
||||
}
|
||||
}
|
||||
unlock_user(dirp, arg2, ret);
|
||||
if (arg4) {
|
||||
if (put_user(basep, arg4, abi_ulong)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* BSD_USER_FREEBSD_OS_STAT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user