summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/has/attribute-format-syslog.c13
-rw-r--r--build/has/posix-getdents.c9
-rw-r--r--build/header.mk1
-rw-r--r--src/dir.c16
4 files changed, 35 insertions, 4 deletions
diff --git a/build/has/attribute-format-syslog.c b/build/has/attribute-format-syslog.c
new file mode 100644
index 0000000..ce988e5
--- /dev/null
+++ b/build/has/attribute-format-syslog.c
@@ -0,0 +1,13 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+#include <stdio.h>
+
+__attribute__((format(syslog, 1, 2)))
+static int foo(const char *format, ...) {
+ return 0;
+}
+
+int main(void) {
+ return foo("%s: %m\n", "main()");
+}
diff --git a/build/has/posix-getdents.c b/build/has/posix-getdents.c
new file mode 100644
index 0000000..f74bbe5
--- /dev/null
+++ b/build/has/posix-getdents.c
@@ -0,0 +1,9 @@
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+
+#include <dirent.h>
+
+int main(void) {
+ char buf[1024];
+ return posix_getdents(3, (void *)buf, sizeof(buf), 0);
+}
diff --git a/build/header.mk b/build/header.mk
index 3cea6d7..a449b77 100644
--- a/build/header.mk
+++ b/build/header.mk
@@ -32,6 +32,7 @@ HEADERS := \
gen/has/getprogname.h \
gen/has/max-align-t.h \
gen/has/pipe2.h \
+ gen/has/posix-getdents.h \
gen/has/posix-spawn-addfchdir-np.h \
gen/has/posix-spawn-addfchdir.h \
gen/has/st-acmtim.h \
diff --git a/src/dir.c b/src/dir.c
index cfbbca4..fadf1c0 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -25,7 +25,13 @@
static ssize_t bfs_getdents(int fd, void *buf, size_t size) {
sanitize_uninit(buf, size);
-#if BFS_HAS_GETDENTS
+#if BFS_HAS_POSIX_GETDENTS
+ int flags = 0;
+# ifdef DT_FORCE_TYPE
+ flags |= DT_FORCE_TYPE;
+# endif
+ ssize_t ret = posix_getdents(fd, buf, size, flags);
+#elif BFS_HAS_GETDENTS
ssize_t ret = getdents(fd, buf, size);
#elif BFS_HAS_GETDENTS64
ssize_t ret = getdents64(fd, buf, size);
@@ -44,11 +50,13 @@ static ssize_t bfs_getdents(int fd, void *buf, size_t size) {
#endif // BFS_USE_GETDENTS
-#if BFS_USE_GETDENTS && !BFS_HAS_GETDENTS
/** Directory entry type for bfs_getdents() */
-typedef struct dirent64 sys_dirent;
-#else
+#if !BFS_USE_GETDENTS || BFS_HAS_GETDENTS
typedef struct dirent sys_dirent;
+#elif BFS_HAS_POSIX_GETDENTS
+typedef struct posix_dent sys_dirent;
+#else
+typedef struct dirent64 sys_dirent;
#endif
enum bfs_type bfs_mode_to_type(mode_t mode) {