This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.21-338-gd2ee815


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  d2ee815ad677bba720c4f0275c1d6065f5809e7a (commit)
       via  83c10893259916152d277327fa37d8f70bb4d4c2 (commit)
       via  b88a18e10c9b18a74e2c2b26817189a5841cff12 (commit)
      from  d9efd775ba51916b58b899d8b1c8501105a830de (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d2ee815ad677bba720c4f0275c1d6065f5809e7a

commit d2ee815ad677bba720c4f0275c1d6065f5809e7a
Author: Roland McGrath <roland@hack.frob.com>
Date:   Wed May 13 12:34:11 2015 -0700

    Refactor scandir/scandirat to use common tail.

diff --git a/ChangeLog b/ChangeLog
index 00079ec..6ecfde2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2015-05-13  Roland McGrath  <roland@hack.frob.com>
 
+	* dirent/scandir64-tail.c: New file.
+	* dirent/Makefile (routines): Add them.
+	* include/dirent.h (__scandir_tail, __scandir64_tail): Declare them.
+	* dirent/scandir.c [!SCANDIR] (SCANDIRAT): Macro removed.
+	[!SCANDIR] (SCANDIR_TAIL): New macro.
+	(SCANDIR): Call __opendir and __scandir_tail, not __scandirat.
+	* dirent/scandir64.c [!_DIRENT_MATCHES_DIRENT64]
+	(SCANDIRAT): Macro removed.
+	(SCANDIR_TAIL): New macro.
+	* dirent/scandirat.c [!SCANDIRAT] (READDIR): Macro removed.
+	[!SCANDIRAT] (SCANDIR_TAIL): New macro.
+	(SCANDIRAT): Just call __opendirat and __scandir_tail.
+	* dirent/scandirat64.c [!_DIRENT_MATCHES_DIRENT64]
+	(READDIR): Macro removed.
+	(SCANDIR_TAIL): New macro.
+	* sysdeps/unix/sysv/linux/i386/scandir64.c (READDIR): Macro removed.
+	(SCANDIR_TAIL): New macro.
+
 	* dirent/scandirat.c (__scandir_cancel_handler): Function moved ...
 	* dirent/scandir-cancel.c: ... to this new file.
 	* dirent/Makefile (routines): Add it.
diff --git a/dirent/Makefile b/dirent/Makefile
index 2a97649..551372e 100644
--- a/dirent/Makefile
+++ b/dirent/Makefile
@@ -27,7 +27,8 @@ routines	:= opendir closedir readdir readdir_r rewinddir \
 		   seekdir telldir scandir alphasort versionsort \
 		   getdents getdents64 dirfd readdir64 readdir64_r scandir64 \
 		   alphasort64 versionsort64 fdopendir \
-		   scandirat scandirat64 scandir-cancel
+		   scandirat scandirat64 \
+		   scandir-cancel scandir-tail scandir64-tail
 
 tests	   := list tst-seekdir opendir-tst1 bug-readdir1 tst-fdopendir \
 	      tst-fdopendir2 tst-scandir tst-scandir64
diff --git a/dirent/scandir-tail.c b/dirent/scandir-tail.c
new file mode 100644
index 0000000..4560834
--- /dev/null
+++ b/dirent/scandir-tail.c
@@ -0,0 +1,110 @@
+/* Logic guts of scandir*.
+   Copyright (C) 1992-2015 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bits/libc-lock.h>
+
+#ifndef SCANDIR_TAIL
+# define SCANDIR_TAIL	__scandir_tail
+# define READDIR	__readdir
+# define DIRENT_TYPE	struct dirent
+#endif
+
+internal_function
+int
+SCANDIR_TAIL (DIR *dp,
+              DIRENT_TYPE ***namelist,
+              int (*select) (const DIRENT_TYPE *),
+              int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **))
+{
+  if (dp == NULL)
+    return -1;
+
+  int save = errno;
+  __set_errno (0);
+
+  int result;
+  struct scandir_cancel_struct c = { .dp = dp };
+  __libc_cleanup_push (&__scandir_cancel_handler, &c);
+
+  DIRENT_TYPE **v = NULL;
+  size_t vsize = 0;
+  DIRENT_TYPE *d;
+  while ((d = READDIR (dp)) != NULL)
+    {
+      if (select != NULL)
+        {
+          int selected = (*select) (d);
+
+	  /* The SELECT function might have changed errno.  It was
+	     zero before and it need to be again to make the later
+	     tests work.  */
+	  __set_errno (0);
+
+          if (!selected)
+            continue;
+        }
+      else
+        __set_errno (0);
+
+      if (__glibc_unlikely (c.cnt == vsize))
+        {
+          if (vsize == 0)
+            vsize = 10;
+          else
+            vsize *= 2;
+          DIRENT_TYPE **new = realloc (v, vsize * sizeof *v);
+          if (new == NULL)
+            break;
+          c.v = v = new;
+        }
+
+      size_t dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d;
+      DIRENT_TYPE *vnew = malloc (dsize);
+      if (vnew == NULL)
+        break;
+      v[c.cnt++] = (DIRENT_TYPE *) memcpy (vnew, d, dsize);
+    }
+
+  if (__glibc_likely (errno == 0))
+    {
+      __closedir (dp);
+
+      /* Sort the list if we have a comparison function to sort with.  */
+      if (cmp != NULL)
+	qsort (v, c.cnt, sizeof *v, (__compar_fn_t) cmp);
+
+      *namelist = v;
+      result = c.cnt;
+    }
+  else
+    {
+      /* This frees everything and calls closedir.  */
+      __scandir_cancel_handler (&c);
+      result = -1;
+    }
+
+  __libc_cleanup_pop (0);
+
+  if (result >= 0)
+    __set_errno (save);
+  return result;
+}
diff --git a/dirent/scandir.c b/dirent/scandir.c
index 99c9681..c0c3f7a 100644
--- a/dirent/scandir.c
+++ b/dirent/scandir.c
@@ -24,23 +24,20 @@
 
 #undef  scandir64
 
