diff options
Diffstat (limited to 'gl/scandir.c')
-rw-r--r-- | gl/scandir.c | 187 |
1 files changed, 0 insertions, 187 deletions
diff --git a/gl/scandir.c b/gl/scandir.c deleted file mode 100644 index d035400def..0000000000 --- a/gl/scandir.c +++ /dev/null @@ -1,187 +0,0 @@ -/* Copyright (C) 1992-1998, 2000, 2002-2003, 2009-2013 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 - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. */ - -#include <config.h> - -#include <dirent.h> - -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#if _LIBC -# include <bits/libc-lock.h> -#endif - -#if ! defined __builtin_expect && __GNUC__ < 3 -# define __builtin_expect(expr, expected) (expr) -#endif - -#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 -# define READDIR __readdir -# define DIRENT_TYPE struct dirent -# endif -#else -# define SCANDIR scandir -# define READDIR readdir -# define DIRENT_TYPE struct dirent -# 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 -# define SCANDIR_CANCEL -struct scandir_cancel_struct -{ - DIR *dp; - void *v; - size_t cnt; -}; - -# if _LIBC -static void -cancel_handler (void *arg) -{ - struct scandir_cancel_struct *cp = arg; - size_t i; - void **v = cp->v; - - for (i = 0; i < cp->cnt; ++i) - free (v[i]); - free (v); - (void) __closedir (cp->dp); -} -# endif -#endif - - -int -SCANDIR (const char *dir, - DIRENT_TYPE ***namelist, - int (*select) (const DIRENT_TYPE *), - int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **)) -{ - DIR *dp = __opendir (dir); - DIRENT_TYPE **v = NULL; - size_t vsize = 0; - struct scandir_cancel_struct c; - DIRENT_TYPE *d; - int save; - - if (dp == NULL) - return -1; - - save = errno; - __set_errno (0); - - c.dp = dp; - c.v = NULL; - c.cnt = 0; -#if _LIBC - __libc_cleanup_push (cancel_handler, &c); -#endif - - while ((d = READDIR (dp)) != NULL) - { - 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 (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) - { - save = errno; - - while (c.cnt > 0) - free (v[--c.cnt]); - free (v); - c.cnt = -1; - } - else - { - /* 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); - - *namelist = v; - } - -#if _LIBC - __libc_cleanup_pop (0); -#endif - - (void) __closedir (dp); - __set_errno (save); - - return c.cnt; -} |