about summary refs log tree commit diff
path: root/dirent/scandir.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-08-09 09:57:55 -0400
committerUlrich Drepper <drepper@gmail.com>2011-08-09 09:57:55 -0400
commitc55fbd1ea768f9fdef34a01377702c0d72cbc213 (patch)
tree0e67d339ad240756843292384535c40cad03df95 /dirent/scandir.c
parent879165f25a1a6b13995e43c11e88b1a21b6f101e (diff)
downloadglibc-c55fbd1ea768f9fdef34a01377702c0d72cbc213.tar.gz
glibc-c55fbd1ea768f9fdef34a01377702c0d72cbc213.tar.xz
glibc-c55fbd1ea768f9fdef34a01377702c0d72cbc213.zip
Implement scandirat function
Diffstat (limited to 'dirent/scandir.c')
-rw-r--r--dirent/scandir.c122
1 files changed, 3 insertions, 119 deletions
diff --git a/dirent/scandir.c b/dirent/scandir.c
index e90b942b1d..3f69a8db77 100644
--- a/dirent/scandir.c
+++ b/dirent/scandir.c
@@ -18,44 +18,14 @@
    02111-1307 USA.  */
 
 #include <dirent.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <bits/libc-lock.h>
+#include <fcntl.h>
 
 #ifndef SCANDIR
 # define SCANDIR scandir
-# define READDIR __readdir
+# define SCANDIRAT scandirat
 # define DIRENT_TYPE struct dirent
 #endif
 
-#ifndef SCANDIR_CANCEL
-# define SCANDIR_CANCEL
-struct scandir_cancel_struct
-{
-  DIR *dp;
-  void *v;
-  size_t cnt;
-};
-
-# ifndef SKIP_SCANDIR_CANCEL
-void
-__scandir_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);
-}
-# else
-extern void __scandir_cancel_handler (void *arg);
-# endif
-#endif
-
 
 int
 SCANDIR (dir, namelist, select, cmp)
@@ -64,91 +34,5 @@ SCANDIR (dir, namelist, select, cmp)
      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;
-  __libc_cleanup_push (__scandir_cancel_handler, &c);
-
-  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;
-    }
-
-  __libc_cleanup_pop (0);
-
-  (void) __closedir (dp);
-  __set_errno (save);
-
-  return c.cnt;
+  return SCANDIRAT (AT_FDCWD, dir, namelist, select, cmp);
 }