This is the mail archive of the libc-alpha@sources.redhat.com 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]

FreeBSD port (13): getdents() called with too small buffer


Hi,

The size of the buffer that opendir() allocates for subsequent getdents()
calls depends on st_blksize of the directory. But on FreeBSD, the kernel
sets st_blksize to 0 for directories, "to catch bogus uses of this field"
(citing the kernel source comment). In this case the allocated buffer size
will be = sizeof (struct dirent), but this is too small: getdents() returns
EINVAL.

Here is a patch that handles this case like the case when there is no
st_blksize at all: size = max (sizeof (struct dirent), BUFSIZ).

On platforms other than FreeBSD, this patch can only increase the readdir()
throughput, because of the increased buffer size.


2002-07-06  Bruno Haible  <bruno@clisp.org>

	* sysdeps/unix/opendir.c (__opendir): If st_blksize is 0 or too small,
	allocate a buffer of at least BUFSIZ bytes, not just of
	sizeof (struct dirent).

diff -r -c3 glibc-20020627.bak/sysdeps/unix/opendir.c glibc-20020627/sysdeps/unix/opendir.c
--- glibc-20020627.bak/sysdeps/unix/opendir.c	Tue Jul 10 23:01:18 2001
+++ glibc-20020627/sysdeps/unix/opendir.c	Fri Jul  5 01:17:11 2002
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1996,98,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1996,98,2000-2002 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
@@ -135,15 +135,13 @@
     goto lose;
 
 #ifdef _STATBUF_ST_BLKSIZE
-  if (__builtin_expect ((size_t) statbuf.st_blksize < sizeof (struct dirent),
-			0))
-    allocation = sizeof (struct dirent);
-  else
+  if (__builtin_expect ((size_t) statbuf.st_blksize >= sizeof (struct dirent),
+			1))
     allocation = statbuf.st_blksize;
-#else
-  allocation = (BUFSIZ < sizeof (struct dirent)
-		? sizeof (struct dirent) : BUFSIZ);
+  else
 #endif
+    allocation = (BUFSIZ < sizeof (struct dirent)
+		  ? sizeof (struct dirent) : BUFSIZ);
 
   dirp = (DIR *) calloc (1, sizeof (DIR) + allocation); /* Zero-fill.  */
   if (dirp == NULL)


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