mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
dirent-util: use getdents64() as is
This partially reverts e86a492ff0.
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.
This commit is contained in:
committed by
Lennart Poettering
parent
abb99d3168
commit
43aacae83a
@@ -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
|
||||
|
||||
@@ -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); \
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user