-/* Copyright (C) 1992-1998, 2000, 2002, 2003, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 1992-1998, 2000, 2002-2003, 2009-2010 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
#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 __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
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;
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)
save = errno;
while (c.cnt > 0)
- free (v[--c.cnt]);
+ free (v[--c.cnt]);
free (v);
c.cnt = -1;
}
{
/* 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;
}