r339 - trunk

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Sep 20 02:57:04 EDT 2007


Author: icculus
Date: 2007-09-20 02:57:04 -0400 (Thu, 20 Sep 2007)
New Revision: 339

Modified:
   trunk/fileio.c
   trunk/platform.h
   trunk/platform_unix.c
Log:
Some initial work on abstracting Unix-specific bits from fileio.c ...


Modified: trunk/fileio.c
===================================================================
--- trunk/fileio.c	2007-09-20 06:56:15 UTC (rev 338)
+++ trunk/fileio.c	2007-09-20 06:57:04 UTC (rev 339)
@@ -305,16 +305,15 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/param.h>
-#include <dirent.h>
 
 typedef struct DirStack
 {
-    DIR *dir;
+    void *dir;
     char *basepath;
     struct DirStack *next;
 } DirStack;
 
-static void pushDirStack(DirStack **_stack, const char *basepath, DIR *dir)
+static void pushDirStack(DirStack **_stack, const char *basepath, void *dir)
 {
     DirStack *stack = (DirStack *) xmalloc(sizeof (DirStack));
     stack->dir = dir;
@@ -330,7 +329,7 @@
     {
         DirStack *next = stack->next;
         if (stack->dir)
-            closedir(stack->dir);
+            MojoPlatform_closedir(stack->dir);
         free(stack->basepath);
         free(stack);
         *_stack = next;
@@ -353,12 +352,12 @@
 static boolean MojoArchive_dir_enumerate(MojoArchive *ar)
 {
     MojoArchiveDirInstance *inst = (MojoArchiveDirInstance *) ar->opaque;
-    DIR *dir = NULL;
+    void *dir = NULL;
 
     freeDirStack(&inst->dirs);
     MojoArchive_resetEntry(&ar->prevEnum);
 
-    dir = opendir(inst->base);
+    dir = MojoPlatform_opendir(inst->base);
     if (dir != NULL)
         pushDirStack(&inst->dirs, inst->base, dir);
 
@@ -370,28 +369,29 @@
 {
     struct stat statbuf;
     char *fullpath = NULL;
-    struct dirent *dent = NULL;
+    char *dent = NULL;  // "dent" == "directory entry"
     MojoArchiveDirInstance *inst = (MojoArchiveDirInstance *) ar->opaque;
+    const char *basepath = inst->dirs->basepath;
 
     MojoArchive_resetEntry(&ar->prevEnum);
 
     if (inst->dirs == NULL)
         return NULL;
 
-    dent = readdir(inst->dirs->dir);
+    // if readdir fails, it's end of dir (!!! FIXME: what about i/o failures?)
+    dent = MojoPlatform_readdir(inst->dirs->dir);
     if (dent == NULL)  // end of dir?
     {
         popDirStack(&inst->dirs);
         return MojoArchive_dir_enumNext(ar);  // try higher level in tree.
     } // if
 
-    if ((strcmp(dent->d_name, ".") == 0) || (strcmp(dent->d_name, "..") == 0))
-        return MojoArchive_dir_enumNext(ar);  // skip these.
+    // MojoPlatform layer shouldn't return "." or ".." paths.
+    assert((strcmp(dent, ".") != 0) && (strcmp(dent, "..") != 0));
 
-    fullpath = (char *) xmalloc(strlen(inst->dirs->basepath) +
-                                strlen(dent->d_name) + 2);
-
-    sprintf(fullpath, "%s/%s", inst->dirs->basepath, dent->d_name);
+    fullpath = (char *) xmalloc(strlen(basepath) + strlen(dent) + 2);
+    sprintf(fullpath, "%s/%s", basepath, dent);
+    free(dent);
     ar->prevEnum.filename = xstrdup(fullpath + strlen(inst->base) + 1);
 
     if (lstat(fullpath, &statbuf) == -1)
@@ -424,7 +424,7 @@
 
         else if (S_ISDIR(statbuf.st_mode))
         {
-            DIR *dir = opendir(fullpath);
+            void *dir = MojoPlatform_opendir(fullpath);
             ar->prevEnum.type = MOJOARCHIVE_ENTRY_DIR;
             if (dir == NULL)
             {

Modified: trunk/platform.h
===================================================================
--- trunk/platform.h	2007-09-20 06:56:15 UTC (rev 338)
+++ trunk/platform.h	2007-09-20 06:57:04 UTC (rev 339)
@@ -81,6 +81,24 @@
 // !!! FIXME: comment me.
 char *MojoPlatform_findMedia(const char *uniquefile);
 
+// Enumerate a directory. Returns an opaque pointer that can be used with
+//  repeated calls to MojoPlatform_readdir() to enumerate the names of
+//  directory entries. Returns NULL on error. Non-NULL values should be passed
+//  to MojoPlatform_closedir() for cleanup when you are done with them.
+void *MojoPlatform_opendir(const char *dirname);
+
+// Get the next entry in the directory. (dirhandle) is an opaque pointer
+//  returned by MojoPlatform_opendir(). Returns NULL if we're at the end of
+//  the directory, or a null-terminated UTF-8 string otherwise. The order of
+//  results are not guaranteed, and may change between two iterations.
+// Caller must free returned string!
+char *MojoPlatform_readdir(void *dirhandle);
+
+// Clean up resources used by a directory enumeration. (dirhandle) is an
+//  opaque pointer returned by MojoPlatform_opendir(), and becomes invalid
+//  after this call.
+void MojoPlatform_closedir(void *dirhandle);
+
 // Convert a string into a permissions bitmask. On Unix, this is currently
 //  expected to be an octal string like "0755", but may except other forms
 //  in the future, and other platforms may need to interpret permissions

Modified: trunk/platform_unix.c
===================================================================
--- trunk/platform_unix.c	2007-09-20 06:56:15 UTC (rev 338)
+++ trunk/platform_unix.c	2007-09-20 06:57:04 UTC (rev 339)
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <signal.h>
 #include <syslog.h>
+#include <dirent.h>
 
 #if MOJOSETUP_HAVE_SYS_UCRED_H
 #  ifdef MOJOSETUP_HAVE_MNTENT_H
@@ -549,6 +550,39 @@
 } // MojoPlatform_isdir
 
 
+void *MojoPlatform_opendir(const char *dirname)
+{
+    return opendir(dirname);
+} // MojoPlatform_opendir
+
+
+char *MojoPlatform_readdir(void *_dirhandle)
+{
+    DIR *dirhandle = (DIR *) _dirhandle;
+    struct dirent *dent = NULL;
+
+    while ((dent = readdir(dirhandle)) != NULL)
+    {
+        if (strcmp(dent->d_name, ".") == 0)
+            continue;  // skip these.
+
+        else if (strcmp(dent->d_name, "..") == 0)
+            continue;  // skip these, too.
+
+        else
+            break;  // found a valid entry, go on.
+    } // while
+
+    return ((dent) ? xstrdup(dent->d_name) : NULL);
+} // MojoPlatform_readdir
+
+
+void MojoPlatform_closedir(void *dirhandle)
+{
+    closedir((DIR *) dirhandle);
+} // MojoPlatform_closedir
+
+
 boolean MojoPlatform_perms(const char *fname, uint16 *p)
 {
     boolean retval = false;




More information about the mojosetup-commits mailing list