diff --git a/libc-test/semver/dragonfly.txt b/libc-test/semver/dragonfly.txt index 31c40372f195..03fb43c471d4 100644 --- a/libc-test/semver/dragonfly.txt +++ b/libc-test/semver/dragonfly.txt @@ -1348,6 +1348,7 @@ freezero fsid_t fstatfs futimes +getdents getdomainname getdtablesize getentropy diff --git a/libc-test/semver/freebsd.txt b/libc-test/semver/freebsd.txt index be24fc9fe9ef..593cd023b258 100644 --- a/libc-test/semver/freebsd.txt +++ b/libc-test/semver/freebsd.txt @@ -1984,6 +1984,7 @@ fsid_t fstatfs ftok futimes +getdents getdomainname getdtablesize getgrent diff --git a/libc-test/semver/hurd.txt b/libc-test/semver/hurd.txt new file mode 100644 index 000000000000..a6f05f8eb4fd --- /dev/null +++ b/libc-test/semver/hurd.txt @@ -0,0 +1 @@ +getdents64 diff --git a/libc-test/semver/linux-gnu.txt b/libc-test/semver/linux-gnu.txt index 7fa8bbd7ace6..ca776444a362 100644 --- a/libc-test/semver/linux-gnu.txt +++ b/libc-test/semver/linux-gnu.txt @@ -604,6 +604,7 @@ fgetpwent_r fgetspent_r futimes getauxval +getdents64 getentropy getgrent_r getloadavg diff --git a/libc-test/semver/linux-musl.txt b/libc-test/semver/linux-musl.txt index 2fcf689e6cff..c806b4f4401b 100644 --- a/libc-test/semver/linux-musl.txt +++ b/libc-test/semver/linux-musl.txt @@ -65,6 +65,8 @@ euidaccess explicit_bzero futimes getauxval +getdents +getdents64 getloadavg getutxent getutxid diff --git a/libc-test/semver/netbsd.txt b/libc-test/semver/netbsd.txt index 4280ec02de73..dd931dd6d046 100644 --- a/libc-test/semver/netbsd.txt +++ b/libc-test/semver/netbsd.txt @@ -1340,6 +1340,7 @@ ftok futimes getbootfile getbyteorder +getdents getdiskrawname getdistcookedname getdomainname diff --git a/libc-test/semver/openbsd.txt b/libc-test/semver/openbsd.txt index 6e452dadea79..07b8a70cc914 100644 --- a/libc-test/semver/openbsd.txt +++ b/libc-test/semver/openbsd.txt @@ -1113,6 +1113,7 @@ ftok fusefs_args futex futimes +getdents getdomainname getdtablesize getentropy diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs index fb6b0fca02ae..0b9f37a90b28 100644 --- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs +++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -1586,6 +1586,8 @@ extern "C" { ) -> c_int; pub fn closefrom(lowfd: c_int) -> c_int; + + pub fn getdents(fd: c_int, buf: *mut c_char, nbytes: c_int) -> c_int; } #[link(name = "rt")] diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs index 88eb12541ff9..e17255543070 100644 --- a/src/unix/bsd/freebsdlike/freebsd/mod.rs +++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -4818,6 +4818,10 @@ cfg_if! { } } +extern "C" { + pub fn getdents(fd: c_int, buf: *mut c_char, nbytes: usize) -> isize; +} + extern "C" { #[cfg_attr(doc, doc(alias = "__errno_location"))] #[cfg_attr(doc, doc(alias = "errno"))] diff --git a/src/unix/bsd/netbsdlike/netbsd/mod.rs b/src/unix/bsd/netbsdlike/netbsd/mod.rs index 07532c84dfba..9ec22626d17f 100644 --- a/src/unix/bsd/netbsdlike/netbsd/mod.rs +++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -2957,6 +2957,8 @@ extern "C" { pub fn flags_to_string(flags: c_ulong, def: *const c_char) -> c_int; pub fn kinfo_getvmmap(pid: crate::pid_t, cntp: *mut size_t) -> *mut kinfo_vmentry; + + pub fn getdents(fd: c_int, buf: *mut c_char, nbytes: usize) -> c_int; } #[link(name = "execinfo")] diff --git a/src/unix/bsd/netbsdlike/openbsd/mod.rs b/src/unix/bsd/netbsdlike/openbsd/mod.rs index df4eb2233781..f6fd0d73495c 100644 --- a/src/unix/bsd/netbsdlike/openbsd/mod.rs +++ b/src/unix/bsd/netbsdlike/openbsd/mod.rs @@ -2074,6 +2074,8 @@ extern "C" { pub fn fstatfs(fd: c_int, buf: *mut statfs) -> c_int; pub fn getmntinfo(mntbufp: *mut *mut crate::statfs, flags: c_int) -> c_int; pub fn getfsstat(buf: *mut statfs, bufsize: size_t, flags: c_int) -> c_int; + + pub fn getdents(fd: c_int, buf: *mut c_void, nbytes: usize) -> c_int; } #[link(name = "execinfo")] diff --git a/src/unix/hurd/mod.rs b/src/unix/hurd/mod.rs index bb9bd87915b5..0441d5bb7c1a 100644 --- a/src/unix/hurd/mod.rs +++ b/src/unix/hurd/mod.rs @@ -4282,6 +4282,8 @@ extern "C" { pub fn seekdir(dirp: *mut crate::DIR, loc: c_long); pub fn telldir(dirp: *mut crate::DIR) -> c_long; + pub fn getdents64(fd: c_int, buf: *mut c_void, nbytes: usize) -> isize; + pub fn dirfd(dirp: *mut crate::DIR) -> c_int; #[link_name = "__xpg_strerror_r"] diff --git a/src/unix/linux_like/linux/gnu/mod.rs b/src/unix/linux_like/linux/gnu/mod.rs index 86ade8f04173..b273eea414d6 100644 --- a/src/unix/linux_like/linux/gnu/mod.rs +++ b/src/unix/linux_like/linux/gnu/mod.rs @@ -1346,6 +1346,13 @@ extern "C" { pub fn mempcpy(dest: *mut c_void, src: *const c_void, n: size_t) -> *mut c_void; } +extern "C" { + // There is no glibc wrapper for the getdents system call, and getdents64() is only available + // from 2.30 onwards. + /// `buffer` points to a buffer of [`crate::dirent64`] structs. + pub fn getdents64(fd: c_int, buffer: *mut c_void, nbytes: usize) -> isize; +} + cfg_if! { if #[cfg(any( target_arch = "x86", diff --git a/src/unix/linux_like/linux/musl/lfs64.rs b/src/unix/linux_like/linux/musl/lfs64.rs index e6506fd3d385..a55259288d42 100644 --- a/src/unix/linux_like/linux/musl/lfs64.rs +++ b/src/unix/linux_like/linux/musl/lfs64.rs @@ -198,6 +198,11 @@ pub unsafe extern "C" fn readdir64_r( crate::readdir_r(dirp, entry as *mut _, result as *mut _) } +#[inline] +pub unsafe extern "C" fn getdents64(fd: c_int, buf: *mut crate::dirent64, len: usize) -> c_int { + crate::getdents(fd, buf as *mut _, len) +} + #[inline] pub unsafe extern "C" fn sendfile64( out_fd: c_int, diff --git a/src/unix/linux_like/linux/musl/mod.rs b/src/unix/linux_like/linux/musl/mod.rs index 80d8003e2172..a0838499000b 100644 --- a/src/unix/linux_like/linux/musl/mod.rs +++ b/src/unix/linux_like/linux/musl/mod.rs @@ -971,6 +971,10 @@ extern "C" { pub fn utmpxname(file: *const c_char) -> c_int; } +extern "C" { + pub fn getdents(fd: c_int, buf: *mut crate::dirent, len: usize) -> c_int; +} + // Alias to 64 to mimic glibc's LFS64 support mod lfs64; pub use self::lfs64::*;