diff options
author | Ulrich Drepper <drepper@redhat.com> | 2003-06-12 02:04:20 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2003-06-12 02:04:20 +0000 |
commit | 70e1c9303a35ca9f957244fd48058ed6206f14e4 (patch) | |
tree | 424a86eb4b0c08158c245f3c2e7206a636a53725 /dirent | |
parent | 2236d6e12474b6f6b0e6728058257eff9e3e16b6 (diff) | |
download | glibc-70e1c9303a35ca9f957244fd48058ed6206f14e4.zip glibc-70e1c9303a35ca9f957244fd48058ed6206f14e4.tar.gz glibc-70e1c9303a35ca9f957244fd48058ed6206f14e4.tar.bz2 |
Update.
* dirent/scandir.c (SCANDIR): Reset errno after calling selector
function [PR libc/5045].
Diffstat (limited to 'dirent')
-rw-r--r-- | dirent/scandir.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/dirent/scandir.c b/dirent/scandir.c index 9f3cc84..748a490 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) { |