summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch')
-rw-r--r--9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch123
1 files changed, 54 insertions, 69 deletions
diff --git a/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch b/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch
index 7a9c5a3..644af1c 100644
--- a/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch
+++ b/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch
@@ -1,8 +1,7 @@
-From c71a60022adc7c9b7e37a813e2abad0d0724245a Mon Sep 17 00:00:00 2001
+From b1ab50b1c7f17d6b38c1e3a665cca971ba16deab Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
-Date: Tue, 20 Oct 2020 16:00:43 -0300
-Subject: [PATCH 09/10] linux: Use getdents64 on readdir64 compat
- implementation
+Date: Fri, 27 Jan 2023 14:28:34 -0300
+Subject: [PATCH 9/9] linux: Use getdents64 on readdir64 compat implementation
It uses a similar strategy from the non-LFS readdir that also
uses getdents64 internally and uses a translation buffer to return
@@ -12,14 +11,45 @@ It allows to remove __old_getdents64.
Checked on i686-linux-gnu.
---
+ sysdeps/unix/sysv/linux/dirstream.h | 13 +++-
sysdeps/unix/sysv/linux/getdents64.c | 93 ----------------------------
sysdeps/unix/sysv/linux/olddirent.h | 2 -
- sysdeps/unix/sysv/linux/opendir.c | 15 ++++-
- sysdeps/unix/sysv/linux/readdir64.c | 62 +++++++++++++++----
- 4 files changed, 64 insertions(+), 108 deletions(-)
+ sysdeps/unix/sysv/linux/readdir64.c | 50 +++++++++++----
+ 4 files changed, 50 insertions(+), 108 deletions(-)
+diff --git a/sysdeps/unix/sysv/linux/dirstream.h b/sysdeps/unix/sysv/linux/dirstream.h
+index 8f58a1c3a6..b03ece4590 100644
+--- a/sysdeps/unix/sysv/linux/dirstream.h
++++ b/sysdeps/unix/sysv/linux/dirstream.h
+@@ -24,6 +24,11 @@
+ #include <libc-lock.h>
+ #include <telldir.h>
+
++#include <shlib-compat.h>
++#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
++# include <olddirent.h>
++#endif
++
+ /* Directory stream type.
+
+ The miscellaneous Unix `readdir' implementations read directory data
+@@ -44,7 +49,13 @@ struct __dirstream
+ int errcode; /* Delayed error code. */
+
+ #if !defined __OFF_T_MATCHES_OFF64_T || !defined __INO_T_MATCHES_INO64_T
+- struct dirent tdp;
++ union
++ {
++ struct dirent tdp;
++#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
++ struct __old_dirent64 tdp64;
++# endif
++ };
+ #endif
+ #if _DIRENT_OFFSET_TRANSLATION
+ struct dirstream_loc_t locs; /* off64_t to long int map for telldir. */
diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
-index 510a586859..92481526c5 100644
+index 01c3517deb..db299864ed 100644
--- a/sysdeps/unix/sysv/linux/getdents64.c
+++ b/sysdeps/unix/sysv/linux/getdents64.c
@@ -36,97 +36,4 @@ weak_alias (__getdents64, getdents64)
@@ -121,7 +151,7 @@ index 510a586859..92481526c5 100644
-# endif /* SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) */
#endif /* _DIRENT_MATCHES_DIRENT64 */
diff --git a/sysdeps/unix/sysv/linux/olddirent.h b/sysdeps/unix/sysv/linux/olddirent.h
-index 00c84b9521..68aafd7c02 100644
+index cde95e192e..2d682a6919 100644
--- a/sysdeps/unix/sysv/linux/olddirent.h
+++ b/sysdeps/unix/sysv/linux/olddirent.h
@@ -36,8 +36,6 @@ extern struct __old_dirent64 *__old_readdir64_unlocked (DIR *__dirp)
@@ -133,44 +163,11 @@ index 00c84b9521..68aafd7c02 100644
int __old_scandir64 (const char * __dir,
struct __old_dirent64 *** __namelist,
int (*__selector) (const struct __old_dirent64 *),
-diff --git a/sysdeps/unix/sysv/linux/opendir.c b/sysdeps/unix/sysv/linux/opendir.c
-index 9a0b7ab4c4..df40b0a64e 100644
---- a/sysdeps/unix/sysv/linux/opendir.c
-+++ b/sysdeps/unix/sysv/linux/opendir.c
-@@ -23,6 +23,11 @@
-
- #include <not-cancel.h>
-
-+#include <shlib-compat.h>
-+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-+# include <olddirent.h>
-+#endif
-+
- enum {
- opendir_oflags = O_RDONLY|O_NDELAY|O_DIRECTORY|O_LARGEFILE|O_CLOEXEC
- };
-@@ -128,7 +133,15 @@ __alloc_dir (int fd, bool close_fd, int flags,
- expand the buffer if required. */
- enum
- {
-- tbuffer_size = sizeof (struct dirent) + NAME_MAX + 1
-+ tbuffer_size =
-+# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-+ /* This is used on compat readdir64. */
-+ MAX (sizeof (struct dirent),
-+ sizeof (struct __old_dirent64))
-+# else
-+ sizeof (struct dirent)
-+# endif
-+ + NAME_MAX + 1
- };
- dirp->tbuffer = malloc (tbuffer_size);
- if (dirp->tbuffer == NULL)
diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c
-index bbe247f95d..01e834e238 100644
+index b901071aa7..88e42c5e90 100644
--- a/sysdeps/unix/sysv/linux/readdir64.c
+++ b/sysdeps/unix/sysv/linux/readdir64.c
-@@ -102,21 +102,52 @@ versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
+@@ -102,21 +102,43 @@ versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
# include <olddirent.h>
@@ -182,29 +179,20 @@ index bbe247f95d..01e834e238 100644
+dirstream_old_entry (struct __dirstream *ds, const struct dirent64 *dp64)
+{
+ /* Check for overflow. */
-+ ino_t d_ino = dp64->d_ino;
-+ if (d_ino != dp64->d_ino)
++ if (!in_ino_t_range (dp64->d_ino))
+ return false;
+
-+ /* Expand the translation buffer to hold the new namesize. */
-+ size_t d_reclen = sizeof (struct __old_dirent64)
-+ + dp64->d_reclen - offsetof (struct dirent64, d_name);
-+ if (d_reclen > ds->tbuffer_size)
-+ {
-+ char *newbuffer = realloc (ds->tbuffer, d_reclen);
-+ if (newbuffer == NULL)
-+ return false;
-+ ds->tbuffer = newbuffer;
-+ ds->tbuffer_size = d_reclen;
-+ }
++ /* And if name is too large. */
++ if (dp64->d_reclen - offsetof (struct dirent64, d_name) > NAME_MAX)
++ return false;
+
-+ struct __old_dirent64 *olddp64 = (struct __old_dirent64 *) ds->tbuffer;
++ ds->filepos = dp64->d_off;
+
-+ olddp64->d_off = dp64->d_off;
-+ olddp64->d_ino = dp64->d_ino;
-+ olddp64->d_reclen = dp64->d_reclen;
-+ olddp64->d_type = dp64->d_type;
-+ memcpy (olddp64->d_name, dp64->d_name,
++ ds->tdp64.d_off = dp64->d_off;
++ ds->tdp64.d_ino = dp64->d_ino;
++ ds->tdp64.d_reclen = dp64->d_reclen;
++ ds->tdp64.d_type = dp64->d_type;
++ memcpy (ds->tdp64.d_name, dp64->d_name,
+ dp64->d_reclen - offsetof (struct dirent64, d_name));
+
+ return true;
@@ -230,7 +218,7 @@ index bbe247f95d..01e834e238 100644
if (bytes <= 0)
{
/* Linux may fail with ENOENT on some file systems if the
-@@ -127,17 +158,24 @@ __old_readdir64_unlocked (DIR *dirp)
+@@ -127,17 +149,21 @@ __old_readdir64_unlocked (DIR *dirp)
__set_errno (saved_errno);
return NULL;
}
@@ -251,15 +239,12 @@ index bbe247f95d..01e834e238 100644
+ /* Skip entries which might overflow d_ino or for memory allocation failure
+ in case of large file names. */
+ if (dirstream_old_entry (dirp, dp64))
-+ {
-+ dirp->filepos = dp64->d_off;
-+ return (struct __old_dirent64 *) dirp->tbuffer;
-+ }
++ return &dirp->tdp64;
+
+ return NULL;
}
attribute_compat_text_section
--
-2.38.2
+2.39.1