X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fscandir.c;h=824fe178a129b0a44fc2d19e2dbf6f93a34c806d;hb=6e33eaed1cd5ddcdfc48476059012fed68f71f8e;hp=8b34070e86f59d3eb678dce2f6500b9f57259a90;hpb=3806f4f65ae6cb6106c82397a4ebba739336175f;p=gnulib.git diff --git a/lib/scandir.c b/lib/scandir.c index 8b34070e8..824fe178a 100644 --- a/lib/scandir.c +++ b/lib/scandir.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1992-1998, 2000, 2002, 2003, 2009 Free Software Foundation, Inc. +/* Copyright (C) 1992-1998, 2000, 2002-2003, 2009-2011 Free Software + Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify it @@ -32,6 +33,13 @@ #undef select +#ifndef _D_EXACT_NAMLEN +# define _D_EXACT_NAMLEN(d) strlen ((d)->d_name) +#endif +#ifndef _D_ALLOC_NAMLEN +# define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1) +#endif + #if _LIBC # ifndef SCANDIR # define SCANDIR scandir @@ -45,6 +53,14 @@ # define __opendir opendir # define __closedir closedir # define __set_errno(val) errno = (val) + +/* The results of opendir() in this file are not used with dirfd and fchdir, + and we do not leak fds to any single-threaded code that could use stdio, + therefore save some unnecessary recursion in fchdir.c and opendir_safer.c. + FIXME - if the kernel ever adds support for multi-thread safety for + avoiding standard fds, then we should use opendir_safer. */ +# undef opendir +# undef closedir #endif #ifndef SCANDIR_CANCEL @@ -75,9 +91,9 @@ cancel_handler (void *arg) int SCANDIR (const char *dir, - DIRENT_TYPE ***namelist, - int (*select) (const DIRENT_TYPE *), - int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) + DIRENT_TYPE ***namelist, + int (*select) (const DIRENT_TYPE *), + int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) { DIR *dp = __opendir (dir); DIRENT_TYPE **v = NULL; @@ -104,43 +120,43 @@ SCANDIR (const char *dir, 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); - } + { + 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 (c.cnt == 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; - c.v = (void *) v; - } - - dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d; - vnew = (DIRENT_TYPE *) malloc (dsize); - if (vnew == NULL) - break; - - v[c.cnt++] = (DIRENT_TYPE *) memcpy (vnew, d, dsize); - } + { + DIRENT_TYPE *vnew; + size_t dsize; + + /* Ignore errors from select or readdir */ + __set_errno (0); + + if (__builtin_expect (c.cnt == 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; + c.v = (void *) v; + } + + dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d; + vnew = (DIRENT_TYPE *) malloc (dsize); + if (vnew == NULL) + break; + + v[c.cnt++] = (DIRENT_TYPE *) memcpy (vnew, d, dsize); + } } if (__builtin_expect (errno, 0) != 0) @@ -148,7 +164,7 @@ SCANDIR (const char *dir, save = errno; while (c.cnt > 0) - free (v[--c.cnt]); + free (v[--c.cnt]); free (v); c.cnt = -1; } @@ -156,7 +172,7 @@ SCANDIR (const char *dir, { /* Sort the list if we have a comparison function to sort with. */ if (cmp != NULL) - qsort (v, c.cnt, sizeof (*v), (int (*) (const void *, const void *)) cmp); + qsort (v, c.cnt, sizeof (*v), (int (*) (const void *, const void *)) cmp); *namelist = v; }