]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dirent-util: use getdents64() as is
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 9 Jun 2025 15:17:36 +0000 (00:17 +0900)
committerLennart Poettering <lennart@poettering.net>
Wed, 18 Jun 2025 08:45:49 +0000 (10:45 +0200)
This partially reverts e86a492ff08526e5adf85fa881c76f80adc3c84a.

The function getdents64() was introduced in glibc-2.30, and our baseline
on glibc is 2.31. Hence, we can assume the function always exists.
The posix_getdents() wrapper was introduced for compatibility with musl.
However, even the latest release of musl does not provide posix_getdents()
yet. Also, even with musl, by defining _LARGEFILE64_SOURCE, we can get
getdents64() and struct dirent64. Hence, the wrapper is anyway not
necessary.

meson.build
src/basic/dirent-util.h
src/basic/recurse-dir.c
src/basic/stat-util.c

index 12e787b552f2c39779d1c7693cd67fe420a99eeb..3f5ddccd12e81d588a1ecc0913aab62e47e76305 100644 (file)
@@ -575,7 +575,6 @@ assert(long_max > 100000)
 conf.set_quoted('LONG_MAX_STR', '@0@'.format(long_max))
 
 foreach ident : [
-        ['struct dirent64',   '''#include <dirent.h>'''],       # for musl, but only for compile time check, see dirent-util.h
         ['struct sched_attr', '''#include <sched.h>'''],        # since glibc-2.41
 ]
         # We get -1 if the size cannot be determined
@@ -586,7 +585,6 @@ endforeach
 foreach ident : [
         ['set_mempolicy',     '''#include <sys/syscall.h>'''],  # declared at numaif.h provided by libnuma, which we do not use
         ['get_mempolicy',     '''#include <sys/syscall.h>'''],  # declared at numaif.h provided by libnuma, which we do not use
-        ['posix_getdents',    '''#include <dirent.h>'''],       # glibc does not implement it, but musl does
         ['strerrorname_np',   '''#include <string.h>'''],       # since glibc-2.32
         ['mallinfo2',         '''#include <malloc.h>'''],       # since glibc-2.33
         ['execveat',          '''#include <unistd.h>'''],       # since glibc-2.34
index 2f1df3cf66726aaa7d7a56ef69d3ec8b31c71aa6..1f305930c6cb428177f51324944e5889a76b552e 100644 (file)
@@ -28,30 +28,12 @@ struct dirent* readdir_no_dot(DIR *dirp);
                      continue;                                          \
              else
 
-/* Musl provides posix_getdents(). But glibc does not, and provides their own implementation as getdents64().
- * Let's introduce a simple wrapper. */
-#if !HAVE_POSIX_GETDENTS
-static inline ssize_t posix_getdents(int fd, void *buf, size_t nbyte, int flags) {
-        assert(fd >= 0);
-        assert(buf);
-        assert(nbyte > 0);
-
-        if (flags != 0)
-                return -EINVAL; /* Currently flags must be zero. */
-
-        return getdents64(fd, buf, nbyte);
-}
-#endif
-
 /* Maximum space one dirent structure might require at most */
 #define DIRENT_SIZE_MAX CONST_MAX(sizeof(struct dirent), offsetof(struct dirent, d_name) + NAME_MAX + 1)
 
 /* Only if 64-bit off_t is enabled struct dirent + struct dirent64 are actually the same. We require this, and
  * we want them to be interchangeable to make getdents64() work, hence verify that. */
 assert_cc(_FILE_OFFSET_BITS == 64);
-/* These asserts would fail on musl where the LFS extensions don't exist. They should
- * always be present on glibc however. */
-#if HAVE_STRUCT_DIRENT64
 assert_cc(sizeof(struct dirent) == sizeof(struct dirent64));
 assert_cc(offsetof(struct dirent, d_ino) == offsetof(struct dirent64, d_ino));
 assert_cc(sizeof_field(struct dirent, d_ino) == sizeof_field(struct dirent64, d_ino));
@@ -63,7 +45,6 @@ assert_cc(offsetof(struct dirent, d_type) == offsetof(struct dirent64, d_type));
 assert_cc(sizeof_field(struct dirent, d_type) == sizeof_field(struct dirent64, d_type));
 assert_cc(offsetof(struct dirent, d_name) == offsetof(struct dirent64, d_name));
 assert_cc(sizeof_field(struct dirent, d_name) == sizeof_field(struct dirent64, d_name));
-#endif
 
 #define FOREACH_DIRENT_IN_BUFFER(de, buf, sz)                           \
         for (void *_end = (uint8_t*) ({ (de) = (buf); }) + (sz);        \
index 36945265473856c1890eafb0d8e94a5942b5982e..508076207804e9ef2d3e0529e260c18166ffa761 100644 (file)
@@ -53,7 +53,7 @@ int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret) {
                 bs = MIN(MALLOC_SIZEOF_SAFE(de) - offsetof(DirectoryEntries, buffer), (size_t) SSIZE_MAX);
                 assert(bs > de->buffer_size);
 
-                n = posix_getdents(dir_fd, (uint8_t*) de->buffer + de->buffer_size, bs - de->buffer_size, /* flags = */ 0);
+                n = getdents64(dir_fd, (struct dirent*) ((uint8_t*) de->buffer + de->buffer_size), bs - de->buffer_size);
                 if (n < 0)
                         return -errno;
                 if (n == 0)
index 237d8e0853740f92197010da3be62da41131a38a..cbdcf190547a0c376b3714e1ff31a4658d9746e1 100644 (file)
@@ -167,7 +167,7 @@ int dir_is_empty_at(int dir_fd, const char *path, bool ignore_hidden_or_backup)
                 struct dirent *de;
                 ssize_t n;
 
-                n = posix_getdents(fd, buf, m, /* flags = */ 0);
+                n = getdents64(fd, buf, m);
                 if (n < 0)
                         return -errno;
                 if (n == 0)