-#include <fcntl.h>
-
 #ifndef SCANDIR
-# define SCANDIR scandir
-# define SCANDIRAT __scandirat
-# define DIRENT_TYPE struct dirent
+# define SCANDIR        scandir
+# define SCANDIR_TAIL   __scandir_tail
+# define DIRENT_TYPE    struct dirent
 #endif
 
 
 int
-SCANDIR (dir, namelist, select, cmp)
-     const char *dir;
-     DIRENT_TYPE ***namelist;
-     int (*select) (const DIRENT_TYPE *);
-     int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **);
+SCANDIR (const char *dir,
+	 DIRENT_TYPE ***namelist,
+	 int (*select) (const DIRENT_TYPE *),
+	 int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **))
 {
-  return SCANDIRAT (AT_FDCWD, dir, namelist, select, cmp);
+  return SCANDIR_TAIL (__opendir (dir), namelist, select, cmp);
 }
 
 #ifdef _DIRENT_MATCHES_DIRENT64
diff --git a/dirent/scandir64.c b/dirent/scandir64-tail.c
similarity index 75%
copy from dirent/scandir64.c
copy to dirent/scandir64-tail.c
index d9f780f..b10dd0a 100644
--- a/dirent/scandir64.c
+++ b/dirent/scandir64-tail.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000-2015 Free Software Foundation, Inc.
+/* Logic guts of scandir*64.
+   Copyright (C) 2015 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
@@ -17,13 +18,9 @@
 
 #include <dirent.h>
 
-/* scandir.c defines scandir64 as an alias if _DIRENT_MATCHES_DIRENT64.  */
 #ifndef _DIRENT_MATCHES_DIRENT64
-
-#define SCANDIR scandir64
-#define SCANDIRAT scandirat64
-#define DIRENT_TYPE struct dirent64
-
-#include <dirent/scandir.c>
-
+# define SCANDIR_TAIL   __scandir64_tail
+# define READDIR        __readdir64
+# define DIRENT_TYPE    struct dirent64
+# include <scandir-tail.c>
 #endif
diff --git a/dirent/scandir64.c b/dirent/scandir64.c
index d9f780f..fbb1866 100644
--- a/dirent/scandir64.c
+++ b/dirent/scandir64.c
@@ -20,10 +20,10 @@
 /* scandir.c defines scandir64 as an alias if _DIRENT_MATCHES_DIRENT64.  */
 #ifndef _DIRENT_MATCHES_DIRENT64
 
