diff options
author | Michal Meloun <mmel@FreeBSD.org> | 2023-08-13 10:41:46 +0200 |
---|---|---|
committer | Warner Losh <imp@bsdimp.com> | 2023-08-28 12:16:18 -0600 |
commit | 91a98c9bbcfba2a9f278a0811676cd2f8000481c (patch) | |
tree | 30d0076eb8ef0ae348b4874f34974ccabd73a76b /bsd-user/freebsd/os-stat.h | |
parent | 196da9d3d3f1ab142473a6b2f714720ba1b29a33 (diff) |
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>
Diffstat (limited to 'bsd-user/freebsd/os-stat.h')
-rw-r--r-- | bsd-user/freebsd/os-stat.h | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h index 04a61fabd1..26909af455 100644 --- a/bsd-user/freebsd/os-stat.h +++ b/bsd-user/freebsd/os-stat.h @@ -41,6 +41,11 @@ __sym_compat(statfs, freebsd11_statfs, FBSD_1.0); int freebsd11_fstatfs(int fd, struct freebsd11_statfs *buf); __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) */ static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2) @@ -469,6 +474,45 @@ static inline abi_long do_freebsd11_getdents(abi_long arg1, } /* 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) */ static inline abi_long do_freebsd_getdirentries(abi_long arg1, abi_ulong arg2, abi_long nbytes, abi_ulong arg4) { |