From 8fbfb0b973b1ff8307f7c29e6e8facb7e0f72ea0 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 17 May 2024 17:58:27 -0400 Subject: dir: Add support for posix_getdents() This will be added to the next POSIX standard, and is already implemented in musl. Link: https://www.austingroupbugs.net/view.php?id=697 Link: https://git.musl-libc.org/cgit/musl/commit/?id=1b0d48517f816e98f19111df82f32bfc1608ecec --- build/has/attribute-format-syslog.c | 13 +++++++++++++ build/has/posix-getdents.c | 9 +++++++++ build/header.mk | 1 + src/dir.c | 16 ++++++++++++---- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 build/has/attribute-format-syslog.c create mode 100644 build/has/posix-getdents.c 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 +// SPDX-License-Identifier: 0BSD + +#include + +__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 +// SPDX-License-Identifier: 0BSD + +#include + +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) { -- cgit v1.2.3