2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: getDirectoryContents.c,v 1.3 1998/12/02 13:27:40 simonm Exp $
6 * getDirectoryContents Runtime Support
12 #ifdef HAVE_SYS_TYPES_H
13 #include <sys/types.h>
16 #ifdef HAVE_SYS_STAT_H
28 /* For cleanup of partial answer on error */
31 freeEntries(char **entries, int count)
35 for (i = 0; i < count; i++)
41 * Our caller expects a malloc'ed array of malloc'ed string pointers.
42 * To ensure consistency when mixing this with other directory
43 * operations, we collect the entire list in one atomic operation,
44 * rather than reading the directory lazily.
47 getDirectoryContents(path)
54 int alloc, count, len;
56 /* Check for an actual directory */
57 while (stat(path, &sb) != 0) {
64 if (!S_ISDIR(sb.st_mode)) {
65 ghc_errtype = ERR_INAPPROPRIATETYPE;
66 ghc_errstr = "not a directory";
71 if ((entries = (char **) malloc(alloc * sizeof(char *))) == NULL) {
72 ghc_errtype = ERR_RESOURCEEXHAUSTED;
73 ghc_errstr = "not enough virtual memory";
77 while ((dir = opendir(path)) == NULL) {
88 errno = 0; /* unchanged by readdir on EOF */
89 while ((d = readdir(dir)) == NULL) {
91 entries[count] = NULL;
93 return (StgAddr) entries;
94 } else if (errno != EINTR) {
97 freeEntries(entries, count);
103 len = strlen(d->d_name);
104 if ((entries[count] = malloc(len+1)) == NULL) {
105 ghc_errtype = ERR_RESOURCEEXHAUSTED;
106 ghc_errstr = "not enough virtual memory";
107 freeEntries(entries, count);
108 (void) closedir(dir);
111 strcpy(entries[count], d->d_name);
112 /* Terminate the sucker */
113 *(entries[count] + len) = 0;
114 if (++count == alloc) {
116 if ((entries = (char **) realloc(entries, alloc * sizeof(char *))) == NULL) {
117 ghc_errtype = ERR_RESOURCEEXHAUSTED;
118 ghc_errstr = "not enough virtual memory";
119 freeEntries(entries, count);
120 (void) closedir(dir);