Mail Archives: cygwin-developers/1999/05/23/13:57:13
The following change to scandir is needed to avoid setting errno incorrectly.
There is one more change that I didn't include -- comparison function that
takes void*, not struct dirent* to be glibc2.1 compatible. It's not a big
deal either way since scandir/alphasort is not part of POSIX; I just didn't
feel like changing the headers as well.
Sat May 22 21:45:01 1999 Mumit Khan <khan AT xraylith DOT wisc DOT edu>
* scandir.cc (scandir): Handle errno correctly. Do preallocation to
reduce realloc calls.
(alphasort): Use strcoll, not strcmp.
Index: scandir.cc
===================================================================
RCS file: /home/khan/CVSROOT/cygwin/cygwin-dev/winsup/scandir.cc,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 scandir.cc
--- scandir.cc 1999/05/21 23:51:13 1.1.1.1
+++ scandir.cc 1999/05/23 02:47:05
@@ -12,6 +12,9 @@
#include <dirent.h>
#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "winsup.h"
extern "C"
int
@@ -23,45 +26,76 @@ scandir (const char *dir,
DIR *dirp;
struct dirent *ent, *etmp, **nl = NULL, **ntmp;
int count = 0;
+ int allocated = 0;
if (!(dirp = opendir (dir)))
return -1;
+
+ int prior_errno = get_errno ();
+ set_errno (0);
+
while ((ent = readdir (dirp)))
{
if (!select || select (ent))
{
+
+ /* Ignore error from readdir/select. See POSIX specs. */
+ set_errno (0);
+
+ if (count == allocated)
+ {
+
+ if (allocated == 0)
+ allocated = 10;
+ else
+ allocated *= 2;
+
+ ntmp = (struct dirent **) realloc (nl, allocated * sizeof *nl);
+ if (!ntmp)
+ {
+ set_errno (ENOMEM);
+ break;
+ }
+ nl = ntmp;
+ }
+
if (!(etmp = (struct dirent *) malloc (sizeof *ent)))
- goto error;
- *etmp = *ent;
- ntmp = (struct dirent **) realloc (nl, (count + 1) * sizeof *nl);
- if (!ntmp)
{
- free (etmp);
- goto error;
+ set_errno (ENOMEM);
+ break;
}
- nl = ntmp;
+ *etmp = *ent;
nl[count++] = etmp;
}
}
+
+ if ((prior_errno = get_errno ()) != 0)
+ {
+ closedir (dirp);
+ if (nl)
+ {
+ while (count > 0)
+ free (nl[--count]);
+ free (nl);
+ }
+ /* Ignore errors from closedir() and what not else. */
+ set_errno (prior_errno);
+ return -1;
+ }
+
closedir (dirp);
+ set_errno (prior_errno);
+
qsort (nl, count, sizeof *nl, (int (*)(const void *, const void *)) compar);
if (namelist)
*namelist = nl;
return count;
-
-error:
- if (nl)
- {
- while (count > 0)
- free (nl[--count]);
- free (nl);
- }
- return -1;
}
extern "C"
int
alphasort (const struct dirent **a, const struct dirent **b)
{
- return strcmp ((*a)->d_name, (*b)->d_name);
+ return strcoll ((*a)->d_name, (*b)->d_name);
}
+
- Raw text -