Skip to content

Commit

Permalink
Some initial work on abstracting Unix-specific bits from fileio.c ...
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Sep 20, 2007
1 parent d85a0b9 commit 7543cf3
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 15 deletions.
30 changes: 15 additions & 15 deletions fileio.c
Expand Up @@ -305,16 +305,15 @@ MojoInput *MojoInput_newFromFile(const char *path)
#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;
Expand All @@ -330,7 +329,7 @@ static void popDirStack(DirStack **_stack)
{
DirStack *next = stack->next;
if (stack->dir)
closedir(stack->dir);
MojoPlatform_closedir(stack->dir);
free(stack->basepath);
free(stack);
*_stack = next;
Expand All @@ -353,12 +352,12 @@ typedef struct
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);

Expand All @@ -370,28 +369,29 @@ static const MojoArchiveEntry *MojoArchive_dir_enumNext(MojoArchive *ar)
{
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)
Expand Down Expand Up @@ -424,7 +424,7 @@ static const MojoArchiveEntry *MojoArchive_dir_enumNext(MojoArchive *ar)

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)
{
Expand Down
18 changes: 18 additions & 0 deletions platform.h
Expand Up @@ -81,6 +81,24 @@ boolean MojoPlatform_chmod(const char *fname, uint16 p);
// !!! 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
Expand Down
34 changes: 34 additions & 0 deletions platform_unix.c
Expand Up @@ -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
Expand Down Expand Up @@ -549,6 +550,39 @@ boolean MojoPlatform_isdir(const char *dir)
} // 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;
Expand Down

0 comments on commit 7543cf3

Please sign in to comment.