1 |
commit: 4e94f64bd9462f55e52de64d1c49b20cdfc686a3 |
2 |
Author: Andreas K. Hüttel <dilfridge <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Feb 1 19:44:39 2023 +0000 |
4 |
Commit: Andreas K. Hüttel <dilfridge <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Feb 1 19:44:39 2023 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/toolchain/glibc-patches.git/commit/?id=4e94f64b |
7 |
|
8 |
Update dirent-related patchset from libc-alpha archive (v5) |
9 |
|
10 |
Signed-off-by: Andreas K. Hüttel <dilfridge <AT> gentoo.org> |
11 |
|
12 |
9999/0001-Disable-ldconfig-during-install.patch | 8 +- |
13 |
...Adapt-to-Gentoo-specific-etc-mail-aliases.patch | 12 +- |
14 |
...O0-in-conform-tests-to-survive-CC-changes.patch | 10 +- |
15 |
.../0004-Fix-miscompilation-on-ia64-s-gcc-10.patch | 8 +- |
16 |
...5-linux-Use-getdents64-on-non-LFS-readdir.patch | 190 +++---- |
17 |
...nternal-DIR-filepos-as-off64_t-BZ-23960-B.patch | 616 +++++++++++---------- |
18 |
9999/0007-linux-Add-__readdir64_unlocked.patch | 14 +- |
19 |
9999/0008-linux-Add-__old_readdir64_unlocked.patch | 14 +- |
20 |
...etdents64-on-readdir64-compat-implementat.patch | 123 ++-- |
21 |
9999/0010-dirent-Deprecate-getdirentries.patch | 100 ---- |
22 |
10 files changed, 500 insertions(+), 595 deletions(-) |
23 |
|
24 |
diff --git a/9999/0001-Disable-ldconfig-during-install.patch b/9999/0001-Disable-ldconfig-during-install.patch |
25 |
index 4a8c771..e947fac 100644 |
26 |
--- a/9999/0001-Disable-ldconfig-during-install.patch |
27 |
+++ b/9999/0001-Disable-ldconfig-during-install.patch |
28 |
@@ -1,7 +1,7 @@ |
29 |
-From 5349895a928bff28939b228824c8265d20d9fa60 Mon Sep 17 00:00:00 2001 |
30 |
+From 3b59ad9dec2c1c7f1b4c7f72d14ea3f2b68a4eca Mon Sep 17 00:00:00 2001 |
31 |
From: Mike Frysinger <vapier@g.o> |
32 |
Date: Tue, 3 Aug 2021 00:34:59 +0200 |
33 |
-Subject: [PATCH 01/10] Disable ldconfig during install |
34 |
+Subject: [PATCH 1/9] Disable ldconfig during install |
35 |
MIME-Version: 1.0 |
36 |
Content-Type: text/plain; charset=UTF-8 |
37 |
Content-Transfer-Encoding: 8bit |
38 |
@@ -19,7 +19,7 @@ Signed-off-by: Andreas K. Hüttel <dilfridge@g.o> |
39 |
1 file changed, 1 insertion(+) |
40 |
|
41 |
diff --git a/Makefile b/Makefile |
42 |
-index 179dd478ff..763d6a084a 100644 |
43 |
+index 224c792185..be9df042e0 100644 |
44 |
--- a/Makefile |
45 |
+++ b/Makefile |
46 |
@@ -110,6 +110,7 @@ elf/ldso_install: |
47 |
@@ -31,5 +31,5 @@ index 179dd478ff..763d6a084a 100644 |
48 |
$(elf-objpfx)ldconfig $(addprefix -r ,$(install_root)) \ |
49 |
$(slibdir) $(libdir) |
50 |
-- |
51 |
-2.38.2 |
52 |
+2.39.1 |
53 |
|
54 |
|
55 |
diff --git a/9999/0002-Adapt-to-Gentoo-specific-etc-mail-aliases.patch b/9999/0002-Adapt-to-Gentoo-specific-etc-mail-aliases.patch |
56 |
index 559e736..09c2dde 100644 |
57 |
--- a/9999/0002-Adapt-to-Gentoo-specific-etc-mail-aliases.patch |
58 |
+++ b/9999/0002-Adapt-to-Gentoo-specific-etc-mail-aliases.patch |
59 |
@@ -1,7 +1,7 @@ |
60 |
-From ab1ca71990a972e375709711f5fa268010505324 Mon Sep 17 00:00:00 2001 |
61 |
+From d8a45f4bfa30b502647a9ef742836c7e8694d009 Mon Sep 17 00:00:00 2001 |
62 |
From: =?UTF-8?q?Andreas=20K=2E=20H=C3=BCttel?= <dilfridge@g.o> |
63 |
Date: Mon, 22 Oct 2018 22:34:13 +0200 |
64 |
-Subject: [PATCH 02/10] Adapt to Gentoo-specific /etc/mail/aliases |
65 |
+Subject: [PATCH 2/9] Adapt to Gentoo-specific /etc/mail/aliases |
66 |
MIME-Version: 1.0 |
67 |
Content-Type: text/plain; charset=UTF-8 |
68 |
Content-Transfer-Encoding: 8bit |
69 |
@@ -18,7 +18,7 @@ Signed-off-by: Andreas K. Hüttel <dilfridge@g.o> |
70 |
3 files changed, 17 insertions(+), 11 deletions(-) |
71 |
|
72 |
diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c |
73 |
-index 505721388f..44d835cace 100644 |
74 |
+index 1c32884fe7..f40fd19288 100644 |
75 |
--- a/nss/nss_files/files-alias.c |
76 |
+++ b/nss/nss_files/files-alias.c |
77 |
@@ -42,7 +42,7 @@ internal_setent (FILE **stream) |
78 |
@@ -31,7 +31,7 @@ index 505721388f..44d835cace 100644 |
79 |
if (*stream == NULL) |
80 |
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; |
81 |
diff --git a/nss/tst-nss-files-alias-leak.c b/nss/tst-nss-files-alias-leak.c |
82 |
-index 576f07fa0a..29962764e2 100644 |
83 |
+index a62e137614..f0cd132ce6 100644 |
84 |
--- a/nss/tst-nss-files-alias-leak.c |
85 |
+++ b/nss/tst-nss-files-alias-leak.c |
86 |
@@ -45,27 +45,27 @@ prepare (int argc, char **argv) |
87 |
@@ -80,7 +80,7 @@ index 576f07fa0a..29962764e2 100644 |
88 |
FILE *fp = xfopen (path, "w"); |
89 |
for (int i = 0; i < many_aliases; ++i) |
90 |
diff --git a/support/support_chroot.c b/support/support_chroot.c |
91 |
-index 4bf6fe0834..1548eba2ad 100644 |
92 |
+index 7a1b7272f0..500c9a79a3 100644 |
93 |
--- a/support/support_chroot.c |
94 |
+++ b/support/support_chroot.c |
95 |
@@ -52,13 +52,19 @@ support_chroot_create (struct support_chroot_configuration conf) |
96 |
@@ -105,5 +105,5 @@ index 4bf6fe0834..1548eba2ad 100644 |
97 |
/* valgrind needs a temporary directory in the chroot. */ |
98 |
{ |
99 |
-- |
100 |
-2.38.2 |
101 |
+2.39.1 |
102 |
|
103 |
|
104 |
diff --git a/9999/0003-Force-O0-in-conform-tests-to-survive-CC-changes.patch b/9999/0003-Force-O0-in-conform-tests-to-survive-CC-changes.patch |
105 |
index f662cda..ac36f58 100644 |
106 |
--- a/9999/0003-Force-O0-in-conform-tests-to-survive-CC-changes.patch |
107 |
+++ b/9999/0003-Force-O0-in-conform-tests-to-survive-CC-changes.patch |
108 |
@@ -1,7 +1,7 @@ |
109 |
-From f44c6c3768c2a3ef274782a2e308fb6b8fe84499 Mon Sep 17 00:00:00 2001 |
110 |
+From d2b4275295e9c5a312063c3bce663ae1dcf754f0 Mon Sep 17 00:00:00 2001 |
111 |
From: =?UTF-8?q?Andreas=20K=2E=20H=C3=BCttel?= <dilfridge@g.o> |
112 |
Date: Fri, 14 Dec 2018 20:43:04 +0100 |
113 |
-Subject: [PATCH 03/10] Force -O0 in conform tests to survive $CC changes |
114 |
+Subject: [PATCH 3/9] Force -O0 in conform tests to survive $CC changes |
115 |
MIME-Version: 1.0 |
116 |
Content-Type: text/plain; charset=UTF-8 |
117 |
Content-Transfer-Encoding: 8bit |
118 |
@@ -22,7 +22,7 @@ Signed-off-by: Andreas K. Hüttel <dilfridge@g.o> |
119 |
2 files changed, 7 insertions(+), 3 deletions(-) |
120 |
|
121 |
diff --git a/conform/conformtest.py b/conform/conformtest.py |
122 |
-index 94a7ee110f..90c81ac88e 100644 |
123 |
+index 124860da01..8b1643a097 100644 |
124 |
--- a/conform/conformtest.py |
125 |
+++ b/conform/conformtest.py |
126 |
@@ -566,7 +566,7 @@ class HeaderTests(object): |
127 |
@@ -46,7 +46,7 @@ index 94a7ee110f..90c81ac88e 100644 |
128 |
subprocess.check_call(cmd, shell=True) |
129 |
bad_tokens = set() |
130 |
diff --git a/conform/linknamespace.py b/conform/linknamespace.py |
131 |
-index f7fe3a7a0a..ad87fd2a6d 100644 |
132 |
+index 983bba1bd2..b6fce8a21c 100644 |
133 |
--- a/conform/linknamespace.py |
134 |
+++ b/conform/linknamespace.py |
135 |
@@ -157,7 +157,9 @@ def main(): |
136 |
@@ -61,5 +61,5 @@ index f7fe3a7a0a..ad87fd2a6d 100644 |
137 |
args.header) |
138 |
with tempfile.TemporaryDirectory() as temp_dir: |
139 |
-- |
140 |
-2.38.2 |
141 |
+2.39.1 |
142 |
|
143 |
|
144 |
diff --git a/9999/0004-Fix-miscompilation-on-ia64-s-gcc-10.patch b/9999/0004-Fix-miscompilation-on-ia64-s-gcc-10.patch |
145 |
index 2d9c8f7..215b5fa 100644 |
146 |
--- a/9999/0004-Fix-miscompilation-on-ia64-s-gcc-10.patch |
147 |
+++ b/9999/0004-Fix-miscompilation-on-ia64-s-gcc-10.patch |
148 |
@@ -1,7 +1,7 @@ |
149 |
-From 4aafe3fae7777fec09e2dd3915a8fd33642bba94 Mon Sep 17 00:00:00 2001 |
150 |
+From 7a2ab3f8d680338aff2559541a4bb748618e16f6 Mon Sep 17 00:00:00 2001 |
151 |
From: Sergei Trofimovich <slyfox@g.o> |
152 |
Date: Sat, 11 Jul 2020 20:06:51 +0300 |
153 |
-Subject: [PATCH 04/10] Fix miscompilation on ia64's gcc-10 |
154 |
+Subject: [PATCH 4/9] Fix miscompilation on ia64's gcc-10 |
155 |
MIME-Version: 1.0 |
156 |
Content-Type: text/plain; charset=UTF-8 |
157 |
Content-Transfer-Encoding: 8bit |
158 |
@@ -13,7 +13,7 @@ Signed-off-by: Andreas K. Hüttel <dilfridge@g.o> |
159 |
1 file changed, 3 insertions(+), 1 deletion(-) |
160 |
|
161 |
diff --git a/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h b/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h |
162 |
-index aa1de6b361..f6472f1942 100644 |
163 |
+index 3e4d5da820..eb7681b704 100644 |
164 |
--- a/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h |
165 |
+++ b/sysdeps/unix/sysv/linux/ia64/dl-sysdep.h |
166 |
@@ -32,7 +32,9 @@ |
167 |
@@ -28,5 +28,5 @@ index aa1de6b361..f6472f1942 100644 |
168 |
# define DL_SYSINFO_IMPLEMENTATION \ |
169 |
asm (".text\n\t" \ |
170 |
-- |
171 |
-2.38.2 |
172 |
+2.39.1 |
173 |
|
174 |
|
175 |
diff --git a/9999/0005-linux-Use-getdents64-on-non-LFS-readdir.patch b/9999/0005-linux-Use-getdents64-on-non-LFS-readdir.patch |
176 |
index 4e1dc0d..4cb21bf 100644 |
177 |
--- a/9999/0005-linux-Use-getdents64-on-non-LFS-readdir.patch |
178 |
+++ b/9999/0005-linux-Use-getdents64-on-non-LFS-readdir.patch |
179 |
@@ -1,127 +1,109 @@ |
180 |
-From 0718c1ca37fe6407bd4bad15dfae873719eabb6e Mon Sep 17 00:00:00 2001 |
181 |
+From 1652c61d24e43a0efd1fd4812f4a67494d093cc2 Mon Sep 17 00:00:00 2001 |
182 |
From: Adhemerval Zanella <adhemerval.zanella@××××××.org> |
183 |
-Date: Tue, 20 Oct 2020 13:37:15 -0300 |
184 |
-Subject: [PATCH 05/10] linux: Use getdents64 on non-LFS readdir |
185 |
+Date: Fri, 27 Jan 2023 14:28:30 -0300 |
186 |
+Subject: [PATCH 5/9] linux: Use getdents64 on non-LFS readdir |
187 |
|
188 |
-The opendir allocates a translation buffer to be used to return the |
189 |
-non-LFS readdir entry. The obtained dirent64 struct is translated |
190 |
-to the temporary buffer on each readdir call. |
191 |
+The non-LFS opendir reserves a translation entry to be used to return |
192 |
+the entry and the dirent64 struct is translated to the temporary buffer |
193 |
+on each readdir call. |
194 |
|
195 |
Entries that overflow d_off/d_ino and the buffer reallocation failure |
196 |
(in case of large d_name) are ignored. |
197 |
|
198 |
Checked on x86_64-linux-gnu and i686-linux-gnu. |
199 |
--- |
200 |
- sysdeps/unix/sysv/linux/closedir.c | 4 ++ |
201 |
+ dirent/tst-scandir.c | 6 ++- |
202 |
+ include/dirent.h | 2 +- |
203 |
sysdeps/unix/sysv/linux/dirstream.h | 5 ++ |
204 |
- sysdeps/unix/sysv/linux/opendir.c | 21 +++++++ |
205 |
- sysdeps/unix/sysv/linux/readdir.c | 94 +++++++++++++++++++++-------- |
206 |
- 4 files changed, 98 insertions(+), 26 deletions(-) |
207 |
+ sysdeps/unix/sysv/linux/readdir.c | 83 +++++++++++++++++++---------- |
208 |
+ 4 files changed, 67 insertions(+), 29 deletions(-) |
209 |
|
210 |
-diff --git a/sysdeps/unix/sysv/linux/closedir.c b/sysdeps/unix/sysv/linux/closedir.c |
211 |
-index eee0193fc4..d876d49d78 100644 |
212 |
---- a/sysdeps/unix/sysv/linux/closedir.c |
213 |
-+++ b/sysdeps/unix/sysv/linux/closedir.c |
214 |
-@@ -47,6 +47,10 @@ __closedir (DIR *dirp) |
215 |
- __libc_lock_fini (dirp->lock); |
216 |
- #endif |
217 |
- |
218 |
-+#if !_DIRENT_MATCHES_DIRENT64 |
219 |
-+ free (dirp->tbuffer); |
220 |
-+#endif |
221 |
-+ |
222 |
- free ((void *) dirp); |
223 |
+diff --git a/dirent/tst-scandir.c b/dirent/tst-scandir.c |
224 |
+index 8d87d4dd74..7bc666449e 100644 |
225 |
+--- a/dirent/tst-scandir.c |
226 |
++++ b/dirent/tst-scandir.c |
227 |
+@@ -155,8 +155,12 @@ do_test (void) |
228 |
+ } |
229 |
+ if (n != 6) |
230 |
+ { |
231 |
++ /* Non-lfs opendir skips entries that can not be represented (for |
232 |
++ instance if d_off is not an offset but rather an internal filesystem |
233 |
++ representation. For this case there is no point in continue the |
234 |
++ testcase. */ |
235 |
+ printf ("scandir returned %d entries instead of 6\n", n); |
236 |
+- return 1; |
237 |
++ return EXIT_UNSUPPORTED; |
238 |
+ } |
239 |
|
240 |
- return __close_nocancel (fd); |
241 |
+ struct |
242 |
+diff --git a/include/dirent.h b/include/dirent.h |
243 |
+index d7567f5e86..17827176ba 100644 |
244 |
+--- a/include/dirent.h |
245 |
++++ b/include/dirent.h |
246 |
+@@ -1,8 +1,8 @@ |
247 |
+ #ifndef _DIRENT_H |
248 |
++# include <dirent/dirent.h> |
249 |
+ # ifndef _ISOMAC |
250 |
+ # include <dirstream.h> |
251 |
+ # endif |
252 |
+-# include <dirent/dirent.h> |
253 |
+ # ifndef _ISOMAC |
254 |
+ # include <sys/stat.h> |
255 |
+ # include <stdbool.h> |
256 |
diff --git a/sysdeps/unix/sysv/linux/dirstream.h b/sysdeps/unix/sysv/linux/dirstream.h |
257 |
-index a0d8acf08d..064273cc31 100644 |
258 |
+index 3cb313b410..adcf8234f1 100644 |
259 |
--- a/sysdeps/unix/sysv/linux/dirstream.h |
260 |
+++ b/sysdeps/unix/sysv/linux/dirstream.h |
261 |
-@@ -41,6 +41,11 @@ struct __dirstream |
262 |
+@@ -18,6 +18,7 @@ |
263 |
+ #ifndef _DIRSTREAM_H |
264 |
+ #define _DIRSTREAM_H 1 |
265 |
+ |
266 |
++#include <dirent.h> |
267 |
+ #include <sys/types.h> |
268 |
+ |
269 |
+ #include <libc-lock.h> |
270 |
+@@ -41,6 +42,10 @@ struct __dirstream |
271 |
|
272 |
int errcode; /* Delayed error code. */ |
273 |
|
274 |
+#if !defined __OFF_T_MATCHES_OFF64_T || !defined __INO_T_MATCHES_INO64_T |
275 |
-+ char *tbuffer; /* Translation buffer for non-LFS calls. */ |
276 |
-+ size_t tbuffer_size; /* Size of translation buffer. */ |
277 |
++ struct dirent tdp; |
278 |
+#endif |
279 |
+ |
280 |
/* Directory block. We must make sure that this block starts |
281 |
at an address that is aligned adequately enough to store |
282 |
dirent entries. Using the alignment of "void *" is not |
283 |
-diff --git a/sysdeps/unix/sysv/linux/opendir.c b/sysdeps/unix/sysv/linux/opendir.c |
284 |
-index 9e81d00630..bfd2f382a6 100644 |
285 |
---- a/sysdeps/unix/sysv/linux/opendir.c |
286 |
-+++ b/sysdeps/unix/sysv/linux/opendir.c |
287 |
-@@ -120,6 +120,27 @@ __alloc_dir (int fd, bool close_fd, int flags, |
288 |
- return NULL; |
289 |
- } |
290 |
- |
291 |
-+#if !_DIRENT_MATCHES_DIRENT64 |
292 |
-+ /* Allocates a translation buffer to use as the returned 'struct direct' |
293 |
-+ for non-LFS 'readdir' calls. |
294 |
-+ |
295 |
-+ The initial NAME_MAX size should handle most cases, while readdir might |
296 |
-+ expand the buffer if required. */ |
297 |
-+ enum |
298 |
-+ { |
299 |
-+ tbuffer_size = sizeof (struct dirent) + NAME_MAX + 1 |
300 |
-+ }; |
301 |
-+ dirp->tbuffer = malloc (tbuffer_size); |
302 |
-+ if (dirp->tbuffer == NULL) |
303 |
-+ { |
304 |
-+ free (dirp); |
305 |
-+ if (close_fd) |
306 |
-+ __close_nocancel_nostatus (fd); |
307 |
-+ return NULL; |
308 |
-+ } |
309 |
-+ dirp->tbuffer_size = tbuffer_size; |
310 |
-+#endif |
311 |
-+ |
312 |
- dirp->fd = fd; |
313 |
- #if IS_IN (libc) |
314 |
- __libc_lock_init (dirp->lock); |
315 |
diff --git a/sysdeps/unix/sysv/linux/readdir.c b/sysdeps/unix/sysv/linux/readdir.c |
316 |
-index c9a04dc160..c078146d7d 100644 |
317 |
+index 4a4c00ea07..cd0ccaf33a 100644 |
318 |
--- a/sysdeps/unix/sysv/linux/readdir.c |
319 |
+++ b/sysdeps/unix/sysv/linux/readdir.c |
320 |
-@@ -21,42 +21,84 @@ |
321 |
+@@ -21,42 +21,71 @@ |
322 |
#if !_DIRENT_MATCHES_DIRENT64 |
323 |
#include <dirstream.h> |
324 |
|
325 |
-+/* Translate the DP64 entry to the non-LFS one in the translation buffer |
326 |
++/* Translate the DP64 entry to the non-LFS one in the translation entry |
327 |
+ at dirstream DS. Return true is the translation was possible or |
328 |
-+ false if either an internal fields can be represented in the non-LFS |
329 |
-+ entry or if the translation can not be resized. */ |
330 |
++ false if either an internal field can not be represented in the non-LFS |
331 |
++ entry or if the name is too long. */ |
332 |
+static bool |
333 |
+dirstream_entry (struct __dirstream *ds, const struct dirent64 *dp64) |
334 |
+{ |
335 |
-+ off_t d_off = dp64->d_off; |
336 |
-+ if (d_off != dp64->d_off) |
337 |
-+ return false; |
338 |
-+ ino_t d_ino = dp64->d_ino; |
339 |
-+ if (d_ino != dp64->d_ino) |
340 |
++ /* Check for overflow. */ |
341 |
++ if (!in_off_t_range (dp64->d_off) || !in_ino_t_range (dp64->d_ino)) |
342 |
+ return false; |
343 |
+ |
344 |
-+ /* Expand the translation buffer to hold the new name size. */ |
345 |
-+ size_t new_reclen = sizeof (struct dirent) |
346 |
-+ + dp64->d_reclen - offsetof (struct dirent64, d_name); |
347 |
-+ if (new_reclen > ds->tbuffer_size) |
348 |
-+ { |
349 |
-+ char *newbuffer = realloc (ds->tbuffer, new_reclen); |
350 |
-+ if (newbuffer == NULL) |
351 |
-+ return false; |
352 |
-+ ds->tbuffer = newbuffer; |
353 |
-+ ds->tbuffer_size = new_reclen; |
354 |
-+ } |
355 |
++ /* And if name is too large. */ |
356 |
++ if (dp64->d_reclen - offsetof (struct dirent64, d_name) > NAME_MAX) |
357 |
++ return false; |
358 |
+ |
359 |
-+ struct dirent *dp = (struct dirent *) ds->tbuffer; |
360 |
++ ds->filepos = dp64->d_off; |
361 |
+ |
362 |
-+ dp->d_off = d_off; |
363 |
-+ dp->d_ino = d_ino; |
364 |
-+ dp->d_reclen = new_reclen; |
365 |
-+ dp->d_type = dp64->d_type; |
366 |
-+ memcpy (dp->d_name, dp64->d_name, |
367 |
++ ds->tdp.d_off = dp64->d_off; |
368 |
++ ds->tdp.d_ino = dp64->d_ino; |
369 |
++ ds->tdp.d_reclen = sizeof (struct dirent) |
370 |
++ + dp64->d_reclen - offsetof (struct dirent64, d_name); |
371 |
++ ds->tdp.d_type = dp64->d_type; |
372 |
++ memcpy (ds->tdp.d_name, dp64->d_name, |
373 |
+ dp64->d_reclen - offsetof (struct dirent64, d_name)); |
374 |
+ |
375 |
+ return true; |
376 |
@@ -145,7 +127,19 @@ index c9a04dc160..c078146d7d 100644 |
377 |
- bytes = __getdents (dirp->fd, dirp->data, maxread); |
378 |
- if (bytes <= 0) |
379 |
+ if (dirp->offset >= dirp->size) |
380 |
-+ { |
381 |
+ { |
382 |
+- /* Linux may fail with ENOENT on some file systems if the |
383 |
+- directory inode is marked as dead (deleted). POSIX |
384 |
+- treats this as a regular end-of-directory condition, so |
385 |
+- do not set errno in that case, to indicate success. */ |
386 |
+- if (bytes == 0 || errno == ENOENT) |
387 |
+- __set_errno (saved_errno); |
388 |
+- return NULL; |
389 |
+- } |
390 |
+- dirp->size = (size_t) bytes; |
391 |
+- |
392 |
+- /* Reset the offset into the buffer. */ |
393 |
+- dirp->offset = 0; |
394 |
+ /* We've emptied out our buffer. Refill it. */ |
395 |
+ ssize_t bytes = __getdents64 (dirp->fd, dirp->data, |
396 |
+ dirp->allocation); |
397 |
@@ -169,23 +163,9 @@ index c9a04dc160..c078146d7d 100644 |
398 |
+ dirp->offset += dp64->d_reclen; |
399 |
+ |
400 |
+ /* Skip entries which might overflow d_off/d_ino or if the translation |
401 |
-+ buffer can't be resized. */ |
402 |
++ buffer can not be resized. */ |
403 |
+ if (dirstream_entry (dirp, dp64)) |
404 |
- { |
405 |
-- /* Linux may fail with ENOENT on some file systems if the |
406 |
-- directory inode is marked as dead (deleted). POSIX |
407 |
-- treats this as a regular end-of-directory condition, so |
408 |
-- do not set errno in that case, to indicate success. */ |
409 |
-- if (bytes == 0 || errno == ENOENT) |
410 |
-- __set_errno (saved_errno); |
411 |
-- return NULL; |
412 |
-+ dirp->filepos = dp64->d_off; |
413 |
-+ return (struct dirent *) dirp->tbuffer; |
414 |
- } |
415 |
-- dirp->size = (size_t) bytes; |
416 |
-- |
417 |
-- /* Reset the offset into the buffer. */ |
418 |
-- dirp->offset = 0; |
419 |
++ return &dirp->tdp; |
420 |
} |
421 |
- |
422 |
- dp = (struct dirent *) &dirp->data[dirp->offset]; |
423 |
@@ -197,5 +177,5 @@ index c9a04dc160..c078146d7d 100644 |
424 |
|
425 |
struct dirent * |
426 |
-- |
427 |
-2.38.2 |
428 |
+2.39.1 |
429 |
|
430 |
|
431 |
diff --git a/9999/0006-linux-Set-internal-DIR-filepos-as-off64_t-BZ-23960-B.patch b/9999/0006-linux-Set-internal-DIR-filepos-as-off64_t-BZ-23960-B.patch |
432 |
index 38acaf8..59e01fc 100644 |
433 |
--- a/9999/0006-linux-Set-internal-DIR-filepos-as-off64_t-BZ-23960-B.patch |
434 |
+++ b/9999/0006-linux-Set-internal-DIR-filepos-as-off64_t-BZ-23960-B.patch |
435 |
@@ -1,240 +1,121 @@ |
436 |
-From 36f553f67b8268341b7879640637fac5ea806017 Mon Sep 17 00:00:00 2001 |
437 |
+From 861793671bd8daeed1f00902d9a9523ddae77462 Mon Sep 17 00:00:00 2001 |
438 |
From: Adhemerval Zanella <adhemerval.zanella@××××××.org> |
439 |
-Date: Mon, 13 Apr 2020 18:09:20 -0300 |
440 |
-Subject: [PATCH 06/10] linux: Set internal DIR filepos as off64_t [BZ #23960, |
441 |
- BZ #24050] |
442 |
+Date: Fri, 27 Jan 2023 14:28:31 -0300 |
443 |
+Subject: [PATCH 6/9] linux: Set internal DIR filepos as off64_t (BZ #23960, BZ |
444 |
+ #24050) |
445 |
|
446 |
It allows to obtain the expected entry offset on telldir and set |
447 |
it correctly on seekdir on platforms where long int is smaller |
448 |
than off64_t. |
449 |
|
450 |
-On such cases telldir will mantain an internal list that maps the |
451 |
-DIR object off64_t offsets to the returned long int (the function |
452 |
-return value). The seekdir will then set the correct offset from |
453 |
-the internal list using the telldir as the list key. |
454 |
+On such cases opendir creates a map entry between the DIR d_off |
455 |
+offset and the returned long int (the telldir return value). |
456 |
+seekdir will then set the correct offset from the internal list |
457 |
+using the telldir as the list key. |
458 |
|
459 |
It also removes the overflow check on readdir and the returned value |
460 |
will be truncated by the non-LFS off_t size. As Joseph has noted |
461 |
in BZ #23960 comment #22, d_off is an opaque value and since |
462 |
telldir/seekdir works regardless of the returned dirent d_off value. |
463 |
|
464 |
-Finally it removed the requirement to check for overflow values on |
465 |
+Finally it removes the requirement to check for overflow values on |
466 |
telldir (BZ #24050). |
467 |
|
468 |
Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc-linux-gnu, |
469 |
and arm-linux-gnueabihf. |
470 |
--- |
471 |
- dirent/Makefile | 2 +- |
472 |
- dirent/tst-seekdir2.c | 158 ++++++++++++++++++++++++++++ |
473 |
- sysdeps/unix/sysv/linux/closedir.c | 4 + |
474 |
- sysdeps/unix/sysv/linux/dirstream.h | 6 +- |
475 |
- sysdeps/unix/sysv/linux/opendir.c | 3 + |
476 |
- sysdeps/unix/sysv/linux/readdir.c | 1 + |
477 |
- sysdeps/unix/sysv/linux/rewinddir.c | 5 + |
478 |
- sysdeps/unix/sysv/linux/seekdir.c | 36 ++++++- |
479 |
- sysdeps/unix/sysv/linux/telldir.c | 47 ++++++++- |
480 |
- sysdeps/unix/sysv/linux/telldir.h | 64 +++++++++++ |
481 |
- 10 files changed, 317 insertions(+), 9 deletions(-) |
482 |
- create mode 100644 dirent/tst-seekdir2.c |
483 |
+ dirent/tst-seekdir.c | 8 ++ |
484 |
+ sysdeps/unix/sysv/linux/Makefile | 1 + |
485 |
+ sysdeps/unix/sysv/linux/alpha/bits/dirent.h | 3 + |
486 |
+ sysdeps/unix/sysv/linux/bits/dirent.h | 4 + |
487 |
+ sysdeps/unix/sysv/linux/closedir.c | 4 + |
488 |
+ sysdeps/unix/sysv/linux/dirstream.h | 6 +- |
489 |
+ sysdeps/unix/sysv/linux/opendir.c | 3 + |
490 |
+ sysdeps/unix/sysv/linux/readdir.c | 11 +- |
491 |
+ sysdeps/unix/sysv/linux/rewinddir.c | 5 + |
492 |
+ sysdeps/unix/sysv/linux/seekdir.c | 35 ++++- |
493 |
+ sysdeps/unix/sysv/linux/telldir.c | 35 +++++ |
494 |
+ sysdeps/unix/sysv/linux/telldir.h | 65 +++++++++ |
495 |
+ sysdeps/unix/sysv/linux/tst-opendir-nolfs.c | 146 ++++++++++++++++++++ |
496 |
+ 13 files changed, 319 insertions(+), 7 deletions(-) |
497 |
create mode 100644 sysdeps/unix/sysv/linux/telldir.h |
498 |
+ create mode 100644 sysdeps/unix/sysv/linux/tst-opendir-nolfs.c |
499 |
|
500 |
-diff --git a/dirent/Makefile b/dirent/Makefile |
501 |
-index cfa61826ed..9a9d91b8a5 100644 |
502 |
---- a/dirent/Makefile |
503 |
-+++ b/dirent/Makefile |
504 |
-@@ -31,7 +31,7 @@ routines := opendir closedir readdir readdir_r rewinddir \ |
505 |
- scandir-cancel scandir-tail scandir64-tail |
506 |
- |
507 |
- tests := list tst-seekdir opendir-tst1 bug-readdir1 tst-fdopendir \ |
508 |
-- tst-fdopendir2 tst-scandir tst-scandir64 |
509 |
-+ tst-fdopendir2 tst-scandir tst-scandir64 tst-seekdir2 |
510 |
- |
511 |
- CFLAGS-scandir.c += $(uses-callbacks) |
512 |
- CFLAGS-scandir64.c += $(uses-callbacks) |
513 |
-diff --git a/dirent/tst-seekdir2.c b/dirent/tst-seekdir2.c |
514 |
-new file mode 100644 |
515 |
-index 0000000000..3e01b361e5 |
516 |
---- /dev/null |
517 |
-+++ b/dirent/tst-seekdir2.c |
518 |
-@@ -0,0 +1,158 @@ |
519 |
-+/* Check multiple telldir and seekdir. |
520 |
-+ Copyright (C) 2020 Free Software Foundation, Inc. |
521 |
-+ This file is part of the GNU C Library. |
522 |
-+ |
523 |
-+ The GNU C Library is free software; you can redistribute it and/or |
524 |
-+ modify it under the terms of the GNU Lesser General Public |
525 |
-+ License as published by the Free Software Foundation; either |
526 |
-+ version 2.1 of the License, or (at your option) any later version. |
527 |
-+ |
528 |
-+ The GNU C Library is distributed in the hope that it will be useful, |
529 |
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
530 |
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
531 |
-+ Lesser General Public License for more details. |
532 |
-+ |
533 |
-+ You should have received a copy of the GNU Lesser General Public |
534 |
-+ License along with the GNU C Library; if not, see |
535 |
-+ <https://www.gnu.org/licenses/>. */ |
536 |
-+ |
537 |
-+#include <dirent.h> |
538 |
-+#include <stdlib.h> |
539 |
-+#include <unistd.h> |
540 |
-+#include <stdio.h> |
541 |
-+#include <string.h> |
542 |
-+ |
543 |
-+#include <support/temp_file.h> |
544 |
-+#include <support/support.h> |
545 |
-+#include <support/check.h> |
546 |
-+ |
547 |
-+/* Some filesystems returns a arbitrary value for d_off direnty entry (ext4 |
548 |
-+ for instance, where the value is an internal hash key). The idea of |
549 |
-+ create a large number of file is to try trigger a overflow d_off value |
550 |
-+ in a entry to check if telldir/seekdir does work corretly in such |
551 |
-+ case. */ |
552 |
-+static const char *dirname; |
553 |
-+static const size_t nfiles = 10240; |
554 |
-+ |
555 |
-+static void |
556 |
-+do_prepare (int argc, char *argv[]) |
557 |
-+{ |
558 |
-+ dirname = support_create_temp_directory ("tst-seekdir2-"); |
559 |
-+ |
560 |
-+ for (size_t i = 0; i < nfiles; i++) |
561 |
+diff --git a/dirent/tst-seekdir.c b/dirent/tst-seekdir.c |
562 |
+index dcdd699b09..187eda7584 100644 |
563 |
+--- a/dirent/tst-seekdir.c |
564 |
++++ b/dirent/tst-seekdir.c |
565 |
+@@ -41,6 +41,14 @@ do_test (void) |
566 |
+ if (i == 400) |
567 |
+ break; |
568 |
+ } |
569 |
++ if (i < 3) |
570 |
+ { |
571 |
-+ int fd = create_temp_file_in_dir ("tempfile.", dirname, NULL); |
572 |
-+ TEST_VERIFY_EXIT (fd > 0); |
573 |
-+ close (fd); |
574 |
-+ } |
575 |
-+} |
576 |
-+#define PREPARE do_prepare |
577 |
-+ |
578 |
-+/* Check for old non Large File Support (LFS). */ |
579 |
-+static int |
580 |
-+do_test_not_lfs (void) |
581 |
-+{ |
582 |
-+ DIR *dirp = opendir (dirname); |
583 |
-+ TEST_VERIFY_EXIT (dirp != NULL); |
584 |
-+ |
585 |
-+ size_t dirp_count = 0; |
586 |
-+ for (struct dirent *dp = readdir (dirp); |
587 |
-+ dp != NULL; |
588 |
-+ dp = readdir (dirp)) |
589 |
-+ dirp_count++; |
590 |
-+ |
591 |
-+ /* The 2 extra files are '.' and '..'. */ |
592 |
-+ TEST_COMPARE (dirp_count, nfiles + 2); |
593 |
-+ |
594 |
-+ rewinddir (dirp); |
595 |
-+ |
596 |
-+ long *tdirp = xmalloc (dirp_count * sizeof (long)); |
597 |
-+ struct dirent **ddirp = xmalloc (dirp_count * sizeof (struct dirent *)); |
598 |
-+ |
599 |
-+ size_t i = 0; |
600 |
-+ do |
601 |
-+ { |
602 |
-+ tdirp[i] = telldir (dirp); |
603 |
-+ struct dirent *dp = readdir (dirp); |
604 |
-+ TEST_VERIFY_EXIT (dp != NULL); |
605 |
-+ ddirp[i] = xmalloc (dp->d_reclen); |
606 |
-+ memcpy (ddirp[i], dp, dp->d_reclen); |
607 |
-+ } while (++i < dirp_count); |
608 |
-+ |
609 |
-+ for (i = 0; i < dirp_count - 1; i++) |
610 |
-+ { |
611 |
-+ seekdir (dirp, tdirp[i]); |
612 |
-+ struct dirent *dp = readdir (dirp); |
613 |
-+ TEST_COMPARE (strcmp (dp->d_name, ddirp[i]->d_name), 0); |
614 |
-+ TEST_COMPARE (dp->d_ino, ddirp[i]->d_ino); |
615 |
-+ TEST_COMPARE (dp->d_off, ddirp[i]->d_off); |
616 |
++ /* Non-lfs opendir skips entries that can not be represented (for |
617 |
++ instance if d_off is not an offset but rather an internal filesystem |
618 |
++ representation. For this case there is no point in continue the |
619 |
++ testcase. */ |
620 |
++ return 77; |
621 |
+ } |
622 |
+ |
623 |
+ printf ("going back past 4-th entry...\n"); |
624 |
+ |
625 |
+diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile |
626 |
+index f8bd12d991..09adb99b86 100644 |
627 |
+--- a/sysdeps/unix/sysv/linux/Makefile |
628 |
++++ b/sysdeps/unix/sysv/linux/Makefile |
629 |
+@@ -464,6 +464,7 @@ ifeq ($(subdir),dirent) |
630 |
+ sysdep_routines += getdirentries getdirentries64 |
631 |
+ tests += \ |
632 |
+ tst-getdents64 \ |
633 |
++ tst-opendir-nolfs \ |
634 |
+ tst-readdir64-compat \ |
635 |
+ # tests |
636 |
+ endif # $(subdir) == dirent |
637 |
+diff --git a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h |
638 |
+index c8a0cfe93f..586d75586a 100644 |
639 |
+--- a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h |
640 |
++++ b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h |
641 |
+@@ -54,4 +54,7 @@ struct dirent64 |
642 |
+ /* Inform libc code that these two types are effectively identical. */ |
643 |
+ #define _DIRENT_MATCHES_DIRENT64 1 |
644 |
+ |
645 |
++/* alpha 'long int' is enough to handle off64_t. */ |
646 |
++#define _DIRENT_OFFSET_TRANSLATION 0 |
647 |
++ |
648 |
+ #endif /* bits/dirent.h */ |
649 |
+diff --git a/sysdeps/unix/sysv/linux/bits/dirent.h b/sysdeps/unix/sysv/linux/bits/dirent.h |
650 |
+index ab34d986ff..bb02dcb70a 100644 |
651 |
+--- a/sysdeps/unix/sysv/linux/bits/dirent.h |
652 |
++++ b/sysdeps/unix/sysv/linux/bits/dirent.h |
653 |
+@@ -57,3 +57,7 @@ struct dirent64 |
654 |
+ #else |
655 |
+ # define _DIRENT_MATCHES_DIRENT64 0 |
656 |
+ #endif |
657 |
+ |
658 |
-+ closedir (dirp); |
659 |
-+ free (tdirp); |
660 |
-+ for (i = 0; i < dirp_count; i++) |
661 |
-+ free (ddirp[i]); |
662 |
-+ free (ddirp); |
663 |
-+ |
664 |
-+ return 0; |
665 |
-+} |
666 |
-+ |
667 |
-+/* Same as before but with LFS support. */ |
668 |
-+static int |
669 |
-+do_test_lfs (void) |
670 |
-+{ |
671 |
-+ DIR *dirp = opendir (dirname); |
672 |
-+ TEST_VERIFY_EXIT (dirp != NULL); |
673 |
-+ |
674 |
-+ size_t dirp_count = 0; |
675 |
-+ for (struct dirent64 * dp = readdir64 (dirp); |
676 |
-+ dp != NULL; |
677 |
-+ dp = readdir64 (dirp)) |
678 |
-+ dirp_count++; |
679 |
-+ |
680 |
-+ /* The 2 extra files are '.' and '..'. */ |
681 |
-+ TEST_COMPARE (dirp_count, nfiles + 2); |
682 |
-+ |
683 |
-+ rewinddir (dirp); |
684 |
-+ |
685 |
-+ long *tdirp = xmalloc (dirp_count * sizeof (long)); |
686 |
-+ struct dirent64 **ddirp = xmalloc (dirp_count * sizeof (struct dirent64 *)); |
687 |
-+ |
688 |
-+ size_t i = 0; |
689 |
-+ do |
690 |
-+ { |
691 |
-+ tdirp[i] = telldir (dirp); |
692 |
-+ struct dirent64 *dp = readdir64 (dirp); |
693 |
-+ TEST_VERIFY_EXIT (dp != NULL); |
694 |
-+ ddirp[i] = xmalloc (dp->d_reclen); |
695 |
-+ memcpy (ddirp[i], dp, dp->d_reclen); |
696 |
-+ } while (++i < dirp_count); |
697 |
-+ |
698 |
-+ for (i = 0; i < dirp_count - 1; i++) |
699 |
-+ { |
700 |
-+ seekdir (dirp, tdirp[i]); |
701 |
-+ struct dirent64 *dp = readdir64 (dirp); |
702 |
-+ TEST_COMPARE (strcmp (dp->d_name, ddirp[i]->d_name), 0); |
703 |
-+ TEST_COMPARE (dp->d_ino, ddirp[i]->d_ino); |
704 |
-+ TEST_COMPARE (dp->d_off, ddirp[i]->d_off); |
705 |
-+ } |
706 |
-+ |
707 |
-+ closedir (dirp); |
708 |
-+ free (tdirp); |
709 |
-+ for (i = 0; i < dirp_count; i++) |
710 |
-+ free (ddirp[i]); |
711 |
-+ free (ddirp); |
712 |
-+ |
713 |
-+ return 0; |
714 |
-+} |
715 |
-+ |
716 |
-+static int |
717 |
-+do_test (void) |
718 |
-+{ |
719 |
-+ do_test_not_lfs (); |
720 |
-+ do_test_lfs (); |
721 |
-+ |
722 |
-+ return 0; |
723 |
-+} |
724 |
-+ |
725 |
-+#include <support/test-driver.c> |
726 |
++/* The telldir function returns long int, which may not be large enough to |
727 |
++ store off64_t values. In this case, translation is required. */ |
728 |
++#define _DIRENT_OFFSET_TRANSLATION (LONG_WIDTH < 64) |
729 |
diff --git a/sysdeps/unix/sysv/linux/closedir.c b/sysdeps/unix/sysv/linux/closedir.c |
730 |
-index d876d49d78..8e5669963c 100644 |
731 |
+index f1c2608642..9585a6ca3a 100644 |
732 |
--- a/sysdeps/unix/sysv/linux/closedir.c |
733 |
+++ b/sysdeps/unix/sysv/linux/closedir.c |
734 |
-@@ -43,6 +43,10 @@ __closedir (DIR *dirp) |
735 |
- |
736 |
- fd = dirp->fd; |
737 |
+@@ -47,6 +47,10 @@ __closedir (DIR *dirp) |
738 |
+ __libc_lock_fini (dirp->lock); |
739 |
+ #endif |
740 |
|
741 |
-+#ifndef __LP64__ |
742 |
++#if _DIRENT_OFFSET_TRANSLATION |
743 |
+ dirstream_loc_clear (&dirp->locs); |
744 |
+#endif |
745 |
+ |
746 |
- #if IS_IN (libc) |
747 |
- __libc_lock_fini (dirp->lock); |
748 |
- #endif |
749 |
+ free ((void *) dirp); |
750 |
+ |
751 |
+ return __close_nocancel (fd); |
752 |
diff --git a/sysdeps/unix/sysv/linux/dirstream.h b/sysdeps/unix/sysv/linux/dirstream.h |
753 |
-index 064273cc31..a284292cb2 100644 |
754 |
+index adcf8234f1..8f58a1c3a6 100644 |
755 |
--- a/sysdeps/unix/sysv/linux/dirstream.h |
756 |
+++ b/sysdeps/unix/sysv/linux/dirstream.h |
757 |
-@@ -21,6 +21,7 @@ |
758 |
+@@ -22,6 +22,7 @@ |
759 |
#include <sys/types.h> |
760 |
|
761 |
#include <libc-lock.h> |
762 |
@@ -242,7 +123,7 @@ index 064273cc31..a284292cb2 100644 |
763 |
|
764 |
/* Directory stream type. |
765 |
|
766 |
-@@ -37,7 +38,7 @@ struct __dirstream |
767 |
+@@ -38,13 +39,16 @@ struct __dirstream |
768 |
size_t size; /* Total valid data in the block. */ |
769 |
size_t offset; /* Current offset into the block. */ |
770 |
|
771 |
@@ -251,44 +132,60 @@ index 064273cc31..a284292cb2 100644 |
772 |
|
773 |
int errcode; /* Delayed error code. */ |
774 |
|
775 |
-@@ -45,6 +46,9 @@ struct __dirstream |
776 |
- char *tbuffer; /* Translation buffer for non-LFS calls. */ |
777 |
- size_t tbuffer_size; /* Size of translation buffer. */ |
778 |
+ #if !defined __OFF_T_MATCHES_OFF64_T || !defined __INO_T_MATCHES_INO64_T |
779 |
+ struct dirent tdp; |
780 |
#endif |
781 |
-+#ifndef __LP64__ |
782 |
++#if _DIRENT_OFFSET_TRANSLATION |
783 |
+ struct dirstream_loc_t locs; /* off64_t to long int map for telldir. */ |
784 |
+#endif |
785 |
|
786 |
/* Directory block. We must make sure that this block starts |
787 |
at an address that is aligned adequately enough to store |
788 |
diff --git a/sysdeps/unix/sysv/linux/opendir.c b/sysdeps/unix/sysv/linux/opendir.c |
789 |
-index bfd2f382a6..9a0b7ab4c4 100644 |
790 |
+index 4336196a4d..3e2caabb9d 100644 |
791 |
--- a/sysdeps/unix/sysv/linux/opendir.c |
792 |
+++ b/sysdeps/unix/sysv/linux/opendir.c |
793 |
-@@ -150,6 +150,9 @@ __alloc_dir (int fd, bool close_fd, int flags, |
794 |
+@@ -129,6 +129,9 @@ __alloc_dir (int fd, bool close_fd, int flags, |
795 |
dirp->offset = 0; |
796 |
dirp->filepos = 0; |
797 |
dirp->errcode = 0; |
798 |
-+#ifndef __LP64__ |
799 |
++#if _DIRENT_OFFSET_TRANSLATION |
800 |
+ dirstream_loc_init (&dirp->locs); |
801 |
+#endif |
802 |
|
803 |
return dirp; |
804 |
} |
805 |
diff --git a/sysdeps/unix/sysv/linux/readdir.c b/sysdeps/unix/sysv/linux/readdir.c |
806 |
-index c078146d7d..f377e5f268 100644 |
807 |
+index cd0ccaf33a..7a7f484c36 100644 |
808 |
--- a/sysdeps/unix/sysv/linux/readdir.c |
809 |
+++ b/sysdeps/unix/sysv/linux/readdir.c |
810 |
-@@ -17,6 +17,7 @@ |
811 |
- <https://www.gnu.org/licenses/>. */ |
812 |
+@@ -36,6 +36,15 @@ dirstream_entry (struct __dirstream *ds, const struct dirent64 *dp64) |
813 |
+ if (dp64->d_reclen - offsetof (struct dirent64, d_name) > NAME_MAX) |
814 |
+ return false; |
815 |
|
816 |
- #include <dirent.h> |
817 |
-+#include <unistd.h> |
818 |
++ /* telldir can not return an error, so preallocate the map if the entry can |
819 |
++ not be packed directly. */ |
820 |
++ if (telldir_need_dirstream (dp64->d_off)) |
821 |
++ { |
822 |
++ dirstream_loc_add (&ds->locs, dp64->d_off); |
823 |
++ if (dirstream_loc_has_failed (&ds->locs)) |
824 |
++ return false; |
825 |
++ } |
826 |
++ |
827 |
+ ds->filepos = dp64->d_off; |
828 |
|
829 |
- #if !_DIRENT_MATCHES_DIRENT64 |
830 |
- #include <dirstream.h> |
831 |
+ ds->tdp.d_off = dp64->d_off; |
832 |
+@@ -76,7 +85,7 @@ __readdir_unlocked (DIR *dirp) |
833 |
+ |
834 |
+ /* Reset the offset into the buffer. */ |
835 |
+ dirp->offset = 0; |
836 |
+- } |
837 |
++ } |
838 |
+ |
839 |
+ struct dirent64 *dp64 = (struct dirent64 *) &dirp->data[dirp->offset]; |
840 |
+ dirp->offset += dp64->d_reclen; |
841 |
diff --git a/sysdeps/unix/sysv/linux/rewinddir.c b/sysdeps/unix/sysv/linux/rewinddir.c |
842 |
-index b1e8259703..0194d29e38 100644 |
843 |
+index c0fb7aa765..1b158a584f 100644 |
844 |
--- a/sysdeps/unix/sysv/linux/rewinddir.c |
845 |
+++ b/sysdeps/unix/sysv/linux/rewinddir.c |
846 |
@@ -33,6 +33,11 @@ __rewinddir (DIR *dirp) |
847 |
@@ -304,10 +201,10 @@ index b1e8259703..0194d29e38 100644 |
848 |
__libc_lock_unlock (dirp->lock); |
849 |
#endif |
850 |
diff --git a/sysdeps/unix/sysv/linux/seekdir.c b/sysdeps/unix/sysv/linux/seekdir.c |
851 |
-index f4e1a9f8e0..0c3e58a2ed 100644 |
852 |
+index 939ccc4447..30cce691a4 100644 |
853 |
--- a/sysdeps/unix/sysv/linux/seekdir.c |
854 |
+++ b/sysdeps/unix/sysv/linux/seekdir.c |
855 |
-@@ -22,14 +22,40 @@ |
856 |
+@@ -22,14 +22,39 @@ |
857 |
#include <dirstream.h> |
858 |
|
859 |
/* Seek to position POS in DIRP. */ |
860 |
@@ -323,11 +220,8 @@ index f4e1a9f8e0..0c3e58a2ed 100644 |
861 |
- dirp->offset = 0; |
862 |
- dirp->filepos = pos; |
863 |
+ |
864 |
-+#ifndef __LP64__ |
865 |
-+ union dirstream_packed dsp; |
866 |
-+ |
867 |
-+ dsp.l = pos; |
868 |
-+ |
869 |
++#if _DIRENT_OFFSET_TRANSLATION |
870 |
++ union dirstream_packed dsp = { .l = pos }; |
871 |
+ if (dsp.p.is_packed == 1) |
872 |
+ filepos = dsp.p.info; |
873 |
+ else |
874 |
@@ -335,9 +229,11 @@ index f4e1a9f8e0..0c3e58a2ed 100644 |
875 |
+ size_t index = dsp.p.info; |
876 |
+ |
877 |
+ if (index >= dirstream_loc_size (&dirp->locs)) |
878 |
-+ return; |
879 |
-+ struct dirstream_loc *loc = dirstream_loc_at (&dirp->locs, index); |
880 |
-+ filepos = loc->filepos; |
881 |
++ { |
882 |
++ __libc_lock_unlock (dirp->lock); |
883 |
++ return; |
884 |
++ } |
885 |
++ filepos = *dirstream_loc_at (&dirp->locs, index); |
886 |
+ } |
887 |
+#else |
888 |
+ filepos = pos; |
889 |
@@ -354,10 +250,14 @@ index f4e1a9f8e0..0c3e58a2ed 100644 |
890 |
__libc_lock_unlock (dirp->lock); |
891 |
} |
892 |
diff --git a/sysdeps/unix/sysv/linux/telldir.c b/sysdeps/unix/sysv/linux/telldir.c |
893 |
-index b60b231e48..874905489f 100644 |
894 |
+index 1e5c129e9f..c3ef14f3da 100644 |
895 |
--- a/sysdeps/unix/sysv/linux/telldir.c |
896 |
+++ b/sysdeps/unix/sysv/linux/telldir.c |
897 |
-@@ -18,16 +18,59 @@ |
898 |
+@@ -15,9 +15,11 @@ |
899 |
+ License along with the GNU C Library; if not, see |
900 |
+ <https://www.gnu.org/licenses/>. */ |
901 |
+ |
902 |
++#include <assert.h> |
903 |
#include <dirent.h> |
904 |
|
905 |
#include <dirstream.h> |
906 |
@@ -365,68 +265,55 @@ index b60b231e48..874905489f 100644 |
907 |
|
908 |
/* Return the current position of DIRP. */ |
909 |
long int |
910 |
- telldir (DIR *dirp) |
911 |
- { |
912 |
-- long int ret; |
913 |
-+#ifndef __LP64__ |
914 |
-+ /* If the directory position fits in the packet structure returns it. |
915 |
+@@ -26,7 +28,40 @@ telldir (DIR *dirp) |
916 |
+ long int ret; |
917 |
+ |
918 |
+ __libc_lock_lock (dirp->lock); |
919 |
++ |
920 |
++#if _DIRENT_OFFSET_TRANSLATION |
921 |
++ /* If the directory position fits in the packet structure, returns it. |
922 |
+ Otherwise, check if the position is already been recorded in the |
923 |
+ dynamic array. If not, add the new record. */ |
924 |
+ |
925 |
+ union dirstream_packed dsp; |
926 |
-+ size_t i; |
927 |
- |
928 |
- __libc_lock_lock (dirp->lock); |
929 |
-- ret = dirp->filepos; |
930 |
+ |
931 |
-+ if (dirp->filepos < (1U << 31)) |
932 |
++ if (!telldir_need_dirstream (dirp->filepos)) |
933 |
+ { |
934 |
+ dsp.p.is_packed = 1; |
935 |
+ dsp.p.info = dirp->filepos; |
936 |
-+ goto out; |
937 |
+ } |
938 |
-+ |
939 |
-+ dsp.l = -1; |
940 |
-+ |
941 |
-+ for (i = 0; i < dirstream_loc_size (&dirp->locs); i++) |
942 |
-+ { |
943 |
-+ struct dirstream_loc *loc = dirstream_loc_at (&dirp->locs, i); |
944 |
-+ if (loc->filepos == dirp->filepos) |
945 |
-+ break; |
946 |
-+ } |
947 |
-+ if (i == dirstream_loc_size (&dirp->locs)) |
948 |
++ else |
949 |
+ { |
950 |
-+ dirstream_loc_add (&dirp->locs, |
951 |
-+ (struct dirstream_loc) { dirp->filepos }); |
952 |
-+ if (dirstream_loc_has_failed (&dirp->locs)) |
953 |
-+ goto out; |
954 |
++ dsp.l = -1; |
955 |
++ |
956 |
++ size_t i; |
957 |
++ for (i = 0; i < dirstream_loc_size (&dirp->locs); i++) |
958 |
++ if (*dirstream_loc_at (&dirp->locs, i) == dirp->filepos) |
959 |
++ break; |
960 |
++ /* It should be pre-allocated on readdir. */ |
961 |
++ assert (i != dirstream_loc_size (&dirp->locs)); |
962 |
++ |
963 |
++ dsp.p.is_packed = 0; |
964 |
++ /* This assignment might overflow, however most likely ENOME would |
965 |
++ happen long before. */ |
966 |
++ dsp.p.info = i; |
967 |
+ } |
968 |
+ |
969 |
-+ dsp.p.is_packed = 0; |
970 |
-+ /* This assignment might overflow, however most likely ENOMEM would happen |
971 |
-+ long before. */ |
972 |
-+ dsp.p.info = i; |
973 |
-+ |
974 |
-+out: |
975 |
++ ret = dsp.l; |
976 |
++#else |
977 |
+ ret = dirp->filepos; |
978 |
++#endif |
979 |
__libc_lock_unlock (dirp->lock); |
980 |
|
981 |
-+ return dsp.l; |
982 |
-+#else |
983 |
-+ long int ret; |
984 |
-+ __libc_lock_lock (dirp->lock); |
985 |
-+ ret = dirp->filepos; |
986 |
-+ __libc_lock_unlock (dirp->lock); |
987 |
return ret; |
988 |
-+#endif |
989 |
- } |
990 |
diff --git a/sysdeps/unix/sysv/linux/telldir.h b/sysdeps/unix/sysv/linux/telldir.h |
991 |
new file mode 100644 |
992 |
-index 0000000000..7c45886341 |
993 |
+index 0000000000..758bcb0eb3 |
994 |
--- /dev/null |
995 |
+++ b/sysdeps/unix/sysv/linux/telldir.h |
996 |
-@@ -0,0 +1,64 @@ |
997 |
+@@ -0,0 +1,65 @@ |
998 |
+/* Linux internal telldir definitions. |
999 |
-+ Copyright (C) 2020 Free Software Foundation, Inc. |
1000 |
++ Copyright (C) 2023 Free Software Foundation, Inc. |
1001 |
+ This file is part of the GNU C Library. |
1002 |
+ |
1003 |
+ The GNU C Library is free software; you can redistribute it and/or |
1004 |
@@ -446,9 +333,8 @@ index 0000000000..7c45886341 |
1005 |
+#ifndef _TELLDIR_H |
1006 |
+#define _TELLDIR_H 1 |
1007 |
+ |
1008 |
-+#ifndef __LP64__ |
1009 |
-+ |
1010 |
-+/* On platforms where long int is smaller than off64_t this is how the |
1011 |
++#if _DIRENT_OFFSET_TRANSLATION |
1012 |
++/* On platforms where 'long int' is smaller than 'off64_t' this is how the |
1013 |
+ returned value is encoded and returned by 'telldir'. If the directory |
1014 |
+ offset can be enconded in 31 bits it is returned in the 'info' member |
1015 |
+ with 'is_packed' set to 1. |
1016 |
@@ -461,34 +347,188 @@ index 0000000000..7c45886341 |
1017 |
+ long int l; |
1018 |
+ struct |
1019 |
+ { |
1020 |
-+ unsigned long is_packed:1; |
1021 |
-+ unsigned long info:31; |
1022 |
++ unsigned long int is_packed:1; |
1023 |
++ unsigned long int info:31; |
1024 |
+ } p; |
1025 |
+}; |
1026 |
+ |
1027 |
+_Static_assert (sizeof (long int) == sizeof (union dirstream_packed), |
1028 |
+ "sizeof (long int) != sizeof (union dirstream_packed)"); |
1029 |
+ |
1030 |
-+/* telldir will mantain a list of offsets that describe the obtained diretory |
1031 |
++/* telldir maintains a list of offsets that describe the obtained diretory |
1032 |
+ position if it can fit this information in the returned 'dirstream_packed' |
1033 |
+ struct. */ |
1034 |
+ |
1035 |
-+struct dirstream_loc |
1036 |
-+{ |
1037 |
-+ off64_t filepos; |
1038 |
-+}; |
1039 |
-+ |
1040 |
+# define DYNARRAY_STRUCT dirstream_loc_t |
1041 |
-+# define DYNARRAY_ELEMENT struct dirstream_loc |
1042 |
++# define DYNARRAY_ELEMENT off64_t |
1043 |
+# define DYNARRAY_PREFIX dirstream_loc_ |
1044 |
+# include <malloc/dynarray-skeleton.c> |
1045 |
++ |
1046 |
++static __always_inline bool |
1047 |
++telldir_need_dirstream (__off64_t d_off) |
1048 |
++{ |
1049 |
++ return d_off >= 1UL << 31; |
1050 |
++} |
1051 |
+#else |
1052 |
+ |
1053 |
+_Static_assert (sizeof (long int) == sizeof (off64_t), |
1054 |
+ "sizeof (long int) != sizeof (off64_t)"); |
1055 |
++ |
1056 |
+#endif /* __LP64__ */ |
1057 |
+ |
1058 |
+#endif /* _TELLDIR_H */ |
1059 |
+diff --git a/sysdeps/unix/sysv/linux/tst-opendir-nolfs.c b/sysdeps/unix/sysv/linux/tst-opendir-nolfs.c |
1060 |
+new file mode 100644 |
1061 |
+index 0000000000..52e18171a7 |
1062 |
+--- /dev/null |
1063 |
++++ b/sysdeps/unix/sysv/linux/tst-opendir-nolfs.c |
1064 |
+@@ -0,0 +1,146 @@ |
1065 |
++/* Check multiple telldir and seekdir. |
1066 |
++ Copyright (C) 2023 Free Software Foundation, Inc. |
1067 |
++ This file is part of the GNU C Library. |
1068 |
++ |
1069 |
++ The GNU C Library is free software; you can redistribute it and/or |
1070 |
++ modify it under the terms of the GNU Lesser General Public |
1071 |
++ License as published by the Free Software Foundation; either |
1072 |
++ version 2.1 of the License, or (at your option) any later version. |
1073 |
++ |
1074 |
++ The GNU C Library is distributed in the hope that it will be useful, |
1075 |
++ but WITHOUT ANY WARRANTY; without even the implied warranty of |
1076 |
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1077 |
++ Lesser General Public License for more details. |
1078 |
++ |
1079 |
++ You should have received a copy of the GNU Lesser General Public |
1080 |
++ License along with the GNU C Library; if not, see |
1081 |
++ <https://www.gnu.org/licenses/>. */ |
1082 |
++ |
1083 |
++#include <dirent.h> |
1084 |
++#include <fcntl.h> |
1085 |
++#include <stdio.h> |
1086 |
++#include <stdlib.h> |
1087 |
++#include <string.h> |
1088 |
++#include <unistd.h> |
1089 |
++ |
1090 |
++#include <support/check.h> |
1091 |
++#include <support/support.h> |
1092 |
++#include <support/temp_file.h> |
1093 |
++#include <support/xunistd.h> |
1094 |
++ |
1095 |
++/* Some filesystems returns an arbitrary value for d_off direnty entry (ext4 |
1096 |
++ for instance, where the value is an internal hash key). The idea of create |
1097 |
++ a large number of file is to try trigger a overflow d_off value in a entry |
1098 |
++ to check if telldir/seekdir does work corretly in such case. */ |
1099 |
++static const char *dirname; |
1100 |
++/* The 2 extra files are '.' and '..'. */ |
1101 |
++static const size_t nfiles = (1<<14) + 2; |
1102 |
++ |
1103 |
++static inline bool |
1104 |
++in_ino_t_range (ino64_t v) |
1105 |
++{ |
1106 |
++ ino_t s = v; |
1107 |
++ return s == v; |
1108 |
++} |
1109 |
++ |
1110 |
++static inline bool |
1111 |
++in_off_t_range (off64_t v) |
1112 |
++{ |
1113 |
++ off_t s = v; |
1114 |
++ return s == v; |
1115 |
++} |
1116 |
++ |
1117 |
++static void |
1118 |
++do_prepare (int argc, char *argv[]) |
1119 |
++{ |
1120 |
++ dirname = support_create_temp_directory ("tst-opendir-nolfs-"); |
1121 |
++ |
1122 |
++ for (size_t i = 0; i < nfiles - 2; i++) |
1123 |
++ { |
1124 |
++ int fd = create_temp_file_in_dir ("tempfile.", dirname, NULL); |
1125 |
++ TEST_VERIFY_EXIT (fd > 0); |
1126 |
++ close (fd); |
1127 |
++ } |
1128 |
++} |
1129 |
++#define PREPARE do_prepare |
1130 |
++ |
1131 |
++static int |
1132 |
++do_test (void) |
1133 |
++{ |
1134 |
++ DIR *dirp = opendir (dirname); |
1135 |
++ TEST_VERIFY_EXIT (dirp != NULL); |
1136 |
++ |
1137 |
++ long int *tdirp = xmalloc (nfiles * sizeof (long int)); |
1138 |
++ struct dirent **ddirp = xmalloc (nfiles * sizeof (struct dirent *)); |
1139 |
++ |
1140 |
++ /* For non-LFS, the entry is skipped if it can not be converted. */ |
1141 |
++ int count = 0; |
1142 |
++ for (; count < nfiles; count++) |
1143 |
++ { |
1144 |
++ tdirp[count] = telldir (dirp); |
1145 |
++ struct dirent *dp = readdir (dirp); |
1146 |
++ if (dp == NULL) |
1147 |
++ break; |
1148 |
++ ddirp[count] = xmalloc (dp->d_reclen); |
1149 |
++ memcpy (ddirp[count], dp, dp->d_reclen); |
1150 |
++ } |
1151 |
++ |
1152 |
++ closedir (dirp); |
1153 |
++ |
1154 |
++ /* Check against the getdents64 syscall. */ |
1155 |
++ int fd = xopen (dirname, O_RDONLY | O_DIRECTORY, 0); |
1156 |
++ int i = 0; |
1157 |
++ while (true) |
1158 |
++ { |
1159 |
++ struct |
1160 |
++ { |
1161 |
++ char buffer[1024]; |
1162 |
++ struct dirent64 pad; |
1163 |
++ } data; |
1164 |
++ |
1165 |
++ ssize_t ret = getdents64 (fd, &data.buffer, sizeof (data.buffer)); |
1166 |
++ if (ret < 0) |
1167 |
++ FAIL_EXIT1 ("getdents64: %m"); |
1168 |
++ if (ret == 0) |
1169 |
++ break; |
1170 |
++ |
1171 |
++ char *current = data.buffer; |
1172 |
++ char *end = data.buffer + ret; |
1173 |
++ while (current != end) |
1174 |
++ { |
1175 |
++ struct dirent64 entry; |
1176 |
++ memcpy (&entry, current, sizeof (entry)); |
1177 |
++ /* Truncate overlong strings. */ |
1178 |
++ entry.d_name[sizeof (entry.d_name) - 1] = '\0'; |
1179 |
++ TEST_VERIFY (strlen (entry.d_name) < sizeof (entry.d_name) - 1); |
1180 |
++ |
1181 |
++ if (in_ino_t_range (entry.d_ino) && in_off_t_range (entry.d_off)) |
1182 |
++ { |
1183 |
++ TEST_COMPARE_STRING (entry.d_name, ddirp[i]->d_name); |
1184 |
++ TEST_COMPARE (entry.d_ino, ddirp[i]->d_ino); |
1185 |
++ TEST_COMPARE (entry.d_off, ddirp[i]->d_off); |
1186 |
++ TEST_COMPARE (entry.d_type, ddirp[i]->d_type); |
1187 |
++ |
1188 |
++ /* Offset zero is reserved for the first entry. */ |
1189 |
++ TEST_VERIFY (entry.d_off != 0); |
1190 |
++ |
1191 |
++ TEST_VERIFY_EXIT (entry.d_reclen <= end - current); |
1192 |
++ i++; |
1193 |
++ } |
1194 |
++ |
1195 |
++ current += entry.d_reclen; |
1196 |
++ } |
1197 |
++ } |
1198 |
++ |
1199 |
++ /* direntries_read has been called more than once. */ |
1200 |
++ TEST_COMPARE (count, i); |
1201 |
++ |
1202 |
++ free (tdirp); |
1203 |
++ for (int i = 0; i < count; i++) |
1204 |
++ free (ddirp[i]); |
1205 |
++ free (ddirp); |
1206 |
++ |
1207 |
++ return 0; |
1208 |
++} |
1209 |
++ |
1210 |
++#include <support/test-driver.c> |
1211 |
-- |
1212 |
-2.38.2 |
1213 |
+2.39.1 |
1214 |
|
1215 |
|
1216 |
diff --git a/9999/0007-linux-Add-__readdir64_unlocked.patch b/9999/0007-linux-Add-__readdir64_unlocked.patch |
1217 |
index 631550c..18dcda4 100644 |
1218 |
--- a/9999/0007-linux-Add-__readdir64_unlocked.patch |
1219 |
+++ b/9999/0007-linux-Add-__readdir64_unlocked.patch |
1220 |
@@ -1,7 +1,7 @@ |
1221 |
-From 4cca67d0d2d615918e05db864c236e33c0fda8f3 Mon Sep 17 00:00:00 2001 |
1222 |
+From f697eec9ff1939e46d7730aa5cc0f696f41d8bd7 Mon Sep 17 00:00:00 2001 |
1223 |
From: Adhemerval Zanella <adhemerval.zanella@××××××.org> |
1224 |
-Date: Mon, 13 Apr 2020 08:35:40 -0300 |
1225 |
-Subject: [PATCH 07/10] linux: Add __readdir64_unlocked |
1226 |
+Date: Fri, 27 Jan 2023 14:28:32 -0300 |
1227 |
+Subject: [PATCH 7/9] linux: Add __readdir64_unlocked |
1228 |
|
1229 |
And use it on readdir_r implementation. |
1230 |
|
1231 |
@@ -13,7 +13,7 @@ Checked on i686-linux-gnu. |
1232 |
3 files changed, 33 insertions(+), 68 deletions(-) |
1233 |
|
1234 |
diff --git a/include/dirent.h b/include/dirent.h |
1235 |
-index d7567f5e86..0c6715d0e4 100644 |
1236 |
+index 17827176ba..f391476298 100644 |
1237 |
--- a/include/dirent.h |
1238 |
+++ b/include/dirent.h |
1239 |
@@ -21,6 +21,7 @@ extern DIR *__fdopendir (int __fd) attribute_hidden; |
1240 |
@@ -25,7 +25,7 @@ index d7567f5e86..0c6715d0e4 100644 |
1241 |
libc_hidden_proto (__readdir64) |
1242 |
extern int __readdir_r (DIR *__dirp, struct dirent *__entry, |
1243 |
diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c |
1244 |
-index 7952da5c27..9d82054182 100644 |
1245 |
+index db1c6214d8..2327511736 100644 |
1246 |
--- a/sysdeps/unix/sysv/linux/readdir64.c |
1247 |
+++ b/sysdeps/unix/sysv/linux/readdir64.c |
1248 |
@@ -28,15 +28,11 @@ |
1249 |
@@ -67,7 +67,7 @@ index 7952da5c27..9d82054182 100644 |
1250 |
__libc_lock_unlock (dirp->lock); |
1251 |
#endif |
1252 |
diff --git a/sysdeps/unix/sysv/linux/readdir64_r.c b/sysdeps/unix/sysv/linux/readdir64_r.c |
1253 |
-index afd7f9af0f..32962a176a 100644 |
1254 |
+index 285dc99509..5ae099bde7 100644 |
1255 |
--- a/sysdeps/unix/sysv/linux/readdir64_r.c |
1256 |
+++ b/sysdeps/unix/sysv/linux/readdir64_r.c |
1257 |
@@ -32,89 +32,43 @@ __readdir64_r (DIR *dirp, struct dirent64 *entry, struct dirent64 **result) |
1258 |
@@ -178,5 +178,5 @@ index afd7f9af0f..32962a176a 100644 |
1259 |
|
1260 |
|
1261 |
-- |
1262 |
-2.38.2 |
1263 |
+2.39.1 |
1264 |
|
1265 |
|
1266 |
diff --git a/9999/0008-linux-Add-__old_readdir64_unlocked.patch b/9999/0008-linux-Add-__old_readdir64_unlocked.patch |
1267 |
index 3cd2923..a1d289a 100644 |
1268 |
--- a/9999/0008-linux-Add-__old_readdir64_unlocked.patch |
1269 |
+++ b/9999/0008-linux-Add-__old_readdir64_unlocked.patch |
1270 |
@@ -1,7 +1,7 @@ |
1271 |
-From cd6d96ae0a09c1bff40f19d54e2910d7d4e74864 Mon Sep 17 00:00:00 2001 |
1272 |
+From 5af443d8a53475680fdc51ff1c496b13a9e9e6d0 Mon Sep 17 00:00:00 2001 |
1273 |
From: Adhemerval Zanella <adhemerval.zanella@××××××.org> |
1274 |
-Date: Tue, 14 Apr 2020 11:14:22 -0300 |
1275 |
-Subject: [PATCH 08/10] linux: Add __old_readdir64_unlocked |
1276 |
+Date: Fri, 27 Jan 2023 14:28:33 -0300 |
1277 |
+Subject: [PATCH 8/9] linux: Add __old_readdir64_unlocked |
1278 |
|
1279 |
And use it __old_readdir64_r. |
1280 |
|
1281 |
@@ -13,7 +13,7 @@ Checked on i686-linux-gnu. |
1282 |
3 files changed, 35 insertions(+), 70 deletions(-) |
1283 |
|
1284 |
diff --git a/sysdeps/unix/sysv/linux/olddirent.h b/sysdeps/unix/sysv/linux/olddirent.h |
1285 |
-index 9a22609177..00c84b9521 100644 |
1286 |
+index 9789ffae07..cde95e192e 100644 |
1287 |
--- a/sysdeps/unix/sysv/linux/olddirent.h |
1288 |
+++ b/sysdeps/unix/sysv/linux/olddirent.h |
1289 |
@@ -32,6 +32,8 @@ struct __old_dirent64 |
1290 |
@@ -26,7 +26,7 @@ index 9a22609177..00c84b9521 100644 |
1291 |
struct __old_dirent64 **__result); |
1292 |
extern __ssize_t __old_getdents64 (int __fd, char *__buf, size_t __nbytes) |
1293 |
diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c |
1294 |
-index 9d82054182..bbe247f95d 100644 |
1295 |
+index 2327511736..b901071aa7 100644 |
1296 |
--- a/sysdeps/unix/sysv/linux/readdir64.c |
1297 |
+++ b/sysdeps/unix/sysv/linux/readdir64.c |
1298 |
@@ -104,15 +104,11 @@ versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2); |
1299 |
@@ -79,7 +79,7 @@ index 9d82054182..bbe247f95d 100644 |
1300 |
__libc_lock_unlock (dirp->lock); |
1301 |
#endif |
1302 |
diff --git a/sysdeps/unix/sysv/linux/readdir64_r.c b/sysdeps/unix/sysv/linux/readdir64_r.c |
1303 |
-index 32962a176a..699d120b76 100644 |
1304 |
+index 5ae099bde7..b499388de7 100644 |
1305 |
--- a/sysdeps/unix/sysv/linux/readdir64_r.c |
1306 |
+++ b/sysdeps/unix/sysv/linux/readdir64_r.c |
1307 |
@@ -91,89 +91,44 @@ __old_readdir64_r (DIR *dirp, struct __old_dirent64 *entry, |
1308 |
@@ -190,5 +190,5 @@ index 32962a176a..699d120b76 100644 |
1309 |
|
1310 |
compat_symbol (libc, __old_readdir64_r, readdir64_r, GLIBC_2_1); |
1311 |
-- |
1312 |
-2.38.2 |
1313 |
+2.39.1 |
1314 |
|
1315 |
|
1316 |
diff --git a/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch b/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch |
1317 |
index 7a9c5a3..644af1c 100644 |
1318 |
--- a/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch |
1319 |
+++ b/9999/0009-linux-Use-getdents64-on-readdir64-compat-implementat.patch |
1320 |
@@ -1,8 +1,7 @@ |
1321 |
-From c71a60022adc7c9b7e37a813e2abad0d0724245a Mon Sep 17 00:00:00 2001 |
1322 |
+From b1ab50b1c7f17d6b38c1e3a665cca971ba16deab Mon Sep 17 00:00:00 2001 |
1323 |
From: Adhemerval Zanella <adhemerval.zanella@××××××.org> |
1324 |
-Date: Tue, 20 Oct 2020 16:00:43 -0300 |
1325 |
-Subject: [PATCH 09/10] linux: Use getdents64 on readdir64 compat |
1326 |
- implementation |
1327 |
+Date: Fri, 27 Jan 2023 14:28:34 -0300 |
1328 |
+Subject: [PATCH 9/9] linux: Use getdents64 on readdir64 compat implementation |
1329 |
|
1330 |
It uses a similar strategy from the non-LFS readdir that also |
1331 |
uses getdents64 internally and uses a translation buffer to return |
1332 |
@@ -12,14 +11,45 @@ It allows to remove __old_getdents64. |
1333 |
|
1334 |
Checked on i686-linux-gnu. |
1335 |
--- |
1336 |
+ sysdeps/unix/sysv/linux/dirstream.h | 13 +++- |
1337 |
sysdeps/unix/sysv/linux/getdents64.c | 93 ---------------------------- |
1338 |
sysdeps/unix/sysv/linux/olddirent.h | 2 - |
1339 |
- sysdeps/unix/sysv/linux/opendir.c | 15 ++++- |
1340 |
- sysdeps/unix/sysv/linux/readdir64.c | 62 +++++++++++++++---- |
1341 |
- 4 files changed, 64 insertions(+), 108 deletions(-) |
1342 |
+ sysdeps/unix/sysv/linux/readdir64.c | 50 +++++++++++---- |
1343 |
+ 4 files changed, 50 insertions(+), 108 deletions(-) |
1344 |
|
1345 |
+diff --git a/sysdeps/unix/sysv/linux/dirstream.h b/sysdeps/unix/sysv/linux/dirstream.h |
1346 |
+index 8f58a1c3a6..b03ece4590 100644 |
1347 |
+--- a/sysdeps/unix/sysv/linux/dirstream.h |
1348 |
++++ b/sysdeps/unix/sysv/linux/dirstream.h |
1349 |
+@@ -24,6 +24,11 @@ |
1350 |
+ #include <libc-lock.h> |
1351 |
+ #include <telldir.h> |
1352 |
+ |
1353 |
++#include <shlib-compat.h> |
1354 |
++#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) |
1355 |
++# include <olddirent.h> |
1356 |
++#endif |
1357 |
++ |
1358 |
+ /* Directory stream type. |
1359 |
+ |
1360 |
+ The miscellaneous Unix `readdir' implementations read directory data |
1361 |
+@@ -44,7 +49,13 @@ struct __dirstream |
1362 |
+ int errcode; /* Delayed error code. */ |
1363 |
+ |
1364 |
+ #if !defined __OFF_T_MATCHES_OFF64_T || !defined __INO_T_MATCHES_INO64_T |
1365 |
+- struct dirent tdp; |
1366 |
++ union |
1367 |
++ { |
1368 |
++ struct dirent tdp; |
1369 |
++#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) |
1370 |
++ struct __old_dirent64 tdp64; |
1371 |
++# endif |
1372 |
++ }; |
1373 |
+ #endif |
1374 |
+ #if _DIRENT_OFFSET_TRANSLATION |
1375 |
+ struct dirstream_loc_t locs; /* off64_t to long int map for telldir. */ |
1376 |
diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c |
1377 |
-index 510a586859..92481526c5 100644 |
1378 |
+index 01c3517deb..db299864ed 100644 |
1379 |
--- a/sysdeps/unix/sysv/linux/getdents64.c |
1380 |
+++ b/sysdeps/unix/sysv/linux/getdents64.c |
1381 |
@@ -36,97 +36,4 @@ weak_alias (__getdents64, getdents64) |
1382 |
@@ -121,7 +151,7 @@ index 510a586859..92481526c5 100644 |
1383 |
-# endif /* SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) */ |
1384 |
#endif /* _DIRENT_MATCHES_DIRENT64 */ |
1385 |
diff --git a/sysdeps/unix/sysv/linux/olddirent.h b/sysdeps/unix/sysv/linux/olddirent.h |
1386 |
-index 00c84b9521..68aafd7c02 100644 |
1387 |
+index cde95e192e..2d682a6919 100644 |
1388 |
--- a/sysdeps/unix/sysv/linux/olddirent.h |
1389 |
+++ b/sysdeps/unix/sysv/linux/olddirent.h |
1390 |
@@ -36,8 +36,6 @@ extern struct __old_dirent64 *__old_readdir64_unlocked (DIR *__dirp) |
1391 |
@@ -133,44 +163,11 @@ index 00c84b9521..68aafd7c02 100644 |
1392 |
int __old_scandir64 (const char * __dir, |
1393 |
struct __old_dirent64 *** __namelist, |
1394 |
int (*__selector) (const struct __old_dirent64 *), |
1395 |
-diff --git a/sysdeps/unix/sysv/linux/opendir.c b/sysdeps/unix/sysv/linux/opendir.c |
1396 |
-index 9a0b7ab4c4..df40b0a64e 100644 |
1397 |
---- a/sysdeps/unix/sysv/linux/opendir.c |
1398 |
-+++ b/sysdeps/unix/sysv/linux/opendir.c |
1399 |
-@@ -23,6 +23,11 @@ |
1400 |
- |
1401 |
- #include <not-cancel.h> |
1402 |
- |
1403 |
-+#include <shlib-compat.h> |
1404 |
-+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) |
1405 |
-+# include <olddirent.h> |
1406 |
-+#endif |
1407 |
-+ |
1408 |
- enum { |
1409 |
- opendir_oflags = O_RDONLY|O_NDELAY|O_DIRECTORY|O_LARGEFILE|O_CLOEXEC |
1410 |
- }; |
1411 |
-@@ -128,7 +133,15 @@ __alloc_dir (int fd, bool close_fd, int flags, |
1412 |
- expand the buffer if required. */ |
1413 |
- enum |
1414 |
- { |
1415 |
-- tbuffer_size = sizeof (struct dirent) + NAME_MAX + 1 |
1416 |
-+ tbuffer_size = |
1417 |
-+# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) |
1418 |
-+ /* This is used on compat readdir64. */ |
1419 |
-+ MAX (sizeof (struct dirent), |
1420 |
-+ sizeof (struct __old_dirent64)) |
1421 |
-+# else |
1422 |
-+ sizeof (struct dirent) |
1423 |
-+# endif |
1424 |
-+ + NAME_MAX + 1 |
1425 |
- }; |
1426 |
- dirp->tbuffer = malloc (tbuffer_size); |
1427 |
- if (dirp->tbuffer == NULL) |
1428 |
diff --git a/sysdeps/unix/sysv/linux/readdir64.c b/sysdeps/unix/sysv/linux/readdir64.c |
1429 |
-index bbe247f95d..01e834e238 100644 |
1430 |
+index b901071aa7..88e42c5e90 100644 |
1431 |
--- a/sysdeps/unix/sysv/linux/readdir64.c |
1432 |
+++ b/sysdeps/unix/sysv/linux/readdir64.c |
1433 |
-@@ -102,21 +102,52 @@ versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2); |
1434 |
+@@ -102,21 +102,43 @@ versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2); |
1435 |
# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) |
1436 |
# include <olddirent.h> |
1437 |
|
1438 |
@@ -182,29 +179,20 @@ index bbe247f95d..01e834e238 100644 |
1439 |
+dirstream_old_entry (struct __dirstream *ds, const struct dirent64 *dp64) |
1440 |
+{ |
1441 |
+ /* Check for overflow. */ |
1442 |
-+ ino_t d_ino = dp64->d_ino; |
1443 |
-+ if (d_ino != dp64->d_ino) |
1444 |
++ if (!in_ino_t_range (dp64->d_ino)) |
1445 |
+ return false; |
1446 |
+ |
1447 |
-+ /* Expand the translation buffer to hold the new namesize. */ |
1448 |
-+ size_t d_reclen = sizeof (struct __old_dirent64) |
1449 |
-+ + dp64->d_reclen - offsetof (struct dirent64, d_name); |
1450 |
-+ if (d_reclen > ds->tbuffer_size) |
1451 |
-+ { |
1452 |
-+ char *newbuffer = realloc (ds->tbuffer, d_reclen); |
1453 |
-+ if (newbuffer == NULL) |
1454 |
-+ return false; |
1455 |
-+ ds->tbuffer = newbuffer; |
1456 |
-+ ds->tbuffer_size = d_reclen; |
1457 |
-+ } |
1458 |
++ /* And if name is too large. */ |
1459 |
++ if (dp64->d_reclen - offsetof (struct dirent64, d_name) > NAME_MAX) |
1460 |
++ return false; |
1461 |
+ |
1462 |
-+ struct __old_dirent64 *olddp64 = (struct __old_dirent64 *) ds->tbuffer; |
1463 |
++ ds->filepos = dp64->d_off; |
1464 |
+ |
1465 |
-+ olddp64->d_off = dp64->d_off; |
1466 |
-+ olddp64->d_ino = dp64->d_ino; |
1467 |
-+ olddp64->d_reclen = dp64->d_reclen; |
1468 |
-+ olddp64->d_type = dp64->d_type; |
1469 |
-+ memcpy (olddp64->d_name, dp64->d_name, |
1470 |
++ ds->tdp64.d_off = dp64->d_off; |
1471 |
++ ds->tdp64.d_ino = dp64->d_ino; |
1472 |
++ ds->tdp64.d_reclen = dp64->d_reclen; |
1473 |
++ ds->tdp64.d_type = dp64->d_type; |
1474 |
++ memcpy (ds->tdp64.d_name, dp64->d_name, |
1475 |
+ dp64->d_reclen - offsetof (struct dirent64, d_name)); |
1476 |
+ |
1477 |
+ return true; |
1478 |
@@ -230,7 +218,7 @@ index bbe247f95d..01e834e238 100644 |
1479 |
if (bytes <= 0) |
1480 |
{ |
1481 |
/* Linux may fail with ENOENT on some file systems if the |
1482 |
-@@ -127,17 +158,24 @@ __old_readdir64_unlocked (DIR *dirp) |
1483 |
+@@ -127,17 +149,21 @@ __old_readdir64_unlocked (DIR *dirp) |
1484 |
__set_errno (saved_errno); |
1485 |
return NULL; |
1486 |
} |
1487 |
@@ -251,15 +239,12 @@ index bbe247f95d..01e834e238 100644 |
1488 |
+ /* Skip entries which might overflow d_ino or for memory allocation failure |
1489 |
+ in case of large file names. */ |
1490 |
+ if (dirstream_old_entry (dirp, dp64)) |
1491 |
-+ { |
1492 |
-+ dirp->filepos = dp64->d_off; |
1493 |
-+ return (struct __old_dirent64 *) dirp->tbuffer; |
1494 |
-+ } |
1495 |
++ return &dirp->tdp64; |
1496 |
+ |
1497 |
+ return NULL; |
1498 |
} |
1499 |
|
1500 |
attribute_compat_text_section |
1501 |
-- |
1502 |
-2.38.2 |
1503 |
+2.39.1 |
1504 |
|
1505 |
|
1506 |
diff --git a/9999/0010-dirent-Deprecate-getdirentries.patch b/9999/0010-dirent-Deprecate-getdirentries.patch |
1507 |
deleted file mode 100644 |
1508 |
index 28f744a..0000000 |
1509 |
--- a/9999/0010-dirent-Deprecate-getdirentries.patch |
1510 |
+++ /dev/null |
1511 |
@@ -1,100 +0,0 @@ |
1512 |
-From 2f0668caf22acf6493dce8dcfd670e4b35fb6892 Mon Sep 17 00:00:00 2001 |
1513 |
-From: Adhemerval Zanella <adhemerval.zanella@××××××.org> |
1514 |
-Date: Fri, 17 Apr 2020 09:59:51 -0300 |
1515 |
-Subject: [PATCH 10/10] dirent: Deprecate getdirentries |
1516 |
- |
1517 |
-The interface has some issues: |
1518 |
- |
1519 |
- 1. It is build on top getdents on Linux and requires handling |
1520 |
- non-LFS call using LFS getdents. |
1521 |
- |
1522 |
- 2. It is not wildly used and the non-LFS support is as problematic |
1523 |
- as non-LFS readdir. glibc only exports the LFS getdents. |
1524 |
- |
1525 |
- 3. It is not a direct replacement over BSD since on some plataform |
1526 |
- its signature has changed (FreeBSD 11, for instance, used to |
1527 |
- set the offset as a 'long' and changed to 'off_t' on version 12). |
1528 |
- |
1529 |
-The idea is to eventually move the symbols to compat ones. |
1530 |
---- |
1531 |
- NEWS | 3 +++ |
1532 |
- dirent/dirent.h | 14 ++++++++++---- |
1533 |
- sysdeps/unix/sysv/linux/Makefile | 4 ++++ |
1534 |
- 3 files changed, 17 insertions(+), 4 deletions(-) |
1535 |
- |
1536 |
-diff --git a/NEWS b/NEWS |
1537 |
-index a10bb08fb0..2b4ed6bbc1 100644 |
1538 |
---- a/NEWS |
1539 |
-+++ b/NEWS |
1540 |
-@@ -21,6 +21,9 @@ Deprecated and removed features, and other changes affecting compatibility: |
1541 |
- corresponds to the AT_PLATFORM system name, or employs the legacy AT_HWCAP |
1542 |
- search mechanism, which was deprecated in version 2.33. |
1543 |
- |
1544 |
-+* The function getdirentries is now deprecated, applications should use |
1545 |
-+ either getdents64, readdir64 or readdir. |
1546 |
-+ |
1547 |
- Changes to build and runtime requirements: |
1548 |
- |
1549 |
- [Add changes to build and runtime requirements here] |
1550 |
-diff --git a/dirent/dirent.h b/dirent/dirent.h |
1551 |
-index c47d3273b2..1c299e5be8 100644 |
1552 |
---- a/dirent/dirent.h |
1553 |
-+++ b/dirent/dirent.h |
1554 |
-@@ -350,29 +350,35 @@ extern int alphasort64 (const struct dirent64 **__e1, |
1555 |
- /* Read directory entries from FD into BUF, reading at most NBYTES. |
1556 |
- Reading starts at offset *BASEP, and *BASEP is updated with the new |
1557 |
- position after reading. Returns the number of bytes read; zero when at |
1558 |
-- end of directory; or -1 for errors. */ |
1559 |
-+ end of directory; or -1 for errors. |
1560 |
-+ This is deprecated and getdents64 or readdir should be used instead. */ |
1561 |
- # ifndef __USE_FILE_OFFSET64 |
1562 |
- extern __ssize_t getdirentries (int __fd, char *__restrict __buf, |
1563 |
- size_t __nbytes, |
1564 |
- __off_t *__restrict __basep) |
1565 |
-- __THROW __nonnull ((2, 4)); |
1566 |
-+ __THROW __nonnull ((2, 4)) |
1567 |
-+ __attribute_deprecated_msg__ ("Use getdents64 instead"); |
1568 |
- # else |
1569 |
- # ifdef __REDIRECT |
1570 |
- extern __ssize_t __REDIRECT_NTH (getdirentries, |
1571 |
- (int __fd, char *__restrict __buf, |
1572 |
- size_t __nbytes, |
1573 |
- __off64_t *__restrict __basep), |
1574 |
-- getdirentries64) __nonnull ((2, 4)); |
1575 |
-+ getdirentries64) |
1576 |
-+ __nonnull ((2, 4)) |
1577 |
-+ __attribute_deprecated_msg__ ("Use getdents64 instead"); |
1578 |
- # else |
1579 |
- # define getdirentries getdirentries64 |
1580 |
- # endif |
1581 |
- # endif |
1582 |
- |
1583 |
- # ifdef __USE_LARGEFILE64 |
1584 |
-+/* This is deprecated and getdents64 or readdir64 should be used instead. */ |
1585 |
- extern __ssize_t getdirentries64 (int __fd, char *__restrict __buf, |
1586 |
- size_t __nbytes, |
1587 |
- __off64_t *__restrict __basep) |
1588 |
-- __THROW __nonnull ((2, 4)); |
1589 |
-+ __THROW __nonnull ((2, 4)) |
1590 |
-+ __attribute_deprecated_msg__ ("Use getdents64 instead"); |
1591 |
- # endif |
1592 |
- #endif /* Use misc. */ |
1593 |
- |
1594 |
-diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile |
1595 |
-index f298878e8f..41e5341450 100644 |
1596 |
---- a/sysdeps/unix/sysv/linux/Makefile |
1597 |
-+++ b/sysdeps/unix/sysv/linux/Makefile |
1598 |
-@@ -467,6 +467,10 @@ tests += \ |
1599 |
- tst-getdents64 \ |
1600 |
- tst-readdir64-compat \ |
1601 |
- # tests |
1602 |
-+ |
1603 |
-+# Avoid the warning for the weak_alias for _DIRENT_MATCHES_DIRENT64 |
1604 |
-+CFLAGS-getdirentries64.o = -Wno-deprecated-declarations |
1605 |
-+CFLAGS-getdirentries64.os = -Wno-deprecated-declarations |
1606 |
- endif # $(subdir) == dirent |
1607 |
- |
1608 |
- ifeq ($(subdir),nis) |
1609 |
--- |
1610 |
-2.38.2 |
1611 |
- |