diff --git a/Makefile b/Makefile
index 08dd7e89a9c62e64707790f572b7f34049aaa849..945e0f2f749e535e693d5a9e1427849ca9238af4 100644
--- a/Makefile
+++ b/Makefile
@@ -169,6 +169,9 @@ TESTSYSRUNS     := $(patsubst \
 REALPATHSRCS_C  := $(wildcard $(TESTNAMEPREFIX)realpath*.c)
 REALPATHRUNS    := $(patsubst \
                      $(TESTNAMEPREFIX)%.c,$(TESTRUNPREFIX)%,$(REALPATHSRCS_C))
+FDOPENDIRSRCS_C := $(wildcard $(TESTNAMEPREFIX)fdopendir*.c)
+FDOPENDIRRUNS   := $(patsubst \
+                     $(TESTNAMEPREFIX)%.c,$(TESTRUNPREFIX)%,$(FDOPENDIRSRCS_C))
 
 # Tests that are only run manually
 MANTESTDIR       = manual_tests
@@ -475,6 +478,10 @@ $(TESTNAMEPREFIX)realpath_nonext.o: $(TESTNAMEPREFIX)realpath.c
 $(TESTNAMEPREFIX)realpath_nonposix.o: $(TESTNAMEPREFIX)realpath.c
 $(TESTNAMEPREFIX)realpath_compat.o: $(TESTNAMEPREFIX)realpath.c
 
+# The fdopendir_ino?? tests include the fdopendir source
+$(TESTNAMEPREFIX)fdopendir_ino32.o: $(TESTNAMEPREFIX)fdopendir.c
+$(TESTNAMEPREFIX)fdopendir_ino64.o: $(TESTNAMEPREFIX)fdopendir.c
+
 # Provide a target for all "darwin_c" tests
 $(XTESTRUNPREFIX)darwin_c_all: $(DARWINRUNS)
 
@@ -484,6 +491,9 @@ $(XTESTRUNPREFIX)scandir_all: $(SCANDIRRUNS)
 # Provide a target for all "realpath" tests
 $(TESTRUNPREFIX)realpath_all: $(REALPATHRUNS)
 
+# Provide a target for all "fdopendir" tests
+$(TESTRUNPREFIX)fdopendir_all: $(FDOPENDIRRUNS)
+
 $(MANTESTRUNS): $(MANRUNPREFIX)%: $(MANTESTPREFIX)%
 	$< $(TEST_ARGS)
 
@@ -544,6 +554,7 @@ clean: $(MANRUNPREFIX)clean test_clean
 .PHONY: $(TESTRUNS) $(XTESTRUNS) $(MANTESTRUNS)
 .PHONY: $(MANRUNPREFIX)clean test_clean xtest_clean
 .PHONY: $(XTESTRUNPREFIX)scandir_all
+.PHONY: $(TESTRUNPREFIX)fdopendir_all
 .PHONY: install install-headers install-lib install-dlib install-slib
 .PHONY: tiger-bins install-tiger
 .PHONY: allobjs dlibobjs slibobjs syslibobjs
diff --git a/test/test_fdopendir_ino32.c b/test/test_fdopendir_ino32.c
new file mode 100644
index 0000000000000000000000000000000000000000..a4c31e434e47fc33b7675c14d328b2223e57c8da
--- /dev/null
+++ b/test/test_fdopendir_ino32.c
@@ -0,0 +1,26 @@
+/*
+ * Version of test_fdopendir with 32-bit inodes (if possible).
+ *
+ * This doesn't work on arm64.
+ */
+
+#if defined(__arm64__) && __arm64__
+
+#include <libgen.h>
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+  (void) argc;
+  printf("%s doesn't work on arm64.\n", basename(argv[0]));
+  return 0;
+}
+
+#else /* !arm64 */
+
+#define _DARWIN_NO_64_BIT_INODE 1
+
+#include "test_fdopendir.c"
+
+#endif /* !arm64 */
diff --git a/test/test_fdopendir_ino64.c b/test/test_fdopendir_ino64.c
new file mode 100644
index 0000000000000000000000000000000000000000..36a91b17bfc9f3b81881891a61b18153ff61c033
--- /dev/null
+++ b/test/test_fdopendir_ino64.c
@@ -0,0 +1,32 @@
+/*
+ * Version of test_fdopendir with 64-bit inodes (if possible).
+ *
+ * This is primarily for 10.5, where 64-bit inodes are supported
+ * but not the default.
+ *
+ * Currently, 64-bit inodes don't work on 10.4.  Although requesting
+ * 64-bit inode support is ignored by the 10.4 SDK, it can work when
+ * building with a 10.5+ SDK, so we explicitly disable it here.
+ */
+
+#if !defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) \
+    || __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1050
+
+#include <libgen.h>
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+  (void) argc;
+  printf("%s doesn't work on 10.4.\n", basename(argv[0]));
+  return 0;
+}
+
+#else /* >= 10.5 */
+
+#define _DARWIN_USE_64_BIT_INODE 1
+
+#include "test_fdopendir.c"
+
+#endif /* >= 10.5 */