aboutsummaryrefslogtreecommitdiff
path: root/dirent/scandir.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-06-12 02:04:20 +0000
committerUlrich Drepper <drepper@redhat.com>2003-06-12 02:04:20 +0000
commit70e1c9303a35ca9f957244fd48058ed6206f14e4 (patch)
tree424a86eb4b0c08158c245f3c2e7206a636a53725 /dirent/scandir.c
parent2236d6e12474b6f6b0e6728058257eff9e3e16b6 (diff)
downloadglibc-70e1c9303a35ca9f957244fd48058ed6206f14e4.tar
glibc-70e1c9303a35ca9f957244fd48058ed6206f14e4.tar.gz
glibc-70e1c9303a35ca9f957244fd48058ed6206f14e4.tar.bz2
glibc-70e1c9303a35ca9f957244fd48058ed6206f14e4.zip
Update.
* dirent/scandir.c (SCANDIR): Reset errno after calling selector function [PR libc/5045].
Diffstat (limited to 'dirent/scandir.c')
-rw-r--r--dirent/scandir.c72
1 files changed, 43 insertions, 29 deletions
diff --git a/dirent/scandir.c b/dirent/scandir.c
index 9f3cc8424f..748a490739 100644
--- a/dirent/scandir.c
+++ b/dirent/scandir.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-1998, 2000, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1992-1998, 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -27,6 +27,7 @@
#define DIRENT_TYPE struct dirent
#endif
+
int
SCANDIR (dir, namelist, select, cmp)
const char *dir;
@@ -48,34 +49,47 @@ SCANDIR (dir, namelist, select, cmp)
i = 0;
while ((d = READDIR (dp)) != NULL)
- if (select == NULL || (*select) (d))
- {
- DIRENT_TYPE *vnew;
- size_t dsize;
-
- /* Ignore errors from select or readdir */
- __set_errno (0);
-
- if (__builtin_expect (i == vsize, 0))
- {
- DIRENT_TYPE **new;
- if (vsize == 0)
- vsize = 10;
- else
- vsize *= 2;
- new = (DIRENT_TYPE **) realloc (v, vsize * sizeof (*v));
- if (new == NULL)
- break;
- v = new;
- }
-
- dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d;
- vnew = (DIRENT_TYPE *) malloc (dsize);
- if (vnew == NULL)
- break;
-
- v[i++] = (DIRENT_TYPE *) memcpy (vnew, d, dsize);
- }
+ {
+ int use_it = select == NULL;
+
+ if (! use_it)
+ {
+ use_it = select (d);
+ /* The select function might have changed errno. It was
+ zero before and it need to be again to make the latter
+ tests work. */
+ __set_errno (0);
+ }
+
+ if (use_it)
+ {
+ DIRENT_TYPE *vnew;
+ size_t dsize;
+
+ /* Ignore errors from select or readdir */
+ __set_errno (0);
+
+ if (__builtin_expect (i == vsize, 0))
+ {
+ DIRENT_TYPE **new;
+ if (vsize == 0)
+ vsize = 10;
+ else
+ vsize *= 2;
+ new = (DIRENT_TYPE **) realloc (v, vsize * sizeof (*v));
+ if (new == NULL)
+ break;
+ v = new;
+ }
+
+ dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d;
+ vnew = (DIRENT_TYPE *) malloc (dsize);
+ if (vnew == NULL)
+ break;
+
+ v[i++] = (DIRENT_TYPE *) memcpy (vnew, d, dsize);
+ }
+ }
if (__builtin_expect (errno, 0) != 0)
{