summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-04-18 16:16:18 -0400
committerTavian Barnes <tavianator@tavianator.com>2024-04-19 15:50:45 -0400
commit1207086b5a6341412c647480eea68c870b18bba1 (patch)
tree3bdacc576075c5d7c71456c841e3e720c0eb84a4
parent29ddac2bf64bb305b285db86015abebe8a0bd8b3 (diff)
downloadbfs-1207086b5a6341412c647480eea68c870b18bba1.tar.xz
config: Check for getdents{,64}()
-rw-r--r--config/flags.mk1
-rw-r--r--config/getdents.c10
-rw-r--r--config/getdents64-syscall.c12
-rw-r--r--config/getdents64.c10
-rw-r--r--config/header.mk3
-rw-r--r--src/dir.c14
-rw-r--r--src/dir.h4
7 files changed, 45 insertions, 9 deletions
diff --git a/config/flags.mk b/config/flags.mk
index 9959d10..8a2e50e 100644
--- a/config/flags.mk
+++ b/config/flags.mk
@@ -36,7 +36,6 @@ export BFS_CPPFLAGS= \
-D_DARWIN_C_SOURCE \
-D_DEFAULT_SOURCE \
-D_GNU_SOURCE \
- -D_LARGEFILE64_SOURCE \
-D_POSIX_PTHREAD_SEMANTICS \
-D_FILE_OFFSET_BITS=64 \
-D_TIME_BITS=64
diff --git a/config/getdents.c b/config/getdents.c
new file mode 100644
index 0000000..d0d4228
--- /dev/null
+++ b/config/getdents.c
@@ -0,0 +1,10 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+#include <dirent.h>
+
+int main(void) {
+ struct dirent de;
+ getdents(3, &de, 1024);
+ return 0;
+}
diff --git a/config/getdents64-syscall.c b/config/getdents64-syscall.c
new file mode 100644
index 0000000..4838c14
--- /dev/null
+++ b/config/getdents64-syscall.c
@@ -0,0 +1,12 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+#include <dirent.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+int main(void) {
+ struct dirent64 de;
+ syscall(SYS_getdents64, 3, &de, 1024);
+ return 0;
+}
diff --git a/config/getdents64.c b/config/getdents64.c
new file mode 100644
index 0000000..1abf36d
--- /dev/null
+++ b/config/getdents64.c
@@ -0,0 +1,10 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+#include <dirent.h>
+
+int main(void) {
+ struct dirent64 de;
+ getdents64(3, &de, 1024);
+ return 0;
+}
diff --git a/config/header.mk b/config/header.mk
index 8867200..cc4ae05 100644
--- a/config/header.mk
+++ b/config/header.mk
@@ -9,6 +9,9 @@ include config/exports.mk
# All header fragments we generate
HEADERS := \
+ ${GEN}/getdents.h \
+ ${GEN}/getdents64.h \
+ ${GEN}/getdents64-syscall.h \
${GEN}/getprogname.h \
${GEN}/getprogname-gnu.h \
${GEN}/posix-spawn-addfchdir.h \
diff --git a/src/dir.c b/src/dir.c
index 53c9be3..8b1bee0 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -17,7 +17,7 @@
#include <unistd.h>
#if BFS_USE_GETDENTS
-# if __linux__
+# if BFS_HAS_GETDENTS64_SYSCALL
# include <sys/syscall.h>
# endif
@@ -25,12 +25,14 @@
static ssize_t bfs_getdents(int fd, void *buf, size_t size) {
sanitize_uninit(buf, size);
-#if (__linux__ && __GLIBC__ && !__GLIBC_PREREQ(2, 30)) || __ANDROID__
- ssize_t ret = syscall(SYS_getdents64, fd, buf, size);
-#elif __linux__
+#if BFS_HAS_GETDENTS
+ ssize_t ret = getdents(fd, buf, size);
+#elif BFS_HAS_GETDENTS64
ssize_t ret = getdents64(fd, buf, size);
+#elif BFS_HAS_GETDENTS64_SYSCALL
+ ssize_t ret = syscall(SYS_getdents64, fd, buf, size);
#else
- ssize_t ret = getdents(fd, buf, size);
+# error "No getdents() implementation"
#endif
if (ret > 0) {
@@ -42,7 +44,7 @@ static ssize_t bfs_getdents(int fd, void *buf, size_t size) {
#endif // BFS_USE_GETDENTS
-#if BFS_USE_GETDENTS && __linux__
+#if BFS_USE_GETDENTS && !BFS_HAS_GETDENTS
/** Directory entry type for bfs_getdents() */
typedef struct dirent64 sys_dirent;
#else
diff --git a/src/dir.h b/src/dir.h
index 18d907e..19dfa98 100644
--- a/src/dir.h
+++ b/src/dir.h
@@ -14,8 +14,8 @@
* Whether the implementation uses the getdents() syscall directly, rather than
* libc's readdir().
*/
-#ifndef BFS_USE_GETDENTS
-# define BFS_USE_GETDENTS (__linux__ || __FreeBSD__)
+#if !defined(BFS_USE_GETDENTS) && (__linux__ || __FreeBSD__)
+# define BFS_USE_GETDENTS (BFS_HAS_GETDENTS || BFS_HAS_GETDENTS64 | BFS_HAS_GETDENTS64_SYSCALL)
#endif
/**