From b2d1051e938f8de6203f6f147507e984de5be2fb Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andrew.caldwell@metaswitch.com>
Date: Fri, 30 Sep 2022 23:54:47 +0100
Subject: [PATCH 01/14] Alias all LFS64 symbols to their non-LFS64 counterparts
 on musl

---
 src/unix/linux_like/linux/mod.rs      | 10 +++++++++
 src/unix/linux_like/linux/musl/mod.rs | 29 +++++++++++++++++++++++++++
 src/unix/linux_like/mod.rs            | 18 +++++++++++++++++
 3 files changed, 57 insertions(+)

diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs
index a9829011135fd..d2bf78b80bd16 100644
--- a/src/unix/linux_like/linux/mod.rs
+++ b/src/unix/linux_like/linux/mod.rs
@@ -4269,20 +4269,29 @@ extern "C" {
     pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int;
     pub fn __errno_location() -> *mut ::c_int;
 
+    #[cfg(not(target_env = "musl"))]
     pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE;
+    #[cfg(not(target_env = "musl"))]
     pub fn freopen64(
         filename: *const c_char,
         mode: *const c_char,
         file: *mut ::FILE,
     ) -> *mut ::FILE;
+    #[cfg(not(target_env = "musl"))]
     pub fn tmpfile64() -> *mut ::FILE;
+    #[cfg(not(target_env = "musl"))]
     pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn fseeko64(stream: *mut ::FILE, offset: ::off64_t, whence: ::c_int) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn ftello64(stream: *mut ::FILE) -> ::off64_t;
     pub fn fallocate(fd: ::c_int, mode: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn fallocate64(fd: ::c_int, mode: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int;
     pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int;
     pub fn readahead(fd: ::c_int, offset: ::off64_t, count: ::size_t) -> ::ssize_t;
     pub fn getxattr(
@@ -4584,6 +4593,7 @@ extern "C" {
         offset: *mut off_t,
         count: ::size_t,
     ) -> ::ssize_t;
+    #[cfg(not(target_env = "musl"))]
     pub fn sendfile64(
         out_fd: ::c_int,
         in_fd: ::c_int,
diff --git a/src/unix/linux_like/linux/musl/mod.rs b/src/unix/linux_like/linux/musl/mod.rs
index 37a8ca2aff2fe..5462711304eff 100644
--- a/src/unix/linux_like/linux/musl/mod.rs
+++ b/src/unix/linux_like/linux/musl/mod.rs
@@ -784,6 +784,35 @@ extern "C" {
     pub fn basename(path: *mut ::c_char) -> *mut ::c_char;
 }
 
+pub use tmpfile as tmpfile64;
+pub use fallocate as fallocate64;
+pub use fgetpos as fgetpos64;
+pub use fopen as fopen64;
+pub use freopen as freopen64;
+pub use fseeko as fseeko64;
+pub use fsetpos as fsetpos64;
+pub use ftello as ftello64;
+pub use posix_fallocate as posix_fallocate64;
+pub use sendfile as sendfile64;
+pub use statfs as statfs64;
+pub use fstatfs as fstatfs64;
+pub use statvfs as statvfs64;
+pub use fstatvfs as fstatvfs64;
+pub use creat as creat64;
+pub use fstat as fstat64;
+pub use fstatat as fstatat64;
+pub use ftruncate as ftruncate64;
+pub use lseek as lseek64;
+pub use lstat as lstat64;
+pub use open as open64;
+pub use openat as openat64;
+pub use pread as pread64;
+pub use pwrite as pwrite64;
+pub use readdir as readdir64;
+pub use readdir_r as readdir64_r;
+pub use stat as stat64;
+pub use truncate as truncate64;
+
 cfg_if! {
     if #[cfg(any(target_arch = "x86_64",
                  target_arch = "aarch64",
diff --git a/src/unix/linux_like/mod.rs b/src/unix/linux_like/mod.rs
index db57745967f79..0c1ac1c9bb203 100644
--- a/src/unix/linux_like/mod.rs
+++ b/src/unix/linux_like/mod.rs
@@ -1673,10 +1673,14 @@ extern "C" {
     pub fn setgroups(ngroups: ::size_t, ptr: *const ::gid_t) -> ::c_int;
     pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int;
     pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn statfs64(path: *const ::c_char, buf: *mut statfs64) -> ::c_int;
     pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn fstatfs64(fd: ::c_int, buf: *mut statfs64) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn statvfs64(path: *const ::c_char, buf: *mut statvfs64) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn fstatvfs64(fd: ::c_int, buf: *mut statvfs64) -> ::c_int;
     pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void;
 
@@ -1698,16 +1702,22 @@ extern "C" {
     pub fn freelocale(loc: ::locale_t);
     pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t;
     pub fn uselocale(loc: ::locale_t) -> ::locale_t;
+    #[cfg(not(target_env = "musl"))]
     pub fn creat64(path: *const c_char, mode: mode_t) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn fstat64(fildes: ::c_int, buf: *mut stat64) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn fstatat64(
         dirfd: ::c_int,
         pathname: *const c_char,
         buf: *mut stat64,
         flags: ::c_int,
     ) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn ftruncate64(fd: ::c_int, length: off64_t) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn lseek64(fd: ::c_int, offset: off64_t, whence: ::c_int) -> off64_t;
+    #[cfg(not(target_env = "musl"))]
     pub fn lstat64(path: *const c_char, buf: *mut stat64) -> ::c_int;
     pub fn mmap64(
         addr: *mut ::c_void,
@@ -1717,22 +1727,30 @@ extern "C" {
         fd: ::c_int,
         offset: off64_t,
     ) -> *mut ::c_void;
+    #[cfg(not(target_env = "musl"))]
     pub fn open64(path: *const c_char, oflag: ::c_int, ...) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn openat64(fd: ::c_int, path: *const c_char, oflag: ::c_int, ...) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn pread64(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off64_t) -> ::ssize_t;
+    #[cfg(not(target_env = "musl"))]
     pub fn pwrite64(
         fd: ::c_int,
         buf: *const ::c_void,
         count: ::size_t,
         offset: off64_t,
     ) -> ::ssize_t;
+    #[cfg(not(target_env = "musl"))]
     pub fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64;
+    #[cfg(not(target_env = "musl"))]
     pub fn readdir64_r(
         dirp: *mut ::DIR,
         entry: *mut ::dirent64,
         result: *mut *mut ::dirent64,
     ) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn stat64(path: *const c_char, buf: *mut stat64) -> ::c_int;
+    #[cfg(not(target_env = "musl"))]
     pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int;
 
     pub fn mknodat(

From b95fbeeef0743a63b9438e498dbd8712afa56123 Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andrew.caldwell@metaswitch.com>
Date: Mon, 3 Oct 2022 00:11:00 +0100
Subject: [PATCH 02/14] Move musl-exclusions to cfg_if blocks and alias types
 on Musl too

---
 libc-test/build.rs                    |   5 +-
 src/unix/linux_like/linux/mod.rs      | 112 ++++++++++++----------
 src/unix/linux_like/linux/musl/mod.rs |  67 +++++++++----
 src/unix/linux_like/mod.rs            | 132 +++++++++++++-------------
 4 files changed, 180 insertions(+), 136 deletions(-)

diff --git a/libc-test/build.rs b/libc-test/build.rs
index ac0f996fc4e92..ba4e6c23d7736 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -3319,8 +3319,11 @@ fn test_linux(target: &str) {
 
             t if t.ends_with("_t") => t.to_string(),
 
-            // In MUSL `flock64` is a typedef to `flock`.
+            // In MUSL `xxx64` is a typedef to `xxx`.
             "flock64" if musl => format!("struct {}", ty),
+            "dirent64" if musl => format!("struct {}", ty),
+            "rlimit64" if musl => format!("struct {}", ty),
+            "fpos64_t" if musl => format!("struct {}", ty),
 
             // put `struct` in front of all structs:.
             t if is_struct => format!("struct {}", t),
diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs
index d2bf78b80bd16..4d8a8cda809a6 100644
--- a/src/unix/linux_like/linux/mod.rs
+++ b/src/unix/linux_like/linux/mod.rs
@@ -51,21 +51,20 @@ pub type iconv_t = *mut ::c_void;
 // linux/sctp.h
 pub type sctp_assoc_t = ::__s32;
 
-#[cfg_attr(feature = "extra_traits", derive(Debug))]
-pub enum fpos64_t {} // FIXME: fill this out with a struct
-impl ::Copy for fpos64_t {}
-impl ::Clone for fpos64_t {
-    fn clone(&self) -> fpos64_t {
-        *self
+cfg_if! {
+    if #[cfg(not(target_env = "musl"))] {
+        #[cfg_attr(feature = "extra_traits", derive(Debug))]
+        pub enum fpos64_t {} // FIXME: fill this out with a struct
+        impl ::Copy for fpos64_t {}
+        impl ::Clone for fpos64_t {
+            fn clone(&self) -> fpos64_t {
+                *self
+            }
+        }
     }
 }
 
 s! {
-    pub struct rlimit64 {
-        pub rlim_cur: rlim64_t,
-        pub rlim_max: rlim64_t,
-    }
-
     pub struct glob_t {
         pub gl_pathc: ::size_t,
         pub gl_pathv: *mut *mut c_char,
@@ -687,6 +686,17 @@ s! {
     }
 }
 
+cfg_if! {
+    if #[cfg(not(target_env = "musl"))] {
+        s! {
+            pub struct rlimit64 {
+                pub rlim_cur: rlim64_t,
+                pub rlim_max: rlim64_t,
+            }
+        }
+    }
+}
+
 s_no_extra_traits! {
     pub struct sockaddr_nl {
         pub nl_family: ::sa_family_t,
@@ -703,14 +713,6 @@ s_no_extra_traits! {
         pub d_name: [::c_char; 256],
     }
 
-    pub struct dirent64 {
-        pub d_ino: ::ino64_t,
-        pub d_off: ::off64_t,
-        pub d_reclen: ::c_ushort,
-        pub d_type: ::c_uchar,
-        pub d_name: [::c_char; 256],
-    }
-
     pub struct sockaddr_alg {
         pub salg_family: ::sa_family_t,
         pub salg_type: [::c_uchar; 14],
@@ -806,6 +808,20 @@ s_no_extra_traits! {
     }
 }
 
+cfg_if! {
+    if #[cfg(not(target_env = "musl"))] {
+        s_no_extra_traits! {
+            pub struct dirent64 {
+                pub d_ino: ::ino64_t,
+                pub d_off: ::off64_t,
+                pub d_reclen: ::c_ushort,
+                pub d_type: ::c_uchar,
+                pub d_name: [::c_char; 256],
+            }
+        }
+    }
+}
+
 s_no_extra_traits! {
     // linux/net_tstamp.h
     #[allow(missing_debug_implementations)]
@@ -4269,30 +4285,8 @@ extern "C" {
     pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int;
     pub fn __errno_location() -> *mut ::c_int;
 
-    #[cfg(not(target_env = "musl"))]
-    pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE;
-    #[cfg(not(target_env = "musl"))]
-    pub fn freopen64(
-        filename: *const c_char,
-        mode: *const c_char,
-        file: *mut ::FILE,
-    ) -> *mut ::FILE;
-    #[cfg(not(target_env = "musl"))]
-    pub fn tmpfile64() -> *mut ::FILE;
-    #[cfg(not(target_env = "musl"))]
-    pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn fseeko64(stream: *mut ::FILE, offset: ::off64_t, whence: ::c_int) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn ftello64(stream: *mut ::FILE) -> ::off64_t;
     pub fn fallocate(fd: ::c_int, mode: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn fallocate64(fd: ::c_int, mode: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int;
     pub fn posix_fallocate(fd: ::c_int, offset: ::off_t, len: ::off_t) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int;
     pub fn readahead(fd: ::c_int, offset: ::off64_t, count: ::size_t) -> ::ssize_t;
     pub fn getxattr(
         path: *const c_char,
@@ -4593,13 +4587,6 @@ extern "C" {
         offset: *mut off_t,
         count: ::size_t,
     ) -> ::ssize_t;
-    #[cfg(not(target_env = "musl"))]
-    pub fn sendfile64(
-        out_fd: ::c_int,
-        in_fd: ::c_int,
-        offset: *mut off64_t,
-        count: ::size_t,
-    ) -> ::ssize_t;
     pub fn sigsuspend(mask: *const ::sigset_t) -> ::c_int;
     pub fn getgrgid_r(
         gid: ::gid_t,
@@ -4851,6 +4838,35 @@ extern "C" {
     ) -> ::ssize_t;
 }
 
+// LFS64 extensions
+//
+// * musl has 64-bit versions only so aliases the LFS64 symbols to the standard ones
+cfg_if! {
+    if #[cfg(not(target_env = "musl"))] {
+        extern "C" {
+            pub fn fallocate64(fd: ::c_int, mode: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int;
+            pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int;
+            pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE;
+            pub fn freopen64(
+                filename: *const c_char,
+                mode: *const c_char,
+                file: *mut ::FILE,
+            ) -> *mut ::FILE;
+            pub fn fseeko64(stream: *mut ::FILE, offset: ::off64_t, whence: ::c_int) -> ::c_int;
+            pub fn fsetpos64(stream: *mut ::FILE, ptr: *const fpos64_t) -> ::c_int;
+            pub fn ftello64(stream: *mut ::FILE) -> ::off64_t;
+            pub fn posix_fallocate64(fd: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int;
+            pub fn sendfile64(
+                out_fd: ::c_int,
+                in_fd: ::c_int,
+                offset: *mut off64_t,
+                count: ::size_t,
+            ) -> ::ssize_t;
+            pub fn tmpfile64() -> *mut ::FILE;
+        }
+    }
+}
+
 cfg_if! {
     if #[cfg(target_env = "uclibc")] {
         mod uclibc;
diff --git a/src/unix/linux_like/linux/musl/mod.rs b/src/unix/linux_like/linux/musl/mod.rs
index 5462711304eff..5341e0b683070 100644
--- a/src/unix/linux_like/linux/musl/mod.rs
+++ b/src/unix/linux_like/linux/musl/mod.rs
@@ -22,8 +22,6 @@ pub type fsblkcnt_t = ::c_ulonglong;
 pub type fsfilcnt_t = ::c_ulonglong;
 pub type rlim_t = ::c_ulonglong;
 
-pub type flock64 = flock;
-
 cfg_if! {
     if #[cfg(doc)] {
         // Used in `linux::arch` to define ioctl constants.
@@ -719,8 +717,6 @@ extern "C" {
         timeout: *mut ::timespec,
     ) -> ::c_int;
 
-    pub fn getrlimit64(resource: ::c_int, rlim: *mut ::rlimit64) -> ::c_int;
-    pub fn setrlimit64(resource: ::c_int, rlim: *const ::rlimit64) -> ::c_int;
     pub fn getrlimit(resource: ::c_int, rlim: *mut ::rlimit) -> ::c_int;
     pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int;
     pub fn prlimit(
@@ -729,13 +725,6 @@ extern "C" {
         new_limit: *const ::rlimit,
         old_limit: *mut ::rlimit,
     ) -> ::c_int;
-    pub fn prlimit64(
-        pid: ::pid_t,
-        resource: ::c_int,
-        new_limit: *const ::rlimit64,
-        old_limit: *mut ::rlimit64,
-    ) -> ::c_int;
-
     pub fn ioctl(fd: ::c_int, request: ::c_int, ...) -> ::c_int;
     pub fn gettimeofday(tp: *mut ::timeval, tz: *mut ::c_void) -> ::c_int;
     pub fn ptrace(request: ::c_int, ...) -> ::c_long;
@@ -784,33 +773,71 @@ extern "C" {
     pub fn basename(path: *mut ::c_char) -> *mut ::c_char;
 }
 
-pub use tmpfile as tmpfile64;
+// Musl's standard entrypoints are already LFS64 compatible, historically the library aliased
+// these together in header files (as `#define`s) _and_ in the library with weak symbol aliases.
+//
+// Since <version> these aliases were removed from the library (both in the API and the ABI) so we
+// alias them here to keep the crate API stable.
+#[allow(dead_code)]
+fn check_type_aliases(
+    dirent: ::dirent,
+    ino: ::ino_t,
+    flock: ::flock,
+    off: ::off_t,
+    pos: ::fpos_t,
+    rlimit: ::rlimit,
+    stat: ::stat,
+    statfs: ::statfs,
+    statvfs: ::statvfs,
+) {
+    let _dirent: ::dirent64 = dirent;
+    let _ino: ::ino64_t = ino;
+    let _flock: ::flock64 = flock;
+    let _off: ::off64_t = off;
+    let _pos: ::fpos64_t = pos;
+    let _rlimit: ::rlimit64 = rlimit;
+    let _stat: ::stat64 = stat;
+    let _statfs: ::statfs64 = statfs;
+    let _statvfs: ::statvfs64 = statvfs;
+}
+pub type dirent64 = ::dirent;
+pub type fpos64_t = ::fpos_t;
+pub type rlimit64 = ::rlimit;
+pub type flock64 = ::flock;
+pub use creat as creat64;
 pub use fallocate as fallocate64;
 pub use fgetpos as fgetpos64;
 pub use fopen as fopen64;
 pub use freopen as freopen64;
 pub use fseeko as fseeko64;
 pub use fsetpos as fsetpos64;
-pub use ftello as ftello64;
-pub use posix_fallocate as posix_fallocate64;
-pub use sendfile as sendfile64;
-pub use statfs as statfs64;
-pub use fstatfs as fstatfs64;
-pub use statvfs as statvfs64;
-pub use fstatvfs as fstatvfs64;
-pub use creat as creat64;
 pub use fstat as fstat64;
 pub use fstatat as fstatat64;
+pub use fstatfs as fstatfs64;
+pub use fstatvfs as fstatvfs64;
+pub use ftello as ftello64;
 pub use ftruncate as ftruncate64;
+pub use getrlimit as getrlimit64;
 pub use lseek as lseek64;
 pub use lstat as lstat64;
+pub use mmap as mmap64;
 pub use open as open64;
 pub use openat as openat64;
+pub use posix_fadvise as posix_fadvise64;
+pub use posix_fallocate as posix_fallocate64;
 pub use pread as pread64;
+pub use preadv as preadv64;
+pub use prlimit as prlimit64;
 pub use pwrite as pwrite64;
+pub use pwritev as pwritev64;
 pub use readdir as readdir64;
 pub use readdir_r as readdir64_r;
+pub use sendfile as sendfile64;
+pub use setrlimit as setrlimit64;
 pub use stat as stat64;
+pub use statfs as statfs64;
+pub use statvfs as statvfs64;
+pub use tmpfile as tmpfile64;
 pub use truncate as truncate64;
 
 cfg_if! {
diff --git a/src/unix/linux_like/mod.rs b/src/unix/linux_like/mod.rs
index 0c1ac1c9bb203..1d514bdccb3db 100644
--- a/src/unix/linux_like/mod.rs
+++ b/src/unix/linux_like/mod.rs
@@ -1673,24 +1673,9 @@ extern "C" {
     pub fn setgroups(ngroups: ::size_t, ptr: *const ::gid_t) -> ::c_int;
     pub fn pipe2(fds: *mut ::c_int, flags: ::c_int) -> ::c_int;
     pub fn statfs(path: *const ::c_char, buf: *mut statfs) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn statfs64(path: *const ::c_char, buf: *mut statfs64) -> ::c_int;
     pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn fstatfs64(fd: ::c_int, buf: *mut statfs64) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn statvfs64(path: *const ::c_char, buf: *mut statvfs64) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn fstatvfs64(fd: ::c_int, buf: *mut statvfs64) -> ::c_int;
     pub fn memrchr(cx: *const ::c_void, c: ::c_int, n: ::size_t) -> *mut ::c_void;
-
     pub fn posix_fadvise(fd: ::c_int, offset: ::off_t, len: ::off_t, advise: ::c_int) -> ::c_int;
-    pub fn posix_fadvise64(
-        fd: ::c_int,
-        offset: ::off64_t,
-        len: ::off64_t,
-        advise: ::c_int,
-    ) -> ::c_int;
     pub fn futimens(fd: ::c_int, times: *const ::timespec) -> ::c_int;
     pub fn utimensat(
         dirfd: ::c_int,
@@ -1702,57 +1687,6 @@ extern "C" {
     pub fn freelocale(loc: ::locale_t);
     pub fn newlocale(mask: ::c_int, locale: *const ::c_char, base: ::locale_t) -> ::locale_t;
     pub fn uselocale(loc: ::locale_t) -> ::locale_t;
-    #[cfg(not(target_env = "musl"))]
-    pub fn creat64(path: *const c_char, mode: mode_t) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn fstat64(fildes: ::c_int, buf: *mut stat64) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn fstatat64(
-        dirfd: ::c_int,
-        pathname: *const c_char,
-        buf: *mut stat64,
-        flags: ::c_int,
-    ) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn ftruncate64(fd: ::c_int, length: off64_t) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn lseek64(fd: ::c_int, offset: off64_t, whence: ::c_int) -> off64_t;
-    #[cfg(not(target_env = "musl"))]
-    pub fn lstat64(path: *const c_char, buf: *mut stat64) -> ::c_int;
-    pub fn mmap64(
-        addr: *mut ::c_void,
-        len: ::size_t,
-        prot: ::c_int,
-        flags: ::c_int,
-        fd: ::c_int,
-        offset: off64_t,
-    ) -> *mut ::c_void;
-    #[cfg(not(target_env = "musl"))]
-    pub fn open64(path: *const c_char, oflag: ::c_int, ...) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn openat64(fd: ::c_int, path: *const c_char, oflag: ::c_int, ...) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn pread64(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off64_t) -> ::ssize_t;
-    #[cfg(not(target_env = "musl"))]
-    pub fn pwrite64(
-        fd: ::c_int,
-        buf: *const ::c_void,
-        count: ::size_t,
-        offset: off64_t,
-    ) -> ::ssize_t;
-    #[cfg(not(target_env = "musl"))]
-    pub fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64;
-    #[cfg(not(target_env = "musl"))]
-    pub fn readdir64_r(
-        dirp: *mut ::DIR,
-        entry: *mut ::dirent64,
-        result: *mut *mut ::dirent64,
-    ) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn stat64(path: *const c_char, buf: *mut stat64) -> ::c_int;
-    #[cfg(not(target_env = "musl"))]
-    pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int;
-
     pub fn mknodat(
         dirfd: ::c_int,
         pathname: *const ::c_char,
@@ -1824,8 +1758,65 @@ extern "C" {
     pub fn strchrnul(s: *const ::c_char, c: ::c_int) -> *mut ::c_char;
 }
 
+// LFS64 extensions
+//
+// * musl has 64-bit versions only so aliases the LFS64 symbols to the standard ones
+// * ulibc doesn't have preadv64/pwritev64 (TODO: Or does it?!)
 cfg_if! {
-    if #[cfg(not(target_env = "uclibc"))] {
+    if #[cfg(not(target_env = "musl"))] {
+        extern "C" {
+            pub fn fstatfs64(fd: ::c_int, buf: *mut statfs64) -> ::c_int;
+            pub fn statvfs64(path: *const ::c_char, buf: *mut statvfs64) -> ::c_int;
+            pub fn fstatvfs64(fd: ::c_int, buf: *mut statvfs64) -> ::c_int;
+            pub fn statfs64(path: *const ::c_char, buf: *mut statfs64) -> ::c_int;
+            pub fn creat64(path: *const c_char, mode: mode_t) -> ::c_int;
+            pub fn fstat64(fildes: ::c_int, buf: *mut stat64) -> ::c_int;
+            pub fn fstatat64(
+                dirfd: ::c_int,
+                pathname: *const c_char,
+                buf: *mut stat64,
+                flags: ::c_int,
+            ) -> ::c_int;
+            pub fn ftruncate64(fd: ::c_int, length: off64_t) -> ::c_int;
+            pub fn lseek64(fd: ::c_int, offset: off64_t, whence: ::c_int) -> off64_t;
+            pub fn lstat64(path: *const c_char, buf: *mut stat64) -> ::c_int;
+            pub fn mmap64(
+                addr: *mut ::c_void,
+                len: ::size_t,
+                prot: ::c_int,
+                flags: ::c_int,
+                fd: ::c_int,
+                offset: off64_t,
+            ) -> *mut ::c_void;
+            pub fn open64(path: *const c_char, oflag: ::c_int, ...) -> ::c_int;
+            pub fn openat64(fd: ::c_int, path: *const c_char, oflag: ::c_int, ...) -> ::c_int;
+            pub fn posix_fadvise64(
+                fd: ::c_int,
+                offset: ::off64_t,
+                len: ::off64_t,
+                advise: ::c_int,
+            ) -> ::c_int;
+            pub fn pread64(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off64_t) -> ::ssize_t;
+            pub fn pwrite64(
+                fd: ::c_int,
+                buf: *const ::c_void,
+                count: ::size_t,
+                offset: off64_t,
+            ) -> ::ssize_t;
+            pub fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64;
+            pub fn readdir64_r(
+                dirp: *mut ::DIR,
+                entry: *mut ::dirent64,
+                result: *mut *mut ::dirent64,
+            ) -> ::c_int;
+            pub fn stat64(path: *const c_char, buf: *mut stat64) -> ::c_int;
+            pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int;
+        }
+    }
+}
+
+cfg_if! {
+    if #[cfg(not(any(target_env = "ulibc", target_env = "musl")))] {
         extern "C" {
             pub fn preadv64(
                 fd: ::c_int,
@@ -1839,6 +1830,13 @@ cfg_if! {
                 iovcnt: ::c_int,
                 offset: ::off64_t,
             ) -> ::ssize_t;
+        }
+    }
+}
+
+cfg_if! {
+    if #[cfg(not(target_env = "uclibc"))] {
+        extern "C" {
             // uclibc has separate non-const version of this function
             pub fn forkpty(
                 amaster: *mut ::c_int,

From cd78c714bde3f97220d6a733774e2b752eb69602 Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Thu, 13 Apr 2023 19:02:14 +0100
Subject: [PATCH 03/14] Fix up duplicate derives with extra_traits

---
 src/unix/linux_like/linux/mod.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs
index 4d8a8cda809a6..35993956fa0b1 100644
--- a/src/unix/linux_like/linux/mod.rs
+++ b/src/unix/linux_like/linux/mod.rs
@@ -916,6 +916,7 @@ cfg_if! {
             }
         }
 
+        #[cfg(not(target_env = "musl"))]
         impl PartialEq for dirent64 {
             fn eq(&self, other: &dirent64) -> bool {
                 self.d_ino == other.d_ino
@@ -930,8 +931,10 @@ cfg_if! {
             }
         }
 
+        #[cfg(not(target_env = "musl"))]
         impl Eq for dirent64 {}
 
+        #[cfg(not(target_env = "musl"))]
         impl ::fmt::Debug for dirent64 {
             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
                 f.debug_struct("dirent64")
@@ -944,6 +947,7 @@ cfg_if! {
             }
         }
 
+        #[cfg(not(target_env = "musl"))]
         impl ::hash::Hash for dirent64 {
             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
                 self.d_ino.hash(state);

From 57195640c76bc83bfeac7d450eb969931d53e68a Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Wed, 10 May 2023 18:49:02 +0100
Subject: [PATCH 04/14] Tidy up build.rs now that all xxx64 are absent for the
 musl target

---
 libc-test/build.rs | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/libc-test/build.rs b/libc-test/build.rs
index ba4e6c23d7736..93cb37cb3b0b2 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -3315,16 +3315,10 @@ fn test_linux(target: &str) {
             "Ioctl" if gnu => "unsigned long".to_string(),
             "Ioctl" => "int".to_string(),
 
-            t if is_union => format!("union {}", t),
-
+            // `_t` is already a typedef, no need for a keyword
             t if t.ends_with("_t") => t.to_string(),
-
-            // In MUSL `xxx64` is a typedef to `xxx`.
-            "flock64" if musl => format!("struct {}", ty),
-            "dirent64" if musl => format!("struct {}", ty),
-            "rlimit64" if musl => format!("struct {}", ty),
-            "fpos64_t" if musl => format!("struct {}", ty),
-
+            // put `union` in front of all unions:
+            t if is_union => format!("union {}", t),
             // put `struct` in front of all structs:.
             t if is_struct => format!("struct {}", t),
 
@@ -3383,7 +3377,11 @@ fn test_linux(target: &str) {
             "priority_t" if musl => true,
             "name_t" if musl => true,
 
-            _ => false,
+            t => if musl {
+                t.ends_with("64") || t.ends_with("64_t")
+            } else {
+                false
+            }
         }
     });
 

From eea022dd8b7f67b66f49ccf98e250c496ee3d47b Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Fri, 26 May 2023 22:43:40 +0100
Subject: [PATCH 05/14] Provide shim functions to backfill LFS64 ABI

---
 src/unix/linux_like/linux/mod.rs              |  46 ++--
 .../linux_like/linux/musl/b32/riscv32/mod.rs  |  16 --
 .../linux_like/linux/musl/b64/riscv64/mod.rs  |  16 --
 src/unix/linux_like/linux/musl/lfs64.rs       | 251 ++++++++++++++++++
 src/unix/linux_like/linux/musl/mod.rs         |  77 +-----
 5 files changed, 277 insertions(+), 129 deletions(-)
 create mode 100644 src/unix/linux_like/linux/musl/lfs64.rs

diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs
index 35993956fa0b1..c056cd1fcca1e 100644
--- a/src/unix/linux_like/linux/mod.rs
+++ b/src/unix/linux_like/linux/mod.rs
@@ -51,16 +51,12 @@ pub type iconv_t = *mut ::c_void;
 // linux/sctp.h
 pub type sctp_assoc_t = ::__s32;
 
-cfg_if! {
-    if #[cfg(not(target_env = "musl"))] {
-        #[cfg_attr(feature = "extra_traits", derive(Debug))]
-        pub enum fpos64_t {} // FIXME: fill this out with a struct
-        impl ::Copy for fpos64_t {}
-        impl ::Clone for fpos64_t {
-            fn clone(&self) -> fpos64_t {
-                *self
-            }
-        }
+#[cfg_attr(feature = "extra_traits", derive(Debug))]
+pub enum fpos64_t {} // FIXME: fill this out with a struct
+impl ::Copy for fpos64_t {}
+impl ::Clone for fpos64_t {
+    fn clone(&self) -> fpos64_t {
+        *self
     }
 }
 
@@ -684,16 +680,10 @@ s! {
     pub struct sctp_authinfo {
         pub auth_keynumber: ::__u16,
     }
-}
 
-cfg_if! {
-    if #[cfg(not(target_env = "musl"))] {
-        s! {
-            pub struct rlimit64 {
-                pub rlim_cur: rlim64_t,
-                pub rlim_max: rlim64_t,
-            }
-        }
+    pub struct rlimit64 {
+        pub rlim_cur: rlim64_t,
+        pub rlim_max: rlim64_t,
     }
 }
 
@@ -806,19 +796,13 @@ s_no_extra_traits! {
         pub tx_type: ::c_int,
         pub rx_filter: ::c_int,
     }
-}
 
-cfg_if! {
-    if #[cfg(not(target_env = "musl"))] {
-        s_no_extra_traits! {
-            pub struct dirent64 {
-                pub d_ino: ::ino64_t,
-                pub d_off: ::off64_t,
-                pub d_reclen: ::c_ushort,
-                pub d_type: ::c_uchar,
-                pub d_name: [::c_char; 256],
-            }
-        }
+    pub struct dirent64 {
+        pub d_ino: ::ino64_t,
+        pub d_off: ::off64_t,
+        pub d_reclen: ::c_ushort,
+        pub d_type: ::c_uchar,
+        pub d_name: [::c_char; 256],
     }
 }
 
diff --git a/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs b/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs
index 9ce6a9fd3cb0f..bf7a4f59c7945 100644
--- a/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs
+++ b/src/unix/linux_like/linux/musl/b32/riscv32/mod.rs
@@ -184,22 +184,6 @@ s! {
         __pad1: ::c_ulong,
         __pad2: ::c_ulong,
     }
-
-    pub struct flock {
-        pub l_type: ::c_short,
-        pub l_whence: ::c_short,
-        pub l_start: ::off_t,
-        pub l_len: ::off_t,
-        pub l_pid: ::pid_t,
-    }
-
-    pub struct flock64 {
-        pub l_type: ::c_short,
-        pub l_whence: ::c_short,
-        pub l_start: ::off64_t,
-        pub l_len: ::off64_t,
-        pub l_pid: ::pid_t,
-    }
 }
 
 //pub const RLIM_INFINITY: ::rlim_t = !0;
diff --git a/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs b/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs
index f354293e0d05c..9e9dbf6c83097 100644
--- a/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs
+++ b/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs
@@ -173,22 +173,6 @@ s! {
         __unused5: ::c_ulong,
         __unused6: ::c_ulong,
     }
-
-    pub struct flock {
-        pub l_type: ::c_short,
-        pub l_whence: ::c_short,
-        pub l_start: ::off_t,
-        pub l_len: ::off_t,
-        pub l_pid: ::pid_t,
-    }
-
-    pub struct flock64 {
-        pub l_type: ::c_short,
-        pub l_whence: ::c_short,
-        pub l_start: ::off64_t,
-        pub l_len: ::off64_t,
-        pub l_pid: ::pid_t,
-    }
 }
 
 pub const SYS_read: ::c_long = 63;
diff --git a/src/unix/linux_like/linux/musl/lfs64.rs b/src/unix/linux_like/linux/musl/lfs64.rs
new file mode 100644
index 0000000000000..a78c049d5ab91
--- /dev/null
+++ b/src/unix/linux_like/linux/musl/lfs64.rs
@@ -0,0 +1,251 @@
+#[no_mangle]
+pub unsafe extern "C" fn creat64(path: *const ::c_char, mode: ::mode_t) -> ::c_int {
+    ::creat(path, mode)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn fallocate64(
+    fd: ::c_int,
+    mode: ::c_int,
+    offset: ::off64_t,
+    len: ::off64_t,
+) -> ::c_int {
+    ::fallocate(fd, mode, offset, len)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn fgetpos64(stream: *mut ::FILE, pos: *mut ::fpos64_t) -> ::c_int {
+    ::fgetpos(stream, pos.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn fopen64(pathname: *const ::c_char, mode: *const ::c_char) -> *mut ::FILE {
+    ::fopen(pathname, mode)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn freopen64(
+    pathname: *const ::c_char,
+    mode: *const ::c_char,
+    stream: *mut ::FILE,
+) -> *mut ::FILE {
+    ::freopen(pathname, mode, stream)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn fseeko64(
+    stream: *mut ::FILE,
+    offset: ::off64_t,
+    whence: ::c_int,
+) -> ::c_int {
+    ::fseeko(stream, offset, whence)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn fsetpos64(stream: *mut ::FILE, pos: *const ::fpos64_t) -> ::c_int {
+    ::fsetpos(stream, pos.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn fstat64(fildes: ::c_int, buf: *mut ::stat64) -> ::c_int {
+    ::fstat(fildes, buf.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn fstatat64(
+    fd: ::c_int,
+    path: *const ::c_char,
+    buf: *mut ::stat64,
+    flag: ::c_int,
+) -> ::c_int {
+    ::fstatat(fd, path, buf.cast(), flag)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn fstatfs64(fd: ::c_int, buf: *mut ::statfs64) -> ::c_int {
+    ::fstatfs(fd, buf.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn fstatvfs64(fd: ::c_int, buf: *mut ::statvfs64) -> ::c_int {
+    ::fstatvfs(fd, buf.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn ftello64(stream: *mut ::FILE) -> ::off64_t {
+    ::ftello(stream)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn ftruncate64(fd: ::c_int, length: ::off64_t) -> ::c_int {
+    ::ftruncate(fd, length)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn getrlimit64(resource: ::c_int, rlim: *mut ::rlimit64) -> ::c_int {
+    ::getrlimit(resource, rlim.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn lseek64(fd: ::c_int, offset: ::off64_t, whence: ::c_int) -> ::off64_t {
+    ::lseek(fd, offset, whence)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn lstat64(path: *const ::c_char, buf: *mut ::stat64) -> ::c_int {
+    ::lstat(path, buf.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn mmap64(
+    addr: *mut ::c_void,
+    length: ::size_t,
+    prot: ::c_int,
+    flags: ::c_int,
+    fd: ::c_int,
+    offset: ::off64_t,
+) -> *mut ::c_void {
+    ::mmap(addr, length, prot, flags, fd, offset)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn open64(
+    pathname: *const ::c_char,
+    flags: ::c_int,
+    mode: ::mode_t,
+) -> ::c_int {
+    ::open(pathname, flags | ::O_LARGEFILE, mode)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn openat64(
+    dirfd: ::c_int,
+    pathname: *const ::c_char,
+    flags: ::c_int,
+    mode: ::mode_t,
+) -> ::c_int {
+    ::openat(dirfd, pathname, flags | ::O_LARGEFILE, mode)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn posix_fadvise64(
+    fd: ::c_int,
+    offset: ::off64_t,
+    len: ::off64_t,
+    advice: ::c_int,
+) -> ::c_int {
+    ::posix_fadvise(fd, offset, len, advice)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn posix_fallocate64(
+    fd: ::c_int,
+    offset: ::off64_t,
+    len: ::off64_t,
+) -> ::c_int {
+    ::posix_fallocate(fd, offset, len)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn pread64(
+    fd: ::c_int,
+    buf: *mut ::c_void,
+    count: ::size_t,
+    offset: ::off64_t,
+) -> ::ssize_t {
+    ::pread(fd, buf, count, offset)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn preadv64(
+    fd: ::c_int,
+    iov: *const ::iovec,
+    iovcnt: ::c_int,
+    offset: ::off64_t,
+) -> ::ssize_t {
+    ::preadv(fd, iov, iovcnt, offset)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn prlimit64(
+    pid: ::pid_t,
+    resource: ::c_int,
+    new_limit: *const ::rlimit64,
+    old_limit: *mut ::rlimit64,
+) -> ::c_int {
+    ::prlimit(pid, resource, new_limit.cast(), old_limit.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn pwrite64(
+    fd: ::c_int,
+    buf: *const ::c_void,
+    count: ::size_t,
+    offset: ::off64_t,
+) -> ::ssize_t {
+    ::pwrite(fd, buf, count, offset)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn pwritev64(
+    fd: ::c_int,
+    iov: *const ::iovec,
+    iovcnt: ::c_int,
+    offset: ::off64_t,
+) -> ::ssize_t {
+    ::pwritev(fd, iov, iovcnt, offset)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64 {
+    ::readdir(dirp).cast()
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn readdir64_r(
+    dirp: *mut ::DIR,
+    entry: *mut ::dirent64,
+    result: *mut *mut ::dirent64,
+) -> ::c_int {
+    ::readdir_r(dirp, entry.cast(), result.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn sendfile64(
+    out_fd: ::c_int,
+    in_fd: ::c_int,
+    offset: *mut ::off64_t,
+    count: ::size_t,
+) -> ::ssize_t {
+    ::sendfile(out_fd, in_fd, offset, count)
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn setrlimit64(resource: ::c_int, rlim: *const ::rlimit64) -> ::c_int {
+    ::setrlimit(resource, rlim.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn stat64(pathname: *const ::c_char, statbuf: *mut ::stat64) -> ::c_int {
+    ::stat(pathname, statbuf.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn statfs64(pathname: *const ::c_char, buf: *mut ::statfs64) -> ::c_int {
+    ::statfs(pathname, buf.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn statvfs64(path: *const ::c_char, buf: *mut ::statvfs64) -> ::c_int {
+    ::statvfs(path, buf.cast())
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn tmpfile64() -> *mut ::FILE {
+    ::tmpfile()
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn truncate64(path: *const ::c_char, length: ::off64_t) -> ::c_int {
+    ::truncate(path, length)
+}
diff --git a/src/unix/linux_like/linux/musl/mod.rs b/src/unix/linux_like/linux/musl/mod.rs
index 5341e0b683070..4c605338972e3 100644
--- a/src/unix/linux_like/linux/musl/mod.rs
+++ b/src/unix/linux_like/linux/musl/mod.rs
@@ -187,6 +187,14 @@ s! {
         pub l_pid: ::pid_t,
     }
 
+    pub struct flock64 {
+        pub l_type: ::c_short,
+        pub l_whence: ::c_short,
+        pub l_start: ::off64_t,
+        pub l_len: ::off64_t,
+        pub l_pid: ::pid_t,
+    }
+
     pub struct regex_t {
         __re_nsub: ::size_t,
         __opaque: *mut ::c_void,
@@ -773,72 +781,9 @@ extern "C" {
     pub fn basename(path: *mut ::c_char) -> *mut ::c_char;
 }
 
-// Musl's standard entrypoints are already LFS64 compatible, historically the library aliased
-// these together in header files (as `#define`s) _and_ in the library with weak symbol aliases.
-//
-// Since <version> these aliases were removed from the library (both in the API and the ABI) so we
-// alias them here to keep the crate API stable.
-#[allow(dead_code)]
-fn check_type_aliases(
-    dirent: ::dirent,
-    ino: ::ino_t,
-    flock: ::flock,
-    off: ::off_t,
-    pos: ::fpos_t,
-    rlimit: ::rlimit,
-    stat: ::stat,
-    statfs: ::statfs,
-    statvfs: ::statvfs,
-) {
-    let _dirent: ::dirent64 = dirent;
-    let _ino: ::ino64_t = ino;
-    let _flock: ::flock64 = flock;
-    let _off: ::off64_t = off;
-    let _pos: ::fpos64_t = pos;
-    let _rlimit: ::rlimit64 = rlimit;
-    let _stat: ::stat64 = stat;
-    let _statfs: ::statfs64 = statfs;
-    let _statvfs: ::statvfs64 = statvfs;
-}
-pub type dirent64 = ::dirent;
-pub type fpos64_t = ::fpos_t;
-pub type rlimit64 = ::rlimit;
-pub type flock64 = ::flock;
-pub use creat as creat64;
-pub use fallocate as fallocate64;
-pub use fgetpos as fgetpos64;
-pub use fopen as fopen64;
-pub use freopen as freopen64;
-pub use fseeko as fseeko64;
-pub use fsetpos as fsetpos64;
-pub use fstat as fstat64;
-pub use fstatat as fstatat64;
-pub use fstatfs as fstatfs64;
-pub use fstatvfs as fstatvfs64;
-pub use ftello as ftello64;
-pub use ftruncate as ftruncate64;
-pub use getrlimit as getrlimit64;
-pub use lseek as lseek64;
-pub use lstat as lstat64;
-pub use mmap as mmap64;
-pub use open as open64;
-pub use openat as openat64;
-pub use posix_fadvise as posix_fadvise64;
-pub use posix_fallocate as posix_fallocate64;
-pub use pread as pread64;
-pub use preadv as preadv64;
-pub use prlimit as prlimit64;
-pub use pwrite as pwrite64;
-pub use pwritev as pwritev64;
-pub use readdir as readdir64;
-pub use readdir_r as readdir64_r;
-pub use sendfile as sendfile64;
-pub use setrlimit as setrlimit64;
-pub use stat as stat64;
-pub use statfs as statfs64;
-pub use statvfs as statvfs64;
-pub use tmpfile as tmpfile64;
-pub use truncate as truncate64;
+// Alias <foo> to <foo>64 to mimic glibc's LFS64 support
+mod lfs64;
+pub use self::lfs64::*;
 
 cfg_if! {
     if #[cfg(any(target_arch = "x86_64",

From 18d91d6bc07220c3d2e42547630026c3c5bcc8b8 Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Fri, 26 May 2023 22:49:02 +0100
Subject: [PATCH 06/14] Revert extra_traits change now dirent64 is a
 distinguished type

---
 src/unix/linux_like/linux/mod.rs | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs
index 8450f7b97f3f9..989241cf177fe 100644
--- a/src/unix/linux_like/linux/mod.rs
+++ b/src/unix/linux_like/linux/mod.rs
@@ -900,7 +900,6 @@ cfg_if! {
             }
         }
 
-        #[cfg(not(target_env = "musl"))]
         impl PartialEq for dirent64 {
             fn eq(&self, other: &dirent64) -> bool {
                 self.d_ino == other.d_ino
@@ -915,10 +914,8 @@ cfg_if! {
             }
         }
 
-        #[cfg(not(target_env = "musl"))]
         impl Eq for dirent64 {}
 
-        #[cfg(not(target_env = "musl"))]
         impl ::fmt::Debug for dirent64 {
             fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
                 f.debug_struct("dirent64")
@@ -931,7 +928,6 @@ cfg_if! {
             }
         }
 
-        #[cfg(not(target_env = "musl"))]
         impl ::hash::Hash for dirent64 {
             fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
                 self.d_ino.hash(state);

From 0d4f8b5b105e47dcd9f149ea08a268c05c8dd27c Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Fri, 26 May 2023 22:50:14 +0100
Subject: [PATCH 07/14] Confirm uclibc support for preadv/pwritev

---
 src/unix/linux_like/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/unix/linux_like/mod.rs b/src/unix/linux_like/mod.rs
index 77a921c5e9462..a28d93215d7f1 100644
--- a/src/unix/linux_like/mod.rs
+++ b/src/unix/linux_like/mod.rs
@@ -1782,7 +1782,7 @@ extern "C" {
 // LFS64 extensions
 //
 // * musl has 64-bit versions only so aliases the LFS64 symbols to the standard ones
-// * ulibc doesn't have preadv64/pwritev64 (TODO: Or does it?!)
+// * ulibc doesn't have preadv64/pwritev64
 cfg_if! {
     if #[cfg(not(target_env = "musl"))] {
         extern "C" {

From e5b8ede843762eaa13bd9d71957a9dc6991dd083 Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Fri, 26 May 2023 23:02:31 +0100
Subject: [PATCH 08/14] Disable libc-test for LFS64 types

---
 libc-test/build.rs | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/libc-test/build.rs b/libc-test/build.rs
index 3dea03af7b174..56ebfcb94ee8b 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -3333,6 +3333,9 @@ fn test_linux(target: &str) {
             "Ioctl" if gnu => "unsigned long".to_string(),
             "Ioctl" => "int".to_string(),
 
+            // LFS64 types have been removed in musl 1.2.4+
+            "off64_t" if musl => "off_t".to_string(),
+
             // typedefs don't need any keywords
             t if t.ends_with("_t") => t.to_string(),
             // put `struct` in front of all structs:.
@@ -3397,6 +3400,7 @@ fn test_linux(target: &str) {
             "name_t" if musl => true,
 
             t => if musl {
+                // LFS64 types have been removed in musl 1.2.4+
                 t.ends_with("64") || t.ends_with("64_t")
             } else {
                 false
@@ -3412,6 +3416,10 @@ fn test_linux(target: &str) {
         if musl && ty.starts_with("uinput_") {
             return true;
         }
+        // LFS64 types have been removed in musl 1.2.4+
+        if musl && (ty.ends_with("64") || ty.ends_with("64_t")) {
+            return true;
+        }
         // FIXME: sparc64 CI has old headers
         if sparc64 && (ty == "uinput_ff_erase" || ty == "uinput_abs_setup") {
             return true;
@@ -3529,6 +3537,10 @@ fn test_linux(target: &str) {
             {
                 return true;
             }
+            // LFS64 types have been removed in musl 1.2.4+
+            if name.starts_with("RLIM64") {
+                return true;
+            }
         }
         match name {
             // These constants are not available if gnu headers have been included

From 53b811e670fa72d429c3f9d44bea686ffbc26fd1 Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Fri, 26 May 2023 23:30:07 +0100
Subject: [PATCH 09/14] Placate the style gods

---
 libc-test/build.rs               | 12 +++++++-----
 src/unix/linux_like/linux/mod.rs |  7 ++++++-
 src/unix/linux_like/mod.rs       |  7 ++++++-
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/libc-test/build.rs b/libc-test/build.rs
index 56ebfcb94ee8b..27359a8f62d30 100644
--- a/libc-test/build.rs
+++ b/libc-test/build.rs
@@ -3399,11 +3399,13 @@ fn test_linux(target: &str) {
             "priority_t" if musl => true,
             "name_t" if musl => true,
 
-            t => if musl {
-                // LFS64 types have been removed in musl 1.2.4+
-                t.ends_with("64") || t.ends_with("64_t")
-            } else {
-                false
+            t => {
+                if musl {
+                    // LFS64 types have been removed in musl 1.2.4+
+                    t.ends_with("64") || t.ends_with("64_t")
+                } else {
+                    false
+                }
             }
         }
     });
diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs
index 989241cf177fe..e52b3d3a85eae 100644
--- a/src/unix/linux_like/linux/mod.rs
+++ b/src/unix/linux_like/linux/mod.rs
@@ -4858,7 +4858,12 @@ extern "C" {
 cfg_if! {
     if #[cfg(not(target_env = "musl"))] {
         extern "C" {
-            pub fn fallocate64(fd: ::c_int, mode: ::c_int, offset: ::off64_t, len: ::off64_t) -> ::c_int;
+            pub fn fallocate64(
+                fd: ::c_int,
+                mode: ::c_int,
+                offset: ::off64_t,
+                len: ::off64_t
+            ) -> ::c_int;
             pub fn fgetpos64(stream: *mut ::FILE, ptr: *mut fpos64_t) -> ::c_int;
             pub fn fopen64(filename: *const c_char, mode: *const c_char) -> *mut ::FILE;
             pub fn freopen64(
diff --git a/src/unix/linux_like/mod.rs b/src/unix/linux_like/mod.rs
index a28d93215d7f1..4b796a9d550ba 100644
--- a/src/unix/linux_like/mod.rs
+++ b/src/unix/linux_like/mod.rs
@@ -1817,7 +1817,12 @@ cfg_if! {
                 len: ::off64_t,
                 advise: ::c_int,
             ) -> ::c_int;
-            pub fn pread64(fd: ::c_int, buf: *mut ::c_void, count: ::size_t, offset: off64_t) -> ::ssize_t;
+            pub fn pread64(
+                fd: ::c_int,
+                buf: *mut ::c_void,
+                count: ::size_t,
+                offset: off64_t
+            ) -> ::ssize_t;
             pub fn pwrite64(
                 fd: ::c_int,
                 buf: *const ::c_void,

From 65338d5be14f6c520252064a0699d5f8a6443493 Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Sun, 28 May 2023 00:50:06 +0100
Subject: [PATCH 10/14] Allow alias symbols to be mangled ensure inlining
 happens

---
 src/unix/linux_like/linux/musl/lfs64.rs | 70 ++++++++++++-------------
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/src/unix/linux_like/linux/musl/lfs64.rs b/src/unix/linux_like/linux/musl/lfs64.rs
index a78c049d5ab91..259e786f53d49 100644
--- a/src/unix/linux_like/linux/musl/lfs64.rs
+++ b/src/unix/linux_like/linux/musl/lfs64.rs
@@ -1,9 +1,9 @@
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn creat64(path: *const ::c_char, mode: ::mode_t) -> ::c_int {
     ::creat(path, mode)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn fallocate64(
     fd: ::c_int,
     mode: ::c_int,
@@ -13,17 +13,17 @@ pub unsafe extern "C" fn fallocate64(
     ::fallocate(fd, mode, offset, len)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn fgetpos64(stream: *mut ::FILE, pos: *mut ::fpos64_t) -> ::c_int {
     ::fgetpos(stream, pos.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn fopen64(pathname: *const ::c_char, mode: *const ::c_char) -> *mut ::FILE {
     ::fopen(pathname, mode)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn freopen64(
     pathname: *const ::c_char,
     mode: *const ::c_char,
@@ -32,7 +32,7 @@ pub unsafe extern "C" fn freopen64(
     ::freopen(pathname, mode, stream)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn fseeko64(
     stream: *mut ::FILE,
     offset: ::off64_t,
@@ -41,17 +41,17 @@ pub unsafe extern "C" fn fseeko64(
     ::fseeko(stream, offset, whence)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn fsetpos64(stream: *mut ::FILE, pos: *const ::fpos64_t) -> ::c_int {
     ::fsetpos(stream, pos.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn fstat64(fildes: ::c_int, buf: *mut ::stat64) -> ::c_int {
     ::fstat(fildes, buf.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn fstatat64(
     fd: ::c_int,
     path: *const ::c_char,
@@ -61,42 +61,42 @@ pub unsafe extern "C" fn fstatat64(
     ::fstatat(fd, path, buf.cast(), flag)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn fstatfs64(fd: ::c_int, buf: *mut ::statfs64) -> ::c_int {
     ::fstatfs(fd, buf.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn fstatvfs64(fd: ::c_int, buf: *mut ::statvfs64) -> ::c_int {
     ::fstatvfs(fd, buf.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn ftello64(stream: *mut ::FILE) -> ::off64_t {
     ::ftello(stream)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn ftruncate64(fd: ::c_int, length: ::off64_t) -> ::c_int {
     ::ftruncate(fd, length)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn getrlimit64(resource: ::c_int, rlim: *mut ::rlimit64) -> ::c_int {
     ::getrlimit(resource, rlim.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn lseek64(fd: ::c_int, offset: ::off64_t, whence: ::c_int) -> ::off64_t {
     ::lseek(fd, offset, whence)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn lstat64(path: *const ::c_char, buf: *mut ::stat64) -> ::c_int {
     ::lstat(path, buf.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn mmap64(
     addr: *mut ::c_void,
     length: ::size_t,
@@ -108,7 +108,7 @@ pub unsafe extern "C" fn mmap64(
     ::mmap(addr, length, prot, flags, fd, offset)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn open64(
     pathname: *const ::c_char,
     flags: ::c_int,
@@ -117,7 +117,7 @@ pub unsafe extern "C" fn open64(
     ::open(pathname, flags | ::O_LARGEFILE, mode)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn openat64(
     dirfd: ::c_int,
     pathname: *const ::c_char,
@@ -127,7 +127,7 @@ pub unsafe extern "C" fn openat64(
     ::openat(dirfd, pathname, flags | ::O_LARGEFILE, mode)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn posix_fadvise64(
     fd: ::c_int,
     offset: ::off64_t,
@@ -137,7 +137,7 @@ pub unsafe extern "C" fn posix_fadvise64(
     ::posix_fadvise(fd, offset, len, advice)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn posix_fallocate64(
     fd: ::c_int,
     offset: ::off64_t,
@@ -146,7 +146,7 @@ pub unsafe extern "C" fn posix_fallocate64(
     ::posix_fallocate(fd, offset, len)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn pread64(
     fd: ::c_int,
     buf: *mut ::c_void,
@@ -156,7 +156,7 @@ pub unsafe extern "C" fn pread64(
     ::pread(fd, buf, count, offset)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn preadv64(
     fd: ::c_int,
     iov: *const ::iovec,
@@ -166,7 +166,7 @@ pub unsafe extern "C" fn preadv64(
     ::preadv(fd, iov, iovcnt, offset)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn prlimit64(
     pid: ::pid_t,
     resource: ::c_int,
@@ -176,7 +176,7 @@ pub unsafe extern "C" fn prlimit64(
     ::prlimit(pid, resource, new_limit.cast(), old_limit.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn pwrite64(
     fd: ::c_int,
     buf: *const ::c_void,
@@ -186,7 +186,7 @@ pub unsafe extern "C" fn pwrite64(
     ::pwrite(fd, buf, count, offset)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn pwritev64(
     fd: ::c_int,
     iov: *const ::iovec,
@@ -196,12 +196,12 @@ pub unsafe extern "C" fn pwritev64(
     ::pwritev(fd, iov, iovcnt, offset)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64 {
     ::readdir(dirp).cast()
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn readdir64_r(
     dirp: *mut ::DIR,
     entry: *mut ::dirent64,
@@ -210,7 +210,7 @@ pub unsafe extern "C" fn readdir64_r(
     ::readdir_r(dirp, entry.cast(), result.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn sendfile64(
     out_fd: ::c_int,
     in_fd: ::c_int,
@@ -220,32 +220,32 @@ pub unsafe extern "C" fn sendfile64(
     ::sendfile(out_fd, in_fd, offset, count)
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn setrlimit64(resource: ::c_int, rlim: *const ::rlimit64) -> ::c_int {
     ::setrlimit(resource, rlim.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn stat64(pathname: *const ::c_char, statbuf: *mut ::stat64) -> ::c_int {
     ::stat(pathname, statbuf.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn statfs64(pathname: *const ::c_char, buf: *mut ::statfs64) -> ::c_int {
     ::statfs(pathname, buf.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn statvfs64(path: *const ::c_char, buf: *mut ::statvfs64) -> ::c_int {
     ::statvfs(path, buf.cast())
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn tmpfile64() -> *mut ::FILE {
     ::tmpfile()
 }
 
-#[no_mangle]
+#[inline(always)]
 pub unsafe extern "C" fn truncate64(path: *const ::c_char, length: ::off64_t) -> ::c_int {
     ::truncate(path, length)
 }

From 04f8a609a1f805598e49bc2fe22fb7afcd28e529 Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Sun, 28 May 2023 19:06:12 +0100
Subject: [PATCH 11/14] Don't be too enthusiastic

---
 src/unix/linux_like/linux/musl/lfs64.rs | 70 ++++++++++++-------------
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/src/unix/linux_like/linux/musl/lfs64.rs b/src/unix/linux_like/linux/musl/lfs64.rs
index 259e786f53d49..e3ede154bac33 100644
--- a/src/unix/linux_like/linux/musl/lfs64.rs
+++ b/src/unix/linux_like/linux/musl/lfs64.rs
@@ -1,9 +1,9 @@
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn creat64(path: *const ::c_char, mode: ::mode_t) -> ::c_int {
     ::creat(path, mode)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn fallocate64(
     fd: ::c_int,
     mode: ::c_int,
@@ -13,17 +13,17 @@ pub unsafe extern "C" fn fallocate64(
     ::fallocate(fd, mode, offset, len)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn fgetpos64(stream: *mut ::FILE, pos: *mut ::fpos64_t) -> ::c_int {
     ::fgetpos(stream, pos.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn fopen64(pathname: *const ::c_char, mode: *const ::c_char) -> *mut ::FILE {
     ::fopen(pathname, mode)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn freopen64(
     pathname: *const ::c_char,
     mode: *const ::c_char,
@@ -32,7 +32,7 @@ pub unsafe extern "C" fn freopen64(
     ::freopen(pathname, mode, stream)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn fseeko64(
     stream: *mut ::FILE,
     offset: ::off64_t,
@@ -41,17 +41,17 @@ pub unsafe extern "C" fn fseeko64(
     ::fseeko(stream, offset, whence)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn fsetpos64(stream: *mut ::FILE, pos: *const ::fpos64_t) -> ::c_int {
     ::fsetpos(stream, pos.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn fstat64(fildes: ::c_int, buf: *mut ::stat64) -> ::c_int {
     ::fstat(fildes, buf.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn fstatat64(
     fd: ::c_int,
     path: *const ::c_char,
@@ -61,42 +61,42 @@ pub unsafe extern "C" fn fstatat64(
     ::fstatat(fd, path, buf.cast(), flag)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn fstatfs64(fd: ::c_int, buf: *mut ::statfs64) -> ::c_int {
     ::fstatfs(fd, buf.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn fstatvfs64(fd: ::c_int, buf: *mut ::statvfs64) -> ::c_int {
     ::fstatvfs(fd, buf.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn ftello64(stream: *mut ::FILE) -> ::off64_t {
     ::ftello(stream)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn ftruncate64(fd: ::c_int, length: ::off64_t) -> ::c_int {
     ::ftruncate(fd, length)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn getrlimit64(resource: ::c_int, rlim: *mut ::rlimit64) -> ::c_int {
     ::getrlimit(resource, rlim.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn lseek64(fd: ::c_int, offset: ::off64_t, whence: ::c_int) -> ::off64_t {
     ::lseek(fd, offset, whence)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn lstat64(path: *const ::c_char, buf: *mut ::stat64) -> ::c_int {
     ::lstat(path, buf.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn mmap64(
     addr: *mut ::c_void,
     length: ::size_t,
@@ -108,7 +108,7 @@ pub unsafe extern "C" fn mmap64(
     ::mmap(addr, length, prot, flags, fd, offset)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn open64(
     pathname: *const ::c_char,
     flags: ::c_int,
@@ -117,7 +117,7 @@ pub unsafe extern "C" fn open64(
     ::open(pathname, flags | ::O_LARGEFILE, mode)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn openat64(
     dirfd: ::c_int,
     pathname: *const ::c_char,
@@ -127,7 +127,7 @@ pub unsafe extern "C" fn openat64(
     ::openat(dirfd, pathname, flags | ::O_LARGEFILE, mode)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn posix_fadvise64(
     fd: ::c_int,
     offset: ::off64_t,
@@ -137,7 +137,7 @@ pub unsafe extern "C" fn posix_fadvise64(
     ::posix_fadvise(fd, offset, len, advice)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn posix_fallocate64(
     fd: ::c_int,
     offset: ::off64_t,
@@ -146,7 +146,7 @@ pub unsafe extern "C" fn posix_fallocate64(
     ::posix_fallocate(fd, offset, len)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn pread64(
     fd: ::c_int,
     buf: *mut ::c_void,
@@ -156,7 +156,7 @@ pub unsafe extern "C" fn pread64(
     ::pread(fd, buf, count, offset)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn preadv64(
     fd: ::c_int,
     iov: *const ::iovec,
@@ -166,7 +166,7 @@ pub unsafe extern "C" fn preadv64(
     ::preadv(fd, iov, iovcnt, offset)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn prlimit64(
     pid: ::pid_t,
     resource: ::c_int,
@@ -176,7 +176,7 @@ pub unsafe extern "C" fn prlimit64(
     ::prlimit(pid, resource, new_limit.cast(), old_limit.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn pwrite64(
     fd: ::c_int,
     buf: *const ::c_void,
@@ -186,7 +186,7 @@ pub unsafe extern "C" fn pwrite64(
     ::pwrite(fd, buf, count, offset)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn pwritev64(
     fd: ::c_int,
     iov: *const ::iovec,
@@ -196,12 +196,12 @@ pub unsafe extern "C" fn pwritev64(
     ::pwritev(fd, iov, iovcnt, offset)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64 {
     ::readdir(dirp).cast()
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn readdir64_r(
     dirp: *mut ::DIR,
     entry: *mut ::dirent64,
@@ -210,7 +210,7 @@ pub unsafe extern "C" fn readdir64_r(
     ::readdir_r(dirp, entry.cast(), result.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn sendfile64(
     out_fd: ::c_int,
     in_fd: ::c_int,
@@ -220,32 +220,32 @@ pub unsafe extern "C" fn sendfile64(
     ::sendfile(out_fd, in_fd, offset, count)
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn setrlimit64(resource: ::c_int, rlim: *const ::rlimit64) -> ::c_int {
     ::setrlimit(resource, rlim.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn stat64(pathname: *const ::c_char, statbuf: *mut ::stat64) -> ::c_int {
     ::stat(pathname, statbuf.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn statfs64(pathname: *const ::c_char, buf: *mut ::statfs64) -> ::c_int {
     ::statfs(pathname, buf.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn statvfs64(path: *const ::c_char, buf: *mut ::statvfs64) -> ::c_int {
     ::statvfs(path, buf.cast())
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn tmpfile64() -> *mut ::FILE {
     ::tmpfile()
 }
 
-#[inline(always)]
+#[inline]
 pub unsafe extern "C" fn truncate64(path: *const ::c_char, length: ::off64_t) -> ::c_int {
     ::truncate(path, length)
 }

From 56e8db047cfe4c2ecc8f14a66c14655893774ea7 Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Tue, 30 May 2023 17:39:29 +0100
Subject: [PATCH 12/14] Fix feature typo

---
 src/unix/linux_like/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/unix/linux_like/mod.rs b/src/unix/linux_like/mod.rs
index 4b796a9d550ba..764f3ae793298 100644
--- a/src/unix/linux_like/mod.rs
+++ b/src/unix/linux_like/mod.rs
@@ -1842,7 +1842,7 @@ cfg_if! {
 }
 
 cfg_if! {
-    if #[cfg(not(any(target_env = "ulibc", target_env = "musl")))] {
+    if #[cfg(not(any(target_env = "uclibc", target_env = "musl")))] {
         extern "C" {
             pub fn preadv64(
                 fd: ::c_int,

From 5e752449bd051e3d439dc3ce2260cdcc6458bcb8 Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Tue, 30 May 2023 17:46:19 +0100
Subject: [PATCH 13/14] Use `as *mut _` instead of `.cast()` for 1.13.0
 compatibility

---
 src/unix/linux_like/linux/musl/lfs64.rs | 30 ++++++++++++-------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/src/unix/linux_like/linux/musl/lfs64.rs b/src/unix/linux_like/linux/musl/lfs64.rs
index e3ede154bac33..031833b64687f 100644
--- a/src/unix/linux_like/linux/musl/lfs64.rs
+++ b/src/unix/linux_like/linux/musl/lfs64.rs
@@ -15,7 +15,7 @@ pub unsafe extern "C" fn fallocate64(
 
 #[inline]
 pub unsafe extern "C" fn fgetpos64(stream: *mut ::FILE, pos: *mut ::fpos64_t) -> ::c_int {
-    ::fgetpos(stream, pos.cast())
+    ::fgetpos(stream, pos as *mut _)
 }
 
 #[inline]
@@ -43,12 +43,12 @@ pub unsafe extern "C" fn fseeko64(
 
 #[inline]
 pub unsafe extern "C" fn fsetpos64(stream: *mut ::FILE, pos: *const ::fpos64_t) -> ::c_int {
-    ::fsetpos(stream, pos.cast())
+    ::fsetpos(stream, pos as *mut _)
 }
 
 #[inline]
 pub unsafe extern "C" fn fstat64(fildes: ::c_int, buf: *mut ::stat64) -> ::c_int {
-    ::fstat(fildes, buf.cast())
+    ::fstat(fildes, buf as *mut _)
 }
 
 #[inline]
@@ -58,17 +58,17 @@ pub unsafe extern "C" fn fstatat64(
     buf: *mut ::stat64,
     flag: ::c_int,
 ) -> ::c_int {
-    ::fstatat(fd, path, buf.cast(), flag)
+    ::fstatat(fd, path, buf as *mut _, flag)
 }
 
 #[inline]
 pub unsafe extern "C" fn fstatfs64(fd: ::c_int, buf: *mut ::statfs64) -> ::c_int {
-    ::fstatfs(fd, buf.cast())
+    ::fstatfs(fd, buf as *mut _)
 }
 
 #[inline]
 pub unsafe extern "C" fn fstatvfs64(fd: ::c_int, buf: *mut ::statvfs64) -> ::c_int {
-    ::fstatvfs(fd, buf.cast())
+    ::fstatvfs(fd, buf as *mut _)
 }
 
 #[inline]
@@ -83,7 +83,7 @@ pub unsafe extern "C" fn ftruncate64(fd: ::c_int, length: ::off64_t) -> ::c_int
 
 #[inline]
 pub unsafe extern "C" fn getrlimit64(resource: ::c_int, rlim: *mut ::rlimit64) -> ::c_int {
-    ::getrlimit(resource, rlim.cast())
+    ::getrlimit(resource, rlim as *mut _)
 }
 
 #[inline]
@@ -93,7 +93,7 @@ pub unsafe extern "C" fn lseek64(fd: ::c_int, offset: ::off64_t, whence: ::c_int
 
 #[inline]
 pub unsafe extern "C" fn lstat64(path: *const ::c_char, buf: *mut ::stat64) -> ::c_int {
-    ::lstat(path, buf.cast())
+    ::lstat(path, buf as *mut _)
 }
 
 #[inline]
@@ -173,7 +173,7 @@ pub unsafe extern "C" fn prlimit64(
     new_limit: *const ::rlimit64,
     old_limit: *mut ::rlimit64,
 ) -> ::c_int {
-    ::prlimit(pid, resource, new_limit.cast(), old_limit.cast())
+    ::prlimit(pid, resource, new_limit as *mut _, old_limit as *mut _)
 }
 
 #[inline]
@@ -198,7 +198,7 @@ pub unsafe extern "C" fn pwritev64(
 
 #[inline]
 pub unsafe extern "C" fn readdir64(dirp: *mut ::DIR) -> *mut ::dirent64 {
-    ::readdir(dirp).cast()
+    ::readdir(dirp) as *mut _
 }
 
 #[inline]
@@ -207,7 +207,7 @@ pub unsafe extern "C" fn readdir64_r(
     entry: *mut ::dirent64,
     result: *mut *mut ::dirent64,
 ) -> ::c_int {
-    ::readdir_r(dirp, entry.cast(), result.cast())
+    ::readdir_r(dirp, entry as *mut _, result as *mut _)
 }
 
 #[inline]
@@ -222,22 +222,22 @@ pub unsafe extern "C" fn sendfile64(
 
 #[inline]
 pub unsafe extern "C" fn setrlimit64(resource: ::c_int, rlim: *const ::rlimit64) -> ::c_int {
-    ::setrlimit(resource, rlim.cast())
+    ::setrlimit(resource, rlim as *mut _)
 }
 
 #[inline]
 pub unsafe extern "C" fn stat64(pathname: *const ::c_char, statbuf: *mut ::stat64) -> ::c_int {
-    ::stat(pathname, statbuf.cast())
+    ::stat(pathname, statbuf as *mut _)
 }
 
 #[inline]
 pub unsafe extern "C" fn statfs64(pathname: *const ::c_char, buf: *mut ::statfs64) -> ::c_int {
-    ::statfs(pathname, buf.cast())
+    ::statfs(pathname, buf as *mut _)
 }
 
 #[inline]
 pub unsafe extern "C" fn statvfs64(path: *const ::c_char, buf: *mut ::statvfs64) -> ::c_int {
-    ::statvfs(path, buf.cast())
+    ::statvfs(path, buf as *mut _)
 }
 
 #[inline]

From 75ac488063b968699c48881b59d525cd46ca95eb Mon Sep 17 00:00:00 2001
From: Andy Caldwell <andycaldwell@microsoft.com>
Date: Wed, 31 May 2023 17:20:39 +0100
Subject: [PATCH 14/14] Don't merge in O_LARGEFILE since it's a noop and not
 defined on some platforms

---
 src/unix/linux_like/linux/musl/lfs64.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/unix/linux_like/linux/musl/lfs64.rs b/src/unix/linux_like/linux/musl/lfs64.rs
index 031833b64687f..64759e8bd4813 100644
--- a/src/unix/linux_like/linux/musl/lfs64.rs
+++ b/src/unix/linux_like/linux/musl/lfs64.rs
@@ -114,7 +114,7 @@ pub unsafe extern "C" fn open64(
     flags: ::c_int,
     mode: ::mode_t,
 ) -> ::c_int {
-    ::open(pathname, flags | ::O_LARGEFILE, mode)
+    ::open(pathname, flags, mode)
 }
 
 #[inline]
@@ -124,7 +124,7 @@ pub unsafe extern "C" fn openat64(
     flags: ::c_int,
     mode: ::mode_t,
 ) -> ::c_int {
-    ::openat(dirfd, pathname, flags | ::O_LARGEFILE, mode)
+    ::openat(dirfd, pathname, flags, mode)
 }
 
 #[inline]