-#define SCANDIR scandir64
-#define SCANDIRAT scandirat64
-#define DIRENT_TYPE struct dirent64
+# define SCANDIR        scandir64
+# define SCANDIR_TAIL   __scandir64_tail
+# define DIRENT_TYPE    struct dirent64
 
-#include <dirent/scandir.c>
+# include <dirent/scandir.c>
 
 #endif
diff --git a/dirent/scandirat.c b/dirent/scandirat.c
index d7ae5e5..41725af 100644
--- a/dirent/scandirat.c
+++ b/dirent/scandirat.c
@@ -24,114 +24,20 @@
 
 #undef  scandirat64
 
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <bits/libc-lock.h>
-
 #ifndef SCANDIRAT
-# define SCANDIRAT __scandirat
-# define READDIR __readdir
-# define DIRENT_TYPE struct dirent
+# define SCANDIRAT	__scandirat
+# define SCANDIR_TAIL	__scandir_tail
+# define DIRENT_TYPE	struct dirent
 # define SCANDIRAT_WEAK_ALIAS
 #endif
 
-
 int
-SCANDIRAT (dfd, dir, namelist, select, cmp)
-     int dfd;
-     const char *dir;
-     DIRENT_TYPE ***namelist;
-     int (*select) (const DIRENT_TYPE *);
-     int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **);
+SCANDIRAT (int dfd, const char *dir,
+	   DIRENT_TYPE ***namelist,
+	   int (*select) (const DIRENT_TYPE *),
+	   int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **))
 {
-  DIR *dp = __opendirat (dfd, 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 (__glibc_unlikely (c.cnt == vsize))
-	    {
-	      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 SCANDIR_TAIL (__opendirat (dfd, dir), namelist, select, cmp);
 }
 libc_hidden_def (SCANDIRAT)
 #ifdef SCANDIRAT_WEAK_ALIAS
diff --git a/dirent/scandirat64.c b/dirent/scandirat64.c
index fcdd1a9..e330a7b 100644
--- a/dirent/scandirat64.c
+++ b/dirent/scandirat64.c
@@ -20,10 +20,10 @@
 /* scandirat.c defines scandirat64 as an alias if _DIRENT_MATCHES_DIRENT64.  */
 #ifndef _DIRENT_MATCHES_DIRENT64
 
-#define SCANDIRAT scandirat64
-#define READDIR __readdir64
-#define DIRENT_TYPE struct dirent64
+# define SCANDIRAT      scandirat64
+# define SCANDIR_TAIL   __scandir64_tail
+# define DIRENT_TYPE    struct dirent64
 
-#include "scandirat.c"
+# include <scandirat.c>
 
 #endif
diff --git a/include/dirent.h b/include/dirent.h
index c50bd23..258f2d0 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -49,6 +49,26 @@ extern DIR *__alloc_dir (int fd, bool close_fd, int flags,
 extern __typeof (rewinddir) __rewinddir;
 
 extern void __scandir_cancel_handler (void *arg) attribute_hidden;
+extern int __scandir_tail (DIR *dp,
+			   struct dirent ***namelist,
+			   int (*select) (const struct dirent *),
+			   int (*cmp) (const struct dirent **,
+				       const struct dirent **))
+  internal_function attribute_hidden;
+#  ifdef _DIRENT_MATCHES_DIRENT64
+#   define __scandir64_tail (dp, namelist, select, cmp)         \
+  __scandir_tail (dp, (struct dirent ***) (namelist),           \
+		  (int (*) (const struct dirent *)) (select),   \
+		  (int (*) (const struct dirent **,             \
+			    const struct dirent **)) (cmp))
+#  else
+extern int __scandir64_tail (DIR *dp,
+			     struct dirent64 ***namelist,
+			     int (*select) (const struct dirent64 *),
+			     int (*cmp) (const struct dirent64 **,
+					 const struct dirent64 **))
+  internal_function attribute_hidden;
+#  endif
 
 libc_hidden_proto (__rewinddir)
 extern __typeof (scandirat) __scandirat;
diff --git a/sysdeps/unix/sysv/linux/i386/scandir64.c b/sysdeps/unix/sysv/linux/i386/scandir64.c
index 824bf84..8629078 100644
--- a/sysdeps/unix/sysv/linux/i386/scandir64.c
+++ b/sysdeps/unix/sysv/linux/i386/scandir64.c
@@ -17,22 +17,21 @@
 
 #include <dirent.h>
 
-#define SCANDIR __scandir64
-#define SCANDIRAT scandirat64
-#define READDIR __readdir64
-#define DIRENT_TYPE struct dirent64
+#define SCANDIR		__scandir64
+#define SCANDIR_TAIL	__scandir64_tail
+#define DIRENT_TYPE	struct dirent64
 
 #include <dirent/scandir.c>
 
-#undef SCANDIR
-#undef READDIR
-#undef DIRENT_TYPE
+#undef	SCANDIR
+#undef	SCANDIR_TAIL
+#undef	DIRENT_TYPE
 
 #include <shlib-compat.h>
 
 versioned_symbol (libc, __scandir64, scandir64, GLIBC_2_2);
 
-#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
 # include <string.h>
 # include <errno.h>
 # include "olddirent.h"

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=83c10893259916152d277327fa37d8f70bb4d4c2

commit 83c10893259916152d277327fa37d8f70bb4d4c2
Author: Roland McGrath <roland@hack.frob.com>
Date:   Wed May 13 12:33:56 2015 -0700

    Break __scandir_cancel_handler out into its own file.

diff --git a/ChangeLog b/ChangeLog
index deb575d..00079ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2015-05-13  Roland McGrath  <roland@hack.frob.com>
 
+	* dirent/scandirat.c (__scandir_cancel_handler): Function moved ...
+	* dirent/scandir-cancel.c: ... to this new file.
+	* dirent/Makefile (routines): Add it.
+	* dirent/scandirat64.c (SKIP_SCANDIR_CANCEL): Macro removed.
+	* sysdeps/unix/sysv/linux/i386/scandir64.c
+	(SKIP_SCANDIR_CANCEL): Macro removed.
+	* include/dirent.h (__scandir_cancel_handler): Add attribute_hidden.
+
 	* dirent/tst-scandir.c: New file.
 	* dirent/tst-scandir64.c: New file.
 	* dirent/Makefile (tests): Add them.
diff --git a/dirent/Makefile b/dirent/Makefile
index 3c71ccf..2a97649 100644
--- a/dirent/Makefile
+++ b/dirent/Makefile
@@ -27,7 +27,7 @@ routines	:= opendir closedir readdir readdir_r rewinddir \
 		   seekdir telldir scandir alphasort versionsort \
 		   getdents getdents64 dirfd readdir64 readdir64_r scandir64 \
 		   alphasort64 versionsort64 fdopendir \
-		   scandirat scandirat64
+		   scandirat scandirat64 scandir-cancel
 
 tests	   := list tst-seekdir opendir-tst1 bug-readdir1 tst-fdopendir \
 	      tst-fdopendir2 tst-scandir tst-scandir64
diff --git a/dirent/scandirat64.c b/dirent/scandir-cancel.c
similarity index 69%
copy from dirent/scandirat64.c
copy to dirent/scandir-cancel.c
index c9a6186..549a4f8 100644
--- a/dirent/scandirat64.c
+++ b/dirent/scandir-cancel.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000-2015 Free Software Foundation, Inc.
+/* Cancellation handler used in scandir* implementations.
+   Copyright (C) 1992-2015 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
@@ -17,14 +18,14 @@
 
 #include <dirent.h>
 
-/* scandirat.c defines scandirat64 as an alias if _DIRENT_MATCHES_DIRENT64.  */
-#ifndef _DIRENT_MATCHES_DIRENT64
-
-#define SCANDIRAT scandirat64
-#define READDIR __readdir64
-#define DIRENT_TYPE struct dirent64
-#define SKIP_SCANDIR_CANCEL 1
-
-#include "scandirat.c"
-
-#endif
+void
+__scandir_cancel_handler (void *arg)
+{
+  struct scandir_cancel_struct *cp = arg;
+  void **v = cp->v;
+
+  for (size_t i = 0; i < cp->cnt; ++i)
+    free (v[i]);
+  free (v);
+  (void) __closedir (cp->dp);
+}
diff --git a/dirent/scandirat.c b/dirent/scandirat.c
index 004b152..d7ae5e5 100644
--- a/dirent/scandirat.c
+++ b/dirent/scandirat.c
@@ -36,21 +36,6 @@
 # define SCANDIRAT_WEAK_ALIAS
 #endif
 
-#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);
-}
-#endif
-
 
 int
 SCANDIRAT (dfd, dir, namelist, select, cmp)
diff --git a/dirent/scandirat64.c b/dirent/scandirat64.c
index c9a6186..fcdd1a9 100644
--- a/dirent/scandirat64.c
+++ b/dirent/scandirat64.c
@@ -23,7 +23,6 @@
 #define SCANDIRAT scandirat64
 #define READDIR __readdir64
 #define DIRENT_TYPE struct dirent64
-#define SKIP_SCANDIR_CANCEL 1
 
 #include "scandirat.c"
 
diff --git a/include/dirent.h b/include/dirent.h
index 2e797ae..c50bd23 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -46,9 +46,10 @@ extern int __versionsort64 (const struct dirent64 **a,
 extern DIR *__alloc_dir (int fd, bool close_fd, int flags,
 			 const struct stat64 *statp)
      internal_function;
-extern void __scandir_cancel_handler (void *arg);
 extern __typeof (rewinddir) __rewinddir;
 
+extern void __scandir_cancel_handler (void *arg) attribute_hidden;
+
 libc_hidden_proto (__rewinddir)
 extern __typeof (scandirat) __scandirat;
 libc_hidden_proto (__scandirat)
diff --git a/sysdeps/unix/sysv/linux/i386/scandir64.c b/sysdeps/unix/sysv/linux/i386/scandir64.c
index 6dafa84..824bf84 100644
--- a/sysdeps/unix/sysv/linux/i386/scandir64.c
+++ b/sysdeps/unix/sysv/linux/i386/scandir64.c
@@ -21,7 +21,6 @@
 #define SCANDIRAT scandirat64
 #define READDIR __readdir64
 #define DIRENT_TYPE struct dirent64
-#define SKIP_SCANDIR_CANCEL 1
 
 #include <dirent/scandir.c>
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b88a18e10c9b18a74e2c2b26817189a5841cff12

commit b88a18e10c9b18a74e2c2b26817189a5841cff12
Author: Roland McGrath <roland@hack.frob.com>
Date:   Wed May 13 12:33:41 2015 -0700

    Add a test case for scandir.

diff --git a/ChangeLog b/ChangeLog
index dc7431b..deb575d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-05-13  Roland McGrath  <roland@hack.frob.com>
+
+	* dirent/tst-scandir.c: New file.
+	* dirent/tst-scandir64.c: New file.
+	* dirent/Makefile (tests): Add them.
+
 2015-05-13  H.J. Lu  <hongjiu.lu@intel.com>
 
 	[BZ #18409]
diff --git a/dirent/Makefile b/dirent/Makefile
index b4f0a91..3c71ccf 100644
--- a/dirent/Makefile
+++ b/dirent/Makefile
@@ -30,7 +30,7 @@ routines	:= opendir closedir readdir readdir_r rewinddir \
 		   scandirat scandirat64
 
 tests	   := list tst-seekdir opendir-tst1 bug-readdir1 tst-fdopendir \
-	      tst-fdopendir2
+	      tst-fdopendir2 tst-scandir tst-scandir64
 
 CFLAGS-scandir.c = $(uses-callbacks)
 CFLAGS-scandir64.c = $(uses-callbacks)
diff --git a/dirent/tst-scandir.c b/dirent/tst-scandir.c
new file mode 100644
index 0000000..a7ad9b6
--- /dev/null
+++ b/dirent/tst-scandir.c
@@ -0,0 +1,298 @@
+/* Basic test for scandir function.
+   Copyright (C) 2015 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef D
+# define D(x) x
+#endif
+
+static void prepare (void);
+static int do_test (void);
+#define PREPARE(argc, argv)     prepare ()
+#define TEST_FUNCTION           do_test ()
+#include "../test-skeleton.c"
+
+static const char *scandir_test_dir;
+
+static void
+prepare (void)
+{
+  size_t test_dir_len = strlen (test_dir);
+  static const char dir_name[] = "/tst-scandir.XXXXXX";
+
+  size_t dirbuflen = test_dir_len + sizeof (dir_name);
+  char *dirbuf = malloc (dirbuflen);
+  if (dirbuf == NULL)
+    {
+      puts ("out of memory");
+      exit (1);
+    }
+
+  snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
+  if (mkdtemp (dirbuf) == NULL)
+    {
+      puts ("cannot create temporary directory");
+      exit (1);
+    }
+
+  add_temp_file (dirbuf);
+  scandir_test_dir = dirbuf;
+}
+
+/* The directory should be empty save the . and .. files.  */
+static void
+verify_empty (const char *dirname)
+{
+  DIR *dir = opendir (dirname);
+  if (dir == NULL)
+    {
+      printf ("opendir (%s): %s\n", dirname, strerror (errno));
+      exit (1);
+    }
+
+  struct dirent64 *d;
+  while ((d = readdir64 (dir)) != NULL)
+    if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
+      {
+        printf ("temp directory contains file \"%s\"\n", d->d_name);
+        exit (1);
+      }
+
+  closedir (dir);
+}
+
+static void
+make_file (const char *dirname, const char *filename)
+{
+  char *name = NULL;
+  if (asprintf (&name, "%s/%s", dirname, filename) < 0)
+    {
+      puts ("out of memory");
+      exit (1);
+    }
+
+  int fd = open (name, O_WRONLY | O_CREAT | O_EXCL, 0600);
+  if (fd < 0)
+    {
+      printf ("cannot create \"%s\": %s\n", name, strerror (errno));
+      exit (1);
+    }
+  close (fd);
+
+  free (name);
+}
+
+static void
+remove_file (const char *dirname, const char *filename)
+{
+  char *name = NULL;
+  if (asprintf (&name, "%s/%s", dirname, filename) < 0)
+    {
+      puts ("out of memory");
+      exit (1);
+    }
+
+  remove (name);
+
+  free (name);
+}
+
+static void
+freelist (struct D(dirent) **list, size_t n)
+{
+  for (size_t i = 0; i < n; ++i)
+    free (list[i]);
+  free (list);
+}
+
+static int
+select_a (const struct D(dirent) *d)
+{
+  return d->d_name[0] == 'a';
+}
+
+static int
+do_test (void)
+{
+  verify_empty (scandir_test_dir);
+
+  make_file (scandir_test_dir, "c");
+  make_file (scandir_test_dir, "aa");
+  make_file (scandir_test_dir, "b");
+  make_file (scandir_test_dir, "a");
+
+
+  /* First a basic test with no select or compare functions.  */
+
+  struct D(dirent) **list;
+  int n = D(scandir) (scandir_test_dir, &list, NULL, NULL);
+  if (n < 0)
+    {
+      printf ("scandir failed on %s: %s\n",
+              scandir_test_dir, strerror (errno));
+      return 1;
+    }
+  if (n != 6)
+    {
+      printf ("scandir returned %d entries instead of 6\n", n);
+      return 1;
+    }
+
+  struct
+  {
+    const char *name;
+    bool found;
+  } expected[] =
+    {
+      { ".", },
+      { "..", },
+      { "a", },
+      { "aa", },
+      { "b", },
+      { "c", },
+    };
+
+  /* Verify the results, ignoring the order.  */
+  for (int i = 0; i < n; ++i)
+    {
+      for (size_t j = 0; j < sizeof expected / sizeof expected[0]; ++j)
+        if (!strcmp (list[i]->d_name, expected[j].name))
+          {
+            expected[j].found = true;
+            goto found;
+          }
+
+      printf ("scandir yields unexpected entry [%d] \"%s\"\n",
+              i, list[i]->d_name);
+      return 1;
+
+    found:;
+    }
+
+  for (size_t j = 0; j < sizeof expected / sizeof expected[0]; ++j)
+    if (!expected[j].found)
+      {
+        printf ("failed to produce \"%s\"\n", expected[j].name);
+        return 1;
+      }
+
+  freelist (list, n);
+
+
+  /* Now a test with a comparison function.  */
+
+  n = D(scandir) (scandir_test_dir, &list, NULL, &D(alphasort));
+  if (n < 0)
+    {
+      printf ("scandir failed on %s: %s\n",
+              scandir_test_dir, strerror (errno));
+      return 1;
+    }
+  if (n != 6)
+    {
+      printf ("scandir returned %d entries instead of 6\n", n);
+      return 1;
+    }
+
+  assert (sizeof expected / sizeof expected[0] == 6);
+  for (int i = 0; i < n; ++i)
+    if (strcmp (list[i]->d_name, expected[i].name))
+      {
+        printf ("scandir yields [%d] of \"%s\", expected \"%s\"\n",
+                i, list[i]->d_name, expected[i].name);
+        return 1;
+      }
+
+  freelist (list, n);
+
+
+  /* Now a test with a select function but no comparison function.  */
+
+  n = D(scandir) (scandir_test_dir, &list, &select_a, NULL);
+  if (n < 0)
+    {
+      printf ("scandir failed on %s: %s\n",
+              scandir_test_dir, strerror (errno));
+      return 1;
+    }
+  if (n != 2)
+    {
+      printf ("scandir returned %d entries instead of 2\n", n);
+      return 1;
+    }
+
+  if (strcmp (list[0]->d_name, "a") && strcmp (list[0]->d_name, "aa"))
+    {
+      printf ("scandir yields [0] \"%s\", expected \"a\" or \"aa\"\n",
+              list[0]->d_name);
+      return 1;
+    }
+  if (strcmp (list[1]->d_name, "a") && strcmp (list[1]->d_name, "aa"))
+    {
+      printf ("scandir yields [1] \"%s\", expected \"a\" or \"aa\"\n",
+              list[1]->d_name);
+      return 1;
+    }
+  if (!strcmp (list[0]->d_name, list[1]->d_name))
+    {
+      printf ("scandir yields \"%s\" twice!\n", list[0]->d_name);
+      return 1;
+    }
+
+  freelist (list, n);
+
+
+  /* Now a test with both functions.  */
+
+  n = D(scandir) (scandir_test_dir, &list, &select_a, &D(alphasort));
+  if (n < 0)
+    {
+      printf ("scandir failed on %s: %s\n",
+              scandir_test_dir, strerror (errno));
+      return 1;
+    }
+  if (n != 2)
+    {
+      printf ("scandir returned %d entries instead of 2\n", n);
+      return 1;
+    }
+
+  if (strcmp (list[0]->d_name, "a") || strcmp (list[1]->d_name, "aa"))
+    {
+      printf ("scandir yields {\"%s\", \"%s\"}, expected {\"a\", \"aa\"}\n",
+              list[0]->d_name, list[1]->d_name);
+      return 1;
+    }
+
+  freelist (list, n);
+
+
+  /* Clean up the test directory.  */
+  remove_file (scandir_test_dir, "c");
+  remove_file (scandir_test_dir, "aa");
+  remove_file (scandir_test_dir, "b");
+  remove_file (scandir_test_dir, "a");
+  rmdir (scandir_test_dir);
+
+  return 0;
+}
diff --git a/dirent/tst-scandir64.c b/dirent/tst-scandir64.c
new file mode 100644
index 0000000..3f4c68e
--- /dev/null
+++ b/dirent/tst-scandir64.c
@@ -0,0 +1,2 @@
+#define D(x) x##64
+#include "tst-scandir.c"

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                |   32 ++++
 dirent/Makefile                          |    5 +-
 dirent/scandir-cancel.c                  |   31 +++
 dirent/scandir-tail.c                    |  110 +++++++++++
 dirent/scandir.c                         |   19 +-
 dirent/scandir64-tail.c                  |   26 +++
 dirent/scandir64.c                       |    8 +-
 dirent/scandirat.c                       |  125 +------------
 dirent/scandirat64.c                     |    9 +-
 dirent/tst-scandir.c                     |  298 ++++++++++++++++++++++++++++++
 dirent/tst-scandir64.c                   |    2 +
 include/dirent.h                         |   23 +++-
 sysdeps/unix/sysv/linux/i386/scandir64.c |   16 +-
 13 files changed, 555 insertions(+), 149 deletions(-)
 create mode 100644 dirent/scandir-cancel.c
 create mode 100644 dirent/scandir-tail.c
 create mode 100644 dirent/scandir64-tail.c
 create mode 100644 dirent/tst-scandir.c
 create mode 100644 dirent/tst-scandir64.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]