Subject: Re: PR/36464 CVS commit: src/lib/libc/gen
To: None <lib-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Christos Zoulas <christos@zoulas.com>
List: netbsd-bugs
Date: 06/12/2007 12:00:04
The following reply was made to PR lib/36464; it has been noted by GNATS.
From: christos@zoulas.com (Christos Zoulas)
To: Ed Ravin <eravin@panix.com>, gnats-bugs@NetBSD.org
Cc:
Subject: Re: PR/36464 CVS commit: src/lib/libc/gen
Date: Tue, 12 Jun 2007 07:58:44 -0400
On Jun 12, 12:29am, eravin@panix.com (Ed Ravin) wrote:
-- Subject: Re: PR/36464 CVS commit: src/lib/libc/gen
Thanks, I will ask releng to pull it up.
christos
| See attached for a patch against 3.1. It seems to work for the two apps
| I tried that use scandir() (Pine, Midnight Commander).
|
| I got lazy and left the "divide by 24" bit in there, but otherwise
| I think it matches what you did with the current tree.
|
|
| --rwEMma7ioTxnRzrJ
| Content-Type: application/DEFANGED-11858; charset="us-ascii"
| Content-Disposition: attachment; filename="scandir_c_diff.DEFANGED-11858"
|
| --- scandir.c 2007/06/11 23:17:07 1.1
| +++ scandir.c 2007/06/12 04:25:56
| @@ -60,6 +60,34 @@
| __weak_alias(alphasort,_alphasort)
| #endif
|
| +
| +/*
| + * Compute an estimate of the number of entries in a directory based on
| + * the file size. Returns the estimated number of entries or 0 on failure.
| + */
| +static size_t
| +dirsize(int fd, size_t olen)
| +{
| + struct stat stb;
| + size_t nlen;
| +
| + if (fstat(fd, &stb) == -1)
| + return 0;
| + /*
| + * Estimate the array size by taking the size of the directory file
| + * and dividing it by a multiple of the minimum size entry.
| + */
| + nlen = (size_t)(stb.st_size / 24 /*_DIRENT_MINSIZE((struct dirent *)0)*/ );
| + /*
| + * If the size turns up 0, switch to an alternate strategy and use the
| + * file size as the number of entries like ZFS returns. If that turns
| + * out to be 0 too return a minimum of 10 entries, plus the old length.
| + */
| + if (nlen == 0)
| + nlen = (size_t)(stb.st_size ? stb.st_size : 10);
| + return olen + nlen;
| +}
| +
| /*
| * The DIRSIZ macro is the minimum record length which will hold the directory
| * entry. This requires the amount of space in struct dirent without the
| @@ -80,7 +108,6 @@
| {
| struct dirent *d, *p, **names, **newnames;
| size_t nitems, arraysz;
| - struct stat stb;
| DIR *dirp;
|
| _DIAGASSERT(dirname != NULL);
| @@ -88,14 +115,10 @@
|
| if ((dirp = opendir(dirname)) == NULL)
| return (-1);
| - if (fstat(dirp->dd_fd, &stb) < 0)
| +
| + if ((arraysz = dirsize(dirp->dd_fd, 0)) == 0)
| goto bad;
|
| - /*
| - * estimate the array size by taking the size of the directory file
| - * and dividing it by a multiple of the minimum size entry.
| - */
| - arraysz = (size_t)(stb.st_size / 24);
| names = malloc(arraysz * sizeof(struct dirent *));
| if (names == NULL)
| goto bad;
| @@ -110,9 +133,8 @@
| * realloc the maximum size.
| */
| if (nitems >= arraysz) {
| - if (fstat(dirp->dd_fd, &stb) < 0)
| - goto bad2; /* just might have grown */
| - arraysz = (size_t)(stb.st_size / 12);
| + if ((arraysz = dirsize(dirp->dd_fd, arraysz)) == 0)
| + goto bad2;
| newnames = realloc(names,
| arraysz * sizeof(struct dirent *));
| if (newnames == NULL)
|
| --rwEMma7ioTxnRzrJ
| Content-Type: text/sanitizer-log; charset="iso-8859-1"
| Content-Transfer-Encoding: 8bit
| Content-Disposition: attachment; filename="sanitizer.log"
|
| This message has been 'sanitized'. This means that potentially
| dangerous content has been rewritten or removed. The following
| log describes which actions were taken.
|
| Sanitizer (start="1181622556"):
| Part (pos="1903"):
| SanitizeFile (filename="unnamed.txt", mimetype="text/plain"):
| Match (names="unnamed.txt", rule="2"):
| Enforced policy: accept
|
| Part (pos="2951"):
| SanitizeFile (filename="scandir.c.diff", mimetype="text/plain"):
| Match (rule="default"):
| Enforced policy: defang
|
| Replaced mime type with: application/DEFANGED-11858
| Replaced file name with: scandir_c_diff.DEFANGED-11858
|
| Total modifications so far: 1
|
|
| Anomy 0.0.0 : Sanitizer.pm
| $Id: Sanitizer.pm,v 1.89 2004/09/02 10:14:15 bre Exp $
| $Id: gw.conf,v 1.1 2005/06/23 02:18:04 kim Exp $
|
| --rwEMma7ioTxnRzrJ--
-- End of excerpt from Ed Ravin