Rollup merge of #146549 - asomers:freebsd-readdir, r=Mark-Simulacrum

On FreeBSD, use readdir instead of readdir_r

readdir_r has the same problems on FreeBSD as it does on other platforms: it assumes a fixed NAME_MAX.  And readdir has the same thread-safety guarantee as it does on other platforms: it's safe as long as only one thread tries to read from the directory stream at a given time.

Furthermore, readdir_r is likely to be removed for FreeBSD 16, so we should stop using it now.
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
index dfd6ce5..33a1e7f 100644
--- a/library/std/src/sys/fs/unix.rs
+++ b/library/std/src/sys/fs/unix.rs
@@ -21,29 +21,31 @@
 #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))]
 use libc::fstatat64;
 #[cfg(any(
-    target_os = "android",
-    target_os = "solaris",
-    target_os = "fuchsia",
-    target_os = "redox",
-    target_os = "illumos",
     target_os = "aix",
+    target_os = "android",
+    target_os = "freebsd",
+    target_os = "fuchsia",
+    target_os = "illumos",
     target_os = "nto",
+    target_os = "redox",
+    target_os = "solaris",
     target_os = "vita",
     all(target_os = "linux", target_env = "musl"),
 ))]
 use libc::readdir as readdir64;
 #[cfg(not(any(
+    target_os = "aix",
     target_os = "android",
-    target_os = "linux",
-    target_os = "solaris",
+    target_os = "freebsd",
+    target_os = "fuchsia",
+    target_os = "hurd",
     target_os = "illumos",
     target_os = "l4re",
-    target_os = "fuchsia",
-    target_os = "redox",
-    target_os = "aix",
+    target_os = "linux",
     target_os = "nto",
+    target_os = "redox",
+    target_os = "solaris",
     target_os = "vita",
-    target_os = "hurd",
 )))]
 use libc::readdir_r as readdir64_r;
 #[cfg(any(all(target_os = "linux", not(target_env = "musl")), target_os = "hurd"))]
@@ -271,16 +273,17 @@ unsafe impl Send for Dir {}
 unsafe impl Sync for Dir {}
 
 #[cfg(any(
-    target_os = "android",
-    target_os = "linux",
-    target_os = "solaris",
-    target_os = "illumos",
-    target_os = "fuchsia",
-    target_os = "redox",
     target_os = "aix",
-    target_os = "nto",
-    target_os = "vita",
+    target_os = "android",
+    target_os = "freebsd",
+    target_os = "fuchsia",
     target_os = "hurd",
+    target_os = "illumos",
+    target_os = "linux",
+    target_os = "nto",
+    target_os = "redox",
+    target_os = "solaris",
+    target_os = "vita",
 ))]
 pub struct DirEntry {
     dir: Arc<InnerReadDir>,
@@ -295,16 +298,17 @@ pub struct DirEntry {
 // we're not using the immediate `d_name` on these targets. Keeping this as an
 // `entry` field in `DirEntry` helps reduce the `cfg` boilerplate elsewhere.
 #[cfg(any(
-    target_os = "android",
-    target_os = "linux",
-    target_os = "solaris",
-    target_os = "illumos",
-    target_os = "fuchsia",
-    target_os = "redox",
     target_os = "aix",
-    target_os = "nto",
-    target_os = "vita",
+    target_os = "android",
+    target_os = "freebsd",
+    target_os = "fuchsia",
     target_os = "hurd",
+    target_os = "illumos",
+    target_os = "linux",
+    target_os = "nto",
+    target_os = "redox",
+    target_os = "solaris",
+    target_os = "vita",
 ))]
 struct dirent64_min {
     d_ino: u64,
@@ -319,16 +323,17 @@ struct dirent64_min {
 }
 
 #[cfg(not(any(
-    target_os = "android",
-    target_os = "linux",
-    target_os = "solaris",
-    target_os = "illumos",
-    target_os = "fuchsia",
-    target_os = "redox",
     target_os = "aix",
-    target_os = "nto",
-    target_os = "vita",
+    target_os = "android",
+    target_os = "freebsd",
+    target_os = "fuchsia",
     target_os = "hurd",
+    target_os = "illumos",
+    target_os = "linux",
+    target_os = "nto",
+    target_os = "redox",
+    target_os = "solaris",
+    target_os = "vita",
 )))]
 pub struct DirEntry {
     dir: Arc<InnerReadDir>,
@@ -698,16 +703,17 @@ impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
 
     #[cfg(any(
-        target_os = "android",
-        target_os = "linux",
-        target_os = "solaris",
-        target_os = "fuchsia",
-        target_os = "redox",
-        target_os = "illumos",
         target_os = "aix",
-        target_os = "nto",
-        target_os = "vita",
+        target_os = "android",
+        target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "hurd",
+        target_os = "illumos",
+        target_os = "linux",
+        target_os = "nto",
+        target_os = "redox",
+        target_os = "solaris",
+        target_os = "vita",
     ))]
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         use crate::sys::os::{errno, set_errno};
@@ -768,6 +774,9 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
                 // only access those bytes.
                 #[cfg(not(target_os = "vita"))]
                 let entry = dirent64_min {
+                    #[cfg(target_os = "freebsd")]
+                    d_ino: (*entry_ptr).d_fileno,
+                    #[cfg(not(target_os = "freebsd"))]
                     d_ino: (*entry_ptr).d_ino as u64,
                     #[cfg(not(any(
                         target_os = "solaris",
@@ -791,16 +800,17 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
     }
 
     #[cfg(not(any(
