From 423017b865e6570c60cf529537963d45ff2d40f9 Mon Sep 17 00:00:00 2001 From: Danny McClanahan <1305167+cosmicexplorer@users.noreply.github.com> Date: Thu, 3 Jul 2025 00:07:27 -0400 Subject: [PATCH 1/6] add musl and glibc wrappers for getdents{,64} --- src/unix/linux_like/linux/gnu/mod.rs | 7 +++++++ src/unix/linux_like/linux/musl/lfs64.rs | 5 +++++ src/unix/linux_like/linux/musl/mod.rs | 15 +++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/unix/linux_like/linux/gnu/mod.rs b/src/unix/linux_like/linux/gnu/mod.rs index 86ade8f04173e..b273eea414d62 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 e6506fd3d385d..a55259288d420 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 80d8003e21724..bc5003162c92f 100644 --- a/src/unix/linux_like/linux/musl/mod.rs +++ b/src/unix/linux_like/linux/musl/mod.rs @@ -37,6 +37,15 @@ cfg_if! { } } +#[repr(C)] +pub struct posix_dent { + pub d_ino: ino_t, + pub d_off: off_t, + pub d_reclen: c_ushort, + pub d_type: c_uchar, + pub d_name: *mut c_char, +} + impl siginfo_t { pub unsafe fn si_addr(&self) -> *mut c_void { #[repr(C)] @@ -971,6 +980,12 @@ extern "C" { pub fn utmpxname(file: *const c_char) -> c_int; } +extern "C" { + pub fn posix_getdents(fd: c_int, buf: *mut c_void, len: usize, flags: c_int) -> isize; + + 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::*; From 5bd1a65b0784013f5bf5f0c6437297eba48cad0a Mon Sep 17 00:00:00 2001 From: Danny McClanahan <1305167+cosmicexplorer@users.noreply.github.com> Date: Thu, 3 Jul 2025 00:50:11 -0400 Subject: [PATCH 2/6] add debug impl to posix_dent --- src/unix/linux_like/linux/musl/mod.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/unix/linux_like/linux/musl/mod.rs b/src/unix/linux_like/linux/musl/mod.rs index bc5003162c92f..f90f3a2a411e4 100644 --- a/src/unix/linux_like/linux/musl/mod.rs +++ b/src/unix/linux_like/linux/musl/mod.rs @@ -37,13 +37,15 @@ cfg_if! { } } -#[repr(C)] -pub struct posix_dent { - pub d_ino: ino_t, - pub d_off: off_t, - pub d_reclen: c_ushort, - pub d_type: c_uchar, - pub d_name: *mut c_char, +s_no_extra_traits! { + #[repr(C)] + pub struct posix_dent { + pub d_ino: ino_t, + pub d_off: off_t, + pub d_reclen: c_ushort, + pub d_type: c_uchar, + pub d_name: *mut c_char, + } } impl siginfo_t { From e0d0894b1e5a214228dee8ce9c000a2500cb910b Mon Sep 17 00:00:00 2001 From: Danny McClanahan <1305167+cosmicexplorer@users.noreply.github.com> Date: Thu, 3 Jul 2025 00:58:00 -0400 Subject: [PATCH 3/6] update semver tests --- libc-test/semver/linux-gnu.txt | 1 + libc-test/semver/linux-musl.txt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/libc-test/semver/linux-gnu.txt b/libc-test/semver/linux-gnu.txt index 7fa8bbd7ace63..ca776444a362d 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 2fcf689e6cff6..e6f170ce08102 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 @@ -72,6 +74,8 @@ getutxline lio_listio ntptimeval open_wmemstream +posix_dent +posix_getdents posix_spawn_file_actions_addchdir_np posix_spawn_file_actions_addfchdir_np preadv2 From cc648b3b975bc26a1380aeb5e6b6dd2e9766ee7e Mon Sep 17 00:00:00 2001 From: Danny McClanahan <1305167+cosmicexplorer@users.noreply.github.com> Date: Thu, 3 Jul 2025 06:39:25 -0400 Subject: [PATCH 4/6] remove posix_getdents() from musl the musl bundled with rust appears to be from january 2024 --- libc-test/semver/linux-musl.txt | 2 -- src/unix/linux_like/linux/musl/mod.rs | 13 ------------- 2 files changed, 15 deletions(-) diff --git a/libc-test/semver/linux-musl.txt b/libc-test/semver/linux-musl.txt index e6f170ce08102..c806b4f4401b7 100644 --- a/libc-test/semver/linux-musl.txt +++ b/libc-test/semver/linux-musl.txt @@ -74,8 +74,6 @@ getutxline lio_listio ntptimeval open_wmemstream -posix_dent -posix_getdents posix_spawn_file_actions_addchdir_np posix_spawn_file_actions_addfchdir_np preadv2 diff --git a/src/unix/linux_like/linux/musl/mod.rs b/src/unix/linux_like/linux/musl/mod.rs index f90f3a2a411e4..a0838499000b4 100644 --- a/src/unix/linux_like/linux/musl/mod.rs +++ b/src/unix/linux_like/linux/musl/mod.rs @@ -37,17 +37,6 @@ cfg_if! { } } -s_no_extra_traits! { - #[repr(C)] - pub struct posix_dent { - pub d_ino: ino_t, - pub d_off: off_t, - pub d_reclen: c_ushort, - pub d_type: c_uchar, - pub d_name: *mut c_char, - } -} - impl siginfo_t { pub unsafe fn si_addr(&self) -> *mut c_void { #[repr(C)] @@ -983,8 +972,6 @@ extern "C" { } extern "C" { - pub fn posix_getdents(fd: c_int, buf: *mut c_void, len: usize, flags: c_int) -> isize; - pub fn getdents(fd: c_int, buf: *mut crate::dirent, len: usize) -> c_int; } From 87ca6bc1297db81c6c6e06c782b4fa460d9c420d Mon Sep 17 00:00:00 2001 From: Danny McClanahan <1305167+cosmicexplorer@users.noreply.github.com> Date: Sat, 13 Sep 2025 17:27:21 -0400 Subject: [PATCH 5/6] add semver tests for hurd and bsds --- libc-test/semver/dragonfly.txt | 1 + libc-test/semver/freebsd.txt | 1 + libc-test/semver/hurd.txt | 1 + libc-test/semver/netbsd.txt | 1 + libc-test/semver/openbsd.txt | 1 + 5 files changed, 5 insertions(+) create mode 100644 libc-test/semver/hurd.txt diff --git a/libc-test/semver/dragonfly.txt b/libc-test/semver/dragonfly.txt index 31c40372f195c..03fb43c471d47 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 be24fc9fe9efe..593cd023b2587 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 0000000000000..a6f05f8eb4fd6 --- /dev/null +++ b/libc-test/semver/hurd.txt @@ -0,0 +1 @@ +getdents64 diff --git a/libc-test/semver/netbsd.txt b/libc-test/semver/netbsd.txt index 4280ec02de730..dd931dd6d0469 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 6e452dadea797..07b8a70cc9144 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 From ee6b7ee09a4879c624c7b3313785f1f5960166e6 Mon Sep 17 00:00:00 2001 From: Danny McClanahan <1305167+cosmicexplorer@users.noreply.github.com> Date: Sat, 13 Sep 2025 16:56:51 -0400 Subject: [PATCH 6/6] add hurd and bsd implementations --- src/unix/bsd/freebsdlike/dragonfly/mod.rs | 2 ++ src/unix/bsd/freebsdlike/freebsd/mod.rs | 4 ++++ src/unix/bsd/netbsdlike/netbsd/mod.rs | 2 ++ src/unix/bsd/netbsdlike/openbsd/mod.rs | 2 ++ src/unix/hurd/mod.rs | 2 ++ 5 files changed, 12 insertions(+) diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs index fb6b0fca02aeb..0b9f37a90b285 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 88eb12541ff94..e172555430703 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 07532c84dfbaf..9ec22626d17fe 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 df4eb22337810..f6fd0d73495c3 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 bb9bd87915b52..0441d5bb7c1a0 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"]