r340 - trunk

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Sep 20 04:34:56 EDT 2007


Author: icculus
Date: 2007-09-20 04:34:55 -0400 (Thu, 20 Sep 2007)
New Revision: 340

Modified:
   trunk/fileio.c
   trunk/lua_glue.c
   trunk/mojosetup.c
   trunk/platform.h
   trunk/platform_unix.c
Log:
Reworked the rest of the Unix-specific bits out of fileio.c ... untested!


Modified: trunk/fileio.c
===================================================================
--- trunk/fileio.c	2007-09-20 06:57:04 UTC (rev 339)
+++ trunk/fileio.c	2007-09-20 08:34:55 UTC (rev 340)
@@ -6,8 +6,6 @@
  *  This file written by Ryan C. Gordon.
  */
 
-#include <sys/stat.h>  // !!! FIXME: unix dependency for stat().
-
 #include "fileio.h"
 #include "platform.h"
 
@@ -88,7 +86,7 @@
 {
     boolean retval = false;
     uint32 start = MojoPlatform_ticks();
-    FILE *out = NULL;
+    void *out = NULL;
     boolean iofailure = false;
     int64 flen = 0;
     int64 bw = 0;
@@ -120,7 +118,11 @@
 
     MojoPlatform_unlink(fname);
     if (!iofailure)
-        out = fopen(fname, "wb");
+    {
+        const uint32 flags = MOJOFILE_WRITE|MOJOFILE_CREATE|MOJOFILE_TRUNCATE;
+        const uint16 mode = MojoPlatform_defaultFilePerms();
+        out = MojoPlatform_open(fname, flags, mode);
+    } // if
 
     if (out != NULL)
     {
@@ -141,7 +143,7 @@
                     iofailure = true;
                 else
                 {
-                    if (fwrite(scratchbuf_128k, br, 1, out) != 1)
+                    if (MojoPlatform_write(out, scratchbuf_128k, br) != br)
                         iofailure = true;
                     else
                     {
@@ -159,7 +161,7 @@
             } // if
         } // while
 
-        if (fclose(out) != 0)
+        if (MojoPlatform_close(out) != 0)
             iofailure = true;
 
         if (iofailure)
@@ -204,7 +206,7 @@
 
 typedef struct
 {
-    FILE *handle;
+    void *handle;
     char *path;
 } MojoInputFileInstance;
 
@@ -217,43 +219,25 @@
 static int64 MojoInput_file_read(MojoInput *io, void *buf, uint32 bufsize)
 {
     MojoInputFileInstance *inst = (MojoInputFileInstance *) io->opaque;
-    return (int64) fread(buf, 1, bufsize, inst->handle);
+    return MojoPlatform_read(inst->handle, buf, bufsize);
 } // MojoInput_file_read
 
 static boolean MojoInput_file_seek(MojoInput *io, uint64 pos)
 {
     MojoInputFileInstance *inst = (MojoInputFileInstance *) io->opaque;
-#if 1
-    rewind(inst->handle);
-    while (pos)
-    {
-        // do in a loop to make sure we seek correctly in > 2 gig files.
-        if (fseek(inst->handle, (long) (pos & 0x7FFFFFFF), SEEK_CUR) == -1)
-            return false;
-        pos -= (pos & 0x7FFFFFFF);
-    } // while
-    return true;
-#else
-    return (fseeko(inst->handle, pos, SEEK_SET) == 0);
-#endif
+    return (MojoPlatform_seek(inst->handle, pos, MOJOSEEK_SET) == pos);
 } // MojoInput_file_seek
 
 static int64 MojoInput_file_tell(MojoInput *io)
 {
     MojoInputFileInstance *inst = (MojoInputFileInstance *) io->opaque;
-//    return (int64) ftello(inst->handle);
-    STUBBED("ftell is 32 bit!\n");
-    return (int64) ftell(inst->handle);
+    return MojoPlatform_tell(inst->handle);
 } // MojoInput_file_tell
 
 static int64 MojoInput_file_length(MojoInput *io)
 {
     MojoInputFileInstance *inst = (MojoInputFileInstance *) io->opaque;
-    int fd = fileno(inst->handle);
-    struct stat statbuf;
-    if ((fd == -1) || (fstat(fd, &statbuf) == -1))
-        return -1;
-    return((int64) statbuf.st_size);
+    return MojoPlatform_flen(inst->handle);
 } // MojoInput_file_length
 
 static MojoInput *MojoInput_file_duplicate(MojoInput *io)
@@ -265,7 +249,7 @@
 static void MojoInput_file_close(MojoInput *io)
 {
     MojoInputFileInstance *inst = (MojoInputFileInstance *) io->opaque;
-    fclose(inst->handle);
+    MojoPlatform_close(inst->handle);
     free(inst->path);
     free(inst);
     free(io);
@@ -274,9 +258,9 @@
 MojoInput *MojoInput_newFromFile(const char *path)
 {
     MojoInput *io = NULL;
-    FILE *f = NULL;
+    void *f = NULL;
 
-    f = fopen(path, "rb");
+    f = MojoPlatform_open(path, MOJOFILE_READ, 0);
     if (f != NULL)
     {
         MojoInputFileInstance *inst;
@@ -301,11 +285,6 @@
 
 // MojoArchives from directories on the OS filesystem.
 
-// !!! FIXME: abstract the unixy bits into the platform/ dir.
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-
 typedef struct DirStack
 {
     void *dir;
@@ -367,7 +346,7 @@
 
 static const MojoArchiveEntry *MojoArchive_dir_enumNext(MojoArchive *ar)
 {
-    struct stat statbuf;
+    uint16 perms = 0644; //(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
     char *fullpath = NULL;
     char *dent = NULL;  // "dent" == "directory entry"
     MojoArchiveDirInstance *inst = (MojoArchiveDirInstance *) ar->opaque;
@@ -392,48 +371,53 @@
     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);
+    ar->prevEnum.filesize = 0;
+    ar->prevEnum.type = MOJOARCHIVE_ENTRY_UNKNOWN;
 
-    if (lstat(fullpath, &statbuf) == -1)
-        ar->prevEnum.type = MOJOARCHIVE_ENTRY_UNKNOWN;
-    else
+    // We currently force the perms from physical files, since CDs on
+    //  Linux tend to mark every files as executable and read-only. If you
+    //  want to install something with specific permissions, wrap it in a
+    //  tarball, or use Setup.File.permissions, or return a permissions
+    //  string from Setup.File.filter.
+    //MojoPlatform_perms(fullpath, &perms);
+    ar->prevEnum.perms = perms;
+
+    if (MojoPlatform_isfile(fullpath))
     {
-        ar->prevEnum.filesize = statbuf.st_size;
+        ar->prevEnum.type = MOJOARCHIVE_ENTRY_FILE;
+        ar->prevEnum.filesize = MojoPlatform_filesize(fullpath);
+    } // if
 
-        // We currently force the perms from physical files, since CDs on
-        //  Linux tend to mark every files as executable and read-only. If you
-        //  want to install something with specific permissions, wrap it in a
-        //  tarball, or use Setup.File.permissions, or return a permissions
-        //  string from Setup.File.filter.
-        //ar->prevEnum.perms = statbuf.st_mode;
-        ar->prevEnum.perms = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-        if (S_ISREG(statbuf.st_mode))
-            ar->prevEnum.type = MOJOARCHIVE_ENTRY_FILE;
-
-        else if (S_ISLNK(statbuf.st_mode))
+    else if (MojoPlatform_issymlink(fullpath))
+    {
+        ar->prevEnum.type = MOJOARCHIVE_ENTRY_SYMLINK;
+        ar->prevEnum.linkdest = MojoPlatform_readlink(fullpath);
+        if (ar->prevEnum.linkdest == NULL)
         {
-            ar->prevEnum.type = MOJOARCHIVE_ENTRY_SYMLINK;
-            ar->prevEnum.linkdest = MojoPlatform_readlink(fullpath);
-            if (ar->prevEnum.linkdest == NULL)
-            {
-                free(fullpath);
-                return MojoArchive_dir_enumNext(ar);
-            } // if
-        } // else if
+            free(fullpath);
+            return MojoArchive_dir_enumNext(ar);
+        } // if
+    } // else if
 
-        else if (S_ISDIR(statbuf.st_mode))
+    else if (MojoPlatform_isdir(fullpath))
+    {
+        void *dir = MojoPlatform_opendir(fullpath);
+        ar->prevEnum.type = MOJOARCHIVE_ENTRY_DIR;
+        if (dir == NULL)
         {
-            void *dir = MojoPlatform_opendir(fullpath);
-            ar->prevEnum.type = MOJOARCHIVE_ENTRY_DIR;
-            if (dir == NULL)
-            {
-                free(fullpath);
-                return MojoArchive_dir_enumNext(ar);
-            } // if
-            // push this dir on the stack. Next enum will start there.
-            pushDirStack(&inst->dirs, fullpath, dir);
-        } // else if
+            free(fullpath);
+            return MojoArchive_dir_enumNext(ar);
+        } // if
+
+        // push this dir on the stack. Next enum will start there.
+        pushDirStack(&inst->dirs, fullpath, dir);
+    } // else if
+
+    else
+    {
+        assert(false && "possible file i/o error?");
     } // else
 
     free(fullpath);
@@ -475,11 +459,16 @@
     MojoArchive *ar = NULL;
     MojoArchiveDirInstance *inst;
     char *real = MojoPlatform_realpath(dirname);
-    struct stat st;
 
-    if ( (real == NULL) || (stat(real, &st) == -1) || (!S_ISDIR(st.st_mode)) )
+    if (real == NULL)
         return NULL;
 
+    if (!MojoPlatform_exists(real, NULL))
+        return NULL;
+
+    if (!MojoPlatform_isdir(real))
+        return NULL;
+
     inst = (MojoArchiveDirInstance *) xmalloc(sizeof (MojoArchiveDirInstance));
     inst->base = real;
     ar = (MojoArchive *) xmalloc(sizeof (MojoArchive));
@@ -508,17 +497,23 @@
 
     if ((cmd = cmdlinestr("base", "MOJOSETUP_BASE", NULL)) != NULL)
     {
-        if (MojoPlatform_isdir(cmd))
-            GBaseArchive = MojoArchive_newFromDirectory(cmd);
-        else
+        char *real = MojoPlatform_realpath(cmd);
+        if (real != NULL)
         {
-            io = MojoInput_newFromFile(cmd);
-            if (io != NULL)
-                GBaseArchive = MojoArchive_newFromInput(io, cmd);
-        } // else
+            if (MojoPlatform_isdir(real))
+                GBaseArchive = MojoArchive_newFromDirectory(real);
+            else
+            {
+                io = MojoInput_newFromFile(real);
+                if (io != NULL)
+                    GBaseArchive = MojoArchive_newFromInput(io, real);
+            } // else
 
-        if (GBaseArchive != NULL)
-            basepath = xstrdup(cmd);
+            if (GBaseArchive != NULL)
+                basepath = real;
+            else
+                free(real);
+        } // if
     } // else if
 
     else

Modified: trunk/lua_glue.c
===================================================================
--- trunk/lua_glue.c	2007-09-20 06:57:04 UTC (rev 339)
+++ trunk/lua_glue.c	2007-09-20 08:34:55 UTC (rev 340)
@@ -876,9 +876,23 @@
 {
     const char *dir = luaL_checkstring(L, 1);
     return retvalBoolean(L, MojoPlatform_isdir(dir));
-} // luahook_platform_writable
+} // luahook_platform_isdir
 
 
+static int luahook_platform_issymlink(lua_State *L)
+{
+    const char *fname = luaL_checkstring(L, 1);
+    return retvalBoolean(L, MojoPlatform_issymlink(fname));
+} // luahook_platform_issymlink
+
+
+static int luahook_platform_isfile(lua_State *L)
+{
+    const char *fname = luaL_checkstring(L, 1);
+    return retvalBoolean(L, MojoPlatform_isfile(fname));
+} // luahook_platform_isfile
+
+
 static int luahook_platform_symlink(lua_State *L)
 {
     const char *src = luaL_checkstring(L, 1);
@@ -1458,6 +1472,8 @@
             set_cfunc(luaState, luahook_platform_exists, "exists");
             set_cfunc(luaState, luahook_platform_writable, "writable");
             set_cfunc(luaState, luahook_platform_isdir, "isdir");
+            set_cfunc(luaState, luahook_platform_issymlink, "issymlink");
+            set_cfunc(luaState, luahook_platform_isfile, "isfile");
             set_cfunc(luaState, luahook_platform_symlink, "symlink");
             set_cfunc(luaState, luahook_platform_mkdir, "mkdir");
         lua_setfield(luaState, -2, "platform");

Modified: trunk/mojosetup.c
===================================================================
--- trunk/mojosetup.c	2007-09-20 06:57:04 UTC (rev 339)
+++ trunk/mojosetup.c	2007-09-20 08:34:55 UTC (rev 340)
@@ -316,7 +316,7 @@
 #define DEFLOGLEV "everything"
 #endif
 MojoSetupLogLevel MojoLog_logLevel = MOJOSETUP_LOG_EVERYTHING;
-static FILE *logFile = NULL;
+static void *logFile = NULL;
 
 void MojoLog_initLogging(void)
 {
@@ -336,16 +336,23 @@
     else  // Unknown string gets everything...that'll teach you.
         MojoLog_logLevel = MOJOSETUP_LOG_EVERYTHING;
 
+    // !!! FIXME: allow logging to stdout on Unix.
     if (fname != NULL)
-        logFile = fopen(fname, "w");
+    {
+        const uint32 flags = MOJOFILE_WRITE|MOJOFILE_CREATE|MOJOFILE_TRUNCATE;
+        const uint16 mode = MojoPlatform_defaultFilePerms();
+        logFile = MojoPlatform_open(fname, flags, mode);
+    } // if
 } // MojoLog_initLogging
 
 
 void MojoLog_deinitLogging(void)
 {
     if (logFile != NULL)
-        fclose(logFile);
-    logFile = NULL;
+    {
+        MojoPlatform_close(logFile);
+        logFile = NULL;
+    } // if
 } // MojoLog_deinitLogging
 
 
@@ -364,9 +371,10 @@
         MojoPlatform_log(buf);
         if (logFile != NULL)
         {
-            fputs(buf, logFile);
-            fputs("\n", logFile);
-            fflush(logFile);
+            const char *endl = MOJOPLATFORM_ENDLINE;
+            MojoPlatform_write(logFile, buf, strlen(buf));
+            MojoPlatform_write(logFile, endl, strlen(endl));
+            MojoPlatform_flush(logFile);
         } // if
     } // if
 } // addLog

Modified: trunk/platform.h
===================================================================
--- trunk/platform.h	2007-09-20 06:57:04 UTC (rev 339)
+++ trunk/platform.h	2007-09-20 08:34:55 UTC (rev 340)
@@ -73,6 +73,15 @@
 boolean MojoPlatform_isdir(const char *dir);
 
 // !!! FIXME: comment me.
+boolean MojoPlatform_issymlink(const char *fname);
+
+// !!! FIXME: comment me.
+boolean MojoPlatform_isfile(const char *fname);
+
+// !!! FIXME: comment me.
+int64 MojoPlatform_filesize(const char *fname);
+
+// !!! FIXME: comment me.
 boolean MojoPlatform_perms(const char *fname, uint16 *p);
 
 // !!! FIXME: comment me.
@@ -81,6 +90,42 @@
 // !!! FIXME: comment me.
 char *MojoPlatform_findMedia(const char *uniquefile);
 
+// Flag values for MojoPlatform_fopen().
+typedef enum
+{
+    MOJOFILE_READ=(1<<0),
+    MOJOFILE_WRITE=(1<<1),
+    MOJOFILE_CREATE=(1<<2),
+    MOJOFILE_EXCLUSIVE=(1<<3),
+    MOJOFILE_TRUNCATE=(1<<4),
+    MOJOFILE_APPEND=(1<<5),
+} MojoFileFlags;
+
+typedef enum
+{
+    MOJOSEEK_SET,
+    MOJOSEEK_CURRENT,
+    MOJOSEEK_END
+} MojoFileSeek;
+
+// !!! FIXME: comment me.
+void *MojoPlatform_open(const char *fname, uint32 flags, uint16 mode);
+// !!! FIXME: comment me.
+int64 MojoPlatform_read(void *fd, void *buf, uint32 bytes);
+// !!! FIXME: comment me.
+int64 MojoPlatform_write(void *fd, const void *buf, uint32 bytes);
+// !!! FIXME: comment me.
+int64 MojoPlatform_tell(void *fd);
+// !!! FIXME: comment me.
+int64 MojoPlatform_seek(void *fd, int64 offset, MojoFileSeek whence);
+// !!! FIXME: comment me.
+int64 MojoPlatform_flen(void *fd);
+// !!! FIXME: comment me.
+boolean MojoPlatform_flush(void *fd);
+// !!! FIXME: comment me.
+boolean MojoPlatform_close(void *fd);
+
+
 // 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
@@ -100,7 +145,7 @@
 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
+//  expected to be an octal string like "0755", but may expect other forms
 //  in the future, and other platforms may need to interpret permissions
 //  differently. (str) may be NULL for defaults, and is considered valid.
 // If (str) is not valid, return a reasonable default and set (*valid) to
@@ -175,6 +220,13 @@
 #error Unknown processor architecture.
 #endif
 
+// Other basic truths...
+#if PLATFORM_WINDOWS
+#define MOJOPLATFORM_ENDLINE "\r\n"
+#else
+#define MOJOPLATFORM_ENDLINE "\n"
+#endif
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/platform_unix.c
===================================================================
--- trunk/platform_unix.c	2007-09-20 06:57:04 UTC (rev 339)
+++ trunk/platform_unix.c	2007-09-20 08:34:55 UTC (rev 340)
@@ -541,7 +541,7 @@
 {
     boolean retval = false;
     struct stat statbuf;
-    if (stat(dir, &statbuf) != -1)
+    if (lstat(dir, &statbuf) != -1)
     {
         if (S_ISDIR(statbuf.st_mode))
             retval = true;
@@ -550,6 +550,125 @@
 } // MojoPlatform_isdir
 
 
+boolean MojoPlatform_issymlink(const char *dir)
+{
+    boolean retval = false;
+    struct stat statbuf;
+    if (lstat(dir, &statbuf) != -1)
+    {
+        if (S_ISLNK(statbuf.st_mode))
+            retval = true;
+    } // if
+    return retval;
+} // MojoPlatform_issymlink
+
+
+boolean MojoPlatform_isfile(const char *dir)
+{
+    boolean retval = false;
+    struct stat statbuf;
+    if (lstat(dir, &statbuf) != -1)
+    {
+        if (S_ISREG(statbuf.st_mode))
+            retval = true;
+    } // if
+    return retval;
+} // MojoPlatform_issymlink
+
+
+void *MojoPlatform_open(const char *fname, uint32 flags, uint16 mode)
+{
+    void *retval = NULL;
+    int fd = -1;
+    int unixflags = 0;
+
+    if ((flags & MOJOFILE_READ) && (flags & MOJOFILE_WRITE))
+        unixflags |= O_RDWR;
+    else if (flags & MOJOFILE_READ)
+        unixflags |= O_RDONLY;
+    else if (flags & MOJOFILE_WRITE)
+        unixflags |= O_WRONLY;
+    else
+        return NULL;  // have to specify SOMETHING.
+
+    if (flags & MOJOFILE_APPEND)
+        unixflags |= O_APPEND;
+    if (flags & MOJOFILE_TRUNCATE)
+        unixflags |= O_TRUNC;
+    if (flags & MOJOFILE_CREATE)
+        unixflags |= O_CREAT;
+    if (flags & MOJOFILE_EXCLUSIVE)
+        unixflags |= O_EXCL;
+
+    fd = open(fname, unixflags, (mode_t) mode);
+    if (fd != -1)
+    {
+        int *intptr = (int *) xmalloc(sizeof (int));
+        *intptr = fd;
+        retval = intptr;
+    } // if
+
+    return retval;
+} // MojoPlatform_open
+
+
+int64 MojoPlatform_read(void *fd, void *buf, uint32 bytes)
+{
+    return (int64) read(*((int *) fd), buf, bytes);
+} // MojoPlatform_read
+
+
+int64 MojoPlatform_write(void *fd, const void *buf, uint32 bytes)
+{
+    return (int64) write(*((int *) fd), buf, bytes);
+} // MojoPlatform_write
+
+
+int64 MojoPlatform_tell(void *fd)
+{
+    return (int64) lseek(*((int *) fd), 0, SEEK_CUR);
+} // MojoPlatform_tell
+
+
+int64 MojoPlatform_seek(void *fd, int64 offset, MojoFileSeek whence)
+{
+    int unixwhence;
+    switch (whence)
+    {
+        case MOJOSEEK_SET: unixwhence = SEEK_SET; break;
+        case MOJOSEEK_CURRENT: unixwhence = SEEK_CUR; break;
+        case MOJOSEEK_END: unixwhence = SEEK_END; break;
+        default: return -1;  // !!! FIXME: maybe just abort?
+    } // switch
+
+    return (int64) lseek(*((int *) fd), offset, unixwhence);
+} // MojoPlatform_seek
+
+
+int64 MojoPlatform_flen(void *fd)
+{
+    struct stat statbuf;
+    if (fstat(*((int *) fd), &statbuf) == -1)
+        return -1;
+    return((int64) statbuf.st_size);
+} // MojoPlatform_flen
+
+
+boolean MojoPlatform_flush(void *fd)
+{
+    return (fsync(*((int *) fd)) == 0);
+} // MojoPlatform_flush
+
+
+boolean MojoPlatform_close(void *fd)
+{
+    boolean retval = false;
+    if (close(*((int *) fd)) == 0)
+        free(fd);
+    return retval;
+} // MojoPlatform_close
+
+
 void *MojoPlatform_opendir(const char *dirname)
 {
     return opendir(dirname);
@@ -583,6 +702,16 @@
 } // MojoPlatform_closedir
 
 
+int64 MojoPlatform_filesize(const char *fname)
+{
+    int retval = -1;
+    struct stat statbuf;
+    if (stat(fname, &statbuf) != -1)
+        retval = (int64) statbuf.st_size;
+    return retval;
+} // MojoPlatform_filesize
+
+
 boolean MojoPlatform_perms(const char *fname, uint16 *p)
 {
     boolean retval = false;




More information about the mojosetup-commits mailing list