* sysdeps/unix/opendir.c (__alloc_dir): If allocation fails for size
authorUlrich Drepper <drepper@redhat.com>
Sun, 30 Mar 2008 08:51:55 +0000 (08:51 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 30 Mar 2008 08:51:55 +0000 (08:51 +0000)
provided through st_blksize, try the default size before giving up.

ChangeLog
sysdeps/unix/opendir.c

index a43e7c6..8ac1f18 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-03-30  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/opendir.c (__alloc_dir): If allocation fails for size
+       provided through st_blksize, try the default size before giving up.
+
 2008-03-29  Ulrich Drepper  <drepper@redhat.com>
 
        * stdio-common/vfprintf.c (vfprintf): Correct overflow test.
index 0a11624..92029c6 100644 (file)
@@ -171,6 +171,8 @@ __alloc_dir (int fd, bool close_fd, const struct stat64 *statp)
        goto lose;
     }
 
+  const size_t default_allocation = (BUFSIZ < sizeof (struct dirent64)
+                                    ? sizeof (struct dirent64) : BUFSIZ);
   size_t allocation;
 #ifdef _STATBUF_ST_BLKSIZE
   if (__builtin_expect ((size_t) statp->st_blksize >= sizeof (struct dirent64),
@@ -178,20 +180,30 @@ __alloc_dir (int fd, bool close_fd, const struct stat64 *statp)
     allocation = statp->st_blksize;
   else
 #endif
-    allocation = (BUFSIZ < sizeof (struct dirent64)
-                 ? sizeof (struct dirent64) : BUFSIZ);
+    allocation = default_allocation;
 
   DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation);
   if (dirp == NULL)
-  lose:
     {
-      if (close_fd)
+#ifdef _STATBUF_ST_BLKSIZE
+      if (allocation == statp->st_blksize
+         && allocation != default_allocation)
        {
-         int save_errno = errno;
-         close_not_cancel_no_status (fd);
-         __set_errno (save_errno);
+         allocation = default_allocation;
+         dirp = (DIR *) malloc (sizeof (DIR) + allocation);
+       }
+      if (dirp == NULL)
+#endif
+      lose:
+       {
+         if (close_fd)
+           {
+             int save_errno = errno;
+             close_not_cancel_no_status (fd);
+             __set_errno (save_errno);
+           }
+         return NULL;
        }
-      return NULL;
     }
 
   dirp->fd = fd;