From d6ddbb04504258a970e101d1fb7969f87c2c68b3 Mon Sep 17 00:00:00 2001 From: sof Date: Wed, 22 Apr 1998 12:44:38 +0000 Subject: [PATCH] [project @ 1998-04-22 12:44:36 by sof] Simplified C stubs used to implement Directory.getDirectoryContents --- ghc/lib/std/cbits/directoryAux.lc | 74 +++++++++++++++++ ghc/lib/std/cbits/getDirectoryContents.lc | 126 ----------------------------- ghc/lib/std/cbits/stgio.h | 7 +- 3 files changed, 78 insertions(+), 129 deletions(-) create mode 100644 ghc/lib/std/cbits/directoryAux.lc delete mode 100644 ghc/lib/std/cbits/getDirectoryContents.lc diff --git a/ghc/lib/std/cbits/directoryAux.lc b/ghc/lib/std/cbits/directoryAux.lc new file mode 100644 index 0000000..2b352c3 --- /dev/null +++ b/ghc/lib/std/cbits/directoryAux.lc @@ -0,0 +1,74 @@ +% +% (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 +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#endif + +#ifdef HAVE_DIRENT_H +#include +#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} diff --git a/ghc/lib/std/cbits/getDirectoryContents.lc b/ghc/lib/std/cbits/getDirectoryContents.lc deleted file mode 100644 index 6f66b45..0000000 --- a/ghc/lib/std/cbits/getDirectoryContents.lc +++ /dev/null @@ -1,126 +0,0 @@ -% -% (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 -#endif - -#ifdef HAVE_SYS_STAT_H -#include -#endif - -#ifdef HAVE_DIRENT_H -#include -#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} diff --git a/ghc/lib/std/cbits/stgio.h b/ghc/lib/std/cbits/stgio.h index 2c5eab2..05213ec 100644 --- a/ghc/lib/std/cbits/stgio.h +++ b/ghc/lib/std/cbits/stgio.h @@ -13,6 +13,10 @@ StgInt closeFile PROTO((StgForeignObj)); /* 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 **)); @@ -71,9 +75,6 @@ StgInt clockTicks(); /* getCurrentDirectory.lc */ StgAddr getCurrentDirectory(STG_NO_ARGS); -/* getDirectoryContents.lc */ -StgAddr getDirectoryContents PROTO((StgByteArray)); - /* getLock.lc */ int lockFile PROTO((int, int)); int unlockFile PROTO((int)); -- 1.7.10.4