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