From 322ba046d8375d3c607860b5aff2b45f4cdd5c37 Mon Sep 17 00:00:00 2001
From: Scott Lamb <slamb@slamb.org>
Date: Tue, 5 Jun 2018 06:28:03 -0700
Subject: [PATCH] add fdopendir on macOS

Fixes #1017

I moved it up to src/unix/mod.rs, as it's specified in POSIX.1-2008 and
appears to be implemented on every Unix-like system.

The symbol names on macOS appear similar to those for opendir; I found
them via the commands below. I tested the x86_64 version;
fdopendir$INODE64 worked as expected.

$ nm -arch x86_64 /usr/lib/system/libsystem_c.dylib | grep fdopendir
000000000007ea6d T _fdopendir
000000000002ba97 T _fdopendir$INODE64
$ nm -arch i386 /usr/lib/system/libsystem_c.dylib | grep fdopendir
00082d1e T _fdopendir
0002b528 T _fdopendir$INODE64$UNIX2003
00082d1e T _fdopendir$UNIX2003
---
 src/unix/bsd/freebsdlike/mod.rs | 2 --
 src/unix/bsd/netbsdlike/mod.rs  | 2 --
 src/unix/haiku/mod.rs           | 1 -
 src/unix/mod.rs                 | 7 +++++++
 src/unix/notbsd/mod.rs          | 2 --
 src/unix/solaris/mod.rs         | 2 --
 src/unix/uclibc/mod.rs          | 2 --
 7 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs
index cf3e41b5..92d8a7bc 100644
--- a/src/unix/bsd/freebsdlike/mod.rs
+++ b/src/unix/bsd/freebsdlike/mod.rs
@@ -1170,8 +1170,6 @@ extern {
     pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::c_int;
     pub fn rtprio(function: ::c_int, pid: ::pid_t, rtp: *mut rtprio) -> ::c_int;
 
-    pub fn fdopendir(fd: ::c_int) -> *mut ::DIR;
-
     #[cfg_attr(target_os = "freebsd", link_name = "mknodat@FBSD_1.1")]
     pub fn mknodat(dirfd: ::c_int, pathname: *const ::c_char,
                   mode: ::mode_t, dev: dev_t) -> ::c_int;
diff --git a/src/unix/bsd/netbsdlike/mod.rs b/src/unix/bsd/netbsdlike/mod.rs
index a7c6f960..a9cc5f98 100644
--- a/src/unix/bsd/netbsdlike/mod.rs
+++ b/src/unix/bsd/netbsdlike/mod.rs
@@ -631,8 +631,6 @@ extern {
     pub fn getpriority(which: ::c_int, who: ::id_t) -> ::c_int;
     pub fn setpriority(which: ::c_int, who: ::id_t, prio: ::c_int) -> ::c_int;
 
-    pub fn fdopendir(fd: ::c_int) -> *mut ::DIR;
-
     pub fn mknodat(dirfd: ::c_int, pathname: *const ::c_char,
                    mode: ::mode_t, dev: dev_t) -> ::c_int;
     pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char,
diff --git a/src/unix/haiku/mod.rs b/src/unix/haiku/mod.rs
index 8e312856..dd3dc7b1 100644
--- a/src/unix/haiku/mod.rs
+++ b/src/unix/haiku/mod.rs
@@ -1097,7 +1097,6 @@ extern {
     pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t,
                   options: ::c_int) -> ::c_int;
 
-    pub fn fdopendir(fd: ::c_int) -> *mut ::DIR;
     pub fn glob(pattern: *const ::c_char,
                 flags: ::c_int,
                 errfunc: Option<extern fn(epath: *const ::c_char,
diff --git a/src/unix/mod.rs b/src/unix/mod.rs
index d6cde7ae..2810266f 100644
--- a/src/unix/mod.rs
+++ b/src/unix/mod.rs
@@ -416,6 +416,13 @@ extern {
                link_name = "opendir$INODE64$UNIX2003")]
     #[cfg_attr(target_os = "netbsd", link_name = "__opendir30")]
     pub fn opendir(dirname: *const c_char) -> *mut ::DIR;
+
+    #[cfg_attr(all(target_os = "macos", target_arch = "x86_64"),
+               link_name = "fdopendir$INODE64")]
+    #[cfg_attr(all(target_os = "macos", target_arch = "x86"),
+               link_name = "fdopendir$INODE64$UNIX2003")]
+    pub fn fdopendir(fd: ::c_int) -> *mut ::DIR;
+
     #[cfg_attr(target_os = "macos", link_name = "readdir$INODE64")]
     #[cfg_attr(target_os = "netbsd", link_name = "__readdir30")]
     #[cfg_attr(target_os = "freebsd", link_name = "readdir@FBSD_1.0")]
diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs
index 2de3ac88..b13af239 100644
--- a/src/unix/notbsd/mod.rs
+++ b/src/unix/notbsd/mod.rs
@@ -1036,8 +1036,6 @@ extern {
     pub fn stat64(path: *const c_char, buf: *mut stat64) -> ::c_int;
     pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int;
 
-    pub fn fdopendir(fd: ::c_int) -> *mut ::DIR;
-
     pub fn mknodat(dirfd: ::c_int, pathname: *const ::c_char,
                    mode: ::mode_t, dev: dev_t) -> ::c_int;
     pub fn pthread_condattr_getclock(attr: *const pthread_condattr_t,
diff --git a/src/unix/solaris/mod.rs b/src/unix/solaris/mod.rs
index aecc6117..d76bb802 100644
--- a/src/unix/solaris/mod.rs
+++ b/src/unix/solaris/mod.rs
@@ -1297,8 +1297,6 @@ extern {
     pub fn getpriority(which: ::c_int, who: ::c_int) -> ::c_int;
     pub fn setpriority(which: ::c_int, who: ::c_int, prio: ::c_int) -> ::c_int;
 
-    pub fn fdopendir(fd: ::c_int) -> *mut ::DIR;
-
     pub fn mknodat(dirfd: ::c_int, pathname: *const ::c_char,
                    mode: ::mode_t, dev: dev_t) -> ::c_int;
     pub fn mkfifoat(dirfd: ::c_int, pathname: *const ::c_char,
diff --git a/src/unix/uclibc/mod.rs b/src/unix/uclibc/mod.rs
index 49f7792d..e9c1f21e 100644
--- a/src/unix/uclibc/mod.rs
+++ b/src/unix/uclibc/mod.rs
@@ -1612,8 +1612,6 @@ extern {
     pub fn truncate64(path: *const c_char, length: off64_t) -> ::c_int;
     pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int;
 
-    pub fn fdopendir(fd: ::c_int) -> *mut ::DIR;
-
     pub fn mknodat(dirfd: ::c_int, pathname: *const ::c_char,
                    mode: ::mode_t, dev: dev_t) -> ::c_int;
     pub fn ppoll(fds: *mut ::pollfd,
-- 
GitLab