-        target_os = "android",
-        target_os = "linux",
-        target_os = "solaris",
-        target_os = "fuchsia",
-        target_os = "redox",
-        target_os = "illumos",
         target_os = "aix",
-        target_os = "nto",
-        target_os = "vita",
+        target_os = "android",
+        target_os = "freebsd",
+        target_os = "fuchsia",
         target_os = "hurd",
+        target_os = "illumos",
+        target_os = "linux",
+        target_os = "nto",
+        target_os = "redox",
+        target_os = "solaris",
+        target_os = "vita",
     )))]
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         if self.end_of_stream {
@@ -970,36 +980,32 @@ pub fn file_type(&self) -> io::Result<FileType> {
     }
 
     #[cfg(any(
-        target_os = "linux",
+        target_os = "aix",
+        target_os = "android",
         target_os = "cygwin",
         target_os = "emscripten",
-        target_os = "android",
-        target_os = "solaris",
-        target_os = "illumos",
-        target_os = "haiku",
-        target_os = "l4re",
-        target_os = "fuchsia",
-        target_os = "redox",
-        target_os = "vxworks",
         target_os = "espidf",
+        target_os = "freebsd",
+        target_os = "fuchsia",
+        target_os = "haiku",
         target_os = "horizon",
-        target_os = "vita",
-        target_os = "aix",
-        target_os = "nto",
         target_os = "hurd",
+        target_os = "illumos",
+        target_os = "l4re",
+        target_os = "linux",
+        target_os = "nto",
+        target_os = "redox",
         target_os = "rtems",
+        target_os = "solaris",
+        target_os = "vita",
+        target_os = "vxworks",
         target_vendor = "apple",
     ))]
     pub fn ino(&self) -> u64 {
         self.entry.d_ino as u64
     }
 
-    #[cfg(any(
-        target_os = "freebsd",
-        target_os = "openbsd",
-        target_os = "netbsd",
-        target_os = "dragonfly"
-    ))]
+    #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "dragonfly"))]
     pub fn ino(&self) -> u64 {
         self.entry.d_fileno as u64
     }
@@ -1014,7 +1020,6 @@ pub fn ino(&self) -> u64 {
     #[cfg(any(
         target_os = "netbsd",
         target_os = "openbsd",
-        target_os = "freebsd",
         target_os = "dragonfly",
         target_vendor = "apple",
     ))]
@@ -1030,7 +1035,6 @@ fn name_bytes(&self) -> &[u8] {
     #[cfg(not(any(
         target_os = "netbsd",
         target_os = "openbsd",
-        target_os = "freebsd",
         target_os = "dragonfly",
         target_vendor = "apple",
     )))]
@@ -1040,6 +1044,7 @@ fn name_bytes(&self) -> &[u8] {
 
     #[cfg(not(any(
         target_os = "android",
+        target_os = "freebsd",
         target_os = "linux",
         target_os = "solaris",
         target_os = "illumos",
@@ -1055,6 +1060,7 @@ fn name_cstr(&self) -> &CStr {
     }
     #[cfg(any(
         target_os = "android",
+        target_os = "freebsd",
         target_os = "linux",
         target_os = "solaris",
         target_os = "illumos",