--- /dev/null
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1998
+%
+\subsection[directoryAux.lc]{Support functions for manipulating directories}
+
+\begin{code}
+
+#include "rtsdefs.h"
+#include "stgio.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
+StgAddr
+openDir__(path)
+StgByteArray path;
+{
+ struct stat sb;
+ DIR *dir;
+
+ /* Check for an actual directory */
+ while (stat(path, &sb) != 0) {
+ if (errno != EINTR) {
+ cvtErrno();
+ stdErrno();
+ return NULL;
+ }
+ }
+ if (!S_ISDIR(sb.st_mode)) {
+ ghc_errtype = ERR_INAPPROPRIATETYPE;
+ ghc_errstr = "not a directory";
+ return NULL;
+ }
+
+ while ((dir = opendir(path)) == NULL) {
+ if (errno != EINTR) {
+ cvtErrno();
+ stdErrno();
+ return NULL;
+ }
+ }
+ return dir;
+}
+
+StgAddr
+readDir__(dir)
+StgAddr dir;
+{
+ struct dirent *d;
+ while ((d = readdir((DIR*)dir)) == NULL) {
+ if (errno == 0) {
+ (void) closedir((DIR*)dir);
+ return NULL;
+ } else if (errno != EINTR) {
+ cvtErrno();
+ stdErrno();
+ (void) closedir((DIR*)dir);
+ return 1;
+ }
+ errno = 0;
+ }
+ return d;
+}
+
+\end{code}
+++ /dev/null
-%
-% (c) The GRASP/AQUA Project, Glasgow University, 1995
-%
-\subsection[getDirectoryContents.lc]{getDirectoryContents Runtime Support}
-
-\begin{code}
-
-#include "rtsdefs.h"
-#include "stgio.h"
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-
-#ifndef LINK_MAX
-#define LINK_MAX 1024
-#endif
-
-/* For cleanup of partial answer on error */
-
-static void
-freeEntries(char **entries, int count)
-{
- int i;
-
- for (i = 0; i < count; i++)
- free(entries[i]);
- free(entries);
-}
-
-/*
- * Our caller expects a malloc'ed array of malloc'ed string pointers.
- * To ensure consistency when mixing this with other directory
- * operations, we collect the entire list in one atomic operation,
- * rather than reading the directory lazily.
- */
-StgAddr
-getDirectoryContents(path)
-StgByteArray path;
-{
- struct stat sb;
- DIR *dir;
- struct dirent *d;
- char **entries;
- int alloc, count, len;
-
- /* Check for an actual directory */
- while (stat(path, &sb) != 0) {
- if (errno != EINTR) {
- cvtErrno();
- stdErrno();
- return NULL;
- }
- }
- if (!S_ISDIR(sb.st_mode)) {
- ghc_errtype = ERR_INAPPROPRIATETYPE;
- ghc_errstr = "not a directory";
- return NULL;
- }
-
- alloc = LINK_MAX;
- if ((entries = (char **) malloc(alloc * sizeof(char *))) == NULL) {
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "not enough virtual memory";
- return NULL;
- }
-
- while ((dir = opendir(path)) == NULL) {
- if (errno != EINTR) {
- cvtErrno();
- stdErrno();
- free(entries);
- return NULL;
- }
- }
-
- count = 0;
- for (;;) {
- errno = 0; /* unchanged by readdir on EOF */
- while ((d = readdir(dir)) == NULL) {
- if (errno == 0) {
- entries[count] = NULL;
- (void) closedir(dir);
- return (StgAddr) entries;
- } else if (errno != EINTR) {
- cvtErrno();
- stdErrno();
- freeEntries(entries, count);
- (void) closedir(dir);
- return NULL;
- }
- errno = 0;
- }
- len = strlen(d->d_name);
- if ((entries[count] = malloc(len+1)) == NULL) {
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "not enough virtual memory";
- freeEntries(entries, count);
- (void) closedir(dir);
- return NULL;
- }
- strcpy(entries[count], d->d_name);
- /* Terminate the sucker */
- *(entries[count] + len) = 0;
- if (++count == alloc) {
- alloc += LINK_MAX;
- if ((entries = (char **) realloc(entries, alloc * sizeof(char *))) == NULL) {
- ghc_errtype = ERR_RESOURCEEXHAUSTED;
- ghc_errstr = "not enough virtual memory";
- freeEntries(entries, count);
- (void) closedir(dir);
- return NULL;
- }
- }
- }
-}
-
-\end{code}
/* createDirectory.lc */
StgInt createDirectory PROTO((StgByteArray));
+/* directoryAux.lc */
+StgAddr openDir__ PROTO((StgByteArray));
+StgAddr readDir__ PROTO((StgAddr));
+
/* env.lc */
char * strDup PROTO((const char *));
int setenviron PROTO((char **));
/* getCurrentDirectory.lc */
StgAddr getCurrentDirectory(STG_NO_ARGS);
-/* getDirectoryContents.lc */
-StgAddr getDirectoryContents PROTO((StgByteArray));
-
/* getLock.lc */
int lockFile PROTO((int, int));
int unlockFile PROTO((int));